Tag: tips

Timeboxing: TODO List 2.0!

I recently wrote about TODO lists and how they can help with focus now that many of us are working from home. I had a former colleague on LinkedIn mention this concept of “timeboxing” (which I think many people are familiar with the general idea) and how that can improve the effectiveness of a TODO list.

Here’s the post I made on LinkedIn sharing my blog article:

And the comment that came in right away from Graeme Harvey:

Graeme Harvey - Timeboxing

This obviously got me thinking because sure, Elon Musk is a pretty smart dude, but I also have a lot of respect for Graeme and his perspective on things. So I decided I’d try something out!

TODO Lists v1.0

My original TODO lists didn’t factor in any timeboxing techniques, but they had some benefits. The engineering mind in me says this is a great opportunity to do a little bit of a pros & cons analysis, so if you didn’t think I was nerdy before… Buckle up!

Pros:

  • Generally written out in the order I want (or need) to get things done. Acts a bit like a schedule in that regard.
  • Can have big and small items on the list.
  • Making progress on small items can help build momentum.
  • Let’s me record all the things I want (or need) to get done in the day and track if I did that or not

Cons:

  • No concept of how many things are too many or too few for an entire day’s worth of activity… There’s no timeboxing!
  • No concept of relative time spent on things (If I wrote “eat breakfast” and “Write a novel”, do they each get equal amount of time?)

TODO Lists v1.1

Okay we’re not quite yet at version 2.0 for these, but I took some of the concepts Graeme was referring to and I’ve implemented them every day since he made the comment. I’ve been trying to gauge how things have been going in terms of productivity and I’m already impressed. In fact, writing this blog post is part of my TODO list with timeboxing constraints (so meta, right?).

So the changes I made were very subtle but I’ll list them below:

  • I dropped the concept of putting in order what has to get done. Much of what I’m working on right now doesn’t have true dependencies, so trying to come up with an order for things doesn’t make sense (right now).
  • Every item I write down I put a time estimate on in minutes or hours. Literally everything. Remember I said little things like “Eat breakfast” can still be a TODO item that can help you feel like there’s momentum? Right. Breakfast, 10 minutes. Lunch, 15 minutes. Everything gets a time!
  • I tally up the total time my TODO list should take with timeboxing and do a gut check. I’m at least awake for 16 hours (typically people sleep like 8 hours, right?), but it’s probably closer to 18 hours. Because I’m starting off and don’t have great estimates, I’m ensuring I’m around the 12 hour mark for filling up my day.
  • I’m purposefully leaving some wiggle room in my schedule so that I can try incrementally building this out to be more accurate.

Nothing groundbreaking to implement, but what have I noticed so far?

  • Having a (relatively) small list of things I need to get done and getting to pick the next thing I want to tackle is kind of nice. A bit of flexibility is great!
  • The timeboxing really helps me make sure I’m focused on what I set out to do. 1 hour to review interview questions? Better not scroll on Instagram. 30 minutes to research a topic? Better not be on YouTube.
  • Some estimates for things are way off and some are very accurate! That’s okay though, because the following day I can adjust my estimates accordingly.
  • The overall feeling of being productive and making progress, for me at least, is even higher than it was before.

I’ve really enjoyed this small tweak and I’m hoping to get this to v2.0 status really soon ūüôā Thanks Graeme!


TODO Lists: Keeping focused when you feel lost

TODO List - Photo by Tirachard Kumtanom from Pexels

It’s more relevant for more people now than it probably has been in other times in their professional careers, but COVID-19 means remote work for a lot of people. It also means no work for a lot of people too. I’ve found that a simple tool for me to keep focused is leveraging a TODO list. It’s so simple that I think people often overlook the power of a TODO list when you’re feeling like you’re a bit lost or not making progress.

With your TODO list, the first thing I’d suggest is thinking about a daily routine. Now that you’re working remote, or in the unfortunate case out of work, I think it’s really important that you keep some sort of daily routine to help give you some guard rails. Think about what things you usually do in the morning. What does your lunch look like? How about the later afternoon and into the evening? What does before bed look like? Thinking through your routine will give you an idea of the things you want to focus on and then give you an idea of how much time you’ll need for regular things and how much time you’ll have remaining for stuff that can pop up.

The next thing I’d suggest with your TODO list is to get granular. This is especially important in my opinion if you’re struggling to feel like you’re making progress on anything. You can even write things down like “brush your teeth”. It doesn’t have to be specific to work and it doesn’t have to be anything groundbreaking. You’ll find that as you start making progress by checking off small items that suddenly you’re accomplishing a lot and a day might have gone from feeling like nothing getting done to fulfilling, or from insurmountable to progress being made! The small steps you can take while working through your TODO list are a great way to remind yourself that you’re making progress.

It’s also a good opportunity to remind yourself that these are very strange times for many of us. If you’re working from home or at home and out of work, these could be very new circumstances for you and not at all like your normal routine. That’s okay! Remember the rest of the world is in this together with you.

You should be affording yourself the time to do little things here and there around the house even if you’re working remotely. For example, if you hear your washer/dryer go off in the middle of the day, instead of letting that be something that’s nagging you in the back of your mind consciously go make the time to take a few minute break and change loads of laundry! There are plenty of unique distractions to be had while working from home, but instead of letting them distract you take control and consciously spend the time on the appropriate things.

A sample TODO list might look like the following:

  • AM
    • Get the dog outside!
    • Feed the dog
    • Eat breakfast
    • Hygiene routine
    • Coffee + read news
    • Answer emails
    • Work on Project A
    • Video meeting 1
    • Continue Project A
  • Afternoon
    • Eat lunch
    • Get the dog outside!
    • Do the dishes
    • Answer emails
    • Video meeting 2
    • Work on Project B
    • Get work schedule planned for tomorrow
  • Evening
    • Eat dinner
    • Get the dog outside!
    • Get some exercise!
    • Hygiene routine
    • Pick-a-chore around the house
    • Watch TV/Movie or play a game
  • Before Bed
    • Hygiene routine
    • Read your current book
    • Write out your TODO list for tomorrow

You might have read through that and thought that it feels silly to have a line item for something as simple as brushing your teeth or eating a meal. And that’s totally normal for some people! You might have adapted really well to your change of environment and you’ve got little to no issues adjusting. For others, that won’t be the case. If you’re struggling to feel like you’re making progress, staying on track, or if that the day seems like you’ll never accomplish everything you need to… Take the little wins with very simple things. You’ll notice that you’ll build momentum for yourself.

