Ollama: Ottimizzare la Finestra di Contesto (Context Window)

Lavorando con risorse ristrette (neanche tanto, ho 20 GB di VRAM sulla scheda, ma comunque poche per modelli oltre una certa dimensione), devo limitare la Finestra di Contesto, ovvero, quella zona di memoria usata dall’LLM per immagazzinare i dati che gli diamo in pasto (prompt, file, …).

Più è grande questa finestra, più il modello ha capacità di immagazzinare dati e svolgere lavori sempre più complessi, tuttavia, questo aumenta linearmente la richiesta di memoria al sistema, superata la quale, viene utilizzato un meccanismo (da parte di Ollama, in questo caso, ma immagino che anche gli altri software analoghi adottino la medesima tecnica) di sdoppiamento tra VRAM e RAM; in altri termini, i layer che compongono il modello, vengono suddivisi tra VRAM e RAM e il risultato è che si riesce a far girare comunque un modello che non riuscirebbe a risiedere nella sola VRAM, salvo riducendo la finestra di contesto a valori che poi lo rendono pressoché inutile (ovviamente parliamo di modelli per hardware terrestre).

Tuttavia, questa modalità, ha una penalizzazione: il drastico crollo delle prestazioni.

Quindi?

Sei fottuto.

Spera che la riduzione della finestra non debba scendere sotto i 64k, altrimenti, forse è meglio evitare. Per come la penso io (e dai test che ho fatto), il minimo sindacale è 32k, non meno, sotto: lascia perdere.

Ma come si fa?

Ecco i passaggi:

  1. Creati una cartella (ad es.: Qwen-27B-48k , per un modello che deve avere la finestra a 48k, che però è solo un nome mnemonico, non stabilisce la dimensione voluta, ci fa solo ricordare per cosa è stata creata la cartella); dimenticavo, il tutto va fatto da terminale, quindi Alt+x i (su Windows), quindi mkdir Qwen-27B-48k.
  2. All’interno della cartella ci dobbiamo creare un file “Modelfile”, ad esempio: edit Modelfile_48k.
  3. Il contenuto del file in questione deve essere analogo a questo di esempio:
FROM Qwen3.8-27B
PARAMETER num_ctx 49152

La misura del contesto va espressa in byte, quindi, dobbiamo ipotizzare la misura che desideriamo; solitamente i tagli sono 4k, 8k, 16k, 32k, 64k, 128k, 256k ma nulla vieta di fare tagli intermedi, importante è che siano interi e soprattutto, moltiplicare il taglio scelto per 1024, quindi, se ad esempio scegliamo 48k (un taglio intermedio), abbiamo: 48 * 1024 = 49152.

Potrebbe sorgere spontanea (anzi, dovrebbe) la domanda: ma in che modo ipotizzo la misura di contesto ottimale per il mio hardware?

Il metodo ortodosso non so quale sia, io mi sono arrangiato con un metodo empirico: lancio il modello e con ollama ps vedo come viene suddiviso e in base a questa informazione riduto per ottenere l’occupazione della VRAM ottimale.

Ad esempio ho provato un modello quantizzato a 4 bit e de-censurato di Qwen3.8-27b (sì, lo so, è un casino, tra finestre di contesto, layer, quantizzazione, ecc., un sacco di roba molto nebulosa, ma così è …) e questo è il risultato sul mio hardware (che ha 20 GB di VRAM e 64 GB di RAM):

ollama ps
NAME                                        ID              SIZE     PROCESSOR          CONTEXT    UNTIL
orcarouter/Qwen3.8-27B-Uncensored:iq4_xs    84e6355d6764    34 GB    48%/52% CPU/GPU    262144     4 minutes from now   

Come si può notare, ben il 52% è collocato in RAM; questo significa che richiede oltre 40 GB di VRAM per girare (e già è quantizzato scarso).

Invece, con contesto a 48k, questo il risultato:

NAME                   ID              SIZE     PROCESSOR    CONTEXT    UNTIL
Qwen-27B-48k:latest    b5fff7ca760e    18 GB    100% GPU     49152      4 minutes from now

Come si può notare, risiede completamente nella VRAM!
Questo implica prestazioni e stabilità completamente diverse dalla situazione precedente.

5. L’ultimo passaggio consiste nel creare il modello, ad esempio:

ollama create Qwen-27B-48k -f Modelfile_48k

Dopodiché, vi basta un semplice ollama run Qwen-27B-48k per lanciarlo e ollama ps (in un altro terminale) per vedere il consumo di risorse.

Da lì potete aumentare o calare con il contesto (importante: ricordarsi di modificare il Modelfile, tipicamente mi scordo di farlo!) per ottimizzare alle vostre esigenze.

Linux: cambiare cartella corrente navigando con le frecce della tastiera

Per come è intrinsecamente sviluppato il kernel di Linux, non risulta possibile creare un’app che:
1. L’utente lancia.
2. Naviga nella cartella desiderata.
3. Esce e si trova nella cartella desiderata.

Per farlo bisogna adottare un escamotage.

Come prima cosa, consiglio di installare “nnn” (o n3), tramite sudo apt install nnn .

Dopodichè, bisogna creare o aggiungere al file ~/.bash_aliases il seguente codice:

n() {
    # Blocca un file temporaneo per memorizzare l'ultima directory
    export NNN_TMPFILE="${XDG_CONFIG_HOME:-$HOME/.config}/nnn/.lastd"

    # Avvia nnn
    nnn "$@"

    # Legge l'ultima directory ed esegue il cd se il file esiste
    if [ -f "$NNN_TMPFILE" ]; then
        . "$NNN_TMPFILE"
        rm -f "$NNN_TMPFILE"
    fi
}

Per farlo è sufficiente un nano ~/.bash_aliases è incollare il codice sopra, quindi, riavviare il terminale.

Dopodiché, con n parte il programma, con le frecce ci si sposta e con q si esce nella cartella scelta!

Il programma nnn è un file manager minimale e atipico, con ? si ottiene la guida agli altri comandi disponibili, a voi la scelta se usarli o meno.

Ollama: Prova empirica con Finestre di Contesto (ContextWindow) diverse

Ho a disposizione una workstation HP Z2, con processore Inter(R) Core(TM) i9-14900K, 64 GB di RAM, Scheda video NVIDIA RTX A4500 20 GB.

Su questa macchina ci ho installato Ollama e alcuni modelli.

Tramite il setup di ollama, ho provato a fare inferenza modificando la “ContextWindow” (Finestra di Contesto), uno dei parametri fondamentali affinché i modelli riescano fattivamente a realizzare un ragionamento compiuto e prolungato (non la semplice domanda, ma proprio una discussione, un lavoro, ecc.).

Più è grande la finestra di contesto, più il modello riuscirà ad immagazzinare informazioni ed elaborarle, ragionandoci sopra (se previsto il ragionamento).

Ma è chiaro che, all’aumentare di questa finestra, Ollama deve allocare sempre più risorse (in realtà, come si vedrà poi dalla tabella di comparazione, non sempre) hardware: prima andrà ad occupare la VRAM (la memoria della scheda video), quindi farà uno “split” e userà la RAM di sistema; nel mio caso specifico sono esattamente 20 GB (VRAM) e 64 GB (RAM).

Tuttavia, ho constatato alcuni aspetti fondamentali:

  1. Finché il modello gira totalmente in VRAM, le prestazioni sono ottime, al pari di un servizio online a pagamento (ChatGPT, Claude, Gemini, ecc.).
  2. Appena il contesto non riesce più ad essere allocato in VRAM, Ollama “spezza” e qui le prestazioni crollano, ma non solo perché …
  3. … ho constatato che anche i crash del modello si fanno MOLTO più probabili.

Quindi: scegliere la finestra di contesto in base al modello e al proprio hardware, diventa estremamente dirimente, fa la differenza tra “tirare fuori un lavoro anziché un fallimento”.

Da qui nasce la mia idea di fare una tabella comparativa dove, semplicemente, ho provato a fare inferenza su tre modelli che sto usando (siamo a Settembre 2026) con soddisfazione, ma variando la Finestra di Contesto dal minimo di 4K fino al massimo di 256K (4K, 8K, 16K, 32K, 64K, 128K, 256K).

Ecco il risultato:

