domenica 29 marzo 2015

Un esempio di ordine con awk [Brevi Esercizi]

Salve!

L'esercizio di oggi consiste nel "mettere ordine" nel file di configurazione /etc/passwd. Mettere ordine nel senso di formattazione dei dati, eh!

Ed awk, in questo, cioè nel fare ordine, è leader mondiale.

Magari si può fare di meglio. Di questo ne sono sicuro.

Intanto vi dico come ho fatto io.

cat /etc/passwd

Il casino infernale....


Lo scritp: ordina.awk

#!/usr/bin/awk -f

BEGIN{
      FS=":"
      print "------------------------------------------------------------------"
      printf "%-14s %-7s %-7s %-15s %-30s\n", "User","UID", "GID", "Home Dir.", "Shell"
      print "------------------------------------------------------------------"
 }


    NR==1, NR==10 {printf "%-14s %-7d %-7d %-15s %-30s\n", $1, $3, $4, $6, $7}



END{
      print ""
      print "------------------------------------------------------------------"
      print ""
   }

Come si può evincere dallo script, NR==1, NR==10, verranno stampate solo le prime 10 righe.

Il risultato


Alla prossima!

P.S.1 Per chi volesse approfondire il comando passwd e il file di configurazione /etc/passwd, qui.

P.S.2 Indice Brevi Esercizi

venerdì 27 marzo 2015

Corso Lua - puntata 4 - Costrutti di base


Hello world!

Come tutti i linguaggi di scripting non occorre compilare il codice Lua. Basta scrivere il programma in un file di testo --- preferibilmente assegnandogli l'estensione .lua --- ed eseguirlo con il comando da terminale $ lua nomefile.

Per scrivere il codice vi consiglio di utilizzare l'editor SciTE perché è già predisposto per eseguire programmi Lua ed è programmabile in Lua. Tra l'altro l'output del programma viene visualizzato nella output tab che funge da comodo terminale. Il tasto funzione F5 esegue il programma visualizzato nella scheda attiva in quel momento e il tasto F8 attiva/diasttiva la finestra di output che è un terminale incorporato nell'editor.

Prepariamoci a scrivere il primo programma in Lua, ovviamente il fatidico 'Hello world!'.
Salviamo il seguente codice in un file chiamato "primo.lua" ed eseguiamolo direttamente in SciTE premendo il tasto funzione F5 o al terminale con il comando $ lua primo.lua:

  print("Hello world!")


In ambiente Linux o Mac OS X come per tutti gli altri linguaggi di scripting possiamo inserire come prima riga la sha-bang. Dando i permessi di esecuzione al file possiamo eseguire il programma semplicemente scrivendone il nome al terminale, e in questo caso è conveniente omettere l'estensione.
Ecco il programma:
#!/usr/bin/env lua

print("Hello world!")

Lua è in grado di passare al programma gli argomenti che l'utente digita separandoli da spazi nella linea di comando, tramite la tabella array chiamata 'arg'. arg[0] conterrà il nome dello script mentre arg[1], arg[2], eccetera conterrà i vari argomenti utente convertiti nel tipo stringa. Questa proprietà assieme alla tecnica dello sha-bang da all'utente la possibilità di scrivere programmi in Lua come se fossero comandi da terminale, almeno per gli ambienti di classe *nix.

Primo problema: il ciclo for

Va bene, ma siamo qui per scrivere codice e allora cominciamo con il voler contare i numeri pari contenuti in una tabella che funziona come un array --- ricordandoci che gli indici partono da 1 e non da 0.
Rileggete le prime tre puntate del corso come utile riferimento.

