The CSS background-image property as an anti-pattern

Andrew Welch:

There are some seri­ous down­sides to using the CSS background-image prop­er­ty, and more impor­tant­ly, we have bet­ter ways to imple­ment images in our browsers today. Time is now to ditch background-image from your toolset and use <picture> tag instead.

Old way:

1
2
3
<div style="background-image: url('/some/man-with-a-dog.jpg'); 
            background-size: cover;">
</div>

New Way:

1
2
3
4
5
<picture>
  <img src="/some/man-with-a-dog.jpg"
       alt="Man with a dog"
       style="object-fit: cover;" />
</picture>

Cadillac Mountain, Acadia

Sony ILCE-7RM2 • FE 70-200mm F2.8 GM
ƒ/9.0 • 70mm • 1/80s • ISO 2000

Cadillac Mountain, which is the highest point of the North American continent seaboard is known for first place in the United States to see the sunrise. This makes Cadillac Mountain one of the primary destinations for visitors in Acadia.

This photo will give you a glimpse of what it’s like to be at the Cadillac Mountain to view the extravagantly gorgeous sunrise. The shot was a bit tricky because of the low light. It’s always a balance you have to create between aperture, shutter speed, and ISO when you are in such a situation. I wanted to keep the shutter speed around 1100 sec to account for people movements. Hence, bumping up the ISO to 2000 was one option to have acceptable photo quality while keeping infinite depth-of-field. Lowering the ƒ-stop was another option, but that will lead to a decision which part in the composition will be sharp and which not.

If you are planning to visit Cadillac around Autumn, be prepared for freezing temperatures and extremely low wind chills. Do check weather condition night before if you are planning next morning. Avoid planing on overcast or cloudy morning when probability sunrise is low. Car/Van is the only means of transportation. So if you plan to visit for sunrise view, make it to the summit least an hour before. It will be otherwise impossible for you to get a parking spot during this time of the day. Also, make sure you have multiple layers of warm clothing to protect yourself from intensely cold and windy conditions.

Use unique and unlimited number of email addresses for Gmail

Gmail has a great feature which allows you to create an unlimited number of email addresses based on your actual Gmail address. You can append plus sign (+) and any word after that, and that email address will still come to your Gmail mailbox. If your email address is johndoe@gmail for example, you will still receive the email if someone sends an email to johndoe+test@gmail, or johndoe+tech@gmail, or johndoe+games@gmail, etc. You can leverage this feature by creating a unique email address like johndoe+apple@gmail, or johndoe+cnn@gmail, etc. for each website you registered.

These individual pseudo email addresses will help you to identify the original registration website if they sold your email address to a third party or unknown service and you start receiving spam or junk emails from those services. Using these pseudo email address for all of your web registrations and subscriptions, you can easily configure your Mailbox filters to manage or block incoming emails.

Coming up with a random string and creating a unique email address every time is a bit hassle, so I created a AutoHotKey script which will automate the process a bit.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
^+e::
  email := "johndoe"
  string := "abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz0123456789abcdefghijklmnopqrstuvwxyz"
  suffix := ""
  loop, 10
  {
    Random, Var, 1, 98
    char = % SubStr(string, Var, 1)
    suffix = %suffix%%char%
  }
  SendInput %email%{+}%suffix%@gmail.com
  return

Please change the value of email (Line: 2) in the script from “johndoe” to your email. If you email address is firstlast@gmail.com, change the value of the email (Line: 2) to “firstlast”.

With the above script running in AutoHotKey, press Ctrl+Shift+E whenever you need a unique address on email field while registering to a website and script will generate that unique email address for the site and place it in the email field of the registration form.

Here are few generated email address examples by the script:

johndoe+lzkcrpg8oo@gmail.com
johndoe+1h0xdiix83@gmail.com
johndoe+jnnvur5nn7@gmail.com
johndoe+rtsphp0mq7@gmail.com
johndoe+sfbfoq2d85@gmail.com
johndoe+4m4cnrpom0@gmail.com
johndoe+uhxee82ozo@gmail.com

For every registration or subscription to the web site, you should receive some form of confirmation email which will help you to identify the original registration website. Received a spam email which uses your unique email address? Search for that email address in your mailbox, and you will know who’s the culprit.

This hack should also work for other email service providers like Outlook etc. Change the AutoHotKey script accordingly.

Unraveling the JPEG

This article is about how to decode a JPEG image. In other words, it’s about what it takes to convert the compressed data stored on your computer to the image that appears on the screen. It’s worth learning about not just because it’s important to understand the technology we all use everyday, but also because, as we unravel the layers of compression, we learn a bit about perception and vision, and about what details our eyes are most sensitive to.

Can Enum return string instead of integer value?

Spoiler: Answer is NO!

Current implementation C# Enum is very primitive; it can only return integer value for the selected enumerator option. If your project requirement needs something like returning a string for Enum, you have to come up with your own solution.

You cannot declare enum like this:

1
2
3
4
5
6
7
// enum type can't have string value
public enum WorkerType
{
  Employee = "WT001",
  Contractor = "WT003",
  Resigned = "WT099"
}

One solution usually popular is to declare Description attribute to each enumerators (for example, [Description("WT003")] for Contractor) and use it to store a respective string value. This is more of a hack work to as intend of Description attribute is to provide description for enumerators for documentation purpose only. With that, you then also require to use reflection to pull the string from Description attribute. This is not a clean solution.

I think the best way to implement the solution is through creating a dedicated class instead and provide all implementation underneath to make it behave like an enum.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class WorkerType
{
  private WorkerType(string value)
  {
    Value = value;
  }

  public string Value { get; }

  public static WorkerType Employee => new WorkerType("WT001");
  public static WorkerType Contractor => new WorkerType("WT003");
  public static WorkerType Resigned => new WorkerType("WT099");
}

class Program
{
  static void Main(string[] args)
  {
    WorkerType workerType = WorkerType.Contractor;
    Console.WriteLine($"Contractor Value: {workerType.Value}");
  }
}

We set the Constructor of the class as private which will keeping this class initiated anywhere in the project. All this class is exposing is defined members and Value property in which are interested in.

We can then further extend this class by overriding Equals and implementing == and != operators. Complete implementation will look like this:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
using System;

namespace ConsoleApp
{
  public class WorkerType
  {
    private WorkerType(string value)
    {
      Value = value;
    }

    public string Value { get; }

    public static WorkerType Employee => new WorkerType("WT001");
    public static WorkerType Contractor => new WorkerType("WT003");
    public static WorkerType Resigned => new WorkerType("WT099");

    public override bool Equals(Object obj)
    {
      return obj is WorkerType && this.Value == ((WorkerType)obj).Value;
    }

    public static bool operator ==(WorkerType x, WorkerType y)
    {
      return x.Value == y.Value;
    }

    public static bool operator !=(WorkerType x, WorkerType y)
    {
      return !(x == y);
    }
  }

  class Program
  {
    static void Main(string[] args)
    {
      WorkerType workerType = WorkerType.Contractor;
      Console.WriteLine($"Contractor Value: {workerType.Value}");

      if (workerType.Equals(WorkerType.Contractor))
      {
        Console.WriteLine("And it matches using Equals method.");
      }

      if (workerType == WorkerType.Contractor)
      {
        Console.WriteLine("Yea! It also matches using == Operator.");
      }

      if (workerType != WorkerType.Resigned)
      {
        Console.WriteLine("And also with != Operator.");
      }

      Console.ReadKey();
    }
  }
}
Works like Enum!

Once we establish the pattern using the above implementation, it’s just a matter of replicating this pattern for other complex enums which has this string return value requirements. I hope this help!

Accessible Icon Buttons

Sara Soueidan:

If your button isn’t supposed to visually contain any text, you can still provide the text inside the <button> so that it’s picked up and used by screen readers, while hiding it visually using CSS.

1
2
3
4
5
6
7
<button>
   <svg viewBox="0 0 32 32" width="32px" height="32px" 
           aria-hidden="true" focusable="false">
        <!-- svg content -->
    </svg>
    <span class="sr-only">Menu</span>
</button>
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
/* 
 * Utility class to hide content visually while keeping it screen reader-accessible.
 * Source: https://www.scottohara.me/blog/2017/04/14/inclusively-hidden.html 
 */

.sr-only:not(:focus):not(:active) {
  clip: rect(0 0 0 0); 
  clip-path: inset(100%);
  height: 1px;
  overflow: hidden;
  position: absolute;
  white-space: nowrap; 
  width: 1px;
}

More productive Git

These tips and techniques by James Turnbull will help you to avoid potential source control pitfalls and make your development workflow bit smoother.

Tip # 6: I am bisect and so can you

git bisect is one of the most powerful, seemingly magical, code-based debugging tools available to you. It can be used when you discover a bug you can’t trace to a specific piece of code. A git bisect runs a binary search between two commits: a good commit where the bug wasn’t present and a bad commit where the bug appears.

$ git bisect start
$ git bisect bad                 # Current version is bad
$ git bisect good v2.6.13-rc2    # v2.6.13-rc2 is known to be good

How to exclude Google Analytics running under local Hugo

I recently added Google Analytics to my website, which gives me a traffic report on my site. I was checking my analytic reports last night, and I discovered that page views from my localhost on analytics report. This contaminated traffic report is not good news. Google Analytics should only capture page view on production instance only.

I am continually running hugo server while making changes or enhancing something on my site as many Hugo developers. This causing localhost traffics captured in Google Analytics. I somehow manage to remove Google Analytics snippet from my pages if instance running on my localhost to resolve this issue.

One way to achieve this is to check the value of window.location.hostname in JavaScript, if it’s localhost then exclude the Google Analytic script. Seems a bit hacky to me! But after some research, I learned about a Hugo object property .Site.IsServer which can tell if the code is running under hugo server or not. I can put my Google Analytic script exclusion logic using .Site.IsServer. This implementation looks more cleaner to me.

Here is the code snippet to exclude Google Analytics script when running on the local machine:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
<!-- layouts\partials\analytics.html -->
{{ if not .Site.IsServer }}

  <script type="text/javascript">
    (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
    })(window,document,'script','https://www.google-analytics.com/analytics.js','ga');

    ga('create', '{{ .Site.Params.ga_api_key }}', 'auto');
    ga('send', 'pageview');
  </script>

{{ end }}

With the above change, Google Analytics code snippet is no more rendering in the web pages when I am runing my site on my local machine and snippet is only rendering when the site is deployed on the production instance. The change should keep my Google Analytics report nice and clean.

Playdate: A New Handheld Gaming System

Playdate: A New Handheld Gaming System

Look like this world has started moving back towards a simplified life. In the age where every device has more and more extra features, small company Panic come up with a basic handheld video game console with the monochrome screen. This pocket device has a crank which you can use to play games. You will not be going to believe me, when I first heard about hand crank on the game controller, I thought it’s a mechanism to charge the device.

Otter Point, Acadia

Sony ILCE-7RM2 • FE 16-35mm F2.8 GM
ƒ/14 • 16mm • 1/20s • ISO 100

You can create many distinct and exciting effects by just experimenting with various ƒ-stops of your lens. One of the most popular effects known among landscape photographers is the sunburst effect, which is also known by other names, such as Sun Star, Sun Flares, etc.

Sunburst effect gives star lines spike around the sun, which can add more visual interest to the sky, especially just a few moments after sunrise or before sunset. The technique to get a sunburst effect is simple; you need to set your lens to higher ƒ-stop number (somewhere between ƒ/11 or ƒ/16). I set my ƒ-stop to ƒ/14 for the above composition, which is moderate enough to get a good sunburst effect.

