Introdução ao Python

Python é uma linguagem muito poderosa bastante utilizada em processamento de imagens e aprendizado de máquina. A maioria das bibliotecas de redes neurais profundas possuem interface para Python.

Tipos de variáveis em Python com ênfase nos tipos sequênciais

O Python é uma linguagem de programação de alto nível, interpretada, imperativa, orientada a objetos, de tipagem dinâmica e forte, que possui ainda as seguintes características:

- Não há pré-declaração de variáveis, e os tipos das variáveis são determinados dinamicamente.
- O controle de bloco é feito apenas por indentação; não há delimitadores do tipo BEGIN e END ou { e }.
- Oferece tipos de dados de alto nível: strings, listas, tuplas, dicionários, arquivos, classes.
- É orientada a objetos.

É uma linguagem moderna e adaptada para o desenvolvimento tanto de aplicações genéricas como científicas. Para aplicações científicas, o Python possui um pacote muito importante e eficiente para o processamento de arrays multidimensionais: Numpy.

Em sua forma nativa, o Python suporta os seguintes tipos de variáveis:

Tipo Variável Descrição Exemplo de sintaxe
int Variável inteira a = 103458
float Variável de ponto flutuante pi = 3.14159265
bool Variável booleana - True ou False a = False
complex Variável de número complexo c = 2+3j
str Variável para cadeia de caracteres ASCII a = "Exemplo"
list Lista heterogênea pode alterar os valores lista = [4,'eu',1]
tuple Tupla heterogênea imutável tupla = (1,'eu',2)
dict Conjunto associativo de valores dic = {1:'eu',2:'você'}

Tipos Númericos:

  • Declarando variáveis dos tipos inteiro, booleano, ponto flutuante e complexo e realizando algumas operações simples

In [2]:
a = 3
print (type(a) )
b = 3.14
print (type(b) )
c = 3 + 4j
print (type(c) )
d = False
print (type(d) )
print (a + b )
print (b * c )
print (c / a )


<class 'int'>
<class 'float'>
<class 'complex'>
<class 'bool'>
6.140000000000001
(9.42+12.56j)
(1+1.3333333333333333j)

Observe que em operações envolvendo elementos de tipos diferentes a linguagem realiza a conversão dos elementos ao tipo adequado, conforme a seguinte hierarquia: complexo > ponto flutuante > inteiro

Tipos Sequenciais:

Python possui três tipos sequenciais principais: listas, tuplas e cadeia de caracteres (string).

Strings:

Pode-se declarar strings tanto usando aspas simples como duplas ou triplas. Strings são vetores imutáveis compostos de caracteres. Pode-se calcular o tamanho do string usando-se len.


In [3]:
nome1 = 'Faraday'
nome2 = "Maxwell"
print ('string do tipo:', type(nome1), 'nome1:', nome1, "comprimento:", len(nome1) )


string do tipo: <class 'str'> nome1: Faraday comprimento: 7

String é um vetor imutável de caracteres. É possível indexar um caractere único e é possível aplicar regras consistentes do Python no tratamento de sequências, tais como fatiamento (slicing) e formas de indexação. Em Python, o primeiro elemento é sempre indexado como zero, assim quando tenho um string de 5 caracteres, ele é indexado de 0 a 4. É possível também indexar os elementos da direita para a esquerda utilizando índices negativos. Assim, o último elemento do vetor pode ser indexado pelo índice -1.


In [4]:
print ('Primeiro caractere de ', nome1, ' é: ', nome1[0] )
print ('Último caractere de ', nome1, ' é: ', nome1[-1] )
print ('Repetindo-se strings 3 vezes', 3 * nome1  )


Primeiro caractere de  Faraday  é:  F
Último caractere de  Faraday  é:  y
Repetindo-se strings 3 vezes FaradayFaradayFaraday

Listas:

Lista é uma sequência de elementos de diferentes tipos que podem ser indexados, alterados e operados. Listas são definidas por elementos separados por vírgulas iniciado e terminado por colchetes.


