OmniAICreator/Qiita-1.07M huggingface dataset:
リモートワークでPMをやる上での気にした点_工数見積もり版

### はじめに

こんにちは。@akr-takaです。
コロナ禍で緊急事態宣言が発生してからは在宅でPMをやってみて半年がたち、
リモートならでは苦労などもありましたので2020年を振り返り、工数見積もりに注目して書いてみました。

### 対象読者

1. 最近プロジェクト管理を始め出した人
1. 最近工数見積もりを出してといわれだした人
1. WBS見てたら工数を出されているけどなんでこんな数字になっているか興味がある人

## 簡単な自己紹介

Web系をメインにJavaやPHPや色々な言語でシステム開発をバック・フロント共に携わっていました。
この数年はアプリ開発を行ったり、アジャイルでの開発をやっていたりしていましたが、
紆余曲折あって今となってはPMでもSEでもPGでも時と場合に合わせて与えられたポジションで
求められる動きをする様になっていました。
子供も7歳と2歳の子供が2人います。

## 結論

今までと同じやり方でやっていたらうまくいくわけがない！！！
これで終わるとこの記事の意味がないのでちゃんと理由を説明します。

## その前に

緊急事態宣言が出る前も半分出社、半分リモートでコード書いたりと
リモートワークには経験があったのですが、やはり子供がいると話しかけられたり
おむつ交換をしないといけない、
日中家にいるということで宅配便がくる、色々な勧誘や営業がくるなど出社している時の様に
自分ではどうしようもない中断があって
集中していい感じにのっているスパートタイムが途切れることもあります。
そういう仕事を会社ではなく家ですることによる弊害という事は事前に経験していました。

## 見積もり時の考え方で変わったところ

大前提としてこちらで提示したスケジュールは守らないといけません。
決めたスケジュールを守れなくなるイレギュラー要素を除外する方がいいのは当然です。
（例：突然入るできれば参加してほしいレベルのMTGや役割以外の作業はなくすなど）
けど、家で仕事しているんだから子供とか介護とか自分ではどうしようもできないイレギュラーは
どうしろっていうんだと思う人もいると思います。
それなら自分たちでは制御できないイレギュラーは発生すると受け入れて工数を見積もったら
精神的にも余裕が生まれて働きやすくなるんじゃないかとなりました。

### 作業時間の確保がバラバラなのを認める

#### 今までの考え方・やり方

* 1日の作業時間を定時（8時間）で考えない
  * 定例の朝会やメールチェック・チャット対応などで1時間は時間を取られるので実質8時間勤務なら7時間しか作業できない
  * レビューを担当している人はレビュー時間も考えて1日の作業時間を考えてあげる
  * 役職者など業務外の工数が必要な人はちゃんと抜いて考える
  * 定例のMTGや勉強会も参加するならその時間は考える

#### 新たな考え方・やり方

* 1日の作業時間は人によって様々。相手の状況を考えて考慮する
  * 子供・介護などで数分間の中断が発生するなど作業効率が落ちてしまう。
      * だからと言って残業をしてちゃんと1日で終わらせて欲しいかというとそうではない。
      （定時内で仕事を終わらせる量にすべき派）
      * とはいえ毎日3時間しか作業できないというのは論点が違うのでそこは話し合う必要があります。
* よくある事例
  * PM「相談なんだけどこれなら簡単な実装だから1日で終わるよね。」
      * Aさん「これなら1日でできますね。」
      * Bさん「（今日は子供を預けれないから集中してできないかも・・・）多分できると思います。」
          * Bさん「普段だったらできるけど今日は子供がよく泣く日で作業が細切れになってちゃんとできなかった。1日で終わるといった手前夜中でも作業しないと・・・」
          * こういう人が出てこない様にその人の状況を考えて作業を見積もってあげると助かる
          * 他の人がフォローしあえるためにも次の項目にもある通り、タスクは細かく考えておくと作業割り振りを柔軟にできます

### タスクは細かく分割する

完成ができるか心配だからと大きく工数を見積もってしまうといざ遅れが発生した時に
原因が特定できず進捗遅れに繋がる事があります。
複数人で作業をしていることも多いかと思いますが、先行タスク・後続タスク・並行タスクに
分けて考えていたらアサインする時に先行タスクはベテラン、後続タスクに若手といった風に
作業を組み立てることができ、バッファも細かいタスク事に見積もるので
遅れが発生してもフォローがしやすいというメリットもあります。
また、チェックポイントが細かく設定することになりますので
遅れを許せる段階なのか、他の人にフォローしてもらう必要がある段階なのかを
考えるという意味でもタスクを細かく分割して見積もる方がいい事があります。
何よりも工数の根拠をお客様やエンジニアの方にするときにも説得力や安心を
与えられるという意味でも利点となります。
デメリットは細かく分割する時に知識や経験がないと無駄に分割してしまって逆に管理が
難しくなる、タスク間の依存関係が大きくなって複数人で作業がしにくくなるなどが
ありますが、そのさじ加減がプロジェクト毎にバラバラなので難しいという点です。

### おまけ：タスク管理ツール
タスクは細かく分割するといってもWBSを細かく分割してしまうと営業の人やお客様に見せた時に
ちょっとした進捗の遅れで突っ込まれることがありえるのでエンジニア以外用と
エンジニア用で分けてタスク管理ツールを分けた事がよかったです。

1. スプレッドシート
  * 主にエンジニア以外向け
  * WBSとしてスケジュール毎のエンドと全体把握用
1. Trello
  * 主にエンジニア向け
  * WBSのタスクを機能分割してカードを登録
  * 不具合が発生した時やTODO事項・リファクタ関連はカードを追加
  * EllegantというChrome拡張機能でWBS風に見れるので後続タスクの繋がり管理

### 最後に

今年は急にリモートワークに切り替わり今までと同じ感覚で仕事をしたくてもできなくなった人も
いたと思います。
ただ、リモートワークになることで働き方が変わることを悪い方向にするのではなく、
プロジェクトメンバーも働きやすくするために進捗を守れるように工数を見積もるところから
しっかりとしていきたいと思います。
映画館の宣伝のような文字が順番に出てくるやつを作る

# どうも7noteです。映画館で最初に流れる予告編のようなテキストを順番に出す処理を実装してみる

![sample.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/661092/ad246319-9406-2c9b-daa3-c90fbfb907e0.gif)
※ちょっと出だし遅いです。気長に待ってください。

javascriptを使い`promise`で順番にjavascriptを処理していくことで表現できています。
テキストをpタグに用意して、それらを順番に表示しています。

それではソースをどうぞ。

