Track
/
Julia
Julia
/
Esercizi
/
Lindo e pulito
Lindo e pulito

Lindo e pulito

Esercizio di apprendimento

Introduzione

Questo è un argomento grande! Si può scrivere un lungo libro al riguardo, ediverse persone l'hanno fatto (cerca «unicode book» su Amazon per vedere qualche esempio).

Una brevissima storia

Gestire i caratteri nei computer era molto più semplice nei decenni passati, quando i programmatori davano per scontato che l'inglese fosse l'unica lingua importante. Quindi: 26 lettere, maiuscole e minuscole, 10 cifre, alcuni segni di punteggiatura, più un codice (0x07) per far suonare un campanello, ed il tutto stava in 7 bit: l'insieme di caratteri ASCII.

Naturalmente, le persone hanno cominciato a chiedersi: e à, ä e Ł? Poi altre persone hanno cominciato a chiedersi: e ऄ, ஹ e ญ? Ed i giovani volevano le emoji 😱. Che fare?

Per farla breve, molte persone intelligenti e pazienti hanno dovuto far parte di comitati per anni, definendo i dettagli dell'insieme di caratteri Unicode e di codifiche come UTF-8, e moltissimo software ha avuto bisogno di una riscrittura molto complicata. Inoltre, sono stati introdotti molti nuovi bug.

Per evitare che tutto si rompa, il design di Unicode/UTF-8 garantisce che i primi 127 codici siano identici a quelli dell'ASCII (anche il campanello).

I caratteri in Julia

I linguaggi progettati dopo il 2005 circa hanno l'enorme vantaggio che esisteva già uno standard Unicode ragionevolmente stabile.

Julia (rilasciato per la prima volta nel 2012) ha potuto dare per scontato che tutto sarebbe stato Unicode: caratteri, stringhe, nomi di variabili e funzioni, operatori matematici...

Per citare il manuale: «Julia rende semplice ed efficiente la gestione del testo ASCII semplice, e la gestione di Unicode è il più semplice ed efficiente possibile». Nota quel «possibile»: è una parte importante di quanto afferma.

I letterali di carattere si scrivono tra apici singoli e sono distinti dalle stringhe, che si scrivono tra virgolette doppie.

Questo è ovvio per chi viene dal mondo C/C++, ma può confondere chi programma in Python e Javascript.

julia> a = 'a'  # Roman alphabet
'a': ASCII/Unicode U+0061 (category Ll: Letter, lowercase)

julia> typeof(a)
Char

julia> jha = 'झ'  # Devanagari alphabet
'झ': Unicode U+091D (category Lo: Letter, other)

julia> typeof(jha)
Char

julia> '❤'  # heart emoji
'❤': Unicode U+2764 (category So: Symbol, other)

Dagli esempi vediamo che il tipo è Char, e Julia ha ulteriori informazioni sulla categoria del carattere.

Guardando più da vicino, sembra che questi caratteri si possano rappresentare con 4 cifre esadecimali. L'insieme completo di caratteri ne richiede fino a 6.

Questi numeri si chiamano «punti di codice» ed attualmente vanno da U+0000 a U+10FFFF. Si visualizzano nella REPL, ma nel codice usa codepoints() per ottenerli.

Convertire tra Char e Int è semplice:

julia> Int('a')
97

julia> Char(97)
'a': ASCII/Unicode U+0061 (category Ll: Letter, lowercase)

Il compilatore consente alcune forme di aritmetica tra interi sui Char:

julia> 'b' - 'a'  # interval, in alphabetic order
1

julia> 'b' + 'a'
ERROR: MethodError: no method matching +(::Char, ::Char)

julia> 'a' + 5
'f': ASCII/Unicode U+0066 (category Ll: Letter, lowercase)

julia> 'f' + ('A' - 'a')  # same as `uppercase('f')`
'F': ASCII/Unicode U+0046 (category Lu: Letter, uppercase)

Funzioni per i caratteri

