Arquivo para a categoria 'Hacks'

06
Ago
09

“Cannot connect to VM”

Uma coisa estranha aconteceu hoje, e por isto estou fazendo uma pausa na preguiça de escrever algo.

Eclipse IDE

Eclipse IDE

Durante um dia normal de pesquisa, em uma reunião onde tentávamos entender o código de um projeto open source, o Eclipse Ganymede que ele utilizava no Linux estava com um problema para executar o Debug. Toda vez que tentava executá-lo, aparecia um dialog informando:

“Cannot connect to VM”.

Estranhamos. Olhando nas configurações de JRE utilizadas, estava tudo ok, e o problema apresentava-se somente no Debug, e não na compilação/execução de programas. Apresentava também, na área “Problems”, um problema com um getthisbyname(). Estranhei. Não estaria resolvendo o nome de que, se ao testarmos só estava tentando rodar um “Hello World”? A única máquina que estaria tentando alcançar seria ela mesma: localhost. Resolvemos olhar o arquivo /etc/hosts (que guarda algumas pré-configurações de hosts em UNIX):

#127.0.0.1   localhost
127.0.0.1   xxx-notebook
#outras configurações de hosts

Para os desavisados, em arquivos de configuração UNIX é comumente utilizado o # como símbolo para comentário de linha. Logo, aparentemente devido ao fato de estar comentado, o Eclipse (ou a função getthisbyname() de Java) não conseguia resolver o nome localhost para 127.0.0.1. Removido o comentário, o Debug do Ganymede passou a funcionar perfeitamente.

Interessante, não?

10
Mar
09

Labirinto em Haskell – tail recursion

Enquanto estava estudando a linguagem de programação Lua, em um capítulo sobre elementos funcionais da linguagem, me deparei com uma explicação interessante para tail recursion. Nela, o autor do livro (Programming in Lua, 1ª Edição) falava como a linguagem implementa completamente tail recursion(que acho que fica bem traduzido como recursão de cauda). Até aí tudo legal, mas melhora.

Bem, pra demonstrar que implementa e também explicar o conceito, o autor se utiliza de um jogo-exemplo: um labirinto. O jogo constrói o labirinto através de funções que chamam umas às outras, porém utilizando-se de recursão de cauda para manter sempre o uso de memória como se só houvesse uma função. Explicação e o exemplo utilizado podem ser encontrados aqui.

Explicando melhor recursão de cauda: o princípio é que não precisamos que uma função fique esperando o retorno de um resultado de outra para terminar sua execução, como acontece normalmente. Se você faz uma função em C, ou um método em Java, que termina com um comando return outraFuncao;, a função original ficaria esperando o termino da chamada para poder terminar sua execução. Só que outraFuncao pode fazer chamadas a outras funções, e essas a mais outras, e assim por diante. Tal carga será deixada para a memória, que acabará por estourar(um stack overflow, ou estouro de pilha). Mas perceba que, no caso de uma instrução final de uma função, não há motivo para a espera de retorno da chamada. Pode-se simplesmente indicar que o retorno será o da função agora chamada, e limpar a memória utilizada pela execução da original. É isto que linguagens funcionais como Haskell e Scheme e linguagens com fortes influências, como Lua, implementam.

A novidade que gostaria de compartilhar aqui é uma implementação do mesmo código feito em Lua, para Haskell. O código pode dar origem a um jogo bastante complexo e infinitamente escalável, já que ao chamar uma nova função (entrar em um novo quarto) nenhuma informação é mantida da que chama, e sua execução é encerrada por completo. Código em Haskell abaixo:

import IO

main = do
         room1

room1 = do
          putStrLn "You're in room #1"
          text <- getLine
          if text=="south" then
            room3 -- movendo-se pro quarto 3
            else
              if text=="east" then
                room2 --movendo-se pro quarto 2
                else
                  putStrLn "Invalid move" >>
                  room1 --permanece no mesmo quarto

room2 = do
          putStrLn "You're in room #2"
          text <- getLine
          if text=="south" then
            room4
            else
              if text=="west" then
                room1
                else
                  putStrLn "Invalid move" >>
                  room2 

room3 = do
          putStrLn "You're in room #3"
          text <- getLine
          if text=="north" then
            room1
            else
              if text=="east" then
                room4
                else
                  putStrLn "Invalid move" >>
                  room3 

room4 = do
          putStrLn "You're in room #4! You won!"

O código é simples, elegante, e correto. É este mesmo comportamento que torna a recursão um ponto tão forte em Haskell: iteração não é necessária à linguagem pois recursividade não apresenta peso adicional algum ao código. Isto nos permite escrever funções recursivas muito mais poderosas do que podemos encontrar em uma linguagem como C ou Java, onde a pilha de execução não suporta tantas chamadas quanto uma tarefa mais complexa possa precisar(ex.: inserção em uma árvore AVL com 100 mil nós). Isso nos permite executar códigos como o clássico exemplo do fatorial:

fact x = if x < 0 then error"Fatoriais sao de numeros positivos!"
                       else fact2 x 1 where
                              fact2 0 acumulador = acumulador
                              fact2 x acumulador = fact2 (x-1) (acumulador*x)

Pode-se rodar este exemplo e calcular o fatorial de 100 mil, o que não é possível com recursão em C. Apesar do peso do alto nível de abstração, vemos aí parte do poder do paradigma funcional e da linguagem Haskell!

PS: Erro corrigido no quanto à recursividade do fatorial. Ah, e o exemplo do fatorial pode não dar Stack Overflow, mas dependendo da entrada você pode atingir picos de uso de CPU. =)

09
Mar
09

Abrindo uma maleta com senha – o guia definitivo

Este post é para resolver o problema de muitas pessoas: ter uma mala que possui uma combinação para abertura, e não lembrar mais qual é. Escrevo isto pois meu caso foi um pouco extremo.

Trava!

Trava!


Tenho aqui uma maleta (na verdade é de minha namorada) cuja combinação de abertura consiste em 3 algarismos. Utilizamos durante um bom tempo uma determinada senha, decidimos mudar após algum tempo, e posteriormente não tivemos necessidade de usá-la durante uns 6 meses. O problema surgiu quando, ao tentar procurar se algo estava na maleta, não lembrávamos a combinação. Uma queda da maleta ou uma tentativa de abri-la usando força física grosseira contra a trava podem tê-la quebrado, o que descobri após testar as 1000 senhas possíveis. A partir disso, passei a procurar formas mais sofisticadas de abrir uma maleta cuja senha foi perdida, pois suspeitava que eu houvesse pulado algum número dos 1000 e que, por azar, tal número fosse a combinação correta. Encontrei vídeos como este:

Bem, métodos conhecidos na internet não funcionavam. Ou estavam errados, ou a trava estava quebrada, ou eu estava com realmente muita má sorte. Foi quando, ao procurar outro objeto mais importante, decidi apelar para força bruta com uma pitada de intelecto, o que poderia chamar de “Método do nó górdio”, para quem sacar referências históricas. Seguem as fotos sequenciais abaixo.

04
Fev
09

VirtualBox – testando

Atualmente, para virtualização no MacBook, tenho usado uma ferramenta que acredito ainda ser pouco comum: o VirtualBox. Desenvolvido atualmente pela Sun(empresa mãe da linguagem Java, da arquitetura SPARC, e atual dona do MySQL), o VirtualBox é uma máquina virtual com propósito de competição com atuais grandes nomes da cena de virtualização, como VMWare e XEN. É a aposta da Sun nesse mercado que atualmente já é responsável por muitas e muitas vendas de servidores(o que já os beneficiava de algum modo).

VirtualBox

VirtualBox

Usei a ferramenta (sem parar muito para leitura de manuais, FAQs e wikis relacionados) por um bom motivo: ela é totalmente gratuita, e decidi apostar após ver alguns vídeos no própria página da empresa a respeito da empreitada. Até agora a utilização tem sido amigável. Já instalei 3 VMs: uma Fedora 10, outra Ubuntu 8.10 e uma Debian Etch. Mas vamos aos pequenos problemas.

O processo de instalação não me deu muita dor de cabeça. A primeira instalação foi do Fedora 10 (Live CD, versão x86). Enfatizo o muita por terem havido alguns problemas. O primeiro passo necessário é escolher as configurações da máquina em si, antes de decidir instalar qualquer coisa nela. Selecionei uma quantidade razoável de RAM (750MB), mas me esqueci de configurar a memória de vídeo. Assim, durante todo o processo de primeira instalação(utilizando modo gráfico), a tela ficava dividida em 3 seções: da metade pra baixo, somente linhas horizontais cinzas preenchiam a tela; a parte superior, por sua vez, mostrava 2 trechos do que seria a visão normal, mas meio embaralhados. Confuso, mas com um pouco de paciência a instalação correu normal. Durante a primeira execução do sistema, a interface ficou também dividida e embaralhada. Desliguei a máquina, reajustei a memória de vídeo para 100MB, e iniciou com normalidade desta vez. Até aí, tudo ok.

Acontece que precisei reinstalar a máquina virtual. Repeti o procedimento, mesmo bug na instalação, resultado diferente na inicialização, mesmo com a memória de vídeo considerável. Tentei algumas mudanças, sem sucesso. Por fim, ajustei a memória para 64MB, e funcionou normalmente. Se alguém souber como isso aconteceu, sinta-se livre para comentar!

Continuando, a instalação do Ubuntu 8.10 não me deu tantos problemas. Com memória de vídeo de 100MB, o sistema instalou e executou com perfeição. Único problema: ambas as máquinas permaneciam com desempenho pouco desejável, apesar da alocação de recursos generosa. Descobri que o VirtualBox possui um conjunto de adições ao sistema operacional virtualizado, que otimizam seu funcionamento em relação ao hospedeiro. Tentei instalá-lo, porém faltavam algumas bibliotecas requeridas, e precisaria atualizar meu sistema (kernel, gcc, etc) para instalá-las. Ficou o dilema: ou gastava um razoável quantidade de tempo baixando atualizações intermináveis, ou sofria com desempenho abaixo do esperado. O que fazer? A solução: Nada. Misteriosamente, após uns dias, liguei a máquina virtual após uma alteração nas regras de consumo de energia no Mac, e o desempenho da VM havia melhorado. Havia sido a configuração de energia a causa do problema? Pouco provavelmente. Durante o tempo seguinte, alterei-as novamente e o desempenho se manteve.

Por último, porém o melhor de todos, instalei o Debian Etch. Com 945MB de RAM e 64MB de vídeo, acredito ser a máquina que está com o melhor desempenho. Nunca tinha tido a experiência de instalar o Debian previamente, mas seguindo a instalação gráfica do sistema, usando o CD net-install, só tive um problema: a demora para baixar os programas que escolhi instalar. Não que seja culpa de ninguém. O tipo de cd de instalação segue exatamente este propósito, onde a imagem do CD é menor, portanto leva menos tempo para baixar, e você não precisa baixar nada que não utilizará. Antes mesmo de terminar de baixar os programas, consegui terminar o download da imagem do CD1(com xfce) de instalação completa. Poderia ter feito por ele, mas o net-install funcionou tão bem quanto. Gostei também da distribuição, e é provável que eu continue a usá-la com frequencia.

VirtualBox em execução

VirtualBox em execução


Outras características interessantes do VirtualBox, algumas que já testei, outras que posso vir a testar, são:

  1. Utilização direta de partições da máquina para armazenamento de dados (ex.: uma partição real para um servidor real. A transição para um servidor real poderia ser feita com a migração física de um HD, caso a partição seja um dispositivo à parte, portanto);
  2. Opção de arquivos de tamanho dinâmico para armazenamento da máquina (já utilizei com o Debian. Cria-se um arquivo com tamanho limite, no meu caso escolhi 5GB. À medida que os dados forem inseridos/criados na imagem, ela ganha tamanho, e não possuirá o tamanho total desde o início. É uma ótima maneira de poupar espaço em partições reais);
  3. Opção de instalação de drivers para otimização, como mencionado acima, os quais permitem melhor desempenho e utilização da máquina (full-screen real, com o sistema virtualizado ocupando a tela inteira da máquina, o que não vem diretamente com o programa);
  4. API para desenvolvimento do VirtualBox, com SDK distribuído gratuitamente pela Sun.

Quaisquer novidades interessantes quanto à utilização, como os itens acima, postarei aqui.

04
Jan
09

Movendo uma imagem usando Haskell e wxHaskell

Há pouco mais de um ano, quando eu estava cursando a cadeira de Linguagens de Programação Funcionais, tive o prazer de começar a utilizar interfaces gráficas em Haskell, linguagem utilizada pela disciplina. Dentre os vários toolkits gráficos disponíveis, o que nos foi apresentado foi o wxHaskell, na verdade um binding para o kit gráfico multi-plataforma/linguagem wxWidgets.

Tivemos vários problemas com o desenvolvimento:

  • o desenvolvimento gráfico para esse binding era exclusivamente textual, logo não há a possibilidade de modelar visualmente(pelo menos que nós conhecêssemos);
  • nossos prazos eram curtos, dado que a parte gráfica só foi nos ensinada no final da disciplina;
  • boa parte do que tentávamos fazer levava um bom tempo para ser estudado e descoberto como ser feito;
  • nossa equipe tinha poucas possibilidades de reunião, se resumindo a através de chat, geralmente;

Mas isso não é o foco deste post. No final das contas, o projeto foi feito.

wxHaskell

wxHaskell


Enquanto produzia, para prototipar o que eu poderia usar do toolkit, comecei a fazer brincadeiras. Uma delas seria fazer algo que poderia se tornar um jogo: movimentar uma imagem na tela. A imagem poderia ser um personagem, em um hipotético jogo. =)

Alguns passos fazem-se necessários. É necessário o GHC instalado, e o a biblioteca wxHaskell. Utilizei-nos no Windows, e tive inclusive que utilizar uma versão desatualizada do GHC para tornar possível a execução. Nunca mais o executei, e futuramente posso colocar uma descrição detalhada de como instalar tudo necessário. =)

Como foi feito? Explicando em alguns passos:
1) Importação dos módulos necessários:

import Graphics.UI.Wx
import Graphics.UI.Wxcore

2) Define-se um jogador, o qual encapsula a imagem a ser impressa e uma posição(um ponto na tela):

data Player = Player FilePath Point String

O tipo FilePath é um apelido para o tipo String, não se diferencia em nada de um pedaço de texto, representando um caminho nos arquivos para algo, que no nosso caso será a imagem. Point é um TAD que encapsula dois números – Integers, se não me engano – e faz parte da biblioteca do wx mesmo. A String final é apenas uma representação do nome do jogador. =)
3) Define-se a função principal, a que executará o programa através da interface gráfica. Aqui a chamaremos de gui:

gui = do

esta função é um Monad, ou seja, ela encapsula comportamento imperativo no paradigma funcional da linguagem. A partir da diretiva do o comportamento será similar a código imperativo, onde as chamadas a funções estarão separadas por quebras de linhas, de maneira ordenada. Claro, permanece a necessidade de organização de código através de indentação. Prosseguindo:

gui = do
	jog <- varCreate (Player "testFace.gif" (Point 0 0) "joao")
	j <- frameFixed [
		clientSize := Size 300 200,
		text := "teste jogo",
		picture :=	"face.ico",
		on paint := (\dc rect -> do
			x <- varGet jog
			printPlayer x dc
			return ()
			)
	]

Temos no código acima a criação de uma variável, jog, a qual representará um jogador(o tipo abstrato Player, mostrado acima). Passamos na criação a String “testFace.gif”, que é o nome do arquivo que coloquei na mesma pasta que o programa. O ponto passado como ponto inicial foi (Point 0 0), o ponto mínimo de exibição.

testeFace.gif!

testeFace.gif!


Na linha seguinte, definimos j, o qual será um Frame de tamanho fixo, com o uso da função frameFixed, onde passamos a lista de argumentos. Widgets em wxHaskell seguem geralmente esta forma, uma função relacionada que recebe uma lista de argumentos, onde outros podem ser configurados posteriormente. No caso, definimos o tamanho utilizável da janela em clientSize(com o TAD Size, que funciona recebendo dimensões de largura e altura), o texto da barra da janela em text, o ícone da janela em picture, a função que será chamada no momento da “pintura” do widget na tela, em on paint. A função, que declaramos on the fly através de uma expressão lambda, recebe um contexto de dispositivo(dc – device context), que neste caso é a janela, e um retângulo(rect), que especifica as coordenadas da área de visualização. Passaremos o dc como segundo argumento para a função de impressão, printPlayer. O primeiro argumento que passamos é o Player da variável jog, através da constante x, inicializada em:

x <- varGet jog 

A função printPlayer pode ser descrita no código como:

printPlayer :: Player->DC a->IO ()
printPlayer (Player a b c) dc = do
	im <- bitmapCreateFromFile a
	drawBitmap dc im b True []

ou seja, recebe o Player e o Device Context, e utiliza a função de criação de bitmap a partir de um caminho, bitmapCreateFromFile, e a função de desenho de bitmaps, drawBitmap, ambas últimas da própria API de WxHaskell. Temos a criação do bitmap im, que é impresso no dispositivo dc, nas cordenadas indicadas pelo ponto b, com o modo de transparência especificado(True). A lista vazia que está como último argumento são as propriedades, as quais não cheguei a utilizar(e descobrir utilidade).
Continuando no código da função gui, após a criação do FrameFixed j, configuramos alguns eventos para ele. Acredito que seja um padrão de codificação configurar os eventos fora da lista principal de atributos. Escolhi só deixar o on paint por ter caráter intrínsico ao frame, diferente dos que criaremos agora:

	set j [
		on downKey := (do
			varUpdate jog desce
			repaint j
			return ();
			),
		on upKey := (do
			varUpdate jog sobe
			repaint j
			return ();
			),
		on rightKey := (do
			varUpdate jog direita
			repaint j
			return ();
			),
		on leftKey := (do
			varUpdate jog esquerda
			repaint j
			return ();
			)
		]

os eventos configurados acima servem para movimentar a imagem a partir das setas do teclado. WxHaskell já utiliza eventos para as 4 teclas direcionais, listadas acima(ex: on rightKey, onde rightKey é o evento de apertar a seta para a direita). O que acontece a cada evento: é chamada a função varUpdate, da própria API de WxHaskell, a qual é uma função polimórfica. Se não me engano, sua assinatura é a seguinte:

varUpdate::a->(a->a)->IO ()

ou seja, recebe um argumento do tipo a, e uma função que também recebe um argumento deste tipo e retorna outro do tipo a, e finalmente retorna um IO (). Após a chamada de varUpdate, temos a chamada da função repaint, tomando como argumento o frameFixed j. O que esta função faz é disparar o evento de pintura(paint) do argumento, já descrito acima.
Mas o que as funções passadas como argumento para varUpdate – esquerda, direita, sobe e desce – fazem? Vejamos uma delas:

sobe :: Player->Player
sobe (Player a (Point x y) c) = if y==0 then (Player a (Point x y) c)
				else Player a (Point x (y-k)) c

sobe recebe um argumento do tipo Player e retorna o mesmo tipo. A lógica desta função consiste em checar se a posição do jogador já atingiu o topo da janela(quando y é igual a 0), e caso contrário retornar um Player com o valor de y reduzido em k, onde k é uma constante de movimentação, indicando quantos pixels serão saltados. O espaço percorrido por unidade de tempo – ou seja, por disparamento do evento – definirá a velocidade do personagem, sendo seus valores diretamente proporcionais. No meu caso, utilizei:

k::Int --Constante de movimentação
k = 10

As outras funções seguem lógica idêntica, sendo somente necessário checar por colisão do Player com as bordas de j, por isso não as colocarei por extenso aqui. Portanto, a partir de cada evento configurado (o pressionar das setas direcionais) temos uma atualização configurada para a variável jog, e portanto a imagem se comportará da maneira apropriada. Poderíamos brincar um pouco com isso também, fazendo alterações de imagens a partir de determinadas situações, que poderiam ser cláusulas if-then-else nas funções de atualização. Basta usar a criatividade.
Após isso, basta compilar o código e voilá!, você tem uma imagem se movimentando pela sua tela. =)

Comentários de aperfeiçoamentos e hacks a partir disto são bem-vindos! Breve, quem sabe, coloco aqui algo com GTK2Haskell!

20
Dez
08

Coisas divertidas em Python (2) – tocando sons

Como prometido aqui, colocando algo que eu estava vendo há algumas semanas atrás, bem interessante e, por enquanto, fácil de mexer: Manipulação de sons com Pygame.

Pygame

Pygame

Uma explicação antes: Pygame é uma biblioteca para produção de jogos em Python. Oferece suporte a sons, gráficos 2D e 3D, entre várias coisas necessárias à produção de jogos. Aqui eu estou mostrando só como utilizá-la para tocar e manipular sons.

Para começar, é necessário importar o módulo pygame e inicializá-lo.

import pygame
pygame.init()

Manipulação mais simples: usa-se a classe Sound.

from pygame.mixer import Sound
audio = pygame.mixer.Sound(caminhoArquivo)

onde caminhoArquivo é uma String contendo o caminho relativo até o arquivo de som, ou o caminho absoluto no sistema. Pygame por padrão suporta extensões .wav e .ogg, ao menos na versão testada(Linux). Chega a ser estupidamente fácil a maneira como você manda tocá-lo:

audio.play()

onde o método play também pode receber um argumento da quantidade de vezes que toca novamente, e outro do tempo destinado a tocar. No caso maior, a interface dele fica algo como play(numeroDeRepetições,duração). Pode-se fazer um som tocar uma quantidade infinita de vezes passando o argumento como -1.
Vários canais de som também estão disponíveis, e você pode tocar vários sons simultaneamente. Por exemplo:

musica = Sound(musica1)
som = Sound(som1)
v = True

musica.play(-1)
while(True):
    if v:
        som.play()
    v = not v

O exemplo é meio absurdo, já que eternamente ocorreria o laço e não haveria pausa alguma. Porém a idéia principal é que toda vez que v for verdadeiro, será tocado o som. Enquanto tudo acontece, a musica continuará tocando normalmente.

Manipulação aprimorada: usaremos agora o tipo sndarray.

import pygame.mixer.sndarray
from pygame.mixer.sndarray import *

arraySom = array(musica)

Agora você tem um array contendo todas as amostras de byte do som. Isso é um array BEM grande. Por exemplo, se o som tiver uma taxa de amostragem de 11000Hz, temos 11000 amostras por segundo. Logo, o tamanho do array é de 11000 * tamanho do som em segundos. Você pode testar isso manipulando este array, como no exemplo abaixo:

novoArray = arraySom[0:33000]

Considerando que temos um som com amostragem de 11000Hz, temos agora um novoArray com o equivalente a 3 segundos de amostragem(≈1/11000 segundo). Para tocar, podemos converter de volta para Sound.

novoSom = sndarray.make_sound(novoArray)
novoSom.play()

Pronto, agora você tocará aproximadamente 3 segundos do objeto musica original, do tipo Sound, uma representação do arquivo de som original passado como argumento.

Canais de reprodução
Há também maneiras para controlar os canais que são utilizados. O método play da classe Sound retorna um objeto de tipo Channel. Com ele, você pode controlar algumas coisas como volume de audio, inclusive para cada saída de som. Como funciona: a classe Channel possui um método setVolume, o qual recebe uma tupla numérica, onde os argumentos vão de 0 a 1(argumentos maiores que 1 funcionam como 1, até onde testei).

volume = 0.3, 0.7
canal = musica.play()
canal.setVolume(volume)

Você pode ouvir agora a saída da esquerda com som menor que a da direita, e nenhuma das duas com o volume máximo.
Canais de reprodução são alocados automaticamente pelo sistema, e possuem um numero limitado. Você pode aumentar a quantidade de canais, usando-se do método set…, e alocar explicitamente o canal que você deseja para o toque do som, utilizando-se do seguinte formato:

valor_desejado = 10
pygame.mixer.set_num_channels(valor_desejado) #você tem agora 10 canais disponíveis.

pygame.mixer.set_reserved(1) #você reservou um canal. Agora pygame não alocará automaticamente nada no canal 0.
canal = pygame.mixer.Channel(0) #atribuiu seu canal reservado à variável canal

canal.play(musica) #tocará o som musica no canal reservado.

Com tudo isso você pode editar seus sons, fazê-los tocar da maneira que deseja, simular sons vindos de diferentes posições(Stereo Panning, brincando com os volumes das caixas), ou seja, tem um arsenal pra manipulações sonoras bastante potente. Tudo graças a uma biblioteca de jogos. =)

Boa parte desse código foi testado em uma instalação do pygame, usando de Python versão 2.6. Talvez não haja disponível versão para a nova versão 3.0. Talvez haja algum erro, mas prometo revisar isso depois. =)

28
Nov
08

Posting from a Mac

Pela primeira vez estou escrevendo um post a partir de um Mac. É diferente/estranho:

...

...

- Teclado estranho 1: Para quem estava acostumado com um Acer, onde para colocar uma interrogação (?) era preciso “AltGr + W”, ele se torna altamente incômodo. O que acontece: o semelhante, nas teclas do Mac, se encaixa em “Command+W”, o que, geralmente, fecha uma janela/aba. É, realmente irritado estar conversando e, sem querer, fechar a janela ao tentar fazer uma pergunta.
- Teclado estranho 2: A acentuação(e qualquer caractere não usado na lingua inglesa) requer uma série de passos estranhos para quem passou sua vida usando acentuação para Windows ou GNU/Linux. Alguns básicos:

  • Acento agudo: Option+”e”+letraDesejada
  • Acento circunflexo: Option+”i”+letraDesejada
  • Acento grave: Option+”`”+letraDesejada
  • Sinal gráfico Til: Option+”n”+letraDesejada
  • C cedilha: Option+”c”
  • Trema: Option+”u”+letraDesejada

Para mais sinais gráficos, uma busca no google por Mac OS X accent deve ajudar suficientemente.
Outra maneira de corrigir isso pode ser feita com configuração alternativa para o layout do teclado. Estou em dúvida ainda se faço isso, talvez daqui uns dias minha paciência se acabe… Bem, a lei do menor esforço pode ser conseguida aqui: http://www.brockerhoff.net/usi/index.html

-Teclado estranho 3: Não possui delete! Bem, a tecla delete funciona como backspace. Para fazê-la funcionar como delete em um teclado comum, é preciso pressionar Fn+delete.

-Trackpad: Diferente de outros touchpads que usei até hoje, em vários notebooks e de diversas marcas, o trackpad do Mac não permite clique no meio dele. Em outros(comuns), um clique do mouse pode ser simulado com um toque(ou dois) no meio do dispositivo. No caso da maçã, todos têm que ser feitos no botão especificado. E mais: só há um botão, para clicar com (o que seria) o botão esquerdo, precisa-se pressionar control + o botão.
Essa configuração é a padrão do trackpad. Como isso me incomodou um pouco, olhando configurações do sistema(teclado e mouse) consegui habilitar clique no touchpad, e há outras para facilitar também o do botão secundário. Ok, pelo menos aí o Mac merece manter seu ponto de boa usabilidade. =)
O outro comportamento “diferente” na minha opinião, o fato de fazer rolamento de tela usando dois dedos, não me incomodou. Pra falar a verdade, achei muito bom, dado que algumas vezes uma movimentação comum do mouse pode sem querer provocar rolamento. E, outro ponto pro Mac, já vem habilitado, por padrão, rolagem horizontal. Bem, ao menos eu gostei.

Warhol

Warhol


-Aplicações: Ao menos no meu Mac OS X (cuja instalação foi inicializada a contra-gosto pelo meu irmão) já vieram diversas aplicações “interessantes”: programa para criar músicas, para criar filmes, para tirar fotos(inclusive com efeito, vide nesse post) álbum de fotografias, um pequeno messenger, entre outras, que são bem interessantes. Para falar a verdade, nunca mexi em nenhum desses tipos de programas, mas provavelmente eles vêm com o pacote devido a pesquisas feitas pela Apple sobre público-alvo comprador de Macs.
Vale ressaltar algo que não me acostumei: não fui com a cara do Safari, navegador que vem com o OS X e produzido pela Apple. Não sustentei 3 dias e instalei logo o Mozilla Firefox 3.0. Muuuuito melhor. =)

-Unix: Pra finalizar, o Mac OS X é comprovadamente um Unix, o que me interessará muito em hackear um pouco nele. Também possui um kernel baseado no FreeBSD, e pelo que vi já vem com pelo menos python instalado! Ainda bem que minhas férias estão chegando… =)

Houve outras coisas que me incomodaram um pouco, mas não lembro agora. Pode ser que eu venha a complementar aqui posteriormente.

No mais, continuo principalmente interssado em GNU/Linux e FOSS, então devo instalar ou o Ubuntu, ou o Fedora no Macbook. Afinal de contas, apesar de tudo dito acima, o ponto mais interessante será me aproveitar da estabilidade do hardware!

Talvez em breve eu escreva algo sobre Como fazer dual-boot Mac e Linux usando o boot camp.

08
Out
08

Coisas divertidas(?) em Python

Python powered

Python powered


Algumas coisas divertidas de se fazer em Python:

  • Abrir uma página web em um browser
    Para se fazer isso, pode ser usado, diretamente da biblioteca padrão, o módulo webbrowser:

    import webbrowser
    
    webbrowser.open("http://frsoares.wordpress.com")
    

    O módulo suporta vários browsers no Unix e no Windows utiliza o padrão.

  • Listar um diretório e mudar um diretório, entre outros
    O módulo os oferece dezenas de funções para manipular o sistema operacional, de maneira independente de sistema.

    import os
    
    os.listdir(".") #lista o diretorio atual
    
    os.chdir("..") #muda de diretório para o abaixo na árvore do sistema
    
    #entre outros
    
  • Serializar objetos com o cPickle
    Qualquer coisa em Python pode ser transformada para texto ou mandada de volta usando o módulo pickle ou cPickle. Ambos são equivalentes.

    import cPickle
    
    dic = {'oi':12, 'tchau':13}
    arq = open('arquivo.txt','w')
    
    #insere-se itens
    cPickle.dump(dic,arq)
    cPickle.dump('algo',arq)
    arq.close()
    
    #recupera-se itens
    arq2 = open('arquivo.txt','r')
    print cPickle.load(arq2)
    print cPickle.load(arq2)
    arq2.close()

updates a serem adicionados (quando eu lembrar de algo)….

30
Abr
08

Coisas descobertas essa(s) semana(s)

  1. Eu não sei reparticionar HD’s com GParted. É melhor aprender antes de tentar novamente, sob risco de perder todos meus arquivos.
  2. Após instalar o Fedora 8 (ainda não no meu pc), haviam 737 atualizações a serem feitas, o que já havia me sido profetizado.
  3. O jeito que mais me agrada para ver um código direto é: nl nomeDoArquivo | less. Mais rápido que o Notepad++, dentro do terminal, e numerado. Só falta syntax highlighting.
  4. Sim, liberando 20GB devo já conseguir instalar o Fedora. Resta lamentar as atualizações que demorarão horas a serem baixadas.
  5. O orientador de iniciação científica de minha namorada, não satisfeito em escravizá-la, quer me mandar aos trabalhos forçados também.
  6. O meu orientador não parece se importar com isso.
  7. A caminho de implementar uma simulação de máquina de Turing em Haskell(ironia: máquina de turing usando lamda-cálculo)).
  8. Meu horário de sono fica desregulado muito fácil. Um dia entre 18h e 20h, outro dia entre 4h e 6h30, e outro entre 23h e 2h. E consigo ficar mais pontual assim.
  9. Escrever se aprende escrevendo. E lendo. Por isso talvez eu coloque mais alguma coisa aqui em breve: um certo trabalho de Metodologia Científica que me atormenta.

Isso não é feito para ser entendível completamente por ninguém além de mim.

29
Fev
08

Instalando QEMU no Windows

Pra começar, o Qemu é um emulador de um processador. Pra que serve? Emulando um processador de um PC, você pode usá-lo para executar qualquer sistema bootável, esteja ele em um cd, dvd ou um espaço no seu disco rígido.

Não, talvez não seja o melhor emulador do mundo. Sim, ainda estou futucando pra aprender melhor ele. Mas foi simples de instalar.

  1. Primeiro: vá em http://www.h7.dion.ne.jp/~qemu-win – nessa página você pode encontrar um binário pra Windows. Vem até com um linux linha de comando para testes. Funciona – só não muito bem.
  2. Baixar um arquivo qemu-xxx-windows.zip, onde xxx é o número da versão.
  3. Extraia o arquivo em alguma pasta.

Para usar, o mais adequado é ter uma iso de um live-cd disponível, e de preferência em uma pasta facilmente acessível(próxima) da do Qemu. Depois você pode rodar pelo prompt de comando(ou um .bat) um comando de execução semelhante a:

qemu.exe -L . -boot d -cdrom current.iso

e, voilá!, current.iso roda filé em um emulador(configurado por padrão pra 128MB).

Screenshot1 do DSLScreenshot2 do DSL Screenshot3 do DSL

Há algumas configurações e manipulações possíveis pro qemu. Mas isso pode ficar para outro post. o/




X-Files

 

Dezembro 2009
S T Q Q S S D
« Out    
 123456
78910111213
14151617181920
21222324252627
28293031  

Estatísticas:

  • 4,222 erros de pesquisa

possivelmente perigosos:

Tweet! :>

last.fm

Join the Free Software Foundation!

Support freedom