free html hit counter
Posted on: Wednesday, May 13, 2020 by Rajiv Popat

How To Automate Tasks And Other Mundane Stuff - Part 2.

In part 1 we looked at Automagic which allows you a event-logic-action based workflows to automate your mobile and boring and mundane bits of your life. We took an example of creating a simple mindfulness bell.

On the list of things to automate in my life one thing that takes very little time but a lot of psychic weight is picking up, listening to and then hanging up spam calls.

I am on every Do-Not-Call and Do-Not-Disturb registry out there and yet I kept getting a few calls every other day. Everything, ranging from credit card sales call to vacation packages.

There are multiple call blockers you can download and install, but there is a couple of problem with the few I tried:

  1. These folks kept changing their numbers so I wanted to be able to block out patterns rather than blocking individual numbers.
  2. Most of these blockers block the calls without picking them which means the caller doesn't pay for the call. I want to block the spam calls and don't want to get disturbed, but it feels good to know that I made a spammer shell out a tiny bit of money and not get my time or attention in return. :)
  3. When you block calls without picking them and hanging them, the caller still gets an option to leave you a voice mail which can be a nuisance. It's a common problem described here.

With these things I mind I set out to make my own call blocker.

Making a Call Blocker That Supports Pick up and Hang Up in Less than 5 Minutes:

We're going to use automagic for this. If you've gone through my first post on automagic this workflow should look really simple and self explanatory:

automagic-block-call-workflow

The above workflow is really simple. Keep it as a reference as you read the rest of this post.  Like I said automagic works on event - logic and action model. Here, it gives me the event "Incoming call" followed by a few actions. First thing I do is  drag and drop the incoming call event on the workflow.

In the detailed specification of the event (screenshot below), I have the numbers that have 1048909 and 140930 in them getting trapped by the event. The * before and after the number means any other characters or numbers before or after the pattern will still be trapped by this event. I do this since I discovered that all changing numbers from which I receive spam typically start with these numbers.

For you these can be specific numbers or any patterns like these. I even get to pick the state of the incoming call when the event will be fired, where I pick "Ringing", which basically means that I want actions connected to this event to get fired when the phone rings. All of this is set in the detailed view of the event which looks like this:

automagic-receive-phone-event

So when this event happens, i.e. I get a call from any of the these numbers and when my phone rings, I want to fire a couple of actions. These actions are: Answer the ringing call and End The Call.

If you look at the original workflow picture in the beginning of this post, both of these actions follow the incoming call event. Both actions are readily available in Automagic so I just drop them and connect them to the ringing event.

I also want to know that a spam call was blocked, so I put a speech output action (which leverages android text to speech to literally speak out a message). The commas ",,,," are for waiting for a second each, so I basically wait for 4 seconds and then my phone literally says that a "spam call was blocked". That's the last action on the workflow.

And just like that using Automagic we've built an application that folks on this XDA Forum have been asking for sometime now. :)

This is just one example of how we can use some of these powerful frameworks out there to automate some mundane aspects of our lives. If you are interested in more such automations you can watch out for more post in this series of just subscribe to this blog.

posted on Wednesday, May 13, 2020 6:16:43 PM UTC by Rajiv Popat  #    Comments [0]
Posted on: Monday, May 11, 2020 by Rajiv Popat

Automated Testing Of Microservices Without Test Cases.

I love my test cases. But real test cases are so much more than just input output testing. Most folks who I see doing Unit test cases are doing them wrong by doing just some basic input output end to end tests.

If all you're looking to do is write some simple input output test cases to verify your Web API and check if they retain the same request response values across versions of the same API that you deploy so that you can do a quick regression, you shouldn't even be writing test cases.

Diffy from the twitter team actually does a better job than writing test cases manually if this is all you're trying to achieve. Diffy takes a slightly different take on input output testing. Instead of writing test cases, if you have a fully tested stable version of a micro service or WebAPI in production and are planning on rolling out another version of the same service; we'll call this new version the release candidate; Diffy can help automate a lot of basic regression testing without even having to write any test cases.

When you want to launch a new version of release candidate Diffy allows you to make the same call to both production and the release candidate and compare differences so you know if something is broken or what's different between the release candidate and the production version.

Here is a simple example of how you can put Diffy to use for testing WebAPI's without writing Test Cases Explicitly:

To keep things simple let's start with a simple WebAPI with one simple method which are are going to assume is hosted in production. Let's say all the service does is multiply a number by five. We've written the code in a strange convoluted way (by adding the same number five times) so that we can demonstrate refactoring and then testing again using Diffy. So to begin with our controller looks like this:

MultiplyByFiveController

Let's call this service 1 and let's assume this is the version of the service now running in production:

service1running

Now Let's go ahead and deploy another identical release candidate of the service in a different port this time. This time let's call it service 2:

service2running

Ok, so now we have two identical services running. One is in production and one is a Release Candidate. Now let's get Diffy up and running to see it' request and response models are identical. That will allow us to get started with some basic testing.

To get Diffy you can get the latest diffy-server.jar from here. Once I get the Diffy jar and place it on my machine, I just need to install Java on my machine and I can fire this command to get Diffy pointing to both my services so that it can start comparing them:

startdiffy

Command:

Command:  java -jar .\diffy-server.jar -candidate="localhost:5008" -master.primary="localhost:5000" -master.secondary="localhost:5000" -service.protocol="http" -serviceName="MyService" -proxy.port=:31900 -admin.port=:31159 -http.port=:31149 -rootUrl='localhost:31149' -summary.email=''

Here Candidate is the service which is the release candidate; which basically means the newer version we are going to deploy and want to test.

Primary master is the service which is in production. Ideally, you would deploy two copies of the API in the production environment since Diffy does analysis of Request and Response objects and how they vary between two versions of production API allows it to filter noise. Let's say for example a particular attribute of the service in production was returning a random value each time, Diffy would see different values for these attributes being returned in two instance of production and understand that the specific attribute results in 'noise' and difference in values should be ignored. This second version of the production service is called the secondary master, but to keep things really simple let's keep both of those the same; which is why both primary and secondary URL in the above command point to the same endpoint.

Now if all does well, Diffy would have started a proxy where you can send the production traffic and Diffy will send the traffic to both production and Release Candidate to see if they have identical requests and responses. So since in the above command we asked Diffy to spawn a proxy on port 31900 let's send some traffic to that port and URL using postman:

GetCallOnDiffyProxy

