OmniAICreator/Qiita-1.07M huggingface dataset:
クラウドネイティブモニタリング

# モニタリング

## モニタリングとは

サーバのCPU使用率やサイトのアクセス数などシステムに関するリアルタイム定量データの収集、処理、集計、表示を行うことです。

- システムの異変にいち早く気付ける
- システムに障害が起きたときに原因調査が容易になる
- 障害を未然に防ぐ

### 監視の定義

監視とは、あるシステムやそのシステムのコンポーネントの振る舞いや出力を観察しチェックし続ける行為である。

Greg Poirier Monitorama 2016 https://vimeo.com/173610062 via 入門 監視

## カテゴリ
1. プロファイリング
2. トレーシング
3. ロギング
4. メトリクス

### プロファイリング

時間的な制約があればコンテキストを残すことが可能
代表的なプロファイリングツールはtcpdump
メモリの消費が激しいため常時モニタリングする際に使用することは不可

### トレーシングとは
注目している処理、例えばHTTPリクエスト100中の1のような一部のイベントを追いたい時に使用する

### ロギングとは

イベントの一部を対象として、それらのイベント１つ１つのコンテキストの一部を記録する
ストレージの過度な消費を防ぐためにログレベルで振り分けたりフィールド数を制限する必要がある
利点はフィールド数に制限があっても問題のあるリクエストが特定のAPIの特定のユーザーなどと判断ができること

#### 主なロギング
- トランザクションロギング
- リクエストログ
- アプリケーションログ
- デバッグログ

### メトリクス

コンテキストを無視したシステムに関する定量的なデータ
ログよりもフィールドが多めなので追跡する数値には上限を加える必要がある
レイテンシと個々のアプリケーションが処理するデータボリュームを追跡であったりシステム全体的な情報を集めることができる。

#### 主なメトリクス

- 各マイクロサービスが使用するNodeのCPU、メモリ、ロードアベレージ、ネットワーク、ディスク
- Webアプリケーション 秒間リクエスト数、Httpステータスコード、Httpレスポンス、リクエスト数、コネクション数、リクエスト時間、レイテンシ
- データベース コネクション数、秒間クエリ数、スロークエリ、クエリレイテンシ
- メッセージキュー(pub-sub) キューの長さ、消費率
- ログ sudoの使用、SSHログイン
- ヘルスチェック
- パフォーマンス
- データベース接続数
- エラー

#### ヘルスチェックエンドポイント
アプリケーションの健全性と状態についての情報を取得

## モニタリングのメリット

- システムの異変にいち早く気づくことができる
- システムに障害が起きた時に原因調査が容易になる
- システムに障害が起きる前にシステムの成長傾向などが把握でき未然に障害を食い止めることができる

## モニタリングの手法

- ブラックボックスモニタリング
- ホワイトボックスモニタリング

### ブラックボックスモニタリング

システム外部から見た時の振る舞いに関するモニタリング
主にクラスター外からのアクセスを定期的に確認する。

### ホワイトボックスモニタリング

システム内部から見た時の状態に関するモニタリング
主にシステム傾向やキャパシティの把握、障害時の原因調査

## モニタリングの要件
- ロギング
- ダッシュボード
- アラート
- オンコール
- デプロイメントパイプラインのメタ情報
- ヘルスチェックエンドポイント
- ネットワーク

### ロギング
各マイクロサービスの状態を常に把握するため、障害が起きた際の原因を特定するために必要
#### 収集　
kubectl logs、sternコマンド、 kiali logsで標準出力、標準エラー出力をロギング
GKEの場合はFluentdのDaemonSetが同じNode上の全コンテナのログを収集する

#### 保存
GKEの場合はFluentdのDaemonSet(fluentd-gcp-v3.2.0)が同じNode上の全コンテナのログをStackdriver Loggingに転送して保存している

#### 分析

#### アプリケーションロギング
構造化ログを使用することを推奨
メトリクスからログに変換することは可能だがその反対は難しい？
ログの書き込みかかる時間の方がボトルネックになるようなことにならないように注意する
GKEの場合FluentdのDaemonSetがStackdriver Loggingにコンテナログを送信している。

### ダッシュボード
サービスの健全性を視覚的に把握するためやユーザーにとって最も重要なメトリクスを表示するのに必要

### アラート
各マイクローサービスの機能が停止する前に問題を緩和、解決するために必要
- ページロード時間の増加
- エラー率やレイテンシの増加
- DBクエリのレイテンシの増加

### オンコール
機能停止の際に迅速に対応できるように標準化されたオンコール手続きがある
https://pagerduty.digitalstacks.net/blog/prep-on-call-engineer/

### デプロイメントパイプラインのメタ情報
httpステータスの急激な変化などに対応する指標としてデプロイがいつ始まったか、終わったか、どのビルドがデプロイされたか誰がデプロイを実行したか等

### ヘルスチェックエンドポイント
アプリケーションの健全性と状態についての情報をプル
ロードバランサやサービスディスカばりツールによるヘルスチェックにも使用できる(kubernetes service)
DB使用の場合一行selectなどを定義しておく
継続的に監視するツール（kubernetes Readiness Probe, Liveness Proveなど）を設置する必要性やサーバーサイドの作業が増えるというデメリットもある

### ネットワーク
- 帯域幅 ... ある接続から一度に送れる理論上の最大情報量
- スループット ... ネットワークの実際のパフォーマンス
- レイテンシ ... パケットがネットワークリンクを通じてやり取りされるのにかかる時間
基本的な知識のみでネットワークエンジニアリングを行わない
CSSでリンク要素a:activeにopacity:0を指定すると iOS13では遷移しない？から注意

マウスオーバー、タップ時に透過の演出するため、以下のような記述をしていた

```html
<a href="http://example.com" ontouchstart="">
  <img src="https://placehold.jp/150x150.png" alt=""/>
</a>
```

```css
a{opacity:1}
a:active{opacity:0}
```
iOS12以前の端末は、問題なくスタイルやリンクが効いていたが
iPhoneXs iOS13.1.2の実機 Safari Chromeで確認したところ、
タップしても透過0になるだけで指定したリンクへ遷移できなかった。
（一部分をタップすると効いた箇所があったので、リンクのエリアが小さくなってる???）
（画像とテキストで挙動が違う???）

サンプル
https://codepen.io/ofujiii/pen/RwwNPXa


対策としては
iOS13の場合はスタイルを効かせないという暫定的な対応しかできませんでした...
iOS13は公開したばかりで、バグが多数あると報告されているので、
修正されることを期待しつつ、
もし解決方法を知っている方がいればご教授いただきたいです
オブジェクトファイルフォーマットの規格など

ELF、Mach-O、PEに関連する規格やサイトなど書きます。

これを追加したほうがいい、というものがあればコメントにてお願いします。

# ELF

System V Application Binary Interface
http://www.sco.com/developers/gabi/latest/contents.html

過去のSystem V Application Binary Interface
http://www.sco.com/developers/gabi/

ELF-64 Object File Format(PDF)
https://www.uclibc.org/docs/elf-64-gen.pdf

ELF Formatについて
http://caspar.hazymoon.jp/OpenBSD/annex/elf.html

# Mach-O

OS X ABI Mach-O File Format Reference(公式のものは削除されてしまったので、github上のコピー)
https://github.com/aidansteele/osx-abi-macho-file-format-reference

PARSING MACH-O FILES
https://lowlevelbits.org/parsing-mach-o-files/

Mach-Oのヘッダとロードコマンドを読み込む
https://terukusu.hatenablog.com/entry/20100226/1267210640

# PE

PE Format
https://docs.microsoft.com/en-us/windows/win32/debug/pe-format

PE ファイルについて
https://tech.blog.aerie.jp/entry/2015/12/21/183741
https://tech.blog.aerie.jp/archive/category/Portable%20Executable

# その他

binutils(bfdにオブジェクトファイルフォーマットの情報)
https://www.gnu.org/software/binutils/

『リンカ・ローダ実践開発テクニック』
https://www.amazon.co.jp/dp/4789838072
ベアリポジトリにプッシュすると勝手にデプロイされる仕組み

# 何番煎じかわからないけれど…

すぐ試せるように手順だけ書きます。

# 概要

- bareRepo.git
    - 中央リポジトリ
    - 差分情報だけ、ファイルはない
- publishedRepo
    - デプロイ先ディレクトリ
    - 直接さわらない
- localRepo
    - 作業用ディレクトリ
    - ここで作業して中央リポジトリにプッシュする

# 手順

```bash
$ mkdir ~/testdir
$ cd ~/testdir
$ git init --bare --shared bareRepo.git
$ touch bareRepo.git/hooks/post-receive
$ chmod +x bareRepo.git/hooks/post-receive
$ vim bareRepo.git/hooks/post-receive
```

以下の内容を記述します。

```bash:bareRepo.git/hooks/post-receive
#!/usr/bin/env bash

cd ~/testdir/publishedRepo
git --git-dir=.git pull
```

```bash
$ git clone bareRepo.git publishedRepo
$ git clone bareRepo.git localRepo
$ cd localRepo
$ echo Hello, world! > README.md
$ git add README.md
$ git commit -m "Initial commit"
$ git push origin master
$ cd ../publishedRepo
$ cat README.md
```

publishedRepoでは直接作業していませんが、Hello, world!と表示されます。
xcodeでいきなりCould not  raunch MyApp と更にprocess launch failed unspecifiedとエラー実機でのデバッグ不可！！

xcodeでいきなりCould not  raunch MyApp と更にprocess launch failed unspecifiedとエラー実機でのデバッグ不可となった。
更にキーチェーンアクセスにて証明書が信頼されてないとのメッセージ。
![1507569900x.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101462/929a8baa-9dd7-bb00-ad54-973733d2043f.jpeg)
https://www.apple.com/certificateauthority/
上記サイトよりAppleWWDRCA.cerファイルをダウンロードクリックでキーチェーンアクセスへ追加登録
【初心者】HTML入門　基礎の基礎！【備忘録】

#まずはQittaに登録

ここ半月ほどは、自身がプログラミング未経験のため
周りのエンジニア数名に話を聞いたり情報収集を主に行っておりました。
まずは勉強を習慣づける事が自身には一番課題かと思い
備忘録やアウトプットのために当サイトに登録しました。
駄文が多々あるかと思いますが、何か違うところなどありましたら
ご指摘いただければ幸いです。よろしくお願いします。

###直近の目標

- 日々1.5h以上は必ず勉強時間にあてる。
- 予定のない日は5hは勉強時間にあてる。
- 復習の時間を1日1回つくる。
- 躓いたところや理解できないところはアナログでも残していく。
- テンプレートを試すだけでなく自身でも実験しながら進めていく。

#Progateにて勉強開始

###10/7（月）

HTMLで実際のページを作っていく仕組みを学習。
CSSでの書き方と混ざらないように気を付ける。
＜HTML&CSS＞
- classで名前分けをしている分は.（ドット）を忘れることがあるので気を付ける。
- background-colorに関しても、不要なスペースを入れないように気を付ける。
- list-styleのnone以外の物もある。（square,inside.urlなど）
- floatに関して意味を間違えない！（float:left;→左に回り込むという意味）
- padding→内側　margin→外側
 　　→上から時計回りにpxを指定（３つの場合は　上・左右・下　を表していた。）

＜見本ページの作成＞
- 演習のページを作ることはできた。
- 一通り学習できたら、自身で飼っているの犬のページを作ってみたい。

##振り返り

使い慣れてない分、少しでも疑問に感じた箇所があれば
Googleなどでも調べるようにしていきたいと思う。
一度習っただけでは自分の物として扱えないかと思うので
明日以降、復習の時間も割いていければと思います。
ググった？グレッた？レプった？～問題解決フレームの提案～

「エンジニアの仕事は、自身の想定と異なる結果の原因を調べることに最も多くの時間が費やされる」と誰かが言った。[^1]

「詰まったら、すぐに質問してください」と言われて、うまく質問できないと誰かが言った。[^2]

問題解決は迅速に解決することが大事であるからこそ、**おかしも**[^3]のようなフレームがあると便利ではないか？

[^1]: 誰が言ったかは覚えていない
[^2]: [[あるある]「詰まったら、すぐに質問してください」の克服法 - Qiita](https://qiita.com/yasuX/items/bca386bc47322f22072a)より。
[^3]: 学校では避難時の心構えをまとめた標語が作られており、「おかしも」などといった標語を用いて、慎重な行動をするように促している。ちなみに、おかしもは「押さない、駆けない、喋らない、戻らない」の頭文字をとったものである。 [wikipediaより](https://ja.wikipedia.org/wiki/%E9%81%BF%E9%9B%A3%E8%A8%93%E7%B7%B4)


# ググった？グレった？レプった？

インターネットの発展とともに、**ググった？**というアドバイス[^4]を頻繁に受けてきた人は、問題が発生した時にググるという効果的な解決方法を知っていて、即座に実行できる。

**ググる**とは「Googleで検索して調べる行為全般」であり、更に拡大解釈すれば、**「公開されている情報を調べる行為」**である。

しかし、ググるだけでは解決できないことが多い。なぜなら、プロジェクト特有の「公開されていない情報」が必要な場合があるからだ。ググっただけで質問をすると、**グレった？**というアドバイスをもらう。

**グレる**とは「grepコマンドを使用して調べる行為全般」であり、更に拡大解釈すれば**「プロジェクト内の情報を調べる行為」**である。（一般の情報とは違い、なるべく漏れなく調べることがポイント）

ググってグレッタだけで解決するほどエンジニアの仕事は単純ではない。実際に動かさずに、机上で考えてるだけでは**レプった？**というアドバイスをもらう。

**レプる**とは「REPL[^5]を使用して結果を確認する行為全般」であり、更に拡大解釈すれば**「実機での実行確認」**である。（プロジェクトの環境でREPLすることが大事）


[^4]: https://dic.nicovideo.jp/a/ググレカス
[^5]: [REPL wikipedia](https://ja.wikipedia.org/wiki/REPL)

**ググること、グレること、レプることは、即座に並行してに考慮できるように常に訓練しておくべきである。**


# ググって、グレって、レプって問題解決

一例として、ＰＭとしてプロジェクトに参画したばかりのあなたが、想定外にリリース作業に参加することになり、想定外の問題が発生してサービスが停止してしまったことを考えてみよう。

前提知識や経験がないからと言って、立ち止まってはいけない

- 発生した事象や出力されているエラーから、一般的な類似事象を確認する（ググる）
- 発生した事象や出力されているエラーから、プロジェクトのソースや類似事象を確認する（グレる）
- 発生した事象や出力されているエラーから、検証環境等では、発生しないかを確認する（レプる）

もちろん、前提知識や経験がない場合に、上記も難しい場合もあるだろう。それでも、すぐに

- 発生した事象や出力されているエラーから、サポート問い合わせの仕方を確認する（ググり方を調べる）
- 発生した事象や出力されているエラーから、プロジェクトのソースをどう調べればいいか検討させる（グレり方を検討する）
- 発生した事象や出力されているエラーから、検証環境等の準備を検討させる（レプる準備をする）

のように、立ち止まらずに施策を打つべきである。


# ググって、グレって、レプって困ったら質問しよう

この３つにおいて、問題が出たとき、つまり、詰まったときはすぐに質問しよう。

- ググろうとしたがググり方が分からない  
  ⇒ 一般的な知識が足りていない場合。ググり方もわからない場合は、有識者にヒントをもらうのが効果的なので、聞くは一時の恥聞かぬは一生の恥だと思い、即座に質問しよう。その際に、しっかりと、前提知識が足りていないかもしれないことを伝えよう。
- ググってみたが、ググった結果が自分が考えていた結果と違う  
  ⇒ 認識が間違っている可能性があるので、即座に質問しよう。プロジェクト特有の理由などがあるかもしれないので、何が違うかをはっきり示して質問しよう。
- グレろうとしたが、グレり方が分からない  
  ⇒ プロジェクトの情報の取得/共有の仕方が分かっていないため、即座に質問しよう。しっかりと、プロジェクト内の情報を調べたいと伝えよう。
- グレってみたが、グレった結果が自分が考えていた結果と違う  
  ⇒ 認識が間違っている可能性があるので、即座に質問しよう。その際に、(一般的ではなく)プロジェクト内の情報であることも伝えよう。使われていなかったり、誤っている資料の場合もあり、有識者に聞くべきである。
- レプろうとしたが、レプり方が分からない  
  ⇒ プロジェクトの実行環境の理解が足りていないので、即座に質問しよう。環境はなるべく早くに整えて、理解するべきである。
- レプってみたが、レプった結果が自分が考えていた結果と違う  
  ⇒ なるべく細かい粒度でレプることは心がけよう。細かい粒度でレプってもわからない場合、思い込みなどが原因の場合も多い。一人だとはまってしまって時間を無駄に使うが、他の人に見てもらうとあっさり解決する場合もあるので、恥ずかしがらずに相談しよう。


# ググれる職場、グレれる職場、レプれる職場

プロジェクトを受け入れる立場の人は、ググれるか、グレれるか、レプれるかを意識しよう

- 一般的な知識が活用できるところは活用しよう。ググって良記事が出てくるのに、プロジェクトの質の悪いドキュメントを参照させるのは無駄。ググって出てくる良記事がまとめてあるプロジェクトのほうが良い。（ググれる職場）
- プロジェクトの知識は、置き場所をはっきりさせて、網羅的に調べることができるようにしよう。（グレれる職場）
- プロジェクトで実行できるものは、プロジェクトのメンバがすぐに実行できる環境を整えよう。サービスはもちろん、プログラム単体や、ライブラリを含んだREPLはチーム全体の成長を加速させる。なるべくバージョン差異がないと安心。（レプれる職場）

ググれて、グレれて、レプれる職場じゃないと、コストがかさむと心得よう。

# つまり

~~ggrks, grrks, rprksというアドバイスがしたかった。~~
**グレる**と**レプる**は**本記事内の造語**ですが、、~~他にいい造語求ム~~

- 公開されている情報を調べる
- プロジェクト内の情報を調べる
- 実機での実行確認

を常に並行して行うというフレームはどうか？というポエム
[SwiftUI]リスト表示のセルにボタンが配置できない問題とその解決策

いわゆる、UITableViewCellの上にUIButtonを置くような事がしたい場合にSwiftUIでどのように記述すれば良いでしょうか。

```swift
struct ContentView: View {
    var body: some View {
        List {
            Group {
                HStack {
                    Text("Tap ME!! →")
                    Button(action: {
                        print("tap!!")
                    }, label: {
                        Text("Button")
                    })
                }
            }
        }
    }
}
```

このように、Listの中でButtonを書けば良さそうです。では実行してみましょう。

<img width="584" alt="Screen Shot 2019-10-08 at 2.10.06.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24979/e4dadb6e-7468-42c7-6c89-c086c0c9673e.png">

レイアウトは良さそうですが、ボタンが黒色ですね。
もうお気づきかと思いますが、Listの中で宣言するButtonは選択可能なCellを表示することを表現します。
同様に、複数のButtonが存在してもセルをタップした際に全てのボタンが反応するセルになってしまいます。

セル内にボタン（っぽいもの）を配置したい場合は、

```swift

struct ContentView: View {
    var body: some View {
        List {
            Group {
                HStack {
                    Text("Tap ME!! →")
                    Text("Button").onTapGesture {
                        print("tap!!")
                    }
                }
            }
        }
    }
}

```

このように、onTapGestureなどで強制的に反応するようにしてあげれば良いです。
webRTCでtrackイベントが発火したからと言って安心してはいけない

# TL;DR;
* webRTCはtrackイベントが発火して終わりではない
* connectionstateがconnectedになるまではシグナリングし続ける必要あり

# trackで終わりではない
大体のwebRTCのサンプルを見ると、大体ontrackに設定した関数が呼び出されて、
MediaStreamが取れればめでたしめでたしといった感じになっています。

映像を映す分にはこれでOKなのですが、シグナリングのためのDB監視やwebSocket接続を
リソース管理を効率的に行おうとしてその場で切断しようとすると面倒なことになる場合があります。

# 時間がかかるパターンのみ引っかかるという厄介なケース
同一LAN内での接続や、STUNサーバーを利用したパターンなどでは
onTrac後即シグナリングをやめても大体問題ありませんが、TURNサーバーを使ったケースではほとんど繋がりません。
（まったくつながらないわけではないという一番いやなパターンです）

基本的に、connectionstateがconnectedになるまではシグナリングの継続は必須です。
C言語　構造体とポインタ　実践を意識


個人情報入力プログラムで構造体とポインタを練習する
ついでに以下のようなことも意識する
1)コードを実装していく順番
2)現場でよく見かける書き方


標準入力「氏名、年齢、住所、性別、電話番号、その他」
出力「テキスト形式」


今回は大枠のところまで


①扱うデータを決める
→構造体で作ろう。名前は文字列だからchar型の配列にしよう。など
②機能実現にどんな処理が必要か書き出す。
→今回の例では
 1)コマンドプロンプト上で入力させる
 2)入力したデータをファイルへ出力する
 　が主な機能。
③汎用化できそうなものは関数に切り出す。
→main関数では関数呼び出しの枠部分だけ先に考えておく。(inputとoutputは決めておく)
④関数の中身を作っていく。
→大枠を作って詳細を作るのが王道みたい。
  効率化のためにも肝になる最小限の機能をつくって、先に確認する。
  似た処理、装飾の類の実装はあとからでもいい。

```c:userinfo.c
#include "stdio.h"
#define NAME_BUFFER  ( 100 ) //define時の()は大切。仮に演算内で使用された場合、演算順序が意図しないものになることを防げる。  
#define PHONE_BUFFER (  20 )   

typedef unsigned char   uint8_t;  //型のサイズと符合の有り無しが分かる名前での型定義。
typedef unsigned short uint16_t;  //特に"int"は処理系によってサイズが異なるので"int"のまま使用してるのは見かけない。
typedef unsigned long  uint32_t;  //今回使わないけど

typedef struct UserInfo {			//構造体のtypedefは定番。structと毎回書く手間が省ける。
	uint8_t name[NAME_BUFFER];
	uint8_t phoneNumber[PHONE_BUFFER];
}st_UserInfo;

InputUserInfo(st_UserInfo* pst_UserInfo);
OutputToFile(st_UserInfo* pst_UserInfo);

int main(void) {
	st_UserInfo		*AclassP;
	st_UserInfo		Aclass;
	AclassP = &Aclass;
	InputUserInfo(AclassP);  //アドレス渡し　※参照渡しではない。参照渡しはC++のみ
	OutputToFile(AclassP);
	return 0;
}
InputUserInfo(st_UserInfo* pst_UserInfo) {	//p:ポインタ st:構造体　のような接頭語はよく見かける
	printf("名前を入力してください->");
	scanf_s("%s", pst_UserInfo->name,sizeof(pst_UserInfo->name));
}

OutputToFile(st_UserInfo* pst_UserInfo) {
	FILE* fp;   //ここら辺は常套句のようなものかな。
	fopen_s(&fp, "test1.txt", "w"); //調べ方と使い方が分かればOK。VCだとF1でヘルプ機能。
	fprintf_s(fp, "%s", pst_UserInfo->name);
	fclose(fp);
}
```
table.html

### th と td の違い
- tr
    - 列を表すもの、`<tr>`タグで書かれたものは横一列に表示される。
- th
    - table headの略。見出しを書くときに使う。デフォで太文字に。。
- td
    - table dataの略。表の内容を記載する際はtdタグを使用する。通常の文章として表示される。自動的に左揃えになる。

```
<table border="1">
    <thead>
      <tr>
        <th>氏名</th>
        <th>年齢</th>
        <th>趣味</th>
        <th>メアド</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>りんご</td>
        <td>22</td>
        <td>カメラ</td>
        <td>xxxxx@yahoo.co.jp</td>
      </tr>
      <tr>
        <td>みかん</td>
        <td>３２</td>
        <td>読書、音楽鑑賞</td>
        <td>xxxx@gmail.com
      </tr>
      <tr>
        <td>いも</td>
        <td>43</td>
        <td>瞑想</td>
        <td>xxxxx@yahoo.co.jp</td>
```
CentOS8 net install リポジトリURL

CentOS8をインストールしようとしたところ、
インストール用のisoファイルのサイズが6GBもあった。
そこで以下からLive版と思しき"CentOS-8-x86_64-1905-boot.iso"をダウンロードしてインストールしてみた。（こちらは534MB）

http://ftp.riken.jp/Linux/centos/8.0.1905/isos/x86_64/CentOS-8-x86_64-1905-boot.iso

やはりLive版のため、リポジトリのURLを指定する必要があった。
URL指定がCentOS7までと異なるようで、以下を指定するとインストールできた。

http://ftp.riken.jp/Linux/centos/8.0.1905/BaseOS/x86_64/os

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189186/448d0c7e-2467-8b5f-d4cd-563116e19f80.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189186/7fa8152c-165b-0429-bcbd-9ffec8d3bac2.png)
A Kotlinwork Locator: ことりん仕掛けのロケーター

「[ジャバの異常な愛情 またはSpringはいかにしてモダンであることを止めて時代遅れになったのか](https://qiita.com/psycho/items/89dcc690814996984a9c)」で言及されていたServiceLocatorをKotlinで作ってみました。

https://github.com/dobashi/kasl

## 機能
### 機能 - 実装済

- Locatorからのインスタンスの取り出し
- Singleton/Prototypeの使い分け
- Mockへの入れ替え

これだけやって2クラスで60行も行かないんだからもうJavaには戻れない・・

### 機能 - TODO

- Enhancerによるカスタマイズを、利用側がInterceptorを書くだけで実装できるようにする
- Locator自体のインスタンスをカスタマイズに応じて複数扱えるようにする

機能に対する要望等あれば可能な限り対応します。

## 解説 - TODO

## テスト
### サンプルテスト 実装済み

こんな感じでターゲットクラスAとモッククラスMockedAを作っておきます。

```kotlin
package com.lavans.kasl

open class A {
    open fun say() = "A: Hello!"
}

class MockedA : A() {
    override fun say() = "MockedA: Yo!"
}
```
kotlinだとoverrideするメソッドはopenにしておかなきゃいけなくて、テストのためにインターフェースを変えるのは良くなさそう。拡張メソッドでどうにかならないかな。

1) 設定一切なしでインスタンス取得

```kotlin
    @Test
    fun `A says Hello!`() {
        val a = Locator.get<A>(A::class)
        println(a.say())
        assertEquals("A: Hello!", a.say())
    }
```
ちゃんと`A: Hello!`が出力される。

2) AをMockedAに差し替え設定をしてから取得してみる

```kotlin

    @Test
    fun `MockedA says Yo!`() {
        Locator.put(A::class, MockedA::class)
        val a = Locator.get<A>(A::class)
        println(a.say())
        assertTrue(a.say().contains("Yo"))
    }
```

たしかに振る舞いが変わった。

3) デフォルトのsingletonでは何回getしても同じインスタンスが取れること

```kotlin
    @Test
    fun `Singleton returns same instance`(){
        val a = Locator.get<A>(A::class)
        val b = Locator.get<A>(A::class)
        val c = Locator.get<A>(A::class)
        val d = Locator.get<A>(A::class)
        println("$a\n$b\n$c\n$d")
        assertEquals(a, b)
        assertEquals(a, c)
        assertEquals(a, d)
    }
```

ちゃんと同じobject idで帰ってきますね

```
com.lavans.kasl.A@41675a1f
com.lavans.kasl.A@41675a1f
com.lavans.kasl.A@41675a1f
com.lavans.kasl.A@41675a1f
````

4) プロトタイプ指定すると別々のインスタンスになる

```kotlin

    @Test
    fun `Prototype returns different instance`(){
        Locator.put(A::class, type = KClassInfo.Type.Prototype)
        val a = Locator.get<A>(A::class)
        val b = Locator.get<A>(A::class)
        val c = Locator.get<A>(A::class)
        val d = Locator.get<A>(A::class)
        println("$a\n$b\n$c\n$d")
        assertNotEquals(a, b)
        assertNotEquals(a, c)
        assertNotEquals(a, d)
    }
```

なるほどー、全部違うIDだ。

```kotlin

com.lavans.kasl.A@309bde2d
com.lavans.kasl.A@42eda0a8
com.lavans.kasl.A@400f3528
com.lavans.kasl.A@522b5d4c
```

### サンプル TODO

- AOPでloggerを差し込んでmethodの開始と終了でlogを吐くやつやりたい。そうするとloggerとcglibへの依存が増えるな、増やしたくないな、別プロジェクトでもいいけど
Nuxt.jsでaxiosの共通処理を作成し、API呼び出し処理をラップして使用する

Nuxt.jsでAPIを叩くとき、共通のヘッダーとか設定したいですよね？
さらにAPIの呼び出しをラップして、 `api.getUser(1)` みたいな感じで使いたかったので、いろいろ試した際の備忘録です。
酔っ払いながら試したので、忘れないうちにメモっておきます。

ということで今回は、下記を目的としています。

* APIを叩く際に共通のAuthorizationヘッダーを付ける
* APIの呼び出し処理をラップして、Component内でより手軽に呼び出させるようにする

# ディレクトリ構成
`/plugins` 内に、下記のような構成でファイルを置きます。

```
plugins
└─ axios
    ├─ modules
    │   ├─ user.js   # user関係のAPI処理
    │   ├─ hoge.js   # hoge関係のAPI処理
    │   └─ fuga.js   # fuga関係のAPI処理
    └─ index.js      # 共通処理の記述
```
`user.js` とか `hoge.js` とかファイルを分けていますが、関連するAPIの処理をファイル毎にまとめたかったのでこんな感じにしてます。

# nuxt.config.js に設定を追加
`nuxt.config.js` のpluginsの箇所に追加

``` nuxt.config.js
  plugins: [
    '@/plugins/axios/index'
  ],
```

# axios 共通処理部分の作成
axiosで共通処理を作成するには、[Interceptors](https://axios.nuxtjs.org/helpers#interceptors)という機能を使います。

``` plugins/axios/index.js
export let axios;

export default ({ store, $axios }) => {

  $axios.defaults.baseURL = 'https://api.hoge/'

  $axios.onRequest(config => {
    config.headers.common['Authorization'] = `Bearer token`;
    config.headers.common['Accept'] = 'application/json';
  });

  $axios.onResponse(response => {
    return Promise.resolve(response);
  })

  $axios.onError(error => {
    return Promise.reject(error.response);
  });

  axios = $axios;
}
```

[Auth Module](https://nuxt-api-state.lec.cafe/5.%E8%AA%8D%E8%A8%BC/#auth-modules%E3%81%AE%E8%A8%AD%E5%AE%9A)を使用して、Authorizationヘッダーに付けるトークンをstoreに保存しておくと、いい感じに実装できると思います。
参考：[Nuxt.jsでAuth Moduleを使ってログイン機能を実装する](https://qiita.com/itouuuuuuuuu/items/1dc6401022e0d771c757)

# APIを呼び出す部分の作成
とりあえず、特定のユーザーを取得する `getUser` と、ユーザー一覧を取得する `getUsers` という処理を作成するものとします。
user関係の処理なので、 `user.js` にまとめようと思います。

```plugins/axios/modules/user.js
import { axios } from '../index.js';

export default {
  getUser(id) {
    return axios.$get(`users/${id}`)
  },

  getUsers() {
    return axios.$get(`users`)
  }
}
```

`plugins/axios/index.js` でexportした `axios` をimportして使用しています。

# 実際にComponent内で利用する
上記で作成した `getUser` をComponent内で使用したい場合は、例えば下記のように関数を定義して呼び出すことができます。

```pages/index.vue
<script>
import UserApi from '@/plugins/axios/modules/user'
export default {
  methods: {
    getUser(id) {
      UserApi.getUser(id).then((response) => {
        console.log(response)
      }).catch((error) => {
        console.log(error)
      })
    }
  }
}
</script>
```

以上でやりたかったことはできました！

もっと効率良くできるよーなどアドバイスあれば、ぜひ教えてください！
SQLの制約と指定方法まとめ

#SQLの制約と指定方法

##前回までの流れ
前回は、**SQLの四大命令文**についてまとめました。
→[SQLの四大命令文まとめ](https://qiita.com/matsukei/items/5281ae5c45b059fb54fc)

今回は**制約**についてまとめています。

##SQLの制約とは？
制約とは、テーブルに格納するデータを制限する方法です。

データ型によって、

- **整数であるか？**
- **文字列であるか？**

といったデータの種類を限定することはできますが、それだけでは、

- **正数のデータのみを受け付ける**
- **同じデータが重複してはいけない**

とかといった制限を行うことができません。

制約はこのような制限を列やテーブルに対して定義することができます。


※「そもそも、なぜ制約が必要なのか？」と言う方はこちらのサイトがわかりやすいです。
→[「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典](https://wa3.i-3-i.info/word16591.html)

#1.　制約の種類

- NOT NULL制約
- 一意性制約（UNIQUE KEY)
- 主キー制約 (PRIMARY KEY)
- 外部キー制約 (FOREIGN KEY)
- チェック制約

#2.　制約と指定方法

特に使用頻度が高い、

- NOT NULL制約
- 主キー制約

を中心に説明します。


##2.1　NOT NULL

- `NULL値を禁止`

```
CREATE TABLE user_table (
　　user_id 　　INT PRIMARY KEY,
　　user_name 　VARCHAR(50) NOT NULL,　     // ここ
　　tel_no 　　　VARCHAR(50) NOT NULL       // ここ
);
```
##2.2　UNIQUE KEY(一意性制約)

- `重複した値を禁止`
**一意性** = **「オンリーワンな値」**　という意味で思ってもらえば大丈夫です。
つまり、
**一意性制約** = **「他の行の値と重複する値はダメですよ〜」**という制約。

- `複数の列に設定可能`
- `NULLを禁止するわけではない`

以下の文は**「電話番号とアドレスは他の人と被っちゃマズイよね〜」**ということで、制約しています。

```
CREATE TABLE user_table (
　　user_id 　　INT PRIMARY KEY,
　　address     VARCHAR(255),
　　tel_no 　　　VARCHAR(50) ,
   UNIQUE (telephone, address)    // ここ　
);
```

#2.3　PRIMARY KEY(主キー制約)

- `「列」、または「複数の列の組み合わせ」に対して指定`
-  `指定できるのは1つのテーブルに1つだけ`
- `一意を保証`
- `重複とNULLを禁止`

つまり、「**指定された列**、または**複数の列**は重複もNULLもダメですよ〜」ということ。

```
CREATE TABLE user_table (
　　user_id 　　INT PRIMARY KEY,　　　 // ここ
　　user_name 　VARCHAR(50) NOT NULL,
　　tel_no 　　　VARCHAR(50) NOT NULL
);
```

#2.4　FOREIGN KEY(外部キー制約)

- `他のテーブルの列を参照し、その列にある値以外は禁止`

以下の例を見てみよう。
２つのテーブルがある。

###■　生徒テーブル
```
CREATE TABLE student (
  student_id    INT PRIMARY KEY,
  student_name  VARCHAR(20),
  school_id     INT,
  age           INT
);
```

###■　学校テーブル

```
CREATE TABLE school (
  school_id     INT PRIMARY KEY,
  school_name   VARCHAR(20)
);
```

といったときに、
生徒(student)テーブルのschool_idの値には、
学校(school)テーブルのschool_idの値を入れ、
「その生徒がどの学校に在籍しているかを紐づけたい」という場合がありますよね。

その場合は、生徒テーブルに**外部キー制約**を以下のように指定すれば良い。

###■　生徒テーブル
```
CREATE TABLE student (
  student_id    INT PRIMARY KEY,
  student_name  VARCHAR(20),
  school_id     INT,
  age           INT

  //　以下の部分
  FOREIGN KEY (school_id) 
  REFERENCES  school (school_id)
);
```

###解説


**FOREIGN KEY (school_id)**　　　 　・・・どの列に外部キーで制約をつけるのか（参照元）
**REFERENCES  school (school_id)**　・・・どのテーブルの、どの列を参照するか（参照先）

つまり、以下が式になる。

```
FOREIGN KEY (制約をつけたい列名)
REFERENCES  参照したいテーブル (参照したい列名)
```


#まとめ
以上、SQLの制約と指定方法についてのまとめでした。

間違ってる点があれば、ご指摘お願いします(^ ^)
nimでgnuplot使ってみたお話

#はじめに
こんにちは、YagiELです。Qiita初投稿です。
もともとpythonをやっていたんですが、最近nimという至高の言語に出会ってしまい勉強中です。
なんか、nimnimしてきたな...
nimとの出会いとなった記事、貼っときますね。
[https://qiita.com/rigani/items/6e87c7cee6903ed65ed2](https://qiita.com/rigani/items/6e87c7cee6903ed65ed2)

さて、今回はそのnimを用いてgnuplotをやってみたお話をしようかなと思います。pythonのときはanacondaを使っていたのでmatplotlibで簡単にグラフ描画できたんですけどね。nimにはまだ(?)そういったパッケージがないのでgnuplotを利用します。


#環境
Windows10　64bit
Visual Studio Code 1.38.1
nim 1.0.0

#やったことリスト
1.　nim動きますか?
2.　nimbleでgnuplotをインストールしよう
3.　gnuplot(自体)を入れましょう

#1.　nim動きますか?
nimのインストールからvscodeで使えるようにするまでの詳細はまた後日書きたいですね。今回はvscodeからちゃんと実行できるよってことの確認をします。

```nim:helloworld.nim
echo "Hello World"
#Hello World
```
をターミナルを使って"nim c -r helloworld.nim"で実行して動作確認をしましょう。動けばok

#2.　nimbleでgnuplotをインストールしよう
[https://github.com/dvolk/gnuplot.nim](https://qiita.com/rigani/items/6e87c7cee6903ed65ed2)
をインストールします。
名前がややこしくて勘違いしていたんですが、これをいれればグラフ描画ができるよってものではないらしいです。あくまでこれはnimでgnuplotを動かすためのインターフェイスなので、後でgnuplot自体をインストールする必要があります。(私はこれに気づかずに2週間ほど唸った...)
とまれ、ターミナルを使って"nimble install gnuplot"でインストールします。

現時点でgnuplotを利用したプログラムを実行してみましょう

```nim:gnu_test1.nim
import gnuplot,math

var
    X=newSeq[float64](1500)
    Y=newSeq[float64](len(X))
    Z=newSeq[float64](len(X))
proc f(x:float64):float64=
#ちょこっとムダだけど関数の練習で使ってみた
    result=x.sin
proc g(x:float64):float64=
    result=x.cos
for i in 0 ..< len(X):
    X[i]=i/100
    Y[i]=(i/100).f#Y[i]=(i/100).sinとかでもいいはず
    Z[i]=(i/100).g
cmd "set size square"
plot X,Y
plot X,Z

discard readChar stdin
```
するとこんな感じのエラーが出ます。
Error: execution of an external program failed: 'c:\Users\yagie\Documents\myprograms\nim\gnu_test1.exe '
いやー、ダメですねーーーgnuplot自体を入れないといけません(当然ちゃあ当然)...
#3.　gnuplot(自体)を入れましょう
さてさて、gnuplotを入れましょう。
[https://sourceforge.net/projects/gnuplot/files/gnuplot/](https://sourceforge.net/projects/gnuplot/files/gnuplot/)
からダウンロードできます。あとダウンロードした"gp527-win64-mingw"を使ってインストールします。で、インストールが終わったらPATHを通します。私の場合"C:\Program Files\gnuplot\bin"でした。環境変数はWindows10ならコントロールパネル→システムとセキュリティ→システム→システムの詳細設定→環境変数でいじれます。できれば終了です。vscodeを開いて再度gnu_test1.nimを動かしてみましょう!!

![コメント 2019-10-08 001753.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/508735/36b960c9-b182-81c7-4833-1ddaf7335f71.png)

やったー！！できましたね。
以上、nimでグラフ描画でしたー
それではよいnim-lifeを!!
Power BI データフローで モデルのインポート ができるようになるみたいですよ

そのうち製品チームから公開されるはずなのだけど、機能としては展開済みになっていたので使ってみたよという話。Power BI データフローでは Azure Data Lake Storage Gen2 + Common Data Model フォルダが採用されているのだけど、Common Data Model のメタデータである JSON ファイル(model.json)、つまりCommon Data Model フォルダの構成を知るものをインポートすることで、Power BI データフローを構成することも可能になったということでよいかと思う。

# 操作自体はいたってシンプル
モデルをインポート
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193509/07079312-38ab-62bc-dff4-438332551885.png)
インポートが成功したらデータソースの資格情報を設定して、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193509/b6097ec5-e734-52e1-e399-3c50dc9bb93f.png)
初回のリフレッシュ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193509/a49ee3f1-dec7-2464-9d90-f82b0509048b.png)
ほとんどの場合、すでに配置されたPower BI データフローから メタデータファイルをエクスポートする感じでしょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193509/463407a4-40b7-24ab-10e2-4a8f80fbbe6e.png)

どんなフォーマットなのか？は[The metadata file (model.json) for the Common Data Model](https://docs.microsoft.com/en-us/common-data-model/model-json)に書いてある通り。
メタデータですからデータ本体は含まれないし資格情報も含まれない。何が含まれるかは実際に見てみても複雑なものではないから理解できるはず。Power Query と エンティティ情報(列名やデータ型)、実体となる CSV ファイルのURLとかですよね。

# 思ったこと🙄
モデルのインポートにあまり関係ないけれども。今のところ Power Query Online と Power BI Desktop の Power Query エディタ、これらには Common Data Model フォルダをサポートするコネクタがある。なので特段の準備なくPower BI データフローからデータを取得できる。
サポートするコネクタがない場合とか Azure Data Lake Storage Gen2 のCommon Data Model フォルダを直接見に行かなければならないとき、エンティティの情報 / CSV のURL / パーティションとかを model.json から読み解かなければならんのよね。

# その他
- [Power BI 勉強会 - connpass](https://powerbi.connpass.com/)
- [Power BI Desktop を使い始めるには](http://qiita.com/PowerBIxyz/items/6c4735cb5b5712e70981)
- [Excel で Power Query を使い始めるには](http://qiita.com/PowerBIxyz/items/52e563037b855a099ca9)
Spring Boot + Docker + Github での環境構築 クイックスタート


## Spring Bootのアプリ作成

### 1. Spring InitilizarでHelloWorldのアプリ作成

以下のリンクをクリックして、Generateでダウンロード

https://start.spring.io/

### 2. HelloWorldのコントローラーを作成

HelloWorldを表示するアプリ作成。

```java:HelloWorld.java

@RestController
public class HelloWorld {
	@RequestMapping("/")
	public String helloWorld() {
		return "hello world";
	}
}

```

以下のURLをクリックすると、ローカル環境にアクセスできることを確認

http://localhost:8080/

### 3. Githubにデータをプッシュする

上記の作成したモジュールをGitに追加する

https://github.com/harutotanabe09/SpringBootHelloWorld

### 4. Dockerファイルを用意する

・　できるだけ軽量コンテナを使用する（alpineを使用する）
・　コンテナ内でのGradleのインストールは不要
・　gradlew bootRunでコンパイルから実行まで実施する

```Docker:Dokcerfile

FROM openjdk:8-alpine

RUN apk update && \
    apk upgrade && \
    apk add --no-cache \
    bash \
    curl-dev \
    ruby-dev \
    build-base \
    git

RUN mkdir /usr/app
WORKDIR /usr/app

# アプリケーションをダウンロード
RUN git clone https://github.com/harutotanabe09/SpringBootHelloWorld.git . 

# アプリケーションを実行
ENTRYPOINT ["sh", "./gradlew", "bootRun"]
```

### 5. Dockerコマンドでためす

・上記で作成したDockerFileのディレクトリで以下実行
・DockerFileのimageのビルド＆コンテナ起動する　（rmオプションで実行停止したときプロセス削除）

```sh
# ビルドコマンド
docker build -t my-java-app .
# 実行
docker run -p 3000:8080 my-java-app --rm
```

### 6. Docker-Compose作成

・上記で作成したDockerFileをコマンド１つで実行できるようにするためにDocker-Composeを作成

```yml:docker-compose.yml
version: "3.7"
services:
  javaapp:
    build: .
    ports:
      - "3000:8080"
```

・`docker-compose up`を実行してみる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230829/0c2bb968-84be-733d-dba9-7c9d4a47a7b0.png)

・ローカルで動いていることを確認

http://localhost:3000/

### 7. 作成したDockerFileとDockerComposeをGithubにプッシュ

・サンプルとして以下に配置

https://github.com/harutotanabe09/SpringBootHelloWorldDocker.git

##### ワンポイント：Gitのサブモジュールでアプリ側にGitのDockerFileを入れると見分けがしやすい
ブログスポットの中でのMobileNet利用　／　Using MobileNet inside BlogSpot

ブログスポットの中でのMobileNet利用

Using MobileNet inside BlogSpot

[Demo]
https://randomwalkjapan.blogspot.com/2019/10/mobilenetusing-mobilenet-inside-blogspot.html

[Source] 
https://github.com/tanakayutaka/MobileNetOnBlogspot-Blogger-


Googleが運営する無料ブログサービスであるブログスポット（このサイト）に、カメラに映った映像を分類するMobileNetという実験プログラムを組み込んでみた。既に学習済みのネットを利用するだけで、学習は行わない。映し出された窓にはカメラの映像が、その下に画像判定結果とその可能性（０から１の範囲）が示される。計算負荷が大きいため処理が遅くなります。実行したくない人はカメラアクセスを拒否してください。


Installed MobileNet on this site, blogspot, i.e., Google's free blog service. This only classifies object based on pre-educated neural net but no new learning is done.  Under the camera video shown, object name and possibilities(0-1) are shown.  Due to heavy computation, reactions will be slow. Pls deny camera access if you do not wish to run.



なお、BlogSpotの記事の場所に結果を表示するには、下のようにparentメソッドを利用します。To display the result on blog body, use parent method as below.



&lt;body&gt;

  &lt;div id='myContainer'&gt;&lt;/div&gt; 

&lt;/body&gt;



  function setup() {

    // Create a camera input

    video = createCapture(VIDEO);

    video.parent('myContainer')

    video.size(200,300)

    // Initialize the Image Classifier method with MobileNet and the video as the second argument

    classifier = ml5.imageClassifier('MobileNet', video, modelReady);

    resultsP = createP('Loading model and video...');

    resultsP.parent('myContainer')

  }



  function gotResult(err, results) {

    // The results are in an array ordered by confidence.

    resultsP.html(results[0].label + ' ' + nf(results[0].confidence, 0, 2));

    resultsP.parent('myContainer')

    classifyVideo();

..Just Cut &amp; Paste from Visual Studio Code

(also pls delete, white-space: pre; )
Travis CIでPipenv + Pytestの自動テストを行った

# 概要
前回[「Pipenv+Pytestを使って気象情報API用のPythonライブラリを作成した」](https://qiita.com/devara/items/fc450723906e64d3ba36)が、せっかくなので自動テストを行いたいと思い、Travis CIを使ってみた。（[Github Actions](https://github.com/features/actions)はリクエストは出したが、まだ来ていない・・・）

今回Travis CIと連携したリポジトリは下記である。
https://github.com/doara-developer/weatherlib

# Travis CI とは
GitHubと連携した自動テスト実行サービス。オープンソースソフトウェア向けには無償でサービスを提供している。[Travis CIの料金プラン一覧](https://travis-ci.com/plans)

# アカウント登録＆Github連携方法
下記の通り行えばすぐに可能。特に困ることはない。
https://knowledge.sakura.ad.jp/3754/

# 注意：[travis-ci.com](https://travis-ci.com)から登録すること
[travis-ci.org](https://travis-ci.org)と[travis-ci.com](https://travis-ci.com)の２つが現状存在し、昔はアクセスできるリポジトリがプライベートorパブリックと違ったらしい。今は[travis-ci.com](https://travis-ci.com)で両方アクセスできるので、使い分ける必要はない。間違えないように注意。
[Travis CIは公開リポジトリもプライベートリポジトリもtravis-ci.comになるみたい](https://qiita.com/nwtgck/items/da0e2f5ba2247403c2db)

# 後は設定ファイル（.travis.yml）をパッケージに置くだけ
今回のリポジトリでは設定ファイルに下記を記述した。Pipfileにテスト環境も明記してあるので、これだけで問題なし。

```yaml
language: python
python:
  - "3.7"

# command to install dependencies
install:
  - "pip install pipenv --upgrade-strategy=only-if-needed"
  - "pipenv install --dev"

# command to run the dependencies
script:
  - "pipenv run tests"
```

Travis CIのページに行くと下記のようにテスト結果が確認できる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/497222/1dcb02c6-8935-6506-bf64-53af5714014f.png)

# わざわざTravis CIのページまで毎回確認しに行くのがめんどくさい。。。
そんな方は下記リンク通りにやれば、Readme.mdにビルドステータスを表示することが可能。便利便利。
[Travis CIで自動テストして、結果をGitHubのトップページに表示する](https://qiita.com/hoshimado/items/4090d8e64beb8a7f95e1)
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/497222/4ed965e4-aae3-88f7-3485-d4b970070442.png" width=30%>

# まとめ
最近はCIについて知らなきゃいけないだろうと重い腰を上げて勉強してみたが、とてもサクサク出来て助かった。Github Actionsが利用できるようになったらそちらも使ってみたい。

# 2019/11/09 Github Actionsが利用できるようになったので試してみた。
https://qiita.com/devara/items/e74c6491d340c9729bc3
Xcode 11.0のオススメ初期セットアップ

## はじめに

Xcodeを11.0に上げたらフォントなどが変わったので、設定し直します。

Xcode 10.0のときに行った設定は省略するので、以下の記事をご参照ください。
https://qiita.com/uhooi/items/ed148c68855ce4fd665f

## 環境

- OS：macOS Mojave 10.14.5
- Xcode：11.0 (11A420a)

## 環境設定

### フォントと文字サイズ、文字色を変更する

以前設定したフォントと文字サイズ、文字色が変更されたため、元に戻します。
以下の記事をご参照ください。
https://qiita.com/uhooi/items/ed148c68855ce4fd665f#ソースコードのフォントと文字サイズを変更する
https://qiita.com/uhooi/items/ed148c68855ce4fd665f#ドキュメンテーションコメントの文字色を変更する
https://qiita.com/uhooi/items/ed148c68855ce4fd665f#コンソールのフォントを変更する

ソースコードについて、文字サイズのデフォルトが12.0から11.0に変わったので、戻されてしまったようです。

<img width="558" alt="スクリーンショット_2019-10-08_0_28_33.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138245/cf936797-e8a8-b188-7de8-93dbd9675015.jpeg">

ドキュメンテーションコメントの変数名の文字色をどこで設定するかわかりません、、
あとスラッシュやカッコの文字色がちょっと薄いです。
わかる方がいらっしゃったら、教えていただけると嬉しいです。

## その他の設定

### ミニマップを非表示にする

ソースコードの表示幅を圧迫したくないため、ミニマップを非表示にします。

__画面右上のメニューをクリック > [Minimap]をクリック__
<img width="317" alt="スクリーンショット_2019-10-07_23_48_31.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138245/b244da09-dc9a-c09a-c8f9-aa3a4654cbbe.jpeg">

## おわりに

オススメ初期セットアップというより、以前の設定に戻す方法の紹介でした。
まだXcode 11.0をインストールしたばかりなので、他にもわかれば追記します！

## 参考リンク

- [How would I disable the minimap in Xcode 11? - Stack Overflow](https://stackoverflow.com/questions/57255442/how-would-i-disable-the-minimap-in-xcode-11)
Win10のSSHでBad owner or permissionsが出た時の対応策

:::note warn
Windows10 1903はすでにサービスを終了しています。
詳しくは[こちら](https://docs.microsoft.com/ja-jp/lifecycle/announcements/windows-10-1903-end-of-servicing)を参照。
 
:::

# 概要
Win10のアップデート後(win10 1903)でsshをできなくなって、困ったので対応策を記載。

# 症状
- win10 1903で、powershell・コマンドプロンプト経由で実行できない
- sshしようとすると以下が返ってくる

```shell:Terminal
Bad owner or permissions on C:/Users/*****/.ssh/config
```

- Git Bashからはsshできる 


# 原因
- エラーメッセージから言われているとおり、vscodeのsshの拡張機能で使うconfigファイルに不適切な権限が与えられているため
- 自分の場合、sshのprivateキーをconfigファイルと同じ

```shell:Directory
C:/Users/*****/.ssh/
```

に置いていたのがセキュリティ的によくないということらしい。
※以下参照

https://github.com/cmderdev/cmder/issues/1763


# 対処
VScodeのsshに使うconfigファイルを以下のように変更した。

```shell:VSCodeで使用するconfigファイル
# 変更前)
C:/Users/*****/.ssh/config

# 変更後）
C:/ProgramData/ssh/ssh_config
```

ほんとは、`C:/Users/*****/.ssh/config`のパーミッションを変更するだけでいいんですが、うまく変更できなかったので、privateキーの保存場所とconfigのファイルの場所を変更した。

再度、VSCodeでsshを試みる。
以下の図の歯車マークから、上から２番目の`C:/ProgramData/ssh/ssh_config`を選ぶ。

![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306295/11f99af7-159e-1cdc-6485-cd83ec2fd516.png)

これで、sshできる。

以上です。
youtube-dlでHTTP Error 429: Too Many Requests (caused by <HTTPError 429: 'Too Many Requests'>)が出たときの対処法

# エラーが出た経緯
私は、自分のDiscord botに音楽機能をつけており、それで音楽を聞いていると...

```
[stderr] ERROR: Unable to download webpage: HTTP Error 429: Too Many Requests (caused by <HTTPError 429: 'Too Many Requests'>); please report this issue on https://yt-dl.org/bug . Make sure you are using the latest version; see  https://yt-dl.org/update  on how to update. Be sure to call youtube-dl with the --verbose flag and include its complete output.
```
と言うエラーが発生しました。
つまり、YouTube上の動画のダウンロードしすぎということです。

# 試行錯誤
エラーを調べてみると、https://github.com/ytdl-org/youtube-dl/issues/5138
このissuesがヒットしました。しかし、解決法は見つかりませんでした。
次に、https://github.com/ytdl-org/youtube-dl#http-error-429-too-many-requests-or-402-payment-required
これを発見しました。どうやらIPアドレスでブロックされているようです。
これを解除するにはYouTubeに連絡するか、ホワイトリストに登録されているIPアドレスを使う必要があるようです...
ん？IPアドレスでブロック...？

# 解決方法
はい、というわけで解決方法です。
IPアドレスでブロックされているということは、IPアドレスを変えればいいということです。
昔、どこかで「再起動するたびにIPが変わってしまい、IPが固定でないといけないサービスはできない」と書いてあるページを見たのを思い出しました。
ということで、ダッシュボードの`More`から`Restart all dynos`で再起動しました。
すると...IPが無事変わり、ダウンロードできるようになりました。
家のネット回線で使っている場合は、ルーター再起動でできると思います(未検証)
固定IPを使っている場合は...変えないと無理ですね。
Nuro光みたいに半固定IPだとどうなんでしょうか。
自分用メモ(form_for関連・render・パスの確認)

<h2>render　(Viewでの役割)</h2>
→部分テンプレートをビューに出力する

ex)<%= render 'form'%>　←ここに _form.html.erbが挿入される



<h2>post:@postって何</h2>
postという名のパラメーターにテンプレート変数@postを渡しなさい

ex) <%= render 'form' post:@post%>
→部分テンプレートの_form.html.erbの post という変数に @postを渡せ


・オプション色々はここに書いてある
https://web-camp.io/magazine/archives/17675


<h2>form_for(ビューヘルパーの一種)</h2>
→特定のモデルを編集するためのフォーム

(ビューヘルパーにはモデルのプロパティ名に対応した名前(シンボル)を渡すという点を覚えておくと良いらしい)あまりわからないのであとでビューヘルパーについて学ぶ

モデルを受け取る ex)post
↓
form_for(model) do |f|
ーーーbodyーーー
end

bodyの中身
<% f.text_field :title %>
→postオブジェクトを編集するフォームで、titleプロパティに対応するテキストボックス



f.text_field


f.submit
→新規作成と編集の時では挙動が異なる
新規作成の時→create
編集する時→update


<h2>newで@postに代入する意味</h2>
formから代入する情報を格納するための器を作るため

<h2>newからcreateまでの流れ</h2>

フォーム作っておく
→データ受け取るときに受け取るデータ絞れる(1)

(C-new)newで空の容器＠postを作成
↓
(V)render 'なんたら',post: @post
でformのpostというパラメータに@postを渡す
↓
(V)データ入力
↓
(V)submitでデータ送信
↓
(C-create)@postにデータを受け取る(再構築)
・データを絞って受け取る params.require(:model名).permit(:A,:B,:C...)
(Strongパラメータっていうらしい)
↓
保存

<h2>パスの確認</h2>

rake routes
で出てくる

参考：https://qiita.com/nantekkotai/items/6fab459e1b9a38b9a816
Redisクライアントのサーバ起動、コマンド投入

#概要

Redisを最近いじっているため、自分用に使い方を（ざっくりと）メモ。
環境:RHEL。

##Redisとは
インメモリのKVS(Key Value Store)である。
インメモリということで、ハードディスクなどのストレージを利用せず、メインメモリのみでデータを管理している。

KVSのため、キーと値の組み合わせによってデータを保存する。この設定したキーを指定することで、対になる値を取得できる。


またクラスター化するため可用性が非常に高い。データ構造が多様なため、様々なアプリケーションのニーズを満たしやすい。などのいいところをいっぱい持っているらしい。



##クライアント立ち上げ方法
まずはクライアントサーバの立ち上げから。
サーバ立ち上げには「**redis.conf**」という名前の設定ファイルを用いて行う。
設定ファイルの「bind」には接続するIPが記述されていなければ一生つながらないので注意。
あと「loglevel」を「:Debug」に変更してサーバを起動したままにしておくとだとディスク容量がいっぱいになって命が尽きる。

・　redis-server /usr/local/etc/redis.conf

上記コマンドでサーバは立ち上がるはず。

ここからクラスター化したい場合は
<https://redis.io/topics/cluster-tutorial>
を参照しながらやると、
7000,7001,7002,7003,7004,7005のポートでクラスター化する羽目になる。

##クライアントサーバへ接続

クライアントサーバへ接続するには、「./redis-cli」を利用する。
クラスター化の時にも使うすごいやつで、大体こいつが何とかしてくれる。

・　 ./redis-cli -h "ホスト名" -p "ポート番号"
 
上記のコマンドを入力することで、接続可能。
クラスタモードで接続する場合にはオプション「-c」をつけることで接続できる。

##コマンド投入例
https://redis.io/commands
コマンドリファレンスを見れば全部わかる、と思う。
とりあえず差し当たって、
・SET
・KEYS
・GET
・DEL
さえ覚えておけばRedisで遊ぶことができる。
**「SET "Key" "Value"」**
キーと値を指定してデータを登録。
　ex.SET banana umai
**「kEYS "Key"」**
指定したキーが存在する場合は表示。
Keyの部分を「*」にすると、登録されているキーがすべて見られる。
　ex.Keys banana
**「GET "Key"」**
string だった場合の値をみる方法。
Redisは格納されているデータのタイプによって取得コマンドが違うらしい。
<https://blog.eiel.info/blog/2014/08/26/remember-redis/>
にちゃんと書いてあるっぽいから僕はここを見ます。
　ex.GET banana
**「DEL "Key"」**
指定したキーをデータベースから削除するコマンド。
　ex.DEL banana

##あとがき
まだまだ知ることはたくさんあるのでいろいろわかり次第追記。
分散ロックの話とか、何ならインストールの方法とかも書く予定。
attr_encryptedなカラムを検索する方法

初めまして、ガッシーです。Qiita初投稿となります。（なんか癖でQuiitaって打っちゃうんですよね）
日頃Railsの開発で躓いて調べたことなどを書き留めていければなと思ってます。
そんなところで本題へ。

railsでカラムを暗号化する際には一般的に[attr_encrypted](https://github.com/attr-encrypted/attr_encrypted)を利用するかと思いますが
READMEを翻訳しますと　
>暗号化されたデータを検索することはできません。検索できないため、インデックスを作成することもできません。

との記載があります。
でも暗号化しつつ検索したいことって結構あると思うんですよね。

そこで登場するGemが[blind_index](https://github.com/ankane/blind_index)です。
ただし **LIKE検索はできない** ので注意してください。

#blind_indexとは
例えばnameというカラムでattr_encryptedを使うときは `encrypted_name` と `encrypted_name_iv` の2つのカラムを用意すると思いますが、
それに加えて `encrypted_name_bidx` というカラムを追加してあげることで、そこに検索できる値を保存する感じです。早速やってみましょう。

##設定
[README](https://github.com/ankane/blind_index/blob/master/README.md)に書いてあることをそのままやっていけばいいのですが一応書きます。
Gemfileに下記を追加して`bundle install`

```Gemfile
gem 'blind_index'
```

コンソールを起動して下記コードを実行しランダムなキーを取得します。

```
irb(main):001:0> BlindIndex.generate_key
# SecureRandom.hex(32).force_encoding(Encoding::US_ASCII) でも同じ
=> "222189cbba7ba0381c66faf8f687197b4bd4256a99bf81c917256c2871ca5289"
```

キーを保存・設定します。

```credentials.yml.enc
blind_index_master_key: "222189cbba7ba0381c66faf8f687197b4bd4256a99bf81c917256c2871ca5289"
```

```config/initializers/blind_index.rb
BlindIndex.master_key = Rails.application.credentials.blind_index_master_key
```

（initializerを読み込むためサーバーは再起動しておいてください）

blind_index用のカラムを追加します。

```db/migrate/add_name_bidx_to_users.rb
add_column :users, :encrypted_name_bidx, :string
```

modelも変更を加えます。

```app/models/user.rb
class User < ApplicationRecord
  attr_encrypted :name, key: Rails.application.credentials.encrypted_key
  blind_index :name, key: Rails.application.credentials.blind_index_master_key #←こちら追加
end
```

以上で設定は完了です！

※既に暗号化カラムが保存されている方はコンソールにて下記コマンドを実行することで既存のレコードにも対応できます。

```
User.unscoped.where(encrypted_name_bidx: nil).find_each do |user|
  user.compute_name_bidx
  user.save(validate: false)
end
```

##実行

```
User.where(name: "山田太郎")
```

これができるようになっているはずです。

#感想
完全一致検索しかできないけど何もできないよりはマシか・・・
知識がないのですが、最初こちらの記事 [attr_encryptedされたカラムに対してwhere likeしたかった。](https://qiita.com/mmmpa/items/e22149b1ae2b1feae94c)を見ましたが恐らく現在ivカラムを利用した暗号化を行っている場合は適応できないかな？と思ってます。
Qiita初めての記事となりましたのでもし誤りがありましたらご指摘いただければ幸いです。
シリアルポートをUSB接続するたびに権限付与させたい

# はじめに
Ubuntuで`sudo chmod 666 /dev/ttyACM0`とコマンド入力することで権限が付与される。
ただし、再起動すると元の権限に戻ってしまうので接続するたびに自動で権限を付与させたい。

# 対処法
以下のディレクトリのファイルを修正する
`nano /lib/udev/rules.d/50-udev-default.rules`
変更箇所は以下の通り。
```text
(変更前)KERNEL=="tty[A-Z]*[0-9]|pppox[0-9]*|ircomm[0-9]*|noz[0-9]*|rfcomm[0-9]*", GROUP="dialout"
(変更後)KERNEL=="tty[A-Z]*[0-9]|pppox[0-9]*|ircomm[0-9]*|noz[0-9]*|rfcomm[0-9]*", GROUP="dialout", MODE="0666"
```
これで、USB接続するたびに権限が付与される。
Jetson nano ROS(Melodic)インストール〜Gazeboまで

★よく壊すのでメモ。。。笑
インストール〜gazeboまで＾＾

*Reference wikiの方がわかりやすい。
 http://wiki.ros.org/melodic/Installation/Ubuntu

1:Setup your sources.list
packages.ros.orgからソフトウェアを受け入れるようにコンピューターをセットアップします。
`sudo sh -c 'echo "deb http://packages.ros.org/ros/ubuntu $(lsb_release -sc) main" > /etc/apt/sources.list.d/ros-latest.list'`

2:Set up your keys
キーを設定する
`sudo apt-key adv --keyserver 'hkp://keyserver.ubuntu.com:80' --recv-key C1CF6E31E6BADE8868B172B4F42ED6FBAB17C654`

3:Installation
`sudo apt update`

4:Desktop-Full Install: (Recommended) : ROS, rqt, rviz, robot-generic libraries, 2D/3D simulators and 2D/3D 
`sudo apt install ros-melodic-desktop-full`

***To find available packages, use:
`apt search ros-melodic`

5:Initialize rosdep
`sudo rosdep init
rosdep update`

6:Environment setup
`echo "source /opt/ros/melodic/setup.bash" >> ~/.bashrc
source ~/.bashrc`

7:Dependencies for building packages
`sudo apt install python-rosinstall python-rosinstall-generator python-wstool build-essential`

8:Gazebo
・1つ目のターミナル
`roscore`
・２つ目のターミナル
`gazebo`
あとはあそびましょう！！！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/351913/fff8a2e9-710f-6718-90cc-1211e55fb770.png)
よいしょっと！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/351913/d7341938-6e39-0cc5-2fb6-eede59da567c.png)
Ubuntu19.10 KVMでGPUのパススルーができない問題の解決策

## 問題
Ubuntu19.10からKVMでGPUをパススルーし、Windowsのゲストを起動したところ以下の問題が発生しました。
1. ログインパスワードを入力した段階でフリーズ
2. ログイン後数秒で画面が出力されない
3. 画面描写のフレームレートが著しく低い


## 解決策
該当VMのxmlの`os` `feature`内を以下のようにします。
ポイントはq35チップセットを使う点と、 `<ioapic driver="kvm"/>` **(重要)** を追加する点です。

```
  <os>
    <type arch="x86_64" machine="pc-q35-4.0">hvm</type>
    <loader readonly="yes" type="pflash">/usr/share/OVMF/OVMF_CODE.fd</loader>
    <nvram>/var/lib/libvirt/qemu/nvram/Windows_Main_VARS.fd</nvram>
    <boot dev="hd"/>
  </os>
  <features>
    <acpi/>
    <apic/>
    <hyperv>
      <relaxed state="on"/>
      <vapic state="on"/>
      <spinlocks state="on" retries="8191"/>
      <vendor_id state="on" value="129286789ab"/>
    </hyperv>
    <kvm>
      <hidden state="on"/>
    </kvm>
    <vmport state="off"/>
    <ioapic driver="kvm"/>
  </features>
```

## 原因
NvidiaのドライバーがGPU Passthroughされていることを感知すると、動作を停止させるようです (Error 43問題)
これを回避するために、xmlを以下のようにする手法が、[いくつかのサイト](https://wiki.archlinux.jp/index.php/OVMF_%E3%81%AB%E3%82%88%E3%82%8B_PCI_%E3%83%91%E3%82%B9%E3%82%B9%E3%83%AB%E3%83%BC#Windows_.E3.81.AE.E4.BB.AE.E6.83.B3.E3.83.9E.E3.82.B7.E3.83.B3.E3.81.AB_NVIDIA_.E3.81.AE_GPU_.E3.82.92.E3.83.91.E3.82.B9.E3.82.B9.E3.83.AB.E3.83.BC.E3.81.97.E3.81.9F.E5.A0.B4.E5.90.88.E3.81.AB_.22Error_43_:_Driver_failed_to_load.22)で紹介されています。

```
<features>
	<hyperv>
		...
		<vendor_id state='on' value='whatever'/>
		...
	</hyperv>
	...
	<kvm>
	<hidden state='on'/>
	</kvm>
</features>
```

しかしこれはqemu4.0未満の環境の設定であり、ubuntu19.10で採用されているqemu4.0では追加で`<ioapic driver="kvm"/>` の記述が必要なようです。
WorkManager覚書

# はじめに
こちらの記事はAndroidのWorkManagerの覚書です。
PJでWorkManagerを使った際に使用した知識や調査した内容を残しています。

[公式](https://developer.android.com/topic/libraries/architecture/workmanager)

# そもそもWorkManagerとは？

> WorkManager API を使用すると、
> 延期可能な（ただし確実に実行される必要がある）非同期タスクのスケジュールを簡単に設定できます。
> また、タスクを作成して WorkManager に引き渡し、作業の制約が満たされたときに実行させることができます。
> 詳しくは、リファレンス ドキュメントをご覧ください。

[引用](https://developer.android.com/jetpack/androidx/releases/work#declaring_dependencies)

延期可能で、確実に実行される非同期の処理と言うと、多くの方が言っているとおり、
ログ送信やユーザーの操作を記録する機能に使えそうですね。

# OneTimeWorkRequest
単発の送信です。
Stethoなどを使うと見えるのですが、
内部的にリクエストはDB(SQLite)を使ってるので、安心ですね(アプリが落ちても消えないはず)。

なので、条件が来たら送信して、失敗したらリトライの設定もできるのでほとんどはこちらで事足りそうです。

# PeriodicWorkRequest
定期的な繰り返し実行です。
JobSchedulerと同じような使い方ができそうです。

公式にある通り、最短時間は15分みたいです。内部的にはJobSchedulerを使ってるっぽいですね。
> Note: The minimum repeat interval that can be defined is 15 minutes (same as the JobScheduler API).

# まとめ
小ネタですが、既存のPJでWorkManagerを使う場合は、
WorkManager以外のcomponentもバージョンを上げる必要が出てくることがあります。
（ライブラリのバージョンが競合して、ビルドができなくなるなどで）

そのため、特にView周りのライブラリのバージョンが上がった時に
コンパイルエラーや非推奨のコードが生まれるのでWorkManagerを導入するだけ以外の
コストも考慮しておいた方が良さそうです。

あとは、BackOffPolicyとテストコードの部分を書き切れていないので、
そちらは別の機会に調査しようと思います。

調査に使ったコード
https://github.com/shinya-takano/WorkManagerSample
AWS SDK for Ruby v3をAWS Lambdaで使おうとしたらタイムアウトした

AWS SDK for Ruby v3をLambdaで使おうとしたらタイムアウト（確認したのは128MBで1分）した。
切り分けをしたところ、以下だけの簡単なコードでもタイムアウトしてしまって、どうやらAWS SDKのライブラリ全体を require しようとすると時間がめちゃめちゃかかってしまうみたい（手元だと全然時間がかかるようなことは無いのだが、理由はよく分からない…深追いはしていない）。

```ruby:main.rb
require 'aws-sdk'

# エントリポイント
def lambda_handler(event:, context:)
  { statusCode: 200, body: JSON.generate('Hello from Lambda!') }
end
```

なので

```ruby:main.rb(抜粋）
require 'aws-sdk-s3'
```

みたいに必要なサービスのみ require するようにしたら問題無くすぐに実行された。

***

と思って上記記事を書いた後にもう少しぐぐってみたところ同じような部分で格闘していた方がいらっしゃった↓。こちらはより詳しく検証している。やはり結論としては大きめのgemのロードには（初回は）時間を要するみたい。

続・日本で 128 番目くらいに Ruby で AWS Lambda を試したメモ 〜俺のライブラリを Lambda で動かしたいけど...〜 - ようへいの日々精進XP https://inokara.hateblo.jp/entry/2018/12/01/091005
GraphicsGaleをインストールする

# はじめに
Surface Proでドット絵を描くための環境を整えることにした。
中川悠京さん著作の「ドット絵教室」などを参考にすると、「EDGE」の使用を推奨されるが、Surface Penでは滑らかに線を引くことができなかった。
色々探し回ってみた結果、フリーソフト化した「GraphicsGale」というアプリを発見。そのうち使い方もQiitaにまとめたいと思う。

## GraphicsGaleをインストールする

1. GraphicsGaleの配布元[https://graphicsgale.com/]にアクセスし、[download]ボタンをクリック。
<img width="604" alt="graphicsGale_install_01.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184939/4e74f0fd-5bfa-4480-352e-2188f1db5f1f.png">

2. [インストール版をダウンロード]をクリック。
<img width="641" alt="graphicsGale_install_021.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184939/740f2af9-ef90-4e0f-2c89-9fa7e51325de.png">

3. ダウンロードが実行されます。[保存]を選択し、インストーラを任意の場所に保存。
<img width="629" alt="graphicsGale_install_03.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184939/0d991c8f-d3a1-9453-41a2-20b15d5ec3c6.png">

4. ダウンロードが完了したら、[実行]をクリック。
<img width="629" alt="graphicsGale_install_04.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184939/397d34ea-9387-991d-e7fb-d5db26038ceb.png">

5. [同意する]を選択し、[次へ]を選択。
<img width="374" alt="graphicsGale_install_05.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184939/e649fb2c-71a9-e4d6-1f5a-26cfa62b75da.png">

6. インストール先を変更しないため、このまま[次へ]をクリック。
<img width="374" alt="graphicsGale_install_06.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184939/14101d1d-b4e3-6934-40dd-614061dab3b9.png">

7. アプリケーショングループも変更しないため、[次へ]をクリック。
<img width="374" alt="graphicsGale_install_07.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184939/2ce704de-7b6f-213f-72af-0f183e76db24.png">

8. [インストール]をクリック。
<img width="374" alt="graphicsGale_install_08.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184939/c45a2687-66ee-da39-7f2f-c9b782525f08.png">

9. [完了]をクリック。
<img width="374" alt="graphicsGale_install_09.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184939/87ce121d-3533-49f4-2e4e-e151e49d70d1.png">

10. 自動バックアップ先となるフォルダが作られる。[OK]をクリック。
<img width="247" alt="graphicsGale_install_10.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184939/278f6d0e-fe6a-784e-330e-9dde11b88bec.png">

11. アプリが実行される。
<img width="1016" alt="graphicsGale_install_11.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184939/933eef8e-e493-37d1-4f5c-247891d8cb06.png">

以上でGraphicsGaleのインストールが完了。使い方についてはまた別のナレッジとして残したいと思います。
コマンドメモ（スクリーンショット、日本語入力）

よく忘れるのでメモ。
★ スクリーンショット（任意の範囲）
` gnome-screenshot --area`


★日本語入力＜ibus-mozc＞
この３つをやる。
`sudo apt-get install ibus-mozc`
`killall ibus-daemon`
`ibus-daemon -d -x &`
設定から
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/351913/41b05c47-aa69-6e88-e45e-7cfad6828865.png)
選択して、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/351913/78305532-889e-6d6d-64df-bdc8fa91a253.png)
ここ変えたらok!