Tuesday, April 17, 2012

Am I a good enough programmer ?

Ever since I started programming, this question has been bugging me. Now, I am trying to reflect on it from a different angle and I'm trying to understand what this even means to me and if in fact I am a "good enough programmer".

One of the most important things I learned a couple of years ago (from my team leader at the time), was that you can't define a goal without having a well-defined system to measure the success of reaching it. So, I must first define what being 'good enough' means to me.
In order to do that, I need to go back to the beginning...

The beginning
I started programming when I was about 12 years old (around the year 2000). It was building small applications for my first PC in Visual Basic for a short period, and about a year after that I started building websites using PHP and MySQL. Back in the day, I remember myself learning a lot from some books I ordered from amazon and reading easy-to-understand tutorials on the internet. I think at the time I was pretty much a script kiddie. A lot of the sites I built were from tutorials on the internet, and when I ran into problems I would run straight to the internet forums and wait for someone to help me out. I looked up to the ones in the forums answering my questions and publishing all the open source javascript/php components I was using freely, when sometimes I didn't even understand how they worked.
What I remember clearly from that period was wanting to be as good as those 'guys' on the internet - the ones answering my questions and publishing open source. I wanted to be another success story like the guys from Mirabilis or other companies at the time I was reading about during the dot-com bubble period.

Getting better
After a while, I felt like I had a lot of knowledge about PHP and MySQL (boy, was I wrong at the time), and I started building ecommerce websites as a freelancer. I built some nice websites (which some of are running till this date without any need of maintenance) and I felt like I was on top of the world. I was just waiting to finish high-school and make a career out of my favorite hobby!

Working on a team
After high school I served in the Air Force (mandatory in Israel) for 3 and a half years, 2 of those years as a computer programmer. This was the first time working on a team with other developers. Some of these developers had fancy college degrees and some of them had a couple more years of experience than I did. This blew my mind away! All of a sudden I felt like I met a new species of programmers I didn't know before. It seemed like these guys didn't only know how to program but they had a deep sense of knowledge of what their code means and how it was affecting the CPU. They all had their own blogs and every week one of them would present a lecture, talking about something new and teaching the team about new technologies.
I was totally blown away by this, and this convinced me that I wasn't even close to where I wanna be as a programmer...

Getting even better
I started reading a shit load of programming books, subscribing to some blogs on the internet and started diving into some leading open source code projects that were popular at the time. I even started a blog on my own as a way of learning more myself. During this period I learned so much and looking back at it, I would've never reached the amount of knowledge I know today without working with other people better than me (just a side note to others). By the end of those two years, I even managed to do some lectures myself and I think in some of them I got to teach others something new.

The 'real' world
My first 'real' job was working for an Israeli credit card company. At first I felt intimidated by this, since I didn't know if I gained enough experience to be working in a big company, so I continued doing what I learned to do. Learn, learn and learn! I continued reading a lot of blogs and learning as much as I can, so I can be as good as the best at my current workplace. That didn't take long and I became one of the best there. I soon became bored and started looking for a new job...
I interviewed at a couple of places but only had a connection with one of them. (I wrote about this in a previous post : A new direction) This is Sears Israel (SHC), which has been my current workplace for the past 6-7 months. Not surprisingly, here I met programmers that are even better than I ever met before, and immediately wanted to go in their footsteps.

I could go on about how I continued learning as much as I can, but I think you get the point (and looking back at how much I wrote, I doubt anyone would read this whole post!)...
So now I look back at that feeling I had when I first started out programming, not knowing how good I wanted to be, just knowing I want to be better, and I think today I can say that I feel almost the same way. A couple of times already, I tried to define goals as to 'how good' I want to be, but these definitions never hold, since there are always new technologies out there to conquer and more programming languages to learn. The second I feel like I reached that point, I just find something new I want to learn and think I'm not good enough since I don't know that yet...
This is probably one of the reasons I am still in this field of work. The challenges are never over, and your work is never complete.

Today, I can appreciate the fact that I know that I am working amongst some of the more talented programmers in Israel.
I know I'm not the best, but I am still striving to get there! I still don't know what being the best means, and if I'll ever get there, but I do know that I'm enjoying the whole process. I know as a fact I am getting better all the time and I know that just the fact of wanting to be better and doing something about it makes me better than most.

I know I am a whole lot better than I used to be just a couple of years ago, and I'm pretty sure that in a couple of years from today I will be able to say the same again. This thought gives me some peace :) and is VERY satisfying by itself!

