Skip to content

Lógica de Programação

Definição: lógica de programação

Lógica de programação é a habilidade de decompor um problema em passos ordenados e não ambíguos (um algoritmo) que um computador consiga executar. A linguagem é só a forma de escrever esses passos; esta página usa Python por ser simples e muito usada, mas os conceitos valem para qualquer linguagem.

É a base de toda a trilha técnica, e é o que testes de entrevista de nível inicial e live coding verificam (Perguntas técnicas). Os detalhes da linguagem estão em Python; estruturas como listas e árvores, em Estrutura de dados.

Algoritmo, fluxograma e pseudocódigo

Antes de codificar, descreva a solução. Um fluxograma mostra o fluxo e as decisões:

flowchart TD
    A([Início]) --> B[/Ler idade/]
    B --> C{idade >= 12?}
    C -- sim --> D[Pode jogar]
    C -- não --> E[Não pode jogar]
    D --> F([Fim])
    E --> F

Pseudocódigo é a mesma ideia em texto (LEIA idade; SE idade >= 12 ENTÃO ESCREVA "pode jogar"). Um bom algoritmo é finito, preciso, tem entrada(s), saída(s) e é eficaz (resolve o problema). Todo programa é uma combinação de três estruturas: sequência, decisão e repetição.

Preparando o ambiente

  • Interpretador Python 3 (o Python 2 está descontinuado): confirme com python --version (Windows) ou python3 --version (Linux/macOS). No instalador, marque a opção de adicionar ao PATH.
  • IDE (ambiente de desenvolvimento integrado), como PyCharm Community ou VS Code: editor + execução + depuração.
  • pip instala bibliotecas (pip install numpy pandas); use ambientes virtuais (python -m venv .venv) por projeto.

Entrada, saída, variáveis e tipos

print("Hello, World!")                      # saída
nome = input("Digite seu nome: ")           # entrada: SEMPRE devolve texto (str)
print("Olá, " + nome)
print(f"Olá, {nome}!")                       # f-string: forma moderna de formatar
  • Variável é um nome para um espaço na memória que guarda um dado durante a execução. Em Python não se declara o tipo: ele vem do valor (tipagem dinâmica). Nomes de arquivos e variáveis em minúsculas com _ (snake_case).
  • Tipos básicos: int (inteiro), float (real), str (texto), bool (True/False). type(x) mostra o tipo.
  • input() devolve str: para calcular, converta com int() ou float(). Somar "2" + "3" concatena ("23"); somar 2 + 3 calcula (5). O erro clássico de iniciante é tentar subtrair textos (TypeError).
  • Formatação de números: f"{valor:.2f}" mostra duas casas decimais (use Decimal para dinheiro em sistemas reais).
  • Comentários com # ignoram a linha (úteis para explicar e para desativar trechos ao depurar).
valor1 = float(input("Primeiro valor: "))
valor2 = float(input("Segundo valor: "))
print(f"Soma: {valor1 + valor2:.2f}  Divisão: {valor1 / valor2:.2f}")

Operadores

Tipo Operadores Observações
Aritméticos + - * / // % ** / divide (real), // divisão inteira, % resto, ** potência
Relacionais (devolvem bool) == != > < >= <= == compara; = atribui (confundir os dois é erro clássico)
Lógicos and or not and: ambos verdadeiros; or: pelo menos um; not: inverte
Pertinência in not in "Test" in "Teste" → True

Desvios condicionais (if)

Programas deixam de ser lineares quando precisam decidir:

idade = int(input("Idade: "))

# if simples: um teste, um conjunto de instruções
if idade >= 12:
    print("Você pode jogar!")

# if composto (if/else): duas saídas excludentes
doacao = float(input("Doação: "))
if doacao <= 1000:
    investimento = doacao * 0.05
else:
    investimento = doacao * 0.15

# encadeado (if/elif/else): várias faixas
if idade < 16:
    print("Não vota")
elif idade >= 18:
    print("Voto obrigatório")
else:
    print("Voto opcional")
  • Dois if seguidos testam duas vezes, mesmo que o primeiro já tenha sido verdadeiro: quando as condições são excludentes, prefira if/else ou elif.
  • Em Python o recuo (indentação) define os blocos; é parte da sintaxe.
  • Truthy/falsy: 0, "", [], None valem como falso numa condição.

Laços de repetição

Laço Quando usar Exemplo
while Repetir enquanto uma condição for verdadeira, sem saber quantas vezes (como bater a massa de um bolo até ficar homogênea) Pedir a senha até acertar
for Repetir um número conhecido de vezes ou percorrer uma coleção (como voltas numa corrida) Tabuada, percorrer uma lista
# while: tentativas até acertar o login
tentativas = 0
logado = False
while not logado:
    tentativas += 1
    usuario = input("Usuário: ")
    senha = input("Senha: ")
    logado = usuario.upper() == "ADMIN" and senha == "123"
print(f"Logou após {tentativas} tentativa(s)")

# for com range(inicio, fim_exclusivo, passo)
numero = int(input("Tabuada de: "))
for i in range(1, 11):
    print(f"{i} x {numero} = {i * numero}")

Cuidados: laço infinito (a condição nunca muda), erro de "um a mais/um a menos" (range(0, 1000) vai de 0 a 999), e uso de break (sai do laço) e continue (pula para a próxima volta).

Funções e modularização

Um programa grande escrito num único bloco é difícil de ler, alterar e testar: uma mudança simples pode exigir editar muitas linhas e quebrar algo sem relação. Modularizar é dividir em subprogramas que resolvem problemas específicos.

def exibe_menu():                      # função sem parâmetros e sem retorno
    print("1 - Somar  2 - Subtrair  0 - Sair")

def exibe_resultado(resultado):        # com parâmetro
    print(f"O resultado foi {resultado}")

def somar(a, b):                       # com retorno
    return a + b

exibe_resultado(somar(2, 3))
  • Parâmetros (nomes na definição) recebem argumentos (valores na chamada); return devolve o resultado e encerra a função. Função sem return devolve None.
  • Boa função: faz uma coisa, tem nome de verbo, poucos parâmetros e não depende de variáveis globais (Clean Code).
  • Separe cálculo de exibição: somar retorna o valor e quem chama decide o que fazer (mais fácil de testar).

Arquivos de texto

with open("notas.txt", encoding="utf-8") as arquivo:    # with fecha o arquivo sozinho
    for linha in arquivo:                                # lê linha a linha
        print(linha.strip())

with open("saida.txt", "w", encoding="utf-8") as arquivo:   # "w" sobrescreve; "a" acrescenta
    arquivo.write("primeira linha\n")

readlines() devolve uma lista de linhas; sempre feche o recurso (o with garante isso, mesmo em caso de erro).

Bibliotecas para dados: NumPy e Pandas

Python ganha força em análise de dados com bibliotecas instaladas pelo pip:

  • NumPy (import numpy as np): vetores e matrizes (ndarray) de tipo único e operações vetorizadas (rápidas, sem laço): np.array([[1,2,3],[4,5,6]]), np.zeros((3, 4)), np.ones(...), e array - 2 aplica a conta a todos os elementos. Base de Scikit-Learn e SciPy.
  • Pandas (import pandas as pd): Series (coluna) e DataFrame (tabela com colunas de tipos diferentes, criada, por exemplo, a partir de um dicionário), com filtros, agregações e leitura de CSV. Veja Machine Learning e Estatística.

Orientação a objetos em poucas linhas

class Cliente:
    def __init__(self, nome, cpf):
        self.__nome = nome            # "privado" por convenção (name mangling)
        self.__cpf = cpf
        self.__ativo = False

    @property
    def nome(self):                   # getter: acessa como atributo, com a lógica protegida
        return self.__nome

    def ativar(self):
        self.__ativo = True

class Conta:
    def __init__(self, numero, cliente):
        self.__numero = numero
        self.__cliente = cliente      # composição: a conta TEM um cliente
        self.__saldo = 0.0

    def depositar(self, valor):
        if valor <= 0:
            raise ValueError("valor inválido")
        self.__saldo += valor

Classe é o molde; objeto é a instância; atributos guardam estado; métodos são funções da classe; encapsulamento protege o estado (acesso por métodos e @property); composição monta objetos a partir de outros (Conta tem Cliente) (Orientação a Objetos, Python).

Depuração e boas práticas

  • Leia o erro de baixo para cima: a última linha diz o tipo (TypeError, NameError, IndexError), as de cima, onde.
  • Teste pequeno e cedo: rode a cada trecho; use print e o depurador da IDE (pontos de parada).
  • Nomes que revelam intenção, funções curtas, evite repetir código (DRY), valide entradas do usuário e trate exceções (try/except).
  • Resolva "no papel" (fluxograma ou pseudocódigo) antes de digitar.

Problemas clássicos de entrevista (nível inicial)

# 1. FizzBuzz: de 1 a 100, "Fizz" para múltiplos de 3, "Buzz" para 5, "FizzBuzz" para ambos
for n in range(1, 101):
    print("FizzBuzz" if n % 15 == 0 else "Fizz" if n % 3 == 0 else "Buzz" if n % 5 == 0 else n)

# 2. Palíndromo
def eh_palindromo(texto):
    t = "".join(c.lower() for c in texto if c.isalnum())
    return t == t[::-1]

# 3. Maior valor de uma lista sem usar max()
def maior(valores):
    atual = valores[0]
    for v in valores[1:]:
        if v > atual:
            atual = v
    return atual

# 4. Contar ocorrências de cada palavra
def contar(texto):
    contagem = {}
    for p in texto.lower().split():
        contagem[p] = contagem.get(p, 0) + 1
    return contagem

Ao resolver em voz alta numa entrevista: repita o problema, peça exemplos e casos extremos (lista vazia, número negativo), descreva o algoritmo antes de codificar, codifique de forma legível e teste mentalmente com os exemplos; depois comente a complexidade (Estrutura de dados).

Para responder em entrevista

Pergunta Ideias para a resposta
"Diferença entre while e for?" while repete por condição (quantidade desconhecida); for percorre um intervalo ou coleção (quantidade conhecida)
"O que é uma função e por que usar?" Subprograma reutilizável e testável; reduz repetição e isola mudanças
"Por que input() + input() não soma?" Devolve texto; é preciso converter para número
"== ou =?" == compara; = atribui
"O que é encapsulamento?" Proteger o estado e expô-lo por métodos/propriedades, mantendo as regras num lugar só
"Como você resolve um problema de lógica?" Entender, exemplos, algoritmo (fluxograma/pseudocódigo), codificar, testar casos extremos