Tuesday, October 29, 2013

Functional Practice: Euler Problem #1

I've learned about Euler problems quite a while back. If you're not familiar with them, you can check out Project Euler.

These are very mathematically focused problems, and I was thinking about using them as practice problems for C#. Many people have done that; here's one example: http://www.mathblog.dk/project-euler-solutions/.

When I was looking at the problems, though, I always felt that my C# solutions would be a bit of a mess -- lots of if/else, while, switch, and so on. The solution is not functional or elegant (which always makes me think of this song).

But these seem like a great place to start using functional programming. Since I'm learning functional programming with Haskell, that's the language I'll use for my solutions.

Now, I'm not going to blog about all of the Euler problems (there are a lot of solutions out there). I'm just going to go over my thinking to solve the first problem. This will show how learning about functional programming will let you start to think a bit differently if you come from the OO world.

Euler Problem #1
Here's the first problem:
If we list all the natural numbers below 10 that are multiples of 3 or 5, we get 3, 5, 6 and 9. The sum of these multiples is 23. Find the sum of all the multiples of 3 or 5 below 1000.
This doesn't sound that hard. We'll start by trying to replicate the sample: the natural numbers below 10.

Thinking Functionally
What I found myself doing immediately was breaking this problem down into different parts. We need the natural numbers below a certain value. We need to find the ones that are multiples of 3. We need to find the ones that are multiples of 5. We need to sum things up.

This is a great place to use a list in Haskell.

First, let's get a list of all the natural numbers less than 10. We'll use a list comprehension with a range:
[x | x <- [1..9]]
And here's the output
That's a good start.  Now we need to filter things a bit. Let's add the modulo function (mod) to get the values evenly divisible by 3:
[x | x <- [1..9], mod x 3 == 0]
 The "mod" function takes 2 parameters. This may look a little strange, so we'll change this to use infix notation by using a backtick around the function name:
[x | x <- [1..9], x `mod` 3 == 0]
This seems a little less strange. And here's the output:
And since we want multiples of 5 along with multiples of 3, we can "or" these together with "||". Here's how that looks:
[x | x <- [1..9], x `mod` 3 == 0 || x `mod` 5 == 0]
And here's the output:
Success! This matches the list from the sample. Now we just have to sum these numbers. Fortunately, we can just pass a list to the "sum" function.
sum [x | x <- [1..9], x `mod` 3 == 0 || x `mod` 5 == 0]
And the output:
This matches the sample case. Now we just need to swap out the "below 10" for "below 1000":
sum [x | x <- [1..999], x `mod` 3 == 0 || x `mod` 5 == 0]
And the answer:
Note: I've verified this is correct by looking at the answer to Euler Problem #1.

