✨Here✨ there is a dashboard to display all the relevant plots that we produced to better develop our analysis and interpretation. The task was to cluster spatio-temporal data about air pollution in Lombardy, using Bayesian models.
✨Qui✨ c'è la dashboard che abbiamo creato per mostrare tutti i plot rilevanti che abbiamo prodotto nella nostra analisi e che meglio permettono di interpretarne i risultati. L'obiettivo del progetto era di clusterizzare dati spazio-temporali riguardo all'inquinamento dell'aria in Lombardia, usando modelli bayesiani.
Link diretto al pdf qui. Direct link to pdf here.
In this projoect we had to detect defects into 3d printed objects, using control charts, the method we learnt at lectures. We also had a big part of image analysis to develop the meaningful variables to then monitor in order to detect defects. In the end our model detected 7 out of the 9 defected objects, on a total of 40 objects.
In questo progetto abbiamo dovuto rilevare difetti in oggetti stampati in 3d, utilizzando grafici di controllo, ovvero il metodo imparato a lezione. Una considerevole parte del progetto è stata anche quella di analisi delle immagini, per estrarre le variabili più rilevanti da monitorare per rilevare i difetti. Alla fine, il nostro modello ha rilevato 7 tra i 9 oggetti che presentavano difetti, da un campione totale di 40 oggetti.
Link diretto al pdf qui. Direct link to pdf here.
In this project we had to develop a statistical analysis on a topic at our choice. We studied the PISA dataset, which contains measurements about students in european high school, with the goal of inferring results about their wealth and well-being.
In questo progetto abbiamo sviluppato un'analisi statistica su un tema a nostra scelta. Abbiamo studiato il PISA dataset, che comprende dati riguardo agli studenti delle scuole medie in Europa, con l'obiettivo di indagare il loro benessere fisico e psicologico.
Link diretto al pdf qui. Direct link to pdf here.
Al primo anno, quarto laboratorio di informatica, dovevamo implementare il gioco del 15 in C, quello con la griglia 4 per 4, una casella vuota, e i numeri all'interno da riordinare. Però, già che c'ero, l'ho implementato in dimensione generica N per N, e quindi anzichè "gioco del 15" si è esteso in "gioco dell'", di cui segue il codice. Tale codice è scritto in C quando ero al primo anno e ai primi mesi, quindi è molto disordinato e poco efficiente, ma ✨qui✨ potete trovare una versione equivalente (e giocabile!) in html e javascript.
Importante notare che la board non può essere inizializzata con numeri in ordine casuale, altrimenti si potrebbe arrivare a configurazioni non risolvibili, per esempio questa
dove l'8 e il 7 non possono essere invertiti. Perciò, per inizializzarla, e per regolare la difficoltà del gioco, il codice parte da una board risolta e su quella applica per un po' di volte delle mosse casuali, per disordinare la sequenza di numeri preservando la possibilità di risolvere il gioco.
/*
Si vuole realizzare un programma che permetta di giocare al gioco del 15
Nella risoluzione dell'esercizio si implementino le seguenti funzioni:
int valida (int gioco[N][N], int mossa)
che riceve la scacchiera e una mossa e restituisce 1 se la mossa è valida, 0 altrimenti.
void muovi (int gioco[N][N], int mossa)
che riceve la scacchiera e una mossa e aggiorna la scacchiera in base alla mossa effettuata.
int risolto (int gioco[N][N])
che riceve la scacchiera e restituisce 1 se il gioco è stato risolto, 0 altrimenti.
void stampa (int gioco[N][N])
che riceve la scacchiera e la stampa a video.
*/
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<math.h>
#define N 7
#define DIFF 10
int valida (int gioco[][N], int mossa);
void muovi (int gioco[][N], int mossa);
int risolto (int gioco[][N]);
void stampa (int gioco[][N]);
int main(){
srand(time(0));
int gioco[N][N];
int i,j,n;
int mossa;
//creazione della scacchiera/matrice di gioco
/*
for(i=0;i<(N*N);i++)
num[i]=i+1;
for(i=0;i<N;i++){
for(j=0;j<N;j++){
esatto=0;
do{
n=rand()%(N*N);
if( num[n]!=0 ){
gioco[i][j]=num[n]-1;
num[n]=0;
esatto=1;
}
}
while(esatto!=1);
}
}
*/
n=1;
for(i=0;i<N;i++){
for(j=0;j<N;j++){
gioco[i][j]=n;
n++;
}
}
gioco[N-1][N-1]=0;
printf("Obiettivo: \n");
stampa(gioco);
int prevmossa=-1;
for(i=0;i<DIFF;i++){
mossa=-1;
while(!valida(gioco,mossa) || mossa==prevmossa){
mossa=rand()%(N*N);
}
prevmossa=mossa;
// printf("%d ",mossa );
muovi(gioco,mossa);
}
printf("\nGioco: \n");
stampa(gioco);
while( !risolto(gioco) ){
printf("\n");
do{
printf("Mossa: ");
scanf("%d",&mossa);
}while( !valida(gioco,mossa) );
muovi(gioco,mossa);
stampa(gioco);
printf("\n");
}
return 0;
}
void stampa (int gioco[][N]){
int i,j;
for(i=0;i<N;i++){
for(j=0;j<N;j++){
printf("%4d",gioco[i][j]);
}
printf("\n");
}
}
int risolto (int gioco[][N]){
int esatto=1;
int i,j,c=0;
int v[N*N];
for(i=0;i<N;i++){
for(j=0;j<N;j++){
v[c]=gioco[i][j];
c++;
}
}
// for(i=0;i<N*N;i++)
// printf("%d ",v[i]);
for(i=0;i<N*N-2;i++){
if(v[i+1]!=v[i]+1 || v[N*N-1]!=0)
esatto=0;
}
if(esatto==1)
printf("Gioco risolto!\n");
return esatto;
}
int valida (int gioco[][N], int mossa){
int p0r,p0c,i,j;
int pmossac,pmossar;
int giusta=0;
for(i=0;i<N;i++){
for(j=0;j<N;j++){
if(gioco[i][j]==0){
p0r=i;
p0c=j;
}
}
}
for(i=0;i<N;i++){
for(j=0;j<N;j++){
if(gioco[i][j]==mossa){
pmossar=i;
pmossac=j;
}
}
}
if( p0r==pmossar){
if( abs(p0c-pmossac)==1 )
giusta=1;
}
else if( p0c==pmossac){
if(abs(p0r-pmossar)==1 )
giusta=1;
}
else
giusta=0;
return giusta;
}
void muovi (int gioco[][N], int mossa){
int p0r,p0c,i,j;
int pmossac,pmossar;
for(i=0;i<N;i++){
for(j=0;j<N;j++){
if(gioco[i][j]==0){
p0r=i;
p0c=j;
}
if(gioco[i][j]==mossa){
pmossar=i;
pmossac=j;
}
}
}
gioco[p0r][p0c]=mossa;
gioco[pmossar][pmossac]=0;
}
Il nostro grest, o campo estivo, dell'oratorio gestiva i bambini delle elementari e medie dividendoli in 8 squadre, definite da delle bandane colorate. Anche i ragazzi più grandi, delle superiori, erano distribuiti all'interno delle squadre, ma lavoravano come animatori. Quindi i bambini giocavano e partecipavano alle varie attività, mentre gli animatori in parte li accompagnavano ed in parte organizzavano proprio quelle varie attività.
Nella mia lunga carriera da animatore ho scalato le dure gerarchie di potere fino a diventare Referente, cioè moralmente capo degli arbitri. Il mio lavoro, insieme ai miei compagni, era quindi di organizzare i giochi da fare ogni giorno (come pallabollata, bandierina, ecc, o inventarne di nuovi), definire materialmente i campi, cioè proprio tracciarli in qualche modo per terra, assegnare arbitri ed accompagnatori, decidere quali squadre far scontrare in ogni turno, ecc.
E qui nasceva un interessante problema.
In ogni campo, dove si sfidavano coppie di squadre, c'erano due arbitri, ovvero due animatori, per supervisionare lo svolgimento del gioco in quel campo. Gli animatori però appartenevano anch'essi a delle squadre, e quindi sarebbe stato ingiusto far giocare, per esempio, la squadra rossa in un campo in cui c'era un arbitro dei rossi. Le coppie di squadre da far scontrare in una partita le calcolavo in base alla classifica generale e all'andamento dei vari round, e in quanto referente era poi mio dovere cercare di organizzare queste assegnazioni ai campi opportuni, in modo da evitare conflitti sulle decisioni arbitrali. In questo modo ho quindi pensato ad un piccolo algoritmo che risolvesse il problema.
La sua esecuzione si faceva tranquillamente sul foglio di carta che avevo per tenere traccia del gioco, ma qui c'è una versione interattiva che ne dimostra l'esecuzione. L'idea era di ricavare le disponibilità nei campi ("Disponibilità (debug table)" nella pagina linkata), e poi trovare un percorso di assegnazione che li coprisse tutti.
Quoridor è un giochino che ho trovato molto interessante, ma purtroppo non ancora molto diffuso. La sua piacevolezza secondo me sta nell'essere un gioco dalle regole molto semplici, ma che si complica molto nella scelta delle strategie. Un po' tipo scacchi ma senza le troppe complicazioni dell'avere molti pezzi in gioco e del perdere quasi sempre se non ha un minimo studiato (per esempio le aperture).
L'idea è che ogni giocatore ha una pedina che deve arrivare dall'altro lato della scacchiera di gioco, e può posizionare lungo il cammino dei separatori, dei muri, che possono o agevolare il suo percorso o ostacolare quello dell'avversario (oviamente lasciandogli sempre però una via per arrivare al suo obiettivo, ovvero l'avversario non può essere "intrappolato"). Quindi occorre valutare bene quando muoversi, quando posizionare invece un muro, e dove posizionarlo, se nel frattempo metterne altri che saranno utili a lungo termine per mosse future, ecc.
Ebbene, io e il mio caro amico Ettore, anche lui abbastanza smanettone, ci siamo messi a crearlo con l'obiettivo poi di implementare magari anche delle AI (intelligenze artificiali) da sfidare. Per ora è un work in progress, e qui trovate tutto il codice. Lui ha preferito scrivere il gioco in C++ mentre io in Julia, naturalmente. Le regole sono state implementate, quindi il gioco è giocabile, ma implementare delle AI sembra molto complicato perché oltre a scegliere come muovere la pedina c'è anche la scelta di dove piazzare un muro, e in che orientamento, quindi ci sono molte varianti di decisioni a cui pensare. Quindi per ora c'è solo rand_AI
che gioca mosse casuali, e target_AI
che invece si muove verso il lato della vittoria nel modo più veloce possibile (quindi moralmente è un metodo greedy).
Questo è un piccolo esempio di come appare il gioco nella mia versione in Julia, c'è la scacchiera di gioco, in cui ci si muove con i tasti intorno ad S (per esempio W vuol dire andare verso nord, C verso sud-est, ecc), con indicate le coordinate delle righe e colonne per scegliere dove piazzare i muri. Sotto c'è una piccola heatmap della distanza di un giocatore dalla riga di vittoria, che servirà presumibilmente per sviluppare le varie AI.
Quando sistemerò (o anche solo scansionerò) tutti i miei appunti popolerò meglio anche questa sezione.
A seconda dei casi, e dei corsi, non carico qui i miei appunti effettivi, quelli presi sui quaderni durante le lezioni, ma piuttosto le loro "rielaborazioni" che in genere faccio quando studio una materia. Moralmente queste rielaborazioni condensano insieme varie fonti: gli appunti effettivi presi a lezione, metodi ed esempi visti ad esercitazione, qualcosa tratto da libri o trovato online, ecc; il tutto per arrivare a una forma nella versione più chiara, ordinata e studiabile possibile.
Se carico invece gli appunti effettivi dei quaderni è perché o per quel corso non ho avuto voglia di riordinare e integrare il materiale, o semplicemente perché tali appunti, per i miei gusti di studio, erano già usciti perfettamente nel formato quaderno (per esempio quelli del corso di ARF).
Link diretto al pdf qui. Direct link to pdf here.
Link diretto al pdf qui. Direct link to pdf here.
Link diretto al pdf qui. Direct link to pdf here.
Link diretto al pdf qui. Direct link to pdf here.
Link diretto al pdf qui. Direct link to pdf here.
Ecco i miei appunti per il corso di Metodi Analitici e Numerici delle EDP. Corso tostissimo, ma gli appunti mi sono usciti davvero molto bene: era il periodo in cui mi sono accorto che scrivere a quadretti alternati era una mera forzatura e convenzione imposta dagli ordini inferiori di educazione scolastica, e quindi qui ho iniziato la mia conversione alla scrittura su ogni quadretto (ma ovviamente mantenendo sempre l'ordine, ad esempio limitando a tre il numero di righe consecutive scrivibili prima di una riga vuota di spaziatura).
Link diretto al pdf qui. Direct link to pdf here.