Why I blog

One of my goals in 2019 is to write often and specifically, have at least 200 published blog posts when the year closes its curtains. So far I have been on track to meet the target. As I look back at the last 8 months of consistent blogging, this endeavor has brought to me so much more than I anticipated.

Last August, I started this blog as a medium to practice what I learned, share my opinion in my own way to give back, create a healthy habit and build up my self-confidence. Fast forward to now:

  1. I have learned a lot more along the way. To really write about something, first I need to know what I am going to write about. I read more quarterly/annual reports, earning call transcripts, industry reports, long blog posts, you know, the boring stuff to many of my peers. I listen to more podcasts, interviews. I read more books. I analyze reported numbers by companies more. And it leads to a lot learning; which fits the name of this blog.
  2. I enjoy the process. Writing is such a pleasant experience to me nowadays that I often really look forward to it as a highlight of my day, especially when I have a long day at work. Anne Lamott said it best: “Writing has so much to give, so much to teach, so many surprises. That thing you had to force yourself to do – the actual act of writing – turns out to be the best part. It’s like discovering that while you thought you needed the tea ceremony for the caffeine, what you really needed was the tea ceremony. The act of writing turns out to be its own reward.”
  3. I feel much more confident about blogging now than when I first started. Not because I am an expert now. I still have a long way to go. But I believe it is because of the practice. Blogging often helps me reduce my self-doubt and shyness bit by bit and gives my confidence a little boost. Even though the progress is nothing earth-shattering, as long as I don’t stand still, I am happy.
  4. I came to realization that this blog gradually is becoming a collection of my notes, a bookmarking tool, a mind-refresher. Sometimes, I come back to remind myself of some highlights in a book I read, of some code I wrote and of something that I jogged down. Instead of carrying an actual notebook which would be challenging to categorize and search, I know where to find what I need with just a few key strokes.

I came across a post by M.G. Siegler that really hit home to me:

Imagine the humiliation of putting yourself out there and zero people caring because zero people saw it. I know a lot of people feel this way when they start doing something with regard to content on the internet — I applied it to blogging, but I imagine it’s the exact same story with recording videos for YouTube, starting a podcast, etc. Just keep at it.

This is, of course, easier said than done. It takes time to do anything, no matter the type of content you’re focused on. The good news is that even if the audience doesn’t show up at first, the work pays off in other ways. Namely, you’ll get better at what you’re doing.

I look back at some of my early blog posts and cringe. They were awful. I was foolish. But I kept going and the posts got less awful and less foolish (this statement is subject to review in another decade). I honestly think the worst thing that could have happened was getting a large audience from day one. I wouldn’t have been ready for it (even if I thought I was).

And so again, the advice is simply to keep at it. Even if the next post gets zero readers too. And the next one. Eventually, zero turns to one and then one to two and then you’re off to the races.

M.G. Siegler

I know the feeling of having zero people view what you wrote all too well. Part of it is I don’t advertise it. I put a link to my blog on my Instagram profile, LinkedIn profile and in my resume. That’s it. I don’t actively post on Facebook or tweet about it whenever I publish. I am doing this for me first and foremost, not to be validated by others. Plus, I know I am not ready. Even though this blog has gained traction in the last few months , I am still on my way from zero to one. Good news is that I am willing to keep at it.

Geocoding & reverse-geocoding with Google Map

Since I don’t think the documentation from Google is very clear on how to actually implement the Geocoding API, especially to a newbie like I am, here are the steps to geocode an address or reverse-geocode a set of coordinates and to get the key you want

Reverse-geocoding

Here is a short piece of code in Python

import googlemaps
gmaps = googlemaps.Client(key='<enter your Google API key here>’)

result = gmaps.reverse_geocode((40.714224, -73.961452))
print(result)

If you run that code, what you will get is a very long json. It is important to use an online tool to have a good understanding of your code’s result. Here is how it looks

full result

Go through each number to see what keys interest you. Let’s say if you are interested in [0] in the json. Here is the code to get it:

import googlemaps
gmaps = googlemaps.Client(key='<enter your Google API key here>’)

result = gmaps.reverse_geocode((40.714224, -73.961452))
print(result[0])

Here is how it looks

partial result

Continue to parse through the JSON to get the key you want such as result[0][‘geometry’]…

Geocoding

import googlemaps
gmaps = googlemaps.Client(key='<enter your Google API key here>’)

result = gmaps.reverse_geocode(‘1600 Amphitheatre Parkway, Mountain View, CA’)
print(result)

The rest is similar to Reverse-coding

Concatenate strings to form a full address

If you have address, city, state, zip code and countries in different columns, one quick way to form a full address is

df[‘fulladdress’] = df[[‘Address’, ‘City’, ‘State’, ‘Zip’]].apply(lambda x: ‘ ‘.join(x.astype(str)), axis=1)

Df stands for the current data frame. df[‘fulladdress’] refers to the creation of a new column called “full address”. The whole line of code means to add values on the same row in the address, city, state and zip columns to form a full address accordingly.

Hope it helps

Turn Excel into GEOJSON

My Capstone project requires me to turn Excel in GEOJSON for mapping purposes. Handling and preparing data is 50% of the whole process. I’d like to share what I did step by step, hoping that it will be useful to some who are learning the ropes like I am.

I am using Python as the programming language of choice and Pycharm as IDE. Create a folder on your computer and store the Excel file in question in it. Open the folder in Python and create a new Python file. Here is how it looks on my Pycharm

ExceltoGEOJSON_1

Before we move forward, it’s important to know what a GEOJSON is and how it looks. This website offers a great review on GEOJSON. In terms of structure, a GEOJSON file looks like this

{
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "geometry": {
        "type": "Point",
        "coordinates": [0, 0]
      },
      "properties": {
        "name": "null island"
      }
    }
  ]
}

I am pretty sure we can have as many variables under “properties” as we want. The rest should be standard to be followed as possible.

This is how the Excel file looks. Notice that there are coordinates available already. In the future, I’ll work on geocoding an address into coordinates.

ExceltoGEOJSON_2

Let’s start working on the Python code.

import pandas as pd

df = pd.read_excel('CommunityPartner.xls')

Import the “pandas” package. Shorten the package’s name as pd because who would want to repeat a long name many times in the code?

The following line is to read the Excel file into a data frame called df. You can name it however you want. Since the Excel file and the Python code are in the same folder, there is no need to have a directory. Otherwise, it’s necessary to have a full directory.

collection = {'type': 'FeatureCollection', 'features': []}

The next step is to create a shell dictionary. Refer back to the sample structure of a GEOJSON file above to see why I structure the collection variable like that.

df['description'] = df[['Address', 'City', 'State', 'Zip']].apply(lambda x: ' '.join(x.astype(str)), axis=1)

Since we don’t have a full address, the above line is to combine four columns together to form a full address string. The next step is to populate the dictionary

def feature_from_row(CommunityPartner, latitude, longitude, fulladdress, Primary, Website, Phone):
    feature = {'type': 'Feature', 'properties': {'PartnerName': '', 'Address': '', 'marker-color': '',
                                                 'Website': '', 'PrimaryMission': '', 'Phone': ''},
               'geometry': {'type': 'Point', 'coordinates': []}
               }
    feature['geometry']['coordinates'] = [longitude, latitude]
    feature['properties']['PartnerName'] = CommunityPartner
    feature['properties']['Address'] = fulladdress
    feature['properties']['Website'] = Website
    feature['properties']['PrimaryMission'] = Primary
    feature['properties']['Phone'] = Phone
    if Primary == "Economic Sufficiency":
        feature['properties']['marker-color'] = "FF5733"
    elif Primary == "Social Justice":
        feature['properties']['marker-color'] = "FFF033"
    elif Primary == "Health and Wellness":
        feature['properties']['marker-color'] = "74FF33"
    elif Primary == "Environmental Stewardship":
        feature['properties']['marker-color'] = "338DFF"
    elif Primary == "Educational Support":
        feature['properties']['marker-color'] = "CE33FF"
    else:
        feature['properties']['marker-color'] = "FF3374"
    collection['features'].append(feature)
    return feature

Create a function that will undertake the data processing. Between the brackets are the input variables.

feature = {'type': 'Feature', 'properties': {'PartnerName': '', 'Address': '', 'marker-color': '',
                                             'Website': '', 'PrimaryMission': '', 'Phone': ''},
           'geometry': {'type': 'Point', 'coordinates': []}
           }

Create a “feature”variable as above. Try to mirror it in “type” and “geometry” agains the standard GEOJSON (see above) as much as possible. Leave the “coordinate” value as empty to fill in later. Under “properties”, list the keys you want.

feature['geometry']['coordinates'] = [longitude, latitude]
feature['properties']['PartnerName'] = CommunityPartner
feature['properties']['Address'] = fulladdress
feature['properties']['Website'] = Website
feature['properties']['PrimaryMission'] = Primary
feature['properties']['Phone'] = Phone

Time to populate the keys. Remember to key the names of the keys and input variables consistent with what was already posted so far.

You must wonder: what about “marker-color”. You can use the conditional argument to assign values to the variable as follows:

if Primary == "Economic Sufficiency":
    feature['properties']['marker-color'] = "FF5733"
elif Primary == "Social Justice":
    feature['properties']['marker-color'] = "FFF033"
elif Primary == "Health and Wellness":
    feature['properties']['marker-color'] = "74FF33"
elif Primary == "Environmental Stewardship":
    feature['properties']['marker-color'] = "338DFF"
elif Primary == "Educational Support":
    feature['properties']['marker-color'] = "CE33FF"
else:
    feature['properties']['marker-color'] = "FF3374"

If you wonder about the HTML color code, just Google “HTML Color Code” and you’ll see it.

collection['features'].append(feature)
return feature

The first line of the block above dictates that we add every single row of the Excel file to the “features” key of the collection variable. “Return” is a mandatory feature of every function.

geojson_series = df.apply(
    lambda x: feature_from_row(x['CommunityPartner'], x['Lat'], x['Longitude'], x['description'], x['Primary'],
                               x['Website'], x['Phone']),
    axis=1)

jsonstring = pd.io.json.dumps(collection)

The first line is to add every single row of the Excel file to the function so that we can create the string needed for the GEOJSON. The second line is to turn it into json file.

output_filename = 'CommunityPartner.geojson' 
with open(output_filename, 'w') as output_file:
    output_file.write(format(jsonstring))

Name the file however you want and use the second line to write it into GEOJSON. The file product will look like this:

import pandas as pd

df = pd.read_excel('CommunityPartner.xls') #Get the Excel file from static/Excel

collection = {'type': 'FeatureCollection', 'features': []}

df['description'] = df[['Address', 'City', 'State', 'Zip']].apply(lambda x: ' '.join(x.astype(str)), axis=1)


def feature_from_row(CommunityPartner, latitude, longitude, fulladdress, Primary, Website, Phone):
    feature = {'type': 'Feature', 'properties': {'PartnerName': '', 'Address': '', 'marker-color': '',
                                                 'Website': '', 'PrimaryMission': '', 'Phone': ''},
               'geometry': {'type': 'Point', 'coordinates': []}
               }
    feature['geometry']['coordinates'] = [longitude, latitude]
    feature['properties']['PartnerName'] = CommunityPartner
    feature['properties']['Address'] = fulladdress
    feature['properties']['Website'] = Website
    feature['properties']['PrimaryMission'] = Primary
    feature['properties']['Phone'] = Phone
    if Primary == "Economic Sufficiency":
        feature['properties']['marker-color'] = "FF5733"
    elif Primary == "Social Justice":
        feature['properties']['marker-color'] = "FFF033"
    elif Primary == "Health and Wellness":
        feature['properties']['marker-color'] = "74FF33"
    elif Primary == "Environmental Stewardship":
        feature['properties']['marker-color'] = "338DFF"
    elif Primary == "Educational Support":
        feature['properties']['marker-color'] = "CE33FF"
    else:
        feature['properties']['marker-color'] = "FF3374"
    collection['features'].append(feature)
    return feature


geojson_series = df.apply(
    lambda x: feature_from_row(x['CommunityPartner'], x['Lat'], x['Longitude'], x['description'], x['Primary'],
                               x['Website'], x['Phone']),
    axis=1)

jsonstring = pd.io.json.dumps(collection)

output_filename = 'CommunityPartner.geojson' #The file will be saved under static/GEOJSON
with open(output_filename, 'w') as output_file:
    output_file.write(format(jsonstring))

ExceltoGEOJSON_3

This is how the GEOJSON looks:

 
   “type”:“FeatureCollection”,
   “features”: 
       
         “type”:“Feature”,
         “properties”: 
            “PartnerName”:“75 North”,
            “Address”:“4383 Nicholas St Suite 24 Omaha NE 68131.0”,
            “marker-color”:“FF5733”,
            “Website”:null,
            “PrimaryMission”:“Economic Sufficiency”,
            “Phone”:“402-502-2770”
         },
         “geometry”: 
            “type”:“Point”,
            “coordinates”: 
               -95.957309,
               41.276479
            ]
         }
      },
       
         “type”:“Feature”,
         “properties”: 
            “PartnerName”:“A Time to Heal”,
            “Address”:“6001 Dodge St CEC 216 Suite 219C  Omaha NE 68182.0”,
            “marker-color”:“74FF33”,
            “Website”:null,
            “PrimaryMission”:“Health and Wellness”,
            “Phone”:“402-401-6083” …

One important note. If you are a fan of Jupyter Notebook, beware that there may be a problem when it comes to the last step of the process. Here is how the collection variable looks before being dumped into the GEOJSON file.

ExceltoGEOJSON_4

But I ran into errors in the last step. I spent quite some time on fixing it but I couldn’t.

ExceltoGEOJSON_5

Creating the Python code in Pycharm is much easier and produces the same result. It’s even more convenient if you are in the middle of an application development project.

Hope this post helps. Much thanks to appendto and geoffboeing for inspiration.

 

Create a hover effect on Mapbox

I am sharing my experience in trying to create a hover effect on Mapbox. The first thing to do is to read their example and understand what is going on. Let’s unpack a little bit:

<!DOCTYPE html>
<html>
<head>
    <meta charset='utf-8' />
    <title>Create a hover effect</title>
    <meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no' />
    <script src='https://api.tiles.mapbox.com/mapbox-gl-js/v0.49.0/mapbox-gl.js'></script>
    <link href='https://api.tiles.mapbox.com/mapbox-gl-js/v0.49.0/mapbox-gl.css' rel='stylesheet' />
    <style>
        body { margin:0; padding:0; }
        #map { position:absolute; top:0; bottom:0; width:100%; }
    </style>
</head>

It’s the <head> of the HTML that has scripts from Mapbox. Just follow them and you’ll be fine. Change the text in <title> to have your own page title.

<body>


—- Your real code goes here —–

</body>

Your real work will go between and . The <div> is a container that refers to the map you are working on. The next part is Mapbox token

mapboxgl.accessToken = '<your access token here>';

To get a token, just create a free account on Mapbox. A free account is allowed up to 50,000 requests a month if I am not mistaken. It should be enough for a student or an enthusiast wishing to try it out. Once you have a token, just put it in between ” in the above line.

Let’s have a base map

var map = new mapboxgl.Map({
    container: 'map',
    style: 'mapbox://styles/mapbox/streets-v9',
    center: [-100.486052, 37.830348],
    zoom: 2
});

The “center” feature’s coordinates refer to where you want to focus on. Get your chosen destination’s coordinates and just put them there. Alternate the two figures in coordinates if you don’t get it right in the first try. “Zoom” is how close you look at the chosen destination. The greater the number, the closer the zoom.

var hoveredStateId =  null;

map.on('load', function () {
    map.addSource("states", {
        "type": "geojson",
        "data": "https://www.mapbox.com/mapbox-gl-js/assets/us_states.geojson"
    });

HoveredStateID is a placeholder variable that will be used later for hover effect. The following code block is to load the base map. Just follow the templates. Three things to note here:

  • “state” refers to the object’s name that contains the GEOJSON data. You can name whatever you want
  • “GEOJSON” refers to to the style of the file. Mapping requires GEOJSON files, whether you load it from an external source, like we do in this case, or from a hardcoded file
  • The link that goes with “data” is where the author stores the data.

One note here: if you use Github or any cloud platform to store and source your file, be careful. For instance, let’s look at a file I have on github.

Github_Link

Just copying the usual link when you access your file on Github like that won’t work. To get the link that works, click on “Raw” and here is how it shows on the screen

Github_Content_Link

Copy the link in the browser. It should work.

Back to the HTML. Add the two “map.addLayer” code sections to what you already have. It should look like the below

map.on('load', function () {
    map.addSource("states", {
        "type": "geojson",
        "data": "https://www.mapbox.com/mapbox-gl-js/assets/us_states.geojson"
    });

    map.addLayer({
        "id": "state-fills",
        "type": "fill",
        "source": "states",
        "layout": {},
        "paint": {
            "fill-color": "#627BC1",
            "fill-opacity": ["case",
                ["boolean", ["feature-state", "hover"], false],
                1,
                0.5
            ]
        }
    });

    map.addLayer({
        "id": "state-borders",
        "type": "line",
        "source": "states",
        "layout": {},
        "paint": {
            "line-color": "#627BC1",
            "line-width": 2
        }
    });

The first addLayer is for the polygon itself while the second one is for the lines between the states. “id” refers to the name of the layer for future reference. Remember to tie the “source” value back to the name of map.addSource. In this case, it’s “states”. The rest is a Mapbox standard template for hover effect. You can change the color whenever you feel like.

The next step is to work on “hover effect”. Add the following code to the end of the previous block

    map.on("mousemove", "state-fills", function(e) {
        if (e.features.length > 0) {
            if (hoveredStateId) {
                map.setFeatureState({source: 'states', id: hoveredStateId}, { hover: false});
            }
            hoveredStateId = e.features[0].id;
            map.setFeatureState({source: 'states', id: hoveredStateId}, { hover: true});
        }
    });

    // When the mouse leaves the state-fill layer, update the feature state of the
    // previously hovered feature.
    map.on("mouseleave", "state-fills", function() {
        if (hoveredStateId) {
            map.setFeatureState({source: 'states', id: hoveredStateId}, { hover: false});
        }
        hoveredStateId =  null;
    });

The first thing to notice is here:  map.on(“mousemove”, “state-fills”, function(e) {

“State-fills” is the “id” of the polygon layer mentioned previously. So whatever name is chosen for that addLayer, it should be used here.

source: ‘states’

In this case, ‘states’ refers to the source of the data in the map.addSource section above. Remember to use the same reference name for the source. The rest is just a standard template. If you have time, feel free to explore. I am under pressure to deliver features for my Capstone, so I just prefer not touching or changing any of it.

Here is an important note. If you don’t follow, the hover effect won’t work. I use the same code as Mapbox’s example, just changing the GEOJSON source. The hover effect doesn’t work as you can see below:

The key is the data source. Let’s look at the data that Mapbox uses. Here is the tree view of the first item in the polygon array, just to show its structure

GEOJSON_2

Here is the structure of the data I used that led to the unsuccessful “hover effect”

GEOJSON_3

Notice the difference? As far as I am concerned, the hover template in question needs the data to have a certain structure. Otherwise, the code won’t work. Now, there should be other ways to go around this, but if you don’t have time, I’d suggest modifying the data to mirror Mapbox’s example. Here is the structure of my modified data

GEOJSON_4

Does the code work? You bet!

GEOJSON_5

Hopefully this post will be useful to starters like I am.

 

 

What I learned at a Managed Service Provider

It has been 9 months since I started working at a managed service provider in Omaha, where I am living now. It’s not a long time, but I have learned quite a bit and some are more profound than others.

To back up a little bit, a managed service provider is a fancy term for an IT outsourcing company. In simpler words, consider it like an advertising agency, but for IT services. If your company doesn’t have the personnel or expertise for IT needs, managed service providers are where to seek help

In this post, I’ll get to some of the things I learn and considered among the most profound personally.

IT space moves at an unbelievable speed.

In the IT world, innovation happens vertically and horizontally. Once a new breakthrough was brought to this world by one or a few pioneers, it won’t take long before many followers copy and offer alternative options to the original innovation. Some popular points of differentiation can be pricing, integration with other tools, user experience, speed, flexibility of contracts or, my favorite, customer service. As a result, innovation takes place horizontally.

Another direction for innovation in the IT space is to invent a new technology that supports or is built upon the incumbent/existing ones. It is crucial to know that no tool or technology is perfect. By identifying and trying to negate the weaknesses in every tool, service or product, innovators in the IT space give birth to new offerings. From what I have observed so far, that process happens at a lightning speed. As a result, innovation takes place vertically.

Let me give you examples with popular services that you are more likely familiar with. In the past, companies had to buy expensive servers to run their applications. That approach had a lot of downsides such as

  • Slow time-to-market (red tape, slow purchasing process)
  • High-maintenance – staff has to monitor around-the-clock in case there is a glitch
  • Lack of scalability – if businesses want to expand the capacity a little bit, they have to invest in the whole new hardware; which is a waste
  • Inefficiency – Servers usually aren’t used to their capacity. As a result, running them around the clock is a waste of time. Plus, staff has to spend time on updates, maintenance and security
  • Lack of customization – On top of a piece of hardware can there be only one operating system. Hence, if an application needs to be run on different operating systems, companies have to add more hardware. It would add to the waste of resources
  • Lack of expertise – small companies that don’t have IT staff cannot afford to hire IT personnel and invest in infrastructure at the same time

Infrastructure-as-a-Service is a solution to that, addressing the weaknesses of traditional on premise servers listed above. With IaaS, companies outsource the most foundational parts of their IT infrastructure to suppliers. AWS was the first IaaS provider and it didn’t take long for them to have competition in Rackspace, Google Cloud Platform and Microsoft Azure, each claiming to have advantages over the others. They are called Public Cloud Providers. Then, companies copy the model at a smaller scale, building enterprise-grade architecture and leasing it to other firms. From there, a complementary tool allowing a comparison of these providers’ prices is needed and of course, was born.

iaas-paas-saas-comparison-1024x759

After a while, people realized even though some components of the infrastructure are already outsourced, there is still a lot of work left that can be outsourced too. Hence, a new model called Platform-as-a-Service was born. In this model, companies only have to worry about developing applications. The rest is already taken care of. Obviously enough, the task of developing applications was soon “outsourced” too, resulting in what is called Software-as-a-Service (SaaS). With SaaS, companies buy ready-to-use software from vendors without having to care about anything else. Examples are what we use almost on a daily basis: Google Drive, Dropbox, Salesforce or Mailchimp, just to name a few. Each software serves a particular function and in that particular market, rest assured that it will have competitors.

I hope with that oversimplified example, I make my point that innovation (competition) can take place horizontally and vertically in IT. One thing leads to another and more. And that process happens, I can’t stress it enough, breathtakingly fast. AWS was introduced in 2006. 12 years later, there are so many public and private cloud providers. We have container technology and its providers such as Kubernetes or Docker. We have Pivotal Cloud Foundry as a Platform-as-a-Service and countless Software-as-a-Service offerings none of which would be impossible without cloud technology.

If you work in it, be prepared to read constantly

As I mentioned above, innovation happens constantly in IT at every single level. Look at the image above. Innovation doesn’t take place at the model level. It happens at the component level such as storage, networking, virtualization, etc…If you want to be reasonably informed, let alone being an authority or expert, reading constantly every day, understanding hundreds of concepts as well as various acronyms, and linking everything together is a must. The silver lining here is that with the Internet, there is no lack of resources to learn.

Be careful what you wish for

Data is the lifeblood of business today. Invest in the data. Analyze. Extract the insights. Act. Sounds easy, right? Not quite.

As almost all businesses go online and everybody has access to the Internet at any given time in a day, acquiring data shouldn’t be an issue. To manage the data; however, is another story. Statistical methods used to extract insights from data grow in effectiveness as data grows in quantity. The problem is that the more data a firm has, the more it has to invest in IT infrastructure. Everything from servers and storage to network has to be upgrade accordingly to accommodate the growing data. Plus, data analytics tools such as Tableau are highly expensive. The alternative is to hire data scientists skillful in free language such as R or Python. However, those individuals are in high demand nowadays and command a hefty salary.

But that’s not over. As data controllers, your responsibility for securing the data and using it responsibly is more important than ever. Compliance regulations are tighter than ever. Failure to comply can result in serious consequences. Industries such as healthcare have to invest to comply with HIPAA, for instance. Unfortunately, the required security services that help businesses comply can be very expensive. Here are a few things, including but not limited to, that are needed to comply with HIPAA:

  • Data at rest
  • Security information and Event management (SIEM)
  • Identity and Access Management
  • Cloud Access Security Broker (CASB)
  • Data Loss Prevention
  • Backup

As you can tell, the bills can be more expensive than your expectation, fast.

IT – The powerful enabler

I believe people and processes in an organization decide its fate and success. And I believe IT is a powerful enabler of those two vital factors. Tricky, fast changing and possibly expensive as it is, IT is an indispensable piece of the puzzle, helping firms, at the end of the day, do two things: save money and time.

Let’s take a look at a few examples. Dropbox used to host their application and data on AWS, but decided to build their own server. The move saved them $75 million. Regarding application development, Pivotal Cloud Foundry, a fairly new but meteoric Platform-as-a-Service, is reported to save millions of dollars and hours of work for developers. Without a robust disaster recovery (a service that quickly brings a server back up in case it goes down), companies in some industries can lose at least $6 million per every hour of downtime. These examples go to show that IT, if deployed properly, can bring a firm a competitive advantage, or improve the bottom line at the very least.

I hope that one day, this experience can be one of the dots I can connect