2007-03-30

Desabafo II

Baal Recentemente um internauta postou um comentário dizendo que eu e o Walter deveríamos esclarecer nossos critérios.

Então respondi dizendo que nós não devemos nada. O resultado foi que um nerd postou um comentário na lista de Lisp se mostrando ofendido quanto a meu comentário.

Quero aqui em meu espaço pessoal de comunicação com o mundo, as Reflexões de Monte Gasppa e Giulia C., então esclarecer algumas coisas.

Se eu achar que estou errado, vou me retratar, mas não vou pedir desculpas nem voltar atrás em nada que eu disser só porque algum nerdzinho mariquinhas se sentiu ofendido.

Não devo nada a ninguém. Se alguém quiser falar de dever, aqui segue o que considero dever:

  • meu dever cívico;
  • meu dever para com minha família;
  • meu dever com meus contratos (pelos quais sou pago);
  • meu dever de saldar minhas dívidas;
  • meu dever para comigo mesmo e meus princípios.


Isso é dever.

Se você é algum nerd infalível, dono absoluto da verdade, que sofre de síndrome do pânico e desconta suas frustrações na Internet, não tem nada pra você aqui.

Não estou aqui para fazer trollagem, mas também não estou aqui para ficar de quatro, satisfazendo as vontades de pessoas que se ofendem com quem não se curva diante de suas ideias.

Isso aqui não é uma democracia e não devo nada a ninguém – a menos que me pague por algum serviço, aí passo a dever o serviço pago e nada mais.

Agora assim vou pedir desculpas

Quero pedir desculpas àqueles que não precisavam estar lendo esta bronca, este desabafo. Sei que a maioria das pessoas que navegam pela Internet, leem o RSS, etc., são conscientes, entendem como as coisas funcionam.

Mas existe uma minoria de pessoas com problemas sociais que veem na Internet uma fuga, a bronca é para esses. Desculpem-me os inoscentes.

[]'s

2007-03-26

Usando SQL com Lua

Lua Já há bastante tempo existe em programação a ideia de separar os dados da lógica do programa e, quando queremos poder fazer consultas estruturadas, bancos de dados relacionais são ótimos.

Primeiro as consultas eram feitas usando um pré-processamento que lia códigos estranhos à linguagem inseridos entre marcações de início e fim, mais ou menos assim:

EXEC SQL
DECLARE CUR CURSOR FOR
SELECT * FROM cadastro
WHERE grupo = 1
END-EXEC.


Mas era necessário rodar o pré-compilador, que substituía esses trechos por códigos mais complexos, o que era no mínimo desconfortável.

Mais tarde pensaram em fazer diferente: módulos com funções que recebem strings representando os comandos SQL (Structured Query Language) e os executam, «escondendo» assim toda complexidade do acesso sem necessidade de uma pré-compilação.

Outras sintaxes para acesso, também abstraindo a complexidade, foram desenvolvidas, como SQLObject e SQLAlchemy, mas nenhuma tão simples e popular quanto a simples passagem de uma string como parâmetro de uma função.

Por exemplo, em Python, temos o módulo MySQLdb:
import MySQLdb as mysql

conn = mysql.connect(
host="localhost",
user="batalema",
password="sEnH4",
db="empresa"
)

conn.query("""
SELECT * FROM cadastro WHERE grupo = 1
""")
cur = conn.use_result()


A conexão deve ser fechada com conn.close(). Os resultados de uma consulta são lidos com um tipo especial de reiterador chamado cursor. Isso permite que tabelas de centenas (ou milhares) de linhas (tuplas) sejam tratadas com muito pouco uso de memória. Já escrevi alguns artigos sobre o assunto.

LuaSQL


Seguindo o exemplo de Python, PHP e outras linguagens, Lua também envia os comandos SQL por meio de strings como parâmetros de funções para uma conexão e percorre os resultados com um cursor.

O módulo de Lua para acesso a SQL é LuaSQL, que é parte do projeto Kepler, uma plataforma para desenvolvimento web usando Lua. Por isso é recomendável instalar tanto Lua quanto LuaSQL através da instalação completa de Kepler 1.1 – no momento em que este artigo foi escrito, só havia disponíveis snapshots (release-cadidates). Também é recomendável a instalação de todos os pacotes opcionais (--with-optional=lualogging,luasql,luaexpat,luazip,md5).

Podemos ver agora como fazer os acessos usando LuaSQL.

O módulo traz submódulos de acesso a diversos SGBDs diferentes: MySQL (luasql.mysql), Oracle (luasql.oci8), PostgreSQL (luasql.postgres), SQLite (luasql.sqlite) e MS SQL Server (via ODBC: luasql.odbc). Vamos usar o padrão, luasql.mysql.

Em LuaSQL, antes de conectar ao SGBD, é preciso criar um ambiente de conexão:
require "luasql.mysql"

local env = assert(luasql.mysql())


