JonixLUG Forum

Programmazione => Java => Topic started by: Gas75 on January 14, 2017, 11:03:15 PM

Title: Creare una sorta di "goto" uscendo da un if-else
Post by: Gas75 on January 14, 2017, 11:03:15 PM
Salve,
sto sviluppando un progettino/programmino matematico in Java, piuttosto essenziale e che già funziona tranne quando viene immesso un valore matematicamente non accettabile. :-\ Mi spiego meglio. :)

Tramite la classe Scanner ricevo in input tre valori di tipo int, r, i e g.
Ho bisogno di controllare che g sia un valore strettamente positivo prima di eseguire tutte le operazioni che portano all'output. Chiaramente potrei risolvere chiedendo da subito g e poi, se positiva chiedere anche r e i:
Code: You are not allowed to view links. Register or Login
if (g > 0) {
System.out.print("Immetti r: ");
int r = input.nextInt();
System.out.print("Immetti i: ");
int i = input.nextInt();
// tutto il resto del codice
} else {
System.out.print("Valore di g non valido!");
}
Purtroppo sono vincolato, per la natura stessa di come viene generalmente impostato il problema matematico, a richiedere i dati in quell'ordine, per cui il controllo dev'essere fatto dopo l'immissione dell'ultimo valore che è quello da controllare.
Un "goto" tipico del Basic sarebbe l'ideale ma in Java, mi pare, non esiste una classe del genere.
Qualche idea a riguardo?
Title: Re:Creare una sorta di "goto" uscendo da un if-else
Post by: davenull on January 15, 2017, 01:35:52 AM
ho eliminato la dicitura "java" dal titolo del tuo topic creando immediatamente la sezione adeguata. purtroppo non conosco il java e non posso aiutarti, lo iniziai a studiare anni fa quando era ancora della sun, poi è passata ad oracle (non vedo di buon occhio la oracle) e l'ho abbandonato come linguaggio. segnalo la tua richiesta di aiuto a tetsuya che conosce molto bene il java, sia per android che per x86!!! :)
Title: Re:Creare una sorta di "goto" uscendo da un if-else
Post by: devilicecream on January 15, 2017, 02:33:10 AM
Secondo il mitico Dijkstra, il goto è un comando che non bisognerebbe mai utilizzare, perchè porta a diversi punti di uscita negli algoritmi e genera facilmente "spaghetti code".
Gli amici Bohm e Jacopini hanno inoltre dimostrato un teorema secondo cui qualunque programma scritto utilizzando il goto è riscrivibile senza di esso.
Nel tuo caso è abbastanza semplice:

Code: You are not allowed to view links. Register or Login
int isGValid = 0;
while (!isGValid) {
    System.out.print("Immetti r: ");
    int r = input.nextInt();
    System.out.print("Immetti i: ");
    int i = input.nextInt();
    System.out.print("Immetti g: ");
    int g = input.nextInt();
    if (g > 0) {
        isGValid = 1;
        // Tutto il resto del codice
    } else {
        System.out.print("Valore di g non valido!");
    }
}

Title: Re:Creare una sorta di "goto" uscendo da un if-else
Post by: davenull on January 15, 2017, 05:25:29 AM
nel mio caso creo tanti piccoli sottoprogrammi che fanno cose diverse, e si richiamano tra loro. in questo modo evito il goto ed il cosiddetto spaghetti code, infatti il mio codice è leggibilissimo e stracommentato!!! :D
i commenti sono fondamentali, specialmente se crei un progetto, lo abbandoni e lo riprendi dopo anni. non ti ricordi più cosa ti frullava nella testa quando hai creato il progetto, e soprattutto non è facilmente leggibile e modificabile nel caso in cui lo devi passare ad altri!!! giusto walter???
io sono del parere che puoi scrivere il miglior programma al mondo, ma se non è ben commentato è da cestinare!!!
Title: Re:Creare una sorta di "goto" uscendo da un if-else
Post by: Gas75 on January 15, 2017, 12:38:39 PM
You are not allowed to view links. Register or Login
Secondo il mitico Dijkstra, il goto è un comando che non bisognerebbe mai utilizzare, perchè porta a diversi punti di uscita negli algoritmi e genera facilmente "spaghetti code".
Gli amici Bohm e Jacopini hanno inoltre dimostrato un teorema secondo cui qualunque programma scritto utilizzando il goto è riscrivibile senza di esso.
Nel tuo caso è abbastanza semplice:

Code: You are not allowed to view links. Register or Login
int isGValid = 0;
while (!isGValid) {
    System.out.print("Immetti r: ");
    int r = input.nextInt();
    System.out.print("Immetti i: ");
    int i = input.nextInt();
    System.out.print("Immetti g: ");
    int g = input.nextInt();
    if (g > 0) {
        isGValid = 1;
        // Tutto il resto del codice
    } else {
        System.out.print("Valore di g non valido!");
    }
}
Grazie, funzionicchia ;D ma va usato un boolean al posto di un int come "valore di controllo" isGValid...
Non va bene perché mi chiede daccapo anche i primi due valori mentre a me serve che torni soltanto su g. Per questo cercavo un "goto", che sinceramente a me non ha mai rappresentato problemi, tutt'ora lo sfrutto per dei programmini sulla mia calcolatrice. Forse perché sono programmi semplici, ma mi riesce più facile controllare dei "salti" di codice che scrivere un programma "saltando" da un .java all'altro!
Title: Re:Creare una sorta di "goto" uscendo da un if-else
Post by: lynx on January 15, 2017, 01:54:23 PM
quoto devilicecream per il goto
Perché non puoi usare booleani? Per via della calcolatrice?
Se no, fai come ha scritto davenull.
Title: Re:Creare una sorta di "goto" uscendo da un if-else
Post by: Gas75 on January 15, 2017, 02:59:56 PM
You are not allowed to view links. Register or Login
Perché non puoi usare booleani? Per via della calcolatrice?
No, il contrario: non posso fare !dato, se dato è un int, funziona soltanto coi booleani.
Title: Re:Creare una sorta di "goto" uscendo da un if-else
Post by: lynx on January 15, 2017, 03:52:44 PM
Ah ok, quindi il while va bene, ma devi usare le classi per verificare solo g e poter continuare senza uscire e riavviare lo script, un po come ha detto davenull. Non c'è bisogno di fare + scripts in diversi files.
Title: Re:Creare una sorta di "goto" uscendo da un if-else
Post by: davenull on January 15, 2017, 05:25:21 PM
You are not allowed to view links. Register or Login
Ah ok, quindi il while va bene, ma devi usare le classi per verificare solo g e poter continuare senza uscire e riavviare lo script, un po come ha detto davenull. Non c'è bisogno di fare + scripts in diversi files.

esatto, crea un sottoprogramma apposito.
con i sottoprogrammi diventa tutto più leggibile e facile da gestire!!!
Title: Re:Creare una sorta di "goto" uscendo da un if-else
Post by: Gas75 on January 16, 2017, 10:28:13 AM
Ok, vediamo cosa riesco a combinare... :D
Grazie.
Title: Re:Creare una sorta di "goto" uscendo da un if-else
Post by: devilicecream on January 16, 2017, 11:10:28 AM
D'accordissimo con davenull e dario sul fatto di fare programmi modulari e object-oriented, quindi divisi in classi.
Se il problema però è solo di non chiedere da capo i primi due dati, basta letteralmente spostare la riga del while 4 righe più sotto, dopo aver salvato il valore di i ma prima di chiedere g.
Come utilizzare i cicli al posto dei goto per evitare algoritmi non strutturati è una delle basi della programmazione moderna!
Hai mai letto documentazione o un libro sugli algoritmi di base e le loro implementazioni?
Title: Re:Creare una sorta di "goto" uscendo da un if-else
Post by: Gas75 on January 16, 2017, 12:59:23 PM
You are not allowed to view links. Register or Login
Hai mai letto documentazione o un libro sugli algoritmi di base e le loro implementazioni?[/size]
Ho fatto un corso di Java "base", ma era troppo teorico e con poche applicazioni pratiche per focalizzare i concetti, almeno per come sono sempre stato abituato a studiare... :-\

