River crossing problem

In the book From Bacteria to Bach and Back by Daniel Dennet there is this note:

Four people come to a river in the night. There is a narrow bridge, and it can only hold two people at a time. They have one torch and, because it’s night, the torch has to be used when crossing the bridge. Person A can cross the bridge in one minute, B in two minutes, C in five minutes, and D in eight minutes. When two people cross the bridge together, they must move at the slower person’s pace. The question is, can they all get across the bridge in fifteen minutes or less?

This is a well know crossing problem like wolf cabbage and goat problem. Many of this problem are solved by simple Prolog program. But now i want solve this problem with a functional language: F#. A simple solution is (based on this):

open System

//cambia per trovare soluzioni in tempi diversi
let MAX_TIME = 15

type Person = 
  | Person of string * int

type Direction =
  | L
  | R

type Move =
  | Move of Direction * Person list

//estende il modulo List
module List =
  let rec combinations items =
    [
      match items with
      | [] -> ()
      | x::xs ->
        for y in xs do yield x, y
        yield! combinations xs
    ]

let rec Solve cost moves atStart atEnd dir =
  seq {
    if cost > MAX_TIME then ()
    elif Set.isEmpty atStart then yield cost, List.rev moves
    else
      match dir with
      | L ->
        for Person(_, time) as person in atEnd do
          let move = Move(dir, [person])
          yield! Solve (cost + time) (move :: moves) (Set.add person atStart) (Set.remove person atEnd) R
      | R ->
        let combinations = List.combinations (Set.toList atStart)
        for (Person(_, time1) as person1), (Person(_, time2) as person2) in combinations do  
          let move = Move(dir, [person1; person2])
          let persons = set [person1; person2]
          yield! Solve (cost + (max time1 time2)) (move :: moves) (atStart - persons) (atEnd + persons) L
  }      

let Persons =
  set [
    Person("A", 1)
    Person("B", 2)
    Person("C", 5)
    Person("D", 8)
    //Person("E", 1)
  ]

Solve 0 [] Persons Set.empty R
|> Seq.iter (printfn "%A")

 

Executing the program yield the following output (can be executed as is in LINQPad):

(15,
 [Move (R,[Person (“A”,1); Person (“B”,2)]); Move (L,[Person (“A”,1)]);
  Move (R,[Person (“C”,5); Person (“D”,8)]); Move (L,[Person (“B”,2)]);
  Move (R,[Person (“A”,1); Person (“B”,2)])])
(15,
 [Move (R,[Person (“A”,1); Person (“B”,2)]); Move (L,[Person (“B”,2)]);
  Move (R,[Person (“C”,5); Person (“D”,8)]); Move (L,[Person (“A”,1)]);
  Move (R,[Person (“A”,1); Person (“B”,2)])])

So the puzzle have two equivalent solution.

Playing with set of Persons and MAX_TIME constant, is possible to explore solution for different problem.

Deep learning

Keras è una libreria per il deep learning che può utilizzare TensorFlow, CNTK o Theano come motore di calcolo. CNTK è la libreria Cognitive Toolkit di Microsoft. Tutti i framework citati lavorano nativamente con Phyton.

Connection Pooling and the “Timeout expired” exception

Consider this pseudocode:

/*
	TData tabele of data to elaborate
*/
ConcurrentQueue<Exception> exceptions = new ConcurrentQueue<Exception>();
Parallel.ForEach(TData.AsEnumerable (),row =>
            {
                try
                {                    
                    using (WorItem p = new WorkItem(row,connectionstring))
                    {                        
                        p.DoWork();                        
                    }
                }
                catch (Exception ex)
                {                    
                    exceptions.Enqueue(ex);
                }
            });

