Would that all our codebases be that straightforward...
I worked in a team with low skill. One of our flagship apps had a lot of inherent complexity, and was coded by an over-promoted fool. He wrote spaghetti that was vile even at launch.
To my complete lack of surprise, after launch, the users wanted an enormous list of changes and new features. When you try to add features to code that's already spaghetti, the complexity compounds.
There's only one way to manage that, and it's to refactor. But to refactor you need good tests, and your team needs to accept the use of resources for refactoring.
This dungheap had objects with fucky interlocking responsibilities, e.g., scheduling was partly done by the ORM classes and partly by the class for customer output.
This app was also extremely time-based. A CRUD app doesn't really require you to think about how state changes over time; but in the dungheap, you couldn't "see" the state from the code, you also had to understand when in the sequence of operations a method was called. This is one of the hardest types of complexity to deal with.
The app was completely untyped. Some functions take enums and others take strings. There were state enums and also free text strings for state. You might see both "FAILED" and "FAILURE" for the same state concept. A huge amount of data was passed as nested dicts, and without the benefit of consistent kwarg names, so you would not know whether the variable you're looking at has an "error" or an "err_msg" key, or an "output" key containing a dict with an "error" key. To find out, you had to run the app for several minutes with a bunch of print statements, and the answer you got might vary depending on any of the 20 input flags.
I generated a call graph to try to grok the sequence statically but the graph was spaghetti and the sequence contained loops. A few code paths called methods once with one datatype and then again with another type.
Type hints massively reduced the cognitive burden. My violent impulses towards our dickhead "architect" reduced from daily occurrences to weekly.
Fwiw, TypedDict turned out to be a great fit for the use case.
I worked in a team with low skill. One of our flagship apps had a lot of inherent complexity, and was coded by an over-promoted fool. He wrote spaghetti that was vile even at launch.
To my complete lack of surprise, after launch, the users wanted an enormous list of changes and new features. When you try to add features to code that's already spaghetti, the complexity compounds.
There's only one way to manage that, and it's to refactor. But to refactor you need good tests, and your team needs to accept the use of resources for refactoring.
This dungheap had objects with fucky interlocking responsibilities, e.g., scheduling was partly done by the ORM classes and partly by the class for customer output.
This app was also extremely time-based. A CRUD app doesn't really require you to think about how state changes over time; but in the dungheap, you couldn't "see" the state from the code, you also had to understand when in the sequence of operations a method was called. This is one of the hardest types of complexity to deal with.
The app was completely untyped. Some functions take enums and others take strings. There were state enums and also free text strings for state. You might see both "FAILED" and "FAILURE" for the same state concept. A huge amount of data was passed as nested dicts, and without the benefit of consistent kwarg names, so you would not know whether the variable you're looking at has an "error" or an "err_msg" key, or an "output" key containing a dict with an "error" key. To find out, you had to run the app for several minutes with a bunch of print statements, and the answer you got might vary depending on any of the 20 input flags.
I generated a call graph to try to grok the sequence statically but the graph was spaghetti and the sequence contained loops. A few code paths called methods once with one datatype and then again with another type.
Type hints massively reduced the cognitive burden. My violent impulses towards our dickhead "architect" reduced from daily occurrences to weekly.
Fwiw, TypedDict turned out to be a great fit for the use case.