sabato 20 maggio 2017

PostgreSQL abbandonerà il supporto al download FTP

Dal giorno 15 Agosto 2017 non sarà piu' possibile scaricare PostgreSQL tramite FTP!
Come spiegato nella mailing list pgsql-announce, visto il basso traffico
del protocollo FTP, nonché la vetustà del protocollo e dei relativi programmi,
il team che mantiene l'infrastruttura ha deciso di spegnere l'accesso FTP.
Questo non dovrebbe risultare in un particolare disservizio per gli utenti finali, quanto
forse solo per alcune applicazioni e script automatici.

Noisli: un servizio di suoni per aumentare la concentrazione al lavoro

E' molto importante rimanere concentrati durante lo svolgimento del proprio lavoro, penso sia un concetto noto a tutti.
Io ho la fortuna di svolgere un lavoro ad una scrivania, senza pubblico, quindi per estraniarmi dall'ambiente circostante utilizzo
la musica e, raramente, la radio. Il mio cervello aggancia la melodia e non si fa distrarre da altre cose e rumori, lasciandomi
quindi proseguire nel mio lavoro. Tuttavia non indico questa come possibile strategia di studio, che invece richiede maggior silenzio
e in generale sonorità che il cervello non è in grado di "comprendere" razionalmente (es. parole).

Ecco, ho scoperto che esiste un servizio Noisli che consente di comporre un suono ambientale che possa aumentare la produttività
individuale. Ad esempio mescolando il suono della pioggia battente con quello di un caminetto. E c'è anche chi ha pensato
di integrare il servizio dentro a Gnome.

venerdì 19 maggio 2017

Arabic to Roman number converter in Perl 5

Puzzled by a post on the Planet KDE about GCompris and roman numbers, and needing an easy way to explain to my six-years old son about roman numbers, I thought it would be an easy task to make a simple program in Perl to convert an arabic number into its roman notation.
Not so easy, pal!
Well, it's not a problem about Perl, of course, rather I found it required a quite brainpower for me to write down rules to convert numbers, and I did not search for the web for a copy-and-paste alghoritm. Please note: if you need a rock-solid way to handle conversions, have a look at CPAN that is full of modules for this particular aim.
Here I'm going to discuss the solution I found and how I implemented it. It is not supposed to be the best one, or the faster one, it's just my solution from scratch.

The program

I split the problem of converting an arabic number into a roman one into three steps, with one dedicated subroutine for each step, so that the main loop reduces to something like the following:
say "$_ = " . $roman_string->( $reassemble->( $disassemble->( $_ ) ) )
              for ( 1..30 );
that produces the following output:
1 = I
2 = II
3 = III
4 = IV
5 = V
6 = VI
7 = VII
8 = VIII
9 = IX
10 = X
11 = XI
12 = XII
13 = XIII
14 = XIV
15 = XV
16 = XVI
17 = XVII
18 = XVIII
19 = XIX
20 = XX
21 = XXI
22 = XXII
23 = XXIII
24 = XXIV
25 = XXV
26 = XXVI
27 = XXVII
28 = XXVIII
29 = XXIX
30 = XXX
The steps must be read from the inner subroutine to the outer, of course, and therefore we have:
  • disassemble that translates an arabic number into roman basis, that is computes how many units, tens, hundreds and thousands are required. In this phase there is no application of roman rules, so numbers are decomposed into a linear string of letters. As an example the number 4 is translated into IIII, which is of course a non-existent roman number.
  • reassemble applies roman rules, in particular promoting numbers so that groups are translated, when needed, into higher order letters. For instance IIII is promoted into two groups: I and V.
  • roman_string compose the promoted groups into the final string. The main difficulty of this part is to understand when a letter has to be placed on the right (addition) or on the left (subtraction) of another letter. For instance, having the groups I and V the function must understand if the output have to be VI (6) or IV (4).
To speed up the writing of the code, I placed main roman letters and their correspondance with arabic numbers into a global hash:
my $roman = {
    1    => 'I',
    5    => 'V',
    10   => 'X',
    50   => 'L',
    100  => 'C',
    500  => 'D',
    1000 => 'M',
};
Each method references $roman when needing to convert from an arabic number to its roman letter. In order to allow method to cooperate together, they accept and return an hash keyed by a roman letter and the number of occurences such letter must appear in the final string. The following is an example of the hash for a few numbers:
# 4 (IV)
{ 'I' => 1, 'V' => 1 }
# 19 (XIX)
{ 'I' => 1, 'X' => 2 }
# 5 (V)
{ 'V' => 1 }
# 17 (XVII)
{ 'X' => 1, 'V' => 1, 'I' => 2 }

The disassemble function

The following is the code for the disassemble function, that accepts as only input the arabic number.
# Accepts the arabic number and provides an hash
# keyed by each letter, with the value of how many times
# such letter should be summed in order to obtain the
# starting number.
my $disassemble = sub{
    my ( $number ) = @_;
    my $items = {};

    # sort the keys, that are arabic thresolds, from
    # the greater to the smaller one
    for my $current_value ( sort { $b <=> $a } keys $roman->%* ){

        my $how_many = int( $number / $current_value );
        next unless ( $how_many );

        my $letter = $roman->%{ $current_value };
        $items->{ $letter } = $how_many;

        $number -= $current_value * $how_many;
    }

    return $items;
};
The first thing the method does it to create the hash $items that is what it will return to allow other methods to consume. Each key of the $roman hash is passed ordered by the bigger to the smaller (please note that sort has $b first!). In this way we can surely scompose the number from the thousands, hundreds, tens, and units in this exact order. The $how_many variable contains the integer part of each letter. For example the number 29 is processed as follows:
  1. 29 / 10 that drives $how_many to be 2 and the remaining to be a 9;
  2. 9 / 5 that makes $how_many to be 1 and the remaining to be a 4;
  3. 4 / 1 that makes $how_many to be 4 and there's nothing more to do.
At each step the roman letter and the $how_many value is inserted into the $items has, that in the above ecample becomes:
# 29 (XIX)
{ 'X' => 2,
  'V' => 1,
  'I' => 4
}

The reassemble method

The reassemble method takes as input the hash produced by disassemble and checks if any letter requires a promotion. Here it is the code:
# Accepts an hash with keys the letters and values the number
# of times each letter should appear.
# Traverse the hash from the smaller to the greater
# in order to "promote" smaller aggregates. For instance
# 'IIII' (4) is aggregated and therefore the hash is modified
# so there's only an 'I' and another 'V', in such case
# the quantity of the promoted letter is negative to indicate
# it has been promoted.
my $reassemble = sub{
    my ( $items ) = @_;
    my @sorted_thresolds = sort { $a <=> $b } keys $roman->%*;

    for ( my $i = 0; $i < @sorted_thresolds; $i++ ){
        my $current_value = $sorted_thresolds[ $i ];
        my $key      = $roman->%{ $current_value };
        my $how_many = $items->%{ $key };

        next unless ( $how_many );

        my $greater_value = ( $i + 1 > @sorted_thresolds ? 1000 : $sorted_thresolds[ $i + 1 ] );
        my $greater_key   = $roman->%{ $greater_value };


        my $need_to_promote = $how_many == 4
            || ( $greater_value / $current_value == $how_many );

        if ( $need_to_promote ){
            $items->{ $greater_key }++;
            $how_many = $greater_value - $how_many * $current_value;
            $items->{ $key } = $how_many * -1;

        }

    }

    return $items;
};
The promotion must be done from the smaller letter to the greater one, so this time the letters are walked in ascending order (i.e., sort has $a first!). Since to promote a letter I need to access the following one, I need a C-style for loop.
A letter requires to be promoted if its quantity is 4 or /it is 2 and the right bigger value is exactly the double of the current one~, that is while ( $greater_value / $current_value == $how_many ). This makes, for instance IIII to be promoted (the quantity is 4), and VV to be promoted into X (because the quantity is 2 and the X is exactly the double of V). The promotion manipulates the hash increasing by one the right bigger letter and leaving a single current letter. In order to flag the promoted letter, I decided to use a negative quantity (where the absolute value is the exact one).
So for instance, the 29 hash of the previous paragraph is passed as follows:
# input to the method
{ 'X' => 2,
  'V' => 1,
  'I' => 4
}


# first for step (I)
{ 'X' => 2,
  'V' => 2,
  'I' => -1  # promoted, keep 1 and increase 'V'
}

# second step (V)
{ 'X' => 3,
  'V' => 0,  # promoted, increase X by one
  'I' => -1
}
At the end of method we know the final string will be made by three X and one I, the point now is to understand how to render them in the correct order. This is the aim of the roman_string method.

The roman_string method

The method accepts the normalized hash (i.e., groups are already formed) and compose the final string placing letter on the left or the right of each other depending on their quantity. The following is the code of the method:
# Do the hard work of composing
# each group of letters in order to compose the roman string.
my $roman_string = sub {
    my ( $items ) = @_;
    my @chars;

    for my $current_value ( sort { $b <=> $a } keys $roman->%* ){
        my $letter   = $roman->%{ $current_value };
        my $how_many = $items->%{ $letter };

        next unless ( $how_many );


        if ( $how_many > 0 ){
            push @chars, $letter for ( 1 .. $how_many );
        }
        else{
            # this is promoted, so it has to be inserted as last-to-last
            # in the previous chain
            # example: @chars( X, X ) and here I've 'I' to make XIX (19)
            push @chars, ( $letter, pop @chars );
        }

    }

    return join "", @chars;
};
In order to be able to manipulate easily the final string, moving letters from left to right and vice-versa, I decided to place each single letter into the @chars array, that is then join -ed into a single string.
Let's suppose we need just to add letters: in this case we need to write letters from the greater to the smaller from left to right, and this is the order I traverse the letters of $roman (again, note that sort has $b first!). If the quantity of the letter is positive the letter has not been promoted and therefore it will not be placed to the left of another letter, so just insert into @chars the $letter for the $how_many quantity. On the other hand, if $how_many is negative, the letter has been promoted and therefore have to be printed on the left of the last printed letter. This is as easy as doing:
push @chars, ( $letter, pop @chars );
that inserts into @chars the $letter and the previous last character that has been removed via pop.
With regards to the previous example of 29 we have that:
# method input
{ 'X' => 3,
  'I' => -1
}

# first step: prints X
# with quantity 3 (not promoted)
@chars = ( 'X', 'X', 'X' );

# second step: prints I
# that has been promoted
# and must be inserted ascending
# as last-to-last
@chars = ( 'X', 'X' ,
           ( 'I', # $letter
             'X'  # pop @chars
         ) );

Conclusions

Well, it has been much code that I expected to write. Using an object notation, instead of plain hashes, could surely make the program more robust. I'm pretty sure there's a way to shrink the code down and to avoid that ugly C-style for loop, as well as the promotion part could be simplified keeping in mind that it often reduces to -1 for the current letter and +1 for the greater one. Anyway, it does what I need and seems correct!

PostgreSQL 10 beta 1!

Ci siamo!
PostgreSQL 10 fa finalmente capolino nel mondo con il rilascio, ieri, della prima beta release.
Il download comprende pacchetti binari per le maggiori distribuzioni, oltre ovviamente alla possibilità
di compilare i sorgenti, anch'essi scaricabili come archivi.

sabato 13 maggio 2017

KDE e cgit

Il progetto KDE utilizza cgit come frontend web per i repository git.
Il progetto cgit fornisce un accesso web super fast ai repository git, con
alcune funzione di utilità specifiche come il riconoscimento dei repository on-the-fly.
Sicuramente rappresenta una valida alternativa alle molteplici interfacce web
già presenti sul mercato.

venerdì 12 maggio 2017

Postfix dereference operator

Starting from Perl 5.20 it is allowed to use a postfix dereference notation, first as an explicit feature, and since Perl 5.24 it is enabled by default.
The postfix dereference notation allows you to use the arrow operator -> on a reference (as often used when combined with references) specifying the type of the deferencing you want to. Types are indicated by their well know sigils, so for instance a $ means a scalar, a @ an array, & is for a subroutine, % for an hash and * for a typeglob. The sigil on the right of the arrow operator is enhanced by a star, so it really becomes type and *, as in $*. In the special case of arrays and hashes the star can be dropped in favor of a slicing operator, e.g., the square brackets.
The following is a sample program that prints out the values of an array using full access (->@*) and slicing (->@[]):

#!env perl
use v5.24;

my @array = ( 'a' .. 'z' );
my $ref   = \@array;
say "Here comes the array @{ $ref }";
say "And post dereferences is $ref->@*";

say "Here comes a slice @{ $ref }[ 0 .. 5 ]";
say "And using it as post dereference is $ref->@[ 0 .. 5 ]";
 
 
As you can see, $ref->@* is the equivalent of @{ $ref }, while $ref->@[] is the same as @{ $ref }[]. The same applies to hash references.
Code and subroutine references are a little more controversial, at least to my understanding of references. First of all there is only the star operator, so ->&*, and the behavior is such that $ref->&* is the same as &{ $ref }. This makes me think there is no short way of passing method arguments thru a postfix deference, as the following code demonstrates:

#!env perl
use v5.24;

