Another stab at programming

Discussion in 'Scripting & Programming' started by tripwire45, Jul 23, 2009.

  1. tripwire45
    Honorary Member

    tripwire45 Zettabyte Poster

    13,493
    180
    287
    Taking another swing at learning programming/computer science using this book. It's a really good book, but the exercises at the end of each chapter don't have an answer key. I tried the forums for the publisher, but no love there.

    Despite that, I conquered 9 out of 10 of the exercises from the first chapter, but number 9 is sticking me. To understand the problem, I have to tell you how I solved another problem first (you'll see how it figures in).

    I was to write a function that converts miles per gallon to liters per 100 kilometers. Here's my solution (and it works):

    Code:
    def convert_mileage(m):
         return (100 * 3.7854411784) / (1.609355 * m)
    The problem I'm stuck on is having to define a function that takes the value of distance in kilometers and th evalue for a car's gas mileage, and returns the amount of gas in liters needed for the trip. One of the conditions of the exercise is that this function should call the "convert_mileage" function as previously written. Here's my solution where d = kilometers and m = mileage:

    Code:
    def liters_needed(d, m):
        return d / convert_mileage(m)
    The results are close, but the values are too large. I'm not an algebra guru so I've probably made a basic math problem somewhere along the way. Any ideas?

    Thanks.
     
    Certifications: A+ and Network+
  2. dmarsh
    Honorary Member 500 Likes Award

    dmarsh Petabyte Poster

    4,305
    503
    259
    I'm not a python programmer so the syntax looks a bit nasty to me.

    For the second part :-
    Don't you need to convert kilometers to miles first ? Then divide miles by miles per galllon to get gallons. Then convert gallons to litres ?

    If you were doing this for real you'd have a lot more self documenting code.

    Like in C :-

    // returns Litres required for a given distance travelled in km and a vehicles miles per gallon consumption.
    double litresRequired(double distanceInKm, double mpg);

    // returns Litres per 100 km consumption for a vehicle
    double mileageInLitresPerHundredKm(double mpg);

    In reality you'd prob have to be even more anal than that, as there is no universal definition of a gallon.

    The way your codes written you'd need to divide by 100 in your litres_needed method as your unit is 100 km not 1 km.

    Heres what happens when you get your units wrong :-

    http://www.youtube.com/watch?v=YAg-WauGrLU
    http://en.wikipedia.org/wiki/Ariane_5_Flight_501
     
  3. tripwire45
    Honorary Member

    tripwire45 Zettabyte Poster

    13,493
    180
    287
    I think the convert_mileage function should fit the bill. The formula I used to write the covert_mileage function is here:

    Definitions:

    lp100km = liters per 100 km
    kmpm = mpg = miles per gallon
    lpg = liters per gallon (US) = 3.785411784
    kmpm = kilometers per mile = 1.609344

    Formula:

    lp100km = 100 * lpg / kmpm * mpg

    Function:

    Code:
    >>> def convert_mileage(m):
    ...     return (100 * 3.7854411784) / (1.609355 * m)
    Since one of the conditions of the new function is that it should call the convert_mileage function, It seems like I should just be able to divide the distance by the convert_mileage function to get the desired result. In the liters_needed function, d = distance in kilometers and m = mileage (as it does in the convert_mileage function), so providing the specific values of d and m in the liters_needed function and then performing this:

    Code:
    return d / convert_mileage(m)
    should do it. Mathematically, it's really this:

    Code:
    return d * (100 * 3.7854411784) / (1.609355 * m)
    I don't thing my problem is so much my coding as my lack of understanding the correct mathematical formula to accomplish the desired goal (curse my poor math skills).
     
    Certifications: A+ and Network+
  4. dmarsh
    Honorary Member 500 Likes Award

    dmarsh Petabyte Poster

    4,305
    503
    259
    If the first conversion is from mpg to litresPer100Km then obviously your input is mpg.

    For the second part :-

    You want your answer in litres right ?
    And your input is in kilometers ?
    But you function works out litresPer100Km !

    What is your test data ?
    Expected, actual etc ?

    First bit :-

    mpg/3.785411784 = Miles per litre = MPL
    MPL*1.609344 = Kilometers per litre = KPL
    (1/KPL) = Litres per kilometre = LPK
    LPK*100 = Litres per 100 Kilometer = LP100K

    e.g.

    (1/((mpg/3.785411784)*1.609344))*100.0


    Second bit :-

    (km*LP100K)/100 = litres

    e.g.

    (km * convertMileage(mpg))/100.0

    I'm sure BM will correct me, chemists and scientists do this stuff all day long...
     
  5. tripwire45
    Honorary Member

    tripwire45 Zettabyte Poster

    13,493
    180
    287
    Ok, I can't solve the problem using the convert_mileage function, but I can modify the formula used in convert_mileage to solve the problem.

    Here's the original formula that solves the convert_mileage function and tests correctly:

    Code:
    >>> def convert_mileage(m):
    ...     return (100 * 3.7854411784) / (1.609355 * m)
    Here's what makes the liters_needed function work:

    Code:
    def liters_needed(d, m):
        return d * (100 * 3.7854411784) / (1.609355 * m)
    Basically, instead of multiplying liters per gallon (US) by 100 to get the miles per gallon to liters per 100 kilometers conversion, I multiply by 1 to get miles per gallon to liters per kilometer. The function tests out correctly now.

    Guess I was thrown by the instruction to use the convert_mileage function as originally written.

    Thanks for all the input. :biggrin
     
    Certifications: A+ and Network+
  6. dmarsh
    Honorary Member 500 Likes Award

    dmarsh Petabyte Poster

    4,305
    503
    259
    Are you sure ? :blink

    Multiplying anything by 1 does nothing, how could this perform a units conversion ? None of this statement makes any sense !

    EDIT : I see now inverting statement or taking reciprocal using 1/x can swap the units round.

    Have a good look at my answer. :D
     
  7. tripwire45
    Honorary Member

    tripwire45 Zettabyte Poster

    13,493
    180
    287
    Post #3 here in this thread listed the conversion data I'm using. I know what you're saying about multiplying by one, but the original formula has the value "100" in that position as part of converting miles per gallon to liters per 100 kilometers. I figured if it just had to convert miles per gallon to liters per (1) kilometer, that would work.

    The book I'm using provides several test cases such as liters_needed(150, 30) and liters_needed(100, 30). When I test the function using those values, the result matches the book very, very closely.

    Book: 11.761938367442955
    Me: 11.760740105197424

    and

    Book: 7.84129224496197
    Me: 7.8404934034649489

    If my function is bogus, I'd be surprised the output matches so closely with what's expected. You're right, though about BM. I suppose he's come in here at some point and straighten this mess out. Sorry to try your patience.
     
    Certifications: A+ and Network+
  8. dmarsh
    Honorary Member 500 Likes Award

    dmarsh Petabyte Poster

    4,305
    503
    259
    No problem trip, glad if I can be of any help !:thumbleft

    The problem with division and multiplication is they are commutative, thus you could put all the operations in any order and still get the right result !

    As long as the operations themselves were correct !

    Does your convert_mileage() routine pass the tests ?

    Something per something, is basically a ratio or fraction, it has an in built division basically.

    Multiplying by the divisor brings it back to the original units, ie mph * hours = miles. Because (m/h)*h=m

    Linear conversions are normally done wih ratios, here you either multiply by the ratio or divide by another number.

    eg

    1 m = 1/1000 km or 1000 m = 1 km

    Therefore m -> km we multiply by ratio 1/1000. We use the reciprocal to go the other way, eg km -> m multiply by 1000.

    Similar with currencies except theres a spread involved so there are two seperate ratios.

    Then there are non linear conversion like celcius to farenheit etc.

    Heres how I read you equation :-

    return d * (100 * 3.7854411784) / (1.609355 * m)

    d = kilometres travelled
    m = miles per gallon

    miles per gallon * 1.609355 = ??? Makes no sense, gallons -> litres is multiply by 3.7854411784, however here gallons is on the bottom mile PER gallon, mph -> mpl, you should get LESS miles per litre ! This conversion could be kilometres per gallon I guess ?

    100 * 3.7854411784 = ??? You need to divide km by 100 to get per 100km not multiply ! To convert miles to km you need to multiply by 3.7854411784, however your mph figure is the wrong side of the division operator ! Multiply by 100 is correct based on above, it turns kilometers per gallon into 100 kilometres per gallon. So is litres conversion correct, to turns gallons into litres.

    d * ...

    To convert km to liters using litresPer100Km to litres you need to divide by 100 and multiply by your litresPer100Km figure. So this is probably correct, see above corrected post !

    So yes your calculations are correct, but in a somewhat strange order ! :D If there were non commutative operators like + and - you could have had some issues ! Also its good to try to structure it in a easilly readable fashion.

    Also I would use constants for your conversion factors.

    I do like the pragmatic programmer series though, they are very good in general.
     
  9. dmarsh
    Honorary Member 500 Likes Award

    dmarsh Petabyte Poster

    4,305
    503
    259
    Code:
    #include "stdafx.h"
    #include <iostream>
    
    using namespace std;
    
    static const double KM_TO_MILE = 1.609344L;
    static const double US_GALLON_TO_LITRE = 3.785411784L;
    
    // returns Litres per 100 km consumption for a vehicle 
    double mileageInLitresPerHundredKm(double mpg) {
    	
    	double mileage = (1.0L/((mpg/US_GALLON_TO_LITRE)*KM_TO_MILE))*100.0L;
    
    	return mileage;
    }
    
    // returns Litres required for a given distance travelled in km and a vehicles miles per gallon consumption.
    double litresRequired(double distanceInKm, double mpg){
    	
    	double litres = (distanceInKm * mileageInLitresPerHundredKm(mpg))/100.0L;
    
    	return litres;
    }
    
    int _tmain(int argc, _TCHAR* argv[])
    {
    	cout.precision(10);
    	cout.setf(ios::fixed,ios::floatfield);
    
    	cout << "Expected : 11.761938367442955" << endl;
    	cout << "Actualt : " << litresRequired(150,30) << endl << endl;
    
    	cout << "Expected : 7.84129224496197" << endl;
    	cout << "Actualt : " << litresRequired(100,30) << endl << endl;
    
    	char n;
    	cin >> n;
    
    }
    Ok heres it in C++.

    Code:
    Expected : 11.761938367442955
    Actualt : 11.7607291667
    
    Expected : 7.84129224496197
    Actualt : 7.8404861111
    Heres my output, our results agree to 4.d.p. Gotta be something wrong somewhere should be able to get at least 5 digits of precision. Maybe they got theirs wrong ?
     

Share This Page

Loading...
  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.