So I make call to the Diffy proxy exactly as if I am making a call to the service. I pass a value of 8 for the service to multiply by 5. I also add a Canonical Response header because that helps Diffy identify and group calls using that name (see the word "Multiplication" in the screenshot below? that's because of the canonical resource header) but that's not mandatory. If you don't do that Diffy just groups your calls under a group called "Unidentified Endpoint". Once I make that call that I can hit the Diffy console to see if everything went all right.

DiffyDashboard

The above console shows that Diffy received a request which was routed to both the services and the difference in inputs and output of these services was zero (i.e. 0 diffs) and hence my release candidate is safe to deploy and continue to work with all production calls.

Now let's go to the Release candidate and change the internal logic from adding the same number five times to multiplying by five directly (remember we added the same number five them initially?):

CodeChangesAndRefactoringForDiffy

Note that I've just refactored the code and made changes to the service internally but the outer signatures and request response associated with the release candidate is still the same. Now I want to quickly test the release candidate for regression to see if it's safe to send to production. So I make the same postman call I made earlier again! And once I make the same post man call again, I check the Diffy Dashboard:

DiffyDashboardPostRefactoring

Notice how Diffy now shows 2 calls, the second request is for the call we made after refactoring. However since the code changes were internal to the service, the request response elements are still identical so Diffy tells me none of my services are failing and it's still safe to take my release candidate to production. The refactoring I did is safe to deploy to production.

Now let's go ahead and make a mistake on purpose. Let's say instead of multiplying by 5 we end up multiplying by 8 in our release candidate and we do this by mistake.

MultiplyByEightController

Now that we've made a mistake that effects the end output that the clients consuming the release candidate will notice and be effected by, let's see if Diffy can catch that. Lets make the same post man call a couple of additional times. Now I make two more post man calls on the proxy just to see how Diffy captures that:

DiffyFailing

Because I made two more calls to the proxy, Diffy captured those calls, passed them to production and release candidate both and noticed they weren't behaving identically and hence started showing me those two calls as Diffs. 2 out of my 4 calls are considered failures and I have a failing rate of 50%.

And just like Unit Test Results Diffy tells me what's wrong in the two calls that failed:

DiffyDifferences

I can further drill down and compare my request and response objects too. If I had huge response objects it helps to see exactly where my production and release candidate response objects vary:

DiffyDifferencesDrillDown

Like I said, this does not replace writing good Unit Test Cases or Test Driven Development, but if all you are interested in doing is writing basic input output test cases and all you need is basic peace of mind for some regression test cases, you don't need to write test cases just for that. Why not use Diffy instead?

Of course, this is just the tip of the iceberg and things get even more interesting where you can automatically take production traffic and route it to Diffy instead testing it explicitly. A lot of the testing we did here with Diffy can also be automated but that's for another day. For now this should tell you what Diffy is all about and get you playing with Diffy!

Go ahead and give Diffy a try. See if makes your automated input output testing or your basic integration testing that much simpler so you don't have to write and maintain test cases for basic micro service regression.

posted on Monday, May 11, 2020 8:47:27 PM UTC by Rajiv Popat  #    Comments [1]
Posted on: Thursday, May 7, 2020 by Rajiv Popat

How To Automate Tasks And Other Mundane Stuff - Part 1.

Your phone is always on. Always connected. And it's always with you. That makes a perfect automation server to automate most things in your life.

There are a couple of great apps out there that let you do crazy automation with your phone.  One of them is Automagic. I love it because it lets me automate most mindfulness and mundane tasks of my life.

automagiconplaystore

It's a paid tool but given the kick ass extendibility and the stuff that you can do with it - it's worth the couple of bucks the developers make you shell out. The price as of this writing is less than a cup of coffee as a decent safe.

(Full disclosure: I don't know or work with anyone from automagic and neither am I getting paid for this post, I'm just a fan of the app because it kicks some serious a$s!)

The other day, for example, I felt that time was slipping by, so I thought I'd make my own mindfulness bell that rings every twenty minutes. If you don't know yet, mindfulness bells are a thing.

There are lots of apps out there, but why buy or install a dedicated app and give it tons of permission when you can make it yourself with automagic?

Building a Mindfulness Bell with Automagic:

Automagic works on the idea of triggers and actions.

Triggers are events that happen in your phone and actions are things you want to do when a trigger happens.

So, for example, if you receive a call and your phone rings, that's an event or a trigger.

Actions are things you want to do when triggers happen. So when your phone rings (event / trigger) check if the call is from a specific number and if it is, hang up without picking the phone; that's an action.

With automagic you drag and drop triggers, logic and actions to create workflows which get fired when you have programmed them to get fired right inside your phone.

For example my workflow for a mindfulness bell looks like this:

mindfullnessnotificationworkflow

In the above workflow we use an event / trigger called the periodic timer which fires at a configurable time interval i.e. ever X seconds/ minutes / hours. That's the first step of the workflow. I click the edit icon on it, and I pick the configuration of that trigger where I specify an interval of 20 minutes (20m):

 automaticmindfullnesstimertrigger

In the above picture I use a period timer event which fires at a configurable interval. I'm telling it to start firing at 8:00 AM every morning, continue till 9:30 PM and fire every 20 minutes (20m). What happens when this trigger is fired will be an action that I add to the trigger. I now drag and drop a sound action and connect it to the timer event using drag and drop features of automagic IDE. Here is what my sound action looks like:

automagicnotificationsoundaction

I just pick one of the pre-existing chime sounds from the (notification_004) and then I start the workflow. This literally takes me less than 5 minutes to design and start running on my phone and just like that, I've introduced a mindfulness bell in my life.

Notice in the overall workflow picture how I've added another vibrate action as well. That ensures that apart from hearing the sound I also get a vibration every twenty minutes.

The Power of Something Like Automagic

Since I started using Automagic I've built a lot of workflows for myself. I am blown away by the volume of triggers and actions is provides. Literally every tiny thing that can happen on your phone shows up as an event. Literally everything you can do with your phone is an action. This is literally like writing scripts for your phone - and that too graphically.

More and more I find myself spending time to design small workflows more and more for things I need to automate and downloading less and less of small tiny apps that do trivial things.

I genuinely think you should give automagic a try. There are a bunch of other such apps that do the same thing. I liked automagic the most because I personally think it's much more powerful than anything out there in terms of collection of events and actions. You might like a different tool, too and that's cool.

Any tool is fine, but the sooner you pick one such app and start automating workflows . It's fun, it's set-and-forget and it lets you focus on things that really matter to you.

This series of posts is going to focus on automating multiple aspects of your life with this single automagic instance always running on my phone. You can keep looking here for most posts on automating the mundane stuff in your life here. Or just subscribe to the entire blog.

posted on Thursday, May 7, 2020 6:04:56 PM UTC by Rajiv Popat  #    Comments [2]
Posted on: Tuesday, May 5, 2020 by Rajiv Popat

Debugging Mysterious 500 Internal Server Errors.

When 500 Internal Server Error Shows up With Missing Logs in Event Viewer and IIS Logs.

When it comes to publishing Dotnet core APIs on IIS, 500 Internal server errors are a pain in all the wrong places.

500InternalServerError

What's most annoying about them is that most of the times, the IIS logs say nothing about what's wrong. And neither does the event viewer. In most cases these are not even logged on the event viewer. This is what makes internal server errors so difficult to debug.

Turns out that most of these can be debugged locally just fine and you can see the exact issue on the browser if you can manage to RDP into the server and hit the URL using localhost.

ErrorUsingLocalHost

But there are many a times when running the application using localhost is not an option in production. Maybe because the application uses static routing. My blog for instance, always routes to a URL even if you access it using localhost.

In cases like these, you can 'temporarily' configure IIS to spit out the exact issue and even the stack trace rather than the generic "500 - Internal server error" page even when testing things remotely.

You do this by modifying the Error Pages for your website:

errorpages

Once here you can pick the error code 500 and modify it's feature settings:

editfeaturesettings

The default here is configured in a way where you can see the errors when testing locally but when you test remotely using a simple browser from a client you will get a generic 500 error page. But you can change this to always show the detailed error messages:

detailederrors

This should make the relevant changes to the underlying web.config and once you do this you should see the exact issue on the page even when you hit it remotely over a web URL instead of the typical 500 error page.

Once you debug the issue and fix it, you can revert the configuration back to "custom error pages" for a more secure experience but this should allow you to debug those pesky 500 internal server errors rather easily and quickly. Worth noting that this makes a change to web.config of your application so if you push the codebase again or overwrite that file you may have to make the same change all over again using IIS.

This configuration has always been around but most of us spend so much time looking at logs and fiddling around event viewer whenever these issues occur in production that sometimes we forget the obvious.

Hope this helps someone struggling with debugging their very own 500 Internal server error.

posted on Tuesday, May 5, 2020 7:46:16 PM UTC by Rajiv Popat  #    Comments [0]
Posted on: Monday, May 4, 2020 by Rajiv Popat

Customizing Prompts With A Customized Terminal.

In an older post we talked about how we can customize the new Windows Terminal and make it look beautiful.  If you went through the post your terminal pretty much looks like this:

BasicTerminalLookAndFeel

Generally I'm happy with this, but I'm not happy with the prompt: "rajivpopat@localhost" part. It annoys me and I was to change or customize that.

With dos prompt was easy to change. You used PROMPT $P$G to show the path followed by the greater than sign. Which means you could just use the PROMPT followed by anything and your prompt would change to that.

With power-shell things are a little more complicated if you want to change the prompt. In Power Shell this is done using the prompt function. You can read more about it here.

In our case we are just using oh-my-posh so our power-shell profile looks like this:

powershellprofile

In the above profile we are using the Agnoster theme so to change the prompt we hop into the Angoster Profile script file which, if you have followed my previous post, can be found at: C:\ Users\ [your_user_name]\Documents \ WindowsPowerShell\ Modules\ oh-my-posh\ 2.0.332\ Themes\ Agnoster.psm1 (without the spaces).

These are the lines controlling the prompt I see on screen:

ProfilePrompt

I want to change my prompt to show a static text instead of user name and the computer name. So I change:   $prompt += Write-Prompt -Object "$user@$computer " to  $prompt += Write-Prompt -Object "thousandtyone " and my lo and behold my console looks like:

BasicTerminalWithChangedPrompt

I can obviously configure it to whatever I want. For example, I could print the time or use any combination of PowerShell functions to show anything I wanted on my screen.

For someone like me who blogs from different machines and different users names and takes screenshots being able to change the prompt and make it something constant which is same as my blog name helps.

The same file also lets you control color options and also provides how the git symbols and colors show up in the command line. If you've followed my previous post and were wondering how to you can control and fine tune the prompt this post should help.

posted on Monday, May 4, 2020 12:57:45 PM UTC by Rajiv Popat  #    Comments [0]
Posted on: Wednesday, April 29, 2020 by Rajiv Popat

The Difference Between A Nice Person and A Doormat.

Back in the day when I did consulting at a client office, a developer decided to throw a tantrum at his manager. We were in a meeting where a discussion the developers was having with his manager turned into an argument and then a fight.

officefight

One moment, it's a reasonable technical argument, another moment, this dev, is fuming with anger and the tosses the white board duster on the wall, takes off his coat, rolls his sleeves, kicks the chair, says something really nasty to his manager, slams the gate of the meeting room and leaves the meeting.

There is an awkward silence. We all look at each other. The manager is embarrassed. But in a few seconds, he pretends as if nothing has happened and continues the meeting without the developer.

After the meeting there was a general discussion on the episode with the central focus around WWYD (What would you do) if someone in your team had done that to you and my stance on this was crystal clear. If I was the manager I would have done all in my power to get the get a firing decision taken for this guy at the organization level. I would then get the firing letter printed, given him the letter and then asked for a public apology if he wanted me to take back the firing decision.

Based on how sincere his apology was and what the reason of outbreak was, I would then have calmly reconsidered if I wanted to revert my firing decision or move forward with it.

Being a nice guy, is an active decision. A choice. Not a weakness.

Both David Allen (the guy who created GTD) and a sequence in the movie the karate kid talks about the concept of mind like water. If you throw a small pebble in water, the water gives you a small splash back and then returns to calm state. If you throw a boulder in water, you get an appropriate reaction, followed by calmness. If someone throws a huge boulder at you and gets no reaction, you're not calm, you are just weak. There is no niceness or glory is being treated like a doormat and yet doing no harm.

We all like being loved and respected. But whether it's work on personal relationships, you job is not to be loved or liked by people who can't offer you basic respect and decency. When people start fights and lash out at you, not lashing out back at them tells them it's OK for them to lash out at people without any reason.

When someone is repeatedly humiliating you, insulting you and walking all over you, just taking it and doing nothing about it, is never an answer.

The mark of a nice person is that you don't start fights or don't say nasty things to begin with or you can let go things a couple of times. But when others behave inexcusably with you continuously, your inability to retaliate doesn't make you a nice person. It just makes you a weak, uninteresting, spineless doormat.

A lot of young managers I have worked with think it's cool to be friends with your team and in this desperate desire to be liked and be seen as a nice person they are willing to be treated like a doormat but never retaliate.

I also see a lot of developers who believe it's not a big deal if their manager continuously intimidates and humiliates them. It's a same problem in parenting. If you don't believe me look at a few kids throwing tantrums in the isles of any supermarket and the parents tolerating that behavior because they want to be seen as nice caring parents.

Same problem with married couples. Same problem with friendships. Today it's not hard to bump into a couple or a parent child or a sibling relationship where one person is humiliating the other person publicly and the other, is just taking it. The strategy of avoiding a fight when you are being treated like a door mat never works out in the long run.

The problem is so commonplace you have an article on life hacker around how you can avoid this issue. The bullet points in the article are spot on:

  1. Start With You - If someone else is devaluing you there’s a good chance that you’re doing the same thing, so change has to start with you.
  2. Start Teaching Others - Your response to someone’s behavior teaches them what is and isn’t acceptable, so if you roll over and take whatever they give, the message is that it’s okay for them to do that.
  3. Stop Being a Bottomless Pit - It’s great to do things for other people, unless the act of doing things for other people is how you get validation, of course. People-pleasing is not a selfless act; it’s a selfish one.
  4. Apply Confidence - If you’re used to people walking all over you, it’s likely that you’re not used to asserting yourself.
  5. Raise Your Expectations - An easy life is one thing, but sticking your head in the sand and hoping things will fix themselves is crazy—as is setting your expectations so low that you expect to be treated like a doormat.

If you've ever been treated like a doormat, I recommend you go through the entire article. From chimpanzees to bears every animals marks their territory and sets expectations of how they wish to be treated by others in their group, tribe or flock. If those expectations are not met they retaliate.

You may have seen a dogfight or a bear fight on the discovery channel where the alpha is bullying the underdog and then after a point the underdog gets annoyed, fights back and beats the crap out of the alpha.

That's an animal telling the Alpha, "I've had enough dude, step away from me!". And once the alpha backs off the underdog goes about his job of grazing the grass or straying peacefully. I personally believe that the retaliation from the underdog is what ultimately brings peace and harmony to the flock.

bearfight

I'm not saying you fight or punish everyone for every little thing, but it's equally important you have boundaries beyond which you will not allow anyone to mistreat you.

The retaliation doesn't have to be driven by anger. Neither do you have to become passive aggressive, destructive or play games. The reaction can be a calm, composed retaliation just to set boundaries but none the less, there needs to be a retaliation.

Taking ongoing abuse and allowing someone to treat you like a doormat invariably leads to failed projects, outright insubordination, broken relationships, bullying, shattered self respect and eventually does as much harm to the the person humiliating you as it does to you.

From time to time we all have to take some disagreement, even some insult, humiliation and crap. This is not about being an arrogant prick who makes everything about his / her bloated ego and self respect. It's okay to take some humiliation or even insult. It makes us a humble person and teaches us the power of self control. But equally important is drawing very specific boundaries on how much crap and humiliations you will take and making it clear that you will not be walked over or insulted beyond a point.

So the next time someone blatantly disrespects you and shows that as a consistent behavioral pattern, speak up if you can. Being nice is completely different from a being a weak, spineless doormat with no personality. We need lesser jerks in the industry and sometimes you have to become a jerk to tell someone it's not okay to be one.

posted on Wednesday, April 29, 2020 8:24:14 AM UTC by Rajiv Popat  #    Comments [0]
Posted on: Tuesday, March 31, 2020 by Rajiv Popat

Facing And Embracing Your Incompetence.

I'm incompetent. On days I feel like a absolute looser who is unable to focus and get anything done. On other days when I am productive, I see others around me being incompetent and I get urges to tell them to snap out of it and get them to get some real work done.

In my entire life span, I can count the consistently productive people I've worked with using fingers on my one hand. And just to be absolutely clear, I'm not one of them. Oh and when I'm not productive, I've got thousands of excuses about why I'm unable to give my best.

officespacemotivationposter

The other day I downloaded a version of ionic and out of the box and it wouldn't compile a hello world project I stubbed out using it's own CLI. I felt angry at the incompetence of developers who were building the ionic framework and had the audacity to throw a crappy build out there under the name of iterative development!

Then I went looking for some help and someone had already whined about it on the ionic git repository, where someone else had given them an ugly patch to unblock them. So I applied the same ugly patch myself and life moved on.

On a different day, I was trying to get .NET core 2 application migrated to .NET Core 3 and it was just annoying. Were the developers at Microsoft incompetent? Or was I just having a bad day? Or, was I incompetent for not going through all the breaking changes between two version and writing planned code rather than doing reactive development every time something broke? I told myself I was just having a bad day and pushed on applying one fix after another and migrating the code over to the newer version of the framework. This was defect driven development but I got a lot done. Maybe I was incompetent but I was productive.

Then, the other day, I got on an elevator, and pressed the button to go to the sixth floor, the elevator literally bounced around a bit, then went to basement at full speed, then shot up at full speed all the way to fifth floor instead of sixth, came to a screeching halt, opened it's door and stopped. All of us in there were shit scared and spell bound.

Then the maintenance guy shows up and tells us he had no idea what just happened but 'guarantees' it wouldn't happen again. My nerd brain is screaming to tell him that he cannot theoretically give us that guarantee till he knows exactly what happened. But as per him, 'for now' everything 'seems' fine and we could go ahead and use the elevator again. I took the stair case instead.

Like it or not, we live in a world where everything is broken. I don't know how we got there. Maybe it was materialism or maybe it was just our desire to move fast or be agile, or maybe it was just our animal instinct to win races, but we're here. And like it or not everything is either broken or will break down soon. The only question is how badly will it break down and how soon?

This also means that as much as you want your work to be reliable it is just as reliable as the underlying frameworks you use, and most frameworks you use are going to be broken at some level. Add to that, our inherent incompetence, our laziness, all the distractions, the work culture most of us are working in, the interactions you're having at work, the number of meetings we're expected to attend  and the amount of grunt work that we're expected to do. On any given day if you can get anything done, you should give yourself a pat on your back.

We live in a world where incompetence is the norm. Everyone around you is incompetent. You are incompetent and so am I. And there are only two ways to deal with this incompetence:

Embrace Incompetence and Design for Resilience.

Start your day with realizing the potential of incompetence you have and set smaller goals and turning productivity into a game. If you have a todo list that expects you to do more than 2 hours of real work on any given day you are just going to be disappointed end up feeling like a piece of crap.

Know that you are incompetent, the frameworks you work with are unreliable, your work culture is broken and above all the folks you work with are going to struggle with these exact set of issues of incompetence as you are struggling with and they too will have mood swings and productivity cycles like you and you have to deal with all of that; not to mention your phone buzzing and email streams to distract you. So just aim to get less done without feeling guilty about it. You'll be happier.

If you want any mental sanity in today's world have really low expectations about your own productivity and productivity of folks around you.

Then when you get 3 hours of work done in a day you feel good about it rather than feeling like crap. And then when your dopamine circuits kick in, instead of being being constantly depressed about being non productive you can be happy and slowly push the two hour check list to a higher hour count because you are now gaining self confidence and control.

Put simply, design your life around unreliable things and build resilience into your work routines, the quality of work you do and even your social interactions. Life today is literally a game of inches and instead of hoping to walk a focused yard, it all boils down to your ability to grab and collect those little wins and inching forward. Embrace incompetence and grab whatever tiny inches of productivity you can grab out of your own life.

Draw Incompetence Boundaries

An elevator bouncing and going to the basement when you press 6 on the dials is acceptable. The same elevator crashing and killing people isn't. They told me that the elevator has a safety mechanism in place and it could dance around all it wanted but the likelihood of us dying in an elevator crash are very low:

The only known occurrence of an elevator car free falling due to a snapped cable (barring fire or structural collapse), was in 1945. A B25 Bomber crashed into the Empire State Building, severing the cables of two elevators. The elevator car on the 75th floor had a woman on it, but she survived due to the 1000 feet of coiled cable of fallen cable below, which lessened the impact.

The elevator manufacturers have clearly drawn a line on what's acceptable level of incompetence.

My general rule is, incompetence is fine as long as it's not costing someone their life, a physical injury, mental trauma or their hard earned money. That's where my boundaries are at. Anytime there is even a remote chance that any of these are violated, I have to shake my incompetence off, get some serious work done and take extra measures to try my level best to ensure that this doesn't happen. Absolutely, no excuses allowed. Fortunately most of us work on CRUD apps where the bugs we introduce are such that we can just go "Oops! Sorry!" - fix them and move on.

Also, It's good to have boundaries around just how much incompetence you will  tolerate from yourself. For me those boundaries are pretty relaxed but every once in a while I'll snap and will send a virtual check of hundreds of dollars to my mom stating that if I don't complete this task by a specific time and send her proof of it's completion she is free to encash the check and just take the money. She is not supposed to give me a chance to produce any excuses or explanations. Do you know how many time's she has had to encash the check because of me not fishing the task on time? Zero.

Suddenly, I've taken my incompetence which was causing me some minor annoyance and turned it into incompetence that's going to cost me enough money to make me uneasy. Lo and behold, things get done. Not in months or weeks, but in days and sometimes hours.

The other important thing to realize is that the only incompetence you can address or fix is your own. Trying to fix anyone else's incompetence is a recipe for becoming an as$hole. Every loud obnoxious jerk at your workplace believes that his or her coworkers are incompetent and he / she is just trying to help them get rid of their incompetence when in reality he / she is just being an as$hole.

The other day I was watching a video about a mass murderer who was being put on the electric chair but it was taking some time. This dude got so annoyed at the incompetence of his executor that he yelled something to the effect, that his executor was incredibly incompetent and in that much time he himself would have killed half the city! Once you start looking at incompetence of anyone other than yourself and start acting on your urges to 'fix them' you have taken your first step towards being a prick because now you're seeing someone as a lesser person.

Long story short incompetence is all around us and we live in a world where there are very few people or things that work consistently. You can either bitch about it and use it as an excuse to get nothing done, brood over it and be an arrogant pompous prick who thinks every else is incompetent; or embrace this incompetence and ship anyways. I don't know about you, but I prefer the later.

posted on Tuesday, March 31, 2020 8:25:20 PM UTC by Rajiv Popat  #    Comments [0]
Posted on: Monday, December 16, 2019 by Rajiv Popat

Back To Basics - Bubble Sort.

I did a talk in one of the Microsoft Events a couple of years ago where I took the audience back to basics using C# and the folks seemed to love it and gave it a five star rating. Simple things like function pointers, delegates, basic algorithms and data structures. I think everyone should recap at-least one of these topics every week and this series is my humble attempt to share what I recap with you. Today I'm recapping Bubble Sort.

Bubble Sort

Bubble sort is by far one of the simplest sorting algorithms. Let's assume that if you have 5 numbers in an array and you need to sort these numbers from low to high. Let's assume this is what the initial state of the array looks like:

InitialState

Assuming you are sorting in ascending order, the goal is to run a for loop through every element in the array, using a simple for-loop and check if the number is larger than the number next to it. If the number is larger, swap it with the number on the right.

In the above example, the for-loop begins with 5. Because 5 is larger than 4, 4 and 5 are swapped. And then you compare 5 with 3. Basically here is how every iteration of the for loop looks like:

 firstforloopexecution


Once the for loop completes you are left with:

FirstPass

One round of the for-loop execution is what we call the first pass on the array.

From the above image you can clearly see that if I do three more passes (i.e put the for-loop inside another for-loop) the array would be sorted and the right numbers would 'bubble up' to the right places. Here is what the second pass looks like:

secondforloopexecution

From the above diagram it is intuitively evident that if you do this for three more passes this is what the outcome the third pass would look like:

ThirdPass

And the fourth pass would look like this:

FourthPass

So basically if you see each pass as a for-loop and 4 (N elements i.e. Len(array) - 1) passes as another loop, we can easily translate the above logic into code:

bubblesort

In the above code, the inner for-loop is basically a single pass where we run through each element in an array and swap values if the value of the element is higher than the value it's next element. The outer for loops is number of passes.

When I wrote the example and published the blog, Steve was kind enough the point out in the comments section of this post that the algorithm wasn't fully optimized and than it was doing way more iterations than it really needed. And he is absolutely correct. In the above example we have two loops and both are iterating through the entire array. However if you notice in the above theory after the first pass, the largest number would have essentially moved to the extreme right of the array:

FirstPass

What this means is the second pass can actually ignore the last element of the array when it iterates. The third pass can ignore the last two elements and so on. This means that the second loop can essentially be further optimized and doesn't have to iterate the highest numbers which have already been moved to the extreme right of the array. The optimized version of the code looks like this:

bubblesortwithoptimizediterations

If you want a slightly different way of doing the same thing you can also look at Steve's code in the comments of this post. Special thanks to him for pointing out the optimization which I had completely forgotten, which is why revisiting these topics every now and then often helps!

Bubble sort is not super efficient when it comes to it's time complexity, and there is hardly anywhere we hand code sorting, but the algorithm itself is something that gets thrown around a lot in discussions so it's good to know what bubble sorting is all about.

posted on Monday, December 16, 2019 10:52:43 AM UTC by Rajiv Popat  #    Comments [2]