OmniAICreator/Qiita-1.07M huggingface dataset:
モブプロ始めてみました

モブプロを始めて2週間が経ったので状況のふりかえりを。
スクラム開発を開始して約1年が経ち、満を持しての導入でしたが、結果的に導入して成功だったと思います！！

## メンバーに展開した時の状況

前回の記事「[モブプログラミング始めてみます](https://qiita.com/shimi58/items/3cb41a36f0b7999a4bae)」を元にメンバーにモブプロを共有。
リソース効率重視よりもフロー効率重視という認識を持ってもらえました。
スプリントゴールをフロー効率重視、そのためにモブプログラミングを取り入れる、とし1ストーリーだけ実験的に取り入れてみました。

## やってみた感想は

1ストーリーを終えてみて、スプリントレトロスペクティブから最初はモブプロを疑っていたメンバーも続けたいと言ってくれたので良さを実感してもらえたと思います。
なかでもエキスパートのメンバーが率先して楽しんでくれたのがよかったです。(一人でやるほうが早いので、もどかしさはあったはず)
生産性について従来よりも落ちはしました(前回記事の通り生産性以上のメリットがある)が、そんなに悪くなく今日は何ステップ実装した！と日々ふりかえりの白い帽子(Thinking Hats)で共有できており、楽しく開発できています。

## チームのモブプロルール

時間配分はチームメンバー5人なので、10分ごとにタイピスト交代を行い、1順した後15分休憩という流れにしています。(喫煙メンバーがいるので)
2時間予定としていたので、2順できたらいいなーといった感じ。

ドキュメントや調べ物を行う用にサブPCも用意しました。
あとは、今日やるタスクを意識合わせする、リファクタは後回しといったことも取り入れつつ行っています。

## モブプロふりかえりとカイゼン

導入してすぐはやはりカイゼン点が盛りだくさんでした。

~~~
- 最後に合意形成
    - 1つだけ決める
        - 1度に多くのことを変えるのは得策でない。徐々に適応していくことが大事
~~~

1つだけカイゼンは全然守れなかった。。
まあ、カイゼンポイントがたくさんあることはいいことです。

主な課題とカイゼン内容を。

- モブプロ用の場所が遠い
近場の会議室に変更しました。(60インチ4Kモニターは最高によかったが移動に15分かかるのはツライ。。)

- プロジェクターは文字が滲む、目がツライ、眠たくなる
液晶モニターに変えましたが、遠い、見づらい、との意見が。
最終的にはこのような形で落ち着きました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/384317/073d4246-d766-d58a-186b-1e4143a77fe5.png)


    下にいるメンバーはモブマシンの画面を、上にいるメンバーは液晶モニターを見つつ作業することで、遠いという課題をクリアしました。
タイピストにはモブマシンにつないだキーボード、マウスを回しています。


- 切り替え時間が分かりづらい
[kakku22さんのブログ](https://kakakakakku.hatenablog.com/entry/2018/07/01/170255)を参考に、モブタイマーを導入しました。
最初tomato-timerを導入しましたが、音がならなかったり、時間がきているけどキリのいいところまで、となり初回は2時間で1巡しかできませんでした。

    その後、mobsterを取り入れてこれが劇的にカイゼン。
モブマシンの最前面にタイマーが表示され、常に時間を意識することができ、作業にメリハリができました。
時間がくるとアプリ画面にバンッと切り替わるので、強制的にタイピスト交換ができるようになりました。(いいところで時間がきたときは笑いが生まれます笑)
サイコロでランダムにメンバーをシャッフルできるのもいいですね！

- モブプロ後の個人タスクの生産性が落ちる
午後イチから2時間、モブプロに時間を当てていたのですが、終わった後の疲労感がハンパない、個人タスクの時間が分断されてやりにくい、との意見から午前中にモブプロを実施するようにしました。


## モブプロの品質の担保について

「モブプログラミング・ベストプラクティス」では、モブプロを行ったソースレビューについて、

- 従来どおりのレビュープロセスと同じように扱う
- モブ用のIDを発行し、モブコミット分はレビューから省く

という対策案が挙げられています。
当チームは、モブプロを始めて導入したことから、品質を担保しているという証明が難しく、従来どおりレビューを行う対策を採用しています。
本書でもモブがレビューしているのに、なぜモブコードも従来のレビューをしなければいけないのか、と書かれており、、これからの品証の意識カイゼンに期待ですね。。

## 今後の課題

まだ解決策が見えていない課題もあり。

- 単純作業をモブプロでやるのはいかがなものか
訳あってJunitに書いた単体テストコードをExcelに転記する作業があるのですが、みんな無言でタイピストの打鍵音だけが響くという状況に陥っていました笑
全部が全部モブでやるのもツライという意見が。
ソースレビューもそうですが、モブプロ後はメンバーを割り当てての残処理が必要ですね。。

- より早いタイピストになるために
最近Eclipse上ではマウス禁止ルールを掲げました。意外となんとかなるものですね！まだまだぎこちないですがキーボードのみだと無駄な動きがなくなるのでマスターしたいところです。

- スケジュールが厳しい中のモブプロは可能か
今回は比較的スケジュールに余裕がある中でのモププロ導入でしたが、今後モブプロを忙しいチームにも展開するとなったときに果たして受け入れられるかなぁと。
やるやらないはチームの判断ですので、今回のように、やってよかった！って思ってもらえるように売り込んでいこうかと。

## 最後に

モブプロを始めてみて、やはり技術が共有できるというのがいいなと感じました。
フロントエンドに強い人、バックエンドに強い人、テストコードに強い人の様々な知識が共有できて日々得るものが大きいです。
なかでも、マウス禁止ルールは一人でやっているとなかなか踏み込めませんでしたが、モブプロだとモブが知っていることをフォローしてくれるので、慣れるスピードも早いと思います。

個人的には、テスト駆動開発(TDD)は「モブプログラミング・ベストプラクティス」でも取り入れていると書いてあり、信頼と実績ありの手法と再認識。
勉強しなければ。

では、ハッピーモビング！
年賀状をpythonを使って他己分析してみた

#開発の動機
毎年送りあう年賀状…
部屋の整理をしていたら、先輩や後輩からもらった年賀状がたくさん出てきた。
これを何か役立てないかと考えた。

そこで閃いたのが、他人から見た自分を年賀状を通じて可視化できるのではなかろうかと思いついた。
いわゆる他己分析が年賀状を通じてできるのではないだろうかと思った。

考えてみれば、自分が他の人に書くときは、去年のその人の印象やエピソードなんかを交えて書く。
これは他人も同じなのではないかと考えた。

年賀状を形態素解析して、自分に対する印象を抽出できるはず…
それをワードクラウドにして、自分の他人に対する印象を可視化しようと思った。


#作り方

##1 年賀状の文面の打ち込み(データ入力)

まず、分析するデータを集める必要があるので、年賀状の内容をエクセルにまとめる。

![messageImage_1585488373040.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/453622/d004b890-2d64-9e4a-eea4-1760f740db16.jpeg)

こんな感じで、あけおめ・ことよろ系のしょうもない挨拶は省いたもので入力した。
なるべく、自分の印象やエピソードに関連する文言のみを入力するようにした。

##2 データをまとめる

次に、入力したエクセルを一つのデータにまとめる

```python:
import xlrd

wb = xlrd.open_workbook('/nenga2020.xlsx')
sheet = wb.sheet_by_name('Sheet1')
col_values = sheet.col_values(0)
text=""
for i in col_values:
    text=text+i
print(text)
```

これで、textに年賀状の文面がすべて入っていることになる。

##3 形態素解析＆ワードクラウド作成
とうとうここから形態素解析＆ワードクラウドの作成をする。

```python

import MeCab
import wordcloud, codecs

m = MeCab.Tagger("")
text = text.replace('\r', '')
parsed = m.parse(text)

splitted = ' '.join(
    [x.split('\t')[0] for x in parsed.splitlines()[:-1] if x.split('\t')[1].split(',')[0]  in ["名詞","形容詞","形容動詞"] ])

wordc = wordcloud.WordCloud(font_path='HGRGM.TTC',
                            background_color='white',
                            contour_color='steelblue',
                            contour_width=2).generate(splitted)
wordc.to_file('nenga2020.png')
```

これで年賀状で書かれた印象について、解決できる。

```python:
splitted = ' '.join(
    [x.split('\t')[0] for x in parsed.splitlines()[:-1] if x.split('\t')[1].split(',')[0]  in ["名詞","形容詞","形容動詞"] ])

```

のところで、品詞を名詞,形容詞,形容動詞に絞っている。
これは自分の印象の抽出を目的にしているから。

#まとめ
コード全体

```python
import xlrd
import MeCab
import wordcloud, codecs


wb = xlrd.open_workbook('/nenga2020.xlsx')
sheet = wb.sheet_by_name('Sheet1')
col_values = sheet.col_values(0)
text=""
for i in col_values:
    text=text+i

m = MeCab.Tagger("")
text = text.replace('\r', '')
parsed = m.parse(text)

splitted = ' '.join(
    [x.split('\t')[0] for x in parsed.splitlines()[:-1] if x.split('\t')[1].split(',')[0]  in ["名詞","形容詞","形容動詞"] ])

wordc = wordcloud.WordCloud(font_path='HGRGM.TTC',
                            background_color='white',
                            contour_color='steelblue',
                            contour_width=2).generate(splitted)
wordc.to_file('nenga2020.png')
```

そして完成した他己分析のワードクラウドはこちら。
![nenga2020_qujita.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/453622/975dfda2-6808-edb0-2529-847796fc3e19.png)

剣道部関連から多くの年賀状をもらったので、関連ワードが多い…

面白いとか有能とか尊敬とかのワードが他人からの自分の印象であると考察される。
nginx + php-fpm で PHP だけ File not found. の時の対応

Amazon Linux 2 に nginx + php-fpm の構成を一から作った際に
nginx が php ファイルの時だけ `File not found.` と返してきて困ったので、
原因の調査方法をメモします。

尚、 nginx のエラーログに以下の出力がある前提です。

```
FastCGI sent in stderr: "Primary script unknown" while reading response header from upstream, ...
```

## 考えられる原因

`File not found.` が表示される場合は多分以下のどちらか。

- nginx の設定がおかしい。
    - `SCRIPT_FILENAME`, `fastcgi_pass` など
- php-fpm の設定がおかしい。
    - 実行ユーザなど

## 確認する事、調査方法

### nginx

document root 配下のディレクトリ、ファイルに対して nginx の読み込み権限がある前提。

- `index.html` を document root に置いてみて、対応するリクエストで意図した内容が返って来るかどうか。 `add_header` ディレクティブを加えると意図したレスポンスヘッダが返ってくるかどうか。
- ↑と同じディレクトリに `index.php` を置いて `File not found.` となるかどうか。
    - (↑php-fpm まで渡ってるけど php-fpm から指定の PHP ファイルが参照できていないという状態？)
- 拡張子 `.php` に対する `location` ディレクティブの設定を確認してみる。
    - `fastcgi_pass` で指定したパスで php-fpm は待ち受けているか？
    - `SCRIPT_FILENAME` の値は合っているか？
        - `root` の値が `/var/www/html/current/public` の場合、 `/var/www/html/current/public/index.php` が存在するかどうか。

### php-fpm

`/etc/php-fpm.d/*.conf` で `access.log` の指定がされている前提。

- アクセスログで、 nginx の document root 以降のファイルパス (`/index.php` など) がリクエストされている事を確認。 (nginx → php-fpm の疎通が意図通り出来ているかどうか)
- php-fpm の実行ユーザが意図した物になっているかどうか。 (php-fpm → PHP ファイルが出来ているかどうか)
    - `user`, `group`, または `listen.owner`, `listen.group` が nginx の実行ユーザ/グループになっているかどうか。
    - `ps aux | grep php-fpm` 等で実際に実行しているユーザを確認する。

---

今回の自分の場合は、 php-fpm の実行ユーザ/グループが `nginx` になっていなかった事が原因でした。
document root 配下を作成者または `nginx` グループしか読めないよう設定したのに対し
php-fpm 実行ユーザが `nginx` グループではなかったため、 php-fpm が PHP ファイルを読めなかったようです。

`/etc/php-fpm.d/` 配下に `www.conf` と `www-override.conf` を配置し、
`www-override.conf` で `user`, `group` を `nginx` と指定していましたが、実際には `www.conf` の内容 (`apache`) が採用されていました。
ファイルを跨いでの同一 pool に対する設定の上書きが出来ると思ってたけど違ったみたい :rolling_eyes: 
もしくは `www.conf` が後に読まれたかな？
Node-REDでping

# Node-REDでpingしたい

とある理由でNode-REDでpingしたくなったが、ちょっとハマったので投稿。

環境: Raspberry Pi 4 Model B (OS: Raspbian Buster)

# 結論

[node-red-contrib-advanced-ping](https://flows.nodered.org/node/node-red-contrib-advanced-ping) か [node-red-configurable-ping](https://flows.nodered.org/node/node-red-configurable-ping) が使いやすい。

# Node-REDのpingノードいろいろ

pingで検索したら複数ノードが見つかったので、いろいろ試した。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70022/44542a9b-7aa9-47ee-0015-4d2669265093.png)

## [node-red-node-ping](https://flows.nodered.org/node/node-red-node-ping)

名前が一番シンプルだったのでこれが定番かなと思った。
しかしノードを並べてみると…

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70022/09fa9453-7073-b695-5bd8-ee90f7f47094.png)

入力がないため、固定のアドレスにしかpingできない。また、任意のタイミングでpingできない。ちょっと使いずらい。

## [node-red-contrib-net-ping](https://flows.nodered.org/node/node-red-contrib-net-ping)

これなら入力があるため、任意のタイミングでpingできそう。また、msg.hostにアドレスを入れると宛先を可変にできる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70022/efcee92a-ac7c-8bd0-fae1-79d37f16c300.png)

しかし実行してみたところ、

```
"Error: Operation not permitted"
```

と表示されて実行できなかった。

公式サイトには、Node-REDをroot権限で実行してくださいとあった。ちょっと危ない。

## [node-red-contrib-tcp-ping](https://flows.nodered.org/node/node-red-contrib-tcp-ping)

これならTCPを使っているので、root権限は必要なさそうな予感。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70022/02dfd459-045a-f7bd-44a1-6ce9dbb01cd6.png)

しかし、pingはICMPなのでTCPを使うというのは違った模様。TCPの宛先ポートを指定するが、必ず開いているポートなど保障できない。公式サイトに何も説明がないのでこれ以上わからなかった。

## [node-red-contrib-advanced-ping](https://flows.nodered.org/node/node-red-contrib-advanced-ping)

最終的にこれに行き着いた。msg.hostに宛先を指定すれば可変にできるし、任意のタイミングでpingができる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70022/9b2ce70f-e8f7-b341-04d1-067d2575a61e.png)

## [node-red-configurable-ping](https://flows.nodered.org/node/node-red-configurable-ping)

node-red-contrib-advanced-ping からの派生で、タイムアウト時間やリトライ回数を可変にできる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70022/bc8135b0-c515-f651-ce9f-5ddbd63988b6.png)

これらを変更したい場合はこっちを選択。
GitHub Workflow の実行順や制御を試してみる

GitHub Workflow を色々扱ってみているのでそのまとめを残しておきます。時々更新するかもです
Actions も初めてやってるので両方の内容が混ざってます

コード: https://github.com/kakkunpakkun/workflow-test

## step は順に、 job は並行
step は順番に実行されますが、job は並行して実行されます。
なので、以下の様な場合に job_A が終わる前に job_B が開始されます。

```yaml
on: push

jobs:
  job_A:
    name: job A
    runs-on: ubuntu-latest
    steps:
      - name: job A step 1
        run: |
          echo "job A step 1"

      - name: job A step 2
        run: |
          echo "job A step 2"

  job_B:
    name: job B
    runs-on: ubuntu-latest
    steps:
      - name: job B step 1
        run: |
          echo "job B step 1"
```

## job の順番は needs で制御する
needs を設定することで job の順番を指定することが出来ます。
例えば `needs: job_A` としておけば job_A が成功するまで待って、job_A が成功しないと実行されない。

あと、job 内では同じファイルを同じマシン上のものとして扱えるけど、job が違うと別の仮想マシンとなっているみたいで共有は artifact などを使うことになります。
artifact はまだ試していないので分かりません

```yaml
on: push

jobs:
  job_A:
    name: job A
    runs-on: ubuntu-latest
    steps:
      - name: job A step 1
        run: |
          echo "job A step 1"

      - name: job A step 2
        run: |
          echo "job A step 2"

  job_B:
    name: job B
    runs-on: ubuntu-latest
    steps:
      - name: job B step 1
        run: |
          echo "job B step 1"
          echo "job B" >> job_b.txt
          cat job_b.txt

  job_C:
    name: job C
    needs: job_A
    runs-on: ubuntu-latest
    steps:
      - name: job C step 1
        run: |
          echo "job C step 1"
          cat job_b.txt #ここでファイルがなくて fail する

```
実行結果:
<img width="904" alt="スクリーンショット 2020-03-28 21.59.53.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8772/aa89f252-0333-732f-e069-3be1239523c6.png">

needs は便利かもしれないけどあんまり多いと読みにくくなりそうだし、制御のしやすさを考えると別の Workflow を作った方が良いかもしれないです


## failure() や always()
job の途中で失敗した時、以降の step は実行されませんが、 `if: failure()` となっている step は実行されます。
`if: always()` もあるので後処理をしたい時に便利かもしれないです。
が、job としては失敗の状態になるのであまり `if: failure()` に頼らずに job が成功するように作ったほうが良さそう

```yaml
# ...省略...

jobs:
  job_A:
    name: job A
    runs-on: ubuntu-latest
    steps:
      - name: job A step 1
        run: |
          echo "job A step 1"

      - name: job A step 2
        run: |
          echo "job A step 2"
          false

      - name: job A step 3
        if: failure()
        run: |
          echo "job A step 3"

      - name: job A step 4
        run: |
          echo "job A step 4"

      - name: job A step 5
        if: always()
        run: |
          echo "job A step 5"

# ...省略...

  job_C:
    name: job C
    needs: job_A
    runs-on: ubuntu-latest
    steps:
      - name: job C step 1
        run: |
          echo "job C step 1"

```

