-
6 votes
-
Reflections on past lessons regarding code quality.
Preface Over the last couple of years, I've had the opportunity to learn from the mistakes of my predecessors and put those lessons into practice. Among those lessons, three have stood out to me...
Preface
Over the last couple of years, I've had the opportunity to learn from the mistakes of my predecessors and put those lessons into practice. Among those lessons, three have stood out to me in particular:
- Consistency is king.
- Try not to be too clever for your own good.
- Good code takes time.
I know that there are a lot of new and aspiring programmers here (and I'm admittedly far from being a guru myself), so I thought it would be good to touch on these three lessons, what they mean, and why they're so important.
Consistency is King
This is something that I had drilled into my head over nearly two years working on the code base at my previous job. Not by my fellow programmers (who did not exist), nor by my boss, but by the code itself.
Consistency can mean a number of things, but there are two primary points that matter:
- Syntactic consistency.
- Architectural consistency.
Syntactic consistency concerns standards in what your code looks like. For example, the choice between
snake_case
orcamelCase
orPascalCase
for naming; function parameter order; or even something as benign as what kind of indentation and how much of it you use.Architectural consistency concerns standards in how you structure your code. Making sure that you either use public class properties or getter and setter methods; using multiple booleans or using bitmasks; using or not using objects for encapsulating data to be passed around; validating data within the primary object or relegating that responsibility to a validator class; and other seemingly minor decisions about how you handle certain behavior make a big difference.
The code base I maintained had no such consistency. You could never remember whether the method you needed to call was named using
snake_case
orcamelCase
and had to perform several searches just to find it. Worse still, some methods defined to handle Ajax calls were prefixed withajax
while many weren't. Argument ordering seemed to be determined by a coin flip, and indentation seemed to vary between 2-space, 3-space, 4-space, and even 5-space indentation depending on what mood my predecessor was in at the time. You often could not tell where a function's body began and where it ended. Writing code was an exercise both in problem solving and in deciphering ancient religious texts.Architecturally it was no better. There was no standardization in how data was validated or sanitized, how class members were accessed or modified, how functionality was inherited, whether the functionality was encapsulated in an object method or in a function, or which objects were responsible for which behavior.
That lack of consistency makes introducing or modifying a small feature, a task which should ordinarily be a breeze, an engineering feat of its own. Often you end up implementing that feature, after dancing around the tangled mess of spaghetti, only to find that the functionality that you implemented already existed somewhere else in the code base but was hiding out in a deep, dark corner that you never even knew was there until you had to fix some other broken feature months later and happened to stumble across it.
Consistency means predictability, and predictability means discoverability and, more importantly, easier changes and higher confidence in those changes.
Cleverness is a Fallacy
In any given project, it can be tempting to do something that saves you extra lines of code, or saves on CPU cycles, or just looks awesome and does something nobody would have thought of before. As human beings and especially as craftsmen, we like to leave our mark and take pride in breaking the status quo by taking a novel and interesting approach to a problem. It can make us feel fulfilled in our work, that we've done something unique, a trademark of sorts.
The problem with that is that it directly conflicts with the aforementioned consistency and predictability. What ends up being an engineering wonder to you ends up being an engineering nightmare to someone else. While you're enjoying the houses you build with wall studs arranged in the shape of a spider's web, the home remodelers who come along later aren't even sure if they can change part of the structure without causing the entire wall to collapse, and they're not even sure which walls are load-bearing and which aren't, so they're basically playing Jenga while blindfolded.
The code base I maintained had a few such gems, with what looked like load-bearing walls but were actually made of papier-mâché and were only decorative in nature, and the occasional spider's web wall studs. One spider's web comes to mind in particular. It's been a while since I've worked on that piece of code, so I can't recall what exactly it did, but two query-constructing pieces of logic had overlapping query structure with the difference being the operators and data. Rather than being smart and allowing those two constructs to be different, however, my predecessor decided to be clever and the query construction was abstracted into a separate method so that the same general query structure could be used in other places (note: it never was, and was only ever used in those two instances). It was abstracted so that all original context was lost and no comments existed to explain any of it. On top of that, the method was being called from the most critical piece of the system which, unfortunately, was already a convoluted mess and desperately required a rewrite and thus required me to understand what the hell that method was even doing (incidentally, I fell in love with whiteboards as a result).
When you feel like you're being clever, you should always stop what you're doing and make sure that what you're doing isn't actually a really terrible idea. Cleverness doesn't exist. Knowledge and intelligence do. Write intelligent code, not clever code.
Good Code Takes Time
Bad code more often than not is the result of impatience. We don't like to plan out the solution before we get to writing code. We like to use variables like
x
andtemp
in order to quickly achieve functional correctness of our code because stopping to think about how to name them is just additional overhead getting in the way. We don't like to scrap our bad work if we can salvage it in some way instead, because then we have to start from scratch and that's daunting. We continually work against ourselves and gradually increase our mental overhead because we try to decrease our mental overhead. As a result we find ourselves too exhausted by the end of our initial implementations to concern ourselves with fixing obvious problems. Obviously bad but functional code is preferable because we just want the task to be done and over with.The more you get exposed to bad code and the more you try to avoid pushing that hell onto yourself and your successors, the more you realize that you need to spend less time coding and more time researching and planning. Whereas you may have been spending upwards of 50% of your time coding previously, suddenly you find yourself spending as little as 10% of your time writing any code at all.
Professionals from just about any field can tell you that you can either do something right or you can do it twice. You might recognize this most easily in the age-old piece of woodworking wisdom, "measure twice, cut once". The same is true of code, and doing something right means planning how to do it right in the first place before you've even started on the job.
Putting into Practice
I've been fortunate over the last couple of months to be able to start on a brand new project and architect it in a way that I see fit. Changes which would ordinarily take days or weeks in the old code base now take me half a day at most, and a matter of minutes at best. I remember where to find a piece of code that I need because I'm consistent and predictable about where I place things; I don't struggle to tell where something begins and where it ends because I'm consistent about structure; I don't continually hate myself when I need to make changes to my code because I don't do anything wildly out of the ordinary; and most importantly, I take my time to figure out what it is that I need to do and how I want to do it before I've written a single line of code.
When I needed to add a web portal interface for uploading a media asset to associate with a database object, the initial implementation took me a week, due to the need for planning, adding the interface, and supporting and debugging the asset management. When I needed to extended that interface to allow for uploading the same kinds of assets for a completely different object type, it took me only half an hour, with most of that time being dedicated toward updating a Vue.js component to accept configuration via props rather than working for only the single hard-coded object type. If I need to add a case for any additional object type, it will take me only five minutes.
That initial week of work for the web interface provided me with cost savings that would not have been feasible otherwise, and that initial week of work would have taken as many as three weeks had I not structured the API to be as consistent as it is now. Every initial lag in implementation is offset heavily by the long-term cost savings of writing good code.
Technical Debt
Technical debt is the cost of your code over time. The messier and worse your code gets, the more it costs you to try to change, and those costs only build up. Even good code can accumulate technical debt if the needs for your software have changed and its current architecture isn't compatible with those changes.
No project is without technical debt. Even my own code, that I've been painstakingly working on for the last couple of months, has technical debt. Odds are a programmer far more experienced than I am will come along and want to scrap everything I've done, and will do a far better job rewriting it.
That's okay, though. In fact, a certain amount of technical debt is good. If we try to never write any bad code whatsoever, then we could never possibly get to writing any code at all, because there are far too many unknowns for a new project.
What's important is knowing when to pay down on that technical debt, which could mean anything from paying it up front (i.e. through planning ahead of time) to paying it down when it starts to get too expensive (e.g. refactoring a complicated section of code when changes become sufficiently difficult). That's not something you can learn through a StackOverflow post or a college lecture, and certainly not from some unknown stranger on some relatively unknown website in a long, informal blog-like post.
Final Thoughts
I'm far from being a great programmer. There's a lot that I don't know and I still have quite a bit to learn. I love programming, though, and more than that I enjoy sharing the lessons I've learned with others. Especially the ones that I wish I'd learned back in college.
Please feel free to share your own experiences, learned lessons, and (if you have it) feedback here. I'd love to read up on some other thoughts on this subject!
21 votes -
The Foundations of Algorithmic Bias
8 votes -
Getting started with qemu
9 votes -
The Effectiveness of Publicly Shaming Bad Security
21 votes -
The Julia Language Challenge
4 votes -
Writing a simple SQL interpreter in Julia
7 votes -
GSM Phone on a Conference Badge - Computerphile
4 votes -
Need recommendation for codecademy-like course for PHP
Hi there, It looks like codecademy took down their PHP course, which stinks becuase I love, love, love how that site approaches teaching by doing. Any other free resources out there for a...
Hi there,
It looks like codecademy took down their PHP course, which stinks becuase I love, love, love how that site approaches teaching by doing. Any other free resources out there for a do-not-show approach for learning PHP?
Looking to get my feet wet so I'm a little less dangerous when tinkering with my WordPress templates.
14 votes -
Do technologies like Snap and Flatpak have a future?
I just gave up on installing Gimp via flatpack because it required a 2GB download. I run i3 on top of Xfce. I have lots of Gtk libraries already. Storage is cheap and my internet has no limits,...
I just gave up on installing Gimp via flatpack because it required a 2GB download. I run i3 on top of Xfce. I have lots of Gtk libraries already. Storage is cheap and my internet has no limits, but this seems very inefficient to me. What if I had to install all my software that way?
27 votes -
Celebrating 10 years of V8
4 votes -
What is/are your go-to system fonts?
By system fonts I specifically mean fonts that come shipped with an OS, things like Times New Roman or Cambria.
24 votes -
Idle musings about the Pollard Rho method of factoring integers
5 votes -
xkcd 2044: Sandboxing Cycle
37 votes -
Google and Certbot: Let's Encrypt not renewing certs for sites Google flags
17 votes -
Total noob looking for (hopefully) simple greasemonkey script
I have knowledge of the basic concepts of programming in general and html and some very basic knowledge of javascript, but this specific task is proving a little beyond me. I'm actually using...
I have knowledge of the basic concepts of programming in general and html and some very basic knowledge of javascript, but this specific task is proving a little beyond me. I'm actually using tampermonkey, in case that matters.
www.bricklink.com is a site to buy Lego from private sellers. By default, when looking at a shop's listing of items, it shows 25 per page. I would like to automatically switch to 100 per page every time.
Here's a randomly selected store page (no affiliation) at the default 25 per page:
https://store.bricklink.com/TheBricky#/shop?o={"itemType":"P","catID":"18","showHomeItems":0}
Now, same page set to display 100 per page. Note how "pgSize" is added to the url but doesn't appear by default:
What I would like is for pgSize to be set to 100 only IF
"shop" appears in the url
AND
"pgSize" does not appear in the url OR "pgSize" does appear in the url but does not equal 100.
Since Bricklink remembers pgSize per shop page per session, once pgSize is set to 100 for a particular shop greasemonkey doesn't need to do anything. Intercepting the url before the page loads would be nice but unnecessary since loading is fast and I'm not worried about bandwidth.
I tried making this but wasn't sure how to input what I'm trying to test for in the url. Of course now that I've thought about it some more it seems the task is more probably difficult than I thought it would be at first. Any help would be appreciated.
EDIT: This comment below seems to be working, although the way Bricklink makes their urls feels funky at times.
10 votes -
Coding Noob Needs Help/Guidance on Small Project
Hi, There's a certain site which hosts media files and has a player that depends on a lot of third-party resources to play, while browsers have native support for those file types. Those 3rd-party...
Hi,
There's a certain site which hosts media files and has a player that depends on a lot of third-party resources to play, while browsers have native support for those file types. Those 3rd-party resources are often blocked by ad blockers and I have no desire to white-list them. I would like to extract the direct link to the media file and make it playable on my custom web page.
The link to the media file is present in the page source of each page, always on the same line. It's not anchored in HTML but present in the JavaScript for the player, like so:
$(document).ready(function(){ $("#jquery_jplayer_1").jPlayer({ ready: function () { $(this).jPlayer("setMedia", { [ext]: "https://[domain]/[filename.ext]" }); },
In this example it's on line #5. [ext] = the file extension.
I want to build the following:
- A web page with a form with a single input field meant to receive links from that specific file host
- [Something] that extracts the file link from the source of the host's page
- Present the linked file as playable in an embedded native player
So far I've managed to create a form with an input box and a submit button, but it doesn't do anything yet. What is the best way to build the actual functionality? I know HTML/CSS. I have some rudimentary understanding of JavaScript/jQuery and Python3, so those would be my preferred tools.
For those worried about piracy: The files in question are not copyrighted and I'm not looking to make copies. I just want to make them playable. This is for personal use.
Thank you for reading this far. Any and all advice is welcome!
10 votes -
RustConf 2018 - Using Rust For Game Development
7 votes -
What are your unsolved programming problems?
I thought it could be fun to discuss problems that we've encountered in our programming or programming-related work and have never found a solution for. I figure that at worst we can have a lot of...
I thought it could be fun to discuss problems that we've encountered in our programming or programming-related work and have never found a solution for. I figure that at worst we can have a lot of fun venting about and scratching our heads at things that just don't make any sense to anyone, and at best we might be able to help each other find answers and, more importantly, some closure.
16 votes -
Reverse-engineering "Adware Doctor", the #4 app in the Mac App Store that's been surreptitiously stealing users' browser history
17 votes -
Bootstrappable builds
5 votes -
How we fit the NES game Micro Mages into 40 Kilobytes
14 votes -
Conservative web development
29 votes -
Let's talk about tooling.
Hey! Since it's a small community at the moment, I think we can have a very genreral thread about anything regarding tooling: interesting technologies you use at work/home, your editor, plugins,...
Hey! Since it's a small community at the moment, I think we can have a very genreral thread about anything regarding tooling: interesting technologies you use at work/home, your editor, plugins, themes, bruh let's even share some screenshots. I find this kind of shit exciting and know more people like me exist out there :)
13 votes -
Website Admin Question: How to Block Google?
I have a personal website, and while I don't mind it showing up in SERPs for DuckDuckGo, Bing, etc. I do not want it showing up on Google at all. Google doesn't send traffic my way, I pay for my...
I have a personal website, and while I don't mind it showing up in SERPs for DuckDuckGo, Bing, etc. I do not want it showing up on Google at all.
Google doesn't send traffic my way, I pay for my site out of my salary from my day job instead of running ads, and preventing Google from indexing my site seems like the best form of nonviolent direct action I can take to protest their continuing dominance and their "embrace, extend, and extinguish" campaign against the Web.
I figure the easiest way to do this is to add the following to my site's
.htaccess
file since I don't have access to the server config file:X-Robots-Tag: googlebot: none, noarchive, nosnippet, notranslate, noimageindex
Are there any downsides that I should know about besides not showing up in Google results?
11 votes -
Inexperienced Programming Question
TLDR: What programming language would be useful for taking info in an excel file and producing a text file (that is organized and arranged in a particular way) containing that info? Which would be...
TLDR: What programming language would be useful for taking info in an excel file and producing a text file (that is organized and arranged in a particular way) containing that info? Which would be useful for this problem but also helpful in general? And also, are there any recommended online courses where I could learn it?
I have no real experience coding or anything but have always wanted to learn. Recently at work we've encountered a problem. My boss had created a matlab program in order to take text/numbers from an excel document and transfer them to a text file, but in an organized way.
Say you have something you call "Pancakes" and the cell next to it has the number "3", as in there are three pancakes. I want to be able to create a text file that would read something like this:
NUMBER OF PANCAKES
- Pancakes: 3
We recently have changed around the format of the excel document for a different item, for example "French Toast". I've tried to mess with matlab briefly but was unable to change the program to compensate, and I no longer easily have access to matlab.
I'm seeing this as an opportunity to learn some programming and also fix some stuff at work. So what programming language would be useful for fixing this problem? Which would be useful for this problem, but also helpful in general? And also, are there any recommended online courses where I could learn it?
Thanks for any help, I appreciate it.
16 votes -
A Constructive Look At TempleOS
34 votes -
Don't blindly take that coding challenge
26 votes -
Windows 2000 VM running in the browser with WebAssembly
13 votes -
Rubber Duck just saved me. What about you?
To put this into context: I'm still minor, in Europe, and I was hired into SW company as backend developer. I'm making about 2-3 times as much as my friends in fastfoods. I'm basically making WS...
To put this into context: I'm still minor, in Europe, and I was hired into SW company as backend developer. I'm making about 2-3 times as much as my friends in fastfoods.
I'm basically making WS that would be unified wrapper for about 15 another WS - instead of crafting request for each of those, you will just call the API and it will do everything for you.
Everything was fine, until I encountered a nightmare: WSDL/SOAP protocol over HTTPS with need to use client certificate.
Full of false hope, I thought: "It'll be easy, I finished communication with another companies in few hours, this will be quick".
I was very wrong. I spent countless hours on this. I tried 3 programming languages and 4 different frameworks, copy-pasting solutions from stack overflow and wondering why does this still throw errors! I copied it from stack overflow! I used windows alongside linux and installed like 10 wsdl/soap clients from 2008 forums.
I created 8 or so SO questions, most about different language/framework, but the same problem.
Worth of mentoining, at the time, I could obtain wsdl and xsd of the WS with usage of two certificates (crt.pem and key.pem) over PHP. I tried to use PHP SoapClient, which accepted just one certificate file. I used .pem certificate that I received and should get the work done.
Then, I started writing the final question. Including PHP that downloaded wsdl and SoapClient that didn't work. Knowing someone will probably want to see certificates, I used
cat key.pem cert.pem > certCombined.pem
anddiff certCombined.pem cert.pem
. cert.pem was the certificate I received and should work. I expected no differences. When I saw two pages of differences, I started to suspect the cert I was given is wrong. So I pointed the PHP SoapClient to certCombined - and it started working!This would have never happened (at least for several more hours) unless I known someone will want to see diff between working and not-working certificates. Thank you, rubber duck debugging! Next time I'll be solving something, I'll write on paper everything I use and know.
What are your stories?
13 votes -
TypeScript 3.0
8 votes -
What conferences are on your wish list? (for team leads or wannabee managers)
Imagine that your boss told you that the company is happy to send you to one or two conferences next year, with the aim of helping you to improve your leadership skills. In this context,...
Imagine that your boss told you that the company is happy to send you to one or two conferences next year, with the aim of helping you to improve your leadership skills.
In this context, "leadership" includes Culture; Coaching & Mentoring; Teamwork; Continuous Improvement; Collaboration; Agile; Culture Change.
You want to make a list of conferences worth considering in order to estimate the budget. What events would you put on your list?
7 votes -
"Disable SMT/Hyperthreading in all Intel BIOSes"
23 votes -
How 5 years of burning ambition brought Retro City Rampage to DOS
6 votes -
Scaling Mercurial at Facebook (2014)
7 votes -
Learna project reverts blacklisting in license
14 votes -
Baker, a simple tool for provisioning virtual machines and containers
4 votes -
Go 2 Draft Designs
14 votes -
Making C less dangerous
16 votes -
castling.club: play Chess via Mastodon (ActivityPub)
10 votes -
React Fire: Modernizing React DOM
7 votes -
Better CLI Commands
21 votes -
DNS Privacy
11 votes -
The Performance Cost Of Spectre, Meltdown, & Foreshadow Mitigations On Linux 4.19 with Intel & AMD processors
14 votes -
Contrast Ratio: Easily calculate color contrast ratios. Passing WCAG was never this easy!
6 votes -
Direct ring 3 to ring 0 privilege escalation on some x86 processors using an embedded RISC core.
19 votes -
RISC-V implemented in a night
14 votes -
Programming Challenge: Make a game in 1 hour!
Background There's been some talk on ~ before, and it seems like there are quite a few people who are either interested in, learning, or working in game development, so I thought this could be a...
Background
There's been some talk on ~ before, and it seems like there are quite a few people who are either interested in, learning, or working in game development, so I thought this could be a fun programming challenge.
This one is fairly open-ended: make a game in 1 hour. Any game, any engine, don't worry about art or sound or anything.
Doing is the best way to learn. Most people's first project is something overly ambitious, and when they find that it's more difficult than they thought, they can get discouraged, or even give up entirely. This is why the 1 hour limit is important: it forces you to finish something, even if it's small. When you're done, you can come out of it saying you made a game, and you learned from it.
Chances are the game might not be fun, look bad, be buggy, etc. But don't worry about that, everyone's game will have problems, and if you do create something really fun or innovative, congratulations, you have a prototype that you can expand on later!
"Rules"
Like I said before, these "rules" are pretty simple: make a game in (approximately) 1 hour. You can use any tools you want. If you use external assets (art, sound), it's probably best you use something you have the rights to (see resources). If you're completely new to game development/programming, your goal could even be to finish a tutorial.
If you're the kind of person who tends to get carried away with these things, you might want to post a comment saying you're starting, then another one once you've finished your game.
Please share your finished game, I'm sure everyone would love to try them! If your game is web-based, it can be hosted for free on Github Pages or Itch.io. If downloadable, it can be hosted for free on Google Drive, Mega, Dropbox, Itch.io, etc.
Resources
Engines
If you're a beginner, a good engine to start with is LÖVE. It's very simple, and uses Lua, which is very easy to learn.
If you're familiar with another language, you could use a library to make it in that language. Some examples:
Javascript: kontra, Phaser, pixi.js
Python: pygame
If you want something more complex, consider Godot, Unity, or Unreal.
You can also try something visual like Construct, Clickteam Fusion, or GDevelop
Art
For such a short time constraint, I'd suggest you use your own "programmer art": just use some basic shapes. Your primary focus should be gameplay.
If you think you have time to find something, try looking on OpenGameArt.
Sound
You can make simple sound effects very quickly with sfxr (or in this case, a web port of sfxr called jsfxr).
27 votes -
Google Cloud grants $9M in credits for the operation of the Kubernetes project
3 votes -
Now that Ubuntu 18.04.1 is out, have you upgraded from 16.04 LTS?
The first point release came out July 26, and enables upgrades from 16.04 LTS. https://blog.ubuntu.com/2018/07/26/first-point-release-of-18-04-lts-available-today Have you upgraded your desktop?...
The first point release came out July 26, and enables upgrades from 16.04 LTS.
https://blog.ubuntu.com/2018/07/26/first-point-release-of-18-04-lts-available-today
Have you upgraded your desktop? Server?
Happy with it? Any pitfalls?
20 votes