NameIDSizeProcessorContext
orcarouter/Qwen3.8-27B-Uncensored:iq4_xs84e6355d676434 GB48%/52% CPU/GPU262144
orcarouter/Qwen3.8-27B-Uncensored:iq4_xs84e6355d676425 GB28%/72% CPU/GPU131072
orcarouter/Qwen3.8-27B-Uncensored:iq4_xs84e6355d676420 GB10%/90% CPU/GPU65536
orcarouter/Qwen3.8-27B-Uncensored:iq4_xs84e6355d676417 GB100% GPU32768
orcarouter/Qwen3.8-27B-Uncensored:iq4_xs84e6355d676416 GB100% GPU16384
orcarouter/Qwen3.8-27B-Uncensored:iq4_xs84e6355d676415 GB100% GPU8192
orcarouter/Qwen3.8-27B-Uncensored:iq4_xs84e6355d676415 GB100% GPU4096
gemma4:26b5571076f3d7018 GB32%/68% CPU/GPU262144
gemma4:26b5571076f3d7018 GB17%/83% CPU/GPU131072
gemma4:26b5571076f3d7018 GB10%/90% CPU/GPU65536
gemma4:26b5571076f3d7017 GB100% GPU32768
gemma4:26b5571076f3d7017 GB100% GPU16384
gemma4:26b5571076f3d7017 GB100% GPU8192
gemma4:26b5571076f3d7017 GB100% GPU4096
gpt-oss:20b17052f91a42e12 GB100% GPU131072
gpt-oss:20b17052f91a42e12 GB100% GPU65536
gpt-oss:20b17052f91a42e12 GB100% GPU32768
gpt-oss:20b17052f91a42e12 GB100% GPU16384
gpt-oss:20b17052f91a42e12 GB100% GPU8192
gpt-oss:20b17052f91a42e12 GB100% GPU4096
ornith-1.5:9be5df7dcdd8a214 GB100% GPU262144
ornith-1.5:9be5df7dcdd8a29.9 GB100% GPU131072
ornith-1.5:9be5df7dcdd8a27.8 GB100% GPU65536
ornith-1.5:9be5df7dcdd8a26.7 GB100% GPU32768
ornith-1.5:9be5df7dcdd8a26.1 GB100% GPU16384
ornith-1.5:9be5df7dcdd8a25.8 GB100% GPU8192
ornith-1.5:9be5df7dcdd8a25.6 GB100% GPU4096

Analizzando la tabella, si possono fare alcune considerazioni:

  • Non è il numero di parametri a fare la differenza. Le diverse strutture interne degli LLM fanno una certa differenza, tant’è che “Qwen3.8:27b” è molto più esoso di risorse (da 64K in poi, prima sono analoghi) di un “Gemini4:26b” che ha “solo” 1b di differenza.
  • Esiste un caso emblematico fornito da “gpt-oss:20b”, il quale, ha comunque una finestra massima di 128K, ma consuma comunque la stessa RAM, indipendentemente dal contesto attribuito da Ollama.
  • Infine abbiamo “ornith-1.5:9b” che occupa pochissimo e riesce a stare sempre in VRAM, probabilmente anche su una scheda da 16 GB (la mia ha 20 GB, ma è una misura sfigata, l’ideale credo sarebbe 24 GB, molto più standard e che mi consentirebbe di arrivare tranquillamente a 64K anche con i modelli più grandi).

Ho provato (solo a livello di inferenza, non variando il contesto) in passato molti altri modelli, ma – quantomeno a livello “agentico” – non mi hanno dato grandi soddisfazioni.

Se usati solo come chatbot, effettivamente ce ne sarebbero diversi altri interessanti, penso a “mistral:7b” o il velocissimo “lfm2:24b”.

Se qualcuno vuole consigliarmi altri modelli da provare o ha suggerimenti o commennti, non esiti a scrivermi!

Pi Coding Agent non funziona su Windows 11

Provando ad eseguire “Pi Coding Agent” su Windows 11 mi usciva questo errore:

pi exiting due to uncaughtException:
TypeError: zlib.createZstdDecompress is not a function
    at Object.onResponseStart (file:///C:/Users/andrea.orlando/AppData/Roaming/npm/node_modules/@earendil-works/pi-coding-agent/dist/bundle/chunks/chunk-OMWWHBTG.js:268:70392)
    at Request.onResponseStart (file:///C:/Users/andrea.orlando/AppData/Roaming/npm/node_modules/@earendil-works/pi-coding-agent/dist/bundle/chunks/chunk-OMWWHBTG.js:141:145989)
    at Parser2.onHeadersComplete (file:///C:/Users/andrea.orlando/AppData/Roaming/npm/node_modules/@earendil-works/pi-coding-agent/dist/bundle/chunks/chunk-OMWWHBTG.js:152:15221)
    at wasm_on_headers_complete (file:///C:/Users/andrea.orlando/AppData/Roaming/npm/node_modules/@earendil-works/pi-coding-agent/dist/bundle/chunks/chunk-OMWWHBTG.js:152:6943)
    at wasm://wasm/00034eea:wasm-function[10]:0x571
    at wasm://wasm/00034eea:wasm-function[20]:0x845f
    at Parser2.execute (file:///C:/Users/andrea.orlando/AppData/Roaming/npm/node_modules/@earendil-works/pi-coding-agent/dist/bundle/chunks/chunk-OMWWHBTG.js:152:9713)
    at Parser2.readMore (file:///C:/Users/andrea.orlando/AppData/Roaming/npm/node_modules/@earendil-works/pi-coding-agent/dist/bundle/chunks/chunk-OMWWHBTG.js:152:9059)
    at TLSSocket.onHttpSocketReadable (file:///C:/Users/andrea.orlando/AppData/Roaming/npm/node_modules/@earendil-works/pi-coding-agent/dist/bundle/chunks/chunk-OMWWHBTG.js:152:19492)
    at TLSSocket.emit (node:events:518:28)
Error: exit status 1

Ho provato a sistemare con questo comando:

npm install -g @earendil-works/pi-coding-agent@latest

Che auspicabilmente doveva aggiornare l’installazione di Pi Coding Agent, ma per tutta risposta ricevevo:

npm warn EBADENGINE Unsupported engine {
npm warn EBADENGINE   package: '@earendil-works/pi-coding-agent@0.84.4',
npm warn EBADENGINE   required: { node: '>=22.19.0' },
npm warn EBADENGINE   current: { node: 'v22.14.0', npm: '11.12.1' }
npm warn EBADENGINE }
npm warn deprecated node-domexception@1.0.0: Use your platform's native DOMException instead

changed 136 packages in 11s

15 packages are looking for funding
  run `npm fund` for details

Ho quindi cercato di capire come NodeJs fosse stato installato con:

Get-Command node | Select-Object -ExpandProperty Source

E la risposta è stata: C:\Program Files\nodejs\node.exe

Da qui ho tentato l’aggiornamento tramite winget upgrade OpenJS.NodeJS ma, ancora, ottenevo un altro errore:

Prima di usare l'origine `msstore`, è necessario visualizzare i contratti seguenti.
Terms of Transaction: https://aka.ms/microsoft-store-terms-of-transaction
L'origine richiede che l'area geografica di 2 lettere del computer corrente venga inviata al servizio back-end per funzionare correttamente ,ad esempio "STATI Uniti".

Accetti tutte le condizioni dei contratti di origine?
[Y] Sì  [N] No:
[Y] Sì  [N] No: y
Non è stato trovato alcun pacchetto installato corrispondente ai criteri di input.

Per sistemare anche questo ho usato: winget upgrade --query Node.js e finalmente è partito “pi” usando il comando ollama launch pi.

Pi Coding Agent su Windows 11

Tentando di eseguirlo su Windows 11 in una PowerShell mi è uscito questo messaggio di errore:

pi : Impossibile caricare il file C:\Users\Utente\AppData\Roaming\npm\pi.ps1. L'esecuzione di script è disabilitata nel sistema in uso. Per ulteriori informazioni, vedere about_Execution_Policies
all'indirizzo https://go.microsoft.com/fwlink/?LinkID=135170.
In riga:1 car:1
+ pi
+ ~~
    + CategoryInfo          : Errore di protezione: (:) [], PSSecurityException
    + FullyQualifiedErrorId : UnauthorizedAccess

Per risolvere il problema ho usato questo comando:

Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser

Dopodiché, usando il comando pi è partito come previsto.

Eseguire un bat che si “auto-invoca” per richiedere i privilegi di amministratore (se non presenti) e restituisce un codice di uscita.

Il comando di esempio che propongo come soluzione è questo:
powershell -WorkingDirectory "C:\cartella\di\lavoro\raggiungibile\da\admin" -Command "$p = Start-Process cmd.exe -ArgumentList '/c', 'C:\percorso\raggiungibile\da\admin\script.bat', '/comando1', '\"C:\un percorso con spazi\giusto\di\esempio\"', 'PARAMETRO3' -Verb RunAs -Wait -PassThru; exit $p.ExitCode"

Leggi tutto: Eseguire un bat che si “auto-invoca” per richiedere i privilegi di amministratore (se non presenti) e restituisce un codice di uscita.

Scenario: ho un file bat che deve eseguire delle operazioni con privilegi elevati (nel mio caso specifico, giusto per dare un esempio: registrare una DLL che rappresenta un Add-in del CAD SolidWorks) e – se non trovati – auto-invocarsi dopo aver chiesto le credenziali di amministratore, attendere che la “propria copia” eseguita nel “cmd.exe” appositamente creato faccia il suo lavoro e termini con un codice di uscita, il quale, deve poi essere catturato dal processo iniziale e gestito.

Lo so, scritta così, è un po’ “arzigogolata” la cosa; una AI la scriverebbe così:

Ho un file batch che deve eseguire operazioni con privilegi elevati (ad esempio, registrare una DLL che funge da add‑in per SolidWorks). Se la DLL non è presente, il batch deve:

  1. Richiedere le credenziali di amministratore.
  2. Ri‑eseguire se stesso in una nuova istanza di cmd.exe con i privilegi ottenuti.
  3. Attendere che la copia “eseguita” completi il lavoro e termini con un codice di uscita.
  4. Catturare quel codice di uscita nella sessione originale e gestirlo di conseguenza.

Forse sono io che ho posto male la domanda all’AI quando gli ho chiesto di realizzare la cosa ma, avendo tribolato molto per ottenere un risultato funzionante, magari l’esempio sopra può servire a qualche disperato come me.

Per quanto riguarda il comando di esempio, espongo la relativa descrizione (sempre fatta da AI):

Spiegazione dettagliata del comando

powershell `
  -WorkingDirectory "C:\cartella\di\lavoro\raggiungibile\da\admin" `
  -Command "$p = Start-Process cmd.exe `
              -ArgumentList '/c', `
                           'C:\percorso\raggiungibile\da\admin\script.bat', `
                           '/comando1', `
                           '\"C:\un percorso con spazi\giusto\di\esempio\"', `
                           'PARAMETRO3' `
              -Verb RunAs `
              -Wait `
              -PassThru; `
          exit $p.ExitCode"

1. powershell – avvio di PowerShell

Il comando è eseguito da un prompt di comando (cmd.exe) o da un altro script batch.
powershell lancia una nuova istanza di PowerShell in modalità interattiva (o in modalità script, a seconda del contesto).


2. -WorkingDirectory "C:\cartella\di\lavoro\raggiungibile\da\admin"

Imposta la cartella di lavoro corrente della sessione PowerShell.
Tutto ciò che viene eseguito all’interno di PowerShell (ad esempio i file batch o i comandi) verrà cercato in questa directory se non viene specificato un percorso assoluto.


3. -Command "<script>"

Il parametro -Command indica a PowerShell di eseguire immediatamente la stringa di script che segue.
La stringa è racchiusa tra virgolette doppie ("), quindi è interpretata come un unico argomento per PowerShell.


4. $p = Start-Process cmd.exe ...

a. $p =

La variabile $p conterrà l’oggetto Process restituito da Start-Process.
Questo oggetto fornisce, tra le altre cose, la proprietà ExitCode che verrà usata alla fine.

b. Start-Process cmd.exe

Avvia un nuovo processo cmd.exe.
Questo è il motivo per cui il comando è avvolto in PowerShell: Start-Process è un cmdlet nativo di PowerShell, non di cmd.exe.

c. -ArgumentList '/c', 'C:\percorso\raggiungibile\da\admin\script.bat', '/comando1', '\"C:\un percorso con spazi\giusto\di\esempio\"', 'PARAMETRO3'

-ArgumentList specifica gli argomenti che verranno passati a cmd.exe.

  • '/c' dice a cmd.exe di eseguire il comando che segue e poi chiudersi.
  • 'C:\percorso\raggiungibile\da\admin\script.bat' è il file batch da eseguire.
  • '/comando1', '\"C:\un percorso con spazi\giusto\di\esempio\"', 'PARAMETRO3' sono gli argomenti che il batch riceverà.
  • L’argomento con spazi è racchiuso tra virgolette doppie (\"...\") per garantire che venga passato come un singolo parametro a cmd.exe.
  • Le virgolette doppie sono escape (\") perché la stringa è già racchiusa tra virgolette doppie di PowerShell.

d. -Verb RunAs

Chiede a Windows di eseguire il processo con privilegi elevati (prompt UAC).
Se l’utente non è già amministratore, verrà mostrata la finestra di dialogo “Richiesta di credenziali”.

e. -Wait

Il comando PowerShell attende che il processo cmd.exe termini prima di continuare.
Ciò garantisce che il batch abbia finito di lavorare prima di procedere.

f. -PassThru

Restituisce l’oggetto Process (che viene assegnato a $p).
Se non fosse presente, $p sarebbe null e non si potrebbe leggere ExitCode.


5. exit $p.ExitCode

Dopo che cmd.exe è terminato, PowerShell esce con lo stesso codice di uscita del processo avviato.
Questo è fondamentale se il batch viene chiamato da un altro script o da un sistema di automazione: il valore di ritorno indica se l’operazione è andata a buon fine o se è stato riscontrato un errore.


Riepilogo in un unico flusso

  1. PowerShell viene lanciata con una cartella di lavoro specificata.
  2. All’interno di PowerShell, si avvia cmd.exe con:
    • cmd.exe /c script.bat … (il batch e i suoi argomenti)
    • privilegi elevati (RunAs)
    • attesa della terminazione (-Wait)
    • restituzione dell’oggetto processo (-PassThru)
  3. Una volta terminato il batch, PowerShell termina con lo stesso codice di uscita del batch.

Word: apre tutti i file .doc in modalità compatibilità

Apri un doc su un PC e lo vedi bene, lo apri su un altro e ti si apre come in figura:

Cioè: in Modalità compatibilità.

Il modo semplice per risolvere il problema è usare il menu: Visualizza > Modifica documento, come mostrato in figura:

Dovrebbe tornare subito in modo simile a questo:

Il pulsante evidenziato è quello che puà causare il problema, ad esempio se premuto inavvertitamente.

Se ti ho salvato, lascia un like, grazie!

Tastiera Italiana per Sviluppatori

Purtroppo, la tastiera italiana di default (quantomeno su Windows 11) fa schifo, mancano alcune sequenze comode, obbligando ad arrangiarsi con il tastierino numerico.
Ad esempio manca l’accento grave (`) e la tilde (~).

Per risolvere il problema ho scaricato ed installato (dopo aver controllato tramite VirusTotal ) un software che aggiunge la tastiera italiana, lo trovate (spero) a questo link (si tratta di una condivisione su OneDrive, non il massimo, lo ammetto … e sia chiaro: non è roba mia e non ho idea di chi l’abbia prodotta!).

Dopodiché, questo è l’elenco dei tasti che va a risolvere:

` (AltGr + ')
~ (AltGr + ì)
À (AltGr + shift + a)
È (AltGr + shift + e)
Ì (AltGr + shift + i)
Ò (AltGr + shift + o)
Ù (AltGr + shift + u)
® (AltGr + r) registered
© (AltGr + c) copyright

Si tratta di roba che ho trovato tramite SuperUser .

Test Antincendio Online

Ho realizzato un quiz online per il rilascio dell’attestato di idoneità tecnica per la qualifica di “Addetto Antincendio” di livello 2.

Si basa sul documento che potete trovare in PDF a questo indirizzo: https://www.vigilfuoco.it/sites/default/files/2024-06/RN-Quiz%20Livello%202.pdf

Il quiz online si trova qui: https://www.budus.it/Apps/TestAntincendio/

Sostanzialmente propone le 294 domande presenti nel documento PDF di cui sopra, in ordine casuale.

L’utente non deve fare altro che fare click sulla risposta che ritiene corretta; se risponde esattamente, il quiz passa automaticamente alla domanda successiva, viceversa, segnala quale sarebbe stata la risposta esatta ed è l’utente che deve cliccare sul pulsante “Avanti” per procedere con il quesito successivo.

Prevede che l’utente non superi il 10% di errore, altrimenti, viene bocciato!

In bocca al lupo. Se avete suggerimenti per migliorarlo, basta chiedere, alla peggio non lo faccio (lol).