venerdì, 29 Marzo 2024

[FIFA20] Configurazione firewall di Fastweb per consentire la connessione online

Premetto che non dovrebbe essere necessario aggiungere il gioco al firewall del router di Fastweb e che, la maggior parte dei problemi di connessione, dipende dai server della EA o altri elementi mistici fuori dalla nostra comprensione umana.

A tale proposito rimando agli articoli dove ho affrontato la cosa in modo più generale:

[FIFA19] La connessione con l’avversario si è interrotta

[FIFA20] La connessione con l’avversario si è interrotta

Qui voglio vedere quali sono le porte che devono essere aperte sul router e, nel caso specifico, come configurare il router di Fastweb.

Anzitutto il modello del mio router è un MediaAccess TG788vn v2 della Technicolor (quelli recenti in dotazione con Fastweb).

Per accedere al router, se non sappiamo come fare, procediamo nella maniera seguente. Premiamo WIN+R e digitiamo cmd.

Si aprirà il Prompt dei comandi. Digitiamo ipconfig e premiamo INVIO.

Dovremmo vedere qualcosa di simile:

L’indirizzo Gateway predefinito è l’indirizzo del router. Nel mio caso aprirò quindi il browser per andare sul web e digiterò: http://192.168.1.254

Si aprirà la schermata di accesso al router. I dati di accesso predefiniti dovrebbero essere:

username: fastweb

password: lasciare vuoto

Nel caso di dubbi si possono trovare i manuali online sul sito stesso di Fastweb, come questo qui: Technicolor TG788VN

Una volta dentro il router spostiamoci su Casella degli strumenti > Condivisione giochi e applicazioni

Clicchiamo su Crea un nuovo gioco o una nuova applicazione

Si aprirà una schermata nella quale dovremo immettere le porte da assegnare allo specifico gioco o applicazione.

Per l’elenco delle porta necessarie a tale scopo si può consultare il sito della EA: Aprire le porte per risolvere i problemi di connessione

Nel caso specifico di FIFA le porte da aprire sono le seguenti:

Le porte che devono essere aperte per FIFA20 da PC sono: UDP 3659, 9565, 9570, 9000 – 9999, TCP 3569, 9946, 9988, 10000 – 20000, 42124.

Configuriamo quindi le porte per il dispositivo che ci interessa, io le configurerò per il gioco da PC, nel modo seguente:

Quando è tutto pronto clicchiamo su Applica in cima, dopo aver assegnato un nome al gioco. Torniamo alla schermata precedente e selezioniamo Assegna un gioco o un’applicazione a un dispositivo di rete locale.

Selezioniamo dal menu a tendina il gioco appena configurato e il nome del nostro dispositivo (nel mio caso è il nome del mio computer) e premiamo su Applica.

Faccio notare che devono essere attive le opzioni Usa UPnP e Usa attivazione estesa.

Se abbiamo fatto tutto correttamente possiamo tornare a provare a giocare.

Installare Ubuntu 19.10 con webserver pronto all’uso [per esordienti assoluti]

Abbiamo già visto come installare Ubuntu 18.04.2 LTS e Ubuntu 16.04.2 LTS predisponendoli per fare da webserver. Oggi voglio ripetere la procedura con Ubuntu 19.10.

Prima di andare avanti vorrei far notare come questa non sia una versione LTS, ossia una distribuzione con supporto a lungo termine, quindi ne sconsiglio caldamente l’installazione per progetti di lunga portata.

Detto ciò proseguiamo come di consueto utilizzando VirtualBox ai fini di questa guida, benché la procedura sarebbe analoga per chiunque lo volesse installare su una macchina fisica.

Gli argomenti trattati saranno:

  1. Configurazione ed installazione Ubuntu Server 19.10
  2. Installazione e configurazione Apache
  3. Installazione e configurazione MySQL
  4. Installazione e configurazione PHP
  5. Installazione di phpMyAdmin
  6. Ulteriori configurazioni

1. Configurazione Ubuntu Server 19.10

Anzitutto andiamo sul sito ufficiale di Ubuntu e procuriamoci la ISO per l’installazione. Assicuriamoci di selezionare la versione server e poi premiamo download:

A questo punto andiamo a creare la nostra macchina virtual con VirtualBox. All’interno di VirtualBox premiamo su CTRL+N per avviare l’installazione di una nuova macchina.

Diamo un nome alla macchina e scegliamo eventualmente il percorso di installazione, come nell’immagine di sopra. Assicuriamoci anche che il tipo sia settato su Linux e la Versione su Ubuntu (64-bit). Premiamo su Successivo.

Selezioniamo la quantità di memoria da destinare alla macchina virtuale (1GB è più che sufficiente). Ancora Successivo.

Lasciamo l’opzione selezionata Crea subito un nuovo disco fisso virtuale per crearne uno nuovo e andiamo avanti.

Se non abbiamo esigenze specifiche lasciamo il tipo di disco su VDI e procediamo avanti.

Lasciamo l’allocazione del disco su Allocato dinamicamente. In questo modo il disco crescerà solo in presenza di file effettivi, occupando meno spazio sulla macchina ospite. Andiamo avanti.

Diamo un po’ di spazio ad Ubuntu, visto che comunque andrà ad occupare solo quello necessario, mettendo il disco su 20GB.

A questo punto nell’elenco delle nostre macchine virtuali vedremo comparire quella con Ubuntu.

Una volta selezionata spostiamoci in alto e clicchiamo sul tasto verde Avvia per farla partire.

Al primo avvio ci verrà chiesto se caricare una ISO per l’avvio della macchina virtuale. Clicchiamo sulla cartellina gialla e poi selezioniamo la ISO che abbiamo scaricato in precedenza, se abbiamo fatto tutto bene, prima di procedere avanti, vedremo una situazione simili alla seguente:

Aspettiamo che compaia la sezione della selezione della lingua. Tanto per cambiare manca l’italiano, perciò proseguirò in inglese (o per fare uno scherzo proseguo in croato!).

Premiamo INVIO. Ci potrebbe chiedere se vogliamo aggiornare l’installer, diciamo di sì premendo di nuovo INVIO.

Adesso ci verrà chiesto il layout della tastiera. Dal momento che sto usando una tastiera italiana dovrò impostare il layout su Italian, come nell’immagine in alto, altrimenti potrei avere problemi specialmente con i caratteri speciali. Per farlo mi sposto in alto con le frecce direzionali e seleziono il menu premendo SPAZIO. Una volta trovata la voce giusta premo nuovamente INVIO. Dopodiché posso tornare alla voce Done e premere INVIO per procedere.

Mi verrà chiesto di configurare la rete, posso premere nuovamente INVIO e andare avanti.

Sulle impostazioni del proxy, a meno di non essere a conoscenza di diversa configurazione, lascio tutto com’è e premo INVIO.

L’indirizzo del mirror per la repository lo posso lasciare tale e quale, premendo ancora INVIO.

Alla voce successiva seleziono la seconda opzione, quella di configurazione dell’intero disco con utilizzo di LVM. Per approfondimenti sull’argomento consiglio LVM, gestore logico dei volumi su Ubuntu [per pinguini alle prime armi]

Mi verrà chiesto quale disco utilizzare, avendone uno soltanto non ho molto da scegliere, in caso contrario potrei selezionare il disco sul quale intendo installare le partizioni principali del server.

A questo punto mi verrà proposto un riassunto di tutte le modifiche che saranno applicate al disco. Se non ho altre esigenze posso premere INVIO e procedere.

Comparirà un avviso che mi segnalerà che l’intero contenuto del disco adesso verrà cancellato e sostituito con la nuova installazione; mi sposto con le frecce direzionali su Continue e premo INVIO.

Adesso inseriamo il nostro nome, scegliamo un nome per il server e username e password, compilando i campi come di seguito.

Una volta compilati tutti i campi premiamo INVIO.

A questo punto ci viene chiesto se vogliamo installare anche il server OpenSSH, che ci permetterà di collegarci in SSH al nostro server. Premiamo la SPAZIO per selezionare l’opzione e poi premiamo INVIO. Prima di premere invio la configurazione dovrebbe apparire come la seguente.

Saltiamo la selezione di snaps per il server (ovvero configurazioni preconfezionate, come viene spiegato alle singole voci). Spostiamoci in basso e selezioniamo semplicemente Done e poi premiamo INVIO.

Se abbiamo fatto tutto bene comincerà un’installazione come la seguente:

Una volta terminata ci verrà chiesto di riavviare il sistema e rimuovere il supporto di installazione. Premiamo semplicemente INVIO.

Se ci dovessero essere problemi con l’unmounting del cdrom, e dovesse comparire una schermata come quella di seguito, sarà sufficiente premere INVIO un’altra volta per dire al sistema di procedere comunque (VirtualBox avrà già smontato l’ISO per conto suo probabilmente).

A questo punto ci si dovrebbe trovare di fronte ad una schermata simile alla seguente:

Faccio notare che continua a persistere il ridicolo problema delle ultimissime versioni di Ubuntu, per cui la schermata di login appare prima che sia terminato il processo di avvio, cosa che riempie la shell di output anche dopo l’apparizione del prompt di ingresso.

Per effettuare il login sarà sufficiente premere nuovamente INVIO e poi digitare il nome utente e la password che abbiamo creato in precedenza.

Adesso, prima di procedere, voglio configurare la scheda di rete di VirtualBox, in modo da poter utilizzare Putty per collegarmi alla macchina virtuale. Lo faccio principalmente per poter copiare ed incollare i comandi sul terminale, cosa non possibile dall’interfaccia di VirtualBox stesso.

Per spegnere il sistema operativo digitiamo quindi:

Una volta spenta la macchina virtuale torniamo sull’interfaccia di VirtualBox e andiamo su File > Preferenze (che possiamo aprire anche premendo CTRL+G)

Andiamo su Rete e clicchiamo sul piccolo pulsante della scheda con il più verde sulla destra che ci permetterà di creare una nuova Rete con NAT da far utilizzare alla nostra macchina virtuale.

Configuriamo la rete nel modo seguente:

Clicchiamo su Inoltro del porte e configuriamo le porte da inoltrare dalla scheda di rete virtuale sul nostro computer alla rete interna di VirtualBox.

Configuriamo l’inoltro delle seguenti porte:

 

Stiamo dando per scontato che la macchina virtuale si troverà all’indirizzo 10.0.2.4 della rete interna (che è tipicamente l’indirizzo predefinito che viene assegnato dal DHCP di VirtualBox).

Detto questo premiamo OK su tutte le finestre aperte e torniamo alla nostra macchina virtuale. Dopo averla selezionata premiamo il tasto Impostazioni (vicino a quello di Avvio).

Dalla schermata delle Impostazioni andiamo su Rete e selezioniamo Rete con Nat, scegliendo dal menu sottostante la Rete Ubuntu che abbiamo creato prima.

Fatto tutto questo premiamo OK e avviamo di nuovo la nostra macchina virtuale. Una volta che sarà ripartita apriamo Putty e digitiamo come indirizzo di connessione 192.168.56.1

Premiamo OK. Se abbiamo fatto tutto correttamente ci verrà chiesto di effettuare la connessione.

Apparirà una schermata che ci chiederà di copiare la chiave di crittografia. Premiamo .

Inseriamo le credenziali e siamo pronti a procedere oltre.

2. Installazione e configurazione Apache

Adesso procediamo con l’installazione di Apache. Aggiorniamo anzitutto tutti i riferimenti della repository digitando:

Dopodiché digitiamo:

Alla domanda se proseguire digitiamo Y e poi premiamo INVIO. Aspettiamo che l’installazione termini. Se tutto è andato bene aprendo l’indirizzo http://192.168.56.1/ dal nostro browser dovremmo vedere la schermata predefinita del webserver Apache nel modo seguente:

3. Installazione e configurazione MySQL

Adesso installiamo il Server MySQL per il database. Per farlo digitiamo:

Come al solito confermiamo l’installazione con Y e aspettiamo che sia terminata.

Una volta terminata l’installazione digitiamo:

Questo avvierà una procedura di configurazione del nostro database, durante la quale ci verranno richieste diverse cose. Alle varie domande rispondiamo rispettivamente:

Press y|Y for Yes, any other key for No: Y

Please enter 0 = LOW, 1 = MEDIUM and 2 = STRONG: 2

(dove: STRONG Length >= 8, numeric, mixed case, special characters and dictionary file)

New password: 4y!7dz=6/%lF-4fes2=lkpl|E^DTL*  (questo è un esempio di password che possiamo mettere, questa password ha una qualità di 180bit e una lunghezza di 30 caratteri)

Se la passowrd è buona ci verrà detto qualcosa come:

Estimated strength of the password: 100

Proseguiamo:

Do you wish to continue with the password provided?(Press y|Y for Yes, any other key for No) : Y

Remove anonymous users? (Press y|Y for Yes, any other key for No) : Y

Disallow root login remotely? (Press y|Y for Yes, any other key for No) : Y

Remove test database and access to it? (Press y|Y for Yes, any other key for No) : Y

Reload privilege tables now? (Press y|Y for Yes, any other key for No) : Y

Fatto questo il database è pronto per essere utilizzato.

L’utente predefinito del database sarà root e la password quella che abbiamo scelto prima.

4. Installazione e configurazione PHP

Adesso installiamo il PHP, aggiungendo la libreria per Apache e quella per il database MySQL.

Faccio notare che in questo modo verrà installato l’ultimo PHP disponibile, che nel mio caso specifico, come si può vedere anche dall’immagine di seguito, è il PHP 7.3.

Una volta installato il PHP verifichiamo che sotto Apache siano configurate le pagine predefinite come index.php per l’esecuzione. Digitiamo:

Se va tutto bene sotto la voce DirectoryIndex dovremmo trovare, tra gli altri file, anche index.php. Se così non fosse lo aggiungiamo come nell’immagine seguente:

Nel caso avessimo modificato il file salviamo il tutto premendo CTRL+O, altrimenti direttamente CTRL+X per uscire dall’editor.

Fatte tutte queste belle cose riavviamo Apache.

5. Installazione di phpMyAdmin

Per installare il phpMyAdmin utilizzeremo il composer, per cui installiamolo digitando:

Il composer è uno strumento per la gestione delle dipendenze e delle librerie del PHP, che ci permette di installare progetti in PHP come è per l’appunto il phpMyAdmin.

A questo punto installiamo il minimo indispensabile per usare il phpMyAdmin digitando:

Riavviamo Apache digitando come al solito:

Fatto tutto questo possiamo procedere con l’installazione vera e propria. Spostiamoci anzitutto dentro a /var/www:

Assegniamo il nostro utente alla cartella html (che è la cartella predefinita del nostro webserver raggiungibile dall’indirizzo di prima):

Entriamo dentro con:

