[{"data":1,"prerenderedAt":259},["ShallowReactive",2],{"tag-labels":3,"site-header":4,"article-python-strings-en":69},{},{"featuredPost":5,"navigations":26},{"id":6,"title":7,"title_en":8,"slug":9,"excerpt":10,"excerpt_en":8,"has_translation":11,"published_at":12,"reading_time":13,"hidden_from_listing":11,"tags":14,"thumbnail_image":8,"og_image":19,"series":20,"authors":25},110,"Ketika Pilih Framework Cuma Biar Kelihatan Beda",null,"ketika-pilih-framework-cuma-biar-kelihatan-beda","Terakhir kali kamu milih framework atau library baru, itu karena masalahmu butuh alat itu, atau karena alatnya kedengaran keren dan belum banyak yang pakai? Pertanyaan ini nggak enak dijawab. Soalnya keputusan teknologi sering diambil dengan alasan yang nggak pernah ditulis di dokumen teknis mana pun.",false,"2026-10-06T15:25:21.000Z",5,[15,16,17,18],"karier","framework","opini","pengalaman","\u002Fog\u002Fketika-pilih-framework-cuma-biar-kelihatan-beda.png",{"id":21,"title":22,"title_en":23,"slug":24},9,"Artikel","Articles","all",[],[27,43,64],{"collection":28,"item":29},"series",{"__typename":28,"title":22,"title_en":23,"slug":24,"children_series":30},[31,35,39],{"title":32,"title_en":33,"slug":34},"Kecerdasan Artifisial","Artificial Intelligence","kecerdasan-artifisial",{"title":36,"title_en":37,"slug":38},"Konsep Dasar Pemrograman","Programming Fundamentals","konsep-dasar-pemrograman",{"title":40,"title_en":41,"slug":42},"Algoritma dan Struktur Data","Algorithms and Data Structures","algoritma-struktur-data",{"collection":28,"item":44},{"__typename":28,"title":45,"title_en":45,"slug":46,"children_series":47},"Tutorial","tutorial",[48,52,56,60],{"title":49,"title_en":50,"slug":51},"Belajar Python","Learning Python","belajar-python",{"title":53,"title_en":54,"slug":55},"Belajar Golang","Learning Go","belajar-golang",{"title":57,"title_en":58,"slug":59},"Belajar Java","Learning Java","belajar-java",{"title":61,"title_en":62,"slug":63},"Belajar Pascal","Learning Pascal","belajar-pascal",{"collection":28,"item":65},{"__typename":28,"title":66,"title_en":66,"slug":67,"children_series":68},"Lab","lab",[],{"article":70,"renderedBody":176,"renderedTakeaway":177,"latestArticles":178,"toc":236},{"id":71,"title":72,"title_en":8,"slug":73,"excerpt":74,"excerpt_en":8,"has_translation":11,"published_at":75,"reading_time":76,"hidden_from_listing":11,"tags":77,"thumbnail_image":8,"og_image":80,"series":81,"authors":168,"body_locale":171,"available_locales":172,"body":174,"takeway":175,"prerequisite":8},133,"Python Strings: the Badge That Only Worked for One Name","python-strings","The badge script printed the right name for the person who wrote it and the wrong name for everybody else. Slicing counts characters, and a name is words.","2026-10-28T13:00:00.000Z",6,[78,79],"python","string","\u002Fog\u002Fpython-strings.png",{"id":82,"title":83,"title_en":84,"slug":85,"description":86,"description_en":87,"articles":88,"children_series":137,"parent_series":138},30,"Koleksi dan String","Collections and Strings","python-collections","Dictionary, set, tuple, dan cara mengolah string. Tipe data yang baru kepakai begitu program berhenti menyimpan satu nilai saja.","Dictionaries, sets, tuples, and the string methods that do the boring parts. The types you need once a program stops holding a single value.",[89,106,119,132],{"id":90,"title":91,"title_en":8,"slug":92,"excerpt":93,"excerpt_en":8,"has_translation":11,"published_at":94,"reading_time":76,"hidden_from_listing":11,"tags":95,"thumbnail_image":8,"og_image":97,"series":98,"authors":99},130,"Python Dictionaries: the Key That Isn't There","python-dictionary","A word counter dies the first time it meets a word twice. The fix is one line; what takes longer is knowing which of a dict's three lookups to reach for.","2026-10-28T10:00:00.000Z",[78,96],"dictionary","\u002Fog\u002Fpython-dictionary.png",{"id":82,"title":83,"title_en":84,"slug":85},[100],{"authors_id":101},{"id":102,"name":103,"slug":104,"role":105,"profile_picture":8},1,"Daffa Izzuddin","izzudd","Writer",{"id":107,"title":108,"title_en":8,"slug":109,"excerpt":110,"excerpt_en":8,"has_translation":11,"published_at":111,"reading_time":76,"hidden_from_listing":11,"tags":112,"thumbnail_image":8,"og_image":114,"series":115,"authors":116},131,"Python Sets: the Duplicate That Keeps Coming Back","python-sets","A de-duplication loop that works on clean data leaves four tags where there should be two. The bug is case, and the fix is a `set`.","2026-10-28T11:00:00.000Z",[78,113],"set","\u002Fog\u002Fpython-sets.png",{"id":82,"title":83,"title_en":84,"slug":85},[117],{"authors_id":118},{"id":102,"name":103,"slug":104,"role":105,"profile_picture":8},{"id":120,"title":121,"title_en":8,"slug":122,"excerpt":123,"excerpt_en":8,"has_translation":11,"published_at":124,"reading_time":76,"hidden_from_listing":11,"tags":125,"thumbnail_image":8,"og_image":127,"series":128,"authors":129},132,"Python Tuples: Why All Three Points Are the Same Point","python-tuples","Three points walk into a loop and come out identical. The list was never copied three times; the name was. A tuple makes that bug impossible.","2026-10-28T12:00:00.000Z",[78,126],"tuple","\u002Fog\u002Fpython-tuples.png",{"id":82,"title":83,"title_en":84,"slug":85},[130],{"authors_id":131},{"id":102,"name":103,"slug":104,"role":105,"profile_picture":8},{"id":71,"title":72,"title_en":8,"slug":73,"excerpt":74,"excerpt_en":8,"has_translation":11,"published_at":75,"reading_time":76,"hidden_from_listing":11,"tags":77,"thumbnail_image":8,"og_image":80,"series":133,"authors":134},{"id":82,"title":83,"title_en":84,"slug":85},[135],{"authors_id":136},{"id":102,"name":103,"slug":104,"role":105,"profile_picture":8},[],{"id":139,"title":49,"title_en":50,"slug":51,"parent_series":140,"children_series":141},10,{"id":102,"title":45,"title_en":45,"slug":46},[142,147,152,157,162,167],{"id":143,"title":144,"title_en":145,"slug":146,"cover_image":8},16,"Berkenalan dengan Bahasa Python","Getting Started with Python","python-intro",{"id":148,"title":149,"title_en":150,"slug":151,"cover_image":8},17,"Variabel, Tipe Data, dan Operasi","Variables, Types, and Operations","python-variabel-tipe-data",{"id":153,"title":154,"title_en":155,"slug":156,"cover_image":8},18,"Menggunakan Script Python","Working with Python Scripts","python-pemrograman-dengan-script",{"id":158,"title":159,"title_en":160,"slug":161,"cover_image":8},19,"Struktur Kontrol","Control Structures","python-struktur-kontrol",{"id":163,"title":164,"title_en":165,"slug":166,"cover_image":8},20,"Pemrograman Fungsional dengan Python","Functional Programming with Python","python-pemrograman-fungsional",{"id":82,"title":83,"title_en":84,"slug":85,"cover_image":8},[169],{"authors_id":170},{"id":102,"name":103,"slug":104,"role":105,"profile_picture":8},"en",[173],"id","\nA name badge is a fine first string exercise, right up until a second person joins.\n\nThe script worked. It read a name, printed the first name, the last name, and the initials, and the output was exactly what the person who wrote it expected. The next name on the list was longer, and the badge came out as `Alexa`, `Der Hamilton`, `A. D.`. Three lines, none of them right, and no error to explain any of it.\n\n## Two files, one command\n\nSame contract as the rest of this series: you write the program, the article hands you a checker, you run it until it goes from red to green. No repository, no Docker, `python3` only.\n\nCreate `badge.py`:\n\n```python\n# badge.py\nimport sys\n\nraw = sys.stdin.read().strip()\n\nfirst = raw[0:5].title()\nlast = raw[6:].title()\n\nprint(first)\nprint(last)\nprint(f\"{first[0]}. {last[0]}.\")\n```\n\nThen `check_badge.py` next to it. It feeds in a name and reads the three lines back:\n\n```python\n# check_badge.py\nimport subprocess\nimport sys\n\nNAME = \"  alexander hamilton  \"\nEXPECTED = [\"Alexander\", \"Hamilton\", \"A. H.\"]\n\n\ndef report(results):\n    for label, passed, detail in results:\n        mark = \"PASS\" if passed else \"FAIL\"\n        note = f\"  \u003C- {detail}\" if detail and not passed else \"\"\n        print(f\"{mark}  {label}{note}\")\n    passed = [ok for _, ok, _ in results].count(True)\n    print(f\"\\n{passed} of {len(results)} checks passed\")\n\n\ndef main():\n    run = subprocess.run([sys.executable, \"badge.py\"], input=NAME, text=True, capture_output=True)\n    crashed = run.returncode != 0\n    last_error = run.stderr.strip().splitlines()[-1] if run.stderr.strip() else \"\"\n\n    results = [(\"the script runs without crashing\", not crashed, last_error)]\n    if crashed:\n        report(results)\n        return 1\n\n    lines = [line.strip() for line in run.stdout.splitlines() if line.strip()]\n    results.append((\"prints three lines\", len(lines) == 3, f\"got {len(lines)}: {lines}\"))\n\n    for index, expected in enumerate(EXPECTED):\n        got = lines[index] if index \u003C len(lines) else \"nothing\"\n        results.append((f\"line {index + 1} is {expected!r}\", got == expected, repr(got)))\n\n    report(results)\n    return 0 if all(ok for _, ok, _ in results) else 1\n\n\nif __name__ == \"__main__\":\n    sys.exit(main())\n```\n\n```\n$ python3 check_badge.py\nPASS  the script runs without crashing\nPASS  prints three lines\nFAIL  line 1 is 'Alexander'  \u003C- 'Alexa'\nFAIL  line 2 is 'Hamilton'  \u003C- 'Der Hamilton'\nFAIL  line 3 is 'A. H.'  \u003C- 'A. D.'\n\n2 of 5 checks passed\n```\n\nFeed it `daffa izzuddin` instead and all three lines are correct. That is the whole problem: the script is not broken, it is fitted to one piece of data.\n\n## A slice counts characters, not words\n\nSquare brackets address positions. `raw[0]` is the first character, `raw[-1]` is the last, `raw[1:4]` is positions 1, 2 and 3 (the end is excluded), and `raw[3:]` runs to the end of the string. That is all a slice is: a range of positions.\n\nSo `raw[0:5]` asks for five characters from the left. When the name was `daffa izzuddin`, five characters happened to be `daffa`, the first name, and `raw[6:]` happened to start right after the space. Both numbers were correct once, for one name, and never again.\n\nNothing in the expression says \"first name\". A slice cannot tell a word from a coincidence, and it will not warn you when the data changes shape. That is not a flaw in slicing; it is slicing doing exactly what it was asked.\n\n## The methods that know about words\n\nStrings come with methods that already understand the structure you are after, and they are usually shorter than the slice you were about to write. `.split()` with no argument cuts on any run of spaces, tabs or newlines, and it drops the runs entirely, which is why the padding around the input never reaches the output. `.strip()` removes whitespace at the two ends. `.title()` capitalises each word, `.upper()` and `.lower()` change case, `.replace(\"a\", \"b\")` swaps text, `.startswith()` and `.endswith()` answer about the edges, and `\" \".join(words)` is the reverse of `split`.\n\nThe rule that keeps this simple: **if the question is \"which word\", split. If the question is \"which character\", slice.** Nine times out of ten you were asking the first one.\n\n## A method does not change the string\n\nThis one costs everybody an afternoon. Strings cannot be modified in place:\n\n```python\nname = \"daffa\"\nname.upper()\nprint(name)\n```\n\n```\ndaffa\n```\n\n`.upper()` returns a new string and leaves the old one alone. Nothing was assigned, so the result was dropped. `.strip()`, `.title()` and `.replace()` behave the same way. That is also why the reading line in the script starts with `raw = sys.stdin.read().strip()`: the assignment is doing the work, not the method.\n\n## The fix\n\n```python\n# badge.py\nimport sys\n\nname = sys.stdin.read().strip()\nparts = name.split()\n\nfirst = parts[0].title()\nlast = parts[-1].title()\n\nprint(first)\nprint(last)\nprint(f\"{first[0]}. {last[0]}.\")\n```\n\n```\n$ python3 check_badge.py\nPASS  the script runs without crashing\nPASS  prints three lines\nPASS  line 1 is 'Alexander'\nPASS  line 2 is 'Hamilton'\nPASS  line 3 is 'A. H.'\n\n5 of 5 checks passed\n```\n\n`split()` returns a list of words of whatever length the name happens to be. `parts[0]` is the first word and `parts[-1]` is the last one, and both of those are true for any number of words, which is the property the hardcoded slice was pretending to have.\n\n## When a slice is the right tool\n\nSlicing is not the villain. It is the right tool when the position itself carries the meaning: the first letter of a word, the last segment of a file name, the first four digits of a year, a fixed-width code from a form. Notice that `first[0]` survives in the fixed version, because \"the first character of this word\" is true regardless of how long the word is.\n\nThe useful test is whether the number would still be correct if the data doubled in size. `first[0]` would. `raw[0:5]` would not.\n\n## Before the next article\n\nGive it a single-word name. It does not crash, does not warn, and prints `Cher`, `Cher`, `C. C.` — a badge nobody would accept, produced silently. Then try `first, last = name.split()` instead of the two indexed lines: with a middle name it raises `ValueError: too many values to unpack (expected 2, got 3)`.\n\nTwo failures with nothing in common except that the checker only knows what you told it to expect. Deciding what a one-word badge *should* say is your job; the checker can only hold you to your own answer.\n","- `raw[0:5]` means five characters from the left, not the first word — slices never check what they cut.\n- `.split()` with no argument splits on any run of whitespace and handles the padding, which is why `.strip()` is less necessary than it looks.\n- A string method returns a new string: `s.upper()` on its own changes nothing until you assign it.\n- Slice when the position is the point, split when the word is the point, and use a method before writing either.\n- `s[0]` and `s[-1]` are safe at any length; `s[0:5]` is a guess about the data.","\u003Cp>A name badge is a fine first string exercise, right up until a second person joins.\u003C\u002Fp>\n\u003Cp>The script worked. It read a name, printed the first name, the last name, and the initials, and the output was exactly what the person who wrote it expected. The next name on the list was longer, and the badge came out as \u003Ccode>Alexa\u003C\u002Fcode>, \u003Ccode>Der Hamilton\u003C\u002Fcode>, \u003Ccode>A. D.\u003C\u002Fcode>. Three lines, none of them right, and no error to explain any of it.\u003C\u002Fp>\n\u003Ch2 id=\"two-files-one-command\">Two files, one command\u003C\u002Fh2>\n\u003Cp>Same contract as the rest of this series: you write the program, the article hands you a checker, you run it until it goes from red to green. No repository, no Docker, \u003Ccode>python3\u003C\u002Fcode> only.\u003C\u002Fp>\n\u003Cp>Create \u003Ccode>badge.py\u003C\u002Fcode>:\u003C\u002Fp>\n\n\u003Cdiv class=\"code-block-wrapper my-6 not-prose rounded-xl border-2 border-black dark:border-gray-600 shadow-neo overflow-hidden bg-[#24292e] text-[#e1e4e8] transition-all\">\n  \u003Cdiv class=\"code-block-header flex items-center justify-between px-4 py-2.5 bg-[#1f2428] border-b-2 border-black dark:border-gray-600 font-mono text-xs font-bold text-gray-300 select-none\">\n    \u003Cdiv class=\"flex items-center gap-2\">\n      \u003Cspan class=\"w-3 h-3 rounded-full bg-[#ff5f56] border border-black\u002F40 inline-block\">\u003C\u002Fspan>\n      \u003Cspan class=\"w-3 h-3 rounded-full bg-[#ffbd2e] border border-black\u002F40 inline-block\">\u003C\u002Fspan>\n      \u003Cspan class=\"w-3 h-3 rounded-full bg-[#27c93f] border border-black\u002F40 inline-block\">\u003C\u002Fspan>\n      \u003Cspan class=\"ml-2 font-mono font-bold text-xs uppercase tracking-wider text-gray-300\">PYTHON\u003C\u002Fspan>\n    \u003C\u002Fdiv>\n    \u003Cbutton type=\"button\" class=\"copy-code-btn flex items-center gap-1.5 px-3 py-1 text-xs font-bold bg-[#2f363d] text-gray-200 border-2 border-black dark:border-gray-500 rounded-lg shadow-neo-sm hover:translate-x-0.5 hover:translate-y-0.5 hover:shadow-none hover:bg-gray-700 transition-all cursor-pointer\" data-code=\"%23%20badge.py%0Aimport%20sys%0A%0Araw%20%3D%20sys.stdin.read().strip()%0A%0Afirst%20%3D%20raw%5B0%3A5%5D.title()%0Alast%20%3D%20raw%5B6%3A%5D.title()%0A%0Aprint(first)%0Aprint(last)%0Aprint(f%22%7Bfirst%5B0%5D%7D.%20%7Blast%5B0%5D%7D.%22)\" title=\"Salin kode\">\n      \u003Csvg class=\"w-3.5 h-3.5 copy-icon-svg\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n        \u003Cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\">\u003C\u002Fpath>\n      \u003C\u002Fsvg>\n      \u003Cspan class=\"copy-text\">Copy\u003C\u002Fspan>\n    \u003C\u002Fbutton>\n  \u003C\u002Fdiv>\n  \u003Cdiv class=\"code-block-content p-4 overflow-x-auto text-sm font-mono leading-relaxed bg-[#24292e]\">\n    \u003Cpre class=\"shiki github-dark\" style=\"background-color:#24292e;color:#e1e4e8\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\"># badge.py\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">import\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> sys\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">raw \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">=\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> sys.stdin.read().strip()\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">first \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">=\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> raw[\u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\">0\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">:\u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\">5\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">].title()\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">last \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">=\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> raw[\u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\">6\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">:].title()\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">print\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">(first)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">print\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">(last)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">print\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">(\u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">f\u003C\u002Fspan>\u003Cspan style=\"color:#9ECBFF\">\"\u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\">{\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">first[\u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\">0\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">]\u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\">}\u003C\u002Fspan>\u003Cspan style=\"color:#9ECBFF\">. \u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\">{\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">last[\u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\">0\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">]\u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\">}\u003C\u002Fspan>\u003Cspan style=\"color:#9ECBFF\">.\"\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">)\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\n  \u003C\u002Fdiv>\n\u003C\u002Fdiv>\u003Cp>Then \u003Ccode>check_badge.py\u003C\u002Fcode> next to it. It feeds in a name and reads the three lines back:\u003C\u002Fp>\n\n\u003Cdiv class=\"code-block-wrapper my-6 not-prose rounded-xl border-2 border-black dark:border-gray-600 shadow-neo overflow-hidden bg-[#24292e] text-[#e1e4e8] transition-all\">\n  \u003Cdiv class=\"code-block-header flex items-center justify-between px-4 py-2.5 bg-[#1f2428] border-b-2 border-black dark:border-gray-600 font-mono text-xs font-bold text-gray-300 select-none\">\n    \u003Cdiv class=\"flex items-center gap-2\">\n      \u003Cspan class=\"w-3 h-3 rounded-full bg-[#ff5f56] border border-black\u002F40 inline-block\">\u003C\u002Fspan>\n      \u003Cspan class=\"w-3 h-3 rounded-full bg-[#ffbd2e] border border-black\u002F40 inline-block\">\u003C\u002Fspan>\n      \u003Cspan class=\"w-3 h-3 rounded-full bg-[#27c93f] border border-black\u002F40 inline-block\">\u003C\u002Fspan>\n      \u003Cspan class=\"ml-2 font-mono font-bold text-xs uppercase tracking-wider text-gray-300\">PYTHON\u003C\u002Fspan>\n    \u003C\u002Fdiv>\n    \u003Cbutton type=\"button\" class=\"copy-code-btn flex items-center gap-1.5 px-3 py-1 text-xs font-bold bg-[#2f363d] text-gray-200 border-2 border-black dark:border-gray-500 rounded-lg shadow-neo-sm hover:translate-x-0.5 hover:translate-y-0.5 hover:shadow-none hover:bg-gray-700 transition-all cursor-pointer\" data-code=\"%23%20check_badge.py%0Aimport%20subprocess%0Aimport%20sys%0A%0ANAME%20%3D%20%22%20%20alexander%20hamilton%20%20%22%0AEXPECTED%20%3D%20%5B%22Alexander%22%2C%20%22Hamilton%22%2C%20%22A.%20H.%22%5D%0A%0A%0Adef%20report(results)%3A%0A%20%20%20%20for%20label%2C%20passed%2C%20detail%20in%20results%3A%0A%20%20%20%20%20%20%20%20mark%20%3D%20%22PASS%22%20if%20passed%20else%20%22FAIL%22%0A%20%20%20%20%20%20%20%20note%20%3D%20f%22%20%20%3C-%20%7Bdetail%7D%22%20if%20detail%20and%20not%20passed%20else%20%22%22%0A%20%20%20%20%20%20%20%20print(f%22%7Bmark%7D%20%20%7Blabel%7D%7Bnote%7D%22)%0A%20%20%20%20passed%20%3D%20%5Bok%20for%20_%2C%20ok%2C%20_%20in%20results%5D.count(True)%0A%20%20%20%20print(f%22%5Cn%7Bpassed%7D%20of%20%7Blen(results)%7D%20checks%20passed%22)%0A%0A%0Adef%20main()%3A%0A%20%20%20%20run%20%3D%20subprocess.run(%5Bsys.executable%2C%20%22badge.py%22%5D%2C%20input%3DNAME%2C%20text%3DTrue%2C%20capture_output%3DTrue)%0A%20%20%20%20crashed%20%3D%20run.returncode%20!%3D%200%0A%20%20%20%20last_error%20%3D%20run.stderr.strip().splitlines()%5B-1%5D%20if%20run.stderr.strip()%20else%20%22%22%0A%0A%20%20%20%20results%20%3D%20%5B(%22the%20script%20runs%20without%20crashing%22%2C%20not%20crashed%2C%20last_error)%5D%0A%20%20%20%20if%20crashed%3A%0A%20%20%20%20%20%20%20%20report(results)%0A%20%20%20%20%20%20%20%20return%201%0A%0A%20%20%20%20lines%20%3D%20%5Bline.strip()%20for%20line%20in%20run.stdout.splitlines()%20if%20line.strip()%5D%0A%20%20%20%20results.append((%22prints%20three%20lines%22%2C%20len(lines)%20%3D%3D%203%2C%20f%22got%20%7Blen(lines)%7D%3A%20%7Blines%7D%22))%0A%0A%20%20%20%20for%20index%2C%20expected%20in%20enumerate(EXPECTED)%3A%0A%20%20%20%20%20%20%20%20got%20%3D%20lines%5Bindex%5D%20if%20index%20%3C%20len(lines)%20else%20%22nothing%22%0A%20%20%20%20%20%20%20%20results.append((f%22line%20%7Bindex%20%2B%201%7D%20is%20%7Bexpected!r%7D%22%2C%20got%20%3D%3D%20expected%2C%20repr(got)))%0A%0A%20%20%20%20report(results)%0A%20%20%20%20return%200%20if%20all(ok%20for%20_%2C%20ok%2C%20_%20in%20results)%20else%201%0A%0A%0Aif%20__name__%20%3D%3D%20%22__main__%22%3A%0A%20%20%20%20sys.exit(main())\" title=\"Salin kode\">\n      \u003Csvg class=\"w-3.5 h-3.5 copy-icon-svg\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n        \u003Cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\">\u003C\u002Fpath>\n      \u003C\u002Fsvg>\n      \u003Cspan class=\"copy-text\">Copy\u003C\u002Fspan>\n    \u003C\u002Fbutton>\n  \u003C\u002Fdiv>\n  \u003Cdiv class=\"code-block-content p-4 overflow-x-auto text-sm font-mono leading-relaxed bg-[#24292e]\">\n    \u003Cpre class=\"shiki github-dark\" style=\"background-color:#24292e;color:#e1e4e8\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\"># check_badge.py\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">import\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> subprocess\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">import\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> sys\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">NAME\u003C\u002Fspan>\u003Cspan style=\"color:#F97583\"> =\u003C\u002Fspan>\u003Cspan style=\"color:#9ECBFF\"> \"  alexander hamilton  \"\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">EXPECTED\u003C\u002Fspan>\u003Cspan style=\"color:#F97583\"> =\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> [\u003C\u002Fspan>\u003Cspan style=\"color:#9ECBFF\">\"Alexander\"\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">, \u003C\u002Fspan>\u003Cspan style=\"color:#9ECBFF\">\"Hamilton\"\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">, \u003C\u002Fspan>\u003Cspan style=\"color:#9ECBFF\">\"A. H.\"\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">]\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">def\u003C\u002Fspan>\u003Cspan style=\"color:#B392F0\"> report\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">(results):\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">    for\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> label, passed, detail \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">in\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> results:\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">        mark \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">=\u003C\u002Fspan>\u003Cspan style=\"color:#9ECBFF\"> \"PASS\"\u003C\u002Fspan>\u003Cspan style=\"color:#F97583\"> if\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> passed \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">else\u003C\u002Fspan>\u003Cspan style=\"color:#9ECBFF\"> \"FAIL\"\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">        note \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">=\u003C\u002Fspan>\u003Cspan style=\"color:#F97583\"> f\u003C\u002Fspan>\u003Cspan style=\"color:#9ECBFF\">\"  &#x3C;- \u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\">{\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">detail\u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\">}\u003C\u002Fspan>\u003Cspan style=\"color:#9ECBFF\">\"\u003C\u002Fspan>\u003Cspan style=\"color:#F97583\"> if\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> detail \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">and\u003C\u002Fspan>\u003Cspan style=\"color:#F97583\"> not\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> passed \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">else\u003C\u002Fspan>\u003Cspan style=\"color:#9ECBFF\"> \"\"\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">        print\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">(\u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">f\u003C\u002Fspan>\u003Cspan style=\"color:#9ECBFF\">\"\u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\">{\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">mark\u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\">}\u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\">  {\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">label\u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\">}{\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">note\u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\">}\u003C\u002Fspan>\u003Cspan style=\"color:#9ECBFF\">\"\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    passed \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">=\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> [ok \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">for\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> _, ok, _ \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">in\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> results].count(\u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\">True\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">    print\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">(\u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">f\u003C\u002Fspan>\u003Cspan style=\"color:#9ECBFF\">\"\u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\">\\n{\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">passed\u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\">}\u003C\u002Fspan>\u003Cspan style=\"color:#9ECBFF\"> of \u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\">{len\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">(results)\u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\">}\u003C\u002Fspan>\u003Cspan style=\"color:#9ECBFF\"> checks passed\"\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">def\u003C\u002Fspan>\u003Cspan style=\"color:#B392F0\"> main\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">():\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    run \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">=\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> subprocess.run([sys.executable, \u003C\u002Fspan>\u003Cspan style=\"color:#9ECBFF\">\"badge.py\"\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">], \u003C\u002Fspan>\u003Cspan style=\"color:#FFAB70\">input\u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">=\u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\">NAME\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">, \u003C\u002Fspan>\u003Cspan style=\"color:#FFAB70\">text\u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">=\u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\">True\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">, \u003C\u002Fspan>\u003Cspan style=\"color:#FFAB70\">capture_output\u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">=\u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\">True\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    crashed \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">=\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> run.returncode \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">!=\u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\"> 0\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    last_error \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">=\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> run.stderr.strip().splitlines()[\u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">-\u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\">1\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">] \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">if\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> run.stderr.strip() \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">else\u003C\u002Fspan>\u003Cspan style=\"color:#9ECBFF\"> \"\"\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    results \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">=\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> [(\u003C\u002Fspan>\u003Cspan style=\"color:#9ECBFF\">\"the script runs without crashing\"\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">, \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">not\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> crashed, last_error)]\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">    if\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> crashed:\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">        report(results)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">        return\u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\"> 1\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    lines \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">=\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> [line.strip() \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">for\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> line \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">in\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> run.stdout.splitlines() \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">if\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> line.strip()]\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    results.append((\u003C\u002Fspan>\u003Cspan style=\"color:#9ECBFF\">\"prints three lines\"\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">, \u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\">len\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">(lines) \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">==\u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\"> 3\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">, \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">f\u003C\u002Fspan>\u003Cspan style=\"color:#9ECBFF\">\"got \u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\">{len\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">(lines)\u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\">}\u003C\u002Fspan>\u003Cspan style=\"color:#9ECBFF\">: \u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\">{\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">lines\u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\">}\u003C\u002Fspan>\u003Cspan style=\"color:#9ECBFF\">\"\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">))\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">    for\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> index, expected \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">in\u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\"> enumerate\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">(\u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\">EXPECTED\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">):\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">        got \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">=\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> lines[index] \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">if\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> index \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">&#x3C;\u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\"> len\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">(lines) \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">else\u003C\u002Fspan>\u003Cspan style=\"color:#9ECBFF\"> \"nothing\"\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">        results.append((\u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">f\u003C\u002Fspan>\u003Cspan style=\"color:#9ECBFF\">\"line \u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\">{\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">index \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">+\u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\"> 1}\u003C\u002Fspan>\u003Cspan style=\"color:#9ECBFF\"> is \u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\">{\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">expected\u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">!r\u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\">}\u003C\u002Fspan>\u003Cspan style=\"color:#9ECBFF\">\"\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">, got \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">==\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> expected, \u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\">repr\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">(got)))\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    report(results)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">    return\u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\"> 0\u003C\u002Fspan>\u003Cspan style=\"color:#F97583\"> if\u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\"> all\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">(ok \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">for\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> _, ok, _ \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">in\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> results) \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">else\u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\"> 1\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">if\u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\"> __name__\u003C\u002Fspan>\u003Cspan style=\"color:#F97583\"> ==\u003C\u002Fspan>\u003Cspan style=\"color:#9ECBFF\"> \"__main__\"\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">:\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    sys.exit(main())\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\n  \u003C\u002Fdiv>\n\u003C\u002Fdiv>\n\u003Cdiv class=\"code-block-wrapper my-6 not-prose rounded-xl border-2 border-black dark:border-gray-600 shadow-neo overflow-hidden bg-[#24292e] text-[#e1e4e8] transition-all\">\n  \u003Cdiv class=\"code-block-header flex items-center justify-between px-4 py-2.5 bg-[#1f2428] border-b-2 border-black dark:border-gray-600 font-mono text-xs font-bold text-gray-300 select-none\">\n    \u003Cdiv class=\"flex items-center gap-2\">\n      \u003Cspan class=\"w-3 h-3 rounded-full bg-[#ff5f56] border border-black\u002F40 inline-block\">\u003C\u002Fspan>\n      \u003Cspan class=\"w-3 h-3 rounded-full bg-[#ffbd2e] border border-black\u002F40 inline-block\">\u003C\u002Fspan>\n      \u003Cspan class=\"w-3 h-3 rounded-full bg-[#27c93f] border border-black\u002F40 inline-block\">\u003C\u002Fspan>\n      \u003Cspan class=\"ml-2 font-mono font-bold text-xs uppercase tracking-wider text-gray-300\">TEXT\u003C\u002Fspan>\n    \u003C\u002Fdiv>\n    \u003Cbutton type=\"button\" class=\"copy-code-btn flex items-center gap-1.5 px-3 py-1 text-xs font-bold bg-[#2f363d] text-gray-200 border-2 border-black dark:border-gray-500 rounded-lg shadow-neo-sm hover:translate-x-0.5 hover:translate-y-0.5 hover:shadow-none hover:bg-gray-700 transition-all cursor-pointer\" data-code=\"%24%20python3%20check_badge.py%0APASS%20%20the%20script%20runs%20without%20crashing%0APASS%20%20prints%20three%20lines%0AFAIL%20%20line%201%20is%20'Alexander'%20%20%3C-%20'Alexa'%0AFAIL%20%20line%202%20is%20'Hamilton'%20%20%3C-%20'Der%20Hamilton'%0AFAIL%20%20line%203%20is%20'A.%20H.'%20%20%3C-%20'A.%20D.'%0A%0A2%20of%205%20checks%20passed\" title=\"Salin kode\">\n      \u003Csvg class=\"w-3.5 h-3.5 copy-icon-svg\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n        \u003Cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\">\u003C\u002Fpath>\n      \u003C\u002Fsvg>\n      \u003Cspan class=\"copy-text\">Copy\u003C\u002Fspan>\n    \u003C\u002Fbutton>\n  \u003C\u002Fdiv>\n  \u003Cdiv class=\"code-block-content p-4 overflow-x-auto text-sm font-mono leading-relaxed bg-[#24292e]\">\n    \u003Cpre class=\"shiki github-dark\" style=\"background-color:#24292e;color:#e1e4e8\">\u003Ccode>$ python3 check_badge.py\nPASS  the script runs without crashing\nPASS  prints three lines\nFAIL  line 1 is 'Alexander'  &lt;- 'Alexa'\nFAIL  line 2 is 'Hamilton'  &lt;- 'Der Hamilton'\nFAIL  line 3 is 'A. H.'  &lt;- 'A. D.'\n\n2 of 5 checks passed\u003C\u002Fcode>\u003C\u002Fpre>\n  \u003C\u002Fdiv>\n\u003C\u002Fdiv>\u003Cp>Feed it \u003Ccode>daffa izzuddin\u003C\u002Fcode> instead and all three lines are correct. That is the whole problem: the script is not broken, it is fitted to one piece of data.\u003C\u002Fp>\n\u003Ch2 id=\"a-slice-counts-characters-not-words\">A slice counts characters, not words\u003C\u002Fh2>\n\u003Cp>Square brackets address positions. \u003Ccode>raw[0]\u003C\u002Fcode> is the first character, \u003Ccode>raw[-1]\u003C\u002Fcode> is the last, \u003Ccode>raw[1:4]\u003C\u002Fcode> is positions 1, 2 and 3 (the end is excluded), and \u003Ccode>raw[3:]\u003C\u002Fcode> runs to the end of the string. That is all a slice is: a range of positions.\u003C\u002Fp>\n\u003Cp>So \u003Ccode>raw[0:5]\u003C\u002Fcode> asks for five characters from the left. When the name was \u003Ccode>daffa izzuddin\u003C\u002Fcode>, five characters happened to be \u003Ccode>daffa\u003C\u002Fcode>, the first name, and \u003Ccode>raw[6:]\u003C\u002Fcode> happened to start right after the space. Both numbers were correct once, for one name, and never again.\u003C\u002Fp>\n\u003Cp>Nothing in the expression says &quot;first name&quot;. A slice cannot tell a word from a coincidence, and it will not warn you when the data changes shape. That is not a flaw in slicing; it is slicing doing exactly what it was asked.\u003C\u002Fp>\n\u003Ch2 id=\"the-methods-that-know-about-words\">The methods that know about words\u003C\u002Fh2>\n\u003Cp>Strings come with methods that already understand the structure you are after, and they are usually shorter than the slice you were about to write. \u003Ccode>.split()\u003C\u002Fcode> with no argument cuts on any run of spaces, tabs or newlines, and it drops the runs entirely, which is why the padding around the input never reaches the output. \u003Ccode>.strip()\u003C\u002Fcode> removes whitespace at the two ends. \u003Ccode>.title()\u003C\u002Fcode> capitalises each word, \u003Ccode>.upper()\u003C\u002Fcode> and \u003Ccode>.lower()\u003C\u002Fcode> change case, \u003Ccode>.replace(&quot;a&quot;, &quot;b&quot;)\u003C\u002Fcode> swaps text, \u003Ccode>.startswith()\u003C\u002Fcode> and \u003Ccode>.endswith()\u003C\u002Fcode> answer about the edges, and \u003Ccode>&quot; &quot;.join(words)\u003C\u002Fcode> is the reverse of \u003Ccode>split\u003C\u002Fcode>.\u003C\u002Fp>\n\u003Cp>The rule that keeps this simple: \u003Cstrong>if the question is &quot;which word&quot;, split. If the question is &quot;which character&quot;, slice.\u003C\u002Fstrong> Nine times out of ten you were asking the first one.\u003C\u002Fp>\n\u003Ch2 id=\"a-method-does-not-change-the-string\">A method does not change the string\u003C\u002Fh2>\n\u003Cp>This one costs everybody an afternoon. Strings cannot be modified in place:\u003C\u002Fp>\n\n\u003Cdiv class=\"code-block-wrapper my-6 not-prose rounded-xl border-2 border-black dark:border-gray-600 shadow-neo overflow-hidden bg-[#24292e] text-[#e1e4e8] transition-all\">\n  \u003Cdiv class=\"code-block-header flex items-center justify-between px-4 py-2.5 bg-[#1f2428] border-b-2 border-black dark:border-gray-600 font-mono text-xs font-bold text-gray-300 select-none\">\n    \u003Cdiv class=\"flex items-center gap-2\">\n      \u003Cspan class=\"w-3 h-3 rounded-full bg-[#ff5f56] border border-black\u002F40 inline-block\">\u003C\u002Fspan>\n      \u003Cspan class=\"w-3 h-3 rounded-full bg-[#ffbd2e] border border-black\u002F40 inline-block\">\u003C\u002Fspan>\n      \u003Cspan class=\"w-3 h-3 rounded-full bg-[#27c93f] border border-black\u002F40 inline-block\">\u003C\u002Fspan>\n      \u003Cspan class=\"ml-2 font-mono font-bold text-xs uppercase tracking-wider text-gray-300\">PYTHON\u003C\u002Fspan>\n    \u003C\u002Fdiv>\n    \u003Cbutton type=\"button\" class=\"copy-code-btn flex items-center gap-1.5 px-3 py-1 text-xs font-bold bg-[#2f363d] text-gray-200 border-2 border-black dark:border-gray-500 rounded-lg shadow-neo-sm hover:translate-x-0.5 hover:translate-y-0.5 hover:shadow-none hover:bg-gray-700 transition-all cursor-pointer\" data-code=\"name%20%3D%20%22daffa%22%0Aname.upper()%0Aprint(name)\" title=\"Salin kode\">\n      \u003Csvg class=\"w-3.5 h-3.5 copy-icon-svg\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n        \u003Cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\">\u003C\u002Fpath>\n      \u003C\u002Fsvg>\n      \u003Cspan class=\"copy-text\">Copy\u003C\u002Fspan>\n    \u003C\u002Fbutton>\n  \u003C\u002Fdiv>\n  \u003Cdiv class=\"code-block-content p-4 overflow-x-auto text-sm font-mono leading-relaxed bg-[#24292e]\">\n    \u003Cpre class=\"shiki github-dark\" style=\"background-color:#24292e;color:#e1e4e8\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">name \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">=\u003C\u002Fspan>\u003Cspan style=\"color:#9ECBFF\"> \"daffa\"\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">name.upper()\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">print\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">(name)\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\n  \u003C\u002Fdiv>\n\u003C\u002Fdiv>\n\u003Cdiv class=\"code-block-wrapper my-6 not-prose rounded-xl border-2 border-black dark:border-gray-600 shadow-neo overflow-hidden bg-[#24292e] text-[#e1e4e8] transition-all\">\n  \u003Cdiv class=\"code-block-header flex items-center justify-between px-4 py-2.5 bg-[#1f2428] border-b-2 border-black dark:border-gray-600 font-mono text-xs font-bold text-gray-300 select-none\">\n    \u003Cdiv class=\"flex items-center gap-2\">\n      \u003Cspan class=\"w-3 h-3 rounded-full bg-[#ff5f56] border border-black\u002F40 inline-block\">\u003C\u002Fspan>\n      \u003Cspan class=\"w-3 h-3 rounded-full bg-[#ffbd2e] border border-black\u002F40 inline-block\">\u003C\u002Fspan>\n      \u003Cspan class=\"w-3 h-3 rounded-full bg-[#27c93f] border border-black\u002F40 inline-block\">\u003C\u002Fspan>\n      \u003Cspan class=\"ml-2 font-mono font-bold text-xs uppercase tracking-wider text-gray-300\">TEXT\u003C\u002Fspan>\n    \u003C\u002Fdiv>\n    \u003Cbutton type=\"button\" class=\"copy-code-btn flex items-center gap-1.5 px-3 py-1 text-xs font-bold bg-[#2f363d] text-gray-200 border-2 border-black dark:border-gray-500 rounded-lg shadow-neo-sm hover:translate-x-0.5 hover:translate-y-0.5 hover:shadow-none hover:bg-gray-700 transition-all cursor-pointer\" data-code=\"daffa\" title=\"Salin kode\">\n      \u003Csvg class=\"w-3.5 h-3.5 copy-icon-svg\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n        \u003Cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\">\u003C\u002Fpath>\n      \u003C\u002Fsvg>\n      \u003Cspan class=\"copy-text\">Copy\u003C\u002Fspan>\n    \u003C\u002Fbutton>\n  \u003C\u002Fdiv>\n  \u003Cdiv class=\"code-block-content p-4 overflow-x-auto text-sm font-mono leading-relaxed bg-[#24292e]\">\n    \u003Cpre class=\"shiki github-dark\" style=\"background-color:#24292e;color:#e1e4e8\">\u003Ccode>daffa\u003C\u002Fcode>\u003C\u002Fpre>\n  \u003C\u002Fdiv>\n\u003C\u002Fdiv>\u003Cp>\u003Ccode>.upper()\u003C\u002Fcode> returns a new string and leaves the old one alone. Nothing was assigned, so the result was dropped. \u003Ccode>.strip()\u003C\u002Fcode>, \u003Ccode>.title()\u003C\u002Fcode> and \u003Ccode>.replace()\u003C\u002Fcode> behave the same way. That is also why the reading line in the script starts with \u003Ccode>raw = sys.stdin.read().strip()\u003C\u002Fcode>: the assignment is doing the work, not the method.\u003C\u002Fp>\n\u003Ch2 id=\"the-fix\">The fix\u003C\u002Fh2>\n\n\u003Cdiv class=\"code-block-wrapper my-6 not-prose rounded-xl border-2 border-black dark:border-gray-600 shadow-neo overflow-hidden bg-[#24292e] text-[#e1e4e8] transition-all\">\n  \u003Cdiv class=\"code-block-header flex items-center justify-between px-4 py-2.5 bg-[#1f2428] border-b-2 border-black dark:border-gray-600 font-mono text-xs font-bold text-gray-300 select-none\">\n    \u003Cdiv class=\"flex items-center gap-2\">\n      \u003Cspan class=\"w-3 h-3 rounded-full bg-[#ff5f56] border border-black\u002F40 inline-block\">\u003C\u002Fspan>\n      \u003Cspan class=\"w-3 h-3 rounded-full bg-[#ffbd2e] border border-black\u002F40 inline-block\">\u003C\u002Fspan>\n      \u003Cspan class=\"w-3 h-3 rounded-full bg-[#27c93f] border border-black\u002F40 inline-block\">\u003C\u002Fspan>\n      \u003Cspan class=\"ml-2 font-mono font-bold text-xs uppercase tracking-wider text-gray-300\">PYTHON\u003C\u002Fspan>\n    \u003C\u002Fdiv>\n    \u003Cbutton type=\"button\" class=\"copy-code-btn flex items-center gap-1.5 px-3 py-1 text-xs font-bold bg-[#2f363d] text-gray-200 border-2 border-black dark:border-gray-500 rounded-lg shadow-neo-sm hover:translate-x-0.5 hover:translate-y-0.5 hover:shadow-none hover:bg-gray-700 transition-all cursor-pointer\" data-code=\"%23%20badge.py%0Aimport%20sys%0A%0Aname%20%3D%20sys.stdin.read().strip()%0Aparts%20%3D%20name.split()%0A%0Afirst%20%3D%20parts%5B0%5D.title()%0Alast%20%3D%20parts%5B-1%5D.title()%0A%0Aprint(first)%0Aprint(last)%0Aprint(f%22%7Bfirst%5B0%5D%7D.%20%7Blast%5B0%5D%7D.%22)\" title=\"Salin kode\">\n      \u003Csvg class=\"w-3.5 h-3.5 copy-icon-svg\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n        \u003Cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\">\u003C\u002Fpath>\n      \u003C\u002Fsvg>\n      \u003Cspan class=\"copy-text\">Copy\u003C\u002Fspan>\n    \u003C\u002Fbutton>\n  \u003C\u002Fdiv>\n  \u003Cdiv class=\"code-block-content p-4 overflow-x-auto text-sm font-mono leading-relaxed bg-[#24292e]\">\n    \u003Cpre class=\"shiki github-dark\" style=\"background-color:#24292e;color:#e1e4e8\" tabindex=\"0\">\u003Ccode>\u003Cspan class=\"line\">\u003Cspan style=\"color:#6A737D\"># badge.py\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">import\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> sys\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">name \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">=\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> sys.stdin.read().strip()\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">parts \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">=\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> name.split()\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">first \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">=\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> parts[\u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\">0\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">].title()\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">last \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">=\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> parts[\u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">-\u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\">1\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">].title()\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">print\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">(first)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">print\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">(last)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">print\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">(\u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">f\u003C\u002Fspan>\u003Cspan style=\"color:#9ECBFF\">\"\u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\">{\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">first[\u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\">0\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">]\u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\">}\u003C\u002Fspan>\u003Cspan style=\"color:#9ECBFF\">. \u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\">{\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">last[\u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\">0\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">]\u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\">}\u003C\u002Fspan>\u003Cspan style=\"color:#9ECBFF\">.\"\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">)\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\n  \u003C\u002Fdiv>\n\u003C\u002Fdiv>\n\u003Cdiv class=\"code-block-wrapper my-6 not-prose rounded-xl border-2 border-black dark:border-gray-600 shadow-neo overflow-hidden bg-[#24292e] text-[#e1e4e8] transition-all\">\n  \u003Cdiv class=\"code-block-header flex items-center justify-between px-4 py-2.5 bg-[#1f2428] border-b-2 border-black dark:border-gray-600 font-mono text-xs font-bold text-gray-300 select-none\">\n    \u003Cdiv class=\"flex items-center gap-2\">\n      \u003Cspan class=\"w-3 h-3 rounded-full bg-[#ff5f56] border border-black\u002F40 inline-block\">\u003C\u002Fspan>\n      \u003Cspan class=\"w-3 h-3 rounded-full bg-[#ffbd2e] border border-black\u002F40 inline-block\">\u003C\u002Fspan>\n      \u003Cspan class=\"w-3 h-3 rounded-full bg-[#27c93f] border border-black\u002F40 inline-block\">\u003C\u002Fspan>\n      \u003Cspan class=\"ml-2 font-mono font-bold text-xs uppercase tracking-wider text-gray-300\">TEXT\u003C\u002Fspan>\n    \u003C\u002Fdiv>\n    \u003Cbutton type=\"button\" class=\"copy-code-btn flex items-center gap-1.5 px-3 py-1 text-xs font-bold bg-[#2f363d] text-gray-200 border-2 border-black dark:border-gray-500 rounded-lg shadow-neo-sm hover:translate-x-0.5 hover:translate-y-0.5 hover:shadow-none hover:bg-gray-700 transition-all cursor-pointer\" data-code=\"%24%20python3%20check_badge.py%0APASS%20%20the%20script%20runs%20without%20crashing%0APASS%20%20prints%20three%20lines%0APASS%20%20line%201%20is%20'Alexander'%0APASS%20%20line%202%20is%20'Hamilton'%0APASS%20%20line%203%20is%20'A.%20H.'%0A%0A5%20of%205%20checks%20passed\" title=\"Salin kode\">\n      \u003Csvg class=\"w-3.5 h-3.5 copy-icon-svg\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n        \u003Cpath stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z\">\u003C\u002Fpath>\n      \u003C\u002Fsvg>\n      \u003Cspan class=\"copy-text\">Copy\u003C\u002Fspan>\n    \u003C\u002Fbutton>\n  \u003C\u002Fdiv>\n  \u003Cdiv class=\"code-block-content p-4 overflow-x-auto text-sm font-mono leading-relaxed bg-[#24292e]\">\n    \u003Cpre class=\"shiki github-dark\" style=\"background-color:#24292e;color:#e1e4e8\">\u003Ccode>$ python3 check_badge.py\nPASS  the script runs without crashing\nPASS  prints three lines\nPASS  line 1 is 'Alexander'\nPASS  line 2 is 'Hamilton'\nPASS  line 3 is 'A. H.'\n\n5 of 5 checks passed\u003C\u002Fcode>\u003C\u002Fpre>\n  \u003C\u002Fdiv>\n\u003C\u002Fdiv>\u003Cp>\u003Ccode>split()\u003C\u002Fcode> returns a list of words of whatever length the name happens to be. \u003Ccode>parts[0]\u003C\u002Fcode> is the first word and \u003Ccode>parts[-1]\u003C\u002Fcode> is the last one, and both of those are true for any number of words, which is the property the hardcoded slice was pretending to have.\u003C\u002Fp>\n\u003Ch2 id=\"when-a-slice-is-the-right-tool\">When a slice is the right tool\u003C\u002Fh2>\n\u003Cp>Slicing is not the villain. It is the right tool when the position itself carries the meaning: the first letter of a word, the last segment of a file name, the first four digits of a year, a fixed-width code from a form. Notice that \u003Ccode>first[0]\u003C\u002Fcode> survives in the fixed version, because &quot;the first character of this word&quot; is true regardless of how long the word is.\u003C\u002Fp>\n\u003Cp>The useful test is whether the number would still be correct if the data doubled in size. \u003Ccode>first[0]\u003C\u002Fcode> would. \u003Ccode>raw[0:5]\u003C\u002Fcode> would not.\u003C\u002Fp>\n\u003Ch2 id=\"before-the-next-article\">Before the next article\u003C\u002Fh2>\n\u003Cp>Give it a single-word name. It does not crash, does not warn, and prints \u003Ccode>Cher\u003C\u002Fcode>, \u003Ccode>Cher\u003C\u002Fcode>, \u003Ccode>C. C.\u003C\u002Fcode> — a badge nobody would accept, produced silently. Then try \u003Ccode>first, last = name.split()\u003C\u002Fcode> instead of the two indexed lines: with a middle name it raises \u003Ccode>ValueError: too many values to unpack (expected 2, got 3)\u003C\u002Fcode>.\u003C\u002Fp>\n\u003Cp>Two failures with nothing in common except that the checker only knows what you told it to expect. Deciding what a one-word badge \u003Cem>should\u003C\u002Fem> say is your job; the checker can only hold you to your own answer.\u003C\u002Fp>\n","\u003Cul>\n\u003Cli>\u003Ccode>raw[0:5]\u003C\u002Fcode> means five characters from the left, not the first word — slices never check what they cut.\u003C\u002Fli>\n\u003Cli>\u003Ccode>.split()\u003C\u002Fcode> with no argument splits on any run of whitespace and handles the padding, which is why \u003Ccode>.strip()\u003C\u002Fcode> is less necessary than it looks.\u003C\u002Fli>\n\u003Cli>A string method returns a new string: \u003Ccode>s.upper()\u003C\u002Fcode> on its own changes nothing until you assign it.\u003C\u002Fli>\n\u003Cli>Slice when the position is the point, split when the word is the point, and use a method before writing either.\u003C\u002Fli>\n\u003Cli>\u003Ccode>s[0]\u003C\u002Fcode> and \u003Ccode>s[-1]\u003C\u002Fcode> are safe at any length; \u003Ccode>s[0:5]\u003C\u002Fcode> is a guess about the data.\u003C\u002Fli>\n\u003C\u002Ful>\n",[179,184,189,194,199,218],{"id":71,"title":72,"title_en":8,"slug":73,"excerpt":74,"excerpt_en":8,"has_translation":11,"published_at":75,"reading_time":76,"hidden_from_listing":11,"tags":77,"thumbnail_image":8,"og_image":80,"series":180,"authors":181},{"id":82,"title":83,"title_en":84,"slug":85},[182],{"authors_id":183},{"id":102,"name":103,"slug":104,"role":105,"profile_picture":8},{"id":120,"title":121,"title_en":8,"slug":122,"excerpt":123,"excerpt_en":8,"has_translation":11,"published_at":124,"reading_time":76,"hidden_from_listing":11,"tags":125,"thumbnail_image":8,"og_image":127,"series":185,"authors":186},{"id":82,"title":83,"title_en":84,"slug":85},[187],{"authors_id":188},{"id":102,"name":103,"slug":104,"role":105,"profile_picture":8},{"id":107,"title":108,"title_en":8,"slug":109,"excerpt":110,"excerpt_en":8,"has_translation":11,"published_at":111,"reading_time":76,"hidden_from_listing":11,"tags":112,"thumbnail_image":8,"og_image":114,"series":190,"authors":191},{"id":82,"title":83,"title_en":84,"slug":85},[192],{"authors_id":193},{"id":102,"name":103,"slug":104,"role":105,"profile_picture":8},{"id":90,"title":91,"title_en":8,"slug":92,"excerpt":93,"excerpt_en":8,"has_translation":11,"published_at":94,"reading_time":76,"hidden_from_listing":11,"tags":95,"thumbnail_image":8,"og_image":97,"series":195,"authors":196},{"id":82,"title":83,"title_en":84,"slug":85},[197],{"authors_id":198},{"id":102,"name":103,"slug":104,"role":105,"profile_picture":8},{"id":200,"title":201,"title_en":8,"slug":202,"excerpt":203,"excerpt_en":8,"has_translation":11,"published_at":204,"reading_time":13,"hidden_from_listing":11,"tags":205,"thumbnail_image":8,"og_image":212,"series":213,"authors":215},129,"Biar RAG nggak kena 504: pisahin jalur query dan ingestion","rag-pisah-jalur-query-dan-ingestion","Satu service RAG yang merangkap parsing dan menjawab kueri bakal tumbang pas ada yang upload PDF 200 halaman. Obatnya dua jalur dan satu queue.","2026-10-22T01:30:00.000Z",[206,207,208,209,210,211],"rag","cloud-run","cloud-tasks","gcp","serverless","arsitektur","\u002Fog\u002Frag-pisah-jalur-query-dan-ingestion.png",{"id":214,"title":32,"title_en":33,"slug":34},8,[216],{"authors_id":217},{"id":102,"name":103,"slug":104,"role":105,"profile_picture":8},{"id":219,"title":220,"title_en":8,"slug":221,"excerpt":222,"excerpt_en":8,"has_translation":11,"published_at":223,"reading_time":76,"hidden_from_listing":11,"tags":224,"thumbnail_image":8,"og_image":231,"series":232,"authors":233},128,"Linear atau graf: cara mengatur banyak agent tanpa loop abadi","multi-agen-linear-atau-grafik","Satu agent dengan dua puluh tool gampang kacau. Begitu beberapa agent saling revisi, kamu butuh graf yang mendukung cycle dan angka yang membuatnya berhenti.","2026-10-21T16:05:00.000Z",[225,226,227,228,229,230],"multi-agent","langgraph","autogen","orkestrasi","checkpoint","llm","\u002Fog\u002Fmulti-agen-linear-atau-grafik.png",{"id":214,"title":32,"title_en":33,"slug":34},[234],{"authors_id":235},{"id":102,"name":103,"slug":104,"role":105,"profile_picture":8},[237,241,244,247,250,253,256],{"text":238,"depth":239,"id":240},"Two files, one command",2,"two-files-one-command",{"text":242,"depth":239,"id":243},"A slice counts characters, not words","a-slice-counts-characters-not-words",{"text":245,"depth":239,"id":246},"The methods that know about words","the-methods-that-know-about-words",{"text":248,"depth":239,"id":249},"A method does not change the string","a-method-does-not-change-the-string",{"text":251,"depth":239,"id":252},"The fix","the-fix",{"text":254,"depth":239,"id":255},"When a slice is the right tool","when-a-slice-is-the-right-tool",{"text":257,"depth":239,"id":258},"Before the next article","before-the-next-article",1793248588196]