Introdução aos conceitos e Ferramentas

Neste exercício procura compreender algumas questões referentes a programacão em Python, a utilização da biblioteca Numpy e a ferramenta Graphviz para vizualização de grafos.

Python

Como introdução, o python é uma linguagem de programação de alto nível, interpretada, imperativa, orientada a objetos, de tipagem dinâmica e forte[1]. Dentre os vários tipos de variáveis que possuem, quatro delas podem ser caracterizadas como de alto nível. São elas:

  • listas

A lista é um conjunto (ou seqüência) de valores acessados (indexados) por um índice numérico, inteiro, começando em zero[2]. A lista em Python pode armazenar valores de qualquer tipo e são construidas com colchetes, observe o exemplo:

1 lista = [1, 2, 3,"G","i","o","v","a","n","i"," - GIOVANI - "]
2 print lista
3 lista[1] = lista[10]
4 print lista
[1, 2, 3, 'G', 'i', 'o', 'v', 'a', 'n', 'i', ' - GIOVANI - ']
[1, ' - GIOVANI - ', 3, 'G', 'i', 'o', 'v', 'a', 'n', 'i', ' - GIOVANI - ']
  • tuplas

No caso das tuplas, seu comportamento é semelhante a lista, no entanto existe uma peculiaridade de que uma vez criadas não podem ser alteradas, denominadas de imutáveis. Veja o exemplo demonstrando esta propriedade, e note que sua construção é feita com parentes diferentemente das listas:

1 tupla = (1, 2, 3,"G","i","o","v","a","n","i"," - GIOVANI - ")
2 print tupla
3 tupla[1] = tupla[10] # Este trecho de código irá gerar um erro, devido a propriedade apresentada.
4 print tupla
ERROR execute
(1, 2, 3, 'G', 'i', 'o', 'v', 'a', 'n', 'i', ' - GIOVANI - ')
------------------------------------------------------------
*** Exception while evaluating code:
  File "<string>", line 3, in <module>
TypeError: 'tuple' object does not support item assignment

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

  • strings

A string é uma cadeia de caracteres bastante conhecida entre os programadores. Uma caracterísca é que este tipo de variável no python possui a propriedade abordada anteriormente, ela é uma seqüência imutável, alocada dinamicamente, sem restrição de tamanho[2]. Observe um simples exemplo deste tipo de variável:

1 stringss = " - GIOVANI - "
2 print stringss
- GIOVANI -
  • dicionários

Segundo[2], dicionários são seqüências que podem utilizar índices de tipos variados, bastando que estes índices sejam imutáveis. Demonstração da manipulação deste tipo de variável:

1 dic = {"MARCA":"fiat", "MODELO":"punto", "COR":"branco", "RPM":"3000rpm"}
2 print dic
3 print dic["MODELO"]
4 dic["MODELO"] = "bravo"
5 print dic
{'RPM': '3000rpm', 'COR': 'branco', 'MODELO': 'punto', 'MARCA': 'fiat'}
punto
{'RPM': '3000rpm', 'COR': 'branco', 'MODELO': 'bravo', 'MARCA': 'fiat'}
Demonstrado os tipos de variáveis de alto nível que irá encontrar na programação em python, uma crucial característica desta linguagem é o uso da identação. O python obriga o programador a estruturar o código de forma identada, não havendo a necessidade de se utilizar qualquer tipo de caracter para delimitar o escopo de uma dada instrução. Observe um exemplo:
1 i=0
2 
3 # laço de repetição identado
4 while i < 5:
5     print i
6     i = i+1
0
1
2
3
4

Numpy

NumPy é um pacote para a linguagem Python que suporta arrays e matrizes multidimensionais, possuindo uma larga coleção de funções matemáticas para trabalhar com estas estruturas. Sua principal caracteristica é a concepção de raciocínio e modelagem de maneira matricial, tornando os códigos mais legíveis e curtos.
 1 a = array([[1, 2, 3],[4, 5, 6],[7, 8, 9]]) # cria uma matriz de dim. 3x3
 2 print "\n a - Matriz: \n"
 3 print a
 4 
 5 a.resize((3,4)) # altera o objeto a, novas posições são preenchidas com zero
 6 print "\n a - Matriz resize (3,4): \n"
 7 print a
 8 
 9 b = array([[1, 2, 3],[4, 5, 6],[7, 8, 9]])
10 print "\n b - Matriz: \n"
11 print b
12 
13 c = resize(b, (3,4)) # retorna um objeto com tamanho (3,4) e com as posições preenchidas a partir de b
14 print "\n c - Matriz resize (3,4): \n"
15 print c
a - Matriz: 

[[1 2 3]
 [4 5 6]
 [7 8 9]]

 a - Matriz resize (3,4): 

[[1 2 3 4]
 [5 6 7 8]
 [9 0 0 0]]

 b - Matriz: 

[[1 2 3]
 [4 5 6]
 [7 8 9]]

 c - Matriz resize (3,4): 

[[1 2 3 4]
 [5 6 7 8]
 [9 1 2 3]]
Exemplos de slicing: - Slicing é o termo utilizado para a extração e inserção de sub-matrizes. Em Python, o slicing é muito parecido com MATLAB, e também pode ser operado sobre listas. A sintaxe utilizada difere na ordem dos parâmetros. Em Python, o slicing é feito com mylist[primeiro_elemento:ultimo_elemento:passo]. Deve-se lembrar que o intervalo utilizado é do tipo [primeiro,ultimo), ou seja, o ultimo indice dado não é incluido. O primeiro índice, se for zero é opcional, e o passo se for 1 também é opcional.
1 ex = ones((10,10))
2 ex[3:6,3:6] = zeros((3,3)) # atribui uma matriz 3x3 a um bloco 3x3 do quarto ao sexto elemento na linha e coluna
3 ex[4:9:2,4:9:3]= 2 # atribui a constante 2 do quinto elemento até o nono, andando de dois em dois nas linhas e 3 em 3 nas colunas
4 print "\n ex - Matriz exemplo: \n"
5 print ex
ex - Matriz exemplo: 

