23/01/2026
[Source code] Determine to which subsquare does a cell belong to in a sudoku grid
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)
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
"https://api.coingecko.com/api/v3/simple/price?ids=" + token + "&vs_currencies=usd&x_cg_demo_api_key="
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
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
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); } } }
21/08/2024
[TypeScript] Debounce function in vanilla TypeScript
19/08/2024
[Java] Prim algorithm to find Minimum Spanning Tree in a graph
17/08/2024
[Java] Graph union find algorithm
14/02/2024
22/12/2023
[Google Sheets] Import data from Yahoo Finance
06/11/2023
[Tampermonkey] Disable Bing Chat search integrations
When using Bing search there are multiple places that integrate the Chat functionality with the ChatGPT AI. Some of these integrations are annoying and can be easily disabled by installing the Tampermonkey browser extension then adding a couple scripts to modify the displayed webpage and its behavior.
// ==UserScript==
// @name Disable Bing Search Engine Scroll
// @namespace your-namespace
// @description Disables scrolling on the Bing search engine page to prevent accidental scrolling into the Bing chat feature.
// @match https://www.bing.com/*
// @version 1
// @grant none
// ==/UserScript==
window.addEventListener("wheel", e=>{
if(e.target.className.includes("cib-serp-main")) e.stopPropagation();
});
- Disable sidebar Chat autosearch functionality when disaplying search results:
// ==UserScript==
// @name Disable Bing Chat autosearch
// @namespace your-namespace
// @description Disables the Bing Chat autosearch functionality on the right side of results when doing a search.
// @match https://www.bing.com/*
// @version 1
// @grant none
// ==/UserScript==
const element = document.getElementById("sydwrap_wrapper");
element.remove();
const element1 = document.getElementById("b_sydTigerCont");
element1.remove();
09/08/2023
[Spring] Execute method in separate transaction
We can easily work around this issue by creating a new class that will execute a given method in a new transaction:
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import java.util.function.Supplier;
/**
* Since spring ignores transaction settings for methods within the same class, we need a separate service
* to run isolated transactions which can be called from anywhere simply by supplying the method to execute
*/
@Service
public class TransactionHandlerService {
/**
* Runs the given method in a the same transaction as the caller
*
* @param supplier the method to execute
* @param <T>
* @return the result of the invoked method
*/
@Transactional(propagation = Propagation.REQUIRED)
public <T> T runInSameTransaction(Supplier<T> supplier) {
return supplier.get();
}
/**
* Runs the given method in a separate transaction
*
* @param supplier the method to execute
* @param <T>
* @return the result of the invoked method
*/
@Transactional(propagation = Propagation.REQUIRES_NEW)
public <T> T runInNewTransaction(Supplier<T> supplier) {
return supplier.get();
}
}
Then ensure the callers are annotated as @Transactional and simply pass the method to execute as input to our, for example:
transactionHandlerService.runInNewTransaction(() -> myMethod(someInput));
03/12/2021
[Python] Simple command line options and menu
I recently needed to make a script automatable, meaning I had to provide all inputs to it from the CLI command used to execute it, rather than wait for it to prompt me during execution.
Turns out Python has a nice module dedicated to this: argparse
The usage is very simple and will also create the help menu automatically for us:
import argparse
parser = argparse.ArgumentParser("myScript")
parser.add_argument("-a_flag_input", help="This is a true/false flag", action='store_true')
parser.add_argument("-a_string_input", help="This is a string input", type=str)
args = parser.parse_args()
options = vars(args)
print(args)
if options["a_flag_input"]:
print("a_string_input")
Basically, we define each input parameter along with its type, if the input is a flag (true/false) we can specify an action on it to determine the value it would receive if set.
The inputs will be collected in a Namespace object, which we can convert to dictionary and get easy access to the inputs from the code.
29/11/2021
[Docker] Multi stage builds
I've been recently introduced to a nice Docker feature: multi-stage builds.
The idea is simple, if the build is containerized as well, the build itself is a developer responsability as well and the operations team need only provide a build server with docker installed on all worker nodes.
To achieve the result, we use a simple Dockerfile where we specify multiple FROM statements and tag each layer as necessary. The last layer will be the one responsible to run the application, while the previous layers are only used for the build. A sample file for a SpringBoot app looks like this:
# syntax=docker/dockerfile:1
# build layer
FROM adoptopenjdk/openjdk11:latest as build
WORKDIR /app
# copy project files into container workdir
COPY . .
# build jar, skip tests, avoid daemon
RUN ./gradlew build -x test --no-daemon
# run layer
FROM adoptopenjdk/openjdk11:latest as prod
WORKDIR /app
#copy fat jar from previous layer into current workdir and rename it
COPY --from=build /app/build/libs/*.jar ./myApp.jar
# not mandatory, must use -p 8080:8080 later anyway
EXPOSE 8080
# start the spring boot app
CMD ["java", "-jar", "myApp.jar"]
Then it can be placed in the project directory and we can trigger the build with:
docker build -t TAG .
Finally run it with (binding for example port 8080 and executing it in background):
docker run -p 8080:8080 -d TAG
We can also see the container output with (find container name with docker ps first):
docker logs -f CONTAINER_NAME
13/10/2021
[Java] Kerberos login and retrieve GSSCredentials from KerberosTicket
A scenario that popped up recently was to login a user via Java code to Kerberos and retrieve a GSSCredential object containing the Kerberos ticket. I used Java 8, but this works since Java 7 onwards.
Java offers a Krb5LoginModule class which can be used in conjuction with a LoginContext to achieve this.
The flow is quite simple (once you have read all the Kerberos documentation):
- on the machine where the code runs, place a correct krb5.conf file in the default location for your OS (Windows uses krb5.ini) OR set the java.security.krb5.conf system property pointing to the file
- define a PasswordCallback handler class
- create a LoginContext with a configuration using Krb5LoginModule and provide the password callback handler. The configuration must force the login to request a user input, which will then be routed to the callback handler. It is possible to use a keytab or cache credentials, but it's not shown here
- login the user and get its KerberosTicket
- create a GSSCredentials object using the ticket
This procedure allows handling multiple login mechanisms in the application and even multiple Kerberos realms.
11/10/2021
[Java] Calculate the angle between clock hands
return null;
Unless it's an analog clock, in which case:
The hour hand makes a 360 degree turn every 12 hours or 12*60 = 720 minutes, therefore each minute the hand moves 360/720 = 0.5 degrees
The minute hand makes a 360 degree turn every hour or 60 minutes, therefore each minute the hand moves 360/60 = 6 degrees
Setting 12 as the 0 position, to calculate the angle of each hand we can:
- hours = 0.5 * current minutes for that hour (60 * hours + minutes)
- minutes = 6 * minutes
We now have the position of both hand with respect to the 12 o'clock, the angle between them will simply be the difference, between the two positions (absolute value!)
If the difference is more than 180 degrees, the angle is a reflex angle and since we want the smallest angle between the hands, we take its complement by subtracting it from 360 (again, absolute value unless we did a modulo before to account for 24 hour format)
You can check my implementation of clockAngle on my Gist along with some tests in ClockAngleJTests.