Quando a gente está implementando alguma coisa nova,
a gente nunca constrói tudo do zero.
Então, nessa brincadeira de reaproveitar
o que já está feito,
a gente começa a conversar sobre função nativa para cá e para lá,
e agora finalmente chegou o momento da gente entender
o que são funções, para que servem
e construir a nossa primeira.
Como a gente já comentou,
a gente consegue reaproveitar bastante coisa no desenvolvimento
e tem vários motivos para fazer isso.
Se a gente quisesse,
a gente até poderia fazer isso tudo do zero,
mas tem alguns problemas nessa abordagem.
Imagina que dentro da sua aplicação,
você tem que exibir uma mensagem para algum usuário.
Dentro dessa mensagem,
você provavelmente vai ter o nome do usuário
e alguns elementos extras, como um prefixo ou sufixo,
alguma coisa desse tipo.
Pronto, esse seu código vai funcionar mais,
felizmente ou, infelizmente, mais para frente no seu código,
você vai ter que repetir aquele mesmo comportamento.
E conforme sua aplicação for crescendo,
provavelmente em outros lugares você vai ter que fazer isso também.
E não só nesse arquivo, mas em vários outros arquivos.
E agora você já está começando a enxergar qual que é o problema.
Não só a gente não está conseguindo reaproveitar aquele código,
porque ele está espalhado no meio da nossa aplicação,
como se a gente precisar trocar aquele comportamento
para adicionar ou remover alguma característica,
isso vai ser muito complicado,
porque a gente vai ter que depender de ferramentas de busca
para procurar algum trecho de código
e então alterá-lo em todos os lugares.
É muito fácil a gente acabar esquecendo um ou dois lugares
e, com isso, injetar bugs no nosso programa.
Para resolver esse problema, a gente tem as funções,
que é a porta de entrada para o tema de abstração.
Com elas, a gente consegue criar blocos de código parametrizáveis
e executar uma lógica específica quantas vezes a gente quiser.
Funções existem basicamente todas as linguagens,
de uma forma ou de outra.
E a característica principal delas é isolar bloco de código
para reaproveitamento.
Sendo assim, a gente consegue implementar o que a gente quiser
e dar manutenção em um só lugar do nosso código.
Se a gente precisar alterar um comportamento,
basta alterar dentro daquela função
e aonde ela estiver sendo referenciada,
o comportamento vai ser atualizado também.
Legal.
Agora que você entendeu a motivação e, mais ou menos,
a ideia por trás das funções, vamos ver, na prática,
como que isso funciona no Python.
Então, vamos lá para o código.
Aqui no VS Code, eu já tenho o meu arquivo main.py criado.
Então, vamos começar definindo a nossa função.
E, para isso, eu vou usar a palavra reservada def.
Cada linguagem de programação tem a sua forma de fazer
e é assim que a gente faz no Python.
Eu vou começar, então, aqui colocando o nome da minha função,
que vai ser exatamente minha função.
A gente pode mudar isso no futuro sem problema nenhum.
E, para que o Python entenda, de fato, que isso é uma função,
eu vou colocar aqui os parênteses e os dois pontos.
Pronto.
A partir de agora,
eu estou livre para desenvolver o corpo da minha função.
Ou seja, o que eu quero que seja executado
quando essa função for invocada.
No nosso exemplo, a gente vai colocar apenas um print,
escrevendo alguma mensagem simples, como, por exemplo,
"olá, aluno".
E salvar o arquivo.
Nesse momento, a gente já pode executar a nossa aplicação
usando o python.exe e o nome do arquivo.
Veja só.
Aqui no terminal, eu vou escrever python.exe,
ponto barra e o nome do meu arquivo.
Ponto barra, main.py.
E se eu der um enter,
repara que a aplicação até executou,
mas não aconteceu nada de muito interessante.
Isso foi, basicamente, porque eu declarei a minha função,
mas eu não invoquei ela em lugar algum.
Lembra, funções são blocos de abstração.
Eu consigo escrever código lá dentro,
mas ele só é executado, de fato,
quando eu invoco essa função.
Então, vamos lá, aqui no nosso código.
E aqui embaixo, eu vou invocar essa função.
Para fazer isso,
basta eu executar o nome dessa função
e colocar aqui os parênteses.
Dessa forma, eu estou pedindo para o python
para que ele pegue e execute aquele bloco de código.
Se eu rodar novamente o meu programa, dessa vez sim,
a gente tem a mensagem "olá, alunos", sendo exibida.
E bacana, a nossa função está funcionando,
mas ela ainda não tem muita funcionalidade
na nossa aplicação.
Porque uma das características de funções
é ter a capacidade de ser parametrizada.
Ou seja, a gente deve, dependendo do cenário,
conseguir manipular o comportamento dela
baseado em informações externas.
E isso a gente faz justamente através de parâmetros.
No Python, a gente consegue definir uma lista de parâmetros
que essa função recebe,
semelhante à própria funcionativa print.
Se a gente quiser executar ela,
a gente tem que mandar um string, ou seja,
um texto que vai ser exibido no terminal.
É assim que a gente controla o comportamento da função print,
parametrizando para ela a mensagem que a gente quer que seja exibida.
No nosso caso, o que a gente vai fazer é adicionar um parâmetro
para que a gente informe o nome que a gente
quer que esteja dentro da mensagem.
Entendeu?
Então, vamos lá.
Aqui no nosso código, então, eu vou começar entre os parênteses,
colocando o meu parâmetro, que eu vou chamar de nome.
E no Python, a gente tem a tipagem dinâmica.
Isso significa que eu posso deixar o meu código dessa forma,
e em tempo de execução, o Python vai saber o tipo dessa variável.
Mas caso eu queira deixar mais claro para algum desenvolvedor
que pegar o nosso código, eu posso colocar aqui do lado,
na frente dos dois pontos, o tipo str.
Lembra, isso não vai mudar na prática nada dentro da linguagem,
mas vai fazer com que alguém que pegue meu código
entenda que eu estou esperando que ele mande um string.
Se ele mandar um número, o Python não vai reclamar nesse momento.
Mas eu estou informando para ele que o comportamento esperado
é que ele mande um texto.
Tá bom? Então vamos lá.
Agora que dentro do contexto da minha função eu tenho essa variável,
eu posso usar ela.
Então eu vou basicamente copiar ela aqui
e remover a palavra aluno da minha mensagem,
porque agora eu vou fazer uma concatenação simples.
E para isso, eu vou colocar aqui na frente do sinal de mais
a variável nome.
E vamos ver o que acontece se eu executar o meu código
do jeito que ele está.
Pronto.
A gente agora tem um erro, porque eu defini um parâmetro
e ele é um parâmetro posicional.
Ou seja, eu posso definir vários parâmetros.
A ordem com que eu passar eles vai ser a ordem
com que o Python vai alocá-los dentro das variáveis.
Vamos lá.
Isso significa que se eu tivesse uma outra variável aqui,
por exemplo, idade, eu teria que passar aqui embaixo,
dentro da invocação da minha função,
a primeira variável que é o nome.
Por exemplo, aluno.
E se eu quiser passar idade, eu coloco aqui na frente.
Repara que a própria IDE já vai dando dicas para a gente
de como que a gente está esperando receber os valores.
Mas no nosso cenário, a gente só vai ter um parâmetro.
Então eu vou remover a idade.
E se a gente executa novamente o nosso código, agora sim.
A gente tem a mesma mensagem de antes, mas um pouco diferente.
Porque essa mensagem agora, ela está parametrizável.
Ou seja, a gente consegue controlar o comportamento
daquela função do lado de fora.
E se eu quiser usar essa função quantas vezes eu quiser,
eu posso sem problema nenhum.
Então, imagina, por exemplo, que aqui embaixo
eu vou querer executar ela mais duas vezes.
Só que dessa vez, colocando aluna,
e aqui embaixo,
talvez você esteja sentindo falta disso.
Então, mundo,
se eu limpar o meu terminal e executar novamente a aplicação,
a gente vê que a gente tem as três exibições daquela função,
sendo que cada uma delas reaproveitou o código
que a gente definiu na função, mas foi parametrizado
para que o comportamento fosse diferente.
Incrível, né?
A gente construiu uma função simples,
mas as funções estão por todo lugar na linguagem.
Sejam funções nativas ou funções de pacote que a gente
vai uma hora ou outra até que acabar usando.
Dá uma explorada nesse código aqui e tenta melhorar ele um pouco.
Tenta adicionar um outro parâmetro, um outro tipo,
faz condicionais lá dentro, loops, quem sabe.
Experimenta.
Ganha afinidade com essa sintaxe aqui e vamos ver até onde você chega.