[comp.sources.misc] v02i017: MPG - Fuel Economy Calculator

wnp@dcs.UUCP (01/26/88)

Comp.sources.misc: Volume 2, Issue 17
Submitted-By: Wolf Paul <wnp@dcs.UUCP>
Archive-Name: mpg

I hope this is useful to some of the folks out there, if only
as a sample of what can be done with the UNIX shell.

Wolf Paul
ihnp4!killer!wnp

-------------------
#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create the files:
#	README
#	eurmpg
#	fpdivide.1
#	fpdivide.c
#	mpg.1
#	mpgdata
#	ukmpg
#	usmpg
# This archive created: Sun Jan 17 18:10:21 1988 by ihnp4!killer!wnp
export PATH; PATH=/bin:$PATH
if test -f 'README'
then
	echo shar: will not over-write existing file "'README'"
else
cat << \SHAR_EOF > 'README'
The enclosed files are an example of a floating point application
written in Bourne shell scipt, with the aid of a short program,
FPDIVIDE.

FPDIVIDE will divide, multiply, add, and subtract floating point
numbers, depending on its name.

The sample application enclosed is a Fuel Economy Calculator,
in versions for the US, UK, and the rest of the (decimal) world.

While fuel economy is not such a hot topic in the US, I don't know
of any other topic more frequently discussed when drivers of automobiles
talk about their cars in Europe.

This program will let you enter the distance driven and fuel consumed
every time you fill your tank, and will then tell you how many miles
to the gallon you have driven, or how many liters of fuel your have
consumed per 100 km driven.

It will optionally print out a short statement on the standard line printer.

With minimal modifications, this program should also run under the
MKS Toolkit implementation of the Korn Shell.

FILES:

README			this file
fpdivide.c		the source for the floating point commands
fpdivide.1		man page for the floating point commands
mpg.1			man page for the MPG programs
eurmpg			European/Decimal version of MPG
ukmpg			UK/Imperial Gallons version of MPG
usmpg			US version of MPG
mpgdata			initial $HOME/.mpgdata file, all zeros

I hope sombody finds this useful. I welcome your comments!

Wolf N. Paul
ihnp4!killer!wnp
ihnp4!killer!dcs!wnp
ihnp4!killer!doulos!wnp
SHAR_EOF
fi # end of overwriting check
if test -f 'eurmpg'
then
	echo shar: will not over-write existing file "'eurmpg'"
else
cat << \SHAR_EOF > 'eurmpg'
:
# eurmpg  (Miles Per Gallon - European Version) -- A Fuel Economy Calculator
# 
# This shell program uses the floating point arithmetic commands
# "fp*" to calculate fuel economy in terms of liters per 100 km,
# miles per US gallon, and miles per UK (Imperial) gallon.
#
# As distributed, the program assumes that the user will enter 
# the distance travelled in KILOMETERS, and the amount of fuel used
# in LITERS, but that is not difficult to change to any other
# combination of volume and distance measuring units.
#
# Author: Wolf N. Paul (ihnp4!killer!dcs!wnp), 1/13/88
# Released into the Public Domain, Jan 18, 1988
#
# set -v # enable debugging
#
# CONSTANTS:
#
FILE=$HOME/.mpgdata
US_GALLON=3.8
UK_GALLON=4.5
MILE=1.6
#
# Variables - all initialized to 0.0
C_MILES=0.0		# current miles
C_KMS=0.0		# current kilometers
C_USGAL=0.0		# current gallons US
C_UKGAL=0.0		# current gallons UK
C_LITERS=0.0	# current liters
T_MILES=0.0		# total miles
T_KSM=0.0		# total kilometers
T_USGAL=0.0		# total gallons US
T_UKGAL=0.0		# total gallons UK
T_LITERS=0.0	# total liters
C_USMPG=0.0		# current miles/gallon US
C_UKMPG=0.0		# current miles/gallon UK
C_LP100=0.0		# current liters/100 km
A_USMPG=0.0	# average miles/gallon US
A_UKMPG=0.0	# average miles/gallon UK
A_LP100=0.0	# average liters/100 km
TMP=0.0			# kms/100

