giovedì 28 agosto 2014

Cercare in un file in Windows 8

Vi sarà sicuramente capitato di ricercare i contenuti di un file in Windows 8... e di non trovarli mai! Fate il vostro bel "swype" come vi hanno insegnato, andate sulla lente di ingrandimento, mettete la parola da cercare e... mai che vi trovi il documento che contiene quella parola!

Avrete sicuramente mandato a quel paese gli ingegneri del software della Microsoft, e avrete pensato che quelli che dicono che Windows non funziona hanno ragione!

No, in realtà la ricerca indicizzata di Windows 8 (e 8.1 ovviamente) funziona molto bene, peccato che occorra personalizzarla - e questa è una delle prime cose che andrebbe fatte dopo aver installato il sistema operativo.

Per ovvi motivi, Windows appena installato indicizza solo alcune (poche!) cartelle, perché altrimenti le operazioni di indicizzazione sarebbero molto lunghe, e il file che contiene l'indice potrebbe diventare enorme.

Tuttavia, è molto semplice personalizzare le opzioni di ricerca e ottenere un'indicizzazione dei vostri contenuti, in modo da poterli trovare immediatamente.

Per prima cosa, swype (cioè passare il mouse sulla parte destra dello schermo), selezionare "Impostazioni" ("Settings") e poi "Pannello di Controllo" ("Control Panel").

In alto a sinistra nel box di ricerca scrivete, se avete Windows in inglese "index", altrimenti in italiano "indicizzazione". Verrete portati a questa schermata:


Attraverso questa schermata, premendo "Modify" ("Modifica"), è possibile selezionare le cartelle del PC i cui contenuti verranno indicizzati e saranno quindi disponibili per una ricerca veloce.

Unico consiglio: non esagerate! Immettete solamente le cartelle dove effettivamente archiviati i vostri documenti.

Se, come me, avete due dischi, e sul primo mettete solamente il sistema operativo, è buona norma cambiare la posizione del file di indice in modo che questo risieda sul vostro disco più capiente.

Per farlo andate su "Advanced" ("Impostazioni avanzate"):


Selezionate la cartella che conterrà i file di indice, e poi premete il tasto "Rebuild" ("Ricostruisci"). In questo modo, i vecchi file indice verranno cancellati, e quelli nuovi verranno salvati nella nuova posizione.

Infine, valutate se vi interessa che le ricerche fatte con lo swype includano o meno risultati dal Web. Per personalizzare quest'ultima opzione potete agire su: "Settings" ("Impostazioni"), "Change PC Settings" ("Cambia impostazioni"), "Search and Apps" ("Ricerca e App"), e poi mettete a "Off" (oppure "On") l'impostazione "Use Bing to search online" ("Usa Bing per cercare online").


 

mercoledì 14 maggio 2014

Clonare un repository da GitHub


Ecco una breve guida per effettuare il clone di un repository di codice sorgente da GitHub, modificarlo e poi sottomettere le modifiche. Il tutto direttamente da linea di comando. Com'è ovvio, occorre aver installato in locale git.

Per prima cosa occorre creare una directory e posizionarvisi sopra.

Quindi occorre effettuare il 'cloning':

git clone https://github.com/guildenstern70/cpp11learn.git
git status

Questa operazione crea un'esatta replica di tutti i file sul repository, non solo i sorgenti ma anche tutti i file ancillari, ad esempio la 'History'.

'git status' mi dà un feedback delle operazioni effettuate.

A questo punto posso cominciare a modificare i miei file. Quando ho finito il lavoro, occorre mettere in 'stage' le modifiche, che saranno così pronte per essere committate: lo si fa con il comando 'add':

git add <files...>
git status

Con il comando 'add' aggiungo i file che non erano presenti, oppure indico quali file esistenti sono stati modificati - esatto, è lo stesso comando per entrambe le operazioni.

Quando sono pronto per rendere operative le modifiche, effettuo il commit in locale:

git commit
git status

Ora occorre dare un nome al branch remoto, ad esempio: github. In questo modo posso indicare su quale repository lavorare, quello in locale, che normalmente è indicato come 'master' e quello in remoto, che qui chiamo 'github', ma che normalmente si indica come 'origin':

git remote add github https://github.com/[username]/[projectname].git
git remote -v

L'indirizzo https del repository si trova sul sito github del repository stesso.

Infine, per sincronizzare il repository locale con quello remoto, cioè in un certo senso per fare l'upload delle modifiche si dà il comando 'push':

git push -u github master

Viene chiesta la nostra username e password su GitHub, e dopo averle inserite, il gioco è fatto.

martedì 29 aprile 2014

Di che tipo è una Funzione Lambda?


Le funzioni lambda sono balzate agli onori delle cronache soprattutto perché l'ultima versione di Java le supporta direttamente, mentre sono molti altri i linguaggi che le integrano nella loro sintassi, ad esempio Ruby, Python e Scala.

Nel campo della programmazione una funzione lambda è una funzione anonima che può essere chiamata e passata direttamente, senza cioè essere nominata con un identificatore, come lo è una funzione normale, che ha un suo nome che rende possibile chiamarla nominalmente.

Ad esempio, in Scala, una funzione lambda ha questa sintassi:



val circleArea = (radius: Double) => 
                     { radius * radius * Math.PI }



in questo caso il nome "circleArea" non è il nome della funzione, ma è il nome dell'oggetto a cui si associa la funzione lambda. La differenza è sottile ma sostanziale: una funzione lambda può essere associata a molte diverse variabili con diverso nome, mentre una funzione normale ha uno e un solo nome.

Perché mai un programmatore dovrebbe usare funzioni senza nome? Il motivo principale risiede nell'immediatezza: sono parti di codice di facile scrittura, tipicamente formule matematiche, il cui uso è in porzioni di codice "vicine" a quello in cui vengono definite. Oppure ancora si tratta di shortcut, cioè di un modo veloce per passare mini-funzioni ad una super-funzione che le richiama all'interno di se stessa - il caso, nell'esempio sotto in Java8, della gestione degli eventi nei controlli:

// Lambda in Java 8
button.addActionListener( (e) -> {
        System.out.println("The button was clicked. From lambda expressions !");
});


C'è però una questione: quando passo una funzione anomima ad un'altra funzione, qual è il "tipo" con cui la identifico? In altre parole: se scrivo un metodo che prende come input una funzione lambda, come sarà la "firma" di quel metodo? Qual è insomma il tipo di una funzione lambda?

La questione è cruciale nei linguaggi fortemente tipizzati, dove è necessario identificare sempre il tipo di un oggetto per poterlo passare.

In Scala, che è un linguaggio fortemente tipizzato, la cosa viene risolta in modo elegante, cioè dando al tipo "funzione" una sintassi propria. Di seguito l'esempio di una High Order Function, cioè di una funzione che prende in input un'altra funzione:

function def highOrderFunction(func: Double => Double, v: Double ):String = {
        
        val result = func(v)
        result.toString();
        
}

Il primo parametro dice che deve essere passata una "funzione" che ritorna un numero decimale Double e prende in input un altro Double. Quindi, in Scala, la domanda non ha molto senso: il tipo di una funzione non è necessario specificarlo, perché il linguaggio ha una sintassi propria per definire un placeholder di funzione, che è il seguente:

(Input Parameters) => (Expression)


Però in altri linguaggi la questione si pone eccome. Ad esempio in C#. In questo linguaggio una funzione lambda viene definita come segue:

(double radius) => { radius * radius * Math.PI}


Ma se voglio "tradurre" la funzione Scala che abbiamo visto sopra (highOrderFunction) in C#, ho bisogno di sapere di che "tipo" è la funzione lambda.

Bene, in C# esistono due tipi (in realtà sono delegates) che rappresentano procedure e funzioni, sia che queste siano normali, e quindi nominali, sia che siano anonime, o lambda. Consideriamo di avere una procedura "VoidProcedure", che prende in input un intero, e una funzione "SimpleFunction" che prende in input un intero e ritorna un decimale:

static void VoidProcedure(int i)
{
    Console.WriteLine(i);
}

static double SimpleFunction(int i)
{
    return (double)i/2;
}


I tipi che le possono rappresentare sono:
Per cui si può scrivere un programma per invocarle indirettamente attraverso questi due nuovi tipi (delegati):

static void Main(string[] args)
{
    Action myAction = new Action(VoidProcedure);
    myAction.Invoke(123);           // Prints out "123"

    Func myFunc = new Func(SimpleFunction);
    Console.WriteLine(myFunc(5));   // Prints out "2.5"

    Console.ReadKey();
}


Ora, utilizzando al posto delle funzioni, le funzioni lambda, lo stesso programma diventa:

static void Main(string[] args)
{
    Action myAction = new Action(

        // Lambda procedure
        (i) => Console.WriteLine(i)

        );
    myAction.Invoke(123);           // Prints out "123"

    Func myFunc = new Func(
               
        // Lambda function
        (i) => (double)i/2
                
        );
    Console.WriteLine(myFunc(5));   // Prints out "2.5"

    Console.ReadKey();
}


In Java, i tipi lambda sono addirittura sei:

  • Predicate: una funzione che torna un booleano (normalmente per fare query)
  • Consumer: simile alla Action di cui sopra
  • Function: simile alla Func di cui sopra
  • Supplier: una funzione factory, che genera oggetti di tipo
  • UnaryOperator: funzione unaria che trasforma un oggetto
  • BinaryOperator: funzione binaria che trasforma due parametri in un valore di ritorno.

Cosicché il nostro esempio, in Java8, può scriversi come:

package lambdajava;

import java.util.function.Function;

public class LambdaJava {

    public static void main(String[] args) {

        byte[] ch = null;
        Function<Integer, Double> myFunc = i -> (double)i/2;
        System.out.println(myFunc.apply(5));
        
    }
      
}