OmniAICreator/Qiita-1.07M huggingface dataset:
ComposerでSlim4を導入

#はじめに
普段PHPで開発を行っていますが、しばらく前からSlim3というフレームワークで開発を行うようになりました！
前回はComposerとXamppの導入を行ったので、今回はフレームワークを入れて、PHPが組める環境にしていきます。

##目次
・実行環境
・環境構築
　- Xampp、Composerの用意
・Slim4導入
　- env作成(設定ファイル)
　- DB接続設定
・Xampp実行(WEBサーバー、DBサーバー)
・初期設定
・動作確認


##実行環境
・Windows
・Composer
・Xampp（Apache,Mysql）
・Slim4
ネットにつながるWindowsPC1台で完結します！

##環境構築
今回以下のディレクトリ配下で作業することを想定しています。
C:\demo\slim4
上記のディレクトリを事前に作成し、PowerShellで開いておいてください。
プロジェクト作成後は
C:\demo\slim4\my-app
がルートディレクトリになります。（my-appは自動作成です。）

###Xampp、Composerの用意
前回の記事でXamppとComposerを導入しています。
もし入れていなければそちらをご覧ください。

##Slim4導入
早速Slim4を入れていきます。
ただ一からフレームワークの部品をすべて作成していくと非常に手間がかかるので、
Skeletonを使用して作成していきます。
今回は
odan/slim4-skeleton
というものを使用していきます。
以下のコマンドを実行してください。

```
composer create-project odan/slim4-skeleton my-app
```

ルートディレクトリの下に
my-app
という名前でプロジェクト作成されました。
ではファイルを編集していきます。

###env作成(設定ファイル)
configフォルダの下にある
env.example.php 
をコピーして
env.php
を作成してください。

###DB接続設定
env.phpを開いて、
DBの接続設定を編集します。
ですがXamppを入れた人はここでは設定の記述はデフォルトで問題ないと思います。

```
// Database
$settings['db']['database'] = 'test';
$settings['db']['username'] = 'root';
$settings['db']['password'] = '';
```

##Xampp実行(WEBサーバー、DBサーバー)
PC下部の検索バーでXamppを検索し、Xampp Control Panel を実行します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172553/b320013d-de26-b3b3-359e-e6f7d3828491.png)

コントロールパネルを実行したら以下のようなウィンドウが開くので、
まずはWebサーバーの設定をします。
Apacheの列のConfigからApache(httpd.conf)を開きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172553/84f3ae9a-fcb7-47cf-b5c1-9acbe999bae2.png)

httpd.confというテキストが開くので、
以下編集していきます。
既にDocumentRootという記述があるので編集します。

```
DocumentRoot "C:\demo\slim4\my-app\public"
```
これはlocalhostにアクセスしたときの参照先の設定になります。

また、以下をファイル最下段に追記します。

```
<Directory "C:\demo\slim4\my-app">
    Options Indexes FollowSymLinks Includes ExecCGI
    AllowOverride All
    Require all granted
</Directory>
```
これを記述することによりプログラムからDirectoryに記述したフォルダにアクセスすることができるようになります。
設定できたらWebサーバーを起動します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172553/ef55ee30-23a6-8a65-0761-f302890cc140.png)

DBサーバーも起動します。
DBサーバーは特に設定の変更は必要ありません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172553/9d916710-c1fc-578c-f1af-a485a1807b98.png)

##初期設定
プロジェクトの作成とWEBサーバー、DBサーバーの作成が済んだら初期設定を実行します。
プロジェクトのルートディレクトリ（C:\demo\slim4\my-app）で以下を実行します。

```
composer migrate
```
自動で初期設定が完了するのでアクセスしてみましょう！

##動作確認
ブラウザを開いて、
http://localhost/
にアクセスします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/172553/96dbead9-2837-4d31-2c33-ba7ff46d8b66.png)
こんな画面が出ていたら導入に成功しています。

OKを押下すると画面にアクセスできます。
時刻が表示されていることや
Usersなどアクセスしてみてください。
DBに接続できているはずなので、DB接続のツール等（MySQL Workbench等）でテーブルをいじることができればユーザーを追加してUsers画面で確認できると思います。

次回はこのSkeletonにページを作成したいと思います！
Django#2（テンプレート）

# Djangoでテンプレートを使う

とりあえずの設定。以下のファイルを編集する。

- アプリ/views.py
  - views.py内で定義した関数（ビュー関数）からテンプレートファイルを呼び出し、HTTPレスポンスを返す
- config/settings.py
  - テンプレートファイルの置き場所を設定する
- template/テンプレート.html
  - 実際のテンプレートファイル（ファイル名、サブディレクトリは任意）

## ビュー関数を書く

とりあえずhelloに対応する内容。

```python/app_name/views.py
from django.shortcuts import render  # render(request, 'hello.html', context)
from django.http import HttpResponse  # HttpResponse('Hello, World !!')
from django.shortcuts import render
from django.views import View

class HelloView(View):
    def get(self, request, *args, **kwargs):
        context = {
            'message': "Hello World! from View!!",
        }
        return render(request, 'hello.html', context)

hello = HelloView.as_view()
```

render関数がテンプレートを呼び出してHTMLを生成する関数。

- 第1引数のrequestはとりあえず書いておく。
- 第2引数'hello.html'でテンプレートファイルの指定。templates/フォルダ以下の相対パス指定。
- 第3引数contextはテンプレートに渡す変数の辞書。
  - テンプレートファイルの中ではキーを変数名として値を参照できる。
  - テンプレートファイル名では柔軟な変数の追加、変更はできないので、基本contextに全部詰め込む。

最後の`hello = HelloView.as_view()`はHelloViewクラスをhelloビュー関数として紐づける操作。
この関数名はurls.pyで設定する関数名と対応させる。

## テンプレートの置き場所を設定する

テンプレートファイルのベースになる場所を設定する。
下記は`プロジェクトフォルダ/templates/`に設定。

```diff:config/settings.py
57c58
<         'DIRS': [],
---
>         'DIRS': [os.path.join(BASE_DIR, 'templates')],
```

## テンプレートファイルを用意する

上記の`config/settings.py`に記載したディレクトリを作って
その中にテンプレートファイルを作成する。

```bash
$ mkdir templates
$ vi templates/hello.html
```

