Jump to content
Larry Ullman's Book Forums

Can'T Get My Head Around Widget Cost Calculator


Recommended Posts

Hi People.

 

I fly a flexwing microlight aircraft and I am trying to write a calculator that adds up time for my website and my logbook.

 

You see as a pilot we have to keep a valid logbook and the pages are set out in 12s we then need to add up the times.

 

My idea is that I have a list of boxes to put in your hours and minutes.

 

Then click the calculate button and it adds up your time and displays it in the box at the bottom.

 

My code needs to do this...... add up all 12 minute boxes, add up all the hours boxes and multiply it by 60, add both results to get the total minutes, then run through a loop to do the following.

 

check to see if variable "total minutes" >60 and if so add 1 to the hour variable, continue through the loop until the condition >60 in the minutes is not met. Then put the resulting hours and minutes into the result box.

 

Here is the code so far, any help would really be appreciated.

 

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Untitled Document</title>


</head>

<body>

<form action="logbook_add.php" method="post">

<table width="527" border="0" cellspacing="5" cellpadding="5" bgcolor="#c0c5c9">
 <tr>
   <td width="146">Entry 01</td>
   <td width="346"><input type="int" name="hour01" size="10" maxlength="10" />
     Hrs 
       <input type="int" name="min01" size="10" maxlength="10" /> 
       whole mins</td>
 </tr>
 <tr>
   <td>Entry 02</td>
   <td><input type="int" name="hour02" size="10" maxlength="10" />
Hrs
 <input type="int" name="min02" size="10" maxlength="10" />
whole mins</td>
 </tr>
 <tr>
   <td>Entry 03</td>
   <td><input type="int" name="hour03" size="10" maxlength="10" />
Hrs
 <input type="int" name="min03" size="10" maxlength="10" />
whole mins</td>
 </tr>
 <tr>
   <td>Entry 04</td>
   <td><input type="int" name="hour04" size="10" maxlength="10" />
Hrs
 <input type="int" name="min04" size="10" maxlength="10" />
whole mins</td>
 </tr>
 <tr>
   <td>Entry 05</td>
   <td><input type="int" name="hour05" size="10" maxlength="10" />
Hrs
 <input type="int" name="min05" size="10" maxlength="10" />
whole mins</td>
 </tr>
 <tr>
   <td>Entry 06</td>
   <td><input type="int" name="hour06" size="10" maxlength="10" />
Hrs
 <input type="int" name="min06" size="10" maxlength="10" />
whole mins</td>
 </tr>
 <tr>
   <td>Entry 07</td>
   <td><input type="int" name="hour07" size="10" maxlength="10" />
Hrs
 <input type="int" name="min07" size="10" maxlength="10" />
whole mins</td>
 </tr>
 <tr>
   <td>Entry 08</td>
   <td><input type="int" name="hour08" size="10" maxlength="10" />
Hrs
 <input type="int" name="min08" size="10" maxlength="10" />
whole mins</td>
 </tr>
 <tr>
   <td>Entry 09</td>
   <td><input type="int" name="hour09" size="10" maxlength="10" />
Hrs
 <input type="int" name="min09" size="10" maxlength="10" />
whole mins</td>
 </tr>
 <tr>
   <td>Entry 10</td>
   <td><input type="int" name="hour10" size="10" maxlength="10" />
Hrs
 <input type="int" name="min10" size="10" maxlength="10" />
whole mins</td>
 </tr>
 <tr>
   <td>Entry 11</td>
   <td><input type="int" name="hour11" size="10" maxlength="10" />
Hrs
 <input type="int" name="min11" size="10" maxlength="10" />
whole mins</td>
 </tr>
 <tr>
   <td>Entry 12</td>
   <td><input type="int" name="hour12" size="10" maxlength="10" />
Hrs
 <input type="int" name="min12" size="10" maxlength="10" />
whole mins</td>
 </tr>
 <tr>
   <td><input type="submit" name="submit" value="Add Your Logbook Times" /></td>
   <td>Answer
     <input type="int" name="hour_answer" size="10" maxlength="10" />
     <!--<input type="hidden" name="submitted" value ="1" /> -->
