QB64 Phoenix Edition
Paranoia - Printable Version

+- QB64 Phoenix Edition (https://qb64phoenix.com/forum)
+-- Forum: QB64 Rising (https://qb64phoenix.com/forum/forumdisplay.php?fid=1)
+--- Forum: Code and Stuff (https://qb64phoenix.com/forum/forumdisplay.php?fid=3)
+---- Forum: Help Me! (https://qb64phoenix.com/forum/forumdisplay.php?fid=10)
+---- Thread: Paranoia (/showthread.php?tid=767)



Paranoia - bartok - 08-13-2022

Hi,

I followed this forum in the old web-site.

Starting from 0, after having done the Terry Ritchies's tutorials, I created, little by little, a quite articulated program, that I have finished since some months, leaving out some little improvementS.



Currently, in order to maximize a kind of formal elegance in the code, I'm starting to suspect to be going towards a paranoia. I wonder things like that: "in a SELECT CASE, is it better to provide each CASE, even the most important part of the code, or it would be better to have the code outside the SELECT CASE, like a flow?



For example:
First paranoia.


Is it better like this:


Code: (Select All)
DO
    _LIMIT 30
    KeyPress$ = INKEY$
LOOP UNTIL KeyPress$ = "1" OR KeyPress$ = "2" OR KeyPress$ = CHR$(27) OR KeyPress$ = CHR$(9) OR KeyPress$ = CHR$(0) + CHR$(59)
SELECT CASE KeyPress$
    CASE "1", "2"
        [A LOT OF CODE 1] <---------------------------------------------
        DO
            _LIMIT 30
            KeyPress$ = INKEY$
        LOOP UNTIL KeyPress$ = CHR$(27) OR KeyPress$ = CHR$(9) OR KeyPress$ = CHR$(0) + CHR$(59) OR KeyPress$ = CHR$(0) + CHR$(77)
        SELECT CASE KeyPress$
            CASE CHR$(27)
                esc~` = 1
            CASE CHR$(9)
                riavvio~` = 1
            CASE CHR$(0) + CHR$(59)
                menu~` = 1
            CASE CHR$(0) + CHR$(77)
                [A LOT OF CODE 2] <---------------------------------------------
        END SELECT
    CASE CHR$(27)
        esc~` = 1
    CASE CHR$(9)
        riavvio~` = 1
    CASE CHR$(0) + CHR$(59)
        menu~` = 1
END SELECT

Or like that:
Code: (Select All)
DO
    _LIMIT 30
    KeyPress$ = INKEY$
LOOP UNTIL KeyPress$ = "1" OR KeyPress$ = "2" OR KeyPress$ = CHR$(27) OR KeyPress$ = CHR$(9) OR KeyPress$ = CHR$(0) + CHR$(59)
SELECT CASE KeyPress$
    CASE CHR$(27)
        esc~` = 1
    CASE CHR$(9)
        riavvio~` = 1
    CASE CHR$(0) + CHR$(59)
        menu~` = 1
END SELECT

[A LOT OF CODE 1] <---------------------------------------------

DO
    _LIMIT 30
    KeyPress$ = INKEY$
LOOP UNTIL KeyPress$ = CHR$(27) OR KeyPress$ = CHR$(9) OR KeyPress$ = CHR$(0) + CHR$(59) OR KeyPress$ = CHR$(0) + CHR$(77)
SELECT CASE KeyPress$
    CASE CHR$(27)
        esc~` = 1
    CASE CHR$(9)
        riavvio~` = 1
    CASE CHR$(0) + CHR$(59)
        menu~` = 1
END SELECT

[A LOT OF CODE 2] <---------------------------------------------

That's absolutely the same! But the structure completely changes in a conceptual way. I have take a little example, but it is not difficult to figure how the structure of a greater program could changes in a way, or in the other one. In the second example, the code is more simular to a flow. In the first, the logical structure is strictly respected, but nonetheless the program in it self, leaving out the possibility to navigate in it going back or ahead, it actually is a flow which begins from a start, until the end.

What is the better one, according to the "art of coding"?


Second paranoia.
About the the main code. As we know, the main code is the real tree of the program, which contains its structure, calling routines and subroutines which make specific things. That said, is it better to maximize the possibility to can understand the logical structure of the program at the expense of the logical comprehension of what the program actually does, or is it better the contrary.

I put 2 examples, that have the absolutely same structures and made absolutley the same things. In the first, it is avoided ALL is not strictly required in order to have the structure working, above all discursive parts, but not only.

Is it better this:
Code: (Select All)
DO
    CLEAR

    DIM SHARED DESKTOPWIDTH%, DESKTOPHEIGHT%
    DIM SHARED i%, n%%, z%%, p%%
    DIM SHARED ieto%%
    DIM SHARED VisualizzaIeto%%
    DIM SHARED tipo%%
    DIM SHARED esc~`, riavvio~`, menu~`, TornaAlGrafico~`
    DIM SHARED interrompi~`(2)
    DIM SHARED inputs$(8)
    DIM SHARED KeyPress$
    DIM SHARED CoefficientiDiscretizzazioneTemporale(24) AS CoefficientiDiscretizzazioneTemporale
    DIM SHARED TempiRitorno(10) AS TempiRitorno
    DIM SHARED idrogrammi1a24(2, 24, 50, 1) AS idrogramma
    DIM SHARED MassimiIdrogrammi1a24(2, 24, 1) AS idrogramma
    DIM SHARED MassimiAssolutiIeto(2) AS idrogramma
    DIM SHARED IdroMaxieto%%(2)
    DIM SHARED FinePioggiaIdrogrammi1a24(2, 24, 1) AS idrogramma
    DIM SHARED FinePioggiaIdrogrammi1e2(2) AS idrogramma
    DIM SHARED PassiFinePioggia1a24%%(24)
    DIM SHARED ore!(3), portata!(3)

    REDIM SHARED IdroPixel1(1) AS idrogramma
    REDIM SHARED IdroPixel2(1) AS idrogramma

    DIM L%, H%
    DIM posizione%
    DIM OriginaleGrafico&
    DIM schermo&
    DIM unitari&
    DIM quadro&
    DIM ComplessivoIeto1e2(2) AS composizione
    DIM idrogramma1e2(2) AS composizione
    DIM MatriciIeto1e2(2, 24)
    DIM mockus(50) AS mockus
    DIM matrice1(2, 24, 50, 1) AS matrice1
    DIM matrice2!(2, 24, 50, 50)
    DIM MinimiMatriciQuadrante1(2, 24, 1) AS idrogramma
    DIM MinimiMatriciQuadrante2(2, 24, 1) AS idrogramma
    DIM MassimiQuadrante2(2, 24, 1) AS idrogramma
    DIM k!
    DIM a1!
    DIM n1!
    DIM A2&
    DIM L~%
    DIM s1!
    DIM CNII%%
    DIM CoeffPerditeIniziali!
    DIM CNIII!
    DIM tl!
    DIM S2!
    DIM Ia!
    DIM tc!
    DIM ta!
    DIM qp!
    DIM dt!(24)

    RESTORE TempiRitorno
    FOR i% = 1 TO 20
        IF i% <= 10 THEN READ TempiRitorno(i%).T
        IF i% > 10 THEN READ TempiRitorno(i% - 10).k
    NEXT i%
    RESTORE CoefficientiIdrogrammaUnitarioMockus
    FOR i% = 1 TO 100
        IF i% <= 50 THEN READ mockus(i%).tSUta
        IF i% > 50 THEN READ mockus(i% - 50).qSUqp
    NEXT i%
    RESTORE CoefficientiDiscretizzazioneTemporale
    FOR i% = 1 TO 48
        IF i% <= 24 THEN READ CoefficientiDiscretizzazioneTemporale(i%).N
        IF i% > 24 THEN READ CoefficientiDiscretizzazioneTemporale(i% - 24).tSUta
    NEXT i%

    DESKTOPWIDTH% = _DESKTOPWIDTH
    DESKTOPHEIGHT% = _DESKTOPHEIGHT
    'DESKTOPWIDTH% = 1280 'limite inferiore della risoluzione dello schermo in pixel per il funzionamento del programma.
    'DESKTOPHEIGHT% = 720
    'DESKTOPWIDTH% = 1366 'valore intermedio della risoluzione dello schermo in pixel per il funzionamento del programma.
    'DESKTOPHEIGHT% = 768
    'DESKTOPWIDTH% = 1024 'sotto il limite inferiore della risoluzione dello schermo in pixel per il funzionamento del programma.
    'DESKTOPHEIGHT% = 768
    IF DESKTOPWIDTH% < 1280 THEN
        esc~` = 1 'il programma è avviato verso la chiusura.
        PRINT "Il programma Š incompatibile con schermi larghi meno di 1280 pixel."
        PRINT "Questo schermo Š largo"; DESKTOPWIDTH%; "pixel."
        PRINT "Premere un tasto per uscire."
        BEEP
        SLEEP
        EXIT DO
    ELSE
        _FULLSCREEN
        L% = DESKTOPWIDTH%: H% = L% \ 1.62
    END IF
    DO
        menu~` = 0
        VisualizzaIeto%% = 0
        inizio:
        IF _DIREXISTS(".\RisultatiQB64") THEN
            ON ERROR GOTO cancel1
            KILL (".\RisultatiQB64\*.*")
            ON ERROR GOTO cancel2
            RMDIR (".\RisultatiQB64")
        END IF
        ON ERROR GOTO 0

        REDIM SHARED idrogramma1(1) AS idrogramma
        REDIM SHARED idrogramma2(1) AS idrogramma

        ERASE idrogrammi1a24, MassimiIdrogrammi1a24, FinePioggiaIdrogrammi1a24, MassimiAssolutiIeto, IdroMaxieto%%, FinePioggiaIdrogrammi1e2, PassiFinePioggia1a24%%, IdroPixel1, IdroPixel2, dt!, matrice1, matrice2!,_
        MinimiMatriciQuadrante1, MinimiMatriciQuadrante2, MassimiQuadrante2
        FOR ieto%% = 1 TO 2
            ComplessivoIeto1e2(ieto%%).grafico = _NEWIMAGE(L% - 48 * 8, H%, 32)
            ComplessivoIeto1e2(ieto%%).composizione = _NEWIMAGE(L%, H%, 32)
            idrogramma1e2(ieto%%).grafico = _NEWIMAGE(L% - 59 * 8, H%, 32)
            idrogramma1e2(ieto%%).composizione = _NEWIMAGE(L%, H%, 32)
            FOR z%% = 1 TO 24
                MatriciIeto1e2(ieto%%, z%%) = _NEWIMAGE(L%, H%, 32)
            NEXT z%%
        NEXT ieto%%
        schermo& = _NEWIMAGE(DESKTOPWIDTH%, DESKTOPHEIGHT%, 32)
        unitari& = _NEWIMAGE(L%, H%, 32)
        quadro& = _NEWIMAGE(L% - 97 * 8, H% \ 2, 32)
        GOSUB IstruzioniMenu
        CALL InserimentoDati(k!, a1!, n1, A2&, L~%, s1!, CNII%%, CoeffPerditeIniziali!)
        IF esc~` = 1 OR riavvio~` = 1 THEN EXIT DO
        GOSUB Richiesta
        DO
            _LIMIT 30
            KeyPress$ = INKEY$
        LOOP UNTIL KeyPress$ = "1" OR KeyPress$ = "2" OR KeyPress$ = CHR$(27) OR KeyPress$ = CHR$(9) OR KeyPress$ = CHR$(0) + CHR$(59)
        SELECT CASE KeyPress$
            CASE "1", "2"
                GOSUB CalcoloDatiPartenza
                IF esc~` = 1 OR riavvio~` = 1 THEN EXIT SELECT
                GOSUB IstruzioniIdrogrammi
                DO
                    _LIMIT 30
                    KeyPress$ = INKEY$
                LOOP UNTIL KeyPress$ = CHR$(27) OR KeyPress$ = CHR$(9) OR KeyPress$ = CHR$(0) + CHR$(59) OR KeyPress$ = CHR$(0) + CHR$(77)
                SELECT CASE KeyPress$
                    CASE CHR$(27)
                        esc~` = 1
                        IF VisualizzaIeto%% = 2 THEN
                            CALL CalcolaIdrogramma(MassimiIdrogrammi1a24(VisualizzaIeto%%, 24, 1).ore, idrogrammi1a24(VisualizzaIeto%%, 24, 50, 1).ore, MassimiAssolutiIeto(VisualizzaIeto%%).ore,_
                            MassimiAssolutiIeto(VisualizzaIeto%%).portata, ComplessivoIeto1e2(VisualizzaIeto%%).grafico, ComplessivoIeto1e2(VisualizzaIeto%%).composizione)
                            GOSUB DisegnaIdrogramma
                        END IF
                    CASE CHR$(9)
                        riavvio~` = 1
                    CASE CHR$(0) + CHR$(59)
                        menu~` = 1
                    CASE CHR$(0) + CHR$(77)
                        GOSUB Visualizza
                END SELECT
            CASE CHR$(27)
                esc~` = 1
            CASE CHR$(9)
                riavvio~` = 1
            CASE CHR$(0) + CHR$(59)
                menu~` = 1
        END SELECT
        IF riavvio~` = 0 AND menu~` = 0 THEN
            _DEST shermo&
            VIEW PRINT
            CLS
            IF VisualizzaIeto%% <> 0 THEN
                IF interrompi~`(1) = 0 OR interrompi~`(2) = 0 THEN
                    GOSUB RichiestaSalvataggio
                    DO
                        _LIMIT 30
                        KeyPress$ = INKEY$
                    LOOP UNTIL KeyPress$ = "1" OR KeyPress$ = "2" OR KeyPress$ = CHR$(27) OR KeyPress$ = CHR$(9) OR KeyPress$ = CHR$(0) + CHR$(59)
                    SELECT CASE KeyPress$
                        CASE "1", "2"
                            GOSUB Salva
                            DO
                                _LIMIT 30
                                KeyPress$ = INKEY$
                            LOOP UNTIL KeyPress$ = CHR$(27) OR KeyPress$ = CHR$(9) OR KeyPress$ = CHR$(0) + CHR$(59)
                            SELECT CASE KeyPress$
                                CASE CHR$(27)
                                    esc~` = 1
                                CASE CHR$(9)
                                    riavvio~` = 1
                                CASE CHR$(0) + CHR$(59)
                                    menu~` = 1
                            END SELECT
                        CASE CHR$(27)
                            esc~` = 1
                        CASE CHR$(9)
                            riavvio~` = 1
                        CASE CHR$(0) + CHR$(59)
                            menu~` = 1
                    END SELECT
                END IF
            END IF
        END IF
        IF riavvio~` = 1 OR menu~` = 1 THEN GOSUB freeimage
    LOOP UNTIL esc~` = 1 OR riavvio~` = 1
LOOP UNTIL esc~` = 1
freeimage:
IF DESKTOPWIDTH% >= 1280 THEN
    FOR ieto%% = 1 TO 2
        _FREEIMAGE ComplessivoIeto1e2(ieto%%).grafico
        _FREEIMAGE ComplessivoIeto1e2(ieto%%).composizione
        _FREEIMAGE idrogramma1e2(ieto%%).grafico
        _FREEIMAGE idrogramma1e2(ieto%%).composizione
        FOR z%% = 1 TO 24
            _FREEIMAGE MatriciIeto1e2(ieto%%, z%%)
        NEXT z%%
    NEXT ieto%%
    _FREEIMAGE unitari&
    _FREEIMAGE quadro&
    ON ERROR GOTO cancel1: _FREEIMAGE OriginaleGrafico&: ON ERROR GOTO 0
END IF
IF riavvio~` = 1 OR menu~` = 1 THEN RETURN
SYSTEM

Or that:
Code: (Select All)
DO
    CLEAR

    DIM SHARED DESKTOPWIDTH%, DESKTOPHEIGHT%
    DIM SHARED i%, n%%, z%%, p%%
    DIM SHARED ieto%%
    DIM SHARED VisualizzaIeto%%
    DIM SHARED tipo%%
    DIM SHARED esc~`, riavvio~`, menu~`, TornaAlGrafico~`
    DIM SHARED interrompi~`(2)
    DIM SHARED inputs$(8)
    DIM SHARED KeyPress$
    DIM SHARED CoefficientiDiscretizzazioneTemporale(24) AS CoefficientiDiscretizzazioneTemporale
    DIM SHARED TempiRitorno(10) AS TempiRitorno
    DIM SHARED idrogrammi1a24(2, 24, 50, 1) AS idrogramma
    DIM SHARED MassimiIdrogrammi1a24(2, 24, 1) AS idrogramma
    DIM SHARED MassimiAssolutiIeto(2) AS idrogramma
    DIM SHARED IdroMaxieto%%(2)
    DIM SHARED FinePioggiaIdrogrammi1a24(2, 24, 1) AS idrogramma
    DIM SHARED FinePioggiaIdrogrammi1e2(2) AS idrogramma
    DIM SHARED PassiFinePioggia1a24%%(24)
    DIM SHARED ore!(3), portata!(3)

    REDIM SHARED IdroPixel1(1) AS idrogramma
    REDIM SHARED IdroPixel2(1) AS idrogramma

    DIM L%, H%
    DIM posizione%
    DIM OriginaleGrafico&
    DIM schermo&
    DIM unitari&
    DIM quadro&
    DIM ComplessivoIeto1e2(2) AS composizione
    DIM idrogramma1e2(2) AS composizione
    DIM MatriciIeto1e2(2, 24)
    DIM mockus(50) AS mockus
    DIM matrice1(2, 24, 50, 1) AS matrice1
    DIM matrice2!(2, 24, 50, 50)
    DIM MinimiMatriciQuadrante1(2, 24, 1) AS idrogramma
    DIM MinimiMatriciQuadrante2(2, 24, 1) AS idrogramma
    DIM MassimiQuadrante2(2, 24, 1) AS idrogramma
    DIM k!
    DIM a1!
    DIM n1!
    DIM A2&
    DIM L~%
    DIM s1!
    DIM CNII%%
    DIM CoeffPerditeIniziali!
    DIM CNIII!
    DIM tl!
    DIM S2!
    DIM Ia!
    DIM tc!
    DIM ta!
    DIM qp!
    DIM dt!(24)

    RESTORE TempiRitorno
    FOR i% = 1 TO 20
        IF i% <= 10 THEN READ TempiRitorno(i%).T
        IF i% > 10 THEN READ TempiRitorno(i% - 10).k
    NEXT i%
    RESTORE CoefficientiIdrogrammaUnitarioMockus
    FOR i% = 1 TO 100
        IF i% <= 50 THEN READ mockus(i%).tSUta
        IF i% > 50 THEN READ mockus(i% - 50).qSUqp
    NEXT i%
    RESTORE CoefficientiDiscretizzazioneTemporale
    FOR i% = 1 TO 48
        IF i% <= 24 THEN READ CoefficientiDiscretizzazioneTemporale(i%).N
        IF i% > 24 THEN READ CoefficientiDiscretizzazioneTemporale(i% - 24).tSUta
    NEXT i%

    DESKTOPWIDTH% = _DESKTOPWIDTH
    DESKTOPHEIGHT% = _DESKTOPHEIGHT
    'DESKTOPWIDTH% = 1280 'limite inferiore della risoluzione dello schermo in pixel per il funzionamento del programma.
    'DESKTOPHEIGHT% = 720
    'DESKTOPWIDTH% = 1366 'valore intermedio della risoluzione dello schermo in pixel per il funzionamento del programma.
    'DESKTOPHEIGHT% = 768
    'DESKTOPWIDTH% = 1024 'sotto il limite inferiore della risoluzione dello schermo in pixel per il funzionamento del programma.
    'DESKTOPHEIGHT% = 768
    IF DESKTOPWIDTH% < 1280 THEN
        esc~` = 1 'il programma è avviato verso la chiusura.
        PRINT "Il programma Š incompatibile con schermi larghi meno di 1280 pixel."
        PRINT "Questo schermo Š largo"; DESKTOPWIDTH%; "pixel."
        PRINT "Premere un tasto per uscire."
        BEEP
        SLEEP
        EXIT DO
    ELSE
        _FULLSCREEN
        L% = DESKTOPWIDTH%: H% = L% \ 1.62
    END IF
    DO
        menu~` = 0
        VisualizzaIeto%% = 0
        inizio:
        IF _DIREXISTS(".\RisultatiQB64") THEN
            ON ERROR GOTO cancel1
            KILL (".\RisultatiQB64\*.*")
            ON ERROR GOTO cancel2
            RMDIR (".\RisultatiQB64")
        END IF
        ON ERROR GOTO 0

        REDIM SHARED idrogramma1(1) AS idrogramma
        REDIM SHARED idrogramma2(1) AS idrogramma

        ERASE idrogrammi1a24, MassimiIdrogrammi1a24, FinePioggiaIdrogrammi1a24, MassimiAssolutiIeto, IdroMaxieto%%, FinePioggiaIdrogrammi1e2, PassiFinePioggia1a24%%, IdroPixel1, IdroPixel2, dt!, matrice1, matrice2!,_
        MinimiMatriciQuadrante1, MinimiMatriciQuadrante2, MassimiQuadrante2
        FOR ieto%% = 1 TO 2
            ComplessivoIeto1e2(ieto%%).grafico = _NEWIMAGE(L% - 48 * 8, H%, 32)
            ComplessivoIeto1e2(ieto%%).composizione = _NEWIMAGE(L%, H%, 32)
            idrogramma1e2(ieto%%).grafico = _NEWIMAGE(L% - 59 * 8, H%, 32)
            idrogramma1e2(ieto%%).composizione = _NEWIMAGE(L%, H%, 32)
            FOR z%% = 1 TO 24
                MatriciIeto1e2(ieto%%, z%%) = _NEWIMAGE(L%, H%, 32)
            NEXT z%%
        NEXT ieto%%
        schermo& = _NEWIMAGE(DESKTOPWIDTH%, DESKTOPHEIGHT%, 32)
        unitari& = _NEWIMAGE(L%, H%, 32)
        quadro& = _NEWIMAGE(L% - 97 * 8, H% \ 2, 32)
        SCREEN schermo&
        CLS
        COLOR giallo&: PRINT "        C A L C O L O   D E L L ' I D R O G R A M M A   D I   P I E N A   D I   P R O G E T T O   T R A M I T E   I L   M E T O D O   S C S - C N"
        COLOR grigio&: PRINT "                                                  -  I N G .   C A R L O   B A R T O L I N I  -"
        COLOR bianco&
        PRINT "Questo programma calcola:"
        PRINT "- l'idrogramma di piena di progetto (e relativa portata di picco);"
        PRINT "- se voluto, l'idrogramma di piena corrispondente ad un'ora di picco a scelta,"
        PRINT "per un dato tempo di ritorno tramite l'idrogramma unitario adimensionale di Mockus,il metodo afflussi-deflussi SCS-CN, ietogrammi "; CHR$(34); "Chicago"; CHR$(34); " e "; CHR$(34); "costanti"; CHR$(34); "."
        PRINT "Sar… possibile scegliere se  visualizzare i risultati in base  a l'uno o all'altro  tipo di ietogramma, ma anche  quello non visualizzato, sar…  comunque"
        PRINT "calcolato ed  eventualmente salvato nei  risultati dal  programma che, dopo  l'elaborazione e  premendo ESC o al suo termine, chieder…  se salvarli nella"
        PRINT "seguente directory:"
        PRINT
        PRINT CHR$(34); _CWD$; "\RisultatiQB64"; CHR$(34); "."
        PRINT
        PRINT "Nel caso si vogliano salvare i risultati,Š consigliato che il programma si trovi sul computer locale,nel qual caso l'operazione di salvataggio richieder…"
        PRINT "pochi  secondi o 1-2 minuti, a  seconda che  si salvino  solo i tabulati o anche le immagini. Da rete, invece, possono  occorrere molti minuti solo per i"
        PRINT "tabulati."
        PRINT "I file salvati saranno di 3 tipi:"
        PRINT "- immagini dei grafici, con estensione "; CHR$(34); "BMP"; CHR$(34); ";"
        PRINT "- tabulati, con estensione "; CHR$(34); "CSV"; CHR$(34); ". Possono essere aperti con  Excel, ma per essere visualizzati correttamente, nelle impostazioni di Windows il separatore"
        PRINT "  dell'elenco dev'essere la virgola. Le celle dei fogli di lavoro dei file relativi al calcolo di ogni idrogramma contengono le formule,per cui in essi Š"
        PRINT "  esemplificata la procedura di calcolo del programma stesso;"
        PRINT "- un file con estensione "; CHR$(34); "TXT"; CHR$(34); " in cui Š riportato il codice del programma commentato, comprese le procedure di calcolo."
        PRINT "Rieseguendo o riavviando  il programma [TAB], o tornando al menu degli input qui  di seguito [F1], la directory "; CHR$(34); "RisultatiQB64"; CHR$(34); "sar… cancellata, quindi se"
        PRINT "s'intende preservare i risultati, sar… prima necessario o rinominarla o spostarla."
        PRINT "---------------------------------------------------------------------------------------------------------------------------------------------------------"
        PRINT "Di seguito,si dovranno inserire i valori della curva di possibilit… climatica "; CHR$(34); "h = Ktúaúd^n"; CHR$(34); ". Se si dispone dei valori del Centro Funzionale, digitare il"
        PRINT "valore "; CHR$(34); "Kt"; CHR$(34); " relativo al  tempo di ritorno "; CHR$(34); "T"; CHR$(34); " d'interesse, con i relativi valori "; CHR$(34); "a"; CHR$(34); " e "; CHR$(34); "n"; CHR$(34); ". Se invece si ha una propria curva di possibilit… climatica,in"
        PRINT "corrispondenza di "; CHR$(34); "Kt"; CHR$(34); ", digitare "; CHR$(34); "INVIO"; CHR$(34); ", o "; CHR$(34); "1"; CHR$(34); ".In tal caso "; CHR$(34); "Kt"; CHR$(34); " sar… considerato pari a "; CHR$(34); "1"; CHR$(34); " e "; CHR$(34); "T"; CHR$(34); " come "; CHR$(34); "definito dall'utente"; CHR$(34); "."
        PRINT
        PRINT "- Kt [-] (INVIO per 1)                                            = "
        PRINT "- a [mm/d^n]                                                      = "
        PRINT "- n [-] (0ö1)                                                     = "
        PRINT "- Area in pianta del bacino idrografico [mý] (>=1)                = "
        PRINT "- Lunghezza dell'asta principale del bacino idrografico [m] (>=1) = "
        PRINT "- Pendenza media del bacino idrografico [%] (>=1)                 = "
        PRINT "- CN(II) [-] (1ö100)                                              = "
        PRINT "- Coefficiente delle perdite inziali [-] (0ö0.2 - INVIO per 0.1)  = "
        LOCATE CSRLIN + 2,
        COLOR giallo&: PRINT "  [ESC]: esci; [TAB]: riavvia.": COLOR bianco&
        CALL InserimentoDati(k!, a1!, n1, A2&, L~%, s1!, CNII%%, CoeffPerditeIniziali!)
        IF esc~` = 1 OR riavvio~` = 1 THEN EXIT DO
        LOCATE PosizioneCursore%% + 9, 1
        COLOR giallo&
        PRINT "  [1]: utilizza lo ietogramma Chicago; [2]: utilizza lo ietogramma costante;"
        PRINT "  [ESC]: esci; [TAB]: riavvia; [F1]: torna agli input iniziali."
        COLOR bianco&
        DO
            _LIMIT 30
            KeyPress$ = INKEY$
        LOOP UNTIL KeyPress$ = "1" OR KeyPress$ = "2" OR KeyPress$ = CHR$(27) OR KeyPress$ = CHR$(9) OR KeyPress$ = CHR$(0) + CHR$(59)
        SELECT CASE KeyPress$
            CASE "1", "2"
                VisualizzaIeto%% = VAL(KeyPress$)
                CNIII! = (23 * CNII%%) / (10 + 0.13 * CNII%%) '                                                  ¿
                tl! = 0.342 * ((L~% / 1000) ^ 0.8 / s1! ^ 0.5) * (1000 / CNIII! - 9) ^ 0.7 '* formula di Mockus. ³ dati immediatamente discendenti dagli input iniziali, che fungono da input interni al programma per le elaborazioni.
                S2! = 25.4 * (1000 / CNIII! - 10) '*                                                             ³
                Ia! = CoeffPerditeIniziali! * S2! '* coeff.=0.03-0.2. 'perdite iniziali                          ³ *  La sistemazione dei bacini montani - Vito Ferro - Seconda edizione - cap. 3.4.7. "Il metodo SCS" - pp. 195-205.
                tc! = tl! / 0.6 '**                                                                              ³
                ta! = tl! / 0.9 '*                                                                               ³ ** ibid. cap. 3.4.4. "Il tempo di corrivazione di un bacino" - p. 188.
                qp! = 0.208 * ((A2& / 1000000) / ta!) '*                                                         Ù
                FOR ieto%% = 1 TO 2
                    interrompi~`(ieto%%) = 0
                    continua1:
                    IF interrompi~`(1) = 1 THEN IF ieto%% = 1 THEN _CONTINUE
                    continua2:
                    IF interrompi~`(2) = 1 THEN EXIT FOR
                    IF ieto%% = 1 THEN ON ERROR GOTO salta1
                    IF ieto%% = 2 THEN ON ERROR GOTO salta2
                    FOR z%% = 1 TO 24
                        GOSUB CalcolaMatriciIeto1e2
                        GOSUB DisegnaMatriciIeto1e2
                    NEXT z%%
                    IF interrompi~`(ieto%%) = 0 THEN GOSUB DisegnaComplessivoIeto1e2
                NEXT ieto%%
                ON ERROR GOTO 0
                GOSUB TerminaSeErrore
                IF esc~` = 1 OR riavvio~` = 1 THEN EXIT SELECT
                GOSUB DisegnaUnitari
                _DEST schermo&
                PRINT "---------------------------------------------------------------------------------------------------------------------------------------------------------"
                PRINT "Sono stati calcolati 24 idrogrammi di piena con relative portate di picco,per durate della pioggia fino a 32 volte il tempo di corrivazione. Nella pagina"
                PRINT "successiva, saranno visualizzati insieme alla spezzata (in";: COLOR giallo&: PRINT " giallo";: COLOR bianco&: PRINT ") congiungente le portate di picco dei vari idrogrammi. Per  determinare l'idrogramma di"
                PRINT "progetto e relativa portata di picco, sar… possibile avvalersi dei suddetti risultati (per esempio tramite Excel), oppure proseguire su questo programma."
                PRINT
                SELECT CASE VisualizzaIeto%%
                    CASE IS = 1
                        PRINT "In tal caso, il programma chieder… 2 input:"
                        PRINT "- una soglia percentuale S, per il calcolo dell'idrogramma di progetto."
                        PRINT "  Per esempio, scrivendo 10%, viene verificato se, sulla spezzata gialla, la portata di picco corrispondente all'ora 1 aumentata del 10%, Š minore  della"
                        PRINT "  portata di picco corrispondente all'ora 2. Se Š minore, l'algoritmo prosegue finch‚ non trova la portata di picco di un'ora "; CHR$(34); "i"; CHR$(34); " che, aumentata del 10%,"
                        PRINT "  risulta maggiore della portata di picco dell'ora "; CHR$(34); "i+1"; CHR$(34); ". Sar… considerato come idrogramma di progetto quello  relativo all'ultima ora la cui  portata di"
                        PRINT "  picco risulta essere superiore alla portata di picco dell'ora precedente aumentata del 10%."
                        PRINT "  Qualora la soglia percentuale  digitata sia troppo bassa per determinare, nel corso  delle iterazioni, un superamento  della  portata di picco dell'ora"
                        PRINT "  successiva, viene computato, come idrogramma di progetto, quello che presenta la massima portata di picco tra i 24 calcolati;"
                        PRINT "- un'ora di picco a scelta, di cui viene calcolata la corrispondente portata di picco e relativo idrogramma."
                    CASE IS = 2
                        PRINT "In tal caso, il programma chieder… 1 input:"
                        PRINT "- un'ora di picco a scelta, di cui viene calcolata la corrispondente portata di picco e relativo idrogramma."
                        PRINT "Come idrogramma di progetto, Š computato quello che presenta la massima portata di picco tra i 24 calcolati."
                END SELECT
                PRINT
                COLOR giallo&: PRINT "  [ESC]: salva; [TAB]: riavvia; [F1]: torna agli input iniziali; []: prosegui.": COLOR bianco&
                LOCATE CSRLIN + 1,
                DO
                    _LIMIT 30
                    KeyPress$ = INKEY$
                LOOP UNTIL KeyPress$ = CHR$(27) OR KeyPress$ = CHR$(9) OR KeyPress$ = CHR$(0) + CHR$(59) OR KeyPress$ = CHR$(0) + CHR$(77)
                SELECT CASE KeyPress$
                    CASE CHR$(27)
                        esc~` = 1
                        IF VisualizzaIeto%% = 2 THEN
                            CALL CalcolaIdrogramma(MassimiIdrogrammi1a24(VisualizzaIeto%%, 24, 1).ore, idrogrammi1a24(VisualizzaIeto%%, 24, 50, 1).ore, MassimiAssolutiIeto(VisualizzaIeto%%).ore,_
                            MassimiAssolutiIeto(VisualizzaIeto%%).portata, ComplessivoIeto1e2(VisualizzaIeto%%).grafico, ComplessivoIeto1e2(VisualizzaIeto%%).composizione)
                            GOSUB DisegnaIdrogramma
                        END IF
                    CASE CHR$(9)
                        riavvio~` = 1
                    CASE CHR$(0) + CHR$(59)
                        menu~` = 1
                    CASE CHR$(0) + CHR$(77)
                        CLS
                        VIEW PRINT 1 TO 4
                        DO
                            TornaAlGrafico~` = 0
                            ERASE IdroPixel1, IdroPixel2, idrogramma1, idrogramma2
                            FOR ieto%% = 1 TO 2
                                _DEST idrogramma1e2(ieto%%).grafico: CLS
                                _DEST idrogramma1e2(ieto%%).composizione: CLS
                            NEXT ieto%%
                            GOSUB VisualizzaComplessivo
                            CALL CalcolaIdrogramma(MassimiIdrogrammi1a24(VisualizzaIeto%%, 24, 1).ore, idrogrammi1a24(VisualizzaIeto%%, 24, 50, 1).ore, MassimiAssolutiIeto(VisualizzaIeto%%).ore,_
                            MassimiAssolutiIeto(VisualizzaIeto%%).portata, ComplessivoIeto1e2(VisualizzaIeto%%).grafico, ComplessivoIeto1e2(VisualizzaIeto%%).composizione)
                            GOSUB DisegnaIdrogramma
                            GOSUB VisualizzaIdrogramma
                            IF TornaAlGrafico~` = 1 THEN _CONTINUE
                            IF esc~` = 1 OR riavvio~` = 1 OR menu~` = 1 THEN EXIT DO
                            GOSUB VisualizzaUnitari
                            IF TornaAlGrafico~` = 1 THEN _CONTINUE
                            IF esc~` = 1 OR riavvio~` = 1 OR menu~` = 1 THEN EXIT DO
                            GOSUB VisualizzaMatrici
                            IF TornaAlGrafico~` = 1 THEN _CONTINUE
                            IF esc~` = 1 OR riavvio~` = 1 OR menu~` = 1 THEN EXIT DO
                        LOOP
                END SELECT
            CASE CHR$(27)
                esc~` = 1
            CASE CHR$(9)
                riavvio~` = 1
            CASE CHR$(0) + CHR$(59)
                menu~` = 1
        END SELECT
        IF riavvio~` = 0 AND menu~` = 0 THEN
            _DEST shermo&
            VIEW PRINT
            CLS
            IF VisualizzaIeto%% <> 0 THEN
                IF interrompi~`(1) = 0 OR interrompi~`(2) = 0 THEN
                    esc~` = 0
                    PRINT
                    COLOR giallo&
                    PRINT "[1]: salva su disco tabulati e immagini (richiede pi— tempo);"
                    PRINT "[2]: salva solo tabulati;"
                    PRINT "[ESC]: esci; [TAB]: riavvia; [F1]: torna agli input iniziali."
                    PRINT
                    COLOR R&: PRINT "Si ricorda che se il programma non si trova sul computer locale, ma in rete, il salvataggio potrebbe richiedere molti minuti."
                    COLOR bianco&
                    PRINT
                    DO
                        _LIMIT 30
                        KeyPress$ = INKEY$
                    LOOP UNTIL KeyPress$ = "1" OR KeyPress$ = "2" OR KeyPress$ = CHR$(27) OR KeyPress$ = CHR$(9) OR KeyPress$ = CHR$(0) + CHR$(59)
                    SELECT CASE KeyPress$
                        CASE "1", "2"
                            MKDIR "RisultatiQB64"
                            CHDIR ".\RisultatiQB64"
                            PRINT "Attendere, salvataggio in corso nella directory:"
                            PRINT CHR$(34); _CWD$; CHR$(34); "."
                            PRINT
                            PRINT "Si ricorda che:"
                            PRINT "- rieseguendo o riavviando il programma [TAB], o tornando  al menu degli input [F1], la  directory "; CHR$(34); "RisultatiQB64"; CHR$(34); " sar…  cancellata, quindi se  s'intende"
                            PRINT "  preservare i risultati, sar… prima necessario o rinominarla o spostarla;"
                            PRINT "- per i file di estensione "; CHR$(34); "CSV"; CHR$(34); ", affinch‚ siano visualizzati correttamente in Excel,";: COLOR R&: PRINT " Š necessario che  nelle impostazioni di Windows il separatore dello"
                            PRINT "  elenco sia la virgola";: COLOR bianco&: PRINT "."
                            SLEEP 3
                            PRINT
                            COLOR giallo&: PRINT "Per terminare il salvataggio cliccare su questa schermata, premere [ESC] e attendere qualche istante."
                            SHELL _CWD$
                            GOSUB Risultati
                            CHDIR "..\"
                            LOCATE CSRLIN - 1,: PRINT STRING$(115, 32)
                            COLOR giallo&
                            LOCATE CSRLIN - 1,: PRINT "Cliccare su questa schermata e [ESC]: esci; [TAB]: riavvia; [F1]: torna agli input iniziali."
                            BEEP
                            DO
                                _LIMIT 30
                                KeyPress$ = INKEY$
                            LOOP UNTIL KeyPress$ = CHR$(27) OR KeyPress$ = CHR$(9) OR KeyPress$ = CHR$(0) + CHR$(59)
                            SELECT CASE KeyPress$
                                CASE CHR$(27)
                                    esc~` = 1
                                CASE CHR$(9)
                                    riavvio~` = 1
                                CASE CHR$(0) + CHR$(59)
                                    menu~` = 1
                            END SELECT
                        CASE CHR$(27)
                            esc~` = 1
                        CASE CHR$(9)
                            riavvio~` = 1
                        CASE CHR$(0) + CHR$(59)
                            menu~` = 1
                    END SELECT
                END IF
            END IF
        END IF
        IF riavvio~` = 1 OR menu~` = 1 THEN GOSUB freeimage
    LOOP UNTIL esc~` = 1 OR riavvio~` = 1
LOOP UNTIL esc~` = 1
freeimage:
IF DESKTOPWIDTH% >= 1280 THEN
    FOR ieto%% = 1 TO 2
        _FREEIMAGE ComplessivoIeto1e2(ieto%%).grafico
        _FREEIMAGE ComplessivoIeto1e2(ieto%%).composizione
        _FREEIMAGE idrogramma1e2(ieto%%).grafico
        _FREEIMAGE idrogramma1e2(ieto%%).composizione
        FOR z%% = 1 TO 24
            _FREEIMAGE MatriciIeto1e2(ieto%%, z%%)
        NEXT z%%
    NEXT ieto%%
    _FREEIMAGE unitari&
    _FREEIMAGE quadro&
    ON ERROR GOTO cancel1: _FREEIMAGE OriginaleGrafico&: ON ERROR GOTO 0
END IF
IF riavvio~` = 1 OR menu~` = 1 THEN RETURN
SYSTEM



RE: Paranoia - bplus - 08-13-2022

If you have sections of code doing the exact same thing, it is more efficient to put that code in a Sub or Function and call those instead of repeating code blocks, even a GOSUB is better than repeating code blocks, from "The Art of Coding". GOSUBs are a little less desirable because they aren't completely independent of the main code they are called from but sometimes they are better for convenience.


RE: Paranoia - SMcNeill - 08-13-2022

Generally speaking, as long as you're not dealing with looping and such, it doesn't matter. For example:

SELECT CASE foo
CASE 1
'let's do lots of stuff
'and some optional stuff that only happens when foo is one
CASE 2
'let's do lots of stuff like above
'and some optional stuff that only happens when foo is two
END SELECT

Verses this:

'Let's do lots of stuff exactly as above
SELECT CASE foo
CASE 1
'we do the optional stuff for case 1
CASE 2
'we do the optional stuff for case 2
END SELECT

In both these situations, we're not going to see any real difference in program speed or performance. We still do the bunch of stuff no matter which branch we take with the SELECT CASE, so there's no savings in performance to come along anywhere. The second method produces less code and is generally easier to keep up with and debug, but performance wise, it's not going to be very different than the first method.

Now, where you *do* see changes in performance is when loops are involved.

FOR I = 1 to 1000
SELECT CASE Foo
CASE 1 'do some stuff if foo is 1
CASE 2 'do some stuff if foo is 2
END SELECT
NEXT

Verses the following:

SELECT CASE foo
CASE 1
FOR I = 1 TO !000
'Do some stuff for when foo is 1
NEXT
CASE 2
FOR I = 1 TO !000
'Do some stuff for when foo is 2
NEXT
END SELECT

In this situation, the second set of code will perform better than the first set of code, even though it's more code to it!! WHY?? Because it's only making that SELECT CASE decision once, whereas the first set of code has to make that decision 1000 different times. Structure here can play a huge part on performance, and is something to keep in mind if your code is running noticeably slower than desired.


RE: Paranoia - Kernelpanic - 08-13-2022

Quote:Now, where you *do* see changes in performance is when loops are involved.

FOR I = 1 to 1000
SELECT CASE Foo
CASE 1 'do some stuff if foo is 1
CASE 2 'do some stuff if foo is 2
END SELECT
NEXT

Verses the following:

SELECT CASE foo
CASE 1
FOR I = 1 TO !000
'Do some stuff for when foo is 1
NEXT
CASE 2
FOR I = 1 TO !000
'Do some stuff for when foo is 2
NEXT
END SELECT

In this situation, the second set of code will perform better than the first set of code, even though it's more code to it!! WHY?? Because it's only making that SELECT CASE decision once, whereas the first set of code has to make that decision 1000 different times. Structure here can play a huge part on performance, and is something to keep in mind if your code is running noticeably slower than desired.


That's correct! For a farmer you know a hell of a lot about programming.  Rolleyes

Have you ever thought of a book? Maybe with the other cracks here? - But not the umpteenth introduction and such, but just such special tips.


RE: Paranoia - bartok - 08-13-2022

(08-13-2022, 04:51 PM)bplus Wrote: If you have sections of code doing the exact same thing, it is more efficient to put that code in a Sub or Function and call those instead of repeating code blocks, even a GOSUB is better than repeating code blocks, from "The Art of Coding". GOSUBs are a little less desirable because they aren't completely independent of the main code they are called from but sometimes they are better for convenience.

In all the preview examples, not one single block is repeated: I tried to acheve this result from the very beginning. So, in all the cases, the program lasts about 2500 lines, line plus, line minus. It is not possible, I think, to reduce the lenght or the computational burden. Generally, I use GOSUBs to make something that virtually could stay in the main code and that is virtually executed once, as a kind of "part" of the code detached. For example, if I have a section of 300 lines of calculations, I put tham in a GOSUB, instead to have these 300 lines in the main code. On the contrary, I use subroutines to do repeated things, as to to create tables and graphics. In a case, I used a subroutine to execute a kind of program in the program.

The question is purely formal.
Is it better:

Example 1:
DO
KeyPress$ = INKEY$
LOOP UNTIL KeyPress$ = "1" OR KeyPress$ = CHR$(27) OR KeyPress$ = CHR$(9)
SELECT CASE
CASE "1"
PRINT "HELLO"
CASE CHR$(27)
esc~` = 1
CASE CHR$(9)
riavvio~` = 1
END SELECT

or:

Example 2:
DO
KeyPress$ = INKEY$
LOOP UNTIL KeyPress$ = "1" OR KeyPress$ = CHR$(27) OR KeyPress$ = CHR$(9)
CASE CHR$(27)
esc~` = 1
CASE CHR$(9)
riavvio~` = 1
END SELECT

PRINT "HELLO"

(08-13-2022, 04:58 PM)SMcNeill Wrote: Generally speaking, as long as you're not dealing with looping and such, it doesn't matter.  For example:

SELECT CASE foo
  CASE 1
      'let's do lots of stuff
      'and some optional stuff that only happens when foo is one
    CASE 2
      'let's do lots of stuff like above
      'and some optional stuff that only happens when foo is two
END SELECT

Verses this:

'Let's do lots of stuff exactly as above
SELECT CASE foo
  CASE 1
      'we do the optional stuff for case 1
    CASE 2
      'we do the optional stuff for case 2
END SELECT

In both these situations, we're not going to see any real difference in program speed or performance.  We still do the bunch of stuff no matter which branch we take with the SELECT CASE, so there's no savings in performance to come along anywhere.  The second method produces less code and is generally easier to keep up with and debug, but performance wise, it's not going to be very different than the first method.

Now, where you *do* see changes in performance is when loops are involved.

FOR I = 1 to 1000
    SELECT CASE Foo
        CASE 1 'do some stuff if foo is 1
        CASE 2 'do some stuff if foo is 2
    END SELECT
NEXT

Verses the following:

SELECT CASE foo
    CASE 1
        FOR I = 1 TO !000
          'Do some stuff for when foo is 1
        NEXT
    CASE 2
        FOR I = 1 TO !000
          'Do some stuff for when foo is 2
        NEXT
END SELECT

In this situation, the second set of code will perform better than the first set of code, even though it's more code to it!!  WHY??  Because it's only making that SELECT CASE decision once, whereas the first set of code has to make that decision 1000 different times.  Structure here can play a huge part on performance, and is something to keep in mind if your code is running noticeably slower than desired.

I undestand what you say, but it is not exactly about on what I tried to explain. Let's think about my examples above in this message. Your "let's do lots of stuff", is my PRINT "HELLO", but my PRINT "HELLO" is after the DO and after (or inside) the SELECT CASE. your "let's do lots of stuff" is before the SELECT CASE and there is not DO. This changes completely the situation.

In both the Example 1 and 2, the program waits the pression of "1", "ESC" or "TAB". But in the Example 2, if "1" is pressed, the program will simply jump the SELECT CASE and it goes ahead, as in a flow, towards PRINT "HELLO". In the Example 1, if "1" is pressed, it is executed the specific CASE "1" of the SELECT CASE. We can easily think that "let's do lots of stuff" or PRINT "HELLO", as an huge part of the code where the same scheme is repeated. So, if we follow the concept of "Example 2", at the "n" interation, we actually have a kind of flow, where the SELECT CASEs are jumped while the program goes ahead, but if we follow the concept of "Example 1", at the "n" interation we are in a CASE of an nSELECT CASE, inside a CASE of a n-1SELECT CASE, inside a CASE of a n-2SELECT CASE, ...

But what is it the better between the 2? I think that at a computational level they are the same, if I am not wrong. At a logical level "Example 1" it seems to me more formally accurate, but I don't reallyt know. Both the "solutions" do the exactly the same thing, with likely the same computational effort, but they are completely different at a logical level.


RE: Paranoia - Petr - 08-13-2022

Basically, it doesn't matter as long as you know the flow of the program. Personally, I find it 1000x better to search for possible errors in programs with SUB. And that's what it's all about. To be blunt, I'm not going to deal with anything that has a lot of GOTOs and the author asks to find a bug. No. Life is short and it comes at a high price. That's why even troubleshooting must be short. And programs with GOTO do not meet this condition.


RE: Paranoia - bartok - 08-14-2022

(08-13-2022, 09:16 PM)Petr Wrote: Basically, it doesn't matter as long as you know the flow of the program. Personally, I find it 1000x better to search for possible errors in programs with SUB. And that's what it's all about. To be blunt, I'm not going to deal with anything that has a lot of GOTOs and the author asks to find a bug. No. Life is short and it comes at a high price. That's why even troubleshooting must be short. And programs with GOTO do not meet this condition.

Thanks. But I don't use GOTO, except than in ON ERROR, but in this case is compulsory and they are a few commands, and I don't have problmes with SUBs. Generally, the program is navigable with command DO and _CONTINUE, depending if some variables are equal to 0 or 1.


RE: Paranoia - TempodiBasic - 08-15-2022

Hi Bartok
I have no great theorical knowledge about "the art of coding"... so I can talk about my ideas and thought on your 2 first examples in the while that you can explaing better to me what it means "beautyfy" a code:
I've used to code as Bplus said... large indipendent block of code that do something with no correlation with the rest of code can be closed in a GOSUB (if it uses global main variables) or in a SUB/FUNCTION (passing global main variables needed by parameters or SHARED) so at the place of [a lot of code 1] you can write SubCode1 and at the place of [a lot of code 2] you can write SubCode2.
What is the difference? You read one row of code at the place of a lot of lines of code... so you can have a easier aspect of the code that gives a more editable and debuggable code.

Talking about the two specific examples that you have posted (the first and the second ones) in the first you have a nested SELECT CASE so the logical flow is clear!
In the second example you have 2 equential SELECT CASE... the code does the same thing until when one of the conditions in the first SELECT CASE is activated AND the flow doesn't come back there after the calling.
to be clearer in the first SELECT CASE of the second example posted, if a condition matches (esc, riavvio, menu) then after activated the linked code the flow mustn't come back there in that SELECT CASE...

PS:
My answer is in english just to be accesible to all QB64 friends of this forum.


RE: Paranoia - bartok - 08-16-2022

(08-15-2022, 10:04 PM)TempodiBasic Wrote: Hi Bartok
I have no great theorical knowledge about "the art of coding"... so I can talk about my ideas and thought on your 2 first examples in the while that you can explaing better to me what it means "beautyfy" a code:
I've used to code as Bplus said... large indipendent block of code that do something with no correlation with the rest of code can be closed in a GOSUB (if it uses global main variables) or in a SUB/FUNCTION (passing global main variables needed by parameters or SHARED) so at the place of [a lot of code 1] you can write  SubCode1 and at the place of [a lot of code 2] you can write SubCode2.
What is the difference? You read one row of code at the place of a lot of lines of code... so you can have a easier aspect of the code that gives a more editable and debuggable code.

Thank you for the answer.

What you have said replies to the "Second paranoia" of the first message. The longer version of the main code was already structurated like that and [a lot of code 1&2] already refered to "a lot" of SubCode, through the call of GOSUBs. In fact, the longer version of the "main code" lasts almost 400 lines, while the code is about 2500. So, in the main code, a lot of GOSUBs are called, there are some discursive parts and in GOSUBs, SUBs are called many many times.
Following what you say, it is possibile to maximize the concept (that was my dilemma), in order to have, in the "main code", absolutely nothing more than what is strictly necessary, as to say merging many GOSUBs and texts in more generic GOSUBs: in that way, the shorter version of the main code decreases from 400 to 200 lines, while the length of the code remains stable. I thought a lot about that and I reached a kind of conclusion: this extreme synthesis in the main code makes its own structure clearer, this is true, but maybe it doesn't make the code in general much more editable and debuggable, beacause the maximization of the synthesis in the "main code" leads to an explosion of nested GOSUBs. So, I reached a kind of rule: to have GOSUBs that, in general, are called directly from the main code, to try to avoid nested GOSUBs, and to have a nested GOSUB ony for the necessities of the GOSUB of the upper level, not for those of the main code. Futhermore, I noticed that the extreme syntesis in the main code leads some to other issues, that are difficult to explain, but that consit to have, in certain cases, some nested GOSUBs, inside a main GOSUB, that aren't logically releated, without it is possibile to avoid that. So, I have opted, on this issue, for the original version of the main code.

(08-15-2022, 10:04 PM)TempodiBasic Wrote: Talking about the two specific examples that you have posted (the first and the second ones) in the first you have a nested SELECT CASE so the logical flow is clear!
In the second example you have 2 equential SELECT CASE... the code does the same thing until when one of the conditions in the first SELECT CASE is activated AND the flow doesn't come back there after the calling.
to be clearer  in the first SELECT CASE of the second example posted, if a condition matches (esc, riavvio, menu) then after activated the linked code the flow mustn't come back there in that SELECT CASE...

When I posted the first message, I didn't have thought about your objection, so I have omitted some part of the code. The 2 situation (with the 2 separated SELECT CASE, and with the 2 nested SELECT CASE), make actually the same things: as you can see below, the possibility of the repetition of the first SELECT CASE was been solved with a nested DO-LOOP:

Code: (Select All)
DO
    '[A LOT OF OTHER CODE]
    DO
        DO
            DO
                _LIMIT 30
                KeyPress$ = INKEY$
            LOOP UNTIL KeyPress$ = "1" OR KeyPress$ = "2" OR KeyPress$ = CHR$(27) OR KeyPress$ = CHR$(9) OR KeyPress$ = CHR$(0) + CHR$(59)
            SELECT CASE KeyPress$
                CASE CHR$(27)
                    esc~` = 1
                CASE CHR$(9)
                    riavvio~` = 1
                CASE CHR$(0) + CHR$(59)
                    menu~` = 1
            END SELECT

            IF esc~` = 1 OR riavvio~` = 1 OR menu~` = 1 THEN EXIT DO

            '[A LOT OF CODE 1] <---------------------------------------------

            DO
                _LIMIT 30
                KeyPress$ = INKEY$
            LOOP UNTIL KeyPress$ = CHR$(27) OR KeyPress$ = CHR$(9) OR KeyPress$ = CHR$(0) + CHR$(59) OR KeyPress$ = CHR$(0) + CHR$(77)
            SELECT CASE KeyPress$
                CASE CHR$(27)
                    esc~` = 1
                CASE CHR$(9)
                    riavvio~` = 1
                CASE CHR$(0) + CHR$(59)
                    menu~` = 1
            END SELECT

            IF esc~` = 1 OR riavvio~` = 1 OR menu~` = 1 THEN EXIT DO

            '[A LOT OF CODE 2] <---------------------------------------------

        LOOP

    LOOP UNTIL esc~` = 1 OR riavvio~` = 1 '<--------------------------------------------- if menu~` = 1, then the first SELECT CASE is repeated.
LOOP UNTIL esc~` = 1
END

With the nested SELECT CASE, conversely, I made like this:
Code: (Select All)
DO
    '[A LOT OF OTHER CODE]
    DO
        DO
            _LIMIT 30
            KeyPress$ = INKEY$
        LOOP UNTIL KeyPress$ = "1" OR KeyPress$ = "2" OR KeyPress$ = CHR$(27) OR KeyPress$ = CHR$(9) OR KeyPress$ = CHR$(0) + CHR$(59)
        SELECT CASE KeyPress$
            CASE "1", "2"
                '[A LOT OF CODE 1] <---------------------------------------------

                IF esc~` = 1 OR riavvio~` = 1 OR menu~` = 1 THEN EXIT SELECT

                DO
                    _LIMIT 30
                    KeyPress$ = INKEY$
                LOOP UNTIL KeyPress$ = CHR$(27) OR KeyPress$ = CHR$(9) OR KeyPress$ = CHR$(0) + CHR$(59) OR KeyPress$ = CHR$(0) + CHR$(77)
                SELECT CASE KeyPress$
                    CASE CHR$(27)
                        esc~` = 1
                    CASE CHR$(9)
                        riavvio~` = 1
                    CASE CHR$(0) + CHR$(59)
                        menu~` = 1
                    CASE CHR$(0) + CHR$(77)
                        '[A LOT OF CODE 2] <---------------------------------------------
                END SELECT
            CASE CHR$(27)
                esc~` = 1
            CASE CHR$(9)
                riavvio~` = 1
            CASE CHR$(0) + CHR$(59)
                menu~` = 1
        END SELECT
    LOOP UNTIL esc~` = 1 OR riavvio~` = 1
LOOP UNTIL esc~` = 1
END

I agree that the soluton with the nested SELECT CASE, it is better: there is one less DO - LOOP and maybe it is clearer. So, in this case, I opted for the modified solution.