$30 off During Our Annual Pro Sale. View Details »

1日で基本が身につく! Python超入門

1日で基本が身につく! Python超入門

私が技術評論社から出版したPythonの入門書をベースとしたトレーニング資料です。
出版元の承諾をえたうえで400P近いスライドにして公開します。
企業の自社研修や大学/社会人の勉強会などに利用してもらって構いませんが、再販などの営利利用はお控えください。
後半にはおまけ資料としてプログラミングのレベルマップとレベル向上法および、駆け出しエンジニア向けにインフラエンジニアの世界をまとめています。

yuichi

May 20, 2020
Tweet

More Decks by yuichi

Other Decks in Programming

Transcript

  1. Python3
    無料トレーニング資料
    (技術評論社公認)
    内容
    • 解説資料(1-2時間) x 8章
    • 演習 x 8章
    • おまけ(プログラミング上達法)
    オリジナルの書籍
    副読本もしくは次のステップにご利⽤ください!!
    Amazon: たった1⽇で基本が⾝に付く! Python超⼊⾨

    View Slide

  2. ⽬次
    はじめに
    Python3をWindowsとMacにインストールしよう
    Pythonでプログラミングを始めよう
    制御構⽂を理解しよう
    関数の使い⽅をマスターしよう
    オブジェクト指向を理解しよう
    クラスの使い⽅をマスターしよう
    モジュールを利⽤しよう
    ファイルの読み書きと例外処理を⾏おう
    アプリケーションを作成しよう
    おまけ。レベル別プログラミングスキル向上法など
    CHAPTER 1
    CHAPTER 2
    CHAPTER 3
    CHAPTER 4
    CHAPTER 5
    CHAPTER 6
    CHAPTER 7
    CHAPTER 8

    View Slide

  3. はじめに
    • この資料は技術評論社より出版されている「たった1⽇で基本
    が⾝に付く! Python超⼊⾨(ISBN978-4-7741-9112-6)」を著者
    (伊藤裕⼀)が出版社の許諾を得てトレーニング資料として公開
    しております。
    • 個⼈だけでなく企業や組織も利⽤できますが、本資料⾃体や改
    変したものを営利⽬的(販売、有償トレーニング)で利⽤するこ
    とは禁⽌いたします。⼤学での講義や社内トレーニングでの利
    ⽤は問題ありませんが、当資料を改変して出⾃を不明にするこ
    とはお控えください。
    • 本資料内で利⽤している図などの著作権は技術評論社及び著者
    に帰属します。本資料外で利⽤することはお控えください。

    View Slide

  4. 皆様へのお願い
    • 書籍を底本として当資料のみでPython3を学べる構成としてお
    りますが、書籍はトレーニング講師の解説に相当する丁寧で詳
    細な説明がされています。
    • 書籍及び当資料の制作にもコストがかかっていますので、オリ
    ジナルの書籍を副読本もしくは本資料を完遂した次の学習ス
    テップとして購⼊頂けると出版社及び著者としては幸いです。
    • Amazon: たった1⽇で基本が⾝に付く! Python超⼊⾨

    View Slide

  5. サンプルファイルのダウンロード
    • 以下のURLより書籍で利⽤しているサンプルファイルをダウン
    ロードできます。
    • 書籍の内容が本スライドと100%同⼀ではないため、使わない
    ファイルやここにないファイルがあることにご留意ください。
    • http://gihyo.jp/book/2017/978-4-7741-9112-6/support

    View Slide

  6. 広告(1): 技術評論社(書籍出版元)
    • DockerとKubernetesの書籍を2020年夏に販売
    • コンテナの基礎に加えて開発技法やコンテナベースアプリケー
    ションのCI/CD環境の構築なども扱う
    書籍表紙絵
    (あとで更新)
    ⽬次
    • Dockerを使ってみよう
    • イメージの利⽤と開発を体験しよう
    • ネットワークとストレージ
    • Dockerfileでイメージ作成しよう
    • Composeを使ってマルチコンテナアプリを作ろう
    • DockerアプリでCI/CDしよう
    • Kubernetes⼊⾨
    • Kubernetesの利⽤

    View Slide

  7. 広告(2): Nutanix(トレーニング資料作成)
    • プライベートクラウドの構築ソフトウェア開発会社
    • AWS類似のクラウドをオンプレミス(⾃社内)に数時間で構築可能
    • ご相談は「https://www.nutanix.com/jp」へ
    • インフラ⾃動化やDevOps系は著者が⽀援可能
    ネットワーク機器
    (L2/L3スイッチ)
    サーバー
    サーバー
    サーバー
    サーバー
    クラスタ(冗⻑化と障害時の⾃動回復)
    簡単な構築作業
    1. サーバーをラックに設置
    2. 物理スイッチにケーブル接続
    3. 構築ツールで⾃動構築
    構築ツール
    (VMアプライアンス)
    GUIでIP設定など
    (約10分)
    アプライアンスがサーバーを検出して
    インストール指⽰後は⾃動で構築(約1時間)
    • ブラウザ管理画⾯(⽇本語)
    • ハイパーバイザー
    • ファイルサーバー
    • ブロックストレージ
    • オブジェクトストレージ
    • バックアップ
    • マネージドKubernetes
    • マネージドデータベース
    • パブリッククラウド連携
    • マイクロセグメンテーション
    • VDI(仮想デスクトップ基盤)
    • 監視、その他
    ほぼフルスタックなクラウド機能
    使いやすい操作画⾯(REST APIサポート)

    View Slide

  8. 著者について
    • Nutanix社のソリューションスペシャリスト(DevOps)。開発 + インフラ屋
    • 得意領域
    • ソフトウェア開発およびDevOps(CI/CD)
    • コンテナとオーケストレーション
    • モダンアプリケーション開発と⾃動化
    • パブリック/プライベートクラウド
    • ネットワーク(L2/L3)
    • サーバー仮想化(VMWare, KVM)
    • サーバーOS(Linux)
    • 略歴(英語): LinkedIn(@yuichiito)
    • 副業で技術書や記事の執筆。企業や⼤学向け技術資料作成をしています
    • 仕事依頼はメールで[email protected]にお願いします
    出版社様へ。中級者を想定したモダンなLinuxの使い⽅の本を書きたいです。
    Twitter(@yuichi110)

    View Slide

  9. WindowsにPython3をインストールする (1/3)
    • WindowsにはPythonはインストールされていない
    • 公式サイト(https://www.python.org/)にアクセスする
    • 「Python3」のインストーラーをダウンロードし起動

    View Slide

  10. WindowsにPython3をインストールする (2/3)
    • インストーラーをブラウザもしくはダブルクリックで起動

    View Slide

  11. WindowsにPython3をインストールする (3/3)
    • インストーラーのガイドにしたがってインストール
    • 「パスを通すにチェックをつける(4)」を忘れないこと

    View Slide

  12. MacにPython3をインストールする
    • Macには標準でPythonがインストールされているが古い(2系)
    • 公式サイトからPython3系のインストーラーを⼊⼿しインス
    トールを実施。ガイドにそってインストール
    • Mac標準のPython2でPython3を想定した本トレーニングのプ
    ログラムは実⾏できない場合が多いのでご注意ください。

    View Slide

  13. Pythonでプログラミングを始めよう
    CHAPTER
    1
    1. プログラミングとPythonについて知る
    2. Pythonで電卓代わりに計算する
    3. 値を格納する「変数」を理解する
    4. データの種類を決める「型」を理解する

    View Slide

  14. プログラミングとPythonについて知る
    • このセクションで学ぶこと
    • プログラムってなに?
    • プログラミング⾔語の存在意義
    • なぜプログラミング⾔語としてPythonを選ぶか
    • コンパイル型とインタプリタ型の⾔語の違い
    SECTION
    01

    View Slide

  15. プログラムはコンピューターへの指令書
    • 「プログラム」は機械に「こう動け」と命令する指令書
    • PCのアプリだけでなく、ブラウザのサービス(検索エンジンや
    ウェブメールなど)も提供会社側でプログラムが動いている
    • プログラムを書くこと「プログラミング」という
    • プログラムのことを「コード」、プログラミングのことを
    「コーディング」ともいう

    View Slide

  16. プログラミング⾔語で機械への命令が簡単に
    • 機械は電気のON/OFF(01の2進数)で状態を管理している
    • 最終的に01で命令を機械に伝える必要があるが、⼈間が01を扱
    うことは難しい
    • プログラミング⾔語は「01しか使えない機械」と「⾃然で曖昧
    な⾔葉を使う⼈間」の間にある「厳格な⽂法の⼈⼯⾔語」
    • ⼈間がプログラミング⾔語で命令を書き、機械がそれを01に変
    換して解釈実⾏する
    ⼈間の領域
    (曖昧)
    機械の領域
    (01)
    プログラミング⾔語

    View Slide

  17. Pythonを選ぶ理由
    • 「なにをやりたいか(⽬的)」に応じて使うプログラミング⾔語
    は変わってくる
    • Pythonは「簡単である(すぐに覚えられる、同じプログラムを
    他の⾔語より素早く書ける)」ことに加えて、「広範囲の開発作
    業に使える」「インタプリタ型」という特徴があるのでおすす

    View Slide

  18. コンパイル型とインタプリタ型の⾔語の違い
    • コンパイル型: プログラミング⾔語から機械語(01)に事前変換
    • インタプリタ型: 実⾏時にプログラミング⾔語から機械語に変換
    • Pythonはインタプリタ型の⾔語
    • インタプリタ型はコンパイルの⼿間(時間)がないので開発が楽

    View Slide

  19. Pythonが苦⼿なこと
    • 超⾼速性が求められるシステムやデスクトップアプリケーション(⼀
    般ユーザー向けの再配布)、組み込み機器の開発が苦⼿。多くのスク
    リプト系⾔語も全く同じ領域が苦⼿
    • ⾼速な処理(科学計算系はライブラリが⾼速なので問題なし)。⼀般
    的にインタプリタ型はコンパイラ型に⽐べると実⾏時にコンパイル
    するので遅い。速度は⾔語より設計やアルゴリズムに起因すること
    が多いので、⾔語の速度はプログラミング上級者になってから気に
    すれば問題なし
    • Pythonがインストールされている環境でPythonアプリを利⽤するこ
    とは簡単だが、Pythonがインストールされていない環境(⼀般ユー
    ザーのPC)で動かすのは不可能ではないものの⼿間がかかる。
    • 組み込み機器のような機械に近いレイアはPythonが使えないことが
    多い 。基本は汎⽤OSの上でPythonを使う

    View Slide

  20. 汎⽤性の⾼さもPythonの魅⼒
    • プログラミング⾔語には得意苦⼿がある
    • 様々なことが得意な⾔語を学べば何にでもその⾔語を使える
    • 利⽤⽬的が限られる⾔語は⽬的ごとに複数⾔語の習得が必要
    • C⾔語: OSに近い領域や組み込み向けのプログラミングが得意
    • Python
    • 使い捨ての短い簡単なスクリプトでも使える
    • ⼤規模なシステムの開発でも使える
    • ウェブサービスの開発でも使える
    • 科学計算(機械学習/ビッグデータ処理など)でも使える

    View Slide

  21. プログラミング⾔語の分類とPython
    • プログラミング⾔語は以下の3種類に分類できる
    • ⼿続き型⾔語(オブジェクト指向型⾔語のベース)
    • オブジェクト指向型⾔語(現在の主流。Pythonも)
    • 関数型⾔語
    • ただしPythonは⼿続き型のような書き⽅もできるし、関数型の
    ような書き⽅(中上級者向け)もできる
    ⼿続き型
    ⾔語
    オブジェクト
    指向型⾔語
    関数型
    ⾔語
    Python

    View Slide

  22. • なぜプログラムの作成にアセンブリ⾔語ではなくモダンなプロ
    グラミング⾔語を使うべきか説明してください
    • コンパイル型とインタプリタ型のプログラミング⾔語の違いを
    説明してください
    • スクリプトやウェブサービスの開発にC⾔語ではなくPythonを
    使うべき理由を説明してください
    • Pythonが苦⼿な領域を説明してください
    演習

    View Slide

  23. Pythonで電卓代わりに計算する
    • このセクションで学ぶこと
    • Pythonの起動⽅法: Windows, Mac
    • Pythonのバージョン
    • インタラクティブシェルを操作して計算
    • 値(あたい)とは
    SECTION
    02

    View Slide

  24. Windows: PowershellでPythonを起動する
    • 「インタラクティブシェル」は対話形式でPythonを利⽤する操
    作法で「REPL(Read Eval Print Loop)」やとも呼ばれる
    • Windows左下の検索ボックスに「powershell」と⼊⼒して
    PowerShell(コマンドラインアプリ)を起動
    • Powershellで半⾓にて「python」と⼊⼒することで起動する
    • インストール時にパスを通し忘れていると「pythonというコマ
    ンドは存在しない」といった旨のエラー。再インストール。

    View Slide

  25. Mac: ターミナルでPythonを起動する(1/2)
    • ターミナルアプリケーションを開く

    View Slide

  26. Mac: ターミナルでPythonを起動する(2/2)
    • ターミナルで「python3」と⼊⼒して起動
    • 注意: Macでは「python」と⼊⼒するとPython3ではなくデフォル
    トでインストールされているPython2が起動する。両者とも
    Pythonだが仕様(⽂法など)が⼤きくことなるので注意
    • 本資料ではWindowsを優先してpython表記とするが、python3と
    読み替えること

    View Slide

  27. コラム: Pythonとバージョン
    • バージョン: Python X.Y という形式。Xがメジャーバージョン
    (Windows7, 10などのレベル)でYがマイナーバージョン(リリー
    ス時期やパッチなどのレベル)。
    • Python2: ⼀般普及した最初のメジャーバージョン。新規開発は
    停⽌している。バージョン2で開発されたシステムのメンテ作
    業は2020年代中盤あたりまでは継続することが予想される。⽇
    本語の扱いが苦⼿
    • Python3: 現在普及しているメジャーバージョン。今から学ぶな
    らPython3をやるべき。新規開発も当然ながらPython3を使う
    • Python2と3は似ているが⽂法やライブラリが異なる別⾔語

    View Slide

  28. インタラクティブシェルで⾜し算、引き算
    • インタラクティブシェルの挙動
    1. 「>>>」に続けて実⾏したいことを書く
    2. Enter(Return)キーを押す
    3. Pythonが書かれていることを解釈する
    4. Pythonが実⾏結果を画⾯に表⽰する
    5. ステップ1に戻る
    $ python
    Python 3.8.2 (v3.8.2:7b3ab5921f, Feb 24 2020, 17:52:18)
    [Clang 6.0 (clang-600.0.57)] on darwin
    Type "help", "copyright", "credits" or "license" for more information.
    >>> 5 + 3
    8
    >>> 7 - 2
    5
    注意: MacはPython3コマンドで起動

    View Slide

  29. インタラクティブシェルで掛け算、割り算、剰余
    • ⾜し算(+)引き算(-)は算数と同じ記号を使う
    • 掛け算には「*」記号を使う
    • 割り算には「/」記号を使う
    • 剰余(余り。たまに使う)では「%」記号を使う
    • 算数と同じく⼩カッコ「()」で計算順序を調整できる
    >>> 4 * 4
    16
    >>> 7 / 2
    3.5
    >>> 31 % 2
    1
    >>> 5 + 2 * 3
    11
    >>> (5 + 2) * 3
    21

    View Slide

  30. 値(あたい)とは
    • 「値(あたい)」はPythonが扱うデータのこと。英語ではvalue
    • たとえば数字の4や5
    • たとえばテキスト(⽂字列と呼ばれる)のHello
    • 今後学ぶ様々な種類のデータも値

    View Slide

  31. • インタラクティブシェルを⽴ち上げて、「10 x 2」の計算を実
    施してください
    • 「5 ÷ 2」の計算を実施してください
    • 「5 + 2 * 2」と「(5 + 2) * 2」の計算結果の違いを確認し、な
    ぜ結果が異なるか説明してください
    • Python2とPython3の違いについて説明してください
    演習

    View Slide

  32. 値を格納する「変数」を理解する
    • このセクションで学ぶこと
    • 変数と代⼊
    • 変数の名前のつけかた
    • 複合代⼊演算⼦
    • 定数
    SECTION
    03

    View Slide

  33. 変数とは (1/3)
    • 「変数」は値を格納する容器
    • 作成した変数に値をいれることを「代⼊」するという
    • 変数に代⼊された値は必要なときに⾃動で取り出される
    • 変数から値が取り出されてもなくならない

    View Slide

  34. 変数とは (2/3)
    • 変数を作成することを「宣⾔」するという
    • 「変数 = 値」という⽂法で変数の宣⾔と代⼊を同時におこなう。
    (他のプログラミング⾔語では変数の宣⾔のみできるものもある
    が、Pythonでは宣⾔時に代⼊もおこなう)
    >>> abc = 51
    >>> abc
    51
    >>> abc + 5
    56
    >>> abc + 10
    61
    変数abcを宣⾔し、51を代⼊
    変数abcから51が取り出されている
    値が変数から取得されても中⾝はなくならない

    View Slide

  35. 変数とは (3/3)
    • 変数に新しい値を代⼊(「再代⼊」とよばれる)すると、古い値
    は上書きされてなくなる
    • 変数Aに変数A(⾃分⾃⾝)や変数Bの値を代⼊することもできる
    >>> abc = 51
    >>> abc + 5
    56
    >>> abc = 8
    >>> abc
    8
    >>> abc = abc + 3
    >>> abc
    11
    すでに存在している変数に新しい値を代⼊(再代⼊)
    変数が持つ値は新しい値で上書きされる
    変数に変数の値を代⼊することもできる。
    左は「abc = 8 + 3」と同じ意味

    View Slide

  36. 変数の⽤語
    • 変数を作成すること => 「宣⾔」する
    • 変数に値をいれること => 「代⼊」する
    • すでに変数を持つ変数に値をいれること => 「再代⼊」する
    • 変数に値を代⼊する記号 => 「代⼊演算⼦」。「=」のこと
    • 変数から値を取り出すこと => 変数が値を「返す」
    • これらの⽤語はプログラマの常識なので、知っていないと専⾨
    書籍を読んだりプログラマと会話する際に困ります。覚えて⾃
    分も使うことをおすすめします。

    View Slide

  37. 変数名の規則
    • 変数に使える記号は「アルファベットと数字及びアンダーバー
    (_)」が基本。⽇本語も使えるがおすすめしない。
    • 「必ずアルファベットから始まる」というルールがある
    • Pythonでは変数に⼤⽂字を使わないのが⼀般的
    • 特別な意味を持つ予約後(たとえばforなど)は使えない
    • 変数名にはなにが⼊っているか分かりやすいものを使う
    >>> abc = 3
    >>> 5ab = 3
    File "", line 1
    5ab = 3
    ^
    SyntaxError: invalid syntax
    >>> price = 100
    >>> text_length = 10
    問題のある変数名はエラーとなる
    上記のような分かりやすい名前が望ましい。
    意味を持つ⼩⽂字英数字で単語の区切りを
    アンダーバーとするのが⼀般的なPythonの
    変数の名付けかた。
    この命名規則は「スネークケース」と呼ばれる

    View Slide

  38. 複合代⼊演算⼦
    • 代⼊と演算(+や-)を同時にやる特殊な演算⼦は「複合代⼊演算
    ⼦」と呼ばれる
    • 代⼊演算⼦の前に演算記号がつく。たとえば「+=」
    • すでに代⼊されている変数を加⼯するためによく使われる
    • 変数に1を加えることを「インクリメント」と呼び、Pythonは
    それを複合代⼊演算⼦で実現する。「a += 1」
    >>> a = 10
    >>> a += 1
    >>> a
    11
    >>> a -= 5
    >>> a
    6
    複合代⼊演算⼦の例 同⼀の意味を持つ命令
    a += 1 a = a + 1
    a -= 5 a = a - 5
    a *= 10 a = a * 10
    a /= 3 a = a / 3

    View Slide

  39. 値の変わらない定数
    • ⽬的の分からない値のことを「マジックナンバー」と呼ぶ
    • マジックナンバーやプログラムのパラメーター(たとえば処理を
    何秒おきに呼び出すか)などは「定数」で宣⾔するのが⼀般的
    • 定数は「⼤⽂字英数字とアンダーバーを使う」のが⼀般的
    • プログラムファイル内で定数を使っているとパラメーター変更
    時のコード変更箇所を減らせる
    • 変数と異なり「定数は内部の値が変化しない」特徴がある
    >>> 100 * 1.08
    108.0
    >>> TAX_RATE = 1.08
    >>> 100 * TAX_RATE
    108.0
    100に1.08をかけている理由が分からない。
    これなに?
    1.08が定数 TAX_RATE に代⼊されていると、
    100に消費税 1.08 をかけていると⼀⽬瞭然。
    宣⾔部を1.1に変えれば消費税率の変更にすぐ対応できる

    View Slide

  40. コラム: Pythonの定数
    • 多くのプログラミング⾔語では定数に値を再代⼊するとエラー
    が発⽣する
    • Pythonでは定数に再代⼊してもエラーが発⽣しない
    • 実はPythonには⽂法としての定数はなく、ただの変数に過ぎな
    い。ただし、「⼤⽂字で宣⾔された変数は定数として使われ
    る」というのはPythonプログラマの常識なので再代⼊をするこ
    とは避ける必要がある。⼤⽂字の変数を定数として使う。

    View Slide

  41. • インタラクティブシェルを⽴ち上げて、変数abに5を代⼊し、
    次に変数cdに10を代⼊し、最後に変数同⼠を⾜し算して結果を
    確認してください
    • 変数aに10を代⼊し、それを複合代⼊演算⼦を使ったインクリ
    メントで11にしてください
    • 変数と定数の役割の違いについて説明してください
    • ⼀般的なPythonの変数名と定数名の命名ルールを説明してくだ
    さい
    演習

    View Slide

  42. データの種類を決める「型」を理解する
    • このセクションで学ぶこと
    • ⽂字列
    • データの種類と型
    • 概念としての型と、実データとしての値
    • 関数(詳細は3章)
    • type関数で型を調べる⽅法
    • キャストを使った型の変換⽅法
    SECTION
    04

    View Slide

  43. ⽂字列
    • テキストデータは「⽂字列」と呼ばれる。⽂字が1つの字でそ
    れが列(複数)となるので⽂字列
    • 1⽂字もない(空⽂字と呼ばれる)や1⽂字でも⽂字列と呼ばれる
    • ⽂字列は「シングルクオテーション(')」か「ダブルクオテー
    ション(")」でテキストを囲うことで宣⾔できる。Pythonではシ
    ングルクオテーションを使うのが⼀般的
    >>> a = 'h'
    >>> b = 'hello'
    >>> c = 'hello world'
    >>> d = "hello 123"
    >>> e = ''
    これらはすべて⽂字列

    View Slide

  44. ⽂字列の演算
    • ⽂字列も数値と同じように演算できる
    • ただし⾜し算(結合)はできるが、引き算はできない
    • 数値の「123」と⽂字列の「'123'」はデータの種類が異なるの
    で同じではない
    >>> 'abc' + '123'
    'abc123'
    >>> '123' + '456'
    '123456'
    >>> 123 + 456
    579
    >>> a = '123'
    >>> a += '456'
    >>> a
    '123456'
    >>> 456 - 123
    333
    >>> '456' - '123'
    Traceback (most recent call last):
    File "", line 1, in
    TypeError: unsupported operand type(s) for -: 'str'
    and 'str'
    ⽂字列の123は数値計算されていない

    View Slide

  45. ⽇本語の⽂字列
    • Python3では⽇本語の⽂字列も使える。Python2は⽇本語が苦⼿
    • アルファベットと異なり「⽂字コード(Shift-JISやUTF-8など)」
    に気を配る必要がある
    • Python3のデフォルト⽂字コードはUTF-8なので「Pythonでは常
    にUTF-8を使う」とルール化するのが⼀般的
    • Shift-JISなどを含んだ⽇本語の詳細は7章で扱う
    $ python3
    >>> 'あいうえお' + 'かきくけこ'
    'あいうえおかきくけこ'
    $ python2
    >>> 'あいうえお' + 'かきくけこ'
    '\xe3\x81\x82\xe3\x81\x84\xe3\x81\x86\xe3\x81
    \x88\xe3\x81\x8a\xe3\x81\x8b\xe3\x81\x8d\xe3\
    x81\x8f\xe3\x81\x91\xe3\x81\x93'
    MacでのPython3とPython2の⽇本語の扱い

    View Slide

  46. 概念とデータ - 型が持つ2つの性格
    • 「123」と「'123'」の演算は異なる動きとなった。
    • これは両者の値の「型(データの種類)」が異なるため
    • 型が「データの概念レベル」で値が「実際のデータ」
    • どの型がどういった処理をできるか覚えるのがプログラミング
    の最初の⼀歩

    View Slide

  47. 関数
    • 「受け取った値」にたいして「決められた処理」をおこない、
    「結果を返す」仕組みをプログラミングでは「関数」と呼ぶ
    • 「結果を受け取る変数 = 関数名(関数に与える値)」という書式
    で使うのが⼀般的
    • 関数に与える値のことを「引数」と呼び、関数から返される値
    を「返り値」と呼ぶ
    • 関数の詳細は第3章で扱う
    >>> print(15)
    15
    >>> print('hello world')
    hello world
    print関数は与えられた値をコンソール出⼒する

    View Slide

  48. type関数を使った型の確認
    • Pythonは「あまり型にうるさくない⾔語」
    • メリット: 気軽にコーディングをおこなえる
    • デメリット: 変数に⼊っている型が想定していたものと違う
    といったトラブルがある
    • 「type 関数」を使うことで変数の型を確認できる
    • 拘束性は⾼くないが変数名に型を宣⾔することも可能(割愛)
    >>> a = 10
    >>> type(a)

    >>> a = 'hello'
    >>> type(a)

    数値を代⼊した変数aに⽂字列を再代⼊できる。
    型にうるさい⾔語(C⾔語やJava)ではできない。
    type関数に変数(そのなかの値)を与えると型がわかる。
    intは「整数型」のこと

    View Slide

  49. キャストを使った型の変換(1/2)
    • プログラミングでは型を変換する場⾯が多々ある
    • たとえば「⽂字列型の値と整数型の値は結合できない」ので整
    数型を⽂字列型に変換してから結合など
    • 型の変換のことを「キャスト」と呼ぶ
    >>> price = 100
    >>> price + ' yen'
    Traceback (most recent call last):
    File "", line 1, in
    TypeError: unsupported operand type(s) for +: 'int' and 'str'
    数値と⽂字列型の結合でエラーが発⽣

    View Slide

  50. キャストを使った型の変換(2/2)
    • ⽂字列型への変換には「str 関数」を使う
    • 整数型への変換には「int 関数」を使う
    • ⽂字列から数値へのキャストは変換できれば成功し、変換でき
    ない場合は失敗する
    >>> price = 100
    >>> str(price) + ' yen'
    '100 yen'
    >>> int('100')
    100
    >>> int('hello')
    Traceback (most recent call last):
    File "", line 1, in
    ValueError: invalid literal for int() with base 10: 'hello'
    数値を⽂字列型にキャストしてから
    別の⽂字列と結合
    ⽂字列から数値へのキャストは失敗することがある

    View Slide

  51. コラム: シングルクオートとダブルクオート
    • ダブルクオートの⽂字列内ではシングルクオートが使え、シン
    グルクオートの⽂字列内ではダブルクオートが使える。
    • そのため、以下の使い分けがおすすめ
    • 通常時: シングルクオート(Pythonでは⼀般的なため)
    • ⽂字列内にシングルクオートを持つ場合: ダブルクオート
    • エスケープシーケンス(後述)を使うことでシングルクオートの
    ⽂字列内でシングルクオートを使うこともできる。ダブルク
    オートも同様
    >>> 'hello I'm Taro'
    File "", line 1
    'hello I'm Taro'
    ^
    SyntaxError: invalid syntax
    >>> "hello I'm Taro"
    "hello I'm Taro"
    >>> 'hello I\'m Taro'
    "hello I'm Taro"
    >>>

    View Slide

  52. • 値「123」と値「'123'」の違いを説明してください
    • 「'123' + '123'」の結果がどうなるか確認し、キャストを使っ
    て結果が246になるように式を変更してください
    • 数値「1.1」の型をtype関数で確認してください
    演習

    View Slide

  53. 制御構⽂を理解しよう
    CHAPTER
    2
    1. プログラムファイルを作って実⾏する
    2. 条件分岐の仕組みを理解する
    3. ループ処理で繰り返しを記述する

    View Slide

  54. プログラムファイルを作って実⾏する
    • このセクションで学ぶこと
    • IDLE(標準の統合開発環境)の起動⽅法
    • 新規ファイルの作成と保存⽅法
    • IDLEでのプログラムの実⾏⽅法
    • わざとエラーを発⽣させてエラー内容を読む
    • コメント
    • コンソールからプログラムを実⾏
    • コラム: 複数⾏にわたる⽂字列
    SECTION
    01

    View Slide

  55. IDLE(統合開発環境)の起動
    • Pythonをインストールするとには「IDLE」という統合開発環
    境も同時にインストールされている
    • Windows: スタートメニューから選択(以下の図)して起動
    • Mac: アプリケーションのディレクトリから起動

    View Slide

  56. IDLEで新規ファイルを開く
    • IDLEのメニューは英語表記だが操作は単純
    • プログラムを開発するために図の⼿順で新規ファイルを開く
    • 新規ファイルを開くとエディタの画⾯が現れる
    • 既存のファイルを開くこともできる。以下の図の「Open..」

    View Slide

  57. IDLEでファイルを保存する
    • エディタに以下のプログラム(スライド5PめのURLより以後の
    プログラム全てをダウンロード可能)を記述する
    • メニューバーから保存操作(図を参照)する
    • 保存する場所は「デスクトップ上のpythonフォルダ」とし、そ
    こに「test_01.py」という名前で保存
    print(1)
    print('2')
    a = 1 + 2
    print(a)
    /chapter2/test_01.py

    View Slide

  58. IDLEでプログラムを実⾏
    • IDLEのプログラムのエディタを選択(クリックして前⾯に)
    • 以下のいずれかの⽅法で実⾏
    • メニューバーの「 -> 」
    • F5ボタン(MacだとFnボタンを押しながら)を押す
    • インタラクティブシェルと異なりprint関数などで意図的に出⼒
    させないとどのような動きをしているか⾒えない

    View Slide

  59. エラーを発⽣させて確認する
    • プログラムを開発していると、勘違いや⼊⼒ミスで必ずエラー
    は発⽣する
    • エラーを特定して問題箇所の修正を繰り返すことでプログラム
    はきちんと動作するようになる
    • わざとエラーを発⽣させてエラーの読み⽅を確認してみる
    print(1)
    print('2')
    a = 1 + 2
    print(b)
    1
    2
    Traceback (most recent call last):
    File "/Users/yuichi/Desktop/python/test_02.py", line 4, in
    print(b)
    NameError: name 'b' is not defined
    エラーメッセージから「どのファイル(test_02.py)」の
    「どの⾏(line 4)」で
    「どのような問題(NameError: name ʻbʼ is not defined)」が
    おきているかわかる
    /chapter2/test_02.py
    コンソール出⼒

    View Slide

  60. コメント
    • 「コメント」: プログラム中の実⾏されない特別なテキスト
    • プログラムの説明(なにをしているか注釈)に利⽤したり、実⾏
    してほしくない箇所をコメント化する使い⽅が⼀般的
    • コメントの⽅法
    • 「#(シャープではなくハッシュと読む)」の後ろ(1⾏)
    • 「'''」もしくは「"""」で囲まれた複数⾏のテキスト
    #print(1)
    print('2')
    '''
    a = 1 + 2
    print(b)
    '''
    2
    /chapter2/test_03.py
    コンソール出⼒
    コメントした箇所が実⾏されていないので、
    コンソール出⼒されていないことがわかる。
    さきほどのエラー箇所も無視されている。
    プログラムをコメント化することを
    「コメントアウト」という

    View Slide

  61. コンソールからプログラムを実⾏
    • Pythonのプログラムはコンソール(Powershellやターミナル)か
    ら実⾏できる。
    • プログラムファイルを指定してpythonコマンドで呼び出す
    • 本格的な開発ではプログラミング⽤エディタ(VSCodeなど)で
    開発してコンソール実⾏するか、IDLEより⾼度な
    IDE(PyCharmなど)の利⽤が⼀般的
    PS C:\Users\yito> cd ~/Desktop/python
    PS C:\Users\yito\Desktop\python> python test_01.py
    1
    2
    3
    $ cd ~/Desktop/python
    $ python3 test_01.py
    1
    2
    3
    Windowsの例
    Macの例
    (python3コマンド)

    View Slide

  62. コラム: 複数⾏にわたる⽂字列
    • 「トリプルクオテーション(''')」を使った複数⾏のコメントア
    ウトは厳密には「囲んだ箇所を⽂字列化」している
    • 純粋な複数⾏のコメントアウトの⽂法はない
    • ⽂字列化でのコメントアウトに問題がある場合はすべての⾏に
    「#」をつけてコメントアウトする
    text = '''hello world
    python'''
    print(text)
    $ python3 multi_line_string.py
    hello world
    python
    /chapter2/multi_line_string.py コンソール出⼒

    View Slide

  63. コラム: エスケープシーケンス
    • 改⾏やタブといった特殊⽂字を使う場合は「エスケープシーケ
    ンス」を使う
    • エスケープシーケンスは半⾓バックスラッシュ「\」(⽇本語
    キーボードだと半⾓「\」記号)に続けて特定の1⽂字を書く
    • よく使うエスケープシーケンス
    • 改⾏: \n
    • タブ: \t
    • シングルクオテーション: \'
    • ダブルクオテーション: \"
    >>> print('hello\nworld')
    hello
    world
    エスケープシーケンス「\n」で
    改⾏されている

    View Slide

  64. • IDLEを起動して以下のプログラム(1)を新規作成して実⾏
    • プログラミング⽤エディタ(好みがなければVSCodeをインス
    トール)で以下のプログラム(1)を作成して、コンソールで実⾏
    • インタプリタで以下の出⼒(2)をする
    • コメントの利⽤⽤途を2つ以上説明する
    演習
    print('I love Python') I
    will
    complete
    this
    training
    プログラム(1)
    出⼒(2)

    View Slide

  65. 条件分岐の仕組みを理解する
    • このセクションで学ぶこと
    • 絶対値を求めるabs関数
    • abs関数の条件分岐
    • if⽂を使った条件分岐
    • インデントによるコードブロック
    • Bool型
    • ⽐較演算⼦
    • Bool値を扱う演算⼦
    • 複雑なif⽂
    SECTION
    02

    View Slide

  66. 絶対値を求めるabs関数
    • 絶対値はある数値(マイナスも含む)の0からの距離
    • 「変化の⼤きさ」を表現するのに使われる
    • Pythonでは「abs関数」を使うことで絶対値を求められる
    >>> abs(5)
    5
    >>> abs(-10)
    10
    >>> abs(0)
    0
    インタプリタでのabs関数の確認

    View Slide

  67. abs関数の条件分岐
    • 「条件分岐」は「ある特定の条件を満たす場合のみ、何かの処
    理をする」という仕組み
    • 絶対値を得る条件分岐は 「値(変数aとする)が0より⼤きいとい
    う条件」を満たす場合のみ「値に-1をかけてプラスにする」と
    いう処理をする
    abs関数の条件分岐

    View Slide

  68. if⽂を使った条件分岐
    • Pythonで条件分岐を使うには「if」を使う
    • ifに続けて「条件式(TrueかFalseが得られる式)」を書く
    • 次の⾏以降でインデント(字下げ)して処理を書く
    • 注意: 他のプログラミング⾔語のようにifのあとに()で条件式を
    囲んでも問題ないが、Pythonでは囲まないのが⼀般的
    a = -5
    if a < 0:
    a = a * -1
    print(a)
    if 条件式:
    条件式を満たす場合の処理
    /chapter2/abs_01.py
    $ python3 abs_01.py
    5
    コンソール出⼒
    If⽂の⽂法

    View Slide

  69. インデントによるコードブロック
    • 「コードブロック」はプログラムの制御処理の対象範囲のこと
    • 何⾏⽬から何⾏⽬までをコードブロックとするかはインデント
    による字下げで表現する
    • Pythonでは半⾓4つが標準的なインデントでタブは⾮推奨(1つ
    のプログラム中で空⽩とタブの字下げを混在させるとエラー)
    • プログラミング⽤エディタはタブを半⾓に⾃動変換するものも
    ある
    a = -5
    if a < 0:
    print(1)
    print(2)
    a = a * -1
    print(3)
    print(a)
    $ python3 abs_02.py
    1
    2
    3
    5
    /chapter2/abs_02.py
    コンソール出⼒
    インデント
    (字下げ)は
    半⾓4つが標準

    View Slide

  70. Bool型
    • 条件を満たす/満たさないを表現する型。条件分岐などに使う
    • 「True」と「False」の2値しかない
    • 「条件を満たす」は「条件式がTrueを返す」こと
    • 「条件を満たさない」は「条件式がFalseを返す」こと
    >>> 5 > 3
    True
    >>> 5 < 3
    False
    a = -5
    if a < 0:
    a = a * -1
    print(a)
    /chapter2/abs_01.py
    インタプリタでの確認

    View Slide

  71. ⽐較演算⼦ (1/2)
    • True/Falseを得るための演算⼦
    • 制御構⽂の条件式などでよく利⽤される
    • 数字以外でも⽂字列などでも使える
    演算⼦ 意味 使⽤例(Trueの場合)
    == 左辺と右辺が等しいときにTrueを返す 20 == 20
    != 左辺と右辺が等しくないときにTrueを返す 20 != 30
    > 左辺が右辺より⼤きいときにTrueを返す 30 > 20
    >= 左辺が右辺以上のときにTrueを返す 30 >= 20, 30 >= 30
    < 左辺が右辺より⼩さいときにTrueを返す 20 < 30
    <= 左辺が右辺以下のときにTrueを返す 20 <= 30, 20 <= 20

    View Slide

  72. ⽐較演算⼦ (2/2)
    • 異なる型での⽐較などもできる
    • ⽂字列の⽐較などはCやJavaと挙動が異なるので注意(Pythonは
    ポインタではなく値で⽐較するので分かりやすい)
    >>> 4 == 4.0
    True
    >>> 4 == '4'
    False
    >>> 'abc' > 'def'
    False
    >>> 'hello' == 'hello'
    True
    >>> 'hello' == ('hel' + 'lo')
    True
    コンソール出⼒
    ⽂字列の⽐較はユニコードの
    順番で決まっている。
    aはdより前にあるので⼩さい

    View Slide

  73. Bool値を扱う演算⼦
    • 条件式ではBool値の反転や「かつ」「または」などもよく使う
    • 「and」演算⼦: 左辺と右辺の値がともにTrueの時にTrueを返す
    • 「or」演算⼦: 左辺と右辺の値のどちらかがTrueの時にTrueを返す
    • 「not」演算⼦: True/Falseを逆転させる
    >>> True and True
    True
    >>> True and False
    False
    >>> True or True
    True
    >>> True or False
    True
    >>> not True
    False
    >>> not False
    True
    and演算⼦の確認 or演算⼦の確認 not演算⼦の確認

    View Slide

  74. 複雑なif⽂
    • 「elif」は 前⽅のifかelifに合致しなかったときに条件チェック
    される分岐。好きなだけ繰り返せる
    • 「else」は前⽅のifとelifの全てに合致しなかったときに呼び出
    される処理を書く
    a = 15
    if a % 2 == 0:
    print('2')
    elif a % 3 == 0:
    print('3')
    elif a % 5 == 0:
    print('5')
    else:
    print('nothing')
    $ python3 if_elif_else.py
    3
    /chapter2/if_elif_else.py
    コンソール出⼒

    View Slide

  75. • 有名なFizzBuzz問題のプログラムを作成する
    • 変数 a に整数を任意の数を与える
    • 変数 a が3で割り切れれば「Fizz」と出⼒
    • 変数 a が5で割り切れれば「Buzz」と出⼒
    • 変数 a が3でも5でも割り切れれば「FizzBuzz」と出⼒
    • ヒント: 「1章で学んだ剰余で余りが0になること」が「割り
    切れる」ということ
    • 変数aを様々な値に変更して挙動を確認してください
    演習

    View Slide

  76. ループ処理で繰り返しを記述する
    • このセクションで学ぶこと
    • リストのデータを準備する
    • リストのデータを取り出す
    • リストのデータを上書きする
    • リスト⻑を取得する
    • リストのデータをまとめて処理するforループ
    • Breakによるループ打ち切り
    • Continueによるループの周回スキップ
    • Continueの便利な利⽤法
    • 条件が満たされる間はループを繰り返すwhile⽂
    SECTION
    03

    View Slide

  77. リストのデータを準備する
    • Pythonのループでは「リスト型」の値をよくつかう
    • リスト型は⼀覧(リスト)となっているデータを扱うための型
    • 「要素」はリストの中⾝のデータ(数値や⽂字列など)のこと
    • リストの要素には順序がある
    >>> ['taro', 'jiro', 'saburo']
    ['taro', 'jiro', 'saburo']
    >>> []
    []
    >>> a = ['taro', 'jiro', 'saburo']
    >>> print(a)
    ['taro', 'jiro', 'saburo']
    >>>
    リストの宣⾔は⼤かっこ([])に要素を並べる
    要素がひとつもない場合は[]のみ
    リスト内の要素の順序は保たれる

    View Slide

  78. リストのデータを取り出す
    • リスト内のデータは前⽅から0,1,2と数える。1からではなく0か
    ら数え始めるので注意
    • 要素の順番のことを「インデックス番号」と呼ぶ
    • 「リスト[インデックス番号]」とすると、指定したインデック
    ス番号の要素が取り出される。取り出されてもなくならない
    >>> a = ['taro', 'jiro', 'saburo', 10]
    >>> a[0]
    'taro'
    >>> a[2]
    'saburo'
    リスト要素の取得

    View Slide

  79. リストのデータを上書きする
    • 「リスト[インデックス番号] = 代⼊する値」という形式でイン
    デックス番号を指定して要素に代⼊することもできる
    • リストの⻑さを超えたインデックスの参照は取得でも代⼊でも
    エラーとなる
    >>> a = ['taro', 'jiro', 'saburo', 10]
    >>> a[1] = 'hanako'
    >>> a[3] = 'adam'
    >>> print(a)
    ['taro', 'hanako', 'saburo', 'adam']
    存在しないインデックスの参照はエラーとなる
    >>> a = ['taro', 'jiro', 'saburo', 10]
    >>> a[4]
    Traceback (most recent call last):
    File "", line 1, in
    IndexError: list index out of range
    >>> a[4] = 100
    Traceback (most recent call last):
    File "", line 1, in
    IndexError: list assignment index out of range
    リストの要素をインデックスで指定して代⼊すると
    その要素が代⼊値で上書きされる

    View Slide

  80. リスト⻑を取得する
    • リスト⻑: リストの要素の数のこと
    • 「len関数」でリスト⻑を取得できる
    • 「len関数の取得値-1までインデックスでアクセスができる」と
    覚えておく
    >>> a = ['taro', 'jiro', 'saburo', 10]
    >>> len(a)
    4
    >>> a[3]
    10
    >>> a[4]
    Traceback (most recent call last):
    File "", line 1, in
    IndexError: list index out of range
    len関数の確認と要素へのアクセス
    len関数の取得値でアクセス
    可能なインデックス値の最⼤値が
    わかる

    View Slide

  81. リストのデータをまとめて処理するforループ
    • リストに代表される「シーケンス(連なりのあるデータ)」構造
    • 「for」ループでシーケンスを前から後ろに順番に処理できる
    name_list = ['taro', 'jiro', 'saburo', 'shiro', 'goro']
    for name in name_list:
    print(name)
    $ python3 forloop.py
    taro
    jiro
    saburo
    shiro
    goro
    for 変数 in シーケンス:
    処理
    /chapter2/forloop.py
    コンソール出⼒
    for⽂の⽂法
    ループするごとにシーケンスの要素を前から後ろに変数に代⼊する
    シーケンスの最後までたどり着くとループが終了
    ブロックの使い⽅はifと同じ

    View Slide

  82. breakによるループ打ち切り
    • 「break」命令でループ処理を打ち切る
    • ループを継続する理由がなくなった場合に利⽤される
    • 例: 整数のリスト中に偶数があるかをチェック。(偶数を⾒つけ
    たら残りのリストの要素はチェック不要なのでbreak)
    a = [5, 9, 11, 3, 6, 5, 11, 4, 9]
    has_even = False
    for i in a:
    print('checking: ' + str(i))
    if i % 2 == 0:
    has_even = True
    break
    print('has even: ' + str(has_even))
    $ python3 forloop_break.py
    checking: 5
    checking: 9
    checking: 11
    checking: 3
    checking: 6
    has even: True
    /chapter2/forloop_break.py
    コンソール出⼒
    リストの6より後ろはbreakされたので
    出⼒されていない

    View Slide

  83. continueによるループの周回スキップ
    • 「continue」命令で ループのそのその回だけを抜ける
    • ループ⾃体は継続するのでシーケンスの次の要素は処理する
    • 要素が「特定条件を満たす場合のみだけ処理する」際に
    continueを使うとよい
    a = [5, 9, 11, 3, 6, 5, 11, 4, 9]
    for i in a:
    if i % 2 == 1:
    continue
    print('Even: ' + str(i))
    $ python3 forloop_continue_01.py
    Even: 6
    Even: 4
    /chapter2/forloop_continue_01.py
    コンソール出⼒

    View Slide

  84. continueの便利な利⽤版
    • breakの利⽤難易度は低いが、continueは使い慣れない⼈が多い
    • ループでの条件分岐のインデント階層を減らすのに便利
    for i in a:
    if 条件1:
    if 条件2:
    if 条件3:
    処理
    for i in a:
    if 条件1:
    continue
    if 条件2:
    continue
    if 条件3:
    continue
    処理
    Continueなし
    Continueあり

    View Slide

  85. 条件が満たされる間はループを繰り返すwhile⽂
    • 「while」ループで条件式が満たされる限り繰り返す
    • 他のプログラミング⾔語ではwhileは多⽤されるが、Pythonで
    はforループを可能な限り使うこと。forが使えない場合にwhile
    ⽂を検討する
    a = [5, 9, 11, 3]
    length = len(a)
    i = 0
    while i < length:
    print('index ' + str(i) + ' : ' + str(a[i]))
    i += 1
    $ python3 while_loop.py
    index 0 : 5
    index 1 : 9
    index 2 : 11
    index 3 : 3
    /chapter2/while_loop.py
    コンソール出⼒
    while 条件式:
    処理
    while⽂の⽂法
    条件式がTrueとなる限りループを継続する
    ブロックの使い⽅はifやforと同じ

    View Slide

  86. • Forループで以下の⾝⻑の平均値、最⼤値、最⼩値を求めてく
    ださい。ヒント: 合計値と最⼤値と最⼩値のそれぞれの変数を
    ループ前に定義して、ループを回るたびにその値を更新する
    • 180cm
    • 170cm
    • 160cm
    • 165cm
    • 175cm
    • 余裕がある⼈は10進数を2進数(⽂字列)に変換するプログラム
    をwhileループで作成してください。検索するとアルゴリズム
    がでてくるはずです。2進数は⽂字列の複合代⼊演算⼦(結合)で
    作成してください。
    演習

    View Slide

  87. 関数の使い⽅をマスターしよう
    CHAPTER
    3
    1. なぜ関数が必要なのか?
    2. オリジナルの関数を定義する
    3. 関数の引数と返り値を⾃在に操る
    4. 名前空間と関数型について知る
    5. 組み込み関数を活⽤する

    View Slide

  88. なぜ関数が必要なのか?
    • このセクションで学ぶこと
    • 関数にしかできない処理を提供する
    • 複雑な処理を簡単に実現する
    • コードの重複の排除
    SECTION
    01

    View Slide

  89. 役割(1) - 関数にしかできない処理を提供する
    • OSやハードウェアの機能(画⾯出⼒やネットワークなど)の利⽤
    は関数しかできない
    • 関数の内部ではシステムコールなどにより低いレイヤのプログ
    ラム(C⾔語)が呼び出されている

    View Slide

  90. 役割(2) - 複雑な処理を簡単に実現する(1/3)
    • アルゴリズムを⾃分で書けば複雑な処理も実現できる
    • ⼀般的な処理はPythonが関数などを提供しているので、それを
    使うほうが「簡単」「バグが少ない」「速い」
    例: リストの要素のソートの実装
    選択ソートというアルゴリズム
    1. リストの最⼩値を探す
    2. 0番⽬の要素とスワップ
    3. 1番⽬以降で最⼩値を探す
    4. 1番⽬の要素とスワップ
    5. …
    6. 要素の最後までたどり着けばソート終了
    変数間の値の交換は
    ⼀時的な変数が必要

    View Slide

  91. 役割(2) - 複雑な処理を簡単に実現する(2/3)
    • 現時点の知識でのソートアル
    ゴリズムの実装(難しい)
    • 変数の値の交換処理には⼀時
    変数が必要
    a = [5,9,4,1,8]
    length = len(a)
    i = 0
    while(i < length):
    # i番⽬以降の最⼩の要素を探す
    minimum_index = i
    j = i + 1
    while j < length:
    if a[j] < a[minimum_index]:
    minimum_index = j
    j += 1
    # i番⽬と最⼩の要素をスワップする
    if minimum_index != i:
    tmp = a[i]
    a[i] = a[minimum_index]
    a[minimum_index] = tmp
    # i番⽬のループが終わった際のリスト
    print(str(i) + ': ' + str(a))
    i += 1
    print('sorted: ' + str(a))
    $ python3 sort_list_01.py
    0: [1, 9, 4, 5, 8]
    1: [1, 4, 9, 5, 8]
    2: [1, 4, 5, 9, 8]
    3: [1, 4, 5, 8, 9]
    4: [1, 4, 5, 8, 9]
    sorted: [1, 4, 5, 8, 9]
    コンソール出⼒
    /chapter3/sort_list_01.py

    View Slide

  92. 役割(2) - 複雑な処理を簡単に実現する(3/3)
    • sorted関数で昇順ソート(⼩さいものから⼤きいものへ)が提供さ
    れている
    • ⾃作のソート処理より以下の点で優れる
    • プログラムの⾒た⽬がシンプル
    • ⾼速(選択ソートより賢いアルゴリズムがC⾔語で実装される)
    • バグが発⽣する可能性が低い
    a = [5,9,4,1,8]
    b = sorted(a)
    print(b)
    $ python3 sort_list_02.py
    [1, 4, 5, 8, 9]
    コンソール出⼒
    /chapter3/sort_list_02.py
    ⾃作の20⾏以上のプログラムがたった1つの
    関数呼び出しに置き換えられた

    View Slide

  93. 役割(3) - コードの重複の排除
    • 同⼀の処理をコピーペーストで何度も書くのはよくない
    • ソースコードが無駄に⻑くなって読みにくくなる
    • バグやコードの修正が発⽣すると⾯倒だしトラブルのもと
    • 関数化されていれば「⾒やすい」し「変更(修正)しやすい」
    a = 5
    if a < 0:
    a *= -1
    # 何か関係ない処理
    b = -3
    if b < 0:
    b *= -1
    print(a) # 5
    print(b) # 3
    a = 5
    a = abs(a)
    # 何か関係ない処理
    b = -3
    b = abs(b)
    print(a) # 5
    print(b) # 3
    /chapter3/get_abs_01.py
    /chapter3/get_abs_02.py

    View Slide

  94. • 関数が必要な理由を3つ説明してください
    • 発展課題: ソートアルゴリズムについて調査し、バブルソート
    を実装してください
    演習

    View Slide

  95. オリジナルの関数を定義する
    • このセクションで学ぶこと
    • 関数の概念の復習
    • 関数を定義する
    • ⾃分で定義した関数を利⽤する
    • 関数の命名ルール
    • 定義と参照の順序
    SECTION
    02

    View Slide

  96. 関数の概念の復習
    • 関数の仕事
    1. 「引数」でデータを受け取る
    2. 受け取ったデータで処理を⾏う
    3. 結果を「返り値」として呼び出し元に返す
    • 絶対値を求めるabs関数の例
    1. 引数で数値を受け取る
    2. 受け取った数値を絶対値にする(マイナスであればプラス
    に変換する)
    3. 絶対値を呼び出し元に返す
    処理 (絶対値の算出)
    引数による⼊⼒(数値) 返り値による出⼒(絶対値)
    関数

    View Slide

  97. 関数を定義する
    • 関数を定義する⽂法ルールがある
    • 引数は関数内で変数として利⽤される。再代⼊も可能
    def my_abs(x):
    if x < 0:
    x *= -1
    return x
    def 関数名(引数1, 引数2, ...):
    処理1
    処理2
    return 返り値
    絶対値を求める関数の定義例
    • 関数名: my_abs
    • 引数: x
    • 処理: if⽂でxを絶対値にする
    • 返り値: 処理されたx
    /chapter3/define_function_02.py
    関数を実装する⽂法
    「return⽂」で呼び出し元に値を返す
    「def⽂」で関数呼び出しの定義
    • 関数名
    • 引数
    処理は関数のブロックで定義する

    View Slide

  98. ⾃分で定義した関数を利⽤する
    • ⾃作関数の利⽤法はPythonが提供する関数(printなど)と同じ
    • 関数名に()をつけ、引数として渡す値や変数を()内に並べる
    • 関数の定義より前で関数を呼び出すとエラーになる
    def my_abs(x):
    if x < 0:
    x *= -1
    return x
    a = my_abs(3)
    print(a)
    print(my_abs(-5))
    print(my_abs(-5))
    def my_abs(x):
    if x < 0:
    x *= -1
    return x
    $ python3 define_function_04.py
    Traceback (most recent call last):
    File "define_function_04.py", line 1, in
    print(my_abs(-5))
    NameError: name 'my_abs' is not defined
    $ python3 define_function_03.py
    3
    5
    コンソール出⼒ コンソール出⼒
    /chapter3/define_function_03.py
    /chapter3/define_function_04.py
    呼び出し側で渡した引数3が
    関数側の引数xに代⼊される。
    引数の数は同じにすること
    returnの
    返り値が
    戻される

    View Slide

  99. 関数の命名ルール
    • 関数名の⽂法的なルールは変数名と同じ
    • アルファベットの⼩⽂字と数字をアンダーバーで区切る
    • ⼤⽂字の利⽤も可能だがPythonらしくない名前
    • 「関数名は動詞から始める」というのが⼀般的なルール
    def add_something(x):
    ...
    def get_something(x):
    ...
    def something_adder(x):
    ...
    def something_getter(x):
    ...
    def addSomething(x):
    ...
    def getSomething(x):
    ...
    よい変数名の例 Pythonらしくない変数名の例

    View Slide

  100. コラム: 変数の定義と参照の順序
    • 関数と同様に変数も「定義前に参照するとエラー」となる
    • プログラムがどのような流れで読み込まれて処理されるかを意
    識すればトラブルを避けやすい
    print(a)
    a = 5
    $ python3 define_variable.py
    Traceback (most recent call last):
    File "define_variable.py", line 1, in
    print(a)
    NameError: name 'a' is not defined
    コンソール出⼒
    /chapter3/define_variable.py

    View Slide

  101. • FizzBuzz問題を関数化してください
    • FizzBuzz⾃体の説明は2章の演習を参照してください
    • 引数は1つで整数を受け取ります
    • 返り値は「 " Fizz " 」「 " Buzz " 」「 " FizzBuzz " 」「 "
    " 」のいずれかの⽂字列とします
    • forループで「0から20までリストの各要素」にたいして
    FizzBuzzの関数を使い、結果を1つずつprintしてください
    • 数値を受け取り、その数値が偶数であればTrue, 奇数であれば
    Falseを返す is_even 関数を作成してください。ヒント: 偶数と
    奇数の判定は2で割り切れるかを剰余計算(%記号)で求める
    演習

    View Slide

  102. 関数の引数と返り値を⾃在に操る
    • このセクションで学ぶこと
    • 返り値の有無によるコードの違い
    • 複数のreturn⽂を記述する
    • 関数に複数の引数を定義する
    • キーワード引数を定義する
    • デフォルト引数
    • 可変⻑引数を利⽤する
    • コラム: help関数で関数の詳細を確認する
    SECTION
    03

    View Slide

  103. 返り値の有無によるコードの違い
    • returnが定義されていないと「None(何もないという値)」を返す
    • returnに変数や値が与えられていないときもNoneを返す
    • 「Noneを返す」ということは「関数の返り値がない」と同じ意味
    def my_print1(x):
    print('my print1: ' + str(x))
    def my_print2(x):
    print('my print2: ' + str(x))
    return
    a = my_print1(5)
    print(a)
    b = my_print2(5)
    print(b)
    $ python3 return_value_01.py
    my print1: 5
    None
    my print2: 5
    None
    コンソール出⼒
    /chapter3/return_value_01.py

    View Slide

  104. 複数のreturn⽂を記述する
    • 関数にreturnを複数定義することができる
    • returnが呼び出されたら関数の処理はそこで終わる。後ろに処
    理が残っていようとループ中であろうと残る処理はスキップさ
    れる
    def my_abs(x):
    if x > 0:
    return x
    print('less than 0')
    return x * -1
    print(my_abs(5))
    print(my_abs(-5))
    $ python3 return_value_02.py
    5
    less than 0
    5
    コンソール出⼒
    /chapter3/return_value_02.py

    View Slide

  105. 関数に複数の引数を定義する
    • 関数の引数は好きな数だけ使うことができる
    • 引数を受け取らない関数は引数を定義しない
    • 「定義した引数の数」と「呼び出し時の引数の数」が異なると
    エラーが発⽣
    def fun0():
    print('fun0')
    def fun1(arg1):
    print('fun1')
    def fun5(arg1, arg2, arg3, arg4, arg5):
    print('fun5: arg1 is ' + arg1)
    fun0()
    fun1(1)
    fun5('a', 'b', 'c', 'd', 'e')
    $ python3 return_value_03.py
    fun0
    fun1
    fun5: arg1 is a
    コンソール出⼒
    /chapter3/return_value_03.py

    View Slide

  106. キーワード引数を定義する
    • 今まで利⽤してきた引数は正式には「位置引数」と呼ばれる。定
    義された引数の「順序」通りに引数を与える使い⽅
    • 「キーワード引数」は 定義された引数名を指定して引数を与える
    • 引数の数が多い場合はキーワード引数だと順番間違いがない
    def test(arg1, arg2, arg3):
    print(str(arg1) + str(arg2) + str(arg3))
    # 位置引数
    test(1, 2, 3)
    # キーワード引数
    test(arg2='a', arg1='b', arg3='c')
    $ python3 keyword_argument_01.py
    123
    bac
    コンソール出⼒
    /chapter3/keyword_argument_01.py
    関数定義の引数名を指定して
    値を渡している

    View Slide

  107. デフォルト引数
    • 「デフォルト引数」で引数にデフォルト値を定義できる
    • キーワード引数とともに利⽤されることが多く、関数呼び出し
    時に対象となる引数を与えないとデフォルト値が使われる
    • デフォルト引数の後ろにデフォルト引数を持たない引数は定義
    できない。⽂法エラーが発⽣する
    def test(arg1, arg2=2, arg3=3):
    print(str(arg1) + str(arg2) + str(arg3))
    test(1, 'B', 'C')
    test(1)
    test(1, arg3='C')
    $ python3 keyword_argument_02.py
    1BC
    123
    12C
    コンソール出⼒
    /chapter3/keyword_argument_02.py

    View Slide

  108. 可変⻑引数を利⽤する
    • 与える引数が固定でない関数の引数を「可変⻑引数」と呼ぶ
    • 可変⻑引数を⾃分で定義するのは初⼼者向けではないが、既存
    関数で使う場⾯は多いので使いかたは知っておくこと
    • 「スプラット演算⼦(*)」を使うとリストを可変⻑引数に使える
    print('hello')
    print('hello', 'python')
    print(1, 2, 3, 4, 5, 6, 7, 8, 9)
    $ python3 variable_arguments_01.py
    hello
    hello python
    1 2 3 4 5 6 7 8 9
    print([1, 2, 3, 4, 5, 6, 7, 8, 9])
    print(*[1, 2, 3, 4, 5, 6, 7, 8, 9])
    $ python3 variable_arguments_02.py
    [1, 2, 3, 4, 5, 6, 7, 8, 9]
    1 2 3 4 5 6 7 8 9
    コンソール出⼒
    コンソール出⼒
    /chapter3/variable_arguments_01.py
    /chapter3/variable_arguments_02.py

    View Slide

  109. コラム: help関数で関数の詳細を確認する
    • 「help関数」の引数に関数名をあたえることで、その関数の詳
    細を確認することができる
    • 引数などを忘れた場合にインタプリタですぐに確認できる
    >>> help(print)
    Help on built-in function print in module builtins:
    print(...)
    print(value, ..., sep=' ', end='\n', file=sys.stdout, flush=False)
    Prints the values to a stream, or to sys.stdout by default.
    Optional keyword arguments:
    file: a file-like object (stream); defaults to the current sys.stdout.
    sep: string inserted between values, default a space.
    end: string appended after the last value, default a newline.
    flush: whether to forcibly flush the stream.
    help関数を使ったprint関数の詳細確認

    View Slide

  110. • None型の値と型名をtype関数で調べてください
    • 先に作成したmyabs関数を「ifブロック内でマイナスをプラス
    に戻した値をreturnで返す」ように変更してください
    • 2つの引数を受け取り、⼤きい側の引数を返すmymax関数を作
    成してください
    • mymax関数をキーワード引数で呼び出してください
    • help関数で今まで学んだPython標準の関数のなにかを調べてく
    ださい
    演習

    View Slide

  111. 名前空間と関数型について知る
    • このセクションで学ぶこと
    • 関数の中にある変数の扱い
    • global宣⾔
    • 名前空間
    • 関数型
    • 関数を受け取る関数
    SECTION
    04

    View Slide

  112. 関数の中にある変数の扱い (1/2)
    • 関数の外では関数内で定義された変数を使えない(アクセスでき
    ない)
    • アクセスできない変数を参照しようとするとエラーが発⽣
    def test(x):
    y = x + 1
    return y
    print(test(5))
    print(y)
    $ python3 name_space_02.py
    6
    Traceback (most recent call last):
    File "name_space_02.py", line 6, in
    print(y)
    NameError: name 'y' is not defined
    コンソール出⼒
    /chapter3/name_space_02.py

    View Slide

  113. 関数の中にある変数の扱い (2/2)
    • 関数の外で定義された変数は、関数内でも参照できる
    • 関数内で関数外の変数を上書きしても、関数外の変数の値は変
    わらない(厳密には関数内部に同じ名前の変数が定義され、それ
    に代⼊されているという動きをしている)
    a = 1
    def test():
    print(a)
    test()
    $ python3 name_space_03.py
    1
    a = 1
    def test():
    a = 10
    test()
    print(a)
    $ python3 test1.py
    1
    コンソール出⼒ コンソール出⼒
    /chapter3/name_space_03.py
    test1.py

    View Slide

  114. global宣⾔
    • 「グローバル宣⾔(global)」を変数にすることで、関数外の変
    数を関数内で上書きできるようになる
    • グローバル宣⾔の利⽤は⾮推奨。関数外の変数を上書きしたい
    のであれば、関数の返り値を変数に再代⼊するのが⼀般的
    a = 1
    def test():
    global a
    a = 10
    test()
    print(a)
    $ python3 name_space_04.py
    10
    コンソール出⼒
    /chapter3/name_space_04.py

    View Slide

  115. 名前空間 (1/2)
    • 変数を参照できるスコープ(エリア)を「名前空間」と呼ぶ
    • 基本的には「中から外の変数は参照できる」「中で外の変数に
    代⼊しない」「外から中の変数は参照できない」と覚えておく
    名前空間のまとめ図
    細かいですが理解してください

    View Slide

  116. 名前空間 (2/2)
    • 名前空間を使う鉄則(中級者向けトピック)
    • どこからでも参照できる変数は「どこでどういった操作が⾏
    われるか」管理しにくく、バグになりやすい
    • あえて変数が利⽤できる範囲を狭めることで、その変数の使
    いみちを分かりやすくし、変な状態にならないようにする
    • 「グローバル変数(どのブロックにも属さない⼀番上のレベ
    ルの変数)」は可能な限り利⽤しないようにして、関数内の
    変数やクラスで定義された変数(5章)を使うこと

    View Slide

  117. 関数型
    • Pythonの関数も「関数型(概念)」の値(具体的なデータ)
    • print関数は関数型の値の1つであり、len関数も同様
    • type関数に関数を与えることで関数型である確認ができる
    • 関数型の値は変数に代⼊でき、変数経由で関数を呼び出せる。
    上級者向けのプログラミングテクニックでよく使う
    >>> type(abs)

    >>> def my_abs(x):
    ... if x < 0:
    ... x *= -1
    ... return x
    ...
    >>> type(my_abs)

    >>> fun = abs
    >>> fun(-5)
    5
    コンソール出⼒
    組み込み関数と⾃作関数の型の確認。厳密には違うが区別しなくてよい

    View Slide

  118. 関数を受け取る関数
    • 関数Aの引数として関数Bを渡す場合がある。関数Aの挙動を関
    数Bで調整する。関数を受け取る関数を「⾼階関数」と呼ぶ。
    • たとえばソートの基準を関数として定義し、その基準通りに
    ソートを実施するなど
    a = [5, -7, 0, 9, -3]
    print(sorted(a))
    a = [5, -7, 0, 9, -3]
    def my_abs(x):
    if x < 0:
    x *= -1
    return x
    print(sorted(a, key=my_abs))
    $ python3 sort_argument_01.py
    [-7, -3, 0, 5, 9]
    $ python3 sort_argument_02.py
    [0, -3, 5, -7, 9]
    コンソール出⼒
    コンソール出⼒
    /chapter3/sort_argument_01.py
    /chapter3/sort_argument_02.py
    keyはキーワード引数(デフォルト付き)の指定

    View Slide

  119. コラム: 制御構⽂の名前空間
    • Pythonではifやforなどの制御⽂のブロックで宣⾔した変数は、
    そのブロック外でも参照できる
    • 他のプログラミング⾔語では参照できないものが多いので注意
    def fun(x):
    if x == 1:
    y = 5
    else:
    y = 10
    print(y)
    fun(1)
    $ python3 test.py
    5
    test.py
    コンソール出⼒
    変数yは条件分岐の構⽂内で宣⾔されているので、
    print⽂があるブロック(関数)より内側にある。
    問題なくアクセスできている

    View Slide

  120. • Pythonの名前空間の動きを説明してください
    • 関数内から関数外の変数のアクセス
    • 関数外から関数内の変数のアクセス
    • global宣⾔の効果
    • なぜglobal宣⾔が推奨されないか
    • 関数で関数外の変数を更新したいときはどのような関数とす
    るのが望ましいか
    • sorted関数に⾃作関数を渡して降順ソート(⼤きいものから
    ⼩さいものへ)を実現してください
    演習

    View Slide

  121. 組み込み関数を活⽤する
    • このセクションで学ぶこと
    • for⽂で便利なrange関数
    • リストを扱うのに便利な関数
    • filter関数でリストの要素を絞り込む
    • map関数でリストをまとめて処理する
    SECTION
    05

    View Slide

  122. for⽂で便利なrange関数
    • 「range関数」で数字の連番(0,1,2...など)を作れる
    • 利⽤法1: 引数を1つ与えて0からその値-1までの連番を作る
    • 利⽤法2: 引数を1つ与えて「1つめの引数の値」から「2つめの
    引数の値 - 1」までの連番を作る
    • 「N回ループする」ときにfor⽂と利⽤法1の組み合わせが便利
    a = range(5)
    print(a)
    print(list(a))
    for i in range(2,5):
    print(i)
    $ python3 range_01.py
    range(0, 5)
    [0, 1, 2, 3, 4]
    $ python3 range_02.py
    2
    3
    4
    コンソール出⼒ コンソール出⼒
    /chapter3/range_02.py
    /chapter3/range_01.py

    View Slide

  123. リストを扱うのに便利な関数
    • len関数: リスト⻑さの取得
    • max関数: 引数の最⼤値を取得。引数はリストか可変⻑引数
    • min関数: 引数の最⼩値を取得。引数はリストか可変⻑引数
    list1 = [4, 2, 5, 8, 9, 1]
    print(len(list1))
    print(max(list1))
    print(min(list1))
    コンソール出⼒
    /chapter3/len_max_min.py
    $ python3 len_max_min.py
    6
    9
    1

    View Slide

  124. filter関数でリストの要素を絞り込む
    • リストから特定条件を満たす要素を取り出す処理は多⽤する
    • 「filter関数」にリストと条件判定の関数を与えて実現可能
    • 返り値はループで直接使えるが、リスト型ではないので注意が
    必要。リストが必要な場合は「list関数」でキャストする
    $ python3 filter.py
    [4, 2, 8]
    def is_even(x):
    return x % 2 == 0
    list1 = [4, 2, 5, 8, 9, 1]
    filter_object = filter(is_even, list1)
    list2 = list(filter_object)
    print(list2)
    コンソール出⼒
    /chapter3/filter.py
    リスト型へのキャスト

    View Slide

  125. map関数でリストをまとめて処理する
    • リストの要素全てに特定の処理を施す場⾯は多い
    • 「map関数」にリストと関数を与えると、リストの全要素に関
    数の処理を実施した結果を返す
    def add5(x):
    return x + 5
    list1 = [4, 2, 5, 8, 9, 1]
    map_object = map(add5, list1)
    for i in map_object:
    print(i)
    $ python3 map.py
    9
    7
    10
    13
    14
    6
    コンソール出⼒
    /chapter3/map.py

    View Slide

  126. • range関数とforループを使って指定された数だけ「hello」と出
    ⼒する関数を作成してください
    • 正と負の整数を持つリストをfilter関数と⾃作関数を使って正の
    整数のみを抽出したリストにしてください。たとえば[5, -3, 8,
    -1, 4]を与えると[5, 8, 4]が得られます
    • map関数を使って数値を含むリストを⽂字列を含むリストに変
    換してください。たとえば[5, -3, 8, -1, 4]を与えると['5', '-3',
    '8', '-1', '4']が得られます
    演習

    View Slide

  127. オブジェクト指向を理解しよう
    CHAPTER
    4
    1. オブジェクトとメソッドの関係を理解する
    2. リストオブジェクトを操作する
    3. 不変オブジェクトを操作する
    4. その他のデータ型を理解する

    View Slide

  128. オブジェクトとメソッドの関係を理解する
    • このセクションで学ぶこと
    • オブジェクトとは
    • メソッドでListインスタンスを操作する
    • メソッドの副作⽤と返り値
    • コラム: dir関数を使ったオブジェクトのメソッド確認
    SECTION
    01

    View Slide

  129. オブジェクトとは
    • ⽂字列型や整数型には概念と実データが存在する
    • 型の概念のことを「クラス」と呼ぶ
    • 型の実データ(値)を「インスタンス」や「オブジェクト」と呼ぶ

    View Slide

  130. メソッドでListインスタンスを操作する (1/2)
    • 「メソッド」はインスタンスを操作するための特別な関数
    • インスタンス(値そのものか変数)の後ろに「.(ドット)」を置き、
    続けてメソッド名とメソッドの引数を記述する
    • appendメソッド: 対象のインスタンスに要素を追加
    • reverseメソッド: 対象のインスタンスの要素の順序を反転
    a = ['ab', 'cd', 'ef']
    print(a)
    # リストに値を追加
    a.append('gh')
    print(a)
    $ python3 object_02.py
    ['ab', 'cd', 'ef']
    ['ab', 'cd', 'ef', 'gh']
    a = ['ab', 'cd', 'ef', 'gh']
    a.reverse() # リストの要素を反転
    print(a)
    $ python3 object_03.py
    ['gh', 'ef', 'cd', 'ab']
    コンソール出⼒
    コンソール出⼒
    /chapter4/object_02.py
    /chapter4/object_03.py

    View Slide

  131. メソッドでListインスタンスを操作する (2/2)
    • メソッドの操作対象はインスタンス内のデータ
    • インスタンス内ではデータと処理が密接に結びついている
    • 利⽤できるメソッドはインスタンスの型に依存する。たとえばList
    型インスタンスと⽂字列型インスタンスが使えるメソッドは違う

    View Slide

  132. メソッドの副作⽤と返り値
    • 「副作⽤」は操作によりオブジェクトの状態が変化すること
    • メソッドには以下のパターンが存在する
    • 副作⽤はあるが、返り値はない(Listのappendメソッド)
    • 副作⽤はなく、返り値がある(Listのcountメソッド)
    • 副作⽤も返り値もある(Listのpopメソッド)
    • 副作⽤も返り値もない(呼び出す意味がないので普通はない)
    a = [1,3,5,3,1,3]
    b = a.count(3)
    print(b)
    print(a)
    $ python3 object_05.py
    3
    [1, 3, 5, 3, 1, 3]
    a = [1,3,5,3,1,3]
    b = a.pop(0)
    print(b)
    print(a)
    $ python3 object_06.py
    1
    [3, 5, 3, 1, 3]
    コンソール出⼒ コンソール出⼒
    /chapter4/object_05.py /chapter4/object_06.py
    副作⽤なし
    返り値あり
    副作⽤あり
    返り値あり

    View Slide

  133. コラム: dir関数を使ったオブジェクトのメソッド確認
    • どの型がどういったインスタンスを使えるか記憶しきれない
    • dir関数を使うことでオブジェクトの属性(5章)を確認できる
    • メソッドも属性の⼀部なので確認可能
    >>> dir([])
    ['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__dir__',
    '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__',
    '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__init_subclass__',
    '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__',
    '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__',
    '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'clear',
    'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']
    コンソールで属性(メソッド)の⼀覧を確認

    View Slide

  134. • リストの「[1,2,3,4]」はクラスですか、インスタンスですか
    • 「クラス」と「インスタンス」の関係について説明してくださ

    • インスタンスのメソッドがなにかについて説明してください
    • 以下のリストのメソッドの副作⽤と返り値を説明してください
    • append
    • reverse
    • count
    • pop
    演習

    View Slide

  135. リストオブジェクトを操作する
    • このセクションで学ぶこと
    • リストオブジェクトを操作するメソッド
    • その他のリスト操作
    SECTION
    02

    View Slide

  136. リストオブジェクトを操作するメソッド (1/4)
    • append: リスト末尾に要素を追加する
    • insert: 指定した位置に要素を挿⼊する
    a = ['a', 'b', 'c', 'd', 'e']
    a.append('hello')
    print(a)
    a = ['a', 'b', 'c', 'd', 'e']
    a.insert(3, 'hello')
    print(a)
    $ python3 list_method_01.py
    ['a', 'b', 'c', 'd', 'e', 'hello']
    $ python3 list_method_02.py
    ['a', 'b', 'c', 'hello', 'd', 'e']
    コンソール出⼒ コンソール出⼒
    /chapter4/list_method_01.py /chapter4/list_method_01.py

    View Slide

  137. リストオブジェクトを操作するメソッド (2/4)
    • remove: 指定した要素を削除する。インデックス指定ではなく
    消したい値を指定するので注意
    • reverse: リストの順序を反転させる
    a = ['a', 'b', 'c', 'd', 'e']
    a.remove('c')
    print(a)
    $ python3 list_method_03.py
    ['a', 'b', 'd', 'e']
    a = ['a', 'b', 'c', 'd', 'e']
    a.reverse()
    print(a)
    $ python3 list_method_04.py
    ['e', 'd', 'c', 'b', 'a']
    コンソール出⼒
    コンソール出⼒
    /chapter4/list_method_03.py /chapter4/list_method_04.py

    View Slide

  138. リストオブジェクトを操作するメソッド (3/4)
    • clear: リストの要素を全削除して空にする
    • count: リストに指定した要素がいくつあるか数える
    a = ['a', 'b', 'c', 'd', 'e']
    a.clear()
    print(a)
    a = ['a', 'b', 'c', 'b', 'a']
    count = a.count('b')
    print(count)
    $ python3 list_method_06.py
    2
    $ python3 list_method_05.py
    []
    コンソール出⼒ コンソール出⼒
    /chapter4/list_method_05.py /chapter4/list_method_06.py

    View Slide

  139. リストオブジェクトを操作するメソッド (4/4)
    • index: 指定した値を持つ要素のインデックス番号を取得
    • pop: リストからインデックスを指定して要素を取り出して削除
    a = ['a', 'b', 'c', 'd', 'e']
    index = a.index('d')
    print(index)
    a = ['a', 'b', 'c', 'd', 'e']
    value = a.pop(0)
    print(value)
    print(a)
    $ python3 list_method_07.py
    3
    $ python3 list_method_08.py
    a
    ['b', 'c', 'd', 'e']
    コンソール出⼒
    コンソール出⼒
    /chapter4/list_method_07.py
    /chapter4/list_method_08.py

    View Slide

  140. その他のリスト操作 (1/2)
    • 「in演算⼦」で指定した値がリストに含まれていればTrueを返す
    • 「del⽂」で指定したインデックス番号の要素を削除
    a = 'c' in ['a', 'b', 'c', 'd']
    print(a)
    print('c' in ['a', 'b', 'd'])
    a = ['a', 'b', 'c', 'd', 'e']
    del a[3]
    print(a)
    $ python3 list_operator01.py
    True
    False
    $ python3 list_operator02.py
    ['a', 'b', 'c', 'e']
    コンソール出⼒
    コンソール出⼒
    /chapter4/list_operator_01.py
    /chapter4/list_operator_02.py

    View Slide

  141. その他のリスト操作 (2/2)
    • 「スライス」でリストの要素の⼀部分を取り出せる。元のリストに
    は変化なし
    • a[x:y] : リストaのインデックス番号xからy-1の要素のリストを取得
    • a[:y] : インデックス番号0からy-1までの要素のリストを取得
    • a[x:] : インデックス番号のxから最後までの要素のリストを取得
    • a[:] : リストaをコピーしたリストを取得
    a = ['a', 'b', 'c', 'd', 'e']
    b = a[1:3]
    print(b)
    c = a[:3]
    print(c)
    $ python3 list_operator03.py
    ['b', 'c']
    ['a', 'b', 'c']
    コンソール出⼒
    /chapter4/list_operator_03.py

    View Slide

  142. • 「[1,2,3,4,5]」を持つリストをinsertで「[1,2,3,100,4,5]」にし
    てください
    • 整数を含むリストから偶数だけを抽出したリストを作成してく
    ださい。ただしfilter関数などは使わず「forループ内で事前に作
    成した偶数リストに偶数を追加」という⽅式です。
    • 「[1,2,3,4,5]」というリストをwhileとpopを使って 5, 4, 3, 2, 1
    と逆順序に要素がなくなるまで取り出してください。reverseメ
    ソッドの利⽤は禁⽌です。ヒント: FIFOとスタックというデー
    タ構造を調べてください
    演習

    View Slide

  143. 不変オブジェクトを操作する
    • このセクションで学ぶこと
    • ⽂字列型のメソッドはオブジェクトを変化させない
    • ⽂字列型のメソッド
    • in演算⼦を使った⽂字列型の処理
    • ⽂字列の⼀部を取り出す
    • コラム: メソッドチェーン
    SECTION
    03

    View Slide

  144. ⽂字列型のメソッドはオブジェクトを変化させない (1/2)
    • upper: ⽂字列を⼤⽂字にした「新しい⽂字列を返す」
    • replace: ⽂字列を置き換えた「新しい⽂字列を返す」
    • 上記2つのメソッドを呼び出してもインスタンスは変化しない
    a = 'Hello Python'
    b = a.upper()
    print('Original a : ' + a)
    print('Return val b : ' + b)
    a = 'Hello Python'
    c = a.replace('Hello', 'Hell')
    print('Original a : ' + a)
    print('Return val c : ' + c)
    $ python3 string_method_01.py
    Original a : Hello Python
    Return val b : HELLO PYTHON
    $ python3 string_method_02.py
    Original a : Hello Python
    Return val c : Hell Python
    コンソール出⼒ コンソール出⼒
    /chapter4/string_method_01.py /chapter4/string_method_01.py

    View Slide

  145. ⽂字列型のメソッドはオブジェクトを変化させない (2/2)
    • 「不変オブジェクト」は⾃分⾃⾝を変化させないオブジェクト
    • ほとんどの型は不変オブジェクトではないが、原始的な型(整数
    型や⽂字列型)は不変オブジェクトであることが多い

    View Slide

  146. ⽂字列型のメソッド (1/5)
    • formatメソッド: ⽂字列に値を埋め込む。+演算⼦で⽂字列化し
    て連結するよりも綺麗に書ける
    • ⽂字列中の{}に引数が埋め込まれた⽂字列を返す
    • 埋め込む値の整形やキーワードでの埋め込みもできる(割愛)
    name = 'Tom'
    age = 25
    text = 'Hi, this is {}. {} years old.'.format(name, age)
    print(text)
    $ python3 string_method_03.py
    Hi, this is Tom. 25 years old.
    コンソール出⼒
    /chapter4/string_method_03.py

    View Slide

  147. ⽂字列型のメソッド (2/5)
    • startswithメソッド: 引数の⽂字列で開始されていればTrue
    • endswithメソッド: 引数の⽂字列で終了していればTrue
    print('Hello Python'.startswith('thon'))
    print('Hello Python'.startswith('Hello'))
    print('Hello Python'.endswith('thon'))
    print('Hello Python'.endswith('Hello'))
    $ python3 string_method_04.py
    False
    True
    $ python3 string_method_05.py
    True
    False
    コンソール出⼒ コンソール出⼒
    /chapter4/string_method_04.py /chapter4/string_method_05.py

    View Slide

  148. ⽂字列型のメソッド (3/5)
    • replaceメソッド: 第1引数の⽂字列を第2引数の⽂字列で置き
    換えた⽂字列を返す
    • lowerメソッド: ⽂字列を全て⼩⽂字にした⽂字列を返す
    • upperメソッド: ⽂字列を全て⼤⽂字にした⽂字列を返す
    print('Hello Python'.replace('Python', 'World'))
    print('Hello Python'.replace('Pyth0n', 'World'))
    print('Hello Python'.replace('Python', ''))
    $ python3 string_method_06.py
    Hello World
    Hello Python
    Hello
    >>> a = 'Hello World'
    >>> a.lower()
    'hello world'
    >>> a.upper()
    'HELLO WORLD'
    >>> a.lower() == 'hello world'
    True
    lowerもしくはupperで⼤⽂字⼩⽂字を
    気にせずに⽂字列の合致判定ができる
    コンソール出⼒
    lowerとupperメソッドの確認
    /chapter4/string_method_06.py

    View Slide

  149. ⽂字列型のメソッド (4/5)
    • stripメソッド: ⽂字列の前後の空⽩(半⾓空⽩、改⾏、タブな
    ど)を取り除く
    • joinメソッド: リストの要素を⽂字列で連結する
    print(' hello\n')
    print(' hello\n'.strip())
    list3 = ['taro', '180', '80']
    text = ','.join(list3)
    print(text)
    $ python3 string_method_07.py
    hello
    hello
    $ python3 string_method_10.py
    taro,180,80
    コンソール出⼒
    コンソール出⼒
    /chapter4/string_method_07.py
    /chapter4/string_method_08.py

    View Slide

  150. ⽂字列型のメソッド (5/5)
    • splitメソッド: ⽂字列を特定の⽂字列で分解して⽂字列のリス
    トにする
    • CSV形式をコンマで分けたり、改⾏コードで複数⾏のテキスト
    を⾏ごとに分解する処理によく使われる
    text = 'taro, 180, 80'
    list1 = text.split(',')
    print(list1)
    text = 'taro, 180, 80'
    list1 = text.split(',')
    def apply_strip(text):
    return text.strip()
    list2 = list(map(apply_strip, list1))
    print(list2)
    $ python3 string_method_08.py
    ['taro', ' 180', ' 80']
    $ python3 string_method_09.py
    ['taro', '180', '80']
    コンソール出⼒ コンソール出⼒
    /chapter4/string_method_08.py
    /chapter4/string_method_09.py

    View Slide

  151. in 演算⼦を使った⽂字列型の処理
    • 特定の⽂字列が別の⽂字列内に含まれるかをin演算⼦で判別で
    きる。返り値はTrue/False
    • 複雑な条件で⽂字列判定がしたい場合は8章の正規表現を使う
    print('Hell' in 'Hello')
    print('Ho' in 'Hello')
    $ python3 string_operator_01.py
    True
    False
    コンソール出⼒
    /chapter4/string_operator_01.py

    View Slide

  152. ⽂字列の⼀部を取り出す
    • ⽂字列はシーケンス型(リストなど)の1つ
    • []でインデックスを指定して特定位置の1⽂字を抜き出せる
    • []を使ったスライスで⽂字列の特定箇所を抜き出せる
    • ⽂字列のスライスの利⽤法は4章2節のリストのスライスと同じ
    $ python3 string_operator_02.py
    l
    lo py
    text = 'hello python'
    print(text[3])
    print(text[3:8])
    コンソール出⼒
    /chapter4/string_operator_02.py

    View Slide

  153. コラム: メソッドチェーン
    • 返り値を変数に格納せずに直接メソッドを呼び出せる
    • 鎖状に連ねることから「メソッドチェーン」と呼ばれる

    View Slide

  154. • 不変オブジェクトについて例を使って説明してください
    • ⽂字列型のformatメソッドでテンプレートを埋めてください。
    「'hello {}'」
    • ⽂字列型のlowerを使って⽂字列からbool値を得る関数を作成
    してください
    • 引数が⼤⽂字⼩⽂字を問わず「true」であればTrue
    • それ以外は全てFalse
    • replaceメソッドで⽂字列「"Hello I'm Yuichi"」の名前を⾃分の
    名前に変えてください。
    • メソッドチェーンで「'hello world python'」を1⾏で
    「['HELLO', 'WORLD', 'PYTHON']」にしてください
    演習

    View Slide

  155. その他のデータ型を理解する
    • このセクションで学ぶこと
    • タプルの概要
    • タプルの利⽤⽅法と利⽤例
    • タプルからタプルへの代⼊(アンパック代⼊)
    • タプルやリストを扱う関数
    • セットの概要
    • セット型の操作
    • 辞書型の概要
    • 辞書型の操作
    • 辞書型のメソッド
    • コラム: 基本的な型と制御がプログラミングの中⼼
    SECTION
    04

    View Slide

  156. タプルの概要
    • 複数の異なるデータをまとめて管理するための型。リストに似
    ているが「不変オブジェクト」。データ構造を作る
    • 出席簿を例としたリストとの使い分け
    • タプル: 各⽣徒のデータ(名前、⾝⻑、体重)
    • リスト: ⽣徒1, ⽣徒2, ⽣徒3, ...

    View Slide

  157. タプルの利⽤⽅法
    • 少カッコ()内に各要素をコンマ区切りで並べる。リストと同じ
    • 要素へのアクセスはインデックス番号を使う
    • 要素は上書きできない
    • 要素数は変更できない
    taro = ('taro', 180, 80)
    print(type(taro))
    print(taro[1])
    $ python3 tuple_02.py

    180
    >>> taro = ('taro', 180, 80)
    >>> taro[0] = 'jiro'
    Traceback (most recent call last):
    File "", line 1, in
    TypeError: 'tuple' object does not support item assignment
    >>> del taro[1]
    Traceback (most recent call last):
    File "", line 1, in
    TypeError: 'tuple' object doesn't support item deletion
    インタプリタでの挙動確認
    /chapter4/tuple_02.py
    コンソール出⼒

    View Slide

  158. タプルの利⽤例
    • 表の列(構成が決まっている)をタプルとする
    • 表の⾏(⻑さが変わる)をリストとする
    taro = ('taro', 180, 80)
    jiro = ('jiro', 170, 70)
    saburo = ('saburo', 160, 60)
    list1 = [taro, jiro, saburo]
    sum_height = 0
    for person in list1:
    sum_height += person[1]
    print(sum_height/len(list1))
    $ python3 tuple_03.py
    170.0
    /chapter4/tuple_03.py
    コンソール出⼒

    View Slide

  159. タプルからタプルへの代⼊
    • 「アンパック代⼊」を使うとタプルに含まれる変数群に右側の
    タプルの要素をまとめて代⼊できる
    • 左辺のカッコは省略できる。例「a, b, c = (1, 2, 3)」
    • for⽂の変数や関数の返り値にタプルを使うことが多い
    (name, height, weight) = ('taro', 180, 80)
    print(height)
    taro = ('taro', 180, 80)
    jiro = ('jiro', 170, 70)
    saburo = ('saburo', 160, 60)
    list1 = [taro, jiro, saburo]
    sum_height = 0
    for (name, height, weight) in list1:
    sum_height += height
    print(sum_height/len(list1))
    $ python3 tuple_04.py
    180
    $ python3 tuple_05.py
    170.0
    /chapter4/tuple_04.py
    /chapter4/tuple_05.py
    コンソール出⼒
    コンソール出⼒

    View Slide

  160. タプルやリストを扱う関数
    • 「enumerate関数」でリストの要素をタプル形式にしてイン
    デックス番号を与える
    • 「zip関数」で複数のリストを束ねてタプル形式のリストにする
    list1 = ['a', 'b', 'c', 'd', 'e']
    enum_object = enumerate(list1)
    print(list(enum_object))
    list1 = ['a', 'b', 'c']
    for (index, item) in enumerate(list1):
    print('{} : {}'.format(index, item))
    $ python3 tuple_06.py
    [(0, 'a'), (1, 'b'), (2, 'c'), (3, 'd'), (4, 'e')]
    $ python3 tuple_07.py
    0 : a
    1 : b
    2 : c
    /chapter4/tuple_06.py
    /chapter4/tuple_07.py
    コンソール出⼒
    コンソール出⼒
    enumerateはforループでインデックス値が必要な時に便利

    View Slide

  161. セットの概要
    • 順序と重複がない複数の要素を保持するデータ構造
    • 要素を追加、削除することができるが、Listと異なり同じ要素
    を2つ持つことはできず、要素の順序もない
    • set()で空のセットオブジェクトを作成する
    >>> set1 = set()
    >>> set1.add('apple')
    >>> print(set1)
    {'apple’}
    >>> set1.add('banana')
    >>> print(set1)
    {'banana', 'apple’}
    >>> set1.add('apple')
    >>> print(set1)
    {'banana', 'apple'}
    インタプリタでの挙動確認(詳細は次ページより)

    View Slide

  162. セット型の操作 (1/2)
    • セットオブジェクトの作成⽅法
    • set()
    • {'elem1', 'elem2', 'elem3'}
    • 宣⾔⽅法が後述する辞書型とほぼ同じなので注意。特に「{}」
    はセット型ではなく辞書型のオブジェクトが⽣成されるのはよ
    く間違えるポイント
    >>> set1 = set()
    >>> type(set1)

    >>> set2 = {'elem1', 'elem2', 'elem3'}
    >>> type(set2)

    インタプリタでの挙動確認

    View Slide

  163. セット型の操作 (2/2)
    • addメソッド: 要素を追加
    • removeメソッド: 要素を削除
    • popメソッド: 要素をランダムに取り出し(取り出すとなくなる)
    • in演算⼦: 要素が存在するかチェック。リストより⾼速
    >>> set1 = {'A', 'B', 'C'}
    >>> 'A' in set1
    True
    >>> 'D' in set1
    False
    >>> set1.remove('B')
    >>> set1
    {'C', 'A’}
    >>> a = set1.pop()
    >>> a
    'C’
    >>> set1
    {'A'}
    インタプリタでの挙動確認

    View Slide

  164. 辞書型の概要
    • セットと似ているが要素は「キー(key)」と「バリュー
    (value)」を持つ。キーは重複できないがバリューは重複できる
    • キーを指定してバリューを取得/更新する
    • 同じキーで要素を追加するとバリューが上書きされる
    >>> fruits_dict = dict()
    >>> fruits_dict['apple'] = 'red'
    >>> fruits_dict['banana'] = 'yellow'
    >>> fruits_dict
    {'apple': 'red', 'banana': 'yellow'}
    >>> fruits_dict['apple']
    'red'
    インタプリタでの挙動確認(詳細は次ページより)

    View Slide

  165. 辞書型の操作 (1/3)
    • 辞書オブジェクトの作成⽅法
    • dict()
    • {}
    • {key1:value1, key2:value2, ...}
    • セット型と使う記号が同じ中括弧。違いは要素がキーとバ
    リューのペアになっていることのみ
    • キーの型は⽂字列が⼀般的だが他の型(数値など)も使える
    >>> fruits_dict = {'apple':'red', 'banana':'yellow'}
    >>> type(fruits_dict)

    >>> fruits_dict2 = {}
    >>> type(fruits_dict)

    インタプリタでの挙動確認

    View Slide

  166. 辞書型の操作 (2/3)
    • 辞書オブジェクトからのバリューの取得
    • 書式: OBJECT[KEY]
    • 辞書オブジェクトへの要素の追加
    • 存在しないキー: 新しいキーとバリューのペアが登録される
    • 存在するキー: キーの対となるバリューが更新される
    • 書式: OBJECT[KEY] = VALUE
    >>> fruits_dict = {'apple':'red', 'banana':'yellow'}
    >>> fruits_dict['apple']
    'red'
    >>> fruits_dict['apple'] = 'green'
    >>> fruits_dict['apple']
    'green'
    インタプリタでの挙動確認

    View Slide

  167. 辞書型の操作 (3/3)
    • in演算⼦: キーの存在確認
    • 存在しないキーのバリューを取得しようとするとエラーになる
    • キーの存在が不明な場合は事前にin演算⼦か後述のgetメソッド
    を使うこと
    >>> fruits_dict = {'apple':'red', 'banana':'yellow'}
    >>> 'apple' in fruits_dict
    True
    >>> 'grape' in fruits_dict
    False
    >>> fruits_dict['grape']
    Traceback (most recent call last):
    File "", line 1, in
    KeyError: 'grape'
    インタプリタでの挙動確認

    View Slide

  168. 辞書型のメソッド (1/4)
    • keys: キーの⼀覧をリスト形式で返す
    • values: バリューの⼀覧をリスト形式で返す
    • items: 「キーとバリューのタプル」をリスト形式で返す
    • itemsはforループでの利⽤に便利
    >>> a = {'apple':'red', 'banana':'yellow'}
    >>> a.keys()
    dict_keys(['apple', 'banana'])
    >>> a.values()
    dict_values(['red', 'yellow'])
    >>> a.items()
    dict_items([('apple', 'red'), ('banana', 'yellow')])
    インタプリタでの挙動確認

    View Slide

  169. 辞書型のメソッド (2/4)
    • 辞書型をforループで全て処理する操作
    • for⽂のin演算⼦に辞書オブジェクトを与える: keyでループ
    • for⽂のin演算⼦にitemsメソッドを与える: keyとvalueでループ
    fruits_dict = {'apple':'red', 'banana':'yellow'}
    for key in fruits_dict:
    print(key)
    fruits_dict = {'apple':'red', 'banana':'yellow'}
    for (key, value) in fruits_dict.items():
    print('{} : {}'.format(key, value))
    $ python3 dict_01.py
    apple
    banana
    $ python3 dict_02.py
    apple : red
    banana : yellow
    /chapter4/dict_01.py
    /chapter4/dict_02.py
    コンソール出⼒
    コンソール出⼒

    View Slide

  170. 辞書型のメソッド (3/4)
    • get: キーを指定してバリューを取得する。キーが存在しない場
    合はデフォルト値を取得
    • デフォルト値を指定しない場合はNoneがデフォルト値
    • デフォルト値を取得しても元の辞書オブジェクトに変化なし
    • 似た関数にsetdefaultがある(割愛)
    page_counter = {}
    value = page_counter.get('/hello.html', 0)
    print(value)
    print(page_counter)
    $ python3 dict_03.py
    0
    {}
    /chapter4/dict_03.py
    コンソール出⼒

    View Slide

  171. 辞書型のメソッド (4/4)
    • getメソッドを使うことでカウンターのような実装を簡単に実
    現できる
    • 複雑な初期化処理が必要な場合はin演算⼦を使って以下のよう
    な実装をすることを推奨
    • 存在しない場合: 初期化処理をして辞書オブジェクトに代⼊
    • 存在する場合: 辞書オブジェクトから取得
    page_counter = {}
    page_counter['/page_a.html'] = page_counter.get('/page_a.html', 0) + 1
    page_counter['/page_a.html'] = page_counter.get('/page_a.html', 0) + 1
    page_counter['/page_b.html'] = page_counter.get('/page_b.html', 0) + 1
    print(page_counter)
    $ python3 dict_04.py
    {'/page_a.html': 2, '/page_b.html': 1}
    /chapter4/dict_04.py
    コンソール出⼒

    View Slide

  172. コラム: 基本的な型と制御がプログラミングの中⼼
    • Pythonプログラミングの基本は以下となる
    • ライブラリにある処理はライブラリに任せる
    • ライブラリを使うプログラムは⾃分で作る(貼り合わせ)
    • 後者はこの章までに学んだ基本的な型(数値、⽂字列、リスト、
    タプル、セット、辞書型)を基本的な制御(if, for, while)で操作
    するのが上級者でもおよそコードの8割以上と思われる
    • すでに学んだ関数や今後学ぶクラスや例外処理などは上記の
    ベーシックなプログラムを整理するためのもの。⾼度なプログ
    ラミングテクニックを学ぶ前に基礎を抑えるのが⼤事
    • フルスクラッチで素材から開発するのではなく、ライブラリと
    いう「レゴの出来合いのパーツ」をスマートに⾃分のコードで
    張り合わせて作品を作るのがPython流のプログラミング

    View Slide

  173. コラム: 著者の型の使い分け
    • タプル: 引数や返り値で値をまとめる
    • リスト: 可変⻑の複数の要素を管理するために使う。なにかを
    ループ処理するときに使う第⼀候補。要素探索が遅いので注意
    • セット: 要素の存在チェックが必要な場合にリスト代替で使う
    • 辞書型: リストに似た使い⽅だが、要素をすばやく検索できる
    必要がある場合に使う。辞書型のキーは「データベースでいう
    主キーやインデックス」で、それを使って該当エントリを素早
    く抜き出すようなイメージ。Pythonプログラミングでは辞書型
    が⾮常に便利なので使いこなそう。
    • 余談: 辞書型とListの特徴をあわせ持つ 「順序付き辞書
    (OrderedDict)」などの変種もある

    View Slide

  174. • 数値のリストを受け取り、そこから最⼩値と最⼤値を同時に返
    す関数 get_min_max を作成し、その関数の返り値の最⼩値と
    最⼤値をそれぞれ別の⾏でコンソールに出⼒してください。
    • リスト型での要素の探索に⽐べて、セット型での要素の探索が
    ⾼速である理由をインターネットで調べてください。
    • 数値のリストを受け取り、各数値が何回出現したかをカウント
    する関数を辞書型を使って作成してください。返り値は{数値1:
    出現数1, 数値2:出現数2, ...}という形式とします。
    • 上記関数の出⼒をforループでキーとバリューのペアごとに
    「'{} : {}'.format(key, value)」というフォーマットでプリント
    出⼒してください。
    演習

    View Slide

  175. クラスの使い⽅をマスターしよう
    CHAPTER
    5
    1. クラスの仕組みと設計⽅法を知る
    2. クラスの必要性を理解する
    3. クラスの⾼度な使い⽅を知る

    View Slide

  176. クラスの仕組みと設計⽅法を知る
    • このセクションで学ぶこと
    • クラスとは
    • この章の学習の流れ
    • クラスとメソッドを定義する
    • ⾃分で定義したクラスのインスタンスを作成
    • メソッド定義の第⼀引数selfは⾃動で代⼊される
    • クラスの命名規則
    • インスタンス変数
    • コンストラクタでのインスタンス変数の定義
    • メソッド間のインスタンス変数の共有
    • インスタンス変数の外部からの参照
    SECTION
    01

    View Slide

  177. クラスとは
    • 複雑なデータと処理をまとめるための⽂法
    • クラスを使わないとプログラムが⼤規模化した際に「どの関数
    がどのデータを使うか」を管理しにくくなる
    • クラスで枠を作ることで構造をプログラマに強制する

    View Slide

  178. この章の学習の流れ
    • クラスの概念の理解は難所のため、以下の順を追って学ぶ
    1. Section1 : クラスとメソッドの定義⽅法
    2. Section1 : クラスをインスタンス化する⽅法
    3. Section1 : データ(インスタンス変数)の定義
    4. Section2 : クラスの有無によるプログラムの⽐較
    5. Section3 : その他のトピック

    View Slide

  179. クラスとメソッドを定義する
    • classに続けてクラス名を書く
    • classのブロック内にメソッドを関数と同じくdefで定義
    • メソッドの第⼀引数は常に「self」とする
    class MyClass:
    def plus(self, a, b):
    return a + b
    def minus(self, a, b):
    return a - b
    /chapter5/myclass.py
    クラスの定義
    インスタンスが使うメソッドの定義

    View Slide

  180. ⾃分で定義したクラスのインスタンスを作成
    • 「クラス名()」でインスタンス化をおこなう
    • インスタンス.メソッド名()でメソッドの呼び出しを⾏なう
    • 呼び出し側で引数selfに相当するものを与えていない(後述)
    class MyClass:
    def plus(self, a, b):
    return a + b
    def minus(self, a, b):
    return a - b
    myclass = MyClass()
    a = myclass.plus(5, 3)
    print(a)
    b = myclass.minus(5, 3)
    print(b)
    $ python3 myclass.py
    8
    2
    /chapter5/myclass.py
    コンソール出⼒

    View Slide

  181. メソッド定義の第⼀引数selfは⾃動で代⼊される
    • 引数の数の違い
    • クラスでの定義: 3つ。 下図のminusは「self, a, b」
    • メソッドで与える数: 2つ。数のminusは「7, 5」
    • Pythonのクラスでのメソッド定義のルール
    • 第⼀引数はselfとする
    • selfにはインスタンス⾃⾝が代⼊されている(利⽤法は後述)

    View Slide

  182. クラスの命名規則
    • 単語の区切りを⼤⽂字にする
    • クラス名の例
    • MyClass
    • User
    • BingoMachine
    • この命名ルールは⼀般的に「キャメルケース」と呼ばれる。
    キャメルはラクダで、⼤⽂字⼩⽂字の連なりがラクダのコブの
    ようにぼこぼこしているため

    View Slide

  183. インスタンス変数
    • 「インスタンス変数」は同⼀インスタンスのメソッド間で共有
    される変数
    • インスタンス変数はインスタンスごとに独⽴している
    • 同⼀クラスから作られた複数インスタンスの差はインスタンス
    変数のみ。メソッドの処理などに違いはない
    クラスでインスタンス変数を定義
    - name
    - age
    インスタンスでインスタンス変数に
    具体的な値が代⼊される
    - name = beckey
    - age = 40

    View Slide

  184. コンストラクタでのインスタンス変数の定義
    • Pythonでインスタンス変数を定義するのは「コンストラクタ」
    • コンストラクタは特殊なメソッドで「__init__(self, 初期化のた
    めの引数)」とし、処理でインスタンス変数の初期化を書く
    • 「self.インスタンス変数名 = 初期価値」として変数定義
    • コンストラクタはクラスのインスタンス化時に呼び出される
    class User:
    def __init__(self, x, y):
    self.name = x
    self.age = y
    def dump(self):
    print('name:{}'.format(self.name))
    print('age:{}'.format(self.age))
    ana = User('ana', 30)
    ana.dump()
    $ python3 define_instance.py
    name:ana
    age:30
    /chapter5/define_instance.py
    コンソール出⼒

    View Slide

  185. メソッド間のインスタンス変数の共有
    • メソッドの第⼀引数 selfはオブジェクト⾃⾝
    • コンストラクタ内で⾃分⾃⾝にインスタンス変数を追加(定義)
    • メソッド内で⾃分⾃⾝が持つ変数にアクセス(read/write)
    self: インスタンス⾃⾝
    name age
    コンストラクタ
    __init__
    メソッド
    dump
    初期化
    (作成)
    参照

    View Slide

  186. インスタンス変数の外部からの参照
    • インスタンス変数はメソッド内部だけでなく「インスタンス.イ
    ンスタンス変数名」としても参照できる
    • この利⽤法はJavaなどでは⾮推奨とされるがPythonは問題ない
    ので不必要なセッターやゲッターは作らないこと
    class User:
    def __init__(self, x, y):
    self.name = x
    self.age = y
    def dump(self):
    print('name:{}'.format(self.name))
    print('age:{}'.format(self.age))
    ana = User('ana', 30)
    print(ana.name)
    print(ana.age)
    $ python3 check_instance.py
    ana
    30
    /chapter5/check_instance.py
    コンソール出⼒

    View Slide

  187. • 以下のクラスを作成してください
    • クラス名: User
    • 以下のインスタンス変数を持ち、コンストラクタで初期化
    • id
    • name
    • address
    • 以下のメソッドを持つ
    • dumps: ⽂字列のformatメソッドを使ってCSV形式で「id,
    name, address」を⽂字列で返す
    • 上記クラスをインスタンス化してdumpsの結果を出⼒する
    演習

    View Slide

  188. クラスの必要性を理解する
    • このセクションで学ぶこと
    • ⽐較題材のプログラムについて
    • クラスを使わないプログラムの実装
    • 中級者向け: 関数内での参照と代⼊の違い
    • クラスを使わないプログラムの実⾏
    • クラスを使うプログラムの実装
    • なぜクラスが必要か
    • インスタンスに閉じた副作⽤を使う
    • 正しいクラスの設計ができたら中級者
    SECTION
    02

    View Slide

  189. ⽐較題材のプログラムについて
    • クラスを使うべき理由を具体例(ビンゴマシーン)で確認する
    • 仕組み
    • 1-99の番号が振られたボールをランダムに抽出する
    • 同じボールは⼀度しか出ない
    • 全てのボールがなくなったら終了
    ボール群をリストとする
    リストに要素(ボール)を追加
    リストの要素(ボール)の順序を
    シャッフルして1つ取り出す
    同じ仕組みをクラスなし/ありで実装

    View Slide

  190. クラスを使わないプログラムの実装
    • ビンゴを実現する関数
    • initialize: 1-99のボール揃える
    • get_ball: ランダムにボールを取り出す(ランダム操作は6章)
    • has_ball: まだボールがあるか確認
    • プログラムの問題: 引数経由でしかデータ共有ができない
    import random # ランダムな機能を使うという宣⾔
    def initialize(balls1):
    balls1.clear() # リストを空にする
    balls1.extend(list(range(1, 100))) # リストに1-99を⼊れる
    def get_ball(balls1):
    random.shuffle(balls1) # リストをランダムに並べ替える
    return balls1.pop()
    def has_ball(balls1):
    return len(balls1) != 0
    balls2 = []
    initialize(balls2)
    # ボールがあればビンゴを回す
    while has_ball(balls2):
    print(get_ball(balls2))
    続き
    /chapter5/bingo_01.py

    View Slide

  191. 中級者向け: 関数内での参照と代⼊の違い
    • さきほどのinitializeで引数balls1にリストを代⼊すると失敗する
    • 引数をextendメソッドで参照して要素変更すると成功
    • 深いレベルの知識(ポインタの概念)を理解していないと間違える
    第3章で関数外の変数を
    関数内で更新する例と
    実はほとんど同じ動き
    bingo_01.py
    bingo_02.py

    View Slide

  192. クラスを使わないプログラムの実⾏
    • /chapter5/bingo_01.py: 2ページ前の正しいプログラム
    • /chapter5/bingo_02.py: 参照ではなく代⼊する誤ったプログラム
    $ python3 bingo_01.py
    29
    41
    93
    28
    84
    ...
    32
    22
    5
    49
    83
    80
    13
    $ python3 bingo_02.py
    ボールの初期化に成功している。
    そのあとのランダムな取り出し処理も
    ボールがなくなるまで繰り返す。
    ボールの初期化に失敗してリストが空のまま。
    取り出すボールがないので取り出し処理はおきない
    bingo_01.pyの実⾏結果
    bingo_02.pyの実⾏結果

    View Slide

  193. クラスを使うプログラムの実装 (1/2)
    • クラスを使うことでメソッド間でデータ(ビンゴのボール)をイ
    ンスタンス変数として共有できる
    • あるメソッドでの変更(たとえば初期化や取り出し)が、別のメ
    ソッドでも反映される
    import random
    class Bingo:
    def __init__(self):
    self.balls = list(range(1, 100))
    def get_ball(self):
    random.shuffle(self.balls)
    return self.balls.pop()
    def has_ball(self):
    return len(self.balls) != 0
    bingo = Bingo()
    while bingo.has_ball():
    print(bingo.get_ball())
    続き
    /chapter5/bingo_03.py

    View Slide

  194. クラスを使うプログラムの実装 (2/2)
    • 初⼼者にはクラスという⽂法で難しく⾒えるかもしれない
    • 処理(メソッド)間で「データ(インスタンス変数)を共有するこ
    と」が簡単になる
    • 難しい参照と代⼊の違いを意識しないでも動く

    View Slide

  195. なぜクラスが必要か
    ⽐較項⽬ クラスなし クラスあり
    ⽂法 シンプル 複雑
    変数と関数 同じ空間上に多数存在 クラス内の数は少ない
    データの共有 難しい メソッド間はインスタンス変数を使えば簡単
    データ構造の定義 タプルやリストなどの組み合わせ クラスで構造を定義し、新しい型を作れる
    初期化処理 ⾃分で任意で実⾏ コンストラクタで⾃動で実施
    副作⽤の利⽤ 管理しにくいので避けるべき クラス内では積極的に使うべき
    デバッグ しにくい 整理されているためやりやすい
    総合判断 単純なプログラム向け 複雑なプログラムでは必須
    • 複雑なプログラムを構造化することで、データや制御の流れをシ
    ンプルにできるため。難しさをクラス内に押し込める
    • 逆に⾔えばシンプルなプログラムではクラスを使わなくてもよい
    気になる⼈は「カプセル化」というキーワードで調べてみるとよいかも

    View Slide

  196. インスタンスに閉じた副作⽤を使う
    • ⼀般的にプログラミングでは副作⽤(3章)を減らすのが望ましい
    • ただしインスタンス内の変数にたいしては例外
    • プログラムの影響範囲がクラス定義内と限定的
    • 外部の複雑さをクラス内に押し込むことで全体を綺麗にする
    • インスタンスを使う側が簡単に使えることを最も優先する

    View Slide

  197. 正しいクラスの設計ができたら中級者
    • オブジェクト指向のクラスの⽂法は頑張れば覚えられる
    • 正しいオブジェクト指向の設計は勉強だけでなく経験が必要
    • 上級者でも設計変更は発⽣するので完璧なものを最初から作ろ
    うとするのではなく、作って修正を繰り返して慣れるのがよい
    ブラック
    ボックス
    複雑な
    プログラム
    複雑な
    プログラム
    利⽤する側の
    プログラム
    クラス内部の複雑なプログラムを
    意識せず表⾯的に他のクラスを使う
    分かりやすい
    メソッドの定義

    View Slide

  198. • テキストを追加するクラスを作成してください
    • インスタンス変数 self.text = “”をコンストラクタで定義
    • メソッドadd_text: インスタンス変数self.textに引数のテキスト
    を追加
    演習
    ta = TextAdder()
    ta.text
    ''
    ta.add_text('hello')
    ta.text
    'hello'
    ta.add_text(' world')
    ta.text
    'hello world' 操作イメージ

    View Slide

  199. • ⽂字の出現数(空⽩を含む)をカウントするクラスを作成してく
    ださい
    • コンストラクタ: 引数はselfのみでインスタンス変数
    self.char_counterに{}を設定する
    • メソッド
    • add_text: 引数はselfとtext(⽂字列)で、メソッド内でtextを1
    ⽂字ごとforループで回す。出現する⽂字を
    self.char_counterで数える(ヒント: dictのgetメソッドと初期
    値を使うと実装が簡単)
    • get_counts: インスタンス変数 self.char_counter の値を返
    す。
    演習

    View Slide

  200. クラスの⾼度な使い⽅を知る
    • このセクションで学ぶこと
    • クラス変数
    • クラスメソッド
    • クラスの継承
    • コラム: 初⼼者はあまり継承を使わない?
    SECTION
    03

    View Slide

  201. クラス変数
    • 「クラス変数(定数)」はインスタンスをまたいで共有されるクラス
    レベルの変数(定数)で、クラス直下に定義する
    • クラス内で「クラス名.クラス変数名」で参照や代⼊をおこなう
    class MyClass:
    abc = 'abc'
    DEF_GHI ='def ghi'
    def print_abc(self):
    print(MyClass.abc)
    def set_abc(self, abc):
    MyClass.abc = abc
    a = MyClass()
    b = MyClass()
    # クラス変数の変更前
    a.print_abc()
    b.print_abc()
    # クラス変数の変更後
    a.set_abc('hello python')
    a.print_abc()
    b.print_abc()
    続き
    $ python3 class_var_const.py
    abc
    abc
    hello python
    hello python
    /chapter5/class_var_const.py
    コンソール出⼒

    View Slide

  202. クラスメソッド (1/2)
    • 「クラスメソッド」はクラス外から直接「クラス名.メソッド名()」
    として呼び出せる特別なメソッド
    • メソッド前に「@classmethod」と「アノテーション」を加える
    • クラスメソッド内でインスタンス変数や通常のメソッドは使えない
    class MyClass:
    def __init__(self):
    self.a = 'aaa'
    @classmethod
    def method1(cls):
    print('class method')
    def method2(self):
    print('instance method')
    # インスタンス化してからクラスメソッドを呼び出す
    mc = MyClass()
    mc.method1()
    mc.method2()
    # インスタンス化せずにメソッドを呼び出す
    MyClass.method1()
    MyClass.method2()
    続き
    /chapter5/method.py

    View Slide

  203. クラスメソッド (2/2)
    • メソッド呼び出し可否のまとめ
    • インスタンスでクラスメソッド: 呼び出せる
    • インスタンスで通常メソッド: 呼び出せる
    • クラス名でクラスメソッド: 呼び出せる
    • クラス名で通常メソッド: 呼び出せない(下記エラー)
    • クラスメソッドに似た「スタティックメソッド」もある(割愛)
    $ python3 method.py
    class method
    instance method
    class method
    Traceback (most recent call last):
    File "method.py", line 19, in
    MyClass.method2()
    TypeError: method2() missing 1 required positional argument: 'self'
    コンソール出⼒
    クラス名でメソッドを
    呼び出そうとしてエラー

    View Slide

  204. クラスの継承
    • 「継承」はクラスAの特徴をクラスBに引き継がせる機能
    • 継承元を「親クラス」、親を継承する側を「⼦クラス」と呼ぶ
    • 基本機能を持つ親クラスを⼦クラスが継承して拡張する使い⽅
    • ⼦クラスのクラス名の後のカッコに親クラス名を書く
    class ParentClass:
    def method1(self):
    print('parent method')
    class ChildClass(ParentClass):
    def method2(self):
    print('child method')
    cc = ChildClass()
    cc.method2()
    cc.method1()
    $ python3 succession.py
    child method
    parent method
    ⼦クラスが親クラスのメソッドも呼び出せている
    /chapter5/succession.py
    コンソール出⼒

    View Slide

  205. コラム: 初⼼者はあまり継承を使わない?
    • クラスAにクラスBの機能を取り込む際に何も考えずに継承を使うの
    は間違った使い⽅。継承は「Reader -> TextReader,
    ImageReader」といったように親を⼦がより詳細化する際に使う
    • 単純に機能だけを使いたければクラスA内でクラスBを使えばよい
    • 別クラスの機能を取り込むことを「委譲(デリゲーション)」という
    class ClassA:
    def __init__(self):
    self.class_b = ClassB()
    def use_class_b(self):
    self.class_b.print_hello()
    class ClassB:
    def print_hello(self):
    print('hello')
    class_a = ClassA()
    class_a.use_class_b() /chapter5/define_instance.py
    $ python3 delegation.py
    hello
    コンソール出⼒

    View Slide

  206. • 継承とデリゲーションの使い所について説明してください
    • Pythonのアノテーションがなにか、他にどのようなものがある
    か調べてみてください
    演習

    View Slide

  207. モジュールを利⽤しよう
    CHAPTER
    6
    1. モジュールを利⽤する
    2. ⾃分でモジュールを作成する
    3. 標準ライブラリを利⽤する
    4. 外部パッケージを利⽤する

    View Slide

  208. モジュールを利⽤する
    • このセクションで学ぶこと
    • モジュールによるプログラムの整理
    • 組み込みモジュール
    • 標準ライブラリ
    • 外部パッケージ
    • ⾃作のモジュール
    • モジュールとクラスの違い
    • モジュールを使ってみよう
    • モジュール内のクラスの利⽤
    • 複数のモジュールを組み込む
    • モジュール名を付けずに関数やクラスを呼び出す
    • コラム: from⽂の問題点
    SECTION
    01

    View Slide

  209. モジュールによるプログラムの整理
    • 「モジュール」はプログラムが書かれたファイルのこと
    • 巨⼤な1つのファイルに全てを書くのではなく、分類に沿って
    プログラムを複数ファイルに分けることで全体を整理できる
    • 「パッケージ」は複数のモジュールをおさめるディレクトリ
    • モジュールは以下の以下図の4つに分類できる

    View Slide

  210. 組み込みモジュール
    • 「組み込みモジュール」はPythonがデフォルトで読み込む
    • print関数などの特に宣⾔なく利⽤できる機能が格納されている

    View Slide

  211. 標準ライブラリ
    • 「標準ライブラリ」はPythonをインストールすると⾃動で付属
    してくるモジュール群
    • プログラム内で利⽤する宣⾔をすると、その内部で定義されて
    いる関数やクラスが利⽤できるようになる

    View Slide

  212. 外部パッケージ
    • 「外部パッケージ」はPythonに標準で付属しないモジュール
    • 「pipコマンド」でインターネット上のリポジトリからインス
    トールをすることで使えるようになる
    • インストール後は標準ライブラリと同じように利⽤可能となる

    View Slide

  213. ⾃作のモジュール
    • 1つのファイルに収まりきらないコードを分割して作成する
    • Pythonでは可能な限り⾃分では難しい処理を書かずに標準ライ
    ブラリや外部パッケージを繋ぐ書き⽅が⼀般的

    View Slide

  214. モジュールとクラスの違い
    • モジュールもクラスもプログラムを整理する仕組み
    • モジュールはクラスよりも⼤きい単位でのコードの分割
    • 1つのモジュール内に複数のクラスを含めることができる

    View Slide

  215. モジュールを使ってみよう
    • 数学関係のモジュール「math」(標準ライブラリ)を利⽤する
    • モジュール利⽤の宣⾔: import モジュール名
    • モジュールの関数などの利⽤: モジュール名.関数()
    • 宣⾔はプログラムファイルの先頭周辺で⾏なうのが⼀般的
    # mathモジュールの読み込み
    import math
    # mathモジュールのceil関数の利⽤
    a = math.ceil(5.4)
    print(a)
    # mathモジュールのfloor関数の利⽤
    print(math.floor(5.4))
    $ python3 math_01.py
    6
    5
    モジュールを利⽤する前にimportしないと
    エラーになる。
    プログラムの冒頭でimportするのが慣習
    /chapter6/math_01.py
    コンソール出⼒

    View Slide

  216. モジュール内のクラスの利⽤
    • ⽇時を扱うdatatimeモジュールを使う
    • モジュールのクラスの利⽤: モジュール名.クラス名
    import datetime
    now = datetime.datetime.now()
    print(now)
    >>> import datetime
    >>> datetime

    >>> datetime.datetime

    >>> datetime.datetime.now

    $ python3 datetime_01.py
    2020-04-17 14:44:45.660410
    /chapter6/datetime_01.py
    「datetime.datetime.now」は「モジュール名.クラス名.メソッド名」
    コンソール出⼒

    View Slide

  217. 複数のモジュールを読み込む
    • 必要なモジュールを1⾏ごと宣⾔するのが⼀般的
    • 1⾏にまとめて宣⾔することもできる
    • 利⽤しないモジュールは宣⾔しないこと
    import math
    import time, datetime
    print(datetime.datetime.now())
    time.sleep(3)
    print(datetime.datetime.now())
    $ python3 math_datetime_01.py
    2020-04-17 14:55:04.546417
    2020-04-17 14:55:07.550372
    /chapter6/math_datetime_01.py
    コンソール出⼒

    View Slide

  218. モジュール名を付けずに関数やクラスを呼び出す
    • fromで宣⾔するとモジュール名を省略して利⽤できる
    • from モジュール名 import クラス名や関数名
    • from モジュール名 import *(全て)
    from math import ceil
    from time import *
    print(ceil(5.4))
    sleep(1)
    print(floor(5.3))
    $ python3 from_import_01.py
    6
    Traceback (most recent call last):
    File "from_import_01.py", line 6, in

    print(floor(5.3))
    NameError: name 'floor' is not defined
    /chapter6/from_import_01.py
    コンソール出⼒
    importで指定したクラスや関数のみ読み込み
    モジュールの全てのクラスや関数を読み込み
    読み込んでいないmathのfloorを
    呼び出そうとしたためエラー

    View Slide

  219. コラム: from⽂の問題点
    • fromで*(ワイルドカード)指定するのは⼿間がかからなくて簡単
    • クラスや関数を多いと「関数やクラスがどのモジュールに属し
    ているかが分かりにくくなる」という問題がある
    • from⽂の使い所
    • 短いスクリプトなどで保守されない場合は使って問題ない
    • メンテされる⼤きめのプログラムではきちんとimport⽂を
    使って宣⾔する

    View Slide

  220. • 「組み込みモジュール」「標準ライブラリ」「外部パッケー
    ジ」の違いについて説明してください
    • 標準ライブラリの利⽤演習
    • jsonモジュールをimportしてください
    • 以下のdictを作成してください。{'apple':'red',
    'banana':'yellow'}
    • json.dumps(dictオブジェクト)で辞書データを⽂字列型の
    JSONに変換してください
    • json.loads(⽂字列型のJSON)で辞書データを得てください
    • JSONはPythonに限らずマシン間やサービス間でのやりとり
    に多⽤されるデータ構造なので調べてみてください。
    演習

    View Slide

  221. ⾃分でモジュールを作成する
    • このセクションで学ぶこと
    • モジュールは2つの種類に分けて書く
    • モジュールを作成する
    • モジュールが組み込まれる流れ
    • モジュールの中⾝と開始条件
    • 定義と実⾏コードの分離
    SECTION
    02

    View Slide

  222. モジュールは2つの種類に分けて書く
    • タイプ1: システム特有の汎⽤的な処理をまとめたモジュール。
    ⾃作ライブラリに近く、他のプロジェクトでも再利⽤可能
    • タイプ2: タイプ1のモジュールを使ってシステムを形作るモ
    ジュール。汎⽤処理はタイプ1に押し込むこと。
    タイプ1のモジュールは
    機能ごとに別モジュールに
    分割することが好ましい

    View Slide

  223. モジュールを作成する
    • モジュールA(main.py)がモジュールB(myutil.py)を使う
    • 2つのファイルは同じフォルダに格納する
    • ファイルがあるフォルダに移動してからプログラムを呼び出し
    print('main.py start')
    import myutil
    print('main.py after import')
    def main_test():
    print('main_test() called')
    main_test()
    myutil.myutil_test()
    print('main.py end')
    print('myutil.py start')
    def myutil_test():
    print('myutil_test() called')
    print('myutil.py end')
    $ python3 main.py
    main.py start
    myutil.py start
    myutil.py end
    main.py after import
    main_test() called
    myutil_test() called
    main.py end
    /chapter6/main-myutil1/main.py
    /chapter6/main-myutil1/myutil.py
    同じフォルダに使う側と使われる側の
    Pythonプログラム(モジュール)を置く。
    そのフォルダでプログラムを起動
    コンソール出⼒

    View Slide

  224. モジュールが読み込まれる流れ
    • 起動したファイルの⽂頭から読まれる
    • 途中でimportやfrom⽂があると指定されたモジュールから先に
    読み込み処理をおこなう

    View Slide

  225. モジュールの中⾝と開始条件
    • 複数のモジュールから構成されるプログラムで最初に呼び出さ
    れるモジュールを「エントリポイント」と呼ぶ
    • エントリポイント以外では実⾏処理は書かないことが期待され
    る。つまり定数や関数、クラスの宣⾔のみをおこなう

    View Slide

  226. 定義と実⾏コードの分離 (1/2)
    • エントリポイント以外では定義のみ⾏い処理は実⾏させない
    • 「if __name__ == ' __main__ ':」という条件式を使う
    • 特殊属性 __name__ にはエントリポイントの場合は
    「'__main__'」が、それ以外はモジュール名が⼊る
    • __name__ が'__main__'の場合にのみ処理を実⾏させる
    import myutil
    def start():
    myutil.myutil_test()
    # エントリポイントの場合の処理
    if __name__ == '__main__':
    print('main.py is entry point')
    start()
    この条件はこのプログラムファイルが
    エントリポイントの場合だけ満たされる
    /chapter6/main-myutil2/main.py

    View Slide

  227. 定義と実⾏コードの分離 (2/2)
    import myutil
    def start():
    myutil.myutil_test()
    # エントリポイントの場合の処理
    if __name__ == '__main__':
    print('main.py is entry point')
    start()
    def myutil_test():
    print('myutil_test() called')
    print('__name__ of myutil : ' + __name__)
    # エントリポイントの場合の処理
    if __name__ == '__main__':
    print('myutil.py is entry point')
    myutil_test()
    $ python3 main.py
    main.py is entry point
    myutil_test() called
    __name__ of myutil : myutil
    $ python3 myutil.py
    myutil.py is entry point
    myutil_test() called
    __name__ of myutil : __main__
    /chapter6/main-myutil2/main.py
    /chapter6/main-myutil2/myutil.py
    コンソール出⼒ コンソール出⼒
    他から使われるモジュールではエントリポイントを
    「モジュールのテストの実施」に使うとよい。
    モジュールレベルでの完成度が得られるまでテストする
    myutilの実⾏処理は動作していない

    View Slide

  228. • モジュール mymath.py を作成して⼩数点を受け取る「切り下
    げ: floor」と「切り上げ: ceil」を関数として作成してください。
    • ヒント: 切り下げはint型への変換、切り上げは「もとの値と切
    り下げ値が同⼀なら切り下げ値、そうでなければ切り下げ+1」
    で実装できます。⾯倒ならmathモジュールを使ってください
    • 5.1 -> 切り下げ:5, 切り上げ6
    • 5.0 -> 切り下げ:5, 切り上げ5
    • 等号演算⼦(==)で5.0と5を⽐較するとTrueになる
    • main.py モジュールで上記のmymathをimportし、切り上げと
    切り下げの計算を確認してください
    • main.pyではエントリポイントとして起動された時だけ上記処
    理を実施するために「if __name__ == '__main__': 」を使って
    ください
    演習

    View Slide

  229. 標準ライブラリを利⽤する
    • このセクションで学ぶこと
    • 時間関連の処理をおこなうtimeモジュール
    • 時間関連の処理をおこなうdatetimeモジュール
    • 乱数を⽣成するrandomモジュール
    SECTION
    03

    View Slide

  230. 時間関連の処理を⾏うtimeモジュール
    • 時間を扱う基本的な処理
    • time.sleep(x): x秒のスリープ
    • time.time(): 現在のUNIX時間(世界標準時の1970年1⽉1⽇から
    何秒経過したか)を取得する
    • ある作業の前後で時間を取得し差分から実⾏時間を測定できる
    import time
    start = time.time()
    print(start)
    time.sleep(10)
    end = time.time()
    print(end)
    print(end - start)
    $ python3 time_01.py
    1587107549.013738
    1587107559.0178628
    10.004124879837036
    /chapter6/time_01.py
    コンソール出⼒

    View Slide

  231. 時間関連の処理を⾏うdatetimeモジュール
    • 時刻を扱うモジュール。⼈間の時間(2020年4⽉17⽇ 16:00な
    ど)はtimeではなくdatetimeが使いやすい
    • datetime.datetime.today(): 現在時刻の取得し、datetimeイン
    スタンスを返す
    • datetimeインスタンスには様々なメソッドと変数がある
    $ python3 datetime_02.py
    2020-04-17 16:16:31.147644
    2020/4/17 16:16:31
    import datetime
    now = datetime.datetime.today()
    print(now)
    print('{}/{}/{} {}:{}:{}'.format(now.year, now.month, now.day,
    now.hour, now.minute, now.second))
    /chapter6/datetime_02.py
    コンソール出⼒

    View Slide

  232. 乱数を⽣成するrandomモジュール
    • 乱数(ランダムな値)を⽣成するモジュール
    • random.random(): 0から1のあいだのランダムな⼩数を得る
    • random.randint(x, y): 引数のあいだにあるランダムな整数を得る
    • random.shuffle(): 引数のリスト要素をランダムに並び替える
    import random
    print(random.random())
    print(random.randint(0, 100))
    import random
    numbers = list(range(10))
    print(numbers)
    random.shuffle(numbers)
    print(numbers)
    $ python3 random_01.py
    0.2799910238537131
    89
    $ python3 random_02.py
    [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
    [4, 9, 3, 7, 1, 6, 5, 2, 0, 8]
    /chapter6/random_01.py
    /chapter6/random_02.py
    コンソール出⼒
    コンソール出⼒

    View Slide

  233. • 3章の⾃作のソート関数を⾃作モジュールのmysortに定義して、
    簡単なリストがきちんとソートされるか確認してください
    • randomモジュールを使って「0から100万」まででランダムに
    ⽣成した数値を1000個持つリスト⽣成してください
    • ⾃作の関数とPythonが提供するsorted関数で昇順ソートしてく
    ださい
    • Timeモジュールを使って⾃作のsort関数とPythonが提供する
    sort関数の処理時間を⽐較計測してください
    演習

    View Slide

  234. 外部パッケージを利⽤する
    • このセクションで学ぶこと
    • 外部パッケージでPythonに機能を追加する
    • パッケージをインストールする
    • パッケージを利⽤する
    • コラム: ライブラリの使い⽅と探し⽅
    SECTION
    04

    View Slide

  235. 外部パッケージでPythonに機能を追加する
    • 標準ライブラリにない処理であっても⼀般的な処理(たとえば後
    述するHTTPの操作)は外部パッケージに多く存在する
    • Python Package Indexにパッケージが集積されている
    • 有名なライブラリは信頼性が⾼いが無名なものは利⽤に注意

    View Slide

  236. パッケージをインストールする
    • Pythonインストール時に付属する「pipコマンド」を使う
    (Linuxのyumやaptに相当する)
    • Windows: pip install <パッケージ名>
    • Mac: pip3 install <パッケージ名>
    PS C: \Users\yito8> pip install requests
    Collecting requests
    Using cached requests-2.13.0-py2.py3-none-any.whl
    Installing collected packages: requests
    Successfully installed requests-2.13.0
    $ pip3 install requests
    Collecting requests
    Using cached .../requests-2.23.0-py2.py3-none-any.whl
    Installing collected packages: requests
    Successfully installed requests-2.23.0
    Windowsでのpipを使ったrequestsのインストール
    Macでのpipを使ったrequestsのインストール

    View Slide

  237. パッケージを利⽤する
    • pipでインストールしたパッケージは標準ライブラリと同じく
    import⽂もしくはfrom⽂で使える
    • インストールしていないパッケージをimportするとエラー
    import requests
    response = requests.get('http://www.yahoo.co.jp/')
    print(response.text)
    $ python3 requests_01.py
    ...
    /chapter6/requests_01.py
    コンソール出⼒

    View Slide

  238. コラム: ライブラリの使い⽅と探し⽅
    • ⾃分で特定の機能を実装する前に有名なパッケージがないか調
    べてみるのがよい。低レイアの実装は可能な限り避けること
    • Googleで「python ライブラリ <やりたいこと>」と調べると
    パッケージの利⽤法ページやQAページがヒットすることが多い
    • 標準ライブラリの利⽤法はPythonの公式ドキュメントにある

    View Slide

  239. • pip(pip3)でcowsayパッケージをインストールしてください
    • インタプリタでcowsay.関数名(⽂字列)を実⾏してください
    • 関数⼀覧[ʻbeavisʼ, ʻcheeseʼ, ʻdaemonʼ, ʻcowʼ, ʻdragonʼ,
    ʻghostbustersʼ, ʻkittyʼ, ʻmeowʼ, ʻmilkʼ, ʻstegosaurusʼ, ʻstimpyʼ,
    ʻturkeyʼ, ʻturtleʼ, ʻtuxʼ]
    演習
    >>> import cowsay
    >>> cowsay.cow('hello python')
    ____________
    < hello python >
    ============
    \
    \
    ^__^
    (oo)\_______
    (__)\ )\/\
    ||----w |
    || ||

    View Slide

  240. ファイルの読み書きと例外処理を⾏おう
    CHAPTER
    7
    1. テキストファイルの読み書きを⾏う
    2. 予期しないエラーに例外処理で対応する
    3. Pythonで⽇本語の⽂字列を扱う
    4. プログラムへのユーザー⼊⼒を利⽤する

    View Slide

  241. テキストファイルの読み書きを⾏う
    • このセクションで学ぶこと
    • ファイルの読み書き処理はテキストエディタと同じ
    • テキストファイルの読み込み
    • ファイルのクローズ
    • ファイルの書き込み処理
    • ファイルの追記処理
    • バイナリデータの読み書き処理
    • コラム: バイナリデータの処理
    SECTION
    01

    View Slide

  242. ファイルの読み書き処理はテキストエディタと同じ
    • ファイル操作の流れ
    1. ファイルをモード(Read/Write/Append)を指定して開く
    2. ファイルを操作する
    3. ファイルを閉じる
    • Pythonでファイルの読み書きには「open」関数を使う
    • 関数の返り値のファイルオブジェクトのメソッドでファイル操作
    hello world
    hello python
    fin = open('hello.txt', 'r')
    print(fin)
    $ python3 open_01.py
    <_io.TextIOWrapper name='hello.txt' mode='r' encoding='UTF-8'>
    コンソール出⼒
    /chapter7/hello.txt
    /chapter7/open_01.py

    View Slide

  243. テキストファイルの読み込み
    • open関数の第⼆引数を「r」にして読み込み専⽤のファイルオ
    ブジェクトを取得する
    • 読み込みモードでの主要な操作
    • readメソッド: ファイルの内容を全て読み込む
    • forループ: ファイルの1⾏ずつループ処理する。省メモリ
    fin = open('hello.txt', 'r')
    text = fin.read()
    print(text)
    hello world
    hello python
    $ python3 open_02.py
    hello world
    hello python
    fin = open('hello.txt', 'r')
    i = 1
    for line in fin:
    line = line.rstrip()
    print('{} {}'.format(i, line))
    i += 1
    $ python3 open_03.py
    1 hello world
    2 hello python
    コンソール出⼒
    コンソール出⼒
    /chapter7/hello.txt
    /chapter7/open_02.py
    1⾏ずつ⾏番号とテキストを出⼒: /chapter7/open_03.py
    巨⼤なファイルには
    必ずforループを使う

    View Slide

  244. ファイルのクローズ
    • OSのリソースの開放と「書き込み処理を確実にする」ために
    ファイル操作終了後にファイルオブジェクトをクローズする
    • 「close」メソッドを使う
    fin = open('hello.txt', 'r')
    text = fin.read()
    fin.close()
    hello world
    hello python
    $ python3 close_01.py
    コンソール出⼒
    /chapter7/hello.txt
    /chapter7/close_02.py

    View Slide

  245. ファイルの書き込み処理
    • openする際に「w(write)」モードを指定する
    • オープン時にファイル内容が全削除される
    • writeメソッドでテキストを書き込む
    • 改⾏は付与されないので必要ならテキストに「\n」を追加
    fout = open('test.txt', 'w')
    fout.write('write text1\n')
    fout.write('write text2\n')
    fout.close()
    $ python3 write_01.py
    write text1
    write text2
    コンソール出⼒
    /chapter7/test.txt
    /chapter7/write_01.py

    View Slide

  246. ファイルの追記処理
    • すでにあるファイルの末尾にデータを書き込むには
    「a(append)」を指定して追記モードでファイルを開く
    • 開いたあとの操作は「w」モードと同じ
    fout = open('test.txt', 'a')
    fout.write('write text3\n')
    fout.close()
    write text1
    write text2
    write text3
    write text1
    write text2
    write text3
    write text3
    $ python3 write_02.py
    $ python3 write_02.py
    コンソール出⼒
    /chapter7/test.txt(1回⽬の実⾏)
    /chapter7/test.txt(2回⽬の実⾏)
    /chapter7/write_02.py

    View Slide

  247. バイナリデータの読み書き処理
    • 画像などのバイナリデータはモードに「b(binary)」を加える
    • 読み込みモード: 「rb」
    • 書き込みモード: 「wb」
    fi = open('sample.png', 'rb')
    image = fi.read()
    fi.close()
    fo = open('test.png', 'wb')
    fo.write(image)
    fo.close()
    $ python3 write_03.py
    コンソール出⼒
    /chapter7/sample.png
    /chapter7/test.png
    画像ファイルのコピー: /chapter7/write_03.py

    View Slide

  248. コラム: バイナリデータの処理
    • バイナリデータを直接ユーザー操作することは少ない
    • たとえばPILモジュールによる画像操作(サイズを⼩さくする)
    1. ファイルからバイナリデータを読み込む
    2. ライブラリにバイナリデータを渡す
    3. ライブラリでデータ加⼯(画像サイズを⼩さくする)
    4. バイナリデータをライブラリから取得
    5. バイナリデータをファイルに書き込む
    • 「io.BytesIO」でバイナリをファイルに⾒せる処理をバイナリ
    系の操作ではよく使う。ファイルパスが求められるところにバ
    イナリを与えたり、ファイルに書き出すのではなくバイナリを
    書き出すなどができる
    データ操作は
    ライブラリ
    任せ

    View Slide

  249. • テキストファイルを読み込んで、各⾏を逆に出⼒したファイル
    を書き出す。各⾏処理はforループがおすすめ。
    • 発展課題: PILモジュールをインストールして画像サイズを編集
    してください。
    • 上記のファイル名指定での動作を確認したら、ライブラリに
    ファイル名を与えるかわり「io.Bytes()」でライブラリにバイ
    ナリデータを渡して、ライブラリからバイナリデータを受け
    取ってファイルに書き出してください
    演習
    abcd
    efgh
    ijkl
    dcba
    hgfe
    lkji
    読み込むファイル 出⼒するファイル
    >>> 'abc'[::-1]
    'cba'
    ヒント: ⽂字列の反転処理

    View Slide

  250. 予期しないエラーに例外処理で対応する
    • このセクションで学ぶこと
    • 例外とは
    • 2種類の例外
    • try/exceptによる例外処理
    • 例外の詳細を取得する
    SECTION
    02

    View Slide

  251. 例外とは
    • 「例外」はプログラムの予期しない動作で発⽣するエラー
    • エラーと例外(英語ではException)はほぼ同じ意味
    • たとえば存在しないファイルを読もうとすると例外が発⽣する
    fin = open('abc.txt', 'r')
    for line in fin:
    print(line)
    fin.close()
    print('finished')
    $ python3 exception_01.py
    Traceback (most recent call last):
    File "exception_01.py", line 1, in
    fin = open('abc.txt', 'r')
    FileNotFoundError: [Errno 2] No such file or directory: 'abc.txt'
    /chapter7/exception_01.py
    コンソール出⼒

    View Slide

  252. 2つのタイプの例外
    • 例外はおおまかに以下の2つに分類できる
    • プログラムのバグから発⽣する例外。⽂法エラーや0除算など
    • 外部要因で発⽣する例外。アクセス先サーバーのダウンなど
    • バグ起因の例外はプログラムを修正して対処することが必要
    • 外部要因の例外は防げないので「例外処理(失敗したときの処理)」
    を定義して対処する

    View Slide

  253. try/exceptによる例外処理 (1/2)
    • 例外発⽣時に処理を継続するために「try/except」⽂を使う
    • try: 例外が発⽣する可能性がある場所
    • except: try内で例外が発⽣した場合におこなわれる処理
    try:
    file_name = 'test.txt'
    print('ファイルの読み込み開始')
    fin = open(file_name, 'r')
    fin.read()
    fin.close()
    print('読み込み成功')
    except:
    print('エラーが発⽣')
    print('プログラムが終了')
    $ python3 exception_02.py
    ファイルの読み込み開始
    読み込み成功
    プログラムが終了
    $ python3 exception_02.py
    ファイルの読み込み開始
    エラーが発⽣
    プログラムが終了
    存在する
    ファイル
    存在しない
    ファイル
    コンソール出⼒
    コンソール出⼒
    /chapter7/exception_02.py エラーが発⽣してもプログラム最後まで実施されている

    View Slide

  254. • tryブロック内の処理はエラー発⽣箇所以降は実⾏されない
    • exceptブロックはエラーが発⽣しなければ実⾏されない
    • try/except後の処理はエラーの有無に関わらず実⾏される
    try/exceptによる例外処理 (2/2)

    View Slide

  255. 例外の詳細を取得する (1/2)
    • except⽂で例外を「例外クラス」の変数に補⾜できる
    • 例外クラスの最も⼀般的なものは「Exception」
    • 例外クラスの種類に応じた例外処理の定義なども可能で、可能
    ならより詳細な例外クラスで実装することを推奨(割愛)
    try:
    fin = open('test999.txt', 'r')
    fin.close()
    except Exception as e:
    print('エラーが発⽣')
    print(e)
    $ python3 exception_03.py
    エラーが発⽣
    [Errno 2] No such file or directory: 'test999.txt'
    /chapter7/exception_03.py
    コンソール出⼒

    View Slide

  256. 例外の詳細を取得する(2/2)
    • 「traceback」モジュールを使うとエラー発⽣時に出⼒されて
    いたメッセージのほぼ全てを補⾜できる
    • エラー発⽣箇所がファイルと⾏単位で分かる
    import traceback
    try:
    fin = open('test999.txt', 'r')
    fin.close()
    except:
    print('エラーが発⽣')
    error_text = traceback.format_exc()
    print(error_text)
    $ python3 exception_04.py
    エラーが発⽣
    Traceback (most recent call last):
    File "exception_04.py", line 4, in
    fin = open('test999.txt', 'r')
    FileNotFoundError: [Errno 2] No such file or directory: 'test999.txt' コンソール出⼒
    /chapter7/exception_04.py
    中級者向け: 例外処理に慣れたら例外クラスを
    指定した「予測していた」例外処理に加えて、
    予測していなかった例外処理をExceptionなどの
    上位の例外クラスでtraceback付きで処理する

    View Slide

  257. • requestsモジュールのgetを例外処理でラップした関数を作成
    してください(6章に従ってインストールが必要)
    • 返り値はタプルで(成功したか, レスポンスのテキスト)とします
    • 例外が発⽣した場合はtracebackをプリントして、(False, '')
    を返す
    • レスポンスに問題がある場合は(False, '')を返す
    • 問題がない場合(True, テキスト)を返す
    • リクエストレスポンスに問題があるかないかは「レスポンスオ
    ブジェクト.ok」で調べられます
    • わざと「存在しないサイトにアクセス」「存在するサイトの存
    在しないURLにアクセス」をしてみてください
    演習

    View Slide

  258. Pythonで⽇本語の⽂字列を扱う
    • このセクションで学ぶこと
    • ⽂字コードとは
    • プログラムファイルの⽂字コード
    • コラム: python2の⽂字コード
    • 様々な⽂字コードのファイルの読み書き
    SECTION
    03

    View Slide

  259. ⽂字コードとは
    • テキストファイル内の⽂字列も01で構成されている
    • 特定の01の組み合わせが「a」や「あ」と解釈されている
    • 同じ⽂字でも「⽂字コード」によって01の組み合わせが異なる
    • 16進数(0,1,...9,A,B,C,D,E)の1桁で2進数4桁「0000-1111」を表
    現できるため、読みやすさで⽂字コードを含むバイナリ表記に
    は16進数を使うのが⼀般的
    ⽂字コード 「a」の⽂字コード 「あ」の⽂字コード
    UTF-8 0x61 0x82A0
    Shift-JIS 0x61 0xA4A2
    EUC-JP 0x61 0xE38182

    View Slide

  260. プログラムファイルの⽂字コード
    • Pythonの標準⽂字コードはUTF-8。これを使うのが基本
    • 諸事情で他の⽂字コードを使う場合はプログラムの冒頭で「ど
    の⽂字コードでプログラムを書いているか」を宣⾔する
    # -*- coding: shift-jis -*-
    print('こんにちは')
    $ python3 encoding_01.py
    こんにちは
    コンソール出⼒
    Shift-Jisで書かれたプログラム: /chapter7/encoding_01.py
    プログラムの⽂字コードの指定。
    プログラムが指定した⽂字コードで
    なければエラーが発⽣する

    View Slide

  261. コラム: python2の⽂字コード
    • Python2のデフォルト⽂字コードはASCII(アルファベットのみ)
    • ⽇本語及びマルチバイト⽂字を使うのであれば⽂頭での⽂字
    コードの宣⾔がUTF-8でも必要
    • ⾊々と⾯倒なので⽇本語を使うのであればPython3を使うべき

    View Slide

  262. 様々な⽂字コードのファイルの読み書き (1/2)
    • OSによってopen関数が想定するデフォルト⽂字コードが異なる
    • Windows(⽇本語環境): Shift-JIS
    • Mac: UTF-8
    fin_sjis = open('sjis.txt', 'r')
    print(fin_sjis.read())
    fin_sjis.close()
    fin_utf8 = open('utf8.txt', 'r')
    print(fin_utf8.read())
    fin_utf8.close()
    $ python3 encoding_02.py
    Traceback (most recent call last):
    File "encoding_02.py", line 2, in
    print(fin_sjis.read())
    File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/codecs.py", line 322, in decode
    (result, consumed) = self._buffer_decode(data, self.errors, final)
    UnicodeDecodeError: 'utf-8' codec can't decode byte 0x82 in position 0: invalid start byte
    • デフォルト⽂字コードと異なる
    ファイルを⽂字コード指定なしに
    openするとエラー
    コンソール出⼒
    /chapter7/encoding_02.py
    MacでUTF-8を期待していたのにShift-Jisをオープンしたのでエラーとなっている

    View Slide

  263. 様々な⽂字コードのファイルの読み書き (2/2)
    • open関数のencode引数で⽂字コードを指定可能
    • マルチプラットフォーム環境も考慮すると以下を推奨
    • テキストファイルの⽂字コードにはUTF-8を利⽤
    • 移植性を考えてMacであってもファイル読み込み時の
    encodeオプションにUTF-8を指定しておく
    • writeモードではopen時に指定した⽂字コードでファイルが書
    き出される
    fin_sjis = open('sjis.txt', 'r', encoding='shift-jis')
    print(fin_sjis.read())
    fin_sjis.close()
    fin_utf8 = open('utf8.txt', 'r', encoding='utf-8')
    print(fin_utf8.read())
    fin_utf8.close()
    $ python3 encoding_03.py
    あいうえお
    かきくけこ
    あいうえお
    かきくけこ
    コンソール出⼒
    /chapter7/encoding_03.py

    View Slide

  264. • 中に書かれている⽂字コードが不明なファイルの⽂字コードを
    特定するプログラムを作成してください
    • UTF-8, Shift-JIS, EUC-JPの3つを判定するものとします
    • AsciiのテキストはUTF-8に分類されるとします
    • ヒント: 指定した⽂字コードで読み込めればその⽂字コード、
    エラーがおきればその⽂字コードでないと分かります
    • 本書籍で提供されているUTF-8とShift-Jisのサンプルファイル
    を使って正しく判別できるか確認してください
    演習

    View Slide

  265. プログラムへのユーザー⼊⼒を利⽤する
    • このセクションで学ぶこと
    • コマンドライン引数による⼊⼒
    • コマンドライン引数の利⽤例
    • input関数での標準⼊⼒
    • input関数の利⽤例
    • コラム: コマンドライン引数 vs 標準⼊⼒
    SECTION
    04

    View Slide

  266. コマンドライン引数による⼊⼒
    • プログラムにユーザー⼊⼒を与える場⾯は多い
    • 解析プログラムで解析するデータのファイル
    • 接続先IPやパスワードなど
    • プログラム内に直接定数で定義するよりユーザーに⼊⼒させた
    ほうがプログラム修正がいらないので利⽤が簡単
    • コンソールでプログラム起動時に与えるパラメーター(コマンド
    ライン引数)を「sys.argv」でリスト形式で取得できる
    $ python3 argument_01.py abcd efgh
    ['argument_01.py', 'abcd', 'efgh']
    import sys
    print(sys.argv)
    起動時にプログラム名に加えて「abcd」「efgh」が与えられている。
    sys.argv(リスト)にプログラムファイルと
    コマンドライン引数が順番に格納されている
    コンソール出⼒
    /chapter7/argument_01.py

    View Slide

  267. コマンドライン引数の利⽤例
    • 指定したファイルを読み込むプログラム
    • コマンドライン引数を使うコツ
    • 引数が指定された数か最初にチェックする
    • sys.argvの要素の値を分かりやすい定数に代⼊する
    import sys
    if len(sys.argv) < 2:
    print('Error. please input file name')
    exit()
    FILE_NAME = sys.argv[1]
    fin = open(FILE_NAME, 'r')
    print(fin.read())
    fin.close()
    $ python3 argument_03.py hello.txt
    hello world
    hello python
    hello world
    hello python
    コンソール出⼒
    /chapter7/argument_03.py
    /chapter7/hello.txt

    View Slide

  268. input関数での標準⼊⼒
    • 「input関数」で標準⼊⼒受け付け(ユーザーのキーボード⼊⼒
    を受け付ける)状態となる
    • エンター(リターン)ボタンが押されたら⼊⼒終了
    print(1)
    a = input('何か⽂字を⼊⼒してください:')
    print('⼊⼒値:' + a)
    print(2)
    $ python3 input_01.py
    1
    何か⽂字を⼊⼒してください:
    $ python3 input_01.py
    1
    何か⽂字を⼊⼒してください:hello
    ⼊⼒値:hello
    2
    コンソール出⼒
    「hello」と⼊⼒しエンターキー
    /chapter7/input_01.py

    View Slide

  269. input関数の利⽤例
    • パラメーター⼊⼒を対話式に⾏なうプログラム
    • IPやパスワードなどを順番に⼊⼒させる
    • 設定項⽬の番号を⼊⼒させ、各項⽬でIPやパスワードを⼊⼒
    • プログラムをあえて⼀時中断させる⽬的
    • デモやテストのステップごとに⽌めて結果を表⽰。確認を終
    えたら次のプログラムに向かう
    file_name = input('please input filename: ')
    fin = open(file_name, 'r')
    print(fin.read())
    fin.close()
    $ python3 input_02.py
    please input filename: hello.txt
    hello world
    hello python
    コンソール出⼒
    ファイル名を聞いて、それを出⼒するプログラム: /chapter7/input_02.py

    View Slide

  270. コラム: コマンドライン引数 vs 標準⼊⼒
    • Pythonのプログラムはシェルスクリプトやバッチなどから呼び
    出されることも多い
    • 標準⼊⼒はユーザーの敷居は低いかもしれないが、他のプログ
    ラムから使いにくくなる
    • コマンドライン引数は呼び出せば動くので、他のプログラムか
    ら使いやすい
    • 特別な理由がなければコマンドライン引数でパラメーターを⼊
    ⼒させるのがよい
    • 第三の⼿法として「環境変数でのパラメーター指定」なども使
    われることがある

    View Slide

  271. • コマンドライン引数と、input関数でそれぞれ以下を実現するプ
    ログラムを作成してください
    • 「数値1, 計算記号, 数値2」を受け取る
    • 対応する計算記号は +, -, *, / の4つ
    • 数値1と数値2を与えられた計算記号で計算した結果をprint
    出⼒する
    • ヒント1: 数値は⽂字列からfloatにキャストする
    • ヒント2: 計算記号の値に応じてif/elseで処理を変える
    演習

    View Slide

  272. アプリケーションを作成しよう
    CHAPTER
    8
    1. アプリケーション開発の流れを知る
    2. 重要箇所をテスト実装する
    3. 本番のプログラムを作る

    View Slide

  273. アプリケーション開発の流れを知る
    • このセクションで学ぶこと
    • プログラム開発の計画を作る
    • ⽬的を実現するためになにが必要かまとめる
    • プログラム全体の流れを考える
    • コラム: 設計とフレームワーク
    SECTION
    01

    View Slide

  274. プログラム開発の計画を作る
    • 題材:インターネットから複数の画像を集めるプログラムを作成
    • アプリケーション開発には計画が必要
    • 本章では以下のステップで開発を進めていく
    • ⽬的を実現するためには何が必要かまとめる
    • プログラム全体の流れを考える
    • プログラムの中の重要な箇所を試験的に作ってみる
    • プログラムの⼤枠を作る
    • コードに機能を追加していき設計や品質を向上させる

    View Slide

  275. ⽬的を実現するためになにが必要かまとめる
    • ⽬的: インターネットから画像を取得する
    • 必要なこと
    • 画像のURLを取得してダウンロード
    • 画像のURLはウェブサイトのHTMLに埋め込まれている
    • 埋め込まれているURLを「正規表現(後述)」で抽出する

    View Slide

  276. プログラム全体の流れを考える
    • 画像ファイルのURLを取得するウェブページのURLが必要
    • ウェブページ1でウェブページと画像URLを集めたら、そこに
    あるウェブページ2で取得。次にウェブページ3と繰り返せる
    • 終了条件や同じURLの再取得を防ぐ⽅法を検討

    View Slide

  277. コラム: 設計とフレームワーク
    • ⼊⾨書は読んで理解できたが、実際にサンプル以上のプログラ
    ムを書けないという⼈が多い
    • フレームワークは「⼤枠のなかの処理を⾃分で実装する」とい
    う⽅式でシステムを作成するので、ライブラリを使って⾃分が
    全てを設計するよりも「設計が簡単」
    • ⾃分で設計をするのは慣れが必要なので、HTML/CSSを学んで
    簡易ウェブフレームワークで簡単な動的なウェブサイトを作っ
    てみるとよいかも
    ライブラリ
    ライブラリ
    ライブラリ
    ⾃分で設計した⼤枠
    作成したパーツ
    フレームワークが⽤意する⼤枠
    作成したパーツ
    作成したパーツ
    独⾃設計のアプリ フレームワークに従うアプリ

    View Slide

  278. 重要箇所をテスト実装する
    • このセクションで学ぶこと
    • なぜテスト実装が必要なのか
    • URLを指定してHTMLを取得
    • 正規表現でHTMLからURLを取得
    • 相対URLを絶対URLに変換
    • URLが画像ファイルか否かを判定
    • 画像ファイルを保存
    SECTION
    02

    View Slide

  279. なぜテスト実装が必要なのか
    • 開発スピードを向上させるため
    • ⼤きなサービスのなかで⼩さな1つの機能を0から開発するの
    は「起動」「準備(テスト値の⽤意など)」に時間がかかる
    • ⼩さなコードでエラーを繰り返しながら機能を実現させ、その
    あとで組み込めばトラブルが少ない
    • 当初の想定と異なる場合があるため
    • 利⽤を想定していたライブラリが⽬的の機能を果たせない場合
    などがある
    • 他を作り込んだうえで発覚すると修正が⼤変なので⼤枠を固め
    る前に可能な限りパーツを作っておく
    • すでに重要箇所が動いているとメンタル的に安⼼して開発できる

    View Slide

  280. URLを指定してHTMLを取得
    • 本番プログラムは⼤きくて複雑なので、「本番でも使いやすい
    テスト⽤のコード(たとえば関数)」を作成するのがよい
    • HTMLの取得には6章のrequestsモジュールを利⽤
    import requests
    def download_html(url):
    response = requests.get(url)
    html = response.text
    return html
    html = download_html('https://gihyo.jp/book/list')
    fout = open('sample.html', 'w', encoding='utf8')
    fout.write(html)
    fout.close()
    $ python3 get_images_01.py

    View Slide

  281. 正規表現でHTMLからURLを取得(1/2)
    • 先に取得したHTML内にはURLが多数ある
    • ウェブサイトや画像のURLを抜き出す処理に正規表現を使う
    • 「正規表現」は 特定のパターンの⽂字列が含まれるかのチェック
    や抜き出し処理をする⼿法。他のプログラミング⾔語にもある
    • 複雑な正規表現のパターンは検索するのが⼿っ取り早い。たとえ
    ば「Python 正規表現 URL」や「Python regex URL」など
    ...
    複雑な正規表現は検索から
    答えを発⾒

    View Slide

  282. 正規表現でHTMLからURLを取得(2/2)
    import re
    text = 'Hello Worldhref="http://example.com">More Exampleshref="http://example2.com">Even More Examples"'
    links = re.findall(']*)', text)
    print(links)
    $ python3 get_url_from_html.py
    ['http://example.com', 'http://example2.com']
    import requests
    import re
    def get_urls(url):
    response = requests.get(url)
    html = response.text
    urls = re.findall(']*)', html)
    return urls
    urls = get_urls('https://gihyo.jp/book/list')
    print(urls)
    $ python3 get_images_02.py
    ['/book', '/site/inquiry', '/site/profile', …
    コンソール出⼒
    コンソール出⼒
    HTMLからURLを抜き出すプログラム: /chapter8/get_url_from_html.py
    指定したURLにアクセスしてURLを抜き出すプログラム: /chapter8/get_images_02.py

    View Slide

  283. 相対URLを絶対URLに変換
    • 絶対URL: https://gihyo.jp/news/info/2020/03/1301
    • 相対URL(ドメインが省略): /news/info/2020/03/1301
    • 相対URLは現在のURLを基準とした表記なので、プログラムで
    使う場合は現在地に依存がない絶対URLへの変換が望ましい
    import urllib.parse
    def get_abs_url(current_url, url):
    abs_url = urllib.parse.urljoin(current_url, url)
    return abs_url
    print(get_abs_url('https://gihyo.jp/book/list', 'http://gihyo.jp/site/inquiry'))
    print(get_abs_url('https://gihyo.jp/book/list', '/book/2017/978-4-7741-8751-8'))
    print(get_abs_url('https://gihyo.jp/book/list', '2017/978-4-7741-8751-8'))
    $ python3 get_abs_url.py
    http://gihyo.jp/site/inquiry
    https://gihyo.jp/book/2017/978-4-7741-8751-8
    https://gihyo.jp/book/2017/978-4-7741-8751-8 コンソール出⼒
    相対URLを絶対URLに変換するプログラム:
    /chapter8/get_abs_url.py

    View Slide

  284. URLが画像ファイルか否かを判定
    • URLを以下の2種類のいずれか拡張⼦で判定する
    • 画像ファイル: 拡張⼦が「.jpg」「.png」「.gif」
    • HTMLファイル: 画像ファイルでない場合全て
    • (厳密にはHTTPレスポンスのMIMEで判断することが望ましい)
    def check_url_type(url):
    if '.jpg' in url:
    print('jpg')
    elif '.png' in url:
    print('png')
    elif '.gif' in url:
    print('gif')
    else:
    print('html')
    urlの画像判定プログラム: /chapter8/check_url_type.py

    View Slide

  285. 画像ファイルを保存
    • requestsで取得したレスポンスからデータを取得
    • データをバイナリ書き込みモードでファイルに保存
    import requests
    import os
    def save_image(url, filepath):
    # 画像データを取得
    response = requests.get(url, stream=True)
    image_data = response.content
    fout = open(fpath, 'wb')
    fout.write(image_data)
    fout.close()
    URLの画像を保存する: /chapter8/save_image.py

    View Slide

  286. • このセクションで作成したプログラムを全て実⾏してみる
    • 関数定義のみで実⾏コードが書かれていないプログラムは、⾃
    分で実⾏コードを作成してください
    演習

    View Slide

  287. 本番のプログラムを作る
    • このセクションで学ぶこと
    • クラスを設計する流れ
    • コンストラクタの実装
    • メソッドの役割を決める
    • メインメソッドの実装
    • 指定ページから絶対URL⼀覧を得るメソッドの実装
    • 絶対URLを画像とHTMLに振り分けるメソッドの実装
    • 画像データを保存するメソッドの実装
    • メインプログラムの実⾏
    • コラム: プログラムのテスト
    SECTION
    03

    View Slide

  288. クラスを設計する流れ
    • 複雑なプログラムでは「関数(メソッド含む)が別の関数を呼び出
    す」を繰り返すことで実現する
    • 関数間で全てのデータを引数で受け渡しするとカオスになるので、
    クラスを使って共有データはインスタンス変数として定義する(詳
    細な理由は5章を参照)
    • クラス設計
    • プログラムが必要とする情報はコンストラクタで受け取る
    • メソッド間で共有されるデータはコンストラクタでインスタン
    ス変数として定義する
    • 処理に応じてメソッドを分けて、中⼼となるメソッドが各機能
    を担当するメソッドを呼び出すシンプルな処理の流れを作る

    View Slide

  289. このアプリケーションの設計概要
    __init__(コンストラクタ)
    インスタンス変数の定義
    run
    メインメソッド
    Whileループで集め
    終わるまで繰り返す
    get_abs_url
    指定URLから絶対値のURL群を取得
    get_image_url_list
    URL群から画像のURL群を取得
    save_images
    画像URL群の画像をローカルに保存
    実⾏
    コード
    クラス定義
    (1)
    (2)
    (3)
    (4)
    (5)
    (6)
    この章での実装順序

    View Slide

  290. コンストラクタの実装
    • 引数
    • save_dirpath: 画像保存場所
    • start_page: 最初にアクセスするURL
    • maximum_download: 集める画像の枚数
    import os
    import re
    import urllib
    import requests
    class ImageCrawller:
    def __init__(self, save_dirpath, start_page, maximum_download):
    self.save_dirpath = save_dirpath
    self.crawl_url_list = [start_page]
    self.stocked_url = set()
    self.maximum_download = maximum_download
    self.download_counter = 0
    • インスタンス変数
    • self.save_dirpath: 引数より
    • self.crawl_url_list: 次にアクセスするURLのリスト
    • self.stocked_url: すでにアクセスしたURLのセット
    • self.maximum_download: 引数より
    • self.download_counter: 何枚保存したか数える
    コンストラクタの定義: /chapter8/image_crawller_01.py

    View Slide

  291. メソッドの役割を決める
    • メソッドの分割について
    • ⼤きい: 処理が多すぎてメソッドの⾒通しが悪くなる
    • ⼩さい: メソッド間の呼び出しが多すぎて分かりにくい
    • 適切な粒度(分割する⼤きさ)が必要
    • 本章で作成するメソッド
    • コンストラクタ(作成済み)
    • 下記3つを束ねる中⼼となるメソッド(メインメソッド)
    • あるURLのHTMLに含まれる絶対URLをリストで返すメソッド
    • URLをHTMLと画像に振り分けるメソッド
    • イメージを保存するメソッド

    View Slide

  292. メインメソッドの実装 (1/2)
    • 荒削りでよいので、全体の処理の流れをコメント付きで書く
    • 細部を実装してからメインメソッドも微修正される
    • 実験的に主要な機能をテストしていないと設計しづらく、あと
    にプログラムの⼤きな修正が発⽣する可能性が⾼まる
    • プログラム(次ページ)の設計
    1. 終了条件に合致していないか確認。合致していれば終了
    2. URL回収⽤のウェブページURLをリストから取得
    3. そのURLにアクセスして絶対URLのリストを取得
    4. 絶対URLのリストを「画像」「ウェブページ」に分類
    5. 画像のURLリストの画像を全て取得
    6. 1に戻る(whileによる無限ループ)

    View Slide

  293. メインメソッドの実装 (2/2)
    def run(self):
    while True:
    # 処理1: 探索するURLがなければ終了。規定数以上を集めていても終了
    if len(self.crawl_url_list) == 0:
    break
    if self.download_counter >= self.maximum_download:
    break
    # 処理2: 次に調べるHTMLのURLを取得
    crawl_url = self.crawl_url_list.pop(0)
    # 処理3: HTMLページから絶対URLを抽出する
    urls = self.get_abs_urls(crawl_url)
    # 処理4: 絶対URLをHTMLかイメージかに分類する。イメージのリストを返す
    image_url_list = self.get_image_url_list(urls)
    # 処理5: リストに格納されたイメージを全て保存する
    self.save_images(image_url_list)
    print('Finished')
    メインメソッドの定義を追加: /chapter8/image_crawller_02.py

    View Slide

  294. 指定ページから絶対URL⼀覧を得るメソッドの実装
    def get_abs_urls(self, url):
    try:
    # URLから⽂字列のHTMLを取得
    response = requests.get(url)
    html = response.text
    # HTMLからURLを抜き出してリストに格納
    relative_url_list = re.findall(']*)', html)
    # 相対URLを絶対URLに変換。HTTP/HTTPS以外のURLは除外
    abs_url_list = []
    for relative_url in relative_url_list:
    abs_url = urllib.parse.urljoin(url, relative_url)
    if abs_url.startswith('http://') or abs_url.startswith('https://'):
    abs_url_list.append(abs_url)
    return abs_url_list
    except Exception as e:
    print('Error: {}'.format(e))
    return []
    メソッドget_abs_urlsを追加: /chapter8/image_crawller_03.py

    View Slide

  295. 絶対URLを画像とHTMLに振り分けるメソッドの実装
    def get_image_url_list(self, url_list):
    try:
    image_url_list = []
    for url in url_list:
    if url in self.stocked_url: # すでに登録されたURLなので無視
    continue
    if '.jpg' in url:
    image_url_list.append(url)
    elif '.png' in url:
    image_url_list.append(url)
    elif '.gif' in url:
    image_url_list.append(url)
    else:
    self.crawl_url_list.append(url) # 画像ファイルではないのでURL取得に使う
    self.stocked_url.add(url) # URLを登録。同じものは再登録しない
    return image_url_list
    except Exception as e:
    print('Error: {}'.format(e))
    return []
    メソッドget_image_url_listを追加: /chapter8/image_crawller_04.py

    View Slide

  296. 画像データを保存するメソッドの実装
    def save_images(self, image_url_list):
    for image_url in image_url_list:
    try:
    # 決められた回数以上のダウンロードをした場合は終了
    if self.download_counter >= self.maximum_download:
    return
    # イメージを取得
    response = requests.get(image_url, stream=True)
    image = response.content
    # イメージをファイルに保存
    file_name = image_url.split('/').pop()
    save_path = os.path.join(self.save_dirpath, file_name)
    fout = open(save_path, 'wb')
    fout.write(image)
    fout.close()
    self.download_counter += 1
    print('saved image: {}/{}'
    .format(self.download_counter, self.maximum_download))
    except Exception as e:
    print('Error: {}'.format(e))
    メソッドsave_imagesを追加: /chapter8/image_crawller_05.py

    View Slide

  297. メインのプログラムの実⾏
    • プログラム最後に「if __name__ == ' __main__ ' :」を定義
    if __name__ == '__main__':
    save_dirpath = 'test'
    start_page = 'https://gihyo.jp/book/list'
    maximum_download = 10
    crawller = ImageCrawller(save_dirpath, start_page, maximum_download)
    crawller.run()
    $ python3 image_crawller_06.py
    saved image: 1/10
    saved image: 2/10
    saved image: 3/10
    saved image: 4/10
    saved image: 5/10
    saved image: 6/10
    saved image: 7/10
    saved image: 8/10
    saved image: 9/10
    saved image: 10/10
    Finished
    コンソール出⼒
    アプリを動かす実⾏コードを追加: /chapter8/image_crawller_06.py

    View Slide

  298. コラム: プログラムのテスト
    • 数⼗⾏以上のコードがミスなく書けていると思わないこと
    • 「ビッグバンテスト」と呼ばれる全てを書き終わってから動かし
    てテストをすることは避けること
    • テストを使ってきちんと動くプログラムを書くコツ
    • モジュールの設計で役割ごとにプログラムファイルを分離
    • 確実に動く⼩さなプログラムを開発してモジュールに組み込む
    • モジュール間の依存関係を減らしてモジュールレベルでテスト
    を実施できるようにする
    • 変更を繰り返した汚いコードは綺麗に書き直す
    • ユニットテストでテストを⾒える化する(中級者)
    • ⾃動化などでテストを勝⼿に⾛らせるようにする(上級者)

    View Slide

  299. • 最初にアクセスするページを変更してアプリケーションを⾃分
    で起動してみる(ウェブサイトに過負荷を与えるのを避けるため
    ⼩規模のサイトは使わないでください)
    • 画像ではなくHTMLを集めて保存するプログラムを作成してく
    ださい
    • 発展課題: HTMLがすでに保存されているファイル名であれば
    名前に連番を付けるなどしてください
    演習

    View Slide

  300. お悩み相談コーナー
    教科書は理解したけど次のレベルに進めません!!
    おまけ
    1. ⼊⾨者卒業: 本を読むよりコードを書くべし
    2. 初級者卒業: 美しい設計を体と頭で覚える
    3. 中級者卒業: 開発はプログラミング以外にもある
    4. 駆け出し編: インフラエンジニアという道もある
    5. 歴史編: 開発とインフラの技術変遷

    View Slide

  301. ⼊⾨者卒業: 本を読むよりコードを書くべし
    • このセクションで学ぶこと
    • プログラミングのレベル
    • 包丁をにぎらず本ばかり読む駆け出し料理⼈
    • やりたいことは書き始めてから考えよう
    • おすすめ1: Flaskによる簡易ウェブサービスの作成
    • おすすめ2: Tkinterによるデスクトップアプリの作成
    • おすすめ3: 業務向けの作業スクリプト作成
    • 著者が興味でプログラムを書いた例
    • ⼊⾨者卒業に難しい知識はいらない
    SECTION
    01

    View Slide

  302. プログラミングのレベル
    • ドラクエと同じで「適切な場所(学習内容)」でレベル上げ
    • 低いレベルで難易度の⾼すぎるエリアには向かわないこと
    • 2010年以降は開発スタイルが⼤きく変わってきている
    ⼊⾨者 初級者 中級者 中上級者
    (オールラウンド型)
    上級者
    (プログラミング特化型)
    ⼊⾨書(2000円ぐらいの書籍)の
    レベルの内容を習得済み。
    • 基礎⽂法はわかる
    • オブジェクト指向を使える
    • 簡単なスクリプトを書ける
    • 簡易フレームワーク習得
    • ⾃分で簡単なアプリを作成できる
    ⾼度なプログラミング知識
    • ⾃分で中規模アプリを作成できる
    • オブジェクト指向を設計可能
    • フルスタックフレームワーク習得
    • デザインパターン習得
    • リファクタリング習得
    • テスト習得
    • 複数のプログラミング⾔語を習得
    3ヶ⽉ 2年
    達⼈プログラマ
    中級者からの純粋レベルアップ
    プログラミング以外も得意
    クラウドの普及で最近増加
    5年
    3年(中級者向けの⾼度なプログラミング知識習得をスキップ)
    ⼊⾨書完読。
    基本レベルの演習を
    全て解答可能

    View Slide

  303. 包丁をにぎらず本ばかり読む駆け出し料理⼈
    • プログラミングの第⼀歩は本やトレーニングで問題ない
    • 本だけを読んで「分かった気になる」かもしれないが、実際に
    コードを書かないとプログラミングは⾝につかない
    • アプリケーションを作るレベル(脱初⼼者)になるまでは本ト
    レーニングの演習のようなお題をこなすことで基礎スキルを⾝
    につけるのが⼿っ取り早い
    • 同じ演習でもいくつかの解答⽅法はある場合が多いので、いろ
    いろなテクニックを駆使して解いてみよう

    View Slide

  304. やりたいことは書き始めてから考えよう
    • プログラミングは作りたいものを作ることで学べる
    • ただし適切なレベルの作りたいものがある⼈はごく少数
    • 多くの個⼈プログラマは以下の3種類を作る
    • ウェブサービス <- おすすめ
    • デスクトップアプリ
    • 作業スクリプト
    • これらの利⽤法を学びながらなにか作りたいものを探すか、練
    習がてら⼀般的なサービス(掲⽰板)を簡易模倣したり、仕事の
    作業(エクセル操作など)をPythonで実装してみるとよいかも

    View Slide

  305. おすすめ1: Flaskによる簡易ウェブサービスの作成
    • Pythonの軽量Webフレームワーク
    • アクセスされるURLに処理を関数として結びつけることでウェ
    ブサービスを簡単に作ることができる
    • ウェブアプリは現在の開発の⼤きな割合になりつつあるので、
    簡易ウェブサービスの作成経験は損にはならない
    ページ(HTML)作成の関数1
    ページ(HTML)作成の関数2
    ページ(HTML)作成の関数3
    ページ(HTML)作成の関数4
    フレームワーク
    ウェブサーバー機能
    ブラウザ
    ページ要求
    ページを返す
    開発者ページ(HTML)作成のみを開発
    他のサーバー処理は全てFlaskが担当

    View Slide

  306. 補⾜) HTML/CSS
    • ウェブページのマークアップ⾔語
    • HTMLにウェブページの内容を書く。これをFlaskで動的に作成
    する。たとえばお店サイトの商品ページをURLごとに作成
    • CSSはHTML(ページ本体)にデザインを加える。
    • フロントエンジニアやウェブデザイナーなどの専⾨家がいる領
    域なので素⼈が有名サイトレベルのものを作ることは不可能
    • 素⼈でウェブ作成したければ「Bootstrap」などの「初級者で
    もそこそこのページ」を作れるフレームワークを学ぶとよい

    View Slide

  307. おすすめ2: Tkinterによるデスクトップアプリの作成
    • ⽬に⾒えるものを作るので「プログラム初⼼者が楽しみながら
    開発をしやすい」という学習メリットがある
    • アプリケーションを他の⼈にも利⽤してほしければ「バイナ
    リ」にしてから配布(⼿法は割愛)
    • 他にもGUI作成の外部ライブラリがあるので深⼊りするのであ
    れば、Tkinter以外の⾃分にあったライブラリを探すとよい
    GUIのカウンターアプリ アプリケーションの配布

    View Slide

  308. 補⾜) アプリからのデータベースの利⽤
    • 状態を持つアプリケーション(ユーザーや商品などがある)は必ず
    データベースを使っている
    • Pythonや他の⾔語およびフレームワークには⼤事な情報を持たせ
    ずに、データベースを介して情報を読み書きする
    • フレームワーク依存の⾼度な利⽤法を学ぶまえにローレベルの利
    ⽤法(SQLの直接呼び出し、ORマッピング)を体感しておくとよい
    Python
    DB
    (SQLite3など)
    Sqlite3モジュール
    SQLAlchemy

    View Slide

  309. おすすめ3: 業務向けの作業スクリプト作成
    • 以下の操作をPythonで実施して省⼒化。ウェブやGUI化してもOK
    • ディレクトリやファイル操作
    • ExcelやCSV
    • Word
    • PDF
    • Eメール
    • 画像
    • ウェブページのスクレープ
    • キーボードとマウス操作の⾃動化
    • 英語ですが「Automate the Boring Stuff with Python」のウェブサ
    イト(無料)がおすすめ。オライリーから4000円ぐらいの邦訳本も
    でている

    View Slide

  310. 著者が興味でプログラムを書いた例
    • 本トレーニングの8章の画像回収ツール相当のものをJavaで作
    成(1番最初に作ったアプリ)
    • ゆっくり実況が好きだったので、⾳声合成ソフトのMacアプリ
    (Objective-C)とクラウド版(Python + C⾔語)を作成して公開
    • 仕事での巨⼤なログの解析アプリケーション(C++とQt)。あく
    までも仕事ではなく趣味の⼀環で
    • 鉱物標本のラベルを作成するサイト
    • インフラ作業の⾃動化系(趣味から現在の本業へ)

    View Slide

  311. ⼊⾨者卒業に難しい知識はいらない
    • プログラミングの書籍やウェブ情報は簡単なものから難しいも
    のまで様々ある
    • あれもこれもと⼿を出さずに以下に絞って学ぶとよい
    • 薄い超初⼼者向けのプログラミング書籍を2-3冊を何度も読
    む(内容を95%理解するまで)
    • テーマを絞って簡単なアプリを作成する
    • プログラミングで分からないことは検索をする

    View Slide

  312. 初級者卒業: 美しい設計を体と頭で覚える
    • このセクションで学ぶこと
    • スキルは「困ってからの設計変更」で向上
    • 複雑さを減らすことに気を配ろう
    • クラスを徹底活⽤しよう
    • リファクタリング
    • テスト
    • デザインパターン
    • フルスタックフレームワーク: Django
    • 他のプログラミング⾔語を学んでみよう
    • 初級者卒業には⾼度な専⾨書が必要
    SECTION
    02

    View Slide

  313. スキルは「困ってからの設計変更」で向上
    • ⾼度なプログラミングスキルの基本は「巨⼤なコードを整理して、
    バグを少なく拡張しやすくする」ことに尽きる
    • ⾼度なプログラミングスキルが役⽴つ場⾯
    • 開発前の設計
    • 増築/改造を繰り返したコードの整理
    • ⼤規模な開発を効率よくおこなう
    • 初級者は深い経験が必要なことはできない(短時間では⾝につけに
    くい)ので、最初からよい設計をするための⼿法を学ぶのではなく、
    「とりあえずコードを書きまくり、増築⽅式アプリをでかくしてい
    き、継ぎ接ぎがカオスになってからコード整理」して体で覚える
    • どのように設計しなおすと「構造がシンプルになるか」を考える

    View Slide

  314. 複雑さを減らすことに気を配ろう
    • プログラム複雑になるシナリオ
    • 関数やメソッドの呼び出しが深くなっている
    • 1つのデータが⾊々な箇所で読み書きされている
    • 機能追加をその場しのぎの継ぎ接ぎで加えた
    • 複雑なコードを設計変更して綺麗にするとスキルが向上
    関数
    関数
    関数
    関数
    関数
    関数
    関数
    関数
    関数
    関数
    汚いコード例
    (深い階層)
    綺麗なコード例
    (階層を浅くした)

    View Slide

  315. クラスを徹底活⽤しよう
    • クラスには様々な機能がある
    • 処理や複数のデータをまとめられる(トレーニングで学んだ)
    • クラスにクラスをいれて複雑さをさらに集約できる
    • 継承により複数の似たクラスの実装をまとめられる
    • 多重継承でクラス内のメソッドを分離できる
    共通処理のクラス












    利⽤したいクラス
    常に継承
    必要な機能の
    クラスのみ継承
    (ハリボテ)
    呼び出し側
    多重継承の利⽤例(REST APIをPythonラップするライブラリの作成などに便利)

    View Slide

  316. リファクタリング
    • プログラム(関数やクラス、モジュールレベルなど)の挙動を変
    えずにコードの品質をあげること
    • 専⾨書籍などで学んでもよいが、初級者は⾃分で試⾏錯誤しな
    がら設計変更するのがよい(痛いめに合って、それを頑張って解
    決することが経験となる)
    • ライブラリで解決できる問題ではないか
    • 関数、クラス、モジュールの⼤きさは適切か
    • ループ処理はわかりやすいか
    • クラスの設計は正しいか
    • 中級者に近くなったら「教科書的な解答」も学習して覚える

    View Slide

  317. テスト
    • プログラムが正常に動作するかをテストで確認
    • 開発を終えてからテストをするのではなく、モジュールをテス
    トしながら開発していくことが望ましい
    • 習得するべきテスト
    • Printデバッグ
    • ユニットテスト
    • ツールを使ったテスト(サービスに⼤量の負荷を与えてみる、
    Seleniumでブラウザ操作チェックなど)

    View Slide

  318. デザインパターン
    • ⼤規模なコードを書くための設計パターン
    • クラスやモジュール間をどう接続して連携するのがよいかとい
    うベストプラクティス
    • 1つのシステムから構成される中規模以上のサービス開発で設
    計段階で導⼊するとよい
    • ⾃分で設計したりリファクタリングした経験が積み重なってい
    ないと机上の理論にすぎないので、数年のプログラミングの経
    験を積んでから学べばよい(超有名なシングルトンなど10個以
    下のパターンをピックアップして学習してもよい)

    View Slide

  319. フルスタックフレームワーク: Django⼊⾨
    • メジャーなPythonのフルスタックWebフレームワーク
    • Ruby⾔語でいうところのRailsに近い
    • Flaskと異なりウェブサービスに必要なほとんど全ての機能が
    フレームワークに搭載されているので「フルスタック」と呼ば
    れる
    • Flaskで作成した動的なウェブサイトの作り込み(DBとの連携や
    HTML⽣成)あたりをDjangoのモデル(DB)やテンプレート機能
    (Jinja)で作り直すとフルスタックのメリットがわかる

    View Slide

  320. 他のプログラミング⾔語の学習
    • おすすめはJavaScript。ウェブ開発で他に選択肢がない場合が多い
    ため
    • 次点はGo(モダンな開発によい)か、Java(まだ需要が多くてオブ
    ジェクト指向の学習によい)
    • 他にはやりたい仕事向きの⾔語(SwiftやC#、PHPなど)
    • 以下は3⾔語め以降でよいと思う
    • Pythonと利⽤⽬的が近い他のスクリプト⾔語(Ruby/Perlなど)
    • 学習難易度の⾼いC/C++や関数型の⾔語。(これらを必要とする
    仕事についていないと利⽤する機会は少ない)
    • 汎⽤的でない⾔語。Rなど

    View Slide

  321. 初級者卒業には⾼度な専⾨書が必要
    • 3000円 - 4000円あたりの書籍は⼊⾨書に⽐べると専⾨的
    • 中級者向けの書籍は⼊⾨書よりも扱う範囲が広いので「まんべん
    なく深い」のではなく「いくつかのトピックが深い」傾向がある
    • 2000円台の本とは違ってプログラミングの⾼度な専⾨書籍の半分
    以上の知識は必須ではないのですぐには役⽴てられない
    • 詰め込みではなく継続的に書籍を読み続けてスキルの⼟壌を耕し
    ておくとよい
    • コードを書き続けているうちに利⽤するべき場⾯に遭遇する場合
    がある。⼟壌が整っていると難しい状況でもよい判断ができる

    View Slide

  322. 中級者卒業: 開発はプログラミング以外にもある
    • このセクションで学ぶこと
    • 巨⼈の肩の上に⽴つ凡⼈ > プログラミングだけを知る達⼈
    • パーツごとに別々に作成するのが今のトレンド
    • パーツ間の連携⽅法
    • 軽量な実⾏基盤であるコンテナ
    • 既存ミドルウェアをアプリケーションで使う
    • サービスの監視
    • APIフレームワーク: FastAPI
    • リバースプロキシーのURL設計例
    • CI/CDによる省⼒化と安定性の確保
    • DevOps環境の構築と著者が採⽤している環境の紹介
    SECTION
    03

    View Slide

  323. 開発巨⼈の肩の上に⽴つ凡⼈ > プログラミングだけを知る達⼈
    • 開発スキルはプログラミングスキル以外も含む
    • たとえばデータベースの利⽤のように「プログラムに既存のサー
    ビスを使わせる」ことでシステム開発を効率化できる
    • 全てをコードで作ると開発も保守も⼤変になる
    Linuxの知識
    DBの知識
    コンテナの知識
    その他、多数
    プログラミングスキル
    プログラミングスキル
    開発の達⼈
    プログラミングの達⼈
    インフラの知識

    View Slide

  324. パーツごとに別々に作成するのが今のトレンド
    • モノリシックなサービス: 1つの構成要素からなるアプリ
    • マイクロサービス: 複数の構成要素からなるアプリ
    • 2010年以降はマイクロサービスが⼤幅に普及
    • ウェブサービス以外でもマイクロサービスの設計は使える。た
    とえばプライベート基盤を提供するNutanixの製品もコンポー
    ネントごとに独⽴したマイクロサービスな設計となっている
    モジュールC
    モジュールD
    (過去遺産)
    モジュールA モジュールB
    アプリケーション
    モノリシックな設計
    サービスA
    (新規でPython製)
    サービスB
    (MongoDBなど)
    サービスC
    (Go製の過去遺産)
    サービスD
    (新規でJava製)
    APIで連携
    マイクロサービスアーキテクチャ
    達⼈プログラマ(上級)
    でないと設計できない
    万能プログラマ(上級)
    でないと設計できない

    View Slide

  325. パーツ間の連携⽅法
    • リバースプロキシー: URLによるアクセス先の振り分け。
    HTTPSオフロードやキャッシュ機能などもある
    • メッセージング: サービス間のやりとりのための仕組み(割愛)
    Web
    Server
    API
    Server
    Image
    Server
    /api/...へのアクセス
    /images/...へのアクセス
    /...へのアクセス
    リバースプロキシー
    内部IPで通信
    外部IP(1つ)
    アプリケーション全体
    サービスA
    サービスB
    サービスC

    View Slide

  326. 軽量な実⾏基盤であるコンテナ
    • コンテナはサービスを独⽴させるのに便利なツール
    • 軽量ですぐに起動できて、どこでも動かせる擬似OS環境
    • 複数のコンテナを1つのホスト上で動かしたり、多数のコンテ
    ナを複数ホストで構成されるクラスタ上で動かせる
    本番ホスト
    Docker
    コン
    テナ
    コン
    テナ
    コン
    テナ
    コン
    テナ
    コン
    テナ
    コン
    テナ
    コン
    テナ
    コン
    テナ
    ホスト1
    Docker
    ホスト2
    Docker
    クラスタ(Kubernetesなど)
    コン
    テナ
    コン
    テナ
    コン
    テナ
    コン
    テナ
    コン
    テナ
    コン
    テナ
    コン
    テナ
    コン
    テナ
    コン
    テナ
    コン
    テナ
    コン
    テナ
    コン
    テナ
    コン
    テナ
    コン
    テナ
    コン
    テナ
    コン
    テナ
    開発ホスト
    Docker
    コン
    テナ
    コン
    テナ
    コン
    テナ
    コン
    テナ
    コン
    テナ
    コン
    テナ
    コン
    テナ
    コン
    テナ
    コン
    テナ
    他環境(別IPなど)に
    すぐに移せる
    マイクロサービスの各サービスを
    コンテナとして動かすことが多い

    View Slide

  327. 既存ミドルウェアをアプリケーションで使う
    • 以下は筆者がマイクロサービス開発よく使うサービス。⾃作す
    るのではなくサービスを使う前提でプログラムを書くと簡単
    • NGINX
    • リバースプロキシー
    • ウェブサーバー(静的なファイルの配布)
    • MongoDB: ドキュメント指向データベース。プログラムが使う
    データ構造(辞書型。JSON)をそのまま格納したり検索可能
    • Redis: KVSと呼ばれる⾼速なキャッシュ
    • オブジェクトストレージ: ファイルやイメージをURL形式で保
    存する。著者はローカルではMinioを利⽤

    View Slide

  328. サービスの監視
    • 複雑に構成されるサービス群は監視が必要。以下は著者の構成
    • Loki: システムログの集約(次世代のシスログサーバー)
    • Prometheus: メトリックの集約(性能や稼働状況などの指標)
    • AlertManager: しきい値を超えた際に管理者にメール通知
    • Grafana: 集約したログやメトリックを表⽰、検索
    ホスト
    Docker
    (Loki Logging Driver)
    コン
    テナ
    コン
    テナ
    コン
    テナ
    コン
    テナ
    コン
    テナ
    コン
    テナ
    コン
    テナ
    コン
    テナ
    全コンテナの
    ログ
    全コンテナの
    メトリック
    ウェブで表⽰

    View Slide

  329. ミドルウェアを利⽤する際のポイント
    • 完璧なものを⽬指すのではなく規模にあったコスパで選ぶ
    • 「構築/運⽤コストと覚えること」は少ないほうがいい
    • たとえば著者はログ監視にElasticsearch/Kibana/Fluentdという
    構成ではなく、Grafanaを使っているのでLokiを採⽤している
    • 状態をホストやコンテナではなく共有されるミドルウェアに任せる
    • たとえばローカルキャッシュではなくRedisを使う
    • たとえば画像やファイルの管理はローカルではなくオブジェクト
    ストレージを利⽤する
    • これを守らないとパーツへの依存性が発⽣して、構成変更(ノード
    数を増やすなど)の難易度が跳ね上がる

    View Slide

  330. マイクロサービスのウェブアプリの構成例
    Node (SPA担当)
    ウェブサーバー
    (静的ファイル配信)
    Node (JS等のビルド)
    APIサーバー 1
    APIサーバー N
    Minio(画像)
    JS CSS
    画像
    gulp
    アプリサーバー
    (HTML⽣成)
    内部API呼び出し
    画像の
    取得/保存
    画像取得
    外部API呼び出し
    SPAのページへの
    アクセス
    静的ファイル
    取得
    ページ
    アクセス
    Redis
    MongoDB
    キャッシュ
    セッション管理
    データ管理
    Grafana
    Loki
    Prometheus
    Exporters
    管理/監視系
    AlertManager
    Browser
    ページ
    アクセス
    セッション管理
    (ログイン状態で表⽰切り替え)
    JavaScript
    API呼び出し
    リバースプロキシ
    + ⼀部のキャッシュ
    信頼できないゾーン 信頼できるゾーン
    コンテンツビルダー
    (MarkDown -> JSON)
    ページデータ
    作成
    ...
    ⾃作ツール群

    View Slide

  331. APIフレームワーク: FastAPI⼊⾨
    • フルスタックフレームワークはマイクロサービス向きでない
    • Flaskのような軽量フレームワークを主体とした⼩型のAPIサー
    バー群を⽤途ごとに作成する
    • 著者はPython製のAPI向けで⾼速なFastAPIを利⽤している
    Docker (Logging-Driver)
    ミドルウェア
    • 例外処理
    • Prometheus Exporter
    APIの実装
    他のAPIサーバー
    Appサーバーのみ他を参照
    Redis
    MongoDB
    キャッシュ
    セッション管理
    データ管理
    バルクアクセス
    Prometheus
    Loki
    APIアクセス

    View Slide

  332. リバースプロキシーのURL設計例
    • リバースプロキシーでプレフィックス(前⽅)基準でURLごとに処理変更
    • ウェブ(APPサーバー)の懸念事項
    • キャッシュ対象(全ユーザー共通)と⾮対象(ユーザーごと)ページがある
    • 同⼀ドメインで多⾔語対応させることが現在は多い(URLで⾔語区別)
    • APIの懸念事項
    • 複数のAPIサーバーが存在している。APIのバージョン管理も必要
    • パブリックAPI(外から)とプライベートAPI(中のみ)がある
    • URLの設計例
    • 静的ファイル: /static/...
    • ウェブ: /<キャッシュの有無>/<⾔語>/...
    • API: /api///<バージョン>/...
    • オブジェクトストレージ: /images/...

    View Slide

  333. CI/CDによる省⼒化と安定性の確保
    • リポジトリにコードをPushしたら複雑なマイクロサービスアプ
    リを全⾃動でビルド。⼈間よりスクリプトのほうが信頼できる
    • ビルドしたコード(イメージ)を起動して全⾃動でテストを実施
    • テストにパスしたらステージング環境にのせて、管理者が最終
    チェックしてから本番環境に切り替える
    著者が採⽤しているDockerアプリの
    CI/CDの流れ。
    Kubernetes利⽤時はDocker-Composeでは
    なく実際にK8sを利⽤する。
    宣伝!!
    詳しくは私のDocker本にあります

    View Slide

  334. DevOps環境の構築
    • DevOpsはバズワード
    • DevOpsの著者なりの解釈は「CI/CDを中⼼として、(クラウド
    より上の世界での)インフラを維持しつつサービスを開発/更新
    公開し続ける技術」
    • ⼩規模なDevOps環境はある程度の知識と試⾏錯誤は必要だが、
    個⼈レベルで構築可能
    • 上級者向けの個々の技術を1つ1つ深堀りする前に、とりあえず
    全体像を理解するために浅知恵でよいので作って動かすべき
    • 開発と運⽤にDevOpsを採⽤するのであれば、チームの半分以
    上は全体像を掴んでいること
    • 少数精鋭チームから導⼊して横展開することを推奨

    View Slide

  335. 著者が採⽤しているDocker中⼼のDevOps環境
    Dockerレベルの運⽤
    Compose
    (開発サーバー)
    Dockerfile
    DockerHub
    (Pull)
    Compose
    (本番環境)
    Compose
    App
    Infra
    Ansible
    ホストレベルの運⽤
    Python
    GitHub
    (Code Push)
    App
    Infra
    App
    Compose
    (⾃分のPC)
    GitHub
    (Code Pull)
    Dockerfile
    Jenkins
    (ビルドからデプロイまで)
    DockerHub
    (Push)
    Jenkinsのトリガー
    GitHub
    (ドキュメント等)
    メトリックとログ
    規模が⼤きくなると
    ビルドからデプロイは
    Composeではなく
    Kubernetesに切り替え

    View Slide

  336. 駆け出し編: インフラエンジニアという道
    • このセクションで学ぶこと
    • ウェブ業界はレッドオーシャン
    • ITインフラ業界は敷居が⾼いが安定している
    • 代表的なインフラエンジニアの仕事
    • 本当の基盤(電気、空調、ラック)
    • ネットワーク系
    • サーバーとストレージの世界
    • パブリッククラウドとプライベートクラウド
    • 構成管理ツール
    • インフラの⾃動化
    • 専⾨性や資格について
    SECTION
    04

    View Slide

  337. ウェブ業界はレッドオーシャン
    • 低スキルから中堅まで⼈材が豊富
    • ⾒た⽬にわかりやすい仕事なので新⼈が多い
    • ⼤量のプログラミングスクール卒業⽣
    • ⼀部の優秀なエンジニアや好業績の会社を除けば、求められる
    技量のわりに待遇がITインフラ業界より低いことが多い
    • 技術のサイクルが速いのでずっと(⼤量に)勉強し続けないとい
    けない

    View Slide

  338. ITインフラ業界は敷居が⾼いが安定している
    • 専⾨知識が要求されるため学習が必要
    • ウェブ業界に⽐べると⼈員供給が少ないので需要が多め(?)
    • ウェブ業界に⽐べるとコア技術の変遷が⼩さい(ウェブ開発スタ
    イルは⼤きく変わっても、ネットワークの仕組みやLinuxの根
    幹は簡単には変わらない)
    • 以後で著者が経験したインフラエンジニアとしての仕事内容を
    列挙していく
    • 仕事が⾯⽩そうと感じたなら、ウェブ屋よりもインフラ屋を駆
    け出しエンジニアは⽬指したほうが仕事と給料は安定する可能
    性が⾼いかも

    View Slide

  339. サーバーラック利⽤法の設計
    • コアとなるIT機器はサーバーラックに搭載するのが⼀般的
    • インフラエンジニア以外がこれらを⾒かけることは珍しい
    • サーバーラックの利⽤法の設計に必要なステップ
    1. ネットワークとサーバーの論理設計 -> 物理設計
    2. 必要な電⼒と発⽣する熱量の設計
    3. 物理⼯事(ラック設置、電⼒供給、ACの設置)
    • 配線が多い場合はネットワーク機器をToR(Top of Rack)ではな
    くMoR(Middle of Rack)にするとケーブルを分散させやすい。
    必ずケーブルガイドを使って配線を左右に逃がすこと
    • スイッチのポート(ケーブルがささる側)はラックサーバーにさ
    すものは背⾯側の機種を選ぶ。それ以外は前⾯側にする

    View Slide

  340. サーバーラック利⽤法の設計例
    ...
    1G L2 Switch
    1G L2 Switch
    2U/4Node Servers
    2U/4Node Servers
    ...
    2U/4Node Servers
    2U/4Node Servers
    ...
    Core L3 Switch
    Core L3 Switch
    Data Stack
    Data Stack
    ...
    Voice Stack (PoE)
    Voice Stack (PoE)
    ...
    ...
    Infra Servers
    10G/40G L3 Switch
    10G/40G L3 Switch
    1G L2 Switch
    1G L2 Switch
    2U/4Node Servers
    2U/4Node Servers
    ...
    2U/4Node Servers
    2U/4Node Servers
    ...
    Firewall
    Firewall
    ONU ONU
    Career1 Career2
    Internet
    Wifi Stack (PoE)
    Wifi Stack (PoE)
    Wifi
    Controller
    Wifi
    Controller
    PCs on Desk
    IP Phones on Desk
    Meeting Systems
    APs
    終端ラック(1,2): ラック間の接続その他
    ラック(1-N): ワークロード⽤
    10G/40G L3 Switch
    10G/40G L3 Switch
    バックボーン接続(冗⻑化)
    ラック内接続(冗⻑化)
    ラック内接続(冗⻑化)
    ラック内接続(冗⻑化)
    床下配線
    冗⻑化
    オフィスエリア
    天井配線

    View Slide

  341. 電⼒と空調の設計
    • IT基盤を動かすより低いレイヤーの基盤
    • 電⼒: サーバーは200kVAでのPSU冗⻑化が⼀般的(kVA≒KW)
    • ラックあたりの電⼒量: ⼀般的には4kVA - 20kVA程度
    • 重要な環境は電気系統と空調も冗⻑化すること
    • コールドアイル(冷たい空気)の通路をラック前⾯に設置し、
    ホットアイル(排熱による暖かい空気)をラック背⾯に設置
    • 排出熱量に猶予をもたせること。空調が冷やせる限度を越える
    と冷⾵が送れずに急激にオーバーヒートをおこす。夏は室外機
    (排熱)も⾼温になるので冷却性能が落ちる点に注意
    • ITインフラとは異なる領域なので、その専⾨家(電気、空調等)
    と相談しながら要件にあった設計をする(⼿伝う)必要がある

    View Slide

  342. 電⼒と空調の設計例
    Front
    Front
    コールド
    アイル
    室内機
    室外機
    室外機 室内機
    ホット
    アイル
    発⽣する熱量と電気使⽤量、価格
    あたりから適切な機器を選定する。
    弱いよりは強いほうがだいぶマシ。
    稼働後の増強は難しい(⾦と時間がかかる)
    排熱環境に注意
    排熱できない = 冷やせない
    200V
    100V
    200V
    100V
    200V
    100V
    200V
    100V
    200Vの電⼒使⽤量の⾒積もりが必要。
    100Vを⼤量に使⽤する場合は⼤容量の
    配電が可能な200Vを使うことを検討。
    ⽇本では100Vもないと不便
    100V配電盤 200V配電盤
    ...
    PDU(電源タップ)は
    背⾯側の左右が基本

    View Slide

  343. L2/L3ネットワークの設計
    • L2ネットワーク: 同じネットワーク内の通信
    • L3ネットワーク: ネットワーク間をまたぐ通信
    • L3スイッチ: ネットワークの中⼼なる機器。L2/L3の両対応
    • 設計のコツ: 利⽤⽤途から正しいサイジングをして、L2の物理
    範囲を狭めて、アドレス集約を徹底してルーティングを簡単に
    する。責任分界点には社内であってもFirewallを設置する
    • 重要箇所は全て冗⻑化することが必須
    • ネットワークを使う側のサーバーエンジニアのレベルは⾊々
    • ネットワークに詳しくない⼈が使う⼤きなVLAN(Native)
    • 詳しい⼈が複雑なことをできる複数の⼩さなVLAN
    • パブリックIPやDMZの設定は素⼈にはやらせないかガイド

    View Slide

  344. L2/L3ネットワークの設計例
    Goto
    Corp, External
    Office
    10.4.0.0/16
    Office Core
    Office Infra
    Office Data
    1
    Office Voice
    1
    Office Wifi 1
    External
    Firewall
    VRF Routing +
    Internal Firewall
    Goto
    Corp, External
    Site B
    Small Sites
    Big VLAN
    Small
    VLANs
    Site A
    External
    Firewall
    Lab1
    10.5.0.0/16
    Lab2
    10.6.0.0/16
    10.4.0.0/23
    10.4.100.0/24
    10.4.101.0/24
    10.4.2.0/23
    10.4.4.0/22
    10.4.8.0/22
    10.4.12.0/22
    10.5.0.0/17
    10.5.128.0/20
    ⽀社A 10.4.0.0/14 本社: 10.0.0.0/8
    (全⽀社は内部にある)
    ...
    ⽀社B ⽀社C
    ...
    サイト間VPN(冗⻑化)
    サイト間VPN(冗⻑化)
    サイト間VPN(冗⻑化)
    必要に応じて
    拠点間も直接
    接続をする
    極論すると全てスタティックルートの設定で
    まかなえるぐらい経路を集約しまくること。
    最初に正しく設計してないと集約できなくなる
    Internet
    10.0.0.0/8
    10.4.0.0/14
    0.0.0.0/0
    Corp
    0.0.0.0/0
    10.6.0.0/16
    全ての通信を
    通す必要はない

    View Slide

  345. 名前解決の設計
    • ドメイン名をIPアドレスに変換する仕組み
    • アプリケーションを様々な環境で動かすための必須条件なので、
    クラウドが⼀般化した今では昔よりも重きがおかれる
    • 完全にランダム割り振られるDHCPや固定IPの使⽤ではなく、
    「IPAM(IP Address Management)」で賢くDHCPを使うこと
    • クラウドにはIPAMが搭載されることが多い
    • 存在しない場合には作る(Linux or Windows)
    • アプリケーションを構成するノード間は名前解決で連携できる
    ように実装しておくこと。接続先を固定IPではなく解決可能な
    ドメイン名にしておく。⾃分⾃⾝のIPもDHCPでIPAMから得る

    View Slide

  346. 名前解決の設計例
    プライベート
    クラウド
    パブリック
    クラウド
    コンテナ基盤
    VLAN
    172.30.0.0/16
    VPC
    172.31.0.0/16
    コンテナネットワーク
    172.32.0.0/16
    Backend
    VM
    Front
    VM
    Reverse
    Proxy
    etc
    Backend
    Instance
    Front
    Instance
    CDN
    etc
    Backend
    Container
    Front
    Container
    Load
    Balance
    r
    etc
    IPAM + DHCP(管理コンソール) IPAM + DHCP(管理コンソール) YAMLでの定義
    ネットワークアドレスに依存せずサービス
    構成ノード間で会話できる必要がある。
    IPではなく名前で相⼿を指定する。
    フロントも直接外に出さないほうがよい
    Global IP
    DNS
    公開⽤パブリックIPとサービスのドメイン名の結びつけ

    View Slide

  347. Wifiの設計
    • 物理設計
    • L2ネットワークへの接続と給電(PoEが多い)
    • アクセスポイントがカバーできる範囲の調査
    • 設置ポイントと⼈⼯密度、衝突しない周波数の調整など
    • 認証システム
    • 物理的に離れた多数のAPをどう⼀元管理するか
    • 数⼗台以上のAPは個別ではなくコントローラーに設定を集
    約するのが基本

    View Slide

  348. セキュリティの設計
    • Firewall
    • 社外から社内だけでなく、社内から社外への通信も対象
    • 社内の異なるグループ間もFirewallを通すべき
    • VPN
    • サイト間接続
    • PCからの接続
    • ActiveDirectory(AD)
    • セキュリティ系の機能はADに強く依存しているものが多い。
    また、ADを安定稼働させるための専⾨知識が必要
    • FirewallやActiveDirectoryも壊れることがあるので、冗⻑化と
    壊れた際にきちんとシステムが動き続けるかの検証が必須

    View Slide

  349. クラウド間接続の設計
    • 接続⽅式
    • VPN
    • 専⽤線(ダイレクトコネクト): ⾼額
    • アドレスレンジを「/16」程度で分離しておかないとルーティ
    ングができなくなる(パブリッククラウドには従来のL2/L3の
    ルールが適⽤されないことが多いので注意)
    • アプリのレイヤーを「グループレベルでクラウド間で動く」こ
    とを前提に構築しておく必要がある。クラウド間やリージョン
    間は遅延が⼤きいので「アプリはクラウドでDBはオンプレ」
    などの構成はNG

    View Slide

  350. クラウド間接続の設計例
    172.31.0.0/16
    Public Cloud
    (AWS)
    172.30.0.0/16
    Public Cloud
    (Azure)
    172.31.1.0/24
    172.31.2.0/24
    172.31.3.0/24
    VM VM VM VM VM
    172.30.1.0/24
    172.30.2.0/24
    172.30.3.0/24
    VM VM VM VM VM
    Firewall
    Appliance 1
    Firewall
    Appliance 2
    L3 Switch
    (Gateway)
    172.16.0.0/16
    Private Cloud
    (Nutanix)
    172.16.1.0/24
    172.16.2.0/24
    172.16.3.0/24
    VM VM VM VM VM VPN
    VPN
    0.0.0.0/0 via L3 Switch
    172.31.0.0/16 via L3 FW1
    172.30.0.0/16 via L3 FW2
    172.16.0.0/16 via L3 Switch
    172.31.0.0/16 via AWS
    172.16.0.0/16 via FW1
    172.30.0.0/16 via Azure
    172.16.0.0/16 via FW2
    VLAN X VLAN Y
    ⽮印の通信経路の設定はスタティック
    ルートか⾃動学習(BGPとOSPFなど)で与える

    View Slide

  351. 物理サーバーの設計
    • 今は「仮想化」を前提に考える。ベアメタルは特殊な状況のみ
    • 基盤導⼊後に拡張することを前提に考えておく(ネットワークのア
    ドレス空間の⼤きさ、物理スペース、電⼒、エンジニアの物理と
    設定作業のコストなど)
    • ミドルレンジより性能が上がっても落ちても「処理能⼒あたりの
    購⼊価格」が⾼く傾向、台数が増えると維持コストが増える
    • 物理より上の価格(ライセンス代など)が⾼ければ、⾼いサーバーで
    コストを圧縮したほうがよい。普通はコスパでミドルレンジを選
    び、予算がなければローエンドを選ぶ。ミッションクリティカル
    環境はハイエンド
    • ワークロード(負荷)に応じたサイジング(台数や構成決定)をする

    View Slide

  352. 物理サーバーの設計例
    ハイパー
    バイザー
    ハイパー
    バイザー
    仮想化基盤のクラスタ
    物理サーバー 物理サーバー
    SAN
    Switch
    San
    Switch
    Network
    Switch
    Network
    Switch
    上流
    ネットワーク
    ストレージ ストレージ
    VM VM VM VM VM VM VM
    VM VM VM VM VM VM VM
    ...
    上流
    ネットワーク
    物理サーバー 物理サーバー
    Network
    Switch
    Network
    Switch
    プライベートクラウド
    VM VM VM
    VM VM VM マネージドDB
    その他機能
    レガシーな「3Tier」と呼ばれる構成
    構築と拡張が難しい
    現在主流になりつつあるプライベートクラウド⽅式
    全般的に3Tierよりも簡単(個⼈で作る⼈もいるぐらい)
    ...
    コン
    テナ
    コン
    テナ
    コン
    テナ
    コン
    テナ

    View Slide

  353. 障害と保守
    • 機械は壊れるもの
    • ソフトウェアにはバグがある
    • エンジニアは知らないことが多いし間違えることも多い
    • アプリでバグがおきるようにインフラにも障害が発⽣する
    • 障害に対応するように以下が必要
    • ハードウェアの冗⻑化(2つ構成で組み、1つ壊れても動き続
    ける)
    • 冗⻑化と故障を想定した設計のソフトウェア
    • 障害発⽣時の対処法(知識かマニュアル)
    • 保守契約(ハード交換や障害復旧の⼿伝い)
    • ハードやソフトに詳しくなりたいならきちんとした保守(技術サ
    ポート)の仕事から始めるとよいかも。著者も経験者

    View Slide

  354. ストレージの設計
    • ⼤前提として以下の3種類を区別する
    • サーバー内のSSD。⾼速だが死ぬと終わるし融通が利かない
    • NAS(共有ファイルサーバー, NFS/SMB)
    • 外部ブロックストレージ(SCSI, iSCSI)
    • サーバー冗⻑化には外部ストレージが必要なことが多い
    • SCSI(SAN)は⼤企業向けだが、iSCSIは⼩規模向け
    • 環境の引っ越しをしにくくなる第⼀要因はストレージ(DB含む)
    なので最初から移⾏プランを考えておくのがよい
    • ストレージとSANの障害はインフラ障害で最もダメージが⼤き
    いのでデリケートな箇所。基盤のパフォーマンスのボトルネッ
    クにもなりがち。バックアップ必須
    • ストレージとSANのエンジニアは⽐較的レアキャラ

    View Slide

  355. データベースの設計
    • 2種類のDBエンジニア
    • アプリより: アプリが使いやすいテーブルの設計
    • インフラより: 複雑なクエリーや、冗⻑化やバックアップ
    • 純粋な「データベースだけをやるエンジニア」は少ないのでア
    プリであれば開発(アプリ側がDBをどう使うか)を先に学び、イ
    ンフラであればDBが動くサーバーレベルを先に習得するのが
    個⼈的推奨
    • SQL⾃体に詳しくなる(知っていてあたりまえ)というより、運
    ⽤(クローンやバックアップ、スケールアップ)周りの知識が特
    に求められる
    • DBの障害(システム全停⽌)でもデータは絶対になくさないこと

    View Slide

  356. バックアップの設計
    • 冗⻑化(Raidなど)はバックアップではない
    • 仮想化のスナップショットもバックアップではない
    • 集約箇所やシステムごとなくなる可能性を考慮しておくこと
    • バックアップのレベル
    • ファイルレベル(以下のどれかの付属機能なことが多い)
    • OSレベル
    • 仮想環境レベル
    • ストレージレベル
    • バックアップ取得時間とバックアップからの復旧時間もだいじ
    な指標なので、検証環境で実測しておくこと(バックアップはあ
    るけど戻しに2⽇かかります。などということも。。。)

    View Slide

  357. パブリッククラウドの設計
    • 「とりあえずOSを使いたい」という状況でインフラの構築と運
    ⽤が不要で簡単に使えるというメリットがある
    • 動かすサービスをクラウドに適した設計に変更し、インスタン
    スを使い捨て(スケール含む)にできることが望ましい
    • マネージドサービスを使うことで「DBなどの⼿がかかるマシ
    ンのおもり」をへらすことができる
    • インターネットに近いのでウェブサービスに強い
    • 「従来の業務⽤VMを24時間稼働させる」⽬的でパブリックク
    ラウドを使うと割⾼になることが多いので注意が必要
    • 注意:「特定パブリッククラウドのシステムにだけ強い」という
    エンジニアは⻑期的には不安定だと思われる。クラウドにも役
    ⽴つベーシックなLinuxと開発スキルにも投資すべきかも

    View Slide

  358. パブリッククラウドの設計例
    パブリッククラウド基盤
    インスタンス
    (ウェブサーバー)
    マネージドDB
    インスタンス
    (アプリサーバー)
    バックアップ
    インスタンス
    (アプリサーバー)
    インスタンス
    (ウェブサーバー)
    CDN(Cache) +
    HTTPS Offload
    ドメイン名
    RDS
    S3
    EC2
    Cloud Front
    Route53
    インターネット
    ユーザー
    名前解決
    アクセス
    サービス名にはAWSを使ったが、基本機能程度の利⽤であれば
    主要クラウドであれば似たサービスを持っている。
    これ以外にもサーバーレスや各クラウド独特の機能は多い。
    初⼼者は汎⽤(どのクラウドでも使える)機能から学ぼう
    プライベートネットワーク
    広いエリアからの⼤量のアクセスに
    強いが、特定の拠点(会社など)からの
    ⼤量のアクセスには弱い。
    ⾃社ファイルサーバーなどはクラウド
    ではなく拠点内に置くのが⼀般的。

    View Slide

  359. プライベートクラウドの設計
    • パブリッククラウド相当のものを社内に構築する
    • レガシーな3Tier構成やOpenStack(難しいので専任エンジニア
    が多数必要)より、NutanixのHCIなどの構築と運⽤が簡単なも
    のがよい
    • 展開する台数が多い場合は仮想マシン(インスタンス)単価で考
    えると、パブリッククラウドより安価な傾向(1/2 - 2/3程度)
    • 初期投資が必要なので⼩規模な場合はパブリッククラウドより
    も⾼額になる傾向
    • 24時間稼働のエンタープライズアプリや、⾼トラフィックが必
    要なVDI、⾃由な操作が求められる開発基盤などに適している
    • 注意: プライベートクラウドはパブリッククラウドに⽐べると
    設計と運⽤がきちんとできるインフラエンジニアが必要

    View Slide

  360. プライベートクラウドの設計例
    物理基盤(電気、ネットワーク)
    VM VM
    VM VM
    VM VM
    VM VM
    VM VM
    VM VM
    VM VM
    VM VM
    VDIサービス
    (管理された⼤量のユーザーマシン)
    ⼤量の社内通信
    (40G以上の⾼速なLAN)
    ⾃社設備(オフィス、データセンター)
    VM
    VM VM
    エンタープライズ
    アプリケーション
    (会社の重要システム)
    DB
    バック
    アップ
    プライベートクラウド基盤
    ⼤量のユーザー(社員)
    社内通信
    秘匿データ
    VM VM VM VM
    インターネット
    Firewall
    セキュリティ管理
    Firewall
    セキュリティ管理
    VPN
    社外の
    ユーザー
    (社員)

    View Slide

  361. 構成管理ツール
    • 主にサーバーレベルでのインフラ構築/変更作業は「構成管理
    ツール(Ansibleなど)」を使うことで省⼒化できる
    • 定義した構成にサーバーを⾃動設定(初期構築/変更)してくれる
    サーバーA
    サーバーB
    サーバーC
    構成ファイル
    (Yamlで定義)
    Ansibleを実⾏ Ansibleが⾃動設定
    必ず構成管理ツールで
    全ての設定をしないと
    いけないわけではない
    著者の利⽤例
    • 構成管理ツール: Dockerホスト
    やK8s環境の構築(⼟台)
    • コンテナ: アプリケーションの
    構築

    View Slide

  362. インフラの⾃動化(1)
    • ITインフラの仕事には定型業務が多い
    • 新規ネットワークを作成した際の機器の設定変更
    • 仮想マシンを作成する際の設定作業
    • マシンやログの監視とアラートの作成
    • 決まりきったことを毎回⼈間がやるのではなくプログラムに実
    ⾏させることで労⼒削減ができる
    • 定形作業(⼿続きの流れが明確)以外は⾃動化できない
    • システム開発には「開発とインフラの両⽅の知識」が必要
    ⼈海戦術の廃⽌
    プログラム ITインフラ
    操作省⼒化
    ⾃動実⾏(定期/イベント駆動)

    View Slide

  363. インフラの⾃動化(2)
    • 管理者が増えると作業が遅くなる。マシン展開の例
    1. ネットワークエンジニアが場所とアドレスを決める
    2. セキュリティエンジニアがポリシーを設定
    3. サーバーエンジニアがインスタンスを作成
    4. アプリエンジニアが環境をもらえる
    5. 監視員がリソース利⽤状況をチェックして使いすぎを警戒
    • ⾃動化された例。インスタンス構成のプラン化と⾃動作成
    1. アプリエンジニアが必要なインスタンスの種類を選ぶ
    2. システムが機械的にインスタンスを作成
    3. アプリエンジニアが環境をもらえる
    4. システムがクオーターを超えた利⽤やアイドルを検知した
    らユーザーと管理者に通達

    View Slide

  364. インフラの⾃動化の構築例
    VM VM VM VM
    基盤構築アプライアンス
    クラウド基盤
    (Nutanix)
    Foundation
    VMs
    基盤のイメージング
    物理ネットワーク設定
    基盤の初期設定
    (論理ネットワーク等)
    仮想マシン管理
    (クラウドレベル)
    仮想マシン設定
    (OSレベル。Ansible)
    Nginx(Reverse Proxy)
    + Node(SPA)
    DB (基盤情報)
    物理電源操作
    (Power-on/off)
    ベアメタルサーバーへの
    クラウド基盤インストール
    REST API
    IPMI, SSH
    SSH, Ansible
    REST API
    ⾃動化の利⽤者
    L3物理 Switch
    物理ネットワークの結線
    マイクロサービス設計の
    ブラウザアプリ
    SSH, API
    SSHにはPythonのParamikoを利⽤
    するのがおすすめ。
    ローカルコマンドと同じ感覚で
    リモートでのコマンド発⾏が可能
    ブラウザGUI
    仮想マシンレベル
    の⾃動化
    基盤レベル
    の⾃動化
    ネットワークレベル
    の⾃動化
    Docker
    (VM設定後)

    View Slide

  365. インフラのおかね
    • 買う価格: 物理機器やライセンスなどのコスト。性能と安定性及び
    価格を考慮して構成を決める
    • 維持する価格: 買った後に維持するコスト。⼈件費や保守費。複雑
    なシステムだと⾼くなる
    • 「常に⾼機能/⾼性能であればいいわけではない」ことに注意。た
    とえば画像編集の素⼈は⾼いお⾦を払ってPhotoshopを買うよりも
    安いiPhoneアプリのほうがうまく使えるのと同じ。必要になって
    からPhotoshopを買えばいい。必要な機能を⾒極めて「可能な限り
    シンプルなものを選ぶ」ことを⼼がける
    • オープンソース vs ベンダー製品: オープンソースは素晴らしいが、
    それを採⽤することによる「構築コスト、運⽤コストの増加、サ
    ポートを得ることが難しい」点を懸念すること。全てのオープン
    ソースが著名なオープンソース相当のレベルと思わないこと

    View Slide

  366. 開発やインフラの専⾨性を変えることについて
    • キャリア的に袋⼩路に陥ったと思ったら「今の⾃分が得意なこと」
    から「半歩だけ外(完全に別領域ではない)」に出てみる
    • 著者の場合はデータセンターというカテゴリで「ネットワークエン
    ジニア(4年) -> サーバー仮想化エンジニア(4年)」とキャリアチェン
    ジし、クラウドという観点で「インフラエンジニア(合計8年) ->
    DevOpsエンジニア(現在1年め)」とキャリアチェンジしている
    • 正しいタイミングで正しい場所に移れるように⾃分が関わるIT技術
    全般についてはエキスパートレベルではなくとも「素⼈ではない」
    状態にしておくのが⼤事
    • 指標として業界の最⾼峰と呼ばれる⼈達と会話して「なんか違う
    な」「⾃分のほうができる(たいていは勘違い)」と感じたら少し別
    の領域へ移ることも検討する

    View Slide

  367. IT系の資格について
    • IT資格は特定領域を包括的に勉強するには役⽴つ(投資的価値)
    • 資格を取るだけでは本当のエキスパートにはなれない。たとえば
    著者が社会⼈4年⽬のときに「Cisco CCIE」「RedHat RHCE」
    「VMWare VCAP」「Oracle Java Gold」と広いエリアの⾼ランク
    の資格を持っていた。知識はあったが技術⼒評価では社内の最下
    位職位の下位20%程度。知識と技術⼒は別ものと割り切ること
    • 戦略的に適切なタイミングで転職やポジションの変更をおこなう
    ことで机上の知識を現場スキルに落とし込める
    • 英語ができると国内でもキャリアの選択肢が増えて、ライバルが
    ⼤幅に減るので、個⼈的には既にプロ以上のレベルの⼈はIT系より
    も英語の勉強のコスパのほうがはよいかもしれないと思う

    View Slide

  368. 歴史編: 開発とインフラの技術変遷
    • このセクションで学ぶこと
    • おおまかなインフラの歴史
    • おおまかな開発の歴史
    • ペット vs 家畜
    • クラウドの抽象化
    • トレンドを読むことで将来に備える
    • 終わりに
    SECTION
    05

    View Slide

  369. おおまかなインフラ基盤の歴史
    • - 2005ベアメタル
    • 全OSを直接ハードにインストール
    • 2000 - : サーバー仮想化(3Tier)
    • ハード上のハイパーバイザーに複数のOSをインストール
    • 2010年までは主流だったが構築と維持コストが低いパブリック/プラ
    イベートクラウドに置き換えられることが現在は多い
    • 2010 - : パブリッククラウド
    • 開放されているコンピュート資源をお⾦を払って借りる
    • ⾃分で構築しないのでメンテナンスコストが下がる
    • 2015 - : プライベートクラウド
    • 構築と維持が難しいサーバー仮想化を簡単に実現できる
    • パブリッククラウド相当のものを⾃組織のために構築する
    • 2020 - : ハイブリットクラウド
    • 複数のパブリッククラウドとプライベートクラウドのミックス構成

    View Slide

  370. おおまかなインフラ基盤の歴史(図)
    HW HW HW
    OS OS OS HW HW HW
    OS
    サーバー仮想化
    ストレージ
    OS OS OS
    OS OS OS OS
    HW HW HW
    OS OS
    OS OS Managed
    Services
    SAN
    HW HW HW
    OS OS
    OS OS Managed
    Services
    ベアメタル
    2000 ~
    2010 ~
    2015 ~
    2020 ~
    サーバー仮想化 クラウド
    2020 ~
    パブリック
    プライベート
    ハイブリット
    OS OS OS OS
    HW HW HW
    OS OS OS
    ハイブリット
    2020 ~
    ハイブリット

    View Slide

  371. おおまかな開発⼿法の歴史
    • - 2000: 開発の対象はデスクトップアプリ中⼼
    • Javaによるエンタープライズ向けサービスの開発など
    • 2000 - 2010: サーバーサイドレンダリングのウェブサービス開発
    • Windows95/98あたりからPCとインターネットが⼀般に普及
    • ⼀般ユーザー向けのサービスがブラウザ経由で提供されはじめる
    • 2005 - : クライアントサイドレンダリングのウェブサービス開発
    • ページ遷移を伴わずにページ内容を書き換えるブラウザアプリ
    • Google Mapなどが広く普及し始める。多くはサーバーサイドレンダリ
    ングとの併⽤
    • 2010 : ⾼速な開発/更新とスケールするウェブサービスの開発
    • インターネット上のユーザー数が膨⼤な数となる
    • ユーザーを集めるために⾼速にサービスを開発/公開を繰り返して、⼤
    量のトラフィックを捌ける設計が採⽤されるようになる
    • スマホやタブレット向けアプリも⼤きく普及

    View Slide

  372. おおまかな開発⼿法の歴史(図)
    ビジネス
    アプリケーション
    サーバーサイド
    ウェブアプリ
    クライアントサイド
    ウェブアプリ
    スマホ向けアプリ
    複雑化した
    ⼤規模ウェブアプリ
    2000 ~ 2005 ~ 2010 ~

    View Slide

  373. ペット vs 家畜
    • インフラと開発に共通するトレンド。ペットのような環境から家畜のよう
    な環境へ。
    • ペット
    • ⾮常に⼤事な存在なので、⼿がかかる
    • 数は少ない
    • 病気になったり死んだりするとダメージが⼤きい
    • 家畜
    • 機械的に管理される存在
    • 数は多い
    • ごく⼀部が病気になったり死んだりしても、ダメージは⼩さい
    • クラウドで「家畜のように扱えるサービスを開発」することで、インフラ
    側の構築/運⽤コストを⼤幅に減らせる

    View Slide

  374. HW HW
    OS
    サーバー仮想化
    OS
    HW HW
    OS OS
    クラウド
    HW HW
    HW HW
    クラウド
    OS OS OS
    Managed Network
    Managed Storage
    Managed Database
    マネージドサービス
    • マシン台数の削減
    • 複雑な操作を削減
    コンテナ
    サービス開発⼒
    維持管理
    変更コスト
    OS OS OS OS
    Legacy Backup etc.
    Legacy Backup etc.
    VS
    レガシーな開発と運⽤⽅式 新しい開発と運⽤⽅式
    ビジネススピード
    ペット vs 家畜 (図)

    View Slide

  375. クラウドの抽象化
    • 変化が激しい世界ではサービス(⼀般向け、社内向け)を塩漬け
    させないことが⼤事
    • 塩漬けさせないコツ
    • 「開発して終わり -> 2年後に更新」ではなく運⽤を続けな
    がら開発を継続する
    • 開発したサービスをすぐに「どこにでも」展開できる
    • 特定クラウドにサービスを依存させないコツ
    • 特定クラウドに特化した機能ではなく、汎⽤的な機能を使う
    • コンテナやオーケストレーションツールをつかって、サービ
    ス⾃⾝を最初から可搬性が⾼い設計で作る

    View Slide

  376. クラウドの抽象化 (図)
    HW HW HW HW HW HW
    パブリック1 プライベート
    HW HW HW
    パブリック2
    Ct2
    Ct1
    クラウドの抽象化レイヤー(Docker, Kubernetesなど)
    Ct2
    Ct1
    開発
    本番(ウェブサービス)
    Ct4
    Ct3
    開発
    Ct4
    Ct3
    Ct4 Ct4
    本番(ビッグデータ処理)

    View Slide

  377. トレンドを読むことで将来に備える
    • ⾰新的な技術はいきなりは普及しない
    • その技術が求められている⼟壌が確実にある
    • 技術が誕⽣してから最先端の⼈達に広がるのに3年以上はか
    かる。⼀般層に広がるにはもっと時間がかかる
    • ⽇本で普及する前にアメリカで普及することがほとんど
    • 相当な審美眼がない限りは超最先端を追う必要はなく、超最先
    端な技術の多くは普及せず終わる
    • 「世間に広まりつつあるな」と思ってから「誰にたいして」
    「背景」「タイミング」などについて考察してみる
    • 興味を持てば新しいことは楽しんで学べるし試せる

    View Slide

  378. 終わりに
    • ⼩中学校でのプログラミング履修からわかるように、簡単なプ
    ログラミングは⾮ITを含む多くの業務で求められるベーシック
    スキルとなりつつあります
    • Pythonは他の多くのプログラミング⾔語より簡単で、いろいろ
    な⽬的で利⽤することのできる⾔語です
    • 是⾮、本トレーニング資料を読んで終わりにするのではなく実
    際に⾃分の⼿でプログラムを書いてみてください

    View Slide