In [5]:
lista1 = [1, 1.1, 'um'] # Listas podem conter elementos de diferentes tipos.
lista2 = [3+4j, lista1] # Inclusive uma lista pode conter outras listas como elementos!
print ('tipo da lista1=', type(lista1) )
print ('lista2=', lista2 )
lista2[1] = 'Faraday' #Diferentemente das strings, pode-se atribuir novos valores a elementos da lista.
print ('lista2=', lista2 )
lista3 = lista1 + lista2 # Concatenando 2 listas
print ('lista3=',lista3 )
print ('concatenando 2 vezes:',2*lista3 )


tipo da lista1= <class 'list'>
lista2= [(3+4j), [1, 1.1, 'um']]
lista2= [(3+4j), 'Faraday']
lista3= [1, 1.1, 'um', (3+4j), 'Faraday']
concatenando 2 vezes: [1, 1.1, 'um', (3+4j), 'Faraday', 1, 1.1, 'um', (3+4j), 'Faraday']

Tuplas:

Tupla é similar a lista, porém seus valores são imutáveis. Tupla é uma sequência de objetos separados por vírgulas que podem, opcionalmente, serem iniciados e terminados por parênteses. Tupla contendo um único elemento precisa ser seguido de uma vírgula.

note: O entendimento da tupla é muito importante e ela será bastante utilizada neste curso, pois muitos parâmetros do ndarray do NumPy são setados utilizando tuplas.


In [6]:
#Declarando tuplas
tupla1 = () # tupla vazia
tupla2 = ('Gauss',)  # tupla com apenas um elemento. Note a vírgula.
tupla3 = (1.1, 'Ohm', 3+4j)
tupla4 = 3, 'aqui', True
print ('tupla1=', tupla1 )
print ('tupla2=', tupla2 )
print ('tupla3=', tupla3 )
print ('tupla4=', tupla4 )
print ('tipo da tupla3=', type(tupla3) )


tupla1= ()
tupla2= ('Gauss',)
tupla3= (1.1, 'Ohm', (3+4j))
tupla4= (3, 'aqui', True)
tipo da tupla3= <class 'tuple'>

Slicing em tipos sequenciais

Além dos tipos sequenciais como listas, tuplas e strings poderem ser indexados, é possível também selecionar subconjuntos através do conceito de slicing (fatiamento).

Por exemplo:


In [7]:
s = 'abcdefg'
print ('s=',s )
print ('s[0:2] =', s[0:2] )  # caracteres a partir da posição 0 (inclusivo) até 2 (exclusivo)
print ('s[2:5] =', s[2:5] )  # caracteres a partir da posição 2 (inclusivo) até 5 (exclusivo)


s= abcdefg
s[0:2] = ab
s[2:5] = cde

Quando o início for zero e o final for o comprimento do string, ele pode ser omitido. Veja os exemplos:


In [8]:
s = 'abcdefg'
print ('s=',s )
print ('s[:2] =', s[:2] )  # caracteres a partir do início até 2 (exclusivo)
print ('s[2:] =', s[2:] )  # caracteres a partir da posição 2 (inclusivo) até o final do string
print ('s[-2:] =', s[-2:] )# últimos 2 caracteres


s= abcdefg
s[:2] = ab
s[2:] = cdefg
s[-2:] = fg

Note que a posição de início é sempre inclusiva e a posição final é sempre exclusiva. Isto é feito para que a concatenação entre s[:i] e s[i:] seja igual a s.

O slicing permite ainda um terceiro valor que é opcional: step.

Para quem é familiarizado com a linguagem C, os 3 parâmetros do slicing é similar ao for:

comando for slicing
for (i=inicio; i < fim; i += passo) a[i] a[inicio:fim:passo]

Veja exemplos de indexação usando slicing num string de 7 caracteres, indexados de 0 a 6:

slice indices explicação
0:5 0,1,2,3,4 vai de 0 até 4 que é menor que 5
2:5 2,3,4 vai de 2 até 4
0:5:2 0,2,4 vai de 0 até 4, pulando de 2 em 2
::2 0,2,4,6 vai do início até o final de 2 em 2
:5 0,1,2,3,4 vai do início até 4, que é menor que 5
3: 3,4,5,6 vai de 3 até o final
::-1 6,5,4,3,2,1,0 vai do final (6) até o início

Veja estes exemplos aplicados no string 'abcdefg':


