{"id":"strings-indexing","slug":"indexing","title":"One character at a time","text":"A string is a row of characters, and each character has a number that tells its place: its **index**. Indexes start from 0, not 1. The first character has the index 0, the second has 1, and so on:\n\n```text\np  y  t  h  o  n\n0  1  2  3  4  5\n```\n\nTo get a single character, write its index in square brackets after the string:\n\n```python\nword = \"python\"\nprint(word[0])\nprint(word[1])\nprint(word[5])\n```\n\n```output\np\ny\nn\n```\n\nThe result is a string too, one character long, so you can join it, compare it and print it like any other string.\n\n### The last character\n\nA string of 6 characters has the indexes 0 to 5: the last index is always one less than the length. So for a string of any length, the last character is at `len(text) - 1`.\n\nIn a word chain game, each word must start with the letter the previous word ended with. This program checks one link of the chain, comparing the first character of the new word with the last character of the old one:\n\n```python\nold = input(\"Previous word: \")\nnew = input(\"Your word: \")\nif new[0] == old[len(old) - 1]:\n    print(\"Good link!\")\nelse:\n    print(\"Your word should start with \" + old[len(old) - 1])\n```\n\n```input\npython\napple\n```\n\n```output\nPrevious word: python\nYour word: apple\nYour word should start with n\n```\n\n### IndexError\n\nAsking for an index that the string doesn't have stops the program. A very common slip is to use the length itself as the last index:\n\n```python\nword = \"cat\"\nprint(word[len(word)])\n```\n\n```crash\nTraceback (most recent call last):\n  File \"main.py\", line 2, in <module>\n    print(word[len(word)])\n          ~~~~^^^^^^^^^^^\nIndexError: string index out of range\n```\n\n`\"cat\"` has the indexes 0, 1 and 2, and `len(word)` is 3. \"Out of range\" means the index is outside the indexes the string has.\n\n### Every character in turn\n\nWith a helper variable as the index, a loop can visit the characters one by one. It goes on while the index is below the length, so the last round has the index `len(word) - 1`:\n\n```python\nword = \"loop\"\nindex = 0\nwhile index < len(word):\n    print(f\"{index}: {word[index]}\")\n    index += 1\n```\n\n```output\n0: l\n1: o\n2: o\n3: p\n```\n","task":"Fill in the blanks so the program prints the initials of the name typed in, each followed by a dot.\n\n```\nFirst name: Ada\nLast name: Lovelace\nA.L.\n```\n","kind":"fill","seed":"first = input(\"First name: \")\nlast = input(\"Last name: \")\nprint(first[[[0]]] + \".\" + last[[[0]]] + \".\")\n","solution":"first = input(\"First name: \")\nlast = input(\"Last name: \")\nprint(first[0] + \".\" + last[0] + \".\")\n","hints":["An initial is the first character of a name.","Indexes start from 0, so the first character of `first` is `first[0]`. Type the index into each blank."],"tests":[{"name":"Test 1","stdin":"Ada\nLovelace\n","expect":"First name: Ada\nLast name: Lovelace\nA.L.","hidden":false},{"name":"Test 2","stdin":"Grace\nHopper\n","expect":"First name: Grace\nLast name: Hopper\nG.H.","hidden":true},{"name":"Test 3","stdin":"Linus\nTorvalds\n","expect":"First name: Linus\nLast name: Torvalds\nL.T.","hidden":true}],"require":[],"forbid":[],"more":[{"task":"Write a program that asks for a word and prints its characters one per line, each with its place in the word, counted from 1.\n\n```\nWord: cat\n1. c\n2. a\n3. t\n```\n","kind":"code","seed":"word = input(\"Word: \")\n","solution":"word = input(\"Word: \")\nindex = 0\nwhile index < len(word):\n    print(f\"{index + 1}. {word[index]}\")\n    index += 1\n","hints":["Loop with an index that starts at 0 and goes on while it's below `len(word)`.","The character is `word[index]`. Its place counted from 1 is one more than its index, `index + 1`."],"tests":[{"name":"Test 1","stdin":"cat\n","expect":"Word: cat\n1. c\n2. a\n3. t","hidden":false},{"name":"Test 2","stdin":"a\n","expect":"Word: a\n1. a","hidden":true},{"name":"Test 3","stdin":"banana\n","expect":"Word: banana\n1. b\n2. a\n3. n\n4. a\n5. n\n6. a","hidden":true},{"name":"Test 4","stdin":"hi there\n","expect":"Word: hi there\n1. h\n2. i\n3.\n4. t\n5. h\n6. e\n7. r\n8. e","hidden":true}],"require":[],"forbid":[]},{"task":"This program should print every character of a word twice, one pair per line, but it stops with an `IndexError`. Fix it.\n\n```\nWord: cat\ncc\naa\ntt\n```\n","kind":"code","seed":"word = input(\"Word: \")\nindex = 0\nwhile index <= len(word):\n    print(word[index] + word[index])\n    index += 1\n","solution":"word = input(\"Word: \")\nindex = 0\nwhile index < len(word):\n    print(word[index] + word[index])\n    index += 1\n","hints":["Check it and read the error: which index is it asking for when it stops? For `cat`, which indexes exist?","The last index is `len(word) - 1`, but the loop also runs with `index` equal to `len(word)`. Look at the comparison in the condition."],"tests":[{"name":"Test 1","stdin":"cat\n","expect":"Word: cat\ncc\naa\ntt","hidden":false},{"name":"Test 2","stdin":"x\n","expect":"Word: x\nxx","hidden":true},{"name":"Test 3","stdin":"hello\n","expect":"Word: hello\nhh\nee\nll\nll\noo","hidden":true}],"require":[],"forbid":[]}]}