How To Learn a New Programming Topic

(Note: this article is really long, but every word of it is important. Follow along and learn the topic with me.)

I had an interesting conversation with another programmer the other day about how to learn a new programming skill. He's a very smart guy, but he was having trouble getting started learning new topics. Programming topics are built up in layers, and you can't understand high-level things until you understand their lower layers. Many programming books, articles, and even our development software is fighting this idea and trying to make high-level processes accessible without the low-level knowledge. This is because many people reject what I consider a basic property of programming itself: programming is hard work. Part of the reason for that is because you are constantly learning the minutiae of many new topics simply to keep up with your job. This can be boring at times, and requires hard work and dedication. Programmers who lack this dedication can survive for a while, but they almost always either become glorified data entry clerks, or they become doctors, preachers, and pizza drivers (true stories).

One of my major pet peeves on internet forums is the "How do I do this" question, when the person hasn't even tried yet. Programming is a topic which often presents the student with so many problems right up front, that they throw up their hands in disbelief and have no idea what to do. So they go begging to experts for some tidbit of arcane majick that will make it all make sense. The experts will often come back with a flame of epic proportions, which I have been guilty of on numerous occasions, telling people "why don't you try to learn it before you come in here with your stupid questions?!" At some point, it occurred to me that for some people it's not as simple as "go and learn it." This can be true of people with good learning skills and high intelligence. However, it is possible to learn this skill. That is, learn to learn.

Learning a new programming skill is an organic process and will not be the same every time, but there are some basic processes you can apply in all cases. This example will show you what those are in as much detail as possible. Research skills are important, but so is experience. In many places in this adventure, I rely on my experience to figure things out. In the cases where I have no experience with something, I go get some. I chose a topic which I have no experience with: Visual Studio Add-ins. Here goes...

Defining your goals
At first, I want to think about what my ultimate purpose is, but I have to mentally accept that I probably won't get there right away. I need to carefully define this because I don't want to confuse myself and waste my time by exploring topics that don't apply to my situation. What I want is a VS Add-in that would allow me to highlight a section of variable declarations (such as the long sections generated by the Forms Designer), and sort them by type and alphabetically. Ideally I would like this to be a context menu that comes up when you highlight some code. I need to think about some of the possible issues with this right up front, but I don't dwell on them. Some things that come to mind right away are: how to get a context menu to come up in the first place, how to read the code from the editor window, how to automatically modify that code, how to make sure I don't introduce errors in the code, and how to reject bad user input if they highlight a section of code that doesn't include variable declarations. Overall, I know this is going to be a pretty hard project, so I want to start with something simple. At first I want to create a simple Add-in that puts up a context menu item whenever I right-click in the editor window. Without any research, I'm assuming that's going to be easier that testing to see if any code is highlighted and if it's proper code for my routine and so on. This initial context menu item will not do anything, it will just be there to let me know it's working.

Searching for information
In the old days, I would be on my bike headed to the library, but these days we have Google, and it should be the first place you go for any information. Using Google to search for programming information works fairly well, but you need to know how to use Google. Coming up with the right search terms is very important, and in this case I have a good idea what I need. I know what my topic is called, which is a good start, and I know what language I want to program in. Including the language in programming queries is one of the best things you can do to help Google find what you want. So I go to Google, and say "Visual Studio Add-in C#", and start looking at the results. I'll usually read the first few results of a Google search, checking which sites they come from and the preview text to see if the article applies to my situation... only then, do I click a link. If I don't get good results, I don't waste my time clicking anything, I change my search terms, or if I'm positive I have good words, I check other search engines like Ask.com. I also check programming sites and forums like Codeproject and specialized programming documentation search engines like MSDN. I prefer tutorials when I'm just getting started, so I do avoid MSDN and the Visual Studio "F1" function until I've gotten an intro to the topic, but I will eventually be consulting the technical documentation for something. This will probably be time-consuming and painful - I know this and accept this right up front.

Anyway, back to my Google results. The first result is from Codeproject, and I know that's a good site, but it says some kind of error, so I look at some of the others. There's some good things there, and I might go back to the Codeproject one, but I like the second one, so I click it and start to read the article.

Reading and processing information
At first, I don't read the whole article, I skim over it. Skimming is a skill you should have learned in school, and if you don't have this skill, you should learn it. It comes in handy when looking through long code files too, so it's a good skill for any programmer. The article looks good overall, so I start reading it word-for-word. No, I am not going to skip any words... this is super-important with a topic you know nothing about, and I shouldn't have to say it, but don't skip over anything. I am eventually going to read this whole article, but there's going to be interruptions along the way, so I use tricks to keep track of where I am, such as highlighting sections in my web browser as I read. I want to make sure I don't miss anything important, but this is a tutorial, so I need to follow along. In this case, I'm not going to read the whole article before I try the process. I know that c-sharp corner is a good site and I'm fairly confident that the article will lead me somewhere interesting. This is where the organic process begins, and I'm going to alternate between learning and doing, and possibly also between various levels of information within my topic. In the first paragraph of the article, it makes it clear that this tutorial is a more complicated project than I initially wanted to do, but it's still pretty simple: it adds a comment to your code file. I decide this is cool, so I open up Visual Studio and start to follow along.

Trying it out
At this point, it's worth mentioning that having a good machine will really help you. Make sure you have enough memory to run Visual Studio and a few web browsers and if you have multiple monitors or other bells and whistles, use them. I'm actually reading the tutorial, running several web browsers and Visual Studio, and writing this blog, all at the same time. If I was short on memory or something, that would simply not be possible. If you are reading this and you want to follow along, you should have the same applications open. If you don't have my type of ADD, you will simply have to learn to multi-task... it's a programmers greatest time-saver (caffeine helps).

At first, I make a note that this article mentions "Visual Studio .Net" - I'm not sure what version he means by this, but I have version 2005 so if I notice anything weird, I might have to abandon this tutorial and find one that is specifically for Visual Studio 2005. I start to create project as described and everything is going well. I see that there is a lot more stuff in the screenshots than what I see in my Visual Studio, but I have the options I need, so I press on. I choose a good name for my project (JazzysCodeSifter), and I check the options one more time before I click the Open button. I am presented with a Wizard that looks a little different than the one in the article, but again, the option I need is there ("Create an Add-in using Visual C#"), so I select it and click Next. The next few screens in the wizard are covered in the tutorial, so I click through and finish the wizard part. I take note of the options along the way, because I'll eventually go back and learn more about them, but for now I just select what the tutorial says. When I get to the finish screen, I see that things are a little different than the tutorial says, so I go back and read some more and I twiddle the options in the wizard until it's exactly right. THEN I click finish in the wizard to create my project. I make sure everything is exactly right, because I don't want to confuse myself by accidentally going down a different path from the tutorial. This has burned me before, so now I make sure I do it exactly right.

Now, there's some things I'll do here regardless of what the tutorial says. This is just from experience, so I depart from the tutorial for a minute and I do two things: compile the project and read through the code. The project compiles fine, and when it was created, it automatically opened a file called "Connect.cs", so I take a look at that. I don't like wizards very much, so I scrutinize the code that it created in my project, and I may eventually go back and create an Add-in from an empty project, writing all the code myself. For some project types that generate a lot of code, this is not practical, but if possible I like to know what those wizards do and the best way to find out is to do it yourself by hand. For now I see a lot of confusing stuff in the code and I have no idea what most of it is, but I make note of some key things, like what libraries are used (the using directives tell me this), how my object is created (it has an empty constructor), what some of its events are (I see OnConnect, OnDisconnect, etc.) I consider looking up the Visual Studio "F1" help on some of the object type names, but I want to finish the tutorial first, I'll do that later. The tutorial will tell me some of what I need to know, so I go back to it...

When I go back to the tutorial, I notice that the next thing in the process is a very cryptic operation and I don't fully understand what they are saying here:

To build the setup project (CopyrRightAddInSetup in this case), youll need to go into the Configuration Manager in the Build menu and check the build, because by default it is unchecked.

This comes along with a screenshot that doesn't help very much. Now, I happen to know what a setup project is (it's the installer that you will distribute), so I go to create one for this Add-in using the wizard. I know from experience that it's best to add the setup project to my existing solution, so I do that. I also know the basic steps to create a setup project, so I do those and I end up with something like the screenshot in the tutorial. If I didn't know about setup projects, that one sentence in the tutorial would have sent me off on a tangent to find out the basics of setup projects, and my learning process would become recursive. I would be back to Google and probably another tutorial. I feel confident at this point that I haven't messed anything up too bad yet, so I continue in the tutorial.

The tutorial says to "Run the project in debug mode," and I know how to do this, so I click the little arrow and it runs. I see it open up a new instance of Visual Studio, and I go to the "Tools" menu to see if my Add-in is available, and it is. Again, lots of memory and a good computer is handy here: I'm now using 1771MB of RAM, for two instances of Visual Studio (one running a program in debug mode), 4 web browser windows, and a paint program for this screenshot of my Add-in.

If I was using virtual memory for this, my hard drive would be thrashed and I would be staring at the hourglass. Anyway, I have reasonable proof that my basic Visual Studio Add-in works, and at this point, I have created The Null Program, so I have a choice. I can go ahead and stop reading the tutorial and go off on my own, or I can finish the tutorial and learn what it has to offer. I choose the first option.

Finishing the first try
I usually like to create a very basic project at first and then dive into the technical documentation, but this tutorial is worth finishing, so I'll do the idea in the tutorial: an Add-in that puts a comment in your code files. This isn't a big departure from the code-modification tool that I eventually want to do. In some cases, I will abandon the tutorial at this point and go off on my own tangent if I think it's necessary. Sometimes, that works, but sometimes I end up going back to the tutorials. This is completely unfamiliar ground, so I want to see where I end up with this example, so I finish the tutorial. I make note of a lot of things along the way, which I will have to read up on from other sources. Tutorials don't explain everything, and I want to understand some things in detail. Experience tells me the things I need to investigate further and those I can safely ignore. For example, this Add-in is invoked in a different way from what I want and the tutorial doesn't explain it fully, so I will investigate the interface between Visual Studio and my program a little more, but for my purpose, I don't particularly care about the Toolbar it created so I won't investigate that any more. Not right now anyway.

Remember the idea here was just to get an introduction to the subject, because I had no idea how to get started. It took a lot of work to get to that point, but it wasn't impossible. I think an organized approach to this task can make it seem less overwhelming, and if you use this example to develop your own learning techniques, you should be able to adopt new programming topics a little easier. This will only get you started though. If you want to become an expert on Visual Studio Add-ins, it will take years of experience, because this topic is built on so many others. If you don't know C#, for example, you can never be an expert on anything that uses C#. Learning topics like this can be very time-consuming, but I think it is the only way if you want to be any good. Learning programming can require some special techniques, but this is essentially the same process you would use to learn anything else: an iterative process of study, practice, reflection on what you have done, and refinement of your skill. Tiger Woods practices every day, studies the golf swings of other people and himself, and sometimes even takes golf lessons, and he's Tiger Woods! You need that kind of dedication to truly understand any subject, and programming is no different. Good luck!


OMG, This Is Cute

This is one of those things that reminds you that the cheap video camera actually is a positive addition to society. When I was a kid, capturing something like this on 8mm would have been a rare occurrence. It was just too expensive to shoot film back then, and note that this is in a restaurant where it would have been totally rude to pull out a large, noisy movie camera. The cellphone camera is so much less intrusive that we're now able to capture moments like this all the time. I have memories of my kids doing this, but the next generation has video. I have about 30 minutes of 8mm film of my childhood. This generation has YouTube... what a difference! This is so cute... if it doesn't brighten your day, then you are mentally ill.

