Prévia do material em texto
Autor: Prof. Tarcísio de Souza Peres
Colaboradores: Prof. Angel Antonio Gonzalez Martinez
Profa. Christiane Mazur Doi
Pensamento Lógico
Computacional com Python
© Todos os direitos reservados. Nenhuma parte desta obra pode ser reproduzida ou transmitida por qualquer forma e/ou
quaisquer meios (eletrônico, incluindo fotocópia e gravação) ou arquivada em qualquer sistema ou banco de dados sem
permissão escrita da Universidade Paulista.
Dados Internacionais de Catalogação na Publicação (CIP)
P437p Peres, Tarcísio de Souza.
Pensamento Lógico Computacional com Python / Tarcísio de
Souza Peres. – São Paulo: Editora Sol, 2025.
252 p., il.
Nota: este volume está publicado nos Cadernos de Estudos e
Pesquisas da UNIP, Série Didática, ISSN 1517-9230.
1. Python. 2. Dados. 3. PPO. I. Título.
CDU 681.3.019
U521.28 – 25
Professor conteudista: Tarcísio de Souza Peres
Graduado em Gestão de Projetos pela FIA/USP e em Gestão Estratégica e Competitividade pela Fundação Dom
Cabral. Tem MBA em Gestão de TI pela Fiap. Também é graduado e mestre em Engenharia da Computação pela
Unicamp. Atuou como pesquisador no Human Cancer Genome Project. Com perfil multidisciplinar, tem experiência nas
áreas de tecnologia, saúde, governança, novos negócios e inovação. Trabalhou em multinacionais e órgãos públicos.
É certificado pelo PMI, Cobit e autor de obra sobre mercado financeiro, além de livros de programação orientada
a objetos básica e avançada em C#, desenvolvimento de software para internet com ASP.net, gestão de projetos e
engenharia de requisitos. Atua como empreendedor (startups de inovação em tecnologia) e como professor na UNIP,
na cFGV e no CPS.
Prof. João Carlos Di Genio
Fundador
Profa. Sandra Rejane Gomes Miessa
Reitora
Profa. Dra. Marilia Ancona Lopez
Vice-Reitora de Graduação
Profa. Dra. Marina Ancona Lopez Soligo
Vice-Reitora de Pós-Graduação e Pesquisa
Profa. Dra. Claudia Meucci Andreatini
Vice-Reitora de Administração e Finanças
Profa. M. Marisa Regina Paixão
Vice-Reitora de Extensão
Prof. Fábio Romeu de Carvalho
Vice-Reitor de Planejamento
Prof. Marcus Vinícius Mathias
Vice-Reitor das Unidades Universitárias
Profa. Silvia Renata Gomes Miessa
Vice-Reitora de Recursos Humanos e de Pessoal
Profa. Laura Ancona Lee
Vice-Reitora de Relações Internacionais
Profa. Melânia Dalla Torre
Vice-Reitora de Assuntos da Comunidade Universitária
UNIP EaD
Profa. Elisabete Brihy
Profa. M. Isabel Cristina Satie Yoshida Tonetto
Material Didático
Comissão editorial:
Profa. Dra. Christiane Mazur Doi
Profa. Dra. Ronilda Ribeiro
Apoio:
Profa. Cláudia Regina Baptista
Profa. M. Deise Alcantara Carreiro
Profa. Ana Paula Tôrres de Novaes Menezes
Projeto gráfico: Revisão:
Prof. Alexandre Ponzetto Vitor Andrade
Lucas Ricardi
Sumário
Pensamento Lógico Computacional com Python
APRESENTAÇÃO ......................................................................................................................................................7
INTRODUÇÃO ........................................................................................................................................................ 10
Unidade I
1 INTRODUÇÃO À LÓGICA DE PROGRAMAÇÃO E PYTHON ................................................................ 13
1.1 Conceitos de lógica, algoritmos, pseudocódigo e fluxogramas ........................................ 14
1.2 Introdução à linguagem Python .................................................................................................... 27
2 ESTRUTURAS DE CONTROLE ....................................................................................................................... 44
2.1 Estruturas de decisão (if, else, elif) ................................................................................................ 48
2.2 Estruturas de repetição (for, while) ............................................................................................... 60
Unidade II
3 TIPOS DE DADOS E VARIÁVEIS ................................................................................................................... 77
3.1 Tipos numéricos e strings ................................................................................................................. 78
3.2 Variáveis e operadores em Python ................................................................................................ 99
4 FUNÇÕES EM PYTHON ................................................................................................................................115
4.1 Criação e chamada de funções.....................................................................................................116
4.2 Passagem de parâmetros e retorno ............................................................................................127
Unidade III
5 MANIPULAÇÃO DE LISTAS E DICIONÁRIOS .........................................................................................146
5.1 Listas: operações e métodos ..........................................................................................................147
5.2 Dicionários: criação e uso ...............................................................................................................157
6 ENTRADA E SAÍDA DE DADOS ..................................................................................................................174
6.1 Leitura de dados do teclado ...........................................................................................................175
6.2 Escrita de dados em arquivos ........................................................................................................189
Unidade IV
7 DEPURAÇÃO E TESTE DE ALGORITMOS ................................................................................................209
7.1 Técnicas de depuração em Python ..............................................................................................210
7.2 Testes automatizados simples .......................................................................................................217
8 INTRODUÇÃO À PROGRAMAÇÃO ORIENTADA A OBJETOS (POO) EM PYTHON ....................227
8.1 Classes e objetos .................................................................................................................................228
8.2 Métodos e encapsulamento ...........................................................................................................236
7
APRESENTAÇÃO
No mundo contemporâneo, a tecnologia está intrinsecamente ligada a praticamente todos os
aspectos da vida humana. Desde a maneira como nos comunicamos até a forma como conduzimos
negócios, a influência da computação é inegável. Nesse contexto, esta disciplina é uma ferramenta
essencial para capacitar indivíduos a navegar e contribuir efetivamente nesse ambiente digital.
O pensamento computacional é uma habilidade cognitiva que envolve a resolução de problemas
de maneira estruturada e eficiente. Segundo Wing (2006), o pensamento computacional engloba
a resolução de problemas, o design de sistemas e a compreensão do comportamento humano,
baseando-se nos conceitos fundamentais da ciência da computação. Essa habilidade permite que as
pessoas decomponham problemas complexos em partes menores e mais manejáveis, tornando a solução
mais acessível.
Para que esse pensamento seja efetivamente aplicado e testado, é necessário expressá-lo por
meio de uma linguagem que o computador possa compreender. Essa necessidade surge porque os
computadores operam com base em instruções precisas e sequências definidas de comandos, os quais
são fornecidos através de linguagens de programação.
Uma linguagem de programação serve como intermediária entre o ser humano e a máquina,
permitindo que ideias e soluções abstratas sejam traduzidas em códigos executáveis. Sem essa tradução,
o pensamento computacional permaneceria no âmbito teórico, sem possibilidade de implementação
prática. Portanto, utilizarnão é apenas recomendada, mas obrigatória para que o código
funcione adequadamente.
Uma das principais vantagens de Python é sua vasta biblioteca padrão e a disponibilidade de inúmeras
bibliotecas de terceiros. Essas bibliotecas cobrem uma ampla gama de áreas, incluindo manipulação
de arquivos, redes, desenvolvimento web, interfaces gráficas, ciência de dados, aprendizado de
máquina, entre outras. Essa riqueza de recursos permite que os programadores desenvolvam aplicações
complexas sem precisar escrever o código do zero para funcionalidades comuns, agilizando o processo
de desenvolvimento.
Python é uma linguagem multiplataforma, o que significa que os programas escritos em Python
podem ser executados em diferentes sistemas operacionais, como Windows, macOS e Linux, sem
modificações significativas. Isso aumenta a portabilidade das aplicações e facilita a colaboração entre
desenvolvedores que utilizam ambientes diferentes. Além disso, Python é uma linguagem de código
aberto, com uma comunidade ativa que contribui para seu desenvolvimento contínuo.
34
Unidade I
A linguagem tem recursos avançados, como gerenciamento automático de memória e coleta de lixo,
que simplificam a gestão de recursos e reduzem a probabilidade de erros comuns, como vazamentos de
memória. Além disso, o tratamento de exceções em Python é direto, permitindo que os programadores
lidem com erros e situações inesperadas de maneira elegante.
Observação
Em computação, o termo elegante refere-se à ideia de uma solução que
é clara, eficiente e intuitiva. No contexto do tratamento de exceções em
Python, elegante implica que o processo de lidar com erros e situações
inesperadas é realizado de forma organizada e compreensível, evitando
complexidade desnecessária e facilitando a manutenção do código.
No âmbito da ciência de dados e IA, Python é amplamente utilizada devido à robustez de suas
bibliotecas especializadas. Bibliotecas como NumPy e Pandas facilitam a manipulação e análise de
grandes conjuntos de dados, enquanto Matplotlib e Seaborn permitem a criação de visualizações gráficas
complexas. Para aprendizado de máquina e redes neurais, bibliotecas como Scikit-learn, TensorFlow e
PyTorch fornecem ferramentas poderosas para a construção e o treinamento de modelos avançados.
Saiba mais
O livro acentuado a seguir é uma excelente referência para quem quer
entender como utilizar a linguagem Python na ciência de dados:
GRUS, J. Data Science do zero: noções fundamentais com Python. 2. ed.
São Paulo: Alta Books, 2021.
Outra referência interessante é o livro de McKinney, que é um manual
para manipulação, processamento, limpeza e extração de informações de
conjuntos de dados em Python:
MCKINNEY, W. Python para análise de dados: tratamento de dados com
Pandas, NumPy & Jupyter. 3. ed. São Paulo: Novatec, 2023.
Por fim, o livro de Aurélien Géron tem exercícios práticos para aprendizado
de Python em IA:
GÉRON, A. Mãos à obra: aprendizado de máquina com Scikit-Learn,
Keras & TensorFlow – conceitos, ferramentas e técnicas para a construção de
sistemas inteligentes. 2. ed. São Paulo: Alta Books, 2021.
35
PENSAMENTO LÓGICO COMPUTACIONAL COM PYTHON
Uma biblioteca em Python (ou em qualquer linguagem de programação) é um conjunto de código
pré-escrito que fornece funcionalidades específicas para resolver problemas ou executar tarefas comuns.
Essas bibliotecas são criadas para facilitar o trabalho dos programadores, permitindo que eles reutilizem
soluções prontas em vez de escreverem tudo do zero.
As bibliotecas geralmente incluem funções, classes e métodos organizados para realizar operações
relacionadas a um domínio específico, como manipulação de dados, aprendizado de máquina, visualização
gráfica ou processamento de imagens. Elas são como “caixas de ferramentas” que oferecem soluções já
otimizadas e testadas por outros desenvolvedores.
No desenvolvimento web, Python também se destaca com frameworks como Django e Flask.
O primeiro é um framework de alto nível que promove o desenvolvimento rápido e limpo de aplicações
web, seguindo o princípio DRY (Don’t Repeat Yourself). Ele fornece uma estrutura completa para o
desenvolvimento, incluindo gerenciamento de banco de dados, autenticação de usuários e administração.
Flask, por outro lado, é um microframework mais leve, que oferece maior flexibilidade para projetos
menores ou que requerem customização específica.
Um framework é como um kit de ferramentas pré-fabricado que ajuda os desenvolvedores a criar
softwares ou aplicações de forma mais fácil e eficiente. Imagine que você vai construir uma casa: em
vez de começar do zero, criando cada tijolo e peça de madeira, você utiliza uma estrutura pré-moldada
já existente que fornece a base e o esqueleto da casa. Assim, você pode se concentrar nos detalhes que
realmente importam para você, como a decoração e o layout dos cômodos.
No mundo da programação, um framework oferece uma base pronta com componentes e códigos já
desenvolvidos para tarefas comuns, como conectar-se a um banco de dados, gerenciar usuários ou criar
interfaces visuais. Isso significa que os programadores não precisam escrever tudo do zero cada vez que
criam uma nova aplicação. Em vez disso, eles usam essa estrutura pronta e personalizam conforme as
necessidades do projeto.
Para começar a programar em Python, é importante instalar o interpretador da linguagem, disponível
gratuitamente no site oficial do Python (https://www.python.org/). Existem também diversos ambientes
de desenvolvimento integrados (IDEs) que facilitam a escrita e depuração de código, como o PyCharm,
Visual Studio Code, Spyder e Jupyter Notebook. O uso de um IDE pode melhorar significativamente a
experiência de programação, oferecendo recursos como destaque de sintaxe, autocompletar, depurador
integrado e gerenciamento de projetos. Caso você tenha alguma limitação de ambiente, é possível
também editar e executar códigos Python em plataformas online, que não demandam nenhum tipo de
instalação. Essa opção é útil para programas mais simples, por isso começaremos por ela.
A prática desempenha um papel vital no processo de aprendizado de Python, sendo uma das
habilidades mais importantes para quem deseja dominar essa linguagem de programação. Embora a
teoria seja essencial para compreender os fundamentos, é por meio da prática que o conhecimento se
consolida e se torna aplicável em situações reais. A programação, em geral, é uma habilidade prática, e
Python, com sua sintaxe acessível e versatilidade, oferece um excelente ambiente para experimentação
e aprendizado ativo.
36
Unidade I
Para ajudar na prática, vamos propor diversos exercícios com a seguinte temática pedagógica:
viagens no tempo. Imagine ter a possibilidade de viajar através das eras, testemunhar eventos históricos
marcantes e até mesmo interagir com personagens que moldaram o mundo como o conhecemos.
Desde os primórdios da humanidade, o tempo sempre intrigou filósofos, cientistas e sonhadores.
A ideia de mover-se livremente entre passado, presente e futuro alimenta nossa curiosidade e desperta
inúmeras possibilidades. Agora, com as ferramentas da programação, você terá a oportunidade de
criar suas próprias viagens temporais, simulando cenários, explorando eventos e compreendendo as
complexidades que envolvem alterar o curso da história.
Ao longo deste livro-texto, cada conceito de Python que você aprender será um passo adiante na
construção de sua própria máquina do tempo virtual. Iniciaremos com os fundamentos da linguagem,
quando você aprenderá a comunicar-se com o computador e dar os primeiros comandos para configurar
sua jornada temporal. Conforme avançamos, estruturas de controle como decisões e repetições serão
as engrenagens que permitirão navegar por diferentes épocas e lidar com os desafios que cada
uma apresenta.
Você descobrirá como armazenar e manipular informações cruciais para suas viagens, utilizando
variáveis e tipos de dados. Funções serão suasaliadas na hora de modularizar tarefas e tornar suas
expedições mais eficientes. Com listas e dicionários, será possível gerenciar um inventário de artefatos
históricos, registrar encontros com figuras ilustres e mapear linhas temporais alternativas.
A interação com o usuário e a capacidade de salvar registros de suas aventuras serão exploradas por
meio da entrada e saída de dados. Imagine poder criar um diário de bordo detalhado, documentando
cada salto temporal e suas consequências. Além disso, refletiremos sobre os paradoxos e as implicações
éticas de interferir em eventos passados, promovendo o aprendizado técnico e uma compreensão mais
profunda sobre responsabilidade e causalidade.
Ajuste os controles de sua máquina do tempo, verifique os parâmetros de destino e esteja pronto
para desvendar os mistérios que o tempo reserva. O passado, o presente e o futuro estão ao alcance dos
seus códigos.
Imagine que, em um dia comum, você presencia algo extraordinário: uma figura misteriosa aparece
do nada em um brilho ofuscante, trajando roupas futurísticas e carregando uma pequena máquina
reluzente. Esse é um viajante do tempo que veio de um futuro distante para explorar nossa época
e compartilhar sua missão. Agora, como programadores iniciantes, nosso desafio é ajudá-lo a se
apresentar ao mundo atual. Para isso, utilizaremos a função print() em Python, responsável por
exibir mensagens na tela:
# Exibindo a mensagem do viajante do tempo
print(“Olá, humanos do século XXI!”)
print(“Meu nome é Chronos e venho do ano 3023.”)
print(“Minha missão é estudar como a tecnologia moldou o mundo ao longo dos
séculos.”)
37
PENSAMENTO LÓGICO COMPUTACIONAL COM PYTHON
Esse código-fonte precisa ser digitado em uma IDE com o interpretador Python, como falamos
anteriormente. Para simplificar, inicialmente vamos usar interpretadores disponíveis online, que
executam diretamente pelo navegador web (Chrome, Edge, Safari etc.), sem a necessidade de
instalações prévias. As figuras a seguir ilustram três exemplos de interpretadores online. Você pode
escolher um deles ou usar outro similar. Eles têm layouts ligeiramente distintos, mas o mesmo perfil
de funcionalidade: um espaço para digitar o código Python, um botão Run para executar o código após
a digitação e um espaço para visualizar o resultado da execução.
Figura 8 – Interpretador Python online. Note que o código-fonte foi digitado na parte superior,
o botão Run aparece em verde no topo e o resultado da execução aparece na parte inferior
Figura 9 – Interpretador Python online. Note que o código-fonte foi digitado na parte superior, o botão
Run aparece em verde no centro à esquerda e o resultado da execução aparece na parte inferior
38
Unidade I
Figura 10 – Interpretador Python online. Note que o código-fonte foi digitado na parte esquerda,
o botão Run aparece em vermelho à direita (no topo) e o resultado da execução aparece à direita
Vamos analisar cada linha do código. Observe que adicionamos um comentário no início do código:
# Exibindo a mensagem do viajante do tempo. Em Python, comentários começam
com o símbolo # e são ignorados pelo interpretador. Eles servem para documentar o código, explicando
sua finalidade ou fornecendo instruções para quem estiver lendo. Vamos analisar as demais linhas:
• print(“Olá, humanos do século XXI!”): a função print() é uma das mais
básicas e essenciais em Python. Ela permite exibir mensagens ou informações na saída padrão,
geralmente a tela do computador. Nesse caso, estamos exibindo uma saudação inicial feita pelo
viajante do tempo. O texto entre aspas duplas (“) é chamado de string, que é um tipo de dado em
Python usado para representar sequências de caracteres. As aspas indicam o início e o fim da
string, e tudo o que estiver entre elas será exibido exatamente como está. Uma função é um bloco
de código reutilizável que realiza uma tarefa específica. Em Python, funções são identificadas por
um nome (como print) seguido de parênteses. Esses parênteses podem conter argumentos, que
são os dados que a função processará. A função print() é uma função embutida (ou seja, já vem
pronta na linguagem Python) e tem como tarefa exibir informações na tela. Ao evocá-la, você
fornece dentro dos parênteses o que deseja que seja exibido, como um texto, números ou até
resultados de cálculos.
• print(“Meu nome é Chronos e venho do ano 3023.”): utilizamos outra
chamada da função print(), reforçando que ela pode ser usada várias vezes em um programa
para exibir diferentes mensagens. O viajante se apresenta, mencionando seu nome e o ano de
onde veio. Mais uma vez, estamos adotando uma string para compor a mensagem que será
exibida na saída padrão. A saída padrão é o local para o qual o programa envia informações que
devem ser exibidas ao usuário. Em Python, a saída padrão é, por padrão, o console ou terminal
(a janela na qual o programa é executado). Quando chamamos print(), a mensagem especificada
nos parênteses é direcionada para a saída padrão. Se você executar esse código em um terminal
ou ambiente de desenvolvimento como o Jupyter Notebook, verá a mensagem aparecer na tela.
Se quisermos, podemos redirecionar a saída padrão para outros destinos, como arquivos, mas, por
ora, a saída padrão é o terminal (tela).
39
PENSAMENTO LÓGICO COMPUTACIONAL COM PYTHON
• print(“Minha missão é estudar como a tecnologia moldou o mundo
ao longo dos séculos.”): essa linha finaliza a apresentação, explicando a razão da
viagem temporal. O texto é mais longo, mas a função print() não tem limite para o tamanho
da string que pode ser exibida. É possível incluir quantos caracteres forem necessários, desde que
sejam delimitados pelas aspas.
Ao executar o código (Run), o console (saída padrão) exibirá o seguinte:
Olá, humanos do século XXI!
Meu nome é Chronos e venho do ano 3023.
Minha missão é estudar como a tecnologia moldou o mundo ao longo dos séculos.
Após o viajante do tempo se apresentar, ele inicia um diálogo mais interativo com uma pessoa do
presente. Esse diálogo não é fixo: será gerado dinamicamente com base em informações fornecidas
pelo usuário. O viajante do tempo pedirá o nome da pessoa e adaptará sua fala para criar uma
conversa personalizada. Com isso, vamos introduzir o conceito de entrada de dados pelo usuário
e armazenamento em variáveis, elementos essenciais para tornar programas mais interativos e
dinâmicos. Eis o código Python:
# Solicitar o nome da pessoa do presente
nome_pessoa = input(“Viajante do Tempo: Olá, humano do século XXI! Qual é o seu
nome? “)
# Resposta personalizada
print(f”Pessoa do Presente: Meu nome é {nome_pessoa}. Quem é você?”)
print(“Viajante do Tempo: Eu sou Chronos, vindo do ano 3023.”)
print(f”Viajante do Tempo: Prazer em conhecê‑lo, {nome_pessoa}. Minha missão é
estudar como a tecnologia moldou a humanidade.”)
A seguir utilizaremos esse código no interpretador online.
Figura 11 – Código Python com entrada de dados do usuário e armazenamento em variáveis
40
Unidade I
Note na parte inferior da figura anterior que, após a execução do código (botão Run), a mensagem
Viajante do Tempo: Olá, humano do século XXI! Qual é o seu nome? é
escrita na tela do console e o programa fica aguardando a digitação de um nome para dar continuidade
ao fluxo do programa.
Figura 12 – Execução do programa após a digitação do nome Emmett Lathrop Brown
Esse exercício apresenta dois conceitos novos e importantes: a função input() e o uso de variáveis
para personalizar o programa.
• nome_pessoa = input(“Viajante do Tempo: Olá, humano do século XXI!
Qual é o seu nome? “): a função input() é usada para coletar dados do usuário.
Aqui, estamos solicitando ao usuário que insira seu nome pelo console. A mensagem dentro
de input() será exibida no console como uma pergunta ou instrução. O valor digitado pelo
usuário é armazenado na variável nome_pessoa.
• print(f”Pessoa do Presente: Meu nome é {nome_pessoa}. Quem é
você?”): esse é um exemplo de f-strings, uma formamoderna e eficiente de formatar strings
em Python. Dentro de uma f-string (iniciada por f antes das aspas), podemos incluir variáveis ou
expressões diretamente no texto, usando chaves {}. Aqui, o nome fornecido pelo usuário em
nome_pessoa é integrado à fala da pessoa do presente, tornando o diálogo personalizado.
• print(“Viajante do Tempo: Eu sou Chronos, vindo do ano 3023.”):
essa é uma mensagem fixa, semelhante às do exercício anterior.
• print(f”Viajante do Tempo: Prazer em conhecê‑lo, {nome_pessoa}.
Minha missão é estudar como a tecnologia moldou a humanidade.”):
mais uma vez, utilizamos uma f-string para incluir o nome do usuário na fala do viajante,
reforçando a personalização do diálogo.
41
PENSAMENTO LÓGICO COMPUTACIONAL COM PYTHON
A função input() permite que o programa receba dados digitados pelo usuário. Isso torna o programa
interativo e dinâmico. O valor retornado por input() é sempre uma string, mesmo que o usuário insira
números. Se for necessário realizar operações matemáticas com a entrada, será preciso convertê-la para
um tipo numérico (como int ou float), algo que exploraremos em exercícios futuros.
A entrada padrão (standard input, ou apenas stdin) é um canal de comunicação que permite que um
programa receba dados fornecidos por quem está interagindo com ele, geralmente através do teclado.
Em Python, a função input() é usada para acessar a entrada padrão e capturar informações digitadas
pelo usuário. Quando você chama a função input() em Python, ela pausa a execução do programa e
aguarda que o usuário digite algo. Assim que o usuário pressiona a tecla Enter, o que foi digitado
é retornado como uma string para o programa.
Observação
No contexto de sistemas operacionais, a entrada padrão é um dos três
fluxos básicos gerenciados por quase todos os programas:
• entrada padrão (stdin): dados enviados para o programa, geralmente
digitados no teclado;
• saída padrão (stdout): dados exibidos pelo programa, normalmente
no console (tela);
• erro padrão (stderr): mensagens de erro exibidas pelo programa.
No tópico anterior, quando falamos de pseudocódigos, mencionamos que uma variável era uma
espécie de “caixa” para guardar valores. Agora podemos detalhar um pouco melhor. Uma variável é um
espaço na memória do computador usado para armazenar dados que podem ser reutilizados ou
modificados durante a execução do programa. Em Python, basta dar um nome à variável e usar o
operador de atribuição (=) para armazenar um valor nela. No código anterior, a variável nome_pessoa
armazena o nome fornecido pelo usuário.
Quando o código for executado, o programa perguntará o nome do usuário. Supondo que o usuário
insira “Dr. Emmett Lathrop Brown”, a saída será:
Viajante do Tempo: Olá, humano do século XXI! Qual é o seu nome?
Dr. Emmett Lathrop Brown
Pessoa do Presente: Meu nome é Dr. Emmett Lathrop Brown. Quem é você?
Viajante do Tempo: Eu sou Chronos, vindo do ano 3023.
Viajante do Tempo: Prazer em conhecê‑lo, Dr. Emmett Lathrop Brown. Minha missão
é estudar como a tecnologia moldou a humanidade.
42
Unidade I
O exemplo anterior mostra exatamente esse resultado na parte inferior da tela. A interação muda
conforme o nome inserido, permitindo diferentes experiências para cada execução. Você pode expandir
esse mesmo exercício alterando o código-fonte para:
• Experimentação com diferentes nomes: peça a outros colegas para inserir nomes diferentes e
observe como a personalização do diálogo afeta a experiência.
• Criação de novos diálogos: adicione mais interações (inputs) ao programa, como o viajante
perguntando sobre os interesses da pessoa ou oferecendo conselhos baseados no século XXI.
• Validação de entrada: teste o que acontece se o usuário não inserir um nome (apenas pressionar
Enter) ou digitar algo inesperado. Considere tratar essas situações em exercícios futuros.
O viajante do tempo, Chronos, decide compartilhar como conseguiu construir sua máquina do
tempo. Essa história deve ser exibida no console utilizando strings multilinha, um recurso essencial para
textos longos ou narrativas formatadas. Esse exercício introduz o uso de strings multilinha em Python,
que facilitam a escrita e a exibição de textos extensos com quebras de linha incorporadas.
Figura 13 – Utilização da string multilinha
43
PENSAMENTO LÓGICO COMPUTACIONAL COM PYTHON
O código da figura anterior utiliza strings multilinha para exibir a história completa do viajante
do tempo, permitindo a formatação de texto com quebras de linha incorporadas. Strings multilinha
em Python são delimitadas por três aspas duplas (“””) ou simples (‘’’). Elas permitem que o texto
contenha várias linhas sem a necessidade de concatená-las ou usar caracteres de quebra de linha
manualmente (\n). Todo o texto entre as três aspas é tratado como uma única string e será exibido
exatamente como foi escrito, incluindo quebras de linha e espaçamento. A string narra como o
viajante construiu sua máquina do tempo. Note que a quebra de linha no código será refletida
diretamente na saída exibida no console.
Strings multilinha são ideais para textos longos, narrativas ou documentos que exigem
formatação específica. Elas são mais legíveis e práticas do que concatenar várias strings pequenas.
Além disso, preservam formatação e espaçamento, facilitando a criação de textos organizados.
Elas também permitem a adição de variáveis dentro da string usando f-strings, como no exemplo
da figura a seguir:
Figura 14 – Utilização da string multilinha com variáveis e f-strings
As strings multilinha também permitem a inclusão de caracteres especiais, como \t (tabulação).
A figura 15 apresenta um exemplo.
44
Unidade I
Figura 15 – Utilização da string multilinha com inclusão de tabulação
2 ESTRUTURAS DE CONTROLE
As estruturas de controle em Python englobam todos os mecanismos que permitem gerenciar o
fluxo de execução de um programa. Essas estruturas podem ser divididas em três categorias principais:
estruturas de decisão, estruturas de repetição e mecanismos de controle de fluxo mais específicos.
A execução, em termos de programação, pode ser comparada ao momento em que um programa de
computador começa a realizar as ações ou instruções que foram escritas no código-fonte. Imagine
que um programa é como uma receita de bolo: a execução seria o ato de seguir a receita, passo a passo,
misturando os ingredientes e assando o bolo.
O fluxo de execução, por sua vez, é o caminho que o programa segue ao realizar essas ações. Assim
como em uma receita você pode encontrar instruções que dizem “se o bolo ainda não estiver dourado,
deixe mais cinco minutos no forno”, em um programa de computador há instruções que determinam
como ele deve agir em diferentes situações. Essas instruções podem incluir decisões (como “se isso
acontecer, faça aquilo”), repetições (como “repita essa ação até alcançar certo resultado”) e sequências
simples de ações. Portanto, o fluxo de execução é o movimento que o programa realiza ao seguir essas
instruções, ajustando-se às condições que encontra pelo caminho, como se estivesse navegando
por um roteiro cheio de bifurcações, voltas e repetições, dependendo do que está programado.
45
PENSAMENTO LÓGICO COMPUTACIONAL COM PYTHON
As estruturas de decisão em Python, compostas pelos comandos if, else e elif, desempenham
um papel crucial no controle de fluxo de um programa. Essas estruturas permitem que o código seja
executado de maneira condicional, dependendo da avaliação de expressões lógicas. O comando if
é utilizado para verificar uma condição específica e executar um bloco de código associado somente
quando essa condição é verdadeira. Já o else é empregado para fornecer uma alternativa, garantindo
que um bloco de código seja executado caso a condição do if seja falsa. O elif funciona como uma
extensão do if, permitindo a inclusão de verificações adicionais no mesmo conjunto de lógica, o que
possibilita a criação de ramificações complexas e otimizadas.
Essas estruturassão fundamentais para implementar decisões dinâmicas, pois ajustam o comportamento
do programa com base em diferentes situações, como validações, verificações e escolhas entre múltiplos
caminhos de execução. A avaliação das condições segue uma lógica booleana, respeitando a precedência
dos operadores, o que assegura flexibilidade e precisão na criação de algoritmos.
A lógica booleana é um fundamento da computação que opera com valores binários, ou seja,
verdadeiro e falso, geralmente representados como True e False em Python. Esses valores são o
resultado de expressões condicionais ou comparações, sendo amplamente utilizados para controlar
o luxo de execução de programas. A lógica booleana baseia-se no sistema desenvolvido pelo matemático
George Boole e usa operadores lógicos para combinar ou modificar expressões.
Os operadores lógicos em Python incluem and, or e not, cada um desempenhando um papel
específico. O operador and retorna verdadeiro apenas quando ambas as condições comparadas também
forem verdadeiras. O operador or resulta em verdadeiro se ao menos uma das condições for verdadeira.
Já o operador not inverte o valor lógico de uma expressão, transformando verdadeiro em falso e
vice-versa. Esses operadores permitem a criação de expressões complexas, que podem ser empregadas
em estruturas de decisão e repetição.
A precedência dos operadores é o conjunto de regras que determina a ordem na qual as operações
são avaliadas em uma expressão com múltiplos operadores. Em Python, a precedência dos operadores
segue princípios matemáticos semelhantes aos da álgebra, garantindo que as expressões sejam
resolvidas de forma lógica e previsível. Operadores de maior precedência são avaliados antes daqueles
de menor precedência, a menos que o uso de parênteses altere essa ordem explicitamente.
Na lógica booleana, a ordem de precedência influencia como expressões lógicas são avaliadas. Por
exemplo, o operador not tem maior precedência em relação aos operadores and e or, o que significa
que expressões contendo not são resolvidas antes de quaisquer operações com and ou or. Entre os
operadores restantes, and tem precedência superior a or. Isso implica que, em uma expressão que
combina os dois, os operadores and serão avaliados primeiro, a menos que parênteses sejam utilizados
para modificar essa sequência.
Esses conceitos são cruciais para escrever código preciso e funcional. A lógica booleana permite
a construção de condições sofisticadas, enquanto a compreensão da precedência dos operadores
evita ambiguidades e erros, garantindo que as expressões sejam avaliadas conforme a intenção do
46
Unidade I
programador. Essas ferramentas, quando dominadas, fortalecem a habilidade de criar algoritmos
eficientes e bem estruturados.
Usando a metáfora do bolo, imagine que você está seguindo uma receita automatizada em um
robô de cozinha inteligente. Esse robô, programado com lógica booleana, deve tomar decisões durante
a preparação. A lógica booleana, operando com verdadeiro (True) e falso (False), ajuda o robô a
decidir o que fazer em cada etapa da receita. O fluxograma para esse robô está na figura a seguir.
Por exemplo, o robô começa verificando os ingredientes disponíveis. Ele tem um fluxo de execução
para decidir se deve continuar com a receita ou avisar que algo está faltando. A verificação seria assim:
• Condição: “Tenho todos os ingredientes principais (farinha, ovos, leite e açúcar)?”.
• Lógica booleana: se a resposta for True (verdadeiro), ele segue para a próxima etapa. Se for
False (falso), ele para e emite um alerta.
Depois, o robô precisa escolher o tempo de cozimento. Ele avalia a consistência da massa e a
temperatura do forno:
• Condição 1: “A massa está homogênea?” (representada como True ou False com base nos
sensores do robô).
• Condição 2: “O forno está pré-aquecido a 180 graus?”.
• Lógica booleana com operador and: o robô só coloca o bolo para assar se ambas as condições
forem verdadeiras.
Durante o assamento, o robô monitora o estado do bolo:
• Condição: “O bolo está completamente assado?”. Ele verifica isso ao medir o tempo e checar se a
massa está firme.
• Lógica booleana com operador not: Enquanto not bolo_assado (ou seja, enquanto o
bolo não estiver assado), ele continua assando.
Por fim, o robô pode permitir personalizações, como adicionar coberturas. Aqui entra o operador or:
• Condição: “O cliente escolheu cobertura de chocolate ou cobertura de baunilha?”.
• Lógica booleana com operador or: se qualquer uma das opções for True, o robô aplica a
cobertura correspondente.
47
PENSAMENTO LÓGICO COMPUTACIONAL COM PYTHON
Início: verificar
ingredientes
principais Emitir alerta:
ingredientes
insuficientes
e encerrar
Preparar a massa
Misturar mais
a massa
Aguardar
pré-aquecimento
Colocar o bolo
para assar
TeTenho todos os os
ingredientes
(farinha, ovos,
leleite e açúcar)?r)?
A A massa está á
hhomogênea??
O O forno estáá
pré-aquecido
a 180 °C?
TrueTrue
TrueTrue
TrueTrue
FalseFalse
FalseFalse
FalseFalse
Figura 16 – Fluxograma sobre como fazer o bolo
Aguardar
pré-aquecimento
Colocar o bolo
para assar
Bolo pronto:
permitir
personalização
Continuar
assando
Aplicar cobertura
escolhida
Bolo finalizado
Finalizar sem
cobertura
O bolo está
completamente
assado?
O clieO cliente escolheu olheu
cobertura
de chocolate
ou cobertura
de de baunilha?ha?
TrueTrue
TrueTrueTrueTrue
FalseFalse
FalseFalse
FalseFalse
Figura 17 – Fluxograma sobre como fazer o bolo (continuação da figura anterior)
Essa sequência de decisões e ações é controlada pelas estruturas lógicas mencionadas, como
if (se) e while (enquanto), que utilizam operadores booleanos para determinar o que fazer. Assim, o
comportamento do robô se ajusta dinamicamente às condições encontradas, assegurando que o bolo
seja preparado da melhor forma possível.
No que se refere às estruturas de repetição, Python oferece os comandos for e while, que são
ferramentas poderosas para a execução iterativa de blocos de código.
A repetição controlada por for é geralmente utilizada quando o número de iterações é conhecido
ou delimitado, sendo ideal para percorrer sequências, como listas ou intervalos numéricos. Esse tipo de
laço (loop) promove uma iteração eficiente e simplifica a manipulação de conjuntos de dados.
O laço while, por outro lado, baseia-se em uma condição lógica que é avaliada antes de cada
iteração. Esse comportamento o torna adequado para situações nas quais o número de repetições
não é previamente conhecido, mas depende de uma condição que pode variar durante a execução.
O controle sobre o fluxo do while exige atenção para evitar a criação de laços infinitos, o que ressalta a
importância de garantir que a condição eventualmente seja falsificada.
Ambos os tipos de laços podem ser complementados por comandos adicionais ou mecanismos de
controle de fluxo mais específicos como break e continue, que permitem manipular o fluxo
de execução. Enquanto o break interrompe completamente o laço, o continue pula para a
próxima iteração sem finalizar o ciclo. Esses mecanismos aprimoram a capacidade de controlar e refinar
o comportamento iterativo, assegurando flexibilidade e eficiência na construção de programas.
48
Unidade I
2.1 Estruturas de decisão (if, else, elif)
Nosso viajante do tempo, equipado com sua máquina extraordinária, deve decidir para onde viajar:
explorar o passado, desvendando mistérios históricos, ou aventurar-se no futuro, descobrindo o que
ainda está por vir. O programa ajudará nesse processo ao solicitar a escolha do usuário e tomar uma
decisão baseada em sua resposta. Esse exercício introduz estruturas condicionais básicas, como if e
else, que permitem ao programa reagir de forma diferente a entradas específicas. A seguir o exemplo
no interpretador online.
# Solicitar ao usuário a escolha do destino temporal
print(“Você está prestes a iniciar sua viagem no tempo.”)
print(“Escolha seu destino: digite‘passado’ para viajar ao passado ou ‘futuro’
para viajar ao futuro.”)
# Capturar a escolha do usuário
destino = input(“Qual é a sua escolha? “).lower() # Converte a entrada para
minúsculas
# Decisão com base na escolha
if destino == “passado”:
print(“Você escolheu o passado! Prepare‑se para explorar os grandes
mistérios da história.”)
elif destino == “futuro”:
print(“Você escolheu o futuro! Prepare‑se para vislumbrar inovações e
surpresas.”)
else:
print(“Escolha inválida. Por favor, digite ‘passado’ ou ‘futuro’.”)
Figura 18 – Condicionais if, else e elif: o viajante deve ir para o passado ou para o futuro?
49
PENSAMENTO LÓGICO COMPUTACIONAL COM PYTHON
Note que, após a execução, o programa aguarda (figura 18, parte inferior) a escolha do período para
o qual o viajante deve seguir sua jornada. Na figura 19 digitamos passado e o viajante foi remetido ao
passado. Executamos novamente o programa (botão Run) na figura 20, escolhemos futuro e o viajante
teve o futuro como destino. Em uma nova execução (figura 21), digitamos presente e o programa não
aceitou essa escolha. Poderíamos ter digitado gato, bazinga ou coxinha que o resultado seria o mesmo.
Figura 19 – Condicionais if, else e elif: a escolha é que o viajante vá para o passado
Figura 20 – Condicionais if, else e elif: a escolha é que o viajante vá para o futuro
50
Unidade I
Figura 21 – Condicionais if, else e elif: as únicas opções são passado e futuro; não há outro destino para nosso viajante
O código utiliza a estrutura condicional if‑elif‑else para tomar decisões baseadas na entrada
do usuário. Vamos entender cada parte em detalhes:
• print(): mensagens iniciais explicam o objetivo do programa e as opções disponíveis para
o usuário.
• input(): a função input() solicita ao usuário que insira sua escolha. O valor digitado é
armazenado na variável destino. O método .lower() converte a entrada para letras
minúsculas, garantindo que a escolha seja interpretada corretamente mesmo que o usuário use
letras maiúsculas (como “Passado” ou “FUTURO”).
• if destino == “passado”: a estrutura if verifica se a variável destino contém exatamente
o valor “passado”. Se a condição for verdadeira, a mensagem correspondente é exibida.
• elif destino == “futuro”: caso a primeira condição não seja satisfeita, o programa
verifica se a escolha é “futuro”. Se for, exibe a mensagem apropriada.
• else: caso nenhuma das condições anteriores seja atendida (por exemplo, o usuário digita algo
inválido como “agora”), o bloco else é executado, exibindo uma mensagem de erro.
51
PENSAMENTO LÓGICO COMPUTACIONAL COM PYTHON
Lembrete
Vimos que no método socrático as questões são formuladas para
examinar diferentes hipóteses e chegar à verdade por meio da eliminação
de contradições. De maneira semelhante, a estrutura if-then-else avalia
condições lógicas para determinar quais ações tomar, explorando os diferentes
cenários que podem ocorrer com base nos dados fornecidos. Assim como
Sócrates questionava para guiar o raciocínio até uma conclusão lógica,
o if-then-else conduz o fluxo de execução do programa de maneira
estruturada, permitindo que ele “decida” o melhor caminho a seguir
diante de escolhas e condições diversas. Essa relação destaca como a lógica,
seja na filosofia ou na programação, é uma ferramenta para organizar o
pensamento e resolver problemas de maneira sistemática.
Métodos em programação são blocos de código associados a objetos, projetados para realizar
ações ou retornar informações sobre esses objetos. Em Python, tudo é tratado como um objeto,
incluindo números, strings (cadeias de caracteres), listas e até mesmo funções. Cada tipo de objeto tem
seus métodos específicos, que podem ser chamados para executar operações relacionadas ao objeto
em questão. Por exemplo, métodos em strings, como .lower(), são utilizados para manipular ou
transformar o texto de alguma maneira, como converter letras maiúsculas em minúsculas. Esses métodos
permitem que programadores realizem operações complexas de forma simplificada, sem a necessidade
de reescrever toda a lógica do processo.
O ponto (.), conhecido como dot operator (ou operador de ponto), é a notação utilizada para
acessar os métodos e atributos de um objeto. Ele funciona como um conector entre o objeto e o método
que será aplicado a ele. Quando escrevemos algo como texto.lower(), o operador de ponto
está indicando que o método .lower() pertence ao objeto texto. Isso significa que o método está
intimamente ligado à instância específica do objeto e que sua execução considera o estado atual do
objeto, utilizando suas propriedades internas para realizar a tarefa desejada. Em outras palavras, o dot
operator facilita a interação com os métodos e atributos de objetos, promovendo uma abordagem
orientada a objetos no desenvolvimento.
Já o operador == é utilizado para comparar dois valores e verificar se eles são iguais. Ele é um
operador de comparação e retorna um valor booleano: True se os valores forem iguais e False
caso contrário. Diferentemente do símbolo = (que é o operador de atribuição usado para armazenar
valores em variáveis), o == não altera os valores envolvidos; sua única função é comparar. Esse
operador é amplamente aplicado em estruturas condicionais e em loops para decidir o fluxo do programa
com base no resultado da comparação. Em Python, ele é sensível ao tipo dos dados comparados. Por
exemplo, comparar uma string com um número usando == sempre resultará em False, pois os dois
valores pertencem a tipos diferentes, mesmo que visualmente pareçam iguais. Depois veremos com mais
detalhes os operadores.
52
Unidade I
As estruturas condicionais permitem que o programa execute diferentes blocos de código com base
em condições específicas. Em Python:
• if verifica uma condição e executa o bloco de código correspondente se a condição for verdadeira;
• elif é usado para verificar outras condições adicionais, caso a primeira não seja atendida;
• else é um bloco opcional cuja função é capturar todos os outros casos não tratados pelos
blocos if ou elif.
Como vimos, o método .lower() é usado para converter uma string para letras minúsculas, o que ajuda
a evitar erros causados por diferenças de capitalização. Sem isso, o programa poderia rejeitar entradas
como “Passado” ou “FUTURO”, mesmo que o usuário tenha a intenção correta. Podemos explorar ainda
mais o exercício, introduzindo outras escolhas, como “presente” ou “multiverso” para expandir o diálogo
(linhas 13 a 16 da figura a seguir).
Figura 22 – Adicionando os destinos presente e multiverso para nosso viajante
Vamos imaginar também que queremos remover espaços extras digitados desnecessariamente
pelo usuário. Usaremos o método .strip() junto com .lower(), conforme observado na linha 6 da
figura 23. Note também na figura que na execução do código (após pressionar o botão Run) digitamos
a cadeia de caracteres “ PAssado ” com maiúsculas, minúsculas e espaços extras.
53
PENSAMENTO LÓGICO COMPUTACIONAL COM PYTHON
Figura 23 – Uso do método .strip() para remover espaços extras em uma cadeia de caracteres
Nesse exemplo, na instrução input(“Qual é a sua escolha?“) .strip().
lower(), os métodos .strip() e .lower() são aplicados sequencialmente ao valor retornado
por input(). Aqui, input() retorna uma string que, por sua vez, é manipulada pelos métodos
subsequentes. O resultado de cada método intermediário é um objeto string, permitindo que o próximo
método seja acionado. Essa técnica é chamada de method chaining, uma prática comum em Python
porque promove uma escrita de código mais concisa e expressiva.
Considere agora que nosso viajante do tempo voltou ao ano de 1985 com o objetivo de impedir que
um evento importante aconteça. No entanto, interferir em eventos do passado pode causar paradoxos
temporais que ameaçam a estrutura do espaço-tempo.
Na ficção científica, um paradoxo temporal ocorre quando uma alteração no passado causa uma
contradiçãono futuro. Por exemplo, se você impedir o encontro de seus pais no passado, você não
nasceria, logo não poderia voltar no tempo para impedir o encontro. Nosso programa da figura 24
simula a avaliação do risco de tais paradoxos com base nas ações do viajante no tempo. O programa
determinará se sua ação causará um paradoxo temporal com base em três condições:
• interação consigo mesmo no passado: você encontra e interage com sua versão mais jovem;
• alteração de um evento histórico crucial: você modifica um evento que tem grande impacto
no futuro;
• interferência na linha do tempo de um ancestral direto: suas ações afetam diretamente a
vida de um antepassado.
54
Unidade I
Figura 24 – Código-fonte para verificar um paradoxo temporal
No início do código (linhas 3 a 6), definimos três variáveis booleanas que representam as
condições do cenário:
• interage_com_si_mesmo: indica se você interage com sua versão mais jovem;
• altera_evento_crucial: mostra se você altera um evento histórico importante;
• interfere_com_ancestral: destaca se você interfere na vida de um ancestral direto.
Essas variáveis são do tipo booleano, ou seja, só podem assumir os valores True ou False. Elas são
usadas para representar situações que podem ou não ocorrer. O programa avalia as condições na ordem:
• se a primeira condição if for True, executa o bloco associado e termina a verificação;
• se não, passa para a próxima condição elif e assim sucessivamente;
• se nenhuma condição for satisfeita, executa o bloco else.
Vamos analisar essa estrutura. A primeira condição com if (linha 9) verifica se ambas as situações
ocorrem: você interage consigo mesmo e altera um evento crucial. Se ambas forem verdadeiras, o
programa conclui que o paradoxo temporal é certo.
55
PENSAMENTO LÓGICO COMPUTACIONAL COM PYTHON
Se a primeira condição não for satisfeita, o programa verifica (linha 11, com elif) se você interfere
na linha do tempo de um ancestral. Se verdadeiro, indica um alto risco de paradoxo.
Na sequência (linha 13), o programa verifica se pelo menos uma das duas condições é verdadeira:
interagir consigo mesmo ou alterar um evento crucial. Se for o caso, há um risco moderado de paradoxo.
Por fim, se nenhuma das condições anteriores for satisfeita (linha 15), o programa conclui que há um
risco mínimo de paradoxo.
Note também que os condicionais usam os operadores lógicos:
• and: retorna True se ambas as condições forem verdadeiras;
• or: retorna True se pelo menos uma das condições for verdadeira.
Esses operadores permitem combinar múltiplas condições em uma única expressão lógica.
Considere agora que nosso viajante quer saber se um determinado ano é bissexto, tarefa que pode
ser crucial para cálculos precisos de datas e coordenadas temporais. Um dia extra no calendário
pode afetar a sincronização de eventos e a localização temporal exata. Portanto, o viajante do tempo
precisa determinar se o ano para o qual pretende viajar é bissexto. O programa da figura a seguir solicita
ao usuário que insira um ano e verifica se esse ano é bissexto, auxiliando no planejamento preciso da
viagem temporal.
Figura 25 – Calculando ano bissexto
56
Unidade I
Observação
O ano bissexto é uma correção no calendário gregoriano que ocorre
a cada quatro anos, adicionando um dia extra ao mês de fevereiro. Isso
faz com que o mês tenha 29 dias, totalizando 366 dias no ano, em vez
dos habituais 365. Essa adaptação é necessária para alinhar o calendário
civil ao ano solar, ou seja, ao tempo que a Terra leva para completar uma
volta ao redor do Sol.
O ano solar tem aproximadamente 365 dias e 6 horas. As seis horas excedentes, acumuladas
anualmente, somam um dia completo a cada quatro anos. Assim, a inclusão de um dia adicional
mantém o calendário ajustado às estações do ano e evita um descompasso progressivo entre o tempo
astronômico e o civil.
Nem todo ano divisível por quatro é bissexto. Existem exceções para manter maior precisão: anos
múltiplos de 100 não são bissextos, a menos que também sejam divisíveis por 400. Por exemplo, o
ano 2000 foi bissexto, enquanto 1900 não foi. Essa regra ajuda a ajustar pequenos desvios acumulados
ao longo dos séculos, garantindo que o calendário permaneça sincronizado com os movimentos da Terra.
Nosso programa inicia solicitando ao usuário que insira um ano, utilizando a função input.
A entrada é inicialmente uma string, mas é convertida em um número inteiro com a função int para
permitir cálculos numéricos. A variável ano armazena esse valor para uso posterior nas verificações.
Em seguida, o programa utiliza estruturas condicionais para determinar se o ano é bissexto. A primeira
condição if verifica se o ano é divisível por 4, usando o operador módulo %. Se o resto da divisão de
ano por 4 for zero, isso indica que o ano é potencialmente bissexto segundo a primeira regra.
Se a condição anterior for verdadeira, o programa prossegue para verificar se o ano é divisível
por 100. Isso é necessário porque anos múltiplos de 100 não são bissextos, a menos que sejam também
divisíveis por 400. Novamente, o operador % é usado para essa verificação. Se o ano for divisível por
100, o programa entra em outra verificação aninhada.
Dentro dessa verificação aninhada, o programa verifica se o ano é divisível por 400. Se for, o ano
é confirmado como bissexto. Caso contrário, não é bissexto. Essa verificação finaliza a aplicação das
regras para anos centenários.
O termo aninhado refere-se à estrutura de código na qual uma verificação condicional (ou qualquer
bloco de código) está contida dentro de outra verificação condicional. Esse tipo de organização
hierárquica, na qual uma condição depende do resultado de outra, é caracterizado como aninhamento.
Isso facilita a aplicação de regras mais específicas após uma condição mais geral ter sido satisfeita. Essa
abordagem é útil para tratar casos nos quais as condições precisam ser avaliadas em etapas, garantindo
que somente os casos pertinentes avancem para as verificações subsequentes.
57
PENSAMENTO LÓGICO COMPUTACIONAL COM PYTHON
Se o ano não for divisível por 100, mas for divisível por 4, o programa conclui que o ano é bissexto.
Caso a primeira condição, de ser divisível por 4, não seja satisfeita, o programa determina que o ano
não é bissexto.
As mensagens de saída são exibidas ao usuário utilizando a função print e formatação de strings
com f-strings, que inserem o valor da variável ano diretamente na mensagem.
Embora o programa funcione corretamente para a maioria dos casos, ele não inclui tratamento de
exceções para entradas inválidas. Em uma aplicação prática, seria recomendável incluir verificações
adicionais para garantir que o usuário insira um número inteiro válido.
No universo das viagens temporais, somente indivíduos com maturidade e responsabilidade
adequadas podem operar uma máquina do tempo. A manipulação do contínuo espaço-tempo é uma
tarefa delicada que requer não apenas conhecimento, mas também discernimento ético. Por essa
razão, estabeleceu-se que apenas pessoas com idade igual ou superior a 18 anos estão autorizadas a
pilotar tais dispositivos. O programa da figura a seguir tem como finalidade auxiliar nessa verificação,
solicitando ao usuário que informe sua idade e determinando se ele está apto a receber permissão para
a viagem temporal.
Figura 26 – Verificando se o viajante tem a idade requerida
Esse programa inicia solicitando que o usuário insira sua idade, utilizando a função input. Como
a entrada recebida por input é do tipo string, é necessário convertê-la para um número inteiro
usando a função int(). Essa conversão é essencial para que seja possível realizar comparações
numéricas posteriormente. A idade fornecida é então armazenada na variável idade.
58
Unidade I
Em seguida, o programa utiliza uma estrutura condicional if para verificar se o usuário tem 18 anos
ou mais. A condição idade >= 18 usa o operador de comparação >=, que verifica se o valor à
esquerda émaior ou igual ao valor à direita. Se essa condição for verdadeira, o programa entende que o
usuário tem idade suficiente para operar a máquina do tempo. Nesse caso, ele executa o bloco de código
associado ao if, que consiste em exibir uma mensagem informando que o acesso foi concedido.
Caso a condição idade >= 18 não seja satisfeita, ou seja, se o usuário tiver menos de 18 anos,
o programa segue para o bloco else. Aqui, uma mensagem é exibida informando que o acesso foi
negado, pois o usuário não tem a idade mínima requerida para operar a máquina. Esse fluxo garante
que apenas usuários com idade adequada recebam permissão.
As mensagens exibidas utilizam a função print, que mostra o texto entre parênteses na tela do
usuário. Dessa forma, o programa fornece um feedback imediato, informando o resultado da verificação
de forma clara e direta.
Esse programa exemplifica o uso de operadores de comparação e estruturas condicionais em
Python para tomar decisões com base na entrada do usuário. Os operadores de comparação, como
>= (maior ou igual a), (maior que),da variável contagem, que representa o número
atual na contagem regressiva. Lembre-se que após imprimir o número, o programa chama time.
sleep(1), fazendo uma pausa de um segundo antes de continuar para o próximo número. Essa pausa
é crucial para simular o efeito de uma contagem regressiva real. Você pode aumentar esse número e
observar o efeito.
Após o loop ter percorrido todos os números, o programa sai do loop e imprime a mensagem
“Viagem temporal iniciada!”, indicando que a contagem regressiva foi concluída e que a
partida da viagem temporal ocorreu.
Esse programa ilustra o uso de loops for em Python para iterar sobre uma sequência de números.
O loop for é uma estrutura de controle que permite repetir um bloco de código para cada item em
uma sequência. No caso desse programa, a sequência é gerada pela função range(), que cria uma lista
virtual de números inteiros dentro de um intervalo especificado.
Observe novamente o código-fonte da figura 23. Note que se o usuário digitar algo diferente de
“passado” ou “futuro”, o programa simplesmente exibe uma mensagem de erro e termina a execução.
Desse modo, o usuário não tem uma nova oportunidade de corrigir o erro e escolher uma opção válida.
No código-fonte adaptado, disponível na figura a seguir, vamos resolver esse problema com o uso de
um laço de repetição while.
Figura 30 – Uso do loop while para permitir que o usuário corrija sua entrada
63
PENSAMENTO LÓGICO COMPUTACIONAL COM PYTHON
O novo fragmento de código (linhas 5 até 10 da figura anterior) adiciona um mecanismo que
mantém o programa solicitando uma resposta até que o usuário insira uma escolha válida. Nesse caso,
o loop funciona como uma repetição automática da pergunta. Quando o usuário digita algo incorreto,
como “não sei” ou “presente”, o programa identifica que a resposta não está entre as opções corretas
(destino not in [“passado”, “futuro”]) e repete a pergunta com uma mensagem
explicativa, dando uma nova chance para que a pessoa tente novamente.
Assim, o programa não encerra imediatamente quando há um erro. Em vez disso, ele continua
insistindo educadamente até que o usuário escolha “passado” ou “futuro”. Isso garante que a interação seja
mais clara e amigável, além de evitar interrupções desnecessárias. Para o usuário, a experiência é muito mais
intuitiva, pois ele tem um guia direto que o orienta a corrigir a entrada e continuar normalmente.
Vamos recapitular a lógica do nosso laço while na figura anterior:
• A condição do loop, destino not in [“passado”, “futuro”], verifica se a entrada
do usuário não está contida na lista de opções válidas.
• Caso a entrada seja inválida, o código dentro do loop é executado novamente, pedindo ao usuário
para inserir outra escolha.
• Assim que o usuário insere “passado” ou “futuro”, a condição do loop se torna falsa, e o programa
segue para o bloco principal, no qual a mensagem apropriada é exibida.
• A variável destino foi inicializada como uma string vazia (destino = “”) antes do loop.
Em Python, todas as variáveis precisam ser declaradas (inicializadas) antes de serem usadas.
Se tentarmos usar uma variável que não foi definida, o Python gerará um erro.
Analise agora o exemplo da figura a seguir:
Figura 31 – Código-fonte para registro dos anos já visitados (à esquerda) e
resultado da execução para os anos de 1500, 1822 e 1922 (à direita)
64
Unidade I
Como viajante do tempo, é importante manter um registro dos anos já visitados para evitar
interferências em eventos históricos e para planejamento de futuras viagens. Registrar os anos visitados
ajuda a prevenir paradoxos temporais e encontros indesejados consigo mesmo em diferentes linhas
temporais. O programa da figura anterior permite que o usuário insira os anos que já visitou, continuando
a solicitar novas entradas até que ele decida encerrar o processo digitando “sair”. Ao final, o programa
apresenta uma lista completa dos anos registrados.
O programa começa inicializando uma lista vazia chamada anos_visitados, que servirá para
armazenar os anos informados pelo usuário. As listas em Python são estruturas que permitem armazenar
múltiplos valores em uma única variável, mantendo a ordem de inserção e permitindo duplicatas.
Falaremos das listas com mais detalhes mais adiante.
Em seguida, o programa entra em um loop while infinito com a condição while True:. Esse
tipo de loop continua executando indefinidamente até que seja interrompido por um comando break.
Dentro do loop, o programa solicita ao usuário que insira um ano visitado ou digite “sair” para encerrar
o programa. A função input() captura a entrada do usuário e armazena na variável ano.
O programa então verifica se a entrada do usuário é igual a “sair”. A comparação é feita utilizando
ano.lower() == ‘sair’, que converte a entrada para letras minúsculas antes da comparação.
Isso permite que o usuário digite “sair”, “Sair”, “SAIR” ou qualquer variação de maiúsculas e minúsculas,
e ainda assim o programa reconhecerá o comando para encerrar.
Se o usuário digitar “sair”, o comando break é executado, interrompendo o loop while e
prosseguindo para a parte final do programa. Caso contrário, o programa entra no bloco else: no
qual o ano informado é adicionado à lista anos_visitados usando o método append(). Uma
mensagem é exibida confirmando o registro do ano.
Após o loop ser encerrado, o programa imprime uma linha em branco para separar visualmente as
entradas anteriores da saída final. Em seguida, exibe a mensagem Anos visitados: e utiliza um
loop for para iterar sobre a lista anos_visitados, imprimindo cada ano registrado. As mensagens
exibidas utilizam f-strings (strings formatadas) para inserir o valor da variável ano diretamente na
mensagem, tornando a saída mais informativa. A ideia é fornecer ao usuário um resumo completo dos
anos que ele inseriu durante a execução do programa.
Embora o programa armazene os anos como strings, se houver necessidade de realizar operações
numéricas com esses anos (como ordenação numérica ou cálculos de intervalos de tempo), seria
adequado converter as entradas para inteiros usando int(ano)dentro de um bloco try‑except
para tratar possíveis entradas inválidas e evitar erros durante a execução.
65
PENSAMENTO LÓGICO COMPUTACIONAL COM PYTHON
Lembrete
O loop while é especialmente útil quando o número de iterações não é
conhecido antecipadamente e depende de uma condição dinâmica, como
a entrada do usuário. No contexto do código da figura 31, o loop while
permite que o programa continue solicitando anos visitados até que o
usuário decida encerrar o processo.
Em contraste, o loop for é ideal para iterar sobre sequências
conhecidas, como listas, tuplas ou strings. Ele permite executar um bloco
de código para cada elemento da sequência, facilitando operações como a
exibição de todos os itens armazenados. No programa apresentado, o loop
for é utilizado para percorrer a lista anos_visitados e imprimir
cada ano registrado.
A compreensão da diferença entre while e for permite ao programador
escolher a estrutura de loop mais adequada para cada situação. Enquanto
o while é orientado por uma condição que precisa ser verdadeira para
continuar a execução, o for é orientado pela sequência de elementos
a ser percorrida.
No contexto das viagens no tempo, intervenções em momentos históricos cruciais podem alterar
profundamente o curso de uma nação. No caso do Brasil, eventos marcantes moldaram a sociedade e
a política do país ao longo dos séculos. Um viajante do tempo interessado em entender ou até mesmo
influenciar a história brasileira precisa considerar como diferentes ações em anos decisivos poderiam
criar linhas temporais alternativas. O programa da figura 32 simula essas possibilidades, explorando
intervenções em marcos importantes da história do Brasil. Utilizaremos loops aninhados para
percorrer diferentes anos e escolhas, demonstrando como decisões específicas poderiam ter mudado o
destino da nação.
66
UnidadeI
Figura 32 – Simulação de linhas temporais usando loops aninhados
O programa inicia definindo uma lista chamada anos, que contém anos fundamentais na história
do Brasil: 1822, 1888 e 1932. O ano de 1822 marca a independência do Brasil, quando o país deixou
de ser uma colônia de Portugal. Em 1888, a assinatura da Lei Áurea aboliu a escravidão, alterando
profundamente a estrutura social brasileira. Já 1932 é o ano da Revolução Constitucionalista.
Em seguida, é criado um dicionário chamado intervencoes, no qual cada chave corresponde a
um dos anos na lista anos, e cada valor é uma lista de possíveis intervenções que um viajante do tempo
poderia realizar nesse ano específico. Por exemplo, em 1822 as intervenções possíveis são “Incentivar a
permanência do Brasil como colônia de Portugal” e “Apoiar a proclamação da Independência do Brasil
por Dom Pedro I”. Essas ações representam escolhas que poderiam alterar significativamente o rumo da
história brasileira.
Um contador chamado contador_linhas é inicializado com o valor 1. Ele será utilizado para
numerar cada linha temporal gerada, permitindo acompanhar quantas alternativas foram exploradas.
O programa então entra em um loop for externo que percorre cada ano na lista anos. Para cada
ano, utiliza-se o ano como chave para acessar a lista de intervenções no dicionário intervencoes.
Em seguida, entra em um loop for interno que percorre cada intervenção possível nesse ano.
67
PENSAMENTO LÓGICO COMPUTACIONAL COM PYTHON
Dentro do loop interno, o programa imprime uma mensagem que inclui o número da linha temporal,
o ano em que a intervenção ocorreu e a ação realizada. A mensagem é formatada usando uma f-string
para inserir os valores das variáveis diretamente na string. Após imprimir a mensagem, o contador
contador_linhas é incrementado em 1, preparando-o para a próxima linha temporal.
Esse processo de loops aninhados permite explorar todas as combinações de anos e intervenções,
simulando a criação de múltiplas linhas temporais alternativas baseadas em ações específicas em
momentos históricos vitais do Brasil. O resultado da execução é ilustrado na figura a seguir.
Figura 33 – Resultado da execução dos loops aninhados
Esse programa exemplifica o uso de loops aninhados em Python para iterar sobre estruturas de
dados complexas. O loop externo percorre uma lista de anos significativos, enquanto o loop interno
percorre as possíveis intervenções associadas a cada ano. Ao combinar esses loops, o programa gera
todas as combinações possíveis de anos e intervenções.
Convém observar também que a indentação em Python é essencial para definir a estrutura do
código. Ela indica quais linhas pertencem a quais blocos, especialmente em estruturas de controle como
loops e condicionais. No código acentuado, as linhas dentro dos loops for estão devidamente indentadas,
garantindo que o interpretador Python compreenda a hierarquia das operações e execute o código na
ordem correta.
É fundamental que um viajante tenha conhecimento dos eventos históricos significativos para
planejar suas jornadas e evitar interferências indesejadas na linha temporal. Manter uma lista dos
acontecimentos mais importantes permite que o viajante selecione destinos temporais com propósito e
compreensão das possíveis implicações de suas ações. O programa da figura 34 demonstra como exibir
uma lista de eventos históricos importantes utilizando um loop for, facilitando a consulta e o estudo
desses eventos.
68
Unidade I
Figura 34 – Registro de eventos históricos
O programa inicia definindo uma lista chamada eventos_historicos, que contém uma
série de strings. Cada string representa um evento histórico importante no Brasil, incluindo uma breve
descrição e a data em que ocorreu. A lista é construída colocando-se os eventos entre colchetes [],
separados por vírgulas, e cada evento é delimitado por aspas, indicando que são strings.
Em seguida, o programa exibe uma mensagem introdutória utilizando a função print(), informando
que os eventos históricos importantes serão listados. A sequência \n dentro da string representa
uma quebra de linha, adicionando um espaço em branco entre a mensagem e a listagem dos eventos
para melhorar a formatação da saída.
O loop for é então utilizado para iterar sobre a lista eventos_historicos. A sintaxe for
evento in eventos_historicos: indica que o loop irá percorrer cada elemento da lista,
atribuindo o valor de cada elemento à variável evento em cada iteração. Dentro do loop, a função
print(evento)é chamada para exibir o conteúdo da variável evento, que contém o evento
histórico atual.
Ao final da execução do loop, todos os eventos da lista terão sido impressos no console (conforme
exibido na figura 35), cada um em uma linha separada. Esse método permite apresentar a lista completa
de eventos históricos de forma organizada e sequencial, facilitando a leitura e a compreensão do usuário.
69
PENSAMENTO LÓGICO COMPUTACIONAL COM PYTHON
Figura 35 – Marcos históricos exibidos na tela do console
70
Unidade I
Resumo
Esta unidade abordou a lógica de programação como base essencial
para quem deseja atuar em computação e desenvolvimento de software,
destacando ferramentas como algoritmos, pseudocódigos e fluxogramas.
Essas ferramentas estruturam soluções e são vitais no planejamento antes
da implementação em linguagens de programação, como Python.
Os algoritmos foram descritos como sequências finitas de instruções
claras que solucionam problemas. O pseudocódigo facilita a representação
de algoritmos de forma mais simples, enquanto os fluxogramas indicam
visualmente o fluxo lógico, ajudando na identificação de falhas.
Python, uma linguagem de programação de alto nível, foi destacada
por sua simplicidade, versatilidade e capacidade de atender demandas
modernas, sendo amplamente usada tanto por iniciantes quanto por
profissionais experientes. Sua sintaxe legível, bibliotecas robustas e suporte
multiplataforma tornam-na ideal para ciência de dados, aprendizado de
máquina, entre outras aplicações. A interação com essa linguagem foi
apresentada por meio de exercícios didáticos que introduziram conceitos
como variáveis, entrada e saída de dados, além de strings.
Também trabalhamos as estruturas de controle em Python, que são
ferramentas cruciais para gerenciar o fluxo de execução de um programa,
permitindo que ele reaja de forma dinâmica a diferentes condições. As estruturas
abordadas incluíram decisões condicionais, repetições e operadores lógicos,
além de exemplos práticos aplicados ao conceito de viagens no tempo.
As estruturas condicionais, como if, elif e else, permitem ao
programa avaliar condições e executar blocos de código específicos. A lógica
booleana é destacada como base para a computação, operando com valores
True e False e utilizando operadores como and, or e not. Esses
operadores são cruciais para a criação de condições complexas e seguem
uma ordem de precedência que influencia a avaliação das expressões.
Em termos de repetição, os laços for e while foram explicados
com aplicações distintas. O laço for é ideal para iterar sobre sequências
conhecidas, como listas, enquanto o while é útil para situações em que
o número de iterações depende de uma condição dinâmica. Complementos
como break e continue permitem maior controle sobre esses loops.
Por fim, o uso de loops aninhados e operadores lógicos foi explorado em
simulações de linhas temporais alternativas, demonstrando como decisões
específicas podem impactar eventos históricos.
71
PENSAMENTO LÓGICO COMPUTACIONAL COM PYTHON
Exercícios
Questão 1. O aplicativo de relacionamentos Tinder está diretamente associado à facilitação do
encontro inicial entre duas pessoas que tenham interesses afetivos ou românticos em comum. O
aplicativo atua como um mediador virtual, ampliando o alcance das possibilidades de interação e
superando algumas das dificuldades e barreiras anteriormente encontradas em ambientes tradicionais
de socialização.Um match no Tinder ocorre quando duas pessoas mostram interesse mútuo ao, na tela
do aplicativo, deslizarem os dedos para a direita no perfil uma da outra, possibilitando o início de uma
conversa. A equipe de desenvolvimento do Tinder tinha a missão de dar manutenção no aplicativo e
criou o fluxograma a seguir, que utiliza símbolos de acordo o padrão ISO 5807. Ele apresenta um cenário
comum de uso do aplicativo.
NãoNão
NãoNão
SimSim
SimSim
Aplicar algoritmos de correspondência
Trocar mensagens
Fim
Início
Criar perfil
Exibir correspondências
Configurar encontro
Houve match?
Interessado em encontro?
Figura 36
72
Unidade I
Você é membro dessa equipe de desenvolvimento e tem a tarefa de criar um pseudocódigo que
represente o funcionamento principal do aplicativo. Qual das alternativas a seguir melhor representa a
linha do pseudocódigo que verifica o interesse mútuo antes de liberar a troca de mensagens?
A) Se Interessado_Em_Encontro(Perfil_do_Usuário, Perfil_Matched)
então
B) Perfis_Correspondentes := Aplicar_Algoritmos_de_Correspondência
(Perfil_do_Usuário)
D) Permitir_Troca_de_Mensagens(Perfil_do_Usuário, Perfil_Matched)
D) Configurar_Encontro(Perfil_do_Usuário, Perfil_Matched)
E) Se Houve_Match(Perfil_do_Usuário, Perfis_Correspondentes)
entãointeressados
Resposta correta: alternativa E.
Análise da questão
Na prática do desenvolvimento de sistemas, tanto a criação de fluxogramas quanto a escrita de
pseudocódigo são técnicas usadas para planejar e estruturar a lógica antes de implementar o código
efetivamente. A ordem com que essas técnicas são aplicadas pode variar de acordo com a preferência
da equipe de desenvolvimento, a complexidade do projeto ou os métodos adotados pela organização.
No entanto, geralmente, observamos em primeiro lugar o desenho do fluxograma e, posteriormente, a
criação do pseudocódigo, como apresentado no enunciado da questão.
O fluxograma é frequentemente usado no início do processo de desenvolvimento, pois fornece uma
visão visual e clara da sequência de processos e decisões.
Após a definição do fluxo geral pelo fluxograma, o pseudocódigo é útil para detalhar mais
precisamente como cada parte do sistema irá operar. Ele permite que os desenvolvedores pensem sobre
as estruturas de dados necessárias, as operações específicas e outros detalhes de implementação antes
de codificar.
Para resolver a questão, é necessário escrever o pseudocódigo. O fluxograma especifica que, após
criar um perfil, o aplicativo aplica algoritmos de correspondência, exibe perfis potenciais, verifica se
houve match e só então permite a troca de mensagens. Caso não haja match, o aplicativo retorna à
etapa de exibir as correspondências. Se houver match, o usuário poderá trocar mensagens. Se houver
interesse em um encontro, ele será configurado; caso contrário, o ciclo retornará novamente à exibição
de correspondências. A seguir, vemos o resultado desse trabalho.
73
PENSAMENTO LÓGICO COMPUTACIONAL COM PYTHON
Início
// Passo 1: Criar o perfil do usuário
Perfil_do_Usuário := Criar_Perfil()
// Estrutura de repetição para voltar a exibir correspondências caso não
haja match ou não haja interesse em encontro
Encontro_Configurado := falso
Enquanto Encontro_Configurado = falso faça
// Passo 2: Aplicar Algoritmos de Correspondência
Perfis_Correspondentes := Aplicar_Algoritmos_de_Correspondência(Perfil_do_
Usuário)
// Passo 3: Exibir perfis correspondentes
Exibir(Perfis_Correspondentes)
// Passo 4: Verificar se houve match
Se Houve_Match(Perfil_do_Usuário, Perfis_Correspondentes) então
// Passo 5: Permitir troca de mensagens
Permitir_Troca_de_Mensagens(Perfil_do_Usuário, Perfil_Matched)
// Passo 6: Verificar interesse em encontro
Se Interessado_Em_Encontro(Perfil_do_Usuário, Perfil_Matched) então
// Passo 7: Configurar encontro
Configurar_Encontro(Perfil_do_Usuário, Perfil_Matched)
Encontro_Configurado := verdadeiro
Fim Se
Fim Se
// Caso não haja match ou não haja interesse em encontro, o loop se
repete,
// voltando a exibir correspondências novamente, conforme o fluxograma.
Fim Enquanto
Fim
De acordo com o fluxo representado, antes que a troca de mensagens seja permitida, é necessário
verificar se há match entre o perfil do usuário e os perfis exibidos. Esse momento é crítico, pois o match
garante o interesse mútuo. Uma vez confirmado, avança-se no processo, o que permite as mensagens.
Posteriormente, verifica-se o interesse em um encontro.
A linha de pseudocódigo Se Houve_Match(Perfil_do_Usuário, Perfis_
Correspondentes) é a que melhor reflete essa decisão essencial. A etapa de verificar interesse em
encontro (A) acontece após a troca de mensagens. A etapa de aplicar algoritmos de correspondência (B)
ocorre antes da verificação do match. A permissão de troca de mensagens (C) e a configuração do
encontro (D) são consequências do match e do interesse mútuo, respectivamente, e não do momento
da verificação inicial.
Portanto, a alternativa E é a correta, pois expressa precisamente o ponto no qual se verifica o
interesse mútuo antes de avançar no fluxo.
74
Unidade I
Questão 2. A equipe de desenvolvimento do aplicativo de relacionamentos Tinder estava avaliando
o trecho de código em Python a seguir:
def criar_perfil():
perfil = {
“nome”: “João”,
“idade”: 30,
“interesses”: [“música”, “cinema”, “esportes”]
}
return perfil
def aplicar_algoritmos(perfil, todos_perfis):
perfis_correspondentes = []
for p in todos_perfis:
if “cinema” in p[“interesses”]: # Simulação simples de uma
correspondência
perfis_correspondentes.append(p)
return perfis_correspondentes
def exibir_perfis_correspondentes(perfis):
for perfil in perfis:
print(f”Nome: {perfil[‘nome’]}, Idade: {perfil[‘idade’]}, Interesses:
{perfil[‘interesses’]}”)
def trocar_mensagens():
print(“Você tem uma nova mensagem!”)
def configurar_encontro():
print(“Encontro configurado para sexta‑feira às 19h no parque central!”)
def verificar_match(perfis_correspondentes):
for perfil in perfis_correspondentes:
if perfil[“nome”] == “Maria”: # Simulação de um ‘match’
return True
return False
# Fluxo principal
def main():
# Passo 1: Criar perfil
meu_perfil = criar_perfil()
# Simulação de um banco de dados de perfis
todos_perfis = [
{“nome”: “Maria”, “idade”: 28, “interesses”: [“cinema”, “leitura”,
“arte”]},
{“nome”: “Pedro”, “idade”: 25, “interesses”: [“música”, “jogos”,
“esportes”]}
]
# Passo 2: Aplicar algoritmos de correspondência
perfis_correspondentes = aplicar_algoritmos(meu_perfil, todos_perfis)
# Passo 3: Exibir perfis correspondentes
exibir_perfis_correspondentes(perfis_correspondentes)
75
PENSAMENTO LÓGICO COMPUTACIONAL COM PYTHON
# Passo 4: Verificar se houve ‘match’
if verificar_match(perfis_correspondentes):
print(“Match encontrado!”)
# Passo 5: Permitir troca de mensagens
trocar_mensagens()
# Passo 6: Decidir sobre encontro
resposta = input(“Deseja configurar um encontro? (sim/não): “)
if resposta.lower() == “sim”:
configurar_encontro()
else:
print(“Ok, talvez em outra ocasião.”)
else:
print(“Nenhum match encontrado, continue procurando.”)
if __name__ == “__main__”:
main()
Qual alternativa descreve corretamente o comportamento do código quando encontra um perfil
chamado “Maria” entre os perfis correspondentes e o usuário responde “não” à pergunta sobre configurar
um encontro?
A) O programa envia uma mensagem e pergunta se o usuário quer configurar um encontro, mas não
faz nada após receber a resposta “não”.
B) O programa automaticamente rejeita qualquer perfil que não seja “Maria”, sem verificar outros
perfis em perfis_correspondentes.uma linguagem de programação é vital para materializar conceitos lógicos em
aplicações funcionais, possibilitando a verificação, a validação e o aprimoramento das soluções propostas.
A sintaxe de uma linguagem de programação é o conjunto de regras e padrões que determinam
como instruções e comandos devem ser escritos para que o computador possa entendê-los e executá-los
corretamente. Pense na sintaxe como as normas gramaticais de uma linguagem humana; ela define a
estrutura e o modo correto de combinar palavras e símbolos para formar sentenças compreensíveis.
Entre as diversas linguagens de programação disponíveis atualmente, Python foi escolhida para esta
disciplina como ferramenta para ensinar e aplicar o pensamento computacional por diversas razões.
Primeiro, Python é reconhecida por sua sintaxe simples e clara, o que a torna acessível para iniciantes.
Essa facilidade de compreensão permite que os alunos se concentrem nos conceitos fundamentais de
lógica e estruturação de problemas, sem serem sobrecarregados por detalhes sintáticos complexos. Como
afirmou Van Rossum, criador da linguagem, Python permite aos programadores expressar conceitos em
menos linhas de código do que em linguagens como C++ ou Java (Van Rossum; Drake, 2007). Essa
eficiência torna Python uma ferramenta poderosa para implementar algoritmos e soluções de maneira
rápida e eficaz.
Além disso, Python é uma linguagem extremamente versátil e amplamente utilizada em diferentes
áreas da tecnologia, como desenvolvimento web, ciência de dados, inteligência artificial (IA) e
automação de tarefas. Isso significa que o aprendizado de Python facilita a compreensão do pensamento
computacional e fornece habilidades práticas valorizadas no mercado de trabalho atual.
8
Desse modo, abordaremos os conceitos fundamentais da lógica de programação utilizando Python
como ferramenta de desenvolvimento. O objetivo geral é capacitar os alunos a pensar de forma lógica e
estruturada para resolver problemas computacionais, desenvolvendo o raciocínio lógico e a capacidade
de abstração necessária para a criação de algoritmos eficientes.
No decorrer da disciplina, os estudantes são introduzidos aos conceitos básicos de lógica, algoritmos,
pseudocódigo e fluxogramas. Esses fundamentos são essenciais, pois estabelecem a base para
compreender como os programas funcionam internamente. Compreendê-los permite que os alunos
escrevam código para o computador e entendam o raciocínio por trás das soluções implementadas.
As estruturas de controle, como condicionais e loops, são componentes cruciais na programação.
Elas permitem que programas tomem decisões e executem tarefas repetitivas de maneira eficiente. Ao
dominar estruturas como if, else, for e while, os alunos aprendem a controlar o fluxo de execução de
seus programas, tornando-os mais dinâmicos e responsivos às diversas situações que possam encontrar.
A manipulação de tipos de dados e variáveis é outro aspecto crucial abordado na disciplina. Entender
como armazenar e manipular dados permite que os programadores criem programas que interajam
com o usuário e processem informações de maneira significativa. Além disso, a introdução ao uso
de operadores e funções matemáticas amplia a capacidade dos alunos de desenvolver soluções mais
complexas e robustas.
Também abordaremos o conceito de modularização e funções em Python. A capacidade de dividir
o código em módulos ou funções menores torna o código mais organizado e facilita a manutenção
e reutilização de código. Como destaca Knuth (1997), a programação é a arte de explicar a um
computador o que queremos que ele faça para nós. A modularização é uma das ferramentas que torna
essa comunicação mais clara e eficiente.
Essa disciplina também ensina a manipulação de estruturas de dados mais avançadas, como listas
e dicionários. Essas estruturas permitem o armazenamento e a manipulação de conjuntos de dados de
maneira eficiente. Com listas, os alunos aprendem a trabalhar com sequências ordenadas de elementos,
enquanto os dicionários introduzem o conceito de pares chave-valor, ampliando as possibilidades de
organização e acesso aos dados.
A entrada e saída de dados são aspectos práticos que conectam os programas ao mundo exterior.
Aprender a ler dados do teclado ou de arquivos permite que os programas interajam com o usuário e
processem informações provenientes de diferentes fontes. Essa interação é essencial para desenvolver
aplicações úteis e relevantes no mundo real.
A depuração e o teste de algoritmos são habilidades cruciais para qualquer programador. Identificar
e corrigir erros é parte inevitável do processo de desenvolvimento. Introduziremos técnicas de depuração
em Python e testes automatizados simples. Essas práticas garantem que os programas funcionem
conforme o esperado e atendam aos requisitos estabelecidos.
9
Por fim, a introdução à programação orientada a objetos (POO) em Python amplia ainda mais o
horizonte dos estudantes. A POO é um paradigma que modela os programas como uma coleção de
objetos que interagem entre si. Esse modelo reflete de maneira mais fiel o mundo real e permite a
criação de programas mais flexíveis e extensíveis. Como mencionado por Booch (1994), a programação
orientada a objetos é uma técnica que se baseia no uso de objetos que interagem através de mensagens.
Para concluir, convém destacar que esta disciplina desempenha um papel crucial no início deste
curso, pois estabelece os fundamentos essenciais para a compreensão da programação e da lógica
computacional. Ao introduzir conceitos básicos de algoritmos, estruturas de controle e manipulação
de dados utilizando Python, ela prepara os alunos para enfrentar desafios mais complexos nas etapas
posteriores do curso. Essa base sólida em lógica de programação é indispensável para entender as
disciplinas avançadas.
10
INTRODUÇÃO
O avanço tecnológico nas últimas décadas transformou profundamente a forma como interagimos
com o mundo ao nosso redor. Computadores e dispositivos digitais tornaram-se onipresentes,
desempenhando papéis cruciais em diversas áreas, desde a saúde até a economia global. Nesse contexto,
compreender os fundamentos que permitem a esses dispositivos executarem tarefas complexas é
essencial para qualquer estudante de computação. Este livro-texto tem como objetivo introduzir você
aos conceitos vitais de lógica de programação, utilizando a linguagem Python como ferramenta para
materializar essas ideias.
A lógica de programação é a base sobre a qual todos os programas de computador são construídos.
Trata-se de um conjunto de princípios e técnicas que permitem a resolução sistemática de problemas
por meio de algoritmos. Um algoritmo, por sua vez, é uma sequência finita de instruções bem definidas
e não ambíguas, destinadas a resolver uma classe de problemas ou executar uma tarefa específica.
A capacidade de elaborar algoritmos eficientes é uma habilidade central para qualquer programador,
pois determina a eficácia e a eficiência dos programas desenvolvidos.
No entanto, antes de mergulharmos nos detalhes da programação em si, é fundamental entender
o que é um computador e como ele processa informações. Um computador é uma máquina capaz de
receber, processar e armazenar dados, seguindo instruções pré-definidas. Essas instruções são escritas
em linguagens de programação, que servem como intermediárias entre o pensamento humano e a
linguagem binária compreendida pelos computadores. Python é uma dessas linguagens, conhecida por
sua sintaxe clara e legibilidade, o que a torna especialmente adequada para iniciantes.
Python se destaca por ser uma linguagem de alto nível e multiparadigma, suportando programação
estruturada, orientada a objetos e funcional. Sua simplicidade sintática não diminui seu poder; pelo
contrário, permite que os programadores se concentrem na resolução de problemas em vez de se
preocuparem com detalhes técnicos excessivos. Além disso, Python tem uma ampla comunidadeC) O programa imprime Match encontrado!, permite a troca de mensagens e, se a resposta
for ”não”, imprime Ok, talvez em outra ocasião.
D) O programa configura um encontro independentemente da resposta do usuário.
E) O programa entra em um loop infinito se a resposta for “não”, pois a condição de “match” é
sempre verdadeira.
Resposta correta: alternativa C.
Análise das alternativas
A) Alternativa incorreta.
Justificativa: o programa explicitamente imprime Ok, talvez em outra ocasião. após
receber a resposta “não”.
76
Unidade I
B) Alternativa incorreta.
Justificativa: o código verifica se há um match com “Maria”, mas não rejeita automaticamente
outros perfis. A função verificar_match pode, teoricamente, permitir matches com outros perfis,
dependendo de sua implementação.
C) Alternativa correta.
Justificativa: aqui temos o teste do entendimento sobre estruturas condicionais (if, else), a
manipulação de strings (lower()) e o fluxo lógico básico de um programa Python, o que é apropriado
para avaliar conhecimentos básicos em programação. Esta alternativa aciona a cláusula else do if
mais externo em consonância com a identação do código.
D) Alternativa incorreta.
Justificativa: o programa só configura um encontro se a resposta for “sim”. Se a resposta for “não”,
ele imprimirá uma mensagem diferente e não configurará o encontro.
E) Alternativa incorreta.
Justificativa: apresenta erro, uma vez que não há indicação de um loop no código fornecido.
A pergunta sobre configurar um encontro é feita uma vez, e o fluxo do programa continua com base na
resposta, sem repetição, a menos que todo o processo seja reiniciado externamente.e uma
vasta coleção de bibliotecas, o que facilita a expansão de programas para áreas como ciência de dados,
desenvolvimento web e IA.
Este livro-texto está estruturado para conduzi-lo desde os conceitos mais básicos até tópicos mais
avançados, sempre enfatizando a aplicação prática dos conhecimentos adquiridos. Iniciamos com uma
introdução à lógica de programação, algoritmos, pseudocódigos e fluxogramas. Esses conceitos são
vitais para saber como desenvolver uma solução passo a passo para um problema dado. O pseudocódigo
e os fluxogramas são ferramentas que auxiliam na representação dessas soluções de forma abstrata,
antes mesmo de serem implementadas em uma linguagem de programação.
Em seguida, introduzimos a linguagem Python e você terá o primeiro contato com a sintaxe e
a estrutura de um programa simples. Abordaremos conceitos como variáveis, que são espaços na
memória do computador destinados a armazenar valores que podem variar durante a execução do
programa. Também exploraremos os diferentes tipos de dados, como números e strings (textos), e como
manipulá-los utilizando operadores aritméticos e lógicos.
11
As estruturas de controle são outro pilar da programação. Elas permitem que o fluxo de execução
de um programa seja alterado com base em condições específicas ou que certas instruções sejam
repetidas múltiplas vezes. Abordaremos as estruturas de decisão, como if, else e elif, que permitem que o
programa tome diferentes caminhos de acordo com determinadas condições. Além disso, exploraremos
as estruturas de repetição, como for e while, que são essenciais para a iteração e o processamento de
coleções de dados.
A modularização é um conceito que promove a organização e a reutilização de código por meio
de funções. Uma função é um bloco de código que realiza uma tarefa específica e pode ser chamado
várias vezes ao longo do programa. Discutiremos como criar e utilizar funções em Python, incluindo a
passagem de parâmetros e o retorno de valores. Isso não apenas torna o código mais limpo e legível,
mas também facilita a manutenção e a expansão de programas mais complexos.
Avançando, entraremos na manipulação de estruturas de dados mais sofisticadas, como listas e
dicionários. Listas são coleções ordenadas de elementos que podem ser acessados e modificados de forma
dinâmica. Dicionários, por sua vez, são estruturas que armazenam pares de chave e valor, permitindo
um acesso mais eficiente aos dados. Compreender essas estruturas é crucial para lidar com conjuntos de
dados mais complexos e para implementar algoritmos mais elaborados.
A entrada e saída de dados são aspectos práticos que permitem a interação do programa com o
mundo externo. Acentuaremos como receber dados do usuário através do teclado e como escrever
e ler dados em arquivos. Isso amplia significativamente as capacidades dos programas, permitindo
o armazenamento persistente de informações e a interação dinâmica com o usuário.
Depurar e testar algoritmos é uma etapa fundamental no desenvolvimento de software. Erros e bugs
são inevitáveis, e saber identificá-los e corrigi-los é uma habilidade essencial. Discutiremos técnicas de
depuração em Python e como criar testes automatizados simples para verificar se as funcionalidades
do programa estão operando conforme o esperado. Isso garante a confiabilidade e a robustez do
software desenvolvido.
Introduziremos também os conceitos básicos de POO em Python. A POO é um paradigma que
organiza o software em objetos que têm atributos e métodos, refletindo melhor as entidades do mundo
real. Estudaremos a definição de classes, a criação de objetos e conceitos como encapsulamento,
que controla o acesso aos dados internos de um objeto. Embora seja um tópico mais avançado, uma
compreensão básica da POO é essencial para desenvolver um software moderno.
Este livro-texto não requer nenhum conhecimento prévio de programação ou de como um
computador funciona. Todos os conceitos são introduzidos de forma gradual e acompanhados de
exemplos práticos que facilitam a compreensão. O objetivo é capacitá-lo a pensar de forma lógica e
estruturada, desenvolvendo a habilidade de resolver problemas computacionais por meio da elaboração
e implementação de algoritmos eficientes.
12
Ao final desta jornada, espera-se que você seja capaz de:
• Compreender os fundamentos da lógica de programação e como eles se aplicam na resolução
de problemas.
• Desenvolver algoritmos simples utilizando estruturas sequenciais, condicionais e de repetição.
• Implementar soluções de problemas na linguagem Python, usando suas estruturas fundamentais.
• Trabalhar com variáveis, tipos de dados e operadores para manipular informações de forma eficaz.
• Aplicar o conceito de modularização por meio da criação e utilização de funções.
• Manipular listas e dicionários para gerenciar conjuntos de dados complexos.
• Interagir com o usuário e com o sistema de arquivos através de operações de entrada e
saída de dados.
• Depurar e testar programas, identificando e corrigindo erros de lógica.
• Ter uma visão inicial da POO e de como ela pode ser adotada em Python.
A aprendizagem da programação é um processo contínuo que requer prática e perseverança.
Encorajam-se a experimentação e a exploração além dos exemplos fornecidos. Python é uma linguagem
com vastos recursos e uma comunidade ativa, o que significa que há sempre novas ferramentas e
técnicas a serem descobertas.
Em resumo, este livro-texto é um guia introdutório que visa fornecer os alicerces para o pensamento
computacional e a programação em Python. Ao desenvolver essas habilidades, você estará preparado
para enfrentar desafios mais complexos no campo da computação e contribuir para o avanço tecnológico
que molda o futuro.
Vamos começar esta jornada explorando os fundamentos da lógica de programação, entendendo
como algoritmos são concebidos e como podemos representá-los de forma clara e precisa antes de
traduzi-los para código executável. Com uma base sólida, a transição para a implementação em Python
será natural e intuitiva, permitindo que o leitor veja concretamente os resultados de seus esforços.
13
PENSAMENTO LÓGICO COMPUTACIONAL COM PYTHON
Unidade I
1 INTRODUÇÃO À LÓGICA DE PROGRAMAÇÃO E PYTHON
A lógica de programação é o pilar para quem deseja ingressar no campo da computação e do
desenvolvimento de software. Ela possibilita a criação de soluções eficientes por meio de sequências
estruturadas de passos lógicos. Ferramentas como algoritmos, pseudocódigos e fluxogramas
desempenham um papel crucial nesse processo, permitindo a representação e análise das soluções
antes de sua implementação em linguagens como Python. Essas ferramentas fortalecem a capacidade
de planejar e organizar a lógica, que é a base para resolver problemas de maneira sistemática.
Os algoritmos, considerados a essência da programação, são conjuntos de instruções finitas e
bem definidas que conduzem à resolução de um problema específico. A criação de algoritmos requer
uma análise detalhada do problema e das etapas necessárias para solucioná-lo, buscando eficiência,
legibilidade e correção. O pseudocódigo, por sua vez, oferece uma forma simplificada de representar
algoritmos, livre de restrições sintáticas, permitindo foco na lógica e facilitando a comunicação e o
planejamento no desenvolvimento de software.
Os fluxogramas complementam o pseudocódigo ao apresentar o fluxo de execução de um algoritmo
de maneira visual, por meio de símbolos padronizados que representam processos, decisões e operações.
Essa abordagem gráfica ajuda a identificar possíveis falhas e otimizações antes da codificação,
promovendo um raciocínio estruturado. Juntas, essas ferramentas fornecem uma base sólida para a
construção de soluções computacionais claras e eficazes.
A linguagem Python, amplamente utilizada devido à sua simplicidade e versatilidade, desempenha
um papel vital no ensino e na aplicação da lógica de programação. Com uma sintaxe legível,bibliotecas
robustas e suporte multiplataforma, Python facilita a implementação prática de conceitos de lógica e
algoritmos. Sua popularidade, especialmente em áreas como ciência de dados e desenvolvimento web,
reflete sua capacidade de atender às demandas de um mundo tecnológico em constante evolução,
tornando-a ideal tanto para iniciantes quanto para profissionais experientes.
Nesse tópico estudaremos em detalhes tais conceitos, cruciais para a formação de bons profissionais
na área da computação.
14
Unidade I
1.1 Conceitos de lógica, algoritmos, pseudocódigo e fluxogramas
A lógica de programação é o alicerce fundamental para qualquer indivíduo que deseja ingressar no
universo da computação e desenvolvimento de software. Ela permite que os programadores elaborem
soluções eficientes e eficazes para problemas complexos, utilizando-se de sequências de passos lógicos
bem estruturados. Compreender os conceitos de algoritmos, pseudocódigo e fluxogramas é essencial
nesse contexto, pois essas ferramentas auxiliam na representação e análise das soluções antes mesmo
de serem codificadas em uma linguagem específica, como o Python.
A lógica, em seu sentido mais amplo, é a ciência que estuda as formas e leis do pensamento humano,
visando distinguir raciocínios válidos dos inválidos. Na programação, a lógica é aplicada para desenvolver
sequências coerentes de instruções que conduzem à solução de um problema. A habilidade de pensar
logicamente permite ao programador decompor um problema em partes menores e mais manejáveis,
facilitando a criação de algoritmos eficientes.
Observe essa conversa hipotética entre o filosofo Sócrates e um discípulo:
Destaque
Sócrates: O que é a coragem?
Discípulo: A coragem é enfrentar os perigos sem medo.
Sócrates: Interessante. Então, uma pessoa que corre em direção a um leão faminto
sem sentir medo seria corajosa?
Discípulo: Sim, claro.
Sócrates: Mas e se essa pessoa não souber que o leão é perigoso? Ela ainda
seria corajosa?
Discípulo: Hum... talvez não. A coragem deve envolver conhecimento do perigo.
Sócrates: Então, você diria que a coragem não é apenas enfrentar algo, mas saber que
é perigoso e ainda assim enfrentá-lo?
Discípulo: Sim, isso faz sentido.
Sócrates: Muito bem. Agora, imagine um soldado que conhece os perigos da guerra,
mas foge do campo de batalha porque acredita que sua morte seria inútil. Essa pessoa
seria corajosa?
15
PENSAMENTO LÓGICO COMPUTACIONAL COM PYTHON
Discípulo: Não, fugir não é coragem.
Sócrates: Então, coragem significa sempre enfrentar o perigo, mesmo que a situação
não tenha esperança de sucesso?
Discípulo: Acho que não. Talvez haja situações em que recuar seja a coisa certa a fazer.
Sócrates: Fascinante. Então, parece que a coragem envolve mais do que simplesmente
enfrentar perigos. Talvez tenha a ver com decidir corretamente quando agir e quando
não agir.
Discípulo: Sim, coragem deve incluir sabedoria para distinguir entre o que é útil e o
que é tolice.
Sócrates: Portanto, diríamos que a coragem é agir de maneira sábia diante do perigo,
sem ser paralisado pelo medo ou impulsivo na ação?
Discípulo: Sim, acho que é isso!
Adaptado de: Platão (2007).
A lógica computacional por trás do diálogo socrático sobre coragem pode ser compreendida ao
observar como as perguntas e respostas seguem um processo de análise sequencial e condicional,
características fundamentais de um raciocínio programático. Em termos simples, a lógica computacional
busca organizar e estruturar pensamentos de maneira sistemática, avaliando condições e
tomando decisões com base nos resultados dessas avaliações. Esse mesmo processo está presente
no método socrático, que pode ser traduzido para uma abordagem lógica.
No início do diálogo, Sócrates propõe uma questão inicial: o que é a coragem? A resposta dada pelo
interlocutor é avaliada com um cenário hipotético que testa a validade da definição apresentada. Esse é
o equivalente a verificar uma hipótese em um sistema lógico, no qual cada nova condição introduzida
refina ou invalida a definição inicial. Por exemplo, ao perguntar se alguém que enfrenta um leão sem
conhecer o perigo é corajoso, Sócrates apresenta uma situação que obriga o interlocutor a reconsiderar
sua ideia inicial. Esse processo é semelhante à construção de um raciocínio condicional, no qual cada
nova informação modifica a análise e ajusta o resultado.
Ao longo do diálogo, Sócrates introduz mais cenários e variáveis que desafiam a ideia inicial. Isso
reflete como a lógica computacional lida com diferentes possibilidades e ramificações de um problema.
Cada cenário apresentado equivale a uma nova condição a ser avaliada, no qual a resposta determina
qual caminho lógico será seguido. Quando Sócrates pergunta sobre o soldado que recua, ele introduz
uma nova perspectiva, obrigando o interlocutor a combinar informações anteriores e reconsiderar
o que havia sido concluído até então. Esse é o processo de construção de regras que interagem de
maneira cumulativa, algo essencial em qualquer sistema lógico.
16
Unidade I
Outro aspecto computacional no diálogo é a busca por generalização. Sócrates não se contenta com
respostas específicas, mas orienta o interlocutor a criar uma definição que seja ampla o suficiente para
abranger diferentes cenários, mas ainda coerente e precisa. Esse processo é semelhante à abstração
em lógica computacional, no qual se busca um princípio geral que pode ser aplicado a uma variedade
de situações, sem contradições. Aqui, a coragem começa como “enfrentar perigos sem medo” e evolui
para “agir sabiamente diante do perigo”, uma definição que é mais abrangente e consistente com os
cenários acentuados.
A lógica computacional presente no método socrático ensina que as decisões não devem ser
tomadas de maneira arbitrária, mas devem seguir regras claras e consistentes. Cada pergunta de
Sócrates corresponde a uma etapa de validação de hipóteses, e cada resposta do interlocutor ajusta ou
refina a “solução” final. Esse é o mesmo processo que ocorre em algoritmos: a resolução de um problema
é alcançada por meio de uma série de passos lógicos, nos quais cada decisão depende das condições
estabelecidas e dos resultados obtidos anteriormente.
O diálogo mostra, portanto, como a lógica computacional é uma ferramenta técnica e uma
extensão do pensamento humano estruturado. A forma como Sócrates conduz a conversa reflete o
princípio fundamental de pensar sistematicamente sobre um problema, avaliando cenários, ajustando
hipóteses e buscando soluções que sejam coerentes e aplicáveis em diferentes contextos. Esse processo
de raciocínio lógico é a base tanto para a programação quanto para o método filosófico socrático.
O termo lógica tem sua origem na palavra grega logos, que tem uma ampla gama de significados,
incluindo “razão”, “discurso”, “palavra” e “pensamento”. Na Grécia Antiga, filósofos como Aristóteles
desenvolveram a lógica como um campo formal de estudo, estabelecendo as bases para o raciocínio
dedutivo, que consiste em partir de premissas gerais para chegar a conclusões específicas. Por exemplo,
na famosa forma de argumento conhecida como silogismo, diz-se: “Todos os homens são mortais.
Sócrates é um homem. Logo, Sócrates é mortal”. Essa estrutura demonstra como essas premissas levam
a uma conclusão inevitável (“Sócrates é mortal”), desde que sejam verdadeiras e estejam conectadas de
maneira válida.
A lógica evoluiu ao longo dos séculos, passando de uma ferramenta filosófica para uma linguagem
formalizada usada em matemática e computação. Na Idade Média, foi amplamente estudada por
filósofos e teólogos, que aprofundaram seu uso em argumentações complexas. Mais tarde, no século XIX,
matemáticos como George Boole e Gottlob Frege transformaram a lógica em uma disciplina formal e
simbólica, criando a base para a lógica matemática, que seria fundamental para o desenvolvimento da
ciência da computação.
Já os algoritmos são a essência da programação. Elessão definidos como um conjunto finito de
instruções bem definidas e ordenadas que, quando executadas, resolvem um problema específico.
A elaboração de um algoritmo requer uma compreensão profunda do problema a ser solucionado, bem
como das etapas necessárias para chegar à solução. Um bom algoritmo deve ser correto (produzir o
resultado esperado), eficiente (utilizar recursos de forma otimizada) e legível (ser compreensível por
outros programadores).
17
PENSAMENTO LÓGICO COMPUTACIONAL COM PYTHON
Utilizar recursos de
forma otimizada
Produzir o
resultado esperado
Ser compreensível por
outros programadores
Algoritmo
Figura 1 – Características de um bom algoritmo
Observação
A palavra algoritmo tem origem no nome de um matemático persa
chamado Muhammad ibn Musa al-Khwarizmi, que viveu entre os
séculos VIII e IX. Ele é reconhecido como um dos fundadores da álgebra
e escreveu um tratado matemático intitulado Kitab al-Mukhtasar fi Hisab
al-Jabr wal-Muqabala, que introduziu conceitos fundamentais na resolução
de equações lineares e quadráticas. Esse trabalho teve grande influência na
matemática europeia medieval após sua tradução para o latim.
O nome al-Khwarizmi foi transliterado para o latim como algoritmi.
Com o tempo, a expressão passou a ser associada aos procedimentos
sistemáticos descritos em suas obras e evoluiu para “algoritmo”, que hoje
designa qualquer sequência de passos finitos e bem definidos para resolver
um problema ou realizar uma tarefa. Essa transformação linguística
demonstra a influência histórica e cultural do trabalho de al-Khwarizmi na
ciência e na tecnologia modernas.
Um algoritmo é uma série de instruções passo a passo projetadas para executar uma tarefa específica.
No exemplo prático de uma criança que derruba leite com chocolate no chão da sala, o algoritmo para
resolver o problema pode ser estruturado da seguinte maneira:
• Identificar o problema: a criança nota que o leite com chocolate foi derramado e observa que a
sujeira se espalhou pelo chão e possivelmente atingiu os móveis próximos.
• Informar um adulto: antes de tentar resolver o problema, a criança deve informar um adulto
sobre o incidente, pois ela precisa de supervisão para usar qualquer material de limpeza necessário.
18
Unidade I
• Coletar materiais de limpeza: sob supervisão de um adulto, a criança ajuda a reunir os materiais
necessários como papel-toalha ou um pano limpo e seco.
• Absorver o líquido: a criança usa o papel-toalha ou o pano para absorver cuidadosamente o leite
do chão, pressionando sobre o líquido derramado sem esfregar para evitar espalhar a sujeira.
• Limpar as superfícies atingidas: se o leite espirrou nos móveis, a criança pode usar outro pano
seco para limpar suavemente as superfícies afetadas.
• Secar as áreas que foram limpas: a criança usa um pano seco para passar sobre o chão e sobre
qualquer móvel que tenha sido limpo, garantindo que todas as superfícies estejam secas.
• Avaliar o resultado: finalmente, a criança, com o adulto, verifica se toda a área afetada está
limpa e sem resíduos de leite ou marcas.
• Guardar os materiais: os materiais de limpeza são guardados de volta em seus lugares apropriados,
preferencialmente pelo adulto, para garantir que tudo seja armazenado de forma segura.
Esse conjunto de etapas forma um algoritmo, que é uma sequência ordenada de instruções que resolve
o problema de derramamento de leite de forma segura e eficaz. Algoritmos como esse são essenciais em
muitas situações, facilitando a execução de tarefas com clareza e eficiência. Note que inverter etapas
de um algoritmo pode levar a situações absurdas ou completamente ilógicas, especialmente quando a
sequência foi projetada para cumprir requisitos específicos. No exemplo do derramamento de leite com
chocolate, algumas inversões que violariam a lógica incluem:
• Guardar os materiais antes de usá-los: se os materiais de limpeza forem guardados antes de
a limpeza estar concluída, a criança teria que interromper a tarefa para buscá-los novamente,
tornando o processo redundante e ineficaz. Pior ainda, poderia encerrar o processo sem
resolver o problema.
• Secar as áreas antes de limpar as superfícies atingidas: secar móveis ou o chão que ainda
estejam sujos não faz sentido, pois a sujeira permaneceria no local e poderia até espalhar-se mais
ao ser manipulada com um pano seco.
• Avaliar o resultado antes de coletar os materiais de limpeza: tentar verificar se a área está
limpa sem ter sequer começado a limpar seria inútil. A inspeção seria prematura e provavelmente
levaria à conclusão óbvia de que o problema ainda persiste.
• Informar o adulto apenas no final do processo: esperar até que todo o incidente esteja
resolvido para contar a um adulto não só compromete a segurança, mas também pode levar a
um resultado inadequado, já que a criança pode não saber manusear os materiais corretamente
ou deixar resíduos que passam despercebidos sem supervisão.
19
PENSAMENTO LÓGICO COMPUTACIONAL COM PYTHON
• Coletar materiais de limpeza depois de tentar absorver o líquido: essa inversão cria uma
situação absurda na qual a criança tenta limpar sem as ferramentas necessárias, possivelmente
usando as mãos ou qualquer objeto inadequado ao alcance, o que apenas agravaria o problema.
Esses exemplos mostram como a ordem das etapas em um algoritmo deve seguir uma sequência
lógica e dependente, na qual cada passo prepara o terreno para o seguinte. Inverter etapas sem respeitar
essa lógica pode tornar o processo ineficiente, redundante ou até inviável.
Agora suponha que você quer ensinar seu sobrinho de 9 anos a calcular a média de um conjunto
de números. Você irá criar um algoritmo simples e claro que o guie pelas etapas necessárias de forma
compreensível. Vamos considerar um exemplo prático no qual seu sobrinho tenha cinco números e
deseja calcular a média:
• Reunir os números: primeiro, a criança deve escrever ou listar todos os números dos quais deseja
calcular a média. Por exemplo, os números podem ser 4, 8, 6, 10 e 2.
• Somar todos os números: a criança deve somar todos os números da lista. Isso significa adicionar
cada número um ao outro. Para os números dados, a soma seria: 4 + 8 + 6 + 10 + 2 = 30.
• Contar quantos números foram reunidos: a criança precisa contar quantos números há na
lista. Em nosso exemplo, existem cinco números.
• Dividir a soma pelo total de números: para encontrar a média, a criança deve dividir a soma
total dos números pelo total de números que foram somados. No exemplo, ela dividiria 30 (a soma)
por 5 (o total de números): 30 ÷ 5 = 6.
• Escrever o resultado: o resultado da divisão é a média. A criança deve anotar que a média dos
números 4, 8, 6, 10 e 2 é 6.
Esse algoritmo ensina seu sobrinho a calcular a média de uma forma que ele possa entender
claramente cada passo do processo, aplicando aritmética básica de uma maneira estruturada e ordenada.
Para facilitar a elaboração e compreensão de algoritmos, utiliza-se frequentemente o pseudocódigo,
que é uma representação textual simplificada de um algoritmo, utilizando uma linguagem próxima do
natural. Ele não segue a sintaxe rígida de uma linguagem de programação específica, o que permite ao
programador concentrar-se na lógica do algoritmo sem se preocupar com detalhes de implementação.
O pseudocódigo é especialmente útil em ambientes educacionais e na fase de planejamento
de projetos, pois facilita a comunicação entre membros da equipe e a transição para a codificação
efetiva. Ele é usado para descrever algoritmos de forma que possam ser facilmente compreendidos,
independentemente do conhecimento específico de uma linguagem de programação.
20
Unidade I
Vamos transformar o algoritmo de calcular a média de um conjunto de números em pseudocódigo:
Início
// Passo 1: Reunir os números
Lista_de_Números := [4, 8, 6, 10, 2]
// Passo 2: Somar todos os números
Soma := 0
Para cada Número em Lista_de_Números faça
Soma := Soma+ Número
Fim Para
// Passo 3: Contar quantos números existem
Total_de_Números := tamanho de Lista_de_Números
// Passo 4: Dividir a soma pelo total de números
Média := Soma / Total_de_Números
// Passo 5: Escrever o resultado
Escrever “A média dos números é: “, Média
Fim
O quadro a seguir explica cada parte do pseudocódigo que descrevemos para calcular a média de
um conjunto de números:
Quadro 1 – Elementos de um pseudocódigo
Elemento Descrição
Comentários //: usado para adicionar comentários, que são notas que explicam o que o código faz, mas que não
são executadas. No pseudocódigo, tudo após // é apenas para esclarecimento e não afeta a execução
Variáveis Lista_de_Números := [4, 8, 6, 10, 2]: define uma lista de números. A variável Lista_de_Números
armazena esses valores. O símbolo := é usado para atribuir valores a uma variável
Inicialização Soma := 0: inicializa a variável Soma com o valor zero. Isso prepara a variável para ser usada na
soma dos números
Estruturas de
repetição (loops)
Para cada Número em Lista_de_Números faça: esse comando inicia um loop que passa por cada
elemento na lista Lista_de_Números. Para cada elemento (chamado aqui de Número), o loop
executa o bloco de código que segue até que todos os elementos tenham sido processados. Fim
Para: Marca o fim do bloco de código que deve ser repetido no loop
Operações
matemáticas
Soma := Soma + Número: dentro do loop, cada número da lista é adicionado à soma atual. Isso é
feito até que todos os números sejam somados
Funções e operações
de lista
Total_de_Números := tamanho de Lista_de_Números: calcula quantos números estão na lista
usando a função tamanho, que retorna o número de elementos na lista
Divisão Média := Soma / Total_de_Números: calcula a média dividindo a soma total pelo número de
elementos na lista
Saída de dados Escrever “A média dos números é: “, Média: exibe a média calculada. O comando Escrever é usado
para mostrar resultados ou mensagens
Vale a pena também detalharmos alguns conceitos importantes que foram usados no quadro 1:
• Variável: uma variável é como uma caixa na qual você pode guardar valores que deseja usar
mais tarde em seu programa. No contexto do pseudocódigo, quando dizemos Lista_de_
Números := [4, 8, 6, 10, 2], estamos colocando a lista de números [4, 8, 6, 10, 2]
dentro de uma “caixa” chamada Lista_de_Números, para que possamos acessá-la e usá-la
quando precisarmos.
21
PENSAMENTO LÓGICO COMPUTACIONAL COM PYTHON
• Atribuir a uma variável: significa colocar um valor dentro dessa “caixa”. No exemplo anterior,
atribuímos a lista de números à variável Lista_de_Números. Isso é feito usando o símbolo :=,
que pode ser pensado como uma seta apontando para a variável, indicando “coloque este valor
aqui”. Um caixa que não foi atribuída ainda pode conter um valor aleatório (uma espécie de
“lixo”, que explicaremos melhor após falarmos dos fluxogramas).
• Inicialização (por que fazer Soma:=0 ?): inicializar uma variável, como Soma := 0, significa
dar a ela um valor inicial antes de começar a usá-la. No caso de Soma, começamos com
zero porque queremos adicionar a ela os números de nossa lista. Se não começássemos com zero,
Soma poderia conter qualquer valor aleatório deixado na caixa (ou seja, lixo), o que afetaria o
resultado da média.
• Loop: um loop, ou laço, é uma parte do pseudocódigo que repete um bloco de passos várias vezes.
No pseudocódigo, Para cada Número em Lista_de_Números faça é um exemplo
de loop. Ele diz ao programa para executar um conjunto de ações para cada número na lista
Lista_de_Números. Nesse caso, ele repete a ação de adicionar cada número à soma total
(Soma := Soma + Número). O loop continua repetindo até que todos os números na lista
tenham sido processados.
A figura a seguir mostra como os valores evoluem dentro das variáveis (caixas) Lista_de_Números,
Soma, Total_de_Números e Média:
Lista_de_Números =
[4, 8, 6, 10, 2], Soma = 0
Soma = 0 + 4 = 4
Soma = 4 + 8 = 12
Soma = 12 + 6 = 18
Soma = 18 + 10 = 28
Soma = 28 + 2 = 30
Total_de_Números = 5,
Média = Soma / Total =
30 / 5 = 6
Figura 2 – Evolução dos valores nas variáveis ao longo da execução do pseudocódigo
22
Unidade I
Você deve ter observado que esse pseudocódigo, da forma que está escrito, só funciona para os
números 4, 8, 6, 10 e 2 e que o resultado da média é sempre igual a 6. Vamos alterar esse pseudocódigo
para que aceite qualquer quantidade de números e calcule a média desses números. Em matemática
dizemos que vamos calcular a média de n números, onde n é a quantidade de números.
Início
// Passo 1: Reunir os números
Escrever “Digite a quantidade de números que deseja calcular a média:”
Total_de_Números := Ler entrada do usuário
Lista_de_Números := []
Para i de 1 até Total_de_Números faça
Escrever “Digite o número “, i, “:”
Número := Ler entrada do usuário
Adicionar Número à Lista_de_Números
Fim Para
// Passo 2: Somar todos os números
Soma := 0
Para cada Número em Lista_de_Números faça
Soma := Soma + Número
Fim Para
// Passo 3: Contar quantos números existem
// Já sabemos que Total_de_Números foi fornecido pelo usuário
// Passo 4: Dividir a soma pelo total de números
Média := Soma / Total_de_Números
// Passo 5: Escrever o resultado
Escrever “A média dos números é: “, Média
Fim
As alterações realizadas no pseudocódigo original foram feitas para que o pseudocódigo pudesse
aceitar números inseridos pelo usuário, tornando-o mais flexível e interativo. No pseudocódigo inicial,
os números eram fixos e predefinidos em uma lista, o que significava que o programa sempre trabalharia
com o mesmo conjunto de valores. A atualização permitiu que o usuário decidisse quantos números
gostaria de calcular e fornecesse os valores manualmente, adaptando o programa para lidar com
diferentes entradas em cada execução.
A primeira modificação foi incluir um momento no início do programa para que o usuário indicasse a
quantidade de números que deseja utilizar no cálculo da média. Essa informação é armazenada em uma
variável chamada Total_de_Números. A partir disso, um processo foi adicionado para permitir
que o programa peça ao usuário os números um por um. À medida que o usuário fornece os valores,
eles são inseridos em uma lista chamada Lista_de_Números, que serve para armazenar todos os
números que serão usados no cálculo.
23
PENSAMENTO LÓGICO COMPUTACIONAL COM PYTHON
No pseudocódigo original, o tamanho da lista era contado automaticamente após ser predefinida. No
entanto, com a nova abordagem, essa contagem não é mais necessária, pois a quantidade de números é
informada pelo próprio usuário no início. Essa perspectiva simplifica o cálculo, pois o programa já sabe
quantos números existem e pode usá-los diretamente para dividir a soma total.
O restante do algoritmo permanece praticamente inalterado. Após a coleta dos números, o programa
soma todos os valores da lista, divide a soma pelo total de números informado pelo usuário e exibe a
média. Essas etapas são as mesmas do pseudocódigo original, mas agora a flexibilidade permite que o
programa se adapte a diferentes entradas fornecidas pelo usuário, em vez de trabalhar com valores fixos.
Essa alteração transforma o programa de algo estático em uma ferramenta dinâmica e personalizável,
permitindo que ele se adeque a diferentes necessidades e situações. Para quem está aprendendo
programação, a nova versão demonstra como criar programas que interajam com os usuários e respondam
às suas entradas, o que é um dos fundamentos da construção de softwares úteis e funcionais.
O fluxograma é outra ferramenta valiosa no desenvolvimento de algoritmos. Ele é um diagrama
que representa graficamente o fluxo de execução de um algoritmo, utilizando símbolos padronizados
para indicar operações, decisões, entradas e saídas. Os fluxogramas ajudam a visualizar a estrutura
do algoritmo, identificandofacilmente caminhos alternativos, loops e processos sequenciais. Isso é
particularmente útil na identificação de possíveis erros lógicos e na otimização do algoritmo antes de
sua implementação.
Ao utilizar fluxogramas, o programador é incentivado a pensar de forma estruturada, organizando
o algoritmo de maneira lógica e coerente. Essa prática facilita a implementação posterior em uma
linguagem de programação e melhora a comunicação com outros membros da equipe ou partes
interessadas que possam não ter conhecimento técnico aprofundado.
A ISO 5807 é uma norma internacional que trata da documentação e representação de diagramas
de fluxo de informações, fluxogramas e gráficos de processo no contexto da informática. Criada pela
Organização Internacional de Normalização (ISO), ela foi concebida para padronizar a forma como
os processos e fluxos de trabalho são representados graficamente em sistemas computacionais e de
informação. O objetivo principal dessa padronização é facilitar a comunicação e o entendimento entre
diferentes profissionais e equipes, especialmente em ambientes técnicos e de engenharia de software.
A norma define símbolos, regras de disposição e convenções específicas que devem ser seguidas na
criação de diagramas. Esses elementos garantem a uniformidade e a clareza na indicação dos processos.
Exemplos incluem formas geométricas como retângulos, losangos e círculos, que são usados para representar
atividades, decisões e terminais de processos. Cada elemento gráfico tem um significado bem definido, o
que minimiza ambiguidades e permite a interoperabilidade entre diferentes ferramentas e metodologias.
A adoção da ISO 5807 é particularmente relevante em projetos que envolvem o desenvolvimento de
sistemas de informação e programas de computador. Esses diagramas são amplamente utilizados em
etapas como análise de requisitos, design de sistemas e documentação técnica. Além disso, a norma é
útil para mapear processos organizacionais e identificar melhorias no fluxo de trabalho.
24
Unidade I
Embora a ISO 5807 seja uma ferramenta valiosa para a padronização, sua utilização depende
do contexto e da complexidade do projeto. Organizações podem adaptá-la às suas necessidades,
combinando-a com outras normas e metodologias, como a UML (Unified Modeling Language), para
alcançar um nível maior de detalhamento e especificidade em suas representações. A figura a seguir
mostra os elementos de um fluxograma, conforme a norma ISO 5807:
Início
Preparação
Entrada
manual
Entrada
de dados
Processo
Condição?
Fim
Salvar
dados
Subprocesso
Operação
manual
Exibir
resultado
Gerar
relatório
Conector Conector
AA
NãoNão
SimSim
Continua
na pág. 2
Figura 3 – Elementos de um fluxograma
Agora detalharemos cada um desses elementos no quadro a seguir:
Quadro 2 – Descrição dos elementos de um fluxograma
Elemento Descrição Forma
Terminal (início/fim) Representa o início ou fim do fluxo Elipse
Processo Representa uma etapa ou ação Retângulo
Decisão Indica pontos de decisão no fluxo Losango
Entrada/Saída de dados Representa entrada ou saída de informações Paralelogramo
Conector Conecta fluxos em diferentes partes do diagrama Pequeno círculo
Conector fora de página Indica que o fluxo continua em outra página Pentágono invertido
Processo predefinido Representa sub-rotinas ou processos predefinidos Retângulo com linhas duplas
Preparação Indica etapas de preparação Hexágono
Entrada manual Representa entrada manual de dados Trapézio com base menor em cima
Operação manual Representa uma operação manual Trapézio com base maior em cima
Armazenamento de dados Representa bancos de dados ou armazenamento Cilindro
Documento Representa documentos Retângulo com base inferior ondulada
Exibição Representa exibição de informações, como em uma tela Retângulo com um lado aberto
Fluxo de dados Indica a direção do fluxo entre os símbolos Setas
25
PENSAMENTO LÓGICO COMPUTACIONAL COM PYTHON
A transformação de pseudocódigos em fluxogramas é uma prática comum na computação para
representar graficamente a lógica de um programa ou algoritmo. Ambos são ferramentas de modelagem
utilizadas para descrever o funcionamento de um sistema antes de sua implementação, mas atendem a
diferentes necessidades de clareza e compreensão.
O pseudocódigo é uma descrição textual que utiliza linguagem informal, próxima do natural, para
descrever a lógica de um algoritmo. Por ser conciso e legível, ele facilita a compreensão dos passos
necessários para resolver um problema, servindo como um intermediário entre a linguagem humana e a
linguagem de programação. No entanto, devido à sua natureza textual, pode ser desafiador compreender
a interação entre diferentes componentes do sistema em casos mais complexos.
Por outro lado, o fluxograma traduz os mesmos passos descritos no pseudocódigo em representações
gráficas usando formas geométricas padronizadas. Como vimos, cada forma tem um significado
específico, representando ações, decisões, entradas/saídas ou processos. Os fluxogramas destacam a
sequência e o fluxo de controle, facilitando a identificação de loops, condições e pontos críticos no
algoritmo. A figura a seguir ilustra o fluxograma do primeiro pseudocódigo que vimos:
Início
Escrever ‘A média
é: ´, Média
Lista_de_Números := [4, 8, 6, 10, 2]
Soma := 0
Soma := Soma + Número
Total_de_Números := tamanho de
Lista_de_Números
Média := Soma / Total_de_Números
Número em
Lista_de _Números?
Fim
NãoNão
SimSim
Figura 4 – Fluxograma que representa o pseudocódigo que calcula a média de cinco números
Transformar um pseudocódigo em um fluxograma envolve mapear cada linha ou bloco lógico do
pseudocódigo para um símbolo gráfico correspondente. Essa transformação tem várias vantagens.
Primeiramente, os fluxogramas oferecem uma visão mais visual e intuitiva, o que facilita a comunicação
26
Unidade I
entre equipes técnicas e não técnicas. Também ajudam na detecção precoce de problemas de lógica,
como loops infinitos ou condições mal definidas. Além disso, são úteis em apresentações ou em situações
nas quais o detalhamento textual do pseudocódigo pode ser menos acessível. A figura a seguir ilustra o
segundo pseudocódigo que vimos neste tópico:
Fim
NãoNão
NãoNão
SimSim
SimSim
Escrever ‘A média dos
números é :´ + Média
Média := Soma / Total_de_Números
Início
Escrever ‘Digite o
número´+ i + :´
Número := Ler
entrada do usuário
Escrever ´Digite a
quantidade de números que
deseja calcular a média:´
Total_de_Números :=
Ler entrada do usuário
Lista_de_Números := []
i := 1
Soma := 0
Soma := Soma + Número
i := i + 1
Adicionar Número à
Lista_de_Números
i1.2 Introdução à linguagem Python
Uma linguagem de programação é um conjunto estruturado de regras, símbolos e sintaxes utilizadas
para criar instruções que um computador pode interpretar e executar. Essas linguagens servem como
uma ponte entre o pensamento humano e as operações que um computador realiza, permitindo
que programadores desenvolvam software, controlem dispositivos (hardware) e processem informações
de forma automatizada. A figura a seguir dá destaque para essa ponte:
Linguagem de programação Desenvolver software Controlar dispositivos Processar informações
Regras, símbolos e sintaxes
Base para o desenvolvimento de
soluções computacionais
Ponte entre pensamento
humano e operações
computacionais
Lógica Algoritmos Pseudocódigo Fluxogramas
Figura 6 – A linguagem de programação é uma ponte entre o pensamento humano e as operações computacionais
28
Unidade I
A diferença entre hardware e software pode ser explicada de forma simples: o hardware é a parte física
de um computador, enquanto o software é a parte intangível, formada pelos programas e instruções
que fazem o hardware funcionar.
Imagine que o computador é como um corpo humano. O hardware seria como os órgãos e os
músculos – partes físicas que você pode ver e tocar, como monitor, teclado, mouse, processador, memória
e disco rígido. Já o software seria como a mente, que dá as instruções e controla como o corpo age. Sem
o software, o hardware seria apenas um monte de peças sem utilidade. Da mesma forma, o software
depende do hardware para “executar” suas ordens. Por exemplo:
• Quando você usa um celular para assistir a um vídeo, a tela, os botões e os alto-falantes são o
hardware. Já o aplicativo que reproduz o vídeo é o software.
• No caso de um carro moderno, o volante, os pedais e o motor são o hardware. O sistema que
controla os sensores, ajusta a velocidade ou até permite a direção autônoma é o software.
Observação
Hardware e software trabalham juntos. O hardware fornece a estrutura
para que o software funcione, enquanto o software dá vida ao hardware,
dizendo o que ele deve fazer. Sem um, o outro não pode operar plenamente.
Diferentemente da linguagem natural, que é ambígua e sujeita a interpretações variadas, as
linguagens de programação seguem uma sintaxe rigorosa que precisa ser obedecida para que o código
seja compreendido pelo computador.
A sintaxe em uma linguagem de programação é como as regras de gramática e ortografia em um
idioma que falamos. Assim como, ao escrever em português, precisamos colocar as palavras na ordem
certa, usar pontuação correta e respeitar as regras do idioma para que outras pessoas entendam, a
sintaxe na programação funciona de maneira parecida, mas com o objetivo de que o computador
entenda o que foi escrito.
Existem diversas linguagens de programação. Algumas estimativas, como da Online Historical
Encyclopaedia of Programming Languages (Disponível em: https://hopl.info/. Acesso em: 9 jan. 2025),
contabilizam quase 9 mil linguagens diferentes. Esse fenômeno se deve à variedade de problemas que
precisam ser resolvidos, às diferentes plataformas nas quais esses problemas ocorrem e às preferências
e abordagens dos desenvolvedores. Cada linguagem é projetada com objetivos específicos, que atendem
a necessidades distintas, desde a manipulação de hardware até o desenvolvimento de interfaces
sofisticadas. As razões para essa diversidade incluem, entre outros fatores:
29
PENSAMENTO LÓGICO COMPUTACIONAL COM PYTHON
• Especialização em domínios específicos: algumas linguagens são criadas para resolver
problemas em áreas específicas. Por exemplo:
— A linguagem C é excelente para desenvolvimento de sistemas operacionais e softwares que
precisam de alto desempenho e controle direto do hardware.
— Python é amplamente usado em IA, aprendizado de máquina e análise de dados por sua
simplicidade e vasta coleção de bibliotecas.
— SQL é específica para consultas e manipulação de bancos de dados.
• Abordagens diferentes para a resolução de problemas: as linguagens variam no estilo de
programação que suportam, como:
— Programação procedural (como em C), que foca sequências de instruções.
— POO (como em Java e C#), que organiza o código em objetos e classes para modelar o mundo real.
— Programação funcional (como em Haskell ou Lisp), que enfatiza a aplicação de funções
matemáticas e imutabilidade.
• Eficiência e desempenho: algumas linguagens são criadas para executar tarefas com
alta eficiência e rapidez, como C++ ou Rust, que são usadas em software de alto desempenho.
Outras priorizam a facilidade de escrita e manutenção, como Python ou Ruby, mesmo que isso
custe um pouco de desempenho.
• Evolução tecnológica e histórica: linguagens surgem para acompanhar novas tecnologias ou
superar as limitações das anteriores. Por exemplo:
— JavaScript foi criada para desenvolvimento web, respondendo à demanda por interatividade
nos navegadores.
— Kotlin foi desenvolvido como uma alternativa moderna e mais eficiente ao Java para
desenvolvimento Android.
• Facilidade de uso e aprendizado: algumas linguagens são projetadas para serem mais acessíveis
a iniciantes, como Scratch ou Python, enquanto outras, como Assembly, são complexas e mais
adequadas a programadores experientes que precisam interagir diretamente com o hardware.
• Flexibilidade e inovação: as linguagens também diferem conforme permitem a inovação. Por
exemplo, linguagens como Java são mais rígidas e seguras, enquanto aquelas como Python
oferecem maior liberdade de experimentação.
30
Unidade I
Embora existam milhares de linguagens de programação, um bom programador geralmente é
fluente em um número muito menor, dependendo de sua área de atuação e experiência. Na prática,
a fluência média de um programador costuma variar entre duas e cinco linguagens, embora ele
possa ter familiaridade básica ou intermediária com várias outras. Isso ocorre porque ser fluente em
uma linguagem envolve mais do que conhecer sua sintaxe; é necessário entender profundamente suas
bibliotecas, paradigmas e melhores práticas. Um bom programador não precisa dominar todas as
linguagens disponíveis, mas sim aquelas mais relevantes para seu trabalho.
Observação
Além disso, a capacidade de aprender novas linguagens conforme
necessário é mais valiosa do que o número total de linguagens em
que se é fluente.
O código-fonte é o conjunto de instruções escritas em uma linguagem de programação por
um programador para criar um software (ou programa), resolver um problema ou executar uma
tarefa específica. Ele é chamado de “fonte” porque é a origem do programa, o ponto de partida
que será interpretado ou compilado para se transformar em algo que o computador consiga
executar diretamente.
Quando um programador escreve um código-fonte, ele está dando instruções ao computador. Essas
instruções precisam seguir um conjunto específico de regras para que o computador consiga interpretar
e executar as ações. Cada linguagem de programação tem suas próprias regras de sintaxe. Algumas
são mais rigorosas e detalhadas, enquanto outras são mais flexíveis e fáceis de aprender. No entanto,
o conceito principal é o mesmo: a sintaxe organiza o código de uma forma que o computador consiga
entender e executar sem confusões. Se o código tiver um erro de sintaxe, o programa não funcionará,
assim como uma frase mal escrita pode não ser compreendida por quem a lê.
Cada linguagem tem seu vocabulário, regras gramaticais e estruturas semânticas, proporcionando
aos desenvolvedores maneiras específicas de resolver problemas e implementar soluções. Elas são criadas
para diferentes níveis de abstração, variando desde linguagens de baixo nível, como Assembly, que se
aproximam do funcionamento do hardware, até linguagens de alto nível, como Python ou Java, que
abstraem os detalhes do hardware e são mais próximas da lógica humana.
Para entender o que são linguagens de baixo nível e de alto nível, é útil pensar em como os sereshumanos e os computadores “falam”. Os computadores “entendem” apenas números e sinais específicos,
enquanto os humanos preferem se comunicar em palavras e frases. As linguagens de programação
servem como intermediárias entre o que as pessoas conseguem escrever e o que os computadores
podem entender.
Uma linguagem de baixo nível é muito próxima da forma como o computador “pensa”. Ela usa
instruções que são quase como um manual direto para o hardware do computador. Um exemplo é a
linguagem Assembly. Nela, o programador precisa dar ordens extremamente detalhadas, como dizer
31
PENSAMENTO LÓGICO COMPUTACIONAL COM PYTHON
para o computador mover um número de uma posição de memória para outra ou realizar operações
básicas como somar e subtrair. Essas linguagens são difíceis para os humanos aprenderem e usarem, mas
são muito eficientes para o computador executar, porque quase não precisam de tradução. É como se
você estivesse falando diretamente na “língua” do computador.
Por outro lado, uma linguagem de alto nível é mais parecida com a forma como os humanos pensam
e se comunicam. Em vez de lidar com detalhes técnicos do hardware, o programador escreve comandos
mais abstratos, muitas vezes próximos da linguagem natural. Por exemplo, em Python você pode escrever
algo como print(“Olá, mundo!”) para mostrar uma mensagem na tela. O programador não precisa se
preocupar em como o computador realmente faz isso internamente. Essas linguagens são mais fáceis
de aprender e usar, porém, antes de serem executadas pelo computador, precisam ser traduzidas para
algo que ele entenda, usando programas chamados compiladores ou interpretadores.
As linguagens de programação desempenham papéis fundamentais em diversos contextos. Em
sistemas operacionais e firmware (software básico embutido em hardwares para que eles funcionem
minimamente), linguagens de baixo nível oferecem controle detalhado sobre os recursos da máquina.
Por outro lado, linguagens de alto nível são amplamente utilizadas em aplicações de software, devido à
sua facilidade de aprendizado e à capacidade de escrever código de forma mais expressiva e eficiente.
Algumas linguagens, como C++, oferecem flexibilidade ao permitir que o programador escolha o nível
de abstração mais adequado ao contexto, enquanto outras, como SQL, são especializadas em tarefas
específicas, como manipulação de dados em bancos de dados.
Um compilador e um interpretador são ferramentas usadas para traduzir o código escrito por um
programador em uma linguagem de programação para um formato que o computador consiga entender
e executar. Essas ferramentas desempenham papéis essenciais no desenvolvimento de software, e cada
uma funciona de forma distinta.
No caso de linguagens como Python, é importante entender como um interpretador funciona, já
que Python é interpretado. Um interpretador lê o código-fonte, linha por linha, traduz cada instrução
diretamente para uma linguagem que o computador entende e a executa imediatamente. Por exemplo,
se você escrever print(“Olá, mundo!”) em Python e executar o programa, o interpretador pega essa linha,
a traduz e exibe o texto na tela. Esse processo acontece enquanto o programa está executando.
Por outro lado, um compilador funciona de forma diferente. Ele pega todo o código do programa
de uma vez e o traduz para uma forma chamada “código de máquina” ou “executável”, que é o que o
computador realmente entende. Isso significa que, antes de executar o programa, o compilador precisa
processar tudo. Uma vez traduzido, o programa não precisa mais do compilador para rodar. Linguagens
como C e Java costumam usar compiladores.
Embora Python seja geralmente associado a um interpretador, ele também envolve uma etapa de
compilação intermediária. Quando você executa um código Python, o interpretador primeiro converte o
código-fonte em uma forma intermediária chamada bytecode. Esse bytecode é um conjunto de instruções
mais próximas da máquina, mas ainda independentes do hardware. Esse processo de compilação em
Python é automático e acontece sem que o programador precise se preocupar com ele.
32
Unidade I
Depois que o bytecode é gerado, ele é executado por uma parte especial do interpretador chamada
máquina virtual Python (PVM). A PVM interpreta o bytecode e o executa diretamente. Esse mecanismo,
ilustrado na figura a seguir, permite que o Python combine características de linguagens interpretadas
e compiladas, proporcionando flexibilidade e eficiência.
Escrever código-fonte
Compilação para bytecode
Interpretador
analisa o código
Armazenamento do
bytecode em memória
Execução do bytecode
pela PVM - Máquina
Virtual Python
Resultados são exibidos
ao usuário
Figura 7 – Python: código interpretado
A principal vantagem de um interpretador como o do Python é que ele facilita o desenvolvimento
rápido e iterativo. Você pode escrever, testar e modificar pequenas partes do programa sem precisar
compilar tudo de uma vez, o que é ótimo para aprendizado, prototipagem e desenvolvimento ágil.
Contudo, como o interpretador traduz o código em tempo de execução, programas em Python
geralmente são mais lentos do que aqueles escritos em linguagens compiladas como C.
Cada linguagem de programação é composta por elementos fundamentais, incluindo variáveis,
operadores, estruturas de controle e funções, que, juntos, permitem a construção de algoritmos.
Além disso, muitas linguagens modernas oferecem bibliotecas e frameworks que ampliam sua
funcionalidade, permitindo a integração com tecnologias avançadas, como IA, análise de dados e
desenvolvimento web. A evolução das linguagens de programação acompanha as necessidades da
sociedade, com a criação de novas linguagens ou a atualização das existentes para atender às demandas
tecnológicas em constante mudança.
Com o avanço da tecnologia e a necessidade crescente de soluções rápidas e eficientes, a escolha
da linguagem de programação torna-se crucial. Nesse cenário, como dissemos anteriormente,
a linguagem Python tem se destacado como uma das mais populares e versáteis. Ela é uma
33
PENSAMENTO LÓGICO COMPUTACIONAL COM PYTHON
linguagem de programação de alto nível, interpretada e de propósito geral, conhecida por sua sintaxe
clara e legibilidade, o que a torna ideal tanto para iniciantes quanto para desenvolvedores experientes.
Criada no final da década de 1980 por Guido van Rossum, Python foi concebida com o objetivo
de ser uma linguagem simples de aprender e usar, sem sacrificar a expressividade e a potência. Sua
filosofia de design enfatiza a legibilidade do código e a simplicidade, permitindo que os programadores
expressem conceitos complexos de forma concisa. Isso é alcançado por meio de uma sintaxe que utiliza
indentação significativa, eliminando a necessidade de delimitadores como chaves ou pontos e vírgulas,
comuns em outras linguagens.
Observação
Indentação é o ato de organizar o código-fonte de um programa através
do deslocamento horizontal das linhas, criando uma hierarquia visual
que reflete a estrutura lógica do código. Isso é feito inserindo espaços ou
tabulações no início das linhas para indicar que certos trechos de código
estão aninhados dentro de blocos de controle, como loops, condicionais,
funções, entre outros.
Em muitas linguagens de programação, a indentação é utilizada principalmente para melhorar
a legibilidade do código. Ela permite que programadores identifiquem facilmente quais instruções
estão associadas a determinados blocos lógicos, facilitando a compreensão e manutenção do código.
Embora não seja obrigatória em termos sintáticos nessas linguagens, é considerada uma boa prática
de programação.
No entanto, em Python, a indentação é mais do que uma convenção estilística; ela é parte
fundamental da sintaxe da linguagem. Em vez de utilizar chaves {} ou palavras-chave como begin e
end para delimitar blocos de código, Python usa a indentação para definir a estrutura dos blocos. Isso
significa que a correta indentação