Create a component (class, function, service, whatever) that does one thing only one thing, and does it well. Then another one. And then another one. Usually the next big thing is that, a framework/library combining a lot of those components.
Examples:
- Validate a json/xml/csv input against a schema.
- Construct a schema based on a json/xml/csv input.
- Take a string that looks like a number and try to get an integer or float out of it.
- Take a string that looks like a date and same thing.
- Take html/css (or some other structure/style taxonomy) and convert it to pdf with page size constraints (US letter, legal, A4, etc.).
- Create a process able to register itself as a valid service on the host OS.
- List running services, identify which ones are (say) database or web servers.
In all cases, identify the constraints your input should adhere too, enforce them, add workarounds, etc.
The benefit of this is that after some time (generally less than you’d know) you’ll have the building blocks to create anything you can think of. It also keeps the mind sharp, and solving problems provides small doses of gratification.
A simple example below (it’s in Python, which is not amongst the languages you’ve listed, but I think it’ll be clear enough with the comments).
One day I found out that I was often dealing with several files at once and to tell apart their path, base name and extensions, which is simple enough but also annoying enough to have to do over and over, so I’ve created this function:
import os
# 'root' is (hopefully) a string with the starting folder. If omitted,
# it will default to the current directory ('os.curdir').
#
# 'exts' is (hopefully) a string or a list/tuple of strings. If
# omitted, it will default to 'None' (Python's null). Otherswise,
# we'll use it as a list of file extensions we want to include.
def get_files_info(root, exts=None):
# 'keys' is a tuple of values we'll use to tag a Python dict.
# 'files' is an empty list where we'll store those dicts.
keys = ('filename', 'basename', 'extension', 'path', 'fullname')
files = []
# Long story short: 'os.walk' recursively lists all files in all
# subdirectories from the starting point (in this case 'root').
#
# What matters in this case: by nesting this two iterations, on
# each round we'll get the name of a file in 'filename' and its
# full folder hierarchy in 'path'.
for path, folders, filenames in os.walk(root):
for filename in filenames:
# Concatenate 'path', '/' and 'filename' into 'fullname'.
fullname = f'{path}/{filename}'
# If 'filename' contains at least one dot, split over the
# last of those and assign the resulting substrings to
# 'basename' and 'extension'.
if '.' in filename:
basename, extension = filename.rsplit('.', 1)
else:
# Otherwise, all of 'filename' is assigned to 'basename'
# and 'extension' is left blank.
basename = filename
extension = ''
# 'any' is a function that takes a collection of booleans and
# returns True if at least one of them is true.
# In this case:
# - 'not exts' means that 'exts' is null or empty.
# - 'extension in exts' means that the extension matches
# the value or values on exts.
if any((not exts, extension in exts)):
# We group the variables on a tuple called 'values'.
values = (filename, basename, extension, path, fullname)
# We zip 'keys' (defined earlies) and 'values' in a dict.
file = dict(zip(keys, values))
# We append the dict to the 'files' list.
files.append(file)
# If the 'files' list is not empty, return it. Otherwise return None.
if files:
return files
else:
return None
So, for example, if you were to call it like this:
svgfiles = get_files_info('/Users/frank/code/app', 'svg')
You’d get something like this:
[{'filename': 'search.svg',
'basename': 'search',
'extension': 'svg',
'path': '/Users/frank/code/app/webclient/res/icons',
'fullname': '/Users/frank/code/app/webclient/res/icons/search.svg'},
{'filename': 'burger_menu.svg',
'basename': 'burger_menu',
'extension': 'svg',
'path': '/Users/frank/code/app/webclient/res/icons',
'fullname': '/Users/frank/code/app/webclient/res/icons/burger_menu.svg'},
{'filename': 'settings.svg',
'basename': 'settings',
'extension': 'svg',
'path': '/Users/frank/code/app/webclient/res/icons',
'fullname': '/Users/frank/code/app/webclient/res/icons/settings.svg'}]
And if you were to call it like this:
files = get_files_info('/Users/frank/code/app', ['html', 'png'])
You’d get something like this:
[{'filename': 'index.html',
'basename': 'index',
'extension': 'html',
'path': '/Users/frank/code/app/webclient/',
'fullname': '/Users/frank/code/app/webclient/index.html'},
{'filename': 'logo.png',
'basename': 'logo',
'extension': 'png',
'path': '/Users/frank/code/app/webclient/res',
'fullname': '/Users/frank/code/app/webclient/res/icons/logo.png'}]
Silly enough, and there’s probably other ways of doing it, but it was faster to write it myself than to look for something, it felt good to do it and for all I know this may have been the foundation stone of my own ext big thing.