Hrs
 <input type="int" name="min_answer" size="10" maxlength="10" />
 mins</td>
 </tr>
</table>



<div align="center"></div></form>

</body>
</html>

 

Here is the php I have so far.

 

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Untitled Document</title>
</head>

<body>

<?php 
/*
$hour01 
$hour02
$hour03 
$hour04 
$hour05 
$hour06 
$hour07
$hour08 
$hour09 
$hour10 
$hour11 
$hour12 


$min01
$min02
$min03
$min04
$min05
$min06
$min07
$min08
$min09
$min10
$min11
$min12
*/

$total_mins
//$total_hours
//$total_time_in_mins

//$min_answer
//$hour_answer

//if (isset($_POST['submitted'])) 


$total_mins = ([$_POST['min01'] + [$_POST['min02'] + [$_POST['min03'] + [$_POST['min04']+[$_POST['min05']+[$_POST['min06']+[$_POST['min07']+[$_POST['min08']+[$_POST['min09']+[$_POST['min10']+[$_POST['min11']+[$_POST['min12']);

'min_answer' = $total_mins;																																																															
//$total_mins = $total_hours * 60;
//$total_mins =






?>


</body>
</html>

Link to comment
Share on other sites

So basically, you are logging a bunch of flight times, and you simply want to add them all up and get the total flight time in hour-minute format, right?

 

I guess I want to know is whether or not you want to save the values you log into a database, or if you simply want to use this as a calculator, and you don't mind if all the values are deleted when you close the browser window.

 

I feel like one issue is that you're restricting yourself to the number of entries you hard code on the page. I imagine something a little more dynamic would be helpful, no?

 

Lastly, I don't get the 12s (12 minute?) thing either. Do you mean that each page has 12 entries on it, and you need to add up all the values for that page?

 

Anyway, like Jonathon said, a little more info on what exactly you want to accomplish would be helpful. Thanks.

  • Upvote 1
Link to comment
Share on other sites

So basically, you are logging a bunch of flight times, and you simply want to add them all up and get the total flight time in hour-minute format, right?

 

I guess I want to know is whether or not you want to save the values you log into a database, or if you simply want to use this as a calculator, and you don't mind if all the values are deleted when you close the browser window.

 

I feel like one issue is that you're restricting yourself to the number of entries you hard code on the page. I imagine something a little more dynamic would be helpful, no?

 

Lastly, I don't get the 12s (12 minute?) thing either. Do you mean that each page has 12 entries on it, and you need to add up all the values for that page?

 

Anyway, like Jonathon said, a little more info on what exactly you want to accomplish would be helpful. Thanks.

 

Hi HartleySan and Jonothan, thank you for your replies.

 

The log book entries are 12 per page. Simply adding them up in the hour and minute format is what I want to achieve. I don't mind the values being deleted when I close the browser window.

Here is a screen shot of the code for add_logbook.php in the browser window.

add_logbook.png

 

I would also like it to work (adding '0') if the user puts nothing in the box and also give them an error if they put letters instead of numbers (capture none integers)

Link to comment
Share on other sites

All right, there are several approaches to take for this, but I'd recommend something like the following:

 

I can't recall if Larry mentions this or not in the book, but the superglobals in PHP (POST, GET, etc.) are arrays, and can be treated as such. More specifically, when you post multiple values, they're all in the $_POST array, in the order that you submitted them in. We can use this knowledge to go through each submitted value:

 

$iTotalHours = 0;

$iTotalMin = 0;

$bIsHourValue = true; // Used to alternate between hour and minute values in the POST array.

$bNoErrors = true; // Flag used to indicate that there is some invalid input.

foreach ($_POST as $key -> $value) { // $key represents the names of the various submitted data items (e.g., hour01, min01, hour02, etc.).

 if ($bIsHourValue) { // Is an hour value.

   if (is_int($value)) { // PHP function testing for an integer

     $iTotalHours .= $value;

   } else if (!empty($value)) { // If we get here, we know that we don't have an integer, so if there is any value at all, then it must be invalid.
                                // If it's empty, we don't need to do anything.

     $bNoErrors = false;

     break; // No need to continue the loop if we've already found an error. Note that this is fairly rudimentary error handling.

   }

   $bIsHourValue = false; // Alternate the isHour flag.

 } else { // Is a minute value.

   if (is_int($value)) {

     $iTotalMin .= $value;

   } else if (!empty($value)) {

     $bNoErrors = false;

     break;

   }

   $bIsHourValue = true;

 }

}

if ($bNoErrors) { // If there was no invalid input, do the calculations.

 $iTotalMin .= 60 * $iTotalHours; // Total time in minutes

 $iTotalHours = floor($iTotalMin / 60); // Divide the total time by 60, and round the result down to the nearest integer for the total hours.

 &iTotalMin %= 60; // Kind of a funky notation, but takes the total minutes and sets it equal to the reminder of itself divided by 60.
                   // For example 280 % 60 = 40 (minutes).

} else { // Output a basic message indicating that there was some invalid input.

 echo 'Learn to input data correctly, bozo!';

}

 

At this point, assuming no errors, you have the total hours and minutes stored in $iTotalHours and $iTotalMin, respectively. You can simply echo these values in the appropriate places in the form you created using notation like the following:

 

...value="<?php if (!empty($iTotalHours)) echo $iTotalHours; ?>">...

 

Note that my error handling is really simple, too. It only tells the user that there was an error, but not where. A better implementation would be to have an array that stores each of the errors, and then tells the user where they made mistakes (if in multiple places). I believe this is covered in Larry's book, which is why I glossed over it. Also, it's probably best to tell the user from the beginning that only integers are valid, and that omitted values are counted as 0.

 

Well, does that answer your question?

  • Upvote 1
Link to comment
Share on other sites

foreach ($_POST as $key -> $value)

 

I think you have a syntax error here. It should be:

foreach ($_POST as $key => $value)

(=>, not ->)

 

Nice job on the descriptive variable names! I like how you indicate the variable type in the name: $bWhatever for boolean types, $iWhatever for integers.

  • Upvote 1
Link to comment
Share on other sites

Brilliant HartleySan.

 

Thank you for all that work, that's amazing. I really appreciate it. I have put everything into the files as indicated, but I must be stupid because I can't get it to work.

 

All I get is the error message. Here are my two files as I have put them together.

 

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Untitled Document</title>


</head>

<body>

<form action="logbook_add.php" method="post">

<table width="527" border="0" cellspacing="5" cellpadding="5" bgcolor="#c0c5c9">
 <tr>
   <td width="146">Entry 01</td>
   <td width="346"><input type="int" name="hour01" size="10" maxlength="10" />
     Hrs 
       <input type="int" name="min01" size="10" maxlength="10" /> 
       whole mins</td>
 </tr>
 <tr>
   <td>Entry 02</td>
   <td><input type="int" name="hour02" size="10" maxlength="10" />
Hrs
 <input type="int" name="min02" size="10" maxlength="10" />
whole mins</td>
 </tr>
 <tr>
   <td>Entry 03</td>
   <td><input type="int" name="hour03" size="10" maxlength="10" />
Hrs
 <input type="int" name="min03" size="10" maxlength="10" />
whole mins</td>
 </tr>
 <tr>
   <td>Entry 04</td>
   <td><input type="int" name="hour04" size="10" maxlength="10" />
Hrs
 <input type="int" name="min04" size="10" maxlength="10" />
whole mins</td>
 </tr>
 <tr>
   <td>Entry 05</td>
   <td><input type="int" name="hour05" size="10" maxlength="10" />
Hrs
 <input type="int" name="min05" size="10" maxlength="10" />
whole mins</td>
 </tr>
 <tr>
   <td>Entry 06</td>
   <td><input type="int" name="hour06" size="10" maxlength="10" />
Hrs
 <input type="int" name="min06" size="10" maxlength="10" />
whole mins</td>
 </tr>
 <tr>
   <td>Entry 07</td>
   <td><input type="int" name="hour07" size="10" maxlength="10" />
Hrs
 <input type="int" name="min07" size="10" maxlength="10" />
whole mins</td>
 </tr>
 <tr>
   <td>Entry 08</td>
   <td><input type="int" name="hour08" size="10" maxlength="10" />
Hrs
 <input type="int" name="min08" size="10" maxlength="10" />
whole mins</td>
 </tr>
 <tr>
   <td>Entry 09</td>
   <td><input type="int" name="hour09" size="10" maxlength="10" />
Hrs
 <input type="int" name="min09" size="10" maxlength="10" />
whole mins</td>
 </tr>
 <tr>
   <td>Entry 10</td>
   <td><input type="int" name="hour10" size="10" maxlength="10" />
Hrs
 <input type="int" name="min10" size="10" maxlength="10" />
whole mins</td>
 </tr>
 <tr>
   <td>Entry 11</td>
   <td><input type="int" name="hour11" size="10" maxlength="10" />
Hrs
 <input type="int" name="min11" size="10" maxlength="10" />
whole mins</td>
 </tr>
 <tr>
   <td>Entry 12</td>
   <td><input type="int" name="hour12" size="10" maxlength="10" />
Hrs
 <input type="int" name="min12" size="10" maxlength="10" />
whole mins</td>
 </tr>
 <tr>
   <td><input type="submit" name="submit" value="Add Your Logbook Times" /></td>
   <td>Answer
     <input type="int" size ="10" value="<?php if (!empty($iTotalHours)) echo $iTotalHours; ?>" />


 <input type="int" size="10" value="<?php if (!empty($iTotalMin)) echo $iTotalMin; ?>"/>


 </td>
 </tr>
</table>



<div align="center"></div></form>

</body>
</html>

 

Then logbook_add.php

 

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Untitled Document</title>
</head>

<body>

<?php 
$iTotalHours = 0;

$iTotalMin = 0;

$bIsHourValue = true; // Used to alternate between hour and minute values in the POST array.

$bNoErrors = true; // Flag used to indicate that there is some invalid input.

foreach ($_POST as $key => $value) { // $key represents the names of the various submitted data items (e.g., hour01, min01, hour02, etc.).

 if ($bIsHourValue) { // Is an hour value.

   if (is_int($value)) { // PHP function testing for an integer

     $iTotalHours .= $value;

   } else if (!empty($value)) { // If we get here, we know that we don't have an integer, so if there is any value at all, then it must be invalid.
                                // If it's empty, we don't need to do anything.

     $bNoErrors = false;

     break; // No need to continue the loop if we've already found an error. Note that this is fairly rudimentary error handling.

   }

   $bIsHourValue = false; // Alternate the isHour flag.

 } else { // Is a minute value.

   if (is_int($value)) {

     $iTotalMin .= $value;

   } else if (!empty($value)) {

     $bNoErrors = false;

     break;

   }

   $bIsHourValue = true;

 }

}

if ($bNoErrors) { // If there was no invalid input, do the calculations.

 $iTotalMin .= 60 * $iTotalHours; // Total time in minutes

 $iTotalHours = floor($iTotalMin / 60); // Divide the total time by 60, and round the result down to the nearest integer for the total hours.

 $iTotalMin %= 60; // Kind of a funky notation, but takes the total minutes and sets it equal to the reminder of itself divided by 60.
                   // For example 280 % 60 = 40 (minutes).

} else { // Output a basic message indicating that there was some invalid input.

 echo 'Learn to input data correctly, bozo!';

}

?>

</body>
</html>

 

Please can you tell me what I've done wrong?

Link to comment
Share on other sites

Paul, thanks for the correction. I use a Japanese keyboard, and the - and = are on the same key. I must have forgotten to hold down the Shift key.

 

Anyway, sorry you're getting an error everytime. I have not tested my code out at all, so there may be a small issue that I overlooked. I recommend going through each step, and testing for where the problem is. Obviously, for some reason, at least one of the values is causing the $bNoErrors flag to be changed to false, which is causing the error message to be output everytime.

 

Actually, I really should have tested out my code last night (but I didn't). I would first run the foreach loop and output all the key-value pairs to ensure that your data is there as you expected. For example:

 

foreach ($_POST as $key => $value) {

 echo 'Key: ' . $key . ', value: ' . $value . '<br>';

}

 

You should get something like the following:

 

Key: hour01, value: 3
Key: min01, value: 50
Key: hour02, value: 4
...

 

If you don't get something like that, then something is up with the input data being posted to the other PHP script. Also, test out the absence of a value and letter values, etc., to ensure that regardless, the data is getting to the PHP form all right.

 

After you have ensured that, you might want to echo something for each step of the loop to see where values are going in the loop. For example:

 

foreach ($_POST as $key => $value) {

 if ($bIsHourValue) {

   if (is_int($value)) {

     $iTotalHours .= $value; 

     echo $key . ' is an integer and was added to the total hours.<br>';

   } else if (!empty($value)) {

     $bNoErrors = false; 

     echo $key . ' is not an integer and this is where the loop is broken.<br>';

     break;

   } 

   $bIsHourValue = false;

 } else {

   if (is_int($value)) { 

     $iTotalMin .= $value; 

   } else if (!empty($value)) { 

     $bNoErrors = false; 

     break; 

   } 

   $bIsHourValue = true; 

 } 

} 

 

Naturally, you would add similar echo statements to the minutes part as well. Again, I wasn't able to test my code, so I'm not sure, but perhaps all the data being received from the form is not being interpreted as integer values, but as strings. This will be obvious if the loop is being broken after the first POST value everytime.

 

Anyway, I apologize for the errors, and I'm at work again, so don't have the means to test anything, but please let me know what you find, and we'll resolve this issue. Thanks.

  • Upvote 1
Link to comment
Share on other sites

I think I found the problem.

 

Submitted form data is always in string format. As such, if you test form data using the is_int() function, you will always get false, thus the problem.

 

However, you can use the is_numeric() function to test for the existence of numeric string data (i.e., numbers submitted via a form). Try replacing is_int() with is_numeric(). It should work then.

 

For more info on the is_numeric() function, see the following:

 

http://www.php.net/manual/en/function.is-numeric.php

  • Upvote 1
Link to comment
Share on other sites

One other thing I mistook is the following:

 

$iTotalHours .= $value;

 

If you use .=, it'll add up the values as strings (i.e., append the values). For example, if $iTotalHours is '0', and $value is '1', you'll get '01';

 

As such, you need to do the following:

 

$iTotalHours += $value;

 

That'll treat the values like integers, essentially typecasting them.

 

Anyway, I made a really simple script that seems to work. It has no error testing, so feel free to adapt it to your needs. I have confirmed though that so long as you enter integer values, it works everytime. It also automatically handles the absence of a value as 0.

 

flightlogtest1.php

 

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">

<html lang="en">

 <head>

   <title>Flight Log Test #1</title>

   <meta http-equiv="Content-Type" charset="text/html; charset=utf-8">

 </head>

 <body>

   <?php

     if (!empty($_POST)) {

       $bIsHour = true;

       $iTotalHours = 0;

       $iTotalMins = 0;

       foreach ($_POST as $key => $value) {

         if ($bIsHour) {

           if (is_numeric($value)) {

             $iTotalHours += $value;

           }

         } else {

           if (is_numeric($value)) {

             $iTotalMins += $value;

           }

         }

         $bIsHour = ($bIsHour) ? false : true;

       }

       $iTotalHours += floor($iTotalMins / 60);

       $iTotalMins %= 60;

       echo 'Total hours: ' . $iTotalHours . '<br>' . 'Total minutes: ' . $iTotalMins . '<br>';

     }

   ?>

   <form action="flightlogtest1.php" method="post">

     <p><label for="hour01">Hour 01: </label><input type="text" name="hour01" id="hour01"></p>

     <p><label for="min01">Minute 01: </label><input type="text" name="min01" id="min01"></p>

     <p><label for="hour02">Hour 02: </label><input type="text" name="hour02" id="hour02"></p>

     <p><label for="min02">Minute 02: </label><input type="text" name="min02" id="min02"></p>

     <p><label for="hour03">Hour 03: </label><input type="text" name="hour03" id="hour03"></p>

     <p><label for="min03">Minute 03: </label><input type="text" name="min03" id="min03"></p>

     <p><input type="submit" value="Submit"></p>

   </form>

 </body>

</html>

  • Upvote 1
Link to comment
Share on other sites

 Share

×
×
  • Create New...