MathJax

Friday, December 20, 2013

Programming Language of the Week: C

C is a compiled language. Rather than having a separate program interpret your code line by line, a compiler reads your entire program at once and changes your human-friendly source code into binary code that is directly executed your processor (e.g. an *.exe file on a Windows system). If you know how to interpret binary instructions for your processor, you can trace out which instructions will be loaded into your processor in order.

C of course isn't alone in being a compiled language, but it is perhaps the most prolific. C has been used extensively in the development of Windows, OS X, and the Linux kernel. It's the go-to for systems which have requirements which preclude the overhead of interpreting code line-by-line or pauses for garbage collection. Interpreters for interpreted languages are often written in C.

Learning C gets you "close to the metal." Understanding pointers and being responsible for your own memory management illuminates the barrier between the logical systems we aspire to create and the physical machines which realize those designs.

You can see C's linguistic influence in later languages by noting several features shared by other languages: statement blocks grouped by opening and closing {}s, primitive variable type names int/long/char, for-loop syntax, pre-/post- increment/decrement operators, the same boolean operators are shared in whole or in part by Java, JavaScript, C# and more.

To learn C, you'll need a C compiler, a motivating project, and a good tutorial. Check out http://www.cprogramming.com/tutorial/c-tutorial.html for more.


#include <stdio.h>

int main()
{
    printf("Hello, world!");
    return 0;
}

Wednesday, December 18, 2013

Computing for Everyone: Words to avoid in software, aspirational edition

The two hard things in software are cache invalidation and naming things. We haven't talked here yet about caches, yet alone their invalidation, but recent events triggered my desire to address a subtopic about naming.

As your future adjunct professor, I forbid you from using any of the following words in your names:
  • generic
  • simple
  • standard
  • reusable
  • extensible
  • pluginable
These words represent ideals your software should embody, but these words should never be part of your class names, variable names, namespace names, or overall system branding. Here's why.

Human psychic energy is limited.

Well-written code respects the limited psychic energy the maintainers can devote to understanding and making changes to it. Well-written code will minimize the effort required for someone new to a system to take any stanza of code from the system, understand the purpose of the stanza, and convince himself that the stanza correctly implements the intended purpose.

Names are among mankind's most significant allies in understanding software. Computers are happy to distinguish between variables named llllIlll and lllIllll, but humans will go insane dealing with such code in the long-term, have a huge ramp-up time understanding existing code bases written this way in the medium-term, and be much more likely to introduce errors while making changes vital to the mission of a system in the short-term.

Good names in software, then, refer to the problem domain they are addressing, rather than architectural goals. "simpleExtensibleField1" and "simpleExtensibleField2" as variable names are vastly inferior to "subtotal" and "tax".

The problem with the above list is that the extra words make the variables sound different to a computer, but add noise for a human. There's a temptation to brand large refactoring efforts as any of these words, but these refactoring efforts can end halfway through. Then another refactoring effort comes in on the half-refactored code base, sees their favorite word was taken and uses a different word from the list. While refactoring is supposed to make a code base easier to understand without changing its functionality, these sorts of names do the opposite. It would, in fact, be clearer to a human if these efforts had been branded in variable names with colors instead (not that you should do that, either). By way of example, it's much easier to remember if you're working with all GreenWhatchaMadoogies or all YellowWhatchaMadoogies rather than all GenericWhatchaMadoogies or all PluginableWhatchaMadoogies. And really, if the code is actually simple or generic, rather than just insisting via variable names that it is, the code would refer to instances of WhatchaMadoogies rather than either of the preceding. The "generic"/"simple" labels, having failed their mission, are reduced to brands.

Monday, December 16, 2013

Brain90X: Thoughts from "Characteristics of Games" and "Thinking, Fast and Slow"

There's a disturbing correlation between getting older and losing the ability to learn new things. Since learning new things is one of my favorite things in the whole wide world, I'd like to keep this ability as long as possible and increase this ability to its full potential. My plan? Games.

Here is my 3am rationale from last month, cleaned up slightly on a Saturday afternoon:

Learning new things takes a lot more energy than applying what's been learned. In a modern life, we're able to learn enough after a few decades to subsist mostly on applying what we have learned with a minimal amount of new learning required. Once we can pay our bills simply by applying learned knowledge, we aren't so motivated to go out and engage in the relatively mentally taxing enterprise of learning new things. My theory, then, is that the declining ability to learn new things with age is not a biological inevitability, but a function of atrophy once we've learned enough to pay our bills. What we need is a way to exercise the learning part of our brain so that it stays with us in perpetuity.

Climbing the heuristics ladder of a good game is the best kind of exercise you can give your brain. A "heuristics ladder" for a game is the set of increasingly complex set of rules-of-thumb you build up for yourself to let you know how well you're doing ("state heuristics") and what choices you make to maximize your chances of victory ("directional heuristics"). This type of mental activity is very different from memory recall and applying "street smarts."

