OmniAICreator/Qiita-1.07M huggingface dataset:
DPDKのビルド・実行が出来るようになるまでのメモ


## 環境
- Intel(R) Xeon(R) CPU
- Ubuntu 16.04 LTS
- DPDL 17.11.2 LTS

## 手順

DPDKをダウンロード

```
cd ~
curl https://fast.dpdk.org/rel/dpdk-17.11.2.tar.xz | tar xJvf -
```

NUMAのライブラリをインストール

```
sudo apt install libnuma-dev
```

DPDKのセットアップツールを実行

```
cd dpdk-stable-17.11.2/usertools/
./dpdk-setup.sh
```

`[14] x86_64-native-linuxapp-gcc`を選択
ビルドが走る

ビルド後，`[34] Exit Script`で抜ける

```
sudo mkdir -p /opt/dpdk/
sudo cp ~/dpdk-stable-17.11.2 /opt/dpdk
```

bashrcに環境変数を設定する

```
vim .bashrc
```

DPDKへのパスを通す

```.bashrc
export RTE_SDK=/opt/dpdk/dpdk-stable-17.11.2/
```

サンプルプログラムのコンパイルができるか試す

```
cd ~/dpdk-stable-17.11.2/examples/helloworld
make
```
これでビルドが成功すればDPDKが使えるようになっている．


実行にはhugepageの設定が別途必要
ここでは一時的な方法を使う

```
sudo su -c "echo 20 > /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages"
```

サンプルプログラムを実行

```
sudo ./helloworld
```

実行結果

```
EAL: Detected 32 lcore(s)
EAL: No free hugepages reported in hugepages-1048576kB
EAL: Probing VFIO support...
EAL: PCI device 0000:03:00.0 on NUMA socket 0
EAL:   probe driver: 8086:1528 net_ixgbe
EAL: PCI device 0000:03:00.1 on NUMA socket 0
EAL:   probe driver: 8086:1528 net_ixgbe
EAL: PCI device 0000:07:00.0 on NUMA socket 0
EAL:   probe driver: 8086:1521 net_e1000_igb
EAL: PCI device 0000:07:00.1 on NUMA socket 0
EAL:   probe driver: 8086:1521 net_e1000_igb
hello from core 1
hello from core 2
hello from core 3
hello from core 4
hello from core 5
hello from core 6
hello from core 7
hello from core 8
hello from core 9
hello from core 10
hello from core 11
hello from core 12
hello from core 13
hello from core 14
hello from core 15
hello from core 16
hello from core 17
hello from core 18
hello from core 19
hello from core 20
hello from core 21
hello from core 22
hello from core 23
hello from core 24
hello from core 25
hello from core 26
hello from core 27
hello from core 28
hello from core 29
hello from core 30
hello from core 31
hello from core 0
```

これで一通りDPDKが使えるようになった！
あとはhugepageを再起後も使えるように`grub.cfg`に設定すればOK

```
sudo vim /etc/default/grub
```

下記はデフォルトのhugepageを1Gに設定し，1Gを1つ確保する例

```diff
-GRUB_CMDLINE_LINUX=""
+GRUB_CMDLINE_LINUX="default_hugepagesz=1G hugepagesz=1G hugepages=1"
```

こういった設定もできる
これは1Gを1，2Mを20確保する例

```
GRUB_CMDLINE_LINUX="default_hugepagesz=1G hugepagesz=1G hugepages=1 hugepagesz=2M hugepages=20"
```

設定後，下記のコマンドでgrubを反映して再起動

```
sudo update-grub
sudo reboot
```

下記のように，hugepage_totalが1になっていれば設定されている

```
 cat /proc/meminfo  | grep HugePage
AnonHugePages:         0 kB
HugePages_Total:       1
HugePages_Free:        1
HugePages_Rsvd:        0
HugePages_Surp:        0
```
terraformのタブ補完が効かなくなった時に見るメモ（version 0.11.6〜）

# はじめに
久々にMacにインストールしているterraformをアップデートしたら、zshのタブ補完が効かなくなってしまいました。
原因、経緯、対策を調べたので、超スーパーメモとして残します。

# 前提
* macOS
* zsh
* terraformはhomebrewでインストールしています
* terraform 0.11.1 -> 0.11.7 にバージョンアップしました

# 原因
* terraform 0.11.6から、zshの補完関数群が消されていました<br>
[Remove old completion file for zsh by ryosan-470 · Pull Request #17527 · hashicorp/terraform · GitHub](https://github.com/hashicorp/terraform/pull/17527)
<br><br>
* brewのFormulaからも補完関数をインストールするくだりが消された<br>
[terraform 0.11.6 by commitay · Pull Request #26224 · Homebrew/homebrew-core · GitHub](https://github.com/Homebrew/homebrew-core/pull/26224/files#diff-894421d9cc7cc4f146506e6b88b2f780L51)

# 背景
* 少し前からタブ補完をコマンド自体に組み込んでしまおうという方針になっているようです<br>
[CLI autocomplete by apparentlymart · Pull Request #16176 · hashicorp/terraform · GitHub](https://github.com/hashicorp/terraform/pull/16176)

# 対策
* 以下のコマンドを実行すると、補完に必要となる設定を~/.zshrcおよび~/.bashrcに追記してくれます

```command.
terraform -install-autocomplete
```

```~/.zshrcに追記される内容
autoload -U +X bashcompinit && bashcompinit
complete -o nospace -C /usr/local/Cellar/terraform/0.11.7/bin/terraform terraform
```
ref.) [Commands - Terraform by HashiCorp](https://www.terraform.io/docs/commands/index.html#shell-tab-completion)


* が、見ての通りコマンド実体を参照しており、今後もhomebrew運用を続けるのであれば以下のようにシンボリックリンクのほうに書き換えたほうがよさそうです

```
complete -o nospace -C /usr/local/bin/terraform terraform
```

# おわりに
CIでもterraformを使っているのでなかなかバージョンアップしないのですが、相変わらずマイナーバージョンアップでもけっこう変わりますね。
個人的には元のほうがよかったのと、実装を見る限り各コマンド（applyとかplanとか）ごとに補完処理を書いていくようで、なかなか大変そうだなと思いました。
ただ、マルチクラウド構成管理ツールの雄であるterraformだけに、実行環境の環境差異も極力吸収したいということなのかもしれませんね。
Tao of HashiCorp万歳🙌 ということでこちらからは以上です。
Alexa開発者ポータルの概要

#目次
1. 呼び出し名の設定
2. インテントの設定
3. サンプル発話の設定
4. インテントスロットの設定

<br>

###1.呼び出し名の設定
スキルを起動させる時の名前を設定する

<img width="288" alt="スクリーンショット 2018-04-25 16.19.21.png" src="https://qiita-image-store.s3.amazonaws.com/0/249053/b5842643-f69d-0653-44ae-27efad269580.png">


###2.インテントの設定
インテントとは、
Alexaに呼びかける言葉とそれに対応する機能を結びつける変数のようなもの
Ex)「助けて」「使い方わからない」「ヘルプ」→使い方を説明するHelpIntentを呼び出す

<img width="200" alt="スクリーンショット 2018-04-25 16.27.22.png" src="https://qiita-image-store.s3.amazonaws.com/0/249053/523681fe-8c26-9055-2938-a3fa414a676e.png">

あらかじめ用意されている標準インテントがあるが、
任意の名前でカスタムインテントを設定することも可能

| 標準インテント | 概要 |
|:-----------:|:------------:|
|StopIntent|スキルまたは今の会話を中断する|
|CancellIntent|スキルまたは今の会話を中断する|
|HelpIntent|使い方のヘルプを提供|
|YesIntent|二者択一の質問に'はい'で答える|
|NoIntent|二者択一の質問に'いいえ'で答える|
|StartOverIntent|アクションを最初からやり直す|
|ShuffleOnIntent|シャッフルをオンにする|
|ShuffleOffIntent|シャッフルをオフにする|
|LoopOnIntent|ループをオンにする|
|LoopOffIntent|ループをオフにする|
|RepeatIntent|最後のアクションを繰り返す|
|PauseIntent|進行中のアクションを一時停止する|
|ResumeIntent|停止中のアクションを再開・継続する|
|PreviousIntent|リストの前の項目に移動する|
|NextIntent|リストの次の項目に移動する|
<br>

###3.サンプル発話の登録 
インテントを呼び出す時の話し方を全て設定する
疑問形の？などはこの発話には入力しないこと。あくまで呼び出す時の言葉のみ

任意の単語を受け取りたいときはインテントスロット(下画像の{name}の部分)を設定する

<img width="250" alt="スクリーンショット 2018-04-27 13.04.29.png" src="https://qiita-image-store.s3.amazonaws.com/0/249053/5fe10990-5338-fe2b-bc69-6aedc13cf87c.png">
<br>

###4.インテントスロットの設定
定型句で呼び出すのみのスキルを実装する人はここは飛ばして良い

ここで名前や時間・曜日などを受け取る変数を設定する
下の画像を例にとると、
`name→変数名
AMAZON.FirstName→変数の型`
となり、
「{name}さんの予定は」とサンプル発話を設定したうえで「鈴木さんの予定は」と話しかけると、nameに鈴木が入る。


<img width="400" alt="スクリーンショット 2018-04-27 13.08.47.png" src="https://qiita-image-store.s3.amazonaws.com/0/249053/6b31a3fa-507d-4109-ae4f-4ba838631c81.png">

Amazonでは時間や数字・名前などをある程度自動で取ってくれるスロットタイプが用意されている(AMAZON.FirstNameも名前をある程度自動で取ってくれるという用意されたもの)
種類や細かい概要は[スロットタイプリファレンス](https://developer.amazon.com/ja/docs/custom-skills/slot-type-reference.html)を参照
WordPressローカル環境構築 on VCCW

WordPressをでサイトを作りたい。
わしノンプログラマ。
デザインバイチョイスで良くて、見せたいコンテンツに最適なテーマは探せば出てくるのでそれでよしとする。
ゴリゴリのカスタマイズは不要。

とりあえず10回くらいインストールからテンプレート当てるまでをやってみて把握したい。

## VCCW 良さそう。

> WordPressをVagrant環境にらくらくインストールする。 - VCCW
https://qiita.com/naru0504/items/58011181f2c271808c7f

http://vccw.cc/

なるほど。

VirtualBox は IE 検証用にインストール済み。
Vagrant をインストールする。

あとは、↓ ここにある通り、テンプレートを設置して起動 → とりあえず動いた。

http://vccw.cc/#h2-2


## WP-CLI でほいほい作れるようになりたい。

> WP-CLIでVCCW環境をほいほい作る
https://qiita.com/miya0001/items/687d142d714b1386a44f



#### WP-CLIのインストール
↓ インストール→ファイルのパーミッションを変更→パスを通す。

> 仮想環境で始めるWordPressローカル環境開発手順
https://qiita.com/nishina555/items/1a10b1fbe17b847a4a6d

#### WP-CLI で WPのパッケージをローカルにインストール。

```
$ wp package install vccw/scaffold-vccw:@stable
```
メモリ不足のエラー出た。

> WP-CLI でメモリ不足のエラーが出る時の対処法
https://qiita.com/miya0001/items/9797832db58b60786803

→ 自分の環境だと、.bash_profile に書き込む一択でした。

#### VCCWファイルのダウンロード。
任意のフォルダに移動してコマンド実行。オプションで言語を指定。

```
$ wp scaffold vccw wpdev --lang=ja
```

#### Vagrantを起動

```
$ vagrant up
```

#### ビューを見る

http://vccw.test/ (デフォルト:internal)
http://192.168.33.10/ (デフォルト:external)

#### Vagrantを終了
```
$ vagrant halt
```





## WPの知識アップデート

- Repeater Field  
	Advanced Custom Fields のアドオン（有料）  
	Advanced Custom Fields の入力項目を、管理画面からGUIで任意に増やすことができる。マジ必須。知らなかった…。

https://hirashimatakumi.com/blog/30.html


- Theme Test Drive  
	権限持っている人だけ新しいテンプレート見れるプラグイン

https://love-guava.com/wordpress-theme-test-drive-plugin/
Google Calendar 新デザインで説明欄に HTML タグがついてたので対応（Swift）

小ネタ。

もう大分前になるのですが、Google Calendarが新しいデザインになりました。（たしか2018年1月8日ぐらいから）

iOSアプリ（Swift記述）でGoogle Calendar APIを利用し、カレンダーイベントの説明欄に、特定の記述が入っていたら処理を実行するみたいなソースコードを書いていたのですが、見事動かなくなりました。

原因はタイトルの通り、カレンダーの説明欄にHTMLタグが入るようになったからです。その対応を行ったので、コードのメモ書き。

```swift
if let events = response.items, !events.isEmpty {
    for event in events {
        if event.descriptionProperty != nil {
            // カレンダーイベント説明項目（descriptionProperty）からHTMLタグ消す
            let eventNonHtml = event.descriptionProperty.replacingOccurrences(of: "<.+?>", with: "", options: String.CompareOptions.regularExpression, range: nil)
            print("説明項目: \(eventNonHtml)")
        }
    }
} else {
    print("No upcoming events found.")
}
```

※動かなくなった実際の処理ではない、かつリクエスト部分などの前後処理の記述も端折っています。詳細は[公式](https://developers.google.com/calendar/quickstart/ios?ver=swift)を参照してください。

HTMLタグなので<>に囲まれてる箇所を除けば欲しい説明欄の文章だけが取得できます。"replaceingOccurrences"を使いました。

せっかくならHTMLタグ有りと無しとで別のプロパティを用意してくれればよかったのに。。とも思いますが、そもそも説明欄を何かに使う人なんてほとんどいないでしょうから仕方ないですね。。。
Cognosの条件付きスタイルを他のレポートに簡単にコピーする方法

#はじめに
Cognosのレポート開発を実施している時に、すでに開発済みのレポート上に定義している「条件付きスタイル」をコピーしたいと思ったことはありませんか？
新規開発中のレポートで一から作成してもいいのですが、細かく書式を設定している場合は再度設定するのは手間だったりしますよね。設定漏れも起きやすくなってしまう箇所でもあります。

#条件付きスタイルは簡単にはコピーできない
レポート編集画面のこちらから (図1)、条件付きスタイルを参照することはできるのですが (図2)、
他のレポートに移行するためのコピー用のアイコンなどはありません。

(図1)
![WS000000.JPG](https://qiita-image-store.s3.amazonaws.com/0/146283/988bb061-edd5-a2b6-21f7-a5209c038cc6.jpeg)


(図2)
![WS000001.JPG](https://qiita-image-store.s3.amazonaws.com/0/146283/e442c035-3b43-b20a-4403-d1e62d679412.jpeg)



また、条件付きスタイルが設定されているリストやグラフなどのオブジェクトごとコピーしようとしても、「条件付きスタイル"条件付きスタイル1"はこのレポートにありません」とエラーになってしまいます。(図3)

(図3)
![WS000003.JPG](https://qiita-image-store.s3.amazonaws.com/0/146283/745da7c3-dce0-08c5-d93d-64146dad7271.jpeg)



#XMLベースでコピーを実施
そんな時に役に立つのが、レポートXMLを使用したコピーです。
レポートXML上、条件付きスタイルは\<namedConditionalStyles> タグで定義されています。
条件付きスタイル全体をコピーする場合は、この\<namedConditionalStyles> をまるっとコピーすることで新規レポートに移行できます。
条件付きスタイルが複数有り、定義ごとにコピーしたい場合は、\<advancedConditionalStyle name="条件付きスタイル 1"> (nameは条件付スタイルの定義名) をコピーすることで、対応可能です。この場合は、\<namedConditionalStyles> タグ内にコピーするようにしてください。


#詳細手順

1. コピー元のレポートのXMLを取得する
　　※「ページ」ペインから「レポート」を右クリックして「クリップボードにレポートをコピー」を選択します
![WS000004.JPG](https://qiita-image-store.s3.amazonaws.com/0/146283/50203a22-fb44-61f6-4f6f-2e2c2da2aedb.jpeg)

2. コピーしたXMLをテキストエディタに貼り付け、\<namedConditionalStyles> ~ \</namedConditionalStyles>の部分を見つけておく
　　※ XMLの最下部のほうに定義されているので下から探すと見つけやすいです。
![WS000005.JPG](https://qiita-image-store.s3.amazonaws.com/0/146283/86911217-6828-bd34-8f29-453ce920e45a.jpeg)

3. コピー先のレポートのXMLを取得する
　　※ 手順1と同様の操作で、今開発中にレポートのXMLを取得します
4. 手順2で見つけた条件付きスタイルに関する定義部分を、\</reportName>と\</report>の間にコピーします
![WS000006.JPG](https://qiita-image-store.s3.amazonaws.com/0/146283/cb0d8258-e383-e3d9-af93-1fe31d5eefd4.jpeg)

5. 条件付きスタイルの定義を追加したXML全体をクリップボードにコピーする
　　※ 全選択してからコピーを実施しましょう
6. クリップボードからレポートを開き、条件付きスタイルがコピーされていることを確認します。
　　※「ページ」ペインから「レポート」を右クリックして「クリップボードからレポートを開く」を選択します。
![WS000004 - コピー.JPG](https://qiita-image-store.s3.amazonaws.com/0/146283/37f5c961-f088-3137-ec0c-8ba008297828.jpeg)

　　※ 条件付きスタイルの確認は、上述の図1、図2のキャプチャを参考に確認してください。

正しく、条件付きスタイルがコピーできていたら、レポートに名前をつけて保存します。




以上で、条件付きスタイルのコピーが完了です。
いかがでしたか。Cognosのレポート開発はGUIベールのツールですがXMLを使用することで、簡単に定義をコピーすることができました。
ServiceNowでJavaのHttpClientを操作する

# 作るもの

ServiceNowのServer SideのScriptでJavaのHttpClientを操作します

![FireShot Screen Capture #013 - 'Incident Ticket System' - dev48240_service-now_com_nav_to_do_uri=_sys_scripts_do.png](https://qiita-image-store.s3.amazonaws.com/0/193272/7b2212b0-a71b-9427-40f2-6e3d7e60b872.png)

# Scripts - Backgroundで試す

ServiceNowには[System Web Service] - [▼Outbound] - [SOAP Message], [System Web Service] - [▼Outbound] - [REST Message]とServiceNowから外部サイトにHTTP Requestを送る機能が用意されているのですが

[ServiceNowでHTTP Request/Responseを実行してScriptへの組み込み方を確認する]
https://qiita.com/20_percent_cooler/items/468edc9a1fbe51ca179a

外部サイトのWeb ServerにおいてHttp ResponceのHeaderにSet-Cookieを指定された場合に上記機能だけで一旦受け取って次のHTTP Requestに設定するといったことが難儀だったので他に方法が無いか検索したところ、以下の情報を見つけました

[HTTP POST to external url - Developer Community - ServiceNow Community](
https://community.servicenow.com/community?id=community_question&sys_id=05b01f69dbdcdbc01dcaf3231f961973

*This should get you started. It is basically just the Java HttpClient library so the javadocs have been helpful to us in figuring out obscure details.*

```
var client = new Packages.org.apache.commons.httpclient.HttpClient();
var post = new Packages.org.apache.commons.httpclient.methods.PostMethod("http://www.exampledestination.com/page_to_post_to.html");
post.addParameter("parameter_name", "parameter value");
var returnCode = client.executeMethod(post);
var output = "" + post.getResponseBodyAsString();
```

上記コードのurlの値を http://example.com に変更して最終行に画面にプリントする文を追加して

```
var client = new Packages.org.apache.commons.httpclient.HttpClient();
var post = new Packages.org.apache.commons.httpclient.methods.PostMethod("http://www.example.com");
post.addParameter("parameter_name", "parameter value");
var returnCode = client.executeMethod(post);
var output = "" + post.getResponseBodyAsString();
gs.print(output);
```

[Scripts - BackGround]のRun script(JavaScript execute on server)にコピペして

![FireShot Screen Capture #014 - 'Incident Ticket System' - dev48240_service-now_com_nav_to_do_uri=_sys_scripts_do.png](https://qiita-image-store.s3.amazonaws.com/0/193272/de64e966-e67a-b724-0813-a6edab72bad5.png)

[Run script]をクリックして実行して成功しました

![FireShot Screen Capture #013 - 'Incident Ticket System' - dev48240_service-now_com_nav_to_do_uri=_sys_scripts_do.png](https://qiita-image-store.s3.amazonaws.com/0/193272/7b2212b0-a71b-9427-40f2-6e3d7e60b872.png)

JavaのHttpClientが使えるのであればSet-Cookieをそのまま受け取れるので認証認可処理があるWeb Serverとおしゃべりする際など便利そうです

アプリケーションに組み込む場合には上記コードをServer SideのScript IncludeにClient Callableで実装してClientからはUI Actionのボタンから読み込んで実行といった感じでできそうです
プログラマ脳を鍛える数学パズル Q.2「数列の四則演算」

# もっとコードを書きたい
phpプログラミングを始めて半年以上がたった。その間phpの基本的な文法は一通り学んだが、処理やアルゴリズムに工夫をこらして書く経験も積みたいと思ったので、手始めに「プログラマ脳を鍛える数学パズル」という本の問題を解いてみることにした。
# 今回の問題
今回の問題は下記のとおりである。
>並んでいる数字の各桁の間に四則演算の演算子を入れて計算することにします（演算子を入れない場所があっても構いませんが、最低でも1つは入れるものとします）。
(中略)
できあがった式を計算した結果、「元の数の桁を逆から並べた数字」と同じになるものを考えます。なお、式の計算は数学の順序で行います。
100~999の場合、以下の3つがあります。
351　→　3+51 = 153
621　→　6+21 = 126
886　→　8*86 = 688
**問題**
1000~9999のうち、上記の条件を満たす数を求めてください

# 実装手順
実装手順は下記を考えた。
①1000から9999までのループ文を作る
②千の位と百の位、百の位と十の位、十の位と一の位を分け、それぞれの間に加減乗除を差し込む組み合わせを網羅するループ文を作る
③上記で作成した式を計算し、比較対象の4桁数字を反転させた数字と一致するか確認する
![201804ブログ画像.png](https://qiita-image-store.s3.amazonaws.com/0/210985/28d3f347-7e81-1b2a-dc30-3375aea98de7.png)

# 書いたPHPコードと問題点、JavaScriptで書き直し
php文は下記のとおりである。

```php:q02.php
<?php

// 四則演算を格納する配列
// 桁の間に四則演算が入らず数字が連結する場合もあるため、""も入れる
$tools = array("+", "-", "*", "/", "");

// 1000から9999まで数え上げるループ文
for ($i = 1000; $i < 10000; $i++) {
  // 千の位と百の位の間に入る四則演算記号を網羅するループ文
  for ($j = 0; $j  < count($tools); $j++) {
    // 百の位と十の位の間に入る四則演算記号を網羅するループ文
    for ($k = 0; $k < count($tools); $k++) {
      // 十の位と一の位の間に入る四則演算記号を網羅するループ文
      for ($l = 0; $l < count($tools); $l++) {
        // 四則演算された値を$numberに格納
        $number = (substr($i, 0, 1).$tools[$j].substr($i, 1, 1).$tools[$k].substr($i, 2, 1).$tools[$l].substr($i, 3, 1));
        // 元の4桁数字を反転させた数字と$numberを比較し、合致すれば出力
        if (strrev($i) === $number) {
          echo $number;
        }
      }
    }
  }
}
```
ここで1つ問題が発生した。
$tools配列にString型で四則演算記号を入れたが**元に戻す方法が分からなかった**
ググっても分からなかったため今回はJavaScriptで書き直すことにした。
実装手順はphpとほぼ同じ

```javascript:q02.js
<script>
  var op = ["+", "-", "*", "/", ""];
  for (i = 1000; i < 10000; i++) {
    var c = String(i);
    for (j = 0; j < op.length; j++) {
      for (k = 0; k < op.length; k++) {
        for (l = 0; l < op.length; l++) {
          val = c.charAt(3) + op[j] + c.charAt(2) + op[k] + c.charAt(1) + op[l] + c.charAt(0);
          if (val.length > 4) {
            if (i == eval(val)) {
              console.log(val + " = " + i);
            }
          }
        }
      }
    }
  }
</script>
```
答えは**5*9*31 = 1395**
できた～～:joy:

# 学び
- 頭の中でぼんやりとは解き方は浮かぶが、いざコードで表現しようとすると意外と手間がかかった。今の実力では頭の中でコードが完成することはないので、とにかく書いて体で覚えていこうと思う。

>**Shut the fuck up and write some code**
さっさとコードを書けよハゲ

- substr、strrev、複数のループ処理、まとめておきたい変数の配列格納など実務でも使えそうなアイデアや処理に触れられた。副産物も色々とありそう。
LumenでEloquent

Laravelより軽量なLumenということでEloquent使おうとしたらハマった。

いつも通りModelを作って

```php:UserController.php
$user = User::find(1);
```

実行してみると

```
FatalThrowableError
Call to a member function connection() on null
```

んん？
database.phpも大丈夫、というかphp artisan migrateできてる。

調べてみるとLumenではデフォルト設定ではEloquentは無効になってました。
[公式ドキュメント](https://lumen.laravel.com/docs/5.6/database)にもちゃんと書いてありました。

```
Eloquent ORM
If you would like to use the Eloquent ORM,
you should uncomment the $app->withEloquent() 
call in your bootstrap/app.php file.
```

ということで

```php:bootstrap/app.php
$app->withEloquent();
```

こんな感じにコメントアウトを外したら使えるようになります。
DB::select("SELECT * FROM users");みたいにクエリビルダーを使いたいなら

```php:bootstrap/app.php
$app->withFacades();
```

こちらもコメントアウト外す必要があります。
CWL conformance test 1に関して

CWL conformance test 1に関して
=============================


(追記: 2018-07-17)

- 実行したコマンドが `cwl.output.json` を作成した場合、それを回収する必要がある。
    - conformance test 1 (bwa-mem-tool.cwl)では、それが実行する。 `args.py` が `cwl.output.json` を作成する
    - 仕様としては[4.4](https://www.commonwl.org/v1.0/CommandLineTool.html#Output_binding)



いか、何度かはまる(のを横で見ていた)トラップのようなもの。

```
conformance_test の1番目のテスト、実は仕様を満たしていないのでは…？
と、思うことがあるが、満たしている。
```


- [仕様の 4.4](http://www.commonwl.org/v1.0/CommandLineTool.html#Output_binding) には `If the output directory contains a file named "cwl.output.json", ...` と記述がある
- [conforance_test](https://github.com/common-workflow-language/common-workflow-language/blob/master/v1.0/conformance_test_v1.0.yaml) の[1番目のテスト](https://github.com/common-workflow-language/common-workflow-language/blob/master/v1.0/v1.0/bwa-mem-tool.cwl) (と、[パラメータ](https://github.com/common-workflow-language/common-workflow-language/blob/master/v1.0/v1.0/bwa-mem-job.json))では、`args.py` が *カレントディレクトリ* に `cwl.output.json` を出力する
- cwltool を `--outdir` オプション込みで実行し、docker コマンドを確認しても、出力ディレクトリをマウントなどしている様子がない
 - docker 上のカレントディレクトリにある `cwl.output.json` を読み込んでしまっている
 - つまりこのテストは、`args` オブジェクトではなく `sam` オブジェクトと空の配列の `args` を返すのが仕様上は正しいはず！

という、思考をしてしまうことがあるが、実際には、以下に書いてある。

[4.2 Runtime Environment](http://www.commonwl.org/v1.0/CommandLineTool.html#Runtime_environment)


```
When executing the tool, the tool must execute in a new,
empty environment with only the environment variables
described below; the child process must not inherit
environment variables from the parent process except as
specified or at user option.

- `HOME` must be set to the designated output directory.
```

## Hints for implementation

まずは以下を見ればよいとのこと。

- [Common Workflow Language \(CWL\) Command Line Tool Description, v1\.0\.2](https://www.commonwl.org/v1.0/CommandLineTool.html#Input_binding)

おそらく、

1. 4.1.1 says objects from arguments first. (-t is written in arguments)
2. 4.1.2 says objects from the inputs next. (-I is written in inputs) So I think -t is before -I
3. Before section 4.1.1

```Strings are sorted lexicographically based on UTF-8 encoding.```

`min_std_max_min` < `minimum_seed_length`
4文字目の大小を比較した結果上記のようになるので、
`position` が `1` で同じだが、`-I`が `-m` より前になるのだろう
NavigationBarの戻るボタンをハンドリングしたい


※最新（2021年10月）で、進化版の記事はこちら。
https://www.fuwamaki.com/article/154

NavigationBarの戻るボタンって、StoryBoardで作成した際に自動で付いてくれるので非常に便利です。
ただ、戻る時に特定の挙動を加えたい場合、戻る操作イベントをトラッキングしたい場合などは、
戻るボタンをハンドリングする必要があります。

しかし、戻るボタン用のメソッドが用意されていないので、
厳密に戻るボタンをハンドリングすることは難しいです。
ただし、それっぽいことをすることはできます。

参考：[navigationbarのバックボタンを押した時に-値を渡したい](https://ja.stackoverflow.com/questions/34521/navigationbarのバックボタンを押した時に-値を渡したい)

## 開発環境

Mac OS High Sierra 10.13.3
Xcode 9.3
Swift 4

## おすすめしたくない方法：viewWillDisappearを利用

`viewWillDisappear` は、その画面が消えるときに呼ばれる挙動です。
これを用いれば、戻るボタンをハンドリングすることが可能です。
しかし、これだと不便な場合があります。下記例で示します。

【例】
遷移：画面A -> 画面B -> 画面C
目的：画面B -> 画面A に戻る際に確認アラートを出したい
実装：画面Bの `viewWillDisappear` に確認アラートを表示するコードを記載
-> **問題：画面B -> 画面C でも確認アラートがでてしまう**

画面Cが存在しない状況で利用するなら問題ないとは思いますが、おすすめはできません。

## おすすめしたい方法：navigationControllerのwillShow

上記の【例】を実現できるコードを下記に記載します。

```swift
class BViewController: UIViewController, UINavigationControllerDelegate {

	override func viewDidLoad() {
		super.viewDidLoad()
		navigationController?.delegate = self
	}
	
	func navigationController(_ navigationController: UINavigationController, willShow viewController: UIViewController, animated: Bool) {
	    if viewController is AViewController {
		    //挿入したい処理
	    }
	}
	
}
```

`func navigationController(_ navigationController: UINavigationController, willShow viewController: UIViewController, animated: Bool)` は、その画面（上記だと画面B）から別の画面に遷移したときに呼ばれるメソッドです。

つまり **「B画面からA画面に遷移した時をハンドリング」** しています。
厳密に戻るボタンをハンドリングしているわけではないですが、これなら目的を達成できます。

- `UINavigationControllerDelegate` を継承する
- `navigationController?.delegate = self` を定義しておく

をお忘れずに。

## まとめ

`func navigationController(_ navigationController: UINavigationController, didShow viewController: UIViewController, animated: Bool)` もあったので、便利そうです。
【Swift4】リッチテキストファイル(rtf)のテキストをUITextViewに表示する。

リッチテキストファイル(*.rtf)のテキストをUITextViewに表示する方法です。

操作の流れは

* rtfをメインバンドルに組み込む
* rtfファイルからNSAttributeStringsを作成
* UITextViewのattributedTextプロパティに代入

# rtfをメインバンドルに組み込む
今回は`Terms.rtf`というファイルをアプリに組み込みます。

# rtfファイルからNSAttributeStringsを作成

`getTermAttributeString`というメソッドを作りました。
NSAttributeStringsを作成したいと思います。

```swift

enum FileError: Error {
    case notExitPath
    case faildRead
}

func getTermAttributeString() throws -> NSAttributedString {

        if let url =  Bundle.main.url(forResource: "Terms", withExtension: "rtf") {
            do {
                let terms = try Data(contentsOf: url)
                let attributeString = try NSAttributedString(data: terms, options: [NSAttributedString.DocumentReadingOptionKey.documentType: NSAttributedString.DocumentType.rtf], documentAttributes: nil)
                return attributeString

            } catch let error {
                print("ファイルの読み込みに失敗しました: \(error.localizedDescription)")
                throw FileError.faildRead
            }
        } else {
            throw FileError.notExitPath
        }
    }
```

説明です。

```swift

if let url =  Bundle.main.url(forResource: "Terms", withExtension: "rtf")
```
`Bundle.main.url`メソッドでメインバンドルのファイルのURLを取得します。


```swift

try NSAttributedString(data: terms, options: [NSAttributedString.DocumentReadingOptionKey.documentType: NSAttributedString.DocumentType.rtf], documentAttributes: nil)
```

`NSAttributedString`のイニシャライズで`options`に`[NSAttributedString.DocumentReadingOptionKey.documentType: NSAttributedString.DocumentType.rtf]`を指定します。
こうすることでリッチテキストフォーマットでNSAttributedStringを作ることができます。


# UITextViewのattributedTextプロパティに代入
作ったNSAttributedStringをattributedTextに代入します。


```swift
termsTextView.attributedText = try viewModel.getTermAttributeString()
```

以上です。

# 参考
* [ios - Xcode 9.1 Swift 4, unable to compile with NSDocumentTypeDocumentAttribute if "if #available" is used - Stack Overflow](https://stackoverflow.com/questions/47281756/xcode-9-1-swift-4-unable-to-compile-with-nsdocumenttypedocumentattribute-if-if)
* [swift - SwiftでUITextViewのattributedTextの内容をリッチテキストファイル(test.rtf)として保存するには？ - スタック・オーバーフロー](https://ja.stackoverflow.com/questions/8813/swift%e3%81%a7uitextview%e3%81%aeattributedtext%e3%81%ae%e5%86%85%e5%ae%b9%e3%82%92%e3%83%aa%e3%83%83%e3%83%81%e3%83%86%e3%82%ad%e3%82%b9%e3%83%88%e3%83%95%e3%82%a1%e3%82%a4%e3%83%abtest-rtf%e3%81%a8%e3%81%97%e3%81%a6%e4%bf%9d%e5%ad%98%e3%81%99%e3%82%8b%e3%81%ab%e3%81%af)
* [ios - Objective C - How to create rtf from NSAttributedString - Stack Overflow](https://stackoverflow.com/questions/24134217/objective-c-how-to-create-rtf-from-nsattributedstring)
High Sierraにアップグレードしたら、sidekiqが起動できなくなった

## 環境
- System Version: macOS 10.13.3 (17D102)
- rails (5.0.3)
- sidekiq (5.0.0)

## 現象
macbook proを更新する時期になった。タッチバーのMacBook Porを選んだ。最新のMacOS High Sierraも搭載されてます。

ローカル環境でいつものようにsidekiqを起動しようとしたら、以下のエラーが出てきた

```ruby
RAILS_ENV=development bundle exec sidekiq -C config/sidekiq.yml

objc[96412]: +[__NSPlaceholderDictionary initialize] may have been in progress in another thread when fork() was called.
objc[96412]: +[__NSPlaceholderDictionary initialize] may have been in progress in another thread when fork() was called. We cannot safely call it or ignore it in the fork() child process. Crashing instead. Set a breakpoint on objc_initializeAfterForkError to debug.
```

なにこれ?

## 調査
最初は自分のSidekiqが古くて、多分新しいバージョンが対応しているかなと思って、最新の5.1.3にアップグレードしてみたけど、同じエラーでした。

この問題についてのきちんとの説明はこれ[こちら](https://blog.phusion.nl/2017/10/13/why-ruby-app-servers-break-on-macos-high-sierra-and-what-can-be-done-about-it/)を読んでいただければわかると思います。

おそらくsidekiqがプロセスをforkする時に、high sierraは許してないです。

現在Workaroundとして

```bash
export OBJC_DISABLE_INITIALIZE_FORK_SAFETY=YES
```

## 参照
- https://blog.phusion.nl/2017/10/13/why-ruby-app-servers-break-on-macos-high-sierra-and-what-can-be-done-about-it/
WSHとExcelでふりがなの生成

Excelの機能を使ってふりがなを生成します。
完全ではありませんが、自分でやるより全然楽です。

`cscript //nologo genPhonetic.js [読みを付けたい感じのリスト]`

みたいな感じで実行します。

```genPhonetic.js
// magic spell for WSH ///////////////////////////////////////////////////////
if(typeof console==="undefined")  console={log: function(s){WScript.Echo(s)}};
if(typeof process==="undefined"){ process={exit:function(e){WScript.Quit(e)}};
var v=process.argv=[];v.push(WScript.FullName);v.push(WScript.ScriptFullName);
var n=WScript.Arguments.Unnamed;for(var i=0;i<n.length;i++)v.push(n.item(i))};
//////////////////////////////////////////////////////////////////////////////
//
// ExcelのApplication.GetPhonetic メソッドを使ってふりがなを生成する
//
// Application.GetPhonetic メソッド (Excel)
// https://msdn.microsoft.com/ja-jp/vba/excel-vba/articles/application-getphonetic-method-excel

var fso = new ActiveXObject("Scripting.FileSystemObject");
var ExcelApp = new ActiveXObject( "Excel.Application" );

try {
	var book = ExcelApp.Workbooks.Add();
	var sheet = book.Worksheets( 1 );

	var argv = process.argv.slice(2);
	if( argv.length > 0 ) {
		for( var i=0; i<argv.length; i++ ) {
			main( argv[i] );
		}
	} else {
		main( WScript.StdIn );	// フィルター動作
	}
	function main( file ) {		// 主処理
		var result=[];
		if( typeof file==="string" ) {
			var f = fso.OpenTextFile( file, 1);	// 1:ForReading
		} else {
			f = file;
		}
		while ( !f.AtEndOfStream) {
			var phrase = f.ReadLine();
			var yomi = ExcelApp.GetPhonetic(phrase);
			result.push( [ phrase, yomi ].join("\t") );
		}
		f.Close();
		console.log( result.join("\n") );
	}
}
finally {	// 後処理
	ExcelApp.Quit();
	ExcelApp = null;
}	// エラー時もExcelを終わらせるため、try～catch～finallyを使う。

```
Windowsでv9.xで入れたgrpcをNode.js v10.0.0で使うには

# 背景

Windows10環境で
[nvs](https://github.com/jasongin/nvs)でNode.jsを切り替えて使っている


# Node.js v10.0.0でgrp動かそうとしてハマった

一旦node_moduelsディレクトリを消して再度入れないと駄目！

```shell-session
npm　rebuild
```

したら解決するみたいな一見親切なメッセージに惑わされるけど、
現状、これに従ってもダメな模様。

それにしてもgrpcでNode.jsだと.protoファイルを変更しても
とくに何もしなくていいダイナミック方式が使えるにが
気に入っている。

# 関連記事

- [Raspberry Piの温度をgRPCを使ってElectronで作ったデスクトップマスコットに表示させた](https://abrakatabura.hatenablog.com/entry/2018/06/16/070747)
SQLを動的に作る時の小技

WHERE句にAND条件をループで出力させるときは、ループ前に`1 = 1`を書く。

```sql
SELECT *
FROM テーブル名
WHERE 1 = 1
<CFLOOP ループ条件>
    AND カラム名 = #変数名#
</CFLOOP>
```

OR条件をループで出力させる時は、ループ前に`1 = 0`を書く。

```sql
SELECT *
FROM テーブル名
WHERE 1 = 0
<CFLOOP ループ条件>
    OR カラム名 = #変数名#
</CFLOOP>
```

こうすることで、「1回目のループは`AND`を出力しないようにIF文を入れる」とかやらなくて済みます。
（ColdFusionで書きましたが、言語は何にでも置き換えできるかと思います）
高速道路は渡らない。という話（心理的安全性の担保）

## 徐々にバズワード化してきた
最近、チームマネジメント、人事領域で叫ばれ始めた言葉に
「**心理的安全性の担保**」という言葉があります。

2012年にグーグルさんが**プロジェクトアリストテレス**という、チーム生産性向上の
ための、研究チームを立ち上げました。
何百万ドルもの資金と約4年の歳月を費やして実施されたこのプロジェクトで
チームがチームとして成功するための因子として紹介され、今注目されています。

心理的安全性の担保がされることで、より高い生産性があがる「行動」につながる。
というお話です。

## そもそも
先輩から行動量が足りない。という指摘だったり、
メンバーが想像以上に動かない。と感じたり、すること無いですか？

「あー、動かなきゃ！やらなきゃ！」って思う反面、
「でもさー」って思うこともあったりして、行動することの大切さは
わかるけど、動けないことや、動かないことが有りますよね。

## 横断歩道を渡ることはできるか？

**Q1. 高速道路に横断歩道があったら、人は渡るだろうか？**
僕は渡らないですよ。下手すると死にますし。。。

**Q2. 高速道路に「信号付きの横断歩道があって、歩行者側が青」だったら？**
~~そんな高速道路は嫌だけど。。。~~
渡る人はいるかもしれないですね。信号ついてるし、歩行者が青だし、車止まる（と思う）し。
でも、渡らない人のほうが多いかもしれない。

**Q3. 歩行者天国の信号無しの横断歩道があったら？**
横断歩道すら、使わないかもしれないですね。

**Q4. 過去、歩行者天国を歩いてたら、自転車に激突されて大怪我をした経験がある人だったら？**
横断歩道があっても、注意深く左右を見ながら、中々渡らないかもしれないですね。

## 何で行動が変わるのか
上の例は、至極当たり前のことですが、状況によって
「横断歩道を渡る」という**行動が抑制されるケース**がある。ということです。

信号があろうが、青だろうが、ルールを無視して車が突っ込んでくるリスクは
全てにおいてあるものの、

**安全だと思う量は、置かれる環境や自身の状況によって、圧倒的に変化します。**

人は、経験則から、その安全が確保される範囲であれば、行動を起こしやすい
心理的状況に置かれます。

これを、**心理的安全性** と呼び、素晴らしいチームは、色々なタスクに対し、

**心理的安全性の担保**

がしっかりと取れている。ことが、アリストテレスにより解明されました。

## 良い行動は、安心感から始まる
なぜ、素晴らしいチームは、心理的安全性が担保されていることが多いのでしょうか。

それは、様々な事柄に「安心して」チャレンジできるから。
言い換えると、失敗できる土壌がある。ということですね。

失敗しても良い事ばかりではないですが、少なくとも、

**失敗から学び、改善を繰り返し続ける事ができるチーム**

は、素晴らしいチームに育つ可能性が高い。ということです。

## 最初から素晴らしいわけではない

どんな人でも最初から上手く出来るわけではないですよね。
試して、失敗して、反省して、出来るようになります。

たった一人の行動ですらこうなのですから、複数人が集まるチームが最初から上手く行くわけがない

当たり前のことです。

沢山の試行と沢山の反省を繰り返し、それでも前に進むために行動出来るチームが、
素晴らしいチームに成長していく。

そのために、重要な要素が、「**心理的安全性**」である。

ということでした。

## 成長してますか？

失敗に対し、怒ったり、諦めたりしてませんか？
いらっとする事もあります。だって人だもの。

でも、本質は「成功」させるために仕事をしています。
チームが本来出すべきアウトプットを「邪魔する」行動が悪なのであれば、
感情に身を任せ、失敗した人を叱責する「だけ」という行為も、悪なのですよね。

**全ては、成功するために、成長するために、本当に必要なことをする**

そのために、どうしたら良いのか。どういった声をかけるべきなのか。
失敗に対しどう向き合うのか。を考えていく必要がありますよ。

という話でした。

## まとめ
- 素晴らしいチームは、心理的安全性が担保されている
- 心理的安全性を担保する活動は、素晴らしいチームに成長するための栄養になる
- そのために、失敗に対し、チームとしてどう向き合うべきなのか、考えましょう
[Unity] 動かないオブジェクトの後ろに軌跡を出す

自機が常に原点にいると何かと都合がよい、などの理由で、実は自分が止まっていてまわりが動いている、といった作り方をすることがあります。

![2018-04-27_113233.png](https://qiita-image-store.s3.amazonaws.com/0/59911/ad8567ba-c08f-67ea-a3e4-2e684018fd1b.png)


そんな時、「動いている感」を出すために軌跡を表示したくても、TrailRenderer は自分が動いていないと軌跡を出してくれません。

そこで、LineRendererを使って自分の後ろに軌跡を作ってみます。

まずは軌跡のスタート地点となる空のオブジェクトを用意します。
そこにAdd Component > Effect > LineRendererをアタッチします

![2018-04-27_112139.png](https://qiita-image-store.s3.amazonaws.com/0/59911/b050c538-674a-35e3-d915-be64e4c40ae2.png)

次に以下のスクリプトを同じオブジェクトにアタッチします

```InvTrail.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class InvTrail : MonoBehaviour {
    [SerializeField] float m_spd=10f;
    [SerializeField] int m_positionCount = 50;
    LineRenderer m_lr;
    Vector3[] m_oldPos;
    int m_cnt;

	// Use this for initialization
	void Start () {
        m_lr = GetComponent<LineRenderer>();
        if (!m_lr)
            Destroy(this);

        m_lr.positionCount = m_positionCount;
        m_oldPos = new Vector3[m_lr.positionCount];
        for (int i = 0; i < m_oldPos.Length; ++i)
        {
            m_oldPos[i] = transform.position;
        }
        m_lr.SetPositions(m_oldPos);
        m_cnt = m_oldPos.Length - 1;
    }
	
	// Update is called once per frame
	void Update () {
        Vector3 wSpd = transform.rotation * Vector3.back * m_spd;
        m_cnt = Mathf.Max(0,m_cnt - 1);
        for (int i = m_oldPos.Length-1; i > m_cnt; --i)
        {
            m_oldPos[i] = m_oldPos[i-1]+wSpd*Time.deltaTime;
        }
        m_oldPos[m_cnt] = transform.position;
        m_lr.SetPositions(m_oldPos);
    }
}
```

実行するとオブジェクトの後ろ方向に軌跡が描画されます

![2018-04-27_112440.png](https://qiita-image-store.s3.amazonaws.com/0/59911/9e1acf2b-a5c2-8c1f-8fee-e06b549cfce2.png)

マテリアルや見かけの移動速度などパラメータを調整します
m_spdは見かけのスピード、m_positionCountは軌跡の頂点数です

![2018-04-27_112839.png](https://qiita-image-store.s3.amazonaws.com/0/59911/6ae734e8-ea53-35b7-101d-cf7f2cc16d12.png)
MariaDBのインストール/初期設定 [CentOS7]

# はじめに
最近のMySQLの文字コード(utf8)の指定がすこし変わったみたいなので、ついでにまとめます。
主に一般的なMariaDBのセッティングです。

今回インストールしたMariaDBのバージョンは
`mysql  Ver 15.1 Distrib 5.5.56-MariaDB, for Linux (x86_64) using readline 5.1`
でした。

# MariaDBのインストール

```console
$ sudo yum update
$ sudo yum install -y mariadb mariadb-server
```
MariaDBサーバーを起動させ、OS再起動時の自動起動を設定します。

```console
$ sudo systemctl start mariadb
$ sudo systemctl enable mariadb # 任意
```
確認します。

```console
$ mysql --version
mysql  Ver 15.1 Distrib 5.5.56-MariaDB, for Linux (x86_64) using readline 5.1
```
（上記のバージョンは、本記事の投稿時点のバージョンです）

# 初期設定
簡易な初期設定スクリプトを実行します。

```console
$ sudo mysql_secure_installation
```
初期設定が対話モードで始まるので設定していきます。
主に、rootパスワードを設定し、残りはEnterを入力すれば妥当な設定になります。(EnterでYを入力したことになります)

```console
# １つ目: 今のrootパスワードを入力(初めはパスワードが無いのでEnterでOK)
Enter current password for root (enter for none): # Enter

# 2つ目: rootパスワードを設定するか
Set root password? [Y/n] # Enter

# 3つ目: 新しいrootパスワードを設定
New password: # 新しいパスワードの入力

# 4つ目: 新しいパスワードの確認
Re-enter new password: # 新しいパスワードを再入力

# 5つ目: 匿名ユーザ(初期設定などのために誰でもログインできるユーザ)を削除するか
Remove anonymous users? [Y/n] # Enter

# 6つ目: rootのリモートログインを禁止するか
Disallow root login remotely? [Y/n] # Enter

# 7つ目: testデータベース(テスト用の誰でもアクセス可能なデータベース)を削除するか
Remove test database and access to it? [Y/n]  # Enter

# 8つ目: 権限を管理するテーブルをリロードして、設定をすぐに反映するか
Reload privilege tables now? [Y/n] # Enter

```

## 文字コードをUTF-8に設定する
日本語などを問題なく登録できるように、文字コードをUTF-8に設定します。
以前までは`utf8`と指定すればよかったのですが、より多くの漢字や絵文字を表現できる`utf8mb4`の指定が推奨されるようになりました。後々デフォルトになるようです。２つの違いはMySQL内の話なので、UTF-8と同じと考えて大丈夫です。
`mysql  Ver 15.1 Distrib 5.5.56-MariaDB, for Linux (x86_64) using readline 5.1`環境では、`utf8mb4`を指定しないと、正常に設定が反映されませんでした。

`sudo vi`などで`/etc/my.cnf.d/server.conf`を編集します。

```conf:/etc/my.cnf.d/server.conf
<<< 省略 >>>

[mariadb]
character-set-server = utf8mb4 <- これを追記

<<< 省略 >>>
```
続いて、`/etc/my.cnf.d/client.conf`を編集します。

```conf:/etc/my.cnf.d/client.conf
<<< 省略 >>>

[client-mariadb]
default-character-set = utf8mb4 <- これを追記

<<< 省略 >>>
```

MariaDBを再起動します

```console
$ sudo systemctl restart mariadb
```

ログインし、確認します。

```console
$ mysql -u root -p # MariaDBにログイン
Enter password: # rootパスワードを入力
```

文字コードの設定を確認します。

```console
MariaDB [(none)]> show variables like "chara%"; # 文字コードの設定を参照
+--------------------------+----------------------------+
| Variable_name            | Value                      |
+--------------------------+----------------------------+
| character_set_client     | utf8mb4                    |
| character_set_connection | utf8mb4                    |
| character_set_database   | utf8mb4                    |
| character_set_filesystem | binary                     |
| character_set_results    | utf8mb4                    |
| character_set_server     | utf8mb4                    |
| character_set_system     | utf8                       |
| character_sets_dir       | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+
8 rows in set (0.00 sec)


```
上記のように表示されれば、正常に設定が完了しています。`quit;`でログアウトします。
Pythonのabs()の挙動から学んだこと

データ型の情報は、処理の高速化に役立つよ、というお話。


###abs()とは
引数の絶対値を返す！！！
<br/>
<br/>
<br/>
<br/>
・・・だけじゃないんですね。


###以下のコードで確認
<a href="https://paiza.io/ja">paiza io</a>あたりにぶち込んですぐ試せます

```python:abs.py
v = -1.0
print(type(v), abs(v))
# <class 'float'> 1.0

v = 1 - 1j
print(type(v), abs(v))
# <class 'complex'> 1.4142135623730951
```

###つまり？
つまり、
・引数が整数や浮動小数点の場合　→　単に負→正に変えるだけ
・複素数の場合　→　各要素の二乗和の平方根を返す(下のコードの出力値は√2の値になっています)

pythonは動的型付け言語であるため、裏側では
**「absを呼び出す前に変数vの型を調べてから」**
どの処理を適用するかを決定する必要があります。

このようなオーバーヘッドは、同じ関数を何回も繰り返し呼び出すような場合に無視できない大きさになってしまいます。

###そういう場合は？
静的コンパイルを使って高速化しましょう！(雑)
Gitの要点を抑える(トラブルシューティング抜き)

# 概要

研修において改めて復習したので記事化。

# Git とは

1. Gitとは、分散型バージョン管理システムの一つ
2. もともとLinuxのソースコードを効果的に管理するために開発された
3. Gitでは、ファイルの状態を好きなときに更新履歴として保存しておくことができる。
4. 古いファイルを元に編集したファイルで、他人の編集した最新ファイルを上書きしようとすると、サーバにアップロードした時に警告が出る。

## 要約すると

- 一度編集したファイルを過去の状態に戻したり、編集箇所の差分を表示したりすることができる。
- 知らず知らずのうちに他人の編集内容を上書きしてしまうといった失敗は起こらない。

ネットにバックアップを上げておくということ。さらにそれがお互いに勝手に上書きされないように管理する。

# リポジトリってなんだ？

リポジトリとは、ファイルやディレクトリの状態を記録する場所のこと。2種類しかない。

|種類|説明|
|:---:|:---|
|ローカルリポジトリ|自分のパソコンにあるリポジトリ|
|リモートリポジトリ|ネット(クラウド)にあるリポジトリ|

# コミットとは

ファイルやディレクトリの追加・変更を、リポジトリに記録する操作のこと。基本的にはローカルリポジトリへの記録を指すことが多い。よって、その意味で使われている場合には、これを実行した時点ではまだ、リモートへの記録が終わっていない。

# 

# 初心者向け注意書き

### 1. エラーが出たら無理やりpushしようとしない

これをやってしまうと最悪意図せぬ情報を反映する可能性が高いです。
また、master以外であれば(最悪)良いですが、masterにpushしてしまい、バグをリリースしてしまうのだけは避けたいところです。そのため、エラーが出たらまずpushのフローをストップして確認してから頼れる先輩に相談すると良いです。

### 2. 間違えて操作しちゃった！

まず焦ってgit resetをすぐやらないこと。癖になって本当に必要な変更まで取り消してしまう日が来る可能性が高いです。そのため、必要なもn


# 参考 

[gitを使ったバージョン管理【Gitの基本】 | サルでもわかるGit入門 〜バージョン管理を使いこなそう〜](https://backlog.com/ja/git-tutorial/)
BSD sedで行挿入

BSD sedで行挿入は結構面倒くさい。とくにインタラクティブシェルから操作しようとすると、シェルの様々な機能とバッティングするのか、期待通りに動作させるのは一苦労だ。

今のところ、`/usr/bin/printf`でコマンド列を用意して、`sed -f /dev/stdin`で受け取るのが可搬性が高いのかなと思っている。

```shell
/usr/bin/printf '/^rpcbind/i\\\nrpcbind : 192.168.0.1/255.255.255.0 : allow\n' | sed -i '' -f /dev/stdin /etc/hosts.allow
```

bashやzshならプロセス置換を使って、

```shell
sed -i '' -f <(/usr/bin/printf '/^rpcbind/i\\\nrpcbind : 192.168.0.1/255.255.255.0 : allow\n') /etc/hosts.allow
```

と書く方が直感的だろうか。

printf（やecho）もシェルのビルトインとシステムのバイナリとで挙動が違うことが多く悩ましい。

この辺のノウハウがまとまっているページを求めているのだけど、GNU sedの話と切り分けて検索するのが手間で辛い。
TurboNASからLinkStationへのRsyncによるバックアップ

# はじめに
この記事はQNAP製NAS TurboNASからBUFFALO製NAS LinkStationへのバックアップを行おうと思い、TurboNASのバックアップメニューで試行錯誤してみたが、思うようにはできなかったという記事です。

# 使用機器
| 接続 | 機器名称 |
|:----|:----|
| バックアップ元 | QNAP [TS-251+](https://www.qnap.com/ja-jp/product/ts-251+) |
| バックアップ先 | BUFFALO [LS420D](http://buffalo.jp/product/hdd/network/ls420d/) |

# 準備
## LinkStation
バックアップ用フォルダを作成。
この時、公開プロトコルのバックアップにチェックを入れておく。
![buffalo-nas.PNG](https://qiita-image-store.s3.amazonaws.com/0/253073/cf201135-921b-e96c-9311-27cda01ed574.png)

## TurboNAS
接続はバックアップ機能を使用。
![backupmanager.PNG](https://qiita-image-store.s3.amazonaws.com/0/253073/6d396d93-9d3f-20de-ec86-ab64b4934336.png)

**レプリケーションジョブの作成**にてTurboNAS側でリモートサーバとしてLinkStationの登録を実施。
この時点では導通確認OKとなる。
![Setting1.PNG](https://qiita-image-store.s3.amazonaws.com/0/253073/b81040a2-cb1a-f7a3-1410-7f2d86e22b64.png)
※HOST-NAMEはLinkStationのアドレス

しかし、いざフォルダを参照しようとするといつまで経ってもフォルダが表示されない不具合が発生。
![Error.PNG](https://qiita-image-store.s3.amazonaws.com/0/253073/3458e063-2fa4-534c-3802-ef7f816e04af.png)
宛先を選択するまで先に進めないため、断念。

# 調査
まずはrsyncが動作しているかを確認するため、LinkStation側のポート状態を確認。

```
$ nmap HOST-NAME
PORT      STATE SERVICE
80/tcp    open  http
139/tcp   open  netbios-ssn
443/tcp   open  https
445/tcp   open  microsoft-ds
873/tcp   open  rsync
8873/tcp  open  dxspider
22939/tcp open  unknown
```

rsyncのポートはopen状態になっているため、rsyncサーバは正常に動作している模様。

TurboNASにSSHでログイン後、次のコマンドにて仮実行をしLinkStation側のフォルダ一覧を確認。

```
$ rsync rsync://admin@HOST-NAME:873/
opening tcp connection to HOST-NAME port 873
sending deamon args: --server --sender -vvnlogDtpre.iLsf . /
array1_BackupFolder
 :
```
LinkStation側では各ディレクトリの前にprifixが付加されており、通常のフォルダ名でディレクトリを指定しようとするとエラーになる。
例：BackupFolder -> <font color="red">array1_</font>BackupFolder

# 手動バックアップ
rsync自体の動作確認のためにTuboNAS側からSSHでrsyncを実行。
TurboNAS側の保存先は下記の方法で確認

```
$ ls /share
homes@
Movie@
Public@
 :
```

@の付いたパスはリンクでありそのままでは指定できないため、リンク先のパスを確認

```
$ readlink -f /share/Public
/share/CACHEDEV1_DATA/Public
```

確認できた実パスで同期を実行。

```
$ rsync -av /share/CACHEDEV1_DATA/Public rsync://admin@HOST-NAME:873/array1_BackupFolder
```


# 結論
TurboNAS内でどのようにフォルダリストを参照しているかわからないが、バックアップマネージャでの一覧取得は行えないため、スクリプトで実行するしかなさそうである。

# 参考サイト
[BuffaloのNASをrsyncサーバとして使う - どねすの備忘録](http://d.hatena.ne.jp/rednes/20090806/1249516084)
ノートアプリ探しの旅

# ノートアプリ探しの旅
今までノートアプリはEvernoteを使用していました。これはこれで昔から使っているというのもあり、すごく便利でした。
で、最近はMarkdownでノートを取ることが多いのですが、Evernoteは対応していません。
そのため、他のノートアプリを探し始めた次第です。

## 試したアプリ
- Boostnote: https://boostnote.io/
- Inkdrop: https://www.inkdrop.info/
- esa.io: https://esa.io/

### Boostnote
日本製のノートアプリで、一応マルチプラットフォームです。

- 良いところ
  - 見た目がシンプルで使いやすい
  - Dropboxで同期できる
  - ノートにスターをつけられて、後で重要なものを見返すのが楽
  - 無料で使える
- 良くないところ
  - iOSアプリでDropboxと同期してあるノートの編集はほぼ不可能（できるっぽいのですが、動作的に無理でしょう、、、）
  - エディットとプレビューの2段表示のときにスクロールするとどちらも追従して動くのですが、スクロール中は止まっています。そのため、確認がワンテンポ遅れる。気にしなければいいのですが、なんか気になってしまう、、、
  - pdfへのExport機能はなく、印刷画面の保存をしないといけないので少し手間がかかる
  - Dropboxの同期通知がひっきりなし

### Inkdrop
こちらも日本製のノートアプリで、マルチプラットフォームです。

- 良いところ
  - 見た目がシンプルでおしゃれ（←意外と重要）
  - 同期が独自サーバーなのでシンプル
  - 各ノートにStatusをつけられて、書き途中のノートがひと目でわかる
  - エディットとプレビュー画面のスクロールが同時に動く
  - pdfへのExportができる
  - プラグインによる拡張ができる
- 良くないところ
  - 月額使用料がかかる（作成者の方もブログで言っていましたが、有料にする方が、ユーザー側にもメリットが大きいとのこと。基本的に有料でも良いという人種は一定数いる←私）
  - Tagがサイドバーに羅列されるので折りたためるようになっているとすっきりする

### esa.io
ブラウザで使用できるノートアプリ。これは仕事で使用していて、ドキュメントとか共有事項、議事録などを保存しています。
基本的にチームで使用する感じなので、個人利用はあんまりしないんじゃないかなーとか思っています。

## 結論
シンプルだし、使い勝手は問題ないのでInkdropを使ってみようかなと。今後アップデートもあるだろうから期待して待ってます。
と思っていましたが、ランニングコストがかかるのはどうなのか...と思い始めてしまいました。
使用感としてはBoostnoteもInkdropもさほど変わらず、値段相応の何かを感じることができませんでした。
なので、とりあえずはBoostnote使って、不満があったらその時にInkdropへの移行を考えようかなと思います。
とか言いつつInkdrop使って書いてます。
パスワード認証のsftpサーバに sftp(1) で接続する

誰得なメモ

公開鍵と秘密鍵 を使わないで、ユーザIDとパスワードで認証を行います。

## 環境

amazon-linux の `openssh-clients-6.6.1p1-31.63.amzn1.x86_64` パッケージ。

## 実行するコマンド

```
sftp -o PubkeyAuthentication=no {ユーザID}@{接続先サーバ}
```

## 確認方法
*-v* オプションで表示されるデバッグログから確認します。

```
$ sftp -v -o PubkeyAuthentication=no {ユーザID}@{接続先サーバ}
OpenSSH_6.6.1, OpenSSL 1.0.1k-fips 8 Jan 2015
debug1: Reading configuration data /etc/ssh/ssh_config
debug1: /etc/ssh/ssh_config line 56: Applying options for *
debug1: Connecting to ftp.example.com [www.xxx.yyyy.zzz] port 22.
debug1: Connection established.
debug1: identity file /home/userid/.ssh/id_rsa type 1
debug1: identity file /home/userid/.ssh/id_rsa-cert type -1
debug1: identity file /home/userid/.ssh/id_dsa type -1
debug1: identity file /home/userid/.ssh/id_dsa-cert type -1
debug1: identity file /home/userid/.ssh/id_ecdsa type -1
debug1: identity file /home/userid/.ssh/id_ecdsa-cert type -1
debug1: identity file /home/userid/.ssh/id_ed25519 type -1
debug1: identity file /home/userid/.ssh/id_ed25519-cert type -1
debug1: Enabling compatibility mode for protocol 2.0
debug1: Local version string SSH-2.0-OpenSSH_6.6.1
debug1: Remote protocol version 2.0, remote software version 1.82_sshlib Globalscape
debug1: no match: 1.82_sshlib Globalscape
debug1: SSH2_MSG_KEXINIT sent
debug1: SSH2_MSG_KEXINIT received
debug1: kex: server->client aes128-ctr hmac-md5 none
debug1: kex: client->server aes128-ctr hmac-md5 none
debug1: kex: diffie-hellman-group-exchange-sha1 need=16 dh_need=16
debug1: kex: diffie-hellman-group-exchange-sha1 need=16 dh_need=16
debug1: SSH2_MSG_KEX_DH_GEX_REQUEST(1024<3072<8192) sent
debug1: expecting SSH2_MSG_KEX_DH_GEX_GROUP
debug1: SSH2_MSG_KEX_DH_GEX_INIT sent
debug1: expecting SSH2_MSG_KEX_DH_GEX_REPLY
debug1: Server host key: RSA 00:11:22:33:44:55:66:77:88:99:aa:bb:cc:dd:ee:ff
debug1: Host 'ftp.example.com' is known and matches the RSA host key.
debug1: Found key in /home/userid/.ssh/known_hosts:2
debug1: ssh_rsa_verify: signature correct
debug1: SSH2_MSG_NEWKEYS sent
debug1: expecting SSH2_MSG_NEWKEYS
debug1: SSH2_MSG_NEWKEYS received
debug1: SSH2_MSG_SERVICE_REQUEST sent
debug1: SSH2_MSG_SERVICE_ACCEPT received
Welcome to Enhanced FTP Service (ftp)
debug1: Authentications that can continue: password
debug1: Next authentication method: password
userid@ftp.example.com's password: 
debug1: Authentication succeeded (password).
Authenticated to ftp.example.com ([www.xxx.yyyy.zzz]:22).
debug1: channel 0: new [client-session]
debug1: Entering interactive session.
debug1: Sending environment.
debug1: Sending env LANG = ja_JP.UTF-8
debug1: Sending subsystem: sftp
Connected to ftp.example.com.
```

パスワード入力のプロンプト `userid@ftp.example.com's password:` の前後にある

```
debug1: Authentications that can continue: password
debug1: Next authentication method: password
```

と

```
debug1: Authentication succeeded (password).
```

からパスワード認証を行い、成功したことを確認できます。


## 参考
[鍵を使わずにログインしたいときのsshオプション](https://qiita.com/smallpalace/items/a29ee4a3b170804355b9)
Cognos でPDFやExcelでの実行をレポート内にボタンで実装する

#概要
簡単なネタです。
Cognos Analyticsでレポートを実行した後に、PDFやExcel表示に切り替えるメニューが下のアイコンですが、このメニューからでなく、レポート内にボタンを配置したい、という要望が良くあります。
![001.JPG](https://qiita-image-store.s3.amazonaws.com/0/147246/98533e64-3267-05a6-d193-f3017ac44a4a.jpeg)

#実装
自レポートへのドリルスルーを実装しましょう、というだけの話ですが。

赤枠のテキストアイテムにドリルスルーを実装していて、それぞれ前述のメニューで以下の機能を実装しています。
PDF = PDFを実行
Excel = Excelを実行
プロンプト = プロンプトをリセットして実行
![002.JPG](https://qiita-image-store.s3.amazonaws.com/0/147246/5070a261-f975-8ced-c2ad-fffcaee1e7f3.jpeg)

PDFドリルスルーの実装です。
ターゲットのレポートは、自レポート自身です。
形式を「PDF」にして、パラメーターを飛ばすようにしています。
※Excelの実装も同様なので割愛します。
![003.JPG](https://qiita-image-store.s3.amazonaws.com/0/147246/97687ba0-22d3-811a-fe3c-385dba5b29c9.jpeg)

プロンプトのドリルスルー実装です。
形式は選択せず、これでデフォルトのHTML表示になります。
パラメーターも選択せず、これで再プロンプトの意味になります。
![004.JPG](https://qiita-image-store.s3.amazonaws.com/0/147246/56d12ade-3703-78f8-0deb-6f125ce5e074.jpeg)

実行イメージはこんな感じ。
![005.JPG](https://qiita-image-store.s3.amazonaws.com/0/147246/d808bf83-adf4-87ad-b75b-e5e7422d93d1.jpeg)

「PDF」を選択した場合。
![006.JPG](https://qiita-image-store.s3.amazonaws.com/0/147246/bb806f3c-f11e-5e3f-03cd-02b91f8b028e.jpeg)

「プロンプト」を選択した場合。
![007.JPG](https://qiita-image-store.s3.amazonaws.com/0/147246/2d91d2a7-5e43-dc81-1db4-06333c913d86.jpeg)

#参考
ドリルスルーをテキストからではなく、ボタンっぽくするにはこちらをご参照下さい。

**Cognos レポートでドリルスルーのボタンを簡単に実装する**
https://qiita.com/shinyama/items/c51d0876feec2bc029bb
python:便利すぎるrequestsライブラリ

#pycurlとの比較

###1.**import**

```python:pycurl
import pycurl,json #pycurlとjsonデータ分析のため
from cStringIO import StringIO #テキストファイルライクなもの
```

```python:requests
import requests #request本体だけ
import urllib3
from urllib3.exceptions import InsecureRequestWarning
```

urllib3関係はオレオレ証明書ワーニング突破のため。
jsonとテキストを用意する必要が無い。

（20180427　追加）
###1-1. 追加設定
```python:requests
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

```
上記、ワーニング回避の追加設定。
失念していた・・・。ただ、これ入れてもrequestsの利便性における
優位性は圧倒的。

###2.**実処理**
```python:pycurl
data.truncate(0) #繰り返し利用する場合、テキストの初期化が必要。
curl.setopt(pycurl.URL, 'http://~') #ここから
curl.setopt(pycurl.CUSTOMREQUEST, 'GET')
curl.setopt(pycurl.TIMEOUT, 300)
curl.setopt(pycurl.WRITEFUNCTION, data.write)
curl.setopt(pycurl.SSL_VERIFYPEER, 0) #ここまでがオプション
curl.perform() #実行
json.loads(data.getvalue()) #jsonデータ解析
```

```python:requests
requests.get('http://~', verify=False, timeout=300).json()

```
requestsなら一行で済んでしまう。
IOの余計な処理もなし。

```python:requests
#メソッド各種
requests.get('http://~', verify=False, timeout=300).json()
requests.post('http://~', verify=False, timeout=300).json()
requests.put('http://~', verify=False, timeout=300).json()
requests.delete('http://~', verify=False, timeout=300).json()
requests.head('http://~', verify=False, timeout=300).json()

#戻り値参照
r.status_code #ステータスコード
r.text #ボディ
r.content #バイナリ
```

putでデータを送信したり、認証のオプションとかもあるので、お作法については
本家URL参照。
http://docs.python-requests.org/en/master/
どこまでサービスをしてもらえるか？

サーバ関連のサポートを依頼するときに、すり合わせる事項のリストをつくってみました。
サポートしてくださいというときに、発注側と受注側の思っていることがずれることは多々あるので、まずは、大項目でのすりあわせです。思いついたのをただ書いてあるので、随時更新していきます。

実際に使うときは、対応可能は、受注側の対応可能な選択肢を書き、希望は、発注側の希望を書いて、ずれがあるところを明確にします。

```
#これは、キーワード
aws server chef git selenium fabric jupyter modsec zabbix ubuntu php
```

|No|項目|対応可能|希望|備考|
|---|---|---|---|---|
| 1|サーバインフラ|aws,azure,sakura|aws|セキュリティ、課金など|
| 2|OS|ubuntu,centOS|ubuntu|アップデートのタイミング設定|
| 3|サーバ設定管理|chef,ansible|ansible||
| 4|サーバ管理|fabric,ansible|fabric||
| 5|コード管理|git(github,gitlab)|github|redmineとの連動|
| 6|web|apache,Nginx|apache||
| 7|DB|mysq,postgres|mysql||
| 8|web用プログラム|PHP,ruby|PHP||
| 9|管理用プログラム|python(jupyter),ruby,shell|python(jupyter),shell||
| 10|管理用エージェントなど|zabbix,Mackerel|zabbix||
|11|CMS|wordpress,netcommons|netcommons||netcommons 2 カスタムモジュール対応|
|12|テスト|selenium|selenium(python)|HTML parserは、BeautifulSoup|
|13|進捗管理|redmine|redmine||
|14|ドキュメント管理|wiki||redmine wiki|
Android 5,6系の最新Chromeで「ファイル選択」を押すとChromeが落ちる場合に確認すること

下記条件のAndroid Chromeで **inputタグのaccept属性の設定がimageだけの指定されている場合に、 「Chromeは停止しました」** となってしまいます。

![stop_chrome.png](https://qiita-image-store.s3.amazonaws.com/0/3821/cac00ff6-56ff-e46d-3ab6-56edc1ba492c.png)


## 発生条件
* Android 5系と6系 (Android 7系と8系では問題なさそうでした）
* 最新のChromeブラウザ（66.0.3359.126）


具体的には以下のようにimageだけが指定されているとダメなようです。

```html
<input type="file" accept="image/*">

<input type="file" accept="image/jpeg,image/png,image/gif">

<input type="file" accept="image/jpeg">
```


image以外にpdfを指定するとChromeは停止しないようです。

```html
<input type="file" accept="image/*,application/pdf">
```

Chromeの不具合が改善されるまではimage属性以外でアップロードされにくいファイルタイプを指定して凌ぐのがよさそうです。

## 確認手段
最後に、本事象が発生するかどうかを確認しやすいようにサンプルのHTMLを配置していますので、こちらにアクセスしてお試しいただければと思います。
https://s3-ap-northeast-1.amazonaws.com/qiita-samples/sample.html