Part of the reason I am writing this post is to be a message to myself and to others - You are not the best (this goes for 99.99% of potential readers), but (and this is a big 'but') you should always strive to be the best. Keep reading, learning and programming as much as you can and maybe one day you will be. Doing this will keep you in a good position and on the way to getting there.

Tuesday, March 6, 2012

Cleaning up that ugly client side aspx code


When managing a big web project, you might find yourself ending up with a big master page, that has a bunch of centralized code client side logic, like includes. What I mean by 'includes', is the part of the code where you spit out all the declarations for js and css files. I got to this stage many times by myself, and i've seen it happen at my various work places as well.

This usually ends up to some big nasty chunk of code that looks like this (and this is a relatively small example of what i mean...) :
<link rel="stylesheet" href="../../Content/bootstrap.css" />
<link rel="stylesheet" href="../../Content/common.css" />
<link rel="stylesheet" href="../../Content/widgets.css" />

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/bootstrap/bootstrap-dropdown.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/common.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/homepage.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/add-form.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/search-form.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/bookmark-list.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/register.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/openid.js")" type="text/javascript"></script>


Why is this bad ?
For starters, there's so much similar text here, that typing it all up should've ringed a huge bell for us, screaming "THIS IS WRONG!!".
The clutter of text here, bothers us from seeing what's really important here, and all that is, is the files being included here.

Why does this happen ?
The main reason for this is because we don't think of client side code as 'actual' code. This leads to us forgetting about DRYing up our code. The equivalent of this in server side code would be to copy the whole body of a certain method a dozen times, and just changing one parameter between different versions. If this were server code, we would've easily spotted the code duplication, and extracted this to a method that receives a parameter and saved a lot of typing, and kept the maintainability of the code.

How do we fix this ?
All we need to do is introduce a small helper method that will print this again and again for us. We can do this on the client and on the server. In this case, I would go with doing this on the client, just because this piece of code will probably only be useful for us in this specific context.

Here is my clean solution to this problem :
@{ Func<string, string> JsRequire = s => "<script src=\"" + Url.Content(s) + "\" type=\"text/javascript\"></script>"; }
@{ Func<string, string> CssRequire = s => "<script rel=\"stylesheet\" href=\"" + s + "\" />"; }

@CssRequire("../../Content/bootstrap.css")
@CssRequire("../../Content/common.css")
@CssRequire("../../Content/widgets.css")

@JsRequire("https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js")
@JsRequire("~/Scripts/bootstrap/bootstrap-dropdown.js")
@JsRequire("~/Scripts/common.js")
@JsRequire("~/Scripts/homepage.js")
@JsRequire("~/Scripts/add-form.js")
@JsRequire("~/Scripts/search-form.js")
@JsRequire("~/Scripts/bookmark-list.js")
@JsRequire("~/Scripts/register.js")
@JsRequire("~/Scripts/openid.js")


Sunday, March 4, 2012

jQuery relative position plugin - nextTo


The Problem :
I've already created quite a few jQuery plugins in the past, at work, and for personal use, and in many of them there are certain parts of code that always tend to repeat themselves.

One of these parts of code has to do with element positioning calculations relative to another element.
For example, when creating a plugin for a drop-down menu, or a tooltip, you can't avoid having a nasty piece of code in there, that all it does is calculate the element's position relative to the element we clicked on or hovered above.

I don't think there's any need for me to post an example of this, you probably know what I mean. This is usually the least most maintainable part of code in the plugin and the least easy to understand.

The Solution :
I finally decided to extract this ugly piece of code into a nice jQuery plugin that will hold all the dirty work calculations, and will leave you with a nice clean and understandable piece of code inside your plugin.

<scrip type="text/javascript">
    $(function() {
        $('.PutThisDiv').nextTo('.ThisOtherDiv', {position:'right', shareBorder:'top'});
    });
</script>


This plugin is hosted on google code : https://code.google.com/p/next-to/ (project name: 'next-to')
At the project page you will find more sample usages, usage explanations, the source code and a minified version.

Saturday, March 3, 2012

FireSheep version 2.0


