[{"data":1,"prerenderedAt":3664},["ShallowReactive",2],{"page-\u002Fpython\u002F04-control-flow":3},{"id":4,"title":5,"body":6,"description":36,"extension":3658,"meta":3659,"navigation":65,"path":3660,"seo":3661,"stem":3662,"__hash__":3663},"content\u002Fpython\u002F04-control-flow.md","04 — Control Flow",{"type":7,"value":8,"toc":3631},"minimark",[9,13,27,873,880,1004,1016,1144,1151,1167,1402,1409,1572,1579,1592,1617,1784,1797,2026,2038,2047,2070,2074,2262,2266,2600,2604,2903,2907,3134,3138,3245,3249,3364,3368,3371,3499,3553,3557,3627],[10,11,5],"h1",{"id":12},"_04-control-flow",[14,15,17,18,22,23,26],"h2",{"id":16},"production-state-machine-with-matchcase-310","Production State Machine with ",[19,20,21],"code",{},"match","\u002F",[19,24,25],{},"case"," (3.10+)",[28,29,31],"code-wrapper",{"language":30},"python",[32,33,37],"pre",{"className":34,"code":35,"language":30,"meta":36,"style":36},"language-python shiki shiki-themes github-light github-dark","# ── Real-world: async task state machine using structural pattern matching ──\n# Models a job scheduler's lifecycle — each state transition is a pattern match\n# against the current state + event tuple, with guards for conditional transitions.\n\nfrom dataclasses import dataclass\nfrom enum import Enum, auto\n\nclass State(Enum):\n    PENDING = auto()\n    RUNNING = auto()\n    PAUSED = auto()\n    COMPLETED = auto()\n    FAILED = auto()\n\n@dataclass\nclass Task:\n    id: str\n    state: State = State.PENDING\n    retries: int = 0\n    error: str | None = None\n\ndef transition(task: Task, event: str, payload: dict | None = None) -> Task:\n    \"\"\"State machine: (current_state, event) → new_state, with guard clauses.\"\"\"\n    payload = payload or {}\n\n    match (task.state, event):\n        case (State.PENDING, \"start\"):\n            task.state = State.RUNNING\n\n        case (State.RUNNING, \"pause\"):\n            task.state = State.PAUSED\n\n        case (State.PAUSED, \"resume\"):\n            task.state = State.RUNNING\n\n        case (State.RUNNING, \"complete\") if payload.get(\"success\", True):\n            task.state = State.COMPLETED\n\n        case (State.RUNNING, \"complete\"):\n            task.error = payload.get(\"error\", \"unknown\")\n            task.state = State.FAILED\n\n        case (State.FAILED, \"retry\") if task.retries \u003C 3:   # guard: max 3 retries\n            task.retries += 1\n            task.error = None\n            task.state = State.PENDING\n\n        case (State.FAILED, \"retry\"):\n            raise RuntimeError(f\"Task {task.id} exhausted retries ({task.retries})\")\n\n        case (State.COMPLETED, _):\n            pass   # terminal state — any event is a no-op\n\n        case (state, event):\n            raise ValueError(f\"Invalid transition: {state.name} + {event}\")\n\n    return task\n\n# Drive the state machine through a realistic lifecycle\ntask = Task(\"job-42\")\ntransition(task, \"start\")\ntransition(task, \"pause\")\ntransition(task, \"resume\")\ntransition(task, \"complete\", {\"success\": False, \"error\": \"OOM\"})\nprint(task)   # Task(id='job-42', state=\u003CState.FAILED: 5>, retries=0, error='OOM')\ntransition(task, \"retry\")\nprint(task.state)   # State.PENDING — back in queue\n","",[19,38,39,48,54,60,67,84,97,102,121,134,144,154,164,174,179,185,196,208,223,237,257,262,293,300,317,322,331,351,364,369,386,398,403,420,431,436,469,481,486,501,522,534,539,573,585,594,605,610,625,666,671,684,693,698,706,743,748,757,762,768,784,794,803,812,841,853,862],{"__ignoreMap":36},[40,41,44],"span",{"class":42,"line":43},"line",1,[40,45,47],{"class":46},"sdCPZ","# ── Real-world: async task state machine using structural pattern matching ──\n",[40,49,51],{"class":42,"line":50},2,[40,52,53],{"class":46},"# Models a job scheduler's lifecycle — each state transition is a pattern match\n",[40,55,57],{"class":42,"line":56},3,[40,58,59],{"class":46},"# against the current state + event tuple, with guards for conditional transitions.\n",[40,61,63],{"class":42,"line":62},4,[40,64,66],{"emptyLinePlaceholder":65},true,"\n",[40,68,70,74,78,81],{"class":42,"line":69},5,[40,71,73],{"class":72},"svdQ7","from",[40,75,77],{"class":76},"ssxIu"," dataclasses ",[40,79,80],{"class":72},"import",[40,82,83],{"class":76}," dataclass\n",[40,85,87,89,92,94],{"class":42,"line":86},6,[40,88,73],{"class":72},[40,90,91],{"class":76}," enum ",[40,93,80],{"class":72},[40,95,96],{"class":76}," Enum, auto\n",[40,98,100],{"class":42,"line":99},7,[40,101,66],{"emptyLinePlaceholder":65},[40,103,105,108,112,115,118],{"class":42,"line":104},8,[40,106,107],{"class":72},"class",[40,109,111],{"class":110},"sIsaT"," State",[40,113,114],{"class":76},"(",[40,116,117],{"class":110},"Enum",[40,119,120],{"class":76},"):\n",[40,122,124,128,131],{"class":42,"line":123},9,[40,125,127],{"class":126},"snvgF","    PENDING",[40,129,130],{"class":72}," =",[40,132,133],{"class":76}," auto()\n",[40,135,137,140,142],{"class":42,"line":136},10,[40,138,139],{"class":126},"    RUNNING",[40,141,130],{"class":72},[40,143,133],{"class":76},[40,145,147,150,152],{"class":42,"line":146},11,[40,148,149],{"class":126},"    PAUSED",[40,151,130],{"class":72},[40,153,133],{"class":76},[40,155,157,160,162],{"class":42,"line":156},12,[40,158,159],{"class":126},"    COMPLETED",[40,161,130],{"class":72},[40,163,133],{"class":76},[40,165,167,170,172],{"class":42,"line":166},13,[40,168,169],{"class":126},"    FAILED",[40,171,130],{"class":72},[40,173,133],{"class":76},[40,175,177],{"class":42,"line":176},14,[40,178,66],{"emptyLinePlaceholder":65},[40,180,182],{"class":42,"line":181},15,[40,183,184],{"class":110},"@dataclass\n",[40,186,188,190,193],{"class":42,"line":187},16,[40,189,107],{"class":72},[40,191,192],{"class":110}," Task",[40,194,195],{"class":76},":\n",[40,197,199,202,205],{"class":42,"line":198},17,[40,200,201],{"class":126},"    id",[40,203,204],{"class":76},": ",[40,206,207],{"class":126},"str\n",[40,209,211,214,217,220],{"class":42,"line":210},18,[40,212,213],{"class":76},"    state: State ",[40,215,216],{"class":72},"=",[40,218,219],{"class":76}," State.",[40,221,222],{"class":126},"PENDING\n",[40,224,226,229,232,234],{"class":42,"line":225},19,[40,227,228],{"class":76},"    retries: ",[40,230,231],{"class":126},"int",[40,233,130],{"class":72},[40,235,236],{"class":126}," 0\n",[40,238,240,243,246,249,252,254],{"class":42,"line":239},20,[40,241,242],{"class":76},"    error: ",[40,244,245],{"class":126},"str",[40,247,248],{"class":72}," |",[40,250,251],{"class":126}," None",[40,253,130],{"class":72},[40,255,256],{"class":126}," None\n",[40,258,260],{"class":42,"line":259},21,[40,261,66],{"emptyLinePlaceholder":65},[40,263,265,268,271,274,276,279,282,284,286,288,290],{"class":42,"line":264},22,[40,266,267],{"class":72},"def",[40,269,270],{"class":110}," transition",[40,272,273],{"class":76},"(task: Task, event: ",[40,275,245],{"class":126},[40,277,278],{"class":76},", payload: ",[40,280,281],{"class":126},"dict",[40,283,248],{"class":72},[40,285,251],{"class":126},[40,287,130],{"class":72},[40,289,251],{"class":126},[40,291,292],{"class":76},") -> Task:\n",[40,294,296],{"class":42,"line":295},23,[40,297,299],{"class":298},"sJ6F3","    \"\"\"State machine: (current_state, event) → new_state, with guard clauses.\"\"\"\n",[40,301,303,306,308,311,314],{"class":42,"line":302},24,[40,304,305],{"class":76},"    payload ",[40,307,216],{"class":72},[40,309,310],{"class":76}," payload ",[40,312,313],{"class":72},"or",[40,315,316],{"class":76}," {}\n",[40,318,320],{"class":42,"line":319},25,[40,321,66],{"emptyLinePlaceholder":65},[40,323,325,328],{"class":42,"line":324},26,[40,326,327],{"class":72},"    match",[40,329,330],{"class":76}," (task.state, event):\n",[40,332,334,337,340,343,346,349],{"class":42,"line":333},27,[40,335,336],{"class":72},"        case",[40,338,339],{"class":76}," (State.",[40,341,342],{"class":126},"PENDING",[40,344,345],{"class":76},", ",[40,347,348],{"class":298},"\"start\"",[40,350,120],{"class":76},[40,352,354,357,359,361],{"class":42,"line":353},28,[40,355,356],{"class":76},"            task.state ",[40,358,216],{"class":72},[40,360,219],{"class":76},[40,362,363],{"class":126},"RUNNING\n",[40,365,367],{"class":42,"line":366},29,[40,368,66],{"emptyLinePlaceholder":65},[40,370,372,374,376,379,381,384],{"class":42,"line":371},30,[40,373,336],{"class":72},[40,375,339],{"class":76},[40,377,378],{"class":126},"RUNNING",[40,380,345],{"class":76},[40,382,383],{"class":298},"\"pause\"",[40,385,120],{"class":76},[40,387,389,391,393,395],{"class":42,"line":388},31,[40,390,356],{"class":76},[40,392,216],{"class":72},[40,394,219],{"class":76},[40,396,397],{"class":126},"PAUSED\n",[40,399,401],{"class":42,"line":400},32,[40,402,66],{"emptyLinePlaceholder":65},[40,404,406,408,410,413,415,418],{"class":42,"line":405},33,[40,407,336],{"class":72},[40,409,339],{"class":76},[40,411,412],{"class":126},"PAUSED",[40,414,345],{"class":76},[40,416,417],{"class":298},"\"resume\"",[40,419,120],{"class":76},[40,421,423,425,427,429],{"class":42,"line":422},34,[40,424,356],{"class":76},[40,426,216],{"class":72},[40,428,219],{"class":76},[40,430,363],{"class":126},[40,432,434],{"class":42,"line":433},35,[40,435,66],{"emptyLinePlaceholder":65},[40,437,439,441,443,445,447,450,453,456,459,462,464,467],{"class":42,"line":438},36,[40,440,336],{"class":72},[40,442,339],{"class":76},[40,444,378],{"class":126},[40,446,345],{"class":76},[40,448,449],{"class":298},"\"complete\"",[40,451,452],{"class":76},") ",[40,454,455],{"class":72},"if",[40,457,458],{"class":76}," payload.get(",[40,460,461],{"class":298},"\"success\"",[40,463,345],{"class":76},[40,465,466],{"class":126},"True",[40,468,120],{"class":76},[40,470,472,474,476,478],{"class":42,"line":471},37,[40,473,356],{"class":76},[40,475,216],{"class":72},[40,477,219],{"class":76},[40,479,480],{"class":126},"COMPLETED\n",[40,482,484],{"class":42,"line":483},38,[40,485,66],{"emptyLinePlaceholder":65},[40,487,489,491,493,495,497,499],{"class":42,"line":488},39,[40,490,336],{"class":72},[40,492,339],{"class":76},[40,494,378],{"class":126},[40,496,345],{"class":76},[40,498,449],{"class":298},[40,500,120],{"class":76},[40,502,504,507,509,511,514,516,519],{"class":42,"line":503},40,[40,505,506],{"class":76},"            task.error ",[40,508,216],{"class":72},[40,510,458],{"class":76},[40,512,513],{"class":298},"\"error\"",[40,515,345],{"class":76},[40,517,518],{"class":298},"\"unknown\"",[40,520,521],{"class":76},")\n",[40,523,525,527,529,531],{"class":42,"line":524},41,[40,526,356],{"class":76},[40,528,216],{"class":72},[40,530,219],{"class":76},[40,532,533],{"class":126},"FAILED\n",[40,535,537],{"class":42,"line":536},42,[40,538,66],{"emptyLinePlaceholder":65},[40,540,542,544,546,549,551,554,556,558,561,564,567,570],{"class":42,"line":541},43,[40,543,336],{"class":72},[40,545,339],{"class":76},[40,547,548],{"class":126},"FAILED",[40,550,345],{"class":76},[40,552,553],{"class":298},"\"retry\"",[40,555,452],{"class":76},[40,557,455],{"class":72},[40,559,560],{"class":76}," task.retries ",[40,562,563],{"class":72},"\u003C",[40,565,566],{"class":126}," 3",[40,568,569],{"class":76},":   ",[40,571,572],{"class":46},"# guard: max 3 retries\n",[40,574,576,579,582],{"class":42,"line":575},44,[40,577,578],{"class":76},"            task.retries ",[40,580,581],{"class":72},"+=",[40,583,584],{"class":126}," 1\n",[40,586,588,590,592],{"class":42,"line":587},45,[40,589,506],{"class":76},[40,591,216],{"class":72},[40,593,256],{"class":126},[40,595,597,599,601,603],{"class":42,"line":596},46,[40,598,356],{"class":76},[40,600,216],{"class":72},[40,602,219],{"class":76},[40,604,222],{"class":126},[40,606,608],{"class":42,"line":607},47,[40,609,66],{"emptyLinePlaceholder":65},[40,611,613,615,617,619,621,623],{"class":42,"line":612},48,[40,614,336],{"class":72},[40,616,339],{"class":76},[40,618,548],{"class":126},[40,620,345],{"class":76},[40,622,553],{"class":298},[40,624,120],{"class":76},[40,626,628,631,634,636,639,642,645,648,651,654,656,659,661,664],{"class":42,"line":627},49,[40,629,630],{"class":72},"            raise",[40,632,633],{"class":126}," RuntimeError",[40,635,114],{"class":76},[40,637,638],{"class":72},"f",[40,640,641],{"class":298},"\"Task ",[40,643,644],{"class":126},"{",[40,646,647],{"class":76},"task.id",[40,649,650],{"class":126},"}",[40,652,653],{"class":298}," exhausted retries (",[40,655,644],{"class":126},[40,657,658],{"class":76},"task.retries",[40,660,650],{"class":126},[40,662,663],{"class":298},")\"",[40,665,521],{"class":76},[40,667,669],{"class":42,"line":668},50,[40,670,66],{"emptyLinePlaceholder":65},[40,672,674,676,678,681],{"class":42,"line":673},51,[40,675,336],{"class":72},[40,677,339],{"class":76},[40,679,680],{"class":126},"COMPLETED",[40,682,683],{"class":76},", _):\n",[40,685,687,690],{"class":42,"line":686},52,[40,688,689],{"class":72},"            pass",[40,691,692],{"class":46},"   # terminal state — any event is a no-op\n",[40,694,696],{"class":42,"line":695},53,[40,697,66],{"emptyLinePlaceholder":65},[40,699,701,703],{"class":42,"line":700},54,[40,702,336],{"class":72},[40,704,705],{"class":76}," (state, event):\n",[40,707,709,711,714,716,718,721,723,726,728,731,733,736,738,741],{"class":42,"line":708},55,[40,710,630],{"class":72},[40,712,713],{"class":126}," ValueError",[40,715,114],{"class":76},[40,717,638],{"class":72},[40,719,720],{"class":298},"\"Invalid transition: ",[40,722,644],{"class":126},[40,724,725],{"class":76},"state.name",[40,727,650],{"class":126},[40,729,730],{"class":298}," + ",[40,732,644],{"class":126},[40,734,735],{"class":76},"event",[40,737,650],{"class":126},[40,739,740],{"class":298},"\"",[40,742,521],{"class":76},[40,744,746],{"class":42,"line":745},56,[40,747,66],{"emptyLinePlaceholder":65},[40,749,751,754],{"class":42,"line":750},57,[40,752,753],{"class":72},"    return",[40,755,756],{"class":76}," task\n",[40,758,760],{"class":42,"line":759},58,[40,761,66],{"emptyLinePlaceholder":65},[40,763,765],{"class":42,"line":764},59,[40,766,767],{"class":46},"# Drive the state machine through a realistic lifecycle\n",[40,769,771,774,776,779,782],{"class":42,"line":770},60,[40,772,773],{"class":76},"task ",[40,775,216],{"class":72},[40,777,778],{"class":76}," Task(",[40,780,781],{"class":298},"\"job-42\"",[40,783,521],{"class":76},[40,785,787,790,792],{"class":42,"line":786},61,[40,788,789],{"class":76},"transition(task, ",[40,791,348],{"class":298},[40,793,521],{"class":76},[40,795,797,799,801],{"class":42,"line":796},62,[40,798,789],{"class":76},[40,800,383],{"class":298},[40,802,521],{"class":76},[40,804,806,808,810],{"class":42,"line":805},63,[40,807,789],{"class":76},[40,809,417],{"class":298},[40,811,521],{"class":76},[40,813,815,817,819,822,824,826,829,831,833,835,838],{"class":42,"line":814},64,[40,816,789],{"class":76},[40,818,449],{"class":298},[40,820,821],{"class":76},", {",[40,823,461],{"class":298},[40,825,204],{"class":76},[40,827,828],{"class":126},"False",[40,830,345],{"class":76},[40,832,513],{"class":298},[40,834,204],{"class":76},[40,836,837],{"class":298},"\"OOM\"",[40,839,840],{"class":76},"})\n",[40,842,844,847,850],{"class":42,"line":843},65,[40,845,846],{"class":126},"print",[40,848,849],{"class":76},"(task)   ",[40,851,852],{"class":46},"# Task(id='job-42', state=\u003CState.FAILED: 5>, retries=0, error='OOM')\n",[40,854,856,858,860],{"class":42,"line":855},66,[40,857,789],{"class":76},[40,859,553],{"class":298},[40,861,521],{"class":76},[40,863,865,867,870],{"class":42,"line":864},67,[40,866,846],{"class":126},[40,868,869],{"class":76},"(task.state)   ",[40,871,872],{"class":46},"# State.PENDING — back in queue\n",[14,874,876,879],{"id":875},"while-loops",[19,877,878],{},"while"," Loops",[28,881,882],{"language":30},[32,883,885],{"className":34,"code":884,"language":30,"meta":36,"style":36},"def collatz_steps(n):\n    steps = 0\n    while n != 1:\n        n = n \u002F\u002F 2 if n % 2 == 0 else 3 * n + 1\n        steps += 1\n    return steps\n\nprint(collatz_steps(27))   # 111\n",[19,886,887,897,906,922,968,977,984,988],{"__ignoreMap":36},[40,888,889,891,894],{"class":42,"line":43},[40,890,267],{"class":72},[40,892,893],{"class":110}," collatz_steps",[40,895,896],{"class":76},"(n):\n",[40,898,899,902,904],{"class":42,"line":50},[40,900,901],{"class":76},"    steps ",[40,903,216],{"class":72},[40,905,236],{"class":126},[40,907,908,911,914,917,920],{"class":42,"line":56},[40,909,910],{"class":72},"    while",[40,912,913],{"class":76}," n ",[40,915,916],{"class":72},"!=",[40,918,919],{"class":126}," 1",[40,921,195],{"class":76},[40,923,924,927,929,931,934,937,940,942,945,947,950,953,956,958,961,963,966],{"class":42,"line":62},[40,925,926],{"class":76},"        n ",[40,928,216],{"class":72},[40,930,913],{"class":76},[40,932,933],{"class":72},"\u002F\u002F",[40,935,936],{"class":126}," 2",[40,938,939],{"class":72}," if",[40,941,913],{"class":76},[40,943,944],{"class":72},"%",[40,946,936],{"class":126},[40,948,949],{"class":72}," ==",[40,951,952],{"class":126}," 0",[40,954,955],{"class":72}," else",[40,957,566],{"class":126},[40,959,960],{"class":72}," *",[40,962,913],{"class":76},[40,964,965],{"class":72},"+",[40,967,584],{"class":126},[40,969,970,973,975],{"class":42,"line":69},[40,971,972],{"class":76},"        steps ",[40,974,581],{"class":72},[40,976,584],{"class":126},[40,978,979,981],{"class":42,"line":86},[40,980,753],{"class":72},[40,982,983],{"class":76}," steps\n",[40,985,986],{"class":42,"line":99},[40,987,66],{"emptyLinePlaceholder":65},[40,989,990,992,995,998,1001],{"class":42,"line":104},[40,991,846],{"class":126},[40,993,994],{"class":76},"(collatz_steps(",[40,996,997],{"class":126},"27",[40,999,1000],{"class":76},"))   ",[40,1002,1003],{"class":46},"# 111\n",[1005,1006,1008,1011,1012,1015],"h3",{"id":1007},"while-true-with-break-the-idiomatic-loop-until-condition-found-inside",[19,1009,1010],{},"while True"," with ",[19,1013,1014],{},"break"," — the idiomatic \"loop until condition found inside\"",[28,1017,1018],{"language":30},[32,1019,1021],{"className":34,"code":1020,"language":30,"meta":36,"style":36},"import random\n\ndef guess_number(target):\n    attempts = 0\n    while True:\n        attempts += 1\n        guess = random.randint(1, 100)\n        if guess == target:\n            return attempts\n        if attempts > 10_000:   # safety valve against infinite loops\n            raise RuntimeError(\"too many attempts\")\n",[19,1022,1023,1030,1034,1044,1053,1062,1071,1091,1105,1113,1131],{"__ignoreMap":36},[40,1024,1025,1027],{"class":42,"line":43},[40,1026,80],{"class":72},[40,1028,1029],{"class":76}," random\n",[40,1031,1032],{"class":42,"line":50},[40,1033,66],{"emptyLinePlaceholder":65},[40,1035,1036,1038,1041],{"class":42,"line":56},[40,1037,267],{"class":72},[40,1039,1040],{"class":110}," guess_number",[40,1042,1043],{"class":76},"(target):\n",[40,1045,1046,1049,1051],{"class":42,"line":62},[40,1047,1048],{"class":76},"    attempts ",[40,1050,216],{"class":72},[40,1052,236],{"class":126},[40,1054,1055,1057,1060],{"class":42,"line":69},[40,1056,910],{"class":72},[40,1058,1059],{"class":126}," True",[40,1061,195],{"class":76},[40,1063,1064,1067,1069],{"class":42,"line":86},[40,1065,1066],{"class":76},"        attempts ",[40,1068,581],{"class":72},[40,1070,584],{"class":126},[40,1072,1073,1076,1078,1081,1084,1086,1089],{"class":42,"line":99},[40,1074,1075],{"class":76},"        guess ",[40,1077,216],{"class":72},[40,1079,1080],{"class":76}," random.randint(",[40,1082,1083],{"class":126},"1",[40,1085,345],{"class":76},[40,1087,1088],{"class":126},"100",[40,1090,521],{"class":76},[40,1092,1093,1096,1099,1102],{"class":42,"line":104},[40,1094,1095],{"class":72},"        if",[40,1097,1098],{"class":76}," guess ",[40,1100,1101],{"class":72},"==",[40,1103,1104],{"class":76}," target:\n",[40,1106,1107,1110],{"class":42,"line":123},[40,1108,1109],{"class":72},"            return",[40,1111,1112],{"class":76}," attempts\n",[40,1114,1115,1117,1120,1123,1126,1128],{"class":42,"line":136},[40,1116,1095],{"class":72},[40,1118,1119],{"class":76}," attempts ",[40,1121,1122],{"class":72},">",[40,1124,1125],{"class":126}," 10_000",[40,1127,569],{"class":76},[40,1129,1130],{"class":46},"# safety valve against infinite loops\n",[40,1132,1133,1135,1137,1139,1142],{"class":42,"line":146},[40,1134,630],{"class":72},[40,1136,633],{"class":126},[40,1138,114],{"class":76},[40,1140,1141],{"class":298},"\"too many attempts\"",[40,1143,521],{"class":76},[14,1145,1147,1150],{"id":1146},"for-loops-iterating-not-counting",[19,1148,1149],{},"for"," Loops — Iterating, Not Counting",[1152,1153,1154,1155,1157,1158,1162,1163,1166],"p",{},"Python's ",[19,1156,1149],{}," iterates over any ",[1159,1160,1161],"strong",{},"iterable"," (chapter 19 covers the protocol in depth) — there is no C-style ",[19,1164,1165],{},"for (i = 0; i \u003C n; i++)",".",[28,1168,1169],{"language":30},[32,1170,1172],{"className":34,"code":1171,"language":30,"meta":36,"style":36},"for fruit in [\"apple\", \"banana\", \"cherry\"]:\n    print(fruit)\n\n# Need an index too? Use enumerate — don't manually track a counter\nfor i, fruit in enumerate([\"apple\", \"banana\", \"cherry\"], start=1):\n    print(f\"{i}. {fruit}\")\n\n# Need a numeric range? range() is lazy — doesn't build a list\nfor i in range(5):          # 0, 1, 2, 3, 4\n    print(i)\nfor i in range(2, 10, 2):    # 2, 4, 6, 8 — start, stop, step\n    print(i)\nfor i in range(10, 0, -1):     # counts down: 10, 9, ..., 1\n    print(i)\n",[19,1173,1174,1203,1211,1215,1220,1258,1289,1293,1298,1321,1328,1358,1364,1396],{"__ignoreMap":36},[40,1175,1176,1178,1181,1184,1187,1190,1192,1195,1197,1200],{"class":42,"line":43},[40,1177,1149],{"class":72},[40,1179,1180],{"class":76}," fruit ",[40,1182,1183],{"class":72},"in",[40,1185,1186],{"class":76}," [",[40,1188,1189],{"class":298},"\"apple\"",[40,1191,345],{"class":76},[40,1193,1194],{"class":298},"\"banana\"",[40,1196,345],{"class":76},[40,1198,1199],{"class":298},"\"cherry\"",[40,1201,1202],{"class":76},"]:\n",[40,1204,1205,1208],{"class":42,"line":50},[40,1206,1207],{"class":126},"    print",[40,1209,1210],{"class":76},"(fruit)\n",[40,1212,1213],{"class":42,"line":56},[40,1214,66],{"emptyLinePlaceholder":65},[40,1216,1217],{"class":42,"line":62},[40,1218,1219],{"class":46},"# Need an index too? Use enumerate — don't manually track a counter\n",[40,1221,1222,1224,1227,1229,1232,1235,1237,1239,1241,1243,1245,1248,1252,1254,1256],{"class":42,"line":69},[40,1223,1149],{"class":72},[40,1225,1226],{"class":76}," i, fruit ",[40,1228,1183],{"class":72},[40,1230,1231],{"class":126}," enumerate",[40,1233,1234],{"class":76},"([",[40,1236,1189],{"class":298},[40,1238,345],{"class":76},[40,1240,1194],{"class":298},[40,1242,345],{"class":76},[40,1244,1199],{"class":298},[40,1246,1247],{"class":76},"], ",[40,1249,1251],{"class":1250},"sCrzJ","start",[40,1253,216],{"class":72},[40,1255,1083],{"class":126},[40,1257,120],{"class":76},[40,1259,1260,1262,1264,1266,1268,1270,1273,1275,1278,1280,1283,1285,1287],{"class":42,"line":86},[40,1261,1207],{"class":126},[40,1263,114],{"class":76},[40,1265,638],{"class":72},[40,1267,740],{"class":298},[40,1269,644],{"class":126},[40,1271,1272],{"class":76},"i",[40,1274,650],{"class":126},[40,1276,1277],{"class":298},". ",[40,1279,644],{"class":126},[40,1281,1282],{"class":76},"fruit",[40,1284,650],{"class":126},[40,1286,740],{"class":298},[40,1288,521],{"class":76},[40,1290,1291],{"class":42,"line":99},[40,1292,66],{"emptyLinePlaceholder":65},[40,1294,1295],{"class":42,"line":104},[40,1296,1297],{"class":46},"# Need a numeric range? range() is lazy — doesn't build a list\n",[40,1299,1300,1302,1305,1307,1310,1312,1315,1318],{"class":42,"line":123},[40,1301,1149],{"class":72},[40,1303,1304],{"class":76}," i ",[40,1306,1183],{"class":72},[40,1308,1309],{"class":126}," range",[40,1311,114],{"class":76},[40,1313,1314],{"class":126},"5",[40,1316,1317],{"class":76},"):          ",[40,1319,1320],{"class":46},"# 0, 1, 2, 3, 4\n",[40,1322,1323,1325],{"class":42,"line":136},[40,1324,1207],{"class":126},[40,1326,1327],{"class":76},"(i)\n",[40,1329,1330,1332,1334,1336,1338,1340,1343,1345,1348,1350,1352,1355],{"class":42,"line":146},[40,1331,1149],{"class":72},[40,1333,1304],{"class":76},[40,1335,1183],{"class":72},[40,1337,1309],{"class":126},[40,1339,114],{"class":76},[40,1341,1342],{"class":126},"2",[40,1344,345],{"class":76},[40,1346,1347],{"class":126},"10",[40,1349,345],{"class":76},[40,1351,1342],{"class":126},[40,1353,1354],{"class":76},"):    ",[40,1356,1357],{"class":46},"# 2, 4, 6, 8 — start, stop, step\n",[40,1359,1360,1362],{"class":42,"line":156},[40,1361,1207],{"class":126},[40,1363,1327],{"class":76},[40,1365,1366,1368,1370,1372,1374,1376,1378,1380,1383,1385,1388,1390,1393],{"class":42,"line":166},[40,1367,1149],{"class":72},[40,1369,1304],{"class":76},[40,1371,1183],{"class":72},[40,1373,1309],{"class":126},[40,1375,114],{"class":76},[40,1377,1347],{"class":126},[40,1379,345],{"class":76},[40,1381,1382],{"class":126},"0",[40,1384,345],{"class":76},[40,1386,1387],{"class":72},"-",[40,1389,1083],{"class":126},[40,1391,1392],{"class":76},"):     ",[40,1394,1395],{"class":46},"# counts down: 10, 9, ..., 1\n",[40,1397,1398,1400],{"class":42,"line":176},[40,1399,1207],{"class":126},[40,1401,1327],{"class":76},[1005,1403,1405,1406],{"id":1404},"iterating-multiple-sequences-together-with-zip","Iterating multiple sequences together with ",[19,1407,1408],{},"zip",[28,1410,1411],{"language":30},[32,1412,1414],{"className":34,"code":1413,"language":30,"meta":36,"style":36},"names = [\"Ada\", \"Grace\", \"Alan\"]\nscores = [98, 95, 87]\n\nfor name, score in zip(names, scores):\n    print(f\"{name}: {score}\")\n\n# zip stops at the SHORTEST iterable — silent truncation, not an error\nextra = [\"Ada\", \"Grace\", \"Alan\", \"Linus\"]\nfor name, score in zip(extra, scores):\n    print(name)   # Linus is silently dropped — no error, no warning\n",[19,1415,1416,1441,1465,1469,1484,1514,1518,1523,1549,1562],{"__ignoreMap":36},[40,1417,1418,1421,1423,1425,1428,1430,1433,1435,1438],{"class":42,"line":43},[40,1419,1420],{"class":76},"names ",[40,1422,216],{"class":72},[40,1424,1186],{"class":76},[40,1426,1427],{"class":298},"\"Ada\"",[40,1429,345],{"class":76},[40,1431,1432],{"class":298},"\"Grace\"",[40,1434,345],{"class":76},[40,1436,1437],{"class":298},"\"Alan\"",[40,1439,1440],{"class":76},"]\n",[40,1442,1443,1446,1448,1450,1453,1455,1458,1460,1463],{"class":42,"line":50},[40,1444,1445],{"class":76},"scores ",[40,1447,216],{"class":72},[40,1449,1186],{"class":76},[40,1451,1452],{"class":126},"98",[40,1454,345],{"class":76},[40,1456,1457],{"class":126},"95",[40,1459,345],{"class":76},[40,1461,1462],{"class":126},"87",[40,1464,1440],{"class":76},[40,1466,1467],{"class":42,"line":56},[40,1468,66],{"emptyLinePlaceholder":65},[40,1470,1471,1473,1476,1478,1481],{"class":42,"line":62},[40,1472,1149],{"class":72},[40,1474,1475],{"class":76}," name, score ",[40,1477,1183],{"class":72},[40,1479,1480],{"class":126}," zip",[40,1482,1483],{"class":76},"(names, scores):\n",[40,1485,1486,1488,1490,1492,1494,1496,1499,1501,1503,1505,1508,1510,1512],{"class":42,"line":69},[40,1487,1207],{"class":126},[40,1489,114],{"class":76},[40,1491,638],{"class":72},[40,1493,740],{"class":298},[40,1495,644],{"class":126},[40,1497,1498],{"class":76},"name",[40,1500,650],{"class":126},[40,1502,204],{"class":298},[40,1504,644],{"class":126},[40,1506,1507],{"class":76},"score",[40,1509,650],{"class":126},[40,1511,740],{"class":298},[40,1513,521],{"class":76},[40,1515,1516],{"class":42,"line":86},[40,1517,66],{"emptyLinePlaceholder":65},[40,1519,1520],{"class":42,"line":99},[40,1521,1522],{"class":46},"# zip stops at the SHORTEST iterable — silent truncation, not an error\n",[40,1524,1525,1528,1530,1532,1534,1536,1538,1540,1542,1544,1547],{"class":42,"line":104},[40,1526,1527],{"class":76},"extra ",[40,1529,216],{"class":72},[40,1531,1186],{"class":76},[40,1533,1427],{"class":298},[40,1535,345],{"class":76},[40,1537,1432],{"class":298},[40,1539,345],{"class":76},[40,1541,1437],{"class":298},[40,1543,345],{"class":76},[40,1545,1546],{"class":298},"\"Linus\"",[40,1548,1440],{"class":76},[40,1550,1551,1553,1555,1557,1559],{"class":42,"line":123},[40,1552,1149],{"class":72},[40,1554,1475],{"class":76},[40,1556,1183],{"class":72},[40,1558,1480],{"class":126},[40,1560,1561],{"class":76},"(extra, scores):\n",[40,1563,1564,1566,1569],{"class":42,"line":136},[40,1565,1207],{"class":126},[40,1567,1568],{"class":76},"(name)   ",[40,1570,1571],{"class":46},"# Linus is silently dropped — no error, no warning\n",[1152,1573,1574,1575,1578],{},"Use ",[19,1576,1577],{},"itertools.zip_longest(names, scores, fillvalue=None)"," from the standard library when mismatched lengths should be padded rather than silently truncated.",[14,1580,1582,345,1584,1587,1588,1591],{"id":1581},"break-continue-and-the-rarely-known-else-on-loops",[19,1583,1014],{},[19,1585,1586],{},"continue",", and the Rarely-Known ",[19,1589,1590],{},"else"," on Loops",[1152,1593,1594,1596,1597,1599,1600,1611,1612,1166],{},[19,1595,1014],{}," exits a loop immediately. ",[19,1598,1586],{}," skips to the next iteration. Both work identically to C\u002FJS. What's unique to Python: ",[1159,1601,1602,1604,1605,1607,1608,1610],{},[19,1603,1149],{}," and ",[19,1606,878],{}," loops can have an ",[19,1609,1590],{}," clause",", which runs only if the loop completed ",[1159,1613,1614,1615],{},"without hitting a ",[19,1616,1014],{},[28,1618,1619],{"language":30},[32,1620,1622],{"className":34,"code":1621,"language":30,"meta":36,"style":36},"def find_first_prime_factor(n):\n    for candidate in range(2, int(n ** 0.5) + 1):\n        if n % candidate == 0:\n            print(f\"Found factor: {candidate}\")\n            break\n    else:\n        # Runs ONLY if the loop never broke — i.e., n is prime\n        # (or n \u003C 4, where the range is empty and the loop trivially \"completes\")\n        print(f\"{n} is prime\")\n\nfind_first_prime_factor(15)   # Found factor: 3\nfind_first_prime_factor(17)   # 17 is prime\n",[19,1623,1624,1633,1670,1686,1709,1714,1721,1726,1731,1754,1758,1772],{"__ignoreMap":36},[40,1625,1626,1628,1631],{"class":42,"line":43},[40,1627,267],{"class":72},[40,1629,1630],{"class":110}," find_first_prime_factor",[40,1632,896],{"class":76},[40,1634,1635,1638,1641,1643,1645,1647,1649,1651,1653,1656,1659,1662,1664,1666,1668],{"class":42,"line":50},[40,1636,1637],{"class":72},"    for",[40,1639,1640],{"class":76}," candidate ",[40,1642,1183],{"class":72},[40,1644,1309],{"class":126},[40,1646,114],{"class":76},[40,1648,1342],{"class":126},[40,1650,345],{"class":76},[40,1652,231],{"class":126},[40,1654,1655],{"class":76},"(n ",[40,1657,1658],{"class":72},"**",[40,1660,1661],{"class":126}," 0.5",[40,1663,452],{"class":76},[40,1665,965],{"class":72},[40,1667,919],{"class":126},[40,1669,120],{"class":76},[40,1671,1672,1674,1676,1678,1680,1682,1684],{"class":42,"line":56},[40,1673,1095],{"class":72},[40,1675,913],{"class":76},[40,1677,944],{"class":72},[40,1679,1640],{"class":76},[40,1681,1101],{"class":72},[40,1683,952],{"class":126},[40,1685,195],{"class":76},[40,1687,1688,1691,1693,1695,1698,1700,1703,1705,1707],{"class":42,"line":62},[40,1689,1690],{"class":126},"            print",[40,1692,114],{"class":76},[40,1694,638],{"class":72},[40,1696,1697],{"class":298},"\"Found factor: ",[40,1699,644],{"class":126},[40,1701,1702],{"class":76},"candidate",[40,1704,650],{"class":126},[40,1706,740],{"class":298},[40,1708,521],{"class":76},[40,1710,1711],{"class":42,"line":69},[40,1712,1713],{"class":72},"            break\n",[40,1715,1716,1719],{"class":42,"line":86},[40,1717,1718],{"class":72},"    else",[40,1720,195],{"class":76},[40,1722,1723],{"class":42,"line":99},[40,1724,1725],{"class":46},"        # Runs ONLY if the loop never broke — i.e., n is prime\n",[40,1727,1728],{"class":42,"line":104},[40,1729,1730],{"class":46},"        # (or n \u003C 4, where the range is empty and the loop trivially \"completes\")\n",[40,1732,1733,1736,1738,1740,1742,1744,1747,1749,1752],{"class":42,"line":123},[40,1734,1735],{"class":126},"        print",[40,1737,114],{"class":76},[40,1739,638],{"class":72},[40,1741,740],{"class":298},[40,1743,644],{"class":126},[40,1745,1746],{"class":76},"n",[40,1748,650],{"class":126},[40,1750,1751],{"class":298}," is prime\"",[40,1753,521],{"class":76},[40,1755,1756],{"class":42,"line":136},[40,1757,66],{"emptyLinePlaceholder":65},[40,1759,1760,1763,1766,1769],{"class":42,"line":146},[40,1761,1762],{"class":76},"find_first_prime_factor(",[40,1764,1765],{"class":126},"15",[40,1767,1768],{"class":76},")   ",[40,1770,1771],{"class":46},"# Found factor: 3\n",[40,1773,1774,1776,1779,1781],{"class":42,"line":156},[40,1775,1762],{"class":76},[40,1777,1778],{"class":126},"17",[40,1780,1768],{"class":76},[40,1782,1783],{"class":46},"# 17 is prime\n",[1152,1785,1786,1787,1792,1793,1796],{},"The mental model: ",[1159,1788,1789,1791],{},[19,1790,1590],{}," on a loop means \"no-break.\""," It is most useful for search loops where you need to distinguish \"found it, handled inside the loop\" from \"searched everything, found nothing\" — without a separate ",[19,1794,1795],{},"found = False"," flag variable.",[28,1798,1799],{"language":30},[32,1800,1802],{"className":34,"code":1801,"language":30,"meta":36,"style":36},"# WITHOUT for-else — needs an extra flag variable\ndef contains_duplicate_verbose(items):\n    seen = set()\n    found = False\n    for item in items:\n        if item in seen:\n            found = True\n            break\n        seen.add(item)\n    if not found:\n        print(\"No duplicates\")\n    else:\n        print(f\"Duplicate: {item}\")\n\n# WITH for-else — no flag needed, and scope is naturally clearer\ndef contains_duplicate(items):\n    seen = set()\n    for item in items:\n        if item in seen:\n            print(f\"Duplicate: {item}\")\n            break\n        seen.add(item)\n    else:\n        print(\"No duplicates\")\n",[19,1803,1804,1809,1819,1832,1842,1854,1865,1875,1879,1884,1895,1906,1912,1934,1938,1943,1952,1962,1972,1982,2002,2006,2010,2016],{"__ignoreMap":36},[40,1805,1806],{"class":42,"line":43},[40,1807,1808],{"class":46},"# WITHOUT for-else — needs an extra flag variable\n",[40,1810,1811,1813,1816],{"class":42,"line":50},[40,1812,267],{"class":72},[40,1814,1815],{"class":110}," contains_duplicate_verbose",[40,1817,1818],{"class":76},"(items):\n",[40,1820,1821,1824,1826,1829],{"class":42,"line":56},[40,1822,1823],{"class":76},"    seen ",[40,1825,216],{"class":72},[40,1827,1828],{"class":126}," set",[40,1830,1831],{"class":76},"()\n",[40,1833,1834,1837,1839],{"class":42,"line":62},[40,1835,1836],{"class":76},"    found ",[40,1838,216],{"class":72},[40,1840,1841],{"class":126}," False\n",[40,1843,1844,1846,1849,1851],{"class":42,"line":69},[40,1845,1637],{"class":72},[40,1847,1848],{"class":76}," item ",[40,1850,1183],{"class":72},[40,1852,1853],{"class":76}," items:\n",[40,1855,1856,1858,1860,1862],{"class":42,"line":86},[40,1857,1095],{"class":72},[40,1859,1848],{"class":76},[40,1861,1183],{"class":72},[40,1863,1864],{"class":76}," seen:\n",[40,1866,1867,1870,1872],{"class":42,"line":99},[40,1868,1869],{"class":76},"            found ",[40,1871,216],{"class":72},[40,1873,1874],{"class":126}," True\n",[40,1876,1877],{"class":42,"line":104},[40,1878,1713],{"class":72},[40,1880,1881],{"class":42,"line":123},[40,1882,1883],{"class":76},"        seen.add(item)\n",[40,1885,1886,1889,1892],{"class":42,"line":136},[40,1887,1888],{"class":72},"    if",[40,1890,1891],{"class":72}," not",[40,1893,1894],{"class":76}," found:\n",[40,1896,1897,1899,1901,1904],{"class":42,"line":146},[40,1898,1735],{"class":126},[40,1900,114],{"class":76},[40,1902,1903],{"class":298},"\"No duplicates\"",[40,1905,521],{"class":76},[40,1907,1908,1910],{"class":42,"line":156},[40,1909,1718],{"class":72},[40,1911,195],{"class":76},[40,1913,1914,1916,1918,1920,1923,1925,1928,1930,1932],{"class":42,"line":166},[40,1915,1735],{"class":126},[40,1917,114],{"class":76},[40,1919,638],{"class":72},[40,1921,1922],{"class":298},"\"Duplicate: ",[40,1924,644],{"class":126},[40,1926,1927],{"class":76},"item",[40,1929,650],{"class":126},[40,1931,740],{"class":298},[40,1933,521],{"class":76},[40,1935,1936],{"class":42,"line":176},[40,1937,66],{"emptyLinePlaceholder":65},[40,1939,1940],{"class":42,"line":181},[40,1941,1942],{"class":46},"# WITH for-else — no flag needed, and scope is naturally clearer\n",[40,1944,1945,1947,1950],{"class":42,"line":187},[40,1946,267],{"class":72},[40,1948,1949],{"class":110}," contains_duplicate",[40,1951,1818],{"class":76},[40,1953,1954,1956,1958,1960],{"class":42,"line":198},[40,1955,1823],{"class":76},[40,1957,216],{"class":72},[40,1959,1828],{"class":126},[40,1961,1831],{"class":76},[40,1963,1964,1966,1968,1970],{"class":42,"line":210},[40,1965,1637],{"class":72},[40,1967,1848],{"class":76},[40,1969,1183],{"class":72},[40,1971,1853],{"class":76},[40,1973,1974,1976,1978,1980],{"class":42,"line":225},[40,1975,1095],{"class":72},[40,1977,1848],{"class":76},[40,1979,1183],{"class":72},[40,1981,1864],{"class":76},[40,1983,1984,1986,1988,1990,1992,1994,1996,1998,2000],{"class":42,"line":239},[40,1985,1690],{"class":126},[40,1987,114],{"class":76},[40,1989,638],{"class":72},[40,1991,1922],{"class":298},[40,1993,644],{"class":126},[40,1995,1927],{"class":76},[40,1997,650],{"class":126},[40,1999,740],{"class":298},[40,2001,521],{"class":76},[40,2003,2004],{"class":42,"line":259},[40,2005,1713],{"class":72},[40,2007,2008],{"class":42,"line":264},[40,2009,1883],{"class":76},[40,2011,2012,2014],{"class":42,"line":295},[40,2013,1718],{"class":72},[40,2015,195],{"class":76},[40,2017,2018,2020,2022,2024],{"class":42,"line":302},[40,2019,1735],{"class":126},[40,2021,114],{"class":76},[40,2023,1903],{"class":298},[40,2025,521],{"class":76},[1152,2027,2028,2031,2032,2034,2035,2037],{},[19,2029,2030],{},"while ... else"," follows the same rule and is far less commonly used in practice, but behaves identically — the ",[19,2033,1590],{}," runs unless a ",[19,2036,1014],{}," fired.",[14,2039,2041,2042,2044,2045,26],{"id":2040},"structural-pattern-matching-match-case-310","Structural Pattern Matching — ",[19,2043,21],{}," \u002F ",[19,2046,25],{},[1152,2048,2049,2056,2057,22,2059,2061,2062,2065,2066,2069],{},[2050,2051,2055],"a",{"href":2052,"rel":2053},"https:\u002F\u002Fpeps.python.org\u002Fpep-0634\u002F",[2054],"nofollow","PEP 634"," added ",[19,2058,21],{},[19,2060,25],{},". It looks like a ",[19,2063,2064],{},"switch"," statement but is dramatically more powerful — it does ",[1159,2067,2068],{},"structural destructuring",", not just value equality.",[1005,2071,2073],{"id":2072},"basic-literal-matching","Basic literal matching",[28,2075,2076],{"language":30},[32,2077,2079],{"className":34,"code":2078,"language":30,"meta":36,"style":36},"def http_status_message(code):\n    match code:\n        case 200:\n            return \"OK\"\n        case 404:\n            return \"Not Found\"\n        case 500 | 502 | 503:              # OR-pattern\n            return \"Server Error\"\n        case _ if 400 \u003C= code \u003C 500:        # guard clause\n            return \"Client Error\"\n        case _:                              # wildcard — like `default`\n            return \"Unknown\"\n\nprint(http_status_message(404))    # Not Found\nprint(http_status_message(503))     # Server Error\nprint(http_status_message(422))      # Client Error\n",[19,2080,2081,2091,2098,2107,2114,2123,2130,2153,2160,2188,2195,2205,2212,2216,2232,2247],{"__ignoreMap":36},[40,2082,2083,2085,2088],{"class":42,"line":43},[40,2084,267],{"class":72},[40,2086,2087],{"class":110}," http_status_message",[40,2089,2090],{"class":76},"(code):\n",[40,2092,2093,2095],{"class":42,"line":50},[40,2094,327],{"class":72},[40,2096,2097],{"class":76}," code:\n",[40,2099,2100,2102,2105],{"class":42,"line":56},[40,2101,336],{"class":72},[40,2103,2104],{"class":126}," 200",[40,2106,195],{"class":76},[40,2108,2109,2111],{"class":42,"line":62},[40,2110,1109],{"class":72},[40,2112,2113],{"class":298}," \"OK\"\n",[40,2115,2116,2118,2121],{"class":42,"line":69},[40,2117,336],{"class":72},[40,2119,2120],{"class":126}," 404",[40,2122,195],{"class":76},[40,2124,2125,2127],{"class":42,"line":86},[40,2126,1109],{"class":72},[40,2128,2129],{"class":298}," \"Not Found\"\n",[40,2131,2132,2134,2137,2139,2142,2144,2147,2150],{"class":42,"line":99},[40,2133,336],{"class":72},[40,2135,2136],{"class":126}," 500",[40,2138,248],{"class":72},[40,2140,2141],{"class":126}," 502",[40,2143,248],{"class":72},[40,2145,2146],{"class":126}," 503",[40,2148,2149],{"class":76},":              ",[40,2151,2152],{"class":46},"# OR-pattern\n",[40,2154,2155,2157],{"class":42,"line":104},[40,2156,1109],{"class":72},[40,2158,2159],{"class":298}," \"Server Error\"\n",[40,2161,2162,2164,2167,2169,2172,2175,2178,2180,2182,2185],{"class":42,"line":123},[40,2163,336],{"class":72},[40,2165,2166],{"class":76}," _ ",[40,2168,455],{"class":72},[40,2170,2171],{"class":126}," 400",[40,2173,2174],{"class":72}," \u003C=",[40,2176,2177],{"class":76}," code ",[40,2179,563],{"class":72},[40,2181,2136],{"class":126},[40,2183,2184],{"class":76},":        ",[40,2186,2187],{"class":46},"# guard clause\n",[40,2189,2190,2192],{"class":42,"line":136},[40,2191,1109],{"class":72},[40,2193,2194],{"class":298}," \"Client Error\"\n",[40,2196,2197,2199,2202],{"class":42,"line":146},[40,2198,336],{"class":72},[40,2200,2201],{"class":76}," _:                              ",[40,2203,2204],{"class":46},"# wildcard — like `default`\n",[40,2206,2207,2209],{"class":42,"line":156},[40,2208,1109],{"class":72},[40,2210,2211],{"class":298}," \"Unknown\"\n",[40,2213,2214],{"class":42,"line":166},[40,2215,66],{"emptyLinePlaceholder":65},[40,2217,2218,2220,2223,2226,2229],{"class":42,"line":176},[40,2219,846],{"class":126},[40,2221,2222],{"class":76},"(http_status_message(",[40,2224,2225],{"class":126},"404",[40,2227,2228],{"class":76},"))    ",[40,2230,2231],{"class":46},"# Not Found\n",[40,2233,2234,2236,2238,2241,2244],{"class":42,"line":181},[40,2235,846],{"class":126},[40,2237,2222],{"class":76},[40,2239,2240],{"class":126},"503",[40,2242,2243],{"class":76},"))     ",[40,2245,2246],{"class":46},"# Server Error\n",[40,2248,2249,2251,2253,2256,2259],{"class":42,"line":187},[40,2250,846],{"class":126},[40,2252,2222],{"class":76},[40,2254,2255],{"class":126},"422",[40,2257,2258],{"class":76},"))      ",[40,2260,2261],{"class":46},"# Client Error\n",[1005,2263,2265],{"id":2264},"structural-destructuring-matching-shape-not-just-value","Structural destructuring — matching shape, not just value",[28,2267,2268],{"language":30},[32,2269,2271],{"className":34,"code":2270,"language":30,"meta":36,"style":36},"def handle_event(event):\n    match event:\n        case {\"type\": \"click\", \"x\": x, \"y\": y}:\n            return f\"Click at ({x}, {y})\"\n        case {\"type\": \"keypress\", \"key\": str(key)}:\n            return f\"Key pressed: {key}\"\n        case {\"type\": \"resize\", \"width\": w, \"height\": h} if w \u003C= 0 or h \u003C= 0:\n            return \"Invalid resize dimensions\"\n        case {\"type\": \"resize\", **rest}:\n            return f\"Resized: {rest}\"\n        case _:\n            return \"Unknown event\"\n\nprint(handle_event({\"type\": \"click\", \"x\": 10, \"y\": 20}))\nprint(handle_event({\"type\": \"resize\", \"width\": 800, \"height\": 600}))\nprint(handle_event({\"type\": \"resize\", \"width\": -1, \"height\": 600}))\n",[19,2272,2273,2283,2290,2319,2348,2373,2392,2441,2448,2467,2485,2492,2499,2503,2536,2568],{"__ignoreMap":36},[40,2274,2275,2277,2280],{"class":42,"line":43},[40,2276,267],{"class":72},[40,2278,2279],{"class":110}," handle_event",[40,2281,2282],{"class":76},"(event):\n",[40,2284,2285,2287],{"class":42,"line":50},[40,2286,327],{"class":72},[40,2288,2289],{"class":76}," event:\n",[40,2291,2292,2294,2297,2300,2302,2305,2307,2310,2313,2316],{"class":42,"line":56},[40,2293,336],{"class":72},[40,2295,2296],{"class":76}," {",[40,2298,2299],{"class":298},"\"type\"",[40,2301,204],{"class":76},[40,2303,2304],{"class":298},"\"click\"",[40,2306,345],{"class":76},[40,2308,2309],{"class":298},"\"x\"",[40,2311,2312],{"class":76},": x, ",[40,2314,2315],{"class":298},"\"y\"",[40,2317,2318],{"class":76},": y}:\n",[40,2320,2321,2323,2326,2329,2331,2334,2336,2338,2340,2343,2345],{"class":42,"line":62},[40,2322,1109],{"class":72},[40,2324,2325],{"class":72}," f",[40,2327,2328],{"class":298},"\"Click at (",[40,2330,644],{"class":126},[40,2332,2333],{"class":76},"x",[40,2335,650],{"class":126},[40,2337,345],{"class":298},[40,2339,644],{"class":126},[40,2341,2342],{"class":76},"y",[40,2344,650],{"class":126},[40,2346,2347],{"class":298},")\"\n",[40,2349,2350,2352,2354,2356,2358,2361,2363,2366,2368,2370],{"class":42,"line":69},[40,2351,336],{"class":72},[40,2353,2296],{"class":76},[40,2355,2299],{"class":298},[40,2357,204],{"class":76},[40,2359,2360],{"class":298},"\"keypress\"",[40,2362,345],{"class":76},[40,2364,2365],{"class":298},"\"key\"",[40,2367,204],{"class":76},[40,2369,245],{"class":126},[40,2371,2372],{"class":76},"(key)}:\n",[40,2374,2375,2377,2379,2382,2384,2387,2389],{"class":42,"line":86},[40,2376,1109],{"class":72},[40,2378,2325],{"class":72},[40,2380,2381],{"class":298},"\"Key pressed: ",[40,2383,644],{"class":126},[40,2385,2386],{"class":76},"key",[40,2388,650],{"class":126},[40,2390,2391],{"class":298},"\"\n",[40,2393,2394,2396,2398,2400,2402,2405,2407,2410,2413,2416,2419,2421,2424,2427,2429,2432,2435,2437,2439],{"class":42,"line":99},[40,2395,336],{"class":72},[40,2397,2296],{"class":76},[40,2399,2299],{"class":298},[40,2401,204],{"class":76},[40,2403,2404],{"class":298},"\"resize\"",[40,2406,345],{"class":76},[40,2408,2409],{"class":298},"\"width\"",[40,2411,2412],{"class":76},": w, ",[40,2414,2415],{"class":298},"\"height\"",[40,2417,2418],{"class":76},": h} ",[40,2420,455],{"class":72},[40,2422,2423],{"class":76}," w ",[40,2425,2426],{"class":72},"\u003C=",[40,2428,952],{"class":126},[40,2430,2431],{"class":72}," or",[40,2433,2434],{"class":76}," h ",[40,2436,2426],{"class":72},[40,2438,952],{"class":126},[40,2440,195],{"class":76},[40,2442,2443,2445],{"class":42,"line":104},[40,2444,1109],{"class":72},[40,2446,2447],{"class":298}," \"Invalid resize dimensions\"\n",[40,2449,2450,2452,2454,2456,2458,2460,2462,2464],{"class":42,"line":123},[40,2451,336],{"class":72},[40,2453,2296],{"class":76},[40,2455,2299],{"class":298},[40,2457,204],{"class":76},[40,2459,2404],{"class":298},[40,2461,345],{"class":76},[40,2463,1658],{"class":72},[40,2465,2466],{"class":76},"rest}:\n",[40,2468,2469,2471,2473,2476,2478,2481,2483],{"class":42,"line":136},[40,2470,1109],{"class":72},[40,2472,2325],{"class":72},[40,2474,2475],{"class":298},"\"Resized: ",[40,2477,644],{"class":126},[40,2479,2480],{"class":76},"rest",[40,2482,650],{"class":126},[40,2484,2391],{"class":298},[40,2486,2487,2489],{"class":42,"line":146},[40,2488,336],{"class":72},[40,2490,2491],{"class":76}," _:\n",[40,2493,2494,2496],{"class":42,"line":156},[40,2495,1109],{"class":72},[40,2497,2498],{"class":298}," \"Unknown event\"\n",[40,2500,2501],{"class":42,"line":166},[40,2502,66],{"emptyLinePlaceholder":65},[40,2504,2505,2507,2510,2512,2514,2516,2518,2520,2522,2524,2526,2528,2530,2533],{"class":42,"line":176},[40,2506,846],{"class":126},[40,2508,2509],{"class":76},"(handle_event({",[40,2511,2299],{"class":298},[40,2513,204],{"class":76},[40,2515,2304],{"class":298},[40,2517,345],{"class":76},[40,2519,2309],{"class":298},[40,2521,204],{"class":76},[40,2523,1347],{"class":126},[40,2525,345],{"class":76},[40,2527,2315],{"class":298},[40,2529,204],{"class":76},[40,2531,2532],{"class":126},"20",[40,2534,2535],{"class":76},"}))\n",[40,2537,2538,2540,2542,2544,2546,2548,2550,2552,2554,2557,2559,2561,2563,2566],{"class":42,"line":181},[40,2539,846],{"class":126},[40,2541,2509],{"class":76},[40,2543,2299],{"class":298},[40,2545,204],{"class":76},[40,2547,2404],{"class":298},[40,2549,345],{"class":76},[40,2551,2409],{"class":298},[40,2553,204],{"class":76},[40,2555,2556],{"class":126},"800",[40,2558,345],{"class":76},[40,2560,2415],{"class":298},[40,2562,204],{"class":76},[40,2564,2565],{"class":126},"600",[40,2567,2535],{"class":76},[40,2569,2570,2572,2574,2576,2578,2580,2582,2584,2586,2588,2590,2592,2594,2596,2598],{"class":42,"line":187},[40,2571,846],{"class":126},[40,2573,2509],{"class":76},[40,2575,2299],{"class":298},[40,2577,204],{"class":76},[40,2579,2404],{"class":298},[40,2581,345],{"class":76},[40,2583,2409],{"class":298},[40,2585,204],{"class":76},[40,2587,1387],{"class":72},[40,2589,1083],{"class":126},[40,2591,345],{"class":76},[40,2593,2415],{"class":298},[40,2595,204],{"class":76},[40,2597,2565],{"class":126},[40,2599,2535],{"class":76},[1005,2601,2603],{"id":2602},"matching-classes-structurally","Matching classes structurally",[28,2605,2606],{"language":30},[32,2607,2609],{"className":34,"code":2608,"language":30,"meta":36,"style":36},"from dataclasses import dataclass\n\n@dataclass\nclass Point:\n    x: int\n    y: int\n\ndef describe(point):\n    match point:\n        case Point(x=0, y=0):\n            return \"Origin\"\n        case Point(x=0, y=y):\n            return f\"On the Y-axis at {y}\"\n        case Point(x=x, y=0):\n            return f\"On the X-axis at {x}\"\n        case Point(x=x, y=y) if x == y:\n            return \"On the diagonal\"\n        case Point():\n            return \"Somewhere else\"\n        case _:\n            return \"Not a point\"\n\nprint(describe(Point(0, 0)))     # Origin\nprint(describe(Point(3, 3)))       # On the diagonal\nprint(describe(Point(0, 5)))         # On the Y-axis at 5\n",[19,2610,2611,2621,2625,2629,2638,2646,2653,2657,2667,2674,2697,2704,2725,2742,2763,2780,2809,2816,2823,2830,2836,2843,2847,2866,2885],{"__ignoreMap":36},[40,2612,2613,2615,2617,2619],{"class":42,"line":43},[40,2614,73],{"class":72},[40,2616,77],{"class":76},[40,2618,80],{"class":72},[40,2620,83],{"class":76},[40,2622,2623],{"class":42,"line":50},[40,2624,66],{"emptyLinePlaceholder":65},[40,2626,2627],{"class":42,"line":56},[40,2628,184],{"class":110},[40,2630,2631,2633,2636],{"class":42,"line":62},[40,2632,107],{"class":72},[40,2634,2635],{"class":110}," Point",[40,2637,195],{"class":76},[40,2639,2640,2643],{"class":42,"line":69},[40,2641,2642],{"class":76},"    x: ",[40,2644,2645],{"class":126},"int\n",[40,2647,2648,2651],{"class":42,"line":86},[40,2649,2650],{"class":76},"    y: ",[40,2652,2645],{"class":126},[40,2654,2655],{"class":42,"line":99},[40,2656,66],{"emptyLinePlaceholder":65},[40,2658,2659,2661,2664],{"class":42,"line":104},[40,2660,267],{"class":72},[40,2662,2663],{"class":110}," describe",[40,2665,2666],{"class":76},"(point):\n",[40,2668,2669,2671],{"class":42,"line":123},[40,2670,327],{"class":72},[40,2672,2673],{"class":76}," point:\n",[40,2675,2676,2678,2681,2683,2685,2687,2689,2691,2693,2695],{"class":42,"line":136},[40,2677,336],{"class":72},[40,2679,2680],{"class":76}," Point(",[40,2682,2333],{"class":1250},[40,2684,216],{"class":72},[40,2686,1382],{"class":126},[40,2688,345],{"class":76},[40,2690,2342],{"class":1250},[40,2692,216],{"class":72},[40,2694,1382],{"class":126},[40,2696,120],{"class":76},[40,2698,2699,2701],{"class":42,"line":146},[40,2700,1109],{"class":72},[40,2702,2703],{"class":298}," \"Origin\"\n",[40,2705,2706,2708,2710,2712,2714,2716,2718,2720,2722],{"class":42,"line":156},[40,2707,336],{"class":72},[40,2709,2680],{"class":76},[40,2711,2333],{"class":1250},[40,2713,216],{"class":72},[40,2715,1382],{"class":126},[40,2717,345],{"class":76},[40,2719,2342],{"class":1250},[40,2721,216],{"class":72},[40,2723,2724],{"class":76},"y):\n",[40,2726,2727,2729,2731,2734,2736,2738,2740],{"class":42,"line":166},[40,2728,1109],{"class":72},[40,2730,2325],{"class":72},[40,2732,2733],{"class":298},"\"On the Y-axis at ",[40,2735,644],{"class":126},[40,2737,2342],{"class":76},[40,2739,650],{"class":126},[40,2741,2391],{"class":298},[40,2743,2744,2746,2748,2750,2752,2755,2757,2759,2761],{"class":42,"line":176},[40,2745,336],{"class":72},[40,2747,2680],{"class":76},[40,2749,2333],{"class":1250},[40,2751,216],{"class":72},[40,2753,2754],{"class":76},"x, ",[40,2756,2342],{"class":1250},[40,2758,216],{"class":72},[40,2760,1382],{"class":126},[40,2762,120],{"class":76},[40,2764,2765,2767,2769,2772,2774,2776,2778],{"class":42,"line":181},[40,2766,1109],{"class":72},[40,2768,2325],{"class":72},[40,2770,2771],{"class":298},"\"On the X-axis at ",[40,2773,644],{"class":126},[40,2775,2333],{"class":76},[40,2777,650],{"class":126},[40,2779,2391],{"class":298},[40,2781,2782,2784,2786,2788,2790,2792,2794,2796,2799,2801,2804,2806],{"class":42,"line":187},[40,2783,336],{"class":72},[40,2785,2680],{"class":76},[40,2787,2333],{"class":1250},[40,2789,216],{"class":72},[40,2791,2754],{"class":76},[40,2793,2342],{"class":1250},[40,2795,216],{"class":72},[40,2797,2798],{"class":76},"y) ",[40,2800,455],{"class":72},[40,2802,2803],{"class":76}," x ",[40,2805,1101],{"class":72},[40,2807,2808],{"class":76}," y:\n",[40,2810,2811,2813],{"class":42,"line":198},[40,2812,1109],{"class":72},[40,2814,2815],{"class":298}," \"On the diagonal\"\n",[40,2817,2818,2820],{"class":42,"line":210},[40,2819,336],{"class":72},[40,2821,2822],{"class":76}," Point():\n",[40,2824,2825,2827],{"class":42,"line":225},[40,2826,1109],{"class":72},[40,2828,2829],{"class":298}," \"Somewhere else\"\n",[40,2831,2832,2834],{"class":42,"line":239},[40,2833,336],{"class":72},[40,2835,2491],{"class":76},[40,2837,2838,2840],{"class":42,"line":259},[40,2839,1109],{"class":72},[40,2841,2842],{"class":298}," \"Not a point\"\n",[40,2844,2845],{"class":42,"line":264},[40,2846,66],{"emptyLinePlaceholder":65},[40,2848,2849,2851,2854,2856,2858,2860,2863],{"class":42,"line":295},[40,2850,846],{"class":126},[40,2852,2853],{"class":76},"(describe(Point(",[40,2855,1382],{"class":126},[40,2857,345],{"class":76},[40,2859,1382],{"class":126},[40,2861,2862],{"class":76},")))     ",[40,2864,2865],{"class":46},"# Origin\n",[40,2867,2868,2870,2872,2875,2877,2879,2882],{"class":42,"line":302},[40,2869,846],{"class":126},[40,2871,2853],{"class":76},[40,2873,2874],{"class":126},"3",[40,2876,345],{"class":76},[40,2878,2874],{"class":126},[40,2880,2881],{"class":76},")))       ",[40,2883,2884],{"class":46},"# On the diagonal\n",[40,2886,2887,2889,2891,2893,2895,2897,2900],{"class":42,"line":319},[40,2888,846],{"class":126},[40,2890,2853],{"class":76},[40,2892,1382],{"class":126},[40,2894,345],{"class":76},[40,2896,1314],{"class":126},[40,2898,2899],{"class":76},")))         ",[40,2901,2902],{"class":46},"# On the Y-axis at 5\n",[1005,2904,2906],{"id":2905},"sequence-patterns-with-unpacking-and-the-rest","Sequence patterns with unpacking and \"the rest\"",[28,2908,2909],{"language":30},[32,2910,2912],{"className":34,"code":2911,"language":30,"meta":36,"style":36},"def process_command(parts):\n    match parts:\n        case []:\n            return \"empty command\"\n        case [cmd]:\n            return f\"run {cmd} with no args\"\n        case [cmd, *args] if cmd == \"echo\":\n            return \" \".join(args)\n        case [\"move\", x, y]:\n            return f\"move to {x}, {y}\"\n        case [cmd, *_]:\n            return f\"unrecognized command: {cmd}\"\n\nprint(process_command([\"echo\", \"hello\", \"world\"]))   # hello world\nprint(process_command([\"move\", 3, 4]))                 # move to 3, 4\nprint(process_command([]))                               # empty command\n",[19,2913,2914,2924,2931,2938,2945,2952,2971,2996,3006,3018,3043,3054,3071,3075,3101,3124],{"__ignoreMap":36},[40,2915,2916,2918,2921],{"class":42,"line":43},[40,2917,267],{"class":72},[40,2919,2920],{"class":110}," process_command",[40,2922,2923],{"class":76},"(parts):\n",[40,2925,2926,2928],{"class":42,"line":50},[40,2927,327],{"class":72},[40,2929,2930],{"class":76}," parts:\n",[40,2932,2933,2935],{"class":42,"line":56},[40,2934,336],{"class":72},[40,2936,2937],{"class":76}," []:\n",[40,2939,2940,2942],{"class":42,"line":62},[40,2941,1109],{"class":72},[40,2943,2944],{"class":298}," \"empty command\"\n",[40,2946,2947,2949],{"class":42,"line":69},[40,2948,336],{"class":72},[40,2950,2951],{"class":76}," [cmd]:\n",[40,2953,2954,2956,2958,2961,2963,2966,2968],{"class":42,"line":86},[40,2955,1109],{"class":72},[40,2957,2325],{"class":72},[40,2959,2960],{"class":298},"\"run ",[40,2962,644],{"class":126},[40,2964,2965],{"class":76},"cmd",[40,2967,650],{"class":126},[40,2969,2970],{"class":298}," with no args\"\n",[40,2972,2973,2975,2978,2981,2984,2986,2989,2991,2994],{"class":42,"line":99},[40,2974,336],{"class":72},[40,2976,2977],{"class":76}," [cmd, ",[40,2979,2980],{"class":72},"*",[40,2982,2983],{"class":76},"args] ",[40,2985,455],{"class":72},[40,2987,2988],{"class":76}," cmd ",[40,2990,1101],{"class":72},[40,2992,2993],{"class":298}," \"echo\"",[40,2995,195],{"class":76},[40,2997,2998,3000,3003],{"class":42,"line":104},[40,2999,1109],{"class":72},[40,3001,3002],{"class":298}," \" \"",[40,3004,3005],{"class":76},".join(args)\n",[40,3007,3008,3010,3012,3015],{"class":42,"line":123},[40,3009,336],{"class":72},[40,3011,1186],{"class":76},[40,3013,3014],{"class":298},"\"move\"",[40,3016,3017],{"class":76},", x, y]:\n",[40,3019,3020,3022,3024,3027,3029,3031,3033,3035,3037,3039,3041],{"class":42,"line":136},[40,3021,1109],{"class":72},[40,3023,2325],{"class":72},[40,3025,3026],{"class":298},"\"move to ",[40,3028,644],{"class":126},[40,3030,2333],{"class":76},[40,3032,650],{"class":126},[40,3034,345],{"class":298},[40,3036,644],{"class":126},[40,3038,2342],{"class":76},[40,3040,650],{"class":126},[40,3042,2391],{"class":298},[40,3044,3045,3047,3049,3051],{"class":42,"line":146},[40,3046,336],{"class":72},[40,3048,2977],{"class":76},[40,3050,2980],{"class":72},[40,3052,3053],{"class":76},"_]:\n",[40,3055,3056,3058,3060,3063,3065,3067,3069],{"class":42,"line":156},[40,3057,1109],{"class":72},[40,3059,2325],{"class":72},[40,3061,3062],{"class":298},"\"unrecognized command: ",[40,3064,644],{"class":126},[40,3066,2965],{"class":76},[40,3068,650],{"class":126},[40,3070,2391],{"class":298},[40,3072,3073],{"class":42,"line":166},[40,3074,66],{"emptyLinePlaceholder":65},[40,3076,3077,3079,3082,3085,3087,3090,3092,3095,3098],{"class":42,"line":176},[40,3078,846],{"class":126},[40,3080,3081],{"class":76},"(process_command([",[40,3083,3084],{"class":298},"\"echo\"",[40,3086,345],{"class":76},[40,3088,3089],{"class":298},"\"hello\"",[40,3091,345],{"class":76},[40,3093,3094],{"class":298},"\"world\"",[40,3096,3097],{"class":76},"]))   ",[40,3099,3100],{"class":46},"# hello world\n",[40,3102,3103,3105,3107,3109,3111,3113,3115,3118,3121],{"class":42,"line":181},[40,3104,846],{"class":126},[40,3106,3081],{"class":76},[40,3108,3014],{"class":298},[40,3110,345],{"class":76},[40,3112,2874],{"class":126},[40,3114,345],{"class":76},[40,3116,3117],{"class":126},"4",[40,3119,3120],{"class":76},"]))                 ",[40,3122,3123],{"class":46},"# move to 3, 4\n",[40,3125,3126,3128,3131],{"class":42,"line":187},[40,3127,846],{"class":126},[40,3129,3130],{"class":76},"(process_command([]))                               ",[40,3132,3133],{"class":46},"# empty command\n",[14,3135,3137],{"id":3136},"tips-tricks","💡 Tips & Tricks",[3139,3140,3141,3157,3188,3202,3225],"ul",{},[3142,3143,3144,3150,3151,3153,3154,3156],"li",{},[1159,3145,3146,3149],{},[19,3147,3148],{},"for...else"," for search loops eliminates flag variables"," — anywhere you'd write ",[19,3152,1795],{}," before a loop just to check it after, reach for ",[19,3155,3148],{}," instead; it reads as \"did I search everything without finding it.\"",[3142,3158,3159,3168,3169,3172,3173,3175,3176,3180,3181,3184,3185,1166],{},[1159,3160,3161,3164,3165,3167],{},[19,3162,3163],{},"case _:"," must be last, and a bare name in ",[19,3166,25],{}," always matches (and binds!) — not compares"," — ",[19,3170,3171],{},"case x:"," (no literal, no structure) always matches and binds the value to ",[19,3174,2333],{},"; to match against an existing variable's ",[3177,3178,3179],"em",{},"value",", use a dotted name or guard: ",[19,3182,3183],{},"case value if value == existing_var:"," or ",[19,3186,3187],{},"case SomeEnum.MEMBER:",[3142,3189,3190,3199,3200,1166],{},[1159,3191,3192,3195,3196,3198],{},[19,3193,3194],{},"itertools.zip_longest"," avoids ",[19,3197,1408],{},"'s silent truncation"," — whenever mismatched-length inputs should be an explicit case (padding or erroring), don't reach for the builtin ",[19,3201,1408],{},[3142,3203,3204,3210,3211,345,3214,3217,3218,3221,3222,3224],{},[1159,3205,3206,3209],{},[19,3207,3208],{},"sorted(..., key=...)"," beats writing manual comparison loops"," — most \"loop to find the max\u002Fmin\u002Fsorted order\" code is better expressed with ",[19,3212,3213],{},"max(items, key=...)",[19,3215,3216],{},"min(items, key=...)",", or ",[19,3219,3220],{},"sorted(items, key=...)"," than a hand-rolled ",[19,3223,1149],{}," loop.",[3142,3226,3227,3241,3242,3244],{},[1159,3228,3229,3230,3232,3233,3235,3236,3232,3238,3240],{},"Guard clauses (",[19,3231,455],{}," inside ",[19,3234,25],{},") let you avoid deeply nested ",[19,3237,455],{},[19,3239,25],{}," bodies"," — keep matching logic flat by pushing conditions into the ",[19,3243,25],{}," line itself.",[14,3246,3248],{"id":3247},"️-edge-cases-gotchas","⚠️ Edge Cases & Gotchas",[3139,3250,3251,3287,3296,3323,3348],{},[3142,3252,3253,3168,3259,3262,3263,3266,3267,3270,3271,3274,3275,3278,3279,3282,3283,3286],{},[1159,3254,3255,3256,3258],{},"A bare name pattern in ",[19,3257,21],{}," always matches and shadows — it never compares to an existing variable",[19,3260,3261],{},"case status:"," inside a ",[19,3264,3265],{},"match status:"," block does NOT mean \"matches if status equals status\" (that's a no-op tautology anyway) — more subtly, ",[19,3268,3269],{},"case some_variable:"," where ",[19,3272,3273],{},"some_variable"," was defined ",[3177,3276,3277],{},"outside"," the match block still just binds a new local, it does not compare against the outer variable's value. Use ",[19,3280,3281],{},"case value if value == some_variable:"," or wrap in ",[19,3284,3285],{},"case SomeClass.CONSTANT:"," (dotted\u002Fattribute patterns compare, bare names bind).",[3142,3288,3289,3295],{},[1159,3290,3291,3294],{},[19,3292,3293],{},"zip()"," silently truncates to the shortest iterable — no error, no warning"," — a length mismatch between two lists you expected to be equal-length produces quietly wrong output rather than a crash, which makes it a debugging trap in data-pipeline code.",[3142,3297,3298,3168,3311,3314,3315,3318,3319,3322],{},[1159,3299,3300,3303,3304,3307,3308,3310],{},[19,3301,3302],{},"range(start, stop)"," never includes ",[19,3305,3306],{},"stop",", and negative steps require ",[19,3309,3306],{}," to be reachable in the negative direction",[19,3312,3313],{},"range(5, 0)"," (no step) is an ",[3177,3316,3317],{},"empty"," range, not an error and not a descending range — you must pass ",[19,3320,3321],{},"range(5, 0, -1)"," explicitly to count down.",[3142,3324,3325,3335,3336,3338,3339,3341,3342,3344,3345,3347],{},[1159,3326,3327,22,3329,3331,3332,3334],{},[19,3328,878],{},[19,3330,1149],{}," ",[19,3333,1590],{}," is one of the most misread pieces of syntax in the language"," — many experienced developers coming from other languages assume ",[19,3337,1590],{}," on a loop means \"if the loop body never executed\" (like an empty-collection check); it actually means \"if the loop was not exited via ",[19,3340,1014],{},",\" which is a materially different condition especially for loops with zero iterations (the ",[19,3343,1590],{}," still runs in that case, since no ",[19,3346,1014],{}," occurred).",[3142,3349,3350,3168,3356,3359,3360,3363],{},[1159,3351,3352,3353,3355],{},"Mutating a list while iterating over it with a ",[19,3354,1149],{}," loop skips elements",[19,3357,3358],{},"for x in lst: if cond: lst.remove(x)"," silently skips every other matching element, because removal shifts subsequent elements into the position the iterator has already passed. Iterate over a copy (",[19,3361,3362],{},"for x in lst[:]:",") or build a new list via a comprehension instead.",[14,3365,3367],{"id":3366},"spot-the-bug","🧠 Spot the Bug",[1152,3369,3370],{},"What does this print?",[28,3372,3373],{"language":30},[32,3374,3376],{"className":34,"code":3375,"language":30,"meta":36,"style":36},"def find_negative(numbers):\n    for n in numbers:\n        if n \u003C 0:\n            result = \"found a negative\"\n            break\n    else:\n        result = \"all non-negative\"\n    return result\n\nprint(find_negative([]))\nprint(find_negative([1, 2, 3]))\nprint(find_negative([1, -2, 3]))\n",[19,3377,3378,3388,3399,3411,3421,3425,3431,3441,3448,3452,3459,3479],{"__ignoreMap":36},[40,3379,3380,3382,3385],{"class":42,"line":43},[40,3381,267],{"class":72},[40,3383,3384],{"class":110}," find_negative",[40,3386,3387],{"class":76},"(numbers):\n",[40,3389,3390,3392,3394,3396],{"class":42,"line":50},[40,3391,1637],{"class":72},[40,3393,913],{"class":76},[40,3395,1183],{"class":72},[40,3397,3398],{"class":76}," numbers:\n",[40,3400,3401,3403,3405,3407,3409],{"class":42,"line":56},[40,3402,1095],{"class":72},[40,3404,913],{"class":76},[40,3406,563],{"class":72},[40,3408,952],{"class":126},[40,3410,195],{"class":76},[40,3412,3413,3416,3418],{"class":42,"line":62},[40,3414,3415],{"class":76},"            result ",[40,3417,216],{"class":72},[40,3419,3420],{"class":298}," \"found a negative\"\n",[40,3422,3423],{"class":42,"line":69},[40,3424,1713],{"class":72},[40,3426,3427,3429],{"class":42,"line":86},[40,3428,1718],{"class":72},[40,3430,195],{"class":76},[40,3432,3433,3436,3438],{"class":42,"line":99},[40,3434,3435],{"class":76},"        result ",[40,3437,216],{"class":72},[40,3439,3440],{"class":298}," \"all non-negative\"\n",[40,3442,3443,3445],{"class":42,"line":104},[40,3444,753],{"class":72},[40,3446,3447],{"class":76}," result\n",[40,3449,3450],{"class":42,"line":123},[40,3451,66],{"emptyLinePlaceholder":65},[40,3453,3454,3456],{"class":42,"line":136},[40,3455,846],{"class":126},[40,3457,3458],{"class":76},"(find_negative([]))\n",[40,3460,3461,3463,3466,3468,3470,3472,3474,3476],{"class":42,"line":146},[40,3462,846],{"class":126},[40,3464,3465],{"class":76},"(find_negative([",[40,3467,1083],{"class":126},[40,3469,345],{"class":76},[40,3471,1342],{"class":126},[40,3473,345],{"class":76},[40,3475,2874],{"class":126},[40,3477,3478],{"class":76},"]))\n",[40,3480,3481,3483,3485,3487,3489,3491,3493,3495,3497],{"class":42,"line":156},[40,3482,846],{"class":126},[40,3484,3465],{"class":76},[40,3486,1083],{"class":126},[40,3488,345],{"class":76},[40,3490,1387],{"class":72},[40,3492,1342],{"class":126},[40,3494,345],{"class":76},[40,3496,2874],{"class":126},[40,3498,3478],{"class":76},[3500,3501,3502,3506,3540],"details",{},[3503,3504,3505],"summary",{},"Answer",[1152,3507,3508,3509,345,3512,345,3514,3517,3518,3521,3522,3524,3525,3527,3528,3530,3531,3533,3534,3536,3537,3539],{},"Prints ",[19,3510,3511],{},"all non-negative",[19,3513,3511],{},[19,3515,3516],{},"found a negative",". The first case surprises many readers: an ",[1159,3519,3520],{},"empty list"," never executes the loop body at all, so ",[19,3523,1014],{}," never runs — and since the ",[19,3526,1590],{}," clause's condition is precisely \"the loop finished without ",[19,3529,1014],{},",\" it fires even though the loop body ran zero times. ",[19,3532,3148],{},"'s ",[19,3535,1590],{}," is not an \"if nothing matched after searching\" clause in the intuitive sense — it is purely \"no ",[19,3538,1014],{}," occurred,\" and a loop over an empty (or already-satisfied-before-entry) iterable trivially satisfies that.",[1152,3541,3542,204,3545,3533,3547,3549,3550,3552],{},[1159,3543,3544],{},"The lesson",[19,3546,3148],{},[19,3548,1590],{}," fires whenever a ",[19,3551,1014],{}," statement did not execute, including when the loop body never ran — treat it as \"no-break\", not as \"search exhausted with a non-trivial search.\"",[14,3554,3556],{"id":3555},"key-takeaways","Key Takeaways",[3139,3558,3559,3582,3597,3610,3624],{},[3142,3560,3561,3562,3564,3565,22,3567,22,3570,3572,3573,3576,3577,22,3579,3581],{},"Python has no ",[19,3563,2064],{},"\u002Fternary in the C sense — use ",[19,3566,455],{},[19,3568,3569],{},"elif",[19,3571,1590],{},", the ",[19,3574,3575],{},"x if cond else y"," conditional expression, or (3.10+) ",[19,3578,21],{},[19,3580,25],{}," for structural matching.",[3142,3583,3584,3586,3587,3590,3591,3593,3594,3596],{},[19,3585,1149],{}," iterates over iterables, not indices — use ",[19,3588,3589],{},"enumerate()"," for index+value and ",[19,3592,3293],{}," for parallel iteration (remembering ",[19,3595,1408],{}," silently truncates to the shortest input).",[3142,3598,3599,22,3601,3603,3604,3606,3607,3609],{},[19,3600,1149],{},[19,3602,878],{}," loops support an ",[19,3605,1590],{}," clause that runs unless a ",[19,3608,1014],{}," occurred — useful for search loops, but easy to misread as \"loop found nothing.\"",[3142,3611,3612,22,3614,3616,3617,3620,3621,3623],{},[19,3613,21],{},[19,3615,25],{}," does structural destructuring (dicts, sequences, classes via ",[19,3618,3619],{},"__match_args__","), not just value comparison — a bare name in a ",[19,3622,25],{}," always binds, it never compares against an outer variable.",[3142,3625,3626],{},"Never mutate a list while iterating over it directly — iterate a copy or build a new collection instead.",[3628,3629,3630],"style",{},"html pre.shiki code .sdCPZ, html code.shiki .sdCPZ{--shiki-default:#6A737D;--shiki-github-dark:#6A737D}html pre.shiki code .svdQ7, html code.shiki .svdQ7{--shiki-default:#D73A49;--shiki-github-dark:#F97583}html pre.shiki code .ssxIu, html code.shiki .ssxIu{--shiki-default:#24292E;--shiki-github-dark:#E1E4E8}html pre.shiki code .sIsaT, html code.shiki .sIsaT{--shiki-default:#6F42C1;--shiki-github-dark:#B392F0}html pre.shiki code .snvgF, html code.shiki .snvgF{--shiki-default:#005CC5;--shiki-github-dark:#79B8FF}html pre.shiki code .sJ6F3, html code.shiki .sJ6F3{--shiki-default:#032F62;--shiki-github-dark:#9ECBFF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .github-dark .shiki span {color: var(--shiki-github-dark);background: var(--shiki-github-dark-bg);font-style: var(--shiki-github-dark-font-style);font-weight: var(--shiki-github-dark-font-weight);text-decoration: var(--shiki-github-dark-text-decoration);}html.github-dark .shiki span {color: var(--shiki-github-dark);background: var(--shiki-github-dark-bg);font-style: var(--shiki-github-dark-font-style);font-weight: var(--shiki-github-dark-font-weight);text-decoration: var(--shiki-github-dark-text-decoration);}html pre.shiki code .sCrzJ, html code.shiki .sCrzJ{--shiki-default:#E36209;--shiki-github-dark:#FFAB70}",{"title":36,"searchDepth":50,"depth":50,"links":3632},[3633,3635,3640,3645,3647,3654,3655,3656,3657],{"id":16,"depth":50,"text":3634},"Production State Machine with match\u002Fcase (3.10+)",{"id":875,"depth":50,"text":3636,"children":3637},"while Loops",[3638],{"id":1007,"depth":56,"text":3639},"while True with break — the idiomatic \"loop until condition found inside\"",{"id":1146,"depth":50,"text":3641,"children":3642},"for Loops — Iterating, Not Counting",[3643],{"id":1404,"depth":56,"text":3644},"Iterating multiple sequences together with zip",{"id":1581,"depth":50,"text":3646},"break, continue, and the Rarely-Known else on Loops",{"id":2040,"depth":50,"text":3648,"children":3649},"Structural Pattern Matching — match \u002F case (3.10+)",[3650,3651,3652,3653],{"id":2072,"depth":56,"text":2073},{"id":2264,"depth":56,"text":2265},{"id":2602,"depth":56,"text":2603},{"id":2905,"depth":56,"text":2906},{"id":3136,"depth":50,"text":3137},{"id":3247,"depth":50,"text":3248},{"id":3366,"depth":50,"text":3367},{"id":3555,"depth":50,"text":3556},"md",{},"\u002Fpython\u002F04-control-flow",{"title":5,"description":36},"python\u002F04-control-flow","1Zh2YCwGY3gD4H9Fm33R_9nrLG3pwoWWLOWribC5CzQ",1789924651311]