0

I recently worked on a program that asked the user for his age in: years, months, and days.

After receiving that input, it had to calculate and print

a) Age in Seconds (totalAgeInSecs) and

b) the Amount of Seconds left to live. b is going to be based on the average lifespan in seconds (avgLifeSpan = 250000000000l. So secondsLeft = avgLifeSpan - totalAgeInSecs).

Anyway,I was able to get the program to work utilizing (switch) statements for simplicity purposes and not having to write a bunch of if/else statements, but I feel that in doing that, I ended up writing repetitive lines, and I'd like to be able to not have to repeat the calculation or the print statements.

I know there are classes and arrays I can combine with loops, but for the sake of simplicity and logic understanding I didn't use them to understand the bareback bones and logic of this project in "English." haha.

Anyway, check the code out below and let me know your thoughts on how to simplify the repetitive lines or better ways of approaching this. Thanks.

import java.util.*;

public class AgeInSeconds {

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

        int totalNumDays, daysInMonth, daysToHours;
        int yrsToDays,minsInHr, secsInMin;

        long timeRemaining, avgLifeSecs;

        System.out.println("Enter your age in years months and days: ");

        System.out.print("Years: ");
        int years = kbd.nextInt();

        System.out.print("Months: ");
        int months = kbd.nextInt();

        System.out.print("Days: ");
        int days = kbd.nextInt();

        yrsToDays = years * 365;
        avgLifeSecs = 2500000000l;

