ECS 40 Program #1 - CS-CSIF

ECS 40
Program #1 (50 points, my time 2.5 hours)
Spring 2015
Due: Wednesday, April15th at 11:59pm using handin to p1 directory of cs40a.
New concepts: None.
Name of executable: simulator.out
File names: Makefile, main.cpp, city.cpp, city.h, vector.cpp, vector.h, authors.txt.
authors.txt should be in the format:
First line: <e-mail of first partner> <space> <name of first partner, last name first then comma then first name>
Second line (if needed): <e-mail of second partner> <space> <name of second partner in above format>
For example:
[email protected] Potter, Harry
[email protected] Flintstone, Fred
For this assignment and the ones that follow, you will be developing an airline route simulator. If all goes well (and it
rarely does in programming), our final program will determine how many flights of which type of plane should go from
each city to every other city based on criteria the user specifies. I imagine the user could specify the capacity and costs of
operation of each type of plane, number of hubs, and maximum number of stops per passenger trip.
As the first step of constructing our simulator, we will need to organize and calculate some information about the cities
themselves. We need to know where cities are, how far apart they are, and how many passengers wish to fly between
each city pair. I have found two files that can help provide this information. airportLL.txt contains the longitude and
latitude for the airports in the United States. citypopulations.csv contains the populations of all the cities in the United
States with a population greater than 100,000. Your first program will read these two files, combine their data, and
calculate the distance between any two major cities. I will also provide a completely artificial formula that determines the
number of passengers wishing to fly between any two cities each day based on their populations and distance apart.
You may write this program in either C or C++, but the files must be named as indicated and rely on g++ for
compiling and linking. I recommend that you write it in C unless you already know C++. In Program #3, you will be
converting this program to C++, and add some new functionality. For this assignment must have two typedeffed structs
(or classes): 1) City will hold the information about a city; 2) Vector will hold a dynamically allocated array of City. You
will find my executable, and the two data files in ~ssdavis/40/p1. Note that you must be logged into the CSIF to access
that directory.
On Thursday, I will be adding an automatic grading shell script named testhw to that directory that will test for proper
style, design, and operation. At my discretion, I may add additional tests and change the two data files (while maintaining
their format) in the checker used for the actual grading. Warning: any program that attempts to fool the design or
operation checkers will receive a zero for the entire program, and the authors will be reported to Student Judicial Affairs
as an honor code violation.
Here are further specifications:
1. main.cpp
1.1. main.cpp will only contain main(), and run(). It should not need to #include city.h.
1.2. main() may only contain a declaration of a Vector named cities, function calls, and a return statement. No loops
are allowed. You should call separate functions to initialize the vector, read the city populations, read the airport
information, remove the cities without airports, interact with the user (which is run()), and deallocate the vector.
1.3. You may assume that the user will never enter an entry longer than 79 characters.
2. city.cpp and city.h
2.1. Your typedeffed struct (or class) should be named City
2.1.1. It will contain a city's longitude, latitude, name, state, airport abbreviation, and population.
2.1.2. The name, and state should be dynamically allocated based on those read from the file.
2.1.3. Airport abbreviations always have three letters.
2.2. All implementation code that involves setting or accessing individual values of City structs must be in city.cpp.
2.3. You should use the following formula to determine the distance between cities based on longitude and latitude.
π‘‘π‘–π‘ π‘‘π‘Žπ‘›π‘π‘’ = cosβˆ’1 (sin πœ‘1 βˆ™ sin πœ‘2 + cos πœ‘1 βˆ™ cos πœ‘2 βˆ™ cos(𝛾1 βˆ’ 𝛾2 )) βˆ™ 𝑅,
π‘€β„Žπ‘’π‘Ÿπ‘’ πœ‘ = π‘™π‘Žπ‘‘π‘–π‘‘π‘’π‘‘π‘’ 𝑖𝑛 π‘Ÿπ‘Žπ‘‘π‘–π‘Žπ‘›π‘ , 𝛾 = π‘™π‘œπ‘›π‘”π‘–π‘‘π‘’π‘‘π‘’ 𝑖𝑛 π‘Ÿπ‘Žπ‘‘π‘–π‘Žπ‘›π‘ , π‘Žπ‘›π‘‘ 𝑅 = 3963. Be sure to use M_PI / 180 to
convert to radians.
3. vector.cpp and vector.h
3.1. The Vector struct (or class) will contain a pointer to City named cityArray, the current size of the array, and the
current count of the number of Citys stored in the array. Note that size is always greater than or equal to count.
3.2. The array must be initially allocated to size 10, and then doubled in size whenever necessary to accommodate a
new City, i.e., 10, 20, 40, 80 …
3.3. All implementation code involving changing or accessing the Vector struct, must be in vector.cpp.
3.3.1. Note that the Vector WILL be declared in main(), and passed to run() as well as the functions in vector.cpp.
3.4. You should have two separate functions to read the two files. You may assume both files will be in the current
directory.
3.5. Only cities that have known populations and an airport should be included in the Vector passed to run().
3.5.1. Your program should remove inappropriate cities from the array after processing both files. To be safe,
you should set one of the variables in each City to an inappropriate sentinel value when each City is first
created.
4. General programming standards beyond those provided on the Programming Standards handout.
4.1. All structs should always be passed as pointers.
4.2. All functions must be implemented in .cpp files.
4.3. Use const wherever possible in function parameters.
4.4. Enclose all of your header file code in #ifndef .. #endif preprocessor blocks.
4.5. Your Makefile must use g++ with –ansi, -Wall, and –g on all compiling and linking lines.
4.6. All dynamically allocated memory must be freed before reaching the return statement in main().
4.7. You may not use /* */ commenting anywhere.
5. Output
5.1. The values and format of your output must match mine exactly.
5.2. The formula to determine the number passengers from city1 to city2 each day is (pop1 * pop2) / 250,000,000.
5.2.1. If the two cities are less than 100 miles apart, then no passengers wish to fly between them.
5.3. You should use doubles throughout your calculations to avoid rounding errors.
6. Suggestions:
6.1. To read an entire line all at once use fgets(). To parse the line, you may wish to use the strtok() function.
6.2. Develop your code using stubs, and in a top down fashion. A stub is a function that has no code in its body,
except possibly a return statement. A stub should be able to compile without any warnings. When you do
provide code for a stub, you may need to write new stubs for functions it calls. After writing the code for a stub,
your program should be able to compile without warnings and run!
6.3. Here is a suggested order for development with additional specifications in bold:
6.3.1. Write the typedef structs for Vector and City in their respective header files.
6.3.2. Write main(), and the stubs for all the functions it calls.
6.3.2.1. A good way to ensure proper linking is to copy each function call line from main() and paste it into
the appropriate header file, fill in the data type(s) in the header file function prototype, then copy the
header file prototype and paste it into the .cpp file, and finally add the { } with function comment to
the .cpp function.
6.3.2.2. From here on, your code should compile without warnings after each step, and run all the way to
completion in main().
6.3.3. Write and then test the initialize() function for vector.cpp.
6.3.3.1. You will need a separate initialize() function in city.cpp that takes a City pointer to set default values
for each City, e.g., name = NULL (NULL is defined in stdio.h and iostream).
6.3.4. Write, and then test the two functions in vector.cpp to read citypopulations.csv and to resize the array.
6.3.4.1. In resize(), remember to call initialize() for the upper half of the new cityArray.
6.3.4.2. Remember, all access to the City information must be take place in city.cpp, so you will need to call a
function that is implemented in city.cpp to actually read each line of the file.
6.3.5. Write, and then test the function in city.cpp to actually read the information in a City.
6.3.5.1. Note that I actually passed the FILE* to this function.
6.3.5.2. I suggest that you write a temporary for-loop in main() to ensure that the cityArray is filled correctly.
6.3.6. Write, and then test the function, readAirports(), to read airportsLL.txt in vector.cpp.
6.3.6.1. Note that I couldn't pass the FILE * to a specific City of the array because I have to read the line
before knowing which city in the Vector was involved. After determining if a line is an airport line,
use a local City variable and call a new City function, readAirport() that will take the line, and parse
it. Next call a City function, isEqual(), that compares the city names of two Cities and returns a bool.
Next call copyLocation() to copy the data from the local variable to the appropriate City in the array.
6.3.6.2. To avoid a memory leak, you will have to call the City deallocate() function.
6.3.6.2.1. Make sure you call the City initialize function right after you create the local City variable.
6.3.7. Write, and then test readAirport(), isEqual(), copyLocation(), and deallocate().
6.3.7.1. As before, I suggest that you write a temporary for-loop in main() to ensure that the cityArray is filled
correctly.
6.3.8. Write, and then test the function cleanCities() to remove the cities without airports from the array. Note
that you need not preserve the order of the cities.
6.3.8.1. You will need to add a City function, hasAirport(), to determine if a city has an airport.
6.3.8.2. Make sure you don’t have any memory leaks!
6.3.8.3. Again use your temporary for-loop in main() to ensure that this function is working properly.
6.3.9. Write, and test the run function.
6.3.10. Write, and test the findAirport() function of Vector.
6.3.10.1. Write a setAirport() function of City that will set the airport of a local City variable of
findAirport().
6.3.10.2. Modify City isEqual() so that it will return true if either the names or airports of the two Cities are
the same.
6.3.11. Write, and test the calcDistance() functions of Vector and City.
6.3.11.1. Note that calcDistance() of Vector needs only one line since all of the work should be done by the
calcDistance() of City.
6.3.11.2. To calculate the number of passengers, you may need to cast one of the variables.
6.3.12. Write, and test the Vector deallocate() function that frees the City and Vector dynamically allocated
memory. Your done!
[[email protected] p1]$ simulator.out
Please enter two airport abbreviations (XXX XXX = done): SFO NYC
25319 passengers fly the 2570 miles from
San Francisco, California to New York City, New York.
Please enter two airport abbreviations (XXX XXX = done): LAX DEN
9023 passengers fly the 848 miles from
Los Angeles, California to Denver, Colorado.
Please enter two airport abbreviations (XXX XXX = done): SFO SMF
0 passengers fly the 85 miles from
San Francisco, California to Sacramento, California.
Please enter two airport abbreviations (XXX XXX = done): SMF CHI
5222 passengers fly the 1792 miles from
Sacramento, California to Chicago, Illinois.
Please enter two airport abbreviations (XXX XXX = done): ECS 40
ECS is not a valid airport
40 is not a valid airport
Please enter two airport abbreviations (XXX XXX = done): HNL YYY
YYY is not a valid airport
Please enter two airport abbreviations (XXX XXX = done): ZZZ MIA
ZZZ is not a valid airport
Please enter two airport abbreviations (XXX XXX = done): Whoops Hi
Whoops is not a valid airport.
Hi is not a valid airport.
Please enter two airport abbreviations (XXX XXX = done): XXX XXX
[[email protected] p1]$