free html hit counter
Posted on: Thursday, May 21, 2020 by Rajiv Popat

Boxing Your Help Time.

The other day someone was talking about pair programming at work, and someone said, "I already pair 5 hours of my day every day helping others".

Help Time - is a time in your schedule that is usually not accounted for. It's really hard to plan for and it usually begins any time someone walks to your desk and says, "Got a minute? I need your help."

And that's paid help. One of my bosses believed that as seniors we get paid to help. His belief was simple:

It's a silent part of our work profile. We are paid to help, mentor and train others. You should have an open door and an open heart when someone walks up to you for help specially at workplace.

To an extent I agree, but when your entire day goes in helping others put out the same kind of fires, it's often time to introspect philosophically if helping folks is really helping them? Or just making them dependent on you and boosting your self ego? Is that what you are really getting paid to do? When it comes to professional life, help without training and mentoring usually harms both the giver and the taker.

Then there is unpaid help. Someone, somewhere, who is remotely related to you, whose laptop just broke down and merely by the virtue of the fact that "You are in IT" you are expected to replace their RAM.

NoIWillNotFixYourComputer

You know, the kind of help we all know about.

A lot of folks and self help gurus speak at length about the power of No. 'Just say no' is what almost every book out there says. But no is not always an option. Specially for people who are reluctant at saying no. As a regular nice guy (or girl) your chances of being exploited using the help bait are much higher than a jerk who can say no and get away with it.

There is nothing wrong with helping, but there are a few simple things you can do to not bite into the help bait more than you actually want to. Here are some:

#1: Help using advice, direction or artifacts: Advice and direction are easy to provide. A five minute conversation which says 'look at this' or 'google that' and you give the seeker a general direction he or she should go towards. If you want to be a little more involved give them an artifact which others can reuse. Scott Hanselman has an excellent post on the topic of building reusable artifacts while helping others, so I won't repeat that material.

#2: Help but in a timeboxed duration: Sometimes advice, direction or artifacts aren't enough. There are times when takers will seek for explicit customized help. For example that uncle of yours's who wants a full blown accounting system and he is expecting you to build it for free. This is where you don't have to say no to helping, but make it very clear that you would love to help but you're busy (see point #4 on excuses) and so you're only going to be able to do X.

This X, could be as simple as - "I won't be able to design an entire application for you but I can connect you with someone who does this really well and at a reasonable price. I'll also be there in the first half hour meeting to connect you two and then you guys can negotiate a rate and take this forward. It's the only person I know so I won't be able to connect you to others but you can look at others online if you don't like this guy."

Whether you are helping your fellow developers or personal acquaintances, time boxing your help time is a good idea and when that time runs out, schedule for a different day in your calendar. The other day a school friend called for a help he needed and I told him I'm completely booked (again, see point #4 on excuses) but, "let me get that done for you by Friday late evening". There was a slight awkward silence because he just needed an hour of my time and he was probably expecting immediate help, but he was finally ok with Friday late evening and we both were happy with the arrangement. As much as I wanted to help him on the same day, I couldn't help it. My help time quota for the day had already run out. When you run out of money you can't spend more. Time is no different when you budget it.

#3: Recognize Patterns: If the same person calls you from help regarding the same kind of thing over and over he isn't seeking help. He is just exploiting you. For example I had an acquaintance who had a habit of visiting strange sites and getting his machine loaded with malware ever couple of months.

The first time it happened I showed him how to reimage his machine and a couple of weeks later he called me again, stating his machine was infected again, how he wasn't feeling confident reimaging it himself and would 'prefer' I do it. I told him I wouldn't mind doing it but in that case it would have to wait for two months since I am badly tied up with this huge project I had taken up and may have to fly out next week.

Next day he called me about a small question when he was stuck trying to do it himself. I answered the question and he was able to get it done.  Win-win.

Recurring patterns for same kind of help isn't someone seeking for help. More often than not it's someone exploiting you and sucking your time to feed their own agendas and their own laziness. They aren't bad people but when you help them with the same problem again and again instead of empowering them to fix it themselves you are feeding their laziness.

#4: Plan our excuses ahead of time and practice with loved ones: I have a collection of excuses predefined for all occasions. A few of these are ones that can be pushed back or questioned, which lets me validate how serious a person is. For example, "I've got  a meeting during office hours but can we sit at 10 in the night and work at it?" - If the person' isn't serious he would usually refuse that offer. If he accepts the offer I can always tell him I got another call at 10 and help him the next day. Win-win.

