boardix


Post New Topic  New Poll  Post A Reply
my profile | directory login | | search | faq | forum home
  next oldest topic   next newest topic
» boardix   » Groups   » Codecrave   » Homework

 - UBBFriend: Email this page to someone!    
Author Topic: Homework
Yoda
Member
Member # 27

 - posted      Profile for Yoda     Send New Private Message       Edit/Delete Post   Reply With Quote 
Well, I figured enough of us were in some sort of programming class that I might as well post my homework here. Who knows, maybe our teachers all get their assignments from the same devil book. Maybe we can learn from each other or something, yeah... If I am completely out of line posting this here let me know and I wont do it again, the problem is followed with my solution.

CSCI 241 Assignment 1
100 points
Purpose
This assignment is an exercise in C++ I/O, the use of Makefiles, a review of command line arguments. It is also an exercise in becoming accustomed to the programming environment used for this course.
Assignment
Write a program which will reads two files of data containing some records. One file will contain information about the townships in DeKalb, Kane, Lee, and Ogle counties. The other will contain some lines describing the boundaries of the townships in those counties. The program should use the lines to calculate the area of each township and print a report based on the result.
The data for this assignment comes from the TigerLine database used by the U.S. Census Bureau in its work. The data is a collection of lines, with latitude and longitude given for the endpoints of each line. In addition, each line has two codes associated with it which identify the townships to the left and right of the line.

Each line constitutes a small piece of a boundary between two townships. Each line is used with a point called a base point to create a small triangle. The areas of the small triangles are all added together to compute the area of the township. In theory, the base point can be arbitrary, usually the coordinate system origin. In practice however, a point must be chosen that is relatively close to the set of lines or numerical error occurs. This affects the steps needed to process each line and will be discussed in more detail below.

Program
You will need to write several functions and create three new data types for this assignment. These new types should be structures and should contain the fields described below exactly in the order given, using the exact types. This can not be emphasized enough. The data has been saved in binary form from the structures and if your structures do not match the ones used to save the data, you will read in garbage.
struct Region
This structure holds information about townships that will be read from a data file. The structure contains
an integer code, uniquely assigned to the township.
a string of 60 characters, giving the name of the township.
a string of 20 characters, giving the name of the state containing the township.
a string of 20 characters, giving the name of the county containing the township.
All of the strings in this struct are C style strings, i.e., arrays of characters ending with a null terminating character.
struct RegionInfo
This structure holds additional information about a township that will be computed as part of the program:
a double for holding the area of the township.
a boolean flag, which will be true when the structure is initialized.
two integers, which hold the x and y coordinates of a point associated with the township.
struct Line
The fields of this structure are
two integers giving the x and y coordinates of the starting endpoint of the line.
two integers giving the x and y coordinates of the ending endpoint of the line.
two integers giving the identification codes for the townships to the left and right of the line, respectively.
read_regions()
This function takes as arguments an array of Regions and a C style string giving the name of a data file containing binary township data. The function returns an integer which will be the number of records successfully read from the file.
This function should open the file with the given name and read the binary records out of the file into the array. Records are read until the end of the file is reached. If the file can not be opened, the function should return a negative error value, which should be a symbolic constant. Otherwise, the function should return the number of records read.

find_region_index()
This function takes three arguments: an array of Regions, an integer giving the number of elements used in the array, and an integer that is a township identification code. The routine should search for the identification code in the regions in the array. When a match is found, the index position in the array of the match should be returned. If the code is not found in the array, a negative error value should be returned.
compute_area()
This is the core routine of the program. It takes three arguments, a Line and two integers giving the x and y values of a point called the base point. This function calculates and returns the area of a triangle formed by the Line and the base point. Understanding the math of what happens here is non-trivial and not important for this course, so the code is given here.
double compute_area(Line border, int base_x, int base_y)
{
double x1, y1, x2, y2;
double scale;
double area;

// Calculate coordinates in kilometers on earth's surface
x1 = (border.x1 - base_x) / 1.0e+06 * EARTH_RADIUS * M_PI / 180.0;
y1 = (border.y1 - base_y) / 1.0e+06 * EARTH_RADIUS * M_PI / 180.0;

x2 = (border.x2 - base_x) / 1.0e+06 * EARTH_RADIUS * M_PI / 180.0;
y2 = (border.y2 - base_y) / 1.0e+06 * EARTH_RADIUS * M_PI / 180.0;

// Rescale longitude
scale = cos(border.y1 / 1.0e+06 * M_PI / 180.0);

x1 *= scale;
x2 *= scale;

area = 0.5 * (x1 * y2 - x2 * y1);

return area;
}

