Exercício 2 - Introdução Python, Numpy, Graphviz.

Autor: ericmsilveira
Data: 07/03/2012

1. Python

O Python é uma linguagem de programação de alto nível. Algumas de suas características são:

  • linguagem interpretada: não é compilada e convertida num executável, ao contrário, ela é executada por um programa que interpreta o código durante a execução
  • tipagem dinâmica: uma variável pode assumir diferentes tipos durante a execução
  • orientada a objetos: suporta a maioria das técnicas de OO
Seus tipos de alto nível são:
  • Lista
  • Tupla
  • String
  • Dicionário
  • Arquivo
  • Classe

Lista: Sequência de valores indexados que podem ser de diferentes tipos. Utiliza-se colchetes na declaração.

 1 L=[4, 1, "texto", 3.1415]
 2 print L
 3 print type(L)
 4 
 5 print "\nTestes de indexação\n"
 6 print "L[2] traz o terceiro elemento"
 7 print L[2]
 8 print "\nL[:2] se refere aos elementos 0 e 1"
 9 print L[:2]
10 print "\nL[-1] se refere ao último elemento"
11 print L[-1]
12 print "\nAlterando o ultimo elemento"
13 L[3]=["outra", "lista"]
14 print L
[4, 1, 'texto', 3.1415000000000002]
<type 'list'>

Testes de indexação

L[2] traz o terceiro elemento
texto

L[:2] se refere aos elementos 0 e 1
[4, 1]

L[-1] se refere ao último elemento
3.1415

Alterando o ultimo elemento
[4, 1, 'texto', ['outra', 'lista']]

Tupla: Sequência de elementos semelhante à lista com a diferença de que ela não pode ser alterada e sua criação é com parênteses ao invés de colchetes.

1 T=(78, 23, "abc")
2 print T
3 print type(T)
4 
5 print "Tentativa de alterar algum valor"
6 T[2]="cba"
ERROR execute
(78, 23, 'abc')
<type 'tuple'>
Tentativa de alterar algum valor
------------------------------------------------------------
*** Exception while evaluating code:
  File "<string>", line 6, in <module>
TypeError: 'tuple' object does not support item assignment

------------------------------------------------------------

String: Sequência imutável de caracteres delimitada por aspas simples, duplas ou triplas. São indexáveis e possuem diversos métodos.

1 S="Lorem ipsum dolor sit amet"
2 print S
3 print type(S)
4 
5 print "\nS[6:17] exibe os elementos da posição 6 até a 16"
6 print S[6:17]
7 
8 print "\nTentativa de alterar algum valor"
9 S[2]="a"
ERROR execute
Lorem ipsum dolor sit amet
<type 'str'>

S[6:17] exibe os elementos da posição 6 até a 16
ipsum dolor

Tentativa de alterar algum valor
------------------------------------------------------------
*** Exception while evaluating code:
  File "<string>", line 9, in <module>
TypeError: 'str' object does not support item assignment

------------------------------------------------------------

Dicionário: É como uma lista, mas, ao invés dos elementos serem associados a índices inteiros e sequenciais, eles são associados a chaves. As chaves podem ser de qualquer tipo imutável.

 1 senhas = {"user_1":4576, "user_2":9987, "user_3":2543}
 2 print senhas
 3 print type(senhas)
 4 
 5 print "\nAs chaves deste dicionário são:"
 6 print senhas.keys()
 7 
 8 print "\nOs valores deste dicionário são:"
 9 print senhas.values()
10 
11 print "\nO valor associado à chave user_2 é"
12 print senhas["user_2"]
13 
14 print "\n"
{'user_2': 9987, 'user_3': 2543, 'user_1': 4576}
<type 'dict'>

As chaves deste dicionário são:
['user_2', 'user_3', 'user_1']

Os valores deste dicionário são:
[9987, 2543, 4576]

O valor associado à chave user_2 é
9987

Arquivo: Um arquivo pode ser aberto para leitura e escrita.

1 A = open(find_attachment_file('arquivo.txt'))
2 print type(A)
3 print "\nAs informações sobre o arquivo lido são:"
4 print A
5 
6 print "\nO conteudo do arquivo:"
7 conteudo = A.read()
8 print conteudo
9 A.close
<type 'file'>

As informações sobre o arquivo lido são:
<open file u'/home/rubens/www/media/Attachments/courseIA368Q1S2012/eri_2/arquivo.txt', mode 'r' at 0x2606540>

O conteudo do arquivo:
Lorem ipsum dolor sit amet, metus pede, lectus mattis.
Nec lorem dictum, lobortis vivamus, suspendisse tellus.

Classe: A Classe possui nome, um conjunto de atributos e métodos.

 1 #nome da classe
 2 class pessoa:
 3     #atributos
 4     nome = None
 5     peso = None
 6     altura = None
 7 
 8     #métodos
 9     def __init__(self, nome, peso, altura):
10         self.nome = nome
11         self.peso = peso
12         self.altura = altura
13 
14     def calcula_imc(self):
15         return self.peso/self.altura**2
16 
17 a = pessoa("João", 85, 1.75)
18 b = pessoa("Maria", 58, 1.6)
19 
20 print a.nome + " tem IMC igual a"
21 print a.calcula_imc()
22 
23 print "\n" + b.nome + " tem IMC igual a"
24 print b.calcula_imc()
João tem IMC igual a
27.7551020408

Maria tem IMC igual a
22.65625
Importância da Identação

O uso de identação é obrigatório em Python já que ela é responsável por fazer a separação entre os blocos de código. Portanto não se usa {} ou BEGIN END como em outras linguagens para começar e terminar uma função ou um while, por exemplo. Essa característica ajuda a tornar o código bem legível.

