diff --git a/018_Conditional_branching_and_looping/GuidedProject/Own/Program.cs b/018_Conditional_branching_and_looping/GuidedProject/Own/Program.cs index abc79be..1ed7326 100644 --- a/018_Conditional_branching_and_looping/GuidedProject/Own/Program.cs +++ b/018_Conditional_branching_and_looping/GuidedProject/Own/Program.cs @@ -126,13 +126,22 @@ int availability(string[,] animals) { return slots; } -string get_input(string text="Please enter your text: ") { +string get_input(string text="Please enter your text: ", bool integer=false) { bool invalid = true; while (invalid){ print(text, false); string? usr_in = Console.ReadLine(); if (!string.IsNullOrEmpty(usr_in) && usr_in.Trim() != "") { - return usr_in.Trim(); + if (integer) { + string resp = usr_in.Trim(); + int temp_int; + if (int.TryParse(resp, out temp_int)) { + print($"Opción 1: {temp_int}"); + return resp; + } + } else { + return usr_in.Trim(); + } } } return ""; @@ -143,7 +152,7 @@ void add_new_pet(string[,] animals, int slots){ string id = $"{rand_str(abcd)}{rand_int(nums)}"; string specie = get_input("Enter pet specie: "); string name = get_input("Enter the pet name: "); - int age = Int32.Parse(get_input("Enter pet age: ")); + int age = Int32.Parse(get_input("Enter pet age: ", true)); string desc = get_input("Enter the physical description: "); string perso = get_input("Enter pet personality: "); //print($"Will be added at index: {at_indx}"); diff --git a/019_branching_and_looping_structures/019_csharp.md b/019_branching_and_looping_structures/019_csharp.md new file mode 100644 index 0000000..142b534 --- /dev/null +++ b/019_branching_and_looping_structures/019_csharp.md @@ -0,0 +1,409 @@ +# Challenge project + +## Develop branching and looping structures in C# + +Demonstrate your ability to develop a console app that implements selection and +iteration statements to achieve app specifications. + +### Learning objectives + +In this module, you'll demonstrate your ability to: + +- Use Visual Studio Code to develop a C# console application that uses a +combination of selection and iteration statements to implement logical +workflows in accordance with supplied application data and user interactions. +- Evaluate the underlying conditions and make an informed decision when +choosing between if-elseif-else and switch statements, and between foreach, +for, while, and do iteration statements. +- Scope variables at an appropriate level within an application. + +## Introduction + +Applications often use a combination of selection and iteration statements to +establish code execution paths. In addition, user input and calculations +influence the flow through an application. Creating a user interface that +implements a design specification can be challenging. + +Suppose you're a developer working on the Contoso Pets application, an +application that's used to find homes for stray or abandoned pets. Some of the +development work has already been completed. For example, the application's +main menu and the code used to store new pet information have been developed. +However, certain information isn't always available when a pet is entered in +your system. You need to develop the features that ensure a complete dataset +exists for each animal in your care. + +In this module, you'll develop the following features of the Contoso Pets +application: + +- A feature that ensures animal ages and physical descriptions are complete. +- A feature that ensures animal nickname and personality descriptions are +complete. + +By the end of this module, your Contoso Pets application will ensure that every +element in the ourAnimals array is complete. + +> Note +> This is a challenge project module where you’ll complete an end-to-end +project from a specification. This module is intended to be a test of your +skills; there’s little guidance and no step-by-step instructions. + +### Learning Objectives + +In this module, you'll demonstrate your ability to: + +- Develop a C# console application that uses a combination of selection and +iteration statements to implement logical workflows. +- Evaluate the underlying conditions in your application and make an informed +decision between selection statement options. +- Scope variables at an appropriate level within an application. + +--- + +## Prepare + +In this challenge project, you'll develop portions of a C# console application. +You'll use boolean expressions, selection statements, and iteration statements +to implement the features of a design specification. As you develop the +application, you'll need to scope variables at the appropriate level. + +### Project specification + +The Starter code project for this module includes a Program.cs file with the +following code features: + +- The code declares variables used to collect and process pet data and menu item +selections + +- The code declares the ourAnimals array that includes the following information +for each animal in the array: + + - Pet ID #. + - Pet species (cat or dog). + - Pet age (years). + - A description of the pet's physical appearance. + - A description of the pet's personality. + - The pet's nickname. + +- The code uses a for loop around a `switch-case` construct to populate elements +of the `ourAnimals` array. + +- The code includes a loop around a main menu that terminates when the user +enters "exit". The main menu includes: + +```txt +1. List all of our current pet information. +2. Assign values to the ourAnimals array fields. +3. Ensure animal ages and physical descriptions are complete. +4. Ensure animal nicknames and personality descriptions are complete. +5. Edit an animal’s age. +6. Edit an animal’s personality description. +7. Display all cats with a specified characteristic. +8. Display all dogs with a specified characteristic. + +Enter menu item selection or type "Exit" to exit the program +``` + +- The code reads the user's menu item selection and uses a switch statement to +branch the code for each menu item number. + +- The code includes implementation for menu options 1 and 2. + +- The code displays an "under construction" message for menu options 3-8. + +Your goal in this challenge is to create the app features aligned with menu +options 3 and 4. + +> Note +> New animals must be added to the ourAnimals array when they arrive. However, +an animal's age and some physical characteristics for a pet may be unknown +until after a veterinarian's examination. In addition, an animal's nickname and +personality may be unknown when a pet first arrives. The new features that +you're developing will ensure that a complete dataset exists for each animal in +the ourAnimals array. + +To ensure that animal ages and physical descriptions are complete, your code +must: + +- Assign a valid numeric value to petAge for any animal that has been assigned +data in the ourAnimals array but has not been assigned an age. +- Assign a valid string to petPhysicalDescription for any animal that has been +assigned data in the ourAnimals array but has not been assigned a physical +description. +- Verify that physical descriptions have an assigned value. Assigned values +cannot have zero characters. Any further requirement is up to you. +- To ensure that animal nicknames and personality descriptions are complete, +your code must: + +- Assign a valid string to petNickname for any animal that has been assigned +data in the ourAnimals array but has not been assigned a nickname. +- Assign a valid string to petPersonalityDescription for any animal that has +been assigned data in the ourAnimals array but has not been assigned a +personality description. +- Verify that nicknames and personality descriptions have an assigned value. +Assigned values cannot have zero characters. Any further requirement is up to +you. + +### Setup + +Use the following steps to prepare for the Challenge project exercises: + +To download a zip file containing the Starter project code, select the +following link: +[Lab Files](https://github.com/MicrosoftLearning/Challenge-project-branching-looping-CSharp/archive/refs/heads/main.zip). + +Unzip the files in your development environment. Consider using your PC as your +development environment so that you have access to your code after completing +this module. If you aren't using your PC as your development environment, you +can unzip the files in a sandbox or hosted environment. + +You're now ready to begin the Challenge project exercises. Good luck! + +--- + +## Exercise + +### Ensure that petAge and petPhysicalDescription contain valid information + +The Contoso Pets application is used to help find new homes for abandoned pets. +Your goal in this challenge is to develop the application features used to +ensure that you have a completed dataset for each animal in the ourAnimals array. + +### Specification + +In this challenge exercise, you need to develop a feature that ensures animal +ages and physical descriptions are complete. + +This feature must: + +- Be enabled inside the appropriate application branch (must not overwrite the +code in the code branch for menu option 2). + +- Skip over any animal in the ourAnimals array when the value of pet ID is set +to the default value. + +- Display the pet ID value and prompt the user for an updated data value if +ourAnimals array data is missing or incomplete. + +- Ensure that a valid numeric value is assigned to animalAge for all animals in +the ourAnimals array that have assigned data. + +- Ensure that a valid string is assigned to animalPhysicalDescription for all +animals in the ourAnimals array that have assigned data. + +- Enforce the following validation rules for animalAge. + + - It must be possible to convert the value entered to numeric data type. + +- Enforce the following validation rules for animalPhysicalDescription: + + - Values cannot be null. + - Values cannot have zero characters. + - Any further restriction is up to the developer. + +- Inform the application user when all data requirements are met, pausing the +application to ensure the message can be seen and responded to. + +### Check your work + +To validate that your code satisfies the specified requirements + +> Note +> You can exit the verification test before completing all of the verification +steps if see a result that does not satisfy the specification requirements. To +force an exit from the running program, in the Terminal panel, press Ctrl-C. +After exiting the running app, complete the edits that you believe will address +the issue you are working on, save your updates to the Program.cs file, and +then re-build and run your code. + +At the Terminal command prompt, enter 3 + +Verify that the Terminal panel updates with a message similar to the following: + +```txt +Enter an age for ID #: c4 +``` + +At the Terminal command prompt, enter one + +Verify that your code repeats the prompt requesting a value for the age of the +pet. + +The Terminal panel should update to show the repeated prompt. The display +should be similar to the following: + +```txt +Enter an age for ID #: c4 +one +Enter an age for ID #: c4 +``` + +At the Terminal command prompt, enter 1 + +Verify that your code accepts 1 as a valid numeric entry and that the Terminal +panel displays a message similar to the following: + +```txt +Enter a physical description for ID #: c4 (size, color, breed, gender, weight, housebroken) +``` + +At the Terminal command prompt, press the Enter key (without typing any characters). + +Verify that your code repeats the prompt requesting a value for the physical +description of the pet. + +The Terminal panel should update to show the repeated prompt. The display +should be similar to the following: + +```txt +Enter a physical description for ID #: c4 (size, color, gender, weight, housebroken) + +Enter a physical description for ID #: c4 (size, color, gender, weight, housebroken) +``` + +At the Terminal command prompt, enter small white Siamese cat weighing about 8 +pounds. litter box trained. + +Verify that your code accepts small white Siamese cat weighing about 8 pounds. +litter box trained. as a valid entry and that the Terminal panel displays a +message similar to the following: + +```txt +Age and physical description fields are complete for all of our friends. +Press the Enter key to continue +``` + +If you specified further restrictions for valid entries, run the appropriate +test cases to verify your work. + +> Note +> If your code meets the requirements you should be able to complete each step +in order and see the expected results in a single test pass. If you added +additional restrictions, you may need to exit the application and then run a +separate test pass to complete your verification. + +Once you've validated the results for this exercise, proceed to the next +exercise in this challenge. + +## Exercise + +### Ensure that pet nicknames and personality descriptions are complete + +The Contoso Pets app is used to help find new homes for abandoned pets. Your +goal in this challenge is to develop the app features used to ensure that we +have a completed dataset for each animal in the ourAnimals array. + +### Specification + +You need to develop a feature that ensures animal nicknames and personality +descriptions are complete. + +This feature must: + +- Be enabled inside the appropriate application branch (must not overwrite the +code in the code branch for menu option 2). + +- Skip over any animal in the ourAnimals array when the value of pet ID is set +to the value default value. + +- Display the pet ID value and prompt the user for an updated data value if +ourAnimals array data is missing or incomplete. + +- Ensure that a valid string is assigned to animalNickname for all animals in +the ourAnimals array that have assigned data. + +- Ensure that a valid string is assigned to animalPersonalityDescription for +all animals in the ourAnimals array that have assigned data. + +- Enforce the following validation rules for petNickname and +petPersonalityDescription: + + - Values cannot be null. + - Values cannot have zero characters. + - Any further restriction is up to the developer. + +Inform the application user when all data requirements are met, pausing the +application to ensure the message can be seen and responded to. + +### Check your work + +To validate that your code satisfies the specified requirements, complete the +following steps: + +Build and run your app. + +At the Terminal command prompt, enter 4 + +Verify that the Terminal panel updates with a message similar to the following: + +```txt +Enter a nickname for ID #: c4 +``` + +At the Terminal command prompt, press the Enter key (without typing any +characters). + +Verify that your code repeats the prompt requesting a value for the nickname of +the pet. + +The Terminal panel should update to display something similar to the following: + +```txt +Enter a nickname for ID #: c4 + +Enter a nickname for ID #: c4 +``` + +At the Terminal command prompt, enter snowflake + +Verify that your code accepts snowflake as a valid entry and that the Terminal +panel displays a message similar to the following: + +```txt +Enter a personality description for ID #: c4 (likes or dislikes, tricks, energy level) +``` + +At the Terminal command prompt, press the Enter key (without typing any +characters). + +Verify that your code repeats the prompt requesting a value for the personality +description of the pet. + +The Terminal panel should update to display something similar to the following: + +```txt +Enter a personality description for ID #: c4 (likes or dislikes, tricks, energy level) + +Enter a personality description for ID #: c4 (likes or dislikes, tricks, energy level) +``` + +At the Terminal command prompt, enter loves to curl up in a warm spot + +Verify that your code accepts loves to curl up in a warm spot as a valid entry +and that the Terminal panel displays a message similar to the following: + +```txt +Nickname and personality description fields are complete for all of our friends. +Press the Enter key to continue +``` + +If you specified further restrictions for valid entries, run the appropriate +test cases to verify your work. + +Congratulations if you succeeded in this challenge! + +--- + +## Summary + +Your goal was to demonstrate the ability to develop features of an application +that achieve a design specification. You needed to choose and implement the +appropriate iteration and selection statement types to meet the stated +requirements. + +By creating nested combinations of iteration and selection statements, you +built a user interface that enables the application user to enter valid pet +data that filled gaps in the ourAnimals array. + +Your ability to implement features of the Contoso Pets application based on a +design specification demonstrates your understanding of the iteration and +selection statements. diff --git a/019_branching_and_looping_structures/ChallengeProject/Final/Final.csproj b/019_branching_and_looping_structures/ChallengeProject/Final/Final.csproj new file mode 100644 index 0000000..91b464a --- /dev/null +++ b/019_branching_and_looping_structures/ChallengeProject/Final/Final.csproj @@ -0,0 +1,10 @@ + + + + Exe + net8.0 + enable + enable + + + diff --git a/019_branching_and_looping_structures/ChallengeProject/Final/Program.cs b/019_branching_and_looping_structures/ChallengeProject/Final/Program.cs new file mode 100644 index 0000000..4f622bf --- /dev/null +++ b/019_branching_and_looping_structures/ChallengeProject/Final/Program.cs @@ -0,0 +1,434 @@ +using System; +using System.IO; + +// the ourAnimals array will store the following: +string animalSpecies = ""; +string animalID = ""; +string animalAge = ""; +string animalPhysicalDescription = ""; +string animalPersonalityDescription = ""; +string animalNickname = ""; + +// variables that support data entry +int maxPets = 8; +string? readResult; +string menuSelection = ""; +int petCount = 0; +string anotherPet = "y"; +bool validEntry = false; +int petAge = 0; + +// array used to store runtime data, there is no persisted data +string[,] ourAnimals = new string[maxPets, 6]; + +// create some initial ourAnimals array entries +for (int i = 0; i < maxPets; i++) +{ + switch (i) + { + case 0: + animalSpecies = "dog"; + animalID = "d1"; + animalAge = "2"; + animalPhysicalDescription = "medium sized cream colored female golden retriever weighing about 65 pounds. housebroken."; + animalPersonalityDescription = "loves to have her belly rubbed and likes to chase her tail. gives lots of kisses."; + animalNickname = "lola"; + break; + + case 1: + animalSpecies = "dog"; + animalID = "d2"; + animalAge = "9"; + animalPhysicalDescription = "large reddish-brown male golden retriever weighing about 85 pounds. housebroken."; + animalPersonalityDescription = "loves to have his ears rubbed when he greets you at the door, or at any time! loves to lean-in and give doggy hugs."; + animalNickname = "loki"; + break; + + case 2: + animalSpecies = "cat"; + animalID = "c3"; + animalAge = "1"; + animalPhysicalDescription = "small white female weighing about 8 pounds. litter box trained."; + animalPersonalityDescription = "friendly"; + animalNickname = "Puss"; + break; + + case 3: + animalSpecies = "cat"; + animalID = "c4"; + animalAge = "?"; + animalPhysicalDescription = ""; + animalPersonalityDescription = ""; + animalNickname = ""; + + break; + + default: + animalSpecies = ""; + animalID = ""; + animalAge = ""; + animalPhysicalDescription = ""; + animalPersonalityDescription = ""; + animalNickname = ""; + break; + + } + + ourAnimals[i, 0] = "ID #: " + animalID; + ourAnimals[i, 1] = "Species: " + animalSpecies; + ourAnimals[i, 2] = "Age: " + animalAge; + ourAnimals[i, 3] = "Nickname: " + animalNickname; + ourAnimals[i, 4] = "Physical description: " + animalPhysicalDescription; + ourAnimals[i, 5] = "Personality: " + animalPersonalityDescription; +} + +// display the top-level menu options +do +{ + Console.Clear(); + + Console.WriteLine("Welcome to the Contoso PetFriends app. Your main menu options are:"); + Console.WriteLine(" 1. List all of our current pet information"); + Console.WriteLine(" 2. Add a new animal friend to the ourAnimals array"); + Console.WriteLine(" 3. Ensure animal ages and physical descriptions are complete"); + Console.WriteLine(" 4. Ensure animal nicknames and personality descriptions are complete"); + Console.WriteLine(" 5. Edit an animal’s age"); + Console.WriteLine(" 6. Edit an animal’s personality description"); + Console.WriteLine(" 7. Display all cats with a specified characteristic"); + Console.WriteLine(" 8. Display all dogs with a specified characteristic"); + Console.WriteLine(); + Console.WriteLine("Enter your selection number (or type Exit to exit the program)"); + + readResult = Console.ReadLine(); + if (readResult != null) + { + menuSelection = readResult.ToLower(); + // NOTE: We could put a do statement around the menuSelection entry to ensure a valid entry, but we + // use a conditional statement below that only processes the valid entry values, so the do statement + // is not required here. + } + + // use switch-case to process the selected menu option + switch (menuSelection) + { + case "1": + // List all of our current pet information + for (int i = 0; i < maxPets; i++) + { + if (ourAnimals[i, 0] != "ID #: ") + { + Console.WriteLine(); + for (int j = 0; j < 6; j++) + { + Console.WriteLine(ourAnimals[i, j].ToString()); + } + } + } + Console.WriteLine("\n\rPress the Enter key to continue"); + readResult = Console.ReadLine(); + + break; + + case "2": + // Add a new animal friend to the ourAnimals array + // + // The ourAnimals array contains + // 1. the species (cat or dog). a required field + // 2. the ID number - for example C17 + // 3. the pet's age. can be blank at initial entry. + // 4. the pet's nickname. can be blank. + // 5. a description of the pet's physical appearance. can be blank. + // 6. a description of the pet's personality. can be blank. + + anotherPet = "y"; + petCount = 0; + for (int i = 0; i < maxPets; i++) + { + if (ourAnimals[i, 0] != "ID #: ") + { + petCount += 1; + } + } + + if (petCount < maxPets) + { + Console.WriteLine($"We currently have {petCount} pets that need homes. We can manage {(maxPets - petCount)} more."); + } + + while (anotherPet == "y" && petCount < maxPets) + { + // get species (cat or dog) - string animalSpecies is a required field + do + { + Console.WriteLine("\n\rEnter 'dog' or 'cat' to begin a new entry"); + readResult = Console.ReadLine(); + if (readResult != null) + { + animalSpecies = readResult.ToLower(); + if (animalSpecies != "dog" && animalSpecies != "cat") + { + //Console.WriteLine($"You entered: {animalSpecies}."); + validEntry = false; + } + else + { + validEntry = true; + } + } + } while (validEntry == false); + + // build the animal the ID number - for example C1, C2, D3 (for Cat 1, Cat 2, Dog 3) + animalID = animalSpecies.Substring(0, 1) + (petCount + 1).ToString(); + + // get the pet's age. can be ? at initial entry. + do + { + Console.WriteLine("Enter the pet's age or enter ? if unknown"); + readResult = Console.ReadLine(); + if (readResult != null) + { + animalAge = readResult; + if (animalAge != "?") + { + validEntry = int.TryParse(animalAge, out petAge); + } + else + { + validEntry = true; + } + } + } while (validEntry == false); + + + // get a description of the pet's physical appearance - animalPhysicalDescription can be blank. + do + { + Console.WriteLine("Enter a physical description of the pet (size, color, gender, weight, housebroken)"); + readResult = Console.ReadLine(); + if (readResult != null) + { + animalPhysicalDescription = readResult.ToLower(); + if (animalPhysicalDescription == "") + { + animalPhysicalDescription = "tbd"; + } + } + } while (validEntry == false); + + + // get a description of the pet's personality - animalPersonalityDescription can be blank. + do + { + Console.WriteLine("Enter a description of the pet's personality (likes or dislikes, tricks, energy level)"); + readResult = Console.ReadLine(); + if (readResult != null) + { + animalPersonalityDescription = readResult.ToLower(); + if (animalPersonalityDescription == "") + { + animalPersonalityDescription = "tbd"; + } + } + } while (validEntry == false); + + + // get the pet's nickname. animalNickname can be blank. + do + { + Console.WriteLine("Enter a nickname for the pet"); + readResult = Console.ReadLine(); + if (readResult != null) + { + animalNickname = readResult.ToLower(); + if (animalNickname == "") + { + animalNickname = "tbd"; + } + } + } while (validEntry == false); + + // store the pet information in the ourAnimals array (zero based) + ourAnimals[petCount, 0] = "ID #: " + animalID; + ourAnimals[petCount, 1] = "Species: " + animalSpecies; + ourAnimals[petCount, 2] = "Age: " + animalAge; + ourAnimals[petCount, 3] = "Nickname: " + animalNickname; + ourAnimals[petCount, 4] = "Physical description: " + animalPhysicalDescription; + ourAnimals[petCount, 5] = "Personality: " + animalPersonalityDescription; + + // increment petCount (the array is zero-based, so we increment the counter after adding to the array) + petCount = petCount + 1; + + // check maxPet limit + if (petCount < maxPets) + { + // another pet? + Console.WriteLine("Do you want to enter info for another pet (y/n)"); + do + { + readResult = Console.ReadLine(); + if (readResult != null) + { + anotherPet = readResult.ToLower(); + } + + } while (anotherPet != "y" && anotherPet != "n"); + } + //NOTE: The value of anotherPet (either "y" or "n") is evaluated in the while statement expression - at the top of the while loop + } + + if (petCount >= maxPets) + { + Console.WriteLine("We have reached our limit on the number of pets that we can manage."); + Console.WriteLine("Press the Enter key to continue."); + readResult = Console.ReadLine(); + } + + break; + + case "3": + // Ensure animal ages and physical descriptions are complete + // + // ourAnimals[i, 2] = "Age: " + animalAge; + // ourAnimals[i, 4] = "Physical description: " + animalPhysicalDescription; + + for (int i = 0; i < maxPets; i++) + { + if (ourAnimals[i, 2] == "Age: ?" && ourAnimals[i, 0] != "ID #: ") + { + do + { + Console.WriteLine($"Enter an age for {ourAnimals[i, 0]}"); + readResult = Console.ReadLine(); + if (readResult != null) + { + animalAge = readResult; + validEntry = int.TryParse(animalAge, out petAge); + } + } while (validEntry == false); + ourAnimals[i, 2] = "Age: " + animalAge.ToString(); + } + + if (ourAnimals[i, 4] == "Physical description: " && ourAnimals[i, 0] != "ID #: ") + { + do + { + Console.WriteLine($"Enter a physical description for {ourAnimals[i, 0]} (size, color, gender, weight, housebroken)"); + readResult = Console.ReadLine(); + if (readResult != null) + { + animalPhysicalDescription = readResult.ToLower(); + if (animalPhysicalDescription == "") + { + validEntry = false; + } + else + { + validEntry = true; + } + + } + } while (validEntry == false); + + ourAnimals[i, 4] = "Physical description: " + animalPhysicalDescription; + } + } + Console.WriteLine("\n\rAge and physical description fields are complete for all of our friends. \n\rPress the Enter key to continue"); + readResult = Console.ReadLine(); + + break; + + case "4": + // Ensure animal nickname and personality descriptions are complete + // + // ourAnimals[i, 3] = "Nickname: " + animalNickname; + // ourAnimals[i, 5] = "Personality: " + animalPersonalityDescription; + + for (int i = 0; i < maxPets; i++) + { + if (ourAnimals[i, 3] == "Nickname: " && ourAnimals[i, 0] != "ID #: ") + { + do + { + Console.WriteLine($"Enter a nickname for {ourAnimals[i, 0]}"); + readResult = Console.ReadLine(); + if (readResult != null) + { + animalNickname = readResult; + if (animalNickname == "") + { + validEntry = false; + } + else + { + validEntry = true; + } + + } + + } while (validEntry == false); + + ourAnimals[i, 3] = "Nickname: " + animalNickname; + } + + if (ourAnimals[i, 5] == "Personality: " && ourAnimals[i, 0] != "ID #: ") + { + do + { + //"Enter a description of the pet's personality (likes or dislikes, tricks, energy level" + Console.WriteLine($"Enter a personality description for {ourAnimals[i, 0]} (likes or dislikes, tricks, energy level)"); + readResult = Console.ReadLine(); + if (readResult != null) + { + animalPersonalityDescription = readResult.ToLower(); + if (animalPersonalityDescription == "") + { + validEntry = false; + } + else + { + validEntry = true; + } + } + } while (validEntry == false); + + ourAnimals[i, 5] = "Personality: " + animalPersonalityDescription; + } + } + Console.WriteLine("\n\rAge and physical description fields are complete for all of our friends. \n\rPress the Enter key to continue"); + readResult = Console.ReadLine(); + + break; + + case "5": + // Edit an animal’s age"); + Console.WriteLine("UNDER CONSTRUCTION - please check back next month to see progress."); + Console.WriteLine("Press the Enter key to continue."); + readResult = Console.ReadLine(); + break; + + case "6": + // Edit an animal’s personality description"); + Console.WriteLine("UNDER CONSTRUCTION - please check back next month to see progress."); + Console.WriteLine("Press the Enter key to continue."); + readResult = Console.ReadLine(); + break; + + case "7": + // Display all cats with a specified characteristic + Console.WriteLine("UNDER CONSTRUCTION - please check back next month to see progress."); + Console.WriteLine("Press the Enter key to continue."); + readResult = Console.ReadLine(); + break; + + case "8": + // Display all dogs with a specified characteristic + Console.WriteLine("UNDER CONSTRUCTION - please check back next month to see progress."); + Console.WriteLine("Press the Enter key to continue."); + readResult = Console.ReadLine(); + break; + + default: + break; + } + +} while (menuSelection != "exit"); diff --git a/019_branching_and_looping_structures/ChallengeProject/LICENSE b/019_branching_and_looping_structures/ChallengeProject/LICENSE new file mode 100644 index 0000000..2080d95 --- /dev/null +++ b/019_branching_and_looping_structures/ChallengeProject/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2023 Microsoft Learning + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/019_branching_and_looping_structures/ChallengeProject/Own/Own.csproj b/019_branching_and_looping_structures/ChallengeProject/Own/Own.csproj new file mode 100644 index 0000000..2150e37 --- /dev/null +++ b/019_branching_and_looping_structures/ChallengeProject/Own/Own.csproj @@ -0,0 +1,10 @@ + + + + Exe + net8.0 + enable + enable + + + diff --git a/019_branching_and_looping_structures/ChallengeProject/Own/Program.cs b/019_branching_and_looping_structures/ChallengeProject/Own/Program.cs new file mode 100644 index 0000000..c5f3fd7 --- /dev/null +++ b/019_branching_and_looping_structures/ChallengeProject/Own/Program.cs @@ -0,0 +1,276 @@ +int max_pets = 8; +bool exit = false; +string? selection; +string separator = "+-------------------------------------" + + "--------------------------------------+"; +string main_menu = @" + 1. List all of our current pet information. + 2. Assign values to the ourAnimals array fields. + 3. Ensure animal ages and physical descriptions are complete. + 4. Ensure animal nicknames and personality descriptions are complete. + 5. Edit an animal's age. + 6. Edit an animal's personality description. + 7. Display all cats with a specified characteristic. + 8. Display all dogs with a specified characteristic. + + Enter menu item selection or type 'Exit' to exit the program +"; +string[] description = { + "big sized female golden colored weighing about 20 pounds. housebroken.", + "large dark-brown male siver back weighing about 15 pounds. housebroken.", + "small white female weighing about 8 pounds. translucid at sun.", + "medium size male. fluorescent at night.", +}; +string[] personality = { + "friendly", + "loves to have his ears rubbed at any time! loves to lean-in.", + "loves to have her belly rubbed. gives lots of kisses.", + "sauvage and lovelly.", +}; +string[] options = { "1", "2", "3", "4", "5", "6", "7", "8", "exit" }; +string[] nickname = { "lola", "loki", "fuzz", "boby", "gogo", "besti" }; +string[] species = { "cat", "dog", "bee", "pig" }; +string[] abcd = { "a", "b", "c", "d" }; +int[] nums = { 1, 2, 3, 4, 5, 6, 7, 8 }; +string[,] our_animals = new string[max_pets, 6]; +Random rand = new Random(); + +var clear = Console.Clear; + +void print(string text, bool new_line = true) { + if (new_line) { + Console.WriteLine(text); + } else { + Console.Write(text); + } +} + +string rand_str(string[] choices) { + int indx = rand.Next(choices.Length); + return choices[indx]; +} + +int rand_int(int[] choices) { + int indx = rand.Next(choices.Length); + return choices[indx]; +} + +void populate_animals_array() { + for (int i = 0; i < max_pets - 4; i++) { + bool uniq_id = false; + our_animals[i, 0] = rand_str(species); + while (!uniq_id) { + bool check = true; + string id = $"{rand_str(abcd)}{rand_int(nums)}"; + for (int j = 0; j < max_pets - 4; j++) { + if (!string.IsNullOrEmpty(our_animals[j, 1]) && our_animals[j, 1] == id) { + uniq_id = false; + check = false; + break; + } + } + if (check) { + our_animals[i, 1] = id; + uniq_id = true; + } + } + our_animals[i, 2] = rand_str(description); + our_animals[i, 3] = $"{rand_int(nums)}"; + our_animals[i, 4] = rand_str(personality); + our_animals[i, 5] = rand_str(nickname); + } +} + +void press_enter() { + print("\n\tPress 'Enter' to continue", false); + Console.ReadLine(); +} + +void print_pets(string[,] animals) { + clear(); + print(separator); + for (int j = 0; j < animals.GetLength(0); j++) { + string[] animal = new string[6]; + for (int k = 0; k < animals.GetLength(1); k++) { + animal[k] = animals[j, k]; + } + print_pet(animal); + } +} + +void print_pet(string[] pet) { + if (!string.IsNullOrEmpty(pet[1])) { + string id = pet[1]; + string name = pet[5]; + string specie = pet[0]; + int age = Int32.Parse(pet[3].ToString()); + string year_word = age > 1 ? "years" : "year"; + string desc = pet[2]; + string perso = pet[4]; + print($@" ID: {id} SPECIE: {specie} + NAME: {name} AGE: {age} {year_word} + DESCRIPTION: {desc} + PERSONALITY: {perso} +{separator}"); + } +} + +int availability(string[,] animals) { + int pet_count = 0; + for (int j = 0; j < animals.GetLength(0); j++) { + if (!string.IsNullOrEmpty(animals[j, 1])) { + pet_count++; + } + } + int slots = max_pets - pet_count; + return slots; +} + +string get_input(string text = "Please enter your text: ", bool integer = false) { + bool invalid = true; + while (invalid) { + print(text, false); + string? usr_in = Console.ReadLine(); + if (!string.IsNullOrEmpty(usr_in) && usr_in.Trim() != "") { + if (integer) { + string resp = usr_in.Trim(); + int temp_int; + if (int.TryParse(resp, out temp_int)) { + print($"Opción 1: {temp_int}"); + return resp; + } + } else { + return usr_in.Trim(); + } + } + } + return ""; +} + +void add_new_pet(string[,] animals, int slots) { + int at_indx = max_pets - slots; + string id = $"{rand_str(abcd)}{rand_int(nums)}"; + string specie = get_input("Enter pet specie: "); + string name = get_input("Enter the pet name (? if unknown): "); + int age = Int32.Parse(get_input("Enter pet age (-1 if unknown): ", true)); + string desc = get_input("Enter the physical description (? if unknown): "); + string perso = get_input("Enter pet personality (? if unknown): "); + //print($"Will be added at index: {at_indx}"); + //print($"{id}\n{specie}\n{name}\n{age}\n{desc}\n{perso}"); + animals[at_indx, 0] = specie; + animals[at_indx, 1] = id; + animals[at_indx, 2] = desc; + animals[at_indx, 3] = age.ToString(); + animals[at_indx, 4] = perso; + animals[at_indx, 5] = name; +} + +void ask_new_pet() { + clear(); + print("Assign values to the ourAnimals array fields"); + print(separator); + int slots = availability(our_animals); + print($"\nWe currently have {max_pets - slots} pets that need homes."); + print($"We can manage {slots} more."); + if (slots > 0) { + bool another = false; + do { + string resp = get_input("Do you want to enter info for another pet?: "); + bool invalid = true; + if (resp != "") { + while (invalid) { + switch (resp) { + case "y" or "yes": + add_new_pet(our_animals, slots); + resp = ""; + invalid = false; + another = true; + break; + case "n" or "no": + invalid = false; + another = false; + break; + default: + resp = get_input("Please enter [Y]es or [N]o: "); + break; + } + } + } + slots = availability(our_animals); + } while (another && slots > 0); + if (slots == 0) { + print("We have reached our limit on the number of pets that we can manage."); + press_enter(); + } + press_enter(); + } else { + press_enter(); + } +} + +void check_age_and_desc() { + int pet_count = max_pets - (availability(our_animals)); +} + +populate_animals_array(); +while (!exit) { + clear(); + print(main_menu); + selection = Console.ReadLine(); + if (selection != null && options.Contains(selection.ToLower())) { + selection = selection.ToLower(); + switch (selection) { + case "1": + print_pets(our_animals); + press_enter(); + break; + case "2": + ask_new_pet(); + break; + case "3": + clear(); + print("Ensure animal ages and physical descriptions are complete"); + check_age_and_desc(); + press_enter(); + break; + case "4": + clear(); + print("Ensure animal nicknames and personality descriptions are complete"); + press_enter(); + break; + case "5": + clear(); + print("Edit an animal's age"); + press_enter(); + break; + case "6": + clear(); + print("Edit an animal's personality description"); + press_enter(); + break; + case "7": + clear(); + print("Display all cats with a specified characteristic"); + press_enter(); + break; + case "8": + clear(); + print("Display all dogs with a specified characteristic"); + press_enter(); + break; + case "exit": + print("\n\tTerminating application\n"); + exit = !exit; + break; + default: + print("\n\tPlease read the instructions"); + press_enter(); + break; + } + } else { + print("\n\tPlease read the instructions"); + press_enter(); + } +} + +Environment.Exit(0); diff --git a/019_branching_and_looping_structures/ChallengeProject/README.md b/019_branching_and_looping_structures/ChallengeProject/README.md new file mode 100644 index 0000000..7eb830d --- /dev/null +++ b/019_branching_and_looping_structures/ChallengeProject/README.md @@ -0,0 +1,2 @@ +# Challenge-project-branching-looping-CSharp +Starter and Solution code for the Challenge project: "Develop conditional branching and looping structures in C#" from the Microsoft Learn collection "Getting started with C#" diff --git a/019_branching_and_looping_structures/ChallengeProject/Starter/Program.cs b/019_branching_and_looping_structures/ChallengeProject/Starter/Program.cs new file mode 100644 index 0000000..59d4d12 --- /dev/null +++ b/019_branching_and_looping_structures/ChallengeProject/Starter/Program.cs @@ -0,0 +1,334 @@ +using System; +using System.IO; + +// the ourAnimals array will store the following: +string animalSpecies = ""; +string animalID = ""; +string animalAge = ""; +string animalPhysicalDescription = ""; +string animalPersonalityDescription = ""; +string animalNickname = ""; + +// variables that support data entry +int maxPets = 8; +string? readResult; +string menuSelection = ""; +int petCount = 0; +string anotherPet = "y"; +bool validEntry = false; +int petAge = 0; + +// array used to store runtime data, there is no persisted data +string[,] ourAnimals = new string[maxPets, 6]; + +// create some initial ourAnimals array entries +for (int i = 0; i < maxPets; i++) +{ + switch (i) + { + case 0: + animalSpecies = "dog"; + animalID = "d1"; + animalAge = "2"; + animalPhysicalDescription = "medium sized cream colored female golden retriever weighing about 65 pounds. housebroken."; + animalPersonalityDescription = "loves to have her belly rubbed and likes to chase her tail. gives lots of kisses."; + animalNickname = "lola"; + break; + + case 1: + animalSpecies = "dog"; + animalID = "d2"; + animalAge = "9"; + animalPhysicalDescription = "large reddish-brown male golden retriever weighing about 85 pounds. housebroken."; + animalPersonalityDescription = "loves to have his ears rubbed when he greets you at the door, or at any time! loves to lean-in and give doggy hugs."; + animalNickname = "loki"; + break; + + case 2: + animalSpecies = "cat"; + animalID = "c3"; + animalAge = "1"; + animalPhysicalDescription = "small white female weighing about 8 pounds. litter box trained."; + animalPersonalityDescription = "friendly"; + animalNickname = "Puss"; + break; + + case 3: + animalSpecies = "cat"; + animalID = "c4"; + animalAge = "?"; + animalPhysicalDescription = ""; + animalPersonalityDescription = ""; + animalNickname = ""; + + break; + + default: + animalSpecies = ""; + animalID = ""; + animalAge = ""; + animalPhysicalDescription = ""; + animalPersonalityDescription = ""; + animalNickname = ""; + break; + + } + + ourAnimals[i, 0] = "ID #: " + animalID; + ourAnimals[i, 1] = "Species: " + animalSpecies; + ourAnimals[i, 2] = "Age: " + animalAge; + ourAnimals[i, 3] = "Nickname: " + animalNickname; + ourAnimals[i, 4] = "Physical description: " + animalPhysicalDescription; + ourAnimals[i, 5] = "Personality: " + animalPersonalityDescription; +} + +// display the top-level menu options +do +{ + Console.Clear(); + + Console.WriteLine("Welcome to the Contoso PetFriends app. Your main menu options are:"); + Console.WriteLine(" 1. List all of our current pet information"); + Console.WriteLine(" 2. Add a new animal friend to the ourAnimals array"); + Console.WriteLine(" 3. Ensure animal ages and physical descriptions are complete"); + Console.WriteLine(" 4. Ensure animal nicknames and personality descriptions are complete"); + Console.WriteLine(" 5. Edit an animal’s age"); + Console.WriteLine(" 6. Edit an animal’s personality description"); + Console.WriteLine(" 7. Display all cats with a specified characteristic"); + Console.WriteLine(" 8. Display all dogs with a specified characteristic"); + Console.WriteLine(); + Console.WriteLine("Enter your selection number (or type Exit to exit the program)"); + + readResult = Console.ReadLine(); + if (readResult != null) + { + menuSelection = readResult.ToLower(); + // NOTE: We could put a do statement around the menuSelection entry to ensure a valid entry, but we + // use a conditional statement below that only processes the valid entry values, so the do statement + // is not required here. + } + + // use switch-case to process the selected menu option + switch (menuSelection) + { + case "1": + // List all of our current pet information + for (int i = 0; i < maxPets; i++) + { + if (ourAnimals[i, 0] != "ID #: ") + { + Console.WriteLine(); + for (int j = 0; j < 6; j++) + { + Console.WriteLine(ourAnimals[i, j].ToString()); + } + } + } + Console.WriteLine("\n\rPress the Enter key to continue"); + readResult = Console.ReadLine(); + + break; + + case "2": + // Add a new animal friend to the ourAnimals array + // + // The ourAnimals array contains + // 1. the species (cat or dog). a required field + // 2. the ID number - for example C17 + // 3. the pet's age. can be blank at initial entry. + // 4. the pet's nickname. can be blank. + // 5. a description of the pet's physical appearance. can be blank. + // 6. a description of the pet's personality. can be blank. + + anotherPet = "y"; + petCount = 0; + for (int i = 0; i < maxPets; i++) + { + if (ourAnimals[i, 0] != "ID #: ") + { + petCount += 1; + } + } + + if (petCount < maxPets) + { + Console.WriteLine($"We currently have {petCount} pets that need homes. We can manage {(maxPets - petCount)} more."); + } + + while (anotherPet == "y" && petCount < maxPets) + { + // get species (cat or dog) - string animalSpecies is a required field + do + { + Console.WriteLine("\n\rEnter 'dog' or 'cat' to begin a new entry"); + readResult = Console.ReadLine(); + if (readResult != null) + { + animalSpecies = readResult.ToLower(); + if (animalSpecies != "dog" && animalSpecies != "cat") + { + //Console.WriteLine($"You entered: {animalSpecies}."); + validEntry = false; + } + else + { + validEntry = true; + } + } + } while (validEntry == false); + + // build the animal the ID number - for example C1, C2, D3 (for Cat 1, Cat 2, Dog 3) + animalID = animalSpecies.Substring(0, 1) + (petCount + 1).ToString(); + + // get the pet's age. can be ? at initial entry. + do + { + Console.WriteLine("Enter the pet's age or enter ? if unknown"); + readResult = Console.ReadLine(); + if (readResult != null) + { + animalAge = readResult; + if (animalAge != "?") + { + validEntry = int.TryParse(animalAge, out petAge); + } + else + { + validEntry = true; + } + } + } while (validEntry == false); + + + // get a description of the pet's physical appearance - animalPhysicalDescription can be blank. + do + { + Console.WriteLine("Enter a physical description of the pet (size, color, gender, weight, housebroken)"); + readResult = Console.ReadLine(); + if (readResult != null) + { + animalPhysicalDescription = readResult.ToLower(); + if (animalPhysicalDescription == "") + { + animalPhysicalDescription = "tbd"; + } + } + } while (validEntry == false); + + + // get a description of the pet's personality - animalPersonalityDescription can be blank. + do + { + Console.WriteLine("Enter a description of the pet's personality (likes or dislikes, tricks, energy level)"); + readResult = Console.ReadLine(); + if (readResult != null) + { + animalPersonalityDescription = readResult.ToLower(); + if (animalPersonalityDescription == "") + { + animalPersonalityDescription = "tbd"; + } + } + } while (validEntry == false); + + + // get the pet's nickname. animalNickname can be blank. + do + { + Console.WriteLine("Enter a nickname for the pet"); + readResult = Console.ReadLine(); + if (readResult != null) + { + animalNickname = readResult.ToLower(); + if (animalNickname == "") + { + animalNickname = "tbd"; + } + } + } while (validEntry == false); + + // store the pet information in the ourAnimals array (zero based) + ourAnimals[petCount, 0] = "ID #: " + animalID; + ourAnimals[petCount, 1] = "Species: " + animalSpecies; + ourAnimals[petCount, 2] = "Age: " + animalAge; + ourAnimals[petCount, 3] = "Nickname: " + animalNickname; + ourAnimals[petCount, 4] = "Physical description: " + animalPhysicalDescription; + ourAnimals[petCount, 5] = "Personality: " + animalPersonalityDescription; + + // increment petCount (the array is zero-based, so we increment the counter after adding to the array) + petCount = petCount + 1; + + // check maxPet limit + if (petCount < maxPets) + { + // another pet? + Console.WriteLine("Do you want to enter info for another pet (y/n)"); + do + { + readResult = Console.ReadLine(); + if (readResult != null) + { + anotherPet = readResult.ToLower(); + } + + } while (anotherPet != "y" && anotherPet != "n"); + } + //NOTE: The value of anotherPet (either "y" or "n") is evaluated in the while statement expression - at the top of the while loop + } + + if (petCount >= maxPets) + { + Console.WriteLine("We have reached our limit on the number of pets that we can manage."); + Console.WriteLine("Press the Enter key to continue."); + readResult = Console.ReadLine(); + } + + break; + + case "3": + // Ensure animal ages and physical descriptions are complete + Console.WriteLine("Challenge Project - please check back soon to see progress."); + Console.WriteLine("Press the Enter key to continue."); + readResult = Console.ReadLine(); + break; + + case "4": + // Ensure animal nicknames and personality descriptions are complete + Console.WriteLine("Challenge Project - please check back soon to see progress."); + Console.WriteLine("Press the Enter key to continue."); + readResult = Console.ReadLine(); + break; + + case "5": + // Edit an animal’s age"); + Console.WriteLine("UNDER CONSTRUCTION - please check back next month to see progress."); + Console.WriteLine("Press the Enter key to continue."); + readResult = Console.ReadLine(); + break; + + case "6": + // Edit an animal’s personality description"); + Console.WriteLine("UNDER CONSTRUCTION - please check back next month to see progress."); + Console.WriteLine("Press the Enter key to continue."); + readResult = Console.ReadLine(); + break; + + case "7": + // Display all cats with a specified characteristic + Console.WriteLine("UNDER CONSTRUCTION - please check back next month to see progress."); + Console.WriteLine("Press the Enter key to continue."); + readResult = Console.ReadLine(); + break; + + case "8": + // Display all dogs with a specified characteristic + Console.WriteLine("UNDER CONSTRUCTION - please check back next month to see progress."); + Console.WriteLine("Press the Enter key to continue."); + readResult = Console.ReadLine(); + break; + + default: + break; + } + +} while (menuSelection != "exit"); diff --git a/019_branching_and_looping_structures/ChallengeProject/Starter/Starter.csproj b/019_branching_and_looping_structures/ChallengeProject/Starter/Starter.csproj new file mode 100644 index 0000000..91b464a --- /dev/null +++ b/019_branching_and_looping_structures/ChallengeProject/Starter/Starter.csproj @@ -0,0 +1,10 @@ + + + + Exe + net8.0 + enable + enable + + +