Commit 072e6200 authored by Bernardo Quaresma Dias's avatar Bernardo Quaresma Dias
Browse files

Inclusão de versão 1_10 de lib-list

INSTMPA-1339
parent a1ca7860
func{ id = "minimo", name = "Calcular Mínimo de Lista",
description = [[
Função que recebe lista de valores reais e retorna o mínimo desses valores.
Se o pârametro for positivo, as N primeiras amostras serão consideradas;
Se o parâmetro for negativo, as N últimas amostras serão consideradas na média;
Caso o parâmetro seja nulo, todas as amostras serão consideradas.
Se o valor absoluto de N for maior que o número de elementos da lista, todos os elementos serão considerados.
Se for uma lista vazia, a função retornará nil.
]],
parameters = {
{name = "Lista", type = "REAL[]" },
{name = "N", type = "INTEGER" },
},
results = {
{name = "Mínimo", type = "REAL" },
{name = "Primeiro", type = "INTEGER" },
{name = "Último", type = "INTEGER" },
},
code = [===[ function (l, n)
local first, last = 1, #l
if n ~= nil then
if n > 0 then
last = math.min(last, n)
elseif n < 0 then
first = math.max(first, 1 + last + n)
end
end
local value = l[first]
for i = first+1, last do
value = math.min(value, l[i])
end
return value, first, last
end ]===],
}
func{ id = "maximo", name = "Calcular Máximo de Lista",
description = [[
Função que recebe lista de valores reais e retorna o máximo desses valores.
Se o pârametro for positivo, as N primeiras amostras serão consideradas;
Se o parâmetro for negativo, as N últimas amostras serão consideradas na média;
Caso o parâmetro seja nulo, todas as amostras serão consideradas.
Se o valor absoluto de N for maior que o número de elementos da lista, todos os elementos serão considerados.
Se for uma lista vazia, a função retornará nil.
]],
parameters = {
{name = "Lista", type = "REAL[]" },
{name = "N", type = "INTEGER" },
},
results = {
{name = "Máximo", type = "REAL" },
{name = "Primeiro", type = "INTEGER" },
{name = "Último", type = "INTEGER" },
},
code = [===[ function (l, n)
local first, last = 1, #l
if n ~= nil then
if n > 0 then
last = math.min(last, n)
elseif n < 0 then
first = math.max(first, 1 + last + n)
end
end
local value = l[first]
for i = first+1, last do
value = math.max(value, l[i])
end
return value, first, last
end ]===],
}
func{ id = "sum", name = "Calcular Somatório de Lista",
description = [[
Função que recebe lista de valores reais e retorna o somatório desses valores.
Se o pârametro for positivo, as N primeiras amostras serão consideradas;
Se o parâmetro for negativo, as N últimas amostras serão consideradas na média;
Caso o parâmetro seja nulo, todas as amostras serão consideradas.
Se o valor absoluto de N for maior que o número de elementos da lista, todos os elementos serão considerados.
]],
parameters = {
{name = "Lista", type = "REAL[]" },
{name = "N", type = "INTEGER" },
},
results = {
{name = "Somatório", type = "REAL" },
{name = "Primeiro", type = "INTEGER" },
{name = "Último", type = "INTEGER" },
},
code = [===[ function (l, n)
local first, last = 1, #l
if n ~= nil then
if n > 0 then
last = math.min(last, n)
elseif n < 0 then
first = math.max(first, 1 + last + n)
end
end
local value = 0
for i = first, last do
value = value + l[i]
end
return value, first, last
end ]===],
}
func{ id = "average", name = "Calcular Média de Lista",
description = [[
Função que recebe lista de valores reais e retorna a média desses valores de acordo com parâmetro N.
Se o pârametro for positivo, as N primeiras amostras serão consideradas;
Se o parâmetro for negativo, as N últimas amostras serão consideradas na média;
Caso o parâmetro seja nulo, todas as amostras serão consideradas.
Se o valor absoluto de N for maior que o número de elementos da lista, todos os elementos serão considerados.
Se for uma lista vazia, a função retornará nil.
]],
parameters = {
{name = "Lista", type = "REAL[]" },
{name = "N", type = "INTEGER" },
},
results = {
{name = "Média", type = "REAL" },
{name = "Primeiro", type = "INTEGER" },
{name = "Último", type = "INTEGER" },
},
code = [===[ function (l, n)
local total, first, last = sum(l, n)
local size = last - first + 1
if size == 0 then
return nil, first, last
end
return total / size, first, last
end ]===],
}
func{ id = "devsq", name = "Calcular Desvio Padrão de Lista",
description = [[
Função que recebe lista de valores reais, calcula a média e retorna o desvio padrão para os valores.
Se o pârametro for positivo, as N primeiras amostras serão consideradas;
Se o parâmetro for negativo, as N últimas amostras serão consideradas na média;
Caso o parâmetro seja nulo, todas as amostras serão consideradas.
Se o valor absoluto de N for maior que o número de elementos da lista, todos os elementos serão considerados.
Se for um lista vazia, a função retornará nil.
]],
parameters = {
{name = "Lista", type = "REAL[]" },
{name = "N", type = "INTEGER" },
},
results = {
{name = "Desvio Padrão", type = "REAL" },
{name = "Média", type = "REAL" },
},
code = [===[ function (l, n)
local avg, first, last = average(l, n)
if avg == nil then
return nil, nil
end
local value = 0
for i = first, last do
value = value + (l[i] - avg) ^ 2
end
local size = last - first + 1
return math.sqrt(value/size), avg
end ]===],
}
func{ id = "covar", name = "Calcular Co-Variância de Lista",
description = [[
Função que recebe duas listas de valores reais, e calcula a co-variância entre os valores.
Se as listas forem vazias, a função retornará nil.
]],
parameters = {
{ name = "Lista 1", type = "REAL[]" },
{ name = "Lista 2", type = "REAL[]" },
},
results = { {name = "Desvio Padrão", type = "REAL" }, },
code = [===[ function (l1, l2)
assert(#l1 == #l2,"lists need to have the same number of elements")
local n = #l1
if n == 0 then
return nil
end
local m1 = average(l1)
local m2 = average(l2)
local c = 0
for i = 1, n do
c = c + (l1[i] - m1) * (l2[i] - m2)
end
return c / n
end ]===],
}
func{ id = "slope", name = "Calcular Slope de Lista",
description = [[
Função que recebe duas listas de valores reais, e calcula a co-variância entre os valores.
Se as listas forem vazias, a função retornará nil.
]],
parameters = { {name = "Lista 1", type = "REAL[]" }, {name = "Lista 2", type = "REAL[]" }, },
results = { {name = "Slope", type = "REAL" }, },
code = [===[ function (l1, l2)
local covar_12 = covar(l1,l2)
if covar_12 == nil then
return nil
end
local l1_n = #l1
local dpl2 = devsq(l2)
if dpl2 == nil then
return nil
end
local q = dpl2/l1_n
if q == 0 then
return 0
end
return covar_12/q
end ]===],
}
func{ id = "mediana", name = "Calcular Mediana de Lista",
description = [[
Calcula a mediana de uma lista de valores.
Se a lista for vazia, a função retornará nil.
]],
parameters = {
{ name = "Valores", type = "REAL[]" },
},
results = {
{ name = "Mediana", type = "REAL" },
},
code = [===[ function(l)
local size = #l
if size == 0 then
return nil
end
table.sort(l)
local m = size/2
if #l%2 == 0 then -- número par de elementos na lista
return (l[m] + l[m+1])/2
else
return l[math.floor(m)+1]
end
end ]===],
}
func{ id = "truncate", name = "Truncar Lista",
description = [[Retorna a lista ordenada sem os N maiores e menores valores.]],
parameters = {
{ name = "Valores", type = "REAL[]" },
{ name = "N", type = "INTEGER" },
},
results = {
{ name = "Lista Truncada", type = "REAL[]" },
},
code = [===[ function(l, n)
table.sort(l)
for i=1, n do
local last = #l
if last > 2 then
table.remove(l, last)
table.remove(l, 1)
end
end
return l
end ]===],
}
class{ id = "lista_persistente", name = "Lista Persistente", group = "Listas",
bases = {},
description = [[
Equipamento para armazenar uma lista de valores textuais em disco para que possam ser carregados em uma nova sessão.
A lista é carregada automaticamente ao inicilaizar a instância da classe e salva ao inserir ou remover um elemento.
]],
attributes = {
{ id = "limite_elementos", name = "Limite de Elementos", type = "INTEGER", access = "gs",
description = [[
Limite de elementos que podem ser inseridos na lista.
Se, ao inserir um novo elemento, esse limite seja excedido, os elementos são removidos a partir do início da lista até que esse valor seja respeitado.
]],
},
},
code = [====[
function _CLASS:load()
local val = loadfile(self._filename)
self._valores = val and val() or {}
end
function _CLASS:save()
os.remove(self._filename)
local file = io.open(self._filename, "w")
file:write("return {\n")
for i, elem in ipairs(self._valores) do
file:write(string.format("%q,\n",elem))
end
file:write("}\n")
file:close()
end
function _CLASS:init()
self._filename = tostring(self)..".lua"
self:load()
end
]====],
methods = {
{ id = "inserir", name = "Inserir",
description = [[
Insere um novo elemento no final da lista.
Os valores são armazenados como texto.
]],
parameters = {
{ name = "Novo Valor", type = "STRING" },
},
results = {
},
code = [===[ function(self, valor)
table.insert(self._valores, valor)
while self.limite_elementos and (#self._valores > math.max(0, self.limite_elementos) ) do
self:remover()
end
self:save()
end ]===],
},
{ id = "remover", name = "Remover",
description = [[
Remove o elemento na posição informada e retorna.
Se nenhuma posição for informada, o primeiro elemento da lista será removido.
]],
parameters = {
{ name = "Posição", type = "INTEGER" },
},
results = {
},
code = [===[ function(self, posicao)
local ret = table.remove(self._valores, posicao or 1)
self:save()
return ret
end ]===],
},
{ id = "informar", name = "Informar",
description = [[
Informa o valor de determinada posição da lista.
Se nenhuma posição for passada, indica o valor na última posição.
]],
parameters = {
{ name = "Posição", type = "INTEGER" },
},
results = {
{ name = "Valor", type = "STRING" },
},
code = [===[ function(self, posicao)
return self._valores[posicao or #self._valores]
end ]===],
},
{ id = "informar_tamanho", name = "Informar Tamanho",
description = [[Informa o tamanho da lista.]],
parameters = {
},
results = {
{ name = "Tamanho", type = "INTEGER" },
},
code = [===[ function(self)
return #self._valores
end ]===],
},
},
}
class{ id = "amostras", name = "Amostras", group = "Listas",
bases = {},
description = [[Classe que modela um conjunto de amostras de uma variável de processo.]],
attributes = {
{ id = "intervalo_min", name ="Intervalo Mínimo", type = "REAL", access ="",
description = [[
Intervalo mínimo entre amostras.
Se um intervalo não for configurado, toda amostra será considerada.
]],
},
{ id = "validade", name ="Validade", type = "REAL", access ="",
description = [[Validade em segundos de uma amostra inserida na lista.]],
},
},
code = [====[
function _CLASS:init()
self._samples = {}
end
]====],
methods = {
{ id = "iniciar", name ="Iniciar",
description = [[Apaga a lista de amostas inseridas.]],
parameters = {
},
results = {
},
code = [===[ function(self)
self:init()
end ]===],
},
{ id = "inserir", name ="Inserir",
description = [[Insere elemento na lista de amostras com o valor informado.]],
parameters = {
{ name = "Valor", type = "REAL" },
},
results = {
},
code = [===[ function(self, v)
local t_atual = time()
local amostras = self._samples
local t_ultima = amostras[1] and amostras[1].tempo
if (not t_ultima) or (t_atual - t_ultima >= (self.intervalo_min or 0) ) then
local amostra = {
valor = v,
tempo = t_atual
}
table.insert(amostras, 1, amostra)
end
self:atualizar()
end ]===],
},
{ id = "atualizar", name ="Atualizar",
description = [[Atualiza amostras removendo vencidas da lista.]],
parameters = {
},
results = {
},
code = [===[ function(self)
if self.validade then
local t_limite = time() - self.validade - (self.intervalo_min or 0)/2
local amostras = self._samples
while amostras[#amostras] and (amostras[#amostras].tempo < t_limite) do
table.remove(amostras)
end
end
end ]===],
},
{ id = "validar", name ="Validar",
description = [[
Informa se o tempo da última amostra é maior que a validade configurada
ou que o período de tempo passado por parâmetro.
]],
parameters = {
{ name = "Tempo", type = "REAL" },
},
results = {
{ name = "Válido", type = "BOOLEAN" },
},
code = [===[ function(self, t)
if self:vazia() then
return false
else
local amostras = self._samples
-- se não tem validade configurada, é considerada válida
local validade = (t or self.validade)
if not validade then
return true
else
local t_limite = time() - validade + (self.intervalo_min or 0)/2
return amostras[#amostras].tempo < t_limite
end
end
end ]===],
},
{ id = "vazia", name ="Vazia",
description = [[Informa se a lista de amostras está vazia.]],
parameters = {
},
results = {
{ name = "Vazia", type = "BOOLEAN" },
},
code = [===[ function(self)
self:atualizar()
return self._samples[1] == nil
end ]===],
},
{ id = "obter_historico", name ="Obter Histórico",
description = [[
Obtém o histórico de valores de amostras pelo período de tempo passado por parâmetro.
Se o parâmetro tempo for positivo, o histórico se refere ao período mais recente.
Se o parâmetro tempo for negativo, o histórico se refere ao período mais antigo.
Se um parâmetro tempo não for informado, todas as amostras serão incluídas no histórico.
]],
parameters = {
{ name = "Tempo", type = "REAL" },
},
results = {
{ name = "Histórico", type = "REAL[]" },
},
code = [===[ function(self, t)
local historico = {}
if not self:vazia() then
local t_newest = self._samples[1].tempo
local t_oldest = self._samples[#self._samples].tempo
local t_init = t_oldest
local t_end = t_newest
if type(t) == "number" then
if t < 0 then
t_end = t_init - t
else
t_init = t_end - t
end
end
for a, amostra in ipairs(self._samples) do
local t_amostra = amostra.tempo
if t_amostra <= t_end then
if t_amostra < t_init then
break
end
historico[#historico+1] = amostra.valor -- [[DEBUG]] print("[DEBUG]",t,t_oldest,t_init,t_end,t_newest)
end
end
end
return historico
end ]===],
},
},
}
class{ id = "lista_indexada", name = "Lista Indexada", group = "Listas",
bases = {},
description = [[Classe que modela uma lista de valores indexada por índices crescentes.
Os índices não precisam ser sequenciais, nesses casos o índice anterior ou inicial é informado.]],
attributes = {
{ id = "indices", name = "Indices", type = "REAL[]", access = "",
description = [[Lista de Indices]],
},
{ id = "valores", name = "Valores", type = "REAL[]", access = "",
description = [[Lista de Valores indexados]],
},
},
methods = {
{ id = "obter_valor", name = "Obter Valor",
description = [[Retornar o valor correspondente ao índice informado.]],
parameters = {
{ name = "Valor do Indice", type = "REAL" },
},
results = {
{ name = "Resultado", type = "REAL" },
},
code = [===[ function(self, indice)
local indices = self.indices --[[ASSERT]] assert(indices and (#indices > 0), "lista de indices indefinida ou vazia")
local valores = self.valores --[[ASSERT]] assert(valores and (#valores > 0), "lista de valores indefinida ou vazia")
local i = 1
while indices[i] and indices[i] <= indice do
i = i+1
end
return valores[math.max(1, i-1)]
end ]===],
},
},
}
class{ id = "lista_enumerada", name = "Lista Enumerada", group = "Listas",
bases = {},
description = [[
Lista de valores indexada por índices números que indicam a posição do item na sequência.
]],
code = [====[
function _CLASS:init()
local valores = self.valores --[[ASSERT]] assert(valores and (#valores > 0), ("%s: lista de valores indefinida ou vazia"):format(self) )
self._map = {}
for i, valor in ipairs(valores) do
self._map[valor] = i
end
end
]====],
attributes = {
{ id = "valores", name = "Valores", type = "STRING[]", access = "",
description = [[Lista de Valores.]],
},
},
methods = {
{ id = "obter_indice", name = "Obter Índice",
description = [[Retornar o valor correspondente ao índice informado.]],
parameters = {
{ name = "Valor", type = "STRING" },
},
results = {
{ name = "Índice", type = "INTEGER" },
},
code = [===[ function(self, valor)
local valor_txt = tostring(valor)
local indice = self._map[valor_txt] --[[ASSERT]] assert(indice, ("%s: Valor '%s' não foi encontrado na lista."):format(tostring(self), valor_txt) )
return indice
end ]===],
},
{ id = "obter_valor", name = "Obter Valor",
description = [[Retornar o valor correspondente ao índice informado.]],
parameters = {
{ name = "Índice", type = "INTEGER" },
},
results = {
{ name = "Valor", type = "STRING" },
},
code = [===[ function(self, indice)
return self.valores[indice]
end ]===],
},
},
}
class{ id = "lista_rotulada", name = "Lista Rotulada", group = "Listas",
bases = {},
description = [[
Lista de valores indexada por rótulos que indicam a posição do item.
O número de rótulos deve coincidir com o número de valores.
]],
code = [====[
function _CLASS:init()
local rotulos = self.rotulos
local rotulos_n = rotulos and #rotulos --[[ASSERT]] assert(rotulos_n and (rotulos_n > 0), ("%s: lista de rótulos indefinida ou vazia."):format(self) )
local valores = self.valores
local valores_n = rotulos and #valores --[[ASSERT]] assert(valores_n and (valores_n > 0), ("%s: lista de valores indefinida ou vazia."):format(self) )
--[[ASSERT]] assert(rotulos_n == valores_n, ("%s: número de itens na lista de rótulos (%d) diferente da lista de valores (%d)."):format(tostring(self), rotulos_n, valores_n) )
self._map = {}
for i, rotulo in ipairs(rotulos) do
self._map[rotulo] = valores[i]
end
end
]====],
attributes = {
{ id = "rotulos", name = "Rótulos", type = "STRING[]", access = "",
description = [[Lista de Rótulos.]],
},
{ id = "valores", name = "Valores", type = "REAL[]", access = "",
description = [[Lista de Valores.]],
},
},
methods = {
{ id = "obter_valor", name = "Obter Valor",