OmniAICreator/Qiita-1.07M huggingface dataset:
FirebaseとVue.jsを使って息子の教材を作った話 

## はじめに
はじめまして。ジークスの酒井です。
今回は業務とは別で日曜プログラミングネタになります。

中１の息子のために家族で単語カードを作ろうとしてたんですが、あまりに面倒くさいので
ツールを作ってみる事にしました

## 設計方針

・用紙はミシン目や穴があらかじめ空いている単語カード向け用紙を使います。

https://www.a-one.co.jp/product/search/detail.php?id=51163

・シンプルなPWAとして、入力画面 -> 印刷画面 の２画面構成にする

・vue.jsを使って、画面遷移などを実装する

・最後はFirebaseのHostingを使ってWebサイトにアップする


・印刷はpaper.cssにまかせる

paper.css
https://github.com/cognitom/paper-css

## いざ実装
まずは２画面を切り替える仕組みを作ってしまいます。
vueのlistというデータに画面名が入っていて、代入すると画面が切り替わる仕組みです。
入力画面：list、印刷画面：print

JS側

```js:fc_maker.js
data: {
    mode: 'list'
}
```

HTML側

```html:index.html
    <div v-if="mode === 'list'" id="input-list">
　　　　入力画面
    </div>
    <div v-if="mode === 'print'">
　　　　印刷画面
    </div>
```

こんなふうに準備しておくと、mode変数に代入するだけで画面を切り替える事ができます。

入力画面はExcelやGoogleスプレッドシートなどからコピペすれば
TAB区切りの文字列になる事を利用して、textareaタグをひとつ用意するだけです。

### 印刷画面

```html:index.html
    <div v-if="mode === 'print'">
      <section class="sheet" v-for="page in pages" v-bind:class="{front: page.mode === 'front'}">
        <div v-bind:id="'cardbox' + card.id" class="card" v-for="card in page.cards"><p v-bind:id="'card' + card.id" v-html="card.caption"></p></div>
      </section>
    </div>
```
こんな感じで１ページごとにsectionというタグが生成されるようにしておきます。
あとはpaper.cssにまかせるだけでok!
![FC_SS_DATA.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/160143/3e5b2986-55d3-57c7-ec5b-f20fee6c5447.png)

こんなデータを用意して流し込むだけで
![FC_SS_PAGE2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/160143/f1379a84-e176-7e24-6c42-dedc0347fba7.png)

こんなふうに、画面で見ると、１ページごとにプレビューが表示されているんですが
印刷すると、ちゃんと枠の中身が印刷されます。

## WEBサイトにUP
あとはFirebaseのHostingを使ってアップロードするだけ！
ごめんなさい。Firebaseを使ったのはここだけです＾＾

## できあがったもの

俺のフラッシュカード

https://my-flashcard.web.app/
![FC_SS_PAGE1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/160143/7d64ca7e-330e-b4dd-6073-78e313a52682.png)
Tableau初心者によるちょっっとした小技

###<font color="green">ご挨拶</font>

こんにちは:hatching_chick:
IT業界未経験の初心者が業務でTableauを使用し
可視化レポートを作成する中で発見した小技を記録しようと思います:muscle_tone4:

**※すでに既知の方が大半かと思いますが温かい目で見ていただけると幸いです:bow:**




##<font color="green">ここから本題に入ります</font>

あるデータの可視化レポートを作成している時に
データをテキスト表で表示させたのですが

月によってデータがゼロの時もあるため下記のように空白になっています。

![Before.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/529514/8b3ce85b-bfbe-391b-77b6-0954bb1a186b.png)


見た目が少し寂しい感じがして改善できないかなと考えたら
以前、同じグループの先輩が作成したレポートで
空白ではなく”0”が表示されてるのを見た気が。。する。。。:thinking::thinking:
と思い出し確認してみるとやっぱりありました:sparkles:

計算式を真似て実行してみました:feet:

![分析＞計算フィールドpng.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/529514/96349605-a1b5-142e-a694-2766598346ab.png)


分析タブ > 計算フィールドの作成から任意の計算式が入力します。



計算式は　<font color="green">ZN(LOOKUP(COUNT([レコード数]),0))</font> 　です！！！


![計算式入力.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/529514/4d67e1c4-d9a5-83da-8e68-078b14908eb7.png)


タイトルは適当に「0表記」とでもしておきます！

早速、先程のテキスト表に反映させていきます:ok_woman_tone3:


ちなみに反映する前のテキスト表をもう一度。。


<font color="red">$\mathbb{Before}$</font>

![Before.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/529514/cdb7600f-73bb-8602-2016-7c8de707d55f.png)


先程作成した計算式をテキストカードにドラッグすると。。。


<font color="red">$\mathbb{After}$

![After.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/529514/248c5041-5206-5fa0-7793-b08bdfff7089.png)



無事に反映する事ができました～🐵
空白をなくし”0”を表示するという一手間で見やすくなったと思います🐭


##<font color="green">最後に</font>
レポートは誰が見ても瞬時に理解できるのが好ましいので
データの整合性はもちろん！もっとビジュアライズを追求していかなくては！
とこの記事を書いてより実感しました:pencil2:


Tableauを使いこなせている方なら朝飯前の事かもしれませんが
初心者の私にとっては大きな発見でした:sparkles:

今後Tableauをもっと使いこなせるようになり
誰がみても視覚的に分かりやすいレポートが作れるように精神いたします。

簡潔ではありますが、最後までお読みいただきありがとうございました🙇
CoderDojo静岡のDiscord Botを作っている話

# はじめに
最近CoderDojo静岡という子どもたちのためのプログラミング道場に参加しています。
CoderDojo静岡には子どもたちのDiscord（Slackのようなチャットサービス）のコミュニティがあります。
そこでCoderDojo静岡のイベントがconnpass上で公開されたらコミュニティ上で通知してくれたり、ちょっとしたゲームも遊べるボットを作ろうと考えました。

## 以前に作ったもの
![coderdojo-shizuoka-bot-title.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154299/13169d69-909c-ba7e-2bac-18b58807a21c.png)

**使用技術**

