Lua – Linguagem de Programação – Parte 8

Introdução

Este artigo trata o uso de operações de aleatoriedade e a manipulação de cadeias (operações de detecção de tamanho de cadeias – revisão, repetição de caracteres, separação de cadeias, busca e substituição de caracteres, conversão em modo ASCII).

Aleatoriedade

É sabido que aleatoriedade é a característica do que é indeterminado ou incerto. Uma das possibilidades operativas de uma linguagem de programação é a capacidade de “gerar” valores numéricos aleatórios. O termo: gerar é grafado entre aspas devido a característica que os computadores possuem de fazer este trabalho de uma forma considerada não real, ou seja, por meio de uma acção considerada pseudo-aleatória. Para esta acção em linguagem Lua há as funções de geração de números aleatórios: math.randomseed() e math.rendom(). Os valores gerados por estas funções são valores pseudo-aleatórios, e necessitam ser usados com alguma cautela, tanto que há no manual de referência da linguagem Lua a advertência: Nenhuma garantia pode ser dada para suas propriedades estatísticas.

A função math.randomseed(n) faz uso do valor n como parâmetro de semente para a geração de valores aleatórios. A função math.random([n[,m]]) pode ser usada de três formas diferentes: usada sem parâmetros o que fará a geração de valores entre 0 e 1 , pode ser usada apenas com o parâmetro n para gerar valores inteiros entre 1 e o valor estabelecido junto a parâmetro n e pode ainda ser usada com os parâmetros n e m para gerar valores inteiros entre n e m. O programa seguinte efectua a acção de geração de valores aleatórios da forma mais simples possível.

-- inicio do programa ALEAT01
math.randomseed(0)
local function SORTEIO()
N = math.random()
return N
end
for I = 1, 5 do
X = SORTEIO()
print(X)
end
-- fim do programa ALEAT01

Em seguida escreva o código de programa em um editor de texto, gravando-o com o nome aleat01.lua e execute-o com a linha de comando lua 5.1 aleat01.lua. A função math.randomseed() necessita ser usada a frente da função math.random() para que math.random() consiga gerar os valores aleatórios. Ao executar o programa várias vezes os valores apresentados como saída sempre serão: 0.0011597033600879, 0.23557237464522, 0.64815210425123, 0.074373607593005, 0.27024140140996. Os valores se repetem pelo fato de estar sendo utilizado o valor de semente 0 (zero). Se o valor de semente for mudado para 1, 2, 3 ou outro valor qualquer serão conseguidos valores diferentes. No entanto para um mesmo valor de semente para mais de uma execução ter-se-á a apresentação dos mesmos valores. Uma forma de mudar um pouco este comportamento é fazer uso da função os.time() como valor de semente. A função os.time() retorna o valor do tempo corrente. Assim sendo, observe o código de programa seguinte:

-- inicio do programa ALEAT02
math.randomseed(os.time())
local function SORTEIO()
N = math.random()
return N
end
for I = 1, 5 do
X = SORTEIO()
print(X)
end
-- fim do programa ALEAT02

Em seguida escreva o código de programa em um editor de texto, gravando-o com o nome aleat02.lua e execute-o com a linha de comando lua 5.1 aleat02.lua. Ao se executar o programa várias vezes notar-se-á que os resultados apresentados são levemente diferentes. Por exemplo, a seguir apresenta-se os valores de saída de duas execuções sequenciais do programa:

0.85509811700797, 0.76201666310617, 0.21799371318705, 0.17670216986602, 0.24967192602313, 0.85558641315958, 0.40208136234626, 0.94387646107364, 0.84850611896115, 0.82357249671926.

Observe que uso da função os.time() como valor semente permite um comportamento de aleatoriedade mais convincente. Agora imagine que se queira sortear valores numéricos entre 1 e 5. Assim sendo, observe o código seguinte:

-- inicio do programa ALEAT03
math.randomseed(os.time())
local function SORTEIO()
N = math.random(1,5)
return N
end
for I = 1, 5 do
X = SORTEIO()
print(X)
end
-- fim do programa ALEAT03

Em seguida escreva o código de programa em um editor de texto, gravando-o com o nome aleat03.lua e execute-o com a linha de comando lua 5.1 aleat03.lua. Execute o programa algumas vezes. Note que o primeiro valor é sempre o mesmo em toda a execução, somente os demais valores são apresentados diferentemente. Este é um comportamento operativo da linguagem Lua que gera dúvidas nos iniciantes no uso desta linguagem. Não se preocupe em seguida será mostrado como contornar este tipo de ocorrência. Observe que para gerar valores entre 1 e 5 fora usado: N = math.random(1 ,5). O próximo programa mostra como contornar o problema de repetição do primeiro valor da sequência sorteada.

-- inicio do programa ALEAT04
math.randomseed(os.time())
math.random()
local function SORTEIO()
return N
end
for I = 1, 5 do
X = SORTEIO()
print(X)
end
-- fim do programa ALEAT04