        switch (months){
        case 1: 
            daysInMonth = 31;
            totalNumDays = yrsToDays + daysInMonth + days;
            daysToHours = totalNumDays * 24;
            minsInHr = daysToHours * 60;
            secsInMin = minsInHr * 60;

            timeRemaining = avgLifeSecs - secsInMin;

            System.out.printf("You have been alive for %,d seconds.\n", secsInMin);
            System.out.printf("The average human life is  %,d seconds.\n", avgLifeSecs);
            System.out.printf("You have  %,d seconds.\n", timeRemaining);           
            break;
        case 2: 
            daysInMonth = 59;
            totalNumDays = yrsToDays + daysInMonth + days;
            daysToHours = totalNumDays * 24;
            minsInHr = daysToHours * 60;
            secsInMin = minsInHr * 60;

            timeRemaining = avgLifeSecs - secsInMin;    

            System.out.printf("You have been alive for %,d seconds.\n", secsInMin);
            System.out.printf("The average human life is  %,d seconds.\n", avgLifeSecs);
            System.out.printf("You have  %,d seconds.\n", timeRemaining);
            break;      
        case 3: 
            daysInMonth = 90;
            totalNumDays = yrsToDays + daysInMonth + days;
            daysToHours = totalNumDays * 24;
            minsInHr = daysToHours * 60;
            secsInMin = minsInHr * 60;

            timeRemaining = avgLifeSecs - secsInMin;

            System.out.printf("You have been alive for %,d seconds.\n", secsInMin);
            System.out.printf("The average human life is  %,d seconds.\n", avgLifeSecs);
            System.out.printf("You have  %,d seconds.\n", timeRemaining);
            break;      
        case 4: 
            daysInMonth = 120;
            totalNumDays = yrsToDays + daysInMonth + days;
            daysToHours = totalNumDays * 24;
            minsInHr = daysToHours * 60;
            secsInMin = minsInHr * 60;

            timeRemaining = avgLifeSecs - secsInMin;

            System.out.printf("You have been alive for %,d seconds.\n", secsInMin);
            System.out.printf("The average human life is  %,d seconds.\n", avgLifeSecs);
            System.out.printf("You have  %,d seconds.\n", timeRemaining);
            break;      
        case 5:
            daysInMonth = 151;
            totalNumDays = yrsToDays + daysInMonth + days;
            daysToHours = totalNumDays * 24;
            minsInHr = daysToHours * 60;
            secsInMin = minsInHr * 60;

            timeRemaining = avgLifeSecs - secsInMin;

            System.out.printf("You have been alive for %,d seconds.\n", secsInMin);
            System.out.printf("The average human life is  %,d seconds.\n", avgLifeSecs);
            System.out.printf("You have  %,d seconds.\n", timeRemaining);
            break;      
        case 6: 
            daysInMonth = 181;
            totalNumDays = yrsToDays + daysInMonth + days;
            daysToHours = totalNumDays * 24;
            minsInHr = daysToHours * 60;
            secsInMin = minsInHr * 60;

            timeRemaining = avgLifeSecs - secsInMin;
            System.out.printf("You have been alive for %,d seconds.\n", secsInMin);
            System.out.printf("The average human life is  %,d seconds.\n", avgLifeSecs);
            System.out.printf("You have  %,d seconds.\n", timeRemaining);           
            break;      
        case 7: 
            daysInMonth = 212;
            totalNumDays = yrsToDays + daysInMonth + days;
            daysToHours = totalNumDays * 24;
            minsInHr = daysToHours * 60;
            secsInMin = minsInHr * 60;

            timeRemaining = avgLifeSecs - secsInMin;
            System.out.printf("You have been alive for %,d seconds.\n", secsInMin);
            System.out.printf("The average human life is  %,d seconds.\n", avgLifeSecs);
            System.out.printf("You have  %,d seconds.\n", timeRemaining);       
            break;      
        case 8: 
            daysInMonth = 243;
            totalNumDays = yrsToDays + daysInMonth + days;
            daysToHours = totalNumDays * 24;
            minsInHr = daysToHours * 60;
            secsInMin = minsInHr * 60;

            timeRemaining = avgLifeSecs - secsInMin;
            System.out.printf("You have been alive for %,d seconds.\n", secsInMin);
            System.out.printf("The average human life is  %,d seconds.\n", avgLifeSecs);
            System.out.printf("You have  %,d seconds.\n", timeRemaining);

            break;

        case 9: 
            daysInMonth = 273;
            totalNumDays = yrsToDays + daysInMonth + days;
            daysToHours = totalNumDays * 24;
            minsInHr = daysToHours * 60;
            secsInMin = minsInHr * 60;

            timeRemaining = avgLifeSecs - secsInMin;
            System.out.printf("You have been alive for %,d seconds.\n", secsInMin);
            System.out.printf("The average human life is  %,d seconds.\n", avgLifeSecs);
            System.out.printf("You have  %,d seconds.\n", timeRemaining);           
            break;      
        case 10: 
            daysInMonth = 304;
            totalNumDays = yrsToDays + daysInMonth + days;
            daysToHours = totalNumDays * 24;
            minsInHr = daysToHours * 60;
            secsInMin = minsInHr * 60;

            timeRemaining = avgLifeSecs - secsInMin;
            System.out.printf("You have been alive for %,d seconds.\n", secsInMin);
            System.out.printf("The average human life is  %,d seconds.\n", avgLifeSecs);
            System.out.printf("You have  %,d seconds.\n", timeRemaining);           
            break;          
        case 11: 
            daysInMonth = 334;
            totalNumDays = yrsToDays + daysInMonth + days;
            daysToHours = totalNumDays * 24;
            minsInHr = daysToHours * 60;
            secsInMin = minsInHr * 60;
            timeRemaining = avgLifeSecs - secsInMin;

            System.out.printf("You have been alive for %,d seconds.\n", secsInMin);
            System.out.printf("The average human life is  %,d seconds.\n", avgLifeSecs);
            System.out.printf("You have  %,d seconds.\n", timeRemaining);
            break;      
        case 12:
            daysInMonth = 365;
            totalNumDays = yrsToDays + daysInMonth + days;
            daysToHours = totalNumDays * 24;
            minsInHr = daysToHours * 60;
            secsInMin = minsInHr * 60;

            timeRemaining = avgLifeSecs - secsInMin;

            System.out.printf("You have been alive for %,d seconds.\n", secsInMin);
            System.out.printf("The average human life is  %,d seconds.\n", avgLifeSecs);
            System.out.printf("You have  %,d seconds.\n", timeRemaining);

        default:

        }

        kbd.close();    

    }


}

This is the output when: years = 24, months = 5, days = 8.

Enter your age in years months and days: 
Years: 24
Months: 5
Days: 8
You have been alive for 770,601,600 seconds.
The average human life is  2,500,000,000 seconds.
You have  1,729,398,400 seconds.
Jens
  • 67,715
  • 15
  • 98
  • 113
