diff --git a/025_Work_with_variable_data/025_csharp.md b/025_Work_with_variable_data/025_csharp.md
new file mode 100644
index 0000000..06b126b
--- /dev/null
+++ b/025_Work_with_variable_data/025_csharp.md
@@ -0,0 +1,704 @@
+# Guided 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 search feature.
+
+### Learning objectives
+
+- Apply iteration statements to gather data input.
+
+- Use data processing.
+
+- Format data output.
+
+- Choose the correct data types and safely convert data types.
+
+- Manipulate number, string and character arrays, as well as add, remove, and
+sort data.
+
+- Modify and build complex strings from multiple data sources, and format data
+for display across regions.
+
+## Introduction
+
+Suppose you're a developer who likes to support the local community. You and
+some of your friends started a business that helps find new homes for stray or
+abandoned cats and dogs. Your business started off small, with just a couple of
+animals, but it's starting to grow. Your friends have an initial application
+developed that enables the entry and display of the animals available for
+adoption. They ask you to investigate adding features to the app that could
+help to match the animals in your care with people who are looking for a new
+family pet.
+
+In completing this coding project, you apply your C# data knowledge and skills
+in:
+
+- Choosing the correct data types and safely converting data types.
+- Create two dimensional arrays of numbers and strings.
+- Search data in arrays to display or update data.
+- Modifying and building complex strings from multiple data sources, and
+formatting data for display across regions.
+
+Your team has found that it's important to search the pet data to identify
+animals with possible matches based on characteristics provided by potential
+owners. Further, the team wants to include a fundraising feature to include
+suggested donation data and to present the pet data with fewer lines of output.
+
+You begin with a starting application that adds a predefined sample data to the
+pets array. The application has two menu items. The first item displays all the
+pet data, and the code is complete. The second is menu item, "Display all dogs
+with a specified characteristic", is "work in progress" that you complete.
+
+You also make updates to existing code to add `suggestedDonation` data and
+display all data in a shortened format.
+
+By the end of this module, you're able to develop code that combines iteration
+statements with data input, data processing, string indexing, and data output.
+
+---
+
+### Prepare for guided project
+
+Develop a version of a C# console application. The application comes with the
+basic features that create sample data on pets available for adoption and is
+able to display the pet's information. The main feature to add is searching
+available dogs using a single search term. The secondary tasks include adding
+and displaying suggestedDonation data.
+
+### The design specification
+
+For the new features of the Contoso Pets application, the design specification
+provides details for the dog search and suggested donation features:
+
+- Dog attribute search
+ - Gather input for the pet characteristic search term
+ - Loop through the animals array and identify "dogs"
+ - For each dog, combine the physical and personality descriptions to search
+ - Search the combined description for the input term match
+ - Output the dogs that have a term match
+
+- Suggested donation data
+ - Define `suggestedDonation` string
+ - Expand the `ourAnimals` array to contain `suggestedDonation` and populate
+ sample data for `suggestedDonation`
+ - Ensure all usage of `ourAnimals` array accounts for the added
+ `suggestedDonation` data
+ - Output `suggestedDonation` with regional currency symbol ($, €, ¥,... )
+
+#### Starter code overview
+
+Initial starter code development is complete.
+
+The Starter project for this guided 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`-`else if`-`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 code reads the user's menu item selection and displays a message
+echoing their selection
+
+- only selection "1. List all of our current pet information" functions using
+the starter code
+
+Your goal is to update the existing code to develop app features described
+previously. The key features:
+
+- Add dog attribute search
+- Include suggested donation data
+
+Use your development environment, and you test your application at each stage
+of your development process.
+
+#### Setup
+
+Download the zip file containing the code folders for the guided
+[project](https://github.com/MicrosoftLearning/Guided-project-Work-with-variable-data-in-CSharp/archive/refs/heads/main.zip)
+and then extract.
+
+- [Contoso](../019_branching_and_looping_structures/ChallengeProject/Own/Program.cs)
+
+You're now ready to begin the Guided project exercises. Good luck!
+
+---
+
+## Exercise
+
+### Review starter code
+
+In this first step of the development process, you review the code provided in
+the Starter project folder.
+
+#### Review the contents of the Program.cs file
+
+The Program.cs file contains a preliminary version of the application that you
+'re working on. The code includes features to generate and display the sample
+data for the application, and it displays a list of menu options that define
+the main features of the application.
+
+Take a few minutes to review the initial variable declarations at the top of
+the Program.cs file.
+
+```cs
+// #1 the ourAnimals array will store the following:
+string animalSpecies = "";
+string animalID = "";
+string animalAge = "";
+string animalPhysicalDescription = "";
+string animalPersonalityDescription = "";
+string animalNickname = "";
+
+// #2 variables that support data entry
+int maxPets = 8;
+string? readResult;
+string menuSelection = "";
+
+// #3 array used to store runtime data, there is no persisted data
+string[,] ourAnimals = new string[maxPets, 6];
+```
+
+First, you see a comment (comment #1) followed by a list of variables. These
+variables, `animalSpecies` through `animalNickname`, used to hold the values of
+the pet characteristics within a multidimensional string array named
+`ourAnimals`, and initialized to contain a zero length string `""`. The
+`ourAnimals` array declaration is a little further down in the code.
+
+The next group of variables (under comment #2) are a mix of `string` and `int`
+variables used to help generate sample data, read user input, and establish
+exit criteria for the main program loop. Notice the code line
+`string? readResult;`. You use the `?` character to transform a normally
+non-nullable variable type (int, string, bool,...) with support for the
+nullable type.
+
+> Note
+> When reading user entered values with the `Console.ReadLine()` method, it's
+best to enable a nullable type string using string? to avoid the code compiler
+generating a warning when you build the project.
+
+The final variable (under comment #3) is the two-dimensional string array named
+`ourAnimals`. You initialized the number of rows, defined by maxPets, to 8. The
+number of characteristics that you're storing initially is six. The six
+characteristics match the number of string variables that you examined in the
+sample code, but the number of characteristics needs to expand to add a field
+for `suggestedDonation`.
+
+Scroll down the Program.cs file to examine the `for` loop that contains a
+`switch` selection construct within its code block.
+
+The code sample is a shortened version to save space.
+
+```cs
+// #4 create 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";
+ 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";
+ break;
+ // case 2: deleted for brevity
+ // case 3: deleted for brevity
+ 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;
+}
+```
+
+Notice that the `for` loop uses the `maxPets` variable to establish an upper
+bound on the number of iterations following comment # 4.
+
+Also notice that the `switch` construct selectively branches the code so that
+you can define different pet characteristics for the pets in the sample data
+set.
+
+You use a `switch` statement to define different values for the first four
+iterations of the `for` loop. After the sample data processing, all
+characteristics are empty, or zero-length, string.
+
+The values of the animal characteristic variables are assigned to the
+`ourAnimals` array at the bottom of the for loop.
+
+Scroll to the bottom of the code file. Examine the code used to display the
+menu options and capture the input of the user's selection.
+
+You should observe the following code:
+
+```cs
+// #5 display the 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();
+ }
+ // use 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 < 6; j++) {
+ Console.WriteLine(ourAnimals[i, j]);
+ }
+ }
+ }
+ Console.WriteLine("\n\rPress the Enter key to continue");
+ readResult = Console.ReadLine();
+ break;
+ case "2":
+ // Display all dogs with a specified characteristic");
+ Console.WriteLine("\nUNDER 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");
+```
+
+Take a minute to review the two `case` statements.
+
+There are only two menu options working with a limited version of the
+application. The starter application provides only the capabilities needed for
+running and testing features prototype.
+
+Notice the line of code is `readResult = Console.ReadLine();` is followed by a
+check for a null value.
+
+The code using the `Console.ReadLine()` method, has the value set to the
+nullable string `readResult` to avoid the code compiler generating a warning
+when you build the project.
+
+#### Check your work
+
+Test the starter code console app, at the TERMINAL command prompt build & run
+your project code with one command by entering: `dotnet run`.
+
+When the code runs, two menu items are displayed.
+
+- Enter "`1`" to test the "List all of our current pet information" output
+- Enter "`2`" to test the placeholder message "under construction" message
+
+Enter 1 followed by pressing the Enter key to "display all pets".
+
+Check that all of the pet information displays.
+
+As you observe the data on all pets, the last pet displayed should match the
+following output:
+
+```txt
+ID #: c4
+Species: cat
+Age: 3
+Nickname: Lion
+Physical description: Medium sized, long hair, yellow, female, about 10 pounds. Uses litter box.
+Personality: A people loving cat that likes to sit on your lap.
+
+Press the Enter key to continue
+```
+
+Press the Enter key to continue and return to the menu.
+
+At the menu prompt, enter `2` followed by pressing the Enter key.
+
+This choice is a place holder for "Display all dogs with a specified
+characteristic" functionality.
+
+Check that the "UNDER CONSTRUCTION" message displays for "Display all dogs with
+a specified characteristic" selection.
+
+You should observe the following output:
+
+```txt
+UNDER CONSTRUCTION - please check back next month to see progress.
+Press the Enter key to continue.
+```
+
+Type `exit`, at the app menu, to end the program and then close the terminal
+panel.
+
+The program should exit.
+
+Now you're ready to start developing the new features.
+
+---
+
+## Exercise
+
+### Add suggested donation data
+
+In this step of the development process, you update the code provided in the
+starter project folder, adding features for "suggested donation" to the
+application.
+
+#### Create the "Suggested Donation" features
+
+The added donation features require you to create `suggestedDonation` variable,
+and to expand the `ourAnimals` array accommodate the new donation data. Also,
+you need to add the suggested donation amounts for each animal, and implement a
+default amount when there suggested donation information is missing.
+
+##### Add support for suggested donation data
+
+You need to create a new variable to hold suggested donations and expand the
+`ourAnimals` array to hold the new data.
+
+Notice the code under comment #1 that declares variables used for populating
+the `ourAnimals` array for each animal.
+
+You need to declare another string for the suggested donation data.
+
+```cs
+// #1 the ourAnimals array will store the following:
+string animalSpecies = "";
+string animalID = "";
+string animalAge = "";
+string animalPhysicalDescription = "";
+string animalPersonalityDescription = "";
+string animalNickname = "";
+```
+
+Create the `suggestedDonation` variable below the declaration for
+`animalNickname`.
+
+The declaration for the `suggestedDonation` is added with the following
+code:
+
+```cs
+string suggestedDonation = "";
+```
+
+Locate the code to create the `ourAnimals` array following comment # 3.
+
+The following line of code creates the array:
+
+```cs
+string[,] ourAnimals = new string[maxPets, 6];
+```
+
+The sizes defining the two dimensions of the array are the maximum number of
+pets `maxPets` and the number `6` for the six strings originally defined, but
+without room for the new `suggestedDonation` data.
+
+Update `ourAnimals` array to hold `7` "columns" of data for each animal instead
+of `6`.
+
+The following line shows the updated code:
+
+```cs
+string[,] ourAnimals = new string[maxPets, 7];
+```
+
+You've expanded the `ourAnimals` array to support the added `suggestedDonation`
+data.
+
+#### Add suggestedDonation amounts to the sample data
+
+Take a minute to review `case 0:` inside the switch statement following comment
+#4.
+
+The following code that defines sample data for the first pet before the
+`suggestedDonation` data is created. It would fit nicely below the
+`animalNickname`!
+
+```cs
+ 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";
+ break;
+```
+
+Insert a `suggestedDonation` value above the `break` statement for `case 0;`
+through `default:` with the following values:
+
+- Case 0: `suggestedDonation = "85.00";`
+- Case 1: `suggestedDonation = "49.99";`
+- Case 2: `suggestedDonation = "40.00";`
+- Case 3: `suggestedDonation = "";`
+- default: `suggestedDonation = "";`
+
+The following code shows `case 0:` code with the addition of
+'suggestedDonation':
+
+```cs
+ 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;
+```
+
+In your project.cs file, locate the following array populated with the pet data
+from case statements (it's just before comment # 5):
+
+```cs
+ 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;
+```
+
+Notice that `suggestedDonation` data isn't included as part of the sample data
+starter code for populating the array.
+
+It makes sense to populate the array with a statement like:
+
+```cs
+ourAnimals[i, 6] = "Suggested Donation: " + suggestedDonation;
+```
+
+But, you won't add that code. In the next section you'll use another approach.
+
+#### Data validation with `TryParse()`
+
+The variable `suggestedDonation` is intended to be a numeric value, but is
+collected and stored as a `string`. In the future you may have to validate
+`suggestedDonation` represents a decimal, and that you can convert it to a
+decimal so it's available to use for billing calculations. To avoid an error
+trying to use an entry like `twenty` you need to use `TryParse` validation.
+
+> Note
+> The code samples in this exercise are designed based on en-US culture setting
+s, and use a period (`.`) as the decimal separator. Building and running the
+code with a culture setting that uses a different decimal separators (such as a
+comma `,`) may give unexpected results or errors. To fix this issue, replace the
+period decimal separators in the code samples with your local decimal separator
+(such as `,`). Alternatively, to run a program using the en-US culture setting,
+add the following code to the top of your program: `using System.Globalization;`
+and after any other `using` statements add
+`CultureInfo.CurrentCulture = new CultureInfo("en-US");`.
+
+Before comment #5, inside the end of the code block, add the code to validate
+that `suggestedDonation` can be cast as a decimal.
+
+You add the following:
+
+```cs
+if (!decimal.TryParse(suggestedDonation, out decimalDonation)) {
+ decimalDonation = 45.00m; // if suggestedDonation NOT a number, default to 45.00
+}
+````
+
+If the `suggestedDonation` variable can't be cast as a `decimal` the code
+assigns a default value `decimalDonation = 45.00m;`. If the cast is successful,
+the `TryParse` populates `decimalDonation`. Either way, `decimalDonation`
+represents a proper decimal.
+
+Ensure that your validation code is in the right place!
+
+The two lines you added should appear in the code as the top two lines of the
+following code:
+
+```cs
+ if (!decimal.TryParse(suggestedDonation, out decimalDonation)){
+ decimalDonation = 45.00m; // if suggestedDonation NOT a number, default to 45.00
+ }
+}
+
+// #5 display the top-level menu options
+```
+
+Note, validation still doesn't work. You can't forget, the need to declare
+`decimalDonation` to use it in the code.
+
+Following the comment #2, declare `decimalDonation`, after
+`string menuSelection = "";`:
+
+```cs
+decimal decimalDonation = 0.00m;
+```
+
+Finally you're ready to populate `suggestedDonation` data for each pet.
+
+Above comment #5, immediately after the `TryParse` closing bracket `}` you
+completed, add the following code:
+
+```cs
+ourAnimals[i, 6] = $"Suggested Donation: {decimalDonation:C2}";
+```
+
+You used the `decimalDonation` version of the suggested donation data. You also
+used string interpolation and currency formatting in the output.
+
+Take a minute to review how the suggested donation data finally makes it into
+the `ourAnimals` array.
+
+The following code populates the `decimalAnimals` in context of the
+`TryParse()`:
+
+```cs
+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}";
+}
+
+// #5 display the top-level menu options
+```
+
+Notice that by using the code `{decimalDonation:C2}` the suggested donation,
+from `decimalDonation`, will display with the local currency symbol and two
+decimal places as directed by the currency formatting `:C2`.
+
+#### Review and update where ourAnimals array should be used
+
+The addition of the `suggestedDonation` data created need for further updates.
+The menu option `"1. List all of our current pet information"` is missing the
+added data.
+
+Notice the code under comment #5, for the menu loop within `case 1`.
+
+The inner loop "`for (int j = 0; j < 6; j++)`" that prints the pet attributes
+needs to account for `suggestedDonation` data added.
+
+Update the inner loop code exit condition. Increased the exit condition by "1",
+so it becomes `j <7`. Check that your code matches the following:
+
+```cs
+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++) { // increased exit condition
+ Console.WriteLine(ourAnimals[i, j]);
+ }
+ }
+}
+```
+
+#### Testing Overview
+
+With several code additions in place, you need to confirm your code works as
+expected. The two significant test areas are:
+
+The code complies without errors.
+
+Selecting menu option 1 all pet information displays:
+
+- Output includes all of sample pet information, including: ID, species, age,
+nickname, physical description, and personality description.
+- For each pet, the suggested donation displays with a currency symbol and with
+two decimal places of precision.
+
+#### Check your work
+
+Build and run to test the code.
+
+At the TERMINAL command prompt, to build your project code, enter the following
+command: `dotnet build`
+
+After a couple seconds, you should see a message telling you that your build
+succeeded, and that you have 0 Warning(s) and 0 Error(s).
+
+The solution code may look considerably different than the Program.cs code that
+you've developed at this point in the Guided project. However, you can try
+examining the Program.cs code in Final to help you isolate and fix an issue in
+your code if you need to.
+
+Try not to limit your use the solution code. Remember that you learn from
+mistakes and that every developer spends time finding and fixing errors.
+
+Test the updated console app, at the TERMINAL command prompt build & run your
+project code with one command by entering: `dotnet run`. When the code runs two
+menu items display.
+
+- Enter "1" to test the "display all pets" output
+- Enter "2" to test the placeholder message "under construction" message
+
+The output for menu item #1 should closely match the following sample:
+
+```txt
+ID #: d1
+Species: dog
+Age: 2
+Nickname: lola
+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.
+Suggested Donation: $85.00
+
+ID #: d2
+Species: dog
+Age: 9
+Nickname: gus
+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.
+Suggested Donation: $49.99
+
+ID #: c3
+Species: cat
+Age: 1
+Nickname: snow
+Physical description: small white female weighing about 8 pounds. litter box trained.
+Personality: friendly
+Suggested Donation: $40.00
+
+ID #: c4
+Species: cat
+Age:
+Nickname: lion
+Physical description:
+Personality:
+Suggested Donation: $45.00
+```
+
+If everything worked as expected, congratulations! Otherwise, look for the
+error by checking code instruction steps involved. If needed, start over with a
+new starter Project.cs file and if you still have issues check the solution
+folder code for this exercise.
+
+Type exit, at the app menu, to end the program and then close the terminal
+panel.
diff --git a/025_Work_with_variable_data/GuidedProject/Final/Final.csproj b/025_Work_with_variable_data/GuidedProject/Final/Final.csproj
new file mode 100644
index 0000000..f02677b
--- /dev/null
+++ b/025_Work_with_variable_data/GuidedProject/Final/Final.csproj
@@ -0,0 +1,10 @@
+
+
+
+ Exe
+ net7.0
+ enable
+ enable
+
+
+
diff --git a/025_Work_with_variable_data/GuidedProject/Final/Program.cs b/025_Work_with_variable_data/GuidedProject/Final/Program.cs
new file mode 100644
index 0000000..49dbc35
--- /dev/null
+++ b/025_Work_with_variable_data/GuidedProject/Final/Program.cs
@@ -0,0 +1,189 @@
+// using System;
+
+// #1 the ourAnimals array will store the following:
+string animalSpecies = "";
+string animalID = "";
+string animalAge = "";
+string animalPhysicalDescription = "";
+string animalPersonalityDescription = "";
+string animalNickname = "";
+string suggestedDonation = "";
+
+// #2 variables that support data entry
+int maxPets = 8;
+string? readResult;
+string menuSelection = "";
+decimal decimalDonation = 0.00m;
+
+// #3 array used to store runtime data, there is no persisted data
+string[,] ourAnimals = new string[maxPets, 7];
+
+// #4 create 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}";
+}
+
+// #5 display the 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();
+ }
+
+ // use 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("\n\rPress the Enter key to continue");
+ readResult = Console.ReadLine();
+
+ break;
+
+ case "2":
+ // Display all dogs with a specified characteristic");
+
+ string dogCharacteristic = "";
+
+ while (dogCharacteristic == "")
+ {
+ // have the user enter physical characteristics to search for
+ Console.WriteLine($"\nEnter one desired dog characteristics to search for");
+ readResult = Console.ReadLine();
+ if (readResult != null)
+ {
+ dogCharacteristic = readResult.ToLower().Trim();
+ }
+ }
+
+ bool noMatchesDog = true;
+ string dogDescription = "";
+
+ // #6 loop through the ourAnimals array to search for matching animals
+ for (int i = 0; i < maxPets; i++)
+ {
+ bool dogMatch = true;
+
+ if (ourAnimals[i, 1].Contains("dog"))
+ {
+
+ if (dogMatch == true)
+ {
+ // #7 Search combined descriptions and report results
+ dogDescription = ourAnimals[i, 4] + "\n" + ourAnimals[i, 5];
+
+
+ if (dogDescription.Contains(dogCharacteristic))
+ {
+ Console.WriteLine($"\nOur dog {ourAnimals[i, 3]} is a match!");
+ Console.WriteLine(dogDescription);
+
+ noMatchesDog = false;
+ }
+ }
+ }
+ }
+
+ 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/025_Work_with_variable_data/GuidedProject/LICENSE b/025_Work_with_variable_data/GuidedProject/LICENSE
new file mode 100644
index 0000000..2080d95
--- /dev/null
+++ b/025_Work_with_variable_data/GuidedProject/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/025_Work_with_variable_data/GuidedProject/Own/Own.csproj b/025_Work_with_variable_data/GuidedProject/Own/Own.csproj
new file mode 100644
index 0000000..2150e37
--- /dev/null
+++ b/025_Work_with_variable_data/GuidedProject/Own/Own.csproj
@@ -0,0 +1,10 @@
+
+
+
+ Exe
+ net8.0
+ enable
+ enable
+
+
+
diff --git a/025_Work_with_variable_data/GuidedProject/Own/Program.cs b/025_Work_with_variable_data/GuidedProject/Own/Program.cs
new file mode 100644
index 0000000..cc71f21
--- /dev/null
+++ b/025_Work_with_variable_data/GuidedProject/Own/Program.cs
@@ -0,0 +1,363 @@
+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 = @"
+ 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 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", "rat", "bat" };
+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];
+}
+
+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);
+ }
+}
+
+void press_enter(string msg = "\n\tPress 'Enter' to continue") {
+ print(msg, 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);
+ }
+ 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];
+ 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,
+ 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 (integer) {
+ int temp_int;
+ if (int.TryParse(resp, out temp_int)) {
+ 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, 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 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;
+}
+
+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();
+}
+
+
+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);
+ 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":
+ clear();
+ print(WIP);
+ press_enter();
+ break;
+ case "8":
+ clear();
+ print(WIP);
+ 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/025_Work_with_variable_data/GuidedProject/Starter/Program.cs b/025_Work_with_variable_data/GuidedProject/Starter/Program.cs
new file mode 100644
index 0000000..6a963bd
--- /dev/null
+++ b/025_Work_with_variable_data/GuidedProject/Starter/Program.cs
@@ -0,0 +1,109 @@
+// #1 the ourAnimals array will store the following:
+string animalSpecies = "";
+string animalID = "";
+string animalAge = "";
+string animalPhysicalDescription = "";
+string animalPersonalityDescription = "";
+string animalNickname = "";
+
+// #2 variables that support data entry
+int maxPets = 8;
+string? readResult;
+string menuSelection = "";
+
+// #3 array used to store runtime data, there is no persisted data
+string[,] ourAnimals = new string[maxPets, 6];
+
+// #4 create 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";
+ 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";
+ break;
+ case 2:
+ animalSpecies = "cat";
+ animalID = "c3";
+ animalAge = "1";
+ animalPhysicalDescription = "small white female weighing about 8 pounds. litter box trained.";
+ animalPersonalityDescription = "friendly";
+ animalNickname = "snow";
+ break;
+ case 3:
+ animalSpecies = "cat";
+ animalID = "c4";
+ animalAge = "3";
+ animalPhysicalDescription = "Medium sized, long hair, yellow, female, about 10 pounds. Uses litter box.";
+ animalPersonalityDescription = "A people loving cat that likes to sit on your lap.";
+ animalNickname = "Lion";
+ 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;
+
+}
+
+// #5 display the 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();
+ }
+ // use 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 < 6; j++) {
+ Console.WriteLine(ourAnimals[i, j]);
+ }
+ }
+ }
+ Console.WriteLine("\n\rPress the Enter key to continue");
+ readResult = Console.ReadLine();
+ break;
+ case "2":
+ // Display all dogs with a specified characteristic
+ Console.WriteLine("\nUNDER 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/025_Work_with_variable_data/GuidedProject/Starter/Starter.csproj b/025_Work_with_variable_data/GuidedProject/Starter/Starter.csproj
new file mode 100644
index 0000000..f02677b
--- /dev/null
+++ b/025_Work_with_variable_data/GuidedProject/Starter/Starter.csproj
@@ -0,0 +1,10 @@
+
+
+
+ Exe
+ net7.0
+ enable
+ enable
+
+
+
diff --git a/README.md b/README.md
index 5827484..a265548 100644
--- a/README.md
+++ b/README.md
@@ -27,5 +27,6 @@ Following
20. [Choose the correct data type](./020_data_types/020_csharp.md)
21. [Convert data types](./021_Casting_and_conversion_techniques/021_csharp.md)
22. [Array Operations](./022_array_operations/022_csharp.md)
-23. [Format alphanumeric data](/023_alphanumeric_data_format/023_csharp.md)
-24. [String data type methods](/024_String_data_type_methods/024_csharp.md)
+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)