my $sub_ref = sub { say "Hello sir @_ !" };
$sub_ref->( 'Luca' );         # Hello sir Luca !
&{ $sub_ref }( 'Luca' );      # Hello sir Luca !
$sub_ref->&* ;                # Hello sir  !
{ $sub_ref->&* }( 'Luca' );   # Hello sir  !
&$sub_ref( 'Luca' );          # Hello sir Luca !

If you try to pass arguments in any way to the ->&* dereferencing, you got either a compile time error or a code that does not what you expect:

{ $sub_ref->&>* }( 'Luca ');   # Hello sir  !
$sub_ref->&( 'Luca' );        # syntax error at tmp/ref.pl line 19, near "->&"
$sub_ref->&*( 'Luca' );       # syntax error at tmp/ref.pl line 20, near "&*( "
{ $sub_ref->& }( 'Luca ');    # syntax error at tmp/ref.pl line 21, near "->&"

The only catch-all way of passing arguments, as suggested on irc.perl.org, is to use the @_, so I suggest to localize it:


  local @_ = qw( Luca ); 
  $sub_ref->&*; # Hello sir Luca ! 
}

I must admit this is a little too much for my poor brain in order to efficiently use the references, so if anyone has something to comment is truly welcome!
Now, back to the main topic, it seems to me that the postfix dereference notation is a way of managing reference more like objects, at least it reminds me a kind of as_xx methods (yes, Ruby-ers, I'm looking at you). If we read the arrow operator like as and the type on sigil on the right as the type name, we have that, for instance:
  • $ref->$* is $ref as scalar;
  • $ref->@* is $ref as array or $ref>@[] becomes $ref as array slice
and so on. While I'm pretty sure this is not the real meaning of this notation, it is sure most readable than the "usual" one, where we have the type on the left and the reference on the right (or better in the middle), as in @$ref or @{ $ref }.

mercoledì 10 maggio 2017

Diamonds in Perl

A diamond ascii is a geometric structure represented as, ehm, a diamond. For example, in the case of letters it becomes something like:


      a
    b  b
   c    c
  d      d
 e        e
f          f
 e        e
  d      d
   c    c
    b  b
     a

How hard can it be to build a Perl program to represent a diamond like the above one?
Well, not so much hard, but we have to observe some geometric properties:

  • the diamond is simmetric (in the sense it becomes and ends with the same letters), but the
    central row is reproduced only once (that is, the f appears only on one line, not two!);
  • each letter or couple of letters is vertically centered around the number of letters in the whole diamond, that is
    the letter a (vertical centre) is shifted to right of 6 chars (the total number of letters is a..f = 6);
  • each couple of letters has a left and right position, and both are equally distant from the vertical
    centre of the diamond.

Ok, so here it comes my shorter solution:



#!env perl

use v5.20;

my @letters = qw( a b c d e f );

my %index;
@index{ @letters } = ( 0 .. $#letters );


    say {*STDOUT}
  " " x ( $#letters - $index{ $_ } )
 , $_
 , " " x ( $index{ $_ } * 2 )
 ,( $index{ $_ } > 0 ? $_ : '' )
     for  ( ( @letters, reverse @letters[ 0 .. $#letters - 1 ] ) );

Allow me to explain it in all its pieces.


First of all, @letters contains the letters to be printed in the right order, and this of course could come from user's input, a sequence, an array slice, or whatever, it does not mind here. Since I have to place letters depending on where they are in the array of @letters, I need to have an handy way to get the index within the array for each letter, so I build up an hash where the keys are the letters themselves and the values are the positions of such letters. In other words, $index{a} = 0, $index{f] = 5 and so on.


Finally, I print a line every time I need with say. Let's dissect the say statement:

  • " " x ( $#letters - $index{ $_ } ) shifts to right a number of spaces required to reach the vertical centre or the right distance from it, in other words it is the left position. For example, for the letter a it comes
    down to 5 - 0 = 5, while for b it comes to 5 - 1 = 4 and so on.
  • then I print $_ that is the current char;
  • then I move again to the right of " " x ( $index{ $_ } * 2 ), that is in the case of a nothing, in the case of b by 2, and so on;
  • then if required I print again the char. Here "required" means the char is not the first one (i.e., not the one at index 0), since that is the only one character printed exactly one time per line.

The say is repeated over the whole @letters array, so this produces the first part of the diamond:


      a
    b  b
   c    c
  d      d
 e        e
f          f

then I need to get the bottom, so I need to iterate over the reverse @letters with the exception of the last element, that is I need to iterate over a reversed slice of @letters with the missing f: reverse @letters[ 0 .. $#letters - 1 ] ). This provides me the whole bottom of the diamond.