Executando verificação de segurança...
3

Projeto de calculadora de calorias em Java

Estou começando a aprender Java e decidi cuidar melhor de mim mesmo começando pela alimentação.
Comecei a assistir alguns vídeos sobre alimentação e vi que os cálculos de gasto calórico são meio chatos de se fazer, então, decidi Unir o útil ao agradável e melhorar as minhas habilidades em Java.
Fiz uma calculadora, que pede seus dados e faz a conta sozinho pra você, isso foi acompanhado com uma amiga que é estudante de nutrição. Claro, é sempre melhor procurar um profissional, mas o programa ajudaria a ter um norte e ainda me ajuda a melhor minhas capacidades de programação, já que sou iniciante

O código é esse:

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);

        // Pegando dados básicos
        System.out.print("Digite seu nome: ");
        String nome = scanner.nextLine();
        System.out.print("Digite seu peso (kg): ");
        double peso = scanner.nextDouble();
        System.out.print("Digite sua altura (cm): ");
        int altura = scanner.nextInt();
        System.out.print("Digite sua idade: ");
        int idade = scanner.nextInt();

        scanner.nextLine(); // Limpa buffer
        System.out.print("Digite seu sexo (M/F): ");
        String sexo = scanner.nextLine().toUpperCase();

        while (!sexo.equals("F") && !sexo.equals("M")) {
            System.out.print("Sexo inválido! Digite novamente (M/F): ");
            sexo = scanner.nextLine().toUpperCase();
        }

        // Definição do fator atividade
        double fatorAtividade;
        while (true) {
            System.out.println("Você se considera: " +
                    "\n1 - Pouco Ativo " +
                    "\n2 - Moderadamente Ativo " +
                    "\n3 - Muito Ativo");
            int atividade = scanner.nextInt();

            switch (atividade) {
                case 1:
                    fatorAtividade = 1.3;
                    break;
                case 2:
                    fatorAtividade = 1.5;
                    break;
                case 3:
                    fatorAtividade = 1.7;
                    break;
                default:
                    System.out.println("Opção inválida! Digite novamente.");
                    continue;
            }
            break;
        }


        // Cálculo da Taxa Metabólica Basal (TMB)
        double taxaMetabolicaBasal = (sexo.equals("M")) ?
                (13.75 * peso) + (5 * altura) - (6.75 * idade) + 66.5 :
                (9.56 * peso) + (1.85 * altura) - (4.68 * idade) + 65.71;

        // Cálculo do Gasto Energético Total (TMT)
        double taxaMetabolicaTotal = taxaMetabolicaBasal * fatorAtividade;

        // Déficit ou superávit
        System.out.print("Digite o valor da diferença de calorias que você quer ter (negativo para superávit): ");
        int defictKcal = scanner.nextInt();
        int kcalTotais = (int) (taxaMetabolicaTotal - defictKcal);

        // Cálculo de macronutrientes
        double gramaProteinas = 2 * peso;
        double gramaLipideos = 1 * peso;
        double kcalProteinas = gramaProteinas * 4;
        double kcalLipideos = gramaLipideos * 9;
        double kcalCarboidratos = kcalTotais - (kcalProteinas + kcalLipideos);
        double gramaCarboidratos = kcalCarboidratos / 4;

        // Exibição dos resultados
        System.out.println("\n---- Ficha Técnica ----\n");
        System.out.println("Nome: " + nome);
        System.out.println("Idade: " + idade + " anos");
        System.out.println("Altura: " + altura + " cm");
        System.out.println("Peso atual: " + peso + " kg\n");

        System.out.printf("Taxa Metabólica Basal (TMB): %.0f kcal\n", taxaMetabolicaBasal);
        System.out.printf("Gasto Total de Calorias (TMT): %.0f kcal\n\n", taxaMetabolicaTotal);

        System.out.println("Com o déficit de " + defictKcal + " kcal, você precisará comer:");
        System.out.println(kcalTotais + " kcal no total, sendo dessas:");
        System.out.printf("%.0f kcal de proteínas (%.0f g)\n", kcalProteinas, gramaProteinas);
        System.out.printf("%.0f kcal de lipídeos (%.0f g)\n", kcalLipideos, gramaLipideos);
        System.out.printf("%.0f kcal de carboidratos (%.0f g)\n", kcalCarboidratos, gramaCarboidratos);

        scanner.close();
    }
}