mlopman
  • 67
  • 1
  • 1
  • 7
  • 2
    that´s a case where you should call a method and put the whole code in it. – SomeJavaGuy Sep 28 '15 at 07:58
  • 1
    What about leap years? Btw from the statistical point of view the result of the program is incorrect. What if I'm 100 years old? I have negative number of seconds? That does not make sense. – Tagir Valeev Sep 28 '15 at 08:01
  • This is indeed repeating a lot of code. Also, there is a thing called leap year. – laune Sep 28 '15 at 08:02
  • You should absolutely obviously extract case contents into a method which you call with `daysInMonth` argument – Alex Salauyou Sep 28 '15 at 08:02
  • 2
    Actually the whole approach is incorrect. If I'm 1 month old it does not mean that I'm 31 days old. It could be any amount of days from 28 to 31 depending on the current date. – Tagir Valeev Sep 28 '15 at 08:04
  • 1
    You have a major blunder in your code. First, nobody knows their age in years, months and days. But if they do: what does x years and y months mean? The second month doesn't have 28 days if the person is born in April or June... – laune Sep 28 '15 at 08:05
  • This code break principle Do Nor Repeat Yourself and many principles too (answer of Michale improves). 2. variable `daysInMonth ` is lying his sense (maybe days from begin of year?) – Jacek Cz Sep 28 '15 at 08:10

2 Answers2

2

To correctly calculate how many days the user is alive, you should first calculate his birthdate based on the supplied data and today's date. For example:

  • User is 1 month old, current date is Sept 28th 2015, thus user was born at Aug 28th 2015 and he is 31 days old.
  • User is 1 month old, current date is March 2nd 2015, thus user was born at Feb 2nd 2015 and he is 28 days old.

After that you can calculate the difference in seconds. There are ready classes and methods in Java API to do these steps. The easiest is to use Java 8 Time API:

import java.time.LocalDateTime;
import java.time.Period;
import java.time.temporal.ChronoUnit;
import java.util.Scanner;

public class AgeInSeconds {

    public static void main(String[] args) {
        try (Scanner kbd = new Scanner(System.in)) {

            System.out.println("Enter your age in years months and days: ");

            System.out.print("Years: ");
            int years = kbd.nextInt();

            System.out.print("Months: ");
            int months = kbd.nextInt();

            System.out.print("Days: ");
            int days = kbd.nextInt();

            Period period = Period.of(years, months, days);
            LocalDateTime now = LocalDateTime.now();
            LocalDateTime birthDate = now.minus(period);
            long seconds = birthDate.until(now, ChronoUnit.SECONDS);
            long avgLifeSecs = 2500000000l;
            long timeRemaining = avgLifeSecs - seconds;

            System.out.printf("You have been alive for %,d seconds.\n", seconds);
            System.out.printf("The average human life is  %,d seconds.\n", avgLifeSecs);
            System.out.printf("You have  %,d seconds.\n", timeRemaining);
        }
    }
}

I'm not addressing the statistical problem here. To calculate estimate remaining lifespan (provided I'm an average person) you should average the lifespan of the people who died older than me.

Tagir Valeev
  • 97,161
  • 19
  • 222
  • 334
  • I think you might be going over OP's head. I think he's in chapter 1 or chapter 2 of learn how to code ;-) good answer though, +1 – Tschallacka Sep 28 '15 at 08:29
0

Your integer daysInMonth will transfer past the switch statement. So you can just utilise the repetitive code after the switch statement.

As a rule of thumb: When you have repeating code put it in it's own method, or cosolidate the code so you only need to call it at one spot.

import java.util.*;

public class AgeInSeconds {

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

    int totalNumDays, daysInMonth, daysToHours;
    int yrsToDays,minsInHr, secsInMin;

    long timeRemaining, avgLifeSecs;

    System.out.println("Enter your age in years months and days: ");

    System.out.print("Years: ");
    int years = kbd.nextInt();

    System.out.print("Months: ");
    int months = kbd.nextInt();

    System.out.print("Days: ");
    int days = kbd.nextInt();

    yrsToDays = years * 365;
    avgLifeSecs = 2500000000l;

    switch (months){
    case 1: 
        daysInMonth = 31;
        break;
    case 2: 
        daysInMonth = 59;
        break;      
    case 3: 
        daysInMonth = 90;
        break;      
    case 4: 
        daysInMonth = 120;
        break;      
    case 5:
        daysInMonth = 151;
        break;      
    case 6: 
        daysInMonth = 181;
        break;      
    case 7: 
        daysInMonth = 212;
        break;      
    case 8: 
        daysInMonth = 243;
        break;

    case 9: 
        daysInMonth = 273;
        break;      
    case 10: 
        daysInMonth = 304;
        break;          
    case 11: 
        daysInMonth = 334;
        break;      
    case 12:
        daysInMonth = 365;
        break;
    default:
        daysInMonth = 0;
    }
    totalNumDays = yrsToDays + daysInMonth + days;
    daysToHours = totalNumDays * 24;
    minsInHr = daysToHours * 60;
    secsInMin = minsInHr * 60;

    timeRemaining = avgLifeSecs - secsInMin;

    System.out.printf("You have been alive for %,d seconds.\n", secsInMin);
    System.out.printf("The average human life is  %,d seconds.\n", avgLifeSecs);
    System.out.printf("You have  %,d seconds.\n", timeRemaining);           

    kbd.close();    

}


}

The above is a "quick and dirty" solution to your code so you can see how you can transfer variables past an switch statement.

Better practise it would be to use an modulus operator to check if it's odd or even and if it's not month two, give the correct value.

import java.util.*;

public class AgeInSeconds {

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

    int totalNumDays, daysInMonth, daysToHours;
    int yrsToDays,minsInHr, secsInMin;

    long timeRemaining, avgLifeSecs;

    System.out.println("Enter your age in years months and days: ");

    System.out.print("Years: ");
    int years = kbd.nextInt();

    System.out.print("Months: ");
    int months = kbd.nextInt();

    System.out.print("Days: ");
    int days = kbd.nextInt();

    yrsToDays = years * 365;
    avgLifeSecs = 2500000000l;
    /** predifine with 0 so we always have a value **/
    daysInMonth = 0;
    /** Our months here. Please consider using calendar **/
    int[] legaldays =  {31,28,31,30,31,30,31,31,30,31,30,31};
    /** Looping through all months **/
    for(i=0;i<legaldays.length;i++) { 
       /** check if we didn't pass our max limit **/
       if(i+1 > daysInMonth) {
          break;
       }
       /** add the days to our tally **/
       daysInMonth += legaldays[i];
    }
    totalNumDays = yrsToDays + daysInMonth + days;
    daysToHours = totalNumDays * 24;
    minsInHr = daysToHours * 60;
    secsInMin = minsInHr * 60;

    timeRemaining = avgLifeSecs - secsInMin;

    System.out.printf("You have been alive for %,d seconds.\n", secsInMin);
    System.out.printf("The average human life is  %,d seconds.\n", avgLifeSecs);
    System.out.printf("You have  %,d seconds.\n", timeRemaining);           

    kbd.close();    

   }    
}

See the comments to know how I improved it. By looping you take yourself off the headache of having to hardcode the values of the months days and it gives you an amount of flexibility. For a more reliable day count instead of hardcode I suggest you look at Number of days in a month of a particular year so you can be flexible with leap years and such.

When ever possible try to not hardcode intangible or dynamic data values, but try to deduct them accurately. Dates are notoriously hard to keep in order.

Community
  • 1
  • 1
Tschallacka
  • 27,901
  • 14
  • 88
  • 133
  • Ever used an array for storing values based on 1..12 (or 0..11)? – laune Sep 28 '15 at 08:02
  • I considered that, but what int he case of invalid input. plus i'm still editing putting in some best practises. – Tschallacka Sep 28 '15 at 08:03
  • Also consider that the approach proposed by OP is nonsense. If I'm x years and 5 months today, the second month sure doesn't have 28 days. – laune Sep 28 '15 at 08:07
  • This is semi-correct answer - at low question level. +1 from me. Bad question, answer cannot be splendid. BTW variable `daysInMonth ` is lying his sense. Theoretically goal from question has many implementations, like `final int ml[] = ...} ` with `if` at february etc ... – Jacek Cz Sep 28 '15 at 08:09
  • yea, i'm not happy with this question either, but i have the sense that OP wants to learn how to code. And looking at this repetitive code I kinda try to mold my answer to his level so he can understand it. obviously op is still a newbie, and needs a different approach than an experienced programmer. – Tschallacka Sep 28 '15 at 08:25