echo "MPG - Fuel Economy Calculator\n"
echo "European (Decimal) Version - enter Kilometers and Liters\n"

echo "Reading old values ... \c"

T_MILES=`cut -d: -f1 $FILE`
T_KMS=`cut -d: -f2 $FILE`
T_USGAL=`cut -d: -f3 $FILE`
T_UKGAL=`cut -d: -f4 $FILE`
T_LITERS=`cut -d: -f5 $FILE`
echo "done!\n"

echo "Enter kilometers driven: \c"
read C_KMS

echo "Enter liters used: \c"
read C_LITERS

echo "\nOne moment - calculating consumption figures ... \c"
C_MILES=`fpdivide $C_KMS $MILE`
C_USGAL=`fpdivide $C_LITERS $US_GALLON`
C_UKGAL=`fpdivide $C_LITERS $UK_GALLON`

T_MILES=`fpadd $T_MILES $C_MILES`
T_KMS=`fpadd $T_KMS $C_KMS`
T_USGAL=`fpadd $T_USGAL $C_USGAL`
T_UKGAL=`fpadd $T_UKGAL $C_UKGAL`
T_LITERS=`fpadd $T_LITERS $C_LITERS`

C_USMPG=`fpdivide $C_MILES $C_USGAL`
A_USMPG=`fpdivide $T_MILES $T_USGAL`

C_UKMPG=`fpdivide $C_MILES $C_UKGAL`
A_UKMPG=`fpdivide $T_MILES $T_UKGAL`

TMP=`fpdivide $C_KMS 100.00`
C_LP100=`fpdivide $C_LITERS $TMP`
TMP=`fpdivide $T_KMS 100.00`
A_LP100=`fpdivide $T_LITERS $TMP`

echo "$T_MILES:$T_KMS:$T_USGAL:$T_UKGAL:$T_LITERS" > $FILE

echo "done!"
echo "\nFuel Economy:\n"
echo "\t$C_LP100 liters per 100 km\t\t(Average ${A_LP100})"
echo "\t$C_UKMPG miles per UK gallon\t(Average ${A_UKMPG})"
echo "\t$C_USMPG miles per US gallon\t(Average ${A_USMPG})"
echo "\nDo you want a printout of these results? \c"
read REPLY
if [ "$REPLY" != "y" -a "$REPLY" != "Y" ] ; then
	exit
fi
echo "
MPG (Eur) -- Fuel Economy Calculator
Fuel Economy Statement as of `date '+%h %d, 19%y'`

Kilometers this Filling:   $C_KMS\t($C_MILES miles)
Liters this Filling:       $C_LITERS\t($C_USGAL US, $C_UKGAL UK)

Total Kilometers so far:   $T_KMS\t($T_MILES miles)
Total Liters so far:       $T_LITERS\t($T_USGAL US, $T_UKGAL UK)

Current Liters per 100 km: $C_LP100\t($C_USMPG US, $C_UKMPG UK)
Average Liters per 100 km: $A_LP100\t($A_USMPG US, $A_UKMPG UK)\
" | lp -s &
SHAR_EOF
fi # end of overwriting check
if test -f 'fpdivide.1'
then
	echo shar: will not over-write existing file "'fpdivide.1'"
else
cat << \SHAR_EOF > 'fpdivide.1'
.TH FPDIVIDE 1L Local
.SH NAME
fpdivide, fpmultiply, fpadd, fpsubtract \-
floating point math programs for shell scripts
.SH SYNOPSIS
fpdivide
.I num1 num2
# performs the division
.I num1 / num2

fpmultiply
.I num1 num2
# performs the multiplication
.I num1 * num2

fpadd
.I num1 num2
# performs the addition
.I num1 + num2

fpsubtract
.I num1 num2
# performs the subtraction
.I num1 - num2

.SH DESCRIPTION
These commands, which are really links to the same program, perform
the floating point arithmetical operations as listed above, and print
their result (with a precision of two decimal digits) on the standard
output.