A friendly reminder to make sure you take the time to get your TODO list together before the next day! I like doing it right before bed so I can run through what I think my following day will look like.


Autofac Modules and Code Organization

Organizing Code With Autofac Modules

What are Autofac Modules?

I’ve been writing a little bit about Autofac and why it’s rad, but today I want to talk about Autofac modules. In my previous post on this, I talk about one of drawbacks to the constructor dependency pattern is that at some point in your application, generally in the entry point, you get allllll of this spaghetti code that is the setup for your code base.

Essentially, we’ve balanced having nice clean testable classes with having a really messy spot in the code. But it’s only ONE spot and the rest of your code is nice. So it’s a decent trade off. But we can do better than that, can’t we?

Autofac modules!

We can use Autofac modules to organize some of the code that we have in our entry point into logical groupings. So an Autofac module is an implementation of a class that registers types to our dependency container to be resolved at a later time. You could do this all in one big module, but like many things in programming, having some giant monolothic thing that does ALLLL the work usually isn’t the best.

An Example of Converting to Autofac Modules

Let’s create a simple application as an example. I’ll describe it in words, and then I’ll toss up some code to show a simple representation if it. We’ll assume we’re using dependencies passed as interfaces via constructors as one of our best practices, which makes this conversion much easier!

So our app will have a main window with a main content area and a header area. These will be represented by three objects. Our application will also have a logger instance that we pass around so classes that need logging abilities can take an ILogger in their constructor. But our logger will have some simple configuration that we need to do before we use it.

Let’s assume to start our Program.cs file looks like this:

internal sealed class Program
{
    private static void Main(string[] args)
    {
        var logger = new FileLogger();
        logger.LogLevel = LogLevel.Debug;
        logger.FilePath = "log.txt";

        var header = new FancyHeader(logger);
        var content = BoringMainContent();
        var window = new MainWindow(header, content);
        window.Show();
    }
}

Before getting comfortable with Autofac, my initial first step would be to logically group things in the main method. In this particular case, we have something simple and surprise… it’s all grouped. But my next step would usually be to pull these things out into their own methods. I do this because it helps me identify if my groupings make sense and where my dependencies are. Let’s try it!

internal sealed class Program
{
    private static void Main(string[] args)
    {
        var logger = InitializeLogging();
        var window = InitializeGui(logger);
        window.Show();
    }

    // no params passed in, so no dependencies
    // return value is an ILogger, so we have a
    // logical grouping that will provide us a logger
    private static ILogger InitializeLogging()
    {
        var logger = new FileLogger();
        logger.LogLevel = LogLevel.Debug;
        logger.FilePath = "log.txt";
        return logger;
    }

    // only parameter is a logger, so that's our dependency
    // return value is a window, so this grouping provides
    // a window for us
    private IWindow InitializeGui(ILogger logger)
    {
        var header = new FancyHeader(logger);
        var content = BoringMainContent();
        var window = new MainWindow(header, content);
        return window;
    }
}

Alright cool. So yes, this is a bit of extra code compared to the initial example, but I promise you grouping these things out into separate methods as a starting point when you have a LOT of initialization logic will help a ton. Once they are in methods, you can pull them out into their own classes. Refactoring 101 for single responsibility principle going on here ūüėČ BUT, we’re interested in Autofac. So what’s the next step?

We have two logical groupings going on here in our example. One is logging and the other is for the GUI. So we can actually go ahead and make two Autofac modules that do this work for us.

public sealed class LoggingModule : Module
{
    protected override void Load(ContainerBuilder builder)
    {
        builder
            .RegisterType<FileLogger>()
            .AsImplementedInterfaces() // FileLogger will be resolved as an ILogger
            .SingleInstance() // we only ever need to use one logger instance for our app
            .OnActivated(x =>
            {
                // this handles our extra setup we had for this object
                x.Instance.LogLevel = LogLevel.Debug;
                x.Instance.FilePath = "log.txt";
            });
    }
}

public sealed class GuiModule : Module
{
    protected override void Load(ContainerBuilder builder)
    {
        builder
            .RegisterType<FancyHeader>() // this has a dependency on ILogger, but autofac will figure it out for us
            .AsImplementedInterfaces() // FancyHeader will be resolved as IHeader
            .SingleInstance(); // we only ever need to use one instance for our app
        builder
            .RegisterType<BoringMainContent>()
            .AsImplementedInterfaces() // BoringMainContent will be resolved as IContent
            .SingleInstance(); // we only ever need to use one instance for our app
        builder
            .RegisterType<MainWindow>() // Autofac will resolve our IHeader and IContent dependencies for us
            .AsImplementedInterfaces() // MainWindow will be resolved as IWindow
            .SingleInstance(); // we only ever need to use one instance for our app
    }
}

And those are our two logical groupings for modules! So, how do we use this and what does our Main() method look like now? I’ll demonstrate with one way that works for a couple modules, but I want to follow up with another post that talks about dynamically loading modules. If you can imagine this scenario blown out across MANY modules, you’ll understand why it might be helpful.

The idea for our Main() method is that we just want to resolve the one main dependency manually and let Autofac do the rest. So in this case, it’s our MainWindow.

private static void Main(string[] args)
{
    // create an autofac container builder
    var containerBuilder = new ContainerBuilder();

    // manually register our two new modules we made
    containerBuilder.RegisterModule<LoggingModule>();
    containerBuilder.RegisterModule<GuiModule >();

    // create the dependency container
    var container = containerBuilder.Build();

    // resolve and use our main dependency by it's interface
    // (because we shouldn't care what the implementation is...
    // that was up to the configuration via modules!)
    var window = container.Resolve<IWindow>();
    window.Show();
}

In Summary…

This example showed us how to group your main initialization logic out into groups that would play nice as Autofac modules. In a really simple example, having modules might look like bloated extra code, but it already illustrated that your entry point is very simple and follows a pattern to extend (just register another module for more dependencies… and I’ll add more on this later). There’s also an obvious way to group more new logic into your application for dependencies! So discussed logging and GUI initialization, but you could extend this to:

  • User Settings
  • Analytics/Telemetry
  • Error Reporting
  • Database Configuration
  • Etc… Just add more modules!

