OmniAICreator/Qiita-1.07M huggingface dataset:
[Unity] 物理的に正しい2Dアクションを作る


ゲームではよくプレイヤーがピョンピョン飛び跳ねていますが、これは物理的にどうなんだろうと疑問が湧きます。ぼくが全力でジャンプしても50cmぐらいしか飛びませんからね。
これは単純に考えれば、ミニチュアの世界であれば、ああいった跳躍力も可能かもしれません。じゃあ、

**どのぐらいミニチュアならあのジャンプが成立するのか？**

これが今回のテーマです。

#原理

たしかに虫とかすごい跳びますね。なぜスケールが小さいと跳躍力が増すのか。これは、

* 質量は尺の３乗に比例する
* 筋力は尺の２乗に比例する

という事実から説明できます。すなわち、

質量に関しては
```小さくなっても密度は変わらないだろう（分子間距離が縮むわけではないだろう）から、密度が一定ならば質量は体積に比例する。よって３乗に比例する```

筋力に関しては
```筋繊維の縮む力は断面積に比例する。よって２乗に比例する```

という理屈から仮定できるわけです。
つまり小さくなれば質量は３乗の勢いで減少し、筋力は２乗の勢いで減少する。筋力も減少するけど質量が減少するほうがずっと勢いがあるので、相対的に筋力のほうが大きくなり、その結果ジャンプ力も高まるよね、というわけです。

#計算

![Kobito.bnXQiG.png](https://qiita-image-store.s3.amazonaws.com/0/90046/77d42456-250e-e769-adac-3a06bc0d421b.png "Kobito.bnXQiG.png")


$身長をT$
$ジャンプの最高到達点をH$

とします。図のように、普通の成人男性のジャンプ力はこのHぐらいでしょうね。
そして

$筋力をF$
$体重をM$
$縮尺率をs$

として、最終的にはこのsを求めます。
sで縮小後の身長、筋力、体重をそれぞれ T', F', M' とすると

$ T'=sT \ （縮尺率に比例）$
$ F'=s^2F \ （縮尺率の２乗に比例）$
$ M'=s^3M \ （縮尺率の３乗に比例）$

こうなります。なお縮小なので、sは1以下の値になります（縮尺率じゃなく拡大率といったほうが正確ですがややこしいので縮尺率で通します）。
次に
$ジャンプの初速をv$
$重力加速度をg$
とすると、物理の公式により

$v-gt=0$
$H=vt-\frac{1}{2}gt^2$

これを解いて

$ H=\frac{v^2}{2g} $

となります。

運動方程式

$ F=m\frac{\Delta v}{\Delta t} $

から

$ F\Delta t = m \Delta v = mv - mv_{0} $

$mv_{0}$は初期速度でジャンプ前はゼロとします。よって

$ mv = F\Delta t $
$ v = \frac{F}{m}\Delta t $

ここで、縮小後の速度を $ v' $ とすると、上の関係を用いて

$ v' = \frac{F'}{m'} \Delta t $

$ F'=s^2F $
$ m'=s^3m $

より

$ v' = \frac{s^2F}{s^3m} \Delta t = \frac{1}{s} \frac{F}{m}\Delta t = \frac{1}{s} v $

これで縮小後の速度が出ました。縮小後の到達高度 H' は

$ H'=\frac{v'^2}{2g} = \frac{1}{2g}(\frac{v}{s})^2 = \frac{v^2}{2gs^2} $

こうなります。

縮小後の到達高度H'が身長のP倍になるとすれば、

$ H'=PT' $

$ \frac{v^2}{2gs^2}=PsT $
$ s^3=\frac{v^2}{2gPT} $

$v^2=sgH $より

$ s^3=\frac{2gH}{2gPT} = \frac{H}{PT} = \frac{H}{T} \frac{1}{P} $

はい。ここで、そもそものHとTの関係を仮定しましょう。成人男性は約60cmのジャンプ力があるそうです。身長を170cmとすると、身長とジャンプ高度の関係は、ざっくり $\frac{H}{T}=\frac{1}{3} $ってとこでしょう。

よって

$ s^3=\frac{H}{T} \frac{1}{P}=\frac{1}{3P} $

通常のピョンピョン跳ぶゲームは、身長の４倍のジャンプをしているとすれば、$P=4$より

$ s^3=\frac{1}{3 \times 4} = \frac{1}{12} $

$ s= \sqrt[3]{\frac{1}{12}} = 0.436790232368149 $

なんと。身長の４倍ものジャンプ力を得るために、たった 43% の縮小で済むという結果が出てしまいました。
果たしてこれは正しいのだろうか！？

#検証
縮小前の人体のスペックを、平均的な日本人を想定して次のように定めます。

