Comparações e condições

E mais: operadores lógicos e indentação

Até agora todo o código que escrevemos age da mesma forma independemente de suas entradas (fora eventuais erros, claro). Por exemplo, nosso programa que calcula a taxa de performance de um fundo de investimento assume que ela sempre será paga; mas o que acontece quando o fundo não bate o benchmark? Neste caso não devemos calcular a taxa de performance. Ou seja, o cálculo da taxa de performance está condicionado à superação do benchmark. Execução condicional de código (ou branching) é fundamental para programação, e é o que vamos aprender nesta aula.

1. Comparações

Para executarmos código condicionalmente, precisamos saber comparar valores. No nosso exemplo, se a valorização do fundo for maior que a valorização, então calcular a taxa de performance. O ‘for maior’ é a comparação que queremos fazer. Comparações retornam um tipo básico conhecido como booleano, que só tem dois valores: True e False.

Operação Python
Igualdade 2 == 2.0,
Desigualdade "You and I are not so different" != "Yes, we are"
Maior que 1 > -1
Menor ou igual que 0 <= 0.0001

O que você acha que resulta de…

  • 1 == 1.0?
  • 42 != "42"?
  • "Rachel" < "Ross"?

2. Operadores lógicos

Operadores de comparação checam condições simples, mas às vezes queremos checar condições mais complexas.

Por exemplo, quando você faz uma compra usando seu cartão de crédito, o emissor do cartão faz pelo menos duas checagens: além de checar se o seu limite disponível é superior ao valor da compra, ele estima a probabilidade de que esta compra seja fraudulenta (se você geralmente só faz compras pequenas em um supermercado no Flamengo e de repente aparece uma compra de uma TV em uma loja em Belo Horizonte é muito provável que alguém tenha clonado seu cartão). A sua compra só é aprovada se o seu limite for superior ao valor da compra e a probabilidade estimada de que a compra seja fraudulenta for baixa.

Para criar condições mais complexas, usamos operadores lógicos:

Operação Python
Negação not True
Conjunção (“e”) True and True
Disjunção (“ou”) False or True

Esses operadores são definidos pela tabela abaixo, de acordo com o valor de seus operandos.

A B not A A and B A or B
True True False True True
True False False False True
False True True False True
False False True False False

3. Branching

Em Python, execução condicional de código é feita principalmente com if, como no exemplo abaixo:

purchase_value = 40.2
available_limit = 3000
fraud_score = 0.02
if available_limit >= purchase_value and fraud_score < 0.05:
    # update available credit limit
    available_limit = available_limit - purchase_value
    print("Sua compra de " + str(purchase_value) + " dinheiros foi aprovada. Seu limite atual é de " + str(available_limit) + " dinheiros")

Se a condição entre o if e o : for verdadeira, o bloco seguinte é executado; caso ela seja falsa, o bloco de código é ignorado, não tendo efeito nenhum sobre o programa. Ao escrever um bloco if, estamos criando uma bifurcação na execução do nosso código; se antes ele sempre seguia um mesmo caminho, agora há dois caminhos possíveis, e a escolha de qual deles será seguido depende da condição do if.

3.1. Indentação e blocos

Blocos de código são definidos pela sua indentação: um conjunto de linhas seguidas com a mesma indentação é um bloco. Seu editor de texto costuma fazer a indentação automaticamente, evitando que você coloque o número de espaços errado, ou misture espaços e tabs. Teste você mesmo!

3.2. Mais caminhos

No exemplo da compra de cartão de crédito nós fizemos só um branching, criando dois caminhos possíveis (quando a compra é aprovada, e quando ela não é). Mas nós não fazemos nada quando a compra do usuário é negada. Vamos corrigir isso?

Para criar outros caminhos de execução do código nós poderíamos usar mais if:

purchase_value = 40.2
available_limit = 3000
fraud_score = 0.02
if available_limit >= purchase_value and fraud_score < 0.05:
    # update available credit limit
    available_limit = available_limit - purchase_value
    print("Sua compra de " + str(purchase_value) + " dinheiros foi aprovada. Seu limite atual é de " + str(available_limit) + " dinheiros")
if available_limit < purchase_value or fraud_score > 0.05:
    print("Sua compra foi negada.")

Criar novos if para condições relacionadas não é o ideal, pois precisamos cuidar de que as condições que escrevermos são uma partição perfeita do espaço de possibilidades (cada valor possível das variáveis envolvidas no código executa um único bloco de código). No exemplo acima, isso é feito de maneira incorreta, e nenhum bloco é executado quando fraud_score == 0.05.

Também seria possível errar de forma a fazer com que os dois blocos if fossem executados, o que neste exemplo seria problemático. A forma ideal de resolver isso é complementando o if com um else:

purchase_value = 40.2
available_limit = 3000
fraud_score = 0.02
if available_limit >= purchase_value and fraud_score < 0.05:
    # update available credit limit
    available_limit = available_limit - purchase_value
    print("Sua compra de " + str(purchase_value) + " dinheiros foi aprovada. Seu limite atual é de " + str(available_limit) + " dinheiros")
else:
    print("Sua compra foi negada.")
dramatic-crossroads.png
Figura 1: Seu código quando encontra um bloco if

Na verdade, podemos criar uma bifurcação de quantos caminhos quisermos (n-furcação?) usando elif (de else if):

purchase_value = 40.2
available_limit = 3000
fraud_score = 0.02
if fraud_score >= 0.05:
    print("Sua compra foi negada sob suspeita de fraude e seu cartão foi bloqueado")
elif available_limit >= purchase_value:
    # update available credit limit
    available_limit = available_limit - purchase_value
    print("Sua compra de " + str(purchase_value) + " dinheiros foi aprovada. Seu limite atual é de " + str(available_limit) + " dinheiros")
else:
    print("Sua compra de " + str(purchase_value) + " dinheiros foi negada pois seu limite atual é de " + str(available_limit) + " dinheiros")

3.2.1. Exercício: elif

Todo uso de elif é, de certa forma, desnecessário. Sempre podemos transformar código que usa elif em código que usa exclusivamente if-else; elif só existe por conveniência, pois economiza-se digitação e o resultado é mais fácil de ler. Como exercício, transforme o exemplo anterior de forma não usar nenhum elif.

3.2.2. Exercício: calculando a taxa de performance somente quando necessário

Como mencionamos, nosso programa que calcula a taxa de performance de um fundo de investimento não lida corretamente com o caso em que a taxa de performance não deve ser calculada pois o fundo não bateu seu benchmark. Modifique o código para que ele somente calcule a taxa de performance do fundo quando o benchmark do fundo foi superado.

Bruno Cuconato / 2024-08-07
TOP | HOME
Computação FGV/EPGE