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.

Advertisement

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 […]

  2. My Haskell solution (see http://bonsaicode.wordpress.com/2012/11/02/programming-praxis-gasoline-mileage-log/ for a version with comments):

    import Text.Printf
    import Text.XFormat.Read
    
    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
    

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: