SlideShare uma empresa Scribd logo
FUGINDO PARA ASFUGINDO PARA AS
COLINAS COMCOLINAS COM
PYTHONPYTHON
Júlio Biason
Azion Technologies
@juliobiason
julio.biason@gmail.com
http://presentations.juliobiason.net
Fugindo para as colinas com Python - Julio Biason - Tchelinux Bento Gonçalves 2017
Eu sou famoso (ou era) por entrar eu reuniões, fazer uma pergunta e a reunião explodir em discussões (úteis, diga-se
de passagem). Mas eu não fazia isso de propósito.
Eu também tenho costume de falar rápido.
O PROBLEMAO PROBLEMA
"Hello world" não é muito didático
Escrever "Fujam para as colinas"
... com randomização de alguns elementos.
Ex: "Cujam para as folinas", "Lujam para as cofinas"
e "Nujam para as folicas"
SOLUÇÃOSOLUÇÃO
"""Randomize a "Run to the hills" phrase."""
from __future__ import print_function
import random
from argparse import ArgumentParser
CONSONANTS = ['f', 'j', 'c', 'l', 'n']
PASSPHRASE = '{}u{}am para as {}o{}i{}as'
def print_phrase(consonants):
"""Print the phrase with the randomized consonants."""
print(PASSPHRASE.format(*consonants).capitalize())
DOCSTRINGSDOCSTRINGS
"""Randomize a "Run to the hills" phrase."""
Docstrings são utilizadas para documentar coisas em Python: módulos, funções, classes. Essas docstrings depois são
utilizadas para o `help` e para extração de documentação, com aplicativos tipo o Sphinx. Outra coisa: Strings.
Docstrings são strings normais, só que ficam logo abaixo do módulo/classe/função. E como strings normais, elas podem
ser geradas com aspas simples ou duplas; as três aspas significam que a string pode ter quebra de linhas.
MÓDULOS E IMPORTSMÓDULOS E IMPORTS
import random
from argparse import ArgumentParser
Para importar módulos no Python, se usa `import` ou `from X import Y`.
MÓDULOS E IMPORTSMÓDULOS E IMPORTS
Imagine dois módulos: `mod1` e `mod2`. `mod1` tem uma função `func1` e `mod2` tem uma funcão `func2`. Como
ambos estão em espaços separados, de `mod1` eu não consigo chamar `func2` (e nem o contrário).
MÓDULOS E IMPORTSMÓDULOS E IMPORTS
Se eu fizer `import mod2`, tudo que tiver dentro de `mod2` vai vir para o "namespace" atual (assim como quando tu cria
um objeto a partir de uma classe ele vira uma "instância", ao importar um módulo, ele vira um namespace). Agora,
usando o nome do módulo/namespace, eu consigo chamar `func2`, por exemplo. Como fazer a chamada usando o
namespace é visto a seguir.
MÓDULOS E IMPORTSMÓDULOS E IMPORTS
Se eu fizer `from mod2 import func2`, a única coisa que eu vou trazer para o namespace atual é `func2`; se houvessem
outras funções ou outros módulos ou classes, essas não estariam disponíveis para uso.
VARIÁVEIS E TIPOSVARIÁVEIS E TIPOS
CONSONANTS = ['f', 'j', 'c', 'l', 'n']
PASSPHRASE = '{}u{}am para as {}o{}i{}as'
Primeiro, como vimos, strings são marcadas com aspas simples ou duplas. Segundo, temos uma lista: `[]` indicam listas
e, nesse caso, nos temos uma lista de strings (não existe o conceito de "um caractere" como em C, por exemplo --
simplesmente, strings com um caractere só). Terceiro: Existe uma string com uns colchetes no meio. Por si só, esses
colchetes não fazem nada e se alguém tentar imprimir essa string, os colchetes ainda vão estar lá. Quarto: como pode
ser visto, o nome dessas variávels está em maiúsculo. Isso é apenas por notação para indicar constantes, embora o
Python não tenha esse conceito de constantes; isso é apenas convenção (e, mais pra frente, nós vamos estragar essa
convenção.)
FUNÇÕESFUNÇÕES
def print_phrase(consonants):
"""Print the phrase with the randomized consonants."""
Nossa primeira função, sem nada de especial: Primeiro, elas começam com `def`. Segundo, elas tem nomes e, por
padrão, tem que ser em minúsculas e separadas por underscore; não existe nada na linguagem barrando criar funções
com nomes todos em maiúsculas ou com camelCase, mas, de novo, é a convenção da comunidade. Terceiro, funções
tem parâmetros, que seguem a mesma convenção de nomes que já vimos. Quarto, funcões são seguidas de dois
pontos. Quinto: Python não usa colchetes para blocos; blocos são definidos por identação (como pode ser visto pela
docstring).
FUNÇÕESFUNÇÕES
def print_phrase(consonants, something_else):
Para ter mais parâmetros, basta adicionar os parâmetros separados por vírgulas.
FUNCÕESFUNCÕES
def soma(primeiro, segundo):
total = primeiro + segundo
return total
Se uma função tem algum retorno, basta adicionar `return`; funções sem `return` retornam um valor vazio, chamado
`None` (que é o mesmo que `nil`, `null` e tantos outros nomes). Não existe diferença na hora de criar uma "função" e
uma "procedure", como existe no Pascal: Simplesmente funções que não retornam valor não retornam valor (e ficam
como None).
FUNÇÕESFUNÇÕES
soma(1, 2)
Para chamar uma função, basta chamar a função passando os parâmetros.
FUNÇÕESFUNÇÕES
soma(primeiro=2, segundo=3)
O legal de Python é que é possível colocar nome dos parâmetros na chamada da função...
FUNÇÕESFUNÇÕES
soma(segundo=3, primeiro=2)
... e por isso dá pra misturar a ordem dos parâmetros, se ficar mais fácil de ler. Também ajuda se a função tiver vários
parâmetros, sem contar que ajuda quem tiver lendo o código pra não precisar voltar e ver quais são os parâmetros.
FUNÇÕESFUNÇÕES
def soma(primeiro=0, segundo=0):
soma()
soma(1)
soma(segundo=3)
Parâmetros também podem ser opcionais, passando o valor que o mesmo vai ter se não for passado. E, com nomes
nos parâmetros, é possível "pular" por parâmetros que tem valor default.
PAUSA: VARARGSPAUSA: VARARGS
def soma(primeiro, segundo):
total = primeiro + segundo
return total
soma(1)
soma(1, 2, 3)
O que acontece quando não se passa a quantidade correta de parâmetros para uma função?
PAUSA: VARARGSPAUSA: VARARGS
TypeError: soma() takes exactly 2 arguments (3 given)
Simplesmente, o Python se recusa a executar porque não foi passado o número correto de parâmetros.
PAUSA: VARARGSPAUSA: VARARGS
def soma(*valores):
Entram os varargs: Quando um parâmetro tem um asterísco na frente do nome, ele significa "colete tudo que foi
passado que não conseguiu associar a um parâmetro e retorne como lista"
PAUSA: VARARGSPAUSA: VARARGS
def soma(*valores):
print(valores)
soma(1, 2, 3, 4, 5)
[1, 2, 3, 4, 5]
PAUSA: VARARGSPAUSA: VARARGS
def soma(inicial, segundo=0, *valores):
print(inicial)
print(segundo)
print(valores)
soma(2)
2
0
[]
PAUSA: VARARGSPAUSA: VARARGS
E o que acontece com parâmetros com nomes?
PAUSA: VARARGSPAUSA: VARARGS
def soma(**valores):
print(valores)
soma(primeiro=1, segundo=2)
{'primeiro': 1, 'segundo': 2}
Para capturar parâmetros com nomes, usam-se dois asteríscos na frente do nome. Assim como um asterísco significa
"capture tudo que não for capturado por parâmetros normais", dois asteríscos significam "capture tudo que tiver nome e
não for capturado por parâmetros normais". E agora também vimos como funcionam dicionários em Python (que são
chamadas de "objetos", "arrays associativos", "mapas" e outros nomes em outras linguagens).
PAUSA: VARARGSPAUSA: VARARGS
O legal de varargs (e o asterísco) é que ele funciona
pros dois lados: Não só ele transforma parâmetros em
lista, mas ele também pode funcionar para converter
uma lista em parâmetros.
PAUSA: VARARGSPAUSA: VARARGS
params = [4, 4]
soma(*params)
PAUSA: OBJETOSPAUSA: OBJETOS
Sem entrar em detalhes sobre como criar objetos:
Objetos tem métodos (funções associadas a um
objeto)
Para chamar um método, usa-se '.' e o nome do
método
Strings são objetos
PAUSA: OBJETOSPAUSA: OBJETOS
"isso é uma string"
Uma string é um objeto.
PAUSA: OBJETOSPAUSA: OBJETOS
help("isso é uma string")
Pedindo help num objeto vai mostrar o help da classe do objeto; no caso, serão mostrados todos os métodos presentes
no objeto "str", de string. E é por isso que é interessante colocar docstrings: help() vai mostrar tudo que aquele objeto
faz, desde que documentado.
PAUSA: OBJETOSPAUSA: OBJETOS
"isso é uma string".capitalize()
frase = "isso é uma string"
frase.capitalize()
WELCOME TO HELLWELCOME TO HELL
print(PASSPHRASE.format(*consonants).capitalize())
Holy cow!
WELCOME TOWELCOME TO HELLHELL
O que sabemos:
PASSPHRASE é uma string.
.format deve ser um método de strings.
consonants é uma lista
*consonants tá transformando a lista em
parâmetros
capitalize também deve ser um método de
strings
WELCOMEWELCOME TO HELLTO HELL
Lembram que PASSPHRASE tinha um monte de
colchetes no meio?
.format() converte cada um deles para um dos
parâmetros passados.
WELCOMEWELCOME TO HELLTO HELL
'Bem vindo {}!'.format('Júlio')
Bem vindo Júlio!
Format funciona da seguinte format: Tudo que tiver `{}` no meio, ele troca pelo que vier de parâmetro.
WELCOME TO HELLWELCOME TO HELL
PASSPHRASE = '{}u{}am para as {}o{}i{}as'
PASSPHRASE.format('f', 'j', 'c', 'l', 'n')
'fujam para as colinas'
... se eu passar cada uma das consoantes no format com a nossa string original, ele vai trocar cada um dos `{}` pelas
consoantes passadas como parâmetros, uma a uma.
WELCOME TO... HELLWELCOME TO... HELL
CONSONANTS = ['f', 'j', 'c', 'l', 'n']
PASSPHRASE = '{}u{}am para as {}o{}i{}as'
PASSPHRASE.format(*CONSONANTS)
'fujam para as colinas'
... e como a gente viu que dá pra converter listas para parâmetros, usando o `*` a gente passa a lista, que é convertida
para chamada de parâmetros exatamente como anteriormente e ainda temos o mesmo resultado.
WELCOME TO... HELL?WELCOME TO... HELL?
'fujam para as colinas'.capitalize()
Fujam para as colinas
E `capitalize()` simplesmente converte o primeiro caractere para maiúscula.
RANDOMIZAÇÕESRANDOMIZAÇÕES
def totally_random():
"""Run a totally random way."""
random.shuffle(CONSONANTS)
print_phrase(CONSONANTS)
Nada complicado: A gente chama o `random.shuffle`, que é um método do módulo `random` que a gente fez import lá
no começo. O único problema aqui é que `shuffle` faz *in-place*, ou seja, a lista vai ter o conteúdo alterado.
RANDOMIZAÇÕESRANDOMIZAÇÕES
def switch_two():
"""Run by changing two steps at a time."""
first = random.randint(0, 1)
second = random.randint(2, 4)
Essa função simplesmente escolhe dois números randomicamente. O primeiro vai de 0 a 1. E o segundo de 2 a 4. ...
que, se a gente contar, são exatamente as posições das consoantes de "fujam" e de "colinas", respecticamente,
começando por 0.
WELCOME TO HELL, MAYBE?WELCOME TO HELL, MAYBE?
CONSONANTS[second], CONSONANTS[first] = 
CONSONANTS[first], CONSONANTS[second]
WELCOME TO LISTAS!WELCOME TO LISTAS!
# CONSONANTS = ['f', 'j', 'c', 'l', 'n']
# second = random.randint(2, 4)
CONSONANTS[second]
Para acessar um elemento específico de uma lista é só usar colchetes e um índice; ou seja, iremos pegar a consoante
indicada pelo número randômico seleciado (entre 2 e 4, inclusive).
WELCOME TO TUPLES!WELCOME TO TUPLES!
Tuplas são como listas, só que não podem ser
alteradas.
E pra criar uma tupla:
Ou mais bonitinho: (valor, valor)
valor, valor
WELCOME TO DESTRUCTURINGWELCOME TO DESTRUCTURING
primeiro, segundo = [1, 2]
print(primeiro)
print(segundo)
1
2
Destructuring (e não destroying) serve para "desmontar" tuplas e listas. Por exemplo, a lista tem dois elementos; se eu
apontar os dois valores para ela, o primeiro vai ter o primeiro valor e o segundo, o segundo; se forem três, eu preciso de
três variáveis. E se o número de váriaveis estiver errado, dá erro.
TUDO JUNTO, AGORA!TUDO JUNTO, AGORA!
CONSONANTS[second], CONSONANTS[first] = 
CONSONANTS[first], CONSONANTS[second]
tmp = CONSONANTS[first]
CONSONANTS[first] = CONSONANTS[second]
CONSONANTS[second] = tmp
Ou seja, estamos pegando a consonante escolhida randomicamente entre 0 e 1 (f e j) e a consoante escolhida
randomicante entre 2 e 4 (c, l, n) e criando uma tupla com esses dois valores; a seguir a gente desmonta (destructura)
esses dois na ordem inversa.
O PAI DE TODOS MÓDULOSO PAI DE TODOS MÓDULOS
if __name__ == "__main__":
Falamos antes que um módulo, quando importado, vira um namespace. Pois bem, namespaces tem nomes que podem
ser acessados com `__name__`. E o que acontece quando um script é executado diretamente pela linha de comando?
O módulo é "importado" pelo interpretador, mas qual é o nome do namespace? `__main__`. Essa construção permite
que scripts sejam tanto executados diretamente quando importados. No caso, todo o conteúdo desse if só vai ser
executado se for executado pela linha de comando. Se for importado por um outro script, o script vai ter acesso às
funções, mas não vai ser afetado pela leitura da linha de comando.
A LINHA DE COMANDOA LINHA DE COMANDO
args = ArgumentParser()
args.add_argument('-t', '--totally',
dest='totally',
default=False,
action='store_true',
help='Like, toootaly random')
args.add_argument('-s', '--short',
dest='short',
default=False,
action='store_true',
help='Not so random')
result = args.parse_args()
Nada de muito mágico aqui, exceto que o ArgumentParser faz um monte de coisas pra nós: nós só definimos os
parametros, onde eles vão ficar no final, qual ação a ser tomada e um help. E o ArgumentParser faz todo o resto.
E OS FINALMENTES...E OS FINALMENTES...
if result.totally:
totally_random()
elif result.short:
switch_two()
else:
print('Dude, option!')
E a gente simplesmente acessa as propriedades do objeto de resultado do `parse_args` e, se for verdadeiro (True),
executamos uma função ou a outra.
PERGUNTAS?PERGUNTAS?

