This is an extended response to a posting by Melissa Guachun - LeetCode #136: Single Number
As the topic here is half about the process of "crafting a solution to a problem" I'll respond to that rather than offer thoughts on the specific example.
( Which is of course hard, as my nerd brain wants to dive into that mix of: - what is the solution to that? - how would I tackle that?)
One thing about having been around a bit longer, is that I began my coding life well before there was any great chance to search the Internet for solutions. This means that my natural bent - even these days - is to start thinking on my own. It seems a strange thing to say now, but maybe that has imprinted a skill for that kind of thinking. A mental muscle for starting from scratch. To be honest that's not something I've explicitly meta-thought about for a very long time.
As all our experiences are exactly that: just our experiences - it means I have no basis for the following, but maybe:
- yes, it is well worth investing in the working out of solutions by ourselves.
Not because that 's the most efficient way to get something done - but instead because it builds a skill at solving problems. I could even go so far as to suggest it might also improve that skill for its benefit in evaluating solutions when looking for them online.
The reality these days is that I freely mix these approaches. Sometimes I really can't be bothered devising a solution for something I can be quite sure someone will have posted a good answer. Ditto the reverse, because sometimes I really can't be bothered trying to search and read my way to an answer. Of course, it helps to have a confidence/delusion that I can always work out a solution myself if need be.
For context, I should point out that there are two versions of coding-me. One exists in my employment, which is a closed world of languages and tools that I don't get to choose. The irony is that in that world there is little chance to use solutions from outside and that along with the span of years means it has been largely spent devising my own solutions to all manner of things.
I've only recently returned to doing some coding outside of work, and have only done such to make solutions when I couldn't find anything (Open Source as I rarely use proprietary tech at home) to solve a problem. So the irony is that there too, I am devising my own solutions to things.
As a further aside, being on dev.to has been interesting partly because my kind of person is not the norm here. Clearly most people here are having - or hoping to have - tech careers in a general market of "developers". This is a whole other topic of course.
Also, that idea of having developed a muscle memory for tackling things, could perhaps explain why it seems so hard to share solutions with colleagues. It's more an observation than a criticism that I'm always surprised at how many, after being shown a method will a year later seem to have no awareness of it - right down to asking me the same question again. Even more so when the interaction with me is sitting in my email archive ready for me to re-send them. If I still had it and remember it, why did they not even thing to look there? Apparently one answer to that is that some don't even keep an email archive. But perhaps another answer is this lost (or never attained) confidence in being their own resource for a solution.
An other thing about solving coding problems is that there are several forms that this takes:
- algorithms
- language/concept specifics
- library/framework/environment specifics
While each instance is probably mostly just one of these, the boundaries won't always be simple. Sometimes:
- a language or library won't help you if you need a unique or new algorithm;
- a language won't help you if it lacks a concept required by the algorithm;
- a library function might use a language feature which which you're not familiar.
That said, I find in practice that I'm usually doing each time just one of the following:
- working out an algorithm from scratch, even if only to work if I've really got the problem fully understood
- needing to know how to do the thing I want to do in language X that I already know well how to do in language W (currently at home that's me trying to use Python)
- needing to find the specific name/syntax/feature in a library I'm using - often because the primary "documentation" doesn't read the way I need it to, and so a quoted example is what I need to see right now. (Hello Tkinter!)
A nice thing about my coding-at-home is that I don't have to stress over any of this. An idea I have for a tool-that-does-this can simply wait until the right combination of the above comes up with an answer.
Top comments (2)
p.s. Quite by chance, today at my work I decided it was worth looking at a method to improve the use of looking up data tables during a process. I didn't have a pressing need but thought it would be a useful run-time performance option to have to hand.
A lot of my work is data driven, trying hard to make program code unchanging and the changing parts all stored as data. Consequently I design in a lot of use of small tables to control actions on the much larger ones. A rewrite that I was toying with would happen to require every single data action to involve a check-the-control-table step. So I felt I shouldn't go there unless I had a way to do in-memory (but otherwise transparent) lookups. A first lookup would lead to data being loaded and thereafter fetches would pull from memory. Just in case I needed it, I figured I should include a call to have the in-memory version reloaded from the database.
Because of reasons (trust me, you don't want to know) I can't just go looking for plug-ins/modules/libraries that might already provide that feature. So if I want it, I'd need to code it.
As described above, I didn't feel like searching the net for something similar, and as the programming environment offers me dictionary and list objects I figured I should be able to build something good enough to use.
So I did the unfashionable thing and simply started coding from several different angles. Unusually for me, I wrote a separate text file of musings as I went along. At first it read like I was whingeing - "the language won't let me do this, so I'll have to rewrite it as this other way" followed by "now it won't let me do this other way". FWIW this involved some tension between object-oriented methods and defined-datatype+procedural methods.
As the attempt meandered - from me resolving the contradictions of my early guesses - I eventually realised that I had an Object that was internally all procedural code and would only ever require one instance of the object. At one point in the middle of all that, I was looking at an object definition per required table to be covered - it was my rebellion over how much code that would mean managing that led to my solution. Apart from the dictionary objects nothing is written as Object-Oriented - but it does happen that the new module can operate holding one static dictionary of all the tables it's covering.
To my surprise it only requires dictionaries throughout, no lists and only a couple of simple values (string, boolean, number) also as keyed dictionary values. I tested that I could tell it to load one table and that I could then fetch selected items from it. And thus I was happy.
Ironically, I might now do some looking for how other people may have tackled the same need - I presume it's a common one.
BTW - that work environment was not Python, but as Python has dictionary objects I should be able to find inspiration to achieve something similar for my Python coding at home.
As a further postscript, I have now completed a Python implementation of this example. It can be seen at this GitLab location
As I have already indicated, creating a solution is often a worthwhile exercise. In this case, a useful aspect is that it provides a quite minimal solution and thus requires fewer introduced dependencies than I'd be likely to find with more extensively crafted things.
There's no special line in the sand about this kind of thing. Sometimes this minimalism equals unchecked error conditions that will make for more technical debt than importing a more polished module would.
Personally I see this as being about the difference between what is required during the proof of concept creation phase versus what may be better for long term management and maintenance of a coding project.