They are designed to add simple floating point arithmetic to Bourne and
Korn shell scripts.

.SH INSTALLATION
Compile the source file,
.I fpdivide.c,
copy the resulting executable into your local
.I bin
directory, and make additional links
.I fpmultiply, fpadd,
and
.I fpsubtract
to the same binary.

.SH AUTHOR
Wolf N. Paul, ihnp4!killer!dcs!wnp
.br
Released into the Public Domain, Jan 18, 1988

SHAR_EOF
fi # end of overwriting check
if test -f 'fpdivide.c'
then
	echo shar: will not over-write existing file "'fpdivide.c'"
else
cat << \SHAR_EOF > 'fpdivide.c'
/* fpdivide.c - floating point math program
 *
 * The program's action depends on its name:
 *
 * fpdivide		divide two floating point numbers
 * fpmultiply	multiply two floating point numbers
 * fpadd		add two floating point numbers
 * fpsubtract	subtract two floating point numbers
 *
 * In any case, the program takes two arguments and prints its result
 * to the standard output.
 *
 * The program was written to add floating point arithmetic to shell programs.
 *
 * Author: Wolf N. Paul, ihnp4!killer!dcs
 * 
 * Released into the Public Domain, Jan 18, 1988
 */

#include <stdio.h>


char *basename(s)
char *s;
{
	char *base;
	char *strrchr();

	if ( ( base = strrchr(s, '/')) != NULL)
		return(&base[1]);
	return(s);
}


main(argc, argv)
int argc;
char **argv;
{
	int division, multiplication, addition, subtraction;
	char *progname;
	char *basename();
	float dividend, divisor, quotient;
	float factor1, factor2, product;
	float num1, num2, sum;
	float atof();

	progname = basename(argv[0]);

	if ( strcmp(progname, "fpdivide") == 0 )
		division = 1;
	else if ( strcmp(progname, "fpmultiply") == 0 )
		multiplication = 1;
	else if ( strcmp(progname, "fpadd") == 0 )
		addition = 1;
	else if ( strcmp(progname, "fpsubtract") == 0)
		subtraction = 1;

	if ( argc != 3 )
	{
		if ( division )
			fprintf(stderr,"Usage: %s dividend divisor\n\n", progname);
		else if ( multiplication )
			fprintf(stderr,"Usage: %s factor1 factor2\n\n", progname);
		else if ( addition || subtraction)
			fprintf(stderr,"Usage: %s num1 num1\n\n", progname);
		exit(-1);
	}

	if ( division )
	{
		dividend = atof(argv[1]);
		divisor  = atof(argv[2]);
		if ( divisor <= 0.0 )
		{
			fprintf(stderr,"%s: divisor is zero or less.\n",
					argv[0]);
			exit(-2);
		}
		quotient = dividend / divisor;
		fprintf(stdout,"%.2f\n", quotient);
	}
	else if ( multiplication )
	{
		factor1 = atof(argv[1]);
		factor2 = atof(argv[2]);
		product = factor1 * factor2;
		fprintf(stdout,"%.2f\n", product);
	}
	else if ( addition || subtraction )
	{
		num1 = atof(argv[1]);
		num2 = atof(argv[2]);
		if ( addition ) sum = num1 + num2;
		else if ( subtraction ) sum = num1 - num2;
		fprintf(stdout,"%.2f\n", sum);
	}
}
SHAR_EOF
fi # end of overwriting check
if test -f 'mpg.1'
then
	echo shar: will not over-write existing file "'mpg.1'"
else
cat << \SHAR_EOF > 'mpg.1'
.TH MPG 1L Local
.SH NAME
mpg, usmpg, ukmpg, eurmpg \- Miles Per Gallon, A Fuel Economy Calculator
.SH SYNOPSIS
mpg
.SH DESCRIPTION
.B Mpg
is a
.I fuel economy calculator,
i.e. it calculates fuel consumption statistics for a motor vehicle.

The program displays its results on the terminal screen, and optionally
will produce a short statement on the standard line printer.

There are three versions of the program, based on the fact that there are
three (or rather, two and one half) systems of measurement commonly used
to measure distance travelled and fuel consumed.

.B USMPG
is the American version of the program, requesting input in miles and 
US gallons.

.B UKMPG
is the British version of the program, requesting input in miles and Imperial
gallons. Obviously, it is useful anywhere where this combination of
measurements is used.

.B EURMPG
is the European or Decimal version of the program, requesting input in
kilometers and liters. It is useful wherever the metric system has been fully
implemented.

All three versions of the program print their results both for the current
tank filling, and for the average from the first time a particular user
used the program (old data for this purpose is kept in a file in the user's
home directory.

All three versions print their results in three different formats:
.nf

-  Miles per US Gallon
-  Miles per Imperial Gallon
-  Liters per 100 Kilometers

.fi
which to my knowledge covers all common conventions to measure fuel efficiency.

The datafile $HOME/.mpgdata contains the total figures since the first time
a particular user used the program, in the form of a single line of text.
This line consists of five colon-delimited fields which contain the total miles,
kilometers, US gallons, UK gallons, and liters. Here is a sample of the
$HOME/.mpgdata file:

.nf
    598.35:957.36:21.50:18.15:81.71
       |      |     |     |     |
    miles     |  US Gall. |   Liters
		 kilometers     UK Gall.
.fi
.SH INSTALLATION
Make sure the floating point arithmetic commands (fpdivide.1) are available.
Copy the shell scripts for the three versions to your local bin directory,
and make an additional link
.I mpg
to the version you will most frequently use.
Copy the file
.I mpgdata
to $HOME/.mpgdata for every user who will use the program.
The file is compatible with all versions of the program, so the versions can
be used alternatively with no modification to #HOME/.mpgdata necessary.
.SH FILES
$HOME/.mpgdata	the datafile
.SH AUTHOR
Wolf N. Paul (ihnp4!killer!wnp)
.br
Released to the Public Domain Jan 18, 1988
SHAR_EOF
fi # end of overwriting check
if test -f 'mpgdata'
then
	echo shar: will not over-write existing file "'mpgdata'"
else
cat << \SHAR_EOF > 'mpgdata'
0.0:0.0:0.0:0.0:0.0
SHAR_EOF
fi # end of overwriting check
if test -f 'ukmpg'
then
	echo shar: will not over-write existing file "'ukmpg'"
else
cat << \SHAR_EOF > 'ukmpg'
:
# ukmpg  (Miles Per Gallon -- UK Version) -- A Fuel Economy Calculator
# 
# This shell program uses the floating point arithmetic commands
# "fp*" to calculate fuel economy in terms of liters per 100 km,
# miles per US gallon, and miles per UK (Imperial) gallon.
#
# As distributed, the program assumes that the user will enter 
# the distance travelled in MILES, and the amount of fuel used
# in UK GALLONS, but that is not difficult to change to any other
# combination of volume and distance measuring units.
#
# Author: Wolf N. Paul (ihnp4!killer!dcs!wnp), 1/13/88
# Released into the Public Domain, Jan 18, 1988
#
# set -v # enable debugging
#
# CONSTANTS:
#
FILE=$HOME/.mpgdata
US_GALLON=3.8
UK_GALLON=4.5
MILE=1.6
#
# Variables - all initialized to 0.0
C_MILES=0.0		# current miles
C_KMS=0.0		# current kilometers
C_USGAL=0.0		# current gallons US
C_UKGAL=0.0		# current gallons UK
C_LITERS=0.0	# current liters
T_MILES=0.0		# total miles
T_KSM=0.0		# total kilometers
T_USGAL=0.0		# total gallons US
T_UKGAL=0.0		# total gallons UK
T_LITERS=0.0	# total liters
C_USMPG=0.0		# current miles/gallon US
C_UKMPG=0.0		# current miles/gallon UK
C_LP100=0.0		# current liters/100 km
A_USMPG=0.0	# average miles/gallon US
A_UKMPG=0.0	# average miles/gallon UK
A_LP100=0.0	# average liters/100 km
TMP=0.0			# kms/100

echo "MPG - Fuel Economy Calculator\n"
echo "UK Version - enter Miles and Imperial Gallons\n"

echo "Reading old values ... \c"

T_MILES=`cut -d: -f1 $FILE`
T_KMS=`cut -d: -f2 $FILE`
T_USGAL=`cut -d: -f3 $FILE`
T_UKGAL=`cut -d: -f4 $FILE`
T_LITERS=`cut -d: -f5 $FILE`
echo "done!\n"

echo "Enter miles driven: \c"
read C_MILES

echo "Enter gallons used: \c"
read C_UKGAL

echo "\nOne moment - calculating consumption figures ... \c"
C_KMS=`fpmultiply $C_MILES $MILE`
C_LITERS=`fpmultiply $C_UKGAL $UK_GALLON`
C_USGAL=`fpdivide $C_LITERS $US_GALLON`

T_MILES=`fpadd $T_MILES $C_MILES`
T_KMS=`fpadd $T_KMS $C_KMS`
T_USGAL=`fpadd $T_USGAL $C_USGAL`
T_UKGAL=`fpadd $T_UKGAL $C_UKGAL`
T_LITERS=`fpadd $T_LITERS $C_LITERS`

C_USMPG=`fpdivide $C_MILES $C_USGAL`
A_USMPG=`fpdivide $T_MILES $T_USGAL`

C_UKMPG=`fpdivide $C_MILES $C_UKGAL`
A_UKMPG=`fpdivide $T_MILES $T_UKGAL`

TMP=`fpdivide $C_KMS 100.00`
C_LP100=`fpdivide $C_LITERS $TMP`
TMP=`fpdivide $T_KMS 100.00`
A_LP100=`fpdivide $T_LITERS $TMP`

echo "$T_MILES:$T_KMS:$T_USGAL:$T_UKGAL:$T_LITERS" > $FILE

echo "done!"
echo "\nFuel Economy:\n"
echo "\t$C_UKMPG miles per UK gallon\t(Average ${A_UKMPG})"
echo "\t$C_USMPG miles per US gallon\t(Average ${A_USMPG})"
echo "\t$C_LP100 liters per 100 km\t\t(Average ${A_LP100})"
echo "\nDo you want a printout of these results? \c"
read REPLY
if [ "$REPLY" != "y" -a "$REPLY" != "Y" ] ; then
	exit
fi
echo "
MPG (UK) -- Fuel Economy Calculator
Fuel Economy Statement as of `date '+%h %d, 19%y'`

Miles this Filling:        $C_MILES\t($C_KMS km)
Gallons this Filling:      $C_UKGAL\t($C_USGAL US, $C_LITERS liters)

Total Miles so far:        $T_MILES\t($T_KMS km)
Total Gallons so far:      $T_UKGAL\t($T_USGAL US, $T_LITERS liters)

Current Miles per Gallon:  $C_UKMPG\t($C_USMPG US, $C_LP100 L/100 km)
Average Miles per Gallon:  $A_UKMPG\t($A_USMPG US, $A_LP100 L/100 km)\
" | lp -s &
SHAR_EOF
fi # end of overwriting check
if test -f 'usmpg'
then
	echo shar: will not over-write existing file "'usmpg'"
else
cat << \SHAR_EOF > 'usmpg'
:
# usmpg  (Miles Per Gallon -- US Version) -- A Fuel Economy Calculator
# 
# This shell program uses the floating point arithmetic commands
# "fp*" to calculate fuel economy in terms of liters per 100 km,
# miles per US gallon, and miles per UK (Imperial) gallon.
#
# As distributed, the program assumes that the user will enter 
# the distance travelled in MILES, and the amount of fuel used
# in US GALLONS, but that is not difficult to change to any other
# combination of volume and distance measuring units.
#
# Author: Wolf N. Paul (ihnp4!killer!dcs!wnp), 1/13/88
# Released into the Public Domain, Jan 18, 1988
#
# set -v # enable debugging
#
# CONSTANTS:
#
FILE=$HOME/.mpgdata
US_GALLON=3.8
UK_GALLON=4.5
MILE=1.6
#
# Variables - all initialized to 0.0
C_MILES=0.0		# current miles
C_KMS=0.0		# current kilometers
C_USGAL=0.0		# current gallons US
C_UKGAL=0.0		# current gallons UK
C_LITERS=0.0	# current liters
T_MILES=0.0		# total miles
T_KSM=0.0		# total kilometers
T_USGAL=0.0		# total gallons US
T_UKGAL=0.0		# total gallons UK
T_LITERS=0.0	# total liters
C_USMPG=0.0		# current miles/gallon US
C_UKMPG=0.0		# current miles/gallon UK
C_LP100=0.0		# current liters/100 km
A_USMPG=0.0	# average miles/gallon US
A_UKMPG=0.0	# average miles/gallon UK
A_LP100=0.0	# average liters/100 km
TMP=0.0			# kms/100

echo "MPG - Fuel Economy Calculator\n"
echo "US Version - Enter Miles and US Gallons\n"

echo "Reading old values ... \c"

T_MILES=`cut -d: -f1 $FILE`
T_KMS=`cut -d: -f2 $FILE`
T_USGAL=`cut -d: -f3 $FILE`
T_UKGAL=`cut -d: -f4 $FILE`
T_LITERS=`cut -d: -f5 $FILE`
echo "done!\n"

echo "Enter miles driven: \c"
read C_MILES

echo "Enter gallons used: \c"
read C_USGAL

echo "\nOne moment - calculating consumption figures ... \c"
C_KMS=`fpmultiply $C_MILES $MILE`
C_LITERS=`fpmultiply $C_USGAL $US_GALLON`
C_UKGAL=`fpdivide $C_LITERS $UK_GALLON`

T_MILES=`fpadd $T_MILES $C_MILES`
T_KMS=`fpadd $T_KMS $C_KMS`
T_USGAL=`fpadd $T_USGAL $C_USGAL`
T_UKGAL=`fpadd $T_UKGAL $C_UKGAL`
T_LITERS=`fpadd $T_LITERS $C_LITERS`

C_USMPG=`fpdivide $C_MILES $C_USGAL`
A_USMPG=`fpdivide $T_MILES $T_USGAL`

C_UKMPG=`fpdivide $C_MILES $C_UKGAL`
A_UKMPG=`fpdivide $T_MILES $T_UKGAL`

TMP=`fpdivide $C_KMS 100.00`
C_LP100=`fpdivide $C_LITERS $TMP`
TMP=`fpdivide $T_KMS 100.00`
A_LP100=`fpdivide $T_LITERS $TMP`

echo "$T_MILES:$T_KMS:$T_USGAL:$T_UKGAL:$T_LITERS" > $FILE

echo "done!"
echo "\nFuel Economy:\n"
echo "\t$C_USMPG miles per US gallon\t(Average ${A_USMPG})"
echo "\t$C_UKMPG miles per UK gallon\t(Average ${A_UKMPG})"
echo "\t$C_LP100 liters per 100 km\t\t(Average ${A_LP100})"
echo "\nDo you want a printout of these results? \c"
read REPLY
if [ "$REPLY" != "y" -a "$REPLY" != "Y" ] ; then
	exit
fi
echo "
MPG (US) -- Fuel Economy Calculator
Fuel Economy Statement as of `date '+%h %d, 19%y'`

Miles this Filling:        $C_MILES\t($C_KMS km)
Gallons this Filling:      $C_USGAL\t($C_UKGAL UK, $C_LITERS liters)

Total Miles so far:        $T_MILES\t($T_KMS km)
Total Gallons so far:      $T_USGAL\t($T_UKGAL UK, $T_LITERS liters)

Current Miles per Gallon:  $C_USMPG\t($C_UKMPG UK, $C_LP100 l/100 km)
Average Miles per Gallon:  $A_USMPG\t($A_UKMPG UK, $A_LP100 l/100 km)\
" | lp -s &
SHAR_EOF
chmod +x 'usmpg'
fi # end of overwriting check
#	End of shell archive
exit 0