Juros e lógica
Um dos problemas de lógica de programação que mais quebram a cabeça de quem está começando são os problemas com cálculo de porcentagens ou juros.
Começa assim: Calcule 10% de aumento de um salário de R$2.500,00
Dependendo da base matemática do aluno, porcentagem se aprende na quarta/quinta série… alguns conceitos tem que ser relembrados. Como diz o nome, a 10% significa que a cada 100 do valor, você deve retirar 10. O cálculo é bem simples, pode ser realizado com uma multiplicação. Por exemplo: 10/100 * 2500, que resulta em 250. Até aí tudo bem, mas alguns alunos perguntam por que as vezes fazemos 0.1 * 2500. Bem, é apenas a forma de representar que muda, pois 10/100 é equivalente a 0.1, alias 100/1000 também e por aí vai. Mas está é a parte fácil e depois de acertar a notação, as coisas voltam a andar novamente.
Quando chegamos em repetições, problemas como cálculo da poupança começam a aparecer. Eles tem o seguinte formato: imagine que alguém deposita R$1.000,00 para poupança e que esta rende 1% ao mês (bons tempos). Depois de n meses, quanto a pessoa terá como saldo? O problema combina porcentagem com repetição. Vejamos como fica para 6 meeses:
saldo = 1000 # Valor inicial
n = 6 # Número de meses
juros = 0.01 # Juros mensal 1% = 1/100 = 0.01
for mês in range(1, n + 1):
saldo *= 1 + juros
print(f"Mês ({mês}): {saldo:7.2f}")
que resulta em:
Mês (1): 1010.00
Mês (2): 1020.10
Mês (3): 1030.30
Mês (4): 1040.60
Mês (5): 1051.01
Mês (6): 1061.52
Várias perguntas surgem.
Por que o *=
?#
É que o juros é composto, ou seja, aplicado ao saldo precedente. Não se calcula 1% do saldo inicial e se multiplica pelo número de meses. Vai ficar mais claro depois com a fórmula.
Por que se soma 1 ao juros?#
Como estamos multiplicando o saldo, precisamos ajustar o novo saldo para que seja igual ao anterior mais o juros do mês. Em formato mais longo seria saldo = saldo + juros * saldo
. Este cálculo pode ser simplificado, agrupando a variável saldo de forma que saldo = saldo * (1 + juros)
. Como em Python podemos escrever saldo = saldo *
como saldo *=
, a expressão fica resumida a saldo *= (1 + juros)
, veja que retirei os parênteses pois não são mais necessários.
Precisa de repetição para realizar este cálculo?#
Não, você pode ter uma solução analítica, aplicando a fórmula: `saldo = saldo * (1 + juros) ** mês). Exemplo:
>>> print(f"{1000 * (1 + 0.01) ** 6:7.2f}")
1061.52
E de onde vem essa exponenciação?#
Se voltarmos ao exemplo com repetição, veremos que:
No mês 1, o saldo é saldo * 1.01.
O saldo no mês 2 é saldo * 1.01 * 1.01
No mês 3, saldo * 1.01 * 1.01 * 1.01
E assim por diante, começamos a ver um padrão onde o 1.01 é multiplicado por ele mesmo o número de mês que estamos calculando. Podemos então escrever de forma genérica que saldo *= 1.01 ** mês
, que é justamente a definição da exponenciação: a ** n = a * a * a ... (n vezes)
Por que usamos a repetição?#
Porque o curso é de lógica de programação e o professor quer que você tenha uma motivo para usar o for ou while.
Uma questão que apareceu hoje no StackOverflow em Português#
A questão foi votada para baixo e logo depois fechada :-(
Duas fabricantes de calçado disputam o mercado no Brasil. A empresa A tem produção de 10.000 pares/mês e um crescimento mensal de 15%. A empresa B, de 8.000 pares/mês e tem um crescimento mensal de 20%. Determinar o número de meses necessários para que a empresa B supere o número de pares produzidos pela empresa A.
Vamos ver como ficaria isso na matemática:
Produção da empresa A: 10000 x 1.15m
Produção da empresa B: 8000 x 1.20m
Onde m é número de meses.
O que você procura é o valor de m quando:
8000 x 1.20m > 10000 x 1.15m
Você pode resolver isso usando logaritmos, mas num curso de lógica de programação, o professor provavelmente espera que você varie o valor de m de 1 em 1.
Então, tente calcular a produção quando m = 1. Compare a produção das duas fábricas (use as fórmulas acima). Se o valor de B não ultrapassar o de A, continue incrementando m de 1. Pare quando a produção de B for maior que A (a resposta é o valor de m quando isso acontecer).
m = 0
while True:
prodA = 10000 * 1.15 ** m
prodB = 8000 * 1.2 ** m
print(f"Prod A: {prodA:8.2f} Prod B: {prodB:8.2f} - mês: {m}")
if prodB > prodA:
break
m += 1
print(f"Meses para que a produção de B ultrapasse a produção de A: {m}")
que resulta em:
Prod A: 10000.00 Prod B: 8000.00 - mês: 0
Prod A: 11500.00 Prod B: 9600.00 - mês: 1
Prod A: 13225.00 Prod B: 11520.00 - mês: 2
Prod A: 15208.75 Prod B: 13824.00 - mês: 3
Prod A: 17490.06 Prod B: 16588.80 - mês: 4
Prod A: 20113.57 Prod B: 19906.56 - mês: 5
Prod A: 23130.61 Prod B: 23887.87 - mês: 6
Meses para que a produção de B ultrapasse a produção de A: 6
E a solução analítica? Como falei o curso é de lógica de programação :-D
Mas você pode resolver a desigualdade usando logaritmos:
8000 x 1.20m > 10000 x 1.15m
ln(8000) + m * ln(1.20) > ln(10000) + m * ln(1.15)
m * ln(1.20) - m * ln(1.15) > ln(10000) - ln(8000)
m * (ln(1.20) - ln(1.15)) > ln(10000) - ln(8000)
m = (ln(10000) - ln(8000))/(ln(1.20) - ln(1.15))
que em Python fica:
from math import log
m = (log(10000) - log(8000))/(log(1.20) - log(1.15))
print(m)
que resulta em:
5.243082071149164
Que podemos arredondar para 6, caso não consideremos frações de um mês. Agora conhecemos o método analítico e o iterativo. Fica fácil de entender porque o segundo é mais usado em cursos de lógica de programação.