At a recent Software Engineer position I worked on developing and improving internal tools. Internal tools are software systems that are developed and used within an organization to improve efficiency, productivity, and communication.
These tools are often not marketed to or made available to external customers, clients, or end users and are instead designed for internal usage by workers. Systems for project management, communication, time tracking, human resource management, business intelligence tools, IT management, and document management are a few examples.
As a programmer working on internal tools, there are a few vital things you can do to make the most impact:
Recognize your users’ needs before beginning any tool development: It’s critical to recognize your users’ demands before beginning any tool development. This entails conversing with them, looking over their processes, and getting their comments. The key to success here is scheduling interviews with the people who will be using your work.
Prioritize based on impact: As soon as you are aware of your users’ needs, focus on adding features and making enhancements that will have the biggest positive effects on their efficiency and effectiveness.
Keep it (super) simple: Make an effort to keep the user interface straightforward and basic so that internal tools are simple to use and comprehend. Keep any extra features or complexity to a minimum.
Continuously improve: Continue to gather user feedback and make ongoing adjustments to your tools. This will make it more likely that they will continue to be useful and satisfy the needs of their users.
Make sure it’s maintainable: Internal tools’ long-term success depends on the creation of maintainable code. Ensure that your code is well-structured, commented, and adheres to standard practices.
The look-and-say sequence is a series of integers. It can grow indefinitely. It is generated by reciting a number phonetically, and writing what you spoke numerically. Its popularity is attributed to famed cryptographer Robert Morris. It was introduced by mathematician John Conway. It looks like this:
1
11
21
1211
111221
312211
13112221
The first line would be pronounced as “one 1”, and then written as “11” on the second line. That record would be spoken as “two 1’s”, giving us the third line “21”. The greatest individual symbol you’ll ever find in this consecution is a 3.
This topic has lots of trivia, variations, and history that could be dug up and expounded upon. Here, I’ll explain a solution written in PHP to produce this chain of numerals. The input will be the count of how many lines, or iterations, in the series to generate. Below is the code:
<?php
echo "Count And Say: \n";
function countAndSay($count=0){
$value = 1; // initial seed
for($i=1;$i<=$count;$i++){
echo $value . "\n";
$value = calcOutput($value);
}
}
function calcOutput($value){
$value = "$value"; // change it into a string, so we can iterate over each character
$current = $value[0]; // first character
$count = 1;
$return = '';
for ($i = 1; $i <= strlen($value); $i++) { // keep going until we get through the whole string
if ($current != $value[$i] || $i == strlen($value)) { // found a different character, or end of the input string
$return .= "$count$current";
$count = 1; // reset count
$current = $value[$i]; // set new current character
} else {
$count++;
}
}
return $return;
}
countAndSay(7);
echo "\n\n";
?>
I separated my code into two functions. I think this is the best approach. As an exercise, see if you can figure out how to refactor it into one. This could help you to internalize the logic as you write it out for yourself.
The initial seed value is “1”, and that is hard-coded at the top. The for-loop iterates based on the count input parameter. That means the code circles back and re-runs, with updated values, until its internal count (represented by the variable $i ) matches the $count variable passed into countAndSay($count).
The code that we loop over outputs the current sequence value (starting with 1) as its own line (“\n” will output a new line in most programming languages) , and then calculates the next. The function that determines the next line of output, calcOutput($value), takes the current value as an argument.
The first thing we do is cast the integer value passed along into a string. This lets us refer to each character by index – starting at zero – and save it to a variable $current. We start a new $count, to keep track of how many times we see the same digit.
The next for-loop executes for the length of the $value string. On each loop, we check if the $current character we saved matches the subsequent one in that $value string. It is again referenced by index, this time based on the for-loop’s iteration count represented by the variable $i.
If it does match, one is added to the $count variable that is keeping track of how many times we see the same character is a row. If it doesn’t match (or we’ve reached the end of the input), the $count and $current number are concatenated to the $return element. At that point, the $count is reset to 1, and the $current value is updated.
Writing an algorithm to generate the look-and-say (also known as, count-and-say) sequence is a common coding puzzle. You might run into it during a job interview as a software engineer. As practice, see if you can simplify my example code, or even write it in a different programming language than PHP.
The web, as a platform, is open and free. Unlike native app markets, we don’t have to wait for software to be approved by any third-party. It works across any device or operating system that has a web browser. (Which is why standards across browsers is so important). But, until recently web-apps faced limitations. Not having full access to a device’s hardware and operating system was an issue – but that’s being fixed as more native APIs are being added to modern web browsers.
A disadvantage of having a web-only app was losing out on the discoverability that comes with having it listed in a searchable marketplace. Adding a web-app to your device home screen, from a web browser, is not intuitive to average users. Fortunately, the Google Play Market allows us to upload an app file that links to a progressive web app.
I had to make sure it qualified as a PWA. It needed offline support, as well as any other features that would make it feel like a native app. Google Chrome’s developer tools has a section called “Audits” that helped me identify such opportunities.
The first step was to create a “service worker” JavaScript file, and register it when BJJ Tracker loads.
I added the above code to a shared file that loads on every page of my app. Below is an example service worker file. This file downloads any vital assets to a user’s device, and later loads them from the cache. Including a polyfill ensures that the cache methods exist (in case the browser does not support them natively). “We need to use the polyfill because the Cache API is not yet fully supported in all browsers.”
Next, I created a “manifest” file. This file is written in JSON format. It helps describe how the web-app behaves once “installed”. It handles things such as app icon images and meta data.
The manifest needs to be referenced by the app. I added a link tag to a shared <head> file. Additionally, I included a few other meta tags that let browsers know to treat this website as an app.
When creating the app bundle (“Build > Generate Signed Bundle/APK”) we’ll need a signing key. I created a new one, and named the file mykeystore.keystore.
That command shows us the certificate fingerprints. Copy the SHA256 value. It is used with Google’s Statement List Generator to create the contents of the assetlinks.json file. The statement file is then placed in a “.well-known” directory on the root of our PWA domain (eg.https://www.bjjtracker.com/.well-known/assetlinks.json)
This app is a side project I use to toy with new web technologies. I’m trying to drive traffic to it so that I can experiment with optimizing conversions. I’m using it as a trial grounds for another software service called SplitWit. SplitWit is focused on optimizing conversions for the web, and helping digital marketers reach their goals. You can read about it on another post from this blog.