OmniAICreator/Qiita-1.07M huggingface dataset:
Dockerコンテナにパッケージ管理ツールpoetryを使ってPythonの分析環境を構築する方法

昨年のとあるアドベントカレンダーでPythonのパッケージ管理ツールの一つ`poetry`が紹介されていました。
[2020 年の Python パッケージ管理ベストプラクティス](https://qiita.com/sk217/items/43c994640f4843a18dbe)
普段業務で使っているのは`pipenv`なのですが、パッケージを作るのに`setup.py`とかその他諸々のファイルが必要で面倒だったり、`pipfile.lock`の作成に異常に時間がかかったりしていてストレスを感じていましたが、`poetry`だとそれらがいい具合に解決されている？とのことだったので試してみました。
`poetry`を使って`Docker`コンテナに分析環境を構築したので、その方法をメモします。
コードは[こちら](https://github.com/yolo-kiyoshi/poetry_docker)にあげています。

# 解説
ディレクトリ構造は以下の通りです。

```:tree
.
├── Dockerfile
├── README.md
├── docker-compose.yml
├── notebook # EDAで使用するnotebook
│   └── eda.ipynb
├── poetry.lock
├── pyproject.toml
├── src # パッケージ化したいモジュール
│   ├── __init__.py
│   └── helloworld.py
└── tests # テストコード
    ├── __init__.py
    └── test_helloworld.py
```

設定ファイル群`Dockerfile`、`docker-compose.yml`、`pyproject.toml`は以下の通りです。

## pyproject.toml
`pandas`、`numpy`、`sklearn`、`matplotlib`といったパッケージを入れています。
また、開発用に`pytest`も入れています。
_※他パッケージの追加方法に関しては後述_

```toml:pyproject.toml
[tool.poetry]
name = "poetry_docker"
version = "0.1.0"
description = ""
authors = ["yolo-kiyoshi"]

[tool.poetry.dependencies]
python = "^3.9"
sklearn = "^0.0"
jupyterlab = "*"
pandas = "*"
numpy = "*"
matplotlib = "*"
seaborn = "*"
japanize-matplotlib = "*"

[tool.poetry.dev-dependencies]
pytest = "^5.2"

[build-system]
requires = ["poetry>=0.12"]
build-backend = "poetry.masonry.api"
```

## Dockerfile
`poetry`はデフォルトで仮想環境`venv`を構築しますが、Dockerコンテナにわざわざ`venv`を構築する必要はないので、`poetry config virtualenvs.create false`によってコンテナ上に直にパッケージをインストールするようにしてます[^1]。
その後、`poetry install`によって`poetry.lock`の依存関係をみながらパッケージをインストールします。

```dockerfile:Dockerfile
FROM python:3.9-slim

ENV PYTHONUNBUFFERED=1

WORKDIR /app

COPY poetry.lock pyproject.toml ./

RUN pip install poetry

RUN poetry config virtualenvs.create false \
  && poetry install
```

## docker-compose.yml
`ports`でローカルport8888とコンテナport8888を接続し、`command`でjupyterを起動します。

```yml:docker-compose.yml
version: '3'
services:
  eda:
    build: ./
    user: root
    volumes:
      - ./:/app
    working_dir: /app
    ports:
      - "8888:8888"
    command: jupyter lab --ip=0.0.0.0 --allow-root --NotebookApp.token='' --port=8888
```

# 使い方
ソース一式をローカルにcloneします。

```
git clone https://github.com/yolo-kiyoshi/poetry_docker.git
```

## ビルドとコンテナ起動
以下のコマンドによりDockerイメージのビルドとコンテナを起動できます。

```
docker-compose up -d
```

_※`Dockerfile`を変更しリビルドしたい場合、`docker-compose up -d --build`を実行します_

## jupyterへのアクセス
コンテナ実行後、以下にアクセスすることでJupyter labにアクセスできます。  
<a>http://localhost:8888/lab</a>

## テスト実行
以下のコマンドで`tests/`配下のテストコードを実行できます。

```
pytest
```

※`pytest`の詳しい使い方は以下がわかりやすいです。
　[pytest ヘビー🐍ユーザーへの第一歩](https://www.m3tech.blog/entry/pytest-summary)

## パッケージの追加
以下のコマンドでPythonパッケージを追加できます。

```
poetry add <追加したいパッケージ>
```


# 感想
`poetry` 使いやすいと思います。
パッケージ作成が容易になったのもいいのですが、何より`pipenv`よりも`.lock`ファイル作成にかかる時間が短いなと感じます[^2]。
今年はバンバン`poetry`を使って開発していこうと思いました。

[^1]: [Integrating Python Poetry with Docker](https://stackoverflow.com/questions/53835198/integrating-python-poetry-with-docker)
[^2]: PipenvとPoetryを比較した記事 [Pipenv and Poetry: Benchmarks & Ergonomics](https://johnfraney.ca/posts/2019/03/06/pipenv-poetry-benchmarks-ergonomics/)
Web担当者として身につけるべきスキルとは？

明けましておめでとうございます！ついに2020年が始まりました！皆さん、お正月はいかがお過ごしでしょうか？新年の始まりにあたり、今年の目標/やりたいことを立てる方が多いと思います。Web担当者としての私、2020に何かの新しいWebスキルを勉強するのか、いろいろ考えてみました。

グーグルしたところ、まだ身につけていないスキルはたくさんあります。今日はWeb担当者として身につけるべきWebスキルをまとめて、皆さんに紹介したいと思います。

 
#Web担当者とは？

そもそもWeb担当者はどんな人でしょうか？Web担当者とは、Webマーケター、Webマーケティング担当者とも呼ばれ、Webサイトへの集客に関する業務を担当します。Webサイトの登録者数やPVなどの増加を目的として、様々な施策を行い、アクセス解析の結果を分析し、施策の検証・改善を行います。

#Web担当者の仕事内容は？

Web担当者はどんな仕事をするのでしょうか？まずはある求人情報に掲載した仕事内容を見てみましょう。
![图片1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/262932/fbfb6c68-ade8-078b-8513-6abefd744e2f.png)


いかがでしょうか？Web制作、SEO対策、リサーチ、分析、企画提案などたくさんありますね。私自身もそれらの仕事をしています。もちろん、企業の大小や業種によって、仕事内容は変わりますが、必要とされる事はあります。

- SEO（検索エンジン最適化）
- Webサイト・ホームページ制作
- リスティング広告・ディスプレイ広告
- SNSの運用
- メールマーケティング
- コンテンツマーケティング

など、これらの手法を通じて、集客の目的を達成します。

 

 


#Web担当者に必要なスキル

 
##１.情報収集・分析のスキル

新しい製品・サービスを立ち上げるとき、必ず市場分析、競合分析を行います。分析を行う前、たくさんの情報を収集しなければなりません。情報収集を効率的に進めるために、情報収集力は必須なスキルです。それに、収集した情報を整理して、目的に応じて分析、解析できるスキルを身につけておくのも重要です。

**利用可能リソース：**

Web情報を収集するには、[Octoparse](https://www.octoparse.jp/)というスクレイピングツールがオススメです。プログラミングする必要がなく、クリックするだけで素早くデータを抽出できます。

[スクレイピングツールにオススメの10選](https://www.octoparse.jp/blog/the-10-best-web-scraping-tools/)

データ分析・可視化なら、Tableauがオススメです。Tableauは非常に強力で柔軟な分析プラットフォームで、プログラミングなどの専門知識・スキル不要で複数のユーザのコラボレーションも可能です。

[データ分析にオススメのツール31選](https://www.octoparse.jp/blog/top-30-big-data-tools-for-data-analysis/)

 

 

 

##2.サイト企画／制作／デザイン／更新のスキル

自社で新しいサービスを行なう場合、新しくホームページを作らなければいけないことがあります。以前作ったホームページを更新や修正などことも時々ありますね。ホームページをイチから作るには、企画書作成、レイアウト作成、ドメイン・サーバー準備、サイトマップ作成など、様々なノウハウや作業が必要になります。可能であれば、プログ（THML・CSSの知識）やデザインのスキルを身につけておきましょう。

**利用可能リソース：**

今では、Instapage、WiXやStrikinglyなど、LPを作れるツールがたくさんあります。テンプレートが豊富で、PowerPointのように簡単でおしゃれなページを作れます。

 

 

##3.SEO対策のスキル

新しいサイトを立ち上げた後、検索順位を上げるために、サイトのリンクやコンテンツを最適化しなければなりません。それはSEO対策です。SEOを行うことで、検索結果で上位表示できれば、より多くの検索ユーザーにリーチすることができます。SEOでは、キーワード、被リンク、コンテンツが重要で、最適化するのに一定の需要がずっと続くことになります。ですから、成果を出すのは時間かかるし、難しいことです。

**利用可能なリソース：**

Moz、SEMrush、AhrefsなどSEOに役に立つツールもたくさんあります。それらのツールを利用して、キーワード、リンクの分析を簡単にすることができます。

 

 

##4.良質なコンテンツを書くスキル

質が良いコンテンツとは、検索ユーザーが喜び記事のことです。さっき言ったSEO対策では、コンテンツ作りは重要です。コンテンツマーケティングの一環として、多くの企業はブロクを立ち上げました。ですから、相手が読みやすく、分かりやすい記事を書くノウハウが必要になります。

**利用可能なリソース：**

WEB上では多くのノウハウ記事がありますので、ここでは一本をオススメします。

[良質なコンテンツとは：良い記事を書くための14のポイント](https://saruwakakun.com/it/seo/good)

 

 

 

##5.SNS運用のスキル

SNSの普及に従って、SNSマーケティングを行う企業も増えました。多くの人に自社の製品やサービスを見てもらえる機会を増加するために、どれだけ拡散できるかが重要です。ですからフォロワー、「いいね」や「シェア」を増やすのもWeb担当者の仕事となります。そのため、FacebookやTwitter、Instagramなど、それぞれサービスの特徴とできることを把握する上で、ふさわしいコンテンツを配信することも重要です。

**利用可能なリソース：**

SNSでマーケティング活動を行う際に、SNS分析はとても有用です。より正確でタイムリーな情報を入手するには、ツールを活用するのが効率的です。無料ツールなら、HootsuiteとSocial Mentionがオススメです。

 

 

#まとめ

いかがでしたか？以上は、私自身の仕事を元にして、仕事内容とそれに必要なスキルと利用可能なソースの紹介でした。Web担当者になった１年以上の私はスキル不足を感じた時が多いです。今年もWeb担当者の必要なスキルの向上に日々努力をしたいと思います。もしその中では、皆さんが身につけたいスキルがあれば嬉しいです。

元記事：https://www.octoparse.jp/blog/web-marketing-skills-you-must-have/
未定義の変数 NameError

```py
import traceback, sys

number1 = 100
number2 = 2

print('start')
try:
    answer = number1 / number2
    print(answer2)
except NameError as e:
    print('未定義の変数を呼び出しています')
    sys.stderr.write(traceback.format_exc())
finally:
    print('end')
```

```:実行結果
start
未定義の変数を呼び出しています
end
```

```:実行時エラー
Traceback (most recent call last):
  File "Main.py", line 9, in <module>
    print(answer2)
NameError: name 'answer2' is not defined
```

本来answerをprint出力する場面で、
answer2という未定義の変数を呼び出してしまった。

exceptするエラーの対象を
0で割ったエラーの場合から、
ZeroDivisionErrorからNameErrorにかえて、
print出力する文字列を'未定義の変数を呼び出しています'にかえただけ。
pyenvを使ってpythonのバージョンが変更できない時の原因

# 背景
python2のサポートが2019年いっぱいで終了してしまうということで、pythonのバージョンを簡単に切り替えることのできるpyenvを導入することにしました。
しかし、pyenvでのバージョン切替に少し躓いてしまったので、バージョン切り替えができない主な原因に関してまとめておきます。
python2サポート終了に関する記事
https://news.mynavi.jp/article/20191118-924132/
# 環境
MacOS Catalina 10.15.2
Homebrew 2.2.2
pyenv 1.2.16
# バージョン変更できない原因
## １. pyenvのパスが通っていない
pyenvをインストールするためにhomebrewで以下のようにインストールしました。

```bash:pyenvのインストール
$ brew install pyenv
```
インストールも無事に終わりいざpython3.7.6をpyenvでインストールしようと思ったのですが、なぜかpyenvが存在しないと言われました。通常はhomebrewでインストールした時は自動的に`/usr/local/bin`にシンボリックリンクが作られパスが通るのですが、その時はなぜかパスが通っていませんでした。
どうやら事前にインストールされていた古いバージョンのpyenvを削除した関係かリンクが自動的に貼られなかったことが原因でした。
そのためhomebrewコマンドでリンクを貼り直したら、pyenvのパスが通るようになりました。

```bash:brewでリンク貼り
$ brew link pyenv
$ pyenv --version
pyenv 1.2.16
```

## ２. pythonコマンドパスの変更をしていない
次にpyenvでpython3をインストールして、バージョンを2から3に変更しました。
pyenvコマンドでバージョンを確認すると`3.7.6`となっているのに、pythonコマンドでバージョンを確認すると`2.7.16`となっており、なぜかバージョンを変更できていませんでした。

```bash:pythonバージョン変更
$ python --version
Python 2.7.16
# インストールできるバージョンを確認
$ pyenv install --list
Available versions:
  2.1.3
  2.2.3
  2.3.7
  2.4.0
  2.4.1
  2.4.2
  ・・・
# python3.7.6をインストール
$ pyenv install 3.7.6
# インストール済のバージョンを確認
$ pyenv versions
* system
  3.7.6
# バージョンを3.7.6に変更
$ pyenv global 3.7.6
$ pyenv versions
  system
* 3.7.6
# バージョンを確認
$ python --version 
Python 2.7.16
```
そこでpythonコマンドが見ている先のパスを確認しました。
するとその向き先は`/usr/bin/python`となっていました。
pyenvでのバージョン管理をしているpythonを使用したい場合は、
コマンドの向き先のパスを`~/.pyenv/shims/python`に変更する必要があったのです。

```bash:pythonコマンドの向き先のパスを変更する
$ which python
/usr/bin/python
$ eval "$(pyenv init -)"
$ which python
~/.pyenv/shims/python
$ python --version
Python 3.7.6
```
無事バージョンを変更することができました。
# まとめ
今回のpythonのバージョン変更作業を通して、プログラミング言語のバージョン管理は意外と面倒くさいなと感じました。
ただ、pythonに限らずどのプログラミング言語もバージョンアップは頻繁に行われています。
そして、どのコンテンツもそのハージョン変更に合わせて、メンテナンスをして新しいバージョンに合わせる必要があります。そのことを考えるとpyenvのように気軽にバージョンを変更できるツールも必要だなと感じました。
新しいコンテンツを作成するときはプログラミング言語のインストールと同時に**その言語のバージョン管理を気軽に行える仕組みもまずは考えること**が重要そうですね。
# 参考資料
pyenvのインストール、使い方、pythonのバージョン切り替えできない時の対処法
https://qiita.com/koooooo/items/b21d87ffe2b56d0c589b
[python]pyenvがバージョンを切り替える仕組みを理解する
https://akamist.com/blog/archives/2610
Homebrewにおけるlinkについて
https://hacknote.jp/archives/23816/
エラー「Uncaught Error: Access to undeclared static property: 〜」の対処方法

###発生状況

phpでクラスから別クラスの変数を取得しようとした際にエラー発生しました。

簡単な処理を以下に記載します。
別クラスから取得した変数を出力する処理で、`yamada` と出力されれば成功です！

```php:処理内容
$person = new GetInfo;
$person->getName();

class PostInfo{
    public $name = 'yamada' . PHP_EOL;
}

class GetInfo{
    public function getName(){
        echo PostInfo::$name;
    }
}
```

```terminal:結果
Fatal error: Uncaught Error: Access to undeclared static property: PostInfo::$name
```
このように `PostInfo`クラスの `$name` 変数が取り出せずにエラーになってしまいます。


###解決方法

 `$name` 変数前に `static` を記載することで解決しました。 

```php:example.php
$person = new GetInfo;
$person->getName();

class PostInfo{
    static public $name = 'yamada' . PHP_EOL;
}

class GetInfo{
    public function getName(){
        echo PostInfo::$name;
    }
}
```
```terminal:結果
yamada
```
このように成功しました！

###staticプロパティについて
こちらのエラーをわかりやすく解説しているサイトがありましたので、学んだことを簡単に引用させていただきました。
>staticキーワードを付けたプロパティには、外部から直接アクセス出来ます。
>staticキーワードを付けて宣言したプロパティは、クラスをインスタンス化せずに使用できます。
>staticを指定していないプロパティにstatic形式でアクセスすると、**「PHP Fatal error: Access to undeclared static property」エラーが発生します。**

>**staticプロパティの参考サイト**
>http://akutaka00.blog102.fc2.com/blog-entry-69.html


####まとめ
つまり今回「staticを指定していないプロパティにstatic形式でアクセス」していたことが原因だったことがわかりました。
プログラミングの学習をしていると様々なエラーが発生し心折れそうになりますがきちんと原因がわかると、知識が増えた・理解が深まったとポジティブな方向に持っていけることが良いことだなと思いました。

これからも理解したことを少しずつアウトプットしていければと思います。
0で割ったエラー ZeroDivisionError の処理2

```py
import traceback, sys

number1 = 100
number2 = 0

print('start')

try:
    answer = number1 / number2
    print(answer)
except ZeroDivisionError as e:
    print('0では割れません。')
    sys.stderr.write(traceback.format_exc())
finally:
    print('end')
```

```:実行結果
start
0では割れません。
end
```

```:実行時エラー
Traceback (most recent call last):
  File "Main.py", line 9, in <module>
    answer = number1 / number2
ZeroDivisionError: division by zero
```

こうする事で、
出力タブだけを見ていても、
どんなエラーが出ているのかわかりやすい。

また、
実行時エラータブを見れば、
エラーの詳細を確認する事ができる。
termuxでgitのbranch名表示できるようにする

## はじめに

termux上で、ターミナル上にbranch名を表示する方法が見つからなかったので備忘として残しておきます。ちなみにamazon linuxやmacなどでもやることは同じです

## gitのinstall

termuxではデフォルトではgit入っていないので、installしておきます

```shell
pkg install git
```

## Setting

以下2ファイルのpathを確認します。

```shell
find ~/../usr/ -name git-prompt.sh
find ~/../usr/ -name git-completion.bash
```

おそらく、
`/data/data/com.termux/files/home/../usr/etc/bash_completion.d/git-prompt.sh`と
`/data/data/com.termux/files/home/../usr/etc/bash_completion.d/git-completion.bash`
が返ってくるはずです。

あとは.bash_profileと.bashrcをいじるだけです

`~/.bash_profile`に以下を追記

```shell

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

`~/.bashrc`に以下を追記

```shell

source /data/data/com.termux/files/home/../usr/etc/bash_completion.d/git-completion.bash
source /data/data/com.termux/files/home/../usr/etc/bash_completion.d/git-prompt.sh

GIT_PS1_SHOWDIRTYSTATE=true

PS1='\[\033[34m\]\w\[\033[31m\]$(__git_ps1)\[\033[00m\]\n\$ '
# サーバ名も先頭に表示させたいときは以下を使う
# PS1='\[\033[32m\]\u@\h\[\033[00m\]:\[\033[34m\]\w\[\033[31m\]$(__git_ps1)\[\033[00m\]\n\$ '
```

あとは

```shell
source ~/.bash_profile
```

すれば次のような見た目になっているはずです。

![Screenshot_20200113-150919.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/437488/57179abb-1494-abd1-d259-bea63bc40d02.png)
【動画解説付き】Windows10からTeraTerm(テラターム)を使ってRaspberryPi(ラズパイ)を遠隔操作する方法

![図1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538330/cf618bb5-f5cc-1372-fcc3-a921a45309be.png)
どうも、プログラミングの鬼シヨツ鬼です。
この記事では「Raspberry Pi(ラズパイ)をWindowsから遠隔操作したいぜ」って人に向けてTeraTermという無料のソフトを使って遠隔操作する方法を説明します。
初心者の人がこの記事を見ただけで操作できるように、IPアドレスを調べる方法などの準備からコマンドの意味などできるだけ丁寧に説明しているので、ぜひ参考にしてみてください。

ちなみに、この記事は次の動画と同じ内容ですので、記事だけだと分かりづらい部分は、そちらもご活用ください。
**(ボタンの位置や操作方法などがわかるので、初心者の方は動画のほうが分かりやすいかも)**
[YouTube:【電子工作】TeraTerm(テラターム)を使ってRaspberryPi(ラズパイ)を遠隔操作する方法](https://youtu.be/sut1qUbfrJ4)

#準備するもの
・Raspberry Pi 3 model B（OSインストール済のもの。OSのインストール方法は[こちら](https://qiita.com/shiyotsuki/items/150b5b476bce79a54544)）
・遠隔操作されていることが分かる部品(本記事で使っているLチカのやり方は[こちら](https://qiita.com/shiyotsuki/items/375e1b8791767c8b1841))
・Windows10が入っているPC
・無線LAN環境(Wi-fi)
・フリーソフトへの感謝の気持ち

#WindowsへTeraTermをインストールする
Windowsからラズパイを操作するためにTeraTermという無料のソフトをインストールします。インストールは簡単ですので、下記に紹介するページを参考にインストールしてください。
[TeraTermの配布ページ](https://ja.osdn.net/projects/ttssh2/releases/)
[インストール方法](https://eng-entrance.com/teraterm-install)

#ラズパイのIPアドレスを調べる
IPアドレスとはネットワークに接続された機器に割り当てられた数値のことです。電話番号のようなイメージで、通信の際に必要に必要になるので調べます。
###1.ラズパイをネットワークに繋げる
画面右上の電波のマークをクリックしてWi-Fiに接続してください。
###2.IPアドレスを表示する
ラズパイのプロンプトを開いて以下のコマンドを打ち込みます。
`ifconfig`
###3.IPアドレスを確認する
先ほどのコマンドによりネットワークの情報が画面に出力されるので、inetと書かれた部分にどのような値が記載されているか確認します。
(例)`inet 192.168.1.27`

#WindowsのIPアドレスを調べる
###1.Windowsをネットワークに繋げる
画面右下の電波マークをクリックしてラズパイと同じネットワークに接続されていることを確認してください。
###2.IPアドレスを表示する
「コマンドプロンプト」を開いて、以下のコマンドを打ち込みます。
`ipconfig`
###3.IPアドレスを確認する
先ほどのコマンドによりネットワークの情報が画面に出力されるので、IPv4アドレスと書かれた部分にどのような値が記載されているか確認します。
(例)`IPv4 アドレス . . . . . . . . . . . .: 192.168.1.24`

#ラズパイの設定を行う
TeraTermでの遠隔操作を実現するためにラズパイの設定を行います。
次の設定を行うことで、遠隔操作を行うための通信が可能になります。(難しい言葉で言うと「SSH」というプロトコルによる通信を許可する設定)
###1.設定画面を開く
次のコマンドを打ち込み設定画面を開きます。
`sudo raspi-config`
###2.「5 Interfacing Opetions」を選択する
###3.「P2 SSH」を選択する
###4.「<はい>」を選択する
###5.「<了解>」を選択する
###6.「< Finish>」を選択する

#TeraTermより接続を行う
###1.WindowsでTeraTermを起動する
###2.「新しい接続」の画面でホスト欄にラズパイのIPアドレスを入力して「OK」
初めての接続で「セキュリティ警告」が出た場合は「続行」を選択
###3.「SSH認証」の画面でユーザ名とパスフレーズ欄にラズパイのアカウント情報を入力
コマンド入力の画面が表示されれば、成功です。
ラズパイをWindowsからコマンドベースで接続することができます。

#まとめ
コマンドを打ったりする操作は、慣れないと時間がかかったり、打ち間違いで動かなかったりするかもしれないけど、だんだん慣れるよ。
得体の知れない怖いものではないから、落ち着いて使ってみてね。
最後まで、読んでくれてありがとう。
参考になったら「:thumbsup_tone2:」押してね。
Kubernetes 学習環境の構築(for mac)

Kubernetesを勉強するために学習環境をmacにインストールしたのでその備忘です。

1.Docker for Mac のインストール
---
こちらの記事参照

https://qiita.com/Uenrio/items/27355170e09da650cf48


2.VirtualBoxのインストール
---
下記リンクからインストール。OS X hostsをクリックして、dmbをダウンロード。
オプションは全てデフォルトでOK。
https://www.virtualbox.org/wiki/Downloads
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319276/c3853122-4b93-4bea-2480-729aa71f00b2.png)


3.kubectlコマンドのインストール
---
こちらの記事参照

https://qiita.com/Uenrio/items/3a4168e7e96bc7f8235c

4.Minikube*のインストール
---
*小規模なKubernetes環境を作成するために作られたパッケージです。 1台のPC上に、仮想的にKubernetesの環境を構築することができます。 Minikubeは、Windows上でもLinux上でもインストールできるのが特徴

macosのPKGマネージャー Homebrewを使ってインストール



```
$ brew install minikube
 ..(中略)..
$ minikube version
minikube version: v1.6.2

$ 下記コマンドだとエラーが出るので注意
$ brew cask install minikube
 ..(中略)..
Error: Running Homebrew as root is extremely dangerous and no longer supported.
***
```

エラーの詳細は下記。
https://github.com/kubernetes/website/pull/17296

5.Vagrantのインストール
---
Mac OSをクリックしてダウンロード
https://www.vagrantup.com/downloads.html
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319276/fbfed61a-9d74-c898-d1f5-bd7d2afade80.png)

6.Gitコマンドのインストール
---
```
$brew install git
...(中略)...
==> Summary
🍺  /usr/local/Cellar/gettext/0.20.1: 1,893 files, 18.4MB
```

以上で環境構築は完了です。ここからkubernetesが触れます。詳細は別で。

99.参考
---
* Vagrantとは  
https://qiita.com/tomoemon/items/d4c4fe0c5afcb2482ee8
* 15Stepで習得 Dockerから入るKubernetes コンテナ開発からK8s本番運用まで  
https://www.amazon.co.jp/15Step%E3%81%A7%E7%BF%92%E5%BE%97-Docker%E3%81%8B%E3%82%89%E5%85%A5%E3%82%8BKubernetes-%E3%82%B3%E3%83%B3%E3%83%86%E3%83%8A%E9%96%8B%E7%99%BA%E3%81%8B%E3%82%89K8s%E6%9C%AC%E7%95%AA%E9%81%8B%E7%94%A8%E3%81%BE%E3%81%A7-StepUp-%E9%81%B8%E6%9B%B8/dp/4865941614
僕のsklearn(Python)

自分用のまとめ
随時更新
自分が使った、調べたコマンドを記載
**自分がわかればいいからところどころ用語が間違ってるかも**

！見方

```python
#コマンド
    #引数のオプションの説明
```




###モジュール読み込み

```python
import sklearn
```



####k_最近傍法

```python
import sklearn.neighbors import KNeighborsClassifier

#KNeighborsClassifierクラスのインスタンス化
knn = KNeighborsClassifier(n_neighbors=x)
    n_neighbors = #何個の点の近似点から判定を行うか

#アルゴリズムにトレーニングデータを与える
knn.fit(X,y)
    X #データ
    y #ラベル

#
```
JavaのAssertionとは？まとめ。

# 概要
JavaのIntegrationTestをやったので、忘れないようアウトプットします。

#目次
1. Javaのassert文とは
2. Assert Classのメソッドたち、JUnitの説明


# 1. Javaのassert文とは
##Javaのassert文とは
 [Oracle公式ドキュメントによると](https://docs.oracle.com/javase/jp/8/docs/technotes/guides/language/assert.html)
> アサーションとは、プログラムに関する前提をテストできるようにするJavaプログラミング言語の文です。

## Assertionのライフサイクル
アサーションは**常にBoolean型**となっており、**trueを前提**としてテストをしていきます。
falseの場合、**AssertionError**をthrowします。


## カバレッジ
また、機能をテストでどの程度カバーできているかを**カバレッジ**といいます。
**カバレッジ**の質が高いほどバグが減ります。

# 2. Assert Classのメソッドたち、JUnitの説明
## assertEqual()
期待される結果と実際の結果が同じかどうか判定

```java:EqualIntegrationTest.java
/**
 * expected: 期待値
 * actual: 実際の値
 * message: メッセージ(期待値と実際の値が一致しない場合表示)
 */ 
Assert.assertEqual(expected, actual);
Assert.assertEqual(message, expected, actual);
```
## assertTrue()
与えられた条件が正しいかどうか判定する

```java:TrueIntegrationTest.java
/**
 * actual: 実際の値
 * message: メッセージ(与えられた条件が正しくない場合表示)
 */ 
Assert.assertTrue(expected > 1);
Assert.assertTrue(message, expected > 1);
```
## assertNotNull()
与えられたObjectがnullでないかどうか判定する

```java:NotNullIntegrationTest.java
/**
 * object: 期待値
 * message: メッセージ(objectがnullの場合表示)
 */
Assert.assertNotNull(object);
Assert.assertNotNull(message, object);
```
## assertNull()
与えられたObjectがnullか判定する

```java:NullIntegrationTest.java
/**
 * object: 期待値
 * message: メッセージ(objectがnullではない場合表示)
 */ 
Assert.assertNull(object);
Assert.assertNull(message, object);
```
## assertSame()
与えられた２つのObjectが同じObjectを参照しているか判定する

```java:SameIntegrationTest.java
/**
 * expectedObject: 期待値
 * actualObject: 実際値
 * message: メッセージ(objectがnullではない場合表示)
 */ 
Assert.assertSame(expectedObject, actualObject);
Assert.assertSame(message, expectedObject, actualObject);
```

## assertThat()　
基本的に比較だが、その使用方法は多岐に渡る [詳細](https://qiita.com/opengl-8080/items/e57dab6e1fa5940850a3)

#参考資料
- https://qiita.com/opengl-8080/items/e57dab6e1fa5940850a3
- https://docs.oracle.com/javase/jp/8/docs/technotes/guides/language/assert.html
テスト時のみEquatableプロトコルに準拠させる方法(Swift)

## はじめに

「製品コードでは構造体を比較しないけど、テスト時は比較したい」ということはありませんか:interrobang:

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">テストで比較するためだけにEqutableに準拠させるのはありかなぁ🤔</p>&mdash; ウホーイ (@the_uhooi) <a href="https://twitter.com/the_uhooi/status/1216361184783302656?ref_src=twsrc%5Etfw">January 12, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

`Equatable` プロトコルに準拠することで、構造体同士を `==` で比較できるようになります。

```swift:FooEntity.swift
struct FooEntity: Equatable {
    let name: String
    let age: Int
}
```

```swift:FooTests.swift
let fooEntity1 = FooEntity(name: "foo", age: 18)
let fooEntity2 = FooEntity(name: "foo", age: 24)

// `Equatable` に準拠しているため、ビルドが通る
XCTAssertEqual(fooEntity1, fooEntity2) // `age` が異なるのでテストは失敗する
```


このように製品コードで直接 `Equatable` プロトコルに準拠させる方法が考えられますが、「 __テスト時のみ比較したい__ 」という意図が読み取れません。

Twitterでテスト時のみ `Equatable` プロトコルに準拠させる方法を教えていただいたので、備忘録として残します。

## 個人的な結論：テスト時のみEquatableプロトコルに準拠させる必要はない

本題に入る前にまず私の結論を言います。
本末転倒ですが、Twitterでいろいろ意見を頂いた結果、私は製品コードで `Equatable` プロトコルに準拠させればいいと結論付けました。
理由は以下の通りです。

- `Equatable` プロトコルに準拠しても副作用がほとんどない
  - コンパイラが自動生成する `==` のコードによるオーバーヘッドくらい
- テスト時のみ `Equtable` プロトコルに準拠させる方法はどれもデメリットがある  
  - 詳しくは後述する
- 「構造体が比較できる」ことを当たり前の言語仕様と考えれば、製品に不要なコードが含まれていることにはならない
  - StringやIntも `Equatable` プロトコルに準拠しており、比較しなくても普通に使っている

## 方法①：テスト用のマクロを作る

[@_ha1f](https://twitter.com/_ha1f) さんから教えていただきました。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr"><a href="https://twitter.com/hashtag/if?src=hash&amp;ref_src=twsrc%5Etfw">#if</a> TEST<br><br>extension Foo: Equatable {}<a href="https://twitter.com/hashtag/endif?src=hash&amp;ref_src=twsrc%5Etfw">#endif</a> <br><br>はどう思いますか<br><br>（僕の中ではなしよりのあり）</p>&mdash; はるふ（冬） (@_ha1f) <a href="https://twitter.com/_ha1f/status/1216523865385361410?ref_src=twsrc%5Etfw">January 13, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

テスト用のマクロを作り、テスト時のみエクステンションで準拠させます。

```swift:FooEntity.swift
struct FooEntity {
    let name: String
    let age: Int
}

#if TEST
extension FooEntity: Equatable {}
#endif
```

これは思いつかなかったので目から鱗でした。
「テスト時のみ比較する」という意図が明確にわかります。

ただし、「 __マクロが増える__ 」というデメリットがあります。

## 方法②：テストターゲットで準拠させる

方法①のエクステンションをテストターゲット側に記述すれば、マクロが不要になります。

```swift:FooTests.swift
@testable import FooTarget

extension FooEntity: Equatable {
    public static func == (lhs: FooEntity, rhs: FooEntity) -> Bool {
        return lhs.name == rhs.name && lhs.age == rhs.age
    }
}
```

しかし、 `==` のコードを自分で実装し、 `public` にする必要があります。
（なぜその必要があるかの言語仕様までは調べていません）

これは「 __構造体に新しくプロパティを追加したときに、修正が必要になる__ 」というデメリットがあります。
修正しなくても警告やエラーが発生しないため、忘れがちになります。

## おわりに

方法①も②もデメリットがあることがわかりました。
私はできる限りテスト時のみ使うコードを製品に含めたくないので、デメリットがなければ採用していました。

Twitterで議論が広がると、自分だけでは考えつかなかったことを学べるので、とてもありがたいです。
他にご意見のある方がいらっしゃれば、遠慮なくコメントやTwitterでご連絡ください！
Python3:  Post 処理

Python のサーバーで Post のパラメーター処理がうまくいかない例です。
cgi.FieldStorage は JSON 形式の Post を処理できません。

サーバープログラム

```py:simple_server.py
import http.server
import socketserver
from http.server import BaseHTTPRequestHandler
import cgi
import sys

class PostHandler(BaseHTTPRequestHandler):
	def do_POST(self):
		sys.stderr.write("*** do_POST *** aaa\n")
		try:
			ff = cgi.FieldStorage(
				self.rfile,
				self.headers,
				environ={
				"REQUEST_METHOD": "POST",
				"CONTENT_TYPE": self.headers["Content-Type"],
				},)
			key = ff.getfirst("key","")
			sys.stderr.write("*** do_Post *** key = %s\n" % key)
		except Exception as ee:
			sys.stderr.write("*** error *** in cgi.FieldStorage ***\n")
			sys.stderr.write(str(ee) + "\n")

if __name__ == '__main__':
	sys.stderr.write("*** start ***\n")
	PORT = 8080

	with socketserver.TCPServer(("", PORT), PostHandler) as httpd:
		print("serving at port", PORT)
		sys.stderr.write("*** start ***\n")
		httpd.serve_forever()
```

サーバーの実行

```bash
python3 simple_server.py
```

クライアントからアクセス

１）POST のパラメーターが渡せるケース

```bash
curl -X POST http://localhost:8080/ -d 'key=t1855'
```

２）POST のパラメーターが渡せないケース

```bash
curl -X POST -H "Content-Type: application/json" -d '{"key":"t1855"}' http://localhost:8080/
```

サーバー側のエラー

```text
*** error *** in cgi.FieldStorage ***
write() argument must be str, not bytes
```

３）次のケースも渡せません。

```bash
curl -X POST -H "Content-Type: application/json" -d@in01.json http://localhost:8080/
```

```json:in01.json
{"key":"t1855"}
```

テストに使ったバージョン (Ubuntu 19.10)

```text
$ python3 --version
Python 3.7.5
```

次のバージョンでも同じ結果でした (Arch Linux)

```text
$ python3 --version
Python 3.8.1
```

こちらに、解決策があります。
[Python3: JSON 形式の Post を処理する方法](https://qiita.com/ekzemplaro/items/66f846cc9fcd640a9b8c)
Golang on DockerでEchoを動かす

# TL;DR

Docker上でGolangのWebフレームワークであるEchoを動かしてみました。

# DockerでGolang環境の構築

```dockerfile
FROM golang:1.13.6-alpine

WORKDIR /go/src

COPY ./src /go/src

RUN apk update && apk add git
#RUN go get -u github.com/labstack/echo/...
```

`dockerfile`内の`go get -u github.com/labstack/echo/...`が実行出来なかったのは何故だろう。。。

```docker-compose.yml
version: '3'
services:
  app:
    build: .
    ports:
      - 8080:8080
    volumes:
      - ./src:/go/src
    tty: true
```

```sh
$ mkdir src
```

```src/server.go
package main

import (
    "net/http"
    "github.com/labstack/echo"
)

func main() {
    e := echo.New()
    e.GET("/", func(c echo.Context) error {
        return c.String(http.StatusOK, "Hello, Echo World!!")
    })
    e.Logger.Fatal(e.Start(":8080"))
}
```

```sh
$ docker-compose build
$ docker-compose up -d
```

# Echoのインストール

https://echo.labstack.com/
https://echo.labstack.com/guide

```sh
$ docker-compose exec app go get -u github.com/labstack/echo/...
$ docker-compose exec app go run server.go

   ____    __
  / __/___/ /  ___
 / _// __/ _ \/ _ \
/___/\__/_//_/\___/ v4.1.13
High performance, minimalist Go web framework
https://echo.labstack.com
____________________________________O/_______
                                    O\
⇨ http server started on [::]:8080
```

<img width="1118" alt="スクリーンショット 2020-01-13 15.07.08.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123511/80d8f170-b3a5-36a9-b6f1-9fdd04d022ad.png">

出来ました:beer:
本当は`docker-compose up -d`だけでEchoの実行までいきたいんですがね。。。
brew の PHP が 7.4 に上がったら Mcrypt PHP extension required. が出たので対応

Mac OS X 10.15.2 で brew でインストールした PHP のバージョンが 7.4 に上がった際に一部のプログラムが Mycrypt PHP extension required. で動かなくなったのでその対応

# mcrypt の手動 Install

    $ wget https://pecl.php.net/get/mcrypt-1.0.1.tgz                                                                                                                                                                                                          
    $ tar zxvf mcrypt-1.0.1.tgz
    $ cd mcrypt-1.0.1
    $ phpize
    $ ./configure
    $ make 
    $ make install
    $ rm -rf ../mcrypt-1.0.1*

インストールが完了したら PHP の設定を変更する

    $ vim /usr/local/etc/php/php7.4/php.ini
    ...
    extension=mcrypt ; mcrypt を読み込むように設定
    ...

# 試したこと
あまり調べていないので単純に設定等が足りないだけの可能性もある
## pecl でのインストール
PHP7.3 利用時にインストールしていたものがすでにインストールされているということでインストールできなかった

    $ sudo pecl install channel://pecl.php.net/mcrypt-1.0.1
    pecl/mcrypt is already installed and is the same as the released version 1.0.1
    install failed

## pecl での再インストール
PHP7.2 から PHP7.3 でないとインストールできなかった

    $ sudo pecl uninstall mcrypt-1.0.1
    Extension mcrypt disabled in php.ini
    uninstall ok: channel://pecl.php.net/mcrypt-1.0.1
    $ pecl install mcrypt-1.0.1
    pecl/mcrypt requires PHP (version >= 7.2.0, version <= 7.3.0, excluded versions: 7.3.0), installed version is 7.4.1
    No valid packages found
    install failed
#Rails + #rspec / ActiveJob perform_later or deliver_later and send email difficult to test. how to resolve it?

change later  to now and test it!

```rb
it { expect { perform_enqueued_jobs { subject } }.to_not raise_error }
```

# Original by Github issue

https://github.com/YumaInaura/YumaInaura/issues/2942








<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
JavaScript勉強の記録その16: 文字列の操作

#文字列の長さを取得する

JavaScriptには文字列を操作する為の方法がいくつか用意されてありますので、メモとして書き残します。

```index.js
const str = 'hello';
console.log(str.length);
//=>5
```
#文字へのアクセス

文字へのアクセスの方法は、文字列[インデックス番号]とすることで可能です。
以下の例ではhelloという文字列の1番目と2番目にアクセスし、コンソールに表示しています。

```index.js
const str = 'hello';
console.log(str[1]);
//=>e
console.log(str[2]);
//=>l
console.log('hello'[1]);
//=>e
```
#substring()を利用して、文字列の一部を切り出す

substring()という文字列を操作するメソッドを使えば、文字列の一部を切り出すことができます。
substring(切り出しを開始したいインデックス番号、切り出しを終了したいインデックス番号)というように引数を取れば利用することができます。

具体的な使い方としては以下です。
substringメソッドの第一引数は２で第二引数を４とすることで、「ll」のみを取ることができます。

```index.js
const str = 'hello';
console.log(str.substring(2, 4));
//=>ll
```
Alexa道場やってみたわい

家にEchoがあるが実際のところ音楽聞いたり天気予報確認することくらいでしか使っていない。
Alexaのスキルってどんなのあるのかな？と軽く調べてみた。
Alexaアプリのスキル一覧から各ジャンル毎にスキルの確認できる。
良くも悪くも、まぁこんなもんかって感じ。

既存のアプリどうこうは置いておいて
とりあえず何でもいいから作ってみてたら
ちょっとは息子が褒めてくれるかも。

息子に、「パパ、スゴイ」って言ってほしい。

よし、Alexa Skillやってみよう。
ということでチュートリアル的なのないかなと探していたら公式で動画があったので
それに沿って手を動かしてみることにしました。
https://developer.amazon.com/ja-JP/alexa/alexa-skills-kit/webinars

# Season1 はじめてのAlexaスキル開発

 - Episode1:スキル開発の準備をしよう
 - Episode2:ハローワールドスキルを作ってみよう
 - Episode3:スキルをテストしてみよう

## Episode1:スキル開発の準備をしよう

**動画**
https://www.youtube.com/watch?v=KlU907D0ahY&feature=youtu.be

 - amazon.co.jpのアカウントがなければ作成
 - 開発者アカウントの作成
 - Alexa開発者ポータルサイトの確認

ここではアカウント作成と開発者ポータルなどのページを確認するだけ。

## Episode2:ハローワールドスキルを作ってみよう

**動画**
https://www.youtube.com/watch?v=nkzhxoOr0p8&feature=youtu.be

 - カスタムスキルを作成する
 - Alexaシミュレーターでテストする
 - デベロッパーコンソールからスキルを作成しスキルのモデルとホスト先を選択する。

Alexaホストを選択しないとデベロッパーコンソールからエディタが使えないとのこと。

動画だと、ホスト選択でAlexaホストの選択が一つだけだがNode.jsがPythonかで選べるようになっていた。
今回も動画がNode.jsなのでNode.jsを選択。

画面上のシミュレーターを使って対話式のテストが出来る。
この時点では「ハローワールドを開いて」って入力するとアレクサから英語でゴニョゴニョ返してくれます。

## Episode3:スキルをテストしてみよう

**動画**
https://www.youtube.com/watch?v=dRYtYQy5S6k&feature=youtu.be

 - 日本語に修正する
 - Echoデバイスでテストしてみる

Episode2ではAlexaが英語で応答してくれるが、これを日本語に変更します。
デベロッパーコンソールに付いているコードエディタにスキルのスクリプトが書いてあるので、英語で記載している部分を日本語に変更する。

```py
    def handle(self, handler_input):
        # type: (HandlerInput) -> Response
        speak_output = "ようこそハローワールドへ。ハローと言ってみて？"

        ...

    def handle(self, handler_input):
        # type: (HandlerInput) -> Response
        speak_output = "こんにちわ。"

        ...
```
そう、これだけでAlexaが日本語で応答してくれます。
スキル作成しただけでスクリプトも書いてあってビルドとデプロイもポチってやるだけだし、自然言語も書き直すだけだし、ええ、そう、まさに至れり尽くせり。

対話形式で入力するとAlexaが応答してくれるが、入力をテキスト入力ではなくマイクから音声入力することも出来る。
入力インプットのところにマイクアイコンがあるので押しながら話すと応答してくれます。

さて、ここまでは、フムフムと言った感じで進めているのですが
なんと、Echoデイバイスをお持ちの方はこの時点でEchoを使ってハローワールドを試せます。
※Alexaアプリのスキルから有効なスキルに遷移して開発スキルのタブを開くと今回追加したハローワールドが追加されているはずです。

おそるおそるEchoデバイスに近づき「アレクサ、ハローワールドを開いて」と呟いてみました。

アレクサ「ようこそハローワールドへ。ハローと言ってみて？」

私「！！！　。。。ハロー」

アレクサ「こんにちわ」

私「まじか。。。。簡単すぎないかい、ちょっと」

次回は「Season2 Alexaスキル開発の基礎を学ぼう」をやります。
PythonでPLCのレジスタアクセスを試す

[SLMP](https://www.cc-link.org/ja/cclink/slmp/index.html)でPLCレジスタのリード/ライトを試します。
バイナリコードでのビットアクセスについては[こちらの記事](https://qiita.com/satosisotas/items/eb867d2a71a8cf1f8e3e)に書きました。

## 接続

まずPLCとコネクションを張ります。

```python
HOST = '192.168.1.1'
PORT = 1026
BUFSIZE = 4096

import socket

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((HOST, PORT))
sock.settimeout(3)
```

## 基本パラメータ

SLMPの要求伝文に設定する基本パラメータです。

### アクセス先設定

ホストPCと直接Ethernet接続されているPLCのCPUユニットレジスタを読みます。
この場合、SLMPの規定によりPLCアクセス先の設定は下記のようにします。

項目 | 値
---  | ---
要求先ネットワーク番号 | 00h
要求先局番 | FFh
要求先ユニットI/O番号 | 3FFh
要求先マルチドロップ局番 | 0

### 監視タイマ

監視タイマは250ms単位で設定します。今回は 4 (1秒) に設定します。

### デバイスコード

今回はデータレジスタを使用します。ワードアクセスです。
ASCIIコードででは "D*"、バイナリコードでは A8h となります。

## リード

要求伝文を組み立ててフレームを送信します。
Readコマンド(0401h)のワードアクセスとします。

バイナリコード時には、サブヘッダ以外はリトルエンディアンで値を格納する必要があります。
サブヘッダだけは何故かビッグエンディアンなので気を付けましょう。

D0001 ～ D0003 の3つのレジスタの値を読み込みます。

```python
# '5000 00 FF 03FF 00 0018 0020 0401 0000 D* 000001 0003'

data = [
    0x50,0x00,      # サブヘッダ
    0x00,           # 要求先ネットワーク番号
    0xFF,           # 要求先局番
    0xFF,0x03,      # 要求先ユニットI/O番号
    0x00,           # 要求先マルチドロップ局番
    0x0C,0x00,      # 要求データ長 (後で設定)
    0x20,0x00,      # 監視タイマ
    0x01,0x04,      # コマンド
    0x00,0x00,      # サブコマンド
    0x01,0x00,0x00, # 先頭デバイス番号
    0xA8,           # デバイスコード
    0x03,0x00       # デバイス点数
]

# 要求データ長を設定
data[7] = len(data[9:]) & 0xFF
data[8] = (len(data[9:]) >> 16) & 0xFF

# 要求送信
sock.send(bytes(data))

# 応答受信
res = sock.recv(BUFSIZE)
print (*[format(i,'02X') for i in res])
```

受信データは下記のようになります。
現在のレジスタ値はすべて 0 でした。

```
D0 00 00 FF FF 03 00 08 00 00 00 00 00 00 00 00 00
```

## ライト

要求伝文を組み立ててフレームを送信します。
Writeコマンド(1401h)のワードアクセスとします。

D0000 ～ D0004 の5つのレジスタに値を書き込みます。

```python
# '5000 00 FF 03FF 00 0018 0020 0401 0000 D* 000000 0005 1122 3344 5566 7788 99AA'

data = [
    0x50,0x00,      # サブヘッダ
    0x00,           # 要求先ネットワーク番号
    0xFF,           # 要求先局番
    0xFF,0x03,      # 要求先ユニットI/O番号
    0x00,           # 
    0x00,0x00,      # 要求データ長 (後で設定)
    0x04,0x00,      # 監視タイマ
    0x01,0x14,      # コマンド (1401H)
    0x00,0x00,      # サブコマンド
    0x00,0x00,0x00, # 先頭デバイス番号
    0xA8,           # デバイスコード
    0x05,0x00,      # デバイス点数
    0x11,0x22,      # D0000
    0x33,0x44,      # D0001
    0x55,0x66,      # D0002
    0x77,0x88,      # D0003
    0x99,0xAA,      # D0004
]

# 要求データ長を設定
data[7] = len(data[9:]) & 0xFF
data[8] = (len(data[9:]) >> 16) & 0xFF

# 要求送信
sock.send(bytes(data))

# 応答受信
res = sock.recv(BUFSIZE)
```

ライト完了後、先ほどのReadコマンドを再度実行すると、実行結果は下記のようになります。

```
D0 00 00 FF FF 03 00 08 00 00 00 33 44 55 66 77 88
```

正しく書込みと読み出しができていることが分かります。

## コネクション切断

```python
sock.close()
```
[Rails] rails db:migrate してもなぜかmigrationファイルが無視されるとき

# Versions

```bash
$ ruby -v
ruby 2.5.5p157 (2019-03-15 revision 67260) [x86_64-linux]
$ bundle exec rails -v
Rails 5.1.7
```

# 症状

こういうことが起きた。

まず、migrateされていないmigrationファイルがあることを確認。

```bash
$ bin/rails db:migrate:status

database: database名

 Status   Migration ID    Migration Name
--------------------------------------------------
   up     20200101xxxxxx  Devise create users
              ...(略)
  down    20200101xxxxxx  Drop users
```
OK！（｀・ω・´）

では、migrateしよう。

```bash
$ bin/rails db:migrate
Model files unchanged.
```

ほう....何も変わらないと。
では、再度migrate状況を確認しよう。

```bash
$ bin/rails db:migrate:status

database: database名

 Status   Migration ID    Migration Name
--------------------------------------------------
   up     20200101xxxxxx  Devise create users
              ...(略)
  down    20200102xxxxxx  Drop users
```

終わってないじゃないかあぁぁああorz

# 対策

`db:migrate:redo` で解決した

```bash
$ bin/rails db:migrate:redo VERSION=20200102xxxxxx
Model files unchanged.
== 20191125071019 DropUsers: migrating ============================
-- drop_table(:users)
   -> 0.0046s
== 20191125071019 DropUsers: migrated (0.0047s) ===================
```

なんなんじゃい！！(´;ω;｀)

# 発生状況

同じmigrationファイルに対してrollbackとmigrateを何度も繰り返していたら発生した。
migrationファイル自体の書き換えも発生していた。
もしかしたら、railsで管理している内部データか何かが壊れたのではないかと疑っている。

面倒なので詳細は掲載しませんが、migrate:statusの結果とDB本体（mysql）のテーブルの状況は正しく一致していました。
Flaskチュートリアル（インストールからhello worldまで）

# はじめに
FlaskでHello worldをするための、備忘録です。

## 作業ディレクトリの作成
```bash
mkdir flask-tutorial
cd flask-tutorial
```

## Pythonの仮想環境作成 & アクティベート
```bash
python3 -m venv venv
source venv/bin/activate
```


## Flaskのインストール
```bash
pip install flask
pip freeze
```

## メインファイルの作成
```python:app.py
from flask import Flask
app = Flask(__name__)

@app.route('/')
def hello():
    return 'Hello world'

if __name__ == "__main__":
    app.run(debug=True)
```

## 実行
```bash
python3 app.py
```
自分用のアウトプット

マイグレーションファイルで困った時の解決策を自分なりのアウトプットでまとめます

①マイグレーションファイルは
　createコマンドが先に来るように作成すること

　例えば
　create_brandは１番目に来るように作成
　もし、ブランドのマイグレーションファイルに対し、何か加えるようなファイルを作成する
　場合はcreate_brandのマイグレーションファイルより後になるようにマイグレーション
　ファイルを作る
　例
　１番目：(2020〜)_create_brand　
　２番目：(2020〜)_add_brand_to_create
　３番目：〜

②マイグレーションファイルは日付を変えることで順番を変えることができる
PythonでABC151のA~Cを解く

### はじめに
レートが少しあがりました。今回は、A,Bしか解けませんでした。

### A問題
[問題](https://atcoder.jp/contests/abc151/tasks/abc151_a)

**考えたこと**
入力されたアルファベットをasciiに変換して1を足して、戻してprintすればいい。
前に似たような問題を解いた時は、zが出てきたのでif文を使ったので今回も同じような問題だと思って遅れた。

```python
c = ord((input()))

print(chr(c+1))
```

### B問題
[問題](https://atcoder.jp/contests/abc151/tasks/abc151_b)

**考えたこと**
それぞれの教科の合計点数とMの差で分ける。

```python
n, k, m =map(int,input().split())
a = map(int,input().split())

score = 0
for i in a:
    score += i
if (score + k) / n < m:
    print(-1)
elif (m*n - score) < 0:
    print(0)
else:
    print(m*n - score)
```

### C問題
[問題](https://atcoder.jp/contests/abc151/tasks/abc151_c)

**考えたこと**
時間内に解けませんでした。TLEになってしまった。
ACした問題のWAをカウントしない、WAした問題でもACしていなかったらカウントしないという条件をうまく実装できなかった。

```python

import collections
n, m =map(int,input().split())
p = []
for i in range(m):
    p.append(input().split())
 
del_l = []
for j in range(m):
    if p[j][1] == 'AC':
        del_l.append(p[j][0])
        p[j][0] = 'pass'
        p[j][1] = 'pass'
    if p[j][1] =='WA' and p[j][0] in del_l:
        p[j][0] = 'pass'
        p[j][1] = 'pass'
pen = 0
for s in range(m):
    if p[s][1] == 'WA' and p[s][0] in del_l:
        pen += 1
print(len(collections.Counter(del_l)),pen)
```

自分の力では、なんでTLEになってるか分からなかったので、[ryuki](https://twitter.com/e145755)氏に教えてもらった。感謝

TLEしていた理由は、p[j][0] in del_lの$in$で計算量が増えているらしい。
そして、ACしているかはWA or ACなのでboolで書ける。という色々なアドバイスを貰ってACできました。

```python

n, m = map(int,input().split())
a = [input().split() for i in range(m)]
p = [int(i[0]) for i in a]
q = [j[1] for j in a]

ac = 0
wa = 0
wa_c = [0] * n
ac_c = [False] * n

for t in range(m):
    if ac_c[p[t]-1]:
        continue
    if q[t] == 'AC':
        ac += 1
        ac_c[p[t]-1] = True
        wa += wa_c[p[t]-1]
    else:
        wa_c[p[t]-1] += 1
print(ac,wa)
```

###まとめ
初めてTLEが原因でACできなかったので、これからは計算量を意識したように書けるようになりたい
学校のテストがやばい
[Archlinux]Macbook Air(5,1)の内蔵Wi-Fiの設定

しばらくMacbook AirにArch Linuxを入れて使っていて、以前はwifiは使えていたが、なぜか1Mbpsくらいしか速度が出なかった。

今回クリーンインストールして、wifiのセットアップをやり直していたら、ちゃんと使える設定を見つけたので備忘録。

NetworkManagerの環境。

ハードウェアの情報

```
$ lspci -nn -vv |grep Broadcom
02:00.0 Network controller [0280]: Broadcom Inc. and subsidiaries BCM43224 802.11a/b/g/n [14e4:4353] (rev 01)
```



ドライバはb43を使う。

```
yaourt -S b43-firmware --noconfirm  #b43をインストール

sudo rmmod brcmsmac  #デフォルトのwifiモジュール無効 
sudo rmmod mac80211 bcma brcmutil  #付随モジュール無効

sudo modinfo b43 | grep depends  #b43に必要なモジュールを調べる
sudo modprobe b43 mac80211 ssb bcma mmc_core cfg80211 cordic rng-core
reboot
```

見事に上下で100Mbps程度出るようになった。




参考先
https://is.gd/6YiNwJ
#AzureAutomation のログを #AzureMonitor（Log Analytics）と統合する際に発生したエラー（microsoft.insights 未登録）を解消する

# 初めに
Azure Automation を利用して運用作業の自動化を検討していたが、自動実行された PowerShell が正常終了したかどうかの判断がつかなかったため、Log Analytics を利用した検知機能を設定しました。
設定の際に、「Set-AzDiagnosticSetting」というコマンドで Azure Automation のログを Azure Monitor と統合する設定を行うわけですが、microsoft.insights が登録されていないというエラーが発生しました。microsoft.insights を登録することでエラーは解消したため、その手順をまとめたいと思います。

Azure Automation のエラーをLog Analyticsで検知する手順については以下記事を参考にしてください。

# 参考にした記事・サイト
[Azure AutomationのエラーをLog Analyticsで検知する(Qiita)](https://qiita.com/shingo_kawahara/items/724452276dc1a9dd37e9)
[Automation から Azure Monitor ログにジョブの状態とジョブ ストリームを転送する(MSドキュメント)]
(https://docs.microsoft.com/ja-jp/azure/automation/automation-manage-send-joblogs-log-analytics)
[Configuring Network Security Group Flow logs with PowerShell]
(https://docs.microsoft.com/bs-latn-ba/Azure/network-watcher/network-watcher-nsg-flow-logging-powershell)

# 環境
- Azure Automation 
- Azure Monitor （Log Analytics）
- Office 365 開発者プログラム → 今回の手順には直接関係ありません
- Microsoft.Online.SharePoint.PowerShell 16.0.19515.12000 → 今回の手順には直接関係ありません
- SharePointPnPPowerShellOnline 3.16.1912.0 → 今回の手順には直接関係ありませ

# 発生したエラー
```
 Set-AzDiagnosticSetting : Exception type: ErrorResponseException, Message: The subscription '<サブスクリプションID>' is not registered to use microsoft.insights., Code:
  SubscriptionNotRegistered, Status code:BadRequest, Reason phrase: Bad Request
 発生場所 行:1 文字:1
 + Set-AzDiagnosticSetting -ResourceId $automationAccountId -WorkspaceId ...
 + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     + CategoryInfo          : CloseError: (:) [Set-AzDiagnosticSetting]、PSInvalidOperationException
     + FullyQualifiedErrorId : Microsoft.Azure.Commands.Insights.Diagnostics.SetAzureRmDiagnosticSettingCommand
```
メッセージにある通り、microsoft.insights が登録されていないのが理由なのですが、通常、microsoft.insightsって最初から登録されてるものじゃないんですかね？
ネットで調べながら、microsoft.insights を登録する以下の手順を実施しました。

# 登録されているプロバイダ一覧を取得する
```powershell
Get-AzResourceProvider -ListAvailable | Select-Object ProviderNamespace, RegistrationState
```
未登録の場合、以下が表示される
```microsoft.insights                     NotRegistered
```

# microsoft.insights をプロバイダとして登録する → 正常に登録完了
```powershell
Register-AzResourceProvider -ProviderNamespace microsoft.insights
```

# 再度、登録されているプロバイダ一覧を取得する
```powershell
Get-AzResourceProvider -ListAvailable | Select-Object ProviderNamespace, RegistrationState
```
登録が完了すると Registerd となる
登録済み
```microsoft.insights                     Registered```

以下は登録中の状態。しばらくたってから再度確認する
```microsoft.insights                     Registereding```

# エラーとなったコマンドを再度発行する
```powershell
Set-AzDiagnosticSetting -ResourceId $automationAccountId -WorkspaceId $workspaceId -Enabled 1
```
NuxtでVuex  を使いかた覚えるために作ったもの

Vueで書かれている本をNuxtに書き換えたときのメモ
NuxtやVue関してあまり詳しくないのでもっといい方法あれば教えて欲しい

リアルタイムで入力した値がVuexを通して変換するものを作りました。

まずファイル構成はこんな感じ　
<img width="181" alt="スクリーンショット 2020-01-13 13.54.52.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356197/12b78621-ccac-97f2-540c-74c93f026b2a.png">
<img width="179" alt="スクリーンショット 2020-01-13 13.55.12.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356197/285b6a06-b1fb-78a8-c23a-16a6be378841.png">

###pages/index.vue

```
.<template>
  <div>
    {{message}}
    <EditForm />
  </div>
</template>

<script>
import EditForm from "./component/EditForm";

export default {
  computed: {
    message() {
      return this.$store.state.store.message;
    }
  },
  components: {
    EditForm
  }
};
</script>

```


###pages/component/index.vue
```
<template>
  <div>
    <input :value="message" @input="doUpdate" />
  </div>
</template>

<script>
export default {
  computed: {
    message() {
      return this.$store.state.message;
    }
  },
  methods: {
    doUpdate(event) {
      this.$store.dispatch("store/doUpdate", event.target.value);
    }
  }
};
</script>

```
###store/store.js

```

export default {
    name: 'store',
    state: {
        message: 'Hello Vue.js'
    },

    // 
    mutations: {
        setMessage(state, payload) {
            state.message = payload.message
        }
    },

    actions: {
        doUpdate({ commit }, message) {
            commit('setMessage', { message })
        }
    }
}
```


##メモ（つまずいたところ）
 this.$store.dispatch("store/doUpdate", event.target.value);
の部分本ではdoUpdateのみになっているがこの書き方にせねばならん
Perlで warning: Setting locale failed. と警告された時の対処

Ubuntuでperlを動かしたときに以下のような警告が表示されてしまう場合の対処方法です。

```
perl: warning: Setting locale failed.
perl: warning: Please check that your locale settings:
        LANGUAGE = (unset),
        LC_ALL = (unset),
        LANG = "en_US.UTF-8"
    are supported and installed on your system.
perl: warning: Falling back to the standard locale ("C").
```

ググると対処方法がいくつか出てきます。

- `locale-gen` を実行すれば治る
  [Perl warning Setting locale failed in Debian - Thomas-Krenn-Wiki](https://www.thomas-krenn.com/en/wiki/Perl_warning_Setting_locale_failed_in_Debian)
- `/etc/sysconfig/i18n` を修正すれば治る
  [sshでログインした時、localeまわりでエラーが出た場合の対処法 - Qiita](https://qiita.com/rm-rf-slant/items/ae84ffa8e61c054320fd)
- `/etc/ssh/ssh_config` を修正すれば治る
  [UbuntuやDebianでperl: warning: Setting locale failed.と怒られる問題を解決する - Qiita](https://qiita.com/networkelements/items/12e2448b75f7ff057139)

私の場合は、以下を実行したら治りました。

```sh 
$ sudo apt install locales-all
```

Ubuntuのバージョンは19.10です。本記事は2020年1月投稿です。

# 2021/03/08追記

DockerのCentOS 8でも同じことが起きました。以下で解決しました。

```sh
$ sudo yum install -y glibc-langpack-en
```

日本語ロケールなら `glibc-langpack-ja` だと思います。
初めてのQiitaで自己紹介(テスト投稿)

#初めてのQiita
初めてQiitaに投稿します。　テスト投稿です。
##自己紹介
現在大学一年生の**りょうた**といいます。趣味は将棋です。
よろしくお願いします。
##プログラミングについて
大学で情報工学を専攻しています。　
プログラミングを始めたのは大学生になってからで、初心者です。
###Python
機械学習やWebアプリケーションに興味を持ったのでPythonで、プログラミングデビューしました。
PyQで勉強中です
###競プロ
大学の授業で紹介されていて興味を持ったのでAtCoderを始めました。
ABC151(1/12)でデビュー
参加回数 **１**
現在レート **６** （笑）
##Qiita
Qiitaにはプログラミングのことや競プロのことを投稿しようと思います。
##さいごに
今後は、Qiitaでも情報共有出来たらうれしいです！
Qiitaもプログラミングも頑張りますのでよろしくお願いします。
つたない初投稿を読んでいただきありがとうございます。
閏年を含む経過年数と経過月数の計算

ライブラリ依存のため、競技プログラミングでは出る類の問題ではないが、メモ。

- 補足(2020/1/13)

```Python
dd = relativedelta(end, begin)
delta_years =  dd.years
delta_months = dd.months
```
でいいらしいです。

- 以下、前の記事

```
01.01.2000
01.01.2016
という入力から
16 years, total 5844 days
```

という出力を得たい。まず、daysに関しては非常に容易で、datetime.datetimeを引き算すればよい。
ただ、datetimeの引き算で得られるtimedeltaはdaysを持つものの、monthは持たない。
加えて、dateimte自身も、daysの足し算はできるものの、月単位の加減算はできない。

# 解法1:


# 解法2
`dateutil.relativedelta`をつかうことで、月単位の加減算を行える。この結果はdatetimeに保存されるので、例えば、以下のように実装できる。

```Python
import sys
import math
from dateutil.relativedelta import relativedelta

# 入出力処理とdatetime化
import datetime
begin = input()
end = input()
bd, bm, by = map(int, begin.split("."))
b = datetime.datetime(year=by, month=bm, day=bd)
ed, em, ey = map(int, end.split("."))
e = datetime.datetime(year=ey, month=em, day=ed)

# delta daysは簡単に得られる
dt = e - b
resd = dt.days

# relativedeltaを使い、「月の差分」を得る
deltamonth = 0
while True:
    b = b + relativedelta(months=1)
    if b <= e:
        deltamonth += 1
        continue
    break

# 年は必ず12月なので、月と年に分ける。
resy = deltamonth // 12
resm = deltamonth % 12


# ここは問題より複数形と単数形を区別する処理
res = ""
if resy > 0:
    if resy == 1:
        res += "1 year, "
    else:
        res += "{0} years, ".format(resy)

if resm > 0:
    if resm == 1:
        res += "1 month, "
    else:
        res += "{0} months, ".format(resm)

if resd == 1 or resd == 0:
    res += "total {0} days".format(resd)
else:
    res += "total {0} days".format(resd)

print(res)
```
情報処理安全確保支援士試験(SC)を受験&合格しての感想。

<img width="180" alt="_i_icon_12593_icon_125930_256.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237882/2a508a98-974f-2b38-ed60-1599ab85a8b0.png">

# はじめに
2019年秋期試験で、[情報処理安全確保支援士試験(SC)](https://www.jitec.ipa.go.jp/1_11seido/sc.html)受けました、受かりました。

毎回IPAの試験に受かったら記事を書くことにしているので、受験までの準備と、受けてみての感想を書きます。
個人の感想です。

# 受験理由
~~会社から奨励金でる。お金欲しい。~~
自分の力試しをしようと思ったからです。

# バックグランド
とあるWebシステムのインフラ運用を主にやってます。
IPAの試験は割と受けています。直近だと、

- 2018年 秋期
    - [ギリギリでネットワークスペシャリスト試験 (ネスペ) に一発合格した私の勉強方法](https://qiita.com/tr_ikym/items/8eb9010d066f4bfdd541)
- 2019年 春期
    - [2回目で合格したデータベーススペシャリスト試験 (デスペ) のFAQ式振り返り](https://qiita.com/tr_ikym/items/aca3a6a42940252730f0)
- 2019年 秋期
    - 本記事

# 勉強方法
他の試験と被ってしまったので、3週間くらい前から問題解き始めました。
使用した問題集はこちら。
<img width="200" alt="IMG_3483.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237882/8340e3ce-d6e6-2061-4c41-ac71fd63b977.jpeg">

２回は解いたかな？
それ以外にも、HPで過去問をときました。

- https://www.jitec.ipa.go.jp/1_04hanni_sukiru/_index_mondai.html

最近は、いかにお金を使わずに勉強するか、がひとつのテーマにもなっています。(笑)
時間測って過去問解く、分からなかったこと調べる、の繰り返しだけやりました。

# 勉強時間
- 平日は1時間強
- 休日は3時間くらい

# 結果
受かりました。
9割とはいかずとも、それなりに余裕を持って合格することができました。
<img width="300" alt="IMG_3484.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237882/d4ea2f2f-edc6-cd25-b2ae-4ce4a03cb0f1.jpeg">
(なんで午後Iだけ悪かったんだろうか・・・)

# 感想
## 割と簡単だった印象
後述するように暗記すべき内容も少ないですし、問題を解くのに時間がかかるといったこともありませんでした。情報処理安全確保支援士と関連するような業務経験があれば割と楽に感じるのではないでしょうか？

現に[統計資料](https://www.jitec.ipa.go.jp/1_07toukei/toukei_r01a.pdf)を見ると、令和元年度秋期だと、合格率は19.4%あったみたいです。同年度秋期ネスぺが14.4%、同年度春期デスペも14.4%と、やや合格率は高いですね。

## 問題設定が面白かった(笑)
問題文読んでいるだけで「いやいや、そんな設定したらあかんやんwww」みたいな箇所が多々あるので、問題解いてて面白いと感じることが多かったです。まあそれを見つけれるための試験でもあるわけですが。

例：WEBシステムのDBエンドポイントがパグリックにオープン

## 覚えることは少なかった
自分が先にデスペやネスぺを受けていたからかもしれませんが、暗記はほとんどありませんでした。問題文から設問の意図さえ読めればなんとかなりそう、って感じですかね。

## 時間余らせて退席する人多かった印象
比較的簡単と言われる情報処理安全技術者試験、試験中にキョロキョロできないので退席っぽい音を耳で聞いた範囲ですが、試験を早めに終わらせて退席する人は多かった印象です。自分も午後Ⅱ試験は、30分くらい早く退席しましたね。

## 受験会場に若い人は少なかった印象
印象でしかないのですが、比較的若い人は少なかったように思います。
実際、統計をみても受験の平均年齢は38歳くらい。
基本情報や応用情報を除けば、そんなに平均年齢は他試験と変わりませんがね。
ともかく若い人には人気ないんですね。

<img width="280" alt="test_shiken_man.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237882/dcab0129-8c63-0665-e24b-decc9cab92d0.png">

# 最後に
試験勉強で使用した本はメルカリで売りました。
書き込みやら一切しなかったので。

そして、試験に受かったので登録セキスペになるかどうか、、、。多分登録はしませんね。