【5日目】試しにPythonで遊んでみよう【PythonでDiscordBOTを作ろう！】

# 試しにPythonで遊んでみよう

初めてのものを手に入れたら、やっぱり遊びたくなりますよね。
というわけで、色々なものをすっ飛ばしながら遊んでいきます。

...しかし凄い適当な説明！
出来る限り分かりやすくしたいと思ったのですが、私にはこれが限界のようです！

## Pythonの実行方法
Pythonの実行方法は2種類あります。
`インタラクティブモード`と`スクリプトモード`です。

インタラクティブモードは対話モードと呼ばれ、**1行ずつコードを実行する**モードです。
ちょっとPythonでわからないことがあって、試したいときとかによく使います。
対話モードは`python`と実行するだけで始まります。
```sh
$ python
Python 3.10.0 (default, Dec 11 2021, 16:18:22) [GCC 8.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> import sys
>>> if __name__ == "__main__":
...     print("This is interactive mode")
...
This is interactive mode
>>>
```
こんな感じで、1行ずつコードを実行していきます。

スクリプトモードは、実際にコードを書いてそれを実行するモードです。
基本的にこっちを使います。
`python [ファイル名]`という風に実行することが出来ます。

## 僕が優しく理解らせてあげるからね...？

今後のプログラミングでは**非同期処理**というものを多用します。
非同期処理というのは、プログラミングにおいてかなり難しい分野ですが、意外と何とか理解できるかもしれないので頑張ってみましょう。

```py
import os
import sys

print("Hello world!")
```
これを実行してみてください。
```
Hello world!
```
こんな感じに表示されると思います。

`print`という関数は、画面に文字を表示する関数です。
特に何も問題がないですよね。

では、次です。

```py
import time

print("Hello")
time.sleep(3)
print("World!")
```

`time.sleep`というのは、指定した時間待機する関数です。
Pythonデフォルトの`time`というモジュールの中にあります。

モジュールと`import`については省略させていただきます。
こちらをご参照ください。

https://www.python.jp/train/type_and_func/modules.html

これを実行すると...
```sh
Hello
World!
```
と、`Hello`を表示した後に3秒経ってから`World!`と表示されたと思います。

つづいては関数です。

```py
import time

def hogehoge():
    print("hoge?")
    time.sleep(3)
    print("hoge!")

hogehoge()
```

`hogehoge`という関数を作って、そのあとで呼び出しています。
```sh
hoge?
hoge!
```
ほげほげしてたら成功です。
こんな風に`def 関数名():`という感じにやれば関数を作ることが出来ます。

では早速非同期処理です。

```py
import asyncio

async def main():
    print("Ohayou")
    await asyncio.sleep(3)
    print("Gozaimasu!")

asyncio.run(main())
```
`def`の左に`async`とつけることで、その関数をコルーチン関数にすることが出来ます。
はて...コルーチン関数？となったでしょうが、コルーチン関数とは、おおざっぱに言うと非同期関数のことです。
中に非同期処理を入れることが出来たり、外で非同期処理として実行することが出来ます。

そして、このコルーチン関数は普通に`main()`とやっても実行できません。
(C#とかとは違うんです！)
`await main()`と、先に`await`とつけることで実行できます。
じゃあ、`await main()`と書けばいいじゃんと思いますが、`await`は関数内でしか使えません。
なので、代わりに`asyncio.run(main())`とすることで、実行できます。
...難しいことは私も分かりません。

```sh
Ohayou
Gozaimasu!
```

OhayouとGozaimasu!の間に3秒時間が空いてれば成功です。

```py
import asyncio

async def main1():
    print("main1 start")
    await asyncio.sleep(3)
    print("main1 end")

async def main2():
    print("main2 start")
    await asyncio.sleep(3)
    print("main2 end")

async def main():
    asyncio.ensure_future(main1())
    asyncio.ensure_future(main2())
    await asyncio.sleep(5)

asyncio.run(main())
```

さて、こういう風にしてみましょう。
`asyncio.run(main())`によってmain関数が実行されます。
`main`の中では`asyncio.ensure_future(main1())`と`asyncio.ensure_future(main2())`がありますね。
この`ensure_future`という関数は、コルーチン関数を実行するという点では`asyncio.run`に近いですが、**投げっぱなし**となります。
普通は、関数を実行したらその関数が終わるまで待ち、その次の関数を実行して...となりますが、投げっぱなしとは、実行したら終了を待たずに次の関数を実行するというような感じです。
なので、この関数を実行すると、`main1`が実行された後にそれの終了を待たずに`main2`が実行されます。

```sh
main1 start
main2 start
main1 end
main2 end
```
こんな感じに実行されると思います。

「じゃあ、同時に関数を実行してるんだ！　すげぇ！」となった方。
実をいうとそれは間違いなんです。

Pythonの非同期処理というのは、おおざっぱに言うと「待ち時間を利用した同時処理（風）」だと思ってます。

待ち時間とはIO時間やネットワークの待ち時間。
上のやつで言うと、
まず`print("main1 start")`を実行します。
そして次に`asyncio.sleep(3)`と、3秒待機の**待ち時間**が発生します。
すると、別の関数に実行の権限が渡されて、`print("main2 start")`が実行されます。
そして、`asyncio.sleep(3)`が実行され、また待ち時間が発生します。
すると別の関数に実行が渡されます。そして`print("main1 end")`が実行されます。そして`print("main2 end")`が実行されます。

...

は？

いやまぁ、私も書いてて何言ってるかわかんないです。
とりあえずこのシリーズでわかっておいて欲しいことは、「コルーチン関数内では出来る限り非同期処理を実行する」ということです。
そうすることで、他の関数にちゃんと実行権限が渡されて、関数ちゃんがみんな喜びます。

分からないことがあったら「Python 分からない」とかでググってください。
多分分かります。

# ...

いや、プログラミングって難しいんですよ...
ほんと...自分で理解してても、人に解説するのって本当に難しくて...

とりあえず、習うより慣れよです。
実際にコードを書きながら説明していきます。

なので、あきらめないでください...ほんと...クリスマスまで僕と一緒にいてください...

というわけで、今日の記事はここまでです。
もしよろしければ記事へのいいねをして、次回記事をお楽しみに！