Python プログラミング ワークショップ - 超々入門編 Vol.2

# 本題の前に

---
## 位置付け・前提

本記事は、**社内ワークショップ** のために用意したものです。そのため、次の前提で進めることをご理解ください。

---
## 本ワークショップの目的
参加者が**必要に併せて自学できる入口に立つ** ことを目的とします。

* 実用的なプログラミングを **ハンズオン形式** で実行して、理解を深めます。
* 本ワークショップだけで、あらゆるプログラムがすいすい組めるようになるわけではありません。
* 後日にプログラミングで何かを作ろうとしたときに、自分で調べて製作できるようになることを目指します。
* なんかこういうもんだ、という感じで軽く頭に残れば大丈夫と考えましょう。

---
## ワークショップの進め方
ワークショップは、基本的にハンズオンを中心に進めます。（一部解説は入れます）

* ご自分の業務用途のパソコンを利用してください。
* 基本的には**「写経」**を原則とします。
    * 写経 ＝ 自分でキー入力して写すこと ≠ コピペ
        * 自分が書いたコードをコピペしてから改変するのはOK。
    * 書き方を頭の中に入力する/刷り込むつもりで、時間がかかっても全て手でキー入力してください。
    * IMEの入力補完はOK。
    * 入力間違いによるトライ・アンド・エラーも、学習の中での重要な要素とご理解ください。
* 紹介する内容は、**基本的には分からないもの**です。一度すべて動作させてから「あー、あんな感じか」とニュアンスを掴んでください。
* 深く悩んではいけません。

---
## 注意

本ワークショップは **60〜120分** を想定しています。そのため、本格的な学習には時間が圧倒的に足りないので、**体系的な学習は行いません**。

本格的に０から思い通りのプログラムが組めるようになるには、自学習もしくは何らかの講座を受講する必要があります。

---
## ターゲット
本ワークショップでは、主に下記の参加者を対象とします。

* プログラミングを本業としない人
* プログラミングが苦手、あるいは実用的なプログラムを組んだことが無い人
* プログラミングの基礎的なことを知らない初心者

中上級者はまったく相手にしていないため、敢えて言及しない事項が沢山あることについてはご了承ください。

---
## プログラミング環境の準備

[こちら](https://qiita.com/syamane/items/76942bdd7258b13a9f3b)をごらんください。

---
## 前回の復習

次の問題に答えてください。
1. **print("Hello")** を Python で実行すると何が起こる？
2. **TEXT = "Hello World!"** の TEXT を何て呼ぶ？
3. ファイルを保存するときに使う３つの命令は、ファイルを開く「　　　」、書き込む「　　　　」、書き込み終了「　　　」です。

※分からない方は [Vol.1](https://qiita.com/syamane/items/76942bdd7258b13a9f3b) を読み直してください

---
前回覚えたこと

* Python言語の実行環境の作り方
* プログラム（スクリプト）の実行方法
* 変数
* ファイルへの書き込み
* データをダウンロードする方法（GET）

---
## 本日のゴール

保存したテキストファイルの内容や計算結果を**Slackへ投稿するスクリプト**（ほぼSlack bot）を作成します。

可能であれば、書いた内容については後から正しく理解してください。ただし、完璧に覚える必要はありません。

---
# ハンズオン開始

---
## ハンズオン1

---
### ハンズオン1-0. Slack アカウントとアップロード先の準備

別の指示に従って、下記を準備してください。

* Slack アカウント
* Slack ワークスペースへのログイン
* Slack アップロード先URL（Incoming Webhook） 

なお、最後のSlack アップロード先URLは、今後「**POST先URL**」と呼びます。（理由は後述）

---
### ハンズオン1-1. Slack に投稿する

c:\scriptフォルダに、次のスクリプトを exp11.py という名前で保存して実行しなさい。

```python:ex11.py
import requests
import json
URL = "［POST先URL］"
MESSAGE = json.dumps({"text": "TEST"})
requests.post(URL, MESSAGE)
```
もちろん、［POST先URL］は準備したURLに置き換えてください。

---
### ハンズオン1-2. Slack に投稿する内容を変更する

ex11.py の内容のうち、３行目を下記のように書き換えなさい。（自分が書いたコードはコピペOK）

```python:ex11.py（変更箇所のみ）
MESSAGE = json.dumps({"text": "Hello"})
```

その後、再度 exp11.py を保存して、スクリプトを実行しなさい。

---
### ハンズオン1-3. Slack に何度も投稿する

c:\scriptフォルダを作成し、次のスクリプトを exp13.py という名前で保存して実行しなさい。

```python:ex13.py
import requests
URL = "［POST先URL］"

MESSAGE = json.dumps({"text": "Hello"})
requests.post(URL, MESSAGE)

MESSAGE = json.dumps({"text": "Hi"})
requests.post(URL, MESSAGE)

MESSAGE = json.dumps({"text": "YEAH!"})
requests.post(URL, MESSAGE)
```

もちろん、［POST先URL］は準備したURLに置き換えてください。

---
### ハンズオン1-3a. Slack に何度も投稿する（改善版）

c:\scriptフォルダを作成し、次のスクリプトを exp13.py という名前で保存して実行しなさい。

```python:ex13.py
import json
import requests
URL = "［POST先URL］"

for Msg in ["Hello", "Hi", "YEAH!"]:
    MESSAGE = json.dumps({"text": Msg})
    requests.post(URL, MESSAGE)
```

もちろん、［POST先URL］は準備したURLに置き換えてください。

---
### ハンズオン1-3b. Slack に何度も投稿する（追加）

exp12.py の該当箇所を、次のように書き換えて実行しなさい。

```python:ex13.py
for Msg in ["Hello", "Hi", "YEAH!", "Good!!"]:
```

もちろん、［POST先URL］は準備したURLに置き換えてください。

---
## 解説１

---
### プログラミングのおやくそく（復習）

* 基本的に**上から一行ずつ実行**します。
* プログラミングとは、「プログラムを書く → 実行する → 誤ったところを修正する → 再実行する」を繰り返すのが基本です。
* なるべく読みやすく、短く書ければ書けるほど良いです。
* **最初はルールを暗記**しないこと。慣れるまでは、**後でググれるように練習**していくのが近道です。
* **変数 = 何かに付けた別名**

---
### ハンズオン1-1 解説

実行した ex11.py に解説をつけるとこうなります。

```python
import requests
```

前回ダウンロードに使った便利なツール（モジュール）「requests」を利用することを宣言します。

---

```python
import json
```

同じく **JSON**という書き方を扱うためのモジュールを利用することを宣言します。

この JSON の書き方は簡単ですが、いくつかルールがあります。

ここでは詳しく触れませんので、そういうものだと割り切ってください。また、可能な方は、[コチラ](http://www.tohoho-web.com/ex/json.html)を読んでください。

---

```python
URL = "［POST先URL］"
```

前回勉強した変数が出てきました。

ここでは POST先URL を変数に入れています。

以降は URL と書けば、POST先URL の文字列として利用できます。

---

```python
MESSAGE = json.dumps({"text": "TEST"})
```

また、変数が出てきました。

変数 MESSAGE は良いとして、問題は json.dumps({"text": "TEST"}) です。

仕方ないので、JSONの書き方を一部だけお伝えします。

JSON は **{"名前": "何かの値/文字列"}** という書き方をします。

そうすると、{"text": "TEST"} は text が名前、TEXT が文字列と書いていることが分かります。

その手前に おまじないとして json.dumps があります。

このような書き方をすれば、Python がJSON形式のデータだと認識してくれるわけです。

非常にメンドクサイですが、こんな書き方をするには分けがあります。

---

```
requests.post(URL, MESSAGE)
```

いよいよ Slack に投稿するところです。

よく「アップロードする」と言いますが、専門用語では「POST（ポスト）」と呼びます。

詳しいことは省きますが、POST は特定のURLに何らかのデータを送る処理です。

![POST](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107190/4e3333f2-e114-864f-1678-a616b8c21428.png)

このときの命令の書き方のオーソドックスな例として、上記の書き方になります。

そして、先程の変数 MESSAGE が JSON形式 でなければいけなかった理由ですが、答えはこちらです。

**Slack の API（受付口） が JSON形式しか受け付けてくれないから**

そんなわけで、仕方なく JSON形式 を使いました。

覚えると便利な形式ですが、今はそんなに詳しく覚える必要はありません。

---
### ハンズオン1-2 解説

書き換えた箇所を確認しましょう。

```python:ex11.py（変更箇所のみ）
MESSAGE = json.dumps({"text": "Hello"})
```

JSONデータの "text" の値を "Test" から "Hello" に書き換えただけです。

つまり、Slack のタイムラインに投稿するメッセージは、この値がそのままだということが分かります。

もちろん、他の文字列に書き換えれば、投稿するメッセージの内容も書き換わります。

---
### ハンズオン1-3 解説

最初の ex13.py は同じ処理をメッセージの文字列を変更して、３回並べただけです。

しかし、同じ記載を３回も書くのはメンドクサイですよね。例えコピペしたとしても。

そこで、**繰り返し処理** というものに書き換えたのが次の書き方です。

```python:ex13.py（抜粋）
for Msg in ["Hello", "Hi", "YEAH!"]:
    MESSAGE = json.dumps({"text": Msg})
    requests.post(URL, MESSAGE)
```

この書き方だと、メッセージだけは変更しながら３回同じ処理を実行してくれます。

その中でも、ここが最大の山場です。そして、覚えるとかなり便利！

```python
for Msg in ["Hello", "Hi", "YEAH!"]:
```

変数 Msg に "Hello"、"Hi"、"YEAH!"　の順番で入れて、その後の処理を実行しろ、という意味になります。

---
この**繰り返し処理**を各ルールは下記の通りです。

```python
for 変数名 in [順番に変数に入れる内容]:
    繰り返す処理内容
```

for / in / : の順番がとても重要ですので、どれも忘れないようにして下さい。

また、繰り返す処理内容 部分は、前に数個（だいたい４個）のスペースを入れてください。これを**インデント**と呼びます。

このインデントの有無で、繰り返す処理の範囲を決めています。

この**繰り返し処理**によって、大量の処理をコンピュータに行わすことが可能になってきます。

---
ちなみに、1～5までを表示させる繰り返し処理ははこんな感じ。

```python
for i in range(1, 6):
    print(i)
```

rangeで範囲を指定していますが、それ以外は先程の繰り返しと同じです。

rangeは次のようなルールになります。

```python
range(表示する最初の値, 繰り返す上限（この値自体は表示されない)
```

実行すると、次のようになります。
```bash
1
2
3
4
5
```
6は表示されず、1<=N<6 で整数を表示する指定になっています。



変数と併せて、この**繰り返し処理はプログラミングの肝**になります。

丸暗記しなくても良いのですが、必ず習得はしましょう。

---

ハンズオン1-3b はこちらです。

```python:ex13.py
for Msg in ["Hello", "Hi", "YEAH!", "Good!!"]:
```

"YEAH!" と ] の間に、「, "Good!!"」とを追加しました。

このように書くことで、繰り返し処理の回数を増やすことができます。

もちろん、"YEAH!" などを消せば、繰り返し処理の回数は減らせます。

---
### ハンズオン1 まとめ

* POST（request.post）
* 繰り返し処理
* ~~JSON形式~~

---
## ハンズオン2

---
### ハンズオン2-1. Slack にファイルに保存した内容を投稿する

c:\scriptフォルダに、次の内容を書いたファイルを message.txt という名前で保存しなさい。

```text:message.txt
TEST MESSAGE
```

その後、c:\scriptフォルダに次のスクリプトを exp21.py という名前で保存して実行しなさい。

```python:ex21.py
import requests
import json
URL = "［POST先URL］"

file = open("message.txt")
MSG = file.read()
file.close()

MESSAGE = json.dumps({"text": MSG})
requests.post(URL, MESSAGE)
```

もちろん、［POST先URL］は準備したURLに置き換えてください。

---

### ハンズオン2-2. Slack にファイルに保存した内容を投稿する（複数）

c:\scriptフォルダに、次の内容を書いたファイルを message2.txt という名前で保存しなさい。

```text:message2.txt
Hello world.
```

その後、c:\scriptフォルダに次のスクリプトを exp21.py を次のように書き換えて実行しなさい。

```python:ex21.py（変更箇所）
for filename in ["message.txt", "message2.txt"]:
    file = open(filename)
    MSG = file.read()
    file.close()

    MESSAGE = json.dumps({"text": MSG})
    requests.post(URL, MESSAGE)
```

---
### ハンズオン2-3. Slack に計算した結果を投稿する

c:\scriptフォルダに、次のスクリプトを exp23.py を次のように書き換えて実行しなさい。

```python:ex23.py
import requests
import json
URL = "［POST先URL］"

for i in range(1, 5):
    MSG = 2 * i
    MESSAGE = json.dumps({"text": MSG})
    requests.post(URL, MESSAGE)
```

---
## 解説２

---
### ハンズオン2-1 解説

実行した ex21.py のうち、新しく出てきた箇所はこちらです。

```python:ex21.py
file = open("message.txt")
MSG = file.read()
file.close()
```

前回ファイルへ書き込む方法について紹介しましたが、今回は読み込む方法です。

書き込む場合と読み込む場合は次のように違いがあります。

```python
open("ファイル名", "w")  # ファイルに書き込む場合
open("ファイル名", "r")  # ファイルを読み込む場合
open("ファイル名")       # ファイルを読み込む場合（省略）
---

何も指定しないで open すれば読み込むと覚えると良いでしょう。

また、変数 file にファイルを入れたは良いですが、その内容を読み出すのは次の命令です。

```python
変数 = ファイルの変数.read()
```

そうすればファイルの中身が変数に、文字列として読み込まれます。ちなみに、下記はNGです。

```python
変数 = ファイルの変数
```

これは**ファイルの変数に別の名前を付ける**だけです。中身は読み出してくれません。ご注意ください。

---
### ハンズオン2-2 解説

書き換えた exp21.py のうち、注目すべきところはこちら。

```python:ex21.py（抜粋）
for filename in ["message.txt", "message2.txt"]:
    file = open(filename)
```

指定するファイル名も変数にいれて、繰り返し処理の一部にできるというところです。

これにより、大量のファイルに対して、同じ処理を行うことができます。

よくやる実例としては、大量のCSVファイルを1つのCSVファイルに統合する、といったような使い方です。

繰り返し処理は、覚えるとホントに便利です。

---

### ハンズオン2-3 解説

exp23.py で注目するポイントはコチラです。

```python:ex23.py（抜粋）
for i in range(1, 5):
```

range や open のような特定のまとまった処理を、プログラミングの世界では**関数**と呼びます。

この range 関数は、range(開始番号, 終了番号) の形式で利用します。ここでは、1～5 の整数を出力させるために使いました。

今回の for文（forは関数とは呼びません）では、変数 i に 1 から順に 1 から 5 の整数を入れて、繰り返し処理を行います。

---
そして、もう一つのポイントは計算部分です。

```python
MSG = 2 * i
```

プログラミングでは、いろんな計算を多用します。その代表例が四則演算です。

```python
+  # 加算
-  # 減算
*  # かけ算
/  # 割り算
```

計算式の書き方は、数学の式のそれとまったく同じです。

先の式では、2 かける 変数iの値 の計算結果を、変数 MSG に格納しているわけです。

あとの処理で、その計算結果を Slack に投稿しているというわけです。

なお、四則演算 以外にも様々な演算が行えるのですが、それについてはまた別の機会に。

---
### ハンズオン2 まとめ

* ファイルの読み込み（open関数とread命令)
* 指定した範囲の整数を出力（range関数）
* 四則演算

---
## 練習問題

こちらの要件を満たすスクリプトを作って、実行してみましょう。

1 http://httpbin.org/ip へ接続して、自分の接続元IPアドレスを取得する。
2 ダウンロードした情報（接続元IPアドレス）を tmp.json ファイルに保存する
3 保存した ip.json ファイルの内容を Slack に投稿する
4 http://httpbin.org/json の接続結果（サンプルデータ）を、同じく2～3の処理をする
5 http://httpbin.org/user-agent の接続結果（Webブラウザの種別）を、同じく2～3の処理をする

余談ですが、http://httpbin.org はサンプル作成やネットワークの疎通確認に便利です。ぜひご利用ください。

---
# 終わりに

今回もプログラミングの基礎的なエッセンスを、いくつも詰め込んだワークショップにしてみました。

特に、プログラミングで重要なキーワードとして「繰り返し処理」と「関数」、「四則演算」を紹介しました。

あとは「条件式」や「テキストの整形」、「比較演算」などが理解できれば、徐々に実用的なプログラミンができるようになります。

次回までは、基礎の基礎だと考えながら、我慢して進めましょう！

なお、説明を端折っている部分が沢山ありますが、初心者向けということで玄人は我慢してください。

今後も学習したい方はリクエストをいただければと思います。

<!---
### ハンズオン3-1. Slack に時間を空けて何度も投稿する

---
### ハンズオン3-3. Slack にある時間になったら投稿する
-->

---
# 参考となる情報源

---
## 本日の内容を深めるための情報源

* 表示(print)
    * [初心者がPythonの練習 - Qiita](https://qiita.com/pugiemonn/items/c98e4e24daa177975240)
    * [文字列リテラルを記述する | Python入門](https://www.javadrive.jp/python/string/index1.html)
* 変数
    * [変数の使い方 | Python入門](https://www.javadrive.jp/python/var/)
    * [Python超入門その８〜変数の使い方をマスターしよう〜 | プログラミング教室情報サイト【プロナビ】](https://programming-study.com/technology/python-master-variables/)
* ファイル
    * [【Python入門】ファイルの文字列の読み込みと書き込みの方法 | プログラミング教室情報サイト【プロナビ】](https://programming-study.com/technology/python-file/)
    * [Pythonでファイルの読み込み方法をマスター｜open関数 | 侍エンジニア塾ブログ（Samurai Blog） - プログラミング入門者向けサイト](https://www.sejuku.net/blog/60333)
* ダウンロード（requests）
    * [Requests の使い方 (Python Library) - Qiita](https://qiita.com/sqrtxx/items/49beaa3795925e7de666)
    * [PythonのRequestsモジュールの使い方【初心者向け】 | TechAcademyマガジン](https://techacademy.jp/magazine/19195)
    * [Requests: 人間のためのHTTP — requests-docs-ja 1.0.4 documentation](https://requests-docs-ja.readthedocs.io/en/latest/)
        * 公式資料なので、ちょっと詳しい

---
## 公式
* [Python チュートリアル](https://docs.python.org/ja/3/tutorial/index.html)
* [Python 言語リファレンス — Python 3.7.4 ドキュメント](https://docs.python.org/ja/3/reference/index.html#reference-index)
* [Python 標準ライブラリ — Python 3.7.4 ドキュメント](https://docs.python.org/ja/3/library/)
* [Python 3.7.4 ドキュメント](https://docs.python.org/ja/3/index.html)
* [Pythonモジュール索引](https://docs.python.org/ja/3/py-modindex.html)

---

## Python リファレンスサイト
* [Python入門 ～Pythonのインストール方法やPythonを使ったプログラミングの方法について解説します～ | PythonWeb](https://www.javadrive.jp/python/)
    * やりたいこと別の逆引きなので参照しやすい。
* [Pythonに関する情報 | note.nkmk.me](https://note.nkmk.me/python/)
    * やりたいこと別の逆引きなので参照しやすい。
* [Python入門 - とほほのWWW入門](http://tohoho-web.com/python/index.html)
    * 読みやすいけど、少し古いので注意。Python2ベース。
* [Python - Qiita](https://qiita.com/tags/python)
    * ここで検索すれば大抵の前例は出てくる。

---

## Python関連書籍

* [退屈なことはPythonにやらせよう ―ノンプログラマーにもできる自動化処理プログラミング](https://www.amazon.co.jp/%E9%80%80%E5%B1%88%E3%81%AA%E3%81%93%E3%81%A8%E3%81%AFPython%E3%81%AB%E3%82%84%E3%82%89%E3%81%9B%E3%82%88%E3%81%86-%E2%80%95%E3%83%8E%E3%83%B3%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9E%E3%83%BC%E3%81%AB%E3%82%82%E3%81%A7%E3%81%8D%E3%82%8B%E8%87%AA%E5%8B%95%E5%8C%96%E5%87%A6%E7%90%86%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0-Al-Sweigart/dp/487311778X/)
    * 筆者が Python を学ぶキッカケになった書籍。ただし、タイトルは釣り。
* [いちばんやさしい Python 入門教室](https://www.amazon.co.jp/%E3%81%84%E3%81%A1%E3%81%B0%E3%82%93%E3%82%84%E3%81%95%E3%81%97%E3%81%84-Python-%E5%85%A5%E9%96%80%E6%95%99%E5%AE%A4-%E5%A4%A7%E6%BE%A4-%E6%96%87%E5%AD%9D-ebook/dp/B06Y3ZVS9Y/)
    * 初学者向けに学びやすいと評判。
* [スラスラ読める Pythonふりがなプログラミング](https://www.amazon.co.jp/%E3%82%B9%E3%83%A9%E3%82%B9%E3%83%A9%E8%AA%AD%E3%82%81%E3%82%8B-Python%E3%81%B5%E3%82%8A%E3%81%8C%E3%81%AA%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0-%E6%A0%AA%E5%BC%8F%E4%BC%9A%E7%A4%BE%E3%83%93%E3%83%BC%E3%83%97%E3%83%A9%E3%82%A6%E3%83%89-ebook/dp/B07DR9WNKJ/ref=pd_sbs_351_2/358-4804238-5993600?_encoding=UTF8&pd_rd_i=B07DR9WNKJ&pd_rd_r=40975f9e-29b8-4fe4-b211-14a52bb1f23b&pd_rd_w=0tyUJ&pd_rd_wg=OFv7a&pf_rd_p=ad2ea29d-ea11-483c-9db2-6b5875bb9b73&pf_rd_r=5SPQTNWJSKTJE8VKH4MP&psc=1&refRID=5SPQTNWJSKTJE8VKH4MP)
    * 同上。

---
## Python 学習サービス
手軽にやれるWebサービス/オンラインスクールを集めました。

* [Python 3入門 (全31回) - プログラミングならドットインストール](https://dotinstall.com/lessons/basic_python_v3)
    * 無料で少しは学習できて良い。
* [CheckiO - coding games and programming challenges for beginner and advanced](https://checkio.org/)
    * ゲーム形式で学べて良いと評判。ただし、英語。

---
# おわりに
今後、ワークショップで取り扱いたい題材や困りごとがあれば、本記事のコメントもしくは直接ご連絡ください。（社内外問わず）