1
There is a data-file called “obs.txt”, which contains data automatically recorded by a robotic observing station somewhere on the plains of Africa. The station detects every animal that goes past, and for each one writes a one-line entry into the file. Each line of the file contains the species of animal (a string, with no spaces), the time of the observation (an int, for example 945 means 9:45 a.m., and 1400 means 2:00 p.m.), the number of legs on the animal (an int), and its speed in miles per hour (a floating point number).
For example, the first ten lines of the file might look like this:
elephant 945 4 3.20
lion 1001 4 6.05
elephant 1009 4 2.75
human 1030 2 3.50
tiger 1032 4 5.71
mosquito 1032 6 5.72
mosquito 1032 5 5.72
mosquito 1032 6 5.70
elephant 1049 4 4.04
zebra 1051 4 3.31
Write a complete C++ program that behaves as follows:
First it warns the user if the data file does not exist, or for some other reason can not be read. After warning the user, the program should not attempt to continue.
Will use ifstream fin(“obs.txt”) to open file for input, and test fin.fail() to see if anything went wrong. send error message to cerr stream and use exit(1) to terminate program if necessary.
Then it invites the user to type a species name.
Write a prompt to cout, declare a string, and read it from cin. No need for any complexities such as using getline() because there is only one input for the whole program, and it should not have any spaces in it.
Then it reads through the file, finding the minimum, average, and maximum speed observed for members of that species.
Sounds like a simple while loop. Each time round the loop, read the four variables (string, int, int, double) from the file, and break the loop if the read attempt fails (end-of-file detection). Compare the string read from the file with the string typed by the user; if they are the same, take note of the speed data.
Variables should be declared for min, max, and totals before the loop starts, and initialised carefully. If observed speed is greater than max, reset max; if observed speed is less than min, reset min; always add speed to total and one to count, so average can be calculated after the end of the loop.
Max needs to be initialised to something small, to ensure all real data exceeds it; zero is fine. Min similarly needs to be set to something very big.
Finally, after reaching the end of the file, the program should print out the minimum, average, and maximum speeds as calculated, in a user-friendly manner.
Just watch out for division by zero when calculating the average.
Then close the file.
For example, if the ten lines illustrated above were the entire file, a complete run of the program might look like this:
Species? elephant
minimum observed elephant speed = 2.75 mph
average observed elephant speed = 3.33 mph
maximum observed elephant speed = 4.04 mph
Make sure your program is as reliable as possible. Think of things that could go wrong, and check for them. However, you may assume that if the input file can be read at all, it is in the correct format.
Here is a complete program.
<iostream> is needed for cin, cout, and cerr; <string> is needed because the program uses a string, and <fstream> is needed for access to ifstream.
#include <iostream>
#include <string>
#include <fstream>
void main(void)
{ ifstream fin("obs.txt");
if (fin.fail())
{ cerr < "Input file 'obs.txt' not found\n";
exit(1); }
cout < "What species are you interested in? ";
string wanted;
cin > wanted;
double maxspd=0.0, minspd=9999999999.9, totspd=0.0;
int count=0;
while (1)
{ string species;
int time, legs;
double speed;
fin > species > time > legs > speed;
if (fin.fail())
break;
if (species==wanted)
{ if (speed>maxspd)
maxspd=speed;
if (speed<minspd)
minspd=speed;
totspd+=speed;
count+=1; } }
fin.close();
if (count==0)
cout < "No observations of " < wanted < " were in the file\n";
else
{ double avgspd = totspd/count;
cout < "Minimum observed " < wanted < " speed = " < minspd < " mph\n";
cout < "Maximum observed " < wanted < " speed = " < maxspd < " mph\n";
cout < "Average observed " < wanted < " speed = " < avgspd < " mph\n"; } }
Using 9999999.9 to initialise minspd isn’t always reliable; a better alternative would be to say:
if (species==wanted)
{ if (speed>maxspd || count==0)
maxspd=speed;
if (speed<minspd || count==0)
minspd=speed;
2
For this question, you do not need to write a complete program. Just complete functions. Make your functions perform only the tasks indicated; they should not do anything extra.
(a)Write a function which takes two parameters called a and b, both integers, and works out the sum (i.e. add up) of all the integers between a and b inclusive. The function should return the sum as its result. e.g. sum(2,4) should return 9, because 2+3+4=9.
Keep it simple!
The only question that really concerned anyone (apart from occasionally forgetting how to declare functions) was what to do if b is less than a.
In a mathematical context, a range that is the wrong way around is always considered to be empty, so sum(2,5) is 2+3+4+5 which is 14, but sum(5,2) is zero.
But mathematicians can be surprisingly colloquial; computer professionals usually say what they mean. In the real world, you would probably ask the person who specified the problem exactly what they want, but realising that they could take days to answer, you’d make a rational decision for yourself, and put a comment in the program so you wouldn’t risk forgetting that there is an unresolved question. Under exam conditions, I’d expect you to make a reasonable assumption, state it, and just get on with it. If I had some special demand, I’d’ve said it.
int sum(int a, int b)
{ int min=a, max=b;
if (min>max)
{ min=b;
max=a; }
int answer=0;
for (int i=a; i<=b; i+=1)
answer+=i;
return answer; }
(b)Write a function which takes two parameters called a and b, both integers, and works out the product (i.e. multiply together) of all the integers between a and b inclusive. The function should return the product as its result. e.g. product(2,4) should return 24, because 234=24.
In an exam, I wouldn’t want you to waste time coping out the same thing over and over again. I would be perfectly happy to have you write:
“same as above; on line 1 replace ‘sum’ with ‘product’; on line 6 replace 0 with 1; on line 8 replace + with *”. Your time is worth something.
Other instructors’ attitudes may vary! Find out their policies to avoid disasters.
(c)Write a function which takes one parameter called m, an integer, and finds the smallest integer greater than m for which sum(1,m) and product(1,m) are the same. e.g. find(1) should return 3 because sum(1,3) and product(1,3) are both 6.
The only thing that requires any special attention here is the phrase “smallest integer greater than m”; you need a loop that increments the variable before using it.
int find(int m)
{ while (1)
{ m+=1;
if (sum(1,m)==product(1,m))
return m; } }
It’s a lot simpler than you might have expected. A ‘for’ loop wouldn’t be very good because there is no initialisation required, no test, and the update doesn’t happen at the end of the loop.
What about the 1,000,000 limit? That hasn’t come up yet. This question does not specify any maximum, so it would be wrong to put one in.
(d)Show how your answer to (c) could be used to print a list of all the numbers, n, between 1 and 1,000,000 inclusive, for which sum(1,n)=product(1,n).
The answer to (c) almost answers this already. Find does look for a number where sum(1,n) and product(1,n) are the same. You need to start with n=0 because it always finds the “next” number and the first one we want is 1.
int n=0;
while (n<1000000)
{ n=find(n);
cout < n < "\n"; }
But that isn’t quite ideal. This piece of program won’t deliberately look for any values over a million, but it isn’t completely in control. once n reaches 3, find(n) will run and run and run until it finds another sum=product number; how do we know that the number it finds will not exceed 1000000?
A slightly better answer would be this:
int n=0;
while (1)
{ n=find(n);
if (n>1000000)
break;
cout < n < "\n"; }
At least that answers the question as asked: it will not print any numbers over 1000000. But it isn’t very good. There are no solutions greater than 3. When find(3) is called, it will never terminate. The program does print all the solutions, but it never terminates cleanly. You have the choice of either saying just that, or saying that find() must be modified to include the search limit of one million. Annoying, but you have to be prepared for annoyances. The real world is full of them. Some are even worse than homeworks.
3
Draw a picture of a cat sitting on a table.
No Talent Required