10 millipedes = 1 centipede
106 phones = 1 megaphone
10 cards = 1 decacards
2000 mockingbirds = 2 kilomockingbirds
10-12 boos = 1 picoboo
-- Funny Internet Metric Chart
Let's take a trip back down memory lane. Imagine you're a high-paid engineer for NASA, and the date is late September, 1999. The entire agency is all abuzz with the prospect of the Mars Climate Orbiter (MCO), launched more than nine months ago, reaching a stable orbit around our neighboring red planet and sending back important weather data.
Data in a software file for calculating trajectory forces was in English units of pound-seconds (lbf-s), but the thruster was expecting the data to be in metric units of Newton-seconds (N-s).
History records the experience as one of the most egregious and expensive bugs of all time. Engineers and computer scientists the world over vow to be diligent to check, double-check and triple-check the units in their calculations.
For this project, you'll write a Python program to do unit conversion -- provide the translation of a quantity specified by a certain amount in one source unit and a destination unit. That is, your program should be able to answer the common question (and many more like it): How many meters in 10 miles? (answer: 10 miles = 16,093.44 m)
To make the input easy, you'll specify your queries in a simplified format:
AMOUNT SOURCE_UNIT in DESTINATION_UNIT
...which will make the understanding, or parsing of the input much easier. As an example, this is the way you would specify your earlier request:
10 mi in m
to which your program should respond:
10 mi = 16093.440000 m
What units do you need to support?
We would like you to support units in three categories: distances, volumes, and weights with at least the following units in each category:
|Unit categories||Units within that category you must support|
|distances||m (meters), cm (centimeters), mm (millimeters), km (kilometers), in (inches), ft (feet), yd (yards), mi (miles)|
|volumes||L (liters), mL (millileters), floz (fluid ounces), cup (cups), pint (pints), qt (quarts), gal (gallons)|
|weights||g (grams), kg (kilograms), mg (milligrams), oz (ounces), lb (pounds)|
You should be able to convert any amount of a unit in any category to any other unit in the same category.
Where to find the conversion constants
There are many websites and books with conversion constants listed, so feel free to get this data any way you wish. One great source is Google, who provides a very handy calculator that happens to have the exact same format for specifying these conversions. So, if you type into the Google search field:
10 mi in m
it will respond with:
10 mi = 16 093.44 m
which is the same thing we returned. They separate their thousands with a space and truncate trailing zeros; you don't have to do that if you don't want to. You can use Google to find out how many source units are in a destination unit by typing "1 source_unit in destination_unit" and build internal tables to store these answers. You could also consult the online Dictionary of Units. See the hints section below to see how we suggest you approach the internal details of storing the information.
At this point, you might wonder why we're doing all this work if Google can do it for us. The answer is threefold: first, we don't always have access to the Internet. Second, it's a valuable beginning programming activity. Finally, Google does not permit offline searches (e.g., using a Python program to call it) so we couldn't use them as our "brains".
- Welcome text for your program, listing your name, the program's use, and its input format
- A list of all the categories and units within that category you support so the user knows what they can do
- A repeating loop that asks for conversions over an over in the format we described above.
- If the format is not exactly right, a friendly, helpful error message should be printed along with the prompt again.
For example, here is our interface. Note that your program doesn't have to look exactly like ours, it only needs to adhere to the checklist above (and the final checklist below)
computer% python project2a.py Welcome to our Python-powered Unit Converter v1.0 by Dan Garcia! You can convert Distances , Weights , Volumes & Times to one another, but only within units of the same category, which are shown below. E.g.: 1 mi in ft Distances: ft cm mm mi m yd km in Weights: lb mg kg oz g Volumes: floz qt cup mL L gal pint Convert [AMT SOURCE_UNIT in DEST_UNIT, or (q)uit]: 10 mi in m 10 mi = 16093.440000 m Convert (AMT SOURCE_UNIT in DEST_UNIT, or (q)uit): 1 lb in oz 1 lb = 16.000000 oz Convert [AMT SOURCE_UNIT in DEST_UNIT, or (q)uit]: 123.456789 kg in mg 123.456789 kg = 123456789.000000 mg Convert (AMT SOURCE_UNIT in DEST_UNIT, or (q)uit): q Thanks for converting with us. Y'all come back now, y'hear? computer%
How should you store all of the multiplying factors between units? There's the hard way and the easy way to think about it. The particular Python data type you should use is something you should consider on your own.
The hard way
The hard way is to build an internal two-dimensional table of the conversion of every unit to every other unit for every category. This is really painful. Imagine how many translators the United Nations would need if they had 1,000 people speaking different languages and they used this model...a million people!
The easy way
The easy way is to find a common, base unit (e.g., meters for distances) and then just store the constant (e.g., 1000 for kilometers) that is used to convert from the base unit to that unit. To convert from two units in the same category (neither of which are the base unit), you simply convert from your
SOURCE_UNIT to the base unit, then from that to the
DESTINATION_UNIT. Using the previous analogy you'd only need to hire 1,000 translators at the UN -- as long as each could translate to and from their language to a common language, like one of the click languages. For the math-minded among you, the reason this works is that the conversion among all of our units is a Linear, Transitive relation.
Test each function in your program with enough different inputs to show that it works. When testing a function, print out the input, the expected result, and the actual result.
There are a couple of cool features you can add to make your program sing:
- Support more natural English input, like
How many meters in 10 miles?
10 miles is how many meters?
Please convert 10 miles to meters.
If it's 10 miles from school to my house in the US, how far would that have been had I lived in Europe?
- Add more dimensions, like time, flow, energy, power, area, volume, etc.
- The site OnlineConversion.com advertises 5,000 units and 50,000 conversions!
If you really had fun with this project, you might want to think about what is involved in translating one human language to another and how you'd go about writing a program to do that. Enjoy!
These are the requirements to meet for project completion.
- Use of functions — your program must be broken down into one or more functions — it cannot be one big long script.
- Each function has a docstring that summarizes its purpose and provides a description of its inputs and outputs.
- Tests and test output for each function in the program.
- All functions and variables have meaningful names.
- Tests showing the program produces correct translations among all the units of a category.
- All of the features listed in the Interface section above.