Robitex's Blog

Ideas in the web

Il computo metrico con Lua


Scarica l’articolo in formato PDF per la stampa

Sommario

Certi tipi di opere edili possono essere così articolate da mettere in difficoltà l’utente che intendesse gestirle con un tradizionale software di computazione.
In questo post si svilupperà un’idea che può risolvere il problema di efficienza, secondo la quale i dati sono descritti da un opportuno linguaggio così da esprimere in modo diretto e concettuale le particolarità dell’opera edilizia.

Computi metrici

Un computo metrico di un opera consiste in una serie di voci che definiscono i singoli componenti edilizi quantificate secondo una specifica unità di misura. Inserire le misure è una di quelle attività leggermente noiose e poco attraenti…

Con un linguaggio specifico è possibile rendere efficiente l’inserimento manuale di queste quantità, in particolare se si desidera che i dati siano raggruppati in livelli strutturati.

Il linguaggio dei solai

Se l’opera in progetto è composta da diversi edifici a più piani, dovremo calcolare le superfici dei solai raggruppando i dati secondo la doppia classificazione piano/edificio. Saremo così in grado di fornire le superfici di solaio per ciascun piano, quelle totali per singolo edificio e quelle complessive per piano.

Un linguaggio semplice che descrive questa struttura informativa potrebbe essere questo:

solaio{
   edificio = "A",
   piano = 1,
   superficie = 4.50*3.25,
}

La sintassi che riscontriamo leggendo il frammento di codice, si basa su un costrutto chiave = valore ciascuno separato con una virgola e racchiuso in un coppia di parentesi graffe.

I valori testo sono racchiusi tra doppi apici mentre i valori numerici utilizzano il punto e non la virgola per separare la parte decimale.
Vi anticipo che il codice precedente corrisponde alla sintassi di Lua, un linguaggio di programmazione libero e multi-piattaforma, più volte trattato sul blog.

Continuando a tagliare su misura il codice per renderlo perfettamente adatto ad esprimere le quantità che vorremmo computare, osserviamo che non ci occorre identificare i singoli solai di uno stesso piano di uno stesso edificio. Alla chiave superficie assegniamo allora non un singolo valore o espressione, ma un elenco di espressioni corrispondenti alla geometria dell’impalcato, per esempio (possiamo commentare il codice inserendo due trattini):

-- cambiamo nome all'oggetto🙂
solaiDiPiano{
   edificio   = "A",
   piano      = 1,
   superficie = {
      2*4.50*3.25,           -- qui due solai uguali
      3.80*3.25,
      4.64*4.20 - 0.40*0.70, -- qui una detrazione di una botola!
      4.24*(4.20 + 3.50),
      5.50*3.60,             -- la virgola finale è opzionale
      },                     -- ma rende più comode successive
}                            -- aggiunte di valori

Osservazioni operative

L’ambiente in cui si memorizza il codice è un editor di testo ASCII. La comodità sta nel fatto che i dati sono immediatamente disponibili su qualsiasi sistema operativo per eventuali modifiche o verifiche, e possiamo eseguire le operazioni con poca fatica.

Nel frattempo ho aggiunto altri dati come potete vedere dal prossimo frammento di codice:

solaiDiPiano{edificio="A", piano=1,
   superficie = {
      2*(1.60+3.60+2.07)*(4.345+4.245),
      1.92*2.64,
      3.60*(0.55+1.05)*2,
   }
}

solaiDiPiano{edificio="A", piano=2,
   superficie = {
      2*(1.60+3.60+2.07)*(4.345+4.245),
      1.92*2.64,
      3.60*(0.55+1.05)*2,
   }
}

solaiDiPiano{edificio="A", piano=3,
   superficie = {
      2*(1.65+3.60+2.12)*(4.42+4.32),
      1.92*2.64,
      3.60*(0.55+1.05)*2,
   }
}

solaiDiPiano{edificio="B", piano=1,
   superficie = {
      2*(2.54+2.54+2.56+2.545)*(4.345+4.245),
      2*1.00*2.64
   }
}

