OmniAICreator/Qiita-1.07M huggingface dataset:
日英字幕同時表示で技術と英語を動画学習する。

TOEIC300-600ぐらいの人向けです。
リーディング、リスニング、シャドーイング、リピーティング等が簡単にできます。

## 最新技術と英語を同時に動画学習してみる。
（技術動画は専門用語以外平易な英語が使われている場合が多いです。）

紹介するサイト
CaptionPop
https://www.captionpop.com/

英語と日本語の同時表示（非表示選択可）で動画で英語を学習します。
（最初の設定として、トップページで母国語と学習したい言語を選択する必要があります。）

実際の例
Firebaseの学習をしてみます。
Cloud Functions for Firebase の学習（動画シリーズ）
https://firebase.google.com/docs/functions/video-series/?hl=ja

このシリーズのうちの1つを実際に使ってみます。
Firecasts - TypeScriptを使って Cloud Functions for Firebase を始めよう
https://www.youtube.com/watch?v=DYfP-UIKxH0

この動画を
CaptionPop
https://www.captionpop.com/
というサイトに動画のURLを入力すると動画が再生されます。

実際の例
https://www.captionpop.com/videos/DYfP-UIKxH0

https://www.youtube.com/watch?v= **XXX-XXX**
https://www.captionpop.com/videos/ **XXX-XXX**
この **XXX-XXX** 部分がYoutubeと対応しています。

これで動画を見ながら最新技術と英語を学びます。

## 更に便利にするために。其の1
PCから利用する時にはコントローラーを使ってみます。
JoyToKey
https://joytokey.net/ja/
を使ってボタンにキーを割り当てます。

実際の例
上 上カーソルキー
下 下カーソルキー
リピート 右カーソルキー
一時停止 左カーソルキー
日本語一時表示 ○ボタン
（JoyToKeyのトグル機能 自動連射・トグル入力設定欄の「押すたびにON/OFF切り替え（トグル）」にチェック。）

英語と日本語を同時に表示していると、日本語の方に目がいってしまうので英語パートを何度も聞き返してから日本語を表示するとよいとおもいます。

## 更に便利にするために。其の2
英和辞書ツール
https://chrome.google.com/webstore/detail/mouse-dictionary/dnclbikcihnpjohihfcmmldgkjnebgnj

単語にマウスカーソルを合わせるだけで辞書が引けます。

Chromeブラウザ用の英和辞書ツールです。
フリーの辞書もありますが、自分は英辞郎の辞書ファイルを使っています。
Sugar.jsのdateオブジェクト生成は29:59:59まで対応できる

業界によっては、「25:30～」とかの表記を使うことがあるだろうけど、日付いぢり最強のSugar.jsは、そのまま食わせられることに気づいた。

まぁ、調子に乗ってたらAM6:00でエラー出たけど。

