Archive

Archive for March, 2022

A pattern for dealing with #legacy code in c#

static string legacy_code(int input)
{
	// some magic process
	const int magicNumber = 7;

	var intermediaryValue = input + magicNumber;
	
	return "The answer is " + intermediaryValue;
}

When dealing with a project more than a few years old, the issue of legacy code crops up time and time again. In this case, you have a function that’s called from lots of different client applications, so you can’t change it without breaking the client apps.

I’m using the code example above to keep the illustration simple, but you have to imagine that this function “legacy_code(int)”, in reality, could be hundreds of lines long, with lots of quirks and complexities. So you really don’t want to duplicate it.

Now, imagine, that as an output, I want to have just the intermediary value, not the string “The answer is …”. My client could parse the number out of the string, but that’s a horrible extra step to put on the client.

Otherwise you could create “legacy_code_internal()” that returns the int, and legacy_code() calls legacy_code_internal() and adds the string. This is the most common approach, but can end up with a rat’s nest of _internal() functions.

Here’s another approach – you can tell me what you think :

static string legacy_code(int input, Action<int> intermediary = null)
{
	// some magic process
	const int magicNumber = 7;

	var intermediaryValue = input + magicNumber;

	if (intermediary != null) intermediary(intermediaryValue);

	return "The answer is " + intermediaryValue;
}

Here, we can pass an optional function into the legacy_code function, that if present, will return the intermediaryValue as an int, without interfering with how the code is called by existing clients.

A new client looking to use the new functionality could call;

int intermediaryValue  = 0;
var answer = legacy_code(4, i => intermediaryValue = i);
Console.WriteLine(answer);
Console.WriteLine(intermediaryValue);

This approach could return more than one object, but this could get very messy.

Categories: Uncategorized

Using #AppsScript to call an #API from Google Sheets

AppsScript is a Macro programming language that you can use within Google Sheets to automate data entry. In this case, we want to take one cell, which contains a vehicle registration number, and run it through an API, in order to extract details, like the make / model / VIN of that car. The API providing this is available here; https://www.carregistrationapi.in (India) – Many other countries are available, like the US, UK, Australia, South Africa, etc., but this particular example is for India.

To Access the App Script “IDE” press Extensions > App-Script on your google sheet. Here I am using the code as follows:


var USERNAME = "***USERNAME GOES HERE ****";
var PASSWORD = "*** PASSWORD GOES HERE ****";


function CheckIndia(plate,property,subproperty)
{
  var userProperties = PropertiesService.getUserProperties();
  var cacheHit = userProperties.getProperty(plate);
  if (cacheHit != null)
  {
      var cacheData = JSON.parse(cacheHit);
      if(subproperty == null)
      {
        return cacheData[property];
      }
      else
      {
        return cacheData[property][subproperty];
      }
  }
  // Sample UP14CT0093
  var url = 'https://www.regcheck.org.uk/api/json.aspx/CheckIndia/' + plate;
  var headers = {
    "Authorization" : "Basic " + Utilities.base64Encode(USERNAME + ':' + PASSWORD)
  };
  var params = {
    "method":"GET",
    "headers":headers
  };
   var response = UrlFetchApp.fetch(url,params);
   var json = response.getContentText();
   userProperties.setProperty(plate,json);
   var data = JSON.parse(json);   
   if(subproperty == null)
   {
      return data[property];
   }
   else
   {
      return data[property][subproperty];
   }
}

The USERNAME / PASSWORD variables need to be taken from your registration on https://www.carregistrationapi.in .

The Function “CheckIndia” is what you call from within the Google Sheet Cell, such as:

=CheckIndia(A2,”Description”)

Here, in the example above, A2 is the cell that contains the license plate, and “Description” is the make + model of the vehicle.

There is a level of internal caching built-in so that the API is not called every single time a call is made, if the call was made elsewhere on the sheet.

Categories: Uncategorized