Track
/
Python
Python
/
Esercizi
/
Parsing di SGF
Parsing di SGF

Parsing di SGF

Medio

Istruzioni

Fare il parsing di una stringa in Smart Game Format.

SGF è un formato standard per memorizzare file di giochi da tavolo, in particolare il go.

L'SGF è un formato piuttosto semplice. Un file SGF di solito contiene un singolo albero di nodi, dove ogni nodo è una lista di proprietà. La lista di proprietà contiene coppie chiave-valore: ogni chiave può comparire una sola volta, ma può avere più valori.

L'esercizio ti chiederà di fare il parsing di una stringa SGF e di restituire una struttura ad albero di proprietà.

Un file SGF può avere questo aspetto:

(;FF[4]C[root]SZ[19];B[aa];W[ab])

Questo è un albero con tre nodi:

  • Il nodo di livello superiore ha tre proprietà: FF[4] (chiave = "FF", valore = "4"), C[root](chiave = "C", valore = "root") e SZ[19] (chiave = "SZ", valore = "19"). (FF indica la versione di SGF, C è un commento e SZ è la dimensione del tabellone.)
    • Il nodo di livello superiore ha un solo figlio, che ha una sola proprietà: B[aa]. (Il nero gioca sul punto codificato come "aa", che è il punto 1-1.)
      • Il nodo B[aa] ha un solo figlio, che ha una sola proprietà: W[ab].

Come puoi immaginare, un file SGF contiene molti nodi con un solo figlio, ed è per questo che esiste una forma abbreviata.

L'SGF può codificare varianti di gioco. I giocatori di go fanno molti passi indietro durante le loro revisioni (proviamo questo, non funziona, proviamo quello) e l'SGF supporta le varianti delle sequenze di gioco. Per esempio:

(;FF[4](;B[aa];W[ab])(;B[dd];W[ee]))

Qui il nodo radice ha due varianti. La prima (che per convenzione indica ciò che è stato effettivamente giocato) è quella in cui il nero gioca su 1-1. Il nero ha ricevuto questo file dal suo insegnante, che gli ha fatto notare una giocata più sensata nel secondo figlio del nodo radice: B[dd] (punto 4-4, un'apertura molto standard per prendere l'angolo).

Una chiave può avere più valori associati. Per esempio:

(;FF[4];AB[aa][ab][ba])

Qui AB (aggiungi nero) viene usato per aggiungere tre pietre nere al tabellone.

Tutti i valori delle proprietà saranno del tipo Text dell'SGF. Non devi implementare nessun altro tipo di valore. Anche se puoi leggere la documentazione completa del tipo Text, qui sotto trovi un riassunto dei punti importanti:

  • Le interruzioni di riga vengono rimosse se seguono immediatamente un \, altrimenti restano come interruzioni di riga.
  • Tutti i caratteri di spaziatura diversi dall'interruzione di riga vengono convertiti in spazi.
  • \ è il carattere di escape. Qualsiasi carattere non di spaziatura dopo \ viene inserito così com'è. Qualsiasi carattere di spaziatura dopo \ segue le regole precedenti. Nota che l'SGF non ha sequenze di escape per i caratteri di spaziatura come \t o \n.

Fai attenzione a non confondere:

  • La stringa così come è rappresentata in un letterale stringa nei test
  • La stringa che viene passata al parser SGF

Le sequenze di escape nei letterali stringa potrebbero essere già state elaborate dal parser del linguaggio di programmazione prima di essere passate al parser SGF.

Ci sono alcune altre complessità nel SGF (e nel parsing in generale) che puoi per lo più ignorare. Devi presumere che l'input sia codificato in UTF-8, i test non conterranno alcuna proprietà charset, quindi non preoccuparti di questo. Inoltre puoi presumere che tutte le interruzioni di riga siano in stile unix (\n, nessun \r o \r\n sarà presente nei test) e che nei test non ci sarà alcuna spaziatura opzionale tra proprietà, nodi, ecc.

Messaggi di eccezione

A volte è necessario sollevare un'eccezione. Quando lo fai, dovresti sempre includere un messaggio di errore significativo per indicare qual è l'origine dell'errore. Questo rende il codice più leggibile e aiuta molto durante il debug. Quando sai che l'origine dell'errore sarà di un certo tipo, puoi scegliere di sollevare uno dei tipi di errore predefiniti, ma dovresti comunque includere un messaggio significativo.

Questo esercizio in particolare richiede che tu usi l'istruzione raise per «lanciare» un ValueError se l'input non ha i delimitatori corretti, non è in maiuscolo, non forma un albero con dei nodi, o non forma affatto un albero. I test passeranno solo se, oltre a usare raise per l'exception, includi anche un messaggio.

Per sollevare un ValueError con un messaggio, scrivi il messaggio come argomento del tipo exception:

# if the tree properties as given do not have proper delimiters.
raise ValueError("properties without delimiter")

# if the tree properties as given are not all in uppercase.
raise ValueError("property must be in uppercase")

# if the input does not form a tree, or is empty.
raise ValueError("tree missing")

# if the input is a tree without any nodes.
raise ValueError("tree with no nodes")
Modifica tramite GitHub Il link si apre in una nuova finestra o scheda
Python Exercism

Vuoi iniziare Parsing di SGF?

Iscriviti a Exercism per imparare e padroneggiare Python con 17 concetti146 esercizi e il mentoring di persone reali, tutto gratis.