User Tools

Site Tools


pub:labprog:faq

FAQ

NOTA BENE: aggiungere le domande in TESTA alle altre seguendo il pattern: TITOLO, DOMANDA, RISPOSTA/E

Titolo

Testo domanda

Risposta


javac non trova Integer.compareTo(Integer)

Domanda

Per esempio

public class Main {
    public static void main(String[] args) {
        Integer one = new Integer(1);
        Integer two = new Integer(2);
 
        one.compareTo(two)
    }
}

non compila:

$ javac Main.java 
Main.java:10: error: cannot find symbol
        one.compareTo(two);
           ^
  symbol:   method compareTo(Integer)
  location: variable one of type Integer
1 error

quando il metodo compareTo(Integer) esiste eccome.

Cosa mi sfugge?

Ringrazio, Giuseppe

Risposta

(giuscri) Mi autorispondo: assurdo! Dovevo aver combinato qualche pasticcio nei giorni precedenti con l'istanza di bash che stavo usando. Ho reboottato – bastava aprire un nuovo terminale, probabilmente – e ora il programma compila correttamente.

In quali occasioni scrivere una sottoclasse di una Exception e' buon design?

Domanda

Come da titolo, non riesco ad trovare neanche una situazione particolare in cui dovrei implementare un nuovo tipo di eccezione. Qualcuno sa aiutarmi?

Ringrazio, Giuseppe

Risposta

(atrent) avrei detto: “quando ti serve per catturare 'finemente' l'eccezione” e in effetti e' un parere condiviso

Che senso ha il costruttore in una classe astratta?

Domanda

(giuscri) Faccio riferimento al tema d'esame del 5 Febbraio 2013 (http://sl-lab.it/dokuwiki/lib/exe/fetch.php/pub:labprog:testo-2013-02-05-correttaanna-bis.pdf). Mi si chiede di scrivere una classe astratta `Utente` che

in costruzione lanci un'eccezione se il nickname e email (entrambi attributi della classe) sono stringhe nulle o vuote

Direi qualcosa del tipo

// Utente.java

public abstract class Utente {

    public Utente(String nickname, String email) throws ...Exception {
        if (nickname!=null&&nickname!=""&&email!=null...) {
          this.nickname = nickname;
          this.email = email;
          ...
        } else {
            throw ...Exception;
        }
    }
    
    ...
    
    private String nickname;
    private String password;

}

`Utente` viene poi usata come superclasse per scrivere `Venditore` e `Acquirente` – ciascuna con attributi/metodi diversi dalla successiva. Per esempio `Acquirente` ha un membro budget – che quindi va inizializzato in costruzione. Quindi

// Acquirente.java

public class Acquirente extends Utente {

    public Acquirente(..., int budget, ...) {
        ...
        this.budget = budget;
        ...
    }
    
    ...

    private budget;

}

Ora, come e' scritto il costruttore di `Acquirente`? Io lo riscriverei da zero, andando quindi ad aggiungere

// Acquirente.java

    ...
    
    // !!
    private nickname;
    private email;
    // !!
    
    private budget;

e inizializzando i due “nuovi” attributi. Ma in questo modo perdo tutto il codice scritto nella classe `Utente` – rendendola di fatto inutile.

A pensarci, non mi viene in mente una situazione in cui possa essere utile dotare una classe astratta di un costruttore.

Dove mi perdo?

Ringrazio, Giuseppe

Risposta

(atrent) ti sei quasi autorisposto ;-)

Dunque, intanto MAI (salvo casi che ora non mi vengono in mente :-P ) fare override degli attributi, anche perché in Java il binding è statico sugli attirbuti e dinamico sui metodi, ergo un casino concettuale e problemi enormi a debuggare…

Fare uno o più costruttori in una classe astratta significa che, non potendo istanziarla, vanno usati dalle sottoclassi, cioè deve vedersi un “super(…)” in qualche costruttore delle sottoclassi stesse.

Es.