No exemplo de código anterior, onde exemplificou-se o uso de Classes, nota-se a ausência de chaves para delimitar a definição da classe pessoa.

O inicio do programa principal é marcado pela volta de dois niveis na identação.

2. NumPy

O NumPy oferece a possibilidade de trabalhar com arrays multimensionais. Ele extende o Python com os seguintes tipos:

  • bool - Boleano (True or False) armazenado como um byte
  • int - Inteiro (32 bits ou 64 bits dependendo da plataforma)
  • int8 - Inteiro variando de -128 até 127
  • int16 - Inteiro variando de -32768 até 32767
  • int32 - Inteiro variando de -2147483648 até 2147483647
  • int64 - Inteiro variando de -9223372036854775808 até 9223372036854775807
  • uint8 - Inteiro sem sinal (0 até 255)
  • uint16 - Inteiro sem sinal (0 até 65535)
  • uint32 - Inteiro sem sinal (0 até 4294967295)
  • uint64 - Inteiro sem sinal (0 até 18446744073709551615)
  • float - Float
  • float16 - Float de meia precisão: 1 bit de sinal, 5 bits de expoente, 10 bits de mantissa
  • float32 - Float de precisão simples: 1 bit de sinal, 8 bits de expoente, 23 bits de mantissa
  • float64 - Float de precisão dupla: 1 bit de sinal, 11 bits de expoente, 52 bits de mantissa
  • complex - Atalho para complex128
  • complex64 - Número complexo, representado por 2 floats de 32 bits (parte real e parte imaginária)
  • complex128 - Número complexo, representado por 2 floats de 64 bits (parte real e parte imaginária)

A seguir alguns exemplos de operações com matrizes:

 1 A = array([(1,2), (3,4)])
 2 B = array([(5,6), (7,8)])
 3 
 4 print "A=\n" + str(A)
 5 print "\nB=\n" + str(B)
 6 
 7 print "\nSoma:"
 8 print A+B
 9 
10 print "\nSubtração:"
11 print A-B
12 
13 print "\nMultiplicação elemento a elemento:"
14 print A*B
15 
16 print "\nMultiplicação matricial:"
17 print dot(A,B)
A=
[[1 2]
 [3 4]]

B=
[[5 6]
 [7 8]]

Soma:
[[ 6  8]
 [10 12]]

Subtração:
[[-4 -4]
 [-4 -4]]

Multiplicação elemento a elemento:
[[ 5 12]
 [21 32]]

Multiplicação matricial:
[[19 22]
 [43 50]]

3. Graphviz: ferramenta de visualização

Criação de Grafos com Graphviz

Um grafo não direcionado:

1. graph G { 0--3
2.           0--1
3.           2--3
4.           2--0 }
/media/_xsb/courseIA368Q1S2012/eri_2/GRVIZ68575_001.png

Um grafo direcionado:

1. digraph G { 1->0->3->4->2->0->2->3
2.             2->1->4 }
/media/_xsb/courseIA368Q1S2012/eri_2/GRVIZ68575_002.png

Atribuição de pesos, cores e formas:

1. digraph G { 0 [label="Zero", shape=box, fontcolor=green]
2.             0->2
3.             0->3 [color=red]
4.             1->0 [label=10]
5.             1->4
6.             2->0
7.             2->1
8.             2->3
9.             3->4 [style=dashed]}
/media/_xsb/courseIA368Q1S2012/eri_2/GRVIZ68575_003.png

Criação de Grafos em Python

Usando a função mmgraphviz e passando como parâmetro o texto usado no GraphViz

 1 grafo = """
 2 digraph G { 0 [label="Zero", shape=box, fontcolor=green]
 3             0->2
 4             0->3 [color=red]
 5             1->0 [label=10]
 6             1->4
 7             2->0
 8             2->1
 9             2->3
10             3->4 [style=dashed]} """
11 
12 mmgraphviz(grafo)
/media/_xsb/courseIA368Q1S2012/eri_2/GRVIZ68575_004.png

Fazendo o grafo programaticamente através do GvGen

 1 grafo = gvgen.GvGen()
 2 grafo.smart_mode = 1
 3 
 4 vert_0 = grafo.newItem("Zero")
 5 vert_1 = grafo.newItem("1")
 6 vert_2 = grafo.newItem("2")
 7 vert_3 = grafo.newItem("3")
 8 vert_4 = grafo.newItem("4")
 9 
10 grafo.newLink(vert_0,vert_2)
11 link_a = grafo.newLink(vert_0,vert_3)
12 grafo.newLink(vert_1,vert_0, "10")
13 grafo.newLink(vert_1,vert_4)
14 grafo.newLink(vert_2,vert_0)
15 grafo.newLink(vert_2,vert_1)
16 grafo.newLink(vert_2,vert_3)
17 link_b = grafo.newLink(vert_3,vert_4)
18 
19 grafo.propertyAppend(vert_0, "fontcolor", "green")
20 
21 grafo.styleAppend("0", "shape", "rectangle")
22 grafo.styleApply("0", vert_0)
23 
24 grafo.styleAppend("a", "color", "red")
25 grafo.styleApply("a", link_a)
26 
27 grafo.styleAppend("b", "style", "dashed")
28 grafo.styleApply("b", link_b)
29 
30 
31 import StringIO
32 fd = StringIO.StringIO()
33 grafo.dot(fd)
34 dottext = fd.getvalue()
35 
36 mmgraphviz(dottext)
/media/_xsb/courseIA368Q1S2012/eri_2/GRVIZ68575_005.png