OmniAICreator/Qiita-1.07M huggingface dataset:
Vue.js ページ全体更新されず、コンポーネントのみ更新(reload)の方法

#背景
vueは`<script> `タグを直接組み込み！
すべてのコードを一つhtmlに書く！
ページ全体更新したくない！
特定のコンポーネントのみ更新したい！
という場合は、

###[provide/inject]を使いましょう！



#実装

**実装ロジック：** 

**reload()でisRouterShow(true/false)をコントロール！**
**これにより、router-viewの表示/非表示をコントロール！**
**さらに、これにより、コンポーネントの更新(reload)をコントロール！**



1、親コンポーネントでproviderを作成

```router-viewの表示/非表示をコントロール.html
<body>
  <div id="app">
       <router-view v-if='isRouterShow' class="reload"></router-view>  <!-- これ!router-viewの表示/非表示をコントロール -->
  </div>
</body>
```

###
```reload().
 var vm = new Vue({
    router:router,
    el: '#app'
    provide() {
      return {
        reload: this.reload 
      }
    },
    data() {
      return {
        isRouterShow: true
      }
    },
    methods: {
      async reload() {                    //<-これ!isRouterShow(true/false)をコントロール！
        this.isRouterShow = false
        await this.$nextTick()
        this.isRouterShow = true
      }
    }
  })
```

2、子コンポーネントにinjectでreload()を導入！ reloadしたい場所に　this.reload(); で書けばいい！

```child-reload.
 Vue.component('childreload', {
   inject: ['reload'],    // <- これ！injectによりこのコンポーネントの更新をコントロールできるようになる
    data:function() {
      return {
        dateValue: null
      }
    },
    methods: {
      abtn: function() {
        this.bus.$emit("passData", this.dateValue) ;
        this.reload();    //例えばここ
      }

    },
    template: '#XXXXXXX'
  })

```
Jenkinsでビルド失敗通知はZabbixに任そう

# 問題
ZabbixのアクションにLine、Slack、MSTemas、Lineworksへ通知設定されている。
Jenkinsもビルド失敗時、チャット通知したい要望が来た。
zabbixにある通知スクリプトをコピーしてきてもよいが、運用はシンプルにしたいのでzabbixにまとめたい。

# 対応
## Zabbix
各ホストにトラッパーアイテムを登録

  * ホスト: [hostname]
  * アイテム：トラッパー[itemkey]
  * トリガー

## Jenkins
  * CentOS
  * Zabbix Senderインストール

```bash
rpm -Uvh http://repo.zabbix.com/zabbix/4.2/rhel/6/x86_64/zabbix-sender-4.2.8-1.el6.x86_64.rpm
```

  * ビルドシェルスクリプト

```bash
ret=$(curl -Ss https://www.domain.com/check_function 2> /dev/null)

if [ -z $ret ]; then
  zabbix_sender -z zabbix.domain.com -s [hostname] -k [itemkey] -o [value]
  exit 1
else
  exit 0
fi
```

# 参考1
Zabbix Senderは接続元制限が緩いのか。コマンドでもできるよう。
https://mattintosh.hatenablog.com/entry/20170709/1499586538

```bash
$ nc zabbix.domain.com 10051 <<!
{
    "request": "sender data"
,   "data": [
        {
            "host": "raspberrypi"
        ,   "key": "room_temperature"
        ,   "value": "0"
        }
    ]
,   "clock": `date +%s`
}
```

# 参考2
監視結果をメールで飛ばすが改行されない

```bash
#!/bin/bash
URL="https://alert.domain.com/api/check"
RET=$(curl -s $URL)

echo ''
echo '通知説明・・・・・・・・'
echo ''
echo $RET | tr ';' '\n'   <- trで改行
echo ''

if [ -n "$RET" ]; then
  exit -1      <- Jenkinsはこうすると失敗と認識
fi
```
ruby while、for、loop、break、nextについて

#while

```
 i = 0
 while i < 10 do
     puts "#{i}: hello" 
     i += 1
 end
```
※ 「i = i + 1」は「 i += 1 」と同様の意味


# times

- timesは数字オブジェクトのメソッド  

```
10.times do |i|
puts "#{i}:hello"
end
```
- do～endの中で繰り返したい処理を繰り返す
- do の後で|i|を定義することでwhileの時と同じように何回ループしているかが分かる

###上記のtimesは1行で書くことが出来る
```
10.times { |i|puts "10#{i}:hello" }
```

# for文

- doは省略出来る

```
 for i in 18..20 do
     p i
 end
 for color in ["red", "blue"] do
     p color
 end

 for name,score in {aratomai: 200, Mikkey: 500} do
     puts "#{name}: #{score}"
 end

```
実行結果：

- 18
- 19
- 20
- "red"
- "blue"
- aratomai: 200
- Mikkey: 500


# eachメソッドへの書き換え

```
 (18..20).each do |i|
     p i
 end
 ["red", "blue"].each do |color|
     p color
 end
 {aratomai: 200, Mikkey: 500}.each do |name, score|
     puts "#{name}: #{score}"
 end
```
実行結果：
上記と同じ

# loop
 - breakしない限り永久ループ
 
```
i = 0
 loop do
     p i
     i += 1
     end
``` 
 
# breakとnextについて
- iが5になった時に**処理が終わる**

```
10.times do |i|
    if i == 5
        break
    end
    p i
end
```
実行結果：
0
1
2
3
4


- iが5の時だけ**処理をスキップする**

```
10.times do |i|
    if i == 5
        next
    end
    p i
end
```
実行結果：
0
1
2
3
4
6
7
8
9
github で副業やリモートワークのコミュニケーションを円滑にする

### 前置き
最近、副業やリモートワークでの働き方が増えてきました。

それに伴い、テキストベースで非同期なコミュニケーションが必要になり
エンジニアリング能力とは別に、文章で人に伝える力が
仕事の効率を左右する大きな要因になっています。

少し前に『自分の意見や質問が上手く伝わっていないかも・・』と思うことが重なり、
それに対して GitHub を使ったいくつかの改善で成果が上がってきたので
自分が気を付けていることをまとめてみます。
（どの点も出来ている人から見たら当たり前かもしれません）

### 1. 不完全でも、その日の作業後には最新のコードを公開する
特に副業のような働き方だと、作業時間が少ししか取れない時もあります。
そういった時にも、少しの差分でも良いので Draft PR や WIP コメントなどを付けて
作業内容をプルリクエストにして、
自分の最新の進捗をチームメンバーなどがいつでも見られる形にしておくべきです。
忙しいテックリードに、自分の成果物を確認してもらえる機会を作っておきましょう。
（その際 TODO や FIXME コメントを活用して、実装の方向性を書いておくと◎です）

### 2. 気になる点はプルリクエストのコメントですぐ質問する
これは良く言われることかと思いますが、何か分からない点があったら、
長い時間を費やして調べずに、諦めて質問しましょう。
リモートワークなどでコミュニケーションが少ないチームだと特に
自分が考えている内容がチームと噛み合っていない事が多く
こちらで色々考えて実装しても、作って欲しい方向が合っていなかったため作り直し、
という事もよくあります。
自明な事以外はプルリクエストでどんどん質問しましょう。

個人の意見では、テックリードや偉いエンジニアにメンションを付けるべきです。
『私はこう考えているよ』という意図が伝わるため、コミュニケーションが円滑になります。

※ slack などの SNS で連絡を取り合っても良いと思いますが、
  github だと『この作業内容に関する質問だよ』という旨が伝わりやすいので
  自分はプルリクエスト経由での質問をいつもしています。

### 3. 仕組みのモヤモヤは issue を切って伝える
コードを書く作業とは関係ないところ（CI/CDやレビューの仕組みなど）で
時間を使うことは意外と多いですよね。
でもリモートワークだと『ちょっと○○が気になってて××にしたいのですが・・』というように
ちょっとした休憩に雑談ベースで・・とは伝えにくいかと思います。

そんな、コードを書く上で障害になっていることを
GitHub の issue を使ってリードテックの方に伝えましょう。

『コードを書く上で○○で困っているので××を利用したい』
『レビューをする前に☆☆を利用して最低限の事前チェックを行いたい』
『うちのCI/CDの□□がイケてないので△△を導入したい』など、
コーディングのプルリクエストとは直接関係ないような話題は、
github リポジトリの issue に書いておくと
誰かが見てくれる可能性が高いです。(見て欲しい人にメンションを付けると更に良いです)
『こいつは色々なことに気付いて提案してくれるな』
とプラスの評価もいただける可能性も高いです。

### 最後に
エンジニアにとってコミュニケーションは大変な作業ですが、
仕事を円滑に行い、自分の書くコードをお金にするためには大事な技能です。
少しでもお互いにストレスのないリモートワークライフを送るために
GitHub の各機能を活用しましょう！
HMDBからSDFファイルをダウンロードして自作ライブラリを作成

# はじめに

メタボローム解析をして得られた、HMDB IDを基に、SDF形式のライブラリの作成に迫られたので、Rを使って作成します。

# 下準備

はじめに、ライブラリに含める化合物のリストを作成します。具体的には、下記のようなHMDB IDを列挙したテキストファイルです。
実際には、メタボローム解析結果のExcelファイルから、HMDB IDの列をコピーし、テキストエディタに張り付けて終了です。1行目には、ヘッダーを残しておくと、後の処理が楽になります。

```hmdb_ids.txt
HMDB
HMDB0012497
HMDB0031641
HMDB0013749
HMDB0033529
HMDB0032330
HMDB0032330
HMDB0094691
HMDB0034301
HMDB0034301
HMDB0000039
HMDB0000039
```

# HMDB IDリストの読み込み

早速、上記のファイルを読み込みます。あいにくtinyverse脳なので、脊髄反射で`readr`パッケージを使います。

```sdf.r
library(readr)
hmdb_ids <- read_csv("hmdb_ids.txt")
```

# ダウンロード用の自作関数

SDFファイルをHMDBからダウンロードするための自作関数を作ります。先ほど作成したHMDB IDのリストから、HMDB上にあるSDFファイルのurlを作成し、ファイルをダウンロードする作戦です。

普通ならHMDB ID毎に、SDFファイルを作成するのでしょうが、今回は1ファイルに複数の化合物情報を含んだライブラリとしてのSDFファイルを作成します。そのため、`download.file()`のパラメータを`mode="a"`とし、指定したファイル`library.sdf`にダウンロードしたデータを追記してていきます。

まれに、HMDB上にSDFファイルが存在しない場合があるのですが、その際にエラーが出て処理が止まってしまわないよう`try()`を挟んで、処理が継続されるようにしています。

```sdf.r
download_sdf <- function(hmdb_id) {
    url <- paste0("http://www.hmdb.ca/structures/metabolites/", hmdb_id, ".sdf")
    try(
        download.file(url, "library.sdf", method="libcurl", mode="a"),
        silent=TRUE
    )
    Sys.sleep(5)
}
```

# 最後にダウンロード

`purrr::map`を使って、ダウンロードします。`sapply()`でもいいと思います。

```sdf.r
library(purrr)
map(hmdb_ids$HMDB, download_sdf)
```

ダウンロードが終わると、こんな感じでSDFライブラリが作成されます。一部アノテーション情報は省略しています。

```library.sdf
Structure #1
  Mrv0541 02241206562D          

  5  5  0  0  0  0            999 V2000
    0.5678    1.1143    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
    1.2352    0.6294    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
   -0.0997    0.6294    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
    0.9803   -0.1553    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
    0.1553   -0.1553    0.0000 N   0  0  0  0  0  0  0  0  0  0  0  0
  1  2  1  0  0  0  0
  1  3  1  0  0  0  0
  2  4  1  0  0  0  0
  3  5  2  0  0  0  0
  4  5  1  0  0  0  0
M  END
...

$$$$

  Mrv0541 02241218152D          

  5  5  0  0  0  0            999 V2000
    1.5202    0.2371    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
    0.6952    0.2371    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
    0.4403    1.0217    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
    1.1077    1.5066    0.0000 N   0  0  0  0  0  0  0  0  0  0  0  0
    1.7752    1.0217    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
  1  2  1  0  0  0  0
  2  3  1  0  0  0  0
  3  4  1  0  0  0  0
  4  5  1  0  0  0  0
  1  5  1  0  0  0  0
M  END

...

$$$$

  Mrv0541 02241217062D          

  6  6  0  0  0  0            999 V2000
   -0.2471    0.6600    0.0000 O   0  0  0  0  0  0  0  0  0  0  0  0
   -1.0721    0.4125    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
   -1.0721   -0.4125    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
   -0.2471   -0.6600    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
    0.2471    0.0000    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
    1.0721    0.0000    0.0000 C   0  0  0  0  0  0  0  0  0  0  0  0
  1  2  1  0  0  0  0
  1  5  1  0  0  0  0
  2  3  2  0  0  0  0
  3  4  1  0  0  0  0
  4  5  2  0  0  0  0
  5  6  1  0  0  0  0
M  END

...
```
HEIC to JPEG

iOSで写真を撮るとHEICという拡張子のファイルになります。
これはHEIFという形式のファイルでJPEGよりも高圧縮ということで採用されています。
Windows10だと問題なく表示できますが、JPEGやPNGでしか扱えないツールでは困ります。

そんなときは ImageMagick を使って変換します。

下記からインストール
https://imagemagick.org/script/download.php

high dynamic-range imaging を含んだインストーラーが必要ですので Windowsの場合は ImageMagick-7.0.9-2-Q16-HDRI-x64-static.exe になります。他のOSは良しなに。macosの場合は`sips`でしょうけど。

そしてフォルダ丸ごと一発変換できます。

```
magick mogrify -format jpg *.heic
```
もっと早く知りたかった。開いてるディレクトリで即コマンドプロンプトを立ち上げる方法。

今まで `Win + R` → `cmd`で開いてからパスをコピペしてました…

アドレスバーに「cmd」と打ち込むだけで良かったんですね…

![コマンド立ち上げ.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/260763/afebcf4b-b057-d3f6-57c0-2e4981231a37.gif)
新卒2年目で社内に勉強会文化を根付かせてみた【社内LT大会 レポート】

# 背景

弊社には社内で学びをアウトプット、共有する機会が少ないです。
中途採用のスペシャリストな先輩方がいるのに、その技術を学ぶ場所がありませんでした。
ということで、新卒先輩社員と社内勉強会を立ち上げることにしました。

# 立ち上げ

多くの人に参加して頂きたいと考え、
「社内で業務時間内に一度やらせてください。」と、会社のエラい人に相談しました。

快く許可していただき、第1回が決定。
第2回以降は結果次第になりました。

ノウハウのない我々が一発勝負で成果を出せるのか？
ものすごく不安でしたが、同時にすごくワクワクしていたのを覚えています。


まずはニーズ調査として、フィードバックを可視化しやすいLT大会を開催することになりました。

# 第1回を開催




結果としては、大成功！

当初は10人ほどの参加を想定していたのですが、30名近くの方に参加していただき、アンケートでも好評をいただくことができました。

取り組みの姿勢へ賛同していただく意見が多く、温かい会社だと実感しました。

その後

* 参加人数
* 会場の雰囲気
* 開催後のアンケート

などのレポートをエラい人に提出し、次回以降も開催できるようになりました。

# 第2回

第1回～第3回までを効果測定として扱うことにし、様々な施策を試すことになりました。

* メインイベントとして15分枠を設ける。
    * 5分では語りきれないディープな内容を取り扱ってもらいました。
* 定時後に開催する。
    * 保守業務の方々は業務時間内だと参加しづらいという声を受けて。
* LTのテーマを絞る。
    * UI/UXについてというテーマで開催しました。
