I stumbled upon this question in Stackoverflow regarding software development productivity. It’s a hard question to answer. Of course, productivity cannot be measured by the volume of codes a novice developer writes. Nor it can be measured by the too few awesome codes an experienced developer writes. It’s the marriage of both: developer productivity = code quality * code frequency.

In NESV, we strive hard to ensure a productive developer environment. We invest on tools to help developers solve problems. These tools also help us track their work. Additionally, we adapt processes and conventions to create a foundation in solving problems. Lastly, together with tools and processes, we measure certain facets of development; we have our own key performance indicators (KPIs) to observe, track, and ultimately react to possible problems affecting developers’ productivity. Below are some of our KPIs and how we get the data:

Number of resolved (or missed) issues (tickets)
We use Jira for issue tracking religiously. We have a “no ticket, no movement” policy. This is how we can track with certainty the workload of a developer including the status of assigned tasks. That’s why resolved and missed tickets are among the pillars of our KPI. This gives us an overall picture of how a project or the team is performing.

Number of reopened tickets
Another critical data we pull from Jira is reopened tickets. This highlights several areas we want to measure: QA result, comfort level of the developer, severity of the ticket, handling time, blockers of the ticket, etc. This is important in measuring the quality of code that developers write.

Number of code commits
We use Git as our version management tool and Bitbucket as our code repository. We have implemented several checkpoints in Bitbucket to capture important data points. Arguably the most important, is the frequency of code commit. Instead of line of codes, we use code commit as one of the pointers to developer’s productivity. Coupled with code review (more below), it’s a very telling tool to track the amount and quality of work done.

Code review feedbacks (or lack thereof)
Our code review happens after a developer checks in their code to their branch (not to a main branch). Bitbucket has a facility to apply feedback on committed codes. Code reviewers strictly implement our code conventions. We also include code branching and versioning as part of the review.

Number of pull requests
Merging back to a main branch e.g. `developer` or `production` branch requires a pull request and pull request requires explicit approval. The purpose of this is two-fold: we can monitor how much of a developer’s code make it through the production and second, how much of those code that gets through we have to maintain.

 

When posting multiple types of data (image, JSON, querystring, etc) to an API, you can either create multiple requests and process each data type separately or you can roll them into one and post them altogether as a multipart request. For a project that I did recently, I chose the latter. There are several benefits of rolling everything into a single call:

  • Fewer server trips
  • Less code to tie each data together
  • More elegant

The second item is the most compelling reason to me. I needed to upload multiple files and save a corresponding metadata for each file. Uploading the files and posting the data separately would’ve been messy since I needed to write persistence code just to relate each file to its corresponding data. MultipartFormDataContent is just the thing I needed. Collecting the data is very straightforward. Reading it from the ASP.NET side can be tricky, however.

Sending from the Client 

Collecting the data is basically just adding them as part of MultipartFormDataContent‘s collection. It can have several types as long as they are derived from the HttpContent class.

            //Create a multi-part content
            var multiData = new MultipartFormDataContent();
 
            //Add all the attachments
            files.ToList()
                 .ForEach(file => {
                     var fileContent = new StreamContent(file.Open(FileMode.Open));
                     fileContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data") {
                                                                 Name       = "files",
                                                                 FileName   = "\"" + file.Name + "\""
                                                             }; 
                     fileContent.Headers.ContentType = new MediaTypeHeaderValue("image/jpeg");
                     multiData.Add(fileContent, "files");
                 });
 
            //Add the non-file data and serialise them
            multiData.Add(SerializeContent(disputes), "data");
 
            //Post altogether. Viola!
            return await Post<IEnumerable>("url/end-point", multiData);

Receiving the Data

As I mentioned, receiving the data can be a little tricky. There are several approach. One of them is to read the Request stream and parse it. I tried this and ended up following a series of requirements that would ultimately force me to upgrade multiple packages in my solution. It’s not an option so I kept poking.

Fortunately, ASP.NET makes it easy to access all content of a request. For example, posted files are exposed via Request.Files. It will also be automatically binded if you add an IEnumerable<HttpPostedFileBase> parameter to your handler. Additionally, you can access other data via Request.Form and Request.QueryString collections. In my case, the JSON data is accessible via the Request.Form[“data”] key.

        [HttpPost]
        public async Task ReceiveData(IEnumerable<HttpPostedFileBase> files) {
            try {
                return await Task.Run(() => {
                    //Get the files
                    files.ToList().ForEach(file => {
 
                        file.SaveAs(Path.Combine(savePath, filename));
                    });
 
                    //Get the data (which in the form of JSON)
                    var disputes = JsonConvert.DeserializeObject<IEnumerable>(Request.Form["data"]).ToList();
                    return Json(markedDisputes);
                });
            } catch (Exception exception) {
                return JsonError(exception.Message);
            }
        }

Lastly, I am trying to find a way through model binding so that data is automatically received as a parameter of the handler. I’ll do it in a separate post.

If you’re using Bitbucket together with Jira, you can easily resolve a ticket in Jira by adding a #resolve in your commit comment in Bitbucket. You can resolve multiple tickets, too; just add each ticket number per line with a #resolve right next to it, for example:

JCSW-561 #resolve
JCSW-560 #resolve
JCSW-559 #resolve
JCSW-558 #resolve
JCSW-557 #resolve
JCSW-549 #resolve

You’re welcome.

Scott Guthrie:

As part of this commitment I am pleased to announce today that Microsoft has signed an agreement to acquire Xamarin, a leading platform provider for mobile app development.

I expected this the moment Microsoft open-sourced .NET back in November 2014. I am actually surprised that it took them more than a year to do this. I think it’s a great move to expedite the adoption of .NET outside Windows. I suspect that Xamarin will be merged into the Visual Studio brand to avoid confusion amongst developers.

GMA Network will be covering the first leg of PiliPinas 2016 Debates today in Cagayan De Oro:

PiliPinas Debates 2016 is a debate show developed by the Commission on Elections (COMELEC). This will be the first COMELEC organized debate show in preparation for the May 9, 2016 general elections.

You can live stream the debate from Youtube. If you have a Chromecast, you can stream it directly to your television using the Google Cast plugin in Google Chrome. If you have an Apple TV, you can use Safari to Airplay the live stream to your television.

Alternatively, you can use the Youtube app which supports both Airplay and Google Cast.

If you’re a technology news junkie like me, you probably keep a list of tech news sources. Here’s my personal list of local technology news sources (independent blogs, local news outlet) that I have been collecting through the years.

ABS-CBN News | Gadgets and tech Site
GMA News Online / SciTech / Technology, Gadgets and Gaming RSS Site
Inquirer Technology^ RSS Site
mb.com.ph | Philippine News >> Technology RSS Site
MobileTechPinoy RSS Site
Newsbytes Philippines RSS Site
Rappler: Technology RSS Site
TechInAsia RSS Site
Techolo – Philippine Technology Outlook Blog RSS Site
Webgeek Philippines RSS Site
YugaTech | Philippines, Technology & Reviews RSS Site

I have included the RSS links for the old fogeys like me. I still enjoy my news in my favorite feed reader and coffee. Happy reading.

Inc. Southeast Asia:

2. Do not hire your best friends as employees
“Building a company with your good friends is a very good idea if everybody is equal,” Trikalitis says.
This does not apply to co-founders, but to hiring close friends as your employees. The moment best friends enter into a boss-employee setup, the working relationship becomes complicated. In friendship, you’re equal, but now, your friend has to report to you. And because the two of you had an existing bond, it becomes difficult to draw the lines between friendship and work.

“And that is how friendships fall apart, and can never be mended again,” she says.

In Out There Media, this has happened about three times already, Trikalitis shares. And in those instances, people who used to be good friends have now stopped talking to each other.

Trikalitis adds, “So it is better to keep your good friend, and hire a professional or a person that might be some friend and a professional, but not one of your best friends.”

Two of my very close friends are working for me and are doing a fantastic job. We have great relationship that is mutually beneficial both personally and professionally. It’s not a walk in the park, of course. It’s a combination of setting the correct expectations and having a mature mindset to make it work.

Have the “talk” with them. First things first. Before getting them on board, make sure to be upfront about working professionally would mean acting differently with each other. Make them accept that uncomfortable situation is part of the relationship.

Always wear the right “hat” when interacting with them. Around work environment, your main objective is to get things done, nothing personal. If you stick with this philosophy, working with them will be smoother: you do not have to worry on accidentally hurting their feelings. When socializing with them outside work, be mindful of your actions. Never boss around.

Show them why they should respect you as a colleague. Friends can act comfortably around each other because they usually don’t care what each other does–which is great. However, inside the office, show them that you mean business. Show them how good you are with what you do. They’ll respect you for that and further improve your relationship.

Angela Lee Duckworth’s “The Key to Success? Grit” Ted talk is one of my all time favorites:

Huffington Post wrote an article referencing Duckworth’s work:

Developing grit is all about habitually doing the things that no one else is willing to do. There are quite a few signs that you have grit, and if you aren’t doing the following on a regular basis, you should be.

Good read.

Here’s a good litmus test to determine how seasoned a developer is: ask him to design a method that is conditional clause heavy. Most developers will instinctively resort to arrow code: the excessive nesting of conditional clauses which pushes the code out into an arrow formation. Coding Horror has a good rundown of the problem and some tips to minimize it.

And you know you’re definitely in trouble when the code you’re reading is regularly exceeding the right margin on a typical 1280×1024 display

Guard clause is the most important concept to mitigate arrow code. Most developers are unaware how important it is. First, as explained in the article, it minimize convoluted conditional clauses (cyclomatic complexity). Since they act as sentry points, you can make sure that parameters are satisfied first before moving to the next line of code. Succeeding code can execute with a privilege that variables will always be present, no checks needed (thus reducing additional conditional clauses). Second, it creates a clean and elegant method anatomy: guard clauses, purpose of the method, and return. This makes the method self-documenting and predictable. This also allows you to plan usage of resources, which brings me to my third and last point: efficiency. Resources will only be spent when they are actually needed.

 

 

Coding Horror:

Don’t feel inadequate if you aren’t lining your nest with the shiniest, newest things possible. Who cares what technology you use, as long as it works, and both you and your users are happy with it?

That’s the beauty of new things: there’s always a new one coming along. Don’t let the pursuit of new, shiny things accidentally become your goal. Avoid becoming a magpie developer. Be selective in your pursuit of the shiny and new, and you may find yourself a better developer for it.

There’s a shittier variation of the magpie developer: the one who keeps moving on to the next shiny object without even learning the fundamentals. They’re just in it to tickle their fancy, not to get things done. Stay the hell away from them.