実行結果:
<img width="796" alt="スクリーンショット 2020-03-29 22.11.25.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8772/f6f076eb-c364-5dd0-f8b3-d5978e2db80b.png">

job A が失敗したので job C が実行されずに実行結果に現れません。
step は実行されなかった場合も表示されるのですが job も Workflow も実行されなかったら表示されないです。
Prorate Python編（１）

今日ProgateのPhthon のⅠ〜Ⅲまでをやりました。
感想としては、ｃ++に形は結構似て入るものの、やはり別物であるから少しなれが必要かなと感じました。まだ終わってないのでなんとも言えませんが、明日に残りを終わらせたいと思います。
[2022年版] VSCode+docker-compose+php8.1.4 (xdebug 3.1.4)の環境構築のポイント

# はじめに
ありふれた記事なのではあるが一発では起動できない。。
なので基本的なところは他の記事に譲るとして、必ずデバッグする為のポイントを上げてみた。

使用するdockerイメージ
```dockerfile
FROM php:8.1-apache
```

## 1. VSCodeにPHPDebugのインストールとlaunch.jsonの設定
`RUN and Debug`を起動してlaunch.jsonを適当に作る。

```json:launch.json
{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "XDebug on docker",
            "type": "php",
            "request": "launch",
            "port": 9005,
            "pathMappings": {
                "/var/www/html/": "${workspaceRoot}/src/"
            }
        }
    ]
}
```

## 2. サーバ側にxdebugをインストール
Dockerfileでxdebugをインストールする。
```dockerfile:dockerfile
# xdebug
RUN pecl install xdebug && docker-php-ext-enable xdebug
```
上記を１行追記する。
後ろの
`docker-php-ext-enable xdebug`
で、docker上に
`/usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini`が作られる。中身は
```ini:docker-php-ext-xdebug.ini
zend_extension=xdebug
```
だけだがそのままでOK


そしてxdebug.iniを用意する。

```ini:xdebug.ini
[xdebug]
xdebug.mode=debug
# IP address or host.docker.internal
xdebug.client_host=host.docker.internal
xdebug.start_with_request=yes
xdebug.discover_client_host=0
xdebug.remote_handler="dbgp"
xdebug.client_port=9005
```
ここのclient_portとlaunch.jsonのportをあわせる。
client_hostは環境によってローカルのIPアドレスを記述する必要があるので適宜設定する。

xdebug.iniのコピー先に注意。
docker上の
`/usr/local/etc/php/conf.d`の中に置いてあげる。

```yaml:docker-compose.yaml
    volumes:
      - './src:/var/www/html'
      - ./docker/php-apache/php/xdebug.ini:/usr/local/etc/php/conf.d/xdebug.ini
```


## 3. VSCodeのdebugを起動
あとは、ブレークポイントを設定してアクセスして確認する


## 4. はまりポイント
- xdebug.iniのコピーの位置
- xdebug.client_hostの設定内容。vagrant等の仮想環境を使っている場合はそのIPを指定する。

## 終わりに
記事が古かったので更新。最新のphp8.1.4とxdebug3.1.4に対応した。
MySQLからcsvを出力する

## 環境
mysql : Ver 8.0.19 for Linux on x86_64 (MySQL Community Server - GPL)


## SELECT文でcsvファイルを出力する
```
SELECT * FROM hoge INTO OUTFILE '/output/hoge.csv'
 FIELDS TERMINATED BY ','
 OPTIONALLY ENCLOSED BY '"'
```
dockerでMYSQLコンテナ立ち上げている場合、`OUTFILE`をマウント位置にすると良い


## csvファイルを出力する際にエラーを吐いた場合

```
ERROR 1290 (HY000): The MySQL server is running with the --secure-file-priv option so it cannot execute this statement
```
データの入出力エラー

### MySQLの設定を確認
```
mysql> SELECT @@global.secure_file_priv;

+---------------------------+
| @@global.secure_file_priv |
+---------------------------+
| NULL                      |
+---------------------------+
```
このNULLがダメらしい