FireSheep version 1.0
I think about two years ago I read about the FireSheep firefox plugin that allows you to hijack any user's account to many different sites (Facebook, flickr, twitter, etc.) that is surfing on the same wifi connection that you are using. This can be extremely brutal to use in any coffee shop, hotel, airport, just sitting outside someone's house stalking them, whatever...
The point is, the person who created this, Eric Butler, didn't do this as a hacking tool, but as a wake-up call to all the sites that aren't encrypting there connection via SSL, and a lot of them didn't even change that since...

FireSheep in action...

The potential danger
The second I read about this, I just couldn't stop thinking about what a dangerous tool this can become. Imagine this - Someone expands this tool to send all the currently active session cookies in the current wifi network to an online database, and now all the active sessions from all the firesheep users are shared worldwide. This means that you don't even have to be in the same wifi network as someone else to hijack their account. All you need is for someone else to be there while you're in the comfort of your own home... Isn't the internet a beautiful thing ??? :)

The future...
Two years (maybe more) later, and I'm happy to see that no one did this yet, but I am still very afraid of the day someone will!
I looked at firesheep code a little just out of pure curiosity, but never even downloaded it or tried it myself. I'm not a hacker and not interested in becoming one. The one thing I am concerned about here is my own personal security, so I am still hoping that these sites will improve the security for the sake of their users. Unfortunately, sometimes the only thing that speeds up the process is a lunatic taking advantage of the current situation.

Till then, beware...

Thursday, February 23, 2012

Unit Test looking for missing files in your project


When you're working with a big team of developers and a nice Build Server, a lot of times you rather work on a separate feature branch not to break the build while committing. This is very comfortable since you have your own "work zone" and don't bother anybody else, nor have to worry about breaking the build until you're done with your feature and ready to reintegrate to the trunk (or your main working branch).

But this comes with a price...
It's not always easy dealing with all the conflicts when reintegrating your branch, and sometimes this can lead to problems. One of the main problems we ran into a couple of times recently at my work place while doing this process was that while reintegrating, we missed some new files that were added to the project while dealing with the csproj file conflicts.

This means we had new files added to the project, and were in the project directory, but not in the '.csproj' file. This might be a class that is referenced throughout the project, which in this case you're lucky and the project won't compile, which will immediately let you know there was a problem. But if you're not lucky, this will be a controller class file, or an 'aspx' file, and leaving it out will never cause a problem for the build server (if your project isn't 100% covered with tests - a totally different subject for a whole new post!).

So... what's the easiest way to quickly solve this problem ? Write a test that will check this! :)
That's exactly what I recently did, and now every time this happens the build server will fail, with a nice message that shows you all the files you left out!
(of course, you need to make sure you didn't by accidentally leave this test out of the csproj!! :)

For your unit testing pleasures -

[Test]
public void CheckingThatAllFilesAreInCsProj()
{
    const string projectName = "TestWebsite";
    var projectDirectory = GetProjectDirectory(projectName);
    var projMissingFiles = RetrieveMissingFilesList(projectDirectory.FullName, projectName);

    Assert.IsTrue(projMissingFiles.Count() == 0,
        "There are files that are missing in the .csproj file : \n" + string.Join("\n ", projMissingFiles));
}

private DirectoryInfo GetProjectDirectory(string projectName)
{
    var currentDirectory = new DirectoryInfo(Directory.GetCurrentDirectory());
    while (!currentDirectory.GetDirectories("*", SearchOption.TopDirectoryOnly).Any(x => x.Name == projectName))
    {
        currentDirectory = currentDirectory.Parent;
    }
    return new DirectoryInfo(currentDirectory.FullName + "\\" + projectName);
}

private string[] RetrieveMissingFilesList(string projectDirectory, string projectName)
{
    var csFiles = Directory.GetFiles(projectDirectory, "*.cs", SearchOption.AllDirectories);
    var aspxFiles = Directory.GetFiles(projectDirectory, "*.aspx", SearchOption.AllDirectories);
    var projFiles = csFiles.Union(aspxFiles);

    var csprojDocument = XDocument.Load(projectDirectory + "\\" + projectName + ".csproj");
    var csFileElements = GetCsFileElements(csprojDocument);
    var contentFileElements = GetContentFileElements(csprojDocument);
    var allFileElements = csFileElements.Union(contentFileElements);

    var projMissingFiles = new List<string>();
    foreach (var file in projFiles)
    {
        var stripFileName = file.Replace(projectDirectory, "");

        if (!allFileElements.Any(x => x.Attribute("Include").Value.ToLower() == file.Replace(projectDirectory + "\\", "").ToLower()))
            projMissingFiles.Add(stripFileName);
    }

    return projMissingFiles.ToArray();
}

private static IEnumerable<XElement> GetContentFileElements(XDocument csprojDocument)
{
    return GetFileElements(csprojDocument, "Content");
}

private static IEnumerable<XElement> GetCsFileElements(XDocument csprojDocument)
{
    return GetFileElements(csprojDocument, "Compile");
}

private static IEnumerable<XElement> GetFileElements(XDocument csprojDocument, string elementType)
{
    return csprojDocument.Elements()
        .Where(x => x.Name.LocalName == "Project").Elements()
        .Where(x => x.Name.LocalName == "ItemGroup" &&
            x.HasElements &&
            x.Elements().Where(t => t.Name.LocalName == elementType).Count() > 0).Elements();
}


The code in the test isn't the most beautiful thing I wrote but it does serve a great purpose.
All it does is search the project folder for all .cs and .aspx files, and then dissects the csproj file (which is just a big xml file) to find all the file references.
The code I posted just checks for cs/aspx files, but you can easily add functionality for js, css, html and any other file type you like...

Enjoy :)