Cominciamo creando la tabella con il costruttore in linea per poi iterare con un ciclo for.
-- costruttore (l'ultima virgola è opzionale)
-- i doppi trattini rappresentano un commento
-- come // lo sono per il C
local t = {12, 45, 67, 101,   3,
            2, 89, 36,   7,  99,
           88, 33, 17,  12, 203,
           46,  1, 19,  50, 456}

local c = 0 -- contatore
for i = 1, #t do
    if t[i] % 2 == 0 then
        c = c + 1
    end
end

print(c)

Il corpo del ciclo 'for' di Lua è il blocco compreso tra le parole chiave obbligatorie 'do' ed 'end'. La variabile 'i' interna al ciclo assumerà i valori da 1 al numero di elementi della tabella ottenuti con l'operatore #.

Per ciascuna iterazione con il costrutto condizionale 'if' incrementeremo un contatore solo nel caso che l'elemento della tabella è pari. L'if ha anch'esso bisogno di definire il blocco e lo fa con le parole chiavi obbligatorie 'then' e 'end'.

Ma come si comporta l'operatore di lughezza # per le tabelle array con indici non lineari? Per esempio, qual è il risultato del seguente codice:
 local t = {}
 t[1] = 1
 t[2] = 2
 t[1000] = 3

 print(#t)

Mentre con questo cosa verrà stampato?
 local t = {}
 t[1000] = 123

 print(#t)

Avrete certamente capito che l'operatore # tiene conto solamente degli elementi con indici a cominciare da 1 che proseguono senza 'buchi' di 1 in 1. Infatti, l'operatore di lunghezza # considera il valore nil come termine della tabella, ma è usato molto spesso per inserire progressivamene elementi in una tabella:
local t = {}
for i = 1,100 do
    t[#t+1] = i*i
end

print(t[100])

Secondo problema: il ciclo while

Passiamo a scrivere il codice per inserire in una tabella i fattori primi di un numero. Fatelo per esercizio e poi confrontate il codice seguente che utilizza l'operatore modulo % (resto della divisione intera):
local factors = {}
local n = 123456789

local div = 2
while n > 1 do
    if n % div == 0 then
        factors[#factors + 1] = div
        n = n / div
        while n % div == 0 do
            n = n / div
        end
    end
    div = div + 1
end

for i= 1, #factors do
    print(factors[i])
end

Così abbiamo introdotto anche il ciclo 'while' perfettamente coerente con la sintassi dei costrutti visti fino a ora: il blocco ripetuto fino a che la condizione è vera è obbligatoriamente definito da due parole chiave, quella di inizio è 'do' e quella di fine è 'end'.

Intermezzo

Siamo all'intervallo!
Non ci sarà pubblicità ma ulteriori notizie su Lua!
In Lua non è obbligatorio inserire un carattere delimitatore sintattico ma è facoltativo il ';'.
I caratteri spazio, tabulazione e ritorno a capo vengono considerati dalla grammatica come separatori, perciò si è liberi di formare il codice con identazione o anche più istruzioni sulla stessa linea.
Solitamente non si utilizzano i punti e virgola finali, ma se ci sono due assegnazioni sulla stessa linea --- stile sconsigliabile perché brutto --- li si può separare con un ';'.
Come sempre una forma stilistica chiara e semplice vi aiuterà a scrivere codice più leggibile e semplice da comprendere a distanza di tempo.

Generalmente è buona norma definire le nuove variabili più vicino possibile al punto in cui verranno utilizzate per la prima volta, un beneficio per la comprensione ma anche per la correttezza del codice perché forse eviterà di fare confusione con i nomi e magari introdurre errori.
Ok. Intervallo finito...

Terzo problema: il ciclo for con step

Altro tema: verificare se un numero è palindromo ovvero che gode della proprietà che le cifre decimali sono simmetriche, come per esempio avviene per il numero 123321. Prima provate a scrivere il codice Lua per conto vostro e poi confrontate questa soluzione:
local digit = {}
local n = 123321

local num = n
while num > 0 do
    digit[#digit + 1 ] = num % 10
    num = (num - num % 10) / 10
end

local sym_n, dec = 0, 1
for i=#digit,1,-1 do
    sym_n = sym_n + digit[i]*dec
    dec = dec * 10
end

print(sym_n == n)

La soluzione utilizza una tabella per memorizzare le cifre del numero che vengono poi utilizzate nel ciclo for a partire dall'ultima (la cifra più significativa) fino alla prima per ricalcolare il numero con le cifre invertite. Per esempio se il numero fosse 123 l'algoritmo restituirebbe 321. Se il numero iniziale è palindromo allora il corrispondente numero a cifre invertite è uguale al numero di partenza.

Nel ciclo for il terzo parametro opzionale -1 imposta il passo per la variabile i che quindi passa dal numero di cifre del numero da controllare (6 nel nostro caso) ad 1.

In effetti non è necessaria la tabella:
local n = 123321

local num, sym_n, dec = n, 0, 1
while num > 0 do
    sym_n = sym_n + (num % 10)*dec
    dec = 10 * dec
    num = (num - num % 10) / 10
end

print(sym_n == n)

Quarto problema: if a rami multipli

Il prossimo problema è il seguente: determinare il numero di cifre di un intero. Confrontate ancora una volta il codice proposto solo dopo aver cercato una vostra soluzione.
local n = 786478654
local digits
if n < 10 then
    digits = 1 -- attenzione non 'local digits = 1'
elseif n < 100 then
    digits = 2
elseif n < 1000 then
    digits = 3
elseif n < 10000 then
    digits = 4
elseif n < 100000 then
    digits = 5
elseif n < 1000000 then
    digits = 6
elseif n < 10000000 then
    digits = 7
elseif n < 100000000 then
    digits = 8
elseif n < 1000000000 then
    digits = 9
elseif n < 10000000000 then
    digits = 10
else -- fermiamoci qui...
    digits = 11
end

print(digits)

Questo esempio mostra in azione l'if a più rami che in Lua svolge la funzione del costrutto 'switch' presente in altri linguaggi, che introduce una nuova parola chiave: 'elseif'.
L'esempio è interessante anche per come viene introdotta la variabile 'digits', cioè senza inizializzarla per poi assegnarla nel ramo opportuno dell'if.
Infatti una variabile interna a un blocco non sopravvive oltre esso, quindi dichiararla all'interno dell'if non è sufficiente.

Attenzione a non premettere 'local' nelle assegnazioni dei rami del condizionale: in questo caso verrebbe creata una nuova variabile locale al blocco con lo stesso nome della variabile esterna che viene oscurata. In altri termini, al termine del blocco 'digits' varrebbe ancora nil perché avremmo modificato una variabile locale al blocco.

Esercizi

Contare quanti interi sono divisibili sia per 2 che per 3 nell'intervallo [1, 10000]. Suggerimento:utilizzare l'operatore modulo '%' resto della divisione intera tra due operandi.

Determinare i fattori del numero intero 5461683.

Instanziare la tabella seguente di tre tabelle/array di tre numeri e calcolarne il determinante.
 t = {
    { 0,  5, -1},
    { 2, -2,  0},
    {-1,  0,  1},
}

Data la tabella seguente stampare in console il conteggio dei numeri pari e dei numeri dispari contenuti in essa. Verificare con un costrutto 'assert()' che la somma di questi due conteggi sia uguale alla dimensione della tabella.
 t = {
    45, 23, 56, 88, 96, 11,
    80, 32, 22, 85, 50, 10,
    32, 75, 10, 66, 55, 30,
    10, 13, 23, 91, 54, 19,
    50, 17, 91, 44, 92, 66,
    71, 25, 19, 80, 17, 21,
    81, 60, 39, 15, 18, 28,
    23, 10, 18, 30, 50, 11,
    50, 88, 28, 66, 13, 54,
    91, 25, 23, 17, 88, 90,
    85, 99, 22, 91, 40, 80,
    56, 62, 81, 71, 33, 30,
    90, 22, 80, 58, 42, 10,
}

Data la tabella precedente scrivere il codice per costruire una seconda tabella uguale alla prima ma priva di duplicati senza alterare l'ordine delle cifre.

Data la tabella precedente costruire una tabella le cui chiavi siano i numeri contenuti in essa e i valori siano il corrispondente numero di volte che la chiave stessa compare nella tabella di partenza. Stampare poi in console il numero che si presenta il maggior numero di volte.

Esempio spaziale

Data la tabella Lua riportata nel seguito con dati sugli orbiter del programma Space Shuttle della Nasa, scrivere un programma per calcolare:
  • il numero totale dei voli effettuati dagli orbiter;
  • il numero totale degli attracchi alla Stazione Spaziale Internazionale (ISS);
  • il tempo medio di costruzione in anni degli orbiter (è consentito assumere i mesi pari a 30 giorni);
  • per ciascun orbiter, il tempo in giorni trascorso tra la prima missione e l'ultima;
  • il nome dell'orbiter che a volato per primo.

Un quiz articolato (mentre scrivevo le domande mi sembrava di essere a Rischiatutto con Mike Buongiorno).

-- Space Shuttle Missions Database. Version 1.8.
-- from: https://sites.google.com/site/monzitrek/missioni-shuttle
-- by: © 2005-2011 - Ing. Luigi Morielli
-- licence: http://creativecommons.org/licenses/by-nc-sa/2.5/it/

-- per info consultare anche i siti dell'associazione ISAA:
-- http://www.isaa.it/
-- http://www.forumastronautico.it/
-- http://www.astronauticast.com/

Shuttle_DB = {-- tables' array
    {
        orbiter_id = "OV-099", orbiter_name ="Challenger",
        flight = 10,
        ISS_docking =  0,
        start_costruction = {d=24, m=06, y=1975},
        end_costruction = {d=23, m=10, y=1981},
        first_mission = {d=04, m=04, y=1983},
        last_mission = {d=28, m=01, y=1986},
        cause = "destroyed",
    },
    {
        orbiter_id = "OV-102", orbiter_name ="Columbia",
        flight = 28,
        ISS_docking =  0,
        start_costruction = {d=27, m=03, y=1975},
        end_costruction = {d=08, m=03, y=1979},
        first_mission = {d=12, m=04, y=1981},
        last_mission = {d=01, m=02, y=2003},
        cause = "destroyed",
    },
    {
        orbiter_id = "OV-103", orbiter_name ="Discovery",
        flight = 39,
        ISS_docking = 13,
        start_costruction = {d=27, m=08, y=1979},
        end_costruction = {d=25, m=02, y=1983},
        first_mission = {d=30, m=08, y=1984},
        last_mission = {d=24, m=02, y=2011},
        cause = "retired",
    },
    {
        orbiter_id = "OV-104", orbiter_name ="Atlantis",
        flight = 33,
        ISS_docking = 12,
        start_costruction = {d=03, m=03, y=1980},
        end_costruction = {d=10, m=04, y=1984},
        first_mission = {d=03, m=10, y=1985},
        last_mission = {d=08, m=07, y=2011},
        cause = "retired",
    },
    {
        orbiter_id = "OV-105", orbiter_name ="Endeavour",
        flight = 25,
        ISS_docking = 12,
        start_costruction = {d=15, m=02, y=1982},
        end_costruction = {d=06, m=07, y=1990},
        first_mission = {d=07, m=05, y=1992},
        last_mission = {d=16, m=05, y=2011},
        cause = "retired",
    },
}

Riassunto della puntata

Finalmente un po' di codice in Lua! Abbiamo incontrato le particolarità dell'operatore lunghezza '#' e i costrutti di base come i cicli 'for', 'while' e il condizionale 'if'.

Proseguiamo nella prossima puntata a presentare nuovi elementi del linguaggio attraverso esempi di codice. Sarà la volta degli operatori logici 'and', 'not' e 'or' e delle operazioni sulle stringhe.

mercoledì 25 marzo 2015

Da jpg a png con l'aiuto di sed. [Brevi Esercizi]

Salve!

Come convertire svariate foto da jpg a png.

Prerequisito

$ sudo apt-get install imagemagick


Le foto il cui formato va convertito:


La riga di comando:

for i in *.jpg; do j=$(echo $i | sed -e 's/\.jpg/\.png/'); convert $i $j; done;


Le foto convertite in png.


Alla prossima!

Un esempio di contabilità con AWK [Brevi Esercizi]

Salve!

Ogni tanto ritorno ad awk per svolgere compiti semplici semplici. Forse avrei dovuto scrivere per risolvere problemi semplici con uno strumento estremamente potente come awk.

Andiamo a noi. Ho abbozzato una tabella (incompleta) contenente somme di denaro in entrata(+) e in uscita(-). Lo scopo è quello di avere somme per colonne, per righe e, alla fine, ottenere il totale (rimanente).

tab

Gen -508 +133 -900 
Feb +981 -240 +325 
Mar +450 +340 +435 
Apr +111 +234 +556
Mag +768 -998 +431
Giu +901 +123 +877
Lug +213 +356 +678
Ago +321 +653 +876

test.awk

#!/usr/bin/awk -f
 
  BEGIN { 

         
         print "\n\t\t_____Contabilità 2014_____\n";
         FS=" "; OFS = "\t";
  }                                                   
    { 
      Mese="//"; a += $2; b += $3; c += $4;
      tot = ($2+$3+$4); 
      print "\t" $1,$2,$3,$4,"|  "tot;
    }
  END { 
       print "\t________________________________\n";
       print "\t" Mese,a, b, c, "--> "(a+b+c)" (Totale)","\n";
 }

Risultato: 



Alla prossima!

giovedì 19 marzo 2015

Corso Lua - puntata 3 - La tabella


La tabella

In questa puntata del corso base su Lua, parleremo della tabella l'unico tipo strutturato predefinito di Lua. Diamone subito la definizione.

La tabella è un dizionario cioè l'insieme non ordinato di coppie chiavi/valore. In Lua ne è previsto l'uso molteplice: se le chiavi sono numeri interi la tabella fa le veci di un array, se le chiavi sono di altro tipo essa sarà un dizionario, ovvero un array associativo.

Le chiavi possono essere di tutti i tipi previsti da Lua tranne che il tipo nil. I valori possono appartenere a qualsiasi tipo. Nulla vieta che in una stessa tabella coesistano chiavi di tipo diverso.

Dal punto di vista sintattico, una tabella di Lua è un oggetto racchiuso tra parentesi graffe. La più semplice tabella è quella vuota che si crea così:
  t = {} -- una tabella

Per assegnare e ottenere il valore associato a una chiave si utilizzano le parentesi quadre, ecco un esempio (svolgetelo in modalità interattiva avviando l'interprete Lua in un terminale dando il comando 'lua'):
  t = {}
  t["key"] = "val"

  print(t["key"]) --> stampa "val"

Stando alla definizione che abbiamo dato una tabella può avere chiavi anche di tipo differente, e infatti è proprio così e ciò vale anche per i valori. In questo esempio una tabella ha chiavi di tipo numerico e di tipo stringa con valori a loro assegnati a sua volta di tipo diverso:
  t = {}
  t["key"] = 123
  t[123] = "key"

  print(t["key"]) --> stampa il tipo numerico 123
  print(t["123])  --> stampa il tipo stringa "key"

La tabella è un oggetto

Proseguiamo nel presentare i concetti di base del linguaggio riservando alle prossime puntate del corso la scrittura vera e propria di codice applicativo.

Cosa significa che la tabella di Lua è un oggetto come abbiamo scritto nel titolo di sezione? Vuol dire che la tabella è un'entità in memoria gestita con riferimenti.

In conseguenza, se si copia un riferimento a tabella in una seconda variabile ci si riferirà alla stessa tabella e non a una sua copia:
  t = {}
  t[1] = 10
  t[2] = 20

  other = t
  t[1] = t[1] + t[2]
  assert(other[1] == 30 ) -- other e t si riferiscono alla stessa tabella
  assert(t[1] == 30)

Questa proprietà della tabella di Lua è la premessa fondamentale per la programmazione a oggetti in Lua e per scrivere codice più compatto nelle elaborazioni su tabelle molto complesse.

In effetti possiamo memorizzare in una tabella ulteriori tabelle assegnandole come valore di chiavi stringa e strutturare con complessità arbitraria i dati. In altri termini una tabella può rappresentare una struttura ad albero senza limiti teorici.
Poiché la tabella è gestita attraverso un riferimento come appunto un oggetto, nell'albero di tabelle vi saranno solamente i corrispondenti riferimenti e non le tabelle come valore stivate in qualche area di memoria.

Il costrutture e la 'dot notation'

Dunque la tabella è un tipo di dato molto flessibile (e sufficientemente efficiente). Può essere usata in moltissime diverse situazioni ed essa è ancora più utile grazie all'efficacia del suo costruttore.

Ispirato al formato di dati bibliografici di BibTeX, uno dei programmi storici del sistema TeX per la gestione delle bibliografie nei documenti LaTeX, il costruttore di Lua può creare tabelle da una sequenza di chiavi/valori in questo modo:
  t = { a = 123, b = 456, c = "valore"}

La chiave appare come il nome di una variabile ma in realtà nel costruttore essa viene interpretata come una chiave di tipo stringa. Così l'esempio precedente è equivalente al seguente codice:
  -- codice equivalente
  t = {}
  t["a"] = 123
  t["b"] = 456
  t["c"] = "valore"

La notazione del costruttore non ammette l'utilizzo diretto di chiavi numeriche. Se occorrono è necessario utilizzare le parentesi quadre per racchiudere il numero:
  -- chiavi numeriche nel costruttore?
  t_error = { 1 = 123 }
  t_ok = { [1] = 123 }

Invece, se nel costruttore omettiamo le chiavi otteniamo una tabella che svolgerà il ruolo di array con indici interi impliciti che cominceranno da 1, contrariamente alla maggior parte dei linguaggi dove l'indice comincia sempre da 0. Ecco un esempio:
  t = { 123, 456, 789 }
  print(t[1] + t[2] + t[3]) --> stampa 1368

Non è tutto. L'efficacia sintattica del costruttore è completata dalla dot notation comune in molti linguaggi a oggetti e valida solamente per le chiavi di tipo stringa: il campo di una chiave di tipo stringa si accede scrivendone la chiave dopo il nome del riferimento della tabella separato dal carattere ".":
  t = { chiave = "123" }
  assert(t.chiave == t["chiave"])

Prestate attenzione perché ci sono casi in cui all'inizio si può male interpretare il risultato del costruttore della tabella se unito alla dot notation:
  chiave = "ok"
  t = { ok = "123"}
  assert( t.ok == t[chiave] ) -- ok
  
  -- attenzione!
  k = "ok"
  print( t.k ) --> stampa nil: "k" è una chiave non definita in t
  print( t[k]) --> stampa "123" : vale infatti t[k] == t["ok"] == t.ok
  --> t.k diverso da t[k] !!!

Non confondete il nome di variabile con il nome del campo in dot notation!

Riassumendo, indicizzare una tabella con una variabile restituisce il valore associato alla chiave uguale al valore della variabile, mentre indicizzare in dot notation con il nome uguale a quello della variabile restituisce il valore associato alla chiave corrispondente alla stringa del nome.

Con la funzione assert() di Lua si può esprimere l'equivalenza logica tra due espressioni. Essa ritorna l'argomento se questo è vero oppure se non è nil, altrimenti ritorna un errore descritto eventualmente da un secondo argomento.

Questo perché in Lua un'espressione è vera se essa vale 'true' oppure se non vale nil.

Esercizi (e domande)

Scrivere un programma che memorizzi in una tabella i primi 10 numeri primi.

Utilizzando la 'dot notation' è possibile utilizzare caratteri spazio nel nome della chiave delle tabelle?

Scrivere un programma che stampi il valore associato alle chiavi 'paese' e 'codice', e il numero medio di comuni per regione, per la seguente tabella Lua. Stampare inoltre il numero di abitanti della capitale.
  t = {
    paese = "Italia",
    lingua = "italiano",
    codice = "IT",
    regioni = 20,
    provincie = 110,
    comuni = 8047,
    capitale = {"Roma", "RM", abitanti = 2753000},
}

Riassunto della puntata

Abbiamo introdotto la tabella di Lua, l'unico tipo strutturato predefinito di Lua e il suo motore di funzionalità principale. Fate gli esercizi proposti e qualche prova in modalità interattiva per fissare i concetti di indicizzazione, costruttore e dot notation di una tabella.

Con questa puntata si conclude la fase introduttiva al linguaggio. La luna comincia a splendere ed è ormai piena.

lunedì 16 marzo 2015

Ognuno ha il suo sticky bit che si merita!

Ora vi racconto, che forse neanche Juhan... Vabbe', lui ora è impegnato con lisp...lo state seguendo il corso, vero? :)

Lo sapete che l'associazione Gli Amici di Lubit è diventata un Lug?

Partiamo dall'inizio. Abbiamo creato un server, dove ognuno dei soci può accedervi tramite sftp. Ogni socio ha il suo utente, etc.

Abbiamo creato anche una cartella condivisa, cui ho dato un bel 777, tuttavia, non mi sembrava giusto che ogni utente potesse cancellare oltre ai suoi file anche quelli degli altri. Allora ho fatto ricorso allo sticky bit.

Ma cos'è uno sticky bit?

Lo sticky bit è un permesso speciale che può essere associato ad un file (tipicamente ai file eseguibili) o ad una directory.
Se lo sticky bit è abilitato su una cartella, il contenuto della stessa può essere eliminato solo dal proprietario che lo ha creato o dall'utente root (che tutto può). Nessun altro può eliminare i dati degli altri utenti in questa cartella. Questa è una misura di sicurezza per evitare la cancellazione di cartelle e dei loro contenuti, anche se gli altri utenti hanno autorizzazioni complete, in lettura e scrittura.


Per abilitare lo sticky bit sulla cartella condivisa, che si trova nella directory /home,

# chmod o+t cartella_condivisa

Per disabilitarlo

# chmod -t cartella_condivisa

Una particolarità.

$ cd /

$ ls -la




Se andate a vedere i permessi della directory /tmp, noterete che è già abilitato lo sticky bit, lo si capisce dalla presenza della "t" ;)

Per saperne di più: qui e qui.

Alla prossima! 

venerdì 13 marzo 2015

Corso Lua - puntata 2 - Assegnazione


L'assegnamento

Eccoci alla seconda puntata del corso base su Lua, il formidabile linguaggio di programmazione, veloce, semplice e utile. Dovreste aver accesso a un computer con l'interprete Lua già installato, se no, rileggete la puntata precedente per conoscere alcune informazioni di base per farlo. Così potrete eseguire il codice.

Oggi ci occuperemo di uno degli elementi di base dei linguaggi informatici: l'istruzione di assegnamento. Con questa operazione si introduce un simbolo nel programma associandolo a un valore appartenente a un dato tipo.

La sintassi di Lua non sorprende: a sinistra compare il nome della variabile e a destra l'espressione che fornirà il valore da assegnare mentre il carattere di "=" funge da simbolo semantico e separatore:
  a = 123
Durante l'esecuzione di questo programma Lua determina dinamicamente il tipo del valore letterale '123' --- un numero --- istanziandolo globalmente come simbolo 'a'. La semplice istruzione di assegnamento nasconde quindi due cose importanti di Lua: la prima è che non è necessario specificare esplicitamente il tipo dei dati come in altri linguaggi a tipi dinamici, e la seconda è che il tipo è determinato e associato al simbolo in modo automatico.

Modalità interattiva

Aprite un terminale, o console in Windows, e digitate semplicemente il comando lua. Entreremo nella modalità interattiva dove potremo digitare istruzioni una alla volta. Per uscire tornando al prompt, digitate la funzione Lua os.exit() con un bel tasto invio.

In modalità interattiva possiamo comodamente controllare quale tipo avrà un valore, utilizzando la funzione type(). Essa restituisce una stringa con il nome del tipo di un'espressione, stringa che possiamo a sua volta stampare con la funzione print(): stampa l'argomento in console. Digitiamo:

 a = 123
 print(type(123))    --> stampa "number"
 print(type(a))      --> stampa "number"
 print(type("123"))  --> stampa "string"


Locale o globale?

La seconda proprietà nascosta è che se non diversamente specificato Lua istanzia i simboli nell'ambiente globale del codice in esecuzione. Se si desidera creare una variabile locale sempre rispetto al blocco di codice in cui è definita, basta premettere la parola chiave local.

Le variabili locali evitano alcuni errori di programmazione e in Lua rendono il codice più veloce. Le useremo sempre quando un simbolo appartiene in modo semantico a un blocco, per esempio a una funzione.

Da notare che in sessione interattiva ogni riga è un blocco quindi le variabili locali non sopravvivono alla riga successiva. Perciò negli esempi in questa modalità useremo variabili globali.

Se si crea una variabile locale con una variabile globale quest'ultima viene oscurata e il suo valore protetto da modifiche.

Il tipo nil

Uno dei concetti più importanti che caratterizzano un linguaggio è la presenza o meno del tipo nullo. In Lua esiste e viene chiamato nil. Il tipo nullo ha un solo valore possibile anch'esso chiamato nil. Il nome è così sia l'unico valore possibile che il tipo.

Leggere una variabile non istanziata non è un errore perché Lua restituisce semplicemente nil, mentre assegnare il valore nullo a una variabile la distrugge.
Sempre in sessione interattiva:

 print(z)    --> stampa nil, la variabile 'z' non esiste
 z = 123     --> assegnamento di un tipo numerico
 print(z)    --> stampa 123
 z = nil     --> distruzione della variabile


Le variabili non più utili come quelle riassegnate a nil o quelle locali quando queste escono di scopo, vengono gestite automaticamente dal garbage collector di Lua. Questo componente semplifica la gestione della memoria al prezzo di una piccola diminuzione delle prestazioni.

Certamente se è un garbage collector a liberare dietro le quinte la memoria non più utilizzata il programma non conterrà gli errori tipici di questa gestione manuale.

Assegnazioni multiple

In Lua possono essere assegnate più variabili alla volta nella stessa istruzione.
Questo significa che l'assegnamento è in realtà più complesso di quello presentato fino a ora perché è possibile scrivere una lista di variabili separate da virgole che assumeranno il valore corrispondente in una lista di espressioni sempre separate da virgola:
 x, y, z = 1, 2, 3
 print(x, y, z)

Quando i nomi dei simboli non corrispondono alle espressioni Lua assegnerà automativamente valori nil o ignorerà le espresisoni in eccesso, per esempio sempre in sessione interattiva al terminale proviamo il seguente codice:
 a, b, c = 0.45, "text"  -- c è nil
 print(a, b, c)

 x, y = "op", "qw", "lo"
 print(x, y)  -- "lo" è ignorata

Nell'assegnazione Lua prima valuta le espressioni a destra e solo successivamente crea le rispettive variabili secondo l'ordine nelle liste. Allora per scambiare il valore di due variabili, operazione chiamata di switch, è sufficiente il codice:
 x, y = y, x


Un ulteriore esempio di assegnazione multipla è il seguente, a dimostrazione che le espressioni della lista a destra vengono prima valutate e solo dopo assegnate alle corrispondenti variabili nella lista di sinistra:
  -- costante
  pi = 3.14159
  -- raggio del cerchio
  r = 10.8
  -- grandezze principali del cerchio
  diam, circ, area = 2*r, 2*pi*r, pi*r^2

  -- stampa grandezze
  print("Diametro", diam)
  print("Circonferenza", circ)
  print("Area", area)

Le assegnazioni multiple sono interessanti ma non così importanti, possiamo infatti ricorrere ad assegnazioni semplici. Diverranno invece molto utili con le funzioni e gli iteratori di cui ci occuperemo nel seguito.

Una manciata di tipi

In Lua esiste una manciata di tipi. Essenzialmente omettendone due sono solo questi:
  • il tipo numerico (solamente dalla versione 5.3 di Lua vengono internamente distinti gli interi e i numeri in virgola mobile);
  • il tipo stringa;
  • il tipo booleano;
  • il tipo tabella;
  • il tipo nil;
  • il tipo funzione.

Il breve elenco può suscitare due osservazioni: tranne la tabella non esistono tipi strutturati e le funzioni hanno il rango di tipo.

Questo fa capire molto bene il carattere di Lua: da un lato l'essenzialità ha ridotto all'indispensabile i tipi predefiniti nel linguaggio ma dall'altro ha spinto all'inclusione di concetti intelligenti e potenti.

Esercizi

Scrivere un programma che instanzi due variabili 'x' e 'y' al valore 12.34 e assegnare a altre due variabili 'sum' e 'prod' la somma e il loro prodotto delle prime. Si stampi in console i risultati contenuti in 'sum' e 'prod'.

Scrivere un programma che dimostri che modificare una variabile locale non modifica il valore della variabile globale con lo stesso nome. Suggerimento: utilizzare la coppia do/end per creare un blocco di codice con le proprie variabili locali.

Riassunto della puntata

Ho tenuto al minimo le istruzioni da digitare per effettuare le prove di codice per non distogliere l'attenzione sui concetti fondamentali di Lua che riguardano le variabili che riassunti sono:
  • l'assegnazione semplice istanzia variabili globali;
  • il tipo nil è utilizzato per dare significato alle variabili non istanziate e per eliminare quelle istanziate;
  • l'assegnazione multipla si basa sulla corrispondenza di posizione nelle liste separate da virgole dei nomi e delle espressioni di valori.

Nella prossima puntata affronteremo la tabella, l'oggetto più importante in Lua. Dovremo conoscerlo bene per scrivere programmi utili.

giovedì 12 marzo 2015

Lubit e la frase "ERROR: PAE is disabled on this Pentium M"

E' successo al caro amico Marco Inturri, cui va il mio grazie per aver trovato la soluzione. A Marco succedeva che il sistema, da live, non si avviava proprio e compariva la fatidica e sinistra frase: ERROR: PAE is disabled on this Pentium M


Ovviamente il problema non si presenta solo con Lubit...Ne sono testimoni le infinite ricerche fatte.

Tuttavia, quello che conta è che è stata trovata una soluzione anche a questo problema.


Quando compare questa prima schermata, bisogna premere il tasto "Tab" e, dopo "quiet splash", bisogna digitare in modo corretto:

-- forcepae

State attenti ai due trattini, devono essere staccati dalla parola forcepae.

Lubit sta crescendo, è vero, ma questo perchè sta crescendo anche la comunità intorno a Lubit.

Alla prossima!

mercoledì 11 marzo 2015

Corso Lua - puntata 1


Sperimentare con Lua


Le risorse disponibili oggi per studiare Lua sono molte ma quando Luigi mi ha proposto di realizzare un progetto di divulgazione su questo linguaggio di programmazione ho pensato che accettando avrei potuto sperimentare qualcosa di nuovo.
Eccomi qui allora sul blog Lubit Linux con il desiderio di ricerca e approfondimento.

Naturalmente, auguro a tutti una Buona partecipazione!

Installare Lua sul sistema

Per seguire queste chiaccherate andrà benissimo una versione di Lua uguale o superiore alla 5.1.

L'interprete Lua è scritto in Ansi C e per questo è disponibile praticamente per tutte le piattaforme. Per i sistemi Linux fate ricorso al package manager della vostra distribuzione, per esempio, per le distribuzioni Debian e derivate è sufficiente dare il comando:

$ sudo apt-get install lua


Per Windows fate riferimento alla pagina luabinaries preferendo l'ultima versione (Lua 5.3 è in arrivo mentre scrivo queste note). In caso di problemi potete scaricare un file autoinstallante dal progetto Lua for Windows fermo però alla versione 5.1 di Lua ma completo di alcune librerie utili.

Per Mac OSX andate alla pagine Rudix e individuate il package adatto per la versione del vostro Mac.

Ci può stare anche la compilazione dai sorgenti scaricabili dal sito ufficiale ma è una procedura che l'utente interessato può fare dopo essere diventato esperto del linguaggio, magari per impostare alcuni parametri personalizzati. Credo infatti che sia meglio non perdere tempo se sono già disponibili i binari precompilati, non vi pare?

Pronti? Via. Cominciamo...

Lua, proprio un bel nome

Lua è un linguaggio semplice ma non banale. Il suo ambito di applicazione è quello dei linguaggi di scripting: text processing, manutenzione del sistema, elaborazioni sui file dati, eccetera e lo si può trovare come linguaggio embedded di programmi complessi come i videogiochi o altri applicativi programmabili dall'utente.

Lua è stato ideato da un gruppo di programmatori esperti dell'Università Cattolica di Rio de Janeiro in Brasile.

"Lua" (si pronuncia LOO-ah) significa "Luna" in portoghese!

Primo compito a casa

Il primo compito a casa è proprio quello di installare Lua sul vostro computer e di commentare qui sul blog la procedura.

Per verificare l'installazione è possibile dare il seguente comando da terminale per stampare la versione dell'interprete:

$ lua -v
Lua 5.2.3  Copyright (C) 1994-2013 Lua.org, PUC-Rio


Alla prossima!
R.

domenica 1 marzo 2015

Auguri, ringraziamenti e qualche pensiero sparso.

Buongiorno!

Voi non potete immaginare quanto sia piccolo il mondo. E con internet ancora di più. Tu esprimi un parere attraverso un commento ad un post mentre stai al calduccio della tua stanza, ad esempio, in Brasile, ed io lo leggo quasi in tempo reale al calduccio della mia di stanza. Vabbe', tanto caldo, in effetti, nella mia stanza non fa, per la mia abitudine di tenere la finestra aperta anche d'inverno, di notte e di giorno. In realtà, la ragione di questo mio post è che voglio ringraziare tutti coloro hanno voluto recensire Lubit Linux 5. Sono del parere che chiunque faccia qualcosa per Lubit gli vada riconosciuto.

Ecco, passiamo alle recensioni di lubit 5. Che dire, un grazie di cuore a tutti coloro che l'hanno recensita, alcuni miei amici, altri del tutto sconosciuti. Un grazie va anche a chi l'ha semplicemente presentata, a chi ha espresso soddisfazione, alla comunità che si è venuta a creare intorno alla distro, ma anche a chi ha manifestato delle critiche costruttive, mentre rimando al mittente le critiche cattive (pochissime, a dire il vero), quelle che derivano da persone che non hanno mai fatto niente per il software libero e che tuttavia si arrogano il diritto di sputare sentenze.

Un grazie va al mio socio e amico Massimo Testa, cofondatore del Lubit Project. E un grazie va all'associazione Gli Amici di Lubit.

Un grazie al mio amico Juhan

Lubit 5, Jean

Un grazie allo staff di LFFL

Lubit 5, disponibile per il download

Un grazie all'amico Marco Giannini

Rilasciata Lubit Linux 5, ora anche per sistemi a 64-bit!

Un grazie all'amico Salvatore :)

Lubit 5 , nome in codice JEAN

Un grazie ad Edivaldo

Lubit 5 já está disponível para download

Un grazie al gestore del blog blogredire

Expò Vicenza

Un grazie al professore Cantaro.

Lubit 5 Linux

Un grazie all'amico Gianluigi

Lubit 5

Un grazie all'amico Giuseppe.

Lubit 5 è già operativo!

Un grazie a softpedia.com

Lubit 5

Un grazie ad anarchia.com

Lubit linux elegante e leggero 

Un grazie all'amico Salvatore Cottone

Lubit 5 GNU/Linux

Un grazie a Linuxiarze.pl

Lubit Linux

Un grazie al blog Rubrica informatica

Lubit 5- La distro italiana: ora anche 64bit!

Un grazie a Newsletter di Ubuntu.it

NewsletterItaliana

Grazie a Evilripper blog

Lubit 5

Grazie all'amico Michele

Lubit Linux 5 

Grazie a Oneopensource di HTML.it

Lubit Linux 5, distro leggera e made Italy

Un'altra nota di rilievo, Lubit 5, nei suoi primi 12 giorni di vita, è stata scaricata 4839 volte. Grazie a tutti!!


Chi scarica Lubit (statistica generale)


Ah, dimenticavo... Oggi ricorre anche il compleanno del blog!!!

Auguri al blog Lubit Linux, auguri a tutti gli autori, auguri a tutti i lettori!!! ;)


Alla prossima!