diff --git a/029_return_value_method/029_csharp.md b/029_return_value_method/029_csharp.md new file mode 100644 index 0000000..d27fb15 --- /dev/null +++ b/029_return_value_method/029_csharp.md @@ -0,0 +1,1250 @@ +# Create C# methods that return values + +Learn to create methods that return values + +### Learning objectives + +- Understand return types +- Learn more about the return keyword +- Learn more about capturing method return values + +## Introduction + +Methods can provide return values after performing their tasks. By using +parameters and return types together, you can create streamlined methods that +receive input, perform a task, and provide output. This format allows you to +efficiently build functionality into your programs while maintaining clean, +readable code. + +Suppose you need to create an application that uses many methods to perform +calculations on input values. You need a way to retrieve the results of the +calculations, and use those results throughout your program. You can do this by +creating methods with return values. + +Consider a game where the player must fight enemies. The game contains some +code that determines if a character was hit whenever an `Update()` method is +called. The code might contain the following methods: + +```cs +void Update(); + +int[] GetEnemyCoordinates(string enemyId); +int[] GetDistanceFromHero(string enemyId); +int[] GetHeroCoordinates(); + +bool EnemyCanHitHero(string enemyId); +int GetEnemyDamageOutput(string enemyId); +void UpdateHeroHP(int damage); +``` + +Looking at the method signatures, you can imagine how the input and output of +each method can be used across the program. The methods also make the game code +more robust since each one has return values that can be used for different +types of scenarios. + +Capturing return values from methods is incredibly useful for all sorts of +applications. In this module, you'll learn more about method execution and +working with method return types. + +#### Learning Objectives + +In this module, you will: + +- Understand return types +- Learn more about the `return` keyword +- Learn more about capturing method return values + +--- + +## Exercise + +### Understand return type syntax + +Not only can methods perform operations, they can return a value as well. +Methods can return a value by including the return type in the method signature. +Methods can return any data type, or they can return nothing at all. The return +type must always be specified before the method name. + +Using `void` as the return type means the method only performs operations and +doesn't return a value. For example: + +```cs +void PrintMessage(string message) +``` + +When a data type (such as `int`, `string`, `bool`, etc.) is used, the method +performs operations and then returns the specified type upon completion. Inside +the method, the keyword `return` is used to return the result. In `void` +methods, you can also use the `return` keyword to terminate the method. + +In this exercise, you'll learn more about using the `return` keyword. + +### Prepare your coding environment + +At the Terminali, create a new console application in a +specified folder. + +Delete the existing code lines. + +You'll be using this C# console project to create, build, and run code samples +during this module. + +#### Use methods to calculate the total purchase price + +The Contoso Shopping Center is having a super sale! Many items have discounted +price. You're given a list of item prices and a list of corresponding discounts. +The discounts are represented by percentages, for example **50% = 0.5**. If a +customer spends more than **$30.00**, they recieve **$5.00 of** their total +purchase. In this task, you'll write code to calculate the customer's total. +Let's get started! + +Enter the following code into the Visual Studio Code Editor: + +```cs +double total = 0; +double minimumSpend = 30.00; + +double[] items = {15.97, 3.50, 12.25, 22.99, 10.98}; +double[] discounts = {0.30, 0.00, 0.10, 0.20, 0.50}; + +Console.WriteLine($"Total: ${total}"); + +void GetDiscountedPrice(int itemIndex) { + // Calculate the discounted price of the item +} + +void TotalMeetsMinimum() { + // Check if the total meets the minimum +} + +void FormatDecimal(double input) { + // Format the double so only 2 decimal places are displayed +} +``` + +In this step, you set up the variables your program will need and create +placeholder methods that will be used to perform the tasks to get the total +purchase price. + +Change the `GetDiscountedPrice` method to return a `double` by updating your +code to the following: + +```cs +double GetDiscountedPrice(int itemIndex) { + // Calculate the discounted price of the item +} +``` + +Notice that this method yields the compilation error: `not all code paths +return a value.` A method with a return type must always return a value of that +type. Let's fix this error. + +Update the `GetDiscountedPrice` method with the following code: + +```cs +double GetDiscountedPrice(int itemIndex) { + double result = items[itemIndex] * (1 - discounts[itemIndex]); + return result; +} +``` + +To return a value from a method, add a value or expression after the return +keyword. The value returned must match the data type specified in the method +signature. + +In this code, you calculate the discounted price of the item at `itemIndex` and +then return the result. However, the `return` keyword isn't limited to +returning variables or literal values. Let's skip the variable and return the +expression instead. + +Update the `GetDiscountedPrice` method with the following code: + +```cs +double GetDiscountedPrice(int itemIndex) { + return items[itemIndex] * (1 - discounts[itemIndex]); +} +``` + +Since the code `items[itemIndex] * (1 - discounts[itemIndex])` evaluates to a +`double` value, this `return` statement is valid. + +Change the `TotalMeetsMinimum` method to return a `bool` by updating your code +to the following: + +```cs +bool TotalMeetsMinimum() { + return total >= minimumSpend; +} +``` + +In this code, you return the result of the comparison that evaluates to a +`bool`. Returning expressions from methods is a great way to make your code +organized and improve readability. + +Change the `FormatDecimal` method to return a `string` by updating your code to +the following: + +```cs +string FormatDecimal(double input) { + return input.ToString().Substring(0, 5); +} +``` + +Notice that you can call other methods in a `return` statement expression. When +this method is called, the execution control first evaluates `input.ToString`, +then evaluates and returns the substring value. The flexibility of the `return` +keyword allows you to create short lines of code packed with functionality. + +#### Capture the return values + +Now that your methods return values, you can capture these values and use them +in the rest of your code. Using results returned from methods is a great way to +keep your code structured and easy to read. Let's practice! + +Locate the following line of code in your program: + +```cs +Console.WriteLine($"Total: ${total}"); +``` + +Update your code to the following: + +```cs +for (int i = 0; i < items.Length; i++) { + total += GetDiscountedPrice(i); +} + +Console.WriteLine($"Total: ${total}"); +``` + +In this code, you use the `for` loop to get the sum of all of the discounted +item prices. Since `GetDiscountedPrice` returns a `double` value, you can use +the method to initialize or operate on any other `double` variables. In this +case, you use the result of `GetDiscountedPrice` to increment `total`. + +Enter a new blank code line before `Console.WriteLine`, then add the following +code: + +```cs +if (TotalMeetsMinimum()) { + total -= 5.00; +} +``` + +Since `TotalMeetsMinimum` returns a `bool` value, you can call the method +inside of the `if` condition. You can also use this method in a ternary +expression as follows: + +`total -= TotalMeetsMinimum() ? 5.00 : 0.00;` + +Use `FormatDecimal` to format the displayed purchase price by updating your code as follows: + +```cs +Console.WriteLine($"Total: ${FormatDecimal(total)}"); +``` + +Similar to the previous code, `FormatDecimal` returns a `string` value. So you +can call the method in place of using a string variable or literal. In this +code, execution control is passed to `FormatDecimal` to evaluate the result +before evaluating `Console.WriteLine`. + +### Check your work + +In this task, you'll run your application from the Integrated Terminal and +verify your code is working correctly. Let's get started. + +Compare your code with the following to ensure it's correct: + +```cs +double total = 0; +double minimumSpend = 30.00; + +double[] items = {15.97, 3.50, 12.25, 22.99, 10.98}; +double[] discounts = {0.30, 0.00, 0.10, 0.20, 0.50}; + +for (int i = 0; i < items.Length; i++) { + total += GetDiscountedPrice(i); +} + +total -= TotalMeetsMinimum() ? 5.00 : 0.00; + +Console.WriteLine($"Total: ${FormatDecimal(total)}"); + +double GetDiscountedPrice(int itemIndex) { + return items[itemIndex] * (1 - discounts[itemIndex]); +} + +bool TotalMeetsMinimum() { + return total >= minimumSpend; +} + +string FormatDecimal(double input) { + return input.ToString().Substring(0, 5); +} +``` + +At the Terminal command prompt, enter `dotnet run` + +Verify that your code produces the following output: + +```txt +Total: $44.58 +``` + +If your code displays different results, you'll need to review your code to +find your error and make updates. Run the code again to see if you've fixed the +problem. Continue updating and running your code until your code produces the +expected results. + +- [Program.cs](./return_meth/Program.cs) + +### Recap + +Here's what you've learned about the `return` keyword so far: + +- Methods can return a value by specifying the return data type, or `void` for +no return value +- The `return` keyword can be used with variables, literals, and expressions +- The value returned from a method must match the specified return type +- Data returned from methods can be captured and used by the caller of the +method + +--- + +## Exercise + +### Return numbers from methods + +You might often need to return numbers from methods and use the results for +other tasks. In this brief exercise, you'll practice returning int and double +data types, and capturing the return values. + +### Create a method that returns an integer + +Suppose you're visiting Vietnam and want to create a brief program that +converts currency. You can assume the current exchange rate is `1 USD = 23500 +VND`. In this task, you'll write a method that converts USD to VND. + +Enter the following code into the code editor: + +```cs +double usd = 23.73; +int vnd = UsdToVnd(usd); + +Console.WriteLine($"${usd} USD = ${vnd} VND"); + +int UsdToVnd(double usd) { + +} +``` + +In this step, you initialize two variables to store the USD and VND values. +Notice that `vnd` is initialized to the result of the method `UsdToVnd`. The +method returns an integer value since VND is typically represented in whole +numbers. To display the results of the currency conversion, `Console.WriteLine` +is used. + +Next, you'll add code to perform the conversion. Update the `UsdToVnd` method +with the following code: + +```cs +int UsdToVnd(double usd) { + int rate = 23500; + return (int) (rate * usd); +} +``` + +If you omit the cast from the return result, you'll see the following error: + +```txt +Cannot implicitly convert type 'double' to 'int'. +``` + +This happens because the compiler attempts to cast the value returned to match +the data type specified in the method signature. However, implicit casting is +only available when there's no data loss occurring as a result of the +conversion. The return value must always match the data type specified in the +method signature, so in this case, you must cast the result. + +At the Terminal command prompt, enter `dotnet run` and compare your output with +the following: + +```txt +$23.73 USD = $557655 VND +``` + +If your code displays unexpected results, you'll need to review your code to +find your error and make updates. Run the code again to see if you've fixed the +problem. Continue updating and running your code until your code produces the +expected results. + +#### Create a method that returns a double + +Next, you'll create a method to convert VND back to USD. + +Create a new blank code line at the end of the `UsdToVnd` method. + +Enter the following code: + +```cs +double VndToUsd(int vnd) { + +} +``` + +Update the `VndToUsd` method with the following code: + +```cs +double VndToUsd(int vnd) { + double rate = 23500; + return vnd / rate; +} +``` + +In this case, you need `rate` to be a `double` or else the compiler uses +integer division and return a truncated `int` value. USD needs to be +represented by a decimal number. + +If you set `rate` to an `int` instead of `double`, you'll notice that the +compiler doesn't present you with any errors. This happens because the value of +`vnd / rate` is implicitly casted to the `double` data type specified in the +method signature. When creating methods that return numeric values, it's +important to consider the data types in the operations your method performs. + +Locate the call to `Console.WriteLine` and append a new blank code line. Then +enter the following code to call our new method and print the output: + +```cs +Console.WriteLine($"${vnd} VND = ${VndToUsd(vnd)} USD"); +``` + +### Check your work + +In this task, you'll run our application from the Terminal and verify your code +is working correctly. Let's get started. + +Compare your code to the following to ensure it's correct: + +```cs +double usd = 23.73; +int vnd = UsdToVnd(usd); + +Console.WriteLine($"${usd} USD = ${vnd} VND"); +Console.WriteLine($"${vnd} VND = ${VndToUsd(vnd)} USD"); + +int UsdToVnd(double usd) { + int rate = 23500; + return (int) (rate * usd); +} + +double VndToUsd(int vnd) { + double rate = 23500; + return vnd / rate; +} +``` + +At the Terminal command prompt, enter `dotnet run` + +Verify that your code produces the following output: + +```txt +$23.73 USD = $557655 VND +$557655 VND = $23.73 USD +``` + +If your code displays different results, you'll need to review your code to +find your error and make updates. Run the code again to see if you've fixed the +problem. Continue updating and running your code until your code produces the +expected results. + +- [Program.cs](./return_nums/Program.cs) + +--- + +## Exercise + +### Return strings from methods + +You may often find that you need to write a method that returns a string. For +example, you may want to retrieve a string from a set of data or modify a +string in some way. In this exercise, you'll gain some experience working with +strings in methods while practicing a common interview question. + +#### Create a method that returns a string + +Suppose you're a candidate in a coding interview. The interviewer asks you to +write a method to reverse a string without using `string.Reverse`. Take a +moment to think about how you might accomplish this task. + +You might have decided that you can reverse a string by iterating from the end +of the string. You can use a temporary string to store each letter from end to +beginning. Let's get started! + +Enter the following code in the editor: + +```cs +string ReverseWord(string word) { + string result = ""; + + return result; +} +``` + +The method needs to iterate through the given word and update the result. To do +this, update the `ReverseWord` method with the following code: + +```cs +string ReverseWord(string word) { + string result = ""; + for (int i = word.Length - 1; i >= 0; i--) { + result += word[i]; + } + return result; +} +``` + +In this code block, you start from the end of the word using `word.Length - 1`. +You subtract one from the length since array indices start at zero, and you +want to avoid accessing an element out of bounds. Then you add the letter at +the current index to the `result` string and move the index backwards. You use +`i >= 0` since `i` is updated after the code in the loop is executed, and you +want to be sure to include the zeroth index. + +#### Test your code + +When coding, it's important to frequently check your work. Finding and +correcting mistakes early in the coding process allows you to spend more time +building upon correct code rather than debugging one large program. Checking +your work frequently is a skill that coding interviewers value highly as well. + +Enter a new blank code line. Then create some input text and call your method +by entering the following code above the `ReverseWord` method: + +```cs +string input = "snake"; + +Console.WriteLine(input); +Console.WriteLine(ReverseWord(input)); +``` + +At the Terminal command prompt, enter `dotnet run`. Compare your output with +the following: + +```txt +snake +ekans +``` + +If your code displays unexpected results, you'll need to review your code to +find your error and make updates. Run the code again to see if you've fixed the +problem. Continue updating and running your code until your code produces the +expected results. + +#### Create a method to reverse words in a sentence + +Suppose your interviewer asks you a follow up question. They want you to +reverse each word in a given sentence, maintaining the original position of +each word. You can assume each word is separated by a space. For example, +"string return type" would become "gnirts nruter epyt". Take a moment to think +about how you might perform this task. + +If you use the method you wrote in the previous task, you might realize that +you can use the method to reverse each word in the string individually. You can +create a new sentence and add each word as it's reversed. Let's get started! + +Create a new blank code line at the end of the current program. Then enter the +following code to create a new method: + +```cs +string ReverseSentence(string input) { + string result = ""; + + return result; +} +``` + +Next, you can extract the individual words from the string using `string.Split`. +Update the `ReverseSentence` method to the following: + +```cs +string ReverseSentence(string input) { + string result = ""; + string[] words = input.Split(" "); + + return result; +} +``` + +Now that you have access to each individual word in the sentence, you can use +your ReverseWord method on each word and store them in result. + +Update the `ReverseSentence` method to the following: + +```cs +string ReverseSentence(string input) { + string result = ""; + string[] words = input.Split(" "); + foreach(string word in words) { + result += ReverseWord(word) + " "; + } + return result; +} +``` + +Notice how you can call the `ReverseWord` method inside of a compound +assignment operator. In this code, the return value is captured from +`ReverseWord` and added to `result`. Methods with return values can be used +anywhere you need them, as long as the data type fits the requirements. + +In this code, each reversed word is appended to the result with an added space. +However, this leaves an extra space at the end of the reversed sentence. + +You can remove the extra space at the end using `string.Trim`. Update the +method to the following code: + +```cs +string ReverseSentence(string input) { + string result = ""; + string[] words = input.Split(" "); + foreach(string word in words) { + result += ReverseWord(word) + " "; + } + return result.Trim(); +} +``` + +Take a moment to consider the return result of this method. A method can use +other methods throughout its execution and even in the return statement, as +long as the data types match. + +Now you're ready to call your method! + +Update the `input` text and the `Console.WriteLine` statement to the following: + +```cs +string input = "there are snakes at the zoo"; + +Console.WriteLine(input); +Console.WriteLine(ReverseSentence(input)); +``` + +### Check your work + +Compare your code with the following to ensure it's correct: + +```cs +string input = "there are snakes at the zoo"; + +Console.WriteLine(input); +Console.WriteLine(ReverseSentence(input)); + +string ReverseSentence(string input) { + string result = ""; + string[] words = input.Split(" "); + foreach(string word in words) { + result += ReverseWord(word) + " "; + } + return result.Trim(); +} + +string ReverseWord(string word) { + string result = ""; + for (int i = word.Length - 1; i >= 0; i--) { + result += word[i]; + } + return result; +} +``` + +At the Terminal command prompt, enter `dotnet run` + +Verify that your code produces the following output: + +```txt +there are snakes at the zoo +ereht era sekans ta eht ooz +``` + +If your code displays different results, you'll need to review your code to +find your error and make updates. Run the code again to see if you've fixed the +problem. Continue updating and running your code until your code produces the +expected results. + +- [Program.cs](./return_str/Program.cs) + +--- + +## Exercise + +### Return Booleans from methods + +Methods with Boolean return types can be simple but are useful in consolidating +code. Methods that return `bool` values can be called to evaluate data input +anywhere, in `if` statements, in variable declarations, and more. In this +exercise, you'll gain some experience creating and using Boolean return type +methods. + +### Create a method that returns a Boolean + +Suppose you're a candidate in a coding interview. The interviewer wants you to +check if several words are a palindrome. A word is a palindrome if it reads the +same backwards and forwards. For example, the word `racecar` is a palindrome. +Let's get started! + +Enter the following code into the Editor: + +```cs +string[] words = {"racecar" ,"talented", "deified", "tent", "tenet"}; + +Console.WriteLine("Is it a palindrome?"); +foreach (string word in words) { + Console.WriteLine($"{word}: {IsPalindrome(word)}"); +} +``` + +This code establishes some test cases and references a method named +`IsPalindrome`. The words and output of the `IsPalindrome` method are printed +in the `Console.WriteLine` statements. + +Enter a new blank code line and create `bool` method by entering the following +code: + +```cs +bool IsPalindrome(string word) { + return true; +} +``` + +Consider how you'd check if a word is a palindrome. + +One way to check is to compare the first and the last letters of the word. If +they match, then compare the second and the second-to-last letter of the word. +If you reach the middle of the word, then all the letters have been compared +and matched. If any letters don't match, the word isn't a palindrome. + +Update the `IsPalindrome` method with the following code: + +```cs +bool IsPalindrome(string word) { + int start = 0; + int end = word.Length - 1; + + while (start < end) { + if (word[start] != word[end]) { + return false; + } + start++; + end--; + } + return true; +} +``` + +Notice the variables `start` and `end` to point to the first and last +characters in the string. The loop breaks when the middle of the word is met; +when `start` and `end` point to the same character or cross over each other. +The pointers are moved inwards each time there's a match. If they don't match, +the method terminates and returns `false`. + +Now your method successfully checks if a word is a palindrome and returns `true` +or `false` accordingly. + +### Check your work + +At the Terminal command prompt, enter `dotnet run` + +Verify that your code produces the following output: + +```txt +Is it a palindrome? +racecar: True +talented: False +deified: True +tent: False +tenet: True +``` + +If your code displays different results, you'll need to review your code to +find your error and make updates. Run the code again to see if you've fixed the +problem. Continue updating and running your code until your code produces the +expected results. + +- [Program.cs](./return_bool/Program.cs) + +--- + +## Exercise + +### Return arrays from methods + +When developing applications, you'll often need to build and modify sets of +data. Methods are useful for performing operations on data, and they're +especially powerful tools for building the data sets themselves. Developing +methods to create arrays representing your data set helps to keep your code +reusable, organized, and simplified. In this exercise, you'll practice +returning arrays from methods. + +#### Find coins to make change + +Suppose you have several coins of different values. You're tasked to find two +coins whose sum is equal to a target value. In this exercise, the coins +available are represented in an integer array. You'll need to return the +indices of the two coins in a new array. Let's get started! + +Enter the following code into the code editor: + +```cs +int[] TwoCoins(int[] coins, int target) { + return new int[0]; +} +``` + +In the case where no two coins are found, your method returns an empty array. +Take a moment to consider the syntax of the returned result. While you can +create a variable to store a new `int[]` array and return the variable, the +`return` statement allows you to simultaneously create and return values. + +There are many approaches to solve this problem. Take a moment to consider how +you might search for two numbers in an array whose sum is equal to a given +value. + +In this exercise, the following approach will be used: + +- Choose one number from the array +- Check other numbers one at a time to see if they add up to the target value +- Return the result as soon as a match is found + +To check each number in the array, update the `TwoCoins` method with the +following code: + +```cs +int[] TwoCoins(int[] coins, int target) { + for (int curr = 0; curr < coins.Length; curr++) { + for (int next = curr + 1; next < coins.Length; next++) { + + } + } + return new int[0]; +} +``` + +Here, `curr` represents one fixed coin index and `next` represents the +subsequent coin indices. You'll try adding each `next` coin with the fixed +`curr` coin to see if they equal the target value. + +Next, add logic to check the sum of the two coins for the target value. To do s +o, update the previous `for` loops with the following code: + +```cs +for (int curr = 0; curr < coins.Length; curr++) { + for (int next = curr + 1; next < coins.Length; next++) { + if (coins[curr] + coins[next] == target) { + return new int[]{curr, next}; + } + + } +} +``` + +In this code, you're checking if the sum of the values at `curr` and `next` in +the array are equal to the target value. If the sum is equal, you create an +array to store those indices and return it. If they aren't equal, you can +ignore them and keep checking. + +### Test your solution + +In this step, you'll test your code to ensure it's running correctly. First you +'ll initialize some variables to store the input data, then you'll call the +method and print the results. + +Create a new blank code line above the `TwoCoins` method signature. Then enter +the following code: + +```cs +int target = 60; +int[] coins = new int[] {5, 5, 50, 25, 25, 10, 5}; +int[] result = TwoCoins(coins, target); +``` + +Recall that the `TwoCoins` method returns an empty array if no change is found. +You'll need to check the array size before attempting to print the `result` +array. + +Enter a new blank code line. Then enter the following code: + +```cs +if (result.Length == 0) { + Console.WriteLine("No two coins make change"); +} else { + Console.WriteLine($"Change found at positions {result[0]} and {result[1]}"); +} +``` + +At the Terminal command prompt, enter `dotnet run`. Compare your output with +the following: + +```txt +Change found at positions 2 and 5 +``` + +If your code displays unexpected results, you'll need to review your code to +find your error and make updates. Run the code again to see if you've fixed the +problem. Continue updating and running your code until your code produces the +expected results. + +#### Find multiple pairs of coins that make change + +In this step, you'll extend the `TwoCoins` method to find more pairs of coins +whose sum is equal to the target value. For this exercise, you'll find a +maximum of five pairs. This means the return type will be a 2D array instead of +a 1D array, and you'll need to modify the way your code returns the results. +Let's get started! + +Change the return type in the method signature from `int[]` to `int[,]` by +updating your code to the following: + +```cs +int[,] TwoCoins(int[] coins, int target) +``` + +Next, you'll create an `int[,]` array to store and return your results, and a +counter variable to keep track of the number of pairs added to the array. + +Update the `TwoCoins` method with the following code: + +```cs +int[,] TwoCoins(int[] coins, int target) +{ + int[,] result = {{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1}}; + int count = 0; +``` + +Notice that you initialized the result array elements to `-1`. This will help +you later when you want to print the pairs that were found. + +Next, you'll use the `result` array to store each found pair instead of +returning the first match. + +Update the `TwoCoins` method with the following code: + +```cs +int[,] TwoCoins(int[] coins, int target) { + int[,] result = {{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1}}; + int count = 0; + for (int curr = 0; curr < coins.Length; curr++) { + for (int next = curr + 1; next < coins.Length; next++) { + if (coins[curr] + coins[next] == target) { + result[count, 0] = curr; + result[count, 1] = next; + count++; + } + + } + } +``` + +Notice that `count` is incremented every time a pair is added to the array. +This can cause an index out of bounds error if there are more than five pairs +found. To prevent this error, you can add code to check the value of `count` +and return the result the `result` array is filled. + +Update the logic in the `TwoCoins` method with the following code: + +```cs +for (int next = curr + 1; next < coins.Length; next++) { + if (coins[curr] + coins[next] == target) { + result[count, 0] = curr; + result[count, 1] = next; + count++; + } + if (count == result.GetLength(0)) { + return result; + } +} +``` + +Lastly, you'll need to update the final return statement to return the correct +result if no matches are found at all, or if fewer than five matches have been +found. + +Navigate to the `return` statement in the `TwoCoins` method. Modify the `return` +statement to match the following code: + +```cs +if (count == 0) { + return new int[0,0]; +} +return result; +``` + +You can also shorten this return code using the ternary operator like so: + +```cs +return (count == 0) ? new int[0,0] : result; +``` + +> Important +> The flexibility of the `return` keyword allows you to return the value of an +expression, as long as the result matches the specified return type of the +method. + +At this point, the `TwoCoins` method should match the following code: + +```cs +int[,] TwoCoins(int[] coins, int target) { + int[,] result = {{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1}}; + int count = 0; + + for (int curr = 0; curr < coins.Length; curr++) { + for (int next = curr + 1; next < coins.Length; next++) { + if (coins[curr] + coins[next] == target) { + result[count, 0] = curr; + result[count, 1] = next; + count++; + } + if (count == result.GetLength(0)) { + return result; + } + } + } + return (count == 0) ? new int[0,0] : result; +} +``` + +#### Capture the new return array + +Now that your method is returning a 2D array, you can update your code to +retrieve and print the results. Since the result array elements were +initialized to `-1`, you can add a check to print all pairs until a `-1` value +is found. + +Navigate to the beginning of your program where the `target` variable is +defined. Modify your code as follows: + +```cs +int target = 30; +int[] coins = new int[] {5, 5, 50, 25, 25, 10, 5}; +int[,] result = TwoCoins(coins, target); +``` + +Next, you'll update the call to `Console.WriteLine` to correctly print the +result values. + + +Navigate to the `Console.WriteLine` call. Update your code to match the +following: + +```cs +if (result.Length == 0) { + Console.WriteLine("No two coins make change"); +} else { + Console.WriteLine("Change found at positions:"); + for (int i = 0; i < result.GetLength(0); i++) { + if (result[i,0] == -1) { + break; + } + Console.WriteLine($"{result[i,0]},{result[i,1]}"); + } +} +``` + +Here, you keep the check for an empty array as-is, and print the values of the +2D array in a for-loop. When a `-1` value is found, you break out of the loop +since there are no next pairs. + +### Check your work + +Compare your code with the following to ensure it's correct: + +```cs +int target = 30; +int[] coins = new int[] {5, 5, 50, 25, 25, 10, 5}; +int[,] result = TwoCoins(coins, target); + +if (result.Length == 0) { + Console.WriteLine("No two coins make change"); +} else { + Console.WriteLine("Change found at positions:"); + for (int i = 0; i < result.GetLength(0); i++) { + if (result[i,0] == -1) { + break; + } + Console.WriteLine($"{result[i,0]},{result[i,1]}"); + } +} + +int[,] TwoCoins(int[] coins, int target) { + int[,] result = {{-1,-1},{-1,-1},{-1,-1},{-1,-1},{-1,-1}}; + int count = 0; + + for (int curr = 0; curr < coins.Length; curr++) { + for (int next = curr + 1; next < coins.Length; next++) { + if (coins[curr] + coins[next] == target) { + result[count, 0] = curr; + result[count, 1] = next; + count++; + } + if (count == result.GetLength(0)) { + return result; + } + } + } + return (count == 0) ? new int[0,0] : result; +} +``` + +At the Terminal command prompt, enter `dotnet run` + +Verify that your code produces the following output: + +```txt +Change found at positions: +0,3 +0,4 +1,3 +1,4 +3,6 +``` + +If your code displays different results, you'll need to review your code to +find your error and make updates. Run the code again to see if you've fixed the +problem. Continue updating and running your code until your code produces the +expected results. + +Next, update the value of `target` to a value of `80`: + +```cs +int target = 80; +``` + +Save your work then enter `dotnet run` at the Terminal command prompt + +To verify that your code is working as expected, compare the output of your +application with the following output: + +```txt +No two coins make change +``` + +If your code displays different results, you'll need to review your code to +find your error and make updates. Run the code again to see if you've fixed the +problem. Continue updating and running your code until your code produces the +expected results. + +- [Program.cs](./return_array/Program.cs) + +--- + +## Exercise + +### Complete the challenge to add methods to make the game playable + +Code challenges throughout these modules reinforce what you've learned, and +help you gain some confidence before continuing on. + +The focus of this challenge is to create correct methods with the proper +parameters and return types. + +### Dice mini-game challenge + +Your challenge is to design a mini-game. The game should select a target number +that is a random number between one and five (**inclusive**). The player must +roll a six-sided dice. To win, the player must roll a number greater than the +target number. At the end of each round, the player should be asked if they +would like to play again, and the game should continue or terminate +accordingly. + +In this challenge, you're given some starting code. You must determine what +methods to create, their parameters, and their return types. + +### Code challenge: + +#### add methods to make the game playable + +In the code that you start with, there are two unavailable methods referenced: + +- `ShouldPlay`: This method should retrieve user input and determine if the user +wants to play again +- `WinOrLose`: This method should determine if the player has won or lost + +There are also two uninitialized variables: + +- `target`: The random target number between 1 and 5 +- `roll`: The result of a random six-sided die roll + +Your challenge is to create the `ShouldPlay` and `WinOrLose` methods, and +create methods that set `target` and `roll` to random values in the correct +range. When all the methods are complete, the game should run successfully. + +Copy and paste the following code into the editor. + +```cs +Random random = new Random(); + +Console.WriteLine("Would you like to play? (Y/N)"); +if (ShouldPlay()) { + PlayGame(); +} + +void PlayGame() { + var play = true; + while (play) { + var target; + var roll; + Console.WriteLine($"Roll a number greater than {target} to win!"); + Console.WriteLine($"You rolled a {roll}"); + Console.WriteLine(WinOrLose()); + Console.WriteLine("\nPlay again? (Y/N)"); + + play = ShouldPlay(); + } +} +``` + +Update the code to use methods to make the game run according to the challenge +specifications. + +Use what you've learned about return values and parameters to complete the +update. + +Verify that your game is working + +Your code should produce output similar to the following: + +```txt +Would you like to play? (Y/N) +Y +Roll a number greater than 1 to win! +You rolled a 2 +You win! + +Play again? (Y/N) +Y +Roll a number greater than 4 to win! +You rolled a 6 +You win! + +Play again? (Y/N) +Y +Roll a number greater than 1 to win! +You rolled a 1 +You lose! + +Play again? (Y/N) +N +``` + +Whether you get stuck and need to peek at the solution or you finish +successfully, continue on to view a solution to this challenge. + +- [Program.cs](./challenge_game/Program.cs) + +--- + +### Summary + +Your goal in this module was to understand how the return keyword affects +method execution and practice using different expressions in return statements. +You also learned how to capture and use values returned from methods. You even +gained experience using return types while practicing some common coding +interview questions. diff --git a/029_return_value_method/challenge_game/Program.cs b/029_return_value_method/challenge_game/Program.cs new file mode 100644 index 0000000..fc58108 --- /dev/null +++ b/029_return_value_method/challenge_game/Program.cs @@ -0,0 +1,45 @@ +Random random = new Random(); + +Console.WriteLine("Would you like to play? (Y/N)"); +if (should_play()) { + play_game(); +} + +string win_or_lose(int target, int roll) { + if(roll > target){ + return "You win!"; + } else { + return "You lose!"; + } +} + +bool should_play() { + bool valid = false; + string? resp; + while (!valid) { + resp = Console.ReadLine(); + if (resp != null) { + resp = resp.Trim().ToLower(); + if(resp.Equals("y")){ + return true; + } else if (resp.Equals("n")) { + return false; + } + } + } + return false; +} + +void play_game() { + var play = true; + while (play) { + var target = random.Next(1,6); + var roll = random.Next(1,7);; + Console.WriteLine($"Roll a number greater than {target} to win!"); + Console.WriteLine($"You rolled a {roll}"); + Console.WriteLine(win_or_lose(target, roll)); + Console.WriteLine("\nPlay again? (Y/N)"); + + play = should_play(); + } +} diff --git a/029_return_value_method/challenge_game/challenge_game.csproj b/029_return_value_method/challenge_game/challenge_game.csproj new file mode 100644 index 0000000..2150e37 --- /dev/null +++ b/029_return_value_method/challenge_game/challenge_game.csproj @@ -0,0 +1,10 @@ + + + + Exe + net8.0 + enable + enable + + + diff --git a/029_return_value_method/return_array/Program.cs b/029_return_value_method/return_array/Program.cs new file mode 100644 index 0000000..9b25545 --- /dev/null +++ b/029_return_value_method/return_array/Program.cs @@ -0,0 +1,37 @@ +//int[] two_coins(int[] coins, int target) { +int[,] two_coins(int[] coins, int target) { + int[,] result = { + {-1,-1},{-1,-1},{-1,-1}, + {-1,-1},{-1,-1} + }; + int count = 0; + for (int curr = 0; curr < coins.Length; curr++) { + for (int next = curr + 1; next < coins.Length; next++) { + if (coins[curr] + coins[next] == target) { + result[count, 0] = curr; + result[count, 1] = next; + count++; + } + if (count == result.GetLength(0)) { + return result; + } + } + } + return (count == 0) ? new int[0, 0] : result; +} + +int target = 55; +int[] coins = new int[] { 5, 5, 50, 25, 25, 10, 5 }; +int[,] result = two_coins(coins, target); + +if (result.Length == 0) { + Console.WriteLine("No two coins make change"); +} else { + Console.WriteLine("Change found at positions:"); + for (int i = 0; i < result.GetLength(0); i++) { + if (result[i, 0] == -1) { + break; + } + Console.WriteLine($"{result[i, 0]},{result[i, 1]}"); + } +} diff --git a/029_return_value_method/return_array/return_array.csproj b/029_return_value_method/return_array/return_array.csproj new file mode 100644 index 0000000..2150e37 --- /dev/null +++ b/029_return_value_method/return_array/return_array.csproj @@ -0,0 +1,10 @@ + + + + Exe + net8.0 + enable + enable + + + diff --git a/029_return_value_method/return_bool/Program.cs b/029_return_value_method/return_bool/Program.cs new file mode 100644 index 0000000..c6ff5f3 --- /dev/null +++ b/029_return_value_method/return_bool/Program.cs @@ -0,0 +1,32 @@ +string[] words = { "racecar", "talented", "deified", "tent", "tenet" }; + +Console.WriteLine("Is it a palindrome?"); +foreach (string word in words) { + Console.WriteLine($"{word}: {is_palindrome(word)}"); + Console.WriteLine($"{word}: {check_palindrome(word)}"); +} + +bool is_palindrome(string word) { + int start = 0; + int end = word.Length - 1; + + while (start < end) { + if (word[start] != word[end]) { + return false; + } + start++; + end--; + } + return true; +} + +bool check_palindrome(string word) { + char[] temp = word.ToCharArray(); + Array.Reverse(temp); + string rev_word = string.Join("", temp); + if (String.Equals(word, rev_word)) { + return true; + } else { + return false; + } +} diff --git a/029_return_value_method/return_bool/return_bool.csproj b/029_return_value_method/return_bool/return_bool.csproj new file mode 100644 index 0000000..2150e37 --- /dev/null +++ b/029_return_value_method/return_bool/return_bool.csproj @@ -0,0 +1,10 @@ + + + + Exe + net8.0 + enable + enable + + + diff --git a/029_return_value_method/return_meth/Program.cs b/029_return_value_method/return_meth/Program.cs new file mode 100644 index 0000000..d01ec50 --- /dev/null +++ b/029_return_value_method/return_meth/Program.cs @@ -0,0 +1,25 @@ +double total = 0; +double min_spend = 30.00; + +double[] items = {15.97, 3.50, 12.25, 22.99, 10.98}; +double[] discounts = {0.30, 0.00, 0.10, 0.20, 0.50}; + +for (int i = 0; i < items.Length; i++) { + total += get_discounted_price(i); +} + +total -= total_meets_minimum() ? 5.00 : 0.00; + +Console.WriteLine($"Total: ${format_decimal(total)}"); + +double get_discounted_price(int item_index) { + return items[item_index] * (1 - discounts[item_index]); +} + +bool total_meets_minimum() { + return total >= min_spend; +} + +string format_decimal(double input) { + return input.ToString().Substring(0, 5); +} diff --git a/029_return_value_method/return_meth/return_meth.csproj b/029_return_value_method/return_meth/return_meth.csproj new file mode 100644 index 0000000..2150e37 --- /dev/null +++ b/029_return_value_method/return_meth/return_meth.csproj @@ -0,0 +1,10 @@ + + + + Exe + net8.0 + enable + enable + + + diff --git a/029_return_value_method/return_nums/Program.cs b/029_return_value_method/return_nums/Program.cs new file mode 100644 index 0000000..06688e1 --- /dev/null +++ b/029_return_value_method/return_nums/Program.cs @@ -0,0 +1,18 @@ +double usd = 23.73; +int vnd = usd_to_vnd(usd); + +Console.WriteLine($"${usd} USD = ${vnd} VND"); +Console.WriteLine($"${vnd} VND = ${vnd_to_usd(vnd)} USD"); + +int usd_to_vnd(double usd) { + int rate = 23500; + return (int) (rate * usd); +} + +double vnd_to_usd(int vnd) { + double rate = 23500; + return vnd / rate; +} + +var temp = 100*0.5; +Console.WriteLine(temp.GetType()); diff --git a/029_return_value_method/return_nums/return_nums.csproj b/029_return_value_method/return_nums/return_nums.csproj new file mode 100644 index 0000000..2150e37 --- /dev/null +++ b/029_return_value_method/return_nums/return_nums.csproj @@ -0,0 +1,10 @@ + + + + Exe + net8.0 + enable + enable + + + diff --git a/029_return_value_method/return_str/Program.cs b/029_return_value_method/return_str/Program.cs new file mode 100644 index 0000000..5cf1ef2 --- /dev/null +++ b/029_return_value_method/return_str/Program.cs @@ -0,0 +1,22 @@ +string reverse_word(string word) { + string result = ""; + for (int i=word.Length - 1; i>=0 ; i--) { + result += word[i]; + } + return result; +} + +string reverse_sentence(string input) { + string result = ""; + string[] words = input.Split(" "); + foreach (string word in words) { + result += reverse_word(word) + " "; + } + return result.Trim(); +} + +string input = "there are snakes at the zoo"; + +Console.WriteLine("Sentece : " + input); +Console.WriteLine("Reversed: " + reverse_word(input)); +Console.WriteLine("Special : " + reverse_sentence(input)); diff --git a/029_return_value_method/return_str/return_str.csproj b/029_return_value_method/return_str/return_str.csproj new file mode 100644 index 0000000..2150e37 --- /dev/null +++ b/029_return_value_method/return_str/return_str.csproj @@ -0,0 +1,10 @@ + + + + Exe + net8.0 + enable + enable + + + diff --git a/README.md b/README.md index 039ad34..de8c7d4 100644 --- a/README.md +++ b/README.md @@ -33,3 +33,4 @@ Following 26. [Challenge - variable data](./026_Challenge_variable_data/026_csharp.md) 27. [Create methods](./027_create_methods/027_csharp.md) 28. [Methods with parameters](./028_method_parameters/028_csharp.md) +29. [Methods that return values](./029_return_value_method/029_csharp.md)