Thursday, February 16, 2012

.net to Java transition gets a little easier for me...


I'm taking a university course in Java this semester, so I've been recently writing a lot of Java and as an IDE using IntelliJ (community edition) by JetBrains a lot. As a .net guy, mostly, I'm used to Visual Studio with ReSharper 6 and I remember so many keyboard shortcuts by heart which make my coding work so productive!

So you can guess how hard it is for someone like me, doing the transition to a different IDE, and not having ANY of the shortcuts you're used to. I tried studying some of the intelliJ shortcuts but it just got too annoying, and I finally decided to take the time and set ALL of the IntelliJ shortcuts to the same VS shortcuts once and for all. While I did that, I ran into a nice surprise - The brilliant guys at JetBrains were one step ahead of me the whole time, and have already added a VS keymap option in their settings panel!!!




Thank you JetBrains for making my Java experience just a little bit more comforting! :)

Saturday, February 11, 2012

VS Spell Check Extension - using Roslyn


A couple of months ago Microsoft published the Roslyn CTP which gives us an inside view on the Compilers view to our code. This also comes with project templates for creating CodeIssues and CodeActions (These are code suggestiongs/actions that are available to the coder in the IDE).

Since I read about this it interested me a little, and wanted to play around with this. Since I've been programming in java at home lately due to a course i'm taking at the university, I realized that one of the nice features that IntelliJ has is that it gives you suggestions on spelling mistakes you made on variable names (because this is one of the most annoying things i see in code and i truly believe makes it harder to maintain), so I thought i'd try to implement this in VS as an extension.

It was really simple to do so -

I just created a CodeIssue project :


With the ExportSyntaxNodeCodeIssueProvider attribute, you can tell it to execute the code only on variable declarations :


Split each variable name into separate words (most variables, at least when I write code looks like this "var myReceivedFilesList" so i separate them by case) :
public IEnumerable<CodeIssue> GetIssues(IDocument document, CommonSyntaxNode node, CancellationToken cancellationToken = new CancellationToken())
{
    var variable = node as VariableDeclarationSyntax;
    if (variable != null)
    {
        var nodes = variable.ChildNodes().Where(x => x.Kind == SyntaxKind.VariableDeclarator);

        foreach (var syntaxNode in nodes)
        {
            var fullVariableName = syntaxNode.GetFirstToken().ValueText;

            var wordsInVariableName = fullVariableName.SplitToWords();
  
            if (wordsInVariableName != null)
            {
                var correctSpelling = CheckAndCorrectSpelling(wordsInVariableName);

                if (correctSpelling != null)
                    yield return new CodeIssue(CodeIssue.Severity.Info, syntaxNode.GetFirstToken().Span, "Possible Typo ?\nMaybe you meant : " + correctSpelling);
            }
        }
    }
}


And viola!
You have the spell check feature on variable names in your VS IDE :



For the spell check I used the NHunspell project (This is the .net wrapper to the OpenOffice dictionary).

I put the code up on google code so you can take a look at it, and who knows, maybe even contribute to it... :)
https://code.google.com/p/gb-coding-extension/

I don't know if this is production-worthy code, I didn't even check performance or if it slows down the IDE. This was just a small learning experience for me.
Maybe if I have some more free time, and good ideas, I'll add to it more features in the future...