~FullSyst3m~
16-12-2008, 01:42
Come ho già detto in altre occasioni ultimamente il libro sul quale sto studianto è drasticamente calato dal punto di vista qualità e correttezza di informazione, sto passando più tempo a correggere gli errori e a capire che cosa vuole dire il libro, che a studiare.
Paragrafo 17.7:
Cosa succede se invochi questo metodo e passi una lista composta da un solo elemento (elemento singolo)? Cosa succede se passi come argomento una lista vuota? C'è una precondizione per questo metodo? Se esiste riscrivi il metodo per gestire gli eventuali problemi.
Il metodo è il seguente:
def RimuoviNodo(Lista):
if Lista == None: return
Secondo = Lista.ProssimoNodo
# Il primo nodo deve riferirsi al terzo
Lista.ProssimoNodo = Secondo.ProssimoNodo
# Separa il secondo nodo dal resto della lista
Secondo.ProssimoNodo = None
return Secondo
E questa è la classe Nodo, le varie assegnazioni e chiamate:
class Nodo:
def __init__(self, Contenuto=None, ProssimoNodo=None):
self.Contenuto = Contenuto
self.ProssimoNodo = ProssimoNodo
def __str__(self):
return str(self.Contenuto)
def StampaLista(Nodo):
Lista = []
while Nodo:
Lista.append(Nodo.Contenuto)
Nodo = Nodo.ProssimoNodo
print Lista
Nodo1 = Nodo(1)
Nodo2 = Nodo(2)
Nodo3 = Nodo(3)
Nodo1.ProssimoNodo = Nodo2
Nodo2.ProssimoNodo = Nodo3
StampaLista(Nodo1)
Rimosso = RimuoviNodo(Nodo1)
StampaLista(Rimosso)
StampaLista(Nodo1)
Io ho provato a lasciare il Nodo1 soltanto e ho tolto Nodo1.ProssimoNodo e Nodo2.ProssimoNodo. Nonostante ci sia il controllo iniziale, il controllo viene bypassato e ovviamente mi viene restituito l'errore che None non ha un attributo ProssimoNodo. Poi ho modificato Nodo1 in Nodo1 = Nodo() cosi da provare il secondo caso che ha detto il libro e ottengo anche qua lo stesso errore.
Premesso tutto questo, non capisco perchè dovrei riscrivere il metodo (come dice il libro) visto che quando viene spiegata la precondizione c'è messo chiaramente che in questi casi viene usata per imporre una limitazione ai parametri, infatti nel codice successivo non c'è nessuna correzione per gestire gli eventuali problemi.
Potrei usare un try/except magari, ma il punto non è questo. Spero si sia capito cosa voglio dire.
Dopo che ho riavviato non dà più l'errore di prima(solo con la funzione RimuoviNodo ovviamente dà errore), però il controllo non viene eseguito lo stesso perchè anche se il nodo che passo vale None viene stampato il valore (None), e per stamparlo dovrebbe entrare nell'if, che però ha come condizione != da None, quindi non dovrebbe essere eseguito. Mi riferisco a questo:
def StampaInversa(Nodo):
if Nodo == None: return
StampaInversa(Nodo.ProssimoNodo)
print Nodo,
def StampaInversaFormato(Lista):
print "[",
if Lista != None:
Coda = Lista.ProssimoNodo
StampaInversa(Coda)
print Lista,
print "]",
Nodo1 = Nodo()
StampaInversa(Nodo1)
StampaInversaFormato(Nodo1)
Output:
None [ None ]
Ma indovinate un pò? Dopo aver modificato il codice come scriverò tra poco sotto non mi stampa più None perchè ora il controllo viene eseguito e funziona. L'unica soluzione che mi viene in mente è che possa essere un problema di IDE (sono sul portatile e uso PyScripter).
Infine, sempre tratto dal libro:
Creiamo innanzitutto una nuova classe chiamata ListaLinkata. I suoi attributi sono un intero che contiene la lunghezza della lista e il riferimento al primo nodo. Gli oggetti ListaLinkata ci serviranno per gestire liste di oggetti Nodo:
class ListaLinkata:
def __init__(self) :
self.Lunghezza = 0
self.Testa = None
Una cosa positiva per quanto concerne la classe ListaLinkata è che fornisce un posto naturale dove inserire funzioni contenitore quale StampaInversaFormato e che possiamo far diventare metodi della classe:
class ListaLinkata:
...
def StampaInversa(self):
print "[",
if self.Testa != None:
self.Testa.StampaInversa()
print "]",
class Nodo:
...
def StampaInversa(self):
if self.ProssimoNodo != None:
Coda = self.ProssimoNodo
Coda.StampaInversa()
print self.Contenuto,
Per rendere le cose più interessanti, rinominiamo StampaInversaFormato. Ora abbiamo due metodi chiamati StampaInversa: quello nella classe Nodo che è l'aiutante e quello nella classe ListaLinkata che è il contenitore. Quando il metodo contenitore invoca self.Testa.StampaInversa sta in effetti invocando l'aiutante dato che self.Testa è un oggetto di tipo Nodo
Dove lo vede l'oggetto di tipo Nodo?
Paragrafo 17.7:
Cosa succede se invochi questo metodo e passi una lista composta da un solo elemento (elemento singolo)? Cosa succede se passi come argomento una lista vuota? C'è una precondizione per questo metodo? Se esiste riscrivi il metodo per gestire gli eventuali problemi.
Il metodo è il seguente:
def RimuoviNodo(Lista):
if Lista == None: return
Secondo = Lista.ProssimoNodo
# Il primo nodo deve riferirsi al terzo
Lista.ProssimoNodo = Secondo.ProssimoNodo
# Separa il secondo nodo dal resto della lista
Secondo.ProssimoNodo = None
return Secondo
E questa è la classe Nodo, le varie assegnazioni e chiamate:
class Nodo:
def __init__(self, Contenuto=None, ProssimoNodo=None):
self.Contenuto = Contenuto
self.ProssimoNodo = ProssimoNodo
def __str__(self):
return str(self.Contenuto)
def StampaLista(Nodo):
Lista = []
while Nodo:
Lista.append(Nodo.Contenuto)
Nodo = Nodo.ProssimoNodo
print Lista
Nodo1 = Nodo(1)
Nodo2 = Nodo(2)
Nodo3 = Nodo(3)
Nodo1.ProssimoNodo = Nodo2
Nodo2.ProssimoNodo = Nodo3
StampaLista(Nodo1)
Rimosso = RimuoviNodo(Nodo1)
StampaLista(Rimosso)
StampaLista(Nodo1)
Io ho provato a lasciare il Nodo1 soltanto e ho tolto Nodo1.ProssimoNodo e Nodo2.ProssimoNodo. Nonostante ci sia il controllo iniziale, il controllo viene bypassato e ovviamente mi viene restituito l'errore che None non ha un attributo ProssimoNodo. Poi ho modificato Nodo1 in Nodo1 = Nodo() cosi da provare il secondo caso che ha detto il libro e ottengo anche qua lo stesso errore.
Premesso tutto questo, non capisco perchè dovrei riscrivere il metodo (come dice il libro) visto che quando viene spiegata la precondizione c'è messo chiaramente che in questi casi viene usata per imporre una limitazione ai parametri, infatti nel codice successivo non c'è nessuna correzione per gestire gli eventuali problemi.
Potrei usare un try/except magari, ma il punto non è questo. Spero si sia capito cosa voglio dire.
Dopo che ho riavviato non dà più l'errore di prima(solo con la funzione RimuoviNodo ovviamente dà errore), però il controllo non viene eseguito lo stesso perchè anche se il nodo che passo vale None viene stampato il valore (None), e per stamparlo dovrebbe entrare nell'if, che però ha come condizione != da None, quindi non dovrebbe essere eseguito. Mi riferisco a questo:
def StampaInversa(Nodo):
if Nodo == None: return
StampaInversa(Nodo.ProssimoNodo)
print Nodo,
def StampaInversaFormato(Lista):
print "[",
if Lista != None:
Coda = Lista.ProssimoNodo
StampaInversa(Coda)
print Lista,
print "]",
Nodo1 = Nodo()
StampaInversa(Nodo1)
StampaInversaFormato(Nodo1)
Output:
None [ None ]
Ma indovinate un pò? Dopo aver modificato il codice come scriverò tra poco sotto non mi stampa più None perchè ora il controllo viene eseguito e funziona. L'unica soluzione che mi viene in mente è che possa essere un problema di IDE (sono sul portatile e uso PyScripter).
Infine, sempre tratto dal libro:
Creiamo innanzitutto una nuova classe chiamata ListaLinkata. I suoi attributi sono un intero che contiene la lunghezza della lista e il riferimento al primo nodo. Gli oggetti ListaLinkata ci serviranno per gestire liste di oggetti Nodo:
class ListaLinkata:
def __init__(self) :
self.Lunghezza = 0
self.Testa = None
Una cosa positiva per quanto concerne la classe ListaLinkata è che fornisce un posto naturale dove inserire funzioni contenitore quale StampaInversaFormato e che possiamo far diventare metodi della classe:
class ListaLinkata:
...
def StampaInversa(self):
print "[",
if self.Testa != None:
self.Testa.StampaInversa()
print "]",
class Nodo:
...
def StampaInversa(self):
if self.ProssimoNodo != None:
Coda = self.ProssimoNodo
Coda.StampaInversa()
print self.Contenuto,
Per rendere le cose più interessanti, rinominiamo StampaInversaFormato. Ora abbiamo due metodi chiamati StampaInversa: quello nella classe Nodo che è l'aiutante e quello nella classe ListaLinkata che è il contenitore. Quando il metodo contenitore invoca self.Testa.StampaInversa sta in effetti invocando l'aiutante dato che self.Testa è un oggetto di tipo Nodo
Dove lo vede l'oggetto di tipo Nodo?