Mais conteúdo relacionado

PPTX
PHP Básico - Parte 3
PDF
Aprendendo ruby
PDF
Curso java 06 - mais construtores, interfaces e polimorfismo
PPT
4º Aula do Grupo de estudos sobre funções
PPTX
Curso java 01 - molhando os pés com java
PDF
Vetores, Matrizes e Strings em C Parte 3
PDF
Algoritmos e Programação: Manipulação de strings
PPT
Aula4
PHP Básico - Parte 3
Aprendendo ruby
Curso java 06 - mais construtores, interfaces e polimorfismo
4º Aula do Grupo de estudos sobre funções
Curso java 01 - molhando os pés com java
Vetores, Matrizes e Strings em C Parte 3
Algoritmos e Programação: Manipulação de strings
Aula4

Mais procurados (20)

KEY
Introdução ao Framework Grails
PPTX
Linguagem C - Strings
PPT
5.II SACIC - 2010 - Desenvolvimento de Aplicações para TVDigital com NCLUA
PDF
Threads 09: Paralelismo
PDF
Vetores, Matrizes e Strings em C Parte 1
PDF
Javafx Introdução
ODP
Java 06 Strings Arrays
PDF
Iteraveis e geradores em Python
PDF
Programação funcional tipada: uma introdução
PDF
Threads 06: Coleções concorrentes
PDF
DOCX
Comandos de controle de fluxo do php
PDF
Android - Dicas de Performance
PDF
Curso java 04 - ap is e bibliotecas
PDF
Curso de Java: Introdução a lambda e Streams
PDF
Desenvolvendo Extensões PECL
PPTX
Estrutura de dados em Java - Filas
PDF
Programando em python funcoes
PDF
Programando em python tuplas e strings
Introdução ao Framework Grails
Linguagem C - Strings
5.II SACIC - 2010 - Desenvolvimento de Aplicações para TVDigital com NCLUA
Threads 09: Paralelismo
Vetores, Matrizes e Strings em C Parte 1
Javafx Introdução
Java 06 Strings Arrays
Iteraveis e geradores em Python
Programação funcional tipada: uma introdução
Threads 06: Coleções concorrentes
Comandos de controle de fluxo do php
Android - Dicas de Performance
Curso java 04 - ap is e bibliotecas
Curso de Java: Introdução a lambda e Streams
Desenvolvendo Extensões PECL
Estrutura de dados em Java - Filas
Programando em python funcoes
Programando em python tuplas e strings
Anúncio

Semelhante a Fugindo para as colinas com Python - Julio Biason - Tchelinux Bento Gonçalves 2017 (20)

PDF
Python: a primeira mordida
PDF
Python Introdução e Orientação a Objetos.pdf
PDF
Py sintaxe
PDF
Python e seus desafios
ODP
Python para Programadores
KEY
Introdução à Linguagem de programação Python
PDF
Python Mini Curso V0812
PDF
Aula 01 python
KEY
Python 02
ODP
Pymordida0 Semana de computação da SOCIESC - 2008/10
PDF
Python Class
PDF
minicurso-python-getmeeting.pdf
PPT
002 - Programando em Python - Tipos Basicos.ppt
PDF
Introdução a linguagem Python 2.7
PDF
Python introdução a linguagem de programação
PPTX
IEEEweek 2017 @ DETI Univ. Aveiro - Workshop Python
PDF
Python Training #1 ed.6
PDF
Python Training #1 - ed5
PDF
Introdução a linguagem de programação Python
Python: a primeira mordida
Python Introdução e Orientação a Objetos.pdf
Py sintaxe
Python e seus desafios
Python para Programadores
Introdução à Linguagem de programação Python
Python Mini Curso V0812
Aula 01 python
Python 02
Pymordida0 Semana de computação da SOCIESC - 2008/10
Python Class
minicurso-python-getmeeting.pdf
002 - Programando em Python - Tipos Basicos.ppt
Introdução a linguagem Python 2.7
Python introdução a linguagem de programação
IEEEweek 2017 @ DETI Univ. Aveiro - Workshop Python
Python Training #1 ed.6
Python Training #1 - ed5
Introdução a linguagem de programação Python
Anúncio

