{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "60ff008b-c65d-4771-bfbf-125da4a07f62",
   "metadata": {},
   "source": [
    "```{index} labs; for loops\n",
    "```\n",
    "\n",
    "(lab-for-loops)=\n",
    "\n",
    "# Lab: for Loops\n",
    "\n",
    "- Note that the course policy is that you should not use generative AI\n",
    "  without authorization. If you are suspected to have used generative AI\n",
    "  and not able to explain/reproduce your work when requested, all your\n",
    "  **related assignments throughout the semester will be regraded as 0**.\n",
    "\n",
    "1.  Create a dotnet console app project ({ref}`create-project`), if you\n",
    "    have not, in your *USERNAME*/workspace/introcscs directory; call it\n",
    "    **Ch05ForLoop**.\n",
    "2.  Prepare your code in VS Code.\n",
    "3.  Use the file Program.cs to code.\n",
    "4.  The namespace of this project is *IntroCSCS*.\n",
    "5.  The class name of this project is *Ch05ForLoop*.\n",
    "6.  When executing code, you will only use the Main() method in class *Ch05ForLoop*.\n",
    "7.  You will prepare methods in the same class to be called from the Main() method.\n",
    "8.  Use a Word document to prepare your assignment.\n",
    "9.  Number the questions and **annotate** your answers (using // in code when\n",
    "    appropriate) to show your understanding.\n",
    "10. For coding questions, screenshot and paste 1) your code in VS Code and 2) the\n",
    "    results of the code’s execution (**command prompt** and **username** are part\n",
    "    of the execution).\n",
    "\n",
    "Goals for this lab:\n",
    "\n",
    "- Practice with loops. You are encouraged to use a `for` loop where appropriate.\n",
    "- Use nested loops where appropriate.\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9bf03df7",
   "metadata": {},
   "source": "## For Loop Lab\n\nThis part of the lab comes from [loop_lab_stub/loop_lab.cs](https://github.com/mstbit/introcs-csharp-examples/blob/master/loop_lab_stub/loop_lab.cs). You may refer to the\ncode while answering the questions here.\n\n> 1.  From the terminal, go to your Ch05ForLoop project folder.\n> 2.  `code .` + Enter from within the Ch05ForLoop directory.\n> 3.  Start working on the methods.\n\nYour task is to Fill in method bodies for each part below:\n\n```{index} PrintReps\n```\n\n1.  Complete method `PrintReps` to be called from Main() like:\n\n    ```{literalinclude} ../../examples/loop_lab_stub/loop_lab.cs\n    :dedent: 6\n    :end-before: body\n    :start-after: PrintReps chunk\n    ```\n\n    Hint: How would you do something like the example\n    `PrintReps(\"Ok\", 9)` or with a higher count by hand?\n    Probably count under your breath as you write:\n\n    ``` none\n     1 2 3 4 5 6 7 8 9\n    OkOkOkOkOkOkOkOkOk\n    ```\n\n    This is a counting loop. Use a C-style for loop.\n\n    (stringofreps)=\n\n    ```{index} StringOfReps\n    ```\n\n2.  Complete method `StringOfReps`\n\n    ```{literalinclude} ../../examples/loop_lab_stub/loop_lab.cs\n    :dedent: 6\n    :end-before: body\n    :start-after: StringOfReps chunk\n    ```\n\n    Note the distinction from the previous part: Here the method prints nothing.\n    Its work is *returned* as a single string. You have call the method like:\n\n        Console.WriteLine(StringOfReps(\"Ok\", 9));\n\n    ```{index} Factorial\n    ```\n\n3.  Complete method `Factorial`: (A factorial, in mathematics, is the product of\n    all positive integers less than or equal to a given positive integer and\n    denoted by that integer and an exclamation point.)\n\n    ```{literalinclude} ../../examples/loop_lab_stub/loop_lab.cs\n    :dedent: 6\n    :end-before: body\n    :start-after: Factorial chunk\n    ```\n\n    It is useful to think of the sequence of steps to calculate a\n    concrete example of a factorial, say 6!:\n\n    ``` none\n    Start with 1\n    2 * 1 = 2\n    3 * 2 = 6\n    4 * 6 = 24\n    5 * 24 = 120\n    6 * 120 = 720\n    ```\n\n    **ALSO** find the largest value of `n` for which the method works.\n    (You might want to add a bit of code further testing Factorial,\n    to make this easier.) Caution: although a negative result from the\n    product of two positive numbers is clearly wrong, only half of the\n    allowed values are negative, so the first wrong answer could equally well\n    be positive. **Explain how you find the largest value of \\`\\`n\\`\\` that works in this method.**\n\n```{index} Random; static variable\n```"
  },
  {
   "cell_type": "markdown",
   "id": "7365c722",
   "metadata": {},
   "source": "```{index} Random; heads or tails\n```\n\n(head-tails-exercise)=\n\n## Head or Tails\n\nWrite a method `Flip()`,\nthat will just randomly print `Heads` or `Tails` *once*.\nAccomplish this by choosing 0 or 1 arbitrarily with a random\nnumber generator. More details follow.\n\nUse a `Random` object, and make the `Random` object a local variable inside\nthe `Flip` method.\n\n*It is generally a good idea to only create a single \\`\\`Random\\`\\` object\nthat stays in scope for the whole program so it can be used by various programs.\nOne way to do that is to make it* **static**. For our purpose here, just place\nthe random object declaration in your Flip() method:\n\n    Random r = new Random();\n\n*Note again that in the future you would place the object inside your class but\noutside of any method, so you can use \\`\\`r\\`\\` in any method in your class*.\n\nFor `int` variables `low` and `higher`, with `low < higher`:\n\n    int n = r.Next(low, higher);\n\nreturns a (pseudo) random `int`, satisfying `low <= n < higher`.\nIf you select `low` and `higher` as 0 and 2,\nso there are only two possible values for n,\nthen you can choose to print `Heads` or `Tails` with an\n{{ if_else }} statement based on the result.\n\nIn your `Flip` method, create a `for` loop so you generate a random sequence of\n10 heads and/or tails. Print out the heads/tails like:\n\n    Tails Tails Tails Tails Heads Tails Heads Tails Tails Tails\n\nPlace `return \"\"` in your `else` block to avoid a “not all paths return value”\nwarning if you use an else if statement (or simply put the return line at the\nend of the code block).\n\nWe have discovered some problems with the `Next()` implementation\nthat sometimes results in random values not\nbeing generated. This is likely a bug that will be fixed. If you\nexperience any problems with `Next()`, the following is for you!\n\n% An alternative to generating random 0 and 1 values for heads and tails\n\n% is to generate random double-precision values. Using the same\n\n% variable, `r`, you can call `r.NextDouble()` to get a random value\n\n% between 0 and 1. You can consider any generated value :math:`n < 0.5` to\n\n% be heads; :math:`n >= 0.5` represents tails::\n\n% double n = r.NextDouble();\n\n% if (n \\< 0.5) {\n\n% // heads\n\n% } else {\n\n% // tails\n\n% }"
  },
  {
   "cell_type": "markdown",
   "id": "38e5df8e",
   "metadata": {},
   "source": "```{index} exercise; GroupFlips\n```\n\n## Group Flips\n\nWrite a method `GroupFlips()` using the `Flip()` method\nfrom the last question to:\n\n    /// Print out the results from the total number of random flips of a coin.\n    /// Group them groupSize per line, each followed by a space.\n    /// The last line may contain fewer than groupSize flips\n    /// if total is not a multiple of groupSize.  The last line\n    /// should be followed by exactly one newline in all cases.\n    /// For example, GroupFlips(10, 4) *could* produce:\n    ///   Heads Heads Tails Heads\n    ///   Heads Tails Heads Tails\n    ///   Tails Tails\n    static void GroupFlips(int total, int groupSize)\n\nComplete this method definition and test\nwith a variety of calls to `GroupFlips` in `Main`. The output from the\nprevious exercise would be produced by the call:\n\n    GroupFlips(10, 1);"
  },
  {
   "cell_type": "markdown",
   "id": "4a8701db",
   "metadata": {},
   "source": "```{index} exercise; reverse string foreach\n```\n\n(reverse-string-foreach)=\n\n## Reverse String `foreach`\n\nIt used a `for` loop to go through the characters in\nreverse order. Write a version with the only loop heading:\n\n    foreach(char ch in s) {\n\nand no reference to indices in s."
  },
  {
   "cell_type": "markdown",
   "id": "e2c6d533",
   "metadata": {},
   "source": "```{index} exercise; only letters\n```\n\n(only-letters-ex)=\n\n## Only Letters\n\nWrite a program that defines and tests a method with\ndescription and heading:\n\n    /// Return s with all non-letters removed.\n    /// For example OnlyLetters(\"Hello, World!\") returns \"HelloWorld\".\n    static string OnlyLetters(string s)\n\nAssume the English alphabet."
  },
  {
   "cell_type": "markdown",
   "id": "f5ce0a63",
   "metadata": {},
   "source": "```{index} exercise; palindrome\n```\n\n(palindrome-ex)=\n\n## Palindrome Exercise\n\nWrite a program `palindrome.cs` that defines and tests a method with\ndescription and heading:\n\n    /// Return true when s is a palindrome.\n    /// For example IsPalindrome(\"A Toyota!\") returns true.\n    static bool IsPalindrome(string s)\n\nA palindrome is a string that contains the same sequence of letters,\nignoring capitalization, forward and backward. Non-letters are ignored.\nExamples are “Madam, I’m Adam.” and “Able was I ’ere I saw Elba.”\n\n`IsPalindrome` can be written very concisely by copying and using\nmethods from previous exercises.\n\n```{index} exercise; nested play computer\n```\n\nPredict what these code fragments print. Then check yourself in csharp:\n\n    for (int i = 3; i > 0; i--) {\n        for (int j = i; j < 4; j++) {\n            Console.Write(j);\n        }\n        Console.WriteLine();\n    }\n\n    string s = \"abcdef\";\n    for (int i = 1; i < s.Length; i += 2) {\n        for (int k = 0; k < i; k++) {\n            Console.Write(s[i]);\n        }\n    }"
  },
  {
   "cell_type": "markdown",
   "id": "69e58e5e",
   "metadata": {},
   "source": "```{index} exercise; power table\n```\n\n(power-table-exercise)=\n\n## Power Table\n\n1.  Write a method that completes and tests with this heading.\n    Be sure your program tests\n    with several values for each parameter:\n\n        /// Print a table of powers of positive integers.\n        /// Assume 1 <= nMax <= 12, 1 <= powerMax <= 7.\n        /// Example: output of PowerTable(3, 4)\n        ///       n^1       n^2      n^3      n^4\n        ///         1         1        1        1\n        ///         2         4        8       16\n        ///         3         9       27       81\n        ///\n        public static void PowerTable(int nMax, int powerMax)\n\n    Make sure the table always ends up with right-justified columns.\n\n2.  Make the table have columns all the same width, but\n    make the width be as small as possible for the parameters\n    provided, leaving a minimal one space (but not less!) between columns\n    somewhere in the table. Consider heading widths, too.\n\n% #. Modify the method to return a `long`.\n\n% Then what is the largest value of `n` for which the method works?\n\n% *Remember the values from this part and the previous part*\n\n% *to tell the TA’s checking out your work.*\n\n% .. index:: PrintRectangle\n\n% #. Complete the method\n\n% .. literalinclude:: ../../examples/loop_lab_stub/loop_lab.cs\n\n% :start-after: PrintRectangle chunk\n\n% :end-before: body\n\n% :dedent: 6\n\n% Here are further examples::\n\n% PrintRectangle(5, 1, ’ ‘, ’B’);\n\n% PrintRectangle(0, 2, ‘-’, ‘+’);\n\n% would print\n\n% .. code-block:: none\n\n% BBBBBBB\n\n% B B\n\n% BBBBBBB\n\n% ++\n\n% ++\n\n% ++\n\n% ++\n\n% Suggestion: You are always encouraged to build up to a complicated solution\n\n% incrementally.\n\n% You might start by just creating the inner rectangle, without the border.\n\n% #. Complete the method below.\n\n% .. literalinclude:: ../../examples/loop_lab_stub/loop_lab.cs\n\n% :start-after: PrintTableBorders chunk\n\n% :end-before: body\n\n% :dedent: 6\n\n% Here is further example::\n\n% PrintTableBorders(2, 1, 6, 3);\n\n% would print (with actual vertical bars)\n\n% .. code-block:: none\n\n% +——+——+\n\n% \\| \\| \\|\n\n% \\| \\| \\|\n\n% \\| \\| \\|\n\n% +——+——+\n\n% You can do this with lots of nested loops,\n\n% or much more simply you can use `StringOfReps`, possibly six times\n\n% in several assignment statements,\n\n% and print a single string. Think of larger and larger building blocks.\n\n% The source of this book is plain text where some of the tables are laid out\n\n% in a format similar to the output of this method. The Emacs editor\n\n% has a mode that maintains\n\n% a fancier related setup on the screen, on the fly,\n\n% as content is added inside the cells!"
  },
  {
   "cell_type": "markdown",
   "id": "b5642872",
   "metadata": {},
   "source": [
    "## Reverse String Practice\n",
    "\n",
    "The following reverse-string examples were moved from worked examples as lab-style practice.\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d5cf55d0",
   "metadata": {},
   "source": "## Reversed String Print\n\nCreate a method, call it ReverseStringPrint, that, when called with a string, will print\nthe string reversed.\n\nWe know we could use a `for` loop to print the characters in a string reversely.\nLet us consider the following tools we have:\n\n- A string is an array of combined characters with indices.\n- An array is 0-based. The first character of a string str can be accessed as str[0]\n- To reverse a string, we need to start from the last indexed character.\n- The last index number of string `str` is related to the length of the string: `str.Length`.\n- To process the whole string, we can use the decrement assignment operator (`--`) to start\n  the printing from the end of the string.\n\nI managed to come up with some variation of code as below but am running into some errors:"
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "6c8746a0",
   "metadata": {
    "vscode": {
     "languageId": "csharp"
    }
   },
   "outputs": [],
   "source": [
    "string s = \"drab\";\n",
    "  for (int i = s.Length; i >= 0; i++)\n",
    "  {\n",
    "    Console.Write(s[i]);\n",
    "  }"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ba6e995b",
   "metadata": {},
   "source": "One of the errors I see is the famous Index-Out-Of-Range error:\n\n```console\n┌──────────IndexOutOfRangeException──────────┐\n│ Index was outside the bounds of the array. │\n└────────────────────────────────────────────┘\n```"
  },
  {
   "cell_type": "markdown",
   "id": "e82b5b93",
   "metadata": {},
   "source": "(reverse-string-returned-lab)=\n\n## Reversed String Return\n\nreversed. Logically, you will perform two separate ideas:\nreversing a string and printing it. Now consider the first part as its own method:"
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "6fbb304e",
   "metadata": {},
   "outputs": [],
   "source": [
    "// this is a method return a string `s` in reverse order.\n",
    "// say, if s is \"drab\", return \"bard\".\n",
    "// below is the possible form of the header for the method\n",
    "static string Reverse (string s)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f35878e3",
   "metadata": {},
   "source": [
    "\n",
    "In the Reverse method, use a `for` loop:\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "469856a5",
   "metadata": {},
   "outputs": [],
   "source": [
    "for (int i = s.Length - 1; i >= 0; i--) {\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "45287b7c",
   "metadata": {},
   "source": [
    "\n",
    "A significant idea here is that, instead of immediately printing the `char`'s,\n",
    "you need to return a reversed string. That means, you need to create a single\n",
    "string, with all the characters, before returning the result.\n",
    "\n",
    "Let us think about this: If you start with `s` as `\"drab\"`, and you go through\n",
    "the letters one at a time in reverse order, b a r d, you build up successively:\n",
    "\n",
    "```none\n",
    "b\n",
    "ba\n",
    "bar\n",
    "bard\n",
    "```\n",
    "\n",
    "You need a loop with variables and operations. The sequence of reversed letters,\n",
    "`s[i]`, are the last character on the end of each line above.\n",
    "\n",
    "We need a name for the initial part.\n",
    "I used the name `rev`.\n",
    "Combining with a string is done with the `+` operator.\n",
    "Then when `rev` is `\"ba\"` and `s[i]` is `'r'`, the combination,\n",
    "using the variable names, is\n",
    "\n",
    "```\n",
    "rev + s[i]\n",
    "```\n",
    "\n",
    "We want this in our loop, so we must be able to use\n",
    "that expression *each* time through the loop,\n",
    "so `rev` changes each time through the loop. In the next iteration `rev`\n",
    "is the *result* of the previous expression. The assignment statement\n",
    "to give us the next version of `rev` can just be:\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "d6601f8b",
   "metadata": {},
   "outputs": [],
   "source": [
    "rev = rev + s[i];\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "49aa8306",
   "metadata": {},
   "source": [
    "\n",
    "That gives us the general rule. Pay attention now to the beginning and end:\n",
    "The end is simple: The last value for `rev` is the complete reversed string,\n",
    "so that is what we return.\n",
    "\n",
    "How do we initialize `rev`? You could imagine `rev` starting as `\"b\"`,\n",
    "but the the first character that we add is `'a'`, and we would not be going\n",
    "through all the characters in our loop. It is better to go all the way\n",
    "back to the beginning: If we use the general form with the first letter in the\n",
    "reversed sequence,\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "aab8f821",
   "metadata": {},
   "outputs": [],
   "source": [
    "rev = rev + s[i];\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0af62716",
   "metadata": {},
   "source": [
    "\n",
    "then the result of the initial `rev` + `'b'` should just be `\"b\"`.\n",
    "So what would `rev` be?\n",
    "\n",
    "Remember the empty string: initialize `rev` to be `\"\"`.\n",
    "\n",
    "The result is:\n",
    "\n",
    "```{literalinclude} ../../examples/reversed_string/reversed_string.cs\n",
    ":dedent: 6\n",
    ":end-before: chunk\n",
    ":start-after: chunk\n",
    "```\n",
    "\n",
    "We used our new operator `+=` to be more concise.\n",
    "\n",
    "This function and a `Main` used to demonstrate it are in\n",
    "[here](https://github.com/LoyolaChicagoBooks/introcs-csharp-examples/blob/master/reversed_string/reversed_string.cs)."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "74006783",
   "metadata": {},
   "source": [
    "## Additional While/Do-While Lab Exercises\n",
    "\n",
    "The following activities are consolidated from the previous standalone while-loop lab section.\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7156ab65",
   "metadata": {},
   "source": "## Easy `while`\n\nWrite a program with a `while` loop to print:\n\n```none\n10\n9\n8\n7\n6\n5\n4\n3\n2\n1\nBlastoff!\n```"
  },
  {
   "cell_type": "markdown",
   "id": "ed326da0",
   "metadata": {},
   "source": "## Number in Range [1…100]\n\nEnter an integer in the range [1 … 100]. If the entered number is invalid,\nenter it again. In this case, an invalid number will be any number that is not\nwithin the specified range. [^number-in-range]\n\nTo solve the problem, we can use the following algorithm:\n\n- We create a num variable to which we assign the integer value obtained from the console input.\n- For a loop condition, we put an expression that is true if the number of the input is not in the range specified in the problem's description.\n- In the body of the loop: we print a message \"Invalid number!\" on the console, then we assign a new value to num from the console input.\n- Once we have validated the entered number, we print the value of the number outside the body of the loop.\n\nHere's a implementation of the algorithm using a while loop and there are places that\nneed to be fixed in the code:"
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "var num = int.Parse(Console.WiteLine());\n",
    "while (num < 1 && num > 100)\n",
    "{\n",
    "   Console.WriteLine(\"Invalid number!\");\n",
    "   num = int.Parse(Console.WriteLine());\n",
    "}\n",
    "Console.WriteLine(\"The number is: {{10}\", num);\n"
   ],
   "id": "07c915ce"
  },
  {
   "cell_type": "markdown",
   "id": "0aec13aa",
   "metadata": {},
   "source": "Fix the preceding code and make sure the execution performs correctly."
  },
  {
   "cell_type": "markdown",
   "id": "20182723",
   "metadata": {},
   "source": "(lab-number-game)=\n\n## Number Guessing Game\n\nThis lab is inspired by a famous children's game\nknown as the number-guessing game. We suppose two people are playing. The rules are:\n\n- Person A chooses a positive integer less than N and keeps it in his or\n  her head.\n- Person B makes repeated guesses to determine the number. Person A\n  must indicate whether the guess is higher or lower.\n- Person A must tell the truth.\n\nSo as an example:\n\n- George and Andy play the game.\n- George chooses a positive number less than 100 (29) and keeps it in his\n  head.\n- Andy guesses 50. George says \"Lower\". Andy now knows that\n  $1 \\leq number < 50$.\n- Andy guesses 25. George says \"Higher\". Andy now knows that\n  $26 \\leq number < 50$.\n- Andy guesses 30. George says \"Lower\". Andy now knows that the\n  $26 \\leq number < 30$.\n- Andy starts thinking that he is close to knowing the correct answer. He\n  decides to guess 29. Andy guesses the correct number. So George\n  says, \"Good job! You win!\"\n\nThe computer code for the game is going to be acting like Person A and should\nbe configured and behave as follows.\n\n01. Make sure your program has `namespace IntroCSCS;` to match the UI class.\n\n02. Put the code for playing the number game in a method called `Game`:\n\n"
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "    static void Game()\n"
   ],
   "id": "6875916b"
  },
  {
   "cell_type": "markdown",
   "id": "312c0122",
   "metadata": {},
   "source": [
    "\n",
    "03. You call `Game()` from the `Main` method.\n",
    "\n",
    "04. Prompt the player for a guess. Use `UI.PromptInt`.\n",
    "\n",
    "05. When the player guesses the right number, print \"Good job! You win!\"\n",
    "\n",
    "06. When the player is incorrect, print \"Lower!\" or \"Higher!\" as appropriate.\n",
    "\n",
    "07. Have the Game method print \"In this game you guess a positive number\n",
    "    less than 100.\" It is best if you have the printing statement\n",
    "    reference the variable `big`, rather than the literal `100`.\n",
    "\n",
    "08. Have the game generate a *random* number. For your convenience,\n",
    "    use the C# code below to generate the random number. Assuming we want a\n",
    "    `secret` number so $1 \\leq secret < big$, we can use the code:\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "    Random r = new Random();\n",
    "    int secret = r.Next(1, big);\n"
   ],
   "id": "769085b8"
  },
  {
   "cell_type": "markdown",
   "id": "1febe78b",
   "metadata": {},
   "source": ":::{note}\n    In case you are wondering, we are creating a *new object*\n    of the *class* `Random`, which serves as the\n    *random number generator*. We'll cover this in more detail when we\n    get to the {ref}`classes` chapter.\n    :::\n\n    - Here is some illustration using a `Random` object in `csharprepl`.\n      Your answers will not be the same:\n\n      ```\n      > Random r = new Random();\n\n      > r.Next(1, 100)\n      68\n      > r.Next(1, 100)\n      48\n      > r.Next(1, 100)\n      30\n      > r.Next(1, 100)\n      70\n      > r.Next(1, 100)\n      67\n      >\n      ```\n\n    - Note that, the **minimum** possible value of the number returned by `r.Next`\n      is the first parameter, and the value returned is always *less* than\n      the second parameter, *never equal*.\n\n09. As an extra challenge, when the player finally wins, print the number of guesses\n    the player made.\n\n10. When run, the program should work like (where `secret` ended up as 68):\n\n    > Guess a number less than 100!\n    >\n    > Guess the number: \n    >\n    > **60**\n    >\n    > Higher!\n    >\n    > Guess the number: \n    >\n    > **72**\n    >\n    > Lower!\n    >\n    > Guess the number: \n    >\n    > **66**\n    >\n    > Higher!\n    >\n    > Guess the number: \n    >\n    > **68**\n    >\n    > Good job! You win on guess 3!"
  },
  {
   "cell_type": "markdown",
   "id": "c0a14159",
   "metadata": {},
   "source": "(sumton)=\n\n## Sum To `n`\n\n- This lab gives detailed description about the process of arriving at a solution to\n  the problem. Please read the explanations if you are new to coding and while loops.\n\nLet us write a method to sum the numbers from 1 to `n`:\n\n"
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "/// Return the sum of the numbers from 1 through n.\n",
    "static int SumToN(int n)\n",
    "{\n",
    "   ...\n",
    "}\n"
   ],
   "id": "88896eb5"
  },
  {
   "cell_type": "markdown",
   "id": "fee74cea",
   "metadata": {},
   "source": [
    "\n",
    "For instance, SumToN(5) calculates 1 + 2 + 3 + 4 + 5 and returns 15.\n",
    "You know how to generate a sequence of integers (using loop header). To see how this works in steps,\n",
    "let us take a concrete example like the one above for SumToN(5), and write out a detailed sequence of steps like:\n",
    "\n",
    "```none\n",
    "3 = 1 + 2\n",
    "6 = 3 + 3\n",
    "10 = 6 + 4\n",
    "15 = 10 + 5\n",
    "```\n",
    "\n",
    "Since `n` is general, we need a loop, and hence we must see a **pattern** in code that we can repeat:\n",
    "\n",
    "- In each calculation the second term in the additions is a successive integer, that we can generate.\n",
    "\n",
    "- Starting in the second line, the first number in each addition is the sum from the previous line.\n",
    "\n",
    "- The next integer and the next partial sum change from step to step, so in order to use the same code over and\n",
    "  over we will need changeable variables, with names. We can make the partial\n",
    "  sum be `sum` and we can call the next integer `i`. Each addition can be\n",
    "  in the form:\n",
    "\n",
    "  ```\n",
    "  sum + i\n",
    "  ```\n",
    "\n",
    "- We need to remember that result, the new sum. You might first think to introduce\n",
    "  such a name:\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "  newSum = sum + i;\n"
   ],
   "id": "cae1a4fe"
  },
  {
   "cell_type": "markdown",
   "id": "eece68f4",
   "metadata": {},
   "source": [
    "\n",
    "This will work. We can go through the {ref}`Loop Planning Rubric <loop-planning-rubric>`:\n",
    "\n",
    "The variables are `sum`, `newSum` and `i`.\n",
    "\n",
    "To evaluate\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "newSum = sum + i;\n"
   ],
   "id": "6b9cabc8"
  },
  {
   "cell_type": "markdown",
   "id": "0b028da5",
   "metadata": {},
   "source": [
    "\n",
    "the first time in the loop, we need *initial* values for sum and i.\n",
    "Our concrete example leads the way:\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "int sum = 1, i = 2;\n"
   ],
   "id": "fd54c264"
  },
  {
   "cell_type": "markdown",
   "id": "f462d26c",
   "metadata": {},
   "source": [
    "\n",
    "We need a `while` loop heading with a continuation condition. How\n",
    "long do we want to add the next `i`? That is for all the value up to and\n",
    "including n:\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "while (i <= n) {\n"
   ],
   "id": "aa6fef15"
  },
  {
   "cell_type": "markdown",
   "id": "7aa3085c",
   "metadata": {},
   "source": [
    "\n",
    "There is one more important piece - making sure the same code\n",
    "\n",
    "> newSum = sum + i;\n",
    "\n",
    "works for the *next* time through the loop. We have dealt before with\n",
    "the idea of the next number in sequence:\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "i = i + 1;\n"
   ],
   "id": "501a315d"
  },
  {
   "cell_type": "markdown",
   "id": "42444a55",
   "metadata": {},
   "source": [
    "\n",
    "What about `sum`? What was the `newSum`\n",
    "on *one* time through the loop becomes the old or\n",
    "just plain `sum` the *next* time through, so we can make an assignment:\n",
    "\n",
    "```\n",
    "sum = newSum:\n",
    "```\n",
    "\n",
    "All together we calculate the sum with:\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "int sum = 1, i = 2;\n",
    "while (i <= n) {\n",
    "   int newSum = sum + i;\n",
    "   sum = newSum:\n",
    "   i = i + 1;\n",
    "}\n"
   ],
   "id": "4e8ddbb5"
  },
  {
   "cell_type": "markdown",
   "id": "aef6c60c",
   "metadata": {},
   "source": [
    "\n",
    "We can condense it in this case: Since `newSum` is only used\n",
    "once, we can do away with this extra variable name,\n",
    "and directly change the value of sum:\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "int sum = 1, i = 2;\n",
    "while (i <= n) {\n",
    "   sum = sum + i;\n",
    "   i = i + 1;\n",
    "}\n"
   ],
   "id": "e5d3f743"
  },
  {
   "cell_type": "markdown",
   "id": "097df43b",
   "metadata": {},
   "source": [
    "\n",
    "Finally this was supposed to fit in a method. The ultimate purpose\n",
    "was to *return* the sum, which is the final value of the\n",
    "variable `sum`, so the whole method is:\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "/// Return the sum of the numbers from 1 through n.\n",
    "static int SumToN(int n)     // line 1\n",
    "{\n",
    "   int sum = 1, i = 2;       // 2\n",
    "   while (i <= n) {          // 3\n",
    "      sum = sum + i;         // 4\n",
    "      i = i + 1;             // 5\n",
    "   }\n",
    "   return sum;               // 6\n",
    "}\n"
   ],
   "id": "52dd02e1"
  },
  {
   "cell_type": "markdown",
   "id": "3985a4c0",
   "metadata": {},
   "source": "Also you should check the program in a more general situation, say with `n`\nbeing 4. You should be able to play computer and generate this table,\nusing the line numbers shown in comments at the end of lines,\nand following one statement of execution at a time. We only\nmake entries where variables change value.\n\n| Line | i   | sum | Comment                  |\n| ---- | --- | --- | ------------------------ |\n| 1    |     |     | assume 4 is passed for n |\n| 2    | 2   | 1   |                          |\n| 3    |     |     | 2\\<=4: true, enter loop  |\n| 4    |     | 3   | 1+2=3                    |\n| 5    | 3   |     | 2+1=3, bottom of loop    |\n| 3    |     |     | 3\\<=4: true              |\n| 4    |     | 6   | 3+3=6                    |\n| 5    | 4   |     | 3+1=4, bottom of loop    |\n| 3    |     |     | 4\\<=4: true              |\n| 4    |     | 10  | 6+4=10                   |\n| 5    | 5   |     | 4+1=5, bottom of loop    |\n| 3    |     |     | 5\\<=4: false, skip loop  |\n| 6    |     |     | return 10                |"
  },
  {
   "cell_type": "markdown",
   "id": "9a5f2e54",
   "metadata": {},
   "source": "```{index} exercise; loan table\n```\n\n(loan-table-exercise)=\n\n## Loan Table\n\nThis exercise is an extension of the {ref}`savings-exercise`. Different\nforms of iteration may make sense to you but you are encouraged to use the `while` or `do` loop.\n\nLoans are common with a specified interest rate and with a fixed periodic\npayment. Interest is charged at a fixed rate on the amount left in the loan\nafter the last periodic payment (or start of the loan for the first payment).\n\nFor example, if an initial \\$100 loan is made with 10% interest per pay\nperiod, and a regular \\$20 payment each pay period:\nAt the time of the first payment interest of \\$100\\*.10 = \\$10 is accrued,\nso the total owed is \\$110. Right after the payment of \\$20,\n\\$110 - \\$20 = \\$90 remains. That \\$90 gains interest of \\$90\\*.10 = \\$9 up to the\nnext payment, when \\$90 + \\$9 = \\$99 is owed. After the regular payment of\n\\$20, \\$99 - \\$20 = \\$79 is left, and so on. When a payment of at most \\$20 brings\nthe amount owed to 0, the loan is done.\n\nWe can make a table showing\n\n- Payment number (starting from 1)\n- The principal amount after the previous payment (or the beginning of the loan\n  for the first payment)\n- The interest on that principal up until the next periodic payment\n- The payment made as a result.\n\nContinuing the example above, the whole table\nwould look like:\n\n```none\nNumber Principal   Interest    Payment\n     1    100.00      10.00      20.00\n     2     90.00       9.00      20.00\n     3     79.00       7.90      20.00\n     4     66.90       6.69      20.00\n     5     53.59       5.36      20.00\n     6     38.95       3.90      20.00\n     7     22.85       2.29      20.00\n     8      5.14       0.51       5.65\n```\n\nIn the final line, the principal plus interest equal the payment, finishing\noff the loan.\n\nSimilarly, with a \\$1000.00 starting loan, 5% interest per pay period, and\n\\$196 payments due, you would get\n\n```none\nNumber Principal   Interest    Payment\n     1   1000.00      50.00     196.00\n     2    854.00      42.70     196.00\n     3    700.70      35.04     196.00\n     4    539.74      26.99     196.00\n     5    370.73      18.54     196.00\n     6    193.27       9.66     196.00\n     7      6.93       0.35       7.28\n```\n\nIf a \\$46 payment were specified, the principal would not decrease from the\ninitial amount, and the loan would never be paid off.\n\nThere are a couple of wrinkles here: `double` values do not hold decimal\nvalues exactly. The `decimal` type does hold decimal numbers exactly\nand\nhence are better for monetary calculations. Decimal literals end with m, like\n`34.56m` for *exactly* 34.56.\n\nThough decimals are exact, money only has two decimal places. We make the\nassumption that interest will always be calculated as current\nprincipal\\*rate, rounded\nto two decimal places: `Math.Round(principal*rate, 2)`.\n\nWrite the `LoanTable` method and run it from `Main`:\n\n"
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "/// Print a loan table, showing payment number, principal at the\n",
    "/// beginning of the payment period, interest over the period, and\n",
    "/// payment at the end of the period.\n",
    "/// The principal is the initial amount of the loan.\n",
    "/// The rate is fraction representing the rate of interest per PAYMENT.\n",
    "/// The periodic regular payment is also specified.\n",
    "public static void LoanTable(decimal principal, decimal rate,\n",
    "                             decimal payment)\n"
   ],
   "id": "5e3395eb"
  },
  {
   "cell_type": "markdown",
   "id": "ea47b5b8",
   "metadata": {},
   "source": [
    "\n",
    "Note that the `rate`, too, is a `decimal`,\n",
    "even though it does not represent money.\n",
    "That is important, because arithmetic with a `decimal` and a `double` is\n",
    "forbidden: A `double` would have to be explicitly cast to a `decimal`.\n",
    "Insisting on `decimal` parameter simplifies the method code.\n",
    "\n",
    "```{rubric} Footnotes\n",
    "```\n",
    "\n",
    "[^number-in-range]: This question is from `Example: Number in Range [1..100]<https://csharp-book.softuni.org/Content/Chapter-7-1-complex-loops/while-loop/examples/example-number-in-range-1100.html>`"
   ]
  }
 ],
 "metadata": {
  "language_info": {
   "name": "csharp"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}