Directional heuristics: Who's winning?
The first type of cheap, fast brain activity is memory recall: Erudition. The process of rote learning, while oft-scorned, is critical to competently functioning in a field. If your brain is a computer system, this is similar to "warming up your cache." (What is a cache?) I like to think of memory recall as "book knowledge." Literacy is the practice of transferring this type of information between humans (books, speech, this blog, plugs from The Matrix). (An interesting tangent is to note that body language and flirtatious subcommunication don't fit here at all. In fact, this information is background noise for the reality of most social interactions.)

Literacy of the future!
The second kind of cheap, fast brain activity is "street smarts": Worldliness. Street smarts assess both nouns and game strategies based on what has come before. Street smarts come from a statistical learning style where you observe classified and regressed examples in order to assess a new instance. In the computer world, this is how most kinds of machine learning work. Street smarts can be partially transferred through literacy as well--if it's done right and the source is trustworthy.

This leaves us with the most risky and expensive operations our brains perform: experimentation and creativity while climbing heuristics ladders: Cleverness. This is where the brain that comes up with new things to try out, where the brain sets up new literacy caches for information and aggregate data stores for examples. The more novel the situation, the more this part of the brain is engaged. It creates, tests, imagines, evaluates, and combines strategies. It working at its hardest when the answer is not available from recall or street smarts. Recall and street smarts are automatically and invisibly applied first in understanding a situation (thus introducing personal biases and new approaches). Heuristic ladder climbing is difficult, and our brains automatically take shortcuts to get to a passable approach.

This difficulty is a good thing for the brain. This is how the brain hits the gym to stay in shape. What an over-trained brain looks like is an exercise in imagination left to the reader.

Climbing heuristics ladders can itself be a function of literacy (chess books) and street smarts (what has worked for you and others in the past). There's also the punting strategy (try something. What happens?) and the combination strategy (adjust a strategy based on the assessed strengths and weaknesses of previous approaches). This engages Kahneman's "System 2" from Thinking, Fast and Slow. What's great about games is that this process happens when the stakes are low: you can face a variety of novel situations without having to bet your fortune, your business, or your life.

Now let's talk about logic's role here. Logic can transform novel situations into something we are better equipped to deal with: a rote answer or a way to proceed. It is also a System 2 function to multiply the abilities of System 1. Something about logical training is critical to our ability to climb heuristics ladders presented by games. It's a force-multiplier for erudition and honed instinct because it multiplies the situations where we can apply hard-won lessons.

Logic can take the lessons you learned from here...
...and suggest looking for opportunities such as this here.
Climbing heuristics ladders also sharpens creativity. Try something out. Give it your best shot. Compare it against what you know and how it works out. Build a logical system for thinking about the new situation. This is creativity. The germ of creativity can be something simple, but giving it an honest, competent try requires discipline. Plus as you gain experience, you realize that most ideas fail. The ones which succeed are precious. You develop a filter based on book smarts and street smarts to filter out the strategies you will even attempt! The more you know and can apply, the more narrowly you can/will filter the narrative of a creative experiment's success.

So as you get more worldly and erudite, you won't need to be as clever. Unfortunately, the clever part of the brain is a muscle. This is the learning center. This workout is what keeps your mind young and nimble. This is why we need games. Games of all sorts. Low cost of experimentation/success/failure. Creative heuristic ladder climbing/mental model building. Logical transformations to existing data stores. Creation of new data stores. Logically transforming and making analogies from games to other situations and novel situations to each other.

Playing games could keep this muscle in shape. It could be that the reason for declining mental strength is only partly chemical and very behavioral. Once you have enough book and street smarts to live and live comfortably, why continue engaging in this expensive mental exercise? Why sell past the close? Why work hard when you already have enough? To stay in shape.

Another exercise for the reader: How does this sort of narrative apply to the idea of upward mobility in a free economy?

I'd like to finally emphasize that this natural progression from the clever/creative to the worldly to the erudite is inevitable. Even in games with deep, rich heuristics ladders such as chess, a player with many years of experience can fall into winning on erudition and street smarts alone without realizing it. The key is to find competition at around the same level of erudition and worldliness so you force each other into the realm of the clever. Failing that, the game, as beautiful as it is, no longer keeps your brain in shape. It may still be enjoyable to play and very enjoyable to win, but in order to progress you'll need tougher opponents or new games.

Finally, an alternative to games, if none are available, is the deep study of various branches of mathematics. Try it out. There's much to learn, much to experiment with, and much to stir creativity.

Sources:
Footnotes:
  • A cache in computing is local storage of data that is expensive to retrieve; for example, it's faster to read from and write to RAM than to a traditional hard drive, so the contents of often-referenced files are loaded into RAM for fast manipulation. Similarly, microprocessors have a cache on the chip for data that are stored in RAM to speed up computations. When a cache is initialized, it is empty, but as the system is used the cache starts getting populated and the hoped-for speedup is realized. Using a system to populate the cache is sometimes called "warming it up."
  • Kahneman's "System 1" is the fast, cheap, automatic side of the brain. "System 2" is the slow, expensive, methodical part of the brain, sometimes an apologist for System 1, sometimes the only thing helping us see past the biases such automatic processing induces.

Monday, November 11, 2013

Book Review: Thinking, Fast and Slow

"Given the subject matter, I can announce without hyperbole that this book is required reading for anyone with a brain."
Thinking, Fast and SlowThinking, Fast and Slow by Daniel Kahneman
My rating: 5 of 5 stars



View all my reviews

Monday, September 23, 2013

How it went

The day was almost standard. If anything, it was perhaps too low-pressure. The pressure at the surface of Renton Municipal Airport, 32 feet above sea level, was 29.60 inHg, rather than the standard 29.92 inHg.

Breakfast was eggs-in-the-nest with Dave's Killer Bread, a bunch of grapes, and a tall glass of 2% milk. I wasn't hungry enough to eat the banana.

Artist's rendition. The nest is actually buttered toast. Not pictured: bananas.
The temperature warmed from its initial standard conditions of 59ºF/15ºC to 73ºF/23ºC. Cruise performance would be midway between the center and right-hand columns of Cessna's cruise performance table in section 5 of the 172S Skyhawk's Pilot Information Manual. That's fine--I'd just be sipping a little less gas at 2500 RPM. And the checkride wasn't going to burn more than 15 gallons of the C172's 53 usable gallon capacity, anyway.

I had been looking forward to this day for two years. I had been ready in the fall of 2011, but mono, weather, a change of instructors, the school getting really popular, a determination to reach a normal BMI and never get fat again, and changing roles at work all took their toll on my training schedule. But now that that was all done, it was finally time to do what I could have done two years ago.

I got to the airport early to skim through the Private Pilot Oral Exam Guide one last time. Skimming through a book is free; the exam isn't.

The oral exam concluded around 2:15pm. I had skipped lunch on the strength of my breakfast, so I grabbed a Snickers. The 'E' in IMSAFE is Eat!

N639SP had just returned from her 100-hour inspection, trivializing the task of locating her maintenance logs. There were 7 crystal-clear quarts of fresh oil in the engine.

Both while climbing and while on final you could feel each of the day's variable wind's 5 knots shifting direction with the caprice of a bored dilettante. We never climbed above 2700 feet, so we had plenty of bumps from the terrain throughout the maneuvers. Because of the bumps, I increased my airspeed for slow flight and on final approach beyond what was necessary. There's being within PTS and there's being proud with your maneuvers, and I wasn't proud.


Anyway, I passed! This is my announcement! I am now a private pilot.

Here's where it happened.
I'm equal parts pleased with the accomplishment and frustrated that it happened two years later than it could have. I know that becoming-a-private-pilot-is-a-beginning-not-an-end, but it's a huge relief to have finished the end of the beginning, especially after such a delay.

I highly recommend aviation as a hobby for those with the means. Become a software developer, pay off your loans, build up your "oh *&@#$" money, and learn to fly.

Pro tip: don't get mono.1




1If you have to, kiss everyone in sight before starting your training. Stop being a baby about it and go contract a disease.2

2I'm kidding, of course...but only just. Seriously, don't get mono.

Monday, August 19, 2013

Computing for Everyone 6: Conditional Execution

Wasn't that last post fun? I'm guessing for a lot of you the answer is "no." I'm sorry--my bad.

So here's the thing: the goal of this series is to allow people who aren't programmers to take full advantage of their computers and other programmable devices at home, school, and work by giving a light introduction to computing concepts. I think the last post went too deep to really serve that purpose. I'll try to steer clear of posts like that in the future. All right, enough metablogging.


Today's topic is conditional execution.

You've seen this before:
visitor:
for your output:

Or have you? I decided to give myself some special treatment this time. Pretend you're me. Just go and tell that box that your name is John and click again.

Neat, eh? So what's the difference?

All computer programming languages support conditional execution: if something is true, do X; otherwise, do Y. Here's what the new code looks like:

function greet (visitor) {
    var greeting;

    if (visitor === "John") {
        greeting = "Hello, " + visitor + ". Remember, authentication is not authorization!";
    } else {
        greeting = "Hello, " + visitor + "!";
    }

    return greeting;
}

Neat, huh? if and else are special instructions in JavaScript (and in most programming languages). The stuff inside the () following if is evaluated as a boolean expression. If the expression evaluates to true, the block (starts with {, ends with the next }) right after the if statement is executed. Otherwise (else), the block ({ to next }) immediately following the else statement is executed.

The statement this new program evaluates is
  visitor === "John"
. A === comparison is true when the values to the left and right are equal and of the same type (e.g. both are numbers or both are strings), so if visitor is set to "John", the comparison visitor === "John" evaluates to true. "John" === "John" would also be true, just a little silly to write (you could just write "true" without the double-quotes (though writing if(true) is pretty silly to write as well)). "John" === "You" is false, 1 === 1 is true, 1 === 2 is false, 1 === "1" is false because the triple-equals comparison operator we're using treats the number 1 as distinct from a string containing 1.

JavaScript has other comparison operators, mostly for numbers. You'll see these same symbols across a wide variety of modern programming languages (well most of these are the same in, C, C#, F#, Java, Ruby, Python, Perl, PHP, BASIC, at least).

Comparing a and b in JavaScriptTrue when...
  a === b
a equals b
  a !== b
a does not equal b
  a < b
a is less than b
  a > b
a is greater than b
  a <= b
a is less than or equal to b
  a >= b
a is greater than or equal to b

Comparison operations can be combined using logical operators && (and), || (or) and ! (not) from last time:

function coverCharge (sex, itIsLadiesNight) {
    var doorPrice;
    if (sex === "F" && itIsLadiesNight) {
      doorPrice = 0;
    } else {
      doorPrice = 10;
    }
    return doorPrice;
}

So women get in free on ladies' night, otherwise it's $10 for everybody.
coverCharge ("M", true) returns 10.
coverCharge ("F", false) returns 10.
coverCharge ("F", true) returns 0.

In addition to if and else, there is "else if". This is how your describe a multi-tined fork in the road for the progress of your program instead.

function sign(birthMonth, birthDay) {
    var sign = "Oops, I guess I missed one. Sorry about that.";
    if (birthMonth === 3 && birthDay > 20  
            || birthMonth === 4 && birthDay <= 20) {
        sign = "Aries";
    } else if (birthMonth === 4 && birthDay > 20 
            || birthMonth === 5 && birthDay <= 20) {
        sign = "Taurus";
    } else if (birthMonth === 5 && birthDay > 20  
            || birthMonth === 6 && birthDay <= 20) {
        sign = "Gemini";
    // ...more of the same for 8 other signs...
    } else if (birthMonth === 2 && birthDay > 20  
            || birthMonth === 3 && birthDay <= 20) {
        sign = "Pisces";
    }
    return sign;
}

else ifs can be chained off of an if indefinitely, but an if must start the chain, and no else ifs may appear after the final else (the final else may be omitted, as above).

Exercise:
Pretend you're a robot. Imagine you have the data you need to make decisions about what to do as conveniently-named variables, and you have conveniently-named statements that describe what you can do. Can you use a chain of if/else if/else statements to describe what to do when you're bored? Describe a series of if/elses that will make your robot version of yourself behave as close to how you would behave as possible.

Bonus:
Death Note is an awesome anime show and manga. How could you express the rules for the Death Note in JavaScript so that your program can compute an outcome from use of the note? What are your inputs and outputs?

I do not often recommend anime shows, but when I do, it's always Death Note.

Wednesday, August 7, 2013

Computing for Everyone 5: Truth and Logic

Computer programming begets philosophizing. You break down complex tasks into parts simple enough for a calculator to digest. You represent real-world concepts as data in a machine. You build towers with your mind (and since the mind has its limits on how much information it can construct and logically process at once, remember to go easy on yourself).

Today we'll discuss basic logic. We'll talk about how you can combine statements that are true or false via a few different logical operators and evaluate the combination is true or false.

This logical discussion lacks a certain degree of subtlety: we assume we have perfect access to knowledge establishing statements as true or false; we're not taking into account a range of uncertainty about a statement or the risks of being wrong. Often these statements are the results of comparisons: 5 > 10 is false; 50 > 10 is true.

Boolean variables are variables that can have only one of two values: true or false. The adjective "boolean" comes from the last name of a 19th-century mathematician; there isn't any deeper meaning buried in the etymology. There are three basic logical operators: \(\land\) (and), \(\lor\) (or), and \(\lnot\) (not).

\(\land\) ("and") evaluates to true if its left and right sides are both true. \(\lor\) ("or" evaluates to true if either its left side or its right side evaluates to true. \(\lnot\) negates the logical value of what follows: if the value is true, \(\lnot\) makes it evaluate to false and vice-versa. In summary,

Logical expressionReads as...Evaluates to true only when...Written in JavaScript (and many programming languages) as...
\(p \land q\)"p and q"p is true and q is true
  p && q
\(p \lor q\)"p or q"either p is true or q is true (or both are true)
  p || q
\(\lnot p\)"not p"p is false
  !p

Truth tables are helpful charts of what a logical expression evaluates to for every variable involved. Here is what the truth tables for and (\(\land\)) , or (\(\lor\)) , and not (\(\lnot\)) look like (0 = false, 1 = true):

\(p\)\(q\)\(p \land q\)\(p \lor q\)\(\lnot p\)
00001
01011
10010
11110

Okay, this might need a touch more explanation. Let's read the second-to-last row as an example. This row tells us, from left to right, that when \(p\) is true and \(q\) is false, \(p\) and \(q\) (\(p \land q\)) is false, \(p\) or \(q\) (\(p \lor q\)) is true, and not p (\(\lnot p\)) is false. The other rows can be read the same way.

Note that because this chart has two variables (\(p\) and \(q\)), each of which can take on either of two values (true or false), there are \(2^2 = 4\) rows in our truth table.

Exercise:
Every new variable in a boolean expression doubles the number of rows in our truth table, so our table above with two variables has four rows.

For each row in our truth table, the expression we examine can either evaluate to true or false (2 distinct values). This means that for an expression with \(n\) different variables, our truth table has \(2^n\) rows which can be true or false giving \(2^\left(2^n\right)\) boolean expressions which are different from each other in terms of the set of outputs given for all sets of inputs.

The boolean operators \(\land\), \(\lor\), and \(\lnot\) are all that is needed to make any of these other expressions. For example, if we wanted to fill in a truth table whose outputs looked like
\(p\)\(q\)???
001
011
100
111


we could make this happen by replacing ??? with \(\lnot p \lor q\). See if you can fill up the entire two-variable truth table using only \(\land\), \(\lor\), and \(\lnot\) (with parentheses, if it makes life easier). The truth tables we've seen above are filled in below. Hint: there's one more entry given to you from today's Bonus. 


\(p\)\(q\)0\(p \land q\)???\(p\)???\(q\)???\(p \lor q\)????????????\(\lnot p\)\(\lnot p \lor q\)???1
000000000011111111
010000111100001111
100011001100110011
110101010101010101

The 0000 and 1111 columns are known as "contradictions" and "tautologies," respectively. The 1001 column is often read "p if and only if q" (abbreviated as "p iff q" (two f's in iff: "p if q" corresponds to column 1101)).




Bonus:
When we evaluate expressions in basic arithmetic, there is an order of operations. We evaluate exponentiation before multiplication, which we evaluate before addition. We can also change the order of operations by using parentheses, so
\[3 \times 4^2 + 2 = 48 + 2 = 50\], but
\[(3 \times 4)^2 + 2 = 144 + 2 = 146\]

To save us from always showing parentheses, logical operators have an order of precedence as well. Just like our arithmetic operators, from highest to lowest precedence, are exponentiation, multiplication, and addition, the order of operations for the logical operations we have seen, from highest to lowest, is negation (\(\lnot\)), then logical conjunction (the official name for "and," \(\land\)), then logical disjunction (the official name for "or," \(\lor\)).

This means we can actually remove the extra parentheses from the expression \((p \land (\lnot q)) \lor ((\lnot p) \land q)\) and it means the exact same thing. In fact, this function is actually kind of interesting. Let's take a look at its truth table:

\(p\)\(q\)\(p \land \lnot q \lor \lnot p \land q\)
000
011
101
110

This expression evaluates to true when either p or q or true, but not both. This expression is known as an "exclusive or" (\lor meaning "inclusive or") or XOR and comes with its own fancy symbol as well: \(\oplus\). This expression could be written as \(p \oplus q\). It's very convenient for us to have this symbol, since having it allows us to write
\[(p \oplus q) \oplus r\]
rather than
\[\lnot p \land \lnot q \land r \lor \lnot p \land q \land \lnot r \lor p \land \lnot q \land \lnot r \lor p \land q \land r\]
by analogy to the above, or, equivalently,
\[\lnot (p \lor q) \land r \lor \lnot (p \lor r) \land q \lor p \land \lnot (q \lor r) \lor p \land q \land r\]
by writing it the way we think about the concept of an "exclusive or." In fact, it turns out that like addition and multiplication, the exclusive or operation is also associative, so we can even drop the parentheses: \(p \oplus q \oplus r\)

I'm dizzy, too. Thank God for \(\oplus\) in times like these.

Here is the truth table for \(p \oplus q \oplus r\):
\(p\)\(q\)\(r\)\(p \oplus q \oplus r\)
0000
0011
0101
0110
1001
1010
1100
1111

There's no actual bonus exercise; you're just a trooper for getting through the extra material. Honestly, I tend to get a little carried away when I start using math symbols in my blog. Here's a brainteaser as a reward:

Is the following statement true or false?
"This statement is false."

Monday, August 5, 2013

Computing for Everyone 4: Clarity

Last time we looked at some basic JavaScript code to start learning how to read and write source code in general. Before continuing, I'd like to show you something about writing code.

Here's that first bit of JavaScript I wrote for you:
function greet (visitor) {
  var greeting = "Hello, " + visitor + "!";
  return greeting;
}

Armed with your basic knowledge of how JavaScript works, it's pretty easy to tell what this code is trying to do.

What if I wrote it this way?
function g (v) {
  var h = "Hello, " + v + "!";
  return h;
}
Functions g and greet behave identically, but notice how greet names what my function does much more descriptively than does g, and visitor and greeting describes the data I'm storing in my variables much better than v and h. If the two functions behave identically, why did I choose to write the longer version? Because when you write software, you aren't only writing the software in a way the computer can understand it; you're writing it in a way that you can understand it.

Even when writing your code, you will spend most of your time trying to read and understand what's there. Writing software is a process of building with your mind. It's a process of learning, understanding, and describing in detail. Here are two more ways I could have written the function:
function doWhateverThisFunctionDoesWhoKnowsAnyway (santaClaus) {
  var hoHoHo = "Hello, " + santaClaus + "!";
  return hoHoHo;
}
These kitschy names obscure what the code is trying to do.

function xxxxxxxxxx (xxxxxxxxxxx) {
  var xxxxxxxxxxxxx = "Hello, " + xxxxxxxxxxx + "!";
  return xxxxxxxxxxxxx;
}
The different identifiers differ only in the number of x characters in their names. Oh, one more thing about JavaScript: statements are separated by curly braces ({}) and ; characters--we don't actually need any of those line breaks or most of those spaces. This is legal JavaScript:
function xxxxxxxxxx(xxxxxxxxxxx){var xxxxxxxxxxxxx="Hello, "+xxxxxxxxxxx+"!";return xxxxxxxxxxxxx;}

It's not enough to write programs that do what you want the first time: you have to avoid going crazy during the process. Your programs should not only do what you want when the computer reads them, but they should be understandable in intent and mechanism when a human reads them.You will thank yourself when you want to add something new to your program later and when you have to track down a mistake in your code.

Programming languages will let you freely choose names for your functions and variables. Your variable names should describe what they represent; your function names should describe what your functions do. Like so much else in life, clarity is your friend.

Exercise:
Go on a ~20-minute Wikipedia binge rooted at the article on the programming language named brainfuck. Make sure you hit the article on Turing tar-pits along the way. Also, there are contests for writing unintelligible code. To each his or her own.

Bonus:
If your life depended on it, how would you label your goblets to avoid confusion like that encountered by Danny Kaye in this scene from The Court Jester?

Quotes:

"Everything [in Digitopolis] is called exactly what it is. The triangles are called triangles, the circles are called circles, and even the same numbers have the same name. Why, can you imagine what would happen if we named all the twos Henry or George or Robert or John or lots of other things? You'd have to say Robert plus John equals four, and if the four's name were Albert, things would be hopeless." - The Phantom Tollbooth

"Everything should be as simple as possible, and no simpler." - Albert Einstein

"There are two ways of constructing a software design: One way is to make it so simple that there are obviously no deficiencies, and the other way is to make it so complicated that there are no obvious deficiencies." - 1980 Turing Award laureate Tony Hoare

Thursday, August 1, 2013

Computing for Everyone 3: Expressions and Variables

Last time in Computing for Everyone, we discussed the nature of computing at a high level--quickly following a detailed set of simple instructions (a program) to compute output from input. Today we'll start focusing on specific ways to construct the "sentences" that make up these instructions. We're going to start learning how to program. We begin with expressions in JavaScript.


Aside: Why JavaScript? All you need to get started with JavaScript is a text editor and a web browser. I want you to get hooked.


Here is some of the simplest JavaScript you can write:
function greet (visitor) {
  var greeting = "Hello, " + visitor + "!";
  return greeting;
}
Wait, we're missing a means of input and output! Let's hand-wave them into existence for the moment. Here's your input:
Type some text--this will become "visitor" above:
...and for your output:



What's going on here? The computer is executing the JavaScript function above named greet which takes a single input named visitor. Each line ending with a ; between the { and the } is a JavaScript statement, consisting of one or more JavaScript expressions. Linguistically, you can think of statements like sentences and expressions like phrases.

The concept of an expression in computing is pretty much the same as the concept of an expression in arithmetic. Expressions are either values or ways of combining nearby values to get a single value. 3 + 7 is an expression that evaluates to 10. 3 + 7 is also a valid JavaScript expression and evaluates to 10 in JavaScript as well as first grade. Between two numeric values, + is the "addition operator," which evaluates to the sum of the expressions to the left and to the right. For completeness/pedantry, we could note that 3 is an expression that evaluates to 3 and 7 is an expression that evaluates to 7.

Computers don't just manipulate numbers: they manipulate text. A textual value in a computer program is called a string. In JavaScript, string data is text surrounded by 'single' or "double" quotes. Strings can be combined ("concatenated") using the + operator thusly: "Hello, " + "Studmuffin" becomes "Hello, Studmuffin""3" + "7" evaluates to "37", the same answer you might get from a 6-year-old boy on a sugar high. Between two strings, + is interpreted as a "string concatenation operator," joining the left and right strings into a single string. From this you can see that "Hello, " + visitor + "!" evaluates to a sort of "mini Mad Libs" based on the value of the variable visitor.

Programming languages offer more variety in operators than addition and string concatenation, of course. This post isn't meant to give you an exhaustive list of expressions in JavaScript but to introduce the idea of expression evaluation in programming languages. You can (and should) find a more detailed list of JavaScript operators here.

Computer programs keep track of values through variables. You can think of variables like the memory function of your calculator from school. Simpler calculators would let you store a single value; more advanced calculators might let you store many different values.

There are two variables in our little script: visitor and greetingvisitor holds the value of the first text box at the moment the "here" button is clicked (right-click this page and "view source" if you're curious how). greeting is a variable created by our program to store what will become the program's output. The statement return greeting; indicates that the value stored in greeting is the output of our greet function (output which I have hooked up to our second text box). A JavaScript expression consisting only of a variable's name evaluates to the value stored in that variable. You store the result of an expression to a variable by using JavaScript's assignment operator, =. var greeting = "Hello, " + visitor + "!"; stores the result of evaluating the expression right of the = sign to the variable greeting.

Exercise:
Not Photoshopped.
Microsoft has sold software with some complicated names, e.g. Windows Vista Home Premium or Office 2010 Starter. David Finley has written a cheeky bit of JavaScript to generate new Microsoft product names that you can find here.

Visit the link and click "Get Product Name" a few times to see a few different randomly-generated fake (but plausible!) 2006-era Microsoft product names appear in bold next to "Get Product Name."


Right below the link is the script source (between the <script> and </script> tags). Try to read through the code and figure out how it's making the fake product names. Here's that list of JavaScript operators again. That will help with understanding the += operator. Line 23 of Finley's name generator is the HTML that creates a link that causes the instructions in the function getProductName() to be executed when clicked. This page should help clear up some confusion about what the pfx, prd, trm, typ, and sfx variables are and how the function named pick works. How many unique product names can the generator suggest?

Save a copy of the Microsoft Product Name Generator web page as HTML to your computer. By editing the script in a text editor (it starts around line 204--use your text editor's "find" feature to search for "var pfx"), saving changes, and refreshing the view of your local copy in your web browser, add some new product names. They can be whatever you want. Have fun! Remember it's easy to save a backup copy of your file before attempting any particularly ambitious changes.

Bonus:
In Monty Python and the Holy Grail, the ferocity of the French taunting took King Arthur completely by surprise. Based on the movie's two scenes of French taunting, see if you can work out a reusable structure for computing new French insults. Once you have that worked out, try to make a French Taunter by reusing ideas (and possibly code) from the Microsoft Product Name Generator.

Be quick about it, before I make your bottom leak through your underpants, you unfortunate former parent of a salty illegitimate baby seal!



Wednesday, July 31, 2013

Computing for Everyone 2: Sequential Execution

Last time we covered the centrality of experimentation in computing. The exercise reinforced something you've already experienced with computers: input and output. You may have made some changes that led to some bizarre behavior in the web browser, and that's okay: it's all part of experimenting. When you aren't surprised by the results any more, you've gone from experimenting to building. Building brings home the bacon; experimenting makes us better builders.

Anyway, now that we've started experimenting and have an intuitive feel for input and output, let's start exploring the space between input and output. Let's start talking about computing itself.

We begin with a trip into the world of wacky anthropomorphisms. Let's say you're a chess player. You know you need to be really smart to play chess well. On the road to becoming a better chess player, you'll learn things about the game that will help you teach other people to play chess well, strengthen your logical reasoning skills, and grow yourself as a competitor.

Now consider the following: You can buy software that will turn your computer into a machine that can destroy you at chess for $7 USD. This means the computer is quite brilliant and intelligent, right? Perhaps the computer could teach us how to play, and maybe installing Fritz has increased the computer's ability to think logically?

As it turns out, Fritz's real strength is its ability to select extremely strong chess moves for a given position. Your computer's ability to think logically is actually unchanged by installing Fritz. The features of Fritz that give amateur chess lessons aren't significantly affected by improvements to Fritz's ability to play the game.

Computers...aren't actually very smart. If your computer isn't very smart, how can $7 software make your computer defeat every human you know at chess?

For a little more than $7, your computer can take on the best human players in the world.
Computers aren't smart, but they are lightning-fast and uncompromisingly systematic. Fritz can select better chess moves than almost any human because its software lists instructions for how to list legal chess moves based on a position and how to test the viability of different moves by evaluating the "if-I-do-this-then-he'll-do-that" chain of reasoning. Modern computers running Fritz can follow these instructions--to the letter--at an incomprehensible rate of hundreds of millions (if not billions) of instructions per second.

This execution of instructions in the pursuit of an optimal or best-effort decision is the "computing" to which this series refers. Programming a computer is the act of writing instructions, in order, that will compute the desired output for any given input.

When your program runs, the computer executes each instruction in order as fast as it can. No more, no less. Ever. Other devices may assist users of a program with input and output (e.g. a digital camera will turn light hitting a sensor into a form your phone can understand as input for its camera app), but computing is about that space between the input and output, where fast execution of specific instructions allows us to make machines do what machines have never done in human history.

Exercise:

  1. Open a cookbook or browse for an enticing recipe online. Pick a recipe that has between 3 and 5 numbered steps. All this blogging is making me hungry--I could really go for some bruschetta right now. 
    Mmm...bruschetta....
  2. Imagine you have an untrained but literate, obedient, efficient, and self-disciplined child to help you prepare dinner. Your child will do exactly what he is told in the order instructed, but, unfortunately, nothing else. In addition to moving about the kitchen, your child can follow instructions like "if this is true, then take this action; otherwise, take this other action" and "go back to step 2." Now look at the recipe you selected. Is there anything missing from the recipe that glosses over some pretty major details if this is all your child was using to prepare the dish? Imagine how you would have to augment the recipe's instructions to avoid starvation. We'll call the result an "augmented recipe."
  3. Let's say you could teach your child 10 kitchen-specific skills (boiling, chopping, etc.). Which skills would simplify future augmented recipes for the largest variety of dishes?
  4. What are the inputs and outputs to your child?
Extra credit:
  • How could you instruct your child to pay your bills?
  • If you're mathematically inclined, how could you instruct a very patient child to apply Euler's method to trace out a curve specified by a differential equation?
Bonus:
In modern times, we have the bumper-sticker sized phrase "Garbage in, garbage out" (sometimes "GIGO") to express that computers deal with the data we input, not the data we would have liked to input. While this is sometimes frustrating, it is also logically inevitable after brief reflection on the nature of computing as we have discussed it.

Tuesday, July 30, 2013

Computing for Everyone 1: Experiment

Nothing will teach you about computing faster than self-directed experimentation. Experiment confidently. You will not break your computer.


I had a Game Genie growing up. Game Genie gave you three "wishes" to change how your NES games worked by entering 8-character codes from a guide book. Infinite lives, invulnerability, and infinite ammo were popular wishes. You could also skip levels or just make bizarre things happen.

Game Genie: Natural Video Game Enhancement
The Game Genie also came with a book that would tell you how you could tweak the codes they provided for different games to write your own. If there was a code for a game that would let your character start with 5 lives instead of 3, they had tables so you could tweak that code for 7 or 9 lives instead.

I used this table on Super Mario Bros. 3 to tweak a starting world code. SMB3 had 8 "worlds," and Game Genie would send you to any of them. I had to see what world 9 was like, and Game Genie showed me. It was a bizarre, but made a delightful experiment. Notably, my NES was never in danger of exploding.

You will not destroy your computer by experimenting: and low-risk, self-directed experimentation is how you will learn the fastest.

Exercise:
Save this blog post to your computer's hard drive as HTML. Open the .html file in a text editor (e.g. Notepad if you're a Windows user). What you see there should match what you see if you right-clicked this page and selected "View page source" in your web browser.

Open your locally saved copy of this .html file in your web browser: you can drag the file on top of your Chrome/Firefox/Internet Explorer icon or use File -> Open... in your web browser's menu to find your local copy. You'll know you have the right copy of this article open if your browser's address bar starts with "file://" instead of "http://" or "www.".

You are now looking at two views of this web page: one in your browser, and one in your text editor. You can now experiment by making and saving changes to the .html file and refreshing your browser (F5 or Ctrl+R in Windows, Cmd+R on a Mac). Some things to try:
  • Easy: Change some text, save, refresh your browser, look at what happens
  • Exploratory: Find the HTML image tags. HTML tags are the things surrounded by angle brackets (< and >). The image tags look something like '<img src="blah blah blah" />') in your text editor. Change one of the images to a picture of a cat by manipulating the "blah blah blah" part. Here's a nice picture you can use.
  • More exploration: Change other parts of the page, add effects, look at hyperlinks on the page by skimming through w3schools free HTML tutorials (formatting, links and images should be pretty instructive). As a bonus, w3schools has a "try it yourself" functionality to help you quickly experiment.
Extra credit:

Start exploring the files on your hard drive. Look at files related to your operating system: C:\WINDOWS if you're a PC user or /System if you're a Mac user. You definitely don't want to change these files directly without studying them first, but exploring these files can teach you a lot about working with your computer.



Bonus:

Monday, July 29, 2013

Computing for Everyone 0: Yes, Everyone!

Welcome to the Computing for Everyone series! Which everyone? Every everyone--that means you!

The ENIAC was the size of a blue whale and took up about as much space as a volleyball court.


We have arrived in a world of information at our fingertips and ubiquitous computing, and we're only just beginning to grasp what that means as a population. Think of the first electronic computers filling rooms and buildings. Now think of how so many of us have computers millions of times more powerful in our pockets.

My Galaxy SIII fits in my pocket, including the case


What is the nature of computing power? How are we using it? How could we be using it?

Here is a short list of what advances in computing have enabled as of 2013:

  • On-demand entertainment
  • New forms of entertainment
  • Almost-free publishing
  • Almost-free, almost-effortless research
  • Efficiently navigate unfamiliar cities
  • Almost-effortless group outing coordination
  • Convenient, fast, and secure financial and government transactions
  • An explosion of consumer choice
  • An unprecedented reach for businesses with niche markets
  • Ads that are actually for things you might want sometimes

Each of these advances is only possible because of the harnessing of computing power. This is what has been pre-packaged for mass consumption. But computing is a general power that can be adapted much more closely to our own needs.

The MacBook Air runs all day on battery power.


Computing isn't something you need to wait for others to do on your behalf; computing is something you can personally use to save time, reduce risks, spend less mental energy on trivia, and do things which were not possible or feasible before computing power became cheap and ubiquitous.

Enough warm-up. Enjoy the series.

Exercise:
Each bullet point above describes a computing-enabled change in terms of its positive effects. What are the new challenges introduced by each change? 

Example: "On-demand entertainment means there's no pressure to schedule leisure time around TV broadcasting schedules, but it also means that there is less social bonding on the basis of new episodes of popular TV shows. This presents the challenge of bonding with acquaintances through other means."

Extra credit:
What's a repetitive part of your life you could automate away to save time? What are some things you would do or do more often if you could find a way to speed up smaller parts of getting these things done?

Monday, July 1, 2013

Gratitude the easy way

Gratitude is the key to both goodness and happiness. So often, though, we don't know what we've got until it's gone, or we take what we have for granted.

It's a trick in life to know what you've got when you have it. One way to get something and no you've got it? Get an "after body." You'll never take your physique for granted, you'll know the work it took to make it, and you'll never want to go back.

Wednesday, June 5, 2013

Tactics first

Teach tactics first when starting with improving someone's chess.

Tactics are the beginning, middle and end.



Tactics are how you achieve a vision that you have for the board.



The most beautiful strategic vision must be rejected if it is tactically unsound.



You must assume a perfect opponent. You cannot play a move hoping he does not see the correct response.

Teach tactics first when improving someone's life.
Tactics are relevant at the beginning, middle and end.
Tactics are how you achieve the vision for your life.
You must reject even the loftiest goals if they are tactically unsound.
You must expect the world to continue functioning as it does presently. You cannot include a lottery win in your plans.

Monday, June 3, 2013

Post-boredom society

Seattle is a post-boredom world. 

It's a strange world. This is a greater challenge than TV. This is custom-fit entertainment. This is your personally tailored mix of entertainment, knowledge, news and attention. This is an infinity of distractions to keep you just above the threshold of boredom but far, far below any kind of fulfillment.

I call my smart phone my "portable contentment device." In my adult life, I've never been frustrated while waiting in line or at the airport. I haven't felt genuine boredom in a long time. I also haven't turned a stranger into a friend while waiting in line. I also don't spend nearly as much time as I once did deep in thought (not before I started regularly blogging, anyway). I don't think I'm alone in any of this.

Now, more than ever, it's important to develop hobbies, interests and friends to get satisfaction out of the way you spend your time. Being passive about your life will lead to it being lived for you. Cook a meal. Write. Read a classic. Make a video. Reflect. Take a time-out from your silicon brain. Best of all: go camping. Force yourself to get bored, and see what happens.


Friday, May 31, 2013

Make cool stuff happen

The bad news about adulthood is that good things don't just happen by themselves. The natural good news follow-up is that you can make great things happen for yourself and for others pretty much whenever you want.

You're the boss of you, so you have some choices to make, if you realize you have them:
  • You can stay out late or you can make the most of your daylight.
  • You can dress for your own convenience or to class up the joint.
  • You can stay at home bored or you can plan things for you and your friends.
  • You can coast or you can thrive.
  • You can use your freedom to atrophy or you can push yourself to greater heights.

Raise the bar.
Be the change you want to see in your life.
You don't find yourself. You make yourself.


Thursday, May 30, 2013

The most hated object in the universe

Stupid cube.

The Rubik's Cube fiendishly pits our desire for completeness against our aversion to experiencing loss against a backdrop of a puzzle where progress is often visually counterintuitive.

Wednesday, May 29, 2013

Perfect practice makes perfect

To get good, you must practice. This takes work.

If you practice without any theory, you risk developing bad habits. On the other hand, you don't want to get so distracted by theory that you cut into practice time.

So what is the right amount of theory? Enough to avoid bad habits and increase the effectiveness of your practice. All else is noise.

Go practice.

Tuesday, May 28, 2013

Speaking to software

Users of software! Who among you doesn't want this feeling?



A lot of effort goes into making software as simple as possible to use. Classics like Don't Make Me Think! catalog ways to make user interfaces intuitive. On the whole, this is a good thing. Competition in our choice of software is driving everything to be as simple as possible, and no simpler. But software can be more, much more. And not later: right now. The catch? You have to work for it. You have to learn your software's language.

Software is built of thoughts. What you see on a screen are images and words. What you hear are sounds: alerts, sometimes voices. What you feel are vibrations. These are all approximations of the logical world in which your software lives. You interact with this world by typing, clicking, tapping and speaking. Most of our typing, clicking, tapping and speaking is directed against objects presented to us by the user interface: pre-canned and pre-suggested actions. The user interface is a guide to the software's world of thoughts, helping you navigate your way to the solutions you seek.

What if you could interact with your software without a guide? What if you could describe your intent without having to navigate pre-trod logical paths? What if you could construct entire sentences for your software to interpret, beyond the limited vocabulary of "this thing" and "that action"? What if you could bypass the interpreter between your carbon and silicon brain and tell your computer what to do in a language it already speaks instead of trying to hunt for the way to prod the guide to suggest the action you already knew you wanted in the first place?

Think of Plato's Cave. The UI is just the shadows against the wall. Rather than limiting yourself to grasping at these shadows, with a lot of software there is an underlying language you can use to give direct orders. Think "keyboard shortcuts times one hundred."


Just past the covers, a lot of software that you already use has such languages. Excel has formulas. Outlook has rules. All of office has macro support. Your operating system has a command line and a shell you can use to help automate common tasks. If you build web pages, getting to know HTML, CSS and maybe even a little JavaScript will give you much more freedom than what you can experience from within a graphical editor.


Some software is built to be used primarily through its language. If you edit a lot of text for work, you might be familiar with the great vi or emacs. For the price of learning a small grammar and simple vocabulary for text manipulation, you can multiply your productivity at the keyboard.

But this is all on you. Nobody is going to make you think. A world of riches and reclaimed productivity is waiting for you if you can speak to the software you use day-to-day in its native language, not just through a graphical interpreter. Learning the language of a piece of software has the same thrills as learning a foreign language: pride in being able to guide yourself around a new country and the fun of figuring out how to most effectively curse.

This is why software developers should study foreign languages. Studying languages is the study of expressing thoughts, and we are a business of constructing goods made of thoughts. The best software and services enable us to do more than we could by translating our intent into action. The more we can express, the more efficient this communication becomes. In a way, we're all cyborgs now. We can either passively consume via our silicon brains, or we can use them to bend the world to our will.

Monday, May 27, 2013

Focus

Focusing is hard. When talking about focusing on a job or on a lecture, we have this image of paying as much attention as we can all the way through. We're doing it wrong. Tae kwon do does it a little differently.

In a tae kwon do strike, focus is the point in space and time at which all our energy is directed. Only in the last few inches of a strike do the muscles tense, and in those last few inches you put forth everything you have. The muscles immediately relax after impact.

Focus enables you to throw faster strikes, more powerful strikes, and more strikes period. Let's examine a uniformly tense strike and a uniformly loose strike.

Tense limbs arrive at the target after relaxed limbs (try it on a soft, non-living target). It is more difficult to adjust a tensed limb's trajectory. Maintaining a tense limb while in-transit to the target or after impact causes excess fatigue.

Loose limbs collapse upon impact rather than causing the target to collapse; otherwise, they are superior in all stages of a strike. We conclude that focus is actually not about capturing the value of concentrated energy but about capturing the value of relaxation. The milliseconds of focus in a strike are only possible because of the relaxation before and after.

We can relax and tense our minds in the same way as our bodies. Chronic stress and worrying lead to the same fatigue and inflexibility mentally as tense strikes lead to physically. Avoiding or ignoring important problems rather than solving them is analogous to the collapsing of a loose limb at the moment of impact.

Spiritually, holding grudges against the penitent fatigues and fixates the soul. Dogmatically clinging to a nonjudgmental stance in the face of egregious immorality is like a loose limb collapsing on impact.

The applications of focus are endless. The alternating relaxing and tensing in a strike is tae kwon do's staccato music.1 Writing's similar rhythm is a rhythm of brain-dumping and editing. Programming is a rhythm of implementing and refactoring. Try replacing intense, temporally diffuse concentration at work, school and play with focus. Find the music in what you do. Get the most out of your body, mind, and soul.





1 Tae kwon do's martial nature does not negate its musical qualities.

Thursday, May 23, 2013

Digital etiquette: Accept: R, Decline: r

Reply-all when accepting a group event invitation sent out via email or Facebook. Reply only to the organizer when declining the invitation.

Make it easy to adhere to this convention when designing an event or calendar system.

Stay classy.

Wednesday, May 22, 2013

Test harnesses for black box tests vs. white box tests

Most unit testing test harnesses are for white-box testing. They're designed to stay out of the way and allow the programmer to write quick checks for a unit under development. If any unit test fails, the build should break and the build should fail.

When managing automation for black-box test cases against a system, the rules are different. In rare instances the tests will be ready ahead of a significant amount of feature work. Black box integration tests can rarely be complete before the functionality under test is nearly code complete, so authors of automation for black-box tests control the risks of holding up feature completeness by writing test skeletons which will fail until the test can be complete early on in feature development. Since these tests always fail, black-box test harnesses need a means to separate tests which are under development from tests which are complete.

The same goes for tests which have caught bugs: to reduce noise in a continuous deployment pipeline, these tests need to be disabled, but there is great value in running these tests in a separate workflow so that the fix can be detected by the automation.

White-box unit test needs/expectations:
  • Fast individual tests
  • Mocking of dependencies is always okay
  • Event injection can speed up tests
  • Test suites are built up gradually as the individual units are developed
  • Tests often fail for obvious reasons by default
  • There is no environment to gather details around for repro purposes; just re-run the tests!
Black-box integration test needs:
  • Mocking of dependencies defeats the purpose of integration tests
  • Asynchronous waiting for dependent services and normal system behavior is a fact of life
  • Tests will often depend on one another in order to run suites in a reasonable amount of time
  • Tests routinely fail for reasons different from what is explicitly under test
  • Capturing environment data for a repro is necessary
  • Tests are defined in combinatorial clumps rather than gradually, as new functionality is built up. Mutators, Pairwise testing, Model-based testing, and any approaches based on filling in code coverage gaps generate large numbers of test procedures which are most conveniently managed as a group.

Tuesday, May 21, 2013

Fun and Mastery 2: Morale events that actually boost morale

Does your place of work have "morale events"? Are they successful at increasing morale? Would you like them to be?

Here are the steps of running a typical morale event:

  1. Spend money
  2. Feed and booze employees
  3. Hope that it worked
Regular morale events of this sort rarely maintain their potency with employees over the long run. Regular exposure to such rituals tends to jade or entitle employees. Rather than throwing more effort into step 3 above, let's see if our recent lesson on fun can help.

Individually, we experience fun when we try low-stakes tests of our skills; can organizations do the same thing at a group level? Consider activities related to the practice of your organization and see if you can make available small challenges around that. Studying how kids play, these challenges should be:

  • Qualitatively different from business-as-usual
  • Experimental
  • Voluntary
  • Low-stakes
  • A natural creative extension of the organization's ability
In one of my most memorable team meetings, the high-level dev manager running the show (Tom) said he was off to grab a guest speaker. A moment after he left the room, an attendee's (Dave's) phone rang. Tom told Dave to look under his laptop. The note under the laptop told us that Tom had gone to a secret location with a bunch of ice cream bars and we would have to decipher a series of clues involving tiny programming challenges and some crypto libraries in order to find him before the ice cream melted. The guest speaker, was, of course, a ruse. 

For the cost of some ice cream and a little bit of creativity, we got in some bonus programming practice, had some fun exercising their brains and working together, and deepened our pride for being on such a team. Neither jadedness nor entitlement accompanied this morale event. This experience is the target of every teambuilding exercise and every morale event. This is the mark which is so often missed.

If you're planning a morale event, you're still allowed and encouraged to spend money to feed and booze employees, but a small bonus challenge for your team can transform your check-box event into a fun and enduring milestone on your team's path to mastery.

Monday, May 20, 2013

Fun and Mastery

In college I started having a hard time thinking about fun in the abstract. Unsure of how to fill my free time, I started wondering if I had lost some capacity for fun. This bothered me for about eight years.

Last year a friend recommended the short-yet-transformative Mastery by George Leonard. This required reading for anyone who wants to be excellent at anything has some unexpected insights into the nature of fun.

Mastery
 points out that young children get very good at a variety of tasks very quickly--stuff we take for granted, like balancing and speaking. What do children do? They play. Playing is fun. Children will walk on curbs when out walking and play word games when they're bored and away from media sources. They're practicing skills by going slightly outside of what they normally do. They're engaging in low-stakes challenges of their current skills and loving it. This is fun.

Of course, kids don't realize this is what they're doing. They're just thinking, "Hey, this is fun." Then we grow up, spend tons of time doing homework and meeting obligations on our calendar, checking off achievements, and we can forget about going taking those tiny, low-stakes experiments against our skills.

So there you have it: a formula for rediscovering fun. Take something you're doing (anything: your job, your workout, your hobbies, social situations) and test yourself with little low-stakes challenges. Do it backwards. Do it faster. Do it on one foot. Do it with a new tool. Do it in fewer actions. It's fun!

Friday, May 17, 2013

Mirror Image: Anorexia is dumb

It's also a disease, it's also a problem, it's also something I'm not qualified to say much about since it's not part of my life experience or training.

My focus in these posts is to get guys to wake up and stop refusing to see a problem that is sabotaging them in more areas of life than they realize: excess flab. It took me a long time to get to the point where I finally realized my situation and said never again.

Let's take a time-out and focus on what I'm trying to say, because I think it would be very easy to take some things I write when talking about weight issues the wrong way. It's a delicate topic and most people who deal with it have some baggage around the issue.

I'm not saying you're worthless if you're fat.
I'm not saying you're lazy if you're fat.
I'm not saying you need to do what I did.

I'm saying your looks matter because so many first impressions are so firm and so involuntary.
I'm saying prioritizing healthy weight loss will bring with it more benefits than you realize.
I'm saying--now, for the first time--that I don't wish for anyone to get to the point where I was when I started my weight loss. I don't expect others to be motivated the way I was motivated, and I don't wish that motivation on anyone.

If you are struggling with anorexia, please get help. If your friends and family have expressed concern, please let them help. There is such a thing as too much weight loss. I feel dumb writing that: it's so obvious.

Anyway, we're full of exhortations against anorexia in the West. Given the relative rates of anorexia and obesity in the country, we pay way too much attention to anorexia vs. obesity. People think of anorexics as at one point skinny girls, and that tugs at the heart strings in ways that the image of a fat guy simply doesn't. So please, don't get all anorexic on us. But don't let that stop you from waking up.

Wednesday, May 15, 2013

Mirror Image: Looks matter

I might be alone in this, but the main message I got from TV growing up was that looks don't matter. I internalized a lot of hand-wringing about how beauty is in the eye of the beholder and how our image of what is attractive is unreasonable. I took these as excuses to ignore the development of my own looks. This was stupid.

Your looks are the first part of your first impression. Just as a first impression take can take a lot of future interactions to change, looks can drastically affect the merit of a first impression. "A stitch in time saves nine."

Losing 50 pounds in four months showed me the contrast. Put on your best face. Get your best body. Lead your best life.

Tuesday, May 14, 2013

The master must be a hobbyist.

Practice is the key to mastery (read the book!). Part of practice is accepting long plateaus. Progress is bursty and fueled by time spent plateaued.

When working towards mastery in a craft that is part of your profession, customer needs will dictate the lion's share of your craft's development. 

To subordinate customer needs to your craft is to abandon the path of mastery in your profession. 
To surrender all practice outside customer needs is to abandon the practice of your craft.

This is why the professional master must also be a hobbyist. Only as a hobbyist can you practice your craft for its own sake. Only as a hobbyist can you playfully experiment within your practice. Putting aside your craft as a hobby means your are mastering your profession but not your craft.

And that's why I need to go code some tank AIs now!