23/01/2026

[Source code] Determine to which subsquare does a cell belong to in a sudoku grid

Given a valid sudoku grid of size NxN, we might need to determine (for example for validation purposes), in which subsquare a specific cell belongs:

int squareIndex = (i / subsquareSize) * subsquareSize + (j / subsquareSize);

where subsquareSize = Math.sqrt(N);

[Maven] Replace backslashes in property

Using Maven to build code on both Windows and Unix systems, you might end up with some quirky situations especially related to file path handling.

It is possible to generate altered Maven properties so that for example backslashes are converted to forward slashes:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
<plugin>
  <groupId>org.codehaus.mojo</groupId>
  <artifactId>build-helper-maven-plugin</artifactId>
  <executions>
    <execution>
      <id>normalize-property</id>
      <phase>initialize</phase>
      <goals>
        <goal>regex-property</goal>
      </goals>
      <configuration>
        <name>normalized.property</name>
        <value>${property}</value>
        <regex>\\</regex>
        <replacement>/</replacement>
      </configuration>
    </execution>
  </executions>
</plugin>

This can be used to alter properties that are not directly controlled by the developer, such as ${project.baseDir}, and then you can use the result as a property itself: ${normalized.property}

06/11/2025

[Windows] Delete recovery partition

Windows disk manager lets you create, delete, modify partitions on connected drives, but does not allow deleting the recovery partition. To do that, you can use the diskpart utility which can be run from an Administator command line. The following commands will allow you to delete the partition, replace X with the desired disk and partition

diskpart

list disk

select disk X

list partition

select partition X

delete partition override


01/11/2025

[Windows 11] Disable lnk resolver

Windows has a set of features on NTFS file systems called "shortcut resolver" that allow the system to search for a shortcut target in the filesystem if it gets moved around after a link to it is created.

This is convenient normally in case you create a shortcut to something, then move said something somewhere else as usually the shortcut would stop working and throw an error when accessed instead. However, it can lead to security issues as a new attack vector is introduced that could allow a malicious actor to hijack the target and point to something unwanted instead.

The features can be disabled on Windows 11 by enabling some group policies (Start->Run->gpedit.msc):

  • User Configuration\Administrative Templates\Start Menu and Taskbar\Do not use the search-based method when resolving shell shortcuts
  • User Configuration\Administrative Templates\Start Menu and Taskbar\Do not use the tracking-based method when resolving shell shortcuts
  • User Configuration\Administrative Templates\Windows Components\File Explorer\Do not track shell shortcuts during roaming
Additionally the "Distributed Link Tracking Client" service can be disabled (Start->Run->services.msc)

06/08/2025

[Bing] Disable AI search clutter

AI is seemingly unescapable these days and annoying generated content is being shoved everywhere without consent.

To disable AI content clutter (copilot answers, video results, similar content and related searches) on Bing searches you can add a small rule to uBlock Origin extension under "My Filters" section:

www.bing.com##.b_ans

This will obviously break as soon as Microsoft pushes any update that changes the page content setup, however the workaround will be the same and will simply require finding out which element(s) to block.

uBlock Origin also has a very handy element picker mode that allows selecting a page component to create a rule to block it. Naturally the same can be achieved also by inspecting the page with Developer Tools (F12 usually) and finding the element tag(s) to block.

26/07/2025

[Lenovo] Fix PSR screen issues with AMD graphics

Some recent Lenovo laptops come with displays theoretically supporting PSR (Panel Self Refresh) techology which supposedly would improve battery life.

On systems with AMD graphics, both the proprietary drivers and the ones packaged by Lenovo incorrectly implement support for it, leading to issues such as screen flickering, screen tearing and video stuttering.

The workaround is to force disable PSR in Windows registry, by opening regedit and looking for this entry:

Computer\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\{4d36e968-e325-11ce-bfc1-08002be10318}\0000

then modifying or creating a key DWORD 32 bit named DalPSRFeatureEnable with value 0

Afterwards simply reboot the system.

Even though in theory disabling PSR could lead to worse battery life and higher GPU temperatures, I have not seen noticeable differences after a month of use, naturally it might vary for others, therefore monitor your system to detect issues in case.

To reenable it, simply change the value to 1

24/04/2025

[Windows 11] Uninstall widgets app

If you do not need the widgets functionality on your Windows machine, you can disable it from settings or completely remove it with:

winget uninstall "windows web experience pack"

[Windows] Hash a file

Windows offers a builtin tool to compute the hash of a file (example MD5):

CertUtil -hashfile FILENAME MD5

To view the list of supported options and hash algorithms:

CertUtil -hashfile -?

23/04/2025

[Windows 11] Disable telemetry and diagnostic data

Windows 11 collects some data and allows some configuration under Settings > Privacy & Security > Diagnostics & Feedback however you are not allowed to completely disable it. If you wanted to do so, you could apply a policy using the Local Group Policy Editor app (gpedit).

Find the Local Computer Policy > Administrative Templates > Windows Components > Data Collection and Preview Builds > Allow Diagnostic Data

Click to modify it, enable it and set it to "Diagnostic data off"

You can then logout and login again or run from a terminal the command to force reload policies:

gpupdate /force

[Windows 11] Remove PhoneLink app

Removing the PhoneLink app on Windows, is as easy as running (from administrator shell):

Get-AppxPackage Microsoft.YourPhone -AllUsers | Remove-AppxPackage

12/03/2025

[Windows 11] Initial setup without forced login

When setting up Windows 11 from a new installation, you will be guided through a graphical setup at boot. 

Since every other company decided to force onto users annoying choices without much backlash, also Microsoft though to participate in the fun now by forcing you to login to your Microsoft account (or create a new one) during this process.

To avoid this for the moment, you can run a couple commands during the setup. After choosing the language for the setup process, press SHIFT+F10 to open a command prompt, then enter:

OOBE\BYPASSNRO

which will make the PC reboot. Once you are back into the setup process, choose the language again (if prompted) and press again SHIFT+F10 to get back into the command prompt, this time enter:

ipconfig /release

to disconnect from any network you might be connected to.

Finally moving forward in the process, when you reach the "connect to the internet" stage, you will have the option to click on a small link saying "I don't have internet", you will then be prompted to create a local account on your PC.

12/01/2025

[Android] Sprescia app for run activity tracking

No it is not Christmas today, but here is another free, no ads, no trackers, no data collection, minimalistic app to track your run activity!

Built for Android 14+ using help from ChatGPT and icons from SVG Repo this app writes to a local Rooom DB in 1 table: run

Run view allows you to add, edit, delete run details and calculates average speed for each entry, comparing it with the previous one, giving you a quick view of your training progression. You can also export and import data to/from csv for quick backup and restore logic.

Daily stats view allows you to see daily run data and compare it to previous runs using key metrics: steps, average speed, distance, time.

Monthly stats view provides the same capability but averages the data grouping per month instead.

You can find the Sprescia project on my GitHub



[Android] MaiCar app for car expense management (refuels and maintenance)

Finally a free, no ads, no trackers, no data collection, minimalistic app to track your car expenses!

Built for Android 14+ using help from ChatGPT and icons from SVG Repo this app writes to a local Rooom DB in 2 tables: fuel and maintenance

Fuel view allows you to add, edit, delete refuel details (partial and full tank) and calculates efficiency for each entry, comparing it with the previous one, giving you a quick view of your trip efficiency progression.

Maintenance view allows you to add, edit, delete maintenance details for multiple maintenance types, it also allows you to filter the view on a specific maintenance type to quickly find a specific item.

Both views allow you to export and import data to/from csv for quick backup and restore logic.

You can find the MaiCar project on my GitHub




15/12/2024

[Android] Recompile and sign APK

Each new Android version introduces changes that usually require app developers to put some effort into keeping their app compatible with the latest OS releases. As a result, sometimes, your favorite free apps have issues if the developer does not update it.

Depending on the required changes, the effort varies, however you can often adapt the app yourself by simply decompiling it, updating whatever needs to be updated, and repackage it with a new Android version as target. Here are the simple steps to achieve this.

08/11/2024

[Google Sheets] Import data from Investing.com

DISCLAIMER: This is not a stock picking recommendation, the tickers shown are used as example and not provided as financial or investment advice.

DISCLAIMER2: Web scraping can go against usage policies so read them, understand them and abide by them. Also web scraping is notoriously flaky as small changes in the retrieved page can affect the location of the desired element(s).

We have already seen how to import data from Yahoo Finance and Coingecko, now we try to add Investing.com as source which unfortunately does not provide API, so we have to do some HTML scraping instead.

We would like to retrieve the current price of an ETF called JPNA. By looking at that page we can luckily identify a specific locator, which then allows us to do a couple string manipulation operations before getting the desired value:

function getInvestingData(path) {
  var result = UrlFetchApp.fetch("https://www.investing.com/etfs/" + path.toLowerCase());
  var response = result.getContentText();
  var start = response.indexOf(' data-test="instrument-price-last">') + 35;
  var end = response.indexOf('</div>', start)
  var out = response.substring(start, end);
  var strip = out.replace(",", "");
  return Number(strip);
}

19/10/2024

[Google Sheets] Import crypto data from Coingecko

DISCLAIMER: I do not recommend investing in crypto, all tokens you will see are used as sample and not provided as financial or investment advice.

We've already seen how to add custom functions to our Google Sheets projects, importing Yahoo Finance data. Now we expand this to import cryptocurrency data from Coingecko.

I could have picked any of the million sources, but this one has a simple free plan which for light usage works well.

After registering and getting your API key, RTFM to find that they provide a lot of stuff, what we care about is the pricing data in this example, you will need to find the ID of the currency you want (NOT the token) by querying the list and then you can get the data you want by calling (add your API key at the end):