public class Acquirente extends Utente {
    public Acquirente(..., int budget, ...) {
        super(...);
        this.budget = budget;
        ...
    }
    ...
    private budget;
}

O, più esplicitamente:

public class Acquirente extends Utente {
    public Acquirente(String nickname, String email, int budget, ...) {

        super(nickname,email); // costruisce la parte Utente di Acquirente

        this.budget = budget;
        ...
    }
    ...
    private budget;
}

Arrontondare un numero usando una regex?...

Domanda

(giuscri) A proposito di un esercizio proposto che chiedeva di

costruire una sequenza di interi, una di long, una di float, … e riempire ciascuna con dati del tipo (numerico) relativo scelti dall'utente; quindi trovare la media per ciascun set di numeri e stampare la media piu' alta.

Dovendo lavorare con sequenze di Long e di Double succede di ritrovarsi con valori in uscita molto rumorosi (da 5 cifre decimali in su). Specialmente se l'utente e' il programmatore impazzito che prova input battendo a caso sul tastierino numerico …

Serve da qualche parte un'idea per arrotondare i valori – in fase finale s'intende, un attimo prima di stampare.

Dato che la classe Math dispone del metodo statico round() che arrotonda un numero qualsiasi all'intero piu' vicino un'idea sarebbe (volendo arrotondare a due cifre decimali):

# Voglio arrotondare 3.1415926 ...
# Moltiplico per 100 >>> Math.round(3.1415926 * 100) == 314
# Pago il debito >>> 315 / 100. == 3.14

Ora …e' chiaro che una procedura simile non funziona se i decimali di cui voglio fare a meno sono prodotti dalla notazione scientifica. Infatti

# Voglio arrotondare 1.074E10 <<< Il numero di impiegati @ Google
# Riprovo a moltiplicare per 100 >>> Math.round(1.074E10 * 100) == 1.074E10
# Pago il debito >>> 1.074 / 100. == 1.074E10

E' chiaro quindi che ho bisogno di conoscere – per lo meno in generale – l'ordine di grandezza del numero che voglio arrontondare.

Come?

A me erano venuti in mente cicli innestati da far invidia a Mary Shelley.

Poi ho pensato di usare un'espressione regolare … Fuori luogo?

Di seguito il codice – compila e sembra funzionare. Posso avere un feedback? :)

import java.util.Scanner;
import prog.utili.Sequenza;
import java.util.regex.Pattern;
import java.util.regex.Matcher;
 
class theScanner {
    public static void main (String[] args) {
 
        Sequenza<Integer> theIntegerSequenza =
           new Sequenza<Integer>();
        Sequenza<Long> theLongSequenza =
           new Sequenza<Long>();
        Sequenza<Float> theFloatSequenza =
           new Sequenza<Float>();
        Sequenza<Double> theDoubleSequenza =
           new Sequenza<Double>();
 
 
        for (Scanner in = new Scanner(System.in);
                in.hasNext();)
        {
            if (in.hasNextInt()) {
                System.out.println("DEBUG: in.hasNextInt() == "
                                   + in.hasNextInt());
                theIntegerSequenza.add(in.nextInt());
            } else if (in.hasNextLong()) {
                System.out.println("DEBUG: in.hasNextLong() == "
                                   + in.hasNextLong());
                theLongSequenza.add(in.nextLong());
            } else if (in.hasNextFloat()) {
                System.out.println("DEBUG: in.hasNextFloat() == "
                                   + in.hasNextFloat());
                theFloatSequenza.add(in.nextFloat());
            } else if (in.hasNextDouble()) {
                System.out.println("DEBUG: in.hasNextDouble() == "
                                   + in.hasNextDouble());
                theDoubleSequenza.add(in.nextDouble());
            } else {
                // Discard just-read token ...
                System.out.println("DEBUG: Unknown input type.");
                in.next();
            }
        }
 
        // Def+Init of a single container for all the Sequenza's ...
        Sequenza<Sequenza> theSequenceSequenza =
            new Sequenza<Sequenza>();
        theSequenceSequenza.add(theIntegerSequenza);
        theSequenceSequenza.add(theLongSequenza);
        theSequenceSequenza.add(theFloatSequenza);
        theSequenceSequenza.add(theDoubleSequenza);
 
 
        //  We're storing averages of every
        //+ Sequenza into a single Sequenza ...
        Sequenza<Double> theAverageSequenza =
            new Sequenza<Double>();
 
        for (Sequenza tmpSequenza : theSequenceSequenza) {
            Double tmpAverage = new Double(0);
            for (Object tmpItem : tmpSequenza) {
                if (tmpItem instanceof Integer)
                    tmpAverage +=
                       (Integer) tmpItem / (float)tmpSequenza.size();
                else if (tmpItem instanceof Long)
                    tmpAverage +=
                       (Long) tmpItem / (float)tmpSequenza.size();
                else if (tmpItem instanceof Float)
                    tmpAverage +=
                       (Float) tmpItem / (float)tmpSequenza.size();
                else if (tmpItem instanceof Double)
                    tmpAverage +=
                       (Double) tmpItem / (float)tmpSequenza.size();
            }
 
            theAverageSequenza.add(tmpAverage);
        }
 
        // Naif-way of searching for a max ...
        Double maxAverage = new Double(0);
        for (Double tmpAverage : theAverageSequenza)
            if (tmpAverage > maxAverage)
                maxAverage = tmpAverage;
        // Debugging ...
        System.out.println("DEBUG: maxAverage == "
                           + maxAverage);
 
        // Using a regex for catching the magnitude ...
        Pattern thePattern = Pattern.compile(".*([eE])+(\\-?([0-9]+))$");
        Matcher theMatcher = thePattern.matcher(maxAverage.toString());
 
        if (theMatcher.matches()) {
            Double theExponent = Double.valueOf(theMatcher.group(2));
 
            // Debugging ...
            System.out.println("DEBUG: theExponent == "
                               + theExponent);
 
            Double maxAverageRadix =
               new Double(maxAverage * Math.pow(10, (-1) * theExponent));
 
            // Debugging ...
            System.out.println("DEBUG: > before rounding, maxAverageRadix == "
                               + maxAverageRadix);
 
            maxAverageRadix =
               new Double(Math.round(maxAverageRadix * 100) / 100.);
 
            // Debugging ...
            System.out.println("DEBUG: > after rounding, maxAverageRadix == "
                               + maxAverageRadix);
 
            maxAverage = maxAverageRadix * Math.pow(10, theExponent);
 
       } else {
            maxAverage =
               new Double(Math.round(maxAverage * 100) / 100.);
       }
 
       // Debugging ...
       System.out.println("DEBUG: maxAverage == "
                          + maxAverage);
 
    }
}

Ringrazio, Giuseppe

Risposta

E usare questo?


vecchie domande (pre 2010-2011)

Arrivare preparati all' esame di pratica

Domanda

Ciao a tutti, volevo chiedere se ci sono altri argomenti che non abbiamo approfondito durante il corso che potrebbero essere sogetto di esame aparte l'estensione dei tipi genirci? esmpio:

-estensione di tipi enum?

esmpi riscontrati sinora:

-Implementazione tipi enumarativi: Appello Giugno 2008 http://sl-lab.it/dokuwiki/lib/exe/fetch.php?media=pub:labprog:giugno08.pdf

-Estensione tipi generici: Appello Gennaio 2010 http://sl-lab.it/dokuwiki/lib/exe/fetch.php?media=pub:labprog:25gennaio10.pdf

questo puo anche servire per chi si presenta per la prima volta al esame di pratica per sapere cosa aspettarsi.

Non necessariamente gl'argomenti della prova di lab. saranno identici a quelli studiati durante il corso (a differenza della prova teorica).

in fine vorrei mettere un link al tutorial di java che insegna a usare le collezzioni e come estenderle (cosa che sarebbe stata alquanto utile sapere per l'appello di Gennaio.) http://java.sun.com/docs/books/tutorial/collections/intro/index.html

(atrent) ho spostato la proposta di soluzione qui e non ho corretto i typos…

(delca85) Dove si trova la proposta di soluzione dell'esame del 25 gennaio 2010? Il link sopra non portada nnessuna parte! (delca85) Trovate, grazie!

Risposta

(atrent) in lab non siamo riusciti a fare un esempio di ogni argomento possibile immaginabile perche' avremmo avuto bisogno del quadruplo delle lezioni per finire tutto ;)

(atrent) il senso di questo wiki (che state usando un po' solo ora dopo aver visto l'esame ;) ;) ;) mentre potevate farvi coinvolgere un po' prima) e' proprio quello di supportare la “comunita'” degli studenti del corso nella preparazione dell'esame, sia col mio aiuto che tramite la collaborazione di tutti voi :)

I/O senza librerie Pighizzini

ecco un altro esempio che cura anche le eccezzioni e chiede di riinserire i dati in caso non siano compatibili:

import java.io.*;
class Input1{
    boolean procedere;
    //metodi di supporto per l'inserimento dell'input
 
    public String readLine(){
	BufferedReader in;
	String x=null;
	try{
	    in=new BufferedReader(new InputStreamReader(System.in));
	    x=in.readLine();
	}catch(IOException e){e.printStackTrace();}
	return x;
    }
 
    public int readInt(){
	BufferedReader in;
	int x=0;
	do{
	    try{
 
		in = new BufferedReader(new InputStreamReader(System.in));
		x=Integer.parseInt(in.readLine());
		procedere=true;
	    }catch(IOException e){
		e.printStackTrace();}
	    catch(NumberFormatException e){
		System.out.println("valore incompatibile");
		System.out.print("inserisci un int: ");
		procedere=false;}
	}while(procedere==false);
	return x;
    }	
 
    public double readDouble(){
	BufferedReader in;
	double x=0;
	do{
	    try{	    
		in = new BufferedReader(new InputStreamReader(System.in));
		x=Double.parseDouble(in.readLine());
		procedere=true;
 
	    }catch(IOException e){
		e.printStackTrace();}
	    catch(NumberFormatException e){
		System.out.println("valore incompatibile");
		System.out.print("inserisci un double: ");
		procedere=false;}
	}while(procedere==false);
	return x;
    }
}

una volta compilata basta istanziare la classe input nella class che contiene il main(come si faceva con il ConsoleInputManager).

ecco la classe di prova modificata. nota che questa volta non c'e' bisogno di delegare eccezzioni nel metodo main visto che vengono trattate a priori nella classe input.

import java.io.*;
public class Prova{
	public static void main (String []arg){
		// canali di comunicazione
	    Input1 in=new Input1();
 
		//inserimento dati
		System.out.print("inserisci una stringa: ");
		String s = in.readLine();
		System.out.print("inserisci un double: ");
		double d = in.readDouble();
		System.out.print("inserisci un int: ");
		int i = in.readInt();
                //chiusura Stream
		/*in.close();
		  sr.close();*/
		//stampa dati
		System.out.println("La stringa inserita è: " + s);
		System.out.println("Il double inserito è: " + d);
		System.out.println("L'intero inserito è: " + i);
	}
}

Domanda

Buonasera, visto che non è possibile utilizzare le librerie del Prof. Pighizzini vorrei sapere se una soluzione come quella riportata sotto è accettabile per l'inserimento dell'input:

import java.io.InputStreamReader;
import java.io.BufferedReader;
import java.io.IOException;
 
public class Input{
	public static void main (String []arg)throws IOException{
		// canali di comunicazione
		InputStreamReader sr = new InputStreamReader(System.in);
		BufferedReader in = new BufferedReader(sr);
		//inserimento dati
		System.out.print("inserisci una stringa: ");
		String s = in.readLine();
		System.out.print("inserisci un double: ");
		double d = in.readDouble();
		System.out.print("inserisci un int: ");
		int i = in.readInt();
                //chiusura Stream
		in.close();
		sr.close();
		//stampa dati
		System.out.println("La stringa inserita è: " + s);
		System.out.println("Il double inserito è: " + d);
		System.out.println("L'intero inserito è: " + i);
	}
	//metodi di supporto per l'inserimento dell'input
        public String readLine()throws IOException{
		InputStreamReader sr = new InputStreamReader(System.in);
		BufferedReader in = new BufferedReader(sr);
		return in.readLine();
	}
	public int readInt()throws IOException{
		InputStreamReader sr = new InputStreamReader(System.in);
		BufferedReader in = new BufferedReader(sr);
		return Integer.parseInt(in.readLine());;
	}	
	public double readDouble()throws IOException{
		InputStreamReader sr = new InputStreamReader(System.in);
		BufferedReader in = new BufferedReader(sr);
		return Double.parseDouble(in.readLine());
	}
}

Io l'ho provata, ha compilato e ha funzionato, ma ho un dubbio perchè dopo aver apportato una modifica non sono più riuscito a far compilare lo stesso codice anche avendolo ripristinato allo stato precedente.

L'errore riscontrato è il seguente:

Input.java:13: cannot find symbol
symbol  : method readDouble()
location: class java.io.BufferedReader
		double d = in.readDouble();
		             ^
Input.java:15: cannot find symbol
symbol  : method readInt()
location: class java.io.BufferedReader
		int i = in.readInt();
		          ^
2 errors

Risposta

la classe BufferedReader non ha il metodo readDouble o readInt…

se volevi usare i metodi che hai scritto tu dovevi istanziare un Input (la classe che hai definito) e invocare i metodi su tale istanza…

Correzione dopo Risposta

Adesso compila e funziona!!!

import java.io.InputStreamReader;
import java.io.BufferedReader;
import java.io.IOException;
 
public class Input{
	public static void main (String []arg)throws IOException{
		//inserimento dati
		System.out.print("inserisci una stringa: ");
		String s = readLine();
		System.out.print("inserisci un double: ");
		double d = readDouble();
		System.out.print("inserisci un int: ");
		int i = readInt();
		//stampa dati
		System.out.println("La stringa inserita è: " + s);
		System.out.println("Il double inserito è: " + d);
		System.out.println("L'intero inserito è: " + i);
	}
 
	//metodi di supporto per l'inserimento dell'input
 
	public static String readLine()throws IOException{
		BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
		return in.readLine();
	}
 
	public static int readInt()throws IOException{
		return Integer.parseInt(readLine());
	}	
 
	public static double readDouble()throws IOException{
		return Double.parseDouble(readLine());
	}
}	

Classe Console

Domanda

import java.io.*;
 
public class ConsoleTest{
	public static void main(String[] args){
		Console in = System.console();
		System.out.println("scrivi!");
		String str = in.readLine();
		System.out.println("hai scritto: "+str);
	}
}

Ho trovato questa comodissima classe “Console”, mi han detto però di stare attenti poichè il suo funzionamento dipende molto dalla macchina che si ha di fronte: è quindi necessario provarla! Se funziona e viene accettata durante la prova permette di scrivere molto meno, se non funziona si usano i soliti Stream!

Risposta

Guarda, quando sono nato io (in java intendo) la Console non c'era quindi non ti so dire se e dove e come funziona (inteso come probabilita' di funzionamento usabile) quindi non mi sento di darvi certezze… bella risposta eh? 8-)

Diciamo che e' meglio se studiate entrambi i modi (Console e Stream vari) per sicurezza :-)

Esame difficile?

Domanda

ciao a tutti, volevo solo chiedere se qulcun altro ha trovato l'esame di laboratorio leggermente fuori dai limiti di quanto abbiamo studiato sia in teoria che in pratica?

