Solucionado (ver solução)
Solucionado
(ver solução)
3
respostas

Desafio - Conversão de Moedas Dólar x Real

Boa noite,

Para a solução do desafio considerei a construção de um método que verifica:

  • Se o parâmetro quantidade existe na URL e se o seu valor é um número inteiro e maior que zero.
  • As conversões são possíveis somente entre "real" e "dólar". Qualquer outro valor em moedaOrigem e moedaDestino causará um raise.
  • moedaOrigem e moedaDestino não podem ser iguais. Nesse caso um novo raise é mostrado.
  • Satisfeitas as condições, o método retorna uma string formatada com precisão de duas casas decimais para o valor convertido.

Segue o código completo

import re

class ExtratorURL:
    def __init__(self, url):
        self.url = self.sanitiza_url(url)
        self.valida_url()

    def sanitiza_url(self, url):
        if type(url) == str:
            return url.strip()
        else:
            return ""

    def valida_url(self):
        if not self.url:
            raise ValueError("A URL está vazia!")

        padrao_url = re.compile('(http(s)?://)?(www.)?bytebank.com(.br)?/cambio')
        match = padrao_url.match(self.url)

        if not match:
            raise ValueError("A URL não é válida")

    def get_url_base(self):
        indice_interrogacao = self.url.find('?')
        url_base = self.url[:indice_interrogacao]
        return url_base

    def get_url_parametros(self):
        indice_interrogacao = self.url.find('?')
        url_parametros = self.url[indice_interrogacao + 1:]
        return url_parametros

    def get_valor_parametro(self, parametro_busca):
        indice_parametro = self.get_url_parametros().find(parametro_busca)
        indice_valor = indice_parametro + len(parametro_busca) + 1
        indice_e_comercial = self.get_url_parametros().find('&', indice_valor)
        if indice_e_comercial == -1:
            valor = self.get_url_parametros()[indice_valor:]
        else:
            valor = self.get_url_parametros()[indice_valor:indice_e_comercial]
        return valor

    def __len__(self):
        return len(self.url)

    def __str__(self):
        return self.url + "\n" + "Parâmetros: " + self.get_url_parametros() + "\n" + "URL base: " + self.get_url_base()

    def __eq__(self, other):
        return self.url == other.url

    def converte_moeda_origem_moeda_destino(self, moedaOrigem, moedaDestino, quantidade):
        if quantidade.isnumeric():
            quantidade = int(quantidade)
            if quantidade > 0:
                VALOR_DOLAR = 5.50 # 1 dólar = 5.50 reais
                if moedaOrigem == "real" and moedaDestino == "dolar":
                    valorConvertido = float(quantidade) / VALOR_DOLAR
                    msg = f'O valor convertido é de {valorConvertido:_.2f} dólares'
                elif moedaOrigem == "dolar" and moedaDestino == "real":
                    valorConvertido = float(quantidade) * VALOR_DOLAR
                    msg = f'O valor convertido é de {valorConvertido:_.2f} reais'
                else:
                    raise ValueError("A conversão só pode ser entre real e dólar. Favor revisar a URL e tente novamente!")
            else:
                raise ValueError("A quantidade deve ser maior que 0")
            return msg
        else:
            raise ValueError("Não é possível realizar a conversão! Quantidade ausente ou não é um número inteiro!")


url = "bytebank.com/cambio?moedaDestino=real&moedaOrigem=dolar&quantidade=100"
extrator_url = ExtratorURL(url)

print("O tamanho da URL: ",len(extrator_url))
print(extrator_url)


valor_quantidade = extrator_url.get_valor_parametro("quantidade")
moeda_origem = extrator_url.get_valor_parametro("moedaOrigem")
moeda_destino = extrator_url.get_valor_parametro("moedaDestino")
#print(valor_quantidade)

valor = extrator_url.converte_moeda_origem_moeda_destino(moeda_origem, moeda_destino, valor_quantidade)
print(valor)

Acredito que a quantidade de ifs no método poderia ser reduzida... Alguma melhoria a ser sugerida?

3 respostas
solução!

Olá Luis, tudo bem com você?

Meus parabéns pela resolução do desafio, fico feliz que tenha compartilhado o seu código com a comunidade do fórum Alura. Sua implementação atende bem a proposta do desafio.

Uma das formas que podemos estar reduzindo o uso da estrutura condicional if para esse cenário onde ocorre apenas a conversão de real para dólar ou o inverso, será com a utilização de dicionários no método converte_moeda_origem_moeda_destino. Onde as chaves do dicionário serão o nome da moeda de destino ('moedaDestino'), e o valor será a fórmula utilizada para o cálculo. Como apresentado no dicionário abaixo.

