{
 "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} ../../../materials/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} ../../../materials/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} ../../../materials/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:: ../../../materials/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:: ../../../materials/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": [
    "int i = 2;\n",
    "int rev = 0;\n",
    "int[] s = { 3, 7, 1, 9, 4 };\n",
    "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": [
    "int i = 2;\n",
    "int rev = 0;\n",
    "int[] s = { 3, 7, 1, 9, 4 };\n",
    "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} ../../../materials/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)."
   ]
  }
 ],
 "metadata": {
  "language_info": {
   "name": "csharp"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
