Understanding how fast your code runs and how much memory it uses is a superpower for any programmer. This post will guide you from the basics of time and space complexity to more advanced concepts, using real-world analogies, visuals, and simple code.
Searching users based on multiple weighted factors is a common challenge in social platforms and marketplaces. This article explores how to build a sophisticated user search system using Elasticsearch with weighted scoring algorithms for factors like location proximity, network connections, past interactions, and financial transactions.
Divide & Conquer is a powerful algorithm design paradigm that breaks complex problems into smaller, manageable subproblems, solves them recursively, and combines their solutions. This post explains the divide and conquer approach, its applications, and provides detailed examples with visualizations to master this fundamental technique.
This guide explores the core principles, scaling strategies, and architectural designs for building scalable, resilient, and performant database systems.
Want to master data structures and algorithms (DSA)? Here’s a quick guide to the most important topics, what they’re used for, and how to get started. Each topic links to a detailed, beginner-friendly post on this blog.
Handling API rate limiting can be a challenge, especially when you need to manage multiple requests efficiently. Today, we will explore an elegant solution using Celery and decorators to handle rate limiting from APIs on the caller side. We will delve into the sliding window algorithm, understand the problem we are solving, and go through the necessary steps to implement and test this solution.
This guide provides a hands-on walkthrough of PostgreSQL SQL, from basic queries to advanced optimization and real-world scenarios. Each section includes annotated code and practical tips to help you write efficient, effective SQL for any project.
A Binary Search Tree (BST) is a binary tree that maintains sorted order for efficient search, insertion, and deletion. This post introduces BSTs, their properties, use cases, and provides practical Python examples and problems for understanding tree-based data structures.
Segment Trees and Fenwick Trees (Binary Indexed Trees) are advanced data structures for efficient range queries and updates. This post explains their differences, use cases, and provides practical Python implementations and problems for mastering these structures.
Union-Find (Disjoint Set) is a data structure for efficiently managing and merging disjoint sets, supporting fast union and find operations. This post covers the principles of union-find, its applications, and provides practical Python examples and problems.
In the realm of web development, maintaining a clear and concise record of changes made within an application is vital for various reasons, ranging from auditing to debugging. Django, a high-level Python web framework, provides a flexible middleware system that allows developers to intercept and process HTTP requests and responses. In this tutorial, we’ll delve into implementing a Change Log Middleware in Django, step-by-step, to track and log changes made to models and actions within our application.
Dynamic Programming (DP) is a technique for solving problems by breaking them into subproblems and storing results to avoid redundant computation. This post introduces DP tables, their use cases, and provides practical Python examples and problems for mastering dynamic programming.
A linked list is a linear data structure where each element points to the next, allowing efficient insertions and deletions. This post explains the fundamentals of linked lists, their types, use cases, and provides practical Python examples and problems.
A Trie (prefix tree) is a tree-like data structure optimized for storing and searching strings, especially for prefix-based operations. This post covers the basics of Tries, their use cases, and provides practical Python examples and problems for string manipulation and search.
Backtracking is a problem-solving technique that incrementally builds candidates and abandons those that fail constraints, often visualized as a recursion tree. This post explains backtracking, its use cases, and provides practical Python examples and problems for mastering recursive search strategies.
Topological Sort is a method for ordering the nodes of a directed acyclic graph (DAG) so that each node comes before its dependencies. This post introduces topological sorting, its applications, and provides practical Python examples and problems for mastering DAG algorithms.
A graph is a collection of nodes connected by edges, used to model relationships and networks in computer science. This post introduces graph representations, key concepts, and provides practical Python examples and problems for understanding graphs and their applications.
Graph algorithms such as Depth-First Search (DFS) and Breadth-First Search (BFS) are essential for traversing and analyzing graph structures. This post covers the basics of DFS and BFS, their use cases, and provides practical Python examples and problems for mastering graph traversal techniques.
A heap is a specialized binary tree used to efficiently maintain a dynamic ordering of elements, and a priority queue is an abstract data type built on heaps. This post explains heaps and priority queues, their use cases, and provides practical Python examples and problems.
The Sliding Window technique efficiently solves problems involving contiguous subarrays or substrings by maintaining a window that moves through the data. This post covers sliding window patterns, their use cases, and provides practical Python examples and problems for mastering this approach.
A queue is a First-In-First-Out (FIFO) data structure, while a deque allows adding and removing elements from both ends efficiently. This post explores queues and deques in Python, their operations, use cases, and provides practical examples and problems.
Greedy algorithms build solutions step by step by making the locally optimal choice at each stage, aiming for a global optimum. This post explains the greedy approach, its use cases, and provides practical Python examples and problems for understanding greedy strategies.
A stack is a Last-In-First-Out (LIFO) data structure used for managing data with push and pop operations. This post covers stack fundamentals, typical use cases, and practical Python examples, including common problems and variations.
Bit manipulation involves using bitwise operators to perform fast, low-level operations on integers. This post introduces common bit manipulation techniques, their use cases, and provides practical Python examples and problems for mastering bitwise logic.
A set is a collection of unique, unordered elements that supports fast membership testing and set operations. This post introduces sets in Python, their properties, common operations, and provides practical examples and problems for understanding their use cases.
Math and Number Theory in algorithms involve solving problems using mathematical principles such as primes, GCD/LCM, modular arithmetic, and combinatorics. This post covers key techniques, use cases, and provides practical Python examples and problems for mastering math-based algorithms.
A HashMap (or dictionary in Python) is a data structure that maps keys to values for fast lookup, insertion, and deletion. This post covers the fundamentals of hashmaps, their use cases, and practical examples in Python, including common operations and sample problems.
The Two Pointers technique uses two indices to efficiently solve problems involving pairs, subarrays, or partitions in arrays and strings. This post explains the method, its variations, and provides practical Python examples and problems for mastering two-pointer strategies.
Arrays (or lists in Python) are fundamental data structures that store elements in a contiguous block of memory, allowing fast access by index. This post explains the basics of arrays/lists, their operations, use cases, and provides practical Python examples and problems.
Dijkstra’s Algorithm is a classic greedy algorithm for finding the shortest path from a source node to all other nodes in a weighted graph with non-negative edge weights. It uses a min-heap (priority queue) for efficiency and is widely used in routing and navigation. This post explains the algorithm, use cases, and provides annotated code for beginners.
Recursion is a fundamental programming technique where a function calls itself to solve smaller subproblems. It is widely used in algorithms, especially for problems that can be broken down into similar subproblems. This post covers the basics of recursion, common patterns, and annotated code examples for beginners.
Memoization is an optimization technique that speeds up recursive algorithms by storing and reusing results of expensive function calls. It is a key part of top-down dynamic programming and is especially useful for problems with overlapping subproblems. This post explains how to use memoization, with annotated code and practical examples for beginners.
Manacher’s Algorithm is a brilliant linear-time solution for finding the longest palindromic substring in a string. By transforming the input and using symmetry, it avoids the O(n^2) brute-force approach. This post explains the intuition, transformation, and implementation, with annotated code for beginners.
The Rabin-Karp algorithm is a classic example of rolling hash applied to substring matching. Instead of comparing characters one by one, it compares hash values to identify potential matches, making substring search efficient. This post explains the rolling hash technique, Rabin-Karp implementation, and practical use cases, with annotated code for beginners.
Bitmask Dynamic Programming is a powerful technique that uses binary representations to efficiently solve problems involving subsets, permutations, and state tracking. This post explains bitmasks, their applications, and provides detailed examples with visualizations to master this advanced DP technique.
Kadane’s Algorithm is a classic dynamic programming technique for finding the maximum sum of a contiguous subarray in linear time. It is elegant, efficient, and a staple in coding interviews. This post explains the intuition, implementation, and variants of Kadane’s Algorithm, with annotated code for beginners.
Let’s generate a QR code using your contact information. We will learn today about QR codes and a use case of generating a personalized QR code that you can share with people without having to share it using traditional way.
Accessing information using just pin login is dangerous and should be avoided at all costs.
A few cases on how celery signatures would behave with examples explained.
As a stakeholder I would like to know when a software release has been made which includes list of changes categorized by either of the three types (features, maintenance, bug fixes).
Writing tests should be fun and easy. Testing was like an ocean for me when I first started writing test and I didn’t know how to swim. With past few experience I bring some knowledge to you and hope to add value to readers.
We will go through a use case that has recently come up to create name for a version of a file. I have decided to use s3 to accomplish this and we will learn how to do this.
Let’s walk through a bunch of use cases that i’ve learnt over a period of time for writing tests.
Setup up a Django app with ElasticSearch as document store.
An introduction to setting up a Django project with poetry properly.