A questo punto installiamo qui il nostro phpMyAdmin, che creerà una sua cartella alla quale assegneremo successivamente Apache come utente. In realtà la cartella del phpMyAdmin potrebbe essere creata a nostro piacimento in qualsiasi posizione, purché abbia un senso per noi. Tradizionalmente viene inserito sotto etc oppure share. Io l’ho inserito direttamente sotto www per una questione di ordine. (Qualora la si dovesse mettere altrove dovremmo ricordarci di aggiungere il percorso anche ai VirtualHost)

ATTENZIONE! composer non va lanciato come root/super user, quindi non va utilizzato sudo anteposto al commando. 

Aspettiamo con pazienza l’esito dell’installazione che potrebbe richiedere qualche minuto, soprattutto all’inizio quando non sembra succedere niente di che. Se tutto è andato bene vedremo un output come quello di seguito.

In caso di errore assicuriamoci di aver installato tutte le librerie per il PHP come di sopra e di aver riavviato Apache.

Prima di testare il phpMyAdmin così installato ripristiniamo sulla cartella html l’utente predefinito di Apache digitando:

A questo punto digitiamo nel browser http://192.168.56.1/phpmyadmin/

Se abbiamo fatto tutto bene dovremmo vedere qualcosa come questo:

Provando ad inserire root e la password creata in precedenza potremmo incorrere nel seguente errore:

Nessun problema. Torniamo sul terminale e digitiamo:

Inseriamo la password creata in precedenza per l’utente root. (per capirsi nel mio caso la password era 4y!7dz=6/%lF-4fes2=lkpl|E^DTL*)

Creiamo un utente apposito per gestire il database da phpMyAdmin. Per farlo eseguiamo la seguente sequenza di query:

L’utente così creato sarà:

username: admin

password: HGOqXovUhyZJ4}08}eg-lAiOM])}@lYt

Proviamo ad accedere con tali dati da http://192.168.56.1/phpmyadmin/

Nel caso dovesse apparire l’errore mysqli::real_connect(): The server requested authentication method unknown to the client [caching_sha2_password] eseguiamo i seguenti due comandi sul database.

Se è andato tutto bene possiamo riprovare ad accedere e vedremo una situazione simile a questa.

6. Ulteriori configurazioni

A questo punto abbiamo finito la configurazione principale e dovremmo fare ancora qualche implementazione, configurando cose come:

  1. Sistemare il Firewall
  2. Mettere in sicurezza Apache
  3. Configurare fail2ban ed altri eventuali servizi
  4. Aggiungere un VirtualHost al webserver

[javascript] Realizzare un gioco di carte tipo Memory utilizzando jQuery

Obiettivo: realizzare un semplice gioco di carte tipo Memory, utilizzando JavaScript e il framework jQuery.

Per chi non conoscesse il Memory, il gioco consiste nel cercare di indovinare le coppie di carte uguali. All’inizio possono venir mostrate tutte le carte (se vogliamo dare un’aiuto iniziale) che poi vengono coperte; a quel punto si tirano su due carte per volta per vedere se sono uguali: se lo sono le lasciamo scoperte, altrimenti le ricopriamo e procediamo col sollevare un’altra coppia e così via.

La versione giocabile del gioco, realizzato come illustrato nell’articolo, si trova in fondo all’articolo

Il gioco può essere elaborato in diverse varianti, a fini di questo semplice esercizio prendiamo in considerazione le seguenti regole:

  1. Al primo turno vengono mostrate per un attimo tutte le carte, dopodiché vengono nascoste
  2. Quando il giocatore solleva due carte uguali queste vengono lasciate scoperte e vengono assegnati dei punti
  3. Se le carte non sono uguali le ricopriamo nuovamente
  4. Per ogni coppia di carte scoperte assegniamo dei punti, determinati anche in base allo scorrere del tempo (prima si scoprono e più punti si guadagnano); diamo un punteggio maggiorato se le carte vengono trovate uguali in sequenza
  5. Una volta che tutte le carte sono state scoperte il gioco finisce

Prima di procedere oltre nello sviluppo del programma vediamo di cosa avremo bisogno (e cosa ho utilizzato):

Detto questo il risultato che vogliamo ottenere sarà simile a questo qua:

Costruiamo adesso l’idea del programma, che andremo a sviluppare come una singola classe in JavaScript che conterrà tutte le varie funzioni.

Il funzionamento lo potremmo riassumere in questo modo:

Cominciamo quindi costruendo la nostra pagina in HTML che conterrà lo script, per farla utilizziamo il prototipo base di Bootstrap nel modo seguente:

Alla riga 15 abbiamo il pezzo di codice che riguarda il contenitore del gioco, nel mio caso un div. Questa parte si ricollega a quella direttamente utilizzata nel javascript, nel file carte.js.

Affinché la classe funzioni in questo modo dobbiamo far sì che il costruttore accetti per argomento un dizionario e lo utilizzi per parametrizzare le opzioni dell’oggetto. Cominciamo quindi costruendo anche la nostra classe nel modo seguente:

Nel nostro costruttore dichiareremo le impostazioni come una variabile globale this.impostazioni = {}. Faccio notare che, a differenza di altri linguaggi di programmazione, le variabili (eccettuati i casi dei getter e dei setter) non possono essere dichiarate a livello di classe, ma esclusivamente dentro i metodi. Il prefisso this fa sì che la variabile sia globale, sebbene con alcune specifiche eccezioni che vedremo.

Implementiamo ulteriormente la classe nel modo seguente:

Per far sì che le impostazioni dell’utente si sovrappongano alle impostazioni predefinite utilizziamo l’istruzione this.impostazioni = Object.assign({},this.impostazioni,impostazioni). In questo modo uniamo i due dizionari in un nuovo dizionario vuoto e trascriviamo tutto su this.impostazioni. In questo caso è molto importante l’ordine, difatti this.impostazioni viene assegnato prima di impostazioni, dizionario che contiene la parametrizzazione a livello utente. Così le nuove impostazioni andranno a sovrascrivere quelle precedenti, creando il dizionario definitivo delle impostazioni.

Adesso andiamo a creare il metodo di caricamento nella maniera seguente:

Qui stiamo utilizzando due metodi che non abbiamo ancora dichiarato, ovvero this.creazioneStile() e this.creazioneHome(). Con this.contenitore = $(this.impostazioni.contenitore); intercettiamo il contenitore predefinito in precedenza e applichiamo, successivamente gli stili di base. Avrei potuto utilizzare anche un file CSS separato per la parametrizzazione degli stili, ma allo scopo di esercizio ho preferito fare tutto tramite JavaScript all’interno della classe stessa.

Delle istruzioni precedenti è molto importante passare l’opzione this.contenitore.css("position", "relative"); che definirà la posizione del contenitore come relativa. In questo modo potremo utilizzare internamente i riferimenti assoluti per posizionare i vari elementi. Senza la dichiarazione di posizione relativa in modo esplicito, gli elementi interni si sarebbero posizionati rispetto al primo oggetto genitore del contenitore che abbia una posizione dichiarata esplicitamente.

Per il metodo this.creazioneStile() procediamo nel modo seguente:

Sostanzialmente creiamo una sezione <style></style> all’interno del codice dentro la quale andremo ad aggiungere tutti gli stili. Per evitare sovrapposizioni esterne al contenitore anteponiamo ad ogni stile il descrittore in CSS del contenitore con this.impostazioni.contenitore. Infine aggiungiamo il gruppo di stile nell’intestazione con l’istruzione $('html > head').append(stile);

Dentro questo metodo procederemo ad aggiungere via via i vari stili di cui abbiamo bisogno.

Per il metodo this.creazioneHome() procediamo aggiungendo la seguente porzione di codice:

In questo metodo andremo a creare this.creazioneGioco() che verrà richiamato al click su START nella schermata di inizio. Quello che mi interessa in particolare durante questo passaggio è l’utilizzo di this. All’interno dell’evento click this si riferisce all’elemento oggetto del click. Di conseguenza non è più utilizzabile per riferirsi agli oggetti della classe. Per poterlo utilizzare dobbiamo riassegnarlo ad una variabile locale nel metodo genitore, come per esempio var questo = this;

In questo modo dentro l’evento di click potremo utilizzare l’istruzione questo.creazioneGioco(); che richiama un metodo della classe medesima (che dobbiamo ancora creare).

Per la creazione del gioco procediamo nel modo seguente:

Siccome il gioco potrà essere creato diverse volte, per esempio quando si riavvia durante la partita, oppure dopo che si è vinto, ci dobbiamo assicurare che tutte le variabili di gioco vengano inizializzate, ed eventualmente reimpostate, qui.

I metodi che mi interessano in particolare sono:

  1. this.carte = $.merge($.merge([], this.impostazioni.immagini), this.impostazioni.immagini); che ci consente di creare le 16 carte di cui avremo bisogno. Ricordiamoci che le carte sono in coppie quindi le 8 carte iniziali dovranno essere duplicate. Per farlo voglio unire lo stesso dizionario, dentro this.impostazioni.immagini, a se medesimo. Affinché la funzione $.merge non crei un puntatore sul vettore, continuando ad aggiungere le solite immagini ad ogni riavvio successivo e quindi scombinando il gioco, bisogna usare il trucco di chiamare il metodo con un vettore vuoto a cui viene accodato il vettore originale, con l’istruzione $.merge([], this.impostazioni.immagini). Adesso abbiamo creato un vettore completamente nuovo, che potremo poi accodare al solito vettore di prima ripetendo il passaggio una seconda volta. Se non si procede in questo modo al primo riavvio del gioco si rischieranno di avere 3 o 4 carte dello stesso tipo, perché in totale non saranno più 16 ma 32, poi 48 ecc.
  2. this.carte.sort(() => Math.random() - 0.5); che ci permette di ordinare casualmente le carte. Non è un metodo particolarmente efficiente e non produce nemmeno un livello di casualità particolarmente affidabile. Per generare una password non sarebbe quindi molto opportuno, ma per gli scopi che ci servono ai fini del gioco va benissimo, specialmente per la sua brevità di scrittura. Questa scrittura è anche la medesima di this.carte.sort(function(){ return Math.random() - 0.5; });
  3. $('#combo'+this.impostazioni.idunivoco).hide(); che nasconde il contenitore delle combo (poi vedremo meglio)
  4. for(var i = 0; i < 16; i++ ) this.creaCarta(i); che inserisce le carte nell’ordine casuale determinato dal primo punto

Procediamo adesso con la creazione del menu utilizzando this.creazioneMenu();

Faccio notare che il metodo di “restart” è praticamente identico al metodo che abbiamo visto per lo “start” nella home. Stessa procedura. Nel menu abbiamo aggiunto una voce per il punteggio corrente, una per il tempo trascorso e il tasto che consenta di ricominciare.

La creazione del timer implicherà due diversi passaggi, nella maniera seguente:

Il metodo contatoreTimer() si richiamerà su se stesso ogni 500 millisecondi su se stessa, aggiornando lo stato del gioco e dichiarando infine la conclusione dello stesso. In tale contesto andremo anche a calcolare il tempo trascorso e ad aggiornarlo nella visualizzazione.

Arriviamo adesso alla parte più importante, quella dove creiamo le carte e definiamo il funzionamento del gioco. Ricordiamoci che ogni carta dovrà essere cliccabile.

Per gestire la rotazione delle carte stiamo utilizzando jQuery Flip, che ci permette sostanzialmente di ruotare gli elementi sia manualmente che ad ogni click.

Per ogni carta, procedendo in ordine, definiamo quindi le singole proprietà di CSS e attribuiamo la caratteristica flip. Dopodiché al click su ogni carta procediamo con l’impostazione della struttura di gioco. Anzitutto verifichiamo che il gioco sia iniziato e che la carta sia cliccabile. Se la carta è giocabile e non è ancora stata aperta, apriamola con $(this).flip(false). Leggiamo il nome della carta con var cartagiocata = $(this).attr('data-nome'). Se la carta attuale non è ancora stata impostata, allora impostiamola e blocchiamo la carta con $(this).attr('data-giocabile',0). In caso contrario vuol dire che abbiamo già aperto una carta e quindi dobbiamo verificare se il risultato sia corretto o meno. Se la carta attuale è uguale a quella giocata allora vuol dire che è tutto corretto; blocchiamo quindi la carta, aumentiamo il conteggio delle carte aperte consecutivamente con questo.consecutivi++, incrementiamo il punteggio con questo.incrementaPunteggio() e conteggiamo il numero totale di carte aperte (8 coppie trovate equivale alla fine del gioco). Se le carte non sono uguali, allora diamo 800 millisecondi all’utente per poterle vedere entrambe e poi richiudiamole e reimpostiamole giocabili.

Nel suo complesso il codice che avremo creato sarà il seguente (ho incluso alcuni altri commenti specifici nel codice, per spiegare i singoli passaggi):

Per chiunque volesse cimentarsi nel gioco ne riporto di seguito anche la versione giocabile. Inutile dire che ci sarebbero ulteriori possibilità di perfezionamento e che nel gioco ci sono anche alcuni bug che accadono quando si clicca troppo rapidamente tra una carta e l’altra.

Facendo un po’ di prove per ora il meglio che sono riuscito a ottenere, senza usare sotterfugi come screenshot e simili, è stato il seguente risultato:

[excel] Creare un grafico variabile che si adatti alla lunghezza della serie, sfruttando le matrici

Obiettivo: voglio realizzare un grafico che prenda in input n valori x e y, dove n è un valore arbitrario. Questo significa che se imposto n = 7 allora avrò 7 valori di x e y opportunamente calcolati. Per esempio potrebbe trattarsi del valore annuale delle rate di un mutuo calcolato su n anni; quindi se metto 10 anni mi aspetto un grafico con 10 colonne, se metto 20 anni mi aspetto un grafico con 20 colonne, ecc.

Nel caso specifico voglio realizzare qualcosa che dia il seguente risultato.

Per una simulazione con n = 25 anni

Per una simulazione con n = 30 anni

Faccio notare che il grafico è rimasto lo stesso, non ho dovuto rifarlo, ma è aumentato il numero di valori sull’asse delle ascisse in base al numero di anni prescelto.

Per l’esercizio voglio anche sfruttare le nuove possibilità offerte dal recente aggiornamento di Office 365 in merito al calcolo e alla visualizzazione delle matrici.

La versione di Excel che ho utilizzato è la Versione 1912 (build 12325.20298) e non tutte le funzionalità potrebbero essere disponibili nelle versioni precedenti.

Detto tutto questo cominciamo.

Anzitutto quello che voglio realizzare, a titolo di esercizio, è un simulatore semplificato di investimento con mutuo. Vogliamo cioè costruire il business plan per la realizzazione di un qualche progetto che avrà un rendimento annuale e per il quale vogliamo chiedere un finanziamento. I dati di cui avremo bisogno in input saranno quindi

  1. Valore complessivo del progetto (es. 250.000€)
  2. Valore del mutuo per il finanziamento iniziale (mutuo calcolato a tasso fisso su una percentuale del valore del progetto, per esempio l’80% al 3% in 15 anni con rate mensili)
  3. Entrate annuali per il progetto operativo (es. 30.000€ / anno)
  4. Durata del progetto (es. 30 anni)
  5. Tasso di inflazione (es. 2%)

Predisponiamo quindi i valori in input a partire dalla cella C4 nel modo seguente:

Di tutti i valori l’unico calcolato è il valore della rata, dove abbiamo la seguente formula:

Rinominiamo il foglio su cui stiamo lavorando in MUTUO, questo ci servirà dopo:

Adesso calcoliamo i valori di gestione disponendoli nel modo seguente a partire dalla cella H4.

Calcoliamo gli anni che partiranno da 0 fino all’anno indicato in D10. Se in D10 ci fosse 30 il numero totale di anni sarebbe quindi 31. Il numero di anni sarà quindi sempre n + 1. Dal punto di vista teorico l’anno 0 è quello degli investimenti pre-operativi; non è indispensabile ai fini dell’esercizio ma, sebbene stiamo facendo un esempio semplificato, facciamo le cose per bene.

Voglio che gli anni siano generati, come tutto il resto, in modo dinamico senza dover predisporre un numero massimo di valori possibili. Per farlo sfruttiamo le funzioni sulle matrici di excel nel modo seguente:

Inserendo questo valore in H5 nelle celle sottostanti verranno automaticamente completati i dati conseguenti. Selezionando la cella H5 ci verrà mostrata una selezione blu sottostante:

I dati evidenziati non sono inseriti nelle celle, ma generati automaticamente in quanto il risultato in H5 è una matrice colonna contenente i valori calcolati.

Procediamo in modo analogo per le colonne seguenti. Dal momento che vogliamo che ogni colonna sia generata per intero e non debba fare affidamento sulla colonna a fianco, procederemo col calcolo matriciale. Per le rate inseriremo in I5 la seguente formula:

Nel caso specifico dobbiamo usare un doppio se, perché la funzione =E() non è compatibile col calcolo matriciale. Con il primo SE verifichiamo che l’anno sia maggiore di 0, con il secondo SE verifichiamo che l’anno sia minore o uguale all’anno finale del mutuo, in tal caso inseriamo il valore della rata in D12, altrimenti lasciamo a 0.

Per la colonna dei costi, che, come nell’immagine precedente, avrà in realtà un unico valore e il resto a 0, inseriamo la seguente formula:

In pratica l’unico costo iniziale che abbiamo è la parte del progetto non coperta dal mutuo, calcolata con la formula -D4*(1-D7)

Nella colonna delle entrate inseriamo la seguente formula:

In modo analogo a prima quando l’anno è maggiore di 0 allora mettiamo il valore delle entrate annuali in D9. Il risultato lo dividiamo per (1+2%)^anno, dove il 2% è il tasso di inflazione e l’anno è l’anno corrente. Potremmo discutere se mettere al primo anno come anno 1 oppure 0, ma non è questa la sede. Nel mio caso lascerò il valore a 1.

A questo punto scriviamo la colonna della cassa. Questa è la più semplice da realizzare perché è semplicemente la somma delle precedenti tre formule, messe in fila una dopo l’altra.

Adesso vogliamo calcolare il cumulativo di cassa. Qui le cose si complicano perché lo vogliamo fare sulle matrici.

Per intendersi ipotizziamo di avere i seguenti valori: 1, 2, 3, 4, 5

Il valore cumulativo sarebbe dunque: 1, 3, 6, 10, 15

Ovvero la somma di tutti i valori precedenti al valore corrente.

Adesso noi sappiamo che l’istruzione RIF.RIGA(INDIRETTO("1:"&(D10+1))) ci dà dei valori che vanno da 1 a n+1. I valori della cassa si troveranno via via in L5:L[x] dove L[x] sarà in sequenza: L5, L6, L7 ecc.

Quindi possiamo sfruttare l’istruzione precedente sommandole un +4 per trovare tutti i valori di L[x] di cui abbiamo bisogno.

In questo modo verrà generata una serie di matrici contenenti ciascuna i valori da sommare. Per capirsi, riprendendo la sequenza numerica di prima, il risultato sarebbe simile a questo:

La funzione =SOMMA() applicata alla seconda matrice darebbe purtroppo un UNICO risultato. Per ottenere una matrice colonna con la somma delle singole righe della matrice quadrata dobbiamo usare la funzione =SOMMA.SE(). La condizione di somma sarà banalmente <>0

La formula che quindi andremo ad inserire sarà:

Fatte tutte queste belle cose avremo costruito la tabella come mostrato prima.

Questa tabella cambierà automaticamente di dimensione in base al numero di anni. Se per esempio mettessimo gli anni del mutuo a 8 e l’operatività complessiva a 15 passeremmo a qualcosa come questo:

A questo punto andiamo a realizzare il grafico. Per farlo sfrutteremo la definizione dei nomi.

Anzitutto andiamo in Formule > Gestione nomi

Da qui definiremo i nomi nel modo seguente:

Attribuiamo un nome e creiamo un riferimento. In tutti i casi sfrutteremo la funzione scarto che partirà sempre dalla riga 5 e si estenderà per una altezza di n – 1 valori, dal momento che la colonna possiede un titolo. Creiamo quindi i seguenti nomi:

CASSA

CUMULATIVO

ANNI

Andiamo adesso ad inserire un istogramma da Inserisci > Grafici

In seleziona dati aggiungiamo due voci di serie, nello specifico CASSA e CUMULATIVO

Nel nome della serie scriviamo via via la descrizione, per esempio Cassa, mentre nei valori scriviamo:

Ricordiamoci che MUTUO è il nome del foglio. E’ molto importante anteporre alla definizione del nome il nome del foglio, altrimenti non funzionerà.

Alla voce etichette inseriamo:

Il risultato che otterremo sarà simile a questo:

Fatto questo otterremo un grafico simile al seguente:

Per trasformare il flusso cumulativo in una linea, anziché nell’istogramma, clicchiamo col destro su una delle colonne arancioni e scegliamo Cambia tipo di grafico serie…

Nella finestra che si aprirà selezioniamo, dal menu a tendina, la voce Linee

Se abbiamo fatto tutto bene otterremo un grafico come il seguente:

Il grafico cambierà dimensione al variare dei valori in input.

Il vantaggio di questa soluzione è che potremmo inserire valori assolutamente arbitrari per la lunghezza complessiva dei dati, senza doverla predisporre in anticipo. Se per esempio scegliessimo la durata del progetto su 500 anni, andrebbe comunque bene.

[FIFA20] La connessione con l’avversario si è interrotta

Esattamente come succedeva con FIFA19 anche con FIFA20 giocare online è un terno al lotto. Pertanto rimando anzitutto al precedente articolo per alcuni suggerimenti, come l’attivazione dell’UPnP e le verifiche sul firewall. La soluzione che propongo qui è pregare antiche divinità egizie quali Bast oppure Osiride, affinché siano caritatevoli e permettano di giocare.

Dico questo perché dopo diversi tentativi, spesso senza aver cambiato nulla rispetto alla situazione precedente, il gioco decide di partire, quindi la soluzione potrebbe essere: ritenta e sarai più fortunato. Lo con un pizzico di frustrazione perché è veramente incredibile.

Una cosa che talvolta, ma sottolineo talvolta e qui lo dico e qui lo nego, sembra aiutare è disattivare il protocollo IPv6 e riavviare la connessione dalla scheda di rete.

Per farlo, come ho scritto anche nel precedente articolo, basta andare sul Pannello di Controllo > Rete e Internet > Centro connessioni di rete e condivisione

Sulla destra clicchiamo sulla voce Modifica impostazioni scheda

Si aprirà l’elenco delle nostre schede di rete. Individuiamo la nostra scheda di rete e clicchiamo col destro sopra, poi andiamo su Proprietà:

Da qui rimuoviamo il protocollo IPv6 da quelli selezionati, ottenendo una schermata simile:

A questo punto diamo OK e torniamo sulla scheda di rete. Clicchiamoci sopra col destro e scegliamo Disabilita.

NB: Io queste operazioni le ho provate a gioco avviato, senza spegnerlo o riavviarlo.

Quando la scheda si disabilita clicchiamo di nuovo col destro e scegliamo Abilita come prima.

Torniamo al gioco, che nel frattempo ci avviserà che la connessione è stata perduta, e premiamo eventualmente R3 per ricollegarci dal menu principale (dovrebbe riconnettersi da solo dopo poco).

Adesso ritentiamo la fortuna. Ho avuto l’impressione che questa procedura sortisse qualche effetto, ma dal momento che sono stati fatti diversi tentativi a vuoto potrebbe essere stata anche solo un’incredibile coincidenza.

Sono arrivato anche a supporre che sia sufficiente riavviare la connessione, senza dover disabilitare l’IPv6.

Per la configurazione generale rimando all’articolo: [FIFA19] La connessione con l’avversario si è interrotta

Sottolineo il fatto che tutto il resto è rimasto inalterato (tentativi quali disabilitare il firewall non avevano sortito alcun effetto) e che semplicemente, insistendo per quei 20 minuti buoni che ti fanno perdere la pazienza, il gioco ad un certo punto decideva che era possibile giocare in rete.

Quando si dice che serve tanta pazienza…

[python] Disegnare un fiocco di neve con OpenGL, Python e pygame

Visto che siamo in tema natalizio vediamo come disegnare un fiocco di neve con Python, OpenGL e pygame.

Questo esercizio riprende in parte quanto già visto per disegnare un poligono sempre con Python e OpenGL.

Anzitutto assicuriamoci di avere installate le librerie PyOpenGL e pygame, qualora non le avessimo sarà sufficiente installarle mediante pip con i seguenti due comandi:

Fatto questo possiamo cominciare a predisporre il nostro programma.

Anzitutto voglio fare un breve approfondimento su alcune funzioni che andremo ad utilizzare.

Cominciamo da gluPerspective. Questa funzione accetta 4 argomenti:

  • fovy: sostanzialmente l’angolo di visione in gradi, come illustrato nell’immagine di seguito
  • aspect ratio: il rapporto tra altezza e larghezza, sostanzialmente ci andiamo ad inserire il rapporto tra le dimensioni del nostro schermo (poi ne discutiamo meglio)
  • zNear: il piano più vicino dopo il quale comincia la visione
  • zFar: il piano più lontano al quale termina la visione
Risultato immagini per gluPerspective"
Immagine presa da GLUT and OpenGL by Robby T. Tan

Ricordiamoci che andremo a disegnare un oggetto in 3D, che dovrà essere posizionato all’interno del tronco di piramide definito dai due piani e dall’angolo di apertura. Se l’oggetto dovesse uscire da questo spazio semplicemente non risulterebbe visibile sullo schermo (o risulterebbe parzialmente tagliato). Da questo si capisce come l’angolo di apertura determinerà la prospettiva e lo spazio di interazione dell’oggetto. La situazione sostanzialmente è la seguente:

Per maggiori approfondimenti consiglio anche una lettura veloce a Perspective distortion (photography)

Dal momento che andrò a posizionare i nostri oggetti a partire da (0,0,0) voglio anche spostare il punto di visione (viewpoint) indietro, in modo da farceli entrare, altrimenti non sarebbero visibili. Per farlo utilizzo la funzione glTranslatef che prendere come argomenti i valori x, y e z sui quali effettuare la traslazione.

Infine voglio disegnare delle linee usando i rispettivi vertici. Per farlo dovrò aggiungere coppie di vertici alla “matrice del mondo” con il metodo glVertex3fv. Nel caso specifico posso disegnare una linea orizzontale che vada da (0,0,0) a (1,0,0) scrivendo le seguenti quattro righe di codice:

Se volessi disegnare un quadrato dovrei disegnare tutte le linee a coppie di vertici, nel modo seguente:

Sostanzialmente quello che facciamo in questo caso potrebbe essere riassunto col seguente schema:

Disegniamo le varie linee del quadrato seguendo le direzioni delle frecce rosse.

Adesso se volessimo limitarci a disegnare un quadrato e farlo ruotare davanti alla telecamera potremmo scrivere il seguente programma:

Grazie a glClearColor(0, 0, 0.1, 1) coloriamo lo sfondo di un blu scuro. Eseguendo il programma vedremo qualcosa di simile:

Il quadrato sarà in movimento ovviamente, grazie alla funzione glRotatef che ruota la matrice del mondo.

Arrivati a questo punto ci manca solo di disegnare il fiocco di neve, ovvero preparare le coppie di vertici di tutte le linee del fiocco di neve stesso.

Per farlo voglio seguire il seguente schema:

Partiamo dal basso e disegniamo un ramo di lunghezza L. Prendiamo come riferimento un angolo α di 45° (ovvero π/4). Alla fine del ramo teniamo conto dell’angolo di arrivo e disegniamo altri due rami, ciascuno spostato di 45°. Procediamo in avanti ripetendo questo schema per n iterazioni.

Creiamo quindi due classi, una per il Fiocco e una per ciascun Ramo, nel modo seguente (nei commenti in Python ulteriori dettagli):

Fatto tutte questo reintegriamo il tutto nella nostra classe iniziale FioccoDiNeve.

Se abbiamo fatto tutto correttamente otterremo il nostro fiocco di neve frattale ruotante in questo modo:

[FIFA20] Avviare FIFA 20 da Steam e utilizzare il controller DualShock della PS4 su PC

Un’altra soluzione, per usare il DS4 su PC, alternativa all’uso del DS4Windows di cui ho parlato nel precedente articolo, è lanciare FIFA20 direttamente da Steam Big Picture, utilizzando la gestione del controller di Steam stesso (che ricordo essere perfettamente compatibile con i controller PS4).

Per farlo basta seguire la seguente procedura:

1. Disabilitare la sovrapposizione in gioco di Origin

Andare su Origin > Impostazioni applicazione > Origin in gioco e disabilitare l’opzione Attiva Origin in gioco.

In questo modo Origin non interferirà con Steam.

2. Aggiungere il gioco in Steam

A questo punto apriamo Steam e andiamo su Giochi > Aggiungi un gioco non di Steam alla libreria…

Si aprirà una lista di programmi da cui cerchiamo e selezioniamo FIFA20 (nell’immagine di seguito c’è per esempio FIFA19 che non ho aggiunto ancora su Steam).

Spuntiamo il gioco desiderato e premiamo il tasto Aggiungi i programmi scelti.

Fatto questo vedremo comparire il gioco nella nostra lista di giochi.

3. Configuriamo FIFA20 affinché si avvii senza la schermata di Start.

Dal momento che voglio avviare il gioco da Steam Big Picture, che viene controllato dal controller, voglio saltare la noiosa schermata delle impostazioni e di avvio che si apre di predefinito con FIFA.

Per farlo vado a modificare il file in [...]\Origin Games\FIFA 20\FIFASetup\config.ini che si trova nella cartella di installazione del gioco.

Apriamo il file con un editor di testo e aggiungiamo, in fondo, la seguente riga: AUTO_LAUNCH = 1

Una volta modificato il file dovremmo vedere qualcosa come questo al suo interno:

Salviamo e chiudiamo il file.

4. Per giocare avviamo Steam Big Picture

A questo punto possiamo avviare Steam Big Picture cliccando sull’apposita icona in alto a destra.

Da dentro l’applicazione possiamo lanciare FIFA20 e sfruttare le configurazioni e la gestione del controller della PS4 da parte di Steam.

In aggiunta così possiamo anche sfruttare tutte le opzioni della sovrapposizione Steam, compresi gli screenshot con F12.

[FIFA 20] Giocare utilizzando il controller della PS4 sul PC con DS4Windows

Dopo diverse peripezie sono giunto alla conclusione che per FIFA20 la soluzione migliore sia usare Steam Big Picture per le configurazioni del controller PS4. Qui la spiegazione su come fare.

Origin proprio non ne vuole sapere di rendere compatibili i controller DualShock di PS4 con i propri giochi, quindi bisogna munirsi di soluzioni alternative. Nel caso specifico si può usare DS4Windows. Però anche in questo caso le sorprese non mancano. Se con FIFA 19 basta avviare il programma, con FIFA 20 bisogna anche ricorrere all’opzione Hide DS4 Controller.

Anzitutto scarichiamo l’ultima versione di DS4Windows. Possiamo farlo dalla pagina del progetto ufficiale.

Scarichiamo l’ultima versione e scompattiamola nella posizione che preferiamo.

Troveremo un elenco di file in questo modo:

Se vogliamo possiamo aggiungere, per comodità, il collegamento all’eseguibile nel Menu Start. Per farlo clicchiamo col destro sull’eseguibile e selezioniamo l’opzione Aggiungi a Start.

Fatto tutto questo avviamo DS4Windows.exe.

Se non lo abbiamo ancora configurato partirà l’installazione del ViGEmBus Driver.

Nel mio caso cliccherò sullo Step 1: Installa the ViGEmBus Driver.

A questo punto spostiamoci sulla scheda delle impostazioni e spuntiamo l’opzione Hide DS4 Controller.

E’ possibile che ci appaia un messaggio di questo genere: Warning: Could not open DS4 90:89:5F:94:F3:53 exclusively. You must quit other applications like UWP apps (Netflix), Steam, Uplay, NVIDIA IN-GAME before activating the 'Hide DS4 Controller' option. For more info check https://github.com/Ryochan7/DS4Windows/wiki/Exclusive-Mode-(Hide-DS4-Controller-config-option)-tips-and-issues

Il programma ci sta avvisando, in sostanza, che altri programmi impediscono la disattivazione del controller che Windows vede automaticamente. Finché non lo disattiviamo il gioco vedrà entrambi i controller, sia quello creato dal DS4Windows, che quello installato direttamente su Windows stesso.

In poche parole, sul pannello di controllo, da Pannello di controllo > Hardware e suoni > Dispositivi e stampanti si vedranno 2 controller che in realtà sono uno solo:

Affinché l’operazione vada a buon fine dobbiamo disattivare tali programmi, chiudendo quindi tutte le applicazioni come Steam, Uplay oppure Origin stesso.

Inoltre dobbiamo disattivare anche la Sovrapposizione NVIDIA che utilizza il controller.

Per farlo andiamo su NVIDIA GeForce Experience cliccando col destro sull’icona nel vassoio di sistema:

Andiamo sulle impostazioni cliccando sull’ingranaggio in alto a destra:

Da qui deselezioniamo sovrapposizione di gioco.

A questo punto dovremmo essere in grado di usare tranquillamente il controller della PS4 emulato da DS4Windows.

Nel caso ci fossero problemi su questo ultimo passaggio riavviare il PC e prima di avviare qualunque altro programma far partire DS4Windows.

Se dopo il riavvio il controller continuasse a dare problemi, oppure non fosse accessibile a DS4Windows, andare in Pannello di controllo > Hardware e suoni > Dispositivi e stampanti e cliccare col destro su Wireless Controller selezionando l’opzione Rimuovi dispositivo.

Una volta rimosso staccare il cavo USB dal controller e riattaccarlo, aspettando l’installazione dei driver da parte di Windows.

Stimare budget e fattibilità di una campagna su Facebook (simulatore in Excel)

Link (anche in fondo) al Simulatore campagna pubblicitaria su Facebook (Excel)

Quando si intende fare una campagna pubblicitaria online bisogna tenere conto di diversi fattori, oltre che degli obiettivi per cui la campagna è pensata.

A differenza della pubblicità tradizionale (quella che si potrebbe fare sui giornali, sulla TV oppure sui cartelloni per strada) nelle campagne online è possibile verificare le conversioni prodotte dalla campagna stessa.

Con conversioni si intendono quelle azioni intraprese dagli utenti che hanno visto la pubblicità e per le quali la campagna pubblicitaria era stata pensata. Nel caso di una campagna pubblicitaria finalizzata alla promozione di prodotti, la conversione equivale all’acquisto di un prodotto. La conversione potrebbe essere anche l’iscrizione ad una newsletter, una richiesta di contatto o preventivo ecc.

Il processo di conversione può essere sintetizzato nel seguente schema:

 

Analizziamo brevemente i singoli passaggi del processo:

  1. Impressioni: le volte che la pubblicità viene mostrata, se la pubblicità viene mostrata 30.000 volte allora si avranno 30.000 impressioni. Le impressioni sono sempre maggiori o uguali al pubblico raggiunto. Un pubblico di 20.000 persone potrebbe generare 30.000 impressioni. Questo vorrebbe dire che in media ogni persona raggiunta ha visto la pubblicità 1,5 volte. Questo valore viene chiamato anche frequenza.
  2. Visite (o click): il numero di persone che, dopo aver visto la pubblicità, decidono di interagire con essa (o più semplicemente cliccano sull’inserzione). Il rapporto tra quelli che vedono la pubblicità e quelli che decidono di cliccare si chiama CTR (Click-through rate, in italiano “percentuale di click”). In generale come CTR medio si prende, in assenza di ulteriori dati statistici, un valore del 1%. Un CTR del 2% può essere già considerato ottimo. Questo valore dipende ovviamente anche dal messaggio pubblicitario stesso e da altri elementi. Un CTR molto elevato non è garanzia di alcun tipo di successo; significa solamente che le persone cliccano frequentemente sulla pubblicità. Un messaggio pubblicitario fuorviante potrebbe produrre un CTR molto elevato, che non corrisponde poi ad alcuna conversione significativa. Inoltre ad ogni click, in una campagna online, è associato un CPC (costo per click), ovvero quanto spendiamo per ogni click ottenuto. Se il CPC fosse di 0,50€ vorrebbe dire che per ogni click pendiamo 0,50€.
  3. Leads: sono semplicemente dei potenziali acquirenti, persone interessate al prodotto, che ancora non hanno deciso di acquistare il prodotto stesso. Un lead potrebbe “condurre” (di qui il nome) anche altri eventuali clienti all’acquisto del prodotto, tramite per esempio il passaparola, sebbene egli stesso poi non effettui alcun acquisto. E’ importante tenere conto dei lead solo dal punto di vista concettuale; significa che dobbiamo pensare la nostra campagna in modo che le pagine ad essa dedicata (le landing page) suggeriscano oppure consentano all’utente di lasciare i propri dati di contatto o memorizzare la pagina, per poter essere contattato successivamente o recuperare facilmente l’accesso al prodotto. Dal punto di vista statistico del processo di conversione i lead possono essere ignorati.
  4. Acquisti: sotto il termine acquisto si intende qui la finalizzazione della conversione, cioè quell’azione per cui la campagna è stata pensata. Nella maggior parte dei casi si tratta appunto dell’acquisto di un prodotto, ma potrebbe anche trattarsi di una richiesta di contatto, una donazione, un’iscrizione ad una newsletter o un gruppo, ecc. Il rapporto tra il numero di visitatori e il numero di acquisti, ovvero conversioni, viene chiamato tasso di conversione. Se per esempio ottengo 200 visite dalla campagna (click) e ne conseguono 2 acquisti, il tasso di conversione sarà del 1%. In media il tasso di conversione, in mancanza di ulteriori dati statistici a disposizione, oscilla tra il 1% e il 3%. Il tasso di conversione è anche chiamato CVR o CR (conversion rate)

Appurato tutto questo vediamo come valutare una campagna pubblicitaria su Facebook.

Anzitutto procuriamoci dei dati statistici sull’andamento del mercato, a tale proposito utilizzerò quelli pubblicati da WordStream: Facebook Ad Benchmarks for YOUR Industry [2019]

A titolo di esempio immaginiamo di voler fare una campagna pubblicitaria per vendere dei prodotti casalinghi (vasi, piatti, accessori, complementi d’arredo).

WordStream ci informa che il mercato (Home & Garden) di riferimento ha i seguenti valori:

CTR 0,71%

CPC 2,78$ = 2,50€

CVR 7,02%

Da questi valori possiamo calcolare il costo di una singola conversione (CPA, costo per azione o cost per action) nel modo seguente:

CPA=\frac{1}{CVR}*CPC=\frac{CPC}{CVR}

Nel nostro caso specifico avremmo quindi:

CPA=\frac{2,50}{0,0702}=35,61

Questo significa che per vendere 1 prodotto tramite la pubblicità dobbiamo spendere 35,61€

Questo è il valore più importante da tenere in considerazione. In generale si stima che il budget destinabile ad una campagna pubblicitaria rispetto al valore dell’evento (o dei prodotti che si intendono vendere) si dovrebbe aggirare entro il 12% di quest’ultimo.

Questa proprietà può essere estesa ai singoli prodotti, per cui se un prodotto viene venduto a 100€, il massimo che possiamo spendere in pubblicità per venderlo non dovrebbe superare i 12€. Naturalmente questo valore varia notevolmente da prodotto a prodotto e dai margini che abbiamo sul valore dei prodotti stessi.

Esempio: se intendiamo vendere delle camere di albergo mediante una campagna pubblicitaria, dobbiamo tener conto del fatto che sulle OTA le percentuali che vengono prelevate per la vendita si aggirano dal 15% al 18%. Questo significa che possiamo valutare la nostra campagna prendendo il 15% o il 18% come valore di riferimento. Se quindi una camera costa 80€ a notte possiamo spendere fino a 12€ o 14,40€ per cercare di venderla tramite una campagna pubblicitaria. Se la campagna pubblicitaria richiedesse una cifra superiore per venderla potremmo valutare se fare la campagna per la vendita di pacchetti vacanze (più notti per più persone) oppure rinunciare e affidarci alle OTA. Se per esempio il CPA fosse di 33€, vorrebbe dire che dovremmo vendere servizi (camere) ad almeno 183,33€ (nel nostro caso dovremmo proporre, nella pubblicità, non la singola notte, quanto prenotazioni da almeno 3 notti, dove 3 x 80€ = 240€).

Detto questo abbiamo capito quindi che attraverso una campagna online dobbiamo cercare di vendere prodotti per almeno 296,75€.

Dal momento che vendere casalinghi a questo prezzo non è facile (per proseguire sulla nostra ipotesi), dobbiamo valutare che tipo di offerta promuovere attraverso la campagna. Alcune idee potrebbero essere:

  1. Incentivare una spesa di almeno 300€ (spedizioni gratuite, sconti, promozioni future, ecc)
  2. Aggregare i prodotti in pacchetti (vendere per esempio set dello stesso prodotto o set preconfezionati di prodotti pronti all’uso)
  3. Cambiare pubblico di destinazione (cambiare cioè il target; anziché vendere ai privati, potremmo indirizzare la campagna ad altri rivenditori, oppure ad albergatori che vogliono comprare set del medesimo prodotto per arredare diverse stanze nello stesso modo ecc.)

Attenzione! Resta il fatto che non possiamo sperare di vendere efficacemente prodotti che hanno un valore inferiore, per esempio un vaso da 20€, laddove la spesa per ottenere la vendita è di 35,61€

Da questo si deduce un altro fatto importante: le campagne online non sono adatte alla vendita di qualsiasi prodotto.

Per facilitare questo tipo di calcoli ho realizzato un piccolo simulatore in Excel, che ci permette anche di tenere conto di ulteriori dati statistici, quali la dimensione del pubblico, il costo di gestione della campagna, la frequenza di visualizzazione della campagna ecc.

Immettendo i dati di poco prima otterremmo qualcosa di simile a questo:

Nella mia ipotesi ho immaginato una campagna da 5€ al giorno, per una durata totale di 10 giorni ed un pubblico di 10.000 persone. Il valore dei prodotti è di 20€. Il calcolatore mi dirà chiaramente che la campagna non è sostenibile.

Se cambiassi il valore dei prodotti a 300€ otterrei il seguente risultato:

Se adesso provassi ad aumentare il budget giornaliero, portandolo a 60€ al giorno, otterrei di nuovo una campagna fuori dai parametri preimpostati.

Questo perché raggiungendo la saturazione del pubblico (ricordiamoci che sto ipotizzando un pubblico di 10.000 individui) aumenterei la frequenza di visualizzazione che, secondo quanto suggerito da Facebook stesso, non dovrebbe superare i 2 punti. Più è alta la frequenza e più la campagna è onerosa.

E’ altrettanto vero che anche con un budget di 10€ al giorno ed un costo di gestione della campagna (quello che pago a chi la configura e gestisce) di 150€, la campagna resta non fattibile.

Per chiunque volesse cimentarsi in questo genere di simulazioni metto a disposizione il simulatore in Excel utilizzato qui sopra:

Simulatore Facebook Ads

Il simulatore è stato realizzato per il Corso di Social Media Marketing della Mummu Academy di Firenze.

[c#] Creare una classe per stampare con i font installati nella stampante

L’obiettivo è quello di inviare del testo alla stampante utilizzando i font nativi al suo interno e la libreria gdi32.dll di Windows. Questa volta integreremo tutto in una semplice applicazione in C#.

Anzitutto creiamo un semplice form con una TextBox chiamata txtTesto ed un Button chiamato btnStampa.

Aggiungiamo poi una nuova classe che estenda la classe System.Drawing.Printing.PrintDocument

Per usare la classe anzitutto dobbiamo implementare alcuni metodi e creare i corrispondenti per le funzioni della libreria GDI32.

A tale scopo utilizzeremo l’istruzione [DllImport("gdi32.dll")] prima delle specifiche definizioni.

Le funzioni che dobbiamo implementare sono rispettivamente: CreateFont, SelectObject, DrawText, DeleteObject

Per maggiori riferimenti alle singole funzioni consiglio di visionare il sito Pinvoke.net

Detto tutto questo costruiamo la classe nel modo seguente:

Eseguiamo il test della funzione nel form principale:

In questo modo stamperemo attraverso la stampante predefinita.

Nel mio caso una stampante Samsung M2070, che riconosce come font “Courier New“.