Mais de Tchelinux (20)

PDF
Do Zero ao YouTube em menos de 10 softwares livres - Vinícius Alves Hax - Tch...
PDF
Insegurança na Internet - Diego Luiz Silva da Costa - Tchelinux 2019 Rio Grande
PDF
Explorando Editores de Texto Open Source - Gabriel Prestes Ritta - Tchelinux ...
PDF
Desenvolvendo Jogos com PyGame - Jerônimo Medina Madruga - Tchelinux 2019 Rio...
PDF
Me formei. E agora? - Matheus Cezar - Tchelinux 2019 Rio Grande
PDF
APIs, REST e RESTful: O que os programadores precisam saber? - Marcos Echevar...
PPTX
Shell Script: Seu melhor amigo na automatização de instalações e configuraçõe...
PDF
WebRTC: Comunicação aberta em tempo real - Nelson Dutra Junior - Tchelinux 20...
PDF
Introdução à programação funcional com Clojure - Victor Hechel Colares - Tche...
PDF
Construindo um Data Warehouse - Vítor Resing Plentz - Tchelinux 2019 Rio Grande
PDF
Bikeshedding - Márcio Josué Ramos Torres - Tchelinux 2019 Rio Grande
PDF
Produção de textos com Latex - Samuel Francisco Ferrigo - Tchelinux Caxias do...
PDF
A tecnologia no futuro e nas mãos de quem ela estará - Jaqueline Trevizan, Ne...
ODP
oVirt uma solução de virtualização distribuída opensource - Daniel Lara - Tch...
PDF
Sistemas Embarcados e Buildroot - Renato Severo - Tchelinux Caxias do Sul 2019
PDF
Com que ônibus eu vou? Uma gentil introdução ao Python.
PDF
O TCC... um dia ele chega! (The beautiful and easy LaTeX way.
PDF
Não deixe para testar depois o que você pode testar antes.
PDF
Desenvolvendo jogos com pygame
PDF
Essa câmera faz fotos muito boas, né?
Do Zero ao YouTube em menos de 10 softwares livres - Vinícius Alves Hax - Tch...
Insegurança na Internet - Diego Luiz Silva da Costa - Tchelinux 2019 Rio Grande
Explorando Editores de Texto Open Source - Gabriel Prestes Ritta - Tchelinux ...
Desenvolvendo Jogos com PyGame - Jerônimo Medina Madruga - Tchelinux 2019 Rio...
Me formei. E agora? - Matheus Cezar - Tchelinux 2019 Rio Grande
APIs, REST e RESTful: O que os programadores precisam saber? - Marcos Echevar...
Shell Script: Seu melhor amigo na automatização de instalações e configuraçõe...
WebRTC: Comunicação aberta em tempo real - Nelson Dutra Junior - Tchelinux 20...
Introdução à programação funcional com Clojure - Victor Hechel Colares - Tche...
Construindo um Data Warehouse - Vítor Resing Plentz - Tchelinux 2019 Rio Grande
Bikeshedding - Márcio Josué Ramos Torres - Tchelinux 2019 Rio Grande
Produção de textos com Latex - Samuel Francisco Ferrigo - Tchelinux Caxias do...
A tecnologia no futuro e nas mãos de quem ela estará - Jaqueline Trevizan, Ne...
oVirt uma solução de virtualização distribuída opensource - Daniel Lara - Tch...
Sistemas Embarcados e Buildroot - Renato Severo - Tchelinux Caxias do Sul 2019
Com que ônibus eu vou? Uma gentil introdução ao Python.
O TCC... um dia ele chega! (The beautiful and easy LaTeX way.
Não deixe para testar depois o que você pode testar antes.
Desenvolvendo jogos com pygame
Essa câmera faz fotos muito boas, né?

Último (11)

PPTX
Viasol Energia Solar -Soluções para geração e economia de energia
PDF
eBook - GUIA DE CONSULTA RAPIDA EM ROTEADORES E SWITCHES CISCO - VOL I.pdf
PDF
Manejo integrado de pragas na cultura do algodão
PPTX
Arquitetura de computadores - Memórias Secundárias
PPTX
Utilizando code blockes por andre backes
PDF
Termos utilizados na designação de relação entre pessoa e uma obra.pdf
PPTX
Proposta de Implementação de uma Rede de Computador Cabeada.pptx
PPTX
Eng. Software - pontos essenciais para o início
PPTX
Tipos de servidor em redes de computador.pptx
PPTX
Design - Introdução a Gestalt e teoria das formas
PPTX
Informática Aplicada Informática Aplicada Plano de Ensino - estudo de caso NR...
Viasol Energia Solar -Soluções para geração e economia de energia
eBook - GUIA DE CONSULTA RAPIDA EM ROTEADORES E SWITCHES CISCO - VOL I.pdf
Manejo integrado de pragas na cultura do algodão
Arquitetura de computadores - Memórias Secundárias
Utilizando code blockes por andre backes
Termos utilizados na designação de relação entre pessoa e uma obra.pdf
Proposta de Implementação de uma Rede de Computador Cabeada.pptx
Eng. Software - pontos essenciais para o início
Tipos de servidor em redes de computador.pptx
Design - Introdução a Gestalt e teoria das formas
Informática Aplicada Informática Aplicada Plano de Ensino - estudo de caso NR...

Fugindo para as colinas com Python - Julio Biason - Tchelinux Bento Gonçalves 2017

  • 1. FUGINDO PARA ASFUGINDO PARA AS COLINAS COMCOLINAS COM PYTHONPYTHON
  • 4. Eu sou famoso (ou era) por entrar eu reuniões, fazer uma pergunta e a reunião explodir em discussões (úteis, diga-se de passagem). Mas eu não fazia isso de propósito.
  • 5. Eu também tenho costume de falar rápido.
  • 6. O PROBLEMAO PROBLEMA "Hello world" não é muito didático Escrever "Fujam para as colinas" ... com randomização de alguns elementos. Ex: "Cujam para as folinas", "Lujam para as cofinas" e "Nujam para as folicas"
  • 7. SOLUÇÃOSOLUÇÃO """Randomize a "Run to the hills" phrase.""" from __future__ import print_function import random from argparse import ArgumentParser CONSONANTS = ['f', 'j', 'c', 'l', 'n'] PASSPHRASE = '{}u{}am para as {}o{}i{}as' def print_phrase(consonants): """Print the phrase with the randomized consonants.""" print(PASSPHRASE.format(*consonants).capitalize())
  • 8. DOCSTRINGSDOCSTRINGS """Randomize a "Run to the hills" phrase.""" Docstrings são utilizadas para documentar coisas em Python: módulos, funções, classes. Essas docstrings depois são utilizadas para o `help` e para extração de documentação, com aplicativos tipo o Sphinx. Outra coisa: Strings. Docstrings são strings normais, só que ficam logo abaixo do módulo/classe/função. E como strings normais, elas podem ser geradas com aspas simples ou duplas; as três aspas significam que a string pode ter quebra de linhas.
  • 9. MÓDULOS E IMPORTSMÓDULOS E IMPORTS import random from argparse import ArgumentParser Para importar módulos no Python, se usa `import` ou `from X import Y`.
  • 10. MÓDULOS E IMPORTSMÓDULOS E IMPORTS Imagine dois módulos: `mod1` e `mod2`. `mod1` tem uma função `func1` e `mod2` tem uma funcão `func2`. Como ambos estão em espaços separados, de `mod1` eu não consigo chamar `func2` (e nem o contrário).
  • 11. MÓDULOS E IMPORTSMÓDULOS E IMPORTS Se eu fizer `import mod2`, tudo que tiver dentro de `mod2` vai vir para o "namespace" atual (assim como quando tu cria um objeto a partir de uma classe ele vira uma "instância", ao importar um módulo, ele vira um namespace). Agora, usando o nome do módulo/namespace, eu consigo chamar `func2`, por exemplo. Como fazer a chamada usando o namespace é visto a seguir.
  • 12. MÓDULOS E IMPORTSMÓDULOS E IMPORTS Se eu fizer `from mod2 import func2`, a única coisa que eu vou trazer para o namespace atual é `func2`; se houvessem outras funções ou outros módulos ou classes, essas não estariam disponíveis para uso.
  • 13. VARIÁVEIS E TIPOSVARIÁVEIS E TIPOS CONSONANTS = ['f', 'j', 'c', 'l', 'n'] PASSPHRASE = '{}u{}am para as {}o{}i{}as' Primeiro, como vimos, strings são marcadas com aspas simples ou duplas. Segundo, temos uma lista: `[]` indicam listas e, nesse caso, nos temos uma lista de strings (não existe o conceito de "um caractere" como em C, por exemplo -- simplesmente, strings com um caractere só). Terceiro: Existe uma string com uns colchetes no meio. Por si só, esses colchetes não fazem nada e se alguém tentar imprimir essa string, os colchetes ainda vão estar lá. Quarto: como pode ser visto, o nome dessas variávels está em maiúsculo. Isso é apenas por notação para indicar constantes, embora o Python não tenha esse conceito de constantes; isso é apenas convenção (e, mais pra frente, nós vamos estragar essa convenção.)
  • 14. FUNÇÕESFUNÇÕES def print_phrase(consonants): """Print the phrase with the randomized consonants.""" Nossa primeira função, sem nada de especial: Primeiro, elas começam com `def`. Segundo, elas tem nomes e, por padrão, tem que ser em minúsculas e separadas por underscore; não existe nada na linguagem barrando criar funções com nomes todos em maiúsculas ou com camelCase, mas, de novo, é a convenção da comunidade. Terceiro, funções tem parâmetros, que seguem a mesma convenção de nomes que já vimos. Quarto, funcões são seguidas de dois pontos. Quinto: Python não usa colchetes para blocos; blocos são definidos por identação (como pode ser visto pela docstring).
  • 15. FUNÇÕESFUNÇÕES def print_phrase(consonants, something_else): Para ter mais parâmetros, basta adicionar os parâmetros separados por vírgulas.
  • 16. FUNCÕESFUNCÕES def soma(primeiro, segundo): total = primeiro + segundo return total Se uma função tem algum retorno, basta adicionar `return`; funções sem `return` retornam um valor vazio, chamado `None` (que é o mesmo que `nil`, `null` e tantos outros nomes). Não existe diferença na hora de criar uma "função" e uma "procedure", como existe no Pascal: Simplesmente funções que não retornam valor não retornam valor (e ficam como None).
  • 17. FUNÇÕESFUNÇÕES soma(1, 2) Para chamar uma função, basta chamar a função passando os parâmetros.
  • 18. FUNÇÕESFUNÇÕES soma(primeiro=2, segundo=3) O legal de Python é que é possível colocar nome dos parâmetros na chamada da função...
  • 19. FUNÇÕESFUNÇÕES soma(segundo=3, primeiro=2) ... e por isso dá pra misturar a ordem dos parâmetros, se ficar mais fácil de ler. Também ajuda se a função tiver vários parâmetros, sem contar que ajuda quem tiver lendo o código pra não precisar voltar e ver quais são os parâmetros.
  • 20. FUNÇÕESFUNÇÕES def soma(primeiro=0, segundo=0): soma() soma(1) soma(segundo=3) Parâmetros também podem ser opcionais, passando o valor que o mesmo vai ter se não for passado. E, com nomes nos parâmetros, é possível "pular" por parâmetros que tem valor default.
  • 21. PAUSA: VARARGSPAUSA: VARARGS def soma(primeiro, segundo): total = primeiro + segundo return total soma(1) soma(1, 2, 3) O que acontece quando não se passa a quantidade correta de parâmetros para uma função?
  • 22. PAUSA: VARARGSPAUSA: VARARGS TypeError: soma() takes exactly 2 arguments (3 given) Simplesmente, o Python se recusa a executar porque não foi passado o número correto de parâmetros.
  • 23. PAUSA: VARARGSPAUSA: VARARGS def soma(*valores): Entram os varargs: Quando um parâmetro tem um asterísco na frente do nome, ele significa "colete tudo que foi passado que não conseguiu associar a um parâmetro e retorne como lista"
  • 24. PAUSA: VARARGSPAUSA: VARARGS def soma(*valores): print(valores) soma(1, 2, 3, 4, 5) [1, 2, 3, 4, 5]
  • 25. PAUSA: VARARGSPAUSA: VARARGS def soma(inicial, segundo=0, *valores): print(inicial) print(segundo) print(valores) soma(2) 2 0 []
  • 26. PAUSA: VARARGSPAUSA: VARARGS E o que acontece com parâmetros com nomes?
  • 27. PAUSA: VARARGSPAUSA: VARARGS def soma(**valores): print(valores) soma(primeiro=1, segundo=2) {'primeiro': 1, 'segundo': 2} Para capturar parâmetros com nomes, usam-se dois asteríscos na frente do nome. Assim como um asterísco significa "capture tudo que não for capturado por parâmetros normais", dois asteríscos significam "capture tudo que tiver nome e não for capturado por parâmetros normais". E agora também vimos como funcionam dicionários em Python (que são chamadas de "objetos", "arrays associativos", "mapas" e outros nomes em outras linguagens).
  • 28. PAUSA: VARARGSPAUSA: VARARGS O legal de varargs (e o asterísco) é que ele funciona pros dois lados: Não só ele transforma parâmetros em lista, mas ele também pode funcionar para converter uma lista em parâmetros.
  • 29. PAUSA: VARARGSPAUSA: VARARGS params = [4, 4] soma(*params)
  • 30. PAUSA: OBJETOSPAUSA: OBJETOS Sem entrar em detalhes sobre como criar objetos: Objetos tem métodos (funções associadas a um objeto) Para chamar um método, usa-se '.' e o nome do método Strings são objetos
  • 31. PAUSA: OBJETOSPAUSA: OBJETOS "isso é uma string" Uma string é um objeto.
  • 32. PAUSA: OBJETOSPAUSA: OBJETOS help("isso é uma string") Pedindo help num objeto vai mostrar o help da classe do objeto; no caso, serão mostrados todos os métodos presentes no objeto "str", de string. E é por isso que é interessante colocar docstrings: help() vai mostrar tudo que aquele objeto faz, desde que documentado.
  • 33. PAUSA: OBJETOSPAUSA: OBJETOS "isso é uma string".capitalize() frase = "isso é uma string" frase.capitalize()
  • 34. WELCOME TO HELLWELCOME TO HELL print(PASSPHRASE.format(*consonants).capitalize()) Holy cow!
  • 35. WELCOME TOWELCOME TO HELLHELL O que sabemos: PASSPHRASE é uma string. .format deve ser um método de strings. consonants é uma lista *consonants tá transformando a lista em parâmetros capitalize também deve ser um método de strings
  • 36. WELCOMEWELCOME TO HELLTO HELL Lembram que PASSPHRASE tinha um monte de colchetes no meio? .format() converte cada um deles para um dos parâmetros passados.
  • 37. WELCOMEWELCOME TO HELLTO HELL 'Bem vindo {}!'.format('Júlio') Bem vindo Júlio! Format funciona da seguinte format: Tudo que tiver `{}` no meio, ele troca pelo que vier de parâmetro.
  • 38. WELCOME TO HELLWELCOME TO HELL PASSPHRASE = '{}u{}am para as {}o{}i{}as' PASSPHRASE.format('f', 'j', 'c', 'l', 'n') 'fujam para as colinas' ... se eu passar cada uma das consoantes no format com a nossa string original, ele vai trocar cada um dos `{}` pelas consoantes passadas como parâmetros, uma a uma.
  • 39. WELCOME TO... HELLWELCOME TO... HELL CONSONANTS = ['f', 'j', 'c', 'l', 'n'] PASSPHRASE = '{}u{}am para as {}o{}i{}as' PASSPHRASE.format(*CONSONANTS) 'fujam para as colinas' ... e como a gente viu que dá pra converter listas para parâmetros, usando o `*` a gente passa a lista, que é convertida para chamada de parâmetros exatamente como anteriormente e ainda temos o mesmo resultado.
  • 40. WELCOME TO... HELL?WELCOME TO... HELL? 'fujam para as colinas'.capitalize() Fujam para as colinas E `capitalize()` simplesmente converte o primeiro caractere para maiúscula.
  • 41. RANDOMIZAÇÕESRANDOMIZAÇÕES def totally_random(): """Run a totally random way.""" random.shuffle(CONSONANTS) print_phrase(CONSONANTS) Nada complicado: A gente chama o `random.shuffle`, que é um método do módulo `random` que a gente fez import lá no começo. O único problema aqui é que `shuffle` faz *in-place*, ou seja, a lista vai ter o conteúdo alterado.
  • 42. RANDOMIZAÇÕESRANDOMIZAÇÕES def switch_two(): """Run by changing two steps at a time.""" first = random.randint(0, 1) second = random.randint(2, 4) Essa função simplesmente escolhe dois números randomicamente. O primeiro vai de 0 a 1. E o segundo de 2 a 4. ... que, se a gente contar, são exatamente as posições das consoantes de "fujam" e de "colinas", respecticamente, começando por 0.
  • 43. WELCOME TO HELL, MAYBE?WELCOME TO HELL, MAYBE? CONSONANTS[second], CONSONANTS[first] = CONSONANTS[first], CONSONANTS[second]
  • 44. WELCOME TO LISTAS!WELCOME TO LISTAS! # CONSONANTS = ['f', 'j', 'c', 'l', 'n'] # second = random.randint(2, 4) CONSONANTS[second] Para acessar um elemento específico de uma lista é só usar colchetes e um índice; ou seja, iremos pegar a consoante indicada pelo número randômico seleciado (entre 2 e 4, inclusive).
  • 45. WELCOME TO TUPLES!WELCOME TO TUPLES! Tuplas são como listas, só que não podem ser alteradas. E pra criar uma tupla: Ou mais bonitinho: (valor, valor) valor, valor
  • 46. WELCOME TO DESTRUCTURINGWELCOME TO DESTRUCTURING primeiro, segundo = [1, 2] print(primeiro) print(segundo) 1 2 Destructuring (e não destroying) serve para "desmontar" tuplas e listas. Por exemplo, a lista tem dois elementos; se eu apontar os dois valores para ela, o primeiro vai ter o primeiro valor e o segundo, o segundo; se forem três, eu preciso de três variáveis. E se o número de váriaveis estiver errado, dá erro.
  • 47. TUDO JUNTO, AGORA!TUDO JUNTO, AGORA! CONSONANTS[second], CONSONANTS[first] = CONSONANTS[first], CONSONANTS[second] tmp = CONSONANTS[first] CONSONANTS[first] = CONSONANTS[second] CONSONANTS[second] = tmp Ou seja, estamos pegando a consonante escolhida randomicamente entre 0 e 1 (f e j) e a consoante escolhida randomicante entre 2 e 4 (c, l, n) e criando uma tupla com esses dois valores; a seguir a gente desmonta (destructura) esses dois na ordem inversa.
  • 48. O PAI DE TODOS MÓDULOSO PAI DE TODOS MÓDULOS if __name__ == "__main__": Falamos antes que um módulo, quando importado, vira um namespace. Pois bem, namespaces tem nomes que podem ser acessados com `__name__`. E o que acontece quando um script é executado diretamente pela linha de comando? O módulo é "importado" pelo interpretador, mas qual é o nome do namespace? `__main__`. Essa construção permite que scripts sejam tanto executados diretamente quando importados. No caso, todo o conteúdo desse if só vai ser executado se for executado pela linha de comando. Se for importado por um outro script, o script vai ter acesso às funções, mas não vai ser afetado pela leitura da linha de comando.
  • 49. A LINHA DE COMANDOA LINHA DE COMANDO args = ArgumentParser() args.add_argument('-t', '--totally', dest='totally', default=False, action='store_true', help='Like, toootaly random') args.add_argument('-s', '--short', dest='short', default=False, action='store_true', help='Not so random') result = args.parse_args() Nada de muito mágico aqui, exceto que o ArgumentParser faz um monte de coisas pra nós: nós só definimos os parametros, onde eles vão ficar no final, qual ação a ser tomada e um help. E o ArgumentParser faz todo o resto.
  • 50. E OS FINALMENTES...E OS FINALMENTES... if result.totally: totally_random() elif result.short: switch_two() else: print('Dude, option!') E a gente simplesmente acessa as propriedades do objeto de resultado do `parse_args` e, se for verdadeiro (True), executamos uma função ou a outra.