OmniAICreator/Qiita-1.07M huggingface dataset:
Raspberry PiをDHCPサーバにしてローカルエリアネットワークを作る話

# はじめに
ZYBOやPYNQでPetaLinuxで作ったLinuxイメージを起動し，これにSSH経由で接続しようとすることはよくあることだと思います．
ところが，大体のイメージが固定IPを設定してくる割には大学のネットワークでは固定IPを設定できないばかりか，使おうとしてもブラウザを使った接続設定が必要なので現実的ではありません．そこで今回はRaspberry Piを使ってDHCPサーバを立て，ローカルエリアネットワークを作って開発をしてみたのでそのやり方をメモっておきます．

# TL;DR
- Raspberry PiのLinuxにisc-dhcp-serverをインストールする
- dhcpd.confのサブネットの設定を変える
- dhcpd.confに固定IPの割当設定を記述する

# Raspberry PiのLinuxにisc-dhcp-serverをインストールする
普通にaptでインストールします．
なお，Raspberry PiではRaspbianを使っています

```shell-session
$ sudo apt install isc-dhcp-server
```

この状態でisc-dhcp-serverを有効化して実行してみて動くかどうか確認します．

```shell-session
$ sudo systemctl enable isc-dhcp-server
$ sudo systemctl start isc-dhcp-server
```

# dhcpd.confのサブネットの設定を変える
PetaLinuxで作るイメージを自分で設定して作れる場合には何も考えずに自分のサブネット上で有効なIPアドレスをstatic ip addressで設定すれば良いですが，どこかから持ってきたイメージを使う場合には勝手に設定されているため，うまく動かないことがあります．
大抵は192.168.x.xに固定IPアドレスを設定していることが多いので，サブネットは192.168.0.1でネットマスクは255.255.0.0で作っておけば動きます．

```
subnet 192.168.0.1 netmask 255.255.0.0 {
       option broadcast-address    192.168.0.255;
       option subnet-mask          255.255.0.0;
       option routers              192.168.0.1;
       range                       192.168.0.1 192.168.255.255;
}
```

これでisc-dhcp-serverを再起動してみます．

```shell-session
$ sudo systemctl restart isc-dhcp-server
```

このときにtypoなどで設定が正しく行われていなかった場合は，`jurnalctl -xe`で最後の方のログを見るとたいていエラーログが吐かれていて，それを見ると何をどうすればよいのかわかる様になっているはずです．

# dhcpd.confに固定IPの割当設定を記述する
最後にFPGAボードに載せたLinuxのMacアドレスを使って固定IPを設定します．

以下に設定例を示します．

```
host [host-name] {
   hardware ethernet 00:00:00:00:00:00;
   fixed-address 192.168.1.1;
}
```

ここで，上に書いた`00:00:00:00:00:00`のところに設定したいMacアドレスを書きます．このMacアドレスは，`ip addr show`を使って`link/ether`のところを見ると調べることが可能です．または，PetaLinuxのビルド設定で指定することが可能です．

この状態で，dhcpサーバを再起動します．

```shell-session
$ sudo systemctl restart isc-dhcp-server
```

これでLinuxイメージでSSHサーバの設定が有効になっていれば接続できるようになっているはずです．

# 最後に
設定としては上述した通りのことをするだけですが，実際には繋がなければ接続はできません．

基本的には，スイッチングハブを使ってRaspberry PiとFPGAボードと作業したいPCをつなげる必要があります．
Optionalについて

##Optionalとは
nullがあってもいいやつ。以上。

##くわしく
モデルやオブジェクトといわれるようなものに関して、null怖い病あるじゃん
なので、KWSKというEntityクラスがあった場合
Optional<KWSK>というものにして、nullのハンドリングができるというわけです

##具体例
```Optional.java
package optional;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

public class Practice {

	public static void main(String[] args) {
		// Optionalの初期化
		Optional<String> empty = Optional.empty();
		// Optional<String>をStringにする (中身取り出す)
		String str = empty.get();
		// nullじゃなくて、ちゃんと値があるかどうか確かめる
		empty.isPresent(); // false

		System.out.println(run("a"));
		System.out.println(run2("a"));
	}

	/**
	 * 引数を返す<br>
	 * 引数がnullなら空文字を返す
	 * 
	 * @param str
	 * @return
	 */
	private static String run(String str) {
		return Optional.ofNullable(str).orElse("");
	}

	/**
	 * 引数を返す<br>
	 * 引数nullだとNoSuchElementExceptionが発生 (get()メソッドができないため)
	 * 
	 * @param str
	 * @return
	 */
	private static String run2(String str) {
		return Optional.of(str).get();
	}

	/**
	 * streamみたいにfilterやmapも使える
	 * ていうかstreamも使える
	 * 
	 * @param str
	 */
	private static void run3(String str) {
		Optional.ofNullable(str).filter(v -> v.length() == 1).isPresent();
		Optional.ofNullable(str).map(v -> v + "2").isPresent();

		List<Optional<String>> list = new ArrayList<Optional<String>>();
		list.add(Optional.of("a"));
		list.add(Optional.of("b"));
		list.add(Optional.of("c"));
		list.add(Optional.empty());

		list.stream().filter(Optional::isPresent).map(Optional::get).forEach(System.out::println);
	}

}

```
です。

##つまり何が便利？
コードにながくまとめてしまいましたが
つまり何かというと、nullに関するエキスパートです

何かモデルを扱うときに、nullどうするんろって思ったらとりあえずOptional思い浮かべてみてください

```.java
Optional.ofNullable(null判定したいやつ).orElse("");
```

Optional型から元に戻すときの`get()`メソッドで、気を付けないとNoSuchElementexceptionが出てしまいますが
そこさえ徹底すれば基本null怖い病を克服できるものです！

`isPresent`メソッドのbooleanでの条件分岐はstreamでのnullはじきに便利なので
findFirstなどのnullこわい系につけるだけであら簡単

```.java
Objects::nonNull
```
や

```.java
Objects::toString
```
でも対応できそうなものですが、Objects型って最終手段感ありますよね
特にOptionalの方がいい、などの詳しい理由はしらんけども
そんなことするまでもない的な感じなんですかね

[Optional公式リファレンス](https://docs.oracle.com/javase/jp/8/docs/api/java/util/Optional.html)
[Objects公式リファレンス](https://docs.oracle.com/javase/jp/8/docs/api/java/util/Objects.html)
cocos2d-HTML5で、LabelTTFを各文字バラバラに扱う

cocos2d-x、スーツ仕事の隙間で遊んでいるだけだし、なんだかんだ疑問が生じてライブラリソースの中を読んじゃうので、なかなか進まない。で、今回はLabelの話。

なお、バージョンは cocos2d-x v3.17.2。

# LabelTTF

LabelTTFって便利だけど、1文字ずつバラバラに扱いたいケースって結構ある気がする。ググったら、全部まとめてsetOpacity(0)にして、1文字ずつ透明度をいじくる方法が出てきた。それでもまあ良いけど、いずれ不満になるよね。だって、1文字ずつ現れる瞬間にすすすっとY軸方向にちょっぴり動きながら表示されるとか、昔のエロゲなんかでも割とあった気がするし、せっかくゲームエンジンを使っているんだから、その辺凝れるようにしておきたい。お遊びとしては、ちょっくら Quizlet みたいなのを作ってみようかと思っているので、そういうのがあると、問題文を見たときに目が滑らなくて済むからいいな、と思っているのです。エロゲのシステムじゃなくてごめん。

で、公式のhelloworldを弄ってみる。試しに、

```js
        /////////////////////////////
        // 3. add your codes below...
        // add a label shows "Hello World"
        // create and initialize a label
        var helloLabel;
        var text = "bunbuku chagama この道はいつか来た道…… Hello World";
        helloLabel = new cc.LabelTTF(text, "Arial", 38);
        helloLabel.x = size.width / 2;
        helloLabel.y = size.height / 2 + 200;
        var fullsize = helloLabel.getContentSize().width;
        this.addChild(helloLabel, 5);
        cc.log("fullsize: "+fullsize);

        var sumsize = 0;
        for(var i in text){
            helloLabel = new cc.LabelTTF(text[i], "Arial", 38);
            var chsize = helloLabel.getContentSize().width;
            helloLabel.x = size.width / 2 - fullsize / 2 + sumsize + chsize / 2;
            helloLabel.y = size.height / 2 + 280;
            sumsize += chsize;
            this.addChild(helloLabel, 5);
        }
        cc.log("sumsize: "+sumsize);
```

とやったら、見事にズレました。 cc.LabelTTF.getContentSize().width を足していくんじゃあ駄目みたい。表示結果を見てみると、カーニングが反映されてない。カーニングの仕組みを考えれば、そりゃそうだ。でも、やーん、ということで、ライブラリ内の CCLabelTTF.js をざっくり読んで「ずる」しないと無理だって判りました。 cc.LabelTTF._renderCmd._measure(str) で、実際上の文字送り幅がわかります。プライベート前提のメソッドを呼ぶのは嫌ですが、「別途隠しcanvasを作って測定するコードを書き起こす」のはもっと嫌です。だって、そんなことを始めたら、フォント指定文字列の解釈とかも含めて、ごっそり書き増しだよ。楽して遊ぼうと思ってCocos2d-xを使っているのに、それはない。

この cc.LabelTTF._renderCmd._measure(str) は、とても有用なので、ちゃんと公開メソッドにして欲しいもんです。誰かよさげな命名のメソッドでラップしてプルリクしてあげて。

ちなみに、LabelBMFontなら、自前で明示的にカーニング情報をセットするから好きなように扱えるけど、日本語で好き放題メッセージを出したいので、LabelBMFontを使おうとすると、なんか大掛かりなスプライトパッケージングツールを書かなきゃいけない羽目になる確信。それもない。

# これでうまくいく

というわけで、修正したコードが下記になる。試すときには、公式サンプルに埋め込んでね。

```js
        /////////////////////////////
        // 3. add your codes below...
        // add a label shows "Hello World"
        // create and initialize a label
        var helloLabel;
        var text = "bunbuku chagama この道はいつか来た道…… Hello World";
        helloLabel = new cc.LabelTTF(text, "Arial", 38);
        helloLabel.x = size.width / 2;
        helloLabel.y = size.height / 2 + 200;
        var fullsize = helloLabel.getContentSize().width;
        this.addChild(helloLabel, 5);
        cc.log("fullsize: "+fullsize);

        var sumsize = 0;
        for(var i in text){
            helloLabel = new cc.LabelTTF(text[i], "Arial", 38);
            var chsize = helloLabel.getContentSize().width;
            helloLabel.x = size.width / 2 - fullsize / 2 + sumsize + chsize / 2;
            helloLabel.y = size.height / 2 + 280;
            sumsize += helloLabel._renderCmd._measure(text[i]);
            this.addChild(helloLabel, 5);
        }
        cc.log("sumsize: "+sumsize);
```

以上。
もう「公開鍵送ってください」というやり取りは不要だった

# GitHubに登録している鍵ペアの公開鍵は公開されてる！

意外と知られていませんが、GitHubに登録した公開鍵は誰でもアクセス可能なんです。

ユーザーページのURLの末尾に「.keys」をつけるだけで、そのユーザーの登録済みSSH公開鍵を一覧で取得できます。

たとえば、GitHubアカウントが y-tsuzaki の場合：

```
https://github.com/y-tsuzaki.keys
```

このURLにアクセスすると、登録されている公開鍵の内容がテキストで表示されます。

![スクリーンショット 2019-09-30 12.29.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/268801/58ab1567-c931-06f3-e529-44ec463a231a.png)

# 🎉 もう「公開鍵送ってください」は不要！

これを知っていれば、GitHubユーザーにわざわざ「公開鍵送ってください」と依頼する必要はありません。
URLを見ればすぐに取得できるので、SSH接続の設定やユーザー追加もグッと楽になります。

ちょっとしたことですが、作業効率が一段アップするTIPSです。
これは捗りますね。


---

## 公開鍵を `authorized_keys` に設定する方法

GitHubの `.keys` URL を使えば、お使いのマシンへの公開鍵の設定も一瞬です。以下、2パターン紹介します。

### 公開鍵を追記する場合

※ 既存の `authorized_keys` を残したいときはこちら。

```bash
# curl の場合
(echo; curl https://github.com/XXXXXX.keys; echo) >> ~/.ssh/authorized_keys

# wget の場合
(echo; wget https://github.com/XXXXXX.keys -O -; echo) >> ~/.ssh/authorized_keys
```

※ 先頭と末尾の `echo` は改行を入れるためのもの。  
---

### 新しく作る場合

`authorized_keys` を新規作成して置き換える場合はこちら。

```bash
# curl の場合
curl https://github.com/XXXXXX.keys -o ~/.ssh/authorized_keys

# wget の場合
wget https://github.com/XXXXXX.keys -O ~/.ssh/authorized_keys
```

---

### パーミッションを設定

忘れずにアクセス権も整えておきましょう。

```bash
chmod 600 ~/.ssh/authorized_keys
```

> コメントで教えてくださった @grohiro さん @ktooi さん、ありがとうございます！


# 参考＆謝辞
- この方法は同僚(@yamotuki )に教えてもらいました。
- 以下のサイトを全面的に参考にさせていただいてます。
    - [id774.net GitHub に登録した SSH 公開鍵は全世界に公開されている](https://blog.id774.net/entry/2013/12/16/441/)

# 我々について

M&Aクラウドでは一緒に働く仲間を募集してます！
開発チームは、まだ小さなチームですが、日々試行錯誤しながら楽しく開発しています！
興味のある方は、こちらをご覧ください🤝

https://www.wantedly.com/companies/macloud/projects
Starshipのドキュメント翻訳を手伝った話

[🚀 プロンプトを超絶おしゃれにする Starship を紹介](https://qiita.com/unhappychoice/items/3b774310d95e2124eb77)

こちらの記事で流入が非常に増えていたStarshipの翻訳をチョコチョコ手伝ったので、その時の話を少し書いてみようと思います。
自分もまわりの人にちまちまとオススメしていたんですが、こうやって一気に人が増えると嬉しいですね！

# Starshipとは
先の記事でもすでに書かれているんですが、プロンプトに様々な情報を表示するものです。
最初はnodeやpythonなどのバージョンぐらいでしたが、今では現在時間やAWSのバージョンなどかなり表示するのが増えてるみたいです。

# 翻訳の話

## GitLocalize
最初は[Gitlocalize](https://gitlocalize.com/)を使いました。

機能的には以下の感じです。

- 左右分割の2ペイン表示
- レビュー機能
- 機械翻訳
- 翻訳サジェスト
- プロへの翻訳依頼

Gitlocalizeでも十分な機能だったのですが、emoji周りで以下の様に正しく編集できなくなる動作がありました。
![issue gif](https://user-images.githubusercontent.com/12455284/65120159-2b35bd80-da28-11e9-8016-f42dfced7617.gif)

[このPR](https://github.com/starship/starship/pull/390)で一度リセットしようと試したりされてもいましたが、結局は解決できず、別のローカライズサービスを使うことになりました。
この時点でほとんどローカライズが終わっていたので見た時結構つらかったです。

## Crowdin
最終的には[Crowdin](https://crowdin.com/)を使うことになりました。

機能的には以下の感じです。

- レビュー, 投票機能(stack overflowのような)
- 機械翻訳
- 翻訳サジェスト

また、Gitlocalizeと比較して以下の違いがあります。

- 左右分割ではない
- コメント機能がある
- 3ペインだが、翻訳後のドキュメント、原文と翻訳inputとサジェスト、コメントという分割。

エディタの見た目としては、GitLocalizeのほうが良い印象でした。(左右分割のペインが特に)
しかし、実際に翻訳作業をすると、Crowdinのほうが良かったです。
おそらく、「翻訳」という作業に必要なものが、一つのペインに集まっていることが大きいと思います。

CrowdinではGitlocalizeで起きたemoji周りの不具合も起きず、無事にローカライズが完了しました。
今後は、中国語やフランス語、ドイツ語などにもローカライズされていくそうです。

## ちょっとつらかった点
現在Starship自体が活発で、ドキュメントもどんどん更新されてました。
管理上の問題か、しょうがない点なのかは自分にはわからないですが、ドキュメントが更新されると翻訳済みの文章が原文に戻ってしまうという動作を何度か見かけました。
一度翻訳はしているので、サジェストからポチポチ選択していく程度で済むのですが、良いペースで更新されていくので果てしないいたちごっこのように思えてくることがありました。

# 終わりに
前述した通り、starshipは活発です。ですが、レビュアーの手が足りてないというのが現状な気がします。(相変わらずchipbusterがめちゃくちゃ頑張ってる)
シェル横断であったり、Rustだったりというのもあって考えることが多いプロダクトですので、大変だとは思います。
でも、見た目も中身もとても楽しいプロダクトですので、これからもやっていけたらと思います。
フィルターコンテキストを無視する方法（ALL関数の使い方）（PowerBI/PowerPivot/DAX）

PowerBI/PowerPivot（以下、総称してDAXと呼びます）におけるコンテキスト（行コンテキスト、フィルターコンテキスト）のネストについて[書きました。](https://qiita.com/zaboom/items/c5fc4eac121e2186e7c2)今回は、フィルターコンテキストを無視する方法（ALL関数の使い方）について少し書いてみます。

# 暗黙的なフィルターを意識する

次のようなメジャーを定義します。
[定価]列を評価し、1万円以上の定価を持つ商品数をカウントするメジャーです。

[1万円以上の商品数] =
    COUNTROWS(
        FILTER('商品',
            [定価] > 10000
            )
    )

![ALL2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/499774/ff593b77-1da8-6210-6223-a55a27c026f7.png)


この場合、メジャーはフィルターコンテキストで評価されるため、スライサーなどの選択によって、値は変化します。また、それぞれの商品カテゴリ別に、商品数がカウントされていることが分かります。（これは暗黙的にカテゴリ別フィルターがかかっているという捉え方ができます）

## ALL関数でフィルターコンテキストをクリアする

ここで、上記のメジャーを次のように変えてみます。

[1万円以上の商品数] =
    COUNTROWS(
        FILTER(ALL('商品'),
            [定価] > 10000
            )
    )

最初の式と変わっている点は、ALL('商品')となっているところです。ALL関数は、すべてのフィルターをクリアし、引数として指定された表全体もしくは列全体を返します。ここでは「商品」テーブル全体をフィルターを削除したうえで返しています。その結果、[1万円以上の商品数]は全て20となりました。

![ALL1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/499774/93907076-e1d3-2b74-7afd-ef91fb1b2901.png)


さきほど「暗黙的にカテゴリ別フィルターがかかっている」と書きました。この暗黙的にかかっているフィルターがクリアされ、全商品を評価対象とした数値=20が各行に挿入されています。

このように、ALL関数は、コンテキストのネスト状況に関わらず、全てのフィルターをクリアします。この原理を理解しておくと、ALL関数を使いこなせるようになるはずです。ALL関数によって、常にテーブル全体を評価するため、例えば常に合計値を表示する列やセルを作りたい場合などに便利です。個別値のとの比較用の列を作ったりする際にも使えます。

また、これらの動作は、フィルターコンテキストと行コンテキストの動作原理が分かっていると、よりスムーズに理解できると思います。このあたりもぜひ習得しておくことをおすすめします。
SPAはじめました

# はじめに
仕事でAngularを使ったSPAのフロントエンド側アプリの構築を行うことになりました。
私自身SPAやフロントエンド側の開発というものにこれまで馴染みがなかったので、調べたことについてアウトプットしたいと思います:writing_hand:
今回はSPAの概要についてが中心となります。
### 対象読者
- SPAについて馴染みがない方

# SPAとは
簡単にまとめると以下の通りです。

- シングルページアプリケーション(Single Page Application)の略称
- 単一のページ(HTML)で構成されるWebアプリケーションのアーキテクチャ名称
- クライアントにダウンロードされ、サーバと通信・画面制御を行うアプリ(フロントエンド)と、サーバで業務処理を行うRESTfulアプリ(バックエンド)で構成されることが主

### 単一のページで構成されるWebアプリケーション
個人的には最初ここがいまいち理解できませんでした...
画面遷移時の振る舞いについて考えてみると理解がしやすいです。
通常のWebアプリケーションとSPAで処理を比較すると以下のようになります。

■通常のWebアプリケーション
1. ユーザがボタンの押下等のアクションを実行
2. サーバにリクエストが送信される
3. サーバ側で業務処理を実行する
4. サーバ側でHTML全体を生成し、ブラウザに返却する
5. 返却されたHTMLが画面に表示される

■SPA
1. ユーザがボタンの押下等のアクションを実行
2. サーバにリクエストが送信される(フロントエンドアプリがバックエンドアプリのAPIを呼び出す)
3. バックエンドアプリが業務処理を実行する
4. バックエンドアプリがレスポンスを返却する(JSON形式等)
5.フロントエンドアプリがレスポンスを基に、HTMLの一部を編集する
(一部と言っているのはヘッダやフッダ等表示が固定の領域については編集する必要がないためです。)
6. 編集後のHTMLが画面に表示される

このように、SPAはHTML全体を置き換えるのではなく、表示中のHTMLの一部を編集することで画面遷移を実現します。
そのため、HTMLの数としては、編集する用の1つのHTMLがあればよいわけです。
それが、単一のページで構成されるWebアプリケーションという意味になります。

# SPAのメリット
SPAのメリットとしては以下の様な点が挙げられると思います。

- 高速でシームレスな画面遷移
- UIを豊かにできる

### 高速でシームレスな画面遷移
上述の通り、SPAはHTMLの一部を編集することで、画面遷移を実現します。
そのため、ブラウザリロードが発生せず、シームレスな画面切り替えが可能です。
実際使ってみても非常に快適なので、UXの向上につながると思います。

### UIを豊かにできる
ブラウザの挙動に縛られないため、より豊かなUI を実現することが可能となります。
(例えば、画面遷移時にアニメーションを追加したり、グラフィカルな表現等)
UIについてはAngularやReact等フレームワーク側で提供されているものも多く、利用のハードルも低いです。

# SPAのデメリット
反対にデメリットについて考えてみます。

- 開発者が少ない
- 開発コストの増大

### 開発者が少ない
通常のWebアプリケーション構築経験のある開発者数に比べると、SPAの構築経験のある開発者は多いとは言えないでしょう。
特に、フロントエンド側はJavaScript、またはTypeScript+FWで開発することになるので、そういった言語+FWを扱える開発者を揃える必要があります。

### 開発コストの増大
フロントエンド、バックエンド両方のアプリを作成する必要があるため、コード量やテストが増えたり、テスト環境準備のコストが増えることが想定されます。
また、フロントエンドアプリ、バックエンドアプリで開発チームまたはベンダーを分けることになると思いますが、API仕様の決定等の調整に時間がかかることも予想されます。

# まとめ
今回はSPAの概要について簡単にまとめてみました。
SPAに触れるのが初なので、認識誤り等あればコメントいただけると幸いです:bow:
今後は使用しているフロントエンドFW「Angular」のノウハウについて投稿していきたいと思っています！
Electronのプロセス間通信にredux-sagaを利用してみる

# はじめに
Electron+React+redux+redux-sagaを使用した構成でアプリケーションを開発する際に、Electronのプロセス間通信の制御にredux-sagaのchannelを導入してみたので、まとめてみました。
Electronやredux、redux-sagaの説明についてはここでは割愛します。

使用したバージョン
Electron: 3.0.5
redux: 4.0.1
redux-saga: 0.16.2

# Electronのプロセス間通信
ElectronではMainプロセスとRendererプロセスという2種類のプロセスが動いており、これらのプロセス間のやり取りは、それ用のオブジェクト(ipcMain、ipcRenderer)を用いて行います。詳しくは[公式のドキュメントを参照](https://electronjs.org/docs/tutorial/application-architecture#main-and-renderer-processes)。

今回はRendererプロセス内で、Mainプロセスからのメッセージを受け取る部分にredux-sagaのchannelを利用しました。

[redux-sagaの公式doc](https://redux-saga.js.org/docs/advanced/Channels.html)

# サンプルコード
以下がサンプルのコードになります。
まずはRendererプロセスからMainプロセスへメッセージを送る部分。これは[公式のdoc](https://electronjs.org/docs/api/ipc-main#sending-messages)を参考にしています。

```javascript
// In renderer process (web page).
const { ipcRenderer } = require("electron")
ipcRenderer.send("asynchronous-message", "ping")

```

続いて、MainプロセスでRendererプロセスからのメッセージを受け取る部分です。

```javascript
// In main process.
const { ipcMain } = require("electron")
ipcMain.on("asynchronous-message", (event, arg) => {
  console.log(arg) // prints "ping"
  event.reply("asynchronous-reply", "pong")
})
```

最後に、RendererプロセスでMainプロセスからのメッセージを受け取る部分です。ここでredux-sagaのchannelを使用しています。

```javascript
import { put, takeEvery } from "redux-saga/effects"
import { eventChannel } from "redux-saga"

const { ipcRenderer } = require("electron")

function* watchIpcChannelStart() {
  // Mainプロセスからのメッセージを受け取るための eventChannel を作成
  const channel = eventChannel((emit) => {
    ipcRenderer.on("asynchronous-reply", () => {
      emit(receiveAsynchronousEvent())  // dispatchしたいactionをemitの引数に渡す。
    })

    return () => { }
  })

  // 作成したchannelをtakeしてイベントを待ち受ける。
  yield takeEvery(channel, handleIpcChannelStart)
}

function* handleIpcChannelStart(action) {
  // actionをdispatchする  
  yield put(action)
}

export default function* rootSaga() {
  yield fork(watchIpcChannelStart);
}
```

# まとめ
以上、electronのプロセス間通信にredux-sagaを導入する方法でした。
実際に導入してみて感じた利点は、プロセス間通信もreduxのデータフロー（イベントが発火したらactionをdispatch→stateを更新→再レンダリング）に則ることができてわかりやすくなったことでしょうか。また、メインプロセスからのメッセージ受信に関わるコードを１箇所に集約できたのもよかったです。
cv::projectPointsの入出力のshapeについてのメモ

OpenCVに[cv::projectPoints](
http://opencv.jp/opencv-2svn/cpp/camera_calibration_and_3d_reconstruction.html#cv-projectpoints)という関数があるのですが、入出力の配列がいろいろshapeを取り全く分からないので調査した個人的なメモ。OpenCVのいろいろな関数がこんな感じな気がします。

入力

> objectPoints – 3次元物体上の点群座標の入力配列．これは，3xN または Nx3 のシングルチャンネル配列，あるいは 1xN または Nx1 の3チャンネル配列 (あるいは vector<Point3f> ) です．ここで N はビューの点の個数です．

出力

> imagePoints – 出力される，画像上の点の 2xN または Nx2 の1チャンネル配列，あるいは 1xN または Nx1 の2チャンネル配列． (あるいは vector<Point2f> ． )

以下opencv-pythonについて調べましたので、他のライブラリでは仕様が異なるかもしれません。

| objectPoints(入力)のshape     | imagePoints(出力)のshape |
|:----------------------------:|:------------------------:|
| (3, N, 1) | (N, 1, 2) |
| (N, 3, 1) | (N, 1, 2) |
| (N, 1, 3) | (N, 1, 2) |
| (1, N, 3) | (N, 1, 2) |

結果、いずれの場合も(N, 1, 2)で出てくるようです。
そうなると、(2, N, 1), (N, 2, 1), (1, N, 2)というパターンはどういうときに出てくるのか気になりますがコードを読みに行く気力がないです。(opencv-pythonの場合にはreshapeして(N,1,2)に揃えているという事なのかもしれません)

また、(3,3,1)はどるなるのかというと、(N,3,1)のパターンとして処理されるようです。そうすると、N=3の時に意味が変わってしまう(3,N,1)という入力を何故用意したのか謎です。
(1,1,3)が(N,1,3)なのか(1,N,3)なのかも気になる所ですが、こっちは結局的には同じ配列になるのでおいておきます。

個人的なメモとしては、常に
入力: (N,1,3)
出力: (N,1,2)
でやるのが良さそうです。しかし、情報を持っていない2次元目は一体何のためにあるのでしょう。

どういう経緯でこのようなインターフェースが出来上がったのか興味がわきます。(個人的な感想を言うと正直ものすごく使いにくい)
[自分用メモ]Mask R-CNNを最短で動かす9ステップ

#実際に動作するまでにやった9ステップ
環境はUbuntu14.04．しかし大体のLinux環境はこれでいけるはず？

１．GitHub(https://github.com/matterport/Mask_RCNN)をクローンする．
２．新しく仮想環境を作成する．（今回はpython=3.6の環境を作成）
３．READMEのInstallationに従って，pip3 install -r requirements.txt
４．python3 setup.py installを行う．
５．cd samplesに移動して，Jupiter notebookを起動して，demo.jpynbを開き，Download asからpython形式でダウンロードする．（demo.pyをGET）
６．demo.pyをdemo.jpynbと同層に配置して，demo.pyの中のget_ipython().run_line_magic(“matplotlib”, “inline”)の一文をコメントアウトする．
７．一回python demo.pyで実行してみる．（エラーでる．）
８．おそらくcoco周りでエラーが出るので，cd cocoして，その層に，
git clone https://github.com/pdollar/coco.git９
cd cocoapi
make
Sudo make install
Sudo python setup.py install
したら，
(こちらのgithubを参照，https://github.com/matterport/Mask_RCNN/issues/6)

９．samplesのフォルダに戻って，demo.pyを実行すればできるはず．
オブジェクト指向をざっくり理解する(初心者向け)

##はじめに
最近フロントエンドを独学で勉強中ですが、JavaScriptを学習するにあたり「オブジェクト指向」という概念が出てきて色々調べたのでメモを残しておく。
ちなみに私はインフラエンジニアなので業務でプログラミングはshellscriptやIaCしかやってません。
なので、かなり初心者向けの内容になっています。


## オブジェクト指向とは
オブジェクト指向とは要素を`物`と捉えて、それに`動き`を与える考え方。
プログラムを手順ではなくて、物の作成と操作として見るといった感じ。




## RPGを例にオブジェクト指向を理解してみる

例えばこんなRPGのPTがあったとする。
これを例に、基本的な用語と3大要素と呼ばれるものをみていく。

```:疑似言語
Class 人間 {
　性別：
　年齢：
　職業：

　fanction action(){
　　歩く；
  }

 fanction action(){
　　話す；
  }

fanction action(){
　　食べる；
  }
}


勇者 = new 人間{
　性別：男
　年齢：18
　職業：勇者

　fanction action(){
　　剣で切りつける；
  }
}

魔法使い = new 人間{
　性別：女
　年齢：17
　職業：魔法使い

　fanction action(){
　　魔法を唱える；
  }
}

僧侶 = new 人間{
　性別：男
　年齢：40
　職業：僧侶

　fanction action(){
　　回復をする；
  }
}
```
### 基本用語
まずはオブジェクト指向における基本用語を見ていく。

#### オブジェクト
オブジェクトはクラス(設計図)から作った実物のことを指す。
例だと、人間という設計図に勇者という情報を与え、出来上がったものが勇者オブジェクトとなる。
この情報には`プロパティ`と`メソッド`の２つの要素がある。

####プロパティ
オブジェクトが持っている属性を定義するもの。
例だと性別や年齢がこれにあたる。

#### メソッド
オブジェクトが持っている操作を定義するもの。
例だと歩くや話すがこれにあたる。

#### クラス
クラスはオブジェクトの設計書のようなもの。
例だと、人間という設計図があり、そこにプロパティとメソッドを与えることで勇者や魔法使いといったオブジェクトになる。

#### インスタンス
インスタンスとは「実体」という意味。
クラスで説明した、
>人間という設計図があり、そこにプロパティとメソッドを与えることで勇者や魔法使いといった`オブジェクトになる

この設計図からオブジェクトを作ることをインスタンス化と呼ぶ。

### 3大要素
次にオブジェクト指向における3大要素と呼ばれるものについて見ていく。

#### 継承
特定のオブジェクトの機能を引くついで使用すること。
例えば、似たようなオブジェクトを複数作成する場合、全てのプロパティやメソッドを書くとコードが長くなり保守性も悪くなる。
例だと、人間というクラスを継承することでパーティの３人が人間クラスの持つ基本動作をそのまま利用することができる。
継承を使用することで、プログラムの再利用性や保守性を高めることができる。

#### カプセル化
他のプログラムから干渉されないようにする仕組みのこと。
例だと、actionの部分に「切腹する」なんてアクションを追加されたら困る。
カプセル化することによって、他のプログラムからの干渉を防ぐことができる。
(※正確にいうと、干渉されない部分を明確に分けれる)

#### ポリモーフィズム
聞き慣れない言葉だが、日本語にすると多様性という言葉になる。
こちらも継承と同じで、プログラムの再利用性を高める考え方になる。
例えば、ポリモーフィズムという考え方なしで考えると、このパーティが攻撃するときは

```:ポリモーフィズムなし
// action関数を呼び出す
勇者.action()
魔法使い.action()
僧侶.action()
```
みたいに操作を列挙しないといけない。
これをポリモーフィズムの考え方に基づいて直すと

```:ポリモーフィズムあり
// action関数を呼び出す
 party = [勇者,魔法使い,僧侶];

 party.action();
```
といった具合にスッキリ書くことができる。
パーティーのメンバーが増えたり、呼び出す回数が増えるほど両者の違いがどんどん明確になっていく。

##まとめ
まずはオブジェクト指向をイメージだけ理解するためにざっくり書いて見た。
もちろんオブジェクト指向はもっともっと深いですが、まずはイメージだけつかめれば幸いです。
react redux api


## 気づき

- action creater

これはactionを何回の書きたくないから変数だけを引数に渡すのね

- redux store 

reduxを使うときに、apiでfetchするのは、`willMountComponent`でか


## 記事

https://dev.to/markusclaus/fetching-data-from-an-api-using-reactredux-55ao
virtualenvの使い方

## virtualenvの使い方

### Install 方法

```
pip install virtualenv
```

### バージョンの確認

```
virtualenv --version
```

### 仮想環境の作成

```
virtualenv (--name--) --no-site-packages
```

### 仮想環境の有効化

```
. (--name--)/bin/activate
```

### 仮想環境の無効化

```
deactivate
```
Apple iOS Human Interface Guideline を読もう[User interaction編]

Apple iOS Human Interface Guideline
---
Apple iOS Human Interface Guidelineをgoogle翻訳で訳しました。
今回はUser interaction編を読んでいきましょう。

**<h3>・認証</h3>**
エクスペリエンスのパーソナライズ、追加機能へのアクセス、コンテンツの購入、データの同期など、価値と引き換えにのみ認証するようユーザーに求めます。アプリで認証が必要な場合は、Appleでサインインを使用して、簡単で安全な方法でサインインします。Appleでサインインをサポートすると、信頼できる一貫したサインインエクスペリエンスが得られます。複数のアカウントとパスワード。

サインインをできるだけ長く延期します。便利なことをする前にサインインを余儀なくされると、人々はしばしばアプリを放棄します。アプリにコミットする前に、アプリに夢中になるチャンスを彼らに与えてください。ショッピングアプリでは、発売直後に商品を閲覧し、購入の準備ができたときにのみサインインを要求します。メディアストリーミングアプリでは、何かをプレイするためにサインインする前に、他の人があなたのコンテンツを調べて、あなたが提供しなければならないものを見てみましょう。

認証の利点とサービスへのサインアップ方法を説明します。アプリで認証が必要な場合は、ログイン画面に簡潔でわかりやすい説明を表示し、要件の理由とその利点を説明します。また、アプリを使用する全員が最初からアカウントを持っているわけではないことに注意してください。取得方法を説明するか、簡単なアプリ内登録方法を提供してください。

適切なキーボードを表示して、データ入力を最小限にします。たとえば、電子メールアドレスを要求する場合、便利なデータ入力ショートカットを含む電子メールキーボード画面を表示します。関連するガイダンスについては、キーボードを参照してください。使用可能なキーボードタイプの完全なリストについては、UITextInputTraitsのUIKeyboardType定数を参照してください。

パスコードという用語は使用しないでください。パスコードは、生体認証が無効になっている場合に、ユーザーのiOSデバイスのロックを解除し、Apple Payで認証するために使用されます。

Apple Pay認証の設計ガイダンスについては、Apple Payをご覧ください。

---

**<h3>・FaceID</h3>**
認証するための単一の方法を人々に提示します。ユーザーが認証方法を選択する必要がない場合は、最も直感的です。 Face IDのような単一のオプションを与えるだけです。最初の方法が失敗した場合のみフォールバックとして、ユーザー名とパスワードを要求するなどの代替手段を提供します。

ユーザーのアクションに応じてのみ認証を開始します。ボタンをタップするなどの明示的なアクションにより、ユーザーは確実に認証されます。 Face IDの場合、ユーザーがカメラに向かっている可能性も高くなります。

認証方法を常に特定します。たとえば、Face IDを使用してアプリにサインインするためのボタンには、「Sign In」ではなく「Sign In with Face ID」というタイトルを付ける必要があります。

認証方法を正確に参照します。 Face IDをサポートするデバイスでTouch IDを参照しないでください。逆に、Touch IDをサポートするデバイスでFace IDを参照しないでください。デバイスの機能を確認し、適切な用語を使用してください。開発者向けガイダンスについては、LABiometryTypeをご覧ください。

一般に、アプリ内で生体認証にオプトインするための設定を提供することは避けてください。システムレベルで生体認証が有効になっている場合は、ユーザーがそれを使用することを想定してください。アプリ固有の設定を実装すると、ユーザーは、システム全体で実際に無効になっているアプリで生体認証が有効になっているように見える状態になる場合があります。

システム認証機能を識別するためにアイコンを使用しないでください。システムのTouch ID（th印）やFace IDのアイコンのように見えるアイコンを見た人は、認証することになっていると思います。アイコンを使用して認証機能を識別すると、特にアイコンが色付けされ、大きなサイズで表示され、コンテキスト外で表示される場合、矛盾が生じて混乱が生じます。

---
**<h3>・Undo Redo</h3>**

多くのアプリでは、入力や削除などの特定の操作を元に戻したりやり直したりするためにデバイスを振ることができます。この方法で開始されたアラートは、ユーザーに元に戻す操作またはやり直し操作を確認またはキャンセルするように求めます。

元に戻すまたはやり直す操作を簡潔かつ正確に説明します。元に戻すおよびやり直しの警告タイトルには、自動的に「Undo」または「Redo」の接頭辞が含まれます（末尾のスペースを含む）。このプレフィックスの後に表示するには、元に戻すまたはやり直す内容を説明する単語を1つまたは2つ追加する必要があります。たとえば、「名前を元に戻す」や「アドレス変更をやり直す」などのアラートタイトルを作成できます。

元に戻すとやり直しにシェイクジェスチャーを使用する場合は、他のアクションに使用しないでください。シェイクジェスチャにはプログラムで複数の意味を与えることができますが、人を混乱させたり、アプリを予測不能にしたりするリスクがあります。

元に戻すボタンとやり直しボタンは控えめに提供してください。アプリが同じタスクを実行するための複数の方法を提供する場合、混乱を招きます。アプリで専用の[元に戻す]および[やり直し]ボタンが本当に必要な場合は、システムが提供する標準のアイコンを使用して、ナビゲーションバーなどの予想される場所に配置します。

元に戻す操作とやり直し操作は、現在のコンテキストでのみ実行してください。元に戻すとやり直しは、以前のコンテキストではなく、現在のコンテキストに明確かつ即時に影響するはずです。

開発者向けのガイダンスについては、UndoManagerを参照してください。

---
Lenovo Yoga 720にUbuntuをインストールする方法

# 手順
https://askubuntu.com/a/963767 の2のところをやる

# 参考
https://askubuntu.com/questions/946480/installing-ubuntu-alongside-windows-on-lenovo-yoga-720
https://thegeekpage.com/what-is-fast-startup-and-how-to-turn-it-on-in-windows-10/
Linuxでメニューを作ってコマンド作業を減らす

# どんなものなのか

番号を入力するだけで、設定したコマンドを発行してくれるショートカットメニューです。
折角作ったので備忘録がわりに公開。
もっと良くなるとは思うけど、サクッと作ったので、その内良くなっていくかも。


# どんな時に使うのか

- 踏み台サーバから色々なサーバへSSHするのだが、サービスが増えてくるとIPやらホスト名・ユーザー名を覚えるのが面倒。というか、すぐ忘れる。
- 各種コマンドのオプションが長くて、手元のテキストからのコピペがウザい。よく失敗して冷や汗かくし。
- ショートカットコマンド作りすぎて何があるか見ないと分からないし、他人に教えるのも面倒。

# ソースコード

まずはライブラリ。
~/binにPATHが通っていない環境の場合は通るようにしておいてください。

```bash:~/bin/libmenu
#!/bin/bash

###
# メニュー表示
###
function display_menu() {
    echo "##### MENU #####"
    IFS=$'\n'
    for key in ${!menu_title[@]}; do
        if [ "${menu_title[${key}]}" = "-" ]; then
            echo "----------"
        else
            echo "${key}: ${menu_title[${key}]}"
        fi
    done
    echo "0: EXIT"
    echo -n "number> "
    read INPUT_KEY
}

###
# コマンド選択後もメニューに戻るようにする
###
function select_menu() {
    while :
    do
        display_menu

        if [ "${INPUT_KEY}" = "0" ]; then
            exit;
        fi
        IFS=$' '
        ${menu_command[${INPUT_KEY}]}
    done
}
```

実際に叩くコマンド部分。
メニュー表示と実行コマンドの添字を同じにしてください。
メニューを入れ子にすることも可能です。

```bash:~/bin/menu
#!/bin/bash

declare -a menu_title
declare -a menu_command

### メニュー表示
menu_title=(
[1]="[192.168.56.2] 本番環境"
[2]="開発環境リリース"
[3]="エラーログを見る"
[10]="Git Pull"
[11]="フロントエンドのビルド"
[20]="-"
[21]="他環境へのSSH"
)
### 実行コマンド
menu_command=(
[1]="ssh -A chiyoyo@192.168.56.2"
[2]="release_command"
[3]="tail -f /var/log/httpd/error_log"
[10]="git pull origin master"
[11]="npm run build -- --mode development"
[21]="ssh_menu"
)

. ~/bin/libmenu
select_menu
```

# 実行例

```text
$ menu
##### MENU #####
1: [192.168.56.2] 本番環境
2: 開発環境リリース
3: エラーログを見る
10: Git Pull
11: フロントエンドのビルド
----------
21: 他環境へのSSH
0: EXIT
number> _
```

# メリット・デメリット

## メリット

* ホスト名を覚えなくて良くなった。
* コマンド打たなくていいので、すぐに作業・作業結果がわかるようになった。
* リリース手順をコマンドにするようになり、休みの時などの引き継ぎが非常に楽。

## デメリット

* サーバに入れれば誰でもリリースできたりするので、少し不安。
* 勇み足になる場合がある＞ちょっと待ったが途中でかかった時には既に作業完了している。
【Docker】軽量なTerraformコンテナを立てる

# Terraformとは
インフラ構築や設定をコード(テンプレートファイル)を使って自動化するためのツールで、
Infrastructure as Codeによるコードベースで安全で効率的にインフラを管理できる。

複数クラウドに対応しており、OCIだけでなく他のクラウドでもTerraformを利用することができる。

## dockerfileとdocker-composeはgithubで公開しています。
https://github.com/manaki-naoe/docker-terraform

## dockerfileの作成

ベースイメージはalpineを利用します。
ARGでterraformのバージョンを指定しています。

また、terraform init時にcurlを利用するので、
apk addでcurlをインストールしています。

```dockerfile
FROM alpine:3.10

ARG terraform_version="0.12.5"

# Install terraform
RUN apk update --no-cache \
    && apk add --no-cache \
        wget \
        unzip \
        curl \
    && wget https://releases.hashicorp.com/terraform/${terraform_version}/terraform_${terraform_version}_linux_amd64.zip \
    && unzip ./terraform_${terraform_version}_linux_amd64.zip -d /usr/local/bin/ \
    && rm -rf ./terraform_${terraform_version}_linux_amd64.zip \
    && mkdir terraform
```

### docker imageの生成
dockerfileがある階層で以下を実行します。

```bash
$ docker build -t alpine-terraform .
```

## docker-compose.ymlの作成

[Your terraform project]には、terraformのコードがあるパスを指定してください。

```yml
version: '3'
services:
  web_container:
    image: alpine-terraform
    restart: always
    container_name: terraform_container
    volumes:
      - [Your terraform project]:/terraform
    tty: true
```

## terraformコンテナの起動
docker-compose.ymlがある階層で以下を実行します。

```bash
$ docker-compose up -d
```

### terraformコンテナへ接続

```bash
docker exec -it terraform_container /bin/sh
```

terraformディレクトリがあるので、その中でterraformを実行していきます。
【k8s】Liveness、Readinessの使い方、ベストプラクティス

# はじめに

ヘルスチェックは、アプリケーションのインスタンスが機能しているかどうかをシステムにお知らせ簡単な方法である

> k8sの場合：LivenessとReadinessプローブは、podコンテナー内で実行しているアプリケーションの正常性をチェックするのを利用しています

# 概要

続いて、LivenessとReadinessプローブはどういう風に機能するかどうかを見てみましょう

### Livenessプローブ

**定義**

Livenessプローブがk8sにアプリが機能しているかどうかをお知らせします。アプリが機能していない場合、k8sがpodを再起動します（pod削除して、新しいpodを立ち上げます）

**イメージ**

![Liveness Concept](https://storage.googleapis.com/gweb-cloudblog-publish/original_images/google-kubernetes-probe-livenessae14.GIF)

**解決問題**

+ メモリ不足
+ CPU利用率が高い
+ アプリのデッドロック

> アプリケーションが応答しない、エラーが発生する時

### Readinessプローブ

**定義**

Readinessプローブがk8sにアプリがトラフィック受付できるかどうかをお知らせします。k8sは、アプリにトラフィック受付するのを許可する前に、Readnessプローブが通過できることを確認します。Readnessプローブが失敗する場合、k8sがアプリにトラフィックを送信することを停止します。

**イメージ**

![Readiness concept](https://storage.googleapis.com/gweb-cloudblog-publish/original_images/google-kubernetes-probe-readiness6ktf.GIF)

**解決問題**

+ アプリ起動時間、設定する時間
+ DBの更新

> 連携するサービス待ち時間など、アプリケーションがReadyにならない時

# プローブ書類(タイプ)

### HTTP

HTTPプローブは、livenessプローブに一般的なタイプな設定で使われています。
k8sがhttpパスに送信して、返すステータスコードは200か300系だと、成功するとします。そうじゃない場合、失敗とします

> 参考[リンク](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/#define-a-liveness-http-request)

### Command

k8sがタッゲトコンテナーにコマンドを実行する。実行したコマンドの`exit code`は`0`場合、成功するとします。そうじゃない場合、失敗とします

> 参考[リンク](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/#define-a-liveness-command)

### TCP

k8sが指定されたポートで接続を確立しようとします。接続が確立できる場合、成功するとします。そうじゃない場合、失敗とします
*このタイプは、HTTPプローブとCommandプローブを使えない場合によく使われています*

> 参考[リンク](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/#define-a-tcp-liveness-probe)  

**下記の投稿から参考しました**
https://cloud.google.com/blog/products/gcp/kubernetes-best-practices-setting-up-health-checks-with-readiness-and-liveness-probes
RxRelayを利用してデータのブリッジを行う

# 目的
ある定常的に変化する値を常に購読しておきたい場合において、ObservableではOnErrorが発生してしまった場合に購読が終了してしまう。
OnErrorが発生しようとも継続して購読しておきたいときはRxRelayを利用する。

# RxRelay

Jake神が作ったライブラリ
https://github.com/JakeWharton/RxRelay

# 導入方法
build.gradleに以下の文を追加

```groovy
implementation 'com.jakewharton.rxrelay2:rxrelay:2.1.1'
```

# 実装

実装方法はBehaviorSubject等とほとんど同じ。

```kotlin
val dataStream = BehaviorRelay.create<Data>()
```

BehaviorSubjectと異なる点は、onNextの代わりにacceptを利用すること

```kotlin
dataStream.accept(Data(1))
```

３種類提供されていて以下の違いがある。
BehaviorRelay ：購読開始前に流れてきた最後のイベントを、購読開始時に受け取れる
PublishRelay :購読開始前に流れてきたイベントは受け取らない
ReplayRelay :購読開始前に流れてきたイベントは全て受け取る

# onNextとacceptの違い
ほとんど同じ内容だが、onNextの場合はterminalEventがnull出ない場合に処理を終了している。

```java
    @Override
    public void accept(T value) {
        if (value == null) throw new NullPointerException("value == null");

        setCurrent(value);
        for (BehaviorDisposable<T> bs : subscribers.get()) {
            bs.emitNext(value, index);
        }
    }
```

```java
    @Override
    public void onNext(T t) {
        ObjectHelper.requireNonNull(t, "onNext called with null. Null values are generally not allowed in 2.x operators and sources.");

        if (terminalEvent.get() != null) {
            return;
        }
        Object o = NotificationLite.next(t);
        setCurrent(o);
        for (BehaviorDisposable<T> bs : subscribers.get()) {
            bs.emitNext(o, index);
        }
    }
```

terminalEventは想像の通り、onError もしくは onCompleteで設定される。

```java

    @Override
    public void onError(Throwable t) {
        ObjectHelper.requireNonNull(t, "onError called with null. Null values are generally not allowed in 2.x operators and sources.");
        if (!terminalEvent.compareAndSet(null, t)) {
            RxJavaPlugins.onError(t);
            return;
        }
        Object o = NotificationLite.error(t);
        for (BehaviorDisposable<T> bs : terminate(o)) {
            bs.emitNext(o, index);
        }
    }

    @Override
    public void onComplete() {
        if (!terminalEvent.compareAndSet(null, ExceptionHelper.TERMINATED)) {
            return;
        }
        Object o = NotificationLite.complete();
        for (BehaviorDisposable<T> bs : terminate(o)) {
            bs.emitNext(o, index);  // relaxed read okay since this is the only mutator thread
        }
    }
```

なのでRelayではonErrorが発生しようが購読が継続されるよう。
コマンドラインでXcodeのプロジェクトのVersionNumberやBuildNumberの変更方法

Xcodeのプロジェクトのバージョンをコマンドラインから一括で指定した値に変更したい場合や、
バージョン更新したいときに便利なのでメモ。
fastlaneの `increment_build_number` や `increment_version_number` とかの内部で使っているやつです。

VersionNumberを指定した値にする

```bash
agvtool new-marketing-version <VersionNumber(ex. 1.0.1)>
```

BuildNumberを1つ上げる

```bash
agvtool next-version -all
```

バージョン1つ上げると

- `<プロジェクト名>.xcodeproj/project.pbxproj`
- `<プロジェクト名>/Info.plist`
- `<プロジェクト名>Tests/Info.plist`
- `<プロジェクト名>UITests/Info.plist`

の4つのファイルに変更が入るので、手動で変更する際は変更漏れに注意ですね。
二分木における最小共通祖先（Lowest Common Ancestor）の探索

## 概要
木構造における最小共通祖先（Lowest Common Ancestor: LCA）とは、ある二つのノードが与えられた時、その両方を自身以下に持つノードのうち、最も低い（葉に近い）位置にあるノードのことを指します。一方のノードがもう一方のノードの直接の祖先となっている場合は、直接の祖先となっているノードがLCAとなります。例えば以下の二分木において、6と4のLCAは5、0と1のLCAは1となります。

![binarytree.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/122091/5e76848b-800a-ccaa-0495-dbdde414734a.png)

LCAを探索するアルゴリズムは複数ありますが、本記事では各ノードから自身の祖先を辿っていき、最初に遭遇する共通の祖先を探し出す手法を紹介します。

## 方針
各ノードから自身の祖先を辿ろうとする場合、各ノードは自身の親を知っていなければなりません。そこで方針としては下記になります。

1. 各ノードを巡回し、各ノードの親をdictionaryに保存しておく
2. 与えられた二つのノードのうち、一方のノードから親を辿っていき、rootに達するまでに辿ったノード（全ての祖先）をsetに保存しておく
3. もう一方のノードから親を辿っていき、2で保存したsetに含まれるノードが現れた時、それが共通の祖先（LCA）となる

注：1では与えられた二つのノードの親が見つかった時点で巡回を打ち切る方が効率的ですが、今回は便宜上全ノードを巡回することにします。

## 実装例
```python
class TreeNode(object):
    def __init__(self, x):
        self.val = x
        self.left = None
        self.right = None

class Solution(object):
    # 各ノードをDFSで巡回しつつ、親ノードをdictionaryに保存していく
    def traverse(self, node, parents):
        if node is None:
            return parents
        if node.left is not None:
            parents[node.left] = node
            self.traverse(node.left, parents)
        if node.right is not None:
            parents[node.right] = node
            self.traverse(node.right, parents)

        return parents

    # ノードp, qのLCAを探索するメソッド
    def lowestCommonAncestor(self, root, p, q):
        # 各ノードをkey、その親をvalueに持つdictionaryを作成しておく
        parents = {root: None}
        parents = self.traverse(root, parents)

        # 一方のノード（ここではp）の祖先を保存しておくためのsetを用意する
        ancestors = set()
        # 自分自身がLCAになる可能性もあるため、まずは自身をセットする
        parent = p

        # pの親を辿っていき、祖先となるノードを全てsetに保存していく
        while parent is not None:
            ancestors.add(parent)
            parent = parents[parent]

        # 次にqから親を辿っていき、pの祖先とぶつかった時点でLCAとみなす
        node = q
        while node not in ancestors:
            node = parents[node]

        return node

```

## 参考
[Lowest Common Ancestor (Wikipedia)](https://en.wikipedia.org/wiki/Lowest_common_ancestor)
[最小共通祖先](https://freestylewiki.xyz/fswiki/wiki.cgi?page=%E6%9C%80%E5%B0%8F%E5%85%B1%E9%80%9A%E7%A5%96%E5%85%88)
【若手エンジニア】AWSソリューションアーキテクトアソシエイト合格まで！

# はじめに
普段 https://toriken-blog.com/ というブログを運営している toriken です
今回、AWSソリューションアーキテクトの取得しましたので、経緯と勉強法をまとめてみます。

# 前提
- SIerとして社会人２年目
- AWS業務ほぼ未経験
- クラウドとは？からの勉強

# きっかけ
私がAWS認定試験に挑戦したきっかけは、職場のおじさんに勧められたのがきっかけでした。
自分のキャリアアップや評価に繋がるかな、と思い挑戦してみました。

# 勉強時間
**40時間**ぐらいしました。

# 教材
# 1.これだけでOK！ AWS 認定ソリューションアーキテクト – アソシエイト試験突破講座（初心者向け21時間完全コース）
https://www.udemy.com/aws-associate/
**Udemyで配信されている動画で学ぶ教材です。**ハンズオン形式で、本で学ぶよりは入りやすいと思います。
Udemyは頻繁にセールを行うので**セール時に購入しましょう。**１２００円くらいです。

# 2.AWS認定資格試験テキスト AWS認定 ソリューションアーキテクト-アソシエイト
https://www.amazon.co.jp/dp/479739739X/
この本を１周読みました。

# 3.AWS WEB問題集で学習しよう

これが最強です。

https://aws.koiwaclub.com/
4000円ほどかかる有料の教材です。ちょっと高いですが、
**この問題をひたすら周回してれば合格できます！**
SAAだけで900問近く問題があり、私は２周しました。認定資格取得だけを目標としている方は、この問題集をひたすら解くのが最短だと思います。

# 勉強方法
本　→　Udemynハンズオン　→　WEB問題集
この順番で勉強しました。用語、主なAWSサービスの概要を理解してきたら、WEB問題集をひたすら解きました。

# 試験のコツ
私はこのように試験に臨みました。
1. **回答群をサラッとみる。**問題に慣れてくると回答群から何を問われているのかを把握できます。
2. **問題の文末を読む。**文末に問題の本質が記述されていることが多いです。
3. **問題の全体を読む。**最後の確認として全文を読んで、回答に確信を得ます。
Symmathic Zero RISC-Vを使う①

# はじめに
Symmathic Zero RISC-Vは [**Symmathic社**](https://www.symmathics.com/)が提供する、__開発__と__教育__を目的としたRISC-Vベースのsoftcoreです。
第一回の今回は、Symmathic社より提供されているtoolchainである**SET-05**(Symmathics Embedded Toolchain for Zero RISC-V)のbuildについて書いていきたいと思います。(公式Documentation(英文)は[ここから](https://www.symmathics.com/dokuwiki/doku.php?id=set-05)アクセス可能)

# 準備物
- Symmathic Zero RISC-Vが***プレインストール***されたDigilent Arty A7 35T board　(購入は[ここから](https://www.symmathics.com/index.php/product/risc-v-pre-configured-digilent-arty-a7-35t/) )
- MicroUSB ケーブル
- Linux搭載PC(現時点では***Ubuntu 16.04LST***環境下で動作が保証されているらしい)

# SET-05をビルド
#### 1. terminalを開き以下のコマンドを実行します。
```
sudo apt-get install build-essential
```
#### 2. SET-05を[ダウンロード](https://www.symmathics.com/index.php/set-05-page/)し、任意の場所に保存する。
#### 3. Libftdiをダウンロードする。
ダウンロードは[こちら](https://www.intra2net.com/en/developer/libftdi/download.php)から。SET-05はデフォルトでは__/usr/include/libftdi1__へインストールされていると仮定されています。もし、違うダイレクトリに保存した場合は、SET-05ファイル内にある__Makefile__を開き、__LIBFTDI_PATH__をLibftdiがインストールされているパスへ変更する。
#### 4. RISC-V GNU Compiler Toolchainをダウンロードし([ここから](https://static.dev.sifive.com/dev-tools/riscv64-unknown-elf-gcc-8.2.0-2019.02.0-x86_64-linux-ubuntu14.tar.gz))、任意の場所に解凍する。
#### 5. **~/.bashrc**を好きなエディタで開き、以下のパスを追加する
```
export RISCV_GCC=/path/to/riscv-elf-gcc/binary 
```  
```
export RISCV_OBJCOPY=/path/to/riscv-elf-objcopy/binary  
```  
```
export RISCV_AR=/path/to/riscv-elf-ar/binary  
```
パスの例としては、

```
export RISCV_OBJCOPY=/home/USER_NAME/Document/riscv64-unknown-elf-gcc-8.2.0-2019.02.0-x86_64-linux-ubuntu14/bin/riscv64-unknown-elf-gcc
```
```
export RISCV_AR=/home/USER_NAME/Document/riscv64-unknown-elf-gcc-8.2.0-2019.02.0-x86_64-linux-ubuntu14/bin/riscv64-unknown-elf-objcopy
``` 
```
export RISCV_AR=/home/USER_NAME/Document/riscv64-unknown-elf-gcc-8.2.0-2019.02.0-x86_64-linux-ubuntu14/bin/riscv64-unknown-elf-ar
``` 
#### 6. terminal上でSET-05/へ移動して以下のコマンドを実行し、toolchainをビルドする  
```
make build-toolchain
```  

#まとめ
以上でToolchain(SET-05)の初期設定はが完了です。
次回はProjectの作成方法、upload, debug方法について書きたいと思います。
MySQL(INNODB)でロック待ちを確認する方法

MySQL5.6 (INNODB)

```
SELECT
	pl.ID AS ID,
	trx.trx_id AS TRX_ID,
	pl.STATE AS STATE,
	trx.trx_state AS TRX_STATE,
	waits.blocking_trx_id AS BLOCKING_TRX_ID,
	trx.trx_weight AS RECORDS,
	trx.trx_query AS QUERY
FROM
	information_schema.INNODB_TRX AS trx
LEFT JOIN
	information_schema.PROCESSLIST AS pl
ON
	trx.trx_mysql_thread_id = pl.ID
LEFT JOIN
	information_schema.INNODB_LOCK_WAITS AS waits
ON
	trx.trx_id = waits.requesting_trx_id
```

rootアカウントでやらないと他のユーザーの実行したクエリが表示されないので注意
WebGLをふんだんに使った3Dウェブサイトをチームで作ってみた：解説【フロントエンドエンジニア編】

# 初めに
WebGLで3Dを活用したWebサイト、「 [3DWebSite](https://pcpo.sabo.jp/3dwebsite) 」をPlayCanvasを利用して開発しました。
![Imgur](https://imgur.com/bj1IEIF.png)
- PlayCanvas : https://playcanvas.jp
- 3DWebsite : https://playcanvas-demo.jp/examples/web/3dwebsite/

ここでは、3DWebSiteを開発した際に得られた、__ゲームエンジンを利用してWebサイトを作る__知見を残すためそれぞれの担当メンバーが解説記事を執筆しています。

**解説記事一覧**

- [【3Dエンジニア編】](https://qiita.com/utautattaro/items/23f6bc6d3f50b21bf52f)
- [【3Dモデラー編】](https://qiita.com/shujimuna1102/items/89947ffd6a4a79ff1db5)
- [【フロントエンドエンジニア編】](https://qiita.com/yushimatenjin/items/de1aa22ab05fa45d79cc) ←　いまここ
- [【デザインエンジニア編】](https://qiita.com/sutobu000/items/827df2d1cd77b5c4b025)


## 何をやったか
3DWebSiteというPlayCanvasを使用したウェブサイト制作のデモを作成しました。枠割としてはデプロイのためのCLIツールを作りました。PlayCanvasの機能として、すべてのフリープラン・パーソナルプラン・オーガニゼーションプランと３つのプランがあり、その`すべてのプラン`で`REST API`ができます。それを使用して、PlayCanvasの開発を素早くするための物を作成しました。

## 役割
- フロントエンドエンジニア
- DevOps
- バックエンドのCLIツールの作成
役割としては`DevOps`、`フロントエンドエンジニア`という関わり方をしました。

## なぜ
1. PlayCanvas上でソースコードを管理しているためGitの管理化から外れる
PlayCanvasではすべての開発がWebで完結する強みがある一方、開発時に使用するコードエディターを使用すると、ソースコードの管理のフローもウェブ上で行われます。
そのため、PlayCanvasのエディタ－で開発をするとGitでの管理下かから、外れてしまいます。

2. SassやPug、TypeScript等を使用したい
PlayCanvas`TypeScript`や`Babel`、`Sass`、`Pug`などを使用したい場合があります。そのときにもPlayCanvasのコードエディターを直接使用すると少し開発が厳しいため、こちらも解消していきましした。

### PlayCanvasの開発フロー
![](https://i.imgur.com/wbDpOdG.png)
1. 新規作成
    PlayCanvasでは付属のコードエディターがありますので基本的にはそちらを使用して開発をしていきます。こちらに関してはすべてWeb上で開発を行うことができます。
    
2. コード記述
 コードの記述については`PlayCanvas`がしているファイル形式、`HTML`, `CSS`, `JavaScript`を使用して開発を行います。ソースコードを記述した後、ゲーム画面をリロードすることでコードの変更がゲーム画面に反映されています。
3. 書き換え
作成したコードを書き換える際にもコードエディターを使用してちょくせつかきかえます

## 解決策
上記の問題を解決するために、`playcanvas-node`と`playcanvas-gulp`という`npm`のパッケージを作成しました。

* `playcanvas-node`について、こちらについてはPlayCanvasのAPIのラッパーとなっており、`Node.js`からPlayCanvasの`REST API`を使用するのを簡単にするためのパッケージです。PlayCanvasの`REST API`の種類については後述いたします。

* `playcanvas-gulp`についてこちらは`Gulp`と言われるタスクランナーのプラグインです。

## Gulpの役割
今回のGulpの役割はローカルで作成した`ts`,`sass`,`scss`,`pug`などのファイルをビルドします。

![](https://i.imgur.com/0smhdH1.png)


この２つを使用したあたらしいPlayCanvasの開発フローはこちらです
![](https://i.imgur.com/YhtmPzD.png)

1. 監視
`Visual Studio Code`,`Vim`など、ローカルで好きなエディターを使用してファイルを新規作成します。`scss`, `pug`, `ts`ファイルなどが新規作成がされると`gulp`のタスクが実行されます。

2. ビルド
gulpはそれぞれのビルドをするのに、`プラグイン`と言われるライブラリを使用してビルドをします。それぞれのファイルの形式に応じたプラグインを使用してビルドをします。

1. アップロード
ビルドされた後に`gulp-playcanvas`を使用して、PlayCanvasのコードエディター上にアップロードをします。

使い方につきましてはこちらを御覧ください

[Gulpのプラグインを書いたらPlayCanvasでの開発がめちゃくちゃ便利になった
](https://qiita.com/yushimatenjin/items/5f0f178e8a4ba4a5ee57)


PlayCanvasのGulpのプラグインを使用することで開発が簡単になりました。PlayCanvasでのフロントエンドの開発はまだあまりたまっておらず、今から始めると簡単に第一人者になれますのでぜひ
Xhack東京 firebaseとreactでTODOアプリ作るハンズオン 参加メモ

# 概要

 * firebaseとreactを使ったサーバレス開発ハンズオン
 * 参加者15名ほど
 * レベル感はプログラム初心者からReact経験者までまちまち
   * npm知らない人もいた

# ハンズオンの流れ
* 自己紹介
* 開発環境ざっくり説明
* 環境構築
* 機能説明&ちょっと修正
* デプロイ
* おしまい


# 開発環境ざっくり説明
## 巷で言われるサーバーレスとは
* ハード機材やネットワーク構成など気にせずサーバを使用できる便利プラットフォームのこと
* 明確な定義はない
* 最近でいうAWS、Heroku、Firebaseなんかがそう

## React.jsとは
* Facebook社が開発しているJSライブラリ
* インタラクティブなUIが簡単に作れる
* 新しい機能が随時追加される
* 破壊的なアップデートもあるため保守作業が大変
* 習得難易度が高い（Reactは簡単という人もいるけど）

# 環境構築

## システム構成
 * フロントエンド
    * React.js
 * バックエンド
    * firebase
 * パッケージ管理ツール
    * npm
* IDE
    * Gitpod（オンラインIDE）

# 機能説明&ちょっと修正
* 用意されたリポジトリをクローン、npm startで起動する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/401258/1d584bf2-323e-3506-4168-65b62f8cdb01.png)

* このままだとログインやDBアクセスができないので、firebaseを設定する

## firebase構築
* firebaseにログインしてプロジェクトを作成、webアプリケーションを追加する
* apikey情報などをfirebase.jsに転記
* Authentication設定で匿名ログインを許可
* ToDo項目を保存するデータベースを作成
* firebase init でホスティング設定
* build&デプロイでURL公開

### 用語
* 匿名ログイン
 * アプリに登録していないユーザーが、セキュリティ ルールで保護されているデータを使用できる
* Firebase Realtime Database
 * JSON形式で入出力可能なデータベース


## 動作確認

![xhack-react-todo.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/401258/c52e6868-e6e0-abff-465e-13a867a29505.gif)


* 匿名ログインをしているため、ブラウザを更新したり別タブで開いたり、別端末で開いたりするとTODOが表示されない。
* ユーザID、パスワードを使用したログインだと別端末でデータが共有可能になる

# 所感
参加者のレベル感がまちまちだったのでハンズオン中は環境構築で手一杯な感じ
環境構築終わった人はソースを眺めたり勝手に改造してみたり
firebase上で動くログイン機能やDBアクセスが含まれたソースをもらえたのはよかった
ハンズオン後に自分で改造して遊んでみるのが良さそう

# URL
https://x-hack.connpass.com/event/145652/
ノートPCスタンドのMOFTが予想より良かったのご紹介

国内クラウドファウンディング大手のMakuakeで約1800万を集めた
MOFTのPCスタンドを試してみたら予想以上に良かったのでご紹介です。

## MOFTとは

https://www.makuake.com/project/moft/

MOFTは“ Mobile Office for Travellers（旅行者のためのモバイルオフィス）”の略だそうです。
さまざまな角度から生産性を向上させるプロダクトを生み出すことに焦点を当てたチームです。


## 良かった点

- 目線が上がり姿勢がよくなる
- ガタつくこともあまりない
- 薄い・軽い
- デザインも良き
- コスパいい

https://www.wow-creators.com/2019/09/28/moftのpcスタンドがとてもいい【ガジェットレビュー/

詳細はブログ書いたのでぜひご覧ください。
【Ruby】中間テーブルを取得する際の命名

## TL;DR
親のテーブルクラス(User)の中間テーブルのクラス(UserGroup)をインスタンスから呼び出したい時は、下記のように書く

```
user.user_groups
```

## 詳細

### やろうとしたこと
親のテーブルクラスに紐づく中間テーブルのクラスの呼出

### 困ったこと
親のテーブルクラスに紐づく中間テーブルのクラスを呼び出すときに苦労しました。

user.userGroup?
user.usergroup?

命名基礎をちゃんと頭の中で整理せず解決しようとしたので、やばかったです...。

### 解決策
クラスはキャメルケース(UserGroup)のように書くが、呼び出したい時は、
user.user_group
のようにスネークケースで呼び出すのがつまづきポイントでした。

## 感想
rubyの命名規則難しい...
Windowsの「ファイル名を指定して実行」で「chrome」と打つとGoogle Chromeが起動する理由

# Pathが通ってないのに起動した
Windows10の「ファイル名を指定して実行」で「chrome」と打つと、GoogleChromeが起動した。
当然GoogleChromeの実行ファイルが置いてあるフォルダにPathが通っているからなんだろうな…
と思っていて環境変数の一覧を見たら、Pathにはchrome.exeのフォルダは存在しなかった。

なぜ起動するの？？？


# 仕組み
↓こちらをご参照ください
Microsoft Windows Dev Center : [Application Registration](https://docs.microsoft.com/en-us/windows/win32/shell/app-registration#using-the-app-paths-subkey)

レジストリの中に「App Paths」というキーがあり、そこに「chrome.exe」が登録されているから、でした。

> The entries found under App Paths are used primarily for the following purposes:
> ・To map an application's executable file name to that file's fully qualified path.
> ・To pre-pend information to the PATH environment variable on a per-application, per-process basis.

システム環境変数のPathに書くのではなく、アプリの中でプロセス単位で環境変数に入れてくれるみたいです。
権限局所化の一環ということでしょうか。
Class構文にTypeScriptを導入

Class構文にTypeScriptを導入したときの備忘録になります。


## document.querySelector

``` Sample.ts
class Sample {
  eventElement: HTMLInputElement;

  constructor(eventElement: string) {
    this.eventElement =  <HTMLInputElement>document.querySelector(eventElement);
  }
}

export default Sample;
```

`document.querySelector`でelementを指定するとき`HTMLInputElement`を記述しないと

```
TS2322: Type 'Element | null' is not assignable to type 'object'.
```
とエラーが表示される。


## document.querySelectorAllの場合

``` Sample.ts
class Sample {
  targetElements: NodeListOf<HTMLElement>;

  constructor(targetElements: string) {
    this.targetElements = document.querySelectorAll(targetElements);
  }
}

export default Sample;
```

`document.querySelector`と同じ記述(`HTMLInputElement`)をすると

```
Conversion of type 'NodeListOf<Element>' to type 'HTMLInputElement' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.
```

このようなエラーになります。

## document.scrollingElementの場合

``` javascript:Sample.ts
const scrollTopPosition: number = document.scrollingElement ? document.scrollingElement.scrollTop : 0;
```

`document.scrollingElement`がnullを返すので三項演算子で分岐

## resizeイベントの場合

window.resizeのイベントが終わったら処理を走らすソースにになります。

``` javascript:Sample.ts
Class Sample {
  observeResize: NodeJS.Timer | null;

  constructor() {
    this.observeResize = null;
  }

  resizeWindow() {
    window.addEventListener('resize', () => {
      if (this.observeResize) {
        clearTimeout(this.observeResize);
        this.observeResize = null;
      }
      this.observeResize = setTimeout(() => {
       // 処理を書く
      }, 200);
    }, false);
  }
};

export default Sample;
```

## 参考サイト

- [TypeScriptで document.getElementById("hoge").value をすると出るThe property ‘hoge' does not exist on value of type 'HTMLElement' というエラーを解消する](https://qiita.com/Sekky0905/items/a88721f2af41050c93f2)
- [type 'NodeListOf<HTMLLIElement>' is not assignable to type 'Element[]'](https://stackoverflow.com/questions/42943071/type-nodelistofhtmllielement-is-not-assignable-to-type-element)
- [TypeScriptのコード内でのsetInterval()の返り値には罠がある
](https://blog.kubosho.com/entry/setinterval-trap-on-typescript/)
material-ui <Grid item xs={false}> なのに消えなくて少しハマった

##少しハマったところ
material-ui のGridで、xsサイズよりも小さくなったら非表示にしたかった。
最初xs={0}と書いていて何も変わらず、ドキュメントを見に行って　0はダメで、falseの値が書いてあったので、それを使うのかな？って少し苦戦していました。
https://material-ui.com/api/grid/

```javascript

    <Grid container>
      <Grid item xs={12} md={8}>
        here is a main text ......
      </Grid>
      <Grid xs={false} md={4}>
          ここをxsより小さい時は非表示にしたい
      </Grid>
      <Hidden smUp> pop up</Hidden>
    </Grid>
```
このようにしてもうまく行きませんでした。
ドキュメントを見てもfalseは普通に存在してるしうーん..?となっていました。

##解決
解決策は普通に検索していたら見つかりました。
https://material-ui.com/api/hidden/

```javascript

    <Grid container>
      <Grid item xs={12} md={8}>
        here is a main text ......
      </Grid>
      <Hidden xsDown>
        <Grid md={4}>
         これでxsより小さい時は非表示になる
      　</Grid>
      </Hidden>
    </Grid>
```

これで無事解決しました。
おそらく旧バージョン（？）の書き方を無意識にしていて、
xs={0}　を試してもうまくいかないし..ってなって困っておりました
ドキュメントにあるfalseはどういう使い方をするのだろう..?勝手に騙されました笑
IPアドレスからPC名を特定するコマンド(メモ)

### nbtstatコマンドで検索できる


    $>nbtstat -A xxx.xxx.xxx.xxx

           ノード IP アドレス: [自分のIP] スコープ ID: []

           NetBIOS リモート コンピューター ネーム テーブル

       名前               種類         状態
    ---------------------------------------------
    [相手のPC名]     <00>  一意          登録済
    WORKGROUP        <00>  グループ        登録済

    MAC アドレス = yy-yy-yy-yy
【機械学習】データリストを生成するWindowsコマンド【備忘】

# はじめに
Yoloのデータリストを作成しようとしたとき、
そういえばWindowsのfindコマンドってなんだろうと思い調べました。

# dirコマンド
一番覚えやすそうなコマンド。
拡張性はないが簡単に使うだけなら十分。

```
> dir /s /b data\img\*.jpg

C:\Users\User\Documents\data\img\cat_1.jpg
C:\Users\User\Documents\data\img\cat_2.jpg
C:\Users\User\Documents\data\img\cat_3.jpg
.....
```

# whereコマンド
検索パターンに一致するファイルの場所を表示するコマンド
明示的にディレクトリを指定しないとPATH(環境変数)直下も検索検索対象になる上、
明示的にディレクトリを指定する場合、再帰的に検索が走る。
使いにくい。

```
> where /r .\data *.jpg

C:\Users\User\Documents\data\img\cat_1.jpg
C:\Users\User\Documents\data\img\cat_2.jpg
C:\Users\User\Documents\data\img\cat_3.jpg
.....
```

# forfilesコマンド
条件に当てはまるファイルを指定ディレクトリから探し、処理を行うコマンド
・[ドキュメント](https://docs.microsoft.com/ja-jp/windows-server/administration/windows-commands/forfiles)

オプションも多く拡張性が高い。
覚えにくいが使いこなせれば色々できそう。
パスをそのまま出力しようとするとダブルクォーテーションが付いてしまう。

```
> forfiles /p .\data\img /s /m *jpg /c "cmd /c echo @path"

"C:\Users\User\Documents\data\img\cat_1.jpg"
"C:\Users\User\Documents\data\img\cat_2.jpg"
"C:\Users\User\Documents\data\img\cat_3.jpg"
.....
```

## 相対パスで欲しい
forfilesコマンドで、パス名ではなくファイル名のみを取得、
それを出力部分でくっつけたいパスと結合、力業。。

```
> for /f %i in ('forfiles /p .\data\img /s /m *jpg /c "cmd /c echo @file"') do @echo data\img\%~i

data\img\cat_1.jpg
data\img\cat_2.jpg
data\img\cat_3.jpg
.....
```

### ファイルに起こす場合は
追記を使う。
forで回しているので、ただ標準出力をリダイレクトすると最後の一行しか残らない。

```
> for /f %i in ('forfiles /p .\data\img /s /m *jpg /c "cmd /c echo @file"') do @echo data\img\%~i >> train.txt
```
ShellScript で例外処理を実装

ShellScript で例外処理　を実装する機会があったのでまとめます。

##「||」　OR制御演算子を使って例外処理を実装

```
#!/bin/bash

function try() {
    //実行する
    php ./test.php
    return 1
}

function error() {
    # エラーの際に実行する。
    php ./errorhandle.php
    exit 1
}

try || error
```

##ShellScriptを実行
```
sh ファイル名.sh
```

以上