Programmare con coscienza e non a caso basandosi sulla fortuna

di il
14 risposte

Programmare con coscienza e non a caso basandosi sulla fortuna

Ma voi programmatori esperti quando dovete scrivere un codice scrivete prima un algoritmo in italiano da tradurre successivamente?
Perchè io da poco ragiono così e sto vedendo che riesco a risolvere gli esercizi quasi subito.
Praticamente ragiono in questi termini.
Analizzo tutte le situazioni possibili che possono verificarsi, quindi ad esempio scrivo "se A e se B e se C e se......se Z, allora cout<< (o altre cose)".
Questi "se" contemporanei, non potendo essere gestiti tutti insieme, li trasformo in una sequenza di più istruzioni. Quindi avrò "se A, ++j, se B, ++j ecc......"insomma alla fine introduco un ciclo while. In passato invece ragionavo direttamente in termini di codice sorgente e non riuscivo a trovare la strada anche per le cose più banali. Scusate se mi sono espresso da cani.

14 Risposte

  • Re: Programmare con coscienza e non a caso basandosi sulla fortuna

    "Con coscienza"? Ma che vuoi dire?

    Quando hai una certa esperienza (non è facile dire quanto ... ma qualche decennio ...) si sa quello che si vuole scrivere e si sa quale soluzione adottare ...
  • Re: Programmare con coscienza e non a caso basandosi sulla fortuna

    ...
  • Re: Programmare con coscienza e non a caso basandosi sulla fortuna

    selfmademan ha scritto:


    Ma voi programmatori esperti quando dovete scrivere un codice scrivete prima un algoritmo in italiano da tradurre successivamente?
    Perchè io da poco ragiono così e sto vedendo che riesco a risolvere gli esercizi quasi subito.
    Praticamente ragiono in questi termini.
    Analizzo tutte le situazioni possibili che possono verificarsi, quindi ad esempio scrivo "se A e se B e se C e se......se Z, allora cout<< (o altre cose)".
    Questi "se" contemporanei, non potendo essere gestiti tutti insieme, li trasformo in una sequenza di più istruzioni. Quindi avrò "se A, ++j, se B, ++j ecc......"insomma alla fine introduco un ciclo while. In passato invece ragionavo direttamente in termini di codice sorgente e non riuscivo a trovare la strada anche per le cose più banali. Scusate se mi sono espresso da cani.
    Anche se scritto da cani, immagino che tu sia sostenendo che sia meglio prima pensare, e poi agire.
    (gli ingeggneri direbbero prima progettare).
    Hai scoperto l'acqua fredda.

    Bisogna però dire che l'applicazione pratica dipende essenzialmente dal lavoro che fai, e dal livello di esperienza.

    Quando un chirurgo ha fatto che so 5.000 interventi, e va a operare, non è che si compri il manuale di anatomia per scoprire dove si trova la spalla, o si metta prima a fare qualche schemino preventivo.
    Questo è il livello studente-principiante-junior.

    Certamente potrà capitare, nel caso di interventi supercomplessi o innovativi, ma nella stragrande maggioranza dei casi si procede "con un filo di gas", perchè nei 5.000 precedenti interventi si sono già commessi 5.000 errori, che coprono la quasi totalità delle casistiche.
  • Re: Programmare con coscienza e non a caso basandosi sulla fortuna

    Il cervello è, tra le altre cose, una potente memoria associativa (o meglio, un agglomerato di più memorie associative). Ovvero riceve un imput, eventualmente impreciso o distorto, e cerca di tirare fuori la risposta più consona in base a ciò che ha imparato con l'esperienza.
    Ora tu stai ancora addestrando il cervello ad associare certi problemi alle più opportune soluzioni. Man mano che avrai acquisito esperienza, ti capiterà sempre più spesso che di fronte a un problema il cervello ti darà automaticamente una soluzione, più o meno precisa (e che potrebbe eventualmente tornare in input per essere via via affinata).
  • Re: Programmare con coscienza e non a caso basandosi sulla fortuna

    Faccio un esempio pratico. Ho scritto del codice in C++ che memorizza nei vettori "lunghezze" e "partenze" le lunghezze e le posizioni di partenza di tutte le possibili sequenze crescenti di elementi consecutivi presenti in un vettore.
    Mi sono approcciato al problema in due modi diversi e ho prodotto 2 codici diversi che danno gli stessi risultati. Qual è meglio e che strada devo seguire per gli esercizi futuri?

    1)
    In questo caso ragiono analizzando una coppia, poi passo alla successiva e così via.
    
    #include <iostream>
    #include<cstdlib>
    #define nmax 100
    using namespace std;
    void leggi_vettore(int dim,int V[])
    {
        for(int i=0;i<dim;i++)
        {
            cout<<"\nInserisci l'elemento "<<i+1<<" ";
            cin>>V[i];
        }
    }
    void stampa_vettore(int dim,int V[])
    {
        for(int i=0;i<dim;i++)
        {
            cout<<"  "<<V[i];
        }
    }
    int main()
    {
        int V[nmax];
        cout<<"Scegli dimensione V1 ";
        int dim;
        cin>>dim;
        leggi_vettore(dim,V);
        cout<<"\nV = ";
        stampa_vettore(dim,V);
        int progressione=-1;
        int partenze[nmax];
        int par;
        int lunghezze[nmax];
        int lung;
        for(int k=0;k<dim-1;k++)    
        {
            par=k+1;
            lung=1;
            for(int j=k;j<dim-1;j++)
            {
                if(V[j]<V[j+1])
                {
                    ++progressione;
                    partenze[progressione]=par;
                    lunghezze[progressione]=++lung;
                }
                else
                {
                    par=j+2;
                    lung=1;
                }
            }    
        }
        cout<<"\n";
        stampa_vettore(progressione+1,partenze);
        cout<<"\n";
        stampa_vettore(progressione+1,lunghezze);
    }
    
    2)
    In questo caso ragiono non passo passo ma analizzando a priori tutte le possibili situazioni che possono capitare. Cioè dico al calcolatore "se il precedente è < del successivo per tutti gli elementi, memorizza una sequenza lunga dim e che parte da 1, se il precedente è < del successivo per tutti gli elementi tranne l'ultimo, memorizza una sequenza lunga dim-1 e che parte da 1..........se solo il primo è < del secondo, memorizza una sequenza che parte da 1 lunga 2 e cosi via.
    
    #include <iostream>
    #include<cstdlib>
    #define nmax 100
    using namespace std;
    void leggi_vettore(int dim,int V[])
    {
        for(int i=0;i<dim;i++)
        {
            cout<<"\nInserisci l'elemento "<<i+1<<" ";
            cin>>V[i];
        }
    }
    void stampa_vettore(int dim,int V[])
    {
        for(int i=0;i<dim;i++)
        {
            cout<<"  "<<V[i];
        }
    }
    int main()
    {
        int V[nmax];
        cout<<"Scegli dimensione V ";
        int dim;
        cin>>dim;
        leggi_vettore(dim,V);
        cout<<"\nV = ";
        stampa_vettore(dim,V);
       int j;
        int lunghezze[nmax];
        int partenze[nmax];
        int progressione=-1;
        for(int i=0;i<dim-1;i++)
        {
           for(int k=dim-1;k>i;k--)
           {
               j=i;
               while(j<k)
               {
                   if(V[j]<V[j+1])
                   {
                       ++j;
                   }
                   else
                       break;
               }
               if(j==k)
               {
                   ++progressione;
                   partenze[progressione]=i+1; lunghezze[progressione]=k-i+1;
               }
           }
        }
    }
    
    
    Ho l'impressione che il secondo sia poco efficiente e faccia fare al calcolatore passaggi inutili.
  • Re: Programmare con coscienza e non a caso basandosi sulla fortuna

    Ho l'impressione che sei proprio all'inizio (tra l'altro di C++ non c'è praticamente nulla, è tutto C).
    E' scritto proprio male, diciamo a livello suppongo didattico.
    Riguardo alla complessità la domanda è: stai procedendo autodidatticamente, o segui un qualche genere di corso?
  • Re: Programmare con coscienza e non a caso basandosi sulla fortuna

    Devo fare l'esame per ingegneria meccanica ma ragiono troppo a intuito e non mi sento padrone della situazione.
    Non capisco se gli esercizi sui vettori vanno risolti ragionando componente per componente a partire dalla prima o scrivendo istruzioni per tutti gli scenari teoricamente possibili e non ho capito se esiste un collegamento tra i due approcci. Insomma, credo mi manchino nozioni di informatica teorica.

    3)
    altro algoritmo: metto solo il cuore del programma
    
    for(int k=0;k<dim-1;k++)
        {
            j=k;
            while(V[j]<V[j+1])
            {
                ++j;
            }
            while(j>k+2)
            {
               ++progressione;
               partenze[progressione]=k+1;
               lunghezze[progressione]=j-k-1;
               j--;
            }
        }
    
    Quindi fino ad ora ho scritto 3 programmi funzionanti che fanno la stessa cosa ragionando in 3 modi diversi e non riesco a capire quale strada bisogna seguire.
  • Re: Programmare con coscienza e non a caso basandosi sulla fortuna

    Bhè dai, sei "giustificato" allora.
    Per la domanda conclusiva, la risposta è duplice
    1) funzionano sempre, in tutti i casi, i 3 metodi?
    2) quale è più efficiente? come fai? in realtà il programma è banale, potresti facilmente analizzare staticamente il codice. come? conta quante istruzioni vengono eseguite, e magari di quale tipo, durante l'esecuzione.
    se dato un problema di dimensione X il primo metodo richiede 10 passi, il secondo 20, e il terzo 7, allora il terzo è migliore (* in realtà qui ci andrebbe uno spiegone sui casi medi, pessimi, il tradeoff con la memoria eccetera. è una introduzione per ingegneri meccanici)

    un livello di maggior accuratezza puoi averlo se suddividi le istruzioni per tipologie
    - assegnamento
    - incremento
    - test
    perchè questi hanno un costo (lentezza) diverso.
    Un programma che fa 10 assegnamenti e 3 incrementi, è più o meno veloce di un programma che fa 3 assegnamenti e 10 incrementi?
    In generale la seconda, ma è un ulteriore livello di analisi.

    Poi, procedendo, arriverai (...arriveresti...) a discutere quale tipologia di istruzioni in alto livello si possono mappare meglio in basso livello, magari su una certa architettura.
    "costa" di più aggiornare sequenzialmente un vettore (cioè l'elemento 1, 2, 3... n) oppure in maniera "mischiata" (es. 1, n ,2, n-1, 3, n-2...) ?
    in generale il primo, per ragioni di caricamento nella cache.

    Poi arriverai (... arriveresti...) a chiederti se puoi segmentare le strutture dati a blocchi di 4KB, supponendo che questa sia la dimensione della pagina della memoria virtuale del sistema che stai usando. Due strutture dati da 3KB, probabilmente, saranno meglio di una da 6K.

    ...
    Fatto il pippone, torna coi piedi per terra: simula l'esecuzione nei 3 casi e conta le istruzioni.
    E' già un inizio.
    Poi aumenta la dimensione, esempio raddoppiala, e guarda come crescono le istruzioni.
    linearmente con la dimensione del problema? questo è bene.
    più che linearmente? questo è bene.
    come il quadrato della dimensione? questo è male
    come il cubo della dimensione? questo è malissimo
    ...
  • Re: Programmare con coscienza e non a caso basandosi sulla fortuna

    In sostanza detto X la dimensione del problema devi calcolare (X), f2(X), (X), rispettivamente il numero di operazioni operate dall'algoritmo 1 in funzione di X e così via.
    La soluzione migliore è ottenere l'espressione esatta, ad esempio (X)=3X+45 e f2(X)=X^2+4X+6.
    A quel punto (ammesso di considerare uguali tutte le operazioni, cosa che non è, ma studi pur sempre ingegneria...) ti chiederai...
    quando è < di f2 < ? Quando? Sempre ? Per una qualche X?

    Allora concluderai, ad esempio, "fino alla dimensione X=10 conviene usare l'algoritmo 1, per X>10 conviene l'algoritmo 3, o magari conviene sempre l'algoritmo 2 in tutti i casi"
  • Re: Programmare con coscienza e non a caso basandosi sulla fortuna

    Non capirò mai perché nelle facoltà non informatiche va tanto di moda il C++ (o meglio, il C con l'aggiunta di cin e cout e al massimo classi semplici semplici).
    Per le simulazioni da quel che ne so solitamente si usa matlab, python o al più fortran (vedi ing. aerospaziale).
  • Re: Programmare con coscienza e non a caso basandosi sulla fortuna

    Fortran? Aaaarrrgg
  • Re: Programmare con coscienza e non a caso basandosi sulla fortuna

    +m2+ ha scritto:


    Fortran? Aaaarrrgg
    Già. Fortunatamente, di solito si limitano a modificare qualche parametro in programmi già scritti. Sono simulazioni create quando fortran andava ancora di moda e che funzionano bene per cui nessuno si è mai preso la briga di tradurle in altri linguaggi.
  • Re: Programmare con coscienza e non a caso basandosi sulla fortuna

    Beh!!! Da me al dipartimento di Fisica si sviluppa in C++, ma abbiamo iniziato con rudimentali istruzioni in C al primo anno, mentre al secondo anno il Ns. professore di metodi numerici, nonostante ci faceva lavorare in C++ capitava spesso che aggiungeva di suo lo sviluppo di sorgenti in Fortran, a detta sua per ricordare i tempi passati in cui prima che lui si laureasse, studiava e sviluppava tutto in Fortran...

    Ma ad essere sincero, già dal primo anno il Ns. professore di informatica, più volte ripeteva che potevamo sviluppare in qualsiasi linguaggio desideravamo se già eravamo a conoscenza di un qualche linguaggio che fosse diverso dal C++...

    ... quindi questa costrizione nel dover utilizzare esclusivamente il C++ nei dipartimenti che non siano quelli di informatica, almeno da me non risulta... certo è che sicuramente si lavara per la maggiore in C++, ma da parte mia è un vantaggio notevole, anche perchè per gli altri miei colleghi aver imparato i rudimenti di un linguaggio come il C++ non fà male di certo
  • Re: Programmare con coscienza e non a caso basandosi sulla fortuna

    ramcrack ha scritto:


    Beh!!! Da me al dipartimento di Fisica si sviluppa in C++, ma abbiamo iniziato con rudimentali istruzioni in C al primo anno, mentre al secondo anno il Ns. professore di metodi numerici, nonostante ci faceva lavorare in C++ capitava spesso che aggiungeva di suo lo sviluppo di sorgenti in Fortran, a detta sua per ricordare i tempi passati in cui prima che lui si laureasse, studiava e sviluppava tutto in Fortran...

    Ma ad essere sincero, già dal primo anno il Ns. professore di informatica, più volte ripeteva che potevamo sviluppare in qualsiasi linguaggio desideravamo se già eravamo a conoscenza di un qualche linguaggio che fosse diverso dal C++...

    ... quindi questa costrizione nel dover utilizzare esclusivamente il C++ nei dipartimenti che non siano quelli di informatica, almeno da me non risulta... certo è che sicuramente si lavara per la maggiore in C++, ma da parte mia è un vantaggio notevole, anche perchè per gli altri miei colleghi aver imparato i rudimenti di un linguaggio come il C++ non fà male di certo
    Non ho detto che si usa solo il C++, ma che come dici tu si usa principalmente il C++, il che è assurdo. Esistono linguaggi molto più semplici e che tra l'altro dispongono di una marea di librerie per applicazioni scientifiche, tra cui appunto matlab e python.
    Anche mia sorella studia fisica e ha fatto un corso e mezzo di C++, ma tutti i programmini che ha scritto si sarebbero potuti implementare con una decina di righe di python.
Devi accedere o registrarti per scrivere nel forum
14 risposte