Sometimes the pain of having a really hectic entry point isn’t realized until you’ve had to work on teams where people are modifying the same beast of an entry point all the time:

  • Simple merge conflicts in your “using” statements… Because there’s hundreds of lines of using statements at the top of the file
  • Visual studio actually CANNOT use intellisense properly when the file gets too unwieldly
  • The debugger cannot resolve variables properly when the main entry point gets too big
  • Merging and auto-conflict resolution sometimes results in code just getting blown away in the entry point… And good luck finding what went wrong in your thousands of lines of initilization

So what’s next? Well, if you keep building out your app you might notice you have tons of modules now. Your single GUI module might have to get broken out into modules for certain parts of the GUI, for example, just to keep them more manageable. Maybe you want plugins to extend the application dynamically, which is really powerful! Our method for registering modules just isn’t really extensible at that point, but it’s very explicit. I’ll be sharing some information about automatic Autofac module discovery and registration next!


What Makes Good Code? – Should Every Class Have An Interface? Pt 1

What Makes Good Code? - Should Every Class Have An Interface?

What’s An Interface?

I mentioned in the first post of this series that I’ll likely be referring to C# in most of these posts. I think the concept of an interface in C# extends to other languages–sometimes by a different name–so the discussion here may still be applicable. Some examples in C++, Java,¬†and Python to get you going for comparisons.

From MSDN:

An interface contains definitions for a group of related functionalities that a class or a struct can implement.
By using interfaces, you can, for example, include behavior from multiple sources in a class. That capability is important in C# because the language doesn’t support multiple inheritance of classes. In addition, you must use an interface if you want to simulate inheritance for structs, because they can’t actually inherit from another struct or class.

It’s also important to note that an interface¬†decouples the definition of something from its implementation. Decoupled code is, in general, something that programmers are always after. If we refer back to the¬†points I defined for what makes good code (again, in my opinion), we can see how interfaces should help with that.

  • Extensibility: Referring to interfaces in code instead of concrete classes allows a developer to swap out the implementation easier (i.e. extend support for different data providers in your data layer). They provide a specification to be met should a developer want to extend the code base with new concrete implementations.
  • Maintainability:¬†Interfaces make refactoring an easier job (when the interface signature doesn’t have to change). A developer can get the flexibility of modifying the implementation that already exists or creating a new one provided that it meets the interface.
  • Testability: Referring to interfaces in code instead of concrete classes allows mocking frameworks to leverage mocked objects so that true unit tests are easier to write.
  • Readability: I’m neutral on this. I don’t think interfaces are overly helpful for making code more readable, but I don’t think they inherently make code harder to read.

I’m only trying to focus on¬†some of the pro’s here, and we’ll use this sub-series to explore if these hold true across the board. So… should¬†every class have a backing¬†interface?

An Example

Let’s walk through a little example. In this example, we’ll look at an object that “does stuff”, but it requires something that can do a string lookup to “do stuff” with. We’ll look at how using an interface can make this type of code extensible!

First, here is our interface that we’ll use for looking up strings:

public interface IStringLookup
{
    string GetString(string name);
}

And here is our first implementation of something that can lookup strings for us. It’ll just lookup an XML node and pull a value from it. (How it actually does this stuff isn’t really important for the example, which is why I’m glossing over it):

public sealed class XmlStringLookup : IStringLookup
{
    private readonly XmlDocument _xmlDocument;

    public XmlStringLookup(XmlDocument xmlDocument)
    {
        _xmlDocument = xmlDocument;
    }

    public string GetString(string name)
    {
        return _xmlDocument
            .GetElementsByTagName(name)
            .Cast<XmlElement>()
            .First()
            .Value;
    }
}

This will be used to plug into the rest of the code:

private static int Main(string[] args)
{
    var obj = CreateObj();
    var stringLookup = CreateStringLookup();
    
    obj.DoStuff(stringLookup);
 
    return 0;
}
 
private static IMyObject CreateObj()
{
    return new MyObject();
}
 
private static IStringLookup CreateStringLookup()
{
    return new XmlStringLookup(new XmlDocument());
}
 
public interface IMyObject
{
    void DoStuff(IStringLookup stringLookup);
}
 
public class MyObject : IMyObject
{
    public void DoStuff(IStringLookup stringLookup)
    {
        var theFancyString = stringLookup.GetString("FancyString");
        
        // TODO: do stuff with this string
    }
}

In the code snippet above, you’ll see our Main() method creating an instance of “MyObject” which is the thing that’s going to “DoStuff” with our XML string lookup. The important thing to note is that the DoStuff method takes in the interface IStringLookup that our XML class implements.

Now, XML string lookups are great, but let’s show why interfaces make this code extensible. Let’s swap out an XML lookup for an overly simplified CSV string lookup! Here’s the implementation:

public sealed class CsvStringLookup : IStringLookup
{
    private readonly StreamReader _reader;
 
    public CsvStringLookup(StreamReader reader)
    {
        _reader = reader;
    }
 
    public string GetString(string name)
    {
        string line;
        while ((line = _reader.ReadLine()) != null)
        {
            var split = line.Split(',');
            if (split[0] != name)
            {
                continue;
            }
 
            return split[1];
        }
 
        throw new InvalidOperationException("Not found.");
    }
}

Now to leverage this class, we only need to modify ONE line of code from the original posting! Just modify CreateStringLookup() to be:

private static IStringLookup CreateStringLookup()
{
    return new CsvStringLookup(new StreamReader(File.OpenRead(@"pathtosomefile.txt")));
}

And voila! We’ve been able to extend our code to use a COMPLETELY different implementation of a string lookup with relatively no code change. You could make the argument that if you needed to modify the implementation for a buggy class that as long as you were adhering to the interface, you wouldn’t need to modify much surrounding code (just like this example). This would be a point towards improved maintainability in code.

“But wait!” you shout, “I could have done the EXACT same thing with an abstract class instead of the IStringLookup interface you big dummy! Interfaces are garbage!”

And you wouldn’t be wrong about the abstract class part! It’s totally true that IStringLookup could instead have been an abstract class like StringLookupBase (or something…) and¬†the benefits would still apply! That’s a really interesting point, so let’s keep that in mind as we continue on through out this whole series. The little lesson here? It’s not the interface that gives us this bonus, it’s the API boundary and level of abstraction we introduced (something that does string lookups). Both an interface and abstract class happen to help us a lot here.

Continue to Part 2


Staying Productive

Staying Productive

Background

I wrote a post a long while back about how I started to use Google Keep to get myself organized. Google Keep has been a go-to app for me on my phone for a long time now. I love using it to make lists of things, and I find it much more convenient than a paper notebook.

Don’t get me wrong–I think a paper notebook still has plenty of uses! I love my notebook for long running meetings with open-ended discussions or brain storming sessions. It’s great to be able to take a pen/pencil and doodle down any idea that comes to mind. When I’m having a free-form conversation, I need a free-form way to take notes.

However, my phone is something I almost always have with me–and my paper notebook isn’t. My phone allows me to take my Google Keep notes and email them to myself. It allows me to have a reminder right on my homescreen every time I unlock my phone. It’s just more convenient.

But something happened since the last time I wrote about using Google Keep. I use it more and more, and at some point I felt like I was getting less and less done. This is less about in the office and more about how productive I feel at home. So how can I be getting less done (or at least feeling that way) if I’m taking my own advice and using Google Keep to hack my TODO list?

I have tons of lists and no actions.

I think that’s the big take away. I list all the things I’m thinking about, and I keep making more lists. There’s no time frame around actioning things with the lists I’m making! So, in the spirit of continuous improvement, I set out to make some changes.

Inspiration

I know I wanted to make some changes with this part of my life because it was starting to weigh down on me; I didn’t feel productive. But I knew this wasn’t going to be something I’d answer over night. I kept my eyes and ears open for ideas for a little while before I thought up some tweaks.

The first thing I came across while living my alter ego was an Instagram post by Big J. Big J is this¬†guy that’s incredibly big and incredibly strong. He’s lived the bodybuilding life and has a lot to show for it… And because being successful in the bodybuilding and strength world means being extremely motivated and hardworking, it’s no surprise I picked up this little bit from Big J:

Simple idea, right? Put some time into planning your schedule for the upcoming days. It almost seems to obvious to not be doing. I mean, don’t I do this already? I have meeting invites and stuff in my calendar for work… But, that’s right! I don’t have anything in my calendar for my own personal things that I like to do outside of work. Hmmm…

The next little tip to push me along was after a conversation with a teammate of mine at work. Our conversation was mostly about work-life balance, but my colleague was telling me about something he was trying out around forming habits. Essentially, over a period of time he’s been recording his success at keeping on top of good habits and identifying reasons why he’s sometimes missing them. Definitely right up the continuous improvement alley! Another great point he brought up was that good habits need to be introduced one at a time and only once you’ve been consistent with your other habits. By adding too much at once, you can derail the whole good habit process.

The “Staying Productive” Hack

This is the hack I’ve been implementing for a bit over a week now, and it’s helped tremendously with feeling productive!

Every night when I’m laying in bed, I spend about 5-15 minutes with my phone and I schedule personal activities in my calendar for the following day.

There it is. It’s not rocket science or something Earth shattering, but it’s definitely helping. Taking a page out of Big J’s book and a tip from my colleague, I’ve modified my schedule to introduce a very brief planning period every day. And it’s just one change that I think is helping introduce a good habit into my life.

This has helped me:

  • Stay on top of prepping food (which is a big part of the lifestyle I try to live)
  • Schedule time to relax (yes, I even schedule time for things like video games!)
  • Schedule time to blog (I run three blogs, and sometimes finding time to write feels like a chore)
  • Work on personal projects
  • … Feel like I’m being productive.

And no, I didn’t drop Google Keep–It actually helps feed into my scheduling! It’s great to look over my lists of things and try to create actions for them.

Next Steps

This simple hack¬†is not only nothing particularly fancy, it’s also not bullet proof! But that’s okay when you’re always trying to continuously improve. Some snags I’ve run into or things I’ve thought about are:

  • How do I¬†adjust my planned schedule when unexpected things come up? If someone drops in for a visit out of nowhere, or my car breaks down, or my dog decides to tear up the furniture, how do I make sure I can continue on with my planned schedule? Right now some things drop off the schedule or I push other things off to compensate. This hasn’t been too big of a problem so far, but sometimes this has a bit of a landslide effect and it makes the rest of the day feel unproductive. A little bit of dirt in the cogs seems to throw the whole thing off for me! This is something I’ll be thinking about as I encounter it and I’ll try to thing of some easy solutions.
  • How can I be more like Big J?! Aside from being bigger and stronger, how can I plan for more days? Big J plans every Sunday but I plan every night for the next day. Is there a happy medium? Planning every Sunday would potentially amplify the landslide effect I previously mentioned, but it would be a convenient single planning session for the whole week. Perhaps I’ll continue with the advice of my colleague and modify one part of my new habit at a time and look at planning for an extra day at a time and see how that goes!

If you’ve been making checklists and find that you’re unable to action items, try this approach! It takes only a few minutes every day, and so far I’ve been having great success in feeling productive. It’s not difficult, so it’s worth a try!


One on One Evolution

Background

I’m a “middle manager” where I work, but that means a whole bunch of things. My everyday tasks primarily consist of programming, but I do a bunch of work to interface with other departments and teams, and I play a role in managing people on… well, the “people” side of things. For the latter part, I refer to that as people leadership.

I think it’s pretty easy to look at some of the aspects of people leadership and dismiss them as “fluffy” or needless… I consider myself a logical/technical thinker, so I have that frame of mind¬†sometimes. However, I do see the value in¬†actually being able to support my¬†team so that they can operate at the best of their abilities. I try to find ways to do that without it seeming to them like I’m doing “fluffy leadership things”, and in turn, I don’t feel that way about it either. With that in mind, I had previously set out with ways to accommodate team feedback in a way that works best for them.

One on Ones: The Early Days

I worked with my HR manager a couple of years back to establish a one on one template that I could use with the developers on my team. The goal was to be able to identify points of conversation since the last time we met, the individual’s current situation (both positive and concerns), and then identify goals. Ideally, the individual is able to fill this out on the form in as much detail as necessary for us to be able to have a conversation about it later.

I didn’t want this to seem like a chore for people so I’ve tried to identify why this is useful for the individual and for myself. For the individual, it gives them an avenue to discuss anything that’s becoming a problem over the period of a few weeks (i.e. something not obvious all at once) or be able to identify successes in their work. It also allows them to reflect on their goals that they want to set in their career, current projects, or even things outside of work (because¬†improving your abilities outside of work is a good thing too). For me, it provides¬†better insight into the¬†trend of problems people are experiencing, their contributions to their current projects, and even helps me see where people are at with their career goals. Both parties are able to benefit from these!