In merito al problema di partenza, occorre controllare anche i valori di r e di i, in questo caso che siano interi (g deve invece essere intero e positivo).
Ho quindi scritto una cosa del genere:
Code: You are not allowed to view links. Register or Login
rText = String.valueOf(r);
        if (rText.indexOf(".") > 0) {
            throw new ErroreInput();
        }
per verificare la presenza del punto decimale nel dato di input, ma per qualche ragione non viene eseguita la classe per gestire l'errore, cioè sia così che non controllando nulla, se a r assegno 5.1, la console mi restituisce sempre gli stessi errori.
Chiaramente rText è stata dichiarata in apertura di classe, e nella riga del Main c'è throws ErroreInput.
Title: Re:Creare una sorta di "goto" uscendo da un if-else
Post by: devilicecream on January 16, 2017, 09:50:58 PM
Non so bene come java gestisca la input.nextInt(), ma sicuramente se il valore di ritorno lo metti in un int non è possibile che ci sia un valore floating point li dentro!
Se vuoi che sia possibile avere r, i e g come floating point devi utilizzare delle variabili float, e una funzione diversa da input.nextInt() per prenderli dallo standard input.
Per quanto riguarda la verifica che fai, anche avendo i valori come floating point stai facendo una cosa assurda ed inefficiente: indipendentemente dal cast da int a stringa, che come efficienza varia da linguaggio a linguaggio, quando vai a cercare il punto nella stringa stai sicuramente eseguendo un algoritmo O(n), dove n è la lunghezza della stringa.
Questo è incredibilmente più inefficiente di fare un semplice modulo 1 (var % 1) per ottenere la parte decimale e poi semplicemente verificare che questa sia uguale a 0.


Io credo che più che focalizzarti su un corso per un linguaggio specifico, dovresti guardare prima gli algoritmi di base, magari con esempi in linguaggio C. Saranno argomenti molto teorici all'inizio, ma ti assicuro che una volta imparati bene ti serviranno per qualunque linguaggio e applicazione andrai a sviluppare in futuro.
Title: Re:Creare una sorta di "goto" uscendo da un if-else
Post by: devilicecream on January 16, 2017, 10:02:36 PM
Un'altra cosa, stai utilizzando un debugger per fare inspection a runtime delle variabili nello stack? Se usi Eclipse basta lanciare il programma con "Debug" invece che "Run" e dovrebbe attaccarti automaticamente il processo al debugger.
Poi basta usare dei breakpoint dove avvengono le cose "strane" per vedere in quel momento quali sono i valori contenuti nelle variabili.
Se avessi usato il debugger sicuramente ti saresti accorto che anche se dai a r il valore 5.1, nella variabile verrà inserito il valore 5, perchè essendo un intero non supporta i valori decimali.
Title: Re:Creare una sorta di "goto" uscendo da un if-else
Post by: davenull on January 17, 2017, 05:59:39 AM
non esiste uno stepper in modo da capire in che punto preciso genera l'errore?
Title: Re:Creare una sorta di "goto" uscendo da un if-else
Post by: Gas75 on January 17, 2017, 03:06:21 PM
Per necessità di "matematica", i tre valori devono essere int, uno di essi peraltro strettamente positivo (e quest'ultimo l'abbiamo sistemato assieme ;) ).
Più che altro mi sto ponendo il dubbio se occorra effettivamente controllare tutto il "valore" che invio in input (cioè che manchi sia il punto decimale, ma anche il carattere a, il trattino, il carattere p, ecc...) o se, tra le millemila classi Java, ne esiste una che verifica il tipo di dato d'ingresso, una sorta di "if by type". Purtroppo nel corso abbiamo svolto soltanto esempi nei quali i dati erano inclusi e inizializzati nel codice stesso (me ne chiedo l'utilità, a parte la didattica) e quindi scritti coerentemente col tipo dichiarato (al massimo si è fatto qualche casting ove necessario). L'unico caso di input da tastiera è stato poi seguito dal System.out.println del dato stesso come inserito, guarda caso di tipo string per non porsi troppi dubbi che fermassero la lezione...

