[Curso de Python] A função range
26 de Fevereiro de 2010, 0:00 - sem comentários aindaAntes de prosseguir leia os artigos anteriores aqui.
Olá pessoal!
Dando continuidade ao estudo da estrutura for vamos ver uma função muito utilizada em cojuto com o for: a função range
Como brinde, devido a uma dúvida postada nos comentários, vamos ver como fazer combinações em Python.
A função range
Muitas vezes, junto com o for, é necessário criar uma lista de valores, para isso utilizamos a função range. A função range, gera um lista de valores de acordo com os argumentos passados para ela. Segue um exemplo básico:
Ao especificar somente um valor, a função range retorna uma lista de número. Diferente do que imaginamos, ela não retorna uma lista até o número especificado (nesse caso, de 0 a 10) mas sim um intervalo que se inicia no zero e termina no número inteiro que antecede o número especificado. na notação matemática para intervalos, a função range do exemplo anterior criaria o seguinte intervalo: [0,10). Isto é, um intervalo fechado à esquerda e aberto à direita.Código:>>> range(10) [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
É possível alterar o início do intervalo, basta adicionar mais uma argumento. Mesmo alterando o início, o intervalo gerado pelo range sempre será fechado à direita e aberto à esquerda. Um pequeno exemplo:
Também é possível especificar o "passo" do intervalo, ou seja o valor de incremento:Código:>>> range(1,10) [1, 2, 3, 4, 5, 6, 7, 8, 9] >>> range(5,10) [5, 6, 7, 8, 9] >>> range(-5,10) [-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9] >>>
No exemplo acima, utilizamos um incremento de 2, desta forma "pulamos" de 2 em 2.Código:>>> range(-6,6,2) [-6, -4, -2, 0, 2, 4] >>>
O nosso colega Jockerman pediu uma ajuda para re-escrever o seguinte código C em Python:
Esse trecho de código é utilizado para gerar pares de numeros não repetidos. Um trecho da execusão desse código em C:Código:#include <stdio.h> #include <stdlib.h> main(){ int x,y; for(x=1; x<=10;x++){ for(y=x+1;y<=10;++y){ printf(\"%d, %d\n\", x,y); } } }
Vamos reescrever esse código para Python...Código:1, 2 1, 3 1, 4 1, 5 1, 6 1, 7 1, 8 1, 9 1, 10 2, 3 2, 4 2, 5 2, 6 2, 7
Podemos ver que a unica diferença entre os códigos é a ausência de declaração de variáveis, a necessidade da função range (que faz o papel de x=1; x<=10;x++) e que no range temos que especificar o final como 11. Segue um trecho da saída gerada pela execução desse código:Código:for x in range(1,11): for y in range(x+1,11): print '%i, %i'%(x,y)
Mas o mais legal de tudo é a facilidade que o Python provê aos seus programadores. Esse problema citado pelo nosso colega, é uma combinação simples de 2 em 2. Então, porque perder tempo pensando em como fazer esses fors? Gaste sua massa cinzenta em outros problemas, use a biblioteca padrão do Python:Código:1, 2 1, 3 1, 4 1, 5 1, 6 1, 7 1, 8 1, 9 1, 10 2, 3 2, 4 2, 5 2, 6 2, 7
Segue a saída completa gerada pela execução desse código:Código:from itertools import combinations for x,y in combinations(range(1,11), 2): print '%i, %i'%(x,y)
Código:1, 2 1, 3 1, 4 1, 5 1, 6 1, 7 1, 8 1, 9 1, 10 2, 3 2, 4 2, 5 2, 6 2, 7 2, 8 2, 9 2, 10 3, 4 3, 5 3, 6 3, 7 3, 8 3, 9 3, 10 4, 5 4, 6 4, 7 4, 8 4, 9 4, 10 5, 6 5, 7 5, 8 5, 9 5, 10 6, 7 6, 8 6, 9 6, 10 7, 8 7, 9 7, 10 8, 9 8, 10 9, 10
Quantos porcos e quantas galinhas?
23 de Fevereiro de 2010, 0:00 - sem comentários aindaHoje eu estava lendo alguns sites através do Google Reader e dentre todos os assuntos um se destacou. Foi um post do Sérgio Luiz do blog Vivaotux. Nesse post ele apresenta o seguinte problema:
O Sérgio apresentou uma solução em Python onde ele utilizava a 'força bruta' para achar a solução. Achei a solução muito bem elaborada, eu não teria conseguido pensado em algo assim! Confiram o código ao vivo no post dele aqui. Nos comentários deixei outra possibilidade de solução, e pensando agora, enquanto escrevo esse post, percebi que existe terceira forma de resolver esse problema!Um fazendeiro tem um bando de porcos e um bando de galinhas. Ele sai para o terreiro e observa 20 cabeças e 56 pernas. Quantos porcos e quantas galinhas que ele tem?
Vamos primeiro abordar o problema...
Enquanto eu lia o código, me lembrei das aulas de álgebra linear e calculo numérico e pense: deve ter uma maneira mais direta de se resolver isso. Pegando o problema do início, o que temos é um sistema de 2 equações e 2 variáveis:
equação 1: numero_de_galinhas + numero_de_porcos = numero_de_cabecas
equação 2: 2*numero_de_galinhas + 4*numero_de_porcos = numero_de_pernas
Para ser mais matemático, vamos dizer que o numero de galinhas é X e o numero de porcos é Y. Para simplificar, vamos pegar o numero de pernas e cabeças dados no exemplo: 56 e 20, respectivamente. Reescrevendo a equação, e destacando as constantes unitárias temos:
equação 1: 1*X + 1*Y = 20
equação 2: 2*X + 4*Y = 56
As duas maneira que consegui pensar podem ser classificadas como simples e complexa. Vamos pela complexa primeiro...
Resolução de sistemas lineares através de matrizes
Um sistema linear pode ser representado por matrizes da seguinte forma:
[Coeficientes]*[Variaveis] = [Constantes]
Isto é, a matriz de coeficientes multiplicada pela matriz de variáveis é igual a matriz de constantes, onde a matriz de coeficientes é composta pelos coeficientes das variáveis X e Y, a matriz de variáveis é composta pelos próprios X e Y e a matriz de constantes é compostas pelas constantes após o sinal de igual. Dessa forma temos o seguintes:
Matriz coeficientes:
Matriz Variáveis:Código:| 1 1 | | | | 2 4 |
Matriz Constantes:Código:| X | | | | Y |
Juntando tudo temos:Código:| 20 | | | | 56 |
Matriz coeficientes:
Para resolver o sistema tudo que temos que fazer é isolar a matriz das variáveis:Código:| 1 1 | | X | | 20 | | | * | | = | | | 2 4 | | Y | | 56 |
Isto é, a Matriz das variáveis é igual à multiplicação entre a matriz dos coeficientes inversa (por isso o -1) e a matriz das constantes.Código:| X | | 1 1 |-1 | 20 | | | = | | * | | | Y | | 2 4 | | 56 |
Agora vem a mágica! Para fazer isso em Python só precisamos de um import! Segue o código:
Ok, agora a forma simples...Código:from scipy import matrix def resolve_fazenda(cabecas, pernas): # 1*galinhas + 1*porcos = cabecas # 2*galinhas + 4*porcos = pernas # Cria a matriz de coeficientes Mcoef = matrix([[ 1, 1], # Coeficiente da primeira equação [ 2, 4]], # Coeficiente da segunda equação ) # Cria a matriz de constantes Mconst = matrix([[cabecas], [pernas]]) # Calcula a multiplicação entre a matriz dos coeficientes inversa e a matriz das constantes # Aqui eu chamei ela de Matriz Solução Msolucao = Mcoef.getI()*Mconst # Apresenta a solução print 'Tem %s galinhas e %s porcos na fazenda!'%(float(Msolucao[0]), float(Msolucao[1])) # Vamos fazer alguns testes! resolve_fazenda(20, 56) #Tem 12.0 galinhas e 8.0 porcos na fazenda! resolve_fazenda(21, 62) #Tem 11.0 galinhas e 10.0 porcos na fazenda!
Solução algébrica por isolamento
Vamos retomar as equações (substituindo os valores constantes por C e P apra cabeças e pernas, respectivamente):
equação 1: X + Y = c
equação 2: 2*X + 4*Y = P
Isolando o X na primeira equação obtemos:
X = C - Y (equação 3)
Substituindo o X a equação 2 obtemos:
Y = (P/2) - C (equação 4)
Agora usamos as equações 3 e 4 para resolver o problema:
Em ambos os exemplos, vale a pena adicionar testes se os valores encontrados são inteiros porque, com certeza, não faz sentido ter "galinhas negativas" e "porcos negativos" no resultado!Código:def resolve_fazenda2(cabecas, pernas): # Porcos = (Pernas/2) - Cabecas # Galinhas = Cabeças - Porcos porcos = float(pernas/2) - cabecas galinhas = cabecas - porcos # Apresenta a solução print 'Tem %s galinhas e %s porcos na fazenda!'%(galinhas, porcos) # Vamos fazer alguns testes! resolve_fazenda2(20, 56) #Tem 12.0 galinhas e 8.0 porcos na fazenda! resolve_fazenda2(21, 62) #Tem 11.0 galinhas e 10.0 porcos na fazenda!
Código:>>> resolve_fazenda(10, 20) Tem 10.0 galinhas e 0.0 porcos na fazenda! >>> resolve_fazenda(11, 20) Tem 12.0 galinhas e -1.0 porcos na fazenda! >>> resolve_fazenda(12, 20) Tem 14.0 galinhas e -2.0 porcos na fazenda! >>>
[Curso de Python] Estruturas For Aninhadas
22 de Fevereiro de 2010, 0:00 - sem comentários aindaAntes de prosseguir leia os artigos anteriores aqui.
Olá pessoal!! Sei que sumi e demorei para postar essa continuação! Peço desculpas a todos e garanto que vou retomar a regularidade das postagens.
Sem mais delongas, vamos ao que interessa!
Estruturas For Aninhadas
Muitas vezes uma única estrutura for não é o suficiente para realizarmos um trabalho, para sanar isso utilizamos um aninhamento de estruturas for. Uma estrutura for aninhada nada mais é que "um for dentro de outro for".
Um aninhamento de 2 fors torna possível percorrer e analisar estruturas de duas dimensões. Um simples exemplo a baixo:
Nesse exemplo, nosso for mais externo percorre o conteúdo da lista listas_nums, que são as seguintes listas: [1, 2, 3], [4, 5, 6] e [7, 8, 9]. O for mais interno é executado em cada uma dessas listas, dessa forma ele percorre o conteúdo (números) de cada lista. abaixo a saída produzida pelo código acima:Código:listas_nums = [[1, 2, 3], [4, 5, 6], [7, 8, 9]] for lista_num in listas_nums: # For externo, responsável por percorrer pegar a lista de números dentro da lista print 'Encontrei a lista',lista_num print ' Essa lista é composta por:', for num in lista_num: # For interno, responsável por percorrer os números dentro de cada lista. print num, print ''
Esse tipo de abordagem é efetiva para uma série de problemas. Vamos ver agora alguns exemplos mais práticos, como por exemplo calcular a média dos valores de cada lista:Código:Encontrei a lista [1, 2, 3] Essa lista é composta por: 1 2 3 Encontrei a lista [4, 5, 6] Essa lista é composta por: 4 5 6 Encontrei a lista [7, 8, 9] Essa lista é composta por: 7 8 9
Segue a saída gerada pelo código acima:Código:listas_nums = [[1, 2, 3], [4, 5, 6], [7, 8, 9]] for lista_num in listas_nums: tamanho = len(lista_num) soma = 0 for num in lista_num: soma = soma + num media = float(soma)/tamanho print 'A média da lista', lista_num, 'é:',media
Código:A média da lista [1, 2, 3] é: 2.0 A média da lista [4, 5, 6] é: 5.0 A média da lista [7, 8, 9] é: 8.0Exercícios
Agora vou deixar alguns exercícios para vocês resolverem:
1. O dicionário abaixo representa uma lista de alunos (chaves) e suas notas (valores). Percorra esse dicionário e calcule a média de cada aluno imprimindo o nome do aluno seguido de sua nota.
alunos = {'fulano':[6, 7, 5, 2], 'sicrano':[7, 8, 9, 8], 'beltrano':[10, 9, 10, 10]}
2. Repita o exercício 1 informando, ao final de tudo, a média da turma.
3. Repita o exercício 2 informando quais alunos foram aprovados (média deve ser maior ou igual a 6).
[Curso de Python] Entendendo o For
10 de Fevereiro de 2010, 0:00 - sem comentários aindaAntes de prosseguir leia os artigos anteriores aqui.
Olá pessoal! Hoje vamos entender mais um pouco da estrutura for. Vamos começar a ver como o for faz a sua mágica e reduz (muito) o trabalho do desenvolvedor!
Entendendo o For
Como já foi comentado no último post, o for parece estranho para quem está acostumado com linguagens como C/C++ e Java. Nessas linguagens, é necessário informar ao for um limite, para que ele saiba quando parar. No Python ele simplesmente sabe quando parar, como isso é feito?
O For funciona somente com objetos iteráveis, isto é, strings comuns, strings unicode, tuplas, listas, byte arrays, sets comuns, frozen sets, e dicionários. Alguns desses tipos ainda não foram abordados nesse curso por não terem um uso muito frequente.
Quando o for recebe um objeto iterável ele usa a função iter para criar um iterador. Um iterador funciona similar a um ponteiro indicando um objeto. Quando solicitamos a esse iterador o próximo objeto ele pula uma "casa" e retorna o próximo objeto. A baixo temos um exemplo dessa idéia:
Ao solicitarmos o próximo objeto, após o final do objeto iterável, recebemos o erro "StopIteration". Com esse erro o for sabe que deve parar a iteração.Código:>>> frase = "teste" >>> ponteiro = iter(frase) >>> type(ponteiro) <type 'iterator'> >>> ponteiro.next() 't' >>> ponteiro.next() 'e' >>> ponteiro.next() 's' >>> ponteiro.next() 't' >>> ponteiro.next() 'e' >>> ponteiro.next() Traceback (most recent call last): File "<stdin>", line 1, in <module> StopIteration >>>
Todos os objetos possuem o mesmo comportamento no for, com exceção do dicionário:
O for retorna somente as chaves de um dicionário, para obtermos o valor associado a aquela chave utilizamos 'slicing':Código:>>> for item in ('abc', 'cde', 'efg'): ... print 'item='+item ... item=abc item=cde item=efg >>> >>> for numero in [1, 2, 3]: ... print 'numero:',numero ... numero: 1 numero: 2 numero: 3 >>> >>> for album in {'Gish':1991, 'Siamese Dream':1993, 'Mellon Collie':1995}: ... print album ... Gish Mellon Collie Siamese Dream >>>
É possível também utilizar o método items, que cria uma lista de tuplas. Segue um exemplo para melhor entendimento:Código:>>> smashing_pumpkins = {'Gish':1991, 'Siamese Dream':1993, 'Mellon Collie':1995} >>> for album in smashing_pumpkins: ... print 'O album',album,'foi lancado em',smashing_pumpkins[album] ... O album Gish foi lancado em 1991 O album Mellon Collie foi lancado em 1995 O album Siamese Dream foi lancado em 1993 >>>
Cada tuplas dentro da lista é um par chave/valor. Se utilizarmos isso dentro do for teremos um resultado bem diferente:Código:>>> smashing_pumpkins.items() [('Gish', 1991), ('Mellon Collie', 1995), ('Siamese Dream', 1993)] >>>
Agora o item a ser retornado passa a ser um tupla com a chave e o valor associado a ela. É possível utilizar o slicing para obter o nome do album e o ano de lançamento, mas existe também um abordagem mais organizada. Para uma melhor legibilidade do código, podemos fazer o 'unpack' (desempacotar) da tupla. O unpack pode ser feito conforme abaixo:Código:>>> smashing_pumpkins = {'Gish':1991, 'Siamese Dream':1993, 'Mellon Collie':1995 } >>> for item in smashing_pumpkins.items(): ... print item ... ('Gish', 1991) ('Mellon Collie', 1995) ('Siamese Dream', 1993) >>>
Dessa forma temos um código limpo, compacto e extremamente legível. Mesmo que ninguém saiba qual o conteúdo do dicionário smashing_pumpkins, ao ler o for, sabe que as chaves são os nomes dos albums e os valores são os anos de lançamento.Código:>>> smashing_pumpkins = {'Gish':1991, 'Siamese Dream':1993, 'Mellon Collie':1995 } >>> for album,ano in smashing_pumpkins.items(): ... print 'O album',album,'foi lançado em',ano ... O album Gish foi lançado em 1991 O album Mellon Collie foi lançado em 1995 O album Siamese Dream foi lançado em 1993 >>>