テンプレートファイルの内容。今回は`message`という変数を表示するだけ。
詳細な書き方は下記。
[The Django Template Language \| Django ドキュメント \| Django](https://docs.djangoproject.com/ja/2.1/ref/templates/language/)

```html:templates/hello.html
{{ message }}
```

## 動作確認

WEBブラウザでhttp://IPアドレス:8000/app_name/で
`Hello World! from View!!`と表示されればOK
NAS-Bench-101 : NASの再現性の為に

# はじめに
- 自己紹介：UbuntuでPythonを書いてデータ分析とか異常検知してます。
- AutoMLの一つであるNAS(Neural Architecture Search)に興味があります。
- 「NAS-Bench-101: Towards Reproducible Neural Architecture Search」を翻訳しました。
- https://arxiv.org/abs/1902.09635
- https://www.automl.org/nas-bench-101-towards-reproducible-neural-architecture-search/
- イイネと思ったらぜひフォロー, thumbs-up&拡散をお願いします！


# 目次
- イントロ
- NAS-Bench-101のしくみと実例


# イントロ
NAS研究には大量の計算機資源が必要(初期のNASはGPU800台で28日とか掛かっていた)で、大企業以外は研究に参加すらできないし、大企業にしても実験を何度も繰り返すのは困難でした。
しかし、科学的な厳密さのためには、何度も実験を行い、結果の安定性と統計的な有意性を評価することが必要不可欠です。([NAS研究のベストプラクティス][1]も参照して下さい)
そこで、この問題を解決するために、計算資源をあまり使わずにNASの実験ができるベンチマークを作り、OSSとして公開しました。

# NAS-Bench-101のしくみと実例
細かく区分した探索空間(small cell search space)を徹底的に評価してテーブルに保存しました。
GPUで計算する代わりにそのテーブルの値を参照することで、
今まで数時間掛かっていたNNの学習が数秒で終わります。
4種類のエポックで、3回の実験を繰り返し、42万種類の構造を評価しました。
これにより、Hyperband や BOHBなどのmulti-fidelityなoptimizerを評価することができました。

![NAS-Bench-101-eval-labelled.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/331449/ffcb4eae-befb-99ec-31d1-b44393b2191c.png)
上図:NAS-Bench-101での、NASおよびHPOアルゴリズムの評価。

図の通り、(ベイズ最適化等の)古典的なHPOアルゴリズムも評価することができます。
ランダムサーチ<強化学習<regularized evolution=ベイズ最適化(SMAC, BOHB)と評価できます。

RL(2017)がSMAC(2011)に負けているのは驚くべきことかもしれませんが、要するに当時はこれらを簡単&低コストで比較できるベンチマークがなかったということです。

このように、NAS-Bench-101は、様々なアルゴリズムの評価を簡単に行うことができるのです。
NASの分野において、着実・定量化可能な進歩が進み、厳密な実験が行われることを楽しみにしています。

# リンク
[ベンチマークのデータとTensorflowのコード][2]
[論文の実験用のスクリプト][3]


[1]:https://qiita.com/norihitoishida/items/a00c284d83d9d2278fdd
[2]:https://github.com/google-research/nasbench
[3]:https://github.com/automl/nas_benchmarks
ofstreamで可変長かつ1行だけのテキストファイルを出来るだけ瞬時に更新する方法

# 概要
可変長かつ1行しかないCSVテキストファイルを、ほぼリアルタイムに更新したい。
close() → open(path) すれば中身を消せるが、中身が消える瞬間がある。
というのを、無理矢理マシにしたメモ。

# 方法
一時ファイルに書き込み、それをリネーム＆上書きしました。
これでも、一瞬OSがファイルをロックしてしまいますが、中身が消えてるよりいいでしょう。
（ちなみに、固定長であれば、オープンしたままファイル先頭に seekp() するだけでいいいはず。）

環境は Visual Studio 2017のVC++(C++)です。

```cpp:sample.cpp
#include <fstream>
#include <string>
#include <Windows.h>
using namespace std;

int main()
{
    ofstream ofs;
    string tmp_path = "./hoge_tmp";
    string out_path = "./hoge.csv";
    ofs.open(tmp_path);
    if (!ofs) {
        return 1;
    }

    int i = 0;
    while (1) {
        string str = to_string(i) + "," + to_string(i + 1);
        ofs << str << endl;
        ofs.close();
        BOOL ret;
        ret = MoveFileEx(tmp_path.c_str(), out_path.c_str(), MOVEFILE_REPLACE_EXISTING);
        // MoveFileEx()は以下でも可。以下の方がアトミックである信用度が高いが、
        // dst,src双方にファイルが無いと、ファイルが見つからないエラーとなる。
        // また、MoveFileEx()と、dst,srcが逆な事にも注意。
        // 実験した結果、ReplaceFile() は一瞬dst側を削除している事が判明。
        // 詳細は本ページのコメント参照。
        // ret = ReplaceFile(out_path.c_str(), tmp_path.c_str(), NULL, 0, NULL, NULL);
        if (ret == 0) {
            return 1;
        }
        ofs.open(tmp_path);
        if (!ofs) {
            return 1;
        }
        i++;
        Sleep(0); // ほぼウェイト無し無限ループ
    }
    return 0;
}
```

　
ファイルの現在状況は、コマンドプロンプトから以下のコマンドで確認できます。

```windows:cmd
type hoge.csv
```

コマンドプロンプトは、「↑」→「Enter」で前回を同じコマンドを実行できるので、「↑」→「Enter」→「↑」→「Enter」→ .. と繰り返せば、連続して開いてみることが出来ます。
close() → open() の場合は、連打するとよく空データが見えていましたが、本ページのコードにすると、時折アクセス拒否されるものの、空データが見えることは無くなりました。

※ 2019/11/08-1 MoveFileEx()の戻値チェック抜けていたので追記しました。
※ 2019/11/08-2 最後に補足つけたしました。
※ 2019/11/08-3 コード中にReplaceFile()についてコメント記載しました。コメント頂いた方ありがとうございました。
※ 2019/11/08-4 ReplaceFile()の挙動実験結果をコメントに追記しました。
Liferay6.2 + memcached session manager + Elasticache(memcached)

# はじめに

LiferayでElasticacheをセッション管理サーバとして使用した際にとんでもなくはまってしまったので、設定方法をまとめておきます。
なおElasticacheはredisではなくmemcachedにしています。

# 使用環境

## Liferay

- liferay-portal-6.2-ce-ga2

## セッションマネージャ

- [memcached session manager](https://github.com/magro/memcached-session-manager)

## ElastiCache Cluster Client

- マネジメントコンソールのElasitcacheから「ElastiCache Cluster Client」を選択してDL
    - [参考(AWSドキュメント)](https://docs.aws.amazon.com/ja_jp/AmazonElastiCache/latest/mem-ug/AutoDiscovery.Using.html)
- もしくはgithubからCloneしてきて自分でビルドする
   - [aws-elasticache-cluster-client-memcached-for-java](aws-elasticache-cluster-client-memcached-for-java)

# 設定周り

## Elasticache

- マネジメントコンソールに沿って構築するだけ

## Liferay

- [SetupAndConfiguration](https://github.com/magro/memcached-session-manager/wiki/SetupAndConfiguration)を読んで所定のjarをtomcat/libへ配置
- 今回は以下のファイルになりました
    1. memcached-session-manager-2.3.2.jar
    2. memcached-session-manager-tc7-2.3.2.jar
    3. AmazonElastiCacheClusterClient-1.1.1.jar
- Elasticacheへの接続設定を**tomcat/conf/Catalina/localhost/ROOT.xml**に記載する
- 例えばこんな感じに

```
<Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager"
     storageKeyPrefix="static:devperf"
     memcachedNodes="＜設定エンドポイント＞"
     memcachedProtocol="binary"
     sticky="false"
     sessionBackupAsync="false"
     sessionBackupTimeout="300"
     requestUriIgnorePattern=".*\.(gif|jpg|jpeg|png|wmv|avi|mpg|mpeg|mp4|htm|html|js|css|mp3|swf|ico|flv)$"
  />
```

# kryo

- まだ試してないですが、使用する場合はおそらくtomcat/webapps/ROOT/libにjarを置くのではないでしょうか

# まとめ

- ROOTをいじるという発想になるのに時間がかかった
- Liferayのドキュメントすくなすぎ案件
- githubのissueをLiferayという単語で検索すれば秒で解決した内容だった。もっとissueを検索しよう。
    - [Non functioning with Liferay (portlet spec) CMS](https://github.com/magro/memcached-session-manager/issues/351)
- tomcat/conf/context.xmlに設定を書いていた時はrequestUriIgnorePatternのおかげでひどい目にあった
    - 合致するたびに新しいセッションが登録される
lightdmのlogin screenに特定のユーザを表示させない設定

# lightdmのlogin screenに特定のユーザを表示させない設定

lightdmのlogin screenに特定のユーザを表示させたくない方を対象に、
`AccountsService`の設定方法を記載する。


## 背景

`slurm-wln`をインストールすると、slurmユーザがuid 64030で作成されるためUbuntu MATE 18.04などのデスクトップ環境の場合、ログインスクリーンにslurmユーザが表示されて嬉しくない。

そこで`/etc/lightdm/users.conf`で非表示ユーザに`slurm`を追加したが、設定が無効であった。`users.conf`に`AccountsService`がインストールされている場合は`users.conf`の設定は無視されると書かれていた。

以下に`AccountsService`の設定方法を記載する。

## AccountServiceの設定

ユーザ名`slurm`のユーザを隠したい場合は、同名のファイルを以下の場所に作成する。

``` bash
touch /var/lib/AccountsService/users/slurm
```

次に、先程作成したファイルに以下の内容を追記する

```
[User]
SystemAccount=true
```

上の作業を纏めると、、

``` bash
touch /var/lib/AccountsService/users/slurm
cat << EOS >> /var/lib/AccountsService/users/slurm
[User]
SystemAccount=true
EOS
```

以上で設定は終わり


## 参考資料

https://askubuntu.com/questions/92349/how-do-i-hide-a-particular-user-from-the-login-screen
phpのsessionに保存されないときの解決方法(自分の場合)

# はじめに 
centos7・apacheでphpの開発をしているときにsessionが使えなかったので、その原因と解決方法。

##原因
/var/lib/php/sessionの権限が正しくなかった。

##解決方法
$chmod 777 /var/lib/php/session
とりあえず権限を全て許可する。
![session.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/474440/b2c962da-075c-0612-4ac6-76aa0acc5fa4.png)

##結果
・セッションに値を保存(index.php)
![1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/474440/8dec77ed-6a01-0108-b33d-fe586543ba52.png)
・表示するコード(session_test.php)
![2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/474440/9347fd1c-dd20-d591-0de0-b176a1d236fa.png)
・表示された！
![3.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/474440/fc68f5bc-f85d-aa76-9535-7e4d062d7a8d.png)

#おわりに
多分apacheを操作するためのwwwっていうユーザを作ったからこのようなエラーが起きたのだと思う。

権限設定で困ったらとりあえず全て許可するという癖を直したい。

#参考

https://lealog.hateblo.jp/entry/2012/10/13/165901
【備忘録】セッションとは、

#背景
リソース型について調べていたら、「curlセッション」という単語が出てきたが、理解できなかったため


#参考資料
[PHP公式マニュアル セッション](https://www.php.net/manual/ja/session.examples.basic.php)

[「Cookie」と「セッション」と「セッションCookie」の違い](https://ips.nekotype.com/2441/)

[セッション Cookie の概念](https://www.ibm.com/support/knowledgecenter/ja/SSPREK_9.0.2/com.ibm.isam.doc/wrp_config/concept/con_sess_cookies_conc.html)

[セッションとは]
(https://www.seohacks.net/basic/terms/session/)

#セッションとは
PHPでの基本的な使用例
>セッションは、シンプルな方法で個々のユーザーのデータを格納する仕組みで、 個々のユーザーに対して一意なセッション ID を用意します。 これを用いて、複数ページにまたがるリクエストの間で状態の情報を永続させることができます。 セッション ID をブラウザに送信するときには、通常はセッションクッキーを利用します。 また、その ID を使って既存のセッションデータを取得します。 その ID やセッションクッキーが存在しなければ PHP に対して新たなセッションを作るよう伝え、 新たなセッション ID を生成します。

まずは単語について調べてみた。

```単語
セッションとは？
・セッションはユーザーがWebサイトを表示して、離脱するまでの一連の流れ

セッションクッキーとは？
・サーバー固有のCookie
・乱数IDが含まれる（セッション鍵）

クッキーとは？
・ブラウザが保有するCookie
・サーバーから発行されている
・セッション鍵が含まれている
```

【流れ】
1.クライアントが新しいサイトにアクセスしたら、Webサーバーがクライアントに向けてCookieを発行し、それをブラウザに送ると同時に、サーバー自身も同じ鍵をもつCookie（セッションクッキー）を保有する
2.クライアントが同じサイトにアクセスするとき、ブラウザーは発行してもらったCookieをサーバーに送り返し、自信を再識別するようにする
3.Webサーバーが持つセッションクッキーは、ブラウザを使用して、クライアントが認証した単一で固有のサーバーとそのセッションCookie自体を再識別する


##まとめ
セッションやCookieは、Webサーバーとブラウザがクライアントを認識するための仕組み
macOS Catalinaで fastlaneが動作しなくなった件 & 解決方法


macOS Catalinaにアップデート後、fastlaneを実行すると、このようなエラーになる。

```
% fastlane
zsh: /usr/local/bin/fastlane: bad interpreter: /System/Library/Frameworks/Ruby.framework/Versions/2.3/usr/bin/ruby: no such file or directory
```

CatalinaからRubyのバージョンが変わったそうなのだが、その関連でエラーが出ているとおもわれます。

自分はこの辺の設定に詳しくなく、解決にかなり時間を費やしました:frowning2:。もし、同様の件でお困りの方がいれば参考になると思い、解決方法を書き残して置きます。

## エラー解消のために行ったこと

### gem update

gemを更新する。

```
 % sudo gem update --system
```

### install fastlane（失敗）

fastlaneを更新する。

```
% sudo gem install fastlane -n /usr/local/bin
```

が、ここでエラーが出る。

```
Building native extensions. This could take a while...
ERROR:  Error installing fastlane:
	ERROR: Failed to build gem native extension.

    current directory: /Library/Ruby/Gems/2.6.0/gems/unf_ext-0.0.7.6/ext/unf_ext
/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/bin/ruby -I /Library/Ruby/Site/2.6.0 -r ./siteconf20191107-2926-1sstfz1.rb extconf.rb
mkmf.rb can't find header files for ruby at /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/include/ruby.h

You might have to install separate package for the ruby development
environment, ruby-dev or ruby-devel for example.
```

どうやら、Ruby 開発環境が無いようだ。これは「Command Line Tools for Xcode」をインストールすると、その中に含まれているらしい。

### Command Line Tools for Xcodeをインストール

[More Software Downloads - Apple Developer](https://developer.apple.com/download/more/) から、Command Line Tools for Xcode を検索してインストールする.

これでも依然として、先ほどの install fastlane（失敗） と同様のエラーになり、困ってしまった...。


### Command Line Tools for Xcodeをリセット

Command Line Toolsのヘルプを見ていたところ、resetコマンドがあったので、ダメ元で実行してみる。

```
% sudo xcode-select --reset
```

### install fastlane (成功)

resetの後、install fastlaneを実行すると...成功しました:v:

```
% sudo gem install fastlane -n /usr/local/bin
```

## 参考リンク

* [Fastlane not working on MacOS Catalina Dev beta · Issue #15183 · fastlane/fastlane](https://github.com/fastlane/fastlane/issues/15183)
【メモ】python3でbasemapのインストールに失敗するとき (Mojave)

##うまくいかなかった

python3 に basemap を入れて使いたかったが、公式のやりかたでうまくできなかった人です。下記のような親切な記事通りにやってみたのですが。。。
https://qiita.com/duonys/items/c941bc2818abe5cc1da7

コマンドラインでも、jupyterでも

```
ImportError: No module named 'mpl_toolkits.basemap'
```
を吐いて止まりました。

##解決編

結論としては、StackOverflow の [この記事](https://stackoverflow.com/questions/42299352/installing-basemap-on-mac-python) の 14番目（Alexander Pavlovさん）のコメントにある

```
pip3 install https://github.com/matplotlib/basemap/archive/master.zip
```
を実行することで解決しました。ただし、不要なライブラリも多数入ってしまうかもしれません。なお、examples の run_all.py を実行しているとnetCDF4 が無いとおこられたので、追加で下記を実行しました。

```
pip3 install netCDF4
```

Anaconda であれば成功するという記事も散見されましたが、pip派の自分としては両者の不整合による不具合は避けたいため、試していません。最後に、あまり関係ないと思われますが実行環境は以下です。
>macOS Mojave 10.14.6
>MacBook Pro (13-inch)
>Core i5 2.4GHz
>16GB DDR3

##パッケージのインストール状況
インストール失敗直後の状況

```
$ pip3 freeze
beautifulsoup4==4.8.1
certifi==2019.9.11
chardet==3.0.4
cycler==0.10.0
GDAL==2.4.2
html5lib==1.0.1
idna==2.8
kiwisolver==1.1.0
matplotlib==3.1.1
nose==1.3.7
numpy==1.16.4
pandas==0.25.3
Pillow==6.2.1
pyparsing==2.4.4
python-dateutil==2.8.1
pytz==2019.3
requests==2.22.0
scipy==1.3.1
six==1.13.0
soupsieve==1.9.5
urllib3==1.25.6
webencodings==0.5.1
```

解決後の状況。えらいことになっています。

```
$ pip3 freeze
appnope==0.1.0
attrs==19.3.0
backcall==0.1.0
basemap==1.2.1
beautifulsoup4==4.8.1
bleach==3.1.0
certifi==2019.9.11
chardet==3.0.4
cycler==0.10.0
decorator==4.4.1
defusedxml==0.6.0
entrypoints==0.3
GDAL==2.4.2
html5lib==1.0.1
idna==2.8
importlib-metadata==0.23
ipykernel==5.1.3
ipython==7.9.0
ipython-genutils==0.2.0
ipywidgets==7.5.1
jedi==0.15.1
Jinja2==2.10.3
jsonschema==3.1.1
jupyter==1.0.0
jupyter-client==5.3.4
jupyter-console==6.0.0
jupyter-core==4.6.1
kiwisolver==1.1.0
lxml==4.4.1
MarkupSafe==1.1.1
matplotlib==3.1.1
mistune==0.8.4
more-itertools==7.2.0
nbconvert==5.6.1
nbformat==4.4.0
nose==1.3.7
notebook==6.0.2
numpy==1.16.4
pandas==0.25.3
pandocfilters==1.4.2
parso==0.5.1
pexpect==4.7.0
pickleshare==0.7.5
Pillow==6.2.1
prometheus-client==0.7.1
prompt-toolkit==2.0.10
ptyprocess==0.6.0
Pygments==2.4.2
pyparsing==2.4.4
pyproj==2.4.1
pyrsistent==0.15.5
pyshp==2.1.0
python-dateutil==2.8.1
pytz==2019.3
pyzmq==18.1.0
qtconsole==4.5.5
requests==2.22.0
scipy==1.3.1
Send2Trash==1.5.0
six==1.13.0
soupsieve==1.9.5
terminado==0.8.2
testpath==0.4.4
tornado==6.0.3
traitlets==4.3.3
urllib3==1.25.6
wcwidth==0.1.7
webencodings==0.5.1
widgetsnbextension==3.5.1
zipp==0.6.0
```
OpenSSL のクライアント証明書に対する中間CA 作成し直し方法

## 参考

* [openssl - Certification authority root certificate expiry and renewal - Server Fault](https://serverfault.com/questions/306345/certification-authority-root-certificate-expiry-and-renewal)

### 方法

* ca.key : パスワードがあるので注意。
* ca.crt : 既存の ca.crt。有効期限を延長したいやつ
* XXX.csr : 自己署名のためのcsr。この後消して良い。
* XXX.crt : 自己署名されたもの

```sh:ca.crtの有効期限を確認
openssl x509 -text -noout -in ca.crt | more
```

```sh:方法1(-in)
# CSR
openssl x509 -x509toreq -in ca.crt -signkey ca.key -out XXX.csr

# sign
openssl x509 -in XXX.csr -out XXX.crt -signkey ca.key -req -days 6647
```

```sh:方法2(-new)
# CSR
openssl req -new -key ca.key -out XXX.csr \
 -subj "/C=JP/ST=Tokyo/O=XXX/OU=XXX/CN=XXX/emailAddress=XXX@XXXXX.co.jp"

# sign
openssl x509 -in XXX.csr -out XXX.crt -signkey ca.key -req -days 6647
```


## エラー画面

ルート証明書が「信頼されたルート証明機関」に導入されていない場合

![nocert.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25728/ef34f0e1-5914-7deb-01d3-0e75c1a93e1f.png)

ルート証明書が「信頼されたルート証明機関」に導入されているが、期限が切れた場合

![aaa.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25728/c634e170-8e4c-1c7d-56b3-22457dd8f8fc.png)


## 注意点

32bit 環境で作成した csr は 2038年1月19日を超えると 1901年になるため注意。

![openssl.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25728/3a0a39ba-5ead-1b96-adb5-45cf45a009ba.png)

2038/01/18 までは確認できた

![スクリーンショット_2019-11-07_10-25-41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25728/2bdd8bae-71eb-1270-94c5-6bba32a16ea5.png)

* 既存の ca.crt を差し替えたらクライアント証明書を作り直す必要があるっぽい(？)

## md5値の確認

```sh:win10で確認
certutil -hashfile XXXX.cer MD5
```
多クラス分類の結果の混同行列の集計、評価指標の計算

多クラス分類で、未知データを入力とした際、各クラスへの分類確率の予測値が算出される。

テストデータを用いた評価の際、混同行列を書く必要があるので、この記事では、その書き方を例を示す。

## データの用意

3つのクラスに対して、5つのデータを分類器に入力した結果を `results`、正解を `y_true` とする。



```py
results = [
    [0.1, 0.2, 0.7],
    [0.5, 0.3, 0.3],
    [0.2, 0.3, 0.2],
    [0.2, 0.7, 0.2],
    [0.2, 0.5, 0.2]
]
y_true = [
    [0, 0, 1],
    [1, 0, 0],
    [0, 0, 1],
    [0, 0, 1],
    [0, 1, 0]
]
```

## 混同行列を出す

利用するものとしては、 `sklearn.metrics.confusion_matrix` を使う。

[sklearn.metrics.confusion_matrix](https://scikit-learn.org/stable/modules/generated/sklearn.metrics.confusion_matrix.html)

この入力に合う形にデータを整形する。

```py
import numpy as np

results2 = [np.argmax(i) for i in results]
# [2, 0, 1, 1, 1]

y_true2 = [np.argmax(i) for i in y_true]
# [2, 0, 2, 2, 1]
```

よって以下のように集計できる。

```py
from sklearn.metrics import confusion_matrix
confusion_matrix(y_true2, results2)

# array([[1, 0, 0],
#        [0, 1, 0],
#        [0, 2, 1]])
```

### seabornで可視化する

seabornを使うことで、`sklearn.metrics.confusion_matrix`の結果を美しく可視化できるのでやってみよう。

```py
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt

labels = sorted(list(set(y_true2)))

df = pd.DataFrame(confusion_matrix(y_true2, results2), index=labels, columns=labels)

plt.figure()
sns.heatmap(df, annot=True) # annot = Falseにすると図中の各セルの数値表示がなくなる。
plt.show()
```

<img width="347" alt="スクリーンショット 2019-11-07 9.47.07.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88357/c405bba4-ec89-b368-12b3-51522f42fb5e.png">

↑ 図がずれているのは[こちら](https://github.com/matplotlib/matplotlib/issues/14675#issue-463332089)のバグ？のようだ。

## おまけ

`results` を, `y_true` と同様に、binaryで表示すると、 [かつての記事](https://qiita.com/peg/items/0e8d551fd52e3daacca0#%E5%90%8C%E6%99%82%E3%81%AB%E8%A8%88%E7%AE%97)でも書いた `sklearn.metrics.classification_report` が利用できる。これにより、各種評価指標を一度に計算してくれる。

まずは変換。

```py
b_results = []
for i in results:
    max_index = np.argmax(i)
    tmp = [0] * max(map(len, result))
    tmp[max_index] = 1
    b_results.append(tmp)
# [[0, 0, 1], [1, 0, 0], [0, 1, 0], [0, 1, 0], [0, 1, 0]]
```

`sklearn.metrics.classification_report` を利用する。

```py
from sklearn.metrics import classification_report

print(classification_report(np.array(y_true), np.array(b_results)))
```

出力結果。

```py
              precision    recall  f1-score   support

           0       1.00      1.00      1.00         1
           1       0.33      1.00      0.50         1
           2       1.00      0.33      0.50         3

   micro avg       0.60      0.60      0.60         5
   macro avg       0.78      0.78      0.67         5
weighted avg       0.87      0.60      0.60         5
 samples avg       0.60      0.60      0.60         5
```
CentOS7のdocker環境でwekanをインストールして動かすまで

OSSなプロジェクト管理ツールで有名どころはRedmineですが、タスクが増えると入力が面倒ですね。
手軽に使えるタスクボード系のものがあれば、周りもタスクを把握しやすいので、ちょいと調べたところ、"Wekan"いうのがお手軽そうですね。

クラウドや仮想環境でCentOSさえ用意すれば5分ぐらいで使い始められますので、早速インストールして使ってみましょう。

###環境

OS:CentOS7

ミドルウェア:docker、docker-compose

###インストール

1.dockerをインストール

\# yum install docker

2.docker-composeをインストール

今回はgithubにあるものを利用します。

\# curl -L https\://github.com/docker/compose/releases/download/1.6.2/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose

\# chmod +x /usr/local/bin/docker-compose

3.wekan用ユーザ作ります

\# useradd -d /home/wekan -m -s /bin/bash wekan

\# groupadd docker

\# usermod -aG docker wekan

4.dockerを起動

\# systemctl enable docker && systemctl start docker

5.docker-compose.yml ファイルを作成します。

[テスト用](https://github.com/wekan/wekan/wiki/Install-Wekan-Docker-for-testing)なので、メールの箇所は設定しません。

/home/wekan/docker-compose.ymlの中身

```yaml
wekan:
  image: mquandalle/wekan
  restart: always
  links:
    - wekandb
  environment:
    - MONGO_URL=mongodb://wekandb/wekan
    - ROOT_URL=http://192.168.xxx.xxx
#    - MAIL_URL=smtp://user:pass@mailserver.example.com:25/
#    - MAIL_FROM=wekan-admin@example.com
  ports:
    - 8081:80

wekandb:
   image: mongo
   restart: always
   volumes:
     - /home/wekan/data:/data/db
```

URLのIPアドレスは実際に利用するIPアドレスを指定してください。
お好みでポート番号は変更してください。

6.起動します。

wekanユーザになって

\# su - wekan

起動します

$ docker-compose up -d

以上でインストールは完了です。

###wekanを使う

ブラウザで192.168.xxx.xxx:8081を表示

![wekan.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527863/df3920a7-c92d-8307-28eb-b854da502b00.png)

アカウント登録のリンクからアカウントを登録すると使い始められます。
MicroSDカードのSPI接続

ArduinoなどでMicroSDカードを使います。

SPI接続となりますが、一般的なMOSI とか MISO とかとmicroSDカードの信号線の対応の備忘録です。

|ピン番号|microSD/SDモードピン名称|microSD/SPIモードピン名称|ArduinoSPIインターフェース|
|---|---|---|---|
|1| DAT2|Reserved| (N.C.) |
|2|  CD/DAT3 |CS |CS |
|3|  CMD|DI |MOSI|
|4|  VDD|VDD |3.3V|
|5|  CLK|SCLK|CLK |
|6|  VSS|VSS|GND| 
|7| DAT0|DO|MISO |
|8| DAT1|Reserved| (N.C.) |


# SD/microSD カードのピン配置

Part1_Physical_Layer_Simplified_Specification_Ver8.00.pdf によると、SDカードにはSDモードとSPIモードがあり、それぞれでピンの名称が異なります。記載されているSDカードのピン配置、および推測によるmicroSDのピン配置は以下の通りです。ArduinoSPIインターフェースの接続と併せて記載します。



# microSD カードのピン配置
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/6e0d9451-e01e-d380-fde5-182158b9ee35.png)

|ピン番号|SDモード|SPIモード|ArduinoSPIインターフェース|
|---|---|---|---|
|1| DAT2 | Reserved | (N.C.) |
|2| CD/DAT3 | CS | CS |
|3| CMD | DI | MOSI|
|4| VDD | VDD | 3.3V |
|5| CLK | SCLK| CLK |
|6| VSS | VSS | GND |
|7| DAT0 | DO | MISO |
|8| DAT1 | Reserved | (N.C.) |


# SD カードのピン配置
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/d7388e97-f518-6e9c-afc2-394c9cd9a6e9.png)

|ピン番号|SDモード|SPIモード|ArduinoSPIインターフェース|
|---|---|---|---|
|1| CD/DAT3 | CS | CS |
|2| CMD | DI |MOSI|
|3| VSS1 | VSS| GND |
|4| VDD | VDD | 3.3V |
|5| CLK | SCLK| CLK |
|6| VSS2 | VSS2 | GND |
|7| DAT0 | DO | MISO |
|8| DAT1 | Reserved | (N.C.) |
|9| DAT2 | Reserved | (N.C.) |
GCP アップデート (11/1-11/7 2019)

### BigQuery: [Oct 31, 2019](https://cloud.google.com/bigquery/docs/release-notes#October_31_2019)
- GCSにあるParguetとORCを参照する機能がベータになったよ。
- GCSにおいてある、Hiveでパーティション化されたファイル(Avro, Parquet, ORC, CSV, JSON)に対するロードと参照できる機能がベータになったよ。

### BigQuery ML: [Oct 31, 2019](https://cloud.google.com/bigquery-ml/docs/release-notes#september_1_2019)
- TensorFlowモデルをインポートする機能がGAになったよ。

### BigQuery: [Nov 5, 2019](https://cloud.google.com/bigquery/docs/release-notes#November_05_2019)
- テーブルパーティションでinteger型のカラムを指定できる機能がベータになったよ。

### BigTable: [Nov 5, 2019](https://cloud.google.com/bigtable/docs/release-notes#November_05_2019)
- europe-west3でBigTableが使えるようになったよ。

### Functions: [Nov 5, 2019](https://cloud.google.com/functions/docs/release-notes#November_05_2019)
- HTTP functionsへのアクセスをCloud IAMを利用して制御する機能がGAになったよ。

### GKE: [Nov 5, 2019](https://cloud.google.com/kubernetes-engine/docs/release-notes#november_05_2019)
- 新しいGKEバージョンのお知らせ。
  - CVE-2019-17596の対応が入っているよ。
  - cosで以下のバージョンを利用しているとカーネルパニック起きることが確認済み。パッチがテスト中なので必要に応じて影響ないバージョンにダウングレードすることを推奨。
    - 1.13.11-gke.9, 1.13.11-gke.11, 1.13.11-gke.12, 1.13.12-gke.1, 1.13.12-gke.2, 1.13.12-gke.3, 1.13.12-gke.4, 1.14.7-gke.14, 1.14.7-gke.17, 1.14.8-gke.1, 1.14.8-gke.2, 1.14.8-gke.6, 1.14.8-gke.7

### Compute: [Nov 6, 2019](https://cloud.google.com/compute/docs/release-notes#november62019)
- マネージドインスタンスグループのオートスケーリング機能を一時的に停止したり、制限する機能がベータになったよ。

### ディスクレーマ
- アップデートの内容はあくまでも個人の理解していることを書いています。正しい内容はリリースノート等を確認下さい。
- リリース内容できるだけ拾うようにしているのですが、抜けていそうなリリースノートが追加するのでぜひ教えて下さい！(一覧[ここ](https://qiita.com/kenzkenz/items/ac18a359b803dbb6b490)で更新してます。)
asset関数の第2引数の設定先

asset関数の第2引数に使えるのは何かを調べたのでメモ。

```app/config/eccube/packages/framework.yaml

assets:
      base_path: '/html/template/%eccube.theme%'
      packages:
        admin:
          base_path: '/html/template/admin'
        save_image:
          base_path: '/html/upload/save_image'
        plugin:
          base_path: '/html/plugin'
        install:
          base_path: '/html/template/install'
        temp_image:
          base_path: '/html/upload/temp_image'
        user_data:
          base_path: '/html/user_data'
```

参考
https://xoops.ec-cube.net/modules/newbb/viewtopic.php?viewmode=flat&order=DESC&topic_id=20972&forum=2&move=prev&topic_time=1539408186
広域イーサネット、IP-VPNにおける　L2/L3の違いについて

#この記事で学べること
企業向けの専用線サービスを使用する際に
「L2」or「L3」どちらで構築するべきか判断できるようになります。

#専用線サービスについて
本記事では光ファイバーを使った専用サービスを指します。
具体的には、帯域確保型のサービスを指します
例)　10Mbpsのデータ流量を確保するサービス

#広域イーサネットの一般的なサービス
 ・ビジネスイーサ　ワイド(NTT東西)
 ・Universal One ※通称UNO (NTTコミュニケーションズ)
 ・Wide Area Virtual Switch ※通称WVS (KDDI)
 ・Smart VPN (ソフトバンク)
等

#L3 IP-VPN の一般的なサービス
 ・Universal One ※通称UNO (NTTコミュニケーションズ)
 ・Wide Area Virtual Switch ※通称WVS (KDDI)
 ・Smart VPN (ソフトバンク)
等

#両者の違い
　・L2広域イーサネット
　　　　→ データリンク層(レイヤ2)に仕掛けをすることでVPNサービスを提供
　　　https://wa3.i-3-i.info/word12531.html
　・L3 IP-VPN
　　　　→ ネットワーク層(レイヤ3)に仕掛けをすることでVPNサービスを提供
　　　https://wa3.i-3-i.info/word12532.html

#L2広域イーサネットでできること・特徴
・拠点間をフルメッシュに接続
・使用できるルーティングプロトコルに制限なし(OSPF,BGPなどなんでも使える)
・ルーターは基本自前で用意し、(通信キャリア提供は少ない)
・ルーティングは各拠点のルータで実施

#L3 IP-VPNでできること、特徴
・拠点間をフルメッシュに接続
・データの到達にはIP を使用し、IPアドレスを各所に割り当てる必要がある
・使用できるルーティングプロトコルに制限あり
・ルーターは通信キャリア提供のものも使用可能
・ルーティングはキャリア通信網に設定を申し込んで実施
・インターネット接続や、パブリッククラウドへの接続オプション等、オプションサービスが多様

#両者の違い　まとめ
　・L2広域イーサネット　を選択する時
    拡張性が低く簡素だが柔軟性の高いネットワーク設計が求められる時
  
  ・L3IP-VPN を選択する時
　　　オプションサービスによる拡張性を求める、ネットワークを事前設計してキャリアに申し込んでも問題ない
正規表現エンジンの内部状態を可視化してみた

正規表現エンジンの内部状態をインタラクティブに可視化するツールを作ってみました。

![visualizing-regexp-engine.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/323684/a649d9cb-0c55-6850-40b9-9977ffc8d32d.gif)

正規表現エンジンの勉強をしていると、内部状態遷移（NFA）の部分で躓く人が一定数いると思うのですが、このツールで挙動を視覚的に確認しながら進めると理解が早いと思います。

以下から試せます。
https://snoguchi.github.io/visualizing-regexp-engine/dist/

なお使える正規表現は[基本演算子](http://ruby-lecture.s3-website-us-east-1.amazonaws.com/tips/regular-expression/#%E6%AD%A3%E8%A6%8F%E8%A1%A8%E7%8F%BE%E3%81%AE%E5%9F%BA%E6%9C%AC%E4%B8%89%E6%BC%94%E7%AE%97)のみなので注意してください。


## 余談

正規表現エンジンについて勉強したい人には『[正規表現エンジンを作ろう](https://codezine.jp/article/detail/3039)』という記事がおススメです。

連載で少し長めですが基礎から実装まで丁寧に解説されています。

今回の可視化ツールで利用した正規表現エンジンも、この記事に掲載されているPythonのサンプルコードを[TypeScriptに写経したもの](https://github.com/snoguchi/learning-regexp-engine)を使っています。

またステートマシンの描画には[Viz.js](http://viz-js.com/)というGraphviz系のライブラリを利用しました。

いくつかグラフ系のライブラリを試してみたのですが、ステートマシンの可視化に関しては手軽さと綺麗さでGraphviz系が優れているように思います。
PlantUMLをスマートに共有したい旅に出た

## 概要
PlantUMLそのものについてや導入方法についての詳しい説明は省きます。
勉強しつつ模索していったことのまとめです。

## PlantUMLについて
テキストベースでUMLを記述できる言語。

- スタイルやデザインについて考える必要がない(誰が書いても同じくらいにちょっとダサい)ので、記述に集中出来る
- テキストベースなので、gitで管理しやすい

この2点が気に入っています。

## どうにかしたいこと
PlantUmlを初めて使う人に対して共有しにくい。

## 確認してもらう方法
- ローカルに開発環境を作ってもらう
**Javaのインストール、Graphvizのインストール、エディタで開発パッケージをインストールなど大変すぎる**
(余談： パッケージはVScodeやAtomのものがよく紹介されていますが、個人的にはPhpStormのPlantUMLプレビューが使いやすかったです)

- 生成後の画像を見てもらう(UMLを変更の度に画像を生成する)
 **「更新を忘れる」という想像が容易な脆弱性**
 (CIに画像生成を組み込んでしまうというのはアリなんじゃないかと思います)


## 対処
### 希望
- 確認だけさくっと行える
- 改善のためのツールで手間取りたくないため、文字化け対策など考えたくない
- どうにもならなくなったらコピペしてオンラインエディタに貼ってもらいます

### PlantUML Viewer
https://chrome.google.com/webstore/detail/plantuml-viewer/legbfeljfbjgfifnkmpoajgpgejojooj
Chrome拡張。
ブラウザで表示出来るので、これさえ入れてもらえればページ関係なく確認出来る。

**問題: 日本語は文字化けする。**

### Pegmatite
https://chrome.google.com/webstore/detail/pegmatite/jegkfbnfbfnohncpcfcimepibmhlkldo

githubのmarkdownのコードブロックに記入するとUMLとして表示してくれる。
issueやcommentなどでも使えるので便利。

**問題: githubでしか使えない。**

### plantuml/plantuml-server
dockerの公式イメージ

```bash=
$ docker run -d -p 8080:8080 plantuml/plantuml-server:jetty
```
で http://localhost:8080/ にアクセスすると、[PlantUML Web Server](http://www.plantuml.com/plantuml/uml/SyfFKj2rKt3CoKnELR1Io4ZDoSa70000)をローカルで試せる。

```yaml=:docker-compose.yml
plantuml-server:
  image: plantuml/plantuml-server
  ports:
    - "8080:8080"
```

てっきり元のPlantUMLテキストがどこかに保存されていると思っていたのですが、PlantUMLはサーバーで何も保持しないそうです。（PNGもSVGも都度生成する）

**問題: テキスト管理しにくい → git管理しにくい**


## おわり
旅はまだまだ続きそうです。

今回`plantuml/plantuml-server`を使う過程で知ったのですが、
**PlantUMLの記述は圧縮文字になりそのままPlantUML ServerのURLに含まれるそうです。**

http://www.plantuml.com/plantuml/uml/SyfFKj2rKt3CoKnELR1Io4ZDoSa70000 ← `/uml`以降の部分

これが

```:puml
@startuml
Bob -> Alice : hello
@enduml
```

こうなる

```
yfFKj2rKt3CoKnELR1Io4ZDoSa70000
```

この変換アルゴリズムは公開されているので、何か使えそうです。
次はこれを使って自作することを考えてみます。
Linuxやmacでファイルを探したい。ファイル名で、検索。locate/mdfind。コマンドライン派。

# Linuxやmacでファイルを探したい。ファイル名で、検索。locate

Keywordはgrep的に、*(wildcard)などは必要ありません。
つまり、testを含むファイルを検索したい場合は、 
```locate test``` 
です。
（たぶん、とてもたくさん出てくるはずです。私は、test10までありました。いろいろなディレクトリに同じファイル名が、、、）
grepなどを併用すると便利です.

## linuxなら。

```
locate
```

検索のためのインデックスファイルは、たまにupdateする必要があります。

```sudo updatedb```

たまにやると少し時間がかかります。

## macなら

```mdfind -name```

検索のためのインデックスファイルは、たぶん、spotlightと共通です。spotlightのコマンドライン版？これがなかなか思い通りに再構築されない。うまくやるのが難しいです。
【生体情報】初心者が読み解く～超概要編

#目次

1.生体情報とは
2.生体情報の活用方法
3.感想

##1.生体情報とは
人体からは実は様々な情報が発生しており、体の状態を知るバロメータ・固有情報になります。
風邪気味の時に、体温計で測る体温も立派な一つの生体情報なのです。
（思ったより熱が高かったとかありますね、体は正直なのです）
具体的に言うと生体情報には、以下を例に多くの種類があります。

・呼吸
・体動
・脈拍
・体温(表面・深部)
・音声
・脳波
・指紋
・目(眼球の動き・虹彩)
・顔(表情)…

#2.生体情報の活用
生体情報のIT分野での活用としては、大きく以下に分類できると思います。
　1)ヘルスケア
　　体の変化を察知し、異常に繋がる前にサポートするもの
　　→熱中症予防、寝たきりの方の看取り、ストレス察知
　
　2)ロボット
　　ボタン操作などをせず、対象物を意識的に動かしたりするもの
　　→医療用ロボットの遠隔操作での手術、手足の麻痺になった方の義足・義手　　 

　 3)心の可視化
　感情を数値化したり、アンケートでしかとれなかった心の声を定量的に図る
　→商品開発やレビュー、感情(生理的変化)と連動させたい製品
　※感情は人によってとらえ方が変わってくる部分が大きいためサンプルの取り方は重要

 　4)認証技術
　  虹彩認証・顔認証等 　　

#3.感想
実は意識していないけど実際には様々な生体情報がある事が分かりました。
様々な技術の発展には"人が心地よくなる(楽になる)"という人間の欲求の上に成り立っていると思います。
その点でいうと生体情報の分野はとても興味深いと思います。
【Rails】slimを使ってビューを効率良く書こう。

#slimとは
WebアプリケーションはHTMLにより作られていますが、様々な記述やデータの受け渡しなどがあり、文字列を煩雑に並べていってはコードの可読性が低くなってしまいます。
コードを読みやすく記述するために、Railsでは**テンプレートエンジン**を使った開発をします。

>テンプレートエンジンとは、HTMLのテンプレート(雛形)とそこに記述された動的なデータから最終的なHTMLを生成する仕組み
※現場で使えるRuby on Rails速習実践ガイドより

つまりHTMLを生成するための枠組みと捉えてていいと思います。

Railsでは、デフォルトで**ERB**というテンプレートエンジンが設定されています。
このテンプレートエンジンはHTMLの記述に近いので比較的書きやすいというメリットがありますが、コードが長くなってしまうことや、実際の現場で採用されていないことも多いといった点もあります。

そこで効率よくコードを書くための他のテンプレートエンジンの1つが、slimになります。
※その他の1つにHamlというものもあります。

#ERBからslimへの変更の仕方

##①Gemのインストール

```Gemfile
gem 'slim-rails`
gem 'html2slim'
```
上記のgemを追加して、bundle installを実行します。

```
$ bundle install
```
たったこれだけで準備は完了です！今後新たに作成されるビューはslim形式で作られることになります。

##②ERB形式のファイルをslimに変更する

```ターミナル
$ bundle exec erb2slim app/views/layouts/ --delete
```


#変更する際の注意点
- **きちんとgitで管理すること**
slimに変更すると今まで動いていたコードが動かなくなることがあります(僕がそうでした泣)。なので変更する前にきちんとバックアップできるようgitで管理しておくことは必須です。

- **導入する前に記述方法について学んでおくこと**
導入したはいいけどどうやって書くかわからずコードがぐちゃくちゃにならないようにあらかじめ少しは勉強しておくようにしましょう。

#参考
・現場で使えるRuby on Rails速習実践ガイド

・[【爆速で習得】Railsでslimを使う方法から基本文法まで](https://qiita.com/ngron/items/c03e68642c2ab77e7283)
社内勉強会「レンダリング合宿１」 ソフトウェアラスタライザー基本実装編 07.パースペクティブコレクト

#ソフトウェアラスタライザー基本実装編 07.パースペクティブコレクト
前回はテクスチャマッピングを行いましたが、そのままではテクスチャが歪んでいます。
今回はその歪みを補正する方法を解説していきます。

###リポジトリ
https://github.com/NoriyukiHiromoto/Rendering01_SoftwareRasterizer/tree/01_07_perspective_collect

今回の実行結果になります。
歪みがなくなって綺麗なテクスチャマッピングの処理が確認できます。
![top.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/358928/2ba60d96-5ab2-0102-424d-4e27ff175199.png)

#やりかた
前回は (u, v) をそのまま補間していましたがこれでは奥行きに関しての考慮がなされていません。

例えば四角形を斜めから見たときに奥のほうはパースが付いてるので辺が短くなりますが、2D的な処理の場合はただの台形の画像変換として処理されてしまうためにおかしくなってしまいます。

todo:できれば図を用意する・・・

ではどうするのかというと具体的にはプロジェクション変換時の w 値を用います。
ポジションの計算時のxyzwのw値はビュー空間における奥行きを表しており、 (u, v) ではなく (u/w, v/w) を補間し、テクスチャのサンプリング時に補間された 1/w を使ってUVを (u*w, v*w) で戻すことで奥行きを考慮したUVの補間をすることが出来ます。

これがパースペクティブコレクトと言われているやつです。

#実装
まずは座標変換を行っている箇所を見てみます。

```cpp:Renderer.cpp
for (int32 j = 0; j < PointCount; ++j)
{
	auto& pt = TempA[j];
	auto invW = 1.0f / pt.Position.w;
	pt.Position.x = (+pt.Position.x * invW * 0.5f + 0.5f) * WidthF;
	pt.Position.y = (-pt.Position.y * invW * 0.5f + 0.5f) * HeightF;
	pt.Position.w = invW;
	pt.TexCoord.x *= invW;
	pt.TexCoord.y *= invW;
}
```

ｗ の逆数を使ってテクスチャの UV を w で割っています。
この時にポジションの w には w の逆数を入れています。

次にテクスチャをサンプリングしている箇所を見てみましょう。

```cpp:Renderer.cpp
// 重心座標系でwを求める
const auto w = 1.0f / ((b0 * p0.w) + (b1 * p1.w) + (b2 * p2.w));

// 重心座標系でUVを求める
// パースペクティブコレクト対応のため1/wする
Vector2 TexCoord = {
	((b0 * t0.x) + (b1 * t1.x) + (b2 * t2.x)) * w,
	((b0 * t0.y) + (b1 * t1.y) + (b2 * t2.y)) * w,
};
```

補間された w を用いてテクスチャのUVを復元しています。
これにより奥行きを考慮したテクスチャのUVを求めています。

#最後に
今回はパースペクティブコレクトを行いました。
こういうのは今時はハードウェアが勝手にいい感じにやってくれるのでいちいち気にしなくても良くなっているんですが、単語すら知らない状態だと何かあったときに検索すらできないので今回は個別の章として扱いました。
DateとgetXXXの更新タイミング

#タイトルの通り検証していくよ！
Javascriptで時計を作ろうとしたときにはまったのでここにかいときますぅ。
初心者が初心者のために書くので上級者のかたは読まなくてもokです。。。
##dateとは
時間を手にいれるための呪文みたいな…

```javascript
ver date = new Date;
``` 

っていう感じで呼び出して時間に関するものを使っていけます。

```javascript
ver date = new Date;
ver time = date.getFullYear();
console.log(time);
```

実行してみると今の時間が出てきます。
*Consoleの出るところを開いてね！
##本題
時計を作っていたときに自分はこんな感じのコードを最初に作りました。

```javascript
var date = new Date; 

function secondGet(){　
var second = date.getSeconds();
alert(second); 
} 

setInterval(secondGet,1000);
```

かなり省略したけど、最初に秒とかを取得して、secondGet()関数でそれをalertする。そしてsetIntervalで反復するっていう感じ。

実行してみると同じ秒数がずっとalert される。

どうやらdateのなかに時間が

```javascript
var date = new Date; 
```

の時点で確定してしまっているよう

なのでdateも毎回設定しなおせばいいかんじになります

```javascript
function secondGet(){　
var date = new Date; 
var second = date.getSeconds();
alert(second); 
} 

setInterval(secondGet,1000);
```

これで毎秒違った数字がalert されます。

#まとめ
**dateは変数のようなものなのでじかんごとに処理するときはこれも再定義しよう！**
Dateのなかであまり触れられているのをみたことがないのでここにかいときました。

初投稿ですが、評価いただけると嬉しいです( ;´･ω･`)
Vim(NeoVim)でSwift -プラグイン, LSPの導入まで-

こんにちは
みなさん， Vim（NeoVim）やってらっしゃいますでしょうか．

私は最近になってようやくvimを真面目に触り始めました．
普段(?)swiftを書いているのですが,vimでもXcodeばりに補完やハイライトができると嬉しいなと思い,設定してみました．
`deoplete`を使った記事はあったのですが，`coc.nvim`を使ったものはなさそうなので，記事にしました．

### 環境
- OS: macOS Mojave 10.14.6
- NeoVim: NVIM v0.4.2, Build type: Release, LuaJIT 2.0.5 
- Swift: Apple Swift version 5.1 (swiftlang-1100.0.270.13 clang-1100.0.33.7)
- Xcode: Version 11.0 (11A420a)

プラグインマネージャは[vim-plug](https://github.com/junegunn/vim-plug)を使っています.
シンプルで使いやすいです．
vim-plugの導入方法はググるとすぐ出てくるので割愛します．

# シンタックスハイライト

swiftはデフォルトではハイライトされないため，構文ファイルを作る，またはプラグインを導入する必要があります．
今回は以下のプラグインを使います．

`keith/swift.vim`

## インストール

init.vimに以下を記述します.

```vimscript:init.vim

call plug#begin('~/.vim/plugged')
:

" 👇これを記述
Plug 'keith/swift.vim'

:
call plug#end()
```

セーブしてneovimを起動， `:PlugInstall` でインストールされます．
これでシンタックスハイライトが効くようになりました．

# 補完

vimで補完機能を有効にするに当たって，いくつか選択肢があります．

- deoplete
- coc.nvim
- vim-lsp


精査はしていないですが，`coc.nvim`がスター数も多く，設定も直感的であったため，`coc.nvim`を使うことにしました．
[coc.nvim](https://github.com/neoclide/coc.nvim)

deopleteはよくわかりませんが，coc.nvimとvim-lspはLanguage-Server-Clientという点で，補完のアプローチはほとんど同じだと思います．

coc.nvimはtypescriptで実装されており，vim-lspはvimscriptで実装されています．
vimだけで完結させたい方はvim-lspの方が良いかもしれません．

## coc.nvimのインストール
init.vimに以下を記述します．

```vimscript:init.vim
call plug#begin('~/.vim/plugged')
:

" 👇これを記述
Plug 'neoclide/coc.nvim', {'branch': 'release'}

Plug 'keith/swift.vim'
:

call plug#end()
```
セーブしてneovimを起動， `:PlugInstall` でインストールされます．

インストール後は`:Coc*`系のコマンドが使えるようになります．
`:CocConfig`でcocの設定ファイルを開き，そこに設定を書いていくといった流れになります．

# Language-Server-Protocolの導入
coc.nvimはlanguage-server-clientであるため，単体では意味をなさず，言語ごとのlanguage-server-protocol(以下LSP)を動かす必要があります．
swiftのLSPとして[SourceKit-LSP](https://github.com/apple/sourcekit-lsp)があるのでそれを利用します．

## sourcekit-lspのインストール
ソースからbuildします.(Swift5.1以上が必要)

適当なディレクトリでhttps://github.com/apple/sourcekit-lsp.git をcloneします.
その後sourcekit-lspに移動し，buildします．
実行ファイルのあるディレクトリに移動し，`./sourcekit-lsp`を実行してエラーが起きなければインストール完了です．
`sourcekit-lsp`の実行ファイルをpathが通っているディレクトリに置いておく方が良いかもしれません．

以下は実行するコマンドです．

```bash
$ git clone https://github.com/apple/sourcekit-lsp.git
$ cd sourcekit-lsp
$ swift build -c release 👈 そこそこ時間がかかります
$ mv .build/release/sourcekit-lsp /usr/local/bin 👈 やらなくてもヨシ
```

# cocの設定
neovimを起動します．
`:CocConfig`でcocの設定ファイルを開き以下を記述します．

```json:coc-settings.json
{
  "suggest.enablePreselect": true,
  "languageserver": {
    "swift": {
      "command": "<sourcekit-lspの絶対パス>",
      "filetypes": ["swift"]
    }
  }
}
```

お疲れ様でした！
これでswiftの補完が効くようになりました👍

また，他の言語でもLSPを用意すれば補完やコードジャンプなどができるようになります．
LSPの例として

- ruby: solargraph
- python: pyls

などがあります.

# 閑話
設定したのはいいものの，果たしてVimでSwiftを書くタイミングはくるのか?
iOSアプリ開発であればXcode一択なのでは...


# References
[vscodeでswift5.1のSourceKit-LSPを動かす](https://scior.hatenablog.com/entry/2019/10/27/215827)
caseみたいな表現も単語にバラして個々の意味を表示

ローカルに辞書データを持つので高速(重要)
複数単語から成る熟語やイディオムの意味も自動的に表示(重要)
好きな辞書データを簡単にインポートできる(英辞郎オススメ)
camelCaseとかsnake_caseみたいな表現も単語にバラして個々の意味を表示
YouTube等の英語字幕にも使える
ひと手間でPDF文書にも使える(後述)
日英データや英英データにも対応(後述)
小窓が邪魔
ブラウザの辞書ツールは1と2の特徴が本当に重要だと思っていて、これができると知らない表現を覚えることができる機会が圧倒的に増えます。
svlint: SystemVerilogのlinterを作ってみた

# 初めに
最近のプログラミング言語ではlinterなどが標準でついてくるのが当たり前になりつつあります。しかしSystemVerilog用のOSSツールというのはそもそもほとんどなく、当然linterもありません。商用のリントチェッカもあるにはありますが、ライセンスが高価なのでCIなどで気軽に並列で回すというわけにはいきません。

「ないなら自作するしかない」ということでSystemVerilog用のlinterをRustで作りました。

https://github.com/dalance/svlint

こんな感じでチェックできます。

![67759664-377b5480-fa83-11e9-895f-7deef6dde516.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/84296/04dbc818-e06a-9952-1dd3-1b36c35d7a55.png)

# 使い方

[リリースページ](https://github.com/dalance/svlint/releases)からのダウンロードか、[snapのパッケージ](https://snapcraft.io/svlint)があります。Rustを使っている方は`cargo install svlint`でもOKです。

インストールしたら最初に設定ファイルを生成します。

```
$ svlint --example > .svlint.toml
```

設定ファイルは`.gitignore`などと同様にリポジトリルートに置くといいと思います。
この状態では全てのルールがOFFになっているので必要なルールを有効にします。

```toml:.svlint.toml
[option]
exclude_paths = []

[rules]
case_default = false
enum_with_type = false
for_with_begin = false
function_same_as_system_function = false
function_with_automatic = false
generate_for_with_label = false
generate_if_with_label = false
generate_keyword = false
genvar_declaration = false
if_with_begin = false
inout_with_tri = false
input_with_var = false
legacy_always = false
level_sensitive_always = false
loop_variable_declaration = false
non_ansi_module = false
output_with_var = false
parameter_in_package = false
priority_keyword = false
tab_charactor = false
unique0_keyword = false
unique_keyword = false
wire_reg = false
```

使いたいものを`true`にすればいいです。各ルールの説明は[こちら](https://github.com/dalance/svlint/blob/master/RULES.md)。

また、`exclude_paths`には正規表現のリストを設定出来て、マッチするパスは除外できます。例えば`ip`ディレクトリのファイルをチェックしたくないなら

```toml
[option]
exclude_paths = ["ip/.*"]
```

という感じです。

# ルールについて

現状は個人的に使うものしか実装していませんが、[プルリクエスト](https://github.com/dalance/svlint/pulls)でのルール追加や[Issues](https://github.com/dalance/svlint/issues)でのリクエストも歓迎します。
G検定メモ

G検定の学習を行ったので、
メモとして残しておきます。
※追記していきます。
##第1次AIブーム
- 探索と推論
- トイ・プロブレム
##第2次AIブーム

- エキスパートシステム
- 知識ベース
- 推論エンジン
- 専門家知識の蓄積
- 知識獲得のボトルネック

##第3次AIブーム
ディープラーニング

##人物
|名前|私訳|
|---|---|
|レイ・カーツワイル|シンギュラリティは2045年ぐらいに来るかも
|イーロンマスク|
|アーサー・サミュエル|
|ヤン・ルカン|GANは素晴らしい発想だ(10年来ぐらいの)|

## 必要な数学知識
- 微分(偏微分)
微分係数、導関数、偏微分の公式を思い出して、
計算できるようにしておく。

- 線形代数
ベクトル積の計算

- 確率統計
記述統計と推測統計の意味ぐらいで良さそう

## 機械学習
- 教師あり学習
入力と出力データが必要。
回帰と分類の違いを覚えておく。

- 教師なし学習
入力データのみ
クラスタリング(傾向)に分けてくれる。
分類との違いは、グループは最初に決めているわけではない。
次元削減を行う。
- 強化学習
最大のスコア目指す。

##プログラム
|プログラム|
|---|
|ELIZA|
|PARRY|

##機械学習ライブラリ
- Caffe,Caffe2
- DL4j
- Keras
- Chainer(チェイナー)
- TnesorFlow(テンソーフロー)
- Tourch(トーチ)
- Pytourch(パイトーチ)
- Congitive Toolkit(コグニティブ)
- PadlePaddle(パドルパドル)
- MXNet
NRRDファイルの読み込み

# NRRD(Nrrd,nrrd):Nearly Raw Raster Data

NRRDは、N次元ラスターデータ(Rasterデータは、画像を構成する基礎的なデータ定義部分のこと)を含む科学的な視覚化と画像処理をサポートするように設計されたライブラリとファイル形式です。 Nrrdは「ほぼ生のラスターデータ」の略です。
書き込みのエンコード時は、エンディアン（リトル or ビッグエンディアンですね、バイトを上から読むか下から読むかの違いです）を明示して、raw、ascii、hex、またはgzipまたはbzip2で圧縮できます。

# NRRDを読み込むライブラリ（python）

## 1.pynrrd

https://pynrrd.readthedocs.io/en/latest/user-guide.html#reading-nrrd-files

## 2.SimpleITK（pythonでバイオイメージングデータの読み書きは最強かもしれない）

http://simpleitk.github.io/SimpleITK-Notebooks/01_Image_Basics.html

SimpleITKはNRRDだけでなくDICOMやNifti（.nii）ファイルも難なく読み込めます。

# サンプル（読み込み）

- pynrrd

インストール

```
!pip install pynrrd
```

サンプル読み込みコード

```
import numpy as np
import nrrd
ndimage, header = nrrd.read('path/to/.nrrd', index_order='C')#ndarrayを取得

#index_orderはC-order (‘C’) or Fortran-order (‘F’)が指定できます。
#横に読む(C)か縦に読む(F)かの違いです。
#3Dの場合は(x, y, z)はFortran-order (‘F’)、(z, y, x)の場合はC-order (‘C’)を使う。
```

- SimpleITK

インストール

```
#SimpleITK
!pip install SimpleITK
```

サンプル読み込みコード

```
import numpy as np
import SimpleITK as sitk

image = sitk.ReadImage("path/to/nrrd")
ndimage = sitk.GetArrayFromImage(image)#ndarrayを取得
```

以上です。

Visionary Imaging Services, Inc.
DJango で AES 暗号を行う

# ライブラリインストール
$ pip install pycryptodome
$ pip install pycryptodomex

# settings.py に キーを記載
```
$ vim settings.py
```

```py
# AES 暗号
try:
   from .aes_key import *
except ImportError:
   AES_KEY='oDZC5a6rhyukFmKCbPS6M45TFROLmrlB'
```
```
$ vim aes_key.py
```
```py
AES_KEY='dMchLlLllvrDtQUxXDLpAWr2v1EdjuLU'
```

## 確認
```
$ python manage.py shell
```

```py
from project.settings import *
print(AES_KEY)
```

# cipherクラスの作成
```py
import base64
import hashlib
from Crypto import Random
from Crypto.Cipher import AES
from Crypto.Util import Padding


class AESCipher(object):
   def __init__(self, key):
       self.key = (hashlib.md5(key.encode('utf-8')).hexdigest()).encode('utf-8')

   def encrypt(self, raw):
       iv = Random.get_random_bytes(AES.block_size)
       cipher = AES.new(self.key, AES.MODE_CBC, iv)
       data = Padding.pad(raw.encode('utf-8'), AES.block_size, 'pkcs7')
       return base64.b64encode(iv + cipher.encrypt(data)).decode('utf-8')

   def decrypt(self, enc):
       enc = base64.b64decode(enc.encode('utf-8'))
       iv = enc[:AES.block_size]
       cipher = AES.new(self.key, AES.MODE_CBC, iv)
       data = Padding.unpad(cipher.decrypt(enc[AES.block_size:]), AES.block_size, 'pkcs7')
       return data.decode('utf-8')
```

# 呼出し
```py
import random
import string
from project.lib.cipher import AESCipher

raw_text = 'こんにちは'

key = 'y6lLepZQpppdzjkeG5MhUaaaRCychpDd'
print('key:' + key)

cipher = AESCipher(key)

encrypted_text = cipher.encrypt(raw_text)
print(encrypted_text)

decrypted_text = cipher.decrypt(encrypted_text)
print(decrypted_text)
```
画像処理メモ

画像処理の基本的なアルゴリズムに関するメモ


#細線化の処理について

ステップ1 
	ステップ 1.1 パターン1で論理フィルタリングを行う.
	ステップ 1.2 濃度変化の有無を確認し変化がなければ終了、あったら続行
	ステップ 1.3 ステップ2に移行

ステップ2
	ステップ2.1 パターン2で論理フィルタリング
	ステップ2.2 濃度変化あれば終了、1つ以上あったら続行
	ステップ2.3 ステップ1に戻る


#輪郭線追跡について

ステップ1
	ステップ1.1 原点(左上)から探索を開始する.
	ステップ1.2 背景から図形の画素になった画素を探索する
	ステップ1.3 発見画素を注目画素としてセッティングする.

ステップ2
	ステップ2.1 注目画素に対して進入方向を起点とする.
	ステップ2.2 探索方向を時計回りで探索を開始する.
	ステップ2.3 次に見つかった画素を注目画素としてセットする
	ステップ2.4 注目画素が追跡開始点と一致すれば終了する
	ステップ2.5 しない場合ステップ2.1に戻る.

##輪郭の長さについて
左右上下の長さ=1
斜めの長さ=√2

以上の通り計算する.

##内側輪郭の場合

背景から図形に変わった点を追跡開始点にして、反時計周りで探索する.


#空間フィルタリングと論理フィルタリングの違いについてのメモ

##適用画像については
空間フィルタリング RGB・濃淡画像
論理フィルタリング 二値化済み画像

##フィルタリングの効果
空間フィルタリング 平滑化・エッジ抽出
論理フィルタリング 孤立点除去、穴埋め、スムージング

##計算手法
空間フィルタリング 対応する積の和
論理フィルタリング 対応する画素との排他的論理和の否定を取って計算（論理積）

#テンプレートマッチング
画像に対してあるパターンのテンプレートを用いてクラスに分類する手法

##照合の基準
###距離を用いる方法
 距離が小さいほど近いパターンであると考えることができる
 

比較元画像$P$と比較用画像$T$ををおいたとき、以下のような式を置く

```math
D_{max} = max |P_{ik}-T_{jk}| \\
D_{a} = \sum^{N}_{k=1}|P_{ik}-T_{jk}| \\
D_{b} = \sqrt{ \sum^{N}_{k=1}((P_{jk}-T_{jk})^2}
```
 $D_{max}$は各画素の最大距離を示すパラメーターである.
 $D_{a}$は各画素の距離の合計を示す値である
 $D_{b}$は各画素の距離の二乗の合計

以上のような距離の考え方が存在する.

###参考
http://www2.riken.jp/brict/Yoshizawa/Lectures/Lec22.pdf

###類似度を用いる方法

正規化相互相関$R$を求めて計算する方法がある

```math 
R=\frac{ \sum^{N}_{k=1}P_{ik}-T_{jk}}{\sqrt{(\sum^{N}_{k=1}(P_{ik}^2))(\sum^{N}_{k=1}(T_{jk})^2}}
```
これが大きければ大きいほど近似していると考える実装がテンプレートマッチングの類似度を用いる方法である.


以上メモでした
もしも npm script の引数にブランチ名をいれてみたくなったら

## git のローカルブランチをとるのは意外にめんどくさい。
考えに考えられている git なら簡単にとれそうなものなんですが、素の git から取り出すのは結構めんどくさいようです。

https://qiita.com/sugyan/items/83e060e895fa8ef2038c

正直もっと簡単なコマンド一発で取れるかなと思っていたのですが。
もっと簡潔な方法あったら教えてください。

追記：教えてもらいました。

```
git rev-parse --abbrev-ref @ 
```


## きっと誰かが作ってくれているはず

npm 検索すると出てきました。世界は支え合ってます。

[git-branch](https://www.npmjs.com/package/git-branch)

## npm の引数に組み込むには？

npm script に色々書いても、Windows では実行できなかったりするので、node.js を作りました。

引数に callback に入ってくるブランチ名を渡しています。

```js
/* eslint-disable */
const branch = require('git-branch');
const { exec } = require('child_process');

branch('./')
  .then((br) => {
    exec(`npx vue-cli-service storybook:build -c config/storybook -o test-sb-${br}`,function (error, stdout, stderr) {
      if(stdout){
          console.log('stdout: ' + stdout);
      }
      if(stderr){
          console.error('stderr: ' + stderr);
      }
      if (error !== null) {
        console.log('Exec error: ' + error);
      }
    })
  })
  .catch(console.error);
```

ここでは、storybook の出力にブランチ名を入れてみました。

## npm scripts として組み込む

```
  "scripts": {
    "sb:td": "node ./sb-now-deploy.js"
  },
```

こんな感じで書いてあげると npm スクリプトのように実行できます。
shell も使ってないので、Windows 環境でも使えると思われます。


以上でーす👋👋👋
【Swift】Cannot override strong property with weak property

# 環境
・Xcode11.2
・Swift5.1.2

# 出現コード
```swift:Test.swift
class SubCell : UITableViewCell {
  @IBOutlet weak var contentView: UIView!
}
```

# 原因
iOS側で既に保持しているメンバ変数と同名の変数(今回で言うcontentView)を
新たに定義しようとしている

# 解決方法
メンバ変数名を変更する。

誰かのお役に立てば。
dialyzer先生許してください！

# mix dialyzerのエラーを一部無視させたい

ことしになってElixirを使い始めて，最近になってようやく`mix dialyzer`の有り難さが分かるようになった．有り難さがわかると同時に，このdialyzer先生は何が間違ってるのかちゃんと教えてくれないってこともわかってきた．間違ってるところは正しいっぽいが．
それが原因かどうかはわからないが，時々ライブラリがdialyzer先生を怒らせることがある．自分がやったところじゃないことに対しても怒ってくるdialyzer先生マジ理不尽．

これがあまり重要じゃないライブラリならライブラリを使うこと自体をやめれば良いのだが，にっちもさっちもいかないときがやはりある．僕が遭遇したケースは`Phoenix`で`-no-html`オプションを使用したときに何故か発生するエラー．

```
lib/phoenix/router.ex:2: Function call/2 has no local return
lib/phoenix/router.ex:325: The variable __@7 can never match since previous clauses completely covered the type 'error'
```

しかもこのエラーでググってみると，公式へのバグ報告は一応されてはいるものの，公式が「俺らはdialyzerの面倒をいちいち自分たちで確認しないからよろしくな！」なんて言っているから自分で面倒を見なきゃいけない．かといってPhoenixのコードを頑張って弄れたとしても，`mix deps.get`で吹き飛ぶわけで，チョットデキルマンにでもならない限りは根本解決なんかできやしない．

# やり方

ってことで，流石になんか方法あるだろうと思ってdialyzer先生のHexDoc読んでみたら方法が書いてあった．`mix.exs`にdialyzer先生の設定を書き込んで，無視するエラー一覧を作れば良いだけらしい．

```mix.exs
  def project do
    [
      app: :something,
      version: "0.1.0",
      elixir: "~> 1.5",
      elixirc_paths: elixirc_paths(Mix.env()),
      compilers: [:phoenix, :gettext] ++ Mix.compilers(),
      start_permanent: Mix.env() == :prod,
      aliases: aliases(),
      deps: deps(),
      dialyzer: [ignore_warnings: "dialyzer.ignore-warnings"],
    ]
  end
```

まぁ余計なのも並んでいるが、大事なのは`dialyzer: [ignore_warnings: "dialyzer.ignore-warnings"]`の行で，`dialyzer.ignore-warnings`というのが無視するエラー一覧のパス．もちろん相対パス．

```dialyzer.ignore-warnings
lib/phoenix/router.ex:2: Function call/2 has no local return
lib/phoenix/router.ex:325: The variable __@7 can never match since previous clauses completely covered the type 'error'
```

あまりにもそのまま過ぎて驚いたのだけども，無視したいエラーは`mix dialyzer`実行して出てきた文そのままコピペすればいいっぽい．

というわけで以上で`Done (passed successfully)`