[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Style suggestions/critiques

On 24/08/19 7:15 AM, Michael F. Stemper wrote:
> On 20/08/2019 21.57, DL Neil wrote:
>> On 21/08/19 9:11 AM, Michael F. Stemper wrote:
>>> I recently wrote a couple of modules (more to come) to help me
>>> use the tikz package in TeX/LaTeX. Since it's all to do with
>>> drawing, I have a lot of points in R^2. Being unimaginative, I
>>> This all seems reasonably simple and intuitive (to me). However,
>>> in order to actually do some manipulation, I have stuff like:

> This approach eliminates the ad hoc unpacking that I had been doing
> and made the accesses to particular items more explicit.
> Using this approach involves slightly more typing than my original
> approach, which allowed:
> ^^^ Origin = 0,0
> ^^^ wayright = 7,0

Most programmers subscribe to the belief: that code is read more often 
than it is written. Of course, the behavioral aspect of writing code so 
that it can be read, may be less evident...

Inevitably, what makes sense to you, may seem obscure to A.N.Other.

 > But, that's not really much more typing, and it'll help me keep in
 > mind what things are what.

Surely, understanding the "model", is key to a good solution?

> My existing code has a function Intersection(line1,line2) that
> calculates where line1 and line2 intersect (assuming that there
> is a unique such point). To me, this seems to be the proper
> pardigm, since it's clear that line1 and line2 are peers in the
> intersection function.

(To me) You've a good grasp on what is required, because you've realised 
important (levels of) relationships between the components of the problem.

There are both purists and pragmatists in this world, I have to beware 
"paralysis by analysis"!

> Am I being too fastidious here? Is there any reason that an
> idiom such as line1.Intersect( line2 ) would be preferable?

Let's replace the word "fastidious", which may convey ideas of excessive 
zeal, with "questioning". Thus: how else will you learn?

I'm not going to try to answer - as I've said 'here' before, I'm not an 
OOP-native, and often pick-up ideas/correction from others with clearer 

That said, 'looking around' live-code you will find both approaches, 
even within the PSL.

Remember, an object comprises both "data-attributes" and 
"method-attributes" (such formed a recent discussion, over on the 
Python-Tutor Discussion List). Accordingly, I'd put "intersection" 
within the Line object.

Thought 1: I find it easier to have the code 'all together' (within the 
Line class) cf having a separate "helper function" (albeit that likely 
residing within the same Python module). See also recent discussion 
'here', wherein I related from module import-ing a class, but forgetting 
to also import a 'helper'. (try to be nice to the 'grey hair' - he can't 
help it!)

Thought 2: whilst the (possibly) intersecting lines are "peers", within 
an English sentence ("subject", "verb", "object"), we would express one 
as the "subject" and the second as the "object". Accordingly, there is 
no difficulty is asking the same question in Python: (if/where) do 
I/self intersect with that other line/slope?

Accordingly, something like "find_intersection( self, other_line )" 
conveys meaning (to me). The fact is, "self" and "other_line" are both 
of the same object ("is-a" relationship to Line), ie "peers", and the 
code identifies that! Once again, stating the problem in English (or 
?human-language) and then writing it in Python...

Back to the philosophical level: always keep 'the big picture' in mind - 
if you are only coding a couple of lines and to solve a single question, 
it is literally "throw-away code". Who cares what it looks-like - as 
long as it works! However, if you intend to add a list of other analyses 
beyond 'intersection', then build your base-code/base-objects with that 
in-mind. (please recall earlier comment, that it may/not be worth making 
Cartesian points into an object!)

Small confession/admission/illustration/'object' lesson:
I coded a Point object, then later wanted a Vector. "Oh look" says 
lazy-boy, I could (mis-)use Point - they're both x-y pairs after-all... 
Later, along came the need for a "translation" function and delta-x, 
delta-y pairs. You guessed it, I over-over-loaded Point to the point 
(hah!) where I managed to confuse myself with my own over-clever-ness. 
That said, it was easy to "re-factor". Thus created a simple x-y base 
(or "super-class") from which (Cartesian) Point, Vector, Delta 
(whatever) could be derived/"sub-classed", and then the various methods 
applicable to each could be separated from each-other. The worst part, 
was going-through the entire system looking for evidence of my earlier, 
?over-clever, misdeeds. (blessings on modern text-editors which will 
search an entire directory of code at a time) However, thereafter, 
readability improved and progress accelerated...

Whilst OOP can sometimes seem like more work, or more "typing", (or 
consuming more resources) its central tenet is "re-use"! Yes, one can go 
'too far', or 'not far enough'; but what seems reasonable or pragmatic 
today, may change 'tomorrow'. "Uncle Bob" Martin and sundry other System 
Architects/philosophers promote the idea of leaving decisions "as late 
as possible". Certainly, ease of re-factoring makes code restructuring 
far more Agile today, than was once possible/practical!

Closing remarks:
If this is a learning-exercise, go for it! However, per another post, 
this exercise is largely 're-inventing the wheel'. The Python eco-system 
offers a plethora of 'math' extensions, eg NumPy and SciPy. These become 
applicable if it takes you less time to read their docs/learn to use, 
than it would to 'roll your own' functionality. My guess: you'll quickly 
look at the likes of matplotlib if/when you need to 'show' the results 
of these analyses graphically...

Have fun!
Regards =dn