domenica, 19 Gennaio 2025

[python] Esercizio su funzioni ricorsive e calcolo tratte dei treni

Facciamo un piccolo programma in Python che ci permetta di gestire le distanze da percorrere tra due stazioni, di partenza ed arrivo.

Abbiamo le seguenti tratte:

Stazione A Stazione B Distanza
Firenze Bologna 100km
Firenze Roma 250km
Roma Napoli 200km
Bologna Milano 220km
Bologna Venezia 150km

Ogni tratta è percorribile sia in andata che in ritorno. Quello che vogliamo è che il programma ci permetta di inserire due città e calcolare la distanza minima da percorrere e le stazioni da attraversare.

Anzitutto vediamo come sono disposti i nodi dell’intero percorso:

Notiamo che in questa configurazione elementare solo Bologna ha 3 rami, mentre tutte le altre città hanno solo 2 rami ciascuna.

Potremmo affrontare l’esercizio lavorando sui nodi oppure sulle tratte. In questa soluzione lavorerò sulle tratte.

Cominciamo quindi creando anzitutto una classe che ci permetta di descrivere ogni tratta come abbiamo visto nel mandato dell’esercizio.

In questo modo dichiariamo 3 variabili private per registrare le due città della tratta e la rispettiva distanza.

Adesso registriamo tutte le tratte in una lista, nel modo seguente:

Ora cominciamo a pensare all’algoritmo che potrebbe permetterci di calcolare il percorso.

Immaginiamo anzitutto la soluzione più semplice, dove io penso di andare da Firenze a Napoli. Su questa tratta non ci sono diramazione e sostanzialmente il percorso che dovrà venire fuori sarà Firenze – Roma – Napoli.

Fase 1:

Faccio un ciclo su ogni elemento della lista tratte[] e cerco anzitutto dove è presente la città di partenza. Siccome la città può essere sia in A che in B, per ogni oggetto Tratta dovrò implementare un metodo all’interno dell’oggetto stesso che mi permetta di valutare se la città sia presente in modo comodo. Implementiamo quindi la classe nel modo seguente:

Il metodo presente(citta) mi permette di valutare se la città sia presente nella tratta.

Fase 2:

Se trovo la città di partenza su una tratta allora controllo se l’altra città della tratta sia quella di arrivo. Allo stesso tempo registro la città di partenza all’interno di una lista percorso[] in modo da metterla come partenza del percorso complessivo.

Quindi se l’altra città è quella di arrivo posso chiudere il percorso, altrimenti passo il controllo sull’altra città.

Quando mi trovo nella riga 10 capisco anche che ho trovato la fine del percorso, quindi posso salvare l’intero percorso da qualche parte. Siccome potrei avere molteplici percorsi possibili decido di salvare il percorso in una lista globale chiamata percorsi = []

Modifichiamo quindi il codice nel modo seguente:

Adesso analizziamo due aspetti dell’ultima istruzione, quella dove richiamo la funzione.

Anzitutto voglio tirare fuori dalla tratta l’altra città, rispetto alla città di partenza. Per farlo implemento la classe principale nel modo seguente:

In questo modo quando mi trovo per esempio sulla tratta Firenze – Roma posso passare all’oggetto tratta Firenze, che conosco essendo il punto di partenza e chiedergli di darmi l’altra città della tratta, in questo caso Roma.

Il secondo aspetto che voglio evidenziare è che passo la lista percorso[] alla funzione medesima in partenza dall’altra città, per farlo utilizzo l’istruzione []+percorso, in caso contrario percorso passerebbe per riferimento e qualora fosse passato su più rami verrebbe elaborato contemporaneamente da più rami. Io invece voglio che resti un oggetto singolo e lineare per ogni percorso.

