## Gasoline Mileage Log

### November 2, 2012

We assume that the input file has only two fields per line, mileage and gallons. Then we can use `read` to read the two fields in order, converting them to numbers as it reads. Here’s the program:

```(define (show-log file-name)   (display "Miles Gals Avg") (newline)   (display "------ ---- ----") (newline)   (with-input-from-file file-name     (lambda ()       (let* ((old (read)) (gals (read)))         (let loop ((old old))           (let* ((new (read)) (gals (read)))             (unless (eof-object? (peek-char))               (display new) (display " ")               (display gals) (display " ")               (display1 (/ (- new old) gals))               (newline)               (loop new))))))))```

One of the weaknesses of Standard Scheme is its lack of display formatting capabilities:

```(define (display1 x)   (let ((x (inexact->exact (floor (* 10 x)))))   (display (quotient x 10))   (display ".")   (display (modulo x 10))))```

Here’s the output:

```> (show-log log) Miles  Gals  Avg ------ ---- ---- 107934 10.4 24.5 108197 12.2 21.5 108518 13.8 23.2 108762 12.2 20.0 109028 11.5 23.1 109306 12.4 22.4 109589 11.1 25.4```

You can run the program at http://programmingpraxis.codepad.org/Ig82n9QQ.

Pages: 1 2

### 4 Responses to “Gasoline Mileage Log”

1. […] today’s Programming Praxis exercise, our goal is to calculate and show the gas mileage given an input file […]

```import Text.Printf

line :: String -> (Float, Float)
line s = (m,g) where Just (m,_,g) = readf (Float, Space, Float) s

showLog :: [(Float, Float)] -> [String]
showLog es = "Miles  Gals  Avg" : "------ ---- ----" : zipWith (\(m2,g) (m1,_) ->
printf "%.0f %.1f %.1f" m2 g ((m2 - m1) / g)) (tail es) es

main :: IO ()
main = mapM_ putStrLn . showLog . map line . lines =<< readFile "input.txt"
```
3. Paul said

My Python solution.

```print "{0:s}".format("Miles   Gals   Avg\n-----   ----  ----")
oldmiles = None
for line in open("mileage.txt"):
miles, gals = [float(e) for e in line.split()]
if oldmiles:
avg = (miles - oldmiles) / (gals)
print "{0:6.0f}  {1:3.1f}  {2:3.1f}".format(miles, gals, avg)
oldmiles = miles
```
4. […] Pages: 1 2 […]