segunda-feira, 6 de abril de 2020

Data e formatando strings em Python

Data e formatando strings em Python


Datas não são um tipo de dados em python mais podemos importar o módulo datetime e trabalhar com as datas como se fossem objetos.
Exemplo
import datetime

a = datetime.datetime.now()
print(a)
Nesse exemplo a data é mostrada com ano, mês, dia, hora, minutos, segundos e milissegundos. E se nos quiséssemos apenas o ano, o mês e o dia? Nesse caso podemos utilizar a variável year e o método strftime.
Exemplo
import datetime

a = datetime.datetime.now()

print(a.year)
print(a.strftime("%B"))
print(a.strftime("%A"))

Criando uma data

Nós também podemos criar uma data especifica.
Exemplo
import datetime

a = datetime.datetime(2002, 5, 9)

print(a.year)
print(a.strftime("%B"))
print(a.strftime("%A"))

Formatando strings em python

Uma coisa muito importante na apresentação de uma informação é a sua formatação. Com a formatação a leitura do conteúdo fica mais fácil possibilitando o seu maior entendimento. Uma formatação errada facilita a leitura dos dados de modo errado.
Em python, podemos formatar as strings com a função format. Imagine que no meio de uma frase queremos usar o valor de uma variável. Um jeito de se fazer isso é quebrar a string em duas partes e adicionar a variável desejada entre os operadores de adição. Um jeito mais elegante de conseguir o mesmo resultado é com a função format. A função format substitui, na string, as chaves pelo valor da variável passada como parâmetro.
Exemplo
anos = 28
frase = 'Eu tenho {} anos de idade'
print(frase.format(anos))

Formatando números com casas decimais

Se por algum motivo você precisa que um numero decimal seja apresentado com duas ou três casas decimais, isso é possível com a função format.
Exemplo
valor = 23.9876
print('O ventilador custa {:.2f} reais a vista'.format(valor))
É importante notar que nesse exemplo o valor é aredondado.

Vários valores

É possível passar múltiplos valores para a função format.
Exemplo
quantidade = 4
valor = 4.93245
texto = 'Comprei {} pasteis por {:.2f} reais cada'
print(texto.format(quantidade, valor))
É possível utilizar index para ter certeza que o valor vai estar no local certo, mesmo se, por acaso, você trocar a ordem dos parâmetros.
Exemplo
quantidade = 4
valor = 19.93245
texto = '{1:.2f} me custou {0} pasteis'
print(texto.format(quantidade, valor))
Também é possível utilizar um nome como index.
Exemplo
msg = 'Eu tenho um {marca}, {modelo}'
msg = msg.format(modelo='Toro', marca='Fiat')
print(msg)

quarta-feira, 1 de abril de 2020

Tratamento de erros em Python

Tratamento de erros em Python


Um programador deve sempre testar o seu programa muitas e muitas vezes a procura de erros (bugs) e corrigir esses erros. Em algumas situações o erro é do programador, e outra é do usuário, e outras são erros que não se pode colocar a culpa em ninguém. Quando um erro acontece o programa para ali mesmo. Alguns erros são tão críticos para o programa, mais mesmo assim o programa para. Para evitar que isso ocorra o python tem um tratamento de erro com try except.
Dentro do try vai o código que você acha que pode acontecer alguma coisa errada. E o except vai o código que deve ser executado quando um erro acontecer.
Exemplo
try:
  # a variável a não existe
  # um erro vai acontecer
  print(a)
except:
  print('Um erro aconteceu no bloco try')
Nesse exemplo um erro vai acontecer no bloco try. Quando isso acontece o compilador pula a execução para o bloco except e executa o seu código.

Muitas exceções

O nosso ultimo exemplo é muito genérico, serve para todo erro que ocorrer no bloco try. Para refinar o nosso tratamento de erro podemos criar varias exceções, uma para cada tipo de erro. Por exemplo: quando uma variável não existe o erro e o NameError, quando é feita uma tentativa de se dividir por zero o erro é ZeroDivisionError.
Exemplo
try:
  a = 9 / 0
except NameError:
  print('Uma variável não existe')
except ZeroDivisionError:
  print('Não é possível dividir por zero')
A mensagem “uma variável não existe” só vai aparecer se tiver uma tentativa de acessar uma variável que não existe, porque o programa vai retornar o erro NameError, fazendo nosso programa entrar no bloco except NameError.
Se no bloco try houver uma tentativa de dividir por zero o programa vai retornar o erro ZeroDivisionError e entrar no bloco except ZeroDivisionError.

Else

É muito útil saber que não aconteceu nenhum erro durante o nosso programa. E é ai que entra o else. Se nenhum erro acorrer no bloco try o else será executado.
Exemplo
try:
  a = 9 / 2
except:
  print('Um erro aconteceu')
else:
  print('Nenhum erro aconteceu')

Finally

O else só será executado caso não haja erros durante a execução do programa. Mais e se você quiser que um bloco de código seja executado mesmo que nenhum erro ocorra? Com o finally o código será executado mesmo que um erro ocorra ou não.
Exemplo
try:
  a = 9 / 2
except:
  print('Um erro aconteceu')
finally:
  print('Nenhum erro aconteceu. Ou aconteceu, não sei dizer!!')

Lançando uma exceção

Imagine que você precisa que o usuário digite um numero menor do que dez, e se isso não for feito o programa deve lança uma exceção. Em python essa exceção não existe, mais podemos criar com a palavra reservada raise.
Exemplo
a = input('Digite um numero menor que 10: ')
if int(a) > 10:
  raise Exception('Não é permitido números maiores que 10')
Se o usuário digitar um numero maior que 10 a exceção “Não é permitido números maiores que 10” vai ser lançada e o programa para.

Lançando um erro

Para lançar um erro é usada a função TypeError. Essa função recebe como parâmetro o novo erro.
Exemplo
a = 3
if a == 3:
  raise TypeError('O número 3 não é permitido')
No compilador você vai ver o novo erro: O número 3 não é permitido.

terça-feira, 31 de março de 2020

Módulos em Python

Módulos em Python


Os módulos são blocos de códigos separados do programa principal em arquivos separados. Com módulos é possível dividir o programa em blocos (ou módulos). Os módulos são muito úteis para funções e classes que serão usadas em muitos programas diferentes. Assim não é preciso reescrever o mesmo código basta, simplesmente, adicionar o módulo ao seu programa.

Criando um módulo

Para criar um módulo é só criar um novo arquivo no editor texto de sua preferência e salvar com .py.
Exemplo
def show(string):
  print(string)
Salve o arquivo como modulo.py

Usando um módulo

ara usar um módulo primeiro precisamos avisar ao compilador python que vamos usar um. E isso é feito com a palavra reservada import. Com o nosso módulo pronto, e salvo na mesma pasta do nosso programa, é só chamar a função do módulo. Chamar uma função de um módulo é simples: nomedomódulo.função(). O nome do módulo é o mesmo do arquivo. No nosso exemplo anterior salvamos o arquivo com o nome de modulo.py.
Exemplo
import modulo
modulo.show('Meu módulo está funcionando')

Variáveis nos módulos

Além das classes e funções também é possível acessar variáveis declaradas dentro de um módulo.
Exemplo
lista = ['Arquivo não encontrado', 'Procurando', 'Erro fatal']
Exemplo
import modulo
print(modulo.lista[1])

Criando um alias de um módulo

Um alias é um apelido para o modulo. Às vezes e interessante mudar o nome do modulo para tornar o nome menor. Com um alias do módulo é só trocar o nome do módulo pelo alias.
Exemplo
import modulo as mdl
print(mdl.lista[1])

Importando partes de um módulo

Algumas vezes precisamos apenas de uma classe ou função de um módulo, utilizando import o módulo completo é carregado no nosso programa deixando ele “pesado”. Para contornar isso no python é possível importar apenas uma parte do módulo com a palavra reservada from.
Exemplo
# Salve em um arquivo diferente
carros = ['Fiat Toro', 'Toyota Hilux', 'Ford Fiesta']
motos = ['Honda CB1000R', 'Honda CRF', 'Yamaha Drag Star']

from modulo import carros
print(carros[0])
Note que importando apenas a lista termos acesso direto a ela, sem precisar dizer de que módulo essa lista pertence.

segunda-feira, 30 de março de 2020

Scope de uma variável em Python

Scope de uma variável em Python


Quando uma variável é criada dentro de uma função essa variável só pode ser acessada dentro dessa função. Para outras funções essa variável não existe.

Variável local

Uma variável criada dentro de uma função existe somente dentro dessa função. Isso quer dizer que para alterar o valor dessa variável o código deve pertencer a mesma função da variável.
Exemplo
def funcao():
  a = 42
  if 'a' in locals():
    print('A variável a existe!')

if 'a' in locals():
  print('A variável a existe!')
else:
  print('A variável a não existe')

funcao()
As funções dentro de funções podem acessar as variáveis da mesma função a qual a função pertence. Imagine que a função e a variável estão no mesmo nível. Por isso a função pode “ver” a variável. A variável está no seu scope.
Exemplo
def foo():
  a = 42
  def mostrar():
    print(a)
  mostrar()

foo()

Variável global

Uma variável global pode ser acessada em qualquer parte do programa. Elas podem ser acessadas dentro de funções e classes. As variáveis globais ao visíveis em qualquer parte do programa.
Exemplo
# scope global
answer = 42

def ask():
  # scopo local
  a = 'O significado da vida, do universo e tudo mais é '
  print(a + str(answer))

ask()

Palavra reservada global

Também é possível declarar uma variável dentro de uma função ou classe como uma variável global. Para isso é utilizada a palavra reservada global. Com essa declaração a variável passar ater um scope global, podendo ser acessada por todo o programa.
Exemplo
def foo():
  global a
  a = 42
  print(a)

foo()

# fora do sope da função foo
print(a)
Repare que nesse exemplo a função foo deve ser chamada antes de tentar acessar o valor de a. Enquanto a função foo não for executada a variável global a não existe. Somente a partir da execução da função é que a variável global passa a existir.

Variáveis com o mesmo nome

Normalmente não é permitido duas variáveis com o mesmo nome. Mais duas variáveis com o mesmo nome e com scope diferentes isso é possível. Como uma variável local não existe para um bloco de código diferente uma variável é independente da outra.
Exemplo
# scope global
a = 8
def foo():
  # scope local
  a = 80
  print(a)

foo()

print(a)
Quando a variável a é acessada dentro da função foo o seu valor será 80, pois a função procura a variável no scope local e só depois no scope global.

domingo, 29 de março de 2020

Iteradores em Python

Iteradores em Python


Os iteradores em python são objetos que contêm n elementos. Com objetos que podem ser iterados é possível acessar cada elemento, do primeiro ao ultimo. Temos como exemplo de objetos que podem ser iterados as listas, as tuplas, os sets, etc. Todos os objetos que podem ser iterados fazem uso de dois métodos: __iter__() e __next__().
Os objetos que podem ser iterados são contêineres que tem um numero para cada elemento no objeto. Com esse numero é possível saber a posição do elemento no objeto. A função iter retorna o iterador de um objeto e a função next coloca mais um na contagem. Assim obtendo o endereço do próximo elemento do objeto.
Exemplo
lista = ['Abacaxi', 'Banana', 'Manga']
iterador = iter(lista)

print(next(iterador))
print(next(iterador))
print(next(iterador))
As strings também são objetos iteráveis.
Exemplo
string = 'Melão'
iterador = iter(string)

print(next(iterador))
print(next(iterador))
print(next(iterador))
print(next(iterador))
print(next(iterador))

Loop for

O loop for como você já deve ter percebido, cria um objeto iterável e executa a função next.
Exemplo
string = 'Melão'
for i in string:
  print(i)

