{
  "nbformat": 4,
  "nbformat_minor": 5,
  "metadata": {
    "kernelspec": {
      "display_name": "Python 3",
      "language": "python",
      "name": "python3"
    }
  },
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": "# ZHUDDLE | Chapter 06: Strings\n\n8 coding missions + 10 MCQs. 100 XP.\n\nAdapted from Charles R. Severance, Python for Everybody (CC BY 4.0).\n\nSource: https://www.py4e.com/html3/06-strings\n\nReading: https://www.py4e.com/html3/06-strings\n\nThe browser runs five independent cases per coding mission. This notebook supplies the first sample; input prompts here are interactive.",
      "id": "strings-000"
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": "## C01 | First, last, and length\n\nFor supplied nonempty `fruit`, assign its first character to `first`, its last character to `last`, and its length to `length`. Use indexing and len.\n\nFive independent checks are worth 2 XP each. The checker supplies the variables below with different values on each check. Use them without replacing their starting values.\n\n```python\nfruit = 'banana'\n```\n\n**Source checkpoint:** A string is a sequence; Getting the length of a string using len",
      "id": "strings-001"
    },
    {
      "cell_type": "code",
      "metadata": {},
      "source": "fruit = 'banana'",
      "execution_count": null,
      "outputs": [],
      "id": "strings-002"
    },
    {
      "cell_type": "code",
      "metadata": {},
      "source": "first = None\nlast = None\nlength = None",
      "execution_count": null,
      "outputs": [],
      "id": "strings-003"
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": "## C02 | Walk a string backwards\n\nUse a while loop to print each character of `fruit` on its own line, starting at the end. An empty string should print nothing.\n\nFive independent checks are worth 2 XP each. The checker supplies the variables below with different values on each check. Use them without replacing their starting values.\n\n```python\nfruit = 'banana'\n```\n\n**Source checkpoint:** Traversal through a string with a loop; Exercise 1",
      "id": "strings-004"
    },
    {
      "cell_type": "code",
      "metadata": {},
      "source": "fruit = 'banana'",
      "execution_count": null,
      "outputs": [],
      "id": "strings-005"
    },
    {
      "cell_type": "code",
      "metadata": {},
      "source": "# Start at the final index and work backwards.",
      "execution_count": null,
      "outputs": [],
      "id": "strings-006"
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": "## C03 | Slice a word\n\nUsing slices of `fruit`, save its first three characters as `prefix`, everything from index 3 as `suffix`, and the full string as `copy`. Short and empty strings are valid.\n\nFive independent checks are worth 2 XP each. The checker supplies the variables below with different values on each check. Use them without replacing their starting values.\n\n```python\nfruit = 'banana'\n```\n\n**Source checkpoint:** String slices; Exercise 2",
      "id": "strings-007"
    },
    {
      "cell_type": "code",
      "metadata": {},
      "source": "fruit = 'banana'",
      "execution_count": null,
      "outputs": [],
      "id": "strings-008"
    },
    {
      "cell_type": "code",
      "metadata": {},
      "source": "prefix = None\nsuffix = None\ncopy = None",
      "execution_count": null,
      "outputs": [],
      "id": "strings-009"
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": "## C04 | Create a new greeting\n\nKeep supplied nonempty `greeting` unchanged. Build `new_greeting` by replacing its first character with supplied `letter`, using concatenation and a slice.\n\nFive independent checks are worth 2 XP each. The checker supplies the variables below with different values on each check. Use them without replacing their starting values.\n\n```python\ngreeting = 'Hello, world!'\nletter = 'J'\n```\n\n**Source checkpoint:** Strings are immutable",
      "id": "strings-010"
    },
    {
      "cell_type": "code",
      "metadata": {},
      "source": "greeting = 'Hello, world!'\nletter = 'J'",
      "execution_count": null,
      "outputs": [],
      "id": "strings-011"
    },
    {
      "cell_type": "code",
      "metadata": {},
      "source": "new_greeting = None",
      "execution_count": null,
      "outputs": [],
      "id": "strings-012"
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": "## C05 | Count a chosen letter\n\nUse a for loop to count occurrences of supplied `letter` in `word`. Save the integer in `count`. Matching is case-sensitive. Practice the counter pattern without using the count method.\n\nFive independent checks are worth 2 XP each. The checker supplies the variables below with different values on each check. Use them without replacing their starting values.\n\n```python\nword = 'banana'\nletter = 'a'\n```\n\n**Source checkpoint:** Looping and counting",
      "id": "strings-013"
    },
    {
      "cell_type": "code",
      "metadata": {},
      "source": "word = 'banana'\nletter = 'a'",
      "execution_count": null,
      "outputs": [],
      "id": "strings-014"
    },
    {
      "cell_type": "code",
      "metadata": {},
      "source": "count = 0\n# Count matching letters.",
      "execution_count": null,
      "outputs": [],
      "id": "strings-015"
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": "## C06 | Clean and normalize\n\nRemove whitespace from both ends of `line` into `clean`. Save an uppercase copy as `loud` and a lowercase copy as `quiet`. Set `starts` to whether quiet starts with \"have\". Leave line unchanged.\n\nFive independent checks are worth 2 XP each. The checker supplies the variables below with different values on each check. Use them without replacing their starting values.\n\n```python\nline = '  Have a nice day  '\n```\n\n**Source checkpoint:** String methods",
      "id": "strings-016"
    },
    {
      "cell_type": "code",
      "metadata": {},
      "source": "line = '  Have a nice day  '",
      "execution_count": null,
      "outputs": [],
      "id": "strings-017"
    },
    {
      "cell_type": "code",
      "metadata": {},
      "source": "clean = None\nloud = None\nquiet = None\nstarts = None",
      "execution_count": null,
      "outputs": [],
      "id": "strings-018"
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": "## C07 | Find the mail host\n\nThe supplied `data` contains a From line with an email address followed by a space and date. Use find and slicing to extract the domain after @ into `host`. Do not use split.\n\nFive independent checks are worth 2 XP each. The checker supplies the variables below with different values on each check. Use them without replacing their starting values.\n\n```python\ndata = 'From stephen@uct.ac.za Sat Jan 5'\n```\n\n**Source checkpoint:** Parsing strings",
      "id": "strings-019"
    },
    {
      "cell_type": "code",
      "metadata": {},
      "source": "data = 'From stephen@uct.ac.za Sat Jan 5'",
      "execution_count": null,
      "outputs": [],
      "id": "strings-020"
    },
    {
      "cell_type": "code",
      "metadata": {},
      "source": "host = None\n# Locate @, then the space after it.",
      "execution_count": null,
      "outputs": [],
      "id": "strings-021"
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": "## C08 | Extract a numeric field\n\nFrom `text` in the form `X-DSPAM-Confidence: number`, use find and slicing to take the text after the colon. Convert it to a float called `confidence` and print it. Whitespace around the number is allowed.\n\nFive independent checks are worth 2 XP each. The checker supplies the variables below with different values on each check. Use them without replacing their starting values.\n\n```python\ntext = 'X-DSPAM-Confidence: 0.8475'\n```\n\n**Source checkpoint:** Exercises: Exercise 5",
      "id": "strings-022"
    },
    {
      "cell_type": "code",
      "metadata": {},
      "source": "text = 'X-DSPAM-Confidence: 0.8475'",
      "execution_count": null,
      "outputs": [],
      "id": "strings-023"
    },
    {
      "cell_type": "code",
      "metadata": {},
      "source": "confidence = None\n# Find the colon, slice, convert, and print.",
      "execution_count": null,
      "outputs": [],
      "id": "strings-024"
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": "## M01 | Zero-based indexing\n\nWhat is `\"banana\"[1]`?\n\nA. b\nB. a\nC. n\nD. An error",
      "id": "strings-025"
    },
    {
      "cell_type": "code",
      "metadata": {},
      "source": "m01 = \"\"  # A, B, C, or D",
      "execution_count": null,
      "outputs": [],
      "id": "strings-026"
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": "## M02 | Final character\n\nFor a nonempty string s, which selects its final character?\n\nA. s[len(s)]\nB. s[1]\nC. s[-1]\nD. s[0]",
      "id": "strings-027"
    },
    {
      "cell_type": "code",
      "metadata": {},
      "source": "m02 = \"\"  # A, B, C, or D",
      "execution_count": null,
      "outputs": [],
      "id": "strings-028"
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": "## M03 | Slice boundary\n\nWhat is `\"Monty Python\"[0:5]`?\n\nA. \"Monty \"\nB. \"Python\"\nC. \"Mont\"\nD. \"Monty\"",
      "id": "strings-029"
    },
    {
      "cell_type": "code",
      "metadata": {},
      "source": "m03 = \"\"  # A, B, C, or D",
      "execution_count": null,
      "outputs": [],
      "id": "strings-030"
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": "## M04 | Empty slice\n\nWhat is `\"banana\"[3:3]`?\n\nA. An empty string\nB. \"a\"\nC. None\nD. An error",
      "id": "strings-031"
    },
    {
      "cell_type": "code",
      "metadata": {},
      "source": "m04 = \"\"  # A, B, C, or D",
      "execution_count": null,
      "outputs": [],
      "id": "strings-032"
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": "## M05 | Immutable text\n\nWhat happens to `greeting[0] = \"J\"` when greeting is a string?\n\nA. It changes the first letter\nB. It appends J\nC. It raises a TypeError\nD. It deletes greeting",
      "id": "strings-033"
    },
    {
      "cell_type": "code",
      "metadata": {},
      "source": "m05 = \"\"  # A, B, C, or D",
      "execution_count": null,
      "outputs": [],
      "id": "strings-034"
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": "## M06 | Substring membership\n\nWhat is `\"ana\" in \"banana\"`?\n\nA. False\nB. True\nC. 3\nD. \"ana\"",
      "id": "strings-035"
    },
    {
      "cell_type": "code",
      "metadata": {},
      "source": "m06 = \"\"  # A, B, C, or D",
      "execution_count": null,
      "outputs": [],
      "id": "strings-036"
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": "## M07 | Find failure\n\nWhat does `\"banana\".find(\"z\")` return?\n\nA. 0\nB. None\nC. 6\nD. -1",
      "id": "strings-037"
    },
    {
      "cell_type": "code",
      "metadata": {},
      "source": "m07 = \"\"  # A, B, C, or D",
      "execution_count": null,
      "outputs": [],
      "id": "strings-038"
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": "## M08 | Whitespace cleanup\n\nWhich removes whitespace from both ends of a string?\n\nA. strip()\nB. upper()\nC. find()\nD. startswith()",
      "id": "strings-039"
    },
    {
      "cell_type": "code",
      "metadata": {},
      "source": "m08 = \"\"  # A, B, C, or D",
      "execution_count": null,
      "outputs": [],
      "id": "strings-040"
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": "## M09 | Case-sensitive prefix\n\nWhat is `\"Have a nice day\".startswith(\"h\")`?\n\nA. True\nB. \"Have\"\nC. False\nD. An error",
      "id": "strings-041"
    },
    {
      "cell_type": "code",
      "metadata": {},
      "source": "m09 = \"\"  # A, B, C, or D",
      "execution_count": null,
      "outputs": [],
      "id": "strings-042"
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": "## M10 | A full slice\n\nWhat does `fruit[:]` select?\n\nA. The first character\nB. The entire string\nC. The last character\nD. An empty string",
      "id": "strings-043"
    },
    {
      "cell_type": "code",
      "metadata": {},
      "source": "m10 = \"\"  # A, B, C, or D",
      "execution_count": null,
      "outputs": [],
      "id": "strings-044"
    }
  ]
}
