<p>Python:</p>



<h1 class="wp-block-heading">Stringhe</h1>



<h1 class="wp-block-heading">7.1 Tipi di dati composti</h1>



<p>Finora abbiamo visto tre tipi di dati: ;<span class="code">int</span>, ;<span class="code">float</span> ;e ;<span class="code">string</span>. Le stringhe sono qualitativamente diverse dagli altri tipi di dati poiché sono composte di unità più piccole: i caratteri.</p>



<p>I tipi di dati che sono fatti di elementi più piccoli sono detti ;<b>tipi di dati composti</b>.</p>



<p>A seconda di ciò che stiamo facendo possiamo avere la necessità di trattare un tipo composto come fosse una singola entità o possiamo voler agire sulle sue singole parti. Questa duplice possibilità è molto utile.</p>



<h4 class="wp-block-heading">L&#8217;operatore porzione seleziona dei caratteri da una stringa:</h4>



<h4 class="wp-block-heading">>;>;>; Frutto = ;&#8220;banana&#8221;<br>>;>;>; Lettera = Frutto[1]<br>>;>;>; ;print ;Lettera<br></h4>



<p>L&#8217;espressione ;Frutto[1] ;seleziona il carattere numero 1 dalla stringa ;Frutto. La variabile ;Lettera ;contiene il risultato. Quando stampiamo ;Lettera ;abbiamo però una sorpresa:</p>



<h4 class="wp-block-heading">a<br></h4>



<p>La prima lettera di ;&#8220;banana&#8221; ;logicamente non è ;&#8220;a&#8221;: in informatica i conteggi partono spesso da 0 e non da 1 come potrebbe sembrare normale e per accedere al primo carattere di una stringa dobbiamo quindi richiedere il numero 0, per il secondo il numero 1 e così via. Sembra un po&#8217; illogico ma ci farai facilmente l&#8217;abitudine perché questo è il modo normale di contare in molti linguaggi di programmazione. Quindi se vogliamo sapere l&#8217;iniziale della stringa scriviamo:</p>



<h4 class="wp-block-heading">>;>;>; Lettera = Frutto[0]<br>>;>;>; ;print ;Lettera<br>b<br></h4>



<p>il numero tra parentesi quadre è chiamato ;<strong>indice</strong>.</p>



<p>Esso identifica un particolare elemento di un insieme ordinato che nel nostro caso è l&#8217;insieme dei caratteri di una stringa.</p>



<h4 class="wp-block-heading">L&#8217;indice può essere una qualsiasi espressione intera.</h4>



<h3 class="wp-block-heading">7.2 Lunghezza</h3>



<p>La funzione ;len ;ritorna il numero di caratteri di una stringa:</p>



<h4 class="wp-block-heading">>;>;>; Frutto = ;&#8220;banana&#8221;<br>>;>;>; len(Frutto)<br>6<br></h4>



<p>Per ottenere l&#8217;ultimo carattere di una stringa potresti essere tentato di fare qualcosa di simile a:</p>



<h4 class="wp-block-heading">Lunghezza = len(Frutto)<br>Ultimo = Frutto[Lunghezza] ;  ;  ;  ;# ERRORE! ;<br></h4>



<p>ma c&#8217;è qualcosa che non va: infatti ottieni un errore ;IndexError: string index out of range ;dato che stai facendo riferimento all&#8217;indice 6 quando quelli validi vanno da 0 a 5. Per ottenere l&#8217;ultimo carattere dovrai quindi scrivere:</p>



<h4 class="wp-block-heading">Lunghezza = len(Frutto)<br>Ultimo = Frutto[Lunghezza-1]<br></h4>



<p>In alternativa possiamo usare indici negativi che in casi come questo sono più comodi, contando a partire dalla fine della stringa: l&#8217;espressione ;Frutto[-1] ;ritorna l&#8217;ultimo carattere della stringa, ;Frutto[-2] ;il penultimo e così via.</p>



<h3 class="wp-block-heading">7.3 Elaborazione trasversale e cicli ;for</h3>