Molte funzioni che gestiscono stringhe possono funzionare anche con input di tipo Char.

  • Per gli alfabeti appropriati, trasforma tra maiuscolo e minuscolo con uppercase() e lowercase().
  • Controlla maiuscole e minuscole con isuppercase() e islowercase().
  • Verifica il tipo di carattere con:
    • isletter() copre molti alfabeti
    • isdigit(), verifica se è strettamente tra 0:9
    • isnumeric(), più ampio di isdigit, quindi true per ¾ e per varie scritture non europee
    • isxdigit(), cifre esadecimali
    • isascii(), caratteri precedenti a Unicode
    • ispunct(), punteggiatura
    • isspace(), qualsiasi carattere di spazio bianco
    • isprint(), caratteri stampabili (l'opposto è iscntrl())
islowercase('A')  # false
uppercase('γ')  # 'Γ': Unicode U+0393 (category Lu: Letter, uppercase)
ispunct('@')  # true
isdigit('A')  # false
isxdigit('A')  # true

Conversioni tra vettori di Char e stringhe

Per passare da una stringa a un vettore di Char, possiamo usare collect().

Per passare da un vettore di Char a una stringa, c'è il costruttore String().

julia> s = "abcde"
"abcde"

julia> cv = collect(s)
5-element Vector{Char}:
 'a': ASCII/Unicode U+0061 (category Ll: Letter, lowercase)
 'b': ASCII/Unicode U+0062 (category Ll: Letter, lowercase)
 'c': ASCII/Unicode U+0063 (category Ll: Letter, lowercase)
 'd': ASCII/Unicode U+0064 (category Ll: Letter, lowercase)
 'e': ASCII/Unicode U+0065 (category Ll: Letter, lowercase)

julia> String(cv)
"abcde"

Funziona con qualsiasi carattere, non solo con l'ASCII.

julia> collect("❤,😱")
3-element Vector{Char}:
 '❤': Unicode U+2764 (category So: Symbol, other)
 ',': ASCII/Unicode U+002C (category Po: Punctuation, other)
 '😱': Unicode U+1F631 (category So: Symbol, other)

Nota che il costruttore String() opera su un vettore. Per fare il cast di un singolo Char in una stringa di un solo carattere, la funzione è string(), con la s minuscola.

julia> string('a')
"a"

Memorizzazione

Tutto quello che abbiamo visto finora in questo documento sembra relativamente semplice, quindi davvero non c'è molto di cui preoccuparsi?

Purtroppo, questo è troppo ottimistico!

Una complicazione deriva dalla necessità di «fino a» 6 cifre esadecimali per ogni punto di codice. Questo significa che caratteri diversi richiedono quantità diverse di spazio in memoria quando sono codificati in UTF-8.

Un byte può memorizzare solo numeri (senza segno) fino a 255, due cifre esadecimali, quindi UTF-8 usa un numero variabile di byte (da 1 a 4) per memorizzare un Char. Questi si chiamano «unità di codice», e la funzione ncodeunits() restituisce il numero necessario per un dato carattere.

julia> codepoint(jha)  # jha 'झ' is defined in an earlier example
0x0000091d

julia> ncodeunits(jha)
3

julia> ncodeunits('a')  # ASCII character
1

julia> ncodeunits('😱')  # emoji
4

Inoltre, non tutto ciò che può essere visualizzato sullo schermo ha un proprio punto di codice univoco. Alcuni caratteri visivamente distinti sono considerati derivati da altri, quindi Unicode li tratta come un carattere base più un modificatore.

Questo problema riguarda le stringhe, dove presenta delle difficoltà per l'indicizzazione.

Istruzioni

In questo esercizio implementerai una serie parziale di routine di utilità per aiutare uno sviluppatore a ripulire i nomi degli identificatori.

Nelle 6 attività costruirai gradualmente le funzioni transform, per convertire singoli caratteri, e clean, per convertire le stringhe.

Un identificatore valido è composto da zero o più lettere, underscore, trattini, punti interrogativi ed emoji.

Se alla funzione clean viene passata una stringa vuota, deve essere restituita una stringa vuota.

1. Sostituisci ogni trattino incontrato con un underscore

Implementa la funzione transform per sostituire ogni trattino con un underscore.

julia> transform('-')
"_"

2. Rimuovi tutti gli spazi bianchi

Rimuovi tutti i caratteri di spazio bianco. Questo include gli spazi bianchi all'inizio e alla fine.

julia> transform(' ')
""

3. Converti il camelCase in kebab-case

Modifica la funzione transform per convertire il camelCase in kebab-case

julia> transform('D')
"-d"

4. Ometti i caratteri che sono cifre

Modifica la funzione transform per omettere i caratteri numerici.

julia> transform('7')
""

5. Sostituisci le lettere greche minuscole con punti interrogativi

Modifica la funzione transform per sostituire le lettere greche nell'intervallo da 'α' a 'ω'.

julia> transform('β')
"?"

6. Combina queste operazioni per lavorare su una stringa

Implementa la funzione clean per applicare queste operazioni a un'intera stringa.

I caratteri che non rientrano in queste regole devono passare invariati.

julia> clean("  a2b Cd-ω😀  ")
"ab-cd_?😀"
Modifica tramite GitHub Il link si apre in una nuova finestra o scheda
Julia Exercism

Vuoi iniziare Lindo e pulito?

Iscriviti a Exercism per imparare e padroneggiare Julia con 35 concetti128 esercizi e il mentoring di persone reali, tutto gratis.