Assignment 1: Getting Started

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:

  1. readonly uint id — a unique identifier for this Person.
  2. string lastName & string firstName — you... you know what these represent.
  3. string occupation — self-explantory
  4. readonly DateTime birthday — benefit of using self-documenting variable names, eh?
  5. 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.

  1. 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.
  2. birthday — cannot be a date in the future.
  3. 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:

  1. readonly uint id — a unique identifier for this Property.
  2. uint ownerID — ID of the Person who owns this property.
  3. readonly uint x & readonly unit y — We're going to utilize these in later assignments.
  4. string streetAddr
  5. string city
  6. string state
  7. string zip
  8. 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:

  1. uint bedrooms
  2. uint baths
  3. 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:

  1. bool garage
  2. Nullable<bool> attachedGarage
  3. 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:

  1. SortedSet<Property> props — a Collection of Property objects that are contained in this Community.
  2. 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.
  3. readonly uint id — a unique identifier for this Community.
  4. readonly string name
  5. 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.

  1. Full property list
  2. List addresses of either House or Apartment-type properties
  3. List addresses of all for-sale properties
  4. List all residents of a community
  5. List all residents of a property, by street address
  6. Toggle a property, by street address, as being for-sale or not.
  7. Buy a for-sale property, by street address
  8. Add yourself as an occupant to a property.
  9. Remove yourself as an occupant from a property
  10. 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)