<p>Molti tipi di elaborazione comportano un&#8217;azione su una stringa un carattere per volta. Spesso queste elaborazioni iniziano dal primo carattere, selezionano un carattere per volta e continuano fino al completamento della stringa. </p>



<p>Questo tipo di elaborazione è definita ;<strong>elaborazione trasversale</strong> ;o ;<strong>attraversamento</strong>, in quanto attraversa la stringa dall&#8217;inizio alla fine. Un modo per implementare un&#8217;elaborazione trasversale è quello di usare un ciclo ;while:</p>



<h4 class="wp-block-heading">Indice = 0<br>while ;Indice <; len(Frutto):<br>Lettera = Frutto[Indice]<br>print ;Lettera<br>Indice = Indice + 1<br></h4>



<p>Questo ciclo attraversa la stringa e ne mostra una lettera alla volta, una per riga. </p>



<p>La condizione del ciclo è ;Indice <; len(Frutto) ;così che quando ;Indice ;è uguale alla lunghezza della stringa la condizione diventa falsa, il corpo del ciclo non è eseguito ed il ciclo termina. </p>



<p>L&#8217;ultimo carattere cui si accede è quello con indice ;len(Frutto)-1 ;che è l&#8217;ultimo carattere della stringa.</p>



<h4 class="wp-block-heading">Esercizio: </h4>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p>scrivi una funzione che prende una stringa come argomento e la stampa un carattere per riga partendo dall&#8217;ultimo carattere.</p></blockquote>



<p>Usare un indice per attraversare un insieme di valori è un&#8217;operazione così comune che Python fornisce una sintassi ancora più semplice: il ciclo ;for.</p>



<h4 class="wp-block-heading">for ;Lettera ;in ;Frutto:<br>print ;Lettera<br></h4>



<p>Ad ogni ciclo, ;Lettera ;assume il valore del prossimo carattere della stringa ;Frutto, così che ;Frutto ;viene attraversata completamente finché non rimangono più caratteri da analizzare.</p>



<h4 class="wp-block-heading">quindi:</h4>



<p>L&#8217;esempio seguente mostra come usare il concatenamento e un ciclo ;for ;per generare una serie alfabetica, e cioè una lista di valori nei quali gli elementi appaiono in ordine alfabetico. Per esempio nel libro ;<em>Make Way for Ducklings</em> ;di Robert McCloskey i nomi dei protagonisti sono Jack, Kack, Lack, Mack, Nack, Ouack, Pack e Quack. Questo ciclo restituisce i nomi in ordine:</p>



<h4 class="wp-block-heading">Prefissi = ;&#8220;JKLMNOPQ&#8221;<br>Suffisso = ;&#8220;ack&#8221;</h4>



<h4 class="wp-block-heading">for ;Lettera ;in ;Prefissi:<br>print ;Lettera + Suffisso</h4>



<h4 class="wp-block-heading">Il risultato del programma è:</h4>



<h4 class="wp-block-heading">Jack<br>Kack<br>Lack<br>Mack<br>Nack<br>Oack<br>Pack<br>Qack<br></h4>



<p>Non è del tutto corretto dato che ;Ouack ;e ;Quack ;sono scritti in modo errato.</p>



<h4 class="wp-block-heading">

Esercizio: 

</h4>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p>modifica il programma per correggere questo errore.</p></blockquote>



<h3 class="wp-block-heading">7.4 Porzioni di stringa</h3>



<p>Un segmento di stringa è chiamato ;<strong>porzione</strong>. La selezione di una porzione è simile alla selezione di un carattere:</p>



<h4 class="wp-block-heading">>;>;>; s = ;&#8220;Pietro, Paolo e Maria&#8221;<br>>;>;>; ;print ;s[0:6]<br>Pietro<br>>;>;>; ;print ;s[8:13]<br>Paolo<br>>;>;>; ;print ;s[16:21]<br>Maria<br></h4>



<p>L&#8217;operatore ;[n:m] ;ritorna la stringa a partire dall&#8217; &#8220;n-esimo&#8221; carattere incluso fino all&#8217; &#8220;m-esimo&#8221; escluso. </p>



