FUGINDO PARA ASFUGINDO PARA AS
COLINAS COMCOLINAS COM
PYTHONPYTHON
Júlio Biason
Azion Technologies
@juliobiason
julio.biason@gmail.com
http://presentations.juliobiason.net
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?

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

  • 1.
    FUGINDO PARA ASFUGINDOPARA AS COLINAS COMCOLINAS COM PYTHONPYTHON
  • 2.
  • 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 tenhocostume de falar rápido.
  • 6.
    O PROBLEMAO PROBLEMA "Helloworld" 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 "Runto 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 "Runto 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ÓDULOSE 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ÓDULOSE 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ÓDULOSE 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ÓDULOSE 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ÁVEISE 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 thephrase 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): Parater 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 chamaruma função, basta chamar a função passando os parâmetros.
  • 18.
    FUNÇÕESFUNÇÕES soma(primeiro=2, segundo=3) O legalde Python é que é possível colocar nome dos parâmetros na chamada da função...
  • 19.
    FUNÇÕESFUNÇÕES soma(segundo=3, primeiro=2) ... epor 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âmetrostambé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 defsoma(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 defsoma(*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 defsoma(*valores): print(valores) soma(1, 2, 3, 4, 5) [1, 2, 3, 4, 5]
  • 25.
    PAUSA: VARARGSPAUSA: VARARGS defsoma(inicial, segundo=0, *valores): print(inicial) print(segundo) print(valores) soma(2) 2 0 []
  • 26.
    PAUSA: VARARGSPAUSA: VARARGS Eo que acontece com parâmetros com nomes?
  • 27.
    PAUSA: VARARGSPAUSA: VARARGS defsoma(**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 Olegal 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.
  • 30.
    PAUSA: OBJETOSPAUSA: OBJETOS Sementrar 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 HELLWELCOMETO HELL print(PASSPHRASE.format(*consonants).capitalize()) Holy cow!
  • 35.
    WELCOME TOWELCOME TOHELLHELL 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 HELLTOHELL Lembram que PASSPHRASE tinha um monte de colchetes no meio? .format() converte cada um deles para um dos parâmetros passados.
  • 37.
    WELCOMEWELCOME TO HELLTOHELL '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 HELLWELCOMETO 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... HELLWELCOMETO... 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?WELCOMETO... 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 atotally 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 bychanging 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!WELCOMETO 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!WELCOMETO 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 DESTRUCTURINGWELCOMETO 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!TUDOJUNTO, 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 DETODOS 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 DECOMANDOA 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...EOS 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.
  • 51.