OmniAICreator/Qiita-1.07M huggingface dataset:
stm32f4-discoveryの作法 その4

#概要

stm32f4-discoveryの作法、調べてみた。
serialに、垂れ流す。

#サンプルコード


```
#include "stm32f4_discovery.h"
#include <stm32f4xx.h>
#include <stm32f4xx_usart.h>
#include <stdio.h>
#include <stdarg.h>

void init_usart(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	USART_InitTypeDef USART_InitStructure;
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_USART2);
	USART_InitStructure.USART_BaudRate = 9600;
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;
	USART_InitStructure.USART_StopBits = USART_StopBits_1;
	USART_InitStructure.USART_Parity = USART_Parity_No;
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
	USART_InitStructure.USART_Mode = USART_Mode_Tx;
	USART_Init(USART2, &USART_InitStructure);
	USART_Cmd(USART2, ENABLE);
}
void uart_send(const char * str)
{
	while (* str)
	{
		while (USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET);
		USART_SendData(USART2, * str++);
	}
}
void printk(const char * fmt, ...)
{
	char a[256] = {
		'\0'
	};
	va_list ap;
	va_start(ap, fmt);
	vsprintf(a, fmt, ap);
	uart_send(a);
	va_end(ap);
}
void delay(__IO uint32_t nCount)
{
	while(nCount--)
	{
	}
}
int main(void)
{
	init_usart();
	while (1)
	{
		printk("ok\n");
		delay(0xFFFFFF);
	}
}



```

#配線

PA2が、出力。


以上。
Document Image Classification with Intra-Domain Transfer Learning and Stacked Generalization of Deep Convolutional Neural Networks

ImageNetなどの一般的な画像分類からの転移学習で、特定の小さいドメインの問題が解けるのが関心があったので読んでみました。