conversao = {
    'dolar': quantidade / VALOR_DOLAR,
    'real': quantidade * VALOR_DOLAR,
}

Criaremos também um segundo dicionário que irá conter no nome das moedas de destinos como chave e os valores serão o nome da moeda conjugada. Abaixo o dicionário.

moedas_cadastradas = {
    'real': 'reais',
    'dolar': 'dólares',
}

Usaremos agora apenas um if para verificar se a moeda de destino é uma das chaves do dicionário, caso seja, acessaremos os dicionários usando o nome da moeda de destino. No código abaixo apresento essa implementação.

if moeda_destino in conversao.keys():
    valorConvertido = conversao[moeda_destino]
    unidade = moedas_cadastradas[moeda_destino]
    return f'O valor convertido é de {valorConvertido:_.2f} {unidade}'

Utilizando a validação acima, usaremos apenas um if para realizar as duas conversões, também reduzimos a repetição das mensagens, pois, ela será criada com base no nome da moeda de destino. Os códigos acima devem ser adicionados dentro da estrutura condicional if quantidade > 0:

No código abaixo temos a implementação completa para o método converte_moeda_origem_moeda_destino.

    def converte_moeda_origem_moeda_destino(self, moeda_destino, quantidade):
        if quantidade.isnumeric():
            quantidade = int(quantidade)
            if quantidade > 0:
                VALOR_DOLAR = 5.50  # 1 dólar = 5.50 reais

                conversao = {
                    'dolar': quantidade / VALOR_DOLAR,
                    'real': quantidade * VALOR_DOLAR,
                }

                moedas_cadastradas = {
                    'real': 'reais',
                    'dolar': 'dólares',
                }

                if moeda_destino in conversao.keys():
                    valorConvertido = conversao[moeda_destino]
                    unidade = moedas_cadastradas[moeda_destino]
                    return f'O valor convertido é de {valorConvertido:_.2f} {unidade}'
                else:
                    raise ValueError("A conversão só pode ser entre real e dólar. Favor revisar a URL e tente novamente!")
            else:
                raise ValueError("A quantidade deve ser maior que 0")
        else:
            raise ValueError("Não é possível realizar a conversão! Quantidade ausente ou não é um número inteiro!")

Utilizando a url presente no seu código, teremos o seguinte resultado.

url = "bytebank.com/cambio?moedaDestino=dolar&moedaOrigem=real&quantidade=100"
extrator_url = ExtratorURL(url)
moeda_destino = extrator_url.get_valor_parametro("moedaDestino")
valor_quantidade = extrator_url.get_valor_parametro("quantidade")
valor = extrator_url.converte_moeda_origem_moeda_destino(moeda_destino, valor_quantidade)
print(valor)

Resultado

O valor convertido é de 18.18 dólares

Caso opte por implementar a proposta acima, lembre-se de salvar o arquivo após a implementação antes de executá-lo.

Para aprofundar ainda mais o seu aprendizado junto a Alura, gostaria de recomendar um curso onde é abordado com detalhes sobre o uso dos dicionários em projetos na linguagem Python. Você pode estar acessando o curso através do seguinte link.

Espero ter ajudado. Em caso de dúvidas estou à disposição.

Não hesite em voltar ao fórum para continuar aprendendo e interagindo com a comunidade.

Abraços e bons estudos!

Caso este post tenha lhe ajudado, por favor, marcar como solucionado ✓. Bons Estudos!

Excelente Felippe!

Obrigado por revisar e propor uma interessante melhoria para o código. O curso sugerido está na formação Python e em breve devo estar me aprofundando no assunto.

Mais uma vez, obrigado.

Meu método ficou assim:

def converte_moeda(self, moeda_origem):
        if self.get_valor_parametro(moeda_origem) == 'real':
            valor_convertido = int(self.get_valor_parametro('quantidade')) * 5.5
        elif self.get_valor_parametro(moeda_origem) == 'dolar':
            valor_convertido = int(self.get_valor_parametro('quantidade')) / 5.5
        return valor_convertido

Dessa maneira utilizo passando apenas a moeda de origem. Irei implementar a validação numérica.

VALOR_DOLAR = 5.5
extrator_url = ExtratorURL("bytebank.com/cambio?quantidade=100&moedaOrigem=dolar&moedaDestino=real")
print(extrator_url.converte_moeda('moedaOrigem'))