solaiDiPiano{edificio="B", piano=2,
   superficie = {
      2*(2.54+2.54+2.56+2.545)*(4.345+4.245),
      2*1.00*2.64
   }
}

solaiDiPiano{edificio="C", piano=1,
   superficie = {
      2*(1.60+3.60+2.07)*(4.345+4.245),
      1.92*2.64,
      3.60*(0.55+1.05)*2,
   }
}

solaiDiPiano{edificio="C", piano=2,
   superficie = {
      2*(1.60+3.60+2.07)*(4.345+4.245),
      1.92*2.64,
      3.60*(0.55+1.05)*2,
   }
}

solaiDiPiano{edificio="C", piano=3,
   superficie = {
      2*(1.65+3.60+2.12)*(4.42+4.32),
      1.92*2.64,
      3.60*(0.55+1.05)*2,
   }
}

Elaborare i dati

Ma come si elaborano i dati?
Il codice scritto corrisponde esattamente ad una serie di chiamate alla funzione Lua solaiDiPiano() a cui passiamo una tabella.
Eseguendo il codice, verranno calcolate le espressioni delle superfici e le istruzioni contenute nella funzione.

Elaborazione diretta

Proviamo a scrivere la funzione in modo da ottenere la superficie totale dei solai:

-- superficie totale
local totsup = 0

-- definizione della funzione
function solaiDiPiano(s)
   -- campi in s:
   -- s.superficie -> array di valori

   -- sommo tutti i valori in s.superficie
   -- e li inserisco nel totale
   for _, val in ipairs(s.superficie) do
      totsup = totsup + val
   end
end

-- carico il file dati
dofile("solai.lua")

-- stampo il risultato
print(string.format("Superficie totale : %0.3f",totsup))

Una volta installato sul sistema Lua, inseriamo i dati dei solai così come si è deciso di descriverli nel file testo “solai.lua”. Salviamo in un secondo file il codice che li elabora “calcsuptot.lua”, ed infine apriamo il terminale o la console ed eseguiamo il comando:

> lua calcsuptot.lua

Fatto! La schermata rappresentativa dell’operazione in Windows è la seguente, dove si può notare l’uso del comando cd per spostarsi nella directory dove avevo salvato i due file.

Esecuzione del report per la superficie totale in console

Esecuzione del report per la superficie totale in console

Elaborazione strutturata

Diamo una definizione strutturata della funzione solaiDiPiano() in modo da costruire una tabella dati chiamata Solai che potremo leggere in modi diversi. Questa è la via sicuramente più flessibile e potente.

-- serve un contenitore per i dati:
local Solai = {}

-- creazione della tabella dati
function solaiDiPiano(s)
   -- ricordiamo i nomi dei campi in s
   -- s.edificio   := nome edificio
   -- s.piano      := numero di piano
   -- s.superficie := array di valori

   -- se non esiste ancora creiamo
   -- una tabella per edificio
   -- rispetto al nome
   -- es.: Solai.A
   if not Solai[s.edificio] then
     Solai[s.edificio] = {}
   end

   -- prendiamoci un riferimento più comodo
   -- alla singola tabella edificio
   local edificio = Solai[s.edificio]

   -- calcoliamo la somma delle superfici
   local suppiano = 0
   for _, val in ipairs(s.superficie) do
      suppiano = suppiano + val
   end

   -- intenderemo la tabella edificio
   -- come un array dove l'indice sarà
   -- il numero di piano ed il valore
   -- corrispondente, la superficie
   if edificio[s.piano] then
      edificio[s.piano] = edificio[s.piano] + suppiano
   else
     edificio[s.piano] = suppiano
   end
end

Fatto questo, potremo elaborare decine od anche migliaia di elementi si solaio. Tutti i dati saranno memorizzati nella tabella Solaio Solaio.

A questo punto scriviamo la funzione di reporting che opererà in lettura. Vogliamo stampare per esempio i totali di piano per edificio:

-- report piano/edificio
function reportPianoEdificio()
   -- Solai contiene i dati in modo strutturato
   -- Al primo livello ci sono le tabelle edificio

   local totsup = 0
   for nomeEd, arraysup in pairs(Solai) do
      print(string.format("Edificio %s: --------------------", nomeEd))

      -- stampiamo le superfici piano per piano
      local totsupEd = 0
      for level, sup in pairs(arraysup) do
         totsupEd = totsupEd + sup
         print(string.format("Piano %2d, superficie %10.3f", level, sup))
      end

      totsup = totsup + totsupEd
      print("--------------------------------")
      print(string.format("Tot. sup. edificio %s: %10.3f", nomeEd, totsupEd))
      print("--------------------------------")
   end
   print("--------------------------------")
   print(string.format("Tot. superfici %10.3f", totsup))
   print("--------------------------------")
end

In console ottengo questo:

Esecuzione del report in console

Esecuzione del report Piano/Edificio in console

Se volessimo stampare le superfici piano per piano dovremo costruire una funzione in lettura di questo tipo:

-- report per piani
function reportPiani()
   -- una tabella per le sup di piano
   local suppiani = {}

   -- ciclo per singolo edificio
   -- primo livello della struttura dati Solaio
   for nomeEd, arraySup in pairs(Solai) do
      -- ciclo interno di lettura delle sup
      for piano, sup in pairs(arraySup) do
         if suppiani[piano] then
            suppiani[piano] = suppiani[piano] + sup
         else
            suppiani[piano] = sup
         end
      end
   end

   -- stampa
   local ts = 0
   for level, sup in pairs(suppiani) do
      ts = ts + sup
      print(string.format("Livello %2d: sup = %10.3f",level,sup))
   end
   print("--------------------------")
   print(string.format("Totale sup = %10.3f",ts))
end

--[[
-- l'output con i soliti dati è questo
Livello  1: sup =    463.233
Livello  2: sup =    463.233
Livello  3: sup =    290.833
--------------------------
Totale sup =   1217.299
--]]

Conclusioni

L’idea proposta è originale? No! Volendo, si possono fare molti esempi tratti dal mondo dell’informatica dove un linguaggio testuale descrive dati strutturati. Con Lua è semplice creare il proprio linguaggio ed elaborare i dati, pensiamo per esempio al caso più complesso riguardante la costruzione dei libretti dei ferri…

Naturalmente, potremo preparare report molto più professionali che non un semplice output in console, per esempio compilando un opportuno sorgente LaTeX per l’uscita in PDF, direttamente con le funzioni Lua di reporting.

Uno svantaggio consiste nella necessità di scrivere qualche linea di codice Lua, ma del resto questo consente la massima libertà di cucire la soluzione sul problema e non è poi così terribilmente difficile. A voi dunque l’onore e l’onere di rendere un po’ più attraente la stesura dei computi metrici!

Note tecniche

Il software occorrente per utilizzare la procedura è il seguente: un editor di testi, consiglio SciTE perché in grado di far eseguire il codice premendo semplicemente il tasto F5, e l’interprete Lua, quindi tutto software libero, gratuito e legalmente installabile anche in ambito professionale, infine un pizzico di fantasia.
Per imparare Lua non vi è niente di meglio del PiL.
Un saluto.

Una risposta a “Il computo metrico con Lua

  1. Pingback:Visto nel Web – 3 « Ok, panico

Lascia un commento

Inserisci i tuoi dati qui sotto o clicca su un'icona per effettuare l'accesso:

Logo WordPress.com

Stai commentando usando il tuo account WordPress.com. Chiudi sessione / Modifica )

Foto Twitter

Stai commentando usando il tuo account Twitter. Chiudi sessione / Modifica )

Foto di Facebook

Stai commentando usando il tuo account Facebook. Chiudi sessione / Modifica )

Google+ photo

Stai commentando usando il tuo account Google+. Chiudi sessione / Modifica )

Connessione a %s...

%d blogger cliccano Mi Piace per questo: