Designing my own theme in Hugo - I

Hugo is all about themes Hugo is a developers dream of static sites. Whether you are planning on a new blog site or maybe a documentation for a product, you can easily launch a static site using Hugo. The most powerful feature of Hugo is its simplicity. It is designed to separate your content from styling. This means you can write your content in normal markdown files independent of all the website pages and layouts. The actual design of the website can be stored as a separate theme. And as it is independent of the content, you can easily switch themes without ever thinking about your content. Creating a new theme To create a new theme, you can just use the below hugo command. It will create a new directory under theme with your theme name. hugo new theme <theme-name>The below files will be created on executing the above command. Let's get an idea on what are these files in this blog. . └── awesometheme ├── LICENSE ├── archetypes │   └── default.md ├── layouts │   ├── 404.html │   ├── _default │   │   ├── baseof.html │   │   ├── list.html │   │   └── single.html │   ├── index.html │   └── partials │   ├── footer.html │   ├── head.html │   └── header.html ├── static │   ├── css │   └── js └── theme.toml8 directories, 11 filesThe interesting part are the archetypes and layouts directory. The layout directory contains the template for your pages. A single page template is defined inside single.html. A page containing a list of items like blog posts are defined inside list.html. The archetypes directory provides the defaults for a type of content. When you run hugo new content post/learninghugo, the new file is created using the default template as described in archetypes/default.md, given you don't have any overrides. Applying the theme My blogs are written in Hugo so I can just start experimenting with my blogs theme. This way, I can forget about generating any dummy content for my theme. To tell Hugo to use a theme, you can just update the theme entry in your config. My blog site uses toml, so below are the changes. - theme = "poison" + theme = "awesometheme"Now let's run the dev server using hugo server --buildDrafts. And I got the below error. 2025-02-15 06:00:39.535 +0530 ERROR 2025/02/15 06:00:39 render of "section" failed: "/home/cold/Projects/Personal/blog.shubham.codes/layouts/_default/baseof.html:1:3": execute of template failed: template: cv/cv.html:1:3: executing "cv/cv.html" at <partial "head/head.html" .>: error calling partial: partial "head/head.html" not found ERROR 2025/02/15 06:00:39 failed to render pages: render of "home" failed: "/home/cold/Projects/Personal/blog.shubham.codes/layouts/_default/baseof.html:1:3": execute of template failed: template: index.html:1:3: executing "index.html" at <partial "head/head.html" .>: error calling partial: partial "head/head.html" not foundSeems like, I have overridden the poison theme for customization. But now, I am using my own theme which does not contains the poison partials. And this is causing the issue. Both the error corresponds to my layout's directory. So let's rename layouts to layouts_. And we will need to refactor these layouts as well.And this is why you should always keep your code loosely coupledmv layouts layouts_And it worked. Start building sites … hugo v0.92.2+extended linux/amd64 BuildDate=2023-01-31T11:11:57Z VendorInfo=ubuntu:0.92.2-1ubuntu0.1 | EN -------------------+------- Pages | 13 Paginator pages | 0 Non-page files | 0 Static files | 1014 Processed images | 0 Aliases | 0 Sitemaps | 1 Cleaned | 0Built in 88 ms Watching for changes in /home/cold/Projects/Personal/blog.shubham.codes/{archetypes,assets,content,data,static,themes} Watching for config changes in /home/cold/Projects/Personal/blog.shubham.codes/config.toml Environment: "development" Serving pages from memory Running in Fast Render Mode. For full rebuilds on change: hugo server --disableFastRender Web Server is available at http://localhost:1313/ (bind address 127.0.0.1) Press Ctrl+C to stopBut my screen is blank. Summary In this post, we went thorough the basic flow of creating a new theme in Hugo. Next, we will learn about layouts and implement the single and list layout for the blog.

Julia and basic matrix operations

What is Julia? Julia is a scientific programming language. It is close to R and Python in syntax and scripting feel. But it is more like a light weight MATLAB. I was going with Gilbert Strang's lectures on Linear Algebra and as always, you can't learn if you are not experimenting. I searched for any language support for MATLAB in Doom Emacs. Instead I saw this - ;;julia ; a better, faster MATLAB. And my curious mind was like - Why not give this a try? And here I am. I am not a Julia developer yet. Maybe I'll be one, given the feel of the language. Maybe I'll start saying Julia instead of MATLAB in some days. Let the future be what it will be. Here are some basic matrix operations you can perform in Julia. Installation I am using Ubuntu on WSL2 hosted on Windows 11. And the following worked for me. wget https://julialang-s3.julialang.org/bin/linux/x64/1.8/julia-1.8.1-linux-x86_64.tar.gz tar zxvf julia-1.8.1-linux-x86_64.tar.gz# maybe move it to your home directory mv julia-1.8.1 ~/juliaExport # ~/.bashrc or ~/.zshrc export PATH="$PATH:/home//julia/bin"Julia Linear Algebra For linear algebra operations, Julia has a library called LinearAlgebra. Just like Python where you import your libraries, here you use using keyword. You can define a matrix very easily as below. Let's say you want to define a matrix \(A = \begin{bmatrix} 1 & 2 & 3 \\ 4 & 1 & 6 \\ 7 & 8 & 1 \end{bmatrix}\). You can just write the elements of a row separated by space and a new row is specified by semi-colon. using LinearAlgebra A = [1 2 3; 4 1 6; 7 8 1]: 3×3 Matrix{Int64}: : 1 2 3 : 4 1 6 : 7 8 1Basic Operations The operations like finding the trace (tr) or determinant (det) or rank or inverse (inv) can be easily done as follows. using LinearAlgebra A = [1 2 3; 4 1 6; 7 8 1]tr(A) det(A) rank(A) inv(A)3×3 Matrix{Int64}: 1 2 3 4 1 6 7 8 1// Trace 3// Determinant 104.0// Rank 3// Inverse 3×3 Matrix{Float64}: -0.451923 0.211538 0.0865385 0.365385 -0.192308 0.0576923 0.240385 0.0576923 -0.0673077Calculation of Eigen values and Eigen vectors are also very easy. using LinearAlgebra A = [1 2 3; 4 1 6; 7 8 1] eigvals(A) eigvecs(A)3×3 Matrix{Int64}: 1 2 3 4 1 6 7 8 1// Eigen values 3-element Vector{Float64}: -6.214612641961068 -1.5540265964847833 10.768639238445843// Eigen vectors 3×3 Matrix{Float64}: -0.175709 -0.766257 -0.344989 -0.570057 0.587185 -0.589753 0.802596 0.26089 -0.730188There are different ways you can factorize a matrix and you can do this in Julia as well. LU Factorization LU factorization basically factorizes a matrix A as LU, where L is lower triangular matrix and U is upper triangular matrix. using LinearAlgebra A = [1 2; 4 5]; LU=lu(A)2×2 Matrix{Int64}: 1 2 4 5 LinearAlgebra.LU{Float64, Matrix{Float64}, Vector{Int64}} L factor: 2×2 Matrix{Float64}: 1.0 0.0 0.25 1.0 U factor: 2×2 Matrix{Float64}: 4.0 5.0 0.0 0.75Eigen value decomposition A matrix can be factorized as \(S\Lambda S^{-1}\) where \(S\) is the Eigen vector matrix and \(\Lambda\) is the Eigen values in diagonal matrix. using LinearAlgebra A = [1 2; 4 5]; E=eigen(A)2×2 Matrix{Int64}: 1 2 4 5 Eigen{Float64, Float64, Matrix{Float64}, Vector{Float64}} values: 2-element Vector{Float64}: -0.4641016151377544 6.464101615137754 vectors: 2×2 Matrix{Float64}: -0.806898 -0.343724 0.59069 -0.939071SVD SVD or Singular Value Decomposition is a way to factorize a matrix in \(u\Sigma v\) form where \(u\) and \(v\) are some special vectors and \(\Sigma\) is a special matrix. Going in detail about them would only make this blog grow infinitely. Maybe I should consider writing blogs on mathematical learning in future. using LinearAlgebra A = [1 2; 4 5]; SVD=svd(A)2×2 Matrix{Int64}: 1 2 4 5 LinearAlgebra.SVD{Float64, Float64, Matrix{Float64}, Vector{Float64}} U factor: 2×2 Matrix{Float64}: -0.324536 -0.945873 -0.945873 0.324536 singular values: 2-element Vector{Float64}: 6.767828935632369 0.44327361529561016 Vt factor: 2×2 Matrix{Float64}: -0.606994 -0.794707 0.794707 -0.606994Conclusion Julia has much more to offer. This blog was a basic introduction to Julia in Linear Algebra. I will keep sharing as I explore more of this language.

Object pool design pattern in Java

What is it? The object pool design pattern exposes a manager to manage a pool of reusable objects. The idea is to keep a know number of reusable objects (with a hard limit to initialize some more lazily). Whenever someone need the object from the pool, it will ask the pool manager. If there are free objects, the manager will engage one for your. If there aren't any free objects but the hard limit is not breached, then the manager will initialize a new object and provide you. Else if the hard limit is breached then you will return empty handed. Why is this? This is used when we have an resource object which takes some time to initialize. And once initialized, it can be reused over and over again without a performance hit. Basically, creation is expensive and hence we want to reuse already created instances. Generally, we put a soft limit on the number of resources initially initialized. And we want to create more resources lazily if required. To prevent a huge number of resources from being created, we also put a hard limit. Example At GreyOrange, we use something called as IDC files. These are huge binary files (sometimes 100-200 GBs). They provide the time it takes to travel b/w 2 coordinates. We created an IDC Manager to parse these files and provide us the required information. The initialization takes a huge amount of time (sometimes 10s). Once initialized, it takes less than 1ms to provide the information. Right now, we are good with just once instance of this manager, so it is a singleton class with one buffer linked to an IDC file. But if the demands for parallel calls increases, we might want to implement the manager as a Object Pool. How to implement this? There are 3 requirements.An Object Pool Manager The initial number of objects - m The maximum number of objects - nThe Object Pool Manager will be a singleton class. We cannot allow multiple Object Pool Manager objects as they will create max, n objects each. We will create 2 lists, availableResources and enagaedResources. Initially, we will populate the availableResources with m new resource objects. Each getter call will check the availableResources list for available objects. If the objects are available then it will move the last object to engagedObjects. If the objects are not available then there are 2 choices. Check the hard limit, if not reached then create more objects and add to availableResources. Else return null. A pseudo code for the manager is as follows. class PoolManager { private static PoolManager instance; private List<Object> availableResources; private List<Object> engagedResources; private Integer initialLimit; private Integer hardLimit; private PoolManager() { // Get these properties from already defined config // Assume this is defined as per standard or equivalent configurations initialLimit = Properties.getInstance().getIntegerValue("POOL_INITIAL_LIMIT"); hardLimit = Properties.getInstance().getIntegerValue("POOL_HARD_LIMIT"); availableResources = new ArrayList<>(); engagedResources = new ArrayList<>(); // Initialize the initial number of resources in the pool for (int i=0; i<initialLimit; i++) { availableResources.add(new ResourceObject()); } } public static PoolManager getInstance() { if (instance == null) { synchronized(PoolManager.class) { if (instance == null) { instance = new PoolManager(); } } } return instance; } public Object getObject() { if (!availableResources.isEmpty()) { // A sync is required as 2 thread may want to get a free object at the same time synchronized(availableResources) { Object freeObject = availableResources.remove(availableResources.size()-1); engagedResources.add(freeObject); return freeObject; } } else if (engagedResources.size() < hardLimit) { Object freeObject = new ResourceObject(); availableResources.add(freeObject); return getObject(); } else { return null; } } public void releaseObject(Object engagedObject) { if (engagedObject != null) { try { synchronized(engagedResources) { Object freeObject = engagedResources.remove(engagedObject); availableResources.add(freeObject); } } catch (Exception e){} } } }

Make String a Subsequence Using Cyclic Increments

This is the LeetCode problem number 2825. Cyclic increment This is when you increase an entity by an amount and when you reach the end you circle back to start and continue the count. If a is increased cyclicly by 1, we will get b. If a is increased cyclicly by 2, we will get c. But if z is increased cyclicly by 1, we get a. By 2 we will get b. String increaseCyclic (String str, int index) { char ch = str.charAt(index); char newch = (char) ((ch - 'a' + 1) % 26 + 'a'); return str.substring(0, index) + newChar + str.substring(index + 1); }Subsequence String str1 is said to contain the subsequence of str2 if we can delete some characters from str1 to get str2. During this deletion we are not allowed to disturb the relative order of chars in the str1. A code to check if str1 contains subsequence str2. We can iterate over all the characters of str1 sequencely and check if all the letters are there as in str2. boolean isSubsequence(String str1, String str2) { int p1 = 0; int p2 = 0; while (p1 < str1.length() && p2 < str2.length()) { if (str1.charAt(p1) == str2.charAt(p2)) { p2++; } p1++; } return p2 == str2.length(); }Solution The problem asks us that we are allowed to cyclic increase any number of chars in str1. And check whether we are able to say str1 will contain a subsequence of str2. We can solve this problem by just merging both the problems. Instead of checking just the characters equality, we can add an additional check on character of str1 after increasig it cyclicly. public boolean canMakeSubsequence(String str1, String str2) { int p1 = 0; int p2 = 0; while (p1 < str1.length() && p2 < str2.length()) { char cyclicCh = (char) ((str1.charAt(p1) - 'a' + 1) % 26 + 'a'); if (str1.charAt(p1) == str2.charAt(p2) || cyclicCh == str2.charAt(p2)) { p2++; } p1++; } return p2 == str2.length(); }

