#!/usr/bin/perl # NOTE: You must change the line above to point to the path to Perl # on your system. ######################################################################### ##### MetaboCalc v1.0 # ##### Copyright 2004, Kristina L. Pfaff-Harris, www.tesol.net/scripts # # # # A simple metabolism calculator using the Harris-Benedict equation to # # tell approximately how many calories a person needs per day. Shows # # plus and minus 5% and 20% due to errors inherent in the Harris- # # Benedict equation. # # # # Please read the README file for instructions on how to set this up, # # what to change, and how to use this program. # # # ######################################################################### ##### License for MetaboCalc 1.0 ##### ##### This program may be used free of charge under the following ##### conditions: ##### ##### 1. All instructions and Copyright lines must remain unchanged. ##### ##### 2. All pages generated by the program must contain one of the ##### following pieces of HTML code: ##### ##### ##### Powered by MetaboCalc v1.0 ##### OR: ##### ##### ##### ##### You may not remove the information described above from the script ##### without express written permission from the author. ##### ##### 3. You may not sell or distribute this program. You may charge ##### a reasonable fee for installing it for a client as long as ##### you make it clear that you are not the author, and you are ##### not selling the program to them: only charging for installing ##### it. ##### ##### 4. You agree that this program is offered without warranty of ##### any kind, including warranty of fitness for a particular ##### purpose. You further agree that the author and all sites ##### associated in any way with this program are not liable for ##### any damage or loss incurred as a result of using this program. ##### ##### 5. You may modify the program for your own use but you may not ##### distribute modified copies under any circumstances without ##### express written permission from the author. ##### ##### 6. Use of this program requires agreement to all the terms and ##### conditions of this license. If you do not agree to one or ##### more of these terms, you may not use the program. ##### ######################################################################### ##### # ##### IMPORTANT INSTRUCTIONS: # ##### # ##### In this program, I have put **CHANGE** in all the places where # ##### you will need to modify the program to run on your server, so # ##### that you can easily find all the places where changes are # ##### necessary. This program must be chmod 755 or 775 in order to # ##### work, and the html page must be chmod 644. # ##### # ######################################################################### # Note: On most servers, this is fine the way it is. However, on some # servers, you may have to change this to the full URL of the # metabocalc.cgi program. For example: # $cgi_url = "http://www.your_site.com/cgi-bin/metabocalc.cgi"; # If everything seems to work, then leave this as it is. $cgi_url = "$ENV{'SCRIPT_NAME'}"; ######################################################################### ##### # ##### This is the beginning of the part where you must **CHANGE** # ##### things. # ##### # ######################################################################### # First, let's choose a color scheme. You'll need to know "hex" # colors for fonts and bacgrounds for this to work effectively. # If you don't know the hex colors, try plain words such as "blue", # "red" or "black" or leave these as they are. The hex colors for # the way the demo program is are below. You may **CHANGE** these # to colors more in keeping with your site, or just use a CSS # stylesheet in $header below. $text_color = "000000"; $page_background_color = "FFFFF0"; $page_links_color = "0000FF"; $page_active_links_color = "FF0000"; $page_visited_links_color = "0000FF"; $table_background_color= "F4E3C8"; $table_cell_color= "FFFFFF"; # $header is the HTML header that will be generated by the results page # of the program. You may **CHANGE** this to any HTML code you like. # The caveats here are as follows: First, any of the following # characters: # " % @ $ \ # must have a backslash (\) in front of them like this: # \" \% \@ \$ \\ # or the program will not work. ONLY change between the lines that # say and # You may also leave this as it is. # Please see the FAQ at http://tesol.net/scripts/FAQ/ for how to # set up $header and $footer so that the script will match your site. # Search for "htmlheader" or look for "How do I make the pages from the # script look like the rest of my site" in the list of questions. $header = qq[ MetaboCalc v1.0
MetaboCalc v1.0: Calculate your Daily Calorie Needs!

]; # $footer is the HTML code that will go at the bottom of pages # generated by the program. The same rules apply as to $header # above. You may also leave this as it is, and it will work fine. # Again, ONLY change between the lines that say # and $footer = qq[
]; # Now, would you like the default to be Kilograms, or Pounds for the # person entering his or her weight? If you would like it to be # Kilograms, please set this to $default_weight = "k"; Otherwise, # set this to $default_weight = "p"; $default_weight = "p"; # And, would you like the default to be Centimeters, or Inches for the # person entering his or her height? If you would like it to be # Centimeters, please set this to $default_height = "c"; Otherwise, # set this to $default_height = "i"; $default_height = "i"; # Okay, one last thing: there are various little question marks that, # when clicked on, pop up a window with explanations about things. # The text in these popup windows can be modified by changing the $notes, # $bmi_notes, $lifestyle_notes, and $bmr_notes variables below. For # each of these, you may change the explanation using pretty much any # HTML code you choose, but please, only change in between the # and tags, # where by "something" I mean "HB", "BMI," "BMR", or "Lifestyle" as # appropriate. You should also know that the $ and @ signs are interpreted # in a special way by the Perl programming language, so if you use them, # they will not show up unless you put a backslash in front of them, like # \$ or \@. In some versions of Perl, using @ without a backslash will # break the program so you'll get "Internal Server Error." Just a word # to the wise. :-) $notes = qq[
About Caloric Needs Calculation


