This program will help you develop a useful application from input, output, calculations (including modulo), and data types. It is also a good place to start using constants.
Write a program that helps the user convert information given in (whole) ounces into pounds and ounces.
To refresh your memory, there are 16 ounces (which is always abbreviated oz.) in a pound (which is abbreviated lb. singularly or lbs. in the plural).
Be sure to report the results neatly.
As an example, you might have the program interaction look something like (the parts in this color are typed by the user):
$ ./ounces.out
Welcome to the Ounce Conversion Program!!!
How many ounces do you have? 62
Thank you!! Calculating... Done.
62 oz. is equivalent to 3 lbs. and 14 oz. (3.875 lbs.).
Thank you for using the OCP!!
Endeavor to have a magnanimous day!
$
This assignment is (Level 2).
Some users might like to type in their units along with their ounce value. Although we could just ignore them on a personal level — since there is only one input in this program and leaving crap...er... their units in the buffer wouldn't hurt anyone — it would probably be best to truly ign...er...to get rid of the units from the input buffer. If nothing else, it would be good practice for us, right?
Add (Level 1) to allow the user to type the oz (or perhaps even ounces?) after their weight value. Since this is the only unit we told them they could use, we do not need to care about what was actually entered — we just need to remove it from the input stream so that, should we update this code later and need to input more values, we'd be able to do so readily and with a clean buffer.
With this change, the program interaction might look like so (the parts in this color are typed by the user):
$ ./ounces.out Welcome to the Ounce Conversion Program!!! How many ounces do you have? 62 oz Thank you!! Calculating... Done. 62 oz. is equivalent to 3 lbs. and 14 oz. (3.875 lbs.). Thank you for using the OCP!! Endeavor to have a magnanimous day! $ ./ounces.out Welcome to the Ounce Conversion Program!!! How many ounces do you have? 62oz Thank you!! Calculating... Done. 62 oz. is equivalent to 3 lbs. and 14 oz. (3.875 lbs.). Thank you for using the OCP!! Endeavor to have a magnanimous day! $
Note that, on the first run, this example user has entered the same value as above and gotten the same answers. They simply typed in the units after their value instead of the value alone.
Note also that, on the second run, they mistyped and skipped the space between the value and the unit name!
Here's another example that should work with this option-enhanced program (the parts in this color are typed by the user):
$ ./ounces.out Welcome to the Ounce Conversion Program!!! How many ounces do you have? 62 ounces (of course...that is what you told me to use, isn't it?) Thank you!! Calculating... Done. 62 oz. is equivalent to 3 lbs. and 14 oz. (3.875 lbs.). Thank you for using the OCP!! Endeavor to have a magnanimous day! $
This one should also work (the parts in this color are typed by the user):
$ ./ounces.out Welcome to the Ounce Conversion Program!!! How many ounces do you have? 62 Thank you!! Calculating... Done. 62 oz. is equivalent to 3 lbs. and 14 oz. (3.875 lbs.). Thank you for using the OCP!! Endeavor to have a magnanimous day! $
And even this one — sadly (the parts in this color are typed by the user):
$ ./ounces.out Welcome to the Ounce Conversion Program!!! How many ounces do you have? 62 blah, blah, blah, blah...always worried about them ounces, ain't ye'? no one ever considers the poor, lonely 'gram' or the miserable, out-cast 'stone', do they?! BAH! Thank you!! Calculating... Done. 62 oz. is equivalent to 3 lbs. and 14 oz. (3.875 lbs.). Thank you for using the OCP!! Endeavor to have a magnanimous day! $
If the user's input is potentially followed by garbage (well, textual information we don't want or need, anyway), how can we throw it away? More specifically, how do we tell cin that we don't want or need the buffer contents...that it can simply be ignored?
Does this facility require anything other than our usual #include of iostream at the top of our program?
(What else do we need? Where do we get it? What does it normally represent? What does it represent here in cin's philosophy of the world?)
Why don't we need/use the string data type in this situation? (Doesn't string allow us to store multiple characters in a single variable — like units?) (Which of the above example situations would the string data type not handle well? What would happen in those situations were we to use string — as opposed to what we said we'd want to happen in the examples?)
The pattern used for unit conversions is fairly simplistic and common. But it would seem that we are doing some extra 'divisions' that are not really necessary. (A really smart compiler will remove the duplicates for us, but not all compilers are smart, much less really smart...)
What can we remove? Let's look at the pattern again here:
UNITS = amount / units_per_UNITS; Units = amount % units_per_UNITS / units_per_Units; units = amount % units_per_UNITS % units_per_Units;
Here I've got the ALL CAPITAL variable UNITS to represent the largest-sized unit of the set in which we are interested (that could be hours for time of day or yards in the length example online or dimes in some monetary example you may have seen...er...somewhere or whatever). Then the Merely Capitalized variable Units is representing the middle-sized unit of the set in which we are interested (like minutes, feet, or nickels...). Lastly, the all lowercased variable units is representing the smallest-sized unit of the set in which we are interested (like seconds, inches, or pennies). The constants of conversion are all named in a manner similar to these results variables (in terms of capitalization vs. unit size).
(Um...I suppose I forgot the variable amount, hunh? That is the amount of whatever we are measuring that the user entered in the first place. It is measured in the smallest-sized unit of our unit system.)
Now, there are at least two ways to approach this problem. The first is as a mathematician and the second is as a programmer. Since most of us aren't much of either (or of only one or the other), I'll make it worth (Level 2) to write a report (see the standards for writing papers elsewhere) detailing both of these approaches to reducing the 'divisions' in our pattern. (If you can only figure out one of the two patterns, you can still get (Level 1) to write that one up.) You must explain how each approach reduces the number of division and/or modulo operations, which one(s) you can remove, and show the resulting code (code typesets best in a fixed width font — like Courier, btw). Make your explanation clear and thorough! (Don't explain like you are telling the teacher, explain like you are telling your friend or room-mate or little brother/sister.)
Please note that you won't be making a major reduction in the number of divisions/modulos that occurs, but any reductions in coding complexity and user time taken up are always welcome! Using either method, you can reduce the code to at the fewest three (3) division/modulo operations. Each approach, however, removes different ones in different ways.
To be perfectly honest, the pattern as it stands only makes four (4) division/modulo operations — even though there are clearly five (5) in the code. (Remember that the CPU calculates both the quotient and the remainder in one-fell-swoop so if properly paired, the compiler can take advantage of this and not actually request the second operation...um...*looks around furtively*...never-mind... Forget I said anything... If anyone asks, we never spoke! *frantic footsteps run down the alley-way*)
This problem is, though, interesting numerically, since we are always dividing/moduloing by the conversion factor from the smallest-sized unit's perspective. That is, when dealing with lengths, all the conversion factors are measuring how many inches it takes to make up the other units. Or when dealing with time, all the conversion factors deal with the number of seconds it takes to equal a single one of the other units. That seems somehow useful...if I could just put my finger on it...
Maybe a slightly different perspective! The conversion factors are all built from the smallest unit up. And if we examine how the constants were defined just below the pattern in the notes, we see that is exactly how they are defined — starting with the conversion from smallest unit to middle unit and then using that information to build to the next largest and so on (see the time constants). Hmm...they are are multiplied up from the bottom...so they all start with that first conversion factor...um...yeah! That first conversion factor is a common factor through all of the conversion factors! (And if a common factor isn't useful in dividing then I...*snaps fingers* Um...disregard that...yeah... *shakes head unconvincingly* I don't really know what I'm talking about! Just forget I was even here... *a jerk of the wrist and a puff of smoke and he's gone!*)
!!!SPECIAL!!!: Since you aren't writing a program for this option, but a report, you can answer these as part of your report. In fact, a discussion of either method without the proper questions from below answered would be poor and inadequate!
[Programmer Approach]
Of what use is our knowledge (imparted by that mysterious stranger
above) that the CPU does integer 'division' operations as a
two-for-one deal? That is, is it useful to us here to know that
whenever we request either an integer quotient or an integer
remainder, we actually get both?
[Mathematician Approach]
If two integers m and n share a common factor p, what can you tell me about the following
calculations' results?
r1 = q % m % p; r2 = q % n % p;
What, if anything, does this have to do with:
r3 = q % p;
Bonus
Would any of this be of use in working with either of the
following?
r4 = q % m % n; r5 = q % n % m;
[Either Approach]
The first hesitant helper above pointed out (round-about-ly) that we'd
only be reducing the division/modulo count from four (4) to three (3)
— or by one (1). This kind of makes sense — that only one could be
removed. You can't remove one of each, since they do such vastly
different (yet intimately related) things.
Explore this idea...well, a little, anyway.
If you did all above options, this lab could be worth as much as (Level 5).