Change the field names as needed to match the field names in your Line struct. You should define the symbolic constant EARTH_RADIUS and give it the value of 6378.137 kilometers. The symbolic constant M_PI is the value of pi and is already defined for you in the standard math header files.
print_areas()
This function takes as arguments an array of Regions, an array of RegionInfos, and an integer specifying the number of elements in each array (which is the same). The arrays should be printed out in their existing order, printing the township name and accumulated area for each township. To make things more interesting, whenever there is a change of county, a few extra lines of header information should be printed. See the example output below for details.
main()
Your program should take two command line arguments, the names of a file containing the line data and another containing the township data. If the wrong number of command line arguments are given, a brief reminder should be printed on how to use the program and the program should exit.
The program should have two array, one of Regions for holding the township file data, and a corresponding array of RegionInfos. The size of the arrays should be set by a symbolic constant with a value of at least 100.

The regions should be read by calling read_regions, storing the return value for the number of regions read. This value should be tested for errors (negative) and the program should exit if an error has occurred. The array of the RegionInfo values should be initialized to have zero area. The initialization flag should be set to false. The remainder of the structure can not be initialized until the line data is read from the other file.

The program should open the data file for the lines, exiting if there is an error. Lines should be read from the file and processed until there are no more lines in the file.

Each line must be processed twice, once for the left hand township and once for the right hand township. If the township code is 0 for a particular side, then no more processing is done for that side. A non-zero township code is used to look up an array position for that code by calling find_region_index(). All computation for a particular township will be stored in the arrays in the position given by this function.

After finding the position in the arrays, the township must be checked to see if a base point has been initialized for it. This is done by checking the boolean flag associated with the township. If no initialization has been done, the starting point of the line is copied as the base point and the flag is set to true. The RegionInfo struct is now fully initialized.

Now the line and the township base point are used to calculate a triangle area by calling compute_area(). This triangle area is added to the township area on the left hand side of the line. When processing the right hand side township this area must be subtracted from the total township area. (This is because the direction the line is traversed in the area formula is important, resulting in negative areas for base points on the right hand side. A bit bizarre, but it works.)

After all the lines are processed, (both left and right sides), the data file is closed and the results are printed using print_areas().

Input
This program requires no input other than the command line arguments.
Two data files for this assignment can be copied from ux/mp as

/home/ux/duffin/courses/cs241/data/lines.dat
/home/ux/duffin/courses/cs241/data/township.dat
Output
The output of this program when using the data files given with the assignment is shown below. The exact values shown may differ slightly with the ones computed by your program but should be quite close.
DeKalb County:
Township Area (sq. km)
------------------------------------------------
Afton 91.2830
Clinton 91.4031
Cortland 91.4559
DeKalb 91.6388
Franklin 93.8630
Genoa 93.7420
Kingston 93.4228
Malta 90.7073
Mayfield 91.2270
Milan 91.3254
PawPaw 98.1201
Pierce 90.9716
Sandwich 39.9113
Shabbona 91.2391
Somonauk 50.3541
South Grove 89.4299
Squaw Grove 90.9612
Sycamore 89.3426
Victor 85.3872

Kane County:
Township Area (sq. km)
------------------------------------------------
Aurora 91.5591
Batavia 48.3412
Big Rock 91.2139
Blackberry 90.7336
Burlington 87.6728
Campton 89.7632
Dundee 93.2146
Elgin 84.5954
Geneva 42.4514
Hampshire 93.1066
Kaneville 91.0264
Plato 86.7544
Rutland 94.1634
St. Charles 91.6251
Sugar Grove 91.2294
Virgil 90.8384