This calculator uses what is called the "Harris-Benedict Formula" to determine your daily calorie needs. There are a few things that are important to remember about this formula. First, the formula was devised many years ago, and has in recent years been determined to have up to a 20% error rate, depending upon the percentage of body fat and other variables. (For this reason, the calculator shows plus and minus 5% and 20% so you can get an idea of the range.)

Secondly, the modification for your "lifestyle" (sedentary vs. moderately active and so forth) is really a bit of a guess. "Sedentary" is "little or no exercise" and you can imagine that there can be quite a bit of difference between "little" and "no" exercise.

Weight loss cannot, unfortunately, be boiled down into an exact number. All this can do is give you an idea of a potential range. Chances are good, however, that if you limit your intake to the lower end of the spectrum, you may be able to lose weight, but different people have different metabolisms and so you may need fewer or more calories.

Calculation of your "Basal Metabolic Rate" (or "Resting Metabolic Rate" as it's sometimes called) is only one tool in your fitness arsenal.

--Close Window-- ]; # Here is the explanation for BMR $bmr_notes = qq[
About BMR (Basal Metabolic Rate)


"Basal Metabolic Rate" (sometimes also called "Resting Metabolic Rate") or BMR is an approximate calculation of how many calories you would need to maintain your current weight if you did nothing but stayed in bed all day. This calculation is really only accurate for a certain percentage of people, because your actual BMR depends on other things such as body fat percentage, etc. For this reason, we also show BMR at plus or minus 20 percent, so you can get a better idea of the range.

When computed with your "lifestyle" number, this gives your overall calorie needs in a given day.

--Close Window-- ]; # Here is the explanation for the "lifestyle" part of the calculator $lifestyle_notes = qq[ About the Lifestyle Selection

The lifestyle selections are a bit vague, but here are some approximations that may help you choose.
Bed-Bound If you stay in bed all day for health or other reasons, choose this selection.
Sedentary This selection would be for someone with a "desk job" who does not exercise at all.
Lightly Active If you do light exercise 1 - 3 days per week, this selection may be appropriate for you.
Moderately Active If you do moderate exercise 3 - 5 days per week, this selection may be appropriate for you.
Active Usually, if you have a physical job (loading boxes, warehouse, delivery) and do moderate to strenous exercise 6 - 7 days per week, try this selection.
Very Active For people who are exercising or moving most of the time. For example, loading boxes in a warehouse plus several hours of hard exercise or sports 6 - 7 days per week, cross training, etc. Athletes and bodybuilders often fall into this category.


--Close Window-- ]; # <-- Do not touch this. :-) # And finally, here is the explanation for the "BMI" part of the # calculator. $bmi_notes = qq[
About Body Mass Index


It's important to realize that BMI is not the most accurate determination of whether or not you are at an unhealthy weight. For example, if you are extremely muscular, your BMI may show as "Overweight" or even "Obese," when you're not. By the same token, if you are a "Normal" BMI, but have a very high body fat percentage, you may have the same health risks as someone with an "Obese" BMI.

BMI or "Body Mass Index" is based on the following formula:

( Weight in pounds )  * 703
______________
Height in inches2
BMI is only one tool in your health arsenal. Body fat percentage is a much better predictor of health risks than the ratio of your height to your weight.

--Close Window-- ]; # $about_hb_height is for the height (in pixels) of the popup explanation # window. You may **CHANGE** this to get a taller window. Note: it's # probably a bad idea to make this bigger than 600. $about_hb_height = "400"; # $about_hb_width is for the width (in pixels) of the popup explanation # window. You may **CHANGE** this to get a wider window. It's probably # a bad idea to make this bigger than 400. $about_hb_width = "300"; ######################################################################### ##### # ##### This is the end of the part where you must **CHANGE** # ##### things. Feel free to look through the code if you are # ##### interested in checking out such things, but don't change # ##### anything beyond this point unless you know what you're doing. # ##### Since this is a free script, there is no warranty, but if there # ##### were a warranty, you'd definitely void it if you modified stuff # ##### below this line. :-) # ##### # ######################################################################### # First, we get the data submitted on the form into variables we can # use. # This line just makes it so everything printed by the script is printed # immediately instead of being "buffered." $| = 1; # This line calles the parse_form_data subroutine, which grabs all the # input from the form into an associative array so we can use the # variables. %data = &parse_form_data(); # And this line must be in any CGI script: it tells your web browser # that HTML stuff is coming out. If you had a CGI script that showed # an image, you might use "Content-type: image/gif", but you have to # have a content-type (or MIME header) of some kind. If you were using # the Perl CGI module with "use CGI;" then you could probably do something # like "print header;" but oddly enough, a lot of servers don't have the # CGI module, so we're taking no chances. print "Content-type: text/html\n\n"; # If you remove this link, without replacing it with a similar # HTML comment (as above in the License section) you are in violation # of the license for this program. No, I don't have the resources to # enforce this, and I know that some people will remove it anyway. # But honestly, since you didn't have to pay for this, is the link # really too much to ask? :) $footer = "
Powered by MetaboCalc v1.0
$footer"; ################################################################# # If it's one of the popup window links that people are clicking on, # we're just going to print out whatever explanation there is, and exit. if($data{'FA'} eq "AboutHB"){ &print_explanation($notes); } if($data{'FA'} eq "AboutBMR"){ &print_explanation($bmr_notes); } if($data{'FA'} eq "AboutBMI"){ &print_explanation($bmi_notes); } if($data{'FA'} eq "AboutLifestyle"){ &print_explanation($lifestyle_notes); } # If not, then we're going to print the whole form and so forth. First, # print our HTML for the top of the page. print $header; # Now, figure out whether they chose kilos/centimeters or pounds/inches. # They could also choose pounds/centimeters, or kilos/inches. We will # convert if necessary. :-) $kilos_or_pounds = $data{'wt'}; $centimeters_or_inches = $data{'ht'}; # This next set of things is just checking so that if they enter # strange values (weight less than 0 or gender that is not "m" or "f", # age over 120, etc) we just show a little red * next to the form # field, and don't bother trying to calculate anything. :-) # If weight is not a number at all, or if it is blank, or if it # is less than or equal to zero, do the error. $weight = $data{'weight'}; if($weight * 1 ne $weight || $weight eq "" || $weight <= 0){ $errweight = "*"; $no_calc = 1; } # Same for height. $height = $data{'height'}; if($height * 1 ne $height || $height eq "" || $height <=0 ){ $errheight = "*"; $no_calc = 1; } # Same for age, except we also don't allow ages over 120. # My apologies in advance to anyone over the age of 120 # attempting to use this calculator. $age = $data{'age'}; if($age == 0 || $age eq "" || $age > 120 | $age < 0){ $errage = "*"; $no_calc = 1; } # If gender is not "m" or "f", do an error. $gender = $data{'gender'}; if($gender ne "m" && $gender ne "f"){ $errgender = "*"; $no_calc = 1; } # If their lifestyle is "bed bound," or anything but the general # lifestyle multiples, we just call it the same as the BMR. # I don't think you're really supposed to do this with Harris-Benedict # calculations, but I have, in the past, wanted to do the base calculation # so therefore everyone gets to. $lifestyle = $data{'lifestyle'}; if($lifestyle != 1.2 && $lifestyle != 1.375 && $lifestyle != 1.55 && $lifestyle != 1.725 && $lifestyle != 1.9){ $lifestyle = 1; } # Set a variable to tell us it's okay to do the calculations if we # didn't hit one of our errors above. if($no_calc != 1){ $do_calc = 1; } # We're just going to do the formula in pounds and inches, regardless. # So, if they entered it in kilos or centimeters, we need to convert. # Since the answers are ratios, the numbers will be the same whichever # we use. if($kilos_or_pounds eq "k"){ $weight = &convert_to_pounds($weight); } else { $weight = $weight; } if($centimeters_or_inches eq "c"){ $height = &convert_to_inches($height); } else { $height = $height; } # There are two formulae for BMR: one for men and one for women. If they # entered female, do the one for women. The sprintf() thing tells it # to display as a number with no decimal places. if($gender eq "f" && $do_calc == 1){ # This is the female version of the formula $BMR = sprintf("%d", 655 + (4.35 * $weight) + (4.7 * $height) - (4.7 * $age)); } # Otherwise, do the one for men. elsif($gender eq "m" && $do_calc == 1){ # This is the male version of the formula $BMR = sprintf("%d", 66 + (6.23 * $weight) + (12.7 * $height) - (6.8 * $age)); } # If they're not male or female, or there was another error above, # then it's No BMR for You! else { $BMR = 0; } # We're also going to do some little calcs for plus and minus 5 and 20% so # people can see a range. sprintf("%d", some number) makes it chop off any # decimal places and just show a whole number. $HB_main = sprintf("%d",$BMR * $lifestyle); $BMR_plus_20 = sprintf("%d", $BMR + ($BMR * 0.2)); $HB_plus_20 = sprintf("%d",$BMR_plus_20 * $lifestyle); $BMR_plus_5 = sprintf("%d",$BMR + ($BMR * 0.05)); $HB_plus_5 = sprintf("%d",$BMR_plus_5 * $lifestyle); $BMR_minus_20 = sprintf("%d",$BMR - ($BMR * 0.2)); $HB_minus_20 = sprintf("%d",$BMR_minus_20 * $lifestyle); $BMR_minus_5 = sprintf("%d",$BMR - ($BMR * 0.05)); $HB_minus_5 = sprintf("%d",$BMR_minus_5 * $lifestyle); $HB = qq[
Your BMR Range:] . qq[(?)] . qq[Your Total Calorie needs] . qq[(?)] . qq[
Minus 20%:$BMR_minus_20 Minus 20%:$HB_minus_20
Minus 5%:$BMR_minus_5 Minus 5%:$HB_minus_5
Calculated: $BMR Calculated: $HB_main
Plus 5%:$BMR_plus_5 Plus 5%:$HB_plus_5
Plus 20%:$BMR_plus_20 Plus 20%:$HB_plus_20
]; # Now everything is in pounds and inches, since HB is relative anyway. # Calculate BMI because the code was already stolen from SFEBMIcalc and # what the heck -- give people more info! if($weight > 0 && $height > 0){ $BMI = sprintf("%.02f", ( $weight / ($height * $height)) * 703); } else { $BMI = "?"; } # The get_form subroutine pretty much prints out the form, saves whatever # they entered, etc. print &get_form; $about_hb_link = qq[] . qq[About this calculator]; print qq[
]; print "$HB" if $HB; print "Your calorie needs are unknown: calculate them!" if !$HB; print qq[ ]; print $about_hb_link; print qq[
]; print $footer; exit(); sub get_form { $form = "
How many calories do you need?

(Based on the Harris-Benedict formula)

$errweight Your weight:
$errheight Your Height:
$errage Your Age (in Years):
$errgender Your Gender:
$errlifestyle Your Lifestyle: (?)
 
BMI Meaning
Over 29.9 Obese
25.0 - 29.9 Overweight
18.5 - 24.9 Healthy
Under 18.5 Underweight
Your BMI $BMI
About BMI
"; $form; } sub parse_form_data { my($string,%data,@data); # get data if ($ENV{'REQUEST_METHOD'} eq 'GET') { $_ = $string = $ENV{'QUERY_STRING'}; tr/\"~;/_/; $string = $_; } else { read(STDIN, $string, $ENV{'CONTENT_LENGTH'}); $_ = $string; $OK_CHARS='a-zA-Z0-9=&%\n\/_\-\.@'; tr/\"~;/_/; $string = $_; } # split data into name=value pairs @data = split(/&/, $string); # split into name=value pairs in associative array foreach (@data) { split(/=/, $_); $_[0] =~ s/\+/ /g; # plus to space $_[0] =~ s/%(..)/pack("c", hex($1))/ge; # hex to alphanumeric $data{"$_[0]"} = $_[1]; } # translate special characters foreach (keys %data) { $data{"$_"} =~ s/\+/ /g; # plus to space $data{"$_"} =~ s/%(..)/pack("c", hex($1))/ge; # hex to alphanumeric } %data; # return associative array of name=value } sub convert_to_pounds { my($kilos) = $_[0]; my($pounds) = $kilos * 2.20462262; $pounds; } sub convert_to_inches { my($centimeters) = $_[0]; my($inches) = $centimeters * 0.393700787; $inches; } sub print_explanation { print "$_[0]"; exit(); }