Note that higher the ƒ-stop, lowers the quality of your photos. You have to constraint yourself while picking the higher number for your composition. Anything between ƒ/11 and ƒ/16 is good enough for the best result. Higher then that will degrade the quality of the photo because of the diffraction caused by high ƒ-stop.

The number of star spikes will depend upon the number of blades you have in your lens. Double of the number of blades you have in your lens and that’s the number of star spikes you will get in your composition. For example, if your lens has seven blades, you will get 14 spikes.

To get more distinct star spikes, try to achieve narrowest possible sun source. That’s why this effect is more effective when the sun is just rising on the horizon. Alternatively, try hiding the sun behind a tree branch or rock, on something by changing your camera position or your composition.

A vital thing to remember when working with the higher ƒ-stop numbers: make sure your lens front element is spot clean from any dirt or smudge. Any imperfection on the front glass of your lens will grossly expose as huge circular spots in your photos. Don’t be surprised if a minuscule dust spike on your glass you never noticed on other pictures is enlarged and spotlighted in your sunburst photos. So do regularly visually glance over and spot clean the front element of your lens; removing those circular spots in Photoshop is not fun.

Windows Command Prompt Alternative - Cmder

Cmder - Console Emulator

Till Microsoft releases its new Windows Terminal, there is not much option for a decent command prompt tool in Windows. Forget about having a color theme and or multiple tabs in command windows; you won’t find the essential feature even things like copy/paste. Windows stuck with the same feature sets for command windows which they built more than 20 years back and not much enhancement made to it afterward. There is always a room for basic terminal windows with few more functionalities which match with those pimp terminals in MaxOS or Linux. I believe Cmder fills that room as I find every feature I expect from a terminal window. It has multiple tabs, can split the screen into multiple panels, can run many Unix commands, comes with Git setup, and much more.

Cmder is a self-contained console emulator for Windows without any dependencies. Being a portable application, Cmder offers to run without any need to install on the machine. It is based on ConEmu with the major config overhaul, comes with many color schemes, fantastic clink, and a custom prompt layout. If you are looking for a replacement for existing command windows with features like multiple tabs, custom color scheme, minimize to the system tray, etc. then you will love Cmder. Pick your shell you want to work with like Cmd, PowerShell, Bash, or Mintty, and run it using Cmder emulator as standard terminal experience.

If disk space is not the constraint, make sure you download full version (108 MB) which also has Git for Windows.

Cmder - VIM Editor

Link:
Cmder

FakeItEasy - The easy mocking library for .NET

A .Net dynamic fake framework for creating all types of fake objects, mocks, stubs etc. Context-aware fluent interface guides the developer.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
namespace FakeItEasyQuickstart
{
    using FakeItEasy;
    using NUnit; // any test framework will do

    public class SweetToothTests
    {
        [Test]
        public void BuyTastiestCandy_should_buy_top_selling_candy_from_shop
        {
            // make some fakes for the test
            var lollipop = A.Fake<ICandy>();
            var shop = A.Fake<ICandyShop>();

            // set up a call to return a value
            A.CallTo(() => shop.GetTopSellingCandy()).Returns(lollipop);

            // use the fake as an actual instance of the faked type
            var developer = new SweetTooth();
            developer.BuyTastiestCandy(shop);

            // asserting uses the exact same syntax as when configuring calls—
            // no need to learn another syntax
            A.CallTo(() => shop.BuyCandy(lollipop)).MustHaveHappened();
        }
    }
}

Text Editor - Find Text Using Regular Expressions

It’s in our muscle memory. Press Ctrl+F in your favorite text editor to find something, provide find criteria, and hit the Find button. As always, we usually stick with the simple Find functionality of the text editor as it serves almost all of our basic search needs. But beneath Find dialog box, there is a powerful Find option, Use Regular Expressions which most seldom use.

Visual Studio 2019 - Find in Files

Able to recall a correct regular expression when we need it most is rare. Which often leads to the hassle of googling regular expression and trying few failed attempts, and going back to simple Find. This is where following regular expressions cheatsheet comes handy for me.

Regular Expressions:

  • Have foo anywhere and bar later in the same line

    .*foo.*bar

  • Have foo at the beginning of the line

    ^\s{2,}foo

  • Have foo at the beginning of the line and bar later in the same line

    ^\s{2,}foo.*bar

  • Have foo in the commentted line

    .*//.*foo

  • Have foo inside double quotes

    ^.*".*foo.*"

  • Have foo at the beginning or end of the word

    ^.*".*\bfoo.*"

  • Have foo at the end of the line

    foo\r?\n

  • Have foo); at the end of the line

    foo\);\r?\n

  • Have foo but not bar in the same line

    ^.*foo.*(?!bar)

  • Have foo and { in the next line

    .*foo.*\r?\n.*{

Hemlock Bridge, Acadia

Sony ILCE-7RM3 • FE 16-35mm F2.8 GM
ƒ/8.0 • 16mm • 5s • ISO 100

Far from over-touristed places in Mount Desert Island, Hemlock Bridge is a place for a quiet escape for photographers. Other than one or two souls hiking or wandering around on their bike, you will hardly find anyone asking about your camera or lens. This is the place where you can take your time to find your composition without any distraction. Though you have to hike with your camera gears for 40 mins to get to this place, but it is well worth it. My only suggestion to photograph at this place is to pick a cloudy or overcast day. Harsh direct light under those trees on bright and sunny day will ruin your composition.

Visual Studio Tips

Jeremy Hutchinson listed out series of tips to be more productive in Visual Studio.

I was not aware of tip #2 - $exception Pseudovariable - Viewing uncaptured exception while debugging. Visual studio has a pseudo variable $exception in the debug mode which will hold the details of the last exception. To explore $exception, let’s create a small project:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
static void Main(string[] args)
{
    Object foo = null;

    string bar;
    try
    {
        bar = foo.ToString();
    }
    catch (Exception)
    {
        // Oh! What cause this exception?
        bar = null;
    }
}

Put a breakpoint at line 13 and run above code. The code will throw an exception and pause the execution in catch block. Now here you can use $exception variable to inspect exception details.

Visual Studio - $exception variable

Visual Studio - $exception variable

SQL SERVER - Stored Procedure sp_datatype_info to Get Supported Data Types

Sometimes you need to know more information about various data types supports by your SQL Server version. Information like if the specific data type is searchable or not, or it’s maximum precision, or if it’s case sensitive or not. sp_datatype_info system SP comes handy to retrieve such information.

1
2
3
4
5
USE master;
GO

EXEC sp_datatype_info;
GO
sp_datatype_info

ZarahDB - JSON based flat file database

The relational database management system is the de facto choice for any standard application to persist data on the disk. It provides all interfaces one requires to store, optimize, and query data for the client. But sometimes persisting data requirement for the application is so basic that we don’t need whole RDBMS engine on the backend to store data - storing in some form of flat file is sufficient enough to serve application data persistence need.

Creating such a backend layer to store data as flat files and querying data from these files can be a bit tedious which can become a project in itself. But there are many open source wrappers already around which can help you to kickstart building such data access layer. ZarahDB is one such open-source project.

ZarahDB is a flat file database engine which uses the combination of the root folder (per database), child folders (per table) and JSON files (per record) to persist data. Storing data as JSON files makes ZarahDB more structured and reliable compare to others. With that, storing data as files make it easy to backup or restore as it become just a matter of copying and pasting application data folder. As with other flat file based database platforms, you don’t need to install any database software on your server.

Project URL: http://zarahdb.com/
NuGet URL: https://www.nuget.org/packages/ZarahDB.Library
Source Code: https://github.com/MikeReedKS/ZarahDB

Using ZarahDB library in your project is easy - Simply add ZarahDB.Library through NuGet and your are ready.

ZarahDB - Nuget

ZarahDB - Nuget

Enough talk, let’s create a very basic .NET Core console application which will store and retrieve an employee information.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
using System;
using ZarahDB_Library;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            var instance = new Uri(AppDomain.CurrentDomain.BaseDirectory + "Data");
            var table = "Employees";

            // Save an employee to the database
            var key = "0001";
            ZarahDB.Put(instance, table, key, "Name", "Mike Smith");
            ZarahDB.Put(instance, table, key, "City", "Chicago");

            // Retrive employee from the database
            var name = ZarahDB.Get(instance, table, key, "Name").Value;
            var city = ZarahDB.Get(instance, table, key, "City").Value;

            Console.WriteLine("Name: " + name);
            Console.WriteLine("City: " + city);

            Console.ReadKey();
        }
    }
}