Lee County:
Township Area (sq. km)
------------------------------------------------
Alto 90.2941
Amboy 91.8580
Ashton 46.2458
Bradford 93.2926
Brooklyn 94.2480
China 69.6020
Dixon 77.0587
East Grove 92.3955
Hamilton 92.7907
Harmon 92.8832
Lee Center 94.7102
Marion 92.5404
May 92.7239
Nachusa 74.9421
Nelson 63.2152
Palmyra 90.4591
Reynolds 92.1762
South Dixon 76.8585
Sublette 94.6363
Viola 91.7794
Willow Creek 90.9573
Wyoming 93.3925

Ogle County:
Township Area (sq. km)
------------------------------------------------
Brookville 46.6472
Buffalo 87.4854
Byron 97.4157
Dement 90.5208
Eagle Point 50.7144
Flagg 92.4485
Forreston 94.0291
Grand Detour 31.3824
Lafayette 45.2771
Leaf River 92.5274
Lincoln 93.3142
Lynnville 90.4978
Marion 116.3765
Maryland 93.9371
Monroe 93.7851
Mount Morris 93.8597
Oregon-Nashua 102.7850
Pine Creek 102.9524
Pine Rock 99.0393
Rockvale 92.9741
Scott 93.0622
Taylor 40.4821
White Rock 92.3003
Woosung 45.9398
Other Points
The C++ string class is allowed but not needed for this assignment.

You must have a complete Makefile, with a separate rule for compiling the object file and linking the executable file.

The name of your source code file should be assign1.cc.

The name of your executable should be assign1.

Function prototypes are required for all functions.

Don't forget to get rid of all compiler warnings when the -Wall compilation option is used.

As always, programs that do not compile on mp automatically receive 0 points.

Submit your program using the electronic submission guidelines posted on the course web site and discussed in class.

Implementation Hints
Focus first on getting the data in from the files correctly. If you can't get good data in, you can't process it.
For the township data file listed above there are 81 records. The first two records have the following values:

State Name: Illinois
County Name: DeKalb
ID code: 386
Township Name: Afton

State Name: Illinois
County Name: DeKalb
ID code: 14988
Township Name: Clinton
For the line data file listed above there are 4119 records. The first two records have the following values:

left/right ID codes: 386 / 14988
starting coordinates(-88828357, 41804930)
ending coordinates(-88828143, 41804929)

left/right ID codes: 386 / 14988
starting coordinates(-88822335, 41804952)
ending coordinates(-88808812, 41805148)

-------------------------------------------------

code:
#include <iostream.h>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <fstream.h>
#include <iomanip.h>

struct Region
{
int towncode;
char townname[60];
char state[20];
char county[20];
};

struct RegionInfo
{
double area;
bool init;
int x, y;
};

struct Line
{
int startx, starty, endx, endy, townleft, townright;
};

// Reads in all the regions from a file to a structure
int read_regions(Region townships[],char* filenames[])
{
const int error(-1);
int valread(0);

// Open the binary township data file
ifstream towninfo;
towninfo.open(filenames[1], ios::in|ios::binary);
if (!towninfo)
{
cerr<<"Error opening file"<<endl;
return error;
}

// Read the regions into the array
while (towninfo)
{
towninfo.read((char*)&townships[valread],sizeof(Region));
valread++;
}

// Close the township data file
towninfo.close();
if (!towninfo.fail())
{
cerr<<"Error closing file"<<endl;
return error;
}

return valread;
}

// Takes an integer and finds the coresponding towncode
int find_region_index(Region townships[], int datanum, int code)
{
int curpas;

for (curpas = 0; curpas < (datanum - 1); curpas++)
if (code == townships[curpas].towncode)
return curpas;

return (-1);
}