- [Node.js](https://nodejs.org)
- [Discord.js](https://discord.js.org/#/)
- [Bisco(自作ライブラリ)](https://scrapbox.io/bisco/)
- [Heroku](https://jp.heroku.com)

[Bisco](https://scrapbox.io/bisco/)はJavaScriptで作ったDisocrd.jsのフレームワークのようなものです。
簡単にコマンド（ヘルプコマンドは用意されている）やゲームなどを作ることができます。

**機能**
以下は`cds.help`コマンド（ヘルプを表示するコマンド）の結果です。
ちょっとおかしい項目もありますが、このコマンドで使えるコマンドの一覧を確認することができます。

<img width="300" alt="スクリーンショット 2019-12-11 18.08.42.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154299/1d51cfad-a778-d198-2c48-8750bbb300bd.png">

#### CoderDojo静岡のイベント公開通知について
![スクリーンショット 2019-12-11 18.04.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154299/d119140d-beab-bf69-c5db-a168f5ac6c6b.png)
<img width="1063" alt="スクリーンショット 2019-12-11 18.06.21.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154299/10cf6f6b-5b02-1a60-92ac-7df898e8008e.png">

というのも、connpassのAPIの反映が遅いんですよね...スクレイピングで作り直す予定です。

## 作り直している話
先程の「バグで動かない」のとコードが汚いので現在このボットを作り直しています。
現在僕は「Kuro」というボットを別で運営しているのですが、そちらもいい機会なので作り直そうとしています。

両ボットとも[Bisco](https://scrapbox.io/bisco/)を使っています。
ただ最近TypeScriptに手を出しているのでフレームワークレベルから作り直しています。

### 新しく作っているDiscordBotフレームワーク「Kuro Framework」
**特徴**

- 良い感じの引数パーサー（[kuro-chan-bot/argument-parser](https://github.com/kuro-chan-bot/argument-parser)）
- 良い感じのコマンドシステム
- 良い感じのイベントリスナシステム
- 良い感じのコマンドパイプラインシステム（例:`$ reverse 4021ATOH > lower → hota1024`）

（良い感じは個人的に良い感じに使えるという意味です。）

# 今後のCoderDojoShizuoka Botについて
最近、CoderDojo静岡の一部の子たちがDiscordボットを作るのにハマっているので、CoderDojoShizuoka Botで簡単に作ったボットをデプロイする仕組みを考えています。
イベント開催通知も合わせていろいろな機能を考えていきたいと思います。
生産性を上げるための便利ツール3つ

## はじめに

こんにちは、[yuto_nakano44](https://twitter.com/yuto_nakano44)です! iOSエンジニアのインターンをしてます！
最近知った・教えてもらったツールを3つ紹介させてもらいたいと思います。

どれも一度使ったら手放せないほど便利です！

## 1. tig

gitクライアントです！
[tig](https://jonas.github.io/tig/INSTALL.html)を知るまではgitコマンドのみで作業を行なってました。

tigの魅力は..

- 1行単位でステージング調整ができる
- 過去コミットの差分を簡単に見れる
- cherry-pickが簡単

かなと思います。

### 1行単位でステージング試してみる

tigのstatus画面(git stastusに該当)の見方はこんな感じです↓

Changes to be committed: ステージングされた差分

Changes not staged for commit: まだステージングされてない差分

Untracked files: 未追跡ファイル

![output.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241322/885c5f80-9f1e-17f2-f0ff-b74ffc5c274a.gif)

tig知るまではgit add -p でステージング操作を頑張ってたけどさらに細かくできる!
ありがたい。

## 2. Charles


[Charles](https://www.charlesproxy.com/)は、プロキシアプリケーションです。

Charlesの魅力は..

- APIのレスポンスを確認できる
- APIのレスポンスを上書きできる

だと思います。


※ 無料版だと30分ほどで一度接続が切れてしまうので再度接続する必要があります。有料版($50)にすれば接続切れずに普通に使える!

今年Charlesの[アプリ版](https://apps.apple.com/app/charles-proxy/id1134218562)が出たらしい

## 3. BeFocused 

最後3つ目は、「Be Focused」というアプリです！

私はスマホアプリ,Macで連携して、使ってます。
とても重宝しています。


https://apps.apple.com/jp/app/be-focused-focus-timer/id973130201



<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">最近ハマっているタスク管理アプリ。<br>良いのは、<br>人間の集中力が最大限に発揮される<br>「25分+5分」(ポモドーロ)<br>のタイマー！<br><br>ポモドーロに合わせてタスクも細かく区切ると<br>- 作業のスケジュールがしやすくなる<br>- 見積もりと作業のズレを知れる<br>- 集中モードに入る練習になる<a href="https://t.co/GmuQPCx0pW">https://t.co/GmuQPCx0pW</a> <a href="https://t.co/ItTI5YYYWP">pic.twitter.com/ItTI5YYYWP</a></p>&mdash; 中野湧仁🌟iOS (@yuto_nakano44) <a href="https://twitter.com/yuto_nakano44/status/1193323909690486784?ref_src=twsrc%5Etfw">November 10, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>



<img width="397" alt="EF96B989-046F-4C3A-ADC7-09F605C86C4D.jpeg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241322/2cf6ad9a-9f1f-bd33-3d60-167452915a64.jpeg">

これを使ってから、集中する時間のムラが減りました！

なにより、疲れ切った脳を無理やり動かして作業するのではなく、潔く休んだ方が生産性高まることを身をもって感じれたことが良かったです。



## まとめ

オススメのツールあるよ！という方いらっしゃいましたら是非教えていただきたいです!

ご覧いただきありがとうございました。
メモ:　RaspberryPi（Buster）にOpenCVをインストール

#pipでインストール

OpenCVのインストール方法は幾通りかあるけど、現時点（2019/12/11現在）で簡単なのは

```
$ sudo apt install libpango-1.0-0 libatk1.0-0 libcairo-gobject2 libpangocairo-1.0-0 libqt4-test 
$ sudo apt install libtiff5 libqtcore4 libwebp6 libavcodec58 libavutil56 libqtgui4 libavformat58 libgdk-pixbuf2.0-0 
$ sudo apt install libgtk-3-0 libilmbase23 libjasper1 libcairo2 libswscale5 libopenexr23

$ sudo pip3 install opencv-python==4.1.0.25
$ sudo pip3 install opencv-contrib-pyhton==4.1.0.25
```

としてインストールする。

もしかすると追加のライブラリはすべて必要ではないかもしれない。

バージョン指定は必須。

最新版（4.1.0.26)だとimport時にエラーが発生する。

動作確認はRaspberryPi3B+　に Raspbian(buster)　の環境

後ほどRaspberryPi4でも確認してみる。

-------------------------------------------------------------------------------------------
追記
-------------------------------------------------------------------------------------------
RaspberryPi4にインストールしてみた。

初期状態から 

```
$ sudo apt update
$ sudo apt upgrade
```

次のモジュールを追加する。

```
$ sudo apt install libqt4-test libqtgui4 libjasper1 libatlas-base-dev libhdf5-dev
```

次にOpenCVのインストールで完了。

```
$ sudo pip3 install opencv-python==4.1.0.25
$ sudo pip3 install opencv-contrib-python==4.1.0.25 （こちらは必要に応じてインストール）
```

次はRaspberryPi Zeroにも入れてみようかな。

-------------------------------------------------------------------------------------------
追記２
-------------------------------------------------------------------------------------------
JBPBさんからの情報です。ありがとうございます。

環境変数を設定することで最新版（4.1.1）を利用できました。

```
$ LD_PRELOAD=/usr/lib/arm-linux-gnueabihf/libatomic.so.1
```

.bashrcの最後に以下の文を追加しておくと起動時に設定されます。

```
export LD_PRELOAD=/usr/lib/arm-linux-gnueabihf/libatomic.so.1
```

これでバージョン指定なしでインストールしても正常にimportできます。

-------------------------------------------------------------------------------------------
追記３　2020/01/15
-------------------------------------------------------------------------------------------
Raspberry Pi WHでもインストールできました。
しかし、まだサンプルは動作させてません。
Node-redで使用する予定です。
HeidiSQLのすゝめ

# なんで書いたの
DBを見るときphpMyAdminからHeidiSQLに変えたら作業が爆速になったので
こんなソフトもあるよとの思いで書きました。
簡単に使えるので試してみてください。

# HeidiSQLって何？
DB管理ソフト

# いいところ・わるいところ
- **長所**
 - 簡単に始めれる！
 - 直感的な操作ができる！
 - データを簡単にいじれる！

- **短所** 
 - うっかり操作が危ないので本番環境では注意
 - 重いと表示に時間がかかるorフリーズする
 - フィルターを失敗したとき対処するのが面倒

# さくっと使ってみよう
 **インストール**
　[HeidiSql](https://www.heidisql.com/download.php)
 
 **起動**
　起動すると下記画面でます
　今回はローカルにつなぎます
　![キャプチャ.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/539246/9b5869d6-5dad-155f-dd46-44fea73c2117.jpeg)
 **画面**
　①でDBとテーブルの選択
　②で入ってるデータの確認
　データの編集・追加はマウスで選択するだけでガシガシできちゃいます
![キャプチャ3.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/539246/d34cdcd8-e82d-7024-65c3-4d842e0712cc.jpeg)

　基本的な使い方は以上！

# おわりに
　・sshトンネルでつなぐ
　・SQL直接叩く
　・DBのCREATE文をコピー
　・フィルター機能
　・選択したデータをcsv/REPLACE/INSERTで吐き出す
　等々色々な便利機能が簡単に使えるので、一度使ってみると作業速度があがるかも？
【備忘録】売上数値を顧客で別で見たときのパレード図をEinstein analyticsで作る

下記を参照にパレード図を作成したところ、パレード図自体は一発で作成できた。

>Einstein Analyticsでパレート図を作る https://qiita.com/haneco/items/f601f43fdb0c840cc1f3 #Qiita

ただ、これだとグループ項目名のデータ数で集計されてしまう。
顧客毎の売上数値を集計して、それでパレード図を作成したかったので、最終的に下記になった。


```
q = load "データセット"; 
q = group q by 'グループ項目名'; 
q = foreach q generate
       'グループ項目名',
        sum(売上項目) as '集計', --売上の合計値を集計とする--
        sum(sum(売上項目)) over([..] partition by all) as '合計',--全ての行の売上合計値を合計とする--
        coalesce(sum(sum(売上項目)) over([.. -1] partition by all order by sum(売上項目) desc), 0) as '累積値';
--売上合計を該当行の一行前の合計値で取得
その際の並び順は売上合計値の降順。ただしnullの場合は0に変更する--
        --sum(sum())を利用することで、グルーピングされていない項目での値集計に対するエラーを回避する--
q = foreach q generate
        'グループ項目名',
        '集計',
        ('累積値' + '集計') / ('合計' + '合計') * 2 * 100 as '比率の累計';
q = order q by '集計' desc;
q = limit q 2000;
```


ただsum(sum())のところ、本当に理由がこうなのかよくわからない。
分かる人いたら教えてください。
Goでの画像生成

この記事は[tomowarkar ひとりAdvent Calendar 2019](https://qiita.com/advent-calendar/2019/tomowarkar)の11日目の記事です。

記事を書く時間が取れず、またストックもないのでどんどんと簡素化していくのがわかりますね笑

今回はGoで640×400のpng画像を生成をしていきます。

# ランダム生成
1. `int Slice` で描画するフィールドを生成(ランダム)
2. 1.を元に`png`ファイル生成
3. ローカル保存

をしていきます。

### コード
```go
package main

import (
	"image"
	"image/color"
	"image/png"
	"math/rand"
	"os"
)

var (
	khaki         = color.RGBA{240, 230, 140, 255}
	darkgoldenrod = color.RGBA{184, 134, 11, 255}
	royalblue     = color.RGBA{65, 105, 225, 255}
	seagreen      = color.RGBA{46, 139, 87, 255}
	width         = 640
	height        = 400
)

func setField() []int {
	field := make([]int, width*height)
	for i := 0; i < len(field); i++ {
		field[i] = rand.Intn(4)
	}
	return field
}

func main() {
	field := setField()
	img := image.NewRGBA(image.Rect(0, 0, width, height))
	for x := 0; x < width; x++ {
		for y := 0; y < height; y++ {
			switch field[y*height+x] {
			case 1:
				img.Set(x, y, khaki)
			case 2:
				img.Set(x, y, royalblue)
			case 3:
				img.Set(x, y, seagreen)
			default:
				img.Set(x, y, darkgoldenrod)
			}
		}
	}
	f, _ := os.Create("./img/image.png")
	defer f.Close()
	png.Encode(f, img)
}
```
### 結果
![image1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235435/60f71072-290e-046e-2d31-814fbb7f5902.png)
# ランダム生成(倍率指定)
これでは少し描画粒度が細かいので、倍率を指定して描画粒度を荒くしていきます。


差分のみの表示なので詳しく知りたい方は[ソースコード](https://gist.github.com/tomowarkar/8877ae34df9e1ae627b51c55ce6d2710)までどうぞ。
### コード
```go

-	width         = 640
-	height        = 400

+	width         = 16
+	height        = 10
+	scale         = 40


-	img := image.NewRGBA(image.Rect(0, 0, width, height))
-	for x := 0; x < width; x++ {
-		for y := 0; y < height; y++ {
-			switch field[y*height+x] {

+	img := image.NewRGBA(image.Rect(0, 0, width*scale, height*scale))
+	for x := 0; x < width*scale; x++ {
+		for y := 0; y < height*scale; y++ {
+			switch field[y/scale*height+x/scale] {
```
### 結果
![image1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235435/4c8cc46e-dead-5ee3-4f40-f77ba6962946.png)

# おまけ
今回紹介したコードを走らせても、同じ画像しか生成されないと思います。
これはフィールド生成の乱数の初期シード値が固定されているためです。

なので以下のように`setField`の関数内で時刻をもとにシード値を設定してやります。
これで毎回違ったフィールドが生成されます。

```go
rand.Seed(time.Now().UnixNano())
```
画像生成時に指定するファイルパスも固定化してしまうと上書きで更新されてしまうので、タイムスタンプを入れることで上書きを防ぎ新たなファイルを作ることができます。

```go
t := time.Now()
timestamp := fmt.Sprintf("%04d%02d%02d%02d%02d%02d",
	t.Year(), t.Month(), t.Day(),
	t.Hour(), t.Minute(), t.Second(),
)
fpath := fmt.Sprintf("./img/image%s.png", timestamp)
```
どちらも詳細は[ソースコード](https://gist.github.com/tomowarkar/8877ae34df9e1ae627b51c55ce6d2710)で!

# おわりに
以上明日も頑張ります！！
[tomowarkar ひとりAdvent Calendar Advent Calendar 2019](https://qiita.com/advent-calendar/2019/tomowarkar)
# 参考
### 画像生成周り
https://yourbasic.org/golang/create-image/
https://golang.org/pkg/image/
### Goでの乱数
https://qiita.com/makiuchi-d/items/9c4af327bc8502cdcdce
### 時間のフォーマット
https://stackoverflow.com/questions/20234104/how-to-format-current-time-using-a-yyyymmddhhmmss-format
Pythonで好きな場所のファイルをimportする方法

##条件
Pythonのバージョンによって?できるものとできないものがあるようです。
いくつか例をあげたので、もし失敗したら他の方法を試してみてください。

##フォルダの構成
```
├─python
| main.py
|
| ├─code
| | |mnist.py
|
| ├─dataset
| | |activation_function.py
```
##やりたいことリスト
1. **main.py**内で**mnist.py**を**import**したい!!
2. **mnist.py**内で**activation_function.py**を**import**したい!!
3. **mnist.py**内で**main.py**を**import**したい!!


##やりたいこと１
**main.py**内で**mnist.py**を**import**したい!!

###方法1

```python:main.py
import sys
sys.path.append("code")
import mnist
```

###方法2
「[Pythonの自作モジュールをimportしたいならsys.pathを設定しよう](https://qiita.com/Anaakikutsushit/items/49d1eff7e5da082edad1)」を参考にさせていただきました。
自分の環境では動作しませんでした。環境によっては動作するかもしれません。


```python:main.py
import sys
sys.path.append("python/code")
import mnist
```

##やりたいこと2
**mnist.py**内で**activation_function.py**を**import**したい!!

###方法1
[ゼロから作るDeepLearning](https://www.oreilly.co.jp/books/9784873117584/)を参考にしました。
自分の環境では動作しませんでした。環境によっては動作するかもしれません。

```python:mnist.py
import sys, os
sys.path.append(os.pardir)  # 親ディレクトリのファイルをインポートするための設定
import dataset.activation_function
```
###方法2
```python:mnist.py
import sys
sys.path.append("")
# sys.path.append("./")でも可能
# sys.path.append(".")でも可能
import dataset.activation_function

```

###方法3

```python:mnist.py
import sys
sys.path.append("dataset")
import activation_function #ちょっと綺麗になる
```
##やりたいこと3
**mnist.py**内で**main.py**を**import**したい!!

**これはわかりませんでした!!可能であるのならば教えてください!!**
まず下のファイルから上のファイルをimportするのはフォルダーの構造として駄目な気がするので、フォルダー構成を見直せ!ということなのかもしれません。
ちなみに以下のことを試してみましたが自分の環境では、動作しませんでした。

```python:mnist.py

import sys
sys.path.append("../")
import main
```

##おわり
紹介した多くの方法がPython2系では動かないと思います。
Python3を使っておきましょう
いくつか動かないのはおそらく親フォルダーの扱いの差だと思うのですが、これはOS(MacとWindows)の差なのかな？あとで検証するかもです。

タイトルの「ファイル」の部分が適切では無い気がしますので、それに置き換わる何かがあればコメントで教えてくださいm(_ _)m
黒い画面がキライな人へ

ターミナルとかシェルとかコンソールとかよくわからんけど、文字がずらずらしててピコピコしてる通称：**黒い画面**。「なんか怖い」とか「なんで使うのかわからない」というのをよく聞くので、そういえばなんで使ってるんだっけ？と思った次第です。ちなみに僕は黒い画面が苦手です。

# そういえば何故
- そもそもGUIが使えないことがある
- マウスポチポチで出来ないことができる（こともある）
- 楽！（なこともある）
- 早い！（こともある）

## GUIが使えない状況とは

コンピューターがディスプレイやマウスとつながっているからアイコンやボタンをポチポチ出来るのですが、つながっていない、もしくはそのマウスを操作できない、という状況があります。インフラの人が触っている所謂サーバーというやつは大体そうです。海外にあったり、そもそも人が立ち入れないところに設置されていたりしますので、遠隔地からコントロールするしかないです。
そういうコンピューターでGUIを使えるようにする仕組みもあるのですが、余計な工数を使って余計なマシンリソースを割くことになるので、あまり好まれません。
ポチポチして出来ることは黒い画面にコマンドを打ち込むことで可能なので、皆さんそうやって済ませています。

## ポチポチで出来ないこととは
いろんなソフトウェアはゲームの裏技のようにたくさんの機能が隠されています。Macもシステム環境設定などでは変更できない項目をターミナルでコマンドを実行する形で変更できるものがあるのは有名です。

エンジニアのお仕事ではインストーラーが配布されていないアプリケーション（的なもの）を使うことがとても多いです。インストーラーが配布されることもありますが、ダウンロード->解凍->インストールなどせずにコマンド1行でインストールできたりしますし、そのリリースを待っているのもナンセンスです。

## 楽？
例えばSourceTreeを使ってGitでコミットする例ですが、
![commit.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546514/c50439c4-5fcc-67e2-c99c-34b7678ea61b.jpeg)
ポチして、メッセージをいれて、ポチですね。他のクライアントでもだいたい同じような感じかと。
コマンドだと、こう。

```
git commit -am 'commit message'
```

この方が楽、って感じる人もいるんです。

## 早い？
Finderで必要なファイルの場所まで、
![ls.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546514/4139e318-bbe5-231e-24fc-0583a2955043.jpeg)
ポチポチポチと。
ターミナルでこう。

```
cd /usr/local/bin
```

この方が早い、って感じる人もいるんです。

## 使う必要がないところでは使わなくてもいい。派

さて、さも万能であるかのように紹介してきましたが、僕はとても苦手です。
なぜかというと、覚えることがとても多く、業務をすべてカバーするのはとても大変だからです。前述のGitではもちろんコマンドを使うほうが早いのですが、僕のように常時コミットしてるわけではない人間にはとてもじゃないですが覚えきれません。[SourceTree](https://www.sourcetreeapp.com/)や[Fork](https://git-fork.com/)などのAppにはよく使う機能はだいたい揃ってます。Git初学者にはこれらのクライアントで触り始めてもらうほうがイメージしてもらいやすいですしウケがいいです。

こちらはDocker初学者におすすめのコンテナ管理App：[Kitematic](https://kitematic.com/)
![kitematic.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546514/c524b29f-2c49-ee6e-fe78-686c72e3568a.jpeg)

また一般的に、GUIを備えたクライアントアプリケーションは情報量が多く、一覧性に優れていることが多いと思います。その道のプロフェッショナルは勘所が働くのですべてが見えている必要はないかもしれませんが、見落としやミスが発生するくらいならこういうものに頼るのも手だと思っています。

## まとめ
一応書いておくと、使いこなす必要はなくとも確実にスキルややれることの幅が広がりますので、チュートリアルや各種ドキュメントなどを読んで、適宜実行できる程度には使えるようになっておくことをおすすめします。
インストーラーのボタンとインストール用コマンドが並んでいる時にターミナルでコマンドを叩いてみる勇気を！

ということで[Heroku cli](https://devcenter.heroku.com/articles/heroku-cli)でもインストールしておきましょうか？

## おまけ
ターミナルとかコンソールとか用語的な話は下記を読むと理解できるかも。
[【初心者向け】シェル・ターミナル・コンソールの違いとは？](https://eng-entrance.com/linux-basic-shell-terminal-console)
【ColdFusion】cfcomponent タグ の extends 属性内には変数を使えない

#cfcomponent タグ の extends 属性内には変数を使えない！

アプリが入っているディレクトリ名'hoge'を後から自由に変更できるように

```cfc:Application.cfc
<cffunction name="onApplicationStart">
  <cfset Application.app_name = "hoge">
</cffunction>
```

なんてやって、ソース内のディレクトリ名部分を`#Application.app_name#`に置換しまくったんですが、継承を使用しているコンポーネントでエラーが出ちゃいました。cfcomponent タグ の extends 属性内には変数を使えないみたいです。

```cfc:example.cfc
<!--- extends属性内に変数が使えない！ --->
<CFCOMPONENT extends="#Application.app_name#.component.MyClass">
```

同じピリオド記法を使う局面でもcreateObjectや、CFOBJECT タグの component 属性なら変数が使えるのに・・・。

#マッピングを使おう！

ググってみたんですが、[Extend a CFC using a relative path](https://stackoverflow.com/questions/287187/extend-a-cfc-using-a-relative-path) でなにやらマッピングするといいみたいなことが書かれていたので以下のようにしてみました。

```cfc:Application.cfc
<cfset This.mappings["/MyApp"]="c:\ColdFusion2018\cfusion\wwwroot\hoge">
```

```cfc:example.cfc
<CFCOMPONENT extends="MyApp.component.MyClass">
```

Application.app_name は使えなかったですが、Application.cfc 内の「hoge」部分を置換すればよいだけなのでこれで解決としました。（目的は Application.cfc 以外を触らずにディレクトリ名を変更することなので）
Ruby on Jetsでserverlessなサービスの運用環境を作ってみた

[Ateam cyma Advent Calendar 2019](https://qiita.com/advent-calendar/2019/ateam-cyma)、16日目です！
トップバッターに続いて本日は [株式会社エイチーム]((https://www.a-tm.co.jp)) のエンジニア @u_minor3110 が務めさせていただきます。
今回はRuby on Jetsの紹介をします。
アプリの開発に時間を割いて、**サーバ運用は楽したい！**という人にオススメだと感じています。

# Ruby on Jetsとは

Ruby on Jetsは**AWSサービスと連携**し、serverlessなサービスを作ることができるRubyのフレームワークです。もちろん開発マシンではAWSサービスを使わずとも開発を行うことができます。
https://rubyonjets.com/
https://github.com/tongueroo/jets

# Ruby on Jetsの個人的に感じた魅力

* severlessでサービスを運用することができるため、アプリの開発に集中ができる
    * サーバのメンテナンスコストが発生しない！
* Ruby on Railsに似ているのでRailsを知っていれば学習コストがかからない
* 料金もEC2を使って運用するより安く済む可能性がある（料金計算自信なし）
    * Lambdaは月100万リクエスト、128MBの
    のメモリを割り当てた場合約37日実行時間分までは無料
    * API Gatewayは月100万リクエストまでは無料だが、超えてくると100万リクエスト毎に$1以上かかるので高いか？
    * S3は月100万リクエストで平均ファイルサイズも5KB程度あれば、$1未満程度
    * CloudFormationは8リソースを使用しており、リリースに2分かかるとして、一日４回、20日リリースを行ったとしても、
        * (8 * 4 * 20 - 1000) + 2 * 20 * 4 * 0.00008 ≒ $1未満
    * 結論、小規模のサービスなら安くすみそうだが、デイリー100万リクエストを超えるようなサービスだと、高くなりそう(´・ω・`)
    * [AWS料金シミュレーター](https://calculator.s3.amazonaws.com/index.html?lng=ja_JP)

# セットアップからAWSへのデプロイはとても簡単

```sh
# gemのインストール
$ gem install jets
# プロジェクトの作成(オプションもrails newと似ている）
$ jets new app --mode=api --no-database
# ディレクトリの移動
$ cd app
# コントローラの作成
$ jets g controller Hellos index
# rackサーバの起動（開発マシンで検証する場合）
$ jets serve
# awsへの本番deploy(IAMのアクセスキーを環境変数として指定する必要があり)
$ jets deploy production
```

# サービスの運用にあたり

### 本番用カスタムドメインの指定

AWS Certificate Managerで証明書を作成し、API Gatewayでカスタムドメインの設定を行う。

### デプロイ権限の管理について

検証環境は誰でも、本番環境にリリースできる人は制限したい。Lambda, S3等への権限がFullAccessでは検証も本番にもデプロイがされてしまう。
例えばS3に対してなら、以下のようにpolicyを指定し、本番用と開発用の権限を別々に作るのが良さそう。

```
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:*"
            ],
            "Resource": [
                "arn:aws:s3:::*-dev-*"
            ]
        }
    ]
}
```

# まとめ

時間が無くてきちんとした運用に乗せられていないですが、リリースまでが本当に簡単だったので、小規模なサービスには使ってみたいと考えています。

# 終わりに

[Ateam cyma Advent Calendar 2019](https://qiita.com/advent-calendar/2019/ateam-cyma)の16日目、いかがでしたか。
17日目は@ouka___さんがseo関連の話をしてくれますのでお楽しみに！

[株式会社エイチーム](https://www.a-tm.co.jp)では、一緒に働けるチャレンジ精神旺盛な仲間を募集しています。

エンジニアで興味を持った方は[cymaのQiita Jobs](http://bit.ly/35E1I08)をご覧ください。

そのほかの職種は、[エイチームグループ採用サイト](http://bit.ly/2XQpd3q)をご覧ください。
Bootstrap 4 のGRID SYSTEMを使ってWebサイトのコラムをレスポンシブ化する

#BootStrapでコラムをレスポンシブデザインにする

HTML, CSSだけだとレスポンシブ化って難しいけど、Bootstrapを使用すると簡単！

##まず【前提】WEBサイトの横幅は12個のBOXでできている

←------------------WEBサイトの横幅-----------------→


| 1 |2 |3|4|5|6|7|8|9|10|11|12| 
|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|:-:|


BootstrapのGrid SystemではWidthが12個のBOXで敷き詰められている。

PC,タブレット, スマホによって、その12個のBOXのうちの何個を使用するかをそれぞれ指定できる。説明難しいからとりあえずコード。



```html:column-responsive.html
<div class="container">
  <div class="row">
    <div class="col-lg-2 col-md-3 col-sm-12" style="background-color:red; border: 1px solid;">
        コンテンツ
    </div>
  </div>
</div>
```

まずdiv class="row（行）"の中にcolumn（列） divを作成する。

ここでポイントが 
①col-lg-2 (PC表示の時は12個のBOXのうち2個のスペース使いますよ)
②col-md-3  (タブレット表示の時は12個のBOXのうち3個のスペース使いますよ)
③col-sm-12  (スマホ表示の時は12個のBOXのうち12個のスペース使いますよ)

つまり
①2/12 = 6分割（6コラム）
②3/12 = 4分割（4コラム）
③12/12 = 1分割（1コラム）
となる。

ちなみにlgはPC、mdはタブレット、smはスマホの表示コラムってしたけど、厳密には横幅のPixcel数で区切っているみたい。

<img width="813" alt="スクリーンショット 2019-12-11 17.50.47.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/161691/9976c329-34c9-4c89-c885-3f903c4dcfed.png">
(BootStrapのHPより抜粋)

レスポンシブ化、Bootstrapを使うとめちゃくちゃ簡単だからとてもおすすめ。
ちなみにコラムのレスポンシブ化するときは、基本的に最初にclass="container"のdivを使うから気をつけてね。

ちなみにこちらが公式ドキュメント
https://getbootstrap.com/docs/4.4/layout/grid/


ちなみに、Bootstrapを使用する時はheadタグの中に下記いれないと使えないからご注意を。

```html:getstarted.html
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">

```


UdemyのAngelaさんの講座でのメモです。（英語だけどめっちゃわかりやすいです！） → [リンク](https://www.udemy.com/course/the-complete-web-development-bootcamp/?deal_code=JPA8DEAL2PERCENTAGE&aEightID=s00000016735001)
TypeScriptをVSCodeでデバッグするための設定

# 概要
Windows 10にて、VirtualBox上で動作しているウェブサイトのTypeScriptコードをVSCode上でデバッグするための設定のメモです。

以下の環境が前提です。

- VirtualBox
    - Ubuntuの最新版が動いている
    - sambaが動作しており、Windows 10とはZ:ドライブを介してソースコードを共有している
- TypeScript

(実際はこの環境以外でも大丈夫なはず)

# VSCodeの設定
以下の拡張機能をインストールします。

- Debugger for Chrome

VSCodeではTypeScriptのソースのあるディレクトリをオープンしておきます(これをワークスペースとします)。

通常はこのようなレイアウトになっているはず。(sampleというプロジェクトの場合)

```
+ sample
    +-- .vscode (←ここはVSCodeの設定、launch.jsonなど)
    +-- node_modules (←ライブラリとか)
    +-- public
    +-- src (←ここにTypeScriptのソース)
```

ワークスペースのlaunch.jsonに以下の設定を行います。

```
{
    // Use IntelliSense to learn about possible attributes.
    // Hover to view descriptions of existing attributes.
    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "type": "chrome",
            "request": "launch",
            "name": "Launch Chrome against localhost",
            "url": "http://localhost:8080",
            "webRoot": "${workspaceFolder}",
            "sourceMaps": true,
            "sourceMapPathOverrides": {
                "webpack:///./*": "${webRoot}/*",
            }
        }
    ]
}
```

以上がミニマムの設定です。

ポイントはこの部分。

```
            "webRoot": "${workspaceFolder}",
            "sourceMaps": true,
            "sourceMapPathOverrides": {
                "webpack:///./*": "${webRoot}/*",
            }
```

souceMapsをtrueにして、sourceMapPathOverridesの、"webpack:///./*"を\${webRoot}（すなわち\${workspeceFolder})に設定し、トランスパイル後のTypeScriptソースと、トランスパイル前のTypeScriptソースを関連付けます。

今回はたまたま、VirtualBox上に環境を作っていますが、Windows 10上で直接yarn serveなどして、デバッグすることも可能なはず。

要はソースマップと実ソースの対応がきちんと設定できていれば良いだけです。
そのために、VirtualBox上の実ソースはsambaなどを利用してWindowsから見られる状態にする必要があります。

おしまい。
エラーメッセージ：SQLSTATE[21S01]

まれにPHPでコードを書く時がありますが、MYSQLでINSERTしたいとき、書いたコードがエラーで動かない。
時間がどんどん過ぎていく。
苛々してさらに進まない。。

なんてことはありませんか？

エラーメッセージ：SQLSTATE[21S01]: Insert value list does not match column list: 1136 Column count doesn't match value count at row 1

カラムの数が間違っている。ってエラーですが、
どこをミスタイプしてエラーを発生しているか調べるの難しいです。

そんな時は、エクセルなどのソフトに各項目を1行ずつ貼り付けて、項目数や入力の間違いないかを確認すると、
以外とあっさり見つけられます。

初心者でもそうでなくても、見つけられない時は、少しいつもと発想を変えて、チェックしてみるとよいです。
面接で「Terraform使えまぁす！」と言えるのはだいたいどのレベル感なのか

# はじめに

- この記事は完全に私見であり、全ての企業様に通じるものではありません
- この記事の内容が最適であるという保証はできません
- Terraformマウントを取りたい目的の記事ではありません
- TerraformでAWSやGCPリソースの構成管理ができる、というスコープを意識しています

## なぜこの記事を書こうと思ったのか

自身がいくつかの企業に「クラウドエンジニア、SREエンジニア」といったロールで転職をする際に
Infrastructure as Code(以下IaC)関連のツールにおける習熟度について、以下のような状況を経験したため整理したかったという動機です。

- あまり深くツッコミを入れられることが無かった
- 面接側になったときもどこまでツッコミを入れるべきか思案することが多かった

## Terraformを使えれば面接を制する？
答えは No です。

IaCやDevOps、CloudNativeといった最近よく聞く耳障りのいい概念が昨今いくつも産まれています。
これらに共通する意味合いとして「特定のツールを使うことがこれらの概念を体現するわけではない、文化として個人からチーム、チームから組織へ伝搬させて馴染ませていくこと」が重要であり、これが出来て初めてこれらの概念を取り入れたと言えます。

話が脱線しましたが、TerraformやAnsibleといったツールは
1. 管理しやすいコードを書ける人が
2. それを使うことで何が美味しいのかを伝えることができて
3. それを導入したプロダクトやプロジェクトに対して、より健全なサポートを行える
ことを成せることが重要です。

そのために、ある程度のレベルというのがどれくらいなのかを主観的に把握することが本記事の目的となります。

## 本題

### 抑えておくと評価されやすい事柄

下記に明示したチェックリストがだいたい埋まる、もしくはより良い方法が頭に浮かびメリットも説明できるという状態であれば
堂々と履歴書に書いたり、自分のリポジトリに公開してもマイナスにはならないのではないかと思います。

#### コードを書くまで

- [ ] インフラ構成図を作れる
- [ ] 通信の流れを簡略化して非技術者に説明できる
- [ ] それぞれのエンドポイントに定義されるポートやプロトコルを明示できる
- [ ] リージョンやゾーンレベルでのネットワーク階層化ができ、技術者に説明できる
- [ ] インターネット通信するトラフィックの暗号化要否を技術者に説明できる

#### コードを書くとき

- [ ] いつ「やっぱ複数環境を同じように作って！」と言われても最小限の対応(workspaceを切り替える等)で作れるよう冪等性を意識する
- [ ] いつ「デフォルトで使用するリージョンとは別のリージョンにも同じように作って！」と言われても作れるよう冪等性を意識する
- [ ] VMのマシンタイプやログの保持期間など差異がある場合は必ずコメントに理由を書く
- [ ] あわせて議論のソースが別途ドキュメントなどにあればURLを書く
- [ ] ローカルマシンで構築する際にプロファイルを切り替える必要がある場合、特に意識しなくても切り替わるようにする
- [ ] 開発環境では必要だが本番環境では不要なリソース(WAFによるIP制限等)などがあれば冗長にならないよう定義する
- [ ] Terraform VersionとProvider Versionを明示し、意図せずバージョンを更新しなければならなくなる状況を避ける
- [ ] 複数人で利用できるようtfstateファイルの管理をクラウド(本番環境や管理環境のオブジェクトストレージ、terraform cloud等)に保存する
- [ ] tfstateファイルを間違って消してしまっても復元できるようバージョン管理する
- [ ] ｖ0.11系以前とv0.12系の差異を知っている
- [ ] 構築するまでに思ったより時間がかかるリソースは一旦手動で構築して terraform importコマンドで補完する

#### コードの内容
- [ ] Data resourceは率先して使うようにする(クラウドベンダー側で変動する情報は特に)
- [ ] Meta Parameterのdepends_onやlifecycleを使うことで構築優先度をコントロールしなければならない場合は使うようにする
- [ ] よく確認する値や参照先を間違えるとまずい値、開発者へよく連絡する値はOutputに定義し、なにかしらの方法ですぐに共有できるようにしておく
- [ ] HCL(Hashicorp Configuration Language)に詳しくない開発者でもなんとなく読み取れるように簡素化して書くことを意識する
- [ ] formatやreplaceなどの関数で値を加工する場合はLocalsで定義しておく
- [ ] gitなどでパスワードのような秘匿情報を管理する場合は、KMSなどで暗号化したファイルをコミットする

## まとめ

ここまでざっくりと自身がTerraformを書いたりコードレビューする際に意識していることを書き出してみました。
もっと考えられることはありますし、プロジェクト内での制約に縛られたコードを書かざるを得ないケースもあると思います。

この記事が数ある構成管理ツールの一つであるTerraformをアピールポイントにしたい求職者の方や、保有スキルとしてチーム開発に溶け込めるか判断したい面接担当者の方に少しでも役立てば幸いです。
ITパス　出力装置(ディスプレイとプリンタ)

#目次　出力装置
1. [ディスプレイ](#1ディスプレイ)
  - 解像度
  2. 色の表し方
  3. ディスプレイの種類と特徴
2. [プリンタ](#2プリンタ)
  - プリンタの性能の見方
     - プリンタの解像度
     - プリンタの印字速度
  - 色の表し方
  - プリンタの種類と特徴

#1. ディスプレイ
コンピュータの処理結果を出力を画面上に出力する。
###・ ディスプレイの「解像度」
ディスプレイは画面上を細かく区切った小さな点の集まりを使って出力する。この小さな点を**ドット**という。区切りが細かければ細かいほど出力結果が滑らかに表現され、このきめ細かさのことを**解像度**という。解像度が高くなるに比例して多くのドットが使えるため、より多くの情報を表現できる。

###・ 色の表し方
ディスプレイの１つのドットの色は、**３つの色の光**を合わせて表現される。この３つの色は光の三原色の**「RGB（Red Green Blue)カラー」**。３つの色が１００％で光ると白が表現できる。

###・ ディスプレイの種類と特徴
ディスプレイには以下のような種類がある。

| ディスプレイの種類   | 特徴 |
|:-----------------:|:-----------------|
| CRTディスプレイ     | **ブラウン管**を使ったディスプレイ。奥行きがあるため邪魔。**消費電力が大きい。** |
| 液晶ディスプレイ     | **電圧**によって液晶を制御する。**バックライトか、外部からの強い光**がないと暗くて何も見えない。薄型で消費電力が少ない。自分のIPhone8にもこれが使われている。 |
| 有機ELディスプレイ   | **有機化合物**に電圧を加えると発光する仕組みを利用したディスプレイ。液晶と違い**自ら発光**するので、**バックライトが不要**でより**省電力**。２０１９年の最新テレビや最新スマホ（IPhoneX等）にも使われている。 |
| プラズマディスプレ   | **プラズマ放電**による発光を利用するディスプレイ。**高電圧が必要**なのでパソコン専用モニタとしてはあまり使われない。 |


#2. プリンタ
コンピュータの処理結果を印刷して出力する。プリンタの性能は、印字品質とその速度によって評価される。
##プリンタの性能の見方
###・ プリンタの解像度（印字品質の見方）
プリンタの場合は、**「１インチあたりのドット数」**の**dpi(dot per inch)**で表す。
数値が大きいほどドットが多く、きめ細かい表現ができる。

###・ プリンタの印字速度
印字速度の見方は
**「１秒間に何文字印刷できるか」**の**cps(character per second)**と
**「1分間に何ページ印刷できるか」**の**ppm(page per minute)**がある。
プリンタの印字方式によって、最適な方を用いて表す。
ドットインパクトプリンタは**cps**、レーザプリンタは**ppm**で表す。([プリンタの種類は後述](#プリンタの種類と特徴))

##プリンタの色の表し方
ディスプレイは光の三原色RGBで表すが、プリンタは色の三原色の**CMYK(Cyan:シアン、Magenta:マゼンタ、Yellow:イエロー、blacK:ブラック)**の**４色**の組み合わせで色を表現する。3原色と言いつつ４色必要。
CMYKだけなぜK(ブラック)が入っているかというと、CMYを１００％で重ねても純粋な黒が表現できないため。

##プリンタの種類と特徴
印刷方式の違う代表的なな３種類がある。

| プリンタの種類       |    特徴 |
|:----------------:|:------------------|
| ドットインパクトプリンタ | 印字ヘッドに多数にピンが内蔵されていて、それで**インクリボンを打ち付ける**ことで印刷する。物理的に打ち付けるので**印字音が大きく**、**印字品質も高くない**。しかし**複写式の伝票**が印刷できるプリンタがこれしかないので、事務処理分野で重宝されている。 |
| インクジェットプリンタ  | 印字ヘッドのノズルから**直接インクを吹き付け**て印刷する。インクのにじみなど、印刷の品質は印字先の紙によって左右される(インクジェット紙等)。基本的には音が静かで高速。**高品質のカラー印刷が安価**にできるので、**個人、家庭用プリンタ**として普及している。基本のCMYKに加えてライトシアン等を入れることによって、写真並みの高画質印刷ができるモデルもある。我が家のプリンタはこれ。|
| レーザプリンタ       | **レーザ光線**を照射して感光体に**1ページ分の印刷イメージ**を作成し、そこに付着しトナー(顔料などから作られた色粒子からなる粉)を紙に**転写**することで印刷する。基本的にはコピー機と同じ原理。ページ単位で印刷するので**高速で音も静か**。**粉を定着させる方式**なのでインクのにじみもなく、**最も高品質な印刷**ができる。**ビジネス用途**のプリンタとして普及している。 |
enebularで値の見えるWebページを作る ~enebularからherokuへのデプロイ~

[enebularで値の見えるWebページを作る（http post版）](https://qiita.com/jksoft/items/7b2373d07b51b14b55fa)の続きの記事になります。
enebularのフローエディタで動作しているフローはあくまで動作確認用の為、1時間で止まってしまいます。
残り時間は右上の!マークのアイコンにマウスカーソルを合わせると確認できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109992/d193aed3-62cd-97de-3b89-58b81f64a23e.png)

（時間が切れた場合は、ページをリロードすれば再開できます。）

そのため、継続的に動作させるWebサービスとして動作させるにはどこかのサーバサービスにデプロイするしかありません。enebularではデバイス以外にも[heroku](https://docs.enebular.com/ja/deploy/deployflow/Heroku/)か[AWS Lamuda](https://docs.enebular.com/ja/deploy/deployflow/Lambda/)へのデプロイをサポートしているので、今回はherokuへデプロイしてみました。

# [heroku](https://jp.heroku.com/)とは
heroku(へろく)とはクラウド上にサーバを構築できるサービスであり、ある程度の範囲であれば無料でwebサイトを構築できるサービスです。
サーバを構築できるだけではなくOSやデータベース、プログラミング言語の実行環境も提供されている「PaaS(パース)」（「Platform as a Service(プラットフォーム アズ ア サービス)」）です。

※herokuの無料で使える範囲は「[無料で試せて月額固定ならHerokuがおすすめ](https://qiita.com/zzzzz/items/3a8efddc910c78655dd5)」が分かりやすかったです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109992/9e35d84c-7eb4-fe8e-af06-88a41ad1a9be.png)


# herokuの準備とenebularからのデプロイ
enebularからherokuへデプロイするには、以下の手順で行います。詳細はenebularのドキュメント「[Heroku へのデプロイ](https://docs.enebular.com/ja/deploy/deployflow/Heroku/)」を参照ください
1. herokuのアカウントを作る（後で設定画面が開きますが、クレジットカードの登録が必要です。プランを変えない限り無料で使えるので、請求はされません）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109992/267b8b4f-5f05-7538-dc7d-e4f89b908138.png)
2. APIキーを調べる![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109992/fa721fdb-0d12-11e1-6e57-d200dbc9ed52.png)
3. enebularのconnectionを作成する![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109992/25bd0fb4-4086-b2dd-32d9-a14f5e47f021.png)
4. herokuのアプリケーションを作り、環境をデプロイする![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109992/08e50914-a7f4-e022-d655-6e4dae407f57.png)
5. フローをデプロイする![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109992/e17d83a1-927d-5358-ac27-e992c7d84c2d.png)

# heroku上でフローを確認する
デプロイしたフローはnode-redごとheroku上にデプロイされるので、フローの編集や確認ができます。
herokuのアプリケーション管理画面からOpen Appをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109992/2897dd26-63fc-7290-3ba3-96e0a5e4478e.png)

enebularのフローエディタと同じ画面が開きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109992/b8d644dc-7c19-b574-4ebd-7330b96bc22a.png)

# フローで動作しているページを開く
http inノードで設定しているURLをherokuアプリケーションのURLの後に足せばフローで動作しているページを開くことができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109992/0cf1c32b-3031-a3a4-d4ff-386d088eb4d8.png)
この場合、URLは以下の様になります。
https://{herokuのアプリケーション名}.herokuapp.com/environment

このフローでは引数で、デバイスを判断しているので、idが1のデバイスの場合は以下のURLで指定すればセンサー情報が見れるようになります。
https://{herokuのアプリケーション名}.herokuapp.com/environment?id=1

スマホで開いたページ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109992/a4e4c6d1-517d-a874-b11b-e4af74099d21.png)

次の記事ではデバイス側のことを書きたいと思います。
PHPでslackにメッセージを送ってみる

#通知をまとめたいと思った
バックグラウンドで動いているPHPの実行通知がメールだったり、ツールの管理画面だったりといろんなところに散らばっているので、どっか簡単に見れるところにまとめたい考えた。
slackを使っているのでそのチャンネルに送れば手軽にチェックできるのでは？と思いやってみた。
#準備するもの
php
curl
slackのチャンネル
php内でcurlが動作さえすればphpのバージョンは問わず。
#実装してみる
##①slack appを検索する
slack内でappから「Incoming Webhook」を検索する。
「appディレクトリで確認する」ボタンを押してアプリのページに移動。
![screenshot-app.slack.com-2019.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546466/4807fbc3-b1f7-35bd-783d-5f8e477249d6.png)
##②「Incoming Webhook」を追加する
チャンネルを選択して「Incoming Webhookインテグレーションの追加」ボタンを押す。
![screenshot-torico.slack.com-2019.12 (1) (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546466/1dbc75af-1146-dd6e-e357-5241d18c1b6b.png)
##③「Incoming Webhook」の設定ページ
アプリ登録後、投稿用のurlやサンプルが表示されます。
基本このサンプルに沿って実装するだけで簡単にできました。
![screenshot-torico.slack.com-2019.12 (3).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546466/f07ba0d6-f5e4-3417-b093-1def1cb69d6f.png)
##④PHPを書く
1.まずは一番簡単な形で送信してみる。
設定画面に表示されたWebhook URLにPOSTリクエストでpayloadパラメーターをJSON形式で送信すればよいらしい。

```
$url = 「設定画面に表示されたWebhook URL」
$message = [
    "channel" => "#チャンネル名",
    "text" => "これはテストです",
];

$ch = curl_init();
$options = [
    CURLOPT_URL => $url,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_SSL_VERIFYPEER => false,
    CURLOPT_POST => true,
    CURLOPT_POSTFIELDS => http_build_query([
        'payload' => json_encode($message)
    ])
];
curl_setopt_array($ch, $options);
curl_exec($ch);
curl_close($ch);
```

2.結果
成功！
<img src='https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546466/7eabdf81-2d6b-69fb-dc3c-2e86e38fb66c.png' width='300px'>

3.少し凝ってみる
デフォルトIncoming Webhookからのユーザー名や画像のなどの変更も可能。

```
$message = [
    'channel' => '#チャンネル名',
    'username' => 'System',
    'icon_emoji' => ':eyes:',
    'text' => 'これはテストです',
];
```

4..もっと凝ってみる
attachmentsを追加してその下に配列としてメッセージ添付ファイルを設定することができる。

```
$message = [
    'channel' => '#チャンネル名',
    'username' => 'System',
    'text' => 'これはテストです',
    'attachments' => [
        [
            'text' => '結果OK',
            'color' => 'good',
            'fields' => [
                [
                    'title' => 'xxxx',
                    'value' => 'xxxx01',
                ],
                [
                    'title' => 'xxxx',
                    'value' => 'xxxx02',
                ]
            ]
        ],
        [
            'text' => '要チェック',
            'color' => 'warning',
            'fields' => [
                [
                    'title' => 'xxxx',
                    'value' => 'xxxx03',
                ],
            ]
        ],
        [
            'text' => '結果NG',
            'color' => 'danger',
            'fields' => [
                [
                    'title' => 'xxxx',
                    'value' => 'xxxx04',
                ]
            ]
        ]
    ]
];
```
<img src='https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546466/7ebb6937-253b-05b1-ed46-105c9bfa44f6.png' width='300px'>

#使ってみた感想
Incoming Webhookのページが親切。
attachmentsを使用することで引用の色を変えたり、複数の値をリストで送れるので通知にはもってこいだとおもう。
元事務職がモデル駆動型アプリを使ってタスク管理を作ってみたの巻～その1～


モデル駆動型アプリってなんかわかりずらいよねーとくにエンティティーとかとかとか…
と思い、最初っから標準に入ってるのでつくろーかなって。
そこで見つけたのがタスク！これなら知ってるｗｗじゃーつくってみよー

##作るの巻
まずは？
エンティティ→標準機能にあるから作らなくてよし！
じゃあ次は？
新規でモデル駆動型を一から作成！
1,サイトマップデザイナーの鉛筆マークを開いてタイトルに「タスク管理」新しいサブエリアにエンティティを追加する
![タスク管理１.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/404009/f824e495-8caa-7b31-c9c3-484b85283aab.png)
2,アプリデザイナーに戻ってコンポーネントのエンティティからタスクを追加する
![タスク管理２.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/404009/b6d9ccc2-0bb8-867a-32e7-c47ed18b978f.png)
3,最後に保存して公開！

#再生してみよーの巻

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">やっとできたー！<a href="https://twitter.com/hashtag/powerapps?src=hash&amp;ref_src=twsrc%5Etfw">#powerapps</a> <a href="https://twitter.com/hashtag/JPAUG?src=hash&amp;ref_src=twsrc%5Etfw">#JPAUG</a> <a href="https://t.co/6YPQRVG3G1">pic.twitter.com/6YPQRVG3G1</a></p>&mdash; さやか (@sayaka121413) <a href="https://twitter.com/sayaka121413/status/1204674597313843200?ref_src=twsrc%5Etfw">December 11, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

#その2の巻

その２はMicrosoftAutomateを使ってplannerに連携してみた！の巻
ちょっとMicrosoft Teamsもはいるかも？
LXDチートシート・関連リンクまとめ



## 関連リンク
- イントロダクション
 - https://linuxcontainers.org/ja/lxd/introduction/
- はじめに - コマンドライン
 - https://linuxcontainers.org/ja/lxd/getting-started-cli/
- LXDドキュメント翻訳プロジェクト
 - https://lxd-ja.readthedocs.io/ja/latest/
- Image server for LXC and LXD
 - https://us.images.linuxcontainers.org/
- LXD - ArchWiki
 - https://wiki.archlinux.jp/index.php/LXD
- 第521回　入門システムコンテナマネージャーLXD 3.0
 - https://gihyo.jp/admin/serial/01/ubuntu-recipe/0521
- 仮想ゲストOSにコンテナのLXDを選ぶ理由
 - https://qiita.com/takaaki_kurihara/items/41bfc2b3253eb8b6a98e

### 私がQiitaに書いた記事
- Ubuntu 18.04 LTSでLXDの初期設定～コンテナ作成～実行まで
 - https://qiita.com/tabimoba/items/85b24544da14483349c4
- LXDでコンテナ作成する時のコマンド（CentOS, Ubuntu, その他)
 - https://qiita.com/tabimoba/items/abb7ee3144567e465016
- LXDコンテナで固定IPアドレスを設定する方法　
 - https://qiita.com/tabimoba/items/8ba2793507d86be261c7
- LXDコンテナからコンテナ外へポートフォワーディング
 - https://qiita.com/tabimoba/items/587f5b3853de9dce8c66
- LXDコンテナやイメージを一括削除する方法
 - https://qiita.com/tabimoba/items/be2013ed0cf8f92376cf
- lxdコンテナをイメージファイル化して、そのままS3バケットへアップロードするスクリプト
 - https://qiita.com/tabimoba/items/f79ce4edf6797ad81a69
- LXD上でDockerを動かす方法　
 - https://qiita.com/tabimoba/items/581f3adb79a9154cc7ce
- LXDでコンテナの環境変数をセットする方法
 - https://qiita.com/tabimoba/items/e23929b5e667ffb564a9
bigqueryの実行履歴取得


bigqueryの実行履歴クエリをまとめて取ってくる

```
$ bq ls -j -n 1000 | sed -e '1d' | sed -e '1d'  | awk '{print $1}' | xargs -n 1 bq show --format=prettyjson -j   | jq -c '[.statistics.startTime, .configuration.query.query, .configuration.query.destinationTable.tableId]'
```
MacBook Pro (16-inch, 2019, Catalina)で辞書.app（Dictionary.app）の英和/和英辞典が使えなくなる不具合の復旧


MacBookを最新機種に更新したのだが、急にウィズダム英和/和英辞典が使えなくなった。

macOS標準搭載のアプリで使用頻度が高い辞書.app。
よりによって英和・和英辞典・・・。

他にもいろんな方が同様なケースを体験されているようで、特に機種やOSのバージョンは関係なさそう。

辞書.appの環境設定画面を開くと、辞書名は正しく表示されているが、チェックボックスを選択できない。


参考にした記事：

[@mybdesignさん「MacBook Pro (16-inch, 2019)で辞書.app（Dictionary.app）の英和/和英辞典が使えなくなった話。」](https://qiita.com/mybdesign/items/72a09ccbbb38a3ec72e2)


参考記事にあるように`com_apple_MobileAsset_DictionaryServices_dictionaryOSX.xml` を調べて、ダウンロードURLを特定し対象のzipファイルをダウンロードできたのだが、その後の手順がうまくいかない。

[ダウンロードURLはこちら](http://appldnld.apple.com/osxassets/058-55450-2016008023-8A4D782E-661F-11E6-B483-D75733D2D062/com_apple_MobileAsset_DictionaryServices_dictionaryOSX/1a184f41ee27bbb203ba596a25c8ea104c13d98f.zip)


そこで、ダウンロードしたファイル内のAssetDataフォルダにある`Sanseido The WISDOM English-Japanese Japanese-English Dictionary.dictionary`を取り出して、ターミナルから `~/Library/Dictionaries/`ディレクトリを開き、辞書ファイルを保存。

```
$ open ~/Library/Dictionaries/
```

<img width="454" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155751/a602cf96-4cec-ef6f-a7b9-d9f009a01ca1.png">

そのままだと参照がうまくいかないようで、なんでもいいので少しファイル名を変更する。
例：`Sanseido The WISDOM English-Japanese Japanese-English Dictionary_copied.dictionary`  (拡張子の前に_copiedを追加）

するとオリジナルの辞書と追加した辞書が同じ名称で環境設定画面に現れた。追加した方はちゃんと選択できるし、検索もできるようになった。

<img width="924" alt="スクリーンショット 2019-12-11 14.17.35.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155751/e46bddca-e1df-1f50-d3a5-0094db11c71d.png">

辞書が使えるようになれば十分なので、このやり方（辞書ファイルの追加）でもいいような気がする。
bsnmpdでetherswitchのmibを拾う

etherswitchのMIBをFreeBSDに標準で入るbsnmpdで拾えるようにしてみました。

スクリプトによる拡張はsnmp_ucd.soが必要で、snmpd.configには以下を追加しました。

```snmpd.config
begemotSnmpdModulePath."ucd" = "/usr/local/lib/snmp_ucd.so"
%ucd
updateInterval = 500
extCheckInterval = 100
extUpdateInterval = 3000
extTimeout = 60

# Extension commands (extTable)

extNames.0 = "rtlswitch"
extCommand.0 = "/tmp/es.rb 0"
```

ターゲットはRTL8366SRで、[mruby-etherswitch](https://github.com/yamori813/mruby-etherswitch)入りのmrubyでスクリプトは以下になります。

extCheckIntervalとextUpdateIntervalの関係はこの図のようになっています。

![snmpext.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104066/fe51d152-1d3d-fa46-b938-c4893b205e47.png)

extCheckIntervalでチェックしてextUpdateInterval間隔で実際のコマンドを実行しています。次のupdateまでwalkへの問い合わせはこの値を返します。

```ruby:es.rb
#!/usr/local/bin/mruby

t = EtherSwitch.new(0)

port = ARGV[0].to_i

off = 0x1000 + port * 0x0040

t.writereg(off, 0)

v = t.readreg(0x11F0)
if v == 0 then
  lo = t.readreg(off)
  hi = t.readreg(off + 1)
  val = hi << 16 | lo
else
  val = 0
end
p val
```

walkしてみます。

```
% bsnmpwalk -s 10.0.1.3 .1.3.6.1.4.1.2021.8.1.101
1.3.6.1.4.1.2021.8.1.101.0 = 13929442
```

いつもの蟹さん仕様で、なにが拾えてるかは謎です。^ ^;

FreeBSDのetherswitchのRTL8366SRのサポートコードは私が作りました。

追記：

snmp_mibII.soを利用するとinterfaceの情報が拾えるようになります。

```
bsnmpwalk -s 10.0.1.1 .1.3.6.1.2.1.2.2.1.16 | awk '{if(NR > 1){printf ","};printf $3}
```

この方法だと、PHYのMIBも拾おうとして、bsnmpdのエラーメッセージが複数でるようです。

```
Apr  4 10:51:00  snmpd[13473]: SIOCGIFDESCR (arswitch0port1): Device not configured
```

OIDを完全に指定して並べるのが良さそうです。

```
bsnmpwalk -s 10.0.1.1 .1.3.6.1.2.1.2.2.1.16.5 .1.3.6.1.2.1.2.2.1.16.6 .1.3.6.1.2.1.2.2.1.16.7 .1.3.6.1.2.1.2.2.1.16.8 | awk '{if(NR > 1){printf ","};printf $3}
```

これでもarswitch0port1のエラーメッセージだけは出てしまうようです。

しばらく動かしていたら数値がオーバーフローしてしまいました。なんらか対策が必要です。
Servicenowがなぜ注目されているのか

#Servicenowが注目されているのかまとめてみた

##ポイント
- 日本法人ができた
　2014年にServicenow Japanが設立された。
　→日本人は海外製品を使いたがらないし、問い合わせが日本語で出来るのは大きい。

- 日本のデータセンターができた
　NTTコミュニケーションズが日本(東京、大阪)を立てた。
　[記事はこちら](https://www.ntt.com/about-us/press-releases/news/article/2018/1017.html)
　→データを海外に置くのは...と抵抗のある経営陣は多いだろう。
　→BCP/DR対策もバッチリ

- 働き方改革
　お金を出すのは経営層。この層が最高に響くフレーズだろう。

---

##追記
2019/12/13
　働く場所を変える技術ばかりが先行して、業務そのものにかかる労働時間を大きく削減できたわけではない。
　Now Platform上でAPPを構築することで、現場業務そのものを変革して本質的な働き方改革が実現可能になる。

経団連が掲げる働き方改革
1. 長時間労働の是正
2. 年次有給休暇の取得促進
3. 柔軟な働き方の促進
この「1.」「2.」をNow Platformを利用することで自動化できるようになる。

---

##終わりに
初めての投稿なので至らない点が多くあるかと思いますが
また記事を投稿できたらなと。

次は、アーキテクチャについて書きたい。
Laravel6 Formファサードでフォームを作る

簡易メモ気味。

# 環境
- Laravel 6.6.1（執筆時点の最新環境）

# インストール

```
$ composer require laravelcollective/html
```

# 組み込み
フォームの大外

```
{!! Form::open(['url' => 'recruit']) !!}
（略）
{!! Form::close() !!}
```
{{ }}ではなく{!! !!}にしてるのは私的趣味（要素を{{ }}で書くから外枠だと強調したい）。

以下、html要素とかクラスについては適宜脳内変換で。

## テキスト、テキストエリア、日付
```
<div class="form-group row">
  {{Form::label('hoge', '（ラベル名称）', ['class' => 'col-md-3 col-form-label'])}}
  {{Form::text('hoge', old('hoge'), ['class' => 'col-md-9 form-control'])}}
  @if($errors->has('hoge'))
    @foreach($errors->get('hoge') as $message)
      <p class="offset-3 col-md-9 alert alert-danger">{{ $message }}</p>
    @endforeach
  @endif
</div>

```
勿論テキストエリアのときは"Form::textarea"、日付のときは"Form::date"で。

受け取りは簡単。とりあえずcontrollerで受け取るとして。

```HogeController.php
$hogemodel->hoge = $request->hoge;
```

## ラジオボタン

```

<div class="form-group row">
  {{Form::label('hoge', （ラベル名称）, ['class' => 'col-md-3 col-form-label'])}}
  <div class="col-md-9 form-inline">
    @foreach(（項目配列） as $key => $value)
      <div class="form-inline">
        {{Form::radio('hoge' , $key , $key == old('hoge') , ['class' => 'form-control' , 'id' => 'hoge_'.$key ])}}
        {{Form::label('hoge_'.$key , $value)}}
      </div>
    @endforeach
  </div>
  @if($errors->has('hoge'))
    @foreach($errors->get('hoge') as $message)
      <p class="offset-3 col-md-9 alert alert-danger">{{ $message }}</p>
    @endforeach
  @endif
</div>
```
配列をforeachで回すやつ。この作りの場合、Formのvalueは配列でのkey値になる。

## チェックボックス（複数選択可）
```
<div class="form-group row">
  {{Form::label('hoge', （ラベル名称）, ['class' => 'col-md-3 col-form-label'])}}
  <div class="col-md-9 form-inline">
    @foreach(（項目配列） as $key => $value)
      <div class="form-inline">
        {{Form::checkbox('hoge[]' , $key , false , ['class' => 'form-control' , 'id' => 'hoge_'.$key ])}}
        {{Form::label('hoge_'.$key , $value )}}
      </div>
    @endforeach
  </div>
  @if($errors->has('hoge'))
    @foreach($errors->get('hoge') as $message)
      <p class="offset-3 col-md-9 alert alert-danger">{{ $message }}</p>
    @endforeach
  @endif
</div>
```
ほとんどラジオボタンと同じ。ただしこれだけ受け取り方が特殊。

```HogeController.php
$hogemodel->hoge = is_array($request->hoge) ? implode( ",", $request->hoge) : $request->hoge;
```
複数選択時は配列で来るので文字列にする。他にも方法はあるはず。

## 単選択プルダウンボックス

```
<div class="form-group row">
  {{Form::label('hoge', '（ラベル名称）', ['class' => 'col-md-3 col-form-label'])}}
  {{Form::select('hoge', （項目配列） , old('hoge'), ['class' => 'col-md-9 form-control'])}}
  @if($errors->has('hoge'))
    @foreach($errors->get('hoge') as $message)
      <p class="offset-3 col-md-9 alert alert-danger">{{ $message }}</p>
    @endforeach
  @endif
</div>
```
こちらは配列を食わせるだけで勝手に生成してくれる。
Livedataの罠:双方向databindingの無限ループ

## 目的
・EditTextの値とSharedPreferenceを連携したい
・EditTextには数字しか入力させたくない
・Livedataを監視し、値を使って処理する

## 想定の実装
EditTextのInputTypeに```number```を指定すれば、数字のみの入力制限は完成です。
さらに、```text```に```@={livedata}```livedataを指定すると、双方向databindingを完成し、画面で修正した内容をそのままSharedPreferenceに保存するはずです！！

## ソースコード
### SharedPreference　
```
fun getSharedPrefValue(): SharedPreferenceLiveData<String> = mPrefs.stringLiveData(PREF_KEY_PARING_INTEGER, "")
```
＊ 参考：[SharedPreferenceLiveDataの作成方法](https://medium.com/@er.abhishek.luthra/sharedpreference-livedata-c621c15f0a4f)

### Livedata
IntのLivedataで連携したいですが、２wayの場合にはうまくできません。
できる方法があれば、ぜひ！コメント欄で教えてください！　

```
var prefValue: MutableLiveData<String> = getSharedPrefValue()
```

### Layout XML
```
<EditText
    android:id="@+id/paring_pref_text"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:inputType="number"
    android:text="@={viewModel.prefValue}"/>
```

## 実行結果

画面が固まって、操作できない！！！

debugして、Livedataの値は無限に変更しているようです。

## 原因

色々試した結果、`inputType`の問題でした。
1.`inputType`に`number`を指定すると、裏で走っている処理より、EditTextの値が変更されました。
2.その変更をLivedata経由でSharedPreferenceへ保存しました。
3.また、SharedPreferenceの変更をLivedata経由で画面に通知し、EditTextの値を変更しました。
4.EditTextの値が変更されたので、1の処理が呼ばれて、ループになってしまいました。

## 対策

双方向databindingの`text="@={livedata}"`をやめるか、inputTypeの指定`inputType="number"`をやめるかの２択しか思いつかない。。。。