[{"data":1,"prerenderedAt":265},["ShallowReactive",2],{"tag-labels":3,"site-header":4,"article-python-class-object-id":72},{},{"featuredPost":5,"navigations":29},{"id":6,"title":7,"title_id":8,"slug":9,"excerpt":10,"excerpt_id":11,"has_translation":12,"published_at":13,"reading_time":14,"hidden_from_listing":15,"tags":16,"thumbnail_image":21,"og_image":22,"series":23,"authors":28},110,"When You Pick a Framework Just to Look Different","Ketika Pilih Framework Cuma Biar Kelihatan Beda","ketika-pilih-framework-cuma-biar-kelihatan-beda","The last time you chose a new framework or library, was it because your problem needed that tool, or because it sounded cool and few people around you were using it? That question is uncomfortable. Technology decisions are often made for reasons that never appear in any technical document.","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.",true,"2026-10-06T15:25:21.000Z",5,false,[17,18,19,20],"karier","framework","opini","pengalaman",null,"\u002Fog\u002Fketika-pilih-framework-cuma-biar-kelihatan-beda.png",{"id":24,"title":25,"title_id":26,"slug":27},9,"Articles","Artikel","all",[],[30,46,67],{"collection":31,"item":32},"series",{"__typename":31,"title":25,"title_id":26,"slug":27,"children_series":33},[34,38,42],{"title":35,"title_id":36,"slug":37},"Artificial Intelligence","Kecerdasan Artifisial","kecerdasan-artifisial",{"title":39,"title_id":40,"slug":41},"Programming Fundamentals","Konsep Dasar Pemrograman","konsep-dasar-pemrograman",{"title":43,"title_id":44,"slug":45},"Algorithms and Data Structures","Algoritma dan Struktur Data","algoritma-struktur-data",{"collection":31,"item":47},{"__typename":31,"title":48,"title_id":48,"slug":49,"children_series":50},"Tutorial","tutorial",[51,55,59,63],{"title":52,"title_id":53,"slug":54},"Learning Python","Belajar Python","belajar-python",{"title":56,"title_id":57,"slug":58},"Learning Go","Belajar Golang","belajar-golang",{"title":60,"title_id":61,"slug":62},"Learning Java","Belajar Java","belajar-java",{"title":64,"title_id":65,"slug":66},"Learning Pascal","Belajar Pascal","belajar-pascal",{"collection":31,"item":68},{"__typename":31,"title":69,"title_id":69,"slug":70,"children_series":71},"Lab","lab",[],{"article":73,"renderedBody":152,"renderedTakeaway":153,"latestArticles":154,"toc":254},{"id":74,"title":75,"title_id":75,"slug":76,"excerpt":77,"excerpt_id":77,"has_translation":12,"published_at":78,"reading_time":14,"hidden_from_listing":15,"tags":79,"thumbnail_image":21,"og_image":82,"series":83,"authors":144,"seoTitle":21,"seoDescription":21,"body_locale":147,"available_locales":148,"body":150,"takeway":151,"prerequisite":21},139,"Python Class: Riwayat yang Dipakai Bersama Semua Akun","python-class-object","Dua akun, dan riwayat masing-masing memuat setoran akun lain. List-nya duduk di body class, `append` tidak pernah menulis ke objek, jadi kedua akun menambah ke list yang sama.","2026-11-07T01:00:00.000Z",[80,81],"python","oop","\u002Fog\u002Fpython-class-object.png",{"id":84,"title":52,"title_id":53,"slug":54,"description":85,"description_id":21,"articles":86,"children_series":98,"parent_series":135},10,"Python from zero: the shape of the language, why it reads the way it does, and where it's the right tool.",[87],{"id":74,"title":88,"title_id":75,"slug":76,"excerpt":89,"excerpt_id":77,"has_translation":12,"published_at":78,"reading_time":14,"hidden_from_listing":15,"tags":79,"thumbnail_image":21,"og_image":82,"series":90,"authors":91},"Python Classes: the History Every Account Shared","Two accounts, and each history lists the other account's deposits. The list sat in the class body, `append` never writes to the object, so both accounts appended into the same one.",{"id":84,"title":52,"title_id":53,"slug":54},[92],{"authors_id":93},{"id":94,"name":95,"slug":96,"role":97,"profile_picture":21},1,"Daffa Izzuddin","izzudd","Writer",[99,105,111,117,123,129],{"id":100,"title":101,"title_id":102,"slug":103,"description":104,"cover_image":21},16,"Getting Started with Python","Berkenalan dengan Bahasa Python","python-intro","Your first step with Python: meet the language, install Python 3, poke around the interpreter, and get the syntax.",{"id":106,"title":107,"title_id":108,"slug":109,"description":110,"cover_image":21},17,"Variables, Types, and Operations","Variabel, Tipe Data, dan Operasi","python-variabel-tipe-data","Create variables, then meet the types one by one, from numbers and strings to booleans and the list that keeps tripping up beginners.",{"id":112,"title":113,"title_id":114,"slug":115,"description":116,"cover_image":21},18,"Working with Python Scripts","Menggunakan Script Python","python-pemrograman-dengan-script","Leave the interpreter and start writing real .py files, including how to take input and print output.",{"id":118,"title":119,"title_id":120,"slug":121,"description":122,"cover_image":21},19,"Control Structures","Struktur Kontrol","python-struktur-kontrol","Make a program decide things and repeat work: branching, loops, and list comprehension.",{"id":124,"title":125,"title_id":126,"slug":127,"description":128,"cover_image":21},20,"Functional Programming with Python","Pemrograman Fungsional dengan Python","python-pemrograman-fungsional","Wrap your code in functions so you stop writing the same thing twice. Parameters, return values, and default arguments.",{"id":130,"title":131,"title_id":132,"slug":133,"description":134,"cover_image":21},30,"Collections and Strings","Koleksi dan String","python-collections","Dictionaries, sets, tuples, and the string methods that do the boring parts. The types you need once a program stops holding a single value.",{"id":94,"title":48,"title_id":48,"slug":49,"parent_series":21,"children_series":136},[137,138,140,142],{"id":84,"title":52,"title_id":53,"slug":54,"cover_image":21},{"id":139,"title":56,"title_id":57,"slug":58,"cover_image":21},11,{"id":141,"title":60,"title_id":61,"slug":62,"cover_image":21},13,{"id":143,"title":64,"title_id":65,"slug":66,"cover_image":21},14,[145],{"authors_id":146},{"id":94,"name":95,"slug":96,"role":97,"profile_picture":21},"id",[149,147],"en","\nLaporan rekening bank yang kamu jalankan mencetak setoran Ani di dalam riwayat Budi. Saldonya benar dan tidak ada error yang muncul, jadi tidak ada yang menunjuk ke body class. Di situlah bug-nya: sebuah *class attribute* yang bisa diubah dan dipakai bersama semua akun.\n\nIni output dari skrip yang membuat `Account(\"Ani\", 100)` dan `Account(\"Budi\", 0)`, lalu memanggil `ani.deposit(50)` dan `budi.deposit(20)`:\n\n```text\nani.balance 150\nbudi.balance 20\nani.history ['Ani deposit 50', 'Budi deposit 20']\nbudi.history ['Ani deposit 50', 'Budi deposit 20']\nsame list: True\nAccount.history ['Ani deposit 50', 'Budi deposit 20']\nani.__dict__ {'owner': 'Ani', 'balance': 150}\n```\n\nBaca baris terakhir. `__dict__` milik Ani hanya berisi `owner` dan `balance`, tanpa `history`. Atribut itu tidak pernah dipasang di objeknya, jadi pencariannya menemukan list milik class.\n\nMembaca `self.history` mencari di objek dulu, baru di class. `self.history.append(x)` adalah pemanggilan method pada list hasil pencarian itu. Itu bukan assignment, jadi tidak ada yang ditulis ke objek. [Tutorial class di Python](https:\u002F\u002Fdocs.python.org\u002F3\u002Ftutorial\u002Fclasses.html) membahas urutan pencarian ini.\n\n## Dua berkas, satu perintah\n\nMulai dari versi yang rusak. List-nya duduk di body class, di atas `__init__`:\n\n```python\n# account.py\nclass Account:\n    history = []\n\n    def __init__(self, owner, balance=0):\n        self.owner = owner\n        self.balance = balance\n\n    def deposit(self, amount):\n        self.balance = self.balance + amount\n        self.history.append(f\"{self.owner} deposit {amount}\")\n```\n\nBerikutnya, sebuah checker. Skrip ini membuat dua akun, melakukan satu setoran di masing-masing, lalu mengajukan empat pertanyaan:\n\n```python\n# check_account.py\nimport account\n\npassed = 0\ntotal = 0\n\n\ndef check(name, ok, detail=\"\"):\n    global passed, total\n    total += 1\n    if ok:\n        passed += 1\n        print(f\"PASS  {name}\")\n    else:\n        print(f\"FAIL  {name}  \u003C- {detail}\")\n\n\nani = account.Account(\"Ani\", 100)\nbudi = account.Account(\"Budi\", 0)\n\nani.deposit(50)\nbudi.deposit(20)\n\ncheck(\"a deposit lands in the account that made it\", ani.balance == 150, f\"balance is {ani.balance}\")\ncheck(\"the other account's balance does not move\", budi.balance == 20, f\"balance is {budi.balance}\")\ncheck(\n    \"each account has one line of history\",\n    len(ani.history) == 1 and len(budi.history) == 1,\n    f\"ani has {len(ani.history)}, budi has {len(budi.history)}\",\n)\ncheck(\n    \"the two history lists are different lists\",\n    ani.history is not budi.history,\n    \"both accounts point at the same list\",\n)\n\nprint()\nprint(f\"{passed} of {total} checks passed\")\nraise SystemExit(0 if passed == total else 1)\n```\n\nJalankan `python3 check_account.py` dengan versi rusak di atas. Exit code-nya 1:\n\n```text\nPASS  a deposit lands in the account that made it\nPASS  the other account's balance does not move\nFAIL  each account has one line of history  \u003C- ani has 2, budi has 2\nFAIL  the two history lists are different lists  \u003C- both accounts point at the same list\n\n2 of 4 checks passed\n```\n\nDua pemeriksaan sudah lolos, dan itu jebakannya. `self.balance = ...` adalah assignment, dan assignment selalu menulis di objeknya, jadi setiap akun punya `balance` sendiri. `self.history.append(...)` tidak pernah melakukan assignment. Saldo adalah hal pertama yang biasanya kamu uji, dan saldonya kelihatan benar.\n\nSekarang pindahkan list-nya ke `__init__`, supaya setiap objek membuat list sendiri:\n\n```python\n# account.py\nclass Account:\n    def __init__(self, owner, balance=0):\n        self.owner = owner\n        self.balance = balance\n        self.history = []\n\n    def deposit(self, amount):\n        self.balance = self.balance + amount\n        self.history.append(f\"{self.owner} deposit {amount}\")\n```\n\nJalankan perintah yang sama lagi. Kali ini exit code-nya 0:\n\n```text\nPASS  a deposit lands in the account that made it\nPASS  the other account's balance does not move\nPASS  each account has one line of history\nPASS  the two history lists are different lists\n\n4 of 4 checks passed\n```\n\nSemua ini dijalankan di Python 3.14.9 di Linux. Versi Python lain belum dicoba, jadi ini bukti dari satu mesin.\n\n## Yang tidak dilakukan checker ini\n\nClass attribute tetap tempat yang benar untuk nilai yang tidak pernah diubah siapa pun. Checker tidak bisa membedakan konstanta bersama dari list bersama, dan memang tidak perlu. Berbagi bukan masalahnya; mengubah sesuatu yang dipakai bersama itulah masalahnya.\n\n`history` yang kosong juga bukan bukti bahwa kamu sudah memperbaikinya. Kedua versi memulai setiap akun dengan list kosong. Bug-nya baru muncul begitu objek kedua ada, dan itulah yang dibangun oleh checker.\n\n## Rusak dengan sengaja\n\nTaruh `history = []` kembali di body class. Lalu tambahkan satu baris di `__init__`:\n\n```python\nself.history = Account.history\n```\n\nKelihatannya setiap akun sekarang dapat list sendiri, tapi jalankan checker-nya dan dua pemeriksaan gagal lagi:\n\n```text\nPASS  a deposit lands in the account that made it\nPASS  the other account's balance does not move\nFAIL  each account has one line of history  \u003C- ani has 2, budi has 2\nFAIL  the two history lists are different lists  \u003C- both accounts point at the same list\n\n2 of 4 checks passed\n```\n\nBaris baru itu menyalin objek list yang sama ke kedua objek, jadi keduanya masih berbagi list itu.\n\nSebelum menaruh list, dict, atau set di body class, ajukan satu pertanyaan: apakah objek kedua seharusnya melihat perubahan ini? Kalau iya, bagikan dengan sengaja. Kalau tidak, buat di `__init__`.\n","- List yang dipasang di body class adalah milik class, jadi setiap objek membaca list yang sama sampai objek itu punya list sendiri.\n- `self.history.append(x)` membaca atribut class lalu mengubahnya; tidak ada atribut yang ditulis ke objek, itu sebabnya `history` tidak muncul di `ani.__dict__`.\n- `self.balance = ...` kelihatan benar karena assignment selalu menulis di objek yang memegang namanya.\n- Buat state yang bisa berubah di `__init__`, dan sisakan class attribute untuk nilai yang tidak boleh diubah objek mana pun.","\u003Cp>Laporan rekening bank yang kamu jalankan mencetak setoran Ani di dalam riwayat Budi. Saldonya benar dan tidak ada error yang muncul, jadi tidak ada yang menunjuk ke body class. Di situlah bug-nya: sebuah \u003Cem>class attribute\u003C\u002Fem> yang bisa diubah dan dipakai bersama semua akun.\u003C\u002Fp>\n\u003Cp>Ini output dari skrip yang membuat \u003Ccode>Account(&quot;Ani&quot;, 100)\u003C\u002Fcode> dan \u003Ccode>Account(&quot;Budi&quot;, 0)\u003C\u002Fcode>, lalu memanggil \u003Ccode>ani.deposit(50)\u003C\u002Fcode> dan \u003Ccode>budi.deposit(20)\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\">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=\"ani.balance%20150%0Abudi.balance%2020%0Aani.history%20%5B'Ani%20deposit%2050'%2C%20'Budi%20deposit%2020'%5D%0Abudi.history%20%5B'Ani%20deposit%2050'%2C%20'Budi%20deposit%2020'%5D%0Asame%20list%3A%20True%0AAccount.history%20%5B'Ani%20deposit%2050'%2C%20'Budi%20deposit%2020'%5D%0Aani.__dict__%20%7B'owner'%3A%20'Ani'%2C%20'balance'%3A%20150%7D\" 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>ani.balance 150\nbudi.balance 20\nani.history ['Ani deposit 50', 'Budi deposit 20']\nbudi.history ['Ani deposit 50', 'Budi deposit 20']\nsame list: True\nAccount.history ['Ani deposit 50', 'Budi deposit 20']\nani.__dict__ {'owner': 'Ani', 'balance': 150}\u003C\u002Fcode>\u003C\u002Fpre>\n  \u003C\u002Fdiv>\n\u003C\u002Fdiv>\u003Cp>Baca baris terakhir. \u003Ccode>__dict__\u003C\u002Fcode> milik Ani hanya berisi \u003Ccode>owner\u003C\u002Fcode> dan \u003Ccode>balance\u003C\u002Fcode>, tanpa \u003Ccode>history\u003C\u002Fcode>. Atribut itu tidak pernah dipasang di objeknya, jadi pencariannya menemukan list milik class.\u003C\u002Fp>\n\u003Cp>Membaca \u003Ccode>self.history\u003C\u002Fcode> mencari di objek dulu, baru di class. \u003Ccode>self.history.append(x)\u003C\u002Fcode> adalah pemanggilan method pada list hasil pencarian itu. Itu bukan assignment, jadi tidak ada yang ditulis ke objek. \u003Ca href=\"https:\u002F\u002Fdocs.python.org\u002F3\u002Ftutorial\u002Fclasses.html\">Tutorial class di Python\u003C\u002Fa> membahas urutan pencarian ini.\u003C\u002Fp>\n\u003Ch2 id=\"dua-berkas-satu-perintah\">Dua berkas, satu perintah\u003C\u002Fh2>\n\u003Cp>Mulai dari versi yang rusak. List-nya duduk di body class, di atas \u003Ccode>__init__\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%20account.py%0Aclass%20Account%3A%0A%20%20%20%20history%20%3D%20%5B%5D%0A%0A%20%20%20%20def%20__init__(self%2C%20owner%2C%20balance%3D0)%3A%0A%20%20%20%20%20%20%20%20self.owner%20%3D%20owner%0A%20%20%20%20%20%20%20%20self.balance%20%3D%20balance%0A%0A%20%20%20%20def%20deposit(self%2C%20amount)%3A%0A%20%20%20%20%20%20%20%20self.balance%20%3D%20self.balance%20%2B%20amount%0A%20%20%20%20%20%20%20%20self.history.append(f%22%7Bself.owner%7D%20deposit%20%7Bamount%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\"># account.py\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">class\u003C\u002Fspan>\u003Cspan style=\"color:#B392F0\"> Account\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">:\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    history \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">=\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> []\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">    def\u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\"> __init__\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">(self, owner, balance\u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">=\u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\">0\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">):\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">        self\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">.owner \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">=\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> owner\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">        self\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">.balance \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">=\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> balance\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">    def\u003C\u002Fspan>\u003Cspan style=\"color:#B392F0\"> deposit\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">(self, amount):\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">        self\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">.balance \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">=\u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\"> self\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">.balance \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">+\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> amount\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">        self\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">.history.append(\u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">f\u003C\u002Fspan>\u003Cspan style=\"color:#9ECBFF\">\"\u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\">{self\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">.owner\u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\">}\u003C\u002Fspan>\u003Cspan style=\"color:#9ECBFF\"> deposit \u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\">{\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">amount\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>Berikutnya, sebuah checker. Skrip ini membuat dua akun, melakukan satu setoran di masing-masing, lalu mengajukan empat pertanyaan:\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_account.py%0Aimport%20account%0A%0Apassed%20%3D%200%0Atotal%20%3D%200%0A%0A%0Adef%20check(name%2C%20ok%2C%20detail%3D%22%22)%3A%0A%20%20%20%20global%20passed%2C%20total%0A%20%20%20%20total%20%2B%3D%201%0A%20%20%20%20if%20ok%3A%0A%20%20%20%20%20%20%20%20passed%20%2B%3D%201%0A%20%20%20%20%20%20%20%20print(f%22PASS%20%20%7Bname%7D%22)%0A%20%20%20%20else%3A%0A%20%20%20%20%20%20%20%20print(f%22FAIL%20%20%7Bname%7D%20%20%3C-%20%7Bdetail%7D%22)%0A%0A%0Aani%20%3D%20account.Account(%22Ani%22%2C%20100)%0Abudi%20%3D%20account.Account(%22Budi%22%2C%200)%0A%0Aani.deposit(50)%0Abudi.deposit(20)%0A%0Acheck(%22a%20deposit%20lands%20in%20the%20account%20that%20made%20it%22%2C%20ani.balance%20%3D%3D%20150%2C%20f%22balance%20is%20%7Bani.balance%7D%22)%0Acheck(%22the%20other%20account's%20balance%20does%20not%20move%22%2C%20budi.balance%20%3D%3D%2020%2C%20f%22balance%20is%20%7Bbudi.balance%7D%22)%0Acheck(%0A%20%20%20%20%22each%20account%20has%20one%20line%20of%20history%22%2C%0A%20%20%20%20len(ani.history)%20%3D%3D%201%20and%20len(budi.history)%20%3D%3D%201%2C%0A%20%20%20%20f%22ani%20has%20%7Blen(ani.history)%7D%2C%20budi%20has%20%7Blen(budi.history)%7D%22%2C%0A)%0Acheck(%0A%20%20%20%20%22the%20two%20history%20lists%20are%20different%20lists%22%2C%0A%20%20%20%20ani.history%20is%20not%20budi.history%2C%0A%20%20%20%20%22both%20accounts%20point%20at%20the%20same%20list%22%2C%0A)%0A%0Aprint()%0Aprint(f%22%7Bpassed%7D%20of%20%7Btotal%7D%20checks%20passed%22)%0Araise%20SystemExit(0%20if%20passed%20%3D%3D%20total%20else%201)\" 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_account.py\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">import\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> account\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">passed \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\">total \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">=\u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\"> 0\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\"> check\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">(name, ok, detail\u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">=\u003C\u002Fspan>\u003Cspan style=\"color:#9ECBFF\">\"\"\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">):\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">    global\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> passed, total\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    total \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">+=\u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\"> 1\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">    if\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> ok:\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">        passed \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">+=\u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\"> 1\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\">\"PASS  \u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\">{\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">name\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:#F97583\">    else\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\">\"FAIL  \u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\">{\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">name\u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\">}\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:#E1E4E8\">)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">ani \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">=\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> account.Account(\u003C\u002Fspan>\u003Cspan style=\"color:#9ECBFF\">\"Ani\"\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">, \u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\">100\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">budi \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">=\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> account.Account(\u003C\u002Fspan>\u003Cspan style=\"color:#9ECBFF\">\"Budi\"\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">, \u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\">0\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">ani.deposit(\u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\">50\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">budi.deposit(\u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\">20\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">check(\u003C\u002Fspan>\u003Cspan style=\"color:#9ECBFF\">\"a deposit lands in the account that made it\"\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">, ani.balance \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">==\u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\"> 150\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">, \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">f\u003C\u002Fspan>\u003Cspan style=\"color:#9ECBFF\">\"balance is \u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\">{\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">ani.balance\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\">check(\u003C\u002Fspan>\u003Cspan style=\"color:#9ECBFF\">\"the other account's balance does not move\"\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">, budi.balance \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">==\u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\"> 20\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">, \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">f\u003C\u002Fspan>\u003Cspan style=\"color:#9ECBFF\">\"balance is \u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\">{\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">budi.balance\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\">check(\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#9ECBFF\">    \"each account has one line of history\"\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">    len\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">(ani.history) \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">==\u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\"> 1\u003C\u002Fspan>\u003Cspan style=\"color:#F97583\"> and\u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\"> len\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">(budi.history) \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">==\u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\"> 1\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">    f\u003C\u002Fspan>\u003Cspan style=\"color:#9ECBFF\">\"ani has \u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\">{len\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">(ani.history)\u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\">}\u003C\u002Fspan>\u003Cspan style=\"color:#9ECBFF\">, budi has \u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\">{len\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">(budi.history)\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\">)\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">check(\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#9ECBFF\">    \"the two history lists are different lists\"\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">    ani.history \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">is\u003C\u002Fspan>\u003Cspan style=\"color:#F97583\"> not\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> budi.history,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#9ECBFF\">    \"both accounts point at the same list\"\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">,\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#E1E4E8\">)\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\">()\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\">passed\u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\">}\u003C\u002Fspan>\u003Cspan style=\"color:#9ECBFF\"> of \u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\">{\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">total\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\">\u003Cspan style=\"color:#F97583\">raise\u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\"> SystemExit\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">(\u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\">0\u003C\u002Fspan>\u003Cspan style=\"color:#F97583\"> if\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> passed \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">==\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> total \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">else\u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\"> 1\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">)\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\n  \u003C\u002Fdiv>\n\u003C\u002Fdiv>\u003Cp>Jalankan \u003Ccode>python3 check_account.py\u003C\u002Fcode> dengan versi rusak di atas. Exit code-nya 1:\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\">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=\"PASS%20%20a%20deposit%20lands%20in%20the%20account%20that%20made%20it%0APASS%20%20the%20other%20account's%20balance%20does%20not%20move%0AFAIL%20%20each%20account%20has%20one%20line%20of%20history%20%20%3C-%20ani%20has%202%2C%20budi%20has%202%0AFAIL%20%20the%20two%20history%20lists%20are%20different%20lists%20%20%3C-%20both%20accounts%20point%20at%20the%20same%20list%0A%0A2%20of%204%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>PASS  a deposit lands in the account that made it\nPASS  the other account's balance does not move\nFAIL  each account has one line of history  &lt;- ani has 2, budi has 2\nFAIL  the two history lists are different lists  &lt;- both accounts point at the same list\n\n2 of 4 checks passed\u003C\u002Fcode>\u003C\u002Fpre>\n  \u003C\u002Fdiv>\n\u003C\u002Fdiv>\u003Cp>Dua pemeriksaan sudah lolos, dan itu jebakannya. \u003Ccode>self.balance = ...\u003C\u002Fcode> adalah assignment, dan assignment selalu menulis di objeknya, jadi setiap akun punya \u003Ccode>balance\u003C\u002Fcode> sendiri. \u003Ccode>self.history.append(...)\u003C\u002Fcode> tidak pernah melakukan assignment. Saldo adalah hal pertama yang biasanya kamu uji, dan saldonya kelihatan benar.\u003C\u002Fp>\n\u003Cp>Sekarang pindahkan list-nya ke \u003Ccode>__init__\u003C\u002Fcode>, supaya setiap objek membuat list sendiri:\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%20account.py%0Aclass%20Account%3A%0A%20%20%20%20def%20__init__(self%2C%20owner%2C%20balance%3D0)%3A%0A%20%20%20%20%20%20%20%20self.owner%20%3D%20owner%0A%20%20%20%20%20%20%20%20self.balance%20%3D%20balance%0A%20%20%20%20%20%20%20%20self.history%20%3D%20%5B%5D%0A%0A%20%20%20%20def%20deposit(self%2C%20amount)%3A%0A%20%20%20%20%20%20%20%20self.balance%20%3D%20self.balance%20%2B%20amount%0A%20%20%20%20%20%20%20%20self.history.append(f%22%7Bself.owner%7D%20deposit%20%7Bamount%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\"># account.py\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">class\u003C\u002Fspan>\u003Cspan style=\"color:#B392F0\"> Account\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">:\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">    def\u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\"> __init__\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">(self, owner, balance\u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">=\u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\">0\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">):\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">        self\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">.owner \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">=\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> owner\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">        self\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">.balance \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">=\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> balance\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">        self\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">.history \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">=\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> []\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#F97583\">    def\u003C\u002Fspan>\u003Cspan style=\"color:#B392F0\"> deposit\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">(self, amount):\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">        self\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">.balance \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">=\u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\"> self\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">.balance \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">+\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> amount\u003C\u002Fspan>\u003C\u002Fspan>\n\u003Cspan class=\"line\">\u003Cspan style=\"color:#79B8FF\">        self\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">.history.append(\u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">f\u003C\u002Fspan>\u003Cspan style=\"color:#9ECBFF\">\"\u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\">{self\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">.owner\u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\">}\u003C\u002Fspan>\u003Cspan style=\"color:#9ECBFF\"> deposit \u003C\u002Fspan>\u003Cspan style=\"color:#79B8FF\">{\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">amount\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>Jalankan perintah yang sama lagi. Kali ini exit code-nya 0:\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\">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=\"PASS%20%20a%20deposit%20lands%20in%20the%20account%20that%20made%20it%0APASS%20%20the%20other%20account's%20balance%20does%20not%20move%0APASS%20%20each%20account%20has%20one%20line%20of%20history%0APASS%20%20the%20two%20history%20lists%20are%20different%20lists%0A%0A4%20of%204%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>PASS  a deposit lands in the account that made it\nPASS  the other account's balance does not move\nPASS  each account has one line of history\nPASS  the two history lists are different lists\n\n4 of 4 checks passed\u003C\u002Fcode>\u003C\u002Fpre>\n  \u003C\u002Fdiv>\n\u003C\u002Fdiv>\u003Cp>Semua ini dijalankan di Python 3.14.9 di Linux. Versi Python lain belum dicoba, jadi ini bukti dari satu mesin.\u003C\u002Fp>\n\u003Ch2 id=\"yang-tidak-dilakukan-checker-ini\">Yang tidak dilakukan checker ini\u003C\u002Fh2>\n\u003Cp>Class attribute tetap tempat yang benar untuk nilai yang tidak pernah diubah siapa pun. Checker tidak bisa membedakan konstanta bersama dari list bersama, dan memang tidak perlu. Berbagi bukan masalahnya; mengubah sesuatu yang dipakai bersama itulah masalahnya.\u003C\u002Fp>\n\u003Cp>\u003Ccode>history\u003C\u002Fcode> yang kosong juga bukan bukti bahwa kamu sudah memperbaikinya. Kedua versi memulai setiap akun dengan list kosong. Bug-nya baru muncul begitu objek kedua ada, dan itulah yang dibangun oleh checker.\u003C\u002Fp>\n\u003Ch2 id=\"rusak-dengan-sengaja\">Rusak dengan sengaja\u003C\u002Fh2>\n\u003Cp>Taruh \u003Ccode>history = []\u003C\u002Fcode> kembali di body class. Lalu tambahkan satu baris di \u003Ccode>__init__\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=\"self.history%20%3D%20Account.history\" 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:#79B8FF\">self\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\">.history \u003C\u002Fspan>\u003Cspan style=\"color:#F97583\">=\u003C\u002Fspan>\u003Cspan style=\"color:#E1E4E8\"> Account.history\u003C\u002Fspan>\u003C\u002Fspan>\u003C\u002Fcode>\u003C\u002Fpre>\n  \u003C\u002Fdiv>\n\u003C\u002Fdiv>\u003Cp>Kelihatannya setiap akun sekarang dapat list sendiri, tapi jalankan checker-nya dan dua pemeriksaan gagal lagi:\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\">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=\"PASS%20%20a%20deposit%20lands%20in%20the%20account%20that%20made%20it%0APASS%20%20the%20other%20account's%20balance%20does%20not%20move%0AFAIL%20%20each%20account%20has%20one%20line%20of%20history%20%20%3C-%20ani%20has%202%2C%20budi%20has%202%0AFAIL%20%20the%20two%20history%20lists%20are%20different%20lists%20%20%3C-%20both%20accounts%20point%20at%20the%20same%20list%0A%0A2%20of%204%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>PASS  a deposit lands in the account that made it\nPASS  the other account's balance does not move\nFAIL  each account has one line of history  &lt;- ani has 2, budi has 2\nFAIL  the two history lists are different lists  &lt;- both accounts point at the same list\n\n2 of 4 checks passed\u003C\u002Fcode>\u003C\u002Fpre>\n  \u003C\u002Fdiv>\n\u003C\u002Fdiv>\u003Cp>Baris baru itu menyalin objek list yang sama ke kedua objek, jadi keduanya masih berbagi list itu.\u003C\u002Fp>\n\u003Cp>Sebelum menaruh list, dict, atau set di body class, ajukan satu pertanyaan: apakah objek kedua seharusnya melihat perubahan ini? Kalau iya, bagikan dengan sengaja. Kalau tidak, buat di \u003Ccode>__init__\u003C\u002Fcode>.\u003C\u002Fp>\n","\u003Cul>\n\u003Cli>List yang dipasang di body class adalah milik class, jadi setiap objek membaca list yang sama sampai objek itu punya list sendiri.\u003C\u002Fli>\n\u003Cli>\u003Ccode>self.history.append(x)\u003C\u002Fcode> membaca atribut class lalu mengubahnya; tidak ada atribut yang ditulis ke objek, itu sebabnya \u003Ccode>history\u003C\u002Fcode> tidak muncul di \u003Ccode>ani.__dict__\u003C\u002Fcode>.\u003C\u002Fli>\n\u003Cli>\u003Ccode>self.balance = ...\u003C\u002Fcode> kelihatan benar karena assignment selalu menulis di objek yang memegang namanya.\u003C\u002Fli>\n\u003Cli>Buat state yang bisa berubah di \u003Ccode>__init__\u003C\u002Fcode>, dan sisakan class attribute untuk nilai yang tidak boleh diubah objek mana pun.\u003C\u002Fli>\n\u003C\u002Ful>\n",[155,178,199,217,222,240],{"id":156,"title":157,"title_id":158,"slug":159,"excerpt":160,"excerpt_id":161,"has_translation":12,"published_at":162,"reading_time":163,"hidden_from_listing":15,"tags":164,"thumbnail_image":21,"og_image":169,"series":170,"authors":175},48,"What a Linked List Actually Is","Tentang Struktur Data LinkedList","tentang-struktur-data-linked-list","A linked list is a linear chain of nodes, each holding data and a pointer to the next node. Here is what that chain costs next to an array, plus a minimal implementation you can run.","Linked list adalah rantai linear berisi node, dan setiap node menyimpan data plus pointer ke node berikutnya. Ini ongkosnya dibanding array, plus implementasi paling sederhananya.","2026-11-21T01:00:00.000Z",3,[165,166,167,168],"struktur-data","linked-list","pointer","konsep","\u002Fog\u002Ftentang-struktur-data-linked-list.png",{"id":171,"title":172,"title_id":173,"slug":174},28,"Linear Data Structures","Struktur Data Linear","asd-struktur-linear",[176],{"authors_id":177},{"id":94,"name":95,"slug":96,"role":97,"profile_picture":21},{"id":179,"title":180,"title_id":181,"slug":182,"excerpt":183,"excerpt_id":184,"has_translation":12,"published_at":185,"reading_time":186,"hidden_from_listing":15,"tags":187,"thumbnail_image":21,"og_image":190,"series":191,"authors":196},47,"Why Understanding Algorithms and Data Structures Actually Matters","Pentingnya Memahami Algoritma dan Struktur Data","pentingnya-memahami-algoritma-dan-struktur-data","An algorithm is an ordered list of steps, and that order decides how expensive a problem is. The examples are on the back of an instant noodle packet, in a factorial, and behind ctrl+z.","Sebagai konsep fundamental, algoritma menentukan seberapa mahal sebuah masalah diselesaikan. Contohnya ada di bungkus mie instan, di bilangan faktorial, dan di tombol undo.","2026-11-19T01:00:00.000Z",7,[188,165,168,189],"algoritma","dasar","\u002Fog\u002Fpentingnya-memahami-algoritma-dan-struktur-data.png",{"id":192,"title":193,"title_id":194,"slug":195},27,"About Algorithms and Data Structures","Tentang Algoritma dan Struktur Data","asd-intro",[197],{"authors_id":198},{"id":94,"name":95,"slug":96,"role":97,"profile_picture":21},{"id":200,"title":201,"title_id":202,"slug":203,"excerpt":204,"excerpt_id":205,"has_translation":12,"published_at":206,"reading_time":14,"hidden_from_listing":15,"tags":207,"thumbnail_image":21,"og_image":212,"series":213,"authors":214},108,"At 11 a.m. the AI Quota Runs Out, and the Work Stops There","Jam 11 siang kuota AI-nya habis, dan kerjaan berhenti di situ","jam-11-kuota-ai-habis-kerjaan-berhenti","The panel says the usage limit is reached and the work stops, not because it is finished. Three guesses explain it, and all three are wrong: the limit is shaped like a cliff, and the day is built on top of one tool.","Panel di layar bilang batas pemakaian tercapai, dan kerja berhenti di situ. Bukan karena selesai. Ada tiga tebakan kenapa ini terjadi, dan ketiganya salah: batasnya berbentuk tebing, dan harinya dibangun di atas satu alat.","2026-11-12T01:00:00.000Z",[208,209,210,211],"ai","tooling","rate-limit","produktivitas","\u002Fog\u002Fjam-11-kuota-ai-habis-kerjaan-berhenti.png",{"id":24,"title":25,"title_id":26,"slug":27},[215],{"authors_id":216},{"id":94,"name":95,"slug":96,"role":97,"profile_picture":21},{"id":74,"title":88,"title_id":75,"slug":76,"excerpt":89,"excerpt_id":77,"has_translation":12,"published_at":78,"reading_time":14,"hidden_from_listing":15,"tags":79,"thumbnail_image":21,"og_image":82,"series":218,"authors":219},{"id":84,"title":52,"title_id":53,"slug":54},[220],{"authors_id":221},{"id":94,"name":95,"slug":96,"role":97,"profile_picture":21},{"id":223,"title":224,"title_id":225,"slug":226,"excerpt":227,"excerpt_id":228,"has_translation":12,"published_at":229,"reading_time":14,"hidden_from_listing":15,"tags":230,"thumbnail_image":21,"og_image":233,"series":234,"authors":237},137,"Java Operators: the Average That Came Out a Whole Number","Operator Java: Rata-Rata yang Keluar Sebagai Bilangan Bulat","java-operators","Three scores, one division, and the average prints as 82. Both operands are `int`, so the fraction is cut off, and the obvious cast prints `82.0` without fixing anything.","Tiga nilai, satu pembagian, dan rata-ratanya tercetak 82. Kedua operand-nya `int`, jadi pecahannya dipotong, dan cast yang paling wajar malah mencetak `82.0` tanpa memperbaiki apa pun.","2026-11-06T01:00:00.000Z",[231,232],"java","operator","\u002Fog\u002Fjava-operators.png",{"id":235,"title":107,"title_id":108,"slug":236},22,"java-variabel-tipe-data",[238],{"authors_id":239},{"id":94,"name":95,"slug":96,"role":97,"profile_picture":21},{"id":241,"title":242,"title_id":243,"slug":244,"excerpt":245,"excerpt_id":246,"has_translation":12,"published_at":229,"reading_time":186,"hidden_from_listing":15,"tags":247,"thumbnail_image":21,"og_image":249,"series":250,"authors":251},136,"Python Modules: the Import That Printed the Report","Modul Python: Import yang Mencetak Laporannya","python-modules","You pull one function out into its own file, import it, and the whole report runs again and eats your input. A module is a file, `import` runs it top to bottom, and one line decides which of the two jobs it is doing.","Kamu memindahkan satu fungsi ke file sendiri, meng-import-nya, dan seluruh laporan jalan lagi lalu memakan inputmu. Modul adalah file, `import` menjalankannya dari atas ke bawah, dan satu baris menentukan pekerjaan mana yang sedang dijalankan file itu.",[80,248],"modules","\u002Fog\u002Fpython-modules.png",{"id":112,"title":113,"title_id":114,"slug":115},[252],{"authors_id":253},{"id":94,"name":95,"slug":96,"role":97,"profile_picture":21},[255,259,262],{"text":256,"depth":257,"id":258},"Dua berkas, satu perintah",2,"dua-berkas-satu-perintah",{"text":260,"depth":257,"id":261},"Yang tidak dilakukan checker ini","yang-tidak-dilakukan-checker-ini",{"text":263,"depth":257,"id":264},"Rusak dengan sengaja","rusak-dengan-sengaja",1794029330851]