プログラムちょい替え（１）「Pythonと共に百人一首で勝ちたい」をdockerで動かしてみた, docker(83)

Pythonと共に百人一首で勝ちたい
https://qiita.com/chizuchizu/items/c5401c10682daef5a260

を拝見した。

面白そう。子供が小学生の頃、２年生と５年生での百人一首の対抗戦があった。
同じ先生が２学年担当されていて、、、。

小学生でもすぐに動かせるようにdocker hubに登録してみた。
（小学生の親御さんには、pythonで言語処理100本ノックを試していただくために、
docker登録をwindowsでもmac OSでも、Linuxでもお願い中。）

 
 <この項は書きかけです。順次追記します。>

dockerが動く場所なら

```
docker run -it kaizenjapan/hyaku-py  /bin/bash --login
```
で動くはず。うまくうごかなければ、エラーメッセージなどをおしらせくださると幸いです。

#git
gitは下記とのこと

Chizuchizu/百人一首_GUI.py
https://gist.github.com/Chizuchizu/bb4f067beaabc80e7c64bf461f36c095#file-_-csv

>詳しいことは https://chizuchizu.com/2018/12/18/pythonと共に百人一首で勝つ！！/
こちらに書いてあります。

はリンク切れになっていた。

Pythonと共に百人一首で勝ちたい
https://chizuchizu.com/2018/12/18/pythonと共に百人一首で勝ちたい/

らしい。

データが、
百人一首_百人一首.csv
となっている。プログラム上は

Qiitaでは

```
 return pd.read_csv("百人一首.csv")
```

githubでは

```
    df = pd.read_csv("uta.csv")
```

データ名をuta.csvにしてもらえるとありがたいかも。
docker上ではuta.csvにcopyして使っています。

#動作

dockerで動かしてみた。自分では、普段、pythonはanacondaを利用している。

```
$ docker run -it continuumio/anaconda3 /bin/bash
```

```
# wget https://gist.github.com/Chizuchizu/bb4f067beaabc80e7c64bf461f36c095/archive/519226da82f8822ce99bab6d3e95200f9585e22d.zip
--2019-04-27 07:16:15--  https://gist.github.com/Chizuchizu/bb4f067beaabc80e7c64bf461f36c095/archive/519226da82f8822ce99bab6d3e95200f9585e22d.zip
Resolving gist.github.com (gist.github.com)... 192.30.255.119, 192.30.255.118
Connecting to gist.github.com (gist.github.com)|192.30.255.119|:443... connected.
HTTP request sent, awaiting response... 302 Found
Location: https://codeload.github.com/gist/bb4f067beaabc80e7c64bf461f36c095/zip/519226da82f8822ce99bab6d3e95200f9585e22d [following]
--2019-04-27 07:16:16--  https://codeload.github.com/gist/bb4f067beaabc80e7c64bf461f36c095/zip/519226da82f8822ce99bab6d3e95200f9585e22d
Resolving codeload.github.com (codeload.github.com)... 192.30.255.121, 192.30.255.120
Connecting to codeload.github.com (codeload.github.com)|192.30.255.121|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: unspecified [application/zip]
Saving to: ‘519226da82f8822ce99bab6d3e95200f9585e22d.zip’

519226da82f8822ce99     [ <=>                ]   4.72K  --.-KB/s    in 0.1s    

2019-04-27 07:16:17 (44.9 KB/s) - ‘519226da82f8822ce99bab6d3e95200f9585e22d.zip’ saved [4830]

(base) root@6f043c08a45e:/# ls
519226da82f8822ce99bab6d3e95200f9585e22d.zip  dev   lib    mnt	 root  srv  usr
bin					      etc   lib64  opt	 run   sys  var
boot					      home  media  proc  sbin  tmp

(base) root@6f043c08a45e:/# apt install unzip
Reading package lists... Done
Building dependency tree       
Reading state information... Done
Suggested packages:
  zip
The following NEW packages will be installed:
  unzip
0 upgraded, 1 newly installed, 0 to remove and 22 not upgraded.
Need to get 170 kB of archives.
After this operation, 547 kB of additional disk space will be used.
Get:1 http://deb.debian.org/debian stretch/main amd64 unzip amd64 6.0-21 [170 kB]
Fetched 170 kB in 0s (540 kB/s)
debconf: delaying package configuration, since apt-utils is not installed
Selecting previously unselected package unzip.
(Reading database ... 12505 files and directories currently installed.)
Preparing to unpack .../unzip_6.0-21_amd64.deb ...
Unpacking unzip (6.0-21) ...
Processing triggers for mime-support (3.60) ...
Setting up unzip (6.0-21) ...
(base) root@6f043c08a45e:/# unzip 519226da82f8822ce99bab6d3e95200f9585e22d.zip 
Archive:  519226da82f8822ce99bab6d3e95200f9585e22d.zip
519226da82f8822ce99bab6d3e95200f9585e22d
   creating: bb4f067beaabc80e7c64bf461f36c095-519226da82f8822ce99bab6d3e95200f9585e22d/
  inflating: bb4f067beaabc80e7c64bf461f36c095-519226da82f8822ce99bab6d3e95200f9585e22d/百人一首_GUI.py  
  inflating: bb4f067beaabc80e7c64bf461f36c095-519226da82f8822ce99bab6d3e95200f9585e22d/百人一首_main.py  
  inflating: bb4f067beaabc80e7c64bf461f36c095-519226da82f8822ce99bab6d3e95200f9585e22d/百人一首_百人一首.csv  
(base) root@6f043c08a45e:/# ls
519226da82f8822ce99bab6d3e95200f9585e22d.zip				   opt
bb4f067beaabc80e7c64bf461f36c095-519226da82f8822ce99bab6d3e95200f9585e22d  proc
bin									   root
boot									   run
dev									   sbin
etc									   srv
home									   sys
lib									   tmp
lib64									   usr
media									   var
mnt
(base) root@6f043c08a45e:/# cd bb4f067beaabc80e7c64bf461f36c095-519226da82f8822ce99bab6d3e95200f9585e22d/
(base) root@6f043c08a45e:/bb4f067beaabc80e7c64bf461f36c095-519226da82f8822ce99bab6d3e95200f9585e22d# ls
百人一首_GUI.py  百人一首_main.py  百人一首_百人一首.csv

(base) root@6f043c08a45e:/bb4f067beaabc80e7c64bf461f36c095-519226da82f8822ce99bab6d3e95200f9585e22d# ls -al
total 24
drwxr-xr-x 2 root root 4096 Dec 25 03:09 .
drwxr-xr-x 1 root root 4096 Apr 27 07:16 ..
-rw-r--r-- 1 root root 5395 Dec 25 03:09 百人一首_GUI.py
-rw-r--r-- 1 root root 2039 Dec 25 03:09 百人一首_main.py
-rw-r--r-- 1 root root 2146 Dec 25 03:09 百人一首_百人一首.csv
(base) root@6f043c08a45e:/bb4f067beaabc80e7c64bf461f36c095-519226da82f8822ce99bab6d3e95200f9585e22d# chmod +x *.py
(base) root@6f043c08a45e:/bb4f067beaabc80e7c64bf461f36c095-519226da82f8822ce99bab6d3e95200f9585e22d# ls -al
total 24
drwxr-xr-x 2 root root 4096 Dec 25 03:09 .
drwxr-xr-x 1 root root 4096 Apr 27 07:16 ..
-rwxr-xr-x 1 root root 5395 Dec 25 03:09 百人一首_GUI.py
-rwxr-xr-x 1 root root 2039 Dec 25 03:09 百人一首_main.py
-rw-r--r-- 1 root root 2146 Dec 25 03:09 百人一首_百人一首.csv

(base) root@6f043c08a45e:/bb4f067beaabc80e7c64bf461f36c095-519226da82f8822ce99bab6d3e95200f9585e22d# python 百人一首_main.py
【チズチズの決まり字特訓】

【ルール】
上の句（決まり字）を詠むので、下の句の決まり字を答えて下さい。
辞めたかったら「end」って言ってね！

Traceback (most recent call last):
  File "百人一首_main.py", line 86, in <module>
    main()
  File "百人一首_main.py", line 78, in main
    uta = load()[uta_len]
  File "百人一首_main.py", line 9, in load
    df = pd.read_csv("uta.csv")
  File "/opt/conda/lib/python3.7/site-packages/pandas/io/parsers.py", line 678, in parser_f
    return _read(filepath_or_buffer, kwds)
  File "/opt/conda/lib/python3.7/site-packages/pandas/io/parsers.py", line 440, in _read
    parser = TextFileReader(filepath_or_buffer, **kwds)
  File "/opt/conda/lib/python3.7/site-packages/pandas/io/parsers.py", line 787, in __init__
    self._make_engine(self.engine)
  File "/opt/conda/lib/python3.7/site-packages/pandas/io/parsers.py", line 1014, in _make_engine
    self._engine = CParserWrapper(self.f, **self.options)
  File "/opt/conda/lib/python3.7/site-packages/pandas/io/parsers.py", line 1708, in __init__
    self._reader = parsers.TextReader(src, **kwds)
  File "pandas/_libs/parsers.pyx", line 384, in pandas._libs.parsers.TextReader.__cinit__
  File "pandas/_libs/parsers.pyx", line 695, in pandas._libs.parsers.TextReader._setup_parser_source
FileNotFoundError: File b'uta.csv' does not exist
(base) root@6f043c08a45e:/bb4f067beaabc80e7c64bf461f36c095-519226da82f8822ce99bab6d3e95200f9585e22d# ls
百人一首_GUI.py  百人一首_main.py  百人一首_百人一首.csv
(base) root@6f043c08a45e:/bb4f067beaabc80e7c64bf461f36c095-519226da82f8822ce99bab6d3e95200f9585e22d# cp *.csv uta.csv
(base) root@6f043c08a45e:/bb4f067beaabc80e7c64bf461f36c095-519226da82f8822ce99bab6d3e95200f9585e22d# ls
uta.csv  百人一首_GUI.py  百人一首_main.py  百人一首_百人一首.csv
(base) root@6f043c08a45e:/bb4f067beaabc80e7c64bf461f36c095-519226da82f8822ce99bab6d3e95200f9585e22d# python 百人一首_main.py
【チズチズの決まり字特訓】

【ルール】
上の句（決まり字）を詠むので、下の句の決まり字を答えて下さい。
辞めたかったら「end」って言ってね！

【 1 問目】上の句は つく
下の句は？ こひそ
正解です！

【 2 問目】上の句は せ
下の句は？ しらん
不正解です

せ の正解は われ でした。

【 3 問目】上の句は ほ
下の句は？ end
またね
```
 
直接実行しようとすると、

```
# ./百人一首_main.py
./百人一首_main.py: line 1: import: command not found
./百人一首_main.py: line 2: from: command not found
./百人一首_main.py: line 3: import: command not found
./百人一首_main.py: line 4: import: command not found
./百人一首_main.py: line 5: import: command not found
./百人一首_main.py: line 8: syntax error near unexpected token `('
./百人一首_main.py: line 8: `def load():'
```
pythonファイルの先頭に、

```python:hyaku_main.py
#! /usr/bin/env python
# -*- coding: utf-8 -*-
import random
import pandas as pd
 
 
def load():
    return pd.read_csv("百人一首.csv")
 
 
def loop(simo, kami):
    while True:
        k = 99  # 1~99の数字です。 何番目までの範囲か決められます。
        n = random.randint(0, k)  # 詠む番号を決める
        i = 0
 
        while True:
            j = 1
            simo_n = simo[n]
            kami_n = kami[n]
 
            print("【", j, "問目】下の句は", simo_n, "\n")
 
            s = input()
            if s == "end":  # endは終了
                break
 
            if kami_n == s:  # 正解ならもう次のループ
                print("正解です！\n")
                break
            else:
                print("不正解です…\n")
                print("後", 1, "回チャンスを与えます")
                if len(kami_n) != 0:
                    print("上の句の一文字目は", kami_n[0])
                    print(len(kami_n), "文字です。")
                else:
                    print("1文字です。\n")
 
                s = input()
                if s == "end":
                    break
                if kami_n == s:
                    print("正解です")
                    print(simo_n, "の正解は", kami_n, "でした。\n")
                else:
                    print("不正解です\n")
                    print(simo_n, "の正解は", kami_n, "でした。\n")
 
                break
 
        j += 1
        if s == "end":
            break
 
 
def main():
    df = load()  # データの読み込み
 
    kami = df["上"]
    simo = df["下"]
 
    # ルール説明
    print("【チズチズの決まり字特訓】\n")
    print("【ルール】")
    print("下の句（決まり字）を詠むので、上の句の決まり字を答えて下さい。")
    print("辞めたかったら「end」って言ってね！\n")
 
    loop(simo, kami)
 
 
if __name__ == "__main__":
    main()  # 実行
```
２行追記。

「coding: utf-8」は、下記のコーディング規則では、

>ASCII (Python 2) や UTF-8 (Python 3) を使用しているファイルにはエンコーディング宣言を入れるべきではありません。

と書かれている。Webで公開している文字列は保存する際に、保存する側の都合の文字コードになる。各種OS間で複写、変数するソフトで、文字コードを変換してしまう場合がある。おまじないとして入れておくことに意味があるかどうかは、事例を蓄積して検討する予定。



# ファイル名

ファイル名で日本語を使うと、OSによっては文字として認識しない場合があります。
ASCII文字と_（アンダーバー）だけでファイル名にすることをお勧めします。

日本語の方がわかりやすいと思うことがあるかもしれません。文字コードの落とし穴に嵌っても自力で這い上がれる技術力のある人向けのソフトなら日本語ファイル名もいいかもしれません。技術力を前提としない場合は日本語のファイル名にはしない方がいいかも。

Shift_JISのダメ文字
https://sites.google.com/site/fudist/Home/grep/sjis-damemoji-jp

日本語は使っちゃダメ!?ファイル名の正しいつけ方
http://blog.black-and-lemonade.com/2015/03/30/charcode

```shell-session:docker
# cp 百人一首_百人一首.csv uta.csv
# cp 百人一首_main.py hyaku_main.py
# cp 百人一首_GUI.py hyaku_GUI.py
```

# 自動起動

dockerコマンドを打てば、プログラムの実行までを自動実行するようにする。

## .bash_profile

```shell:.bash_profile
# .bash_profile

if [ -f ~/.bashrc ]; then
     . ~/.bashrc
fi

cd /hyaku-py
./hyaku_main.py
```
.bash_profile ファイルを、/rootの下に作る。

```shell-session
# apt install vim
# cd /root
# vi .bash_profile
# source .bash_profile
```
最後の行は動作確認
host OSでのdocker登録作業は下記。

```shell-session
$ docker ps
CONTAINER ID        IMAGE                  COMMAND                  CREATED             STATUS              PORTS               NAMES
ca6835b1824a        kaizenjapan/hyaku-py   "/usr/bin/tini -- /b…"   2 minutes ago       Up 2 minutes        8888/tcp            elegant_allen
$ docker commit ca6835b1824a  kaizenjapan/hyaku-py
sha256:d87300f44f3fd0c75516e35156ec2bb7e984abb7cf89a7896c20630f6ffa9f97
$ docker push kaizenjapan/hyaku-py
The push refers to repository [docker.io/kaizenjapan/hyaku-py]
6263853356bd: Pushed 
bdd734594f82: Layer already exists 
ad6b039e5efa: Layer already exists 
21501c69c20b: Layer already exists 
9338785d3498: Layer already exists 
abd2c1804296: Layer already exists 
b1f721b57648: Layer already exists 
60b398413f86: Layer already exists 
b28ef0b6fef8: Layer already exists 
latest: digest: sha256:7c28c1656e5e1ce712e48b2ad7cafa6123652d9d6c42865751902a15a4762c99 size: 2210
```

#起動方法

```shell-session
$ docker run -it kaizenjapan/hyaku-py  /bin/bash --login
【チズチズの決まり字特訓】

【ルール】
上の句（決まり字）を詠むので、下の句の決まり字を答えて下さい。
辞めたかったら「end」って言ってね！

【 1 問目】上の句は ほ
下の句は？ 
```

#GUI版
GUI版の方が実行できる環境はまだ設定していません。ごめんなさい。

```
# ./hyaku_GUI.py 
Traceback (most recent call last):
  File "./hyaku_GUI.py", line 168, in <module>
    app = tk.Tk()
  File "/opt/conda/lib/python3.7/tkinter/__init__.py", line 2023, in __init__
    self.tk = _tkinter.create(screenName, baseName, className, interactive, wantobjects, useTk, sync, use)
_tkinter.TclError: no display name and no $DISPLAY environment variable
```

# コーディング規約
Python の標準ライブラリに含まれているPythonコードのコーディング規約
https://pep8-ja.readthedocs.io/ja/latest/
>スタイルガイドは一貫性に関するものです。このスタイルガイドに合わせることは重要ですが、プロジェクトの中で一貫性を保つことはもっと重要です。一番重要なのは、特定のモジュールや関数の中で一貫性を保つことです。
しかし、一貫性を崩すべき場合があることも知っておいてください - つまり、このスタイルガイドが適用されない場合があります。疑問に思ったときは、あなたの判断を優先してください。他の例を調べ、一番良さそうなものを決めて下さい。そして、躊躇せずに質問して下さい！
特に、このPEPに準拠するためにコードの後方互換性を壊すようなことは絶対にしないで下さい！

# 参考資料(reference)
言語処理100本ノックをdockerで。
https://qiita.com/kaizen_nagoya/items/7e7eb7c543e0c18438c4

なぜdockerで機械学習するか 書籍・ソース一覧作成中 (目標100)
https://qiita.com/kaizen_nagoya/items/ddd12477544bf5ba85e2

Dockerをどっかーらどうやって使えばいいんでしょう。TOPPERS/FMP on RaspberryPi with Macintosh編 ５つの関門「名古屋のIoTは名古屋のOSで」
https://qiita.com/kaizen_nagoya/items/9c46c6da8ceb64d2d7af

一覧の一覧( The directory of directories of mine.) Qiita(100)
https://qiita.com/kaizen_nagoya/items/7eb0e006543886138f39

官公庁・学校・公的団体（NPOを含む）システムの課題、官（０）
https://qiita.com/kaizen_nagoya/items/04ee6eaf7ec13d3af4c3

プログラマが知っていると良い「公序良俗」
https://qiita.com/kaizen_nagoya/items/9fe7c0dfac2fbd77a945

自動制御、制御工学一覧（０）
https://qiita.com/kaizen_nagoya/items/7767a4e19a6ae1479e6b

Rust(0) 一覧　
https://qiita.com/kaizen_nagoya/items/5e8bb080ba6ca0281927

小川清最終講義、最終講義（再）計画, Ethernet(100) 英語(100) 安全(100)
https://qiita.com/kaizen_nagoya/items/e2df642e3951e35e6a53

 ＜この記事は個人の過去の経験に基づく個人の感想です。現在所属する組織、業務とは関係がありません。＞
### 文書履歴(document history)
ver. 0.01 初稿 20190427 夕
ver. 0.02 参考資料, docker hub登録方法追記 20190427 夜
ver. 0.03 はてな追記 2090514

<a href="http://b.hatena.ne.jp/entry/s/qiita.com/kaizen_nagoya/items/f8297f544fcbf4787f2a" class="hatena-bookmark-button" data-hatena-bookmark-layout="basic-label-counter" data-hatena-bookmark-lang="ja" title="このエントリーをはてなブックマークに追加"><img src="https://b.st-hatena.com/images/v4/public/entry-button/button-only@2x.png" alt="このエントリーをはてなブックマークに追加" width="20" height="20" style="border: none;" /></a><script type="text/javascript" src="https://b.st-hatena.com/js/bookmark_button.js" charset="utf-8" async="async"></script>
http://b.hatena.ne.jp/guide/bbutton

### 最後までおよみいただきありがとうございました。
いいね　💚、フォローをお願いします。
#### Thank you very much for reading to the last sentence.
Please press the like icon 💚　and follow me for your happy life.