{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "![Python with Birds](images/python_with_Birds.gif)*Coding freedom*" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# คำสั่งวนลูปในภาษาไพธอน (Loops in Python)\n", "\n", "**20** minutes\n", "\n", "\n", " **วัตถุประสงค์**\n", "\n", "\n", " หลังจากทำทำแล็บ นศ.จะสามารถ \n", "\n", "\n", "* เขียนคำสั่งวนลูป (Loop) ในภาษาไพธอน (for-loop & while-loop) ได้\n", "\n", "**Ref:**\n", "\n", "* https://docs.python.org/3/reference/compound_stmts.html\n", "* https://realpython.com/python-while-loop/\n", "\n", "\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## คำสั่งวนลูป (Loop)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Range\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "ในบางครั้งเราอาจต้องการรันโค้ดเดิมซ้ำหลายๆ ครั้ง เราเรียกว่า การวนลูปหรือการวนซ้ำ (Loop) \n", "\n", "คำสั่งที่สามารถควบคุมโปรแกรมให้ทำงานซ้ำๆ ในเงื่อนไขที่กำหนดและเพิ่มความสามารถในการเขียนโปรแกรมมี 2 คำสั่ง คือ for Loop และ while Loop\n", "\n", "\n", "ก่อนที่เราจะไปเขียนคำสั่ง for Loop เรามาดูฟังก์ชัน range( ) กันก่อน เนื่องจากในภาษา Python เรามักจะใช้ฟังก์ชัน range( ) กับคำสั่ง for Loop ในการวนอ่านค่าออบเจ็คของตัวเลข (ดู Note)\n", "\n", "**ฟังก์ชัน range( )** เป็น built-in ฟังก์ชัน** ใช้สำหรับสร้างออบเจ็คของตัวเลขที่มีการเรียงลำดับและไม่สามารถเปลี่ยนค่าได้ (Immutable sequence type)\n", "\n", "เช่น ตัวเลขเรียงลำดับ (เพิ่มขึ้นที่ละ 1) 0, 1, 2, 3, 4, 5 หรือตัวเลขเรียงลำดับแบบก้าวกระโดด 3, 6, 9, 12 มีทั้งไปทาง + และ - ตามระบบเส้นจำนวนจริง (ดังนั้น 2, 1, 0, -1, -2 ก็ได้)\n", "\n", "เราสามารถเรียกฟังก์ชัน range( ) ได้ 3 วิธี ดังนี้\n", "\n", "1. range(stop) รับหนึ่งอาร์กิวเมนต์\n", "2. range(start, stop) รับสองอาร์กิวเมนต์\n", "3. range(start, stop, step) รับสามอาร์กิวเมนต์\n", "\n", "โดยที่อาร์กิวเมนต์ทั้ง start, stop, step ต้องเป็นเลขจำนวนจริง\n", "\n", "**วิธีที่ 1** รับหนึ่งอาร์กิวเมนต์ : จะเป็นชุดตัวเลขที่เริ่มจาก 0 (เสมอ) แล้วเพิ่มทีละ 1 จนถึง stop-1 (ไม่รวมเลขที่เป็น stop) เช่น range(9): 0, 1, 2, 3, ..., 7, 8 (ทั้งหมด 9 (9-0) ตัวเลข)\n", "\n", "**วิธีที่ 2** รับสองอาร์กิวเมนต์ : จะเป็นชุดตัวเลขที่เริ่มจากเลข start แล้วเพิ่มทีละ 1 จนถีง stop-1 (ไม่รวมเลขที่เป็น stop) เช่น range(1, 9): 1, 2, 3, ..., 7, 8 (ทั้งหมด 8 (9-1) ตัวเลข)\n", "\n", "**วิธีที่ 3** รับสามอาร์กิวเมนต์ : จะเป็นชุดตัวเลขที่เริ่มจากเลข start แล้วเพิ่มทีละ step ... (แต่ไม่รวมเลข stop) เช่น range(1, 9, 2): 1, 3, 5, 7 (ทั้งหมด 4 ตัวเลข)\n", "\n", "\n", "\n", "** ตามข้อเท็จจริงแล้ว range ไม่ได้เป็นฟังก์ชัน แต่เป็นคอนสตรัคเตอร์ (Constructor)*1 [Ranges](https://docs.python.org/3/library/stdtypes.html#typesseq-range)\n", "\n", "รายการของ Built-in functions in Python3 : https://docs.python.org/3/library/functions.html\n", "\n" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "range(0, 10)" ] }, "execution_count": 1, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Use the range\n", "\n", "range(10)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "![](images/range.png)\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "***NOTE:*** \n", "\n", "range(10) กับ range(0,10) ได้ผลลัพธ์เหมือนกัน (เนื่องจากดีฟอลต์เริ่มที่ 0)\n", "\n", "ค่าส่งกลับของฟังก์ชัน range() ไม่ใช่ list แต่เป็น...." ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "range" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# range() is a type in Python! \n", "type(range(3))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "```{note}\n", "อาร์กิวเมนต์ที่ส่งให้ฟังก์ชัน ```range()``` ต้องเป็นเลขจำนวนเต็ม (int) เสมอ \n", "```" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "ename": "TypeError", "evalue": "'float' object cannot be interpreted as an integer", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", "Cell \u001b[0;32mIn [3], line 2\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[38;5;66;03m# Try calling range() with a float and see what happens\u001b[39;00m\n\u001b[0;32m----> 2\u001b[0m \u001b[38;5;28;43mrange\u001b[39;49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m10.3\u001b[39;49m\u001b[43m)\u001b[49m\n", "\u001b[0;31mTypeError\u001b[0m: 'float' object cannot be interpreted as an integer" ] } ], "source": [ "# Try calling range() with a float and see what happens\n", "range(10.3)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**เราสามารถใช้คอนสตรัคเตอร์ (Constructor)*1 list( ) แปลง range( ) ให้เป็น List ได้**\n", "\n", "\n", "**Syntax :**\n", "\n", "list([iterable*2])\n", "\n", "*1 คอนสตรัคเตอร์ (Constructor) ในภาษาอื่น ๆ (C++ , JAVA หรือ C#) จะหมายถึงเมธอดที่มีชื่อเดียวกันกับคลาส แต่ในภาษา Python จะหมายถึง ฟังก์ชันที่ทำงานเมื่อมีการเรียกใช้งาน class โดยอยู่ในฟังก์ชัน ____init____ เพื่อกำหนดค่าเริ่มต้นให้กับออบเจ็กต์ที่ถูกสร้างจากคลาส คอนสตรัคเตอร์จะทำงานอัตโนมัติเมื่อมีการสร้างอ็อปเจ็คขึ้นมา\n", "\n", "\n", "*2Iterable คือ อ็อบเจกต์ใดๆ ที่เราสามารถทำการวนซ้ำกับมันได้ เช่น range, lists, dictionaries, tuples หรือแม้แต่ strings ก็เป็น Iterable (ข้อมูลประเภท collection/containers เป็น Iterable)\n", "\n", "([iterable กับ iterator ต่างกัน](https://realpython.com/python-for-loop/))" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# How range works in Python?\n", "\n", "# empty range\n", "print(list(range(0)))\n", "\n", "# using range(stop)\n", "print(list(range(10)))\n", "\n", "# using range(start, stop, step)\n", "print(list(range(1, 10, 2)))\n", "\n", "# using range(start, (neg)stop, (neg)step)\n", "print(list(range(1, -10, -2)))\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "เข้าถึงสมาชิกใน range( ) ได้โดยใช้เลขดัชนีอาร์เรย์เหมือน Lists" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "9" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Access items in a range() by index, just as you would with a list\n", "range(10)[-1]" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "range(0, 4)" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "range(10)[0:4]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### คำสั่ง for Loop" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "คำสั่ง for loop เป็นคำสั่งวนซ้ำที่ใช้ควบคุมการทำงานซ้ำๆ ในจำนวนรอบที่แน่นอน\n", "\n", "\n", "รูปแบบของการใช้งานคำสั่ง for loop ในภาษา Python\n", "\n", "**For Syntax:**\n", "```python\n", "for in :\n", " \n", "```\n", "โดย in เป็นโอเปอร์เรตอร์ (Membership operators) สำหรับตรวจสอบว่าค่าหรือตัวแปร < var > อยู่ใน < iterable > หรือไม่ ถ้าเป็นจริง (**True**) ก็จะทำการรันโค้ดบรรทัดใหม่ที่เยื้องเข้าไปหลัง colon ใน **Block-for-loop (บล็อกของโค้ด-for-loop)** โดยจะทำการรันวนซ้ำๆ จนกว่าเงื่อนไข ( < var> in < iterable > ) จะเป็นเท็จ (**False**)\n", "\n", "\n", "ถ้าเราต้องการรัน 10 ครั้ง เราจะเขียนโค้ด\n", "ในกรณีภาษา C \n", "```C\n", "for (i = 0; i < 10; i++){\n", " \n", "}\n", "```\n", "\n", "ในกรณีภาษา Python\n", "```python\n", "for i in range(10):\n", " \n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Membership operators\n", "in และ not in เป็น Membership operators ใน Python\n", "\n", "ตามชื่อของโอเปอร์เรตอร์ in ใช้ตรวจสอบว่าค่าหรือตัวแปรหรือออบเจ็กต์นั้นๆ เป็นส่วนประกอบหรือเป็นสมาชิกใน Iterable (เช่น ข้อมูลประเภท Container (string, list, tuple, set และ dictionary) ฯลฯ) หรือไม่ ส่วนโอเปอร์เรตอร์ not in ก็ทำงานตรงกันข้ามกับโอเปอร์เรตอร์ in \n", "\n", "\n", " \n", " \n", "\n", " \n", " \n", "\n", " \n", " \n", "
OperatorMeaningExample
inTrue if value/variable is found in the sequence5 in x
not inTrue if value/variable is not found in the sequence5 not in x
\n", "\n", "[Python Operators](https://www.programiz.com/python-programming/operators)\n", "\n", "ตัวอย่างการใช้โอเปอร์เรตอร์ in แสดงได้ดังต่อไปนี้" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "Note: \n", "for ของไพธอนจะต่างจากภาษาอื่นเล็กน้อย กล่าวคือ แทนที่จะใช้ตัวนับซึ่งเป็นตัวเลขในการวนรอบ ไพธอนกลับใช้ข้อมูลที่มีลำดับ เช่น สตริงก์ ลิสต์ หรือทูเปิล แทน\n", "
" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "True\n", "True\n", "True\n", "False\n" ] } ], "source": [ "# Example: Membership operators in Python\n", "x = 'Hello world'\n", "y = {1:'a',2:'b'}\n", "\n", "# Output: True\n", "print('H' in x)\n", "\n", "# Output: True\n", "print('hello' not in x)\n", "\n", "# Output: True\n", "print(1 in y)\n", "\n", "# Output: False ***\n", "print('a' in y)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "----------" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "ถ้าต้องการเขียนภาษาซีให้แสดงตัวเลขจาก 0, 1,...ถึง 9 โค้ดจะเป็นดังนี้\n", "\n", "```C\n", "#include \n", "\n", "int main() {\n", " int i;\n", " for(i=0;i<10;i++){\n", " printf(\"%d \\n\",i);\n", " } \n", " return 0;\n", "}\n", "```\n", "ลองเขียนโค้ดภาษาไพธอน โดยใช้คำสั่ง range ดู\n" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [], "source": [ "# For loop\n", "# Write your code below. Don't forget to press Shift+Enter to execute the cell\n", "\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
Click here for the solution\n", "\n", "```python\n", "for i in range(10):\n", " print(i)\n", " \n", "```\n", "\n", "
\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "----------" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "ถ้าเราต้องการลูปข้อมูลใน List (การ **Iterate List**) เช่น พิมพ์ทุกสมาชิกที่อยู่ใน List ออกหน้าจอ เราสามารถทำได้หลายวิธี\n", "\n", "**วิธีที่ 1: ใช้ฟังก์ชัน range( )**\n" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1982\n", "1980\n", "1973\n" ] } ], "source": [ "# For loop example\n", "\n", "dates = [1982,1980,1973]\n", "N = len(dates)\n", "for i in range(N):\n", " print(dates[i]) " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "โค้ดที่เยื้องเข้าไปจะถูกรัน N ครั้ง ในแต่ละครั้งที่รัน ค่าของ i จะเพิ่มขึ้นทีละ 1 และรันคำสั่ง print( ) ดังแสดงในรูป\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "![](images/LoopsForRange.gif)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "เขียนให้สั้นลง ได้ดังนี้" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1982\n", "1980\n", "1973\n" ] } ], "source": [ "# For loop example\n", "\n", "dates = [1982,1980,1973]\n", "\n", "for i in range(len(dates)):\n", " print(dates[i]) " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**แต่!** ในกรณีของ List ซึ่งเป็นอ็อบเจกต์ *iterable* เราสามารถเข้าถึงสมาชิกได้โดยตรง\n", "\n", "**วิธีที่ 2: ใช้โอเปอเรเตอร์ in** เข้าถึงโดยตรง" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1982\n", "1980\n", "1973\n" ] } ], "source": [ "# Exmaple of for loop, loop through list\n", "\n", "for year in dates: \n", " print(year) " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "ในกรณีนี้ จำนวนครั้งในการรันคำสั่ง print( ) จะเท่ากับจำนวนสมาชิกที่อยู่ใน dates และในการรันแต่ละครั้ง ตัวแปร year จะทำงานเหมือนกับ dates\\[i] ในโค้ดก่อนหน้า\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "![](images/LoopsForList.gif)\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "นอกจากนี้ เรายังสามารถเข้าถึงเลขดัชนี (Index) และค่า (Value) ของสมาชิกของ List ได้โดยใช้ฟังก์ชัน enumerate( )\n", "\n", "**วิธีที่ 3: ใช้ฟังก์ชัน enumerate( )**" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "ฟังก์ชัน enumerate( ) เป็น Built-in function ใช้สำหรับแจกแจงค่า index และข้อมูลที่อิงกับ index (Value) ในรูปแบบ Tuple (Index,Value) โดยต้องใช้กับข้อมูลชนิด list \n", "\n", "ฟังก์ชัน enumerate( ) ส่งค่ากลับในรูปแบบของ Enumerate Object" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[(0, 1982), (1, 1980), (2, 1973)]" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Enumerate Object\n", "\n", "dates = [1982,1980,1973]\n", "\n", "# Enumerate() method adds a counter to an iterable and returns it \n", "# in a form of enumerating object. \n", "enumerate(dates)\n", "\n", "# This enumerated object can then be used directly for loops or \n", "# converted into a list of tuples using the list() function.\n", "list(enumerate(dates)) \n" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Index: 0 , Value: 1982\n", "Index: 1 , Value: 1980\n", "Index: 2 , Value: 1973\n" ] } ], "source": [ "# The enumerate() function allows you to loop over an iterable object and \n", "# keep track of how many iterations have occurred.\n", "# For loop example\n", "\n", "dates = [1982,1980,1973]\n", "\n", "for i,date in enumerate(dates):\n", " print('Index: ', i,', Value: ', date)\n", " " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "____" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "เราสามารถเปลี่ยนค่าของสมาชิกที่อยู่ใน List ได้" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Before square[ 0 ] is red\n", "After square[ 0 ] is white\n", "Before square[ 1 ] is yellow\n", "After square[ 1 ] is white\n", "Before square[ 2 ] is green\n", "After square[ 2 ] is white\n", "Before square[ 3 ] is purple\n", "After square[ 3 ] is white\n", "Before square[ 4 ] is blue\n", "After square[ 4 ] is white\n" ] } ], "source": [ "# Use for loop to change the elements in list\n", "\n", "squares = ['red', 'yellow', 'green', 'purple', 'blue']\n", "\n", "for i in range(0, 5):\n", " print(\"Before square[\", i, '] is', squares[i])\n", " squares[i] = 'white'\n", " print(\"After square[\", i, '] is', squares[i])" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Index: 0 , Value: red\n", "Index: 1 , Value: yellow\n", "Index: 2 , Value: green\n", "Index: 3 , Value: purple\n", "Index: 4 , Value: blue\n" ] } ], "source": [ "# Loop through the list and iterate on both index and element value\n", "\n", "squares=['red', 'yellow', 'green', 'purple', 'blue']\n", "\n", "for i, square in enumerate(squares):\n", " print('Index: ', i,', Value: ', square)\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### การใช้คำสั่ง for เขียนโปรแกรมภายในลิสต์ (List Comprehension)" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "['Michael Jackson', 'Maroon 5']\n" ] } ], "source": [ "artists = [\"Michael Jackson\", \"SPRITE x GUYGEEGEE\", \"Whitney Houston\", \"BNK48\", \"Maroon 5\", \"Bee Gees\"]\n", "\n", "newlist = [] # empty list\n", "\n", "for x in artists:\n", " if \"a\" in x:\n", " newlist.append(x)\n", "\n", "print(newlist)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "เราสามารถเขียนแทนด้วยบรรทัดเดียวได้" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "['Michael Jackson', 'Maroon 5']\n" ] } ], "source": [ "# Using list Comprehension\n", "\n", "artists = [\"Michael Jackson\", \"SPRITE x GUYGEEGEE\", \"Whitney Houston\", \"BNK48\", \"Maroon 5\", \"Bee Gees\"]\n", "\n", "newlist = [x for x in artists if \"a\" in x]\n", "\n", "print(newlist)" ] }, { "cell_type": "markdown", "metadata": { "tags": [] }, "source": [ "
\n", "เมื่อใช้ list comprehension ไม่ต้องมี : หลังคำสั่ง for และหลังคำสั่ง if\n", "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "----" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## คำสั่ง while loop" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "คำสั่ง for loop เป็นคำสั่งวนซ้ำที่ใช้ควบคุมการทำงานซ้ำๆ ในจำนวนรอบที่แน่นอน\n", "แต่ถ้าเราไม่รู้จำนวนรอบล่ะ? \n", "\n", "คำสั่ง while loop เป็นคำสั่งใช้ควบคุมโปรแกรมให้ทำงานบางอย่างซ้ำๆ ในขณะที่เงื่อนไขของลูปนั้นยังคงเป็นจริงอยู่\n", "\n", "รูปแบบของการใช้งานคำสั่ง while loop ในภาษา Python\n", "\n", "**While Syntax:** \n", "\n", "```python\n", "while :\n", " \n", "```\n", "\n", "เราสร้างลูปด้วยคำสั่ง while และตามด้วยเงื่อนไข <expr> ซึ่งเป็นเงื่อนไขที่จะให้โปรแกรมทำงาน โดยโปรแกรมจะตรวจสอบเงื่อนไข <expr> ก่อน ถ้าเงื่อนไขเป็นจริง (**True**) ก็จะทำการรันคำสั่งภายใน **Block-while-loop** ซ้ำๆ จนกว่าเงื่อนไขจะเป็นเท็จ (**False**) ซึ่งถือเป็นการสิ้นสุดการทำงานของลูป\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "สมมติว่าเราต้องการพิมพ์ข้อมูลปีที่อยู่ใน List dates ออกมาซ้ำๆ และให้หยุดเมื่อข้อมูลเป็นปี 1973 เราสามารถเขียนบล็อกของโค้ดได้ต่อไปนี้" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1982\n", "1980\n", "It took 2 repetitions to get out of loop.\n" ] } ], "source": [ "# While Loop Example\n", "\n", "dates = [1982, 1980, 1973, 2000]\n", "\n", "i = 0\n", "year = dates[0]\n", "\n", "while(year != 1973): \n", " print(year)\n", " i = i + 1\n", " year = dates[i]\n", " \n", "\n", "print(\"It took \", i ,\"repetitions to get out of loop.\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "โปรแกรมจะทำงานวนซ้ำๆ จนกว่าเงื่อนไขจะเป็น **False** เป็นการสิ้นสุดการทำงานของลูป ตามรูป" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "![](images/LoopsWhile.gif)\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## คอลัมน์พิเศษ: การใช้วิธีนิวตันในการคำนวณหาคำตอบของสมการ\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "สมการ $f(x) = 0$ เราสามารถหาคำตอบของสมการนี้ได้โดยวิธีง่ายๆ ดังนี้ สมมุติให้กราฟ $y = f(x)$ มีกราฟดังในรูป \n", "\n", "![](images/newton_method.png)\n", "\n", "ขั้นตอนแรกคือเลือกจุดเริ่มต้น $x_o$ โดยการสุ่ม จากนั้นทำการลากเส้นสัมผัสกับกราฟที่จุด $(x_o, f(x_o))$ ให้ตัดกับแกน $x$ สมมุติว่าได้จุดตัดที่ $x_1$ จากนั้นให้ $x_1$ เป็นจุดเริ่มต้น ทำการลากเส้นสัมผัสกับกราฟให้ตัดกับแกน $x$ อีกครั้งโดยจะทำวนอย่างนี้ไปเรื่อยๆก็จะได้รูปคล้ายๆกับฟันเลื่อนดังรูป จากรูปเราสามารถคาดการณ์ได้ว่า ค่าของ $x$ ที่ได้จะเข้าใกล้คำตอบของสมการการ\n", "ค่า $x_i$ หาได้จากค่า $x_{i-1}$ ตามสมาการ\n", "\n", "$$\n", "x_i=x_{i-1}-\\frac{f(x_i)}{f^{'}(x_i)}\n", "$$\n", "\n", "\n", "\n", "ถ้าเขียนโปรแกรมให้มีการประมวลผลที่ดี ก็จะได้ค่าของ $x$ ที่เข้าใกล้คำตอบของสมการ เราเรียกวิธีนี้ว่า Newton method\n" ] }, { "cell_type": "markdown", "metadata": { "tags": [] }, "source": [ "ตามหลักการของ Newton method ข้างต้น ถ้าหากเราเขียนโค้ดตาม flow chart ต่อไปนี้ แล้วรัน" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "![](images/NewtonMethod_FindSquareRoot_with_Error.png)\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "จะเกิดปัญหาอะไรหรือไม่???????? \n", "\n", "ก่อนที่จะรันโค้ด ให้ลองคิดดูก่อน (ว่า จะเกิดปัญหาอะไรหรือไม่)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Calculate the square root using Newton's Method\n", "a = float(input(\">>\"))\n", "x = a\n", "\n", "while (x**2 != a) :\n", " print(x**2 - a)\n", " x = (x + a/x) / 2\n", "\n", "print( \"sqrt(\",a,\") =\", x )\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "ถ้าแก้ใหม่เป็น" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "![](images/NewtonMethod_FindSquareRoot_no_Error.png)\n" ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [ { "name": "stdin", "output_type": "stream", "text": [ ">> 5\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "sqrt( 5.0 ) = 2.236067977499978\n" ] } ], "source": [ "a = float(input(\">>\"))\n", "x = a\n", "\n", "error = 1e-10\n", "\n", "while abs(x**2-a) > error:\n", " x = (x + a/x) / 2\n", "\n", "print( \"sqrt(\",a,\") =\", x )\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## คอลัมน์พิเศษ: หาค่าประมาณของ $\\pi$ ที่ดีกว่า 22/7" ] }, { "cell_type": "code", "execution_count": 21, "metadata": { "tags": [] }, "outputs": [ { "data": { "text/plain": [ "-2.667641894049666e-07" ] }, "execution_count": 21, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from math import pi\n", "pi-22/7\n", "pi-355/113" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": { "tags": [] }, "source": [ "**The magic number: 113355**" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "\n", "![](images/find_pi_113355.png)\n" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "from IPython.core.interactiveshell import InteractiveShell\n", "InteractiveShell.ast_node_interactivity = \"all\"" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "3.141592653589793" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" }, { "data": { "text/plain": [ "3.142857142857143" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from math import pi\n", "pi\n", "22/7" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "355 / 113 = 3.1415929203539825\n" ] } ], "source": [ "from math import pi\n", "\n", "error = 1e-6\n", "n = 22\n", "d = 7\n", "\n", "\n", "while abs(pi-n/d) >= error :\n", " delN = abs(pi - (n+1)/d)\n", " delD = abs(pi - n/(d+1))\n", "\n", " if delN < delD :\n", " n = n + 1\n", " else :\n", " d = d + 1\n", "\n", "print(n,\"/\",d,\"=\",n/d)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## [Exercise] For Loop & While Loop" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "1) จงใช้คำสั่งลูป for พิมพ์เลขจำนวนนับที่อยู่ระหว่าง -5 กับ 5 โดยใช้ฟังก์ชัน range" ] }, { "cell_type": "code", "execution_count": 23, "metadata": {}, "outputs": [], "source": [ "# Write your code below and press Shift+Enter to execute\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "2) จงเขียนโค้ดแสดงสมาชิกที่อยู่ในลิส Genres=\\[ 'rock', 'R\\&B', 'Soundtrack', 'soul', 'pop'] ออกหน้าจอ" ] }, { "cell_type": "code", "execution_count": 24, "metadata": {}, "outputs": [], "source": [ "# Write your code below and press Shift+Enter to execute\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "3) ใช้คำสั่งลูป for พิมพ์สมาชิกที่อยู่ในลิส squares=\\['red', 'yellow', 'green', 'purple', 'blue'] ออกหน้าจอ\n" ] }, { "cell_type": "code", "execution_count": 25, "metadata": {}, "outputs": [], "source": [ "# Write your code below and press Shift+Enter to execute\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "4) จงใช้คำสั่งลูป while แสดงค่าเรตติ้งของอัลบั้มที่เก็บอยู่ในลิส PlayListRatings. โดยกำหนดเงื่อนไขให้ออกจากลูปถ้าค่าเรตติ้งน้อยกว่า 6 และ PlayListRatings = [10, 9.5, 10, 8, 7.5, 5, 10, 10]\n" ] }, { "cell_type": "code", "execution_count": 26, "metadata": {}, "outputs": [], "source": [ "# Write your code below and press Shift+Enter to execute\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "5) จงใช้คำสั่ง while loop ก็อปปี้สตริง 'orange' ที่อยู่ในลิส squares เป็นลิสใหม่ที่ชื่อ new_squares. กำหนดให้ออกจากลูปและหยุดการก็อปปี้ถ้าค่าที่อยู่ในลิสไม่ใช่ 'orange'\n" ] }, { "cell_type": "code", "execution_count": 27, "metadata": {}, "outputs": [], "source": [ "# Write your code below and press Shift+Enter to execute\n", "\n", "squares = ['orange', 'orange', 'purple', 'blue ', 'orange']\n", "new_squares = []\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### คำสั่ง break และคำสั่ง continue (break and continue Statements)\n", "\n", "คำสั่ง break เป็นคำสั่งที่ใช้ร่วมกับคำสั่งวนลูป เมื่อมีการประมวลผลคำสั่ง break โปรแกรมจะออกจากการวนลูปทันที และไปประมวลผลคำสั่งที่อยู่ในลำดับถัดไปจากคำสั่งวนลูป ดังนั้น คำสั่ง break จึงมักถูกกำกับด้วยเงื่อนไขพิเศษบางอย่างเพื่อให้ออกจากลูป ดังแสดงในรูป\n", "\n", "คำสั่ง continue เป็นคำสั่งที่ใช้ร่วมกับคำสั่งวนลูปเช่นเดียวกับคำสั่ง break เมื่อมีการประมวลผลคำสั่ง continue โปรแกรมจะหยุดการทำงานที่จุดนั้น แล้วกลับไปเริ่มวนรอบใหม่ถัดไป ดังนั้น คำสั่ง continue จึงมักถูกกำกับด้วยเงื่อนไขพิเศษบางอย่างเพื่อให้ไปตรวจสอบเงื่อนไขใหม่ ดังแสดงในรูป\n", "\n", "\n", "![](images/break_continue.png0\n", "\n" ] }, { "cell_type": "code", "execution_count": 28, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "4\n", "3\n", "Loop ended.\n" ] } ], "source": [ "# a script demonstrates the break statement\n", "\n", "n = 5\n", "while n > 0:\n", " n -= 1\n", " if n == 2:\n", " break\n", " print(n)\n", " \n", "print('Loop ended.')" ] }, { "cell_type": "code", "execution_count": 29, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "4\n", "3\n", "1\n", "0\n", "Loop ended.\n" ] } ], "source": [ "# a script demonstrates the continue statement\n", "\n", "n = 5\n", "while n > 0:\n", " n -= 1\n", " if n == 2:\n", " continue\n", " print(n)\n", " \n", "print('Loop ended.')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### คำสั่ง pass ( pass Statements)\n", "\n", "คำสั่ง pass เป็นคำสั่งที่ไม่ทำอะไรเลย แต่มีไว้เผื่อเวลาเราวางโครงสร้างโค้ดไว้แล้ว แต่ยังไม่ได้เขียนท่อนนั้น ก็บรรจุคำสั่งนี้ไว้เพื่อให้สามารถทดสอบการรันได้ เช่น\n", "\n", "```python\n", "while True:\n", " pass # Busy-wait for keyboard interrupt\n", "\n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Infinite Loop (Endless Loop)\n", "\n", "การวนลูปที่ไม่มีที่สิ้นสุด\n", "\n", "
\n", "\n", "กดคีย์เพื่อขัดจังหวะ (KeyboardInterrupt): กด Control-C หรือ DEL (Interactive Mode), กด **i** สองครั้ง (Jupyter Nootbook)\n", "
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "```{warning} \n", "กดคีย์เพื่อขัดจังหวะ (KeyboardInterrupt): กด Control-C หรือ DEL (Interactive Mode), กด **i** สองครั้ง (Jupyter Nootbook)\n", "```" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# A while loop that theoretically never ends\n", "# You can press 'I' twice to interrupt the kernel!\n", "# or try 'Ctrl-m i' to interrupts the kernel. (press letter 'i' after Ctrl-m) \n", "\n", "while True:\n", " print('foo')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "---" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "“Everybody should learn to program a computer, because it teaches you how to think\"\" - Steve Jobs 1995" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "---" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Author\n", "\n", "S.C.\n", "\n", "### Change Log\n", "\n", " \n", "| Date | Version | Change Description |\n", "|---|---|---|\n", "| 08-08-2021 | 0.1 | First edition |\n", "| | | |\n", "| | | |\n" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel(3.8.13))", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.8.13" }, "latex_envs": { "LaTeX_envs_menu_present": true, "autoclose": false, "autocomplete": true, "bibliofile": "biblio.bib", "cite_by": "apalike", "current_citInitial": 1, "eqLabelWithNumbers": true, "eqNumInitial": 1, "hotkeys": { "equation": "Ctrl-E", "itemize": "Ctrl-I" }, "labels_anchors": false, "latex_user_defs": false, "report_style_numbering": false, "user_envs_cfg": false }, "toc": { "base_numbering": 1, "nav_menu": {}, "number_sections": true, "sideBar": true, "skip_h1_title": true, "title_cell": "Table of Contents", "title_sidebar": "Contents", "toc_cell": false, "toc_position": {}, "toc_section_display": true, "toc_window_display": false }, "vscode": { "interpreter": { "hash": "e921dbf9f2d20a8528fa054ff97aae3eb23f1abc9a6f29b7bcee4307a5b88bad" } } }, "nbformat": 4, "nbformat_minor": 4 }