### 設定を変更して解決する
[DockerでMySQLコンテナを立ち上げて.sqlファイルからDBを作る](https://qiita.com/sasadango/items/fd5abcb886a329f4ab2a)
立ち上げているコンテナは上の通りなので、`my.cnf`に以下を追記

```
[mysqld]
secure-file-priv = ""
```

コンテナ再起動で設定を反映させてると設定欄のNULLが消える

```
mysql> SELECT @@global.secure_file_priv;

+---------------------------+
| @@global.secure_file_priv |
+---------------------------+
|                           |
+---------------------------+
```
これでSELECT文でcsvファイルが吐き出せるようになっているはず



## 参考資料
[MySQLのバージョン確認方法](https://qiita.com/haxpig/items/b270acb9550efddd5fe5)
[MySQLのSELECT文でcsvを出力する](https://qiita.com/catatsuy/items/9fdf4423d5f4885b9bf9)
[MySQLでCSV出力しようとしたら --secure-file-priv option のエラーになった](https://qiita.com/kiyodori/items/7281a5bdcfbcbbe03c68)
[MySQLでCSVファイルを使って結果出力やデータ入力を行う方法](https://proengineer.internous.co.jp/content/columnfeature/6776)
DockerToolboxでOracle環境構築ではまったことメモ

## 容量足りないエラー

イメージ作成時に容量エラーとなる。
VMの仮想ディスクサイズを変更する。
とりあえず40GBくらいにしておきたい。

vmdkだと拡張できないのでvdiに複製してから拡張する。
複製＆拡張はグローバルメニューから実施。

拡張後にvmdkに戻してアタッチするもVMが起動しないので、
拡張後のvdiのままでアタッチしてみたら起動した。

##　共有フォルダのマウントがうまくいかない

[問題]
データ領域に共有フォルダをマウントしたいのだが何度やっても
下記のようにうまくいかない。

```
[oracle@2f26fe3ef960 ~]$ df -h
Filesystem      Size  Used Avail Use% Mounted on
overlay          37G  6.2G   29G  18% /
tmpfs            64M     0   64M   0% /dev
tmpfs           999M     0  999M   0% /sys/fs/cgroup
shm             4.0G     0  4.0G   0% /dev/shm
/dev/sda1        37G  6.2G   29G  18% /etc/hosts
tmpfs           1.8G  284M  1.5G  16% /opt/oracle/oradata
tmpfs           999M     0  999M   0% /proc/asound
tmpfs           999M     0  999M   0% /proc/acpi
tmpfs           999M     0  999M   0% /proc/scsi
tmpfs           999M     0  999M   0% /sys/firmware
```
[原因]
VM側のVirtualBoxの共有フォルダ設定ミス。
というかインストール後の初期設定で入るフォルダパスに"？"とか入っているのが問題。
変更後、default側で認識していることを確認すること。

[DockerコンテナにOracle Database 19c をインストールして、Windows 側から接続](https://ts0818.hatenablog.com/entry/2019/11/17/205437)
[Dockerでファイル共有をするための、VirtualBoxの設定](https://qiita.com/toomuchpopcorn/items/9c5501dd9e500ae5aaed)
ゼロコスト抽象化とは何なのか？

# 記事のターゲット

* Rustを学ぼうと思っている人（俺）
* [公式ドキュメント](https://doc.rust-jp.rs/the-rust-programming-language-ja/1.6/book/)でいきなり出てきた「ゼロコスト抽象化」が何なのか気になっている人（僕）
* つまり他言語に比べてRustが勝っている点を一つでも自分の言葉で説明したい人（私）

# ゼロコスト抽象化

Rustの公式ドキュメントに出てくるあまり一般的ではない単語です 
文字通り **コスト**が**ない(ゼロ)**としている**抽象化**のことです

## プログラミング的抽象化

現代でよく扱われる高級言語には抽象化の概念が実装されている事が多く、デザインパターンの殆どがこの抽象化をベースにしている内容が多数見られます
処理系・属性値などをブラックボックス化して、使用タイミングで具体化した動きに変えるような書きぶりです
その名の通り、**ゆるふわで定義**しておいてその**定義に合わせた実装を用意**する内容です

## この文脈の「コスト」とは？

**抽象化に対する追加のコスト** と考えて良いでしょう
ここで「え？抽象化のコストってなんぞや？」と思われるかも知れません

主に抽象化に対するコストは **メモリの動的利用** （動的ディスパッチ）です
golangでも関数の引数に*interface*を指定した場合はメモリアロケーション、つまりは動的なメモリ割り当てが発生します
golangも型付き言語なので事前にメモリ確保領域は確定できそうですが、*interface*を指定すると「どれくらいメモリ確保したらええねん？」ってなるので動的にメモリ確保するしかなくなるわけですね

※ 正直、パフォーマンスがシビアに求められるようなシステムでない限りは意識する領域では有りません

コストが肥大化すると大規模な処理系でCPU使用率がGCの影響でスパイクしたり、メモリ使用量が瀑増するなどの影響があります
参考：[実装言語を「Go」から「Rust」に変更、ゲーマー向けチャットアプリ「Discord」の課題とは](https://www.atmarkit.co.jp/ait/articles/2002/10/news038.html)

よくわからないという人は以下を踏まえてコストを理解すると良いと思います

### メモリが使われていないことを検知する

少なからず検知のためのリソースを用意する必要があります
コストですね

### 使われていないメモリ領域を解放する

同じく確保していたメモリ空間を誰かが「使っていいよ！」と解放させる必要があります
コストですね

## ゼロコスト？

「抽象化すればコスト無いんじゃん？！ヒャフー！」なんて思わないでください
あくまでも **抽象化に対する追加のコスト** がゼロなので「抽象化してもしなくてもコストが変わらないよ」というニュアンスです

# Rustはなぜゼロコストなのか？

言うならば抽象化を動的ディスパッチではなく **デフォルトで静的ディスパッチ**により実現するためです
静的ディスパッチでは抽象化したコードをコンパイル時に単相化、つまり **それぞれの型の分だけコードを生成** します
人間がint用の関数・bool用の関数…と言った横展開をしているのと変わりがない状態です

コレならば型が明確なのでメモリの確保も動的に行う必要がありません！
なので **抽象化に対する追加のコスト** がゼロなのです

# まとめ

* Rustはゼロコスト抽象化である
* このコストは抽象化に対する追加のコストである
* ゼロコストの理由は静的ディスパッチを利用しているからである

# 参考

[Goのインタフェースがパフォーマンスに及ぼす影響](http://inforno.net/articles/2015/12/11/go-interface-performance-penalty)
[ゼロコスト抽象化とは一体何なのか](https://rustforbeginners.hatenablog.com/entry/zero-cost-abstraction)
[Rustのゼロコスト抽象化の効果をアセンブラで確認](https://blog.rust-jp.rs/tatsuya6502/posts/2019-12-zero-cost-abstraction/)
PHP ＋ MYSQL 入門ノートでの学び_3/30


##スーパーグローバル変数
関数レベルのローカルスコープとグローバルスコープを持つ変数。

###使用例
関数の中からグローバルスコープを呼び出す際に、関数内で'global $変数名'のように明示的に呼び出さなくいて済む。

$GLOBALS['変数名'] = '...'のように宣言する。
スーパーグローバル変数は値を辞書型で保存している。

##static変数

staticを明示する場合

```sample.php
function CountUp(){

 static $count = 0
 $count += 1
 reuturn $count

}

for($i=0;$i<3;$i++){
 $num = CountUp();
 echo $num.'回目|';
}

```

```結果.

1回目|2回目

```

staticを明示しない場合

```sample.php
function CountUp(){

 $count = 0
 $count += 1
 reuturn $count

}

for($i=0;$i<3;$i++){
 $num = CountUp();
 echo $num.'回目|';
}

```

```結果.

0回目|0回目

```

##変数の参照渡し, 値渡し


値渡し

```sample.php

function oneUp($var) {
 
 $var += 1;
 

}

$num = 5;
oneUp($num);
echo $num;

```


```結果.
5
```

参照渡し

```sample.php

function oneUp(&$var) {
 
 $var += 1;
 

}

$num = 5;
oneUp($num);
echo $num

```


```結果.
6
```
nokogiri関連でエラーが出ちゃった人は、、、


#エラー

①
An error occurred while installing nokogiri (1.6.7.rc4), and Bundler cannot continue.
Make sure that `gem install nokogiri -v '1.6.7.rc4'` succeeds before bundling.

②
Library not loaded: /usr/local/opt/openssl/lib/libssl.1.0.0.dylib (LoadError)

#対処法

色々やったけど無理でした。

最終的にrubyをインストールしなおしました
PythonのTinkerを使ってお絵かき

# 完成イメージ
<img width="616" alt="スクリーンショット 2020-03-29 午後10.19.21.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/216701/a3118e95-ec50-6482-a388-5a73eaaa88f8.png">

# コード

```sample.py
import tkinter as tk

# 黒（black）の点を描画（数字を大きくすると、大きな点になります。）
def myMotion(mouse):
    cv.create_oval(mouse.x - 1, mouse.y - 1, mouse.x + 1, mouse.y + 1, fill = "black")
    
win = tk.Tk()
cv = tk.Canvas(win, width = 600, height = 400)
cv.create_rectangle(0, 0, 600, 400, fill = "white")
cv.pack()

win.bind("<B1-Motion>", myMotion)

win.mainloop()
```

## 解説
クリックを押している間だけマウスの位置に点(小さい円)を描画しています。
【UE4】マテリアルをブループリントで動的に切り替える方法【UnrealEngine】

モンスターやアイテム等使用するモデルは同じで色だけ切り替えたい時ってありますよね。
今回はブループリントでマテリアルを切り替える機能を紹介します。

実装手順
-------------------------------

![マテリアル複製.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/497331/cbfce836-ba9c-b304-045d-6a5190c958d1.png)
まず変更するマテリアルを用意します。

#####↓マテリアルを切り替えるブループリント内で SetMaterial を呼びMaterialの項目に変更したいマテリアルを入れる
![SetMaterial.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/497331/7f496720-3ea7-5d1c-356b-cc4a1f304e99.gif)

###実装手順終了

応用
----------------------------
![イルミBP.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/497331/364f0426-0fef-2ba0-6002-8b4c8730fc7d.gif)
![イルミ.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/497331/7c68b618-b404-ce2e-f34d-b12ae5e1c15c.gif)

SetMaterialを使えば簡単にイルミネーションっぽい物も作れました。
qiitaの記事をgithubに移しました（劣化版）

backupの観点から、今までのqiitaの記事をとりあえずgithubに移しました。
https://github.com/JunNakamura/til

下記のシェルを出していた記事があったのですが、もう退会されたかもしれません。。。
このシェルで、これまでの記事をmarkdownとして取得します。

```bash
curl -s "https://qiita.com/api/v2//users/${user_id}/items?per_page=100" \
  | jq -r ".[].url" \
  | xargs -n1 -I{} bash -c "curl -s  {}.md > \$(echo {} | awk -F / '{print \$NF}').md"
```


単純にそれを、そのままgithubにあげました。
なので、markdownのファイル名はハッシュっぽいになっています。
githubにはリポジトリ内の検索機能があるので、タイトルかタグとかでなんとか拾えるかなと。

もっといい感じにしたい方はこちらを参考にすると良さそうです。
https://qiita.com/mima_ita/items/ec33706c20f11a95516a


自分がこれまでqiitaを使っていた理由としては、

1. 日々の業務などで得た知識のメモ
2. 得た知識を記事の形で整理
3. 同じ悩みを持っている人に解決策の共有

が主です。今後も使い続けますが、自分の得た知識の蓄積がqiitaだけになっている（自分の中にはあるものの）のは、ここ最近の流れで少し不安になりました。

緩和策として、とりあえずgithubにつっこむことにしました。
Rails をアンインストールする時にエラーが出た場合の対処方法


# エラー発生

$ gem uninstall railties -v '6.0.2.2'

を実行するとこんなエラーが

ERROR:  While executing gem ... (Errno::ENOTEMPTY)
    Directory not empty @ dir_s_rmdir - /Users/ユーザ名/.rbenv/versions/2.6.3/lib/ruby/gems/2.6.0/gems/rails-6.0.2.2


原因はインストールの際に管理者権限で作成していたから

# 解決方法

$ sudo gem uninstall railties -v '6.0.2.2'

これだけでした。
[Rails]DM機能に送信日時を日本時間で表示させる

#本記事投稿のいきさつ
現在作成中のアプリでメッセージ機能を作成しました。
その中で日本時間で送信日時を表示させる際に、初めて知った内容があったため備忘録として書きたいと思います。
内容自体はとても簡単なものとなっています。
今回は以下のアプリで実装していきます。
![スクリーンショット 2020-03-29 21.43.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562008/9c0ea834-5735-a484-392c-a4c10775e8d2.png)

##ビューに追記
メッセージを表示させるビューに以下を追記

````message.html.haml
= message.created_at
````

しかし、これだけでは以下の表示となってしまいます。
![スクリーンショット 2020-03-29 21.49.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562008/c0c03fd6-6e97-8093-b1d3-5aa9815efa43.png)

とても見づらい表示となってしまうため、先ほどのコードに追記をし、表示の方法を指定します

````message.html.haml
= message.created_at.strftime("%Y年%m月%d日 %H時%M分")
````
すると、こんな感じに。
![スクリーンショット 2020-03-29 21.50.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562008/71c07752-0dbe-9d94-1848-930b55ec4ed1.png)

##日本時間の設定
ここが自分が知らなかった点なのですが、Railsのアプリケーションの時間基準は、デフォルトでは協定時(UTC)となっています。
そのため、日本時間で表示をするためには、config/application.rbを以下のように編集する必要があります。

````config/application.rb
class Application < Rails::Application
#以下を追記
  config.time_zone = 'Asia/Tokyo'
````


#終わり
これでメッセージアプリに日本時間での表示ができるようになりました。
最後まで見ていただきありがとうございました。
【Ruby on Rails】ストロングパラメータについてbinding.pryで理解を深める　



##この記事の目的
先日tech::campとういうプログラミングスクールを卒業しました
この学習を無駄にしないように理解が浅いところを復習する為に書きます
createアクションにストロングパラメータを設定せず、Post.create(params)とだけ書いて値の保存を試みたら、エラーが出たことがこの記事を書くきっかけです。


##1.ストロングパラメータについて
「Web上から入力されてきた値を制限することで、不正なパラメータを防ぐ仕組み」です。セキュリティ上の問題に対処するための仕組みとしてRails4系から導入されました。
参考　https://kirohi.com/strong_parameters_rails

##2.ストロングパラメータを設定する理由
簡潔にいうと管理者情報を乗っ取られないようにする為です。
本来ユーザーから送られてくることのないパラメータが存在していたとしても、それを取り除いて安全にDBの更新を行うことができます。
悪意のあるユーザーが管理者権限付きのユーザーを取得する為にパラメータを改竄しても、許可されたパラメーターだけに絞り込むことができます。
データの登録・更新機能に設定することが多いのもこの理由からです。
以下のquitaの記事が理解しやすいです。
参考　https://qiita.com/ozackiee/items/f100fd51f4839b3fdca8

privateメソッド以下に定義することが多い理由は、クラス内部からしか使わないので、クラス外部で呼び出されるとエラーが起きるようなメソッドが使われるのを防いで、さらにコードの可読性が上げる為です。




##4.ストロングパラメータを設定してbinding.pryで見てみる

まずはストロングパラメータの設定

```ruby:post_controller.rb
def create
  Post.create(post_params)
end

private
def post_params
  params.require(:post).permit(:name, :image, :text)
end
```


投稿フォームで値を入力してbinding.pryでデバックしてみましょう。

<img width="575" alt="ターミナル.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/594126/f863143f-4cd6-ff75-13aa-f4fd6e4ee2a4.png">

[1]はparamsの中身をみています。permitted: falseと出ていますね。
値の取得に失敗しています。
でも、これでいいんです。
なぜfalseかというとストロングパラメータを設定しているからです。
ストロングパラメーター内に書いたpermitメソッドで指定したparamsしか保存しません。


続いて[2]でpost_paramsの中身をみています。
これはストロングパラメーター内に書いたpermitメソッドの返り値です。
こちらはpermitted: trueとなっています。

このようにbinding.pryでデバックすると入力されてきた値をちゃんと制限できていることがわかります。



##まとめ
ストロングパラメータについて備忘録として書いてみました。
間違った記述があればご指摘お願いします。
Dockerコンテナ内部からホストにアクセスする方法

# いつ使うのか？

Dockerコンテナを開発環境として、コンテナのホストOSで動いているサービスと通信したいときに、コンテナ内部からホストにアクセスするためのIPアドレスを調べる。

以下は、下記のDockerfileからビルドしたコンテナを具体例として説明する。

    FROM ruby:2.6
    
    RUN ln -fs /usr/share/zoneinfo/Asia/Tokyo /etc/localtime
    
    RUN apt-get update -qq && \
        apt-get install -y vim

    docker build --tag example-ruby-dev .

# 方法

## OS X/Winの場合

[公式のドキュメント](https://docs.docker.com/docker-for-mac/networking/#i-want-to-connect-from-a-container-to-a-service-on-the-host)によって、DockerのバージョンがCEの18.03以上の場合、"host.docker.internal"といったDNS名でデフォルトで設定されて。そうすると、下記のコマンドを使って、コンテナを立ち上げた上で、"Ping -a host.docker.internal"などの方法で、ホストのIPアドレスを調べる。

    docker container run -it example-ruby-dev /bin/bash

## Linuxの場合

Linux版のDockerでは、上述のようなデフォルト設定がまだないので、上記のコマンドを使って、コンテナを立ち上げた上で、以下のコマンドで、ホストのIPアドレスを調べる。

    ip route show default | awk '/default/ {print $3}'

# 後書

ホストにアクセスするIPアドレスをDockerから発行することではなく、最初から特定な値で指定したい場合、@ijufumiさんの[記事](https://qiita.com/ijufumi/items/badde64d530e6bade382)で述べた設定方法を参考してください。
【python】時系列データをプロット

時系列データを解析するとき、目的変数がどのように変化しているかを
時系列で確認するために、グラフとして可視化します。

手順
**①日付カラムをインデックス化**
　`df.set_index('Date')`
**②プロット**
　`df.plot()`
　`plt.xticks(rotation=70) `
**③後の処理のために元に戻す**
　`df = df.reset_index()` 


```Python:date.py
import pandas as pd
import matplotlib.pyplot as plt

df = pd.read_csv('dataset.csv')
df.head()

""" 出力
	patient	Last UpDdated	
0	5.0	    2020-03-22 10:00:00
1	4.0	    2020-03-22 11:00:00
2	6.0	    2020-03-22 12:00:00
3	10.0	2020-03-23 10:00:00	
4	3.0	    2020-03-23 11:00:00
"""

# 日付をインデックスにする
df = df.set_index('Last UpDdated')
df.head(3)

"""出力

Last UpDdated　　　　　patient	
2020-03-22 10:00:00	　5.0
2020-03-22 11:00:00	　4.0
2020-03-22 12:00:00	　6.0
"""

# プロット
df.plot()
# X軸のラベルの角度をかえる
plt.xticks(rotation=70)
```
![ダウンロード (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/610435/d249a964-a302-b4d6-3fe8-23c6bc410d07.png)

```Python:date.py
# 後の処理のためインデックスを戻しておく
df = df.reset_index()
df.head(3)

"""出力
    Last UpDdated	    patient
0	2020-03-22 10:00:00	5.0
1	2020-03-22 11:00:00	4.0
2	2020-03-22 12:00:00	6.0
"""
```
Pythonでのファイル・フォルダパス操作

#Pythonでのファイル・フォルダパス操作

メイン環境のversionが2.7なので、ver3.0以降では情報が異なる可能性があります。
ご容赦ください。

##＜os.path.exists＞ フォルダやファイルの存在を調べる
###フォルダが存在するかどうか

```py
import os
folderpath = ("C:\\test_folder\\test1")
print(os.path.exists(folderpath))
# True
```

os.path.existsを利用する事で指定したフォルダが存在しているかどうかを調べる事が出来ます。
結果はboolで返ります。

**フォルダパスを指定する際にはエスケープシーケンス`\`に注意が必要です。**
r を付けて`r"C:\Users\xxx\desktop\xxx"`と表記するか、
もしくは`\`を文字列として認識させるために`\\`を用いて、`"C:\\Users\\xxx\\desktop\\xxx"`と記述する方法があります。

###ファイルが存在するかどうか

```py
import os
filepath = ("C:\\test_folder\\test1\\sample.txt") 
print(os.path.exists(filepath))
# True
```
直接ファイル名を指定すれば、ファイルの有無を調べる事が出来ます。

##＜os.path.isfile＞ファイルが存在する事を判定
```py
import os
filepath = ("C:\\test_folder\\test1\\sample") 
print(os.path.isfile(filepath))

# True
```
指定のファイルが存在する場合Trueが返ります。
フォルダだった場合や、ファイルが存在しない場合は、Falseが返ります。

##＜os.path.isdir＞フォルダが存在する事を判定
```py
import os
filepath = ("C:\\test_folder\\test1") 
print(os.path.isdir(filepath))

# True
```
指定のフォルダが存在する場合Trueが返ります。
ファイルだった場合や、存在しない場合はFalseが返ります。

##＜os.listdir＞フォルダの中のファイルの詳細を調べる
```py
import os
folderpath = ("C:\\test_folder\\test1")
print(os.listdir(folderpath))

#['test2''test1.bmp','test1.txt']
```
指定のフォルダに存在するファイル、フォルダがリストに格納されます。
サブフォルダ内のデータは表示されません。

##＜os.walk＞サブフォルダの中身まで調べる
```py
import os

filepath = ("C:\\test_folder\\test1")  
for i in os.walk(filepath):
    print(i)

#('C:\\test_folder\\test1', ['test2'], ['test1-A.txt', 'test1-B.txt'])
#('C:\\test_folder\\test1\\test2', [], ['test2-A.txt', 'test2-B.txt'])
```
タプルが作成されます。
（フォルダパス、サブフォルダ名、ファイル名）の三要素で構成されています。
出力情報は適当。

###例）ファイル名だけを抽出する
```py
import os

filepath = ("C:\\test_folder")  
for folder,subfolder,filename in os.walk(filepath):
    print(filename)

#['test1-A.txt', 'test1-B.txt']
#['test2-A.txt', 'test2-B.txt']
```
folder,subfolder,filenameの三要素でfor文を回し、filenameのみをprintしています。
実際の利用時にはデータの加工が必要ですね。


##まとめ
2.7と3.0で大きな違いはなさそう。

##参考にしたページ
https://tonari-it.com/python-os-walk/
OPTIONSにAccess-Control-Allow-Originが付けれない環境でのPOST送信時のCROS対処法

# はじめに
別ドメインのサーバにブラウザ上からPOSTを送りたい場合に、特定の条件を満たしていないと必ずpreflightとしてOPTIONSを送信を行い、確認がとれた後にPOSTを送信します。
最近使えるようになったAWSのAPI GatewayのHTTP APIでは、CROS設定を行っていてもOPTIONSにはAccess-Control-Allow-Originはつきません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58795/6791735c-b94d-e854-bc09-91120f64616c.png)
そのため、ブラウザ側でPOSTを送信するまえにOPTIONSでCROS設定がされていないと拒否されてPOST送信にまでいきません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58795/2907a716-70b2-2313-dd33-f124e12a92f5.png)

既存のAPI GatewayのREST APIで設定するかLambdaなどから強制的にヘッダーをつけたりすれば問題なく送信することはできるようにはなりますが、HTTP APIでなんとかしたい！！となるとうまくいきません。
※ AWSのAPI GatewayのHTTP APIではLambdaからHeaderをつけるような書き方をしても、他のものはつくもののAccess-Control-Allow-OriginなどのCROS関係のヘッダーはつけても削除されてしまいました。悲しい。

# 解決方法
ざっくりのピックアップですが、以下の条件の場合にはpreflightが飛ばないという仕様になっています。
細かい情報は下部の参考をみてください。

- HTTPリクエストメソッド
    - GET, POST, HEAD。
- HTTPリクエストヘッダ
    - Content-Type
        - application/x-www-form-urlencoded
        - multipart/form-data
        - text/plain

そのためPOSTの Content-Type が **application/json** となってる場合には、上記のようにpreflightであるOPTIONSが飛びCROS設定がされていないためブラウザが拒否します。

なので、ajaxで送信時に~~心で何かが叫んでますが~~ Content-Type を **text/plain** とすればOPTIONSは飛ばす、すぐにPOST送信が行われるためHTTP APIのCROSの設定通りの挙動で送信が成功します。
同様にJavascriptのfatch apiを使ってjpegなどを送信する場合には~~より心で何かが叫んでますが~~multipart/form-dataなどと~~Content-Typeを偽って~~送信することで、開発環境からもクラウドに向けて送信することができます。

# 参考
https://fetch.spec.whatwg.org/#cors-preflight-fetch
https://qiita.com/tomoyukilabs/items/81698edd5812ff6acb34
「autorest」および「go-autorest」とは？

「[Azure SDK for Go documentation](https://docs.microsoft.com/ja-jp/azure/developer/go/)」サイトの「[Install the Azure SDK for Go](https://docs.microsoft.com/ja-jp/azure/developer/go/azure-sdk-install)」ページを読み進めています。

「[Include the Azure SDK for Go in your project](https://docs.microsoft.com/ja-jp/azure/developer/go/azure-sdk-install#include-the-azure-sdk-for-go-in-your-project)」セクションにて、GoでAzure サービスを使うには [Azure/azure-sdk-for-go](https://github.com/Azure/azure-sdk-for-go) とは別に [Azure/go-autorest](https://github.com/Azure/go-autorest) もインポートする必要があるとの記述がありましたので、autorestについて少し調べてみました。

ちなみに Azure/go-autorest は Azure/azure-sdk-for-go をgo getした時に一緒にダウンロードされます。

- go get -u -d github.com/Azure/azure-sdk-for-go/...

**AzureのREST API**

AzureにはREST APIが用意されており、各プログラミング言語はAzure SDKで用意されているHTTPクライアントを通じてこのAPIにアクセスし、Azureとの連携を図ります。

AzureのREST API 仕様はOpen API 仕様 形式で書かれており、また、公開されています。

- [Azure REST API Reference](https://docs.microsoft.com/ja-jp/rest/api/azure/)
- [Azure/azure-rest-api-specs](https://github.com/Azure/azure-rest-api-specs)

Azure SDKで用意されているHTTPクライアントは、この仕様書をautorestに読み込ませて自動作成されています。

**[Azure/autorest](https://github.com/Azure/autorest)**

autorestは、Microsoft社が開発している汎用（Azure専用ではない）オープンソースのツールで、Open API 仕様 形式を読み込んでRESTful Webサービスにアクセスするクライアント ライブラリーを生成します。

OpenAPI 3.0をサポートしており、PowerShall、C#、Python、Java、TypeScript、Ruby、そしてGoのHTTPクライアント ライブラリーを生成できます。

**[Azure/go-autorest](https://github.com/Azure/go-autorest)**

go-autorestは、autorestで作成されたAzure SDK for Goのクライアント ライブラリーに対して、ゴルーチンを使ってHTTPリクエストを並列処理できる機能を追加するパッケージで、

- Azure Active Directory 認証 ライブラリー (autorest/adal)
- 日付型を正確にパースするパッケージ (autorest/date)
- 型アサーション(autorest/to)
- モック (autorest/mock)
- バリデーション (autorest/validation)
- ロガー (logger)

なども含まれています。

**例：autorest/adal（[Active Directory Authentication Library](https://docs.microsoft.com/ja-jp/azure/active-directory/azuread-dev/active-directory-authentication-libraries)）**

クライアント サービスでは、毎回ログイン画面からログインするのはわずらわしいため、リソースを操作するためのアプケーション IDである「サービス プリンシパル」を作成してアクセスします。

- 参考スライド：[3分でわかるAzureでのService Principal](https://www.slideshare.net/ToruMakabe/3azure-service-principal)

autorest/adal はサービス プリンシパルのトークンを扱うためのパッケージです。

- 参考記事：[go-autorest を使って、Azure の生REST-API をしばき上げる。 - Qiita](https://qiita.com/TsuyoshiUshio@github/items/272fe201972d961de088)

今回で「Azure SDK for Go のインストール / Install the Azure SDK for Go」ページを読み終えたことになります。

P.S. これまで通りja-jpでアクセスしたのですが日本語ドキュメントが表示されなくなっていました... > Microsoftさん
React Tutorial 中

node.js インストール後
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/209211/ad3b3cf7-f82a-5985-cf75-808dda625e63.png)

node.jsがインストールされたら自動的にnpmも一緒にセットされていることを確認する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/209211/e12e56a4-782c-401d-33e4-33ee1fbdfeb2.png)


それと、npxのセットアップが必要？
→javascript package management module(node Package Module)
npm@5.2.0verから新しく追加されたツールらしい。
->npmの場合はresistryからhostingされた以下のものが使いやすかった一方、
npxの場合はrestiryからhositngされたCLI?? および他実行ファイルが使いやすいらしい。
何か単純化されたらいいけど。。わからん！

※ローカルでセットされたツールをnpm run scriptsなしで使用する場合
※臨時使いもの、あまり使わないコマンドをする時
→重いpackageがインストールされたまま残ってしまうとか。
※ほかのnode.jsと一緒に交換できること
npmはできなかったっけ？
※gistを基づいたscriptを共有する時


https://blog.npmjs.org/post/162869356040/introducing-npx-an-npm-package-runner
韓国語：https://geonlee.tistory.com/32

npx セット確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/209211/640a9c1c-f913-a4c6-63fd-32fb17f4d25e.png)


React自体がfacebookが作ったもの
aribnbはもうreactを利用しない(2019~
https://softwareengineeringdaily.com/2018/09/24/show-summary-react-native-at-airbnb/
React-> spotify/ Netflix


yarn... First Look at the New Package Manager for Javasciprt?

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/209211/46343737-8bf9-efa8-58a6-2e0137c97d2c.png)


Happy Hacking!


※20200729 追記 create to create-react-app

```terminal
yarn global add npx
npm i npx -g
npx create-react-app project名
```

vsc terminalでは問題がなかったが、
ubuntu でyarnのコマンドを使おうとしたら、以下のようなエラーが出た。ふむふむterminalことで何が違うでしょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/209211/85b0efdc-ed05-baa8-b9ef-4eceeac704c1.png)
python Beautifulsoup4をInstall

pythonを勉強している初心者です。
この記事は学習の目的として記録中です。
なので、参考にできる記事とか内容が間違ってたらコメントをよろしくお願いします。

# 開発環境
OS : macOS Catalina
Version : 10.15.3

# そもそもBeautifulsoupって何？
>Beautiful Soup is a Python library for pulling data out of HTML and XML files. It works with your favorite parser to provide idiomatic ways of navigating, searching, and modifying the parse tree. It commonly saves programmers hours or days of work.

らしい…

# beautifulsoup4をInstall
```
$ pip install beautifulsoup4
または
$ pip3 install beautifulsoup4
```
※自分の環境ではpip3でinstallができた！！！

# Install確認
```
pip freeze | grep -e beautiful 
または
pip3 freeze | grep -e beautiful 
```


#参考記事
[Beautiful Soup Documentation](https://www.crummy.com/software/BeautifulSoup/bs4/doc/)
FlutterでGoogleMapを使ったアプリを作ってみる

## どんなアプリか？

- 西中島南方駅周辺のキャッシュレス対応のお店情報を表示するアプリ
- ピンをタップでお店情報を表示 & スライド変更でお店のピンへ移動

[‎「ポイント還元対象店舗検索アプリ」](https://apps.apple.com/jp/app/%E3%83%9D%E3%82%A4%E3%83%B3%E3%83%88%E9%82%84%E5%85%83%E5%AF%BE%E8%B1%A1%E5%BA%97%E8%88%97%E6%A4%9C%E7%B4%A2%E3%82%A2%E3%83%97%E3%83%AA/id1477479075) が既にあるのですが、Flutterの勉強がてら作ってみました。

![ezgif.com-video-to-gif.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510204/517f4168-bc8c-25dd-4a47-5711e8d56b1f.gif)

リポジトリ: https://github.com/matometaru/my_app


## API

キャッシュレス・消費者還元事業のAPIを使わさせていただきました。

出典：キャッシュレス・消費者還元事業（ https://cashless.go.jp/terms_of_use.html ）

## 使用したライブラリ

- [google_maps_flutter \| Flutter Package](https://pub.dev/packages/google_maps_flutter)
- [location \| Flutter Package](https://pub.dev/packages/location)
- [carousel_slider \| Flutter Package](https://pub.dev/packages/carousel_slider)
- [http \| Dart Package](https://pub.dev/packages/http)

## 苦労した点


### AndroidとiOSの差異

Andoridにある`Info Window`がiOSにはありませんでした。
[GitHub - Solido/awesome-flutter](https://github.com/Solido/awesome-flutter#gaming) から代用できそうなライブラリを探したところ[flutter_carousel_slider](https://github.com/serenader2014/flutter_carousel_slider)で代用できました。

### 非同期処理

carousel_sliderのanimateToPageが非同期処理なのでスライド時にgoogleMapのカメラとの同期がうまくいかず、jumpToPageに変更するとうまく行きました。

``` xxx.dart
basicSlider.jumpToPage(pageIndex);
// basicSlider.animateToPage(
//   pageIndex,
//   duration: Duration(milliseconds: 300),
//   curve: Curves.linear
// );
```


### レイアウトの調整

以下のような簡単なレイアウト実装に対するコード量が多い。
なかなか思い通りのレイアウトが再現できずもどかしかったです。

![スクリーンショット 2020-03-29 21.32.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510204/6fb7d1f7-791b-742f-ad56-1b13d6a1d60d.png)

``` xxx.dart
child: Column(
  children: [
    Container(
      alignment: Alignment.centerLeft,
      child: Text(
        "${store.name}",
        style: TextStyle(fontSize: 20.0, fontWeight: FontWeight.bold)
      ),
    ),
    Container(
      margin: EdgeInsets.fromLTRB(0, 10, 0, 0),
      alignment: Alignment.centerLeft,
      child: Text(
        'ID: ${store.id}',
        style: TextStyle(fontSize: 16.0)
      ),
    ),
    Container(
      margin: EdgeInsets.fromLTRB(0, 10, 0, 0),
      alignment: Alignment.centerLeft,
      child: Text(
        "Tel: ${store.tel}",
        style: TextStyle(fontSize: 16.0)
      ),
    ),
  ],
),
```

[flutterstudio](https://flutterstudio.app/)を使いこなすと、レイアウト周りはかなり楽になるかもしれません。

## 今後追加したい機能

- 現在地周りの店舗情報を取得
- 店舗のキャッシュレス対応アプリの掲載
- Push通知

以上です。
Mo's algorithm(クエリ平方分割)の話

Mo's algorithmの紹介記事です。
# Mo's algorithmとは
区間に対するクエリを高速に処理するためのアルゴリズムです。
次のような問題を考えてみましょう。
> 長さ $N$ の数列 $A$ がある。$l_i,r_i$ に関するクエリがたくさん飛んでくるので、$[l_i,r_i)$ の最小値を答えよ。

これは、みなさんよくご存じ、Segment TreeやSparse Tableを使うことで高速に処理できます。
では、次の問題はどうでしょう。
> 長さ $N$ の数列 $A$ がある。$l_i,r_i$ に関するクエリがたくさん飛んでくるので、$[l_i,r_i)$ の**値の種類数**をオフラインで答えよ。

これを同じようにSegment TreeやSparse Tableで解くことはできません。
必要となる区間のマージに $O(N)$ かかってしまうからです。
では、これを高速に解く方法はないでしょうか。実は、この問題は、クエリがオフラインなら**Mo's algorithm**と呼ばれるアルゴリズムを使って、高速に解くことができます。

# Mo's algorithmの仕組み
Mo's algorithmは、クエリを先読みして適切な順番に並び替えることにより、計算量を減らすテクニックです。
まず、区間全体を $\sqrt N$ 個ずつまとめ、平方分割をします。
ここで、与えられたクエリを、次のようにソートします。

- 平方分割後、どこの区間に含まれるかの順序でソートする。
- 含まれる区間が同じ場合は、右端の順でソートする。

こうしてソートした順序で、前の結果を利用しながらクエリを処理していきます。具体的には、左右の端を伸ばしたり縮めたりすることで、前の結果をもとに計算します。
計算量を解析してみましょう。
左端は、区間ごとにソートされていることにより最大 $\sqrt N$ ずつしか動きません。
また、右端は、左端がひとつの分割された区間に属している間は、右端でのソート順によって合計で最大 $N$ しか動きません。
よって、左端の移動では $O(Q\sqrt N)$, 右端は $O(N\sqrt N)$ となります。
これで、合計の計算量が $O((N+Q)\sqrt N)$ になります。
ただし、左右の端を動かすのにSegment Treeなどを使ったりすれば、当然全体に $\log$ がつくので、$O((N+Q)\sqrt N\log N)$ などになることもあります。

# 名前の由来
Mo's algorithmの名前の由来について紹介します。
Mo's algorithmは、2009年の中国における情報オリンピック春合宿で出題された問題、[小Z的袜子(hose)](http://www.lydsy.com/JudgeOnline/problem.php?id=2038)で初めて使われたようです。
ところで、イギリス英語で靴下をhoseと言うようですね。初めて知りました。
問題概要の訳を示します。
> $N$ 枚の靴下が並んでいて、それぞれに色がある。区間が $M$ 個与えられるので、ランダムに $2$ 枚の靴下を区間から選んだとき、同じ色である確率を求めよ。
制約:$N,M\leq 50000$

まさにMo's algorithmで解ける問題ですね。
区間の遷移の際には、Segment Treeを用いて色ごとにその色の靴下を2枚選べる通り数を管理し、クエリに答える際には区間和を用いて、全体の通り数に占める確率を計算すればよいです。
なお、オリジナルの問題では有理数の形での出力が求められるようで、少し特殊だな、と思いました。
これに対して、莫涛(Mo Tao)氏が発明したアルゴリズムがMo's algorithmというわけです。

# 実装例
実装は非常に簡単です。
分割する区間ひとつひとつのサイズを決定した後、次のような関数を用いてクエリをソートすればよいです。

```cpp
int M;  //分割するひとつひとつの区間サイズ
bool func(const pair<int, int>& lhs, const pair<int, int>& rhs) {
	if (lhs.first / M < rhs.first / M)return true;
	if (lhs.first / M == rhs.first / M && lhs.second < rhs.second)return true;
	return false;
}
```
これで、区間の左端と右端を次のクエリの左右の端に向けてずらしていけばよいです。

# 問題例
先ほど挙げた中国の情報オリンピックの問題の他に、日本語では[JOI2014春合宿Day1-3 歴史の研究(Historical Research)](https://www.ioi-jp.org/camp/2014/2014-sp-tasks/2014-sp-d1.pdf#page=9)がMo's algorithmで解けます。定数倍が少し重いですが、高速化をすると通ります。想定解法はバケット法のようです。
[提出コード](https://atcoder.jp/contests/joisc2014/submissions/11203999)

# おわりに
そこまで頻出のアルゴリズムではないですが、これがないと解けない問題も存在します。覚えておきましょう。
SDカードイメージの作成

### 経緯

[第2回AIエッジコンテスト（実装コンテスト①）](https://signate.jp/competitions/191)に参加しています。
その過程でSDカードイメージを作る必要があったので、メモとして残します。
私はWSL上のUbuntuで操作していますが、Linuxであれば同じ操作でいけると思います。

### 要件

[提出物詳細 (submission_details.pdf)](https://signate.jp/competitions/191/data/985)より

>- SDカードバイナリイメージ(e.g. sd.img)
>  - SDカードイメージにはboot.bin(uboot+bitstream)、LinuxKernel、アプリを含めて「 Win32 DiskImager 」などのソフトでIMG形式のファイルを作成してください。
>  - 審査の過程では、Ultra96ボードのSDカードのセットアップで使用した「Etcher」を用いて動作確認を行います。

### 手順

イメージ自体は[Ultra96V2向けVitis AI(2019.2)の組み立て方。](https://qiita.com/basaro_k/items/e71a7fcb1125cf8df7d2)を参照し作成しています。

#### サイズが8GiBのimageを作成
```
$ truncate -s 8GiB sd.img
```

#### 使用されていないループデバイスを確認
```
$ sudo losetup -f
/dev/loop0
```

#### 使用されていないループデバイスにsd.imgを関連付ける
```
$ sudo losetup /dev/loop0 sd.img
```

#### パーティショニングとフォーマット
```
$ # 8GiB中、先頭2GiBをfat32、残りをext4で確保
$ sudo parted /dev/loop0 -s mklabel msdos -s mkpart primary fat32 0 2GiB -s mkpart primary ext4 2GiB 100%
$
$ # bootをfat32でフォーマット
$ sudo mkfs.vfat /dev/loop0p1
$ # rootをext4でフォーマット
$ sudo mkfs.ext4 /dev/loop0p2
```

#### マウント
```
$ # マウントポイント作成
$ mkdir -p ./mnt/boot ./mnt/root
$
$ # マウントする
$ sudo mount /dev/loop0p1 ./mnt/boot/
$ sudo mount /dev/loop0p2 ./mnt/root/
```

#### データの格納
```
$ # boot領域のデータコピー
$ sudo cp ./make_ultra96/sd_card/boot/* ./mnt/boot/
$
$ # root領域のデータをコピー
$ sudo tar -C ./mnt/root/ -xzvf ./make_ultra96/sd_card/rootfs/rootfs.tar.gz
$ # 追加で必要なデータは、 ./mnt/root/home/root 以下に置けばOK
$
$ # キャッシュ上のデータをディスクへ反映
$ sudo sync
```

#### マウント解除
```
$ sudo umount ./mnt/boot
$ sudo umount ./mnt/root
$ sudo losetup -d /dev/loop0
```

あとは、sd.imgを[BalenaEcher](https://www.balena.io/etcher/)等のツールで焼けばOK。
ターミナルの環境構築について

## はじめに
先日、ターミナルを環境構築しました。</br>
そのときに出てきたターミナル関係の設定、アプリを理解するためにまとめてみました。</br>
参考サイトは最後に書いてあります。

完全初心者向けにわかりやすいように書いていきます。

- iTerm
- iceberg
- prezto
- zinit

### iTerm
エンジニアが必ず使うターミナルの上位互換版</br>
画面分割をして使えるのが便利です。

<img width="1440" alt="スクリーンショット 2020-03-29 14.45.28.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510350/6258575d-17f7-f432-f606-aa967d2b95ff.png">

背景を透けさせて重ねたり、ショートカットの設定もできるみたいだけど僕は設定してないです笑

### iceberg
iTermやターミナルの**見た目**をオシャレに、見やすく設定するのにオススメなテーマ</br>
他にもいろいろなテーマがあるので自分に合ったものを探してみるのがいいかと

### prezto
zshのフレームワークの一つです。</br>
要は、zshを使うにあたって色々と便利な機能を入れてくれる有能なやつ

コマンドを補完してくれたり、プロンプトを見やすくしてくれたりします。
プロンプトとは、下の画像(ターミナル)内のコマンド前の`>`のことです。
ここの見た目を変えて、自分の好きな見た目にすることができます。

<img width="697" alt="スクリーンショット 2020-03-29 15.04.30.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510350/c9280517-36c3-f6b5-e6b2-54e01fd87cb4.png">

### zinit
zshのプラグインマネージャです。</br>
プラグインというのは拡張機能のことで、それを簡単に入れられるようにするために、プラグインマネージャを使用します。

`zsh-completions`という補完機能や、`zsh-history-substring-search`というヒストリーサーチなどがあります。

`zplug`から`zinit`に名前が変わりました。

## 参考
[MacのターミナルアプリはiTerm2で決まり!!オススメの設定と基本的な機能まとめ](https://webrandum.net/iterm2/)

[Macのターミナルをおしゃれにする！【icebergテーマ】](https://qiita.com/samuraibrass/items/1bf4ff34e8682f762682)

[Preztoのインストールとプロンプトテーマの選択方法(for macOS)](https://qiita.com/notakaos/items/89057f2119655ab9f920)

[zplugやめてzinitにしたらちょっと速くなったよって話](https://qiita.com/Jung0/items/bec15a0285a02d5761d4)
消せないAndroidアプリをadbを使って強制アンインストール

## 前提

adbコマンドを実行できることが前提です。

また、開発者モードをOnにして、USBデバッグモードでPCに接続してください。

## スマホに接続する

`adb shell`を実行して、スマホに接続します。

## 削除したいアプリのpackage名を調べる

`am monitor`を実行する。

`am monitor`は、起動するアプリをリアルタイムで把握するコマンドです。

`HWPOT-H`はスマホの機種によって変わると思います。

```bash
HWPOT-H:/ $ am monitor
Monitoring activity manager...  available commands:
(q)uit: finish monitoring
```

`am monitor` を実行した後、アンインストールしたいアプリを起動することで、下のようになります。

```bash
HWPOT-H:/ $ am monitor
Monitoring activity manager...  available commands:
(q)uit: finish monitoring
** Activity starting: com.android.calculator2
```

今回は、最初から入っている計算アプリを消そうとしています。

この、`com.android.calculator2`というpackage名をどこかに記録しておいてください。

そして、`q`を押してからエンターをおすことで、`am monitor`を終了し、次のコマンドを入力できるようになります。

## アプリをアンインストールする

`pm uninstall com.android.calculator2`を実行します。(`com.android.calculator2`は削除したいアプリのpackage名に置き換えてください)

そうすると、そのアプリをアンインストールすることができます。

## 備考

### `DELETE_FAILED_INTERNAL_ERROR1`が発生する場合

`pm uninstall -k --user 0 package名`を`pm uninstall package名`の代わりに使用する。

## その他
[hatena](https://2lu3.hatenablog.com/entry/adb-uninstall)でも投稿しています。
ぜひ、そちらも見てください
読みやすいコードを書きたい！

#この記事の趣旨
　自分の学習のメモとして残します。
　どなたかのお役に立てたら光栄です。

#こんな方におすすめです
　・コードが見づらいと言われる
　・初心に返りたい
　このような方には何か発見があると思います。

#読みやすいコードとは？
　ズバリ『良いコード』のこと。
　良いコードは、他人がそのコードを見た時に短時間で理解できるコードのことを言います。

　逆に、分かりづらい・理解しづらいコードは解読に時間がかかります。それだけ開発の工数もかかってしまい、効率が良くありません。

　では、良いコードの条件・要素を紐解いていきましょう！

##●コードの命名に規則を
　変数やメソッドは好きなように命名ができます。
　ルールがありませんので、個人の好きなようにできます。
　特に共同開発の現場などでは、「他人が見てわかる」を意識する必要があります。

###　◎命名のポイント
　　【目的がわかる単語を使う】
　　　　例）new　→　new_account

　　【汎用的な名前は避ける】
　　　・一時的な変数などは避ける
　　　・可読性を意識して

　　【名前に情報を含める】
　　　大文字、小文字をルールに沿って活用
　
　　【誤解されない名前を使う】
　　　・何がしたいかが明確な名前
　　　・説明的に長くなっても良いので、可読性重視
　　　　　例）read_books → already_read_books

##●コードレイアウト
　プログラムの挙動に影響はないが、可読性を大幅にあげることができる

###　◎レイアウトのポイント
　　　・整列　　　　：縦列を揃える。イコールの位置など縦が揃うと見やすい
　　　・一貫性　　　：似たような構造は同じフォーマットに統一できないか検討
　　　・ブロック化　：同じ系統の変数などをまとめてグループ化すること


##●コメント
　・プログラムの動作を説明
　・他の開発者がコードを読む際の理解を助ける
　　※多すぎても読むのに時間がかかるため、簡潔に

###　◎コメントのポイント
　　　・理由をコメントする　　：なぜそのコードを書いたか
　　　・他の開発者へメモを残す：開発中のメモとして
　　　・実際の例を記入する　　：コメントでは伝わりづらい時は、コメントとしてコードを記載


#まとめ
　結局大事なことは
　　「人に対する思いやり」だなぁと。

　複数人で仕事をする以上、「自分だけ良ければそれで良い」という考えはNG。
　誰もが見やすく、仕事をしやすい状況を自分が作り出す意識が大切。

　そのための知識や技術であると思う。

　これからしっかり学んでいきましょう。
python pip3 Install 方法

pythonを勉強している初心者です。
この記事は学習の目的として記録中です。
なので、参考にできる記事とか内容が間違ってたらコメントをよろしくお願いします。

# 開発環境
OS : macOS Catalina
Version : 10.15.3

# yumを使ってpip3をInstall
```
yum --enablerepo=epel install python34-pip
```

# aptを使ってpip3をInstall
```
sudo apt install python3-pip
```

#pip3をVersion確認
```
# pip3 -V
```

# pip3をUpgrade
```
pip3 install pip --upgrade
```

# pip3をUninstall
```
sudo python3 -m pip uninstall pip
```

# メモ
※python3をinstallしたらpip3も同時にInstallできたので、自分の環境ではPass~~

#参考記事
[pip3コマンド自体のインストール](https://python.open-code.club/ライブラリ/pip3コマンド自体のインストール.html)
[pip3をインストールする](http://ytyaru.hatenablog.com/entry/2017/05/29/000000)
【GAS】Browser.msgBoxでポップアップが表示されない

##問題

```javascript

function myFunction() {
  Browser.msgBox('Hello');
}
```

で実行してスプレッドシートを開いても、ポップアップが表示されない。

##解決策
プロジェクト名をつける。
スプレッドシートの名前を変更する。
【laravel5.8】php artisan migrate --seedでseedが効かない時

`database>seeds>DatabaseSeeder.php`に自分が作ったSeederが登録されてるか確認してみてください。

```DatabaseSeeder.php
<?php

use Illuminate\Database\Seeder;

class DatabaseSeeder extends Seeder
{
    /**
     * Seed the application's database.
     *
     * @return void
     */
    public function run()
    {
        $this->call(UsersTableSeeder::class);
        $this->call(GroupsTableSeeder::class);
        $this->call(AgendasTableSeeder::class);
        $this->call(CommentsTableSeeder::class);
    }
}

```

laravel公式リファレンスだとマイグレーションと一緒にテストデータを流し込む際に「`php artisan migrate --seed`で一髪完了！」と書いてあるのになかなかできなかったので調べてみました。
同じエラーで困ってる方がいたらご参考までに。