Domanda esercizio python

markito

Utente Iron
3 Marzo 2021
23
7
2
19
L'esercizio è questo:
"Scrivete un programma che legga il file words.txt e stampi solo le parole composte
da almeno 20 caratteri (caratteri spaziatori esclusi)."

facendo riferimento ad un file contenente 113783 parole che ho scaricato online.

una soluzione a cui ho pensato è questa:

Python:
def caratteri20():
    fin=open('words.txt')
    riga=fin.readline()
    parola=riga.strip()
    for parola in fin:
        if len(parola)>=20:
            print(parola)

caratteri20()

e sembra funzionare se non per qualche piccolo difetto; infatti non capisco il motivo per cui non considera la prima riga del file words.txt e quindi non considera la prima parola e inoltre mi stampa parole anche di lunghezza 19 nonostante io abbia scritto di considerare le parole con len() >= 20.

Qualcuno che può aiutarmi a capire il perchè di questi comportamenti?

grazie in anticipo.
 
Scusa se rispondo con un'altra domanda: vuoi solo capire il comportamento o, se possibile, avere altre soluzioni (magari piu' semplici) per l'esercizio?
Conosci le Regex?
 
Scusa se rispondo con un'altra domanda: vuoi solo capire il comportamento o, se possibile, avere altre soluzioni (magari piu' semplici) per l'esercizio?
Conosci le Regex?
innanzitutto vorrei sapere il perchè di questi comportamenti del mio programma, poi sì, guardare soluzioni più semplici non mi dispiacerebbe.
per quanto riguarda le Regex non le conosco ma mi posso informare e studiare guardando anche la soluzione che mi mandi.
grazie per la velocità di risposta.
 
Com'e' composto il file? Una parola a riga?
Non vorrei dir boiate, ma credo che ogni volta che chiami 'riga', lui effettui il readline, quindi la prima riga la salta per quello, conviene usare qualcosa tipo:


Python:
with open('words.txt', 'r') as fp:
    lines = fp.readlines()

    for line in lines:
        #lo strip avviene in automatico se non erro
        if len(line)>= 20:
            print(line)
 
Com'e' composto il file? Una parola a riga?
Non vorrei dir boiate, ma credo che ogni volta che chiami 'riga', lui effettui il readline, quindi la prima riga la salta per quello, conviene usare qualcosa tipo:


Python:
with open('words.txt', 'r') as fp:
    lines = fp.readlines()

    for line in lines:
        #lo strip avviene in automatico se non erro
        if len(line)>= 20:
            print(line)
scusa se rispondo solo adesso.

si il file è composto una parola a riga ma effettuando il readline non dovrebbe comunque leggermi anche la prima riga dato che se scrivo il comando da interprete mi parte appunto dalla prima riga del file?

grazie per il codice più pulito anche se continuo a non capire perchè continua a stampare anche le parole con 19 caratteri.
 
Ultima modifica:
scusa se rispondo solo adesso.

si il file è composto una parola a riga ma effettuando il readline non dovrebbe comunque leggermi anche la prima riga dato che se scrivo il comando da interprete mi parte appunto dalla prima riga del file?

grazie per il codice più pulito anche se continuo a non capire perchè continua a stampare anche le parole con 19 caratteri.
Scusa il ritardo, si vede che non fa lo strip in automatico come credevo, scusami


Python:
with open('words.txt', 'r') as fp:
    lines = fp.readlines()

    for line in lines:
        if len(line.strip())>= 20:
            print(line)


(testato)
 
L'esercizio è questo:
"Scrivete un programma che legga il file words.txt e stampi solo le parole composte
da almeno 20 caratteri (caratteri spaziatori esclusi)."

facendo riferimento ad un file contenente 113783 parole che ho scaricato online.

una soluzione a cui ho pensato è questa:

Python:
def caratteri20():
    fin=open('words.txt')
    riga=fin.readline()
    parola=riga.strip()
    for parola in fin:
        if len(parola)>=20:
            print(parola)

caratteri20()

e sembra funzionare se non per qualche piccolo difetto; infatti non capisco il motivo per cui non considera la prima riga del file words.txt e quindi non considera la prima parola e inoltre mi stampa parole anche di lunghezza 19 nonostante io abbia scritto di considerare le parole con len() >= 20.

Qualcuno che può aiutarmi a capire il perchè di questi comportamenti?

grazie in anticipo.

hai fatto un po' di casino nel codice.
La prima riga non ti viene considerata perche'
-Prima chiami readline() che rimuove e legge una riga alla volta
-Poi iteri sulle righe rimaste del file
Nota:
Python:
    #Metodo 1
    for parola in fin:
    #Metodo 2
    for parola in list(fin):
    #Metodo 3
    for parola in fin.readlines():
Metodo 1, 2 e 3 sono equivalenti

Altro problema del codice e' che lo strip lo chiami solo sulla prima riga che rimuovi, quindi di fatto, oltra alla prima riga che escludi, stai elaborando un risultato errato per tutto il resto del file.


Ultimo punto:
se accedi ad un file ricordati sempre di chiuderlo
Python:
       try:
             fin=open('words.txt')
       finally:
             fin.close()
       # Ancora meglio usando il contex manager
       with open('words.txt') as fin:
              read_file_here
       do_stuff_here
 
Python:
with open('words.txt', 'r') as fp:
lines = fp.readlines()

for line in lines:
if len(line.strip())>= 20:
print(line)
fp.close()
grazie del codice che tra l'altro mi sembra in linea con quello che diceva luzzi.
mi sono un attimo informato riguardo a "with as" di python e, in teoria, con questa istruzione il fp.close() non è superfluo?
comunque grazie ancora
Messaggio unito automaticamente:

hai fatto un po' di casino nel codice.
La prima riga non ti viene considerata perche'
-Prima chiami readline() che rimuove e legge una riga alla volta
-Poi iteri sulle righe rimaste del file
ah okok, ho capito dove sta l'errore ma a sto punto sono curioso di capire perchè con queste due righe di codice:
Python:
    riga=fin.readline()
    parola=riga.strip()
come dici tu sto chiamando il readline(), non starei semplicemente, o almeno è quello che pensavo, facendo un assegnazione di delle variabili? comunque ho provato a togliere queste due righe modificando un po il codice originale giusto per provare il codice e perlomeno mi stampa anche la prima riga a conferma del mio errore, sono solo curioso del perchè quelle assegnazioni mi portano a fare il readline() solo della prima riga.
grazie in anticipo
 
grazie del codice che tra l'altro mi sembra in linea con quello che diceva luzzi.
mi sono un attimo informato riguardo a "with as" di python e, in teoria, con questa istruzione il fp.close() non è superfluo?
comunque grazie ancora
Messaggio unito automaticamente:


ah okok, ho capito dove sta l'errore ma a sto punto sono curioso di capire perchè con queste due righe di codice:
Python:
    riga=fin.readline()
    parola=riga.strip()
come dici tu sto chiamando il readline(), non starei semplicemente, o almeno è quello che pensavo, facendo un assegnazione di delle variabili? comunque ho provato a togliere queste due righe modificando un po il codice originale giusto per provare il codice e perlomeno mi stampa anche la prima riga a conferma del mio errore, sono solo curioso del perchè quelle assegnazioni mi portano a fare il readline() solo della prima riga.
grazie in anticipo

1) se usi il contex manager il close non va chiamato perche' lo fa gia' lui.
2) se usi il readline rimuovi il primo elemento e lo ritorni quindi quando iteri sulla lista il primo elemento sarebbe il secondo originario
Immagina di avere un file con 3 righe
paperino
pluto
pippo

Hai una cosa del genere
Python:
   #fp non e' proprio cosi' ma immaginalo come tale per il caso corrente
   fp=["paperino", "pluto", "pippo"]
   riga = fp.readline()
   #Valori fp = ["pluto", "pippo"]
   #Valori riga= "paperino"'
   riga = fp.readline()
   #Valori fp = ["pippo"]
   #Valori riga= "pluto"
 
1) se usi il contex manager il close non va chiamato perche' lo fa gia' lui.
2) se usi il readline rimuovi il primo elemento e lo ritorni quindi quando iteri sulla lista il primo elemento sarebbe il secondo originario
Immagina di avere un file con 3 righe
paperino
pluto
pippo

Hai una cosa del genere
Python:
   #fp non e' proprio cosi' ma immaginalo come tale per il caso corrente
   fp=["paperino", "pluto", "pippo"]
   riga = fp.readline()
   #Valori fp = ["pluto", "pippo"]
   #Valori riga= "paperino"'
   riga = fp.readline()
   #Valori fp = ["pippo"]
   #Valori riga= "pluto"
ah okok grazie penso di aver capito.
grazie anche a fisica-all per l 'aiuto; ci rivediamo su inforge