I’ve left it open in the past as to how people submit them. Written? Sure. Digital? Sure. Whatever is easiest for the individual provided I can get it a couple of¬†days before we meet. I’ve also left it open ended as to how much of the form they fill in. Based on the trends, I think people see value in having more content but sometimes the goal setting is a bit of a grey area. People might be between setting different goals and want to wait to discuss those things. The best part is, I don’t need to hassle the team to fill in more… They just do a great job of providing information for me!

One on Ones: Continuous Improvement

I’m all for continuous improvement in our development¬†processes that we have as well as our management processes. With that said, we’ve made a few tweaks to the one on ones recently that I think have had a great positive impact.

  • Digitized: I’ve got everyone on board with digitizing their one on ones. This is incredibly handy for being able to search for content later on (instead of sifting through paper), so I get a huge benefit from it. Each individual can probably benefit from this too if their ever looking for things we discussed. Archiving digital documents¬†has so many benefits over the paper counterparts that it’s hard to imagine going back to these mostly being paper-based. I can easily print off copies for the individual if they lose them (or if I lose them) and it makes life easier for me at year end. I can quickly scan over documents on my computer to get a good overview of a person’s year right on my laptop.
  • Nick’s Notes: A little tweak to the one on one process is that with the digital copies, I can put in highlighted notes. This allows me to get down my feedback to the individuals before we meet. In the past, I requested documents a couple of days before we meet so I can try to action what I can ahead of time. However, adding my notes and getting it back to the individual before we meet let’s them know things I want to dive deeper on. It gives them an opportunity to prepare their thoughts, and from what I’ve heard, this is really beneficial for them. The other positive thing is that it let’s me provide them kudos on certain things that I don’t necessarily need to spend a lot of time talking about them with one on one. It’s improved the efficiency of our meetings, and I think it benefits both sides.

What’s Next?

I’ll be honest in that I don’t have any next steps planned for these one on ones. But that’s okay! I’m going to let a few more rounds of these go through before I try to tweak the process. This let’s me get a feel for how the changes are playing out and then from there I can see where I might need to make some improvements.

If you don’t have a semi-structured system in place for your one on ones, I highly recommend it! Make it something you can at least get a feel for how successful they are. If you can gauge their effectiveness, then you can try to tweak the process over time to improve¬†it! You’ll benefit from the information, and your team will benefit from you providing support for them.


Code Smells ‚Äď Issue Number 2