![date.png](https://qiita-image-store.s3.amazonaws.com/0/34041/e1ecb6b2-d99b-6c3b-9695-60c36ac8f78a.png)
redashのSQLでよく使うツール

#目的
エンジニア？アナリスト？歴2ヶ月目の新卒社員が業務をやっていく中で最近学んだこと、これよく使うなあということを簡単にまとめたもの（今回はredash内でPostgreSQLを使ってみた編）。備忘録。

#検索・データの指定をできるようにする
- データを実際に触る際に簡単に見たいデータを抽出できるように、期間や条件をクエリーの手直しをせず検索欄をredash内で作ってもらう。

Queryはこんな感じで書く↓

##期間を指定する場合

```
Select 出力するカラム from テーブル
where 絞り込む期間のカラム名 >= {{from}}
  and 絞り込む期間のカラム名 <= {{to}}
```
今回は{{From}}で検索開始日、{{To}}で検索終了日を設定した。ほかに名前を設定したい場合は、このクエリーのfrom、toの箇所を設定したい名前にすればOK（つまり、{{}}で囲めばOK。また、名前についてはこのあとにも変更することは可能）。クエリーを書くと、こんな感じに出力結果欄に画面が表示される。

![1536722480420.jpg](https://qiita-image-store.s3.amazonaws.com/0/274468/9bae8746-05af-ae78-6edf-fa12220362df.jpeg)
↑この各項目の歯車のところを押すと・・・

![1536722518823.jpg](https://qiita-image-store.s3.amazonaws.com/0/274468/86914a0c-26af-bdd8-94d8-4fd76057eed6.jpeg)
↑こんな画面が出てくるので、ここでTitleを設定したい名前に直し、TypeをDateにすると・・・

![1536723818411.jpg](https://qiita-image-store.s3.amazonaws.com/0/274468/ba9f3302-de25-37e7-2d32-7bd0bbf1d4e0.jpeg)
↑こんな風に画面が変われば成功！！

ちなみに、このTypeは全部で６種類ある。が、現時点で使っているのはDate（年月日のみの指定）と、Textくらい。いつかもっと使うのかな・・・

##期間データが時刻まで指定されているが、指定したいのは年月日のみの場合

時刻を終日にしておくならば、この書き方でOK。終わりについては時刻まで指定したい！！というときは、終わりのTypeを'Date and Time'、またはそのデータにあわせて'Date and Time(with seconds)'に設定すればOK

```
WHERE 絞り込む期間のカラム名 >= '{{ 開始日 }} 00:00:00'
  AND 絞り込む期間のカラム名 <= '{{ 終了日 }} 23:59:59'
```

##カラムのTextを指定する場合

```
Select 指定したい（絞り込みたい）カラム　as 'カラム名:multi-filter'
  from テーブル
　　　　　　　　　　・・・
```
指定するカラムの名前をas以降で指定する際に後ろに':multi-filter'をつけると、出力画面に検索箇所が出てくる（モザイクのところにはasで指定したカラム名が入っています）。

![1536725931541.jpg](https://qiita-image-store.s3.amazonaws.com/0/274468/455cc195-479c-a679-e771-e855a64abfa1.jpeg)

この「Select value for ・・・」を押すと、下のような画面が出てくるので、ここで指定／絞り込みしたいものを選択すると、指定／絞り込みしたもののみが出力される。

![1536725958231.jpg](https://qiita-image-store.s3.amazonaws.com/0/274468/680224ad-9346-cd3e-38bc-60142737b85c.jpeg)

これ、他部署のエンジニアとか、開発系を触らない人にはすごい重宝がられます。欲しそうだけどはっきりとはいってもらっていないときにさらっとこういうことをしておくと喜んでもらえるのでオススメ。

# データをひとつのカラムにまとめて表示したい
ベタなやり方ともっと手軽にできるやり方をのっけとく。よくまとめたくなるのは、名前の姓（苗字）と名（下の名前）。

##ベタ編
concat関数を使用する。が、3つ以上のデータをまとめたいときにはちょっと書き方に注意が必要（入れ子にして書かないといけない）。

```
-- 基本の形
Select concat('カラム名1', 'カラム名2') as まとめた総称
  from テーブル名
     ・・・

-- 入れ子にして3つ以上のデータをまとめる
Select concat('カラム名1', concat('カラム名2', 'カラム名3')) as まとめた総称
  from テーブル名
     ・・・
 
```
入れ子にすると、クエリーがごちゃごちゃして見づらいし、余計なミスを招きかねない。なので、||（パイプ）を使用すると入れ子にしなくても済むし、書くのも（誤差程度とはいえ）楽チンに。

##簡単にやる編
||（パイプ）を使用する。

```
Select 'カラム名1' || 'カラム名2' || 'カラム名3' as まとめた総称
  from テーブル名
     ・・・
```

||（パイプ）にしてしまえば、入れ子にしないでただ順番にひたすら並べてしまえば、いくらでもくっつけてしまうことができる。個人的にはconcat関数は使わないで、こっちで書いてるかなぁ

##注意点
データをまとめたときは、きちんとまとめたあとの名前をasで定義づけておかないとほかの人が見たときももちろん、自分自身が見返したときによくわからなくなることもあるので要注意。要注意！！！

#感想
簡単に（というより、テキトーにだけど）自分が学んだことを人に見えるかたちで文章にしてまとめるって難しい。
これをいろんな感覚（聴覚とか視覚とか）で工夫を凝らして面白くまとめて伝えるようにするユーチューバーってすごいんだなぁっていうまったく関係ない感想。とはいえ、自分の学んだことをまとめるって自分の知識の整理になった。
よかったら高評価、フォローよろしくね！！！！←
おしまい。またまとめまーす
人材不足にどう立ち向かうか。

※主にSESでの人材不足について書いています。

弊社も例に漏れず人材不足で困っている企業の一つです。
正社員に関しても定期採用はしておらず、あくまで自社の社員が参画しているPJで人手が足りない時に募集する程度です。
今までは、正社員にしても何にしても、いい人がいたら採用すればいいよねっていうのんびりした雰囲気で過ごして来たのですが、ある程度人数が増え、参画先でチームというものを組めるようになり、お客様から「増員してもらいたい」と持ちかけられるようになったところで【人材不足】という壁にぶち当たりました。

#どのくらい人材不足なのか
私はエンジニアとして外部に常駐する傍、SESの営業もしています。
10社くらいから案件＆人材情報を共有していますが、日に50件ほど案件情報が流れてきます。そのうち、人材情報は2件ほどです。毎日なにかしらの案件情報が流れてくる会社もあれば、週に1度緊急性の高い案件情報だけ流して来たりとマチマチではあります。
ま、本当に売り手市場です。
スキルシートを送れば短期間で複数案件情報が返ってくるし、スキル要件が多少足りなくても受かることも多く、単価も高い。無理そうな条件（週4日勤務、時短勤務、等）も飲んでもらえる。

「あぁ、マジで人いないんだ」

と実感しました。

あれ？　ということは、人募集しても見つからないよね？　しかも、希望単価が高いよ？　うちこんなに出せないよ？
しかもうちから出す案件は精算なし固定が多いのでもうその時点で弾かれてしまう。

案の定、いくら案件情報を流して人を探しても暖簾になんとかです。
SESの営業先は常に増やしているのに、一向に人が集まらない。

そこでふと出た言葉、
**「もうわかったよ、社員募集しちゃおう。」**

都度調達でなく、囲う作戦へ変更。
しかし、人事もいない小さな会社で、しかも求人関係に関しては動いたことがほぼ皆無で、右も左もわからないので「求人」とはどういう手段があるのか調査してみました。

- 求人媒体への掲載
- セミナーで登壇ないし協賛することで、参加者の連絡先をゲットする
- 勉強会とか交流会を開催する
- 会社説明会＋飲み会を開催する

まだまだ他にも方法はあると思いますが一旦こんな感じで……
求人媒体への掲載は簡単に真似できそうです。試しに「転職する側」になって登録してみることにしました。

…スカウトメールいっぱいくるね！！
じゃなくて。
自分が転職する立場で求人をみると、どうしても自社サービスのある会社に目がいってしまいます。これは今現在SESで外に出ているからせっかく転職するなら別のことがしたい！　ってことなのかなぁと思いました（これは完全に個人的な事情）。
ただ、スカウトメールも、こちらの希望条件にまったくそぐわないものもあり、「本当に私が必要なのだろうか？」と、とりあえず送ってるんじゃないかな？ と思うものもありました（もちろんちゃんと条件面に目を通してくれてる企業もありましたよ！）。
まぁ、それだけ人がいないってことですよね。どこの会社も必死なんだと思います。


少々話が逸れましたが、社員雇用を考えても以下のような課題・問題点が出てきます

##採用するとして、課題
**「未経験採用の場合、社内開発してないのにどうやって教育するの？」**
今は助成金などあるので外部研修を利用するハードルが幾分か下がった印象があるため、積極的に利用していきたいところです。
外部研修については、以前は「こんな研修内容Google先生が教えてくれるよ」と思っていたのですが、その情報だってある程度の検索能力がなければたどり着けないことを考えてなかったなぁと、「人が教える」ということも、薄っぺらな研修内容でも人によっては重要な情報なんですよね。って思えるようになりました。
オンライン学習のサイトも増えてますし、外部に任せるのはありなのではないかと思いました。

##問題点
**「現場決まらないと自社待機になってしまう」**
ここら辺が正規雇用のリスクになっていると思います。これが怖くて未経験はなかなか手が出せません（結局それ）。

#結論
- 人が欲しいなら積極的にならないとダメ
- 待ってても来ない
- ある程度体力をつけて未経験採用に本腰を入れる
（中途採用がベターだけど、若手もほしい）

##補足
###新卒を採った時の話
若手社員が通っていた専門学校に連絡し採用活動をさせてもらったのですが、地方ということもあり、東京にまで出てこようとする人がとても少なかったのが印象的でした。
学生的には「この会社に入りたい」っていうよりは「他と比べていいほう」をとることもあるそうです。
その中で「行きたい！」と思われるような会社でありたいですが、私自身、在籍年数も長く社内ではいろいろな業務をこなしておきながら帰属意識が薄く「自社大好き！」ってわけではないので、魅力とかわからないんですよね（この辺りはわかる人に任せよう）。

##後日談
有料の案件＆人材マッチングサイトを使って、ようやくちらほら人が集まるようになりました（正社員も）:crescent_moon:
採用に関してはまだまだ課題が山積みです。
また、特定派遣の廃止に伴い廃業を余儀なくされる企業も少なからずあるようです。派遣契約できるエンジニアの激減が予想され、単価高騰が懸念されます。
またエンジニアの争奪戦が始まるわけですね……


##またその後の後日談
新卒&中途採用始めました。
中途はオンラインスクールからの斡旋から、新卒は専門学校への求人票提出から始めています。
中途の方は2名面談してみて1名からかなり優秀で内定出して返事待ちです。学習意欲が高く、自己学習もできているので育てやすそう＆教えがいがありそうってこともあり、一緒に働きたいなぁと素直に思えました。
新卒採用は…ちょっとやり方間違えた感が半端なくて仕切り直して21年卒を頑張ります…。
UiPathで使うちょっと便利な機能（右クリック系）

UiPath Studioで開発するにあたり、自分がよく使っている右クリックの機能をまとめました。

[・各アクティビティにコメント（Annotation）を入れる](#各アクティビティにコメントannotationを入れる)
[・不要になった Sequence を削除する](#不要になった-sequence-を削除する)
[・Flowchart の最初のノードを変更する](#flowchart-の最初のノードを変更する)
[・画面キャプチャをとる] (#画面キャプチャをとる)

## 各アクティビティにコメント（Annotation）を入れる
各アクティビティが何をしているか忘れないために、コメントを書く方法です。
（アクティビティの DisplayName 使えますが、表示に限りがあるため。）

　1. コメントを入れたいアクティビティにフォーカス
　2. 右クリック
　3. 「Annotations」 > 「Add Annotation」を選択
　4. ピンのマーク（Dock）をクリック※
　※ピンのマークをクリックせずに閉じると、非表示になる。

編集は「Annotations」 > 「Edit Annotation」
削除は「Annotations」 > 「Delete Annotation」
から選択可能です。

「Show All Annotations」「Hide All Annotations」「Delete All Annotations」は、
同じワークフロー内のすべてのワークフローに影響があるので、使用の際は要注意！！

## 不要になった Sequence を削除する
ワークフローを色々と作りこんで行く中で、多重化して不要になったシーケンスが出てくることがあります。
中にあるアクティビティはそのままに、外側のシーケンスのみ削除する場合に便利な機能です。

　1. 削除したいアクティビティにフォーカス
　2. 右クリック
　3. 「Remove Sequence」を選択

モノによっては動作に影響があって削除できない場合もあります。。

## Flowchart の最初のノードを変更する
Flowchartの中で、最初に処理を行うノードを変更するときに使います。
手で矢印を繋ぎ変えるわずらわしさから解放されます:-)

　1. 最初に処理をしたいアクティビティにフォーカス
　2. 右クリック
　3. 「Set as Start Node」を選択

## 画面キャプチャをとる
Qiitaなどに画面キャプチャを載せたいとき、非常に便利です。

　1. 画面キャプチャを取りたいアクティビティをダブルクリック
　2. 右クリック
　3. 「Copy as Image」または「Save as Image」を選択
　※「Copy as Image」はクリップボード保存
　　「Save as Image」は画像ファイル保存

保存される画面は、その時表示しているアクティビティです。

-----

まだまだありそうなので、いろいろ見つけてみます。
sendmail

# SMTPサーバ設定

以下の先頭の`dnl`を削除して`{{ smtp server }}`にホスト名かIPをかく

```
grep 
dnl define(`SMART_HOST', `{{ smtp server }}')dnl
```

再起動

```
systemctl restart sendmail
```

# メール送信サンプル
```
sendmail kenji-kondo@gmail.com
To: kenji-kondo@gmail.com
From: test@localdomain
Subject: test message from kenji-kondo

test by kenji-kondo

.
```

# 参考
* http://x68000.q-e-d.net/~68user/unix/pickup?sendmail
* http://life.co-hey.com/2012/08/sendmailとpostfixの利用smtpサーバ指定方法/
[Swift4.x] Autolayoutを使用せず天地中央・x軸中央・y軸中央

Swift初心者、本業はWEBのフロントエンドです。

CSSでよくやる天地中央や横縦中央の設定です。
AutolayoutでGUIも良いのですが、一つにまとまっていたほうが楽なので、swiftだけでやってみます。
UILabel自体もコードから作ります。

```swift
import UIKit
class viweController: UIViewController{
    override func viewDidLoad() {
        //UILabelのインスタンス作成
        let titleLabel = UILabel()
        //表示文字の追加
        titleLabel.text = "タイトル"
        //表示位置(あとでx,width,heightを設定するので初期値0)
        titleLabel.frame = CGRect(x:0, y:100, width:0, height:0 )
        //width,heightをオブジェクトにあわせる
        titleLabel.sizeToFit()
        //天地中央
        titleLabel.center = view.center
        //横中央(自分のx軸をviewのx軸に設定)
        //titleLabel.center.x = view.center.x
        //縦中央(自分のy軸をviewのy軸に設定)
        //titleLabel.center.y = view.center.y
        //　vieｗに追加
        self.view.addSubview(titleLabel)
    }
}
```

`変数.frame = CGRect()`が理解できてないのでぐぐると、CGはCore Graphics FrameworkでRectは四角なので、CGRectは「定義された2Dの四角形」　でいいのかな？
frameはsuperview(土台のView)に対してどこに配置するかを決める見えない枠(四角型)で定義する感じ？
JSでcanvas扱うときと似てる気がする。

Core Graphics Framework
https://developer.apple.com/documentation/coregraphics
frame
https://developer.apple.com/documentation/uikit/uiview/1622621-frame
WSLで，どうやっても日本語化できない場合の対処法

#状況
* WSLの日本語化を試してみても，日本語が「□□□」で表示される。
* [こちら](https://qiita.com/ta_b0_/items/984ac713697695814aa0)の設定など，WSL側の言語設定を触っても解決されない。
* WSLの画面を閉じると，日本語設定が何故か消える

#原因
Windows側からWSLに設定されているフォントの設定が悪い場合がある。
→現在設定されているフォントが，日本語に対応していない。

「 灯 台 下 暗 し 」的なヤツです。

## 解決方法
1. タイトルバー(最小化・最大化・閉じるボタンのある場所)の何もないところで右クリック
2. 「プロパティ(P)」を選択
3. 「フォント」タブ内の「フォント(F)」の中にあるフォントのうち，日本語に対応しているフォントを選ぶ（MS ゴシック等）
【小ネタ】FargateのAutoScallingをスケジュールベースで動かす方法

現状、ECSのFargateタイプのAutoScallingは下記タイプをサポートしており、スケジュールベースのスケールには対応していない。

- CPU
- Memory
- ALBのリクエスト数
- CloudWatchアラーム

せっかくFargateになりEC2の存在を気にせずにスケール出来るようになったので、ピークタイムにはコンテナ増やすみたいな事例に対応するためにちょっと検証してみた。


## 必要なもの
CloudWatchEventsでcronベースのイベントをトリガに、Lambdaを起動してFargateタイプで動くECSのサービス内のタスク数を増減させる形

- ECS Serviceの更新をするlambda
- lambdaを実行するための、IAMロール
- lambdaを定期実行するCloudWatchEventsのイベント

## ECS Serviceの更新をするlambda
- boto3を使って、serviceのdesiredCountを増減させるコード
- スケールアウト用とスケールイン用の2つを用意(desiredCountの値が違うだけ)

参考:
[ECS — Boto 3 Docs 1.9.2 documentation](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/ecs.html#ECS.Client.update_service)


```
import boto3
from botocore.exceptions import ClientError


def lambda_handler(event, context):

    try:
        client = boto3.client('ecs')
        service_update_result = client.update_service(
            cluster = 'tst-mamari-q-api',
            service = 'fargate-tst-docker-apache-prd',
            desiredCount = 0 # ここの数を増減させる
        )
        print(service_update_result)
    except ClientError as e:
        print("exceptin: %s" % e)
```

## lambdaを実行するための、IAMロール

【必要な権限】

- ecs serviceの更新
  - ecs系のActionは、Resource絞れるなら指定したほうがベター
- cloudwatchlogsへの出力権限
  

```
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "ecs:DescribeServices",
                "ecs:UpdateService"
            ],
            "Resource": [
                "*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "logs:CreateLogGroup",
                "logs:CreateLogStream",
                "logs:PutLogEvents"
            ],
            "Resource": "arn:aws:logs:*:*:*"
        }
    ]
}
```


## lambdaを定期実行するCloudWatchEventsのイベント
トリガに使うので、CloudWatchEventsにcronスケジュールをセットしておく。

![883FDE07-FBDC-476C-90CF-44DA4D119417.png](https://qiita-image-store.s3.amazonaws.com/0/40850/0420a68c-e621-5546-bcfe-89b31531e7f5.png)



## デモ

【シナリオ】
- 14:47になったらスケールアウト開始(タスク数を1にする)
- 15:05になったらスケールイン開始(タスク数を0にする)

### スケールアウト(14:47にスケールアウト開始)

① スケールアウトするイベント登録
![1BF3D475-48B9-4C55-B587-7087D9F49169.png](https://qiita-image-store.s3.amazonaws.com/0/40850/e5a6e7f8-f3dc-671f-7a48-97741a463540.png)



② ①のイベントをトリガにするlambda登録
![09BDBAC5-B67B-4337-86EA-0D0A6EF90897.png](https://qiita-image-store.s3.amazonaws.com/0/40850/3239e5f1-120d-1f68-fca0-b32bb2171d13.png)


③時間になった時のECSの状態
![D3798586-DC94-4970-A7C6-4765B298F20D.png](https://qiita-image-store.s3.amazonaws.com/0/40850/e23b55a9-34ad-b1a4-de87-c1502feb7373.png)


### スケールイン(15:05にスケールイン開始)

① スケールインするイベント登録
![1666BC04-CBA0-4240-AE6F-4A04AA83D13A.png](https://qiita-image-store.s3.amazonaws.com/0/40850/f08bcb6e-5f3a-88de-67d7-d974cdb48482.png)



② ①のイベントをトリガにするlambda登録

![213C3579-FA4F-47D4-9B6A-AA8BF8039767.png](https://qiita-image-store.s3.amazonaws.com/0/40850/12fc63d8-f35c-6213-2060-d9e6c233acec.png)


③時間になった時のECSの状態

![21C7DBFF-FA81-43C2-A97A-1B968B355026.png](https://qiita-image-store.s3.amazonaws.com/0/40850/59122f9a-dba7-9078-818f-1fa636a6170a.png)


※Lambdaの実行ログは、CloudWatchLogsから見れる
Arduino IDE による BLE Nano v2 のアプリケーション開発

Red Bear Lab の BLE Nano v2 は[公式リポジトリ](https://github.com/redbear/nRF5x)に開発環境構築などが一通り説明されていますが、 Arduino IDE で使える API の説明などが見当たりません。そこで Arduino IDE 向けボードサポートパッケージを一通り読んでみました。

![Nano2_Pinout.png](https://qiita-image-store.s3.amazonaws.com/0/278104/3d3b18ee-0708-475c-0f01-2626d7fbfd7d.png)


## 結論

- Arduino言語はすべてサポート
- 標準ライブラリは「Wire (TWI/I2C)」「SPIのマスター」「Servo」をサポート
- mbed-os がベースになっているため mbed-os の API も利用可能
- BLE を使う場合は mbed-os の API を利用する
- サンプルプロジェクトはそれなりに用意されているので、開発時はこれを基点にするのが良さそう


## Arduino 言語と標準ライブラリについて

[Arduino日本語リファレンス](http://www.musashinodenpa.com/arduino/ref/) というサイトに、 Arduino 言語と標準ライブラリのリファレンスの２つが日本語でまとめられています。

Arduino 言語については BLE Nano v2 ですべてサポートされているようです。標準ライブラリについては Wire, SPIのマスター, Servo の３つしかとりあえず見つかりませんでした。それぞれ

- `#include <Wire.h>`
- `#include <SPI_Master.h>`
- `#include <Servo.h>`

とすることで使えそうです。


## mbed-os の API

Arduino IDE で BLE Nano v2 のアプリケーションを開発する場合、ベースになるのは mbed-os です。そのため、上記の Arduino言語・標準ライブラリ以外にも mbed-os のAPIを使うことができます。

Arduino IDE は明示的に書かなくてもビルド時に Arduino.h をインクルードする仕様になっていますが、この Arduino.h の中で mbed.h もインクルードされているため、そのまま API が使えます。

#### 余談

mbed-os からも Wire (TWI/I2C) と SPI の API が提供されています。 Arduino の標準ライブラリにある Wire と SPI_Master はこの mbed-os の API のラッパーとして実装されています。



## BLE

BLE については `#include <nRF5x_BLE_API.h>` を明示的に書くことで使うことができます。APIについてまとめようかと思いましたが、書き始めると長くなりそうなので割愛します。mbed-os の GitHub リポジトリにある [mbed Bluetooth Low Energy Stack](https://github.com/ARMmbed/mbed-os/tree/master/features/FEATURE_BLE) がこれに対応していると思うので、より細かい内容について調べる際にはこちらを確認するのが良いかと思います。

## サンプルプロジェクトの活用

割愛してしまった BLE の API ですが、 Red Bear Lab の提供しているサンプルプロジェクトを使えば基本的なアプリケーション開発はできそうです。

Arduino IDE で「ファイル」->「スケッチ例」->「BLE_Nano2用のスケッチ」のところを見れば __BLE だけでなく標準ライブラリなどについてもサンプルがある__ ので、実際に開発するときはこれを基点にして開発を進めるのが良さそうです。

<img width="282" alt="キャプチャ1.png" src="https://qiita-image-store.s3.amazonaws.com/0/278104/3c902a45-11bb-e24a-396d-e65bb212bff1.png">
Ubuntu18.04LTS Server でMACアドレスベースのDHCP固定割当てが上手く作動しない場合の対処法

# はじめに

これまで Ubuntu14.04LTS Server を使用していたサーバPCにUbuntu18.04LTS Server をインストールしたら、MACアドレスベースのDHCP固定IPアドレス割当てが上手く作動しなくなった。

使用しているルータは AtermWG300HP で、MACアドレスに基づいてDHCPで指定したIPアドレス割り振る、いわゆるDHCP固定割当てを使用している。Ubuntu18.04 では DHCP要求時にクライアントIDを送付する模様で、これが原因でルータ側でMACアドレスを認識できないみたい。

こちらのサイト https://netplan.io/examples にある、「Windows DHCP Server 」の項を参考に、ネットワークインタフェースを設定することで解決。

# 解決手順

## ネットワークインタフェースの実名

```
$ ip a
$ ifconfig 
```

などでネットワークインタフェースの実名を確認（これは機種毎に違うので都度確認が必要）。私の場合は enp2s0 なので、以下この値を指定します。

## 現在のクライアントIDを確認する

```
$ sudo netplan ip leases  enp2s0
# This is private data. Do not parse.
ADDRESS=192.168.10.2
NETMASK=255.255.255.0
ROUTER=192.168.10.1
SERVER_ADDRESS=192.168.10.1
T1=43200
T2=75600
LIFETIME=86400
DNS=192.168.10.1
CLIENTID=ff5de26c1500020000ab110604134a62bb6d20
```

上記の CLIENTID の値が変更されるようにする。

## インタフェースの設定を変更する

```
$ sudo vim /etc/netplan/01-netcfg.yaml
----------------------------------------
  1 # This file describes the network interfaces available on your system
  2 # For more information, see netplan(5).
  3 network:
  4   version: 2
  5   renderer: networkd
  6   ethernets:
  7     ens33:
  8       dhcp4: yes
* 9       dhcp-identifier: mac
```

上記の9行目のように変更する。

## クライアントIDの変更を確認する

```
$ sudo netplan apply
$ sudo netplan ip leases enp2s0
# This is private data. Do not parse.
ADDRESS=192.168.10.31
NETMASK=255.255.255.0
ROUTER=192.168.10.1
SERVER_ADDRESS=192.168.10.1
T1=4294966
T2=4294966
LIFETIME=4294967295
DNS=192.168.10.1
CLIENTID=01xxxxxxxxxxxx
```

CLIENTIDが変わっている（上記では xxx... で修正しています）。
私の場合は、これで解決しました。
Elmのブームに便乗してみた

# はじめに
[先日みた記事](https://qiita.com/ababup1192/items/c48df0495728f89f756a)に便乗してElmを始めてみました。
すでに[入門してみた記事](https://qiita.com/Nimimal/items/8a648ee3df760a382cf5)はいくつか投稿されているのでn番煎じもいいところなのですが、投稿者のほとんどはフロントエンドの経験がある方たちばかりだったので（当然だとは思いますが）中級～上級者の視点から書かれた内容が多いなという印象を感じました。
そこで敢えて、フロントエンド全くの未経験・JavaScript未経験のど素人である私がノリと勢いでElmを触ってみた件についての記事を書いていこうかなと思います。

# 今まで触ってきた言語
- C言語（Arduinoとかmbedの関係で）
- Python（研究。TensorflowとかOpenCVとか）
- Go（オライリー本の[インタプリタつくるやつ](https://www.oreilly.co.jp/books/9784873118222/)とか[チャットつくるやつ](https://www.oreilly.co.jp/books/9784873117522/)とかやった）
- HTML（高校の授業で）

Web系を全く触ったことないわけではありませんが、入門書を少し読んだくらいです。どっちかというとマイコンとか画像認識とかの方が得意です。

# なぜElmを触ろうと思ったのか
元々Web系で何かプログラミングをやってみたいなと思っていました。そのためにGoを始めて「[Go言語によるWebアプリケーション開発](https://www.oreilly.co.jp/books/9784873117522/)」とかいう本を買ったわけですが、これ結局フロントエンドの部分はHTMLとjqueryで書いてるんですよね。つまるところWebを始めるならJavascriptの知識は必要だということが分かったわけです。ですが、**JavaScriptよくわからんし、ぶっちゃけ勉強すること多そうで嫌だ**という拒否反応が出てしまって、フロントエンドの勉強はモチベーションがあまりわかなかったというのが、この@ufoo68の現状だったわけです。
しかし最近[このElm関係の記事](https://qiita.com/ababup1192/items/c48df0495728f89f756a)を見つけて、**お？なんか面白そうやん？**とか思ったのでその場のノリでElmをインストールしてみたのがきっかけで再びフロントエンドの勉強を始めてみた次第です。要は新しいものと流行物に飛びついたって感じですね。

# インストールとか環境構築
[公式ページ](https://elm-lang.org/)に説明がのっていたのでそれを参考にカチャカチャやってインストールはすんなり通りました。OSはWindowsですが、コマンドラインを使うことが多い言語は[WSL](https://qiita.com/Brutus/items/f26af71d3cc6f50d1640)の方に入れて使っています。なのでインストールは[Linuxの方](https://gist.github.com/evancz/442b56717b528f913d1717f2342a295d)を参考にしました。しかし、このコマンドの最後の`mv elm /usr/local/bin/`は、`sudo mv elm /usr/local/bin/`にしないとpermissionで弾かれると思います。
また、開発環境はvscodeを使いました。WSLをvscodeに適用させる方法は[この記事](https://qiita.com/yo_kanyukari/items/37421f497b7ffaa75502)を参考してみてください。Elm用の拡張機能もvscodeにちゃんとあるので問題はないと思います。
あと、glitchを使えば[こういったサンプル](https://glitch.com/~elm-sample-app)が公開されているので、ローカルで環境を作らずとも始めることができます。

# 勉強に使ったサイトとか
こういうのは、~~[公式ページ](https://www.elm-tutorial.org/jp/)のチュートリアルの日本語版とかあるのでそれを読んでいったら使い方はなんとなくわかるかと思います。~~←どうやら公式ではない模様。日本版の公式は[こっち](https://guide.elm-lang.jp/)のようです。。。しかし私としては何かプロダクトを作りながらリファレンスを適宜参照するやり方の方がモチベーションが湧くのである程度型定義とか関数のルールを読んだ後に、[このワークショップ](https://github.com/rtfeldman/elm-0.19-workshop)の問題を解きながら勉強を進めました。（というかまだ勉強会途中です）
ちなみにこのワークショップの内容はTODOとコメントアウトされている箇所を穴埋めしながら進めていく形式です。「condiut」という掲示板アプリのようなものを作成していきます。
ただし注意として、introのpart5~9に関して訂正が[プルリク](https://github.com/rtfeldman/elm-0.19-workshop/pull/1)にあるので一部ファイルの修正が必要になります。もちろん0.19にちゃんと対応しているので問題なく始められます。

# Elmを触ってみて
@ufoo68はフロントエンド初めてなので、技術的な話は全くできません。なんかHaskellと似てたりするらしいですが、そんなの知りません。とりあえずJavaScriptにアレルギー感じていた者としての感想は、ドキュメントの情報量の少なさが返って嬉しかったです。その点はGoと似ているところがあるなと感じました。
また逆に型についてうるさく言われる部分に関してはGoやc言語で慣れているので親近感を感じました。
あと先ほど述べたように、書き方は違えどGo言語と相性が良いのでは？と思う部分がいくつかありました。例えば、コードの形式のフォーマッターがあるところとか、typeで型をつくるところとかですかね。
ちなみに、[GoとElmの組み合わせでwebを作るサンプル](https://github.com/mremond/go-elm)もあったりします。ただし、0.18に対応しているので、新たにelm.jsonを作成する必要があります。
そんで問題はその部分でして、Elmが0.18から0.19にバージョンアップしたのはつい最近なので、0.18のリポジトリが多く残っている訳ですが、これが厄介なことに、0.19との互換性があったり無かったりするので面倒なところは多々あります。

# まとめ
とりあえず、今までJavaScriptが嫌でフロントエンドを諦めていた私のような人がいればこれを機に、Elmでフロントエンドの勉強を私と一緒に初めてみませんか？
【C#】【ASP.NET】小ネタ・単一のaspxファイルの処理をCSファイルに切り分ける

続き物です。

前の記事：【C#】小ネタ・IISだけインストールしてさくっとASP.NETのHello World!を表示する
https://qiita.com/tabelog2001/items/3532972763db8a70bf1c

ますます「どこに需要があんだよ」的記事になっていきますが、さくっと試すために単一のaspxファイルのコードを提示してコレ一個放り込めば動くんすよ、というのが前回投稿の記事のシメ。

そのクソコードを
**「処理部分だけCSファイルに切り分けたければこうしてください」**
というのが今回のおハナシ。

**前回から変更したhelloworld.aspx**

```C#
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="helloworld.aspx.cs" Inherits="helloworld" %>

<html>
<head runat="server"></head>
<body>
  <form id="form1" runat="server">
    <div>
      <asp:Button ID="Button1" runat="server" onclick="Button1_Click" Text="Button" />
      <asp:Label ID="Label1" runat="server" Text="Label" />
    </div>
  </form>
</body>
</html>

```

変えたところは&lt;script runat="server"&gt;タグを削ったのと、ヘッダに以下の記述を加えたところ。

```C#
CodeFile="helloworld.aspx.cs" Inherits="helloworld"
```

これで、このaspxファイルはhelloworld.aspx.csの中のhelloworldクラスを参照するんだぜ、とIISくんが理解できてそっちの処理を見に行くようになります。


**切り分けたhelloworld.aspx.cs**

```C#
using System;
using System.Web;
using System.Web.UI;

public partial class helloworld : System.Web.UI.Page
{
  protected void Button1_Click(object sender, EventArgs e)
  {
      Label1.Text = "Hello,World!";
  }
}

```

ちなみにpartial識別子は要るらしい。削ったら怒られました。
以上。
画像処理 in Julia 1.0 #1

#JuliaImages
Juliaで画像処理をする場合、有用なパッケージのひとつに[JuliaImages](http://juliaimages.github.io/latest/)がある。ここでは、Julia 1.0の環境にJuliaImagesを導入する方法を示す。また、動作確認には、[ここ](http://juliaimages.github.io/latest/install)のコードを参考にし、発生するエラーの修正方法を紹介する。OSはUbuntu 16.04である。

#インストール
Images, ImageView, TestImagesをaddする。

```julia:add_packages.jl
using Pkg
Pkg.add("Images"); Pkg.add("ImageView"); Pkg.add("TestImages")
```

Imagesは画像処理パッケージの本体である。ImageViewは画像をインタラクティブに表示するパッケージである。TestImagesには画像処理で使われる標準的な画像が収録されている。

##テスト画像の読み込みの動作確認
TestImagesにあるmandrill画像を出力するコマンドで動作確認を行う。

```julia:mandrill.jl
using Images, ImageView, TestImages
img = testimage("mandrill")
imshow(img)
```

ここで、以下のエラー

```
ERROR: ArgumentError: Package ImageMagick not found in current path:
- Run `Pkg.add("ImageMagick")` to install the ImageMagick package.
```

が出るときは、ImageMagickをaddし、再度、mandrill.jlを実行する。また、エラー

```
ERROR: InitError: error compiling __init__: could not load library "/home/username/.julia/packages/ImageMagick/d5KBL/deps/usr/lib/libMagickWand-6.Q16.so"
/lib/x86_64-linux-gnu/libz.so.1: version `ZLIB_1.2.9' not found (required by /home/username/.julia/packages/ImageMagick/d5KBL/deps/usr/lib/libpng16.so.16)
during initialization of module ImageMagick
```

が出たら、zlibの最新版をインストールすればよい。

```:Shell
$ wget http://zlib.net/zlib-1.2.11.tar.gz
$ tar xvzf zlib-1.2.11.tar.gz
$ cd zlib-1.2.11
$ ./configure --prefix=/usr/local
$ make
$ sudo make install
```

##自前画像の読み込みの動作確認
[ここ](http://juliaimages.github.io/latest/install.html#Troubleshooting-1)にあるように、自前の画像（test.jpg）を読み込む。

```julia:test.jl
using Images, ImageView
img = load("test.jpg")
imshow(img)
```

##画像の保存
```julia:save_image.jl
save("filename.jpg", img)
save("filename.png", img)
```

ここまで、エラーが出なければ、JuliaImagesの[Quickstart](http://juliaimages.github.io/latest/quickstart.html)を始めることができる。お疲れ様でした。
iOSで動画をInstagram Storyにシェアする

iOSで、URL SCHEMEを使ってInstagramに動画をシェアする方法です。

## やること

動画を録画できる機能を持つアプリを作っていると、Instagram Storyにシームレスにシェアできるアプリをつくりたいですよね。　

![GIFイメージ-CF38FB296D55-1.gif](https://qiita-image-store.s3.amazonaws.com/0/111366/4de55160-ea40-21f3-1324-7d47731cc781.gif)

上は[Pemoji](https://itunes.apple.com/app/id1410639096?mt=8)のスクショです。この実装のためのメモを残します。

## 前提

InstagramにURL Schemeを使って動画をシェアするためには一旦動画をカメラロールに保存しなければならない。

## 流れ

Photosフレームワークで動画を保存し、localIdentifierを取得

↓

localIdentifierを使ってInstagramのurl schemeを作る

↓

遷移する


## コード

```swift
import Photos

let url = URL(fileURLWithPath: path)
var localId: String?

PHPhotoLibrary.shared().performChanges({
    let request = PHAssetChangeRequest.creationRequestForAssetFromVideo(atFileURL: url)
    localId = request?.placeholderForCreatedAsset?.localIdentifier
}, completionHandler: { success, error in
    
    if let localId = localId {
        shareToInstagram(localIdentifier: localId)
    }
})

private func shareToInstagram(localIdentifier: String) {
    let urlString = "instagram://library?LocalIdentifier=" + localIdentifier
    guard let url = URL(string: encoded) else {
        return
    }
    UIApplication.shared.open(url, options: [:], completionHandler: nil)
}
```

## ポイント

- localIdentifierを使ってカメラロールに保存した動画を一意に判別できるようにすること
- PhotoフレームワークでcreationDateで最新とか取ったりすると、古い動画をシェアしたい時にうまくいかない
- [stackoverflow](https://stackoverflow.com/questions/34226433/instagram-hooks-pre-select-media-issue)にあるように、 `instagram://library?AssetPath=` は使わない方がいい

## 参考

https://stackoverflow.com/questions/34226433/instagram-hooks-pre-select-media-issue
iOSで中スクロールが上手くいかない理由

# iOS上のスクロールの挙動
中の要素でスクロールする場合に`overflow-y: scroll; -webkit-overflow-scrolling: touch;`をセットすると思いますが、その時に動画のようにwindow自体がスクロールしてしまうことがあって中スクロールが上手くいかないことがあります。
下にどの状況を貼ります。iOS11.3のiPhone 8 Plusのものです。iOS10.3でも同じ現象を確認しました。

![output2.gif](https://qiita-image-store.s3.amazonaws.com/0/187768/8c667c01-b7d0-81f1-8a02-374693b4ea66.gif)

この動画を見ればわかると思いますが、中の要素のスクロールイベントの代わりに、windowの方のスクロールイベントが発生しているため中スクロールが上手くいっていません。今回はわかりやすく`position: absolute;`で設定しているためwindowがスクロールした時にスクロール要素自体も動いているので変化がわかりますが、`position: fixed;`にした場合はスクロール要素は固定されたままなので変化に気づけずフリーズしているように見えてしまいます。

触ってみた感じだと、スクロールの終端で一旦止まると慣性スクロールがwindow側になり、スクロール中はwindow側でスクロールされてしまう感じです。終端にいなければ要素側のスクロールから始まるので、window側でスクロールされることはなさそうです（多分）。

# デモページ、サンプルコード
デモページとサンプルコードは以下にあります。
[デモページ](https://takanorionuma.github.io/ios-scroll-test/)
[サンプルコード](https://github.com/TakanoriOnuma/ios-scroll-test)

# 終わりに
結局、中スクロールすると上手くスクロールされなくなる理由はわかりましたが、残念ながら解決方法まではわかりませんでした。
どうしてもやる場合はこの現象を理解した上で使うか、iScrollとか使ってJSでスクロール処理を書くことになるのかなと思いました。
できればこの問題はどうにかしたいので誰か解決方法を知っていたら教えていただけると大変助かります。

# 参考URL
* https://qiita.com/YukieKasai/items/2bd8b585802116c8be66#_reference-756a793737a6a8a1b265
* https://qiita.com/chocolamint/items/67d25933880404c93db0
* https://qiita.com/n4o847/items/c491c040f40809325394
datastore + Goでメタデータを取得する

GAE/Goにてdatastoreのメタデータを取得する場合は`datastore.Kinds`等を利用できますが、それを使わない場合の取得方法についてまとめたメモです。
※公式ドキュメントは[こちら](https://cloud.google.com/datastore/docs/concepts/metadataqueries)

#取得できるメタデータ
- Namespace
- Kind
- Property

## Namespace
```go
func Namespaces(ctx context.Context, client *datastore.Client) ([]string, error) {
	q := datastore.NewQuery("__namespace__").KeysOnly()
	keys, err := client.GetAll(ctx, q, nil)
	if err != nil {
		return nil, err
	}
	namespaces := make([]string, 0, len(keys))
	for _, namespace := range keys {
		namespaces = append(namespaces, namespace.Name)
	}
	return namespaces, nil
}
```
## Kind
```go
func Kinds(ctx context.Context, client *datastore.Client) ([]string, error) {
	q := datastore.NewQuery("__kind__").KeysOnly()
	keys, err := client.GetAll(ctx, q, nil)
	if err != nil {
		return nil, err
	}
	kinds := make([]string, 0, len(keys))
	for _, kind := range keys {
		kinds = append(kinds, kind.Name)
	}
	return kinds, nil
}
```
## Property
指定したkindのpropertyとrepresentationをmapで返す

```go
func KindsProperties(ctx context.Context, client *datastore.Client) (map[string][]string, error) {
	kindKey := datastore.NameKey("__kind__", "Task", nil)
	query := datastore.NewQuery("__property__").Ancestor(kindKey)

	var props []struct {
		Repr []string `datastore:"property_representation"`
	}

	keys, err := client.GetAll(ctx, query, &props)
	if err != nil {
		return nil, err
	}
	propMap := map[string][]string{}
	for i, p := range props {
		propMap[keys[i].Name] = p.Repr
	}
	return propMap, nil
}
```
GoogleSpreadsheetで決まった範囲を選択するボタン

定型レポートを書く業務にあたること、ありますよね。
SpreadSheetを使いこなしてサクサク効率化、あっという間に出来上がった！
最終提出フォーマットに張り付けだ！
毎回同じ範囲を選んでコピーするのがめんどくさい！
GASに任せましょう。

# 方法

### コード
①スクリプトエディタを呼び出します
![image.png](https://qiita-image-store.s3.amazonaws.com/0/151668/5ba9b368-d871-e90f-ef9c-141f115c6df4.png)

②スクリプトエディタでコードを書きます。シート名や範囲は適当に変えてくださいませ。

```javascript:myFunction
function myFunction() {
  var sheet = SpreadsheetApp.getActive().getSheetByName('YourSheetName');
  var selectedRange = sheet.getRange("A1:B2");
  sheet.setActiveRange(selectedRange);
}
```
③実行すると実行権限を求められるのでOKして、うまくいくか確認します。

### ボタン
④図形描画します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/151668/61796b73-d745-c54c-0904-b68b6061ecbf.png)
⑤ボタンを適当につくります。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/151668/825c930f-4c38-7e91-b050-25f26dbc000b.png)
⑥適当に配置したボタン上で右クリックします。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/151668/fa471a1b-4246-4ecf-70fa-c42f37fca4a6.png)
⑦先ほど作ったmyFunctionを割り当てます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/151668/c8257e92-3b88-c117-ca3b-9c526aae2b59.png)

完成！ボタンを押したらctrl+cするだけ。
（マクロを使ってもよいのですが、このほうがレイアウトが変わったときの応用性が高いので…）
RDS(MySQL) でスローログが出力されなくなる場合がある

# 環境
* RDS
* MySQL 5.6.34

# 事象
* RDS(MySQL)でtable出力していたスローログをCloudWatch Logsに出力しようとしたが、寝ても覚めても出力されなかった
* 設定したパラメータでスローログ関連のものの値は以下の通り（設定は間違っていない）

```
slow_query_log=1
log_output=FILE
long_query_time=1
```

# 対応
* パラメータ：slow_query_log を 0 にして保存し、再度 1 に変更するだけで出力されるようになった
* RDSでMySQLを使っている場合に一部で発生しているRDSのバグらしいが、詳細な条件は不明
nodistでnpm6.2.0以降にアップデート出来なかった話 

[nodist](https://github.com/marcelklehr/nodist)でnode.jsのv10.10.0（2018/09時点の最新版）をインストールした際に、npmのバージョンをv6.4.1にアップデートするのが上手くいかなくて手間取った話。

<B>
&lt;UPDATE 2019/04/11&gt;
久しぶりに確認に行ったら、nodistは[0.9.1](https://github.com/nullivex/nodist/releases/tag/0.9.1)がリリースされていました。
本記事記載バージョンは0.8.8です。
最新版を利用すれば色々と問題解決すると思います（8/26一寸補足：この記事を参照した上で、再インストールして[解消されている記事](https://qiita.com/taketakekaho/items/655e63c35a9467f42afa "nodistでnpmとNode.jsのバージョンが合わせられずエラーとなった")がありました）。
この記事を参考にする際には、お手元のバージョンを確認の上で読んでいただけるとお手間を取らせないで済むかと思います。
&lt;/UPDATE 2019/04/11&gt;
</B>


&lt;UPDATE 2019/02/27&gt;
本文記載箇所以外にもいくつか修正ポイントがあるらしく、フォーク先の[astrata-eu/nodist](https://github.com/astrata-eu/nodist)の[修正コミット内容](https://github.com/astrata-eu/nodist/commit/ed60ded3d936abe5ab56d3e1180bd5784c78e0e1)もトラブルが解消しなければ参考になるなと思ってます。
&lt;/UPDATE 2019/02/27&gt;

その道の人たちは問題なく解決できてる話だとは思いますが・・・。

```
>nodist 10.10.0
Installing 10.10.0
 10.10.0 [===============] 24164/24164 KiB 100% 0.0s
Installation successful.

>node --version
v10.10.0

>npm --version
4.0.5
```

nodistでnode.jsの最新版を指定しても、そのままではnpmは対応するバージョンにはならない（   [node.jsバージョン対応表](https://nodejs.org/ja/download/releases/)）。

`nodist npm match`でアップグレードを図るがエラー発生。
モジュールのDLあたりで失敗している。
![nodist_npm_mach_error.PNG](https://qiita-image-store.s3.amazonaws.com/0/290112/5ced3e97-64bf-5f22-984d-1b68d990854d.png)

メッセージ的には、DL用URLの問題な感じですね。
`Error: Failed to read response from https://codeload.github.com/npm/npm/tar.gz/v6.4.1`

どうも2018/07/14のv.6.2.0リリースから、リポジトリが移動した模様。

https://github.com/npm/npm
↓↓↓↓↓↓↓↓↓↓↓
https://github.com/npm/cli

既にPullReqは出てます。っが・・・・一月近くは反応なし（2018/09現在）。
https://github.com/marcelklehr/nodist/pull/217

nodistのgitコミット状況。今年はお忙しいのね。
![nodist_commit状況.PNG](https://qiita-image-store.s3.amazonaws.com/0/290112/dcc5273d-35eb-3ba9-ae95-4c1131155bb5.png)

仕方がないので、PullReq同様URLを変更して対応。

![nodist_npm_設定ファイル.PNG](https://qiita-image-store.s3.amazonaws.com/0/290112/f7516219-1c53-6f89-ca41-e61e122c8b91.png)

Nodeistインストール先のlibディレクトリ下にある、npm.jsを修正（codeload.github.com/npm/npm ⇒ codeload.github.com/npm/cli）。

```
/**
 * Get a download URL for the version
 * @param {string} version
 * @return {string}
 */
NPMIST.downloadUrl = function(version){
  return 'https://codeload.github.com/npm/cli/tar.gz/vVERSION'
    .replace('VERSION',version.replace('v',''));
};
```

ところで、修正前に実行した「nodist npm match」の失敗で時点で、npmのバージョンdirができちゃいます。
![nodist_npm_install状況.PNG](https://qiita-image-store.s3.amazonaws.com/0/290112/e05033ac-abea-a3f0-3af1-edffcc30604e.png)

dirがあると「nodist npm match」はエラーにはならないけど、versionを確認するとエラー
![nodist_npm_version_error.PNG](https://qiita-image-store.s3.amazonaws.com/0/290112/d07a576c-31f6-afdb-f1c5-1ce2630c6df9.png)

dir削除後にnpm matchさせれば無事にインストールされてアップデート完了
![nodist_npm_match_success.PNG](https://qiita-image-store.s3.amazonaws.com/0/290112/ae5738ef-6575-9459-8dce-f229d0faad38.png)

・・・Qiita初投稿なので、お作法とか分かっていません。何かあったら優しく教えてください。
二重引用符などで面倒なことにならない cmd.exe の呼び方

環境変数を使おう

```system.go
package dos

import (
	"os"
	"os/exec"
)

func System(cmdline string) error {
	const CMDVAR = "CMDVAR"

	orgcmdarg := os.Getenv(CMDVAR)
	defer os.Setenv(CMDVAR, orgcmdarg)

	os.Setenv(CMDVAR, cmdline)

	cmd1 := exec.Command("cmd.exe", "/c", "%"+CMDVAR+"%")
	cmd1.Stdout = os.Stdout
	cmd1.Stderr = os.Stderr
	cmd1.Stdin = os.Stdin
	return cmd1.Run()
}
```

```system_test.go
package dos

import (
	"testing"
)

func TestSystem(t *testing.T) {
	err := System("echo \"ahaha ihihi\"")
	if err != nil {
		t.Fatalf("%s\n", err.Error())
	}
}
```

```
$ go test -v
=== RUN   TestSystem
"ahaha ihihi"
```

※テストがおかしいのは分かっているので、つっこまないでくださいｗ
PythonからAzure HDInsightのHiveを使ってデータ取得

# やりたいこと

- Azure HDinsightクラスタのHiveでAzure Data Lake Storeに格納しているデータファイル (e.g., TSVファイル)を読み込む
    - HiveはPythonから呼びたい
    - 取得したデータはPandasのDataFrameとして扱いたい

# 全体の流れ

1. Azure VMの作成
2. Azure VMでJupyter Notebookを起動
3. [Notebook](https://gallery.azure.ai/Notebook/Submit-Queries-to-Azure-HDInsight-Hive-Cluster-in-Jupyter-Notebooks-1)をアップロード

## Azure VMの作成

ここは僕知らない、やってもらったから
こちらを参考にすれば作成できそう
[Linux仮想マシン | Microsoft Doc](https://docs.microsoft.com/ja-jp/azure/virtual-machines/linux/)

## Azure VMでJupyter Notebookを起動

こちらの**[接続]**ボタンの左の**[開始]**ボタンがVM起動のためのボタン
[Linux仮想マシン - 仮想マシンへの接続 | Microsoft Doc](https://docs.microsoft.com/ja-jp/azure/virtual-machines/linux/quick-create-portal?toc=%2Fazure%2Fvirtual-machines%2Flinux%2Ftoc.json#connect-to-virtual-machine)

PythonからHiveのクエリを投げるためのJupyter Notebook

[Submit Queries to Azure HDInsight Hive Cluster in Jupyter Notebooks | Azure AI Gallery](https://gallery.azure.ai/Notebook/Submit-Queries-to-Azure-HDInsight-Hive-Cluster-in-Jupyter-Notebooks-1)



Jupyter NotebookをVM上で起動

上のNotebookをUpload

実行しても以下のエラーが出た

```
ImportErrorTraceback (most recent call last)
<ipython-input-1-7e15b2d6f6c9> in <module>()
     11 # You need the Azure SDK package to download the stdout of hive queries
     12 # which is stored in Azure blob.
---> 13 from azure.storage.blob import BlobService
     14 warnings.filterwarnings("ignore", category=UserWarning, module='urllib2')
     15 

ImportError: No module named azure.storage.blob
```

これを参考にパッケージ入れ直してみる

[Install Azure Python api on linux: importError: No module named storage.blob
 - SrtackOverflow](https://stackoverflow.com/questions/32787450/install-azure-python-api-on-linux-importerror-no-module-named-storage-blob)
Machine Learning＆Deep Learning キャッチアップ

# 概要

[機械学習チュートリアル@Jubatus Casual Talks](https://www.slideshare.net/unnonouno/jubatus-casual-talks/1)

## 勉強方法

[ディープラーニングに入門するためのリソース集と学習法（2018年版） - Qiita](https://qiita.com/keitakurita/items/df3a07135c9cfad810c7)

## フレームワークについて調べた

- Tensorflow
- Keras
- PyTorch
- Chainer

[そろそろデータサイエンティストの定義とスキルセットについて本気で考えてみる - Qiita](https://qiita.com/hik0107/items/f9bf14a7575d5c885a16)
[機械学習の超初心者が、みんなが良いと言う記事を読んでまとめてみた - Qiita](https://qiita.com/hi-ro-to/items/bae866695dfdd4a4b5b5#_reference-4932c484aba8a92acb55)
[【人工知能初心者向け】機械学習・Deep Learningプログラミング学習の道筋と参考書籍 - Qiita](https://qiita.com/ryosuke1120/items/2e0999a35878b997fdca)

## わかりやすそうなBlog

[高卒でもわかる機械学習 | 頭の中に思い浮かべた時には](http://hokuts.com/2015/11/24/ml0/)
[AI技術をぱっと理解する（基礎編） | ASIA](https://products.sint.co.jp/aisia/blog/tag/ai_blog_basics) 

# ReNomのドキュメント読んで

## データの前処理

[数値データとカテゴリデータのマージ - ReNom](http://www.renom.jp/ja/notebooks/preprocessing/preprocessing/notebook.html)

- どのような前処理が一般的なのかわかる
- 以外と簡単なことしかやっていない印象

## TDA

Topological Data Analysis（位相的データ解析）の略
図形中の穴の数で区別する、というのは驚き

[Topological Data Analysis(TDA、位相的データ解析)の参考文献 - Qiita](https://qiita.com/snuffkin/items/b032fa5a938e13275177)

- 参考になる文献がまとまっているよ

[位相的データ解析（Topological Data Analysis）について | ALBERT](https://blog.albert2005.co.jp/2016/02/12/%E4%BD%8D%E7%9B%B8%E7%9A%84%E3%83%87%E3%83%BC%E3%82%BF%E8%A7%A3%E6%9E%90%EF%BC%88topological-data-analysis%EF%BC%89%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6/)

- わかりやすい

[柔らかいトポロジーの穴から眺める世界](http://www.sci.shizuoka.ac.jp/sciencecafe/news/20160128_02.pdf)

- 特にこのスライドはわかりやすい

## SGD

Stochastic Gradient Descent（確率的勾配降下法）の略

[確率的勾配降下法とは何か、をPythonで動かして解説する - Qiita](https://qiita.com/kenmatsu4/items/d282054ddedbd68fecb0)

- [CourseraのMachine Learning](https://www.coursera.org/learn/machine-learning)でやった最急降下法 (Grandient Descent) を思い出した（全部やってない、終わらせたいな！）

## 画像分類

[画像分類の流れと参照](http://www.renom.jp/ja/notebooks/neuralnetwork/classification_basic/notebook.html)

- 「よって配列の形は(500, 353, 3)となります。」確かにって感じ

# Machine LearningとDeep Learningの違い

[「機械学習」と「ディープラーニング」は何が違うのか？ | MUFG Innovation Hub](https://innovation.mufg.jp/detail/id=93)

- Machine Learningは人間が考えた分析のための特徴量に従い、分析される
- Deep Learningは特徴量もデータから学習してくれる

[機械学習とディープラーニングの違い (Vol.5) | AI技術をぱっと理解する（基礎編）](https://products.sint.co.jp/aisia/blog/vol1-5)

- 違いについては言及されていないが、（というより、「機械学習 ⊃ 深層学習」とのことなので、違いという観点がちょいナンセンス）Deep Learningについてわかりやすく説明されている

[AIとは？AI（人工知能）とDeep Learning（深層学習）を簡単に説明 | OPTiM Cloud IoT OS](https://www.optim.cloud/blog/ai/ai-deeplearning/)

- AI全般に対し、浅く広く説明してくれている
Googleスライドでスライドショー・書き出しするとフォントが変わる問題の解決

#結論

- Google Fontのフォントから選べば変わらない
- 最近Google Fontに日本語のフォントも追加されたので、それを使う

# やりかた

### フォント選択から「その他のフォント」を選ぶ
<img width="351" alt="スクリーンショット 2018-09-12 14.13.42.png" src="https://qiita-image-store.s3.amazonaws.com/0/99270/b5a504c8-dc9c-9420-444f-bd2656207137.png">


### 日本語フォントを検索してリストのフォントをクリックし、マイフォント欄に追加されたことを確認する
<img width="735" alt="スクリーンショット 2018-09-12 14.14.04.png" src="https://qiita-image-store.s3.amazonaws.com/0/99270/bde8cb33-5a2b-7de9-366d-c7cf1007853f.png">

> Google Fontにある日本語フォント一覧
> https://fonts.google.com/?subset=japanese
> **「Noto」「Kosugi」「M PLUS」「Sawarabi」で検索して出てきたのを追加しておくと吉**
> (おすすめはKosugi, Notoあたり)

###フォント一覧に追加されるので使用する

<img width="266" alt="スクリーンショット 2018-09-12 14.19.56.png" src="https://qiita-image-store.s3.amazonaws.com/0/99270/9e1af54c-53c6-1114-5081-862e791c1605.png">

### 画像書き出し・スライドショーでもフォントが変わらない!!

デバイスフォントが使えないのは相変わらずなんですが、多少はマシになると思います。
AWSのチュートリアル「エンドツーエンドの IoT アプリケーションをデプロイする」を進めるときのまとめ

AWSの[このページ](https://aws.amazon.com/jp/getting-started/projects/deploy-iot-application/)で「プロジェクトガイドを使用して今すぐはじめる」を押すと表示されるチュートリアルのPDFがところどころ実画面と違っているので、自分用にまとめました。

## Create an IoT Thing
PDFの9ページ目からが大きく異なります。

### 4. Provide a name for the Thing, and click Create thing.
ガイドではCreate thingを押した後にすぐ5にいけるように見えますが、まずモノの名前を入れたら「次へ」の青いボタンを何も入れずに押して先へ進めて、モノの登録を完了させます。
※最後のステップは「証明書なしでモノを作成する」を選択
その次の手順5はこの登録完了したモノについて、モノの一覧画面から開き、API Endpointを表示させるようにします。

## Create an IoT Policy
ガイド通り進めます。

## Create an IoT Certificate
ガイド通り進めますが、AWSの画面を見ているとつい
安全性＞証明書＞作成＞1-Click 証明書作成 (推奨)
という手順で進めたくなってしまいます。このガイドでは
手順1：RasPiからEC2インスタンスにSSHすると
手順2：キー三つ(certificate.pem.crt/private.pem.key/root-ca.pem)が出来上がっていて
手順3：AWSのIoTコンソールに入ると勝手に証明書が出来上がっていてActiveになっている

という流れになっています。
続けて

手順4・5：3でコンソール上に表示された証明書の右上の...ボタンから、前ステップで作成したIoTポリシーにアタッチします。
手順6：証明書の...ボタンから、証明書をモノにアタッチします。


# Raspberry Piと別のPCでAWSをブラウザ上で操作する場合の使い分け
基本は手元の端末で進めて、RasPiから操作が必要な場合のみRasPiで行いたいのですが「AWSコンソールに表示されたアドレスに向けて〇〇する」などの操作が多いので、RasPiでもブラウザからAWSコンソールにログインしておくようにします。
※手元の端末とRasPiでファイルの行き来が容易な場合は使い分けする必要ないと思います

- Step 1: Set Up the Environment
    - 【RasPi】Create an SSH Keypair
    - Deploy the AWS CloudFormation Template
        - 手順10, 11のみRasPiのブラウザで行い、値をメモ帳等にコピーしておく
    - 【RasPi】Confirmation: Connecting to your Instance
- Step 2: Set Up AWS IoT
    - AWS IoT Overview
    - Create the AWS IoT Resources
    - Create an IoT Thing
        - 手順5のみRasPiのブラウザで行い値をメモ帳にコピーしておく
    - Create an IoT Policy
    - Create an IoT Certificate
    - 【RasPi】Configure and Run the Device Simulator
    - Create an IoT Rule and Action
    - Confirmation: View Device Messages with the AWS IoT MQTT Client

---
Create an IoT Certificate で数日ハマっていましたが、落ち着いて読み直しながらやったところ、なんとかできました。
Realm 使い方

#コード作成

```swift:Item.swift
import RealmSwift
class Item: Object{
    // 品名
    dynamic var name: String? = nil
    // 金額
    dynamic var price = 0
    // 登録日時
    dynamic var created = Date()
}
```
###1. 保存
```swift:ViewController.swift
        // 保存
        let realm = try! Realm()// デフォルトRealmを取得
        try! realm.write {
            realm.add(item)
        }
```

###2. 読込
```swift:ViewController.swift
        // 読込
        let realm = try! Realm()// デフォルトRealmを取得
        self.itemList = realm.objects(Item.self).filter("price > 0").sorted(byProperty: "created", ascending: false)

```

>- [Qiita Swift3でRealmSwift（サンプルあり）](https://qiita.com/koji-nishida/items/99efb572ef7d809bb2c1)
>- [【永久保存版】RealmSwiftの使い方 – Swift4.0 - 月曜からSwift](http://somen.site/2018/02/02/realmswift%E3%81%AE%E4%BD%BF%E3%81%84%E6%96%B9%E6%B0%B8%E4%B9%85%E4%BF%9D%E5%AD%98%E7%89%88-swift4-0/)
Ruby メソッド

#メソッド
メソッドとは、ある処理をまとめたものです。

##メソッドの定義
「def メソッド名」と「end」の間に、まとめたい処理を書くことでメソッドをつくることができます。このことを「メソッドを定義する」と言います。

**例）**

```ruby
def introduce  # introduceメソッドを定義
 puts "こんにちは"
 puts "私はTakayukiです"
end
```

上の例では、2つの出力を行う、introduceメソッドを定義しています。

###メソッドの呼び出し
メソッドは、定義するだけでは実行されません。
「メソッド名」とすることで実行できます。メソッドを実行することを、「メソッドを呼び出す」と言います。

**例）**

```ruby
def introduce  # introduceメソッドを定義
  puts "こんにちは"
  puts "私はTakayukiです"
end
introduce
```
コンソール

```
こんにちは
私はTakayukiです
```

##引数
引数（ひきすう）とはメソッドに与える追加情報のようなものです。メソッドを呼び出すときに一緒に引数を渡すことで、メソッドの中でその値を利用することができます。

**例）**

```ruby
def introduce(name)
  #処理
end
```

このように、「def メソッド名(引数名)」とすることで、引数を指定することができます。

###引数を受け取るメソッドの呼び出し
引数を渡してメソッドを呼び出すには、「メソッド名(値)」とします。
メソッドは、指定した値を受け取り、その値は引数に代入されます。

**例）**

```ruby
def introduce(name)
  #処理
end
introduce("Yukihiro")
```

introduceメソッドの呼び出し時に「"Yukihiro"」という値が渡され、引数nameに代入されています。

###メソッド内で引数を使用する
引数はメソッド内では変数のように使用することができます。

**例）**

```ruby
def introduce(name)
  puts "こんにちは"
  puts "私は#{name}です"
end
introduce("Yukihiro")
introduce("Takayama")
```
コンソール

```
こんにちは
私はYukihiroです
こんにちは
私はTakayamaです
```

###引数の呼び出し時の注意点
引数のあるメソッドは、引数を渡さずに呼び出すことができません。 
引数を渡さないで呼び出そうとすると、エラーになってしまいますので注意が必要です。

##メソッド定義のスコープ
メソッドを定義するときに用意した引数は、そのメソッドの中（defからendまでの間）でしか使うことができません。

###メソッドの中の変数
メソッドの中で定義した変数も、引数と同じように、そのメソッドの中（defからendまで）でしか使うことができません。

##複数の引数
引数は複数受け取ることもできます。括弧の中に受け取る引数をコンマ(,)で区切って並べることで、複数の引数を指定することができます。

**例）**

```ruby
def introduce(name,age)
  puts "私は#{name}です"
  puts "#{age}歳です"
end
introduce("Yukihiro",25)
```

コンソール

```
私はYukihiroです
25歳です
```

引数は、左から順番に「第1引数、第2引数」というように呼びます。

##戻り値
呼び出し元で受け取る処理結果を戻り値（もどりち）と呼び、このことを「メソッドが戻り値を返す」と言います。
「return 値」と書くことで、メソッドはその値を戻り値として返します。

```ruby
def add(a,d)
  return a + b #戻り値
end
sum = add (1,3) #呼び出し部分
puts sum
```
コンソール

```
4
```
戻り値がある場合、メソッドの呼び出し部分がそのまま戻り値に置き換わります。 
よって、このようにメソッドの呼び出し部分を変数に代入するように書くことで、メソッドの戻り値を受け取ることができます。

###戻り値if
if文で使うような条件式をreturnすると、その条件式の結果として得られる真偽値（trueまたはfalse）を返すことができます。
真偽値を返すメソッドは、メソッド名の末尾に「?」をつける慣習があります。

```ruby
def nagative?(number)
 return number < 0
end
puts negative?(5)
```
コンソール

```
false
```

###returnの性質
returnは、戻り値を返すだけでなく、メソッドの処理を終了させる性質も持っています。
よって、returnの後にあるメソッドの処理は実行されません。

###複数のreturn
メソッドでは、条件分岐を組み合わせることで複数のreturnを用いることができます。

**例）**

```ruby
def judge(score)
  if score > 80
     return"よくできました"
  end
  return "がんばりましょう"
end
puts judge(70)
```
コンソール

```
がんばりましょう
```

この例では、引数が80以下なので、ifの中のreturnは実行されず、if文の後のreturnが実行されています。もし引数が80より大きければ、ifの中のreturnが実行され、そこで処理が終了します。

##キーワード引数
引数の数が多くなると、呼び出し側で値がどの引数に入るのかがわかりにくくなります。
キーワード引数を用いた書き方をすることで、呼び出し側で引数を明記することができ、わかりやすくなります。

**例）**

```ruby
def introduce(name:,age:)
  puts "私は#{name}です"
  puts "#{age}歳です"
end
introduce(name:"Yukihiro",age:25)
```

① 定義側で、引数の後にコロンを付ける
② 呼び出し側で、値の前に引数名を書く
とすることで、キーワード引数を持つメソッドを書くことができます。

##おわり
[Ruby 基礎](https://qiita.com/y-takayama/items/fe031827297f0b6653b5)
[Ruby 基礎（配列について）](https://qiita.com/y-takayama/items/54c1a7b299af767d62ef)
オブジェクト指向をやる前に、分析と設計……ってなんだっけ？ 分析と設計の違いとは。

# なんのはなし？

プログラマー、ソフトウェア開発とか続けているとわかってきますが、やっぱり急にコードを書き始めるとあまり良くないことが起きます。
「コード書く前にやることあるでしょ？」と。
それが「分析」とか「設計」とか言われるものだったりして「設計書は書いたの？」とか言われるものです。

じゃあ「分析とか設計とかって何！？」 「設計書って何？？」となってくるので、ここら辺で一回まとめてみたいと思います。

## その前に...

エンジニアの仕事とはいったい何でしょうか。

**やることは１つ。 シンプルに言えば『課題の解決』、ただそれだけです。**

とはいっても世の中に存在する「**課題**」というのはとても複雑なものでそれを「**解決**」するための方法も多種多様です。
一筋縄ではいきません。

さて、そんな複雑な状況でいったい何をどうすればいいのか？

それを華麗に解決するための方法が「分析」と「設計」です。

> オブジェクト指向では OOAD といって、Object Oriented **Analysis** and **Design** という言い方をするものです

では、１つ１つ見ていきます。

## その１． 課題を「分析」する ＝ What を定義する

一言で「課題」と言っても実はその課題が何か？というのは誰もわかっていないことが多いです。
例えば、

- **ユーザの○○申請を自動化したい。**

という話があったとして、

- 自動化したい申請というのは一体何でしょうか。
- その申請にはどういう情報は含まれていて、申請する前には何をしていて、申請すると何が起きるのでしょうか。
- そもそもなぜ自動化したいのでしょうか。

そんなことを考えながらまずは「**課題ってなんだ！？＝What's 課題？**」を明らかにする必要があります。

それが「**分析**」です。

**ポイント**は、課題は何なのかを定義するだけであってこの段階では解決策については考えていないということです。課題を明らかにする、紐解くだけであって、そこに解析者の意思が入り込んではいけません。

例えば、

- ユーザーと言ってるけどユーザーにも何種類かある。承認者と申請者と…
- 申請書に書かれている内容は？ 名前や日付や部署名… 他には？
- ユーザーと申請書は 1:N の関係になっている
- 申請がおわった申請書は破棄され履歴は不要になるの？
- 申請書は 申請 → 承認待ち → XXX という状態遷移を持っている。却下や取り下げもできる

こういったことを「分析」していきます。
つまり自分たちが解決しなければいけない課題はいったい何なのかを定義していきます。

補足的に言うとこの「分析」というものは専門的には「**関心の分離**」と表現することがあって自分たちが対処しなければいけない関心事を明確にする作業です。そしてそのときに考え方の指針となる１つが「**オブジェクト指向**」です。 関心事を、オブジェクトという単位を元にして、分解や分類をすることで、明確にしていく作業になります。

> オブジェクト指向の詳しい話は本題ではないので省略

## その２． 課題の既決策を「設計」する ＝ How を考える

さて、課題が具体的に何かがわかったところでその課題をどうやって解決するか？を考えます。

それが「**設計**」です。

自動化対象は○○で、情報としては△△があって、それは夜間に処理される必要があって。。。

という風に分析されたもの対して、色々な解決策を考えてきます。

- こういう情報があるなら、、それは、RDBよりもNoSQLの方が向いている（DB設計）
- 夜間に処理する必要があるならスケジューラを使ったほうがよさそう（システム構成の設計）
- スケジューラを動かすなら24hの体制を作る必要がある（保守設計、運用設計）
- 技術者を集めやすいのでNode.js/ExpressでWebを使った3層モデルでいこう（アーキテクチャ設計）
- CSSはBEMのルールで…（実装設計）
- コーディングの環境はVSCodeでCircleCIでCIをやろう…（実装環境の設計）

他にも様々な設計を行っていき解決策を考えます。

このように様々な視点で「解決策を考える」のが「**設計**」です。


## その３． 設計書を書く

最後に。

せっかく設計を考えたのだから「**設計書**」を書くのも悪くはありません。

ただこれは設計したものを書き留めておいたり人が読める形にするのが目的であって設計書を書くこと自体は決して目的ではありません。

と言っても「設計書が要らない」と言うわけではないです。

大きく３つの目的が考えられます。

### **－ 壱． 設計した本人が忘れないようにするため －**

設計はとても多岐にわたるのでそのすべてを何年もの間覚えておくことは困難です。
なので「ドキュメント」に残すことで後で読み直すことが可能になります。

### **－ 弐． そもそも設計するため －**

これは壱に近いのですが複雑な設計をするときには設計をしてるそばから忘れていく可能性があります。

例えて言うなら、１ケタの暗算ならできますが１０００ケタの計算は筆算が必要で暗算が出来ないのと一緒です。
（出来る人もいるかもしれませんが……わたしには無理です……）

それと同じで、簡単な設計なら頭の中だけで出来るので紙に頼る必要はありませんが、複雑な設計になってくれば頭の中だけでは整理できないので紙に残しながら行う必要があるのです。

### **－ 参． みんなに読んでもらうため －**

頭の中で考えた設計を共有することはできませんが「ドキュメント」になっていればそれを関係者で読むことができます。

関係者が読むことができればそれによって間違いに気付くことができたり更により良い案を考えることもできます。

いわゆるレビューが可能になります。
品質が上がります。

### **では設計書は"絶対"にあった方がいいのか？**

上のようなメリットが明らかに無いのであれば設計書はいりません。

頭の中で考えられるならそれでいいですし、ホワイトボードに書いてすむならそれでいいです。ソースコードから設計の意図が理解できるのであれば別のドキュメントを作る必要はありません。

ただ逆に、ソースコードから読み取れない意図や背景がある場合や、関係者に何かを伝えなければいけないときには書いてください。


## おわりに

ということで、このような分析と設計の違いや、設計書の意味などは、初学者ではなかなか出会う機会がないと思いますので、少し時間あったのでまとめてみました。
CircleCI 2.0 + Carthage で carthage bootstrap に時間がかかる場合の解決方法

# 問題

iOSアプリ開発で Carthage ディレクトリ配下をGitの管理下に入れないようにしたところ、CIのビルドマシン上で毎回 `$ carthage bootstrap` することになり、非常に時間がかかってしまっていた。

# 解決方法

Carthage ディレクトリ配下をキャッシュして、前回から変更がない限りそれを読み出すようにすれば良い。

`.circleci/config.yml` の該当箇所は以下のようになる

```(抜粋).circleci/config.yml
      - restore_cache:
          key: ca-{{ checksum "Cartfile.resolved" }}
      - run:
          name: Carthage
          command: carthage bootstrap --platform iOS --cache-builds
      - save_cache:
          key: ca-{{ checksum "Cartfile.resolved" }}
          paths:
              - Carthage
```


## 各行の説明


```(抜粋2).circleci/config.yml
- restore_cache:
    key: ca-{{ checksum "Cartfile.resolved" }}
```

CircleCI上でキャッシュを読み出す。 `Cartfile.resolved` のチェックサムをキーにキャッシュを読み出すという意味。
こうしておけば、 `Cartfile.resolved` に変更があった場合はキャッシュを読み出さずに済む。

```(抜粋3).circleci/config.yml
- run:
    name: Carthage
    command: carthage bootstrap --platform iOS --cache-builds
```

`--cache-builds` は `$ carthage bootstrap` でチェックアウトしたファイルと`Carthage` ディレクトリ配下のファイルに差分がない場合にビルドをスキップするオプション。

```(抜粋4).circleci/config.yml
- save_cache:
    key: ca-{{ checksum "Cartfile.resolved" }}
    paths:
        - Carthage
```
CircleCI上で`Carthage` ディレクトリ配下のファイルをキャッシュする。 `Cartfile.resolved` のチェックサムをキーにする。

# 環境

- CircleCI 2.0
- Xcode 9.4

# リファレンス
* [Caching Dependencies - CircleCI](https://circleci.com/docs/2.0/caching/)
* [Carthage/Carthage: A simple, decentralized dependency manager for Cocoa](https://github.com/Carthage/Carthage#caching-builds)