Please ignore secret bonuses. Secret tests do NOT award bonus. Max hw grade is 30+2 bonus efficiency

Do you need help?

Cosa cambia? - Simboli HW4

anon3 (10560 points)
20 66 138
in HW4 by (10.6k points)
closed by

Durante l'esecuzione del pytest con Anaconda, il mio programma funziona correttamente con tutti i test che contengono file aventi solo parole, ma appena si passa ai test contenenti simboli ottengo risultati sbagliati. Ho messo la codifica utf-8 e tutto, quindi non capisco cosa ci sia di diverso, considerando che le stringhe risultanti, quando lavoro con i caratteri, sono giuste.

Cambia forse qualcosa a livello di max e sorted del dizionario? Magari l'ordine che il mio programma da ai simboli è diverso da quello che si aspetta il test, non saprei...

EDIT:

ᛢᚦᛠᚦᚤᚬᚬᚽᚸᛘᚣᚢᛜᛥᚳᛜᛖᛄᚢᛊᚬᛟᛈᛅᛞᚹᛯᚥᚧᚺ
ᛢᚦᛝᛡᚤᚬᚬᛍᚸᛘᚣᚢᛜᛥᚳᛜᛖᛄᚢᛊᚬᛟᛈᛅᛞᚹᛯᚼᛁᚺ

Ecco un esempio. Perché solo alcuni caratteri non sono uguali? 

612 views
closed with the note: Sono semplicemente stupido

7 Answers

l.vitale3 (6010 points)
10 22 83
by (6.0k points)
Usi spyder per editarlo? Perchè a livello di funzioni max e sorted non ci sono problemi perchè ho provato ad usarli ed è tutto ok. Hai considerato il fatto che ci sono più caratteri con la stessa frequenza e devi scegliere in ordine alfabetico?
anon3 (10560 points)
20 66 138
by (10.6k points)
Si, uso Spyder. Ho considerato sia la frequenza che l'ordine alfabetico, infatti come ho detto per le stringhe contenenti lettere normali funziona.
l.vitale3 (6010 points)
10 22 83
by (6.0k points)
Allora potrebbero essere due i problemi:

- o non conti in maniera corretta le frequenze (ed è un caso che passi i primi test)

- oppure il modo di scegliere i caratteri, con la massimo freqeunza, ordinati alfabeticamente "sballa" con i simboli perchè utilizzi un meccanismo che funziona solo con le lettere.
Alegau (6770 points)
1 2 43
by (6.8k points)
Ciao!

quando apri il file con with open ecc... quando specifichi l encoding togli il trattino.

da encoding = "utf-8" a -> encoding="utf8", io scrivo cosi e funziona.

Fammi sapere!
anon3 (10560 points)
20 66 138
by (10.6k points)
Ho provato, non cambia nulla.
l.vitale3 (6010 points)
10 22 83
by (6.0k points)
Allora ho provato a replicare il tuo errore, guarda caso l'esempio che hai inviato non contiene più caratteri con la frequenza massima (perchè ho provato a scegliere senza considerare l'ordine alfabetico, in quel test che hai inviato, e comunque lo supero). Quindi a questo punto la cosa più probabile è il modo in cui raccogli le frequenze. Oppure c'è qualche altro errore di logica che però non conoscendo il tuo codice non posso esserti d'aiuto.
anon3 (10560 points)
20 66 138
by (10.6k points)

Quindi a questo punto la cosa più probabile è il modo in cui raccogli le frequenze. 

Ho fatto dei test a mano e colleziono bene le frequenze, conto ogni carattere di una parola nel suo index specifico e il numero risultante è corretto.

Oppure c'è qualche altro errore di logica che però non conoscendo il tuo codice non posso esserti d'aiuto.

Capisco, grazie comunque dell'aiuto...c'è qualche altra informazione che potrei darti in modo tale che tu possa darmi qualche altro suggerimento? 

l.vitale3 (6010 points)
10 22 83
by (6.0k points)
"Uso un max(sorted(dizionario), key=dizionario.get) in pratica. Così ottengo una lettera come risultato. Funziona bene perché con (tutte) le parole normali funziona."