A partir do ambiente podemos iniciar a conexão:
local conn = assert(
env:connect(
"empresa",
"batalema",
"sEnH4",
"localhost"
)
)


A ordem dos parâmetros (para luasql.mysql e luasql.postgresql, para outros ambientes veja o manual) é:
  1. Fonte (nome da base de dados)
  2. Usuário
  3. Senha
  4. Servidor


Efetuada a conexão, podemos criar nosso cursor. Precisaremos ainda de uma tabela Lua para receber cada uma das linhas da tabela SQL, chamadas tuplas:
local cur = conn:execute [[
SELECT * FROM cadastro WHERE grupo = 1
]]
local t = {}


O cursor possui dois métodos interessantes, um é numrows(), que retorna o número de tuplas da seleção, outro é fetch(), que retorna a próxima tupla ou nil se estiver chegado ao final.

O método fetch() recebe dois parâmetros: ¹a tabela que receberá a tupla e ²uma string que indica como a tupla será interpretada pela tabela Lua.

Há duas opções para o 2º parâmetro:
  • "n": os registros serão recebidos como pares índice-valor e a tabela será uma tabela indexada;
  • "a": os registros serão recebidos como pares chave-valor e a tabela será uma tabela associativa.


Então, para listar os resultados podemos fazer algo bem simples:
while cur:fetch(t, "a") do
table.foreach(t, print)
end


Para finalizar precisamos fechar o cursor, a conexão e o ambiente:
cur:close()
conn:close()
env:close()


Outros comandos SQL


O comando SELECT retorna um cursor para a tabela retornada, mas outros comandos não retornam cursores ou tabelas.

Em vez disso os demais comandos retornam o número de tuplas afetadas.

Conclusão


Se alguém ficou decepcionado, desculpe-me a falta de complexidade… mas o módulo é simples mesmo. =P

Aliás, todos os módulos do projeto Kepler são simples.

Para um pouco mais de «complexidade» (hehehe), veja o manual.

[]'s

PS: Publicado também no Kodumaro.

2007-03-23

A beleza da blogsfera

Baal Provavelmente estou equivocado em muitas de minhas suposições, mas na condição de «apenas mais uma alma na multidão» tenho o direito de equivocar-me (e o dever de corrigir-me, claro).

Este não é um pedido de desculpas, apesar da introdução. Mantenho as posições expostas nas Reflexões de Monte Gasppa e Giulia C. (até que alguém me convença do contrário, afinal não sou inflexível).

Apenas estou usando a mim mesmo como exemplo do tópido desta postagem. Já toquei sutilmente neste assunto antes e agora quero explicitá-lo.

A beleza da blogsfera (neologismo originado do inglês blogsphere, que não é a ferramenta Blogsphere) está aqui: antes somente uns poucos tinham capacidade de expor suas opiniões, tornando-as assim automaticamente verídicas, por mais equivocadas que fossem. Agora, com a blogsfera, quase todo mundo – ou pelo menos os internautas – pode expor suas idéias.

Através de um prisma mais amplo, mais ângulos diferentes de visão, é possível formar uma idéia muito melhor sobre os fatos, libertando as pessoas – pelo menos as que têm acesso – da escravidão intelectual vigente.

As academias científicas escravizam o pensamento, determinando convenientemente o que pode ou não ser chamado «científico».

Por exemplo: Ufologia…

Ufologia geralmente representa a primeira pazada de terra sobre a cova onde o ufólogo jogou sua carreira. No entanto, estatisticamente falando é um campo plausível.

Não creio nem descreio na Ufologia, sou cético mas não contra. Apenas acho que o argumento acadêmico contra a Ufologia não é válido.

O argumento usado é o seguinte: toda ciência deve ter um objeto palpável de estudo. Então vamos esquecer a Psicologia.

Ou a Astronomia: alguém aí já manipulou uma estrela? Ou um planeta?

Outro argumento totalmente estúpido que muitos usam é: «a ausência de evidências é evidência de ausência».

Gente, isso é umas das coisas mais idiotas e ignorantes que alguém pode dizer!

Temos evidência de apenas umas poucas espécies viventes no período anterior a sessenta e cinco milhões de anos atrás, o que não significa que não houvesse outras espécies, apenas o «objeto de pesquisa» é fugaz.

São os mesmos argumentos usados contra o estudo da sobrevivência da alma à morte corporal.

Há ainda outro argumento mais cretino que os anteriores: «se algo pode ser fraudado, então é automaticamente uma fraude».

Então o World Trade Center não caiu! Está lá ainda e os nova-iorquinos estão mentido! Porque já vi muitas fotos fraudadas do evento.

O homem também nunca pisou na Lua, porque o evento pôde ser fraudado.

Percebem como o argumento é tendencioso?

Também as instituições religosas escravizam o pensamento, por meio de adestramento e mutilação de idéias.