Proverò col debugger, vediamo cosa mi segnala...

L'errore comunque lo genera nel momento in cui riceve il primo dato che risulta non int.
Title: Re:Creare una sorta di "goto" uscendo da un if-else
Post by: devilicecream on January 18, 2017, 02:52:41 AM
Credo che dovresti anche leggere la documentazione del modulo Scanner che contiene la funzione .nextInt() che stai usando per parsare l'input da tastiera.
Probabilmente il problema si verifica perchè la funzione .nextInt() genera un errore che non stai gestendo quando le passi un carattere non numerico.
Title: Re:Creare una sorta di "goto" uscendo da un if-else
Post by: Gas75 on January 18, 2017, 06:46:23 PM
Sì, il discorso sulla classe Scanner lo sto trovando da più fonti... anche se non ho avuto il tempo materiale per approfondire.
Ho anche visto qualcosa circa le classi Wrapper, ma avendo già importato la classe Scanner, forse (e sottolineo forse ;D) è bene sfruttare quella...
Title: Re:Creare una sorta di "goto" uscendo da un if-else
Post by: Gas75 on January 18, 2017, 06:55:12 PM
You are not allowed to view links. Register or Login
Un'altra cosa, stai utilizzando un debugger per fare inspection a runtime delle variabili nello stack? [...]
Poi basta usare dei breakpoint dove avvengono le cose "strane" per vedere in quel momento quali sono i valori contenuti nelle variabili.
Se avessi usato il debugger sicuramente ti saresti accorto che anche se dai a r il valore 5.1, nella variabile verrà inserito il valore 5, perchè essendo un intero non supporta i valori decimali.
Quando immetto 5.1, l'errore è
Code: You are not allowed to view links. Register or Login
Exception in thread "main" java.util.InputMismatchException
at java.util.Scanner.throwFor(Scanner.java:864)
at java.util.Scanner.next(Scanner.java:1485)
at java.util.Scanner.nextInt(Scanner.java:2117)
at java.util.Scanner.nextInt(Scanner.java:2076)
at radicindic.RadiciNdiC.main(RadiciNdiC.java:39)
che credo esprima in "javese" :D che ho immesso un tipo di valore inatteso, prima che non gestibile dalle operazioni successive (anche dando a r tipo double, ottengo un errore quando il programma ha ricevuto i tre valori e inizia a manipolarli).
Title: Re:Creare una sorta di "goto" uscendo da un if-else
Post by: devilicecream on January 19, 2017, 12:15:31 AM
Esatto, come ti scrivevo prima il problema è che stai utilizzando la .nextInt() nella maniera sbagliata, e quindi il programma non gestisce il caso in cui immetti un punto. Leggi la documentazione ufficiale della classe Scanner e cerca su stackoverflow (in inglese) come acquisire i caratteri numerici, ignorando gli input inattesi. Vedrai che riuscirai a risolvere il problema!
Title: Re:Creare una sorta di "goto" uscendo da un if-else
Post by: Gas75 on January 19, 2017, 05:24:10 PM
Mi sto appunto leggendo il documento ufficiale della classe Scanner dal sito docs.oracle...
E' un po' dispersivo per i miei gusti (e il tempo che riesco a dedicarci) ma se non esce qualcosa da lì, non credo esca da altre fonti.
Title: Re:Creare una sorta di "goto" uscendo da un if-else
Post by: Gas75 on January 22, 2017, 07:41:40 PM
Non conta quanto e come studi ma come scrivono le cose sui testi che vai a leggere!
Ciò che non avevo capito è che in Java si gestiscono le eccezioni e non le cause dell'errore... Quindi mi ponevo la questione se il dato immesso fosse di tipo int piuttosto che intercettare ("to catch") il messaggio di errore generato da Java!
Con un opportuno try/catch il programma continua a funzionare (immettendo i valori di tipo corretto ha girato da subito), intercetta e gestisce qualunque errore d'immissione ma, in tal caso, non riesco a rimandarlo alla richiesta dell'input :( Cioè se non faccio chiudere il Run con un controllo booleano, mi scrive all'infinito l'eccezione relativa all'errore trovato... Mi manca insomma il fatidico "goto" che, con un linguaggio di minori pretese, mi avrebbe risparmiato una settimana di sclerate... :D
Title: Re:Creare una sorta di "goto" uscendo da un if-else
Post by: devilicecream on January 24, 2017, 03:51:49 AM
Purtroppo non tutti gli autori dei libri sono bravissimi a trasmettere le informazioni, specie quando si tratta di argomenti tecnici, che non sono proprio semplici ne da acquisire, ne da trattare.
Finchè non inventeranno la trasmissione di informazioni brain to brain, dobbiamo purtroppo arrangiarci con le risorse che abbiamo: libri, corsi online, corsi fisici e l'aiuto delle persone su internet.
Anche io, quando ero alle prime armi, avevo difficoltà a disegnarmi in mente gli algoritmi dei programmi che sviluppavo. È una cosa che viene con il tempo e con l'esperienza, ma solo se ci si impegna a migliorarsi con le risorse a disposizione. Non certo se si abbandona perchè un libro è troppo complicato da leggere.
Non esiste una regola generale che dice che in Java gli errori vanno gestiti tramite eccezioni e non a priori. Anzi, un approccio del genere è spesso deleterio nei confronti delle performance dei programmi. La questione varia caso per caso, e soprattutto bisogna sapere come utilizzare i try...catch all'interno del flusso dei programmi (quindi all'interno di eventuali cicli o ricorsioni).
Secondo me hai bisogno di rivedere un po' di teoria, se non riesci a controllare il flusso del programma senza il goto. La maggior parte dei linguaggi moderni non ha il costrutto goto proprio per evitare di incorrere in bad practices e per indurre gli sviluppatori a scrivere dei programmi ben strutturati.
Continua a provare e a studiare, vedrai che ce la farai!
Title: Re:Creare una sorta di "goto" uscendo da un if-else
Post by: Gas75 on January 24, 2017, 05:29:18 PM
Il problema è stato risolto tramite una classe apposita che cura il try/catch per ogni input che invio al programma.

Lo step successivo è cercare di "montare" il programma su una interfaccia grafica, e qui o lo faccio per piattaforma Android - ma non credo interessi a qualcuno svolgere da smartphone le operazioni che svolge il mio programma :D , oppure mi devo tuffare nelle Java Visual Guide praticamente da zero (non essendo argomento del corso).
Title: Re:Creare una sorta di "goto" uscendo da un if-else
Post by: davenull on January 26, 2017, 04:28:17 AM
You are not allowed to view links. Register or Login
Purtroppo non tutti gli autori dei libri sono bravissimi a trasmettere le informazioni, specie quando si tratta di argomenti tecnici, che non sono proprio semplici ne da acquisire, ne da trattare.
Finchè non inventeranno la trasmissione di informazioni brain to brain, dobbiamo purtroppo arrangiarci con le risorse che abbiamo: libri, corsi online, corsi fisici e l'aiuto delle persone su internet.
Anche io, quando ero alle prime armi, avevo difficoltà a disegnarmi in mente gli algoritmi dei programmi che sviluppavo. È una cosa che viene con il tempo e con l'esperienza, ma solo se ci si impegna a migliorarsi con le risorse a disposizione. Non certo se si abbandona perchè un libro è troppo complicato da leggere.
Non esiste una regola generale che dice che in Java gli errori vanno gestiti tramite eccezioni e non a priori. Anzi, un approccio del genere è spesso deleterio nei confronti delle performance dei programmi. La questione varia caso per caso, e soprattutto bisogna sapere come utilizzare i try...catch all'interno del flusso dei programmi (quindi all'interno di eventuali cicli o ricorsioni).
Secondo me hai bisogno di rivedere un po' di teoria, se non riesci a controllare il flusso del programma senza il goto. La maggior parte dei linguaggi moderni non ha il costrutto goto proprio per evitare di incorrere in bad practices e per indurre gli sviluppatori a scrivere dei programmi ben strutturati.
Continua a provare e a studiare, vedrai che ce la farai!