Il problema sta qui!

Spiegami com'è formata la struttura finale e ti dico come risolvere. Hai nested dict, lista di dicts, oppure iteri sugli indici e ne crei solo uno per volta ed estrai la chiave?
anon3 (10560 points)
20 66 138
by (10.6k points)

Allora: ho una lista di stringhe contenente tutte le parole (senza spazi, ecc.) di ogni file concatenato. Gli dico di controllare ogni parola[index] (= i caratteri nella loro posizione), di contarne la frequenza e di tornarmi un dizionario del tipo: chiave = lettera, valore=numero_della_medesima_lettera_nel_medesimo_index.

Poi questo dizionario lo ordino come scritto nella parte da te quotata, il che mi ritorna una sola lettera (carattere generico), ovvero quella che ha frequenza massima.

Itero la stessa operazione per tutti gli index nel range della parola (di lunghezza massima), poi "attacco" tutte le lettere risultanti per ottenere la stringa complessiva.

Quindi uso: lista > dizionario key=lettera, value=int_frequenza > carattere (str) > stringa finale (inizializzata vuota) += tutti i caratteri

EDIT: In pratica faccio quello che hai detto qui:

oppure iteri sugli indici e ne crei solo uno per volta ed estrai la chiave?

l.vitale3 (6010 points)
10 22 83
by (6.0k points)
edited by
Il fatto è che tu stai estraendo in modo sbagliato. Dopo che per ogni indice di ogni parola hai raccolto {char:freq}, devi intato capire qual'è il valore massimo, e questo lo puoi fare ad esempio con max(diz.values()) e questo avrà il valore della chiave con valore massimo, poi devi crearti una lista di tutti i caratteri (cioè chiavi solo se il loro valore è uguale al massimo), poi ordini questa con sort/sorted se l'hai ordinata in maniera crescente prendi l'ultimo lista[-1] altrimenti il primo. Questo dovrebbe risolverti il problema ;)
anon3 (10560 points)
20 66 138
by (10.6k points)
edited by

Ho fatto esattamente ciò che mi hai detto, ma ho ottenuto un risultato equivalente (leggermente più lento) che comunque ritorna l'errore, sempre e solo nei test che contengono simboli:

'ᛢᚦᛠᚦᚤᚬᚬᚽᚸᛘᚣᚢᛜᛥᚳᛜᛖᛄᚢᛊᚬᛟᛈᛅᛞᚹᛯᚥᚧᚺ' != 'ᛢᚦᛝᛡᚤᚬᚬᛍᚸᛘᚣᚢᛜᛥᚳᛜᛖᛄᚢᛊᚬᛟᛈᛅᛞᚹᛯᚼᛁᚺ'

Quindi abbiamo verificato che il problema non risiede nel calcolo della frequenza...ma dove? crying

(Grazie infinite per il supporto, comunque!) 

James_F (6070 points)
10 14 47
by (6.1k points)
sei sicuro di usare bene le funzioni max/min o sorted? suppongo tu stia usando una lambda a due condizioni come criterio, ecco, possibile che tu stia banalmente invertendo il criterio di selezione?
anon3 (10560 points)
20 66 138
by (10.6k points)

sei sicuro di usare bene le funzioni max/min o sorted?

Uso un max(sorted(dizionario), key=dizionario.get) in pratica. Così ottengo una lettera come risultato. Funziona bene perché con (tutte) le parole normali funziona.

James_F (6070 points)
10 14 47
by (6.1k points)
perché non sortare/controllare il max direttamente degli oggetti del dizionario? questo ti permetterebbe, data la lambda a doppia condizione di avere quel controllo in più che sicuramente ti fixa il problema
James_F (6070 points)
10 14 47
by (6.1k points)
inoltre, se non ti sono ben chiare le lambda o queste funzioni built-in (a parte imparale!) puoi sempre iterare con un for e controllare con degli if, se hai implementa5o bene il resto non dovresti andare in timeout, avrai solo del codice un po' meno elegante
anon3 (10560 points)
20 66 138
by (10.6k points)

inoltre, se non ti sono ben chiare le lambda o queste funzioni built-in (a parte imparale!) puoi sempre iterare con un for e controllare con degli if, se hai implementa5o bene il resto non dovresti andare in timeout, avrai solo del codice un po' meno elegante

So usare le funzioni built-in e lambda, le ho usate anche per lo scorso HW.  Per sicurezza ho comunque provato, come mi hai suggerito, di usare cicli for/if, ma nulla: i risultati dei test con le parole sono tutti giusti, i risultati con i test con i simboli sono tutti sbagliati.

James_F (6070 points)
10 14 47
by (6.1k points)
mi sembra davvero strano, sei sicuro di non sfruttare qualche caratteristica specifica dei caratteri alfabetici? probabilmente devi solo rendere più generico il controllo che fai.
Shangry_ (9930 points)
7 25 76
by (9.9k points)
io ho scritto quel pezzo di programma sia con sorted che con cicli for, funziona con entrambi.

prova a scrivere encoding=‘utf8’ invece di ‘utf-8’

dimmi se funziona
Shangry_ (9930 points)
7 25 76
by (9.9k points)

in questo modo

with open(filename, encoding='utf8') as f:
anon3 (10560 points)
20 66 138
by (10.6k points)

io ho scritto quel pezzo di programma sia con sorted che con cicli for, funziona con entrambi.

Ho fatto la stessa cosa.

 prova a scrivere encoding=‘utf8’ invece di ‘utf-8’

Lo ho cambiato, ho riprovato ma non cambia nulla. I simboli me li legge, è che alcune volte mi prende quelli sbagliati. 

Paolo Gentili (31130 points)
3 6 114
by (31.1k points)
Ho avuto anche io un problema del genere, sicuramente è la parte finale in cui sorti (con sorted,max,min dipende da come hai fatto) guarda bene la funzione che decide in che ordine prendere i caratteri, a me dava problemi con pochissimi caratteri ma per fixare ho fatto varie prove con ord e ci sono riuscito.
anon3 (10560 points)
20 66 138
by (10.6k points)
Hai settato a mano l'ordine da scegliere con ord() o hai fatto solo delle prove?
James_F (6070 points)
10 14 47
by (6.1k points)
a parità di occorrenze controlli il valore ord() dei caratteri?
anon3 (10560 points)
20 66 138
by (10.6k points)
Sì, uso sorted, quindi (dovrebbe) mettermeli in ordine. Una domanda (stavo ragionando su un'eventualità, magari è quello), è possibile che ci siano più parole uguali nei file concatenati? TIpo che nel file 1.txt ho la parola "hello" e nel file 20.txt ricompare "hello"? Perché io ho costruito la funzione per evitare ripetizioni della medesima parola (quando le raccolgo in una lista), non so se è sbagliato.

Forse nei file con le parole non hanno messo ripetizioni, ma nei simboli sì.
James_F (6070 points)
10 14 47
by (6.1k points)
probabilmente è proprio lì l'errore, conta i duplicati e avrai risolto
anon3 (10560 points)
20 66 138
by (10.6k points)

Ahem...per chi è curioso di sapere quale fosse il problema....blush

Sono stato 6 ore davanti al pc e non mi sono accorto che c'era uno spazio prima di un for, che python non mi mostrava come errore e che guarda caso mi faceva funzionare solo i test con i caratteri dell'alfabeto...il che mi ha portato a pensare, giustamente, che ci fosse qualcosa che non andava con i simboli; non so come sia possibile che questa serie di coincidenze si siano intrecciate perfettamente per un singolo insulso spazio, ma non mi faccio domande, basta che funzioni.

Grazie a tutti per la pazienza e per i consigli! 

James_F (6070 points)
10 14 47
by (6.1k points)
ho fatto di peggio bro, ho fatto di peggio. Tipo perdere 15 punti ad un hw per un controllo fatto al contrario che nei test ordinari non capitava ma nei segreti sì....