One of the things I struggled with when I was new to programming was how to tell whether a given piece of code is good or not. When everything is new and confusing, how do you tell bad confusing from normal confusing?
One thing that will give you a very helpful hint is if you code is hard to explain. Like this Python style guide puts it:
If the implementation is hard to explain, it’s a bad idea. This is a general software engineering principle — but applies very well to Python code. Most Python functions and objects can have an easy-to-explain implementation. If it’s hard to explain, it’s probably a bad idea. Usually you can make a hard-to-explain function easier-to-explain via “divide and conquer” — split it into several functions.
Basically, if something you’re working on is hard to explain, that’s a sign that it needs to be re-thought. Some problems are just unavoidably complex, but it should still be possible to explain what you’re doing at a high level.
That applies to higher level application logic just as much as to individual functions. At a previous job I worked on a multiplayer game project that involved putting groups of players into rooms together for each round, then closing down that room when the round was over and creating a new one. Our first implementation seemed like a good idea at the time, but when we got the game to a point where the team could play together, we had a terrible time explaining how players were sorted into rooms the to the artists and project manager.
The non-programmers on the team were by no means stupid people and had been working on the game for quite a while by that point. The fact that we couldn’t explain our room selection scheme to them was a very strong sign that what we were doing just didn’t make sense. As we kept playing our in-progress game, it also turned out that it was extremely difficult to get the whole team into the same room. There were less than a dozen of us working on that game, so there was really no good reason for it to be that hard to play together.
In the end, we admitted our room selection logic wasn’t working and rewrote it to be much simpler. Players sometimes had to wait a bit longer for a round to start, but they could play with their friends more easily and stay in the same room with the people they played with last round. The simpler logic that was easier to explain was also a better experience for the players.
I’m not going to pretend you’ll never run into anyone who is invested in not understanding what you’re trying to explain to them, but if you give someone an overview of what you’re up to and they don’t follow it, think about whether you’re doing something overly complicated before you assume the person you’re trying to explain it to is just dumb. Complicated code is harder to test, harder to debug, and harder to change when you get a new feature request. It’s worth paying attention to seemingly unimportant signs like having a hard time explaining your code to someone else because it can save you so much time in the long run.