<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-6890958153006612459</id><updated>2012-02-10T20:18:14.640-08:00</updated><category term='Foundations'/><category term='ruby'/><category term='Lean'/><category term='beginnings'/><category term='education'/><category term='meetup'/><category term='weekend testing'/><category term='introduction'/><category term='documentation'/><category term='Bug Advocacy'/><category term='PRACTICUM'/><category term='books'/><category term='collaboration'/><category term='stress testing'/><category term='Selenium'/><category term='AYE'/><category term='PLP'/><category term='web development'/><category term='mission critical'/><category term='terminology'/><category term='The Testing Planet'/><category term='time management'/><category term='Test Design'/><category term='Rspec'/><category term='motivation'/><category term='STP-Con'/><category term='risk mamangement'/><category term='Two Leaf Clover'/><category term='CAST'/><category term='screencasts'/><category term='TWiST'/><category term='STAR'/><category term='performance'/><category term='podcasts'/><category term='BOOK CLUB'/><category term='productivity'/><category term='mobile testing'/><category term='audio editing'/><category term='learning'/><category term='testing techniques'/><category term='training'/><category term='teaching'/><category term='BOOT CAMP'/><category term='testing tools'/><category term='humor'/><category term='life experience'/><category term='speaking'/><category term='career development'/><category term='security'/><category term='programming'/><category term='AST'/><category term='UX'/><category term='cucumber'/><category term='games'/><category term='goals'/><category term='philosophy'/><category term='gaming'/><category term='Sherwood'/><category term='life'/><category term='costs'/><category term='certification'/><category term='people'/><category term='Army of One'/><category term='presenting'/><category term='Audacity'/><category term='Twelve Points of the TESTHEAD Law'/><category term='Agile'/><category term='BBST'/><category term='interviewing'/><category term='volunteering'/><category term='usability testing'/><category term='design'/><category term='podcasting'/><category term='skills development'/><category term='JavaScript'/><category term='PNSQC'/><category term='automation'/><category term='software testing'/><category term='writing'/><category term='TestComplete'/><category term='conferences'/><title type='text'>TESTHEAD</title><subtitle type='html'>The Mis-Education and Re-Education of a Software Tester</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://www.mkltesthead.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6890958153006612459/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://www.mkltesthead.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/6890958153006612459/posts/default?start-index=101&amp;max-results=100'/><author><name>Michael Larsen</name><uri>https://profiles.google.com/104738247543282839437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-L_ARsHiklGg/AAAAAAAAAAI/AAAAAAAABPA/PwBZuynaDbc/s512-c/photo.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>486</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-6890958153006612459.post-2275890415062185432</id><published>2012-02-10T14:38:00.001-08:00</published><updated>2012-02-10T20:18:14.653-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='people'/><category scheme='http://www.blogger.com/atom/ns#' term='design'/><category scheme='http://www.blogger.com/atom/ns#' term='life experience'/><title type='text'>The Watershed Moment</title><content type='html'>A couple of days ago, John Brownlee posted to the web site "&lt;a href="http://www.cultofmac.com/"&gt;Cult of Mac&lt;/a&gt;" &lt;a href="http://www.cultofmac.com/145083/what-phones-looked-like-before-and-after-the-iphone-transformed-the-industry-image/"&gt;what was an interesting picture&lt;/a&gt;. On the left, we see what cell phones looked like and were available prior to the development and the release of the iPhone. On the right, it shows what phones looked like after the iPhone was released.&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Do you notice anything interesting? The first being that, in the first picture, there is a cacophony of different styles and formats for phones. Lots of different styles and features, many of which may be familiar to some and not so familiar to others. There is no question that many different varieties were to be seen and to be had. In the second picture, almost every phone looks as though it were styled and shaped like an iPhone.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;What happened was that tech had a "watershed moment" with the release of the iPhone, and the rules of the game were changed. Yes, there were smart phones before, but no where near the sophistication of the iPhone at the time, and many other companies followed suit. The various Android phone manufacturers took many styling and design cues from the iPhone and made a system that was similar if not exactly the same. Even knock off phones not related to the iPhone or Android systems are following their design cues (I know, I have one).&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;In some ways, watershed moments are good, they show a definitive marker where things change, tastes align, and the world goes on a slightly different tangent than before. One needs just look at music to see similar examples through the years. Sinatra defined his era as clearly as Elvis defined his, The Beatles defined theirs and Led Zeppelin theirs. Add in Guns &amp;amp; Roses, Nirvana and later groups and you see what I mean. Oftentimes, those watershed moments obliterate all that has gone before... and frankly, that's a little bit sad.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;As I've been thinking of testing these past couple of years, I've been able to look back and see some watershed moments as well. The ISO movement, and its brothers CMMI and Six Sigma. In the software world, the arrival of the record and playback tools, and perhaps today we could be seeing certification as a potential watershed moment in some places. My concern is not that these happen. If ideas are good and people embrace them, then there is nothing that's going to stop them and they will be adopted of their own accord. My fear is that much is being discarded that really shouldn't be. It's no secret that I consider the phrase "best practices" to be a terrible combination of words. I don't believe in them, but I do believe in various good practices that have their time and place. The danger with watershed moments is that they tend to sweep out many good practices because they no longer fit the fashionable "time and place" we are currently experiencing.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;In short, not everyone wants to move on from Elvis. Not everyone wants a big screen cell phone. And not everyone wants to have tools that make elaborate promises of "best practices" but don't really deliver. We want to be able to choose what works for us, whether they are fashionable or not.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6890958153006612459-2275890415062185432?l=www.mkltesthead.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.mkltesthead.com/feeds/2275890415062185432/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6890958153006612459&amp;postID=2275890415062185432' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6890958153006612459/posts/default/2275890415062185432'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6890958153006612459/posts/default/2275890415062185432'/><link rel='alternate' type='text/html' href='http://www.mkltesthead.com/2012/02/watershed-moment.html' title='The Watershed Moment'/><author><name>Michael Larsen</name><uri>https://profiles.google.com/104738247543282839437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-L_ARsHiklGg/AAAAAAAAAAI/AAAAAAAABPA/PwBZuynaDbc/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6890958153006612459.post-3879339709778380680</id><published>2012-02-09T15:00:00.000-08:00</published><updated>2012-02-09T15:14:50.186-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='people'/><category scheme='http://www.blogger.com/atom/ns#' term='collaboration'/><category scheme='http://www.blogger.com/atom/ns#' term='books'/><category scheme='http://www.blogger.com/atom/ns#' term='life experience'/><title type='text'>Book Review: The Secrets of Consulting</title><content type='html'>&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://http.cdnlayer.com/itke/blogs.dir/74/files/2011/07/scc.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://http.cdnlayer.com/itke/blogs.dir/74/files/2011/07/scc.jpg" width="217" /&gt;&lt;/a&gt;&lt;/div&gt;First, I'm doing this in reverse order. I actually read "&lt;a href="http://www.mkltesthead.com/2011/03/book-review-more-secrets-of-consulting.html"&gt;More Secrets of Consulting&lt;/a&gt;" almost a year ago, and from that experience, I decided to read some more of Jerry Weinberg's books (&lt;a href="http://www.mkltesthead.com/2011/10/book-review-weinberg-on-writing.html"&gt;Weinberg on Writing&lt;/a&gt;, &lt;a href="http://www.mkltesthead.com/2011/10/book-review-perfect-software-and-other.html"&gt;Perfect Software&lt;/a&gt;, etc.). Thus it's a roundabout way that brings me to the original "&lt;a href="http://www.blogger.com/Failing%20Scenarios:%20cucumber%20-p%20primary%20features/category/profile/public_profile_displays_tracked_shows.feature:6%20# Scenario: User can see tracked shows on public profile page cucumber -p primary features/category/profile/user_views_private_profile.feature:4 # Scenario: view users private profile page with no shows tracked cucumber -p primary features/category/tracking/user_tracks_show_grouped.feature:4 # Scenario: logged in Sidereel user can track show from different page and confirm show is being tracked cucumber -p primary features/category/z_facebook/facebook_user_sees_profile_page.feature:25 # Scenario: facebook user can share a show with other facebook friends cucumber -p primary features/category/z_facebook/facebook_user_sees_profile_page.feature:50 # Scenario: Facebook user tries to share profile with fb and tw unchecked"&gt;The Secrets of Consulting&lt;/a&gt;".&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;This is a book that every tester is encouraged to read. If anyone asks other testers or programmers about which Weinberg books to read, invariably "TSOC" gets mentioned. So what do we get if we follow up and check out this now classic title (if we use automobile standards, anything over 25 years old is "classic").&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;First, this book is a fun read, and it's a quirky book full of American idioms that will really only make sense if you've grown up in the US or have family that has told stories of the US from the 40's on through the 80s (when this book was written). The anecdotes may feel odd to people who didn't grow up in the America of that time period, but for those of us who have, much of these details feel right and their amusement factor helps us remember the concepts.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Weinberg gives names to many of his principles that are whimsical, and that whimsical quality helps make them memorable. There are many folksy stories included, and if you have read any of Jerry's books, this is a hallmark of his writing. For some, it may be off putting. For me, I find it endearing. Having had correspondence and communication with Jerry over the years, you recognize his voice and his demeanor in the prose, and it makes the stories very authentic. As such, principles like the Law of Raspberry Jam, the Orange Juice Rule, Rudy's Law of Rutabaga, Marvin's Great Secrets, etc. become easily recognizable and easily remembered. By themselves, these names are meaningless, but it's the memorable stories that help them come to mind and make them ring true for me.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Don't let the folksy qualities of the book fool you, there is a lot of very practical advice in this book, and while the stories may make you smile, maybe even laugh, or possibly shake your head, there is definitely a lot of real red meat in this book and letting it nourish you will indeed be worth your time. Some may complain that the advice is a little cynical in spots, or that they would never do the things that Jerry advocates, or that some of it comes across as unprofessional. To those people, I would suggest that they take themselves out of the equation for a minute, and examine human behavior. Jerry's examples and laws are not cynical, they are human, and they map to the way that people actually behave and interact with each other. Jerry's Laws are universal. The political, social, and behavioral problems we face tend to likewise be universal.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Most of all, this book is for every consultant out there, not just the ones that have that title tacked on their business cards and letterheads. When we get right down to it, every one of us is a consultant. We offer a service to our clients, and every law that Jerry espouses works just as well for us workaday employees as it does for official consultants. At some point in our careers each of us is going to need to be the bringer of news that others will not want to hear. How we deliver that news most effectively ultimately is up to us, but with these handy rules in mind, we can be more effective in sharing that news.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Bottom Line:&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Don't think that because you are not an officially titled "Consultant" that this book will serve no purpose or have no value for you. In fact, I'd suggest everyone take a little piece of masking tape and cover up the word "Consulting" and write down "Dealing with Other People, Period". See, that way, when you reach for a copy of "the Secrets of Dealing with Other People, Period" then all of the story's, rules, limits, and laws will make much more sense, and their ready applicability to *everyone* can be better appreciated. I've seen many people say that this book is one they read over and over. I can certainly understand why.&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6890958153006612459-3879339709778380680?l=www.mkltesthead.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.mkltesthead.com/feeds/3879339709778380680/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6890958153006612459&amp;postID=3879339709778380680' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6890958153006612459/posts/default/3879339709778380680'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6890958153006612459/posts/default/3879339709778380680'/><link rel='alternate' type='text/html' href='http://www.mkltesthead.com/2012/02/book-review-secrets-of-consulting.html' title='Book Review: The Secrets of Consulting'/><author><name>Michael Larsen</name><uri>https://profiles.google.com/104738247543282839437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-L_ARsHiklGg/AAAAAAAAAAI/AAAAAAAABPA/PwBZuynaDbc/s512-c/photo.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6890958153006612459.post-7846694643480923623</id><published>2012-02-07T17:00:00.000-08:00</published><updated>2012-02-07T17:06:22.757-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='web development'/><category scheme='http://www.blogger.com/atom/ns#' term='BOOK CLUB'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><title type='text'>Book Review: Head First HTML5 Programming</title><content type='html'>&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://covers.oreilly.com/images/9781449390549/cat.gif" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://covers.oreilly.com/images/9781449390549/cat.gif" /&gt;&lt;/a&gt;&lt;/div&gt;It’s a good bet that at some point your everyday tester is going to need to come face to face with the newest web standards, and if you have to get exposed to it from a books viewpoint, well, this is a friendly and straightforward way to do it. &lt;a href="http://shop.oreilly.com/product/0636920010906.do"&gt;Head First HTML5 Programming&lt;/a&gt; uses a fun and graphically dense format to help get people comfortable with the ideas of using HTML5, CSS3 and Javascript.&lt;br /&gt;&lt;br /&gt;OK, first and foremost, this is not an absolute beginner’s book, although you may well find that you don’t need all that much underlying understanding to be effective. If you have a basic understanding of HTML tags understand some CSS formatting and have seen and can recognize XHTML or XML, then you know enough to work through this book. This is also not a grans master’s book, either. It is not a comprehensive reference. What it does do is provide a basic framework and some fun text to help the user get familiar with HTML5 syntax and use JavaScript to help create web applications.&lt;br /&gt;&lt;br /&gt;The book starts out with some basics, showing you how HTML5 is utilizing the standards of HTML, CSS and JavaScript as defaults, and the fact that many of the strict type details that were part of HTML 4.01 and XHTML are integrated. &amp;nbsp;Games such as crossword puzzles, word matches, sample programs and workbook projects are included to help get the gist of how to use recognize the changes and see them in action. Interviews with HTML5 and JavaScript are also included (no, I didn’t just make that up :) ).&lt;br /&gt;&lt;br /&gt;The book then moves into JavaScript and explains the way JavaScript works, including a syntax run down, how to use it in simple programs, as well as how to put the scripts into web pages, and explains the Document Object Model (DOM) that is created and used to enact your JavaScript.&lt;br /&gt;&lt;br /&gt;Creating event handlers and interactive controls to a user is up next. By making a simple song selector, the user is shown how to make buttons and tie events to them, , along with creating new elements to hold information and display songs. The exercises help the user see how the code and page elements interact with each other.&lt;br /&gt;&lt;br /&gt;Functions and objects are next on the list. Chaining, constructors, and scope, oh my.&lt;br /&gt;&lt;br /&gt;Geolocation gets a chapter, meaning that we can make our pages and our code pieces &amp;nbsp;location aware (by using the Geolocation JavaScript API). This can be done at a GPS level or an IP address level, but in both cases, this chapter covers ways to say where you actually are.&lt;br /&gt;&lt;br /&gt;Web Services gets a chapter and a look at XMLHttpRequest, JSON, and JSONP, and shows when to use which, and how to fetch data at regular intervals to update the application you make (and with gumballs, no less).&lt;br /&gt;&lt;br /&gt;The Canvas chapter explains how to use the canvas element to physically draw out parts of the page. With a T-shirt design problem, we create a square, manipulate the pixels to create fills, fail gracefully and inform users if their browsers are too old to support canvas, and create functions to draw circles and other shapes. Creative text can be displayed as well.&lt;br /&gt;&lt;br /&gt;The Video tool allows developers to not just embed video in pages, there’s also playback, moving forward and backwards, handling different video formats, and embedding video images into objects that you have drawn onto the canvas tool. We also get to play with a variety of video formats including H.264, VP8 and Theora. Video also allows the user to use an API to focus on a variety of behavior.&lt;br /&gt;&lt;br /&gt;Web storage, or more commonly, localStorage, gets coverage and an explanation of how it differs from traditional “cookies”. Starting with the space (cookies max out at 4kB, localStorage gives you 5MB for each domain).&lt;br /&gt;&lt;br /&gt;The book rounds out with the topic of Web Helpers, the ability to spawn small JavaScript threads to take over the lengthier or more involved processes, so that the browser doesn’t wait forever for that particular process to finish (with an explanation of an exploration of Mandelbrot Sets just for fun).&lt;br /&gt;&lt;br /&gt;There are also a number of topics that didn’t get covered, such as Modernizr, Audio, jQuery, XHTML, SVG, Offline Web Apps, Web Sockets, more advanced Canvas API, Selectors API, and many other things that would make a book already 600 pages much thicker (especially since most pages are graphically structured with examples, puzzles and a lot of pictures).&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Bottom Line:&amp;nbsp;&lt;/b&gt;&lt;br /&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;It’s cutesey, it’s kitschy, it’s loaded with pictures, diagrams, and other stuff that may drive some people crazy (the “get to the point already” people), and I’d say that, for those people, they are probably already knowledgable enough to go beyond what this book offers anyway. If, however, you are like me, and don’t necessarily mind a variety of presentation options, and the “ooh shiny” quotient is high, and the need to have silly asides and corny jokes abound to keep you smiling, and engaged, then I have to say there’s a lot to like here.&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6890958153006612459-7846694643480923623?l=www.mkltesthead.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.mkltesthead.com/feeds/7846694643480923623/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6890958153006612459&amp;postID=7846694643480923623' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6890958153006612459/posts/default/7846694643480923623'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6890958153006612459/posts/default/7846694643480923623'/><link rel='alternate' type='text/html' href='http://www.mkltesthead.com/2012/02/book-review-head-first-html5.html' title='Book Review: Head First HTML5 Programming'/><author><name>Michael Larsen</name><uri>https://profiles.google.com/104738247543282839437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-L_ARsHiklGg/AAAAAAAAAAI/AAAAAAAABPA/PwBZuynaDbc/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6890958153006612459.post-6900459718833148923</id><published>2012-02-06T05:00:00.000-08:00</published><updated>2012-02-06T05:04:44.158-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='collaboration'/><category scheme='http://www.blogger.com/atom/ns#' term='life experience'/><category scheme='http://www.blogger.com/atom/ns#' term='weekend testing'/><category scheme='http://www.blogger.com/atom/ns#' term='testing techniques'/><title type='text'>Exploring Black Box Machines</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-dfwUTasQi8Y/Ty_PKLjLuAI/AAAAAAAABO4/HA0gHi6kOuo/s1600/WTlogo.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="71" src="http://2.bp.blogspot.com/-dfwUTasQi8Y/Ty_PKLjLuAI/AAAAAAAABO4/HA0gHi6kOuo/s320/WTlogo.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;On Saturday, I had the chance to step back and be a participant again for Weekend Testing. Albert developed and ran the session this time, and frankly, I think it was one of the best ones we've had.&lt;br /&gt;&lt;br /&gt;This session was called "&lt;a href="http://weekendtesting.com/archives/2393"&gt;Black Box Machine&lt;/a&gt;", and it was based around, you guessed it, testing a truly black box device. We really didn't have any idea what we had or what it did. It was a screen with a gauge, a red LED, a green LED, 4 blue buttons and 4 yellow buttons. Click on the experience report link above to see the machine layout we used.&lt;br /&gt;&lt;br /&gt;The buttons were functional, and combinations of the buttons controlled the lights and the gauge.&lt;br /&gt;&lt;br /&gt;I had a chance to work with and discuss the approach with Russ Poole, a newcomer to Weekend Testing. Often, we split into pairs for these sessions to do the actual testing, with an experienced Weekend tester working with someone who is new to the format, or a more experienced tester working with a less experienced tester. We took some time to acquaint ourselves with the machine and worked through the buttons to see what they did. Through exploration, trial and error and questioning, we made a mental model of what the device might be. We knew the mental model might be wrong, but it was useful for a time to help us describe what we were seeing, and use a common language between us. With this approach, we were able to divide and conquer the problem and determine what the machine did. Well, determine what we &lt;i&gt;thought&lt;/i&gt; the machine did.&lt;br /&gt;&lt;br /&gt;Each of the testers or pairs of testers did the same thing in the time frame we provided, and each group or individual presented their approach. It was interesting to see that each pair had a slightly different method to their testing and their vision of the problem. Each of us used heuristics to help us define the problem, and to come to some conclusions. I explained to Russ that our mental model may be correct, or it may not be. Still, as long as we kept learning about the product and could try out our ideas, we were able to determine at least on the surface what we thought the machine was doing.&lt;br /&gt;&lt;br /&gt;This exercise is built on a number of examples that &lt;a href="http://www.workroom-productions.com/black_box_machines.html"&gt;James Lyndsay&lt;/a&gt; developed, the entire purpose of these "machines" being to help people understand exploratory testing in a way that may get lost when working with known products. With everyday well known software applications, we can use some markers and guidelines to help us, and those familiar items and ideas will naturally guide how we test. Tthese machines are void of any natural context, and as such, we are basically left to our own deductive and inductive reasoning to figure out what's going on.&lt;br /&gt;&lt;br /&gt;Again, I think this was a fantastic session. My thanks to Albert Gareev for&amp;nbsp;facilitating&amp;nbsp;it, and my thanks to all of the participants for taking the time to come out and play with us on Saturday.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6890958153006612459-6900459718833148923?l=www.mkltesthead.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.mkltesthead.com/feeds/6900459718833148923/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6890958153006612459&amp;postID=6900459718833148923' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6890958153006612459/posts/default/6900459718833148923'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6890958153006612459/posts/default/6900459718833148923'/><link rel='alternate' type='text/html' href='http://www.mkltesthead.com/2012/02/exploring-black-box-machines.html' title='Exploring Black Box Machines'/><author><name>Michael Larsen</name><uri>https://profiles.google.com/104738247543282839437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-L_ARsHiklGg/AAAAAAAAAAI/AAAAAAAABPA/PwBZuynaDbc/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/-dfwUTasQi8Y/Ty_PKLjLuAI/AAAAAAAABO4/HA0gHi6kOuo/s72-c/WTlogo.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6890958153006612459.post-2636807558981925778</id><published>2012-02-02T11:30:00.000-08:00</published><updated>2012-02-02T11:31:30.936-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='education'/><category scheme='http://www.blogger.com/atom/ns#' term='collaboration'/><category scheme='http://www.blogger.com/atom/ns#' term='learning'/><category scheme='http://www.blogger.com/atom/ns#' term='Agile'/><category scheme='http://www.blogger.com/atom/ns#' term='life experience'/><title type='text'>Online Summit: Agile Transitions</title><content type='html'>&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://www.softwaretestpro.com/EventAssets/1164/STP-OS_FEB_2012%20_Main.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="99" src="http://www.softwaretestpro.com/EventAssets/1164/STP-OS_FEB_2012%20_Main.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;It looks like 2012 is shaping up to be a series of first for me. to that column I can now add "will present to an online forum a webinar/talk". How and when will I be doing that, you say?&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.softwaretestpro.com/Event/1164"&gt;I will be presenting at the SoftwareTestPro Online Summit for "Agile Transitions"&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I've had to go through my own "cultural shift" the past year as I've made my transition away from being a software tester in a traditional testing organization to being a tester embedded into an Agile team. My goal is to share some of my own experiences, pitfalls, adjustments and lessons learned, as well as to offer some tips specifically for Lone Testers who are finding themselves embedded in Agile teams, or interested in making the transition.&lt;br /&gt;&lt;br /&gt;The Online Summit will be held from Tuesday February 21 10:00AM until &amp;nbsp;Thursday February 23 1:30PM PST (each of the summit times will be three hours during that time period). The schedule is listed below (at least the schedule as it stands right now). My session is highlighted :).&lt;br /&gt;&lt;br /&gt;The cost of the summit is $195USD if you sign up before 2/14/12, it will be $245USD after that.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Scott Barber will be hosting this online summit, and he has gathered a number of different speakers to present on various topics. I will be speaking on the topic of being a Lone Tester making the transition to&amp;nbsp;Agile.&lt;br /&gt;&lt;br /&gt;The cool thing about this approach... you don't have to travel. Depending on your work arrangements, you may not even have to block out any specific time. These courses are each about an hour long and only cover three hours each day. The audio and video from each session will be recorded. If you miss a session, you will have access to all of the session recordings once the summit has ended.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The schedule as it currently stands is a follows:&lt;br /&gt;&lt;br /&gt;Tuesday February 21, 2012&lt;br /&gt;&lt;br /&gt;10:00- 10:10 AM PT&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;Welcome, Overview and Agenda&lt;br /&gt;&lt;br /&gt;10:15-11:15 AM PT&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;What is Agile and What's it Got to do With Testing?&lt;br /&gt;– Scott Barber&lt;br /&gt;&lt;br /&gt;11:10-11:20 AM PT&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;Break&lt;br /&gt;&lt;br /&gt;11:25-12:25 PM PT&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;How "Agilists" vs. "Traditionalists" View Testing&lt;br /&gt;– Robert Walsh&lt;br /&gt;&lt;br /&gt;12:20-12:30 PM PT&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;Break&lt;br /&gt;&lt;br /&gt;12:30-1:30 PM PT&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;Keys to Transitioning to Agile Testing: Lessons Learned from the Trenches&lt;br /&gt;– Bob Galen&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Wednesday February 22, 2012&lt;br /&gt;&lt;br /&gt;10:00- 10:05 AM PT&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;Day 2 Welcome and Agenda&lt;br /&gt;&lt;br /&gt;10:05-11:05 AM PT&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;The Secret to Successful Agile Test Automation&lt;br /&gt;– Lisa Crispin&lt;br /&gt;&lt;br /&gt;11:05-11:15 AM PT&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;Break&lt;br /&gt;&lt;br /&gt;11:15-12:15 PM PT&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;Culture &amp;amp; Inter-Focus Area Interactions&lt;br /&gt;– Selena Delesie&lt;br /&gt;&lt;br /&gt;12:15-12:25 PM PT&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;Break&lt;br /&gt;&lt;br /&gt;12:25-1:25 PM PT&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;Avoiding Agile Perversion&lt;br /&gt;– Lanette Creamer&lt;br /&gt;&lt;br /&gt;1:25-1:30 PM PT&lt;br /&gt;&amp;nbsp;Day 2 Summary and Closing Thoughts&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Thursday February 23, 2012&lt;br /&gt;&lt;br /&gt;10:00- 10:05 AM PT&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;Day 3 Welcome and Agenda&lt;br /&gt;&lt;br /&gt;10:05-11:05 AM PT&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;Excelling as an Agile Tester&lt;br /&gt;– Henrik Andersson&lt;br /&gt;&lt;br /&gt;11:05-11:15 AM PT&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;Break&lt;br /&gt;&lt;br /&gt;&lt;b style="background-color: yellow;"&gt;&lt;span style="color: red;"&gt;11:15-12:15 PM PT &amp;nbsp; &amp;nbsp; &amp;nbsp;The Lone Tester in an Agile World&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;b style="background-color: yellow;"&gt;&lt;span style="color: red;"&gt;– Michael Larsen&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;12:15-12:25 PM PT&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;Break&lt;br /&gt;&lt;br /&gt;12:25-1:25 PM PT&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;10 Tips for Agile Transitions &amp;amp; Panel Discussion&lt;br /&gt;– Scott Barber &amp;amp; Panel&lt;br /&gt;&lt;br /&gt;1:25-1:30 PM PT&lt;br /&gt;&amp;nbsp;Day 3 Summary and Closing Thoughts&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;Here's hoping I will see some of you there :).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6890958153006612459-2636807558981925778?l=www.mkltesthead.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.mkltesthead.com/feeds/2636807558981925778/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6890958153006612459&amp;postID=2636807558981925778' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6890958153006612459/posts/default/2636807558981925778'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6890958153006612459/posts/default/2636807558981925778'/><link rel='alternate' type='text/html' href='http://www.mkltesthead.com/2012/02/online-summit-agile-transitions.html' title='Online Summit: Agile Transitions'/><author><name>Michael Larsen</name><uri>https://profiles.google.com/104738247543282839437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-L_ARsHiklGg/AAAAAAAAAAI/AAAAAAAABPA/PwBZuynaDbc/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6890958153006612459.post-6965373999018915666</id><published>2012-01-31T06:00:00.000-08:00</published><updated>2012-01-31T06:02:10.091-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='education'/><category scheme='http://www.blogger.com/atom/ns#' term='teaching'/><category scheme='http://www.blogger.com/atom/ns#' term='learning'/><category scheme='http://www.blogger.com/atom/ns#' term='books'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='PRACTICUM'/><category scheme='http://www.blogger.com/atom/ns#' term='career development'/><title type='text'>Exercise 51: Getting Input From A Browser: Learn Ruby the Hard Way: Practicum</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://upload.wikimedia.org/wikipedia/commons/f/f1/Ruby_logo.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="200" src="http://upload.wikimedia.org/wikipedia/commons/f/f1/Ruby_logo.png" width="199" /&gt;&lt;/a&gt;&lt;/div&gt;All right, so we have a simple Sinatra framework up and running. Now let's see if we can do something just a little more exciting, shall we :)?&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;This time around, we'll make some interactive elements. We will submit text to our application by using that well known method, the form. Additionally, we'll look at ways that we can do automated testing for forms.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;How The Web Works (The Boring Bits)&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-NBBO3eaub6k/TyfxBsXGuDI/AAAAAAAABMw/It-sZErvdT8/s1600/http_request_diagram.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="133" src="http://1.bp.blogspot.com/-NBBO3eaub6k/TyfxBsXGuDI/AAAAAAAABMw/It-sZErvdT8/s320/http_request_diagram.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Zed's got this pretty well nailed down, so I'll let him tell this part :):&lt;br /&gt;&lt;br /&gt;&lt;i&gt;- You type in the url http://learnpythonthehardway.org/ into your browser and it sends the request out on line (A) to your computer's network interface.&lt;/i&gt;&lt;br /&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;br /&gt;&lt;i&gt;- Your request goes out over the internet on line (B) and then to the remote computer on line (C) where my server accepts the request.&lt;/i&gt;&lt;br /&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;br /&gt;&lt;i&gt;- Once my computer accepts it, my web application gets it on line (D), and my web application code runs the / (index) handler.&lt;/i&gt;&lt;br /&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;br /&gt;&lt;i&gt;- The response comes out of my web server when I return it, and goes back to your browser over line (D) again.&lt;/i&gt;&lt;br /&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;br /&gt;&lt;i&gt;- The server running this site takes the response off line (D) then sends it back over the internet on line (C).&lt;/i&gt;&lt;br /&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;br /&gt;&lt;i&gt;- The response from the server then comes off the internet on line (B), and your computer's network interface hands it to your browser on line (A).&lt;/i&gt;&lt;br /&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;br /&gt;&lt;i&gt;- Finally, your browser then displays the response.&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;Rather than go through a full breakdown of what the web terms mean, I'll let the reader take a look at Zed's very well done crash course explanation over at &lt;a href="http://ruby.learncodethehardway.org/book/ex51.html"&gt;http://ruby.learncodethehardway.org/book/ex51.html&lt;/a&gt; (chances are, if you've gotten this far with me, you already know the links and site very well.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;How Forms Work&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Let's take the lib/gothonweb.rb file make some changes to it:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-xYuZcOTyr1o/TyfxOV6iQOI/AAAAAAAABM4/Ty7HMKcO3Ks/s1600/Snapshot1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="242" src="http://1.bp.blogspot.com/-xYuZcOTyr1o/TyfxOV6iQOI/AAAAAAAABM4/Ty7HMKcO3Ks/s320/Snapshot1.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;- Restart Sinatra (hit CTRL-C and then run it again) to make sure it loads again&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-aT3BbnPfc38/TyfxUlh2igI/AAAAAAAABNA/GKrXFyCHtcg/s1600/Snapshot2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="178" src="http://4.bp.blogspot.com/-aT3BbnPfc38/TyfxUlh2igI/AAAAAAAABNA/GKrXFyCHtcg/s320/Snapshot2.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;- With your browser go to http://localhost:4567/hello which should display, "I just wanted to say Hello, Nobody."&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-F4_l1hsSn2Y/TyfxZPOnaFI/AAAAAAAABNI/1hqoWPL55WU/s1600/Snapshot3.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="301" src="http://4.bp.blogspot.com/-F4_l1hsSn2Y/TyfxZPOnaFI/AAAAAAAABNI/1hqoWPL55WU/s320/Snapshot3.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;- Next, change the URL in your browser to http://localhost:4567/hello?name=Frank and you'll see it say "Hello, Frank."&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-KW8mMYjXBHY/TyfxfMVUGnI/AAAAAAAABNQ/-Oh8M-vTVqo/s1600/Snapshot4.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="301" src="http://2.bp.blogspot.com/-KW8mMYjXBHY/TyfxfMVUGnI/AAAAAAAABNQ/-Oh8M-vTVqo/s320/Snapshot4.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Finally, change the name=Frank part to be your name. Now it's saying hello to you.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-MXFKrF_WmN4/TyfxjoWP_OI/AAAAAAAABNY/vVD4b4AkcV8/s1600/Snapshot+5.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="301" src="http://2.bp.blogspot.com/-MXFKrF_WmN4/TyfxjoWP_OI/AAAAAAAABNY/vVD4b4AkcV8/s320/Snapshot+5.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;So what have we done here?&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;- We're now using the "params" hash with a value of ":name" to get data from the browser. Sinatra takes all of the key/value pairs after the ? part of the URL and adds them to the params hash for you to work with.&lt;br /&gt;&lt;br /&gt;- The greeting is then constructed from the value of ":name". By default we set this to "Nobody". If we give it a name value on the command line, it changes it based on the "name=EnteredName" that we put in the URL after the "?"&lt;br /&gt;&lt;br /&gt;We can add more than one param on the command line, too if we modify the script to accept the changes.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;We can change the code to get params[:name] and params[:greet] as well like this:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-PUfNewcMcVA/Tyfxre6fAaI/AAAAAAAABNg/lHCbfQ5pMdw/s1600/Screenshot+6.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="178" src="http://3.bp.blogspot.com/-PUfNewcMcVA/Tyfxre6fAaI/AAAAAAAABNg/lHCbfQ5pMdw/s320/Screenshot+6.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;By default, it looks like this:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-BRDNifDjzCQ/TyfxvQrs29I/AAAAAAAABNo/StxHdaxqkAc/s1600/Screenshot+7.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="301" src="http://4.bp.blogspot.com/-BRDNifDjzCQ/TyfxvQrs29I/AAAAAAAABNo/StxHdaxqkAc/s320/Screenshot+7.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;And with the url values, it looks like this:&lt;br /&gt;&lt;br /&gt;Example:&lt;br /&gt;http://localhost:4567/hello?greet=Wassup&amp;amp;name=Michael&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-7rdhvlwTtyk/Tyfxz1_8rfI/AAAAAAAABNw/MPfiRIsJ5HM/s1600/Screenshot+8.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="301" src="http://3.bp.blogspot.com/-7rdhvlwTtyk/Tyfxz1_8rfI/AAAAAAAABNw/MPfiRIsJ5HM/s320/Screenshot+8.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Creating HTML Forms&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;OK, so we can pass the values through the URL, but let's face it, that's a pain. Most people expect to enter information in the browser directly and hit a button. this uses the time honored web feature called a form (or a POST form, to be more specific). A form is just an HTML file with a "form" tag in it. This form will collect information from the user, then send it to your web application just like you did above.&lt;br /&gt;&lt;br /&gt;Let's make a quick form to see how this works (this is being done in &amp;nbsp;lib/views/hello_form.erb):&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-ksbxvhT5sBs/Tyfx7j_MQ9I/AAAAAAAABN4/rqrJFrWqV3I/s1600/Screenshot+9.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="178" src="http://3.bp.blogspot.com/-ksbxvhT5sBs/Tyfx7j_MQ9I/AAAAAAAABN4/rqrJFrWqV3I/s320/Screenshot+9.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Now make some changes to gothonweb to be able to accept the form:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-KHiYTvMftIk/Tyfx_mXCwVI/AAAAAAAABOA/dhaJahjfq4g/s1600/Screenshot+10.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="178" src="http://4.bp.blogspot.com/-KHiYTvMftIk/Tyfx_mXCwVI/AAAAAAAABOA/dhaJahjfq4g/s320/Screenshot+10.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Once you've got those written up, simply restart the web application again and hit it with your browser like before.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-H-9hpqBAv70/TyfyHScFHGI/AAAAAAAABOI/gn4sWWkwpA8/s1600/Screenshot+11.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="301" src="http://3.bp.blogspot.com/-H-9hpqBAv70/TyfyHScFHGI/AAAAAAAABOI/gn4sWWkwpA8/s320/Screenshot+11.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-Efp28Vw7v64/TyfyH9fmcZI/AAAAAAAABOQ/5BbYOkXSdxY/s1600/Screenshot+12.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="301" src="http://4.bp.blogspot.com/-Efp28Vw7v64/TyfyH9fmcZI/AAAAAAAABOQ/5BbYOkXSdxY/s320/Screenshot+12.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;The part of the hello_form.erb file that makes this work is the line with &lt;br /&gt;&lt;form action="/hello" method="POST"&gt;. This tells your browser to:&lt;br /&gt;&lt;br /&gt;- Collect data from the user using the form fields inside the form.&lt;br /&gt;&lt;br /&gt;- Send them to the server using a POST type of request, which is just another browser request that "hides" the form fields.&lt;br /&gt;&lt;br /&gt;- Send that to the /hello URL (as shown in the action="/hello" part).&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Creating A Layout Template&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;For the final exercise, we'll be making a bunch of small HTML pages. Having to always code up a page each time will soon become tedious, so we'll create a simple "layout" template to wrap all of our pages with common headers and footers.&lt;br /&gt;&lt;br /&gt;So here's the change to lib/views/index.erb:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-6e6kXkyaA9k/TyfyRwNTnxI/AAAAAAAABOY/13X_ynodYs8/s1600/Screenshot+13.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="178" src="http://4.bp.blogspot.com/-6e6kXkyaA9k/TyfyRwNTnxI/AAAAAAAABOY/13X_ynodYs8/s320/Screenshot+13.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Change lib/views/hello_form.erb to be like this:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-_mM_CDgM3bM/TyfyXRMc5MI/AAAAAAAABOg/EsVqOzRs6As/s1600/Screenshot+14.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="178" src="http://4.bp.blogspot.com/-_mM_CDgM3bM/TyfyXRMc5MI/AAAAAAAABOg/EsVqOzRs6As/s320/Screenshot+14.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;This removes all of the general "boilerplate stuff" that every page will have at the top and the bottom, and now we'll make a layout page that contains all of that:&lt;br /&gt;&lt;br /&gt;Here's lib/views/layout.erb file that handles it for us from now on.&lt;br /&gt;&lt;br /&gt;Once you have those changes, create a lib/views/layout.erb file with this in it:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-937LKAKxgTs/Tyfyc2K9EWI/AAAAAAAABOo/fimKb9_rVAY/s1600/Screenshot+15.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="178" src="http://4.bp.blogspot.com/-937LKAKxgTs/Tyfyc2K9EWI/AAAAAAAABOo/fimKb9_rVAY/s320/Screenshot+15.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Writing Automated Tests For Forms&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;So now that we have made these changes, we could keep loading up the web page each time to see if we have made the correct changes... or we could use our unit tests to see if what we have put in works, too. The tester in me would like to see us do both, so lets do that :).&lt;br /&gt;&lt;br /&gt;Create the file test/test_gothonweb.rb with these contents:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-E_Sdo5YVNgo/TyfyntVx-YI/AAAAAAAABOw/zofzugZsZYE/s1600/Screenshot+16.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="178" src="http://4.bp.blogspot.com/-E_Sdo5YVNgo/TyfyntVx-YI/AAAAAAAABOw/zofzugZsZYE/s320/Screenshot+16.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Finally, run test/test_gothonweb.rb to test your web application:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;$ ruby test/test_gothonweb.rb&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;Loaded suite test/test_gothonweb&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;Started&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;Finished in 0.023839 seconds.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;1 tests, 9 assertions, 0 failures, 0 errors, 0 skips&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;Test run options: --seed 57414&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Note: what's being seen here is not what I am seeing. Maybe there is a step missing, but the framework appears to be running as expected. Again, it's a problem I'l tweak a bit more later.&lt;br /&gt;&lt;br /&gt;Zed explains that what is happening here is that we're importing the whole application from the lib/gothonweb.rb library, then running it manually.&lt;br /&gt;&lt;br /&gt;The rack/test library we have included has a very simple API for processing requests. Its get, put, post, delete, and head methods simulate the respective type of request on the application.&lt;br /&gt;&lt;br /&gt;- All mock request methods have the same argument signature:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;get '/path', params={}, rack_env={}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;- /path is the request path and may optionally include a query string.&lt;br /&gt;&lt;br /&gt;- params is a Hash of query/post parameters, a String request body, or nil.&lt;br /&gt;&lt;br /&gt;- rack_env is a Hash of Rack environment values. This can be used to set request headers and other request related information, such as session data.&lt;br /&gt;&lt;br /&gt;This works without running an actual web server so you can do tests with automated tests and also use your browser to test a running server.&lt;br /&gt;&lt;br /&gt;To validate responses from this function, use the assert_response function from test/test_gothonweb.rb which has:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;assert_response(resp, contains=nil, matches=nil, headers=nil, status=200)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;TESTHEAD's TAKEAWAYS:&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;This is pretty cool, again, this helps make a lot more sense out of what I've been seeing in the code and the rails applications that I use (the boilerplate loading up the header and the footer that's the same, and then the specific code elements being loaded as needed and only when needed, it's a beautiful thing. The Unit tests are not behaving the way that I expect them, to, but again, it's possible I'm missing something or I configured something wrong. Even without this specific aspect, I think the point has been made. Sinatra makes for an elegant little framework for running a server.&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/form&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6890958153006612459-6965373999018915666?l=www.mkltesthead.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.mkltesthead.com/feeds/6965373999018915666/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6890958153006612459&amp;postID=6965373999018915666' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6890958153006612459/posts/default/6965373999018915666'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6890958153006612459/posts/default/6965373999018915666'/><link rel='alternate' type='text/html' href='http://www.mkltesthead.com/2012/01/exercise-51-getting-input-from-browser.html' title='Exercise 51: Getting Input From A Browser: Learn Ruby the Hard Way: Practicum'/><author><name>Michael Larsen</name><uri>https://profiles.google.com/104738247543282839437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-L_ARsHiklGg/AAAAAAAAAAI/AAAAAAAABPA/PwBZuynaDbc/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/-NBBO3eaub6k/TyfxBsXGuDI/AAAAAAAABMw/It-sZErvdT8/s72-c/http_request_diagram.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6890958153006612459.post-2054622870147620466</id><published>2012-01-30T23:00:00.000-08:00</published><updated>2012-01-30T23:10:20.601-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='education'/><category scheme='http://www.blogger.com/atom/ns#' term='teaching'/><category scheme='http://www.blogger.com/atom/ns#' term='learning'/><category scheme='http://www.blogger.com/atom/ns#' term='books'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='PRACTICUM'/><category scheme='http://www.blogger.com/atom/ns#' term='career development'/><title type='text'>Exercise 50: Your First Website: Learn Ruby the Hard Way: Practicum</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://upload.wikimedia.org/wikipedia/commons/f/f1/Ruby_logo.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="200" src="http://upload.wikimedia.org/wikipedia/commons/f/f1/Ruby_logo.png" width="199" /&gt;&lt;/a&gt;&lt;/div&gt;Cool, we have finally reached the point where we interact with the web and web components using Ruby.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The example text uses the Sinatra framework.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Having heard of Sinatra in various places, I've been interested in seeing how to interact with it (and see how it differs from Rails, which is an environment I already use and test in my "day job" :).&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Installing Sinatra&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Using gem install Sinatra:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-9XYzkeW54q0/TyeNplD5pTI/AAAAAAAABLY/E4Nm0gLS-_I/s1600/Screen+shot+2012-01-30+at+9.55.30+PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="303" src="http://4.bp.blogspot.com/-9XYzkeW54q0/TyeNplD5pTI/AAAAAAAABLY/E4Nm0gLS-_I/s400/Screen+shot+2012-01-30+at+9.55.30+PM.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Make A Simple "Hello World" Project&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="font-weight: bold;"&gt;&lt;br /&gt;&lt;/div&gt;Now you're going to make an initial very simple "Hello World" web application and project directory using Sinatra. First, make your project directory, and then create the structure by running "bundle gem gothanweb (gothan being the game we've been working with for the past while):&lt;br /&gt;&lt;div style="font-weight: bold;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-aa_oklKzU5M/TyeN5Uq-5nI/AAAAAAAABLg/Mdz22HnCz6o/s1600/Screen+shot+2012-01-30+at+10.01.53+PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="303" src="http://4.bp.blogspot.com/-aa_oklKzU5M/TyeN5Uq-5nI/AAAAAAAABLg/Mdz22HnCz6o/s400/Screen+shot+2012-01-30+at+10.01.53+PM.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both;"&gt;Now let's make a very basic Sinatra application by putting the following code into lib/gothonweb.rb:&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-jTRL2rIfQhs/TyeOhIOhMII/AAAAAAAABLo/WzumbA0RwQ8/s1600/Screen+shot+2012-01-30+at+10.05.42+PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="303" src="http://3.bp.blogspot.com/-jTRL2rIfQhs/TyeOhIOhMII/AAAAAAAABLo/WzumbA0RwQ8/s400/Screen+shot+2012-01-30+at+10.05.42+PM.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both;"&gt;Then run the application like this:&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-N0U6MWD2A-U/TyeO5iwxjsI/AAAAAAAABLw/cbOuUlCFCQc/s1600/Screen+shot+2012-01-30+at+10.33.13+PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="212" src="http://3.bp.blogspot.com/-N0U6MWD2A-U/TyeO5iwxjsI/AAAAAAAABLw/cbOuUlCFCQc/s400/Screen+shot+2012-01-30+at+10.33.13+PM.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both;"&gt;Finally, use your web browser and go to the URL http://localhost:4567/.&lt;/div&gt;&lt;div class="separator" style="clear: both;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both;"&gt;Well, this is what I see:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-pMOYZlqW4ek/TyePFbMsO3I/AAAAAAAABL4/07KY2Gog28Y/s1600/Screen+shot+2012-01-30+at+10.15.49+PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="307" src="http://2.bp.blogspot.com/-pMOYZlqW4ek/TyePFbMsO3I/AAAAAAAABL4/07KY2Gog28Y/s400/Screen+shot+2012-01-30+at+10.15.49+PM.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both;"&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both;"&gt;&lt;b&gt;What's Going On?&lt;/b&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both;"&gt;&lt;i&gt;Here's what's happening when your browser hits your application:&lt;/i&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both;"&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both;"&gt;&lt;i&gt;- The browser makes a network connection to your own computer on port 4567.&lt;/i&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both;"&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both;"&gt;&lt;i&gt;- Once it connects, it makes an HTTP request to the lib/gothonweb.rb application and asks for the / URL, which is commonly the first URL on any website.&lt;/i&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both;"&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both;"&gt;&lt;i&gt;- Inside lib/gothonweb.rb there are blocks of code that map to URLs. The only one we have is the '/' mapping.&lt;/i&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both;"&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both;"&gt;&lt;i&gt;- Sinatra calls the matching block, which simply returns a string for what Sinatra should send to the browser.&lt;/i&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both;"&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both;"&gt;&lt;i&gt;- Finally, Sinatra has handled the request and sends this response to the browser which is what you are seeing.&lt;/i&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both;"&gt;&lt;b&gt;Fixing Errors&lt;/b&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both;"&gt;Comment out line 6 where you assign the greeting variable, then hit refresh in your browser.&amp;nbsp;&lt;/div&gt;&lt;div class="separator" style="clear: both;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-lQj6vJ-zFaI/TyePlmQ3OOI/AAAAAAAABMA/8RJ4Oy2F6cI/s1600/Screen+shot+2012-01-30+at+10.23.05+PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="274" src="http://4.bp.blogspot.com/-lQj6vJ-zFaI/TyePlmQ3OOI/AAAAAAAABMA/8RJ4Oy2F6cI/s320/Screen+shot+2012-01-30+at+10.23.05+PM.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-UwR8habyoDk/TyePmcvecyI/AAAAAAAABMI/qLUuNDOMruc/s1600/Screen+shot+2012-01-30+at+10.23.10+PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="252" src="http://1.bp.blogspot.com/-UwR8habyoDk/TyePmcvecyI/AAAAAAAABMI/qLUuNDOMruc/s320/Screen+shot+2012-01-30+at+10.23.10+PM.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both;"&gt;You should see an error page now that gives you lots of information on how your application just exploded. You know that the variable greeting is now missing, but Sinatra gives you this nice error page to track down exactly where. Do each of the following with this page:&lt;/div&gt;&lt;div class="separator" style="clear: both;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both;"&gt;- Look at the sinatra.error variable.&lt;/div&gt;&lt;div class="separator" style="clear: both;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both;"&gt;- Look at the REQUEST_ variables and see if they match anything you're already familiar with.&amp;nbsp;&lt;/div&gt;&lt;div class="separator" style="clear: both;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both;"&gt;- Uncomment line 6 and all returns back to normal.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Create Basic Templates&lt;/b&gt;&lt;br /&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;The following steps will make a properly formed "web page". This page used the embedded ruby extension [filename.erb]. It's stored in lib/views.&lt;br /&gt;&lt;br /&gt;The first step is to create a lib/views/index.erb file that looks like this:&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-Ad4stVP2t4k/TyeQHA7XbVI/AAAAAAAABMQ/2E5qjEXa35o/s1600/Screen+shot+2012-01-30+at+10.28.09+PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="286" src="http://4.bp.blogspot.com/-Ad4stVP2t4k/TyeQHA7XbVI/AAAAAAAABMQ/2E5qjEXa35o/s400/Screen+shot+2012-01-30+at+10.28.09+PM.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both;"&gt;Now we modifying the lib/gothonweb.rb script, so that Sinatra has a way to access the ERB file:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-PACZthVsnCI/TyeQY6gG1AI/AAAAAAAABMY/g7vBQBy7NMQ/s1600/Screen+shot+2012-01-30+at+10.33.22+PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="212" src="http://1.bp.blogspot.com/-PACZthVsnCI/TyeQY6gG1AI/AAAAAAAABMY/g7vBQBy7NMQ/s400/Screen+shot+2012-01-30+at+10.33.22+PM.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;So what happens if we reload the web page with these changes?&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-fDzQ-i_NO58/TyeQq2oOkVI/AAAAAAAABMg/QzlaTvfW26o/s1600/Screen+shot+2012-01-30+at+10.33.27+PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="314" src="http://1.bp.blogspot.com/-fDzQ-i_NO58/TyeQq2oOkVI/AAAAAAAABMg/QzlaTvfW26o/s320/Screen+shot+2012-01-30+at+10.33.27+PM.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;And just to show that it's properly formsed HTML...:&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-5fz0T4gc1GU/TyeQzuAdFhI/AAAAAAAABMo/AT9nfMCVRs8/s1600/Screen+shot+2012-01-30+at+10.34.08+PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="314" src="http://2.bp.blogspot.com/-5fz0T4gc1GU/TyeQzuAdFhI/AAAAAAAABMo/AT9nfMCVRs8/s320/Screen+shot+2012-01-30+at+10.34.08+PM.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both;"&gt;So what's going on here?&lt;/div&gt;&lt;div class="separator" style="clear: both;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both;"&gt;- In lib/gothonweb.rb we added an erb method call.&lt;/div&gt;&lt;div class="separator" style="clear: both;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both;"&gt;- The erb method loads .erb files out of the lib/views/ directory. We pass it index.erb because we're passing that as a parameter (erb :index ...).&lt;/div&gt;&lt;div class="separator" style="clear: both;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both;"&gt;- Now, when the browser hits / and lib/gothonweb.rb matches and executes the get '/' do block, instead of just returning the string greeting, it calls erb and pass greeting to it as a variable.&lt;/div&gt;&lt;div class="separator" style="clear: both;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both;"&gt;- Finally, the HTML in lib/views/index.erb contains Ruby code that tests the greeting variable, and prints a message using the greeting.&lt;/div&gt;&lt;div class="separator" style="clear: both;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both;"&gt;&lt;b&gt;TESTHEAD's TAKEAWAYS:&lt;/b&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both;"&gt;So this is a very simple and basic example, but it shows that we can fairly quickly develop a web site within a framework and use Ruby to pass variables for the values it would expect to see. That's pretty cool :).&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6890958153006612459-2054622870147620466?l=www.mkltesthead.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.mkltesthead.com/feeds/2054622870147620466/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6890958153006612459&amp;postID=2054622870147620466' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6890958153006612459/posts/default/2054622870147620466'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6890958153006612459/posts/default/2054622870147620466'/><link rel='alternate' type='text/html' href='http://www.mkltesthead.com/2012/01/exercise-50-your-first-website-learn.html' title='Exercise 50: Your First Website: Learn Ruby the Hard Way: Practicum'/><author><name>Michael Larsen</name><uri>https://profiles.google.com/104738247543282839437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-L_ARsHiklGg/AAAAAAAAAAI/AAAAAAAABPA/PwBZuynaDbc/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/-9XYzkeW54q0/TyeNplD5pTI/AAAAAAAABLY/E4Nm0gLS-_I/s72-c/Screen+shot+2012-01-30+at+9.55.30+PM.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6890958153006612459.post-5202390906153152330</id><published>2012-01-30T18:00:00.000-08:00</published><updated>2012-01-30T18:00:01.009-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='education'/><category scheme='http://www.blogger.com/atom/ns#' term='teaching'/><category scheme='http://www.blogger.com/atom/ns#' term='learning'/><category scheme='http://www.blogger.com/atom/ns#' term='books'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='PRACTICUM'/><category scheme='http://www.blogger.com/atom/ns#' term='career development'/><title type='text'>Exercise 49: Making Sentences: Learn Ruby the Hard Way: Practicum</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://upload.wikimedia.org/wikipedia/commons/f/f1/Ruby_logo.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="200" src="http://upload.wikimedia.org/wikipedia/commons/f/f1/Ruby_logo.png" width="199" /&gt;&lt;/a&gt;&lt;/div&gt;For the record, here's the point where people get moderately bent at programming books when they can't seem to figure something out. Again, this is my problem, not Zed or Rob's, but it does point out what often comes to be a challenge for many.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;When you get stuck on a concept, oftentimes, there really isn't a way to move forward until you figure it out. While I don't want to get all the way through the book and decide I'm stranded on one point, two exercises call for me to have my act together on this functionality (which makes perfect sense, because in life, you have to make the system work before you can add new features.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Thus, I'm reviewing this chapter with a significant handicap; I'm still stuck from Exercise 48.&lt;br /&gt;&lt;br /&gt;So if we have managed to get the lexicon scanner to work, we should see output that looks something like this:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre style="background-color: #eeffcc; border-bottom-color: rgb(204, 204, 204); border-bottom-style: solid; border-bottom-width: 1px; border-image: initial; border-left-color: rgb(204, 204, 204); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(204, 204, 204); border-right-style: solid; border-right-width: 1px; border-top-color: rgb(204, 204, 204); border-top-style: solid; border-top-width: 1px; font-family: Consolas, 'Deja Vu Sans Mono', 'Bitstream Vera Sans Mono', monospace; font-size: 0.95em; line-height: 15px; overflow-x: auto; overflow-y: hidden; padding-bottom: 0.5em; padding-left: 0.5em; padding-right: 0.5em; padding-top: 0.5em; text-align: left;"&gt;&lt;span class="go" style="color: #303030;"&gt;ruby-1.9.2-p180 :003 &amp;gt; print Lexicon.scan("go north")&lt;/span&gt;&lt;br /&gt;&lt;span class="go" style="color: #303030;"&gt;[#&amp;lt;struct Lexicon::Pair token=:verb, word="go"&amp;gt;,&lt;/span&gt;&lt;br /&gt;&lt;span class="go" style="color: #303030;"&gt;    #&amp;lt;struct Lexicon::Pair token=:direction, word="north"&amp;gt;] =&amp;gt; nil&lt;/span&gt;&lt;br /&gt;&lt;span class="go" style="color: #303030;"&gt;ruby-1.9.2-p180 :004 &amp;gt; print Lexicon.scan("kill the princess")&lt;/span&gt;&lt;br /&gt;&lt;span class="go" style="color: #303030;"&gt;[#&amp;lt;struct Lexicon::Pair token=:verb, word="kill"&amp;gt;,&lt;/span&gt;&lt;br /&gt;&lt;span class="go" style="color: #303030;"&gt;    #&amp;lt;struct Lexicon::Pair token=:stop, word="the"&amp;gt;,&lt;/span&gt;&lt;br /&gt;&lt;span class="go" style="color: #303030;"&gt;    #&amp;lt;struct Lexicon::Pair token=:noun, word="princess"&amp;gt;] =&amp;gt; nil&lt;/span&gt;&lt;br /&gt;&lt;span class="go" style="color: #303030;"&gt;ruby-1.9.2-p180 :005 &amp;gt; print Lexicon.scan("eat the bear")&lt;/span&gt;&lt;br /&gt;&lt;span class="go" style="color: #303030;"&gt;[#&amp;lt;struct Lexicon::Pair token=:verb, word="eat"&amp;gt;,&lt;/span&gt;&lt;br /&gt;&lt;span class="go" style="color: #303030;"&gt;    #&amp;lt;struct Lexicon::Pair token=:stop, word="the"&amp;gt;,&lt;/span&gt;&lt;br /&gt;&lt;span class="go" style="color: #303030;"&gt;    #&amp;lt;struct Lexicon::Pair token=:noun, word="bear"&amp;gt;] =&amp;gt; nil&lt;/span&gt;&lt;br /&gt;&lt;span class="go" style="color: #303030;"&gt;ruby-1.9.2-p180 :006 &amp;gt; print Lexicon.scan("open the door and smack the bear in the nose")&lt;/span&gt;&lt;br /&gt;&lt;span class="go" style="color: #303030;"&gt;[#&amp;lt;struct Lexicon::Pair token=:error, word="open"&amp;gt;,&lt;/span&gt;&lt;br /&gt;&lt;span class="go" style="color: #303030;"&gt;    #&amp;lt;struct Lexicon::Pair token=:stop, word="the"&amp;gt;,&lt;/span&gt;&lt;br /&gt;&lt;span class="go" style="color: #303030;"&gt;    #&amp;lt;struct Lexicon::Pair token=:noun, word="door"&amp;gt;,&lt;/span&gt;&lt;br /&gt;&lt;span class="go" style="color: #303030;"&gt;    #&amp;lt;struct Lexicon::Pair token=:error, word="and"&amp;gt;,&lt;/span&gt;&lt;br /&gt;&lt;span class="go" style="color: #303030;"&gt;    #&amp;lt;struct Lexicon::Pair token=:error, word="smack"&amp;gt;,&lt;/span&gt;&lt;br /&gt;&lt;span class="go" style="color: #303030;"&gt;    #&amp;lt;struct Lexicon::Pair token=:stop, word="the"&amp;gt;,&lt;/span&gt;&lt;br /&gt;&lt;span class="go" style="color: #303030;"&gt;    #&amp;lt;struct Lexicon::Pair token=:noun, word="bear"&amp;gt;,&lt;/span&gt;&lt;br /&gt;&lt;span class="go" style="color: #303030;"&gt;    #&amp;lt;struct Lexicon::Pair token=:stop, word="in"&amp;gt;,&lt;/span&gt;&lt;br /&gt;&lt;span class="go" style="color: #303030;"&gt;    #&amp;lt;struct Lexicon::Pair token=:stop, word="the"&amp;gt;,&lt;/span&gt;&lt;br /&gt;&lt;span class="go" style="color: #303030;"&gt;    #&amp;lt;struct Lexicon::Pair token=:error, word="nose"&amp;gt;] =&amp;gt; nil&lt;/span&gt;&lt;br /&gt;&lt;span class="go" style="color: #303030;"&gt;ruby-1.9.2-p180 :007 &amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;With this output, we should be able to now take the token pairs and make an actual sentence, using a Sentence class.&lt;br /&gt;&lt;br /&gt;Sentences can be structured simply by combining the following tokens (for English, anyway; different languages will have different rules):&lt;br /&gt;&lt;br /&gt;Subject Verb Object&lt;br /&gt;&lt;br /&gt;So the primary goal of the sentence class is to turn the lists of structs above into a Sentence object with a subject, verb, and object.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Match And Peek&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;To do this we need four tools:&lt;br /&gt;&lt;br /&gt;- A way to loop through the list of structs.&lt;br /&gt;&lt;br /&gt;- A way to "match" different types of structs that we expect in our Subject Verb Object setup.&lt;br /&gt;- A way to "peek" at a potential struct so we can make some decisions.&lt;br /&gt;- A way to "skip" things we do not care about, like stop words.&lt;br /&gt;- We use the peek function to say look at the next element in our struct array, and then match to take one off and work with it.&lt;br /&gt;&lt;br /&gt;So here is the first peek function:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;def peek(word_list)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; begin&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; &amp;nbsp; word_list.first.token&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; rescue&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; &amp;nbsp; nil&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; end&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;This is the match function:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;def match(word_list, expecting)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; begin&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; &amp;nbsp; word = word_list.shift&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; &amp;nbsp; if word.token == expecting&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; word&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; &amp;nbsp; else&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; nil&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; &amp;nbsp; end&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; rescue&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;nil&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; end&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;This is the skip function:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;def skip(word_list, word_type)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; while peek(word_list) == word_type&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; &amp;nbsp; match(word_list, word_type)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; end&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;The Sentence Grammar&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;To build our Sentence objects from the struct array, we can do the following:&lt;br /&gt;&lt;br /&gt;- Identify the next word with peek.&lt;br /&gt;&lt;br /&gt;- If that word fits the grammar, call a function to handle that part of the grammar&lt;br /&gt;&lt;br /&gt;- If it doesn't, raise an error (see below).&lt;br /&gt;&lt;br /&gt;When we're all done, we should have a Sentence object to work with in our game.&lt;br /&gt;&lt;br /&gt;So this time, instead of being given the test and trying to figure out the code, this time, we get the code and we then figure out how to write the test to meet the requirements.&lt;br /&gt;&lt;br /&gt;Here's the code for parsing simple sentences using the ex48 Lexicon class:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-yF_XTPHY5gI/TydJhZ-H15I/AAAAAAAABLA/fGfP7g5xBeE/s1600/Screen+shot+2012-01-30+at+5.49.10+PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://3.bp.blogspot.com/-yF_XTPHY5gI/TydJhZ-H15I/AAAAAAAABLA/fGfP7g5xBeE/s320/Screen+shot+2012-01-30+at+5.49.10+PM.png" width="262" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-W6x3-irVf8A/TydJlkG0TMI/AAAAAAAABLI/87vNtT3h2To/s1600/Screen+shot+2012-01-30+at+5.49.48+PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="310" src="http://2.bp.blogspot.com/-W6x3-irVf8A/TydJlkG0TMI/AAAAAAAABLI/87vNtT3h2To/s320/Screen+shot+2012-01-30+at+5.49.48+PM.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-EdnEaO3jkDo/TydJl9GiXlI/AAAAAAAABLQ/n4EEwseNwq4/s1600/Screen+shot+2012-01-30+at+5.49.58+PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="233" src="http://4.bp.blogspot.com/-EdnEaO3jkDo/TydJl9GiXlI/AAAAAAAABLQ/n4EEwseNwq4/s320/Screen+shot+2012-01-30+at+5.49.58+PM.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;The sections below are advice given by Zed and Rob. It's printed in italic to show it's their words verbatim.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;A Word On Modules&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;i&gt;This code uses something in Ruby called a "module" named Parser. A module (created with module Parser) is a way to package up the functions so that they don't conflict with other parts of Ruby. In Ruby 1.9 there was a change to the testing system that created a skip method which conflicted with the Parser.skip method. The solution was to do what you see here and wrap all the functions in this module.&lt;/i&gt;&lt;br /&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;br /&gt;&lt;i&gt;You use a module by simply calling functions on it with the . operator, similar to an object you've made. In this case if you wanted to call the parse_verb() function you'd write Parser.parse_verb(). You'll see a demonstration of this when I give you a sample unit test.&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;What You Should Test&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;i&gt;For Exercise 49 is write a complete test that confirms everything in this code is working. That includes making exceptions happen by giving it bad sentences. Here is a starter sample so you can see how you would call a function in a module:&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;require 'test/unit'&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;require_relative '../lib/ex49'&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;class ParserTests &amp;amp;lt; Test::Unit::TestCase&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; &amp;nbsp; def test_parse_verb()&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; # WARNING: THIS FAILS ON PURPOSE SEE THE BOOK&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Parser.parse_verb([false])&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; &amp;nbsp; end&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;i&gt;You can see I make the basic test class, then create a test_parse_verb to test out the Parser.parse_verb function. I don't want to do the work for you, so I've made this fail on purpose. This shows you how to use the Parser module and call functions on it, and you should work on making this test actually test all the code.&lt;/i&gt;&lt;br /&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;br /&gt;&lt;i&gt;Check for an exception by using the function assert_raise from the Test::Unit documentation. Learn how to use this so you can write a test that is expected to fail, which is very important in testing. Learn about this function (and others) by reading the Test::Unit documentation.&lt;/i&gt;&lt;br /&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;br /&gt;&lt;i&gt;When you are done, you should know how this bit of code works, and how to write a test for other people's code even if they do not want you to. Trust me, it's a very handy skill to have.&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Extra Credit&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;- &amp;nbsp;Change the parse_ methods and try to put them into a class rather than be just methods. Which design do you like better?&lt;br /&gt;- Make the parser more error resistant so that you can avoid annoying your users if they type words your lexicon doesn't understand.&lt;br /&gt;- Improve the grammar by handling more things like numbers.&lt;br /&gt;- Think about how you might use this Sentence class in your game to do more fun things with a user's input.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6890958153006612459-5202390906153152330?l=www.mkltesthead.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.mkltesthead.com/feeds/5202390906153152330/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6890958153006612459&amp;postID=5202390906153152330' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6890958153006612459/posts/default/5202390906153152330'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6890958153006612459/posts/default/5202390906153152330'/><link rel='alternate' type='text/html' href='http://www.mkltesthead.com/2012/01/exercise-49-making-sentences-learn-ruby.html' title='Exercise 49: Making Sentences: Learn Ruby the Hard Way: Practicum'/><author><name>Michael Larsen</name><uri>https://profiles.google.com/104738247543282839437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-L_ARsHiklGg/AAAAAAAAAAI/AAAAAAAABPA/PwBZuynaDbc/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/-yF_XTPHY5gI/TydJhZ-H15I/AAAAAAAABLA/fGfP7g5xBeE/s72-c/Screen+shot+2012-01-30+at+5.49.10+PM.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6890958153006612459.post-6672145264549778700</id><published>2012-01-30T15:00:00.000-08:00</published><updated>2012-01-30T15:33:29.007-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='software testing'/><category scheme='http://www.blogger.com/atom/ns#' term='cucumber'/><category scheme='http://www.blogger.com/atom/ns#' term='books'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='Rspec'/><title type='text'>Book Review: The Cucumber Book</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://imagery.pragprog.com/products/216/hwcuc.jpg?1310390511" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://imagery.pragprog.com/products/216/hwcuc.jpg?1310390511" width="266" /&gt;&lt;/a&gt;&lt;/div&gt;One of the cool things about &lt;a href="http://pragprog.com/"&gt;Pragmatic Publishing&lt;/a&gt; is the fact that they make it possible to get your hands on Beta books, meaning you get the chance to see a book as its actively being developed. &lt;a href="http://pragprog.com/book/hwcuc/the-cucumber-book"&gt;The Cucumber Book&lt;/a&gt; was one of those books, and as such, I’ve had the benefit of looking at and reviewing this book for the past several months, and have watched it grow into the book that is today (and now available in print form).&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Most people who have a passing understanding of Test Driven Development or Behavior Driven Development have likely heard of Cucumber.  It’s a language that allows anyone who wants to define tests and requirements for applications the ability to do so in plain English (or fill in the blank language if supported). In truth, Cucumber isn’t really a programming language at all, but a symbolic phrase library that matches to various underlying commands and blocks of code (represented in Ruby in this book and referencing a variety of tools including Capybara, Rspec and others). &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Matt Wynne and Aslak Hellesøy have put together a very readable and focused text that help the user get familiar with the basics of the language. The book also focuses the reader on understanding the underpinnings needed to create expressions that work with their respective technologies. Granted, if you are a tester and you want to take advantage of this framework, there is plenty in here to keep you busy. The Cucumber Book starts out by explaining what Cucumber is and the niche it is meant to fill (specifications based tests and requirements). If you are a developer, there is likewise plenty in here to keep you interested, too.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The process in the Cucumber book is heavy on examples and showing how the examples work. Yes, for those who want to know how to use the syntax and language specific details of Cucumber, that stuff is covered. What is also covered, and covered well, is the Behavioral Driven Development approach needed to effectively create tests and have them work effectively. Along with creating feature files and steps for those feature files, the underlying step definitions also have to be coded. Not only do they have to be coded, but they have to have assertions written that will effectively confirm if the step has passed, or if it fails, and why. &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Since the book is primarily based on Cucumber, there is a large section that covers Cucumber fundamentals, including basic Gherkin (the underlying syntax that Cucumber uses), and the ability of using expressive options such as Scenario Outlines, Data tables, Doc Strings, tags, and dealing with some of the pain points seen in your tests (such as "flickering scenarios", where the tests pass some of the time but fail some times, too). More than just using Cucumber to define steps and have step definitions defined, the third part of the book deals with applying Cucumber to a number of different technologies; working with various databases, testing with RESTful web services, working with Rails, running tests and using capybara to simulate common browser actions and many other options that may come to play in your everyday testing life. &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Bottom Line: &lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;If you have ever been interested in looking at Cucumber and your testing environment is built around Ruby, then this will be an ideal book to use. If you are interested in deploying Cucumber in another type of environment, such as testing with Java or .NET, many of the ideas in this book will also carry over, but have a look at “&lt;a href="http://cuke4ninja.com/"&gt;The Secret Ninja Cucumber Scrolls&lt;/a&gt;” by David de Florinier and Gojko Adzic. It provides information about how to apply Cucumber to those environments. Regardless of your particular focus and environment needs, for a practical and effective book for learning and using Cucumber in a meaningful way, &lt;a href="http://pragprog.com/book/hwcuc/the-cucumber-book"&gt;The Cucumber Book&lt;/a&gt; is an excellent addition to any tester or developer’s library.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6890958153006612459-6672145264549778700?l=www.mkltesthead.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.mkltesthead.com/feeds/6672145264549778700/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6890958153006612459&amp;postID=6672145264549778700' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6890958153006612459/posts/default/6672145264549778700'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6890958153006612459/posts/default/6672145264549778700'/><link rel='alternate' type='text/html' href='http://www.mkltesthead.com/2012/01/book-review-cucumber-book.html' title='Book Review: The Cucumber Book'/><author><name>Michael Larsen</name><uri>https://profiles.google.com/104738247543282839437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-L_ARsHiklGg/AAAAAAAAAAI/AAAAAAAABPA/PwBZuynaDbc/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6890958153006612459.post-6127674674696825966</id><published>2012-01-30T07:00:00.000-08:00</published><updated>2012-01-30T07:23:28.298-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='education'/><category scheme='http://www.blogger.com/atom/ns#' term='teaching'/><category scheme='http://www.blogger.com/atom/ns#' term='learning'/><category scheme='http://www.blogger.com/atom/ns#' term='books'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='PRACTICUM'/><category scheme='http://www.blogger.com/atom/ns#' term='career development'/><title type='text'>Exercise 48: Advanced User Input: Learn Ruby the Hard Way: Practicum</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://upload.wikimedia.org/wikipedia/commons/f/f1/Ruby_logo.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="200" src="http://upload.wikimedia.org/wikipedia/commons/f/f1/Ruby_logo.png" width="199" /&gt;&lt;/a&gt;&lt;/div&gt;So it's been awhile since I've posted one of these practicum updates. I could say there's a lot of reasons why. I got sidetracked into doing a tester's autobiography, or that my work and family life&amp;nbsp;accelerated&amp;nbsp;into areas that I needed to get taken acare of and this had to take a back burner. I could say all of those things, but they'd be excuses. No, the reason why I haven't&amp;nbsp;posted&amp;nbsp;in awhile is that, well, I'm stuck.&lt;br /&gt;&lt;br /&gt;this is the first assignment I have not been able to get to work, and I think it's because of what it requires us to do. zed has given us a test, and we are to write the code to make the tests pass. So far, I've not been able to do it. that probably says a whole lot more about me&amp;nbsp;than&amp;nbsp;it does Zed, but be that as it may, I cannot call this project complete or objective if I only post the things I can do well. I said I'd also post the areas I was struggling with, and well, here they are:&lt;br /&gt;&lt;br /&gt;The point to this assignment is that, right now, if we want to use our game and answer questions in the game, we have to be exact in our terminology. "Open the Door" is OK, but:&lt;br /&gt;&lt;br /&gt;- open door&lt;br /&gt;- go THROUGH the door&lt;br /&gt;&lt;br /&gt;will cause an error or not give us the right response, even though they are saying the same thing.&lt;br /&gt;&lt;br /&gt;the goal is that we want to write some classes that will work as a library of possible responses, and in this regard, we want to do the following:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;- We have Words separated by spaces.&lt;br /&gt;- We have Sentences composed of the words.&lt;br /&gt;- We have Grammar that structures the sentences into meaning.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Our Game Lexicon&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;In our game we have to create a Lexicon of words:&lt;br /&gt;&lt;br /&gt;Direction words: north, south, east, west, down, up, left, right, back.&lt;br /&gt;Verbs: go, stop, kill, eat.&lt;br /&gt;Stop words: the, in, of, from, at, it&lt;br /&gt;Nouns: door, bear, princess, cabinet.&lt;br /&gt;Numbers: any string of 0 through 9 characters.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Breaking Up A Sentence&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;The process to break up a sentence into individual words is fairly simple, and looks like this:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;stuff = gets.chomp()&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;words = stuff.split()&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Below is what Zed and Rob provide to help us understand what is happening. On the surface, I get what they are saying, but getting my left hand to get what the right hand is doing, I'm still working through (note, if I figure this out, or someone helps me through this, I will post the solution provided and credit to the person who helps me figure it out :) ).&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Lexicon Structs&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;i&gt;Once we know how to break up a sentence into words, we just have to go through the list of words and figure out what "type" they are. To do that we're going to use a handy little Ruby structure called a "struct". A struct is a convenient way to bundle a number of attributes together, using accessor methods, without having to write an explicit class. It's created like this:&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;Pair = Struct.new(:token, :word)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;first_word = Pair.new("direction", "north")&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;second_word = Pair.new("verb", "go")&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;sentence = [first_word, second_word]&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;i&gt;This creates a pair of (TOKEN, WORD) that lets you look at the word and do things with it.&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Scanning Input&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;i&gt;Now you are ready to write your scanner. This scanner will take a string of input from a user and return a sentence that's composed of a list of structs with the (TOKEN, WORD) pairings. If a word isn't part of the lexicon then it should still return the WORD, but set the TOKEN to an error token. These error tokens will tell the user they messed up.&lt;/i&gt;&lt;br /&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;br /&gt;&lt;i&gt;Here's where it gets fun. I'm not going to tell you how to do this. Instead I'm going to write a unit test und you are going to write the scanner so that the unit test works.&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Exceptions And Numbers&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;i&gt;An area that Zed has provided for us to consider when it comes to converting numbers:&lt;/i&gt;&lt;br /&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;br /&gt;&lt;i&gt;There is one tiny thing I will help you with first, and that's converting numbers. In order to do this though, we're going to cheat and use exceptions. An exception is an error that you get from some function you may have run. What happens is your function "raises" an exception when it encounters an error, then you have to handle that exception. For example, if you type this into IRB:&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;ruby-1.9.2-p180 :001 &amp;gt; Integer("hell")&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;ArgumentError: invalid value for Integer(): "hell"&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; &amp;nbsp; from (irb):1:in `Integer'&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; &amp;nbsp; from (irb):1&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; &amp;nbsp; from /home/rob/.rvm/rubies/ruby-1.9.2-p180/bin/irb:16:in `&lt;main&gt;'&lt;/main&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;i&gt;That ArgumentError is an exception that the Integer() function threw because what you handed Integer() is not a number. The Integer() function could have returned a value to tell you it had an error, but since it only returns numbers, it'd have a hard time doing that. It can't return -1 since that's a number. Instead of trying to figure out what to return when there's an error, the Integer() function raises the TypeError exception and you deal with it.&lt;/i&gt;&lt;br /&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;br /&gt;&lt;i&gt;You deal with an exception by using the begin and rescue keywords:&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;def convert_number(s)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; begin&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; &amp;nbsp; Integer(s)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; rescue ArgumentError&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; &amp;nbsp; nil&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; end&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;i&gt;You put the code you want to "begin" inside the begin block, and then you put the code to run for the error inside the rescue. In this case, we want to call Integer() on something that might be a number. If that has an error, then we "rescue" it and return nil instead.&lt;/i&gt;&lt;br /&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;br /&gt;&lt;i&gt;In your scanner that you write, you should use this function to test if something is a number. You should also do it as the last thing you check for before declaring that word an error word.&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;What You Should Test&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Here are the files test/test_lexicon.rb that I am working with:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-XxMfp-FBbYU/Tya0vy84SnI/AAAAAAAABKg/L20Dm6-Vfg0/s1600/Screen+shot+2012-01-30+at+7.17.01+AM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="311" src="http://1.bp.blogspot.com/-XxMfp-FBbYU/Tya0vy84SnI/AAAAAAAABKg/L20Dm6-Vfg0/s320/Screen+shot+2012-01-30+at+7.17.01+AM.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-6avQZdnPWrU/Tya0wA-gAeI/AAAAAAAABKo/IzlkfGo5ohg/s1600/Screen+shot+2012-01-30+at+7.17.23+AM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="256" src="http://4.bp.blogspot.com/-6avQZdnPWrU/Tya0wA-gAeI/AAAAAAAABKo/IzlkfGo5ohg/s320/Screen+shot+2012-01-30+at+7.17.23+AM.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;b&gt;Design Hints&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Focus on getting one test working at a time. Keep this simple and just put all the words in your lexicon in lists that are in your lexicon.rb file. Do not modify the input list of words, but instead make your own new list with your lexicon pairs in it. Also, use the include? method with these lexicon arrays to check if a word is in the lexicon.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Extra Credit&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;- Improve the unit test to make sure you cover more of the lexicon.&lt;br /&gt;- Add to the lexicon and then update the unit test.&lt;br /&gt;- Make your scanner handles user input in any capitalization and case.&lt;br /&gt;- Update the test to make sure this actually works.&lt;br /&gt;- Find another way to convert the number.&lt;br /&gt;- My solution was 37 lines long. Is yours longer? Shorter?&lt;br /&gt;&lt;br /&gt;&lt;b&gt;TESTHEAD's TAKEAWAY:&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Test Driven Development is not as easy as it seems, at least as I currently understand it. Again, I'm not blaming Zed or Rob here, I'm blaming myself for not quite geting how to do this. this and the next ercise are by necessity going to need to be considered "open ended" for the time being until I can grok what I need to do to make this work. Sometimes that takes beating against it, sometimes it means doing something else until I can see the connection. Either way, my goal was to review and complete this by the end of January, and I'm running low on time now, so I need to get a move on and come backto this one later.&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6890958153006612459-6127674674696825966?l=www.mkltesthead.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.mkltesthead.com/feeds/6127674674696825966/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6890958153006612459&amp;postID=6127674674696825966' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6890958153006612459/posts/default/6127674674696825966'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6890958153006612459/posts/default/6127674674696825966'/><link rel='alternate' type='text/html' href='http://www.mkltesthead.com/2012/01/exercise-48-advanced-user-input-learn.html' title='Exercise 48: Advanced User Input: Learn Ruby the Hard Way: Practicum'/><author><name>Michael Larsen</name><uri>https://profiles.google.com/104738247543282839437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-L_ARsHiklGg/AAAAAAAAAAI/AAAAAAAABPA/PwBZuynaDbc/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/-XxMfp-FBbYU/Tya0vy84SnI/AAAAAAAABKg/L20Dm6-Vfg0/s72-c/Screen+shot+2012-01-30+at+7.17.01+AM.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6890958153006612459.post-1026438698882660377</id><published>2012-01-30T05:00:00.000-08:00</published><updated>2012-01-30T05:05:31.150-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Two Leaf Clover'/><category scheme='http://www.blogger.com/atom/ns#' term='people'/><category scheme='http://www.blogger.com/atom/ns#' term='philosophy'/><title type='text'>Maybe There's a Better Way (Thank You, Two Leaf Clover :) )</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://twoleafclover.net/comics/2012-01-30-One-For-The-Road.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="640" src="http://twoleafclover.net/comics/2012-01-30-One-For-The-Road.png" width="461" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;As many of you know, &lt;a href="http://twoleafclover.net/"&gt;Aaron Scott&lt;/a&gt; and I have been doing some cross pollination with each other's sites. When he posts something that I think might elicit a fun or insightful post on my end, I use one of his cartoons to help illustrate the point. It's been my hope also that I've helped some testers discover his strip, &lt;a href="http://twoleafclover.net/"&gt;Two Leaf Clover&lt;/a&gt; and enjoy it as well.&lt;br /&gt;&lt;br /&gt;Well, Aaron did something cool for me today. He made a cartoon just for me (well, for everyone really, but it's something we talked about a number of times). This strip will now reside on TESTHEAD permanently in the upper corner as a reminder to all of us, that we don't have to accept what has come before, and that the traditions of old need not define our future.&lt;br /&gt;&lt;br /&gt;As some have seen in the past, the "mascot" of the TESTHEAD site is the crash test dummy. It's a metaphor for getting information without us getting hurt. Of course, I've used the crash test dummy as a metaphor for myself as a tester. How often do I just go in and do stuff that doesn't seem to make any sense? How often do I run through endless checklists of steps because "we've always done it that way?" I told Aaron that I wanted to see TESTHEAD and other testing blogs be a way to help "empower the dummies" so that they don't have to specifically just be launched at walls, that they could say "maybe there are better ways to do things that we haven't considered yet".&lt;br /&gt;&lt;br /&gt;Oh, and I think it's pretty cute, too.&lt;br /&gt;&lt;br /&gt;So again, my thanks to Aaron for effectively making a TESTHEAD specific cartoon, and one that I can show, well, for always on here. It's much appreciated. For those who are not familiar with &lt;a href="http://twoleafclover.net/"&gt;Two Leaf Clover&lt;/a&gt;, go pay Aaron's site a visit :).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6890958153006612459-1026438698882660377?l=www.mkltesthead.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.mkltesthead.com/feeds/1026438698882660377/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6890958153006612459&amp;postID=1026438698882660377' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6890958153006612459/posts/default/1026438698882660377'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6890958153006612459/posts/default/1026438698882660377'/><link rel='alternate' type='text/html' href='http://www.mkltesthead.com/2012/01/maybe-theres-better-way-thank-you-two.html' title='Maybe There&apos;s a Better Way (Thank You, Two Leaf Clover :) )'/><author><name>Michael Larsen</name><uri>https://profiles.google.com/104738247543282839437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-L_ARsHiklGg/AAAAAAAAAAI/AAAAAAAABPA/PwBZuynaDbc/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6890958153006612459.post-586722986371034334</id><published>2012-01-29T08:30:00.000-08:00</published><updated>2012-01-30T05:36:28.210-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='goals'/><category scheme='http://www.blogger.com/atom/ns#' term='software testing'/><category scheme='http://www.blogger.com/atom/ns#' term='skills development'/><category scheme='http://www.blogger.com/atom/ns#' term='learning'/><category scheme='http://www.blogger.com/atom/ns#' term='life experience'/><title type='text'>Where I Am Today: A Meandering Walk Through Twenty Years of Software Testing</title><content type='html'>As I made my way into the small loft on the fourth floor of an old brick building on Jessie Street in the South of Market area of San Francisco, I had a new opportunity to start over again with a different kind of company. When SideReel hired me, they were focusing on developing a solid Agile team and releasing software regularly. Like many organizations, they were heavily involved with Test Driven Development and doing much of their testing within their group. It worked in some areas but they wanted to have a better idea from outside of their group as far as testing was concerned, and that's where I came in.&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;SideReel, for those who are not familiar, is a television aggregator. It allows users to find, watch and keep track of television shows, movies, and WebTV programs. We have also made pushes to share that information with other users and help make it a "social" experience, so that, if you want to, you can recommend shows to others and let them know what you are watching. It's a pure web and mobile play, which means that the site is 100% online, and all of the assets of the site and software are deployed online as well. No software needs to be downloaded and installed, but browser compatibility and appearance is a big deal, and something I spend a fair amount of time with.&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;At the time, SideReel had been around for about three years, and had started in the living room of one of the founders, and had grown over time. While they were larger and had a bigger business than Tracker did when I got there, that same "family vibe" was&amp;nbsp;definitely&amp;nbsp;there, and I liked that a lot. I knew that I had a chance to be involved in something very different than anything I'd worked with in the past, and that was what was most appealing about the opportunity.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I had worked in many different types of environments, but Agile was a new experience. While Tracker had tried&amp;nbsp;examining&amp;nbsp;and implementing some elements of it into our process, this was the first time I'd seen a team that actively practiced it in most of their development work. I found the first few weeks when I was there, when I started working on test plans the way I always had, to be enlightening. Rather than having to spend so much of my time working with writing test plans that were scripted out, I was encouraged instead to examine the stories in the tracking system we were using, and to append my tests there. What? No over arching test plan? No long term back and forth over the quantity and details of plans? How crazy was that? It turns out, not so crazy at all. While it seemed odd to have everything associated with just an individual story, it made sense since the stories in question were sliced so thin that the functionality was encapsulated in those areas, and therefore my tests were realistically touching just a few areas; I could focus them into just the parameters of an individual story. I liked this model because it actually fit better with the notion I had of what &amp;nbsp;tester actually did, which was to provide information about what a product does, and allow me to focus on the areas that actually mattered. With the use of Continuous Integration for each check in, we had much of the regression areas covered (not all, as I would find out, but a lot of them).&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;SideReel places a lot of value on exploratory testing, and it felt good to actually be able to apply that in a real sense. It's not that other places didn't value it, but that it was an area that wasn't really understood or given much focus in the past. Having a team that had taken the Test Driven Development approach to heart and emphasizing writing tests before writing code certainly helped in that regard. They also provided a large library of tests that had been written so that I could see what they were looking for at the code level and expand on it to see if there were other questions I could ask and get involved with.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;This wild world of start-up madness, I would discover, would be short lived. I was only with the company for six weeks when I found out that SideReel was to be acquired by Rovi Corporation, which was itself an owner of numerous companies related to video an audio content, information and other properties related to entertainment (their holdings included Sonic Solutions, Roxio, AllMusic, Divx and several other brands). We were told that, while we would be part of a larger organization's structure and business model, our day to day operations as SideReel would largely go unchanged. While we would relocate to a new building and have our own area of that building, we would still be operating as though we were the same 20 people that were in the walk up flat on Jessie Street.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;As we started to make the changeover, I was challenged by the development team to actively learn and get involved with writing automated tests for SideReel. My goal was to work from the idea that I didn't have access to the fundamentals of the code, and to focus on the front facing user experience wherever possible. The goal was to put together a battery of smoke tests that would give us confidence that any new features rolled in would not cause undue problems or challenges to our users. With that, I began to spend a lot more time learning about Cucumber, the underlying tools that worked with it (Capybara and RSpec), and learning as much Ruby as I could. This was a first. While in the past my ability to use automation and computer assisted testing was left to me to do as much or as little as I wanted, the goal of SideReel was to have me be as knowledgeable as possible of the test driven development approach that they used.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;During this year, there was also a big emphasis on my part to write a lot more. TESTHEAD was one of those mediums, but so was getting published in various online journals related to software testing. It seems each time I had a chance to write something for one journal, another would contact me and ask if I could write for them as well. 2011 also saw the "How to Reduce the Cost of Software Testing" book be released and, needless to say, I was excited to be a part of that title and to be able to share with my management team that I was a contributor to that project. My goal was to show them that they had a dedicated and involved tester who was excited about being actively engaged in the testing community. I also enjoyed the opportunities that I had when various testers would come to the Bay area and we'd be able to get together and talk about developments and opportunities. I got involved with taking and then teaching the Bug Advocacy class, which is the second of the Black Box Software Testing classes offered by AST. I participated as a volunteer for the first Selenium Conference which was held in San Francisco, and developed two talks this year, one for CAST 2011 in Seattle and one for PNSQC 2011 to be in Portland. I also made a point of reviewing as many books as I could during the course of the year, with a number of publishers giving me access to lots of great titles to explore and learn from.&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;In a way, I had to deal with a slightly different challenge than I had dealt with at Tracker. Whereas I was dealing with overcoming boredom at doing the same thing over and over, the challenge I was now facing was keeping a balance between all of the amazing opportunities I was getting the chance to get involved with. When I told my team that I had been elected to the Board of Directors of AST, they were congratulatory, but I also spent some time talking with one of our founders about some of his concerns. While he was excited for me and happy to have someone so engaged in testing, he also had some legitimate fears that I was so involved and engaged that it would have a negative effect on what I was doing for &lt;i&gt;them&lt;/i&gt;. While my goal was not to be distracted from doing my job, I could see it was entirely possible that too much testing could get in the way of doing testing (I know that looks odd, but it's actually true. He meant that I'd be so focused on talks, articles and AST business that I'd pay less attention to the testing needs that SideReel has). &amp;nbsp;I assured him that my goal was to do great things in the world of Software Testing if I could, and that that started with doing great things for SideReel. That was my first priority, and that it would be going forward. That actually takes some doing at times, but it also allowed us to set up some plans as to what areas of testing and blogging are "on the clock" and which areas are best spent after hours to explore and consider.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I've mentioned many times on this site the calamity that befell me in August of 2011, with a severely broken leg and the resulting recovery time. That experience actually took me out of the running for being able to present my proposed talk at PNSQC in October (it was still hard to move around at that time; I'd literally spent the month of September in bed or with my leg elevated). It did give me a chance to read more and dive into some areas of testing I hadn't had a chance to explore previously, and I had a chance to sign on for the roll-out of the third class in the Black Box Software Testing series, which was Test Design. This would be an interesting place for me to be, in that I was actually helping to teach a class in its pilot run that I had not actually taken. I had to review the materials a few weeks before the start of the class and get an understanding of the material so that I could help teach it as well. &amp;nbsp;It was a fun experience, but&amp;nbsp;occasionally&amp;nbsp;it felt like I was getting lost in the weeds. This was a big class and it had a lot of information to absorb, but overall I think we did a good job.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I'd be remiss if I were to let 2011 go and not talk about one of the initiatives I most enjoyed being involved in, and that was Weekend Testing. We put on two dozen testing clinics during the course of the past year, and I had a chance to actually discuss the process and do it live at CAST 2011. The real credit, of course, goes to the many participants from all over the world (not just from the Americas) that participated and got involved with our sessions, asked great questions, and offered suggestions for follow-on sessions.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;2012 is now just underway, and my involvement with testing is stronger than ever. I look forward to a year where I will be able to learn more, get involved where I can and discover more opportunities, and in some small way be actively engaged with both my own company and with the broader community of testers in the Bay Area and in the world. The cool thing about software testing is that the only limits there are are the ones you place on yourself. The broader community is more than happy to help fellow testers learn more, do more, get more involved and be more engaged.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So what has this last year taught me?&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;- There's a huge benefit to standing up every day and saying what you have done and what your plans are for that given day. There's a level of accountability that document controls, sign offs an many other methods don't have. When you verbalize your commitments, they feel much more real and tangible, and you feel much more beholden to making sure they get finished.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;- Agile methodologies do help to make testing more focused and help make the process of testing likewise more focused. Rather than having to deal with the changes to a product and having to test everything every single time, the ability to take a thin slice of the product allows the tester the ability to get closer to a more complete level of testing (note, I said more complete; it's still impossible to get to a totally complete level of testing, even in the agile space, but you can get &amp;nbsp;lot close to that goal when you don't have to deal with the entire product).&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;- Being an embedded tester within and Agile team has its benefits. It's nice to just be able to get up and show something to a developer sitting right behind me or across from me rather than having to invade someone's cube. It's a much faster process and a lot more effective.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;- Automation is like any other skill. It takes time and patience to learn it, practice with it, suck at it at first, and slowly over time get better at it. I realize now that my biggest problem in the past was that I didn't really give myself enough time to absorb what I needed to do, not did I give myself enough daily practice to be able to actually have enough to absorb. Just like a batter doesn't go in and immediately hit home runs off a top notch pitcher, so a tester will not be able to write flawless test code the first time out. Start small, make some things work correctly, then branch out. Also, if you need a developer to help you, don't be afraid to ask, but go in with very specific questions, such as "which class should I be using if I want to test the ability of buttons that change wording while you hover over them? I've tried [A, B, and C], but so far, no luck." This shows you have at least done your homework and tried several things, and that you know the area you want to have them focus on and that it's a specific question. Under those circumstances, most developers are more than happy to help you get unstuck. If you are not prepared, or you seem unfocused in your questions, that's a lot harder for them to understand what you mean, and repeated requests will get a less than enthusiastic response back.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;- Singers often fell prey to being under the influence of "L.S.D." back in my performing days. LSD in this case means "Lead Singer Disease". It's where they are so excited to be performing and getting involved in the process that they sometimes forget they are part of a band. When we get involved in the broader community of testing, whether that be speaking, writing, seminars, etc., we also can get very excited about the process, and forget that there's a company that's paying for us to do our day job. &amp;nbsp;When it's something like music and testing, it's easy to separate the two. When we are doing testing in our day job and writing about testing or doing seminars on testing in our off time, the lines do definitely blur. In this case, it's very important to know where one sphere ends and another begins, and while keeping them totally separate may be counter productive, you don't want to have to say that your testing is suffering because you are stressing over your talk you'll be giving at a local testing meetup. If it helps, think of being a musician in an original band and in a cover band. Yes, you're still playing music, but you have two gigs with two different requirements. Remember to sing the covers with the cover band and the originals with the originals band. Otherwise, it can get awkward ;).&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;So that's it... for now at least. Our riverboat ride is at its end. Of course, I hope to have many more years of software testing to examine and consider, and it's possible I may revisit this series each year to reflect on what I've learned and what you might find interesting as well. Until then, be well, and thank you for joining me on this journey.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6890958153006612459-586722986371034334?l=www.mkltesthead.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.mkltesthead.com/feeds/586722986371034334/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6890958153006612459&amp;postID=586722986371034334' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6890958153006612459/posts/default/586722986371034334'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6890958153006612459/posts/default/586722986371034334'/><link rel='alternate' type='text/html' href='http://www.mkltesthead.com/2012/01/where-i-am-today-meandering-walk.html' title='Where I Am Today: A Meandering Walk Through Twenty Years of Software Testing'/><author><name>Michael Larsen</name><uri>https://profiles.google.com/104738247543282839437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-L_ARsHiklGg/AAAAAAAAAAI/AAAAAAAABPA/PwBZuynaDbc/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6890958153006612459.post-971440392927854004</id><published>2012-01-28T12:30:00.000-08:00</published><updated>2012-01-28T14:56:20.449-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='goals'/><category scheme='http://www.blogger.com/atom/ns#' term='software testing'/><category scheme='http://www.blogger.com/atom/ns#' term='skills development'/><category scheme='http://www.blogger.com/atom/ns#' term='learning'/><category scheme='http://www.blogger.com/atom/ns#' term='life experience'/><title type='text'>Into the Blue: A Meandering Walk Through Twenty Years of  Software Testing</title><content type='html'>In some ways, October of 2009 feels like just yesterday. In others, it feels like a lifetime ago. I liken this period of time to my stretch from May 11th, 2003 until February 25th, 2005. Back then I went back to school full time to complete a Bachelor’s Degree and set myself up to work full time, go to school full time and be a dad, husband, Scout leader and competitive snowboarder (well, OK, I used to compete… saying I was competitive might be a stretch ;) ). That period of time proved something to me. It proved that I had a capacity of doing a tremendous amount of work without it killing me. My going back to school was treated like a “youthful obsession” and its level of commitment was almost, well, obsessive.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;A funny thing happens when you embrace your obsessions. You give a little, and you get feedback, and it excites you, and then you want to know more and do more and get more involved and practice more and get more involved until you are literally buzzing with the intensity. That “buzzing” was how I knew that I was channeling an obsessive energy and that I was “getting into something”. The blessing of being ADHD and knowing when these “fixations” are coming to the fore helped me then. I decided to try that experiment again, and see if I could “obsessify” myself as I used to in the days of my youth, and make software testing the target of my focus. &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;For those not familiar with ADHD, this is often not something you can pull off. Most people find that they are obsessing on something, and then they figure out if they can channel it. It’s the old joke that it’s ironic that the rain falls after you wash your car, but the reverse doesn’t work. You typically don’t wash your car in the hope that it’s going to rain. But that’s exactly what I wanted to do. I wanted to immerse myself into software testing and see if I could cause an obsession to develop. Thus, I had to find a way to carry it with me all the time. Did that mean a stack of books? Well, I had one testing book, and that was “Testing Computer Software”. I went back to reread it and while I found it helpful, it also felt very dated. It reminded me of my days at Cisco, and while I used many of the ideas back then, there were many things that I never read because they were not relevant to what I was doing (or so I thought at the time). &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Lugging around TCS everywhere though felt cumbersome, and it made me ask a fateful question… are there any audio books related to software testing? I searched, and while, no, there weren’t at the time, there were some software testing podcasts that had been recorded a couple of years earlier. I downloaded all of them on to my MP3 player and they became my permanent companion in my spare time. Thus, I need to give credit to Randy Rice and his Software Quality Podcast for being the “tinder” that helped me start to set up what would become a roaring fire. Naturally, after listening to Randy and the various people he interviewed, as well as discussing  test tools and actual effective ways of using them, I started to see a different way of thinking about testing. I also saw that what I thought I knew was actually fairly superficial, and that there were many more perspectives. &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;About this time, I saw that my library had a Safari Books Online Subscription, and through that, I had the ability to explore a number of different books. Some of them were specific to given code challenges I was looking at the time, but some were general testing related, as I read through them, I saw that there was a lot of information specific to the ISTQB and getting certified as a tester. While I looked through a few of these books, I didn’t see anything that specifically jumped out to me as a better way of doing testing, or should I say, there didn’t seem to be anything that went beyond what Randy had already discussed in many of his podcasts. As I was exploring a bit, I came across a book from a name I had seen in the magazines and recognized. Actually, it was the fact that it was not a testing book that first caught my attention. It was James Bach's “Secrets of a Buccaneer Scholar”, and the title alone made me fascinated to want to learn more. I bought the book, read through it, and found so much to relate to in my own experiences and my own  “obsession based learning”. I always thought it was weird and strange and not at all a disciplined way to learn  something. It felt great to see that there was someone else saying “your brain is a unique organism, an what works for me may not work for you, and that’s OK. What matters is finding what does work for you and them pimping the living daylights out of it” (OK, so James didn’t really say that, but that’s what I took from it). &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;So we had Randy to give me a daily drip of testing inspiration, and James to re-examine ways to inspire my actual learning and methods of learning. The next “person” to fall into the sphere of motivating me (and that’s appropriate because it was the aspects of motivation that I was looking for), went to Merlin Mann and his 43 Folders podcasts. I was initially going to try to implement 43 Folders as a Get Things Done methodology, but I actually never did. Instead, I became much more interested in the ways that Merlin encouraged time and attention, and understanding why you do things and why you don’t. Additionally, I valued something Merlin said on one of his podcasts early on (I’m paraphrasing here) “I don’t do these things because I’m good at them. I do these things because I’m actually pretty lousy at them.”  So now we have Randy providing tinder, James providing the kindling, and Merlin giving me some big wood blocks to burn. Now all I needed was the match… and Seth Godin would prove to be that match. &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;As I was looking to understanding what and why I was trying to do what I could to learn more and get better at software testing, I heard repeated references to a new book that was being released. The book was called “Linchpin”, and its author was the aforementioned Seth Godin. Since I’d been getting much of my inspiration from the world of podcasting, I decided that getting the audio book version of Linchpin would be interesting. As many of you who have followed my blog now, I credit Seth with being the ultimate catalyst to getting TESTHEAD started. It’s more than that, though. Linchpin was the match that lit up everything for me. By itself it may not have done that, but in combination with the materials I’d listened to, pondered and internalized from Randy, James and Merlin, Seth’s book was the piece that set it all alight and started my trajectory from being on the ground and getting ready to soar into the blue. &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;What I ultimately got out of all of this was that I was waiting for someone to show me the way, to tell me what to do, and when I got that key piece of information, then I’d be ready to be awesome. Truth be told, though, that’s not the way to become awesome. If someone can tell you how to be awesome, then you aren’t going to be. It sounds counter-intuitive, but work with me here. People who make break-throughs don’t follow the road map. They question it. They ask different questions. They approach it from another angle, or several other angles. They don’t do what they are told, but rather, they forge their own way to their understanding. &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Back when I was a musician, I had influences that spanned many different musical genres. Yes, I was a fan of Kiss, but I was also a fan of Earth, Wind and Fire, of David Bowie, of The Jam, of Prince, of Metallica, of Oingo Boingo, of the Cure and of Bauhaus, of the Sisters of Mercy  and The Mission.  I auditioned for a lot of bands that were looking to fit a particular mold. They wanted someone who sounded like Bon Scott of AC/DC, or they wanted someone who sounded like Seven Tyler of Aerosmith. They were looking for someone who fit the blueprint of what they expected a rock singer to be. I came from a much different place, in that, while I loved singing hard rock, and it was a range that worked well for my voice, my personal influences came from a very different place. Thus, when I wrote or when I sang, I didn’t sound like the other singers. Superficially, I did, of course. I had the gravelly style with the ability to sing high and cover a broad range, but my voice didn’t sound like Steven Tyler or like Bon Scott. Nor did I want it to. I wanted it to sound like me. Interestingly, years later, when someone did do an analysis of my voice, they said I sounded like what would happen if Jon Bon Jovi, Paul Stanley and Adam Ant were fused together. I thought that was kind of cool, in  a way, that different styles from my own experience blended to make a somewhat unique voice. That was my success, not that I followed someone else’s blueprint, but that I started to forge my own from all of my influences, and then made a brand around it. &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;This brings me to March of 2010, and the start of TESTHEAD. As I looked back at the initial posts, they are all written in that tentative, just getting started, trying to say the right things to get noticed and be taken seriously way. In short, it mirrored my initial attempts to start a band. I mimicked a number of other people at first, until I started to have unique and interesting experiences of my own. From there, I could see my own style developing, including injecting my own humanity into the process. Just like when a musician writes songs that are abstract and more or less copies of other people’s songs, they may get a nod of appreciation, but they don’t really connect with an audience. That connection gets made a lot easier when the songwriter puts their own world into their songs and puts themselves into the songs. Likewise, I saw that I was doing the same thing with TESTHEAD. Sharing my thoughts, my insecurities, my successes and my failures made the ideas I was exploring much more real. Now it wasn’t just a matter of talking about a test technique, it was putting myself in the middle of it and working through what I understood and, often more telling, what I didn’t. &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Actions cause reactions, an when you are in a band, you learn about other bands, and you oftentimes look forward to playing on the same bill with them. Doing so gives you a fun experience, but it also gives you a little desire to “show the other bands up”. Done correctly, with a spirit of fun and entertainment, there is nothing at all wrong with that. Playing to an audience should be entertaining, and you should want to put on the best show possible. Ripping off another band’s act to do so is not cool, but honing your own show to be the best it can be is totally OK. Testing is much the same way. We interact with many different people, and we rub shoulders with them and learn from them. While I don’t particularly look to “steal” someone elses’s ideas and present them as my own, there is no question that I spend a lot of time trying to understand how various people approach a problem, and learn what I can from them, and incorporate what makes sense to me into what I do.  To that level, a lot of what many other testers have done has made their way into my testing approach. &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;What was interesting to me was that, when all was said and done, I’d managed to do something I didn’t think was possible. I threw myself into a process and a goal with the hope of sparking an obsession, and in a way, that’s exactly what happened. I also modeled my experience on my time as a musician, and I took lessons I learned from that time to help me do this. When I compare being a music Rock Star to endeavoring to be a testing Rock Star, I do it because there are definite parallels. When a musician promotes and markets themselves, they can develop a following and demonstrate expertise to where others will take interest and share that knowledge with others. The same goes with our testing experiences. When we can communicate something that resonates with others, we can help them do better in what they do as well, and in turn, that helps build word of mouth of our own brand. &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Since there was a great deal of influence on me from the world of podcasting, and since I saw how that medium had a tremendous effect on me personally, I was really excited when Matt Heusser put out a call to help him with a new podcast initiative he was working on. As most readers already know, the TWiST podcast has been an active part of my testing journey over the past year and a half, and getting the chance to listen to and shape the shows each week, I have had the chance to learn from many different sources and really explore their thoughts and ideas. For every half an hour show that we produce. I would often spend four hours or more going over every word of the show to edit it to the right length, and that gave me a lot of time to let the ideas sink in and percolate. Each of these ideas gave me a chance to try out the ideas for myself, see if they worked, and give me something to write about. &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;A blog is, in a way, institutional memory. So much of what I’ve written has covered a lot of ground, and has allowed me to formulate my own style and ideas. That writing has allowed me to branch out into other areas such as conference presentations, guest blog postings, and even writing a chapter for a book. Like so many other things, action gets a reaction, and enthusiasm for doing something encourages others to engage because most people just consume (that’s not a dig, it’s just a fact). Most of us in so many things will be happy to consume. We love to read, but far fewer of us will ever write a book. We love to listen to music, but again, far fewer of us will ever join a band and write songs for other people to listen to. We may love and appreciate art, but far fewer of us will actually put in the time to learn how to become exceptional artists. Yet if we actually do put ourselves out there and try to do these things, people will come and get involved with us. It’s a natural reaction. So it is with testing. If we put ourselves out and say “we want to explore this” there will be many to give us a hand. That’s been my experience, in any event. &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;All of this happened within the space of a year, and my friends and co-workers at Tracker definitely noticed the difference. They saw that my level of engagement and interest had grown tremendously, and hat I was once again excited, no, borderline obsessed with testing and learning about testing. Throw in the opportunities that developed with becoming part of the Miagi-do School of Software Testing, joining the Association for Software Testing, taking the Black Box Software Testing classes, teaching the Black Box Software Testing classes, getting involved with Weekend Testing, and all the while  using tools like Twitter, LinkedIn and Facebook to share the conversation with others, an discover others who wanted to share that conversation. &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;One of the benefits of being so open about sharing that information is that, when you are doing so, someone may be watching. Granted, most people may be amused, annoyed, or just plain confused about what you are doing, but someone else in another place may be paying attention, and when a question comes up, such as “hey, our team is looking for a software tester, so you know who might be a good fit?”, they may well say "as a matter of fact, yes!" I mention this because that is exactly what happened in October of 2010. And old friend and co-worker contacted me and said “hey, I can’t help but noticed how involved you are with software testing. We’re in the process of looking for software testers, and while I doubt you’d be interested, we’d love to talk with you about what we should look for”. That conversation branched into several others, and at the end, resulted in me being asked if I would consider taking on a new role as a senior tester at SideReel. Not only did I consider it, I accepted it. When I told my friends at Tracker about the opportunity, they encouraged me to do it. They would be sad to see me go, but also understood that it was a great opportunity and that I had worked really hard to be ready to take it on. Thus, after six years of a tight knit family, I would leave and go forth and explore another opportunity with another small group. Of course, their time as a “small group” would be short lived, so to speak, but that’s part of the next and final installment :). &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;So what came out of all this? &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;-       Inspiration comes from many places. I cannot pinpoint just one person or say “it was THIS that changed everything”, actually, it was a lot of small incremental things that came together that made for the change to take place. We may sometimes have the ability to do something extraordinary in one fell swoop, but usually it’s more like a snowball hat we pack a little snow on and roll down a hill. As it collects more snow it gets bigger and bigger, and very quickly, but it still starts from small actions.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;-       Every person is a brand in one way or another. We are always marketing ourselves, even if we don’t realize it. TESTHEAD is my brand, and it’s the way that I show the world what I do and what I believe about what I do. It doesn’t tell the whole story, but it definitely gives you enough of an idea who I am and what I do to make some conclusions. Some people may want to know more about me because of this blog, maybe even hire me some day. Some may have made up their mind that they will NEVER hire me after reading this blog (LOL!)… and that’s totally OK. At least this way they know what they are getting, or not getting.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;-       A blog is an open portal. People are free to come here and take my ideas and call them their own. I have a copyright and a statement that I would appreciate links back and attribution, but I realize that people the world over may well “steal” my ideas or copy my stuff for themselves and present them as their own. I don’t have a problem with that because I’m not my blog. It’s a repository of my memories and experiences, but it’s not me. I’m the ideas behind the blog, and I’d like to believe that I have a whole lot more where that came from. Time will tell if that is true.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;-       People pay attention to what you post, even when you think no one is. I have found it interesting to hear people talk about things I wrote a years ago and I’d say to myself “wow, I didn’t think anyone had read that!” Just because people don’t comment, doesn’t mean they aren’t reading. Also, don’t be at all surprised if your next interview or job offer comes from someone who has read what you have written. They have also seen that your blog is not you, but the ideas that make it. They want to know more about those ideas.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;-       Put yourself into you material. Regurgitating facts and figures is boring and many other sites already do that. Your experiences and your understanding of the experiences are what makes the information valuable… at least if my own reader stats and comments are any indication.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;-       We are not born with ideas, we all “stand on the shoulders of giants”. I often lament that I have not developed some “great idea” or introduced the “next big thing” in software testing, but really, who has? For the most part, we are dealing with variations on themes that have existed since the time of Socrates. There is little “new” under the sun, but there are lots of new ways to see the world we are already familiar with, and those discoveries are almost always personal. Those break through and “a-ha moments only come when we put our time and attention to the problems we have here an now.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;-       The only way to become a master at something is to do it, a lot, with great focus and energy. The Malcolm Gladwell Outliers formula of 10,000 hours to become an expert at something is legitimate and valid. If you spend an hour a day, you’ll be come an expert in 27 years. If you do it 24 hours a day,  you could become an “expert” in a little over a year, but no one does anything except breathing for 24 hours a day, and suffice it to say you are already an expert at that. Expertise takes time, it takes practice, and it takes dedication. The more time you spend, the more expertise you develop… and no one is born an expert at anything… well, except for that breathing thing, and even then, we still had to learn it at our births.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6890958153006612459-971440392927854004?l=www.mkltesthead.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.mkltesthead.com/feeds/971440392927854004/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6890958153006612459&amp;postID=971440392927854004' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6890958153006612459/posts/default/971440392927854004'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6890958153006612459/posts/default/971440392927854004'/><link rel='alternate' type='text/html' href='http://www.mkltesthead.com/2012/01/into-blue-meandering-through-twenty.html' title='Into the Blue: A Meandering Walk Through Twenty Years of  Software Testing'/><author><name>Michael Larsen</name><uri>https://profiles.google.com/104738247543282839437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-L_ARsHiklGg/AAAAAAAAAAI/AAAAAAAABPA/PwBZuynaDbc/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6890958153006612459.post-5554618469821502063</id><published>2012-01-27T05:00:00.000-08:00</published><updated>2012-01-27T06:46:53.299-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='goals'/><category scheme='http://www.blogger.com/atom/ns#' term='software testing'/><category scheme='http://www.blogger.com/atom/ns#' term='skills development'/><category scheme='http://www.blogger.com/atom/ns#' term='learning'/><category scheme='http://www.blogger.com/atom/ns#' term='life experience'/><title type='text'>Limits and Laws:  A Meandering Walk Through Twenty Years of Software Testing</title><content type='html'>On March 28th, 2005, I became employee #10 at ImmigrationTracker. That was also including a few people who had come and gone over the five years that the company had been formed. Without a question, this was the smallest company I had ever been a part of, and that actually sounded really exciting. When I walked in, there were two people who focused on selling the product, three people who did software development (with one person dedicated to data optimization) a customer services manager, a support person, and our company president/founder. That was the &lt;i&gt;entire company&lt;/i&gt; at that point, and the closest I got to being in an early part of a company’s growth. By the time I left Tracker Corp in January of 2011,  we had tripled in size and had made great strides in being one of the core players in the legal software area. &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Tracker was a neat place, in that it was an outgrowth of an already successful law firm. Our President had had a successful career as an engineer and an executive, and his wife was the Principal attorney of the law firm. When they had children, he actually was looking forward to having an early retirement and being a stay at home dad, but when the law firm’s biggest client said they wouldn’t stay with them unless their clients could view their case status online, he thought “hey, I could probably do that” and with that, the first version of ImmigrationTracker was born. Later on, other people decided they would love to have this product for their practices, and then over time, a company was born. Tracker and the Pearl Law Group were and are what can best be described as “symbiotic companies” and that made for a lot of the ability for Tracker to grow and thrive over the years. &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;It was into this environment that I stepped in to be a Customer Support Specialist. For me, it felt strange to be out of the everyday realm of software testing, but truth be told, It would only be a short period of time for me to be 100% focused on Customer Service and Technical Support. By virtue of our having PLG working with us and co-located with us, and with PLG being the principal “first customer”, their development without a dedicated test team or test process didn’t seem so strange. However, as we would go through issues and “pain points” I was seeing areas where I thought that we could have easily caught some of the issues being described. &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;One thing is for certain in really small companies; if you decide you want to see something get done, nobody is going to tell you “no, you can’t do that!” In fact, people are more than happy to have anyone step up and do more and get involved in any way that will be beneficial. Thus it was, in just a couple of months, I couldn’t keep my mouth shut and I kept talking about how, when I tested certain products, I would do [fillintheblank] and how I found it helpful. Test once, it’s seen as a nice thing. Test twice, and people are appreciative. Test three times, and from then on, you are the de facto company tester. What can I say, I couldn’t leave well enough alone. I would test SQL query changes, installers, and I would also often review customer updates and see what issues kept popping up and ways we could either avoid or minimize issues.  One area that I would often find coming up was forms, lots and lots of forms. Tracker being an immigration management system had a ton of immigration forms associated with it, and one of the most frequently tested areas was any time a form had been updated by the government, we had to turn around a fix that included the new form. I think over the six years I was there I tested somewhere around a thousand form revisions if not more. &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Having to work so often with databases and forms made the creation of “personas” critical. I created companies full of people with obvious to me names so that I could see if the persona was correctly represented, and if the data matched up the way we expected. That was fun when it came to doing our training sessions (I did most of them for our Server, Client and Web product). It was also fun when I’d see comments back from training and I’d occasionally get a comment back of “Dude, you totally used Fullmetal Alchemist for your data set. That was cool!” I’m not sure what was more surreal, the fact that Immigration attorneys and paralegals were giving me kudos for a persona character set, or that there were Immigration Attorneys or Paralegals familiar with Fullmetal Alchemist (LOL!). &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Tracker was a tight knit family, and because we were so small, you couldn’t slack off on things, it would be instantly noticeable. In support, you couldn’t slack off anyway; people were stuck and needed your help. To that end, I really felt that my testing background helped me get to the bottom of some odd problems and helped me develop a good rapport with a lot of our customers. I often found it amusing when I’d hear that a company was planning their upgrade schedule around my vacation time. Loosely translated, they would not schedule an upgrade/update if I was not there (LOL!). It was also interesting to see the relationships that Tracker developed with many of their clients. It was not at all uncommon for customers to come and visit us at our offices and I’d get to meet in person many of the people I was helping over the phone. During those years, we dealt with some interesting challenges, and yes, we also had our share of problems that we all worked through on our product end as well. I am convinced that the Customer Support group was the linchpin that made all that possible (and I’m not blowing my own horn here, I really mean that all of the people we had work through support were fantastic at what they did and do). To a person, if someone were to ask me if I’d recommend customer support reps, without question I’d give our little crack SWAT team top recommendations, every single one of them. &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Over time, our little group would grow, and with it, more support people, and those support people would grow into different roles. After two years of splitting my time between support and doing testing where I could, in the Spring of 2007  our Director of Engineering asked me if I’d consider pulling out of the CS group and becoming a full time tester once again. There would be a stipulation to it, though, in that, because we were growing and had maxed out our current space, I had to set up shop in the Director’s office in what was effectively a continuous pair programmer/tester relationship that would last for six months. Looking back, this was seriously one of the coolest things I ever did. I had never been in such close proximity and working so directly with a developer before, where coding and testing happened so quickly. The ability to have such a quick turnaround and such a tight feedback loop was awesome, and it sold me on the idea of “developer and tester pairing”. That arrangement would ultimately end when we moved into our new building and I got my own little place to call my own lab/work area. &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Another benefit or disadvantage of working with a small and tight team is the fact that, no matter what you do, people are aware of what is going on with you whether you are aware of it or not. We all knew when one of our co-workers was having relationship problems and we saw it was affecting him and his work. We all saw when one of the guys on our team seemed to be buckling under the stress and frustration with issues, and we all rallied around to help him get through it. There was no cold and efficient HR bureaucracy; we all dealt with each other directly and we came to each other’s aid, and sometimes performed interventions when needed, because we were that close. Sometimes we had to be gentle, and other times, we had to be harsh, because we valued each other like family much of the time. Some times you have to be cruel to be kind when your family goes adrift… thus it should have come as no surprise when it was my turn. &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Over the years, I had often said “yeah, I’m a tester, but my real passion is…” and I could rattle off a litany of things I was passionate about. Music, snowboarding, scouting and the various activities that surrounded them all got a great deal of attention from me, and often, it bled into my work life to keep everything on track.  This really came home to me in 2009, when a record label contacted me and asked if my old bands material could be released on a compilation album, and then later, if they could release a CD of our material. This led to a special show we decided to do to celebrate the release of the CD, and this got all of us to come together to perform for this show. It was exciting, it was emotional, it was an awesome experience… and it carved a trench into my productivity as a tester! Actually, these were all excuses. The real truth was that I was developing avoidance and procrastination behaviors regarding testing.  I just figured I’d get over these humps, and then everything would get back to normal and calm down, and I’d be able to just roll on and everything would be cool. But that wasn’t happening, and my team saw it, way before I was able to acknowledge all was not right in my world. To this end, our VP of technology, a guy I’d worked with shoulder to shoulder daily for five years, basically called me in to his office and laid it on the line for me. If I was going to self destruct, I could do it elsewhere, but he was not going to stand around and watch me throw away everything I’d worked for all these years.  It was simple, get my head back into the game, or make plans to go somewhere else. &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Because of the closeness of this “family”, this had a very profound effect. This wasn’t a faceless bureaucrat, this was a good friend, one who didn’t want to see me throw my career away. That interaction caused me to realize something. I was bored. Horribly bored, to the point that I almost didn’t care. Up until now all of the distractions were masking the symptoms. Now, with the situation laid bare to me, I was able to objectively review the real problem. I was bored with testing. It was really that simple. But what was I bored with? I later realized I was bored with doing the same thing over and over and over again. My effectiveness was diminishing because I’d lost all sense of excitement and wonder as relates to doing “real testing”. All I was doing was repeating the same steps with a few variations here and there. There was little left to help me be motivated to do yet another round of the same thing yet again. It was then and there I thought to myself “&lt;i&gt;there has got to be a better way to do this&lt;/i&gt;”. &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;In October of 2009, I made a hard and firm decision. I’d explored my “obsessions” in so many other areas and learned everything in the world I could about them. Why hadn’t I done the same with software testing? When I went back to exploring my previous long lived obsessions, I saw that all of them were things I decided I had to know more about, and I dove into them with every fiber of my being. Why should what is effectively my career be any different? I didn’t explore all of those other areas in my life because I became obsessed with them; I became obsessed because I decided to explore them deeply with everything I had in me. In short, with that fateful week in October of 2009, I “took the red pill” and with it, I decided it was time to see just how deep the rabbit hole would go. &amp;nbsp;For many of you, if you have followed this blog since its inception, you already know the rest of the story. For those who are newer to TESTHEAD, I'll sum up that process tomorrow.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;So what pearls of wit and wisdom did I learn during this stage of my journey? &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;-      -  When you are working with a really small company, it is a guarantee that the people around you, if you even have to question it, are working as hard if not harder than you are. This stands triply true for the founder and president. Guaranteed, they are way more exposed and on the line than you are. It’s one thing to collect a paycheck from a company. It’s another when you realize the check in question is in some cases coming right out of the founder’s own bank account. &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;-     -   When you deal with a lot of data to define if your tests are valid, one of the best ways to make sure that you know if it’s right is to personalize it. Not personalize it by putting your own information in, but having so significant a biography for your personas that you would recognize instantly if something was out of place.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;-     -   Having a built in customer is good, but it dose not replace the need for vigorous testing. Looking at the way that the customer might use the product and getting into their skin may yielded similar results, but it may also open up new avenues to consider that your customers left to their own designs might not come up with.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;-      -  If you can set up an option for a primary developer to have you focus your immediate test efforts with them, you can learn so much more about the code and what they are thinking than going through a bug database and communicating that way. This was my first “semi Agile" experience and I think it worked well.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;-      -  If you are not comfortable with people knowing everything about you and understanding your deeper feelings and the realities of your life, don’t work for a small company (LOL!). Seriously, there’s a bond there that is hard to describe, and goes way beyond just working together. Just count on the fact that, if things are not going right in your world, for whatever reason, your co-workers in this environment will know it before you do. If they care about you, they will help get to the bottom of the problem with you, whether you like it or not ;).&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;-       - We all find ourselves “sleepwalking” at times, and in larger companies, we can do it for longer without anyone really noticing or paying that much attention. Boredom is dangerous, and it can really derail you if you do not make a conscious effort to stave it off. Also, if you do find yourself sleepwalking through what you are doing, make a commitment to explore exactly why you are doing that. Your boredom may be temporary, or it may be a symptom of a deeper problem. &lt;br /&gt;&lt;div class="MsoListParagraphCxSpLast" style="mso-list: l0 level1 lfo1; text-indent: -.25in;"&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6890958153006612459-5554618469821502063?l=www.mkltesthead.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.mkltesthead.com/feeds/5554618469821502063/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6890958153006612459&amp;postID=5554618469821502063' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6890958153006612459/posts/default/5554618469821502063'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6890958153006612459/posts/default/5554618469821502063'/><link rel='alternate' type='text/html' href='http://www.mkltesthead.com/2012/01/limits-and-laws-meandering-walk-through.html' title='Limits and Laws:  A Meandering Walk Through Twenty Years of Software Testing'/><author><name>Michael Larsen</name><uri>https://profiles.google.com/104738247543282839437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-L_ARsHiklGg/AAAAAAAAAAI/AAAAAAAABPA/PwBZuynaDbc/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6890958153006612459.post-5619422629844749483</id><published>2012-01-26T06:30:00.000-08:00</published><updated>2012-01-27T05:18:55.147-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='goals'/><category scheme='http://www.blogger.com/atom/ns#' term='software testing'/><category scheme='http://www.blogger.com/atom/ns#' term='skills development'/><category scheme='http://www.blogger.com/atom/ns#' term='learning'/><category scheme='http://www.blogger.com/atom/ns#' term='life experience'/><title type='text'>Not All Fun and Games: A Meandering Walk Through Twenty Years of Software Testing</title><content type='html'>It's June of 2003. I had resigned myself to focusing on school, and I figured that would be the bulk of my time going forward, and there would be little in the way of my having a realistic amount of time to actually work simultaneously, but there was that strange Craigslist ad... a QA tester that had an excellent singing voice? What was &lt;b&gt;&lt;i&gt;that&lt;/i&gt;&lt;/b&gt; all about? &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I didn’t have to wait very long to find out. The ad was placed by Konami of America, located in Redwood City at the time, and it was a call for testers to help them with their “rhythm games” offerings. Konami is known for a number of different businesses around the world, but their most famous is their video games division, and specifically titles like Dance Dance Revolution. In 2003, Konami was working with Boston game developer Harmonix to publish a game called Karaoke Revolution,  a singing game that tested your vocal ability and scored you based on accuracy and timing. The problem? None of the testers were able to test the game at the Expert mode level. For this purpose, they needed to hire testers that could, well, really sing. &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I went in to interview and I discovered a sub-culture of the testing world I was, up until that time, totally unfamiliar with, that of the “temporary game tester”. For those who don't know about this model, here’s how it existed in 2003. Testers were contracted through various temp agencies, and depending on the company, you were ether hired by the project or for a set contract time. Often the standard block of time was either six months or one year. During that contract, you were paid the industry standard (in 2003, that standard was $12 an hour). Very often, there were periods where overtime was expected (sometimes &lt;i&gt;lots&lt;/i&gt; of overtime) to make sure that a game could meet a release date. At the end of the contract, many workers would find that they were automatically let go and had a non-hire clause of 90 days (yep, that meant that the company that hired you would let you go at the end of the contract and they wouldn’t hire you again for 90 days after your previous contract). For this purpose, a lot of game testers were nomadic, and worked for a lot of different publishers, and frequently moved from company to company to keep steady work. &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;This was a world I was totally unfamiliar with in my testing experiences, but since my focus was on getting through school, any work I could find to help me slow down the burn rate of my savings was welcome, and the fact that I had savings to burn though helped me to say “well, this could be an interesting experience, what have I got to lose?” Shortly after the interview, I was offered a contract and I took it. Interestingly, my first week was not actually testing Karaoke Revolution, but working on  a PC game that had a lot of chapters, a multi-player ability and a need for a lot of video card and sound card testing with various combinations of components. Thus, on June 30th, 2003, I found myself in a big room with a bunch of other game testers, many of them long time veterans of this scene, and me, starting over again. &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;A little bit about game testing. Lots of people look at it like it’s a dream job. “Oh, how awesome, you get paid to play video games all day, what a life!” Well, that may be true for the first couple of days, but really, there’s a big difference between &lt;i&gt;playing&lt;/i&gt; a video game and &lt;i&gt;testing&lt;/i&gt; a video game. Playing a game means walking through a level and enjoying the scenery and interacting with the story and “riding the rails of the title”. Testing a game means taking a character and running them along the walls, solid objects and other characters and making sure they don’t fall through the cracks. It means going through the same dialogs over and over to make sure that they are displayed correctly. It means walking areas over and over and over again after making small hardware changes such as a different video card, sound card, OS or memory change. In short, &lt;i&gt;actually playing the game&lt;/i&gt; is the &lt;i&gt;smallest&lt;/i&gt; part of the job, and often, you don’t even get an awesome title to test. For every &lt;b&gt;Metal Gear Solid,&lt;/b&gt; there is a &lt;b&gt;Barbie’s Horse Adventure&lt;/b&gt; or a &lt;b&gt;Rainbow Bright Studio&lt;/b&gt;, and yes, I know that those games exist (LOL!). &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;One of the things that made testing with Konami interesting was that there were two types of projects. The first were games published in the states primarily and made with US development houses. Those games were a little easier to communicate through, and we used a standard bug tracking system and communicated back and forth between the developers and testers fairly easily. The biggest challenge was that builds would be shipped to us on DVD and we’d need to install them and test them from physical media that had been shipped. This meant that our testing was often gauged in a  week’s worth of time, and the turnaround for any given cycle was often a week, sometimes more. &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The second testing area was the titles Konami directly developed, usually in Japan, and were sent to us in the US to test and make sure they were ready for release into the U.S. and English speaking markets. This was a very different system, and one that required precise language and wording for both bugs and status reports. Every day, I would have to submit a testing report and bug entries, and they had to be reviewed by the Senior Tester for the QA group. The reason for this was to make sure that there was no ambiguity for our translator. Yep, our reports would be &lt;i&gt;manually&lt;/i&gt; translated from English to Japanese and sent over to Japan for review and further comment, and then we’d get the follow-up in our morning meeting each day. &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I had the chance to lead the Karaoke Revolution project with a number of other testers and work on a range of testing challenges. In addition to the singing aspects, there were the “Technical Resource Checks” that were required for any title that would be published by Sony (for the Playstation series), by Microsoft (for the Xbox) and Nintendo (for any of their consoles) and these checklists had to be adhered to exactly. Either they passed or they didn’t. Another aspect of this world that was very strange was the “lock boxes” for the consoles and the PC’s. The workstations had literal cages surrounding them, and locks were applied to them. If you needed to change media or make a component change, the senior tester would then come in and unlock the box so you could make the change, and then lock it up again. Truth be told, I found this practice to be demeaning, but I also understood that the game industry has a history of theft and black market piracy, especially for unreleased games, so I also understood the need for the precautions.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;After the Karaoke Revolution game was shipped, a number of us were reassigned to help out with the Customer Service group. This was a common practice since the Customer Service needs often spiked around various titles releases, and rather than hire and lay off Customer Service reps, they kept a small group of CS people and added or diminished from their ranks by using testers. I got assigned to the CS group and dug into the then massive list of emails, letters and phone calls that we were getting. Over time, I started to notice that the other testers were put on various testing projects, but several months later, I was one of the last of the testers to &lt;i&gt;not&lt;/i&gt; be on a new project. I asked the Senior Tester if I’d done something wrong, and his answer was “actually, no, you did something really right. Not to belittle our testers, but for many of the games, well, we can pick and choose anyone to test or lead those titles, but it takes a real talent to effectively calm down angry customers and help them resolve their issues. You’re not still doing Customer Service because you are being punished. You are still doing Customer Service because you are remarkably good at it!” &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;For much of my time at Konami, I would straddle these two worlds. I would use my testing skills to help answer customer problems and investigate issues and devise workarounds. In these days, unless something was truly catastrophic, a bug that was shipped was eternal. We didn’t fix the systems, we figured out how to get around a problem area and then published it. Thus, I got a lot of experience in doing “forensic testing” or testing products that had already been released and had known issues, and my job was to find ways to get people “unstuck” where possible and help them keep playing and get past the pain point. That’s a very different kind of testing as compared to saying “this area doesn’t look right, it needs to be redesigned”. &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Games are a very cyclical market, with a lot of build up and intensity in the spring, summer and fall months, and a huge dip during the holiday season (everything needs to be ready to be purchased in time for the holidays, so most work is wrapped up two to three months prior). This means it’s common for layoffs to happen during this down time, and I was no exception. Granted I was prepared for it by the nature of the work and how it was presented, but a part of me was a little sad about it. While there was a fair amount of turnover, there was a tight camaraderie among the testers at Konami, and each time someone was let go, it felt like we were losing a friend, and many felt the same way when I was told it was my turn. I was OK with it, though, as I had plenty of other thing vying for my attention, such as a full time school load. &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I mentioned that I was doing school through an online program through the University of Phoenix. I think it only fair I give you an honest review of that approach.  I have heard both good and ill spoken of the UoP system of education, and I will say that for my purposes, it actually worked pretty well for me. I cash flowed my entire time there, and didn’t borrow any money whatsoever. I was also fortunate in that my Dad helped us out, too. He said that, out of all his kids, I had been the “least expensive” when it came to college education. He compared what he had spent helping my siblings get through school over the years and based on that average, offered to split the tuition costs with me. Interestingly, I discovered that, because of my “large” amount of stock equity, I was totally ineligible for any college grants or financial aid, which made sense, I guess ;). Still, when you are writing a check for $2000 for each  class, that has a galvanizing effect to make sure that you did well in those classes, regardless of what the requirements, other students or external community might be saying. For me, I put everything I had into it, and I minimized the time between classes by doing a double rolling schedule. This meant that every class that was scheduled for four weeks would be over-layed on top of another class, but staggered by two weeks. This way, I was doing the peak work for one class while another on was ending or starting. Also, with the strict 9:00 am – 5:30 pm work schedule at Konami, plus other things I was doing with my family, I discovered the prime time for me to study was from 4:30 am to 8:30 am each day. I also discovered that, for all intents and purposes, that was the ideal time for me to actually be studying. I came to the realization at this time that my “brain waves”, for some weird reason, were most in tune to actual learning and problem solving at these ridiculous hours. &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;My reprieve to focus entirely on school would only last about a month, though. Konami called me and asked if I’d be willing to come back and do another contract. It seems that while I was gone, the Customer Service needs had skyrocketed, and the CS team, when asked if they needed help, actually said “yeah, can we get Michael back?” For the record, I thought that was rather cool, and since I still had well over a years worth of classes to get through, I said sure. Over the coming year, I would cycle on and off on projects related to testing titles. I’d also test three more versions of the Karaoke Revolution series (the reason I was hired in the first place) and in a neat twist, I’d get to lend my voice to the game. For those interested, if you play Karaoke Revolution and you load the Doobie Brothers song “China Grove”, like all songs, you have a choice of having the guide vocal in the mix to sing along with, or you can mute it and just sing by yourself. The guide vocal for “China Grove”… is me :). &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;As 2004 wound down, I realized that my time in school was also winding down. In the space of 20 months, I would complete 22 classes for a total of 66 units, and I’d maintain a GPA of 3.96 through that process. As I was now getting to the point where I had to make a decision work wise, I did state to Konami that I might be willing to work permanently with them if they were to make me a full time job offer, but if that were not to materialize, I would be looking elsewhere in earnest. My completion date for my degree was February 25th, 2005. The preceding three months, I’d interviewed for more testing jobs, and while the market had changed a bit in those ensuing two years, it was still the same laundry list of “we’d love to hire you as a tester, but really, we’re looking for junior level software developers that we can grow into developers, and we’re putting them into testing positions for half the salary of seasoned developers”. &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Gah!!! &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Well, I’d just spent the better part of two years doing Customer Service and Technical Support, what does the job market look like for &lt;i&gt;those&lt;/i&gt; positions? Actually, I was surprised to find that there were &lt;b&gt;&lt;i&gt;lots&lt;/i&gt;&lt;/b&gt; of them! Based on my recent classes and my degree completion, I found that, when I submitted my resume for tech support and customer service jobs, I was getting a call-back ratio of two to one over my resume being submitted for testing positions.  I also decided to do something different with my resume this time around. Instead of sending out a bullet point resume with keywords and job descriptions and responsibilities, I made an essay version of my resume, telling about what I learned at each job and how I applied it. This proved to be very effective, in that I received many more call backs with this type of resume than with the standard bullet point approach. I also started using a new tool called LinkedIn, and set up my profile and started to add friends and contacts to it. While this was in the very early days of LinkedIn, I found that it gave me a chance to compare what I was presenting and modify it regularly. I also found that having people I worked with endorse me also added a little bit of a boost to my visibility for job opportunities. &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;After several interviews, I finally accepted a job with ImmigrationTracker (a company that would later change its name to Tracker Corp.)… as a Customer Support Specialist. Wait, what?! But your career is testing, you all would say. Why would you do that?! Well, truth be told, I had seen what the state of testing was like in the middle of the decade of the 2000s in the Bay Area, and I was not very encouraged. I also saw that people actually wanted my problem solving skills in the Customer Service area. I figured “hey, maybe it’s time to put these testing skills to use in another endeavor” and really, I figured that, maybe, my testing days were over and I was now working in an area that was a better fit for me personally. &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Ah, but don’t you fret, dear reader, as you already know... there’s a few twists and turns still to be had. This blog title is called TESTHEAD after all, and I talk about software testing, not customer service and technical support, so you would be wise to think that my days as full time tech support would be limited… but that, as they say, is a different story, and I’ll tell that one to you tomorrow :). &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;So, did I learn something new from these experiences? Oh goodness, yes!!! &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;-        - Was the degree worth it? Financially, I would say it was a wash. Knowing what I know now and the opportunities I have been able to take advantage of in just the past three years, had I done then what I have done more recently, it’s entirely possible that I would have had a greater impact doing TESTHEAD back in 2003 rather than focus on a bachelors degree. Having said that, I did learn a great deal about myself; my capacity to work, study, reason and discover new things that I might not have been able to do had I not gone back to school. So while I may question the financial aspects of going back to school, I do not question at all the personal changes and discoveries I made about myself and my abilities that I learned while I was doing it.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;-       - Game testing is hard work, and it suffers a bit from the same stigma that the music industry has. Because so many people want to be a part of it, there’s a huge and competitive group of people doing this kind of work. It’s brutal, and it’s really not designed to be for everyone. If you survive in the game industry, &lt;i&gt;it’s because you really want to be a part of the game industry&lt;/i&gt;. Many people toil for years before they get a break to become a designer or a producer or have some other role in the industry. Some even stay in the testing realm and work their way up, but make no mistake, these people work &lt;i&gt;very hard&lt;/i&gt; to get where they are, and their effort is very commendable. Yes, many people come into the industry, but only a handful really have the fortitude to stick it out for the long haul. While I like video games, I decided I didn't like them &lt;i&gt;that much&lt;/i&gt;!&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;-       - Customer Service is really another side of the testing coin, and if you have solid testing skills, you may find that you also have the ability to do really well supporting users and helping them through their pain points. It was also a plus that my “rock star” voice and my time spent schmoozing all those years in the music scene helped me to work with a lot of disgruntled people and help “talk them off the ledge” and get to a point where we either resolved the problem, or at least found a way to get around their issue and move on.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;-       - If you want to know if you are communicating clearly, try writing all of your bugs knowing that they will be translated into Japanese. It’s an eye opener how much of our everyday vernacular creeps into our writing (yes, even writing bugs) and upon review, we realize that “we keep using those words. I don’t think it means what you think it means!”.  Much of this approach I still carry with me to this day. I still write my bugs as though I am anticipating them being translated for someone else to read.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;-       - Sometimes it’s the little things that drive people crazy. The big show stopper bugs get the press, but it’s the little areas of a game’s movement, the repetitiveness of dialog, or the really trivial aspects of an area’s design that makes people get really irked. While we may think an area is too small to be considered, or it’s so trifling that a customer would never complain about it, I have lots of phone messages and emails that state otherwise. Again, you never really know which issues will set someone off.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6890958153006612459-5619422629844749483?l=www.mkltesthead.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.mkltesthead.com/feeds/5619422629844749483/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6890958153006612459&amp;postID=5619422629844749483' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6890958153006612459/posts/default/5619422629844749483'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6890958153006612459/posts/default/5619422629844749483'/><link rel='alternate' type='text/html' href='http://www.mkltesthead.com/2012/01/not-all-fun-and-games-meandering-walk.html' title='Not All Fun and Games: A Meandering Walk Through Twenty Years of Software Testing'/><author><name>Michael Larsen</name><uri>https://profiles.google.com/104738247543282839437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-L_ARsHiklGg/AAAAAAAAAAI/AAAAAAAABPA/PwBZuynaDbc/s512-c/photo.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6890958153006612459.post-1065027459449325350</id><published>2012-01-25T12:00:00.000-08:00</published><updated>2012-01-25T12:05:39.150-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='goals'/><category scheme='http://www.blogger.com/atom/ns#' term='software testing'/><category scheme='http://www.blogger.com/atom/ns#' term='skills development'/><category scheme='http://www.blogger.com/atom/ns#' term='learning'/><category scheme='http://www.blogger.com/atom/ns#' term='life experience'/><title type='text'>My "Testing Process": A Meandering Walk Through Twenty Years of Software Testing</title><content type='html'>&lt;br /&gt;&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: left; margin-right: 1em; text-align: left;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://www.marcanthonyjohnson.com/wp-content/uploads/2011/11/Red-Pill-Blue-Pill.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="240" src="http://www.marcanthonyjohnson.com/wp-content/uploads/2011/11/Red-Pill-Blue-Pill.jpg" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: -webkit-auto;"&gt;&lt;span style="font-size: small;"&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;i&gt;"You take the blue pill - the story ends, you wake up in your bed and believe whatever you want to believe. You take the red pill - you stay in Wonderland and I show you how deep the rabbit-hole goes." -- Morpheus (Laurence Fishburn), The Matrix&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Yes, you are getting two posts from me for this series today :).&lt;br /&gt;&lt;br /&gt;I'm taking a bit of a diversion, in the sense that I was asked what my testing process was during the past.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I could post a glib answer and say, in the truest context-driven manner, "well, it depended on the situation". Honestly, I wish I could say that and mean it, but for 85% of the time, I'd be lying.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I wish I could say "I used a naturally developing heuristic model that examined different aspects of a product based on stakeholder values". Yeah, sort of, kind of, but that's on reflection of what I know today. I wasn't doing that cognitively, or with any sense of awareness at the time.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I'd love to say "I used an exploratory model and dug into the various areas of the product to learn about its capabilties". Meh, sorta'... but again, I wasn't aware that I was doing that. In hindsight, of course, I did, a little, but I had no vocabulary to describe it in those terms.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;So what was my testing process? I hope you are ready, 'cause here it is!&lt;br /&gt;&lt;br /&gt;In black and white, from 1991 until 2009, the Michael Larsen Testing Process was:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;1. I diagrammed test steps based on what I was told the feature was.&lt;br /&gt;&lt;br /&gt;2. I performed those test steps.&lt;br /&gt;&lt;br /&gt;3. If it looked OK, I moved on.&lt;br /&gt;&lt;br /&gt;4. If it didn't, I filed a bug, and then followed up to check if the bug was fixed later.&lt;br /&gt;&lt;br /&gt;5. Repeat this process manually until I get so sick of doing it that I figure out some way to get the computer to help me run the same steps (computer aided testing, automation, call it what you will) either by myself, or more often, with the help of developers or automation testers who had that job.&lt;br /&gt;&lt;br /&gt;6. Repeat 1 through 5 for 18 years.&lt;br /&gt;&lt;b&gt;&lt;span style="color: red; font-size: x-large;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;b&gt;&lt;span style="color: red; font-size: x-large;"&gt;TAA-DAA!!!&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;b&gt;&lt;span style="color: red; font-size: x-large;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;Isn't that sad? Isn't that pathetic? Shouldn't I feel ashamed of myself?&lt;br /&gt;&lt;br /&gt;Yes, Yes and YES!!!&lt;br /&gt;&lt;br /&gt;I'd feel even worse were it not for one very large lamentable fact... &lt;b&gt;&lt;i&gt;that's 90% of what testing *IS* in most organizations out there&lt;/i&gt;&lt;/b&gt;. That very testing process I just described is what most testers do, and if you don't, it's because you have "taken the Red Pill", and decided to see how deep the rabbit hole goes. You have woken up and recognize what Michael Bolton calls "checking" and what James Bach calls "fake testing". I called this "my testing life" for 17 of those 20 years.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Generally speaking, I have worked for command and control organizations over the years. By design or by tradition, that's just where I tended to work. When I was at Cisco, ISO 9001&amp;nbsp;certification&amp;nbsp;demanded it, so we complied. We wrote voluminous test plans, we spelled out everything we did, we scripted every step, we made matrix tables and checked off columns, and we did it over and over and over again. At Connectix, we did what we could to be compliant with Apple and Microsoft, so we made test plans, we spelled out our steps, and we did them again and again. At Synaptics, we wrote up proposal documents and we wrote out everything we did for regulatory and manufacturing compliance, and we followed the plan because we had to as part of our contract obligations with hardware manufacturers. At Konami, we had to be very specific with our test steps and the way we reported bugs because we had to make sure two very different languages (English and Japanese) could communicate effectively. At Tracker, because of legal requirements and working in the legal industry, we had to show our test plans and what we were actually doing and stack up books worth of test evidence to show what we knew, when we knew it.&lt;br /&gt;&lt;br /&gt;It was only in my last year of working at Tracker I started to say "now come on, there's &lt;b&gt;&lt;i&gt;got&lt;/i&gt;&lt;/b&gt; to be a better way than &lt;b&gt;&lt;i&gt;this&lt;/i&gt;&lt;/b&gt;!" In the Fall of 2009, I took my Red Pill, and I decided for myself &lt;b&gt;"I want to see how deep the rabbit hole goes"&lt;/b&gt;.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Only now, at SideReel, am I working with a company that has basically said "stop with the voluminous test plans. You don't need it. The story is the spec. The story is the test plan. Go outside of the boundaries to test, look at other options. Feel free to approach your testing from different perspectives. Go and have a play. Learn from the system and adapt your approach. Be open to new information from unusual sources. Be creative in your thinking. You have our permission, and frankly, we'd hope you would do it even if we didn't give you permission!" Other organizations hinted that that was what they wanted, but they had processes in place that implicitly instructed otherwise. Sidereel's Agile approach, and really trying their best to mean it, has been a chance to "work and think&amp;nbsp;differently", to&amp;nbsp;actually&amp;nbsp;do the things I mentioned in the first couple of paragraphs.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Now don't get me wrong, there's still a fair amount of "checking" that happens here, too. I don't not write test plans, but I handle them in a different way, and I'll be getting to that when I get to my discussion of my testing journey when I actually get to the SideReel chapter of the story. Sorry to say, y'all will have to wait just a few more days. I hope that's OK :).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6890958153006612459-1065027459449325350?l=www.mkltesthead.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.mkltesthead.com/feeds/1065027459449325350/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6890958153006612459&amp;postID=1065027459449325350' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6890958153006612459/posts/default/1065027459449325350'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6890958153006612459/posts/default/1065027459449325350'/><link rel='alternate' type='text/html' href='http://www.mkltesthead.com/2012/01/my-testing-process-meandering-walk.html' title='My &quot;Testing Process&quot;: A Meandering Walk Through Twenty Years of Software Testing'/><author><name>Michael Larsen</name><uri>https://profiles.google.com/104738247543282839437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-L_ARsHiklGg/AAAAAAAAAAI/AAAAAAAABPA/PwBZuynaDbc/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6890958153006612459.post-919382934436247836</id><published>2012-01-25T05:00:00.000-08:00</published><updated>2012-01-26T12:05:54.561-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='goals'/><category scheme='http://www.blogger.com/atom/ns#' term='software testing'/><category scheme='http://www.blogger.com/atom/ns#' term='skills development'/><category scheme='http://www.blogger.com/atom/ns#' term='learning'/><category scheme='http://www.blogger.com/atom/ns#' term='life experience'/><title type='text'>Weird Laws of Physics: A Meandering Walk Through Twenty Years of Software Testing</title><content type='html'>After three months of fruitless job searches, friends coming to bat, and me leaving empty handed each time, I was ready for anything. I mean, come on, how hard could it be, I test, for crying out loud! Give me a shot, I can test anything. Several friends heard my plea and gave me an opportunity to prove my point. Truth be told, part of me wished I could take it back. It's rare for me to say that there was a time when I felt I was out of my league, but this really did turn out to be one of those times.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Having worked with routers and other hardware devices, I figured hardware was hardware, and skills in one area would transition into other businesses. In some ways, this was true, but in other aspects, I was very much mistaken. When I got to Synaptics, I discovered that very little of my work was dealing with software. Granted, I did still work with quite a few software applications and utilities, and those were areas I felt confident working with. When my first project was to determine the tensile strength and bonding for various brands of adhesive, I felt like I was definitely pushing the limits of what I could realistically do.&lt;br /&gt;&lt;br /&gt;That's not to say that I didn't have a lot of fun doing some of this testing. It was definitely a unique experience. I literally never knew what I'd be looking at next. For those not familiar with what Synaptics does, if you have a touch pad on your computer, that pad that acts as a mouse, is likely to be either a Synaptics product or a derivative of a Synaptics product. The little eraser in the middle of the keyboard of some systems is also a Synaptics product (among other companies that make them, too). The jog wheels on iPods? Touch screens on smart phones? Fingerprint sensors on computers? Even keypads on cell phones. If it was powered by human touch and the electrical charge of the human body to make it work, Synaptics likely has something to do with it. That was what I was ultimately testing, the capacitance capabilities of a variety of products and the components that helped make it effective, and also peripherally made it look good. Testing software drivers? Not so challenging. Testing the tolerances of the human body model as relates to delivering current to devices for smooth operation? That was a bit more of a challenge.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I found myself looking at all sorts of machines. Some would simulate a human finger and run an electrical current that could be adjusted. Some would simulate touch for continuous periods, like 24 hours plus. I'd use ovens and freezers, I'd use vices and weight fulcrums. I'd use swinging pendulums. I'd go into a hardware lab and grind out brass bezels on a computer controlled lathe with the help of others who knew how to operate the shop. All in all, there were some cool things to play with. One of my favorite (and most unnerving), was the ESD gun. ESD stands for Electro Static Discharge, and voltages ranging from 100 volts up to 50,000 volts! Needless to say, there would be some "shocking results" from time to time.&lt;br /&gt;&lt;br /&gt;The software components I felt pretty good about testing. Formulations of polymers and how they interacted with physical contact, determining the pliability of adhesives after having been exposed to extreme temperatures, and plotting and quantifying those results, were a lot more difficult, and in a lot of ways, I felt very far out of my league. I made a crucial mistake at this time, and that was that I felt embarrassed about admitting how little about Physics and other hard sciences I knew. I was surrounded by PhD's and designers with extraordinary levels of talent, and I felt like I was in the wrong place a lot of the time. This had a debilitating effect on my ability to do certain things, and in many ways, I just tried to keep my head above water as best I could, and muddle along as quietly as possible... fake it 'til you make it. I believed if I just stuck it out, I'd be able to figure all of this stuff out.&lt;br /&gt;&lt;br /&gt;Unfortunately, it became clear to the director of the group I was working with after awhile that, for all intents and purposes, I was not up to the task in the manner that he felt I should be. I was called into his office at one point, and as I sat down to talk with him, one of the comments he made was "I was looking through your resume... you're not a hardware engineer. You've tested software applications and router interfaces... how did you get hired here?" Gang, let's just say that, when you have a conversation like that, you know things aren't going to go well.&lt;br /&gt;&lt;br /&gt;Again, I had been hired on as an Application Engineer, and I had been hired on by another manager, but a subsequent re-organization took me out of their group and into this director's organization. Remember how I said that different people had different ideas as to what being an Application Engineer meant? Well, this director had a clear idea of what it meant to be an Application Engineer, and frankly, I didn't live up to it. Unfortunately, at the same time, there was also a hiring freeze and a no movement clause in the company (we were still deep into the tech downturn of 2001-2003 and the pressures of looking to shed un-necessary headcount were strong). Once again, I found myself being "un-necessary headcount" and I was told to "get my affairs in order". Unlike the last job, when I was told that day and terminated immediately, he said I had 60 days to wrap up what I was doing, but at the end of that sixty days, my employment with Synaptics would end.&lt;br /&gt;&lt;br /&gt;As I contemplated starting the job hunt again, I looked at the job listings, and whereas in 2002 it seemed like the prospects were bleak, in 2003 they looked even worse. the laundry list of skills expected of any grade tester were heavy on the development side, almost no jobs looked to be open that related to what I had experience in, and I just felt like the wind had been completely let out of my sails. I had some chats with my Dad about this, and he brought up an oft discussed and usually dismissed topic on my end... if the job market is so bleak right now, why not go back to school? He reminded me that, since I still had a large quantity of Cisco shares in the bank, that I had &lt;i&gt;way&lt;/i&gt; more resources to fall back on than many of my peers at the time did. Granted, they were worth a fraction of what they were worth just a couple of years previous, but I still had enough to last me several years our of work if it came down to it, so why not consider going back to school? Seeing how few call backs I was getting, and also seeing how many ajobs "required" a bachelors degree at minimum, and were looking for masters degrees as a preference (for testing gigs, yes!), I finally bit the bullet and decided to work with University of Phoenix to see if I could complete my degree through them. Based on the previous work I had done at three different community colleges as well as my UNIX Programming Certificate from UCSC, I could bring 54 units to the table. I'd need 66 more to graduate, and I figured at the best estimate, I could complete that in a little over 18 months. Thus I decided to enroll and finally finish this process I'd never completed after all these years, just so I'd at least have it (a degree, that is).&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;After starting taking classes (entirely online, in the early days of UoP offering their online classes and their format, and all of the issues and interesting challenges that it entailed) I was prepared to just focus on school and not even worry about working... but the thought of burning through my savings for two years without any way to moderate it just made me feel uneasy. With that in mind, I still kept looking to see if there were possibilities on the various job boards, as well as this relatively new thing called Craigslist. As I was settling into my classes and moving through them, I came across an interesting posting on Craigslist. Most of the jobs were way overblown and just felt like they were taunting me, but this one stood out:&lt;br /&gt;&lt;br /&gt;Looking for experience software tester with experience working alone and with small teams.&lt;br /&gt;Experience with documentation and testing standards of large organizations preferred. &lt;br /&gt;Black box testing focus.&lt;br /&gt;&lt;b&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;/b&gt;&lt;br /&gt;&lt;b&gt;&lt;i&gt;... Excellent singing voice a major plus!!!&lt;/i&gt;&lt;/b&gt;&lt;br /&gt;&lt;b&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;/b&gt;&lt;br /&gt;&amp;nbsp;Ummmmm..... what?!! Needless to say, this got my attention. After seeing this message, I fired off a response that said:&lt;br /&gt;&lt;br /&gt;&lt;i&gt;&amp;nbsp;"Well, I've tested for the last ten years with big companies and smaller ones. I've worked with networking equipment, virtual machines, and capacitance touch devices. I've run Sniffer's, written shell scripts and Tcl code, I've frozen plastic and adhesive, zapped electronics at high voltages, reported bugs in the thousands... and I sang professionally for ten years, and have the CD's to prove it. Who are you, and what do you do, because if a singing QA dude is what you need... I'M YOUR MAN!!!"&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;Admit, it, you're curious as to where this one goes... and I don't blame you one bit, as it would be a very interesting and formative two years of my life... but you're just going to have to wait :).&lt;br /&gt;&lt;br /&gt;So did I learn some valuable lessons from this interesting, and somewhat unnerving, time in my life? You bet!&lt;br /&gt;&lt;br /&gt;- I used to believe it was possible to test anything. If you knew the basics of testing, you could apply them anywhere. I will modify that statement by saying "if you have solid testing skills, an ability and the opportunity to learn and adapt, and have a working knowledge or a reasonable way to acquire that knowledge for the domain you will be testing in, then yes, you can test anything. The challenge is the domain knowledge. Some is easier to get compared to others. getting a master's degree in physics would have helped me immensely in what I was doing, but barring that, a more open communication about what I did and didn't know would have made a big difference&lt;br /&gt;&lt;br /&gt;- Everyone is ignorant about something, no one knows it all, and the more specialized a field is, the less likely anyone is going to know everything. I was embarrassed to admit how little I knew about physics and how difficult I found it to accomplish a number of things that needed to be done due to a complete lack of experience. when you find yourself in this situation, it is much wiser to come right out immediately and admit your ignorance. This may seem counter-intuitive, but if you re not going to be the right fit for certain tasks, get that out of the way immediately and let people decide what the best course of action might be. Yeah, it might be that you are let go because you don't have the requisite skill... or you might be paired with a mentor who can help you develop the skills you need.&lt;br /&gt;&lt;br /&gt;- Even if you are not a physics whiz kid, there is still a lot of testing acumen that you can bring to the table just by understanding your surroundings and your natural interactions with objects and items. Even if you can't put into quantitative terms what you are experiencing, gut feelings and personal understanding still matters, and can inform your testing as well as being able to mathematically plot complex equations.&lt;br /&gt;&lt;br /&gt;- Though I had some challenges, I still also had some big wins in discoveries I made, several of them related to polymer sheets and faux-metallic coatings that we were using with engineering samples for touch pads. It's amazing what you can experience and see with a 50,000 volt ESD gun :). Some of those things can help you tell a group that the formulation they are using conducts too much electricity and blows up components much more easily than they should. when I showed these findings to one of the product managers and explained what I as seeing, and what my gut reaction was to it, the product manager asked for a reformulation to be made for that particular Mylar compound. that change being caught when it was saved several hundred thousands of dollars worth of potentially dangerous inventory of being mass produced and sent out. That program manager said I'd earned the equivalent of three times my salary in that day :).&lt;br /&gt;&lt;br /&gt;So what will tomorrow bring? I'll give you a hint... it ain't all fun and games!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6890958153006612459-919382934436247836?l=www.mkltesthead.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.mkltesthead.com/feeds/919382934436247836/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6890958153006612459&amp;postID=919382934436247836' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6890958153006612459/posts/default/919382934436247836'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6890958153006612459/posts/default/919382934436247836'/><link rel='alternate' type='text/html' href='http://www.mkltesthead.com/2012/01/weird-laws-of-physics-meandering-walk.html' title='Weird Laws of Physics: A Meandering Walk Through Twenty Years of Software Testing'/><author><name>Michael Larsen</name><uri>https://profiles.google.com/104738247543282839437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-L_ARsHiklGg/AAAAAAAAAAI/AAAAAAAABPA/PwBZuynaDbc/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6890958153006612459.post-8122272453889954924</id><published>2012-01-24T05:00:00.000-08:00</published><updated>2012-01-24T21:58:44.314-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='goals'/><category scheme='http://www.blogger.com/atom/ns#' term='software testing'/><category scheme='http://www.blogger.com/atom/ns#' term='skills development'/><category scheme='http://www.blogger.com/atom/ns#' term='learning'/><category scheme='http://www.blogger.com/atom/ns#' term='life experience'/><category scheme='http://www.blogger.com/atom/ns#' term='beginnings'/><title type='text'>Virtually Speaking: A Meandering Walk Through Twenty Years of Software Testing</title><content type='html'>In 2001, I stepped away from the only tech company I'd ever worked for, and recalled with amazement that a company that, when I started working with in 1991 had 300 people, when I left they had more than 30,000 people working for them, and had grown to be one of the dominant tech companies in the world (and very briefly, they were THE most valuable company in the world). I joked with people for years that, if I could go back in time and redo anything, there was no question what it would be... sell every share of Cisco stock I owned on March 24th, 2000! Alas, that was not meant to be, but even with the resulting decline, we had enough shares saved up that we could effectively, at the time I had the most shares, lived off the proceeds and had enough money to replace my income for five years. Not enough to retire, by any means (and nor would I want to) but enough that I was open to experimenting and trying different things without too much stress of losing everything.&lt;br /&gt;&lt;br /&gt;Connectix counts as trying a different thing. In some ways, I was still a tester, but in others I definitely wasn't. I was hired on as an Applications Engineer. I wasn't entirely clear as to what that meant, and truth be told, if you asked five different people what it meant, they'd give you five different answers. In a way, I was a senior tester with direct communication to big accounts, which also put me in a position to be a consultant to customers as a top level support rep. It made for an interesting mix of work, and I enjoyed working with both the Quality Assurance team and with the support team. for the first time in my career, I had an office I could call home, and a team that would come in and discuss the challenges they were facing, and I would either offer advice or try to see if I could replicate their results and try to find ways to solve the problems they found. Sometimes I was very successful at this. Other times, not so much.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;One of the most&amp;nbsp;interesting&amp;nbsp;experiences I got to be part of was the official Microsoft Certification process for Virtual PC for Windows. At the time, Windows was just on the verge of releasing Windows XP, and I and a couple of other people in the company got flown up to Redmond to get trained on the new operating systems from an IT and a testing perspective. It was one of the few testing specific trainings I would actually receive in my career up to that point. Additionally, I was given the responsibility to help get Virtual PC certified so that it would have the Windows XP Compatibility logo. To do this, I was periodically flown up to Redmond over a period of several months and worked on site with Microsoft engineers to test various applications. Many of them were simple things to test, but many of them had unique challenges and proved difficult to virtualize (and a few of them, which were specifically created for adaptive users, we had to challenge their findings and state that the applications we were testing made no sense to be run in a virtualized environment, so why were we having to test them?).&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;A good friend of mine worked for Microsoft at the time, and it was fun to head up and talk with her when I was there, and as I explained what I was doing with the applications I was working on, she told me what was actually happening... "Microsoft is sizing your company up. It's a good bet they want to acquire you! You might want to consider where near Redmond you'd like to live!" Interestingly enough, that would prove to be true, but not for awhile.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;2001 was a year of intense transition in the tech field. It seemed no company was immune. Just about everyone went through some kind of "tech sickness" and shed people for various reasons. Connectix was no different. September 11th happened while I was there, and I remember arriving to work early that morning, and my co-worker Sheri told me a plane had crashed into the World Trade Center. I thought it was some idiot joyriding in &amp;nbsp;a Cessna. I went to my lab, turned on the radio... and sat motionless for three hours trying to take it all in. As I heard some noise outside the lab, I came out and saw everyone gathered around a TV on a &amp;nbsp;cart, and we all sat dumbfounded at what we were seeing. We all knew that somehow, the world had just changed. We didn't entirely understand how much, but we would soon.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;One of my most pleasurable memories of the time at Connectix was managing the user forums and helping to answer questions where I could. In many of the forums, there was a guy who was just phenomenal. the crazy things this guy would do with Virtual machines was just, well, awe inspiring. I talked with our management team and said "we have to get this guy on board!" After some additional inquiry and communication, we discovered he was in Australia, and was just barely 21 years old! Still, I lobbied hard to get him out here and onto the company payroll, and fortunately, most of the management team agreed, the kid was a genius, and was a welcome addition to the team. Within a short time, we were paired up as a duo of Application Engineers.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;January 29th, 2002 started like a normal day, and it was as I was getting things ready for the morning when our HR director asked me if I could come in for a meeting really quickly. I said sure, and I walked into our main conference room. Slowly more people would come into the room, and as I noticed that each person seemed to be from a different organization, a sinking feeling hit me. Something's up, and I don't think it's going to be good. A few minutes later, our CEO walked into the room and said "I'm not going to keep you in suspense. This is a lay-off."&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;It was a first for me. I've been underemployed at various times in my life, and I've been in positions where I was able to make a jump from one spot to another, but this was the first time in my working life, ever, where I'd actually been laid off. As I looked at the room full of people, there were some good people in that list, some surprising people, but often, that's how it works. People get fired for under performing a lot, but in layoff circumstances even good people get cut. I'd been lucky over the previous fifteen years, I guess it was just my turn. Still, getting laid off felt like getting the wind knocked out of me, and it was happening at a time when the pendulum had decidedly swung from boom time to bust. I was not relishing the thought of being unemployed in a down economy.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I would spend the next three months working feverishly to try and find a new job. I interviewed with a lot of old friends, and went to a variety of job interviews. Just a year ago, I was a hot commodity and could take my pick of where I wanted to work. Now, however, I found it very difficult to get an interview anywhere, and &amp;nbsp;most of the interviews ended at the first round. Not enough experience, too little automation experience, no knowledge of industry standard tools, no college degree, I didn't have five years programming experience with J2EE (hey now, J2EE hadn't even been OUT for five years, are you KIDDING ME?!!).&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Still, I kept looking and one of my friends got me an interview with Synaptics, a company known for making touch devices to go into laptops, as well as various devices that were being used on products that were being developed for a new generation of devices called Ipod's and smart phones. I figured "&lt;i&gt;hey, I'm a tester, I can test anything&lt;/i&gt;!" Maybe. Then again, maybe not, but you'll have to wait until tomorrow for for me to tell that part of the story.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;So, what pearls of wisdom did I get from this experience?&lt;br /&gt;&lt;br /&gt;- Some of the best "testers" I had the pleasure to work with were the customer support engineers. They had a clear line into the real pain that our customers were feeling, and they helped articulate it in a way that we could all understand and boil down to the issues we should be focusing on.&lt;br /&gt;&lt;br /&gt;- Being a top level support person helps you to start thinking on your feet really fast, and sometimes the ability to talk someone of a ledge is more important than having an immediate fix. Customers appreciate candor, and if you can't promise them a fix, tell them that.&lt;br /&gt;&lt;br /&gt;- Sometimes you have to question another company as to why they picked what they did to be a representation of your product, and yes, even the mighty Microsoft has to be told from time to time that their recommendations and matrix doesn't make sense in some cases.&lt;br /&gt;&lt;br /&gt;- Some people joked with me that, had I not lobbied so hard to get the Whiz Kid from Australia out to work with us, I'd still have a job there (LOL!). Well, no, I doubt it, and frankly, if I had it all to do over again, I'd have made the same recommendation. I'm proud to have championed him coming here, and in some ways I like to believe I have some credit in having come to the U.S. and making a name in the Virtual Server space (if you don't know who I'm talking about, do some Google searching and you should be able to figure it out ;) ). The point is, there's a very real chance that someone is going to come along and show you up. You can either act defensively and block their opportunities, or let the chips fall where they may and let the talent rise to the occasion. In this case, that's exactly what happened, and he deserved it :).&lt;br /&gt;&lt;br /&gt;- Microsoft ultimately did purchase Connectix, and the organization was absorbed into Microsoft. Those who were retained were (mostly) moved up to Redmond. In this sense, it was a blessing that I didn't have to make that decision, as it would have been tremendously unpopular with my wife and children. Sometimes things happen for a reason, and we have to accept that, even if at the time, those happenings don't appear to make any logical sense.&lt;br /&gt;&lt;br /&gt;- It's easy to get discouraged when you lose a job, and to that effect, it's critical to keep a cushion in your savings account that can help you absorb such a blow. I was fortunate in that I had plenty to keep us afloat for a very long while if necessary, but I certainly didn't want to burn through it. Still, if it did turn out to be a lengthy spell of not working, we had the emergency funds in place that we could roll with it. From that experience, if its at all possible, do whatever it takes to gather together three to six months of emergency savings, enough to replace your income for that period of time. It makes a world of diference when you interview. It will help stave off desperation.&lt;br /&gt;&lt;br /&gt;This finishes off the first decade. I hope you'll join me for Decade Number Two starting tomorrow :).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6890958153006612459-8122272453889954924?l=www.mkltesthead.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.mkltesthead.com/feeds/8122272453889954924/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6890958153006612459&amp;postID=8122272453889954924' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6890958153006612459/posts/default/8122272453889954924'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6890958153006612459/posts/default/8122272453889954924'/><link rel='alternate' type='text/html' href='http://www.mkltesthead.com/2012/01/virtually-speaking-meandering-walk.html' title='Virtually Speaking: A Meandering Walk Through Twenty Years of Software Testing'/><author><name>Michael Larsen</name><uri>https://profiles.google.com/104738247543282839437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-L_ARsHiklGg/AAAAAAAAAAI/AAAAAAAABPA/PwBZuynaDbc/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6890958153006612459.post-2774133521082688511</id><published>2012-01-23T12:00:00.000-08:00</published><updated>2012-01-23T22:40:34.646-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='goals'/><category scheme='http://www.blogger.com/atom/ns#' term='software testing'/><category scheme='http://www.blogger.com/atom/ns#' term='skills development'/><category scheme='http://www.blogger.com/atom/ns#' term='learning'/><category scheme='http://www.blogger.com/atom/ns#' term='life experience'/><category scheme='http://www.blogger.com/atom/ns#' term='beginnings'/><title type='text'>10 Years on a Rocket Ride: A Meandering Walk Through Twenty Years of Software Testing</title><content type='html'>&lt;br /&gt;For the first three years of working with Cisco Systems, I had a peripheral relationship to software testing. It was something that I did, but it wasn't my primary responsibility. Mostly, I focused on maintaining a lab to keep the people in Release Engineering happy, and as far as I was concerned, for the most part, that meant working for and helping make sure that the infrastructure to test builds was working, and so that customer problems could be investigated.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I knew who the software development engineers were. They were the ones who wrote the actual code that went into the images. I definitely knew who the micro-coders were, as they were the ones writing the code that went on the interface boards. I knew who the software engineers were that worked on the release engineering side, but I didn't make the connection that they were software testers until considerably later. Why? Well, first off, there was nothing in their title that led me to believe they were testers. All of them were "Software Engineers". The "Testers", i.e. those who were officially titled as such, all worked with hardware, and for the most part, they were responsible for rework of the PCB's and making sure they worked.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I think for me, this idea of being a tester has been bred into me from years of hearing about testing of physical products, and was driven home by the old Hanes Underwear commercials and the "Inspected by #12" commercials. I know I'm really showing my age by that reference, but what I mean to say is that I looked at the group doing testing as the group that was physically testing the assembly line, those physically inspecting boards and electronics. I didn't look at the idea of their being a difference between software development and software test until I met a new hire at the time named "Chuck". Chuck was the first guy on the team to clue me in to the fact that what he did was software testing. I met Chuck because he was one of the Release Engineering team new hires who was willing to roll up his sleeves and help with designing the next hardware testing lab to go online. Because of this, we worked closely together, and as we talked more, I got to understand his role in the company and why he was hired. His phrase has been a hallmark of mine for almost 20 years... "&lt;i&gt;I was hired because I like to break things!&lt;/i&gt;"&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;This was the first time I heard about this kind of approach. I had heard of the testers checking to make sure that boards worked, but the thought of actually deliberately being destructive hadn't occurred to me. One of the ways that this was manifested (and very clearly) was when one of the Release Engineers wanted to get some error output for debugging purposes, but they weren't sure how to do it. Chuck smiled, pulled out a couple of paper clips, and went over to where an AUI cable was plugged in (yes, I remember when Ethernet was too thick to fit into an RJ-45 connector :) ), and jammed the paper clips into the AUI Connector. He then walked over to the console window and lo and behold, errors!&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;This was a whole new idea to me, that software testing could be, well, negative, and aggressive, and have a touch of "weird science" to it. Because of this, and the fact that Chuck and I had a lot in common outside of work (music, video games, spicy food, etc.) I got to spend a lot of time talking with Chuck, and Chuck introduced me to the world of software testing. It was in this world I started to understand that Release Engineering was more than build engineers, that every software engineer that worked for release engineering but wasn't specifically a build engineer was in fact a software tester. Technical software testers, engineering grade software testers, able to code in C and C++ software testers, but still software testers. Through Chuck I got to see more of how the bug tracking system worked and the back and forth between the software developers and the release engineering group (of testers) and what I saw surprised me. There was a bit of a rivalry going on there, and there was a bit of back and forth with each bug. Chuck taught me a number of idioms that would be familiar to many testers; throwing over the wall, the dividing line, us vs. them, breaking things for fun and profit, and the all encompassing "wow, that's interesting... can you do it again?"&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;As Cisco kept growing exponentially each year, more and more testers were joining the team. Around 1993, an initiative was undertaken to help Cisco manage its immense growth, and at the same time, work to secure contracts in the broader marketplace, especially Europe. This initiative was called ISO 9001, and it touched on every part of the organization. As part of this change., the original Release Engineering group was split into three area. The first was the build group, and it would in a sense stand alone from this point going forward. The second group was Development Test, and the third was Product Test. This was the first time that Test as a group in the software realm was codified and made explicit, and it was around this time that I had to decide which group I would support (actually, it wasn't so much "make a choice" as it was that we had three administrators, and it made sense to have a point of contact for each group. Since Chuck was now part of Development Test, I decided to be the point of contact for that group, and with it, I started to work more closely with a core team that was now specifically labeled as Development Test and people who now, for the first time, were called "Dev-Test Engineers".&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;As the growth kept escalating within Cisco, we still had the problem of too much work and not enough people, no matter how fast we hired, so a lot of the manual testing tasks were offered to me, and I accepted them. Over time, a number of the Dev Test team (which was now swelling with the ranks of Manufacturing "Testers" who made the switch over to Engineering) and I felt that it made sense to have me be more directly involved with this group. As had happened a couple of years before, this DevTest crew went to bat for me, and asked if I could be moved into the group as a Dev Test Engineer. The manager for the Dev Test team liked what I was doing, and made it happen. Remember, I'm a kid with no tech training, no CS or EE degree, and no experience with "testing" outside of what I'd picked up from this group. Still, the crew that was there felt I'd be able to do a good job on the team, so in 1994, I was re-assigned to the Development Test group as a junior Dev Test Engineer.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;In many ways, the following six years would be opportunities for me to learn more about testing from the Cisco perspective, to work with various groups and responsibilities (Enhanced Online Insertion and Removal, Performance Testing, Stress Testing, Negative Testing, and a bit of Automated Testing using the Tcl/Tk language and toolkit). I have to admit I was never really good on the programming end, but I did strive to get better at it. Cisco supported testers and engineers in getting further education, and through that support I went and completed a UNIX Programming Certificate through UC Santa Cruz. I also went back to Mission College in Santa Clara during these years to focus on and develop some better Computer Science chops. To that end, I decided it was time to bite the bullet and dive into an area that I was woefully deficient in, and that was mathematics. I went in and took classes starting with first semester College Algebra, and worked my way through over the next several semesters through &amp;nbsp;Pre-Calculus and Trigonometry (about two years worth of total classes), until I completed first semester Calculus with a B. Make no mistake, I considered that one of the greatest academic achievements of my &lt;i&gt;life&lt;/i&gt; at that point :). I also did a number of "Direct Study" projects because what I was working on at Cisco was more advanced than what I would be able to take classes for at Mission. This two year period helped me greatly in filling in a lot of general education requirements that I hadn't taken in my five year stint at DVC so many years earlier. Cisco also sponsored several training brown bags and official product trainings, and I attended a bunch of those, but there was very little in the way of official tester training offered. We tended to fend for ourselves and collaborate together to improve our craft.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;During the six years that I was directly testing, I worked on big teams that were pushing out full platforms like the 7500 and 7200 routers, the Catalyst 5000 switch, and the PIX firewall, as well as in much smaller groups (or even by myself) on projects like the CiscoWorks Network Management platform, and the NetFlow FlowCollector &amp;amp; FlowAnalyzer. I finished up my tenure at Cisco working with the Content Management group and working on the Cisco Cache Engine and Content Switching team.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;One of the things I can say for certain about the Cisco experience was the focus on documentation. Test plans, project plans, test scripts, etc. were the order of the day, and the more detailed, the better. I cannot count how many times I went int to present test plans and then being told that there was "not enough detail" in the plans. Looking back, I really wish I had the presence of mind to say "detail for what purpose?!" But alas, I wasn't at that level of focus or understanding.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;There is no denying the fact that the growth of both the physical company and the growth in their stock price had a big effect on my staying as long as I did. It had its ups and downs, but through the 90s it always came back bigger and more valuable than ever. Cisco's stock had jumped so much in value that it allowed in, in one fell swoop, to exercise options, sell off and pay the taxes necessary, and net enough cash to pay off all of my debts by the middle of 1995. Ten years of debt management came to an end, and with it, I could now sell off my option shares and bank the rest, which I did religiously for the next five years. In 1999, my family was now me, my wife and two young children and with the shares I had saved, I had enough to sell and buy a house with. I bought most of it up front, but took a small mortgage because I didn't want to have to sell ALL of my share to buy the house. To say that Cisco's stock had been very good to me in the 90s would be a tremendous understatement.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Of course, no good thing goes on forever, or as a Chinese proverb well puts it "no tree grows to Heaven". In 2000, I saw the signs of change coming; many of the perks were being restrained for the company, one which had been enjoying a screaming growth curve for a decade. My commute for years had been long and, well, hellish, but it was worth it while the stock was rocketing upward. As it started to come down back to earth, and the value of my shares were coming more in line with a new reality (and for the first time, future shares were well underwater) I started to question whether or not it made sense to keep commuting so long and being away from my family for so many hours. The Golden Handcuffs were less appealing, and I was getting offers from other places to go and see if I'd be a good fit for them. One of these companies was Connectix, located in San Mateo (just ten miles from my house) and the thought of being able to do what I did closer to home really appealed to me. Thus, after ten years, I decided it was time to get off the rocket ride and bid farewell to Cisco. A lot of the old timers were sad to see me go, and I remember well a number of people who told me that "I helped make this Company", and that meant a lot to me.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;So what did I learn from this time and interaction?&lt;br /&gt;&lt;br /&gt;- I learned that there was a distinction between software development and software testing, regardless of the labels applied and the titles used. Developers are developers, and testers are testers, and while the organization can try to foster a different culture, the groups know the difference.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;- I had some great interactions with development managers and individual developers that helped me make my bugs more focused and meaningful, and help me look at what I was really trying to solve. I also learned that a priority to me was not necessarily a priority to development. I also learned that having a high "Junked" bug count was the worst indictment a tester could have (whether this was meant to be the case or not, I did whatever it took to make sure my bugs would not be junked).&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;- I discovered that a lot of projects made sense to have a test team, and others made sense to have just one tester. As a Lone Tester, there were skills I had to step up and develop because I couldn't rely on other testers to fill in the cracks.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;- The World Wide Web was the best friend of a tester if you knew where to look. three cheers for dejanews (look it up for those of you who weren't there ;); it was basically the webified version of NNTP newsgroups).&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;- Cem Kaner's book "Testing Computer Software" would become a good friend, but alas, one I wished I'd read more carefully and completely. Still, with the areas I did read, I did well.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Coming from Cisco, I had the world at my feet and the ability to do just about anything I wanted to do. In a boom economy, you can do things like that. In a bust economy, though, one quickly discovers one may not be as good or as talented as they have led themselves to believe. Needless to say, 2002 would give me my first understanding of this... but I'm getting ahead of myself ;).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6890958153006612459-2774133521082688511?l=www.mkltesthead.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.mkltesthead.com/feeds/2774133521082688511/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6890958153006612459&amp;postID=2774133521082688511' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6890958153006612459/posts/default/2774133521082688511'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6890958153006612459/posts/default/2774133521082688511'/><link rel='alternate' type='text/html' href='http://www.mkltesthead.com/2012/01/10-years-on-rocket-ride-meandering-walk.html' title='10 Years on a Rocket Ride: A Meandering Walk Through Twenty Years of Software Testing'/><author><name>Michael Larsen</name><uri>https://profiles.google.com/104738247543282839437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-L_ARsHiklGg/AAAAAAAAAAI/AAAAAAAABPA/PwBZuynaDbc/s512-c/photo.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6890958153006612459.post-1857635818371146187</id><published>2012-01-22T07:30:00.000-08:00</published><updated>2012-01-22T08:33:09.423-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='goals'/><category scheme='http://www.blogger.com/atom/ns#' term='software testing'/><category scheme='http://www.blogger.com/atom/ns#' term='skills development'/><category scheme='http://www.blogger.com/atom/ns#' term='learning'/><category scheme='http://www.blogger.com/atom/ns#' term='life experience'/><category scheme='http://www.blogger.com/atom/ns#' term='beginnings'/><title type='text'>Learning Ropes and Making Tradeoffs: A Meandering Walk Through Twenty Years of Software Testing</title><content type='html'>When I found myself working at Cisco Systems in 1991, I found myself working with a fascinating mix of very eclectic people. Release Engineering was the group that I would be working with specifically, but because I was actually burning images into EEPROMS, I was actually considered a contractor working for Manufacturing. Manufacturing was in one of the three buildings and when we say manufacturing, we really mean assembly. We sourced various parts from other companies and we had a group of people that actually assembled them. In addition to programming EEPROMS on both an individual level and on a much larger level with seriously big machines that could burn 8 sets of EEPROMS at a time (64 total), I felt like I was living in the world of The Jetsons.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I also had the chance during these early days to get two different visions of testing. In the Manufacturing side of the company, testing was synonymous with hardware rework. Everyone would go through and work at their stations checking boards using oscilloscopes and determining if the electronic pathways were working right. If they weren't they were able to drop in resistors and wires and fix the problems. these were the classic "testers", so in many ways, I felt like that wasn't something I'd be capable of doing. In Release Engineering, though, there was much less hardware rework and much more talk about protocols and interfaces and throttling and other things that has less to do with physical hardware tweaking and much more to do with playing around with the console and sending commands.&lt;br /&gt;&lt;br /&gt;An early, and exciting, interaction came when I met my good friend Shannah, who I still communicate with to this day :). Shannah was a release engineer, and she also spent a lot of her time managing the "testing lab". At first, I thought that this was going to be another place where people reworked boards, but when I came in, I was surprised to see that it was racks of equipment and a lot of cables branching out to various computers. Words like Ethernet, Token Ring, FDDI and X.25 were used, and I saw a bank of big white square boxes that, from my time working in the manufacturing area here and there, I realized was the flagship product of Cisco, the AGS+. &amp;nbsp;As I looked around at the various patch panels and the systems that were on both sides of the room (Sun SPARC 2 workstations, a couple of VAX/VMS servers, various HP-UX systems, plus several variations of PCs and Macintosh systems, I made a mental jump that would help me immensely... this place looks like a recording studio! Not in the sense of the mixing board and tape machines, but in the mass of cables going from machine to machine and having patch panels there to help you route the signals where you wanted to have them go. Now &lt;b&gt;&lt;i&gt;THAT&lt;/i&gt;&lt;/b&gt; I could understand!&lt;br /&gt;&lt;br /&gt;Over the next several months I would do what they needed to have me do so that I could get images burned and released, and to help me also keep track of what was going on, I had my little DEC terminal replaced with what was to me at the time one of the coolest things I'd ever seen. I was given a 21" NCD, which was effectively a graphical UNIX terminal. It allowed me to use X Windows and spawn terminal windows on several machines, give me access to various tools that let me see how I could access this wild thing called Email, and most amazing of all (to me), use a tool called XRN that allowed me to access this insanely wild world of information called "newsgroups".&lt;br /&gt;&lt;br /&gt;Another fact that I was not entirely aware of, but would come to discover soon enough, was that Cisco was on &amp;nbsp;a growth curve that was, to put it quite simply, insane. From the time that I worked there, from March 1991 until February 2001, the company would grow by 100% or more each year, and sometime by much more than that. The net result was that there was a lot of work that had to be done and not enough people to do it. There was no question that I was not at the time qualified in the slightest to be interviewed for a permanent position with the company, but since I &amp;nbsp;came in as a temp, I could easily be applied to any and all "grunt work" jobs that others either didn't have the time for or found less than tasteful to do. As for me, I was just happy to be able to work steadily, and for more money than I'd ever made up to that point. The staggering sum? $8.00 per hour, plus overtime if I worked it, and double time if I worked it. For several months, I really had the ability to do as much as I could stand, and I could be rewarded nicely for doing it (nice is relative here, remember; as a musician, outside of gigs, I'd made maybe a little better than minimum wage).&lt;br /&gt;&lt;br /&gt;The time on the EEPROM programmer was limited; I could only burn one set of images at a time reliably, and since they were connected by a serial connection, it meant that an average image would take a half an hour to burn. This gave me a lot of time to go and help Shannah with the build out of the testing lab in our building, and then to do more build outs for several more labs that were to come on line within the next several months. Setting up the racks, building the PC's, loading the racks, and stringing all of the cables through the wire ladders was actually a lot of fun. It was physical work, and it was very tangible. When a lab was ready, it was obvious how much went into to putting it together. Of course, all of this equipment had to be maintained, and had to be "tested" to make sure that everything was running as it should. To that end, I started to learn how to "telnet" to the various systems console ports and issue commands from my NCD terminal. It felt so high tech and space age. Later I'd realize that, outside of the Cisco specific routers and terminal servers, I was working with what was considered at the time "low end gear", but to me, I felt like I'd been given a shot at being some kind of "mad scientist".&lt;br /&gt;&lt;br /&gt;After ten months, several lab build outs, lots of cable wiring, and more beta software images than I could count, I had made friends with a number of the release engineering team, and they all went to bat for me to get me hired on full time. They felt that I'd done a really good job keeping the labs in shape, and that if I were to be hired on full time, I should be the junior Lab Administrator, along with some others that would be hired to help manage the workload. They realized there was more to do than I could reasonably do even if I worked 14 hours a day (and some days, I &amp;nbsp;did).&lt;br /&gt;&lt;br /&gt;The year that was my break through into the tech world was also a year that was to "crater" the music scene that I was a part of. All this time, I was making money, paying off debt, financing a new but very modest car, and putting money towards getting to that next level. 1991 was known for many things, but in the music industry, it was known as "the year Nirvana changed everything". Truth be told, Nirvana wasn't the change so much as the over-saturation of hair metal ballads was. I'll make no bones about it, I loved being a glam performer. I loved being outrageous, being larger than life, putting on a show, and looking somewhat off the wall. In 1991, al that changed. If you were still wearing make-up and big hair then, you were a relic. If you sang about good times and played sleazy grooves, you were also a relic. Grunge was the order of the day, and it was a time of adapt or die. Industrial was also becoming more mainstream with ultra heavy beat that you could dance to as well as rock out to, and truthfully, this appealed to me more than Grunge did.&lt;br /&gt;&lt;br /&gt;My band morphed into a semi combination of Grunge and Industrial, where I deliberately lowered my voice to less of a high tenor and more of a high baritone. It sounded forced, and while musically it was interesting, I was having a lot less fun doing it. Line-up changes were inevitable, people came and went, and finally, in the late summer of 1992, my band mates decided that they wanted to move to Los Angeles and seek the record deal and go for it all. For the first time in ten years, I found myself in a strange situation. First, I found myself in a situation where I actually had something to lose. Second, would I want to:&lt;br /&gt;- &amp;nbsp;go and drop everything&lt;br /&gt;- lose all of what I'd learned and understood&lt;br /&gt;- to go to a market where my new found skills didn't apply&lt;br /&gt;- and start all over with the debt load that I had (which had actually increased with the money I was making)&lt;br /&gt;- so I could maybe get a record deal in a scene I didn't recognize anymore and play a music I wasn't really enthusiastic about playing&lt;br /&gt;- and lose the connection with the fans that actually supported us all these years in the area where we'd made our mark, i.e. San Francisco?&lt;br /&gt;&lt;br /&gt;Even with all of that, it was the most agonizing decision I had ever made up to that point in my life. How do you effectively drop nearly ten years of your life?! Was this company I was working for really all that? It took me some time to come to some simple conclusions:&lt;br /&gt;&lt;br /&gt;1. I was in debt up to my eyeballs, and were I to go down to LA, I would have to carry all of that with me.&lt;br /&gt;&lt;br /&gt;2. The scene I was part of had changed, and I was enjoying it a lot less than I had two years previously.&lt;br /&gt;&lt;br /&gt;3. In just the 18 months I'd worked at Cisco Systems, I'd seen the company grow from around 300 people to close to 1,200 people, with new offices opening up on the east coast and other places.&lt;br /&gt;&lt;br /&gt;4. I started to pay attention to a little number called "stock options" and ESPP shares, and looked at the stock price. It was doubling every year, and the stocks themselves were splitting just about every year. I did the math and realized that, if the current trend held, I could conceivably work my way out of debt in two years. I had no idea if I'd &lt;b&gt;&lt;i&gt;ever&lt;/i&gt;&lt;/b&gt; be able to do that if I left and went to LA, even if we did get the big record deal. We'd had a chance to see many of our friends who did get record deals and we saw the truth about their financial situations. They were dire. Yes, they'd had some fame, but they were also broke and deeply in debt. I decided I just didn't want to live like that any longer.&lt;br /&gt;&lt;br /&gt;Thus it was in those late summer months of 1992 that I decided it was time to make a change, and let the band I'd worked on for so many years go their own way, and I wished them the best of luck. From there, I decided it was time to put my head into overdrive and see what this tech world really was all about. I would play with other bands over the next couple of years, but really and truly, that magic period where I was "all in" for music had ended, and the prospects of getting married, having a family and exploring some other goals in life took center stage.&lt;br /&gt;&lt;br /&gt;So what had I learned during these couple of years?&lt;br /&gt;&lt;br /&gt;- If you are lucky enough to find a company that has more work than what it can reasonably get done, don't be afraid to volunteer for grunt details. Sure, it's not glamorous work, but in many ways, you can learn a lot about the systems from a holistic standpoint, and get to see what all the moving parts can do.&lt;br /&gt;&lt;br /&gt;- Even the best and most accomplished engineers don't know everything about the systems they work with. You can be a valuable source of information about what the product is doing in &amp;nbsp;a significantly complex arrangement.&lt;br /&gt;&lt;br /&gt;- We had a gathering every week with our customers that came to our training sessions called "Beer and Cookies" and I'd walk around and get to know our customers and see what they were doing, where they worked, and what they were experiencing. Again, because of my years as a musician, I'd learned how to go about and chat with people and do some "promotion". I decided to use some of those skills in this setting, but rather than promote Cisco (let's face it, they were already customers, there was no point in my doing that) I listened to what problems they were having (and there were many of them, to be sure). I would then try to go back to the labs we had and see if I could set something up similar to what they were describing and see if I could make it do the same thing.&lt;br /&gt;&lt;br /&gt;- Release Engineering was, for all practical purposes, the group that built the software to be released to the public. It was also the software testing group. It took me a while to figure that out, but figure it out I did. Most of the people I was working for and with, the ones who were my strongest allies in helping me get hired, were testers.&lt;br /&gt;&lt;br /&gt;I began to self identify as a software tester as well, since I was supporting and helping them do their work. In a short period of time, I would be given the opportunity to see what being a tester, for real and for full time, was all about. I'd also see what being strapped to a rocket ride for 10 years can do to a person, for good and, perhaps, not so good.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6890958153006612459-1857635818371146187?l=www.mkltesthead.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.mkltesthead.com/feeds/1857635818371146187/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6890958153006612459&amp;postID=1857635818371146187' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6890958153006612459/posts/default/1857635818371146187'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6890958153006612459/posts/default/1857635818371146187'/><link rel='alternate' type='text/html' href='http://www.mkltesthead.com/2012/01/learning-ropes-and-making-tradeoffs.html' title='Learning Ropes and Making Tradeoffs: A Meandering Walk Through Twenty Years of Software Testing'/><author><name>Michael Larsen</name><uri>https://profiles.google.com/104738247543282839437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-L_ARsHiklGg/AAAAAAAAAAI/AAAAAAAABPA/PwBZuynaDbc/s512-c/photo.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6890958153006612459.post-7164356566639291079</id><published>2012-01-21T09:49:00.000-08:00</published><updated>2012-01-23T17:01:50.361-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='goals'/><category scheme='http://www.blogger.com/atom/ns#' term='motivation'/><category scheme='http://www.blogger.com/atom/ns#' term='beginnings'/><title type='text'>A Prequel, of Sorts :): A Meandering Walk Through Twenty Years of Software Testing</title><content type='html'>Well, I thought there might be some amused interest at my post of my "former rock and roll self" in yesterday's blog post, but I did not expect the volume of response that I did get (on Twitter and Facebook, as well as emailed and personal comments). Some people wanted to know what led me to this point and how I traded in rock and roll for software testing. The trade in happens later, so I won't be talking about that very much here, but the lead up actually has a fair amount of amusing and interesting details that I don't think I've ever touched on before, or at least, not directly, so for those interested...&lt;br /&gt;&lt;br /&gt;One cannot start a discussion with me about my early life, childhood and teenage years without a very simple detail being put out there, so I'm going to start with it. I have ADHD, and by some accounts also have mild spectrum disorder. I'm aware of all of this, I've dealt with it in various ways over the years, and have managed to be medication free since 1988. I mention this for one reason. My personality is such that I am easily distracted. "Ooh, Shiney!" has my name written all over it :). There was also one tell-tale anti-pattern that is still with me today, and that is what I call "&lt;b&gt;The Obsessive Fixation&lt;/b&gt;". I am not content to dabble in something. If I get involved in anything, I go &lt;b&gt;&lt;i&gt;all in&lt;/i&gt;&lt;/b&gt;, and I often exhaust the knowledge, trivia, minutiae and peoples' patience the way a forest fire consume all available fuel (and air) that surrounds it. &lt;br /&gt;&lt;br /&gt;I've had many obsessions over the years. My first that I can pinpoint was dinosaurs. By the second grade, I knew the timeline and taxonomy of just about every dinosaur known to the western world (at least those known in 1974-1975). Likewise, by the end of 2nd grade, it had run its course, and I was done with it. I still enjoy reading about and seeing shows and stories about dinosaurs, but nothing like the level I did when I was that age.&lt;br /&gt;&lt;br /&gt;Over the years, I could fill in &lt;i&gt;tons&lt;/i&gt; of "year long obsessions" that dotted my youth.&lt;br /&gt;&lt;br /&gt;- 3rd grade it was American History and the Revolutionary War (hey, it was 1976, it shouldn't be too hard to see why ;) )&lt;br /&gt;- 4th Grade it was Chemistry&lt;br /&gt;- 5th Grade it was the band KISS&lt;br /&gt;- 6th grade it was playing Soccer (what the rest of you lot outside of the U.S. call Futbol ;) )&lt;br /&gt;- 7th grade it was performing in a repertory group and singing in chorus at school&lt;br /&gt;- 8th grade it was playing guitar&lt;br /&gt;- 9th grade it was martial arts&lt;br /&gt;- 10th grade it was skiing&lt;br /&gt;- 11th grade it was photography&lt;br /&gt;- 12th grade it was bodybuilding &amp;nbsp;and modeling.&lt;br /&gt;&lt;br /&gt;Also, as an undercurrent and continued "obsession" was an interest in music that crossed just about every known genre, from Classical to Punk Rock, from Funk to Metal, from The Beatles to The Jam, from the English Beat to the Sisters of Mercy, from Black Sabbath to Black Flag.&lt;br /&gt;&lt;br /&gt;Each one of these things was not just an "interest", it was an all consuming passion, and in each case, I actually did something with each of them. Many of them had natural barriers of price, proximity or availability for me to really get too far into them, and most of them, after they had run their course, I was done and went onto something else.&lt;br /&gt;&lt;br /&gt;In a way, that all changed my first year in college. When I met some other musicians, I thought it would be fun to form a band, and just have a lark at being a musician. I realized that performing in repertory theater as a kid, having learned how to play guitar a little (and bass as well) plus having sung in chorus, and my experience working as a teenage model for a little bit (don't make too much of that, I spent way more money to support that pursuit than I ever made :) ), I felt I could help develop and guide a band to where we could play some gigs.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I expected this would be a short lived obsession like so many others, but that was not to be the case. I spent almost ten years working to develop my skills as a musician and the marketing skills to get a band out in the scene and perform. Being a musician certainly had its perks. It also had some tremendous drawbacks. I was planning to spend two years at a community college and then move on to a University someplace. Due to my all consuming focus to make it in my various bands, I took a job delivering pizzas at night and on weekends, and practiced in the afternoons, which left morning hours the only time to take classes. My unit load went from 15 units, to 9 units to 6 units, and a two year stay drifted into almost five years, most of which was classes that were &lt;i&gt;all over the map&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;I took classes in Astronomy, Philosophy, Creative Writing, Music Theory, a BASIC programming class, which I failed spectacularly in, but I got an A in the Computer Lab itself, because I was able to sit with other people and talk about the problems they were having and help them think through the problem they were having... I thought this was just because I liked being social. Instead, I think it's my earliest inclination that showed I was genuinely interested in asking questions of a product, not so much an interest in making the product myself.&lt;br /&gt;&lt;br /&gt;I took a studio recording and arranging class twice (because you could do that and get full credit due to the projects being unique each semester) and one of the things I did was help rewire the control room with my at the time keyboard player, who was an electronics buff. The point is, I took classes that interested me, but I did a lousy job putting together a cohesive transcript with good grades. Oh, and somehow, I tried taking multiple math classes, and ended up dropping each and every one of them. Not one of my prouder admissions, but it just wasn't where my head was at the time. In a later post I'll tell you about going back and taking almost nothing but Math classes for two years, but that's at least ten years from this period.&lt;br /&gt;&lt;br /&gt;During this time, I had very kindly parents who let me live at home, go to school, work where I could. After the job delivering pizzas stopped making sense because I ran three cars into the ground in the process, I started working as a housekeeper, which again meant I went to school Tuesday and Thursday in the mornings, worked the other days, practiced in the afternoons with the bands I was playing with at the time, and did shows whenever and wherever we could.&lt;br /&gt;&lt;br /&gt;The truth is, my bands were my obsession, and all of the work I was doing with them (developing songs, producing recordings, booking shows, marketing shows, developing a stage image, getting us radio play, getting us&amp;nbsp;interviews&amp;nbsp;in small music zines, etc.)&amp;nbsp;&lt;b&gt;&lt;i&gt;THAT&lt;/i&gt;&lt;/b&gt; was everything I was "living for" up to that point. I was also racking up a considerable amount of debt in the process, because I&amp;nbsp;believed&amp;nbsp;that "big break" was just around the corner, and if I just financed "this PA system, this demo tape, this ad campaign, this [fill in the blank]", we'd get over that hump.&lt;br /&gt;&lt;br /&gt;Finally, when I was 22, after several years of plugging away and being on what I felt was the crux of something big, I told my parents I couldn't play half way anymore, I had to go "all in". It was now or never. With that, I dropped out of school completely, moved out of my parents place and in with my guitar player and some other friends so we could share rent, and I devoted 100% of my attention to making the band a success. This was in the Fall of 1990.&lt;br /&gt;&lt;br /&gt;It took me three months to come to a startling conclusion... I wasn't going to survive. I owed too much money, and I wasn't making enough performing or cleaning houses to make ends meet. I was officially living below the poverty line, and while that might sound dramatic and glamorous for awhile, it was really difficult and frustrating. The band was doing well enough for the time and the scene, and it definitely looked promising, but I needed something more stable, and I had to dig myself out of the debt hole that I'd made for myself. The question was, how?&lt;br /&gt;&lt;br /&gt;The answer came from my drummer. He was working with a tech company in their sales department (he had the gift of gab, and out of all of us, was the one doing financially the best). Needless to say, I listened when he suggested I do what he did, which was go to a temp agency and just start developing some work experience, anywhere. Short of my being willing to start my own cleaning business and buy all my own gear to do it (which I really didn't have the funds to do, my credit already having been maxed out, and the thought of running a cleaning business the rest of my life really didn't appeal to me) I figured, OK, I really don't have anything to lose by trying this. The temp agency I picked was the same one that Taz, our drummer, used, and it was them that sent me to Cisco Systems.&lt;br /&gt;&lt;br /&gt;So what can we make from this rather strange litany?&lt;br /&gt;&lt;br /&gt;- From an early age, the idea of exploration and learning, of asking questions, and obsessing over trivia and minutiae proved to be an exceptional training ground for developing the kind of mind that serves a software tester well. Not just "what happened or how it happened, but why did it happen?"&lt;br /&gt;&lt;br /&gt;- I had the chance to look at knowledge from many different areas, and in truth not from a prescribed map. In short, I took classes that interested me, and they brought lots of things to my attention that a more "focused" curriculum would never have helped me tune into.&lt;br /&gt;&lt;br /&gt;- I discovered that I liked to solve problems through experience and learn how things worked, but I wasn't really all that excited about building it from the ground up. I just didn't have that kind of patience (and even today, I fight hard to work though stuff like that).&lt;br /&gt;&lt;br /&gt;- I discovered that I liked to write, but not in the prescribed manner of the term paper requirements of the time. I wrote a lot of bad poetry (and really, most lyrics are truly bad poetry (LOL!)), but I also discovered writing from many different perspectives. I discovered philosophy for the first time, and found I liked talking about different ways of looking at the world.&lt;br /&gt;&lt;br /&gt;- I discovered that a lot of skills come to the fore when you try to create a band. You are not just a singer or a songwriter or a performer. You are also an entrepreneur. You are a salesman. You are a technician. You are a logistics manager. You are a marketeer. You are a financial analyst. You are a designer. More than anything else, you are a creator, someone who has developed a brand, and put it out into the marketplace, and you have adapted and worked with it to help leverage the greatest level of success possible.&lt;br /&gt;&lt;br /&gt;In March of 1991, it really looked like we were almost there as a band, and if I could just get my foot in the door of a job that could help me pay off some of my debts, and help me get some more money so that we could open up some more lines of credit, then we'd be able to make the big push and really get into the marketplace, get signed, put out a real record, get out and tour the country, and we'd be on our way. That was the plan, in any event... but as John Lennon so keenly put it "Life is what happens when you are busy making other plans", and life seemed to have some twists and turns I hadn't yet considered :).&lt;br /&gt;&lt;br /&gt;More on that to come.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6890958153006612459-7164356566639291079?l=www.mkltesthead.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.mkltesthead.com/feeds/7164356566639291079/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6890958153006612459&amp;postID=7164356566639291079' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6890958153006612459/posts/default/7164356566639291079'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6890958153006612459/posts/default/7164356566639291079'/><link rel='alternate' type='text/html' href='http://www.mkltesthead.com/2012/01/prequel-of-sorts.html' title='A Prequel, of Sorts :): A Meandering Walk Through Twenty Years of Software Testing'/><author><name>Michael Larsen</name><uri>https://profiles.google.com/104738247543282839437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-L_ARsHiklGg/AAAAAAAAAAI/AAAAAAAABPA/PwBZuynaDbc/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6890958153006612459.post-747370248680882951</id><published>2012-01-20T13:56:00.000-08:00</published><updated>2012-01-20T14:25:25.434-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='software testing'/><category scheme='http://www.blogger.com/atom/ns#' term='beginnings'/><title type='text'>First Steps: A Meandering Walk Through Twenty Years of Software Testing</title><content type='html'>&lt;br /&gt;I have been thinking about this because, in a way, I&amp;nbsp;officially&amp;nbsp;entered full time employment in the tech industry on January 20th, 1992. It was on that day that I officially became employee number 876 at a company called Cisco Systems. I actually came into Cisco Systems entirely by accident 10 months earlier. At that time, Cisco Systems has about 300 people in their Menlo Park office setting, one that spanned three modest two story buildings between O'Brien&amp;nbsp;and&amp;nbsp;Adams Drive, across the street was Costaño Elementary School in East Palo Alto, and just up the road was open fields and the roadway leading to the Dumbarton Bridge.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I'm serious when I say that I was sent there by accident... well, sent there for another purpose. At the time, I was not looking to get a job in the tech industry. I was just looking for a job, any job, to help me keep from being a literally starving musician. My extent of being tech savvy in those days was that I used a Macintosh that I could find at a Kinko's somewhere in San Francisco (and yes, I learned the schedules of all of them) and would rent the systems by the hour, and would keep all of my stuff on three floppy disks that I kept in my bag. I'd edit my files, make my flyers, and keep up to date my simple database that consisted of a mailing list for sending band flyers (made in Dbase III, for anyone who can remember back that far ;) ) and likewise maintained on any PC that I could rent from a Kinko's as well.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I had never heard of the Internet, I didn't have email, I'd never touched a UNIX box... in short, I was probably the least qualified person to ever be sent to work at a tech company imaginable. For that matter, I wasn't sent there to be a tech guy at all. I was sent there because their engineering library was a complete shambles; all of their printed materials were in piles and boxes and no one could find anything. I was sent there to help with that because I told the temp agency two things. The first was that I'd spent the past three years working as a housekeeper. The second was that I had to work someplace where my having long hair wouldn't be an issue. For the record, and just for a little bit of fun, this was what I looked like for my night time job.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://fbcdn-sphotos-a.akamaihd.net/hphotos-ak-ash2/22374_249960239793_656469793_3398737_3329517_n.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="317" src="https://fbcdn-sphotos-a.akamaihd.net/hphotos-ak-ash2/22374_249960239793_656469793_3398737_3329517_n.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Now seriously, would &lt;i&gt;you&lt;/i&gt; hire this guy ;)?&lt;br /&gt;&lt;br /&gt;A project they thought was going to take an entire week, I was able to finish in two days. Note, this had less to do with it being terribly easy, but because I knew how to clean, and I knew how to organize stuff. They could have sent me home, but since they still had me for three days, they asked who could use some temp resources. The Release Engineering manager had a need for someone to help them with producing beta images for customers. Sounds technical, huh? well, not really. It required someone being willing to sit down and erase Electrically Erasable Programmable Read-Only Memory chips (EEPROMS). I did this by sitting next to a heavily shielded UV machine with a tray that I loaded up with EEPROMS that had been used previously, blasting them with UV light, and then loading them into a machine and checking that they were clean. After doing that, I would then sit in front of a DEC terminal that was connected to a Sun Server of some kind, and I would enter in a cryptic string of words and I would hit Enter. This cryptic string caused an image to be sent to the machine, and that image would be burned into the 8 EEPROMS I loaded up. If all went well and the EEPROMS reached the end of the process with all green lights, I could then eject the EEPROMS from the machine, load them into the small CGS router that I had sitting on the desk, power it up, and issue it five commands:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Show the version number&lt;br /&gt;Show the configuration&lt;br /&gt;Show the interfaces&lt;br /&gt;Configure the console (and make a change)&lt;br /&gt;Confirm that the change took place&lt;br /&gt;&lt;br /&gt;If all this worked, I would then unplug these EEPROMS, put them in a static resistant foam, put them in a box and carry them to people in release engineering and they would do more stuff with these images.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;At the end of the remaining three days, and the end of the week, the release engineering manager asked me if I'd be interested in doing what I was just doing for a little while longer. They were getting ready for a "big release", and would need to get a bunch of images into the hands of "beta customers", and it was a time consuming process. I said "sure", and with that, my one week "filing and cleaning" gig became one where I would be burning images into EEPROMs and making sure they were ready to be shipped to beta customers who would deploy them in their routers on their networks.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Thus, on March 8th, 1991, I officially started working as a temp for the release engineering team. In other words, March 8th, 1991, would be the day I would be able to say that I first became a software tester :).&lt;br /&gt;&lt;br /&gt;I'll post tomorrow on what it was like working in that environment and my recollections of what software testing, to my eyes, was like in 1991.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6890958153006612459-747370248680882951?l=www.mkltesthead.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.mkltesthead.com/feeds/747370248680882951/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6890958153006612459&amp;postID=747370248680882951' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6890958153006612459/posts/default/747370248680882951'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6890958153006612459/posts/default/747370248680882951'/><link rel='alternate' type='text/html' href='http://www.mkltesthead.com/2012/01/first-steps-meandering-walk-through.html' title='First Steps: A Meandering Walk Through Twenty Years of Software Testing'/><author><name>Michael Larsen</name><uri>https://profiles.google.com/104738247543282839437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-L_ARsHiklGg/AAAAAAAAAAI/AAAAAAAABPA/PwBZuynaDbc/s512-c/photo.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6890958153006612459.post-831777228953231447</id><published>2012-01-18T15:00:00.000-08:00</published><updated>2012-01-18T15:00:04.982-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='performance'/><category scheme='http://www.blogger.com/atom/ns#' term='productivity'/><category scheme='http://www.blogger.com/atom/ns#' term='goals'/><category scheme='http://www.blogger.com/atom/ns#' term='education'/><category scheme='http://www.blogger.com/atom/ns#' term='people'/><category scheme='http://www.blogger.com/atom/ns#' term='skills development'/><category scheme='http://www.blogger.com/atom/ns#' term='learning'/><category scheme='http://www.blogger.com/atom/ns#' term='motivation'/><category scheme='http://www.blogger.com/atom/ns#' term='life experience'/><category scheme='http://www.blogger.com/atom/ns#' term='time management'/><title type='text'>The Long Tail Will be The Death of Me!</title><content type='html'>&lt;br /&gt;Having spent nearly three months with Learn Ruby the Hard Way (and now being ever so close to finishing it :) ), I've come to a simple conclusion; long deadlines are evil. No, I'm not serious, but I find that, if I have a deadline that's a day away, I will meet it. Likely just in time, but I'll make it. If I have two days or three days, same deal. When I get into trouble is when I have a week worth of work to do on something and I have a week to do it. Suddenly, life feels like it's wide open and I have all the time in the world, and I relax... and you all know where I'm going with this, don't you ;)?&lt;br /&gt;&lt;br /&gt;Let's consider what I think is a fairly typical reality:&lt;br /&gt;&lt;br /&gt;- A week is 168 hours.&lt;br /&gt;&lt;br /&gt;- Take out a healthy 56 hours for sleep, and that leaves 112 hours... and if you say "aw, I can get by on less sleep than that", check out the number of naps you take during the course of a week outside of your sleep schedule, or necessary mellow/down time needed. I'm willing to bet that you'll be pretty close to 56 hours all told.&lt;br /&gt;&lt;br /&gt;- A work day is 8 hours a day, plus various commute related times (for me at least) and that equals about 9.5 hours a day, or 45 hours, and that gives us 67 hours.&lt;br /&gt;&lt;br /&gt;- My family would like to have me spend some conscious time with them each day, and all told, if I'm generous, that's about 2 hours on a given day, probably averaging out to an hour and a half realistically, so that's 10.5 hours, which brings us to 56.5 hours.&lt;br /&gt;&lt;br /&gt;- I can't speak for anyone else, but when I shower, shave, and do all the stuff I need to do to keep myself looking human and not offend the sensibilities of everyone I come in contact with, I average about 45 minutes on a given day, so that's about 5.25 hours, bringing us down to about 50 hours a week.&lt;br /&gt;&lt;br /&gt;- We spend on average about an hour a day eating when all is said and done, so we're down to 43 hours.&lt;br /&gt;&lt;br /&gt;- My kids have activities that require me to spend some dedicated time throughout the week, so that works out to about an hour per day when averaged out, and that brings us down to 36 hours.&lt;br /&gt;&lt;br /&gt;- If we count the miscellaneous trips to a store, or getting gas or a doctors appointment, we may have another 10 hours per week siphoned off, so we're down to 26 hours in a week.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;All told, under the best of circumstances, and if there's nothing getting in the way of what I'm doing (and not counting any other potential commitments I might have made) that means that I have 3 hours and 45 minutes in a given day at the &lt;b&gt;&lt;i&gt;maximum&lt;/i&gt;&lt;/b&gt; to dedicate to a goal like learning to code, writing a blog, planning for weekend testing, producing a podcast or [fill in the blank]. Note, that's if I am 100% Spartan with my time and don't include things like phone calls, visiting with friends, watching television or surfing the web, which, quite frankly, I do all of those things at times.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;My point with this is that a week is really &lt;i&gt;very little&lt;/i&gt; time to accomplish a big goal. It goes very fast, because in reality, we don't have 168 hours to accomplish a goal, we have maybe 26 hours if we're disciplined, and probably a whole lot less if we are not. Thus what often happens is that optimized time often gets compressed later in the week, our anxiety levels rise; and one of two things happens. Either we get hyper intense and start marathon-ing on our goal, maybe resulting in inspired work, but often being scattered and unfocused; or we find ourselves paring down our expectations and focusing on a smaller goal.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;One thing I love about the TWiST podcast is that I have a hard deliverable, and I cannot be late with it. I'm expected to deliver at a given time so others can review it, set up the space and publish it at the expected time. if I'm late, they're late, and that's not cool. This has a galvanizing effect on me; I don't delay podcasting stuff, I get right to it, because I know how long it takes to do it. The nebulous goal, or the one that is self driven without any real external pressures, are much tougher to handle the same way, because they feel so distant, and there's little in the way of accountability to cause you to get focused and determined.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;That's why I liked the early going of LRtHW. Every exercise was easily done in an hour or two, and having a post a day was easy to accomplish. When the instructions say "I expect you to spend a week on this"... now we're entering danger territory! The long tail allows me to get complacent and relax... I have such a long time to do this. In reality, I don't, but it's hard to shake that thinking. So what can I do?&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;For me, I find that, if I do get myself into this situation, it's best to take a goal and chop it up into much smaller pieces. Sometimes I even focus on just dealing with a single task, and I allocate 10 minutes for that task. For me, I find that 10 minutes is a solid amount of time where I can emphasize on and focus on, well, anything. Given a block of an hour, I'll find some way to distract myself, even if I don't really want to be distracted (this is especially true when it comes to "yak shaving" activities, or things that are just plain tedious). My favorite way to deal with this is to use &lt;a href="http://www.43folders.com/2005/10/11/procrastination-hack-1025"&gt;Merlin Mann's "Procrastination Hack&lt;/a&gt;", or the (10+2)*5 approach to project management. The idea is to work for ten minutes on a given task with your entire energy, then take a two minute break, and then repeat the process five times in an hour. This gives you 50 minutes of solid work and effort, and 10 minutes of break time. This may sound squirrely, but I can attest to how well it works. Granted, for things you are in a groove doing, this isn't such a big deal; there have been times I've gone three hours on a tear, and when that happens, well, let it!&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;If, like me, you find yourself feeling like you have a long, out of focus goal that could take weeks, or even months, to complete, don't let the long tail fool you. Figure out what you need to be doing, and then figure out how to carve it into small atomic pieces. From there, chip away at each little area on a per day, or per hour, or even per minute basis. Do that, and the Long tail won't kill you :).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6890958153006612459-831777228953231447?l=www.mkltesthead.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.mkltesthead.com/feeds/831777228953231447/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6890958153006612459&amp;postID=831777228953231447' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6890958153006612459/posts/default/831777228953231447'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6890958153006612459/posts/default/831777228953231447'/><link rel='alternate' type='text/html' href='http://www.mkltesthead.com/2012/01/long-tail-will-be-death-of-me.html' title='The Long Tail Will be The Death of Me!'/><author><name>Michael Larsen</name><uri>https://profiles.google.com/104738247543282839437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-L_ARsHiklGg/AAAAAAAAAAI/AAAAAAAABPA/PwBZuynaDbc/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6890958153006612459.post-2521630733157916116</id><published>2012-01-18T06:00:00.000-08:00</published><updated>2012-01-18T06:00:18.218-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='education'/><category scheme='http://www.blogger.com/atom/ns#' term='teaching'/><category scheme='http://www.blogger.com/atom/ns#' term='learning'/><category scheme='http://www.blogger.com/atom/ns#' term='books'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='PRACTICUM'/><category scheme='http://www.blogger.com/atom/ns#' term='career development'/><title type='text'>Exercise 47: Automated Testing: Learn Ruby the Hard Way: Practicum</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://upload.wikimedia.org/wikipedia/commons/f/f1/Ruby_logo.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="200" src="http://upload.wikimedia.org/wikipedia/commons/f/f1/Ruby_logo.png" width="199" /&gt;&lt;/a&gt;&lt;/div&gt;Cool, something that I've been curious about for some time. With all of this talk about Ruby being one of the cornerstones of the TDD /&amp;nbsp;BDD&amp;nbsp;/&amp;nbsp;ATDD community, I figured Zed would at &lt;i&gt;some&lt;/i&gt; point get into writing tests for code.&lt;br /&gt;&lt;br /&gt;The benefit to having tests run the code is that, instead of me having to go through and test the paths my program walks down, I can have the test code walk the paths. It's not &lt;b&gt;&lt;i&gt;all&lt;/i&gt;&lt;/b&gt; of the testing &amp;nbsp;I would try to do, but it's a part of the equation I've long wanted to get a better feeling for.&lt;br /&gt;&lt;br /&gt;Going forward, the "&lt;b&gt;What You Should See&lt;/b&gt;" will be replaced by "&lt;b&gt;What You Should Test&lt;/b&gt;". In short, TDD begins here and now, with the idea that I will be writing automated tests for all of the code I write going forward.&lt;br /&gt;&lt;br /&gt;Zed make the following point, and I like the sentiment a great deal:&lt;br /&gt;&lt;br /&gt;&lt;i&gt;"[...] your reason for writing unit tests is to make your brain stronger. You have gone through this book writing code to do things. Now you are going to take the next leap and write code that knows about other code you have written. This process of writing a test that runs some code you have written forces you to understand clearly what you have just written. It solidifies in your brain exactly what it does and why it works and gives you a new level of attention to detail."&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Writing A Test Case&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;So now we are going to get a chance to use our project skeleton that we made.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;- make a &lt;b&gt;Ex47&lt;/b&gt; project from your project skeleton.&lt;br /&gt;&lt;br /&gt;- Make sure you do it right and rename the library and get that first ex47/test/test_ex47.rb test file going right.&lt;br /&gt;&lt;br /&gt;- Next, create a simple file ex47/lib/ex47.rb where you can put the code to test.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-Ra9zFBvGHcs/TxbK6D5_XvI/AAAAAAAABI8/0uJZQjRtJ6o/s1600/Screen+shot+2012-01-18+at+5.21.41+AM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="228" src="http://1.bp.blogspot.com/-Ra9zFBvGHcs/TxbK6D5_XvI/AAAAAAAABI8/0uJZQjRtJ6o/s320/Screen+shot+2012-01-18+at+5.21.41+AM.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&amp;nbsp;- Then update the test file in the test directory with your test code.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-e_eABAnkKIE/TxbK6RhibPI/AAAAAAAABJE/luEbMNxDhzQ/s1600/Screen+shot+2012-01-18+at+5.22.04+AM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://1.bp.blogspot.com/-e_eABAnkKIE/TxbK6RhibPI/AAAAAAAABJE/luEbMNxDhzQ/s320/Screen+shot+2012-01-18+at+5.22.04+AM.png" width="284" /&gt;&lt;/a&gt;&lt;/div&gt;&amp;nbsp;- and while you are at it, you should update your gemspec code as well so that it reflects what you are doing with this project.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-ryd8TdsNAaE/TxbK6-E8eSI/AAAAAAAABJM/Vkr6sUglYxQ/s1600/Screen+shot+2012-01-18+at+5.22.33+AM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="253" src="http://2.bp.blogspot.com/-ryd8TdsNAaE/TxbK6-E8eSI/AAAAAAAABJM/Vkr6sUglYxQ/s320/Screen+shot+2012-01-18+at+5.22.33+AM.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;The point to this experiment is that we load the class Room, and then we can create items that help exercise the functionality that makes up Room. There are then a set of tests that are functions starting with test_. Inside each test case there's a bit of code that makes a Room or a set of Rooms, and then makes sure the rooms work the way you expect them to work.&lt;br /&gt;&lt;br /&gt;The key function here:&lt;br /&gt;&lt;br /&gt;&lt;b&gt;assert_equal&lt;/b&gt; - &amp;nbsp;makes sure that variables you have set or paths you have built are actually what you think they are. If they aren't, Ruby's Test::Unit module prints out an error message.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Testing Guidelines&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;The following is Zed's suggestions verbatim (I like them, why mess with something that's already good ;):&lt;br /&gt;&lt;br /&gt;&lt;i&gt;- Test files go in test/ and are named test_NAME.rb. This keeps your tests from clashing with your other code.&lt;/i&gt;&lt;br /&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;br /&gt;&lt;i&gt;- Write one test file for each module or class you make.&lt;/i&gt;&lt;br /&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;br /&gt;&lt;i&gt;- Keep your test cases (functions) short, but do not worry if they are a bit messy. Test cases are usually kind of messy.&lt;/i&gt;&lt;br /&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;br /&gt;&lt;i&gt;- Even though test cases are messy, try to keep them clean and remove any repetitive code you can.&lt;/i&gt;&lt;br /&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;br /&gt;&lt;i&gt;- Create helper functions that get rid of duplicate code. You will thank me later when you make a change and then have to change your tests. Duplicated code will make changing your tests more difficult.&lt;/i&gt;&lt;br /&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;br /&gt;&lt;i&gt;- Finally, do not get too attached to your tests. Sometimes, the best way to redesign something is to just delete the tests, and start over.&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;What You Should See&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-URzx9-AeF_Q/TxbLzBs_jUI/AAAAAAAABJU/XJtftF0QWLE/s1600/Screen+shot+2012-01-18+at+5.26.23+AM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="264" src="http://4.bp.blogspot.com/-URzx9-AeF_Q/TxbLzBs_jUI/AAAAAAAABJU/XJtftF0QWLE/s320/Screen+shot+2012-01-18+at+5.26.23+AM.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Extra Credit&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;- Go read about Test::Unit more, and also read about alternatives.&lt;br /&gt;&lt;br /&gt;[&lt;br /&gt;&lt;b&gt;&lt;span style="color: red;"&gt;I found this post to be quite clever :):&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;b&gt;&lt;span style="color: red;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;b&gt;&lt;span style="color: red;"&gt;http://evan.tiggerpalace.com/articles/2010/12/18/ruby-test-unit-sucks-and-why-i-still-use-it/&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;]&lt;br /&gt;&lt;br /&gt;- Learn about Rspec and see if you like it better.&lt;br /&gt;&lt;br /&gt;[&lt;b&gt;&lt;span style="color: red;"&gt;I actively use RSpec in my daily testing, and while I'm not sure if I can say I like it "more", I feel like I have a slightly better understanding of it just by virtue of having used it in conjunction with Cucumber for several months. Ideally, I would have learned Test::Unit first, and then been able to see the parallels better, but I can see the benefits both have&lt;/span&gt;&lt;/b&gt;]&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;TESTHEAD's TAKEAWAYS:&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;I quite enjoyed working with this and doing the additional reading on Test::Unit and getting a chance to compare it with Rspec, which again I will say that I do not have an extensive level of experience with, but enough to be kinda' dangerous (so says the kid with the loaded shotgun). I like the fact that going forward I'll be using this framework (and I can now say I like the way that the skeleton is set up; it really does help focus what you are doing and how it gets accomplished. Most of all, I'm enjoying really seeing how TDD can and should be&amp;nbsp;accomplished, and I like seeing how it should fit together.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6890958153006612459-2521630733157916116?l=www.mkltesthead.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.mkltesthead.com/feeds/2521630733157916116/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6890958153006612459&amp;postID=2521630733157916116' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6890958153006612459/posts/default/2521630733157916116'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6890958153006612459/posts/default/2521630733157916116'/><link rel='alternate' type='text/html' href='http://www.mkltesthead.com/2012/01/exercise-47-automated-testing-learn.html' title='Exercise 47: Automated Testing: Learn Ruby the Hard Way: Practicum'/><author><name>Michael Larsen</name><uri>https://profiles.google.com/104738247543282839437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-L_ARsHiklGg/AAAAAAAAAAI/AAAAAAAABPA/PwBZuynaDbc/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/-Ra9zFBvGHcs/TxbK6D5_XvI/AAAAAAAABI8/0uJZQjRtJ6o/s72-c/Screen+shot+2012-01-18+at+5.21.41+AM.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6890958153006612459.post-5302371845520496991</id><published>2012-01-17T15:00:00.000-08:00</published><updated>2012-01-17T15:26:59.341-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='testing tools'/><category scheme='http://www.blogger.com/atom/ns#' term='productivity'/><category scheme='http://www.blogger.com/atom/ns#' term='collaboration'/><category scheme='http://www.blogger.com/atom/ns#' term='skills development'/><category scheme='http://www.blogger.com/atom/ns#' term='design'/><category scheme='http://www.blogger.com/atom/ns#' term='testing techniques'/><title type='text'>Mind Mapping the HTSM</title><content type='html'>&lt;br /&gt;I'm excited to report that &lt;a href="http://www.atlassian.com/"&gt;Atlassian&lt;/a&gt; (the developer of Jira and lots of other software tools) has been running a variety of posts on their &lt;a href="http://blogs.atlassian.com/blog-cat/developer/"&gt;Developer's Blog&lt;/a&gt; regarding testing topics.&lt;br /&gt;&lt;br /&gt;Atlassian reached out to me and asked me if I'd be interested in contributing something, and I responded by talking about James Bach's &lt;a href="http://www.satisfice.com/tools/satisfice-tsm-4p.pdf"&gt;Heuristic Test Strategy Model&lt;/a&gt; and how it can open up the interview process for testers and help them ferret out information from programs, ranging from as small as at the unit test level, to as large as a fully integrated suite of sophisticated applications (think GoogleDocs or OpenOffice).&lt;br /&gt;&lt;br /&gt;&lt;a href="http://blogs.atlassian.com/2012/01/guest-blog-interviewing-the-product-making-testing-more-flexible/"&gt;The post went live yesterday&lt;/a&gt; and judging from the hit counts from my analytics stats, it seems to be bringing quite a bit of Australia and New Zealand traffic here. To that, I give great thanks. If you'd like to check out the post, please head on over and tell them you came from here.&lt;br /&gt;&lt;br /&gt;The HTSM is a core component of the new Black Box Software Testing course on Test Design. One of the things that we did in the Test Design pilot was to look at the HTSM and create a mind map for a product and use the HTSM as the criteria to set up the map. It was an interesting exercise, but it led me to ask "&lt;a href="http://www.xmind.net/share/mkltesthead/heuristic-testing-strategy-model-%28master%29-2/"&gt;what if I mind mapped the entire HTSM&lt;/a&gt;?" This may be of limited value to some, but what I find to be a significant boost is that, for each area, I can expand and collapse branches and find relevant questions (and if they're not relevant, I can roll them back up and get them out of my way).&lt;br /&gt;&lt;br /&gt;For those who would like to use this mind map, and copy it and expand on it for their own projects, please feel free to, you can reach the live link for the map here (you will need to have XMind installed if you want to modify it). My goal is to get more testers familiar with this approach and to help them develop more dynamic and context-driven test strategies that will make the most sense for the product that is actually being tested, and not some made-up Utopian product that may never exist.&amp;nbsp; Here's hoping that it gives you an edge and a way to have the questions at your fingertips as you test.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6890958153006612459-5302371845520496991?l=www.mkltesthead.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.mkltesthead.com/feeds/5302371845520496991/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6890958153006612459&amp;postID=5302371845520496991' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6890958153006612459/posts/default/5302371845520496991'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6890958153006612459/posts/default/5302371845520496991'/><link rel='alternate' type='text/html' href='http://www.mkltesthead.com/2012/01/mind-mapping-htsm.html' title='Mind Mapping the HTSM'/><author><name>Michael Larsen</name><uri>https://profiles.google.com/104738247543282839437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-L_ARsHiklGg/AAAAAAAAAAI/AAAAAAAABPA/PwBZuynaDbc/s512-c/photo.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6890958153006612459.post-6595155578505288682</id><published>2012-01-17T07:00:00.000-08:00</published><updated>2012-01-17T07:00:00.205-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='education'/><category scheme='http://www.blogger.com/atom/ns#' term='teaching'/><category scheme='http://www.blogger.com/atom/ns#' term='learning'/><category scheme='http://www.blogger.com/atom/ns#' term='books'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='PRACTICUM'/><category scheme='http://www.blogger.com/atom/ns#' term='career development'/><title type='text'>Exercise 46: A Project Skeleton: Learn Ruby the Hard Way: Practicum</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://upload.wikimedia.org/wikipedia/commons/f/f1/Ruby_logo.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="200" src="http://upload.wikimedia.org/wikipedia/commons/f/f1/Ruby_logo.png" width="199" /&gt;&lt;/a&gt;&lt;/div&gt;In this section, Zed and Rob explain how to set up a skeleton directory to start working with projects. I had a lot of help setting up my Macbook Pro environment to run the various tests that I do in my work life. If I were to be told "OK, we are going to have you set up a whole new environment, and we're going to shut down the one you are using currently. Now go and set up your stuff"... truthfully, I'd be more than half lost!&lt;br /&gt;&lt;br /&gt;So what should a skeleton directory contain? It should have all of the basic components necessary to get a new project up and running. It include the project layout, automated tests, modules, and install scripts.&lt;br /&gt;&lt;br /&gt;For this project, since my OSX environment is already set up with all of this, I'll use my PC to set this stuff up.&lt;br /&gt;&lt;br /&gt;Skeleton Contents: PC/Windows&lt;br /&gt;First, create the structure of your skeleton directory with these commands:&lt;br /&gt;&lt;br /&gt;- mkdir projects&lt;br /&gt;- &amp;nbsp;cd projects/&lt;br /&gt;- mkdir skeleton&lt;br /&gt;- cd skeleton&lt;br /&gt;- mkdir bin&lt;br /&gt;- mkdir lib&lt;br /&gt;- mkdir lib/NAME&lt;br /&gt;- mkdir test&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Next we need to setup some initial files:&lt;br /&gt;&lt;br /&gt;- &amp;nbsp;lib/NAME.rb&lt;br /&gt;- &amp;nbsp;touch lib/NAME/version.rb&lt;br /&gt;&lt;br /&gt;Then we can create a NAME.gemspec file in our project's root directory which we can use to install our project later if we want:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-1U3OyVeQbTQ/TxWJoy86N-I/AAAAAAAABHw/PG8iIfCuMQk/s1600/Ex46_Image01.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="242" src="http://3.bp.blogspot.com/-1U3OyVeQbTQ/TxWJoy86N-I/AAAAAAAABHw/PG8iIfCuMQk/s320/Ex46_Image01.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Finally we create a simple skeleton file for unit tests (more on that in the next exercise) named test/test_NAME.rb:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-wVBZvYUBLzg/TxWJtyY3W5I/AAAAAAAABH4/8u-Aq6gtRE0/s1600/Ex46_Image02.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="242" src="http://4.bp.blogspot.com/-wVBZvYUBLzg/TxWJtyY3W5I/AAAAAAAABH4/8u-Aq6gtRE0/s320/Ex46_Image02.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Installing Gems&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Next, install the following software packages:&lt;br /&gt;&lt;br /&gt;git - &lt;a href="http://git-scm.com/"&gt;http://git-scm.com/&lt;/a&gt;&lt;br /&gt;rake - &lt;a href="http://rake.rubyforge.org/"&gt;http://rake.rubyforge.org/&lt;/a&gt;&lt;br /&gt;rvm - &lt;a href="https://rvm.beginrescueend.com/"&gt;https://rvm.beginrescueend.com/&lt;/a&gt;&lt;br /&gt;rubygems - &lt;a href="http://rubygems.org/pages/download"&gt;http://rubygems.org/pages/download&lt;/a&gt;&lt;br /&gt;bundler - &lt;a href="http://gembundler.com/"&gt;http://gembundler.com/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Installing these for Windows was, well, interesting. Outside of a graphical environment for git, most of the other applications were easy to install using the gem install option.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-Q_yvb0M9e5Y/TxWLEl75JzI/AAAAAAAABIQ/A4gY8ApQmu0/s1600/Ex46_Image03.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="171" src="http://3.bp.blogspot.com/-Q_yvb0M9e5Y/TxWLEl75JzI/AAAAAAAABIQ/A4gY8ApQmu0/s320/Ex46_Image03.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-v1avG1JkUdU/TxWK_c25LhI/AAAAAAAABIA/8Sleg7JZRn0/s1600/Ex46_Image04.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="170" src="http://2.bp.blogspot.com/-v1avG1JkUdU/TxWK_c25LhI/AAAAAAAABIA/8Sleg7JZRn0/s320/Ex46_Image04.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-gjfxWtXb-do/TxWK_oH7UYI/AAAAAAAABII/g4gsVyMzJEQ/s1600/Ex46_Image05.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="264" src="http://4.bp.blogspot.com/-gjfxWtXb-do/TxWK_oH7UYI/AAAAAAAABII/g4gsVyMzJEQ/s320/Ex46_Image05.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Using The Skeleton&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;- Make a copy of your skeleton directory. Name it after your new project.&lt;br /&gt;- Rename (move) the NAME directory and NAME.rb file to be the name of your project.&lt;br /&gt;- Edit your NAME.gemspec file to have all the information for your project.&lt;br /&gt;- Rename test/test_NAME.rb to also have your project name.&lt;br /&gt;- Start coding.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;TESTHEAD's TAKEAWAYS:&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;This section is incredibly helpful, in that it finally helped me connect the dots on a lot of things I do every day with Cucumber, but couldn't entirely put my finger on what or how I was doing it. there's a lot more I need to do, certainly, and a fair amount of it is just going to require some practice. I'm definitely going to be playing some more with the Windows git interface so I understand what it does and how to use it effectively.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6890958153006612459-6595155578505288682?l=www.mkltesthead.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.mkltesthead.com/feeds/6595155578505288682/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6890958153006612459&amp;postID=6595155578505288682' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6890958153006612459/posts/default/6595155578505288682'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6890958153006612459/posts/default/6595155578505288682'/><link rel='alternate' type='text/html' href='http://www.mkltesthead.com/2012/01/exercise-46-project-skeleton-learn-ruby.html' title='Exercise 46: A Project Skeleton: Learn Ruby the Hard Way: Practicum'/><author><name>Michael Larsen</name><uri>https://profiles.google.com/104738247543282839437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-L_ARsHiklGg/AAAAAAAAAAI/AAAAAAAABPA/PwBZuynaDbc/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/-1U3OyVeQbTQ/TxWJoy86N-I/AAAAAAAABHw/PG8iIfCuMQk/s72-c/Ex46_Image01.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6890958153006612459.post-7427010665079616079</id><published>2012-01-16T13:00:00.000-08:00</published><updated>2012-01-16T14:00:12.673-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Two Leaf Clover'/><category scheme='http://www.blogger.com/atom/ns#' term='life experience'/><title type='text'>The Perfect Alignment</title><content type='html'>&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://twoleafclover.net/comics/2012-01-16-The-Alignment.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="400" src="http://twoleafclover.net/comics/2012-01-16-The-Alignment.png" width="298" /&gt;&lt;/a&gt;&lt;/div&gt;It's been a while since I've done a Two-Leaf Clover post, but today's just struck me as both funny and appropriate.&lt;br /&gt;&lt;br /&gt;Testers love and hate the law of unintended consequences. We don't quite know when we'll run into one, but make no mistake, if we wait long enough, we will find one. Often, though they tend to find us. At times like that, all you can do is shrug, chuckle a little bit, and pledge to keep that in mind and not do it again the next time.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Too often, we take for granted that when we do simple things &amp;nbsp;or we make cursory examinations, things work the way we expect them to. I used to think that was OK, and that, if it worked in this instance and the several others I could think of, then it would probably be fine in every other instance. Now that I've been doing some actual coding that goes beyond just the trivial, I'm starting to see how wrong in fact that hypothesis is.&lt;br /&gt;&lt;br /&gt;Even in simple games that I've been coding, I realize that there are lots of areas where I think to myself "OK, this will work fine, as long as I don't do this!" What's changed? Well, I've realized through my own blocking of the logic that I know where there are potential bad areas. Does that mean that I go the extra mile to code it better? Sometimes, yes, but sometimes I don't know how to (at least, not yet I don't). Because of that, I am reminded of that fact that just because we don't think people will run across our bugs, doesn't mean we can hide our heads in the sand and pretend they are not there. It's not a matter of if people will find our problems, it's a matter of when.&lt;br /&gt;&lt;br /&gt;Sometimes, to get the "spectacular effect" things just have to be lined up exactly right. Hopefully, they will not be as spectacularly bad (or amusing) as Aaron's example ;).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6890958153006612459-7427010665079616079?l=www.mkltesthead.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.mkltesthead.com/feeds/7427010665079616079/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6890958153006612459&amp;postID=7427010665079616079' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6890958153006612459/posts/default/7427010665079616079'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6890958153006612459/posts/default/7427010665079616079'/><link rel='alternate' type='text/html' href='http://www.mkltesthead.com/2012/01/perfect-alignment.html' title='The Perfect Alignment'/><author><name>Michael Larsen</name><uri>https://profiles.google.com/104738247543282839437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-L_ARsHiklGg/AAAAAAAAAAI/AAAAAAAABPA/PwBZuynaDbc/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6890958153006612459.post-1058208800264012656</id><published>2012-01-16T04:30:00.001-08:00</published><updated>2012-01-17T06:55:18.416-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='education'/><category scheme='http://www.blogger.com/atom/ns#' term='teaching'/><category scheme='http://www.blogger.com/atom/ns#' term='learning'/><category scheme='http://www.blogger.com/atom/ns#' term='books'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='PRACTICUM'/><category scheme='http://www.blogger.com/atom/ns#' term='career development'/><title type='text'>Exercise 45: Is-A, Has-A, Objects, and Classes: Learn Ruby the Hard Way: Practicum</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://upload.wikimedia.org/wikipedia/commons/f/f1/Ruby_logo.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="200" src="http://upload.wikimedia.org/wikipedia/commons/f/f1/Ruby_logo.png" width="199" /&gt;&lt;/a&gt;&lt;/div&gt;OK, true confession; this is where I usually go into brain melt time when I've tried to wrap my head around object oriented programming challenges and assignments. This is the spot where I let the Resistance take full control and say "dude, you're a tester, you *really* don't need to get this in depth... ah, but alas, I can't say that anymore, because I made you all a promise that I wouldn't.&lt;br /&gt;&lt;br /&gt;What is the difference between a Class and an Object? In the Abstract, nothing. They are the same thing at different points in time. Zed uses the following example:&lt;br /&gt;&lt;br /&gt;What is the difference between a Fish and a Salmon?&lt;br /&gt;&lt;br /&gt;My example I used in a previous exercise would be an equivalent: What is the difference between a Car and a Lamborghini?&lt;br /&gt;&lt;br /&gt;Fish and Cars are big order items. We know a fish and a car when we see them. However, there are small characteristics that define where in the Fish world Salmon reside (they aren't Sea Bass or barracuda), and where in the Car world a Lamborghini fits (they aren't a Ford or a Chrysler) For that matter, we could consider a Chinook Salmon or a Diablo Lamborghini even more specific, as they are a sub class of their respective class, which is a sub class of a larger class. Mind bendy huh (and strangely, I feel pretty good with that explanation :) ).&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Zed takes it a step further. Let's say that you have caught three Chinook salmon, and named them Frank, Joe, and Mary. What is the difference between Mary and a Salmon?&lt;br /&gt;&lt;br /&gt;The answer is "nothing, really" except that, instead of being an abstract Chinook salmon, each of these specific Chinook salmon represent real and tangible items within their class. We would say that these three fish are "instances" of their class that we can call on and use. Instances are also called Objects.&lt;br /&gt;&lt;br /&gt;Thus the Chinook Salmon named Mary is an Object. she's a simple instance of a class Chinook, which is part of the Class Salmon, which is part of the Class Fish. Object, Instance or Class, they're pretty much the same thing, just more specific as you go down the order.&lt;br /&gt;&lt;br /&gt;Still, there are differences. When is a Class a Class and when is an Object an Object in its specific state? There are two phrases that can help us make this determination.&lt;br /&gt;&lt;br /&gt;The first is "is-a" and the second is "has-a". we use "is-a" when talking about objects and classes being related to each other (Chinook is-a Salmon is-a Fish). We use "has-a" when classes are related but merely reference each other (fish has-a set of gills and fins, Lamborghini has-a set of tires and seats).&lt;br /&gt;&lt;br /&gt;Below are several examples, and each has a &amp;nbsp;comment labeled '##??' replace each section to reflect if it is an 'is-a' or a 'has-a' relationship, and what that relationship is.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-IbA5QvfGi2U/TxQYH6OOEFI/AAAAAAAABHg/Uwne6lknlwk/s1600/Screen+shot+2012-01-16+at+4.25.50+AM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://1.bp.blogspot.com/-IbA5QvfGi2U/TxQYH6OOEFI/AAAAAAAABHg/Uwne6lknlwk/s320/Screen+shot+2012-01-16+at+4.25.50+AM.png" width="252" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-AjsE7emSYkM/TxQYIRxP2fI/AAAAAAAABHo/BY2RehGjqUM/s1600/Screen+shot+2012-01-16+at+4.26.20+AM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://3.bp.blogspot.com/-AjsE7emSYkM/TxQYIRxP2fI/AAAAAAAABHo/BY2RehGjqUM/s320/Screen+shot+2012-01-16+at+4.26.20+AM.png" width="270" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;TESTHEAD's TAKEAWAYS:&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;There is a number of ways that this can be applied and keeping track of it can be a little confusing, but in &amp;nbsp;away it makes a lot of sense when we just think about it on an individual level and "talk it out" like we see here. The relationships can happen on several levels, and certain objects inherit attributes from parent classes.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6890958153006612459-1058208800264012656?l=www.mkltesthead.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.mkltesthead.com/feeds/1058208800264012656/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6890958153006612459&amp;postID=1058208800264012656' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6890958153006612459/posts/default/1058208800264012656'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6890958153006612459/posts/default/1058208800264012656'/><link rel='alternate' type='text/html' href='http://www.mkltesthead.com/2012/01/exercise-45-is-has-objects-and-classes.html' title='Exercise 45: Is-A, Has-A, Objects, and Classes: Learn Ruby the Hard Way: Practicum'/><author><name>Michael Larsen</name><uri>https://profiles.google.com/104738247543282839437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-L_ARsHiklGg/AAAAAAAAAAI/AAAAAAAABPA/PwBZuynaDbc/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/-IbA5QvfGi2U/TxQYH6OOEFI/AAAAAAAABHg/Uwne6lknlwk/s72-c/Screen+shot+2012-01-16+at+4.25.50+AM.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6890958153006612459.post-3969510086540315278</id><published>2012-01-13T13:00:00.000-08:00</published><updated>2012-01-16T16:19:49.484-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='education'/><category scheme='http://www.blogger.com/atom/ns#' term='teaching'/><category scheme='http://www.blogger.com/atom/ns#' term='learning'/><category scheme='http://www.blogger.com/atom/ns#' term='books'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='PRACTICUM'/><category scheme='http://www.blogger.com/atom/ns#' term='career development'/><title type='text'>Exercise 43 &amp; 44: You Make A Game, Evaluating Your Game: Learn Ruby the Hard Way: Practicum</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://upload.wikimedia.org/wikipedia/commons/f/f1/Ruby_logo.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="200" src="http://upload.wikimedia.org/wikipedia/commons/f/f1/Ruby_logo.png" width="199" /&gt;&lt;/a&gt;&lt;/div&gt;As Zed makes the point at this stage, the time has come where I have to start feeding myself, so in this exercise, I revamped my little haunted house program and made it more modular, as well as made it "Classy".&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Well, sort of. I admit I got lost when I tried to make it so that the system could run as multiple classes at the same time, so in this case, I'm just running one class to run the game, and calling the rooms as methods. It's something I will evaluate again, but I need to get moving on this. Because of that, I'm going to treat the Make a Game and Evaluate the Game exercises together.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-gDsgshBp8jo/TxCbpip2aRI/AAAAAAAABF0/erVXFy4MSVw/s1600/Screen+shot+2012-01-13+at+12.23.30+PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://3.bp.blogspot.com/-gDsgshBp8jo/TxCbpip2aRI/AAAAAAAABF0/erVXFy4MSVw/s320/Screen+shot+2012-01-13+at+12.23.30+PM.png" width="204" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-HfnRqjGqyrk/TxCbqEEXZ7I/AAAAAAAABF8/URE8j1ZvdbA/s1600/Screen+shot+2012-01-13+at+12.25.00+PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="257" src="http://2.bp.blogspot.com/-HfnRqjGqyrk/TxCbqEEXZ7I/AAAAAAAABF8/URE8j1ZvdbA/s320/Screen+shot+2012-01-13+at+12.25.00+PM.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-XP7jagS9ic4/TxCbqpx1RKI/AAAAAAAABGE/9b2NZCXIxwc/s1600/Screen+shot+2012-01-13+at+12.25.30+PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="280" src="http://3.bp.blogspot.com/-XP7jagS9ic4/TxCbqpx1RKI/AAAAAAAABGE/9b2NZCXIxwc/s320/Screen+shot+2012-01-13+at+12.25.30+PM.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-PzA9sxNtPF8/TxCbrZ6XymI/AAAAAAAABGM/BfPYgFgTA_Y/s1600/Screen+shot+2012-01-13+at+12.25.55+PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://1.bp.blogspot.com/-PzA9sxNtPF8/TxCbrZ6XymI/AAAAAAAABGM/BfPYgFgTA_Y/s320/Screen+shot+2012-01-13+at+12.25.55+PM.png" width="319" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-3wK2kEhJ-Hs/TxCbsG9lxcI/AAAAAAAABGU/9TC0fller1M/s1600/Screen+shot+2012-01-13+at+12.26.22+PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="142" src="http://2.bp.blogspot.com/-3wK2kEhJ-Hs/TxCbsG9lxcI/AAAAAAAABGU/9TC0fller1M/s320/Screen+shot+2012-01-13+at+12.26.22+PM.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-OZr0sLN4vB4/TxCbtwKre1I/AAAAAAAABGc/sFtQWsR0wpk/s1600/Screen+shot+2012-01-13+at+12.28.17+PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://3.bp.blogspot.com/-OZr0sLN4vB4/TxCbtwKre1I/AAAAAAAABGc/sFtQWsR0wpk/s320/Screen+shot+2012-01-13+at+12.28.17+PM.png" width="296" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-8xHvTKI4Zow/TxCbuoS5NqI/AAAAAAAABGg/F0WiBDHB_Qo/s1600/Screen+shot+2012-01-13+at+12.29.27+PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="148" src="http://2.bp.blogspot.com/-8xHvTKI4Zow/TxCbuoS5NqI/AAAAAAAABGg/F0WiBDHB_Qo/s320/Screen+shot+2012-01-13+at+12.29.27+PM.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-k8rz8Xz8URs/TxCbvL0Qd3I/AAAAAAAABGs/wycZdxKVtMs/s1600/Screen+shot+2012-01-13+at+12.30.03+PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="293" src="http://4.bp.blogspot.com/-k8rz8Xz8URs/TxCbvL0Qd3I/AAAAAAAABGs/wycZdxKVtMs/s320/Screen+shot+2012-01-13+at+12.30.03+PM.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-wpQk_p3yw2k/TxCbwng5o1I/AAAAAAAABG4/PxUZFIAKns4/s1600/Screen+shot+2012-01-13+at+12.30.25+PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="154" src="http://3.bp.blogspot.com/-wpQk_p3yw2k/TxCbwng5o1I/AAAAAAAABG4/PxUZFIAKns4/s320/Screen+shot+2012-01-13+at+12.30.25+PM.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-7u9yz2Y209E/TxCbx7Uo-vI/AAAAAAAABHA/FYKEGBBfn24/s1600/Screen+shot+2012-01-13+at+12.32.16+PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://2.bp.blogspot.com/-7u9yz2Y209E/TxCbx7Uo-vI/AAAAAAAABHA/FYKEGBBfn24/s320/Screen+shot+2012-01-13+at+12.32.16+PM.png" width="212" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;b&gt;Exercise 44: Evaluating Your Game&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;i&gt;In this exercise you will evaluate the game you just made. Maybe you got part-way through it and you got stuck. Maybe you got it working but just barely. Either way, we're going to go through a bunch of things you should know now and make sure you covered them in your game. We're going to study how to properly format a class, common conventions in using classes, and a lot of "textbook" knowledge.&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;The key here is that Zed and Rob are not going to have us just mimic what they do, they are going to have us try it, succeed or get frustrated (maybe both) and then review what we could do better. Hey, I'm all for it, so let's see what they suggest (note: since this is their advice for reviewing code, I'm basically repeating it verbatim).&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Function Style&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;All the other rules I've taught you about how to make a function nice apply here, but add these things:&lt;br /&gt;&lt;br /&gt;- For various reasons, programmers call functions that are part of classes methods. It's mostly marketing but just be warned that every time you say "function" they'll annoyingly correct you and say "method". If they get too annoying, just ask them to demonstrate the mathematical basis that determines how a "method" is different from a "function" and they'll shut up.&lt;br /&gt;&lt;br /&gt;- When you work with classes much of your time is spent talking about making the class "do things". Instead of naming your functions after what the function does, instead name it as if it's a command you are giving to the class. Same as pop is saying "Hey array, pop this off." It isn't called remove_from_end_of_list because even though that's what it does, that's not a command to an array.&lt;br /&gt;&lt;br /&gt;- Keep your functions small and simple. For some reason when people start learning about classes they forget this.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Class Style&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;- Your class should use "proper case" like SuperGoldFactory rather than super_gold_factory.&lt;br /&gt;&lt;br /&gt;- Try not to do too much in your initialize functions. It makes them harder to use.&lt;br /&gt;&lt;br /&gt;- Your other functions should use "underscore format" so write my_awesome_hair and not myawesomehair or MyAwesomeHair.&lt;br /&gt;&lt;br /&gt;- Be consistent in how you organize your function arguments. If your class has to deal with users, dogs, and cats, keep that order throughout unless it really doesn't make sense. If you have one function that takes (dog, cat, user) and the other takes (user, cat, dog), it'll be hard to use.&lt;br /&gt;&lt;br /&gt;- Try not to use variables that come from the module or globals. They should be fairly self-contained.&lt;br /&gt;&lt;br /&gt;- A foolish consistency is the hobgoblin of little minds. Consistency is good, but foolishly following some idiotic mantra because everyone else does is bad style. Think for yourself.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Code Style&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;- Give your code vertical space so people can read it. You will find some very bad programmers who are able to write reasonable code, but who do not add any spaces. This is bad style in any language because the human eye and brain use space and vertical alignment to scan and separate visual elements. Not having space is the same as giving your code an awesome camouflage paint job.&lt;br /&gt;&lt;br /&gt;- If you can't read it out loud, it's probably hard to read. If you are having a problem making something easy to use, try reading it out loud. Not only does this force you to slow down and really read it, but it also helps you find difficult passages and things to change for readability.&lt;br /&gt;&lt;br /&gt;- Try to do what other people are doing in Ruby until you find your own style.&lt;br /&gt;&lt;br /&gt;- Once you find your own style, do not be a jerk about it. Working with other people's code is part of being a programmer, and other people have really bad taste. Trust me, you will probably have really bad taste too and not even realize it.&lt;br /&gt;&lt;br /&gt;- If you find someone who writes code in a style you like, try writing something that mimics their style.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Good Comments&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;- There are programmers who will tell you that your code should be readable enough that you do not need comments. They'll then tell you in their most official sounding voice that, "Ergo you should never write comments." Those programmers are either consultants who get paid more if other people can't use their code, or incompetents who tend to never work with other people. Ignore them and write comments.&lt;br /&gt;&lt;br /&gt;- When you write comments, describe why you are doing what you are doing. The code already says how, but why you did things the way you did is more important.&lt;br /&gt;&lt;br /&gt;- When you write here doc comments for your functions, make the comments documentation for someone who will have to use your code. You do not have to go crazy, but a nice little sentence about what someone does with that function helps a lot.&lt;br /&gt;&lt;br /&gt;- Finally, while comments are good, too many are bad, and you have to maintain them. Keep your comments relatively short and to the point, and if you change a function, review the comment to make sure it's still correct.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;TESTHEAD's TAKEAWAYS:&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;As I've had the chance to consider the way that I do things, I am getting more and more comfortable seeing how the code is structured and understanding what I'm seeing. As I look into some of the underlying code in my own everyday Cucumber suites (and their requisite step definitions) I'm seeing a lot of places where, before, I would have said "OK, I don't quite get what that is doing, but I'll trust it for now" and instead I'm starting to see where I have errors and what should be there in their place. Additionally, I'm starting to notice where style differentiations make a difference and where they don't. &amp;nbsp;All in all, it's been good practice and very helpful.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6890958153006612459-3969510086540315278?l=www.mkltesthead.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.mkltesthead.com/feeds/3969510086540315278/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6890958153006612459&amp;postID=3969510086540315278' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6890958153006612459/posts/default/3969510086540315278'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6890958153006612459/posts/default/3969510086540315278'/><link rel='alternate' type='text/html' href='http://www.mkltesthead.com/2012/01/exercise-43-44-you-make-game-evaluating.html' title='Exercise 43 &amp; 44: You Make A Game, Evaluating Your Game: Learn Ruby the Hard Way: Practicum'/><author><name>Michael Larsen</name><uri>https://profiles.google.com/104738247543282839437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-L_ARsHiklGg/AAAAAAAAAAI/AAAAAAAABPA/PwBZuynaDbc/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/-gDsgshBp8jo/TxCbpip2aRI/AAAAAAAABF0/erVXFy4MSVw/s72-c/Screen+shot+2012-01-13+at+12.23.30+PM.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6890958153006612459.post-4256971994929890145</id><published>2012-01-12T15:30:00.000-08:00</published><updated>2012-01-12T15:54:02.939-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='productivity'/><category scheme='http://www.blogger.com/atom/ns#' term='learning'/><category scheme='http://www.blogger.com/atom/ns#' term='books'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><title type='text'>Book Review: bash Cookbook</title><content type='html'>&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://akamaicovers.oreilly.com/images/9780596526788/cat.gif" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://akamaicovers.oreilly.com/images/9780596526788/cat.gif" /&gt;&lt;/a&gt;&lt;/div&gt;When I started working with SideReel, I was overjoyed to receive a Macbook Pro as my primary work system. The reason? It meant I'd be able to get re-acquainted with the UNIX shell again after a long time away. Having been a regular user of the shell in the 90s, but having not worked with it regularly for many years, I figured the &lt;a href="http://www.amazon.com/Bash-Cookbook-Solutions-Examples-Cookbooks/dp/0596526784/ref=sr_1_1?ie=UTF8&amp;amp;qid=1326412143&amp;amp;sr=8-1"&gt;bash Cookbook&lt;/a&gt; would be a good way to get back into the swing of things and update my shell scripting vocabulary.&lt;br /&gt;&lt;br /&gt;This is the kind of book that, for all intents and purposes, is impossible to review completely. Generally speaking, these types of books serves two purposes. The first is that it presents a number of questions and issues, and then it provides potential answers. The second is that it works as a kind of roundabout reference guide (and not a complete one). Most people will not, if they are in their right minds, go through each one of these entries and try them serially. They will, instead, keep this book in reserve until they have a particular question, and then look up that solution and extrapolate if it and other associated suggestions may help them achieve a particular goal.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;It is with this consideration that I give some well deserved praise for the bash Cookbook. Note, if you are a newcomer to the bash shell, then this is going to be a confusing place to start. If you have worked with other shells and have familiarity with shell programming syntax, and have spent a little time online to learn some of the specifics of how the bash shell responds to user input, handles redirects, and understand some of its basic&amp;nbsp;idiosyncrasies, then this will be a good, and fun, &amp;nbsp;book to work through and play with.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;From basic interactions to advanced level operations and automation, each tip is structured the same way. A &lt;b&gt;Problem&lt;/b&gt; is presented to the reader, usually in a one or two line format. The book then presents a &lt;b&gt;Solution&lt;/b&gt; based on the previous Problem. Each section then follows with a &lt;b&gt;Discussion&lt;/b&gt; that describes the particular technique or recipe in depth. Finally, there is a listing of "&lt;b&gt;See Also&lt;/b&gt;" topics that might help inform the development of your scripts. Note, I have purchased the PDF version of this book, and the PDF version has fully indexed all of the "See Also" links to jump to those particular recipes (a wonderful time saver :) ).&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The cookbook style is not for everyone. This is not meant to be a pure tutorial guide or a structured reference. The cookbook format is structured to give various examples that, when experimented with, can lead to many jumping off points for your own scripts. Likewise, as with a standard cookbook, users will need to play around with the recipes and see if they will meet their specific needs, or see how much experimentation is required to get their desired result.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Although it is set up in small topic sections, and while the topics do not necessarily blend into each other, the coverage is such that, if you do go through the first several chapters, you will learn a lot about shell interaction and methods of programming the shell. From there, having the ability to cross reference other suggestions in often far distant chapters can be quite helpful and help tie individual tips and tricks together.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Bottom Line:&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;For those who plan to use any variant of UNIX/Linux and want to be able to master many file related or text manipulation processes, the command line is the way to go. If you have any intention of using the UNIX command line, getting a handle on the many techniques available to users, the teeming number of utilities available, and a varied approach to learning about how to use them to solve particular problems (both general and specific), and bash happens to be your weapon of choice, and perchance you already have a basic familiarity with the process of programming the bash shell, then the bash cookbook would be a good addition to your personal reference library. It's a gift that keeps on giving.&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6890958153006612459-4256971994929890145?l=www.mkltesthead.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.mkltesthead.com/feeds/4256971994929890145/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6890958153006612459&amp;postID=4256971994929890145' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6890958153006612459/posts/default/4256971994929890145'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6890958153006612459/posts/default/4256971994929890145'/><link rel='alternate' type='text/html' href='http://www.mkltesthead.com/2012/01/book-review-bash-cookbook.html' title='Book Review: bash Cookbook'/><author><name>Michael Larsen</name><uri>https://profiles.google.com/104738247543282839437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-L_ARsHiklGg/AAAAAAAAAAI/AAAAAAAABPA/PwBZuynaDbc/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6890958153006612459.post-772134559857107126</id><published>2012-01-11T12:00:00.000-08:00</published><updated>2012-01-11T20:48:11.410-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PLP'/><category scheme='http://www.blogger.com/atom/ns#' term='teaching'/><category scheme='http://www.blogger.com/atom/ns#' term='collaboration'/><category scheme='http://www.blogger.com/atom/ns#' term='screencasts'/><category scheme='http://www.blogger.com/atom/ns#' term='skills development'/><category scheme='http://www.blogger.com/atom/ns#' term='speaking'/><category scheme='http://www.blogger.com/atom/ns#' term='presenting'/><category scheme='http://www.blogger.com/atom/ns#' term='life experience'/><title type='text'>Pair, Learn, Present?</title><content type='html'>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.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="https://twitter.com/#!/ajay184f"&gt;Ajay Balamurugadas&lt;/a&gt;&amp;nbsp;and&amp;nbsp;&lt;a href="https://twitter.com/#!/bjosman"&gt;Brian Osman&lt;/a&gt;&amp;nbsp;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), &lt;a href="http://pairlearnpresent.blogspot.com/"&gt;&lt;b&gt;Pair, Learn, Present&lt;/b&gt;&lt;/a&gt; is meant to help testers develop their skills as presenters (like, in public, with a full room of people, on testing and technical topics).&lt;br /&gt;&lt;br /&gt;Are you interested yet?&lt;br /&gt;&lt;br /&gt;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.&lt;span style="color: #333333; font-family: Georgia, serif;"&gt;&lt;b&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="line-height: 20px;"&gt;&lt;br style="background-color: white; text-align: left;" /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;span style="background-color: white; color: #333333; font-family: Georgia, serif; font-size: 13px; line-height: 18px;"&gt;&lt;b&gt;&lt;span style="font-family: inherit;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;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.&lt;br /&gt;&lt;span style="color: #333333; font-size: x-small;"&gt;&lt;span style="line-height: 18px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;You can also connect with PLP here:&lt;br /&gt;&lt;br /&gt;On Twitter: &lt;a href="https://twitter.com/#!/PLP_Learning"&gt;@PLP_Learning&lt;/a&gt;&lt;br /&gt;On Facebook: &lt;a href="https://www.facebook.com/profile.php?id=100003306257247"&gt;https://www.facebook.com/profile.php?id=100003306257247&lt;/a&gt;&lt;br /&gt;On Skype: PairLearnPresent&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;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 :).&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6890958153006612459-772134559857107126?l=www.mkltesthead.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.mkltesthead.com/feeds/772134559857107126/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6890958153006612459&amp;postID=772134559857107126' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6890958153006612459/posts/default/772134559857107126'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6890958153006612459/posts/default/772134559857107126'/><link rel='alternate' type='text/html' href='http://www.mkltesthead.com/2012/01/pair-learn-present.html' title='Pair, Learn, Present?'/><author><name>Michael Larsen</name><uri>https://profiles.google.com/104738247543282839437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-L_ARsHiklGg/AAAAAAAAAAI/AAAAAAAABPA/PwBZuynaDbc/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6890958153006612459.post-5864608006939628747</id><published>2012-01-10T14:00:00.000-08:00</published><updated>2012-01-11T09:11:31.708-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='people'/><category scheme='http://www.blogger.com/atom/ns#' term='motivation'/><category scheme='http://www.blogger.com/atom/ns#' term='life experience'/><title type='text'>Don't Quit!</title><content type='html'>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.&amp;nbsp;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. &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;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. &lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;i&gt;&lt;u&gt;Don’t Quit &lt;/u&gt;&lt;/i&gt;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;i&gt;When things go wrong, as they sometimes will, &lt;br /&gt;When the road you’re treading seems all uphill, &lt;br /&gt;When the funds are low and the debts are high, &lt;br /&gt;And you want to smile, but you have to sigh, &lt;br /&gt;When  care is pressing you down a bit, &lt;br /&gt;Rest if you must- but do not quit. &lt;br /&gt;&lt;br /&gt;  Life is queer with its twists and turns, &lt;br /&gt;As every one of us sometimes learns, &lt;br /&gt;And many a failure turns about &lt;br /&gt;When he might have won had he stuck it out; &lt;br /&gt;Don’t give up, though the pace seems slow- &lt;br /&gt;You might succeed with another blow. &lt;br /&gt;  &lt;br /&gt;Often the goal is nearer than it seems &lt;br /&gt;To a faint and faltering man, &lt;br /&gt;Often the struggler has given up&lt;br /&gt; When he might have captured the victor’s cup. &lt;br /&gt;And he learned too late, when the night slipped down, &lt;br /&gt;How close he was to the golden crown. &lt;br /&gt;  &lt;br /&gt;Success is failure turned inside out- &lt;br /&gt;The silver tint of the clouds of doubt- &lt;br /&gt;And you never can tell how close you are, &lt;br /&gt;It may be near when it seems afar; &lt;br /&gt;So stick to the fight when you’re hardest hit- &lt;br /&gt;It’s when things seem worst that you mustn’t quit. &lt;br /&gt;&lt;br /&gt;--Author Unknown&lt;/i&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6890958153006612459-5864608006939628747?l=www.mkltesthead.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.mkltesthead.com/feeds/5864608006939628747/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6890958153006612459&amp;postID=5864608006939628747' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6890958153006612459/posts/default/5864608006939628747'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6890958153006612459/posts/default/5864608006939628747'/><link rel='alternate' type='text/html' href='http://www.mkltesthead.com/2012/01/dont-quit.html' title='Don&apos;t Quit!'/><author><name>Michael Larsen</name><uri>https://profiles.google.com/104738247543282839437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-L_ARsHiklGg/AAAAAAAAAAI/AAAAAAAABPA/PwBZuynaDbc/s512-c/photo.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6890958153006612459.post-5283068673102117417</id><published>2012-01-10T05:00:00.000-08:00</published><updated>2012-01-10T13:57:36.768-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='people'/><category scheme='http://www.blogger.com/atom/ns#' term='skills development'/><category scheme='http://www.blogger.com/atom/ns#' term='philosophy'/><category scheme='http://www.blogger.com/atom/ns#' term='life experience'/><title type='text'>Character Still Counts These Days</title><content type='html'>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.&lt;br /&gt;&lt;br /&gt;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.).&lt;br /&gt;&lt;br /&gt;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 &amp;amp; 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.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;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."&lt;br /&gt;&lt;br /&gt;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 &lt;i style="font-weight: bold;"&gt;that &lt;/i&gt;took me by complete surprise!&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;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!"&lt;br /&gt;&lt;br /&gt;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 ;).&lt;br /&gt;&lt;br /&gt;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 &lt;i style="font-weight: bold;"&gt;can&lt;/i&gt;&amp;nbsp;I do?!" Thomas Edison is famously quoted for saying&amp;nbsp;"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!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6890958153006612459-5283068673102117417?l=www.mkltesthead.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.mkltesthead.com/feeds/5283068673102117417/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6890958153006612459&amp;postID=5283068673102117417' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6890958153006612459/posts/default/5283068673102117417'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6890958153006612459/posts/default/5283068673102117417'/><link rel='alternate' type='text/html' href='http://www.mkltesthead.com/2012/01/character-still-counts-these-days.html' title='Character Still Counts These Days'/><author><name>Michael Larsen</name><uri>https://profiles.google.com/104738247543282839437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-L_ARsHiklGg/AAAAAAAAAAI/AAAAAAAABPA/PwBZuynaDbc/s512-c/photo.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6890958153006612459.post-3598815963993929442</id><published>2012-01-09T15:00:00.000-08:00</published><updated>2012-01-09T18:04:32.463-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='skills development'/><category scheme='http://www.blogger.com/atom/ns#' term='books'/><category scheme='http://www.blogger.com/atom/ns#' term='security'/><category scheme='http://www.blogger.com/atom/ns#' term='career development'/><category scheme='http://www.blogger.com/atom/ns#' term='testing techniques'/><title type='text'>Book Review: The Tangled Web: A Guide to Securing Modern Web Applications</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://nostarch.com/sites/default/files/imagecache/product_full/tangledWeb_cvr-webquality.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://nostarch.com/sites/default/files/imagecache/product_full/tangledWeb_cvr-webquality.png" width="240" /&gt;&lt;/a&gt;&lt;/div&gt;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?"&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Michal Zalewski provides an answer in "&lt;a href="http://nostarch.com/tangledweb.htm"&gt;The Tangled Web&lt;/a&gt;". 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.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;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!).&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;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).&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Bottom Line:&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;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 &lt;a href="http://nostarch.com/tangledweb.htm"&gt;The Tangled Web&lt;/a&gt;. 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.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6890958153006612459-3598815963993929442?l=www.mkltesthead.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.mkltesthead.com/feeds/3598815963993929442/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6890958153006612459&amp;postID=3598815963993929442' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6890958153006612459/posts/default/3598815963993929442'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6890958153006612459/posts/default/3598815963993929442'/><link rel='alternate' type='text/html' href='http://www.mkltesthead.com/2012/01/book-review-tangled-web-guide-to.html' title='Book Review: The Tangled Web: A Guide to Securing Modern Web Applications'/><author><name>Michael Larsen</name><uri>https://profiles.google.com/104738247543282839437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-L_ARsHiklGg/AAAAAAAAAAI/AAAAAAAABPA/PwBZuynaDbc/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6890958153006612459.post-7442690493338141303</id><published>2012-01-09T05:00:00.000-08:00</published><updated>2012-01-09T10:50:15.689-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='education'/><category scheme='http://www.blogger.com/atom/ns#' term='teaching'/><category scheme='http://www.blogger.com/atom/ns#' term='learning'/><category scheme='http://www.blogger.com/atom/ns#' term='books'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='PRACTICUM'/><category scheme='http://www.blogger.com/atom/ns#' term='career development'/><title type='text'>Exercise 42: Gothons Are Getting Classy: Learn Ruby the Hard Way: Practicum</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://upload.wikimedia.org/wikipedia/commons/f/f1/Ruby_logo.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="200" src="http://upload.wikimedia.org/wikipedia/commons/f/f1/Ruby_logo.png" width="199" /&gt;&lt;/a&gt;&lt;/div&gt;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.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;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".&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;We've actually been using classes quite a bit so far without realizing it. Examples are as follows:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;stuff = ['Test', 'This', 'Out']&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;puts stuff.join(' ')&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;stuff is actually an Array class.&lt;br /&gt;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?&lt;br /&gt;&lt;br /&gt;Here's an example class. They are easier to make compared to hashes, but they have their own syntactic details to remember.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-KJEBEIDZnAk/TwrnpJcVZ4I/AAAAAAAABEc/JbHkAq3JuF8/s1600/Screen+shot+2012-01-09+at+4.46.45+AM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="313" src="http://4.bp.blogspot.com/-KJEBEIDZnAk/TwrnpJcVZ4I/AAAAAAAABEc/JbHkAq3JuF8/s320/Screen+shot+2012-01-09+at+4.46.45+AM.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-6HyZVxHkQHM/TwrntWCNKvI/AAAAAAAABEk/NPY79qklPJM/s1600/Screen+shot+2012-01-09+at+5.02.12+AM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="256" src="http://1.bp.blogspot.com/-6HyZVxHkQHM/TwrntWCNKvI/AAAAAAAABEk/NPY79qklPJM/s320/Screen+shot+2012-01-09+at+5.02.12+AM.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;We do that by including the attr_reader :number line.&lt;br /&gt;If we wanted to make @number write-only, we could change the line to "attr_writer :number".&lt;br /&gt;To make it read/write we could change the line to "attr_accessor :number".&lt;br /&gt;&lt;br /&gt;This is all part of what is referred to as "encapsulating data" within an object-oriented context.&lt;br /&gt;&lt;br /&gt;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 &amp;nbsp;in the add_me_up() functions, where we add to the @number that we created.&lt;br /&gt;&lt;br /&gt;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:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-_-EDGyldgK0/TwrpdLAkZFI/AAAAAAAABEs/x6xy35ll5K0/s1600/Screen+shot+2012-01-09+at+5.13.49+AM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="311" src="http://4.bp.blogspot.com/-_-EDGyldgK0/TwrpdLAkZFI/AAAAAAAABEs/x6xy35ll5K0/s320/Screen+shot+2012-01-09+at+5.13.49+AM.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-3K-czx1zIjc/TwrpdoMie7I/AAAAAAAABE0/EBdmj02i-1U/s1600/Screen+shot+2012-01-09+at+5.14.36+AM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://4.bp.blogspot.com/-3K-czx1zIjc/TwrpdoMie7I/AAAAAAAABE0/EBdmj02i-1U/s320/Screen+shot+2012-01-09+at+5.14.36+AM.png" width="290" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-SZqFefdsLmM/TwrpeDPkV5I/AAAAAAAABE8/bCs6MTtsMbs/s1600/Screen+shot+2012-01-09+at+5.14.50+AM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="230" src="http://3.bp.blogspot.com/-SZqFefdsLmM/TwrpeDPkV5I/AAAAAAAABE8/bCs6MTtsMbs/s320/Screen+shot+2012-01-09+at+5.14.50+AM.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-iTmcdcc9_es/TwrpepQsx1I/AAAAAAAABFE/4yjHICjT_j8/s1600/Screen+shot+2012-01-09+at+5.15.09+AM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://4.bp.blogspot.com/-iTmcdcc9_es/TwrpepQsx1I/AAAAAAAABFE/4yjHICjT_j8/s320/Screen+shot+2012-01-09+at+5.15.09+AM.png" width="273" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-lAlxMFaiI9s/TwrpfWFlSHI/AAAAAAAABFM/55gOVvPyCaY/s1600/Screen+shot+2012-01-09+at+5.15.29+AM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://2.bp.blogspot.com/-lAlxMFaiI9s/TwrpfWFlSHI/AAAAAAAABFM/55gOVvPyCaY/s320/Screen+shot+2012-01-09+at+5.15.29+AM.png" width="273" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-h7OXKAkzDAI/Twrpfwv9SoI/AAAAAAAABFU/YSt8rmmh9Dk/s1600/Screen+shot+2012-01-09+at+5.15.52+AM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://2.bp.blogspot.com/-h7OXKAkzDAI/Twrpfwv9SoI/AAAAAAAABFU/YSt8rmmh9Dk/s320/Screen+shot+2012-01-09+at+5.15.52+AM.png" width="265" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;What You Should See&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-Z-Jr9vNuamY/TwrpoeNcxMI/AAAAAAAABFc/hbe5N7HqTds/s1600/Screen+shot+2012-01-09+at+5.18.28+AM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://1.bp.blogspot.com/-Z-Jr9vNuamY/TwrpoeNcxMI/AAAAAAAABFc/hbe5N7HqTds/s320/Screen+shot+2012-01-09+at+5.18.28+AM.png" width="221" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-898x86Cj9ok/Twrpo9uHnOI/AAAAAAAABFk/sz6nfrWzwdk/s1600/Screen+shot+2012-01-09+at+5.19.16+AM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="266" src="http://4.bp.blogspot.com/-898x86Cj9ok/Twrpo9uHnOI/AAAAAAAABFk/sz6nfrWzwdk/s320/Screen+shot+2012-01-09+at+5.19.16+AM.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;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 :).&lt;br /&gt;&lt;br /&gt;&lt;b&gt;TESTHEAD's TAKEAWAYS:&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;The key details we need to be aware of when we are looking at classes and how they are used are as follows:&lt;br /&gt;&lt;br /&gt;- We made a class called Game and put functions inside it.&lt;br /&gt;- Initialize is a special initialization method that sets up important variables.&lt;br /&gt;- We can add functions to a class by nesting their definitions under the class keyword.&lt;br /&gt;- We can nest the contents of the functions under their names.&lt;br /&gt;- We can see how "@" is used with initialize, play, and death.&lt;br /&gt;- We created a "Game" instance at the end and then told it to "play()". That's how everything got started.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6890958153006612459-7442690493338141303?l=www.mkltesthead.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.mkltesthead.com/feeds/7442690493338141303/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6890958153006612459&amp;postID=7442690493338141303' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6890958153006612459/posts/default/7442690493338141303'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6890958153006612459/posts/default/7442690493338141303'/><link rel='alternate' type='text/html' href='http://www.mkltesthead.com/2012/01/exercise-42-gothons-are-getting-classy.html' title='Exercise 42: Gothons Are Getting Classy: Learn Ruby the Hard Way: Practicum'/><author><name>Michael Larsen</name><uri>https://profiles.google.com/104738247543282839437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-L_ARsHiklGg/AAAAAAAAAAI/AAAAAAAABPA/PwBZuynaDbc/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/-KJEBEIDZnAk/TwrnpJcVZ4I/AAAAAAAABEc/JbHkAq3JuF8/s72-c/Screen+shot+2012-01-09+at+4.46.45+AM.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6890958153006612459.post-9173025536230153179</id><published>2012-01-05T13:30:00.000-08:00</published><updated>2012-01-05T13:50:57.828-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='weekend testing'/><title type='text'>A Less Wayward Weekend Testing Americas</title><content type='html'>&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-vt7toyNd0rU/TwYUj4ogA-I/AAAAAAAABEU/JMKFSWLBYek/s1600/WTlogo.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="71" src="http://1.bp.blogspot.com/-vt7toyNd0rU/TwYUj4ogA-I/AAAAAAAABEU/JMKFSWLBYek/s320/WTlogo.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;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, &lt;i&gt;I had to be there&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;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 &lt;i&gt;Albert also be available&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;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 &lt;b&gt;first Saturday of each month&lt;/b&gt;. 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.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;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:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;If you come to Weekend Testing Americas sessions, why do you come out to them?&lt;/li&gt;&lt;li&gt;If you used to come out, but don't any longer, what is the reason you stopped coming?&lt;/li&gt;&lt;li&gt;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?&lt;/li&gt;&lt;li&gt;If you have had no intention at all to participate and still don't, why?&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;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&amp;nbsp;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.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Weekend Testing – Americas Chapter Session No. 23&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Session Type:&lt;/b&gt; Game Play, Brainstorming, Bug Hunting&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Date:&lt;/b&gt; Saturday, January 07, 2012&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Time:&lt;/b&gt; 10:00 a.m. – 12:00 p.m. PST. &lt;a href="http://timeanddate.com/worldclock/fixedtime.html?msg=Weekend+Testing+Americas+%2323&amp;amp;iso=20120107T10&amp;amp;p1=283&amp;amp;ah=2"&gt;Check to see session time in your time zone&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;To join this session, please do the following:&lt;br /&gt;&lt;br /&gt;1. Add “&lt;b&gt;weekendtestersamericas&lt;/b&gt;” to your Skype contacts if you haven’t already.  Request to have us add you as well.&lt;br /&gt;&lt;br /&gt;2. Fifteen minutes prior to the start of the session, please message “&lt;b&gt;weekendtestingamericas&lt;/b&gt;” and ask to be added to the chat session. Once we see you, we will add you to the session.&lt;br /&gt;&lt;br /&gt;For more details, or to be added to our regular distribution, please contact &lt;b&gt;WTAmericas ( at ) gmail (dot) com&lt;/b&gt;.&lt;br /&gt;&lt;br /&gt;Hope to see you there :).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6890958153006612459-9173025536230153179?l=www.mkltesthead.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.mkltesthead.com/feeds/9173025536230153179/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6890958153006612459&amp;postID=9173025536230153179' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6890958153006612459/posts/default/9173025536230153179'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6890958153006612459/posts/default/9173025536230153179'/><link rel='alternate' type='text/html' href='http://www.mkltesthead.com/2012/01/less-wayward-weekend-testing-americas.html' title='A Less Wayward Weekend Testing Americas'/><author><name>Michael Larsen</name><uri>https://profiles.google.com/104738247543282839437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-L_ARsHiklGg/AAAAAAAAAAI/AAAAAAAABPA/PwBZuynaDbc/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/-vt7toyNd0rU/TwYUj4ogA-I/AAAAAAAABEU/JMKFSWLBYek/s72-c/WTlogo.jpg' height='72' width='72'/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6890958153006612459.post-5434415283923650486</id><published>2012-01-04T17:00:00.000-08:00</published><updated>2012-01-04T17:00:01.958-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='productivity'/><category scheme='http://www.blogger.com/atom/ns#' term='goals'/><category scheme='http://www.blogger.com/atom/ns#' term='learning'/><category scheme='http://www.blogger.com/atom/ns#' term='books'/><title type='text'>Book Review: The Creative Habit: Learn It and Use It for Life</title><content type='html'>&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://ecx.images-amazon.com/images/I/51U-BkmvXWL._BO2,204,203,200_PIsitb-sticker-arrow-click,TopRight,35,-76_AA300_SH20_OU01_.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://ecx.images-amazon.com/images/I/51U-BkmvXWL._BO2,204,203,200_PIsitb-sticker-arrow-click,TopRight,35,-76_AA300_SH20_OU01_.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;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.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Over the years, I've had&amp;nbsp;numerous&amp;nbsp;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".&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;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 &lt;b&gt;&lt;i&gt;are&lt;/i&gt;&lt;/b&gt; 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.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;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. "&lt;a href="http://www.amazon.com/Creative-Habit-Learn-Use-Life/dp/0743235274/ref=sr_1_1?ie=UTF8&amp;amp;qid=1325723659&amp;amp;sr=8-1"&gt;The Creative Habit&lt;/a&gt;" 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.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The second chapter, &lt;i&gt;Rituals of Preparation&lt;/i&gt;, 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).&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;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:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;What is the best idea you've ever had?&amp;nbsp;&lt;/li&gt;&lt;li&gt;What made it great in your mind?&lt;/li&gt;&lt;li&gt;What are your habits? What patterns do you repeat?&lt;/li&gt;&lt;li&gt;When faced with impending success or the threat of failure, how do you respond?&lt;/li&gt;&lt;li&gt;At what moments do you feel your reach exceed your grasp?&lt;/li&gt;&lt;li&gt;What is your idea of mastery?&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Bottom Line:&amp;nbsp;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;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 &lt;a href="http://www.amazon.com/Creative-Habit-Learn-Use-Life/dp/0743235274/ref=sr_1_1?ie=UTF8&amp;amp;qid=1325723659&amp;amp;sr=8-1"&gt;The Creative Habit&lt;/a&gt;, and a lot that can be applied to whatever endeavor you aspire to.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6890958153006612459-5434415283923650486?l=www.mkltesthead.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.mkltesthead.com/feeds/5434415283923650486/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6890958153006612459&amp;postID=5434415283923650486' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6890958153006612459/posts/default/5434415283923650486'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6890958153006612459/posts/default/5434415283923650486'/><link rel='alternate' type='text/html' href='http://www.mkltesthead.com/2012/01/book-review-creative-habit-learn-it-and.html' title='Book Review: The Creative Habit: Learn It and Use It for Life'/><author><name>Michael Larsen</name><uri>https://profiles.google.com/104738247543282839437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-L_ARsHiklGg/AAAAAAAAAAI/AAAAAAAABPA/PwBZuynaDbc/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6890958153006612459.post-7100631262395857795</id><published>2012-01-04T10:00:00.000-08:00</published><updated>2012-01-04T10:16:40.134-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='education'/><category scheme='http://www.blogger.com/atom/ns#' term='teaching'/><category scheme='http://www.blogger.com/atom/ns#' term='learning'/><category scheme='http://www.blogger.com/atom/ns#' term='books'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='PRACTICUM'/><category scheme='http://www.blogger.com/atom/ns#' term='career development'/><title type='text'>Exercise 41: Gothons From Planet Percal #25: Learn Ruby the Hard Way: Practicum</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://upload.wikimedia.org/wikipedia/commons/f/f1/Ruby_logo.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="200" src="http://upload.wikimedia.org/wikipedia/commons/f/f1/Ruby_logo.png" width="199" /&gt;&lt;/a&gt;&lt;/div&gt;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 &lt;i&gt;is my hard completion deadline for this project&lt;/i&gt; :) ).&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;Here's the code block that they wanted me to focus on:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;cities[:find] = method(:find_city)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;puts cities[:find].call(cities, state)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;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 ;) ).&lt;br /&gt;&lt;br /&gt;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".&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;The 2nd line of code does the following:&lt;br /&gt;&lt;br /&gt;Ruby reads the variable "cities" and determines it's a hash/dictionary.&lt;br /&gt;&lt;br /&gt;[:find] looks at the "cities" hash/dictionary and evaluates the value of &amp;nbsp;":find".&lt;br /&gt;&lt;br /&gt;This is the proc "find_city" that we set up using "method". When it sees the method ".call", it calls the proc code.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;If it finds a match, it returns it. If it doesn't it returns a message saying it couldn't find a match.&lt;br /&gt;&lt;br /&gt;Finally, prints out the value returned by the ":find_city" proc using the puts method.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;Try this:&lt;br /&gt;&lt;br /&gt;* state and city are...&lt;br /&gt;* passed as parameters to...&lt;br /&gt;* a proc at...&lt;br /&gt;* :find inside...&lt;br /&gt;* the hash cities...&lt;br /&gt;* and finally printed on the screen&lt;br /&gt;&lt;br /&gt;Here's another way to read it, this time "inside-out".&lt;br /&gt;&lt;br /&gt;* Find the center item of the expression, in this case [:find].&lt;br /&gt;* Go counter-clock-wise and you have a hash cities, so this finds the element :find in cities.&lt;br /&gt;* That gives us a proc. Keep going counter-clock-wise and you get to the parameters.&lt;br /&gt;* The parameters are passed to the proc, and that returns a result. Go counter-clock-wise again.&lt;br /&gt;* Finally, we are at the puts statement, and we have our end result.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;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!).&lt;br /&gt;&lt;br /&gt;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:&lt;br /&gt;&lt;br /&gt;* Front to back.&lt;br /&gt;* Back to front.&lt;br /&gt;* Counter-clock-wise.&lt;br /&gt;&lt;br /&gt;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:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-EsxvHUCUCW4/TwRgKCQd0rI/AAAAAAAABCo/RIxQkPogDso/s1600/Screen+shot+2012-01-04+at+5.56.47+AM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="164" src="http://1.bp.blogspot.com/-EsxvHUCUCW4/TwRgKCQd0rI/AAAAAAAABCo/RIxQkPogDso/s320/Screen+shot+2012-01-04+at+5.56.47+AM.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-YqZHbswt72w/TwRgK8tsFAI/AAAAAAAABCw/6smiyvUdMvA/s1600/Screen+shot+2012-01-04+at+5.57.10+AM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://3.bp.blogspot.com/-YqZHbswt72w/TwRgK8tsFAI/AAAAAAAABCw/6smiyvUdMvA/s320/Screen+shot+2012-01-04+at+5.57.10+AM.png" width="301" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-_4Sj04kLPOE/TwRgLa2OMUI/AAAAAAAABC4/kxGSumM5A6E/s1600/Screen+shot+2012-01-04+at+5.57.30+AM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="268" src="http://2.bp.blogspot.com/-_4Sj04kLPOE/TwRgLa2OMUI/AAAAAAAABC4/kxGSumM5A6E/s320/Screen+shot+2012-01-04+at+5.57.30+AM.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-plNgc63WXPY/TwRgL-GVfPI/AAAAAAAABDA/bYAEE0mN3kw/s1600/Screen+shot+2012-01-04+at+5.57.44+AM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="282" src="http://3.bp.blogspot.com/-plNgc63WXPY/TwRgL-GVfPI/AAAAAAAABDA/bYAEE0mN3kw/s320/Screen+shot+2012-01-04+at+5.57.44+AM.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-27yzTG6N2Qo/TwRgMsPQqtI/AAAAAAAABDI/4SluEUzRbK4/s1600/Screen+shot+2012-01-04+at+5.58.00+AM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="244" src="http://1.bp.blogspot.com/-27yzTG6N2Qo/TwRgMsPQqtI/AAAAAAAABDI/4SluEUzRbK4/s320/Screen+shot+2012-01-04+at+5.58.00+AM.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-XNWLpNT3Ud8/TwRgM9QaLtI/AAAAAAAABDQ/Cc2cmre68Pg/s1600/Screen+shot+2012-01-04+at+5.58.45+AM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="186" src="http://2.bp.blogspot.com/-XNWLpNT3Ud8/TwRgM9QaLtI/AAAAAAAABDQ/Cc2cmre68Pg/s320/Screen+shot+2012-01-04+at+5.58.45+AM.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;What You Should See&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;$ ruby ex41.rb&lt;br /&gt;&lt;br /&gt;--------&lt;br /&gt;The Gothons of Planet Percal #25 have invaded your ship and destroyed&lt;br /&gt;your entire crew. &amp;nbsp;You are the last surviving member and your last&lt;br /&gt;mission is to get the neutron destruct bomb from the Weapons Armory,&lt;br /&gt;put it in the bridge, and blow the ship up after getting into an&lt;br /&gt;escape pod.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;You're running down the central corridor to the Weapons Armory when&lt;br /&gt;a Gothon jumps out, red scaly skin, dark grimy teeth, and evil clown costume&lt;br /&gt;flowing around his hate filled body. &amp;nbsp;He's blocking the door to the&lt;br /&gt;Armory and about to pull a weapon to blast you.&lt;br /&gt;&amp;gt; dodge!&lt;br /&gt;Like a world class boxer you dodge, weave, slip and slide right&lt;br /&gt;as the Gothon's blaster cranks a laser past your head.&lt;br /&gt;In the middle of your artful dodge your foot slips and you&lt;br /&gt;bang your head on the metal wall and pass out.&lt;br /&gt;You wake up shortly after only to die as the Gothon stomps on&lt;br /&gt;your head and eats you.&lt;br /&gt;&lt;br /&gt;--------&lt;br /&gt;Such a luser.&lt;br /&gt;&lt;br /&gt;$ ruby ex41.rb&lt;br /&gt;&lt;br /&gt;--------&lt;br /&gt;The Gothons of Planet Percal #25 have invaded your ship and destroyed&lt;br /&gt;your entire crew. &amp;nbsp;You are the last surviving member and your last&lt;br /&gt;mission is to get the neutron destruct bomb from the Weapons Armory,&lt;br /&gt;put it in the bridge, and blow the ship up after getting into an&lt;br /&gt;escape pod.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;You're running down the central corridor to the Weapons Armory when&lt;br /&gt;a Gothon jumps out, red scaly skin, dark grimy teeth, and evil clown costume&lt;br /&gt;flowing around his hate filled body. &amp;nbsp;He's blocking the door to the&lt;br /&gt;Armory and about to pull a weapon to blast you.&lt;br /&gt;&amp;gt; tell a joke&lt;br /&gt;Lucky for you they made you learn Gothon insults in the academy.&lt;br /&gt;You tell the one Gothon joke you know:&lt;br /&gt;Lbhe zbgure vf fb sng, jura fur fvgf nebhaq gur ubhfr, fur fvgf nebhaq gur ubhfr.&lt;br /&gt;The Gothon stops, tries not to laugh, then busts out laughing and can't move.&lt;br /&gt;While he's laughing you run up and shoot him square in the head&lt;br /&gt;putting him down, then jump through the Weapon Armory door.&lt;br /&gt;&lt;br /&gt;--------&lt;br /&gt;You do a dive roll into the Weapon Armory, crouch and scan the room&lt;br /&gt;for more Gothons that might be hiding. &amp;nbsp;It's dead quiet, too quiet.&lt;br /&gt;You stand up and run to the far side of the room and find the&lt;br /&gt;neutron bomb in its container. &amp;nbsp;There's a keypad lock on the box&lt;br /&gt;and you need the code to get the bomb out. &amp;nbsp;If you get the code&lt;br /&gt;wrong 10 times then the lock closes forever and you can't&lt;br /&gt;get the bomb. &amp;nbsp;The code is 3 digits.&lt;br /&gt;[keypad]&amp;gt; 123&lt;br /&gt;BZZZZEDDD!&lt;br /&gt;[keypad]&amp;gt; 234&lt;br /&gt;BZZZZEDDD!&lt;br /&gt;[keypad]&amp;gt; 345&lt;br /&gt;BZZZZEDDD!&lt;br /&gt;[keypad]&amp;gt; 456&lt;br /&gt;BZZZZEDDD!&lt;br /&gt;[keypad]&amp;gt; 567&lt;br /&gt;BZZZZEDDD!&lt;br /&gt;[keypad]&amp;gt; 678&lt;br /&gt;BZZZZEDDD!&lt;br /&gt;[keypad]&amp;gt; 789&lt;br /&gt;BZZZZEDDD!&lt;br /&gt;[keypad]&amp;gt; 384&lt;br /&gt;BZZZZEDDD!&lt;br /&gt;[keypad]&amp;gt; 764&lt;br /&gt;BZZZZEDDD!&lt;br /&gt;[keypad]&amp;gt; 354&lt;br /&gt;BZZZZEDDD!&lt;br /&gt;[keypad]&amp;gt; 263&lt;br /&gt;The lock buzzes one last time and then you hear a sickening&lt;br /&gt;melting sound as the mechanism is fused together.&lt;br /&gt;You decide to sit there, and finally the Gothons blow up the&lt;br /&gt;ship from their ship and you die.&lt;br /&gt;&lt;br /&gt;--------&lt;br /&gt;You died. &amp;nbsp;You kinda suck at this.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Extra Credit&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Explain how returning the next room works.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;[&lt;b&gt;&lt;span style="color: red;"&gt;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.&lt;/span&gt;&lt;/b&gt;]&lt;br /&gt;&lt;br /&gt;Add cheat codes to the game so you can get past the more difficult rooms.&lt;br /&gt;&lt;br /&gt;Instead of having each function print itself, learn about "here document" strings.&lt;br /&gt;&lt;br /&gt;Write the room description as here document strings, and change the runner to use them.&lt;br /&gt;&lt;br /&gt;[ &lt;b&gt;&lt;span style="color: red;"&gt;Here document strings make it easy to put text together, and it's &amp;nbsp;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 :)&lt;/span&gt;&lt;/b&gt; ].&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-lG2sk78APd4/TwSWIOy46NI/AAAAAAAABDc/9nVINWLlkLc/s1600/Screen+shot+2012-01-04+at+10.03.55+AM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="198" src="http://3.bp.blogspot.com/-lG2sk78APd4/TwSWIOy46NI/AAAAAAAABDc/9nVINWLlkLc/s320/Screen+shot+2012-01-04+at+10.03.55+AM.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-jy22Q-ODirE/TwSWIp7IDNI/AAAAAAAABDk/nyvKZ9X89qE/s1600/Screen+shot+2012-01-04+at+10.04.46+AM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://4.bp.blogspot.com/-jy22Q-ODirE/TwSWIp7IDNI/AAAAAAAABDk/nyvKZ9X89qE/s320/Screen+shot+2012-01-04+at+10.04.46+AM.png" width="213" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-7_YXB33u92U/TwSWJG08VhI/AAAAAAAABDs/MkMONA6BCIs/s1600/Screen+shot+2012-01-04+at+10.05.29+AM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://4.bp.blogspot.com/-7_YXB33u92U/TwSWJG08VhI/AAAAAAAABDs/MkMONA6BCIs/s320/Screen+shot+2012-01-04+at+10.05.29+AM.png" width="255" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-5xIbJwC_ctI/TwSWJu9rcqI/AAAAAAAABD0/zdhT8TJsWPg/s1600/Screen+shot+2012-01-04+at+10.06.01+AM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://2.bp.blogspot.com/-5xIbJwC_ctI/TwSWJu9rcqI/AAAAAAAABD0/zdhT8TJsWPg/s320/Screen+shot+2012-01-04+at+10.06.01+AM.png" width="278" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-_z9yh9iC9hM/TwSWKGDwbzI/AAAAAAAABD8/Fq9El-UDEmI/s1600/Screen+shot+2012-01-04+at+10.08.49+AM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://4.bp.blogspot.com/-_z9yh9iC9hM/TwSWKGDwbzI/AAAAAAAABD8/Fq9El-UDEmI/s320/Screen+shot+2012-01-04+at+10.08.49+AM.png" width="279" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-_W-GbBqT7cE/TwSWKgIdIlI/AAAAAAAABEE/w1t6Pj5aGBc/s1600/Screen+shot+2012-01-04+at+10.10.11+AM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="223" src="http://2.bp.blogspot.com/-_W-GbBqT7cE/TwSWKgIdIlI/AAAAAAAABEE/w1t6Pj5aGBc/s320/Screen+shot+2012-01-04+at+10.10.11+AM.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;b&gt;TESTHEAD's TAKEAWAYS&lt;/b&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;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 &amp;nbsp;daily groove where possible (it's amazing what you have to go back and review when you've been away for a few days!).&lt;/div&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6890958153006612459-7100631262395857795?l=www.mkltesthead.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.mkltesthead.com/feeds/7100631262395857795/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6890958153006612459&amp;postID=7100631262395857795' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6890958153006612459/posts/default/7100631262395857795'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6890958153006612459/posts/default/7100631262395857795'/><link rel='alternate' type='text/html' href='http://www.mkltesthead.com/2012/01/exercise-41-gothons-from-planet-percal.html' title='Exercise 41: Gothons From Planet Percal #25: Learn Ruby the Hard Way: Practicum'/><author><name>Michael Larsen</name><uri>https://profiles.google.com/104738247543282839437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-L_ARsHiklGg/AAAAAAAAAAI/AAAAAAAABPA/PwBZuynaDbc/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/-EsxvHUCUCW4/TwRgKCQd0rI/AAAAAAAABCo/RIxQkPogDso/s72-c/Screen+shot+2012-01-04+at+5.56.47+AM.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6890958153006612459.post-865830101990175540</id><published>2012-01-03T12:00:00.000-08:00</published><updated>2012-01-03T12:19:58.349-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='productivity'/><category scheme='http://www.blogger.com/atom/ns#' term='goals'/><category scheme='http://www.blogger.com/atom/ns#' term='people'/><category scheme='http://www.blogger.com/atom/ns#' term='motivation'/><category scheme='http://www.blogger.com/atom/ns#' term='time management'/><title type='text'>Situational Paralysis? Start Talking!</title><content type='html'>&lt;br /&gt;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 ;) ).&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;What do I do in these situations? I start talking. Out loud. Seriously!&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;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, &amp;nbsp;i.e. the computer hutch. With it gone, the closet is the last refuge for this stuff.&lt;br /&gt;&lt;br /&gt;At this stage, I start a very openly verbal dialog (and yes, this is &lt;i&gt;literally&lt;/i&gt; what I do, no hyperbole here):&lt;br /&gt;&lt;br /&gt;&lt;i&gt;"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."&lt;/i&gt;&lt;br /&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;br /&gt;&lt;i&gt;"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."&lt;/i&gt;&lt;br /&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;br /&gt;&lt;i&gt;"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."&lt;/i&gt;&lt;br /&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;br /&gt;&lt;i&gt;"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."&lt;/i&gt;&lt;br /&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;br /&gt;&lt;i&gt;"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."&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;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 &lt;i&gt;so much faster&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6890958153006612459-865830101990175540?l=www.mkltesthead.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.mkltesthead.com/feeds/865830101990175540/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6890958153006612459&amp;postID=865830101990175540' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6890958153006612459/posts/default/865830101990175540'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6890958153006612459/posts/default/865830101990175540'/><link rel='alternate' type='text/html' href='http://www.mkltesthead.com/2012/01/situational-paralysis-start-talking.html' title='Situational Paralysis? Start Talking!'/><author><name>Michael Larsen</name><uri>https://profiles.google.com/104738247543282839437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-L_ARsHiklGg/AAAAAAAAAAI/AAAAAAAABPA/PwBZuynaDbc/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6890958153006612459.post-5319415746352210661</id><published>2012-01-02T09:00:00.000-08:00</published><updated>2012-01-02T11:43:53.519-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='goals'/><category scheme='http://www.blogger.com/atom/ns#' term='learning'/><category scheme='http://www.blogger.com/atom/ns#' term='books'/><title type='text'>Finding New Knowledge in Current Places</title><content type='html'>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 &lt;b&gt;&lt;i&gt;years&lt;/i&gt;&lt;/b&gt; and have &lt;b&gt;&lt;i&gt;never opened&lt;/i&gt;&lt;/b&gt;.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;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 &lt;i style="font-weight: bold;"&gt;anything &lt;/i&gt;if you do not actually open them and read them.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;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, &lt;i&gt;because I know what's in it&lt;/i&gt;. 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 &lt;b&gt;&lt;i&gt;years&lt;/i&gt;&lt;/b&gt; 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"?&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;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 &lt;b&gt;&lt;i&gt;more&lt;/i&gt;&lt;/b&gt; value out of it.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;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:&lt;br /&gt;&lt;br /&gt;1. Do I have any use for this book &lt;b&gt;&lt;i&gt;today&lt;/i&gt;&lt;/b&gt;? If so, what can I apply here and now from this book?&lt;br /&gt;&lt;br /&gt;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)?&lt;br /&gt;&lt;br /&gt;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)?&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Note, this approach requires &lt;b&gt;&lt;i&gt;active review&lt;/i&gt;&lt;/b&gt; of each title. I have to physically read through each book, at least in a skimmed manner, &amp;nbsp;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.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;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 &lt;b&gt;&lt;i&gt;literally&lt;/i&gt;&lt;/b&gt; trip over it whenever I walk into my office :) ).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6890958153006612459-5319415746352210661?l=www.mkltesthead.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.mkltesthead.com/feeds/5319415746352210661/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6890958153006612459&amp;postID=5319415746352210661' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6890958153006612459/posts/default/5319415746352210661'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6890958153006612459/posts/default/5319415746352210661'/><link rel='alternate' type='text/html' href='http://www.mkltesthead.com/2012/01/finding-new-knowledge-in-current-places.html' title='Finding New Knowledge in Current Places'/><author><name>Michael Larsen</name><uri>https://profiles.google.com/104738247543282839437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-L_ARsHiklGg/AAAAAAAAAAI/AAAAAAAABPA/PwBZuynaDbc/s512-c/photo.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6890958153006612459.post-2031307385151146474</id><published>2011-12-30T05:00:00.000-08:00</published><updated>2011-12-30T05:14:21.054-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='education'/><category scheme='http://www.blogger.com/atom/ns#' term='teaching'/><category scheme='http://www.blogger.com/atom/ns#' term='learning'/><category scheme='http://www.blogger.com/atom/ns#' term='books'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='PRACTICUM'/><category scheme='http://www.blogger.com/atom/ns#' term='career development'/><title type='text'>Exercise 40: Dictionaries, Oh Lovely Dictionaries: Learn Ruby the Hard Way: Practicum</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://upload.wikimedia.org/wikipedia/commons/f/f1/Ruby_logo.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="200" src="http://upload.wikimedia.org/wikipedia/commons/f/f1/Ruby_logo.png" width="199" /&gt;&lt;/a&gt;&lt;/div&gt;All right! We're getting into something that I've seen a lot in our data outputs on the console when I am debugging our applications, and I've long wondered what I was looking at. This exercise takes that on. This one is all about hashes. What's a hash, you say? Well, read on :).&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Ruby calls them "hashes", other languages call them, "dictionaries". &amp;nbsp;Zed says he uses both names, but what they are called doesn't really matter. What does matter is what they do when compared to arrays.&lt;br /&gt;&lt;br /&gt;An array lets you do this:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-g7VEwkOV1Ts/Tv22_nNUVoI/AAAAAAAABBM/AOr5Bu0z7wo/s1600/Screen+shot+2011-12-29+at+11.26.59+AM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="242" src="http://4.bp.blogspot.com/-g7VEwkOV1Ts/Tv22_nNUVoI/AAAAAAAABBM/AOr5Bu0z7wo/s320/Screen+shot+2011-12-29+at+11.26.59+AM.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Arrays store their values in an ordered list, and you can reference and access those values by calling the index number from 0 to, well, whatever the last element in the array happens to be, and whatever that number is.&lt;br /&gt;&lt;br /&gt;A hash works similarly, but you don't have to use numbers to access the elements stored in a hash. You can use anything. Here's an example:&lt;br /&gt;&lt;br /&gt;[&lt;b&gt;&lt;span style="color: red;"&gt;For the record, the example on the LRtHW site has a back slash for the multiplication sign. This doesn't work on my environments; both Ruby 1.8.7 and 1.9.2 give me an error. Removing the back slash works as expected. See below. I also let Zed and Rob know about this, so this may well be fixed by the time this entry appears... &amp;nbsp;and has been :)&lt;/span&gt;&lt;/b&gt; ]&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-p_-riiUA-Lg/Tv23KrckwvI/AAAAAAAABBY/jsTjzaHhMD8/s1600/Screen+shot+2011-12-29+at+11.59.12+AM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="273" src="http://3.bp.blogspot.com/-p_-riiUA-Lg/Tv23KrckwvI/AAAAAAAABBY/jsTjzaHhMD8/s320/Screen+shot+2011-12-29+at+11.59.12+AM.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Instead of using numbers, we are using "symbols", which are effectively name tags, an they are easier to remember than trying to figure out where in an array something is.&lt;br /&gt;&lt;br /&gt;Here's another way to do it.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-Q-LTj0QZcwE/Tv23wBlztpI/AAAAAAAABBk/9sxAIlFt-cM/s1600/Screen+shot+2011-12-29+at+12.13.06+PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="208" src="http://4.bp.blogspot.com/-Q-LTj0QZcwE/Tv23wBlztpI/AAAAAAAABBk/9sxAIlFt-cM/s320/Screen+shot+2011-12-29+at+12.13.06+PM.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;So that's kinda cool, I can insert new items and give them a unique id and then if I print out the hash, I can see where it fits along with the number or id.&lt;br /&gt;&lt;br /&gt;Hashes also let you delete stuff, too:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-78ewTVtMvWg/Tv234xCKHFI/AAAAAAAABBw/bR6ncOYrZzI/s1600/Screen+shot+2011-12-29+at+12.22.15+PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="242" src="http://4.bp.blogspot.com/-78ewTVtMvWg/Tv234xCKHFI/AAAAAAAABBw/bR6ncOYrZzI/s320/Screen+shot+2011-12-29+at+12.22.15+PM.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;So here's the exercise for this go around, in case the previous wasn't enough to bring the point home :):&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-6IoTPOE1bnc/Tv23_GqfvZI/AAAAAAAABB8/ao1WKA9n3sI/s1600/Screen+shot+2011-12-29+at+3.14.58+PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://2.bp.blogspot.com/-6IoTPOE1bnc/Tv23_GqfvZI/AAAAAAAABB8/ao1WKA9n3sI/s320/Screen+shot+2011-12-29+at+3.14.58+PM.png" width="315" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;What You Should See&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-AefTaqr4pNU/Tv24Ie_HZWI/AAAAAAAABCI/fJN4B2qBOzw/s1600/Screen+shot+2011-12-29+at+3.15.53+PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="242" src="http://1.bp.blogspot.com/-AefTaqr4pNU/Tv24Ie_HZWI/AAAAAAAABCI/fJN4B2qBOzw/s320/Screen+shot+2011-12-29+at+3.15.53+PM.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Extra Credit&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Go find the Ruby documentation for hashes and try to do even more things to them.&lt;br /&gt;&lt;br /&gt;[&lt;b&gt;&lt;span style="color: red;"&gt;There's a lot of stuff here! hash has a bunch of method options, most of which I'm just barely able to understand how I would use. For grins I played with merge, which allows the user to take two separate hashes and merge them together. Interestingly, if the second hash has a pair with a key that matches the first one, it's the second hash's value of the pair that will be used. See below.&lt;/span&gt;&lt;/b&gt;]&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-ppxzgzibM-M/Tv24XGI8kyI/AAAAAAAABCU/9FEILr8dELM/s1600/Screen+shot+2011-12-30+at+4.38.46+AM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://2.bp.blogspot.com/-ppxzgzibM-M/Tv24XGI8kyI/AAAAAAAABCU/9FEILr8dELM/s320/Screen+shot+2011-12-30+at+4.38.46+AM.png" width="315" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-_61TNTAG-34/Tv24XoEpWFI/AAAAAAAABCc/yDkiJ4cV2qo/s1600/Screen+shot+2011-12-30+at+4.39.34+AM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="242" src="http://2.bp.blogspot.com/-_61TNTAG-34/Tv24XoEpWFI/AAAAAAAABCc/yDkiJ4cV2qo/s320/Screen+shot+2011-12-30+at+4.39.34+AM.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Find out what you can't do with hashes. A big one is that they do not have order, so try playing with that.&lt;br /&gt;&lt;br /&gt;[ &lt;b&gt;&lt;span style="color: red;"&gt;This is correct. They go in as you create them, and they get listed as they are ordered. the one difference is that, if you merge two hashes, then the location of the original hash key and value is replaced with the new value, but its ordering in the hash is preserved.&lt;/span&gt;&lt;/b&gt;]&lt;br /&gt;&lt;br /&gt;&lt;b&gt;TESTHEAD's TAKEAWAYS:&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;This is cool, it's an item I can definitely see using for an application like a phone book or contact lookup. I'm sure it can be used for a lot more than that, and I look forward to more options I can use going forward. What I like about it is the fact that the key can be an actual word, which is a lot more logical way to consider doing a lookup compared to remembering or finding a number in an array.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6890958153006612459-2031307385151146474?l=www.mkltesthead.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.mkltesthead.com/feeds/2031307385151146474/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6890958153006612459&amp;postID=2031307385151146474' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6890958153006612459/posts/default/2031307385151146474'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6890958153006612459/posts/default/2031307385151146474'/><link rel='alternate' type='text/html' href='http://www.mkltesthead.com/2011/12/exercise-40-dictionaries-oh-lovely.html' title='Exercise 40: Dictionaries, Oh Lovely Dictionaries: Learn Ruby the Hard Way: Practicum'/><author><name>Michael Larsen</name><uri>https://profiles.google.com/104738247543282839437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-L_ARsHiklGg/AAAAAAAAAAI/AAAAAAAABPA/PwBZuynaDbc/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/-g7VEwkOV1Ts/Tv22_nNUVoI/AAAAAAAABBM/AOr5Bu0z7wo/s72-c/Screen+shot+2011-12-29+at+11.26.59+AM.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6890958153006612459.post-8037177051261697472</id><published>2011-12-29T19:54:00.000-08:00</published><updated>2011-12-29T20:10:37.836-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='productivity'/><category scheme='http://www.blogger.com/atom/ns#' term='goals'/><category scheme='http://www.blogger.com/atom/ns#' term='philosophy'/><category scheme='http://www.blogger.com/atom/ns#' term='books'/><category scheme='http://www.blogger.com/atom/ns#' term='motivation'/><category scheme='http://www.blogger.com/atom/ns#' term='life experience'/><category scheme='http://www.blogger.com/atom/ns#' term='time management'/><title type='text'>Opening Up New Possibilities</title><content type='html'>The Salvation Army Truck Came, and They Took the Beautiful Monster Away...&lt;br /&gt;&lt;br /&gt;sounds like the opening line of The Dream Academy's "Life in a Northern Town".&lt;br /&gt;&lt;br /&gt;In a way, I feel a little misty today. While just a couple of days ago, I said I was fine with my decision to let the giant walnut computer hutch go, we are often reminded of setting things up, having everything that used to be there, and now it's definitely gone. A friend of mine pointed out to me that it's like having a friend move away. We may not have done much together lately, we may not have talked on the phone all that often recently, but we always knew we were there, until the day that they call you and tell you they've accepted a job back east. You're happy for them, and they go on to do bigger and better, or at least different, things, but suddenly you realize... they are gone. The Beautiful Monster feels a little like that.&lt;br /&gt;&lt;br /&gt;The funny thing when you make a change and suddenly have a lot of fresh options is to think "wow, what am I going to do with all of this space?!" For grins today, I grabbed a folding table and sat down with my two laptops, and started thinking of how I would set everything up. What happened? I realized that I was putting everything back into place, just as though the Beautiful Monster was still there. Hang on... if I'm just going to do the same things I've always done, what was the point in giving the computer hutch away? &amp;nbsp;This is a chance to do something different, to really change up how I do things. Again, the question I asked originally came back into my head... do I really need to have a dedicated home office? With the work that I do now, and the way that I do it, is there really a benefit to having the room permanently set up this way? Are there other things I want to do with this room? I realized that there were lots of things I wanted to be able to do, and if I set everything up exactly the same way, then I couldn't do them. This got me thinking as to the need to keep so many of the things that I've always taken for granted. Why are they there? What purpose do they serve? Well, I have to have a bookshelf... or do I? It's fun and dangerous when you start down these roads :).&lt;br /&gt;&lt;br /&gt;What I found as I thumbed through many of my cherished technology books is that most of them are grossly out of date. I have newer versions of them in PDF format or I have access to sites that cover the same material, often better. I had a book about Tcl/Tk. Cool language, neat framework, I haven't used it in over 12 years, though, and the entire reference is available online should I need it. To what benefit is me keeping an 18 year old book around going to accomplish? Other titles fell into that same category, and I realized that many of the books I had on my shelves were long outdated. Thus, new goal, focus on evergreen books as keepers and references, and liberate titles that will serve no purpose to me or my family any longer.&lt;br /&gt;&lt;br /&gt;This is an interesting exercise, because it really shows what things you value and want to keep. I ended up with a shelf of CDs, a shelf of DVD's related to Korean Drama, some random movies, and Native American handicraft and tradition. Another shelf is "evergreen how-to guides". Think things like &amp;nbsp;sewing, money management, home repair, camping, guitar and playing music, gardening, fitness, Japanese language study and stuff related to Native American handicraft that would be hard to find anyplace else, Another shelf is dedicated to fiction and literature that I enjoy from odd places. Everything from Homer, Cicero, Jane Austen, Orson Scott Card, Stephen King and other titles that I go through semi-regularly. &amp;nbsp;This also includes my full run of of the manga of Neon Genesis Evangelion and my much beloved volumes of the Elfquest saga. Another shelf has what I call my "business and critical knowledge" shelf, which contains a number of books from various disciplines, including a few timeless titles related to writing. Examples include my much used copy of the Little Brown Handbook, Stephen King's "On Writing", Twyla Tharp's "The Creative Habit", Steven Covey's "The 7 Habits of Highly Effective People" and "Principle Centered Leadership", James Bach's "Secrets of a Buccaneer Scholar",&amp;nbsp;and a number of books given to me to review and I have decided were worth keeping as permanent references related to testing and data security. I was surprised that this wasn't a much larger list, until I realized that most of my current reading on these topics is in electronic format.&lt;br /&gt;&lt;br /&gt;I have two sentimental holdovers that I was not willing to do away with. The first is a near complete collection of mental_floss magazine. I have all but three issues dating back to first publication to today, and I keep all of them. The second is a shelf full of classic black bound books from The Nobel Library. These books were a treasure to my grandmother, and she would often talk about stories she read in them and some of the interesting authors she discovered. The books covered the authors who won the &amp;nbsp;Nobel Prize for Literature from its inception on up to 1970 when the volumes were printed, and the pieces of literature that actually won the prize in that given year. When she passed away in 2001, that was one of the few things of hers I wanted to keep. It helped keep a connection of a love of reading and being willing to look for new knowledge and interesting stories wherever they might be found, and to appreciate the different voices and viewpoints in the world.&lt;br /&gt;&lt;br /&gt;Several books that didn't make the cut are still in excellent condition, so I'm going to be bringing them to my local library. Some have been discarded as they are very much out of date or no longer relevant. What I kept says a lot about me personally... it also says I won't be getting rid of or downsizing my current bookshelf after all (though I've made some space for some new acquisitions :) ).&lt;br /&gt;&lt;br /&gt;As I pointed out in yesterday's entry, I don't believe in New Year's Resolutions, but I do take stock in what I've done during the year and what I've held on to, and what I feel should be gotten rid of or left to find a new home. What comes and goes isn't as interesting as what stays year after year. The things that endure are often not the things we think will endure, and the stuff that we put a lot of attention into at one point in time often becomes out dated and useless to us later on.&lt;br /&gt;&lt;br /&gt;Oh, and about that table... I decided to fold it up and stick it under my futon. An additional short term goal for the next few weeks is to only break it out when I physically need a desk to sit at for a needed period. and then to fold it up and put it back away. I'm going to dare to be bold for a while, and allow myself to picture living with and having this open space, and not be in such a hurry to fill it with old habits. New possibilities, after all, can only make themselves manifest if they are given room to be seen :).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6890958153006612459-8037177051261697472?l=www.mkltesthead.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.mkltesthead.com/feeds/8037177051261697472/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6890958153006612459&amp;postID=8037177051261697472' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6890958153006612459/posts/default/8037177051261697472'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6890958153006612459/posts/default/8037177051261697472'/><link rel='alternate' type='text/html' href='http://www.mkltesthead.com/2011/12/opening-up-new-possibilities.html' title='Opening Up New Possibilities'/><author><name>Michael Larsen</name><uri>https://profiles.google.com/104738247543282839437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-L_ARsHiklGg/AAAAAAAAAAI/AAAAAAAABPA/PwBZuynaDbc/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6890958153006612459.post-8348879531169701256</id><published>2011-12-28T17:00:00.000-08:00</published><updated>2011-12-29T20:06:24.993-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='productivity'/><category scheme='http://www.blogger.com/atom/ns#' term='goals'/><category scheme='http://www.blogger.com/atom/ns#' term='training'/><category scheme='http://www.blogger.com/atom/ns#' term='skills development'/><category scheme='http://www.blogger.com/atom/ns#' term='life experience'/><category scheme='http://www.blogger.com/atom/ns#' term='time management'/><category scheme='http://www.blogger.com/atom/ns#' term='writing'/><title type='text'>Chain... Keeps Goals Together</title><content type='html'>&lt;br /&gt;We're homing in on the end of the year, and many are abuzz with the "New Years Resolution" virus. For those curious, I &lt;b&gt;&lt;i&gt;never&lt;/i&gt;&lt;/b&gt; make New Year's Resolutions. Well, OK, I used to make them when I was younger, but I gave up when I realized that I was more times than not just setting myself up for failure. I realized something several years ago. Resolutions are weak willed things, and they are easy to break. Specific goals, with detailed and measurable progress points, are &lt;b&gt;&lt;i&gt;much&lt;/i&gt;&lt;/b&gt; more likely to lead to success.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Unlike resolutions, I believe wholeheartedly in setting regular goals, and I believe in setting small ones. Things I can work on for a given day, week, month, etc. Big, life-changing goals are good, and&amp;nbsp;occasionally, there is a specific incentive to take on one of those big massive goals, but most of the time, the human constitution just can't wrap its head around a massive life-altering change. At least not in big extended chunks. Let's take an example of losing weight. It's a popular New Year's Resolution topic.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;"I'm going to lose 50 pounds!"&lt;/li&gt;&lt;li&gt;"I'm going to work out &lt;b&gt;&lt;i&gt;every&lt;/i&gt;&lt;/b&gt; day!"&lt;/li&gt;&lt;li&gt;"I'm going to give up &lt;b&gt;&lt;i&gt;all processed foods&lt;/i&gt;&lt;/b&gt;!"&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;These are classic weight related resolutions, and more times than not, they are scrapped in a rapid order, often within two weeks. Why? Because they give an impression of being specific, but they aren't. They are very nebulous, with the exception of the "losing 50 pounds". Could be a great goal, but how will you go about doing it? How long will you allow yourself? and what will you do once you get there? The truth is, most long term goals are notoriously unfinished, because we don't really give ourselves realistic parameters.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I'm much more a fan of making very specific small and short term goals, and along with the goals, charting my progress with "chains". I love chains! It's an idea I got from an old Lifehacker piece called "&lt;a href="http://lifehacker.com/281626/jerry-seinfelds-productivity-secret"&gt;Jerry Seinfeld's Productivity Secret&lt;/a&gt;". In a &amp;nbsp;nutshell, the idea is to take a goal, and when you do something related to that goal, mark it on a wall calendar that displays a full year. Each day you do something towards your goal, write down a mark with a red pen, and after doing it multiple days, make a chain. From there, &lt;i&gt;don't break the chain&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;What's great about this advice is that is emphasizes consistency and regular practice of whatever it is you are doing. Jerry Seinfeld used this to meet a writing goal. The same could be used for reading, for exercise, for&amp;nbsp;cessation&amp;nbsp;of a bad habit, or practicing a musical instrument. Whatever the goal, start a &amp;nbsp;chain and make small links to keep building the chain.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Having said all this, you may be wondering what some of my "chains" are. Glad you asked. Some of them I have kept in a focused manner and have some long ones. Some others are collections of short chains interrupted here and there. The col thing is that, if you can create a lot of little chains, even if they are separated by a day here and there, you will still have a hefty chunk of chains to look back on, and likely a lot of accomplished goals to go with them. &lt;b&gt;Learn Ruby the Hard Way&lt;/b&gt; is a chain. Any &lt;b&gt;BOOK CLUB&lt;/b&gt; synopsis I do is a chain. My 10 a day SET practice is a chain (I use it as a drill to see how quickly I can&amp;nbsp;recognize&amp;nbsp;patterns and if I am getting faster at seeing them). So what are my "goals" that I want to focus on in 2012? Here's a basic list.&lt;br /&gt;&lt;br /&gt;* Complete Learn Ruby the Hard Way synopsis and then move on to other Hard Way projects.&lt;br /&gt;* Commit to a once-per-month, 1st Saturday unless impossible to attend Weekend Testing Americas Schedule.&lt;br /&gt;* Get back into the swing of doing a book review each week.&lt;br /&gt;* Work through my stack of Ruby and Rails books, and create more Practicum entries&lt;br /&gt;* Curate and mark-up TESTHEAD, so that topics that are related link posts.&lt;br /&gt;* Go through and do editorial on TESTHEAD, correcting spelling mistakes and grammatical faux pas' (I already know there's an embarrassing amount of them).&lt;br /&gt;* Focus more on topics specific to advances in coding and automation.&lt;br /&gt;* Declutter and dejunk my home and work area.&lt;br /&gt;* Focus on opportunities to develop presentation of testing experience and ideas; create a back log of talk and seminar material.&lt;br /&gt;&lt;br /&gt;That's plenty to keep me busy this year, and there's enough variety in there to keep me busy for, well, many years going forward.&amp;nbsp;Tackling&amp;nbsp;them all simultaneously and with 100% focus would be impractical and likely to fail. But doing one or two at a time, and chaining the small bits I can do each day, as well as staggering the ones I do at a given time, will help me approach many of these goals. A small step each day on the ones I want to see move forward will help me keep moving. If I get bogged&amp;nbsp;down&amp;nbsp;on one, I have many more to jump off to. Yes, SMART goals are good, and yes, being realistic in expectations is also good. Above all of&amp;nbsp;these, though, is the commitment to a little bit each day where you can, and when and where possible, &lt;b&gt;&lt;i&gt;do not break the chain&lt;/i&gt;&lt;/b&gt; :).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6890958153006612459-8348879531169701256?l=www.mkltesthead.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.mkltesthead.com/feeds/8348879531169701256/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6890958153006612459&amp;postID=8348879531169701256' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6890958153006612459/posts/default/8348879531169701256'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6890958153006612459/posts/default/8348879531169701256'/><link rel='alternate' type='text/html' href='http://www.mkltesthead.com/2011/12/chain-keeps-goals-together.html' title='Chain... Keeps Goals Together'/><author><name>Michael Larsen</name><uri>https://profiles.google.com/104738247543282839437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-L_ARsHiklGg/AAAAAAAAAAI/AAAAAAAABPA/PwBZuynaDbc/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6890958153006612459.post-3939263819263787548</id><published>2011-12-28T06:16:00.000-08:00</published><updated>2011-12-28T06:16:34.736-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='education'/><category scheme='http://www.blogger.com/atom/ns#' term='teaching'/><category scheme='http://www.blogger.com/atom/ns#' term='learning'/><category scheme='http://www.blogger.com/atom/ns#' term='books'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='PRACTICUM'/><category scheme='http://www.blogger.com/atom/ns#' term='career development'/><title type='text'>Exercise 39: Doing Things To Arrays: Learn Ruby the Hard Way: Practicum</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://upload.wikimedia.org/wikipedia/commons/f/f1/Ruby_logo.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="200" src="http://upload.wikimedia.org/wikipedia/commons/f/f1/Ruby_logo.png" width="199" /&gt;&lt;/a&gt;&lt;/div&gt;This time it's back to the future, or more specifically, back to arrays and considering some of the things that we can do with them now that we have tools like loops to help us work with them.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;One of the things that arrays allow us to do is to "push" items onto them and "pop" them off. This hearkens back to C programming for me and using UNIX to "push and pop" items off of a stack. I sort of got what that was all about, but it's been awhile, so it's good to get the chance to see how Ruby handles this, and give me a chance to re-explore this approach (and maybe learn it for real this time :) ).&lt;br /&gt;&lt;br /&gt;Zed explains that the approach to pushing an item onto an array covers a number of steps.&lt;br /&gt;&lt;br /&gt;Let's use this example: &lt;b&gt;mystuff.push('hello')&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;1. Ruby looks up the &lt;b&gt;mystuff&lt;/b&gt; variable. From there it determines what kind of variable mystuff is (a function call? A global variable?), In this case, Ruby finds it and sees that it is indeed an array.&lt;br /&gt;&lt;br /&gt;2. Next, it sees the period ('&lt;b&gt;.&lt;/b&gt;'). This keys the Ruby interpreter &amp;nbsp;to start looking at possible functions (methods) associated with this variable (in this case, an array).&lt;br /&gt;&lt;br /&gt;3. When it sees "&lt;b&gt;push&lt;/b&gt;" in the variable name. Ruby checks to see if that is a viable and legitimate function (which it is), and prepares to use it.&lt;br /&gt;&lt;br /&gt;4. The '&lt;b&gt;( )&lt;/b&gt;' (parentheses) let the Ruby interpreter know that what follows is a function call of some kind, and that the value inside of the parentheses is any number of arguments, depending on the function being used (in this case, the string '&lt;b&gt;hello&lt;/b&gt;').&lt;br /&gt;&lt;br /&gt;5. Finally, when it reaches the end of the variable value, with all of its methods and function calls, it then executes that step in the code.&lt;br /&gt;&lt;br /&gt;So yeah, that's a &lt;b&gt;&lt;i&gt;lot&lt;/i&gt;&lt;/b&gt; of stuff to consider, and that's all with just that simple statement.&lt;br /&gt;&lt;br /&gt;All right, let's check out the code for this exercise and see if we understand what's happening.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-bbheTrWznEk/Tvsj3D2LeHI/AAAAAAAABAw/p6UjWROHzCo/s1600/Screen+shot+2011-12-28+at+5.44.00+AM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="243" src="http://4.bp.blogspot.com/-bbheTrWznEk/Tvsj3D2LeHI/AAAAAAAABAw/p6UjWROHzCo/s320/Screen+shot+2011-12-28+at+5.44.00+AM.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-lo1sI3Sk5VQ/Tvsj3vErLeI/AAAAAAAABA4/xdPXVyXJfmo/s1600/Screen+shot+2011-12-28+at+5.44.18+AM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="283" src="http://2.bp.blogspot.com/-lo1sI3Sk5VQ/Tvsj3vErLeI/AAAAAAAABA4/xdPXVyXJfmo/s320/Screen+shot+2011-12-28+at+5.44.18+AM.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&amp;nbsp;And here is what we see:&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-LfyXdP1ch8U/Tvsj38G22YI/AAAAAAAABBA/3BpU3n5giZk/s1600/Screen+shot+2011-12-28+at+5.44.40+AM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="243" src="http://4.bp.blogspot.com/-LfyXdP1ch8U/Tvsj38G22YI/AAAAAAAABBA/3BpU3n5giZk/s320/Screen+shot+2011-12-28+at+5.44.40+AM.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;b&gt;Extra Credit&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Go read about "Object Oriented Programming" online. Confused? Yeah I was too. Do not worry. You will learn enough to be dangerous, and you can slowly learn more later. Read up on what a "class" is in Ruby. Do not read about how other languages use the word "class". That will only mess you up.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;[&lt;b&gt;&lt;span style="color: red;"&gt;Yep, this is something I've had a touch and go understanding of for years, much more touch than go. Generically, I get it. There are objects, and there are ways we can interact with those objects. We can use and reuse objects, we can create whole libraries of simple objects that we can call on as we need them. that much I get. In the Ruby world, a class is a top level object that can have its own methods defined. If we want to make something new in Ruby, we define it as a class, and then we create methods to interact with that class. as long as we name it something that doesn't conflict with a dedicated Ruby keyword, we're clear. Classes are also able to have their own scope and their own variable space, like any function. Classes can also create functions and nest those functions. Functions can also be sub-categorized, and those can be subcategorized even more. When we see something like Class.method.sub-method.sub-sub-method('argument'), each period shows that we are calling a function that resides within that given function.&lt;/span&gt;&lt;/b&gt;]&lt;br /&gt;&lt;br /&gt;What's the relationship between something.methods and the "class" of something?&lt;br /&gt;If you do not have any idea what I'm talking about do not worry. Programmers like to feel smart so they invented Object Oriented Programming, named it OOP, and then used it way too much. If you think that's hard, you should try to use "functional programming".&lt;br /&gt;&lt;br /&gt;[&lt;b&gt;&lt;span style="color: red;"&gt;I think I explained that above :). &lt;/span&gt;&lt;/b&gt;]&lt;br /&gt;&lt;br /&gt;&lt;b&gt;TESTHEAD's TAKEAWAYS:&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;The ability to loop and iterate with arrays, and to have tools that allow us to ad and remove items from an array is very powerful when it comes to processing text. This is how UNIX systems do things like grep and sort and awk, etc. It's cool to see it in this manner, and with a language that feels less bulky, so that we can get a handle on what is actually happening. the ability to manipulate strings and arrays using functions as part of a class is also pretty cool. I expect I'll be working quite a bit more with classes over the ensuing few days.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6890958153006612459-3939263819263787548?l=www.mkltesthead.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.mkltesthead.com/feeds/3939263819263787548/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6890958153006612459&amp;postID=3939263819263787548' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6890958153006612459/posts/default/3939263819263787548'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6890958153006612459/posts/default/3939263819263787548'/><link rel='alternate' type='text/html' href='http://www.mkltesthead.com/2011/12/exercise-39-doing-things-to-arrays.html' title='Exercise 39: Doing Things To Arrays: Learn Ruby the Hard Way: Practicum'/><author><name>Michael Larsen</name><uri>https://profiles.google.com/104738247543282839437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-L_ARsHiklGg/AAAAAAAAAAI/AAAAAAAABPA/PwBZuynaDbc/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/-bbheTrWznEk/Tvsj3D2LeHI/AAAAAAAABAw/p6UjWROHzCo/s72-c/Screen+shot+2011-12-28+at+5.44.00+AM.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6890958153006612459.post-3088766384027287058</id><published>2011-12-27T20:00:00.000-08:00</published><updated>2011-12-28T04:50:04.698-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='performance'/><category scheme='http://www.blogger.com/atom/ns#' term='productivity'/><category scheme='http://www.blogger.com/atom/ns#' term='costs'/><category scheme='http://www.blogger.com/atom/ns#' term='motivation'/><category scheme='http://www.blogger.com/atom/ns#' term='life experience'/><category scheme='http://www.blogger.com/atom/ns#' term='time management'/><title type='text'>"Break Throughs" Sometimes Require "Breaks With"</title><content type='html'>&lt;br /&gt;For the past decade plus, I have had a "beautiful monster" in what is effectively my home office. I say effectively because, in all reality, the Home office is really a place for a book case, a fold down futon/couch, my closet with my clothes and miscellaneous items for said futon (makes for a semi-nice guest bedroom in a pinch), but the dominating feature (and I used that word very literally), is the Computer Hutch/Armoire. It's a beautiful piece of walnut furniture, with six doors, an internal light, adjustable media shelf, places for CPUs, printer, scanner, external drives, filing drawer, and a retractable desk that can be folded in and closed up behind six panels. It's beautiful, and it's huge, as in 24 inches by 48 inches by 72 inches huge, and that's without the desk pulled out.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;This was the first purchase I made for my "home office" in 1999. When we bought our house, I was overjoyed to finally have a room that was going to be my office. An actual room, not setting up in a side closet as in our previous place, not shunted out in the garage when I outgrew the closet and the heat from a SPARC station and a 21" CRT monitor became unbearable. This was going to be a real honest to goodness dedicated office, a veritable "man cave" of my very own, and to house the tons of bulky computer equipment I had at the time, including the said SPARC pizza box, 21" CRT monitor, and a secondary PC that was connected to the same monitor and keyboard, the armoire was ideal, along with a big executive chair and everything in its place.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Fast forward 12 years. The SPARC station and original PC CPU are long gone. They have been replaced a couple times. Today, my digital life and work reside on a Macbook Pro and a Toshiba Sattelite PC. The need for a dedicated printer is now in the family room where the entire family can use it. Network connections come via wi-fi. External storage is now more often than not in the cloud, with some DVD backup media for good measure. Future platforms are possibly looking to be tablets (whether iPad or some Android flavor) or smartphone (whether iPhone or Android). The simple fact is, the Armoire, while it looks nice, it's a relic now. It doesn't fit the way that I work any longer, but I've tried to force myself to &amp;nbsp;keep using it for years now. I paid a lot of money for it. I wanted to get my money's worth out of it.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The funny thing is, we often invest a lot of ourselves, our energy, and our emotions in items that are just plain and simple past their effective use life. Don't get me wrong, this desk will be a gem to someone with the room for it and who would like to have it serve a similar need (it has enough room for a big flat screen TV inside, plus the ability to be a fully functioning office desk if necessary. It's just that it no longer fits &lt;i&gt;&lt;b&gt;my&lt;/b&gt;&lt;/i&gt; life and needs any longer, and justification to keep it around just burns up cycles, not to mention my having to do clutter control of a major scale just to keep the area around it tidy.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Today, I made a decision. I called my local Salvation Army store and said I had a great piece of furniture looking for a new home. They'll be coming by later this week to pick it up and bring it to their showroom. In return, I will have 48 cubic feet of space to do something with. I may set up a card table or something to have a place to sit and type if I need to, or I may just leave the space empty and actually have the ability to walk into the room and sit down and breathe and relax. I may re-purpose the room entirely, who knows? The fact is, I can do my work anywhere now. I don't really need a dedicated office any longer, and I'm willing to bet that developments in the coming years will make the need for a dedicated space even less relevant (though I will probably need it as a quiet space to do show production for the&amp;nbsp;foreseeable&amp;nbsp;future).&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;At the end of this year, think about the tools, practices, policies or equipment&amp;nbsp;that&amp;nbsp;you have "invested in" and ask yourself, are these items, practices or policies genuinely useful to me, or do I keep them on life support just&amp;nbsp;because&amp;nbsp;I'm sort of attached to them? If you can say that you really do use them and they really bring value to what you do, then you'd be perfectly fine to leave things be and not do anything. However, if you find, like me, that you are spending a lot of energy producing "churn" for no other reason than to churn, give that process or item a lot of thought and see if you can live without it. If so, find a place to put it and get it out of your reality. If in truth, you can do just fine without it, let it go. Don't spend another minute&amp;nbsp;letting&amp;nbsp;it clutter up your time or your energies.&lt;br /&gt;&lt;br /&gt;Have you wanted to learn a new&amp;nbsp;language&amp;nbsp;or use a new approach to testing, but you are hamstrung by the practices you &lt;b&gt;&lt;i&gt;have&lt;/i&gt;&lt;/b&gt; to keep up and maintain? If there isn't a real compelling reason to keep them going, dare to set them aside for awhile. Examine their real utility. You may be surprised that all of the attention you've been paying to "essential reports, forms, charts, and processes" might actually be not that essential after all. Dare to do something different, and see how it goes. Consolidate processes where it makes sense, and dare to stop doing some things altogether if you are really just treading water doing them. The end of the year is a classic time to de-junk, de-stress and de-clutter. Take the time to do so, and you may find that your house, your desk, your work group, and quite possibly your sanity function way better by removing the thing that you think you have to keep around, but really don't. Give it a try, let me know how it works for you :).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6890958153006612459-3088766384027287058?l=www.mkltesthead.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.mkltesthead.com/feeds/3088766384027287058/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6890958153006612459&amp;postID=3088766384027287058' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6890958153006612459/posts/default/3088766384027287058'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6890958153006612459/posts/default/3088766384027287058'/><link rel='alternate' type='text/html' href='http://www.mkltesthead.com/2011/12/break-throughs-sometimes-require-breaks.html' title='&quot;Break Throughs&quot; Sometimes Require &quot;Breaks With&quot;'/><author><name>Michael Larsen</name><uri>https://profiles.google.com/104738247543282839437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-L_ARsHiklGg/AAAAAAAAAAI/AAAAAAAABPA/PwBZuynaDbc/s512-c/photo.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6890958153006612459.post-1648721291480370197</id><published>2011-12-27T05:16:00.000-08:00</published><updated>2011-12-27T10:25:02.101-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='education'/><category scheme='http://www.blogger.com/atom/ns#' term='teaching'/><category scheme='http://www.blogger.com/atom/ns#' term='learning'/><category scheme='http://www.blogger.com/atom/ns#' term='books'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='PRACTICUM'/><category scheme='http://www.blogger.com/atom/ns#' term='career development'/><title type='text'>Exercise 38: Reading Code: Learn Ruby the Hard Way: Practicum</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://upload.wikimedia.org/wikipedia/commons/f/f1/Ruby_logo.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="200" src="http://upload.wikimedia.org/wikipedia/commons/f/f1/Ruby_logo.png" width="199" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;This exercise requires us to go out and find someone else's code and see if we can make sense of what we see. What I found was that, in most cases, there is little in the way of completely self contained projects. Most of the projects that are out there rely on other gems or other elements that have already been developed somewhere else. While this is an effective and contained way to pull in functionality, it can be frustrating to try and find where the actual files are.&lt;br /&gt;&lt;br /&gt;I decided to take a look at a project called "&lt;a href="https://github.com/thoughtbot/shoulda"&gt;shoulda&lt;/a&gt;" which is a testing framework along the lines of Cucumber. What I found while going through "shoulda" is that shoulda is a meta project, and that the actual work is being done in two other projects, shoulda-context and shoulda-matchers. &lt;br /&gt;&lt;br /&gt;Right now, my goal is to check and see what I can understand from what I am reading, and what I cannot. As I was looking through a number of the files, I found some things that were easy to understand and made sense of the first run, and I found some other things that, while I didn't quite get how they were being implemented, I understood their context and what they were doing. Case in point, there is a "usage" function. It prints out what is not meeting the requirements and then shows a boilerplate text of how the application should be used.&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-MQdl5XLZPdA/TvnEzbINvII/AAAAAAAABAk/mZn69zGbc7c/s1600/Screen+shot+2011-12-27+at+5.14.17+AM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="218" src="http://2.bp.blogspot.com/-MQdl5XLZPdA/TvnEzbINvII/AAAAAAAABAk/mZn69zGbc7c/s320/Screen+shot+2011-12-27+at+5.14.17+AM.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;While a lot of the specific implementation details are still fuzzy, I've found that by going through the files themselves and just stepping through the modules and functions as they are defined, I can understand a lot of what the application is doing. Some of the stuff is still over my head (mainly because there's a few areas I've yet to focus on) but much of the details are not so foreign now.&lt;br /&gt;&lt;br /&gt;As was made clear in the last exercise, just going through and defining the majority of the keywords, operators and flow control options made a big difference. It has helped me to see that many of the terms that are used in code that I'm unsure of are actually defined someplace else, and usually are not too hard to find once you track down and follow the require statements in key files.&lt;br /&gt;&lt;br /&gt;The areas that I am actually still finding myself having more trouble with are the specific methods that are allowed with a given object. the good news is that, in most cases I've seen so far, these methods are generally well explained if their root objects are easy to get to and understand.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-hfJSVGQx1qA/TvnEPGGJjhI/AAAAAAAABAY/DJIwIxZ7594/s1600/Screen+shot+2011-12-27+at+5.05.47+AM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="212" src="http://4.bp.blogspot.com/-hfJSVGQx1qA/TvnEPGGJjhI/AAAAAAAABAY/DJIwIxZ7594/s320/Screen+shot+2011-12-27+at+5.05.47+AM.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;TESTHEAD's TAKEAWAYS:&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Each time I think "yeah, I've got this down", I'm finding that there's still a lot more to learn when I read someone else's git repository (or check out our own projects that we run in our test environment). My own "simple" scripts that I keep track of on my automation environment use a lot of different gems and projects, and I find that many of the statements used in Cucumber, for example, some are specific to RSpec, some use Capybara nomenclature, and some use things that point to technologies and projects I have little understanding of.&lt;br /&gt;&lt;br /&gt;On one end, it's helpful in that a lot of the details have already been put together for me, and I just use the steps that make sense and I don't have to do a lot of tweaking. On the other hand, this raises new frustrations, in that if you need to make a change or edit something to work in a different way, you may strike it lucky making a change, but you are not 100% sure that you understand where that change has impact.&lt;br /&gt;&lt;br /&gt;For me, certainly, I've found that a change that worked in one instance didn't work so well in another, and I was hard pressed to understand why. This is where being able to track all of the dependencies in a project, and what code and "flavors" of interaction they produce can help a lot.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6890958153006612459-1648721291480370197?l=www.mkltesthead.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.mkltesthead.com/feeds/1648721291480370197/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6890958153006612459&amp;postID=1648721291480370197' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6890958153006612459/posts/default/1648721291480370197'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6890958153006612459/posts/default/1648721291480370197'/><link rel='alternate' type='text/html' href='http://www.mkltesthead.com/2011/12/exercise-38-reading-code-learn-ruby.html' title='Exercise 38: Reading Code: Learn Ruby the Hard Way: Practicum'/><author><name>Michael Larsen</name><uri>https://profiles.google.com/104738247543282839437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-L_ARsHiklGg/AAAAAAAAAAI/AAAAAAAABPA/PwBZuynaDbc/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/-MQdl5XLZPdA/TvnEzbINvII/AAAAAAAABAk/mZn69zGbc7c/s72-c/Screen+shot+2011-12-27+at+5.14.17+AM.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6890958153006612459.post-5568400105902407618</id><published>2011-12-22T15:30:00.000-08:00</published><updated>2011-12-22T16:12:54.327-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Army of One'/><category scheme='http://www.blogger.com/atom/ns#' term='Bug Advocacy'/><category scheme='http://www.blogger.com/atom/ns#' term='AST'/><category scheme='http://www.blogger.com/atom/ns#' term='Foundations'/><category scheme='http://www.blogger.com/atom/ns#' term='goals'/><category scheme='http://www.blogger.com/atom/ns#' term='collaboration'/><category scheme='http://www.blogger.com/atom/ns#' term='career development'/><category scheme='http://www.blogger.com/atom/ns#' term='life experience'/><category scheme='http://www.blogger.com/atom/ns#' term='weekend testing'/><category scheme='http://www.blogger.com/atom/ns#' term='BBST'/><category scheme='http://www.blogger.com/atom/ns#' term='conferences'/><category scheme='http://www.blogger.com/atom/ns#' term='education'/><category scheme='http://www.blogger.com/atom/ns#' term='people'/><category scheme='http://www.blogger.com/atom/ns#' term='learning'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='Test Design'/><category scheme='http://www.blogger.com/atom/ns#' term='writing'/><title type='text'>Into the Blue Again...</title><content type='html'>It's amazing to think that 2011 is almost over, and yes, while last year I lamented writing the obligatory "year that was" letters and somewhat lampooned them with my post last year titled &lt;a href="http://www.mkltesthead.com/2010/12/well-how-did-i-get-here.html"&gt;&lt;b&gt;"Well, How Did I Get Here?"&lt;/b&gt;&lt;/a&gt;, that post resonated with &lt;i&gt;many&lt;/i&gt; people. It is to date my most read and my most commented on article here on TESTHEAD, depending on which metrics you believe.&amp;nbsp; Based on the response to that post, I decided this year to just let it be known, this is a recap of the World of TESTHEAD, and the world of "Michael Larsen, Tester" for the year of 2011. The title this year is indeed, again, in homage to the seminal 1980 Talking Heads classic "Once in a Lifetime".&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;object class="BLOGGER-youtube-video" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0" data-thumbnail-src="http://1.gvt0.com/vi/I1wg1DNHbNU/0.jpg" height="266" width="320"&gt;&lt;param name="movie" value="http://www.youtube.com/v/I1wg1DNHbNU&amp;fs=1&amp;source=uds" /&gt;&lt;param name="bgcolor" value="#FFFFFF" /&gt;&lt;embed width="320" height="266"  src="http://www.youtube.com/v/I1wg1DNHbNU&amp;fs=1&amp;source=uds" type="application/x-shockwave-flash"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;/div&gt;&lt;br /&gt;2011 was a year of transition for me personally. I took many leaps of faith this year, and as the title says, I willingly jumped into new areas and new responsibilities. Early in the year, I ended my employment with Tracker Corp, bringing to an end six years of learning, camaraderie and a focus on the .NET world of software development and testing. In exchange, I came to Sidereel, and a world of learning, camaraderie and Rails software development. This is telling, because I'd never worked with Rails before, and my involvement with Ruby prior had been from recommendations from co-workers that it would be fun to learn. Well, now it was more than "fun to learn", it was an occupational hazard (and necessity :) ).&lt;br /&gt;&lt;br /&gt;With that, I started mapping out and learning a new site, a new programming language, a new model, a new way of storing data, and very different approach to developing software. I was no longer just a tester, I was to integrate with a fully Agile development team and work with and alongside of them. Oh, and I traded in a daily diet of Windows and PC's for a daily diet of Mac OS X and Darwin UNIX all sleekly wrapped in a Macbook Pro. Oh UNIX, how I have missed you!!! There&amp;nbsp; was just something comforting about leaving behind the world of MSI and EXE files and embracing tools such as ruby gems, homebrew and other options for installing software. Scriptable, customizable, and where Test Driven Development and Continuous Integration were not obscure buzzwords but actual practices that were, well, practiced! It's also been telling, humbling, and intriguing to learn about and use tools like Ruby, RSpec, Cucumber, Capybara, Selenium Web Driver and other areas of automating testing. I can safely say I have written more code this year than I have in the past 17 years prior!&lt;br /&gt;&lt;br /&gt;2011 also saw the process of Weekend Testers Americas come into its own. What could have been a few experimental and jerky first few sessions got smoother, cleaner, and better understood, and we had some great successes during the year. While I'm not sure how much others have learned, I know that &lt;i&gt;&lt;b&gt;I &lt;/b&gt;&lt;/i&gt;learned a great deal from this process. What was great to see was that this initiative was embraced by people all over the world, and our participants reflected this fact, including testers who would come into our sessions at 12:30 AM (yes, after midnight) from India to participate. First off, &lt;i&gt;&lt;b&gt;that's dedication&lt;/b&gt;&lt;/i&gt;, and my hats off to everyone who did that, but more to the point, it spoke volumes about the service we were offering and the fact that people &lt;b&gt;&lt;i&gt;wanted&lt;/i&gt;&lt;/b&gt; to come in and participate, even at those insane hours. We had some help from some heavy hitters, too. Michael Bolton and James Bach both came in to guest host some of our sessions ("Domain Testing" and "Creating Testing Charters"), and Jonathan Bach helped me craft one of my breakaway favorite test ideas of this year, that of "Testing Vacations". In all, it was a banner year for Weekend Testing Americas, and I am so thankful for all of the participants that helped make it possible. I'm especially thankful for Albert Gareev, who in addition to being a regular participant, stepped up to become my partner in crime for this enterprise, and frequently helping me develop new ideas or take the process in different directions than I probably would have had I been left to my own devices.&lt;br /&gt;&lt;br /&gt;2011 was a year of meeting and developing relationships with other testers. In January, I met Matt Heusser in person for the first time. As many of you know, one of my most involved and enduring professional relationships was with (and continues to be with) Matt. I produce the "This Week in Software Testing" podcast with him. I helped write a chapter for a book he was the principal editor for (more on that in a bit). I also was a sounding board for other ideas and offered several of my own in return. I had a chance to meet my fellow Weekend Testing Compatriots Marlena Compton, Markus Gaertner, and Ajay Balamurugadas in various places. Marlena and I had the pleasure of live blogging the entirety of the Selenium Conference from San Francisco, with our comments getting us branded as the "Table of Trouble" from the other participants. That was a fun memory, and it helped to set the stage for liveblogging other events throughout the year. Geting the chance to meet so many testers during this year in various capacities was a real highlight and much enjoyed aspect.&lt;br /&gt;&lt;br /&gt;2011 also saw my commitment to being published. I made a decision that I wanted to write beyond the scope of TESTHEAD. As will probably come as no surprise, my first few articles were Weekend Testing based. However, I had the opportunity to venture into other topics as well, including two cover stories for ST&amp;amp; QA magazine; one being my article about "Being the Lone Tester" and another an excerpt of my chapter from "How to Reduce the Cost of Software Testing".&amp;nbsp; Speaking of that, 2011 saw me and 20 other authors get our names in print and become book authors. It was a pleasure to have the chance to write a chapter for "how to Reduce the Cost of Software Testing". A later development, one in which I, literally, just got word about and accepted, was a potential new book that discusses "The Best Writing in Software Testing". I have agreed to be a junior editor for this project, and we are aiming for a 2012 release of this title. In addition, I also published articles with sites like Techwell, the Testing Planet and Tea Time With Testers. As of now, I have eleven articles that have been published external to TESTHEAD, and it is my hope that I'll be able to write more in the coming years.&lt;br /&gt;&lt;br /&gt;2010 was a first in that I attended my first testing conference. I made the commitment then that 2011 would be the year I would present at a testing conference. I received my opportunity to do exactly that. My first ever conference presentation was just 20 minutes, and it was at CAST 2011. I presented in the "Emerging Topics" track and discussed Stages of Team Development lessons I had learned from Scouting, and how they could apply to Testers. All in all, it went well, and even today, I still hear from people who said they appreciated the topic and liked my presentation. In addition, I also gave another full track session at CAST called Weekend Testing 3-D, where not only did i discuss how to facilitate Weekend Testing style sessions, we actually held a live session with participants from all over the world, and processed it in real time (this was the earlier mentioned "Testing Vacations" session that Jonathan Bach helped me develop. In addition, I proposed a track talk and paper for the Pacific Northwest Software Quality Conference titled "Delivering Quality One Weekend at a Time: Lessons Learned in Weekend Testing" and after writing the paper and&amp;nbsp; having it reviewed several times, received the nod to present it. However, fate struck, and I broke both bones in my lower leg (tibia and fibula), thus preventing me from delivering the talk (the organizers of PNSQC, however, still included my paper with the proceedings). Additionally, a friend who felt bad that I couldn't present at PNSQC forwarded my paper to Lee Copeland, the organizer of the STAR conferences. Lee liked the paper and asked if I'd be willing to present it at STAREast in April, 2012. I of course said YES! So I will get my chance to present this paper yet :)!&lt;br /&gt;&lt;br /&gt;There is&amp;nbsp; no question that I learned a great deal from the TWiST podcast, both as a producer and as an active listener, but 2011 will be even more memorable in that I graduated from editing the show and as an occasional guest to being one of a handful of rotating regular contributors on the mic. It's been interesting to have people email me and say "hey, I heard your interview last week, that was a great show and a great topic, thanks for your comments and explanations". I thought it was especially cool when I had someone say that they felt that I'd make a great game show host (LOL!).&lt;br /&gt;&lt;br /&gt;2011 saw my continued focus on working with the Miagi-do School of Software Testing. At CAST 2011, a number of us Miagi-do Ka, including Markus Gaertner, Ajay Balamurugadas, and Elena Hauser worked along with Matt Heusser at the CAST testing challenge. During that competition, I had the chance to show Matt and the other testers there what I was able to do, and due to that experience, Ajay, Elena and I were awarded our Black Belts. While the experience itself was great, it also came with the expectation that I be willing to mentor and teach other testers, an opportunity that I have gladly taken on and look forward to doing more of in 2012.&lt;br /&gt;&lt;br /&gt;One of my most active projects for the year of 2011 was helping to teach the Black Box Software Testing courses for the Association for Software Testing. I had the opportunity this year to instruct, as either an Assistant or as a Lead Instructor, all three courses offered in the BBST series (Foundation, Bug Advocacy and we just completed the pilot program for Test Design on December 10th). I was in this capacity that I was also nominated to run for the Board of Directors for the Association For Software Testing. I never envisioned myself being a Director of anything, much less an international software testing organization! Still, someone in the organization felt I deserved a shot, and nominated me. What's more, someone else seconded it. Even more amazingly, a lot of people (perhaps many of you readers) thought I'd be a good fit for the position as well, since I was indeed elected to serve on the board. My two year term began in October. While daunting, it is also exciting to think that I may actually help shape the future of this organization in the coming years, and to help represent my fellow testers. Believe me, it's not something I take lightly.&lt;br /&gt;&lt;br /&gt;Quite possibly the biggest "Into the Blue Again" moment of the year, though, happened at our first AST board meeting in October. It was at that meeting that Cem Kaner and Becky Fiedler announced their desire to have someone take over as the Chairman of Education Special Interest Group. While a part of me felt I was wholly inadequate for the task, another part of me felt that this was something essential and that it needed someone to spearhead it so that the education opportunities within the organization could be championed and further developed, while allowing Cem and Becky the opportunity to do what they really wanted to do, which was develop more and better testing courses. With that, I offered to chair the Education Special Interest Group. I'm not sure what was more surprising, the fact that I offered, or that the rest of the board took me up on it! Two years ago, Cem Kaner was a man whose books I had read and whose presence loomed large as a "testing guru" on high. The thought I would ever meet him seemed remote. The thought I'd actually take over for him and spearhead an initiative he championed &lt;i&gt;&lt;b&gt;never even crossed my mind&lt;/b&gt;&lt;/i&gt;!!! Still, that's what has happened, and I guess 2012 and beyond will tell us what I actually did with it. I'm hoping, and working towards doing, all I can to prove worthy and up to the task.&lt;br /&gt;&lt;br /&gt;2011 was, really, a year where I took leaps of faith, lots of them, and discovered that I could do even more than I ever imagined I could. I've shared may of those journeys in TESTHEAD posts, and I thank each and every one of you who are actively reading this blog for your help in motivating me to take these leaps of faith. It's been another banner year for me, both in learning and opportunities. Overall, the experiences of the past year have given me confirmation that, if I were to jump "Into the Bue Again", that it would be a great chance to learn and grow, regardless of whether or not the outcome were necessarily successful, lucrative or advantageous. Granted, most of them have been, and those that haven't been, well, I'd like to think I failed quickly and early enough to learn from those experiences and correct my trajectory. Time will tell if that's true, of course. As in all things, there were many people that helped make 2011 a banner year for me. &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Thanking a bunch of people is always fraught with danger, because invariably someone gets left out, and there have been hundreds of people who have been instrumental in making this a banner year for me. Still, there are many that stand out, so to that, my heartfelt thanks to Adam Yuret, Ajay Balamurugadas, Albert Gareev, Alex Forbes, Anne-Marie Charrett, Ashley Wilson, Becky Fiedler, Benjamin Yaroch, Bill Gilmore, Cem Kaner, James Bach, Janette Rovansek, Jason Huggins, Jon Bach, Lalitkumar Bhamare, Lee Copeland, Lynn McKee, Markus Gaertner, Marlena Compton,&amp;nbsp; Matt Heusser, Orian Auld, Rick Baucom, Selena Delesie, Shmuel Gershon,&amp;nbsp; Terri Moore,&amp;nbsp; Thomas Ponnet, Timothy Coulter, Will Usher and Zach Larson. Thank you all for helping me make those leaps of faith. More to the point, thank you for having the faith in me that I'd be able to actually do what you believed I could do! Thank you for what has honestly been, at least as far as software testing is concerned, my greatest year (and remember, last year was pretty awesome, too. I didn't think I'd be able to top &lt;i&gt;&lt;b&gt;that&lt;/b&gt;&lt;/i&gt;!). &lt;br /&gt;&lt;br /&gt;Here's to an every bit as exciting and fun-filled 2012. I'm looking forward to seeing where I might leap next :).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6890958153006612459-5568400105902407618?l=www.mkltesthead.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://www.mkltesthead.com/feeds/5568400105902407618/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6890958153006612459&amp;postID=5568400105902407618' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6890958153006612459/posts/default/5568400105902407618'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6890958153006612459/posts/default/5568400105902407618'/><link rel='alternate' type='text/html' href='http://www.mkltesthead.com/2011/12/into-blue-again.html' title='Into the Blue Again...'/><author><name>Michael Larsen</name><uri>https://profiles.google.com/104738247543282839437</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-L_ARsHiklGg/AAAAAAAAAAI/AAAAAAAABPA/PwBZuynaDbc/s512-c/photo.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6890958153006612459.post-866559116767362725</id><published>2011-12-22T07:00:00.000-08:00</published><updated>2011-12-22T07:11:15.518-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='education'/><category scheme='http://www.blogger.com/atom/ns#' term='teaching'/><category scheme='http://www.blogger.com/atom/ns#' term='learning'/><category scheme='http://www.blogger.com/atom/ns#' term='books'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='PRACTICUM'/><category scheme='http://www.blogger.com/atom/ns#' term='career development'/><title type='text'>Exercise 37: Symbol Review: Learn Ruby the Hard Way: Practicum</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://upload.wikimedia.org/wikipedia/commons/f/f1/Ruby_logo.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="200" src="http://upload.wikimedia.org/wikipedia/commons/f/f1/Ruby_logo.png" width="199" /&gt;&lt;/a&gt;&lt;/div&gt;At this stage, we've been given a bunch of commands, keywords, and options that we can used in our programs. there's a bunch of others we may not yet really know how to use, but it's a good idea to get familiar with them anyway. In this exercise, we're asked to do some sleuthing and see if we can figure out what all the stuff we've been using actually means. Below represents my best efforts to figure these things out. &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Zed makes the point that he considers these to be the symbols and keywords that are important to know.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Keywords&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;alias&lt;/b&gt; - associate a method and make it synonymous with another method.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;and&lt;/b&gt; - flow control operator with low precedence that means do x and do y. Not to be confused with &amp;amp;&amp;amp;, which is a boolean operator with high precedence.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;BEGIN&lt;/b&gt; - Designates, via code block, code to be executed unconditionally before sequential execution of the program begins. Sometimes used to simulate forward references to methods (comes from http://ruby-doc.org/docs/keywords/1.9/Object.html#method-i-BEGIN,and I'm only slightly sure of what it means).&lt;br /&gt;&lt;br /&gt;&lt;b&gt;begin&lt;/b&gt; - Together with end, delimits what is commonly called a “begin” block (to distinguish it from the Proc type of code block).&lt;br /&gt;&lt;br /&gt;&lt;b&gt;break&lt;/b&gt; - terminates execution of a code block and jumps out of it. Think of a case statement, as that's where I'm most familiar with seeing it being used.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;case&lt;/b&gt; - consider it like a stack of related if statements. It's a more simple system to&lt;br /&gt;&lt;br /&gt;&lt;b&gt;class&lt;/b&gt; - defines a object and its methods that can be used in ruby&lt;br /&gt;&lt;br /&gt;&lt;b&gt;def&lt;/b&gt; - used to define a function&lt;br /&gt;&lt;br /&gt;&lt;b&gt;defined?&lt;/b&gt; - determins if a method refers to something directly (a string, a &amp;nbsp;number, etc.)&lt;br /&gt;&lt;br /&gt;&lt;b&gt;do&lt;/b&gt; - execute everything that follows as though it were part of the same block&lt;br /&gt;&lt;br /&gt;&lt;b&gt;else&lt;/b&gt; - do this if all other conditional statements are not met&lt;br /&gt;&lt;br /&gt;&lt;b&gt;elsif&lt;/b&gt; - doo this if the first conditional statement is not met&lt;br /&gt;&lt;br /&gt;&lt;b&gt;END&lt;/b&gt; - defines a section of code that can be run at the end of a code block&lt;br /&gt;&lt;br /&gt;&lt;b&gt;end&lt;/b&gt; - end of a block of code&lt;br /&gt;&lt;br /&gt;&lt;b&gt;ensure&lt;/b&gt; - usually run with a rescue statement, even if the rescue statement doesn't get run, the ensure statement will run&lt;br /&gt;&lt;br /&gt;&lt;b&gt;false&lt;/b&gt; - a boolean value, it's sued to evalute whether or not a statement will run (used often with while and unless)&lt;br /&gt;&lt;br /&gt;&lt;b&gt;for&lt;/b&gt; - keyword to define the start of a for loop&lt;br /&gt;&lt;br /&gt;&lt;b&gt;if&lt;/b&gt; - keyword to define the first conditional statement&lt;br /&gt;&lt;br /&gt;&lt;b&gt;in&lt;/b&gt; - run the steps in the for loop that match this condition&lt;br /&gt;&lt;br /&gt;&lt;b&gt;module&lt;/b&gt; - synonymous with function, it's a scope where local variables are not aware of other values&lt;br /&gt;&lt;br /&gt;&lt;b&gt;next&lt;/b&gt; - an iteration step, modifies the value of a variable even if no ction is performed&lt;br /&gt;&lt;br /&gt;&lt;b&gt;nil&lt;/b&gt; - no value&lt;br /&gt;&lt;br /&gt;&lt;b&gt;not&lt;/b&gt; - is not this value&lt;br /&gt;&lt;br /&gt;&lt;b&gt;or&lt;/b&gt; - do if an example is condition 1 or condition2&lt;br /&gt;&lt;br /&gt;&lt;b&gt;redo&lt;/b&gt; - re-executes a code block without regard to conditions of varibles or state of the program&lt;br /&gt;&lt;br /&gt;&lt;b&gt;rescue&lt;/b&gt; - error handling section of code.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;retry&lt;/b&gt; - associated with rescue, has the program try the section of code where the rescue statement&amp;nbsp;resides again.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;return&lt;/b&gt; - value sent out from a function to the main routine&lt;br /&gt;&lt;br /&gt;&lt;b&gt;self&lt;/b&gt; - the area of code being run at any given time&lt;br /&gt;&lt;br /&gt;&lt;b&gt;super&lt;/b&gt; - looks for anc can call all factors associated
