Query per recuperare gli utenti attivi in un determinato time range

Bisogna presentare un grafico che rappresenta il numero di utenti attivi in trial per ogni giorno del mese.

Abbiamo una tabella in Sql Server che riporta per ogni utente la data di iscrizione e di fine trial.

Il grafico ha bisogno di una riga per ogni giorno con il count di tutti gli utenti che corrispondono alla condizione di ricerca.

Come procedo con un unica query?

La soluzione è utilizzando una CTE, come nell’esempio che segue. Facile, veloce e pulito.

;with days As
(
select DATEADD(day,1,'2019-01-01') as TheDate
UNION ALL
select DATEADD(day,1, TheDate) from days
where TheDate < '2019-01-31’
)
select
*
from days m
outer apply (
select
COUNT(*) UserCount
from Subscribers
where
CreatedDate <= m.TheDate and (ISNULL(ExpirationDate,’3000-01-01')>= m.TheDate) AND ACTIVE=1 AND TRIAL
) Users
OPTION (MAXRECURSION 0)

Attenzione a dettare MAXRECURSION = 0, altrimenti la CTE si ferma dopo un numero predefinito di cicli che di default è a 100.

Il bravo manager

Leggo continuamente articoli che elencano le doti del bravo manager, in molte mi riconosco, ma spesso non condivido le stesse priorità.

Sono fermamente convinto che un manager deve essere un punto di riferimento per il team, come un padre di famiglia: avere il rispetto dei colleghi, ma anche portarne.

Non bisogna essere tirannici, ma ascoltare le idee di tutti e confrontarsi sulle soluzioni possibili, condividendo quanto più possibile le scelte con il gruppo di lavoro.

Bisogna avere la giusta competenza per poter consigliare e orientare il team. Di certo non si può sapere tutto, ma é fondamentale poter dare il suggerimento giusto per sbloccare qualche situazione di stallo o per indirizzare nelle scelte da fare per portare a termine il progetto.

Chiaramente bisogna continuare a studiare ed aggiornarsi, ma anche stimolare la condivisione e il technology transfer con i colleghi che aiuta ad accrescere velocemente le proprie conoscenze.

Per essere efficaci, bisogna avere il coraggio di dare autonoma al gruppo, senza troppe ingerenze, ma confrontandosi continuamente con i collaboratori per ascoltare la loro idea, capire cosa stanno facendo e intervenendo con le dovute correzioni quando stanno andando fuori strada.

Dal punti di vista del business bisogna avere chiari gli obiettivi e condividerli con il team. Se tutti sono allineati e focalizzati, sarà molto più facile arrivare al risultato, anche sperimentando metodologie diverse, ma finalizzate a raggiungere lo stesso obiettivo.

La parte più difficile è rendere tutti partecipi lavorando in modo inclusivo, evitando così malumori e frustrazione per i meno coinvolti. Per questo è importante rapportarsi con i collaboratori in modo continuo, conoscere le attitudini di ognuno e saper orchestrare il lavoro in modo da liberare il potenziale dei singoli.

Non bisogna mai dimenticare di riconoscere attivamente i meriti dei collaboratori, evidenziando i risultati raggiunti e non dando mai per scontato l’impegno profuso.
È forse la cosa più difficile, specie quando si é molto focalizzati sull’avanzamento del progetto.

Bisogna sempre e comunque incentivare la collaborazione, all’interno del team, ma anche con i colleghi e gli altri reparti. È fondamentale per la crescita delle competenze del gruppo, attraverso un confronto costruttivo e condividendo le idee.

Ma la cosa più importante è saper prendere le decisioni nel momento giusto, assumendosi le responsabilità e tutelare i propri collaboratori, che devono sempre potersi fidare del proprio leader.

Questa è la mia visione e il modo in cui cerco di gestire la quotidianità, con impegno e passione.

E voi cosa ne pensate? Lasciatemi un commento se avete altre idee.

Modificare i metadati delle foto con EXIFTool e geolocalizzarle per prossimità con quelle dell’iPhone

Questa estate ho deciso di fare ordine di tutte le foto accumulato negli anni su iCloud e il mio fedele Synology.

Il primo problema che ho incontrato si è presentato ruotando delle vecchie foto del matrimonio.
Di fatto queste foto digitali alquanto datate, non avevano dati EXIF relativi alla data di scatto, quindi il catalogo del Synology utilizzava come riferimento la data del file, con il risultato che tutte le foto ruotate si sono spostate nella timeline ad oggi.

Ovviamente è possibile modificare i files uno ad uno, ma la cosa diventava alquanto tediosa, quindi mi sono messo alla ricerca di un tool per automatizzare la correzione di questo e di eventuali altri casi mi fossero capitati nelle modifiche in corso.

Ho subito individuato EXIFtool come lo strumenti definitivo per questo tipo di attività, è maturo, completo e molto efficace. Sebbene la complessità da riga di comando non sia delle più banali, dedicandoci un pò di tempo ho trovato delle soluzioni veramente interessanti.

Per prima cosa dovevo ripristinare la data del file. L’operazione è alquanto semplice, ma visto che c’ero ho impostato correttamente anche tutte le date in formato Exif.

exiftool.exe -FileModifyDate="2002-09-28 00:00:00" -DateTimeOriginal="2002-09-28 00:00:00" -CreateDate="2002-09-28 00:00:00" -FileCreateDate="2002-09-28 00:00:00" -modifydate="2002-09-28 00:00:00" -datetime="2002-09-28 00:00:00" -P -overwrite_original *.jpg

In questo modo anche se le foto erano vecchie, ho corretto sia la data del file che tutti gli attributi interni. Nulla di più efficace per tornare allo stato iniziale ed evitare futuri casini.

Attenzione ad aggiungere sempre il parametro “-overwrite_original” altrimenti vi troverete la cartella piena di duplicati con i file originali in copia.

Arrivato a questo punto, visto che c’ero ho deciso di completare i tag Exif relativi alle date di tutti i file che ne fossero stati sprovvisti.

EXIFTool è molto potente, ma qui la cosa diventava più complicata. Intanto dovevo aggiornare la data del file in modo dinamico prendendola da un dato certo e poi applicarla solo nei casi in cui questa fosse stata valida.

Il comando corretto per fare questa modifica in un colpo solo è il seguente:

exiftool.exe -if "$CreateDate lt '0001:00:00'" -p "$directory\$FileName" "-DateTimeOriginal&lt;FileModifyDate" "-CreateDate&lt;FileModifyDate" "-FileCreateDate&lt;FileModifyDate" "-modifydate&lt;FileModifyDate" "-datetime&lt;FileModifyDate" -overwrite_original -q -f .

In sostanza utilizzando l’attributo -if si possono applicare dei filtri condizionali e con < si possono copiare attributi su altri attributi. Problema risolto, ora tutte le mie vecchie foto sono taggate indipendentemente dalla data del file.

Proseguendo con il lavoro di pulizia, ho realizzato che per diversi viaggi, mi trovo nella situazione di aver fotografato sia con la mia Sony che con il cellulare. Il risultato è che le foto fatte con il cellulare sono geo-localizzate alla perfezione, mentre quelle prese con la reflex, no.

Solitamente le selezionavo tutte dall’archivio del Synology e impostavo una posizione di massima della città visitata, ma sono pignolo e la cosa non mi piaceva troppo. Anche qui ci viene in aiuto EXIFTool, con le importanti capacità di geotagging. Immaginiamo di avere nella stessa cartella sia foto dell’iPhone che foto della reflex.

Per prima cosa dobbiamo estrarre tutto il percorso fotografico prendendo la posizione di tutte le foto del iPhone e creando un bel file GPX con tutti i punti. Questa operazione è molto semplice, ma bisogna stare attenti ai dettagli. Il comando che ho usato è:

exiftool -r -if "$gpsdatetime" -fileOrder gpsdatetime -p gpx.fmt . &gt; out.gpx

Prima di tutto vi serve un file template per il formato GPX, che inserisco in fondo al post.

Gli altri parametro sono la verifica che esista il tag gpsdatetime altrimenti i dati estratti non avrebbero senso e il programma va in crash, e il parametro fileOrder per avere una traccia ordinata per data e non in ordine sparso che ne impedirebbe la corretta interpolazione.

Una volta generato il file di traccia, possiamo applicarlo a tutte le foto che non sono geo-localizzate, e questa operazione si fa eseguendo il programma con questi parametri:

exiftool -r -if "not $gpsdatetime" -geotag out.gpx "-geotime&lt;DateTimeOriginal" -api GeoMaxIntSecs=7200 GeoMaxExtSecs=7200 -overwrite_original .

Qui c’è qualche trick che ci ho messo un bel pò a capire, nello specifico Geomaxintsecs permette di essere più flessibili in quando a time span temporale tra le foto, per me anche un ora è buona pur di localizzare più foto possibili.

Un altro trucco è impostare di forza il tag geotime, altrimenti molti degli aggiornamenti falliscono.

Per il resto il risultato è ottimale e non avrei saputo come ottenerlo cosi velocemente e gratis.

EXIFTool è uno strumento fondamentale per il fotografo puntiglioso che vuole tutto in ordine, ma prevede anche una buona dose di pazienza e ricerca per capire come si usano le miglia di comando che mette a disposizione.

Segue il template per il file di traccia GPS in formato GPX. Copialo in un file.
#----------------------------------------------------------------------
# File: gpx.fmt
#----------------------------------------------------------------------
#[HEAD]<?xml version="1.0" encoding="utf-8"?>
#[HEAD]<gpx version="1.0"
#[HEAD] creator="ExifTool $ExifToolVersion"
#[HEAD] xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
#[HEAD] xmlns="http://www.topografix.com/GPX/1/0"
#[HEAD] xsi:schemaLocation="http://www.topografix.com/GPX/1/0 http://www.topografix.com/GPX/1/0/gpx.xsd">
#[HEAD]<trk>
#[HEAD]<number>1</number>
#[HEAD]<trkseg>
#[IF] $gpslatitude $gpslongitude
#[BODY]<trkpt lat="$gpslatitude#" lon="$gpslongitude#">
#[BODY] <ele>$gpsaltitude#</ele>
#[BODY] <time>${gpsdatetime#;DateFmt("%Y-%m-%dT%H:%M:%SZ")}</time>
#[BODY]</trkpt>
#[TAIL]</trkseg>
#[TAIL]</trk>
#[TAIL]</gpx>

Perché l’Apple TV è una sola (nel senso di fregatura)

Sono ormai 3 mesi che ho comprato la Apple TV 4K, e mi sono reso conto che sono soldi buttati. In primo luogo l’Italia è mal servita in quanto ad app e funzionalità. Gran parte di quanto pubblicizzato, da noi non funziona, neppure Siri è abilitato.


Poi se guardiamo le applicazioni disponibili nel bel paese, scopriamo che molte di quelle presenti nelle Smart tv non ci sono, e che i broadcaster nostrani, tipo Sky, ben si guardano da fornire un app compatible, nonostante ci sia per iPad, mentre all’estero le troviamo tutte.
Poi la competizione porta a delle limitazioni davvero ridicole, come i video di YouTube non sono a 4K perché Apple non implementa i formati pensati da Google.
Insomma, se confrontata con una Smart TV Samsung o LG, che conosco bene, non da nulla in più da punto di vista squisitamente televisivo.

Se invece guardiamo al mondo dei giochi, allora le cose cambiano. Ci sono parecchie app videoludiche, che però costano carissime rispetto alla versione iPad e spesso sono di qualità inferiore.

Resta solo la condivisione dello schermo nativa per i dispositivi Apple, ma detta tutta per un uso domestico, non vale poi molto.

Tirate le somme, per gli stessi soldi si può acquistare una console che di certo ci darà maggiori soddisfazioni.

CRM 2018 – cosa aspettarsi dal mercato

Il trend per l’anno alle porte è già ben delineato: si chiama AI.

Vuoi perché è il principale driver del mercato informatico, vuoi perché è la chimera di tutti i commerciali, ovvero poter lavorare meno e meglio, con un software che fa da solo le operazioni più tediose.

L’intelligenza artificiale è una realtà, la vediamo in azione quotidianamente quando utilizziamo il navigatore di Google, e chiediamo delle informazioni a Siri. Ora è arrivato il momento di portarla anche nel CRM.

E’ una sfida molto importante, e non sarà affatto semplice comprendere e analizzare gli schermi comportamentali utilizzati dagli utenti, distinguendo le azioni che portano al successo di una vendita da quelle che invece non concludono.

Un aspetto fondamentale per raggiungere questi obiettivi è un utilizzo continuo e coerente dello strumento, ed evitare che parte del processo avvenga al di fuori di esso, impedendo così al software di avere una copertura completa del ciclo di vendita.

Perciò non ci sarà solo un’evoluzione della piattaforma di CRM, ma dovrà anche evolversi il modo in cui viene utilizzata dagli utenti, che spesso si limitano a rendicontare, in modo rapido e superficiale, piuttosto che pianificare le attività di vendita.

Il primo passo è già stato fatto da sistemi esperti che analizzano l’evoluzione dei trend all’interno dei CRM e suggeriscono all’operatore le azioni da svolgere per migliorare le sue performance, sulla base dell’analisi del pregresso.

Ma sarà lo step successivo a dare una svolta radicale al modo di lavorare con un CRM, ovvero quando i workflow relativi a processi di vendita o di assistenza, si adatteranno automaticamente in funzione delle esperienze precedenti analizzate dal sistema di AI.

Come per tutte le innovazioni, all’inizio ci sarà molto “rumore per nulla” e molte false partenze, ma sono convinto che beneficeremo tutti dei sistemi intelligenti che stanno rapidamente permeando il nostro modo di lavorare, permettendoci di essere più efficienti e meno ripetitivi.

SqlServer e parallelismo, la chiave per incrementare le performance in pochi secondi

Nelle configurazioni di SQLServer c’è una sezione denominata Parallelismo.

Questa sezione contiene due chiavi che di default sono impostate con dei parametri eccessivamente aggressivi, e che non danno beneficio nella maggior parte dei casi. Agendo su queste due chiavi, si può migliorare le perfomance senza operare complesse attività di tuning.

  1. Massimo grado di parallelismo (Maximum Degree of Parallelism) è impostato di default a 0, il che significa senza limiti. Fa da se che SqlServer utilizza tutte le CPU disponibili durante l’esecuzione di una query. Se eseguiamo esclusivamente query molto pesanti e su un grandissimo numero di dati, questa configurazione è corretta, ma in un uso applicativo, questo approccio limita la concorrenza, creando dei colli di bottiglia. E’ preferibile limitare il parallelismo dai un numero di socket che permetta un livello di concorrenza sostenibile.

    Ad esempio, un una configurazione con 4 core, sentiamo il valore a 2.

  2. Costo soglia per parallelismo (Cost Threshold for Parallelism) è impostato di default a 5. E’ un valore un pò troppo basso, che induce l’ottimizzatole a valutare piani alternativi di esecuzione che possano utilizzare più thread contemporaneamente.

Anche questa impostazione è ideale per applicazioni di BI o OLTP, ma totalmente inadeguato per applicazioni con IO dati generico, come CRM e gestionali.

Va assolutamente aumentato ad almeno 30, ma c’è chi consiglia di portarlo anche a 50.

Personalmente ho riscontrato un beneficio immediato da un cliente che lamentava rallentamenti, con un crollo del carico della CPU dal 70% al 30% e un immediato raddoppio delle operazioni batch eseguite al secondo. Un must per l’ottimizzazione delle performance.

Sono delle impostazioni poco note ai più, ma fidatevi che avrete un server molto più performante con un operazione di pochi secondi.

Windows 10 bloccato alla build 10240

L’altro giorno sono tornato a casa e ho trovato il PC con Windows completamente andato, dopo un Windows Update.
Non c’è stato modo di ripristinarlo, quindi ho deciso di ripartire con un installazione pulita.

Reinstallato tutto, ho ripristinato tutte le applicazioni che uso abitualmente (grazie Chocolatey), ma mi sono accorto che Docker per Windows non partiva dicendo che non avevo una build 10586 o superiore.

A quel punto ho iniziato ad indagare, perchè Windows Update mi diceva che non ci sono aggiornamenti, e così ho scoperto che ci sono altre persone bloccate a questa build.

La soluzione che mi ha permesso di superare l’empasse è la seguente:

Andate su https://www.microsoft.com/en-gb/software-download/windows10 e scaricate Windows 10 Creators Update. (Precedentemente si era installa da sola).

A quel punto basta seguire i vari passaggi per avere Windows aggiornato all’ultima build.

Tutto qui, ma come al solito le cose semplici se nessuno te le dice diventano complicate.

Scrivere un immagine ISO da MacOS-OSX su una chiavetta USB

Ormai le unità CD/DVD sono completamente scomparse dai nostri Mac, ma spesso rimane la necessità di installare qualche distro Debian o Ubuntu su un PC che a sua volta non ha il DVD.

Il problema nasce una volta scaricato il file ISO dal sito della distro: come faccio a metterlo sulla chiavetta?

Fortunatamente il Mac ha tutto quello che serve a bordo, ma dobbiamo operare da command line, quindi cominciamo con l’aprire il terminal.

La prima cosa da fare è trasformare l’immagine ISO in un formato avviabile da chiavetta USB, perchè nel suo formato base non è “Bootable”.

Il comando da esegire è:

hdiutil convert -format UDRW -o Downloads/ubuntu.img  Downloads/ubuntu-16.04.2-desktop-i386.iso

Il file che otterremo ha l’estensione .dmg, è un default del Mac, ma va bene lo stesso.

Il passo successivo è infilare la chiavetta USB nello slot, e vedere come è stata montata dal sistema.

per fare ciò, eseguiamo il seguente comando:

diskutil list

il risultato sarà:

dev/disk0 (internal, physical):
#: TYPE NAME SIZE IDENTIFIER
0: GUID_partition_scheme *500.3 GB disk0
1: EFI EFI 209.7 MB disk0s1
2: Apple_CoreStorage Macintosh HD 499.4 GB disk0s2
3: Apple_Boot Recovery HD 650.0 MB disk0s3

/dev/disk1 (internal, virtual):
#: TYPE NAME SIZE IDENTIFIER
0: Macintosh HD +499.0 GB disk1
Logical Volume on disk0s2
3AE302D4-9B15-463E-911C-87EF564A95E9
Unencrypted

/dev/disk2 (external, physical):
#: TYPE NAME SIZE IDENTIFIER
0: GUID_partition_scheme *7.9 GB disk2
1: EFI 209.7 MB disk2s1

Il device che andremo ad utilizzare è quello marcato come External – Physical, nel mio caso il /dev/disk2, ma può variare a seconda delle configurazioni.

Prima di tutto andiamo a recuperare tutto lo spazio utile con:

diskutil partitionDisk /dev/disk2 1 "Free Space" "unused" "100%"

Attenzione, questa operazione cancellera tutto il conetenuto della chiavetta.

Quindi proseguiamo con linstallazione dell’immagine appena creata con il seguente comando:

sudo dd if=~/Downloads/ubuntu.img.dmg of=/dev/rdisk3 bs=1m

Ci vuole un pò di pazienza, perchè la scrittura non da evidenza della progressione, quindi attendiamo finchè il cursore non ritorna riportando la quantità di dati scritti.

Probabilmente il sistema ci restituirà anche un bell’errore, perchè il Mac non riconosce il filesystem. Se vi capita, semplicemente confermate l’espulsione, altrimenti, date il segente comando:

diskutil eject /dev/disk2

A questo punto avete la vostra chiavetta avviabile con l’installazione pronta per essere eseguita sul vostro PC.

Risolvere il proprio IP pubblico dalla shell di Linux

Quando abbiamo a disposizione un browser siamo abitati a digitare whatismyip o qualche altro sito che risolve l’indirizzo di provenienza della richiesta.

Se invece abbiamo bash aperto, il modo più rapito è

dig +short myip.opendns.com @resolver1.opendns.com

o meglio aggiungetevi un alias bashrc cosi non bisogna ricordarsi la sintassi

alias wanip='dig +short myip.opendns.com @resolver1.opendns.com'

a questo punto basterà digitare

$ wanip

per vedersi risolto il proprio indirizzo pubblico.

Il dilemma del curriculum. Memories.

L‘altro giorno, ho realizzato che da parecchi anni non aggiorno più il mio curriculum. Davvero tanti. D’altronde non mi è mai servito, e quando lo ho preparato la prima volta, il layout che andava di modaera ben diverso da quelli che vedo quotidianamente.

Devo dire che non apprezzo molto il “formato europeo”. E’ evidente che chi riceve migliaia di curriculum e deve scegliere velocemente preferisce un formato omogeneo e stringato per non può perdere tempo a leggere dei romanzi e che l’attenzione va colta con poche frasi ben strutturate.

Però se mi fermo a pensare a tutti i curriculum che ho letto, quello che mi è rimasto più impresso è uno ricevuto una decina di anni fa, dove un dipendente di HP mi ha mandato la storia della sua vita, fin troppo dettagliata, dove si poteva ben evincere le competenze al di là degli incarichi.

Non mi sembra una cosa proponibile per rivedere il mio curriculum, ma intanto ho deciso di scrivere le mie memorie professionali qui, sul mio blog per poi vedere cosa ne viene fuori.

Parlerò solo di informatica, partendo dell’inizio, e vediamo fino a dove ho voglia di arrivare e fino dove avrete voglia di leggere…

Stay Tuned…