Arrivati a questo punto del codice la situazione è la seguente:

  1. Prendo in input partenza DA = Firenze e A = Napoli
  2. Aggiungo DA (Firenze) al percorso[]
  3. Passo a setaccio la lista delle tratte[]
  4. In posizione 0 trovo la tratta Firenze – Bologna a cui DA appartiene
  5. Controllo se A (Napoli) appartiene alla tratta
  6. Dal momento che non appartiene, prendo l’altra città della tratta, ovvero Bologna e la passo come nuovo DA alla funzione medesima
  7. La funzione ricomincia e aggiungendo DA (Bologna) al percorso[]
  8. Scorro la lista delle tratte[] in cerca di DA (Bologna)
  9. Trovo che DA nella posizione 0 sulla tratta Firenze – Bologna
  10. LOOP INFINITO!

Fase 3:

Devo evitare il loop infinito in cui il percorso possa tornare indietro. Per farlo modifico la mia funzione aggiungendo il seguente controllo all’inizio:

In questo modo controllo che il punto di partenza DA non sia già presente nel percorso[].

Adesso ricomincio a controllare il mio algoritmo da capo:

  1. Prendo in input partenza DA = Firenze e A = Napoli
  2. Aggiungo DA (Firenze) al percorso[]
  3. Passo a setaccio la lista delle tratte[]
  4. In posizione 0 trovo la tratta Firenze – Bologna a cui DA appartiene
  5. Controllo se A (Napoli) appartiene alla tratta
  6. Dal momento che non appartiene, prendo l’altra città della tratta, ovvero Bologna e la passo come nuovo DA alla funzione medesima
  7. La funzione ricomincia e aggiungendo DA (Bologna) al percorso[]
  8. Scorro la lista delle tratte[] in cerca di DA (Bologna)
  9. Trovo che DA nella posizione 0 sulla tratta Firenze – Bologna
  10. L’altra città (Firenze) è uguale ad A? No, quindi ripasso l’altra città come nuovo DA alla funzione medesima
  11. La funzione si interrompe, perché DA (Firenze) è già presente in percorso[]
  12. Torno al punto 9
  13. In posizione 3 trovo Bologna – Milano dentro tratte[] dove appartiene il mio DA
  14. Questo pezzo di codice adesso si ripete uguale a quello tra 10 e 12 fino a chiudersi su Milano e Venezia che terminano il percorso
  15. Trono al punto 3
  16. In posizione 1 trovo la tratta Firenze – Roma a cui DA (Firenze) appartiene
  17. Controllo se A (Napoli) appartiene alla tratta
  18. Dal momento che non appartiene, prendo l’altra città della tratta, ovvero Roma e la passo come nuovo DA alla funzione medesima
  19. La funzione ricomincia e aggiungendo DA (Roma) al percorso[]
  20. Scorro la lista delle tratte[] in cerca di DA (Bologna)
  21. Trovo che DA nella posizione 1 sulla tratta Firenze – Roma
  22. L’altra città (Firenze) è uguale ad A? No, quindi ripasso l’altra città come nuovo DA alla funzione medesima
  23. La funzione si interrompe, perché DA (Firenze) è già presente in percorso[]
  24. Torno al punto 20
  25. Trovo che DA nella posizione 2 sulla tratta Roma – Napoli
  26. Controllo se A (Napoli) appartiene alla tratta
  27. Napoli appartiene alla tratta nel pezzo di codice if t.presente(a)
  28. A questo punto aggiungo A (Napoli) alla fine di percorso[]
  29. Aggiungo il percorso[] ai percorsi[] con l’istruzione percorsi.append(percorso)

Fase 4:

Apporto ancora un paio di correzioni tecniche alla mia funzione per evitare inutili duplicati.

A questo punto posso scrivere la parte principale del mio programma con:

Per stampare il percorso faccio una join su ogni percorso che trovo dentro a percorsi[]

Fase 5:

Aggiungo soltanto un metodo per calcolare le distanze. Potrei farlo anche in modi più ottimizzato, ma per le finalità di questo esercizio ci accontentiamo di percorrere tutte le stazioni, esclusa l’ultima, e di calcolare la distanza tra la stazione corrente e la successiva sommandole tutte insieme.

A tale proposito aggiunto un metodo che mi permetta di valutare se 2 città appartengono entrambe alla tratta ed un getter per la distanza.

La funzione quindi sarà:

Fatto tutto questo posso completare il mio programma nella sua versione finale nel modo seguente:

Se volessimo complicare un po’ lo schema potremmo aggiungere altre tratte:

Ed ottenere una versione finale del programma in questo modo:

Il nostro nuovo programma genererà un output come questo:

Tow Point Hospital su Steam crash con errore TPH.exe e codice eccezione 0xc0000005

Questo codice di errore si verifica probabilmente perché c’è un file corrotto del gioco (o banalmente un aggiornamento andato male).

Si avvia il gioco e dopo un po’ va in crash senza motivo apparente.

Soluzione: bisogna verificare l’integrità dei file di gioco tramite lo strumento di Steam

Per farlo procedere nel modo seguente:

  1. Aprire Steam e andare su Libreria > Giochi
  2. Nell’elenco sulla sinistra cliccare col destro sul gioco e selezionare Proprietà

  3. Selezionare la scheda File locali e poi premere su Verifica integrità dei file di gioco
  4. Attendere la fine della procedura. Se il problema era di integrità si verrà avvisati che c’erano uno o più file corrotti e che saranno scaricati di nuovo. Si potrà notare attivo un download nell’omonima sezione.
  5. Fine. Adesso si può giocare di nuovo.

[excel] Come creare una password casuale di lunghezza arbitraria con un’unica formula

Mi sono chiesto se ci fosse un modo, utilizzando Excel, di generare una password casuale di lunghezza arbitraria con una singola formula.

Naturalmente utilizzando VBA sarebbe semplicissimo, si potrebbe creare una propria funziona ed utilizzarla all’interno della formula. In alternativa si potrebbe creare una tabella di riferimento e generare la password a partire da essa (qui c’è un esempio interessante).

Però mi sono impuntato a voler creare una singola formula, utilizzando le funzioni disponibili nativamente in Excel, per generare una password di lunghezza arbitraria.

Soluzione veloce

Per chi non avesse voglia di proseguire nell’analisi della questione la soluzione è la seguente (per 1 singolo carattere preso tra maiuscole, minuscole, numeri e caratteri speciali):

Per generare una password di 2 caratteri basta concatenare la formula precedente per 2 volte, di 3 caratteri per 3 volte ecc (di seguito l’esempio per 2 caratteri):

Spiegazione

Anzitutto partiamo dalla seguente idea. Se avessi un vettore di 3 caratteri, potrei estrarre casualmente uno dei tre caratteri?

Per farlo mi è sufficiente scrivere:

Ad ogni ricalcolo del foglio questa formula pescherà casualmente un valore tra 10, 20 e 30. Tra le parentesi graffe {} ho inserito una matrice (nello specifico un vettore colonna) di 3 valori. Il punto fa da separatore di riga, altrimenti il backslash farebbe da separatore di colonna.

In ogni caso la presente formula sarebbe equivalente alla seguente situazione:

In A4 in questo caso vedrei un valore casuale preso tra A1:A3.

Seconda idea. Sarebbe possibile generare, al posto dei suddetti valori, dei valori casuali che escano fuori da una funzione? Purtroppo Excel non consente di scrivere esplicitamente una matrice contenente a sua volta delle funzioni, senza passare dall’utilizzo delle celle.

Allora mi sono chiesto: ci sarà un modo per scrivere una stringa e trasformarla in un vettore mediante un separatore di stringa (una specie di str_split per intendersi nel PHP)? Se la stringa è composta di singoli caratteri che dovranno diventare elementi del vettore è effettivamente possibile.

Possiamo cioè trasformare il nome Noctis nel vettore {“N”.”o”.”c”.”t”.”i”.”s”}

Per farlo è sufficiente utilizzare:

Faccio notare che INDIRETTO prendere le righe dalla 1 alla 6. Con RIF.RIGA generiamo un vettore di riferimenti equivalente a {1.2.3.4.5.6}. Per inciso la funzione sarebbe potuta anche essere così:

Dal momento però che mi fa fatica scrivere tutto il vettore da 1 a 6 (più che altro se fosse stato più lungo sarebbe risultato abbastanza impensabile) preferisco generarlo con questo semplice trucchetto.