Downloading a single file from 2 independent apps

Understanding the problem Let's say you have a very large log file. And you want to create an app that can analyze this file and generate insights. Also, let's say you want to create an another app that can simulate the work by reading the logs one-by-one. Both these apps are dependent on the same log file. Now, there are 2 scenarios.App1 starts, downloads the file and then App2 starts. App1 starts, downloading the file and App2 starts while the download is incomlete.The first scenario is easy to deal with. We can check the md5sum of the local file and the file on the server. If they match, nothing to worrry about. If they don't then we can have a complex logic to determine the life of the old log file and decide accordingly. The second scenario is conflicting one and this we can solve in code. The second scenario can also happen when the same app is ran twice simultaneously. Both the instances will start downloading the same file and this will create a havoc. Solution The idea is to have an identifier that an app has already started the download and is still downloading the resouce. If the first app has started the download, then wait for the first app to complete the download and then only start the application. For accomplishing this, we generally use file locking mechanism. Download with file locking The process is modified to first create a lock file with extension .lock. This lock file signifies that a download is already in progress. If this lock file exists then wait for the download to complete by the second app. The lock file will have processid_threadid as identifier. This is useful in checking the race condition that can happen while writing the file. public static void downloadFileWithLock(String filePath) { File lockFile = new File(filePath + ".lock"); // Check if the file is being downloaded by another app // If it is being downloaded by an another app then wait for the download to finish // Else proceed with the download if (lockFile.exists()) { waitForDownloadToFinish(lockFile); } else { int processID = (int) ProcessHandle.current().pid(); String identifier = thread + "_" + processID; String contents = String.valueOf(identifier); writeToFile(lockFile, contents); // May be due to race condition, the file is already downloaded by another app // Check if this process started the download String savedIdentifier = readFromFile(lockFile); if (identifier.equals(savedIdentifier)) { // Download the file System.out.println(thread + " - Downloading file..."); File downloadFile = new File(filePath); try { RandomAccessFile randomAccessFile = new RandomAccessFile(downloadFile, "rw"); randomAccessFile.write("Very important works".getBytes()); Thread.sleep(5000); } catch (IOException e) {} catch (InterruptedException e) {} System.out.println(thread + " - File downloaded successflly."); } else { waitForDownloadToFinish(lockFile); } if (lockFile.exists()) { lockFile.delete(); } } }The Utilities method - waitFoDownloadToFinish, readFromFile and writeToFile are as follows. private static void writeToFile(File file, String contents) { try { Files.write(file.toPath(), contents.getBytes()); } catch (IOException e) { e.printStackTrace(); } } private static String readFromFile(File file) { try { return new String(Files.readAllBytes(file.toPath())); } catch (IOException e) { e.printStackTrace(); } return null; } private static void waitForDownloadToFinish(File lockFile) { System.out.println(thread + " - File is already being downloaded by another app. Wait for it to finish."); while (lockFile.exists()) { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println(thread + " - File download completed."); }Now you can create 2 new apps that will call this method and we will run the apps simultaneously. public class App1 { public static void main(String[] args) { String filePath = "downloaded_file.txt"; FileDownloadUtil.downloadFileWithLock(filePath); System.out.println(Thread.currentThread().getName() + " - App1 starting operation..."); } }public class App2 { public static void main(String[] args) { String filePath = "downloaded_file.txt"; FileDownloadUtil.downloadFileWithLock(filePath); System.out.println(Thread.currentThread().getName() + " - App2 starting operation..."); } }Outputs # For App1 main - Downloading file... main - File downloaded successfully. main - App1 starting operation...# For App2 main - File is already being downloaded by another app. Wait for it to finish. main - File download completed. main - App2 starting operation...App1 started downloading the file and thus App2 waited for the download to complete. After the download completes, both the apps resumed its operations. Conclusion and improvements This is just a basic code that lays the foundation of file locking mechanism for downloading a file simultaneously by multiple apps. This code is not a production ready code. A more complete solution should handle scenarios like downloads in chunks, resume functionality with unexpected shutdowns and other edge cases.