Python Basico
Python Basico
- 2024 -
Além deste E-Book, este curso conta um amplo conjunto de materiais, nos formatos:
Ícone de Vídeo
Neste E-Book haverá uma sinalização quando um vídeo estiver disponível. Esta sinalização é feita com
este ícone ao lado. Então você já sabe: encontrou este ícone, há um vídeo disponível.
Os Exemplos e Exercícios Resolvidos deste E-Book tem o padrão gráfico mostrado a seguir.
Exercício Resolvido nº
Código do programa
Execução
As linhas mais escuras representam o código do programa e as linhas mais claras na sequência
representam o resultado que será visível na tela quando o programa for executado.
Os Exemplos serão feitos com um ou outro. Quando forem feitos com Idle haverá a indicação disso com
a frase:
(exemplo interativo feito com IDE Idle)
Capítulo 1
O PYTHON
A comunidade mundial de colaboradores e usuários de Python é muito grande e dinâmica. Por um lado,
a linguagem é simples e intuitiva, por outro, é poderosa e robusta. Aliar características assim não é nada fácil
e em Python isso tem sido alcançado com grande êxito.
O fato de ser simples e intuitiva permite que ela atenda bastante bem ao propósito de ser uma
linguagem utilizada por estudantes de programação que precisam de uma ferramenta para realizar seus
estudos e implementar seus primeiros algoritmos.
Por ser poderosa e robusta ela pode ser adotada por profissionais de programação que necessitem de
uma ferramenta que traga produtividade e confiabilidade aos projetos de software, em especial quando se
leva em conta a vasta gama de bibliotecas disponíveis e aplicáveis às várias necessidades frequentemente
encontradas no desenvolvimento de software.
Sua importância nos tempos atuais pode ser atestada pela presença no primeiro lugar do índice Tiobe.
Este índice é uma lista das linguagens de programação produzida a partir de estatísticas de sites de buscas
na internet usando o nome da linguagem como palavra-chave. Como esclarecido no próprio site Tiobe, o
índice não existe para indicar qual é a melhor linguagem. Não, não é disso que se trata. O índice Tiobe foi
formulado com o propósito de refletir a grau de interesse pelas linguagens de programação ao redor do
mundo. Para isso seus principais parâmetros são o número de desenvolvedores que usam as linguagens
listadas, a quantidade cursos disponíveis em cada uma, as vagas de emprego ofertados, entre outros.
Portabilidade
O interpretador Python, bem como suas bibliotecas padrão, estão disponíveis para praticamente todas
as plataformas de hardware/sistema operacional, incluindo Unix, Linux, Windows (todas as versões), Mac
OS, BeOS, VMS, entre outros. Isto significa que um programa escrito em Python e que use apenas as
bibliotecas padrão será executado da mesma maneira em qualquer uma dessas plataformas. Se o software
utilizar bibliotecas não consideradas como padrão será necessário verificar a disponibilidade dessas
bibliotecas para as várias plataformas.
Grande Aplicabilidade
Python pode ser utilizada em um grande número áreas do desenvolvimento de software, das quais se
destacam: ferramentas para administração e interface com sistemas operacionais; aplicações que
trabalhem com grandes volumes de dados (big-data) armazenados em bancos de dados Sql e NoSql;
aplicações gráficas e multimídia; análise de dados, tanto exploratória quanto inferencial; aplicações de
machine-learning e inteligência artificial em geral; programação para internet; desenvolvimento de softwares
específicos para áreas como estatística, engenharia, biologia, economia e aplicações científicas em geral.
Embora ambas sejam Python é como se fossem linguagens diferentes. E mesmo que a maioria dos
elementos estejam disponíveis nas duas versões, há diferenças significativas a ponto de a versão 3
representar importante quebra de compatibilidade em relação à versão 2. Sobre isso Guido van Rossum
declarou em uma postagem de 2007 (ROSSUM, 2007):
Por um bom tempo não havia muito mais do que uma lista de
arrependimentos e defeitos estruturais que eram impossíveis de corrigir
sem quebrar a compatibilidade retroativa. A ideia era que Python 3 seria o
primeiro release do Python a desistir desta compatibilidade em favor de
tornar-se uma linguagem melhor e evoluir.
Em um horizonte longo de tempo isso poderia se tornar um problema gigante e até insolúvel de modo
que depois de algum tempo após o lançamento da versão 3 foi publicada no website oficial de Python -
www.python.org - a seguinte afirmação: "Python 2.x é legado, Python 3.x é o presente e o futuro da
linguagem", indicando que a evolução da versão 2 deixaria de existir de fato. Campanhas incentivando a
migração foram iniciadas e isso fez com que, aos poucos, Python 3 passasse a ser usada com maior
intensidade.
Com o tempo, as vantagens da versão 3 se impuseram. Foram necessários mais de dez anos, mas
Python 3 se tornou majoritariamente usada e o suporte a Python 2 encerrou-se oficialmente em 20 de abril
de 2020 quando ocorreu o lançamento da derradeira versão 2.7.18.
Mac
Em alguns casos, usuários de computadores Mac da Apple podem também ter uma versão padrão do
Python pré-instalado. Para verificar isso, basta abrir o Terminal e digitar o comando “python –version”. Se o
Python estiver instalado, você verá a versão atual do Python sendo exibida.
Windows
Em todas as versões do Windows é necessário fazer a instalação de Python 3. E esse é um processo
fácil, rápido, seguro, que pode ser feito em poucos minutos. A única restrição é que você terá que possuir um
acesso ao Windows com privilégio de administrador.
Acesse o endereço de download e baixe a versão mais recente salvando o instalador em alguma pasta.
Inicie a execução do instalador: certifique-se de ligar a opção "Add python.exe to PATH" e depois clique em
"Install Now". Aguarde a instalação terminar. Quando isso acontecer já será possível usar a linguagem.
Link para a página de download do Python 3
https://www.python.org/downloads/
fonte: o Autor
Neste texto, sempre que você encontrar este ícone significa que há um vídeo disponível sobre o assunto.
Junto com a instalação de Python é instalado também um IDE simples chamado Idle. O Idle pode ser
usado para executar instruções de maneira interativa e também para criar, modificar e executar scripts
completos. Ele fornece um editor de texto que inclui recursos como destaque de sintaxe, preenchimento
automático e recuo inteligente. Ele também possui um depurador básico com pontos de interrupção do
código, verificação de conteúdo de variáveis e execução passo-a-passo do código do programa.
Além do Idle, que como dissemos é bastante simples, existem outros IDEs que podem ser usados para
escrever programas em linguagem Python e a figura 1.3 exibe alguns (não todos), com seus respectivos
Logotipos. Cada um tem seu próprio conjunto de recursos, alguns mais simples e outros mais sofisticados.
fonte: o Autor
Todos os IDEs exibidos na figura 1.3 são programas do tipo que o usuário baixa e instala em sua própria
máquina. Designamos estes IDEs como sendo off-line, pois uma vez que tenham sido instalados e
configurados você poderá usá-los sem a necessidade de manter uma conexão com a internet.
Para escrever os programas deste material foi utilizado o PyCharm. Para ilustrar a instalação e
configuração dele foi preparado um vídeo de demonstração.
Existem duas vantagens nos ambientes on-line: a primeira é que o acesso e uso pode ser feito a partir
de qualquer local e qualquer tipo de aparelho, como computadores, celulares ou tablets. Todo trabalho
realizado será armazenado nos servidores on-line (ou “na nuvem” para usar um termo muito corriqueiro
atualmente) o que implica que estará disponível para acesso de qualquer local que você queira trabalhar.
A segunda vantagem de usar um IDE on-line é que a máquina do usuário não precisa ser poderosa, pois
todo o processamento dos comandos ocorrerá no servidor que hospeda o IDE on-line e tais servidores
costumam ser máquinas com grande capacidade de processamento.
Por outro lado, há uma desvantagem a ser considerada. Para usar uma IDE on-line você precisará
contar com uma conexão com a internet para utilizá-los.
Um IDE on-line muito utilizado ao redor do mundo é o Colaboratory, carinhosamente conhecido como
Colab, desenvolvido e disponibilizado gratuitamente (até certos limites de uso) pelo Google. A figura a seguir
mostra a imagem do Colab.
fonte: o Autor
Para usar o Colaboratory é obrigatório que o usuário tenha uma conta Google. Caso você não tenha
uma, poderá criá-la gratuitamente. Além disso, depois de acessar sua conta Google você precisará ativar o
serviço Colaboratory associado a essa conta.
A documentação primária que deve ser a referência para todo programador Python é conhecida como
Python Docs e está disponível online no endereço https://docs.python.org/3
Quando tiver o Python instalado na sua máquina você também terá acesso ao Python Docs. Para
acessá-lo basta entrar no IDE Idle e pressionar a tecla F1 (em PCs).
A figura 1.5 mostra a tela inicial do Python Docs, conforme apresentada em janeiro de 2024, época em
que este material foi produzido. Neste momento a versão mais recente é a 3.12.1 e esta página reflete este
fato. À medida que as versões se sucedem o conteúdo de Python Docs é atualizado de modo que qualquer
acesso feito em um momento futuro poderá exibir na tela inicial uma versão posterior a essa atual.
Figura 1.5 - Tela inicial do Python Docs - Documentação oficial e primária da linguagem Python
Somando-se ao Python Docs há uma vasta disponibilidade de fontes de informação sobre Python, tais
como: artigos, vídeos, cursos, fóruns, listas de discussões, blogs, tudo isso acessível online em vários
idiomas, inclusive português. Também existe uma grande quantidade de livros publicados sobre o assunto.
Para os brasileiros, a comunidade Python Brasil
é excelente recurso em português.
Acesse a comunidade em: http://python.org.br
Considerando as máquinas que em geral estão disponíveis em 2024, ano em que este material foi
produzido, pode-se dizer que qualquer computador a que você tiver acesso executará os exemplos sem
problemas.
Além disso, todos os exemplos contidos neste material foram escritos e testados com uso de Python
versão 3.12.1 para o sistema operacional Windows. Nestes programas não foi usado nenhum recurso
específico da plataforma Windows de modo que se você utiliza outro sistema operacional não encontrará
dificuldades e os exemplos devem funcionar corretamente e sem problemas.
Por exemplo, imagine que você foi a uma papelaria e comprou os itens do quadro a seguir.
Item Qtde Preço por unidade Preço total
Caderno 100 folhas 2 36,90 73,80
Caneta preta 5 6,50 32,50
106,30
Os dados contidos nas colunas "Item", "Qtde" e "Preço por Unidade" são dados de entrada. A coluna azul
"Preço total" contém resultados produzidos a partir de uma manipulação dos dados de entrada. Você pode
escrever um programa em qualquer linguagem de programação para produzir esses resultados e exibi-los na
tela. Com esse exemplo fica claro que será necessário que o programa tenha algum elemento onde os dados
de entrada e os resultados calculados possam ser armazenados. Também é preciso que existam os
comandos que permitam que os cálculos sejam realizados.
fonte: o Autor
No lado esquerdo da figura foi posicionada a categoria "Classes" que contém os elementos que
armazenam os dados. No lado direito estão as categorias que permitem a manipulação dos dados, que são
as "Estruturas de Controle" e as "Funções Internas" da linguagem Python.
Não se preocupe agora com os elementos que estão listados dentro dos quadros. Eles serão vistos em
detalhes adiante e foram colocados aí apenas para que você tenha um resumo para acesso rápido no futuro.
1.7 COMENTÁRIOS
Do que foi dito na seção anterior resulta que um programa de computador é um texto escrito com
palavras que representam comandos, funções, classes e objetos. E todos eles tem que ser escritos de modo
correto, caso contrário o interpretador da linguagem vai dar erro.
No entanto, há situações em que desejamos escrever textos explicativos no meio do nosso código.
Esses textos chamamos de comentários e há o modo certo de escrevê-los de maneira que o interpretador da
linguagem os ignore e eles não interfiram na lógica de processamento do programa.
Comentários são algo muito importante no código de um programa e sua inserção é uma prática
normal. Toda linguagem de programação tem alguma maneira de permitir que comentários sejam inseridos
e em Python não é diferente. Eles são usados para adicionar descrições a partes do seu código, para
documentar e descrever os algoritmos implementados.
fonte: o Autor
Lembre-se
Bons profissionais comentam seus códigos.
• Legibilidade do código
• Simplicidade
• Modularidade e reutilização de código
• Capacidade de integração
Capítulo 2
CLASSES E OBJETOS
Vamos aprofundar essa ideia para em seguida entender como isso é feito em Python.
Está na hora de um exemplo prático para que você perceba que toda essa explicação na verdade
representa algo bem simples. Leia todas as linhas do exemplo 2.1 e a observação que está logo após.
Exemplo 2.1
qtde = 2
puni = 36.90
ptot = qtde * puni
msg = 'Total ='
print(msg, ptot)
Total = 73.8
Observação importante – Explicação sobre a estrutura do exemplo que vale para todos os exemplos contidos neste material.
As linhas mais escuras representam o código do programa e as linhas mais claras na sequência representam o resultado que será
visível na tela quando o programa for executado.
Na primeira linha quando fazemos qtde = 2 o valor 2 está sendo atribuído ao nome qtde. Assim,
dizemos que qtde é a variável e 2 é o seu conteúdo. Outras duas variáveis numéricas estão presentes: puni
para o preço unitário e ptot para o preço total que é um resultado calculado pela multiplicação
qtde * puni. Uma quarta variável, denominada msg, foi criada para conter um texto. Na última linha, a
função print é usada para exibir na tela o texto contido em msg seguido do valor contido em ptot.
Ao ser executado, este programa mostrará na tela Total = 73.8, conforme mostrado na parte cinza
claro da imagem do exemplo.
A expressão "Tipo de Dado" está relacionada à natureza do conteúdo que uma variável pode armazenar.
Esse conceito existe em todas as linguagens de programação, porém há algumas variações sobre a forma
como isso é implementado na prática em cada uma delas.
Há linguagens em que é obrigatório primeiro definir a variável e ao fazer isso é mandatório indicar qual
é o tipo do seu conteúdo. Só depois disso é que o programador pode utilizá-la no programa. Este é o caso das
linguagens C e Java. Além disso, nestas linguagens, o tipo da variável não poderá ser alterado ao longo do
programa.
Por outro lado, há linguagens, como Python e PHP, que abordam esse conceito de um modo diferente.
Nelas não é necessário declarar a variável, nem definir seu tipo previamente. O programador é livre para criá-
la no momento que desejar e para fazer isso basta atribuir um conteúdo, como feito no exemplo 2.1. O tipo
será automaticamente definido a partir do conteúdo. Nessas linguagens também pode ocorrer que um
mesmo identificador tenha um conteúdo numérico inteiro e um pouco adiante no programa esse mesmo
identificador passe a conter um texto, ou qualquer outro tipo de dado possível. Este é um aspecto que confere
grande flexibilidade ao programador, mas também exige certos cuidados para que o programa não fique
incorreto.
Sobre variáveis e tipos de dados pode-se dizer que toda variável possui um nome que a identifica e
armazena um conteúdo cujo formato é definido pelo tipo de dado a ela associado.
Nas duas seções anteriores apresentamos os conceitos de variável e tipo de dados. São conceitos
gerais que se aplicam a qualquer linguagem de programação.
Agora precisamos formalizar como isso é feito em Python. Cabe ressaltar que em Python não existem
tipos de dados e variáveis como nas linguagens C ou Pascal.
E Python é uma linguagem que segue esse paradigma, sendo totalmente orientada a objetos.
Detalhar o conceito de POO neste momento não seria produtivo, pois estamos no início do curso. POO
será assunto para o próximo módulo, mas há alguns conceitos básicos que você precisa conhecer para
compreender vários tópicos que vamos usar neste módulo.
Então vamos lá. Veja a figura 2.1 onde ilustramos alguns pontos centrais da Orientação a Objetos.
fonte: o Autor
Comparando com linguagens Não-POO pode-se dizer que a classe equivale ao tipo de dado e o objeto
equivale à variável.
Pode parecer mera questão de nomenclatura, mas é muito mais que isso. A diferença entre variáveis e
objetos está no fato de que as primeiras são um local de armazenamento. Na prática, a variável é apenas uma
referência a um endereço de memória do computador onde estão os bytes que representam o valor do dado.
Vendedor, Impostos, etc. Em cada classe deverão ser previstos os dados que lhe são relevantes e as ações
que são realizadas pela classe. Na figura 2.1 foi modelada a classe "Livro Didático", com seus atributos
palavras, parágrafos, imagens, etc; e com seus métodos abrir, fechar, etc.
No momento de usar a classe o programador deverá construir um ou mais objetos dessa classe. No
exemplo da figura 2.1 foram criados três objetos específicos, ou instâncias da classe: um livro didático com
conteúdo de geografia, outro com conteúdo de matemática e o terceiro com conteúdo de português.
No objeto "livro de geografia" espera-se que o conteúdo trate do assunto geografia e para isto acontecer,
basta carregar seus atributos – palavras, parágrafos, imagens, etc – com conteúdos de geografia. O mesmo
vale para os outros dois: matemática e português. A estrutura dos atributos é a mesma, mas o conteúdo é
diferente. Assim, podemos dizer que o conteúdo dos atributos personaliza o objeto, tornando-o específico
para uma determinada aplicação.
Como exemplo suponha que um objeto da classe Trabalhador contenha os atributos "salário bruto"
"salário líquido " e "conta corrente". Ele também pode possuir um método para calcular o "salário líquido" a
partir do "salário bruto" e outro método para enviar ao banco a informação de depósito do "salário líquido" na
"conta corrente".
Estes são os conceitos básicos de POO que você precisa conhecer neste momento.
E com base nesses conceitos podemos dizer que o Modelo de Dados de Python (Python Data Model)
é fundamentado no uso de Classes e Objetos.
Todo objeto Python possui três aspectos: um identificador, uma classe e um conteúdo.
• O identificador é o nome que o objeto tem no programa. Depois de criado esse nome nunca
pode ser alterado. Além disso, ele deve ser único, ou seja, não podem existir dois objetos com
o mesmo nome dentro de um escopo (o conceito de escopo é algo que ainda precisa ser
explicado, mas aqui não é o momento – sobre isso, pense que em um pequeno programa não
podem existir dois objetos com o mesmo nome);
• A classe é o gabarito usado para criação do objeto, na qual os atributos servem para
armazenamento e os métodos servem para executar processamento e realizar operações sobre
os atributos. Cada objeto em Python é sempre criado a partir de alguma classe. Assim, um
objeto do tipo número inteiro será da classe int e terá associado a si um conjunto de
operações adequadas à manipulação de números inteiros; um objeto do tipo lista será da
classe list e terá as operações adequadas à manipulação de listas; e assim por diante.
• O conteúdo do objeto é o que estará armazenado dentro do objeto. Observe que os objetos
podem ser simples ou complexos, podendo armazenar apenas um único valor (por exemplo um
número inteiro) ou todo um conjunto de valores interrelacionados (por exemplo nome, celular,
email e data de nascimento de um amigo seu).
Outro fato é que o identificador precisa ser válido e para isso é preciso seguir as seguintes regras:
• Deve ser escrito com letras maiúsculas (A-Z), minúsculas (a-z), algarismos (0-9) e underline
("_"). Quaisquer outros caracteres não são permitidos;
• Não pode haver espaços em branco;
• Não pode começar com um algarismo;
• Letras maiúsculas e minúsculas são consideradas caracteres distintos (case-sensitive);
• Podem ter qualquer quantidade de caracteres, sem limites.
Veja o vídeo do exemplo 2.2 no qual é usado o ambiente interativo Idle para mostrar esses conceitos.
Nele cada objeto é definido e em seguida, usamos a função type para mostrar qual é a classe de cada um.
Exemplo 2.2
>>> qtde = 2
>>> type(qtde)
<class 'int'>
>>> puni = 36.9
>>> type(puni)
<class 'float'>
>>> ptot = qtde * puni
>>> type(ptot)
<class 'float'>
>>> msg = 'Total ='
>>> type(msg)
<class 'str'>
>>> print(msg, ptot)
Total = 73.8
(exemplo interativo feito com IDE Idle)
Considerando o objeto qtde deste exemplo veja que estão presentes os três aspectos mencionados:
o identificador é qtde, a classe é int – exibida como <class 'int'> – e o conteúdo é o valor 2. O mesmo
vale para os outros objetos do exemplo.
Deste ponto em diante neste texto, será usado do termo "classe" ao invés de "tipo" e o termo "objeto"
ao invés de "variável", para referência aos elementos relacionados ao armazenamento de dados em
programas escritos com Python.
Nas próximas seções apresentamos as classes de objetos pré-existentes em Python. Por uma opção
didática será feita uma distinção em duas categorias como mostrado no capítulo 1, figura 1.6:
• Objetos simples: compreendem os tipos de dados mais básicos e são chamados de simples
pois são indivisíveis. São aqueles cujo valor representa uma única informação;
• Objetos compostos: são constituídos de elementos que podem ser acessados em conjunto ou
individualmente (em outras linguagens também são conhecidos como "tipos estruturados").
Exemplo 2.3
>>> n = 12
>>> type(n)
<class 'int'>
>>> f = 7.38
>>> type(f)
<class 'float'>
>>> c = 1.57 + 3.17j
>>> type(c)
<class 'complex'>
>>> b = True
>>> type(b)
<class 'bool'>
>>> x = None
>>> type(x)
<class 'NoneType'>
(exemplo interativo feito com IDE Idle)
Os objetos compostos de Python são descritos de forma sucinta no quadro 2.2 para que você saiba da
sua existência. Porém, nesta seção não colocaremos exemplos deles, pois precisam ser apresentados em
detalhes e com as devidas explicações para que sejam compreendidos. Vários desses objetos serão vistos
mais adiante neste módulo do curso. Outros, porém, devido ao seu grau de especialização e aplicabilidade
serão vistos nos módulos intermediário e avançado.
Em todos os casos colocamos no quadro a seguir, o link para a documentação oficial do Python que
trata do assunto, para que fique como referência rápida facilitando futuras consultas.
A classe str é usada para conter texto, ou seja, uma cadeia de caracteres.
Em um programa para definir uma cadeia de caracteres pode-se usar aspas simples ou duplas.
Os caracteres são armazenados utilizando-se a codificação Unicode (ao invés de ASCII).
Strings são construídos usando aspas. O Python aceita que sejam usadas tanto aspas
simples ('), quanto aspas duplas ("), desde que o mesmo tipo de aspas seja usado no início
e no final do string.
Para saber mais acesse:
https://docs.python.org/pt-br/3/library/stdtypes.html#text-sequence-type-str
list Exemplo: L = [12, 17, 9, 25, 41, 36, 23]
A classe lista é uma sequência. Listas são usadas para armazenar objetos de qualquer classe.
É comum que todos os elementos da lista sejam da mesma classe e quando isso ocorre
dizemos que a lista é homogênea. Porém isso não é obrigatório, ou seja, uma lista pode conter
elementos classes diferentes e aí dizemos que a lista é heterogênea.
Cada elemento da lista pode ser diretamente acessado e alterado através do uso de um índice,
sendo que o primeiro elemento terá índice 0 (zero).
Listas são construídas com o uso de colchetes [ ].
As listas serão vistas em detalhes no capítulo 7 deste material.
Para mais detalhes acesse: https://docs.python.org/pt-br/3/library/stdtypes.html#lists
tuple Exemplo: T = (23, 18, 99, 48, 56)
Uma tupla se assemelha a uma lista, porém com a diferença de que ela é apenas para leitura.
Ou seja, depois de criada não pode ser alterada. Se houver tentativa de alterar um elemento o
interpretador Python gerará uma mensagem de erro.
Assim como as listas, as tuplas também podem ser homogêneas ou heterogêneas.
Cada elemento da lista pode ser diretamente acessado através do uso de um índice, sendo que
o primeiro elemento terá índice 0 (zero).
Tuplas são construídas com o uso de parênteses ( ).
As tuplas serão vistas em detalhes no capítulo 7 deste material.
Para mais detalhes acesse: https://docs.python.org/pt-br/3/library/stdtypes.html#tuples
range Range é uma classe usada para criar sequências de números inteiros seguindo as regras de
uma progressão aritmética. Para produzir o resultado essa classe deve receber 1, 2 ou 3
parâmetros.
Exemplos:
class range(stop)
Se usada deste modo, range produzirá uma sequência iniciando em 0, avançando de 1 em 1 e
terminando em stop-1
Em Python esse operador tem um papel adicional, pois é ele que o programador deve usar para criar os
objetos que estarão presentes no programa. Nos exemplos 2.1 a 2.3 apresentados anteriormente você pode
conferir o uso dele em várias linhas do código. E, mesmo sem a explicação que estamos fazendo agora,
certamente entendeu aquelas linhas.
Veja agora o exemplo 2.4 a seguir. Na primeira linha usamos a função print() para exibir "a" na tela,
porém o resultado foi um erro indicando que o identificador "a" não está definido. Após fazer a = 10 o mesmo
print() funcionou corretamente, pois o objeto "a" foi criado na memória do computador com o uso do
comando de atribuição.
Exemplo 2.4
>>> print(a)
Traceback (most recent call last):
File "<pyshell#0>", line 1, in <module>
print(a)
NameError: name 'a' is not defined
>>> a = 10
>>> print(a)
>>> 10
(exemplo interativo feito com IDE Idle)
O comando de atribuição é uma ideia simples e fácil de assimilar. Porém, há mais informações que
você precisa saber sobre esse assunto. E são informações importantes para compreensão da segunda parte
do Modelo de Dados de Python.
Observe com atenção o exemplo 2.5 em conjunto com a figura 2.2, em especial o uso da função id().
Exemplo 2.5
>>> obj1 = 10
>>> type(obj1)
<class 'int'>
>>> id(obj1)
140730012416728
>>> obj2 = 10
>>> id(obj2)
140730012416728
>>> obj3 = 10.0
>>> type(obj3)
<class 'float'>
>>> id(obj3)
1563128829712
(exemplo interativo feito com IDE Idle)
Todo objeto Python é associado a um número inteiro único gerado no momento da criação do objeto e
que é mantido constante durante todo o tempo em que o objeto existir. A função interna id() é usada para
exibi-lo. Sempre que precisarmos nos referir a esse número usaremos o termo id.
No exemplo 2.5 são criados três objetos nomeados como: obj1, obj2 e obj3. Os dois primeiros
receberam o valor inteiro 10 e o terceiro recebe o valor real 10.0. A magnitude 10 é a mesma, mas a forma
como foi escrito com ponto e uma casa decimal faz toda a diferença.
Se analisarmos esses objetos por tipo de dado (número inteiro – classe int) e conteúdo (valor 10)
concluímos que obj1 e obj2 são idênticos e, em casos assim, a estratégia usada em Python leva à criação
de apenas um objeto e os dois identificadores obj1 e obj2 serão associados a esse objeto. E com isso,
ambos ficam associados ao mesmo id.
Por outro lado, o objeto obj3 é diferente, mesmo com seu valor também sendo de magnitude 10. Como
ele foi criado usando-se o valor no formato de número real o Python entende que deve criar um objeto da
classe float. E assim esse objeto se diferencia dos dois anteriores e estará associado a um id diferente.
Figura 2.2 – Ilustração da relação entre o identificador e o número id dos objetos Pyhton
fonte: o Autor
Cada vez que o interpretador Python precisar processar um comando de atribuição "=", ele vai avaliar a
expressão e determinar a classe e um conteúdo para o objeto, em seguida verificará que se já existe um id
que satisfaça essa combinação: se existir, ele faz a associação do identificador com o número id; se não
existir, ele cria um id para o novo objeto.
O exemplo 2.6 ilustra uma situação em que três objetos: x, y, e z são criados de diferentes formas, que
levam ao mesmo resultado, o valor 50. Ao verificar o id dos três objetos constatamos que é o mesmo número
associado aos três objetos.
Exemplo 2.6
>>> x = 50
>>> y = 12 + 38
>>> z = 100 - 50
>>> id(x)
140730012418008
>>> id(y)
140730012418008
>>> id(z)
140730012418008
>>> print(x, y, z)
50 50 50
>>> z = 90
>>> id(z)
140730012419288
(exemplo interativo feito com IDE Idle)
Agora, observe o que acontece com o objeto z quando alteramos seu valor para 90. Seu id é alterado.
Este fato nos leva à próxima seção.
Agora observe o que ocorre na Parte 2 do exemplo. Uma lista foi criada contendo 5 valores. Ao ser
criada, a lista ganhou um id. Em seguida um dos elementos da lista foi alterado com a atribuição L[0]= 12
e note que após essa alteração o id da lista não mudou.
Exemplo 2.7
# Parte 1 - Exemplo usando número inteiro
>>> obj1 = 8
>>> id(obj1)
140730012416664
>>> obj1 = 12
>>> id(obj1)
140730012416792
Agora que já verificamos esses fatos relativos ao id de objetos podemos nos aprofundar no Modelo de
Dados de Python.
Você pode escrever seus primeiros programas em Python sem conhecer detalhes sobre esses termos.
Porém, este é um conceito muito importante dentro dessa linguagem. Tanto isso é verdade, que basta acessar
qualquer um dos links listados no quadro 2.2 e você vai verificar que a página oficial da documentação Python
informa para cada classe se ela é imutável ou mutável.
Compreender a distinção entre essas duas categorias de objetos em Python é fundamental para criar
um código livre de erros e que também seja eficiente e confiável.
Nesta seção vamos nos concentrar em definir cada categoria e ao longo do restante deste material
vamos sempre nos referir a elas quando estivermos nos aprofundando nos elementos da linguagem.
Números inteiros, números reais, strings, tuplas entre outros são imutáveis.
A documentação oficial informa que os Objetos Imutáveis são aqueles cujos conteúdos não podem ser
alterados após serem criados. Veja o exemplo 2.7. Nesse exemplo o objeto obj1 foi criado, recebeu um id,
e foi carregado com um inteiro de valor 8. Como inteiros são imutáveis, ao ser feita a atribuição obj1 = 12
o objeto antigo foi descartado e um novo foi criado com outro id. Isso é ser imutável!
fonte: o Autor
• na primeira linha: A receberá 10, B receberá 15 e ambos serão inteiros (classe int);
• na segunda linha: X receberá 12 e será inteiro; Y e Z receberão 7.5 e 8.43 respectivamente e serão
números reais (classe float).
Digite essas linhas no Idle e use print() e type() para ver como ficam cada um dos objetos.
Em Python, essas expressões são construídas utilizando-se objetos de classes numéricas, operadores
aritméticos e funções matemáticas. Uma expressão aritmética é algo como essa linha a seguir:
R = A + B
onde: A e B são objetos numéricos e R recebe o resultado de sua adição. Nessa expressão, A e B são
chamados de operandos e " + " é o operador aritmético de adição.
É possível misturar objetos de diferentes objetos numéricos em uma única expressão. Quando houver
uma situação assim, o interpretador Python buscará a melhor maneira de resolvê-la. Havendo, em uma
expressão, a mistura de operandos inteiros e reais, o resultado calculado será real. E quando houver inteiros,
reais e complexos, o valor resultante será tratado como complexo.
Os operadores aritméticos disponíveis em Python são os indicados no quadro 2.3. Para os exemplos
contidos neste quadro foram usados os valores A = 14 e B = 5.
Exemplo 2.8
>>> A = 14
>>> B = 5
>>> C = A + B
>>> print(C)
19
>>> C = A - B
>>> print(C)
9
>>> C = A * B
>>> print(C)
70
>>> C = A / B
>>> print(C)
2.8
>>> C = A // B
>>> print(C)
2
>>> C = A % B
>>> print(C)
4
>>> C = -A
>>> print(C)
-14
>>> C = A ** B
>>> print(C)
537824
(exemplo interativo feito com IDE Idle)
>>> R = 2 * (A + B)
>>> print(R)
>>> X = (A + B) / (A + C)
>>> print(X)
>>> X = (2 * B – C) / (2 * A)
>>> print(X)
>>> X = -A * 2 + B
>>> print(X)
>>> X = A % B * C
>>> print(X)
Uma forma muito frequente de expressão aritmética usada nos algoritmos é aquela em que se toma o
conteúdo de um objeto e a ele se soma um certo valor ou outra variável. Uma expressão assim é escrita assim:
A = A + 1
Para compreender esta expressão primeiro deve-se olhar para seu lado direito: o interpretador irá
executar o cálculo A + 1 e produzir um resultado. Esse resultado será atribuído ao objeto presente no lado
esquerdo da expressão, que é o próprio A. Assim, haverá a substituição do valor original pelo novo valor
calculado.
Em Python, nestes casos, pode-se usar a operação de atribuição incremental, que tem a seguinte
construção:
A += 1
Para a atribuição incremental aplicam-se todos os operadores aritméticos previstos em Python. E o
valor a ser usado no incremento pode ser qualquer um, tanto literal quanto objetos. Veja o exemplo 2.9.
Exemplo 2.9
>>> A = 10
>>> P = 4
>>> A += P # equivale a A = A + P
>>> print(A)
14
>>> A = 0
>>> A += 15 # equivale a A = A + 15
>>> print(A)
15
>>> A -= 10 # equivale a A = A - 10
>>> print(A)
5
>>> A *= 6 # equivale a A = A * 6
>>> print(A)
30
>>> A /= 4 # equivale a A = A / 4
>>> print(A)
7.5
(exemplo interativo feito com IDE Idle)
A biblioteca-padrão está sempre disponível e não é necessário utilizar nenhum comando específico
para usá-la. As bibliotecas math e cmath por sua vez devem ser importadas antes de serem usadas. Veja o
exemplo 2.10, no qual foi utilizada a função matemática sqrt() capaz de calcular a raiz quadrada de um
valor.
Exemplo 2.10
>>> from math import sqrt # importação de função de biblioteca-padrão
>>> X = 49
>>> R = sqrt(X)
>>> print(R)
7.0
(exemplo interativo feito com IDE Idle)
O quadro 2.4 algumas funções disponíveis, indicando a qual biblioteca pertencem. Este quadro não
esgota todas as possibilidades existentes. Consulte a referência para conhecer todas as funções existentes.
Capítulo 3
COMANDOS DE SAÍDA E ENTRADA
Para realizar suas tarefas a função print() tem a estrutura de parâmetros mostrada a seguir.
print(*objects, sep=' ', end='\n', file=None, flush=False)
onde:
*objects é o conjunto de objetos cujo conteúdo será exibido;
sep separador a ser usado quando *objects contiver mais de um objeto. Valor padrão é um branco;
end contém o caractere a ser enviado para a saída no final. Seu valor padrão é \n (pulo de linha);
file define o arquivo de saída. Seu valor padrão é None, indicando que a saída é a tela;
flush se for True indica que o buffer de saída deve ser esvaziado. Seu valor padrão é False.
O único parâmetro obrigatório é *objects. Os demais são opcionais e têm valor padrão.
Exemplo 3.1
>>> print('Esta é uma mensagem exemplo') # caso 1
Esta é uma mensagem exemplo
>>> X = 26
>>> print(X) # caso 2
26
>>> Y = 58
>>> print(Y) # caso 2
58
>>> print(X, Y) # caso 3
26 58
>>> print('Valor de X =', X) # caso 4
Valor de X = 26
>>> print("Valores: X = {0} e Y = {1}".format(X, Y)) # caso 5
Valores: X = 26 e Y = 58
(exemplo interativo feito com IDE Idle)
O print() funciona em duas etapas: primeiro os objetos entre os parênteses (que podem ser de
qualquer classe) serão convertidos em uma sequência de caracteres de texto (classe str); em seguida esse
texto é direcionado para o dispositivo do computador.
Caso 1
Neste caso o objeto a ser exibido é um texto literal.
Caso 2
Os prints do caso 2 exibem objetos da classe int. O que se quer exibir é o valor numérico contido no
objeto de modo que o identificador do objeto é fornecido ao print() sem o uso das aspas.
Caso 3
No caso 3, são exibidos simultaneamente os conteúdos de dois objetos int. Isso faz com que os
valores sejam exibidos na mesma linha separados por um espaço em branco. Esse espaço em branco está
pré-configurado no parâmetro sep. Em casos assim, é possível alterar esse caractere separador
especificando-se um texto alternativo atribuído à sep, como mostrado no exemplo 3.2.
Exemplo 3.2
>>> A = 12
>>> B = 19
>>> print(A, B, sep="-") # o separador "-" contém apenas 1 caractere
12-19
>>> print(A, B, sep=" <--> ") # o separador " <--> " contém 6 caracteres
12 <--> 19
(exemplo interativo feito com IDE Idle)
Caso 4
É exibido um texto literal seguido do conteúdo de um objeto, e como o parâmetro sep não foi
especificado, foi inserido o espaço em branco padrão.
Caso 5
Neste caso é mostrado como produzir uma saída formatada. Esse tipo de saída é muito útil para criar
exibições de fácil leitura, pois permite controlar alguns detalhes da exibição dos dados.
É importante você saber que a função print() não é a responsável pela formatação. O papel dela se
limita a direcionar o texto dos objetos ao dispositivo.
A formatação é realizada pelos métodos disponíveis na classe str. No exemplo 3.3 mostramos que o
string de saída é criado e carregado no objeto s independentemente do print(); depois a função print()
é usada para exibir na tela o conteúdo de s já pronto.
A classe str conta três modos de produzir sequências formatadas. Veremos os dois mais populares.
A substituição dos marcadores pelos argumentos é feita seguindo-se o índice numérico, ou seja, nas
situações 1 e 2 da figura 3.1 o conteúdo do objeto X substituirá o marcador {0} porque X é o primeiro
argumento e o conteúdo de Y substituirá o marcador {1}, independentemente do local em que esses
identificadores estejam posicionados dentro do texto.
Opcionalmente é possível omitir o número dentro das chaves dos marcadores, utilizando apenas {}.
Neste caso, a associação entre marcador e objeto será feita pela ordem de ocorrência, como mostrado na
situação 3 da figura 3.1 (na qual pode-se verificar que é equivalente á situação 1).
fonte: o Autor
O quadro 3.1 mostra típicos casos de uso dos qualificadores de formatação. Sugerimos que você teste
cada um deles no Idle para verificar seu funcionamento e absorve a ideia.
S = "..{:>7d}..".format(A)
7d – número inteiro ocupando no mínimo 7
.. 9.. caracteres alinhado à direita (caractere de
(os pontos servem para marcar início e fim do espaço)
posição >)
7d – número inteiro ocupando no mínimo 7
S = "..{:<7d}..".format(A) ..9 .. caracteres alinhado à esquerda (caractere de
posição <)
7d – número inteiro ocupando no mínimo 7
S = "..{:^7d}..".format(A) .. 9 ..
caracteres centralizado (caractere de posição ^)
Há outras opções, mas não convém nos estender muito mais, pois são muitos os detalhes e este texo
ficaria muito extenso. Partindo dos princípios gerais exemplificados no quadro 3.1, você pode expandir seu
conhecimento dos detalhes a partir da exploração da documentação sobre este assunto que está disponível
no link a seguir:
Disponível em https://docs.python.org/pt-br/3/library/string.html#formatspec
Exemplo 3.4
>>> A = 14
>>> B = 32
>>> s1 = "Valores: A é {} e B é {}".format(A, B)
>>> s2 = f"Valores: A é {A} e B é {B}"
>>> print(s1)
Valores: A é 14 e B é 32
>>> print(s2)
Valores: A é 14 e B é 32
(exemplo interativo feito com IDE Idle)
Um f-string começa com uma das letras "f" ou "F" e dentro do marcador {} é colocado o objeto que
se quer exibir naquela posição.
s2 = f"Valores: A é {A} e B é {B}"
Todas as demais funcionalidades relativas aos qualificadores de formatação vistas na seção 3.1.2
também se aplicam aos f-strings. O quadro 3.2 mostra a correspondência para cada um exemplos.
3.1.4 O QUE É O \n ?
Ao usar a função print() é muito comum nos depararmos com a dupla de caracteres \n. Isso pode
ser encontrado em várias linguagens como C, Java e Python. Na verdade, porém, não se trata de uma dupla
de caracteres: o \n é uma "sequência de escape" (escape sequence). Sequências de escape consistem em
uma barra invertida (\) seguida de uma letra ou dígitos e representam determinadas ações, como no caso do
\n que representa a ação de "pulo de linha" ou "avanço de linha".
Sempre que usado junto com print() ele faz com que o cursor de tela pule para a linha de baixo. Veja
a seguir algumas possibilidades:
print('\n') # pula uma linha na tela
print('um\ndois') # escreve 'um' em uma linha, pula a linha, escreve 'dois' embaixo
print('\n\n\n') # pula três linhas
print('\n\nAlgo') # pula duas linhas e escreve 'Algo'
Para funcionar corretamente o \n deve estar dentro das aspas
Para saber mais sobre sequências de escape veja esta página da Microsoft
https://learn.microsoft.com/pt-br/cpp/c-language/escape-sequences
Em Python 3 quem realiza essa tarefa é a função input(). Para usá-lo basta atribuir seu retorno a
algum identificador como mostrado no exemplo 3.5. Opcionalmente pode-se passar um parâmetro que será
usado como uma mensagem que indique o que deve ser digitado.
Exemplo 3.5
>>> A = input()
Digitei isto # o input vai esperar que algo seja digitado
>>> print(A)
Digitei isto
Quando a função input() é executada o computador aguarda que o usuário digite o que precisar
seguido de "Enter". Quando a tecla "Enter" é pressionada tudo o que foi digitado é carregado no objeto que
recebe o retorno da função.
No exemplo a primeira leitura carrega o objeto A sem mostrar qualquer mensagem na tela. Já na
segunda leitura é apresentada a mensagem "Digite algo: " indicando ao usuário o que deve ser feito e no
retorno dessa função o objeto B é carregado.
O usuário pode digitar o que quiser e a leitura sempre resulta em uma cadeia de caracteres (string)
carregada no objeto de destino. Se forem digitados apenas algarismos, ainda assim a leitura resulta em uma
cadeia de caracteres. Isso pode ser constatado no exemplo 3.6, no qual o objeto N aparentemente recebe
um número inteiro e F aparentemente recebe um número real. Porém, ao utilizar o comando type, verifica-
se que ambos são do tipo da classe str, portanto um string.
Exemplo 3.6
>>> N = input("Digite um inteiro: ")
Digite um inteiro: 37
>>> print(N)
37
>>> type(N)
<class 'str'>
No exemplo pode-se verificar que, de fato, a função input() retorna exclusivamente cadeias de
caracteres. Agora a questão é: como fazer caso precisemos ler números inteiros ou reais?
A resposta para isso são as funções de conversão de tipo apresentadas na próxima seção.
O exemplo 3.7 mostra diversos casos de conversão de tipo. Em cada linha colocamos a explicação do
que está sendo feito e convidamos você a testar todas as linhas do exemplo no Idle.
Uma vez entendido esse processo podemos dar o próximo passo e escrever o mesmo código assim:
A = int(input('Digite A: ')) # lê o teclado, converte para int e carrega A com ele
Agora as duas operações ainda estão presentes, porém escritas em uma única linha e tornando o
código mais compacto. Esta forma é a mais usada nos programas Python.
Dicas: Leve em consideração que 1 hora tem 3600 segundos e 1 minuto tem 60 segundos.
Use os operadores de divisão de inteiros (//) e resto (%).
Escreva um programa que leia 3 dados de entrada reais: Investimento, Custos e Receita, calcule o
ROI usando a fórmula acima e exiba o resultado com uma casa decimal no formato mostrado abaixo.
Exemplo: Investimento = 2300.00 – Custos = 345.73 – Receita = 2712,17
Saída: ROI = 2.5%
Capítulo 4
COMANDO CONDICIONAL
Este capítulo e os próximos dois tratam de comandos da linguagem Python que fazem o controle do
fluxo de execução de um programa. Por controle de fluxo em um programa entende-se a ordem lógica de
execução dos comandos que o compõe. Isso envolve basicamente três aspectos:
• Desvios na ordem de execução do código em função de certas condições que possam ocorrer.
Este tópico será visto neste capítulo;
• Repetição de trechos do programa por um determinado número de vezes, necessária para que
um algoritmo possa ser, de fato, implementado. Este tópico será visto no capítulo 5;
• Tratamento de situações de erro que possam ocorrer, também chamado de Tratamento de
Exceções. Este tópico será visto no capítulo 6.
Exemplo 4.1
A = 10
B = 0
R = A / B
print(R)
Traceback (most recent call last):
File "D:\exemplos\exemplo_4.1.py", line 3, in <module>
R = A / B
~~^~~
ZeroDivisionError: division by zero
Situações de erro assim são indesejáveis e é preciso tomar o cuidado de se evitá-las. Uma das formas
(não a única) de se conseguir isso é usar o Comando Condicional: if-else. Outra forma será vista no
capítulo 6.
Ao utilizar o comando condicional será necessário formular uma condição cujo resultado será uma de
duas possibilidades: falso ou verdadeiro. Em função desse resultado o programa seguirá apenas um de dois
possíveis caminhos distintos. A ideia básica é implementar um código que reflita esta frase: "se B for igual a
zero, então apresente a mensagem 'Não é possível calcular a divisão', senão (ou seja, B é diferente de zero)
calcule e apresente na tela A / B.
Em Python um programa completo capaz de implementar essa ideia é exibido no exemplo 4.2.
Exemplo 4.2
A = int(input('Digite A: ')) # linha 1
B = int(input('Digite B: ')) # linha 2
if B == 0: # linha 3
print('Não é possível calcular a divisão') # linha 4
else: # linha 5
R = A / B # linha 6
print(R) # linha 7
primeira execução
Digite A: 26
Digite B: 0
Não é possível calcular a divisão
segunda execução
Digite A: 26
Digite B: 4
6.5
fonte: o Autor
O próximo passo é avançar em direção aos detalhes que ainda não foram mencionados.
Esta condição será avaliada pelo processador e um resultado será gerado. Esse resultado pode ser
falso ou verdadeiro. Caso seja verdadeiro, o programa seguirá para a linha 4 e executará a função print().
Caso seja falso, o programa vai ignorar a linha 4 e seguirá para a execução das linhas 6 e 7, que estão
subordinadas ao else (senão) da linha 5.
Note que nas linhas 3 e 5 há um caractere ':' (dois pontos) no final da linha. Em Python é obrigatória a
colocação desse caractere no comando tanto no if, como no else, pois é através dele que o interpretador
Python identifica o término do cabeçalho do comando e o início do código subordinado.
Essa relação de subordinação é muito importante na lógica do algoritmo. Neste exemplo a linha 4 está
subordinada ao if da linha 3 e as linhas 6 e 7 estão subordinadas ao else da linha 5.
4.1.3 INDENTAÇÃO
Como dito, a relação de subordinação de um trecho de código a um determinado comando é muito
importante na lógica de um programa.
Na maioria das linguagens essa indentação é opcional e cabe ao programador decidir se vai ou não
usá-la – e é preciso que fique claro que todos os bons programadores usam, porque torna o código mais
legível e fácil de compreender.
No Python a indentação é obrigatória. No exemplo 4.2 note que o if e o else estão no mesmo
alinhamento e seus comandos subordinados estão avançados para a direita indicando uma relação de
subordinação. Generalizando, em Python, todo conjunto de comandos subordinados deve estar indentado
em relação ao seu comando proprietário. Isso vale para if-else, while, for, try, def e qualquer outro
elemento de Python em que exista a relação de subordinação.
A condição B == 0 usada no exemplo 4.2 é uma condição simples, pois ela tem a seguinte construção:
<expressão 1> <operador> <expressão 2>
onde as expressões 1 e 2 podem ser uma dessas possibilidades:
O operador é um dos seis operadores relacionais exibidos no Quadro 4.1. No caso dos operadores que
contém dois caracteres, não é permitido haver espaço em branco entre eles.
Exemplo 4.3
>>> A = 10
>>> B = 50
>>> A > 0 # Comparação entre objeto e literal
True # o resultado é True porque A é maior que zero
>>> B <= 0 # Comparação entre objeto e literal
False # o resultado é False porque B não é maior ou igual a zero
>>> A >= B # Comparação entre dois objetos
False # o resultado é False porque A não é maior ou igual a B
>>> 5 * A == B # Comparação entre fórmula e objeto
True # o resultado é True porque 5 vezes A é igual a B
>>> A >= pow(B, 0.5) # Comparação entre objeto e função (raiz quadrada de B)
True # o resultado é True porque A é maior ou igual à raiz de B
(exemplo interativo feito com IDE Idle)
Um detalhe sobre a última condição do exemplo. Nela foi usada a função de exponenciação
pow(base, exp). Essa função recebe dois parâmetros base e exp e calcula baseexp (base elevado a exp).
Como foi usado o valor 0.5 para exp isso equivale a calcular a raiz quadrada.
Cada um desses operadores é regido por uma Tabela Verdade que define seus resultados em função
das entradas. A figura 4.2 exemplifica o uso do operador lógico not.
fonte: o Autor
fonte: o Autor
fonte: o Autor
Observação:
A linguagem Python não possui o operador lógico xor
(ou exclusivo) que costuma estar disponível em outras linguagens.
Se você precisar usar esse operador deverá usar a expressão equivalente:
C1 xor C2 = (not C1 and C2 or C1 and not C2)
Quando isso ocorre é preciso que você preste atenção à precedência com que esses operadores são
considerados. Existe uma ordem de prioridade a ser respeitada. Essa prioridade segue a seguinte ordem:
not primeiro; and em seguida; or por último.
É possível usar parênteses para alterar a ordem de prioridade na avaliação dessas expressões. Uma vez
inseridos, os parênteses modificam as prioridades e estabelecem qual (ou quais) parte(s) serão avaliada(s)
primeiro. Veja no exemplo 4.4 que a colocação ou não dos parênteses afeta o resultado da condição mista.
Exemplo 4.4
>>> A = 15
>>> B = 9
>>> C = 9
>>> B == C or A < B and A < C # caso 1: Resultará Verdadeiro
True
>>> (B == C or A < B) and A < C # caso 2: Resultará Falso
False
(exemplo interativo feito com IDE Idle)
• inicia-se pela avaliação da <condição 1> e se ela for verdadeira será executado o <bloco de
comandos 1> e pulam-se todos os demais;
• caso a <condição 1> seja falsa, passa-se para a avaliação da <condição 2> e se ela for verdadeira
será executado o <bloco de comandos 2>, pulando-se os demais;
• caso a <condição 2> seja falsa, passa-se para a avaliação da <condição 3> e se ela for verdadeira
será executado o <bloco de comandos 3>, pulando-se os demais;
Essa é a forma completa do comando. Porém, as partes elif e else são opcionais e o programador
poderá omiti-las caso não necessite delas. Quando a quantidade de elif a serem usados, não há limite.
Assim, o programador pode inserir tantos quantos forem necessários para implementar seu programa.
Veja o exemplo 4.5 no qual foi usada a forma completa do comando if.
Exemplo 4.5
PH = float(input("Digite um valor do PH: "))
if PH < 6.0:
r = "ácida"
elif PH < 7.0:
r = "levemente ácida"
elif PH == 7.0:
r = "neutra"
elif PH < 8.0:
r = "levemente alcalina"
else:
r = " alcalina"
print(f'Com pH = {PH} a solução é {r}')
Digite um valor do PH: 4.5
Com pH = 4.5 a solução é ácida
Neste exemplo é lido um número real que representa o valor de pH de uma solução. Há 5 possibilidades
de classificação conforme o valor do pH conforme o quadro 4.3.
É exatamente isso que está implementado no exemplo 4.5, onde foi usada a construção if-elif-else
para avaliar o valor fornecido para o objeto pH e a partir daí carregar o objeto r com a classificação da
solução.
Isso está demonstrado no exemplo 4.6, cujo enunciado é: escreva um programa que forneça o tipo de
aplicação financeira adequado a um investidor a partir de dois dados fornecidos: o grau de aceitação de risco
e o valor a ser investido. O quadro 4.4 mostra as opções de combinação entre esses dois dados. O grau de
aceitação de risco deve ser lido do teclado na forma BX para baixo ou AL para alto. Se for fornecido algo
diferente disso o programa deve mostrar uma mensagem indicando que foi fornecido dado inválido. Para o
valor deve-se ler um número real.
Na solução implementada nas duas linhas iniciais foi feita a leitura dos dados de entrada. Em seguida
um primeiro if é usado para verificar o que foi digitado para o objeto risco; se estiver errado, o programa
exibe a mensagem e termina.
Se estiver correto o programa segue para o else. Dentro desse else do primeiro if é escrito todo o
resto do código. Um segundo if é usado para decidir se o risco é baixo ou alto. Em ambos os casos mais um
if é usado para estabelecer o tipo de aplicação conforme o que tenha sido digitado para o objeto valor.
Exemplo 4.6
risco = input('Digite BX ou AL para o grau de risco: ')
valor = float(input('Digite o valor: '))
if risco != 'BX' and risco != 'AL':
print(f'{risco} é inválido para o grau de risco')
else:
if risco == 'BX':
if valor < 1000.0:
tipo = 'Poupança'
else:
tipo = 'Renda fixa'
else: # risco == 'AL'
if valor < 1000.0:
tipo = 'Bitcoins'
else:
tipo = 'Ações'
print(f'Você deve investir em {tipo}')
primeira execução
Digite BX ou AL para o grau de risco: AL
Digite o valor: 2500
Você deve investir em Ações
segunda execução
Digite BX ou AL para o grau de risco: AL
Digite o valor: 500
Você deve investir em Bitcoins
terceira execução
Digite BX ou AL para o grau de risco: BX
Digite o valor: 2500
Você deve investir em Renda Fixa
quarta execução
Digite BX ou AL para o grau de risco: BX
Digite o valor: 500
Você deve investir em Poupança
quinta execução
Digite BX ou AL para o grau de risco: PP
Digite o valor: 2500
PP é inválido para o grau de risco
Nestes programas que exigem a criação de comandos condicionais aninhados preste bastante atenção
para que a relação de subordinação entre os comandos fique correta.
segunda execução
Digite um inteiro: 53
O número 53 é ímpar
Fim do Programa
Nesta solução, após a leitura de X, é feito o cálculo do Resto com o uso do operador matemático "%".
Em seguida este resultado é usado para construir a condição do comando condicional Resto == 0. Caso
a avaliação da condição resulte em verdadeiro apenas o primeiro print() será executado, mostrando na
tela que o número é par; se resultar em falso será executado apenas o segundo print() mostrando que o
número é ímpar.
Esta segunda forma de fazer é mais usual entre os programadores mais experientes.
segunda execução
Digite A: 58
Digite B: 12
O menor número é 12
Fim do Programa
Para exibir o menor valor dentre A e B foi criada a condição A <= B. Se ela resultar em verdadeiro
significa uma de duas possibilidades: ou A é menor que B; ou A e B são iguais. Neste caso A é exibido – e isso
está de acordo com o enunciado que diz "se ambos forem iguais, mostre qualquer um deles". Caso a condição
resulte em falso, então B será exibido, pois é menor que A.
Quando isso ocorre são necessários dois comandos condicionais aninhados. Optamos por perguntar
primeiro se A == B e em caso verdadeiro exibir a mensagem de que são iguais. No caso de serem diferentes
a execução é desviada para o else do primeiro if. Dentro desse else restam as outras duas possibilidades:
A menor ou B menor e para decidir sobre elas um segundo if foi usado. Escreva esse programa e teste-o com
valores que produzam as três situações.
Esse mesmo enunciado pode ser resolvido de outra maneira se for usada parte elif do comando
condicional. Veja o código 4.3 reescrito a seguir e note que a solução fica bem interessante, pois é mais
compacta e produz o mesmo resultado.
segunda execução
Digite o nome: Felipe
Digite o peso: 43.2
Peso inválido: 43.2
Fim do programa
terceira execução
Digite o nome: Maguila
Digite o peso: 102.3
O lutador Maguila pesa 102.300 kg e se enquadra na categoria Pesado
Fim do programa
Este exercício resolvido 4.4 tem o propósito de ilustrar uma situação também frequente em que há
várias alternativas de seleção. Na implementação dessa solução optou-se por usar a forma completa do
comando condicional, que inclui a parte elif. Também seria possível resolver este problema usando ifs
aninhados. Funcionaria perfeitamente, mas não seria muito prático pois criaria 8 níveis de indentação e com
uma legibilidade não muito boa.
Verifique que existe o caso em que o peso é inválido quando < 52 e os demais casos para pesos
maiores. Na solução optou-se por carregar o objeto Categoria com um string vazio e depois no final do
programa essa informação foi usada em um if para exibir na tela a mensagem final.
Você deve ter percebido que temos dado preferência para usar f-strings na formatação das
mensagens de saída. Porém neste caso, usamos o método .format()também foi usado. Isso foi feito para
mostrar que os dois modos podem coexistir em um programa.
Capítulo 5
COMANDOS DE REPETIÇÃO
Muitas vezes um determinado bloco de código precisa ser repetido várias vezes. A esta situação de
execução de repetições em um programa damos o nome de "laço de repetição" ou "loop de repetição". Na
linguagem Python existem dois comandos que realizam repetições:
• Comando while: este é o comando de repetição de uso geral e será visto neste capítulo;
• Comando for: este comando é para uso especializado e será visto no capítulo 7;
Para exemplificar a implementação de um laço considere o exemplo 5.1 a seguir no qual é feita a
exibição de todos os números inteiros entre 1 e 10, sendo um valor em cada linha.
Neste exemplo, na linha 1 é definido um objeto identificado por cont e inicializado com o valor 1. Na
linha 2 está o comando while construído com a condição cont <= 10. A avaliação dessa condição resulta
em True (verdadeiro) de modo que o conjunto de comandos subordinado, constituído pelas linhas 3 e 4, é
executado uma primeira vez. Com isso, o valor inicial de cont é exibido (linha 3) e 1 é somado a cont (linha
4), que passará a ser 2.
Em seguida o programa retorna para a linha 2, a condição é avaliada e novamente resultará True, pois
cont é menor que 10. Isto fará com que o print e a soma de 1 em cont sejam executados uma segunda vez.
Com isso cont passará a conter o valor 3 e o laço prosseguirá com cont avançando de um e um até o final.
Quando cont atingir o valor 11 a condição cont <= 10 se tornará falsa e o while terminará. Ao final desse
processo dez linhas terão sido exibidas na tela contendo os valores de 1 a 10.
Exemplo 5.1
print("Início do Programa")
cont = 1 # linha 1
while cont <= 10: # linha 2
print(cont) # linha 3
cont = cont + 1 # linha 4
print("Fim do Programa")
Início do Programa
1
2
3
4
5
6
7
8
9
10
Fim do Programa
O primeiro ponto é saber que o teste da condição é feito no início do laço. A figura 5.1 ilustra esta
situação: a avaliação da condição é feita antes de se executar o conjunto de comandos subordinado. Este
fato tem uma implicação conceitual importante porque nos casos em que a condição for previamente falsa
o conjunto subordinado não será executado nenhuma vez.
fonte: o Autor
Os três primeiros dizem respeito à estrutura e controle do laço. A inicialização constitui-se de todo
código necessário para determinar a situação inicial do laço. A condição de continuidade é uma expressão
lógica, simples ou composta, cujo resultado é avaliado em falso ou verdadeiro a cada repetição e que
determinará se o laço termina ou prossegue, respectivamente. A iteração é todo comando (um ou mais de
um) que modifica os objetos envolvidos na condição de continuidade, a cada execução do laço.
Por fim, o bloco de código subordinado é constituído pelos comandos que devem ser executados
repetidas vezes. No exemplo 5.1 acima, a inicialização está na linha 1, a condição de continuidade está na
linha 2 e a iteração é a linha 4. O corpo do laço é a linha 3.
Nesta solução o controle do laço é realizado de forma diferente. Desta vez não temos um contador, ou
seja, a natureza do controle do laço é de outro tipo.
Neste caso não sabemos quantas vezes o laço irá repetir, pois depende dos dados que o usuário for
digitando. O que se sabe apenas é que o laço deve terminar quando zero for digitado para X.
Para garantir que o laço seja iniciado, o objeto X deve ser criado contendo qualquer valor diferente de
0, o que é feito na linha 1. A linha 1 é a linha de inicialização. A Iteração é implementada na linha 3 que altera
o valor do objeto X. O novo X lido logo no início do laço também é usado no corpo do mesmo, que é constituído
pelas linhas 4 a 7. O resto da divisão de X por 2 é calculado e comparado com zero. Se o resultado dessa
comparação for verdadeiro, então o número é par, caso contrário é ímpar. Quando zero for digitado, o
programa dirá que zero é par e terminará.
Neste exercício temos novamente o controle do laço feito com o uso de um contador. O objeto de
controle do laço é o cont, inicializado com 1 e que é incrementado a cada repetição até que assuma um
valor maior que 10. Para cada repetição é feito o cálculo do resultado da linha da tabuada e sua exibição.
Nas duas primeiras linhas é feita a leitura dos dados. Em seguida é implementado o laço de repetição
com o objeto cont inicializado em 0; a condição de continuidade cont < 10; e o incremento
cont = cont + 1 alterando o objeto de controle do laço. A cada repetição um termo da PA é exibido e o
próximo é calculado.
Propositalmente, neste exercício o objeto cont foi inicializado com 0 e a condição foi escrita como
cont < 10. Compare-a com o exemplo 5.1 onde o objeto cont foi iniciado com 1 e a condição escrita como
cont <= 10. Estas são duas formas diferentes de implementar um laço que executa o mesmo número de
vezes. Em situações como essa cabe ao programador escolher a alternativa que considera mais interessante
para o programa.
Neste exercício temos uma novidade: o valor de D deveria ser maior que zero. Com isso usamos um
comando if para fazer a verificação e se D for menor ou igual a zero emitimos uma mensagem dizendo que
é inválido. No else (que ocorrerá quando D for maior que zero) foi implementado o restante do código. Neste
ponto foi implementado um laço de repetição baseado em um contador. O objeto i foi usado no controle do
laço e cada vez que esse i era divisível por D seu valor foi exibido na tela. No teste exibimos todos os números
inteiros até 100 e divisíveis por 22.
Este exercício também tem o propósito de mostrar que podem existir comandos condicionais dentro
de comandos de laço e vice-versa, sem limite de vezes em que isso ocorre.
print(f'Quantidade = {qtde}')
print('Fim do Programa')
Digite X: 16
Digite X: 40
Digite X: 21
Digite X: 6
Digite X: 0
Soma dos valores = 83
Quantidade = 4
Fim do Programa
Neste programa o controle do laço se faz através do objeto A que é lido a cada repetição. Quando for
digitado o valor 0 para A o laço irá terminar e é preciso o cuidado de não somar 1 no objeto qtde quando isso
ocorrer. Por esse motivo foi usado o comando condicional if A != 0 dentro do laço.
Exemplo 5.2
i = 0
while i < 5:
Quando o continue é executado a execução é
i = i + 1
imediatamente retornada ao cabeçalho do comando de
if i == 4:
repetição
continue
print(i)
1
3
4
5
É preciso ter muito cuidado com esse comando, pois é muito comum que o programador inexperiente
cometa erros sérios ao usá-lo de forma inadequada. Como exemplo veja as linhas a seguir:
i = 0
while i < 5:
if i == 4:
continue
i = i + 1 # A mudança de posição desta linha é a única alteração.
print(i)
Uma simples alteração de posição na linha i = i + 1 e este código fica totalmente errado. Quando
o valor de i chegar a 4 será executado o continue sem passar pela linha do incremento de i. Isso implica
que o valor de i será 4 para sempre e esse laço executará indefinidamente. É o que se chama de laço infinito,
um erro severo, pois seu programa parecerá congelado, não exibindo nada na tela e nem respondendo ao
usuário. Faça o teste. Escreva esse código e rode. Ele mostrará na tela os valores de 1 a 4 e depois "congelará".
Exemplo 5.3
X = 1
while True:
X = int(input('Digite X: '))
if X == 0:
print(' você digitou zero...')
break Quando o break é executado o
print(X) laço termina imediatamente
print('Fim do Programa')
Digite X: 8
8
Digite X: -4
-4
Digite X: 1
1
Digite X: 0
você digitou zero...
Fim do Programa
Exemplo 5.4
X = 1
while X > 0: # enquanto X for positivo faça as repetições
X = int(input('Digite X: '))
if X == 0: # se X for zero interrompa o laço
print(' você digitou zero...')
break
print(X)
else: # este else é executado quando X for negativo se X for zero não
print('você digitou negativo')
print('Fim do Programa')
Escreva este programa e teste-o várias vezes, algumas digitando 0 e outras um negativo
O exemplo 5.4 é uma adaptação do 5.3, no qual foram feitas duas alterações: a troca da condição do
while e a inclusão da cláusula else para exibir a mensagem "você digitou negativo". Teste esse código para
ver seu funcionamento.
Capítulo 6
TRATAMENTO DE EXCEÇÕES
6.1 CONCEITO
Erros podem acontecer em um sistema computacional. Há erros de hardware, outros relacionam-se
ao sistema operacional e há os erros dos programas de usuário final. Este último é o que nos interessa.
O tratamento de exceções está relacionado com erros que podem acontecer em um programa. Esse
termo, exceção, se refere às situações que necessitam de atenção e algum tratamento especial fora da
lógica normal de processamento do programa. Essas situações estão sempre relacionadas aos dados que
estão nos objetos e são decorrentes uma grande variedade de fatores, tais como:
A pequena lista acima não esgota todas as possibilidades de erros e falhas que podem ocorrer com os
dados em um programa de computador. E quando qualquer desses fatores ocorre, o programa pode parar de
funcionar podendo ocasionar vários tipos de contratempo e prejuízo. A elaboração de uma boa estratégia de
tratamento de exceções permite a criação de programas robustos e confiáveis.
No capítulo 4 o exemplo 4.1 contém um erro que interrompeu sua execução. É este código:
Neste exemplo ocorre um erro da classe ZeroDivisionError decorrente da tentativa de fazer uma
divisão por zero. Os exemplos 6.1 e 6.2 a seguir mostra mais dois erros de natureza distinta.
No exemplo 6.1 o objeto Dado foi carregado com o string '13o5' e em seguida houve a tentativa de
convertê-lo para número inteiro. É uma situação que pode acontecer em que, por um engano de digitação do
usuário, o programa recebeu uma letra 'o' no lugar do algarismo '0' e em virtude disso não é possível fazer a
conversão. O erro gerado foi da classe ValueError e o programa parou de funcionar.
No exemplo 6.2 existe uma lista que contém 5 elementos e houve a tentativa de exibir na tela o
elemento de índice 10, que não existe. Como resultado ocorreu um erro da classe IndexError.
Você pode estar pensando que está evidente que são erros simples e que basta um pouco de atenção
ao programador para não os cometer. Ocorre, no entanto, que as falhas nos programas do mundo real não
são evidentes dessa forma. O caso 6.1, por exemplo, poderia ser um software rodando na internet e que
recebe esse dado com a letra 'o' digitado por um usuário com pouca familiaridade com computadores. No
caso 6.2 o índice 10 não estaria ali dessa forma explícita, mas sim dentro de um objeto que foi carregado a
partir de um banco de dados, no qual podem existir inconsistências de cadastro. Em outras palavras, existem
inúmeras situações que podem ser exemplificadas e que vão mostrar que falhas ocorrem.
Considere novamente o exemplo 4.1. No capítulo 4 resolvemos o erro de divisão por zero com o uso de
um comando condicional if. Então você poderia questionar: poderíamos sempre evitar os erros usando
ifs? Não é tão simples assim.
Os sistemas computacionais estão cada vez mais complexos e usar condicionais para prever e tratar
tudo o que pode dar errado só vai fazer com que esse sistema fique cheio de condicionais e ainda mais
complexo, pois tudo o que pode dar errado teria que ser previsto e tratado. Assim, a maioria das linguagens
de programação possui recursos voltados para a identificação e o tratamento desses erros, cabendo ao
profissional de programação dominar as técnicas e métodos relacionados a isso.
Exemplo 6.3
A = int(input('Digite A: '))
B = int(input('Digite B: '))
try:
R = A / B
print(f'Resultado = {R}')
except:
print('Não é possível calcular a divisão')
primeira execução
Digite A: 20
Digite B: 0
Não é possível calcular a divisão
segunda execução
Digite A: 75
Digite B: 4
Resultado = 18.75
Nesse código as leituras de A e B estão fora do try e não estão protegidas. O cálculo da divisão e o
print() estão dentro do try e estão protegidos. O except define qual será o tratamento em caso de erro
na parte protegida.
Na primeira execução deste exemplo foi fornecido o valor 0 para B. Como isso gera o erro de divisão por
zero a execução foi desviada para o except, dentro do qual é exibida a mensagem "Não é possível calcular
a divisão". Na segunda execução o valor de B é diferente de zero, então as duas linhas do código protegido
pelo try foram executadas e o resultado da divisão foi apresentado na tela.
Agora volte ao exemplo 6.3 e olhe para a primeira linha onde é feita a leitura de A. Considere que o
usuário quisesse digitar 50, mas colocou a letra 'o' no lugar do zero. Isso vai gerar um ValueError e essa
linha não está protegida.
Vamos então fazer uma alteração e passar os comandos de leitura para dentro do bloco protegido pelo
try. E assim temos o exemplo 6.4 no qual o bloco protegido contém quatro linhas de código conforme pode
ser visto.
A questão da proteção está resolvida, mas agora temos outro problema. Qualquer erro que ocorra vai
desviar para o except e dar a mesma mensagem " Não é possível calcular a divisão", independente de qual
erro realmente ocorreu: se foi na leitura de um dado (ValueError) ou se foi divisão por zero
(ZeroDivisionError). Para programas profissionais isso não é nada adequado.
Para promover um tratamento adequado a cada situação pode-se identificar a classe da exceção na
cláusula except conforme mostrado no exemplo 6.4. Nesse exemplo foram usados dois excepts nomeados
e um genérico. Quando ocorre um erro o interpretador Python primeiro procura a existência de um except
nomeado e se encontrar desvia a execução para ele; caso contrário ele executa o except genérico (não
nomeado). Só pode haver um except genérico.
Exemplo 6.4
try:
A = int(input('Digite A: '))
B = int(input('Digite B: '))
R = A / B
print(f'Resultado = {R}')
except ZeroDivisionError: # except nomeado
print('B não pode ser zero')
except ValueError: # except nomeado
print('Digite números inteiros para A e B')
except: # except genérico (não-nomeado)
print('Não é possível calcular a divisão. Erro desconhecido')
primeira execução
Digite A: 20
Digite B: 0
B não pode ser zero
segunda execução
Digite A: texto
Digite números inteiros para A e B
terceira execução
Digite A: 18
Digite B: 4
Resultado = 4.5
Na primeira execução do exemplo 6.4 foi fornecido 0 para B, ocorreu o erro e a execução desviou para
o except ZeroDivisionError . Na segunda execução foi fornecido um texto na leitura de A, ocorreu o
erro e a execução desviou para o except ValueError . Na terceira execução foram fornecidos valores
adequados para A e B e não ocorreu nenhum erro.
Quando o bloco 1 é executado ele está protegido. Supondo que nenhum erro ocorra, imediatamente
após seu término é feita a execução do bloco 3 que está no else. Se alguma exceção ocorrer o código de
tratamento no except é executado e o código do else não é executado.
A outra parte opcional finally sempre é executada, ocorra erro ou não. Se uma cláusula finally
estiver presente, ela será executada como a última tarefa antes da conclusão da instrução try. Se ambos,
else e finally, estiverem presentes o else será executado antes do finally.
Capítulo 7
OBJETOS COMPOSTOS DE PYTHON – OBJETOS SEQUENCIAIS
Os objetos compostos da linguagem Python constituem recursos muito valiosos aos programadores.
Permitem capacidade de processamento de grandes volumes de dados, com eficiência, confiabilidade e
flexibilidade. São elementos fundamentais que você, estudante, deve se dedicar a aprender.
Estes objetos compostos também são chamados de objetos estruturados pois seu conteúdo é
formado por elementos que podem ser acessados individualmente e também em grupo.
No universo de objetos estruturados de Python há três que são conhecidos como Objetos Sequenciais:
A principal característica dos tipos sequenciais é que seus elementos são mantidos em uma
organização baseada em um índice numérico crescente da esquerda para a direita, que começa em zero e
sofre o incremento de um a um. Com isso, é possível ao programador acessar individualmente seus
elementos através do uso de índices especificados entre colchetes: [ ].
Vamos abordar primeiro a classe list, que é um dos elementos mais importantes de Python.
A classe list é uma sequência. Listas são usadas para armazenar objetos de qualquer classe.
Observe a figura 7.1 e o exemplo 7.1.
fonte: o Autor
Na figura 7.1 nós temos uma representação gráfica do que seria uma lista em Python: um grupo de
objetos reunidos em um mesmo identificador (nome) e que podem ser acessados individualmente através
de um índice numérico. Esse índice é representado pelos números de 0 a 9 na parte de baixo da imagem. Os
números dentro das caixas representam o conteúdo de cada objeto da lista.
Exemplo 7.1
L = [36, 25, 21, 48, 17, 9, 16, 23, 29, 31]
print('Exibição da lista completa')
print(L)
print('\nExibição dos elementos individuais')
i = 0
while i < len(L):
print(L[i], end=' ')
i = i + 1
print('\nFim do Programa')
Exibição da lista completa
[36, 25, 21, 48, 17, 9, 16, 23, 29, 31]
Em um programa Python poderíamos fazer essa lista da forma mostrada no exemplo 7.1, onde a lista L
é pré-carregada com os valores da figura 7.1 e em seguida exibida de duas formas:
Vamos explorar um pouco mais usando o ambiente Idle para interagir com a lista. No exemplo 7.2
criamos a lista com 10 elementos; exibimos o tipo de L; exibimos individualmente alguns elementos usando
o índice; exibimos o tamanho da lista com o uso da função len(); alteramos o primeiro valor da lista; e por
fim exibimos a lista como um todo para conferir se a alteração do primeiro item de fato ocorreu.
Exemplo 7.2
>>> L = [36, 25, 21, 48, 17, 9, 16, 23, 29, 31]
>>> type(L) # exibição da classe de L
<class 'list'>
>>> L[0] # exibição do primeiro elemento -> L[0]
36
>>> type(L[0]) # exibição da classe do primeiro elemento
<class 'int'>
>>> L[9] # exibição do último elemento -> L[9]
31
>>> len(L) # a função len() retorna o tamanho da lista
10
>>> L[0] = 999 # alteração do primeiro elemento da lista
>>> print(L)
[999, 25, 21, 48, 17, 9, 16, 23, 29, 31]
(exemplo interativo feito com IDE Idle)
Nesta lista todos os elementos são da classe in t, de modo que dizemos que essa é uma lista
homogênea. Nada nos impede de criarmos listas com objetos de diferentes classes.
É comum que todos os elementos da lista sejam da mesma classe e quando isso ocorre dizemos que
a lista é homogênea. Porém isso não é obrigatório, ou seja, uma lista pode conter elementos classes
diferentes e aí dizemos que a lista é heterogênea.
Em Python é possível fazer a indexação com números negativos, que permitirá o acesso aos elementos
de trás para frente, sendo que o índice -1 se refere aos últimos objeto da lista.
O Ptyhon não permite indexação fora dos limites. Se houver a tentativa de usar um índice de elemento
(positivos ou negativos) que não existe uma exceção IndexError será gerada.
No exemplo 7.8 a lista Origem tem 10 elementos e é feito o fatiamento [3:6] de modo que os
elementos das posições 3, 4 e 5 serão incluídos na lista Destino1. O elemento da posição 6 ficará de fora –
esteja sempre atento a isso.
Neste caso o terceiro parâmetro é o passo, que será usado como um "pulo" entre elementos
sucessivos. No segundo caso do exemplo foi usado o fatiamento [1:7:2] que resulta em seleção dos
elementos das posições 1, 3 e 5, ou seja [25, 48, 9]. Por padrão o passo é 1 quando não especificado.
Exemplo 7.8
>>> Origem = [36, 25, 21, 48, 17, 9, 16, 23, 29, 31]
>>> Destino1 = Origem[3:6] # primeiro caso
>>> print(Destino)
[48, 17, 9]
>>> Destino2 = Origem[1:7:2] # segundo caso – incluindo o passo
>>> print(Destino2)
[25, 48, 9]
>>> Destino3 = Origem[:4] # terceiro caso – omitindo ini
>>> print(Destino3)
[36, 25, 21, 48]
>>> Destino4 = Origem[6:] # quarto caso – omitindo fim
>>> print(Destino4)
[16, 23, 29, 31]
(exemplo interativo feito com IDE Idle)
Exemplo 7.9
>>> A = [10, 12, 14, 16]
>>> B = A
>>> id(A)
1837485118208
>>> id(B)
1837485118208
>>> B[0] = 99
>>> print(B)
[99, 12, 14, 16]
>>> print(A)
[99, 12, 14, 16]
(exemplo interativo feito com IDE Idle)
Isso acontece porque a classe list de Python é mutável. Retorne à figura 2.2 e releia a seção 2.3 sobre
o Modelo de Dados de Python para relembrar os conceitos de classe imutável e classe mutável.
Quando fizemos B = A neste exemplo o que o Python fez foi criar o objeto B em memória e copiar o id
de A para B. Com isso, na prática, só existe uma lista em memória e os dois objetos, A e B, apontam para ela.
Por consequência qualquer alteração de dados que for feita em B também refletirá em A e vice-versa. No
exemplo alteramos o primeiro elemento de B para 99 e mostramos que A também ficou alterado.
Para quem está aprendendo Python isso pode ser estranho e incômodo no início, então fique atento e
não caia nessa armadilha. Agora a pergunta: se não dá para fazer B = A, como fazer então?
A resposta é simples: use o fatiamento para copiar todos os elementos para uma nova lista, assim:
Nessa nova versão do exemplo 7.9 foi usado o fatiamento no formato Destino = Origem[:] que
faz com que a lista Destino seja uma cópia integral e com id próprio da lista Origem.
Aviso e Dica
O aviso: cuidado com cópias de listas em seus programas.
Se elas forem pequenas, certamente não haverá problemas.
Porém, se suas listas forem grandes, com muitos de milhares de elementos,
fazer cópias e mais cópias pode levar a uma
lentidão indesejada na execução do seu programa.
Assim, a dica é: só faça cópia de uma lista muito grande quando isso for
absolutamente necessário e saiba que isso é necessário em poucas ocasiões.
Pense a respeito...
Observação:
1. Cuidado ao usar o método .sort() com listas heterogêneas. Se o
interpretador Python não conseguir definir a forma de ordenação
entre os vários elementos ele irá falhar.
Exemplo 7.10
Este exemplo é muito longo, pois mostra os métodos da classe list.
Então seu código não foi colocado aqui. O vídeo está disponível.
7.2.7 OPERADOR in
O operador in permite ao programador verificar se um valor está presente em uma lista.
Alternativamente pode-se usá-lo na forma not in para verificar se um valor não está na lista.
Este é um operador de uso geral em Python. Portanto, seu uso não é restrito às listas, podendo ser
usado com a maioria das classes de objetos compostos. O Exemplo 7.2 ilustra seu uso com uma lista.
Agora vamos fazer um exercício completo usando uma lista. Veja o exercício resolvido 7.1
Nesta solução a lista Termos é inicialmente criada contendo o primeiro termo. A cada repetição do laço
while um novo termo é calculado e acrescentado na lista. Para que a lista termine com a quantidade correta
Q de termos é preciso tomar um cuidado. Como o primeiro termo é pré-colocado na lista fora do laço, na
condição usada no while foi preciso descontar 1 de Q. Se isso não fosse feito a lista ficaria no final com um
termo a mais do que foi pedido.
Não-Pythônico e Pythônico
O importante é você saber que isso existe e também saber que os códigos
que foram apresentados até o momento seriam considerados Não-Pythônicos
por programadores experientes na linguagem.
Com certeza, um programador Python diria que o exercício resolvido 7.1 é
totalmente Não-Pythônico.
Já mencionada no quadro 2.2 a classe range existe para produzir um objeto imutável que é uma
sequência de números inteiros. Ela tem grande importância na implementação de vários tipos de algoritmos
e seu uso é muito simples. Sua forma geral é esta:
range(start, stop[, step])
A sequência começará com o valor start e terminará com o valor stop – 1. Assim como no fatiamento,
o valor final nunca é incluído. Se o objeto step for fornecido seu valor será usado como passo para construção
da sequência. Lembre-se sempre desses detalhes:
Alguns exemplos:
range(10) gera a sequência [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
range(3, 8) gera a sequência [3, 4, 5, 6, 7]
range(5, 12, 3) gera a sequência [5, 8, 11]
Não-Pythônico e Pythônico
Neste exercício temos o mesmo enunciado do exercício resolvido 7.1, porém a solução é diferente.
Nela foi usada classe range para gerar a PA. Note que para usar range precisamos saber o último termo da
PA desejada. Assim foi calculado:
ultimo = P + R * (Q-1)
Essa fórmula é decorrente da matemática, não exatamente um assunto de programação de
computadores. Precisamos desse último termo se quisermos usar range, então fomos buscar na
matemática a forma de calculá-lo. Isso ocorre sempre em programação. Muitas vezes precisamos de
informações especializadas da área de conhecimento para a qual estamos escrevendo o programa.
No que diz respeito ao uso do range, o código usado requer duas explicações.
Termos = list(range(P, ultimo+1, R))
Primeiro, note que no parâmetro stop foi usado ultimo+1. Isso é necessário pois o stop nunca está
incluído na sequência gerada, então para garantir a inclusão do ultimo precisamos estabelecer último+1
como stop do range.
Segundo, note que a classe range foi colocada dentro da função de conversão list:
... list(range(...))
Essa conversão da classe range para a classe list é necessária para que possamos ver os valores
da sequência na tela. Se não for feita vamos o que está a seguir:
Termos = range(P, ultimo+1, R) # sem usar list()
print(Termos)
range(7, 52, 4) # é isso que vamos ter na tela
O comando for é usado para iterar sobre os elementos de qualquer objeto estruturado de Python, tais
como: listas, strings, tuplas, dicionários, conjuntos, etc.
Iterar e Iteração
Acostume-se com esses termos.
Iterar é
percorrer os elementos de uma sequência,
na ordem em que eles estão dentro dela e
realizar um processamento com cada um.
Veja seu uso no exemplo 7.12. Neste exemplo uma lista com 4 números inteiros é criada e em seguida
o comando for é usado para iterar sobre ela. Para tornar a iteração possível o objeto valor tem papel
preponderante. Ele recebe cada elemento contido na lista L, um por vez, ou seja, um objeto de L a cada
repetição. E dentro do laço valor pode ser usado normalmente para qualquer fim que o programador
necessite.
Exemplo 7.12
L = [21, 45, 17, 28]
pos = 0
for valor in L:
print(f'A posição {pos} contém {valor}')
pos += 1
print('Fim do Programa')
A posição 0 contém 21
A posição 1 contém 45
A posição 2 contém 17
A posição 3 contém 28
Fim do Programa
Os comandos continue e break, vistos quando falamos do comando while, também se aplicam
ao comando for. Veja as seções 5.3.1 e 5.2.2 para relembrar sobre eles.
Recomendação:
Sempre que possível use um laço for.
Por quê?
Não haverá necessidade de usar objetos extras para controle do laço.
Seu código ficará mais compacto.
Seu código ficará mais legível.
Neste exemplo são definidas duas listas A e B, e em seguida foi usado o operador "+" para juntar as
duas listas. Assim, no contexto de classes sequenciais o operador "+" é denominado "operador de
concatenação".
O operador de multiplicação "*" serve para criar sequências com múltiplas cópias de uma
subsequência. Ele é particularmente útil nas situações em que precisamos de uma lista com uma certa
quantidade pré-definida de elementos e carregados com um determinado valor inicial.
Resultado:
3.1
19.8
7.35
12.4
Fim do Programa
Nesta solução 7.3 o comando for foi usado duas vezes. Na primeira, em combinação com a classe
range, são lidos vários valores de entrada e cada um é adicionado à lista L. Terminada a fase de aquisição
dos dados é feita a exibição com o segundo comando for.
Fim do Programa
Resultado
[138, -79, -14, 63, -49, 41]
A lista contém 6 elementos
Fim do Programa
Perceba que nesta solução foi usado o comando while ao invés do for. O motivo é o fato de que não
sabemos quantas vezes o laço irá se repetir. Como o enunciado impõe que o laço só termina quando o dado
de entrada for 0 (zero), a permanência das repetições depende daquilo que o usuário digita. Este é um
exemplo de situação em que não é possível usar o comando for.
Outra restrição do enunciado é: "cada valor diferente de zero deve ser colocado em uma lista", ou seja,
o zero não pode entrar na lista. Para lidar com esta restrição foi usada a técnica de "aquisição do dado na
saída do laço". Isso é um aspecto de lógica que se aplica a qualquer linguagem. Para implementar essa
técnica fazemos a leitura do primeiro dado antes do laço começar; dentro do laço o primeiro dado é
processado e a última tarefa dentro do laço é ler o próximo dado – se esse dado lido for zero o laço termina,
mas se não for o laço continua e já podemos processar o novo dado. A alternativa a isso seria o código abaixo:
valor = 1
while valor != 0:
valor = int(input('Digite um inteiro: '))
if valor != 0:
LstValores.append(valor)
Nesta alternativa temos que garantir que o laço inicie, para isso fizemos valor = 1 e dentro do laço
temos que acrescentar um if para garantir que o zero não entre na lista.
Resultado
[23, 14, 19]
A lista contém 3 elementos
Fim do Programa
Neste problema queremos criar uma lista sem valores repetidos. Para implementar a solução é preciso
acrescentar uma verificação dentro do laço usando o operador not in, conforme mostrado acima. Se o
valor não está na lista é acrescentado e se já está a mensagem de erro é exibida.
Digite X: 9
há 1 ocorrência(s) de 9 na lista
Digite X: 20
há 4 ocorrência(s) de 20 na lista
Digite X: 3
3 não está na lista
Digite X: 12
há 2 ocorrência(s) de 12 na lista
Digite X: 0
0 não está na lista
Fim do Programa
Esta solução tem duas partes. Na primeira é feita a geração e a exibição da lista. Como o enunciado
fala em gerar números inteiros aleatórios, foi usada a função randint() que pertence ao módulo Random,
que faz parte da instalação padrão de Python. Os valores foram gerados na faixa de 1 a 20 quando escrevemos
a = randint(1, 20), mas você pode mudar esses limites e ver como fica a geração da lista.
Lembrando:
A existência de módulos (foi usado o termo "bibliotecas") foi mencionada
no capítulo 1 e sua importação já foi exemplificada no exemplo 2.10
Na segunda parte foi usado o operador in para saber se o valor de X está na lista e foi usado o método
.count() para saber a quantidade de ocorrências.
Simplificando um pouco pode-se pensar na tupla como sendo uma lista "só para leitura".
Elas são usadas em situações em que queremos armazenar um número fixo de itens que não serão
alterados. Alguns exemplos de situações em que tuplas são usadas:
A principal característica que nos leva a considerar o uso de tuplas nos nossos programas são o fato de
que elas consomem quantidades relativamente pequenas de memória em comparação com as listas.
O exemplo 7.16 mostra como uma tupla é criada. Podemos usar dois formatos, com os dados entre
parênteses, com no caso das tuplas T e V; ou sem os parênteses como no caso da tupla U.
Este exemplo também mostra que tuplas podem ser heterogêneas (T e U) ou homogêneas (V).
Também é mostrado que se pode acessar cada elemento individualmente usando o índice, bem como
usar a tupla em uma iteração com o comando for.
O quadro 7.3 mostra como essa classe é leve, quando comparada à classe list (ver quadro 7.2 em
comparação). Ela contém apenas dois métodos e ambos são relacionados ao acesso aos seus elementos e
por consequência quando usada consome menos bytes da memória do computador.
Por fim, tuplas e listas são totalmente intercambiáveis, ou seja, é possível realizar conversões entre
objetos dessas duas classes. Veja o exemplo a seguir:
Neste exemplo convertemos a tupla T para lista, alteramos um de seus valores e retornamos de lista
para tupla. Isso é algo que sempre pode ser feito em nossos programas, se for necessário, mas antes de se
sentir tentado a fazê-lo pense se é mesmo necessário.
Fazemos esse aviso porque, se muitas conversões entre tuplas e listas precisarem ser feitas, considere
usar uma lista de uma vez por todas e não gastar processamento com as conversões em si.
O exemplo 7.18 ilustra o uso do método .isnumeric() para validar uma entrada via teclado. É uma
forma de evitar erros de digitação de números inteiros.
segunda execução
Digite um número inteiro: 13abc9
Erro: digite apenas números
O exemplo 7.19 ilustra uma situação muito comum, em que vários valores são digitados em uma única
linha, devem ser lidos e separados. A ideia é que o usuário possa digitar algo assim:
Digite dois inteiros e um real: 53 18 37.9
Após a leitura queremos que o valor 53 esteja em um objeto A, o 18 esteja em B e o 37.9 esteja em X. A
solução para isso está neste exemplo:
Adiante neste curso teremos vários usos para objetos da classe str e seus métodos. À medida que
precisarmos de algo que ainda não foi abordado faremos uma explicação específica e demonstração de uso.
Neste exemplo usamos o método .split() para separar o string, usando o caractere espaço em
branco como critério de separação. Como resultado obtemos uma lista onde cada elemento é também um
string. Em seguida cada um é convertido para número inteiro e exibido na tela. No final a soma dos elementos
da lista é calculada e também exibida.