<p>Questo comportamento non è intuitivo, e per comprenderlo è meglio immaginare i puntatori ;<em>tra</em> ;i caratteri, come nel diagramma seguente:</p>



<figure class="wp-block-image"><img src="https://www.python.it/doc/Howtothink/Howtothink-html-it/illustrations/i_banana.png" alt=""/></figure>



<p>Se non è specificato il primo indice (prima dei due punti ;:) la porzione parte dall&#8217;inizio della stringa. Senza il secondo indice la porzione finisce con il termine della stringa:</p>



<h4 class="wp-block-heading">>;>;>; Frutto = ;&#8220;banana&#8221;<br>>;>;>; Frutto[:3]<br>&#8216;ban&#8217;<br>>;>;>; Frutto[3:]<br>&#8216;ana&#8217;<br></h4>



<p>Secondo te cosa significa ;Frutto[:]?</p>



<h3 class="wp-block-heading">7.5 Confronto di stringhe</h3>



<p>Gli operatori di confronto operano anche sulle stringhe. Per vedere se due stringhe sono uguali:</p>



<h4 class="wp-block-heading">if ;Parola == ;&#8220;BANANA&#8221;:<br>print ; ;&#8220;stai parlando di un frutto!&#8221;<br></h4>



<p>Altri operatori di confronto sono utili per mettere le parole in ordine alfabetico:</p>



<h4 class="wp-block-heading">if ;Parola <; ;&#8220;BANANA&#8221;:<br>print ;&#8220;la tua parola&#8221; ;+ Parola + ;&#8220;viene prima di BANANA.&#8221;<br>elif ;Parola >; ;&#8220;BANANA&#8221;:<br>print ;&#8220;la tua parola&#8221; ;+ Parola + ;&#8220;viene dopo BANANA.&#8221;<br>else:<br>print ;&#8220;hai inserito la parola BANANA&#8221;<br></h4>



<p>Devi comunque fare attenzione al fatto che Python non gestisce le parole maiuscole e minuscole come facciamo noi in modo intuitivo: </p>



<p>in un confronto le lettere maiuscole vengono sempre prima delle minuscole, così che:</p>



<h4 class="wp-block-heading">&#8220;BANANA&#8221; ;<; ;&#8220;BAnana&#8221; ;<; ;&#8220;Banana&#8221; ;<; ;&#8220;bANANA&#8221; ;<; ;&#8220;banana&#8221;<br>&#8220;ZEBRA&#8221; ;<; ;&#8220;banana&#8221;<br></h4>



<p>Un modo pratico per aggirare il problema è quello di convertire le stringhe ad un formato standard (tutto maiuscole o tutto minuscole) prima di effettuare il confronto.</p>



<h3 class="wp-block-heading">7.6 Le stringhe sono immutabili</h3>



<p>Si può essere tentati di usare l&#8217;operatore porzione ;[] ;alla sinistra di un&#8217;assegnazione, con l&#8217;intenzione di cambiare un carattere di una stringa:</p>



<h4 class="wp-block-heading">Saluto = ;&#8220;Ciao!&#8221;<br>Saluto[0] = ;&#8216;M&#8217; ;  ;  ;  ;  ;  ; ;# ERRORE! ;<br>print ;Saluto<br></h4>



<p>Invece di ottenere ;Miao! ;questo codice stampa il messaggio d&#8217;errore ;TypeError: object doesn&#8217;t support item assignment.</p>



<p>Le stringhe sono infatti ;<strong>immutabili</strong> ;e ciò significa che non puoi cambiare una stringa esistente. </p>



<p>L&#8217;unica cosa che puoi eventualmente fare è creare una nuova stringa come variante di quella originale:</p>



<h4 class="wp-block-heading">Saluto = ;&#8220;Ciao!&#8221;<br>NuovoSaluto = ;&#8216;M&#8217; ;+ Saluto[1:]<br>print ;NuovoSaluto<br></h4>