Criando uma classe/objeto iterável

Você também pode criar o seu objeto iterável. Para isso é preciso que essa nova classe tenha os métodos iter e next.
Exemplo
class ClassIterador:
  def __iter__(self):
    self.a = 1
    return self

  def __next__(self):
  b = self.a
  self.a += 1
  return b

itrd = ClassIterador()
iterador = iter(itrd)

print(next(iterador))
print(next(iterador))
print(next(iterador))
Nesse exemplo se usássemos um loop for nosso programa nunca teria fim. Para por um fim ao incremento podemos utilizar o StopIteration.
Exemplo
class ClassIterador:
  def __iter__(self):
    self.a = 1
    return self

  def __next__(self):
    if self.a <= 10:
      b = self.a
      self.a += 1
      return b
    else:
      raise StopIteration

itrd = ClassIterador()
for i in itrd:
  print(i)

Herança em Python

Herança em Python


A herança é utilizada na programação orientada a objetos para evitar códigos duplicados. Com a herança uma classe pode receber todos os métodos e propriedades de outra classe, evitando assim código duplicado. A classe que está sendo herdada é chamada de classe base ou pai. E a classe que recebe essa herança e chamada de classe filho.

Criando uma classe com herança

Toda classe pode receber outra classe como herança. Primeiro vamos criar a classe base e depois a classe que vai receber a herança da classe base.
Exemplo
class classeBase:
  def __init__(self, nome, u_nome):
    self.nome = nome
    self.u_nome = u_nome

  def shownome(self):
    print(self.nome)

pessoa = classeBase('Mickey', 'Mouse')
pessoa.shownome()
A classe que vai receber a classe base como herança recebe a classe base na sua definição, entre parênteses.
Exemplo
# Classe base
class classeBase:
  def __init__(self, nome, u_nome):
    self.nome = nome
    self.u_nome = u_nome

  def shownome(self):
    print(self.nome)

# Classe herdeira da classe base
class classeFilho(classeBase):
  pass

pessoa = classeFilho('Mickey', 'Mouse')
pessoa.shownome()
Note que não codificamos nada na classeFilho mais ela recebeu como herança a classeBase por isso ela tem todos os seu métodos e propriedades.
A palavra reservada pass serve para o compilador python não apresentar um erro. A nossa classe filho não faz nada, sem a palavra reservada pass o compilador iria esperar alguma coisa, como um atributo, um método etc. Com a palavra pass o compilador não espera nada, ele pula para a próxima linha de código.

Função init

Quando uma classe recebe a herança de outra classe a função init da classe filho é a mesma da classe base. Para mudar isso é só criar uma classe init na classe que recebeu a herança.
Exemplo
class classeBase:
  def __init__(self):
    print('Classe base iniciada...')

class classeFilho(classeBase):
  def __init__(self):
    print('Classe filho iniciada...')

pessoa = classeFilho()
Nesse exemplo, a função init da classe base foi subscrita. Para a função init, da classe base, ser executada a função precisa ser chamada da classe filho.
Exemplo
class classeBase:
  def __init__(self):
    print('Classe base iniciada...')

class classeFilho(classeBase):
  def __init__(self):
    classeBase.__init__(self)
    print('Classe filho iniciada...')

pessoa = classeFilho()

sábado, 28 de março de 2020

Classes e Objetos em Python

Classes e Objetos em Python


Python é uma linguagem de programação orientada a objetos. Isso quer dizer que quase tudo na linguagem tem métodos e propriedades.
A classe é como um molde onde vários objetos são criados, todos com as mesmas características. Um objeto sempre pertence a alguma classe.

Criando uma classe

Para criar uma classe em python é utilizada a palavra reservada class.
Exemplo
class Umaclasse:
  nome = 'Uchiha Itachi'
Nesse exemplo criamos uma classe com a propriedade nome.

Criando um objeto

Agora que já criamos uma classe podemos criar um objeto utilizando esse “molde”.
Exemplo
class Umaclasse:
  nome = 'Uchiha Itachi'