Ho trovato alquanto spiazzante il fatto che cominciasse tutto con la richiesta di estendera un tipo generico, non avendo trattato ne in teoria in ne in pratica l'implementazione dei tipi generici.

sulla pagina di teoria i tipi genrici appaiono solo in classi della libreria prog-3ed, sequenza e sequenza ordinata, e non si tratta di implementazione. Mentre per quanto riguardo la pratica ci siamo limitati a usare i tipi generici (sempre uso non implementazione)in una lezzione per creare un vettore di pagine web.

grazie per eventuali risposte.

Risposta

(atrent) sono curioso dei vostri feedback, non abbiate timore :) non mi segno i nomi ;) … ah, non ho corretto il testo della domanda anche se c'e' qualche typo ;)

(atrent) ho dato uno sguardo agli esami consegnati, quasi tutti hanno capito la struttura, l'errore piu' comune che ho visto e' stato quello di ereditare da Vector e ANCHE dichiarare l'attributo Vector nella classe, non ha senso e rende la soluzione MOLTO fallata… provate a capire perche'

Risposta

La domanda rimane cmq. Come mai un sogetto ambiguo che non abbiamo trattato a fondo? poi il computer che per cambiare da una schermata all altra ci mette sui 3 secondi ( per non parlare del fatto che non sai su quale schermata vai a finire, alt-tab una volta mostra la schermata sucessiva ma potrebbe non essere questa di cui abbaimo bisogno il che significa altri 3 secondi solo per vedere la schermata dopo ancora e cosi via…), non mi sembra assolutamente un sistema su cui sperimentare.

imho come studente che ha sempre frequentatoio NON ritengo di avere avuto un preparazione sufficente per affrontare questa prova in sole 3 ore su una macchina cosi lenta.

Risposta

Anche io ho sperimentato gravi problemi al pc, purtroppo le maggiori difficoltà nel sostenere l'esame (almeno dal mio punto di vista) non sono state relative all'elaborato in se quanto dal contorno, cioè pc INUTILIZZABILE a causa dello switch lentissimo tra le finestre, in particolar modo dopo aver aperto un paio di task di nedit. A un certo punto ho quasi pensato di consegnare preso da una crisi di nervi (e tenga conto che mi piace scrivere codice). Inoltre una cosa che credo sia risolvibile molto facilmente e che imho ho trovato molto fastidiosa è stata dovermi leggere la traccia a monitor… Sarebbe stato decisamente meglio avere la traccia stampata e avrei potuto tenere sotto controllo tutti i punti da sviluppare… fare lo switch tra xpdf per vedere le richieste della domanda 4 e nedit è stato qualcosa di terribile :-( Saluti a tutti

Risposta

(atrent) capisco i problemi sul pc, ma quando avevo testato il sistema che mi ha proposto lo staff (viene usato per altri esami) aveva funzionato bene, non capisco come mai, riporto il problema allo staff…

Risposta

il sistema funzionava bene, senza grossi rallentamenti. L'unico problema, e su questo non c'è dubbio, lo switch tra le finestre era assolutamente scomodo e lento(bastava mettere una barra per le finestre aperte!!) Per la prova in sè forse era effettivamente un po troppo lunga,sicuramente non svolgibile bene in 3 ore. La difficoltà, è qui mi disunisco dal coro, non era parecchio elevata. Io non so se avete visto qualche prova degli anni scorsi ma mi ricordo di metodi con le matrici a cui non sono ancora riuscito ad arrivare alla soluzione(rifletti();isLatino()…)!!

Risposta

Io ho svolto l'esame in aula sigma e il mio pc era reattivo, non ho notato problemi di alcun tipo. Forse il problema erano solo i pc dell'altra aula?

Risposta

Prof, più o meno quando ci saranno i risultati? Grazie, saluti

(atrent) penso settimana prossima, dobbiamo omogeneizzare i dati tra me e Marra e lui in questa settimana non riusciva a correggerli per impegni vari…

pub/labprog/faq.txt · Last modified: 2014/02/01 17:12 by giuscri