A while back I had blogged about my Morning Routine. The routine helps set the pace for the day and in getting things done that matters to me most. During mid of December 2016, I started running once a week to get some exercise into my routine. I got interested in running and soon was running thrice a week along with some free body exercises another three days. Since this was new and exciting naturally my concentration was more on getting these done. I struggled to keep up with my blogging schedule, failed to get a video out in the month of February and lost track of everything else (FSharp, Reading, etc.). Though I continued to wake up early in the morning, I could not get much done. I badly wanted to fix things up and here is what I have come up with
- One-week sprints and setting weekly goals
- Break the Big Rocks (or MIT’s) into smaller tasks
- Improve Focus using Pomodoro Technique
- Daily Review and Weekly Review
One Week Sprints
The PSM course I attended in January made me realize the importance is sticking to a process. I decided to do weekly sprints for managing my personal work. I have a better estimate of how much I can get done with a shorter interval. I have blocked time on Sunday morning for my weekly planning and processing the ‘In-Basket.’ The In-Basket is where anything that comes up during the week goes. Todoist has an Inbox Project to which any uncategorized items go by default. I process the inbox and move them to various categories that I have setup in Todoist. Depending on the priority things make their way into the coming week or get set to ‘tentative’ dates and appropriate categories.
Big Rocks are tasks that matter to you the most. Identifying them is important so that you do not miss out on them. The idea is to fill your time available over the week with the Big Rocks. The rest will find its way through, just like if you were to fill a bottle with stones first and then fill it with water, sand as opposed to the other way round. Big Rocks are the same as the Most Important Tasks (MIT’s) that we saw earlier.
For me the biggest rock is family, and I have all of my evenings and weekends (rather any time they are awake, and I am home) blocked out for them. Over the past year, since I have written about my Morning Routine one of the MIT’s has changed. Blogging and FSharp still stay on, but I swapped in producing videos for Github contribution. Exercise is something I have set as a goal for 2017. To keep up with my exercise goal, I run three times a week and body weight exercises for another three days.
Every day I have roughly three hours of ‘me time’ from morning 4 am - 7 am. Waking up was difficult for a while but then I realized it’s all about waking up to an alarm. The ‘me time’ acts as the bottle into which I have to fit the Big Rocks into (if you watched the video above). I need to optimize the things in the best way possible to fit it all in there.
Pomodoro Sized Tasks
The Pomodoro Technique is a time management technique that uses a timer to break down work into intervals, traditionally 25 minutes in length, separated by short breaks. These intervals are named Pomodoro.
Many times in the past I have tried Pomodoro Technique on and off but was never able to stick with it. From my previous Morning Routine you can easily tell that I had a high-level plan on what my MIT’s are, but did not have any specific plans or goals on what to do about them. I also left room for flexibility to choose each day to pick up things randomly. Often it happened that I took more time to blog and got a bit of time for the other MIT’s. Though I have automated a lot of blogging activities, writing a post often took more time. And since I was not tracking this I was always happy that I achieved some of my MIT’s daily.
Once I started running things changed drastically. I struggled to keep up the with everything and concentrated on just blogging. It was because I started losing focus and started getting the feeling that it’s too hard to fit in everything. I let this happen for over a month but was not very happy with it. Mid of February I sat down and dumped all my available time onto a paper and broke them up into Pomodoro sized intervals. So now I know how much time I have in a week for getting stuff done. I then broke down my big rocks s into smaller measurable pieces. For, e.g., with blogging, I have 4 Pomodoro of work - Creating a draft (high level), Refining the post body, Writing the introduction and conclusion and finally Adding in images, proofreading, and publishing. Similarly, I broke down publishing videos (happens throughout a month) and learning F#.
Plans are nothing; Planning is everything
I blocked out the time for running and exercise first, then I filled in with blogging tasks, followed by videos and then with FSharp learning. I also have a reading goal for 2017 and found that I can best do that during my commute to work. Though this is not a full sized pomodoro interval, I have this tracked. Weekly Planning and Daily Review are two other activities that I have started following religiously. I do my daily planning right after my Daily Scrum at work so that I get to capture anything work related as well.
I was surprised how easily I could fit all of these into the time I have. Since the task breakdown above is guesstimates, I have some buffer time in my plan so that I can accommodate tasks that take more time or urgent tasks that come up during the week or the laziness that kicks in at times.
Increasing Focus and Removing Distractions
Social Media and emails were one of the biggest distractions for me. Even though I try to reduce the amount of time I spent for these, I often ended up taking a glance at those sites now and then. It often ended distracting and taking me completely off course from the task. I decided to stick to checking personal email only once a day and work emails twice a day. As for social networks (especially Facebook), I decided to keep that to one as well. I wanted to track this as well and see how well I was with it. I use Loop Habit Tracker app on my phone for tracking these habits.
For tracking pomodoro I use Tomighty, a simple Pomodoro tool. It just tracks the interval and does that thing well. The Pomodoro Technique lists down different techniques to manage interruptions and distractions. Managing interruptions is particularly useful when working out of an office and using pomodoro. During the short intervals, I usually take a walk around, fill water, stretch, etc.
I have only been following this for three weeks. But I find this effective and hope to stick on with it for a longer time. I no longer have to spend time deciding what to do as that’s already decided. The only thing is to do it. Having taken the reasoning part of what to do out, I find doing things is easy and I procrastinate less. The important thing is sticking with the process and believing in it. I am sure this is going to pass as well, but for now I happy and it works for me. How do you keep yourself productive? Sound off in the comments
I often come across functions that do multiple things. Many times such functions have a common pattern where multiple sections within the function use the same parameters for calculations. The results from these different code sections within the function are either separated by conditionals (if, switch, etc.) or combined using various arithmetic operators. The most obvious refactoring in such scenarios is to move the code sections into different functions within the same class. Having it in separate functions keeps the code readable. But on closer observation, such functions can be moved into different classes, keeping each of these code sections as the only responsibility.
Identifying the Refactoring
Within a function when a similar pattern of code repeats, it could be refactored into multiple classes and composed to give the same functionality. Let us take a simple example of a function where we are validating an Account object based on different criteria. The various criteria end up as conditionals within the function. This function can soon get big and difficult to manage. It also makes it harder to test. If you are adding more validations to this class over a period you are violating the Open-Closed Principle (OCP), the O in SOLID. Depending on the level of abstraction that we are looking at, the class also violates the Single Responsibility Principle(SRP), the S in SOLID. The function handles validations based on different criteria.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
The Composite Pattern
Composite pattern is appropriate when the client ignores the difference between the composition of objects and individual objects. The pattern helps developers to maintain the complexity of the code and also separate out class responsibilities.
Compose objects into tree structures to represent part-whole hierarchies. Composite lets clients treat individual objects and compositions of objects uniformly
In the Account validation above, the function checks for an email and validates the format, checks for valid billing details, etc. The validations could also extend on to users attached to the account and check if there is at least one user, the user has email, phone number, etc. Each of these validations can be moved into separate classes and composed together in one class so that they are all executed when an account needs to be validated. You can see a tree like hierarchy forming here, and the actual validation is composed of all these validations
The actual C# code looks like this after the refactoring.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
After the refactoring, we have separate classes for each of the validation rules. The AccountValidators class composes all the other validators and provides the same uniform interface for the consumers to validate an account. It calls on to all the Validators iteratively and invokes the Validate method on them. You can use Dependency Injection to inject in all validators to this class if you are not comfortable hard-wiring them. The IoC container can be setup using registration by convention, which prevents the needs for explicit registration for any new validators.
One other worry that I have seen common when moving to such a pattern is that - We now have a lot more classes. Does that not affect the performance?. If you are following SOLID principles to the core and want to maintain loose coupling in your code then creating more classes is something you cannot avoid. We do not want any God Classes in our code and the first step towards it is to split them into different classes.
If an Object Oriented language cannot handle the creation of many classes and objects then why should we be using it in the first place?
The composition can be complex conditions as in the case below. For, e.g., let’s say we need to execute a different kind of algorithm to calculate based on a property.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
The above composition makes it easy to test the composed parts and the composition separately. It also helps keep the tests simple and easy to understand. The code is separated into maintainable classes and each criteria can be modified independently.
Composite Pattern is a useful technique to keep code maintainable and readable. Identifying the pattern is a bit of a challenge, but the more you see it the more familiar you will be. Hope this helps!
Posts on this blog are published automatically on preset dates. I have created a custom workflow for this in Octopress, my blogging framework. If you are interested in the end to end workflow check out my video on it. Publishing to different social media was also one of the things that I wanted to automate in the whole workflow. So whenever a post is published to my blog, it also posts to the different social media (Twitter, Facebook, and LinkedIn).
Buffer is a tool to manage all your social media networks and publish content to it at one. It is a ‘Write Once, Publish Everywhere’ kind of service and works best for me. From the Buffer website or using browser extensions posts can be manually buffered. A buffered post can be published immediately, scheduled to be shared next or scheduled for a particular date and time. You can have custom messages for each of the social network that you are sharing.
For automatic updates from my blog, I use Buffer via Email. With every buffer account, there is an associated email address. A post can be buffered by sending an email to this address in a specific format. So every time a new blog is published I send an email to my buffer account to publish immediately (@postnow). Automatic sharing posts also helps me reduce the time I spend on social networks; learning to disconnect
I am on their Free plan at present. I have only less than ten posts scheduled at any point in time, and the plan provides all the features I need.
Hope this helps you manage your social media content.
I came across the Google Indic Keyboard recently and now enjoy writing in my native language. If you want to write in an Indian language on your Android device, then this post is for you
Google Indic Keyboard allows you to type messages, update on social networks or compose emails in your native language on your Android phone. At the time of writing the keyboard supports the following languages:
- English keyboard
- Assamese keyboard (অসমীয়া)
- Bengali keyboard (বাংলা)
- Gujarati keyboard (ગુજરાતી)
- Hindi keyboard (हिंदी)
- Kannada keyboard (ಕನ್ನಡ)
- Malayalam keyboard (മലയാളം)
- Marathi keyboard (मराठी)
- Odia keyboard (ଓଡ଼ିଆ)
- Punjabi keyboard (ਪੰਜਾਬੀ)
- Tamil keyboard (தமிழ்)
- Telugu keyboard (తెలుగు)
Setting up the keyboard could be a bit confusing as changing keyboards is not something that we often do. I ended up spending some time walking through the setup for some of friends and family.
In Google Play Store search for [Google Indic Keyboard]. If you have not installed/updated before, tap on Install or Update to get the latest application version.
Once installed go to any of the apps where you can open the keyboard. On the bottom right corner tap the icon to change the keyboard.
From the window that pops up select “Choose Keyboards.”
Enable Google Indic Keyboard (English and Indic Languages) listed in the list of available keyboards.
Repeat step 2 and open up the Change Keyboard window. Select Google Indic Keyboard from the list.
The keyboard is now set as Google Indic Keyboard with its default language. To choose a language of your choice, select the Indian Language icon on top left.
From the window that pops up select the language of your choice. For me, it’s Malayalam.
Google Indic Keyboard supports different layout.
- Native Keyboard: Type directly in your native language.
- Transliteration Mode: Get output in your native language by spelling out the pronunciation using English letters(For, e.g., Malayalam -> മലയാളം)
- Handwriting mode (currently available for Hindi only) - Write directly on your phone screen.
- Hinglish mode - If you choose “Hindi” as an input language, the English keyboard will suggest both English and Hinglish terms.
Type away in your native language :)
The transliteration mode is impressive and intuitive. Its fits in perfectly with how I was earlier using my messaging apps; native language spelled out using English letters. The better thing now is that it automatically converts into my mother tongue. The Indic keyboard brings back the forgotten love to my language. Thank you, Google!.
AutoFixture is an open source library for .NET designed to minimize the ‘Arrange’ phase of your unit tests in order to maximize maintainability. Its primary goal is to allow developers to focus on what is being tested rather than how to setup the test scenario, by making it easier to create object graphs containing test data.
If you are on .NET platform and write tests (there is no reason you wouldn’t) you should check out AutoFixture. AutoFixture makes test data setup easy. It is a generalization of the Test Data Builder pattern and helps make your tests more robust and maintainable. Below is a sample (as taken from the GitHub page) shows how minimal setup is required for testing. Check out the post, Refactoring Test Code: Removing Constructor Dependency to see in detail how AutoFixture can be used to make the tests more stable against changes.
1 2 3 4 5 6 7
If you are new to AutoFixture, I highly recommend checking out the Cheat Sheet to get started. Check out my post on Populating Data for Tests for some common patterns of using AutoFixture and how it can reduce setup code. Understanding the Internal Architecture of AutoFixture helps if you want to extend it for customization. AutoFixture integrates well with the different testing frameworks and support libraries that are popular. I mostly use it with xUnit and Moq.
Hope this helps with your testing!
I am happy to have contributed (minor) to such a great library.
It’s about three months since I started running. I just completed my first half marathon and thought of putting together on how I have been going on with my running. I had a lot of questions myself when I started running, so hope this helps someone else taking the same journey.
I started running using the Runtastic application on my android phone. The free version app offers most of the required features to start running. I upgraded to their Premium version primarily for Runtastic Results(more on it below).
Once I got regular with my runs I wanted better tracking, mainly to monitor heart rate. I was unsure of what a heart rate monitor would provide and if at all there is any value in getting one. I reached out to my runner friends, and all of them had one. Most of them had a Garmin, and a few had Fitbit. Until then I was planning to get the Fitbit Charge 2 which comes with optical heart rate monitoring. It primarily uses an optical sensor and senses the heart rate from the wrist. The Garmin’s make watches that are more specific for runners, and since the majority of my friends owned Garmin, I decided on to get one of the Garmin Forerunner series.
One of the shops near to where I live was running a promotional offer on the Garmin Forerunner 630 Bundle. But this model comes with a Heart Rate Monitor (HRM) Strap. The strap needs to be worn around the chest during the run. Strap v Optical HRM added a new dimension of confusion to the whole tracker story. I reached out to my runner friends again and surprisingly all of them had models of Garmin that uses an HRM Strap.
The Garmin Forerunner 630 is a GPS SmartWatch with Advanced Running Metrics. It provides all the data a runner needs (and a lot more than what I need). Paired with HRM monitor it helps measure cadence, vertical oscillation and additional running dynamics like ground contact time balance, stride length and vertical ratio. I still don’t understand all the data that it shows but find the GPS tracking, heart rate monitoring and zones, training plans and custom workouts a great help to my runs. Garmin also integrates well with Strava where most of my other friends are there. The watch has a companion app on the phone and also a website which helps visualize the data.
Runtastic Results provides a 12-week bodyweight training plan with the premium subscription. I am on week five of the training. It took a while for me to get started but now I try not to miss it. The free version of the app has all exercises available as stand-alone exercises. You can use these if you don’t want to get the premium subscription.
I am following a diet to lose weight, and I weigh now 78 (±1) kilos and has been on that for around one month. I was around 95 when I started out with the running and diet.
During the first few weeks of running, I was mostly doing free runs and trying to cover the maximum distance possible. The tracked information was useful in isolation to a specific run, and I did not do anything to improve. I then started on a beginner training plan with Runtastic to Run 50 min after 6 weeks. This put me into the mode to compare my runs with the previous and work to improve on them. Now and then I wanted to stop the plan and continue with my normal run as I felt the plan wasn’t working. But I decided to stick to the process until the end. On completion of the training, I was able to run continuously for fifty minutes, and that was a measurable improvement for me.
My friend and colleague Tony is an avid runner. To improve on the pace, he advised starting shorter interval training. To improve pace, fix the pace to what you want to achieve and run for a specified interval (time or distance). Garmin enables you to create a custom workout setting various parameters on the run. The custom workout helps to keep up with your goals during the run.
Running at a constant pace is important to help cover longer distances. Initially, I used to run with all my energy. So my pace often spiked and then fell and then spiked again. If you are training to improve your speed, it’s hard to tell whether there is an improvement in speed unless you run at a constant (little variation) in speed. Check out the graph that plots your pace to check the pace variations. Most running applications show this information.
Proper breathing is one the key things with running. I did not give much importance to breathing at first. I found it very hard to run long distances without stopping in between by following a random breathing pattern. There are different suggestions on breathing style. I found the article Running On Air: Breathing Technique helpful and try to follow the pattern mentioned there (quoted below).
The singular point of all rhythmic breathing patterns is this: Exhale on alternate footstrikes as you run. You never want to continually exhale on the same foot. The rhythmic breathing patterns I recommend call for a longer inhale than exhale. Why the longer inhale? Your diaphragm and other breathing muscles contract during inhalation, which brings stability to your core. These same muscles relax during exhalation, decreasing stability. With the goal of injury prevention in mind, it’s best to hit the ground more often when your body is at its most stable—during inhalation. Let’s start with a 5-count or 3:2 pattern of rhythmic breathing, which will apply to most of your running. Inhale for three steps and exhale for two.
I particularly liked the reference to yoga and meditation in the article. It gave the realization that running is a form of meditation. Establishing a breathing rhythm helped me run longer distances comfortably and without losing breath. If you want to get a deeper understanding of breath and how it affects our life I recommend reading the book Science Of Breath.
I ran my first Half Marathon on 25th of March. I did at a casual pace to understand what it takes to run one. I tried to keep my pace between 6:15 - 6:30 min/km and was able to finish it at 6:19 min/km. It took me 2:13:11 hours and I am glad that I did not stop even once. It was more a mental game to stay at it than anything physical, and I am happy that I could finish it successfully! Hope this helps someone else as well starting off with running. Sound off in the comments if this helps you or some tips if you are already a runner!
Visual Studio (VS) 2017 improves a lot on Code Navigation features. If at all anything ever attracted me to ReSharper it was code navigation (though I have not been using it for a couple of years now). Visual Studio lacked behind in this aspect but not anymore. The new features help improve developer productivity and here are few I found worth looking.
In earlier versions, the navigation features are all over the menu. In VS2017 all the navigation features are available under Edit -> Go To. Though I usually prefer using the keyboard shortcut for opening the navigate dialogs, it’s good to have all under the same menu.
Control + T brings up the Go To Dialog box which now has a lot more icons and options compared to the previous VS versions. Typing in ‘?’ lists the different filtering criteria available when querying. It also allows searching across all the criteria by just not specifying the filtering criteria. To search for a file, type in ‘f FileName’. These filters also have direct shortcuts as shown in the image above.
CamelCase search is the one that attracts me the most. By entering just the capital letters of the name it quickly filters out the particular class. As shown below by just typing CSG it brings up the class CharSequenceGenerator. Typing in the full class name is no longer required and makes navigation faster.
Check out the video to see these features and more in action. Hope it helps!
Tracking is essential for measuring progress. Depending on your area of focus tracking tools differ. If it is a time-based activity that you are tracking a simple watch can suffice the need. But this can soon become an overhead. Rescue Time helps track time spent on a computer or mobile devices.
Rescue Time is a personal analytics service that shows you how you spend your time and provides tools to help you be more productive.
Rescue time runs in the background and helps you track the applications and websites that you use. Most of the applications are categorized automatically; However, it also allows manual categorization. Rescue Time lets you edit an activity and assign it to various categories and set productivity levels. So if you are spending more time on an application configured as very productive then your overall productivity pulse is higher for the day.
Once you have your time tracked you can then adapt yourself to be more productive. Various reports are provided to visualize the data collected. The premium version offers a lot more features to help improve productivity. I am currently on the Free Plan. Rescue Time helps inspect your current behaviors and patterns at work. Once you have the details, you can understand where your time is spent and improve on it as required. Rescue Time is available for computer and mobile devices. Hope this helps track your time and become more productive!
“Oh yes! That is an expected error. It is because…”.
How many times have you given that explanation yourself or heard the other developer tell that? Known errors or exceptions are common in applications and us developers find ways to live with such errors. At times when the number of such errors grows it becomes a problem directly or indirectly to the business. These known errors could either be exceptions in application logs, failed messages (commands/events) in a message based architecture, alert popups in Windows client applications, etc.
We should try and keep known errors and exception count close to zero. Below are some of the problems that can happen by ignoring it over a period.
Since the errors are known to us, we train ourselves or even the users to ignore them. It is easy to justify that fixing them does not have any business value as there is no direct impact. This assumption need not be true. If a piece of code has no value then why is it there in the first place? Possibly it is not having any visible effects at present but might be having an impact at a later point in time. It could also be that it is not affecting the data consistency of your system, but is a problem for an external system. There can be business flows that are written at a later point of time not being aware of this known error. Some developer time gets lost when glancing over such errors or messages in the log which directly equates to money for the business.
Important Errors Missed
If there are a lot of such known errors, it is easy for new or important ones to get missed or ignored. Depending on the frequency of the known error, it can end up flooding the logs. The logs start to get overwhelming to monitor or trace for other issues with lots of such known errors. The natural tendency for people when they find something overwhelming is to ignore it. I worked on a system which had over 250 failed messages coming to the error queue daily. It was overwhelming to monitor them and was soon getting ignored. Important errors were getting missed and often ended up as support requests for the application. Such errors otherwise could have been proactively handled, giving the end user more confidence.
Lower Perceived Stability
The overall perceived stability of the system comes down as more and more such errors happen. It is applicable both for the users and developers. When errors no longer get monitored or tracked, critical errors gets ignored. Users have to resort to other means like support requests for the errors they face. For users who are new to the system, it might take a while to get used to the known errors. These errors decrease the trust they have in the system and soon starts suspecting everything as an issue or a problem.
Seeing more and more of such errors does not leave a positive impact on the developers. It’s possible that developers loose interest to work on an unstable system and start looking for a change. It is also a challenge when new members join the team. It takes time for them to get used to errors and exceptions and to learn to ignore them.
Errors of a particular type can get stereotyped together, and get ignored mistaking it for one that is already known. It is easy for different ‘object null reference exception’ error messages to be treated as a particular error whereas it could be failing for various reasons. At one of my clients, we had a specific message type failing with the null reference error. We had identified the reason for one such message and found that it is not causing ‘any direct business impact’ and can be ignored. The message was failing as one of the properties on the message was alphanumeric while the code expected numeric. The simple fix in the code would be to validate it, but since this was not causing any business impact it was ignored, and messages of that type kept piling up. Until later where we found that there were other message formats of the same message type failing which was for a different reason. And those messages were causing a loss of revenue to the business. But since we were stereotyping the error messages of the particular type to the one that we found invalid and not having a business impact all of such messages were ignored. The stereotyping resulted in the important message getting ignored.
Maintaining a Known Bugs Database
When having a large number of such errors, it is important to document a list of such errors.It forces us to a new document and also comes with the responsibility of maintaining it. For any new developers or users joining the system, they need to go through the documentation to verify if it is a known error or not. Internalizing these errors might take some time, and critical errors can get missed during this time. Any such document needs to be kept current and up to date as and when new errors are found or more details found for older ones. This is not the best of places where a developers time is spent.
Count Keeps Increasing
If the count of such errors is not monitored and not valued for the probability of the number of error messages increasing is higher. New errors getting introduced will not be noticed, and even when noticed it becomes acceptable. We already have a lot of them, so it is fine. It sets a wrong goal for the team and can soon become unmanageable.
New Business Flow Assuming Exceptions
Since the exceptions are so used to, it is highly possible that we set that as an expectation. New business flows come up expecting a certain kind of exception to be thrown or assuming a particular type of message will not get processed. Since we are so used to the fact that it happens, we take it for granted and start coding against it. It might be the last thing that happens on a project, but believe me, it happens!. Such code becomes harder to maintain and might not work once the actual exception gets fixed.
Ignoring exceptions and getting around to live with it can be more costly over a longer period. The further we delay action on such errors the higher the cost involved. Even though there is no immediate or direct business value seen from fixing such errors, we saw that on a longer run it could have a great impact. So try not to live with such errors but instead prioritize them with the work your team is doing and get it fixed. A fix might not always be an extra null check or a conditional to avoid the error. It might seem the easier approach to reducing the errors but will soon become a different problem. Understand the business and explore into what is causing the error. Do you have any known exceptions in the application you are working? What are you doing about it?
Over the past couple of weeks, I have been trying to improve my focus while working. With running (3 * 1.5 hours a week) and bodyweight training (3 * 30 minutes a week) taking a significant part of my morning routine, I have less time for blogging, learning, and videos. Though I have known The Pomodoro Technique for a long time, I never practiced it regularly. With less time and more things to get done, I badly had to do something to get back on track with everything and thought of giving it a try.
The Pomodoro Technique is a time management technique that uses a timer to break down work into intervals, traditionally 25 minutes in length, separated by short breaks. These intervals are named Pomodoro
Initially, I was looking at apps that can integrate with Todoist, my task management tool. There are a lot of pomodoro apps that integrate with Todoist, but I found all of them an overkill. Tomighty is a simple Pomodoro timer that just tracks time and settings for the Pomodoro interval and long and short breaks. It hides away well in the Notification area of the taskbar and shows the amount of time left in the current interval. It plays sounds when an interval starts and ends. You can interrupt a Pomodoro session and restart it if required. That is all that you need from a timer to keep up with the Pomodoro technique.
If you are on a high DPI machine running Windows, the UI might not scale well. There is a workaround for this.
Sticking to the Pomodoro Technique has been working well for me, and I am able to focus better on the task at hand. I am still exploring the technique and trying to improve on it. Do you use Pomodoro Technique? If you are new to Pomodoro Technique and want to learn more check out the book, The Pomodoro Technique, by Francesco Cirillo, the creator of the technique.