Inside class WorkItem.DoWork, there are some database read with custom tableadapter and one finally write of results to db. The code inside DoWork code unexpectedly fail with error “Timeout expired” or “Failed to activate rows constraints…”. The failure is random. TData table contains about 50k rows. The code is executed on machin with 48 processors, connection pool contains between 20-30 concurrent pooled connection. The failure do not depends on the row, it’s totally random. If for some row i get some strange error, i the program run for that single row, no error is generated. So what to do to correct this error?

Solution 1:  disable connection pool. The problem is solved, but performance are very poor. Run time goes from 2 minutes and 30 seconds, to 16 minutes. Not good.

Solution 2: connection pool for every WorkItem object. In Ado.Net connection pool depends on connection string, so if you modify every connection for every object, connection pool is for object scope. But how modify the connection string on object basis. In connectionstring options there is App option. This option have no pratical effect, the only purpose of this option is that if you enlist the connection on the db server with sp_who, this name is shown as property of the connection. So if you modify the connection with some connectionstring=connectionstring+”App=”+hash(row), the connection pool occurs on per object basis. The drawback of this solution, is that in the destructor of the WorkItem objec (either with Finalize or Dispose) the connection pool must be cleared, with the simple call: SqlConnection.ClearPool(conn);. With this solution the excution time is more or less the same with unique connection pool. Connection pool size grows to 60-70 concurrent pooled connection.

Udate 3-5-2017

Solution 2 is not sufficient, in some heavvy load hour, the connection problem still is there. Be best solution is to open a single connection for every object, open the connection at the first use, en close the connection at Dispose of the WorkItem instance.

Scriver numeri in lettere ROMANE in C#

Dop il ICustomFromatter per scrivere numeri in lettere, ecco un’altro FormatProvider per scrivere un numero intero da cifre arabe in cifre romane:

public class RomanFormatProvider : IFormatProvider, ICustomFormatter
    {

        IFormatProvider _parent;

        public RomanFormatProvider() : this(CultureInfo.CurrentCulture) { }
        public RomanFormatProvider(IFormatProvider parent)
        {
            _parent = parent;
        }

        public object GetFormat(Type formatType)
        {
            if (formatType == typeof(ICustomFormatter)) return this;
            return null;
        }

        public string Format(string format, object arg, IFormatProvider prov)
        {

            if (arg == null || format != "RO")
                return string.Format(_parent, "{0:" + format + "}", arg);

            return ToRoman(arg.ToString());
        }

        private string ToRoman(string n)
        {
            StringBuilder r = new StringBuilder();

            int i = 0;
            foreach (var c in n)
            {
                r.Append(calcDigit(int.Parse(c.ToString()), n.Length  - i - 1));
                i++;
            }
            return r.ToString();
        }

        class Level
        {
            public Level(string i, string v, string x)
            {
                this.i = i;
                this.v = v;
                this.x = x;
            }
            public string i { get; set; }
            public string v { get; set; }
            public string x { get; set; }

        }

        static Level[] levels = new RomanFormatProvider.Level[] {
            new Level("I", "V", "X"),
            new Level("X", "L", "C"),
            new Level("C", "D", "M")
        };

        string calcDigit(int d, int l)
        {
            string str;
            if (l > 2)
            {
                str = "";
                for (var k = 1; k <= d * Math.Pow (10, l - 3); k++)
                    str += "M";
                return str;
            }
            else
                switch (d)
                {
                    case 1:
                        return levels[l].i;
                         
                    case 2:
                        return levels[l].i + levels[l].i;
                         
                    case 3:
                        return levels[l].i + levels[l].i + levels[l].i;
                       
                    case 4:
                        return levels[l].i + levels[l].v;
                       
                    case 5:
                        return levels[l].v;
                       
                    case 6:
                        return levels[l].v + levels[l].i;
                       
                    case 7:
                        return levels[l].v + levels[l].i + levels[l].i;
                       
                    case 8:
                        return levels[l].v + levels[l].i + levels[l].i + levels[l].i;
                       
                    case 9:
                        return levels[l].i + levels[l].x;
                        
                    default:
                        return "";
                        
                }
        }
    }

