{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 9. for나 while 루프 뒤에 else 블록을 사용하지 말라"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "파이썬 루프는 내부 블록 바로 다음에 else 블록을 추가할 수 있다."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Loop 0\n",
      "Loop 1\n",
      "Loop 2\n",
      "Else block!\n"
     ]
    }
   ],
   "source": [
    "for i in range(3):\n",
    "    print('Loop', i)\n",
    "else:\n",
    "    print('Else block!')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "루프가 끝나면 실행이된다.\n",
    "\n",
    "if/else는 '이 블록 앞의 블록이 실행되지 않으면 이 블록을 실행하라' 라는 뜻.\n",
    "\n",
    "try/except 문에서 except와 비슷하다."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "try/except/else도 이런 패턴을 따르는데, 여기서 else는 '처리할 예외가 없는 경우 이 블록을 실행하라' 이다.\n",
    "\n",
    "try/finally 도 '앞의 블록을 실행한 다음에는 이 블록을 실행하라'는 뜻이다."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**for/else에서 else가 '루프가 정상적으로 완료되지 않으면 이 블록을 실행하라'라고 이해할 수 있다.**\n",
    "\n",
    "하지만 반대로 동작된다."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Loop 0\n",
      "Loop 1\n"
     ]
    }
   ],
   "source": [
    "for i in range(3):\n",
    "    print('Loop', i)\n",
    "    if i == 1:\n",
    "        break\n",
    "else:\n",
    "    print('Else block!')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "또 놀라운 점은 빈 시퀀스에 대한 루프를 실행하면 else 블록이 바로 실행된다."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "For Else block!\n"
     ]
    }
   ],
   "source": [
    "for x in []:\n",
    "    print('이 줄은 실행되지 않음')\n",
    "else:\n",
    "    print('For Else block!')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "While Else block!\n"
     ]
    }
   ],
   "source": [
    "while False:\n",
    "    print('이 줄은 실행 x')\n",
    "else:\n",
    "    print('While Else block!')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "서로소임을 검사하는 루프"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "검사 중 2\n",
      "검사 중 3\n",
      "검사 중 4\n",
      "서로소\n"
     ]
    }
   ],
   "source": [
    "a = 4\n",
    "b = 9\n",
    "\n",
    "for i in range(2, min(a, b) + 1):\n",
    "    print('검사 중', i)\n",
    "    if a % i == 0 and b % i == 0:\n",
    "        print('서로소 아님')\n",
    "        break\n",
    "else:\n",
    "    print('서로소')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "이러한 방식보다는 도우미 함수를 사용하는 것이 좋음"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "1. 원하는 조건을 찾자마자 빠르게 함수를 반환하는 방식"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "def coprime(a, b):\n",
    "    for i in range(2, min(a, b) + 1):\n",
    "        if a % i == 0 and b % i == 0:\n",
    "            return False\n",
    "    return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [],
   "source": [
    "assert coprime(4, 9)\n",
    "assert not coprime(3, 6)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "2. 루프 안에서 원하는 대상을 찾았는지 나타내는 결과 변수를 도입하는 것"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "def coprime_alternate(a, b):\n",
    "    is_coprime = True\n",
    "    for i in range(2, min(a, b) + 1):\n",
    "        if a % i == 0 and b % i == 0:\n",
    "            is_coprime = False\n",
    "            break\n",
    "    return is_coprime"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "assert coprime_alternate(4, 9)\n",
    "assert not coprime_alternate(3, 6)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 기억해야 할 내용\n",
    "- 파이썬은 for나 while 루프에 속한 블록 바로 뒤에 else 블록을 허용하는 특별한 문법을 제공한다"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "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.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}