braedens first lemon

Add to My Profile | More Videos


Dog Macros

Just a couple photos I put text on.

Some dogs just don't like to have a camera shoved in their face after they wake up.

This might be funny for hackers


The Decline of the Art of Programming

Two things are happening in the development world that I really don't like. The dumbing down of programming tools, and the dumbing down of programmers themselves. Consider my latest adventure with drag-and-drop. I wanted to create a custom HttpHandler for our web site. I prefer to actually write code, but I found a nice tutorial about how to do all this GUI work in Visual Studio, and presto! a custom HttpHandler. Problem is, if you follow the tutorial, you get an error. If you search for the solution to the error, you get all the forum posts from people who followed the tutorial and ended up in the exact same place I was. If you then go and read the answers (if there are any), you find no actual solutions to the problem... instead you find a bunch of losers who basically decided that since they couldn't drag-n-drop a solution, they decided to do it a completely different way. So, the most popular tutorial on the subject leads to an error, all the other tutorials are directly copied from that one, and nobody ever bothered to figure out the real solution, fix the original tutorial, or post a good answer on a forum, anywhere on the entire Internet! Cool... way to go, Programming Community! Good one.

Clearly, there is not a solution that you can just copy from someone else. If I was the type of person to look at this situation and decide that, since nobody else solved it, the problem can't be solved... I would be implementing a way to tie Apache and IIS together and re-write each other's URLs, or something stupidly complicated like that.

Instead, I used my arcane knowledge of compilers and linkers and How Computers Work, to come up with a solution to the original problem. See, I recognised the error as a linker error right away... and it didn't take me long to figure out why the linker couldn't import my custom handler code. If I was a drag-n-drop programmer, it's likely I wouldn't even know what a linker is, and I would have been screwed. I'm not even sure why I spent a whole day looking for someone else's solution, although I did get an education about the subject, which probably helped my mental process derive the actual answer. Still, my first instinct was to look for a pre-fab solution, and it took a whole day for me to accept that there wasn't one.

The other issue is the dumbing down of programmers themselves. This problem is caused by modern education. Kids are being told that "if you just try hard enough, you can do anything"... this is not true, and it's hurting our kids to teach them that. Kids need to learn when to give up on something. We have too many programmers who shouldn't be programmers because of this issue. These are people who think that if they just try really hard, they can be good at programming. It doesn't work that way. This is a field like being a fashion model - if you aren't the right person for it, you might get somewhere but it's going to be hard and you will never reach the level of proficiency that you could in another field.

In Boulder, the school has a policy outlawing all games where there is either a "winner" or "loser" - because losing at a game is too traumatic for kids. BullSH$!%&?!!!! Losing is important! If I hadn't got my butt kicked multiple times as a kid, I might be out there right now trying really hard to become a football player, and not getting anywhere at all, because I'm skinny and uncoordinated and I have no endurance. I'm not a physical person, and there's nothing wrong with that. Why is it suddenly "not ok" to be a person with limited mental abilities too? I know my mental limitations and my physical limitations, and I'm irritated that kids today are being taught that there aren't any such limits, and they are being prevented from experiencing failure, which makes them totally unaware of their own limitations.

This all leads to an incompetent workforce, and that requires tools that can be used by an incompetent workforce, which is where we are now. These "tools for the dumb" are not helping the problem, and are contributing to the decline in Computer Science as an academic pursuit. People are starting to see computers like they see cars, as a machine to do a job, which it is, but it's so much more than that, and there will always be those of us who are interested in that "more" that it can do. I would bet that there are the same number of us now as there always have been, but our percentage is smaller, because we are now lumped in with everybody else who uses computers. It's like considering all car owners as mechanics... clearly they are not, and I'm insulted by the suggestion that script-kiddies and data-entry clerks are anything other than grunt-workers performing tedious tasks that the knowledgeable people are tired of.

Why can't you get this done on time?

Here's why development projects can't be done on time, or rather, why it's impossible to estimate the time for a project unless you've already done it. You do not need to understand the tasks in italics, which are specific to my company site. This is a typical day for me - for perspective, this is 7 hours of work, with the exception of the HttpHandler issue, which spanned several days.

Had to completely re-code the Master page so that the email claiming would work. This is an example of something that would have been a small change, but there is a condition that ASP.Net will simply not accept, and it's caused by the way the master page is made. In order to make the email claiming work, this underlying problem had to be fixed. Existing pages were not affected, but this new page aggravated the situation and made the error show up. Still working on this re-coding of the master page. This has to be done very carefully because any mistakes could negatively impact every page on the whole site!

Spent an hour looking for the method of securely posting a form field to another page on the server without making a round-trip back to the client. This is important so that it will not be possible for members to claim other members contacts, simply by knowing the email address or contact ID. There is only one way of doing this, and it causes the problem above, which requires a total re-work of the master page to fix it.

Got half way into the email form thing, and then realized that in order to support the sending of attachments, I couldn't just upload the file and send it out. I have to upload the file and figure out a unique name for it, then I have to store that name in the database, associate that attachment with the email message, which now also has to be added to the database, then I have to create a scheduled event in the existing database table, and finally, I have to modify, recompile, and re-install the BEIJobService, so that it will be capable of querying the database, getting the file name, and sending the attachment. This procedure would be easy for a human, but it requires hundreds of lines of code to implement on the computers, and it involves changing 3 seperate codebases, the database, the web site, and the job service. All of these changes must be tested in development environments before being put live on the server, particularly the Job service, because it is capable of causing mass havoc if it malfunctions. And the job service is a bitch to test.

I spent about half a day building a way to auto-login to the Online Boot Camp, but when I finally went to test it I got:

Invalid postback or callback argument. Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. Exception Details: System.ArgumentException: Invalid postback or callback argument.

I basically was back at square one. Maybe square two. The cause of this error can not be eliminated because I don't own the AKP codebase and I can't change it. I have to go into research mode at that point, and I end up spending hours on end reading web pages and getting a headache. I don't like that and I feel like it's a waste of time, but I don't have any choice. All this stuff is so new, that even someone with my experience can be stumped by it, simply because we don't know the specific name of some new feature or we're doing something nobody anticipated, and the system chokes on it, forcing us to find a better method of doing the same thing. I try to avoid this situation with proper planning, but I tend to neglect proper planning when I'm under a lot of time pressure. Sometimes I can pull something right out of air and get it done without any planning, but when that method fails, usually it means I've wasted a bunch of time, and it's extremely frustrating.

When I went to create an HttpHandler so that we could do the version control without having to re-code every link on the entire site, I had major problems getting it to work, but it is the only viable solution to the problem. Nobody, including people who work for Microsoft, was able to answer my question. When I went searching on the net, I found a lot of people had posted similar questions on many different forums, and none of them had an answer to the problem. Everyone has this problem, because the Microsoft tutorial on the subject leads to an error, and everyone else who's written a tutorial on the web, basically copied the Microsoft one. NOBODY GOT IT RIGHT... their method does not work. Instead, it causes an error. This is a very advanced feature of ASP.Net that I'm trying to use, and most people do not have a reason for using it. This makes it very hard to find anyone who has successfully implemented it. I am currently writing an article about this: "HttpHandlers that actually work", which should be posted on CodeProject soon. I had to solve this problem myself, using my knowledge of compilers, linkers, and ASP.Net and the .Net Framework. Microsoft MVPs who were provided with my entire codebase could not solve this problem, so I'm pretty proud of myself for figuring it out, but it took a long time, and I had to actively pursue the solution, so I couldn't work on much of anything else till I figured it out. So, I spent time over several days figuring out why one line of code wouldn't work, and the final solution only took about 10 minutes to implement, once I figured out what needed to be done.

And that is why programs do not get done on time.

hit counter script