Created
May 16, 2025 13:02
-
-
Save tinogomes/e4e04d5fe10598a98536fae767fce076 to your computer and use it in GitHub Desktop.
Aprenda X em Y Minutos
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Comentários em uma única linha começam com uma cerquilha (também conhecido por sustenido). | |
""" Strings de várias linhas podem ser escritas | |
usando três ", e são comumente usadas | |
como comentários. | |
""" | |
#################################################### | |
## 1. Tipos de dados primitivos e operadores | |
#################################################### | |
# Você usa números normalmente | |
3 # => 3 | |
# Matemática é como você espera que seja | |
1 + 1 # => 2 | |
8 - 1 # => 7 | |
10 * 2 # => 20 | |
# Números são inteiros por padrão, exceto na divisão, que retorna número | |
# de ponto flutuante (float). | |
35 / 5 # => 7.0 | |
# O resultado da divisão inteira arredonda para baixo tanto para números | |
# positivos como para negativos. | |
5 // 3 # => 1 | |
5.0 // 3.0 # => 1.0 # funciona em float também | |
-5 // 3 # => -2 | |
-5.0 // 3.0 # => -2.0 | |
# Quando você usa um float, o resultado é float. | |
3 * 2.0 # => 6.0 | |
# operador módulo | |
7 % 3 # => 1 | |
# Exponenciação (x**y, x elevado à potência y) | |
2**4 # => 16 | |
# Determine a precedência usando parênteses | |
(1 + 3) * 2 # => 8 | |
# Valores lógicos são primitivos (Atenção à primeira letra maiúscula) | |
True | |
False | |
# negação lógica com not | |
not True # => False | |
not False # => True | |
# Operadores lógicos | |
# Observe que "and" e "or" são sensíveis a maiúsculas e minúsculas | |
True and False # => False | |
False or True # => True | |
# Observe a utilização de operadores lógicos com números inteiros | |
0 and 2 # => 0 | |
-5 or 0 # => -5 | |
0 == False # => True | |
2 == True # => False | |
1 == True # => True | |
# Igualdade é == | |
1 == 1 # => True | |
2 == 1 # => False | |
# Diferença é != | |
1 != 1 # => False | |
2 != 1 # => True | |
# Mais comparações | |
1 < 10 # => True | |
1 > 10 # => False | |
2 <= 2 # => True | |
2 >= 2 # => True | |
# Comparações podem ser agrupadas | |
1 < 2 < 3 # => True | |
2 < 3 < 2 # => False | |
# 'is' verifica se duas variáveis representam o mesmo endereço | |
# na memória; '==' verifica se duas variáveis têm o mesmo valor | |
a = [1, 2, 3, 4] # Referência a uma nova lista, [1, 2, 3, 4] | |
b = a # b referencia o que está referenciado por a | |
b is a # => True, a e b referenciam o mesmo objeto | |
b == a # => True, objetos a e b tem o mesmo conteúdo | |
b = [1, 2, 3, 4] # Referência a uma nova lista, [1, 2, 3, 4] | |
b is a # => False, a e b não referenciam o mesmo objeto | |
b == a # => True, objetos a e b tem o mesmo conteúdo | |
# Strings são criadas com " ou ' | |
"Isto é uma string." | |
'Isto também é uma string.' | |
# Strings também podem ser somadas! Mas tente não fazer isso. | |
"Olá " + "mundo!" # => "Olá mundo!" | |
# Strings podem ser somadas sem usar o '+' | |
"Olá " "mundo!" # => "Olá mundo!" | |
# Uma string pode ser manipulada como se fosse uma lista de caracteres | |
"Isso é uma string"[0] # => 'I' | |
# .format pode ser usado para formatar strings, dessa forma: | |
"{} podem ser {}".format("Strings", "interpoladas") # => "Strings podem ser interpoladas" | |
# Você pode repetir os argumentos para digitar menos. | |
"Seja ágil {0}, seja rápido {0}, salte sobre o {1} {0}".format("Jack", "castiçal") | |
# => "Seja ágil Jack, seja rápido Jack, salte sobre o castiçal Jack." | |
# Você pode usar palavras-chave se quiser contar. | |
"{nome} quer comer {comida}".format(nome="Beto", comida="lasanha") # => "Beto quer comer lasanha" | |
# Se você precisa executar seu código Python3 com um interpretador Python 2.5 ou acima, você pode usar a velha forma para formatação de texto: | |
"%s podem ser %s da forma %s" % ("Strings", "interpoladas", "antiga") # => "Strings podem ser interpoladas da forma antiga" | |
# None é um objeto | |
None # => None | |
# Não use o operador de igualdade "==" para comparar objetos com None | |
# Use "is" para isso. Ele checará pela identidade dos objetos. | |
"etc" is None # => False | |
None is None # => True | |
# None, 0, e strings/listas/dicionários vazios todos retornam False. | |
# Qualquer outra coisa retorna True | |
bool(0) # => False | |
bool("") # => False | |
bool([]) # => False | |
bool({}) # => False | |
#################################################### | |
## 2. Variáveis e coleções | |
#################################################### | |
# Python tem uma função print | |
print("Eu sou o Python. Prazer em conhecer!") # => Eu sou o Python. Prazer em conhecer! | |
# Por padrão a função print também imprime o caractere de nova linha ao final. | |
# Use o argumento opcional end para mudar o caractere final. | |
print("Olá, Mundo", end="!") # => Olá, Mundo! | |
# Forma simples para capturar dados de entrada via console | |
input_string_var = input("Digite alguma coisa: ") # Retorna o que foi digitado em uma string | |
# Observação: Em versões antigas do Python, o método input() era chamado raw_input() | |
# Não é necessário declarar variáveis antes de iniciá-las | |
# É uma convenção usar letras_minúsculas_com_sublinhados | |
alguma_variavel = 5 | |
alguma_variavel # => 5 | |
# Acessar uma variável que não tenha sido inicializada gera uma exceção. | |
# Veja Controle de Fluxo para aprender mais sobre tratamento de exceções. | |
alguma_variavel_nao_inicializada # Gera a exceção NameError | |
# Listas armazenam sequências | |
li = [] | |
# Você pode iniciar uma lista com valores | |
outra_li = [4, 5, 6] | |
# Adicione conteúdo ao fim da lista com append | |
li.append(1) # li agora é [1] | |
li.append(2) # li agora é [1, 2] | |
li.append(4) # li agora é [1, 2, 4] | |
li.append(3) # li agora é [1, 2, 4, 3] | |
# Remova do final da lista com pop | |
li.pop() # => 3 e agora li é [1, 2, 4] | |
# Vamos colocá-lo lá novamente! | |
li.append(3) # li agora é [1, 2, 4, 3] novamente. | |
# Acesse uma lista da mesma forma que você faz com um array | |
li[0] # => 1 | |
# Acessando o último elemento | |
li[-1] # => 3 | |
# Acessar além dos limites gera um IndexError | |
li[4] # Gera o IndexError | |
# Você pode acessar vários elementos com a sintaxe de limites | |
# Inclusivo para o primeiro termo, exclusivo para o segundo | |
li[1:3] # => [2, 4] | |
# Omitindo o final | |
li[2:] # => [4, 3] | |
# Omitindo o início | |
li[:3] # => [1, 2, 4] | |
# Selecione cada segunda entrada | |
li[::2] # => [1, 4] | |
# Tenha uma cópia em ordem invertida da lista | |
li[::-1] # => [3, 4, 2, 1] | |
# Use qualquer combinação dessas para indicar limites complexos | |
# li[inicio:fim:passo] | |
# Faça uma cópia profunda de um nível usando limites | |
li2 = li[:] # => li2 = [1, 2, 4, 3] mas (li2 is li) resultará em False. | |
# Apague elementos específicos da lista com "del" | |
del li[2] # li agora é [1, 2, 3] | |
# Você pode somar listas | |
# Observação: valores em li e other_li não são modificados. | |
li + other_li # => [1, 2, 3, 4, 5, 6] | |
# Concatene listas com "extend()" | |
li.extend(other_li) # Agora li é [1, 2, 3, 4, 5, 6] | |
# Verifique se algo existe na lista com "in" | |
1 in li # => True | |
# Examine tamanho com "len()" | |
len(li) # => 6 | |
# Tuplas são como l istas, mas imutáveis. | |
tup = (1, 2, 3) | |
tup[0] # => 1 | |
tup[0] = 3 # Gera um TypeError | |
# Observe que uma tupla de tamanho um precisa ter uma vírgula depois do | |
# último elemento mas tuplas de outros tamanhos, mesmo vazias, não precisa,. | |
type((1)) # => <class 'int'> | |
type((1,)) # => <class 'tuple'> | |
type(()) # => <class 'tuple'> | |
# Você pode realizar com tuplas a maior parte das operações que faz com listas | |
len(tup) # => 3 | |
tup + (4, 5, 6) # => (1, 2, 3, 4, 5, 6) | |
tup[:2] # => (1, 2) | |
2 in tup # => True | |
# Você pode desmembrar tuplas (ou listas) em variáveis. | |
a, b, c = (1, 2, 3) # a é 1, b é 2 e c é 3 | |
# Por padrão, tuplas são criadas se você não coloca parêntesis. | |
d, e, f = 4, 5, 6 | |
# Veja como é fácil permutar dois valores | |
e, d = d, e # d é 5, e é 4 | |
# Dicionários armazenam mapeamentos | |
empty_dict = {} | |
# Aqui está um dicionário preenchido na definição da referência | |
filled_dict = {"um": 1, "dois": 2, "três": 3} | |
# Observe que chaves para dicionários devem ser tipos imutáveis. Isto é para | |
# assegurar que a chave pode ser convertida para uma valor hash constante para | |
# buscas rápidas. | |
# Tipos imutáveis incluem inteiros, flotas, strings e tuplas. | |
invalid_dict = {[1,2,3]: "123"} # => Gera um TypeError: unhashable type: 'list' | |
valid_dict = {(1,2,3):[1,2,3]} # Já os valores, podem ser de qualquer tipo. | |
# Acesse valores com [] | |
filled_dict["um"] # => 1 | |
# Acesse todas as chaves como um iterável com "keys()". É necessário encapsular | |
# a chamada com um list() para transformá-las em uma lista. Falaremos sobre isso | |
# mais adiante. Observe que a ordem de uma chave de dicionário não é garantida. | |
# Por isso, os resultados aqui apresentados podem não ser exatamente como os | |
# aqui apresentados. | |
list(filled_dict.keys()) # => ["três", "dois", "um"] | |
# Acesse todos os valores de um iterável com "values()". Novamente, é | |
# necessário encapsular ele com list() para não termos um iterável, e sim os | |
# valores. Observe que, como foi dito acima, a ordem dos elementos não é | |
# garantida. | |
list(filled_dict.values()) # => [3, 2, 1] | |
# Verifique a existência de chaves em um dicionário com "in" | |
"um" in filled_dict # => True | |
1 in filled_dict # => False | |
# Acessar uma chave inexistente gera um KeyError | |
filled_dict["quatro"] # KeyError | |
# Use o método "get()" para evitar um KeyError | |
filled_dict.get("um") # => 1 | |
filled_dict.get("quatro") # => None | |
# O método get permite um parâmetro padrão para quando não existir a chave | |
filled_dict.get("um", 4) # => 1 | |
filled_dict.get("quatro", 4) # => 4 | |
# "setdefault()" insere em dicionário apenas se a dada chave não existir | |
filled_dict.setdefault("cinco", 5) # filled_dict["cinco"] tem valor 5 | |
filled_dict.setdefault("cinco", 6) # filled_dict["cinco"] continua 5 | |
# Inserindo em um dicionário | |
filled_dict.update({"quatro":4}) # => {"um": 1, "dois": 2, "três": 3, "quatro": 4} | |
#filled_dict["quatro"] = 4 #outra forma de inserir em um dicionário | |
# Remova chaves de um dicionário com del | |
del filled_dict["um"] # Remove a chave "um" de filled_dict | |
# Armazenamento em sets... bem, são conjuntos | |
empty_set = set() | |
# Inicializa um set com alguns valores. Sim, ele parece um dicionário. Desculpe. | |
some_set = {1, 1, 2, 2, 3, 4} # some_set agora é {1, 2, 3, 4} | |
# Da mesma forma que chaves em um dicionário, elementos de um set devem ser | |
# imutáveis. | |
invalid_set = {[1], 1} # => Gera um TypeError: unhashable type: 'list' | |
valid_set = {(1,), 1} | |
# Pode definir novas variáveis para um conjunto | |
filled_set = some_set | |
# Inclua mais um item no set | |
filled_set.add(5) # filled_set agora é {1, 2, 3, 4, 5} | |
# Faça interseção de conjuntos com & | |
other_set = {3, 4, 5, 6} | |
filled_set & other_set # => {3, 4, 5} | |
# Faça união de conjuntos com | | |
filled_set | other_set # => {1, 2, 3, 4, 5, 6} | |
# Faça a diferença entre conjuntos com - | |
{1, 2, 3, 4} - {2, 3, 5} # => {1, 4} | |
# Verifique a existência em um conjunto com in | |
2 in filled_set # => True | |
10 in filled_set # => False | |
#################################################### | |
## 3. Controle de fluxo e iteráveis | |
#################################################### | |
# Iniciemos um variável | |
some_var = 5 | |
# Aqui está uma expressão if. Indentação é significante em python! | |
# imprime "somevar é menor que10" | |
if some_var > 10: | |
print("some_var é absolutamente maior que 10.") | |
elif some_var < 10: # Esta cláusula elif é opcional. | |
print("some_var é menor que 10.") | |
else: # Isto também é opcional. | |
print("some_var é, de fato, 10.") | |
""" | |
Laços for iteram sobre listas | |
imprime: | |
cachorro é um mamífero | |
gato é um mamífero | |
rato é um mamífero | |
""" | |
for animal in ["cachorro", "gato", "rato"]: | |
# Você pode usar format() para interpolar strings formatadas | |
print("{} é um mamífero".format(animal)) | |
""" | |
"range(número)" retorna um iterável de números | |
de zero até o número escolhido | |
imprime: | |
0 | |
1 | |
2 | |
3 | |
""" | |
for i in range(4): | |
print(i) | |
""" | |
"range(menor, maior)" gera um iterável de números | |
começando pelo menor até o maior | |
imprime: | |
4 | |
5 | |
6 | |
7 | |
""" | |
for i in range(4, 8): | |
print(i) | |
""" | |
"range(menor, maior, passo)" retorna um iterável de números | |
começando pelo menor número até o maior númeno, pulando de | |
passo em passo. Se o passo não for indicado, o valor padrão é um. | |
imprime: | |
4 | |
6 | |
""" | |
for i in range(4, 8, 2): | |
print(i) | |
""" | |
Laços while executam até que a condição não seja mais válida. | |
imprime: | |
0 | |
1 | |
2 | |
3 | |
""" | |
x = 0 | |
while x < 4: | |
print(x) | |
x += 1 # Maneira mais curta para for x = x + 1 | |
# Lide com exceções com um bloco try/except | |
try: | |
# Use "raise" para gerar um erro | |
raise IndexError("Isto é um erro de índice") | |
except IndexError as e: | |
pass # Pass é um não-operador. Normalmente você usa algum código de recuperação aqui. | |
except (TypeError, NameError): | |
pass # Varias exceções podem ser gerenciadas, se necessário. | |
else: # Cláusula opcional para o bloco try/except. Deve estar após todos os blocos de exceção. | |
print("Tudo certo!") # Executa apenas se o código em try não gera exceção | |
finally: # Sempre é executado | |
print("Nós podemos fazer o código de limpeza aqui.") | |
# Ao invés de try/finally para limpeza você pode usar a cláusula with | |
with open("myfile.txt") as f: | |
for line in f: | |
print(line) | |
# Python provê uma abstração fundamental chamada Iterável. | |
# Um iterável é um objeto que pode ser tratado como uma sequência. | |
# O objeto retornou a função range, um iterável. | |
filled_dict = {"um": 1, "dois": 2, "três": 3} | |
our_iterable = filled_dict.keys() | |
print(our_iterable) # => range(1,10). Esse é um objeto que implementa nossa interface iterável. | |
# Nós podemos percorrê-la. | |
for i in our_iterable: | |
print(i) # Imprime um, dois, três | |
# Mas não podemos acessar os elementos pelo seu índice. | |
our_iterable[1] # Gera um TypeError | |
# Um iterável é um objeto que sabe como criar um iterador. | |
our_iterator = iter(our_iterable) | |
# Nosso iterador é um objeto que pode lembrar o estado enquanto nós o percorremos. | |
# Nós acessamos o próximo objeto com "next()". | |
next(our_iterator) # => "um" | |
# Ele mantém o estado enquanto nós o percorremos. | |
next(our_iterator) # => "dois" | |
next(our_iterator) # => "três" | |
# Após o iterador retornar todos os seus dados, ele gera a exceção StopIterator | |
next(our_iterator) # Gera StopIteration | |
# Você pode capturar todos os elementos de um iterador aplicando list() nele. | |
list(filled_dict.keys()) # => Retorna ["um", "dois", "três"] | |
#################################################### | |
## 4. Funções | |
#################################################### | |
# Use "def" para criar novas funções. | |
def add(x, y): | |
print("x é {} e y é {}".format(x, y)) | |
return x + y # Retorne valores com a cláusula return | |
# Chamando funções com parâmetros | |
add(5, 6) # => imprime "x é 5 e y é 6" e retorna 11 | |
# Outro meio de chamar funções é com argumentos nomeados | |
add(y=6, x=5) # Argumentos nomeados podem aparecer em qualquer ordem. | |
# Você pode definir funções que pegam um número variável de argumentos | |
# posicionais | |
def varargs(*args): | |
return args | |
varargs(1, 2, 3) # => (1, 2, 3) | |
# Você pode definir funções que pegam um número variável de argumentos nomeados | |
# também | |
def keyword_args(**kwargs): | |
return kwargs | |
# Vamos chamá-lo para ver o que acontece | |
keyword_args(peh="grande", lago="ness") # => {"peh": "grande", "lago": "ness"} | |
# Você pode fazer ambos simultaneamente, se você quiser | |
def all_the_args(*args, **kwargs): | |
print(args) | |
print(kwargs) | |
""" | |
all_the_args(1, 2, a=3, b=4) imprime: | |
(1, 2) | |
{"a": 3, "b": 4} | |
""" | |
# Quando chamar funções, você pode fazer o oposto de args/kwargs! | |
# Use * para expandir tuplas e use ** para expandir dicionários! | |
args = (1, 2, 3, 4) | |
kwargs = {"a": 3, "b": 4} | |
all_the_args(*args) # equivalente a foo(1, 2, 3, 4) | |
all_the_args(**kwargs) # equivalente a foo(a=3, b=4) | |
all_the_args(*args, **kwargs) # equivalente a foo(1, 2, 3, 4, a=3, b=4) | |
# Retornando múltiplos valores (com atribuição de tuplas) | |
def swap(x, y): | |
return y, x # Retorna múltiplos valores como uma tupla sem os parêntesis. | |
# (Observação: os parêntesis foram excluídos mas podem estar | |
# presentes) | |
x = 1 | |
y = 2 | |
x, y = swap(x, y) # => x = 2, y = 1 | |
# (x, y) = swap(x,y) # Novamente, os parêntesis foram excluídos mas podem estar presentes. | |
# Escopo de função | |
x = 5 | |
def setX(num): | |
# A variável local x não é a mesma variável global x | |
x = num # => 43 | |
print (x) # => 43 | |
def setGlobalX(num): | |
global x | |
print (x) # => 5 | |
x = num # variável global x agora é 6 | |
print (x) # => 6 | |
setX(43) | |
setGlobalX(6) | |
# Python tem funções de primeira classe | |
def create_adder(x): | |
def adder(y): | |
return x + y | |
return adder | |
add_10 = create_adder(10) | |
add_10(3) # => 13 | |
# Também existem as funções anônimas | |
(lambda x: x > 2)(3) # => True | |
(lambda x, y: x ** 2 + y ** 2)(2, 1) # => 5 | |
# TODO - Fix for iterables | |
# Existem funções internas de alta ordem | |
map(add_10, [1, 2, 3]) # => [11, 12, 13] | |
map(max, [1, 2, 3], [4, 2, 1]) # => [4, 2, 3] | |
filter(lambda x: x > 5, [3, 4, 5, 6, 7]) # => [6, 7] | |
# Nós podemos usar compreensão de lista para interessantes mapas e filtros | |
# Compreensão de lista armazena a saída como uma lista que pode ser uma lista | |
# aninhada | |
[add_10(i) for i in [1, 2, 3]] # => [11, 12, 13] | |
[x for x in [3, 4, 5, 6, 7] if x > 5] # => [6, 7] | |
#################################################### | |
## 5. Classes | |
#################################################### | |
# Nós usamos o operador "class" para ter uma classe | |
class Human: | |
# Um atributo de classe. Ele é compartilhado por todas as instâncias dessa | |
# classe. | |
species = "H. sapiens" | |
# Construtor básico, é chamado quando esta classe é instanciada. | |
# Note que dois sublinhados no início e no final de uma identificados | |
# significa objetos ou atributos que são usados pelo python mas vivem em | |
# um namespace controlado pelo usuário. Métodos (ou objetos ou atributos) | |
# como: __init__, __str__, __repr__, etc. são chamados métodos mágicos (ou | |
# algumas vezes chamados métodos dunder - "double underscore") | |
# Você não deve usar nomes assim por sua vontade. | |
def __init__(self, name): | |
@ Atribui o argumento ao atributo da instância | |
self.name = name | |
# Um método de instância. Todos os métodos tem "self" como primeiro | |
# argumento | |
def say(self, msg): | |
return "{name}: {message}".format(name=self.name, message=msg) | |
# Um método de classe é compartilhado por todas as instâncias | |
# Eles são chamados com a classe requisitante como primeiro argumento | |
@classmethod | |
def get_species(cls): | |
return cls.species | |
# Um método estático é chamado sem uma referência a classe ou instância | |
@staticmethod | |
def grunt(): | |
return "*grunt*" | |
# Instancie uma classe | |
i = Human(name="Ian") | |
print(i.say("oi")) # imprime "Ian: oi" | |
j = Human("Joel") | |
print(j.say("olá")) # imprime "Joel: olá" | |
# Chama nosso método de classe | |
i.get_species() # => "H. sapiens" | |
# Altera um atributo compartilhado | |
Human.species = "H. neanderthalensis" | |
i.get_species() # => "H. neanderthalensis" | |
j.get_species() # => "H. neanderthalensis" | |
# Chama o método estático | |
Human.grunt() # => "*grunt*" | |
#################################################### | |
## 6. Módulos | |
#################################################### | |
# Você pode importar módulos | |
import math | |
print(math.sqrt(16)) # => 4.0 | |
# Você pode importar apenas funções específicas de um módulo | |
from math import ceil, floor | |
print(ceil(3.7)) # => 4.0 | |
print(floor(3.7)) # => 3.0 | |
# Você pode importar todas as funções de um módulo para o namespace atual | |
# Atenção: isso não é recomendado | |
from math import * | |
# Você pode encurtar o nome dos módulos | |
import math as m | |
math.sqrt(16) == m.sqrt(16) # => True | |
# Módulos python são apenas arquivos python comuns. Você | |
# pode escrever os seus, e importá-los. O nome do | |
# módulo é o mesmo nome do arquivo. | |
# Você pode procurar que atributos e funções definem um módulo. | |
import math | |
dir(math) | |
#################################################### | |
## 7. Avançado | |
#################################################### | |
# Geradores podem ajudar você a escrever código "preguiçoso" | |
def double_numbers(iterable): | |
for i in iterable: | |
yield i + i | |
# Um gerador cria valores conforme necessário. | |
# Ao invés de gerar e retornar todos os valores de uma só vez ele cria um em | |
# cada interação. Isto significa que valores maiores que 15 não serão | |
# processados em double_numbers. | |
# Nós usamos um sublinhado ao final do nome das variáveis quando queremos usar | |
# um nome que normalmente colide com uma palavra reservada do python. | |
range_ = range(1, 900000000) | |
# Multiplica por 2 todos os números até encontrar um resultado >= 30 | |
for i in double_numbers(range_): | |
print(i) | |
if i >= 30: | |
break | |
# Decoradores | |
# Neste exemplo beg encapsula say | |
# beg irá chamar say. Se say_please é verdade então ele irá mudar a mensagem | |
# retornada | |
from functools import wraps | |
def beg(target_function): | |
@wraps(target_function) | |
def wrapper(*args, **kwargs): | |
msg, say_please = target_function(*args, **kwargs) | |
if say_please: | |
return "{} {}".format(msg, "Por favor! Eu sou pobre :(") | |
return msg | |
return wrapper | |
@beg | |
def say(say_please=False): | |
msg = "Você me paga uma cerveja?" | |
return msg, say_please | |
print(say()) # Você me paga uma cerveja? | |
print(say(say_please=True)) # Você me paga uma cerveja? Por favor! Eu sou pobre :( |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment