OmniAICreator/Qiita-1.07M huggingface dataset:
MT4からDiscordに通知を送る

Discordに通知したいとの要望があったので書きました。

## Discordの準備
Discordにログインして通知を受け取るテキストチャンネルを作成して下さい。
作成したら[チャンネルの編集]をクリックします。
![image01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89061/ba55813d-5082-8a5a-4688-d2ec069cd088.png)
[ウェブフック]を選択して、[ウェブフックを作成]をクリックします。
![image02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89061/b6f6045e-39e8-55c6-0bc6-48d79227a64d.png)
ダイアログ下部に表示されているウェブフックURLをコピーします。
このウェブフックURLは後ほど使用するので忘れないようにして下さい。
最後に右下の[保存]をクリックしてDiscordの準備は完了です。

## MT4の準備
MT4画面上部の[ツール]から[オプション]を選択します。
表示されたウィンドウにて[エキスパートアドバイザ]タブを選択します。
[WebRequestを許可するURLリスト]にチェックを入れます。
[新しいURLを追加、...]にをクリックし、「https\://discordapp.com」と入力する。
![image03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89061/45e9b1c4-d4f3-40e3-659d-dae0943349f5.png)


ウィンドウ下部の[OK]をクリックする。


## 実装
Discordの準備で取得したウェブフックURLを入力するためのパラメーターを用意します。
AlertDiscord関数はMQL4のWebRequest関数を使ってDiscordに通知を行います。
引数としてウェブフックURLとDiscordに通知したい内容を受け取ります。

```cpp
input string WebhookURL = "";

bool AlertDiscord(const string  url, const string text)
{
    int status_code;
    string headers;
    char data[];
    char result[];
    
    if (IsTesting()) {
        return(false);
    }
    
    StringToCharArray("content=" + text, data, 0, WHOLE_ARRAY, CP_UTF8);
    
    status_code = WebRequest("POST", url, NULL, NULL, 5000, data, 0, result, headers);
   
    if (status_code == -1) {
        Print(GetLastError());
        return(false);
    }
    
    return(true);
}

int OnInit()
{
    AlertDiscord(Webhook, "hoge");

    return(INIT_SUCCEEDED);
}

void OnTick()
{

}
```

注意点として、WebRequest関数を使用しているのでEAかスクリプトでないとエラーが出ます。

上記のコードを実行するとDiscordに通知が送れます。
![image04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89061/9fc72169-16ff-9fdf-08e9-a73fa2e581b9.png)
AIY Voice Kit V1に最新イメージを入れる

AIY Voice Kit V1を買ってあれこれ遊んだあと放置して1年以上経ち、何を思ったか久しぶりに起動してみたら起動せず。SDカードが死んでいたので新しいSDを買ってAIY Voice Kitの最新ImageをDLして入れ直してみた。

2020/3/27時点での最新イメージは
AIY Kits Release 2019-11-13
これを使用する。

下記ページにしたがってセットアップする。
https://aiyprojects.withgoogle.com/voice-v1/

注：V2ではAIY Projects appというAndroid Appを利用すると簡単にセットアップできるようだが、ちょっと試してみた感じ出来なさそう。（蓋を開けて本体中央のボタンを長押ししても何も起こらないためBluetoothのペアリングが出来ないと推測）

```
$ ./assistant_library_demo.py
```
実行するとSegmentation faultが発生。

https://github.com/google/aiyprojects-raspbian/issues/660
ここに書かれているように、以下のコマンドを実行。

```
$ pip3 install google-assistant-library==1.0.0
```

インストール中に赤字で

```
aiy-projects-python 1.4 has requirement google-assistant-library>=1.0.1, but you'll have google-assistant-library 1.0.0 which is incompatible.
```

とか言われるけど無視してOK。

再度

```
$ ./assistant_library_demo.py
```

を実行。
めでたく動作。
macOS Catalinaで日本語タイトルのファイルが含まれたzipファイルを解凍する方法

# はじめに
MacOS Catalinaには、文字コードがSJISで全角文字を含むzipファイルがfinderで解凍できないバグが存在し、2020年3月現在も修正されていません。
ターミナルを起動してもunzipを実行しても失敗します。解凍するためには `ditto` コマンドを使用して解凍する必要があります。

# 読みたくない人向け最短コマンド
※ターミナルで `zipファイル` と `解凍（コピー）先` を書き換えて実行
```shell
ditto -x -k zipファイル 解凍（コピー）先
```

# オプション説明
### -x
指定したzipファイルをアーカイブします

### -k
PKZIPを使用してアーカイブします

# 参考
コマンドのヘルプが一番参考になります。

```
admin@Mac ~ % ditto -h
Usage: ditto [ <options> ] src [ ... src ] dst

    <options> are any of:
    -h                         print full usage
    -v                         print a line of status for each source copied
    -V                         print a line of status for every file copied
    -X                         do not descend into directories with a different device ID

    -c                         create an archive at dst (by default CPIO format)
    -x                         src(s) are archives
    -z                         gzip compress CPIO archive
    -j                         bzip2 compress CPIO archive
    -k                         archives are PKZip
    --keepParent               parent directory name src is embedded in dst_archive
    --arch archVal             fat files will be thinned to archVal
                               multiple -arch options can be specified
                               archVal should be one of "ppc", "i386", etc
    --bom bomFile              only objects present in bomFile are copied
    --norsrc                   don't preserve resource data
    --noextattr                don't preserve extended attributes
    --noqtn                    don't preserve quarantine information
    --noacl                    don't preserve ACLs
    --sequesterRsrc            copy resources via polite directory (PKZip only)
    --nocache                  don't use filesystem cache for reads/writes
    --hfsCompression           compress files at destination if appropriate
    --nopreserveHFSCompression don't preserve HFS+ compression when copying files
    --zlibCompressionLevel num use compression level 'num' when creating a PKZip archive
    --password                 request password for reading from encrypted PKZip archive
```

https://macwiki.osdn.jp/wiki/index.php/OSXの固有コマンド#ditto_.E2.80.A6_.E3.83.95.E3.82.A1.E3.82.A4.E3.83.AB.E3.81.AE.E3.82.B3.E3.83.94.E3.83.BC.E3.82.84.E3.82.A2.E3.83.BC.E3.82.AB.E3.82.A4.E3.83.96.E3.81.AE.E4.BD.9C.E6.88.90.E3.83.BB.E5.B1.95.E9.96.8B
-> Apple公式からは消えてました。
https://www.dan.co.jp/cases/macosx/ditto.html
http://www.openspc2.org/reibun/bash/basic/018/index.html

# 最後に
これでツールをインストールすることなくWindowsから送られてきたファイルを解凍することができました。
Javascript基本集(3)~関数~

#Javascript基本集(3)~関数~
####自分の学習用です

　　
基本書式

```js
function 関数名(引数) {
    内部処理
    return 戻り値;
}
```

例題

```js
function hanbun(hikisuu) {
    var xxx = hikisuu / 2;
    return xxx;
}
```

###関数名・引数
『hanbun』というのが『関数名』。『hanbun』のあとの括弧内に書かれた『hikisuu』が、『引数』（ひきすう）と呼ばれる変数になります。『引数』は、内部処理を行う際に、外部から値を受け取るための変数。

『引数』を書く括弧の中には、変数名を書く。
引数が必要ないのなら、何も書かなくてもOK。『引数』を複数使いたい場合は『hanbun(hikisuu1, hikisuu2)』のように『,』（カンマ）で区切って並べて書く。
**宣言した『引数』は、『関数』内でのみ有効。**

###return 戻り値
最後の行の『return xxx;』について。
『return』は、「ここで『関数』を終了する」という宣言。
『関数』内で『return』の書かれた行が実行されると、その場所で『関数』の処理が終了する。
『関数』が終了すると、その『関数』が呼び出された場所まで処理が戻る。
『関数』は、『{}』の末尾まで来るか、『return』の行まで来ると、処理を終え、呼び出された場所に戻る。

今回はここまで:santa:
KLダイバージェンスで確率分布の距離を測る理由

$$
\newcommand{\R}{\mathbb{R}}
\newcommand{\C}{\mathbb{C}}
\newcommand{\N}{\mathbb{N}}
\newcommand{\Z}{\mathbb{Z}}
\newcommand{\kk}{{\mathbf{k}}}
\newcommand{\pp}{{\mathbf{p}}}
\newcommand{\xx}{{\mathbf{x}}}
\newcommand{\XX}{{\mathbf{X}}}
\newcommand{\yy}{{\mathbf{y}}}
\newcommand{\zz}{{\mathbf{z}}}
\newcommand{\ee}{\mathbf{e}}
\newcommand{\qq}{\mathbf{q}}
\newcommand{\ga}{\gamma}
\newcommand{\la}{\lambda}
\newcommand{\La}{\Lambda}
\renewcommand{\S}{\mathscr{S}}
\renewcommand{\rm}{\mathrm}
\newcommand{\fr}{\frac}
\renewcommand{\hat}{\widehat}
\renewcommand{\>}{\right\rangle}
\renewcommand{\<}{\left\langle}
\newcommand{\LL}{\mathrm{(L)}}
\newcommand{\CC}{\mathrm{(C)}}
\newcommand{\pa}{\partial}
\newcommand{\Ga}{\Gamma}
$$
$\small{キーワード：Sanovの定理，Sanov's theorem, カルバックライブラー情報量，カルバックライブラー距離，KLダイバージェンス，KL情報量}$

[こちら](https://mathtod.online/@genkuroki/1079884)に素晴らしい解説がありますが，私の勉強も兼ねて，理解したことをまとめます．

結論から言うと，KLダイバージェンスで確率分布の距離を測る理由はSanovの定理があるからです．

読み方は**サノフ**です．サノスではありません
[<img width = 250 src = "https://marvel.disney.co.jp/content/dam/disney/characters/marvel/avengers-iw/1679_thanos_main.jpg">](https://www.google.com/)




# Sanovの定理（Sanov's theorem）

集合$ X $上の確率分布全体からなる集合を$ \mathcal{P} $で表す．確率分布$ q \in \mathcal{P} $を任意にとって固定し，$ q $から生成される独立同分布$ x_1 , ... , x_n $から導かれる経験分布を$ p_n $で表す．このとき，集合$ A \subset \mathcal{P} $に対し，その内部（開核）の閉包が$ A $を含むならば，

```math
\lim _{n \to \infty} \frac{1}{n} \log \mathbb{P} (p_n \in A)= - \inf _{p \in A} D_{\text{KL}} (p \| q) 
```
が成立する．

正確なstatementについては[英語wiki](https://en.wikipedia.org/wiki/Sanov%27s_theorem)や[こちらの解説](http://www.math.tohoku.ac.jp/~kuroki/LaTeX/20160616KullbackLeibler.pdf)をご参照下さい．

# Sanovの定理の解釈と，KLダイバージェンスとの関係

（不正確・不誠実な記述があるかもしれません．ご容赦ください）

**何らかの確率分布から生成されていると思われるサンプルたち$ x_1,...,x_n $を観測したとき，真の確率分布$ 
q $を推定したい**，という問題を考えているとします．

Sanovの定理とは，ざっくり言うと，真の確率分布$ q $から生成されるサンプルたち$ x_1 , ... , x_n $が，別の確率分布$ p $から生成されたものであるように振舞う確率は，

```math
\mathbb{P} (p  \approx q)   \approx e^{-n D_{\text{KL}}(p \| q)}
```
で近似できる，という主張です．

単語を変えて言い換えると，真の確率分布$ q $による$ 
n $回の独立試行で，経験分布$ p $が偶然に生じる確率$ \mathbb{P} (p  \approx q) $の$ \log $をとって$ -1/n $倍すると，KL情報量

```math
D_{\text{KL}}(p \| q)
```
が現れる，とも言えます．

もっと言い換えると，$ p $と$ q $の距離（KLダイバージェンス）が，**$ p $と$ q $を混同してしまう確率**に指数のオーダーで効いてくる，とも言えます．

そしてこれこそが，<font color="Red">KLダイバージェンスが，確率分布どうしの距離を測る尺度として最も適切である</font>ことの理由です．

大事なことなのでもう一度書くと，<font color="Red">KLダイバージェンスが確率分布どうしの距離を測る尺度として適切である理由はSanovの定理にあります</font>．

KLダイバージェンス$ D_{\text{KL}}(p \| q) $は対称性を満たしませんが，これは，片方が真の分布，もう片方が経験分布であることからも，自然な帰結であることがわかります．
Vue.js・Nuxt.jsに入門したときにみたリンク集

# はじめに
Nuxt.jsでとあるサイト（HPぐらいのレベル感で状態管理とかはほとんどないシンプルなアプリケーション）を構築することになりVueに入門しました。
Nuxt.jsでSPAでの構築、UIフレームワークはVueｔifyです。
筆者は、Reactの経験はありますが、Vueの経験はありません。
そのため、公式系をざざっと読み、Nuxtでアプリを構築しながら必要なことを調べながら実装しました。
そのときに調べたことのリンク集です。

# だいたいこれで理解した。
- [Vue.jsを100時間勉強して分かったこと](https://qiita.com/kskinaba/items/3e8887d45b11f9132012)

# 公式系
- [Vue.js](https://jp.vuejs.org/)
- [Nuxt.js](https://ja.nuxtjs.org/)
- [Vuetify](https://vuetifyjs.com/ja/)
- [Vuex。Vueの状態管理FW](https://vuex.vuejs.org/ja/)
- アイコンをみつけるまでに時間かかった...最近のデフォはここらしい。違うサイトをみていたりしたので最新のVueでマテリアルアイコンが表示されない現象に遭遇しましたが、アイコン名の指定が違うだけでした。。mdiのprefixつけても表示されずに無駄にハマりました...
    - [issue](https://github.com/nuxt-community/vuetify-module/issues/76)
    - [materialdesigniconのサイト。ここから指定しましょう](https://materialdesignicons.com/)

# Nuxt
- [create-nuxt-appの質問で聞かれることの意味](https://qiita.com/cheez921/items/fdfd224099f686e3173d)
- [assetsとstaticディレクトリの使い分け](https://public-constructor.com/nuxt-assets-static-resource/)


# Vue
- [ライフサイクルフック](https://jp.vuejs.org/v2/api/#%E3%82%AA%E3%83%97%E3%82%B7%E3%83%A7%E3%83%B3-%E3%83%A9%E3%82%A4%E3%83%95%E3%82%B5%E3%82%A4%E3%82%AF%E3%83%AB%E3%83%95%E3%83%83%E3%82%AF)
- [省略記法。:hrefとか、@clickとかなんぞや](https://jp.vuejs.org/v2/guide/syntax.html#%E7%9C%81%E7%95%A5%E8%A8%98%E6%B3%95)
- [methodsとcomputedの違い](https://udomomo.hatenablog.com/entry/2017/12/11/213904)
    - これは算出プロパティを理解すればOK
- [v-forのkeyについて](https://qiita.com/FumioNonaka/items/d1d9c9335116426a8316)
    - 指定していなかったらconsoleで怒られた
- [レスポンシブ対応のために画面サイズを取得する](https://qiita.com/namizatop/items/064e561c59c2196b6ff7)
- [methodsでHTMLを返却してレンダリングしたい](https://forum.vuejs.org/t/how-to-return-strong-hi-strong-from-method/12013/2)
- [コンポーネント間の値の受け渡し](https://qiita.com/y_sasaki/items/5bbed5439fcfef9f8c40)

# Deploy
- [firebaseにデプロイ](https://qiita.com/omochironn/items/27d80d5ef470cdb2baca)
git pull 出来なくなった時の対処法

# どんなことが起きたか
いつもコードを書いているリポジトリで、fetchやpull、pushが出来なくなった。

いつも通りfetchをしようとすると、今までは聞かれなかったのに
`Username`と`Password`を求められてしまう状況。


```
$ git fetch upstream
Username for 'https://github.com':XXXXX
Password for 'https://github.com': 
remote: Invalid username or password.
fatal: Authentication failed for 'https://github.com/XXXXX'
```
正しいものを答えても認証に失敗してしまう・・・

# 調査する
毎回ユーザネームとパスワードを入力しないといけないのは、めんどい・・・
同様の問題に関する記事を参考に調査してみた。

### リポジトリのアドレスを調べる
参考記事によると、通信をhttp通信→sshプロトコル通信に変えればOKとのことなので
現在のgitの通信状態を調べる。

```
$ git remote -v
origin  https://github.com/XXXXX/XXX (fetch)
origin  https://github.com/XXXXX/XXX (push)
```
httpsでした。現在の通信状態がhttp通信であることがわかります。
社内リポジトリはsshでcloneしてくる必要があるのに、httpでcloneして居たことが判明。。。
ちなみに、ssh通信である場合は、`https://`ではなく`git@`から始まります。

# ssh通信に変更する
方法はGitの公式にあります
[リモート URL を HTTPS から SSH に切り替える](https://help.github.com/ja/github/using-git/changing-a-remotes-url#switching-remote-urls-from-https-to-ssh)
上記サイトの通り、SSHに切り替えると
リポジトリのアドレスも`git@`から始まるアドレスに変更されたことが確認取れました。

### それでもダメな場合
ssh通信に変更も完了し、
よし！ついにpullできる！と思い、いざpull。

```
$ git pull
identity_sign: private key /Users/{user_name}/.ssh/XXXX/id_rsa contents do not match public
git@github.com: Permission denied (publickey).
```
・・・？
別のエラーが出ました、、、
秘密鍵が一致せず、権限が拒否されているようです。

#### 秘密鍵、公開鍵の作り直し
秘密鍵や公開鍵を確認しても、おかしいと思われる箇所が見当たらず
秘密鍵・公開鍵を作り直したら、うまく行きました。

作り直しの際は、こちらの記事が参考になりました。
[GithubのSSH通信設定](https://qiita.com/yysskk/items/974c9c55d66a26515651)

途中、SSH接続のテストの際にでたエラーについても解決方法をわかりやすく書かれていました。

```
Warning: Permanently added the RSA host key for IP address '52.192.72.89' to the list of known hosts.
identity_sign: private key /Users/{user_name}/.ssh/XXXX/id_rsa contents do not match public
git@github.com: Permission denied (publickey).
fatal: Could not read from remote repository.
Please make sure you have the correct access rights
and the repository exists.
```


根本解決にはならないですが、どこが悪いのか検討もつかず
かなりの時間を費やしてしまう場合は秘密鍵、公開鍵の作り直しをするのも手段の一つかと思います。
Terraform こういう時どうする

# 実際のインフラの状態と State の状態とが乖離している

## State には無いが実際にはある。

```shell
terraform import
```
[Import - Terraform by HashiCorp](https://www.terraform.io/docs/import/index.html)


## State にはあるが実際には無い。

```shell
terraform state rm
```

[Command: state rm - Terraform by HashiCorp](https://www.terraform.io/docs/commands/state/rm.html)

## リソースの名前を変えたい

```shell
terraform state mv
```

[Command: state mv - Terraform by HashiCorp](https://www.terraform.io/docs/commands/state/mv.html)

## 構成ファイル上の変更は無いがリソースを再作成したい

```shell
terraform taint
```

[Command: taint - Terraform by HashiCorp](https://www.terraform.io/docs/commands/taint.html)
PythonでExcel文字列の一部に色をつける

## はじめに
タイトルの通りですが、Pythonを使用してExcelファイルを読み込み、セル内に書き込まれている文字列の一部に色をつけて出力します。
当初はopenpyxlで行おうと思っていましたが、どうも目的の動きはできなそうだったのでxlsxwriterの**write_rich_string**を使用して実現することにしました。
ですが、xlsxwriterは読み込みができないので、読み込み部分はopenpyxl、書き込み部分はxlsxwriterで行おうと思います。
~~Pythonを選んだのは、自分があまり触ったことがないからです。~~

## やること
1.PythonでExcelを読み込み

``` python:openpyxl
import openpyxl

# openpyxlでファイルを開く
iptbook = openpyxl.load_workbook(filename='test.xlsx')
# シート選択
iptsheet = iptbook.worksheets[0]
# セルの文字列を取得
cellvalue = iptsheet.cell(row=1, column=1).value
# 終了
iptbook.close()
```

2.セル内の文字列の一部に色をつけて出力

``` python:xlsxwriter
import xlsxwriter

# xlsxwriterでブックを作成
optbook = xlsxwriter.Workbook('opt.xlsx')
# xlsxwriterでシートを追加
optsheet = optbook.add_worksheet()
# 書式を定義
red = optbook.add_format({'color': 'red'})
# 文字を分割
splitvalue = cellvalue.split()
# リッチテキストで書き込み
optsheet.write_rich_string('A1', red, splitvalue[0], splitvalue[1])
# 終了
optbook.close()
```

## 結果

実行前と後のファイルになります。

![bf.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275170/36912a5a-6e36-6d53-58b3-41f03cde5ab4.png "before")

![af.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275170/30c18926-71e1-eede-5c09-06c3a43e6547.png "after")

## 参考にさせていただいた記事

[Example: Writing “Rich” strings with multiple formats](https://xlsxwriter.readthedocs.io/example_rich_strings.html)

[Excelで1セル内に複数の書式(フォント)が混在するようなものをPythonで扱いたい](https://qiita.com/tekunikaruza/items/53a5b482b20a85f9c44d)

## おわりに
リッチテキストであれば、色に限らず線の太さやフォントも変えることができます。
今回は2つのライブラリを組み合わせて使用することで実現ができました。
よりよい方法をご存じの方がいましたら教えてくださると嬉しいです。
ng build --prod で abort が発生した困った場合

同様の現象に会う人はあまりいないと思われるけどメモがてら。
Angular の開発にて「よっしゃー仕上げじゃー」と思って意気揚々と

```
ng build --prod
```

をやると

> 92% chunk asset optimization TerserPlugin
> abort

的な感じでコンパイル出来ないので愕然となる。

https://github.com/angular/angular-cli/issues/13939

を斜め読みするとどうもメモリ周りのエラーの模様。が、よくわからんので途方に暮れつつ情報を漁る。

https://github.com/nodejs/node/issues/10137

を見ると

> update to node v13.8.0 solved the issue for me

ということで node のバージョンをあげることで解決するということなので使っていた node のバージョンが ```v10.15.3``` だったので最新版の ```v13.12.0``` に入れて実行したとろこ無事該当エラー箇所は通過。ふぅ、やれやれだぜ。とか思ってると最後に ```Budgets``` のエラーが。またしても愕然としたものの

https://github.com/angular/angular-cli/blob/master/docs/documentation/stories/budgets.md

にて ```angular.json``` の該当箇所を変更すればエラーは一応解消される（アプリケーションサイズの警告らしいので適当な値設定するのは微妙だなと思いつつ）。

今回の TerserPlugin の問題とは別に prod ビルドは「この ts ファイル何処も使ってないけどなんであるの？ちょっとうざいんですけど。」的な感じ（誇張）で容赦なく的確にご指摘してくれるのでやったほうが良いぞなもし。
🐘【PHP】Kubernetesの略称に慣れるためにk8sライク略称を作る関数


## この記事は？

ただのネタ記事です
Kubernetesの略称の一つである「K8s」ってのは
Kとsの間が8文字なのでk8sらしいのですがなじみがなかったので関数化しました

## 環境
PHP 7.2.21

## やったこと

```k8s.php
    /**
     * K8sライクな略称を作成
     *
     * @param string $name 略する名前
     * @return string 略称/$nameが2文字以下の場合は$nameを返す
     */
    public function makeKubernetesLikeAbbreviation(string $name = ''): string
    {
        $prior     = substr($name, 0, 1);
        $posterior = substr($name, -1);

        $len = strlen($name) -2;

        if ($len <= 0) {
            return $name;
        } else {
            return $prior . $len . $posterior;
        }
    }
```

### 返却値

```ret.php
// ''
$moji0 = $this->makeKubernetesLikeAbbreviation('');
// 'a'
$moji1 = $this->makeKubernetesLikeAbbreviation('a');
// 'ab'
$moji2 = $this->makeKubernetesLikeAbbreviation('ab');
// 'Q3a'
$moji5 = $this->makeKubernetesLikeAbbreviation('Qiita');
// 'e7r'
$moji9 = $this->makeKubernetesLikeAbbreviation('eltociear');
// 'K8s'
$moji10 = $this->makeKubernetesLikeAbbreviation('Kubernetes');
```
Amazon Linux2でDockerをインストールする方法が2種類ある

amazon-linux-extrasでインストールすると19.03.13-ceがインストールされる(2021/01/09現在)
yumでインストールすると19.03.13-ceがインストールされる(2021/01/09現在)

# amazon-linux-extrasの場合のインストール方法

```sh
sudo amazon-linux-extras install -y docker

docker -v

# 実行結果
Docker version 19.03.13-ce, build 4484c46
```

# yumの場合のインストール方法

```sh
sudo yum install -y docker

docker -v

# 実行結果
Docker version 19.03.13-ce, build 4484c46
```
WARNING: UNPROTECTED PRIVATE KEY FILE! というエラーが出たらやること

秘密鍵(id_rsa)について、よくつまづくのでメモ。


# はじめに
自分の秘密鍵を.ssh配下にコピペしてSSHでのgit cloneしたら以下のエラーが。

```
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@         WARNING: UNPROTECTED PRIVATE KEY FILE!          @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
Permissions 0644 for '/home/yu_uchida/.ssh/id_rsa' are too open.
It is required that your private key files are NOT accessible by others.
This private key will be ignored.
bad permissions: ignore key: /home/yu_uchida/.ssh/id_rsa
Permission denied (publickey).
fatal: Could not read from remote repository.
```

パーミッションが too openだと怒られてます。

# 解決方法
chmodでパーミッションを0600にする。

```
$ chmod 0600 id_rsa
```

これでgit cloneできるようになりました。
SourceTreeでgitにpushできるようにする

###できること
何にもない状態からソースツリーを使えるようになる
個人開発を想定しています。

###環境
windows10
バージョン1903 (OSビルド 18362.720)

###gitインストール

これの3番まで行う
https://prog-8.com/docs/git-env-win

###SourceTreeインストール

これを行う
https://yttm-work.jp/git/git_0002.html


###クローンする

cloneを選択

![1585288586003.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/355521/33088a90-937c-fc83-5f27-ce902bd79e7d.jpeg)

矢印のところに、gitのHTTPSのpathを入力

![1585288612251.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/355521/e8823a97-c9bd-940d-8372-99abf2c8b061.jpeg)

![1585289160541.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/355521/bdec3609-9320-08fb-478e-851d4dc75f3a.jpeg)

保存先のディレクトリ名はリポジトリと同じ名前じゃないとダメっぽい？
gitのリポジトリをprivateにしている場合はgitHubアカウントでログインを求められる

###鍵登録

これを行う
https://qiita.com/reflet/items/4f7b5c4a312bc27df10e

###push

保存したいファイルを先ほどの”保存先のパス”のディレクトリにコピーする
ステージングのところにファイルが表示されるので、選択してコミット、pushすれば完了！
VirtualBoxにAlpineをいれてdocker redmine

## VirualBox
install

## Alpine
VIRTUALをいれた

## Docker
```
apk update
apk upgrade
apk add nano
nano /etc/apk/repositories
(community, testingを有効にする）
apk add docker docker-compose
```
## sshのroot loginを有効にする
```
nano /etc/ssh/sshd_config

PermitRootLogin yes
を追加

/etc/init.d/sshd restart
```

## docker redmine
[ここ](https://qiita.com/bezeklik/items/b5c39136a8db23e2e81c)に沿って進める

```
ssh -l root 192.168.xxx.xxx

mkdir /var/www/redmine
...
```

## redmineのplugin
[参考](https://www.sejuku.net/blog/86425)

```
cd /var/www/redmine/plugins
必要なpluginをダウンロードして展開
```
以下を実行

```
docker exec redmine bundle install --jobs=4 --without development test && \
docker exec redmine bundle exec rake redmine:plugins:migrate RAILS_ENV=production && \
docker exec redmine passenger-config restart-app /usr/src/redmine
```

### work time
[https://github.com/tkusukawa/redmine_work_time](https://github.com/tkusukawa/redmine_work_time)

### absolute date
[https://github.com/suer/redmine_absolute_dates](https://github.com/suer/redmine_absolute_dates)

### issue badge
[https://www.redmine.org/plugins/redmine_issue_badge]
(https://www.redmine.org/plugins/redmine_issue_badge)

[Redmine 3.x](https://github.com/akiko-pusu/redmine_issue_badge/tree/support-Redmine3)

### clipboard_image_paste
[https://www.redmine.org/plugins/clipboard_image_paste](https://www.redmine.org/plugins/clipboard_image_paste)


### Question
[リンク](https://www.redmineup.com/pages/plugins/questions)
チケットでやったほうがワークフロー、ステータスが管理できて良い。

### Isuue Template
[リンク](https://www.redmine.org/plugins/redmine_issue_templates)
redmine 3.xには0.2.xを持ってこないとだめ
[redmine 3.x用](https://github.com/akiko-pusu/redmine_issue_templates/tree/v0.2.x-support-Redmine3)
また、フォルダ名は"redmine_issue_templates"にする必要がある

いい感じである

※ロールと権限でテンプレートの表示を有効にすること
templateを利用してのチケット作成がシステム管理者でしかできない？
Googleカスタム検索（サイト内検索）の結果ページから別タブに開かない方法


###別タブで開くバージョン

scriptを読み込んだら検索結果を表示するところに下記を挿入する。

```
<div class="gcse-searchresults-only"></div>
```

###別タブで開かないバージョン

`data-linkTarget="_self"`を追加する。

```
<div class="gcse-searchresults-only" data-linkTarget="_self"></div>
```

公式ドキュメントの一覧では`linkTarget`としか書いてないのですが、別の場所にちゃっかりプレフィックス`data-`をつけてねと書いてあります。ちゃんと読まないとだめですね。

公式ドキュメント：https://developers.google.com/custom-search/docs/element
Linux で C++ グラフィックスアプリに CPU 描画の GUI をさくっと付けて, サーバから X11 画面転送したい

## 背景

* レンダリング(レイトレーシング)や, データ可視化(形状処理)などの CPU のみ利用の C++ アプリをサーバ CPU など性能がよいマシンで実行したい
* 処理結果として画像を表示する必要がある
* さらに GUI を付けたい(パラメータをちょっと変えたりなど)
  * JSON-RPC とかでやるのはめんどいので, C++ アプリ単体で全部完結したい.
  * VNC とかで画面転送も, 画面転送で帯域使うので重い
  * libui https://github.com/andlabs/libui という手もあるが, 画像を表示するのが実はめんどい
* すごい full-featured な GUI でなくてもよい
  * SwiftShader で OpenGL アプリを CPU 描画で動かす手もあるが, SwiftShader のビルドがめんどい.

既存の C++ GUI ライブラリは, だいたいが OpenGL(GLX) 使っていて, X11 画面転送というのができません. 

## ライブラリ

imgui と nanogui を動かすことができました.
どちらも基本は GPU 描画ですが, バックエンドを変えることで CPU 描画も可能になります.

### SDL2. 描画のベースライブラリ

SDL2 で, OpenGL を使わない + Software renderer を使うことで, CPU 描画が可能になります.

Ubuntu などでは SDL2 は apt で入りますが, Ubuntu 18.04 では OpenGL や Wayland あたりに固定されているようで, GLX エラーがでました.

https://raspberrypi.stackexchange.com/questions/78475/which-remote-access-method-allows-me-to-access-an-sdl-based-application

にあるように, 環境変数で x11 指定しても

`export SDL_VIDEODRIVER=x11` 

X11 backend に切り替えできませんでした. その場合はソースコードから SDL2 をビルドする必要があります(OpenGL あたりを off にしておく).

SDL2 自体は GUI widget は無いので, この上に GUI ライブラリを乗っけて CPU 描画します.

### imgui  

https://github.com/Tyyppi77/imgui_sdl

imgui + SDL2 backend です. 上記のように SDL を software render にすることで CPU 描画できます.


### nanogui

https://github.com/dalerank/nanogui-sdl

nanogui + SDL2 backend です. これも同じく SDL を software render にすることで CPU 描画できます.
(example1.cpp をちょっと改変する)

colorwheel には現時点では対応してません
(Eigen を使っているため. Eigen の部分をちょっと自前で実装すれば動くはず)

ありがたいことに NanoVG の部分は, nanort を使っていただいています.

NanoVG を CPU で描画する
https://qiita.com/syoyo/items/1b7fe6a1035394a7efe4

内部の実装としては, アイコンなどは SDL の texture にいったん NanoVG で描画して, それを表示しているようです(そのため, 毎回一から描画するよりは高速なはず)

## 感想

CPU 描画なので, やはり CPU は 1 core ぶん 100% になってしまいます. 多コアの高性能 CPU では気にならないかもしれませんが, ちょっと気にはなりますね.

画面に変更ないときは描画しないなどを制御できれば, CPU 負荷を減らすことができるかもしれません.
 
VNC で画面転送よりはレスポンスはよいかと思います(ネットワーク環境次第か. 少なくとも 1 GB イーサネットでは VNC はきびしい)


## TODO

* [ ] nanogui-sdl で, colorwheel 対応をして PR を送る
* [ ] 画面に変更がないときは描画リフレッシュしないようにして, CPU 負荷を下げることができないか検討する.
rex0220 計算式プラグインによるステータス履歴

[計算式プラグイン](https://qiita.com/rex0220/items/ae83c6d5ce50ff7a9a73)で、ステータス履歴を実装してみます。

# ステータス履歴の例

<img width="505" alt="2020-03-27_15h54_46.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/60d599bb-bba8-75ed-ddfc-88bd3d0956c3.png">


# アプリフォーム

「ステータス履歴」と制御用の「ステータスチェック」を配置
※計算式プラグインの実行順により、「ステータス履歴」、「ステータスチェック」の順に配置
または、計算式プラグインのランクを指定
<img width="613" alt="2020-03-27_14h50_54.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/230e1bb5-77a5-ebf4-b8c4-6315f256ef2d.png">

# プロセス管理

とりあえず、デフォルトにステータス変更を何回かできるように「差し戻し」を追加
<img width="846" alt="2020-03-27_14h52_58.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/5ca3c0e0-cf57-0f8e-dec0-de47e5038c66.png">


# 計算式プラグインの設定

- 「循環参照を許可」をチェック
- ステータス履歴：

「NOT($id)」は、新規追加画面の時だけなので、履歴はクリアしておきます。。
「ステータス!=ステータスチェック」は、ステータス変更のイベント時だけ発生する条件なので、ステータス履歴にステータス情報を追加。
それ以外のイベント時は、ステータス履歴を維持。


```
IFS(NOT($id),"",
ステータス!=ステータスチェック,
ステータス&" "&LOGIN_NAME()&" "&DATE_FORMAT("TODAY","YYYY-MM-DD HH:mm:ss")&IF(ステータス履歴,NEWLINE())&ステータス履歴,
ステータス履歴)
```

- ステータスチェック：

```
ステータス
```

<img width="986" alt="2020-03-27_16h03_15.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/bf7b2e3f-5a84-730e-0db1-516d78163321.png">
テレワークするときの３やめとけ

エンジニアにとっては極めて普通の話なのだが、非エンジニアにとっては知らないこともあるかもと思いまとめました。

# 誰でも使える共有PCでログインするのはやめとけ

ネットカフェなどの共有PCで画面内容やキーボードの入力内容が漏れたら困るような作業はやめとけ。
なのでID/PASSWORDを入れてログインするような作業だったり、機密文書の閲覧・作成はやめとけ。
どんな監視ツールが仕込まれているかわかったものではない。
せいぜい何かの調べ物に使うのに止めるべき。
IDCとかにある共用PCとかでChromeのパスワードリスト見ると結構保存されててぉぃぉぃな気持ちになる。

[ユーザー操作の画面とキーボードのログを記録し従業員のPCの不正操作を抑止(イーセクター) | ScanNetSecurity](https://scan.netsecurity.ne.jp/article/2015/04/14/36184.html)

[キーロガーとは？仕組みや危険性、検出・駆除方法について徹底解説](https://cybersecurity-jp.com/security-measures/23974)

# 暗号化されていない無料WIFIにつなぐのはやめとけ

無料WIFIは大体暗号化されていないやつだが、暗号化されていなければWiresharkなどで大した専門知識なしで盗聴できてしまう。
無料WIFI接続時は通信内容が盗聴されているつもりで、それでも良いような使い方をした方が良い。

[Wiresharkとハブを使ってスマホのWi-Fi通信を盗聴する方法 | サイバー犯罪とセキュリティ](https://blog.azunyan1111.com/wireshark%E3%81%A8%E3%83%8F%E3%83%96%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%A6%E3%82%B9%E3%83%9E%E3%83%9B%E3%81%AEwi-fi%E9%80%9A%E4%BF%A1%E3%82%92%E7%9B%97%E8%81%B4%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95/)

自宅WIFIも暗号化していないとかパスワードもかけてないとかあったら設定を見直した方がよい。マンションなら隣の家から盗聴できてしまう。

# 人の多いところでPCを開くのはやめとけ

カフェなどで「社外秘」と書いてある資料を堂々と開いている人をみてぉぃぉぃという気持ちによくなる。世間が興味ないような内容であればライバル企業でもない限り注目もされないのでまあ問題ないが、「ミリシタプラチナスターシアター不正アクセスについて」なんてタイトルのメールを横の人が書いていたらついついガン見してしまう。
なので、大勢の人が集まるところで作業する場合は後ろや左右のどちらかが壁または人が来れないような場所に陣取るのが良い。フォントサイズも極力小さくしておけば読まれにくくなる。背景色と文字色を近しい色にして読みにくくする手もあり。

また、コワーキングスペースとかで会社や自宅にいる感覚でPC、スマホを机の上に置いたままトイレに行ってしまう人がいるが、盗難やいたずらされる可能性があるので、本体は肌身離さず持ち歩いた方が良い。誰かと一緒に行っていれば荷物を見ててもらえるので良い。

# 結論　自宅で作業するのが一番安心

ただし[ニャンサムウェア](https://nlab.itmedia.co.jp/nl/articles/1705/16/news148.html)の脅威には注意されたし。
Gradleってなんだろう？

javaのビルド周りに興味をもったので、その時のメモ。

# Gradleとは
javaのビルドツールで jarファイル(javaのバイトコードファイルや画像をzipファイル形式で一つにまとめたもの)
へのビルドをしてくれます。
mavenと違い、設定ファイルはgrovyという言語で書きます。

また、gradleを毎回インストールすることがないように、gradle wrapper というものを作り、
これを配布することで、gradleをインストールしていない環境でもgradle を使うことが出来ます。

# Gradle 初期化
簡単なgradleプロジェクトを作ります。

```bash
gradle init
```

これで色々ファイルが作られます。具体的には以下の感じ

```bash
├── build.gradle
├── gradle
│   └── wrapper
│       ├── gradle-wrapper.jar
│       └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
└── settings.gradle

```

# 依存性解決

gradleはjavaの外部のパッケージを管理して、自身ののプロジェクトでそのパッケージを使えるようにしてくれます。

```
dependencies {
    implemention("パッケージ名")
}
```



# タスク
gradleにおけるタスクとは,公式から引用すると、ビルドを行うための細かい作業とのことです。

## 組み込みのタスク
このタスクはgradleのプロジェクトが生成された時点でいくつか作られています。
例えば、テスト、ビルド、実行などです。

これらは、 
```
gradle tasks
```

で一覧を見ることが出来ます。

## タスクの定義

これは、自分で定義できるので、簡単なタスクを定義してみましょう。

```gradle
task hello {
    println("hello")
}
```

実行してみよう。

```bash
gradle hello

#以下のが表示されるはず
#hello
#:hello UP-TO-DATE
```

こんな感じでタスクを作って、内部でプラグインの設定や特定のタスクのみを束にしておくことが出来ます。

## タスクをアクションで構成する
タスクは自分が実行スべきタスクをアクションという単位で認識していて、それを配列として順次実行していきます。

アクションは
doFirst:先頭に追加する
doLast: 末尾に追加する

といった形で追加していきます。

```gradle
task hello{
    hello.doFirst {
        println "hello1"
        println "hello2"
    }
    hello.doLast {
        println "hello3"
        println "hello4"
    }
}
```

これを実行すると

```
gradle hello
```
結果は

```
:hello
hello1
hello2
hello3
hello4

BUILD SUCCESSFUL in 0s
1 actionable task: 1 executed
```

となる。

こんな形で実行順序を制御して、処理順序をカスタマイズすることができます。

# gradleのtips
これまででざっくりとgradleの使い方を触ってきましたが、今度は各々のタスクが早くなる設定や分析ための便利な機能を見ていきたいと思います。

## 並列化
graleは基本的にタスクを一つずつしか実行していきません。ですが、
並列実行を強制する設定があります。
なお、これは完全に独立しているタスクを並列実行するので、依存関係があるものに関してはこれまでどおり逐次実行されます。

gradle.propertiesに以下を追加します。

```
org.gradle.parallel=true
```
## プロファイリング

gradleにはタスク実行時にどのくらい時間を使ったか、並列実行したかなどをプロファイリングして、視覚化してくれる機能があります。
これはタスクの実行時に `--scan` をつければ、実行後にCLIにURLが表示され、そこから確認ができます。

ただ、これにはgradleでメールアドレスの登録などが必要なため、情報管理的な部分を考える必要があります。

![screenshot-scans.gradle.com-2020.03.20-12_00_39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179800/39ac1085-f7da-d56f-c3ba-b997dd846b60.png)

このプロファイリングは結構便利で、テストの重い部分やサジェストなど、ビルドの効率化に重要な情報を得ることができます。


# 参考
https://qiita.com/opengl-8080/items/0a192b62ee87d8ac7578#%E3%82%BF%E3%82%B9%E3%82%AF%E3%81%AE%E5%8F%82%E7%85%A7

https://guides.gradle.org/performance/

# 最後に
gradleは設定ファイルが、独自言語だったりしますが、その言語にさえ慣れてしまえば設定は読みやすいし、
タスクの設定も細かく行える印象です。

また、ビルド時のプロファイリングなど、検証と改善の昨日も揃っているところもいいです。

それでは良いgradleライフを
Blender python でシーン編集するメモ(W.I.P.)

## 対象

* Blender 2.82a or later

API としては Maya mel が python になった感じが強いでしょうか.

## パラメータやアトリビュートにアクセスして, 値を取得したり変更したい

たとえばマテリアルで色を変えたいなど.

UI で右クリック -> Copy Data Path して, python console などに貼り付ければ, どのようにアクセスすればいいのかいくらかわかります.

![blender-python.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/36275/22e7f14b-067b-c1ba-ad91-5c75cccc39df.png)

ただ, これはノードを起点としての階層なので, node_tree も取得する必要があります.

node_tree については, 以下のようにしてアクセス.

Blender のノードを Python から操作する
https://dskjal.com/blender/process-node-from-python.html

## 位置などを変えたい

T.B.W.

## 点群をプロットしたい

Blender + Pythonでポイントクラウドを可視化する
https://ksknw.hatenablog.com/entry/2019/10/29/192026

```
bpy.ops.mesh.primitive_uv_sphere_add(location=(x, y, z))
```

のような感じで sphere を作ることができる.

より効率的に行うなら, particle として表現でしょうか.

## 形状データへのアクセス

T.B.W.

* [ ] 頂点座標
* [ ] 法線
* [ ] UV データ
* [ ] Vertex color
* [ ] Skin weight
* [ ] Edge, face
HaskellでMD5 #Haskell

HaskellでMD5を使う方法です.
少し悩んだのでほぼ個人用メモ.

## 使うパッケージ
- cryptohash


```haskell
import qualified Data.ByteString as BS
import           Crypto.Hash     ( Digest
                                 , MD5
                                 , hash
                                 , digestToHexByteString )

md5 :: BS.ByteString -> Digest MD5
md5 =  hash
```

こんな感じにしてやって, `md5 "ByteStringの文字列"`みたいにしてやると結果が返って来ます.
`ByteString`の値として扱いたい場合は`digestToHexByteString . md5`みたいにしてやると良いです.
NGSI v2 まとめ

仕事でNGSIによるInformation modelを扱う機械になったのでまとめてみた。

# NGSIとは
ネットワークAPIの共通規格のこと
国内では主にNECがメインとなって進めていた。
OMA(Open Mobile Alliance)という団体で、仕様策定などを行なっている。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/159589/600e742c-9ff7-38b0-ff9b-9b38991c6bef.png)


# 各国、各社の取り組みについて
## 国内
官民データ活用共通プラットフォーム協議会(製造業やSIer、クラウドベンダーなどの集まり)がNGSIを用いたシステムの実証実験を2018年ごろから実施している。

## 海外
欧州の官民プロジェクトにて
NGSIをベースとしたFIWAREというスマートシティプラットーフォームで活用できるOSS群の活用や、中のデータの持ち方などを定義している。

# NGSI v2とは
#### 改良され単純化された OMA-NGSIのバインディング
- 単純なことが容易にできる
- 複雑なことができる
- アジャイル、実装主導型のアプローチ
- デベロッパー・フレンドリー(RESTful, JSON)

#### リソースURLに/v2プレフィックスを使用する。

# モデル(NGSI)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/159589/d1f6721b-9ccb-aa9c-f264-357f33ce5b16.png)

# RESTful-ness
## NGSI v1では
- 厳密ではRESTfulではなかった。リソースを識別することはできず、単なる操作の種類を示していた。
- POSTのみであった。
- 実際、RESTfulというよりも、RPCに近い。

# NGSI v1との違い
## JSON

以下のようにリクエスト・レスポンスの一連の動きをみても
ペイロードの長さやURLの簡潔さにおいて、v2はv1よりも優れていることがわかる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/159589/60ffb805-5c42-accc-bef2-baa92dc56b9a.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/159589/4965c055-7264-59c2-0496-ecb604990a21.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/159589/1f6e6184-9ad1-ddc2-38d6-f95ea4ec6ec7.png)

v1はXMLエンコーディングに合わせて文字列ベースで作られていたが、v2ではJSONベースで様々な型が利用できる。

以下の例がわかりやすい。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/159589/aad249af-976f-6af2-2b3f-cd5fc5595a36.png)

Datetimeについても、v1は文字列でしか扱うことはできないが、v2ではサポートされている。
これは、v2が優れているというより、v1がビミョーなきがする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/159589/a9a9b18d-0b3e-a357-796e-195e5149964e.png)

ページネーションだと露骨にv1はまずい。
上:v1、下:v2
errorCodeとして扱われている。(errorではないにも関わらず)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/159589/07738d55-0d0a-8178-ac76-69ef12aa8ce6.png)


# その他
## RESTfulとは
REpresentational State Transferの略

### 特徴
#### アドレス可能性
URIをつうじ、リソースを端的にさし示すことができる性質を有している。APIのバージョン、データを取得するのか、それとも更新するのか、などが一目でわかるように全ての情報が一意なURIで表現されているようにすること。

#### ステートレス性
全てのHTTPリクエストが完全に分離している性質であること。セッション管理などの状態管理は行われない。

#### 接続性
ある情報に「別の情報へのリンク」を含めることができること。また別の情報に接続できること。

#### 統一インタフェース
CRUDは全てHTTPメソッドを使用すること


# 参考資料
https://businessnetwork.jp/Detail/tabid/65/artid/245/Default.aspx
https://www.slideshare.net/fisuda/ngsiv2-overview-for-developers-that-already-know-ngsiv1-ja
JPS(JavaServer pages)

#JPS(JavaServer pages)
リクエストされるとサーブレットクラスに変換

##スクリプトレット
Javaのコードを埋め込む

```php:記述方法
<% Javaのコード %>

```

##スクリプト式
変数・メソッド・戻り値などを出力する

```php:記述方法
<%= Javaのコード %>

```

##JSPコメント
コメントの記述

```php:記述方法
<%-- コメント --%>

```

##pageディレクティブ
JPSファイルの設定

```php:記述方法
<%@ page 属性名="値" %>

```

##URL

```php:記述方法
http://<サーバ名>/<アプリケーション名>/<WebContentからのパス>

```
Tips: Ansibleにおけるwhile, until処理


Ansibleによる単一のタスクに対するループ(until)
-------------------------------------

```yaml
-
  until: r.stdout|int <= 0
  shell: |
    NEW=$(( $(cat NUM) - 1 ))
    echo $NEW > NUM
    cat NUM
  register: r
  retries: 10
  delay: 0
```


この例では、shellタスクのstdoutが0以下になるまで、もしくは最大でretries:指定の10回まで処理を繰り返します。
終了条件には、shellモジュールならばコマンドのstdout, stderr, rcなど、register変数に設定される値が使用可能です。
retries:は最大リトライ回数で、省略可能ですがデフォルトは3回とかなり少ない為、余裕を持った指定が必要です。
delay:はループの待ち時間(秒)でデフォルトは1(秒)です。
breakは、until:の条件を満たす事で対応可能です。例えば上の例の場合、echo 0; exit などとすればこのタスクを抜ける事ができます。

コマンド実行結果を判断に使用する為、until:の条件を満たしていても最初の1回は実行されます。


### NUM初期値が5の場合の出力例

```
TASK [shell] *******************************************************************
FAILED - RETRYING: command (10 retries left).
FAILED - RETRYING: command (9 retries left).
FAILED - RETRYING: command (8 retries left).
FAILED - RETRYING: command (7 retries left).
changed: [localhost]
```

5回実行。
untilの条件を満たす事ができなかった回はFAILEDと表示される。5回目に成功して、changed: が出力されている。
retries:の回数内で成功しなかった場合にはtaskそのものがfailedとなる。
実行後のNUMは0。

### NUM初期値が1の場合の出力例

```
TASK [shell] *******************************************************************
changed: [localhost]
```

1回実行。
実行後のNUMは0。


### NUM初期値が0の場合の出力例

```
TASK [shell] *******************************************************************
changed: [localhost]
```

untilの為、1回は実行されてしまう。
実行後のNUMは-1。



Ansibleによる単一のタスクに対するループ(while)
-------------------------------------


通常のプログラミング言語におけるwhileループ、即ち、初回実行に関しても条件による実施判断を行わせるには、例えば以下の様に、事前に情報収拾を行い、when:により判断させる対応が可能でしょう。

```yaml
-
  shell: |
    cat ./NUM
  register: r0
  changed_when: false

-
  when: not r0.stdout|int <= 0
  until:    r1.stdout|int <= 0
  shell: |
    NEW=$(( $(cat ./NUM) - 1 ))
    echo $NEW > ./NUM
    cat ./NUM
  register: r1
  retries: 10
  delay: 0
```

この例では判り易さの為にr0, r1とregister変数を分けていますが、上書きされるので同じ変数を再利用可能です。


### NUM初期値が0(もしくは負)の場合の出力例

```
TASK [shell] *******************************************************************
skipping: [localhost]
```

0回実行(skip)
実行後のNUMは変更なし。



ブロックに対するループ
---------------------

untilやloop:などは個別のタスクに対してのみ指定可能であり、taskを集めたblock:に対して実施できないという制約があります。(エラーとなります。)
また、個別のタスクに複数のループを指定できない事から、そのままでは任意の多重ループに関しても実現できません。
この状況を回避するには、以下の様な対応が可能です。

- 別ファイルに分けたロジックを動的に読み込むinclude_tasks:などに対してループを行う

静的に読み込むimport_tasksなどは使用できない為、制約などがありうる事に注意が必要です。

[公式: Tradeoffs and Pitfalls Between Includes and Imports](https://docs.ansible.com/ansible/latest/user_guide/playbooks_reuse.html#tradeoffs-and-pitfalls-between-includes-and-imports)
S3とCloudFrontを使ったサイトを公開するために最低限行うべき手順

# 前提
- 公開するドメインを取得していること。説明上、<ドメイン名>と表記。
- 以下に挙げるサービスが利用できるアカウントを持っていること

# 利用するAWSサービス
- S3
- CloudFront
- Route53
- Certificate Manager


# 手順

## 1. バケットを作成

S3を開き、バケットを作成します。

|項目|値|
|:--|:--|
|バケット名|<ドメイン名>|

## 2. ホストゾーンを作成

Route 53を開き、ホストゾーンを作成する。

|項目|値|
|:--|:--|
|ドメイン名|<ドメイン名>|
|コメント|（任意）|
|タイプ|パブリックホストゾーン|

## 3. SSL証明を取得

Certificate Managerを開き、証明書をリクエストする。

|項目|値|
|:--|:--|
|証明書タイプ|パブリック証明書のリクエスト|
|ドメイン名|*.<ドメイン名>|
|検証方法|DNSの検証|

作成されたリクエストを選択し、「Route53でのレコードの作成」を押下する。

ステータスが「発行済み」になるまで待つ。

## 4. ディストリビューションの作成

CloudFrontを開き、「Web」のディストリビューションを作成する。

|項目|値|
|:--|:--|
|Origin Domain Name|1.で作成したバケット|
|Restrict Bucket Access|Yes|
|Origin Access Identity|Create a new identity|
|Grant Read Permissions on Bucket|Yes, Update Bucket Policy|
|Viewer Protocol Policy|Redirect HTTP to HTTPS|
|Alternate Domain Names|<ドメイン名>|
|SSL Certificate|Custom SSL Certificate（3.で発行された証明書）|
|Default Root Object|index.html|

Stateが「Enabled」になるまで待つ。

## 5. コンテンツアップロード

作成したバケットにindex.htmlをアップロードする。

ブラウザから、「https://<ドメイン名>」にアクセスすると表示される。


# 参考サイト

- [CloudFrontを使用してS3静的ウェブサイトを提供する手順](https://dev.classmethod.jp/articles/cloudfront-s3-web)
ファイルを DATA URI に変換するフォーム

# ファイルを DATA URI に変換するフォーム

```html
<!DOCTYPE html>
<html lang="ja">

<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <title>DATA URI 変換</title>
  <meta name="viewport" content="width=device-width, initial-scale=1">
</head>

<body>
  <input type="file" id="fileform">
  <br>
  <br>
  <textarea id="datauri" cols="100" rows="30"></textarea>
  <br>
  <button type="button" id="copybutton">コピー</button>
  <script>
    const toBase64DataUri = file => new Promise(resolve => {
      const reader = new FileReader();
      reader.onload = () => resolve(reader.result);
      reader.readAsDataURL(file);
    });

    document.getElementById("fileform").addEventListener("input", async (e) => {
      const file = e.target.files[0];
      const datauri = await toBase64DataUri(file);
      document.getElementById("datauri").value = datauri;
    }, false);

    document.getElementById("copybutton").addEventListener("click", () => {
      document.getElementById("datauri").select();
      document.execCommand("copy");
    }, false);
  </script>
</body>

</html>
```
# ファイルを DATA URI に変換してる部分
```javascript
const toBase64DataUri = file => new Promise(resolve => {
  const reader = new FileReader();
  reader.onload = () => resolve(reader.result);
  reader.readAsDataURL(file);
});
```
# ファイルを DATA URI に変換してる部分を呼び出している部分
```javascript
const datauri = await toBase64DataUri(file);
```
Servlet(サーブレット)

#Servlet(サーブレット)
サーバーサイドプログラムを作るための技術
サーバレットクラスを作りAPサーバ上で実行する
ブラウザからのリクエストによって実行され、結果をHTMLで出力しAPサーバによってブラウザにレスポンスする

##doGet()メソッド
サーブレットクラスがリクエストされると実行されるメソッド

##HttpServletRequest
ブラウザから届いたリクエストに関する情報と機能を持つインスタンス

##HttpServletResponse
サーバから送り出すレスポンスに関する情報と機能を持つインスタンス

##Content-Typeヘッダ

##URL
```PHP:Java
http://<サーバー名>/<アプリケーション名>/<URLパターン>
```
@WebServlet("/URLパターン")で設定
windows flutter インストール　手順　と捕まったところ


https://flutter.io/setup-windows/

zip install

zip Cに展開

flutter/bin/flutter.bat 管理者実行

flutter/bin pathを通す

flutter doctor　実行

エラーでた
: Android license status unknown.


```
対応
JDK インストール
https://www.oracle.com/java/technologies/javase-jdk14-downloads.html
->同じエラー
android　studio　（インストール済み）
setting->appearance&Behavior system Settings->Android SDK
SDK Tools -> android SDK tools インストール

```

flutter doctor --android-licenses
【JavaScript】2次元のベクトルクラス【HTML5】

#はじめに
自分用の2次元のベクトルクラスです。
ES6で書いています。静的クラスとして書いています。

#ソース
```js
// ベクトルクラス(ベクトルの計算に使用)
class Vector {
    // 足し算
    static add(v0, v1) {
        return {
            x: v0.x + v1.x,
            y: v0.y + v1.y,
        };
    }
    // 引き算
    static subtract(v0, v1) {
        return {
            x: v0.x - v1.x,
            y: v0.y - v1.y,
        };
    }
    // スカラー倍
    static scale(v0, s) {
        return {
            x: v0.x * s,
            y: v0.y * s,
        };
    }
    // ベクトルの長さを返す
    static length(v) {
        return Math.sqrt(v.x * v.x + v.y * v.y);
    }
    // 単位ベクトルを返す(非破壊的)
    static unit(v) {
        const len = Vector.length(v);
        return {
            x: v.x / len,
            y: v.y / len
        };
    }
    // 内積
    static innerProduct(v0, v1) {
        return v0.x * v1.x + v0.y * v1.y;
    }
}

```
【JavaScript】 特定の要素が配列に含まれるか判定する

JavaScriptにin演算子があったので、SQLみたいに以下のように書けるかと思ったのですが、うまくいきませんでした😥

```js
const arr = ['a', 'b', 'c'];
console.log('a' in arr); // falseになってしまった
```

どうやらJavaScriptのin演算子は「要素」が含まれるかどうかのチェックではなく、「プロパティ」が含まれるかどうかをチェックするみたいです😌

ですので、以下のような感じが正しい使い方
（arr.lengthは要素の数を返すプロパティ）

```js
const arr = ['a', 'b', 'c'];
console.log('length' in arr); // trueになる
```

今回求めたい、特定の要素が含まれるかどうか、というのはindexOfもしくはincludesで判定できます😁

```js
const arr = ['a', 'b', 'c'];
console.log(arr.indexOf('a') !== -1); // trueになる
console.log(arr.includes('a')); // trueになる
```
【JavaScript】3x3の行列クラス【HTML5】

#はじめに
自分用の3x3の行列クラスです。
ES6で書いています。静的クラスとして書いています。

#ソース
```js
// 行列クラス(行列の計算に使用)
class Matrix {
    // m0は行列、m1は行列又はベクトル
    // 行列は大きさ9の1次元配列であること。 ex. [ 1, 0, 0, 0, 1, 0, 0, 0, 1 ]
    // ベクトルはxとyをプロパティに持つ連想配列であること。 ex. { x: 2, y: 4 }
    // 左からベクトルをかけることは想定していない
    static multiply(m0, m1) {
        if(m1.length && m1.length === 9) {// m1は行列
            return [
                m0[0] * m1[0] + m0[1] * m1[3] + m0[2] * m1[6],
                m0[0] * m1[1] + m0[1] * m1[4] + m0[2] * m1[7],
                m0[0] * m1[2] + m0[1] * m1[5] + m0[2] * m1[8],
                m0[3] * m1[0] + m0[4] * m1[3] + m0[5] * m1[6],
                m0[3] * m1[1] + m0[4] * m1[4] + m0[5] * m1[7],
                m0[3] * m1[2] + m0[4] * m1[5] + m0[5] * m1[8],
                m0[6] * m1[0] + m0[7] * m1[3] + m0[8] * m1[6],
                m0[6] * m1[1] + m0[7] * m1[4] + m0[8] * m1[7],
                m0[6] * m1[2] + m0[7] * m1[5] + m0[8] * m1[8],
            ];
        } else {// m1はベクトル
            return {
                x: m0[0] * m1.x + m0[1] * m1.y + m0[2],
                y: m0[3] * m1.x + m0[4] * m1.y + m0[5],                
            };
        }
    }
    // 単位行列
    static identify() {
        return [1, 0, 0, 0, 1, 0, 0, 0, 1];
    }
    // 平行移動行列
    static translate(x, y) {
        return [1, 0, x, 0, 1, y, 0, 0, 1];
    }
    // 拡大縮小行列
    static scale(x, y) {
        return [x, 0, 0, 0, y, 0, 0, 0, 1];
    }
    // 回転行列
    static rotate(theta) {
        const cos = Math.cos(theta),
            sin = Math.sin(theta);
        return [cos, -sin, 0, sin, cos, 0, 0, 0, 1];
    }
    // 逆行列を求める
    static inverse(m) {
        const det = Matrix.determinant(m),
            inv = [
                m[4] * m[8] - m[5] * m[7],    -(m[1] * m[8] - m[2] * m[7]),   m[1] * m[5] - m[2] * m[4],
                -(m[3] * m[8] - m[5] * m[6]), m[0] * m[8] - m[2] * m[6],      -(m[0] * m[5] - m[2] * m[3]),
                m[3] * m[7] - m[4] * m[6],    -(m[0] * m[7] - m[1] * m[6]),   m[0] * m[4] - m[1] * m[3]
            ];
        return inv.map(elm => elm / det);
    }
    // 行列式を求める
    static determinant(m) {
        return m[0] * m[4] * m[8] 
        + m[1] * m[5] * m[6] 
        + m[2] * m[3] * m[7]
        - m[2] * m[4] * m[6]
        - m[1] * m[3] * m[8]
        - m[0] * m[5] * m[7];
    }
}
```
MacでUSBシリアル接続する

# 概要
NECのルーターUNIVERGE IX2105の設定を弄ることになったが、Mac端末しかない。
Macで初めてのコンソール接続にチャレンジした。

# 環境
* PC：Macbook Pro 13inch(Mojave)
* USB Type-C - USB変換：Amazonにあるようなやつ
* USB - RS-232C変換ケーブル：[サンワサプライ USB-CVRS9](https://www.sanwa.co.jp/product/syohin.asp?code=usb-cvrs9)
* コンソールケーブル：IX2105に同梱のもの

# ドライバの入手

[こちら](https://www.uramiraikan.net/Works/entry-2243.html)のサイトを参考にさせていただいた。
上記変換ケーブルはATEN社の[UC-232A](https://www.aten.com/jp/ja/products/usb-&-thunderbolt/usb%E3%82%B3%E3%83%B3%E3%83%90%E3%83%BC%E3%82%BF%E3%83%BC/uc232a/)という製品のOEMらしく（確かにTeraTermでATENと表示されていた）、そのドライバを入れればいいらしい。

最新のドライバがMac OS X 10.13（High Sierra）しかなかったが、10.14(Mojave)でもインストールできた。

インストールはウィザード形式で特にエラーも出ず、完了後OS再起動。

# ターミナルからの接続
ケーブルを接続し、ルーターの電源を入れた。
以下コマンドでデバイス名がわかるので「/dev/tty.UC-232AC」をコピーしておく。

```
> ls -l /dev/tty.*
crw-rw-rw-  1 root  wheel   18,   0  3 27 12:26 /dev/tty.Bluetooth-Incoming-Port
crw-rw-rw-  1 root  wheel   18,   2  3 27 12:45 /dev/tty.UC-232AC
```

screenコマンドでルーターに接続する。

```
> screen /dev/tty.UC-232AC
```
エンターキーを押したら繋がった！！

### 参考
https://ichibariki.hatenablog.com/entry/2016/11/01/203354


# 操作を終える場合
操作を終える場合は[control]キー + [A]キーの後に[K]キーを押すとscreenコマンドを終了するか聞かれる。


# スクロールできない！
ターミナルでスクロールができない。

``` 
vim ~/.screenrc
termcapinfo xterm* ti@:te@
```

これでスクロールできるようになった！

### 参考
https://blog.onk164.net/archives/462.html


# 終わりに
OSがCatalinaだったらドライバはインストールできたのだろうか。他に使うアプリケーションもCatalinaで動かないためMojaveに戻してしばらく使っている。
早くどうにかしてほしい・・・
Amazon Comprehendの感情分析をAWS CLIで行ってみた。

# Amazon Comprehendの感情分析をAWS CLIで行ってみた。
[Amazon Comprehend](https://ap-northeast-1.console.aws.amazon.com/comprehend/v2/home?region=ap-northeast-1#welcome)でできるらしい。

DetectSentimentのところを参照
https://docs.aws.amazon.com/comprehend/latest/dg/API_DetectSentiment.html

今回PythonでやってみるのでPython用のを見る。
https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/comprehend.html#Comprehend.Client.detect_sentiment

一番上に何をインポートすればいいか書いてある。
https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/comprehend.html

コードはこんな感じ。

```
import boto3
client = boto3.client('comprehend')

response = client.detect_sentiment(
    Text='東京オリンピックが延期になるなんて、まさにアキラの世界みたいだ。',
    LanguageCode='ja'
)
print(response)
```

結果はこんな感じ。

```
{'Sentiment': 'NEUTRAL', 'SentimentScore': {'Positive': 0.12571793794631958, 'Negative': 0.006899271160364151, 'Neutral': 0.8673694729804993, 'Mixed': 1.3250895790406503e-05}, 'ResponseMetadata': {'RequestId': 'e458bcfd-c85e-4314-bb01-f11b8e72ec8f', 'HTTPStatusCode': 200, 'HTTPHeaders': {'x-amzn-requestid': 'e458bcfd-c85e-4314-bb01-f11b8e72ec8f', 'content-type': 'application/x-amz-json-1.1', 'content-length': '164', 'date': 'Fri, 27 Mar 2020 04:44:21 GMT'}, 'RetryAttempts': 0}}
```
Laravelエラー：Argument 1 passed to App\Http\Controllers\GroupController::index() must be of the type int, string givenが出た時



<img width="600" alt="スクリーンショット 2020-03-27 13.29.23.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/394234/9d0cf32e-6ec7-2454-ef68-90b9a81cd0f8.png">

```
TypeError
Argument 1 passed to App\Http\Controllers\GroupController::index() must be of the type int, string given
```

このエラーについて、同じエラーで困ってる方がいたら確認して欲しいポイントをお伝えしていきたいと思います。

#web.phpのルーティング順序を疑ってみよう

前者がエラーが出ていた時のルーティングで、後者がエラーが消えた時のルーティングです。
書き順が違います。
本来は`/groups/new`を呼び出したいアクションでも`new`を`{id}`だと勘違いして、`/groups/{id}`を呼んでしまっていたようです。laravelは仕様で上に書いてある設定を先に読み込んでしまいます。
もっとスマートな解放がlaravalには用意されていると思うのですが、今回は簡単に順序を入れ替えてエラー対処しました。


```web.php
//前者
//グループ一覧表示
Route::get('/groups/{id}', 'GroupController@index')->name('groups.index'); 
//グループを新規作成ページを表示
Route::get('/groups/new', 'GroupController@new')->name('group.new');
//グループを新規作成
Route::post('/groups/new', 'GroupController@store');

```

```web.php
//後者
//グループを新規作成ページを表示
Route::get('/groups/new', 'GroupController@new')->name('group.new');
//グループを新規作成
Route::post('/groups/new', 'GroupController@store');
//グループ一覧表示
Route::get('/groups/{id}', 'GroupController@index')->name('groups.index'); 
///groups/{id}のルーティングを一番下に移動
```
GASでgmailの宛先を複数追加する方法

## A.コンマ区切りのStringで定義する
宛先(to, cc, bcc)は、コンマ区切りのStringで定義する。
アドレスを配列に入れて、joinするのが便利。

```
GmailApp.createDraft(to, subject, body, {cc:[address1, address2].join(',')}
```
参考:[createDraft(recipient, subject, body, options) ](https://developers.google.com/apps-script/reference/gmail/gmail-app#createDraft(String,String,String,Object))
VuePress で alias の設定方法


`.vuepress/config.js` に以下のように書きます。書き方は、２通りあります。configureWebpack をオブジェクトにする書き方と、関数にする書き方です。

```js:.vuepress/config.js
const path = require('path')

module.exports = {
  configureWebpack: {
    resolve: {
      alias: {
        '@root': path.join(__dirname),
        '@account': path.join(__dirname, 'account')
         //                              ^^^^^^^^^ .vuepress/config.js からの相対パスを書きます。
      }
    }
  }
}
```
```js:.vuepress/config.js
const path = require('path')

module.exports = {
  configureWebpack: (config, isServer) => {
    config.resolve.alias['@root'] = path.join(__dirname)
    config.resolve.alias['@account'] = path.join(__dirname, 'account')

    // config の中身が見たいときは console.dir(config) の後に
　　 // エラーを投げて強制的に動作を止めて中身を確認していました。
    // console.dir の内容がターミナルに表示されず（画面が更新されるため）
    // 加えて debugger 文でも止められなかったためです。
    console.dir(config)
    throw new Error('-- stop --')
  }
}
```

* [configreWebpack - VuePress](https://v1.vuepress.vuejs.org/config/#configurewebpack)
* [Relative URLs - VuePress](https://v1.vuepress.vuejs.org/guide/assets.html#relative-urls)
* [Resolve - webpack](https://webpack.js.org/configuration/resolve/)

自分の環境では設定を適用する際は `yarn run dev` を再度行う必要がありました。hot reload が効きませんでした。

Nuxt.js も同じような書き方をするようです。

* [Nuxt.js で webpack.config を拡張してaliasを登録する - Qiita](https://qiita.com/soutarrr7/items/1b9a46df604ed78ec747)