In [9]:
s = 'abcdefg'
print ('s=',s )
print ('s[2:5]=',  s[2:5] )
print ('s[0:5:2]=',s[0:5:2] )
print ('s[::2]=',  s[::2] )
print ('s[:5]=',   s[:5] )
print ('s[3:]=',   s[3:] )
print ('s[::-1]=', s[::-1] )


s= abcdefg
s[2:5]= cde
s[0:5:2]= ace
s[::2]= aceg
s[:5]= abcde
s[3:]= defg
s[::-1]= gfedcba

Este conceito de slicing será essencial neste curso. Ele pode ser aplicado em strings, tuplas, listas e principalmente no ndarray do NumPy. Procure entendê-lo integralmente.

Atribuição em tipos sequenciais

Tanto strings, tuplas como listas podem ser desempacotados através de atribuição. O importante é que o mapeamento seja consistente. Lembrar que a única sequência que é mutável, isto é, pode ser modificada por atribuição é a lista. Procure estudar os exemplos abaixo:


In [10]:
s = "abc"
s1,s2,s3 = s
print ('s1:',s1 )
print ('s2:',s2 )
print ('s3:',s3 )
list = [1,2,3]
t = 8,9,True
print ('list=',list )
list = t
print ('list=',list )
(_,a,_) = t
print ('a=',a )


s1: a
s2: b
s3: c
list= [1, 2, 3]
list= (8, 9, True)
a= 9

Formatação de string para impressão

Um string pode ser formatado de modo parecido com a sintaxe do sprintf em C/C++ na forma: string % tupla. Iremos usar bastante este modelo para colocar legendas nas imagens. Exemplos:


In [11]:
s = 'formatação inteiro:%d, float:%f, string:%s' % (5, 3.2, 'alo')
print (s )


formatação inteiro:5, float:3.200000, string:alo

Outros tipos

Existem ainda os Dicionários e Conjuntos, entretanto eles não serão utilizados durante este curso.

Dicionários:

Dicionários podem ser definidos como sendo listas associativas que ao invés de associar os seus elementos a índices númericos, associa os seus elementos a palavras-chave.

  • Declarando dicionários e realizando algumas operações simples

In [12]:
dict1 = {'blue':135,'green':12.34,'red':'ocean'} #definindo um dicionário
print(type(dict1))
print(dict1)
print(dict1['blue'])
print(dict1.keys()) # Mostra as chaves do dicionário
del dict1['blue'] # Deleta o elemento com  a chave 'blue'
print(dict1.keys()) # Mostra as chaves do dicionário após o elemento com a chave 'blue' ser apagado


<class 'dict'>
{'blue': 135, 'green': 12.34, 'red': 'ocean'}
135
dict_keys(['blue', 'green', 'red'])
dict_keys(['green', 'red'])

Conjuntos

Conjuntos são coleções de elementos que não possuem ordenação e também não apresentam elementos repetidos.

  • Declarando conjuntos e realizando algumas operações simples

In [13]:
lista1 = ['apple', 'orange', 'apple', 'pear', 'orange', 'banana'] 
lista2 = ['red', 'blue', 'green','red','red']
conjunto1 = set(lista1) # Definindo um conjunto
conjunto2 = set(lista2)
print(conjunto1) # Observe que os elementos repetidos são contados apenas uma vez
print(type(conjunto1))
print(conjunto1 | conjunto2) # União de 2 conjuntos


{'apple', 'banana', 'orange', 'pear'}
<class 'set'>
{'apple', 'banana', 'orange', 'green', 'pear', 'red', 'blue'}

A importância da indentação na linguagem Python:

Diferentemente das outras linguagens que utilizam palavras-chave como begin e end ou chaves {, } para delimitar seus blocos (if, for, while, etc.), a linguagem Python utiliza a indentação do código para determinar quais comandos estão aninhados dentro de um bloco, portanto a indentação é de fundamental importância na linguagem Python.


In [14]:
#Ex1: O último comando print (executa independentemente do valor de x
x = -1
if x<0:
   print('x é menor que zero!')
elif x==0:
   print('x é igual a zero')
else:
   print('x é maior que zero!')
print('Esta frase é escrita independentemente do valor de x')