classe = Umaclasse()
print(classe.nome)

Função __init__()

Toda classe tem a função __init__(), até a nossa classe que acabamos de criar. Essa função é criada automaticamente quando criamos uma classe. Mesmo ela não aparecendo no nosso código ela está lá, e é executada toda fez que é criado um novo objeto pertencendo a nossa classe.
Mesmo essa função sendo adicionada no nosso código automaticamente, nos podemos modifica-la para fazer algo realmente útil. Essa função é utilizada para definir as propriedades dos nossos objetos.
Exemplo
class personagem:
  def __init__(self, nome, idade):
    self.nome = nome
    self.idade = idade

personagem01 = personagem('Itachi Uchiha', 21)
personagem02 = personagem('Kakashi Hatake', 31)

print(personagem01.nome)
print(personagem01.idade)

print(personagem02.nome)
print(personagem02.idade)
Repare que em nenhum momento chamamos a função __init__() e mesmo assim ela foi executada. Isso acontece porque quando um objeto é criado a função init é executada, sempre.
O parâmetro self é apenas para identificar o próprio objeto. Você pode ser a linha três (self.nome = nome) assim: a propriedade nome desse objeto será igual á nome (argumento recebido). O nome self pode ser trocado por outro, contanto que seja o primeiro argumento da função init.
Exemplo
class personagem:
  def __init__(primeiro_argumento, nome, idade):
    primeiro_argumento.nome = nome
    primeiro_argumento.idade = idade

personagem01 = personagem('Itachi Uchiha', 21)

print(personagem01.nome)
print(personagem01.idade)

Propriedades dos objetos

As propriedades são como as características de um objeto. Por exemplo, o personagem Kakashi Hatake tem o cabelo branco, um olho vermelho, é quase sem chakra, é humilde (copiou mais de mil justsus mais só usa alguns). Essas são as características do personagem. Podemos dizer que o objeto “Kakashi Hatake” é da classe pessoa, tem uma cabeça, dois braços, etc. Pertencer à mesma classe quer disser que os objetos dessa classe têm as mesmas características, mais com valores diferentes.
Exemplo
class pessoa:
  def __init__(self, nome, idade, cor_olho, cabelo = 'Preto'):
    self.nome = nome
    self.idade = idade
    self.cor_olho = cor_olho
    self.cabelo = cabelo

Kakashi_Hatake = pessoa('Kakashi Hatake', 31, 'Vermelho', 'Cinza')
Itachi_Uchiha = pessoa('Itachi Uchira', 21, 'Vermelho')
Sakura_Haruno = pessoa('Sakura Haruno', 17, 'Verde', 'Rosa')

print(Kakashi_Hatake.nome)
print(Kakashi_Hatake.idade)
print(Kakashi_Hatake.cor_olho)
print(Kakashi_Hatake.cabelo)

Métodos dos objetos

Os métodos são funções dentro de uma classe. Um objeto, além de ter características ele tem funções (métodos). Todo objeto tem suas características e suas funções. Um personagem no mundo de Naruto, por exemplo, pode andar, correr, lançar jutsus. Podemos codificar essas funções (métodos) no nosso código.
Exemplo
class pessoa:
  def __init__(self, nome, idade, cor_olho):
    self.nome = nome
    self.idade = idade
    self.cor_olho = cor_olho

  def lancarJutsu(self, jutsu):
    print('Lançando jutsu ' + jutsu)

  andando = False

Itachi_Uchiha = pessoa('Itachi Uchira', 21, 'Vermelho')

print(Itachi_Uchiha.nome)
Itachi_Uchiha.lancarJutsu('Tsukuyomi')
Itachi_Uchiha.andando = True
print(Itachi_Uchiha.andando)
Um dos objetivos da programação orientada a objetos é o encapsulamento. Com o encapsulamento as variáveis e funções ficam unidas, independentes do resto do programa. Assim podemos criar um programa em blocos e utilizar esses blocos em outros programas com pouca alteração, e às vezes nenhuma.