ATTENTION: You are viewing a page formatted for mobile devices; to view the full web page, click HERE.

Main Area and Open Discussion > General Software Discussion

Gorgeous Karnaugh Review; How To Write Code As I See It

<< < (2/2)

peter.s:
(Immediately above:) "In those languages, you'd do the inter-item checking from the headers again."

Well, it was late in the evening...

In fact, for such languages to check variables, you must run the compiler, and we're speaking of pre-compilation checking here. So it seems some "partial compiling" just for one routine, to check intra-routine, would be a very good idea.

And some general observations:

You absolutely need "global replace", in order to do programming within an outliner; you might think that's ubiquitous, when in fact, in rare but notable cases (Ultra Recall), there is no such functionality (and "global" includes "this entry and its children"...).

In your outliner, you need exporting of "this entry and its children / whole tree" to txt.file; the compiler doesn't need all your formatting. Then you change the suffix, and run the compiler on that file, and in case open it within an editor, in case you can't identify the compiler's messages otherwise than by line number. (I do all this by script.)

If you insist on using an editor to begin with, you need to mimic an outliner's natural division into heading and body, into tree and content pane, and that's why you'll need Boolean search in your editor (always with hit table, i.e. with a list view displaying all occurrences of your search expression, together with their context):

For whatever would be, in an outliner, a heading, have an outcommented line with some special char.
For any variable, use another special char (you could even have several such special chars/char combinations, like $a at the end, or another group with $eb at the end, etc., by "greater context", and also grouping by variable format, i.e. integers, strings, many more, and it's also possible to tag (!) one variable with different such tags, so that they appear in different such searches.
Similar for routine calls and such.

Then, your search expression would e.g. be:
£ OR *$eb
and you would get a long hit table with lots of unnecessary entries/headings (the ££), but also with all variables of the group eb, beneath their respective headings (and which is the part you're after).

Yes, you could try to "optimize" this by also trying to tag your headings (or to cut up longer code into several files, but that would be dangerous if then you don't search "over all"), but if you code headings at the beginning (not the end as for variables and such), i.e. in the form
;£ Respective Heading
you will see at one glance where there are lists of headings with no "hits" in them, and where you should really look.

Of course, some "Expanded Boolean" would be more than welcome, a routine that would only show those "first-OR-element" when the next such element in the list is from the "second-OR-elements" variety, i.e. which would suppress any £ find NOT followed by a $ find in our example, but currently I do not remember any (editor's or other) ready-made search routine that would do that, without your programming that more elaborate routine first, by yourself?

peter.s:
I

After writing the above post, it occurs to me that my first post here was too abstract and not helpful enough.

Why do I muse about first part of a routine, and second part, and then the interconnexions of both? (Have a short look into the first post here if you begin reading down here though.)

Because good programming style is to abstract, to combine, AND to stay easily readable (i.e. a little bit the contrary of what I do in my writings here).

Let's have some real-life examples.

You do a typical, noob AHK script. There's a trap. You'll probable use the construct

#IfWinActive, some program
then all your key bindings there
#IfWinActive, some other program
then all your key bindings for that other program

and so on.

WRONG!

In many cases, you'll have similar routines, triggered from within different scopes. Ok, you could do triggers pointing to routines, but even then, even for the trigger scriptlets, lots of similarities would be spread all over the place, instead of being held together, i.e. you'll need to send (sometimes, multiple) attributes (unfortunately, necessarily by variables, in AHK, and this means that if you have ONE key assigment in the form

somekey(combi)::
if ( winactive("abc") or winactive("def") ... )
else if (winactive ... etc.
else if ...

and then trigger ONE routine, or just a few routines, for similar tasks, you'll get much neater code, here where in most cases, most attributes will be identical (except for the variable indicating from which applic that other routine was triggered), and also "on target", i.e. for those routines which then handle lots of similar functionality, with just some little differentiation depending on the trigger source.

After this intro into "Key, then scope, instead of the other way round, for AHK", i.e. the real-life example for the trigger, let's have a second real-life example, for the trigger-and-target this time.

Let's imagine you do your own little file manager, for PM and such, with 6 or more panes (as they are in some ready-made file managers available out there). Trigger would be selection and then Return, or Click or Double click, in those 6 panes or so; let's imagine such selection, in some panes/list fields, would trigger external display, whilst other such selections would simply change the content in neighbouring/subordinate list fields.

So what will you do? Do like an AHK noob on his first day, and do 100 scriptlets, all VERY similar to each other? I hope not!

Instead, you will gather all those different trigger situations in part 2 of your routine (part 1 containing variable declarations and such stuff); if this kind of trigger in that pane number, your little program should do this or that suite of commands; you assign variables which are then checked for in part 3 of your routine.

There (again, this is a real-life example for what I exposed in post 1 above), you'll do a second if, if else, if else... (or condition / when / when... (not possible in AHK) structure, and indeed, as explained above, this second (part 3) if structure is NOT identical or quasi-identical with the similar conditional structure in part 2 above.

Since, as explained, those triggers are very similar, but there could be several groups of commands; of course, instead of having just one part 3 of the routine, you will instead call external routines, "sub-routines" from there, either if those "executive" routines are rather long on their own (but as explained in my previous post, why not do a a 10- or 12-pages routines, as long as those pages are clearly distinct?!), or if you trigger routines which must also be accessible from other triggers (= keys or routines).

In that second case, there is no choice, and you'll do them as separatine routines of course (and there are cases where first you do that "routine" as page 7 of 12 first, within such a bigger routine, and it'll be after writing this routine that it will occur to you that page 7 should be accessible from elsewhere, too, and then you simply cut off that page to an external subroutine; in this case you'll check for the variables that will be declared in that new external subroutine, in order to get that all the necessary information from its trigger routine of which it was once just one part; i.e., as said above, fractionizing multiplies headers (which can become rather extensive), and if you don't need access to some routine part from the outside, doint it all in one big routine helps with minimizing unnecessary headers).

Back to our tripart routine: Now, in part 3, you check for every variable you will have created/set up in part 2, and here, the similarities between different blocks could be totally different from similarities in part 2: Just some examples, different file formats, different target panes, and as said before, even, instead of showing files, just listing files.

Here in part 3, you'll group again, according to such similarities, but the items in your conditional structure will probably be in a totally different order from the one they, or similar ones, were in part 1. And of course, you will spread up your blocks into different pages here, and this could even determine the order in which you put your blocks, i.e. why not do if var1 = 3 or 4 or 8, else if var1 = 1 or 2 or 5, else if var1 = 6, else if var1 = 7, etc. -

just because those 3 and 4 and 8 are quite similar and easy and can be treated all together on page 3, whilst variants 2 and 5 will be treated on page 4, together again, whilst 6 and 7 each will nead, separately, one page of their own; if afterwards, you'll see that 6 needs its own subroutine, you will not leave the call for that subroutine, alone, on page 8 or so, but you'll do the else if var1 = 6 on page 3, before the "longer" code blocks.

Sideline: It's always a good idea to discard simple things as soon as possible. E.g., I never write, if x ... then 10 lines, else, return, but I always write if x = 0 (or input = zero or something), return, and then, without else, without indentation, the main structure:

not:
if a = 1
{
   10 lines here, all indented
}
else
   return

but

if a = 0 ; even if it's very improbable
   return
here 10 lines of main code (no braces, no indentation)

Accordingly, I check as early as possible for values that would invalidate other structures, so as to not even run parts of those structures, to then be aborted anyway.

Now a sideline: You could do this tripartite 1-2-3 for heading, set-up, execution, with goto's instead of variables, or at least you could replace lots of variables by such goto's.

As said before, don't be afraid of goto's, if their targets are on top of above-described pages 5, 6, 7, no problem whatsoever: Goto's don't make your code spaghetti code PER SE, and functionally, there is no big difference between target-pointer-variables and goto's - except that in my multiple-spreading variable-if-structures, I don't need then further goto's in order to leap over following blocks, whilst in a goto structure, you will need to pay attention to do that, in order to get OUT of your goto target, since if you do not pay that attention, any goto will continue then with the following goto, and so on, and in 99 p.c. of the cases, that's presumably not what you intended it to do (and which an if-else if structure does not)! So, pointer variables are both much more flexible (ok, that could become a trap, your, by laziness, interweaving several if structures...), and neater.

And, of course, most programming languages have abolished goto's, which would become an obstacle when translating to code in some other language. Obviously, those same extremists that abolished goto's, did NOT find a way yet to abolish pointer variables, i.e. can't stop you from (mis)using integer or yes/no/true/false variables as pointers being even better goto's than original goto's ever were.

Use such pointer variables to structure your code, and it will become easy to write for any beginner, and will be perfectly readable/neat, maintanable, etc. It's a good way to code, and that's why it was worth it to better explain it to you than in post 1 here.

II

What about my question at the end of my previous post? Is there any editor where you could suppress search hit lines containing search term 1, which are NOT followed by hit lines containing search term 2? There are many occasions where such an editor would become more than helpful...

(As said before, rtf formatting of your code is so extremely useful that I would not switch from outliner to editor, for writing code, but many people will not switch from editor to outliner, but would switch to a really better editor than their current one, and this feature would make all the difference, as explained above.)

mouser:
I have found one of very the best ways to help new coders become better is to tell them to focus like a laser on ELIMINATING DUPLICATE CODE.

This is especially true because it's very natural for beginning coders to repeat big chunks of code, and the simple act of forcing them to eliminate duplicate code -- either by changing the structure of conditionals and control structures, or by using functions -- does wonders to improve the quality of code.

It is also very helpful as a pedagogical tool (teaching aid) because it can be otherwise difficult to explain to a new coder when and where they should use functions -- wheras anyone can visually see when they have repeated big blocks of text.

phitsc:
There are also tools that detect and report code duplication for various programming languages. These are mostly commercial though.

Navigation

[0] Message Index

[*] Previous page

Go to full version