Then there are excuses in my quiver that just cannot be challenged or negotiated with. For example, "I can't, I'm doing a course on machine learning and have my exam scheduled on that day". I've researched into which course, which exam and have rehearsed this excuse a thousand times over so I don't feel reluctant using the excuses. Be careful when using this though, since in most cases you aren't even obligated to give an excuse. Just saying "I have other important work (or personal) commitments" convincingly should be enough.

As geeks helping folks who are stuck is second nature to us. We see something broken and want to fix it. A lot of folks actually thrive on this weakness of ours. Practicing excuses and having a pre-planned list of excuses for each occasion in your repertoire helps a lot, especially if you are not great at saying no assertively. That's a skill I need a lot of work in.

Helping someone is a noble act and there is nothing wrong with helping people. It's a form of altruism. And like every charity, when it impacts your own well being it becomes dysfunctional. You can only give a small portion of what you have, and when it comes to time, it's really important you put a stake in the ground and pre-decide what percentage of your time you want to dedicate to helping others.

If it's a loved one you can give them a lot of time, if it's acquaintance who is a perpetual taker you may choose to give him nothing. There are no right answers but whatever you do, you should be doing it deliberately. Every time someone requests for help you shouldn't be taken off guard and end up providing hours or your precious life just because you were guilted or emotionally arm twisted into it.

Timeboxing help and picking who to help and how much to help, is an art you master and as you master the art you actually get better at helping people you really want to help and providing help on things you really care about. Go on, plan your help time deliberately and provide help that really matters to people who really matter to you.

posted on Thursday, May 21, 2020 8:16:40 PM UTC by Rajiv Popat  #    Comments [0]
Posted on: Tuesday, May 19, 2020 by Rajiv Popat

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

Automating Buy and Sell Alert for Shares On Your Android Phone.

In my last post, I talked about a simple automation using a python API that constantly monitors price of shares I am interested in and tell me when I should buy and sell them. The API, when called returns a simple JSON which tells me which shares or scripts I should buy and which ones I should sell based:

pythonresponse

Now that I have the API up and running, I need to call that using my mobile phone every hour during business hours and get notified if the price of a share changes and falls in the threshold where I need to act.

That way I can stop staring at my phone all the time and only look at share prices when something I want happens in the stock market.

Automation is all about deliberate and mindful attention and mindlessly staring at stock prices every couple of hours is no way to live specially when trading isn't your full time gig.

I've already talked about how I automate stuff on my android phone using Automagic. So let's use automagic to call this API every hour, parse the results and show alerts and notifications.

Automagic allows me to call an API and parse the JSON responses that I get back from the API using custom code. My overall workflow looks like this:

automagicstockpricescriptworkflow

I use a periodic timer to fire every 25 minutes (you can make this as low or high as you want, even run it every minute if you like) during working hours (1o AM to 6 PM). In these runs, I fire an HTTP-Get (or post, depending on the API you are writing; mine uses a Get) and pass appropriate parameters. Here I'm just passing the username since it's a quick API I wrote using python just for myself.

Once I get the response back from the python script on server I can use the script action in automagic to write custom script to parse the response. My script looks like:

automagicstockpriceactualscript

Now all my buy and sell are contained in a single variable call buysellscript which happens to be a list of strings and I can access that variable from anywhere in the workflow.

If you go back to the entire workflow diagram in the beginning of this post,  the first thing I do after this script parsing the results, is check if the buysellscript variable has a list count of more than zero. This variable will have value (or a count / length of the list will be larger than 0) only if I need to buy or sell shares based on my high price, low price and the live market price of the shares I want to monitor.

If the variable has a value, I need to pay attention to my phone and act. So I use a speech output action and make my phone say out loud using google text-to-speech that I need to buy or sell specific scripts. The phone speaking out loud and telling me that I need to buy or sell specific shares not just grabs my attention but is also often a great conversation starter in parties and in office meetings. :)

Then I show the same message using a dialog box. I can even vibrate my phone in a certain way if I want. All of this grabs my attention when a share becomes worth buying or selling. For the rest of the time I can be completely free and blissfully unware of what the stock market is doing.

And just like that my stock trading pretty much runs on auto-pilot. Earlier I would monitor only a couple of stocks at a time, now I can literally set watches on dozens in my very own private database, set-and-forget, trust the workflow to inform me if something important happens to stocks I am monitoring and move on with my life.

I set fair buy and sell values of stocks every couple of days or weekends and update the database. Once I've done that, I stop looking at the stock prices. No Fear Of Missing Out, No constant distractions.