### Reference
- [Document Image Classification with Intra-Domain Transfer Learning and Stacked Generalization of Deep Convolutional Neural Networks](https://arxiv.org/abs/1801.09321)
- Presented on ICPR 2018

文中の図表は論文より引用しています。

この記事は、Wantedlyの勉強会で取り上げられた論文・技術をまとめたものです。
[2018年に読んだ機械学習系論文・技術まとめ at Wantedly Advent Calendar 2018 - Qiita](https://qiita.com/advent-calendar/2018/wantedly_ml)

## モチベーション
デジタル化以前の過去の大量の文章をデジタル化して、有効活用したいという関心がある。

そのためにOCRをしてドキュメントにするが、色々な種類のドキュメントを一律に扱うのは難しい。
例えばテーブルとか手書きとかは何らかの前処理をするかも知れないし、請求書とかは項目名と数値部分にだけ関心があるかも。
そのため画像をまずは表・請求書・メモなどに分類して扱いたいというストーリー。

この論文は、文章画像はそんなに大量にない点と、224*224くらいのネットワークでは文字レベルの解像度を見るのが難しいという問題にチャレンジしている。

## 手法
メインのコントリビューションは2点。

- 2種類の転移学習, inter-domain, intra-domainを行って精度を上げた。
- 部分領域の分類からスタッキングする手法で精度を上げた。

### 転移学習部分
２種類の転移学習を行った。

- L1: ImageNetで学習したVGG16モデルをベースに、この問題の16種類の分類問題を学習する。
- L2: L1で学習したモデルをベースに、「ドキュメントの小さい領域」を見て16種類の分類問題を学習する。図を参照↓

L1は普通の転移学習。L2がなぜ必要なのか？
モデルはVGG16で、インプットは224 × 224にリサイズされる。このサイズだと文字認識はかなり難しそう。実際に下の画像全体を224*224にリサイズすると恐らく文字は読めない。→部分に分けて認識するというアイディア

![image.png](https://qiita-image-store.s3.amazonaws.com/0/64964/72d7a103-4921-d56e-65a4-e522ab2a8cc9.png)

この論文では、入力画像を小さな部分領域（Header, Footer, Right, Left）に分割してそれを入力として分類するモデルを作った。論文だったらヘッダ部分に特定のレイアウトが見れるし、請求書だったらフッタ部分に定形の文章が来るかも知れない。こういった人間の知識を素直に入れた形。

その後、部分領域と全体の認識結果をConcatしたものを特徴量として、さらにメタ分類器を入れて最終的な16種類の分類を行うというもの。
Kaggleとかで使われるStacking手法と同じ。ただ計算コストは5倍に増えるはず。（ちなみにメタ分類機は、Multi−layer Neural Networkが良かったらしい）

### どうやって有効だと検証した？
16種類の画像データ・セット http://www.cs.cmu.edu/~aharley/rvl-cdip の分類精度でSOTを達成したと報告されている（16クラスならもっと行く気がするけど16種類にアノテートされたデータを見ると人間でも判断が悩むところがありそう）。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/64964/a496e89f-e754-682c-24bf-aeaffbd8d880.png)

## 議論・感想
ドメインが違っても転移学習が有効だったのは知見として面白かったけど、アンサンブルしても1.1％プラスにしかならない。単純に比較して5倍の計算量がかかってもそれに価値があるかは疑問。

ヘッダ・フッタみたいに分ける部分は、実はランダムにパッチで見てアンサンブルという方法でも同じくらいの精度が出るのではとか色々疑問がありそう。

あとドキュメントの分類は2018年時点でもそこまでフォーカスしてやられていないという感想だった。ImageNetなどの分類問題が高精度で解かれているから、本質的には解かれている問題のドメインが違うだけという認識が強いのかも知れない。
iOS+Firebaseでの実装まとめ1

#1.はじめに
Firebaseが良いという話が社内でよく聞いていたもののFirebaseで何ができるのか全然理解できていませんでした。そんな時個人開発で作りたいアプリがあり、web知識ゼロの僕でもサーバーサイドを簡単に実装できるサービスを探していました。そんな時、[こちら](https://qiita.com/kazu0620/items/20ea8cd1c3a2e3bb5574)の記事でMBaaSというものを知ったのでバックエンドはFirebaseすることにしました。
割と調べればFirebaseについての記事もそこそこありますし、公式ドキュメントも充実しているので、作りやすかったですが、それでもつまずいた点もあったので、毎度同じみ備忘録として残します。量が多いので、何回かに分けて投稿する予定です。少しでも参考になれば幸いです。

#2.MBaaSとは
まずは概要から。
読み方は`"エムバース"`。**Mobile Backend as a Service**の略で、2012年ごろからアメリカで使われるようになった言葉のようです。スマホ向けのウェブアプリ機能を提供するサービスのこと。
###・メリット
1. サーバ側の設計が不要
2. サーバを運用する必要がない
3. コストがかからない
4. スピーディーなアプリ開発が可能
5. セキュリティ面が安心

###・デメリット
1. 開発しているアプリの根幹データを預けることになるため、何か問題が生じても乗り換えられない
2. 無料サービスの場合、機能制限があることが多い
3. 従量課金の場合、アプリが大きくヒットするとそれなりのお金がかかる可能性がある

MBaaSサービスはFirebase以外にも色々ありますが、作るサービスによって慎重に選定する必要があります。僕の場合はFirebaseで実装したかったので、Firebase一択でした。

#3.Firebaseでできること
1. **リアルタイムデータベース（Firebase Realtime Database）**
2. **クラウドストレージ(Firebase Cloud Storage)**
3. **アプリのアクセス解析（Firebase向けGoogleアナリティクス）**
4. **クラウドメッセージング（Firebase Cloud Messaging）**
5. **認証（Firebase Authentication）**
6. **クラッシュ分析（Firebase Crashlytics）**

#4. Firebase料金
基本的に無料で利用できます。拡張する場合にデータ量に応じて料金が発生します。
プランそれぞれは**無料のSparkプラン**、**月額25ドルのFlameプラン**、**従量制のBlazeプラン**の3種類。
無料プランの場合は、同時接続数や容量に制限があります。個人開発レベルでは無料プランで十分対応可能だと思います。
料金詳細については公式の[こちら](https://firebase.google.com/pricing/)を参照のこと

#5.導入
僕の場合、認証とリアルタイムデータベース、画像を保存するようにクラウドストレージをメインで使用したのでそれらの導入方法です。
Firebase自体の導入方法については、他にも記事があるので割愛しますが、こちらの記事で丁寧に書かれているので参考になるかと思います。
・[SwiftアプリにFirebaseを入れてみた](https://qiita.com/tochi/items/8828fe3de5408b0bcc0b)

まずはみんな大好き**cocoapods**でライブラリを追加します。
プロジェクトのPodFileに下記を追加。

```bash
pod 'Firebase/Auth'
pod 'Firebase/Storage'
pod 'Firebase/Database'
```
そして

```
pod update
```
初めてライブラリを導入した時に陥ったところなんですが、プロジェクトに初めてライブラリを入れると、プロジェクトディレクトリ以下に、新たにワークスペースファイル(.xcworkspace)が作られるので以後これを開いて開発を進めないとビルドエラーとなりますので注意してください。

あとは使用するファイル内で以下のようにインポートして使用できる状態となります。

```swift
import FirebaseDatabase
import FirebaseAuth
import FirebaseStorage
```
これで準備完了です。
不定期ですが、次回は、実装とFirebaseコンソールでの設定方法について記載できたらと思います。
早くアプリをリリースさせたい...
MySQLを指定してrails newし、rails serverするまでの覚書

たまに新規でアプリを作ろうとすると忘れてるので覚書です。

初心者がとりあえず、railsのアプリを作成して立ち上げる事を想定しています。
コマンドの細かいオプション等は省いています。

## rails new
rails newする時、よく使うと思われるのが下記のオプション

```
rails new rails_app -d mysql -B
```

- ```rails new アプリ名```でrailsアプリの標準ファイルを生成します。
- オプション```-d データベース名```は、データベースを指定してアプリを作成する。デフォルトだとsqliteになっています。
- オプション```-B```は、bundle installを自動実行しないオプション。Gemfileを編集してからbundle installしたい場合に指定します。

詳しくは下記のリンク参照
http://railsdoc.com/rails

## bundel install
rails newするとrailsの基本フォルダが出来ます。
Gemfileを編集したい場合は、編集しbundle installして下さい。

bundle installするには、まず先ほど作ったアプリの直下に移動します。

```
cd rails_app
```

bundle installを実行します。

```
bundle install
```

## DB作成
database.ymlに書いてあるdbを作成します。

```
rake db:create
```

-d mysqlをしたので、database.ymlはmysqlの設定で作られています。

## rails s
サーバーを立ち上げましょう。

```
rails s
```
デフォルトだとポート3000でサーバーが起動するので、下記にアクセスして完了です。

```
http://localhost:3000
```
SQLを修正して修正前と結果が変わらないことを確認する

パフォーマンスチューニングをおこなう際に修正したSQLの取得結果が修正前と変わらないことを確かめるために調べました．

## 事前準備

例えばこんなテーブルとデータがあったとします．

```sql
CREATE TABLE SAMPLE_ROLL
(
    ID int,
    NAME nvarchar(20),
    PRIMARY KEY(ID)
);

CREATE TABLE SAMPLE_USER
(
    ID int,
    NAME nvarchar(20),
    ROLL_ID int,   
    PRIMARY KEY(ID),
    FOREIGN KEY(ROLL_ID)
      REFERENCES SAMPLE_ROLL(ID)
);

INSERT INTO SAMPLE_ROLL(ID, NAME) VALUES(1, 'ADMIN01');
INSERT INTO SAMPLE_ROLL(ID, NAME) VALUES(2, 'TEST01');
INSERT INTO SAMPLE_ROLL(ID, NAME) VALUES(3, 'TEST02');

INSERT INTO SAMPLE_USER(ID, NAME, ROLL_ID) VALUES(1, 'user01', 1);
INSERT INTO SAMPLE_USER(ID, NAME, ROLL_ID) VALUES(2, 'user02', 1);
INSERT INTO SAMPLE_USER(ID, NAME, ROLL_ID) VALUES(3, 'user03', 2);
INSERT INTO SAMPLE_USER(ID, NAME, ROLL_ID) VALUES(4, 'user04', 3);
INSERT INTO SAMPLE_USER(ID, NAME, ROLL_ID) VALUES(5, 'user05', 3);
INSERT INTO SAMPLE_USER(ID, NAME, ROLL_ID) VALUES(6, 'user06', 3);
```

あるSQLが遅いとします．

```sql
SELECT * FROM SAMPLE_USER u WHERE u.ROLL_ID IN (SELECT r.ID FROM SAMPLE_ROLL r WHERE r.NAME LIKE 'TEST%');
```

## チューニング

INをEXISTSで書き直します．

```sql
SELECT * FROM SAMPLE_USER u WHERE EXISTS (SELECT * FROM SAMPLE_ROLL r WHERE r.NAME LIKE 'TEST%' and u.ROLL_ID = r.ID);
```

## 確認

修正前と修正後で取得結果が変わらないことを確かめるにはEXCEPTで差が無いことを確認します．

```sql
SELECT * FROM SAMPLE_USER u WHERE u.ROLL_ID IN (SELECT r.ID FROM SAMPLE_ROLL r WHERE r.NAME LIKE 'TEST%')
EXCEPT
SELECT * FROM SAMPLE_USER u WHERE EXISTS (SELECT * FROM SAMPLE_ROLL r WHERE r.NAME LIKE 'TEST%' and u.ROLL_ID = r.ID)
```

## サンプル

一気通貫で確認したいかたは以下のsqlで．

```sql
BEGIN tran

CREATE TABLE SAMPLE_ROLL
(
    ID int,
    NAME nvarchar(20),
    PRIMARY KEY(ID)
);

CREATE TABLE SAMPLE_USER
(
    ID int,
    NAME nvarchar(20),
    ROLL_ID int,   
    PRIMARY KEY(ID),
    FOREIGN KEY(ROLL_ID)
      REFERENCES SAMPLE_ROLL(ID)
);

INSERT INTO SAMPLE_ROLL(ID, NAME) VALUES(1, 'ADMIN01');
INSERT INTO SAMPLE_ROLL(ID, NAME) VALUES(2, 'TEST01');
INSERT INTO SAMPLE_ROLL(ID, NAME) VALUES(3, 'TEST02');

INSERT INTO SAMPLE_USER(ID, NAME, ROLL_ID) VALUES(1, 'user01', 1);
INSERT INTO SAMPLE_USER(ID, NAME, ROLL_ID) VALUES(2, 'user02', 1);
INSERT INTO SAMPLE_USER(ID, NAME, ROLL_ID) VALUES(3, 'user03', 2);
INSERT INTO SAMPLE_USER(ID, NAME, ROLL_ID) VALUES(4, 'user04', 3);
INSERT INTO SAMPLE_USER(ID, NAME, ROLL_ID) VALUES(5, 'user05', 3);
INSERT INTO SAMPLE_USER(ID, NAME, ROLL_ID) VALUES(6, 'user06', 3);

SELECT * FROM SAMPLE_USER u WHERE u.ROLL_ID IN (SELECT r.ID FROM SAMPLE_ROLL r WHERE r.NAME LIKE 'TEST%')
EXCEPT
SELECT * FROM SAMPLE_USER u WHERE EXISTS (SELECT * FROM SAMPLE_ROLL r WHERE r.NAME LIKE 'TEST%' and u.ROLL_ID = r.ID)

ROLLBACK tran
```
そろそろ銀行コードとか金融庁API化しないのかな・・・。

# ぼちぼちいいんじゃない？
オンラインとかで、銀行口座とか登録するときに、銀行のサイトの中だと手厚くて、「あいうえお」とかで検索できたりしますよね。
# アプリとか
メルカリさんとか銀行選択画面とても便利でした。
素晴らしいUI
これは真似したい！！
# で同じようにしたい
いろいろ調べたのですが、
公的なものは、全国銀行協会様のもので、CDで配布しているそうです。
https://www.jba-shuppancenter.jp/PublishMsts/detail/MjAzNTAwMTkwMg==
４６３００円/Month です。
自分のプロジェクトでは不採用になりました。
# APIないの？
あったのですが、サービスの方にメール送ってみて返事来ませんした。
https://bankcode-api.appspot.com/
いいなって思ったのに。
他にRubyのGemで開発されている方がいまして、こういうのありました。
https://github.com/zengin-code/zengin-rb
データどうしてるのかなって気になりましたが、
https://github.com/zengin-code/source-data
こちらに。
元データは、こちらのページのものを採用しているようです。

角ちゃんのページ
http://ykaku.com/ginkokensaku/index.php

このデータ提供している方、個人の方みたいなのですが、ほんと神だと思いました。

それほど、正確性にとらわれなければ、こちらのデータ採用するのがいいのかなと思いました。

いろいろ調べて、他の方も書いておられました。

たぶん、正確性を着するには、全銀さんが著作権たてに高い値段で売っているのを買うのがまっとうな銀行コードメンテナンスになるようです。

一ヶ月1000円くらいでAPI開放したらもっと売れそうな気がするのですが。
日本から海外にオンラインで売った時に、海外の方から振込してもらうとか？
国際コードあるからまた違うのかな。

# 国境とか
そう考えると、国内の流通だけ考えたら、全銀さんでいいのかもしれませんが、SWIFTとかもできてて、むしろこっちのAPIとかおもソロスやなって思いました。
https://transferwise.com/jp/swift-codes/
あるんかな？　国内でSWIFT送金しちゃったりとかできたらすげーと思いますけどそうはうまくいかないですよね。(´∀｀)

# 貨幣と国家
通貨発行権、軍事、外交など国っていろんな権限もってますよね。
仮想通貨ってそういう枠組み超えてみたい実験なんだと思うのです。
海外で仕事して、母国にお金送る。それやろうとすると、既存の金融システムだとめちゃ手数料かかるから、だったらBitCoinでいいんじゃね？
みたいなことを考えて人がいて、めっちゃ価値上がったのかなと。

# ヨタル
別に、国家批判者とかじゃないです。
色んな国でいろんな方たちがいて、日本だとインバウンドすげーって思うんですけど、なんで、うちら長期休暇とか取れんのかとか。海外うらやましいっすって気持ちが最近あります。
休んじゃいけないってまじよろしくないと。物価の高い国で５年頑張って、母国戻って起業してとかできたら、そうとう労働意欲湧くと思うんすよね。
日本国に生まれ育った身としては、国の問題なのか？国民性なのか？わかんないっす。ただ、海外の人にこやかで明るくて好きです。そういう人と仕事してます。

RobotとかAIとか有りなんすけど、時間って大事だよね？みたいな感覚ないと変なふうな方向に行きそうに思っています。で、うまく行く方に考える？

# 一つの提案
日本国の変な外郭団体に銀行コード設定させないで、国で決めて、APIで果報してくれれば、もっと電子決済進むんじゃないかなって思いました。

国交省のAPI素敵です。こういうの惚れる。なんか作れそうじゃないですか。拾ってみたいって思う。
http://www.land.mlit.go.jp/webland/api.html#torihikikakaku
シンプルで素敵ですよね。

国の統計とかAPI開放したら、いろいろ弄って面白いことやってくれる人出てきそうなのに・・・。
データも税金で集めてんじゃん、開放してしてしてくれくれって感じです。

#終わりに
銀行コードの採択につきましては、いろいろ、路頭に迷った末に、「角ちゃん」さんの善意に甘えることになりました。それをオートで更新していただけているこちらを採用してみました。
https://github.com/zengin-code/source-data
ほんとすごいです・・・。ありがとうございます。m(_ _)m
こういう仕事してる方ってほんと尊敬します。芸術作品です。
CI釜してくれてるらしくて、ほんとありがたいです。
でも、国のデータ普通にAPIで出せばいいんっすよね、そっちのほうが、新しい仕事生まれそうな気がしております。

駄文読んでいただきまして、ありがとうございました！！
[RaspberryPi]AlexaをSnowboyで動かす

## はじめに

ラズパイでAlexaを動かす記事は探せばたくさん見つかります。
また、[こちら](https://github.com/alexa/avs-device-sdk/wiki/Raspberry-Pi-Quick-Start-Guide-with-Script)の公式ガイドも(英語ですが)手順に従えば簡単に動かすことができます。
しかし、ガイドに従うとVoice Wakeup Detectionのライブラリとしてデフォルトで
Sensoryが使用されますが、このSensory、、まともに検知してくれません。
（10回中1回検知できるかどうかでした）

そこで、Voice Wakeup Detectionに`Snowboy`を使う手順を残しておきます。

Snowboyを使う手順をブログやQiitaで紹介されているも記事もいくつかありましたが、
https://github.com/alexa/alexa-avs-sample-app (注. 現在はリンク切れ)
このリンク先のサンプルアプリを前提としたものや、少し古いバージョンを対象にしている
記事しか見つからなかったので、誰かの参考のために残しておきます。
（2019年3月時点の情報です）

基本は、[公式のクイックスタートガイド](https://github.com/alexa/avs-device-sdk/wiki/Raspberry-Pi-Quick-Start-Guide-with-Script)通りでOKなので、
ちょっと端折って記載します ^^;

## 環境

Raspberry Pi 3B+
NOOBS v3.0.0

※なお、この記事の手順はクリーンインストールから動作確認済みです。

## 手順

### 1. 必要なファイル準備
```shell
mkdir ~/sdk-folder
cd sdk-folder

〜〜ここでガイドのSetup 3. まで進めます〜〜

この時点で下記4ファイルが存在している状態だと思います。
~/sdk-folder/setup.sh
~/sdk-folder/genConfig.sh
~/sdk-folder/pi.sh
~/sdk-folder/config.json
```

### 2. snowboyに必要なパッケージを入れる

```shell
sudo apt install swig
sudo apt install libatlas-base-dev
```

### 3. pi.shを書き換える

下記diff結果を参考に書き換える。

```shell
--- pi.sh.org	2019-03-12 04:00:14.881061488 +0900
+++ pi.sh	2019-03-10 22:05:56.082621078 +0900
@@ -20,12 +20,12 @@

 SOUND_CONFIG="$HOME/.asoundrc"
 START_SCRIPT="$INSTALL_BASE/startsample.sh"
-CMAKE_PLATFORM_SPECIFIC=(-DSENSORY_KEY_WORD_DETECTOR=ON \
+CMAKE_PLATFORM_SPECIFIC=(-DKITTAI_KEY_WORD_DETECTOR=ON \
     -DGSTREAMER_MEDIA_PLAYER=ON -DPORTAUDIO=ON \
     -DPORTAUDIO_LIB_PATH="$THIRD_PARTY_PATH/portaudio/lib/.libs/libportaudio.$LIB_SUFFIX" \
     -DPORTAUDIO_INCLUDE_DIR="$THIRD_PARTY_PATH/portaudio/include" \
-    -DSENSORY_KEY_WORD_DETECTOR_LIB_PATH=$THIRD_PARTY_PATH/alexa-rpi/lib/libsnsr.a \
-    -DSENSORY_KEY_WORD_DETECTOR_INCLUDE_DIR=$THIRD_PARTY_PATH/alexa-rpi/include)
+    -DKITTAI_KEY_WORD_DETECTOR_LIB_PATH=$THIRD_PARTY_PATH/snowboy/lib/rpi/libsnowboy-detect.a \
+    -DKITTAI_KEY_WORD_DETECTOR_INCLUDE_DIR=$THIRD_PARTY_PATH/snowboy/include)

 GSTREAMER_AUDIO_SINK="alsasink"

@@ -64,18 +64,20 @@
 build_kwd_engine() {
   #get sensory and build
   echo
-  echo "==============> CLONING AND BUILDING SENSORY =============="
+  echo "==============> CLONING AND BUILDING SNOWBOY =============="
   echo

   cd $THIRD_PARTY_PATH
-  git clone git://github.com/Sensory/alexa-rpi.git
-  bash ./alexa-rpi/bin/license.sh
+  git clone git://github.com/Kitt-AI/snowboy.git
+  cd snowboy
+  python ./setup.py build
 }

 generate_start_script() {
   cat << EOF > "$START_SCRIPT"
   cd "$BUILD_PATH/SampleApp/src"

-  ./SampleApp "$OUTPUT_CONFIG_FILE" "$THIRD_PARTY_PATH/alexa-rpi/models" DEBUG9
+  ./SampleApp "$OUTPUT_CONFIG_FILE" "$THIRD_PARTY_PATH/snowboy/resources" DEBUG9
 EOF
 }
```

### 4. setup.shを実行

ガイドのSetup 4. を実施

```shell:例
sudo bash setup.sh config.json -s 12345
```

### 5. alexa.umdlをコピーして所定のパスに配置

```shell
cd ~/sdk-folder/third-party/snowboy/resources/
sudo cp alexa/alexa_02092017.umdl alexa.umdl
```

### 6. サンプルアプリ実行

```shell
sudo bash startsample.sh
```

あとはガイドにしたがってAuthorizeを済ませれば、ちゃんとウェイクワードに
反応してくれるAlexaが動きます！
Hyper-VのUbuntu18.04で容量可変にしたけれど

# Hyper-VでHDDを容量可変にしたのはいいけれど

Hyper-Vで容量を可変にしたHDDをマウントしたUbuntu18.04でDockerやらKubernetesでいろいろやっていたわけですが、KubernetesのKubeletが返してくる状態がおかしいわけです。ディスク容量不足でpodがデプロイできないとおっしゃっている。
いやいやそんなわけないでしょう、と

```
$ df -h
```
してみると```/```が100%使用済みとかなっていたわけです。
ウソでしょ・・・？というかアレですか、可変って言っても自動で増やしてくれるわけじゃなくて自分でパーティションとか拡張しなきゃダメなん？？というわけで調べてみました。

# 以下のコマンド

いきなり全部はアレなので空き容量の10%を新規に追加

```shell
$ sudo lvextend -l +10%FREE /dev/ubuntu-vg/ubuntu-lv
$ sudo resize2fs /dev/mapper/ubuntu--vg-ubuntu--lv
```
可変のボリュームはLVMでマウントされているんですね～
そこまでディスク使ったことがなかったので困ったことはありませんでしたが、使ってみるもんだね！
深層強化学習大全

今此方でいろいろとまとめをしております。
ここに書くにはまだまだ時間がかかってしまいそうですが、一旦現状の深層強化学習をその手法ごとにまとめております。(現在進行形)
よかったら見てみてください。

https://github.com/Rowing0914/Reinforcement_Learning/blob/master/DRL_Taxonomy.md
無線網(Wi-Fi)と空中線(antenna)(8) 仰角(elevation) 方位(azimuth)

Wifi Antennaでresearchgateで文献調査
https://qiita.com/kaizen_nagoya/items/2cff082e2ef214f2b377

16. 
Design of a dual band printed dipole antenna for WIFI application
Oct 2017, Norun Abdul Malek, S.A. Karsin, Sarah Mohamad, Athirah Mohd Ramly
http://journal.utem.edu.my/index.php/jtec/article/view/1803/2332

空中線(antenna)の指向性は、方位(azimuth)と仰角(elevation)の２つの２次元空間で３次元特性を示す。

上記文献には、 elevation and azimuthという語順で並んでいる。

下図は実測ではなく、模擬試験である。

<img width="323" alt="antena1.png" src="https://qiita-image-store.s3.amazonaws.com/0/51423/79860b2a-1a22-2049-d909-32f813aa9293.png">
Figure 6 Simulation radiation pattern of single band printed dipole antennas. (a) Elevation plane (b) Azimuthal plane

<img width="340" alt="antenna2.png" src="https://qiita-image-store.s3.amazonaws.com/0/51423/07e6ca1c-95ad-9908-c77a-37ca42f6f75a.png">
Figure 11: Simulated radiation pattern of dual band printed dipole antennas at 5 GHz. (a) Elevation and (b) azimuthal plane

# 参考資料(reference)
Wifi(無線網) Antenna(空中線）(3)でresearchgateで文献調査
https://qiita.com/kaizen_nagoya/items/2cff082e2ef214f2b377

Wifi(無線網) Antenna(空中線）(4) researchgateで文献調査 の参考文献一覧
https://qiita.com/kaizen_nagoya/items/e7474ca67842565334b1

無線網(Wifi)空中線(antenna)(5) 設置(install)設計(design)
https://qiita.com/kaizen_nagoya/items/d71eece182768e97039a

Wifi(無線網) Antenna(空中線）(6) 空中線(antenna)の特性
https://qiita.com/kaizen_nagoya/items/4cd18795fbb5eb79896c

無線網(Wifi)空中線(antenna) (7) 障害物と反射物
https://qiita.com/kaizen_nagoya/items/e1a8123094c1d1d836a9

無線網(Wifi)と空中線(antenna)(8) 仰角(elevation) 方位(azimuth)
https://qiita.com/kaizen_nagoya/items/3553ed48e1b03c7340a3

無線網（Wifi）空中線(antenna)(1) 検索論文拝読
https://qiita.com/kaizen_nagoya/items/d6db5de2628a8ebfed94

無線網（Wifi）空中線(antenna)(2) 802.11 Wireless LAN Fundamentals を拝読
https://qiita.com/kaizen_nagoya/items/1ff8e127b52902d34cfd

無線網（Wifi）空中線(antenna)(21) 無料無線網(wifi)利用で便利なこと、不便なこと
https://qiita.com/kaizen_nagoya/items/9244aa0906cbedec83aa

無線網（Wifi）空中線(antenna)(22) WiFi Related document
https://qiita.com/kaizen_nagoya/items/c484c9f21b9d6fc5481e

無線網（Wifi）空中線(antenna)(31) 災害時のwifi-bluetooth網の構築
https://qiita.com/kaizen_nagoya/items/2d82637301650c202715

無線網（Wifi）空中線(antenna)(32) 災害時のWifiおよびbluetooth系の安全分析<予定>
https://qiita.com/kaizen_nagoya/items/c8c679beae7082df47bf

プログラマが知っていると良い「公序良俗」
https://qiita.com/kaizen_nagoya/items/9fe7c0dfac2fbd77a945
# 文書履歴(document history)
ver. 0.01 初稿 20190312 早朝
ver. 0.02 表題統一 20190312 朝
ver. 0.03 誤植訂正 20190312 午前
ver. 0.04 URL追記 20190312 昼
ver. 0.05 URL追記　20230214
### 最後までおよみいただきありがとうございました。
いいね　💚、フォローをお願いします。
####  Thank you very much for reading to the last sentence.
Please press the like icon 💚　and follow me for your happy life.
GCPの無料枠の利用を停止する

# 概要
* GCPの無料枠を使用していたところ、設定していた上限値(1円)に到達した旨のメールがGoogleから送られてきた。
* 上限値を超えた原因はわからないが、ド素人な状態でこのまま使うのは危ない(びっくりするくらいの請求が来て嫁に怒られる)気がするので、一旦利用を停止する。
* このページでは2019/3/12時点でGCPの利用を停止(請求先アカウントを閉鎖)する手順を紹介する。
* 既にプロジェクトの削除は行ったところから閉鎖作業をしました。

# 「お支払い」を選択

![image.png](https://qiita-image-store.s3.amazonaws.com/0/367069/d7adbe9b-26ee-c59a-16d8-ad4d3db1da0e.png)

# 「請求先アカウント名」を選択
![image.png](https://qiita-image-store.s3.amazonaws.com/0/367069/8839ad73-b296-b53c-7e6c-5abdbe7343b7.png)

# 「請求先アカウントを閉鎖」を選択
![image.png](https://qiita-image-store.s3.amazonaws.com/0/367069/a765e463-1307-9db7-5a3a-cefd54a003ba.png)

# 「閉じる」を入力し、「請求先アカウントを閉鎖」を選択
![image.png](https://qiita-image-store.s3.amazonaws.com/0/367069/0fd3581d-7db1-ff66-4ebb-9706239f5e5e.png)

# 請求先アカウントが閉鎖されたことを確認
![image.png](https://qiita-image-store.s3.amazonaws.com/0/367069/58524177-7a0c-c1dc-63f0-6d380765dd8b.png)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/367069/3dbe5d4f-cd6b-4c76-95b4-9dc15a69188b.png)

# 参考資料
[GCPマニュアル:Cloud Platform アカウントを閉じる](https://cloud.google.com/support/docs/close-account?authuser=2&hl=ja)
[GCPマニュアル:プロジェクトの削除](https://cloud.google.com/go/getting-started/delete-tutorial-resources?hl=ja)
[GCPマニュアル:請求先アカウントの作成、変更、閉鎖](https://cloud.google.com/billing/docs/how-to/manage-billing-account?hl=JA&visit_id=636879468443269053-1572551354&rd=1)

# まとめ
* GCPの利用を停止する手順を紹介しました。
* GCPの利用を停止するには、請求先アカウントを閉鎖することで課金やトランザクションを停止することができます。
* GCPの利用停止するためには、「プロジェクトの削除」、「請求先アカウントの閉鎖」の作業が必要です。
Githubを用いたチーム開発 (導入)

#はじめに
現在チーム開発中であり，そちらでGithubを用いてバージョン管理を行なっている．そこで，実際にどのようにしてGithubを用いて管理をしていくのかをメモ書き程度にはなると思うが，自分が忘れない程度の流れまとめをしておこうと思う．

##前提
メインプログラマーのAさんのGitのレポジトリに，自分の開発，修正したものをプルリクして送っていく形で開発を進めていこうと思う．

###1.Fork
まずはメインプログラマのgithubリポジトリにアクセスし，右上のforkボタンを押すことで，自分のgithub上に対象レポジトリがforkされる．
![スクリーンショット 2019-03-04 12.23.24.png](https://qiita-image-store.s3.amazonaws.com/0/363473/63101561-0c3a-66b4-fd3f-35042d157d66.png)

###2.Clone
自分のPC上で開発していくためにforkしたレポジトリをローカル上にcloneする．
```git clone https://github.com/〇〇```

###3.ブランチ
ローカルリポジトリからブランチを作成する．三つのアイコンのうちの真ん中のブランチマークを押すことで新規ブランチを作成することができる．
![スクリーンショット 2019-03-04 12.57.19.png](https://qiita-image-store.s3.amazonaws.com/0/363473/d7dc93aa-8b7f-3c13-0e9f-7a81bdc12f69.png)

###4.開発
プロジェクトの開発を新規作成したブランチで行なっていき，git add，git commitを適宜行なっていき，開発を進めていく．

###5.upstream: fork元リポジトリ設定
forkした自分のリポジトリはfork元のリポジトリの変更内容を自動では更新してはくれないため，手動でfork元の最新情報をforkしたリポジトリに反映する必要がある．
fork元のリポジトリにupstreamコマンドで設定を行う．
```$ git remote add upstream https://github.com/mainprogramer/test.git```

###6.localのmaster更新
ブランチをローカル環境のmasterに移動してから，upstreamがされていることを確認して以下のコマンドをすることによって，ローカルのmasterにfork元の更新を反映させる．

```
$ git fetch upstream
$ git merge upstream/master
$ git push origin master
```

###7.マージ
現在localのmasterが更新されているため，そこに開発したブランチをマージする．
もしマージするときにconflictが発生した場合，解決してからコミットし直して，もう一度マージを試みる．

###8.ブランチのプッシュ
ここまででlocal環境で開発が終わっているため，fork元にブランチをプッシュする必要がある．

###9.pull request
最後にプルリクを送ることによって，開発元に確認を取って，マージしても良いならばマージして開発を完了する．

##まとめ
やっぱり実際にやってみないことには感想も難しいですね．一回ちゃんとやってみたいと思います．
LivaPC (初代)にubuntu18.04.2でWiFiとbluetooth を有効にする

公式HPでの配布がされなくなっている？ためメモ。

```sh
wget "https://github.com/Asus-T100/firmware/raw/master/brcm/brcmfmac43241b4-sdio.txt"

# 設置
sudo mv brcmfmac43241b4-sdio.txt /lib/firmware/brcm/

reboot
```

wifiとbluetoothが動作することを確認。

![1.jpg](https://qiita-image-store.s3.amazonaws.com/0/25728/ac6ac15c-40f3-d9a2-bd21-d9f0935a1dd8.jpeg)
エンジニアなので家系図をGitHub上にYAML形式で管理する

あなたは親戚の名前や兄妹の人数など覚えているでしょうか？私は覚えられません。
そもそも誰かが結婚する度に親戚が増えるわけだから覚えられるわけがない、私はそう思っています。

ということで家族間の親族情報共有とその可視化に取り組むことにしました。

## 技術選定
- 管理・更新が容易(テキストベース)
- 図を自動生成できる

という条件を満たすkingraphというOSSを見つけました。
https://github.com/rstacruz/kingraph

## kingraphとは
家系図をJavaScriptとGraphvizで作図するツールです。インストール方法などはREADMEをみましょう。

以下ではドラゴンボールの家系図を例に書き方を軽く説明します。

## 例: ドラゴンボールの孫悟空周りの家系図
公開リポジトリ: https://github.com/nagamoto/db-family-tree
![image.png](https://qiita-image-store.s3.amazonaws.com/0/112173/f8840805-ae75-3511-4082-1747dcebfe82.png)
※牛魔王やサタンの妻はわからないのでとりあえず”牛魔王の妻”・”サタンの妻”としています


### YAMLファイルの書き方
親子は次のように定義できます、簡単ですね。

```yaml:son.yml
parents: [悟空, チチ]
children: [悟飯, 悟天]
```

それぞれの人の詳細を設定することもできます。今回は兄弟の生まれた順番を図に表現するために、fullnameというプロパティを本来とは違う用途で利用しています。また、後述するスタイリングのためにclassにmaleを指定しています。

```yaml:son.yml
people:
  ラディッツ:
    fullname: 第一子
    class: [male]
  悟空:
    fullname: 第二子
    class: [male]
```


図に細かなスタイリングを施すこともできます。今回は男性であれば枠が青、女性であれば枠が赤となるように設定しました。

```yaml:son.yml
styles:
  male:
    color: blue
  female:
    color: red
```

## 保守運用
誰かが結婚したり、子供が生まれたりしたときにはPullRequestを投げてもらいます。太郎くんが生まれた際に作られるブランチはdeploy-taroでしょうか。これでエンジニアらしく、常に最新の家系図が作成されます。

## 最後に
マジレスをすると、そもそも結婚や出産はそう頻繁に起こることではないので、これはやりすぎです。
また、「親族にエンジニアはそう何人もいない」=「メンテナが少ない」となるため、特定の少数メンバのみが更新するというつらい運用になるでしょう。
[AWS lambda] Slack Botがタイムアウトで何度もレスポンスするのを防ぐ

# 何度もレスポンスする事例
[前の記事](https://qiita.com/kamata1729/items/8d88ea10dd3bb61fa6cc)で、slack botをAWS lambdaを使って作成しましたが、それの最後に述べたように、**何度か同じレスポンスをしてしまう**場合があります。
これはslackのタイムアウト時間が3秒しかなく、3秒以内にレスポンスできないとエラーと見なされ、何度か同じイベントを送ってくるため、それに対してlambda関数が何度か呼ばれてしまうことが原因です。
![samplebot2.gif](https://qiita-image-store.s3.amazonaws.com/0/262908/04e4365d-20b6-e3ae-1ce1-a562d98be79b.gif)

# 解決方法
**新しいlambda関数を作成**し、そこから非同期でslackにpostするlambda関数を呼び出すことにする！
このようにすれば、slack APIへのレスポンスは新しいlambda関数からすぐに行うことができ、そのあとでゆっくりとワークスペースにpostMessageすることができます。

# 新しいlambda関数の作成

## IAMロールの作成
[前回の記事](https://qiita.com/kamata1729/items/8d88ea10dd3bb61fa6cc)と同じ手順でロールを作成します。
今回はロールの名前を`invokeBotRole`としました。
前回と異なるのは、Permissions Policiesに`AWSLambdaBasicExecutionRole`の他に`AWSLambdaRole`を追加してください。これによって他のlambda関数を呼び出すことが可能になります。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/262908/d075c961-2ab6-952f-783d-fce6c9eb6a2b.png)

## lambda関数の作成
[前回の記事](https://qiita.com/kamata1729/items/8d88ea10dd3bb61fa6cc)ではJava縛りで作成しましたが、今回はサクッとPython3.7で作っていきます。
lambdaのページで以下のように設定して、`invokeBot`というlambda関数を作成しました。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/262908/6bbe8489-ee63-c28e-7911-e7042bf71dbb.png)

## API Gatewayの作成
これも[前回の記事](https://qiita.com/kamata1729/items/8d88ea10dd3bb61fa6cc)と同様に作成していきます。
今回は、`invokeBotAPI`という名前のAPIGatewayにして、デプロイ時のステージ名は`invokeBotStage`としました。
デプロイ時に表示されるURLをメモしておくのを忘れないでください。

## lambda関数の編集
再びlambda関数のページに戻って編集していきます。
API Gatewayから入って、他のlambda関数に接続できるようになっていることが確認できると思います。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/262908/2f79b3eb-7c88-88dd-1a2d-8d99d320308c.png)

lambda関数を以下のように編集します。

* `FunctionName='sampleBot'`の部分で呼び出すlambda関数の名前を設定しています
* `InvocationType='Event'`とすることで非同期の実行が可能になります
* Slack Event APIの認証にも対応できるようにしています

```python
import json
import boto3
import logging

logger = logging.getLogger()
logger.setLevel(logging.INFO)

def lambda_handler(event: dict, context):
    
    logging.info(json.dumps(event))
    if "challenge" in event:
        return event.get("challenge")
        
    client = boto3.client('lambda')
    response = client.invoke(
        FunctionName='sampleBot',
        InvocationType='Event',
        LogType='Tail',
        Payload= json.dumps(event)
    )
    
    return {
        'statusCode': 200,
        'body': json.dumps('OK')
    }
```

また、一応念の為lambda関数のtimeout時間も3秒に設定しておくと、確実に3秒以内にslack APIにレスポンスが送られるため安全です。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/262908/31ef111f-4732-e7b4-7354-eb88cba91d53.png)


# イベントのRequest URLに設定
slack APIが呼び出すURLを新しいURLに変更しましょう
先ほどのAPIのデプロイ時にメモしておいたURLを設定し直します
![image.png](https://qiita-image-store.s3.amazonaws.com/0/262908/575b76a9-7629-1751-84d3-099c322169d5.png)

# 動作確認
タイムアウトすることなく実行できています！
![sampleBot3.gif](https://qiita-image-store.s3.amazonaws.com/0/262908/a14a4743-39ab-e642-011e-706cd3ecbd11.gif)

# 参考
[AWS LambdaからLambda呼んでハマった話。](https://qiita.com/shinichi-takahashi/items/04287757c5944818ffe5)
[AccessDeniedException: User is not authorized to perform: lambda:InvokeFunction](https://stackoverflow.com/questions/37498124/accessdeniedexception-user-is-not-authorized-to-perform-lambdainvokefunction)
はじめてのC++【15日目】

#はじめに
5時になってもうた
最近時間取れないな。今週は忙しいから毎日少しでもいいからやる。
まだまだかかりそう。
この本分厚すぎ
##ロベールのC++
###06-05　昨日の続き

```array.cpp
#include <iostream>
#include <array>
#include <algorithm>
#include <cstdlib>
class inArray {
public:
  std::array<int,100> m_array;
  inArray();
  int Get(int i);
  void set(int i,int value);
  void checkindex(std::size_t i);
};

inArray::inArray(){//コンストラクタで配列を初期化
  std::array<int,100> m_array = {};
}

int inArray::Get(int i){
  checkindex(i);
  return m_array[i];
}
void inArray::set(int i, int value){
  checkindex(i);
  m_array[i] = value;
}

void inArray::checkindex(std::size_t i){
  if (m_array.size() <= i){
    std::cout << "インデックスは不正です" <<std::endl
              << "値" << i << std::endl;
    std::quick_exit(EXIT_FAILURE);
  }
}
```
std::がおかしいというエラーが出ます。
実行コマンド【g++ Array.cpp -std=c++17】
<img width="484" alt="スクリーンショット 2019-03-11 17.18.56.png" src="https://qiita-image-store.s3.amazonaws.com/0/298612/85f7b491-f380-417f-60dd-5b8ce50a5ee8.png">
g++のバージョンは5.4です。
<img width="430" alt="スクリーンショット 2019-03-11 17.08.52.png" src="https://qiita-image-store.s3.amazonaws.com/0/298612/140dbb5a-3ae1-1c3f-6d00-bc8ec5df0c2c.png">

おこがましいことをお願いして申し訳ないのですが、解決策を教えていただけないでしょうか。
###06-06　デストラクタ
デストラクタとは、このクラスが処理を終えたら自動的にメモリを解放する機能。
つまり、クラスはコンストラクタに始まりデストラクタに終わる。
コンストラクタ同様にデストラクタもデフォルトコンストラクタが存在する。

デストラクタを作る場合は```~```を用いる。

```cpp
class inArray{
public:
       ~inArray();//デストラクタ

}

inArray::~inArray(){//~をつける
   //なんか書く
}
```

デストラクタでメモリ解放を命令しておくと、メモリリークをすることはなくなる。

06-07 分割コンパイル
ヘッダファイルにはクラスの宣言や関数のプロトタイプを書く。
ソースファイルには、関数の中身などを書く。
そのクラスを使うソースファイルにヘッダファイルをインクルードする。

#終わりに
明日（今日）の内容を少しみたけど、これからは.cppと.hで分けて実装するみたい。
今日はここまで！
PyMySQL デバッグ 小ネタ

# PyMySQLの発行するSQL文の確認方法
```pymysql/cursors.py
166         query = self.mogrify(query, args)
167         print(query) # print文でクエリを出力する。
168         result = self._query(query)
```
# 注意
直接、ライブラリに手を入れているので、本番の時に取り除くことを忘れないように。
rosserial_stm32を使ってみた

#きっかけ
高専ロボコンも近代化してきてそろそろROS使わないと開発に時間がかかりすぎることが考えられるため導入を決定．
主力として使ってるSTM32シリーズでROSを楽に使いたかったのでGoogle先生に聞いた結果「[rosserial_stm32](https://github.com/yoneken/rosserial_stm32)」なるものを発見，とりあえず使ってみることにした．
<font color="LightGray">筆者はROS初心者なので拙いところは許してください</font>

#使用機材
* Nucleo L476
* Ubuntu16.04(kinetic)
* CubeMX
* SW4STM32

#使い方
[ここ](https://www.slideshare.net/k_yone/rosserial-stm32)にほぼ書いてある通りにやってみる．

```console
$ sudo apt install ros-kinetic-rosserial
$ cd ~/catkin_ws/src
$ git clone https://github.com/yoneken/rosserial_stm32.git
$ cd ./rosserial_stm32/src/ros_lib/examples/chatter
```
ここで`chatter.ioc`をあらかじめ作っておいたL476用のiocファイルにすり替えておく．（CubeMXで適当に作っておく）それに加え手前のsrcの`STM32Hardware.h`で

```c
#include "stm32f3xx_hal.h"
#include "stm32f3xx_hal_uart.h"
#include "stm32f3xx_hal_tim.h"
```
を

```c
#include "stm32l4xx_hal.h"
#include "stm32l4xx_hal_uart.h"
#include "stm32l4xx_hal_tim.h"
```
に変更．

```console
$ cd ~/catkin_ws
$ catkin_make
$ cd ./src/rosserial_stm32/src/ros_lib/examples
$ cp -r chatter ~/workspace
$ cd ~/workspace/rosserial_stm32
$ rosrun rosserial_stm32 make_libraries.py .
```
CubeMXを起動して`chatter.ioc`を読み込み，`Project Maneger`でツールチェインをSW4STM32に変更しGENERATE CODEを押しHALを生成.
そのままSW4STM32を起動しCubeMXで生成したプロジェクトを読み込む．
プロジェクトを右クリックしてConvertC++を選択．
`main.c`の中身がCubeMXに上書きされてしまっているので元のところからコピペしてやり過ごす．
で，Buildする．

<font color="Red">失敗しました</font>
エラーは

```
mainpp.cpp:41: undefined reference to `htim2`
mainpp.cpp:41: undefined reference to `huart2`
STM32Hardwear.h:71: undefined reference to `HAL_TIM_Base_Start`
```
でした．
誰か助けて…
もしかして[ここ](https://github.com/yoneken/rosserial_stm32/tree/master/src/ros_lib/examples/chatter)見るとPeripheralの設定してなかった説が濃厚？
CubeMXの使い方がよくわからんので元の`chatter.ioc`からそれっぽいところをコピペして再度生成した．
<font color="Blue">ビルド成功しました</font>

その後，Debugしてみると

```console
$rosrun rosserial_python serial_node.py _port:=/dev/ttyACM0 _baud:=57600
[INFO] [1553585723.997853]: ROS Serial Python Node
[INFO] [1553585724.007428]: Connecting to /dev/ttyACM0 at 57600 baud
[INFO] [1553585726.113745]: Requesting topics...
[ERROR] [1553585741.116108]: Unable to sync with device; possible link problem or link software version mismatch such as hydro rosserial_python with groovy Arduino
```
のようなエラーが出て通信できない…
通信エラーかソフトウェアのバージョンがあってないと言われている．
gtktermで通信を見てみたところ何も送信されていなかった．
~~DMAの設定周りが怪しいけど自分ではどうしようもなくなったのでROS　Answersに投げました．~~
Duff checkerで元の`chatter.ioc`との差分を確認していると気になる箇所がいくつかあった．
結果から言うと犯人はGPIO_Labelみたいだ．こいつにCubeMXでUSART2のGPIO SettingsのUserLabelからVCP_RXなりVCP_TXなりを設定してやると見事動いた．
あと，この記事結構汚いのでいつか試行錯誤の部分抜いてきれいにf3からの移植について書きます．
How to tie specific old minor version of CentOS 7

# How to tie specific old minor version of CentOS 7

- https://unix.stackexchange.com/questions/398609/how-do-i-stick-with-one-version-on-centos-7-via-yum-update

## objectives

- personal memo
- latest release is 7.6.1810
    - http://vault.centos.org/

### For RHEL, use subscription-manager command

- Japanese https://access.redhat.com/ja/solutions/743243
- English https://access.redhat.com/solutions/238533

### Update centos from 7.3 to version 7.5

```
$ sudo su -
# echo '7.5.1804' > /etc/yum/vars/releasever
```

- comment all mirrorlist lines in /etc/yum.repos.d/CentOS-*.repo files

```
#mirrorlist=http://mirrorlist.centos.org/
```

- un-comment all baseurl lines in /etc/yum.repos.d/CentOS-*.repo files
- replace mirror to vault in baseurl line in /etc/yum.repos.d/CentOS-*.repo files

```
From: baseurl=http://mirror.centos.org/
To:   baseurl=http://vault.centos.org/
```
```
# vi /etc/yum.repos.d/CentOS-Base.repo
# vi /etc/yum.repos.d/CentOS-fasttrack.repo
# vi /etc/yum.repos.d/CentOS-CR.repo

# yum clean all
# yum update
```
```
$ cat /etc/redhat-release 
CentOS Linux release 7.5.1804 (Core)
```

### Tie version 7.4 with sed command.

```shell-session
cd /etc/yum.repos.d/
cp -ipv *.repo ~/.
```
```shell-session:test
find . -type f -iname "*.repo" | \
while read x ; do sed \
-e 's/^mirrorlist/#mirrorlist/g' \
-e 's/^baseurl=http:\/\/mirror./baseurl=http:\/\/vault/g' \
-e 's/^#baseurl=http:\/\/mirror/baseurl=http:\/\/vault/g' $x \
; done
```
```shell-session:execute
find . -type f -iname "*.repo" | \
while read x ; do sed -i \
-e 's/^mirrorlist/#mirrorlist/g' \
-e 's/^baseurl=http:\/\/mirror./baseurl=http:\/\/vault/g' \
-e 's/^#baseurl=http:\/\/mirror/baseurl=http:\/\/vault/g' $x \
; done
```
```shell-session:confirm
grep -E "^baseurl.*vault.*/centos/" *.repo
grep -E "^#mirrorlist" *.repo
```
```shell-session
yum clean all
yum update
```
【Vuex】変更が検知されないときの注意点

Vuexで管理しているデータを変更しても検知されず、DOMに反映されなくて困ったのでメモ。
## やりたいこと

- カードが開いているか閉じているかのフラグ（isOpen）をstoreで管理
- isOpenがtrueになったら、実際にカードを開く

## 状況
### カードがOpenされているかのフラグをstoreで管理

```store.js
actionsPayload.openCard = {
  groupKey: {
    type: Number,
    required: true
  }
};

actions.openCard = (store, payload) => {
  store.commit('openCard', payload);
};

mutationsPayload.openCard = {
  groupKey: {
    type: Number,
    required: true
  }
};
mutations.openCard = (state, payload) => {
  // 一度全部閉める
  if (state.cards.items === null || state.cards.items === undefined) return;
  state.cards.items = state.cards.items.map((card) => {
    card['isOpen'] = false;
    return card;
  });

  // 一個開ける
  Vue.set(state.cards.items[payload.groupKey], 'isOpen', true);
};
```

### カード見出しをクリックしたら詳細を表示する

`:v-if="card.isOpen"` がtrueになったらカード詳細表示されてほしい・・

```card.vue
<template>
  <div>
    <div :v-if="!card.isOpen" @click="handleClick">カード見出し</div>
    <div :v-if="card.isOpen">カード詳細</div>
  </div>
</template>

<script>
export default {
  props: {
    card: {
      type: Object,
      required: true
    },
    groupKey: {
      type: Number,
      required: true
    }
  },
  methods: {
    async handleClick() {
      await this.$store.dispatch('store/openCard', { groupKey: this.groupKey });
    }
  }
};
</script>
```

## 困ったこと
上記のコードだとカード詳細はオープンしません。
<img width="217" alt="スクリーンショット 2019-03-12 2.23.55.png" src="https://qiita-image-store.s3.amazonaws.com/0/239038/ec9e2d76-99b7-6a6b-eab2-2e83a3a60ca7.png">
vue devtoolsで確認して、`isOpen: true` になってるのになぜ😢

## 解決法
### Objectからドット表記でisOpenにアクセスせず、直接propsに渡してあげる

```card.vue
<template>
  <div>
    <!-- card.isOpenをpropsのisOpenに変更 -->
    <div :v-if="!isOpen" @click="handleClick">カード見出し</div>
    <div :v-if="isOpen">カード詳細</div>
  </div>
</template>

<script>
export default {
  // 略
  props: {
    // 追加
    isOpen: {
      type: Boolean,
      default: false
    }
  }
};
</script>
```

vueはObjectの中身の一部が変更しても検知してくれないみたいです。
（実際に詰まったのは、多次元配列だったので、このサンプルのように1次元配列だと変更を検知してくれる場合もあるかも？）

実際に公式でもこう書いてあります。

>Vue.js はプロパティの追加または削除を検出できません。
[リアクティブの探求 — Vue.js](https://jp.vuejs.org/v2/guide/reactivity.html#%E5%A4%89%E6%9B%B4%E3%81%AE%E8%BF%BD%E8%B7%A1%E6%96%B9%E6%B3%95)

## どうしても変更が検知されない場合の奥の手

> vm.$forceUpdate()
[API — Vue.js](https://jp.vuejs.org/v2/api/#vm-forceUpdate)

forceUpdate()すれば強制的に初期化され、追加したデータがリアクティブにDOMに反映されます。
ただ、初期化することで全てのデータが取り直しとなり、あまり良い処理ではありません・・。

> もし Vue で強制更新をする必要な場面に遭遇する場合、99.99% のケースであなたは何かを間違えています。
しかし、もし上記の可能性を排除し、手動で強制更新をする非常に稀な状況と認識しているならば、$forceUpdate を用いることで強制更新をすることができます。
[特別な問題に対処する — Vue.js](https://jp.vuejs.org/v2/guide/components-edge-cases.html#%E5%BC%B7%E5%88%B6%E6%9B%B4%E6%96%B0)
個人情報の保存期間とは? 

## 前書き
個人情報の保存期間ってどれくらいなんだ？ 🤔　とふと気になったので、
同じ疑問を持った人の助けになればと思い記載していきます。

## 個人情報保護法の観点では？
個人データは、利用目的の達成に必要な範囲内において、
正確かつ最新の内容に保つとともに、利用する必要がなくなったときは、
当該データを遅滞なく消去するように努めなければならないとされています（個人情報保護法第 19 条）

## そもそも個人データとは?

|名称|説明| 
|:---|:---|
|個人情報データベース等|個人情報をデータベース化したり、検索可能な状態にしたもの|
|個人データ|個人情報データベース等を構成する情報|
|保有個人データ|個人データのうち、事業者に修正、削除等の権限があるもので、６ヶ月以上保有するもの|

## JISQ15001：2017 での個人情報の扱いは？
組織は、

- 個人情報の項目
- 利用目的
- 保管場所
- 保管方法
- アクセス権を有する者
- 利用期限
- 保管期限

などを記載した，個人情報を管理するための台帳を整備すると
ともに、当該台帳の内容を少なくとも年一回、
適宜に確認し，最新の状態で維持されるようにしなければならないとされています。

## 利用期限と保存期限の違い？
利用期限 = 個人情報の利用の期限
保管期限 = 個人情報を保管する期限

利用が終了すると同時に保管も終了し消去する場合には、
利用期限と保管期限は同じとなります。

一方、利用が終了した後、一定期間保管をした後に消去する場合には、
利用期限と保管期限は異なります。

## ただし書類系は注意が必要
従業員に関する申告書・台帳などは注意が必要で、

|書類|理由|
|:---|:---|
|- 給与所得者の扶養控除等（異動）申告書<br>- 従たる給与についての扶養控除等の（異動）申告書<br>- 給与所得者の保険料控除及び配偶者特別控除の申告書<br>-給与所得者の保険料控除申告書|- 所得税法第76条<br>-国税庁の給与所得者の扶養控除等申告書等の保存期限|
|- 退職所得の受給に関する申告書|- 所得税法第77条<br>- 国税庁の給与所得者の扶養控除等申告書等の保存期限|
|- 公的年金等の受給者の扶養親族等申告書|- 所得税法第77条の4<br>- 国税庁の給与所得者の扶養控除等申告書等の保存期限|
|- 給与所得者の(特定増改築等)住宅借入金等特別控除申告書|- 租税特別措置法第18条の23<br>- 国税庁の給与所得者の扶養控除等申告書等の保存期限|
|- 賃金台帳(源泉徴収簿)、給与明細、源泉徴収票|- 国税法第70条〜第73条<br>- 労働基準法第108条<br>- 労働基準法施行規則第54条|

## まとめ
個人情報は利用する必要がなくなったときは、
当該データを遅滞なく消去するように努めなければならない。

JISQ15001：2017の観点では、利用期限、保管期限を決めておくことが必要。

また、従業員に関する申告書・台帳などは別途他の法律で制限されているので注意が必要。

## 参考
個人情報保護法ハンドブック
https://www.ppc.go.jp/files/pdf/kojinjouhou_handbook.pdf

一般財団法人日本情報経済社会推進協会（JIPDEC） JIS改正対応のQ&A
https://privacymark.jp/system/operation/jis_kaisei/faq.html

JISQ15001規格改正に伴う新審査基準の説明（主に更新事業者向け）
https://www.chusanren.or.jp/pmark/pdf/renew_seminar_20180709.pdf

No.2503 給与所得者の扶養控除等申告書等の保存期間
https://www.nta.go.jp/taxes/shiraberu/taxanswer/gensen/2503.htm

所得税法
http://elaws.e-gov.go.jp/search/elawsSearch/elaws_search/lsg0500/detail?lawId=340M50000040011

租税特別措置法
http://elaws.e-gov.go.jp/search/elawsSearch/elaws_search/lsg0500/detail?lawId=332M50000040015

国税通則法
http://elaws.e-gov.go.jp/search/elawsSearch/elaws_search/lsg0500/detail?lawId=337AC0000000066&openerCode=1#557

労働基準法	
http://elaws.e-gov.go.jp/search/elawsSearch/elaws_search/lsg0500/detail?lawId=322AC0000000049&openerCode=1#479
Ruby on Railsのプロジェクト内でAmazon SESを使用する際、IAMの権限エラーが発生する

# 背景
会社プロダクトの招待メールがスパムメール化されるため、AmazonSESを利用した招待メールにすることになったが、その際にIAMエラーがわかりにくかったので投稿しようと思う。

# 開発環境
Ruby on Rails 5.2.1
Ruby 2.5.1

# リージョン
今回使用するリージョンは北部バージニア

| 米国東部 (バージニア北部) | us-east-1 | a4b.us-east-1.amazonaws.com | HTTPS |
|:--|:--|:--|:--|

# ドメイン検証
![verify.png](https://qiita-image-store.s3.amazonaws.com/0/277836/ae35251b-53e3-ac6c-e01f-a709c183a2e8.png)

1. Identity Management > Domains > Verify a New Domain の順に選択
2. 好きなドメイン名を入力

※詳しいAmazon SESの設定は、この記事を参照すると良い
https://qiita.com/tanakaworld/items/94f1ba66801100f6a44f

# Ruby on RailsでSESを設定後、SES経由でメールが送信されていない
それだけでなく、メール自体が送信されない。。
ログを確認すると、下記のようなエラーが。

```
Error performing ActionMailer::DeliveryJob (Job ID: 0000b1-cc00-0000-b000-11bfe1e1e) from Async(mailers) in 1156.29ms: 
AWS::SES::ResponseError 
(AccessDenied - User `arn:aws:iam::123123123:user/system_app_s3' is not authorized to perform `ses:SendRawEmail' on resource `arn:aws:ses:us-east-1:675052735624:identity/smartcanvas.net'):
```

# 原因
ログを確認すると、 AccessDeniedという権限周りっぽいエラーが出ている。。

```
AccessDenied - User `arn:aws:iam::123123123:user/system_app_s3'
```

AWS IAM(ポリシー編集)で、 `arn:aws:iam` に権限がないことが原因みたい。

※Amazon リソースネーム (ARN) は、AWS リソースを一意に識別するもの。
[Amazon ARN](https://docs.aws.amazon.com/ja_jp/general/latest/gr/aws-arns-and-namespaces.html)

# 解決策
AWS IAM(ポリシー権限)で `"ses:SendRawEmail"`の追加

```
Action: [
"ses:SendRawEmail"
]
```
Eメール送信アクションへのアクセスを許可
[Amazon SES へのアクセスの制御](https://docs.aws.amazon.com/ja_jp/ses/latest/DeveloperGuide/control-user-access.html)

このことにより、SES経由でメールを送信することができ、見事スパムメール対策ができた。
コンテナ間通信する（docker runから）

## 概要

`docker run` した時のコンテナ間通信の仕方メモ。
推奨されてないらしいので、 `--link` は使わないよ。
`docker network create` したネットワークを `docker run` 時に指定するとコンテナ間通信ができる。

## メモ

`docker network create` する。

```bash
$ docker network create test-network
3c1309d35ee951ec743d1a7cf1b02178fd4e4107823c7c959089dd79e828a532

$ docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
d7274732b28f        bridge              bridge              local
0a4b170c1445        host                host                local
22009373ca6d        none                null                local
3c1309d35ee9        test-network        bridge              local
```

`docker run` する際にネットワークを指定すると、コンテナの中からコンテナ名指定で通信できるようになる。

```
docker run -it -p 80:80 --network test-network --rm --name nginx nginx
docker run -it --rm --network test-network --name test alpine
```

testコンテナ内から、`wget "http://nginx"` で、 ※nginxはコンテナ名

```bash
$ wget "http://nginx:80" -O - -q

<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>
```

`ping` を打つと、

```bash
$ ping nginx 
PING nginx (172.18.0.4): 56 data bytes
64 bytes from 172.18.0.4: seq=0 ttl=255 time=0.099 ms
64 bytes from 172.18.0.4: seq=1 ttl=255 time=0.096 ms
64 bytes from 172.18.0.4: seq=2 ttl=255 time=0.096 ms

$ping test
PING test (172.18.0.3): 56 data bytes
64 bytes from 172.18.0.3: seq=0 ttl=255 time=0.033 ms
64 bytes from 172.18.0.3: seq=1 ttl=255 time=0.063 ms
64 bytes from 172.18.0.3: seq=2 ttl=255 time=0.062 ms
```

という感じ。
Zabbix3.2をインストールしてみる

#はじめに

業務でZabbixを使うことになったので、これを機に構築・設定などの基本的な手順をパターン化してリファレンスとして残したく、記事にしました。

とりあえず実機がないと何もはじまらないので、インストール作業から手を動かします。
サッとググった感じかなりめんどくさそうなのが気になりますがw、エラー込みの奮闘記として読んでいただけると幸いです。

#作業環境
mac
CentOS7,RHEL
PHP5.4
MySQL5.6
Apache2.4
zabbix3.2

#1.事前調査
##1-1.目標の成果物と実現手段
「AWSに立てたEC2にZabbix3.2をインストールする」です。それに付随してPHPとMySQL、あとApacheも入れます。
それにあたり手順の調査。
監視対象のサーバはまた別途AWS上に作成しますので、今回はそこには触れません。

##1-2.手順の調査
調査しながら湧いた疑問とその回答をメモで記します。

・事前にMySQLをインストールする？DBも作っておく？
この疑問出てくる時点で相当わかっていないのですがw、Zabbixはフロントエンド（要はGUI）〜DB〜Zabbixサーバ（モジュール本体。ここでプロセスがいっぱい動いてAgentと通信したりhttpアクセスしたりする）で構成されています。
ですのでzabbix-server起動する前にDBの構築は必須です。CentOS、RHELはデフォでMariaDBが入っているので削除した方が良いとのこと。

httpdも同様にyum installして、PHPも然りだそうです。
PHPでちょっとつまずきましたが、そこは後述します。

#2.作業開始
##2-1.EC2作成
インターネット接続可能なEC2を立てます。
よくわからない方は[私の過去記事を参照くださいませ。](https://qiita.com/okome-chan/items/fa554dd5fc844a3345b2)

##2-2MySQLのインストール＆ユーザ「zabbix」の作成
[「Zabbix インストール 公式」](https://www.zabbix.com/jp/download?zabbix=3.0&os_distribution=centos&os_version=7&db=mysql)でググると公式のセットアップ手順がヒットするのでありがたく倣います。

MySQLインストールしてrootユーザのパスワード変更して、zabbixって名前のデータベースをutf8で作って、zabbixってユーザー作って権限付与してね！だそうです。
これはぴよぴよエンジニア（今もあまり変わりませんが）時代のぼくには読み取れないですねw

MySQLのインストール手順は[過去記事](https://qiita.com/okome-chan/items/b61dec17605324f83c4b)を参照くださいませ。
ユーザー作成手順は以下のとおり。この時点ではDBは作成しません。

```
# CREATE USER 'user'@'local' IDENTIFIED BY 'password';
```

##2-3.リポジトリとパッケージのインストール
以降は公式の手順の通りに進めます。
3.2を使いたかったのでURLをちょっといじくって使用します。

```
# rpm -Uvh https://repo.zabbix.com/zabbix/3.2/rhel/7/x86_64/zabbix-release-3.2-1.el7.noarch.rpm
# yum -y install zabbix-server-mysql zabbix-web-mysql zabbix-agent
```


zabbix-server,agentをyum install したタイミングでhttpdとphpがインストールされますのでゼロベースから構築する際は事前のインストールは不要です。
ちなみにd.のDBPasswordとは先ほど作成したzabbixユーザのパスワードを指します。
zabbixっていうデータベースの何かのパス？とか無駄に勘ぐりましたが普通にユーザのパスです。
zabbix_server.confのPassも同じパスを入れればOK。ここ地味に迷いました。。

##2-4.起動
あとは手順のとおりにzabbix-serverとzabbix-agentを起動して、自動起動の設定を入れればCLIでの作業は完了です。今回だと以下のURLになります。

LINUXガチャガチャやって、ブラウザでプログラムが動いたときはやっぱり嬉しいですねw

```
http://EIP/zabbix
```

##2-5.エラー
確かRHELだったと思うのですが、作業中にエラーがでました。
phpがインストールされてないからとか依存関係にあるphpが云々（）のように読めます。
ちょっと嫌になりますがw、そのまま進めるとzcatががっつりエラーに。
脳死コピペを諦めて読むと、zcatの対象となるファイルがディレクトリにないようです。見たら確かにない。
MySQLをインストールする前にzabbix-web-mysqlをyum installしたので、そこでコケたんですね。

エラーメッセージを切り取りながらググりましたが、結局RHELの場合は以下のOpticalなんたらが必要とのことでした。以下のコマンドで解決。※CentOSでは不要でした

```
# yum-config-manager --enable rhui-REGION-rhel-server-optional
```

#3.振り返り
CentOSとRHELで差分はあるでしょうが、大筋はだいたいこんな感じだと思います。

Zabbixのインストール手順はググるといっぱい出てくるのですが、以外とベストプラクティスが見つからないというかみんなバラバラなイメージでして、結局のところ公式の手順を軸にして行間を記事やgithubで補う。。というやり方が1番よさげでした。

この記事がザビのインストールに悩める方のお役に立てますと幸いです。
機械学習について誰でもわかるように書く

# 概要
機械学習ってよく聞くけど何から勉強すればいいんだよという人たちのために知っていることを書いていく．
お前の言っていることは本当なのか？とか，わかりにくいからもっと数式を使って説明しろとか，なんでもいいので興味を持つきっかけになったら嬉しい．

ニューラルネットワーク（脳を模倣したやつ; ディープラーニングの先祖）が好きなので，たぶんその話がメインになると思う．

# 機械学習とは
Wikipediaによると
> 1959年、アーサー・サミュエルは、機械学習を「明示的にプログラムしなくても学習する能力をコンピュータに与える研究分野」だとした。

とのこと．

# なぜ機械学習が必要なのか
## コンピュータが得意なこと
コンピュータは，人間がその手順を明確に説明することのできる作業がものすごく得意だ．
例えばエラトステネスのふるい（素数を見つけるやつ．ググって）のように，残った候補の中から$p$の倍数を消していくのを繰り替えす作業が得意．
コンピュータは人間よりずっと計算が早いし，上記のような単純作業を命令しても文句を言わない．

## コンピュータが苦手なこと
ところがコンピュータは，人間がその手順を明確に説明することのできない作業がものすごく苦手だ．
というよりも，コンピュータは人間が書いた手順書（プログラム）を元に作業をするので，人間が手順を明示できない作業は行うことができない．
例えば，人間は以下の写真を3次元で考えたときに，人形と植木鉢，どちらがどちらの前にあるのかなんとなくわかる．
![spring-4032364_640.jpg](https://qiita-image-store.s3.amazonaws.com/0/133491/f1d1f0f1-23de-c2d3-2c14-e714f4d4efee.jpeg)
<a href="https://pixabay.com/ja/photos/%E6%98%A5-%E5%BA%AD%E3%81%A7-%E7%BD%AE%E7%89%A9-%E3%83%9D%E3%83%83%E3%83%88-%E3%83%91%E3%83%A9-4032364/">Image</a> by <a href="https://pixabay.com/ja/users/pasja1000-6355831/">pasja1000</a> on Pixabay

でも，どういう手順でそう判断するに至ったかを説明することはできない．
だから，コンピュータに上の問題を解くプログラムを与えることもできない．

## 機械学習を使ってやりたいこと
そこで，機械学習という手法の出番だ．
機械学習では，ある問題を解決するための手順を与えることはできないけれど，データから（人間には見つけられない）規則性を発掘して「入力を与えたら正解を返す箱みたいなもの」を作ることを目標とする．
上の写真の例で言えば「写真を入れると3次元で考えたときに前にくるものが返ってくる箱」を作る．

# 箱の作り方
ニューラルネットワーク，サポートベクトルマシン，k-meansなどいろいろある．
いずれの手法も，問題を解くための明示的な手法ではなくデータを与えて，コンピュータの得意な四則演算と繰り返し処理で規則性を見つけることを目標としている．
社畜ITエンジニアがフリーランスになるタイミングはいつが良いか？

※初投稿なので多少の落ち度は多めにみてください。
# 会社員がフリーランスになること
都心ではフリーランスのITエンジニアの存在が当たり前のようになっていると思います。
私自身も2年前に独立しましたが、仕事が無くなる心配は全く感じませんし
会社員になると無条件についてくる会社のしがらみなどがなくなり、沢山のメリットを実感しています。

会社員で居続けることにあまり希望を見いだせないITエンジニアには
独立してフリーランスになることは普通におススメできる選択肢だと思います。

## 要因別の独立タイミング
フリーになるタイミングを考えるうえで様々な要因があると思いますが、以下の分類で纏めます。

1. 年齢、就業年数による要因
2. 技術習得、業務経験習熟による要因
3. 会社環境による要因
4. パーソナル(個人的)な要因

### 1.年齢、就業年数による要因
まず就業年数ですが、最低4年は会社員として経験を積むべきと考えます。
理由は**「キャリア転職と同じようなものである」**からです。
エンジニアとしてある程度経歴が詰めていれば、フリーランスでも問題なくやっていけます。
逆に職歴３年以下のいわゆる**「第二新卒」までは独立は難易度が高い**と思います。
会社を辞めたくなったら、別の会社へ転職して経歴の上乗せをオススメします。
**「客観的にみて、一人前であると見なせるかどうか」**が重要だと考えます。

年齢的な面でいうと、**「何歳で独立してもいい」**と思います。
フリーランスというとなんとなく若い人がノマド的にやってるイメージですが
50過ぎ・定年間際のご年配のフリーランサーも普通に居ます。
ですのでフリーでも定年まで普通に働くことが可能です。

### 2.技術習得、業務経験習熟による要因
技術や業務的な区切りは纏めると以下のようなタイミングです。

- ある１つの開発言語による業務経験が3年以上に達した。
- 要件定義フェーズ(上流工程)の業務を経験した。
- 開発チームリーダー(TL,GL)としての管理業務を経験した。
- プロジェクトリーダー(PL)、プロジェクトマネージャー(PM)業務を複数回経験した。

これは**「案件の単価を吊り上げられる要素」**です。

フリーランス案件の発注元はフリーランスに対して**「スペシャリストであること」**を多く求めています。
プログラマーの場合はその基準が大体「言語の業務経験3年」であるということです。
Python、Java、Ruby、JavaScriptのどれかを１つを３年以上経験してたら仕事が切れることはほとんどないと思います。

PL、PMに関しては募集案件は炎上案件が多いと聞きますし会社に居続ける方が懸命な気もしますが、「あまりに収入が見合わない」とか「年収1000万普通に稼ぎたい」という動機でやるなら全然ありだと思います。

### 3.会社環境による要因
「会社が嫌になったらフリー」っていうのも全然ありですが、要因上げたらキリがありませんので客観的にそういう人がいたらフリーランスを勧めたいなというケースを挙げてみました。
#### ・30歳になっても年収が400万を超えない
普通に転職しても年収上げられると思いますが、フリーになる選択肢も考えるべきです。
新卒からITエンジニア業に携わり、30歳近くになるころにはSEレベルの仕事はこなせると思います。
その状態でフリーになったとき、委託業務であれば月収55万程度の案件は高確率で契約取れると思います。体感の年収も100万以上アップになるでしょうし、転職でハズレの会社に当たるリスクを考えるとフリーの方がいいのではないかと個人的には思います。
#### ・業務内容や開発環境を変えたい
自分で開発を行うのはもちろんですが、募集案件についても**フリーランサーを募集している会社は新しい技術に寛容な会社が多い**印象があります。
ずっとフリーは嫌だけどいい職場探しの手段として、フリーランス案件の委託業務を受けてみるというのもオススメできます。

### 4.パーソナル(個人的)な要因
これはタイミングや「こういう性格の人がフリーランスに向いてるよ」というものになります。
#### ・担当してる業務に飽きた、環境に飽きた
まさに私がそうなのですが、**同じ職場、同じシステムの仕事がずっと続くのがイヤ**ってタイプの人です。
案件の契約はプロジェクトや開発フェーズの区切りで終了になるので、長くても1年半くらいですし、短ければ2～3ヶ月位です。環境を変えることでモチベーションを保てる方には向いていると思います。
#### ・職場で密な人間関係を構築したくない
理由は上と同じですが、こちらが特別コミュニケーションを頑張ったり、よほど相性のいい人に合わない限り契約が切れれば人間関係も切れます。
プライベートが充実している人は、会社で関係が出来上がることに面倒くささを感じるケースがあるはずで、そもそも人づきあいをしたくない人もいると思います。
会社に馴染みたくない人、馴染めない人にフリーランスはいい駆け込み先になることでしょう。

# まとめ
いろいろと要因あげましたが、根本の動機は「チャレンジ・キャリアアップ」といった**ポジティブな理由**か、「現状打破・問題回避」のような**ネガティブな理由のどちらか**だと思います。
フリーランスになると言う選択肢は**どちらの理由に対しても受け止められる手段である**というのが私の考えです。
もちろん会社員の方がいいこと・有利なことは沢山ありますが、フリーランスに対してリスクを大きく感じている人には「軽く前向きに考えても大丈夫だよ」と教えてあげたいです。