proprio per questo problema ti do un grossissimo consiglio. quando devi i studiare un qualsiasi linguaggio di programmazione, procurati più libri che trattano la stessa cosa, e confronta tra loro gli argomenti. e magari procurati una sfilza di sorgenti di esempio per capire meglio!!!
Title: Re:Creare una sorta di "goto" uscendo da un if-else
Post by: NebulasIT on January 26, 2017, 09:50:56 PM
Quote
proprio per questo problema ti do un grossissimo consiglio. quando devi i studiare un qualsiasi linguaggio di programmazione, procurati più libri che trattano la stessa cosa, e confronta tra loro gli argomenti. e magari procurati una sfilza di sorgenti di esempio per capire meglio!!!

Faccio la stessa cosa, più che altro le doc inglesi sono sempre le più complete...
Vi faccio un topic con un pò di doc, dove potete studiare dai :D
Title: Re:Creare una sorta di "goto" uscendo da un if-else
Post by: davenull on January 28, 2017, 09:09:55 PM
You are not allowed to view links. Register or Login
Quote
proprio per questo problema ti do un grossissimo consiglio. quando devi i studiare un qualsiasi linguaggio di programmazione, procurati più libri che trattano la stessa cosa, e confronta tra loro gli argomenti. e magari procurati una sfilza di sorgenti di esempio per capire meglio!!!

Faccio la stessa cosa, più che altro le doc inglesi sono sempre le più complete...
Vi faccio un topic con un pò di doc, dove potete studiare dai :D

se sono coperti da copyright non postarli, comunque si, i documenti in inglese sono sempre più completi!!!
Title: Re:Creare una sorta di "goto" uscendo da un if-else
Post by: Gas75 on February 03, 2017, 04:18:17 PM
You are not allowed to view links. Register or Login
quando devi i studiare un qualsiasi linguaggio di programmazione, procurati più libri che trattano la stessa cosa, e confronta tra loro gli argomenti.
:o Per acquisire completezza ci può stare, ma così mi sembra quasi di leggere due quotidiani diversi per farmi un'idea obiettiva su una notizia, mentre invece parliamo di programmazione...
Title: Re:Creare una sorta di "goto" uscendo da un if-else
Post by: davenull on February 03, 2017, 05:36:20 PM
You are not allowed to view links. Register or Login
You are not allowed to view links. Register or Login
quando devi i studiare un qualsiasi linguaggio di programmazione, procurati più libri che trattano la stessa cosa, e confronta tra loro gli argomenti.
:o Per acquisire completezza ci può stare, ma così mi sembra quasi di leggere due quotidiani diversi per farmi un'idea obiettiva su una notizia, mentre invece parliamo di programmazione...

eh lo so ma purtroppo è così, perchè magari ti ritrovi un libro che dice una cosa che l'altro libro non dice, ecc...
te lo dico per esperienza personale!!! :)