Code Smells (Image from http://www.sxc.hu/)

Code Smells

Welcome to the second edition of Code Smells! Periodically I’ll be posting about how to detect code smells and what they mean in terms of the big picture of your code. The previous installment can be found right here.

What’s a code smell? Wikipedia says it perfectly:

In¬†computer programming,¬†code smell¬†is any¬†symptom¬†in the¬†source code¬†of a¬†program¬†that possibly indicates a deeper problem. Code smells are usually not¬†bugs‚ÄĒthey are not technically incorrect and don’t currently prevent the program from functioning. Instead, they indicate weaknesses in design that may be slowing down development or increasing the risk of bugs or failures in the future.

Onto the code smells!

The Stink List

Code Smell #4: (Thanks to reddit user fkaginstrom) You have an large number of parameters being passed in to your function call. Functions that take in a ton of parameters stink for a few reasons. How many is too many though? This is a topic that people have debated all over The Internet. This Stack Overflow answer even quotes an author saying to never have more than three parameters in a function. In my opinion? There’s no fixed number. It’s going to vary from situation to situation, project to project, class to class, and method to method. Putting a fixed number on it is sort of setting up a rule to be broken.

What can you do to avoid this kind of smell? This C#-based Stack Overflow thread has a bunch of great ideas. One simple solution is just to bundle things into logical groupings of data. An example (although, it’s potentially a poor example since it’s only two parameters) is x and y coordinates. You can bundle these into a custom point type and pass this into functions. Now a function that may have taken four pairs of coordinates is reduced from eight parameters down to four. This approach also introduces the dependency on your custom type for your function, but I’m just offering it up as an option. If you’re always passing around the same group of X pieces of data around, it may make sense to bundle them into a single container type.

A side effect of reducing the number of parameters your functions require is readability. It might seem minimal, but having functions with only a handful of parameters keeps them from becoming¬†unwieldy and much easier to understand when scanning through code. Readability is sometimes overlooked by developers, but when you’re in a team (and most developers work in teams), it goes a long way.

Code Smell #5: (Thanks to¬†reddit¬†user¬†fkaginstrom) Your class has a large number of methods. If we keep the Single Responsibility Principle in mind (which states that a class should have one reason to change), it’s a warning sign that we might be creeping in on violating it. How? If more and more methods keep getting added, more responsibilities/capabilities can sneak in. This MSDN blog article also highlights some examples of the Single Responsibility Principle. Essentially, as the methods within your class grow in numbers, your class becomes responsible for more types of things. If you later on want to use ¬†just one of those things in a different context, you’re now required to use one big heavy-weight type. Of course, this heavy-weight type comes with it’s own bundle of dependencies, setup requirements, and so on.

How do you avoid this? You can start by refactoring your monstrous type into multiple types. If your type has 12 methods that it defines, and they fall under three general categories of functionality, consider making three interfaces to group the functionality. Then you might consider adding three classes that stay true to these interfaces. The MSDN article I mentioned before does a good job of explaining  how this kind o approach works.

Code Smell #6: Your single method has grown to hundreds of lines. This is one code smell I find that newer programmers introduce more frequently than experienced programmers. However, when you’re working on an enormous code-base, sometimes this type of thing sneaks right up on you. So what’s the problem with having one method do a ton of things? It’s a convenience, isn’t it? let’s say someone only has to call one method that can launch a rocket, play golf, and invest in the stock market while filming a block-buster movie. That’s power and ease of use, no?

This related to Code Smell #5, in my opinion. The convenience of being able to call a method that does all sorts of fancy things at once is the exact inverse of the problem you face when you want to test the method. If I just want to test that I can successfully start the burners in the rocket, I have no choice but to call the method that does everything. What makes this problem even worse is that once your code has been structured this way, breaking down big methods into smaller methods can prove to be a challenge. When you see how dependencies are passed down the call hierarchy, or where certain classes have knowledge of others, things become scary.

I’ll give one real life example of something I saw recently in a particular code base. A test had to be written to cover a problematic area of code that had been refactored. There needed to be some sort of verification in code that proved this section was behaving as expected under particular conditions. Great stuff. Except the section of code existed inside of a method that did the following:

  • UI interaction
  • Database read
  • Data processing
  • File read
  • Data processing 2
  • Database write
  • External disk operation* (This one was pretty specific to the project I’m describing, but it wasn’t just a simple file read/write)
  • File write
  • UI interaction

Where the highlighted “Data processing 2” is the section of the method that needed testing. How’s that for fun? In order to test this one section properly it required refactoring of all of the encompassing code so that we could test it as a unit.

Have your own code smells? Share them in the comments. Follow Dev Leader on social media outlets to see code smell updates as they come out!

Nick Cosentino – LinkedIn
Nick Cosentino – Twitter
Dev Leader – Facebook
Dev Leader – Google+


Code Smells – Issue Number 1

Code Smells (Image from http://www.sxc.hu/)

Background

I thought this might be kind of fun (fun can also be read as “upsetting”), so I’m giving it a shot. It’s pretty frequent as programmers we go back and revisit some code and find ourselves shaking our heads at what we see. These code smells often don’t show their faces when they’re being created, so don’t beat yourself (or anyone else) up just yet. Common signs you’ve stumbled upon a code smell are when you find yourself saying:

How could that co-op have possibly coded this?! Blast those interns!

Or

What the heck was John thinking when he put this together?! Does he not have a brain?!

Or

No wonder we find so many bugs in this part of code! Look what Jane did!

But it never truly hits home until you get one of these:

What is this crap?! This is by far the worst code I have ever seen. How cou–Oh. Wait. I did that.

Code is always a work in progress. If it’s not, it’s because you’re writing a one off script or your code doesn’t do much of anything. Our skills as programmers are always transforming as are our perspectives. You’re guaranteed to have one of these moments if you’re programming long enough and look back on your code that was once The Pinnacle of Awesome.

With that said, I’m hoping to share some code smells that come up as I see them in my own projects or when talking with friends/colleagues. You might be about to type up one of these code smells, so pay attention! I don’t know how frequently I’ll put one of these posts together, but I might as well start now. Every time I get a handful of code smells I’ll try to push something out to The Interwebz.

The Stink List

Code Smell #1: Your variable is named or prefixed with “temp”, “tmp”, or some variation of “temporary”. This is unnecessary. If you have a variable, by definition it’s something that’s temporary. Nothing in code lasts for forever. You’re just lengthening a variable name or not putting enough thought into a good name.

Code Smell #2: Your variable is one character long. The exception to this is probably for simple loops. You almost always see code that is iterating over a counting variable “i”. Maybe that’s not so bad. If you nest three loops and you have for i, j, and k, things can get messy. If you find you’re using single character names outside of loops… STOP. Just name your variable something that won’t be a puzzle for someone one day from now.

Code Smell #3: You prefix things as “New”, “First”, “Last”, or some other definitive/completely ambiguous position. If you have something that’s “Newest” now and then tomorrow a new one is made, you now have to go change all of your code that used “Newest”, because it’s not the newest now. Same with something like “old” or “new”. It’s the “old” one now, but what happens when your “new” one becomes old because of a third generation? Now you have two olds and a new. What the heck are you going to do? Pick a good name from the start.

Have your own code smells? Share them in the comments. Follow Dev Leader on social media outlets to see code smell updates as they come out!

Nick Cosentino – LinkedIn
Nick Cosentino – Twitter
Dev Leader – Facebook
Dev Leader – Google+


Recognition – Weekly Article Dump

Recognition - Weekly Article Dump (Image from http://www.sxc.hu/)

Recognition – Weekly Article Dump

Not all of the articles this week touch on recognition, and to be honest, I didn’t pick it as a theme for the articles either. Recognition is more a topic of discussion that’s come up over the last week at Magnet Forensics, where I work. Being a team lead and part of the management team at Magnet, I’m often part of conversations about motivation. Providing recognition is an excellent way to motivate your staff and shows that you truly appreciate them. We’ve been trying to get better at recognizing staff for doing an awesome job–especially because we have so many awesome people working with us. It’s pretty obvious with our Profit Hot 50 placement that we’ve got some kick-ass people.

Recognition, whether it’s one-on-one or in a public setting, has a huge impact. I don’t even mean recognition in the form of compensation (e.g. bonus or salary raise). Just giving someone recognition for the awesome work they’ve done–plain and simple. It’s a great way to let someone know that their hard work and commitment isn’t going unnoticed. Sure, if they’re developing products, making sales, or acquiring leads there are certain metrics that indicate they’re doing a great job, but recognition is that additional feedback you can provide to really drive the point home. It motivates people and often has a bigger impact than providing compensation.

I want to make a conscious effort to try and recognize some of my colleagues on Dev Leader, going forward, when the opportunity presents itself. I’m always learning from the people I work with and there’s always something great I can say about them. Why not give them a public acknowledgement?

I also have a little surprise coming from a friend and colleague of mine, Tayfun Uzun, early next week, so keep your eyes open for that!

Articles

  • Job Titles and Responsibilities: Last week I wrote about my thoughts on the true role of job titles. As soon as you start to look at your job title as something that defines your limits, you’re on the wrong path. Your job title should define what you’re responsible for, but it’s by no means supposed to put limits on what you can do. Check it out and let me know what you think! Do you feel like job titles should keep people to only a certain set of tasks? Do you feel like having set responsibilities is useful at all?
  • How Strong Is Your Bench: Having a successful company is all about having the right people on board.¬†Sylvia Hewlett¬†writes about what it means to have a rock solid roster within your company. Some of the things include avoiding hiring clones of people exactly like yourself and instead trying to diversify the skill sets within your company. Absolutely true!
  • 8 Steps for Engineering Leaders to Keep the Peace: There seems to be a natural tendency for engineers or people implementing components of a product to push back on product managers or people who decide how a product/service should be.¬†Steven Sinofsky¬†discusses the importance of being an effective engineering leader and ensuring proper communication between engineering leaders and people like PMs or founders. Open and transparent communication is key and helps remind the other party that you do in fact have the same end-goal.
  • Top Tips To Being a Great Mentor: In this article, James Caan¬†provides four key points for being a better mentor. Patience, honesty, positivity, and focus are the four pillars that James describes. Patience and honesty, in my opinion, are the most important but I certainly agree with all four!
  • Leading a Customer-Centric Transformation: Hopefully it’s not surprising, but customers are what your business should be geared toward. As a result, it makes sense that leading customer-centric employees would be beneficial. Don Peppers¬†outlines six things to focus on to make this transformation necessary. It ties in with my post on avoiding organizational silos.
  • The Dark Side Of Software Development That No One Talks About: Don’t be scared that this article mentions software development if you’re not a programmer! It touches on some great points about having a career in software development, so even if you’re not a developer yourself, it sheds some light on some more broad issues. John Sonmez writes about why software developers seem like jerks sometimes and what you can do about it. It seems to boil down to intelligence being a deciding factor for how well you program, so lording your intelligence over other people makes you superior. And because our own intelligence is something we all hold personally, we can get defensive about it pretty easily. John suggests that part of the solution is trying to simplify aspects of software development.
  • How to Win Loyalty From Other People: To be a successful leader, the people you lead need to be loyal to you.¬†Deepak Chopra¬†writes about seven suggestions for building up loyalty and among them “abstaining from disloyalty” is one of my favourites. If you act differently behind people’s backs compared to when you’re leading them, it may come back to bite you later. It’s also crucial to pay attention to each individual’s personal differences to ensure they feel understood.
  • Strategies for Dealing with Randomness in Business:¬†Don Peppers¬†twice on the list this week! Things in life and business aren’t always predictable for us. It’s just how things are. Are you properly set up to deal with uncertainty in your business though? Remain agile!
  • 10 Quotes All Entrepreneurs Should Memorize: How about some quotes to motivate you? Joel Peterson¬†lists 10 great quotes for entrepreneurs, but I think they carry over to anyone working in a startup. Don’t be afraid to fail and keep moving forward to improve!
  • The Two Biggest Distractions ‚Äď And What to Do About Them: Distractions are ever-increasing in the workplace, but have you ever considered the differences between the different types of distractions?¬†Daniel Goleman¬†discusses two very different types of distractions: sensory and emotional. I hadn’t really noticed it, but often we find ourselves consciously trying to avoid sensory distractions. If our phone lights up or we get an email notification, we either give in or we make an effort to try and reduce the effect of these distractions. But an emotional distraction is much worse. If something tweaks your emotions the wrong way at work, it often has a bigger impact and it’s usually unexpected.

My take away point for this week regarding recognition: Do it early and do it often. Remember to follow Dev Leader on social media outlets to get these updates through the week!

Nick Cosentino – LinkedIn
Nick Cosentino – Twitter
Dev Leader – Facebook
Dev Leader – Google+

You can also check out Dev Leader on FlipBoard.


Raspberry Pi + WordPress => PiPress

Raspberry Pi

Background

In the past, I’ve dabbled a bit with hosting my own server on a spare outdated box that likely should have been thrown out. My least favourite thing to do is sit down and tinker with trying to get services and such configured so that they all work together… But once it’s working, it’s glorious. Enter the¬†Raspberry Pi.

Earlier this year I decided I wanted to get a Pi. Why? I wasn’t too sure… But they’re cheap and nothing bad could come of it ūüôā Once I got the thing up and running I was reading about how people were using them. Hosting a WordPress site was definitely one of the uses, so I figured I’d try my hand at that. There are other guides on The Internet about how to do this, but this is what got me up and running.

Disclaimer: A *lot* of this is taken from IQ Jar where there’s been an absolutely amazing outline posted. Although I am repeating a lot of the same steps here, I wanted to post what I felt was a complete install guide. I found myself going back and forth between a few resources, so hopefully this will reduce that issue for you. I do very highly recommend you have a look at IQ Jar though.

Raspberry Pi: What & Where To Buy?

This part is pretty open ended. Let’s start with the “what” portion of things.

The Raspberry Pi is just the board. If you’re totally content with buying a board without a case that you can’t even power up, then you’re all set. Although, if that’s the case, you probably don’t need to read anymore of this! It’s common to pick up the following to get your Raspberry Pi working:

  • Raspberry Pi
  • Case
  • Power Adapter
  • SD Card

But once you’ve got those things, you still can’t do too much with your Raspberry Pi aside from powering it up. Some other things you’ll likely want:

  • USB Wireless Adapter
  • USB Keyboard
  • HDMI Cable

NOTE: Pay special attention to what wireless adapters and SD cards can be used with a Pi out of the box. You’ll want to save yourself the headache if others have confirmed the parts you’re looking at purchasing are compatible.

So now that you have an idea what things you’ll need to pickup, where do you get them? If you search The Googles for where to buy any of this stuff, you’ll probably get a ton of hits. Maybe that’s not totally useful for you. I’d suggest the following sites:

  • Amazon: I got everything I needed off of Amazon in one fell swoop. You can even find some combo deals that include the Raspberry Pi and a case. Heck, some even come with the SD card too!
  • ModMyPi: A great resource… There’s tons of options on this site and it’s specifically for the Pi. Probably can’t go wrong by looking here.
  • Ebay: Ol’ Faithful. Lots of options here too, just like Amazon. Bound to find something that fits the bill.
  • Newark: There are a great deal of product offerings and resources on Newark. Check them out for full packages, accessories, and additional guides/walk-throughs.

The Walkthrough

First thing: there are a million ways to do this. I’m not going to explore all the options here because I’m not an expert and because I want to provide you with my own steps that worked for me. As soon as I deviate from that… Things will get messy and complicated ūüôā

  1. Download a Raspbian “Wheezy” image from the Raspberry Pi website. This is the image of the operating system your Pi will use.
  2. Download Win32 Disk Imager. You’ll need this to get the image of the operating system onto your SD card.
  3. Once both downloads have completed, run Win32 Disk Imager and use it to write the image to your SD card. You’ll need a card reader/writer in your computer, but this is pretty standard these days.
  4. Take your card out of your computer and pop it into your Pi. You should have your Pi all setup now with power, USB keyboard, USB WIFI adapter, and an HDMI cable plugged into your TV/monitor.
  5. When you power up your Pi, you should be taken to an initialization/configuration menu. If it ain’t working, there are a million and one trouble shooting guides.
  6. Some things I suggest you get going while you’re here:
    • Reduce graphics memory to the minimum (16). Should help with performance.
    • Give yourself a modest overclock. Not sure what’s deemed safe, but I went somewhere in the middle.
    • Enable¬†SSH. Later on you’ll never even need to be near your Pi. I can actually control my Pi from my phone with¬†this sweet app.
  7. Once you’ve got things how you want, expand the file system and reboot your Pi.
  8. When the Raspberry Pi is back up and running, you need to login to your credentials and then type “startx” and press enter. This will get you into the GUI portion of things.

Anyone well versed in *nix may not need or want to do this, but I found it easiest this way. At this point, get your wifi and everything setup. Your blog won’t be very useful if your Pi isn’t on the internet. Having the GUI portion of Raspbian will also let you quickly search the net and pull up articles if you’re running into any oddities with the components you bought. Anyway, now that your Raspberry Pi is working with all the parts you purchased, on with the rest of it:

  1. Open up a terminal. You’re going to need it for basically everything else in this guide. We’re going to start by turning your Raspberry Pi into a LAMP server.
  2. Type “sudo apt-get update” to update the various packages on your Pi.
  3. sudo apt-get install apache2” to download and install the Apache web server. You’ll want to say yes when it asks for confirmation (and same whenever this happens for the other packages we need to install).
  4. sudo nano /etc/apache2/apache2.conf” to open up the apache configuration. You’ll want to stick “ServerName localhost” at the very end of this file and then save and exit the editor. This will get rid of warnings about determining the server’s domain name.
  5. Restart apache by using “sudo service apache2 restart“. Amazing. You now have a web server.
  6. You’ll need to take care of any port forwarding to make sure your router does it’s job to get to your Pi.
  7. Next is installing PHP: “sudo apt-get install php5
  8. Type “ls /usr/lib/php5/” and take not of the entry that looks like “20100525+lfs“. Yours might be slightly different.
  9. sudo nano /etc/php5/apache2/php.ini” to open up the PHP configuration. Find the line that starts with “extension_dir” and change it so it looks like:¬†extension_dir = “/usr/lib/php5/20100525+lfs/” (except with the name of the entry you have if it was different!)
  10. sudo nano /etc/apache2/apache2.conf” to open up the apache configuration. You want to verify you have this line in there:¬†Include conf.d/*.conf
  11. Next up, you’re going to need to make a config file for Apache. This can be done by typing: “sudo nano /etc/apache2/conf.d/php.conf” and then putting the following text inside of the file:
    # PHP is an HTML-embedded scripting language which attempts to make
    # it easy for developers to write dynamically generated webpages.
    LoadModule php5_module modules/libphp5.so
    #
    # Cause the PHP interpreter to handle files with a .php extension.
    AddHandler php5-script .php
    AddType text/html .php
    #
    # Add index.php to the list of files that will be served as
    # directory indexes.
    DirectoryIndex index.phpSave and close nano when you’ve finished.
  12. To improve the performance of PHP, install APC by typing “sudo apt-get install php-apc
  13. Now that you’ve finished that, restart Apache: sudo service apache2 restart

Next we need to get MySQL up and running. This is going to serve as the backend for your WordPress installation.

  1. sudo apt-get install mysql-server mysql-client
  2. Follow up with the MySQL plugin for PHP: “sudo apt-get install php5-mysql
  3. Now that you’ve finished that, restart Apache:¬†sudo service apache2 restart

Next we’re actually going to install wordpress!

  1. In your terminal: “sudo wget¬†http://wordpress.org/latest.tar.gz
  2. Then extract the whole thing: “sudo tar -zxvf latest.tar.gz
  3. From here, you can either follow along with the official WordPress Setup instructions, or just do what I did. If you want to do what I did, just keep following here!
  4. We need to make a user in MySQL:
    1. In the terminal: “mysql -u <YOUR_ADMIN_USERNAME> -p” and hit enter.
    2. (Obviously where it says <YOUR_ADMIN_USERNAME> you should replace with the database admin username you picked)
    3. Enter your password as the prompt suggests and press enter.
    4. Next up: “CREATE DATABASE wordpress” to make the database named wordpress.
    5. And now we set privileges: “GRANT ALL PRIVILEGES ON wordpress.* TO “wordpress”@”localhost” IDENTIFIED BY “<YOUR_PASSWORD>”;” and press enter.
    6. (Again, it’s hopefully obvious to replace <YOUR_PASSWORD> with your password)
    7. FLUSH PRIVILEGES
    8. And then finally “EXIT
  5. For my install, I put WordPress right at the root of my website. To do this, we need to copy the contents of the wordpress directory to your /var/www/ directory, but we’re *NOT* copying the wordpress directory itself there: “cp -a wordpress/.¬†/var/www/
  6. And now, we run the install script! Since we installed WordPress to the root of the website, we go to http://127.0.0.1/wp-admin/install.php in a browser. Follow the few simple steps there and you should be up and running!
  7. Remember to check the troubleshooting section on the WordPress site if something seemed to go wrong!

That’s it! You should be up and running.

What’s Next?

You might find your site is a little slow. That’s somewhat expected on your little Rapsberry Pi. Don’t fret. There are lot’s of methods for optimizing your site.

  • Check out WP Super Cache, or specifically, the guide over at IQ Jar for more information on tweaking this (it’s near the bottom of the post).
  • There’s minifying plugins for javascript and CSS files. This can do a nice job compressing the files and reducing how much data has to be transferred.
  • You can look at something like Smush.it to help with compressing your images that you serve. Again, smaller means faster.
  • Finally, you might want to test your site on GTmetrix to see if it can recommend any other optimizations to you.

Summary

To wrap up, I hope you found this guide informative. I thought a Raspberry Pi was a great way to start a little DIY project at home and it was fun to get a blog up and running on it.

References

I’m sure I consulted a million and one guides on the Internet, but the following that stick out to me (and I highly recommend you look into them):

  • IQ Jar: Crucial for getting me up and running. Specifically, these two guides here¬†and here.
  • WordPress.com: The detailed guide here for installing WordPress once you have all the prerequisites was definitely necessary.
  • GTmetrix: ¬†Serving content was relatively new to me. Once I was analyzing my page with this site, I was lead down a rabbit hole of different things to try and optimize. I highly recommend it!

  • Subscribe to Blog via Email

    Enter your email address to subscribe to this blog and receive notifications of new posts by email.

  • Nick Cosentino

    Nick Cosentino

    I have nearly a decade of professional hands on software engineering experience in parallel to leading multiple engineering teams to great results. I'm into bodybuilding, modified cards, and blogging about leadership/development topics over at http://www.devleader.ca.

    Verified Services

    View Full Profile →

  • Copyright © 1996-2010 Dev Leader. All rights reserved.
    Jarrah theme by Templates Next | Powered by WordPress