Difference between revisions of "Cycling Speed"

From CompSciWiki
Jump to: navigation, search
m
m
 
(30 intermediate revisions by 3 users not shown)
Line 3: Line 3:
 
|ProblemName=Find out your bicycle's speed
 
|ProblemName=Find out your bicycle's speed
  
|Problem=You are an employer on the software team of Bikers Forever, a bicycle company. The software team uses Java and the knowledge of the Java SDK to write programs for Biker Forever. You are a great COMP 1010 student so you already have an idea of writing in Java, so in breathless anticipation, you await your next assignment from the head of the software team :)  
+
|Problem=
 +
<p>
 +
You are an employee on the software team of Bikers Forever, a bicycle company. The software team uses Java and the  
 +
knowledge of the Java SDK to write programs for Bikers Forever. You are a great COMP 1010 student so you already know a
 +
bit about writing in Java, so in breathless anticipation, you await your next assignment from the head of the software team :)  
 +
</p>
  
 
<p>
 
<p>
You arrive at your desk on Monday morning and open your email in-box (as usual) to see this message from the head:
+
You arrive at your desk on Monday morning and open your email in-box (as usual) to see this  
 +
message from the head of the software team:
 
</p>
 
</p>
  
Line 12: Line 18:
 
Hi <insert name here>,
 
Hi <insert name here>,
  
<br />
+
<br /><br />
I need you to write a program that allows customers who visit the Bicycle Forever to calculate the speed of their bicycles. One of the members of the team stumbled upon the formula to calculate cycling speed, and knowing you are just itching for an assignment, I thought of you straightaway to implement it. The program description and the formula is below:
+
I need you to write a program that will allow customers who visit the Bicycle Forever to  
 +
calculate the speed of their bicycles. One of the members of the team stumbled on the formula to  
 +
calculate cycling speed, and knowing that you are just itching for an assignment, I thought of you  
 +
straightaway to implement the formula. The program description and the formula is below:
 
</p>
 
</p>
  
 
<p>
 
<p>
Program Description
+
<b>Program Description</b>
  
 
<br />
 
<br />
1) The program will prompt the user to input a) The RPM (rotations per minute) of the bicycle, and b) The number of teeth in the rear gear
 
  
2) The program will also store as constants the number of teeth in the front gear and the diameter of the bicycle wheel. Assume the number of front teeth to be 45 and the diameter to be 70cm always.
+
<ol>
 +
<li> The program will prompt the user to input
 +
 
 +
<ul>
 +
<li>The RPM (rotations per minute) of the bicycle
 +
<li>The number of teeth in the rear gear of the bicycle
 +
</ul>
 +
 
 +
<li>The program will also store as constants the number of teeth in the front gear and the diameter  
 +
of the bicycle wheel. Assume the number of front teeth to be 45 and the diameter to be 70cm every-time.
 +
</ol>
 
</p>
 
</p>
  
 
<p>
 
<p>
Formula
+
<b>Formula</b>
  
 
<br />
 
<br />
1) Before you calculate the speed, you must first calculate the <b>meters of development</b>. This is the length in meters covered by each rotation of the wheel of the bicycle. Meters of development (mdev, as we'll call them) are calculated this way:
+
<ol>
 +
<li>Before you calculate the speed, you must first calculate the <b>meters of development</b>.  
 +
This is the length in meters covered by each rotation of the wheel of the bicycle.  
 +
Meters of development (mdev, as we'll call them) are calculated this way:
  
 
<pre>
 
<pre>
mdev = circumference[m] * (number front teeth / number rear teeth)
+
mdev = circumference[m] * (number front teeth / number rear teeth)  
 
</pre>
 
</pre>
  
2) Finally, now that we have the mdev we can calculate the speed:
+
<li>Finally, now that we have the mdev we can calculate the speed:
  
 
<pre>
 
<pre>
speed = mdev * rpm * 60/1000
+
speed = mdev * rpm * 60/1000 //Note that 60/1000 helps to calculate the speed in kilometers per hour
 
</pre>
 
</pre>
 +
</ol>
 
</p>
 
</p>
  
 
<p>
 
<p>
Print out
+
<b>Output</b>
  
To display your results, assuming a customer inputs 75 for RPM and 20 for rear teeth, the output will be displayed this way:
+
<br /><br />
 +
To display your results, assuming a customer inputs 75 for RPM and 20 for  
 +
rear teeth, the output will be displayed this way:
  
 
<pre>
 
<pre>
Line 57: Line 81:
 
</pre>
 
</pre>
  
 +
Thanks!, <insert name here>, I am confident you will do a great job.<br />
 +
The Boss
 
</p>
 
</p>
  
<p>
+
|Solution=
For example, the ISBN of the COMP 1010 textbook, “Starting Out With Java” is 0-321-47927-0.
+
The user will input the first 9 digits: 032147927
+
The program will calculate the weighted value of the textbook’s ISBN:
+
<pre>
+
7*9 + 2*8 + 9*7 + 7*6 + 4*5 +1*4 + 2*3 + 3*2 + 0*1 = 220
+
</pre>
+
The program will use the modulus operator to divide the sum of 220 by 11 and find the remainder. In this
+
example, the remainder is 0; so the check digit is 0:
+
<pre>
+
220 % 11 = 0
+
</pre>
+
Check out the back of the text: indeed, the 10th digit of the ISBN is 0!
+
</p>
+
<p>
+
Please note that if the check digit is ten, just output 10, even though the check digit should be only one digit long. In real
+
life, an ISBN check digit of 10 is written as X. But for this program, just output 10. For example, try entering
+
the first nine digits of the ISBN 0-7747-3776-X.
+
</p>
+
<p>
+
For more information on the ISBN check digits, please view [http://www.cs.queensu.ca/~bradbury/checkdigit/isbncheck.htm Queen's University page on ISBN check digits].
+
</p>
+
  
 +
[[Image:Bicyclist.jpg|200px|alt=Eddie Root, famous Australian rugby player riding a bicycle|]]
  
With this knowledge you take a deep breath and look at the messy code:
+
To program our solution, we will go through 4 steps:
 +
<ol>
 +
<li>Identify and declare all variables and constants necessary to implement the solution
 +
<li>Store user input on bicycle information
 +
<li>Perform the calculations for the meters of development and then the speed of the bicycle
 +
<li>Output the results
 +
</ol>
 +
In addition, we will be sure to comment through out our code, and follow correct programming standards as stated in [http://courses.cs.umanitoba.ca/Documents/104913/1010standards.pdf]
  
<pre>
+
==Identify and Declare all Variables and Constants==
import javax.swing.*;
+
Based on The Boss's email to you, and the description of the program and formula, we can
import java.util.Date;
+
easily identify all the variables and constants important to the solution. <br /> <b>NOTE:</b> some
 +
of these variables are dependent on the others.  
  
public class MessyCode_ISBN{
+
<br />
 +
===Constants===
 +
<ul>
 +
<li>The number of front wheel teeth - assumed to be 45 every-time</li>
 +
<li>The diameter of the wheel - assumed to be 70cm every-time</li>
 +
</ul>
  
    public static void main (String [] args) {
 
        String temp = JOptionPane.showInputDialog("");int isbn = Temp;
 
        int digit1 = (isbn % 10);int total = digit1 * 9;isbn = isbn / 10;
 
        int digit2 = (isbn % 10);total = total + digit2 * 8;isbn = isbn / 10;
 
        int digit3 = (isbn % 10);total = total + digit3 * 7;isbn = isbn // 10;
 
        int digit4 = (isbn % 10) total = total + digit4 + 6;isbn = isbn / 10;
 
        int digit5 = (isbn / 10);total = total + digit5 * 5;isbN = isbn / 10;
 
        int digit6 = (isbn % 10);total = total + digit6 * 4;isbn = isbn / 10;
 
int digit7 = (isbn % 10);total = total + digit7 * 3;isbn = isbn / 10;
 
int digit8 = (isbn % 10);total = total + digit8 * 2;isbn = isbn / 10;
 
int digit9 = (isbn * 10);total = total + digit9 - 1;isbn = isbn / 10;int checkDigit = total % 11;
 
        System.out.println ("The weighted total is: " + total +
 
                            "\nThe check digit is : " + checkDigit +
 
                            "\n\nThe 10-digit ISBN is: " + temp + checkDigit);
 
  
        System.out.println("\nProgrammed by Sloppy the Programmer");
+
====Declaration of Constants====
        System.out.println("Date: " + new Date());
+
When declaring constants, we use the keyword <b>final</b>. This ensures that whether it is
        System.out.println ("*** End of Processing ***");
+
an int, double, string or any other data type, it cannot be overwritten.  
        }
+
 
}
+
<br/><br />
 +
As the number of front wheel teeth is a number, we will declare it using "final int"
 +
 
 +
<pre>
 +
final int FRONT_TEETH = 45;
 
</pre>
 
</pre>
  
The code that was produced was such a mess that the employee was let go. Since you are the person to fill the newly available position, it only makes sense that you take over the project.
+
We also know the constant for the diameter is 70cm every-time. However, the diameter is
Complete the following tasks on the code below:
+
not used in the calculations. Rather, the circumference is used to calculate the meters of development.  
<ul>
+
<li>Organize the code.</li>
+
<li>Add comments to explain the code.</li>
+
<li>Optimize the code by removing unnecessary variables.</li>
+
<li>Find any errors in the code.</li>
+
<li>Add code to output progress reports as the program executes.</li>
+
</ul>
+
Remember to abide by the company coding standards while repairing the code.
+
  
 +
<br />So what should we do???
  
|Solution=
+
<br />
There are nine steps to improve this messy code so it complies with the company (and coincidentally, comp 1010) coding standards:
+
It's simple! Going back to your high school days you know that the <b>Circumference of a circle (wheel) = 3.14 (pi) * the diameter</b>.
  
 +
<ul>
 +
<li>Pi in Java has been provided for us through <b>Math.PI</b> </li>
 +
<li> We also want to make sure we divide by 100.0 because our diameter is in centimeters
 +
right now as opposed to the meters we need to calculate the meters of development (if you remember!)</li>
 +
<li>And finally, our constant will be a "final int double" to represent the circumference. We declare and calculate the circumference right away since we already know the diameter and we use a double to accommodate the decimal spaces</li>
 +
</ul>
  
==Organize the Code==
+
<br/>
First, organized code is vital to the readability of the code. The [http://courses.cs.umanitoba.ca/index.asp?sec=3394&too=30&eve=1&ppa=5178 COMP 1010 Coding Standards] give the foundation required to complete the code organization task for this [[Case_Study_I|case study]]. Each of the headings below describe a specific task that helps organize the code.
+
Therefore our declaration becomes:
  
===Separate the Statements===
 
The code file contains more than one [[Your First Java Program#Statements|statements]] on each line.
 
 
<pre>
 
<pre>
int digit1 = (isbn % 10);int total = digit1 * 9;isbn = isbn / 10;
+
final double WHEEL_CIRCUMFERENCE = (70 * Math.PI)/100.0;
int digit2 = (isbn % 10);total = total + digit2 * 8;isbn = isbn / 10;
+
 
</pre>
 
</pre>
Each of the above lines of code performs a similar function. Each line can be interpretted as a block of code. By placing each [[Your First Java Program#Statements|statements]] on a separate line and grouping the statements into appropriate code blocks, the result should look something like the following:
+
 
 +
Now that we have our constants, let go ahead to declare the rest of the variables we
 +
will need based on the formula. We will also include a string variable to store our user's input.
 +
 
 
<pre>
 
<pre>
int digit1 = (isbn % 10);
+
int rpm;
int total = digit1 * 9;
+
int rearTeeth;
isbn = isbn / 10;
+
double mdev; //a double because it will contain decimal spaces because of the circumference
int digit2 = (isbn % 10);
+
double speed;
total = total + digit2 * 8;
+
String input;
isbn = isbn / 10;
+
 
</pre>
 
</pre>
By placing each of the [[Your First Java Program#Statements|statements]] on a separate line, the readability of the code increases dramatically.
 
  
===Separate Statements into Code Blocks===
+
==Store user Input on Bicycle Information==
Once the [[Your First Java Program#Statements|statements]] are readable, the next step would be to organize them into code blocks as stated in [http://courses.cs.umanitoba.ca/index.asp?sec=3394&too=30&eve=1&ppa=5178 COMP 1010 Coding Standards]. Continuing with our previous example, the functionality of the code can be broken into two distinct code blocks.
+
In order to retrieve user input, we will be using the class JOptionPane. We are able to call this
 +
class and its methods when we type in "import javax.swing.*;" at the top of our program.
 +
Future computer science courses will explain what the <b>import</b> statement does.
 +
 
 +
<br />How JOptionPane works:
 +
JOptionPane has an InputDialog method which shows a dialog box and accepts input typed into that box.
 +
This input can then be stored in strings. What we will do in this case, is store the user input
 +
into strings and parse (convert) them to integers using Integer.parseInt.
 +
 
 +
<br />How Integer.parseInt works:
 +
Integer.parseInt accepts a string and converts it to an int. The string however must
 +
contain numbers only or bad things happen :)
 +
 
 +
<br />
 +
Below is our Java code showing the storage of input and conversion to actual integers.
 +
 
 
<pre>
 
<pre>
int digit1 = (isbn % 10);
+
input = JOptionPane.showInputDialog ("Enter rpms.");
int total = digit1 * 9;
+
rpm = Integer.parseInt(input);
isbn = isbn / 10;
+
  
int digit2 = (isbn % 10);
+
input = JOptionPane.showInputDialog ("Enter number of teeth on rear gear.");
total = total + digit2 * 8;
+
rearTeeth = Integer.parseInt(input);
isbn = isbn / 10;
+
 
</pre>
 
</pre>
Almost each line of code in the messy code file can be considered a separate code block. Take the time to read the code and understand how everything works together before deciding which [[Your First Java Program#Statements|statements]] should be grouped together.
 
  
One of the code blocks that should be added is a variable declaration code block at the beginning of [[Your First Java Program#The Main Method|the main method]]. Throughout the [[Case Study I#Code|messy code]], integers are declared. All of the [[Variables and Literals#Variables|declaration statements]] should be placed at the beginning of [[Your First Java Program#The Main Method|the main method]] to ensure the code stays organized. Going to the previous example, two [[Variables and Literals#Variables|declaration statements]] can be moved to the top as depicted below.
+
Now we have all the user input we need to perform the calculations.  
<pre>
+
int digit1;
+
int digit2;
+
  
digit1 = (isbn % 10);
+
==Perform the Calculations==
int total = digit1 * 9;
+
We have the directions from The Boss, and we have all the variables and user input we require. Now we calculate!
isbn = isbn / 10;
+
  
digit2 = (isbn % 10);
+
<br />
total = total + digit2 * 8;
+
Following instructions we calculate the meters of development first. As per the email:
isbn = isbn / 10;
+
</pre>
+
  
===Add Comments to Explain the Code===
+
mdev = circumference[m] * (number front teeth / number rear teeth).
The [http://courses.cs.umanitoba.ca/index.asp?sec=3394&too=30&eve=1&ppa=5178 COMP 1010 coding standards], or the Funky Books Inc. coding standards, make numerous points concerning [[Comments|comments]] in code. To be specific, statements 1, 2, 4, and 7 can be applied to the code file for this [[Case Study I|case study]]. All major code blocks should be identified by now. Look over each code block and briefly explain what it does in a comment. Since all [[Variables and Literals#Variables|declaration statements]] have been moved to the top of the [[Your First Java Program#The Main Method|the main method]] , make sure to apply coding standard 7 from the [http://courses.cs.umanitoba.ca/index.asp?sec=3394&too=30&eve=1&ppa=5178 COMP 1010 Coding Standards].  
+
  
==Optimize the Code by Removing Unnecessary Variables==
+
Translating this into Java code:
At the top of [[Your First Java Program#The Main Method|the main method]], there should now be a number of [[Variables and Literals#Variables|variables]]
+
declared. Notice that there are nine different "digit" [[Variables and Literals#Variables|variables]] which are only used once to store the same calculation.
+
  
 
<pre>
 
<pre>
int digit1;
+
mdev = WHEEL_CIRCUM * (FRONT_TEETH / (double)  rearTeeth); //Remember to cast variable
int digit2;
+
//rearTeeth as a double or you will get an int value for your result. That would be wrong! doubles/doubles = doubles :)
 +
</pre>
  
digit1 = (isbn % 10);
+
Next we calculate the speed:
int total = digit1 * 9;
+
isbn = isbn / 10;
+
  
digit2 = (isbn % 10);
+
speed = mdev * rpm * 60/1000
total = total + digit2 * 8;
+
isbn = isbn / 10;
+
</pre>
+
The code sample from above shows two of the nine digit [[Variables and Literals#Variables|variables]]. These two [[Variables and Literals#Variables|variables]] can be replaced with a single one as follows:
+
<pre>
+
int digit;
+
  
digit = (isbn % 10);
+
Translating this into Java code:
int total = digit * 9;
+
isbn = isbn / 10;
+
  
digit = (isbn % 10);
+
<pre>
total = total + digit * 8;
+
speed = mdev * rpm; //speed in meters per minute
isbn = isbn / 10;
+
speed = speed * (60.0 / 1000); //speed in km per hour
 
</pre>
 
</pre>
  
==Fix the Errors in the Code==
+
I took the liberty of breaking the speed calculation into meters per minute and multiplying
The [[Case Study I#Code|messy code]] contained a total of eight different coding errors. Each error presented in this section is ordered as it appears in the [[Case Study I#Code|code]] from the [[Case Study I|case study]].
+
it by 60.0/1000 in order to provide the result in kilometers per hour (the normal speed scale).
===Error One===
+
 
 +
==Output the Results==
 +
The outputs should closely resemble something like this:
 +
 
 
<pre>
 
<pre>
String temp = JOptionPane.showInputDialog("")
+
You have entered 75 RPM and 20 rear teeth.
</pre>
+
Meters of development: 4.948008429403924
Technically, the above code does not break the functionality of the application as the method call still makes the [[Input using JOptionPane#Input Dialog|input dialog]] appear to take input from the user. Although, from a usability standpoint the code does cause an error. The user who is running the application needs to know what to enter as input into the [[Input using JOptionPane#Input Dialog|input dialog]]. Without a proper message, the user cannot be expected to know what the application is expecting as input. An example of a proper message is as follows:
+
Speed [km/hour]: 22.266037932317655
<pre>
+
temp = JOptionPane.showInputDialog("Enter the first 9 digits of a 10-digit ISBN number.");
+
</pre>
+
  
===Error Two===
+
Programmed by Bicycle Forever
<pre>
+
Date: September 18, 2008
int isbn = Temp;
+
*** End of Processing ***
</pre>
+
There are two problems with the above code sample. The first problem being that the [[Variables and Literals#Variables|variable]] "Temp" is of type [[Strings|string]] and not of the primitive type [[Common Primitive Variables#Primitive Type int|int]]. The second problem is the name of the [[Variables and Literals#Variables|variable]] "Temp". The [[Variables and Literals#Variables|variable]] was originally declared as "temp" and Java is a [[Your First Java Program#Case Sensitivity|case sensitive]] language. Both programs are repaired by replacing the code with the line below.
+
<pre>
+
isbn = Integer.parseInt(temp);
+
 
</pre>
 
</pre>
  
===Error Three===
+
Let us do a breakdown of the output, line by line.
 +
 
 +
Line 1: "You have entered 75 RPM and 200 rear teeth"
 +
This result can be printed immediately after you have read user input and converted the input to integers.
 +
Printing out the input will also help to confirm that it was stored correctly. In this case:
 +
 
 
<pre>
 
<pre>
isbn = isbn // 10;
+
System.out.println ("You have entered " + rpm + " rpms and " + rearTeeth + " rear teeth");
</pre>
+
An extra front slash changes the [[Arithmetic Operators|division operation]] into a comment which also comments out the semi-colon required at the end of every [[Your First Java Program#Statements|statement]]. Remove the extra front slash to correct the error.  
+
<pre>
+
isbn = isbn / 10;
+
 
</pre>
 
</pre>
  
===Error Four===
+
Line 2: "Meters of development: 4.948008429403924"
 +
This can be printed immediately after the calculation of the meters of development.
 +
 
 
<pre>
 
<pre>
digit = (isbn % 10)  
+
System.out.println("Meters of development: " + mdev);
 
</pre>
 
</pre>
The [[Your First Java Program#Statements|statement]] above is missing the semi-colon at the end of the line. Add the semi-colon to fix the error.
+
 
 +
Line 3: "Speed [km/hour]: 22.266037932317655"
 +
The speed also, can be printed out after its calculation has been done.
 +
 
 
<pre>
 
<pre>
digit = (isbn % 10);
+
System.out.println("Speed [km/hour]: " + speed);
 
</pre>
 
</pre>
  
===Error Five===
+
To complete the process we can write code to print out the rest of the output.
<pre>
+
total = total + digit + 6;
+
</pre>
+
This error is known as a run time error. A run time error does not cause a compilation error, but it causes the program to produce incorrect results. In the explaination of the [[Case Study I#ISBN Check Digit Overview|ISBN check digit]], the sixth ISBN number should be multiplied by six, not added. This error is fixed by changing the second [[Arithmetic Operators|addition]] operation to a [[Arithmetic Operators|multiplication]] operation.
+
<pre>
+
total = total + digit * 6;
+
</pre>
+
  
===Error Six===
 
 
<pre>
 
<pre>
digit = (isbn / 10);
+
System.out.println("\nProgrammed by Bicycle Forever");
</pre>
+
System.out.println("Date: ");
Just like [[#Error Five|error five]], the above [[Your First Java Program#Statements|statement]] causes a run time error. To isolate the last digit in the ISBN number, the ISBN must have the [[Arithmetic Operators|modulus operator]] applied, not the [[Arithmetic Operators|division operator]]. The above statement is fixed by replacing the [[Arithmetic Operators|division operator]] with the [[Arithmetic Operators|modulus operator]].  
+
System.out.println ("*** End of Processing ***");
<pre>
+
digit = (isbn % 10);
+
 
</pre>
 
</pre>
  
===Error Seven===
+
You will notice that the output for the date above is empty. You can hardcode the
 +
date in i.e. type it right into the program as part of the output, or use the Calendar class to show the
 +
current date every-time the program is run. I have included the process for showing the current date in the bonus
 +
section below.
 +
 
 +
==Bonus Section: Outputting the Current Date==
 +
Just like we used the <b>import</b> statement in the [[#Store user input on bicycle information|Storing User Input]]
 +
section, we will also be using this statement to access the Calendar class in order to get the current date.
 +
 
 +
You can tell what import statement to use by going through the Java API
 +
documentation: [http://download.oracle.com/javase/1.5.0/docs/api/]. The documentation also explains what
 +
classes are available and the methods attached to them.
 +
 
 +
For the purpose of this solution, we will be including import statements that will:
 +
<ul>
 +
<li>Give us access to the Calendar class and a method that provides the current time
 +
<li>Give us access to a SimpleDateFormat class and a method that helps format the current time
 +
</ul>
 +
 
 
<pre>
 
<pre>
digit = (isbn * 10);
+
import java.text.SimpleDateFormat;
</pre>
+
import java.util.Calendar;
The above [[Your First Java Program#Statements|statement]] is almost identical to [[#Error Six]]. The [[Arithmetic Operators|multiplication operator]] should be replaced with the [[Arithmetic Operators|modulus operator]].
+
<pre>
+
digit = (isbn % 10);
+
 
</pre>
 
</pre>
  
===Error Eight===
+
Now that we have included the import statments, we can call the Calendar class and
 +
its method getInstance() to give us a working calendar, and then call the SimpleDateFormat class that
 +
we shall provide with a format for outputting the current time:
 +
 
 
<pre>
 
<pre>
total = total + digit - 1;
+
Calendar calendar = Calendar.getInstance();
 +
SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy");
 
</pre>
 
</pre>
The error in the code above is [[#Error Five|error five]] almost identical to [[#Error Five]]. Replace the [[Arithmetic Operators|subtraction operator]] with the [[Arithmetic Operators|multiplication operator]] to remedy this error.
+
 
 +
Now that we have a working calendar, we will add the output gotten from formatting the current
 +
time of the Calendar (using the SimpleDateFormat class) into our solution output. This is the
 +
line that provides the output:
 +
 
 
<pre>
 
<pre>
total = total + digit * 1;
+
System.out.println("Date: " + dateFormat.format(calendar.getTime()));
 
</pre>
 
</pre>
  
==Add Code to Output Progress Reports as the Program Executes==
+
==Commenting and Testing==
To add progress reports to the program, three things need to be addressed:
+
Although we have our calculations done and our output printed, we aren't done yet! For the sake
 +
of others, who will read your code, commenting must be done. Using the "//" characters, comment
 +
major lines to show what you are doing. This improves readability and tells The Boss that you are a professional.
 +
 
 +
In addition, you want to test your code, right after every calculation to be sure you
 +
do not provide a wrong bicycle speed. A program that outputs the wrong speed of a bicycle can make
 +
bad things happen! Therefore, check to be sure
 
<ul>
 
<ul>
<li>Where to place the progress reports</li>
+
<li>Input is entered and converted correctly</li>
<li>What progress should be reported</li>
+
<li>Calculations are done correctly</li>
<li>Adding the code to report progress</li>
+
<li>Results are output correctly</li>
 
</ul>
 
</ul>
By adding code to report on the status of the application, the user and yourself know what is happening behind the scenes when the program is executing. For a small application like this [[Case Study I|case study]] it may seem trivial. It is a good practice to get into as in larger programs consisting of many files each with many methods, it can be difficult to locate a run-time error in your code if the program does not explicitly say what it is currently doing.
+
I have included comments and tests using System.out.println() in the sample source code for your benefit.
  
===Location===
+
===COMPLETE!===
By now the code file should be broken up into multiple code blocks, as done [[#Separate the Statements into Code Blocks|earlier in this solution]]. Each code block should represent a major code segment in the program. Each code block can be considered a potential point for a progress report. Read over the code and decide which are vital points in the execution of the program.
+
  
===Report Content===
+
Congratulations!  You have now finished your Cycling Speed program. You can now compile and run your program. You can also click the Solution button below to see a full solution.
The next step is to decide what should be outputted to describe the progress of the program. This output can be the current value of a [[Variables and Literals|variable]], an output statement saying that the program has reached a certain point in the code, or potentially a combination of both. A progress report should output data on the program that is relevant to its execution. For this [[Case Study I|case study]], each calculation performed on the ISBN is vital to determining the check digit, therefore a progress report should output the value of each calculation.
+
 
+
===Adding Output Code===
+
The best way to add output to the program is by adding [[Output using System.out|System.out]] statements to the appropriate code blocks. When adding the code, make sure the message that will be outputted is unique in comparison to the other progress report [[Your First Java Program#Statements|statements]]. Each statement should be unique as they are meant to identify the section of code being executed. If the statements are not unique, then there will be no way of telling which progress report has been outputted. Here is an example of the code before adding a [[Output using System.out|System.out]] statement.
+
<pre>
+
//isolate last digit and multiply by 9
+
digit = (isbn % 10);
+
total = digit * 9;
+
isbn = isbn / 10;
+
</pre>
+
After the output [[Your First Java Program#Statements|statement]] is added, the code will look like the following:
+
<pre>
+
//isolate last digit and multiply by 9
+
digit = (isbn % 10);
+
total = digit * 9;
+
isbn = isbn / 10;
+
System.out.println (digit + " * " + 9 + " for a running total of " + total);
+
</pre>
+
When the program is executing, the following output will appear in the progress window. The ISBN number used as input for the example below is 1-2345-6789.
+
<pre>
+
9 * 9 for a running total of 81
+
</pre>
+
Now the you will know what part of the code is being executed along with the status of the current calculation.
+
 
+
Remember that this is not the only "correct" progress report. There can be many different progress reports based on how the vital points of the program were interpreted. Although, in this [[Case Study I|case study]] the calculations are exceptionally important points to the correct execution of the program.
+
  
 
|SolutionCode=
 
|SolutionCode=
 
import javax.swing.*;
 
import javax.swing.*;
import java.util.Date;
+
import java.text.SimpleDateFormat;
 +
import java.util.Calendar;
  
 
/**
 
/**
  * calculate a check digit for ISBNs
+
  * calculate the speed of a bicycle
 
  *
 
  *
  * @author:    1010 Instructors
+
* Bicycle Forever
  * @version:    2007-September
+
  * @author:    <insert name here>
 +
  * @version:    2011-March
 
  */
 
  */
  
public class CaseStudy1_ISBN_Solution
+
public class BicycleSpeed {
{
+
     /**....................................................main<br>
     /**
+
     * PURPOSE: inputs RPM and Number of Teeth and output speed
     * PURPOSE: inputs a 9-digit ISBN, calculates the check digit and outputs a 10-digit ISBN
+
 
     */
 
     */
     public static void main (String [] args)  
+
     public static void main (String [] args) {
    {
+
  
         //variables declared here
+
        //constants
         String temp;         //temporary input string
+
        final int FRONT_TEETH = 45;
         int isbn;           //9-digit ISBN
+
        final double WHEEL_CIRCUM = (70 * Math.PI)/100.0;  //diameter of wheels is 70cm; convert to circumference in meters
         int digit;           //isolated ISBN digit
+
         int total;           //total of isbn number when each digit is multiplied by check value
+
         //variables
         int checkDigit;     //value of total%11(as per ISBN standard)
+
         String input;                       //inputorary input string
 +
         int rpm ;                           //rpms
 +
         int rearTeeth;                     //number teeth in rear gear
 +
         double mdev ;                       //= circ [m] * (frontTeeth / REAR_TEETH)
 +
         double speed;                       //= mdev * rpm (speed in meters per minute)
  
 
         //get input
 
         //get input
         temp = JOptionPane.showInputDialog
+
         input = JOptionPane.showInputDialog ("Enter rpms.");
         ("Enter the first 9 digits of a 10-digit ISBN number.");
+
         rpm = Integer.parseInt(input);
        isbn = Integer.parseInt(temp);
+
 
 +
        input = JOptionPane.showInputDialog ("Enter number of teeth on rear gear.");
 +
rearTeeth = Integer.parseInt(input);
  
 
         //confirm input
 
         //confirm input
         System.out.println ("You have entered " + temp + ".\n\nThe weighted value of the ISBN is:");
+
         System.out.println ("You have entered " + rpm + " rpms and " + rearTeeth + " rear teeth");
 
+
        //isolate last digit and multiply by 9
+
        digit = (isbn % 10);
+
        total = digit * 9;
+
        isbn = isbn / 10;
+
        System.out.println (digit + " * " + 9 + " for a running total of " + total);
+
 
+
        //isolate next digit and multiply by 8
+
        digit = (isbn % 10);
+
        total = total + digit * 8;
+
        isbn = isbn / 10;
+
        System.out.println (digit + " * " + 8 + " for a running total of " + total);
+
 
+
        //isolate next digit and multiply by 7
+
        digit = (isbn % 10);
+
        total = total + digit * 7;
+
        isbn = isbn / 10;
+
        System.out.println (digit + " * " + 7 + " for a running total of " + total);
+
 
+
        //isolate next digit and multiply by 6
+
        digit = (isbn % 10);
+
        total = total + digit * 6;
+
        isbn = isbn / 10;
+
        System.out.println (digit + " * " + 6 + " for a running total of " + total);
+
 
+
        //isolate next digit and multiply by 5
+
        digit = (isbn % 10);
+
        total = total + digit * 5;
+
        isbn = isbn / 10;
+
        System.out.println (digit + " * " + 5 + " for a running total of " + total);
+
 
+
        //isolate next digit and multiply by 4
+
        digit = (isbn % 10);
+
        total = total + digit * 4;
+
        isbn = isbn / 10;
+
        System.out.println (digit + " * " + 4 + " for a running total of " + total);
+
 
+
        //isolate next digit and multiply by 3
+
        digit = (isbn % 10);
+
        total = total + digit * 3;
+
        isbn = isbn / 10;
+
        System.out.println (digit + " * " + 3 + " for a running total of " + total);
+
  
         //isolate next digit and multiply by 2
+
         //find meters of development
         digit = (isbn % 10);
+
         mdev = WHEEL_CIRCUM * (FRONT_TEETH / (double)  rearTeeth);
        total = total + digit * 2;
+
         System.out.println("Meters of development: " + mdev);
        isbn = isbn / 10;
+
         System.out.println (digit + " * " + 2 + " for a running total of " + total);
+
  
         //isolate next digit and multiply by 1
+
         //find speed
         digit = (isbn % 10);
+
         speed = mdev * rpm; //speed in meters per minute
         total = total + digit * 1;
+
         speed = speed * (60.0 / 1000); //speed in km per hour
        isbn = isbn / 10;
+
        System.out.println (digit + " * " + 1 + " for a running total of " + total);
+
  
         //calculate check digit
+
         //BONUS
         checkDigit = total % 11;
+
         Calendar calendar = Calendar.getInstance();
 +
        SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy");
  
         //output weighted total and check digit
+
         //output
         System.out.println ("The weighted total is: " + total +
+
         System.out.println("Speed [km/hour]: " + speed);
                            "\nThe check digit is : " + checkDigit +
+
                            "\n\nThe 10-digit ISBN is: " + temp + checkDigit);
+
  
         System.out.println("\nProgrammed by COMP 1010 Instructors");
+
         System.out.println("\nProgrammed by Bicycle Forever");
         System.out.println("Date: " + new Date());
+
         System.out.println("Date: " + dateFormat.format(calendar.getTime()));
 
         System.out.println ("*** End of Processing ***");
 
         System.out.println ("*** End of Processing ***");
 +
        System.exit(0);
  
    }//end main
+
        }//end main
}//end class
+
}end class
 
|SideSectionTitle=Cycling Speed
 
|SideSectionTitle=Cycling Speed
 
|SideSection=
 
|SideSection=
[[Image:Wiki_start01.jpg|center]]<BR>
+
[[Image:CyclingHelmet_casestudy.jpg|center]]<BR>
  
 
}}
 
}}

Latest revision as of 10:43, 7 April 2011

Back to the Case Studies homepage

Problem

You are an employee on the software team of Bikers Forever, a bicycle company. The software team uses Java and the knowledge of the Java SDK to write programs for Bikers Forever. You are a great COMP 1010 student so you already know a bit about writing in Java, so in breathless anticipation, you await your next assignment from the head of the software team :)

You arrive at your desk on Monday morning and open your email in-box (as usual) to see this message from the head of the software team:

Hi <insert name here>,

I need you to write a program that will allow customers who visit the Bicycle Forever to calculate the speed of their bicycles. One of the members of the team stumbled on the formula to calculate cycling speed, and knowing that you are just itching for an assignment, I thought of you straightaway to implement the formula. The program description and the formula is below:

Program Description

  1. The program will prompt the user to input
    • The RPM (rotations per minute) of the bicycle
    • The number of teeth in the rear gear of the bicycle
  2. The program will also store as constants the number of teeth in the front gear and the diameter of the bicycle wheel. Assume the number of front teeth to be 45 and the diameter to be 70cm every-time.

Formula

  1. Before you calculate the speed, you must first calculate the meters of development. This is the length in meters covered by each rotation of the wheel of the bicycle. Meters of development (mdev, as we'll call them) are calculated this way:
    mdev = circumference[m] * (number front teeth / number rear teeth) 
    
  2. Finally, now that we have the mdev we can calculate the speed:
    speed = mdev * rpm * 60/1000 //Note that 60/1000 helps to calculate the speed in kilometers per hour
    

Output

To display your results, assuming a customer inputs 75 for RPM and 20 for rear teeth, the output will be displayed this way:

You have entered 75 RPM and 20 rear teeth.
Meters of development: 4.948008429403924
Speed [km/hour]: 22.266037932317655

Programmed by Bicycle Forever
Date: September 18, 2008
*** End of Processing ***

Thanks!, <insert name here>, I am confident you will do a great job.
The Boss

 

Cycling Speed

CyclingHelmet casestudy.jpg

Solution

Eddie Root, famous Australian rugby player riding a bicycle

To program our solution, we will go through 4 steps:

  1. Identify and declare all variables and constants necessary to implement the solution
  2. Store user input on bicycle information
  3. Perform the calculations for the meters of development and then the speed of the bicycle
  4. Output the results

In addition, we will be sure to comment through out our code, and follow correct programming standards as stated in [1]

Identify and Declare all Variables and Constants

Based on The Boss's email to you, and the description of the program and formula, we can easily identify all the variables and constants important to the solution.
NOTE: some of these variables are dependent on the others.


Constants

  • The number of front wheel teeth - assumed to be 45 every-time
  • The diameter of the wheel - assumed to be 70cm every-time


Declaration of Constants

When declaring constants, we use the keyword final. This ensures that whether it is an int, double, string or any other data type, it cannot be overwritten.



As the number of front wheel teeth is a number, we will declare it using "final int"

final int FRONT_TEETH = 45;

We also know the constant for the diameter is 70cm every-time. However, the diameter is not used in the calculations. Rather, the circumference is used to calculate the meters of development.


So what should we do???


It's simple! Going back to your high school days you know that the Circumference of a circle (wheel) = 3.14 (pi) * the diameter.

  • Pi in Java has been provided for us through Math.PI
  • We also want to make sure we divide by 100.0 because our diameter is in centimeters right now as opposed to the meters we need to calculate the meters of development (if you remember!)
  • And finally, our constant will be a "final int double" to represent the circumference. We declare and calculate the circumference right away since we already know the diameter and we use a double to accommodate the decimal spaces


Therefore our declaration becomes:

final double WHEEL_CIRCUMFERENCE = (70 * Math.PI)/100.0;

Now that we have our constants, let go ahead to declare the rest of the variables we will need based on the formula. We will also include a string variable to store our user's input.

int rpm;
int rearTeeth;
double mdev; //a double because it will contain decimal spaces because of the circumference
double speed;
String input;

Store user Input on Bicycle Information

In order to retrieve user input, we will be using the class JOptionPane. We are able to call this class and its methods when we type in "import javax.swing.*;" at the top of our program. Future computer science courses will explain what the import statement does.


How JOptionPane works: JOptionPane has an InputDialog method which shows a dialog box and accepts input typed into that box. This input can then be stored in strings. What we will do in this case, is store the user input into strings and parse (convert) them to integers using Integer.parseInt.


How Integer.parseInt works: Integer.parseInt accepts a string and converts it to an int. The string however must contain numbers only or bad things happen :)


Below is our Java code showing the storage of input and conversion to actual integers.

input = JOptionPane.showInputDialog ("Enter rpms.");
rpm = Integer.parseInt(input);

input = JOptionPane.showInputDialog ("Enter number of teeth on rear gear.");
rearTeeth = Integer.parseInt(input);

Now we have all the user input we need to perform the calculations.

Perform the Calculations

We have the directions from The Boss, and we have all the variables and user input we require. Now we calculate!


Following instructions we calculate the meters of development first. As per the email:

mdev = circumference[m] * (number front teeth / number rear teeth).

Translating this into Java code:

mdev = WHEEL_CIRCUM * (FRONT_TEETH / (double)  rearTeeth); //Remember to cast variable 
//rearTeeth as a double or you will get an int value for your result. That would be wrong! doubles/doubles = doubles :)

Next we calculate the speed:

speed = mdev * rpm * 60/1000

Translating this into Java code:

speed = mdev * rpm; 				//speed in meters per minute
speed = speed * (60.0 / 1000); 			//speed in km per hour

I took the liberty of breaking the speed calculation into meters per minute and multiplying it by 60.0/1000 in order to provide the result in kilometers per hour (the normal speed scale).

Output the Results

The outputs should closely resemble something like this:

You have entered 75 RPM and 20 rear teeth.
Meters of development: 4.948008429403924
Speed [km/hour]: 22.266037932317655

Programmed by Bicycle Forever
Date: September 18, 2008
*** End of Processing ***

Let us do a breakdown of the output, line by line.

Line 1: "You have entered 75 RPM and 200 rear teeth" This result can be printed immediately after you have read user input and converted the input to integers. Printing out the input will also help to confirm that it was stored correctly. In this case:

System.out.println ("You have entered " + rpm + " rpms and " + rearTeeth + " rear teeth");

Line 2: "Meters of development: 4.948008429403924" This can be printed immediately after the calculation of the meters of development.

System.out.println("Meters of development: " + mdev);

Line 3: "Speed [km/hour]: 22.266037932317655" The speed also, can be printed out after its calculation has been done.

System.out.println("Speed [km/hour]: " + speed);

To complete the process we can write code to print out the rest of the output.

System.out.println("\nProgrammed by Bicycle Forever");
System.out.println("Date: ");
System.out.println ("*** End of Processing ***");

You will notice that the output for the date above is empty. You can hardcode the date in i.e. type it right into the program as part of the output, or use the Calendar class to show the current date every-time the program is run. I have included the process for showing the current date in the bonus section below.

Bonus Section: Outputting the Current Date

Just like we used the import statement in the Storing User Input section, we will also be using this statement to access the Calendar class in order to get the current date.

You can tell what import statement to use by going through the Java API documentation: [2]. The documentation also explains what classes are available and the methods attached to them.

For the purpose of this solution, we will be including import statements that will:

  • Give us access to the Calendar class and a method that provides the current time
  • Give us access to a SimpleDateFormat class and a method that helps format the current time
import java.text.SimpleDateFormat;
import java.util.Calendar;

Now that we have included the import statments, we can call the Calendar class and its method getInstance() to give us a working calendar, and then call the SimpleDateFormat class that we shall provide with a format for outputting the current time:

Calendar calendar = Calendar.getInstance();
SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy");

Now that we have a working calendar, we will add the output gotten from formatting the current time of the Calendar (using the SimpleDateFormat class) into our solution output. This is the line that provides the output:

System.out.println("Date: " + dateFormat.format(calendar.getTime()));

Commenting and Testing

Although we have our calculations done and our output printed, we aren't done yet! For the sake of others, who will read your code, commenting must be done. Using the "//" characters, comment major lines to show what you are doing. This improves readability and tells The Boss that you are a professional.

In addition, you want to test your code, right after every calculation to be sure you do not provide a wrong bicycle speed. A program that outputs the wrong speed of a bicycle can make bad things happen! Therefore, check to be sure

  • Input is entered and converted correctly
  • Calculations are done correctly
  • Results are output correctly

I have included comments and tests using System.out.println() in the sample source code for your benefit.

COMPLETE!

Congratulations! You have now finished your Cycling Speed program. You can now compile and run your program. You can also click the Solution button below to see a full solution.

Code

Solution Code

Back to the Case Studies homepage