JSON stored in the Employees data folder (Location: Data\Employees\0\0\0\1\0001.json) will look like following:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
{
  "Keys": [
    {
      "Key": "0001",
      "ColumnValues": [
        {
          "Column": "Name",
          "Value": "Mike Smith",
          "PreviousValue": "",
          "Updated": "636935583251802007"
        },
        {
          "Column": "City",
          "Value": "Chicago",
          "PreviousValue": "",
          "Updated": "636935583256218064"
        }
      ]
    }
  ]
}
ZarahDB - Output

ZarahDB - Output

As you probably noticed, ZarahDB stores data values as string, which means you will require to explicitely convert non-string data type or object type as string before passing it to ZarahDB method to save it. This goes other way around as well: you will retrive stored data as string from ZarahDB, you will then require to convert string value to column data type.

Here is the example which explains how DateTime data value to stored and retrived in ZarahDB.

1
2
3
4
5
// Convert non-string data type value to string
ZarahDB.Put(instance, table, key, "BirthDate", (new DateTime(1998, 09, 12)).ToString());

// Convert string to column specifc data type
var birthDate = Convert.ToDateTime(ZarahDB.Get(instance, table, key, "BirthDate").Value);

To store complex object using ZarahDB, you will require to serialize it to Json or Xml string. And as you guessed, you will then require to deserialize returned Json or Xml string to object type.

To conclude this brief overview of ZarahDB, following is the code snippet which demonstrates taking a complex object like a blog post and store and retrive using ZarahDB through Json serialization.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
using Newtonsoft.Json;
using System;
using ZarahDB_Library;

namespace BlogEngine
{
    internal class Post
    {
        public string Title { get; set; }
        public string Content { get; set; }
        public string Author { get; set; }
        public string Category { get; set; }
        public DateTime Publish { get; set; }
    }

    class Program
    {
        static void Main(string[] args)
        {
            var instance = new Uri(AppDomain.CurrentDomain.BaseDirectory + "Data");
            var table = "Posts";

            string key = "quick-start-tutorial";
            var newPost = new Post
            {
                Title = "Quick Start Tutorial",
                Content = "The basic concept of a scattered database is ...",
                Author = "Mike Reed",
                Category = "Database",
                Publish = DateTime.Now
            };
            var jsonPost = JsonConvert.SerializeObject(newPost);

            // Save blog post to the database
            ZarahDB.Put(instance, table, key, "PostData", jsonPost);

            // Retrive blog post from the database
            var resultJson = ZarahDB.Get(instance, table, key, "PostData").Value;
            var resultPost = JsonConvert.DeserializeObject<Post>(resultJson);

            Console.WriteLine("Title: " + resultPost.Title);
            Console.WriteLine("Content: " + resultPost.Content);
            Console.WriteLine("Author: " + resultPost.Author);
            Console.WriteLine("Category: " + resultPost.Category);
            Console.WriteLine("Publish: " + resultPost.Publish.ToString("MM/dd/yyyy"));

            Console.ReadKey();
        }
    }
}
ZarahDB - Blog Example

ZarahDB - Blog Example

As I mentioned in the early part of this article, ZarahDB is great if you have a basic data persistence requirement but surely it’s not recommended for the more complex or data-heavy requirement. I hope you will find this short overview helpful.

Hunters Head, Acadia

Sony ILCE-7RM3 • FE 16-35mm F2.8 GM
ƒ/8.0 • 16mm • 0.8s • ISO 100

Precarious rocks in the foreground and with the smooth and calm horizon in the background give a good contrast in this composition.

It was a huge gamble to wake up before dawn and drive to this spot for sunrise shots when the night before all weather apps on my iPhone were showing a cloudy morning. I was actually anticipating a cloud break-out in the sky for a very short time window which always creates inverted sunlight illuminating cloud cover turning them to the glowing orange-red-pink fireball. And as you can see in this photo, that gamble does payout that morning. The cloud break-out was not more than 5 mins but it gives me a whole lot of time to take multiple compositions. With the expected cloud-covered sky for the rest of the day, I decided to return back to my hotel and complete my sleep.

Why software projects take longer than you think – a statistical model

Erik Bernhardsson analysis SiP Effort Estimation dataset to illustration why software estimations turn out to be inaccurate and summaries his conclusion:

The mean turns out to be substantially worse than the median, due to the distribution being skewed (log-normally).

Tasks with the most uncertainty (rather the biggest size) can often dominate the mean time it takes to complete all tasks.

randr - Rename And Replace

I thought spending this weekend to kickstart learning Go. As a committed .NET/C# developer for 15 years, working with the Go syntax is a different kind of experience. I am still trying to well verse myself with Go syntax and development

Once I got the hang of Go basic syntax, I thought why not build a small and useful tool in Go which could resolve a daily annoyance. Folk, this is what I come up with, randr.

randr is a command line tool which recursively searches files content for source string and replaces it with the target string. With that, randr will also recursively rename files or folders name which matches source string to target string. You can also specify a command flag, if you want to rename or replace based on case sensitive or case insensitive search. And that is all!

randr - Help

randr - Help

To illustrate the usage of randr, consider you have a project folder with the following structure:

// Project Folder: c:\Projects\Payroll\

// c:\Projects\Payroll\Models\Worker.cs
public class Worker {}

// c:\Projects\Payroll\Services\WorkerService.cs
public class WorkerService {}

// c:\{rojects\Payroll\Repositories\WorkerRepository.cs
public class WorkerRepository {}

// c:\Projects\Payroll\Helpers\Worker\Extensions.cs
public static class Extensions {}

Let’s refactor above project using randr and change Worker entities to Employee. randr command to refactor will look like following which will replace any files text which contains Worker to Employee as well as will rename any file or folder with contains Worker to Employee.

randr.exe -find=Worker -replace=Employee -match=true -location=c:\Projects\Payroll\
randr - Example

randr - Example

After running randr successfully, our example project folder will look like following:

// Project Folder: c:\Projects\Payroll\

// c:\Projects\Payroll\Models\Employee.cs
public class Employee {}

// c:\Projects\Payroll\Services\EmployeeService.cs
public class EmployeeService {}

// c:\Projects\Payroll\Repositories\EmployeeRepository.cs
public class EmployeeRepository {}

// c:\Projects\Payroll\Helpers\Employee\Extensions.cs
public static class Extensions {}

Please go over README.md in the project repository for parameter usage details.

Project Repository: randr

randr is currently a bare minimum tool and it does require some more polishing. I hope you will find randr useful.

The Codeless Code

An illustrated collection of (sometimes violent) fables concerning the Art and Philosophy of software development, written in the spirit of Zen kōans

One of the fables from the collection I like most which I think any software developer can relate to:

Case 100

Ten Thousand Mistakes

A novice asked master Banzen: “What separates the monk from the master?”

Banzen replied: “Ten thousand mistakes!”