Como conversamos eu e meu amigo Walter, toda instituição religiosa nasce da crença na infalibilidade de uma pessoa ou, na melhor das hipóteses, de um grupo de pessoas.

O poder das instituições religiosas é diferente do poder de uma empresa: em vez de investir financeiramente para manter o status quo, as instituições adestram o maior número possível de mentes e são elas que manterão o status quo, sem que a instituição religiosa gaste um centavo.

Adestramento de pensamento. Já parou para pensar se suas idéias são suas mesmo?

Claro, não podemos extremar: nossas idéias são fruto da interação de nossa essência com o contexto onde estamos inseridos. Mas até que ponto a sociedade nos afeta?

Tendo exposto todos esses fatores, volto ao assunto dizendo: como muitas pessoas podem expor seus pontos de vista na blogsfera, temos acesso a mais ângulos de visão e quanto mais diversos são, melhor podemos entender os fatos.

É a beleza da blogsfera! Liberdade intelectual.

Do caos surge alguma ordem, o princípio básico do Universo, entropia: entropia.

[]'s

2007-03-22

A Tumba

Joseph Smith Reencontraram o sepulcro de Jesus, em Talpiot, lacrado há vinte e cinco anos (ou foram vinte e sete?) pelas autoridades israelitas com o apoio da Igreja Católica.

Acredita-se que o Jesus enterrado na tumba seja Jesus Cristo devido a algumas coincidências: Jesus, filho de José e Maria de Nazaré, irmão de Tiago, casado com Mara Myriamne (estava em grego, mas a palavra mara em aramaico significa «mestra», e Myriamne é uma das muitas formas aramaicas de Maria) e pai de Judá. Os ossos de todas estas pessoas – e mais algumas, entre elas Mateus – estavam enterrados juntos (o ossuário de Tiago havia sido removido), num tipo de mausoléu de família, e ainda havia um ossuário de um amigo da família, um tal Simão Pedro (também havia sido removido para um monastério próximo). O túmulo é datado do século I da era cristã.

Estatisticamente, a probabilidade de todos estes nomes juntos não se referirem às pessoas bíblicas é de 1:600.000 (James Cameron foi bonzinho com a Igreja ao dizer 1:600), o que em Arqueologia é praticamente uma certeza.

Agora, temos um problema: a fé milenar cristã, em vez de apoiar (e apoiar-se em) os ensinamentos do Mestre («amar a Deus sobre todas as coisas e ao próximo como a si mesmo», e outras coisas similares), se sustentou no fato da ressurreição e da ascensão de corpo e alma de Jesus ao Céu (que aliás, por favor, alguém me mande a indicação de versículos da Bíblia onde está a ascensão, porque não estou encontrando), tornando-se assim uma fé frágil e superficial.

A simples possibilidade daqueles ossos serem mesmo de Jesus já é suficiente para que os católicos mais incrédulos se tornem agnósticos de vez e os mais crédulos e ignorantes se tornem pentecostais.

Mas os fiéis de bom senso (de quaisquer facções cristãs) questionarão…

O que quero expor aqui é o seguinte: a verdade sobre a coisa não aparecerá enquanto cientistas e religiosos se basearem naquilo que creem ser possível ou não.

O grande problema dos cientistas – os religiosos sofrem do mesmíssimo mal – é que em vez de avaliarem seus conceitos de «possível» e «impossível» segundo fatos e descobertas, eles valiam fatos e descobertas segundo seus conceitos de possível e impossível.

É a típica inversão de causalidade, detectada geralmente em crianças por volta dos cinco anos de idade, segundo Piaget – e também em cientistas e líderes religiosos: será que tem a haver com desenvolvimento emocional?

Não quero afirmar que aquele túmulo seja o túmulo de Jesus Cristo, nem que não seja, nem quero negar ou afirmar a ressurreição.

Segundo o que eu acredito (portanto é uma suposição minha), a ressurreição realmente ocorreu, mas não acredito na ascensão, nem que Jesus tenha sido solteiro.

E logicamente, se Jesus ficou na Terra e escolheu viver e morrer como os homens (duvido que morrer na cruz e ressucitar seja morrer como os homens), ele deve ter deixado ossos em algum lugar.

Deveríamos parar de defender crenças que não levam a nada (a ascensão de alguém não me faz melhor nem pior, é neutro e qualquer um pode manipular esse tipo de fé como quiser) e passar a dar valor ao que realmente importa – como já dizia o poeta, just give peace a chance.

[]'s

PS: Se sua fé é frágil, não tema: as autoridades israelitas mandaram lacrar a tumba de novo.

2007-03-17

Nota ZERO

Clodovil Hernandes Pois é, a gente não pode elogiar ninguém, senão acaba dando merda…

Segundo o Terra, Coldovil está sendo investigado por crime ambiental pelo Supremo Tribunal Federal.

No inquérito consta que «o parlamentar teria suprimido vegetação capoeira em estágio inicial no Parque Estadual da Serra do Mar, em Ubatuba (SP), aterrando o local por meio de terraplanagem a fim de construir uma rua».

Vamos à contagem: primeira nota 10, segunda nota ZERO, conceito -5, média final ZERO. =P

[]'s

PS: Referência: Verdade Absoluta.

2007-03-15

Fanatismo científico

Baal Fazendo uma análise fria do que é fanatismo, podemos perceber que não há apenas o fanatismo religioso.

Fanatismo é o exagero de determinado pensamento ou doutrina, que leva o fanático a rejeitar sistematicamente tudo o que contradiz sua crença e – às vezes – a aceitar automaticamente qualquer coisa que a reafirme.

Na verdade o fanatismo é apenas um mecanismo de proteção do ego usado por pessoas que se consideram infalíveis: elas encontram algum sistema que confirme suas convicções, o adotam e defendem a ferro e fogo.

Geralmente consideramos fanáticos somente religiosos extremistas, mas há um grupo de fanáticos ainda mais perigoso: os fanáticos científicos.

Tais fanáticos aproveitam a ciência para justificar e endossar suas crenças. O fanático científico usa a expressão «cientificamente falando» da mesma forma como o fanático religioso usa «na Bíblia diz», ou seja, querendo dizer que, segundo suas crenças pessoais, a afirmação associada é incontestável.

Mas o pior não é crer que a afirmação seja incontestável… o pior é que ele acredita que tem de ser incontestável para os outros… acreditar que a expressão «cientificamente falando» (assim como seu equivalente religioso) lhe dá autoridade sobre as crenças pessoais alheias!

Veja bem: comprovar algo cientificamente não significa garantir que seja verdade, mas garantir que não contradiga outras verdades científicas aceitas. Toda metodologia sobre o assunto tem o único objetivo real de proteger o status quo vigente.

Ciência não é necessariamente realidade. É a apenas um ponto de vista – que aliás de tempos em tempos se mostra equivocado e precisa ser revisto.

Na comunidade científica clássica falta muito mais bom senso do que em muitas comunidades religiosas.

[]'s

2007-03-14

Uma ou duas palavras sobre a Wikipédia

Wikipédia Antes do advento da web – e de iniciativas como a Wikipédia – o Conhecimento era controlado por um seleto grupo de mercadores culturais que decidiam arbitrariamente qual versão dos fatos seria aceita.

Donos da verdade, durante algum tempo tiveram poder inclusive sobre a Lei, manipulando o Conhecimento para usá-la segundo seus interesses.

Não mais.

Com a Wikipédia as pessoas comuns – ou nem tão comuns assim, os internautas – tiraram o poder de manipulação desses senhores.

Claro, há prós e contras…

Qualquer néscio pode escrever um artigo sobre um assunto que não conhece como se tivesse propriedade sobre o assunto. Qualquer fanático pode defender seu ponto de vista, não importando o quanto esteja longe da verdade.

Por exemplo, outro dia estava lendo um texto que chamava de «cientista imparcial vítima de preconceito» um sujeito que nega sistematicamente a existência de tudo aquilo que não entende. Onde isso é imparcialidade?

Mas essa é a beleza da coisa: você tem acesso não apenas à versão acadêmica, oficial, que pode muito bem estar distorcida (como geralmente ocorre), mas também a opiniões de pessoas que veem o assunto de outros ângulos.

Algumas pessoas não concordam e creem que o Conhecimento deveria continuar sendo ferramenta nas mãos de poucos manipuladores interesseiros. Em algum ponto elas estão corretas, pois algumas pessoas não sabem pesquisar informações – ou, em outras palavras, acreditam em tudo que leem.

Se está escrito, é verdade. =P

Mas esse tipo de pensamento é fruto de séculos de ignorância controlada pelos senhores do Conhecimento. Fomos adestrados a acreditar, não a pensar.

Agora é hora de aprender a pensar.

[]'s

2007-03-13

Bush… why not?

Bush Estava vendo algumas notícias sobre a visita do Bush (sabe como se pronuncia bush em francês?) e vi numa entrevista uma moça defender acordos com os E.U.A. dizendo «Bush… why not?».

Desconsiderando a explícita demonstração de antinacionalismo e ianquismo fanático, gostaria de responder esse «why not?».

¹Primeiramente porque a idéia de acordo do Bush é unilateral: o Brasil passa pra eles a tecnologia e eles mantêm a sobretaxa que encarece o álcool brasileiro nos E.U.A.. Além do mais, eles mantêm o apoio fiscal e financeiro aos produtores de álcool de milho, barateando tanto seu álcool que torna a concorrência impossível.

²Em segundo lugar, porque o objetivo do Bush não é fazer amiguinhos, mas enfraquecer as alianças de Chávez, que, por mais maluco que pareça (ou realmente seja), está trazendo um sentimento de unidade para a América Latina.

³Por último, por conta do desprezo que o presidente ianque demonstra para com os sub-humanos latino-americanos, oferecendo cinco milhões de dólares para que nós, seres atrasados, possamos aprender a falar, digo, aprender inglês, abandonando nosso balbucear primitivo. =P

Os E.U.A. demonstram total desrespeito. Nem água daqui o cara tomou, mandou trazer de lá.

Se pensar bem vai ver que, no fundo, tudo o que ele quer é mais petróleo, digo, combustível. Ele quer uma Alca homeopática, que a gente não sinta.

Não é o momento de bajular o ômi. É tempo de crescer. Vejam a história da bateção de panela na Argentina, da migração de regime no Chile e nosso próprio fim do Regime Militar (que foi ainda mais destrutivo do que o regime em si)…

[]'s

PS: Referências:

2007-03-11

Números complexos em Lua II

Lua Este artigo foi publicado por mim originalmente em Reflexões de Monte Gasppa e Giulia C.. Esta é uma atualização para Lua 5.1.

Lua é uma poderosa linguagem de programação procedimental, orientada a objetos, de tipagem dinâmica, baseada em tabelas associativas e semântica extensível, projetada e implementada no Tecgraf, Grupo de Computação Gráfica da PUC-Rio, em 1993.

Foi projetada para ser uma linguagem de extensão, para que fosse possível que os usuários reconfigurassem aplicações sem necessidade de recompilação das aplicações.

Atualmente é a linguagem de script mais usada para programação de jogos (em segundo lugar está Python).

Uma curiosidade de Lua é não haver um módulo de suporte a números complexos. Vamos então implementar um.

Metatabelas


Em orientação a objetos, classe é um molde para a criação de objetos similares, chamados instâncias em relação à classe. Lua trabalha com um conceito ligeiramente diferente: metatabelas e metamétodos.

Em Lua tudo são tabelas, cujos elementos são quaisquer objetos de primeira ordem, inclusive funções (chamadas métodos ou metamétodos em classes) e outras tabelas.

Alguns métodos especiais, chamados metamétodos aritméticos, são usados para reagir a operações aritméticas. Há ainda os metamétodos comparativos – que reagem a operações de comparação – e os metamétodos de string.

Os metamétodos aritméticos, comparativos e de string são: __add() (adição), __sub() (subtração), __mul() (multiplicação), __div() (divisão), __pow() (potência), __unm() (inversão de sinal), __tostring() (conversão para string), __concat() (concatenação), __eq() (igualdade), __lt() (menor que) e __le() (menor ou igual).

Alguém pode perguntar «e quanto a ‘maior que’ e ‘maior ou igual’?». A resposta é simples, se a > b então b < a, capicci? A mesma idéia é para diferença (a ~= b é o mesmo que not a == b).

Está confuso até aqui? Vai clarear assim que começarmos a criar nossa metatabela. Vamos então à criação de nossa metatabela: primeiro usaremos o construtor de tabela ({}) para criar a metatabela com alguns valores default e em seguida criaremos o construtor próprio para números complexos:
local cmt = { real = 0, img = 1 }
cmt.__index = cmt
function cmt:new(o)
o = o or {}
return setmetatable(o, self)
end


Números complexos são formados por duas partes, uma real (ℜ) e outra imagem (ℑ), então criamos nossa metatabela assim.

A sintaxe function cmt:new(o) é um açúcar sintático para function cmt.new(self, o) e é usada para métodos.

O comando setmetatable(o, self) define que a metatabela de o será self (que representa mt) e o elemento __index informa de onde a tabela deve retirar os valores padrão (para elementos não definidos), e será a própria metatabela.

No entanto queremos ter alguma flexibilidade ao criar um número complexo:
  • e não for passado argumento, queremos que a função retorne j;
  • Se for passado um número (real), queremos retornar ele mesmo;
  • Se for passado um número complexo, queremos retornar uma cópia dele;
  • Se forem passados dois números (reais), queremos que o primeiro seja a parte real e que o segundo seja a imagem (se a imagem for zero, retorne somente a parte real).


Assim sendo, podemos criar a seguinte função:
function new(...)
if #{...} == 0 then
-- nenhum argumento retorna j
return cmt:new { real = 0, img = 1 }
elseif #{...} == 1 and type(select(1, ...)) == "number" then
-- um argumento: numero real
return select(1, ...)
elseif #{...} == 1 and getmetatable(select(1, ...)) == cmt then
-- um argumento: numero complexo
return cmt:new { real = select(1, ...).real, img = select(1, ...).img }
elseif #{...} == 2 and
type(select(1, ...)) == "number" and type(select(2, ...)) == "number" then
-- dois argumentos reais
if select(2, ...) == 0 then
return select(1, ...)
else
return cmt:new { real = select(1, ...), img = select(2, ...) }
end
else
error "parse error"
end
end


Mostrando nosso número complexo


O primeiro método que definiremos será para exibir nosso número complexo.

Sem este método, o comando abaixo retornaria assim:
lua> print(numero)
table: 0×80725e0


E queremos que, na verdade retorne algo do tipo:
lua> print(numero)
3 + 2j


Para tanto é preciso definir o método __tostring(). Mas não será tão fácil assim!

Imagine só: precisamos definir pelo menos oito casos diferentes:
  1. imagem = 0
  2. real = 0, imagem = 1
  3. real = 0, imagem = -1
  4. real ≠ 0, imagem = 1
  5. real ≠ 0, imagem = -1
  6. real = 0, imagem ≠ 0
  7. real ≠ 0, imagem > 0 e imagem ≠ 1
  8. real ≠ 0, imagem < 0 e imagem ≠ -1


Vamos então!
function cmt:__tostring()
local a, b = self.real, self.img
if b == 0 then
return tostring(a)
elseif b == 1 and a == 0 then
return "j"
elseif b == -1 and a == 0 then
return "-j"
elseif b == 1 and a ~= 0 then
return a .. " + j"
elseif b == -1 and a ~= 0 then
return a .. " - j"
elseif b ~= 0 and a == 0 then
return b .. "j"
elseif b > 0 and a ~= 0 then
return a .. " + " .. b .. "j"
elseif b < 0 and a ~= 0 then
return a .. " - " .. (-b) .. "j"
else
error "unexpected (a + bj) combination"
end
end


Uma funçãozinha útil


Para definir alguns parâmetros importantes precisamos definir o que acontece com o número quando tentamos invertê-lo (1 / (a + bj)).

A operação matemática é multiplicar a fração resultante por uma expressão equivalente a 1, como (a - bj) / (a - bj).

Fazendo esta continha simpática, obtemos real a / (a² + b²) e imagem -b / (a² + b²).

Vamos criar nossa função:
local function inv(v)
if getmetatable(v) ~= cmt then
return v ^ (-1)
else
local a, b, q = v.real, v.img
q = a ^ 2 + b ^ 2
return new(a / q, -b / q)
end
end


Nesta função, a primeira coisa que fizemos foi verificar se o argumento é um número complexo. Se não for, a função retorna um dividido pelo argumento. Se for um número complexo, realiza o cálculo citado.

Repare na linha:
local a, b, q = v.real, v.img


Neste comando, a, b e q são definidos como variáveis locais. a recebe v.real, b recebe v.img e q recebe nil.

Inversão de sinais


Se temos um número complexo b, queremos que -b retorne um número complexo com os sinais do real e da imagem invertidos:
function cmt:__unm()
return new(-self.real, -self.img)
end


Igualdade


Vamos verificar igualdade. Quando Lua verifica a == b, sendo a e b tabelas, na verdade está verificando se a e b são exatamente a mesma tabela, não se seus elementos são iguais. O quer queremos quando comparamos dois números complexos é se representam o mesmo valor, ou seja, se seus reais são iguais e se suas imagens também são.

Precisamos então criar um método para tratar isso:
function cmt:__eq(v)
if getmetatable(v) == cmt then
return self.real == v.real and self.img == v.img
else
return self.img == 0 and v == self.real
end
end


Operações binárias


Agora definiremos as operações binárias, ou seja, que necessitam de dois operandos: adição (+), subtração (-), multiplicação (*), divisão (/), potência (^) e concatenação (..).

Em todos os casos verificaremos se o segundo elemento da operação é também um número complexo ou não.

  • Adição

function cmt:__add(v)
local a1, b1, a2, b2, a3, b3 = self.real, self.img
if getmetatable(v) ~= cmt then
a2, b2 = v, 0
else
a2, b2 = v.real, v.img
end
a3, b3 = a1 + a2, b1 + b2
return new(a3, b3)
end


Na declaração das variáveis locais, a1 recebe self.real e b1 self.img. Todas as demais variáveis recebem nil.

  • Subtração (nada além de adição com sinal invertido)

function cmt:__sub(v)
return self + (-v)
end


  • Multiplicação (muito semelhante à adição)

function cmt:__mut(v)
local a1, b1, a2, b2, a3, b3 = self.real, self.img
if getmetatable(v) ~= cmt then
a2, b2 = v, 0
else
a2, b2 = v.real, v.img
end
a3, b3 = a1 * a2 – b1 * 2, a1 * b2 + a2 * b1
return new(a3, b3)
end


  • Divisão (divisão é a multiplicação onde o segundo termo é invertido)

function cmt:__div(v)
return self * inv(v)
end


  • Potência (aqui trataremos apenas expoentes inteiros, que não passam de multiplicações sucessivas)

function cmt:__pow(v)
if v == 0 then
-- expoente 0 retorna 1
return 1
elseif v == 1 then
-- expoente 1 retorna uma cópia de si mesmo
return new(self)
elseif v < 0 then
-- expoente negativo retorna inversão
return inv(self ^ (-v))
else
local aux, cont = new(self)
for cont = 2, v do
aux = self * aux
end
return aux
end
end


Repare a recursividade na linha:
return inv(self ^ (-v))


A potência chama novamente __pow() para self, mas desta vez com argumento -v.

  • Concatenação (fácil: retorna a contenação das strings!)

function cmt:__concat(v)
return tostring(self) .. tostring(v)
end


Vamos tornar isso tudo útil?


Até agora está tudo muito bonito, tratando números complexos e tudo mais… mas números complexos só são úteis se pudermos fazer duas coisas: ¹converter números reais em complexos quando tentamos extrair a raiz de um número negativo e ²converter números complexos para reais por meio das operações básicas.

Bem, a segunda coisa nosso módulo já faz, falta a primeira! Para tanto, vamos criar uma função de raiz quadrada segura, que retorne um número complexo quando a base for negativa:
function sqrt(v)
if type(v) ~= "number" then
error "value must be a number"
end
if v >= 0 then
return v ^ .5
else
return new(0, (-v) ^ .5)
end
end


Também será útil termos uma função que retorne verdadeiro ou falso para verificar se um valor é um número complexo:
function iscomplex(v)
return getmetatable(v) == cmt
end
j = new()


Finalizando


Para transformar isso tudo num pacote, salve todos os códigos num arquivo (pode ser complex.lua) e coloque na primeira linha do arquivo:
module("complex", package.seeall)


Vamos agora testar! Acesse o diretório onde está o arquivo complex.lua e execute o interpretador lua51. Execute os seguintes comandos e veja se funciona:
lua> require “complex”
lua> for c = -4, 7 do print(c, complex.j ^ c) end
-4 1
-3 j
-2 -1
-1 -j
0 1
1 j
2 -1
3 -j
4 1
5 j
6 -1
7 -j
lua> a = complex.sqrt(-9) + 2
lua> b = complex.new(3, 2)
lua> print(a, b)
2 + 3j 3 + 2j
lua> print(a + b)
5 + 5j
lua> print(a * b)
13j
lua> print(a / 2)
1 + 1.5j
lua> print(b ^ 2)
5 + 12j


Se tudo sair direitinho, parabéns! Acabou de fazer seu primeiro módulo de números complexos.

[]’s

PS: A primeira versão deste artigo foi escrita para Lua 5.0 e publicada aqui. Esta versão foi publicada pela primeira vez no Wordpress.com, no entanto tive problemas com a ferramenta deles.

2007-03-09

Empresarial

Baal Meu contador às vezes não me entende – assim como eu às vezes não o entendo –, o que gera uma falha de comunicação que me deixa na saia justa.

Não é culpa dele. Não é minha culpa. Tenho minha empresa há três anos, mas sou marinheiro de primeira viagem (é minha primeira empresa) e penso de forma diferente da maioria das pessoas que abrem empresas – ou nem tão diferente assim, mas diferente de praticamente todos os clientes de meu contador.

Sinto então uma obrigação de esclarecer meu ponto de vista. Não sei se isso pode ser útil, apenas sinto que preciso.

Empregabilidade


Comecei muito cedo na Informática, mas passei um período de minha vida trabalhando com outras coisas por influência de meus familiares, que acreditavam naquela magnífica máxima: «no futuro existirão no máximo cinco computadores no mundo todo».

Então a década de 1990 foi conturbada para mim. Estudei Química, Química Fina e Segurança Laboratorial; trabalhei em um projeto de pesquisa de supercondutores no setor de organometálicos do Departamento de Química Inorgânica (DQI) do Instituto de Química do CCMN, UFRJ. Trabalhei com hotelaria: fui recepcionista e cheguei a gerente. Também trabalhei com Música, tocando jazz e MPB em bares.

Como informata aprendi muito de lógica e criei as bases para minha profissão atual; como químico aprendi sobre segurança e a Natureza; como musicista desenvolvi minha criatividade; como hoteleiro (pretensão) aprendi um pouco sobre a necessidade que o ser humano tem de se sentir superior e menosprezar quem está socialmente inferior sempre que possível.

No entanto esse foi profissionalmente o período mais difícil de minha vida. Era muito difícil conseguir um emprego (como químico, informata, musicista ou hoteleiro) e cheguei a ter de catar inhame e pariparoba pra ter o que comer (não me envergonho disso), trabalhei como puxador de carroça (nem disso) e como professor de cursinho de Informática (disso eu me envergonho).

Nessa época a frase que mais ouvia quando era rejeitado numa entrevista de emprego – ou quando rejeitavam um pedido de mudança de cargo – era que não se cria cobra em casa. Talvez um dia eu conte essa história também.

O fato é que esse período me marcou muito. Teve uma época em que eu estava desempregado e minha esposa trabalhando como balconista numa loja de chocolates. Certo dia a gerente, apoiada pelo patrão, mandou ela limpar o banheiro. Não vejo nada de errado em limpar banheiros quando você é contratado pra isso.

Ela disse que não foi contratada para limpar banheiros, e a gerente retrucou que o padrão era quem pagava as contas dela, então se ele disse que ela tinha de limpar o banheiro, ela tinha de limpar.

Minha esposa contraargumentou que o salário era miserável e que não cobria a limpeza do banheiro, então a gerente – eu contei que a gerente era amiguinha do patrão? – disse que se ela não queria cumprir essas obrigações por aquele salário, havia mais vinte que aceitariam sem discutir.

Minha esposa então abandonou o emprego com o meu apoio.

Isso tudo me marcou demais, e um dos motivos para eu ter aberto uma firma é este: acrescentar um pouco de peso para equilibrar a balança.

Com uma empresa, posso prestar serviço para diversos clientes e nenhum deles pode jogar na minha cara que paga minhas contas. Cumpro com minhas obrigações contratuais – sinceramente nas maioria das vezes faço até mais por pura boa vontade – e espero que meus clientes façam o mesmo.

CLT


Certa vez estava conversando com um conhecido meu – muito transtornado – sobre CLT e fui obrigado a concordar com ele que a CLT brasileira traz mais prejuízo do que benefício.

Os encargos são muito altos, impedindo os empregadores de pagar salários melhores a seus empregados.

Entendo seu ponto de vista.

Os impostos e encargos de uma firma em um contrato empresarial nem se comparam aos de CLT.

Assim posso trabalhar, receber melhor e contribuir para com meu país pagando meus impostos.

Compromisso social


Uma coisa importantíssima é que, com o crescimento de minha firma, posso gerar emprego.

A partir de determinado ponto deixo de ser apenas contratado e me torno contratante.

Acho que todos temos um compromisso social e essa é uma das formas que tenho de cumpri-lo.

Muitos empresários (não todos) contratam apenas por necessidade – maldita Lei de Gerson! – e gostam de ser tratados por patrão. Muitos empregadores têm até alguma boa vontade e contratam porque precisam daquele serviço específico, não pela possibilidade de oferecê-lo a seus clientes, já outros pagam empregados simplesmente para ter capachos, pelo prazer de humilhar.

Penso de forma diferente.

Procuro meios para poder contratar as pessoas. Sinto-me na obrigação social de fazê-lo.

Não por pena, mas porque as pessoas merecem oportunidades e, se posso oferecê-las, é mais que um direito, é meu dever.

Aliás, tenho amigos empresários que, creio eu, pensam mais ou menos da mesma forma.

Conclusão


Não sei se isso pode ajudar alguém ou se foi e será apenas um desabafo – estou num período de muitos desabafos: preciso deixar o peso das costas cair para seguir em frente.

Pelo menos formalizei meu ponto de vista e espero que alguém tire algo de bom disso tudo.

[]'s

2007-03-08

Prece dos desesperados

Baal

Pai, dai-me paciência, porque se me derdes força, eu espanco um!

2007-03-06

O que é um computador?

Vírus Eu diria que este artigo não é para quem entende de tecnologia, mas professores de Informática acreditam que entendem de tecnologia e este artigo é para eles.

Há também aqueles que usam Word/Excel/PowerPoint, às vezes Photoshop/Corel Draw, Dreamweaver ou programas de gênero, e/ou mandam emails, acessam o Iorgut e jogam Second Life. Para vocês também vale.

Meu filho está tendo aulas de Informática no colégio, uma iniciativa de pseudo-inclusão digital, mas a professora dele nunca definiu o que é um computador (ou, se definiu, definiu como sendo essa caixinha do lado da mesa). Acho que qualquer curso de Informática deveria começar definindo isso.

Bem, o que é um computador?

Podemos começar dizendo que é um equipamento eletrônico. Mas espere aí... calculadoras, DVD-players, máquinas de lavar roupa, etc. são equipamentos eletrônicos... =/

Bem, vamos complementar dizendo que é um equipamento eletrônico análogo-digital. Novamente calculadoras, DVD-players..., também são. =P

O que diferencia uma calculadora de um computador?

E ainda há outro problema nesta definição! Calculadoras programáveis (como algumas da HP) tecnicamente são computadores, mas as não-programáveis não são.

Então computador é computador porque é programável? Não!

As calculadores não-programáveis foram de uma certa forma programadas para fazer o que fazem. Elas não são «reprogramáveis» – e há computadores não-reprogramáveis.

Há um recurso que diferencia um computador de outros dispositivos programáveis: controle de fluxo.

Um computador é um equipamento eletrônico, geralmente análogo-digital, programável (reprogramável ou não) que suporta controle de fluxo!

Microinstruções para JMP e família (JA, JE, JG, JGE, JL, JLE, JNA, JNE, JNG, JNGE, JNL, JNLE, JNP, JNS, JNZ, JP, JPE, JPO, JS, JZ...) são essenciais para a criação de um computador.

Agora, como você professor(a) vai explicar isso pros alunos depende de sua didática. Mãos à obra!

[]'s