#!markdown # Chapter 4 - Writing, Debugging, and Testing Functions #!csharp // allow simplified WriteLine and other console method calls using static System.Console; #!markdown ## Writing a times table function #!csharp static void TimesTable(byte number) { WriteLine($"This is the {number} times table:"); for (int row = 1; row <= 12; row++) { WriteLine($"{row} x {number} = {row * number}"); } WriteLine(); } #!csharp TimesTable(6) // semicolon is optional in a .NET notebook #!csharp TimesTable(number: 87) // optional to specify the parameter name #!markdown ## Writing a function that returns a value #!csharp static decimal CalculateTax( decimal amount, string twoLetterRegionCode) { decimal rate = 0.0M; switch (twoLetterRegionCode) { case "CH": // Switzerland rate = 0.08M; break; case "DK": // Denmark case "NO": // Norway rate = 0.25M; break; case "GB": // United Kingdom case "FR": // France rate = 0.2M; break; case "HU": // Hungary rate = 0.27M; break; case "OR": // Oregon case "AK": // Alaska case "MT": // Montana rate = 0.0M; break; case "ND": // North Dakota case "WI": // Wisconsin case "ME": // Maine case "VA": // Virginia rate = 0.05M; break; case "CA": // California rate = 0.0825M; break; default: // most US states rate = 0.06M; break; } return amount * rate; } #!csharp decimal taxToPay = CalculateTax(149, "FR"); WriteLine($"You must pay {taxToPay} in tax."); #!markdown ## Converting numbers from cardinal to ordinal #!csharp /// /// Pass a 32-bit integer and it will be converted into its ordinal equivalent. /// /// Number is a cardinal value e.g. 1, 2, 3, and so on. /// Number as an ordinal value e.g. 1st, 2nd, 3rd, and so on. static string CardinalToOrdinal(int number) { switch (number) { case 11: // special cases for 11th to 13th case 12: case 13: return $"{number}th"; default: int lastDigit = number % 10; string suffix = lastDigit switch { 1 => "st", 2 => "nd", 3 => "rd", _ => "th" }; return $"{number}{suffix}"; } } #!csharp static void RunCardinalToOrdinal() { for (int number = 1; number <= 40; number++) { Write($"{CardinalToOrdinal(number)} "); } WriteLine(); } #!csharp RunCardinalToOrdinal() #!markdown ## Calculating factorials with recursion #!csharp static int Factorial(int number) { if (number < 1) { return 0; } else if (number == 1) { return 1; } else { checked // for overflow { return number * Factorial(number - 1); } } } #!csharp static void RunFactorial() { for (int i = 1; i < 15; i++) { try { WriteLine($"{i}! = {Factorial(i):N0}"); } catch (System.OverflowException) { WriteLine($"{i}! is too big for a 32-bit integer."); } } } #!csharp RunFactorial() #!markdown ## Using lambdas in function implementations #!csharp static int FibImperative(int term) { if (term == 1) { return 0; } else if (term == 2) { return 1; } else { return FibImperative(term - 1) + FibImperative(term - 2); } } #!csharp static void RunFibImperative() { for (int i = 1; i <= 30; i++) { WriteLine("The {0} term of the Fibonacci sequence is {1:N0}.", arg0: CardinalToOrdinal(i), arg1: FibImperative(term: i)); } } #!csharp RunFibImperative() #!csharp static int FibFunctional(int term) => term switch { 1 => 0, 2 => 1, _ => FibFunctional(term - 1) + FibFunctional(term - 2) }; #!csharp static void RunFibFunctional() { for (int i = 1; i <= 30; i++) { WriteLine("The {0} term of the Fibonacci sequence is {1:N0}.", arg0: CardinalToOrdinal(i), arg1: FibFunctional(term: i)); } } #!csharp RunFibFunctional()