The novice, not understanding, sought to avoid all error. An abbot observed and brought the novice to Banzen for correction.

Banzen explained: “I have made ten thousand mistakes; Suku has made ten thousand mistakes; the patriarchs of Open Source have each made ten thousand mistakes.”

Asked the novice: “What of the old monk who labors in the cubicle next to mine? Surely he has made ten thousand mistakes.”

Banzen shook his head sadly. “Ten mistakes, a thousand times each.”

An excerpt from The Codeless Code, by Qi (qi@thecodelesscode.com).

First Aid Git

A searchable collection of the most frequently asked Git questions. Following are a couple of my most favorite commands from the list:

-- Commit changes to a new branch
git checkout -b my-new-branch-name

-- Move stashed changes to current branch
git stash apply

Another handy Git command I surely want to see in this list is git commit --amend which allows adding changes to your last commit.

-- Add changes to last commit
git commit --amend -m "updated commit message"

--amend flag will tackle situation like:

701c70f Fix issue with api_handler
2e7be87 Update fix to api_handler
7e9f104 Some more fixes to api_handler
16e9747 Last changes to api_handler
3d1e7db This is last change to api_handler
e58043e :(

HTTP headers for the responsible developer

Stefan Judis explains why developers should be a bit responsible when it comes to setting HTTP Headers of web applications. Having proper HTTP Headers like Cache-Control will be a deciding factor sometimes if the web application is accessible to some people or not.

If a page on a hospital site is 5MB it is not only slow but also could be too expensive for people needing it the most. The price of 5MB in Europe or the United States is nothing compared to the price of 5MB of data in Africa. Developers are responsible for keeping the web affordable for everybody. This responsibility includes serving the right resources, evaluation of the right tools to use (do you really need a JS framework for a landing page?), and avoiding requests.

Monument Cove Shore, Acadia

Sony ILCE-7RM3 • FE 16-35mm F2.8 GM
ƒ/8.0 • 16mm • 0.6s • ISO 100

Monument Cove Shoreline along the Park Loop Road in Acadia is one of the glorious destinations to capture sunrise shots. To get the best shot, you have to reach the location before sunrise will require walking in the dark on these precarious cobblestones. A headlamp, rubber sole shoes, and a couple of empty plastic bags will surely ease out your photography outing to places like Monument Cove.

The fine art of fast development

David Gilbertson, writing for the Hacker Noon:

Stop multitasking
Chunk your coding time into distraction-free sessions of at least 30 minutes. 2 hour sessions are the best.

If you only take one piece of advice from this article, it should be Stop multitasking. High productive software development can only achieve through quality time between you and your code. Any further multitasking is just an interruption which always translates into a lesser quality output. Multitasking is actually evil! There are many steps you can take to avoid multitasking:

  1. Turn off your email client / disable all notifications for the specific time window.
  2. Priorities your tasks.
  3. Tackle your biggest task first and then only move to smaller tasks.
  4. Have a cleaned workplace.
  5. Be consciously available and mindful of what you are doing.
  6. Keep your internal monologue continue while writing code.
  7. Streamline everything, one task at a time.
  8. Voicemail one of the best innovations, use it more often.
  9. Wear a headphone during coding sessions even if you are not listening to anything.

API Evolution the Right Way

A. Jesse Jiryu Davis:

We keep our promises to the people who depend on our code: we release bugfixes and useful new features. We sometimes delete features if that’s beneficial for the library’s future. We continue to innovate, but we don’t break the code of people who use our library. How can we fulfill all those goals at once?

DataTable add column extension

Unfortunately there is no method to call DataTable.Add with the column size. This extension method will fix that:

1
2
3
4
5
6
7
8
public static DataColumn Add(this DataColumnCollection columns, string columnName, Type type, int maxLength)
{
  DataColumn column = new DataColumn(columnName, type);
  column.MaxLength = maxLength;
  columns.Add(column);

  return column;
}