Making a Reusable Function
The last thing that I want to do is create a reusable function. (I'm not really sure what use I would have for this, but anyway...) So, let's parameterize this with the "below this number" value (ignore any line breaks you might see).
euler1 belowThis = sum [x | x <- [1..(belowThis-1)], x `mod` 3 == 0 || x `mod` 5 == 0]
Basically, we created a named function "euler1" with a parameter for our "belowThis" number. Since ranges are inclusive, we subtract one from the value before creating our original list.

Now we can use this function with the sample:
euler1 10
Or with the target value:
euler1 1000
That's pretty cool.

To create this function, we just started with the inside and worked our way out. And this is a big difference between thinking functionally and thinking procedurally. If I were to try this with C#, I would probably just "brute force" it. You can see an example of that here: http://www.mathblog.dk/project-euler-problem-1/.

But instead, we have something functional and elegant. And also a good way to stretch a bit to learn functional programming. And I'm already starting to see how I can use these techniques to make my everyday programming (in C#) much better.

I'll leave the rest of the Euler Problems as an exercise for the reader.

Happy Coding!

Monday, October 28, 2013

Shameless Promotion

Three of my Pluralsight courses are currently in the Top 100 as of 10/28/2013 (subject to change):

(I guess there's not much love for the BackgroundWorker Component.) You can see all of my courses in one spot on my author page.

I have more courses coming. If you have topics you'd like to see me cover, feel free to leave a comment. As mentioned before, the topics I select are based on several factors including (1) whether I know anything about the topic (this one is kind of important) and (2) whether Pluralsight already has a course covering the topic.

Pluralsight has over 1,000 courses with a ton of great content. Check the Course Library for some really good resources.

Happy Coding!

Tuesday, October 22, 2013

Unblocking Downloaded Visual Studio Projects

As a developer, I download sample projects quite frequently. Usually, when opening these projects, Visual Studio will give the following warning:

Now, we can simply click the "OK" button here. But there may be other problems. This is especially true if the solution includes compiled DLLs. These files may be blocked by Windows since they were downloaded from the internet.

Unblocking Files
The easiest solution is to unblock the files before opening the solution in Visual Studio. Here are the steps:
  1. Locate the original ZIP file that you downloaded from the internet.
  2. Right-click on the ZIP file and choose "Properties".
  3. At the bottom, you may see a "Security" section that says "This file came from another computer and might be blocked to help protect this computer."

  4. Click the "Unblock" button.
  5. Unzip the files and open the solution in Visual Studio.
  6. Before opening any specific project, go to the "Build" menu item and select "Rebuild Solution".
This usually takes care of the problems. (And, of course, only do this with files that come from a trustworthy source.)

Happy Coding!

Monday, October 21, 2013

New Pluralsight Course: Dependency Injection On-Ramp

My latest course is now available on Pluralsight: Dependency Injection On-Ramp.

Dependency Injection On-Ramp
What is Dependency Injection? The answers to the question seem to cause more confusion than help. This course will get us started on the road to understanding. We'll take an example-based approach to see the problems caused by tightly-coupled code. We'll add Dependency Injection to trade that tight-coupling for loose-coupling. And that loose-coupling makes our applications much easier to extend, maintain, and test. Finally, we'll see how Dependency Injection Containers can provide benefits that would be difficult to implement ourselves. This just scratches the surface. Once we're done, we'll be ready to start our journey on the Dependency Injection superhighway.
I've really enjoyed presenting on Dependency Injection over the last year -- I've given my live presentation 12 times since October 2012.

One of the reasons I really like this topic is because I've found it extremely useful in my own development. It took me a while to get the hang of it and to see the usefulness. But once it clicked (the "a-ha" moment (no, not that "a-ha" moment (but that's a good one, too (I miss the '80s)))), it's hard to imagine building complex applications any other way.

My goal is to give a short-cut to that "a-ha" moment. We can't cover everything we need to know about Dependency Injection in such a short time, but we can get a good understanding of the basic concepts and, more importantly, see real code that shows why we may want to use it in our own applications.

This may be my best course yet. Check it out and let me know what you think.

Happy Coding!

Saturday, October 19, 2013

A Foo Bar Example I Actually Like

I really, really dislike "foo bar" examples. You can read about my worst foo bar experience here: Session Spotlight: IEnumerable, ISaveable, IDontGetIt.

There's 2 primary reason for this. First, I like real-world examples -- something that I can hold on to. "Foo" doesn't mean anything (that's why it's used), so I have a difficult time relating. The second reason is that "foo bar" makes me think of FUBAR (which may actually be appropriate).

Higher Order Functions
As recently noted, I'm learning functional programming with Haskell. It is a different way of thinking, and I'm starting to get the hang of it. I'm reading about higher order functions right now.

A higher order function is a function that takes another function as a parameter. To relate this to the C# world, this is similar to passing a predicate/delegate/lambda as a parameter to a method (like a LINQ method such as "Where"). But this seems more natural in a functional language.

Here's the function that we need: zipWith':

The scary thing is that I actually understand this. It uses a combination of a higher order function, recursion, pattern matching, and list heads/tails.

Rather than explain this line by line, let's look at an example of using this method:

This shows a call to zipWith that has the "+" function as the first parameter, then we have 2 lists of integers. This method will apply the function to the items of each list. So, it will add ("+") the first item of the first list ("1") to the first item of the second list ("4"). Then it will add the second items of each list, and so on.

Here's the output:

This is a list consisting of 1+4, 2+5, and 3+6. The 7 at the end of the second list is ignored since there is no corresponding item in the first list.

Foo Bar Baz
So, you've made it this far. Here's the foo bar example:

This has a different function: ++. This will concatenate 2 lists together. Since strings are lists of characters, this will concatenate the strings from the first list with the strings from the second list.

Here's the output:

The sin of using a foo bar example has been forgiven.

Happy Coding!

Thursday, October 17, 2013

How Do I Change Someone Else's Code?

I had an interesting question come up at my Clean Code session at Silicon Valley Code Camp:
How do I change someone else's code?
This question came up as we were talking about refactoring code to improve the readability. And the question was not coming from the technical standpoint, it was coming from the interpersonal standpoint. So, the question could really be stated several different ways:
How do I deal with a developer who is possessive about the changes made to "his" (or "her") code?
How do I tell a developer that his/her code could be more readable?
Let's start with the first question.

Code Ownership
If people are possessive of "their" code in the codebase, this is a sign of a larger issue.

Note: I'm approaching this from a standpoint of developers on a team working for a company just so we have an idea of the environment. But this applies to other types of teams as well.

Our focus really should be on the business -- how the applications we build move the business forward. And the most productive environments I've worked in have this mindset.

In the agile world (and I'm reluctant to use that word since a lot of people who are "Agile" really aren't), everyone on the team is responsible for the code. If someone sees a problem in an application, he is empowered to fix it (or alert someone about it if he is not capable of fixing it himself) -- and arguably, he would be irresponsible to not do anything about it.

So, if you find yourself in a situation where you can't touch a certain module because "that's Jim's code", it might be time to bring in someone to help with the dynamics of the team.

We don't always have control over the team, but we do have control over ourselves. If you find that you're offended that someone changed "your" code, then it's time to take a step back and re-evaluate your own attitude.

Controlling the Ego
Developers are known for having large egos. This really isn't surprising because at its heart, development is more of a creative process than a technical process. The last thing that an artist wants to hear is that you think his painting is ugly. Developers generally react the same way.

But we need to take a step back and look at what we're really doing: we are building tools that propel a business forward. And we don't even own the code we write (from a legal standpoint), the company owns it. This means that the company can do whatever it wants with the code, including rewriting it, breaking it, using it incorrectly, or even never using it at all. So, we cannot get personally attached to any particular function that we create.

I won't say that this is an easy thing to do as a developer. I put a lot of thought and effort into the software that I write. When I see that it is not being used or being used improperly, it really annoys me. But then I take a step back. In my experience, there is very little benefit that comes out getting worked up over these things. I voice my opinion and then let it go (sometimes more successfully than others).

Learn from Other Developers
The same holds true if another developer makes changes to code that you originally wrote. Instead of having a kneejerk reaction, understand that the other developer is not calling your painting ugly. He (hopefully) has the same goal that we all do, to propel the business forward.

So, stop and look at the changes that were made. If you think they are good, learn from them. If you think they are bad, talk to the other developer. Communication goes a very long way in the development world. We don't always approach problems the same way (actually, we probably never approach problems the same way). It's good to understand what someone else is thinking. I've used this several times as a learning experience. And sometimes by working together, we come up with something that neither one would have come up with separately.

It's All in the Approach
So, now let's deal with the second question: How do I tell a developer that his/her code could be more readable?

A great way to approach this is to ask the developer to explain the code. "Hey, Jim, I'm having a little trouble understanding this block of code. Could you help me out?"

If he asks why you're looking at "his" code, tell him that you're just trying to get a better understanding of the system overall.

This may or may not work. It all depends on the other developer. We don't have any control over how other developers react. Just remember to keep your own reactions in check.

If he does explain the code, then you can offer some suggestions to make it more clear to someone just walking up to the code for the first time. Hopefully, you'll be able to work together on making the code better.

Sometimes We're Stuck
If we are part of a dysfunctional development team, sometimes there's nothing we can directly do about it.

But there is a big difference between being *on* a dysfunctional team and being *part of* a dysfunctional team. It is very easy to be overwhelmed by the things going on around you and let them affect you. I've had that experience. I let the problems of a team I was working with get the better of me, and it affected my attitude. I was lucky enough to have someone point this out to me, so I was able to readjust how I was reacting to things.

Attitude is Infectious
Just like a negative attitude is infectious, so is a positive attitude. We can't control others, but we can control ourselves. I've found that if I take a certain attitude toward development (focusing on the business, checking my ego, constant learning), it rubs off on other members of the team.

We *can* change the attitudes on our team. It starts with us re-evaluating our own attitudes. From there, we set a good example, pump out some excellent code, and focus on the goal. Others will want to follow. (And if that doesn't work, polish up the resume. If this is your approach to development, I want to work with you.)

Happy Coding!

Wednesday, October 16, 2013

Functional Programming with Haskell

So, I've been dancing around learning a functional language for a while. And although most of the people I know would like me to learn F#, I've decided to start with Haskell (sorry, Mathias).

So, I started reading Learn You a Haskell for Great Good! by Miran Lipovańća (Amazon link).

Why Functional Programming?
I've heard from several folks that it's a really good idea to try to learn one new programming language a year. The goal isn't to make the language our "main" language but just to become competent with it and understand how it works.

A further recommendation is to learn a language that uses a different paradigm. For example, if we are C# developers (an imperative OO language), then learning Java (another imperative OO language) won't do us that much good. But if we pick up a functional language, it will force us to start thinking about problems differently.

And the programming techniques that we learn can help us in our "main" language. C# started as an OO language, but it's evolved into an all-purpose language and has many functional elements (delegates, lambdas, LINQ, etc.). When learning these functional elements, we don't usually approach them from a purely functional standpoint.

My hope is that by learning a purely functional language, I'll have a better grasp on the idioms and techniques of functional programming, and that will make me more effective as a C# developer.

Why Haskell?
Why did I choose Haskell over F#? Well, there are 2 reasons.

First, I already had the Haskell book. It's been in my heap for a long time (according to Amazon, I've had this book since April 2011).

Second, I wanted to break away from the .NET framework. I am concerned that if I started with F#, I would get wrapped up in things like "What IL does this generate?" and "How does this F# library integrate with a C# application?" As a first step, I want to focus on the functional paradigms.

I fully expect that I will take these learnings into the F# world. And after reading just a couple of chapters, I've picked up a few good things. I got a good head start at the Silicon Valley Code Camp by attending Mathias Brandewinder's "F# for the C# Developer" (Code Camp link). And the concepts of tuples and implicit typing now make a lot of sense.

More to Come
Stay tuned for more functional stuff. I'm already starting to see the coolness around immutability and "no side effects." And the idea that a function *must* return something seems strange to a C# developer at first, but it makes total sense when functions are the primary objects that we're dealing with. I'm looking forward to diving deeper into the concepts of composing functions. And near the end of the book, there are chapters on monoids and monads. That should be interesting since I have no idea what those are.

I'm looking forward to stretching the way that I think about programming.

Happy Coding!

Tuesday, October 8, 2013

Fixed Mindset vs. Agile Mindset

I was impacted pretty sharply by a podcast that I listened to a couple weeks ago: Hanselminutes #389 - The Agile Mindset with Linda Rising. If you haven't heard this conversation, you should go listen to it right now.

Based on this, I went out and watched a keynote given by Linda Rising (in the links of the podcast): The Power of the Agile Mindset.

This got me thinking about my attitudes toward others and toward myself.

The Short Version
The short version (if you don't want to listen to these talks) is that there are two basic mindsets: a fixed mindset and a growth (or agile) mindset.

The fixed mindset says that we have a specific potential that we can live up to. If we succeed at something, it's because we are smart or are meeting our potential. If we fail at something, maybe we just aren't smart enough. But the general idea is that everyone can be grouped by what he/she can be good at and not good at. Someone can learn something new, but there's a ceiling at which he/she will stop getting better. One very telling result is that people with a fixed mindset will often meet failure with helplessness -- "I failed; I guess I'm just not good enough."

The growth/agile mindset says that we are all capable of constantly learning. If we succeed at something, it's because we worked at it. If we fail at something, that's okay. We can use it as a learning experience and do better next time. With this mindset, we continually improve at whatever we work at.

Now there are limits. Not everyone can be an Einstein or a Bach or a Michael Jordan. But we can learn to be competent (and possibly excel) at whatever we set our minds to. And there isn't a "hard cap" on what we can learn. We can keep getting better even if it's just in small steps.

This is a really bad summary, so go and click on the links at the top of the article to find out from the expert.

Mindset in Business
In the Hanselmintues podcast, there was a discussion of how certain companies have the fixed mindset and others have the agile mindset. I've seen this first-hand (although I never thought about it this way).

I was at a company that had two distinct teams and two distinct approaches to software development. I was (thankfully) on the team with the agile mindset. We were constantly learning from our previous projects, looking for things that we could do better, and helping each other grow. From the way that we treated each other, it was obvious that our team embraced the agile mindset. We saw potential growth in each one of our team members.

The other team had a fixed mindset. This team was always looking for the tool or process that would make their development idiot-proof. This really bothered me. If I was in charge of that team, I would have focused on how to make the developers better -- to find out where the gaps were and bring everyone up a level. But it seemed to me (as an outside observer) that the management team had given up on improving the developers. The mindset was that the developers were "only so good" -- they had reached their potential as developers.

I have always treated other developers with an agile mindset. That's not really surprising since I spend so much time helping other developers get better. If I didn't believe this, then I wouldn't spend so much time speaking and writing and teaching.

Mindset in Myself
I did find something surprising about myself though. Even though I treat others with the agile mindset (the potential to continuously get better), I treat myself with the fixed mindset.

I've never really struggled with something. When I was growing up, I was told that I was smart. I did well in school. I did well in sports. I did put a lot of work in. For example, I practiced basketball a lot when I was in high school. But I never struggled with it. I was never overcoming challenges, I was simply putting in time.

There are things that I consider myself to be "not good at." These are things that I have not put much effort into. Music is one of these things. I play the keyboard and guitar very basically. I don't play a lot. And I considered myself to "not be a natural" when it comes to music. Maybe I was missing a trait that would allow me to play really well. And I never really put in a lot of time to learn.

So, I've managed to put limits on myself in some areas but not others. For example, in development, I'm constantly learning, usually through books (that's how I learn best). When I'm speaking, I elicit feedback from the people who attend, and I try to incorporate their suggestions. When I completely blow a presentation (which has happened a couple of times), I try to figure out what I did wrong so that it doesn't happen again. I think that this makes me a better presenter as time goes on.

The Rubik's Cube
I grew up in the era of the Rubik's Cube. If you've never seen one, here you go:

The goal is to get the each side to be a solid color (at the same time). I was never good at this. There were 2 ways that I could solve it: (1) follow step-by-step directions, or (2) take it apart. When I followed the directions, I wasn't really learning the concepts behind the cube, just following the numbers.

Since then, I've been content to think "my brain doesn't work that way." I never thought that I could learn to solve it.

This came up a few weeks back. I was standing around talking with a group of devs after a user group. Someone picked up a Rubik's Cube on a desk and proceeded to solve it in a few minutes. I admitted that I'm not capable (and I don't think I ever would be).

Guitar Hero
So, let's go the other way. Many years back, I saw Guitar Hero (the video game) and decided that it looked like fun. I even went out and bought a PlayStation 2 so I could play it.

The first time I tried to play, I was awful. The beginner level only uses 3 buttons (out of 5) and goes very slowly. But still, I was awful. After playing for a while, I simply turned if off and thought "well, that was a waste of money."

But for some reason I went back to it. And over the years I got really good (which isn't that hard if you have free time). I got to the point where I could not play the beginner level anymore because it went too slowly. And I continued to play through many more iterations of the game (I think I have almost all of them). And when I started a new version, I would start on the "Hard" level.

I even used this to my advantage. The first time I spoke publicly was at the So Cal Code Camp in Orange County in January 2010. I was nervous as heck, and I wasn't sure that I could actually go through with the presentations that I had planned. There was a speaker dinner the night before at Dave and Buster's, and I ended up at the Guitar Hero game there. I played a bit, did very well, and other people commented on it. There was even a teenager who asked to play head-to-head with me. That boosted my confidence -- I could perform well in public. And I was successful in my presentations the next day.

My Challenge
Many times I find myself getting frustrated at things or thinking "I'm not good enough." There's no logical reason for this based on my past performance, but that fixed mindset keeps creeping back in.

So, I'm challenging myself. I will learn how to solve a Rubik's Cube. I know that doesn't sound like a very big challenge, but it really is. In order to solve the cube consistently, I will need to break out of the mindset that says "my brain doesn't work that way."

So, the next time you see me at an event, ask me how I'm doing with that. Hopefully, I'll pull a cube out of my pocket and solve it right in front of you.

The fixed mindset vs. the agile mindset is not simply about how we treat other people. It's also about how we treat ourselves. Keep learning and keep growing.

Happy Coding!

Book Review: Designing with the Mind in Mind

User interaction design is one of those things that I'm fairly decent at, but I don't excel at it (yet). In that vein, I've read several design books over the last few years including Don't Make Me Think (Steve Krug), Universal Principles of Design (Lidwell, Holden, and Butler), and, one of my favorites, The Design of Everyday Things (Donald A. Norman). For more on these books, you can refer to the UX Design section of my Bookshelf.

To continue my exploration, I recently read Designing with the Mind in Mind: Simple Guide to Understanding User Interface Design Rules by Jeff Johnson (Amazon Link). Like most of the design books that I have, this one is fairly short (under 200 pages), but it is packed with lots of useful information.

This book is primarily about how humans perceive the world, and how we can use that to our advantage when building our user interfaces. It also uses studies about how memory, recognition, and process affect how we interact with the world.

The chapter titles themselves are a list of how humans work:

  1. We Perceive What We Expect
  2. Our Vision is Optimized to See Structure
  3. We Seek and Use Visual Structure
  4. Reading is Unnatural
  5. Our Color Vision is Limited
  6. Our Peripheral Vision is Poor
  7. Our Attention is Limited; Our Memory is Imperfect
  8. Limits on Attention Shape Thought and Action
  9. Recognition is Easy; Recall is Hard
  10. Learning from Experience and Performing Learned Actions are Easy;
    Problem Solving and Calculation are Hard
  11. Many Factors Affect Learning
  12. We Have Time Requirements

In each chapter, Johnson gives specific examples of these traits and how our application design can play on the strengths and weaknesses of each.  Here are few that stuck out to me.

Gestalt Principles
Chapter 2 ("Our Vision is Optimized to See Structure") covers the Gestalt principles of human perception. Apparently, these are fairly widely-known (and I've recognized some of them in my own design work), but this is the first time I've seen them delineated.

For example, the Proximity principle states that relative distances between objects determines how we group them mentally. Look at the following picture.

We tend to see the blue stars as 3 rows, and we tend to see the orange stars as being in 3 columns. We can use this in our UI design to make sure that things that go together are actually perceived as belonging together.

The Continuity principles states that we often perceive things as continuous even if it's broken in the middle. As an example, we'll consider a slider bar (this one is from Windows Media Player).

The volume slider is made up of 3 parts: the blue line on the left, the circle in the middle, and the grey line on the right. But the tendency of our brain is to see a single line with the circle on top of it. Now, whoever designed this particular slider added something to enhance this perception. Notice that the circle has a dark line going through the middle of it. This gives the added perception that the circle is semi-transparent, and we are seeing the continuous line underneath it.

The other Gestalt principles (similarity, closure, symmetry, figure/ground, and common fate) all have similar examples.

These principles seem obvious once you see them stated. But unfortunately, this chapter also contains several examples of applications that do not follow these principles, which leads to difficulty in using them.

How Fast Does Our Brain Work?
Another chapter that I found especially interesting was Chapter 12 ("We Have Time Requirements"). This takes a look at how long it takes the brain to perceive things, how long it takes us to process information, how long our attention is really dedicated to a single task, and so forth.

The chapter contains an interesting list of perceptual and cognitive functions and the duration of each. This includes things like the shortest gap that we can detect in sound (1 millisecond), minimum noticeable lag in ink as someone draws with a stylus (10 milliseconds), the time required for a skilled reader's brain to comprehend a printed word (150 milliseconds), duration of unbroken attention to a single task / "unit task" (6-30 seconds), and time to choose a lifetime career (20 years).

The most interesting part has to do with the time of a "unit task". This is covered quite extensively. Unit tasks are small (such as filling in login information). We will dedicate 6-30 seconds to a task before our brain jumps away. Now, it may jump right back, or it may get distracted by something else. Our goal as application designers is to try to keep our tasks within this time window.

For example, rather than having someone fill out an entire tax form in one big scrolling screen, we should break this process down into smaller tasks in a wizard-type interface. This allows us to concentrate on one small task at a time. When we click "Next" our brain may wander (or take a quick breather), but we're right back to concentration on the next task.

Wrap Up
We looked at just 2 of the chapters here. But I found each chapter interesting. I learned quite a bit about how the human mind works. And more specifically, how I can apply that knowledge to how I design my applications.

I know that my personal web site is in pretty bad shape right now (especially the home page). But this book helped me pinpoint several specific problems. I've been planning on updating things for a while, but this will give me the push to do it in the (hopefully) not-too-distant future.

Designing with the Mind in Mind is a great book for anyone wanting to better understand their users (and how their brains work). Once we understand our users, we are better prepared to create excellent experiences for them in our software.

Happy Coding!

Thursday, October 3, 2013

MVP Award 2013

Microsoft has honored me by renewing my MVP Award for Visual C# for a second year. I got my 2013 "disk" today:

If you're unfamiliar with the MVP program, Microsoft recognizes those people who are active in the development community (or, more broadly, the technical community -- the program covers much more than just the developer tools).

I've been recognized for my speaking engagements and articles -- helping developers expand their knowledge in the world of .NET. I consider this to be a great honor, and I've really enjoyed meeting other MVPs from around the world.

But even without this type of recognition, I would continue to do what I do. I love helping other developers. And what really keeps me going is watching people learn and knowing that I've made someone's job a little bit easier.

When you learn something useful, be sure to pass it on.

Happy Coding!