If you invest in stocks, what are you doing to automate or make your investing experience better? What other things grab your attention and make you stare at your mobile every few hours? Have you thought about automating those things?

A lot of people talk about automating a lot of things and some even take automation to extreme but for me the best automations are not just automations that save time, but automations that give you a peace of mind. Automations that assure you that if something you want to know about happens, you'll be informed. You don't need to be glued to your screen or on a app all the time! Automation isn't about becoming obsessed about saving a few minutes but about getting your life back and this by far is one of the really good examples of automation in my life that does exactly that.

posted on Tuesday, May 19, 2020 8:32:47 PM UTC by Rajiv Popat  #    Comments [0]
Posted on: Friday, May 15, 2020 by Rajiv Popat

Automating Buy And Sell Alerts for Shares Using Python.

Learning a new programming language is no different than learning a new spoken language. The biggest hurdle to both isn't picking up the language. It's having a lack of opportunity to then use the language in the real world so you become proficient at it.

I've been playing with python for a few months now and the only reason I've been able to hold on to it and become decently acceptable in the language is because there are a lot of opportunities to use python in your personal life. So if your work doesn't demand that you use python you can still put it to use in the real world to solve real problems.

For example, I have a requirement where I set fair value of stocks and buy or sell shares when the prices of a stock go outside this range. That is, if the price of a share falls beyond a certain value I want to know instantly so that I can buy the share and if the price shoots up beyond a certain value I want to be notified so that I can sell the script. The problem is I don't have time to monitor share prices all the time. So I decided to put python to some good use and see how versatile the language is at automating this task.

Building A Price Tracker For Your Portfolio Which Gives Buy/Sell Notifications Using Python:

The first and the biggest step to this automation is to get the current market price of a share / script. There are a lot of paid services that do this but I wanted to get this for free. Python gives me an excellent library called beautiful soup for parsing HTML so the task of screen scraping shouldn't be as daunting as it is in some other languages.

What I discover is that Yahoo Finance shows me the price of a share. To fetch the price of the share all I have to do is hit a URL: https://in.finance.yahoo.com/quote/ + [name of the script whose price I want to fetch]. So, for example: This URL gets me the price of a script called TVSMOTORS in the Indian National stock exchange.

yahoo

The bit highlighted in blue square above (342.35) is the exact value I need to fetch. To fetch that I select that element using google chrome developer tools, pick the specific div and just click copy selector:

yahoostockpricecopyselector

Now we tweak the selector and it basically looks like this:

#quote-header-info > div . My\(6px\) .Pos\(r\). smartphone_Mt\(6px\) > div (without the spaces).

With this I can write a simple script and fetch the price of the script using python using just five lines of code!

stockpricefunction

That's impressive! Screen scarping technologies and frameworks have come a long way and have become really elegant. Now that I can get the price of a script, I can store the high value (above which I want to sell the shares) and low value (price below which I want to buy) in a SQL Server table and then compare those with the real-time prices we fetch using screen scrapping. [Before you flame me for using SQL server with python, I'm doing this because I already have a server with SQL server for this blog :)]. I can do all of that easily in just about 20 lines of code more:

pythongetallresultsforstockprice

That's another 20 lines of code which looks up my SQL table by user, fetches all high and low prices of shares I've preconfigured, compares them with the current price of shares, does this for all shares in my portfolio and tells me if I need to buy or sell specific shares. And I run this on flask:

pythonflaskscriptrunning

And just like that I have an API that can compare of my portfolio of stocks, their low and high prices set by me with the current price in market and then tell me if I should buy or sell specific shares:

JsonResults

I can now host this on any Linux (or windows) box or container and can consume it with a mobile application or even using my automagic automations or a custom mobile application, but those are topics for a different post.

Long story short, in less than 10 lines of code in python I'm able to fetch prices of scripts. Another 40 odd lines and I can compare my entire portfolio and get insights on which stocks I should be buying and selling and turn the whole thing into a WebAPI I can call from anywhere. If I wanted to I can scale this API and open this for everyone because the concept of user is already baked in the design of the database.

In the next couple of posts we will talk about how we can deploy this on a live URL and how we automate the notifications on an android phone. Till then, If you are a .NET developer, and if you've never tried a different language, python is an excellent language to start playing around with because it's really elegant, versatile and with only a few lines of code you can get a lot done. And most of all, you can use it to solve your own real life problems even if your next work project doesn't require you to use python.

posted on Friday, May 15, 2020 5:18:57 PM UTC by Rajiv Popat  #    Comments [0]
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 [1]
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]