The objective with this assignment will be to get you acclimated to C# programming and using Visual Studio. This
isn't meant to be a particularly difficult assignment, at least not the logic of it. If you disagree, I would
encourage you to meet with me. It will be a long program, so good luck putting it together the night before it's
due.
We're going to build a Console Application — ideally called "myGroupName_Assign1" — that will represent
an early stage, objectively useless command line interaction program for our Real Estate application. This will help
highlight the excessive convenience and ease-of-use that will come with developing Forms later.
"Hear me know or hear me never!
Glue your little eyes to the diagram." You will
lose all of your work
if you aren't careful with where you save your Visual Studios project (via citrix). When you are clicking through
and picking "Console Application: .NET Framework", you
need to change the default
location for your project (some "repos" folder on
C:) and click "Browse" and choose a
folder under
H: If you don't, your project will get saved onto a phantom drive, on an
imaginary computer, in Neverland, next to all of the hecks that I give. And you won't get it back. And I'm not
giving you an extension to compensate.
Also, back-up your work often. That's just a good practice to get into no matter what.
We will have several classes that need defining. ID values should range between 1 and 99999, with one exception.
The Person Class
Attributes:
- readonly uint id — a unique identifier for this Person.
- string lastName & string firstName — you... you know what these represent.
- string occupation — self-explantory
- readonly DateTime birthday — benefit of using self-documenting variable names, eh?
- List residenceIds — a dynamically resizing array of ID's representing places a person lives.
Each of these attributes should have a corresponding public Property, used to control read/write access for non-Person
objects.
- id — when attributes are listed as being unique, that means they cannot share an ID
value with any any other object in this system. Not other Person, Property, House, etc. Also no write-access.
- birthday — cannot be a date in the future.
- residenceIds — no write access. Read-access should return an array of uint's, which you can easily
create via the ToArray() method that is built into most Collections.
It goes without saying, but you should always use Properties when assigning values to the corresponding private
attributes — even from within class methods — as they have your R/W access and restrictions built in.
I'll also want you to build a get-only Property called
FullName, which is simply the
person's last name, a comma and space, followed by their first name.
You will need at least two constructors: a default constructor that takes no arguments and sets all values to 0 or
"" as appropriate; and an alternate constructor for when you want to provide initial values to
all
attributes (like when reading from the provided input file). It is strongly recommended that you simply pass an
array of strings as an argument, as we may modify the number of attributes for Person objects in the future.
I want the
Person class to implement the
IComparable and interface,
which means you must have the
public int CompareTo(object alpha) method defined. Sort by
FullName, in ascending order.
And finally, as with most every class you'll build in C#, you want to provide an
override to
the
ToString() method.
You may add as many other methods as you feel is necessary — what is described above is what you'll be graded on.
I added two additional methods as became necessary when achieving the objectives from the main menu options list, described
down below. You may notice this class isn't particularly exciting.
The ID exception mentioned above comes with the Person you will define. In the [
Persons]
input file, you'll find some instructions on what to do with the very first record, which has an ID value of 0. This
will be your Mayor, and the person used some of the actions to be taken through the main menu.
The Property Superclass
Attributes:
- readonly uint id — a unique identifier for this Property.
- uint ownerID — ID of the Person who owns this property.
- readonly uint x & readonly unit y — We're going to utilize these in later assignments.
- string streetAddr
- string city
- string state
- string zip
- bool forSale
We will
never instantiate a Property object.
You will need at least two constructors: a default constructor that takes no arguments and sets all values to 0 or
"" as appropriate; and an alternate constructor for when you want to provide initial values to
all
attributes (like when reading from the provided input file).
The
Property class will implement the
IComparable This requires
the
CompareTo method to be defined. This will easily be the most complex CompareTo implementation
in this project. You will sort Properties by their State first, followed by their City, followed by their Street Address.
However, I want their Street Addresses to be sorted by the street's name (e.g. Main St.), then sorted by their street
number (e.g. 645 Main St. comes before 1000 Main St.). This will utilize a great number of nested-if statements in
order to realize correctly.
The Residential Class — a Subclass of Property
Attributes:
- uint bedrooms
- uint baths
- uint sqft
We will
never instantiate a Residential object. It is also the most boring class we will build in
this assignment.
The House Class — a Subclass of Residential
Attributes:
- bool garage
- Nullable<bool> attachedGarage
- uint floors
The fourth class described in this handout and only the second one we will instantiate objects from!
The only distinction to point out here is that, for instances when a House object does not have a
garage (represented by a False value), I want the
attachedGarabge
attribute to be set to null.
The Apartment Class — a Subclass of Residential
Attribute: string unit
While the Apartment class has very little going for it, the wrench it throws into some of the objectives to be
achieved by the main menu make it more interesting than the Residential class.
The Community Class
Attributes:
- SortedSet<Property> props — a Collection of Property objects that are contained in this Community.
- SortedSet<Person> residents — for this assignment, everyone and everything lives within the DeKalb
Community. That will not continue being true in future assignments, though, so be mindful of this.
- readonly uint id — a unique identifier for this Community.
- readonly string name
- uint mayorID — ID of the Person designated as the Mayor
You'll need to define a get-only Property called
Population, which is simply the
Count on how many Person objects are stored within the
residents
Collection.
You will need at least two constructors: a default constructor that takes no arguments and sets all values to 0 or
"" as appropriate; and an alternate constructor for when you want to provide initial values to
all
attributes (like when reading from the provided input file). However, for Assignment 1, you can simply hard-code the
construction of a "DeKalb" Community object, with an ID value of 99999, and a mayorID value of 0.
The
Community class will implement both the
IComparable and
IEnumerable Interfaces. This requires the
CompareTo method to be
defined — sort by Name — as well as the
IEnumerator IEnumerable.GetEnumerator()
method, including a corresponding
CommEnum class. This will allow us to use the
foreach mechanic on objects from this class, to iterate through their corresponding
Person objects.
Special Notes
If you defy the class hierarchy described above and decide to just build two classes for House and Apartment
objects, containing copies of the attributes from the superclasses above them, you will lose
50% of the
points available for this assignment. Not just because I'm trying to require a successful utilization of
class inheritance (e.g. you're going to build House objects, by using the Residential class' constructor first, which
uses the Property class' constructor first), but also because the next two assignments will rely on this class
hierarchy as well. We are well past the days of trying to cut corners "because it's easier".
The Menu
Now that we have the classes well-defined, it's time to build the menu functionality. There should be ten (10)
options available.
- Full property list
- List addresses of either House or Apartment-type properties
- List addresses of all for-sale properties
- List all residents of a community
- List all residents of a property, by street address
- Toggle a property, by street address, as being for-sale or not.
- Buy a for-sale property, by street address
- Add yourself as an occupant to a property.
- Remove yourself as an occupant from a property
- Quit
An important feature that you need to be mindful of when developing the user-Menu interactions: every single
action the user takes needs to result in feedback. This feedback is important to notify the user that their
action has been carried out, to some conclusion — success or failure. Without it, you run the risk of
the user repeating an action or performing a different one, in order to finally confirm the success/failure
of the first.
Additionally, your "Quit" option needs to also be triggered by commands such as "q", "e", "quit", and "exit"
— as well as their uppercase counterparts — for increased user convenience. Generally speaking,
the more your software does to anticipate the user's needs, behavior, or actions, the better the UI/UX.
For Option 4, I am dictating that this be completed by using a
foreach loop on your
one Community object, iterating over each of the
Persons held within. You can
technically achieve this functionality in other ways, but if you do, you will lose 10 points.
For Option 7, you should also update the
forSale attribute to False, if the purchase
is successful.
For the other options, I'm recommending that you ahieve them via methods attached to the Community class, as
we will be introducing more classes and Community objects for processing in later assignments.
Input Files
Persons:
unique ID | lastName | firstName | occupation | birthYear | birthMonth | birthday | residenceID
Houses:
unique ID | ownerID | x | y | streetAddr | city | state | zip | forSale | bedrooms | baths | sqft | garage | attachedGarage | floors
Apartments:
unique ID | ownerID | x | y | streetAddr | city | state | zip | forSale | bedrooms | baths | sqft | unit
Sample Output
NOTE: The output shown here was generated two years ago, which is only relevant because the
age
you get for all the residents should be two years older than what is shown below.
The Menu
Option 1 NOTE: the expected output should extend past where this screenshot got cut off.
Option 2
Option 3
Option 4
Option 5
Option 6
Option 7
Option 8 (success)
Option 8 (failed)
Option 9 (success)
Option 9 (failed)
Option 9 (different fail)