(Python) Sub-rotinas: Procedimentos e Funções - 1


Sub-rotinas

Uma sub-rotina é uma parte separada do programa que tem um nome e resolve sua própria tarefa separada. A sub-rotina está localizada no início do programa principal e pode ser iniciada (chamada) a partir do programa principal especificando o nome.

O uso de sub-rotinas permite evitar a duplicação de código, caso seja necessário escrever o mesmo código em locais diferentes do programa. 
As bibliotecas que são importadas para um programa (por exemplo, a biblioteca math math) consistem em sub-rotinas que já foram compiladas por alguém. Os programadores não precisam pensar em quais algoritmos implementam, mas simplesmente aplicá-los, pensando apenas no que exatamente estão fazendo. Esta é uma grande economia de tempo. Não há necessidade de escrever um algoritmo que já foi escrito por outra pessoa.

Cada sub-rotina deve executar apenas uma tarefa,  apenas calcule algo, ou forneça alguns dados, ou faça outra coisa. 

Existem dois tipos de sub-rotinas - procedimentos e funções.

Os subprocedimentos executam alguma ação, como exibir um resultado na tela de uma determinada forma (um exemplo simples, a instrução print() é um subprocedimento padrão que imprime dados na tela).

As sub-rotinas de função retornam um resultado (número, cadeia de caracteres, etc.) que podemos usar no programa principal.

Vamos tentar escrever um procedimento simples:
Suponha que precisamos exibir a string "Error" na tela toda vez que pode ocorrer um erro no código por falha do usuário, por exemplo, quando ele insere dados incorretos.
Isso pode ser feito escrevendo a declaração print("Erro") E agora imagine que tal linha precise ser inserida em vários lugares do programa. Claro, você pode simplesmente escrevê-lo em todos os lugares. Mas esta solução tem duas desvantagens.
1) Esta string será armazenada na memória muitas vezes.
2) Se quisermos alterar a saída em caso de erro, teremos que alterar esta linha ao longo do programa, o que é bastante inconveniente

Para tais casos, são necessários procedimentos.
Um programa com um procedimento pode se parecer com isto:
  def printError(): # descrição do procedimento print("Erro") ... printError() # inicia o procedimento para execução. # Basta especificar o nome do procedimento que queremos executar ... printError()
É preciso lembrar!
  1. O procedimento começa com a palavra def (do inglês - define - definir). Após o nome do procedimento, colchetes vazios e dois pontos são escritos . Os parâmetros podem ser especificados dentro dos colchetes (falaremos sobre isso mais tarde).
  2. Todas as instruções executadas em um procedimento são recuadas. 
  3. Para executar um procedimento, no programa principal você precisa chamá-lo pelo nome e lembre-se de colocar parênteses!
  4. Você pode chamar um procedimento em um programa quantas vezes quiser.

Parâmetros e Argumentos

Agora vamos imaginar que precisamos exibir diferentes mensagens em resposta ao erro de um usuário, dependendo do tipo de erro que ele cometeu.
Nesse caso, você pode escrever seu próprio procedimento para cada erro:   def printErrorZero(): print("Erro. ​​Divisão por zero!") def printErrorInput(): print("Erro na entrada!")
E se houver muitos outros erros possíveis? Esta solução não nos convém!
Precisamos aprender a controlar o procedimento, informando qual mensagem de erro exibir.
Para fazer isso, precisamos de parâmetros que escreveremos entre parênteses após o nome do procedimento def printError(es): print("s")
Neste procedimento, s é um parâmetro - uma variável especial que permite controlar o procedimento.
 
O parâmetro é uma variável que determina como a sub-rotina funciona. Os nomes dos parâmetros são separados por vírgula no cabeçalho da sub-rotina.


Agora, ao chamar o procedimento, você precisa indicar entre parênteses o valor real que será atribuído ao parâmetro (variável s) dentro do nosso procedimento printError("Erro! Divisão por zero!")
Tal valor é chamado de argumento.
 
O argumento é o valor do parâmetro que é passado para a sub-rotina quando ela é chamada.

Um argumento pode ser não apenas um valor constante, mas também uma variável ou uma expressão aritmética.

Variáveis ​​locais e globais

Variáveis ​​que são introduzidas no programa principal são chamadas globais (ou compartilhadas).

Você pode acessar variáveis ​​globais de qualquer sub-rotina. 

Muitas vezes é necessário introduzir variáveis ​​adicionais que serão utilizadas apenas na sub-rotina. Tais variáveis ​​são chamadas locais (ou locais). Você pode trabalhar com eles somente dentro da sub-rotina na qual eles são criados. O resto das rotinas não "sabem" nada sobre elas.

Assim, é possível limitar o escopo (scope) de uma variável apenas à sub-rotina onde ela é realmente necessária. Na programação, essa técnica é chamada de encapsulamento  - ocultar a variável de ser alterada de fora.

Analise três programas:
Descrição Programa
1) Neste programa, a variável i é local. Se não houver variável i no programa principal, obteremos uma mensagem de erro. E se houver tal variável (então é uma variável global), então seu valor é exibido na tela. def teste(): imprimir(i)
2) Aqui, mesmo que exista uma variável global i, uma nova variável local i será criada com valor 2, e 2 aparecerá na tela. def teste():   eu = 2 imprimir(i)
3) Neste programa, existe uma variável global i com valor 15. Seu valor pode ser alterado dentro da sub-rotina, para isso é necessário declarar explicitamente que ela é global ( use o comando global ).
O procedimento funcionará com a variável global i e será atribuído a ela um novo valor de 2. O valor 2 é exibido.
def teste():   global i eu = 2 # programa principal eu = 15 imprimir(i)