Created
July 26, 2024 15:49
-
-
Save uqmessias/15b40f8fc7a466680cf6246b4eced735 to your computer and use it in GitHub Desktop.
Função para calcular a quantidade de meses que alguém poderia gastar um determinado dinheiro considerando o rendimento desse dinheiro e também para calcular quanto de dinheiro se consegue juntar com o rendimento mensal.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const fs = require("fs"); | |
const path = require("path"); | |
const crypto = require("crypto"); | |
const stream = require("stream/promises"); | |
const readline = require("readline"); | |
const { totalmem } = require("os"); | |
const rl = readline.createInterface({ | |
input: process.stdin, | |
output: process.stdout, | |
}); | |
/** | |
* @param {...string} messages | |
* @returns {Promise<string>} | |
*/ | |
async function ask(...messages) { | |
return new Promise((resolve) => { | |
for (let i = 0; i < messages.length - 1; i++) { | |
rl.write(`${messages[i]}\n`); | |
} | |
rl.question(`${messages[messages.length - 1]}\n`, resolve); | |
}); | |
} | |
/** | |
* @param {RegExp} regex | |
* @param {string} regexFormat | |
* @param {(rawValue: string): number} parser | |
* @param {...string} messages | |
* @returns {Promise<number>} | |
*/ | |
async function askNumberFormat(regex, regexFormat, parser, ...messages) { | |
const answer = await ask(...messages); | |
if (!regex.test(answer)) { | |
writeLine(`Formato inválido "${answer}", o correto é "${regexFormat}"`); | |
writeLine(`Tente novamente!\n`); | |
return askNumberFormat(regex, regexFormat, ...messages); | |
} | |
return parser(answer); | |
} | |
/** | |
* @returns {Promise<'d'|'t'>} | |
*/ | |
async function askEnumFormat() { | |
const message = | |
'Digite "d" para inserir depósito mensal ou "t" para calcular a partir do valor total:'; | |
const answer = await ask(message); | |
if (!/^[dt]{1}$/.test(answer)) { | |
writeLine(`Formato inválido "${answer}"`); | |
writeLine(`Tente novamente!\n`); | |
return askEnumFormat(message); | |
} | |
return answer; | |
} | |
/** | |
* @param {...string} messages | |
* @returns {Promise<number>} | |
*/ | |
function askMoneyFormat(...messages) { | |
return askNumberFormat( | |
new RegExp("^[\\d]+([\\.|,]{1}[\\d]{1,2})?$"), | |
"12345.67", | |
(rawValue) => | |
Number.parseFloat(rawValue.replace("%", "").replace(",", ".")), | |
...messages | |
); | |
} | |
/** | |
* @param {...string} messages | |
* @returns {Promise<number>} | |
*/ | |
function askSimpleNumberFormat(...messages) { | |
return askNumberFormat( | |
new RegExp("^[\\d]+$"), | |
"12345", | |
Number.parseFloat, | |
...messages | |
); | |
} | |
/** | |
* @param {...string} messages | |
* @returns {Promise<number>} | |
*/ | |
function askPercentageFormat(...messages) { | |
return askNumberFormat( | |
new RegExp("^[\\d]+([\\.|,]{1}[\\d]+)?$"), | |
"12.3456789%", | |
(rawValue) => | |
Number.parseFloat(rawValue.replace("%", "").replace(",", ".")) / 100, | |
...messages | |
); | |
} | |
/** | |
* @param {number} num | |
* @returns {string} | |
*/ | |
function formatMoney(num) { | |
return `R$ ${num | |
.toFixed(2) | |
.replace(".", ",") | |
.replace(/(\d)(?=(\d\d\d)+(?!\d))/g, "$1.")}`; | |
} | |
/** | |
* @param {string} message | |
*/ | |
function writeLine(message) { | |
rl.write(`${message}\n`); | |
} | |
/** | |
* @param {number} totalAmount | |
* @param {number} interestPercentagePerMonth | |
* @param {number} withdrawAmountPerMonth | |
* @returns {number} | |
*/ | |
function getMonths( | |
totalAmount, | |
interestPercentagePerMonth, | |
withdrawAmountPerMonth | |
) { | |
let monthInterestAmount = totalAmount * interestPercentagePerMonth; | |
if (monthInterestAmount >= withdrawAmountPerMonth) { | |
return Infinity; | |
} | |
let totalAmountRest = totalAmount; | |
let months = 0; | |
while (withdrawAmountPerMonth < totalAmountRest) { | |
totalAmountRest += monthInterestAmount; | |
totalAmountRest -= withdrawAmountPerMonth; | |
monthInterestAmount = totalAmountRest * interestPercentagePerMonth; | |
months++; | |
} | |
return months; | |
} | |
/** | |
* @param {number} monthlyDepositAmount | |
* @param {number} monthlyInterestPercentage | |
* @param {number} totalMonths | |
* @returns {number} | |
*/ | |
function getTotalAmount( | |
monthlyDepositAmount, | |
monthlyInterestPercentage, | |
totalMonths | |
) { | |
if (totalMonths <= 0) { | |
return 0; | |
} | |
let totalAmount = 0; | |
for (let i = 1; i <= totalMonths; i++) { | |
totalAmount += | |
monthlyDepositAmount + totalAmount * monthlyInterestPercentage; | |
} | |
return totalAmount; | |
} | |
async function aposentadoria() { | |
const enumType = await askEnumFormat(); | |
/** @type {number} */ | |
let totalAmount; | |
/** @type {number} */ | |
let monthlyWithdrawAmount; | |
/** @type {number} */ | |
let monthlyInterestPercentage; | |
async function askForMonthlyWithdrawAmountAndPercentage() { | |
monthlyWithdrawAmount = await askMoneyFormat( | |
"Digite o valor que você deseja sacar por mês:" | |
); | |
monthlyInterestPercentage = await askPercentageFormat( | |
"Digite o percentual que rende por mês:" | |
); // percentual de juros que o valor da conta rende por mês | |
} | |
if (enumType === "t") { | |
totalAmount = await askMoneyFormat( | |
"Digite o valor total que você tem ou deseja ter:" | |
); | |
await askForMonthlyWithdrawAmountAndPercentage(); | |
} else { | |
const monthlyDepositAmount = await askMoneyFormat( | |
"Digite o valor que você deseja depositar por mês:" | |
); | |
const months = await askSimpleNumberFormat( | |
"Digite a quantidade de meses que você gostaria de depositar:" | |
); | |
await askForMonthlyWithdrawAmountAndPercentage(); | |
totalAmount = getTotalAmount( | |
monthlyDepositAmount, | |
monthlyInterestPercentage, | |
months | |
); // valor total que alguém tem na conta ou quer ter | |
writeLine( | |
`Com ${formatMoney( | |
monthlyDepositAmount | |
)} depositado todo mês por ${months} meses e rendendo ${( | |
monthlyInterestPercentage * 100 | |
).toFixed(2)}% ao mês, você junta ${formatMoney( | |
months * monthlyDepositAmount | |
)}, mas tem o valor final de ${formatMoney(totalAmount)}` | |
); | |
} | |
const result = getMonths( | |
totalAmount, | |
monthlyInterestPercentage, | |
monthlyWithdrawAmount | |
); | |
writeLine( | |
`Com o valor total de ${formatMoney( | |
totalAmount | |
)} você consegue tirar ${formatMoney( | |
monthlyWithdrawAmount | |
)} por ${result} meses` | |
); | |
} | |
aposentadoria(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Maybe use Gluegun
https://www.youtube.com/watch?v=_KEqXfLOSQY