※jQueryを使用しています。jQueryてなにそれおいしいの？という方は[こちら](https://qiita.com/7note/items/45bd8efbedd557667218)

## ソース

```index.html
<p id="text01">あの名作が再び帰ってくる</p>
<p id="text02">全世界を熱狂の渦に巻き込んだ<br>あの感動作が</p>
<p id="text03">劇場版になって再び旋風を巻き起こす</p>
```

```style.css
body {
  background: #000;
  display: flex;
  align-items: center;
  justify-content: center;
}

p {
  color: #fff;
  font-size: 30px;
  font-weight: bold;
  display: none;
}
```

```script.js
function action() {
	return new Promise(resolve => {
		setTimeout(() => {
			resolve()
		}, 3000) //3秒後に実行
	})
}


action()
	.then(function(){
	$("#text01").show(); // テキスト1を表示
	setTimeout(() => {
		$("#text01").fadeOut()
	}, 1500)  //フェードアウトを1.5秒後に実行
	return action() 
})
	.then(function(){
	$("#text02").show(); // テキスト2を表示
	setTimeout(() => {
		$("#text02").fadeOut()
	}, 1500) //フェードアウトを1.5秒後に実行
	return action() 
})
	.then(function(){
	$("#text03").show(); // テキスト3を表示
	setTimeout(() => {
		$("#text03").fadeOut()
	}, 1500) //フェードアウトを1.5秒後に実行
	return action() 
})
```


## 解説

正直解説できるほど`promise`については詳しくないのですが、`action()`という関数を作って、この関数を通ってから次の命令を動かすみたいな流れになっています。
そのため、`action()`の中で3秒処理を停止させてから、`resolve()`を実行して次の命令に以降する許可を出しているみたいな感じだと思います。（※間違っていたらすみません）

下の方で`then()`を複数かいていますが、このような書き方をすることで処理をこの順番の通りに実行できます。
最初は1のテキストを表示して1.5秒後にフェードアウト。次は2のテキストを・・・のように順番に処理を書いています。

## まとめ

全く非同期処理について知らないときに似たようなことをsetTimeOutでやろうとして挫折したことがあります。
他にも面白いことに使えそうですね。

※思いつきでやってみたのですが、ソースに無駄な部分があるかもしれません。ご指摘改善等コメントお願いします。

#### おそまつ！
~ Qiitaで毎日投稿中!! ~
[【初心者向け】WEB制作のちょいテク詰め合わせ](https://qiita.com/7note)
laravel error: unknown option ‘--hide-modules’ [webpack-cli] Run ‘webpack --help’

2020年、今年最後の投稿になります。今回のエラーは

```
//ターミナルにて
error: unknown option ‘--hide-modules’ [webpack-cli] Run ‘webpack --help’
```
になります。
ターミナルにて```npm install```の後に```npm run dev```を実行させると下記のエラーが発生しました。
![“スクリーンショット” 2020-12-28 19.04.39.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698439/4ec10ec0-14f4-1aa3-441e-3ea18c6b5184.jpeg)
今回はこちらを解決します。
#エラーの意味
webpackというライブラリに```--hide-modules```というオプションは知らないよという意味でした。
ここで```--hide-modules```を省きたいと思います
#エラー解決 
vs codeにて```--hide-modules```を検索します。すると、2箇所該当箇所が出てきます。
こちらを削除します。
![“スクリーンショット” 2020-12-28 18.42.26.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698439/56dfa7f0-bdd4-a573-8fd3-eaf2fb493f2a.jpeg)
再度npmを再インストールの手順を実行します。
###ステップ１
rm -rf node_modules
インストールされたjsモジュールを全部消す
###ステップ2
rm package-lock.json yarn.lock
インストールされたjsモジュールのバージョン情報を消す
###ステップ3
npm cache clear --force
npmのキャッシュをクリアする
###ステップ4
npm install
npm start
再度jsモジュールを全部入れ直して、実行する
###ステップ5
再度 ```npm run dev```を実行する
最後に下記スクショになるかと思います。
![“スクリーンショット” 2020-12-28 20.45.40.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698439/22b5f682-84fd-58c8-64ce-11d1bc5e3a06.jpeg)
今回のエラーですが下記Githubで議論をしているみたいです。(英訳です)
ご興味のある方はこちらを参照して下さい。
https://github.com/Deguta/ym-portfolio/compare/master...Login-Function
「対数って？なる人向けの記事（たぶん中三～くらいの数学知識）」を参考にWolframAlphaでやってみた。

(オリジナルポスト)

https://qiita.com/okdysk/items/07f176b26fa9f045e8ef


##「f(x)=log2xf(x)=log2⁡x のグラフを脳内でイメージする。」WolframAlphaでやってみた。

https://www.wolframalpha.com/input/?i=log%282%2Cx%29&lang=ja

##常用対数log10は、整数の桁数に使っています。
数値を文字列に変換して、文字数を数えるのが、普通かもしれません。
(参考)

https://mathtrain.jp/ketasu

(参考)?位（くらい）の求値<常用対数<wikipeda。よくわかりませんでした。

https://ja.wikipedia.org/wiki/%E5%B8%B8%E7%94%A8%E5%AF%BE%E6%95%B0
Class構文

## 目的
通常のJSで書いた場合とClass構文で書いた場合の比較

## サンプル
### HTML
```html
<p class="js-button" data-button-id="1">button</p>
<p class="js-button" data-button-id="2">button</p>
```

### 通常のJS
```javascript
const button = document.querySelectorAll('.js-button')
for (const el of button) {
  el.addEventListener('click', e => {
    const number = e.currentTarget.getAttribute('data-button-id')
    console.log(number)
  })
}
```

### Class構文を利用
```javascript
class Button {
  constructor(el) { // 変数を定義
    this.el = el
  }
  init() { // 動作を定義
    this.el.addEventListener('click', e => {
      const number = e.currentTarget.getAttribute('data-button-id')
      console.log(number)
    })
  }
}
const buttons = document.querySelectorAll('.js-button')
for (const button of buttons) {
  new Button(button).init()
}
```

## 結論
簡単な動作の場合はClass構文で書くと記述が増えたように感じてしまう
しかし、変数と関数が見やすくなっているので、挙動が複雑なJSを書いているときにとても便利でした
「パスカルの三角形を描く」を参考にWolframAlphaでやってみた。

(オリジナルポスト)
https://qiita.com/kobachii/items/47f29efd25b522ce9e30
##WolframAlphaで
パスカルの三角形
https://www.wolframalpha.com/input/?i=%E3%83%91%E3%82%B9%E3%82%AB%E3%83%AB%E3%81%AE%E4%B8%89%E8%A7%92%E5%BD%A2&lang=ja
##?誰か以下の「WolframAlphaコード」を解説してもらうと助かります。
Wolfram言語のコード:
CellularAutomaton[{#1[[1]] + #1[[3]] & , {}, 1}, {{1}, 0}, 5]
【2020年大晦日版】CentOSとRedhat、そしてオープンソースということ

# CentOS プロジェクト終了の衝撃

2020年12月、CentOS関連で気になるニュースがありました。

- [CentOSプロジェクトの創始者、「Rocky Linux」プロジェクトを立ち上げ | ZDNet Japan](https://japan.zdnet.com/article/35163796/)

個人的には、ここのところ Debian や Ubuntu を使用するのが殆どで `yum` なんて使ってない。ので Centos のリリースサイクルがちょっと変わったくらい、だろうと思っていた。大体、Fedoraが出た時点でおかしいだろ、と思って Ubuntuに渋々乗り換えた派だし。とはいえ、それだけではない模様で。。。

- [「CentOS」の開発方針変更--ユーザーの声、レッドハットの見方は | ZDNet Japan](https://japan.zdnet.com/article/35163736/)

なるほど、最新のCentOS 8は CentOS Stream に移行するからLTSサポートはCentOS 7までで打ち切り、と言われたら困る。。。やっぱりIBMに買収されたから？そういえば、SunがOracleに買収されてからJavaもMySQLもちょっとアレになってしまったよね。。。ということで、

- [「CentOS」の開発方針変更の背景とは | ZDNet Japan](https://japan.zdnet.com/article/35164295/)

やはり RedHat社においてCentOSは重荷でしかなかった模様です。。。

とは言え、Dockerを始めとするコンテナ技術がメインストリームになり、クラウドはただのサービスからサーバレス化してイベントドリブンなサービスが出てきたり、FacebookやGoogleはデータセンターごと自作してオープンにしてしまうとか、ハードウエアとサービスの用途がどんどん変化しOSの重要性はより一層深まるばかり。

当然、OSという基盤を担うソフトウェアの開発コストとリスクは飛んでもないものだ。それを小さな会社が単独で担う、というのにも限界があるし、確かに VSCode を始めとする Microsoft がリリースするOSSのプロジェクトはなかなかエキサイティングだ。OSS後進組だったからこそ、"ちゃんと狙ってる"感はありますよね。

オープンソースの重要性はここでいうまでもなく、僕らがより良いサービス、プロダクトを提供して行くためにはオープンソースに関わるみんなの力が必要な訳で。
大手だからいい、とか大手だから悪い、というわけではなくこれからもオープンソースを"サステナブル"に活用していくためにはどういうカタチが良いのだろうか、というぼんやりとした感じで今年最後の記事を締めくくりたい。

今年もお疲れ様でした。
Pardot のメールマーケティング (Pardot Lightning アプリケーション) ⇒ メールのテストと送信 (Pardot Lightning アプリケーション)

１．Pardot ユーザーをテストリストに追加すると何が行われますか?
２．A/B テストでの成功を測定するために Pardot で使用される 2 つの条件はどれですか?
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634241/fc9de323-9637-52bc-dfe5-73f8af56d8c6.png)
兵庫県の新型コロナウイルス感染症に関する情報の判断基準の画像からテキスト抽出

兵庫県の[新型コロナウイルス感染症に関する情報](https://web.pref.hyogo.lg.jp/index.html)の判断基準の画像からテキスト抽出する

「現在は感染拡大特別期です」のところテキストかと思ったら画像になっている

![Screenshot_2020-12-31 兵庫県 緊急時用トップページ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/36151/c21423aa-c786-1bde-36b2-53674e45ba8e.png)

## スクレイピング

```python
import requests
from bs4 import BeautifulSoup

from urllib.parse import urljoin

url = "https://web.pref.hyogo.lg.jp/index.html"

headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko"
}

r = requests.get(url, headers=headers)
r.raise_for_status()

soup = BeautifulSoup(r.content, "html.parser")

tag = soup.select_one("div#tmp_contents > p > img")

link = urljoin(url, tag.get("src"))

r = requests.get(link, headers=headers)
r.raise_for_status()

with open("alert.png", mode="wb") as fw:
    fw.write(r.content)
```
## OCR

### tesseract-ocrをインストール
```
!add-apt-repository ppa:alex-p/tesseract-ocr -y
!apt update
!apt install tesseract-ocr
!apt install libtesseract-dev
!tesseract -v

!apt install tesseract-ocr-jpn  tesseract-ocr-jpn-vert
!apt install tesseract-ocr-script-jpan tesseract-ocr-script-jpan-vert
!tesseract --list-langs
!pip install pytesseract
```

### 画像から文字を抽出
```python
import pytesseract

import cv2
import numpy as np

from google.colab.patches import cv2_imshow

# 縁に黒いのが残っているので少し切り抜き
img_bgr = cv2.imread("alert.png")[10:-10, 10:-10]

# グレースケール
img_gray = cv2.cvtColor(img_bgr, cv2.COLOR_BGR2GRAY)

# 色確認
img_bgr[10, 10]

# 画像を確認
cv2_imshow(img_gray)

# 色カウント
black = np.sum(img_gray < 151)
white = np.sum(img_gray > 150)

# 白と黒どちらが多いか確認して黒が多い場合は反転
if white < black:
    ret, thresh = cv2.threshold(img_gray, 150, 255, cv2.THRESH_BINARY_INV)

else:
    ret, thresh = cv2.threshold(img_gray, 150, 255, cv2.THRESH_BINARY)

# 画像を確認
cv2_imshow(thresh)

txt = pytesseract.image_to_string(thresh, lang="jpn", config="--psm 6").strip()

txt
```
人生が変わる拡張機能

拡張機能、使ってますか？

今や(?)ブラウザで出来ることは非常にたくさんで、PCでの体験のかなり大部分をブラウザに使っていると思います。
そんなブラウザで「これができればいいのになー」と思ったときに簡単に新機能を追加できるのが、拡張機能です。本当に重要なものだと思います。

しかし、インストールしてもあまり使わないのはあるあるですよね。
ということで、これがなければ今日は無かったという拡張機能を、毎日使っていて生活の一部になっているもの順に紹介します。

※Chromeを使っているのでFirefoxで同様のものがあるかどうかは分かりません。 まぁ有名なやつはあると思いますし、小さいやつは[まあまあ簡単に移行](https://developer.mozilla.org/ja/docs/Mozilla/Add-ons/WebExtensions/Porting_from_Google_Chrome)できるらしいです。

## [Session Buddy](https://chrome.google.com/webstore/detail/session-buddy/edacconmaakjimmfgnblocblbcdcpbko?hl=ja&a8=PlQKLlknX1T5BcZY0wzBDQ_TRQ7LVcTdjByY1_y_6YuAoJQ4CJQTU1QdU56JTVQP6lC_XDQSKDIqxs00000003166005)
開いているタブの情報を（シークレット含め）ボタン１つで保存して、いつでも元通りに開き直すことができます。
環境・使い方にもよりますが、個人的にはシークレットを常用していて、再起動をたくさんするので、活躍します。

## [Video Speed Controller](https://chrome.google.com/webstore/detail/video-speed-controller/nffaoalbilbmmfgbnbgppjihopabppdk?hl=ja)
全ての、本当に全ての動画の左上に速度調節が出来るボタンが付きます。0.1倍単位でどこまでも減速・倍速できるのがいいんですよね。

## [Stylus](https://chrome.google.com/webstore/detail/stylus/clngdbkpkpeebahjckkjfobafhncgmne?hl=ja)
任意の範囲のURLで、CSSを気軽に追加できます。いつも使っているサイトをカスタマイズしたり、特に邪魔な位置の広告したり。
他の人が公開しているものを入れることもできます。
何より気軽に使えるUIが素晴らしいと思います。

## [Rearrange Tabs](https://chrome.google.com/webstore/detail/rearrange-tabs/ccnnhhnmpoffieppjjkhdakcoejcpbga)
タブの移動をキーボードでできるようになります。


## [View Image](https://chrome.google.com/webstore/detail/view-image/jpcmhcelnjdmblfmjabdeclccemkghjk?hl=ja)
Google画像検索でその画像の直URLに飛べるボタンが追加される拡張機能です。
何故か結構使いました。

## [Octotree](https://chrome.google.com/webstore/detail/octotree-github-code-tree/bkhaagjahfmjljalopjnoealnfndnagc?hl=ja&gl=JP)
GitHubで端にリポジトリ内のファイルビューアを追加します。

## [GitHub Repository Size](https://chrome.google.com/webstore/detail/github-repository-size/apnjnioapinblneaedefcnopcjepgkci)
GitHub上で、リポジトリ全体のサイズ、ファイルのサイズ、ディレクトリのサイズとか表示してくれます。

## [JSONView](https://chrome.google.com/webstore/detail/jsonview/chklaanhfefbnpoihckbnefhakgolnmc)
jsonデータを表示したときに、きれいにしてくれたり・折りたたんでくれたりします。
Web APIを触っているときに陰ながら役に立ってくれます。

## [Narrower](https://chrome.google.com/webstore/detail/narrower/jfjaedekncgddegockpigkkpgkhaoljg?hl=ja)
必要かどうかはモニタ環境にもよると思いますが、左詰めで見にくいサイトとかを強制的に中央寄せにしてくれます。
ソフトウェアのドキュメントとか個人ブログとか、特に英語のサイトで衝動的に使ってます。

## [Custom JavaScript for Websites 2](https://chrome.google.com/webstore/detail/custom-javascript-for-web/ddbjnfjiigjmcpcpkmhogomapikjbjdk)
あまりないかもしれませんが、万が一このサイトにカスタムJS書きたいって時に書けます。今見たらMathJaxのNeo-Eulerフォント強制とかに使ってました。

## [Keepa](https://chrome.google.com/webstore/detail/keepa-amazon-price-tracke/neebplgakaahbhdphmkckjjcegoiijjo?hl=ja)
Amazonの商品の価格変動が見られます。何かと便利。

## その他

Proxy SwitchyOmegaとかも使いたくなるときはあるかも。
Google Translateとかはいちいち紹介してません。Images ON/OFF、Awesome Screenshot & Screen Recorder、Etymonline、Search by Imageとか入ってました。

※あと存在するのかは知りませんが、僕みたいな4GBメモリ環境とかを常用している人は、Chromeがその大部分を占めることになって、自動discard機能が大活躍してくれることになると思うのですが、どうしてもdiscardしてほしくないページがあるときはchrome://discardsでできます。

こうやって見てみるとやっぱり、使うことを意識しなくていい・使いやすいことは大切ですね。効率厨みたくなるのもアレですが、普段から自分が感じた不満に敏感に辛抱強く対処することは、後の自分を何回も助けることになるというのは拡張機能だけに限った話ではないな、と思いました。
SARA-R410MでSoracom Harvestにデータを送る

- SARA-R410Mとは

SARA-R410Mは、LTE Cat.M1に対応したu-bloxのLTEモジュールです。SARA-R410シリーズの中の、SARA-R410M-63Bが、技適を取得していて、NTT DoCoMoとSoftBankが使えるモジュールです。詳細の仕様は、[u-bloxのWebページ](https://www.u-blox.com/en/product/sara-r4-series?lang=ja)を参照してください。ドキュメントは、[こちら](https://www.u-blox.com/en/product/sara-r4-series?lang=ja#tab-documentation-resources)です。

SARA-R410Mを利用しやすくした、ブレイクアウトモジュールが、スイッチサイエンスより発売されています。[こちら](https://www.switch-science.com/catalog/6200/)から詳細を確認できます。



- SARA-R410Mの操作方法

SARA-R410Mは、UARTポートに接続して、ATコマンドで操作操作します。PCと接続する場合は、USB-UARTモジュールを使って接続します。マイコンに接続する場合には、マイコンのUARTポートに接続できます。IO電圧が1.8Vの為、1.8Vではない場合には、レベル変換モジュールが必要です。配線方法については、[スイッチサイエンスさんのブログ](https://mag.switch-science.com/2020/12/03/lte-sara-r410m/)に参考できる情報があります。

ATコマンドのマニュアルは、[こちら](https://www.u-blox.com/en/docs/UBX-17003787)にあります。以下のコマンドの説明では、それぞれのコマンドが説明されているページも記載します。

- Soracom Harvestにデータを送る

Soracom Harvestにデータを送るためのATコマンドを解説します

- 流れ

1. モジュールの設定をする
1. Soracomに接続するための情報を設定する
1. Harvestにデータを送信する

- モジュールの設定をするATコマンド

| 送信ATコマンド | モジュールからのレスポンス           |マニュアルのページ|説明           |
|:-------------------------|:----------------------------|:-----------------|:--------------------|
| AT+UMNOPROF=20           | OK                          | P.68|MNO profile を設定する。20はドコモを示す。         |
| AT+CFUN=15               | OK                          | P.32|module functionalityの設定。15は、MT silent resetを示す。|


- Soracomに接続するための情報を設定するATコマンド

| 送信ATコマンド | モジュールからのレスポンス           |マニュアルのページ|説明           |
|:-----------------------------|:-----|:-----------------|:--------------------|
|AT+COPS=2                     |OK    |P.49  |Operator selection。2は、deregister from network |
|AT+CGDCONT=1,"IP","soracom.io"|OK    |P.138 |PDP context definition。APN設定をします。最初の"1"はIPv4使用を示す |
|AT+UAUTHREQ=1,1,"sora","sora" |OK    |P.157 |接続のための認証情報を設定 |
|AT+COPS=0                     |OK    |P.49  |Operator selection。0は、automatic |
 

- Harvestにデータを送信するATコマンド

| 送信ATコマンド | モジュールからのレスポンス           |マニュアルのページ|説明           |
|:-----------------------------|:-----|:-----------------|:--------------------|
|AT+USOCR=6                          |+USOCR: 0 / OK    |P.212 |TCP socketを開きます。"6"はTCPを示す。ここで帰ってくる0は、使用するsocketを識別するための番号。マニュアル上は"local_port"と呼ばれます。 |
|AT+USOCO=0,"harvest.soracom.io",8514|OK                |P.218 |Socketを接続する 最初の"0"は、先に受け取ったlocal_portの値を利用|
|AT+USOWR=0,28                       |@                 |P.219 |socketにデータを書き込みます。最初の"0"は、local_portの値。次の28は、次の行で送信するデータの長さ(Byte数)を記載する |
|{"data1":1.23,"data2":4.567}        |+UUSORF: 0,3      |N/A   |Harvestに実際に送信するデータです。記載方法は、[Harvestのマニュアル](https://dev.soracom.io/jp/start/harvest/)を参照してください。戻り値の最後の"3"は、Soracom側から戻ってきたデータの長さです。次のコマンドで利用します。\"などのエスケープシーケンスはこの行では使えません。
|AT+USORD=0,3                        |+USORD: 0,3,"201" |P.223 |Socketからデータを読み込みます。最初の"0"は、local_portの値。次の3は、先に取得した、Soracom側から戻ってきたデータの長さを記載します。 |
|AT+USOCL=0                          |OK                |P.217 |Socket を閉じます。


以上のコマンドを利用することで、Soracom Harvestにデータを送信できます。
超個人的に選ぶ、PCとかサーバーにつけたらカッコイイ名前大特集！

#マシンに名前を付けて愛でるのはエンジニアの常識
もはや相棒と言っても過言ではないPCやサーバー。
カッコイイ名前が付いてた方が話しかける時にテンション上がりますよね！効率もアップするはずっ！

囚人番号みたいな『PC0001』じゃちょっと味気ない…。
（囚人番号はそれはそれでカッコイイけど）

ということで、独断と偏見で『カッコイイ名前』を選んでみました！

毎日をこんな感じで過ごせるようにね！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/6bb825be-3204-fdff-06bc-2a8e4370b4e5.png)

#「メルキオール」「バルタザール」「カスパー」

* Melchior
* Balthasar
* Casper

脳みそみたいな人工知能入ってそう！
ハッキングされて自爆を提唱しそうで怖い！
でもその『リスクに身を晒してる感じ』がエッジが効いててイイ！

マシンが3台ピッタリの時限定だけどね！
まんまエ〇ァンゲリオンです！

[参考サイトさん](https://ja.wikipedia.org/wiki/%E6%9D%B1%E6%96%B9%E3%81%AE%E4%B8%89%E5%8D%9A%E5%A3%AB)

#とにかくフランス語
話しかけるのが多い人なら **響き** がいいフランス語がオススメ！
言葉の意味までサラッと解説できればカッコよさに拍車がかかること間違いなし！

[フランス語のおしゃれな言葉の参考サイトさん](https://monpetitcahier.com/archives/7407.html) からジュテームな感じのをピックアップしてみました！

| 名前 | 読み方 | 解説 |
|:-----------|:------------|:------------|
| Chanter　| ションテ | 『歌を歌う』という意味。 **軽快な感じ** がカッコイイね！『ちゃんたぁ』なんて読み間違いしちゃった人に向かって人差し指で『ノンノンノン』ってたしなめるところまで一通りの流れ！ |
| Doux | ドゥー | 『甘い、柔らかい』という意味。マシンを **可愛がってる感** が出ますね！『X』が入ってるのもポイント高い！（Xは無条件でカッコイイ文字） |
| Espoir | エスポワール | 『希望、期待』という意味。『ポワ』とかすっごいフランス語感が出ててGOOD！ **未来を作る最先端** なマシンって雰囲気を持たせたい時はコレ！ |

#星座の名前
『無限ループ』という言葉があるくらいなので、エンジニアと宇宙には密接な関係があります。（偏見）

星座の名前を付けたマシンをLEDでピカピカにデコレーションすれば、もうそこはプラネタリウム！

[神秘的な星座の名前の参考サイトさん](http://name-site.net/contents/seiza.php) からロマンティックなのをピックアップしてみました！

| 名前 | 読み方 | 解説 |
|:-----------|:------------|:------------|
| Monoceros | モノケロス | **一角獣座** ！めっちゃセキュリティに強そう！『攻撃してきたハッカーを返り討ち⇒ハッカーのマシンから火花と煙が』 まで容易に想像できますね！ |
| Crux | クルックス | 『X』の文字が入ってるのでまずは無条件でカッコイイ！ **南十字座** っていうのも、なんか十字架を連想してカッコイイね！ |
| Carina | カリーナ | 竜骨座（りゅうこつざ）！**竜** の **骨** だよ！？これ以外に何があるの？って感じ！ドラゴンが出てきちゃった時点でもうカッコよさ125%オーバー！ |

#旧約聖書の登場人物
説明不要！

[旧約聖書の登場人物](https://ja.wikipedia.org/wiki/%E8%81%96%E6%9B%B8%E3%81%AE%E7%99%BB%E5%A0%B4%E4%BA%BA%E7%89%A9%E3%81%AE%E4%B8%80%E8%A6%A7) からいくつかピックアップしてみました！

| 名前 | 読み方 | 解説 |
|:-----------|:------------|:------------|
| Adam | アダム | **創られた最初の人間** 。もうこの意味だけでカッコよさの疼きが止まらない！初めて買うPCの名前はこれで決定！ |
| Noah | ノア | ノアの箱舟で有名なノアです！最後の砦的なサーバーにつけてあげたい名前！ **「ノアが悲鳴を上げたということは、いよいよだな…」** ってセリフを吐けるよ！ |
| Tarach | テラ | ストレージ系を司っている子につけたい名前！ |

#悪魔の名前
ダークサイドに堕ちてしまったエンジニア向け！
闇の名前は付けた瞬間に障害を起こしそうでスリル満点！

不吉な名前も何のその、むしろ自分を逆境に追い込むのが大好きな ~~ドM~~ 向上心の高い人はぜひ挑戦してみてね！

[悪魔の一覧](https://ja.wikipedia.org/wiki/%E6%82%AA%E9%AD%94%E3%81%AE%E4%B8%80%E8%A6%A7) は眺めるだけでも結構面白いです！

#あたいの家の子はこんな感じだよ
| 名前 | 読み方 | 解説 |
|:-----------|:------------|:------------|
| YUKA | ユカ | ルーター。 |
| CERA | セラ | CentOSサーバー。 |
| RENA | レナ | 携帯電話。 |
| MIKA | ミカ | Windowsデスクトップ。 |
| KANA | カナ | Macデスクトップ。 |
| RARA | ララ | Windowsノート。 |
| TICO | ティコ | 外付HDD。（プライマリファイルサーバー） |
| RICO | リコ | 外付HDD。（セカンダリファイルサーバー） |
| VICO | ヴィコ | ウォークマン。 |

4文字。
OSを持ってる系な子は『A』で終わる感じ。
ストレージ系な子は『CO』で終わる感じ。
名前に特に意味は無いです。**響きがいい感じ** ってだけで付けてます！

#蛇足
クラス名でも関数名でも、命名規則って大事だと思います。
最近は『名前の抽象度』と『名前を連結する順番』に気を付けています。

抽象的すぎる名前はパッと見で何の機能か分からないし、誤認識する可能性高い！
例えば **Do（実行）** っていう名前にしてしまうと **『何がどう実行されるのか』** が分からない…。

連結する順番については、ファイル削除という機能は **FileDelete** か **DeleteFile** どっちがいいだろう？とか色々考えます…。
UnityでLocalizationした値をScriptから取得する方法

現在Preview版のLocalization Packageを使って多言語対応する際に、
スクリプトからローカライズされた値を取得する方法が見つからなかったのでメモです。

async/await版で書きましたが、イベントハンドラに登録する書き方もできると思います。


```C#
    var table = await new LocalizedStringTable { TableReference = "stringTable" }.GetTable().Task;
    Debug.Log(table.GetEntry("CHANNEL_NAME").GetLocalizedString());
```

公式ドキュメントは以下です。
https://docs.unity3d.com/Packages/com.unity.localization@0.9/api/UnityEngine.Localization.LocalizedStringTable.html
yarn start時にポートが既に使われている場合の対処法

ReactNativeでの開発をする際に、yarn startまたはnpm startで起動したら下記のエラーが出たので対処法を。
##エラー内容

`.error listen EADDRINUSE: address already in use :::8081. Run CLI with --verbose flag for more details.・・・
`
これは起動時に使おうとしたポートがすでに使われているので競合して起動できないときに起こる問題です。

##解決法
起動したいポートのPIDを調べkillしてあげましょう。

```
//ポートのPIDを特定する
lsof -i :8081

//消去
kill -9 PID
```

または、使われていないポートを指定してstartさせるのでも解決できます。
[Elixir]EnumerableというProtocol

Elixirのソースコードに関数を追加したいと思ってコードを追いかけていたら `Enumerable`というモジュールらしいものが出てきたのでなにか調べてみた。

追いかけてたら突如出てきた `Enumerabe.slice`

```elixir
2163  def random(enumerable) do
2164    result =
2165      case Enumerable.slice(enumerable) do
```


## なぞ :thinking: 

ElixirにはEnumモジュールが存在するのになんでいるのか？
最初これがわからなかった。
IExでこのコードを試してみたところこんな結果になった

```elixir
iex(2)> Enumerable.slice([1,2,3])
{:error, Enumerable.List}
iex(3)> Enumerable.slice(%{a: 10, b: 20})
{:ok, 2, #Function<0.84261211/2 in Enumerable.Map.slice/1>}

```

なんだぁお前？？ :eyes: 

## 結論
結論は [Protocol](https://hexdocs.pm/elixir/Enumerable.html) だった。

ProtocolというのはElixirSchoolさんによると以下のようなものです。

> プロトコルはElixirにおいてポリモルフィズムを獲得する手段です。 

ちなみにEnumerableは以下の関数を持っているといいらしいです。

- count(enumerable)
  - Retrieves the number of elements in the enumerable.

- member?(enumerable, element)
  - Checks if an element exists within the enumerable.

- reduce(enumerable, acc, fun)
  - Reduces the enumerable into an element.

- slice(enumerable)
  - Returns a function that slic

## Functionに実装されたEnumerable.reduceの話

この[enum.ex](https://github.com/elixir-lang/elixir/blob/master/lib/elixir/lib/enum.ex)を見ているとだいぶ下の方に `defimpl`の項目が出てくるのですがそこに `Function`に対して実装した部分があるんですよね :thinking: 

```elixir

3992 defimpl Enumerable, for: Function do
3993  def count(_function), do: {:error, __MODULE__}
3994  def member?(_function, _value), do: {:error, __MODULE__}
3995  def slice(_function), do: {:error, __MODULE__}
3996
3997  def reduce(function, acc, fun) when is_function(function, 2), do: function.(acc, fun)
3998
3999  def reduce(function, _acc, _fun) do
4000    raise Protocol.UndefinedError,
4001      protocol: @protocol,
4002      value: function,
4003      description: "only anonymous functions of arity 2 are enumerable"
4004  end
4005 end
```

なんだこれ :thinking: 
確かに `count`, `member?`, `slice`, `reduce`関数を満たしているけど実際に実装されてるのは `reduce`関数だけ.. :thinking: 

ちなみに使ってみるとこんな感じ

```elixir
iex(8)> Enumerable.reduce(fn acc, f -> Enum.map(1..10, & f.(&1, acc)) end, [], fn n, acc -> acc ++ [n] end)
[[1], [2], [3], [4], [5], [6], '\a', '\b', '\t', '\n']
```
僕の想像力ではなんとなく2次元配列を良しなにreduceできるのでは :thinking: とか思ったりするんですが詳しいことはよくわからん...
もし詳しい使い方をご存じの方おられたら教えて下さい :bow:
Ruby on Railsで「"application.js" is not present in the asset pipeline」エラー

YouTubeでRuby on Railsのアプリ製作の動画を見ながら、ローカル環境で学習中に表題のエラーが発生したため記録としてまとめます。

ログアウト機能実装時に
`ActionView::Template::Error: The asset "application.js" is not present in the asset pipeline`
とjavascriptのファイルが存在しないエラーが発生しました。

調べると原因はrailsのバージョン違いによるものでした。
動画上では開発環境が、`rails : 5.2.4.1`であり、Javascriptのフォルダは
`app/assets/javascripts/application.js`

しかし、rails6では
`app/javascripts/application.js`
と場所が違いました。

ails5.xでのビューファイルhead内は
`<%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>`
となっているため以下のように変更し、正常にapplication.jsが読み込まれるようにし解決しました。

```application.html.erb
<%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
```

ローカル環境では初めてのアプリ製作であった為、何も分からず動画に従い　`rails new [プロジェクト名]`を実行し、最新のバージョンで始めたのが原因でした。
UITextField で英数字のみ入力可能にする

UITextFieldDelegate の shouldChangeCharactersIn メソッドで、許容したい文字以外があった場合に テキスト変更できない False を返します。



```swift
    
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
    if string.count > 0 {
        var allowedCharacters = CharacterSet(charactersIn: "abcdefghijklmnopqrstuvwxyz1234567890_") // 入力可能な文字
        allowedCharacters.insert(charactersIn: " -") // "white space & hyphen"
              
        let unwantedStr = string.trimmingCharacters(in: allowedCharacters) // 入力可能な文字を全て取り去った文字列に文字があれば、テキスト変更できないFalseを返す。
        if unwantedStr.count == 0 {
            return true
        } else {
            return false
        }
    } else {
        return true
    }
}
```

```swift
class ViewController: UIViewController, UITextFieldDelegate {

    override func viewDidLoad() {
        super.viewDidLoad()
        textField.delegate = self
    }

..........
}
```

Falseを返すときに「英数字のみ入力できます」といったラベルを表示してもいいですね。

🐣
****
フリーランスエンジニアです。
お仕事のご相談こちらまで
rockyshikoku@gmail.com

Core MLを使ったアプリを作っています。
機械学習関連の情報を発信しています。

[Twitter](https://twitter.com/JackdeS11)
[Medium](https://medium.com/@rockyshikoku)
【Vue.js】Vuetifyのv-data-tableのフッタ－に選択数を無理矢理表示する

# 概要
以下、Vue.jsのUIライブラリである[Vuetify](https://vuetifyjs.com/en/)の話です。
`v-data-table`のフッターにテーブルで選択している選択数を表示したかったときのメモです。
力技での暫定対応に近く正常に表示できない可能性がありますので参考程度でお願いします。



# 方法


```vuejs:
<template>
  <v-data-table
    v-model="selected"
    :headers="headers"
    :items="desserts"
    :single-select="singleSelect"
    item-key="name"
    show-select
    class="elevation-1"
  >
    <template v-slot:top>
      <v-switch
        v-model="singleSelect"
        label="Single select"
        class="pa-3"
      ></v-switch>
    </template>
  </v-data-table>
  <div class="table-footer-prepend d-flex pl-2 align-center">
    選択：{{selected.length}}
  </div>
</template>

<script>
.table-footer-prepend {
  margin-top: -58px;
  height: 58px;
  color:black;
}
</script>

```
`v-data-table`のコードは[公式のRow selection](https://vuetifyjs.com/en/components/data-tables/#row-selection)のサンプルです。

`<div>`でつけたclassの`.table-footer-prepend`に対してcssを効かせテーブルの`v-data-footer`にあたる部分に被せて表示しています。
各々の開発デザインによって`v-data-footer`の高さに応じてcss側の数値を変える、ユーザの表示する環境、画面のリサイズ等でずれる可能性を否定できない力技です。
`v-data-footer`のslot等でスマートにできると思っていたのですが、パッと見できなさそうだったのでごり押ししました。
Splunk 表を集計して変換する

結構大変だったので

#課題
https://community.splunk.com/t5/Splunk-Search/How-to-maintain-latest-value-for-multiple-values-of-a-field/m-p/534543/highlight/true#M151059

HOST|	VALUE
|:--|--:|
Host1|	1
Host2|	4
Host3|	2
Host2|	7
Host3|	5
Host1|	8
を

HOST|	VALUE|	LATEST
|:--|--:|:--
Host1|	1|	Host1-1
Host2|	4|	Host1-1,Host2-4
Host3|	2|	Host1-1, Host2-4, Host3-2
Host2|	7|	Host1-1, Host2-7, Host3-2
Host3|	5|	Host1-1, Host2-7, Host3-5
Host1|	8|	Host1-8, Host2-7, Host3-5
にする。

ホスト毎最後の値を一覧にしたいとのこと。
#Code
```java:table.spl
| makeresults
| eval _raw="HOST	VALUE
Host1	1
Host2	4
Host3	2
Host2	7
Host3	5
Host1	8"
| multikv forceheader=1
| table HOST VALUE
| rename COMMENT as "this is your sample. from here, the logic"
| reverse
| streamstats count
| reverse
| eval tmp=count."_".HOST."_".VALUE
| streamstats values(tmp) as tmp
| streamstats count as session
| mvexpand tmp
| rex field=tmp "\d_(?<HOST>\w+)_(?<VALUE>\d)"
| streamstats first(VALUE) as VALUE by session HOST
| eval tmp2=HOST."-".VALUE
| streamstats first(HOST) as HOST first(VALUE) as VALUE values(tmp2) as LATEST by session 
| stats values(LATEST) as LATEST by session HOST VALUE delim=","
| fields - session
| nomv LATEST
```
#解説
- `latest()`を自動的にするために`reverse`して`streamstats count`で番号をつけてあげると、後ろに出てくる値が小さな数になってくれるので、`reverse`で戻すと後に出てきた値が上になってくれる。
- `stresmstats values()`で値をまとめたものを作ってあげて、`mvexpand`で分割する。
- `rex`でまとめた値から`mvexpand`で広がった値を上書き。
- また`streamstats first()`で元の表の値を作成。
- 後は`stats`で元の表を*session*を元に作成し、`nomv`で一列にしてあげている。

#まとめ
マルチバリューの整列をする時、できることが少ないのでこれだけの手数が必要になりますね。

なんに使うんでしょうね、この表　:sweat:
CakePHP - Finderを使ったJOINの仕方

#この記事について
CakePHPであるテーブルにWHERE句付きのテーブルをJOINさせたい場合、いろいろやり方があると思います。が、今回はAssociationを使ってなるべくCakePHPが推奨するやり方でデータを取得する方法を示したいと思います。

##CakePHPの推奨するやり方
CakePHPでは、[Association](https://book.cakephp.org/3/en/orm/retrieving-data-and-resultsets.html)でObjectごとの関係を示し、[contain()またはmatching()](https://book.cakephp.org/3/en/orm/retrieving-data-and-resultsets.html)を使ってデータを取得するやり方がおすすめされています。

公式によれば、matching()はprimary modelのデータを制限したい時に使われ、contain()はassociationでprimary modelのものではないデータを取りたい時に使うように設計されています。場合によって使い分けましょう。

##ケーススタディ
例を使った方がしっくりくると思うので、以下のようなシチュエーションを想定します。
作りたい機能：「アクセスしたユーザーの書いた記事のカテゴリ一覧」
テーブル：`categories`, `articles`　（以下参照）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/464595/3453bff6-9b83-355b-ba42-1616219b0c47.png)


例えばアクセスしたユーザーのIDが「１」である場合、赤字のカテゴリーのみが取得されるようにFinderやテーブルを定義していきます。

##アプローチ
STEP1. ArticlesTableでログインユーザーに紐づく記事だけを取得されるようなFinderを定義。
STEP2. CategoriesControllerで、ログインユーザーに紐づく記事のカテゴリを取得。

###STEP1
STEP1はメインではないので割愛します。ぶっちゃけこのケーススタディ程単純な例であれば、[Dynamic Finders](https://book.cakephp.org/3/en/orm/retrieving-data-and-resultsets.html#dynamic-finders)を使ってArticlesを絞ることもできます。
`public function findArticlesOfUser(Query $query, array $options)`のような物を定義したとします。

###STEP2
STEP１で作ったFinderを使えば、ログインユーザーに紐づく記事だけを取得できるので、そこで絞られたArticlesに紐づくカテゴリを取得します。今回の目的は「Primary ModelであるCategoryをSecondary ModelのArticleを使って絞りこむ」ことであるため、`matching()`を使用するのが適切です。「Primary ModelであるCategoryからSecondary ModelのArticleを取得する」であれば`contain()`が適切でしょう。正直、仕様によってはどちらでも問題なく動くことがありますが、CakePHPを理解した上でコードを書く分にはどちらが良いかを考えた方が良いでしょう。
CategoriesControllerは以下のようになります。

```php:CategoriesController.php

    public function index()
    {
        $categories = $this->Categories->find()
            ->matching('Articles', function (Query $q) {
                 return $q->find(
                     'findArticlesOfUser',
                     ['user' => $this->Authentication->getIdentity()]
                 );
            });

         //...あとは省略

```
【Java】LinkedHashMapクラスの使い方

# プログラミング勉強日記
2020年12月31日
LinkedHashMapクラスの使い方を簡単にまとめる。

# LinkedHashMapクラスとは
　HashMapクラスと同じように情報をキーとバリューのペアで格納して使う。LinkedHashMapクラスはHashMapクラスを継承しているので、HashMapクラスが持つ機能を持っている。HashMapクラスは要素の順番を保障しないが、LinkedHashMapクラスは格納された順番を保持している。

　特徴としては、キーとバリューのペアで要素を保持し、キーの重複を許可しない。nullをキーやバリューとすることができる。要素が格納された順番を保持する。

# 使い方
　要素の追加のメソッドは、java.util.HashMapクラスで実装されているメソッドで、サブクラスのLinkedHashMapクラスも同じメソッドで要素の追加を行う。
　要素の取得のメソッドは、引数で指定したオブジェクトをキーに持つバリューを返す。キーがLinkedHashMap内になければnullを返す。

```java:基本的な書き方
// 要素の追加
public V put(K key, V value)

// 要素の取得
public V get(object key)
```

# 参考文献
[Java LinkedHashMapの使い方のサンプル](https://itsakura.com/java-linkedhashmap)
[JavaのLinkedHashMapクラスの使い方を現役エンジニアが解説【初心者向け】](https://techacademy.jp/magazine/22165)
[クラスLinkedHashMap<K,V>](https://docs.oracle.com/javase/jp/8/docs/api/java/util/LinkedHashMap.html)
第十三回講義メモ

\![Mac OS X-10.15.7](<https://img.shields.io/badge/MacOSX-10.15.7-brightgreen>) \![ruby-2.6.3p62](<https://img.shields.io/badge/ruby-2.6.3p62-brightgreen>) 


# thor

いくつかの振る舞いを一つのコマンドに持たそうとすると，オプションなどを適切に扱う必要が出てくる．そのためにいくつかのCLI builder gemsがある．これはRakefileに似たDSLで実現できる.

まずは,

    gem install thor

次に以前作ったhello\_rubyにcliのinterfaceを組み込む.

```ruby
require 'thor'
require "hello_rudy/version"

class HelloRudyCLI < Thor
  desc "hello NAME", "say hello to NAME"
  def hello(name)
    puts "Hello " + name
  end
end

HelloRudyCLI.start(ARGV)
```

CLIという文字列がclass名の最後にないと動かない.


# rubocop紹介

これはcode formatterとかlinterと呼ばれる類のツールらしく, 規約通りにコードが書かれているかをチェックしてくれる便利ツール.

    gem install rubocop
    rubocop --auto-correct fibonacci.rb


# 参考サイト

<https://qiita.com/daddygongon/items/19e58f757fab197bc347>



------
 - **source** ~/my_ruby/grad_members_20f/members/drop-sd/lectures/no13.org
Next.js で LIFF を使ってUserIDを取得する

LIFF( https://www.npmjs.com/package/@line/liff )で`window`が使われているので普通に`import liff from '@line/liff'`とすると怒られます。思いついた選択肢は、

1. `next/dynamic`( https://nextjs.org/docs/advanced-features/dynamic-import )でなんとかする。
2. `useEffect`で`import('@line/liff')`する。
3. npmパッケージを使うのは諦めて、`_document`でCDNから落とす。

今回は2でやってみました。

https://github.com/moeyashi/nextjs-with-liff
SQLとは

### ★SQLとは

「Structured Query Language」の略
直訳すると「構造化問い合わせ言語」

データベース言語の一つで、データベースの定義や操作を行うことができる

ISO（国際標準化機構）で規格が標準化されているので
一度学習すればほかのデータベースでもほぼ同じように操作可能！

コンピュータ言語のひとつだけど、プログラミング言語ではない。
リレーショナルデータベース(RDB)のデータを操作するための言語

→データの登録、検索、削除...等ができる

### ★データベース言語であるSQLの基礎知識や言語の種類、特徴などについて

* SQLはデータベース言語で、最も普及している言語の一つ
* データベース言語はデータを管理して、ユーザーが指定した条件に合致するものを見つけ出すた めのもので、それ以上の機能はない
* プログラミング言語はソースコードに命令を順番に記述して実行するのに対して、SQLはシンプルな命令文を一方的にデータベースに送るだけ
colorizeと正規表現

![ruby-2.7.1p83](<https://img.shields.io/badge/ruby-2.7.1p83-brightgreen>) 

# colorize

colorizeを使うとターミナルで出力する文字に色をつけることができる。

例えば、

```ruby
require 'colorize'

def assert_equal(expected, result)
  if expected == result
    puts 'true'.cyan
  else
    puts 'false'.magenta
  end
end

assert_equal(1, 1)
```

とするとtrueがシアン、falseがマゼンタの色になって表示される。

# 正規表現

Rubular(<http://rubular.com>)はRubyベースの正規表現エディタである。正規表現を書く際にテストとして試すことができる。

例えば、test string として

    Hello world!

と入力し、regular expression(正規表現)の部分に

    \s(.+)

などと入力すれば

    world!

のみが抽出できる。

実際にプログラムに書く前にチェックができるのは便利だと思った。

------
 - **source** ~/grad_members_20f/members/o-michika/3-regular-expression.org
djangoのsetting.pyについての初心者のメモ

###
今回書いていくものはdjango3です。特にいじるものについて書いていこうと思います。ちなみにDjangoを勉強し始めてまだ１ヶ月でプログラミング初心者なので間違っている点などあれば訂正お願いします。
勉強の進み次第随時追加していきたいとおもいます。

##BASE_DIR , SECRET_KEY, DEBUG 
Path(__file__).resolve() = 今あるファイルの場所を示しています。
resolve ...絶対参照でするという意味
.parent fileの１階層上の指定

デフォルトのBISE_DIRは何を表しているの？→ manage.pyのある階層を指定している。

SECRET_key ...　暗号化で使われる秘密鍵を指定しています。startprojectを実行した際にランダムで使われる文字列で、他人に知られないようにしないといけない。

DEBUG ...　デバックモードにするか否かというものです。
下のような画面になるときはTrueになっているため、本番環境ではFalseにする必要があります。

![スクリーンショット 2021-01-01 17.44.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/764631/abbb1f0e-1e11-8204-29cd-a40aa9acaf13.png)


##INSTALLED_APPS
参考になる記事
公式のドキュメントですとこちらも読んでいました。
https://docs.djangoproject.com/ja/3.1/intro/tutorial02/
こちらの下記の記事はとても参考になりました。（但し、django2の記事である点は注意）
とほほのWWW入門
http://www.tohoho-web.com/django/settings.html
記事にもある通り、デフォルトでは６っつのよく使うアプリがインストールされるように指示されています。
'django.contrib.admin',管理サイト
'django.contrib.auth',認証システム
'django.contrib.contenttypes',コンテンツタイプフレームワーク
'django.contrib.sessions',セッションフレームワーク
'django.contrib.messages',メッセージフレームワーク
'django.contrib.staticfiles',ファイルの管理フレームワークです。
ちなみに、自分でstartappコマンドでappを追加した場合など、自分で自由に追加することができる(とおもいますたぶん）



##root_urlconf
Djangoがアクセスした際どのファイルを経由してURLを参照するのかを書いているコードで、基本的に初期設定のままで良い

##templates
→dirs=・・・ テンプレートが入っている場所を指定するもの.manage.pyと同じ階層にテンプレートフォルダを作っているならば、"DIRS" =[BASE_DIR /"templates"]で指定できる。

WSGI_APPLICATION 立ち上げる際に使うファイルを指定するもの。特にいじらないと思う。

databases 
データベースの指示。初期設定ではSQLLITEになっている。

AUTH_PASSWORD_VALIDATORS
パスワードがきちんと条件をみたいしているかを確認するもの

LANGUAGE_CODE
言語設定する際にいじるもの（基本ja)

TIME_ZONE
地域設定をいじるもの（時間関係で）
static_url
画像ファイルやCSSの設定をしていくもの。
第十一回講義メモ

\![Mac OS X-10.15.7](<https://img.shields.io/badge/MacOSX-10.15.7-brightgreen>) \![ruby-2.6.3p62](<https://img.shields.io/badge/ruby-2.6.3p62-brightgreen>) 


# オブジェクト指向

特に, 

-   隠蔽(capsulation)
-   継承(inheritance)
-   多形(polymorphism)

に焦点を当てる.


# class

```ruby
def puts_hello name
  puts "Hello #{name}."
end

def gets_name
  name = ARGV[0] || 'world'
  return name
end

name = gets_name
puts_hello name
```

以前使ったこのコードに置いて, main loopを消すためにクラス化する.

```ruby
class Greeter
  def initialize
    @name = gets_name
    puts_hello
  end

  def puts_hello #salute
    puts "Hello #{@name}."
  end

  def gets_name
    name = ARGV[0] || 'world'
    return name.capitalize
  end
end

Greeter.new
```

    > ruby hello_class.rb

上記で実行すると, 同じで結果を吐くことが確かめられた.


# 継承

以下サンプルコード.

```ruby
require 'colorize'

# method
def hello(name)
  "Hello #{name}."
end

# inherited class
class Greeter < String
  def hello
    "Hello #{self}."
  end
end

# extend class
class String
  def hello
    "Hello #{self}."
  end
end

# method call
name = ARGV[0]
puts hello(name).green

# inherited class call
greeter = Greeter.new(ARGV[0])
puts greeter.hello.green

# extend class call, override
puts ARGV[0].hello.green
```

上記のコードにおける, class Greeter < String部分が継承にあたる.


# 参考サイト

<https://qiita.com/daddygongon/items/969ad5112878f6dab844>



------
 - **source** ~/my_ruby/grad_members_20f/members/drop-sd/lectures/no11.org
iPhone/iPad で IoT（ Inkbird iBS-TH1の温湿度をAzure IoTHubに送信）

# Send Inkbird iBS-TH1 data to Azure IoTHub
**プロジェクトの概要：** iPhoneを経由して、プローブ付きのセンサーデータ（温度、湿度、日時、緯度経度）をAzure IoTHubに送信する。
[githubのプロジェクト](https://github.com/mesgar/inkbird)

**利用シナリオ：** 車やトラックなどで移動するとき、温湿度及び位置情報を（ゲートウエイなしで）iPhone経由でAzure IoTHubに送信して可視化や蓄積する。
今回は温度・湿度センサー情報を送っているが、ソースコードを変更すればどんなBLE（CO2濃度センサー、ガスセンサー等々）デバイスの情報が送られる。
スマートファクトリーやスマートオフィスにはBLE対応のIoTゲートウエイの使用を推奨。

Azure PowerBIと連携すれば、ほぼリアルタイムで位置情報とセンサー情報をマップ上に可視化できる。
![PowerBI](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/967700/a14f0638-4efb-4c4e-fcf9-a4c2d45b8c28.png)




イメージ図：

![イメージ図](https://github.com/mesgar/inkbird/blob/main/image.png?raw=true)

## Build
1. git clone https://github.com/mesgar/inkbird/ inkbird</br>
2. cd inkbird</br>
3. pod install</br>
![スクリーンショット](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/967700/fe50943f-d289-dfd0-b889-21740a685a30.png)

4. open [inkbird.xcworkspace] with xcode and build</br>
<font color="red">上手くいかなかった場合、下記の更新期ドキュメントを参照する。
[クイック スタート:デバイスから IoT ハブへのテレメトリの送信 iOS](https://docs.microsoft.com/ja-jp/azure/iot-hub/quickstart-send-telemetry-ios)


## Settings
1. Add [NSBluetoothAlwaysUsageDescription] [Wants to use bluetooth] to plist.info
実デバイスで許可されたらこんな感じになる
![スクリーンショット 2020-12-31 16.42.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/967700/cc4eacdf-38ae-7131-8075-7e1a6b3fc03a.png)
2. Set your IoTHub Connection string in ViewController.swift 

``` swift:code
    //Put you connection string here
    private let connectionString = ""
```
シミュレーターで実行できないので、実デバイス（iPhone/iPad)で実行する必要がある。
Startボタンを押したら１分おきにセンサーのデータを読み込んで、Azure IoTHubに送信する。
Macの基本コマンド

よく忘れるので備忘録として記事を残します。

<h1>cdコマンド</h1>

```
$ cd ~/  #ホームディレクトリに移動する
$ cd ..  #一つ上の階層のファイルに移動する
```

<h1>pwdコマンド</h1>

```
$ pwd  #カレントディレクトリのパスを表示する
```


<h1>mkdirコマンド</h1>

```
$ mkdir sample #空のディレクトリを作成
```

<h1>touchコマンド</h1>

```
$ touch /sample/sample.html #空のファイルを作成
```

<h1>lsコマンド</h1>

```
$ ls    #カレントディレクトリにあるファイルやディレクトリを表示
$ ls -a #隠しファイルも含めファイルやディレクトリを全てを表示
$ ls -l #ファイルやディレクトリの詳細も同時に表示
```

<h1>mvコマンド</h1>

```
$ mv sample.html bin/  #sample.htmlというファイルを相対パスでbin/に移動
$ mv sample.html sample_app.html  #sample.htmlというファイルをsample_app.htmlに名前変更
```

<h1>rmコマンド</h1>

```
$ rm sample.html #ファイルを削除
$ rm -r sample   #ディレクトリを中身ごと削除
$ rm -f sample   #ファイルを警告なしで削除
$ rm -rf sample  #ディレクトリを中身ごと警告なしで削除
```

<h1>sourceコマンド</h1>

```
$ source ~/.bash_profile  #ホームディレクトリにある.bash_profileに書き込んだ設定を読み込み有効にする
$source .bash_profile  #カレントディレクトリにある.bash_profile設定を読み込み有効にする
```
第十回講義メモ

\![Mac OS X-10.15.7](<https://img.shields.io/badge/MacOSX-10.15.7-brightgreen>) \![ruby-2.6.3p62](<https://img.shields.io/badge/ruby-2.6.3p62-brightgreen>) 


# Recursion


# 例題

フィボナッチ数列を求める.

    fib(n) = fib(n-1)+fib(n-2)
    0 1 1 2 3 5 8 13 21 ...


# fib(0) = 0

Fibonacci数列の初項は0まずは, 関数にしてしまう.

```ruby
def fib(n)
  if n==0
    return 0
  end
end

前回作ったassert_equal.rbのassertionで出力と期待値が一致しているかどうか確認
#+begin_src ruby
require './assert_equal'
puts assert_equal(0, fib(0))
```

結果

    expected :: 0
    result   :: 0
    succeeded in assert_equal.


# fib(1) = 1

n = 1の時を確認.

```ruby
require './assert_equal'

def fib(n)
  if n==0
    return 0
  end
  if n==1
    return 1
  end
end
assert_equal(0, fib(0))
assert_equal(1, fib(1))  
```


# fib(2) = fib(1) + fib(0) = 1

```ruby
require './assert_equal'

 def fib(n)
   if n==0
     return 0
   end
   if n<=2
     return 1
   end
 end
[[0,0],[1,1],[2,1]].each do |index, expected|
  puts assert_equal(expected, fib(index))
end
```

配列の受け取りをより明示的にする/.

    index, expected = pair

と修正できるので,以下のように修正

```ruby
[[0,0],[1,1],[2,1]].each do |index, expected|
  puts assert_equal(pair[1], fib(index))
end
```


# fib(3) = 2 = fib(2) + fib(1)

以下コード.

```ruby
def fib(n)
  return 0  if n==0
  return 1  if n<=2
  return fib(2) + fib(1)
end
```


# 最終形

    fib(2) = fib(1) + fib(0) = 1 + 0

上記が抜けているため, if文の条件分岐をもう少し狭める.

最終的に, 

```ruby
require './assert_equal'

def fib(n)
  return 0 if n==0
  return 1 if n==1
  return fib(n-1) + fib(n-2)
end

[[0,0],[1,1],[2,1],[3,2],[4,3],
[5,5],[6,8],[7,13],[8,21]].each do |index, expected|
  puts assert_equal(expected, fib(index))
end
```

結果 

    > ruby fobonacci.rb
    expected :: 0
    result   :: 0
    succeeded in assert_equal
    expected :: 1
    result   :: 1
    succeeded in assert_equal
    expected :: 1
    result   :: 1
    succeeded in assert_equal
    expected :: 2
    result   :: 2
    succeeded in assert_equal
    expected :: 3
    result   :: 3
    succeeded in assert_equal
    expected :: 5
    result   :: 5
    succeeded in assert_equal
    expected :: 8
    result   :: 8
    succeeded in assert_equal
    expected :: 13
    result   :: 13
    succeeded in assert_equal
    expected :: 21
    result   :: 21
    succeeded in assert_equal
    expected :: 34
    result   :: 34
    succeeded in assert_equal

上手く動作したことがたしかめられた.


# 参考サイト

<https://qiita.com/daddygongon/items/1bb27b8920c201d5c520>



------
 - **source** ~/my_ruby/grad_members_20f/members/drop-sd/lectures/no10.org
1week GameJam に参加して、Unity WebGL Build で色々ハマった話

作ったのはこちら

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">Unityroom の1week GameJam 参加してみました！<br>まだまだ完成度は上げられる状態ですが、一週間ではここまででした…<br><br>とあるESPの異界録(ラノベ感) | フリーゲーム投稿サイト <a href="https://twitter.com/hashtag/unityroom?src=hash&amp;ref_src=twsrc%5Etfw">#unityroom</a> <a href="https://t.co/HnCWQKKcVa">https://t.co/HnCWQKKcVa</a> <a href="https://twitter.com/hashtag/unity1week?src=hash&amp;ref_src=twsrc%5Etfw">#unity1week</a></p>&mdash; GoldenDuck (@Duck2Golden) <a href="https://twitter.com/Duck2Golden/status/1344325264361152512?ref_src=twsrc%5Etfw">December 30, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>


# 起こったエラー色々

かなり局所的な内容になりますが。

## 新Input System でエラー

全然動きません（＾ω＾）
自分は速攻諦めましたｗ
おそらくまだ非対応なのでしょう。


## Cinemachine 関連でエラー

こちらでも言われていたエラーです。

[unityroom 質問掲示板](https://question.unityroom.com/?qa=53/unityroom%E3%81%AB%E3%82%A2%E3%83%83%E3%83%97%E3%83%AD%E3%83%BC%E3%83%89%E3%81%97%E3%81%9F%E3%81%8C%E5%AE%9F%E8%A1%8C%E6%99%82%E3%82%A8%E3%83%A9%E3%83%BC%E3%81%8C%E8%A1%A8%E7%A4%BA%E3%81%95%E3%82%8C%E3%81%A6%E9%81%8A%E3%81%B9%E3%81%AA%E3%81%84)

確かに Cinemachine を削除したら動きました。
ただ単独で動いていたときもあったような…？

Cinemachineを使ったゲームを使っている方もいるようです。

他のエラーも起こったところを鑑みると、初期化周りに問題が起きやすいと思ったほうが良さそうです。
しっかり初期化処理を遅延できるようにコードを組んだほうが良さそう。


## OnJointBreak2D が何故か発生してエラー
テスト実行ではなんの問題のなかったが、WebGLビルドして、ブラウザ実行すると発生。
特に何も使ってないイベントが発生しエラーしているようで困った…。

MonoBehaviour の中でもレアすぎるイベント。
怪しいところを探ったところ、UniRxでユーザーのissue で追加されているのを見つけ、
UniRxを外したところ…動いた。

そもそも惰性で書いていた Observele.everyUpdate が既に非推奨になっており、
メンテナンスされてない可能性が高いかなと思っているが…。
ともかく使ってはいけなかったものだった。

ということで、UniRxは使わずに動いています。


## rendering without using requestAnimationFrame for the main loop.

ビルドしてみたところ、WebGL側で発生していたエラー

```
Looks like you are rendering without using requestAnimationFrame for the main loop.
You should use 0 for the frame rate in emscripten_set_main_loop in order to use requestAnimationFrame, as that can greatly improve your frame rates!
```

なるほど。わからん(^ω^)
で、調べてみたところ、以下のようなスレッドが。

https://forum.unity.com/threads/rendering-without-using-requestanimationframe-for-the-main-loop.373331/
『
デフォルトの設定 Application.targetFrameRate = -1 が最適です。
これは、パフォーマンスが適切である限り、60hzの同期アップデートを提供します。
』

確かに、Application.targetFrameRate=60　を指定しているところがあるが…。
<B>試しにコメントアウトしたところ、エラー発生せず…。</B>

なにかしら描画更新に関するエラーのようだ。

で、自分のプロジェクトを見てみると…怪しいやつがいました。
RenderTexture、こいつが怪しいのではないかと目星をつけています。
まあ演出のために、割とめちゃくちゃやってるからね！　仕方ないね！

副次的に、Application.targetFrameRate = -1 が最適。
指定はしない方向で解決するのが良さそう。


## 突然、RangeError: Maximum call stack size exceeded　が出る

これはブラウザのキャッシュの問題でした。
キャシュの削除をして解決。
ただjs自体あまり再帰呼び出しに強くない構造のようなので、ガッツリ再帰呼び出しするようなコードは気をつけたほうが良さそうです。

# 総じてWebGLする上での教訓

1. 新InputSystem は使わない。まだ動かないよ！
1. フレームレートは指定しないほうが良いので、レートに依存しないコードを書く（30〜144Hzを考慮して書く。）
2. 初期化処理は詰め込まない！Start,Awakeであまり処理を書かない！

今回期日に間に合わせるために雑にコードを書きましたが、それが原因もあるので悩ましいところですね。
Cinemachine 動かなかったのは悔いが残るなぁと。

特に初期化処理周りはエンジニアの領分ですし、ちゃんとこなしたいところですが…。
時間短縮のために ObjectPool 使ってなかったりしたので、あまり良くなかったですね。
（むしろ使ってなくてもまあまあ動いてしまうのが怖いところ）

綺麗にかける時間と設計の時間があればよいのですが、
やはり、<b>期間内に適切なボリュームのものを作る</b>ことが大切ですね。
第九回講義メモ

\![Mac OS X-10.15.7](<https://img.shields.io/badge/MacOSX-10.15.7-brightgreen>) \![ruby-2.6.3p62](<https://img.shields.io/badge/ruby-2.6.3p62-brightgreen>) 


# assert\_equal

今回の題材はテスト駆動用の根幹となる, assert\_equalです.まずは1==1から始めてみます.

code

```ruby
p 1==1
```

結果

    > ruby assert_equal.rb
    true

これをテスト用のメソッドに置き換えると, 

```ruby
def assert_equal(expected, result)
  return expected == result
end

p assert_equal(1, 1)
```


# Colorize

```ruby
require 'colorize'

def assert_equal(expected, result)
  if expected == result
    puts 'true'.green
  else
    puts 'false'.red
  end
end

assert_equal(1, 1)
assert_equal(1, 2)
```

出力結果が, 緑や赤に変化した.


# Richer output

出力をもう少し見やすくする.

```ruby
require 'colorize'

def assert_equal(expected, result)
  puts "expected :: #{expected}"
  puts "result   :: #{result}"
  if expected == result
    puts "succeeded in assert_equal".green
  else
    puts 'failed in assert_equal'.red
  end
end

assert_equal(1,1)
assert_equal(1,2) 

```


# clear code

重複している箇所を個別に分けて関数に書き換える.

```ruby
require 'colorize'

def puts_vals(expected, result)
  puts "expected :: #{expected}"
  puts "result   :: #{result}"
end

def assert_equal(expected, result)
  puts_vals(expected,result)
  if expected == result
    puts "succeeded in assert_equal".green
  else
    puts 'failed in assert_equal'.red
  end
end
```


# 重複実行の予防

```ruby
require './assert_equal'

assert_equal(2, 1*2)
assert_not_equal('bob', 'bob2')
```

しかし, 今のままだとassert\_equal.rbに書いたテストがそのまま実行されてしまう.それを回避してくれる便利な熟語があるらしい.

```ruby
if $PROGRAM_NAME == __FILE__
  assert_equal(1, 1)
  assert_equal(1, 2)
  assert_not_equal(1, 2)
  assert_not_equal(1, 1)
end 
```

これを踏まえて, まとめると以下のようになる.以下の内容は覚えておく!!

```ruby
require 'colorize'
def puts_vals(expected, result)
  puts "expected :: #{expected}"
  puts "result   :: #{result}"
end
def assert_not_equal(expected, result)
  puts_vals(expected, result)
  print expected != result ?
  "succeeded in #{__method__}.\n".green :
    "failed in #{__method__}.\n".red
end
def assert_equal(expected, result)
  puts_vals(expected, result)
  print  case expected == result
     when true  ; "succeeded in #{__method__}.\n".green
     when false ; "failed in #{__method__}.\n".red
     end
end

if $PROGRAM_NAME == __FILE__
  assert_equal(1, 1)
  assert_equal(1, 2)
  assert_not_equal(1, 2)
  assert_not_equal(1, 1)
end
```


# 参考サイト

<https://qiita.com/daddygongon/items/f6cea87314ee26e130ea><https://qiita.com/Mutakouki7595/items/1f3e59fad4aa187a7431>



------
 - **source** ~/my_ruby/grad_members_20f/members/drop-sd/lectures/no9.org
heroku DBをclearDBからjawsdbに入れ替える話

## 入れ替えた経緯
- herokuにデプロイしたWEBアプリのDBにcleardbで使用
- 一つのテーブルにtimestamp型のカラムが複数あり、それぞれデフォルト値をCURRENT_TIMESTAMPに設定し利用しようとすると、問題発生。
- cleardbのMySQLバージョンが5.5.6より低いため複数カラムにデフォルトCURRENT_TIMESTAMPが設定できない
- そのため、バージョンを指定できるjawsdbに入れ替えた。

## 手順
herokuにアプリが存在していることを確認。

```
heroku apps
```

heroku configでDB_NAMEを確認

```
heroku config
```

cleardbで作成したデータベースの削除

```
heroku addons:destroy cleardb --confirm あなたのアプリの名前
```

（ゴミ掃除として）cleardbの設定を削除

```
heroku config:unset DATABASE_URL
heroku config:unset CLEARDB_CRIMSON_URL
heroku config:unset CLEARDB_DATABASE_URL
```

jawsdbを作成

```
heroku addons:create jawsdb:kitefin -a fpl-official --version=8.0
```

追加された環境変数をmysql2用に書き換え。

```
# before (heroku config実行)
JAWSDB_URL:               mysql://~

# コマンド
heroku config:set JAWSDB_URL="mysql2:~"

# after
JAWSDB_URL:               mysql2://~
```


事後確認

```
# ~は伏せ字
% heroku config       
=== あなたのアプリの名前 Config Vars
DB_HOSTNAME:              ~
DB_NAME:                  ~
DB_PASSWORD:              ~
DB_PORT:                  3306
DB_USERNAME:              ~
JAWSDB_URL:               mysql2://~
LANG:                     en_US.UTF-8
RACK_ENV:                 production
RAILS_ENV:                production
RAILS_LOG_TO_STDOUT:      enabled
RAILS_SERVE_STATIC_FILES: enabled
SECRET_KEY_BASE:          ~
```

ローカル環境でテスト環境にDB作成。ridgepoleを使用

```
bundle exec ridgepole -c config/database.yml -E test -f db/Schemafile --apply
```

ローカル環境でテスト環境に投入

```
bundle exec rails db:seed RAILS_ENV=test
```

herokuにDBデプロイ。ridgepoleを使用

```
heroku run 'bundle exec ridgepole -c config/database.yml -E production -f db/Schemafile --apply' --app あなたのアプリ名
```

seedファイルの内容を初期レコードとして投入

```
heroku run rake db:seed
```