{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "b34b4902-51dd-4ca4-92fd-aeda83a66dc0",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "source": [
    "# Python 入門講座　第６回: 残そう,未来のために。\n",
    "\n",
    "今日の目標\n",
    "\n",
    ">ファイルを使って、プログラムの実行結果を記録に残します。またその記録を再利用します。\n",
    ">\n",
    ">  - ファイル　の操作\n",
    ">    - open/close/flush : file mode、 ファイルオブジェクト\n",
    ">    - read/write/readline/readlines/writelines\n",
    ">  - `with` 文\n",
    ">  - `import` 文"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b4dfe676-e85b-46a0-ba6b-c3e30c403d93",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "source": [
    "# そのまえに、前回の質問について\n",
    "前回2つの質問をお尋ねしました。　まずはこの質問について解説しておきます。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ae0bd4ef-0689-4a97-9c64-f1592807202f",
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    },
    "tags": []
   },
   "source": [
    "## ここで質問です。(その1）\n",
    "\n",
    ">ここでクイズです。\n",
    ">``` python\n",
    ">a=100\n",
    ">b=100\n",
    ">```\n",
    ">とした時、\n",
    ">\n",
    ">``` python\n",
    ">print( a == b, a is b, id(a) == id(b))\n",
    ">```\n",
    ">はどんな結果になるでしょう？　結果を予想してから実行してみましょう。\n",
    "\n",
    "実際に実行して見ましょう。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "df0b62e2-733c-4d28-a04b-ed14d6e67528",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "###  予想とあっていましたか？"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "10465d76-5ea4-4238-8122-0e846c8d5887",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\t a=100, b=100,\t(a == b)=True, (a is b)=True, (id(a) == id(b))=True\n"
     ]
    }
   ],
   "source": [
    "a=100\n",
    "b=100+0\n",
    "print(f\"\\t {a=:}, {b=:},\\t{(a == b)=:}, {(a is b)=:}, {(id(a) == id(b))=:}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ae934876-bc8d-4f64-93bc-9025eefbb941",
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "source": [
    "他の値でも試してみましょう。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "8c85210f-5575-49c1-832e-a07529876a28",
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    },
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "i=  100, a=  100,b=  100, (a == b)= True, (a is b)= True, (id(a) == id(b))= True\n",
      "i=  256, a=  256,b=  256, (a == b)= True, (a is b)= True, (id(a) == id(b))= True\n",
      "i=  257, a=  257,b=  257, (a == b)= True, (a is b)= False, (id(a) == id(b))= False\n",
      "i= 1024, a= 1024,b= 1024, (a == b)= True, (a is b)= False, (id(a) == id(b))= False\n"
     ]
    }
   ],
   "source": [
    "for i in (100,256,257,1024):\n",
    "    a=i\n",
    "    b=i+0\n",
    "    print(f\"{i= :4d}, {a= :4d},{b= :4d}, {(a == b)= :}, {(a is b)= :}, {(id(a) == id(b))= :}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d5473beb-49c5-4abf-a0f5-e9e000c2b8e9",
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "source": [
    "Pythonでは256以下の正の整数は特別扱いされています。\n",
    "これらの数値については、インタプリタの初期化時にその数値のオブジェクトが生成／登録されています。\n",
    "(短い文字列についても同様の特別の処理が行われています。）"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "d3a14b2c-292b-4d93-a849-95a4c57ef24e",
   "metadata": {
    "slideshow": {
     "slide_type": "skip"
    },
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "i=  257, a=  257,b=  257, (a == b)= True, (a is b)= False, (id(a) == id(b))= False\n",
      "i=  256, a=  256,b=  256, (a == b)= True, (a is b)= True, (id(a) == id(b))= True\n",
      "i=   20, a=   20,b=   20, (a == b)= True, (a is b)= True, (id(a) == id(b))= True\n",
      "i=    0, a=    0,b=    0, (a == b)= True, (a is b)= True, (id(a) == id(b))= True\n",
      "i=   -5, a=   -5,b=   -5, (a == b)= True, (a is b)= True, (id(a) == id(b))= True\n",
      "i=   -6, a=   -6,b=   -6, (a == b)= True, (a is b)= False, (id(a) == id(b))= False\n"
     ]
    }
   ],
   "source": [
    "for i in reversed((-6,-5,0,20,256,257)):\n",
    "    a=i\n",
    "    b=i+0\n",
    "    print(f\"{i= :4d}, {a= :4d},{b= :4d}, {(a == b)= :}, {(a is b)= :}, {(id(a) == id(b))= :}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8a0506f7-869f-4bc8-8119-0d600dfae5ec",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "### 変数への値の代入（PythonとC/C++の比較)\n",
    "\n",
    "「変数へ値を代入する」、「変数の値を更新する」といった操作の意味はプログラム言語によって\n",
    "若干の違いがあります。ここではPythonとC/C++言語を例に、これらの操作を図解してみました。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "33e4de27-996f-4697-aefc-c9bfcd5ddb5b",
   "metadata": {},
   "source": [
    "|　C/C++　の代入|　Pythonの代入|\n",
    "|:---:|:---:|\n",
    "|![Cの代入](_images/C-assignment.png)|　![Pythonの代入](_images/python-assignment.png) |"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9d45fcb8-1891-4a7d-8ddc-7f6b05d1a01e",
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "source": [
    "C/C++言語などの伝統的なプログラム言語では、変数名はデータを保持する実体(メモリ）につけられています。この関係は、プログラムの実行中に変わることはありません。\n",
    "\n",
    "それに対して、Pythonなどのインタプリタ型言語などでは、変数名はデータの実体を参照する際に使われます。\n",
    "変数名と参照される実体との関係はプログラムの実行に従って変わっていきます。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fdaa23c2-393f-412a-a0df-a1ea4c001ecd",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    },
    "tags": []
   },
   "source": [
    "## ここで質問です。(その2）\n",
    "\n",
    "\n",
    ">`((r:=1) or (r:=r+2)) and (r:=r+4)`\n",
    ">\n",
    ">および\n",
    ">\n",
    ">`(r:=1) and (r:=r+2)) or (r:=r+4)`\n",
    ">\n",
    ">の結果はそれぞれ何になりますか？\n",
    "\n",
    "試してみましょう。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "73567707-b264-4949-a059-20b615bb9f9c",
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "((r:=1) or (r:=r+2)) and (r:=r+4) = 5\n",
      "((r:=1) and (r:=r+2)) or (r:=r+4) = 3\n"
     ]
    }
   ],
   "source": [
    "print(f\"{((r:=1) or (r:=r+2)) and (r:=r+4) = :}\")\n",
    "print(f\"{((r:=1) and (r:=r+2)) or (r:=r+4) = :}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ce1b8f80-0a20-496e-a89f-de13770ddbe6",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    },
    "tags": []
   },
   "source": [
    "### 式の評価の様子を一ステップ毎に見ていきましょう。\n",
    "\n",
    "``` python\n",
    "((r:=1) or (r:=r+2)) and (r:=r+4)　\n",
    "```\n",
    "Pythonは式を左から見て行って、評価の必要な項から順次評価を進めます。\n",
    "最初の代入式で`r`は 1 に設定され、代入式の値自体も 1 になります。\n",
    "\n",
    "``` python\n",
    "(1 or (r:=r+2)) and (r:=r+4)\n",
    "```\n",
    "ここで、`(1 or (r:=r+2))`の論理式としては`True`であることが確定しますから、`(r:=r+2)`を計算する必要はありません。\n",
    "従って、`r`は1のままです。 \n",
    "\n",
    "``` python\n",
    "1 and (r:=1+4)\n",
    "```\n",
    "この式の値は、`r:=1+4`の値が必要です。この式の値は `1+4`つまり`5`で、同時に`r`の値も5となります。\n",
    "\n",
    "``` python \n",
    "1 and 5 \n",
    "5\n",
    "```\n",
    "\n",
    "ということで、`((r:=1) or (r:=r+2)) and (r:=r+4)`の値は 5 となります。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5aa11282-b1a3-43e4-8ed8-9c4bfe520d36",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    },
    "tags": []
   },
   "source": [
    "### 次に第二の式をみてみましょう。\n",
    "``` python\n",
    "((r:=1) and (r:=r+2)) or (r:=r+4)\n",
    "\n",
    "(　1 and (r:=1+2)) or (r:=r+4)\n",
    "\n",
    "(　1 and 3) or (r:=3+4)\n",
    "\n",
    "3 or　(r:=3+4) # 第2項(r:=3+4)は評価の必要なし,rは3のまま\n",
    "\n",
    "3 \n",
    "``` \n",
    "と評価がすすみ、`((r:=1) and (r:=r+2)) or (r:=r+4)`の値は3となりました。\n",
    "\n",
    "`or`演算子の右側の項は、評価されない(実行されない）可能性があるということです。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "dee65b76-1fd8-4843-83a3-439ef76e5dac",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "練習として、\n",
    "\n",
    "``` python\n",
    "print(f\"{((r:=0) or (r:=r+2)) and (r:=r+4) = :}\")\n",
    "print(f\"{((r:=0) and (r:=r+2)) or (r:=r+4) = :}\")\n",
    "```\n",
    "\n",
    "を考えてみましょう。\n",
    "\n",
    "答えは、...."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "41d0adc2-6cfb-45ae-9e09-7797baa4140d",
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "((r:=0) or  (r:=r+2)) and (r:=r+4) = 6\n",
      "((r:=0) and (r:=r+2)) or  (r:=r+4) = 4\n"
     ]
    }
   ],
   "source": [
    "print(f\"{((r:=0) or  (r:=r+2)) and (r:=r+4) = :}\")\n",
    "print(f\"{((r:=0) and (r:=r+2)) or  (r:=r+4) = :}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fa8796ee-cf6c-4631-a015-c0358764c901",
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "source": [
    "となりました。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "97a9723c-901d-4388-9f4f-e63fb76ef355",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    },
    "tags": []
   },
   "source": [
    "# 今日の目標\n",
    "\n",
    "Pythonでのファイルの取り扱いの基礎を学びます。　\n",
    "\n",
    "- 計算結果のファイルへの保存: \n",
    "   - `open` / `.close` / `.write` / `.writelines`\n",
    "   - `with`文\n",
    "    \n",
    "- 保存したデータを再び読み込む：\n",
    "  - `.reaad`/`.readline`/`.readlines`"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "642eb50a-8d42-4ce3-93f7-a3a3fbdb7d78",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## ファイル内容の表示\n",
    "シェルコマンド　`cat` を使えば、ファイルの中身を端末に印刷することができます。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "ac0349b7-ea24-4281-89d0-f48fd26402ef",
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "あのイーハトーヴォの\n",
      "すきとおった風、\n",
      "夏でも底に冷たさをもつ青いそら、\n",
      "うつくしい森で飾られたモリーオ市、\n",
      "郊外のぎらぎらひかる草の波。\n"
     ]
    }
   ],
   "source": [
    "!cat sample.txt"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a2427fbb-c3cd-4801-b757-febe667dbd02",
   "metadata": {
    "slideshow": {
     "slide_type": "notes"
    }
   },
   "source": [
    "Notes:\n",
    "\n",
    "[「ポラーノの広場」宮沢賢治　からの引用](https://www.aozora.gr.jp/cards/000081/files/1935_19925.html)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b8df5e05-117c-43e6-b055-2b892895fcd4",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "### pythonによる　 \"cat\" プログラム\n",
    "この`cat`と同じように、ファイルの中身を端末に印刷するプログラムを作ってみます。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "98803e93-74c1-4091-bdce-c2a6a0a06df4",
   "metadata": {},
   "outputs": [],
   "source": [
    "def ファイル内容の表示(fn:str=\"sample.txt\"):\n",
    "    print(\"ファイル:{0:s}の内容\\n\".format(fn))\n",
    "    with open(fn,mode=\"rt\") as fin:\n",
    "        for line in fin:\n",
    "            print(line,end=\"\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3531cd7f-8cfa-40a3-83ee-54112d568e2c",
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "source": [
    "早速実行してみましょう。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "808ae8cb-e7c3-4366-93ce-fcaf7d14bd31",
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "ファイル:sample.txtの内容\n",
      "\n",
      "あのイーハトーヴォの\n",
      "すきとおった風、\n",
      "夏でも底に冷たさをもつ青いそら、\n",
      "うつくしい森で飾られたモリーオ市、\n",
      "郊外のぎらぎらひかる草の波。\n"
     ]
    }
   ],
   "source": [
    "ファイル内容の表示(\"sample.txt\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f14af716-9dc2-44bc-b80f-3125c3541320",
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "source": [
    "`cat`コマンドと同じ様に、ファイルの中身が印刷されました。\n",
    "プログラムの中身を順番にみて行きましょう。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b95f375b-c6d6-48d0-b65d-a699b23d9cbd",
   "metadata": {
    "slideshow": {
     "slide_type": "notes"
    }
   },
   "source": [
    "Note:\n",
    "\n",
    "``` python\n",
    "def cat(fn:str=\"sample.txt\"):\n",
    "    print(\"ファイル:{0:s}の内容\\n\".format(fn))\n",
    "     with open(fn,mode=\"rt\") as fin:\n",
    "         for line in fin:\n",
    "             print(line,end=\"\")\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "95345f05-a8f2-481a-bd84-ab17ebee5ab9",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "### ファイルを開く : `open(fn,mode=\"rt\")`\n",
    "\n",
    "\n",
    "プログラム中でファイルを使うに、まずファイルを開きます。\n",
    "pythonプログラム中で、ファイルを開くには`open()`関数を使います。\n",
    "`open()`関数には、開くファイルのファイル名と、ファイルの使い方を示す`mode`を与えます。\n",
    "``` python\n",
    "fin=open(\"sample.txt\",mode=\"rt\")\n",
    "```\n",
    "は、\"sample.txt\"という名前のファイルを, 読み出し用(`r`)のテキストファイル(`t`)として開きます。\n",
    "開いたファイルは`open`が返すオブジェクト　`fin`　を通じて操作（`.read/.write`などがある）をします。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "62a196ae-e5be-447c-adc6-a110eaa7a625",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "####  open関数のモード\n",
    "\n",
    "|文字 | 意味 |\n",
    "|--:| :--|\n",
    "|'r'|読み込み用に開く (デフォルト)|\n",
    "|'w'|書き込み用に開き、まずファイルを切り詰める|\n",
    "|'a'|書き込み用に開き、ファイルが存在する場合は末尾に追記する|\n",
    "|'x'|排他的に生成して開く、ファイルが存在する場合は失敗する|\n",
    "|'b'|バイナリモード|\n",
    "|'t'|テキストモード (デフォルト)|\n",
    "|'+'|ファイル内容の更新 (読み書き)|\n",
    "\n",
    "`w+`と`r+`の違いは オープンした時に内容が切り詰められる(`w+`）か内容に追加(`r+`)かの違いがある。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9b2e4821-7f69-4101-8bd9-dff78c9d894d",
   "metadata": {
    "slideshow": {
     "slide_type": "notes"
    }
   },
   "source": [
    "Notes::\n",
    "別のプログラムによって、ファイルを書き換えられないようにロックするには、\n",
    "\n",
    " 1. os.open関数を使う。\n",
    " 2. fcntl.lockfあるいは　fcntl.flock関数 を使う。\n",
    " \n",
    "といった方法があります。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9611f130-1728-43bb-a55e-a0f2ff7c38a7",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "#### モード指定(r/a/w)による違い\n",
    "ファイル オープン時の　モード指定 (`r/a/w/x`)によるopen直後の読み書き位置とファイル内容の違いを図で示します。\n",
    "\n",
    "![](./_images/file-open-mode.png)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5c9cd0f9-1d37-4735-8056-f97e0085179b",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "### ファイルを閉じる `.close()`\n",
    "ファイルを使い終わったら、ファイルを閉じる`.close()`ことが ***必要*** です。\n",
    "さもないと、せっかく書き込んだデータが失われるかもしれません。\n",
    "\n",
    "### `with`文を使って,自動的に、ファイルを閉じる。: `with open(fn,mode=\"rt\") as fin:`\n",
    "\n",
    "ファイルを使い終わった時に、ファイルが確実に閉じられるように次の構文(`with`文）を使います。\n",
    "\n",
    "``` python\n",
    "with open(fn,mode=\"r\") as fin:\n",
    "    ...　# finを通じてファイルの操作(read/writeなど）を行う。\n",
    "    ...\n",
    "\n",
    "... # ここに到達すると ファイル fin は閉じられている。\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1e5758bc-f1c9-4d72-a9d7-4b0c594f86d6",
   "metadata": {
    "slideshow": {
     "slide_type": "notes"
    }
   },
   "source": [
    "Note:\n",
    "\n",
    ">`.close()` メソッドを使って、明示的にファイルを閉じることもできますが、　閉じ忘れを避けるために、\n",
    "`with`文の使用をお勧めします。\n",
    ">\n",
    ">``` python\n",
    ">fin=open(\"sample.txt\",mode=\"rt\")\n",
    ">...\n",
    ">fin.close()\n",
    ">```\n",
    "\n",
    ">プログラムが正常に終了した場合には、計算機システムが適切に終了処理を行います。\n",
    ">\n",
    ">停電を含む異常な状況で終了した場合には、終了処理（close処理）が適切に行われない場合があります。\n",
    "プログラム中では、ファイルを開いておく必要がなくなれば、閉じておくことが推奨されます。\n",
    "`with`文はその振る舞いをより簡潔にしてくれるプログラム言語の機能です。\n",
    ">\n",
    ">`with`文はファイルだけでは、コンテキストマネージャと呼ばれる機能を持つオブジェクトに対して、利用することができます。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d900b043-8917-4302-ba7a-eb895ece39cb",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "### ファイルの中身を順番に読む\n",
    "ファイルの中身を「一行毎に読み込んで、処理する」\n",
    "には、`for`文を次の形で使います。\n",
    "\n",
    "``` python\n",
    "for line in fin:\n",
    "            print(line,end=\"\")\n",
    "```\n",
    "\n",
    "行の終わりは、`\\n`, `\\r\\n` `\\r` のいずれでも対応します(Universal newlines).\n",
    "読み込んだ行末のEOL(End of Line)は\"\\n\"となっています。　(newline 引数を指定することで、変更可能です。）"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f20f9392-2fc8-44de-8eea-a1b02b07c8fc",
   "metadata": {
    "slideshow": {
     "slide_type": "notes"
    }
   },
   "source": [
    "Notes:\n",
    "\n",
    ">ファイルオブジェクトの `.readlines()`メソッドや、`.readline()`メソッド\n",
    "を使ったほぼ等価なプログラムも可能です。\n",
    ">\n",
    ">``` python\n",
    ">for line in fin.readlines():\n",
    ">    ...\n",
    ">\n",
    ">```\n",
    ">あるいは\n",
    ">``` python\n",
    ">while (line:=fin.readline()):\n",
    ">    ...\n",
    ">\n",
    ">```\n",
    ">\n",
    ">しかしながら、大きなファイルを読み込む場合には、最初の方法が**読みやすさ**/メモリ効率/実行時間 の面から有利です。\n",
    "\n",
    "\n",
    "> newlineオプション\n",
    "> ファイルをオープンする際にnewlineオプションを指定することで、EOL文字の取り扱いが変わります。\n",
    ">- 入力：\n",
    ">  - newline=None (default) : ユニバーサル改行モードが有効になります。入力中の行は '\\n', '\\r', または '\\r\\n' で終わり、呼び出し元に返される前に '\\n' に変換されます。\n",
    ">  - newline='' (空文字列)　： ユニバーサル改行モードは有効になりますが、行末は変換されずに呼び出し元に返されます。\n",
    ">  - newline= '\\n', '\\r', '\\r\\n'のいずれかの場合:入力行は与えられた文字列でのみ終わり、行末は変換されずに呼び出し元に返されます。\n",
    ">- 出力：\n",
    ">   - newline=None (default) :出力文字列中の全ての '\\n' 文字はシステムのデフォルトの行セパレータ os.linesep に変換されます\n",
    ">   - newline='' (空文字列) または　'\\n' : 行末文字は変換されません\n",
    ">   - newline = '\\r' または　'\\r\\n' : 出力文字列中の全ての '\\n' 文字は与えられた文字列に変換されます。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9b22e085-0252-453f-8336-c337eb408ade",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "### 別の方法(1): 一行ずつ読む。\n",
    "歴史的な事情もあり、推奨の方法以外にも行毎の処理を行う方法がpythonには存在します。\n",
    "\n",
    "ここで、それらの方法も紹介しますが、\n",
    "明確な理由(例えば、古いバージョンのPythonしか使えないとか）がない限り、\n",
    "推奨の方法を使うのが良いでしょう。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "53eee5f8-1c52-4951-93ab-0a9a6c8cde04",
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [],
   "source": [
    "def ファイル内容の表示F(fn=\"sample.txt\"):\n",
    "    print(\"\\nファイル:{}の内容(assign expression)\\n\".format(fn))\n",
    "    with open(fn,mode=\"r\")as fin:\n",
    "        while (line:=fin.readline()): # ファイルから一行分だけを読み込む。 \n",
    "            print(line,end=\"\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "ca7f4fb1-788b-4dc1-ad21-60b9f772e659",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "ファイル:sample.txtの内容(assign expression)\n",
      "\n",
      "あのイーハトーヴォの\n",
      "すきとおった風、\n",
      "夏でも底に冷たさをもつ青いそら、\n",
      "うつくしい森で飾られたモリーオ市、\n",
      "郊外のぎらぎらひかる草の波。\n"
     ]
    }
   ],
   "source": [
    "ファイル内容の表示F()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "00e77b2a-575e-4503-925e-4945c01093bf",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "### 別の方法(2)：まとめて読む。\n",
    "\n",
    "`.readlines()`や`.read()`メソッドを使うと、ファイル中の全てのデータを一気に読み出すことができます。\n",
    "\n",
    "ファイルのサイズが非常に大きい時には、大量のメモリが必要となります。また、全てのデータを\n",
    "読み込むまで、プログラムはそこで待たされることになります。\n",
    "\n",
    "ということで、`.readlines()`や`.read()`は特別な事情がない限り、使わない方が良いでしょう。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "b12515f1-87e7-4ea0-865f-af35aabb1c0e",
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [],
   "source": [
    "def ファイル内容の表示L(fn=\"sample.txt\"):\n",
    "    print(\"\\nファイル:{}の内容(readlines)\\n\".format(fn))\n",
    "    with open(fn,mode=\"r\")as fin:\n",
    "        for line in fin.readlines(): # ファイルの中身を行毎のリストとして読み込む。\n",
    "            print(line,end=\"\")\n",
    "\n",
    "def ファイル内容の表示B(fn=\"sample.txt\"):\n",
    "    print(\"\\nファイル:{}の内容(read)\\n\".format(fn))\n",
    "    print(open(fn,mode=\"r\").read(),end=\"\") #ファイルの内容を一気に読み込む。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "b593de02-239a-4105-b904-5b37ad337296",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "ファイル:sample.txtの内容(readlines)\n",
      "\n",
      "あのイーハトーヴォの\n",
      "すきとおった風、\n",
      "夏でも底に冷たさをもつ青いそら、\n",
      "うつくしい森で飾られたモリーオ市、\n",
      "郊外のぎらぎらひかる草の波。\n",
      "\n",
      "ファイル:sample.txtの内容(read)\n",
      "\n",
      "あのイーハトーヴォの\n",
      "すきとおった風、\n",
      "夏でも底に冷たさをもつ青いそら、\n",
      "うつくしい森で飾られたモリーオ市、\n",
      "郊外のぎらぎらひかる草の波。\n"
     ]
    }
   ],
   "source": [
    "ファイル内容の表示L()\n",
    "ファイル内容の表示B()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bfaeacaf-08bf-4d07-89fa-309da48e96d4",
   "metadata": {
    "slideshow": {
     "slide_type": "notes"
    }
   },
   "source": [
    "Notes::\n",
    "\n",
    "引数付きの`read(n)`はバイナリモードでファイルを取り扱う際には、頻繁に使われるでしょう。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "447c20ec-0406-4d1b-8d14-d4c13cfee957",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "## テキストファイルとバイナリファイル\n",
    "\n",
    "ファイルの本体は全てバイトデータの並びです。その意味では、全てのファイルはバイナリファイルとして読み込めます。\n",
    "\n",
    "テキスト、画像、音声、動画、その他さまざまなデータをそれらのデータ形式に合った形で読み込むことが必要です。\n",
    "\n",
    "`open()`関数では、ファイルの内容がテキストであることがわかっていれば(`t`)\n",
    "エンコーディング（`encoding`)を指定することで、テキスト(ユニコード）として読むために必要な処理をプログラム処理系が行なってくれます。 "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ffabcbc2-94d7-41d8-8f8d-65b4934cdcb9",
   "metadata": {
    "slideshow": {
     "slide_type": "notes"
    }
   },
   "source": [
    "Note:\n",
    "画像／音声／動画などが収められたファイルでは、それらのデータを適切に取り扱うための関数が用意されていることが普通です。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d8335f4a-ce6a-4d7c-9211-c456a1f2a6f8",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "未知のデータファイルあるいは独自に定義されたでーた形式を取り扱うためには、バイナリファイルとして取り扱う必要がありますが、\n",
    "一般ユーザーがそのような場面に遭遇する機会は無くなってきています。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "11e5510d-c451-4ef1-b5af-1074a16ef250",
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "テキスト： あのイーハトーヴォの\n",
      "バイナリ: b'\\xe3\\x81\\x82\\xe3\\x81\\xae\\xe3\\x82\\xa4\\xe3\\x83\\xbc\\xe3\\x83\\x8f\\xe3\\x83\\x88\\xe3\\x83\\xbc\\xe3\\x83\\xb4\\xe3\\x82\\xa9\\xe3\\x81\\xae\\n'\n",
      "デコード： あのイーハトーヴォの\n"
     ]
    }
   ],
   "source": [
    "with open(\"sample.txt\",mode=\"r\",encoding=\"utf-8\") as fin:\n",
    "    print(\"テキスト：\", fin.readline(),end=\"\")\n",
    "    \n",
    "with open(\"sample.txt\",mode=\"rb\") as fin:\n",
    "    line=fin.readline()\n",
    "    print(\"バイナリ:\", line)\n",
    "    print(\"デコード：\", line.decode(\"utf-8\"),end=\"\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0e7be872-3864-4d14-b3c0-ddd09e6f3994",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## ファイルへの出力\n",
    "\n",
    "次に、以前に作成した数表印刷プログラムを元に、数表をファイルに書き出すプログラムを作ってみます。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bb3d63bd-e414-4791-a3cf-8ac713def946",
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "source": [
    "### print文を使った、数表印刷プログラム\n",
    "\n",
    "```python\n",
    "def 数表の印刷():\n",
    "    print (\"フィボナッチ数の数表\".center(66,\"_\"))\n",
    "    print ( \"   {0}\".format(\n",
    "        \",\".join((\"    {0:02d}\".format(c) for c in range(10))))\n",
    "      )\n",
    "    for r in range(0,30,10):\n",
    "        print(\"{0:02d}:{1}\".format(\n",
    "            r,\n",
    "            \",\".join((\"{0:6d}\".format(fib(c)) for c in range(r,r+10)))\n",
    "        ))\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "46cb1b2e-eaed-45af-aaa8-afd1dbf2fa26",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "端末に文字列を書き出す関数`print()`をファイルへの書き出しの関数(メソッド）`.write()`に書き換えればよさそうです。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "856f63f8-7bb5-4f69-a823-0d15c69d01d9",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "____________________________フィボナッチ数の数表____________________________\n",
      "       00,    01,    02,    03,    04,    05,    06,    07,    08,    09\n",
      "00:     1,     1,     2,     3,     5,     8,    13,    21,    34,    55\n",
      "10:    89,   144,   233,   377,   610,   987,  1597,  2584,  4181,  6765\n",
      "20: 10946, 17711, 28657, 46368, 75025,121393,196418,317811,514229,832040\n"
     ]
    }
   ],
   "source": [
    "from fibonacci import fib\n",
    "\n",
    "def 数表の印刷():\n",
    "    print (\"フィボナッチ数の数表\".center(66,\"_\"))\n",
    "    print ( \"   {0}\".format(\n",
    "        \",\".join((\"    {0:02d}\".format(c) for c in range(10))))\n",
    "      )\n",
    "    for r in range(0,30,10):\n",
    "        print(\"{0:02d}:{1}\".format(\n",
    "            r,\n",
    "            \",\".join((\"{0:6d}\".format(fib(c)) for c in range(r,r+10)))\n",
    "        ))\n",
    "数表の印刷()        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "fd59c1c0-c6d7-4a90-91ac-083e7a05b306",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "outputs": [],
   "source": [
    "from fibonacci import fib\n",
    "\n",
    "def 数表の保存0(fn=\"Fibonacci_table.txt\"):                # 第0試作\n",
    "    with open(fn,mode=\"wt\") as fout:                    # 書き出し(w)用にファイルを開く\n",
    "        fout.write(\"フィボナッチ数の数表\".center(66,\"_\"))  # print() -> fout.write()\n",
    "        fout.write ( \"   {0}\".format(\n",
    "            \",\".join((\"    {0:02d}\".format(c) for c in range(10))))\n",
    "          )\n",
    "        for r in range(0,30,10):\n",
    "            fout.write(\"{0:02d}:{1}\".format(\n",
    "                r,\n",
    "                \",\".join((\"{0:6d}\".format(fib(c)) for c in range(r,r+10)))\n",
    "            ))    "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "956acff6-b436-49e9-ac39-972c4d809bfa",
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "source": [
    "試してみましょう。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "bbd8bab4-c5ca-4b70-b6b0-e035cfb7c2d8",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "ファイル:Fibonacci_table.txtの内容\n",
      "\n",
      "____________________________フィボナッチ数の数表____________________________       00,    01,    02,    03,    04,    05,    06,    07,    08,    0900:     1,     1,     2,     3,     5,     8,    13,    21,    34,    5510:    89,   144,   233,   377,   610,   987,  1597,  2584,  4181,  676520: 10946, 17711, 28657, 46368, 75025,121393,196418,317811,514229,832040"
     ]
    }
   ],
   "source": [
    "if __name__ == \"__main__\":\n",
    "    数表の保存0()\n",
    "    ファイル内容の表示(\"Fibonacci_table.txt\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c208c7cc-f5e8-4da5-9e2f-e4149f5dbbaa",
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "source": [
    "数値は表示されましたが、改行されずに一行に出力されてしまいました。\n",
    "\n",
    "`print()`とは異なり、ファイルの`.write()`は**改行を追加してくれません**。\n",
    "明示的に改行コード **\"\\n\"** をファイルに書き込む必要があります。\n",
    "\n",
    "各行を書き出す際に **\"\\n\"** を追加するように書き換えてみます。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "c0b59d9e-9eaf-4724-908f-52f9928c2a72",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "outputs": [],
   "source": [
    "def 数表の保存1(fn=\"Fibonacci_table.txt\"):\n",
    "    with open(fn,mode=\"w\") as fout:\n",
    "        fout.write(\"{0}\\n\".format(                # \\n 追加\n",
    "            \"フィボナッチ数の数表\".center(66,\"_\"))\n",
    "                )\n",
    "        fout.write ( \"   {0}\\n\".format(           # \\n 追加\n",
    "            \",\".join((\"    {0:02d}\".format(c) for c in range(10))))\n",
    "          )\n",
    "        for r in range(0,30,10):\n",
    "            fout.write(\"{0:02d}:{1}\\n\".format(   # \\n 追加\n",
    "                r,\n",
    "                \",\".join((\"{0:6d}\".format(fib(c)) for c in range(r,r+10)))\n",
    "            ))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "58b04d53-4d4d-48db-bb25-e4d896c548f3",
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "source": [
    "試してみましょう"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "5dd8f19f-72d9-4503-859b-307a69fadf8e",
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "ファイル:Fibonacci_table.txtの内容\n",
      "\n",
      "____________________________フィボナッチ数の数表____________________________\n",
      "       00,    01,    02,    03,    04,    05,    06,    07,    08,    09\n",
      "00:     1,     1,     2,     3,     5,     8,    13,    21,    34,    55\n",
      "10:    89,   144,   233,   377,   610,   987,  1597,  2584,  4181,  6765\n",
      "20: 10946, 17711, 28657, 46368, 75025,121393,196418,317811,514229,832040\n"
     ]
    }
   ],
   "source": [
    "数表の保存1() #改良版でファイルに数表書き出し\n",
    "ファイル内容の表示(\"Fibonacci_table.txt\") #ファイルを読み出す"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "83edb92b-cdbf-4c1e-9b31-e56e1fe9d594",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "### `import` 文\n",
    "\n",
    "数表保存のプログラムで使った`fib()`関数は別ファイル\"fibonacci.py\"で定義されています。(次ページを参照）\n",
    "\n",
    "この様に、作成済みのプログラムを`import`文を使って、再利用することができます。 `import`されるブログラムを**モジュール(module)と呼びます。モジュールの利用法の代表的な方法には次の様なものがあります。\n",
    "\n",
    "| インポート法　| 利用法 | 意味 |\n",
    "| :----: | :---:| :---:|\n",
    "|`from  fibonacci import fib` | `print (fib(10))` | モジュール `fibonacci` から `fib`をインポート|\n",
    "|`from  fibonacci import *` | `print (fib(10))` | モジュール `fibonacci` から 全てをインポート|\n",
    "|`import fibonacci` | `print( fibonacci.fib(10)`| モジュール`fibonacci` をインポート|"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cc35df29-9cee-4733-be80-74b77ff76c37",
   "metadata": {
    "slideshow": {
     "slide_type": "notes"
    }
   },
   "source": [
    "Note:\n",
    "\n",
    "モジュール中の関数を利用するためには、\n",
    "\n",
    "``` python\n",
    "from  fibonacci import fib\n",
    "```\n",
    "としてモジュール中の特定の関数をインポートする方法と、\n",
    "\n",
    "``` python\n",
    "from  fibonacci import *\n",
    "```\n",
    "\n",
    "によって、`fibnacci`モジュール中の全ての関数や変数をインポートする方法があります。\n",
    "\n",
    "いずれの場合にも、`fibonacci.py`で定義した関数`fib()`を\n",
    "\n",
    "``` python\n",
    "print ( fib(10) )\n",
    "``` \n",
    "という様に利用することができます。\n",
    "\n",
    "また、\n",
    "\n",
    "``` python\n",
    "import fibonacci\n",
    "```\n",
    "をプログラムの初めに書くことで、`fibonacci.py`で定義した関数`fib()`をそのプログラム中で使うことができます。\n",
    "``` python\n",
    "print( fibonacci.fib(10) )\n",
    "```\n",
    "\n",
    "モジュール名が長い、あるいは深い階層をもったモジュールに別名をつけてインポートすることもできます。\n",
    "\n",
    "``` python\n",
    "import fibonacci as fibm\n",
    "import matplotlib.pyplot as pyplot\n",
    "print( fibm.fib(10))\n",
    "pyplot.plot([fibm.fib(i) for i in range(100)])\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e26038b9-10ae-4625-a33f-1d156d7d1bbb",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "####  fibonacchi.pyの中身\n",
    "`fibonacchi.py`の中身は次のようになっています。\n",
    "``` python\n",
    "#!python3\n",
    "def fib(n:int)->int:\n",
    "    \"\"\"\n",
    "    returns the n-th fibonacci number.\n",
    "    \"\"\"\n",
    "    if n in (0, 1):\n",
    "        return 1\n",
    "    a=b=1 \n",
    "    while (n := n-1 ) > 0:\n",
    "        a, b = a+b, a # a: f_{k}, b:f_{k-1}\n",
    "    return a\n",
    "\n",
    "if __name__ == \"__main__\":\n",
    "    for i in range(10):\n",
    "        print(f\"{i=:}, {fib(i)=:})\n",
    "```\n",
    "\n",
    "\n",
    "`if __name__ == \"__main__\":`以下の部分は`import`の際には実行されません。\n",
    "このモジュールの単独動作確認の際に役立ちます。\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7a09a974-d183-4bba-b646-003ccc355eab",
   "metadata": {
    "slideshow": {
     "slide_type": "notes"
    }
   },
   "source": [
    "Note: モジュールがみつからない！？\n",
    "\n",
    "モジュールとして使いたいファイルは確かに存在するのに、Pythonで`import`するとエラーになる。\n",
    "といった時はPythonのサーチパスを確認しましょう。\n",
    "\n",
    "pythonモジュールのサーチパスは、\n",
    "\n",
    "```python\n",
    "import sys\n",
    "print(sys.path)\n",
    "``` \n",
    "\n",
    "を実行して確認しましょう。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d5e147c6-b0cf-4233-b1d2-719dc7de62f0",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "###  名前の衝突を避けるために、\n",
    "\n",
    "**複数**のモジュールを同時に使う場合、同じ名前の関数名が別モジュールにもある可能性があります。\n",
    "\n",
    "そのような場合には、名前の付け替え(`import-as`)や階層的な名前を使うことで、名前の衝突を避けることができます。\n",
    "\n",
    "#### 名前の付け替え：\n",
    "\n",
    "``` python\n",
    "from  fibonacci import fib as FIB\n",
    "print( FIB(10) )\n",
    "```\n",
    "として、　関数名`FIB`を使います。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "id": "a9f3b939-001e-46b5-a129-80fa4fc6ee8c",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "89\n"
     ]
    }
   ],
   "source": [
    "from  fibonacci import fib as FIB\n",
    "print( FIB(10) )"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3fb7c4f2-86a8-4b96-b817-37ccd050773d",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "source": [
    "#### 階層的な名前：\n",
    "\n",
    "``` python\n",
    "import fibonacci \n",
    "print( fibonacci.fib(10) )\n",
    "```\n",
    "\n",
    "のように、モジュールを`import`した後に、モジュール名と関数名を組み合わせた`fibonacci.fib()`を関数名として使います。\n",
    "\n",
    "モジュール名は　ファイルシステムと同じく階層的な構造を持っていることがあります　（例：.`matplotlib.pyplot`）。\n",
    "\n",
    "```python\n",
    "import matplotlib.pyplot as pyplot\n",
    "pyplot.plot([fib(i) for i in range(0,10)])\n",
    "```\n",
    "\n",
    "この例の様に、深い階層を持つモジュールも`import xxx.yyy.zzz  as nnn`の構文を使うことで、使いやすくなります。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "id": "c8d9bebb-d8f7-4002-95cd-0829156fcb50",
   "metadata": {
    "slideshow": {
     "slide_type": "subslide"
    }
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "import fibonacci \n",
    "import matplotlib.pyplot as pyplot\n",
    "pyplot.plot([fibonacci.fib(i) for i in range(0,10)]);"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c027b5bd-d7da-4a1f-a0d0-14d83f2528bf",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "# 本日のまとめ #\n",
    "\n",
    " 1. ファイルの操作： `open`/`.close`/`.readline`/`.write`\n",
    " 1. with 文 : `with ... as ... :`\n",
    " 1. モジュール(import 文): `import <module>`/`from <mdule> import <name>`\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "26125771-cbe0-4f15-a26a-d4f7f968ffea",
   "metadata": {
    "slideshow": {
     "slide_type": "skip"
    }
   },
   "source": [
    "## この先にあるものは？\n",
    "\n",
    "- ファイルの指定：\n",
    "    path名とファイル名\n",
    "    - os.path モジュール\n",
    "- sys.stdin,sys.stdout,sys.stderr\n",
    "   - print()\n",
    "   - input()\n",
    "- デバイスファイルからの入出力\n",
    "- ネットワーク経由のデータ交換:`socket`\n",
    "- データ保存のためのファイル形式\n",
    "\n",
    "  - jsonファイルを読み書きする。( yaml, pickle, ..)\n",
    "  - csvファイルを読み書きする。\n",
    "  \n",
    "- Binary File/Text File:全てのファイルはもとを辿れば　Binaryファイル\n",
    "    - 全てのファイルはバイトデータが集まったもの。\n",
    "    - Text file: バイトデータをTextと解釈して読み込む。\n",
    "        - encoding: utf-8, sjis, ...\n",
    "    - バイナリデータ：　バイト列データを、数字として読み込んだり、画像として読み込んだり、動画として読み込んだり、... \n",
    "      - array モジュール　、 struct モジュール, numpy\n",
    "    - エクセルファイルを読み書きする。\n",
    "    - ROOT ファイルを読み書きする。  \n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "22d96773-ee3f-4857-b963-fff1f90c354c",
   "metadata": {
    "slideshow": {
     "slide_type": "skip"
    }
   },
   "source": [
    "##`input`/`print`\n",
    "\n",
    "端末(キーボード）からの入力は`sys.stdin.readline`を、端末ディスプレイへの出力は`sys.stdout.write`を使えば実現可能です。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "id": "edd283ca-b743-4c99-b1f7-b86329400afd",
   "metadata": {
    "slideshow": {
     "slide_type": "skip"
    }
   },
   "outputs": [
    {
     "name": "stdin",
     "output_type": "stream",
     "text": [
      "お名前を教えてください： Noboru\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "こんにちは、　Noboruさん。お会いできて光栄です\n",
      "\n"
     ]
    }
   ],
   "source": [
    "name=input(\"お名前を教えてください：\").strip()\n",
    "print(f\"\\nこんにちは、　{name}さん。お会いできて光栄です\\n\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "87158bda-8ba1-4dd6-ac62-f1b48712a80f",
   "metadata": {
    "slideshow": {
     "slide_type": "skip"
    }
   },
   "source": [
    "### stdin/stdout/stderr\n",
    "オープンしたファイルには、ファイル番号が付けられています。\n",
    "例えば、つぎのようになります。\n",
    "\n",
    "``` python\n",
    ">>> open(\"sample.txt\",mode=\"rt\").fileno()\n",
    "3\n",
    "```\n",
    "初めて開いたファイルにも関わらず、0でも1でもなく3になっています。\n",
    "\n",
    "これは、pythonでは0,1,2のファイル番号はそれぞれ `stdin`, `stdout`, `stderr`と呼ばれる三つのファイルが標準入出力として予約されているためです。\n",
    "\n",
    "``` python\n",
    ">>> import sys\n",
    ">>> sys.stdin.fileno(),sys.stdout.fileno(),sys.stderr.fileno(),\n",
    "(0, 1, 2)\n",
    "```\n",
    "端末への入出力はこれらのファイルを使うことで実現できます。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "id": "abf4cebd-e3c2-4657-8734-1fc91b299249",
   "metadata": {
    "slideshow": {
     "slide_type": "skip"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Welcome to Python world.\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "25"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import sys\n",
    "sys.stdout.write(\"Welcome to Python world.\\n\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "id": "5698e850-df02-41c1-be80-6b075190e623",
   "metadata": {
    "slideshow": {
     "slide_type": "skip"
    }
   },
   "outputs": [
    {
     "name": "stdin",
     "output_type": "stream",
     "text": [
      "お名前は？　 Noboru Yamamoto\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "こんにちは、Noboru Yamamoto さん。お会いできて光栄です\n"
     ]
    }
   ],
   "source": [
    "def ask():\n",
    "    name=input(\"お名前は？　\").strip()\n",
    "    print(f\"こんにちは、{name} さん。お会いできて光栄です\")\n",
    "ask()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "id": "8dd49e64-5ffa-4d3a-a0f2-7350937ae776",
   "metadata": {
    "slideshow": {
     "slide_type": "skip"
    }
   },
   "outputs": [],
   "source": [
    "import sys\n",
    "def ask():\n",
    "    sys.stdout.write(\"お名前は？　\")\n",
    "    sys.stdout.flush()\n",
    "    name=sys.stdin.readline().strip()\n",
    "    sys.stdout.write(f\"\\nこんにちは、{name} さん。お会いできて光栄です\\n\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "786f2c76-b163-425e-aeee-9675db00f756",
   "metadata": {
    "slideshow": {
     "slide_type": "skip"
    }
   },
   "source": [
    "jupyter/jupyterlabのノートブックでは`input`と`sys.stdout`の取り扱いが異なるため、\n",
    "スクリプトとして実行した場合と結果が異なります。"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3.9",
   "language": "python",
   "name": "python3.9"
  },
  "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.9.10"
  },
  "toc-autonumbering": false
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
