Inércia Sensorial

01 de December de 2008

Alfabeto em Python

Filed under: Python — Tags: , — inerte @ 17:19

Não precisa digitar na mão:

1
alfabeto = 'abcdefghijklmnopqrstuvwxyz'

Isso imprime as letras minúsculas:

1
print map(chr, range(97, 123))

E isso as maiúsculas:

1
print map(chr, range(65, 91))

Mas você também pode contar com o próprio Python (pilhas incluídas, afinal!):

1
2
from string import ascii_letters
print ascii_letters

E de novo:

1
2
3
import string
print string.ascii_lowercase
print string.ascii_uppercase

26 de July de 2007

Crivo de Eratóstenes em Python

Filed under: Python — inerte @ 12:56

Estou fazendo os desafios do Projeto Euler e nos dez primeiros já vi três com números primos. Meu primeiro algoritmo ingenuamente testava a primalidade de um número tentando dividí-lo por todos os números menores que ele.

Uma lista com 1.000 números primos dessa maneira gera em pouco menos de um segundo no meu computador. Já 2.000, mais de 9 segundos. E 10.001, como pedido por um dos desafios, eu nem tive paciência de esperar os cálculos acabarem. Minha primeira implementação foi a seguinte:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
def primo(n):
    for i in xrange(2, n):
        if n % i == 0:
            return False
    return True
 
primo_lista = []
n = 1
while 1:
    if primo(n):
        primo_lista.append(n)
        if len(primo_lista) == 1000:
            break
    n = n + 1

Pocurando por métodos mais velozes achei dois, o Crivo de Eratóstenes e o Crivo de Atkin. O primeiro é mais simples, então decidi implementá-lo. O Crivo de Eratóstones é definido assim:

  1. Escreva uma lista dos números entre 2 e o maior número que você quer testar a primalidade. Vamos chamá-la de lista1;
  2. Escreva o número 2, o primeiro número primo, em outra lista que conterá os números primos encontrados. Vamos chamá-la de lista2;
  3. Remova o 2 e todos os múltiplos dele da lista1;
  4. O primeiro número que sobrar da lista1 é primo. Escreva ele na lista2;
  5. Remova essa número e todos os seus múltiplos da lista1. A remoção pode começar da raiz quadrada do número, já que múltiplos menores foram removidos em passos anteriores;
  6. Repita os passos de 4 a 6 até não restarem mais números na lista1;

A classe a seguir, escrita em Python, retorna uma lista com todos os números primos entre 2 e um número especificado (max_n).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
max_n = 50
 
class CrivoDeEratostenes:
    def __init__(self, max_n):
        self.lista = range(2, max_n + 1)
        self.primo_lista = [2]
        self.crivo()
 
    def crivo(self):
        primo_n = self.lista[0]
        max_n = self.lista[-1] + 1
        self.lista.remove(primo_n)
        for n in self.lista:
            if n % primo_n == 0:
                self.lista.remove(n)
        if len(self.lista) > 0:
            self.primo_lista.append(self.lista[0])
            return self.crivo()
        else:
            return self.primo_lista
 
 
print CrivoDeEratostenes(max_n).primo_lista
 
# [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47]

Pesquisando sobre Eratóstenes na Internet, descobri que ele foi um animal. O grego viveu dois séculos antes de Cristo e conseguiu calcular com 16% de erro a circunferência da Terra. Leu nos papiros de Biblioteca de Alexandria (aonde foi Diretor) que o sol iluminava o fundo de um poço na cidade de Siena (hoje Assuã) ao meio dia do dia mais longo (o solstício) no verão daquele cidade, em 21 de Junho. Ou seja, a luz fazia um ângulo reto com a Terra.

Mas no dia 21 de Junho, quando era meio dia em Siena, o Sol projetava sombras em Alexandria. Eratóstenes conclui então que a Terra era redonda. O ângulo das sombras deu 7º12′, quase 1/50 dos 360º de uma circunferência, então a distância entre Alexandria e Siena multiplicada por 50 seria a circunferência do planeta.

Mandou um pessoal percorrer essa distância e eles voltaram com 925km. E 50 vezes 925 é 46.250 km, enquanto a Terra tem 40.076 km.

Queria crescer de novo pra ser igual a ele 🙂

26 de October de 2005

RuntimeError: dictionary changed size during iteration

Filed under: Python — inerte @ 18:34

Em Python, o erro do título desse post acontece quando você percorre um dicionário e ele é mudado durante o laço.

Isso pode acontecer quando fazemos:

1
2
3
4
5
6
7
8
9
>>> dicionario = {'nome': 'Julio', 'sobrenome': 'Nobrega'}
>>> for k, v in dicionario.iteritems():
...     print v
...     del dicionario[k]
...
Nobrega
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
RuntimeError: dictionary changed size during iteration

Se você quer mudar o dicionário durante um laço, use keys():

1
2
3
4
5
6
7
>>> dicionario = {'nome': 'Julio', 'sobrenome': 'Nobrega'}
>>> for k in dicionario.keys():
...     print dicionario[k]
...     del dicionario[k]
...
Nobrega
Julio

Isso só é possível porquê keys() retorna uma lista independente do dicionário.

23 de October de 2005

Thread em Python

Filed under: Python — inerte @ 23:33

Comecei a fazer uma GUI usando o wxPython para tocar um arquivo de música com o código de ontem. Implementei o botão de seleção do arquivo, que até filtra os arquivos a serem mostrados de acordo com as extensões especificadas. No meu caso, *.mp3 e *.ogg.

Só que selecionado o arquivo, a interface travava. Pesquisando no Google, achei como abrir uma thread usando Python. Basta usar o módulo (surpresa) thread ou o threading. A diferença é que o módulo thread é mais baixo-nível (como em low-level, e não que ele te xingue :)), enquanto o módulo threading abstrai o uso e oferece mais opções.

(more…)

MP3 com Python

Filed under: Python — inerte @ 02:45

Sem bibliotecas adicionais como libmpg123 ou gstreamer ou qualquer outra. Puro Python. Bem, quase, já que o PyMedia é escrito em sua maioria em C, mas depois de instalado você pode usar o import para trazê-lo.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import pymedia.audio.sound as sound
import pymedia.audio.acodec as acodec
 
def playFile(file_name):
    file_extension = file_name.split('.' )[ -1 ].lower()
    parms = {'id': acodec.getCodecID(file_extension), 'ext': file_extension}
    decoder = acodec.Decoder(parms)
    f = open(file_name, 'rb')
    s = f.read(8192)
    r = decoder.decode(s)
 
    snd = sound.Output(r.sample_rate, r.channels, sound.AFMT_S16_LE)
 
    while len(s) > 0:
        if r:
            snd.play(r.data)
        s = f.read(512)
        r = decoder.decode(s)
 
    import time
    while snd.isPlaying():
        time.sleep(.05)

Para tocar um arquivo:

playFile(“arquivo.mp3”)

O PyMedia entende outros formatos de aúdio, como WAV e OGG. Ele também mostra vídeos com o Pygame mas isso eu ainda não testei não 🙂

06 de October de 2005

Navegando com Mechanoid

Filed under: Python — inerte @ 18:34

Existe um programa chamado Mechanoid feito em Python, uma colagem dos programas que compõem o Mechanize, só que voltado à execução de determinadas tarefas específicas, como entrar no Sourceforge ou conferir o Yahoo Mail.

Basicamente ele emula um navegador, abrindo páginas, clicando em links, preenchendo formulários. É tão fácil que dói os olhos…

(more…)

29 de September de 2005

SLOC em Python

Filed under: Python — inerte @ 12:18

Um pequeno script em Python para contar o número de linhas de todos os arquivos em um diretório (e sub-diretórios). Apenas edite a variável diretorio.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import os.path
 
diretorio = "/var/www/html/site/"
 
def visit(arg, dirname, names):
    for arquivo in names:
        arquivo_caminho = os.path.join(dirname, arquivo)
 
        if os.path.isfile(arquivo_caminho):
            f = open(arquivo_caminho)
            lines = len(f.readlines())
            arquivos.append(lines)
 
arquivos = []
os.path.walk(diretorio, visit, arquivos)
 
print "%s linhas" % sum(arquivos)

Powered by WordPress