Tutorial Básico de Programação em Python
Tutorial Básico de Programação em Python
Linguagem Python
??/??/2021
Introdução
Neste tutorial será apresentado os conceitos básicos da linguagem de programação
Python. Não é necessário possuir nenhum conhecimento prévio em outras linguagens de
programação.
Python é uma linguagem de alto nível criada com o intuito de ser uma linguagem
simples de se aprender, fácil de ler e concisa. Foi criada em 1992 por Guido van Rossum e
desde então é desenvolvida de forma comunitária com a liderança da Python Software
Foundation.
Configurando o ambiente
Para este tutorial será utilizado a plataforma online [Link] que pode ser encontrada
no seguinte site: [Link] Ao acessar a página deve-se clicar em start coding. Em
seguida será pedido que você crie uma conta, faça isso e siga os passos que o próprio site
fornece. Na hora de escolher as linguagens deve-se escolher a linguagem python e mais
outras duas de sua preferência, pois o site exige que se escolha ao menos três. No meu
caso ficou como na figura a seguir:
2
Em seguida será pedido que você verifique sua conta e faça uma introdução sobre
você mesmo, mas isso é opcional. Para os objetivos deste tutorial você deve selecionar a
opção Python logo após a linha “or start coding” como indicado na próxima figura.
3
Você será levado para uma nova página destinada a programação em Python.
No painel mais à esquerda são mostrados os nomes dos arquivos que estão sendo
editados. Ao abrir pela primeira vez provavelmente haverá apenas o arquivo [Link]. No
painel do meio é a área de edição, onde pode-se escrever ou modificar o código Python.
Por fim, no painel mais à direita fica o terminal contendo o REPL da linguagem e também
onde aparecem os resultados da execução do programa.
4
> 2 + 2
4
Hello World
Na programação é comum que ao se iniciar o aprendizado de alguma linguagem o
primeiro programa escrito seja um “Hello World”, e é exatamente isso que será realizado
neste tutorial. O programa em Python pode ser escrito da seguinte forma:
print("Hello world")
5
Para facilitar a leitura do código pode-se adicionar comentários ao código que serão
ignorados pelo interpretador. Para isso deve-se usar o símbolo # em alguma posição da
linha, tudo escrito entre esse símbolo e o final da linha será considerado um comentário.
# Isso é um comentário
print("Oi amigo") # Outro comentário
# Isso também é um comentário
Variáveis
Uma das coisas mais básicas que um programa de computador deve ser capaz de
realizar é armazenar e modificar valores em memória. Para isso é feito uso das chamadas
variáveis. Uma variável pode ser criada em Python a partir do seguinte código:
a = 15
print(a)
No trecho de código cria-se uma variável chamada a e atribui-se a ela o valor 15. Na
linha seguinte usa-se o comando print para exibi-la. O nome de uma variável pode ter
qualquer comprimento desde que comece com uma letra, ou _, e não utilize nenhum
símbolo não alfanumérico. valor, rato1, grafenó, Aphex_Twin e x_ são exemplos de
nomes válidos. pão quadrado, 123gameplays, tatu#mola? e pula-pula exemplos de
nomes inválidos.
A partir da linha em que se declara uma variável é possível modificar o seu valor,
veja a seguir.
var1 = 15
print(var1)
var1 = 23
print(var1)
var1 = var1 + 1
print(var1)
6
Nesse último exemplo declara-se a variável var1 com o valor 15, exibe-a, altera-se
seu valor para 23 e a exibe novamente. Na linha seguinte, var1 = var1 + 1, a variável é
modificada tal que seu novo valor é o valor antigo somado de 1, ou seja, 24. Lembrando
que só se pode usar uma variável do lado direito do sinal de atribuição(=) se a mesma tiver
sido declarada anteriormente.
Também pode-se declarar variáveis com valores não numéricos como, por exemplo,
texto. Esses valores de texto devem ser escritos entre aspas simples ou duplas e são
chamados de strings.
b = "Hello World"
print(b)
a = 12
b = 123432
c = 99999
a = 12.3
b = 0.6
c = 0.0000001
a = 5 + 7 # soma
b = 3.5 - 1 # subtração
c = a * 10 # multiplicação
d = b/2 # divisão
7
Tentar realizar uma operação matemática entre tipos não numéricos causará um
erro e o programa não será executado.
a = "oi"
b = 1
c = a + b # causa um erro
nome = "Zbigniew"
sobre_nome = "Preisner"
nome_completo = nome + sobre_nome
print(nome_completo)
Ao executar esse código será exibido ZbigniewPreisner tudo junto. Isso ocorre
porque ambas as strings foram simplesmente unidas sem um espaço entre elas. Para
contornar esse problema, pode-se modificar a terceira linha para
Às vezes também pode ser necessário converter um valor numérico para string e
vice-versa. Para isso é muito simples, basta usar os comandos int() float() e str().
inteiro = 12
versao_texto = str(inteiro)
print("o numero é " + versao_texto)
uma cópia de seu valor convertido para string. Por isso, mesmo após e execução do
comando str(), a variável inteiro continua com um valor do tipo numérico.
O contrário também é válido, pode-se converter uma variável de tipo string para um
valor inteiro ou real.
var1 = "12"
var2 = "23.1"
a = int(var1)
b = float(var2)
print(a + b)
Para converter uma string para inteiro usa-se o comando int() e uma string para
real, float(). Uma string só pode ser convertida para um desses valores se ela contiver
um texto que represente um número, caso contrário será gerado um erro.
a = "123/3"
b = "2321a"
c = "zero"
x = float(a) # Erro
y = int(b) # Erro
c = int(c) # Erro
Interpolação de Strings
O operador “%” pode ser usado para realizar interpolação de strings. Representa uma
forma alternativa a concatenação para compor variáveis, constantes e strings em uma
nova string. Durante a interpolação símbolos especiais dentro da string são substituídos
por valores indicados entre parênteses após o operador “%”. Por exemplo:
Observe ao executar o código que o primeiro símbolo “%s” dentro da string foi substituído
pela string na variável nome, a primeira indicada entre os parênteses. Da mesma forma o
segundo símbolo “%s”. Já o símbolo “%d” foi substituído pelo valor inteiro da terceira
variável convertido para string.
Os símbolos disponíveis para substituição são os seguintes:
● %s: string
● %d: inteiro
● %o: inteiro em formato octal
● %x: inteiro em formato hexadecimal
● %f: números de ponto flutuante
● %e: números em notação científica
● %%: caso queira inserir o sinal de porcentagem.
F-Strings
Uma alternativa a interpolação de strings são as F-Strings. São semelhantes as
strings literais porém, seguem o formato f”conteúdo” em vez de “conteúdo”. Ao se colocar o
nome de uma variável entre chaves dentro do conteúdo de uma F-String seu valor é
convertido para string e inserido na mesma. Por exemplo:
nome = "Krzysztof Kieślowski"
nacionalidade = "polonês"
obra = "Trilogia das cores"
frase = f"{nome} é um famoso cineasta {nacionalidade} conhecido pela obra \
{obra}"
print(frase)
Entrada de Dados
Uma outra tarefa muito importante que os programas de computador devem
realizar é a leitura de dados inseridos pelo usuário. Para isso existe o comando input()
que ao ser executado pausa o programa e exibe uma mensagem pedindo que seja digitado
algo. Após ser digitado e ser pressionado Enter o comando retornará uma string contendo
o que foi digitado. Um exemplo deixará mais claro:
a = input("digite algo")
print("Eu digitei isso: " + a)
programa terminará sua execução e será exibido a mensagem "Eu digitei isso: privada
polonesa giratória".
Observe que como o valor retornado por input() é uma string, é necessário
convertê-lo para um tipo inteiro antes de usá-lo em uma expressão matemática. Também
vale ressaltar que se o usuário digitar um valor não numérico o programa irá ser abortado
com um erro.
Expressões Booleanas
Expressões booleanas são expressões cujo valor resultante é verdade ou falso. Por
exemplo, a expressão a seguir gera um valor falso, pois 2 não é maior que 4.
2 > 4
● and
○ Resulta em verdadeiro se ambos os operandos são verdadeiros, falso caso
contrário.
● or
○ Resulta em falso se ambos operandos são falsos, verdade caso contrário.
● not
○ Inverte o valor do operador.
operador descrição
11
== Igual
!= Diferente
Condicionais
if e else
Em certos casos pode querer-se executar um trecho de código apenas quando uma
certa condição for satisfeita. Para isso se faz uso das expressões condicionais através das
palavras-chave if e else.
if 2 > 4:
print("2 é maior que 4")
a = 12
if a == 12:
print("a é igual a 12")
12
Nesse outro exemplo, a linha 3 só será executada se a variável a for igual a 12, o
que é verdade nesse caso. Logo, a mensagem “a é igual a 12” será exibida. Lembrando que,
para realizar-se comparação de igualdade, deve-se usar dois sinais de igual, isto é, ==.
a = "zig"
if a == "zig":
print("zag")
x = -10
if x < 0:
x = -x;
print("módulo de x é " + str(x))
print("Essa linha é sempre executada")
Em outras ocasiões pode ser útil ter um trecho de código que só será executado se
a expressão no if não for verdadeira. Para isso faz-se uso da palavra-chave else. Importante
ressaltar que para todo else deve haver um if.
Nesse exemplo é verificado se x é ímpar ou par. Para isso, lê-se x como um número
digitado pelo usuário e no if é verificado o resultado do resto da divisão de x por 2. Se for 0,
quer dizer que o número é par, caso contrário o código do bloco else será executado,
indicando que o número é ímpar.
elif
Outra palavra chave importante é elif que representa uma condição alternativa ao if,
um exemplo deixará mais claro.
print("VOCÊ É MOLEQUE!")
elif idade < 40:
print("você é adulto")
elif idade < 90:
print("você é velho")
elif idade < 120:
print("nossa...")
else:
print("para de mentir")
O trecho de código funciona da seguinte forma. Primeiro a variável é lida como uma
entrada do usuário. Em seguida, na linha 3, é verificado se o valor de idade é menor que 20.
Caso seja, a linha 3 é executada e o programa se encerra. Caso não seja verdade, na linha 5
é verificado se é menor que 40. Se for menor, então a próxima linha é executada e o
programa se encerra, caso contrário, passa-se ao elif seguinte e assim por diante. Caso
nenhum dos elifs sejam satisfeitos então o else será executado.
Laços de Repetição
Outra funcionalidade básica que uma linguagem de programação deve fornecer é a
capacidade de que um mesmo código possa ser executado repetidas vezes. Os principais
tipos de laços são o while e o for.
while
O laço while executa repetidamente um trecho de código enquanto uma expressão
booleana for verdadeira. No exemplo a seguir, a variável x é exibida enquanto seu valor for
menor que 10.
a = 0
while a < 10:
print(a)
a = a + 1
print("fim")
for
O laço for é parecido com o laço while, porém ele é utilizado, de forma simplificada,
para um número fixo de repetições. Ele é formado pela palavra chave for seguido de um
nome uma variável, palavra chave in e o comando range.
for a in range(10):
print(a)
for a in range(12):
print(a) # a assume valores de 0 a 11
for a in range(3, 10):
print(a) # a assume valores de 3 a 9
for a in range(4, 13, 2):
print(a) # a assume valores de 4 a 12, porém de 2 em 2.
soma = 0
for x in range(4):
valor = float(input("digite um número: "))
soma += valor
print("A soma é " + str(soma))
break
Em algumas ocasiões pode-se querer sair de uma laço antes que o mesmo termine.
Para isso é usado a palavra-chave break. A seguir um exemplo de um programa que exibe a
raiz de um número digitado pelo usuário caso este seja positivo e caso contrário o
programa interrompe a sua execução.
while True:
a = float(input("Entre com com um número: "))
if a < 0:
break
else:
15
print(a**0.5)
Escopos
Um conceito muito importante em linguagens de programação é o de escopo. O
papel dele é indicar, basicamente, onde pode-se utilizar uma variável declarada. Considere
o seguinte exemplo.
a = 12
if True:
print(a)
Observe que a foi declarado fora de qualquer tipo de estrutura como if ou for.
Nesse caso pode-se usar a variável em qualquer lugar do programa, pois ela foi declarada
no que é conhecido como Escopo Global. Porém observe o próximo exemplo.
if True:
a = 12
print(a)
Esse código resultará em um erro, pois a foi declarada em um escopo interno e está
tentando usá-la no escopo global. Porém a variável poderia ser utilizada em um escopo
mais interno:
if True:
a = 12
for i in range(4):
print(a)
Listas
Muitas vezes pode ser útil ter a capacidade de representar um conjunto de valores
em uma única variável. Para isso existem as listas, que consistem em vários valores entre
colchetes e separados por vírgula.
lista1 = [1, 2, 3, 4]
lista2 = ["oi", "meu", "chapa"]
16
print(lista1)
print(lista2)
print(lista3)
Para acessar um único elemento de uma lista faz-se uso de índices, isto é, o nome
da variável seguido de um número entre colchetes. Este número indica a posição do
elemento que se quer acessar. Ressaltando que a posição começa a ser contada a partir do
zero.
Pode-se usar também um número negativo como índice, nesse caso, a contagem
ocorre de trás para frente com -1 sendo o último elemento.
compras[0] = "suco"
compras[1] = "beterraba"
compras[2] = "batata"
compras[-1] = "curso de guerrilha"
print(compras)
Um comando muito útil que pode ser utilizado sobre listas é o len que retorna a sua
quantidade de itens. Com ele é possível percorrer listas da seguinte forma:
for i in range(len(compras)):
print("Na posição " + str(i) + " temos o elemento: " + compras[i])
17
O laço for também pode ser usado para percorrer os elementos de uma lista
diretamente.
lista = [4, 2, 1, 3]
for a in lista:
print(a)
Nesse exemplo a cada repetição a variável a assume um dos valores da variável lista
em ordem, nesse caso, 4, 2, 1 e 3.
Na realidade, a única coisa que o comando for faz é iterar sobre os elementos de
uma lista. O range, apresentado na seção anterior, não faz nada além de criar uma lista de
números. Experimente digitar o seguinte no REPL da linguagem:
list(range(10))
Exemplos
O programa do exemplo a seguir soma todos os elementos de uma lista de inteiros.
lista = [67, 68, 69, 70, 71, 72, 73, 75, 77, 79, 83, 87, 88, 94]
soma = 0
for i in lista:
soma += i
print(soma)
Já o trecho de código a seguir verifica se duas listas de mesmo tamanho são iguais.
listaA = [5, 1, 2, 4]
listaB = [5, 1, 2, 4]
iguais = True
for i in range(len(listaA)):
if listaA[i] != listaB[i]:
iguais = False
break
18
if iguais == True:
print("As listas são iguais")
else:
print("As listas são diferentes")
No trecho, a variável iguais indica se as listas são iguais, e inicialmente ela foi
definida como True. No laço for, a cada iteração, a variável i assume um dos valores de 0
até 3 e o usa para acessar uma dada posição das listas e compará-las. Caso uma das
comparações resulte em falso, a variável iguais assume o valor False e o laço é
interrompido. Já quando todas as comparações são verdadeiras, o laço é completado e
iguais mantém o valor True.
Métodos de Listas
A linguagem Python oferece alguns comandos, chamados métodos, capazes de
realizar determinadas operações sobre listas. Eles são acessados colocando um ponto
após o nome da variável e em seguida o nome do método terminado em abre e fecha
parênteses. Alguns métodos podem receber parâmetros os quais devem ficar no interior
dos parênteses. No código a seguir são apresentados alguns.
lista = [12, 3, 1, 6, 7]
[Link]() # Ordena os elementos de uma lista
[Link](4) # Adiciona o elemento 4 ao final da lista
[Link](12) # Remove o elemento com valor 12
[Link]() # Reverte a ordem da lista
[Link]() # Remove todos os elementos
[Link](0, 41) # insere o elemento 12 na posição 0 da lista
[Link]([6, 6, 6]) # adiciona os elementos da lista [6, 6, 6] ao final
Mais adiante neste tutorial “métodos” serão discutidos com mais detalhes.
Compreensão de Listas
Listas podem ser criadas também através das denominadas compreensão de listas,
semelhantes a notação de conjuntos encontrada na matemática.
[x for x in [1, 2, 3, 4, 5, 6] if x % 2 == 0]
Matematicamente:
Tuplas
Tuplas são semelhantes a listas, porém uma vez criadas não podem ser
modificadas. São declaradas como listas, porém, se utilizando de parênteses.
Dicionários
Os dicionários são uma estrutura no qual os dados são armazenados da forma
chave-valor e podem ser acessados semelhantemente as listas e tuplas, porém
utilizando-se das chaves, ao invés dos índices. Além disso, diferentemente das tuplas, os
valores podem ser modificados ao decorrer da execução do programa. Outra questão
interessante e importante a respeito dos dicionários é que as chaves são únicas. Os
dicionários são declarados de forma literal a partir do uso de chaves e os respectivos
chave-valor são separados através do uso de chaves.
precosProdutos = {
"Laptop": 1999.99,
"Celular": 1599.99,
"Kit mouse + teclado": 99.99
20
}
print(precosProdutos["Laptop"])
for produto in precosProdutos:
print("Preco do {}: R${}".format(produto, precosProdutos[produto]))
Funções
Funções servem para evitar repetição de código além melhorar a organização e
clareza do programa. Uma função é declarada com a palavra-chave def seguido do nome
da função, abre e fecha parênteses, dois pontos e, na próxima linha indentada, o corpo da
função.
def saudacao():
print("Hello")
No código acima foi definido uma função chamada saudacao que ao ser executada
exibirá a mensagem "Hello". Note que, ao executar esse código nada acontece, pois a
função foi apenas declarada e não chamada.
Para chamar uma função deve-se escrever o nome dela seguido de abre e fecha
parênteses.
def hello():
print("Hello")
hello()
def hello(nome):
print("Hello " + nome)
hello("Krzysztof Penderecki")
É possível que funções retornem valores. Para isso deve-se usar a palavra-chave
return seguido do valor a ser retornado.
def cubo(x):
return x*x*x
a = cubo(3)
print(a)
Nesse exemplo cubo retorna o cubo de um número e esse valor retornado foi
armazenado em uma variável.
def primo(n):
for i in range(2, n-1):
if n % i == 0:
return False
return True
Exemplos
O exemplo a seguir calcula as raízes de uma equação do segundo grau a partir de
seus coeficientes.
Observe que essa função retorna uma tupla, isto deve ser levado em conta ao
utilizar os valores retornados:
t = baskara(-1, 7, 11)
print("x1 = " + str(t[0]))
print("x2 = " + str(t[1]))
22
Funções também podem ser recursivas, isto é, podem chamar a si mesmas. Uma
função recursiva muito conhecida é o fatorial que pode ser definido matematicamente por:
def fat(n):
if n <= 1:
return 1
else:
return n*fat(n-1)
Funções Lambda
Existe uma forma alternativa de declarar funções mais simples. Essa forma é
chamada de função lambda. Um exemplo é apresentado a seguir.
Esses tipos de funções não possuem nome e devem ser armazenadas em uma
variável. Os parâmetros vêm logo depois de lambda e separados por vírgula, e após os dois
pontos vem o corpo da função que deve ser uma expressão e é automaticamente
retornada. A função lambda do último exemplo retorna o quadrado de um número x. Já o
próximo exemplo retorna a média entre dois números.
a = quad(4)
b = media(a, 5)
23
Programação Funcional
Módulos
Em Python, módulos são arquivos de código que podem ser trazidos para um
programa. Permitem que o programador possa utilizar em seu código funções, classes,
variáveis e etc. criados em outros arquivos.
Esses módulos podem ser trazidos para o programa através da linha de código
abaixo. A palavra reservada import seguido do nome do módulo.
import nome_do_modulo
Para criar um módulo para ser importado por um outro programa Python, basta
criar um arquivo de código fonte com a extensão “.py”. Por exemplo, a seguir está o
conteúdo do arquivo "[Link]":
# arquivo "[Link]"
def codificar(mensagem):
codificado = ""
for c in mensagem:
# "ord" transforma o caracter em um inteiro q é incrementado e
# convertido para caracter novamente com "chr"
codificado += chr(ord(c) + 1)
return codificado
def decodificar(mensagem):
decodificado = ""
for c in mensagem:
decodificado += chr(ord(c) - 1)
return decodificado
# arquivo "[Link]"
import linguadoP
msg = "se para fazer iogurte precisa de um pouco de iogurte, de onde veio o
primeiro iogurte??"
msg_codificada = [Link](msg)
print(msg_codificada)
msg_decodificada = [Link](msg_codificada)
print(msg_decodificada)
Biblioteca Padrão
O Python quando instalado traz consigo diversos módulos que oferecem
funcionalidades básicas que provavelmente muitos programas necessitam, como funções
matemáticas, acesso a arquivos em disco, chamadas de funções do Sistema Operacional e
etc. Esses módulos são comumente chamados de biblioteca padrão da linguagem.
Um dos módulos mais utilizados da biblioteca padrão é o math que traz consigo
diversas funções matemáticas.
import math
Outro módulo muito útil é o random que permite a geração de números aleatórios.
25
import random
def jogarDado():
return [Link](1, 6)
print(jogarDado())
print(jogarDado())
print(jogarDado())
print(jogarDado())
No código acima apenas a função sqrt de math foi importada e o uso do prefixo
"math" deixa de ser necessário ao usar a função.
Orientação a Objetos
A Programação Orientada a Objetos (POO) é um paradigma de programação que
consiste na estruturação do código através do uso de dos chamados "objetos". Esses
objetos não são nada mais que um tipo de dado que carrega variáveis e funções dentro de
si. Um exemplo de objeto na linguagem Python é uma string.
a = "Taturana"
# Pode-se acessar por exemplo a função "upper" desse objeto string
b = [Link]()
print(b)
class Barata():
def voar(self):
print("bzzzzzzz")
def comer_lixo():
print("mnham mnham mnham hmmmmm")
Após definido o tipo do objeto pode-se de fato criá-lo e guardá-lo em uma variável.
Essa criação é chamada de instanciação. Para isso basta escrever o nome do objeto
seguido de abre e fecha parênteses, como se fosse a chamada de uma função. E para
chamar um determinado método desse objeto usa-se o nome da variável que recebeu o
objeto seguido do operador "." e a chamada da função.
# instanciação de um objeto
uma_barata = Barata()
uma_barata.comer_lixo()
Construtores e Atributos
Também é possível que um objeto possua variáveis internas. Para criá-las é preciso
entender o conceito de construtor. O construtor é uma função que é chamada durante a
instanciação do objeto, ela sempre possui o nome de "__init__"(dois underlines no começo
e dois no final) e recebe um parâmetro chamado "self". A seguir um exemplo.
class Barata():
# definição do construtor
def __init__(self):
print("Uma baratinha nasceu!")
def voar(self):
print("bzzzzzzz")
def comer_lixo(self):
print("mnham mnham mnham hmmmmm")
# instanciação
uma_baratinha = Barata()
Através do construtor podemos adicionar variáveis internas para o objeto. Para isso
usamos o parâmetro "self" que o construtor recebe.
class Barata():
def __init__(self):
[Link] = "Marcia"
[Link] = 23
Essas variáveis internas aos objetos são chamadas de atributos. Elas podem ser
acessadas de forma semelhante aos métodos, porém sem os parênteses:
barata = Barata()
# acessando atributo
print([Link])
28
class Barata():
def __init__(self, nome, idade):
[Link] = nome
[Link] = idade
print([Link])
print([Link])
def Barata():
def __init__(self, nome, idade):
[Link] = nome
[Link] = idade
def fazer_aniversario(self):
print("Parabéns pra você, nesta data querida")
[Link] += 1 # "self" é usado para modificar um atributo do
objeto já criado no construtor
print([Link])
Classes abertas
29
class Barata():
def __init__(self, nome, idade):
[Link] = nome
[Link] = idade
print(barata_trabalhadora.profissao)
# criando função
def apresentacao(self):
print(f"Meu nome é {[Link]}, sou {[Link]} e vou cruzar
{[Link]}")
barata_trabalhadora.apresentacao()
As classes fechadas são aquelas que são implementadas pela própria linguagem
para representar tipos básicos, como strings, inteiros, listas e etc. Essas classes não
permitem a adição de novos atributos e métodos.
existir nenhuma instância da classe. Para defini-los basta fazer a declaração de uma
variável no escopo da classe, fora de qualquer método como no exemplo abaixo.
class Barata():
numero_de_baratas = 0
def __init__(self):
# devem ser acessadas dentro da classe
# indicando o nome da classe antes do ponto
Barata.numero_de_baratas += 1
barata1 = Barata()
barata2 = Barata()
barata3 = Barata()
barata4 = Barata()
barata5 = Barata()
class Barata():
numero_de_baratas = 0
idade_total = 0
@staticmethod
def idade_media():
return Barata.idade_total / Barata.numero_de_baratas
31
barata1 = Barata(15)
barata2 = Barata(121)
barata3 = Barata(3)
barata4 = Barata(49)
barata5 = Barata(69)
Propriedades
Propriedades são atributos cujo acesso e modificação são controlados por métodos.
É muito útil para validar a modificação de um atributo. Por exemplo, se um determinado
atributo representa um dia do mês, não é desejável que alguém possa modificá-lo de
modo a inserir um número maior do que 31 ou menor que 1. Também seria necessário
verificar se o mês tem 30 ou 31 ou dias.
class Aniversario():
def __init__(self):
[Link] = 1975
[Link] = 1
self._dia = 1
return self._dia
aniversario = Aniversario()
[Link] = 2020
[Link] = 2
# usa-se a propriedade "dia" normalmente como se fosse um atributo
[Link] = 34
print([Link])
Repare que é necessário que as funções de "get" e "set" tenham o mesmo nome. E
este nome deve ser diferente do atributo que essas funções estão relacionadas, por isso o
atributo "dia" foi chamado “_dia" neste exemplo.
class Aniversario():
def __init__(self):
33
[Link] = 1975
[Link] = 1
self._dia = 1
# atributo estático
dia = property(get_dia, set_dia)
aniversario = Aniversario()
34
[Link] = 2020
[Link] = 2
# usa-se a propriedade "dia" normalmente como se fosse um atributo
[Link] = 34
print([Link])
Herança
Outro pilar básico da programação orientada a objetos é o conceito de herança.
Herança consiste em uma classe herdar métodos e atributos de uma classe base. Isso é
muito útil pois evita que classes muito parecidas sejam escritas totalmente do zero.
Também é ideal para modelar a relação entre objetos do mundo real, permitindo que um
conjunto de objetos possam ser agrupados de acordo com suas características em comum.
Para herdar de uma classe basta colocar o nome da classe mãe entre parênteses na
declaração da classe conforme o exemplo a seguir:
# classe base
class Barata():
def __init__(self, nome, idade):
[Link] = nome
[Link] = idade
def comer_lixo(self):
print("hmmmm mnham mnham mnham")
def discursar(self):
print(f"Ola povo! Meu nome é {[Link]} e eu prometo não roubar.
Vote {[Link]}!")
35
vereador.comer_lixo()
[Link]()
A linguagem Python também tem suporte a herança múltipla em que uma classe
pode herdar de mais de uma classe base. Para isso deve-se colocar as classes separadas
por vírgula durante a definição da classe:
class Aranha():
def __init__(self):
pass
def soltar_teia(self):
print("*barulho de lançar teia*")
def sentido_aranha(self):
print("*barulho do sentido aranha*")
Sobrecarga de Operadores
36
__add__
+ adição
- __sub__ subtração
* __mul__ multiplicação
/ __div__ divisão
% __mod__ módulo
__pow__
** potência
__pos__
+ positivo
- __neg__ negativo
!= __ne__ diferente de
| __or__ ou bit-a-bit
~ __inv__ inversão
class Vector3():
def __init__(self, x = 0, y = 0, z = 0):
self.x = x
self.y = y
self.z = z
# esse método é usado pelo comando "print" para converter o objeto para
string e printa-lo
def __repr__(self):
38
print(vec3)
print("| ")
print("| ")
elif e == 4:
print("| | ")
print("| O ")
print("| /|\\")
print("| / \\")
print("| ")
elif e == 5:
print("| O ")
print("| ")
print("| /|\\")
print("| / \\")
print("-------------")
return True
Feito isso, pode-se declarar a classe principal da nossa aplicação, que será derivada
do componente Frame da biblioteca Tkinter, e que portanto, também será uma Frame. As
respectivas funções de cada linha do código serão comentadas, para que exista
entendimento a partir de sua leitura.
class Application([Link]):
def __init__(self, master=None):
super().__init__(master) #constroi a janela base, o root.
# atribui o root para uma var local, a fim de poder usar algumas
de suas propriedades
[Link]
def create_widgets(self):
Método productForm()
def productForm(self):
Método productList()
def productList(self):
Como pode ser observado na linha de código responsável por criar o botão Salvar,
no método productForm(), foi realizado um bind, ou seja, uma vinculação de evento ao
clicar no botão. Essa vinculação ocorreu a partir do argumento passado para o parâmetro
command. Desse modo, como foi passado uma função, denominada [Link], é necessário
que tenhamos também ela implementada em nosso código.
Método save()
def save (self):
Por fim, é necessário que nossa classe Application seja instanciada, para que
possamos criar nosso objeto e desse modo, a aplicação possa ficar rodando e esperando a
interação com o usuário.
45
Como o Python é uma das linguagens mais utilizadas no mundo, não é nenhuma surpresa
que ele possua uma extensa coleção de bibliotecas para computação científica disponível
na internet. A biblioteca mais famosa nesse campo é sem dúvidas a Numpy, ela fornece
uma ampla quantidade de funções e estruturas de dados capaz de tornar o Python um
concorrente de Softwares na área, tais como Matlab, Scilab e Octave. Uma outra biblioteca
muito importante que trabalha juntamente com a Numpy é o Matplotlib, que auxilia na
plotagem de gráficos, e também a Pandas, que é usada para análise e representação de
dados.
Numpy
Numpy, abreviação de Numerical Python, é a principal biblioteca de computação numérica
da linguagem, sendo utilizada como base para diversas outras bibliotecas que precisam
executar esse tipo de atividade. É extremamente rápida com operações sobre listas, pois
utiliza um tipo próprio de lista chamado ndarray que por baixo dos panos é semelhante
aos arrays da linguagem C. Além dos ndarrays, essa biblioteca fornece ainda diversas
funções matemáticas relacionadas à álgebra linear, geração de números aleatórios,
transformadas de Fourier e etc.
46
Instalação
Para instalar o numpy é bem simples, basta abrir um terminal e executar o seguinte
comando:
pip install numpy
Para evitar de se escrever numpy antes de toda a chamada de função poderia-se importar
tudo que existe dentro do módulo da seguinte forma:
from numpy import *
Porém isso traria para o escopo global funções do Numpy que entrariam em conflito com
outras funções do Python, como a função max. Por isso é recomendado importar o módulo
e renomeá-lo para um nome mais curto como “np”.
import numpy as np
Arrays
Como dito anteriormente o Numpy implementa o seu próprio tipo de lista chamado
ndarray que é semelhante aos arrays da linguagem C e tão rápido quanto. Para se declarar
um ndarray em Python a partir de uma lista usa-se a função array.
[Link]([2,6,2,8,4,3])
Diferentemente das listas em Python um ndarray não pode conter elementos de tipos
diferentes, ou seja, não se pode criar um array com um elemento do tipo inteiro, outro
elemento do tipo booleano e outro com o tipo string por exemplo.
A maioria das operações realizadas com as listas em Python também são suportadas pelos
ndarrays.
a = [Link]([2, 6, 2, 8, 4, 3])
# acessar elemento
47
print(a[3])
# modificar elemento
a[3] = 12
print(a[3])
# número de elementos
print(len(a))
# percorrer com um for
for elem in a:
print(elem)
Outra forma de se criar ndarrays é através da função arange que é semelhante a função
range do Python. Por exemplo, para se criar um ndarray com os números pares entre 0 e
100:
[Link](0, 100, 2)
Outra grande vantagem dos ndarrays sobre as listas do Python é que operações básicas
realizadas entre valores escalares também podem ser realizadas nos ndarrays usando a
mesma sintaxe. Por exemplo, pode-se multiplicar todos os elementos do array da seguinte
forma.
a = [Link]([2, 6, 2, 8, 4, 3])
b = a * 10
# b é um ndarray com os valores [20, 60, 20, 80, 40, 30]
A variável b no código acima será um ndarray com os valores de a multiplicados por 10.
As operações também podem ser realizadas entre ndarrays.
a = [Link]([2, 3, 6])
b = [Link]([3, 2, -1])
Importante ressaltar que as operações devem ser realizadas entre ndarrays com o mesmo
número de elementos.
Matrizes
Matrizes são arrays bidimensionais, ou seja, um determinado elemento deve ser acessado
utilizando dois índices, um que indica a coluna e outro a linha. Para representar esse tipo
de estrutura com Numpy criamos ndarrays de ndarrays. Uma das formas de se realizar isso
é passar para a função [Link] uma lista de listas, o exemplo a seguir deixará mais claro:
matriz = [Link]([ [10, 12], [23, 14] ])
Onde cada matriz interna representa uma linha. Note que é necessário que todas as linhas
tenham o mesmo número de elementos.
Para acessar um elemento dessas matrizes é trivial:
#acessar elemento 12
print( matriz[0][1] )
# acessar elemento 23
print( matriz[1][0] )
Onde o primeiro valor entre colchetes é o índice da linha e o segundo é o índice da coluna.
Um atributo importante presente nos ndarrays é o shape que consiste em uma tupla de
valores inteiros que indicam o formato da matriz. No caso da matriz dos exemplos
anteriores, ao acessar esse atributo, temos a tupla (2, 2) que indica que essa matriz possui
duas linhas e duas colunas.
Para o código acima será exibido a tupla (2, 4) indicando que a matriz possui 2 linhas e 4
colunas.
Outra maneira de criar matrizes é utilizando as funções [Link] e [Link]. A primeira cria
uma matriz preenchida com 0s e a segunda uma matriz preenchida com 1s. Ambas
49
Também existem outras funções para se criar arrays, como por exemplo, [Link] que cria
uma matriz identidade com o formato especificado pela tupla que recebe, e também [Link]
que é semelhante a zeros e ones com a diferença que recebe de argumento, além de uma
tupla, o valor que será usado para preencher.
Na realidade é possível criar ndarrays com um número arbitrário de dimensões. Para se
criar um array tridimensional por exemplo deve-se passar uma lista de lista de lista para a
função [Link], ou usar as funções [Link], [Link] e etc. passando uma tupla com 3
elementos.
Indexação de Arrays
Os ndarray oferecem alguns recursos avançados de indexação de arrays. Um deles é o
chamado slicing que permite obter sub-arrays de um array da seguinte forma:
a = [Link](['a', 'b', 'c', 'd', 'e', 'f'])
b = a[0:3] # "b" possui os elementos ['a', 'b', 'c'],
# o elemento de índice 3 não é incluído
Uma diferença crucial entre as listas do Python e os ndarrays é que o segundo não faz uma
cópia dos elementos ao gerar o sub-array. Isso significa que ao se modificar um subarray
essa mudança acaba sendo refletida no array original.
a = [Link](['a', 'b', 'c', 'd', 'e', 'f'])
b = a[0:3]
b[0] = 'x'
b[1] = 'x'
b[2] = 'x'
print(a) # será printado: array (['x', 'x', 'x', 'd', 'e', 'f'])
Como o Numpy foi pensado para ser extremamente eficiente com arrays, ele dificilmente
cria cópias do mesmo, pois é uma operação computacionalmente muito custosa. Caso
realmente seja necessário copiar um subarray pode-se usar o método copy.
a = [Link](['a', 'b', 'c', 'd', 'e', 'f'])
b = a[0:3].copy() # "b" armazenará uma cópia do sub-array, modificar ele
# não irá alterar os elementos de "a"
Os mesmos princípios são válidos para arrays com mais de uma dimensão. Uma dica é que
para estes tipos de arrays pode-se acessar um elemento passando os índices separados
por vírgula dentro do mesmo par de colchetes:
a = [Link]([ [1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12] ])
b = a[1, 2] # acessar o elemento da linha 1 e coluna 2, elemento 7 no caso
c = a[0:2, 2:] # acessando o subarray [[3, 4], [7, 8]]
d = a[:, 3:] # acessando o sub array [[4], [8], [12]]
51
Será gerado um novo ndarray onde cada elemento indica se a condição foi satisfeita para o
respectivo elemento do primeiro ndarray. Esse novo array gerado pode ser usado para
indexar um ndarray de mesmo tamanho.
a = [1, 2, 3, 4, 5]
b = a >= 3 # b = [False, False, True, True, True]
c = a[b] # c = [3, 4, 5]
A = [Link]([[3, 2, 4],
[1, 1, 2],
[4, 3, -2]])
b = [Link]([1, 2, 3])
print([Link](A, b))
Jupyter Lab
Uma ferramenta muito popular entre os programadores que trabalham com computação
numérica e análise de dados é o Jupyter Lab. Esta ferramenta open source oferece um
ambiente de desenvolvimento onde código e dados possam ser trabalhados de forma
interativa. Instruções para se utilizar cada uma dessas ferramentas pode ser encontrada
no site oficial.
Para esse tutorial será utilizado uma versão mais simples do Jupyter Lab chamado Jupyter
Notebook, que embora com menos funcionalidades será suficiente para este tutorial. Para
acessá-lo, a partir do site oficial, clique no botão “Try it in your browser”.
53
Agora aguarde alguns segundos enquanto o notebook é carregado. Assim que terminar e a
tela de “bem vindo” for exibida vá até o menu File, New Notebook e Python 3.
54
No campo de texto indicado pela seta vermelha pode-se escrever código Python.
Experimente escrever um simples hello world. Para executar o código basta clicar no botão
Run indicado pela seta verde, ou pressionar a tecla ctrl e enter ao mesmo tempo. A saída
do código será exibida em uma nova linha abaixo.
Cada um desses pares de código e saída é chamada célula. O que torna o Jupyter muito
prático é a possibilidade de se criar várias dessas células cada uma sendo executada de
maneira cooperativa. Para criar uma nova célula pode-se utilizar o botão indicado pela seta
azul.
Suponha que por exemplo tenha-se a seguinte célula:
Ao executá-la, as variáveis declaradas serão válidas para todas as células seguintes. Dessa
forma pode-se criar uma nova célula que utiliza essas variáveis.
55
Isso é muito útil para situações em que um determinado trecho de código leva muito
tempo para ser executado. Em vez de se executar todo o código após realizar uma
pequena modificação pode-se colocar o trecho de código mais demora em uma célula
separada e executar somente aquela que precisa de modificações.
Outro ponto importante dessas células é que caso a última linha de código seja uma
expressão, isto é, algo que retorna algum valor, esse valor será exibido na saída da célula.
Matplotlib
É uma biblioteca que oferece diversas funcionalidades para plotar gráficos e imagens. Se
integra muito bem com o Numpy. A instalação pode ser realizada através do pip rodando o
seguinte comando em um terminal:
Todas as funcionalidades que serão utilizadas nesse tutorial estão contidas no submódulo
pyplot, por isso somente ele será importado. Além disso, é uma convenção renomeá-lo
para plt.
Como foi dito anteriormente, se a última linha da célula for uma expressão o valor dela é
exibido. No caso acima [Link](data) retorna um objeto [Link].Line2D que é lido
pelo Jupyter Notebook e exibido como uma imagem.
A função plot possui uma infinidade de parâmetros que podem ser passados. Quando
apenas uma lista (ou ndarray) é passado para essa função é criado um gráfico de duas
dimensões onde o eixo “y” é representado pelos valores da lista e o eixo “x” pelos índices
dessa lista.
Também é possível passar duas listas ou arrays como argumento da função plot, a primeira
corresponderá ao eixo “x” e a segunda ao eixo “y”, note que ambas devem ter o mesmo
57
tamanho. No exemplo a seguir é criado uma onda senoidal com frequência de 10 Hz com
duração de 0,5 segundos.
O eixo “x” que representa os segundos é criado com a função arange do Numpy
consistindo em um array cujo os elementos representam os instantes de 0 a 0,5 segundos
espaçados por 0,001 segundos. Já o eixo “y” é calculado a partir do “x” aplicando-o uma
função. Nesse caso é aplicado a função senoidal, repare que não é utilizado a função sin da
biblioteca padrão do Python, mas sim a do Numpy por causa do broadcasting. Para se
conseguir a onda senoidal com a frequência desejada de 10 Hz, cada valor de x é
multiplicado por 2 × π × 𝑓𝑟𝑒𝑞𝑢ê𝑛𝑐𝑖𝑎. Para plotar o gráfico passa-se o array “x” como o
primeiro argumento de plot e “y” como o segundo.
Outros caracteres podem ser indicados para representar o restante das cores disponíveis
como indicado na tabela a seguir.
Caractere Cor
‘m’ magenta
59
Também é possível determinar o estilo das linhas do gráfico, podendo ser tracejado '--',
pontilhado ':', sólido '-' ou ponto e traço '-.'. Os pontos do gráfico também podem
receber alguma marcação especial, por exemplo usando o caractere 'o', resultará em
marcações circulares e o caractere 'v' em marcações de formato triangular para baixo.
Observe a seguir que essas formações podem ser combinadas.
Com o Matplotlib também é possível colocar um título no gráfico e nomear os eixos, para
isso usa-se as funções abaixo:
60
Também podem ser criados outros tipos de gráficos além dos criados com a função plot.
Por exemplo, pode-se criar um gráfico de barras utilizando a função bar. É semelhante a
função plot com a diferença que o eixo x pode conter valores não numéricos como strings.
No exemplo a seguir é criado um gráfico de barras que representa as chuvas durante o
ano de 1634.
61
Também pode-se criar um gráfico de pizza com a função pie. Basta passar uma array ou
lista que o matplotlib irá automaticamente criar uma gŕafico de pizza baseado na
proporção de cada número em relação ao total. Também é possível passar um parâmetro
opcional do tipo array chamado label especificando um label para cada valor.
62
Em algumas ocasiões pode ser oportuno exibir vários gráficos em uma mesma figura.
Múltiplos gráficos podem ser criados com a função subplots. Os gráficos criados por ela
são dispostos em forma de matriz, ou seja, a figura é dividida em vários retângulos, cada
um contendo um gráfico. Essa função recebe dois parâmetros indicando o número de
linhas e colunas respectivamente da matriz. Por exemplo, para se criar uma figura
contendo quatro gráficos, dois na linha de cima e dois na linha:
[Link](2, 2)
63
Essa chamada de função retorna uma tupla com dois elementos, o primeiro é um objeto
que representa a figura como um todo. O segundo é uma matriz onde cada elemento é do
tipo axis, um objeto que representa um gráfico e que pode ser plotado com o método plot.
A seguir são criados 4 gráficos, cada um contendo um gráfico de um tipo diferente.
SMTP é a sigla para Simple Mail Transfer Protocol que significa protocolo de transferência
de correio simples. Em sumo é um padrão para o envio de correspondência digital,
funciona basicamente da seguinte forma para enviar um email de uma conta para outra.
smtplib
Para instalar a smtplib usando o pip no terminal:
pip install smtplib
import smtplib
Para realizar o envio de email é necessário saber qual o endereço smtp para o seu
provedor de email, alguns dos provedores mais comuns são:
● Gmail: [Link]
● Hotmail: [Link]
● Outlook: [Link]
● Yahoo: [Link]
Os asteriscos foram usados para representar os dados pessoais, com my_email e password
sendo o email de quem está enviando, o email de envio é um gmail, então é usado
“[Link]” , [Link]("[Link]") cria um objeto da classe SMTP que vai ser
chamado de connection, dentro desse escopo determinado por tudo que está dentro do
with. Em seguida é usado o stattls(), TLS significa Transport Layer Security e é uma forma de
assegurar a conexão ao servidor de email, em seguida é feito o login() e o email é enviado
usando sendmail(). Por estar enviando um email a partir de uma ferramenta externa, é
necessário desabilitar as ferramentas de segurança do email usado para o envio, portanto
é recomendado criar um email apenas para uso na aplicação.
Requests
Trata-se de uma biblioteca HTTP Hypertext Transfer Protocol, a base da troca de dados
Web que é o protocolo que permite a obtenção de recursos como por exemplo
documentos HTML, as requisições são feitas a um endereço de web por um usuário que é
o próprio destinatário da informações, o endereço pode assim responder ao destinatário.
Requests tem portanto como objetivo tornar as solicitações HTTP mais amigáveis aos
usuários da linguagem.
65
requests
É criado separado, um arquivo do tipo texto .txt contendo as informações de login do email
que enviará as mensagens, vale lembrar que para que não haja problema com o envio de
emails, as opções de segurança do email devem estar desabilitadas, uma boa opção é criar
um email diferente do seu email pessoal, então o arquivo é aberto usando open() os dados
são copiados do arquivo e o arquivo é fechado usando close():
login = open('[Link]', 'r')
LOGIN_DATA = [[Link](" \n") for line in login]
[Link]()
São criadas as funções para extrair as informações específicas do API escolhido, com seus
respectivos endpoints, os dados são lidos no formato JSON e percorridos como um
dicionário python:
api = "[Link]
def get_race():
response = [Link](api + "/api/races/")
response.raise_for_status()
response = [Link]()["results"]
response = choice(response)
67
É definida uma função para o envio de emails usando o protocolo smtp, a função recebe
como parâmetros o email para onde a informação deve ser enviada e o texto a ser
enviado:
def send_email(email, text):
with [Link]("[Link]") as connection:
[Link]()
[Link](user = LOGIN_DATA[0], password = LOGIN_DATA[1])
[Link](
from_addr = LOGIN_DATA[0],
to_addrs = email,
msg = f"Subject:RPG\n\n{text}"
)
Para manter os dados é criada a função save() que funciona da seguinte maneira, os dados
são armazenados em variáveis e depois organizados no formato de um dicionário, é feito a
confirmação de que está tudo conforme o planejado ou seja, nenhum espaço está vazio no
preenchimento dos dados, caso algo esteja errado isso será mostrado usando o
messagebox, caso esteja correto o preenchimento, outro messagebox é acionado para
confirmar as informações, se essa confirmação é feita, os dados são salvos em um arquivo
JSON, então podem ser consultados usando a função search_site() que pega o nome
cadastrado, a partir de uma entrada da interface do tkinter, e mostra ao usuário as
informações básicas do jogador:
def save():
nome = nome_entry.get()
email = email_entry.get()
personagem = personagem_entry.get()
race = get_race()
classe = get_classe()
new_data = {
nome:{
"Email": email,
"Personagem": personagem,
"Race": race,
"Classe": classe,
}
}
if nome == "" or email == "" or personagem == "":
[Link](title = "Ooops", message = "Certifique-se de
68
if is_ok:
text = f"Character: {personagem}\n\nRace: {race}\n\nFeastures:
\n{get_race_description(race)}\nClass: {classe}\n\nProficiencies:
\n{get_classe_descriptions(classe,lower())}\n"
send_email(email, text)
try:
with open("[Link]", "r") as data_file:
data = [Link](data_file)
[Link](new_data)
with open("[Link]", "w") as data_file:
[Link](data, data_file, indent = 4)
except FileNotFoundError:
with open("[Link]", "w") as data_file:
[Link](new_data, data_file, indent = 4)
except [Link]:
with open("[Link]", "w") as data_file:
[Link](new_data, data_file, indent = 4)
finally:
nome_entry.delete(0, END)
personagem_entry.delete(0, END)
def search_site():
nome = nome_entry.get()
try:
with open("[Link]", "r") as data_file:
data = [Link](data_file)
except FileNotFoundError:
[Link](title="Not Found", message="Data does not
exist.")
except [Link]:
[Link](title="Not Found", message="Data does not
exist.")
else:
try:
69
search_data = data[nome]
print(search_data)
except KeyError:
[Link](title="Not Found", message="Name not
found.")
else:
[Link](title="Personagem Info", message=f"Nome:
{nome}\nEmail: {search_data['Email']}\nPersonagem:
{search_data['Personagem']}")
finally:
nome_entry.delete(0, END)
personagem_entry.delete(0, END)
#Labels
nome_label = Label(text="Nome:")
nome_label.grid(row=1, column=0)
email_label = Label(text="Email: ")
email_label.grid(row=2, column=0)
personagem_label = Label(text="Personagem:")
personagem_label.grid(row=3, column=0)
#Entries
nome_entry = Entry(width=40)
nome_entry.grid(row=1, column=1, columnspan=1)
nome_entry.focus()
email_entry = Entry(width=50)
email_entry.grid(row=2, column=1, columnspan=2)
email_entry.insert(0, "@[Link]")
personagem_entry = Entry(width=40)
70
personagem_entry.grid(row=3, column=1)
#Buttons
add_button = Button(text="Add", width=45, command=save)
add_button.grid(row=4, column=1, columnspan=2)
search_button = Button(text= "Search", command = search_site)
search_button.grid(row = 1, column = 2)
[Link]()