<p>Abbiamo concatenato la nuova prima lettera ad una porzione di ;Saluto, e questa operazione non ha avuto alcun effetto sulla stringa originale.</p>



<h3 class="wp-block-heading">7.7 Funzione ;Trova</h3>



<p>Secondo te cosa fa questa funzione?</p>



<h4 class="wp-block-heading">def ;Trova(Stringa, Carattere):<br>Indice = 0<br>while ;Indice <; len(Stringa):<br>if ;Stringa[Indice] == Carattere:<br>return ;Indice<br>Indice = Indice + 1<br>return ;-1<br></h4>



<p>In un certo senso questa funzione ;Trova ;è l&#8217;opposto dell&#8217;operatore porzione ;[]: invece di prendere un indice e trovare il carattere corrispondente cerca in una stringa la posizione dove appare un carattere e ne restituisce l&#8217;indice. </p>



<h4 class="wp-block-heading">Se il carattere non è presente la funzione restituisce ;-1.</h4>



<p>Questo è il primo esempio di ;return ;all&#8217;interno di un ciclo. Se ;Stringa[Indice] == Carattere ;il ciclo viene interrotto prematuramente. Se il carattere non fa parte della stringa il programma termina normalmente e ritorna ;-1.</p>



<h4 class="wp-block-heading"> Esercizio: </h4>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p>modifica la funzione ;Trova ;per accettare un terzo parametro che rappresenta la posizione dove si deve cominciare a cercare all&#8217;interno della stringa.</p></blockquote>



<h3 class="wp-block-heading">7.8 Cicli e contatori</h3>



<p>Questo programma conta il numero di volte in cui la lettera ;&#8216;a&#8217; ;compare in una stringa, usando un ;<strong>contatore</strong>:</p>



<h4 class="wp-block-heading">Frutto = ;&#8220;banana&#8221;<br>Conteggio = 0<br>for ;Carattere ;in ;Frutto:<br>if ;Carattere == ;&#8216;a&#8217;:<br>Conteggio = Conteggio + 1<br>print ;Conteggio<br></h4>



<p>La variabile ;Conteggio ;è inizializzata a 0 e poi incrementata ogni volta che è trovata una ;&#8216;a&#8217; ;(<strong>incrementare</strong> ;significa aumentare di 1; </p>



<p>è l&#8217;opposto di ;<strong>decrementare</strong>). Al termine del ciclo ;Conteggio ;contiene il risultato e cioè il numero totale di lettere ;a ;nella stringa.</p>



<h4 class="wp-block-heading">Esercizio:</h4>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p>incapsula questo codice in una funzione ;ContaLettera ;e fai in modo che questa accetti sia la stringa che la lettera da cercare come parametri.</p></blockquote>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p>riscrivi la funzione ;ContaLettera ;in modo che invece di elaborare completamente la stringa faccia uso della versione a tre parametri di ;Trova.</p></blockquote>



<h3 class="wp-block-heading">7.9 Il modulo ;string</h3>



<p>Il modulo ;string ;contiene funzioni molto utili per la manipolazione delle stringhe. Come abbiamo già visto prima di poter usare un modulo lo dobbiamo importare:</p>



<h4 class="wp-block-heading">>;>;>; ;import ;string<br></h4>



<p>\fussy Il modulo ;string ;include una funzione chiamata ;find ;che fa le stesse cose della nostra funzione ;Trova. Per poterla usare, dopo avere importato il modulo, dobbiamo chiamarla usando la notazione punto<br>(<em>NomeDelModulo.NomeDellaFunzione</em>):</p>



<h4 class="wp-block-heading">>;>;>; Frutto = ;&#8220;banana&#8221;<br>>;>;>; Posizione = string.find(Frutto, ;&#8220;a&#8221;)<br>>;>;>; ;print ;Posizione<br>1<br></h4>



<p>In realtà ;string.find ;è più generale della nostra ;Trova. In primo luogo possiamo usarla per cercare stringhe e non soltanto caratteri:</p>