[[ 1.  1.  1.  1.  1.  1.  1.  1.  1.  1.]
 [ 1.  1.  1.  1.  1.  1.  1.  1.  1.  1.]
 [ 1.  1.  1.  1.  1.  1.  1.  1.  1.  1.]
 [ 1.  1.  1.  0.  0.  0.  1.  1.  1.  1.]
 [ 1.  1.  1.  0.  2.  0.  1.  2.  1.  1.]
 [ 1.  1.  1.  0.  0.  0.  1.  1.  1.  1.]
 [ 1.  1.  1.  1.  2.  1.  1.  2.  1.  1.]
 [ 1.  1.  1.  1.  1.  1.  1.  1.  1.  1.]
 [ 1.  1.  1.  1.  2.  1.  1.  2.  1.  1.]
 [ 1.  1.  1.  1.  1.  1.  1.  1.  1.  1.]]
Para exemplificar a utilização da abordagem matricial proporcionada pelo python juntamente com as ferrametnas do numpy, foi realizado uma função que gera o tabuleiro de xadrez aplicando técnicas que não necessitam da formulação do laço de repetição para seu processamento. Observe o exemplo abaixo utilizando a função resize e concatenate:
 1 from numpy import *
 2 import time
 3 
 4 #-------------------------------------------------------------
 5 def chess_resize(s,t):
 6 
 7     # cria duas linhas e faz o resize
 8     r = uint16(arange(s[1])/t[1]) % 2 # Gera a linha de pixel com a largura do quadrado
 9 
10     print r
11     mmshow(r,title="Imagem da linha criada")
12 
13     r = resize(r,(t[0],s[1]))         # Gera a a altura do ladrilho a partir da linha feita no passo anterior
14 
15     print r
16     mmshow(r,title="Imagem do ladrilho gerado")
17 
18     r = concatenate((r,1-r), axis=0)  # concatena a linha modelo para resize...
19     return resize(r, s)
20 
21 #-------------------------------------------------------------
22 
23 t1 = time.time()
24 ex1 = chess_resize((200,200),(10,25))
25 t2 = time.time()
26 mmshow(ex1, title="ex1 - Xadrez 200x200 - Tempo: " + str(t2-t1) + "s  ")
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1
 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0
 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1
 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1]
[[0 0 0 ..., 1 1 1]
 [0 0 0 ..., 1 1 1]
 [0 0 0 ..., 1 1 1]
 ..., 
 [0 0 0 ..., 1 1 1]
 [0 0 0 ..., 1 1 1]
 [0 0 0 ..., 1 1 1]]

Imagem da linha criada

Imagem do ladrilho gerado

ex1 - Xadrez 200x200 - Tempo: 0.00735688209534s

Graphviz

O Graphviz é uma ferramenta para geração e visualização de estruturas como grafos, redes entre outros. Como forma de aprendizagem desta ferramenta, será abordado nesta seção algumas práticas de programação exemplificando sua utilização.

  • Iremos começar com a declaração simples entre dois nós.
1 grafo = """
2     digraph G {
3         edge1[label="Espaço de Imagem", color= blue]
4         edge2[label="Espaço de atributos", color= red]
5         edge1 -> edge2 [label = "transformação"]
6     }
7 """
8 
9 mmgraphviz(grafo, title='Ligação entre dois nós')
/media/_xsb/courseIA368Q1S2012/gio_2/GRVIZ35118_001.png

Ligação entre dois nós

  • Configurando este diagrama para ficar dispostos horizontalmente:
 1 grafo = """
 2     digraph G {
 3         edge1[label="Espaço de Imagem", color= blue]
 4         edge2[label="Espaço de atributos", color= red]
 5         edge1 -> edge2 [label = "transformação"]
 6 
 7         {rank=same; edge1 edge2}
 8     }
 9 """
10 
11 mmgraphviz(grafo, title='Ligação entre dois nós')
/media/_xsb/courseIA368Q1S2012/gio_2/GRVIZ35118_002.png

Ligação entre dois nós

  • Agora vamos apresentar algumas ramificações do grafo de forma organizada:
 1 grafo = """
 2     digraph G {
 3         subgraph clusterImage {
 4             edge11 [label="Filtro sobel"];
 5             edge12 [label="Watershed"];
 6             edge13 [label="extração de features"];
 7             edge11 -> edge12 -> edge13
 8         }
 9         subgraph clusterAtributos {
10             edge21 [label="SVM"];
11             edge22 [label="OPF"];
12             edge23 [label="REDES NEURAIS"];
13 
14 
15         }
16         edge1[label="Espaço de Imagem", color= blue]
17         edge2[label="Espaço de atributos", color= red]
18         edge1 -> edge2 [label = "transformação"]
19         edge1 -> edge11
20 
21         edge2 -> edge21
22         edge2 -> edge22
23         edge2 -> edge23
24 
25         {rank=same; edge1 edge2}
26 
27     }
28 """
29 
30 mmgraphviz(grafo, title='Árvore de Processos')
/media/_xsb/courseIA368Q1S2012/gio_2/GRVIZ35118_003.png

Árvore de Processos


[1] Definição fornecida pela Wikipédia: http://pt.wikipedia.org/wiki/Python

[2] Definição fornecida pelo Curso de programação em Python: http://www.async.com.br/projects/python/pnp/node7.html