#Ex2: Os dois últimos comandos print (estão dentro do laço devido a
#indentação, portanto só executam se x for maior que zero
if x<0:
   print('x é menor que zero!')
elif x==0:
   print('x é igual a zero')
else:
   print('x é maior que zero!')
   print('Esta frase é escrita apenas para x maior que zero')


x é menor que zero!
Esta frase é escrita independentemente do valor de x
x é menor que zero!

Loops

Loop for

Iterando numa lista de strings


In [15]:
browsers = ["Safari", "Firefox", "Google Chrome", "Opera", "IE"]
for browser in browsers:
    print (browser )


Safari
Firefox
Google Chrome
Opera
IE

Iterando numa lista de inteiros


In [16]:
numbers = [1,10,20,30,40,50]
sum = 0
for number in numbers:
    sum = sum + number
print (sum )


151

Iterando nos caracteres de uma string


In [17]:
word = "computer"
for letter in word:
    print (letter )


c
o
m
p
u
t
e
r

Iterando num iterador - xrange

Loop while

O loop while executa até que uma condição de parada seja atingida.


In [19]:
browsers = ["Safari", "Firefox", "Google Chrome", "Opera", "IE"]
i = 0
while i < len(browsers) and i>=0: # Duas condições para que o loop continue
    print (browsers[i] )
    i = i + 1


Safari
Firefox
Google Chrome
Opera
IE

Loops aninhados

É possível aninhar loops, note que a indentação é importante para saber dentro de qual loop o comando se encontra.


In [22]:
for x in range(1, 4):
    for y in range(1, 3):
        print ('%d * %d = %d' % (x, y, x*y) )
    print ('Dentro do primeiro for, mas fora do segundo' )


1 * 1 = 1
1 * 2 = 2
Dentro do primeiro for, mas fora do segundo
2 * 1 = 2
2 * 2 = 4
Dentro do primeiro for, mas fora do segundo
3 * 1 = 3
3 * 2 = 6
Dentro do primeiro for, mas fora do segundo

Funções em Python

Sintaxe para definir funções

As funções em Python utilizam a palavra chave def seguida do nome da função e os parâmetros entre parêntesis terminado por dois pontos como no exemplo a seguir onde a função soma é definida para retornar a soma de seus dois parâmetros. Observe que o corpo da função é indentado da definição da função:


In [23]:
def soma( x, y):
    s = x + y
    return s

Para se realizar a chamada da função soma, basta utilizá-la pelo seu nome passando os parâmetros como argumentos da função. Veja o exemplo a seguir


In [24]:
r = soma(50, 20)
print (r )


70

Parâmetros da função

Existem dois tipos de parâmetros: posicional e com palavra chave. Os posicionais são aqueles que são identificados pela ordem em que aparecem na lista dos parâmetros da função. Já os com palavra chave, são identificados por nome=. Os parâmetros por palavra chave podem também ser posicionais, mas tem a vantagem que se não forem passados, ele assumem o valor mencionado por falta (default). Veja o exemplo abaixo:


In [25]:
def soma( x, y, squared=False):
    if squared:
        s = (x + y)**2
    else:
        s = (x + y)
    return s

Observe que os parâmetros, x e y são posicionais e serão os 2 primeiros argumentos da chamada da função. O terceiro parâmetro é por palavra chave e portanto opcional, posso usá-lo tanto na forma posicional, como na forma explícita com a palavra chave. A grande vantagem neste esquema é que posso ter um grande número de parâmetros com palavra chave e na hora de usar a função deixar explicitamente só os parâmetros desejados.

Veja os exemplos:


In [26]:
print ('soma(2, 3):', soma(2, 3) )
print ('soma(2, 3, False):', soma(2, 3, False) )
print ('soma(2, 3, True):', soma(2, 3, True)  )
print ('soma(2, 3, squared= True):', soma(2, 3, squared= True)  )


soma(2, 3): 5
soma(2, 3, False): 5
soma(2, 3, True): 25
soma(2, 3, squared= True): 25

Referências

As referências a seguir são da documentação oficial do Python. Neste curso, iremos utilizar muito pouco de sua biblioteca padrão, assim não há necessidade (nem condições) de se estudar estas referências todas. O nosso foco neste curso será no NumPy e aos poucos iremos oferecer estes materiais.