<h4 class="wp-block-heading">>;>;>; string.find(&#8220;banana&#8221;, ;&#8220;na&#8221;)<br>2<br></h4>



<p>Inoltre ammette un argomento ulteriore per specificare da dove vogliamo iniziare la nostra ricerca:</p>



<h4 class="wp-block-heading">>;>;>; string.find(&#8220;banana&#8221;, ;&#8220;na&#8221;, 3)<br>4<br></h4>



<p>Ancora, può prendere due argomenti che specificano il dominio di ricerca, cioè la porzione di stringa originale dove vogliamo effettuare la ricerca:</p>



<h4 class="wp-block-heading">>;>;>; string.find(&#8220;bob&#8221;, ;&#8220;b&#8221;, 1, 2)<br>-1<br></h4>



<p>In questo esempio la ricerca fallisce perché la lettera ;&#8216;b&#8217; ;non appare nel dominio definito dagli indici ;1 ;e ;2 ;(da ;1 ;incluso fino a ;2 ;escluso).</p>



<h3 class="wp-block-heading">7.10 Classificazione dei caratteri</h3>



<p>È spesso necessario esaminare un carattere e controllare se questo è maiuscolo, minuscolo, o se si tratta di una cifra o di uno spazio bianco. </p>



<p>A questo scopo il modulo ;string ;fornisce parecchie costanti molto utili.</p>



<p>La stringa ;string.lowercase ;contiene tutti i caratteri che il sistema considera minuscoli. Allo stesso modo ;string.uppercase ;contiene tutti i caratteri maiuscoli. Guarda cosa contengono queste stringhe:</p>



<h4 class="wp-block-heading">>;>;>; ;print ;string.lowercase<br>>;>;>; ;print ;string.uppercase<br>>;>;>; ;print ;string.digits<br></h4>



<p>Possiamo usare queste costanti e la funzione ;find ;per classificare i caratteri. Per esempio se ;find(string.lowercase, Carattere) ;ritorna un valore diverso da ;-1 ;allora ;Carattere ;è minuscolo (un valore diverso da -1 indicherebbe infatti la posizione del carattere trovato):</p>



<h4 class="wp-block-heading">def ;Minuscolo(Carattere):<br>return ;string.find(string.lowercase, Carattere) != -1<br></h4>



<p>In alternativa possiamo usare l&#8217;operatore ;in ;che determina se un carattere compare in una stringa:</p>



<h4 class="wp-block-heading">def ;Minuscolo(Carattere):<br>return ;Carattere ;in ;string.lowercase<br></h4>



<p>o il consueto operatore di confronto:</p>



<p>def ;Minuscolo(Carattere):<br>return ;&#8216;a&#8217; ;<;= Carattere <;= ;&#8216;z&#8217;<br></p>



<p>Se ;Carattere ;è compreso tra ;&#8216;a&#8217; ;e ;&#8216;z&#8217; ;deve per forza trattarsi di una lettera minuscola.</p>



<h4 class="wp-block-heading">Esercizio:</h4>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p>prova a determinare quale di queste versioni è la più veloce. Puoi pensare ad altre ragioni, a parte la velocità, per preferire una versione piuttosto che un&#8217;altra?</p></blockquote>



<p>Un&#8217;altra costante definita nel modulo ;string ;può sorprenderti quando provi a stamparla:</p>



<h4 class="wp-block-heading">>;>;>; ;print ;string.whitespace<br></h4>



<p>I caratteri ;<strong>spazi bianchi</strong> ;infatti muovono il cursore senza stampare nulla: sono questi che creano lo spazio bianco tra i caratteri visibili. </p>



<p>La costante ;string.whitespace ;contiene tutti gli spazi bianchi inclusi lo spazio, la tabulazione (\t) ed il ritorno a capo (\n).</p>



<p>Ci sono molte altre utili funzioni nel modulo ;string ;ma questo libro non è inteso per essere un manuale di riferimento come invece lo è la ;<em>Python Library Reference</em>, </p>



<p>disponibile al sito ufficiale del linguaggio Python ;<a href="http://www.python.org/">www.python.org</a>.</p>