* イベントページを開設する
    * GoogleSiteを使ってスライドのアーカイブを公開しました。
    * そこからイベント参加登録も受け付けるようにしました。
        * [GASとGoogleFormでイベント参加ボタンを作る - Qiita](https://qiita.com/fuga___/items/1611147f0cdd6325b8f4)


# 現在


そんなわけで、4月より立ち上がった有志社員による社内勉強会
IMLT（InfoMart Lightning Talks）は10月で第3回を迎えました。

今回から、開催レポートを社内外に向けて発信して行きたいと思います。

## イベント概要
**IMLT #3 ~DB~**

▼会場の様子
![写真 2019-10-16 11 04 34.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/260763/97558cbb-faae-e694-ed4c-f13e03a80004.jpeg)



### テーマ
直近で弊社DBインフラの大規模な移行があり、社内からの関心が集まっていたので
LTのテーマとしてDBを選択しました。

### 新しい施策

* HTMLメールによるイベント周知
    * デザインチームの方に協力いただいて、見た目のインパクトにこだわりました。
* 前回作成した資料の再利用性の確認
    * イベント参加フォームやイベントページなど、再利用が効くのか確認。
* 社内の時事ネタにテーマを寄せる
* アンケート入力をイベント時間中に行う
    * イベント後に記入を促しても回答率が悪かったため、その場で記入してもらうようにしました。

### 発表

#### NO.1 【SpreadsheetをDBとして扱ってWebアプリ作成してみた】

Speaker📢 : [私](https://qiita.com/fuga___)

内容は以下Qiita記事を元ネタに、実際にVue.jsで作成したアプリの紹介を交えてスライドを作成しました。
[【Vue.js】 Google SpreadSheet をデータベースの代わりに使う。 - Qiita](https://qiita.com/fuga___/items/7f59288be6fa1a328b33)
簡易的なDBを手軽に用意したい！となったときにオススメです。

#### NO.2 【RDBでツリー構造を表現してみた話】

Speaker📢 : ヒルタ さん

ツリー構造を有するRDBを設計するとき、以下のような実現方法があります

* 隣接リストモデル (Adjacency List Model)
* 経路列挙モデル (Path Enumeration Model)
* 入れ子集合モデル (Nested Sets Model)
* 閉包テーブルモデル (Closure Table Model)
* 肥沃な森林モデル(Fertile Forest Model)

エンジニアからの支持が厚い「SQLアンチパターン」の内容と照らし、それぞれの方法を図でわかりやすく解説してくれました。
[SQLアンチパターン - Amazon](https://www.amazon.co.jp/SQL%E3%82%A2%E3%83%B3%E3%83%81%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B3-Bill-Karwin/dp/4873115892/ref=sr_1_1?adgrpid=48776508890&gclid=EAIaIQobChMI26C1iuGi5QIVDbaWCh3CvwrGEAAYASAAEgIwwvD_BwE&hvadid=338538529906&hvdev=c&hvlocphy=1028853&hvnetw=g&hvpos=1t1&hvqmt=e&hvrand=17707252927702880805&hvtargid=kwd-335484809678&hydadcr=27264_11561110&jp-ad-ap=0&keywords=sql%E3%82%A2%E3%83%B3%E3%83%81%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B3&qid=1571296897&sr=8-1)
実用的な知識で、もっと深く掘り下げたものを聞きたくなる内容でした。

#### NO.3 【本当はすごい受発注のデータベース】
Speaker📢 : I・Y さん

弊社のサービスである「BtoBプラットフォーム受発注」はどんなテーブル構成で作られているのか。
また、どれだけの量のデータがDB上に存在しているのかを、ユーモラスな例えを交えて話していただきました。


#### NO.4 【新しくなったDBについて】
Speaker📢 ： DB担当者 さん

テーマ選択の理由にもなった、新しいインフラ設備についてお話していただきました。
今までと比べどんな変化があるのか、どんなスペックを持っているのかを解説していただきました。

### 結果発表
NO1、NO3の発表が同票で一位になりました。

次の登壇でも良い結果を出せるよう精進して行きたいと思います！

# 今後の展望

* 弊社の文化として醸造するために、開発部だけで閉じずに営業部も巻き込んで開催する。
    * 次回以降営業部参加予定！
* 社内勉強会立ち上げの前例となり、社内にノウハウを展開する。
    * Qiitaや社内ブログで展開。
* 同時多発的に様々な勉強会が有志で立ち上がるよう支援する。
@vue/cliを4系にしたらjestの--coverageが効かなくなった。

@vue/cliを4系にしました。

https://cli.vuejs.org/migrating-from-v3/

特段ムズカシイことはありませんでた。

で、テストを実施したところ...

```sh
yarn vue-cli-service test:unit --coverage --verbose --silent
```

あれ？？

```text
----------|----------|----------|----------|----------|-------------------|
File      |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |
----------|----------|----------|----------|----------|-------------------|
All files |        0 |        0 |        0 |        0 |                   |
----------|----------|----------|----------|----------|-------------------|
```

カバレッジが0になっちゃいました。

設定変えてないんですけどね。変えなきゃいけなくなったんでしょうか？

前述のここをみたところ、プリセットが用意されているようです。
https://cli.vuejs.org/migrating-from-v3/

```json:package.json
〜〜〜
  "jest": {
    "preset": "@vue/cli-plugin-unit-jest",
〜〜〜
```

だけでいいとか、でも自分のはcollectCoverageFromで明示してたんですよね。

```json:package.json
〜〜〜
  "jest": {
    〜〜〜
    "collectCoverageFrom": [
      "src/**/*.{vue}",
    ]
〜〜〜
```

なんでこれでダメなの？？と思いいろいろ試してたんですが解決しました。

これでうまく行きました。```*.{vue}```から```*.vue```への変更です。

```json:package.json
〜〜〜
  "jest": {
    〜〜〜
    "collectCoverageFrom": [
      "src/**/*.vue",
    ]
〜〜〜
```

結果もこの通り。

```text
-------------------------------|----------|----------|----------|----------|-------------------|
File                           |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |
-------------------------------|----------|----------|----------|----------|-------------------|
All files                      |      100 |      100 |      100 |      100 |                   |
 src                           |      100 |      100 |      100 |      100 |                   |
  App.vue                      |      100 |      100 |      100 |      100 |                   |
〜〜〜〜
```

なんで```{}```がダメになっちゃったんでしょうね〜
spacemacsのdevelopブランチを新しくした時にdotspacemacs-mode-line-themeがnilとなる

※ dotspacemacs変数関連はまあだいたい [これ](https://qiita.com/v2okimochi/items/cee399ef60201f485a9a)で良いじゃろと思っている



spacemacsの `develop`ブランチを新しくすると、 `.spacemacs`のテストがこうやって落ちる。

- Windows10のユーザ名を `v2okimochi`とする
- Winじゃなくても現象は同じだと思う

```
* Testing settings in dotspacemacs/init [[file:c:/Users/v2okimochi/.spacemacs::dotspacemacs/init][Show in File]]

** TEST: [[file:c:/Users/v2okimochi/.spacemacs::dotspacemacs-mode-line-theme][dotspacemacs-mode-line-theme]] is 'spacemacs, 'all-the-icons, 'custom, 'vim-powerline or 'vanilla or a list with `car' one of the previous values and properties one of the following: `:separator' or `:separator-scale'
*** FAIL: nil
```


フォント設定の上あたり（適当な場所）に `dotspacemacs-mode-line-theme`を差し込んで解決する。
参考：https://github.com/channingwalton/dotfiles/blob/8f393c5a5c52982191c0690294408e132bb6f8bc/spacemacs#L231

```
dotspacemacs-mode-line-theme '(spacemacs :separator wave :separator-scale 1.5)
```
perl-DBD-MySQLのSRPMでmysqlのPATHを指定してRPMを作成する方法

```sh:
# perl-DBD-MySQL の src.rpm をダウンロード
yum install yum-utils
yumdownloader perl-DBD-MySQL
```

```
yum remove -y mysql-devel
yum install -y \
 gcc perl-DBI perl-devel

cd /root/rpmbuild/SPECS/
```

* 自前でビルドした mysql が /opt/mysql/ にインストールしている時、以下指定

```diff:perl-DBD-MySQL.spec
  %build
- perl Makefile.PL INSTALLDIRS=vendor OPTIMIZE="%{optflags}" --ssl
+ perl Makefile.PL --mysql_config=/opt/mysql/bin/mysql_config INSTALLDIRS=vendor OPTIMIZE="%{optflags}" --ssl
  make %{?_smp_mflags}
```

```sh:ビルド
rpmbuild -bb perl-DBD-MySQL.spec
```
Node.jsでログにUser IDを自動出力

## 背景

ECサイトなどを運用する場合、ログにユーザの識別IDが付与されていると調査時に行動を把握することが容易なため便利です。
そこで今回はNode.js（Express）で実現してみたいとおもいます。

## 実装

### userId保持用の箱を準備
ログを出力する際、userIdを参照できるようにシングルトンなクラスを作成しておきます。

```requestContext.js
class RequestContext {
  init(userId) {
    this.userId = userId
  }

  getUserId() {
    return this.userId
  }
}

export default new RequestContext()
```

### Expressサーバ

下記の記述を、他のルーティングの上部に配置します。

```express/app.js
import requestContext from 'path/to/requestContext'

app.use((req, res, next) => {
  if (!req.session.userId) {
    // sessionにuesrIdがない場合は、uuidを設定
    req.session.userId = uuid.v4()
  }
  // 事前に作成したrequestContextに、userIdを設定
  requestContext.init(req.session.userId)
  next()
})
```
※ session管理には、`express-session`を使っています。
※ `next()`では、下部に処理を委ねます。

### winston

今回loggerには[winston](https://github.com/winstonjs/winston)を用います。
例ではtimestampとログレベルも出力してます。

```logger.js
import path from 'path'
import { createLogger, format, transports } from 'winston'
import config from 'config'
import requestContext from './requestContext'

const { combine, timestamp, printf } = format
const logDir = path.resolve('log')

const logFormatter = printf(
  ({ level, message, timestamp }) =>
    `[${timestamp}] [${level.toUpperCase()}] [${requestContext.getUid()}] ${message}`
)

export const logger = createLogger({
  level: config.get('logger.level.default') || 'info',
  format: combine(timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }), logFormatter),
  transports: [
    new transports.Console(),
    new transports.File({
      filename: `${logDir}/application.log`
    })
  ]
})

export const apiLogger = createLogger({
  level: config.get('logger.level.api') || 'info',
  format: combine(timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }), logFormatter),
  transports: [
    new transports.Console(),
    new transports.File({
      filename: `${logDir}/api.log`
    })
  ]
})
```

## 検証

### logger呼び出し例

```javascript

import logger from 'path/to/logger'

logger.error('test!!')
```

### 出力例

```application.log
[2019-10-30 11:08:18] [ERROR] [6ffd3f48-c967-43ac-88e3-d6886c82d3a5] test!!
```
Ruby独特の代入演算子 ||= の意味について説明してみた

# 代入演算子とは

Rubyも含め、多くのプログラミング言語では、`x`に`1`を加算する操作を以下のように記述[^インクリメント演算子]できます。

```
x = x + 1
```

この操作は、Ruby（ほか多くのプログラミング言語）において、以下のような短縮表記が可能です。

```
x += 1
```

このときの`+=`という演算子、並びに加算以外の演算に対して同様の動作を行うように定義された演算子を総称して「代入演算子」と呼びます。

[^インクリメント演算子]: なお、Ruby以外の言語では、`x = x + 1`を`x++`と表記できるものがあります。こうした使い方をする`++`を「インクリメント演算子」と呼びます。しかしながら、Rubyでは`x++`のような表記を使うことはできません。

## `+=`以外の代入演算子

Rubyにおいては、`+=`以外の代入演算子としては以下のようなものが存在します。

```
# rails console
>> x = 1
=> 1
>> x += 1
=> 2
>> x *= 3
=> 6
>> x -= 8
=> -2
>> x /= 2
=> -1
```

# `||=`という演算子の意味

一般的な代入演算子と異なり、こちらはRuby独特の代入演算子です。例えば以下のような形で使われます。

```
# rails console
>> @foo = nil
=> nil
>> @foo ||= "bar"
=> "bar"
```

上記のコードの意味は、下記のコードの意味と同じです。

```
# rails console
>> @foo = nil
=> nil
>> @foo  = @foo || "bar"
=> "bar"
```

その動作は以下の通りです。

* 実行時点で左辺の変数が`true`と評価される場合
    * 代入は行わない
    * 右辺の式は評価しない
* 実行時点で代入先の変数が`false`と評価される場合
    * 右辺の式を評価する
    * 右辺の式の評価結果を左辺の変数に代入する

Rubyにおいては、「変数の値がnilであれば変数に代入するが、nilでなければ代入しない」という操作が頻繁に登場します。同じくRubyの特徴である「`false`と`nil`以外の全てのオブジェクトは、真偽値として評価した場合、常に`true`として評価される」という特徴と合わせて、このような場合に`||=`という演算子の存在が非常に便利なのです。
Laravel5.5 インストール

####・Composerインストール
**参考**
[CentOS7にComposerをインストールする](https://qiita.com/inakadegaebal/items/d370bcb1627fce2b5cd1)
@inakadegaebal 

####1. Laravel インストール
```console:
$composer create-project "laravel/laravel=5.5.*" --prefer-dist {インストールフォルダ名}
```

####2. .env 編集。

```ini:/.env
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE={データベース名}
DB_USERNAME={ID}
DB_PASSWORD={Password}
```
####3. /storageのパーミッション変更
```console:/
$chmod 777 -R storage
```

####4. DBの191文字超エラー回避

```php:app/Providers/AppServiceProvider.php
class AppServiceProvider extends ServiceProvider
{
    public function boot()
    {
        //追記
        \Illuminate\Support\Facades\Schema::defaultStringLength(191);
    }
    ...
```

####5. publicを {アプリドメイン}/ でアクセス
[Php laravel 5.5 project .htaccess file](https://gist.github.com/liaotzukai/8e61a3f6dd82c267e05270b505eb6d5a)

```apache:/.htaccess
//ルートディレクトリに配置
<IfModule mod_rewrite.c>
    <IfModule mod_negotiation.c>
        Options -MultiViews
    </IfModule>
    RewriteEngine On
    RewriteCond %{REQUEST_FILENAME} -d [OR]
    RewriteCond %{REQUEST_FILENAME} -f
    RewriteRule ^ ^$1 [N]
    RewriteCond %{REQUEST_URI} (\.\w+$) [NC]
    RewriteRule ^(.*)$ public/$1 
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^ server.php
</IfModule>
```
####おまけ

```console:git初期設定
$git init
$git add .
$git commit -m 'start'
//Git-Hub マイリポジトリから URL をコピーしておく
$git remote add origin '{URL}'
$git push -u origin master
PythonistがRuby on Railsに異世界転生したときの記録

## 初めに
これまではPHPかPythonでの開発がほとんどだったのですが、様々な事情により、Ruby on Railsの案件に取り組むことになりました。Pythonと比較しながらRuby on Railsを勉強しているのですが、その際に参考にした記事などを残しておきたいと思います。内容は随時更新します。

## 目次

* Rubyの環境構築
* Railsの導入


## 環境

* ubuntu 19.04 eoan ermine
* rbenv version 1.1.1
* ruby verison 2.6.5

## Rubyそのものについて


Pythonでは、以下の環境を使っていました。

```
* pyenv(Pythonのバージョン管理)
* pip(デフォルトのPackage管理)
* pipenv(仮想環境構築+Packageの管理)
```

Rubyでそれぞれに対応するのは、(というかPythonのそこら辺のツールはRubyのツール群に触発されて開発されたものが多いので、こちらのほうが大元というべきなのですが、)

```
* rbenv(Rubyのバージョン管理)
* gem(デフォルトのPackage管理:ただしRubyではPackageのことをGemとよんでいる)
* bundler(仮想環境構築＋Gemの管理）
```
です。Gemというのは、PythonでいうPackageみたいなもののようです。一般的なRubyプロジェクトは、bundlerを用いて

```shell
mkdir PROJECT_DIR
cd PROJECT_DIR

rbenv local 2.6.5 #pipenv install 3.8.0と同じノリです
gem install bundler

bundler init #これによってGemfile, Gemfile.lockが作られる。pipenv initと同じ

vi Gemfile #Gemfileに必要なライブラリ群を記載
bundler install --path vendor/bundler #Gemfileに記載したライブラリ群をvendor/bundler以下にインストール
bundler exec COMMAND #pipenv run COMMANDに対応するコマンド

```
として環境を作るようです。

PipenvとBundlerは大体同じですが、以下のような細かい違いがあります。

* `bundler exec`は`pipenv run`と対応しています。
* `pipenv shell`に対応するコマンドはなさそうです
* pipenvでは、Packageのインストール先は、デフォルトで`~/.local`以下に作られ、`PIPENV_VENV_IN_PROJECT`でプロジェクトディレクトリ以下に作成されます。
* bundlerでは`~/.bundle/config`ファイルに`BUNDLE_PATH = "vendor/bundle"`を指定することでプロジェクトディレクトリ以下(`PROJ_DIR/vendor/bundle`に)作成されます。

`bundle install`時に`--path`オプションを指定すべきかどうかは、宗教戦争になりつつあるようで、[bundle install時に--path vendor/bundleを付ける必要性は本当にあるのか、もう一度よく考えてみよう](https://qiita.com/jnchito/items/99b1dbea1767a5095d85)が参考になりました。（自分はSystemを汚したくない派なのでvendor/bundleすることにしました）


## Rails環境構築

RailsはRuby用のWeb開発フレームワークです。Flaskみたいな感じかと思っていましたが、どちらかというとDjangoのcounterpartという印象です。

Railsは統合的なWeb開発環境であり、bundlerを内包しているとのことです。
ちなみにBundlerとBundleは同じ。
Bundlerの公式ドキュメントによると、RailsはBundlerを内包しています。

> Rails comes with baked in support with bundler.
[Bundler公式ドキュメント](https://bundler.io/v2.0/guides/rails.html)

Bundlerを用いたRailsのインストールは

```shell
gem install rails
rails new APP_DIR
cd APP_DIR
bundler install
```
で良いようです。

しかし、このときのRailsのインストール先はSystemです。SystemのRubyGemはできるだけクリーンに保ちたいので、以下のようにします。

```shell
mkdir APP_DIR
cd APP_DIR
bundler init
vi Gemfile #ここでrailsをGemfileに追加
bundler install --path vendor/bundle #上記のBUNDLE_PATHの設定をしている場合は`--path`オプションは不必要
bundler exec rails install -B -d mysql
# -B：rails new 時に改めて bundler install しない
# -d DBとして mysqlを使用。（デフォルトはsqlite）

# ここで既存のGemfileをOverwirteするかどうか訊かれるので、Y
```

[参考:新規Railsプロジェクトの作成手順まとめ](https://qiita.com/yuitnnn/items/b45bba658d86eabdbb26)

## Ruby on Railsをやっていく
【Unity】【第三回】

# はじめに
 参考サイト[※１](#参考サイト)を軸としつつ、分からない点のみ補足的に記載していく。

## 第13回　攻撃当たり判定
### 概要
・移動(バイオ式)モーションの再生
・攻撃(パンチ，キック)モーションの再生
・攻撃に当たり判定(手と足)を付与

### Character Controllerの使用
・Character Controllerコンポーネントは「Collider」の一つ。（[※４](#参考サイト)）
・部分的なオブジェクトへの食い込みや、階段の昇降を実現するためのパラメタが備わっていて
　おもにプレイヤキャラクタに対して使用される。
・コライダの形状はカプセル

### Invokeメソッド
```csharp
Invoke("MethodName", t);
```
・Invokeが実行されてから，t秒後に同クラス内のメソッド「MethodName()」を実行することができる。

### 接地判定
```csharp
 // 「原点座標」と「方向」を持つ長さ無限の線分
 Ray ray = new Ray(position, direction)
 // 長さlengthのRayが任意のコライダと接触しているかどうか。
 // 地面にコライダを付加することで衝突判定ができる。
 Physics.Raycast(ray, length);
```

# はまった点
![名称未設定.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/505426/31ffe3e6-2c9e-a30f-84a9-5600ca8abce4.png)
ユニティちゃんのモデルにスクリプトをアタッチしようとしたら
「プレハブインスタンスの子要素は削除／移動できないよ」というエラーが発生。
原因は単純で、同スクリプトを2回アタッチしようとしていたため。
(ウィンドウを縮めているとアタッチ済みなことに案外気が付かない。)


#参考サイト
1. [【Unity・Blender】アニメーションの使い方・作り方をマスターする！](https://xr-hub.com/archives/13700)
2. https://unity-shoshinsha.biz/archives/935#State
3. https://qiita.com/r-ngtm/items/c56a2884d09deda78f22
4. [Character Controller](https://docs.unity3d.com/ja/2017.4/Manual/class-CharacterController.html)
[Android] 音量変更（=音量ボタン押下）の検出方法

昔からあるレガシーな方法ですが、ググって出てくる情報が少し実用性には欠けるため、書いておきます。

## 手法
音量変更もしくは音量ボタンが押された事を検出するIntentとして、AudioManager.VOLUME_CHANGED_ACTION （android.media.VOLUME_CHANGED_ACTION）があります。これをBroadcastReceiverで受ければ良いだけです。

ここまではググってすぐに出てくる情報ですが、AudioManager.VOLUME_CHANGED_ACTIONは以下の点に注意する必要があります。

- 一度の音量変更操作で複数のイベントが通知される
    - AudioManager.STREAM_MUSICなどSTREAM毎に通知され、しかも音量変わって無くても通知される
- 画面ON中の初回ボタン操作時は音量UI表示され、実際には音量が変わらないためにイベント通知されない
- 画面OFF中は音楽アプリ等で音楽再生していないと、ボタン押してもイベント通知されない
    - ボリュームが変わらないため

## ソースコード

```xml:AndroidManifest.xml 
<receiver android:name=".VolumeChangedActionReceiver">
    <intent-filter>
        <actionandroid:name="android.media.VOLUME_CHANGED_ACTION" />
    </intent-filter>
</receiver>
```

```java:VolumeChangedActionReceiver.java 
public static class VolumeChangedActionReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {

        if (intent.getAction().equals("android.media.VOLUME_CHANGED_ACTION")) {
            int newVolume = intent.getIntExtra("android.media.EXTRA_VOLUME_STREAM_VALUE", 0);
            int oldVolume = intent.getIntExtra("android.media.EXTRA_PREV_VOLUME_STREAM_VALUE", 0);
            int streamType = intent.getIntExtra("android.media.EXTRA_VOLUME_STREAM_TYPE", 0);

            if (streamType == AudioManager.STREAM_MUSIC) {
                // TODO: write your code
            }
        }
    }
}
```
本家StackOverflowで[closed]がでました

ctrl+↓ on android tablet since it can not be used instead of [closed]
https://stackoverflow.com/questions/58576370/ctrl%e2%86%93-on-android-tablet-since-it-can-not-be-used-instead-of

(原文)
 This question needs details or clarity. It is not currently accepting answers. Learn more.
(google翻訳)
この質問には詳細または明確さが必要です。現在、回答を受け付けていません。もっと詳しく知る。

(原文)
Want to improve this question? Add details and clarify the problem by editing this post.
(google翻訳)
この質問を改善したいですか？この投稿を編集して詳細を追加し、問題を明確にします。

いい方法があれば、教えて下さい。


#2020-03-20
（参照）
I want to color the part with empty characters in the ruled line [closed]
https://stackoverflow.com/questions/60723491/i-want-to-color-the-part-with-empty-characters-in-the-ruled-line

(原文)
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 days ago.
(google翻訳)
閉まっている。この質問には詳細または明確さが必要です。現在、回答を受け付けていません。 
この質問を改善したいですか？この投稿を編集して詳細を追加し、問題を明確にします。 
2日前に閉鎖しました。
ターミナルからiOSシミュレータを立ち上げるよ

iOSシミュレータでテストしたい時、いちいちXcode立ち上げてそこからシミュレータを開くのは面倒ですね。
いきなりXcodeのアップデートとか始まっちゃってイライラ爆発することもありますよね。
そんな訳でターミナルからシミュレータを開く方法をご紹介するよ。

```zsh
$ open -a simulator 
```

これだけです。
僕は.zshrcでエイリアスを作って、"ios"と入力するだけで開くようにしています。

```zsh:.zshrc
# iOS シミュレータを開くエイリアス
alias ios="open -a simulator"
```
GKEで helm + nginx-ingress を使う

# 前提条件
- クラスタをすでに構築済み
- kubectlが使える
- helm install でchatを配置可能
- gcloud auth済み
- kubernetesのnamespaceはdefaultを使用
- tlsは作成済み（tlsはなくても動作します。）

# 1. サンプルappをgcrにpush
※説明のため筆者の公開しているサンプルイメージをダウンロードしています。適時書き換えてください。
```
$ docker push newsdict/rust:v0.0.1
$ docker tag newsdict/rust:v0.0.1 docker gcr.io/newsdict-217812/docker_rust:v0.0.1
$ docker push gcr.io/newsdict-217812/docker_rust:v0.0.1
```

# 2. podとserviceを配置
※このセクションはモックを配置するだけなので適時書き換えてください

kubectl を使いserviceとpodを作成します。（１ファイルに書いてますが、分けても大丈夫です）
## sample-service.yaml
```
apiVersion: v1
kind: Service
metadata:
  name: docker-rust-service
  labels:
    name: docker-rust-service
spec:
  type: NodePort
  ports:
    - port: 80
      targetPort: 3000
  selector:
    app: docker-rust
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: docker-rust
spec:
  replicas: 1
  revisionHistoryLimit: 1
  selector:
    matchLabels:
      app: docker-rust
  template:
    metadata:
      labels:
        app: docker-rust
    spec:
      containers:
      - name: master
        image: gcr.io/newsdict-217812/docker_rust:v0.0.1
        workingDir: /rust
        resources:
          requests:
            cpu: 50m
            memory: 50Mi
        ports:
        - containerPort: 3000
        readinessProbe:
          httpGet:
            path: /
            port: 3000
          initialDelaySeconds: 30
          periodSeconds: 30
          timeoutSeconds: 5
```

## 配置
```
$ kubectl apply -f sample-service.yaml
```

# 3. helmでnginx-ingressをインストール
## static ipの作成
```
gcloud compute addresses create docker-rust-static-ip
```
## install
```
$ helm install --name nginx-ingress stable/nginx-ingress --set rbac.create=true --set controller.service.loadBalancerIP=xxx.xxx.xxx.xxx
```
※xxx.xxx.xxx.xxxのところは作ったstatic-ipに書き換えてください
※--set rbac.create=trueはrbacを使っている時だけのオプションなので適時消すなりしてください

## 確認
以下で作成が完了したことを確認してください。

```
$ kubectl get service nginx-ingress
```
```
$ kubectl get pods |grep nginx
```

# 4. ingressを配置

## ingress.yml
```
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: docker-rust-ingress
  annotations:
    kubernetes.io/ingress.class: "nginx"
spec:
  rules:
    - host: example-rust.newsdict.io
      http:
        paths:
          - backend:
              serviceName: docker-rust-service
              servicePort: 3000
            path: /
  tls:
    - hosts:
        - example-rust.newsdict.io
      secretName: docker-rust-tls
```

## 適用
```
$ kubectl apply -f ingress.yml
```

# 5. ipの確認
nginx-ingressでは ` $kubectl get ingress` で見えるIPは使えない、serviceに配置されているLoadBalancerのIPを使う必要があります。
```
$ kubectl get service | grep nginx-ingress-controller
```

上記に表示されるEXTERNAL-IPをDNSなどに紐づければnginx-ingressの導入完了です
JScrollBarで自動スクロールしようとしたらイベントハンドラの描画が1度だけだった件

詰まって数時間が吹き飛ばされたので、メモ代わりに。Swingを使っている人ならだれでも一度は通る失敗（らしい）。

## どんなのをつくっていたか
Javaで自作シェルっぽいものを作ろうとしていて、JScrollPaneを自動スクロールさせようとしていた。調べながら書いたソースコードがこれ。

```Java:MyShell.java
class MyShell extends JFrame implements ActionListener{
    MyShell{
//（中略）   
    String now = new File(".").getAbsoluteFile().getParent().toLowerCase();//カレントディレクトリ

    JTextField text = new JTextField();//入力エリア
    text.addActionListener( this );
    JTextArea area = new JTextArea(now+"->");//表示エリア
    JScrollPane scrollpane = new JScrollPane(area);

    JPanel p = new JPanel()
    p.add(text,BorderLayout.SOUTH);
    p.add(scrollpane);
//（中略）
    }
    public void actionPerformed(ActionEvent e){
  	    String input = text.getText().toLowerCase();
  	    if(input.equals("exit")){System.exit(0);}//強制終了用
        area.append(text.getText()+"\nPC->"+mani(input.split(" "))+"\n\n"+now+"->");//描画エリアに追記
        text.setText("");//入力エリアの内容を消去

        JScrollBar scrollBar = scrollpane.getVerticalScrollBar();
        scrollBar.setValue(scrollBar.getMaximum());
    }
    public String mani(String[] input){
        //コマンド解釈用関数
    }
//（中略）
}
```
※分かりやすいように、コンストラクタの中で宣言しているように書いていますが、実際はインスタンスフィールドとして各種変数を宣言しています。

一応、解説しておくとactionPerformedは入力用テキストフィールド内でエンターキーが押されたときに呼び出されます[（参考リンク）](https://www.javadrive.jp/tutorial/event/index2.html)。そして、エンターキーを押した直後にコマンドの解釈が行われ、描画エリアに追記。その後、スクロールバーの高さの分だけスクロールされて、JTextAreaの一番下が表示されている......はずでした。

## なにがいけなかったのか
結論から言うと、イベントハンドラとして登録された処理は、そのすべての処理が終わってから描画されます。つまり、```scrollBar.getMaximum()```で取得できる大きさは再描画前の大きさなので、再描画前のJTextAreaの一番下の場所にしか行けないのです。`actionPerformed`の最後の行に`Thread.sleep(1000)`でも挿入してみると、挙動がよく分かると思います。
まあ、よくよく考えれば、描画処理はできるだけ少ない回数で済んだほうが良いですし、当然といえば当然なんですね。

## 解決法
（ネットはちゃんと調べると、いくらでも情報が出てきますね......。）
>単一のイベントハンドラーでは状態の変更とただ一回のrepaintの呼び出しのみが許されると思ってください。複数回repaintを呼び出してもpaintComponentメソッドは一度しか呼び出されません。

引用元：[https://teratail.com/questions/75183](https://teratail.com/questions/75183)

更に調べていると、[こんな記事](http://demmys.hatenablog.com/entry/2012/06/22/153104)が......。同じことで詰まっている人いましたね......。この記事にあるコードを`actionPerformed`に入れてやると無事動きました。

また、Swingはシングルスレッドでの設計のようでした。
> invokeLater() メソッドは（中略）保留中のすべての AWT イベントが処理されたあとに発生します

引用元：[http://wisdom.sakura.ne.jp/system/java/swing/swing4.html](http://wisdom.sakura.ne.jp/system/java/swing/swing4.html)

## まとめ
1. なんでもかんでもイベントハンドラで行おうとしない
2. イベントハンドラでは終了時に1度だけ描画処理を行うのが基本
3. Swingでイベントハンドラのスレッド以外から何らかの描画処理をしたい場合はinvokeLater()を使う

## 余談
余談ですが、`paintImmediately`も使ってみました。どうやら、描画処理だけで、それ以外の数値等の更新はやはりイベントハンドラ終了後に行われるようです。

```Java:MyShell.java
actionPerformed(ActionEvent e){
    System.out.println(scrollbar.getValue()+"#"+scrollbar.getMaximum()+"#"+area.getHeight());
    p.paintImmediately(0,0,5000,5000);
    System.out.println(scrollbar.getValue()+"#"+scrollbar.getMaximum()+"#"+area.getHeight());
}
```

<br>
以上。
veevalidate3 入門

# 開発環境 

- laravel5.8
- vue2
- veevalidate3

# 参考資料

- 公式：https://logaretm.github.io/vee-validate/
- https://logaretm.github.io/vee-validate/guide/validation-provider.html#higher-order-components

# veeValidate3の設定

- app.jsで必要な物をimport(vueとveevalidateはnpm installしていることを前提)

```javascript:app.js

import Vue from 'vue'
import './validate'

import {
    ValidationProvider,
    configure,
    localize,
    extend,
} from 'vee-validate';
import ja from 'vee-validate/dist/locale/ja';

Vue.component('ValidationProvider', ValidationProvider);

// 共通で変更したいoptionがあれば
configure({
    bails: false,
});

// 一括でrulesをextend
import * as rules from 'vee-validate/dist/rules';
for (let rule in rules) {
    extend(rule, rules[rule]);
}

localize('ja', ja);
```

# バリデーション実行

 - templateに記述する例

```vue:sample.vue
<ValidationProvider rules="required" ref="mail" v-slot="{ errors }">
     <input v-model="email" type="text" />
     <span>{{ errors[0] }}</span>
</ValidationProvider>
```
rluesで適応させるバリデーションを設定
以下でバリデーションの種類を確認できる

github
https://github.com/logaretm/vee-validate/tree/master/src/rules


# エラーメッセージの変更

```vue:vue
this.$refs[this.name].setErrors(["error message"]);
```

# エラーメッセージの取得

```vue:vue
this.$refs[this.name].messages;
```

# ボタン押下時のバリデーション

- $refsを使用しバリデーションを実行

```vue:sample.vue
<template>
    <div class="container--small">
        <ValidationProvider rules="required" ref="myinput" v-slot="{ errors }">
            <input v-model="value" type="text" />
            <span>{{ errors[0] }}</span>
        </ValidationProvider>

        <button @click="validateField()">Submit</button>
    </div>
</template>

<script>
export default {
    data() {
        return {};
    },
    computed: {},
    methods: {
        validateField() {
            // Validate the field
            return this.$refs.myinput.validate();
        }
    },
    created() {}
};
</script>

```

# 別ファイルでバリデーション追加
# 画面固有バリデーション
# checkboxのバリデーション

```vue:sample.vue
<template>
    <div class="container--small">
        <P>check box v-for</P>
        <div class="form-check">
            <label class="form-check-label">
                <ValidationProvider rules="required" v-slot="{ errors }">
                    <div v-for="(item, index) in checkArray" :key="index">
                        <input type="checkbox" v-model="checkValue" :value="item.id" />
                        {{ item.val }}
                    </div>
                    <span>{{ errors[0] }}</span>
                </ValidationProvider>
            </label>
        </div>
    </div>
</template>

<script>
export default {
    data() {
        return {
            // チェック結果が入りv-modelをrequiredチェックしている
            checkValue: [],
            checkArray: [
                { id: "1", val: "coffe" },
                { id: "2", val: "milk" },
                { id: "3", val: "cake" }
            ]
        };
    },
    computed: {},
    methods: {},
    created() {}
};
</script>

```
outlook メール仕分けスクリプト

# 概要

outlook 2007で、メール仕分けやってみた。

# 環境

windows10 64bit
outlook 2007

# サンプルコード


```
Sub test()
    Dim NameSpc As Object
    Dim objbox As Object
    Dim fInbox As Object
    Dim jnkbox As Object
    Dim mail As Object
    Set NameSpc = Application.GetNamespace("MAPI")
    Set fInbox = NameSpc.GetDefaultFolder(olFolderInbox)
    Set jnkbox = NameSpc.GetDefaultFolder(olFolderJunk)
    MsgBox fInbox.Items.Count
    For i = fInbox.Items.Count To 1 Step -1
        Set mail = fInbox.Items(i)
        If InStr(mail.Subject, "一般") Then
            MsgBox mail.Subject
            mail.Move jnkbox
        End If
    Next
    Set mail = Nothing
    Set fInbox = Nothing
    Set NameSpc = Nothing
End Sub
```

# VBエディタを起動

[ファイル] タブの [リボンのユーザー設定]> に移動します。
[リボンのユーザー設定] および [メイン タブ] の下の [開発] チェック ボックスをオンにします。

# マクロが動くように

ファイル→オプション→セキュリティセンター→セキュリティセンターの設定→すべてのマクロに警告を表示するまたはすべてのマクロを有効にする

# ワンクリックでマクロ起動

クイック アクセス ツール バーの右端の下向きの三角形をクリックします。
[その他のコマンド] をクリックします。
[コマンドの選択] で [マクロ] を選択します。

以上。
kubectlのbash shell autocompletionの設定

# bashでkubectlのautocompletionを設定する方法

# 参考
- https://kubernetes.io/docs/tasks/tools/install-kubectl/#enabling-shell-autocompletion

# 環境
- ubuntu18.04
- bash

# 設定log
```bash:bash
vagrant@vagrant:~$ apt-get install bash-completion
vagrant@vagrant:~$ sudo apt-get install bash-completion
vagrant@vagrant:~$ type _init_completion
vagrant@vagrant:~$ source /usr/share/bash-completion/bash_completion
vagrant@vagrant:~$  type _init_completion
vagrant@vagrant:~$  echo 'source <(kubectl completion bash)' >>~/.bashrc
vagrant@vagrant:~$  sudo su -
root@vagrant:~# sudo kubectl completion bash >/etc/bash_completion.d/kubectl
```
logout => loginしたらautocompletionが効くようになる
astah*プラグイン開発スニペット

###### 現在開いている図取得
```java
IDiagramViewManager diagramViewManager = api.getViewManager().getDiagramViewManager();
IDiagram currentDiagram = diagramViewManager.getCurrentDiagram();
```

###### 選択されている図要素取得
```java
IDiagramViewManager diagramViewManager = api.getViewManager().getDiagramViewManager();
List<IPresentation> iPresentationList = Arrays.asList(diagramViewManager.getSelectedPresentations());
```

###### 文字の色を変更
例：inpはINodePresentationです。IPresentation派生なら行けるかと。

```java
inp.setProperty(Key.FONT_COLOR, "#FF0000");
```

###### 簡易テキストダイアログ
```java
package xyz.astah.example;
 
import java.awt.Frame;
import java.awt.Insets;
 
import javax.swing.JDialog;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
 
public class TextDialog extends JDialog {
    public TextDialog(String text, Frame frame, int width, int height, boolean modal) {
        super(frame, "Text Dialog", modal);
 
        JTextArea jTextArea = new JTextArea(text);
        jTextArea.setMargin(new Insets(8, 8, 8, 8));
 
        JScrollPane jScrollPane = new JScrollPane(jTextArea);
 
        this.getContentPane().add(jScrollPane);
        this.setBounds(frame.getX() + 100, frame.getY() + 100, width, height);
        this.setVisible(true);
    }
}
```
使用例

```java
TextDialog textDialog = new TextDialog(outputText.toString(), api.getViewManager().getMainFrame(), 300, 300, false);
```
CentOS8へCentOS7のcompat-gcc-44-4.4.7をインストール

CentOS8でGCC4.4.7を使いたい場合。

http://mirror.centos.org/centos/7/os/x86_64/Packages/
から


* compat-gcc-44-4.4.7-8.el7.x86_64.rpm
* compat-gcc-44-c++-4.4.7-8.el7.x86_64.rpm
* libstdc++-4.8.5-39.el7.x86_64.rpm

をダウンロードしインストールするとよい。

```sh:CentOS8で実施
# フォースと共にあれ。
rpm -ivh --force \
 compat-gcc-44-4.4.7-8.el7.x86_64.rpm \
 compat-gcc-44-c++-4.4.7-8.el7.x86_64.rpm \
 libstdc++-4.8.5-39.el7.x86_64.rpm

# もしほかのGCCが入っていたら削除 (お好みで。)
yum remove -y gcc gcc-c++

# シンボリックリンクの修正
update-alternatives \
 --install /usr/bin/gcc gcc /usr/bin/gcc44 20 \
 --slave   /usr/bin/g++ g++ /usr/bin/g++44

export CC=/usr/bin/gcc44
export CXX=/usr/bin/g++44
```

このあと滅茶苦茶コンパイルした
「ねそプロ」ショッピングサイトを作ろう

#ネットワークを利用した双方向性のあるコンテンツのプログラミング教材
ネットワークを利用したプログラムの例として、「ショッピングサイト」の教材を作成しました。
ブロック部品をドラッグして置くだけの簡単プログラミングです。Google Blockly を使ってJavaScriptのコードを作成して実行します。データは、Ajaxで非同期通信をサーバと行い、データベースに記録しています。

http://iwate-manabi-net.sakura.ne.jp

１　ショッピングサイトを作ろう
２　ショッピングサイトで買い物しよう
３　売り上げランキングを見よう

以上３つのWebページでできています。

#「ショッピングサイトを作ろう」の使い方
(1)　「画面に表示　スタート」のブロックを置きます。
(2)　「商店名」のブロックを置き、商店の名前を入力します。
(3)　ショッピングカートを置きます。
(4)　商品を並べるワクを置きます。
(5)　その中に商品を入れます。

ここで「実行」ボタンを押すと、ショップサイトの画面が作られます。
商品の写真、商品名、価格のカードが表示されます。
ブロックを入れ替えると、商品の表示順も変わります。
商品カードの「▲、▼」ボタンを押しても個数が変わりません。
↑これは、プログラムをまだしていないからです。

(6)　「▲ボタンが押された」を置きます。
(7)　その中に、「個数を増やす(+1)」を置きます。
　　このままでは、無限に注文できるので、
(8)　「もし、個数＜５なら」を置き、
　　　この中に「個数を増やす(+1)」を置くようにします。
　→これで、最大注文数５に制限されます。

(9)　「▼ボタンが押された」を置きます。
(10)　その中に、「個数を減らす(-1)」を置きます。
　　　このままでは、注文数がマイナスにできるので、
(11)　「もし、個数＞０なら」を置き
　　　この中に、「個数を減らす(-1)」を置きます。
　　→　これで、注文数がマイナスになることを防ぎます。

(12)　「カートボタンが押された」を置き、決済処理します。
(13)　「選択した全商品を表示」で商品名一覧と合計を表示します。
(14)　「データをサーバに送る」で買い上げ処理をします。
(15)　「もどるボタン」で、途中でやめることができるようにします。

ショッピングサイトに必要な最低の機能を,ブロック一つ一つに分けて
組み合わせてプログラミング学習できるようにしました。
さらに、セキュリティを学べる機能の追加を考えております。

#「ショッピングサイトで買い物しよう」の使い方
(1)　「ショッピングサイトを作ろう」の「接続先アドレス」にとなりの人と、同じ値を入力します。
(2)　 「実行」ボタンを押してください。
　　→　接続先アドレスにショッピングサイトが出店されます。
(3)　「ショッピングサイトで買い物しよう」のページを表示します。
　※ タブで表示を切り替えてください。
(4)　「ショッピングサイトで買い物しよう」の「接続先アドレス」にも同じ値を入力します。
(5)　「ショッピングサイトで買い物しよう」の「最新情報」ボタンを押します。
　→　自分と、となりの人のショッピングサイトが表示されます。
　→　商店名をクリックすると、右側に作成したショッピングサイトが表示されます。
(6)　タブで「ショッピングサイトを作ろう」を表示されて、商品を追加してください。
　→　「ショッピングサイトを作ろう」の「実行」ボタンを押して、出店します。
　→　「ショッピングサイトで買い物しよう」→「最新情報」ボタン
　　→　商店の商品が追加されたことを確認してください。
※　同一コンピュータから、同一アドレスに出店できるのは１サイトのみです。
※　商店名を変えても上書きされます。
※　プログラムを組んだとおりに作動します。不具合のあるサイトもそのまま表示されます。
　↑評価に使ってください。（ただし、表示は１日のみです）
(7)　クラス全体で、「接続先アドレス」を同じものにします。
　　※　「接続先アドレス」は先生が指定してください。
(8)　「ショッピングサイトを作ろう」の「実行」ボタンを押して、出店します。
(9)　「ショッピングサイトで買い物しよう」で出店を確認します。
※　「ショッピングサイトで買い物しよう」は、最新更新の順で表示します。
(10)　クラス全体で、ショッピングモールを作って、売り上げを競いましょう。

#「売り上げランキングを見よう」の使い方
(1)　「売り上げランキングを見よう」のページを表示します。
　→「売り上げランキングを見よう」のページを選択します。
※ タブで表示を切り替えてください。
(2)　「売り上げランキングを見よう」の「接続先アドレス」にも同じ値を入力します。
(3)　クラス全体で売れている商品ランキングを表示します。
(4)　売り上げを上げるために、追加したい機能を考えさせます。
(5)　買い物額のランキングも表示されます。
　　→　使ったお金を支払うための「労働時間」について考えさせます。
　　→　お金を大切に使う心を育てます。
【Unity】【3DAnimation】第二回 自作アニメーションを作成する。

# 

# animation用語について

リギング : スキニングやIK, FKの設定などアニメーションに必要な情報を付与する工程

スケルトン : モデルに付与する骨組み(ボーン)のこと。
　　　　　　　ボーンは球(関節)と線(骨)で構成される。

スキニング : ポリゴン(肉)とボーン(骨組み)の依存関係を設定する工程。

# Unityにおけるアニメーションに関するファイルについて
3Dモデル : fbxファイルの一部で、メッシュ等のポリゴン情報のこと
アバター : fbxファイルの一部で、CGソフト(Blenderなど)で作成したリグとUnityで扱うリグの
　　　　　　　対応関係を保持する。アニメーションを行う際に必須となる。
アニメーションファイル : fbxファイルの一部で、一連のキーフレームanimationを保持する。
アニメーションコントローラファイル : 複数のアニメーションの状態遷移の管理やアニメの再生状況等を管理する。

# 作成してみる
参考サイト1.の通り
## 補足
・fbxファイルでエクスポートする。
・カメラとライトはエクスポート対象外
・アーマチュアとメッシュのみエクスポート対象とする。

## Blenderでの操作まとめ
・オブジェクトを原点に移動させる。
　⇒Shift + S でカーソルを原点に移動させてからオブジェクト作成する。
・カメラの平行移動
 ⇒ Shift + ホイール押下
・アニメーションのキーフレーム挿入
 ⇒ I
・ボーン選択
 ⇒ R + 左クリック

## はまった点
Blender側でのExport時の設定がおかしかったり、フェイスアニメーション?を設定していたりすると一貫してユニティちゃんが下記ポーズをとる。
![aa.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/505426/8bed2e2b-21b0-d6be-84dc-a4fa57ee54fb.png)


# 参考サイト
[1.Blenderで人型用のアニメーションを自作して、Unity上のモデルに適用するまでの流れ](https://qiita.com/ritsuka/items/a8684c52f5320e068f32)
[2.アニメーション - Unity マニュアル](https://docs.unity3d.com/ja/2018.1/Manual/AnimationSection.html)
[3.【Unity】「アニメーションが再生されない」「止まる」時の対処法](http://tsubakit1.hateblo.jp/entry/2019/03/04/210953)
markdown-preview-enhancedでプレビュー実行したpythonが文字化けするやつ

win10環境でutf-8のmarkdown編集中なのにcp932にエンコード出来ないと怒られるので直した。

```python
# ```py {cmd="python"}
  print(chr(ord('€'))) # 検証コード
# ```
```

winの環境変数にPYTHONENCODING='utf-8'を指定して解決。
rescueでエラーを拾ってくれない問題

#BackGround
[Postman](https://www.getpostman.com/)を使ってRailsのアクションを設計どうりに処理してくれるかテストしていました。
問題になったのはこの```user_controller```のshowアクション

``` user_controller.rb
 class UsersController < ApplicationController

  def show
    @user = User.find(params[:id])
      render json: { status: 'success', data: @user }
    rescue ActiveRecord::RecordNotFound
      render json: { status: 'error!', data: @user.errors }
  end

  private
  def user_params params.require(:user).permit(:user_name,:email,:password,:password_confirmation)
    end
end
```
存在したら、ユーザ情報を返し、「存在しなければそんなのいねえよ！」ってことでエラーを吐くはず。
###Let's Do It!!
ってことでPostman上で存在しないユーザ(ID:20)に対し、アクションを要求する。
error！って返って来るはず♪
<img width="569" alt="724920E8-E512-415C-BC37-CF18099F38E6_1_105_c.jpeg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387365/50d858f0-6b53-2f54-7164-113c3d47c678.jpeg">
ん？***404***？？？error!じゃなくて？？
404までは期待どうり。だけどそのあとの処理が拾われていない？？
rescueとは・・・
###Research Solution 
大人しく、[チャレキャラ](https://challecara.org/)のメンターさんに質問しました。
その中でも、日頃お世話になっているアルバイト先のBig Bossに助けてもらいました💦
###Solution
```user_controller.rb
 class UsersController < ApplicationController

  def show
    @user = User.find(params[:id])
    render json: { status: 'success', data: @user }
  rescue ActiveRecord::RecordNotFound
    render json: { status: 'error!', data: '' }, status: :not_found
  end

  private
  def user_params params.require(:user).permit(:user_name,:email,:password,:password_confirmation)
   end
end
```

`render json: { status: 'error!', data: @user.errors }`の部分を
` render json: { status: 'error!', data: '' }, status: :not_found`に変更

<img width="567" alt="724920E8-E512-415C-BC37-CF18099F38E6_1_105_c.jpeg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387365/3771c511-77a5-1737-fb3b-91c5c88456f8.jpeg">
できた！！！
###Why??
理由としては、**userがnillなのに、errorメソッドを呼んで、errorを返してしまうってこと***らしい
確かに`nill`ってオブジェクトでもないわけだからそれにメソッド呼んでも処理ができるはずはない。
だもんで、戻り値にエラーを吐かないようにしてかつ、statusを返すようにしたわけですね！
###+ α
そもそも、`rescue`は多用しないほうがいいという知見をいただきました。
自分も使い慣れてないし、当分はif-else分岐で行こうかと思い、書き直してみよう！

```user_controller.rb
 class UsersController < ApplicationController

  def show
    @user = User.find_by(id:"")
    render json: { status: 'success', data: @user }
  if ActiveRecord::RecordNotFound
    render json: { status: 'error!', data: 'user_params' }, status: :not_found
  end

  private
  def user_params params.require(:user).permit(:user_name,:email,:password,:password_confirmation)
   end
end
```

こんな感じ？
コメントで教えてもらうと助かります
###Summary
チャレキャラのメンターさん達みたいになりたい
SpringBoot 2.1 TomcatとHikariCP設定値を確認するテストクラス

デフォルトの設定値の確認をしたかったので、テストクラスを実行して確認する方法を調べました。


```ConfigInspection.java
package com.example.demo.config;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.web.ServerProperties;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.ApplicationContext;
import org.springframework.test.context.junit4.SpringRunner;

import com.zaxxer.hikari.HikariConfig;

@RunWith(SpringRunner.class)
@SpringBootTest
public class ConfigInspection {

    private Logger log = LoggerFactory.getLogger(getClass());

    @Autowired
    private ApplicationContext ctx;

    @Test
    public void test() throws Exception {
        ServerProperties serverProperties = ctx.getBean(ServerProperties.class);

        ServerProperties.Tomcat tomcat = serverProperties.getTomcat();

        log.debug("tomcat.maxThreads: {}", tomcat.getMaxThreads());
        log.debug("tomcat.maxConnections: {}", tomcat.getMaxConnections());
        log.debug("tomcat.acceptCount: {}", tomcat.getAcceptCount());

        ServerProperties.Servlet servlet = serverProperties.getServlet();

        log.debug("servlet.contextPath: {}", servlet.getContextPath());

        HikariConfig hikariConfig = ctx.getBean(HikariConfig.class);

        log.debug("dataSource: {}", hikariConfig.getDataSource());
        log.debug("dataSourceProperties: {}", hikariConfig.getDataSourceProperties());
        log.debug("jdbcUrl: {}", hikariConfig.getJdbcUrl());
        log.debug("maximumPoolSize: {}", hikariConfig.getMaximumPoolSize());
    }
}

```
ダブルクオートを使う必要がある場合  


ダブルクオートを使う必要がある場合

```
# htmlタグの属性指定
<a href="hogehogegohe">aaa</a>

# シングルクオートを表示したいとき
$text = "わたしは'" . $name . "'です";

# テキストに変数を内包させるばあい
$text = "わたしは$nameです";
```