/* Calculates and returns the area of a triangle formed by the Line and
the base point */
double compute_area(Line border, int base_x, int base_y)
{
const double EARTH_RADIUS = 6378.137;
double x1, y1, x2, y2;
double scale;
double area;

// Calculate coordinates in kilometers on earth's surface
x1 = (border.startx - base_x) / 1.0e+06 * EARTH_RADIUS * M_PI / 180.0;
y1 = (border.starty - base_y) / 1.0e+06 * EARTH_RADIUS * M_PI / 180.0;

x2 = (border.endx - base_x) / 1.0e+06 * EARTH_RADIUS * M_PI / 180.0;
y2 = (border.endy - base_y) / 1.0e+06 * EARTH_RADIUS * M_PI / 180.0;

// Rescale longitude
scale = cos(border.starty / 1.0e+06 * M_PI / 180.0);

x1 *= scale;
x2 *= scale;

area = 0.5 * (x1 * y2 - x2 * y1);

return area;

}

// Prints township name and accumulated area for each township
int print_area(Region townships[], RegionInfo towninfo[],int datanum)
{
int curpos(0);
while (curpos < (datanum-1))
{
if (curpos == 0 ||
strcmp(townships[curpos].county,townships[(curpos-1)].county))
{
cout<<endl<<townships[curpos].county<<" County:"<<endl;
cout<<setw(22)<<left<<"Township"<<"Area (sq. km)"<<endl;
cout<<"----------------------------------------"<<endl;
}

cout<<setw(25)<<left<<townships[curpos].townname<<towninfo[curpos].area<<endl;
curpos++;
}
return 0;
}

int main(int argnum, char* filenames[])
{
// Check the number of input files
if (argnum != 3)
{
cerr<<"Incorrect amount of parameteres"<<endl;
exit(101);
}


// Array declarations
const int arrayval = 100;
Region townships[arrayval];
RegionInfo towninfo[arrayval];

// Variable declarations
int datanum, printok, townct, lcode, rcode;
double area;

// towninfo declaration
for (townct=0;townct<arrayval;townct++)
{
towninfo[townct].area = 0;
towninfo[townct].init = 0;
}

// Read township data
datanum = read_regions(townships,filenames);
if (datanum <= 0)
{
cerr<<"File Error"<<endl;
exit(101);
}

// Open line data
Line border;
ifstream linedata;
linedata.open(filenames[2], ios::in|ios::binary);
if (!linedata)
{
cerr<<"Error opening file"<<endl;
exit (101);
}

// Process line data

while (linedata)
{
linedata.read((char*)&border, sizeof(Line));

// Left side
if (border.townleft != 0)
{
lcode = find_region_index(townships, datanum, border.townleft);
if (!towninfo[lcode].init)
{
towninfo[lcode].init = 1;
towninfo[lcode].x = border.startx;
towninfo[lcode].y = border.starty;
}
area = compute_area(border, towninfo[lcode].x, towninfo[lcode].y);
towninfo[lcode].area += area;
}

// Right side
if (border.townright != 0)
{
rcode = find_region_index(townships, datanum, border.townright);
if (!towninfo[rcode].init)
{
towninfo[rcode].init = 1;
towninfo[rcode].x = border.startx;
towninfo[rcode].y = border.starty;
}
area = compute_area(border, towninfo[rcode].x, towninfo[rcode].y);
towninfo[rcode].area -= area;
}
}

// Close line data
linedata.close();
if (!linedata.fail())
{
cerr<<"Error closing file"<<endl;
exit (101);
}

// Print the township names and area
printok = print_area(townships,towninfo,datanum);
if (printok != 0)
{
cerr<<"Error printing file"<<endl;
exit(202);
}

}



--------------------
May the Force be with you and may your enemies blade chip and shatter.

Posts: 121 | From: Villahurst, IL | Registered: Apr 2002  |  IP: Logged
bigO
He Who Knows All
Member # 7

 - posted      Profile for bigO     Send New Private Message       Edit/Delete Post   Reply With Quote 
Well, i don't really have time to finish looking at that now, but as for file I/O, i don't know so much. My c++ class isn't really a c++ class, it's a data structure class that uses c++. and we skipped structures, cause classes are better (and because its being taught as if you know Java, since the prereq is a Java class) So we only do classes. Right now we are doing templated classes, for generic proggramming.

As for c++ standards that I like, neither of our teachers seems to live up to that. My teacher uses the Java standard for writing functions, yours uses crazy. I believe functions should be capatilized, variables should be like thisIsVar, and constants should be BLAH_BLAH

--------------------
Anybody can be cool, but AWESOME takes practice.

Posts: 4521 | From: VP luv | Registered: Apr 2002  |  IP: Logged
Fahad
Moderator
Member # 16

 - posted      Profile for Fahad     Send New Private Message       Edit/Delete Post   Reply With Quote 
ok first of all..... too big.... I dont think anyone has that kind of time.... secondly... IT'S YOUR HOMEWORK......... you should know how to do it.... and if we help you, it wouldn't be fair to others in your class now would it??

--------------------
Who said anything about going away?

Posts: 798 | From: Lombard, Illinois, USA | Registered: Apr 2002  |  IP: Logged
Mystery Man
vote YES to the Heroes bill
Member # 1

 - posted      Profile for Mystery Man     Send New Private Message       Edit/Delete Post   Reply With Quote 
fahad I don't think he is asking for help, he is merely offering up his homework to enrich our programming minds.

--------------------
 -

Posts: 2726 | From: VP | Registered: Apr 2002  |  IP: Logged
Yoda
Member
Member # 27

 - posted      Profile for Yoda     Send New Private Message       Edit/Delete Post   Reply With Quote 
The code is good, works perfectly, so Kordik is right, but I do think people should post things they need help with, just not as stupid as mine. As for the structs. etc. This program was incredibly easy as anyone can tell, the only thing I had problems with is the file io junk, cuz smith didn't talk at all about it and the binary files made it a total *****, what you have to do is copy the amount of bytes of the file equal to the size of the array of the struct regions into the struct as a whole, which took me a while to figure out.

--------------------
May the Force be with you and may your enemies blade chip and shatter.

Posts: 121 | From: Villahurst, IL | Registered: Apr 2002  |  IP: Logged
SkyRat
Resident Director of Personal
Member # 10

 - posted      Profile for SkyRat     Send New Private Message       Edit/Delete Post   Reply With Quote 
ios::binary

binary = easy as pie! =P

--------------------
 -  -
quote:
With the stupid limit on sigs my googlism won't fit!!


Posts: 2518 | From: BFH | Registered: Apr 2002  |  IP: Logged
SkyRat
Resident Director of Personal
Member # 10

 - posted      Profile for SkyRat     Send New Private Message       Edit/Delete Post   Reply With Quote 
Oh, btw, anyone care to help me clean up CCC Linux ver source code? I'll only give ya the client.cpp file, only 400+ lines of code =P j/k but seriously now, I don't think hw help should be posted here, uofi has some newsgroups for cs students to help each other and I would think that other schools do too. I think it is more proper to post independent programs/coding/any thing program related that you are working on by yourself here. This is codecrave, we work on projects (some of us, actually only a few) that are far cooler than any school project. Anyone wanna get cracking on Boardix jukebox?

--------------------
 -  -
quote:
With the stupid limit on sigs my googlism won't fit!!


Posts: 2518 | From: BFH | Registered: Apr 2002  |  IP: Logged
What Huh Studios
Member
Member # 100

 - posted      Profile for What Huh Studios     Send New Private Message       Edit/Delete Post   Reply With Quote 
OLD thread... but hey, let me know what features are important and I will start up the boardix jukebox... i think i'm a little over my head on the CCC since i only know about 40% of what it really is....

--------------------
http://www.whathuhstudios.com

Posts: 1687 | From: Villa park | Registered: Feb 2003  |  IP: Logged


 
Post New Topic  New Poll  Post A Reply Close Topic   Feature Topic   Move Topic   Delete Topic next oldest topic   next newest topic
 - Printer-friendly view of this topic
Hop To:

kordix.com

(C)2000-2011 The Boardix Community

Powered by Infopop Corporation
UBB.classicTM 6.5.0