* 身長：1.7m
* 体重：60kg
* ジャンプ最高到達点：0.567m (身長の1/3）

この到達点に達するために必要な初速は
 $v^2=2gH $より $v=3.332666599986663 m/s $

この初速のために必要な力積は
 $F \Delta t = mv = 60 * 3.332666599986663 = 199.9599959991998 kgm/s$
 
これを適用してシミュレーションしてみます。スケールを合わせ、Rigidbody2Dに質量60を設定し、AddForceのForceMode.Impulseに上記の力積、199.96を突っ込みます。

 ![jump00.gif](https://qiita-image-store.s3.amazonaws.com/0/90046/0c1923b8-73bd-ce5a-8aac-a7904cf3f479.gif "jump00.gif")

 
身長の1/3ぐらいジャンプしてますね。よしよし。

ここからが本番。縮小後の人体のスペックを、先ほど算出した $s=0.436790232368149$ を使用して以下のように定めます。

* 身長：$1.7*s=0.742543395025853m$
* 体重：$60*s^3=5kg$
* 力積：$199.9599959991998 * s^2 = 38.14951 kgm/s$

縮小前の状態から、体重はsの３乗、力積はsの２乗を掛けます。
これらの値を突っ込んで、さあ、どうなるか！

![jump01.gif](https://qiita-image-store.s3.amazonaws.com/0/90046/583b8811-9b32-dcc5-3565-da9c0c2242b6.gif "jump01.gif")


ちっこい方が縮小人間です。見事に！きっちり身長の４倍のジャンプ力を得ることができました。計算は正しかった！

#というわけで

人類は43%の縮小で身長の４倍までジャンプできることがわかりました。計算と実験がピッタリ合うと楽しいな！めでたしめでたし。
#0: マイクロサービスの構築プロセス

この記事はMicroservices Advent Calendarの16日目の記事です。前回は@yasuabe2613さんのマイクロサービスのパターンの話でした。

## はじめに

マイクロサービス・アーキテクチャの話は多くありますが、実際にマイクロサービスを新たに設計・開発するとき、どのような手順を踏むか、と言ったことを扱った文献はそれほど多くない印象です。そこで、自身の経験を元に、マイクロサービスの設計をどのようにしているか、ポイントをかいつまんで説明したいと思います。

第一回はまず全体像としてのマイクロサービスの構築プロセスに触れます。第二回がサービスの責務の話、第三回がインターフェイスを考える話になる予定です。

## 本題

> すべてのソフトウェア構築には、本質的作業として抽象的なソフトウェア実体を構成する複雑な概念構造体を作り上げること、および、偶有的作業としてそうした抽象的実在をプログラミング言語で表現し、それをメモリスペースとスピードの制約内で機械言語に写像することが含まれている。
> - 銀の弾などない— ソフトウェアエンジニアリングの本質と偶有的事項

ソフトウェア構築の諸原則に従えば、おおよそ以下のようなフローになると思います。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/33539/3e4bf7e1-57d1-7fd0-9dc8-a9e968faf6ef.png)

左側が、他のマイクロサービスから見た抽象としてのマイクロサービスです。マイクロサービスのモデリング、モデル化されたマイクロサービスなど色々な言い方がありますが、同義です。右側が、実際に動作するコードやデータベース・スキーマを含んだ、具体としてのマイクロサービスです。上段がマイクロサービスの全体に関わる設計で、下段が個別のインターフェースに関わる設計です。

矢印は各プロセスが与える影響を表わしています。最初は実線だけを見る方が理解しやすいでしょう。つまり、「サービスの責務を定義」→「インターフェースを定義」、「サービスの責務を定義」→「サービス内部の基本設計」などです（ここで最初に考える「サービス内部の基本設計」は、どういったフレームワークやデータストレージを使うのかというような、「インターフェースの実装」や「サービスの責務」の実現可能性に関わる大まかな設計です）。

しかし、そんなに綺麗に行くでしょうか？実際には、欲しいインターフェースを定義してみてから、欲しいマイクロサービスの全体像がより鮮明に見える、あるいはインターフェースを実装する過程で、より適切なインターフェースの定義にたどり着く、と言ったことはあるはずです。これをフィードバックと呼び、破線で書いています。

フィードバック、と言っているのは、例えば **"インターフェース定義の集合"すなわち"マイクロサービスの責務"ではない** からです。下位のところで遭遇した問題はあくまで上位のことを再考する必要があるかもしれないというシグナルであって、上位のものから下位のものがより具体的に導かれているという関係は維持すべきです。

なおここでは特にスタンスとして、トップダウンな開発を推奨しているわけでも、ボトムアップな開発を推奨しているわけでもありません。それは使い分ければ良いでしょう。ただ、良いソフトウェアを作るのであれば、 **全体の設計と個別の設計・抽象的な事柄と具体的な事柄はそれぞれは分けて考えよう** ということと **分けたものの間を必要に応じて行き来しよう** ということを言っています。

## 他のマイクロサービスとの相互作用

上記の話は、作ろうとしている単一のマイクロサービス上での相互作用の話でしたが、実は「サービスの責務」「インターフェース」のそれぞれのレベルで、マイクロサービス間での相互作用があります。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/33539/7e3d439c-946b-cc31-52c1-cd4a07a3b167.png)

「サービスの責務」の場合、各マイクロサービスは自律していて上位・下位という関係はないのが通常なので、対等なフィードバックという形になると思います。「インターフェースの定義」の場合、これもマイクロサービスの自律性から、インターフェースを提供する側からの影響は直接的に、インターフェースを利用する側からの影響はフィードバックという形で現れます。

## 次回

次回は、マイクロサービスの責務を定義する話です。具体的な道具として、デザイン・ドキュメントを紹介します。
React NativeをXcode 10にするとビルドできない問題

Xcode 10が出てきてから、少し立ちますが、React Nativeはまだ正式に対応が終わっていないらしく、以前から開発しているアプリがビルドできない可能性があります。

## glogの手動ビルド

React Nativeが内部で使っているglogがうまくビルドできない場合があります。

[facebook/react-native #20774](https://github.com/facebook/react-native/issues/20774)より

```bash
cd node_modules/react-native/scripts/
./ios-install-third-party.sh
cd ../third-party/glog-0.3.4/
../../scripts/ios-configure-glog.sh
```

これで`src/`以下に`config.h`ができれば、:ok:です。

### 自動化

glogのビルドは`node_modules`ディレクトリを削除したときなどはいちいち実行しないといけないので、以下のnpmモジュールを組み込んで、`packge.json`の`postinstall`などで実行することをオススメします。

```bash
yarn add rhdeck/react-native-fix-xcode-10
```

```json:package.json
    :
  "scripts": {
      :
    "postinstall": "react-native fix-xcode"
  },
    :
```

#### :warning: 手動ビルドをしておくことが必要
このモジュール、ビルド時に生成されるディレクトリがすでに存在する前提で組まれているので、一度アプリのビルドを実行しておくことがある前提になっています（当然エラーはします）。

```bash
react-native run-ios
```
で手動実行しておくか、Xcodeで一度ビルドを実行しておきましょう。


## ビルドシステムの変更によるエラー

[Xcode 10からビルドシステムが新しく](https://developer.apple.com/documentation/xcode_release_notes/xcode_10_release_notes/build_system_release_notes_for_xcode_10)なっており、既存のReact Nativeだとまだ対応できていない部分があります。

React Nativeも[facebook/react-native #19573](https://github.com/facebook/react-native/issues/19573)で対応中ですが、正式にはまだ先になりそうです（2018年12月15日現在）。

とりあえず、古いビルドシステムに設定を変更すれば通ります。
具体的には[:arrow_up: と同じIssueのコメント](https://github.com/facebook/react-native/issues/19573#issue-329461636) にあるように、具体的には[:arrow_up: と同じIssueのコメント](

1. Xcode 10を起動する。
1. `File` :arrow_right: `Workspace Settings` を選びます。
1. `Build System`を`Legacy Build System`に変更する。

![react_native_xcode_10_legacy_build.png](https://qiita-image-store.s3.amazonaws.com/0/29305/316ba850-3414-d908-9eb1-4b77dbeed24e.png)

この際、出力される `ios/プロジェクト名.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings` をソースコード管理にチェックインするのをお忘れなく :exclamation:  
以下のようなファイルです。

```xml:WorkspaceSettings.xcsettings
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>BuildSystemType</key>
    <string>Original</string>
</dict>
</plist>
```

なお、どうしても手動でやりたい場合は自分が直面したビルドシステムによるエラーは以下の`libfishhook.a` に関するものでしたので、その対応方法だけ記載しておきます。

[facebook/react-native #19569](https://github.com/facebook/react-native/issues/19569)より

1. RCTWebSocketのfishhookターゲットをビルド。
1. `~/Library/Developer/Xcode/DerivedData/プロジェクト名-ランダムな文字列/Build/Products/Debug-iphonesimulator/`以下の `libfishhook.a` ファイルを `node_modules/react-native/Libraries/Websocket` にコピーする。
GAE/GoでTaskQueueを使ったAPIを実装する

[以前書いた記事](https://qiita.com/kecy/items/449414915344e8bc0bcd)で「Google App Engineではレスポンスだけ速攻で返して別プロセスで重い処理を実行する、みたいなAPIは作れない」ってショボンとしていたら、「TaskQueue使えばできる」という託宣をいただき、今回はそれを実際に試してみました。

ソースコードはこちら

[kecbigmt/gae-api-sample](https://github.com/kecbigmt/gae-api-sample)

# TaskQueueなしで実装（NGパターン）

以前の実装はこんな感じです。
これだと、goroutine内でcontextを使おうとしたときに`invalid security ticket (context expired)`というエラーが発生してしまいました。

```go
package main

import (
  "fmt"
  "net/http"
  "encoding/json"

  "google.golang.org/appengine"
  "google.golang.org/appengine/log"
  "google.golang.org/appengine/urlfetch"

  "google.golang.org/appengine/taskqueue"
)

const url = "https://www.google.com/"

type Response struct {
  Status string `json:"status"`
  Message string `json:"message"`
}

func main() {
  http.HandleFunc("/back", helloBackground)
  appengine.Main()
}

// NGパターン
func helloBackground(w http.ResponseWriter, r *http.Request) {
  // URLにリクエストして返ってきたステータスをログに残すgoroutine
  go func() {
    ctx := appengine.NewContext(r) // App Engineのcontext作成
    client := urlfetch.Client(ctx) // contextを使ってhttp.Clientを作成
    resp, err := client.Get(url)
    if err != nil {
      log.Errorf(ctx, "TEST: helloBackground: %s", err)
      return
    }
    log.Infof(ctx, "'%s' returns %s", url, resp.Status)
  }()

  // レスポンス
  json.NewEncoder(w).Encode(Response{
    Status: "ok",
    Message: "processing in background.",
  })
}
```

# TaskQueueありで実装

それをTaskQueueを使って直すとこうなります。

```go
package main

import (
  "fmt"
  "net/http"
  "encoding/json"

  "google.golang.org/appengine"
  "google.golang.org/appengine/log"
  "google.golang.org/appengine/urlfetch"

  "google.golang.org/appengine/taskqueue"
)

const url = "https://www.google.com/"

type Response struct {
  Status string `json:"status"`
  Message string `json:"message"`
}

func main() {
  http.HandleFunc("/back", helloBackground)
  http.HandleFunc("/back/worker", helloBackgroundWorker)
  appengine.Main()
}

// レスポンスだけ速攻で返して時間のかかる処理はTask Queueに渡すAPI（10分 or 24時間でタイムアウト）
func helloBackground(w http.ResponseWriter, r *http.Request) {
  ctx := appengine.NewContext(r) // App Engineのcontext作成

  // タスクをTaskQueueに投げる
  t := taskqueue.NewPOSTTask("/back/worker", map[string][]string{})
  if _, err := taskqueue.Add(ctx, t, ""); err != nil {
    http.Error(w, "internal server error", http.StatusInternalServerError)
    return
  }

  // レスポンス
  json.NewEncoder(w).Encode(Response{
    Status: "ok",
    Message: "processing in background.",
  })
}

// URLにリクエストして返ってきたステータスをログに残すworker
func helloBackgroundWorker(w http.ResponseWriter, r *http.Request) {
  ctx := appengine.NewContext(r) // App Engineのcontext作成
  client := urlfetch.Client(ctx) // contextを使ってhttp.Clientを作成
  resp, err := client.Get(url)
  if err != nil {
    log.Errorf(ctx, "TEST: helloBackground: %s", err)
    return
  }
  log.Infof(ctx, "'%s' returns %s", url, resp.Status)

  return
}
```

taskqueue.NewPOSTTaskの第二引数のmapにパラメータを渡すと、TaskQueueにパラメータを渡すことができます。

そのあたりのやり方はこちらの記事が参考になります。

[GAE/Go TaskQueue その１~Pushキュー~ - The Round](http://knightso.hateblo.jp/entry/2014/06/10/080720)
(自分用メモ) プログラミングの勉強法

# メイン: LeetCode
* https://leetcode.com/problemset/all/
* 問題数 900以上 (Problem set. 他にもいろんな問題があるよう)
* Google, Amazon, Appleなどの大手企業で出されたという問題があるらしい
* さくっと解ける (ものもある)
* 解けない時は解答を見ることもできる問題もある
* 自分の好きな言語で解くことができる
* Web上のEditorで完結する
* やっている途中でもSubmitしとけばその続きから行える
* 全部英語

# いろいろな学習用サイト
* 言語の習得やアルゴリズムの学習に最適 オンラインジャッジサイト一覧
    * https://qiita.com/shibacho/items/20f6eee42083c620b556
    * こちらを参考にして"atCoder, Checkio, HackerRank"あたりを使ってみたが, 定着しなかった. Twitterや勉強会で, LeetCodeを使っているという人たちを見たので使ってみたところ定着した

# 所感
* 学習用サイトはたくさんある
* 自分のスタイルにあった, 学習を継続できるサイトを選ぶ必要がある
Amazon Connectで社内のコールセンターを構築するための調査


# 要求機能一覧
- 発信
- 同時複数着信
- 保留、取次
- 応答フローの切り替え
- 複数番号の取り扱い(番号ごとに受電するユーザを登録できる、重複ok)
- trello連携
- 電話番号に紐ついたアカウント情報の追加編集
- PickGo情報取得
- 音声ガイダンス内容の切り替え
- ユーザ管理/権限管理

# 自前実装する必要がありそうな箇所
- PickGo情報表示
- trello連携
- 通話にひもづくメモを残す
- エージェント用の通話履歴カスタマイズ
- 顧客にひもづくメモを残す
- 現在のキューにたまっている通話を表示する
- 同時着信時に任意のユーザの電話を取れるようにする

# 今回の作業内容
- S3にhtmlファイルを配置し、cloudfront経由でアクセス
- htmlファイル内にccpを設置
- 通話テスト

# 今回の作業で詰まったところ
## 自前のページでccp埋め込んでみたけど表示されない(X-Frame-Options to sameorigin error)
- ホワイトリストへの登録が必要

	```
	Amazon Connect > インスタンス名 > アプリケーション統合
	```

- https通信にする必要があった？

	もともとS3でwebhostingでテストしようと思っていたが、調べてみると、chromeの制限で動かない可能性があるとのことで、急遽cloudfront経由に変更

## 一度ログアウトすると自前のページでccpが表示されない(X-Frame-Options to sameorigin error)
- Amazon Connectに別途ログインすると正常に表示される

	もっといい解決方法がないかは調査する必要あり。

# 残課題
- 同時着信時に任意のユーザの電話を取れるのか → 一つのキューで対応できるのだろうか...今の所実装があまりイメージできない。
- ログアウトした後、ログイン画面を自然に表示させるためにどうすればいいか

# 結論
lambdaでデータ連携とかはまだ実装していないけど、残っている課題がクリアできれば普通にコールセンターシステムを作れそう。思っていた以上にフロント部分の作り込みが必要そうだけど、バックエンドのキュー処理とかその辺りを実装しなくていい分、まだ希望が見えた。
メトリクスとかも用意されているので、AmazonConnectベースで残課題の解決ができないかどうか考えてみることにする。
リリースしてみて電話繋がらないとかなると怖いので、バックエンド部分の構築を限りなく減らしてくれるAmazonConnect素敵。
ただ、cloudfrontの作成や再起動が遅いのはどうにかして欲しい。
Ruby10進数を2進数に変化

```:ruby
puts gets.to_i.to_s(2)
=begin
7
が
111
=end
```

# 参考

参考にしたWebサイトや技術書などを列挙する

- [参Rubyで2進数と10進数の変換 - おもしろwebサービス開発日記](https://blog.willnet.in/entry/2012/01/30/112724)

# 次にやること

SQLをやる
Looker を検証してみた

 この記事は[Speee Advent Calendar 2018](https://qiita.com/advent-calendar/2018/speee)の 15 日目の記事です。

今日は [Looker](https://looker.com/) についてです。

私の部署では日常的に BigQuery を用いたデータ分析を行っており、
もっと簡単にデータ分析を行えるツールを探している一環で Looker と出会い、検証してみて他の BI ツールと比べて良かった点を紹介したいと思います。

## Looker って？

![looker_logo_meta_v0003.png](https://qiita-image-store.s3.amazonaws.com/0/480/6dba8f99-dd57-1ddf-cc4f-d6a50c7be2c4.png)

一言でいうとデータ探索プラットフォームです。
データベースに存在しているデータを SQL を使うことなく、データの集計・可視化・レポーティングなどを行ってくれます。

国内では Mercari や Quipper などで導入実績があります。

- [プロダクトのリリース前から新ダッシュボード「Looker」の導入に踏み切ったわけ - Mercari Engineering Blog](https://tech.mercari.com/entry/2018/08/22/155059)
- [エンジニアを魅了する次世代 BI ツール『Looker』を Quipper が導入した理由（わけ） - Quipper Product Team Blog](https://quipper.hatenablog.com/entry/2018/06/04/080000)

## Looker の良かった点
さて本題の Looker を検証してみてよかったところをいくつかご紹介します。

- 集計・可視化・定期レポーティングまでのフローがとても楽
- ダッシュボードも含めてコード化ができ、Git管理が可能
- 既存のクエリからの分析・可視化が可能
- 利用状況が可視化されている
- 柔軟な権限設定機能により複雑な権限設定が可能
- API提供によるプログラマティックな操作が可能

## 集計・可視化・定期レポーティングまでのフローがとても楽
分析をしていてよくあることとして、分析で作ったロジックや可視化設定を今後追加されるデータにも適用して継続的に監視したい、ということがあります。
この要件に対して Looker はスケジュール実行機能を備えているため、定期的なクエリ実行からレポーティングまでを数クリックで実現することができます。
レポーティング先として Slack も利用できるため、日次や週次の分析結果を簡単にレポーティングすることが可能です。
また、レポーティング先に Webhook の設定も可能なので、分析結果を自動的にアプリケーションに取り込むことも可能です。

参考リンク:

- [Scheduling Data Deliveries](https://docs.looker.com/sharing-and-publishing/scheduling-and-sharing/scheduling)

## ダッシュボードも含めてコード化ができ、Git 管理が可能
Looker は LookML という YAML に似た設定言語を持っていて、データベースのスキーマ情報など分析するためのモデルを定義することで、SQL を使わずデータベースのデータを扱うことができるのですが、このコードによる設定がダッシュボードの設定としても残すことができます。
また、LookML は Git で世代管理されているため、以前の設定を復元することも可能にしています。
このため、ダッシュボードの変更を管理したり、意図しない変更や削除に対しても対策することができます。

参考リンク:

- [LookML Dashboard Overview](https://docs.looker.com/reference/lookml-dashboard-overview)

## 既存のクエリからの分析・可視化が可能
Looker では既存のクエリを使った集計結果を可視化することも可能です。
`SQL Runner` として接続しているデータベースに直接クエリを実行することが可能で、この結果を　LookML　化して分析するためのモデルとして定義することができます。
このため、Looker を導入する前に作成していた分析用クエリをそのまま利用することができます。

参考リンク:

- [Using SQL Runner](https://docs.looker.com/data-modeling/learning-lookml/sql-runner)

## 利用状況が可視化されている
Looker には管理者向け機能として利用状況を可視化する機能があります。
この機能を用いることで、使用されていないユーザーやプロジェクト、さらに、使用されていダッシュボードなどもすぐに判別可能です。
運用が長く続いた際の、リソースの棚卸しも楽に行うことができます。

参考リンク:

- [Usage](https://docs.looker.com/admin-options/server/usage)

## 柔軟な権限設定機能により複雑な権限設定が可能
企業でデータを扱う際に課題となるひとつに、データのアクセス制限があります。
利用者の部署、役職にあったアクセス権を付与することが必要であり、場合によってはデータベースの設計を見直さないといけないこともあります。

Looker ではユーザー属性から適切にアクセスできる範囲を限定できる機能が豊富に用意されており、複雑な権限要件に対応することが可能です。

参考リンク:

- [Access Control and Permission Management](https://docs.looker.com/admin-options/tutorials/permissions)

## API 提供によるプログラマティックな操作が可能
Looker には Restful な API が提供されており、これにより Looker 操作の自動化が行えるようになります。
例えば、別 DB で管理しているユーザー属性を Looker 内部のユーザーリソースに反映することも自動化することもできますし、独自の管理画面の作成にも利用することができたりします。

参考リンク:

- [Getting Started with the Looker API](https://docs.looker.com/reference/api-and-integration/api-getting-started)
- [Looker API Reference](https://docs.looker.com/reference/api-and-integration/api-reference)


## まとめ
Looker ではデータ分析を行う上で便利な機能を提供するツールにとどまらず、アクセス制限やツール自身の運用に対しても豊富な機能を備えており、データ探索プラットフォームといっても過言ではないと思います。
もし、今回紹介したものが現在課題になっていた場合、Looker の利用を検討してみてはどうでしょうか。
More Effective C++

#諸言
　学習履歴全体のリンク
　https://qiita.com/shigural/private/444b991293e5ab1b40af
#本文
##More Effective C++（第3版）
###基本
####1.ポインタと参照の違い
1.ポインタはnullを指しうるが、参照は必ずオブジェクトを指す
2.ポインタは再代入の可能性があるが、参照は初期化された時のオブジェクトを常に指す
一般に、なにか指し示すものがあることをわかっている場合、他のものは指し示したくない場合には参照を、それ以外にはポインタを使うべきである

####2.C++スタイルのキャストを愛用する（Effective C++で既出）
C型よりC++型スタイルのキャストを利用するべきである

####3.配列をポリモルフィズム的に扱ってはいけない
具象クラスを別の具象クラスから派生すると配列のサイズが不定になる可能性があるので、してはならない

####4.根拠のない省略時コンストラクタを避ける（プログラミング言語C++で既出）
不要なばあいには自動的に作られるコンストラクタなどは削除するべきである

###演算子
####5.ユーザ定義の変換関数に気をつけよう
不要ならば変数を暗黙に型変換するような関数を作らないほうが良い

####6.インクリメントとデクリメントの演算子で前置形式と後置形式を区別する
++aはaをインクリメントしてから値を返し、a++はその逆である。
特に理由がない限りは高速である前置インクリメントを利用するべきであり、後置インクリメントを自分で実装するには前置インクリメントを利用して実装するべきである

####7.&&, ||, あるいは,をオーバーロードしない
&&, ||, , はいずれもC++に組み込みとしての定義があり、プログラマはその動作を再現できる保証がないのでオーバーロードするべきでない

####8.newとdeleteの別の意味を理解する
newとdeleteをカスタマイズするとき、「どのようにするか」は変更できるが「何をするか」は言語で定められている

###例外
####9.リソースリークを防ぐためにデストラクタを使う（Effective C++で既出）
リソース漏れをふせぐためにデストラクタでdeleteを行う

####10.コンストラクタでのリソースリークを防ぐ（Effective C++で既出）
スマートポインタでリソース管理するとリソース漏れのリスクがなくなる

####11.デストラクタから発生した例外を抑える（Effective C++で既出）
デストラクタで例外を投げるとリソース漏れを呼び得るので、例外を投げてはならない

####12.例外発生の仕方と引数渡しや仮想関数呼び出しの違いを理解する
■自明なため簡略化
例外処理は関数呼び出しと大きく異なる

####13.参照渡しで例外を受け取る
■難解であるため略

####14.例外仕様を賢く用いる
■難解であるため略

####15.例外処理のコストを理解する
例外が発生したときには発生しなかったときの5～10%の処理時間増加が起こる。
また、例外を含むコードは含まないコードより5～10%のプログラム容量増加が起こる


###効率
####16.80-20規則を覚えておこう
プログラムの処理コストは全体の20%が80%の割合を占める。
よって、プログラムをプロファイルして高速化することで効果は劇的であり、通常の部分をプログラミングするときにはほとんど効率について考える必要がない

####17.遅延評価の仕様を検討する
得られた結果の一部だけが必要な場合には遅延評価が効率的である。（その実装方法は載っていない）

遅延評価の効率化としていくつかの例がある
#####参照回数計測
コピーコンストラクタにおいて、ポインタを共有して参照を数えておく方法。
shared_ptrと同じ実装
#####読み出しと書き込みを区別する
項目30で述べるプロキシークラスにより、読み込みと書き出しのどちらが使われるか確定してからコピーを行う方法がある
#####遅延フェッチ
■難解であるため略
#####式の遅延評価
例えば行列の計算で、(2,4)の数値を読みたいとすれば他の部分は計算する必要がない
必要な箇所が決まってからそこだけを計算するのが遅延評価である

####18.予想される計算のコストを償却する
遅延評価と逆に、結果がほとんど必ず必要な場合には過剰積極評価を行う

具体的にはキャッスの実装や余分な配列確保が挙げられる

####19.テンポラリオブジェクトの由来を理解しよう
Pixi.js in Angular

# Pixi.jsをAngular7で動かす

### pixi.jsのインストール

```
$ npm install --save pixi.js
```

### pixi.jsの型ファイルのインストール

```
npm install --save @types/pixi.js
```

### `angular.json`の修正
build時にpixi.jsを含めるように`scripts`の配列にPATHを追記する

```angular.json
{
  ...
  "projects": {
    "angular7-metronome2": {
      ...
      "architect": {
        "build": {
            "scripts": [
              "node_modules/pixi.js/dist/pixi.min.js"
            ]
```

## Pixi.jsを使う

Pixiを使うコンポネートを作成して、tsファイルに以下のように書き込む

```
import { Component, OnInit } from '@angular/core';

declare var PIXI: any;

@Component({
  ...
})
export class PcComponent implements OnInit {
  public app: any;

  constructor() {
      this.app = new PIXI.Application({
          width: 800,
          height: 600
      });
  }

  ngOnInit() {
  }

}
```
俺がよく忘れる覚えておきたいCSS3

#レスポンシブデザインの救世主
- box-sizing: border-box;

これを使うことにより、width: ~%;という記述を使いたいときに
marginやpaddingの影響によりデザインが崩れることを防ぐことができる。

border-boxはheightやwidthが、marginやpaddingを含めた値となる。

- min-height: 数値px;

これを使うことにより、例えば横に並べたコンテンツごとの最小の高さをそろえることができる。
あまりコンテンツ内容が変更しないときに、一番長い高さのコンテンツに合わせるといいだろう。

- overflow: hidden;

ボックスの範囲内に内容が収まらなかった場合の表示方法
visibleが初期値
hiddenだと、はみ出た内容は表示されずスクロールバーもでない。

no-displayだとdisplay: none;のようにボックス全体が削除され
no-contentだとvisibility: hidden;のようにボックス全体が非表示

#不都合防止のためのCSS


```test.css
input:-webkit-autofill {
    -webkit-box-shadow: 0 0 0px 1000px white inset;
}
```

Chromeでinputにオートフィルされているときの問題。。
なんでや！！なんで背景が勝手に黄色になるんや！！！
って現象が起きる。

それを解決してくれるのがこのCSS！！
丸暗記で大丈夫だと思っている。こまったら頭の片隅にCSSで解決できるとだけ覚えておこう。
はじめてのCron設定

## 概要
いままでcronに触れたことがなかったので、実験的にさわってみようというのがこの記事の主旨です。
内容は初心者向けです。

## 実行環境
- MacOs High Sierra
- ターミナル

## そもそも、Cronとは？
- 設定内容に応じて、定期的にジョブを実行してくれるもの
- crontabというコマンドを用いて①*スケジュール*と②*コマンド*を設定できる

※例えば、「毎週月曜〜金曜日の午前３時から４時の間に〇〇.shを実行してください」というようなスケジュールを組むことができる。

## やったこと
1. シェルスクリプトで超簡単な処理を記述
2. crontabでスケジュールを設定
3. 実行結果を確認

### hoge.shに簡単な処理を記述する

はじめに、簡単な処理をかきます

```terminal:ターミナル
// 編集画面を開く
$ vim hoge.sh 

//　現在日時をテキストファイルにアウトプットする処理をかく
date >> hogelog.txt
~
~
~
"hoge.sh" [New File]

// hoge.shの実行権限を与える
$ chmod 755 hoge.sh

// ついでに、作成したファイルの絶対パスを確認しておく
$ ls -ld $PWD/hoge.sh
-rwxr-xr-x  1 manabee  staff  20 Dec 14 10:40 /Users/manabee/hoge.sh
```

### crontabでスケジュール設定する

今回は、"1分間隔"、"毎時"、"毎月"、"土・日曜日"に実行するようにしてみます

設定方法の詳しい説明はこちらを参照しましょう
https://eng-entrance.com/linux-command-crontab

```terminal:ターミナル
// 設定画面を開く
$ crontab -e 

// 以下のように設定(スケジュール　＋　実行するコマンドのパス)
*/1 * * * 0,6 /Users/manabee/hoge.sh
~
~
~
```

※ちなみに土曜日、日曜日で設定する際　にはじめ"6,7"で試したのですが、うまくいきませんでした
### 実行状況を確認する

```terminal:ターミナル
// 設定しているcronを確認
$ crontab -l 
*/1 * * * 0,6 /Users/manabee/hoge.sh

// 出力されたファイルを確認
$ cat hoge.txt

// ↓内容↓
Sat Dec 14 10:40:16 JST 2018
Sat Dec 14 10:41:16 JST 2018
Sat Dec 14 10:42:16 JST 2018

```
設定した処理が定期実行されていることが確認できました:relaxed:

設定したcronを削除、停止する

```terminal:ターミナル
// 削除する（設定したものが全て消えてしまうので注意）
$ crontab -r

// 停止するだけなら、#でコメントアウトすればとまる
$ crontab -e 
# */1 * * * 0,6 /Users/manabee/hoge.sh
~
~
```
## 感想

ターミナルでコマンドを使うことに抵抗？馴れていなかったため、はじめは難しいものかと思っていましたが、意外ととっかかりやすい仕組みだと思いました。
開封の儀

# 概要
あのボタンを購入しました！しかしプログラムが書けない私、、、そんな私でも
とりあえずボタン押したらLINEに通知することまでやってみた！
開封の儀ってやつですね。簡単な記事でお恥ずかしい。。。

下記のサイトを参考にさせていただきました。
1)SORACOM LTE-M Button powered by AWS をクリックしてSlackに通知する 
https://dev.soracom.io/jp/start/aws_button_slack/
2)AWS IoT 1-Click サービスから LINE に連携するためのサンプル
https://github.com/j3tm0t0/1-click/tree/master/functions/line-bot_py

あのボタン届きましたので開封
![IMG_2081.JPG](https://qiita-image-store.s3.amazonaws.com/0/20632/55325c6f-5a4e-9653-7c50-1a70a8020356.jpeg)

# AWS IoTへ登録
手順通りに、AWS IoT 1-Clickに登録します。

ボタンのカバーを開けて電池2本を入れて、最初の1回目のボタンを押します。
![100.png](https://qiita-image-store.s3.amazonaws.com/0/20632/fead2092-449f-7317-293c-bed1f98d8e1d.png)

ボタンを押してすぐには電波は飛ばないらしいです、
ネットワークの状況を確認してから緑色点灯すればデータが送信されている証拠。
![101.png](https://qiita-image-store.s3.amazonaws.com/0/20632/6bd43eed-8a06-5d24-cdea-07273250c0b8.png)
こんな感じで緑色点灯を確認します。ドキドキ。。。
屋内だと結構赤色点灯してデータ送れないこともしばしばありますね。

データが送れるとAWS IoTにデバイスが登録されます。有効化して下記の状態にします。
![102.png](https://qiita-image-store.s3.amazonaws.com/0/20632/08e03e7b-4e7c-f444-d8e4-6dbd0e4994f0.png)

# SMSテスト
次もサイトの通り、携帯へSMSが通知できるかやってみます。
AWS IoT 1-Click のプロジェクトを作成します。
![103.png](https://qiita-image-store.s3.amazonaws.com/0/20632/09c83d3f-83f8-2886-bf1c-87af164149a8.png)

プロジェクト作成後に、プレイスメントの作成で設定を行い、ボタンを押してみます。
![104.png](https://qiita-image-store.s3.amazonaws.com/0/20632/cdde74e3-c9af-f785-c056-f01b179fe06c.png)
携帯にSMSが届きました！これだけでもだいぶうれしいｗ
SINGLE、と通知ありちゃんと1回押しを通知してくれています。

# SORACOMへのガジェット登録
SORACOMコンソールでボタンを登録します。登録すると送っているデータなども見れて便利。
残りボタンのクリック回数とかもここでわかりますね。
![105.png](https://qiita-image-store.s3.amazonaws.com/0/20632/c5120189-ddac-daae-4ea0-572d248831cc.png)


# LINE登録
さて、ここからは自分のLINEへ通知してみます。
こちらもサイトを参考にして作成していきます。
LINE Developersにログインして、Messaging APIを利用した新規チャンネルを作ります。
![106.png](https://qiita-image-store.s3.amazonaws.com/0/20632/9ceb7caa-c239-6ea5-914a-1097ecb5cc68.png)

アクセストークン（ロングターム）や、Your user IDをコピーしておきます。
QRコードがあるので、LINEから読み込んで友達になります。
![108.png](https://qiita-image-store.s3.amazonaws.com/0/20632/95e55ab5-d004-4bf0-e1cc-b4a72b3aec1f.png)

# AWS IoTへコピペ
あとは、AWS側でLambdaで関数の作成を行います。
一から作成として、参考サイトの通り
名前（1-click_line-bot_py）、ランタイム（Python3.6）を選択して
適宜ロールの設定を行います。
あとは、関数コードのところにある元ソースを消して
参考サイトのコードをコピペしました。
![107.png](https://qiita-image-store.s3.amazonaws.com/0/20632/897294ed-4c51-3f5e-3964-a71b3abc765b.png)

次は、AWS IoT側でさきほどのSMSでテストしたプロジェクトを消して
今作ったLambda関数を呼び出すようなプロジェクトを作ります。
この時にアクセストークン（ロングターム）や、Your user IDの値をセットします。

# できた！
では、いよいよボタンを押してみると。。。

![109.jpg](https://qiita-image-store.s3.amazonaws.com/0/20632/5ed239a7-02db-48bc-efc6-d1f2a8b142cb.jpeg)

きたーー！やっときた。。うれしい。。。
ちゃんと、1回押し、2回押し、長押しを認識しているようです。
バッテリーの残量も少しずつ少なくなっています。

# まとめ
とりあえず、ここまでできました。
今後はみなさんの記事などを参考にデータの中身の確認や
プログラムを改修してみて違うメッセージを飛ばしてみるとか
少しずつやってきたいと思います。

参考サイトすばらしい！！ありがとうございました。
RailsのDirtyモジュール　初心者→中級者へのSTEP15/25

#RailsのDirtyモジュール
##はじめに
今回はDirtyモジュールのご紹介。こやつはオブジェクトに変更が加えられたか検出できるやつ。
何に使うのかイメージ湧かないので掘り下げてみる。

#とりあえずオブジェクトの属性の変更を検出してみる。

```console
irb(main):004:0> user =User.new
=> #<User id: nil, created_at: nil, updated_at: nil, name: nil, email: nil>
irb(main):007:0> user.changed? 
=> false
irb(main):008:0> user.name = 'kamo'
=> "kamo"
irb(main):009:0> user.changed?
=> true
```
名前が変わった変わったね〜.....で？何に使うの？
確かに便利そうだけど使い道が初心者にはわからんのです。てな訳でググります。
→見つけた[記事がこちら](http://ria10.hatenablog.com/entry/20131002/1380705120)
なるほど...ユーザーが何か情報を更新したタイミングで発火させたいメソッドに使うのね。
`before_save`で保存する前に検知してそれに伴い、何か処理をする。

##dirtyを使ってみる。
まずは`include`する。

```User.rb
class User < ApplicationRecord
  include ActiveModel::Dirty
end
```
これでメソッドが使える。

```console
irb(main):004:0> user = User.new
=> #<User id: nil, created_at: nil, updated_at: nil, name: nil, email: nil>
irb(main):007:0> user.changed? 
=> false
irb(main):008:0> user.name = 'kamo'
=> "kamo"
irb(main):009:0> user.changed?
=> true
irb(main):014:0> user.changed 
=> ["name"]
irb(main):015:0> user.name_changed?
=> true
irb(main):016:0> user.email_changed?
=> false
irb(main):018:0> user.name_was
=> nil
irb(main):019:0> user.name_change
=> [nil, "kamo"]
irb(main):017:0> user.name = 'buta' 
=> "buta"
irb(main):021:0> user.name_change 
=> [nil, "dog"]
irb(main):022:0> user.save!
irb(main):028:0> user.name = 'cat'
=> "cat"
irb(main):029:0> user.name
irb(main):029:0> user.name_change 
=> ["kamo", "cat"]
```
長く書きましたが、使ったメソッドは下記のみ。

`changed?`  　　　　　　　　　　　そのオブジェクトが変わったか。
`changes`   　　　　　　　　　　 変更の流れを配列に格納。
`name_changed?`  　その属性変更されたか検知する。
`name_was`　　　　　　　　　　　　　　　　変更前の属性。

途中で試してますが、保存されている属性との比較なので、saveしない限り変更の履歴は増えません。

さて、使い方としては履歴を残す。というのが簡単な発想かなと（先輩に聞いたンゴ）思います。
例えばこのqiitaの記事、編集履歴が残ってますよね。そのような機能もdiretyで実装できます。
意外と便利なのですじゃ


##まとめ
dirtyの実用例聞いてたら、ログを残すためとか結構必須な気がしてきたので書いてみました。
明日はキャッシュかな〜

##参考にしたの

Active Model の基礎
https://railsguides.jp/active_model_basics.html

RailsのDirtyはなぜDirtyというのか。
http://ria10.hatenablog.com/entry/20131002/1380705120
Advent Calendar (2018/12/19)

はじめまして
最近ICT委員会に入った[ハラショー](https://twitter.com/harasho_me)（@HARASHO0103）です

前日の[kurokoji](https://kurokoji.hatenablog.com/entry/2018/12/19/001853)さん、[たにし](http://tanishi345.hatenablog.com/archive/2018/12/19)さんに引き続き、
Advent Calendar2018に参加させていただきます

## 今年やったこと
* Unityとcarbon board、Android端末を用いたVRアプリ制作（途中）（創造研究）
* JOI、ABC

## 以下の概要
私の入学からJOI予選までの話をします

## 入学　～ICTってなんじゃ？～
入学したときからずっとICT委員会が気になってはいたのですが
「**先輩めっちゃプロそう...**」とか「**ダンス部も入りたいし**」
みたいな理由で渋ってました
（今となってはなんで迷ってたんだか）

入学当初の段階で出身の同じ漆黒のキャサリンが
ICT委員会に入ったという話を聞き、
えびなやCaffなど同じ学科でも実力に差が生まれ始め
ICT委員会という存在自体に若干の恐怖心さえ覚えていました

しかし

1年の後半にCaffが学科内でやったプレゼンを見たときあたりから
「 **絶対自分のためになるじゃん！** 」と思うようになり
14thのICT勢から知識を奪おう（？）と考えるようになりました

## 1年後期　～Unity触ったろ！～

そのころから入学した目的でもある
**Unity**に手を出すようになります
自分自身気になることに対するやる気は一気に過熱するので
簡単な3Dゲームを大体6時間ぐらいで作りました

だがしかし

ここで悪い癖で完成してしまうとそこからやる気が減衰していったんです。。。

## 2年生　～競プロer見習い見習いへ～

2年生になり、matsugenやwakimiko等の勧めで競プロを始め、
AtCoderのABCを解きながら

「わっかんねぇ」「んぁ～どうやって解くんやこれぇ」
「あ～～こうやって解くんか俺クソ雑魚ｗｗｗ」とかなりながら
半年間、A問題やB問題を中心に解いていました

そんなときに

2年メディアがJOIを受けると聞き
自分も受けることを勧められ 
受けました

まぁ結局C問題までしか解けず
Bランクで本選はダメでした（笑）

### 総括
これからICT員会では
**書ける人間**になりたいと思ってます（高望みｗ）
まぁ**コーディング力**（？）とか
**アルゴリズム**とか
つまり**開発力**（？）を身に着けたいと思います
まぁ。。。はい
頑張ります。

それでは明日
[ふんど](https://hundo.hatenablog.com/entry/2018/12/20/221837)さん、よろしくお願いします
はじめてのQiita

#こんにちは
はじめまして！
とょしんといいます。
MarkDownを書くのは初めてなので何もわかりませんが＃とかのタグとかだけでこんな立派なブログが書けるんですね
##これはサブ見出しみたいな感じ
よく見るとこっちはさっきの見出しより小さい
使い分けが難しそう
**太字はこう**
文章の途中だと##とか入れても大丈夫だ
##タグの効果は文頭のときだけっぽい

>これ引用でよく見かけるやつ


'''
こんな感じでコードを埋め込める
'''

違うっぽい



```test.swift
print("こう")

```

[リンクもめっちゃ簡単にかけるんですねいいですねこれちなみにツイッターに飛びます](https://twitter.com/Toyoshin_)


#まとめ
MarkDownを使う機会があまりなかったので逃げていたが使ってみると結構いい
dotenvでAPIキーを適切に管理しよう

# APIキーの取り扱いについて
諸々アプリケーションの開発する際に何かしらのAPIを利用することがあると思います。
それと同時に多くの方々は開発にGitを用い、コミットログを残しながら開発を進めるでしょう。

その際、APIキーがコードに記述されたcommitが存在したままでpushが行われると、APIキーを全世界に晒す形となってしまい、貴方の権限を悪用されてしまう恐れがあります。

API元のサービスによっては膨大な契約等を結ばされたりして目も当てられない金額の請求が...といった事態にも繋がります。
そんな自体を未然に防ぐ為に、APIキーをハードコーディングしない手段を取りましょう。

# アップロードの際にキーを隠す
```ruby

  def initialize
    @client = Twitter::REST::Client.new do |config|
      config.consumer_key = "hogehoge"
      config.consumer_secret = "hugahuga"
      config.access_token = "hanyahanya"
      config.access_token_secret = "honyohonyo"
    end
  end
```
例えばTwitterAPIを使用する上でこんなコードがあった場合、gitでcommitする際に

```ruby

  def initialize
    @client = Twitter::REST::Client.new do |config|
      config.consumer_key = ""
      config.consumer_secret = ""
      config.access_token = ""
      config.access_token_secret = ""
    end
  end
```
このように記述することで確かにAPIキーの漏洩は防ぐことが出来ます。しかし、
コーディング -> 実行テスト(APIキーを入れる) -> commit(APIキーを隠す)
といったAPIキーの操作はあまりにも手間です。

# 環境変数とdotenvでAPIキーを管理する

そこで、環境変数とそれを取り込むためのgem 'dotenv'を用いて解決しましょう。


## 環境変数の設定
```
$ export API_KEY=hogehoge  
```
上記コマンドでシェル変数`API_KEY`にhogehogeを入れ、シェル変数`API_KEY`を環境変数にするという一連を行えます。


```
$ printenv
```
`printenv`　で環境変数に設定されているか確認します。

```
API_KEY=hogehoge
```

これで環境変数変数の設定ができました、他に必要な値があれば同様に設定をして下さい。


## Rubyで環境変数を読み取る
設定した環境変数をrubyで読み取るために'dotenv'のgemを使用します。

```:Gemfile
gem 'dotenv'
```


```
$ bundle
```

Gemfileに記述をし、bundle installを行います。


```test.rb

require 'dotenv'

puts ENV["API_KEY"]

>>> hogehoge
```

環境変数に設定したAPI_KEYが読み取れています。

ではこれを先程のTwitterAPIでのコードに置き換えます。

```ruby

  def initialize
    @client = Twitter::REST::Client.new do |config|
      config.consumer_key = ENV['CONSUMER_KEY']
      config.consumer_secret = ENV['CONSUMER_SECRET']
      config.access_token = ENV['ACCESS_TOKEN']
      config.access_token_secret = ENV['ACCESS_TOKEN_SECRET']
    end
  end
```

環境変数`CONSUMER_KEY`以下に適当な環境変数を設定することで、自身の環境のでは動作しGitHub等のサイトに掲載しても問題ない形でAPIキーの設定をすることが出来ます。

# まとめ
APIコードの漏洩を防ぐ為にはそもそもコードにAPIキー等の要素をベタ書きしない事が重要です。
Rubyに限らず、多くの言語で環境変数の読み取りなどAPIキーを扱う上での方法は存在するのでその都度良い方法を探して安全に取り扱って下さい。
あたらしいQAの役割を提案してみる

いくつものプロジェクトでQAとして働いてきましたが、ほとんどのプロジェクトで共通した問題点がありました。

それは、「**QAと企画・開発の相互理解が足りてない**」ということです。


QA側は「なんで企画はQAに資料を共有しないんだろう」、「なんで開発はスモークテストをしないんだろう」、「なんでいつもスケジュール遅れるんだろう」、「なんでいつも同じ不具合を出すんだろう」、「そもそもQAをバグを見つける部署だと思ってないか…？（「問題のないことを確認する部署」です。この差はでかい)」、といったような不満を抱えてます。
一方、企画や開発側も「なんでこんな簡単な不具合を本番流出させてしまうんだろう」、「なんでこんなに金と時間がかかるんだろう」といったような疑問(不満？)を持ってることでしょう。

それらの相互理解不足が原因で起きるトラブルは数知れませんし、時には深刻な問題にも発展します。


私が見てきた限りですが、QAとしてこの問題を解決できた現場は、ほとんどありませんでした。その問題を受け入れた上で、大なり小なりの不満をためつつ業務をしている現場が多かった。
理由としては、「忙しくてそんな暇がない」「他部署との関係性が弱い」「他部署と対等にコミュニケーションができる人材がいない」といったところでしょうか（現在私が所属している会社も例外ではありません）。


しかし、改めて考えてみたところ、この問題はほぼコミュニケーションのみで解決できる問題であり、そして解決できたときのメリットが大きいと感じました。つまり、費用対効果がデカい。


# 提案
ということで、QA側に専任でこの問題をを解決するポジションがあってもいいんじゃないかな、と考えてます。
イメージとしては、カプコンさんの「テクニカルディレクター」が近いかもしれません(参考：https://www.famitsu.com/news/201709/02141012.html)。

QAの現場から企画や開発に対する問題点を吸い上げ、それを企画・開発の担当者に伝え、解決する。
それと同時に、企画・開発側が感じているQAに対する問題点を吸い上げ、解決する。

文章にすると短いですが、何をすべきかは、都度都度考える必要が出てくるでしょうし、ときにはタフなコミュニケーションも発生するかもしれません。求められる知識やスキルや素養も広範囲に及ぶと思いますが、そのようなポジションの人材がQA内に一人でもいれば、QAの社内的なプレゼンスはだいぶ変わってくるのではないかな、と思ってます。

# まとめ
現在所属しているQA組織に、このポジションを提案してみようと検討しています。
自分がやるかもしれませんし、他の人がやるかもしれません。
うまく成果がでて、2020年あたりのCEDECで成果を発表できるといいなと思ってます（笑）
CDN版Vue.jsでポートフォリオをサクッと作ったよ！

[じぇい](https://twitter.com/jyouj__)です。こんにちは。

Vueを使って、[ポートフォリオ](https://jyouj.github.io/Portfolio/)をトータル4時間で作りました！使った技術などを共有しようと思います。

<blockquote class="twitter-tweet" data-lang="en"><p lang="ja" dir="ltr">Vue.jsをちょっと使って、ポートフォリオサイトつくりました！<br><br>クオリティ低いけど、みてくださーい<a href="https://t.co/56qqP0RozR">https://t.co/56qqP0RozR</a></p>&mdash; じぇい👨‍💻 (@jyouj__) <a href="https://twitter.com/jyouj__/status/1073843365353934849?ref_src=twsrc%5Etfw">December 15, 2018</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

# なんでVueを使ったの？
最初はだらだらとCSSやJavaScriptで書いていたのですが、コンポーネントを使わないとめんどくさいと思ったので、Vue.jsを使おうと思った次第です。
基本的にVue.jsの便利なところをちょこっと使いたかっただけなので、CDN版のVue.jsを選択しました。

```html
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.17/dist/vue.js"></script>
```
すぐに始められていいですよね！

# 使ったもの
### [Vue.js](https://jp.vuejs.org/index.html)
コンポーネントとか他にも様々な便利機能をサクッと使えちゃうJavaScriptのフレームワークです。

### [Vue Carousel](https://ssense.github.io/vue-carousel/)
レスポンシブ対応されたカルーセルを使えるライブラリです。これもCDNを使ってサクッと始められます。

```html
<script src="https://ssense.github.io/vue-carousel/js/vue-carousel.min.js"></script>
```

```javascript
var app = new Vue({
  el: '#app',
  components: {
    'carousel': VueCarousel.Carousel,
    'slide': VueCarousel.Slide
  }
})
```
これをAboutページに使いました！
<img width="1141" alt="スクリーンショット 2018-12-15 17.58.22.png" src="https://qiita-image-store.s3.amazonaws.com/0/252295/294b91bc-444a-2cd7-861a-86290e8d71a1.png">

```html
<carousel v-bind:autoplay="true" v-bind:per-page-custom=[[200,1],[480,3],[780,4]]>
```
自動で遷移するようにも設定できます。また、デバイスの大きさで表示するコンテンツ数も設定できてすごく楽ですね！スライドするコンテンツをコンポーネント化するとものすごく便利ですよ！

### [Bulma](https://bulma.io/)
レスポンシブ対応ラクラクなので、重宝してます。

### [iTyped.js](https://github.com/luisvinicius167/ityped)
タイピング風のアニメーションが実装できるライブラリです。これもCDN版でサクッと始められます。

```html
<script src="https://unpkg.com/ityped@1.0.2"></script>
```

解説記事は自分のブログに書いてます(笑)
[［JavaScript］iTyped.jsでタイピングアニメーションをサクッとつくる](https://jyouj.hatenablog.com/entry/2018/12/13/002744)

### [Github Pages](https://pages.github.com/)
無料で簡単にホスティングできるので、助かる！

# 最後に
CSSが多分一番疲れる。あと、やっぱりVue.jsは楽しいってことを再認識しました。もっとWebサービスを作ってWork欄を充実させたい(笑)
ROSパッケージ群ros_coreの中身

## はじめに
[前回の記事](https://qiita.com/ab_yukikaze/items/f7e820de3baa9015d1f6)でROSのインストールの際のメタパッケージ群の関係性についてまとめました．
今回は，ROSの中核をなす**ros_core**パッケージについて中身をまとめていきます．

## ros_coreパッケージに含まれるもの
[**ros_core**メタパッケージ](http://wiki.ros.org/ros_core)には，いくつかのメタパッケージが含まれ，パッケージ・ビルドシステムを提供する**ros**，ノード間通信を提供する**ros_comm**，代表的なメッセージ型を提供する**common_msgs**や**ros_comm_msgs**があります．これら以外に単独のパッケージとして，**roslisp**や**catkin**など多数が含まれています．
![image.png](https://qiita-image-store.s3.amazonaws.com/0/234210/2b176ac1-6f94-2075-d75c-4c247fe396c3.png)

## ros
説明としては，ROSのパッケージ・ビルドシステムということになるのですが，ビルドシステムとしてcatkinが採用されて久しいので，エンドユーザが意識して使うのはツールとしての**rosbash**（**rosclean**も？）ぐらいでしょうか．**roscpp**などクライアントライブラリからは**roslib**や**roslang**が呼ばれています．

### Core
**1. mk
2. rosbuild
3. roslang
4. roslib**

### Tools
**1. rosbash
2. rosboost_cfg
3. rosclean
4. roscreate
5. rosmake
6. rosunit**

## ros_comm 
ROSの中核となるノード間通信を提供するパッケージです．C++とPythonのクライアントライブラリと，ツールやユーティリティの類が入っています．**rosbag**や**roslaunch**のようなよく使われるもの以外にも，有用なツール（たとえばメッセージの同期ができる**message_filters**）があるので，初心者を脱してROSに対する理解を深める意味も含めて，見てみると良いと思います．

### Client
**1. roscpp
2. rospy**

### Tool
**1. rosbag
2. rosgraph
3. roslaunch
4. rosmaster
5. rosmsg
6. rosnode
7. rosout
8. rosparam
9. rosservice
10. rostest
11. rostopic
12. topic_tools**

### Utilities
**1. message_filters
2. roslz4
3. roswtf
4. xmlrpcpp**

## common_msgs
よく使われるROSメッセージを束ねたパッケージです．メッセージという名前ですが，トピック通信用のメッセージ型に限らず，サービス通信用のサービス型，アクション通信用のアクション型も定義されています．ROSのeco-systemの中でテストされ，使われてきた型ですので，独自の型を定義する前に一度確認すると良いですね．

**1. actionlib_msgs
2. diagnostic_msgs
3. geometry_msgs
4. nav_msgs
5. sensor_msgs
6. shape_msgs
7. stereo_msgs
8. trajectory_msgs
9. visualization_msgs**

## ros_comm_msgs
下記2つのメッセージ型は**ros_comm**からの参照がある関係からか，ソースコード上まとめて（https://github.com/ros/ros_comm_msgs.git ）管理されています．取り扱いはつぎの単独パッケージ群と同じです．
なお，**rosgraph_msgs**は，シミュレーション時刻や**rosout**で使われるログ，トピックの統計情報（周期やメッセージ数）などをやり取りするためのLow-Levelメッセージ用の型です．エンドユーザには基本的に関係ないですね．

**1. rosgraph_msgs
2. std_srvs**

## その他（単独パッケージ）
ビルドシステムとしての**catkin**，EigenやNumPyなどをcmake上でお手軽に使えるようにする**cmake_modules**，メッセージ関連のパッケージ，クライアントライブラリ関連のパッケージ，などがあります．

**1. catkin
2. cmake_modules
2. gencpp
3. geneus
4. genlisp
5. genmsg
6. gennodejs
7. genpy
8. message_generation
9. message_runtime
10. rosbag_migration_rule
11. rosconsole_bridge
12. rosconsole** (melodic以降)
**13. roscpp_core
15. roslisp
15. rospack
16. std_msgs**

## まとめ
ROSの中核をなす**ros_core**パッケージの中身を見てきました．

この記事の内容は[ROS Wiki](http://wiki.ros.org/ros_core)と[github](https://github.com/ros/metapackages)を追っていけばわかることなのですが，入り組んでいてどこに何があるかわかりにくいと感じたので，構造を整理してまとめてみました．
BigQuery/Goでテーブルを読み込む（2018年12月現在）

BigQueryで「Goの公式ライブラリで自前のテーブルにデータを流し込む」のは[ドキュメント](https://godoc.org/cloud.google.com/go/bigquery)を参考にすれば簡単にできましたが、それを読み込むところで詰まってしまいました。

`bigquery: query job missing destination table`だの`googleapi: Error 404: Not found: Job my-project:xxxxxxxxxxxxxxxxxxx, notFound`だのいろんなエラーに直面しながら、GCPUGで@sinmetalさんの助けもお借りしてようやく乗り越えられたので、備忘録として書き残しておきます。

# つまづいた原因

一番の原因は、**使っていた公式ライブラリ[cloud.google.com/go/bigquery](https://godoc.org/cloud.google.com/go/bigquery)のバージョンが古かった**こと。

超初歩的なミスですが、こういうことをしでかすとエラーメッセージでググっても解決策が見つからなくてとてもつらい。。

そして二番目の原因は、**[cloud.google.com/go/bigquery](https://godoc.org/cloud.google.com/go/bigquery)のドキュメントの例が古かった**こと。

# 実装例

2018年12月現在で最新の実装例はこちらです。

```go
package main

import (
  "fmt"
  "log"
  "context"

  "google.golang.org/api/iterator"
  "cloud.google.com/go/bigquery"
)

func main(){
  ctx := context.Background()
  client, err := bigquery.NewClient(ctx, "my-project")
  if err != nil {
    log.Fatal(err)
  }
  q := client.Query("SELECT year, SUM(number) as num FROM `bigquery-public-data.usa_names.usa_1910_2013` WHERE name = 'William' GROUP BY year ORDER BY year")
  it, err := q.Read(ctx)
  if err != nil {
      log.Fatal(err)
  }
  for {
    var values []bigquery.Value
    err := it.Next(&values)
    if err == iterator.Done {
        break
    }
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println(values)
  }
}
```

公開データを使っているのでデータセットを用意する必要はありませんが、GCPで適当なプロジェクトを作成してBigQueryを有効にする必要があります。
`my-project`の部分はご自分のプロジェクトIDにしてください。
（自前のテーブルを読み込むときは、クエリにProject IDを入れずに `datasetId.tableId` の形式でも動きます）

# 注意点

公式のドキュメントの例では、下記のようにクエリがLegacy SQLになっています。

```go
q := client.Query(`
    SELECT year, SUM(number) as num
    FROM [bigquery-public-data:usa_names.usa_1910_2013]
    WHERE name = "William"
    GROUP BY year
    ORDER BY year
`)
it, err := q.Read(ctx)
if err != nil {
    // TODO: Handle error.
}
```

現在は[Standard SQL](https://cloud.google.com/bigquery/docs/reference/standard-sql/)が標準になっているようなので、FROM句のところを`[projectId:datasetId.tableId]`の形式にするとエラーが発生します。

最新のライブラリであればエラーメッセージでStandard SQLの形式で書くよう促されるのですが、古いライブラリだと`bigquery: query job missing destination table`などの見当外れなエラーメッセージで「え？？」ってなってしまいます。

もし同じような問題にぶち当たっている方がいたら、とりあえず `$ go get -u cloud.google.com/go/bigquery` をトライしてください。
Hyper-V で Kali Linux を導入する

## 概要

Hyper-V で Kali Linux を起動できるようにしました。
少し前までイメージファイルも配られてたようですが、いまは配布やめてそうなので、一からインストールします。
Kali Linux 2019.1 を試したので記事を更新。

## 環境

Windows 10 Pro バージョン1803（OSビルド17134.407）
※PowerShell or コマンドプロンプトで `winver` コマンドを打つと確認できます。

利用したISOファイル： kali-linux-2019.1a-amd64.iso

## 準備

### Hyper-Vを有効化します。

- 管理者として PowerShell コンソールを開きます。
  - タスクバーの検索ボックスで powershell と入力していると候補にでてきます。
  - 右クリック -> 「管理者として実行」でいけます。
- 次のコマンドを実行して、インストール後に再起動します。<br>
`Enable-WindowsOptionalFeature -Online -FeatureName  Microsoft-Hyper-V -All`

### ISOファイルのダウンロード

[Kali Linux Downloads](https://www.kali.org/downloads/) で「Kali Linux 64 Bit」をダウンロードします。

## 仮想マシンの新規作成

新規 -> 仮想マシンの作成でウィザードを起動します。

### 名前と場所の指定

名前を適当に決めて、次へボタンをクリックします。
例）kali

### 世代の指定

第１世代を選択して、次へボタンをクリックします。

### 起動メモリ

適当にメモリを記載して、次へボタンをクリックします。
例）2048MB

### ネットワークの構成

「既定のスイッチ」を選択して、次へボタンをクリックします。
注意）natを選ぶとインストール中に動的IPが割り振られないとかでハマりました。

### 仮想ハードディスクの接続

仮想ハードディスクを作成するを選択して、下記を入力

名前：kali_20190322.vhdx
サイズ：32GB

注意）何回か試す場合、名前がかぶらないように注意してください。仮想ハードディスクの作成が失敗するみたいです。ハマりました。

次へボタンをクリックします。

#### 仮想ハードディスクの接続（インストールオプション）

「ブート CD/DVD-ROMからシステムをインストールする」を選択し、イメージファイルで、ダウンロードしたファイルを指定して次へボタンをクリックします。

### 仮想マシンの新規作成ウィザードの完了

完了します。

## Kali Linuxのセットアップ

作成した仮想マシンに「右クリック->接続」し、起動します。

### 起動後

Graphical Install をクリックします。

#### Select a language

Japanese を選択して、Continueをクリックします。

インストーラの翻訳は、選択された言語では完全ではありません。と表示されたら、しょうがないので「はい」を選択して続けるをクリックします。

#### 場所の選択

日本を選択して、続けるをクリックします。

#### キーボードの選択

日本語を選択して、続けるをクリックします。

#### ネットワークの設定

ホスト名を適当に入力します。
例）kali

ドメイン名を適当に入力します。
例）localhost

#### ユーザとパスワードのセットアップ

rootのパスワードを設定し、続けるをクリックします。

#### ディスクのパーティショニング

「ガイド・ディスク全体を使う」を選択して、続けるをクリックします。
パーティショニングするディスクを選択して、続けるをクリックします。
「すべてのファイルを1つのパーティションに(初心者ユーザには推奨)」を選択して、続けるをクリックします。
「パーティショニングの終了とディスクへの変更の書き込み」を選択して、続けるをクリックします。
確認されるので、「はい」を選択して、続けるをクリックします。

#### システムのインストール

終わるの待ちます。

#### パッケージマネージャの設定

ネットワークミラーを使いますか？で、「はい」を選択して、続けるをクリックします。
外部接続するためにプロキシが必要であれば、プロキシの情報を入力します。なければ空欄で、続けるをクリックします。

少々長いですが待ちます。
長い…

#### ハードディスクへの GRUB ブートローダのインストール

パッケージマネージャの設定が終わるとこちらに移行します。

マスターブートレコードに GRUB ブートローダーをインストールしますか？と表示されたら、「はい」を選択して、続けるをクリックします。
ブートローダをインストールデバイスは「/dev/sda」を選択して、続けるをクリックします。

#### インストールの完了

待ってたらインストール完了します。
完了したら、続けるをクリックします。
インストールを終了しています、の後、再起動します。

#### ログイン画面

ユーザー名：root
パスワード：xxxxxxx（さっき指定したもの）

ログインできました。

## まとめ

ネットワークの設定と仮想ハードディスクのところを気をつければ、簡単にインストールすることができました。
【備忘録】Rails＋MongoDBで認証エラーではまった時にはmongoid.ymlも確認

Rails+MongoDBでアプリを作成時にローカル環境ではRailsアプリからMongoDBに読みこみ、書き込みは行えるが、HerokuにデプロイしてMongoDBにアクセスした際、認証エラーが起きたのでその対策

例

![スクリーンショット 2018-12-15 17.24.11.png](https://qiita-image-store.s3.amazonaws.com/0/238856/d4550a16-f207-70a9-6c4f-a27a863bc0c8.png)

↓(ログインする(その際にユーザ情報が格納されているDBを見に行く)

![スクリーンショット 2018-12-15 16.34.16.png](https://qiita-image-store.s3.amazonaws.com/0/238856/a4d80248-4178-6f6e-dd46-770cd51cd03e.png)
(何回見てもあんまりみたくない画面ですね)

ログ確認
---
画面遷移時のRailsからDBにアクセスした際に、上記画面が発生したので
その時のログをコマンドより確認します。
(ターミナルからherokuにログインしている必要があります
`$ heroku login`)

```
$ heroku logs -t 
```

ログを確認します

```
2018-12-15T07:14:41.659395+00:00 app[web.1]: F, [2018-12-
15T07:14:41.659296 #4] FATAL -- : [cc6f4a20-feed-492a-a5c7-
96b8ee984f1f] 
Mongo::Auth::Unauthorized 
(User heroku_8v5bk0vx is
 not authorized to access heroku_9v5bk0vx.):
```

どうやらheroku_8v5bk0vxなるユーザが
MongoDBのheroku_9v5bk0vxのDBにアクセスしようとして
認証エラーがおきているようです。

mongoid.ymlの設定
---
まずこのheroku_8v5bk0vxなるユーザがどっから発生しているかに
かなり時間を取られてましたが
結果的には自環境ないのmongoDBの接続先を設定する
mongoid.ymlでユーザ情報がそれを指定していた。というチョンボ・・・

mongoid.ymlの誤った設定例
(パスワードは隠してます)

```
production:
 clients:
   default:
    uri: mongodb://heroku_8v5bk0vx:hogehoge@piyopiyo.mlab.com:37977/heroku_9v5bk0vx
```

uriで記載されている箇所がDBの接続先になります。
見方は

```
mongodb://heroku_dxxxxx:pppppppppppppppppppppppp@dxxxxx.mlab.com:3xxxx/heroku_dxxxxx
          UserName      Password                 Address         Port  Database
```

です

なおVSCODEの場合
[cmd]+[shift]+[F]
でフォルダ内のgrepができるので、
ユーザ名やら何やら、エラーとなっている文字を検索すると見つかりやすくなるかもしれないです。
また、mongoid.ymlの格納場所は`/config`です


Heroku上のMongoDBの確認
---
ということで正しいmongoid.ymlにてurlを設定するために
Heroku環境でのDB情報を取得します。

ターミナル上で
`$ heroku config -a {アプリ名}　|grep MONGODB_URI`を実行すると
MONGODB_URIの値を取得できます。

(もしMONGODB_URIなるものが存在しない。
とエラッた場合`$ heroku config -a {アプリ名}`とgrepを抜いてから調べるのもありです。)

```
$ heroku config -a {アプリ名}　|grep MONGODB_URI
・・・
MONGODB_URI:              mongodb://heroku_9v5bk0vx:hogehoge@piyopiyo.mlab.com:37977/heroku_9v5bk0vx
```

この見方はuriと同じく

```
mongodb://heroku_dxxxxx:pppppppppppppppppppppppp@dxxxxx.mlab.com:3xxxx/heroku_dxxxxx
          UserName      Password                 Address         Port  Database
```

です。ということでMONGODB_URIの値をmongoid.ymlのuriにコピーし、
Herokuに再度デプロイ

mongoid.yml

```
production:
 clients:
   default:
    uri: mongodb://heroku_9v5bk0vx:hogehoge@piyopiyo.mlab.com:37977/heroku_9v5bk0vx
```


結果
(例)
![スクリーンショット 2018-12-15 17.24.11.png](https://qiita-image-store.s3.amazonaws.com/0/238856/d4550a16-f207-70a9-6c4f-a27a863bc0c8.png)

↓ログイン(ログインできて次画面に遷移できるか)

![スクリーンショット 2018-12-15 17.36.09.png](https://qiita-image-store.s3.amazonaws.com/0/238856/5b946f8a-355e-896b-f654-1a9f9ce0b09b.png)

無事突破できました




環境
---
(今回のエラーはversionは関係ないですが載せておきます)

```
Rails 5.2.1
ruby 2.3.7p456
MongoDB v4.0.2
```


参照
---
MONGODB_URIの見方
[Heroku の MongoDBアドオン 『mLab MongoDB』を使う](https://qiita.com/leon-joel/items/2f13172c904b8a14b109)
ありがとうございます。
gzipコマンドによる解凍処理で"unknown suffix -- ignored"と言われるとき


gzipコマンドで`-d`をつけると圧縮ファイルの解凍処理が実行できるが、適切な拡張子がないとタイトルにあるエラーメッセージが出て失敗する。

```
$ echo "Hello" > foo
$ gzip foo
$ ls
foo.gz
$ mv foo.gz foo_gz
$ gzip -d foo_gz
gzip: foo_gz: unknown suffix -- ignored
```

解決方法としては、単純に適切な拡張子を付ければいい。

## 一括して拡張子を変更する

カレントディレクトリのファイルを全て"filename.gz"にする。

```
$ find . -type f　| xargs -i mv {} {}.gz
```

まとめて解凍する。

```
$ find . -type f | xargs gzip -d
```
linux常用命令

#当前路径
pwd

#当前用户
whoami
id -u -n

#当前shell名称
带路径echo $0
不带路径basename $0

#export
export可新增，修改或删除环境变量，供后续执行的程序使用。类似于刷新功能
例如
TEMP=0;export TEMP

#source和.
二者都是执行后面的语句使用，并且执行的脚本中的变量的信息保存在当前shell中，可以访问
例如
脚本test.sh中有一句A=1的语句
执行sh test.sh后echo $A显示为空，因为不是在当前shell中执行的
而执行. test.sh后echo $A可以显示1，因为是通过当前shell来调用，并且把调用过的变量保存了起来

#权限变更
chmod 777 TABLE_LIST

#eval命令
对eval后面的命令进行2次扫描，如果内容中包含别的变量或命令，则先将别的变量、命令的执行结果替换到该命令中，再执行该命令，常用技巧比如在不知道参数个数下动态取得最后一个参数内容
set 11 22 33
echo 反斜杠\$\$# 输出$3，并不能得到其内容
而eval echo 反斜杠\$\$# 输出33，可以把参数内容一次取得

#询问是否覆盖同名，copy文件或路径
cp -i /home/file01 /home/file01_cp

#$var与${var}同效果，但后者直观

#$(( ))计算括号中表达式，其中的变量可以加$也可以不加$，还可以将括号中指定的进制数转为10进制
例 $((2#110))

#(())重新定义变量，可以实现自加自减
例 a=5;b=7
   ((a++))

#将执行结果（包括异常）都输出到同一log
sh xxx.sh > log.txt 2>&1

#传给脚本的参数个数
$#

#tail命令
从第10行开始显示到最后一行tail -n +10 log
显示最后10行tail -n 10 log
psql実行時のパスワード入力省略方法

タイトルでもう分かっちゃてるんですが、
GitLabを用いたCIで、DBへのデータ投入しようとして上手くいかなかったので
その原因と対策をまとめました。

```
$ psql -h <ホスト名> -U <ユーザー名> < ./test/db.sql
ユーザ <ユーザー名> のパスワード: 
psql: FATAL:  password authentication failed for user "<ユーザー名>"
ERROR: Job failed: exit code 1
```

# 対象者
1. GitLab CIの動きをある程度理解している人
2. GitLabの.gitlab-ci.ymlを書いたことがある人
3. PostgreSQLを使ったことがある人

# 環境
1. GitLab Enterprise Edition 11.6.0-rc7-ee
2. CI用コンテナイメージ python:3.6 / postgres:9.6


# 原因
上記のログを見たら、「そりゃそうだ」という感じなんですが
パスワード入力を求められてるのに.gitlab-ci.ymlでパスワードを入力するスクリプトがなかったからでした

使用しているPostgreSQLコンテナではデフォルトで  
ホスト名・DB名・ログインユーザー・パスワードが設定されています

.gitlab-ci.ymlでデプロイも行っている関係上、デフォルトの設定を変更していました  

```.gitlab-ci.yml
variables:
    POSTGRES_DB: <DB名>
    POSTGRES_USER: <ユーザー名>
    POSTGRES_PASSWORD: <パスワード>
```
※ホスト名は変更するのが大変そうと同僚から聞いたので  
今回は調査対象から外しました

# 対策
次の2つを案として検討しました
1. .pgpassまたはPGPASSFILEを利用
2. PGPASSWORDを利用

## .pgpassまたはPGPASSFILEを利用

.pgpassや環境変数PGPASSFILEで指定したファイルにDB接続情報を記載すると
対話式でパスワードを聞かれることなくpsqlコマンドを実行することができます

```
<ホスト名>:<ポート番号>:<DB名>:<ユーザー名>:<パスワード>
```

この時、ファイル権限を600に変更しないとエラーが発生しちゃいます
```
WARNING: password file "<ファイルパス>" has group or world access; permissions should be u=rw (0600) or less
```

## PGPASSWORDを利用

PostgreSQL 9.6.5文書の[32.14. 環境変数](https://www.postgresql.jp/document/9.6/html/libpq-envars.html)によると

>PGPASSWORDはpassword接続パラメータと同様に動作します。 この環境変数は、一部のオペレーティングシステムではroot以外のユーザがpsコマンド経由で環境変数を見ることができるなど、セキュリティ上の理由から現在では推奨されていません。 代わりに~/.pgpass(32.15. パスワードファイルを参照してください)を使用することを検討してください。

`ps e`コマンド実行で環境変数見えちゃうからなるべく使わんといてねって事ですね

# 採用した対策案

最終的には「**PGPASSWORDを利用**」を採用しました  
公式ドキュメントは非推奨って書いてるけど
CIだし本番環境に適用するわけではないので今回のケースでは良しとしました

最初は「.pgpassまたはPGPASSFILEを利用」にしようと思ったのですが
上手くいかなくて「PGPASSWORDを利用」にしました

でも...

## 実は...
「PGPASSWORDを利用」に変更して、GitLab上でCI出来ること確認した後に判明したのですが、
「.pgpassまたはPGPASSFILEを利用」のやり方を間違えてました💦

`/opt/.pgpass`に接続情報を書いて、パーミッションも600にしてるのにパスワード入力を求められてました

ただ、後々よく確認すると**ポート番号**が抜けてました😱
かなりショックを受けました。
自分、何してんの...

# まとめ
1. 環境変数やファイルに設定することでDB接続時の対話式ログインを回避することができる
2. ドキュメントは落ち着いて読みましょう  
ほんまコレ...

DB周りは知識が浅いのでノウハウ貯めていきたいと思います！
rosbag使ってみた

こんにちは、KN_appleです。Qiitaのアドカレ初投稿です。

今回はタイトル通りrosbagを使ってみた話を書こうと思います。

## rosbagとは
rosbagとは[この記事](https://qiita.com/srs/items/f6e2c36996e34bcc4d73)でも紹介されているとおり、簡単に言うと実際に動かしたROSのトピックを保存できる機能です。
実機を動かしてトピックを記録したあと、後日rosbagを再生することでgazebo上などでロボットの状況を再現できます。パラメーター変更などの細かい調整をしたいときに便利です。

## 使い方
まず、いつもどおり動かしたいパッケージなどを起動
その後端末を立ち上げて、

```
$ rosbag record -a
```

とすると、立ち上がってるすべてのトピックを記録することができます。
記録されるファイルの拡張子は```.bag```になります。
ファイル名を指定したいときは、

```
$ rosbag record -a -O ファイル名
```
とします。

bagファイルの情報が見たいときは

```
$ rosbag info ファイル名
```

生成されたbagファイルを再生するときは

```
$ rosbag play ファイル名
```
とするだけ


```
$ rostopic echo -b ファイル名.bag -p トピック名 > file.csv
```
とすると、自分のほしいトピックの情報をcsvファイルに書き出すことが出来るので、これを使って別のプログラムにも利用できます。

## 使ってみた
今回はノートpcとデスクトップを用意。
turtlebotに載せたノートpcからデスクトップにトピックを飛ばし、そこでrosbagを使って記録しました。

1.ノートpc側

```
$ ip address   //ノートpcのipを調べる
$ export ROS_IP=ipアドレス
```
その後、roscoreなりrosrun なりを実行（publisher）
 

2.デスクトップ側

```
$ export ROS_MASTER_URI=http://ノートpcのアドレス:11311      //これでmasterのpcを環境変数に読み込む
$ export ROS_IP=デスクトップのipアドレス
```

あとはlistnerを立ち上げるだけ

このあとデスクトップ側でもう一つ端末を立ち上げて、

```
$ rosbag record -a -O ファイル名
```


これで準備完了
記録が終わればデータをcsvに変換して、好きなように使えばいいと思います
linux常用技巧

#ディスク容量確認
df -h | grep /home

#ファイル内容切り出し、ソート
cut -d "," -f1,2-9 sample.csv | sort -t "," -k2,3 > afterSample.csv

#指定行目から指定行数を削除
sed -i -e '1,1d' afterSample.csv

#日付表示
$ echo "現在時刻:" \`date '+%Y-%m-%d'`

#循环表名List，把所有以表名命名的各表CSV数据压缩，事后删除CSV
for tableName in \$(cat TABLE_LIST);do
  /bin/gzip -c /\${tableName}.csv > /\${tableName}.gz
  rm /${tableName}.csv
done;

#某配置文件重新加载
source "./../env/bwrcmn.env"

#unzip、削除
guzip -c /*test.*gz > /testName.txt
rm /test.log

#字符串剪切拼接
\#!/bin/bash

for tableName in \$(cat TABLE_LIST);do
  T_1=\`echo \${tableName} | cut -b -4\`
  T_2="T"
  T_3=\`echo \${tableName} | cut -b -6\`
  T_ID="\${T_1}\${T_2}\${T_3}"
  echo ${T_ID}
done;

exit 0