diff --git a/026_Challenge_variabe_data/026_csharp.md b/026_Challenge_variabe_data/026_csharp.md
new file mode 100644
index 0000000..ee3f82d
--- /dev/null
+++ b/026_Challenge_variabe_data/026_csharp.md
@@ -0,0 +1,481 @@
+# Challenge project
+
+## Work with variable data in C#
+
+Demonstrate your ability to develop a console app that implements data
+formatting and using arrays to deliver a multiple term search feature.
+
+### Learning objectives
+
+Apply iteration statements using data input.
+
+- Process data.
+
+- Format data output.
+
+- Choose the correct data types and safely converting data types.
+
+- Create and manipulate string arrays, and sort array data.
+
+- Modify and build complex strings from multiple data sources, and format data
+for display.
+
+## Introduction
+
+Suppose you're one of the developers working on the Contoso Pets adoption
+application to help find new homes for pets. Your starting version of the
+application gathers a single search term used to search the descriptions of
+dogs. A single term search is helpful, but the feedback given from the team is
+the application needs more search functionality. The team wants you to extend
+the search functionality to allow for multiple term searches. Additionally, the
+team wants to pilot an update to the "search status" animation that shows
+search progress.
+
+In this challenge coding project, your C# data knowledge and skills are applied
+for:
+
+- Creating string arrays by splitting strings
+- Manipulating array data, iterating through elements in an array, and sorting array data
+- Modifying and building strings from multiple data sources
+
+In short, you'll:
+
+- Develop multi-term search functionality for the "dogs" search
+- Update the "search status" animation, information and countdown
+
+By the end of this module, you complete an updated version of the Contoso Pets
+application that searches all dogs available for adoption using multiple search
+terms and an improved search status simulation.
+
+---
+
+### Project specification overview
+
+Update the existing Contoso Pets starter application to include multiple term
+search and improved "search status" animation features:
+
+#### Add dog attribute multi-term search
+
+Gather user input for the pet characteristic multiple term search
+
+- Users need to provide search terms separated by commas
+- Store the search terms in an array and sort the terms alphabetically
+
+Within the animals array loop that identifies "dogs":
+
+- Iterate through the search terms to search each dog's description
+- Search the combined description for a term match
+- Output each dog's description where there's one or more terms matched
+
+After exiting the "search Animals" array loop that identifies dogs:
+
+If no dogs were a match for any of the users provided search terms, output a no
+dogs matched message.
+
+#### Add "search status" improvements
+
+Update the animation
+
+- Adjust the searchingIcons array to resemble a spinning dial
+- Adjust the animation loop so the animation shows a numeric countdown from two to zero (2.., 1.., 0..)
+
+#### Starter code
+
+The starter code project for this challenge project module includes a Program
+.cs file that provides 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
+
+The code uses a for loop around an if-elseif-else construct to populate the
+ourAnimals array with a sample dataset
+
+The code displays the following main menu options for user selection:
+
+ ```txt
+ 1. List all of our current pet information
+ 2. Display all dogs with a specified characteristic
+
+ Enter menu item selection or type "Exit" to exit the program
+ ```
+
+The application menu code reads the user's menu item selection and displays a
+message echoing their selection
+
+Case 1: "List all of our current pet information" displays the sample data for
+all animals (two dogs and two cats)
+
+Case 2: "2. Display all dogs with a specified characteristic" is the primary
+area where new functionality code is added
+
+ - Under Case 2, the starter code identifies dogs and searches for a single
+ user input term
+ - Before you search each dog, the console shows a simple "animation" that
+ simulates a status for searching occurring
+
+Your goal is to update the existing code to develop key features requested by
+your team:
+
+- Add dog multiple attribute search
+- Update search animation
+
+Use your development environment, and test your application at each stage of
+your development process.
+
+#### Setup
+
+Download a
+[zip](https://github.com/MicrosoftLearning/Challenge-project-Work-with-variable-data-in-CSharp/archive/refs/heads/main.zip)
+file containing the code folders for the challenge project.
+
+Build and run the file entering `dotnet run` in the terminal window.
+
+The menu should display with two options. Enter `1` as shown in the following
+terminal example:
+
+ ```txt
+ Welcome to the Contoso PetFriends app. Your main menu options are:
+ 1. List all of our current pet information
+ 2. Display all dogs with a specified characteristic
+
+ Enter your selection number (or type Exit to exit the program)
+ 1
+ ```
+
+The sample data on the current pets should display followed by the message
+`Press the Enter key to continue`
+
+After pressing Enter, the menu should display again. Choose Option `2`, shown
+in the following example:
+
+ ```txt
+ Welcome to the Contoso PetFriends app. Your main menu options are:
+ 1. List all of our current pet information
+ 2. Display all dogs with a specified characteristic
+
+ Enter your selection number (or type Exit to exit the program)
+ 2
+
+ Enter one desired dog characteristic to search for
+ ```
+
+Enter "large" for the search term and press "Enter."
+
+Notice the "searching" message as shown:
+
+```txt
+searching our dog Nickname: gus for large ...
+```
+
+Notice, the message runs before each search of a pet, and the periods
+(`., .., ...`) at the end change in an animation. Run the search again if you
+missed it.
+
+Once the search ends, press enter to return to the menu. Then type "exit" and
+press "Enter" to close the application.
+
+Take a few minutes to become familiar with the Project.cs started code.
+
+Focus on the areas that require updates, search and the animation.
+
+Notice that there are some comments left in the code that indicate where to
+place an update.
+
+You're now ready to begin the Guided project exercises. Good luck!
+
+---
+
+### Add multiple term search support
+
+The Contoso Pets app helps find new homes for abandoned pets. The team wants
+the search feature improved to let users enter multiple terms when searching
+for dogs to adopt.
+
+### Search specification
+
+In this first challenge exercise, you need to update the single term search
+feature to allow users to enter multiple search terms separated by commas.
+
+#### Gather multiple search terms from the user
+
+- Allow the user to enter multiple search terms when searching for dogs
+- The user needs instructions to "enter the search terms separated by commas"
+- Separate out individual search terms from the user entry string and store as
+values in an array
+- Sort the terms in the array in alphanumeric sort order
+
+#### Identify dogs with descriptions with matches for one, or more, user search term
+
+- As you identify a dog in the `animalsArray`, search for matches for each term
+the user has entered
+- For a term match, output a message with the dogs name and the term that is
+matched
+ - example: `Our dog Jake is a match for your search for sheppard!`
+- When all term searches complete for the current dog description:
+ - For one or more matches, output the nickname and description for the
+ current dog
+ - For one or more matches, track that there has been a match so you know not
+ to display an "no matches found for any available dogs" message (refer to the
+ next item)
+- After **all** dog searches complete with no matches, display a message "No
+matches found for any available dogs"
+
+#### Enforce the following validation rules
+
+- values can't be null
+- values can't have zero characters
+- any further restriction is up to the developer
+
+#### Code comments
+
+- Numbered code comments in the starter code offer suggestions
+- The comments are in a sequential order and only the comments starting with #1, #2, and #3 apply to this exercise of the challenge
+
+#### Sample output
+
+Review the following animated image
+
+Notice the temporary display of "`searching...`" followed by the current term
+(example: "`searching...retriever`")
+
+Notice the order the terms appear in search is now in alphanumeric
+
+Notice the messages for matches persist (example:
+"`Our dog lola is a chase match!`")
+
+Review the sample output in the following section, "How to check your work", to further clarify how to implement features
+
+### How to check your work
+
+To validate that your code satisfies the specified requirements.
+
+Build and run your app.
+
+> 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.
+
+The terminal command prompt should display as the starting point for the
+program
+
+At the command prompt, enter 2 menu:
+
+ ```txt
+ Welcome to the Contoso PetFriends app. Your main menu options are:
+ 1. List all of our current pet information
+ 2. Display all dogs with a specified characteristic
+
+ Enter your selection number (or type Exit to exit the program)
+ 2
+
+ Enter dog characteristics to search for separated by commas
+ ```
+
+At the command prompt, enter large, cream, golden to test when more than one
+search term matches the dog descriptions. Verify that the Terminal panel
+updates with a message similar to the code output sample:
+
+ ```txt
+ Enter dog characteristics to search for separated by commas
+ large, cream, golden
+
+ Our dog Nickname: lola matches your search for cream
+ Our dog Nickname: lola matches your search for golden
+ Nickname: lola (ID #: d1)
+ Physical description: medium sized cream colored female golden retriever weighing about 45 pounds. housebroken.
+ Personality: loves to have her belly rubbed and likes to chase her tail. gives lots of kisses.
+
+ Our dog Nickname: gus matches your search for golden
+ Our dog Nickname: gus matches your search for large
+ Nickname: gus (ID #: d2)
+ Physical description: large reddish-brown male golden retriever weighing about 85 pounds. housebroken.
+ Personality: 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.
+
+ Press the Enter key to continue
+ ```
+
+At the command prompt, press the enter key to continue to the main menu
+
+At the command prompt, enter 2 menu:
+
+ ```txt
+ Welcome to the Contoso PetFriends app. Your main menu options are:
+ 1. List all of our current pet information
+ 2. Display all dogs with a specified characteristic
+
+ Enter your selection number (or type Exit to exit the program)
+ 2
+
+ Enter dog characteristics to search for separated by commas
+ ```
+
+At the command prompt, enter big, grey, stripes to test when none of the search
+terms match dog descriptions. Verify that the Terminal panel updates with a
+message similar to the code output samples:
+
+ ```txt
+ Enter dog characteristics to search for separated by commas
+ big, grey, stripes
+
+ None of our dogs are a match for: big, grey, stripes
+
+
+ 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.
+
+Congratulations if you succeeded in this challenge exercise!
+
+---
+
+## Exercise
+
+### Add improved search animation
+
+The Contoso Pets app helps find new homes for abandoned pets. Part of the
+request for search feature improvement is to update the animated simulation
+indicating search progress.
+
+#### Search animation specification
+
+In this second challenge exercise, you need to update the search animation to
+resemble spinning and add a count down (2, 1, 0).
+
+#### Change the current "searching" animation icons
+
+Update the current animation "icons"
+`string[] searchingIcons = {". ", ".. ", "..."};`
+
+Use new icons that simulate spinning
+
+You can design the "searching" animation to display "spinning" to work
+differently than displayed in the animated image
+
+The "searching..." animation, should continue to be overwritten, after each
+animation completes so it stays on the same line, and so that it doesn't
+display after the animation stops.
+
+#### Add a countdown to the "searching" animation
+
+Review the previous animated image - note the countdown in the output
+"`searching...retriever / 2`"
+The previous number "`2`" displays as "`1`", and finally as "`0`", counting down
+Update the loop that contains the "searching" animation so that the loop can
+display a countdown
+
+##### Code comments
+
+- Numbered code comments in the starter code offer suggestions
+- The comments are in a sequential order and only the comments starting with #4, and #5 apply to this exercise of the challenge
+
+#### How to check your work
+
+To validate that your code satisfies the specified requirements, complete the
+instruction steps:
+
+Build and run your app.
+
+> 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.
+
+The terminal command prompt should display as the starting point for the
+program
+
+At the command prompt, enter 2 menu:
+
+ ```txt
+ Welcome to the Contoso PetFriends app. Your main menu options are:
+ 1. List all of our current pet information
+ 2. Display all dogs with a specified characteristic
+
+ Enter your selection number (or type Exit to exit the program)
+ 2
+
+ Enter dog characteristics to search for separated by commas
+ ```
+
+At the command prompt, enter **golden, big** and press enter to test the search
+status messages with animation and countdown
+
+Verify that the console panel updates with temporary "searching" status
+messages similar to the code output samples:
+
+ ```txt
+ Enter dog characteristics to search for separated by commas
+ golden, big
+
+ searching our dog Nickname: lola for big / 2
+ ```
+
+ ```txt
+ searching our dog Nickname: lola for big -- 1
+ ```
+
+ ```txt
+ searching our dog Nickname: lola for golden \ 1
+ ```
+
+ ```txt
+ searching our dog Nickname: lola for golden * 0
+ ```
+
+All the user entered search terms should display with the "`searching`" spin
+animation and countdown for each dog where the "searching our dog..." line in
+the output overwrites the previous line to create an animation
+
+Refer to the previous animated image of the running program for more examples
+of the "searching" status animation with countdown
+
+Validate after the searching has stopped, the "`searching`" animation and
+countdown no longer displays
+
+> 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.
+
+Congratulations if you succeeded in this exercise challenge!
+
+- [Challenge](./Challenge-Variable_data/Own/Program.cs)
+
+---
+
+### Summary
+
+Your challenge was to update an application to support multiple term search and
+to improve the "search status" information animation.
+
+In this module, you developed code that combines:
+
+- Iterate using data input.
+- Process data.
+- Format data output.
+- Choose the correct data types and safely convert data types.
+- Create and manipulate string arrays, and sort array data.
+- Modify and build complex strings from multiple data sources, and format data
+for display.
+
+You delivered functionality to your Contoso pet app team, including:
+
+- Gather the pet characteristics for multiple search term inputs.
+- Store search input terms in a sorted array.
+- Display the dogs that have a term match.
+- Provide an improved search status animation with a countdown.
diff --git a/026_Challenge_variabe_data/Challenge-Variable_data/Final/Final.csproj b/026_Challenge_variabe_data/Challenge-Variable_data/Final/Final.csproj
new file mode 100644
index 0000000..f02677b
--- /dev/null
+++ b/026_Challenge_variabe_data/Challenge-Variable_data/Final/Final.csproj
@@ -0,0 +1,10 @@
+
+
+
+ Exe
+ net7.0
+ enable
+ enable
+
+
+
diff --git a/026_Challenge_variabe_data/Challenge-Variable_data/Final/Program.cs b/026_Challenge_variabe_data/Challenge-Variable_data/Final/Program.cs
new file mode 100644
index 0000000..7964071
--- /dev/null
+++ b/026_Challenge_variabe_data/Challenge-Variable_data/Final/Program.cs
@@ -0,0 +1,207 @@
+// Final
+
+// ourAnimals array will store the following:
+string animalSpecies = "";
+string animalID = "";
+string animalAge = "";
+string animalPhysicalDescription = "";
+string animalPersonalityDescription = "";
+string animalNickname = "";
+string suggestedDonation = "";
+
+// variables that support data entry
+int maxPets = 8;
+string? readResult;
+string menuSelection = "";
+decimal decimalDonation = 0.00m;
+
+// array used to store runtime data
+string[,] ourAnimals = new string[maxPets, 7];
+
+// sample data 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 45 pounds. housebroken.";
+ animalPersonalityDescription = "loves to have her belly rubbed and likes to chase her tail. gives lots of kisses.";
+ animalNickname = "lola";
+ suggestedDonation = "85.00";
+ 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 = "gus";
+ suggestedDonation = "49.99";
+ break;
+
+ case 2:
+ animalSpecies = "cat";
+ animalID = "c3";
+ animalAge = "1";
+ animalPhysicalDescription = "small white female weighing about 8 pounds. litter box trained.";
+ animalPersonalityDescription = "friendly";
+ animalNickname = "snow";
+ suggestedDonation = "40.00";
+ break;
+
+ case 3:
+ animalSpecies = "cat";
+ animalID = "c4";
+ animalAge = "";
+ animalPhysicalDescription = "";
+ animalPersonalityDescription = "";
+ animalNickname = "lion";
+ suggestedDonation = "";
+
+ break;
+
+ default:
+ animalSpecies = "";
+ animalID = "";
+ animalAge = "";
+ animalPhysicalDescription = "";
+ animalPersonalityDescription = "";
+ animalNickname = "";
+ suggestedDonation = "";
+ 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;
+
+ if (!decimal.TryParse(suggestedDonation, out decimalDonation)) {
+ decimalDonation = 45.00m; // if suggestedDonation NOT a number, default to 45.00
+ }
+ ourAnimals[i, 6] = $"Suggested Donation: {decimalDonation:C2}";
+}
+
+// top-level menu options
+do {
+ // NOTE: the Console.Clear method is throwing an exception in debug sessions
+ 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. 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();
+ }
+
+ // switch-case to process the selected menu option
+ switch (menuSelection) {
+ case "1":
+ // list all pet info
+ for (int i = 0; i < maxPets; i++) {
+ if (ourAnimals[i, 0] != "ID #: ") {
+ Console.WriteLine();
+
+ for (int j = 0; j < 7; j++) {
+ Console.WriteLine(ourAnimals[i, j].ToString());
+ }
+ }
+ }
+
+ Console.WriteLine("\r\nPress the Enter key to continue");
+ readResult = Console.ReadLine();
+
+ break;
+
+ case "2":
+ // #1 Display all dogs with a multiple search characteristics
+
+ string dogCharacteristics = "";
+
+ while (dogCharacteristics == "") {
+ // #2 have user enter multiple comma separated characteristics to search for
+ Console.WriteLine($"\nEnter dog characteristics to search for separated by commas");
+ readResult = Console.ReadLine();
+
+ if (readResult != null) {
+ dogCharacteristics = readResult.ToLower();
+ Console.WriteLine();
+ }
+ }
+
+ string[] dogSearches = dogCharacteristics.Split(",");
+ // trim leading and trailing spaces from each search term
+ for (int i = 0; i < dogSearches.Length; i++) {
+ dogSearches[i] = dogSearches[i].Trim();
+ }
+
+ Array.Sort(dogSearches);
+ // #4 update to "rotating" animation with countdown
+ string[] searchingIcons = { " |", " /", "--", " \\", " *" };
+
+ bool matchesAnyDog = false;
+ string dogDescription = "";
+
+ // loops through the ourAnimals array to search for matching animals
+ for (int i = 0; i < maxPets; i++) {
+ if (ourAnimals[i, 1].Contains("dog")) {
+
+ // Search combined descriptions and report results
+ dogDescription = ourAnimals[i, 4] + "\n" + ourAnimals[i, 5];
+ bool matchesCurrentDog = false;
+
+ foreach (string term in dogSearches) {
+ // only search if there is a term to search for
+ if (term != null && term.Trim() != "") {
+ for (int j = 2; j > -1; j--) {
+ // #5 update "searching" message to show countdown
+ foreach (string icon in searchingIcons) {
+ Console.Write($"\rsearching our dog {ourAnimals[i, 3]} for {term.Trim()} {icon} {j.ToString()}");
+ Thread.Sleep(100);
+ }
+
+ Console.Write($"\r{new String(' ', Console.BufferWidth)}");
+ }
+
+ // #3a iterate submitted characteristic terms and search description for each term
+ if (dogDescription.Contains(" " + term.Trim() + " ")) {
+ // #3b update message to reflect current search term match
+
+ Console.WriteLine($"\rOur dog {ourAnimals[i, 3]} matches your search for {term.Trim()}");
+
+ matchesCurrentDog = true;
+ matchesAnyDog = true;
+ }
+ }
+ }
+
+ // #3d if the current dog is match, display the dog's info
+ if (matchesCurrentDog) {
+ Console.WriteLine($"\r{ourAnimals[i, 3]} ({ourAnimals[i, 0]})\n{dogDescription}\n");
+ }
+ }
+ }
+
+ if (!matchesAnyDog) {
+ Console.WriteLine("None of our dogs are a match found for: " + dogCharacteristics);
+ }
+
+ Console.WriteLine("\n\rPress the Enter key to continue");
+ readResult = Console.ReadLine();
+
+ break;
+
+ default:
+ break;
+ }
+}
+while (menuSelection != "exit");
diff --git a/026_Challenge_variabe_data/Challenge-Variable_data/LICENSE b/026_Challenge_variabe_data/Challenge-Variable_data/LICENSE
new file mode 100644
index 0000000..2080d95
--- /dev/null
+++ b/026_Challenge_variabe_data/Challenge-Variable_data/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/026_Challenge_variabe_data/Challenge-Variable_data/Own/Own.csproj b/026_Challenge_variabe_data/Challenge-Variable_data/Own/Own.csproj
new file mode 100644
index 0000000..2150e37
--- /dev/null
+++ b/026_Challenge_variabe_data/Challenge-Variable_data/Own/Own.csproj
@@ -0,0 +1,10 @@
+
+
+
+ Exe
+ net8.0
+ enable
+ enable
+
+
+
diff --git a/026_Challenge_variabe_data/Challenge-Variable_data/Own/Program.cs b/026_Challenge_variabe_data/Challenge-Variable_data/Own/Program.cs
new file mode 100644
index 0000000..c78e856
--- /dev/null
+++ b/026_Challenge_variabe_data/Challenge-Variable_data/Own/Program.cs
@@ -0,0 +1,434 @@
+const int max_pets = 8;
+bool exit = false;
+string? selection;
+const string WIP = "Under Construction - please check " +
+ "back next month to see progress.";
+const string separator = "+-------------------------------------" +
+ "----------------------------------------+";
+const string main_menu = $@"{separator}
+Welcome to the Contoso PetFriends app. Your main menu options are:
+{separator}
+
+ 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 characteristics.
+ 8. Display all dogs with a specified characteristics.
+
+ Enter menu item selection or type 'Exit' to exit the program
+{separator}";
+string[] description = {
+ "big sized female golden colored weighing 20 pounds. housebroken.",
+ "large dark-brown male siver back weighing 15 pounds. housebroken.",
+ "small white female weighing about 8 pounds. translucid.",
+ "medium size male. fluorescent at night.",
+ "medium size weighing 4 punds, orange with black lines.",
+};
+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.",
+ "mad but cute",
+ "loves to play with a rope",
+};
+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", "fly", "cat", "cat" };
+string[] abcd = { "a", "b", "c", "d" };
+string[] icons = { "", "", "" };
+decimal[] donations = { 85.00M, 49.99M, 40.00M, 45.00M };
+int[] nums = { 1, 2, 3, 4, 5, 6, 7, 8 };
+string[,] our_animals = new string[max_pets, 7];
+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];
+}
+
+decimal rand_dec(decimal[] choices) {
+ int indx = rand.Next(choices.Length);
+ return choices[indx];
+}
+
+string get_uniq_id(string[,] animals) {
+ for (int i = 0; i < max_pets - 4; i++) {
+ bool uniq_id = false;
+ 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(animals[j, 1]) && animals[j, 1] == id) {
+ uniq_id = false;
+ check = false;
+ break;
+ }
+ }
+ if (check) {
+ uniq_id = true;
+ return id;
+ }
+ }
+ }
+ return "?";
+}
+
+void populate_animals_array() {
+ for (int i = 0; i < max_pets - 4; i++) {
+ our_animals[i, 0] = rand_str(species);
+ our_animals[i, 1] = get_uniq_id(our_animals);
+ 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);
+ our_animals[i, 6] = $"{rand_dec(donations):C2}";
+ }
+}
+
+void press_enter(string msg = "\n\tPress 'Enter' to continue") {
+ print(msg, false);
+ Console.ReadLine();
+}
+
+void print_pets(string[,] animals) {
+ clear();
+ int outher_length = animals.GetLength(0);
+ int inner_length = animals.GetLength(1);
+ print(separator);
+ for (int j = 0; j < outher_length; j++) {
+ string[] animal = new string[inner_length];
+ for (int k = 0; k < animals.GetLength(1); k++) {
+ animal[k] = animals[j, k];
+ }
+ print_pet(animal);
+ }
+ press_enter();
+}
+
+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];
+ string donation = pet[6];
+ print($@" ID: {id} SPECIE: {specie}
+ NAME: {name} AGE: {age} {year_word}
+ DESCRIPTION: {desc}
+ PERSONALITY: {perso}
+ SUGGESTED DONATION: {donation}
+{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 is_integer = false,
+ bool is_money = false,
+ string[]? opts = null) {
+ bool invalid = true;
+ while (invalid) {
+ print(text, false);
+ string? usr_in = Console.ReadLine();
+ if (!string.IsNullOrEmpty(usr_in) && usr_in.Trim() != "") {
+ string resp = usr_in.Trim();
+ if (is_integer) {
+ int temp_int;
+ if (int.TryParse(resp, out temp_int)) {
+ return resp;
+ }
+ } else if (is_money) {
+ decimal temp_dec;
+ if (decimal.TryParse(resp, out temp_dec)) {
+ resp = $"{temp_dec:C2}";
+ return resp;
+ }
+ } else if (opts != null) {
+ resp = resp.ToLower();
+ if (opts.Contains(resp)) {
+ return resp;
+ } else {
+ print($"Please enter a valid option (", false);
+ foreach (string opt in opts) {
+ print($" {opt} ", false);
+ }
+ print(")");
+ }
+ } else {
+ return resp;
+ }
+ }
+ }
+ 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: ", false, false, species);
+ string name = get_input("Enter the pet name (? if unknown): ");
+ int age = Int32.Parse(get_input("Enter pet age (-1 if unknown): ", true));
+ string donation = get_input("Enter suggested donation: ", false, true);
+ string desc = get_input("Enter the physical description (? if unknown): ");
+ string perso = get_input("Enter pet personality (? if unknown): ");
+ 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;
+ animals[at_indx, 6] = donation;
+}
+
+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();
+}
+
+void check_age_and_desc(string[,] animals) {
+ clear();
+ print("\nEnsure animal ages and physical descriptions are complete");
+ int pet_count = max_pets - (availability(animals));
+ for (int j = 0; j < pet_count; j++) {
+ if (animals[j, 3] == "-1") {
+ print("\n" + separator);
+ string[] animal = {
+ animals[j,0], animals[j,1], animals[j,2],
+ animals[j,3], animals[j,4], animals[j,5]
+ };
+ print_pet(animal);
+ int age = Int32.Parse(
+ get_input(
+ $"Enter an age for ID: {animals[j, 1]}" +
+ " (-1 if unknown): ", true
+ )
+ );
+ animals[j, 3] = age.ToString();
+ }
+ if (animals[j, 2] == "?") {
+ print("\n" + separator);
+ string[] animal = {
+ animals[j,0], animals[j,1], animals[j,2],
+ animals[j,3], animals[j,4], animals[j,5]
+ };
+ print_pet(animal);
+ string desc = get_input(
+ $"Enter a physical description for ID: {animals[j, 1]}" +
+ " (? if unknown): "
+ );
+ animals[j, 2] = desc;
+ }
+ }
+ press_enter();
+}
+
+void check_nick_and_perso(string[,] animals) {
+ clear();
+ print("Ensure animal nicknames and personality descriptions are complete");
+ print(separator);
+ int pet_count = max_pets - (availability(animals));
+ for (int j = 0; j < pet_count; j++) {
+ if (animals[j, 5] == "?") {
+ print("\n" + separator);
+ string[] animal = {
+ animals[j,0], animals[j,1], animals[j,2],
+ animals[j,3], animals[j,4], animals[j,5]
+ };
+ print_pet(animal);
+ string nick = get_input(
+ $"Enter a nickname for ID: {animals[j, 1]}" +
+ "(? if unknown): "
+ );
+ animals[j, 5] = nick;
+ }
+ if (animals[j, 4] == "?") {
+ print("\n" + separator);
+ string[] animal = {
+ animals[j,0], animals[j,1], animals[j,2],
+ animals[j,3], animals[j,4], animals[j,5]
+ };
+ print_pet(animal);
+ string perso = get_input(
+ $"Enter a personality description for ID: {animals[j, 1]}" +
+ "(? if unknown): "
+ );
+ animals[j, 4] = perso;
+ }
+ }
+ press_enter();
+}
+
+bool search(string specie, string detail, string[,] animals) {
+ bool found = false;
+ for (int j = 0; j < animals.GetLength(0); j++) {
+ if (!string.IsNullOrEmpty(animals[j, 1])) {
+ if (animals[j, 0] == specie) {
+ for (int i=2; i>-1; i--) {
+ foreach (string icon in icons){
+ print(
+ $"\rsearching our {specie} {animals[j, 5]}" +
+ $" for {detail.Trim()} {icon} {i.ToString()}",
+ false
+ );
+ Thread.Sleep(200);
+ }
+ print($"\r{new String(' ', Console.BufferWidth)}", false);
+ }
+ string description = " " + animals[j, 2] +
+ "\n " + animals[j, 4];
+ if (description.Contains(detail)) {
+ found = true;
+ print($"\r{separator}");
+ print($"Our {specie} {animals[j, 5]} is a match!");
+ print($"{description}");
+ }
+ }
+ }
+ }
+ return found;
+}
+
+void search_specie_by_desc(string specie, string[,] animals) {
+ clear();
+ bool found = false;
+ string detail = get_input(
+ $"Enter {specie} characteristics to search for separated by commas: "
+ );
+ if (detail.IndexOf(',') >= 0) {
+ string[] details = detail.Split(',');
+ foreach (string characteristic in details) {
+ found = search(specie, characteristic.Trim(), animals);
+ }
+ } else {
+ found = search(specie, detail, animals);
+ }
+ if (!found) {
+ print($"None of our {specie}s are a match found for: {detail}");
+ }
+ print(separator);
+ press_enter();
+}
+
+populate_animals_array();
+
+while (!exit) {
+ clear();
+ print(main_menu);
+ print(" >_", false);
+ selection = Console.ReadLine();
+ if (selection != null && options.Contains(selection.ToLower())) {
+ selection = selection.ToLower();
+ switch (selection) {
+ case "1":
+ print_pets(our_animals);
+ break;
+ case "2":
+ ask_new_pet();
+ break;
+ case "3":
+ check_age_and_desc(our_animals);
+ break;
+ case "4":
+ check_nick_and_perso(our_animals);
+ break;
+ case "5":
+ clear();
+ print(WIP);
+ press_enter();
+ break;
+ case "6":
+ clear();
+ print(WIP);
+ press_enter();
+ break;
+ case "7":
+ search_specie_by_desc("cat", our_animals);
+ break;
+ case "8":
+ search_specie_by_desc("dog", our_animals);
+ break;
+ case "exit":
+ print("\n\tClosing 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/026_Challenge_variabe_data/Challenge-Variable_data/Starter/Program.cs b/026_Challenge_variabe_data/Challenge-Variable_data/Starter/Program.cs
new file mode 100644
index 0000000..237b5f4
--- /dev/null
+++ b/026_Challenge_variabe_data/Challenge-Variable_data/Starter/Program.cs
@@ -0,0 +1,188 @@
+// ourAnimals array will store the following:
+string animalSpecies = "";
+string animalID = "";
+string animalAge = "";
+string animalPhysicalDescription = "";
+string animalPersonalityDescription = "";
+string animalNickname = "";
+string suggestedDonation = "";
+
+// variables that support data entry
+int maxPets = 8;
+string? readResult;
+string menuSelection = "";
+decimal decimalDonation = 0.00m;
+
+// array used to store runtime data
+string[,] ourAnimals = new string[maxPets, 7];
+
+// sample data 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 45 pounds. housebroken.";
+ animalPersonalityDescription = "loves to have her belly rubbed and likes to chase her tail. gives lots of kisses.";
+ animalNickname = "lola";
+ suggestedDonation = "85.00";
+ 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 = "gus";
+ suggestedDonation = "49.99";
+ break;
+
+ case 2:
+ animalSpecies = "cat";
+ animalID = "c3";
+ animalAge = "1";
+ animalPhysicalDescription = "small white female weighing about 8 pounds. litter box trained.";
+ animalPersonalityDescription = "friendly";
+ animalNickname = "snow";
+ suggestedDonation = "40.00";
+ break;
+
+ case 3:
+ animalSpecies = "cat";
+ animalID = "c4";
+ animalAge = "";
+ animalPhysicalDescription = "";
+ animalPersonalityDescription = "";
+ animalNickname = "lion";
+ suggestedDonation = "";
+
+ break;
+
+ default:
+ animalSpecies = "";
+ animalID = "";
+ animalAge = "";
+ animalPhysicalDescription = "";
+ animalPersonalityDescription = "";
+ animalNickname = "";
+ suggestedDonation = "";
+ 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;
+
+ if (!decimal.TryParse(suggestedDonation, out decimalDonation)) {
+ decimalDonation = 45.00m; // if suggestedDonation NOT a number, default to 45.00
+ }
+ ourAnimals[i, 6] = $"Suggested Donation: {decimalDonation:C2}";
+}
+
+// top-level menu options
+do {
+ // NOTE: the Console.Clear method is throwing an exception in debug sessions
+ 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. 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();
+ }
+
+ // switch-case to process the selected menu option
+ switch (menuSelection) {
+ case "1":
+ // list all pet info
+ for (int i = 0; i < maxPets; i++) {
+ if (ourAnimals[i, 0] != "ID #: ") {
+ Console.WriteLine();
+ for (int j = 0; j < 7; j++) {
+ Console.WriteLine(ourAnimals[i, j].ToString());
+ }
+ }
+ }
+
+ Console.WriteLine("\r\nPress the Enter key to continue");
+ readResult = Console.ReadLine();
+
+ break;
+
+ case "2":
+ // #1 Display all dogs with a multiple search characteristics
+
+ string dogCharacteristic = "";
+
+ while (dogCharacteristic == "") {
+ // #2 have user enter multiple comma separated characteristics to search for
+ Console.WriteLine($"\r\nEnter one desired dog characteristic to search for");
+ readResult = Console.ReadLine();
+ if (readResult != null) {
+ dogCharacteristic = readResult.ToLower().Trim();
+ Console.WriteLine();
+ }
+ }
+
+ bool noMatchesDog = true;
+ string dogDescription = "";
+
+ // #4 update to "rotating" animation with countdown
+ string[] searchingIcons = { ". ", ".. ", "..." };
+
+ // loop ourAnimals array to search for matching animals
+ for (int i = 0; i < maxPets; i++) {
+
+ if (ourAnimals[i, 1].Contains("dog")) {
+
+ // Search combined descriptions and report results
+ dogDescription = ourAnimals[i, 4] + "\r\n" + ourAnimals[i, 5];
+
+ for (int j = 5; j > -1; j--) {
+ // #5 update "searching" message to show countdown
+ foreach (string icon in searchingIcons) {
+ Console.Write($"\rsearching our dog {ourAnimals[i, 3]} for {dogCharacteristic} {icon}");
+ Thread.Sleep(250);
+ }
+
+ Console.Write($"\r{new String(' ', Console.BufferWidth)}");
+ }
+
+ // #3a iterate submitted characteristic terms and search description for each term
+
+ if (dogDescription.Contains(dogCharacteristic)) {
+ // #3b update message to reflect term
+ // #3c set a flag "this dog" is a match
+ Console.WriteLine($"\nOur dog {ourAnimals[i, 3]} is a match!");
+
+ noMatchesDog = false;
+ }
+
+ // #3d if "this dog" is match write match message + dog description
+ }
+ }
+
+ if (noMatchesDog) {
+ Console.WriteLine("None of our dogs are a match found for: " + dogCharacteristic);
+ }
+
+ Console.WriteLine("\n\rPress the Enter key to continue");
+ readResult = Console.ReadLine();
+
+ break;
+
+ default:
+ break;
+ }
+
+} while (menuSelection != "exit");
diff --git a/026_Challenge_variabe_data/Challenge-Variable_data/Starter/Starter.csproj b/026_Challenge_variabe_data/Challenge-Variable_data/Starter/Starter.csproj
new file mode 100644
index 0000000..f02677b
--- /dev/null
+++ b/026_Challenge_variabe_data/Challenge-Variable_data/Starter/Starter.csproj
@@ -0,0 +1,10 @@
+
+
+
+ Exe
+ net7.0
+ enable
+ enable
+
+
+
diff --git a/README.md b/README.md
index a265548..8dbb433 100644
--- a/README.md
+++ b/README.md
@@ -30,3 +30,4 @@ Following
23. [Format alphanumeric data](./023_alphanumeric_data_format/023_csharp.md)
24. [String data type methods](./024_String_data_type_methods/024_csharp.md)
25. [Work with variable data](./025_Work_with_variable_data/025_csharp.md)
+26. [Challenge - variable data](./026_Challenge_variabe_data/026_csharp.md)