"https://api.coingecko.com/api/v3/simple/price?ids=" + token + "&vs_currencies=usd&x_cg_demo_api_key="

You can put this in a Google Sheet function as well (you can extend input parameters to get quote in different currencies as well):

function getCoingeckoData(path) {
  var result = UrlFetchApp.fetch("https://api.coingecko.com/api/v3/simple/price?ids=" + path + "&vs_currencies=usd&x_cg_demo_api_key=YOUR_API_KEY");
  var response = result.getContentText();
  var json = JSON.parse(response);
  return json[path]['usd'];
}

04/10/2024

[Java] Get type of elements in collection using reflection

Java type erasure logic means that at runtime some information is removed/replaced from generic declarations, which poses a minor challenge when trying to identify the actual parameter types using reflection at runtime.

Here is a way:

import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;


//maybe you are looping over fields or have a field of type Field f
ParameterizedType collectionType = (ParameterizedType) f.getGenericType();
Class<?> actualClassOfElementInCollection = (Class<?>) collectionType.getActualTypeArguments()[0];

27/09/2024

[Java] Load entity with lazy children collections

When using JPA and lazy collection loading, at the time the parent entity is retrieved from DB, the lazy children are NOT also loaded in memory, instead, a proxy reference is added, which is used to retrieve the data if that particular field is ever accessed.

In some scenarios you might want to load the whole entity, including the lazy children in memory instead (eg you want to clone/serialize it, whatever).


If you want to load ONE child together with the parent, a JOIN FETCH clause would do the trick: 

SELECT p

FROM Parent p

LEFT JOIN FETCH p.childField c

WHERE p.id = :id


But if you try to load more than one child at the same time, you will get a MultipleBagFetchException. A workaround is to call the load with JOIN FETCH for all entities you need sequentially, for example:

private Parent loadChildViaQuery(ID id, String childClause) {
  return entityManager
    .createQuery(
      "select p " +
      "from Parent p " +
      "left join fetch " +
      childClause +
      " where p.id = :id",
      Parent.class
    )
    .setParameter("id", id)
    .getSingleResult();
}

Where childClause input is the join statement you need, for example:

"p.childField c"

Also remember that if the parent entity is not found, the operation would throw a NoResultException, while if the child is not found, no exception is raised, the child is simply null/empty.

26/09/2024

[Java] Using annotation processing (and validating it) to execute logic at runtime

Sample project showcasing how to use annotations to perform runtime logic to log changes in object values.

Remember it is a SAMPLE, so obviously (lazy me) most null-safe checks and so are not included and obviously some logic is a showcase, should be replaced with a real business scenario to implement.

In this SAMPLE, we tag fields to be included in a diff logic to then print to output when those fields values change by comparing two instances of the same object.

Logic can obviously be made much more complex including collections and maps and whatnot (Java Generics are your friends there).

Also worth mentioning JaVers can do most of it for you, unless you have fancy business requirements that force you to write custom code..


Key points:

- How to create an annotation

- How to create an annotation processor to validate the annotation parameters at compile time

- How to register an annotation processor

- How to configure a multi-module Maven project to use a custom annotation processor (also, in the pom of the root project ensure the module containing the processor is built BEFORE everything else)

- How to test an annotation processor by generating classes at runtime and trigger compilation tasks agains them. Includes verifying compilation warnings are properly triggered as expected.

- How to use reflection to get fields annotated with a given annotation (and then execute whatever logic on them)

- How to use reflection to invoke methods (including static methods)


The full project is available on my GitHub repo with commented code: https://github.com/steghio/diff-annotation-processing

05/09/2024

[Java] Serialize POJO to XML according to XSD

If you generate a class from an XSD schema, it will come with the necessary annotations to serialize it to an XML String.

You can therefore easily convert it with:

import jakarta.xml.bind.JAXBContext;
import jakarta.xml.bind.Marshaller;
import java.io.StringWriter;

/**
 * Provides utility methods for serialization scenarios
 */
public class SerializationUtils {

  /**
   * Serialize the given object to XML String using JAXBContext
   * It will set the output to be pretty printed
   * It relies on the object annotations to correctly place and annotate all fields
   * @param object
   * @return the string representation of this object as XML
   * @param <T>
   */
  public static <T> String serializeXml(T object) {
    try {
      JAXBContext jc = JAXBContext.newInstance(object.getClass());

      Marshaller marshaller = jc.createMarshaller();
      marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
      //to completely remove the xml preamble `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>` add this line:
      //marshaller.setProperty(Marshaller.JAXB_FRAGMENT, true);

      //marshaller cannot output to string directly
      StringWriter sw = new StringWriter();

      marshaller.marshal(object, sw);

      return sw.toString();
    } catch (Exception e) {
      throw new RuntimeException("Failed to convert payload to xml. ", e);
    }
  }
}