Topic: PROBLEMA CON ESERCIZIO LISTE  (Letto 235 volte)

0 Utenti e 1 Visitatore stanno visualizzando questo topic.

Offline gianmarco988

  • python unicellularis
  • *
  • Post: 2
  • Punti reputazione: 0
    • Mostra profilo
PROBLEMA CON ESERCIZIO LISTE
« il: Settembre 30, 2020, 11:41 »
Buongiorno a tutti ragazzi, sono un nuovo membro e ho bisogno di aiuto con questo esercizio con le liste. Premetto che sto iniziando adesso con python e non sono ancora molto ferrato, infatti sto trovando parecchie difficoltà sopratutto con le liste. L'esercizio è questo :
Scrivere una funzione traslazione che riceve in input una lista di caratteri s e un intero n, e restituisce una lista w in cui tutte le lettere sono quelle di s traslate d n posizioni nell’ordinamento lessicografico [a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,x,y,z]


Esempio:
   s=[t,e,l,e,f,o,n,o]   n=7
   w=[b,l,s,l,m,v,u,v]
   
   infatti la settima lettera dopo la t è la b, la settima lettera dopo la e è la l, e così via.

La prima parte la riesco a fare senza problemi ma non riesco proprio a capire come traslare di n posizioni tutti i valori della lista presa da input. AIUTATEMI!!

Offline nuzzopippo

  • python neanderthalensis
  • ****
  • Post: 321
  • Punti reputazione: 0
    • Mostra profilo
Re:PROBLEMA CON ESERCIZIO LISTE
« Risposta #1 il: Settembre 30, 2020, 12:55 »
...La prima parte la riesco a fare senza problemi ma non riesco proprio a capire come traslare di n posizioni tutti i valori della lista presa da input. AIUTATEMI!!

beh ... una piccola perplessità mi viene ed avrei voluto vedere il Tuo codice, dato che le Tue liste non sono nemmeno composte da stringhe ;)

Va bene, dai, anche se non è una buona cosa, dato che Ti serve a ben poco (bisogna leggere la documentazione e sforzarsi di capire come operare perché un "esercizio" sia utile), ti do la soluzione "semplice"
>>> lessico = 'abcdefghijklmnopqrstuvxyz'
>>> def traslate(i_l):
w = []
for lett in i_l:
if lett in lessico:
pos = lessico.index(lett) + 7
if pos >= len(lessico):
pos -= len(lessico)
w.append(lessico[pos])
else:
w.append('Errore')
return w

>>> parola = ['t', 'e', 'l', 'f', 'o', 'n', 'o']
>>> traslate(parola)
['b', 'l', 's', 'm', 'v', 'u', 'v']
:
non devi far altro aggiungere 7 all'indice in lessico di un carattere ed estrarre il carattere di lessico con indice incrementato, ricominciando da zero se l'indice incrementato raggiunge la lunghezza di lessico.

Forse, Ti chiederai del perché utilizzi una stringa, invece di una lista, quale riferimento lessicale ... le stringhe hanno proprietà interessanti e, tra l'altro, sono iterabili, cioè possono anche essere lette un carattere alla volta tramite indice, la funzione non cambierebbe se si trattasse di valutare una stringa invece di una lista :
>>> parola = 'telefono'
>>> traslate(parola)
['b', 'l', 's', 'l', 'm', 'v', 'u', 'v']
>>> parola = 'westpoint'
>>> traslate(parola)
['Errore', 'l', 'a', 'b', 'x', 'v', 'p', 'u', 'b']
>>>

il secondo esempio Ti mostra il perché della verifica che le singole lettere appartengano effettivamente a lessico, "w" non c'è ed avresti un errore.

Dopo averTi dato la risposta, Ti sollecito a leggere la documentazione ed a provarci, a volte "il codice" sembra ubriacante ma sono sicuro che ci riesci, basta mettercisi.

[Ops[ mi era sfuggito che anche il numero doveva essere un parametro della funzione, cambia leggermente, ma il principio è sempre quello, basta aggiungere un parametro alla funzione ed alla chiamata :
>>> lessico = 'abcdefghijklmnopqrstuvxyz'
>>> def traslate(i_l, offset):
w = []
for lett in i_l:
if lett in lessico:
pos = lessico.index(lett) + offset
if pos >= len(lessico):
pos -= len(lessico)
w.append(lessico[pos])
else:
w.append('Errore')
return w

>>> parola = 'telefono'
>>> traslate(parola, 7)
['b', 'l', 's', 'l', 'm', 'v', 'u', 'v']
>>>
« Ultima modifica: Settembre 30, 2020, 13:18 da nuzzopippo »

Offline gianmarco988

  • python unicellularis
  • *
  • Post: 2
  • Punti reputazione: 0
    • Mostra profilo
Re:PROBLEMA CON ESERCIZIO LISTE
« Risposta #2 il: Settembre 30, 2020, 15:14 »
Guarda, io la prima parte l'avevo scritta così:
lista_1=int(input("Inserisci il numero di elementi della lista 1 "))
l=[]
for i in range(lista_1):
  elemento=input("Inserisci solo lettere che vanno da A a Z ")
  l.append(elemento)
intero=int(input("Inserisci un numero intero"))
print(l)
alfabeto=["a", "b", "c", "d", "e", "f", "g", "h", "i", "l" "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "z"]

Perché l'esercizio specificava di usare delle liste

Offline nuzzopippo

  • python neanderthalensis
  • ****
  • Post: 321
  • Punti reputazione: 0
    • Mostra profilo
Re:PROBLEMA CON ESERCIZIO LISTE
« Risposta #3 il: Ottobre 01, 2020, 08:00 »
Guarda, io la prima parte l'avevo scritta così:
...
Perché l'esercizio specificava di usare delle liste

Ok, liste allora, qualche suggerimento :
Il ciclo di input che utilizzi funziona ma è macchinoso, al di la dell'esercizio in se; puoi evitare di dover impostare tanto la lunghezza della stringa da inserire quanto inserimenti continuativi delle singole lettere se consideri la funzione builtin "list()" che, come puoi vedere dalla docs in link, restituisce una lista da un iterabile, come già indicato le stringhe sono iterabili e la lunghezza di una lista può essere ottenuta, se serve, attraverso la funzione builtin "len()"
>>> word = input('Inserisci solo lettere che vanno da A a Z : ')
Inserisci solo lettere che vanno da A a Z : Apelle
>>> parola = list(word)
>>> parola
['A', 'p', 'e', 'l', 'l', 'e']
>>> len(parola)
6
>>>


... poi, suggerirei un piccolo accorgimento, Nel prompt del Tuo input indichi l'intervallo "A - Z" ma le lettere minuscole sono "diverse" dalle lettere maiuscole
>>> 'a' == 'A'
False
>>> 'a' > 'A'
True
>>>

tienilo presente per evitare confusione, quando arriverai alle stringhe leggi i metodi "upper()" e "lower()" della classe.

Ciao :)

Offline RicPol

  • python sapiens sapiens
  • ******
  • Post: 3.141
  • Punti reputazione: 9
    • Mostra profilo
Re:PROBLEMA CON ESERCIZIO LISTE
« Risposta #4 il: Ottobre 04, 2020, 17:53 »
Allora, a parte l'approccio un po' raccapricciante alla strutturazione del codice, questo problema ha un nome e un cognome: si chiama "cifrario di Cesare" ("Caesar cipher", per chi ha voglia di googlare in inglese). Quindi non è difficile trovare in giro delle implementazioni (leggi: soluzioni! evvai) anche in Python.
Ovviamente, siccome le liste Python hanno già degli indici numerici, in linea di principio è banale "traslare"... basta trovare l'indice della lettera voluta, aggiungere (o sottrarre!) il tot di traslazione, e vedere quale lettera si trova al nuovo indice ottenuto. Se appena appena uno conosce i metodi fondamentali per lavorare con gli indici delle liste in Python, è a cavallo.
L'unico problema, ovviamente, è che le lettere dell'alfabeto non devono essere elencate in una semplice lista, ma, idealmente, in un *anello*, in modo che per esempio, dalla Y traslando di 4 posti si fa il giro e si ottiene la C.
Siccome Python ha le liste "piatte" ma non gli anelli, ci tocca fare qualche conticino a mano... in pratica abbiamo bisogno di una funzione "somma circolare" che somma due numeri in un anello di lunghezza data. Non è troppo difficile scrivere una funzione del genere, e sarebbe in effetti il cuore della difficoltà algoritmica dell'esercizio... certamente NON le questioni del tutto marginali su come fare input. Per scrivere questa funzione, può essere utile sapere che questa classe di problemi, dove si devono fare calcoli su un anello, si chiama "aritmetica modulare" (modulare... modulare... modulare viene da "modulo"... questo è un suggerimento).

Offline nuzzopippo

  • python neanderthalensis
  • ****
  • Post: 321
  • Punti reputazione: 0
    • Mostra profilo
Re:PROBLEMA CON ESERCIZIO LISTE
« Risposta #5 il: Ottobre 05, 2020, 08:55 »
Lasciando perdere il "Cifrario di Cesare" (non mi aveva nemmeno fiorato l'idea potesse essere un tentativo di criptazione), trovo molto interessante
... può essere utile sapere che questa classe di problemi, dove si devono fare calcoli su un anello, si chiama "aritmetica modulare" (modulare... modulare... modulare viene da "modulo"... questo è un suggerimento).

... non avevo mai sentito parlare di "aritmetica modulare", una brevissima ricerca me ne rivela la semplicità, applicata alla problematica sopra :
>>> lessico = 'abcdefghijklmnopqrstuvwxyz'
>>> lessico += lessico.upper()
>>> lessico
'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
>>> def circular_traslate(text, step):
my_text = ''
for c in text:
if c in lessico:
index = (lessico.index(c) + step) % len(lessico)
my_text += lessico[index]
else:
my_text += c
return my_text

>>> circular_traslate('telefono', 7)
'Alslmvuv'
>>> circular_traslate('Alslmvuv', -7)
'telefono'
>>> circular_traslate('Zichichi', 4)
'dmglmglm'
>>> circular_traslate('dmglmglm', -4)
'Zichichi'
>>>


argomento interessante indipendentemente dal problema dello OP ... non ho cercato eventuali "moduli" in merito, se avrò tempo lo farò, magari vi sono "ordini" di problematiche che trascendono una tale "semplicità".

Ciao :)

Offline RicPol

  • python sapiens sapiens
  • ******
  • Post: 3.141
  • Punti reputazione: 9
    • Mostra profilo
Re:PROBLEMA CON ESERCIZIO LISTE
« Risposta #6 il: Ottobre 05, 2020, 10:54 »
> non mi aveva nemmeno fiorato l'idea potesse essere un tentativo di criptazione
Beh certo che è un cifrario... si tratta di una mappatura che trasforma una stringa leggibile in una illeggibile...

> non avevo mai sentito parlare di "aritmetica modulare"
te la spiegano alle elementari quando ti insegnano a leggere l'orologio... se adesso sono le 10 di sera, tra 5 ore che ora è? Ma non ti dicono che si chiama aritmetica modulare.
E "modulo" non è un "modulo Python":.. è https://it.wikipedia.org/wiki/Operazione_modulo

Comunque sì, il concetto fondamentale qui è def circular_sum(a, b, n): return (a + b) % n. Questo può essere applicato alle stringhe per "traslarle" del cifrario di Cesare.



Ancora un po' di storia e di terminologia, già che siamo in tema.
Questo tipo di sostituzioni si chiamano (ovviamente) "rotazioni" e si abbreviano ROT. Quindi, per esempio, ROT5 è la traslazione di cinque lettere in avanti, e così via.
Siccome l'alfabeto inglese tipico ha 26 lettere, si capisce che una rotazione "speciale" è quella che lo divide a metà, ovvero ROT13. Questa ha la particolarità di essere il suo stesso inverso, ovvero se la applichi due volte di seguito ottieni la stringa di partenza: rot13(rot13(stringa)) = stringa.
Inutile dire che questa proprietà sembra molto elegante e diverte tutti i geek dai tempi d'oro dell'informatica, e ROT13 è un algoritmo di offuscamento molto usato (per scherzo, ovviamente... nessuno si aspetta davvero di cifrare qualcosa con ROT13). https://it.wikipedia.org/wiki/ROT13

In Python trovate un omaggio semi-scherzoso a ROT_13 nel modulo codecs... perché in effetti anche ROT13 è un codec, se vogliamo!

>>> import codecs
>>> codecs.encode('ciao pippo', 'rot_13')
'pvnb cvccb'

E trovate un altro omaggio, decisamente scherzoso questa volta, nel mitico "import this" che come tutti sanno restituisce lo Zen di Python. Ora, per poter fare "import this", occorre naturalmente che esista davvero un modulo chiamato "this.py" nella libreria standard... e in effetti è proprio così. E il contenuto di "this.py" è scritto in ROT13, guarda un po'. E alla fine del modulo trovate un'implementazione dell'algoritmo ROT13, per riconvertire il testo del modulo e presentarvelo come lo Zen di Python a cui siamo abituati. https://github.com/python/cpython/blob/master/Lib/this.py