Em seguida escreva o código de programa em um editor de texto, gravando-o com o nome aleat04.lua e execute-o com a linha de comando lua 5.1 aleat04.lua. Execute o programa algumas vezes e note a diferença nesta versão. Observe o uso da função math.random() logo após o uso da função math.randomseed(os.time()). Este pequeno ajuste faz o acerto desejado.

Mais Manipulação de cadeias

No sexto artigo desta série fora apresentada uma forma de detecção da quantidade de caracteres de uma cadeia com o uso do operador # por meio da instrução de código print(#"Linguagem Lua") que mostra como resultado o valor 13. Esta mesma acção pode ser efectuada por meio da função string.len(texto) como apresentado no quinto artigo desta série, onde texto é a indicação da cadeia que terá contada a quantidade de caracteres. Em seguida escreva o código de programa em um editor de texto, gravando-o com o nome cadeia01.lua e execute-o com a linha de comando lua 5.1 cadeia01.lua.

-- inicio do programa CADEIA01
X = "Linguagem Lua"
print(string.len(X))
-- fim do programa CADEIA01

Nas operações de manipulação de cadeias há ainda a possibilidade de separar partes de uma cadeia. Para este efeito faz-se uso da função string.sub(texto, início, [fim]), onde texto é a indicação da cadeia que será separada, início é a indicação da posição de separação inicial que pode ser positiva ou negativa e fim – indicação opcional da posição final de separação. Em seguida escreva o código de programa em um editor de texto, gravando-o com o nome cadeia02.lua e execute-o com a linha de comando lua 5.1 cadeia02.lua.

-- inicio do programa CADEIA02
X = "COMPUTADOR"
print(string.sub(X))
print(string.sub(X, 1))
print(string.sub(X, 1, 3))
print(string.sub(X, 4, 5))
print(string.sub(X, 6, 7))
print(string.sub(X, 8))
print(string.sub(X, -5))
-- fim do programa CADEIA02

Após a execução serão apresentados os textos COMPUTADOR, COM, PU, TA, DOR e TADOR. Outro factor de manipulação de cadeias de caracteres é a realização de operações de substituição de caracteres de uma cadeia. Para tanto, use a função de substituição string.gsub(texto, busca, troca, vezes), onde texto é a cadeia de texto definida, busca é o carácter a ser localizado, troca é o carácter que será substituído e vezes indica o número máximo de substituições a serem efectuadas, sendo este último argumento opcional. Em seguida escreva o código de programa em um editor de texto, gravando-o com o nome cadeia03.lua e execute-o com a linha de comando lua 5.1 cadeia03.lua.

-- inicio do programa CADEIA03
X = "A BOLA AZUL APARECEU"
print(string.gsub(X,"A","4"))
print(string.gsub(X,"A","X",2))
-- fim do programa CADEIA03

Observe que após a execução, o programa mostra além da troca realizada o número de trocas realizadas. Outra acção para manipulação de cadeias é a função string.rep(texto, vezes), onde texto é a cadeia a ser repetida e vezes é a definição do número de repetições. Em seguida escreva o código de programa em um editor de texto, gravando-o com o nome cadeia04.lua e execute-o com a linha de comando lua 5.1 cadeia04.lua.

-- inicio do programa CADEIA04
X = "OBA "
print(string.rep(X,2))
-- fim do programa CADEIA04

Outro efeito com cadeias é a obtenção do código ASCII dos caracteres que formam a cadeia com a função string.byte(texto, início, [fim]), onde texto é a indicação da cadeia que terá seus caracteres convertidos em formato ASCII, início é a indicação da posição de separação inicial que pode ser positiva ou negativa e fim – indicação opcional da posição final de separação. Em seguida escreva o código de programa em um editor de texto, gravando-o com o nome cadeia05.lua e execute-o com a linha de comando lua 5.1 cadeia05.lua.

-- inicio do programa CADEIA05
X = "ABCDEF"
print(string.byte(X, 1))
print(string.byte(X, 1, 3))
print(string.byte(X, 4, 5))
print(string.byte(X, 1, 6))
print(string.byte(X, -5))
-- fim do programa CADEIA05

O programa apresenta os valores:

65
65 66 67
68 69
65 66 67 68 69 70
66

A acção inversa é conseguida com o uso da função string.char(código1 , código2, …, códigoN), onde cada argumento usado é um valor ASCII. Em seguida escreva o código de programa em um editor de texto, gravando-o com o nome cadeia06.lua e execute-o com a linha de comando lua 5.1 cadeia06.lua.

-- inicio do programa CADEIA06
print(string.char(65))
print(string.char(65, 66, 67))
-- fim do programa CADEIA06

Conclusão

Neste artigo o enfoque foi o uso dos recursos de geração de valores aleatórios e alguns detalhes sobre a manipulação de cadeias. No próximo artigo a ênfase será dada a criação e uso de módulos em linguagem Lua.

Publicado na edição 28 (PDF) da Revista PROGRAMAR.