Buscar

Modularização aula5

Prévia do material em texto

Disciplina: Informática para Engenharia
Aula 5: Modularização
Apresentação
Os principais desafios para programadores estão relacionados com a construção de
softwares de qualidade. É altamente desejável a construção de programas legíveis e
de fácil manutenção.
A divisão do programa em módulos, ou subprogramas, evita a duplicação de código e
de responsabilidades, tendo impactos diretos para a boa manutenção do software.
Essa estratégia auxilia (e muito) na resolução de problemas grandes e complexos.
Um dos produtos obtidos pela aplicação de técnicas de modularização consiste na
construção de bibliotecas. A criação de rotinas em arquivos específicos possibilita o
seu reuso em futuras implementações.
Objetivos
Formular programas com base em técnicas de modularização;
Construir programas e bibliotecas reusáveis em Python segundo os conceitos da
programação modular.
Modularização de Programas
Até o momento, construímos algoritmos que executam de uma forma
puramente sequencial. Imagine se você precisasse calcular a média final de
um aluno para saber se ele foi aprovado, reprovado ou se foi para a final. A
solução é simples nesse caso, pois precisaremos realizar o cálculo somente
uma vez. Agora suponha que quiséssemos fazer o mesmo cálculo, mas para
uma turma de 30 alunos. Bem, será que agora teremos de escrever a mesma
equação 30 vezes?
# Dados para o 1 aluno
>>> nota_prova1 = input(‘Informe a nota da prova 1’)
>>> nota_prova2 = input(‘Informe a nota da prova 2’)
>>> media = (nota_prova1 + nota_prova2) / 2
# Dados para o 2 aluno
>>> nota_prova1 = input(‘Informe a nota da prova 1’)
>>> nota_prova2 = input(‘Informe a nota da prova 2’)
>>> media = (nota_prova1 + nota_prova2) / 2
# e assim por diante, até o 30 aluno…
Podemos observar dois problemas na construção do algoritmo proposto. O
primeiro está relacionado à repetição das leituras das variáveis nota_prova1 e
nota_prova2, além do cálculo para a média, que nunca muda!
Eis que surge uma questão: não poderíamos criar um módulo responsável por
somente calcular a média? Nesse caso, só chamaremos a função já codificado
passando as notas e tendo como retorno a situação do aluno (aprovado,
reprovado ou em prova final). Esse é o mais simples conceito de
modularização.
Para o referido exemplo, poderíamos pensar em algo do tipo:
o
o
o
Pseudocódigo
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Algoritmo calcula_media
nota_prova1, nota_prova2: real
início
escreva(‘Digite a nota1: ‘)
leia(nota_prova1)
escreva(‘Digite a nota2: ‘)
leia(nota_prova2)
 
media:=calcula_media(nota_prova1,nota_prova2)
escreva(media)
fim
funcao calcula_media(real nota1, real nota2)
inicio
retorna (nota1 + nota2) /2
fim.
Python
1
2
3
4
5
6
def calcula_media(nota1, nota2):
return ((nota1+nota2)/2)
 
nota_prova1=float(input('Digite a nota1: '))
nota_prova2=float(input('Digite a nota2: '))
media=calcula_media(nota_prova1, nota_prova2)
7
8
9
10
11
12
13
14
15
print(media)
Outro ponto positivo reside no fato de que queremos somente calcular a
média, não nos importando como isso é feito. Observe no pseudocódigo que,
se mudarmos a forma de cálculo na função calcula_ media, não precisaremos
alterar nenhuma instrução no algoritmo principal. Ou seja, a manutenção só é
realizada em um único ponto de todo o código.
No entanto, ainda não resolvemos o problema da leitura
repetida dos 30 alunos, correto? Mas, analisando
novamente o pseudocódigo, podemos perceber que as
instruções da linha 4 até a linha 10 seriam as mesmas
para os 30 alunos. Logo, poderíamos criar mecanismos
para repetir esse código do 1 até o 30 aluno. No entanto,
esse é um assunto que será abordado nas próximas aulas.
Blocos de Código
o o
Analisando mais uma vez o pseudocódigo, podemos ver duas estruturas
distintas, delimitadas pelas palavras reservadas início e fim: o conjunto de
ações do algoritmo principal e o outro da função calcula_media. Esses são
dois exemplos de blocos.
Um bloco pode ser definido como um conjunto de ações com uma função
definida. Nesse caso, um algoritmo pode ser visto como um bloco.
Para melhor ilustrar o conceito de blocos, vamos considerar um exemplo um
pouco mais complexo, que envolve a ordenação de dados contidos em uma
lista.
Podemos perceber no exemplo que o uso dessa abordagem torna o algoritmo
principal (Algoritmo OrdenaPorSeleção) mais compreensível e abre a
possibilidade de chamar a mesma rotina (Algoritmo EncontraMenor) em
outras partes do programa sem reescrevê-lo.
Funções
Função é uma sequência de instruções que executa algum tipo de tarefa.
Usamos funções para eliminar a duplicação de código. Em vez de
escrevermos todas as instruções em todos os lugares em nosso código
onde queremos executar a mesma tarefa, nós os definimos em um lugar
e nos referimos a eles pelo nome da função. Se quisermos mudar a
forma como essa tarefa é executada, agora só precisaremos alterar o
código em um só lugar.
Em programação estruturada, um pequeno detalhe diferencia um
procedimento de uma função: a 1 não retorna valor, enquanto a 2
sempre retorna. Outra questão é que uma função deve ter pelo menos
um argumento. A seguir, é mostrado um código para cálculo de juros de
determinada quantia informada pelo usuário. Observe os elementos da
função.
Uma característica do Python é que os parâmetros, também conhecidos
por argumentos, podem ter um valor-padrão caso esse seja omitido na
chamada da função. Observe o código.
a a
O que aconteceria se não informássemos a quantia (linha 11) para a função
calcula_juros (linha 7)? O programa nos retornaria o valor 2.3, já que, na
omissão da quantia na chamada da função (linha 11), o argumento valor
(linha 7) recebe, por padrão,10!
Escopo de Variáveis
Nem todas as variáveis são acessíveis de todas as partes do nosso programa.
Além disso, nem todas elas existem pelo mesmo período de tempo. A
acessibilidade do local de uma variável e o tempo dela dependem de como
essa variável é definida.
Chamamos de escopo a parte de um programa onde uma variável é acessível
e a duração para a qual ela existe em seu tempo de vida.
Uma variável definida no corpo principal de um arquivo é chamada de
variável global. Ela será visível em todo o arquivo e também dentro de
qualquer arquivo que importe esse arquivo.
1
2
3
4
5
6
7
8
9
10
11
# -*- coding: utf-8 -*-
″″″
Algoritmo: Cálculo de juros
Entrada: quantia informada pelo usuário
Saída: juros calculados
″″″
def calcula_juros(valor):
taxa=0.23
return (valor*taxa)
 
quantia=float(input(″Digite uma quantia para o cálculo dos juros″))
12
13
juros = calcula_juros(quantia)
print(juros)
As linhas 11 e 12 ilustram as variáveis globais do programa. Nesse, caso elas
podem ser acessadas dentro da função da linha 7. Já a taxa (linha 8) é uma
variável local da função calcula_juros. Dessa forma, ela não é
acessada/visualizada fora da função. Um artifício para referenciar uma
variável global em um contexto local (uma função, por exemplo) seria usar a
palavra reservada global associada à variável desejada.
Uma variável definida dentro de uma função é local para essa função.
Chamada de variável local, é acessível a partir do ponto em que é definida
até o final da função e existe enquanto a função estiver sendo executada.
Sabendo disso, o que aconteceria se quiséssemos imprimir a variável taxa
(linha 14) conforme o código a seguir?
1
2
3
4
5
6
7
8
9
10
11
12
13
# -*- coding: utf-8 -*-
″″″
Algoritmo: Cálculo de juros
Entrada: quantia informada pelo usuário
Saída: juros calculados
″″″
def calcula_juros(valor):
taxa=0.23
return (valor*taxa)
 
quantia=float(input(″Digite uma quantia para o cálculo dos juros″))
juros = calcula_juros(quantia)
print(juros)
 14 print(taxa)
O Python nos daria a seguinte mensagem: “NameError: name 'taxa' is not
defined”. Ou seja, para o programa principal, a variável taxa não está
definida.
Os nomes dos parâmetros na definição da função se comportam como
variáveis locais, mas contêmos valores que passamos para a função quando a
chamamos. Tomando como exemplo o código anterior, o parâmetro valor
(linha 7) só é visível dentro da função.
Modularizando o Código
Todos os projetos de software começam pequenos, e é provável que você
comece escrevendo todo o código do seu programa em um único arquivo. À
medida que seu projeto cresce, torna-se cada vez mais inconveniente fazer
isso.
É difícil encontrar algo em um único arquivo de código, e, com o tempo, é
provável que você encontre um problema se quiser chamar duas classes
diferentes com o mesmo nome. Em algum momento, será uma boa ideia
arrumar o projeto dividindo-o em vários arquivos, colocando classes ou
funções relacionadas juntas no mesmo arquivo.

Exemplo
Por exemplo, podemos construir dois módulos em Python para lidar com
aspectos financeiros e administrativos (arquivos financeiro.py e
admin.py, respectivamente).
Assim, podemos utilizar as funções desses arquivos simplesmente
importando-os para o programa principal.
A figura apresenta três pacotes distintos.
O ordenacao.py tem uma coleção de funções para ordenar listas.
Já o format.py possui uma série de métodos relacionados com o tratamento
de strings, assim como o pacote io.py.
Com o tempo, os nossos módulos podem ficar maiores, ou seja, com uma
grande quantidade de funções em um único arquivo. Mais uma vez, podemos
agrupar os módulos de acordo com o propósito em pacotes!
De forma resumida, pacote é um diretório (ou pasta) que contém um arquivo
chamado __init__.py. A importação é bem parecida com um módulo e
necessita que usemos o nome do diretório. Automaticamente, todos os
módulos são importados para o código que invocou. De acordo com o exemplo
anterior, imagine se quiséssemos criar um pacote para formatar números
inteiros. Poderia ser uma boa ideia a inclusão de mais funções no arquivo
format.py, ok?
No entanto, estaríamos misturando funções que manipulam string com
números.
Uma boa solução seria a criação de pacotes para string e números!
A figura a seguir exibe a estrutura de pastas após a organização dos pacotes
em módulos.
Agora podemos ter um módulo com mesmo nome, isto é, format.py na pasta
number e outro arquivo format.py na pasta string.
Note que assim agrupamos os arquivos em função de suas características.
Esse é bom um exemplo de organização de código!
Teste o seguinte código no terminal ou no seu IDE preferido. Após criar a
estrutura, digite o conteúdo a seguir no arquivo format.py do diretório
number.
# -*- coding: utf-8 -*-
#format.py
def abs(arg1):
return "retorna valor absoluto"
def to_str(arg1):
return "formatação para string"
A seguir, o código do arquivo main.py.
# -*- coding: utf-8 -*-
#main.py
from number import format
print(format.abs(0))
No caso de existirem nomes de pacotes duplicados, podemos criar um alias
(apelido) através da diretiva as. Por exemplo, suponha que tenhamos pacotes
conversores.py em pastas distintas. Apesar do mesmo nome, poderíamos
importá-los da seguinte maneira:
from pacoteX import conversores as cvs1
from pacoteY import conversores as cvs2
Atividade
1. Observe o código a seguir:
def my_function (a):
b = a - 2
return b
c = 3
if (c > 2):
d = my_function(5)
print(d)
(a) Descreva o escopo das variáveis a, b, c e d neste exemplo.
(b) Qual é o tempo de vida dessas variáveis, ou seja, quando elas serão
criadas e destruídas?
(c) Você consegue adivinhar o que aconteceria se tivéssemos atribuído
ao c um valor de 1?
2. Qual é a saída do programa a seguir?
x = 50
def func():
global x
print('x é', x)
x = 2
print('Alterada a variável global x para', x)
func()
print('O valor de x é ', x)
 a) x é 50; alterada variável global x para 2; O valor de x é 50.
 b) x é 50; alterada variável global x para 2; O valor de x é 2.
 c) x é 50; alterada variável global x para 50; O valor de x é 50.
 d) Nenhuma das mencionadas.
3. Sobre o último exemplo de criação de pacotes e módulos, implemente
uma simples função no arquivo format.py no pacote string. Essa função,
chamada de “para_moeda”, deve receber um argumento e retornar a
mensagem “A conversão efetuada foi ” mais o argumento passado. No
módulo main.py, importe e invoque o referido método.
Referências
GRUS, J. Data science from scratch: first principles with Python. Beijing:
O’Reilly, 2015.
MENEZES, N. N. C. Introdução à programação com Python: algoritmos e lógica
de programação para iniciantes. 1. ed. São Paulo: Novatec, 2017.
MUELLER, J. P. Começando a programar em Python para leigos. Alta Books,
2016.
PERKOVIC, L. Introduction to computing using Python: an application
development focus. 2. ed. [s.l.] Wiley Publishing, 2015.
Próximos Passos
Apresentar técnicas para a resolução de problemas que envolvem tomada de
decisão;
Analisar o uso das relações lógicas e aritméticas para a construção de estruturas
de decisão;
Ilustrar os conceitos relacionados a estruturas condicionais simples e compostas.
Explore mais
Leia o texto:
Módulos e Pacotes <https://wiki.python.org.br/ModulosPacotes> .
Assista aos vídeos:
“Pacotes em Python <https://www.youtube.com/watch?
v=StKzd2331X4> ”.
“Utilizando Módulos <https://www.youtube.com/watch?
v=oOUyhGNib2Q> ”.
https://wiki.python.org.br/ModulosPacotes
https://www.youtube.com/watch?v=StKzd2331X4
https://www.youtube.com/watch?v=oOUyhGNib2Q

Continue navegando