Con questo CustomFormatter è possibile scrivere semplicemente:

RomanFormatProvider fr = new RomanFormatProvider();
s = string.Format(fr, "Il numero {0} in lettere è {0:RO}", 1971);
Console.WriteLine(s);

Il cui output è:

Il numero 1971 in lettere è MCMLXXI

 

Capire meglio le scelte “razionali”

Pensieri lenti e veloci

Daniel Kahneman

Ho iniziato a conoscere il lavoro di Kahneman dalle opere di Nassim Taleb. Ovviamente andare alle fonti e sempre meglio. Un libro sicuramente illuminante, anche se un po’ ostico, forse è la traduzione, magari in originale è meglio. Ma sicuramente non è esageratamente tecnico, e sicuramente divulgativo.

Scrivere numeri in lettere in C#

Il framework .Net offre diversi strumenti per scrivere o leggere in vari tipi dati da/verso stringhe. Una conversione molto particolare è quella di scrivere un numero invece che in cifre a parole, ad esempio 1234 in milleduecentotrentaquattro. Un modo per eseguire questa conversione in maniera integrata con il resto del framework è quella di implementare le interfacce IFormatProvider e ICustomFormatter. Partendo dall’idea di base fornita da Joseph Albahari nel suo C# 6 in a nutshell ho realizzato una classe che esegue la conversione per la lingua italiana:

 

public class WordyFormatProviderITA : IFormatProvider, ICustomFormatter
    {

        IFormatProvider _parent;    

        public WordyFormatProviderITA() : this(CultureInfo.CurrentCulture) { }
        public WordyFormatProviderITA(IFormatProvider parent)
        {
            _parent = parent;
        }

        public object GetFormat(Type formatType)
        {
            if (formatType == typeof(ICustomFormatter)) return this;
            return null;
        }

        public string Format(string format, object arg, IFormatProvider prov)
        {
            // If it's not our format string, defer to the parent provider:
            if (arg == null || format==null || !format.StartsWith("W"))
                return string.Format(_parent, "{0:" + format + "}", arg);

            int c = format.IndexOf(".") == -1 ? 2 : int.Parse(format.Replace("W.",""));
            if (arg is double || arg is float || arg is decimal )
            {
                decimal num = Convert.ToDecimal(arg);
                long parteIntera = (long)Decimal.Truncate(num);
                int parteDecimale = (int)(Math.Round(num - parteIntera, c) * (decimal)Math.Pow(10,c));
                return convertNumberToReadableString(parteIntera) + "/" + parteDecimale.ToString();
            }            
            long l = 0;
            if (long.TryParse(arg.ToString(), out l))
            {
                return convertNumberToReadableString(l);
            }
            return "Invalid argument";
        }

        static readonly string[] unita = { "zero", "uno", "due", "tre", "quattro", "cinque", "sei", "sette", "otto", "nove", "dieci", "undici", "dodici", "tredici", "quattordici", "quindici", "sedici", "diciassette", "diciotto", "diciannove" };
        static readonly string[] decine = { "", "dieci", "venti", "trenta", "quaranta", "cinquanta", "sessanta", "settanta", "ottonta", "novanta" };

        public string convertNumberToReadableString(long num)
        {
            StringBuilder result = new StringBuilder();
            long mod = 0;
            long i = 0;
            
            if (num > 0 && num < 20)
            {
                result.Append( unita[num]);
            }
            else
            {
                if (num < 100)
                {
                    mod = num % 10;
                    i = num / 10;
                    switch (mod)
                    {
                        case 0:
                            result.Append(decine[i]);
                            break;
                        case 1:
                            result.Append(decine[i].Substring(0, decine[i].Length - 1));
                            result.Append(unita[mod]);
                            break;
                        case 8:
                            result.Append(decine[i].Substring(0, decine[i].Length - 1));
                            result.Append(unita[mod]);
                            break;
                        default:
                            result.Append(decine[i] + unita[mod]);
                            break;
                    }
                }
                else
                {
                    if (num < 1000)
                    {
                        mod = num % 100;
                        i = (num - mod) / 100;
                        switch (i)
                        {
                            case 1:
                                result.Append("cento");
                                break;
                            default:
                                result.Append(unita[i]);
                                result.Append("cento");
                                break;
                        }
                        result.Append(convertNumberToReadableString(mod));
                    }
                    else
                    {
                        if (num < 10000)
                        {
                            mod = num % 1000;
                            i = (num - mod) / 1000;
                            switch (i)
                            {
                                case 1:
                                    result.Append("mille");
                                    break;
                                default:
                                    result.Append(unita[i]);
                                    result.Append("mila");
                                    break;
                            }
                            result.Append(convertNumberToReadableString(mod));
                        }
                        else
                        {
                            if (num < 1000000)
                            {
                                mod = num % 1000;
                                i = (num - mod) / 1000;
                                switch ((num - mod) / 1000)
                                {
                                    default:
                                        if (i < 20)
                                        {
                                            result.Append(unita[i]);
                                            result.Append("mila");
                                        }
                                        else
                                        {
                                            result.Append(convertNumberToReadableString(i));
                                            result.Append("mila");
                                        }
                                        break;
                                }
                                result.Append(convertNumberToReadableString(mod));
                            }
                            else
                            {
                                if (num < 1000000000)
                                {
                                    mod = num % 1000000;
                                    i = (num - mod) / 1000000;
                                    switch (i)
                                    {
                                        case 1:
                                            result.Append("unmilione");
                                            break;

                                        default:
                                            result.Append(convertNumberToReadableString(i));
                                            result.Append("milioni");

                                            break;
                                    }
                                    result.Append(convertNumberToReadableString(mod));
                                }
                                else
                                {
                                    if (num < 1000000000000)
                                    {
                                        mod = num % 1000000000;
                                        i = (num - mod) / 1000000000;
                                        switch (i)
                                        {
                                            case 1:
                                                result.Append("unmiliardo");
                                                break;

                                            default:
                                                result.Append(convertNumberToReadableString(i));
                                                result.Append("miliardi");

                                                break;
                                        }
                                        result.Append(convertNumberToReadableString(mod));
                                    }
                                }
                            }
                        }
                    }
                }
            }
            return result.ToString() ;
        }
    }

La funzione convertNumberToReadableString è stata presa da qui. Avendo questa classe tra le proprie utility, è possibile scrivere semplicemente: 

WordyFormatProviderITA f = new WordyFormatProviderITA();
var s = string.Format(f, "Il numero {0} in lettere è {0:W.4}", 9233234.8778);
Console.Write(s);

Che fornisce l’output:

Il numero 9233234,8778 in lettere è novemilioniduecentotrentatremiladuecentotrentaquattro/8778

Il formato è attivato dalla stringa W, nel caso di tipi reali può essere seguito dal parametro .n, dove n è il numero delle cifre dopo la virgola che si vuole stampare come /XX. Insomma è il formato di solito utilizzato sugli assegni.

IIS 8 e Errore HTTP 404.17 – Not Found

Tentando di installare un sito su IIS 8 su una macchina Windows 10, ottenevo l’errore:

Errore HTTP 404.17 – Not Found
Il contenuto richiesto sembra essere uno script e non verrà fornito dal gestore di file statici.

Il sito è realizzato con Asp.Net 3.5, per cui ha bisogno del filtro Asp.Net 2.0, che evidentemente non era installato. Utilizzando il comando

c:\Windows\Microsoft.NET\Framework64\v2.050727\aspnet_regiis.exe -ir

Il problema è sparito. Ovviamente se si è su una macchina 32 bit utilizzare la versione 32 bit del comando.