Sou iniciante e queria sugestões de como melhorar o código ou qualquer outra ideia, se puderem me ajudar eu agradecia.

Obrigado por ler até aqui :D

Carregando publicação patrocinada...
3

Olhei muito por cima e não sou programador de Java no dia-a-dia, mas posso dizer que está acima da média de quem está iniciando e não tem muitas coisas para melhorar neste exemplo. E o mais legal é que está fazendo o certo, começando pelo começo, tem gente que acha que vai aprender programar de verdade já fazendo algo complexo.

Entendo que os comentários são para efeitos didáticos, mas eles não são úteis de fato em código real, comente a fonte de onde achou a fórmula em vez de dizer algo que o nome da variável já diz. Comentários em código real devem dizer o porquê e não o que faz, o código bem feito já diz o que faz. Em alguns casos para ficar mais descritivo seria interessante criar uma função, mas acho exagero para este caso, acabaria complicando o código sem necessidade ou ganho expressivo, então toda regra depende de contexto, quem falar que nunca pode usar comentário só descritivo está errado. Esse é um aprendizado mais importante que muita coisa que fará em código.

Por que misturou println() com printf()? Não tem nada errado, mas o segundo costuma ser mais eficiente (este caso tão simples nem sei se realmente é, não conheço as otimizações que o Java faz), então porque não usar?

Outro ponto que poderia deixar mais eficiente, embora pouco importa para este exemplo, é só para aprender para o futuro, fazer um toUpperCase() é ineficiente, você pode comparar o texto ignorando a sensibilidade de caixa (case sensitive). Consegue pessquisar e ver como melhorar isso?

Em vez do switch poderia usar só matemática para chegar no fator necessário, resolver em uma linha. Ainda precisaria de um if para lidar com opção inválida.

Este trecho tem um duplicação de código, não é o fim do mundo, mas dá para fazer melhor. Consegue? Veja o outro while, você fez melhor.

    String sexo = scanner.nextLine().toUpperCase();

    while (!sexo.equals("F") && !sexo.equals("M")) {
        System.out.print("Sexo inválido! Digite novamente (M/F): ");
        sexo = scanner.nextLine().toUpperCase();
    }

Pode ser preciosismo, mas em sistema real todas as njtradas de dados deveriam ser validadas. Pense nisso como uma melhoria para melhorar os reuisitos, algo que pode ser mais importante que codificar.

Você sabe que os parênteses não são necessários na multiplicação? Não estou falando para tirar, mesmo sendo redundantes, deixa mais legível mesmo.

Você entende que double não trabalha com números exatos? Este caso eu acho que números exatos não são necessários, então está tudo bem, e números exatos em Java são ineficientes demais, então até que alguma versão mude isso, o ideal é só usar quando realmente é necessário.

Já fez um teste digitando absurdos como entrada? Letras, valores muito grandes, negativos, só dar enter, etc.?

S2


Farei algo que muitos pedem para aprender a programar corretamente, gratuitamente (não vendo nada, é retribuição na minha aposentadoria) (links aqui no perfil também).

1
1

Java é uma boa escolha, porque é o novo Cobol. Tem vaga em todo lugar, e por muito tempo ainda. Continua codando, não para.

Se me permite uma sugestão, quebra a função main em funções menores, e cria um record com os dados básicos. Um código estruturado em pequenos blocos fica mais legível (não sempre, mas ajuda).

Trabalhei anos com Java. Aí passei a fazer os testes em Groovy e quando voltava pro Java o System.out começou a sobrar. Depois de algum tempo acabei criando uma helper e dupliquei os métodos print, println e printf como estáticos para usar com static-import. Mesmo usando soh logger, as vezes precisava do print. Pra digitar a IDE até ajuda com autocomplete, mas ficar vendo esse System.out me incomoda bastante até hoje. Que coisa mal projetada da linguagem...