3
\$\begingroup\$

The following question was taken from Absolute Java 5th ed. by Walter Savitch:

Bicyclists can calculate their speed if the gear size and cadence is known. Gear size refers to the effective diameter of the wheel. Gear size multiplied by pi (3.14) gives the distance traveled with one turn of the pedals. Cadence refers to the number of pedal revolutions per minute (rpm).

The speed in miles per hour is calculated by the following:

Speed(mph)=  Gear Size (inches) * pi * 1(ft)/12 (inches) * 1(mile)/5280 (ft) * Cadence (rpm) * 60 (minutes)/(hour)   

This is a program that calculates the speed for a gear size of 100 inches and a cadence of 90 rpm. This would be considered a high cadence and a maximum gear size for a typical bicycle. In writing your program, don’t forget that the expression 1/12 will result in 0, because both 1 and 12 are integers, and when the integer division is performed, the fractional part is discarded.

This is the code that I have written:

    public class Question6 {

    private static final double PI = 3.14;
    private static final double gearSize = 100;
    private static final double cadence = 90;

    public static void main(String[] args) {
        System.out.println(getSpeed() + " mph");
    }

    private static double distancePerRevolution() {
        return gearSize * PI;
    }

    private static double feetPerInches() {
        return 1.0 / 12;
    }

    private static double milesPerFeet() {
        return 1.0 / 5280;
    }

    private static double minutesPerHour() {
        return 60;
    }

    private static double getSpeed() {
        return distancePerRevolution() * feetPerInches() * milesPerFeet()
                * cadence * minutesPerHour();
    }
}
\$\endgroup\$
1
  • 1
    \$\begingroup\$ not sure why any of those are functions when they are all constants \$\endgroup\$ – Keith Nicholas Sep 11 '14 at 5:30
6
\$\begingroup\$

Your question here is again an improvement over your previous version, but, I was hoping you would take some of the abstraction suggestions and apply them.

As it stands, your program is not a general purpose program, rather it is a complex constant value...

Let's look at the things that are actual constants:

  • PI - 3.14 (though, for more accuracy, use Math.PI constant).
  • 12 inches in a foot
  • 5280 feet in a mile
  • 60 minutes per hour

Those are your constants, and should be declared as private static final.

The things which are variables, are the cadence, and the 'gear size'.

A general purpose program would have a method that takes those two variables, and returns a speed....:

public static double calculateSpeed(double gearSize, double cadence) {...}

That method would be reusable, and general, and it exposes the right amount of functionality without exposing the inner workings of the class.

In your main method, if you would call:

System.out.println(calculateSpeed(100, 90) + "mph");

or rather, you would get the 100 and the 90 from somewhere else, perhaps a constant for the purpose of this exercise.

Now, how do you implement the calculateSpeed function? That is where the smarts of your program should be, and it should perhaps call other private methods, or do some basic calculations.

There are some style issues I see, but the most significant is that I always recommend using decimal-style typed values when you are using a double literal in your code. You have code like:

private static double feetPerInches() {
    return 1.0 / 12;
}

That produces the right results, but I recommend expressing the 12 as 12.0 to make the implicit conversions absolutely clear. I have seen too many times when bugs were introduced by integer arithmetic when floating-point was expected.

Bottom line, I would expect your program to look like:

private static final double PI = 3.14;
private static final double MINS_PER_HOUR = 60.0;
private static final double FEET_PER_MILE = 5280.0;
private static final double INCHES_PER_FOOT = 12.0;
private static final double INCHES_PER_MILE = FEET_PER_MILE * INCHES_PER_FOOT;

public static final double getSpeed(double gearSize, double cadence) {
    ....
}

public static void main(String[] args) {
    System.out.printf("%.3fmph%n", getSpeed(100.0, 90.0));
}

Note, I have used a printf at the end to simplify the logic of the output. Well, it is simpler for me, but, I thought you should see how printfs are used in Java. What that printf says, is print a floating-point value with 3 decimal places (%.3f), followed by 'mph', followed by a newline %n. The floating value to print is the speed.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.