A questo punto abbiamo capito che possiamo spezzare una stringa arbitraria nel vettore dei caratteri che la compongono.

Adesso prendiamo in considerazione la seguente tabella ASCII.

Grazie alla funzione CARATT.UNI posso estrarre un carattere a partire dal suo riferimento numerico nella suddetta tabella (nello specifico qualunque carattere UNI-CODE, ma non è il momento di approfondire la cosa).

Per esempio se digito:

Ottengo la lettera p minuscola.

Quindi posso generare caratteri casuali mischiando questa funzione con CASUALE.TRA nel modo seguente.

Caratteri maiuscoli:

Caratteri minuscoli:

Caratteri speciali:

Per generare invece i numeri da 0 a 9 mi basta utilizzare:

Quindi usando la formula:

Posso generare una stringa di 4 caratteri contenente un numero casuale, una maiuscola casuale, una minuscola casuale e un carattere speciale casuale.

Inserendo questa dentro la suddetta formula con STRINGA.ESTRAI posso estrarre i quattro caratteri dalla stringa in un vettore di caratteri casuali con la seguente formula:

A questo punto inserendo il tutto dentro a INDICE ottengo la precedente formula e il gioco è fatto.

Per generare delle password casuali di 16 caratteri come queste:

!#lKTHLb0nx2Z(0H
7&x(128’#L#(t6B3
,77YJ”lu35%LKYVm
svkA.ur1Y””+#r*t
15I35t1Z”(/Lz#0a

Ci sarebbe sufficiente utilizzare la formula un po’ più lunga e ripetuta come detto all’inizio.

 

[wordpress] Too few arguments to function wpdb::prepare()

Soluzione veloce: Nella funzione $wpdb->prepare() va aggiunto almeno un argomento, che può essere anche array(), nella maniera seguente $wpdb->prepare( “SELECT * FROM tabella” , array() ).

Questo errore si presenta perché nella funzione $wpdb->prepare() manca un argomento, ovvero quello dei parametri da “preparare” dentro la query. Supponiamo per esempio di avere una variabile $id che vada inserita in una query. La seguente operazione sarebbe sbagliata:

L’errore sarebbe sia pratico che concettuale. Anzitutto questa scrittura di per se non necessita del $wpdb->prepare() dal momento che la variabile è già inserita nella stringa.

In secondo luogo la definizione della funzione prevede l’utilizzo di almeno due argomenti, come descritto qui: wpdb::prepare( string $query, array|mixed $args )

La funzione corretta sarebbe:

Oppure:

 

Ordine degli spinotti nella stanza di monitoraggio, Resident Evil 2 Remake [Claire B]

Similmente a quanto avviene nella prima parte con Leon, anche con Claire dobbiamo inserire gli spinotti nella stanza di monitoraggio.

Questa volta il messaggio cambia e l’ordine non è lo stesso di prima.

Il messaggio ci dice: “La torre è di fianco al cavallo, ma non di fronte alla regina. Il re non è di fianco alla regina, ma di fronte al cavallo, in fondo. Il cavallo non è dove dovrebbe essere.

La prima cosa da fare quindi è sostituire la posizione del cavallo. Le posizioni da occupare sono le seguenti:

Sulla parete alla nostra sinistra, guardando frontalmente quella centrale, vanno messi regina, alfiere e re. Sulla parete alla nostra destra vanno invece pedone, torre e cavallo.

Trovare auto giocattolo in The Division 2

Una delle missioni del Campus (per inciso quella denominata Giocattoli per bambini) richiede di donare un’auto giocattolo. Ma dove trovarla? In 85 ore di gioco non è saltata fuori da se e sembra che uno degli unici posti (sull’unicità non garantisco) dove salta fuori casualmente sia un vicolo poca sopra la Biblioteca memoriale Martin Luther King.

La posizione per la precisione è questa:

In fondo al vicolo, accanto ad un camion, si trova un mobile con cassetti dove è possibile, dopo un po’ di tentativi, trovare l’auto giocattolo.

Una volta recuperata ci si può recare al Campus per completare la missione (gli altri oggetti sono abbastanza comuni e si trovano un po’ ovunque, specialmente nelle case).

Infine riporto l’intera sequenza video per maggiore chiarezza.

Configurare XAMPP sul Mac e installarci sopra WordPress

Anzitutto procuriamoci XAMPP dal sito ufficiale. Cliccando sul precedente link ci si troverà di fronte ad una schermata simile:

Selezioniamo la versione più appropriata per il nostro sistema operativo e i nostri scopi; in questa guida io utilizzerò la version indicata con la freccia rossa nell’immagine (XAMPP con PHP 7.3.2, il gruppo a seguire è quello di XAMPP con macchina virtuale).

Una volta scaricato il file selezioniamolo dall’elenco e avviamo l’installazione.

A questo punto clicchiamo sull’installer e autorizziamo l’installazione del programma scaricato da internet.

Adesso si aprirà l’installazione vera e propria e scegliamo di proseguire avanti, come nell’immagine.

Ci verranno chieste una serie di impostazioni da scegliere procedendo avanti. Se non hai particolari esigenze o non sai cosa dovresti scegliere premi tranquillamente next finché non parte l’installazione finale e si giunga alla fine.

A questo punto premiamo su Finish lasciando attiva l’opzione Launch XAMPP. Questo aprirà XAMPP su una schermata simile alla seguente:

Spostiamoci su Manage Servers per avviare i server che ci interessano (ovvero Apache e MySQL).

Per farlo selezioniamo il server MySQL Database e premiamo il tasto Start. Poi selezioniamo il server Apache Web Server e premiamo di nuovo Start.

Una volta avviati correttamente dovremmo vedere al fianco di entrambi un pallino verde. Se così è vuol dire che sono attivi e possiamo procedere oltre.

Adesso torniamo alla schermata precedente e clicchiamo su Open application folder.

Si aprirà la cartella di installazione di XAMPP, qui ci spostiamo su htdocs che è la radice del nostro webserver.

Il contenuto di questa cartella corrisponde all’indirizzo http://localhost oppure http://127.0.0.1

Qui dentro vogliamo creare una cartella dove installeremo WordPress, in modo che sia accessibile all’indirizzo http://localhost/wordpress1

Per farlo clicchiamo col destro e selezioniamo dal menu contestuale Nuova cartella, nominiamo la cartella wordpress1

Adesso lo spazio web è pronto. Dobbiamo solo creare ancora il database. Per farlo andiamo su http://localhost/phpmyadmin. Nella schermata che si apre clicchiamo su Database. Sotto la voce Crea nuovo database inseriamo il nome del database che vogliamo creare, per esempio wordpress1. Il nome del database non deve essere necessariamente uguale al nome della cartella per lo spazio web, li ho messi uguali solo per coerenza logica.

Fatto tutto questo abbiamo preparato spazio web e database per installare il nostro nuovo sito.

Ora dobbiamo procurarci WordPress, quindi andiamo sul sito ufficiale e scarichiamolo dalla sezione download.

Per l’ultima versione in italiano è anche sufficiente cliccare qui.

Spostiamoci su Safari e andiamo all’indirizzo http://localhost/wordpress1. Se abbiamo fatto tutto correttamente dovremmo vedere qualcosa di simile a questo:

Nel mentre il download di WordPress dovrebbe essere terminato, per cui dovremmo vederlo nell’elenco dei download di Safari nel modo seguente:

Clicchiamo col destro sopra il download e selezioniamo Mostra nel finder.

Dovremmo visualizzare qualcosa di simile. Entriamo nella cartella chiamata wordpress.

Dovremmo trovare un elenco di file come quello mostrato di seguito. Selezioniamo tutti i file e spostiamoli nella cartella wordpress1, che abbiamo creato prima in htdocs. Per farlo è sufficiente affiancare le due finestre e con tutti i file selezionati trascinarli da una posizione all’altra.

Fatto questo, prima di ogni altra cosa, dobbiamo dare i permessi di lettura e scrittura per i file nella cartella di installazione. Perciò dal Finder spostiamoci su Vai > Utility e selezioniamo, dalla finestra che si aprirà, il terminale.

Nel terminale digitiamo: sudo chmod -R 0777 

Dopo il 0777 lasciamo uno spazio. Poi affianchiamo la cartella htdocs al terminale e trasciniamo verso il terminale la cartella wordpress1.

Per essere precisi i permessi 0777 su tutta la cartella consentiranno il massimo accesso a lettura e scrittura per tutti gli utenti e tutti file. Di per se non sarebbe l’ideale, ma siccome stiamo lavorando in locale può andar bene. Ovviamente la situazione andrebbe valutata in base all’uso che si fa del computer in questione.

In ogni caso se tutto è andato bene dovremmo vedere qualcosa come:

Premiamo Invio da tastiera e digitiamo la password. ATTENZIONE! La password non verrà mostrata e sembrerà di digitare a vuoto. Digitiamo la password del nostro utente e premiamo invio, anche se apparentemente non sta succedendo niente.

Aspettiamo un attimo perché la procedura finisca e ricompaia nuovamente il cursore sul terminale. Dopodiché torniamo su Safari e aggiorniamo la pagina http://locahost/wordpress1. Dovremmo trovarci di fronte alla seguente situazione:

A questo punto possiamo procedere all’installazione di WordPress. Premiamo sul tasto Iniziamo! che compare sotto il testo introduttivo.

Nella schermata che segue inseriamo i dati nella maniera seguente:

Premiamo su Invia. Se abbiamo messo tutti i campi corretti troveremo la seguente schermata.

Premiamo su Avvia l’installazione. Adesso completiamo la seguente schermata, scegliendo a piacere il nome del sito, il nome dell’utente principale (io ho messo il classico admin), una password (WordPress ce ne suggerirà una abbastanza complessa) e il nostro indirizzo email.

Infine premiamo su Installa WordPress. Se abbiamo eseguito tutto a dovere comparirà la schermata finale di login.

Se installando i plugin o i temi dovesse comparirci una schermata come la seguente:

Premiamo sul tasto annulla e dal terminale che abbiamo usato prima per cambiare i permessi digitiamo i seguenti comandi.

Spostiamoci nella cartella wordpress1 che abbiamo creato con cd wordpress1. Poi digitiamo sudo nano wp-config.php e premiamo il tasto Invio.

Si aprirà l’editor nano sul file wp-config.php.

Subito all’inizio, prima delle impostazioni MySQL, aggiungiamo la seguente riga di codice:

Premiamo i tasto CTRL+O per salvare. Premiamo Invio per confermare la modifica del file.

Fatto questo possiamo tornare ad installare tranquillamente temi e plugin.

[bash] Copiare i file trovati con grep in una cartella di destinazione

L’obiettivo è quello di trovare determinati file con dentro un certo contenuto, utilizzando grep e copiarli in una cartella di destinazione (nel mio specifico caso per fini di backup).

Per farlo con bash ci è sufficiente digitare il seguente codice:

Nota che utilizzo cp -a per copiare tutte le caratteristiche del file, permessi compresi.

[vba] Utilizzare il dizionario nelle macro di Excel per calcolare la media dei voti, in diverse materie per diversi studenti

Propongo un veloce esercizio in VBA sull’utilizzo dei dizionari.

Immaginiamo di avere un elenco di studenti e voti in diverse materie come nell’esempio seguente:

Vogliamo calcolare la media dei voti per ciascun studente in ciascuna materia, mettendo tutto in una tabella tipo pivot nel modo seguente:

La cella gialla è in L10

A tale scopo realizziamo la seguente macro in VBA utilizzando i dizionari. Per usare il dizionario anzitutto aggiungiamo il relativo riferimento da Strumenti > Riferimenti…

Il riferimento che ci interessa è il Microsoft Scripting Runtime, libreria dalla quale andremo a prelevare Scripting.Dictionary

Fatto tutto questo vediamo il codice:

Faccio notare che nel mio esempio la tabella di scrittura parte dalla posizione L10 nel foglio di calcolo attivo.

Quello che abbiamo realizzato è un dizionario di dizionari. Per realizzarlo utilizziamo: