OmniAICreator/Qiita-1.07M huggingface dataset:
EtherCATでステッピングモータ を動かしてみる



この記事は [EtherCATについて語る Advent Calendar 2019](https://adventar.org/calendars/4097) の15日目です。
昨日は@nonnoiseさんの [EtherCATの通信距離について](https://qiita.com/nonNoise/items/89ea8010324ac2a853dc) でした。


#はじめに

今回の記事は**こんなこと出来るかなぁ〜**と思った内容の記事です。

<font color="Red">**決してEtherCATの性能とは思わないでください。**</font>

安直な方法で雑にやってます。

本来はもっと慎重に考えてプログラムを作成していく形ですが、**ひとまず動かしてみよう！**という**実験の一つ**です。


#ステッピングモータについて

間に合わなかったので、後日まとめます＞＜

#動作手順

間に合わなかったので、後日まとめます＞＜　２

#小型のステッピングモータ を動かしてみる！

[![画像がここに入る](http://img.youtube.com/vi/HWh1v26XH4w/0.jpg)](http://www.youtube.com/watch?v=HWh1v26XH4w)

サクッと小型のステッピングモータを動かしてみました。
快調快調！
ただ、動作電圧が低い為、速度をあげるとトルクが下がる部分もあり、難しいなぁってところです。

スピード的にはまぁまぁ早く（細かく調整はできませんが）動いたので、正転逆転制御ならできそう。

３個同時に動かしていた動画が見つかったので、一緒に供養しておきます。

[![画像がここに入る](http://img.youtube.com/vi/SoMjkuhsOtE/0.jpg)](http://www.youtube.com/watch?v=SoMjkuhsOtE)


#大型ステッピングモータ を動かしてみる！

さて、大型ステッピングモータ ですが、ステッピングモータ といえばオリエンタモータですね。
オリエンタルモータのステッピングモータが動かせれば、ひとまず**ステッピングモータ**が動かせたとなりますよね。

[![画像がここに入る](http://img.youtube.com/vi/QgDShWGGL8I/0.jpg)](http://www.youtube.com/watch?v=QgDShWGGL8I)

こんな感じで、駆動電圧をアキバで買った19V3.6AのACアダプタにして動かしてます。

スピードはちょっとゆっくりです。やはり大きいと小回りが効かないですが、トルクはあります。


#ステッピングモータでペットボトルを持ち上げる！

EtherCATと関係ないですが、何か面白い事ができないか模索した時に、とりあえずトルクある試してみるか！という事で、**ペットボトル引き上げチャレンジ**をしました！

[![画像がここに入る](http://img.youtube.com/vi/dRYsVknguXo/0.jpg)](http://www.youtube.com/watch?v=dRYsVknguXo)

いぇぃ！！

#おわりに

**EtherCATの説明全くねぇ〜〜〜〜**
**しかも、そんな動いてねぇ〜〜〜**
**もっとすごい事してぇ〜〜〜**

ごもっともです。

正直、この実験は<font color="Red">**挫折**</font>です。

原理的に、確かに早いIOがEtherCATで得られたのでマイコンレスでパルスを生成することができました。
それは良いですが、ステッピングモータ はそれほど甘くなかった。
現代のステッピングモータ制御はすでに電流制御もあったり、台形移動やマイクロステップといった技術が **当たり前**です。

なので、こんな古臭い技術をいまだに使ってるのを驚かれるかもしれません。
やはり、マイコンを使い、きめ細かな制御をするのが一番ですね。

EtherCATはGPIOの制御がメインではなく、データを受け渡すことがメインですので、マイコンを介入することで、**30ステップ進んだところで停止して**と指示を与えれば良いのです。

30ステップ進めと指示を受けたら、マイコンは素直に**30ステップ進めて**次の指示が来るまで停止すれば良いのです。

その繰り返しで、X軸に〜mm進み、Y軸に〜mm進みといった指示が出来るものです。
その際に、電流制御や台形制御を行うのはマイコンがやることで、**EtherCATが面倒を見る必要はない**のです。

なので、今回の実験は、**こんなことがやりたかった！**と**マイコン制御も必要だよね！**
で、終わりたいと思います！！（なんじゃそりゃ）

次週はもっと真面目な記事に戻ります！

ではでは 
北神　(@nonnoise)
【画像処理100本ノックに挑戦】Q.17. Laplacianフィルタ

# 使用したライブラリ
[【画像処理100本ノック】独自の画像入出力クラスを作る](https://qiita.com/jajagacchi/items/834e8425b84f94df8a49)

# Q.17. Laplacianフィルタ
> Laplacianフィルタを実装せよ。
Laplacian（ラプラシアン）フィルタとは輝度の二次微分をとることでエッジ検出を行うフィルタである。

ラプラシアンフィルタは使ったことないです。ラプラシアンの差分近似自体は計算したことがあるので省略します。これもカーネルを変えるだけですね。ここらへんはフィルタ地獄ですね。早く抜け出したい・・・。

```c++
int main()
{
	PPM ppm("imori.pnm");
	int width = ppm.Get_width();
	int height = ppm.Get_height();
	PPM ppm2(width, height);

	auto kernel = [&](int i, int j)
	{
		double ret = 0;
		if (i == 0 && j == 0) ret = -4;
		if (i * j == 0 && (abs(i) == 1 || abs(j) == 1)) ret = 1;
		return ret;// / 16.;
	};

	auto conv = [&](const std::vector<std::vector<double>>& f)
	{
		std::vector < std::vector < double >> ret(width, std::vector<double>(height));
		for (int j = 0; j < height; j++)
			for (int i = 0; i < width; i++)
			{
				ret[i][j] = 0;
			}
		for (int j = 0; j < height; j++)
			for (int i = 0; i < width; i++)
			{
				int sum = 0;
				for (int di = -1; di <= 1; di++)
					for (int dj = -1; dj <= 1; dj++)
					{
						if (i - di >= 0 && i - di < width && j - dj >= 0 && j - di < height)
						{
							ret[i][j] += kernel(di, dj) * f[i - di][j - dj];
							sum += kernel(di, dj);
						}
					}
				//ret[i][j] /= (double)sum;
			}
		return ret;
	};

	std::vector < std::vector < double >> arry(width, std::vector<double>(height));
	for (int j = 0; j < height; j++)
		for (int i = 0; i < width; i++)
		{
			int r = ppm(i, j, 'r');
			int g = ppm(i, j, 'g');
			int b = ppm(i, j, 'b');
			int y = (std::round)(0.2126 * r + 0.7152 * g + 0.0722 * b);
			arry[i][j] = y;
		}
	arry = conv(arry);

	for (int j = 0; j < height; j++)
		for (int i = 0; i < width; i++)
		{
			int val = abs(arry[i][j]);
			if (val > 255) val = 255;
			ppm2(i, j, 'r') = val;
			ppm2(i, j, 'g') = val;
			ppm2(i, j, 'b') = val;

		}

	ppm2.Flush("out.ppm");
	return 0;
}
```

![imori.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520857/fcb7186b-b60a-1079-410e-71e0a5a5a936.png) ![out.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520857/6f8858b0-2063-8432-3efb-2f15fbc4b330.png)
【Ruby】ローカルでKaminari(Gem)をデバッグする環境を作る

# 環境構築
## ソースを取ってくる
- fork
- git clone

## bundle install
```sh
bundle install --path vendor/bundle
```
## Rubyのバージョンを指定する

```:.ruby-version
2．6．5
```

## Bundler.requireしてGemの処理を呼び出す
```tmp/app.rb
require 'bundler'
Bundler.require

p Kaminari.paginate_array([1,2,3,4,5], total_count: 6).page(1).per(2)
```

これでローカルでソースを編集すると反映されるようになります。
RubyMineでDebug実行することも可能です。

# テストを動かす

## script: 'bundle exec rake test'
`.travis.yml`を見てみると`script: 'bundle exec rake test'`という記載があるので実行します。
(`.travis.yml`はTravis CIの定義ファイルなので、`.travis.yml`と同じことをローカルで行えばテストは動くはずという考えです。)

```sh
bundle exec rake test
```

## `sqlite3`をgemfileに追加する
sqlite3がないという旨のエラーが表示されるはずなので、追加して`bundle install`します。

```rb:Gemfile
# frozen_string_literal: true

source 'https://rubygems.org'

# Specify your gem's dependencies in kaminari.gemspec
gemspec

gem 'sqlite3'
```
再度`bundle exec rake test`するとテストが動くはずです。

# まとめ
おそらくですが、他のGemも同じような方法で環境は整いそうな気がします🤔
OSSコントリビュートしていくぞい💪
半々人前のフロントエンドエンジニアが成長するために必要だと感じたこと

#はじめに
　私は今年の4月から初めてMacを使い始めてプログラミングというものに触れ、今日まで約８ヶ月間勉強をしてきました。
今は、フロントエンドの分野で月に約3本のWeb案件に取り組んでいます。（まだ独り立ちはできていませんが...）
今まで勉強してきて、効率的に勉強を進め最も近道に成長をしていくためにはどうしたらいいのか、自分なりの考えをまとめ、初心を忘れないようにするためにも記事にしたいと思います。

#今までやってきたこと
- 　4~6月前半...pythonチュートリアルを基本1人で学び、わからないところは教えてもらう
- 　6月前半~9月中旬...初めての案件に参加(バックエンド)
- 　9月中旬~１０月中旬...フロントエンドの勉強
-  　~現在...フロントエンドの案件でアウトプット＆お勉強

#できるようになったこと（まだまだ未熟ですが...）
1. Git、Github
2. html、css
3. Wordpress
4. Figma
5. インフラ、セキュリティ周り（ほんーの少し）

#実践してみてよかったこと
- pythonチュートリアル→なんとなーくプログラミングの様子がわかり、操作に慣れた
- スキルが全くないにも関わらず案件に参加→急成長できた
- 自分で調べてもわからなかったらためらわずに質問する

#習うより慣れろ！
案件に初めて参加させていただいた時にはpythonしか知らず(それもほんの少し)、いきなりDjangoやDocker、Git、Gihubなどを使い、最初はわからないことが多すぎてパンクしそうでした。任せていただいた仕事も私1人の力で終わらせることはできず、いつも先輩に教えてもらってばっかりでした。でも、思ったのは...**習うより慣れろ！**
自分で勉強を進めるだけでは世界が狭く、モチベーションを保つのも大変です。案件に参加することで先輩方のコードを見ながら勉強することができました。
仕事を振ってもらう→調べる→少しは自己解決→わからないところを教えてもらう→理解する→成長→新たな仕事を振ってもらう、という好循環が生まれ、短期間(?)でいろいろなことができるようになりました。

#教えてもらう立場
教えてもらうには受け身ではなく、積極的に動き、教えてもらえるような人になるということが大切だなと思いました。
自己解決できない時には、
1. 現状報告
2. コードを見せる
3. 何をどう改善したいのか
4. 試してみたこと
これらを報告することは絶対必要です。見た目だけ見せられてもどういうコード書いているのか、考えてもらう手間が発生してしまいます。教えてもらうために開発や休憩する時間を奪って教えてもらうので、少しでも手間を減らさなければいけないと感じました。

#これから
将来的には、フロントエンドの分野だけではなく、バックエンドの分野も理解できるようになりたいです。
まだまだ勉強しなければならないことはたくさんありますが、少しずつ自分の理解していることをアウトプットする機会が増えていきます。
今まで親切に教えてくださったように自分も教えられるようになりたいです。
pandasd.DataFrame.groupbyについて

さて、こんにちは。
最近、床で寝ることにハマっているえーじです。
皆さんも試してみてください〜。笑

#概要
2019/12/1５
今日のテーマは**pandasd.DataFrame.groupby**です！
この記事を書くために勉強していたら意外と簡単でした・・・。
けど、データを扱う上で必ず必要になりそうなのでちょろっと書いておきます。

#*groupby*ってどんな時に使われる？
>A groupby operation involves some combination of splitting the object, applying a function, and combining the results. This can be used to group large amounts of data and compute operations on these groups.
 [Pandas.org](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.groupby.html)

これを日本語訳すると、
>
グループ化の操作は、オブジェクトの分割、関数の適用、結果の結合のいくつかの組み合わせを含む。 これを使用して、大量のデータをグループ化やグループの計算操作をするのに使われます。

つまり主に行うことは二つですね

- グループ化
- グループの計算操作


#パラメータについて
>DataFrame.groupby(self, by=None, axis=0, level=None, as_index=True, sort=True, group_keys=True, squeeze=False, observed=False, **kwargs)

これがパラメータです。特に**by**に着目です。この**by**には「ラベル」が入ります。詳しい事は下記のコードで説明します。
このラベルによって、他のデータがグループ化されるわけですね！納得:relaxed:

#Groupbyオブジェクトに対する関数
- mean() (グループ化された値の平均を取る。)
- min()  (グループ化された値の最小値を取る。)
- max()  (グループ化された値の最大値を取る。)
- sum()  (グループ化された値の合計を取る。)
- etc ・・・・

#サンプルコード
``` python:sample.py
import pandas as pd
from IPython.display import display

# あるバスケットボールの試合にて

df = pd.DataFrame({
    'Name': ['A君', 'B君', 'Cさん', 'A君', 'Cさん', 'A君', 'A君', 'B君'],
    'Score': [2, 3, 3, 2, 3, 3, 2, 3],
})

df2 = df.groupby('Name')
display(df2.mean())
display(df2.sum())
```

結果は下記に↓↓
上は平均で、下は合計得点。
<img width="149" alt="スクリーンショット 2019-12-15 22.08.32.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/255565/95258408-5be2-6d45-5ca7-60615eb87671.png">

#最後に
pandas.DataFrame.groupbyはデータをグループ化して計算する時には必須になる。
必ずマスターしたい部分ですね。
他にも**var()**や**std()**など沢山の関数があります。
確認しながら色々試してみようと思います:eyes:
参考資料：[pandas.pydata.org](https://pandas.pydata.org/pandas-docs/stable/reference/groupby.html)

何か指摘があればコメントよろしくお願いします:joy:

今日も床で寝ようと思います:v:
ではいい夢をみてください〜
おやすみなさい。
【画像処理100本ノックに挑戦】Q.16. Prewittフィルタ

# 使用したライブラリ
[【画像処理100本ノック】独自の画像入出力クラスを作る](https://qiita.com/jajagacchi/items/834e8425b84f94df8a49)

# Q.16. Prewittフィルタ
> Prewittフィルタ(3x3)を実装せよ。

これがプレウィットフィルタですか。

```c++
int main()
{
	PPM ppm("imori.pnm");
	int width = ppm.Get_width();
	int height = ppm.Get_height();
	PPM ppm2(width, height);

	auto kernel = [&](int i, int j)
	{
		double ret = 0;
		/*if (j == -1)
		{
			if (i == -1 || i == 1) ret = 1;
			else if (i == 0) ret = 1;
		}
		else if (j == 1)
		{
			if (i == -1 || i == 1) ret = -1;
			else if (i == 0) ret = -1;
		}*/
		if (i == -1)
		{
			if (j == -1 || j == 1) ret = 1;
			else if (j == 0) ret = 1;
		}
		else if (i == 1)
		{
			if (j == -1 || j == 1) ret = -1;
			else if (j == 0) ret = -1;
		}

		
		return ret;// / 16.;
	};

	auto conv = [&](const std::vector<std::vector<double>>& f)
	{
		std::vector < std::vector < double >> ret(width, std::vector<double>(height));
		for (int j = 0; j < height; j++)
			for (int i = 0; i < width; i++)
			{
				ret[i][j] = 0;
			}
		for (int j = 0; j < height; j++)
			for (int i = 0; i < width; i++)
			{
				int sum = 0;
				for (int di = -1; di <= 1; di++)
					for (int dj = -1; dj <= 1; dj++)
					{
						if (i - di >= 0 && i - di < width && j - dj >= 0 && j - di < height)
						{
							ret[i][j] += kernel(di, dj) * f[i - di][j - dj];
							sum += kernel(di, dj);
						}
					}
				//ret[i][j] /= (double)sum;
			}
		return ret;
	};

	std::vector < std::vector < double >> arry(width, std::vector<double>(height));
	for (int j = 0; j < height; j++)
		for (int i = 0; i < width; i++)
		{
			int r = ppm(i, j, 'r');
			int g = ppm(i, j, 'g');
			int b = ppm(i, j, 'b');
			int y = (std::round)(0.2126 * r + 0.7152 * g + 0.0722 * b);
			arry[i][j] = y;
		}
	arry = conv(arry);

	for (int j = 0; j < height; j++)
		for (int i = 0; i < width; i++)
		{
			int val = abs(arry[i][j]);
			if (val > 255) val = 255;
			ppm2(i, j, 'r') = val;
			ppm2(i, j, 'g') = val;
			ppm2(i, j, 'b') = val;

		}

	ppm2.Flush("out.ppm");
	return 0;
}
```

![imori.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520857/bd8ba397-8ddf-8d16-2278-ab39a1f09688.png) ![out.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520857/871e0d5a-c718-fcce-cbf0-1275f7b09f0d.png) ![out1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520857/6c572465-28bc-b0f5-dd4f-089f10e54b73.png)
超単純なケースのk-means法のpythonのコード

## k-means法の超単純なケースのPythonのコード

2019年の統計検定１級の統計応用の人文科学ではk-means法の初期値依存に関する問題が出ましたが、ここでは実際にk-meansが初期値に依存することを確認するために、超単純なケースのPythonのコードを書いてみました。

状況設定は以下の様にします。
分類する集合：（有限個の）実数を要素とする集合。
クラスターの個数：２つ。


```python:
print("最初に部類する集合の要素数を入力してください。")
n = int(input())
print("次に部類する集合の要素を入力してください。")
a = [float(input()) for _ in range(n)]

print("次に初期値を2つ入力してください。")
b = [float(input()) for _ in range(2)]


A = []
B = []
'''
print(A)
print(B)
'''
for i in range(n):
    if abs(b[0] - a[i]) <= abs(b[1] - a[i]):
        A.append(a[i])
        
    else:
        B.append(a[i])

if  len(A) == 0 or len(B) == 0:
    print("一つ目のクラスターは")
    print(A)
    print("二つ目のクラスターは")
    print(B)
else:
    c = sum(A)/len(A)
    d = sum(B)/len(B)
     
    while c != b[0] or d != b[1]:
        b[0] = c 
        b[1] = d
        A = []
        B = []
        for i in range(n):
            if abs(b[0] - a[i]) <= abs(b[1] - a[i]):
                A.append(a[i])
        
            else:
                B.append(a[i])
        c = sum(A)/len(A)
        d = sum(B)/len(B)
    

    print("一つ目のクラスターは")
    print(A)
    print("二つ目のクラスターは")
    print(B)
```

このコードを初期値を変えて実行した例を２つ下に載せておきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/359600/65e009ce-e6de-d07e-50a4-3e5eec116897.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/359600/5b1139e3-463d-cfeb-e59b-0babdad5ff66.png)

ということで、実際に初期値を変えると最終的なクラスターも異なることが確認できました。∩( ･ω･)∩
k-mean法を使って非階層的クラスター分析をするときは注意が必要ですね。

(追記：2022年の統計検定1級の人文科学問3でもk-meansの問題が出題されました。)

## 改良版

k-meansの初期値選択に改良を行ったクラスタリング手法としてk-means++が存在します。
また、初期値ではありませんが、クラスタ数を自動推定する発展形のアルゴリズムとしてG-meansやX-meansといったアルゴリズムが存在します。
【画像処理100本ノックに挑戦】Q.15. Sobelフィルタ

# 使用したライブラリ
[【画像処理100本ノック】独自の画像入出力クラスを作る](https://qiita.com/jajagacchi/items/834e8425b84f94df8a49)

# Q.15. Sobelフィルタ
> Sobelフィルタ(3x3)を実装せよ。

知らないフィルタがあるなあ。基本的には微分フィルタなんだけど、勾配空間で重み付き平滑化をかけたものかな。重みをつけないものをプレウィットフィルタというらしい。カーネルを変えるだけ。

```c++
int main()
{
	PPM ppm("imori.pnm");
	int width = ppm.Get_width();
	int height = ppm.Get_height();
	PPM ppm2(width, height);

	auto kernel = [&](int i, int j)
	{
		double ret = 0;
		/*if (j == -1)
		{
			if (i == -1 || i == 1) ret = 1;
			else if (i == 0) ret = 2;
		}
		else if (j == 1)
		{
			if (i == -1 || i == 1) ret = -1;
			else if (i == 0) ret = -2;
		}*/
		if (i == -1)
		{
			if (j == -1 || j == 1) ret = 1;
			else if (j == 0) ret = 2;
		}
		else if (i == 1)
		{
			if (j == -1 || j == 1) ret = -1;
			else if (j == 0) ret = -2;
		}

		
		return ret;// / 16.;
	};

	auto conv = [&](const std::vector<std::vector<double>>& f)
	{
		std::vector < std::vector < double >> ret(width, std::vector<double>(height));
		for (int j = 0; j < height; j++)
			for (int i = 0; i < width; i++)
			{
				ret[i][j] = 0;
			}
		for (int j = 0; j < height; j++)
			for (int i = 0; i < width; i++)
			{
				int sum = 0;
				for (int di = -1; di <= 1; di++)
					for (int dj = -1; dj <= 1; dj++)
					{
						if (i - di >= 0 && i - di < width && j - dj >= 0 && j - di < height)
						{
							ret[i][j] += kernel(di, dj) * f[i - di][j - dj];
							sum += kernel(di, dj);
						}
					}
				//ret[i][j] /= (double)sum;
			}
		return ret;
	};

	std::vector < std::vector < double >> arry(width, std::vector<double>(height));
	for (int j = 0; j < height; j++)
		for (int i = 0; i < width; i++)
		{
			int r = ppm(i, j, 'r');
			int g = ppm(i, j, 'g');
			int b = ppm(i, j, 'b');
			int y = (std::round)(0.2126 * r + 0.7152 * g + 0.0722 * b);
			arry[i][j] = y;
		}
	arry = conv(arry);

	for (int j = 0; j < height; j++)
		for (int i = 0; i < width; i++)
		{
			int val = abs(arry[i][j]);
			if (val > 255) val = 255;
			ppm2(i, j, 'r') = val;
			ppm2(i, j, 'g') = val;
			ppm2(i, j, 'b') = val;

		}

	ppm2.Flush("out.ppm");
	return 0;
}
```

![imori.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520857/b671b08d-d626-7f54-c3ef-8a9838fe6ab0.png) ![out.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520857/4f3b1b56-7d71-9cb0-99a0-4e8e5c4f243d.png) ![out1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520857/2d3f2400-7f85-4e99-3040-8bdaccdd8ac6.png)
Vue.jsプラグインで始めるOSS

## はじめに
これは[Vue Advent Calendar 2019](https://qiita.com/advent-calendar/2019/vue)の16日目の記事です。

最近、Vue.jsのプラグインを作ってNPMパッケージとして公開する機会がありました。Vueのプラグインを作るのもNPMパッケージを公開するのも初めてでしたが、意外と手軽にできたので、「OSSはなんか敷居が高そうだ...」と思っているエンジニアにもオススメです。

今回、TypeScriptでVueプラグインを実装し、NPMに公開するためのテンプレートを用意してGithubに公開しました。この記事では、そのテンプレートの紹介をします。

## テンプレートのご紹介
[vue-plugin-ts-template](https://github.com/gyarasu/vue-plugin-ts-template)というテンプレートを用意しました。
中身は本当にシンプルで、一般的なtypescriptのプロジェクトでちょっとだけ実装したコードが入っているだけのものになります。

案外、TypeScriptやeslint、prettierの導入が面倒だったりするので、Vueのプラグインの作り方というよりかは開発環境を一発で作れるという意味の恩恵のほうが強いかもしれません。


## プラグインの実装〜NPMパッケージの公開まで
流れは[README](https://github.com/gyarasu/vue-plugin-ts-template/blob/master/README.md)に書いてありますが、英語になっているので改めて日本語で解説していきたいと思います。


### 0. 要件
NPMパッケージとして公開するにあたり、[NPM](https://www.npmjs.com/)のアカウントが必要になるので、公開しようと思う人は作っておくようにしましょう。
また、typescriptは`tsc`でコンパイルしているのでグローバルにインストールしておくと良いでしょう。


### 1. packageの初期化と依存関係のインストール
まずはテンプレートをダウンロードして依存関係をインストールしましょう。
NPMに公開する際には、パッケージのいろんな情報を入力する必要があります。
下記のコマンドを実行すると、コマンドライン上でインタラクティブに質問が出てくるので自分のパッケージにあったものに修正していきましょう。

```bash
$ yarn install
$ yarn init
```

<img width="933" alt="スクリーンショット 2019-12-15 22.12.42.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29971/9008f050-e16c-9bc0-b365-9930a2c9920d.png">

こんな具合に入力していきます。

- テンプレートには初めから設定値が入っているので、使う場合は上書きしてください。
`keywords`は聞かれないようなので、直接`package.json`を編集する必要があります。
- `endopoint`はデフォルト（`index.js`）で大丈夫です。`tsconfig.json`でビルドファイルをプロジェクト直下の`index.js`として出力するようにしています（好みに応じて変えてください）。


### 2. プラグインの実装
Vueプラグインの実装方法については[公式サイト](https://jp.vuejs.org/v2/guide/plugins.html)が参考になります。
`src`フォルダ内でTypeScriptを書いてください。
テンプレート内ではLoggerをインスタンスメソッドとして追加しています。

https://github.com/gyarasu/vue-plugin-ts-template/blob/master/src/index.ts

```typescript:src/index.ts
import _Vue from 'vue';

// eslint-disable-next-line @typescript-eslint/no-explicit-any
const log = (value: any): void => {
  console.log(value);
};

export default {
  install(Vue: typeof _Vue): void {
    Vue.prototype.$log = log;
  }
};

```

ちなみに、公開したパッケージはこんな感じで使えます。

```main.js
import Vue from 'vue';
import VueLogger from 'vue-logger'; // 公開するパッケージ名

Vue.use(VueLogger);
```


```App.vue
<script>
export default {
  mounted() {
    this.$log('component is mounted!');
  }
};
</script>
```


### 3. ビルド
npmスクリプトとしてビルドコマンドも用意しています。

```bash
$ yarn build
```

これだけです。


### 4. コミット&プッシュ&タグ作成
ビルドまで終わったらNPMに公開できる状態になります。
NPMに公開してるバージョンとGithubのコードのパージョンは揃っていたほうが都合がいいと思うので、公開する前にコードをコミット・プッシュして、バージョンがわかるタグを打っておくようにしましょう。
`package.json`内にあるバージョン情報も必要に応じて更新しましょう。


### 5. NPMへの公開
ここまでくればあとは公開するのみです。
プロジェクト直下（`package.json`がいるディレクトリ） で下記のコマンドを実行すればOKです。

```bash
$ npm adduser 
$ npm publish ./
```
`npm adduser`では、登録済みのNPMアカウントでログインを行います。
ここでログインしたアカウントにパッケージが追加されることになるので、会社用・仕事用で使い分けている場合などは注意しましょう。


## まとめ
Vueでなにかする場合に、プラグインとして使える機能があると結構便利です。
また、プラグインの作成もそんなに難しいものではないですし、OSS活動を始めるにはもってこいの題材かもしれません。
便利なプラグインを作ってVueを盛り上げていきましょう！！
Python の通信を Fiddler で見る

az コマンドの通信を HTTPS デコードして Fiddler で見たかったけど Python は Windows の証明書ストアを見ないらしく、Fiddler のルート証明書を信頼できずに証明書エラーが発生した。

```powershell
Please ensure you have network connection. Error detail: 
HTTPSConnectionPool(host='login.microsoftonline.com', port=443): Max retries exceeded with url: /common/oauth2/token (Caused by SSLError(SSLError("bad handshake: Error([('SSL routines', 'tls_process_server_certificate', 'certificate verify failed')],)",),))
```

## 解決策

Fiddler の Root 証明書を環境変数 `CURL_CA_BUNDLE` にセットする。

```powershell
$env:CURL_CA_BUNDLE = "C:\Path\To\FiddlerRoot.cer"
```

なお、ルート証明書は Base64 エンコードである必要がある。
証明書ストアから、Base64 でエクスポートするのが楽。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/83984/846bdc2e-feae-c7cf-b4f9-b00f2f92d081.png)


あとは環境変数に Fiddler のプロキシをセット

```powershell
$env:http_proxy = "http://127.0.0.1:8888"
$env:https_proxy = $env:http_proxy
````

これで Fiddler で通信トレースを取れる。
ファイルパーミッションとスーパユーザについて調べたこと

Linuxのファイルパーミションや権限などについて無知だったので調べた。

## はじめに
Linuxで扱われるファイルは、自分で作成したファイルからシステムが提供するライブラリから実行コマンドまですべてに所有権が設定される。
ファイルのオーナーは、ファイルへのアクセス権を自由に設定することができる。

ファイルのオーナーの確認

```
$ ls -l /bin/cat
```
```
-rwxr-xr-x  1 root(ファイルのオーナー)  wheel(ファイルが所属するグループ)  23648  9 21  2018 /bin/cat
```

## グループ
グループとは、ユーザをまとめた集まりのこと。

システム管理を行う`wheel`というグループに複数の管理者ユーザーを所属させ、wheelグループに対して許可を与えることで、同じ役割を持つ複数ユーザーに同一の権限を与えることができる。

### ユーザについて

* ユーザーは同時にいくつものグループに所属することができる
* どのユーザーも１つ以上のグループに所属しなければならない
* ユーザーが作られた際に、特に指定を行わない場合は、ユーザーと同一のグループに所属する
* 自身が所属しているグループは`groups`コマンドで確認することができる

## ファイルのパーミッション
それぞれのファイルには、***「誰に、どのような操作を許可する」***という権限を規定する情報が設定される。

```
-rwxr-xr-x(ファイルタイプとファイルパーミッション) 1 root(ファイルのオーナー)  wheel(ファイルが所属するグループ)  23648  9 21  2018 /bin/cat
```

### ファイルタイプについて

* - : 通常ファイル
* d :ディレクトリ
* l :シンボリックリンク

### ファイルのパーミッション
`rwxr-xr-x`で表示されるファイルのパーミッションは3つごとに、１つのブロックになっており、それぞれ「オーナー」「グループ」「その他のユーザ」に対するパーミッションを意味している。
rやw、xといった記号は許可されるファイルへの操作を意味しています。操作は「読み取り」「書き込み」「実行」の3つの種類がある。許可されていない場合には、`-`表示される。


```
-rwxr-xr-x 1 root  wheel  23648  9 21  2018 /bin/cat
```

#### 上記のファイルの権限についての説明

##### オーナー
`rwx` → 「読み取り」「書き込み」「実行」が許可

##### wheelグループのユーザ
`r-x` → 「読み込み」「実行」が許可

##### その他のユーザー
`r-x` → 「読み込み」「実行」が許可

### chmodコマンド
ファイルやディレクトリのパーミッションを設定するコマンド。chmodコマンドにはシンボルモードによる指定と、数値モードによる設定がある。

#### シンボルモードのユーザ指定方法
* u : オーナー
* g : グループ
* o : その他のユーザ
* a : 上記の全て

#### シンボルモードでの利用方法

オーナーの書き込み権限を追加
```$ chmod u+w file.txt```

グループの書き込み権限を削除
```$ chmod g-w file.txt```

その他のユーザの権限を読み込みだけにする
```$ chmod o=r file.txt```

#### 数値モードでのユーザ指定方法

数値モードでのパーミッションの数値

* r(読み込み) : 4
* w(書き込み) : 2
* x(実行) : 1

#### 数値モードでの利用方法

file.txtのパーミッションを`rwxr-xr-x`に指定する
```$ chmod 755 file.txt```

## スーパユーザ
管理者権限を持つ、特別なユーザ

通常は一般ユーザでログインし、操作し、必要な場合のみスーパユーザとして、作業することが一般的。

### suコマンド
一時的に別のユーザになるためのコマンド

suコマンドは任意のユーザーになることができるが、このコマンドは主にスーパユーザになるために利用される。Linuxではセキュリティの理由から、スーパユーザで直接ログインすることはできない。まず一般ユーザでログインして、suコマンドでスーパユーザになる必要がある。

### sudoコマンド
別のユーザとしてコマンドを実行する。ユーザを指定しない場合には、スーパユーザとして実行される。

##　まとめ
なんとなくでchmodコマンドやsudoコマンドを使っていたので、勉強になった。
Magento2 on Docker 2019 を公開しました

## 今年も Magento2 on Docker がアップデートいたしました！

[kzkick2nd/magento2-on-docker: Magento2 docker-compose kit](https://github.com/kzkick2nd/magento2-on-docker)

Magento2 コンテナを研究してもはや4年、カズキック2です。

私の2019年は Meet Magento Japan にてついに Magento2 on GKE のノウハウを発表するなど、ようやくコンテナホスティングが可能な Magento2 コンテナの糸口がつかめてまいりました。

インフラ界に目をやると、CNDF による Kubernetes の標準化とそれに伴い、マネージドコンテナホスティング、通称 CaaS、KaaS が台頭し、デプロイチェーンにおいてコンテナを中心に各インフラサービスに横串を通す状況となってきました。もはやコンテナは Vagrant を置き換える開発用途ではなく、インフラの標準言語となったと感じています。

これに伴い、Magento2 on Docker という名前での提供も一段落がついたと思いますので、2019年版をもって"on Docker"としての更新は終了いたします。

本記事では Magento2 on Docker 最後のβバージョン、2019 で新しくなった点を紹介したいと思います。

### マルチステージ対応
Magento2 は初期化時点で400MB程度の容量を使う大きなアプリケーションです。ビルド時の巨大さが以前より問題になっていたので、マルチステージビルドで容量を削減しました。といっても1.5GBから1G程度への削減ですが、頻繁なビルドにおいてはこの差が効いてきます。より軽量な Alpine イメージであればさらに軽量化できる余地もありますが、複雑な Dockerfile となるためメンテナンス性を重視して php-apache-buster イメージを利用しています。

### ローカル同期をやめた
Magento2 のファイル容量が多いことで、2018 版以前では Docker for Mac の泣き所であるローカル同期の遅さをもろに食らっていました。ホスティング前提のイメージにすること、また通常の開発では Magento2 標準ファイルを編集することはバッドプラクティスであることから、2019 版からイメージで完結し、必要な際に Docker Compose の Volume mount を差し込む形としました。

サンプルで標準出力ロガーを app/code 以下にマウントしていますので、それを参考に必要な場所にディレクトリを同期してください。

### 標準出力ロガーを同梱
コンテナホスティングではログは標準出力に出すことが標準仕様となっています。これに対応するため Magento2 デフォルトロガーを上書きして標準出力するサンプルモジュールを同梱しています。サンプルでは di.xml によるクラス上書き設定と、 monolog の出力先をファイルではなく標準出力にしてあるだけですので、必要に応じてログフォーマット等を変更してください。

### ディレクトリを /var/www/magento/ に変更
公式 PHP Apache イメージでは /var/www/html は root ユーザーによる起動しか許可しておらず、これは Kuberenetes でホスティングした際のプロセス実行ユーザーにも影響します。ホスティング時のセキュリティの観点から、この root 縛りを外すため /var/www/magento/ ディレクトリにて apache 仮想ホストによる起動を行っています。

起動の仕方は [README](https://github.com/kzkick2nd/magento2-on-docker) を参照ください。動作不良の報告、PR はいつでも受け付けていますので、お気軽にご連絡ください。
【備忘録】①tweet取得・保存 ~拡散されるニュースツイートを判別したい~

### 開発環境
Windows10
Anaconda3 ( jupyter notebook )
### 説明と目的
ある大学生の卒論備忘録
テーマは、ニュースツイートにおいて、拡散されるものと拡散されないものの判別器を作るというものです。
今回は、その中でのTweet取得について書いています。
### 前提条件
・Tweet Developer認証済み
・tweepyインストール済み
### 参考
https://qiita.com/i_am_miko/items/a2e5168e619ed37afeb9
### ツイート取得
取得するアカウントは@livedoornewsです。
理由としては、フォロワー数とそのフォロワーの感度のよさ(RTをよくするか)で秀でていたためです。

```python:get_newstweet.ipynb
# 必要なライブラリをインポート
import tweepy
import pandas as pd
```
```python:get_newstweet.ipynb

# Twitter APIを使用するためのConsumerキー、アクセストークン設定
Consumer_key = "API key"
Consumer_secret = "API secret Key"
Access_token = "Access token"
Access_secret = "Access token secret"

# 認証
auth = tweepy.OAuthHandler(Consumer_key,Consumer_secret)
auth.set_access_token(Access_token, Access_secret)
api = tweepy.API(auth)
```
```python:get_newstweet.ipynb
# アカウント名指定
acount = "@livedoornews"
"""
取得内容　ツイートナンバー，時間，ツイートテキスト，いいね数，RT数
"""
def get_tweets(acount):
    tweet_data = [] # 取得するデータを格納するための空リスト
    for tweet in tweepy.Cursor(api.user_timeline,screen_name = acount,exclude_replies = True).items():
        tweet_data.append([tweet.id,tweet.created_at,tweet.text.replace('\n',''),tweet.favorite_count,tweet.retweet_count])
        df = pd.DataFrame(tweet_data,columns=['tweet_no', 'time', 'text', 'favorite_count', 'RT_count']) #pandasのDataFrameに格納
    return df

df = get_tweets(acount)
```
### 取得したツイートを保存する (csv)
上の関数で継続してツイートを取り続けたい場合、追加保存をする必要があります。そのため、保存方法を新規保存用と追加保存用の二つ作りました。

##### 一つ目、新規保存
```python:get_newstweet.ipynb
# 新規保存
file_name = "../data/tweet_{}.csv".format(acount)
df.to_csv(file_name, index=False) # indexは多くの場合必要ない
```
##### 二つ目、上書き保存
```python:get_newstweet.ipynb
# 上書き保存
file_name = "../data/tweet_{}.csv".format(acount)
pre_df = pd.read_csv(file_name) # 前のcsvを読み込む
df = pd.concat([df, pre_df])
df = df.drop_duplicates(subset=['tweet_no']) # ツイートNoで重複したもの削除(新しいデータの方を残す)
df.to_csv(file_name, index=False)
```
### まとめと次回の内容
以上、ツイートの取得とその保存でした。
新規保存や上書き保存はもっとより良い方法があるかと思います。
次回は、RTの削除とURLの除去を行いたいと思います。
【UE4】C++標準バージョンの切り替え方法


# 最初に

この記事はVisual Studio 2019にIDEを設定してプロジェクトがサポートするC++標準のバージョンを変更することを記事にしたものとなります。間違いや更に良い方法があった場合にはそっとTwitter( [@ろっさむ](https://twitter.com/4_mio_11) )やコメント、修正リクエストなどでお知らせ頂けるととても有難いです。 

# 作業環境

記事内で使用する作業環境は以下の通りとなります。

- Unreal Engine：4.23.1
- Visual Studio：Community 2017 or Community 2017 for Mac or Enterprise 2019



# Visual Studio 2019を標準IDEに変更する

左上メニューの`Editor `から`Editor Preferences...`を開き、`Source Code`から`Source Code Editor`を`Visual Studio 2019`に変更してください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/36899/6c1629d9-8f85-614b-cf30-96a4b64458fc.png)

この変更に伴って、UE4ではVisual Studio 2015でのサポートを廃止しています。強制的にコンパイルする方法もありますが、基本的には2017以降を使用する方がよいでしょう。



# 使用するC++バージョンを設定する

Visual Studio のバージョン次第ではC++のバージョンも最新のものを指定することができます。

先ほどの項目でVS2019を使用しているのであれば、C++の最新バージョン（現在だと20の一部サポート）を使用できるように変更することができます。

C++のバージョン指定は`プロジェクト名.Target.cs`でプロパティ`CppStandard`の変更の記述で行います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/36899/74c1e5ac-a64d-ed4f-81c2-1f8204d97936.png)



```c++
// Fill out your copyright notice in the Description page of Project Settings.

using UnrealBuildTool;
using System.Collections.Generic;

public class TEATarget : TargetRules
{
	public TEATarget(TargetInfo Target) : base(Target)
	{
		Type = TargetType.Game;
        
		ExtraModuleNames.AddRange( new string[] { "TEA" } );
 
        // 14ならCppStandardVersion.14;
        // 17ならCppStandardVersion.17;
        CppStandard = CppStandardVersion.Latest;
	}
}
```



# 参考

- [Unreal Engine 4.22 がリリースされました！]( https://www.unrealengine.com/ja/blog/unreal-engine-4-22-released )
AmazonインセンティブAPI実装(Amazonギフト券/giftcode)

#経緯
Amazonギフトカード実装をお願いされ、気軽にokを出したものの、概要がとってもわかりずらく、かつ参考文献が全くなく、意外と四苦八苦したので、同じ悩みの方が出ないように投稿する事にしました。
なお、事前に用意されたphpのサンプルコードからLaravelに実装し直す、という流れが一番良いと思いますが、あまりにも面倒だったのと時間との勝負だった為、決してベストプラクティスでないことはご了承ください。。

#本題
####登録→確認方法
基本的には導入マニュアルがあるので、これに沿って開発をしていきます。
[AmazonインセンティブAPIとの統合プロセスについて](https://s3-us-west-2.amazonaws.com/incentives-api-setup/index-JP.html#)
登録した後、[サンドボックス環境](https://s3.amazonaws.com/AGCOD/htmlSDKv2/htmlSDKv2_NAEUFE/index.html)で正常に動作するか確認

####サンプルコード参照
[FAQ付録](http://s3.amazonaws.com/AGCOD/tech_spec/AGCODTechSpec_WC_Simplified_JP.pdf)にサンドボックス環境のサンプルコードがあります。
今回はphp/Laravelで実装予定だったので、ここのphpのサンプルコードを読み、`htmlSDKv2_php_cr⁩/htmlSDKv2_php/rollups⁩/function.php`にキー発行実装があります。

####実装方法
1. fuciton.phpのみ取り出し、app/Library配下に設置
2. controllerからのinvokeRequest を指定
3. Laravel実装の為、globalで引っ張ってきてるところをconfigにまとめ、アクセスキー等は.envに設定
4. 実装完了。。。。

注意点としては、サンドボックス環境とプロダクション環境の２つともアクセスキーを発行しなければいけません。

####余談(メイン)
今回は、jsonで返したので、XML2Array.phpは使用していません。
今回の僕の実装の流れとしては、
登録した後、サンドボックス環境でidが合っているか確認するところまでは順調でした。
ただresponseを叩いた時に、雲行きが怪しくなりました。responseの情報以外に沢山の情報があり、気づいてしまったんです。

あれ、、？？？これ、、、、api叩くだけじゃダメじゃね、、、？

そうです。僕は必要なrequestを提げて、apiを叩けばそれで実装が完了すると思っていました。
そんな甘い世界ではありません。このapiではSignatureキーを採用しているので、あちらで発行するキーと同じ発行をしなければなりませんでした。
その実装が[開発マニュアル](http://s3.amazonaws.com/AGCOD/tech_spec/AGCODTechSpec_WC_Simplified_JP.pdf)に書いてあるのかと思いきや、そのような実装は見つからずましてや必要なrequestすら曖昧すぎてよくわからなかったです。泣きそうでした。

そんな泣きそうな中、[FAQ付録](http://s3.amazonaws.com/AGCOD/tech_spec/AGCODTechSpec_WC_Simplified_JP.pdf)にサンドボックス環境においてのサンプルコードを見つけ、phpのサンプルコードの`htmlSDKv2_php_cr⁩/htmlSDKv2_php/rollups⁩/function.php`にたどり着きました。。


実装する人は少ないと思いますが、今後同じように実装する人を救えますように。。
React-Native 始める (Hello World)

こんにちは！
javascript言語でiOSとアンドロイドアプリを作れるようにすることに興味を持つようになりました。

#ReactNativeとは
react-nativeはfacebookで公開したiOSとアンドロイドアプリ開発のためのライブラリです。

*ReactiveとReactどちらで合いますか?*
多くの人がReactiveとReactが何なのか混同します。 
名前が似ていて混乱することがあります。 
しかし、この二人はジャワとジャバスクリプトだけ名称が似ている、実際にはとても違った技術です。

- Reactは<br>FacebookがWEB開発を容易にするために作った技術です。<br>カスタムコンポーネントを作り、容易に組み合わせてビューを簡単に作ることができます。
- Reactiveは<br>ストリームと非同期処理などをLINQに影響を受けた方法でキレイに処理できるようにしたパラダイムです。
- Reactnativeは<br>Reactiveのアプローチをモバイルに拡張するフェイスブックのオープンソースプロジェクトです。

#ReactNative使用理由
ReactNativeは、javascriptを知っていれば、早く基本的なアプリを作ることができるというはっきりしたメリットがあります。 
反面、nativeで直接開発した割には、新しい技術に遅れをとっており、プラットフォームごとの特性の機能を積極的に活用しようとするときに不利で、性能上のデメリットが存在します。
多くの短所にもかかわらず生産性が良いため、ReactNativeが多く注目されると思います

#開発環境設定
ReactNativeはできればMacで開発した方が良い。 理由はウィンドウの場合、iOSを直接ビルドすることができず、開発結果をすぐに確認することがむずかしいです
1. node.js install
https://nodejs.org/
LTSバージョンのnodeをインストールします。
2. expo-cli 
`npm install -g expo-cli`
expo-cliを利用すれば簡単にプロジェクトを生成してすぐに開発することができます
3. xcode とandroidがインストール
4. 環境変数や個人の環境に合わせて設定
5. 確認

```
node --version
pod --version
java --version
javac -version
adb
```
↑ コマンドをターミナルに入力した時、バージョンが表示されれば完了したものである。

#プロジェクト生成
環境設定がうまく行ったら、プロジェクトを生成して実際にコードを確認してみます。
`react-native init Hello`
↑ コマンドを入力すると、プロジェクトフォルダが作られる。 
app.jsファイルには実際表示される基本的な画面が作成されているのに不必要な内容を取り除いてくれてhelloというテキストを表示するように変えました。

```
import React from 'react';
import {
  SafeAreaView,
  View,
  Text,
  StatusBar,
} from 'react-native';

import {
  DebugInstructions,
  ReloadInstructions,
} from 'react-native/Libraries/NewAppScreen';

const App: () => React$Node = () => {
  return (
    <>
      <StatusBar barStyle="dark-content" />
      <SafeAreaView>
        <View>
          <Text>hello</Text>
        </View>
      </SafeAreaView>
    </>
  );
};

export default App;
```
生成が完了すると、↓のコマンドを使ってシミュレータを実行すると、helloが出力されます。

```
cd Hello
// iOS 実行
npm run ios
// android 実行
npm run android
```

#参考
react-nativeの説明書を見て提供されるコンポーネントとapi、javascript、reactの基本知識を活用すればモバイルアプリを作っていける。
https://facebook.github.io/react-native/docs/activityindicator
【シェル芸】3の倍数と3が付く数字のときだけアホになる

###【概要】
1～40までの数字に対して、3の倍数と3が付く数字のときだけ"アホ"という文字列を出力します。
それ以外は、数字を出力します。
`awk`で正規表現`/3/`を使用しているところがポイントです。
※40よりも大きい数字でも実行可能です。

###【環境】
```sh
[vagrant@vagrant-centos65 ~]$ cat /etc/redhat-release 
CentOS release 6.5 (Final)
```

###【コード】

```sh
for i in `seq 40`; do echo $i | awk '{ if ($0 ~ /3/ || $0 % 3 == 0) print "アホ"; else print }'; done
```

###【実行結果】

```sh
[vagrant@vagrant-centos65 ~]$ for i in `seq 40`; do echo $i | awk '{ if ($0 ~ /3/ || $0 % 3 == 0) print "アホ"; else print }'; done
1
2
アホ
4
5
アホ
7
8
アホ
10
11
アホ
アホ
14
アホ
16
17
アホ
19
20
アホ
22
アホ
アホ
25
26
アホ
28
29
アホ
アホ
アホ
アホ
アホ
アホ
アホ
アホ
アホ
アホ
40
[vagrant@vagrant-centos65 ~]$ 
```
Yahoo! Hack Day 2019に参加してきた

こんにちは。N高代々木1年、Nepps代々木校講師の髙津です。
皆さんの記事のレベルが高くてこの記事を書くのが少し恥ずかしいですが、先日行われた
#####Yahoo! Hack Day 2019 
に参加してプログラミングをしてきたのでそれについて書いていこうと思います。

##Hack Dayについて
Yahoo!が開催してるハッカソンで、24時間でプロトタイプを作って90秒でプレゼンをする日本最大級のハッカソンイベントです。
詳しくは https://hackday.jp/ をみてみてください。

##作ったもの

職場、学校でラーメンを食べたいというメンバー全員の共通の願いから
####人工知能でユーザーのツイートを学習し、オススメのラーメンを提供する
####ツイートを学習し、食べログを使って近くのオススメのラーメン店をSlackに投稿する

という今すぐに食べたいというニーズと後で店で食べたいという両方のニーズに答えることの出来るプロダクトを作りました。
###名前はRasshai!です。

![IMG_0658.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/526861/7248dde1-9cdc-21de-3613-02002dc82095.jpeg)


この動画をみていただきたいのですが、僕は動画に写っていない食べログの実装とSlackBotを作っていました。あとはiPadで操作するUIはXcodeを使ってちょっちょっと実装しました。シリアル通信とか人工知能とかメインの機能に全く携われませんでしたが、頑張ってコードを書いていました。

https://www.youtube.com/watch?v=HNjXZwRTybU 
これの1時間22分50秒くらいをみてください
白い服でニヤニヤしながら立ってるだけのやつが自分です。

AIとプレゼンでの寸劇はN高のネプソン君 https://qiita.com/kou_nepson
がやってくれています。
残りのハードウェア面とプレゼンターは千葉工業大学の友人がやってくれました。

###RaMyon
これは今すぐにラーメンを食べたい人向けのプロダクトで、主にオフィスや学校に置くことを前提に作りました。AIが学習したツイートのデータから好みのと判断されるカップラーメンを出してくれます。
ちなみにカップ麺を押し出す機構はミニ四駆でできています。

![PC150042.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/526861/a8aa4d6a-20f4-dcc3-254e-a748c31980a3.jpeg)

このミニ四駆というのが会場で少しウケたらしく、公式のTwitterで拾っていただいたり、展示でも何人かに声をかけていただけました。
<img width="598" alt="スクリーンショット 2019-12-15 21.07.17.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/526861/a4657830-13bc-5f54-5473-73457c67e65f.png">
これにはチームメンバー全員興奮していました。

##最後に
めちゃくちゃ突貫工事で作ったので突っ込みどころしか出てこないので、ここらへんでまとめに入ろうと思います。
初めてハッカソンに出場したのですが、通学コース生にはおなじみのプロNを24時間でブレストからプロトタイプ作成をしてプレゼンするようなもので、かなり過酷でした🥺
そして開始8時間くらいで技術力の壁にぶつかってしまい開発が滞ってしまったので短期かつチームでプロジェクトを作る中で少し迷惑をかけてしまったのかなと思いました。ですがなんとかリカバリーしてしっかりと作品にすることができたのでよかったです。
今回最大の学びは
#####自分の技術力の低さをしっかりと知ることができたこと 
だと思っています。
そして寝れないのがとても辛いです。しっかり寝て開発をした方が能率がいいのは言わずともわかるので、皆さんはちゃんと寝て開発しましょう。
当日の賞が取れなかったのでBuzz賞を狙う予定です。
バズらせるために河野太郎さんを学習させたので是非本人に反応して欲しいと思います()
ちなみに河野さんの好みのカップラーメンはカレー味だそうです()

#####きっと来年も参加するのでもっともっともっと技術力を付けて再チャレンジしようと思います

そしてこのハッカソンの感想を一言でまとめると「プログラミング楽しい！！！」に尽きます。
こんな内容スッカスカの記事を最後まで読んでいただいでありがとうございます。めっちゃ楽しいし勉強にもなるし絶望を経験できるので皆さんも是非ハッカソン行ってみてください。
一年間毎日一時間、メンバーに時間と場を配り続けた結果何が起こったのか？

本記事は[ドワンゴ Advent Calendar 2019](https://qiita.com/advent-calendar/2019/dwango)の16日目の記事です。

# はじめに

2016年から毎年、Redis Cluster的なお話をしていました。

 - [プロダクションで2年間Redis Clusterを運用してみて \- Qiita](https://qiita.com/maruloop/items/18932dfc4be8778434d2)
 - [プロダクションでRedis Clusterを3年間運用し続けた所感 \- Qiita](https://qiita.com/maruloop/items/a67b62d2a6a239c8fb67)
 - [production環境で41個のRedis Clusterを4年間運用してみて \- Qiita](https://qiita.com/maruloop/items/f7dcb89af1583dbab852) 

現在も主にドワンゴの開発者向けに

 - Redisを合計688インスタンス提供(運用)していたり
 - MySQLを合計422インスタンス提供(運用)していたり
 - 今年からElasticsearchを45インスタンス提供(運用)し始めたり

とPrivate CloudのManaged DataStore系サービスを続けています。

上記の開発・運用をチームで行うためのマネジメントで上手くいっているものを紹介します。

# ジリ貧を回避する習慣を作る

### マネージャーとしての私が非常に恐れていること

チームとして絶対に避けないといけない状況、それは「ジリ貧」だと考えています。
「ジリ貧」とは、特に定常的に発生する日々の保守・運用作業に手をとられ、学習および改善のための開発に手を割けない状態を指しています。
GoogleのSRE本の言葉で表現すると、『toil(労苦)』で体力/気力/時間が慢性的に不足し、自発的にその状況を抜け出せない状態でしょうか。

### やったこと

毎日夕方※に一時間の会議室を確保し、各々が好きな開発や学習を行えるもくもく会※(場と時間)を作る。

※ドワンゴ標準時における夕方のため18時からです。
※厳密な意味でのもくもく会ではありませんが、似ているのでそう呼んでいます

#### 毎日一時間のもくもく会のルール

 1. やってはいけないこと
    1. SlackやJIRAなどの各種問い合わせ対応
    2. 定常的な保守作業
 2. 推奨されていること
    3. 調べ物・学習
    4. 効率化のための開発や検証(タスクチケット化されてなくても良い)
    5. アサインされた定常的な保守以外のタスクチケット
 3. 入退室自由、参加自由
 4. タスクをやる前に、ホワイトボードにやることを書く
 5. 会終了後、ホワイトボードの写真を取り、slackに流して記録する

### やってみた効果

#### 普段のタスクへの悪い影響：なし
自由意志での参加のため、一日すら惜しいレベルの忙しい日はそもそも参加しなくて良く、
また、もくもく会ではアサインされた開発系のタスクも行って良いため、
この会が原因で遅れることはありません。

このため、この会は部長や本部長から理解されており、タスクやロードマップの優先度調整とは無縁で実施できています。

#### 突然ペアプロが始まる
普段の席では、個々人の席がパーティションで軽く区切られており、
また人によっては会議で席にいない時間があったり、席が遠いこともあります。

しかし、もくもく会では1時間のまとまった時間がお互いあり、パーティションのない場が提供されることで
「今少し教えてもらいたい」と思ったときのハードルが非常に下がるようです。
2-3分程度のペアプロや会話しながらの作業が増えました。

※常にパーティションがない場に拘束されると気が散るので、「この1時間だけ」という制限が良いようです

#### 突然運用改善のブレスト会が始まる

「ここの運用少し重いんですよね」→「じゃあ今日のもくもく会でブレストしてみますか」みたいな流れが多く、
またもくもく会は複数の別チームも同席しているため、他チームのナレッジを教えあったり。
※「もくもく会」というネーミングとは逸脱していますが...

#### 外部の勉強会へ参加するメンバーが増える・頻度が増える

元々ドワンゴは勉強会参加のために職場を抜けることには寛容ですが、
組織・チームとして、学習に積極的な姿勢を示せているからか、勉強会に参加する人が増えました。
また、今までサイレントで参加していた方(それで問題なし)も、可視化されました。

「外部勉強会参加」→「翌週のもくもく会で周りに報告や議論」といった良いループも発生しています。

#### 誰が何に興味を持っているか可視化できる

今の業務に直接関係ないOSSを数種類検証し始めたり、技術選定の勘所を文書化したり、
会計に関する本を読み始めたりといった、各個人の興味が可視化される部分がありました。
最終的にslackに記録されているので、あとから遡ることも容易で、
実際に業務に必要になった人が、もくもく会で自己学習していた人に質問しにいく、といったことも発生しています。

#### ラフなコミュニケーションの場

しばらく黙々と作業とした後、そのまま会議室に残って雑談が始まることもままあります。
あるシステムの歴史的経緯・負債についての話だったり、会社の規則の話だったり、様々です。

#### モチベーションコントロール

周りが自己成長のための投資をしていると、ちょっとだけ感化されて自分も成長しないとな。となる気がします。


## 欠点

オフィスの限られた資産である会議室を毎日1時間消費する点は無視できません。
会議が少ない時間やコワーキングスペースを利用するなど、改善の余地は大いにあります。

また、なるべく一人で集中して作業したい人にはノイズが増えるため、向き不向きがあります。

# まとめ

ジリ貧を回避するために、上記に記載したようなもくもく会を一年ほど継続しました。
当初は5-7名ほどを誘ってやっていましたが、今はメンバーは16名に増えました。
※実際の参加者数は、そのときどきによります

マネージャーとしては、会議室以外はほぼノーコストで継続実施でき
チームビルディングの雑談や成長や興味を可視化できる点で非常に重宝しています。

特に最近はテレワークでの業務も増えたので、ちょっとした雑談をする場・時間があるやりやすさは助かっています。
docker勉強 その①

# dockerの基本的なコマンドを覚える
dockerでubuntu18.04を構築して基本的なコマンドを覚える

# dockerイメージを取得
ubuntu18.04のイメージを取得する。

```sh
$ docker pull ubuntu:18.04
18.04: Pulling from library/ubuntu
7ddbc47eeb70: Pull complete
c1bbdc448b72: Pull complete
8c3b70e39044: Pull complete
45d437916d57: Pull complete
Digest: sha256:6e9f67fa63b0323e9a1e587fd71c561ba48a034504fb804fd26fd8800039835d
Status: Downloaded newer image for ubuntu:18.04
docker.io/library/ubuntu:18.04
```

# dockerイメージの確認

先ほど取得したubuntu18.04のイメージがあるか確認する。

```sh
$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
ubuntu              18.04               775349758637        6 weeks ago         64.2MB
```

# dockerイメージからコンテナを起動する

```sh
$ docker run -it -d --name ubuntu18-04 ubuntu:18.04
8389c53ba63b5c1a45ca256a6ec91cce6f1c3b889f12f1c4a6f64289b612ffea
```

## option

- ` -it:コンテナのプロセスにttyを割り当てる。（標準入出力の割り当て）`
- ` -d:コンテナをバックグラウンドで起動する`
- ` --name:コンテナに指定した名前をつける`


# コンテナの起動確認

```sh
$ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
8389c53ba63b        ubuntu:18.04        "/bin/bash"         8 seconds ago       Up 6 seconds                            ubuntu18-04
```

# dockerのubuntu18.04にアクセス

```sh
$ docker exec -it ubuntu18-04 /bin/bash
root@8389c53ba63b:/#
```

これでdockerのubuntu18.04で色々と操作ができる。`exit`で抜けれる。

# コンテナの停止
ubuntu18.04を停止する。

```sh
$ $ docker stop ubuntu18-04
ubuntu18-04
```

停止しているか確認する。

```sh
$ docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                      PORTS               NAMES
8389c53ba63b        ubuntu:18.04        "/bin/bash"         2 minutes ago       Exited (0) 40 seconds ago                       ubuntu18-04
```

停止したコンテナを再度起動する。

```sh
$ docker start ubuntu18-04
ubuntu18-04
```

# コンテナの削除

ubuntu18.04を削除する。

```sh
$ docker rm ubuntu18-04
ubuntu18-04

$ docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
```

# dockerイメージの削除

ubuntu18.04のイメージを削除する。

```sh
$ docker rmi ubuntu:18.04
Untagged: ubuntu:18.04
Untagged: ubuntu@sha256:6e9f67fa63b0323e9a1e587fd71c561ba48a034504fb804fd26fd8800039835d
Deleted: sha256:775349758637aff77bf85e2ff0597e86e3e859183ef0baba8b3e8fc8d3cba51c
Deleted: sha256:4fc26b0b0c6903db3b4fe96856034a1bd9411ed963a96c1bc8f03f18ee92ac2a
Deleted: sha256:b53837dafdd21f67e607ae642ce49d326b0c30b39734b6710c682a50a9f932bf
Deleted: sha256:565879c6effe6a013e0b2e492f182b40049f1c083fc582ef61e49a98dca23f7e
Deleted: sha256:cc967c529ced563b7746b663d98248bc571afdb3c012019d7f54d6c092793b8b

$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
```

これで基本的なdockerのコマンドは覚えれたと思います。
次はdocker-composeやdockerでwebサーバーを構築し、ポートフォワーディングの設定などやろうと思います。
k8sのログ取りについて

# 初めに
最近業務で触り始めたので、備忘録として簡単にまとめる程度として記載します。ちらっと調べている範囲でもより取り方を見かけるので、そちらの技術を用いる方がいいのかもしれません。

# kubectl logs [podname]
podで標準出力されているログを確認する。オプションに`--since [n]s`でコマンド実行からn秒前のログを表示できる。`s`ではなく`m`にすると分単位になる。`-f`で`tail -f`のようにリアルタイムに表示してくれる。podが死ぬと表示も止まり、通常のコンソール状態になる。

# kubectl describe pod [podname]
これで実際にpod起動時のコマンドや、ホストと共有しているディレクトリの情報、podのステータスが`pending`で止まっているときの理由が表示されたりする。

# 終わり
触り始めたばかりですが、これである程度の情報が集められるのでおうちクラスタ組んだりする程度で実サービスをデプロイするとかでなければイケるかもです。もし「こんな便利コマンドあるよ！！」とかございましたらコメントいただけると嬉しいです。
Goで経過時間を計算するパッケージを作った

# 動機

年月を計算する処理がなかったから。

> X は Y から A 年 B ヶ月 C 日 D 時間 F 分 E 秒 経過しています

というのをやろうとすると、

> C 日 D 時間 F 分 E 秒

はタイムスタンプの差から計算することができますが、それ以降はうるう年などの関係から単純に計算することができません

# 作ったもの

https://github.com/usk81/tiff

## 使い方

```go
d := New(time.Date(2000, 1, 1, 0, 0, 0, 0, time.Local), time.Date(2001, 12, 10, 11, 10, 20, 0, time.Local))

// 時間差の取得
years, months, days, hours, mins, sec := d.Term()
// years:  1
// months: 11
// days:   9
// hours:  11
// mins:   10
// sec:    20

// 年単位で計算で経過時間を計測
years = d.Years()
// 1

// 月単位で計算で経過時間を計測
months = d.Months()
// 23

// 日単位で計算で経過時間を計測
days = d.Days()
// 709

// 時間単位で計算で経過時間を計測
hours = d.Hours()
// 17027

// 分単位で計算で経過時間を計測
mins = d.Minutes()
// 1021630

// 秒単位で計算で経過時間を計測
sec = d.Seconds()
// 61297820
```
Docker上でDjango開発準備

# 目的
Dangoの開発を開始するにあたり、Docker上での開発環境を作成します。
公式のDjango Tutorialの1つ目の完了までを目標とします。

# 開発環境構築
DjangoのDocker環境を構築します。

## Docker file作成
現時点のPythonの最新は3.8ですので、それをベースに作成します。

``` dockerfile
FROM python:3.8
# Python 標準入出力バッファーを無効（反応速度優先のため。性能は下がる。）
ENV PYTHONUNBUFFERED 1
#
# オススメのパッケージは入れない.最小限とする.　--no-install-recommends
# DBを変更する場合は postgresql-client等を追加.
RUN apt-get update \
    && apt-get install -y --no-install-recommends \
    && rm -rf /var/lib/apt/lists/*

WORKDIR /usr/src/app
COPY requirements.txt ./
RUN pip install -r requirements.txt
COPY . .

EXPOSE 8000
# 開発完了したら、以下を有効にする.
# CMD ["python", "manage.py", "runserver", "0.0.0.0:8000"]
```

## Python追加パッケージの設定
requirements.txtにPythonのパッケージを記述します。

``` requirements.txt
django
```


## イメージ作成
イメージ名「django」でイメージをビルドします。

``` docker_build
docker build -t django .
```

## bash 起動
開発を行うため、bash起動します。

``` docker_run
$ docker run -p 127.0.0.1:8000:8000 -it django bash
```

# Django開発
以下のURLを参考にしてアプリを作成します。
[Django ドキュメント](https://docs.djangoproject.com/ja/3.0/)

## djangoアプリ作成
### サンプル作成
確認のためにサンプルを作成します。

``` startproject
$ django-admin startproject sampleapp
```
## サンプル起動
動作確認のため、一旦起動してみます。

``` startproject
$ python manage.py runserver 0:8000
```
HOST側からアクセスするため、「runserver 8000」ではなく「runserver 0:8000」で起動します。
確認したら、Ctrl+Cで終了します。

## チュートリアルで確認

チュートリアルでサンプルアプリを作成します。詳細は以下のURLを参照します。
[はじめての Django アプリ作成、その 1](https://docs.djangoproject.com/ja/3.0/intro/tutorial01/)

以下のURLにアクセスし、表示されることを確認します。

``` polls
http://127.0.0.1:8000/polls/
```

docker環境でdjango開発の準備はできた。
スマホでデバイス方向を検知して振動させるだけのクソアプリ

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

# はじめに
HTML5を使った3分で作れるクソアプリシリーズ。

Webブラウザから取れる情報ってめちゃくそあるんやで!!

# デモページ(スマホで開いてね)
AndroidのChromeでの動作は確認しているよ

https://tomowarkar.github.io/blog_content/motion/mobile.html
# コード
デバイスの方向(加速度)を取得して閾値を超えたらバイブレーションをさせるってだけ。

改良すれば振ったか振ってないかの判定もできました(判定ガバガバだったけど)

```html
<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8" />
  <meta name="viewport" content="initial-scale=1.0" />
  <title></title>

  <script>
    window.addEventListener("devicemotion", e => {
      x = e.accelerationIncludingGravity.x;
      y = e.accelerationIncludingGravity.y;
      z = e.accelerationIncludingGravity.z;
      
      if (z > 9) {
        navigator.vibrate(30);
      } 

      let result = document.getElementById("result");
      result.innerHTML =
        "X：" + Math.round(x * 10) / 10 + "<br>" +
        "Y：" + Math.round(y * 10) / 10 + "<br>" +
        "Z：" + Math.round(z * 10) / 10 + "<br>"
    }, true);
  </script>
</head>

<body>
  <div id="result">vibration</div>
</body>

</html>
```
# おわりに
以上明日も頑張ります！！
[tomowarkar ひとりAdvent Calendar Advent Calendar 2019](https://qiita.com/advent-calendar/2019/tomowarkar)
# 参考
[Vibration API](https://developer.mozilla.org/ja/docs/Web/Guide/API/Vibration)
[デバイスの方向の検出](https://developer.mozilla.org/ja/docs/Web/API/Detecting_device_orientation)
BOSCH XDK110でボタンを押すとLEDが光るサンプルを動かしてみた

## はじめに
本ドキュメントは、自分が BOSCH XDK110のサンプルを動かした時の備忘録です。
まだ使い始めたばかりで公式ドキュメントを読み込めておりませんが、出来る所からやってみました。

## BOSCH XDK110とは？
Bosch社が開発したIoT向けの開発キットです。
加速度計、ジャイロスコープ、湿度、磁力計、圧力、温度のセンサと無線LAN、リチウムイオン電池を備えた筐体です。

## 実際に動かしてみる

### BOSCH XDK WorkBenchをPCへインストール

以下のページから、自身の開発環境に合わせてダウンロードします。
説明ドキュメントも同じページよりダウンロード可能です。
https://www.bosch-connectivity.com/products/cross-domain/cross-domain-developement-kit/downloads/
ダウンロードしたファイルを解凍し、XDK用の開発環境：XDK Workbenchをインストールします。

### BOSCH XDK WorkBenchを起動

インスールしたXDK WorkBenchのアイコンから起動します。

###サンプルコードを読み込む
1枚目の画像において、XDK-Examplesから動かしたいサンプルのボタンを押下すると、サンプルコードを読み込みます。
読み込んだサンプルコードの表示は2枚目の画像の通りになります。

<img width="1792" alt="WorkBench起動画面.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149203/8f36c910-ec9c-0857-ad65-5144aca4fe51.png">

<img width="1792" alt="WorkBench作業画面.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149203/1b13d954-2cfe-6eeb-e512-26afe8004dfd.png">

### BOSCH XDKを接続する
PCとXDK110をUSBケーブルで接続し、XDK110のスイッチをOnにします。
XDK110のスイッチはUSBケーブル接続側にあります。
接続がうまくいけば、WorkBench画面のComが緑色になります。
電源OFF時、未接続時は灰色です。

### XDKでサンプルを実行可能な状態にする
Flashボタンを押下してXDK110へサンプルをクロスコンパイルします。
Flashが成功すれば、サンプルがXDK110で動作する状態になります。

### BOSCH XDKでサンプルを動かす
クロスコンパイル成功後、Boot（またはReboot）でサンプルが動作します。
LedsAndButtonsのサンプルの場合、ボタン1を押すとオレンジ色（１番左を緑とした場合右から２番目）LEDが光ります。
ボタン２を押すと黄色（同左から２番目）LEDが光る。ボタン押下中は赤（一番右）LEDが光ります。

### 今後の予定
1. 他のサンプルを動かす
2. サンプルを参考に、各センサデータを取得するコードを作成
3. 取得したデータの可視化
bashとcurlで実現する初めてのdotfiles

自分のdotfilesをちゃんと整理したいと思っていて、この週末にやっと作業したので、共有したいと思います。

## 下調べ

世の中には、どんなdotfiles管理手法があるのかあるのか調べました。
pythonスクリプトやrubyなど、言語も様々で、
リンクするか、コピーするか等、ファイルの配置方法も色々あることがわかりました。

私としては、最小構成のサーバーに対しても、すぐにdotfilesを展開できるような仕組みを作りたかったので、以下の方針で自分のdotfilesを整備することを考えました。

## 方針

- できるだけシンプルな構成にする
- bashだけでできる

## 参考にした記事、レポジトリ

以下の記事が共感でき、一番参考になりました。

- [最強の dotfiles 駆動開発と GitHub で管理する運用方法 - Qiita](https://qiita.com/b4b4r07/items/b70178e021bef12cd4a2#%E3%83%AF%E3%83%B3%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89%E3%81%A7%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E3%81%A7%E3%81%8D%E3%82%8B)
  - [GitHub - b4b4r07/dotfiles: A repository that gathered files starting with dot](https://github.com/b4b4r07/dotfiles)
- [ようこそdotfilesの世界へ - Qiita](https://qiita.com/yutakatay/items/c6c7584d9795799ee164)
  - [GitHub - yutakatay/dotfiles-mini](https://github.com/yutakatay/dotfiles-mini)

## 作業

- b4b4r07さんとyutalatayさんのinstallスクリプトを参考にして、以下の機能をもつスクリプトを作成しました
  - [dotfilesのダウンロード](https://github.com/hnishi/dotfiles/blob/master/scripts/download.sh)
  - [dotfilesのインストール](https://github.com/hnishi/dotfiles/blob/master/scripts/install.sh)
    - yutakatayさんのスクリプトを一点だけ修正したもの
    - macでは、readlink -f が使えなかったため、以下のように修正

```diff
--- a/yutakatay/dotfiles-mini/.bin/dotsinstall.sh
+++ b/hnishi/dotfiles/scripts/install.sh
@@ -19,7 +19,7 @@ link_to_homedir() {
   fi

   local script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
-  local dotdir=$(readlink -f ${script_dir}/..)
+  local dotdir=$(dirname ${script_dir})
   if [[ "$HOME" != "$dotdir" ]];then
     for f in $dotdir/.??*; do
       [[ `basename $f` == ".git" ]] && continue
```

- ワンラインのコマンド一発で、ダウンロードとインストールを行えるようにしました

```
curl -L raw.githubusercontent.com/hnishi/dotfiles/master/scripts/download.sh | bash
```

- scriptsというディレクトリ名は、私の好みでつけました
- できたdotfilesはこちら。
  - [GitHub - hnishi/dotfiles: hnishi's dotfiles](https://github.com/hnishi/dotfiles)
- bashとcurlがあればワンコマンドでinstallできるdotfilesが完成しました

## 今後の展望

- このdotfilesを充実 + 整理していきたい
- 以下を参考にgithub actionsでCIしたい
  - [ようこそdotfilesの世界へ - Qiita](https://qiita.com/yutakatay/items/c6c7584d9795799ee164#dotfiles%E3%81%A7%E3%82%82ci%E3%81%97%E3%81%A6%E3%81%BF%E3%82%88%E3%81%86)
SVMのプログラミング

# SVMのプログラミングをgoogle Colaboratoryで実行してみる。

SVMの勉強のため
https://datanerd.hateblo.jp/entry/2017/09/03/202738
の内容をgoogle Colaboratoryで実行してみた。

以下、実行上のメモ：

- import mglearnでエラーが出たので
!pip install mglearnをはじめに追加した。

- make_blobsの使い方は
https://qiita.com/fujin/items/bb82d77b0b08c107f819
に記載されている。
centersはデータの塊の数を設定する。
random_stateは乱数生成のシードとなる整数を設定する。
他にもn_samplesによってデータ数を設定できる。

- LinearSVC().fit(X, y)：　(X, y)をLinearSVCでフィッティングする。
- plot_2d_separator：　二次元で境界線を作って作画してくれる。

- discrete_scatter：　
第３引数に各データに対するラベルを指定することにより、そのラベルに応じてMarkerの種類や色を変えて散布図を描写をしてくれるメソッド。
第１引数： 散布図に描写する各データのX値
第２引数： 散布図に描写する各データのY値
第３引数： 散布図に描写する各データのLABEL

- yを表示すると以下のようになっている
[3 2 1 3 3 0 2 1 3 3 0 0 3 1 1 2 2 3 3 0 0 1 0 0 3 0 0 3 2 1 1 3 1 3 0 2 3
 0 1 2 1 3 2 2 0 2 1 0 1 1 1 2 0 0 3 2 2 2 0 3 3 2 1 2 0 1 3 1 0 0 1 2 0 1
 0 0 3 2 3 1 2 0 3 2 3 2 0 2 2 3 1 0 3 2 2 1 1 3 1 1]
これがy = y % 2によって
[1 0 1 1 1 0 0 1 1 1 0 0 1 1 1 0 0 1 1 0 0 1 0 0 1 0 0 1 0 1 1 1 1 1 0 0 1
 0 1 0 1 1 0 0 0 0 1 0 1 1 1 0 0 0 1 0 0 0 0 1 1 0 1 0 0 1 1 1 0 0 1 0 0 1
 0 0 1 0 1 1 0 0 1 0 1 0 0 0 0 1 1 0 1 0 0 1 1 1 1 1]
と0と1にデータになる。
このyをdiscrete_scatterの第３引数に使用すると、２色のデータに分類できる。