diff --git a/1-welcome/README.md b/1-welcome/README.md index bf95465..55f0499 100644 --- a/1-welcome/README.md +++ b/1-welcome/README.md @@ -4,6 +4,9 @@ In this Welcome, we’ll introduce ourselves, give you the lesson rundown, take ![.NET bot waving](../images/dotnet-bot.svg) ## Prerequisite tools +In this series, you can use your editor of choice or GitHub Codespaces. Here are some options we suggest: +- [GitHub Codespaces](https://code.visualstudio.com/docs/remote/codespaces) for an in-browser coding environment +- [Visual Studio Code](https://code.visualstudio.com/), with the [C# Dev Kit Extension](https://marketplace.visualstudio.com/items?itemName=ms-dotnettools.csdevkit) - [Visual Studio](https://aka.ms/WebLearningSeries-git-vsDownload) or [Visual Studio for Mac](https://aka.ms/WebLearningSeries-git-vsmacDownload) - check out our [more detailed instructions](/1-welcome/how-to-install-vs.md) for extra help - [.NET 6 SDK](https://aka.ms/WebLearningSeries-git-dotnetDownload) diff --git a/2-csharp/README.md b/2-csharp/README.md index c3ee4a0..20a60cd 100644 --- a/2-csharp/README.md +++ b/2-csharp/README.md @@ -2,6 +2,19 @@ In this C# Crash Course, we'll go over the basics of C# so that you'll be ready to build out exciting web apps! We'll start by going through the key attributes of C#, syntax basics, and introduce you to OOP. In each section, we'll link you to some quick in-browser C# challenges so you can apply these concepts. +## Curriculum + +If you're completely new to C# and want a more comprehensive learning path, check out our [C# Curriculum](https://aka.ms/selfguidedcsharp). The projects included in that curriculum are listed below. You can open this repository as a Codespace to complete those projects. + +| | Lesson | Guided Project | Challenge Project | +| :-: | :------------------------------------------------------: | ----------------------------------------------------------------------------------------------------------------------------------- | :----------------------------------------------------------------------------------------------------------------------------: | +| 01 | [Write your first code using C#](https://learn.microsoft.com/training/paths/get-started-c-sharp-part-1/) | [Calculate and print student grades](https://learn.microsoft.com/en-us/training/modules/guided-project-calculate-print-student-grades/) | [Calculate final GPA](https://learn.microsoft.com/en-us/training/modules/guided-project-calculate-final-gpa/) +| 02 | [Create and run simple C# console applications](https://learn.microsoft.com/training/paths/get-started-c-sharp-part-2/) | [Develop foreach and if-elseif-else structures to process array data in C#](https://learn.microsoft.com/training/modules/guided-project-arrays-iteration-selection/), [Code](lesson-2-projects/guided-project) | [Develop foreach and if-elseif-else structures to process array data in C#](https://learn.microsoft.com/training/modules/challenge-project-arrays-iteration-selection/), [Code](lesson-2-projects/challenge-project) +| 03 | [Add logic to C# console applications](https://learn.microsoft.com/training/paths/get-started-c-sharp-part-3/) | [Develop conditional branching and looping structures in C#](https://learn.microsoft.com/training/modules/guided-project-develop-conditional-branching-looping/), [Code](lesson-3-projects/guided-project) | [Develop branching and looping structures in C#](https://learn.microsoft.com/training/modules/challenge-project-develop-branching-looping-structures-c-sharp/), [Code](lesson-3-projects/challenge-project) +| 04 | [Work with variable data in C# console applications](https://learn.microsoft.com/training/paths/get-started-c-sharp-part-4/) | [Work with variable data in C#](https://learn.microsoft.com/training/modules/guided-project-work-variable-data-c-sharp/), [Code](lesson-4-projects/guided-project) | [Challenge - Work with variable data in C#](https://learn.microsoft.com/training/modules/challenge-project-work-variable-data-c-sharp/), [Code](lesson-4-projects/challenge-project) +| 05 | [Create methods in C# console applications](https://learn.microsoft.com/training/paths/get-started-c-sharp-part-5/) | [Plan a petting zoo visit](https://learn.microsoft.com/training/modules/guided-project-visit-petting-zoo/), No project files | [Create a mini-game](https://learn.microsoft.com/training/modules/challenge-project-create-mini-game/), [Code](lesson-5-projects/challenge-project) +| 06 | [Debug C# console applications](https://learn.microsoft.com/training/paths/get-started-c-sharp-part-6/) | [Debug and handle exceptions in a C# console application using Visual Studio Code](https://learn.microsoft.com/training/modules/guided-project-debug-handle-exceptions-c-sharp-console-application/), [Code](lesson-6-projects/guided-project) | [Challenge - Debug a C# console application](https://learn.microsoft.com/training/modules/challenge-project-debug-c-sharp-console-application/), [Code](lesson-6-projects/challenge-project) + ## Topics you'll learn * Language attributes diff --git a/2-csharp/lesson-2-projects/challenge-project/Final/Final.csproj b/2-csharp/lesson-2-projects/challenge-project/Final/Final.csproj new file mode 100644 index 0000000..f02677b --- /dev/null +++ b/2-csharp/lesson-2-projects/challenge-project/Final/Final.csproj @@ -0,0 +1,10 @@ + + + + Exe + net7.0 + enable + enable + + + diff --git a/2-csharp/lesson-2-projects/challenge-project/Final/Program.cs b/2-csharp/lesson-2-projects/challenge-project/Final/Program.cs new file mode 100644 index 0000000..3a26828 --- /dev/null +++ b/2-csharp/lesson-2-projects/challenge-project/Final/Program.cs @@ -0,0 +1,144 @@ +/* +This C# console application is designed to: +- Use arrays to store student names and assignment scores. +- Use a `foreach` statement to iterate through the student names as an outer program loop. +- Use an `if` statement within the outer loop to identify the current student name and access that student's assignment scores. +- Use a `foreach` statement within the outer loop to iterate though the assignment scores array and sum the values. +- Use an algorithm within the outer loop to calculate the average exam score for each student. +- Use an `if-elseif-else` construct within the outer loop to evaluate the average exam score and assign a letter grade automatically. +- Integrate extra credit scores when calculating the student's final score and letter grade as follows: + - detects extra credit assignments based on the number of elements in the student's scores array. + - divides the values of extra credit assignments by 10 before adding extra credit scores to the sum of exam scores. +- use the following report format to report student grades: + +Student Exam Score Overall Grade Extra Credit + +Sophia 92.2 95.88 A 92 (3.68 pts) + +*/ +int examAssignments = 5; + +string[] studentNames = new string[] { "Sophia", "Andrew", "Emma", "Logan" }; + +int[] sophiaScores = new int[] { 90, 86, 87, 98, 100, 94, 90 }; +int[] andrewScores = new int[] { 92, 89, 81, 96, 90, 89 }; +int[] emmaScores = new int[] { 90, 85, 87, 98, 68, 89, 89, 89 }; +int[] loganScores = new int[] { 90, 95, 87, 88, 96, 96 }; + +int[] studentScores = new int[10]; + +string currentStudentLetterGrade = ""; + +// display the header row for scores/grades +Console.Clear(); +Console.WriteLine("Student\t\tExam Score\tOverall Grade\tExtra Credit\n"); + +/* +The outer foreach loop is used to: +- iterate through student names +- assign a student's grades to the studentScores array +- calculate exam and extra credit sums (inner foreach loop) +- calculate numeric and letter grade +- write the score report information +*/ +foreach (string name in studentNames) +{ + string currentStudent = name; + + if (currentStudent == "Sophia") + studentScores = sophiaScores; + + else if (currentStudent == "Andrew") + studentScores = andrewScores; + + else if (currentStudent == "Emma") + studentScores = emmaScores; + + else if (currentStudent == "Logan") + studentScores = loganScores; + + int gradedAssignments = 0; + int gradedExtraCreditAssignments = 0; + + int sumExamScores = 0; + int sumExtraCreditScores = 0; + + decimal currentStudentGrade = 0; + decimal currentStudentExamScore = 0; + decimal currentStudentExtraCreditScore = 0; + + /* + the inner foreach loop: + - sums the exam and extra credit scores + - counts the extra credit assignments + */ + foreach (int score in studentScores) + { + gradedAssignments += 1; + + if (gradedAssignments <= examAssignments) + { + sumExamScores = sumExamScores + score; + } + + else + { + gradedExtraCreditAssignments += 1; + sumExtraCreditScores += score; + } + } + + currentStudentExamScore = (decimal)(sumExamScores) / examAssignments; + currentStudentExtraCreditScore = (decimal)(sumExtraCreditScores) / gradedExtraCreditAssignments; + + currentStudentGrade = (decimal)((decimal)sumExamScores + ((decimal)sumExtraCreditScores / 10)) / examAssignments; + + if (currentStudentGrade >= 97) + currentStudentLetterGrade = "A+"; + + else if (currentStudentGrade >= 93) + currentStudentLetterGrade = "A"; + + else if (currentStudentGrade >= 90) + currentStudentLetterGrade = "A-"; + + else if (currentStudentGrade >= 87) + currentStudentLetterGrade = "B+"; + + else if (currentStudentGrade >= 83) + currentStudentLetterGrade = "B"; + + else if (currentStudentGrade >= 80) + currentStudentLetterGrade = "B-"; + + else if (currentStudentGrade >= 77) + currentStudentLetterGrade = "C+"; + + else if (currentStudentGrade >= 73) + currentStudentLetterGrade = "C"; + + else if (currentStudentGrade >= 70) + currentStudentLetterGrade = "C-"; + + else if (currentStudentGrade >= 67) + currentStudentLetterGrade = "D+"; + + else if (currentStudentGrade >= 63) + currentStudentLetterGrade = "D"; + + else if (currentStudentGrade >= 60) + currentStudentLetterGrade = "D-"; + + else + currentStudentLetterGrade = "F"; + + + // Student Exam Score Overall Grade Extra Credit + // Sophia 92.2 95.88 A 92 (3.68 pts) + + Console.WriteLine($"{currentStudent}\t\t{currentStudentExamScore}\t\t{currentStudentGrade}\t{currentStudentLetterGrade}\t{currentStudentExtraCreditScore} ({(((decimal)sumExtraCreditScores / 10) / examAssignments)} pts)"); +} + +// required for running in VS Code (keeps the Output windows open to view results) +Console.WriteLine("\n\rPress the Enter key to continue"); +Console.ReadLine(); diff --git a/2-csharp/lesson-2-projects/challenge-project/LICENSE b/2-csharp/lesson-2-projects/challenge-project/LICENSE new file mode 100644 index 0000000..2080d95 --- /dev/null +++ b/2-csharp/lesson-2-projects/challenge-project/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/2-csharp/lesson-2-projects/challenge-project/README.md b/2-csharp/lesson-2-projects/challenge-project/README.md new file mode 100644 index 0000000..b555e6f --- /dev/null +++ b/2-csharp/lesson-2-projects/challenge-project/README.md @@ -0,0 +1,2 @@ +# Challenge-project-foreach-if-array-CSharp +Starter and Solution code for the Challenge project: "Develop foreach and if-elseif-else structures to process array data in C#" from the Microsoft Learn collection "Getting started with C#" diff --git a/2-csharp/lesson-2-projects/challenge-project/Starter/Program.cs b/2-csharp/lesson-2-projects/challenge-project/Starter/Program.cs new file mode 100644 index 0000000..49fd056 --- /dev/null +++ b/2-csharp/lesson-2-projects/challenge-project/Starter/Program.cs @@ -0,0 +1,132 @@ +/* +This C# console application is designed to: +- Use arrays to store student names and assignment scores. +- Use a `foreach` statement to iterate through the student names as an outer program loop. +- Use an `if` statement within the outer loop to identify the current student name and access that student's assignment scores. +- Use a `foreach` statement within the outer loop to iterate though the assignment scores array and sum the values. +- Use an algorithm within the outer loop to calculate the average exam score for each student. +- Use an `if-elseif-else` construct within the outer loop to evaluate the average exam score and assign a letter grade automatically. +- Integrate extra credit scores when calculating the student's final score and letter grade as follows: + - detects extra credit assignments based on the number of elements in the student's scores array. + - divides the values of extra credit assignments by 10 before adding extra credit scores to the sum of exam scores. +- use the following report format to report student grades: + + Student Grade + + Sophia: 92.2 A- + Andrew: 89.6 B+ + Emma: 85.6 B + Logan: 91.2 A- +*/ +int examAssignments = 5; + +string[] studentNames = new string[] { "Sophia", "Andrew", "Emma", "Logan" }; + +int[] sophiaScores = new int[] { 90, 86, 87, 98, 100, 94, 90 }; +int[] andrewScores = new int[] { 92, 89, 81, 96, 90, 89 }; +int[] emmaScores = new int[] { 90, 85, 87, 98, 68, 89, 89, 89 }; +int[] loganScores = new int[] { 90, 95, 87, 88, 96, 96 }; + +int[] studentScores = new int[10]; + +string currentStudentLetterGrade = ""; + +// display the header row for scores/grades +Console.Clear(); +Console.WriteLine("Student\t\tGrade\tLetter Grade\n"); + +/* +The outer foreach loop is used to: +- iterate through student names +- assign a student's grades to the studentScores array +- sum assignment scores (inner foreach loop) +- calculate numeric and letter grade +- write the score report information +*/ +foreach (string name in studentNames) +{ + string currentStudent = name; + + if (currentStudent == "Sophia") + studentScores = sophiaScores; + + else if (currentStudent == "Andrew") + studentScores = andrewScores; + + else if (currentStudent == "Emma") + studentScores = emmaScores; + + else if (currentStudent == "Logan") + studentScores = loganScores; + + int sumAssignmentScores = 0; + + decimal currentStudentGrade = 0; + + int gradedAssignments = 0; + + /* + the inner foreach loop sums assignment scores + extra credit assignments are worth 10% of an exam score + */ + foreach (int score in studentScores) + { + gradedAssignments += 1; + + if (gradedAssignments <= examAssignments) + sumAssignmentScores += score; + + else + sumAssignmentScores += score / 10; + } + + currentStudentGrade = (decimal)(sumAssignmentScores) / examAssignments; + + if (currentStudentGrade >= 97) + currentStudentLetterGrade = "A+"; + + else if (currentStudentGrade >= 93) + currentStudentLetterGrade = "A"; + + else if (currentStudentGrade >= 90) + currentStudentLetterGrade = "A-"; + + else if (currentStudentGrade >= 87) + currentStudentLetterGrade = "B+"; + + else if (currentStudentGrade >= 83) + currentStudentLetterGrade = "B"; + + else if (currentStudentGrade >= 80) + currentStudentLetterGrade = "B-"; + + else if (currentStudentGrade >= 77) + currentStudentLetterGrade = "C+"; + + else if (currentStudentGrade >= 73) + currentStudentLetterGrade = "C"; + + else if (currentStudentGrade >= 70) + currentStudentLetterGrade = "C-"; + + else if (currentStudentGrade >= 67) + currentStudentLetterGrade = "D+"; + + else if (currentStudentGrade >= 63) + currentStudentLetterGrade = "D"; + + else if (currentStudentGrade >= 60) + currentStudentLetterGrade = "D-"; + + else + currentStudentLetterGrade = "F"; + + // Student Grade + // Sophia: 92.2 A- + + Console.WriteLine($"{currentStudent}\t\t{currentStudentGrade}\t{currentStudentLetterGrade}"); +} + +// required for running in VS Code (keeps the Output windows open to view results) +Console.WriteLine("\n\rPress the Enter key to continue"); +Console.ReadLine(); diff --git a/2-csharp/lesson-2-projects/challenge-project/Starter/Starter.csproj b/2-csharp/lesson-2-projects/challenge-project/Starter/Starter.csproj new file mode 100644 index 0000000..f02677b --- /dev/null +++ b/2-csharp/lesson-2-projects/challenge-project/Starter/Starter.csproj @@ -0,0 +1,10 @@ + + + + Exe + net7.0 + enable + enable + + + diff --git a/2-csharp/lesson-2-projects/guided-project/Final/Final.csproj b/2-csharp/lesson-2-projects/guided-project/Final/Final.csproj new file mode 100644 index 0000000..f02677b --- /dev/null +++ b/2-csharp/lesson-2-projects/guided-project/Final/Final.csproj @@ -0,0 +1,10 @@ + + + + Exe + net7.0 + enable + enable + + + diff --git a/2-csharp/lesson-2-projects/guided-project/Final/Program.cs b/2-csharp/lesson-2-projects/guided-project/Final/Program.cs new file mode 100644 index 0000000..1114aed --- /dev/null +++ b/2-csharp/lesson-2-projects/guided-project/Final/Program.cs @@ -0,0 +1,118 @@ +/* +This C# console application is designed to: +- Use arrays to store student names and assignment scores. +- Use a `foreach` statement to iterate through the student names as an outer program loop. +- Use an `if` statement within the outer loop to identify the current student name and access that student's assignment scores. +- Use a `foreach` statement within the outer loop to iterate though the assignment scores array and sum the values. +- Use an algorithm within the outer loop to calculate the average exam score for each student. +- Use an `if-elseif-else` construct within the outer loop to evaluate the average exam score and assign a letter grade automatically. +- Integrate extra credit scores when calculating the student's final score and letter grade as follows: + - detects extra credit assignments based on the number of elements in the student's scores array. + - divides the values of extra credit assignments by 10 before adding extra credit scores to the sum of exam scores. +- use the following report format to report student grades: + + Student Grade + + Sophia: 92.2 A- + Andrew: 89.6 B+ + Emma: 85.6 B + Logan: 91.2 A- +*/ + +int examAssignments = 5; + +string[] studentNames = new string[] { "Sophia", "Andrew", "Emma", "Logan" }; + +int[] sophiaScores = new int[] { 90, 86, 87, 98, 100, 94, 90 }; +int[] andrewScores = new int[] { 92, 89, 81, 96, 90, 89 }; +int[] emmaScores = new int[] { 90, 85, 87, 98, 68, 89, 89, 89 }; +int[] loganScores = new int[] { 90, 95, 87, 88, 96, 96 }; + +int[] studentScores = new int[10]; + +string currentStudentLetterGrade = ""; + +// display the header row for scores/grades +Console.Clear(); +Console.WriteLine("Student\t\tGrade\n"); + +/* +The outer foreach loop is used to: +- iterate through student names +- assign a student's grades to the studentScores array +- sum assignment scores (inner foreach loop) +- calculate numeric and letter grade +- write the score report information +*/ +foreach (string name in studentNames) +{ + string currentStudent = name; + + if (currentStudent == "Sophia") + studentScores = sophiaScores; + + else if (currentStudent == "Andrew") + studentScores = andrewScores; + + else if (currentStudent == "Emma") + studentScores = emmaScores; + + else if (currentStudent == "Logan") + studentScores = loganScores; + + int sumAssignmentScores = 0; + decimal currentStudentGrade = 0; + int gradedAssignments = 0; + + /* + the inner foreach loop sums assignment scores + extra credit assignments are worth 10% of an exam score + */ + foreach (int score in studentScores) + { + gradedAssignments += 1; + + if (gradedAssignments <= examAssignments) + sumAssignmentScores += score; + else + sumAssignmentScores += score / 10; + } + + currentStudentGrade = (decimal)(sumAssignmentScores) / examAssignments; + + if (currentStudentGrade >= 97) + currentStudentLetterGrade = "A+"; + else if (currentStudentGrade >= 93) + currentStudentLetterGrade = "A"; + else if (currentStudentGrade >= 90) + currentStudentLetterGrade = "A-"; + else if (currentStudentGrade >= 87) + currentStudentLetterGrade = "B+"; + else if (currentStudentGrade >= 83) + currentStudentLetterGrade = "B"; + else if (currentStudentGrade >= 80) + currentStudentLetterGrade = "B-"; + else if (currentStudentGrade >= 77) + currentStudentLetterGrade = "C+"; + else if (currentStudentGrade >= 73) + currentStudentLetterGrade = "C"; + else if (currentStudentGrade >= 70) + currentStudentLetterGrade = "C-"; + else if (currentStudentGrade >= 67) + currentStudentLetterGrade = "D+"; + else if (currentStudentGrade >= 63) + currentStudentLetterGrade = "D"; + else if (currentStudentGrade >= 60) + currentStudentLetterGrade = "D-"; + else + currentStudentLetterGrade = "F"; + + // Student Grade + // Sophia: 92.2 A- + + Console.WriteLine($"{currentStudent}\t\t{currentStudentGrade}\t{currentStudentLetterGrade}"); +} + +// required for running in VS Code (keeps the Output windows open to view results) +Console.WriteLine("\n\rPress the Enter key to continue"); +Console.ReadLine(); diff --git a/2-csharp/lesson-2-projects/guided-project/LICENSE b/2-csharp/lesson-2-projects/guided-project/LICENSE new file mode 100644 index 0000000..2080d95 --- /dev/null +++ b/2-csharp/lesson-2-projects/guided-project/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/2-csharp/lesson-2-projects/guided-project/README.md b/2-csharp/lesson-2-projects/guided-project/README.md new file mode 100644 index 0000000..ee76a63 --- /dev/null +++ b/2-csharp/lesson-2-projects/guided-project/README.md @@ -0,0 +1,2 @@ +# Guided-project-foreach-if-array-CSharp +Starter and Solution code for the Guided project: "Develop foreach and if-elseif-else structures to process array data in C#" from the Microsoft Learn collection "Getting started with C#" diff --git a/2-csharp/lesson-2-projects/guided-project/Starter/Program.cs b/2-csharp/lesson-2-projects/guided-project/Starter/Program.cs new file mode 100644 index 0000000..d852a12 --- /dev/null +++ b/2-csharp/lesson-2-projects/guided-project/Starter/Program.cs @@ -0,0 +1,57 @@ +using System; + +// initialize variables - graded assignments +int currentAssignments = 5; + +int sophia1 = 90; +int sophia2 = 86; +int sophia3 = 87; +int sophia4 = 98; +int sophia5 = 100; + +int andrew1 = 92; +int andrew2 = 89; +int andrew3 = 81; +int andrew4 = 96; +int andrew5 = 90; + +int emma1 = 90; +int emma2 = 85; +int emma3 = 87; +int emma4 = 98; +int emma5 = 68; + +int logan1 = 90; +int logan2 = 95; +int logan3 = 87; +int logan4 = 88; +int logan5 = 96; + +int sophiaSum = 0; +int andrewSum = 0; +int emmaSum = 0; +int loganSum = 0; + +decimal sophiaScore; +decimal andrewScore; +decimal emmaScore; +decimal loganScore; + +sophiaSum = sophia1 + sophia2 + sophia3 + sophia4 + sophia5; +andrewSum = andrew1 + andrew2 + andrew3 + andrew4 + andrew5; +emmaSum = emma1 + emma2 + emma3 + emma4 + emma5; +loganSum = logan1 + logan2 + logan3 + logan4 + logan5; + +sophiaScore = (decimal)sophiaSum / currentAssignments; +andrewScore = (decimal)andrewSum / currentAssignments; +emmaScore = (decimal)emmaSum / currentAssignments; +loganScore = (decimal)loganSum / currentAssignments; + +Console.WriteLine("Student\t\tGrade\n"); +Console.WriteLine("Sophia:\t\t" + sophiaScore + "\tA-"); +Console.WriteLine("Andrew:\t\t" + andrewScore + "\tB+"); +Console.WriteLine("Emma:\t\t" + emmaScore + "\tB"); +Console.WriteLine("Logan:\t\t" + loganScore + "\tA-"); + +Console.WriteLine("Press the Enter key to continue"); +Console.ReadLine(); diff --git a/2-csharp/lesson-2-projects/guided-project/Starter/Starter.csproj b/2-csharp/lesson-2-projects/guided-project/Starter/Starter.csproj new file mode 100644 index 0000000..f02677b --- /dev/null +++ b/2-csharp/lesson-2-projects/guided-project/Starter/Starter.csproj @@ -0,0 +1,10 @@ + + + + Exe + net7.0 + enable + enable + + + diff --git a/2-csharp/lesson-3-projects/challenge-project/Final/Final.csproj b/2-csharp/lesson-3-projects/challenge-project/Final/Final.csproj new file mode 100644 index 0000000..f02677b --- /dev/null +++ b/2-csharp/lesson-3-projects/challenge-project/Final/Final.csproj @@ -0,0 +1,10 @@ + + + + Exe + net7.0 + enable + enable + + + diff --git a/2-csharp/lesson-3-projects/challenge-project/Final/Program.cs b/2-csharp/lesson-3-projects/challenge-project/Final/Program.cs new file mode 100644 index 0000000..c4cb287 --- /dev/null +++ b/2-csharp/lesson-3-projects/challenge-project/Final/Program.cs @@ -0,0 +1,430 @@ +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); + } + } + } 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/2-csharp/lesson-3-projects/challenge-project/LICENSE b/2-csharp/lesson-3-projects/challenge-project/LICENSE new file mode 100644 index 0000000..2080d95 --- /dev/null +++ b/2-csharp/lesson-3-projects/challenge-project/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/2-csharp/lesson-3-projects/challenge-project/README.md b/2-csharp/lesson-3-projects/challenge-project/README.md new file mode 100644 index 0000000..7eb830d --- /dev/null +++ b/2-csharp/lesson-3-projects/challenge-project/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/2-csharp/lesson-3-projects/challenge-project/Starter/Program.cs b/2-csharp/lesson-3-projects/challenge-project/Starter/Program.cs new file mode 100644 index 0000000..647bf8a --- /dev/null +++ b/2-csharp/lesson-3-projects/challenge-project/Starter/Program.cs @@ -0,0 +1,330 @@ +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); + } + } + } 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/2-csharp/lesson-3-projects/challenge-project/Starter/Starter.csproj b/2-csharp/lesson-3-projects/challenge-project/Starter/Starter.csproj new file mode 100644 index 0000000..f02677b --- /dev/null +++ b/2-csharp/lesson-3-projects/challenge-project/Starter/Starter.csproj @@ -0,0 +1,10 @@ + + + + Exe + net7.0 + enable + enable + + + diff --git a/2-csharp/lesson-3-projects/guided-project/Final/Final.csproj b/2-csharp/lesson-3-projects/guided-project/Final/Final.csproj new file mode 100644 index 0000000..f02677b --- /dev/null +++ b/2-csharp/lesson-3-projects/guided-project/Final/Final.csproj @@ -0,0 +1,10 @@ + + + + Exe + net7.0 + enable + enable + + + diff --git a/2-csharp/lesson-3-projects/guided-project/Final/Program.cs b/2-csharp/lesson-3-projects/guided-project/Final/Program.cs new file mode 100644 index 0000000..e592066 --- /dev/null +++ b/2-csharp/lesson-3-projects/guided-project/Final/Program.cs @@ -0,0 +1,319 @@ +using System; + +// 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 = ""; + +// 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; +} + +do +{ + // display the top-level menu options + + 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]); + } + } + } + Console.WriteLine("\n\rPress the Enter key to continue"); + readResult = Console.ReadLine(); + + break; + + case "2": + // Add a new animal friend to the ourAnimals array + string anotherPet = "y"; + int 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) + { + bool validEntry = false; + + // 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 + { + int petAge; + 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/condition - 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 (animalPhysicalDescription == ""); + + // 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 (animalPersonalityDescription == ""); + + // 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 (animalNickname == ""); + + // 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"); + } + } + + 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/2-csharp/lesson-3-projects/guided-project/LICENSE b/2-csharp/lesson-3-projects/guided-project/LICENSE new file mode 100644 index 0000000..2080d95 --- /dev/null +++ b/2-csharp/lesson-3-projects/guided-project/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/2-csharp/lesson-3-projects/guided-project/README.md b/2-csharp/lesson-3-projects/guided-project/README.md new file mode 100644 index 0000000..139866e --- /dev/null +++ b/2-csharp/lesson-3-projects/guided-project/README.md @@ -0,0 +1,2 @@ +# Guided-project-branching-looping-CSharp +Starter and Solution code for the Guided project: "Develop conditional branching and looping structures in C#" from the Microsoft Learn collection "Getting started with C#" diff --git a/2-csharp/lesson-3-projects/guided-project/Starter/Program.cs b/2-csharp/lesson-3-projects/guided-project/Starter/Program.cs new file mode 100644 index 0000000..6652111 --- /dev/null +++ b/2-csharp/lesson-3-projects/guided-project/Starter/Program.cs @@ -0,0 +1,102 @@ +// 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 = ""; + +// array used to store runtime data, there is no persisted data +string[,] ourAnimals = new string[maxPets, 6]; + +// TODO: Convert the if-elseif-else construct to a switch statement + +// create some initial ourAnimals array entries +for (int i = 0; i < maxPets; i++) +{ + if (i == 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"; + } + else if (i == 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"; + } + else if (i == 2) + { + animalSpecies = "cat"; + animalID = "c3"; + animalAge = "1"; + animalPhysicalDescription = "small white female weighing about 8 pounds. litter box trained."; + animalPersonalityDescription = "friendly"; + animalNickname = "Puss"; + } + else if (i == 3) + { + animalSpecies = "cat"; + animalID = "c4"; + animalAge = "?"; + animalPhysicalDescription = ""; + animalPersonalityDescription = ""; + animalNickname = ""; + } + else + { + animalSpecies = ""; + animalID = ""; + animalAge = ""; + animalPhysicalDescription = ""; + animalPersonalityDescription = ""; + animalNickname = ""; + } + + 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 + +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(); +} + +Console.WriteLine($"You selected menu option {menuSelection}."); +Console.WriteLine("Press the Enter key to continue"); + +// pause code execution +readResult = Console.ReadLine(); diff --git a/2-csharp/lesson-3-projects/guided-project/Starter/Starter.csproj b/2-csharp/lesson-3-projects/guided-project/Starter/Starter.csproj new file mode 100644 index 0000000..f02677b --- /dev/null +++ b/2-csharp/lesson-3-projects/guided-project/Starter/Starter.csproj @@ -0,0 +1,10 @@ + + + + Exe + net7.0 + enable + enable + + + diff --git a/2-csharp/lesson-4-projects/challenge-project/Final/Final.csproj b/2-csharp/lesson-4-projects/challenge-project/Final/Final.csproj new file mode 100644 index 0000000..f02677b --- /dev/null +++ b/2-csharp/lesson-4-projects/challenge-project/Final/Final.csproj @@ -0,0 +1,10 @@ + + + + Exe + net7.0 + enable + enable + + + diff --git a/2-csharp/lesson-4-projects/challenge-project/Final/Program.cs b/2-csharp/lesson-4-projects/challenge-project/Final/Program.cs new file mode 100644 index 0000000..bd2262e --- /dev/null +++ b/2-csharp/lesson-4-projects/challenge-project/Final/Program.cs @@ -0,0 +1,228 @@ +// 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/2-csharp/lesson-4-projects/challenge-project/LICENSE b/2-csharp/lesson-4-projects/challenge-project/LICENSE new file mode 100644 index 0000000..2080d95 --- /dev/null +++ b/2-csharp/lesson-4-projects/challenge-project/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/2-csharp/lesson-4-projects/challenge-project/README.md b/2-csharp/lesson-4-projects/challenge-project/README.md new file mode 100644 index 0000000..92a1d69 --- /dev/null +++ b/2-csharp/lesson-4-projects/challenge-project/README.md @@ -0,0 +1,2 @@ +# Challenge-project-Work-with-variable-data-in-CSharp +Starter and Solution code for the **Challenge project**: "Work with variable data in C# console applications" from the Microsoft Learn collection "Getting started with C#" diff --git a/2-csharp/lesson-4-projects/challenge-project/Starter/Program.cs b/2-csharp/lesson-4-projects/challenge-project/Starter/Program.cs new file mode 100644 index 0000000..42d45bc --- /dev/null +++ b/2-csharp/lesson-4-projects/challenge-project/Starter/Program.cs @@ -0,0 +1,206 @@ +using System; + +// 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/2-csharp/lesson-4-projects/challenge-project/Starter/Starter.csproj b/2-csharp/lesson-4-projects/challenge-project/Starter/Starter.csproj new file mode 100644 index 0000000..f02677b --- /dev/null +++ b/2-csharp/lesson-4-projects/challenge-project/Starter/Starter.csproj @@ -0,0 +1,10 @@ + + + + Exe + net7.0 + enable + enable + + + diff --git a/2-csharp/lesson-4-projects/guided-project/Final/Final.csproj b/2-csharp/lesson-4-projects/guided-project/Final/Final.csproj new file mode 100644 index 0000000..f02677b --- /dev/null +++ b/2-csharp/lesson-4-projects/guided-project/Final/Final.csproj @@ -0,0 +1,10 @@ + + + + Exe + net7.0 + enable + enable + + + diff --git a/2-csharp/lesson-4-projects/guided-project/Final/Program.cs b/2-csharp/lesson-4-projects/guided-project/Final/Program.cs new file mode 100644 index 0000000..49dbc35 --- /dev/null +++ b/2-csharp/lesson-4-projects/guided-project/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/2-csharp/lesson-4-projects/guided-project/LICENSE b/2-csharp/lesson-4-projects/guided-project/LICENSE new file mode 100644 index 0000000..2080d95 --- /dev/null +++ b/2-csharp/lesson-4-projects/guided-project/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/2-csharp/lesson-4-projects/guided-project/README.md b/2-csharp/lesson-4-projects/guided-project/README.md new file mode 100644 index 0000000..24dcae1 --- /dev/null +++ b/2-csharp/lesson-4-projects/guided-project/README.md @@ -0,0 +1,3 @@ +# Guided-project-Work-with-variable-data-in-CSharp + +Starter and Solution code for the **Guided project**: "Work with variable data in C# console applications" from the Microsoft Learn collection "Getting started with C#" diff --git a/2-csharp/lesson-4-projects/guided-project/Starter/Program.cs b/2-csharp/lesson-4-projects/guided-project/Starter/Program.cs new file mode 100644 index 0000000..ebdf12b --- /dev/null +++ b/2-csharp/lesson-4-projects/guided-project/Starter/Program.cs @@ -0,0 +1,128 @@ +// #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/2-csharp/lesson-4-projects/guided-project/Starter/Starter.csproj b/2-csharp/lesson-4-projects/guided-project/Starter/Starter.csproj new file mode 100644 index 0000000..f02677b --- /dev/null +++ b/2-csharp/lesson-4-projects/guided-project/Starter/Starter.csproj @@ -0,0 +1,10 @@ + + + + Exe + net7.0 + enable + enable + + + diff --git a/2-csharp/lesson-5-projects/challenge-project/Final/Final.csproj b/2-csharp/lesson-5-projects/challenge-project/Final/Final.csproj new file mode 100644 index 0000000..74abf5c --- /dev/null +++ b/2-csharp/lesson-5-projects/challenge-project/Final/Final.csproj @@ -0,0 +1,10 @@ + + + + Exe + net6.0 + enable + enable + + + diff --git a/2-csharp/lesson-5-projects/challenge-project/Final/Program.cs b/2-csharp/lesson-5-projects/challenge-project/Final/Program.cs new file mode 100644 index 0000000..b4c9e74 --- /dev/null +++ b/2-csharp/lesson-5-projects/challenge-project/Final/Program.cs @@ -0,0 +1,162 @@ +using System; + +Random random = new Random(); +Console.CursorVisible = false; +int height = Console.WindowHeight - 1; +int width = Console.WindowWidth - 5; +bool shouldExit = false; + +// Console position of the player +int playerX = 0; +int playerY = 0; + +// Console position of the food +int foodX = 0; +int foodY = 0; + +// Available player and food strings +string[] states = {"('-')", "(^-^)", "(X_X)"}; +string[] foods = {"@@@@@", "$$$$$", "#####"}; + +// Current player string displayed in the Console +string player = states[0]; + +// Index of the current food +int food = 0; + +InitializeGame(); +while (!shouldExit) +{ + if (TerminalResized()) + { + Console.Clear(); + Console.Write("Console was resized. Program exiting."); + shouldExit = true; + } + else + { + if (PlayerIsFaster()) + { + Move(1, false); + } + else if (PlayerIsSick()) + { + FreezePlayer(); + } else + { + Move(otherKeysExit: false); + } + if (GotFood()) + { + ChangePlayer(); + ShowFood(); + } + } +} + +// Returns true if the Terminal was resized +bool TerminalResized() +{ + return height != Console.WindowHeight - 1 || width != Console.WindowWidth - 5; +} + +// Displays random food at a random location +void ShowFood() +{ + // Update food to a random index + food = random.Next(0, foods.Length); + + // Update food position to a random location + foodX = random.Next(0, width - player.Length); + foodY = random.Next(0, height - 1); + + // Display the food at the location + Console.SetCursorPosition(foodX, foodY); + Console.Write(foods[food]); +} + +// Returns true if the player location matches the food location +bool GotFood() +{ + return playerY == foodY && playerX == foodX; +} + +// Returns true if the player appearance represents a sick state +bool PlayerIsSick() +{ + return player.Equals(states[2]); +} + +// Returns true if the player appearance represents a fast state +bool PlayerIsFaster() +{ + return player.Equals(states[1]); +} + +// Changes the player to match the food consumed +void ChangePlayer() +{ + player = states[food]; + Console.SetCursorPosition(playerX, playerY); + Console.Write(player); +} + +// Temporarily stops the player from moving +void FreezePlayer() +{ + System.Threading.Thread.Sleep(1000); + player = states[0]; +} + +// Reads directional input from the Console and moves the player +void Move(int speed = 1, bool otherKeysExit = false) +{ + int lastX = playerX; + int lastY = playerY; + + switch (Console.ReadKey(true).Key) { + case ConsoleKey.UpArrow: + playerY--; + break; + case ConsoleKey.DownArrow: + playerY++; + break; + case ConsoleKey.LeftArrow: + playerX -= speed; + break; + case ConsoleKey.RightArrow: + playerX += speed; + break; + case ConsoleKey.Escape: + shouldExit = true; + break; + default: + // Exit if any other keys are pressed + shouldExit = otherKeysExit; + break; + } + + // Clear the characters at the previous position + Console.SetCursorPosition(lastX, lastY); + for (int i = 0; i < player.Length; i++) + { + Console.Write(" "); + } + + // Keep player position within the bounds of the Terminal window + playerX = (playerX < 0) ? 0 : (playerX >= width ? width : playerX); + playerY = (playerY < 0) ? 0 : (playerY >= height ? height : playerY); + + // Draw the player at the new location + Console.SetCursorPosition(playerX, playerY); + Console.Write(player); +} + +// Clears the console, displays the food and player +void InitializeGame() +{ + Console.Clear(); + ShowFood(); + Console.SetCursorPosition(0, 0); + Console.Write(player); +} \ No newline at end of file diff --git a/2-csharp/lesson-5-projects/challenge-project/LICENSE b/2-csharp/lesson-5-projects/challenge-project/LICENSE new file mode 100644 index 0000000..2080d95 --- /dev/null +++ b/2-csharp/lesson-5-projects/challenge-project/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/2-csharp/lesson-5-projects/challenge-project/README.md b/2-csharp/lesson-5-projects/challenge-project/README.md new file mode 100644 index 0000000..cc55ae7 --- /dev/null +++ b/2-csharp/lesson-5-projects/challenge-project/README.md @@ -0,0 +1,3 @@ +# Challenge-project-Create-methods-in-CSharp + +Starter and Final code for the Challenge project: "Create methods C# console applications" from the Microsoft Learn collection "Getting started with C#" diff --git a/2-csharp/lesson-5-projects/challenge-project/Starter/Program.cs b/2-csharp/lesson-5-projects/challenge-project/Starter/Program.cs new file mode 100644 index 0000000..56bcd32 --- /dev/null +++ b/2-csharp/lesson-5-projects/challenge-project/Starter/Program.cs @@ -0,0 +1,117 @@ +using System; + +Random random = new Random(); +Console.CursorVisible = false; +int height = Console.WindowHeight - 1; +int width = Console.WindowWidth - 5; +bool shouldExit = false; + +// Console position of the player +int playerX = 0; +int playerY = 0; + +// Console position of the food +int foodX = 0; +int foodY = 0; + +// Available player and food strings +string[] states = {"('-')", "(^-^)", "(X_X)"}; +string[] foods = {"@@@@@", "$$$$$", "#####"}; + +// Current player string displayed in the Console +string player = states[0]; + +// Index of the current food +int food = 0; + +InitializeGame(); +while (!shouldExit) +{ + Move(); +} + +// Returns true if the Terminal was resized +bool TerminalResized() +{ + return height != Console.WindowHeight - 1 || width != Console.WindowWidth - 5; +} + +// Displays random food at a random location +void ShowFood() +{ + // Update food to a random index + food = random.Next(0, foods.Length); + + // Update food position to a random location + foodX = random.Next(0, width - player.Length); + foodY = random.Next(0, height - 1); + + // Display the food at the location + Console.SetCursorPosition(foodX, foodY); + Console.Write(foods[food]); +} + +// Changes the player to match the food consumed +void ChangePlayer() +{ + player = states[food]; + Console.SetCursorPosition(playerX, playerY); + Console.Write(player); +} + +// Temporarily stops the player from moving +void FreezePlayer() +{ + System.Threading.Thread.Sleep(1000); + player = states[0]; +} + +// Reads directional input from the Console and moves the player +void Move() +{ + int lastX = playerX; + int lastY = playerY; + + switch (Console.ReadKey(true).Key) + { + case ConsoleKey.UpArrow: + playerY--; + break; + case ConsoleKey.DownArrow: + playerY++; + break; + case ConsoleKey.LeftArrow: + playerX--; + break; + case ConsoleKey.RightArrow: + playerX++; + break; + case ConsoleKey.Escape: + shouldExit = true; + break; + } + + // Clear the characters at the previous position + Console.SetCursorPosition(lastX, lastY); + for (int i = 0; i < player.Length; i++) + { + Console.Write(" "); + } + + // Keep player position within the bounds of the Terminal window + playerX = (playerX < 0) ? 0 : (playerX >= width ? width : playerX); + playerY = (playerY < 0) ? 0 : (playerY >= height ? height : playerY); + + // Draw the player at the new location + Console.SetCursorPosition(playerX, playerY); + Console.Write(player); +} + +// Clears the console, displays the food and player +void InitializeGame() +{ + Console.Clear(); + ShowFood(); + Console.SetCursorPosition(0, 0); + Console.Write(player); +} \ No newline at end of file diff --git a/2-csharp/lesson-5-projects/challenge-project/Starter/Starter.csproj b/2-csharp/lesson-5-projects/challenge-project/Starter/Starter.csproj new file mode 100644 index 0000000..74abf5c --- /dev/null +++ b/2-csharp/lesson-5-projects/challenge-project/Starter/Starter.csproj @@ -0,0 +1,10 @@ + + + + Exe + net6.0 + enable + enable + + + diff --git a/2-csharp/lesson-6-projects/challenge-project/Final/Final.csproj b/2-csharp/lesson-6-projects/challenge-project/Final/Final.csproj new file mode 100644 index 0000000..f02677b --- /dev/null +++ b/2-csharp/lesson-6-projects/challenge-project/Final/Final.csproj @@ -0,0 +1,10 @@ + + + + Exe + net7.0 + enable + enable + + + diff --git a/2-csharp/lesson-6-projects/challenge-project/Final/Program.cs b/2-csharp/lesson-6-projects/challenge-project/Final/Program.cs new file mode 100644 index 0000000..4db1da6 --- /dev/null +++ b/2-csharp/lesson-6-projects/challenge-project/Final/Program.cs @@ -0,0 +1,182 @@ +/* +This application manages transactions at a store check-out line. The +check-out line has a cash register, and the register has a cash till +that is prepared with a number of bills each morning. The till includes +bills of four denominations: $1, $5, $10, and $20. The till is used +to provide the customer with change during the transaction. The item +cost is a randomly generated number between 2 and 49. The customer +offers payment based on an algorithm that determines a number of bills +in each denomination. + +Each day, the cash till is loaded at the start of the day. As transactions +occur, the cash till is managed in a method named MakeChange (customer +payments go in and the change returned to the customer comes out). A +separate "safety check" calculation that's used to verify the amount of +money in the till is performed in the "main program". This safety check +is used to ensure that logic in the MakeChange method is working as +expected. +*/ + +string? readResult = null; +bool useTestData = false; + +Console.Clear(); + +int[] cashTill = new int[] { 0, 0, 0, 0 }; +int registerCheckTillTotal = 0; + +// registerDailyStartingCash: $1 x 50, $5 x 20, $10 x 10, $20 x 5 => ($350 total) +int[,] registerDailyStartingCash = new int[,] { { 1, 50 }, { 5, 20 }, { 10, 10 }, { 20, 5 } }; + +int[] testData = new int[] { 6, 10, 17, 20, 31, 36, 40, 41 }; +int testCounter = 0; + +LoadTillEachMorning(registerDailyStartingCash, cashTill); + +registerCheckTillTotal = registerDailyStartingCash[0, 0] * registerDailyStartingCash[0, 1] + registerDailyStartingCash[1, 0] * registerDailyStartingCash[1, 1] + registerDailyStartingCash[2, 0] * registerDailyStartingCash[2, 1] + registerDailyStartingCash[3, 0] * registerDailyStartingCash[3, 1]; + +// display the number of bills of each denomination currently in the till +LogTillStatus(cashTill); + +// display a message showing the amount of cash in the till +Console.WriteLine(TillAmountSummary(cashTill)); + +// display the expected registerDailyStartingCash total +Console.WriteLine($"Expected till value: {registerCheckTillTotal}"); +Console.WriteLine(); + +var valueGenerator = new Random((int)DateTime.Now.Ticks); + +int transactions = 100; + +if (useTestData) +{ + transactions = testData.Length; +} + +while (transactions > 0) +{ + transactions -= 1; + int itemCost = valueGenerator.Next(2, 50); + + if (useTestData) + { + itemCost = testData[testCounter]; + testCounter += 1; + } + + int paymentOnes = itemCost % 2; // value is 1 when itemCost is odd, value is 0 when itemCost is even + int paymentFives = (itemCost % 10 > 7) ? 1 : 0; // value is 1 when itemCost ends with 8 or 9, otherwise value is 0 + int paymentTens = (itemCost % 20 > 13) ? 1 : 0; // value is 1 when 13 < itemCost < 20 OR 33 < itemCost < 40, otherwise value is 0 + int paymentTwenties = (itemCost < 20) ? 1 : 2; // value is 1 when itemCost < 20, otherwise value is 2 + + // display messages describing the current transaction + Console.WriteLine($"Customer is making a ${itemCost} purchase"); + Console.WriteLine($"\t Using {paymentTwenties} twenty dollar bills"); + Console.WriteLine($"\t Using {paymentTens} ten dollar bills"); + Console.WriteLine($"\t Using {paymentFives} five dollar bills"); + Console.WriteLine($"\t Using {paymentOnes} one dollar bills"); + + try + { + // MakeChange manages the transaction and updates the till + MakeChange(itemCost, cashTill, paymentTwenties, paymentTens, paymentFives, paymentOnes); + + // Backup Calculation - each transaction adds current "itemCost" to the till + registerCheckTillTotal += itemCost; + } + catch (InvalidOperationException e) + { + Console.WriteLine($"Could not complete transaction: {e.Message}"); + } + + Console.WriteLine(TillAmountSummary(cashTill)); + Console.WriteLine($"Expected till value: {registerCheckTillTotal}"); + Console.WriteLine(); +} + +Console.WriteLine("Press the Enter key to exit"); +do +{ + readResult = Console.ReadLine(); + +} while (readResult == null); + + +static void LoadTillEachMorning(int[,] registerDailyStartingCash, int[] cashTill) +{ + cashTill[0] = registerDailyStartingCash[0, 1]; + cashTill[1] = registerDailyStartingCash[1, 1]; + cashTill[2] = registerDailyStartingCash[2, 1]; + cashTill[3] = registerDailyStartingCash[3, 1]; +} + + +static void MakeChange(int cost, int[] cashTill, int twenties, int tens = 0, int fives = 0, int ones = 0) +{ + int availableTwenties = cashTill[3] + twenties; + int availableTens = cashTill[2] + tens; + int availableFives = cashTill[1] + fives; + int availableOnes = cashTill[0] + ones; + + int amountPaid = twenties * 20 + tens * 10 + fives * 5 + ones; + int changeNeeded = amountPaid - cost; + + if (changeNeeded < 0) + throw new InvalidOperationException("InvalidOperationException: Not enough money provided to complete the transaction."); + + Console.WriteLine("Cashier prepares the following change:"); + + while ((changeNeeded > 19) && (availableTwenties > 0)) + { + availableTwenties--; + changeNeeded -= 20; + Console.WriteLine("\t A twenty"); + } + + while ((changeNeeded > 9) && (availableTens > 0)) + { + availableTens--; + changeNeeded -= 10; + Console.WriteLine("\t A ten"); + } + + while ((changeNeeded > 4) && (availableFives > 0)) + { + availableFives--; + changeNeeded -= 5; + Console.WriteLine("\t A five"); + } + + while ((changeNeeded > 0) && (availableOnes > 0)) + { + availableOnes--; + changeNeeded -= 1; + Console.WriteLine("\t A one"); + } + + if (changeNeeded > 0) + throw new InvalidOperationException("InvalidOperationException: The till is unable to make change for the cash provided."); + + cashTill[0] = availableOnes; + cashTill[1] = availableFives; + cashTill[2] = availableTens; + cashTill[3] = availableTwenties; + +} + +static void LogTillStatus(int[] cashTill) +{ + Console.WriteLine("The till currently has:"); + Console.WriteLine($"{cashTill[3] * 20} in twenties"); + Console.WriteLine($"{cashTill[2] * 10} in tens"); + Console.WriteLine($"{cashTill[1] * 5} in fives"); + Console.WriteLine($"{cashTill[0]} in ones"); + Console.WriteLine(); +} + +static string TillAmountSummary(int[] cashTill) +{ + return $"The till has {cashTill[3] * 20 + cashTill[2] * 10 + cashTill[1] * 5 + cashTill[0]} dollars"; + +} diff --git a/2-csharp/lesson-6-projects/challenge-project/LICENSE b/2-csharp/lesson-6-projects/challenge-project/LICENSE new file mode 100644 index 0000000..2080d95 --- /dev/null +++ b/2-csharp/lesson-6-projects/challenge-project/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/2-csharp/lesson-6-projects/challenge-project/README.md b/2-csharp/lesson-6-projects/challenge-project/README.md new file mode 100644 index 0000000..99a3642 --- /dev/null +++ b/2-csharp/lesson-6-projects/challenge-project/README.md @@ -0,0 +1,2 @@ +# Challenge-project-debugging-CSharp +Starter and Solution code for the Challenge project: "Debug a C# console application using Visual Studio Code" from the Microsoft Learn collection "Getting started with C#" diff --git a/2-csharp/lesson-6-projects/challenge-project/Starter/Program.cs b/2-csharp/lesson-6-projects/challenge-project/Starter/Program.cs new file mode 100644 index 0000000..b769206 --- /dev/null +++ b/2-csharp/lesson-6-projects/challenge-project/Starter/Program.cs @@ -0,0 +1,178 @@ +/* +This application manages transactions at a store check-out line. The +check-out line has a cash register, and the register has a cash till +that is prepared with a number of bills each morning. The till includes +bills of four denominations: $1, $5, $10, and $20. The till is used +to provide the customer with change during the transaction. The item +cost is a randomly generated number between 2 and 49. The customer +offers payment based on an algorithm that determines a number of bills +in each denomination. + +Each day, the cash till is loaded at the start of the day. As transactions +occur, the cash till is managed in a method named MakeChange (customer +payments go in and the change returned to the customer comes out). A +separate "safety check" calculation that's used to verify the amount of +money in the till is performed in the "main program". This safety check +is used to ensure that logic in the MakeChange method is working as +expected. +*/ + + +string? readResult = null; +bool useTestData = false; + +Console.Clear(); + +int[] cashTill = new int[] { 0, 0, 0, 0 }; +int registerCheckTillTotal = 0; + +// registerDailyStartingCash: $1 x 50, $5 x 20, $10 x 10, $20 x 5 => ($350 total) +int[,] registerDailyStartingCash = new int[,] { { 1, 50 }, { 5, 20 }, { 10, 10 }, { 20, 5 } }; + +int[] testData = new int[] { 6, 10, 17, 20, 31, 36, 40, 41 }; +int testCounter = 0; + +LoadTillEachMorning(registerDailyStartingCash, cashTill); + +registerCheckTillTotal = registerDailyStartingCash[0, 0] * registerDailyStartingCash[0, 1] + registerDailyStartingCash[1, 0] * registerDailyStartingCash[1, 1] + registerDailyStartingCash[2, 0] * registerDailyStartingCash[2, 1] + registerDailyStartingCash[3, 0] * registerDailyStartingCash[3, 1]; + +// display the number of bills of each denomination currently in the till +LogTillStatus(cashTill); + +// display a message showing the amount of cash in the till +Console.WriteLine(TillAmountSummary(cashTill)); + +// display the expected registerDailyStartingCash total +Console.WriteLine($"Expected till value: {registerCheckTillTotal}"); +Console.WriteLine(); + +var valueGenerator = new Random((int)DateTime.Now.Ticks); + +int transactions = 100; + +if (useTestData) +{ + transactions = testData.Length; +} + +while (transactions > 0) +{ + transactions -= 1; + int itemCost = valueGenerator.Next(2, 50); + + if (useTestData) + { + itemCost = testData[testCounter]; + testCounter += 1; + } + + int paymentOnes = itemCost % 2; // value is 1 when itemCost is odd, value is 0 when itemCost is even + int paymentFives = (itemCost % 10 > 7) ? 1 : 0; // value is 1 when itemCost ends with 8 or 9, otherwise value is 0 + int paymentTens = (itemCost % 20 > 13) ? 1 : 0; // value is 1 when 13 < itemCost < 20 OR 33 < itemCost < 40, otherwise value is 0 + int paymentTwenties = (itemCost < 20) ? 1 : 2; // value is 1 when itemCost < 20, otherwise value is 2 + + // display messages describing the current transaction + Console.WriteLine($"Customer is making a ${itemCost} purchase"); + Console.WriteLine($"\t Using {paymentTwenties} twenty dollar bills"); + Console.WriteLine($"\t Using {paymentTens} ten dollar bills"); + Console.WriteLine($"\t Using {paymentFives} five dollar bills"); + Console.WriteLine($"\t Using {paymentOnes} one dollar bills"); + + try + { + // MakeChange manages the transaction and updates the till + MakeChange(itemCost, cashTill, paymentTwenties, paymentTens, paymentFives, paymentOnes); + + // Backup Calculation - each transaction adds current "itemCost" to the till + registerCheckTillTotal += itemCost; + } + catch (InvalidOperationException e) + { + Console.WriteLine($"Could not complete transaction: {e.Message}"); + } + + Console.WriteLine(TillAmountSummary(cashTill)); + Console.WriteLine($"Expected till value: {registerCheckTillTotal}"); + Console.WriteLine(); +} + +Console.WriteLine("Press the Enter key to exit"); +do +{ + readResult = Console.ReadLine(); + +} while (readResult == null); + + +static void LoadTillEachMorning(int[,] registerDailyStartingCash, int[] cashTill) +{ + cashTill[0] = registerDailyStartingCash[0, 1]; + cashTill[1] = registerDailyStartingCash[1, 1]; + cashTill[2] = registerDailyStartingCash[2, 1]; + cashTill[3] = registerDailyStartingCash[3, 1]; +} + + +static void MakeChange(int cost, int[] cashTill, int twenties, int tens = 0, int fives = 0, int ones = 0) +{ + cashTill[3] += twenties; + cashTill[2] += tens; + cashTill[1] += fives; + cashTill[0] += ones; + + int amountPaid = twenties * 20 + tens * 10 + fives * 5 + ones; + int changeNeeded = amountPaid - cost; + + if (changeNeeded < 0) + throw new InvalidOperationException("InvalidOperationException: Not enough money provided to complete the transaction."); + + Console.WriteLine("Cashier prepares the following change:"); + + while ((changeNeeded > 19) && (cashTill[3] > 0)) + { + cashTill[3]--; + changeNeeded -= 20; + Console.WriteLine("\t A twenty"); + } + + while ((changeNeeded > 9) && (cashTill[2] > 0)) + { + cashTill[2]--; + changeNeeded -= 10; + Console.WriteLine("\t A ten"); + } + + while ((changeNeeded > 4) && (cashTill[1] > 0)) + { + cashTill[1]--; + changeNeeded -= 5; + Console.WriteLine("\t A five"); + } + + while ((changeNeeded > 0) && (cashTill[0] > 0)) + { + cashTill[0]--; + changeNeeded -= 1; + Console.WriteLine("\t A one"); + } + + if (changeNeeded > 0) + throw new InvalidOperationException("InvalidOperationException: The till is unable to make change for the cash provided."); + +} + +static void LogTillStatus(int[] cashTill) +{ + Console.WriteLine("The till currently has:"); + Console.WriteLine($"{cashTill[3] * 20} in twenties"); + Console.WriteLine($"{cashTill[2] * 10} in tens"); + Console.WriteLine($"{cashTill[1] * 5} in fives"); + Console.WriteLine($"{cashTill[0]} in ones"); + Console.WriteLine(); +} + +static string TillAmountSummary(int[] cashTill) +{ + return $"The till has {cashTill[3] * 20 + cashTill[2] * 10 + cashTill[1] * 5 + cashTill[0]} dollars"; + +} diff --git a/2-csharp/lesson-6-projects/challenge-project/Starter/Starter.csproj b/2-csharp/lesson-6-projects/challenge-project/Starter/Starter.csproj new file mode 100644 index 0000000..f02677b --- /dev/null +++ b/2-csharp/lesson-6-projects/challenge-project/Starter/Starter.csproj @@ -0,0 +1,10 @@ + + + + Exe + net7.0 + enable + enable + + + diff --git a/2-csharp/lesson-6-projects/guided-project/Final/Final.csproj b/2-csharp/lesson-6-projects/guided-project/Final/Final.csproj new file mode 100644 index 0000000..f02677b --- /dev/null +++ b/2-csharp/lesson-6-projects/guided-project/Final/Final.csproj @@ -0,0 +1,10 @@ + + + + Exe + net7.0 + enable + enable + + + diff --git a/2-csharp/lesson-6-projects/guided-project/Final/Program.cs b/2-csharp/lesson-6-projects/guided-project/Final/Program.cs new file mode 100644 index 0000000..f50f7bc --- /dev/null +++ b/2-csharp/lesson-6-projects/guided-project/Final/Program.cs @@ -0,0 +1,178 @@ +/* +This application manages transactions at a store check-out line. The +check-out line has a cash register, and the register has a cash till +that is prepared with a number of bills each morning. The till includes +bills of four denominations: $1, $5, $10, and $20. The till is used +to provide the customer with change during the transaction. The item +cost is a randomly generated number between 2 and 49. The customer +offers payment based on an algorithm that determines a number of bills +in each denomination. + +Each day, the cash till is loaded at the start of the day. As transactions +occur, the cash till is managed in a method named MakeChange (customer +payments go in and the change returned to the customer comes out). A +separate "safety check" calculation that's used to verify the amount of +money in the till is performed in the "main program". This safety check +is used to ensure that logic in the MakeChange method is working as +expected. +*/ + + +string? readResult = null; +bool useTestData = false; + +Console.Clear(); + +int[] cashTill = new int[] { 0, 0, 0, 0 }; +int registerCheckTillTotal = 0; + +// registerDailyStartingCash: $1 x 50, $5 x 20, $10 x 10, $20 x 5 => ($350 total) +int[,] registerDailyStartingCash = new int[,] { { 1, 50 }, { 5, 20 }, { 10, 10 }, { 20, 5 } }; + +int[] testData = new int[] { 6, 10, 17, 20, 31, 36, 40, 41 }; +int testCounter = 0; + +LoadTillEachMorning(registerDailyStartingCash, cashTill); + +registerCheckTillTotal = registerDailyStartingCash[0, 0] * registerDailyStartingCash[0, 1] + registerDailyStartingCash[1, 0] * registerDailyStartingCash[1, 1] + registerDailyStartingCash[2, 0] * registerDailyStartingCash[2, 1] + registerDailyStartingCash[3, 0] * registerDailyStartingCash[3, 1]; + +// display the number of bills of each denomination currently in the till +LogTillStatus(cashTill); + +// display a message showing the amount of cash in the till +Console.WriteLine(TillAmountSummary(cashTill)); + +// display the expected registerDailyStartingCash total +Console.WriteLine($"Expected till value: {registerCheckTillTotal}"); +Console.WriteLine(); + +var valueGenerator = new Random((int)DateTime.Now.Ticks); + +int transactions = 10; + +if (useTestData) +{ + transactions = testData.Length; +} + +while (transactions > 0) +{ + transactions -= 1; + int itemCost = valueGenerator.Next(2, 50); + + if (useTestData) + { + itemCost = testData[testCounter]; + testCounter += 1; + } + + int paymentOnes = itemCost % 2; // value is 1 when itemCost is odd, value is 0 when itemCost is even + int paymentFives = (itemCost % 10 > 7) ? 1 : 0; // value is 1 when itemCost ends with 8 or 9, otherwise value is 0 + int paymentTens = (itemCost % 20 > 13) ? 1 : 0; // value is 1 when 13 < itemCost < 20 OR 33 < itemCost < 40, otherwise value is 0 + int paymentTwenties = (itemCost < 20) ? 1 : 2; // value is 1 when itemCost < 20, otherwise value is 2 + + // display messages describing the current transaction + Console.WriteLine($"Customer is making a ${itemCost} purchase"); + Console.WriteLine($"\t Using {paymentTwenties} twenty dollar bills"); + Console.WriteLine($"\t Using {paymentTens} ten dollar bills"); + Console.WriteLine($"\t Using {paymentFives} five dollar bills"); + Console.WriteLine($"\t Using {paymentOnes} one dollar bills"); + + try + { + // MakeChange manages the transaction and updates the till + MakeChange(itemCost, cashTill, paymentTwenties, paymentTens, paymentFives, paymentOnes); + + // Backup Calculation - each transaction adds current "itemCost" to the till + registerCheckTillTotal += itemCost; + } + catch (InvalidOperationException e) + { + Console.WriteLine($"Could not make transaction: {e.Message}"); + } + + Console.WriteLine(TillAmountSummary(cashTill)); + Console.WriteLine($"Expected till value: {registerCheckTillTotal}"); + Console.WriteLine(); +} + +Console.WriteLine("Press the Enter key to exit"); +do +{ + readResult = Console.ReadLine(); + +} while (readResult == null); + + +static void LoadTillEachMorning(int[,] registerDailyStartingCash, int[] cashTill) +{ + cashTill[0] = registerDailyStartingCash[0, 1]; + cashTill[1] = registerDailyStartingCash[1, 1]; + cashTill[2] = registerDailyStartingCash[2, 1]; + cashTill[3] = registerDailyStartingCash[3, 1]; +} + + +static void MakeChange(int cost, int[] cashTill, int twenties, int tens = 0, int fives = 0, int ones = 0) +{ + cashTill[3] += twenties; + cashTill[2] += tens; + cashTill[1] += fives; + cashTill[0] += ones; + + int amountPaid = twenties * 20 + tens * 10 + fives * 5 + ones; + int changeNeeded = amountPaid - cost; + + if (changeNeeded < 0) + throw new InvalidOperationException("Not enough money provided"); + + Console.WriteLine("Cashier Returns:"); + + while ((changeNeeded > 19) && (cashTill[3] > 0)) + { + cashTill[3]--; + changeNeeded -= 20; + Console.WriteLine("\t A twenty"); + } + + while ((changeNeeded > 9) && (cashTill[2] > 0)) + { + cashTill[2]--; + changeNeeded -= 10; + Console.WriteLine("\t A ten"); + } + + while ((changeNeeded > 4) && (cashTill[1] > 0)) + { + cashTill[1]--; + changeNeeded -= 5; + Console.WriteLine("\t A five"); + } + + while ((changeNeeded > 0) && (cashTill[0] > 0)) + { + cashTill[0]--; + changeNeeded -= 1; + Console.WriteLine("\t A one"); + } + + if (changeNeeded > 0) + throw new InvalidOperationException("Can't make change. Do you have anything smaller?"); + +} + +static void LogTillStatus(int[] cashTill) +{ + Console.WriteLine("The till currently has:"); + Console.WriteLine($"{cashTill[3] * 20} in twenties"); + Console.WriteLine($"{cashTill[2] * 10} in tens"); + Console.WriteLine($"{cashTill[1] * 5} in fives"); + Console.WriteLine($"{cashTill[0]} in ones"); + Console.WriteLine(); +} + +static string TillAmountSummary(int[] cashTill) +{ + return $"The till has {cashTill[3] * 20 + cashTill[2] * 10 + cashTill[1] * 5 + cashTill[0]} dollars"; + +} diff --git a/2-csharp/lesson-6-projects/guided-project/LICENSE b/2-csharp/lesson-6-projects/guided-project/LICENSE new file mode 100644 index 0000000..2080d95 --- /dev/null +++ b/2-csharp/lesson-6-projects/guided-project/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/2-csharp/lesson-6-projects/guided-project/README.md b/2-csharp/lesson-6-projects/guided-project/README.md new file mode 100644 index 0000000..9ac6f1c --- /dev/null +++ b/2-csharp/lesson-6-projects/guided-project/README.md @@ -0,0 +1,2 @@ +# Guided-project-debugging-CSharp +Starter and Solution code for the Guided project: "Debug and handle exceptions in a C# console application using Visual Studio Code" from the Microsoft Learn collection "Getting started with C#" diff --git a/2-csharp/lesson-6-projects/guided-project/Starter/Program.cs b/2-csharp/lesson-6-projects/guided-project/Starter/Program.cs new file mode 100644 index 0000000..9cc76e1 --- /dev/null +++ b/2-csharp/lesson-6-projects/guided-project/Starter/Program.cs @@ -0,0 +1,183 @@ +/* +This application manages transactions at a store check-out line. The +check-out line has a cash register, and the register has a cash till +that is prepared with a number of bills each morning. The till includes +bills of four denominations: $1, $5, $10, and $20. The till is used +to provide the customer with change during the transaction. The item +cost is a randomly generated number between 2 and 49. The customer +offers payment based on an algorithm that determines a number of bills +in each denomination. + +Each day, the cash till is loaded at the start of the day. As transactions +occur, the cash till is managed in a method named MakeChange (customer +payments go in and the change returned to the customer comes out). A +separate "safety check" calculation that's used to verify the amount of +money in the till is performed in the "main program". This safety check +is used to ensure that logic in the MakeChange method is working as +expected. +*/ + +string? readResult = null; +bool useTestData = true; + +Console.Clear(); + +int[] cashTill = new int[] { 0, 0, 0, 0 }; +int registerCheckTillTotal = 0; + +// registerDailyStartingCash: $1 x 50, $5 x 20, $10 x 10, $20 x 5 => ($350 total) +int[,] registerDailyStartingCash = new int[,] { { 1, 50 }, { 5, 20 }, { 10, 10 }, { 20, 5 } }; + +int[] testData = new int[] { 6, 10, 17, 20, 31, 36, 40, 41 }; +int testCounter = 0; + +LoadTillEachMorning(registerDailyStartingCash, cashTill); + +registerCheckTillTotal = registerDailyStartingCash[0, 0] * registerDailyStartingCash[0, 1] + registerDailyStartingCash[1, 0] * registerDailyStartingCash[1, 1] + registerDailyStartingCash[2, 0] * registerDailyStartingCash[2, 1] + registerDailyStartingCash[3, 0] * registerDailyStartingCash[3, 1]; + +// display the number of bills of each denomination currently in the till +LogTillStatus(cashTill); + +// display a message showing the amount of cash in the till +Console.WriteLine(TillAmountSummary(cashTill)); + +// display the expected registerDailyStartingCash total +Console.WriteLine($"Expected till value: {registerCheckTillTotal}\n\r"); + +var valueGenerator = new Random((int)DateTime.Now.Ticks); + +int transactions = 10; + +if (useTestData) +{ + transactions = testData.Length; +} + +while (transactions > 0) +{ + transactions -= 1; + int itemCost = valueGenerator.Next(2, 20); + + if (useTestData) + { + itemCost = testData[testCounter]; + testCounter += 1; + } + + int paymentOnes = itemCost % 2; // value is 1 when itemCost is odd, value is 0 when itemCost is even + int paymentFives = (itemCost % 10 > 7) ? 1 : 0; // value is 1 when itemCost ends with 8 or 9, otherwise value is 0 + int paymentTens = (itemCost % 20 > 13) ? 1 : 0; // value is 1 when 13 < itemCost < 20 OR 33 < itemCost < 40, otherwise value is 0 + int paymentTwenties = (itemCost < 20) ? 1 : 2; // value is 1 when itemCost < 20, otherwise value is 2 + + // display messages describing the current transaction + Console.WriteLine($"Customer is making a ${itemCost} purchase"); + Console.WriteLine($"\t Using {paymentTwenties} twenty dollar bills"); + Console.WriteLine($"\t Using {paymentTens} ten dollar bills"); + Console.WriteLine($"\t Using {paymentFives} five dollar bills"); + Console.WriteLine($"\t Using {paymentOnes} one dollar bills"); + + // MakeChange manages the transaction and updates the till + string transactionMessage = MakeChange(itemCost, cashTill, paymentTwenties, paymentTens, paymentFives, paymentOnes); + + // Backup Calculation - each transaction adds current "itemCost" to the till + if (transactionMessage == "transaction succeeded") + { + Console.WriteLine($"Transaction successfully completed."); + registerCheckTillTotal += itemCost; + } + else + { + Console.WriteLine($"Transaction unsuccessful: {transactionMessage}"); + } + + Console.WriteLine(TillAmountSummary(cashTill)); + Console.WriteLine($"Expected till value: {registerCheckTillTotal}\n\r"); + Console.WriteLine(); +} + +Console.WriteLine("Press the Enter key to exit"); +do +{ + readResult = Console.ReadLine(); + +} while (readResult == null); + + +static void LoadTillEachMorning(int[,] registerDailyStartingCash, int[] cashTill) +{ + cashTill[0] = registerDailyStartingCash[0, 1]; + cashTill[1] = registerDailyStartingCash[1, 1]; + cashTill[2] = registerDailyStartingCash[2, 1]; + cashTill[3] = registerDailyStartingCash[3, 1]; +} + + +static string MakeChange(int cost, int[] cashTill, int twenties, int tens = 0, int fives = 0, int ones = 0) +{ + string transactionMessage = ""; + + cashTill[3] += twenties; + cashTill[2] += tens; + cashTill[1] += fives; + cashTill[0] += ones; + + int amountPaid = twenties * 20 + tens * 10 + fives * 5 + ones; + int changeNeeded = amountPaid - cost; + + if (changeNeeded < 0) + transactionMessage = "Not enough money provided."; + + Console.WriteLine("Cashier Returns:"); + + while ((changeNeeded > 19) && (cashTill[3] > 0)) + { + cashTill[3]--; + changeNeeded -= 20; + Console.WriteLine("\t A twenty"); + } + + while ((changeNeeded > 9) && (cashTill[2] > 0)) + { + cashTill[2]--; + changeNeeded -= 10; + Console.WriteLine("\t A ten"); + } + + while ((changeNeeded > 4) && (cashTill[1] > 0)) + { + cashTill[2]--; + changeNeeded -= 5; + Console.WriteLine("\t A five"); + } + + while ((changeNeeded > 0) && (cashTill[0] > 0)) + { + cashTill[0]--; + changeNeeded--; + Console.WriteLine("\t A one"); + } + + if (changeNeeded > 0) + transactionMessage = "Can't make change. Do you have anything smaller?"; + + if (transactionMessage == "") + transactionMessage = "transaction succeeded"; + + return transactionMessage; +} + +static void LogTillStatus(int[] cashTill) +{ + Console.WriteLine("The till currently has:"); + Console.WriteLine($"{cashTill[3] * 20} in twenties"); + Console.WriteLine($"{cashTill[2] * 10} in tens"); + Console.WriteLine($"{cashTill[1] * 5} in fives"); + Console.WriteLine($"{cashTill[0]} in ones"); + Console.WriteLine(); +} + +static string TillAmountSummary(int[] cashTill) +{ + return $"The till has {cashTill[3] * 20 + cashTill[2] * 10 + cashTill[1] * 5 + cashTill[0]} dollars"; + +} diff --git a/2-csharp/lesson-6-projects/guided-project/Starter/Starter.csproj b/2-csharp/lesson-6-projects/guided-project/Starter/Starter.csproj new file mode 100644 index 0000000..f02677b --- /dev/null +++ b/2-csharp/lesson-6-projects/guided-project/Starter/Starter.csproj @@ -0,0 +1,10 @@ + + + + Exe + net7.0 + enable + enable + + + diff --git a/3-razor-pages/README.md b/3-razor-pages/README.md index db9401d..b672464 100644 --- a/3-razor-pages/README.md +++ b/3-razor-pages/README.md @@ -14,6 +14,15 @@ In Razor Pages applications, you’ll write your logic in a Page Model class, an ## Installing the tools +You can utilize your editor of choice for this course. Below we've included instructions for GitHub Codespaces and Visual Studio. + +### GitHub Codespaces + +1. Open a GitHub Codespace. To do this, simply select the green **Code** button. Then click the **+** to create a Codespace on the main branch. +2. Navigate to the project files in the [0-start/RazorPagesPizza folder](0-start/RazorPagesPizza) + +### Visual Studio + We'll be using Visual Studio 2022 for whole course. If you don't have Visual Studio 2022 installed, you can follow the [directions here](/1-welcome/how-to-install-vs.md). ## Creating a Razor Pages project diff --git a/5-blazor/README.md b/5-blazor/README.md index 52f21ac..c7ac388 100644 --- a/5-blazor/README.md +++ b/5-blazor/README.md @@ -30,15 +30,22 @@ We'll accomllish this by writing a classic four-in-a-row "Connect Four" game tha First, let's scaffold a new project for our game. With .NET 6 installed, we can start building our application at the command-line. +**GitHub Codespaces Instructions** + +1. Open a GitHub Codespace. To do this, simply select the green **Code** button. Then click the **+** to create a Codespace on the main branch. +2. Navigate to the project files in the [0-start folder](0-start) + +**Visual Studio Instructions** + 1. Create a new blazor application in Visual Studio 2022 by choosing the "File - New... - Project" menu. -1. Choose a "Blazor WebAssembly App" from the list of templates and name it "ConnectFour". Click next +2. Choose a "Blazor WebAssembly App" from the list of templates and name it "ConnectFour". Click next -1. Choose the .NET 6 framework, Authentication type should be set to "None" and uncheck the "ASP.NET Core hosted" checkbox. +3. Choose the .NET 6 framework, Authentication type should be set to "None" and uncheck the "ASP.NET Core hosted" checkbox. This should create a _ConnectFour_ directory containing our application. -2. Run the app by pressing F5 in Visual Studio 2022. This builds the app and hosts it on a random port between 5000 and 5300. HTTPS has a port selected for it in the range of 7000 to 7300. +4. Run the app by pressing F5 in Visual Studio 2022. This builds the app and hosts it on a random port between 5000 and 5300. HTTPS has a port selected for it in the range of 7000 to 7300. Your Output Window should report content similar to the following: @@ -56,7 +63,7 @@ First, let's scaffold a new project for our game. With .NET 6 installed, we can Content root path: C:\dev\ConnectFour ``` -1. Let's navigate to the address our web server announced it's serving the application at. You might be able to Ctrl+Click on the address in your terminal, or just copy the address into your browser. In the above sample, we would navigate to `http://localhost:5136`. You should be presented with the following welcome screen in your browser: +5. Let's navigate to the address our web server announced it's serving the application at. You might be able to Ctrl+Click on the address in your terminal, or just copy the address into your browser. In the above sample, we would navigate to `http://localhost:5136`. You should be presented with the following welcome screen in your browser: ![Screenshot from the new Blazor Template](img/1-NewTemplate.png) diff --git a/README.md b/README.md index 29b3ede..3b4ba71 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,9 @@ Here, you'll find a 6-part series of lessons and projects to get you started bui ## How-to To use this curriculum on your own, fork the entire repo and go into the numbered folders to access the lessons and projects. This series is designed to take 6 weeks, about 1 week per lesson, but feel free to complete it at your own pace. +### Codespace +You can also complete the lesson from your browser using GitHub Codespaces. To open a Codespace, simply select the green **Code** button. Then click the **+** to create a Codespace on the main branch. + ## Lessons | | Lesson Name | Learning Objectives | Linked Lesson | | :-: | :------------------------------------------------------: | ----------------------------------------------------------------------------------------------------------------------------------- | :----------------------------------------------------------------------------------------------------------------------------: |