- I'm very specific about when I use None
- I'm a big fan of named function arguments
- I like to think my naming of things is pretty good, as are my conventions for parameters
- I try to handle all possible cases (what I mean here is I do and if I don't I made a mistake)
I use tests very sparingly in personal projects, but yet I haven't really felt their absence. If I ever write a piece of particularly hairy code (metaprogramming comes to mind... lord) I'll write a quick script testing some cases and then delete it.
Anyway, all that is to say I think part of dynamic programming is you build an immune system for this stuff.
I usually avoid bugs in python code by rewriting in bash (at 1-10% the size of the original python, since bash's error handling can be set to "always do the right thing" with "set euxo pipefail")
If bash is a bad fit for the rewrite, go usually works. I don't work on linear algebra software much these days. Python seems to be a good option for that.
I think Python gets bailed out a lot because those things turn out to be a lot of programming these days. The people who have a beef w/ Python are those who've worked with it on large, old codebases. This is a tough job for any language though like, raise your hand if you've ever worked on a large, old codebase in C++ or Java that you liked.
Usually when people push microservices I'm quick with Conway's law, saying "this is a tech solution to an organizational problem that won't actually make a difference", and I think I'm right about that. But I think I've been ignoring that a really nice thing about microservices for engineers is you can keep using languages like Python on small codebases, and at least mentally and emotionally avoid the feeling of working on a huge monolith. That counts for something.