Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

C#

Kyle Jensen
PLUS
Kyle Jensen
Courses Plus Student 6,293 Points

C# project code review - console address book

I am hoping to get a review of my code for the address book project suggested at the end of the C# objects course. Two things I know it can't do that I've only thought of in the last few minutes is take a partial name and search for possible matches and to trim any excess spaces put in by a user at the beginning or end of their entry. Other than that I think this is complete. I've also considered adding a phone number section.

It can: -Add a name and address -remove them -update them -quit at anytime -view the list (currently only set to 2 entries)

using System;

namespace AddressBook {
    class Program {
        static void Main(string[] args) {

            AddressBook addressBook = new AddressBook();

            PromptUser();

            void Menu() {
                Console.WriteLine("TYPE:");
                Console.WriteLine("'Add' to add a contact: ");
                Console.WriteLine("'View' to view the list of contacts: ");
                Console.WriteLine("'Remove' to select and remove a contact: ");
                Console.WriteLine("'Update' to select and update a contact: ");
                Console.WriteLine("'Quit' at anytime to exit: ");
            }

            void UpdateAddressBook(string userInput) {
                string name = "";
                string address = "";
                switch ( userInput.ToLower() ) {
                    case "add":
                        Console.Write("Enter a name: ");
                        name = Console.ReadLine();
                        switch(name) {
                            case "quit":
                                break;
                            default:
                                Console.Write("Enter an address: ");
                                address = Console.ReadLine();
                                switch (address) {
                                    case "quit":
                                        break;
                                    default:
                                        addressBook.AddEntry(name, address);
                                        break;
                                }
                                break;
                        }
                        break;
                    case "remove":
                        Console.Write("Enter a name to remove: ");
                        name = Console.ReadLine();
                        switch (name) {
                            case "quit":
                                break;
                            default:
                                addressBook.RemoveEntry(name);
                                break;
                        }
                        break;
                    case "view":
                        Console.WriteLine(addressBook.ViewContactsList());
                        break;
                    case "update":
                        Console.WriteLine("Please enter the name of the Contact you wish to update");
                        name = Console.ReadLine();
                        addressBook.UpdateContact(name);
                        break;
                }
            }

            void PromptUser() {
                Menu();
                string userInput = "";
                while (userInput != "quit") {
                    Console.WriteLine("What would you like to do?");
                    userInput = Console.ReadLine();
                    UpdateAddressBook(userInput);
                }
            }
        }
    }
}
//--------------------------------------------------------------------------------

using System;

namespace AddressBook {
    class AddressBook {

        public readonly Contact[] contacts;

        public AddressBook() {
            contacts = new Contact[2]; ;
        }

        public bool AddEntry(string name, string address) {
            if (!ContainsEntry(name)) {
                Contact AddContact = new Contact(name, address);
                for (int i = 0; i < contacts.Length; i++) {
                    if (contacts[i] == null) {
                        contacts[i] = AddContact;
                        Console.WriteLine("Address Book updated. {0} has been added!", name);
                        return true;
                    }
                }
                Console.WriteLine($"Cannot add ({name}) to Address Book since it is full!");
                return false;
            }
            else {
                Console.WriteLine($"({name}) already exists in Address Book!");
                UpdateContact(name);
            }
            return false;
        }

        public bool UpdateContact(string originalName) {
            Console.Write("Are you sure you would you like to update the Contact? -- Type 'Y' or 'N': ");
            string userResponse = Console.ReadLine().ToLower();
            if (userResponse == "y") {
                Console.Write($"Would you like to update {originalName}'s name or address? TYPE - 'Name' for name and 'Address' for address: ");
                string entryToUpdate = Console.ReadLine().ToLower();

                Console.Write($"Please enter changes to the {entryToUpdate} here: ");//, (entryToUpdate == "address") ? "address" : "name"
                string userUpdatedEntry = Console.ReadLine();

                int index = GetEntryIndex(originalName);
                if (entryToUpdate == "name") {
                    contacts[index].Name = userUpdatedEntry;
                    Console.WriteLine($"Contact {originalName} updated to {userUpdatedEntry}");
                    return true;
                }
                if (entryToUpdate == "address") {
                    contacts[index].Address = userUpdatedEntry;
                    Console.WriteLine($"Contact {originalName}'s {entryToUpdate} updated to {userUpdatedEntry}");
                    return true;
                }
            }
            return false;
        }

        private int GetEntryIndex(string name) {
            for (int i = 0; i < contacts.Length; i++) {
                if (contacts[i] != null && contacts[i].Name == name)
                    return i;
            }
            return -1;
        }

        private bool ContainsEntry(string name) {
            return GetEntryIndex(name) != -1;
        }

        public void RemoveEntry(string name) {
            var index = GetEntryIndex(name);
            if (index != -1) {
                contacts[index] = null;
                Console.WriteLine("{0} removed from contacts", name);
            }
        }

        public string ViewContactsList() {
            string contactList = "";
            foreach (Contact contact in contacts) {
                if (contact == null) {
                    continue;
                }
                contactList += String.Format("Name: {0} -- Address: {1}" + Environment.NewLine, contact.Name, contact.Address);
            }
            return (contactList != String.Empty) ? contactList : "Your Address Book is empty.";
        }
    }
}

//------------------------------------------------------------------------------------

namespace AddressBook {
    class Contact {
        public string Name { get; set; }
        public string Address { get; set; }

        public Contact(string name, string address) {
            Name = name;
            Address = address;
        }
    }
}

1 Answer

Jon Wood
Jon Wood
9,884 Points

Looks good from a quick look at it! Just a couple of nit picks:

  • Instead of initializing a variable with "", you can use String.Empty. Not a big deal, but some code analysis will yell at you about it.
  • For the switch(name), I wonder if it would be easier to read as just an if/else block since you're just testing for quit and have a default.
  • Have you gotten into the List data structure yet? I think it could be refactored to utilize that.
Jon Wood
Jon Wood
9,884 Points

Also, if you didn't know yet, there is a Code Review StackExchange site that may give you more responses :)

Kyle Jensen
Kyle Jensen
Courses Plus Student 6,293 Points

Jon Wood I didn't realize you could initialize with String.Empty. I knew you could use it in other ways - like I've got it in the ternary condition in ViewContactList(). Definitely a habit from javascript. So, thank you!

I think you're right about the switch(name). I wrote it and it takes me a minute to see what's going on. I think a good place for a switch(), though, is in UpdateContact(). Instead of the if/else it makes it more readable, to me, to be a switch() so I changed that and some of the variable names to something that felt a little more readable. Also, it now uses the FormatContact() method I added. See following code:

 public bool UpdateContact(string originalName) {
            Console.Write("Are you sure you would you like to update the Contact? -- Type 'Y' or 'N': ");
            string userResponse = Console.ReadLine().ToLower();
            if (userResponse == "y") {
                Console.Write($"Would you like to update {originalName}'s name or address? TYPE - 'Name' for name and 'Address' for address: ");
                string contactToUpdate = Console.ReadLine().ToLower();

                Console.Write($"Please enter changes to the {contactToUpdate} here: ");
                string updatedContact = Console.ReadLine().Trim();
                updatedContact = FormatContact(updatedContact);

                int index = GetEntryIndex(originalName);
                switch(contactToUpdate) {
                    case "name":
                        contacts[index].Name = updatedContact;
                        Console.WriteLine($"Contact {originalName} updated to {updatedContact}");
                        return true;
                    case "address":
                        contacts[index].Address = updatedContact;
                        Console.WriteLine($"Contact {originalName}'s {contactToUpdate} updated to {updatedContact}");
                        return true;
                }
            }
            return false;
        }

I haven't gotten into List yet. I do know about it, considered using it, but went with learning about c# arrays. They are a bit different from the array literal in js. I do want to refactor using List at some point, though.

Some other changes I made:

  • Now it trims excess whitespace before and after users input.
  • Also, I added a private formatting method that takes whatever the user enters and makes it have its proper case.
// changed this top portion of the AddEntry() method so it formats the
// name and address and then when the entry is successfully added it 
// returns the entire entry(prints it to the console) instead of just the name 
public bool AddEntry(string name, string address) {
            if (!ContainsEntry(name)) {
                name = FormatContact(name);
                address = FormatContact(address);
                Contact AddContact = new Contact(name, address);
                for (int i = 0; i < contacts.Length; i++) {
                    if (contacts[i] == null) {
                        contacts[i] = AddContact;
                        Console.WriteLine("Address Book updated. Name: {0} -- Address: {1} has been added!", name, address);

// this is the new formatting method I mentioned. 
 private string FormatContact(string stringToFormat) {
            char[] arr = stringToFormat.ToCharArray();
            for (int i = 0; i < arr.Length; i++) {
                int num;
                if (i == 0 || arr[i - 1] == ' ' && !( int.TryParse(arr[i].ToString(), out num) ) ) { 
                    arr[i] = Convert.ToChar( arr[i].ToString().ToUpper() );
                }
                else {
                    arr[i] = Convert.ToChar(arr[i].ToString().ToLower());
                }
            }
            return String.Concat(arr);
        }

Thank you for taking the time to look it over! That was a better review than I expected, lol. By the way, what type of development are you doing for your job? I will look into the link you sent me. I'm also still interested in the info about the breakpoints on visual studio. At this point, I just log things out at different intervals, when I find a bug.

Jon Wood
Jon Wood
9,884 Points

Awesome! Also, I believe you can actually override the ToString method in a custom class to print whatever you need when calling ToString, if you feel that may help with the FormatContact method.

For the breakpoints, this section may get you started. I'll look for some other tutorials for ya.

Kyle Jensen
Kyle Jensen
Courses Plus Student 6,293 Points

Jon Wood I just googled the override of ToString(). That's good to know. I will have to read about it after I get some lunch. Maybe it will help make that method a little less verbose.... Thanks for the link and the review!