OmniAICreator/Qiita-1.07M huggingface dataset:
最前面のViewを検出・参照する[Swift]

## 状況
最前面の`ViewController`を取得する記事はたくさんあるけど
`View`に関しては見つからなかったので僕なりのやり方を残しておきます

## 対策
`GirlsView`はcustomViewです

#### 流れ
`frontView`に存在するViewのなかで最後に配置したView(最前面のView)を入れておく->右スワイプする->ViewとViewの配列を消去する
Viewを配置するたびに`zPosition`を上げている->　**最後に配置したView = 最前面のView** になります

```swift
private func setSwipe(girlsView: GirlsView) {
        let rightSwipe = UISwipeGestureRecognizer(target: self, action: #selector(didSwipe(sender:)))
        rightSwipe.direction = .right
        girlsView.addGestureRecognizer(rightSwipe)
}
    
@objc func didSwipe(sender: UISwipeGestureRecognizer) {
        if sender.direction.contains(.right) {
            print("Right!")
            getFrontView().removeFromSuperview()
            girlsViewArray.removeLast()
        }
}

private func getFrontView() -> GirlsView {
        var frontView: GirlsView?
        Array(0..<girlsViewArray.count).forEach {
            if let view: GirlsView? = girlsViewArray[$0] {
                frontView = view!
            }
        }
        return frontView!
    }
```

```swift
override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        
        Array(0..<girlsViewArray.count).forEach {
            view.addSubview(girlsViewArray[$0]) //$0は0 ~ girlsViewArray-1
            girlsViewArray[$0].layer.zPosition = CGFloat($0) + 1.0
            setSwipe(girlsView: girlsViewArray[$0])
            //省略
        }
    }
```
【ブートストラップ法】標本平均の分散を評価してみる

# 背景
前回（[【ブートストラップ法】経験分布関数について数値計算を通して理解を深める](https://qiita.com/jajagacchi/items/86d13bb89051d16d3cea)）は経験分布関数について数値計算で理解を深めました。今回はいよいよブートストラップ法を試してみることにします。

# ブートストラップ法
ブートストラップ法は、未知の分布関数を経験分布関数で近似して統計的な推定を行う方法です。
経験分布関数からの乱数生成は、実は重複を許したリサンプリングになります（リサンプリングで作った標本をブートストラップ標本といいます）。これにより推定の安定性等を議論出来ます。

# 標本平均の分散を評価してみる
正規分布から$n$個の値を取り出し、母平均を推定することを考えます。この時問題になるのは標本平均の分散です。これについては$\sigma^2/n$となることを知っているので、母分散$\sigma^2$を不偏分散に置き換えれば推定することが出来ます。しかしもっと複雑な統計量については簡単にその分散を評価出来るとは限りません。やってみます。$\sigma^2=1$としました。

```c++
#include <random>
#include <iostream>

int main(int argc, char **argv)
{
	double m = 5;
	double s = 1;
	int n = 100;
	std::normal_distribution<> gauss(m,s);
	std::mt19937 mt(0);
	std::uniform_int_distribution<> u(0, n-1);

	std::vector<double> data(n);
	for (int i = 0; i < n; i++) data[i] = gauss(mt);
	double AV = 0;
	for (int i = 0; i < n; i++)
	{
		AV += data[i] / (double)n;
	}

	int B = atoi(argv[1]);//
	std::vector<double> avb(B);
	double av = 0;
	for (int b = 0; b < B; b++)
	{
		double sum = 0;
		for (int i = 0; i < n; i++)
		{
			double val = data[u(mt)];
			sum += val;
		}
		av += sum / (double)n;
		avb[b] = sum / (double)n;
	}
	av /= (double)B;
	double s2 = 0;
	for (int b = 0; b < B; b++)
	{
		s2 += (avb[b] - AV) * (avb[b] - AV);
	}
	std::cout << s2 / (double)(B-1) << std::endl;
	return 0;
}
```
結果を示します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520857/4c7da604-a0f4-1269-a9dd-cfcc0bffc331.png)
真の値は$\sigma^2/n=0.01$です。横軸は反復抽出の回数です。そこそこの値は出ていますが、ここから反復抽出の回数を増やしても真値に近づくわけではありません。経験分布関数を母分布と考えると、その分散$\hat\sigma^2$を標本サイズで割った値に近づきます。元のデータを増やせば経験分布関数が真の分布関数に近づくので精度がよくなります。

# 何が嬉しいのか
一般に統計量の期待値、分散の評価は手計算で簡単に出来るとは限りません。また、得られたデータの母分布の関数形が既知とも限りません。このような状況で母分布の関数形を仮定せず、手計算なしで統計量（推定量）の性質（不偏性や分散）の評価が出来そうです。
Google Apps ScriptでHappyou Final Scraperを中継してInoreaderで読む

あらゆるウェブページをRSSフィードに変換する[Happyou Final Scraper](https://happyou.info/fs/)という便利なものがあり愛用していたのですが、
かなり昔のあるときから[Inoreader](https://jp.inoreader.com/)からのアクセスが非常に遅くなり、タイムアウトになりRSSを取得できない状態が続いていました。

![failed.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62354/67146720-4cd3-9077-e49a-ee1f28594880.jpeg)

新規追加のときはタイムアウトが長いのか、かなり待てば追加されるのですが、普段の巡回はエラーに書いてあるように3秒以内に応答がなければ失敗扱いとなります。

原因はわからず、私の環境かHappyou Final ScraperとInoreaderの経路間の問題なのか不明で放置していたのですが、
一念発起して迂回スクリプトを書くことに。
普通のアクセスは高速なので、別のところで取得してそのままInoreaderに返せばよかろうとなりました。
ラムダとかでいいのですが簡単なGASで書きます。

```js
function doGet(e) {
  var URL = ''
  if (e.parameter.url) {
    URL = 'https://' + decodeURIComponent(e.parameter.url)
  } else {
    URL = 'https://www.happyou.info/fs/gen.php?u=1525577309&p=-453397430'
  }
  const res = UrlFetchApp.fetch(URL)
  return ContentService.createTextOutput(res.getContentText())
  .setMimeType(ContentService.MimeType.XML);
}
```

GETパラメーターで取得先のRSSURLを渡してあげて、fetchはGASで行いInoreaderにレスポンスを返す単純なアプリを公開します。

こうするとフェッチを加味してもInoreaderとGAS間の応答は3秒以内に収まるので、

![succsess.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62354/a0ad0b74-389c-32f4-a25c-ec655914964d.jpeg)

このようにInoreaderでHappyou Final ScraperのRSSが再び取得できるようになりましたとさ。めでたしめでたし。

URLを指定すると

`https://script.google.com/macros/s/fugafuga/exec?url=www.happyou.info%2Ffs%2Fgen.phphogehoge`


こんなかんじですね。
OneHotEndoderで冗長なダミー変数を減らす

#はじめに
scikit-learnのOneHotEncoderをそのまま使うと、カテゴリ変数の水準数分だけダミー変数が作られる。この場合、線形回帰手法などでは多重共線性が生じるため、ダミー変数を水準数－1に減らしたい。その方法を調べたのでメモっておく。

#環境
- scikit-learn 0.21.2

#方法
OneHotEncoderのdropオプションを"first"にすると、最初のダミー変数を除去してくれる

#やってみよう
ここでは以下のようなカテゴリ変数が格納された列を抽出してカテゴリ変数にしてみよう。

```
[['D']
 ['D']
 ['D']
 ['T']
 ['T']
 ['T']
 ['N']
 ['N']
 ['N']]
```

ソースは以下のとおりである。dropオプションを"first"にした場合、合わせてhandle_unknown='error'も設定しないと怒られる。

```python
from sklearn.linear_model import LinearRegression
from sklearn.preprocessing import OneHotEncoder
import numpy as np

def main():

    X = np.array([
        [1, "D"],
        [3, "D"],
        [5, "D"],
        [2, "T"],
        [4, "T"],
        [6, "T"],
        [1, "N"],
        [8, "N"],
        [2, "N"],
        ])
    y = np.array([2, 6, 10, 6, 12, 18, 1, 8, 2])

    # 2列目を取り出し
    category = X[:, [1]]
    print(category)
    encoder = OneHotEncoder(handle_unknown='error', drop='first')
    encoder.fit(category)
    result = encoder.transform(category)
    print(result.toarray())


if __name__ == "__main__":
    main()
```

#結果
drop='first'をつけない場合。

```
[[1. 0. 0.]
 [1. 0. 0.]
 [1. 0. 0.]
 [0. 0. 1.]
 [0. 0. 1.]
 [0. 0. 1.]
 [0. 1. 0.]
 [0. 1. 0.]
 [0. 1. 0.]]
```

drop='fist'をつけた場合

```
[[0. 0.]
 [0. 0.]
 [0. 0.]
 [0. 1.]
 [0. 1.]
 [0. 1.]
 [1. 0.]
 [1. 0.]
 [1. 0.]]
```

確かに最初の列が消えている。これでこころおきなくfitメソッドを呼び出すことができる。
実務経験無しでAWS SAA受かった話[2019/11時点]

# 経歴
実務ではWPF開発のみでAWS実務経験全く無し。
インフラ系の知識もほとんど無し。
AWSサービスはAlexaスキル作ってた時にDynamoDBやLambdaを使っていた程度です。

# きっかけ
受験を決意したのは以下の理由です。

- デブサミ等カンファレンスに行くとAWSサービスは当たり前のように出るので危機感。
- AWSサービスの知識があれば強いエンジニアの話がもっと楽しく聞けるのかも。
- 今後AWSを業務で関わる可能性があるかもしれない、でも業務が決まってから学ぶのは遅すぎるのでは。

# 勉強方法
教材をおすすめ順に並べておきます。

[これだけでOK！ AWS 認定ソリューションアーキテクト – アソシエイト試験突破講座（初心者向け21時間完全コース）](https://www.udemy.com/course/aws-associate/)
------------------------

AWSサービスを実際に使いながら受ける講座になっていて、実務経験無しで受けるならこの講座は必須ではないかと思うくらい充実しています。
講義の後に削除するリソースも教えてくれるので削除忘れも防げる親切っぷりです。
使ったことあるのとないのとでは思い出しやすさが全く違います。

特に冗長性の構成を実際に作ると試験問題を解いている時にイメージしやすくなりました。

模擬試験が3回も付いていて問題を解くことにも慣れることができます。3周しました。 

[AWS 認定ソリューションアーキテクト アソシエイト模擬試験問題集（5回分325問）](https://www.udemy.com/course/aws-knan/)
---------------------------
問題を解くことに慣れました。
新しいサービスに関する問題もあるので、上のUdemyの講座で補えなかった知識を覚えることができました。

こちらも3周してどの問題も覚えるまで解きました。
ただ上のUdemyの講義と同じ模擬試験が1つ入っているので、上の講義を買うと少し損した気分になります。

[AWS WEB問題集で学習しよう](https://aws.koiwaclub.com/)
---------------------
Udemy講義を受け終わって、サンプル問題をやってみたら思ったより取れなかったのでショックを受けて(試験2週間前に)会員登録しました。
降順で問題を解いていき、#87までと分野別問題集の所を一回解きました。今思うとかなり勿体ないですね。

問題自体は自分では覚えきれていないサービスが見えてきて復習に役立ちました。また、公式のリンクが貼ってあるので、公式の情報を見る機会が圧倒的に増えました。

[AWS BlackBelt](https://aws.amazon.com/jp/aws-jp-introduction/)
-------------------
不安だったIAM等のサービスを見てました。
自分は問題を解きながらの方が覚えやすいと思っていたので、あまり見ていなかったのですが、今思うともう少し見ておけば良かった勉強時間が減ったかなとも思います。

「公式の模擬試験」
----------------------
問題がどんな風か弱い分野はどこかが分かるので良いかと思いますが、答えが分からない、操作感が実際の試験と少し異なる(ピアソンVUEの場合)ので、注意が必要です。

下記はUdemy講座と黒本の模擬試験を2周した時に受けた結果です。
ギリギリ7割ですね、しかし差が酷い。

>総合スコア: 72%
トピックレベルスコア:
1.0  Design Resilient Architectures: 100%
2.0  Define Performant Architectures: 71%
3.0  Specify Secure Applications and Architectures: 50%
4.0  Design Cost-Optimized Architectures: 0%
5.0  Define Operationally-Excellent Architectures: 100%

「AWS認定　ソリューションアーキテクト　アソシエイト 教科書」
--------------------------
黒本と呼ばれてます。
演習問題と模擬問題が1つ付いているので、それを3周しました。本はほとんど読んでないです。

SAAの勉強をするにあたって一番最初に取り組んだのが、この本からだったのですが、読んでてもピンと来ず演習問題でボロボロだったのでUdemy講座にすぐ切り替えました。
実務経験無しでいきなりこの本は辛いと思います。  

因みに
-------------
期間は4か月で、勉強時間は100時間超です。
他の受験体験記に比べるとかなりかけすぎたのでもっと効率よく出来なかったかなと今思うと反省です。

# 本試験
他の方の受験体験記を見て「USキーボードでメールアドレス入力した」「英語でチャットする可能性がある」を見て覚悟して行ったのですが、JISキーボードでメールアドレスを入力することもなく、英語でのチャットもなかったです。

因みにピアソンVUEで受けました。他の試験でピアソンVUEを受けたことがあるのですが、その試験と流れはあんまり変わらなかったように思います。

試験内容は比較的にひねくれた問題はなく素直な問いが多かったと思います。
どういうときにどのサービスを使うのが最適か問う問題が多かったように思います。

# 反省と感想
- 実務経験無し＆インフラ知識ほぼ無しで一から覚えなければならず(記憶力がないのもあって)、周りの受験体験記と比べて勉強時間がかかりすぎた。受けるのが早かったのかもしれない。
- だらだら勉強してたので勉強時間が無駄にかかってしまった。休日は特に勉強するしないのメリハリ大事。
- 模擬試験だけでなく、BlackBelt等公式の情報も眺めておく方が知識が網羅できるのではと思うのでそうすべきだった。
- AWSサービスだけでなくインフラ周りの知識も少し増えた気がする。
- AWSサービスの使い方が分かって、500円/月かかっていたAlexaスキルの運用がほぼ0円に出来た！！！
[Adobe]ゲーム配信するためにしている自己研鑽

# はじめに
「ゲーム配信」がマイブームな私がしている自己研鑽について纏めてみました。
Adobe製品を利用して、YouTubeに趣味でゲーム配信することを前提とします。
これも1つの例として読んで下さい。

# ゲーム配信で利用しているツール
定番ですが、以下のAdobe製品を利用してます。

**Premiere（動画編集）**
**Aftereffects（少しこったモーション作成）**
**PhotoShop（サムネイル編集）**
**Animate（キャラクター編集）※今後、使用予定**

これらは単品で買うと高価ですが、私は「Creative Cloud」という月額のサブスクリプション契約で利用してます。Creative Cloudだと、全てのAdobe製品とAdobe fontsが利用できるので、がっつりAdobe製品を使いたい、勉強したい！という方は迷わず自己投資することをお勧め。
ちなみにCreative Cloudは、年契約および学生だと安くなるプランもあるので、興味がある方はぜひ調べてみて下さい。

Adobeは情報量が多く、ググれば大抵の事は解決できる点も初学者にはメリットです。
なお、ゲーム画面自体はWindows10に標準搭載されている「XBox Game Bar」でキャプチャしてます。

# ツールの学習方法について
私は2019年5月からMTG Arenaというカードゲームを始めて、その時にゲームだけするのではなく自分のスキルアップも兼ねて動画編集、映像制作もできるようになりたいと思い、そこから独学で始めました。

まずは当然ですが、各ツールでできることや使い方の基本操作を知る必要があります。
これは書籍でも良いのですが、私はUdemyというオンライン学習サービスを利用しました。
Udemyは定期的にセールをしており、そのタイミングを狙ってPremiere、Aftereffects、PhotoShopの講座を購入し、休日を利用して一気に基本操作を覚えました。
ただしこれだけではツールの基本操作を覚えて、せいぜい簡単なアニメーションを作るくらいしかできないので、この後は更に書籍を読みます。

私が読んで良かった本を2冊ほど、ご紹介します。

* Premiere Pro スーパーリファレンス

> Premiereの主要機能が丁寧に書いてあり、リファレンスとして便利です。
フレームレートやアスペクト比など、基礎知識が網羅されてる点も良し。

* Photoshop レッスンブック

> Photoshopのレベルがワンランクアップした気になれるほど、役立つ情報が盛りだくさん。

# YouTubeで学ぶ

次にYoutubeでチュートリアル系の動画配信をしている方がおり、その動画を参考にしてます。
主に私が拝見しているのは以下の4名で、どれも無料とは思えないほど素晴らしいチュートリアルです。

* [ダストマンTips](https://www.youtube.com/channel/UCDwwZiOLmFWV_YmOgAks5Ug/videos)
* [TORAERA DOUGA](https://www.youtube.com/channel/UCgHVDgwimLT5Z7cjJWFJfaw)
* [Action Planetあくしょんプラネット](https://www.youtube.com/channel/UCSmgxWssl8L45O6JCYb5NQA/videos)
* [動画っ校 by 那須裕介](https://www.youtube.com/channel/UCSmgxWssl8L45O6JCYb5NQA/videos)

こんな有意義な情報が誰でも見れる時代に感謝ですね。
全てチャンネル登録することをお勧めします。

後はプラスアルファで必要になったらググって調べる感じです。
纏めると、

* Udemyの講座
* 書籍
* YouTubeのチュートリアル
* ググる

こんな感じで独学してます。
1ヶ月程で、少しはゲーム配信っぽい動画制作ができるようになりました。
# サムネイルの作り方

次にサムネイルですが、ほとんどゲーム関連のサムネなので基本的にはゲーム画面をキャプチャしてます。
キャプチャはWindowsに標準搭載されている「Snipping Tool」で必要な個所だけ切り抜きます。

キャプチャした画像はそのままだと少し小さい（解像度が低い）場合もあり、そういう時はPhotoshopのディテールを保持して拡大をします。
この機能を使うことで、画像の解像度を極力落とさないように画像を拡大することができます（拡大しすぎると荒れますが）。

[ディテール保持の方法はこちらのサイトが分かり易いです。](https://www.ddc.co.jp/dtp/archives/20180412/143808.html)

Photoshopが使えない方は、以下のサイトでも解像度を保持したまま画像サイズを拡大することができます。
[waifu2x](http://waifu2x.udp.jp/)

後はいい感じに拡大した画像にテキストやらエフェクトやらをかけて、それっぽい画像に仕上げます。

# さいごに

以上が、私がゲーム配信するために実践した自己研鑽になります。
少しでも参考になれば幸いです。
【2019年版】使ってみてよかったiOSデバッグツール

## はじめに
- アプリ開発の中でデバッグは切っても切り離せない作業です。デバッグ作業の効率を高めるためのツールはたくさんあります。
たくさんのツールの中で使ってみてよかったものについてまとめてみました。
*あくまで個人的な意見です


## 第5位 SwiftyBeaver
####[SwiftyBeaver/SwiftyBeaver](https://github.com/SwiftyBeaver/SwiftyBeaver)⭐️4.5k
- 通信周りなどのログを表示できるツール。browserアプリを使うと便利です


## 第4位 KZFileWatchers
####[krzysztofzablocki/KZFileWatchers](https://github.com/krzysztofzablocki/KZFileWatchers)⭐️954
- localにあるファイルを参照できるデバッグツールです。mockデータで実際のアプリで取得可能になる

## 🥉第３位 LifetimeTracker
####[krzysztofzablocki/LifetimeTracker](https://github.com/krzysztofzablocki/LifetimeTracker)⭐️2.1k
- メモリーリークしているviewController,viewを検知できるツール
- リークしている事に気が付きやすくなるツールです

## 🥈第２位 FLEX
####[Flipboard/FLEX](https://github.com/Flipboard/FLEX)⭐️10.9k
- 便利機能が豊富に搭載されているユーティリティツール
- 特にレイアウトチェックや表示しているクラスの検索に便利

## 🥇第１位 iCimulator
####[YuigaWada/iCimulator](https://github.com/YuigaWada/iCimulator)⭐️80
- シミュレータでカメラ機能が使えるツール
- 是非とも標準機能で対応して欲しいです

## まとめ
- アプリ開発の中でデバッグの効率を上げるツールはたくさんある
- 様々なツールを見ながら、適切なものを選ぶことが重要である
ストレージシステムについて

#ストレージって何？
データの保存を行う装置のことで、いわゆる保存領域のことです。
企業などで運用される大型のストレージとそれを管理・運用しデータの保存などを行う一連のシステムを総称して「ストレージシステム」と呼びます。

#テープストレージ
DATやLTOなどの磁気テープをにデータを保存し運用を行うストレージシステムです。
実際のところはデータを保管するというよりもデータを保存した磁気テープを保管するという形で運用されている感じです。
テープさえ保管されていれば問題ないため保管場所が非常に小さくてよく、サーバーとはまったく別種の場所に保管しておける点もメリットです。
データの保管期間が非常に長く、LTOであれば30年以上保管しておけるものもあります。ランニングコストも非常に安いという利点もありますが、データの入出力を行う際にテープを専用の装置にセットする必要があり運用上の観点からもホットデータの運用には向かないという欠点もあります。

■長所
・データの保管期間が長い
・ランニングコストが安い
■短所
・ホットデータの運用に向かない

#オンライン（クラウド）ストレージ
他者が貸し出している保存領域に、主にインターネットを介してデータの保存を行うストレージシステムです。個人向けではOneDriveやDropBoxなどがありますが、法人向けのクラウドストレージサービスも提供されています。
サーバーの運用・維持管理の必要がないためコストが非常に安い点が大きな特徴です。
多くの人が様々な場所からデータを共有できる大きな利点もありますが、インターネットを介する都合上、機密性の高いデータを運用するには向かないという欠点があります。

■長所
・サーバーの運用、維持管理のコストが必要ない
・様々な場所から多くの人がデータを共有できる
■短所
・機密性の高いデータの運用に向かない


#RAIDストレージ
複数の磁気ディスクを一つの大きな保存領域として運用するストレージシステムです。
構成の仕方によってRAIDレベルというものがあり要件によって構成を柔軟に選ぶことができます。
信頼性、冗長性が非常に高い特徴を持ちますが運用に相応の設備が必要であり、管理・運用上の手間も大きいという点が欠点です。
■長所
・信頼性、冗長性が非常に高い
・構成を柔軟に選択できる
■短所
・設備、場所が必要でありコストが高い
・管理、運用上の手間が大きい

#ストレージシステムに関わるための知識
■ストレージシステムの知識
→ストレージシステムがどのような構造で成り立っているのか、どのように管理・運用されているかの知識が大切です。

■ネットワークの知識
→実は大半のストレージシステムはネットワークを介して　ストレージとつながっているため、設定などにネットワークの要素を要求されることが多いです。そのためネットワークの知識は非常に重要になってきます。
dotfiles入りのdockerコンテナができた

dotfilesアドベントカレンダー4日目の記事です(^^)

> この顔文字を使うのはおじさんだという指摘をどこかで見ました。。。私のことです。。

私のdotfilesは[こちら](https://github.com/IMOKURI/dotfiles)です。

dotfiles自体は至って普通の？dotfilesでして、

- パッケージをインストールしたり、
- Neovim(Vim)やGitをビルドしたり、
- dotfilesにリンクを張ったり、

するスクリプトがあったりするようなものです。

dotfilesはちょくちょく更新したくなるので、それがいざ使いたいときに動かないととても残念な気持ちになるので、テストしてます。

テストは、dockerコンテナを起動して、その中でdotfilesをインストールして、最後まで成功するか、というのを確認してます。

私はよく、社内Proxyのある環境でも作業するので、Proxyがある状況でもちゃんと動くかも、テストしてます。Proxy用のdockerコンテナも合わせて起動して、そのコンテナをProxyに設定する感じです。

こうしてテストしているうちに、このテストでできあがったコンテナをイメージにしておけば、いつでも開発環境のdockerコンテナが手に入るのでは？と思い、テストの最後に、DockerHubにイメージをpushするようにしました。

これで、開発環境はいくらでも使い捨てができます。作業に使うファイルはvolumeマウントしておけば消えてしまうこともありません。

なにかパッケージを試したくなったときも、わざわざ仮想環境を作る必要はありません。失敗したら、コンテナごと起動しなおせばよいのです。

最強の開発環境のできあがりです。みなさんもぜひお試しください。(^^)

---

(▽〃)｡oO（なお、私は、普段は使ってません。。）
クラウドも正直あやしい人向けのAWS概要（初心者向け）

## ■AWSとは
・Amazon Web Servicesの略
・様々なクラウドコンピューティングサービス（90種類以上）を提供
・ネット通販のAmazonの子会社がAWSを提供
・AWSはもともと本家Amazonのインフラを支えるために作られた
　（世界中からのアクセスに耐えるため）
　↓
　ここまで発展した良いサービスなら商売できそう
　→2006年7月に他社へのサービスとして公開

　↓

　＞＞できた＜＜


## ■クラウドについて
広義の意味ではサーバを借りること自体を「クラウド」ととらえる見方もありますが、
AWSが属するパブリッククラウドはその中でもかなり限定的です。
![スライド4.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540751/669680f7-88c6-f02a-7946-7c7e07df6972.png)
サーバを買うと「オンプレミス」
一台の一部だけ借りると「共用サーバ」：サーバの一部を間借り
一台まるごと借りると「（レンタル）専用サーバ」：物理的なサーバを一台専有
一台まるごと借りて仮想化すると「VPS」
※仮想化：一台の物理サーバを借りて、その中を仮想的に複数のサーバに見せかける
　　　　
その点、台数の概念がないのが「パブリッククラウド」
お金を出している限りは自由に増やしたり減らしたりできます。

## ■パブリッククラウドについて
AWSはクラウドコンピューティングサービス（パブリッククラウド）の提供を行っています。
クラウドコンピューティングサービスは大別すると3種類に分けられます。
・Saas：gmail、google Drive、SalesForceなど
・Paas：Google App Engine、App Cloudなど
・Iaas：GoogleのGCP（Google Compute Engine）、MicrosoftのAzureなど
![スライド5.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540751/a81a9df9-c5c9-14cf-b201-0ef1e6fed520.png)
AWSはIaasのEC2というサービスを軸に成長してきたので、
Iaasのイメージが強いのですが、実は90種類以上のサービスの中にはPaasやSaasの
領域のものも含まれていたりします。

## ■構成図サンプル
超シンプルなWeb三層構造をAWSで作るとこうなります。
![スライド6.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540751/9c458afc-e179-12a7-a6ee-551ec04719f4.png)
EC2：Webサーバ/APサーバ：Apache、Tomcat
RDS：DBサーバ：MySQLやOracle
一つのVPCを作成し、二つのアベイラビリティゾーンを中心にリソースを作成します。
※図のRegionはアベイラビリティゾーンの間違いです、すみません…
また、ELBとEC2冗長化で負荷分散・NatGateway・セキュリティグループを設置することでセキュリティ対策をはかっています。
ちなみに端っこにあるバケツはストレージのS3です。ログや静的コンテンツ、Sorry画面を格納できます。

## ■他のサービスとの組み合わせ
Ansible・JenkinsでEC2・RDSのMW・SW設定も可能です。
Ansibleは標準でAWSのモジュールが入っているので、直接リソースの設定ができます。
さらにJenkinsでは、Ansibleのコマンドやシェルを内蔵させたジョブを作り、
場合によってはGUI上からボタン一個で資材がリリース可能になったりするなど、
他のサービスと組み合わせることで構築速度はガンガンあげることができます。

## ■最後に
最初はとっつきにくくても便利なので、気軽にアカウント作ってAWS触ってみてください！
一年間は無料枠がありますので！
VS Code C/C++のデバッグでブレークできない時の対処法(macOS Catalina)

# VS Code C/C++のデバッグでハマった
macOS CatalinaでVS Codeを使ってC/C++のデバッグをしようとしたら、ブレークポイント設定してもちゃんと停止してくれなかったので、その時の対処法をメモしておく。

# デバッグ環境
Microsoft C/C++ for Visual Studio Code Extension

# 問題
1. ブレークポイントを貼る
<img width="561" alt="スクリーンショット 2019-11-30 22.28.57.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/391196/85c4aa1c-de2d-1899-ba7c-daedec3d3dc9.png">

2. debug開始する
<img width="276" alt="スクリーンショット 2019-11-30 22.31.29.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/391196/fcbd01d5-b783-9568-1e05-7ebee87da245.png">

3. ブレークで停止せずにプログラムが終了する

```diff:DEBUG&nbsp;CONSOLE
=thread-selected,id="1"
@"hello world\r\n"
The program '/Users/MyHome/gitlab/pazdora/a.out' has exited with code 0 (0x00000000).
```

# 解決方法
以下に対処法があった
[GitHub : Can't debug on macOS Catalina (LLDB) #3829] (https://github.com/microsoft/vscode-cpptools/issues/3829)
macOS Catalinaでのバグらしいが、EXTENSIONSのCodeLLDB使えばOKとのことらしい。

# 設定
1. EXTENSIONSのCodeLLDBをインストールする
<img width="344" alt="スクリーンショット 2019-11-30 22.18.50.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/391196/d35c90de-73f4-704b-b66c-1a6f75e474cb.png">

2. launch.jsonの"type"を"cppdbg" -> "lldb"に変える

```diff:launch.json
{
    // Use IntelliSense to learn about possible attributes.
    // Hover to view descriptions of existing attributes.
    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "name": "(lldb) 起動",
-           "type": "cppdbg",
+           "type": "lldb,
            "request": "launch",
            "targetArchitecture": "x86_64",
            "program": "${workspaceFolder}/a.out",
            "args": [],
            "stopAtEntry":true,
            "cwd": "${workspaceFolder}",
            "environment": [],
            "externalConsole": false,
            "MIMode": "lldb"
        }
    ]
}
```

# 確認
1. Buildする(cmd + shift + b)
2. Debugモード(cmd + shift + d)
3. 上記と同じようにブレーク貼ってrun
4. ブレークできることを確認
<img width="852" alt="スクリーンショット 2019-11-30 22.41.36.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/391196/98605b16-a7c5-8c82-4e3f-0f44c84ae8ea.png">
UISwipeGestureRecognizerを使ったときにはまった(unrecognized selector sent to instance)

## 状況
`UISwipeGestureRecognizer`を使ったとき

```
unrecognized selector sent to instance
```
がで続けてハマったのでメモ。ちなみにハマったときに書いてたコードが以下。(一部簡略化してます)

```swift
private func setSwipe(girlsView: GirlsView) {
        let rightSwipe = UISwipeGestureRecognizer(target: self, action: "didSwipe:"))
        rightSwipe.direction = .right
        girlsView.addGestureRecognizer(rightSwipe)
}
    
private func didSwipe(sender: UISwipeGestureRecognizer) {
        if sender.direction.contains(.right) {
            print("Right!")
            getFrontView().removeFromSuperview()
            girlsViewArray.removeLast()
        }
}
```

## 対策
調べると`action`の関数名書くところに`:`をつけなきゃダメとかあったのですがうまくいかず
`@objc`にして`#selector`で囲ったらうまく行きました(addTargetと同じやり方ですね)

```swift
private func setSwipe(girlsView: GirlsView) {
        let rightSwipe = UISwipeGestureRecognizer(target: self, action: #selector(didSwipe(sender:)))
        rightSwipe.direction = .right
        girlsView.addGestureRecognizer(rightSwipe)
    }
    
@objc func didSwipe(sender: UISwipeGestureRecognizer) {
        if sender.direction.contains(.right) {
            print("Right!")
            getFrontView().removeFromSuperview()
            girlsViewArray.removeLast()
        }
}
```

## 参考
**・[ios – SpriteKitとUISwipeGestureRecognizer - コードログ](https://codeday.me/jp/qa/20190827/1553795.html)**
**・[ios - UITapGestureRecognizer unrecognized selector sent to instance - Stack Overflow](https://stackoverflow.com/questions/25021571/uitapgesturerecognizer-unrecognized-selector-sent-to-instance)**
**・[UISwipeGestureRecognizerの罠と左右スワイプの実装 - Qiita](https://qiita.com/kentarohorie/items/71dddd6f2ea96fa00b39)**
Power Automate における SharePoint Onlnie のカスタムクエリからリストを取得する際のフィルターは文字列の演算子を使う

# 記事作成に至った経緯
- Power Automate で SharePiont Online のカスタムリストからレコードを取得する際に、フィルターの演算子がよくわからなかったので調べました。
- 「StartDate <= '2019-12-03' and EndDate >= '2019-12-03'」で範囲内を判定してフィルターできるかな？と思ったらエラーになった。
- どうやったら範囲指定で検索できるのか調べてみるものの、なかなか該当する記事が見つからず、英語のコミュニティを検索すると見つかったので、自分の備忘もかねてQiitaに投稿することにしました。
- 初心者向けです。上級者の方にとっては当たり前のように使われているかもしれないので、大した内容ではないです。

# 環境
- Power Automate (旧 Microsoft Flow) for Office 365

# 参考にしたサイト
- [Microsoft Power Automate Community(SharePoint Flow Find Items with Date Less than or Equal to today)](https://powerusers.microsoft.com/t5/Building-Flows/SharePoint-Flow-Find-Items-with-Date-Less-than-or-Equal-to-today/td-p/255779)
- [SharePoint REST 要求で OData クエリ操作を使用する(SharePoint REST サービスでサポートされる OData クエリ演算子)](https://docs.microsoft.com/ja-jp/sharepoint/dev/sp-add-ins/use-odata-query-operations-in-sharepoint-rest-requests#odata-query-operators-supported-in-the-sharepoint-rest-service)

# Odataクエリ(フィルタークエリ)では、演算子はテキストで行います。
- =(イコール) → eq
- >(ｘｘより大きい) → gt
- <(ｘｘより小さい) → lt
- >=(ｘｘ以上) → ge
- <=(ｘｘ以下) → le

# まとめ
- 結果を言うと、文字列の演算子をちゃんと理解していなったという単純な理由なだけですが、私みたいな初心者は意外と引っかかるのではないかなと思っています。
- SharePoint Online のコネクタは、SharePoint REST API または Graph API と同等であると思われる、これらのドキュメントを参照したほうが答えが見つかりやすいです。（内部的には Graph API かな？）
- NG「StartDate <= '2019-12-03' and EndDate >= '2019-12-03'」
- OK「StartDate le '2019-12-03' and EndDate ge '2019-12-03'」
WSL1からWSL2に乗り換える

WSL1はlinuxエミュだけどWSL2はlinux kernelそのものが載るらしいので期待しつつ、[Microsoft公式ページ](https://docs.microsoft.com/ja-jp/windows/wsl/wsl2-install)を参考にしてインストールする。

## 環境
- エディション　Windows 10 Pro
- バージョン　　1809

## Windowsのバージョン確認
> ＜公式引用＞
> WSL 2 は、Windows 10 ビルド18917以降でのみ使用できます。

ということで、まずはWindowsのバージョンを調べる。

### 確認手順
コマンドプロンプトで下記コマンドによりバージョン確認。

```cmd
> ver
Microsoft Windows [Version 10.0.17763.864]
```

自分の環境は古かったので、まずはWindowsのバージョンアップを行う。

## Windowsのバージョンアップ
現時点の最新版は1909だが、トラブルがあると嫌なので少し前のバージョン(1903)を入れる。
[Microsoftの1903Updateページ](https://www.microsoft.com/ja-jp/software-download/windows10)にアクセスし、「今すぐアップデート」ボタンを押下。

アップデート後、ビルド番号は18363.476だった。
1909にしてみたけどビルド番号が変わらず、条件が満たせない…。うーん…

よく調べてみると、どうもPreview Buildをインストールする必要があるらしいので、それをインストールする。

デスクトップ左下のWindowsマークを左クリックし、[設定]→[更新とセキュリティ]→[Windows Insider Program]を選択。
スロー(推奨)にして、[設定]→[更新とセキュリティ]→[Windows Update]を行う。

確認するとビルド19033.1(>18917)となっていた。

```
> ver
Microsoft Windows [Version 10.0.19033.1]
```

## 仮想マシンの有効化
管理者モードでPowerShellを起動し、下記コマンドを実行。
実行後に再起動する。

```
Enable-WindowsOptionalFeature -Online -FeatureName VirtualMachinePlatform
```

## WSL2にする
管理者モードでPowerShellを起動し、下記コマンドを実行。

```
wsl --set-version Ubuntu-16.04 2
```
「変換中です。この処理には数分かかることがあります...」とメッセージが出るけど、数分どころか15分くらい処理が返ってこなかった(;´Д\`A ```
「変換が完了しました。」と出たら終了。

規定のアーキテクチャをWSL2にしておく。

```
wsl --set-default-version 2
```

WSL2になっていることを確認する。

```
> wsl -l -v
  NAME            STATE         VERSION
* Ubuntu-16.04    Stopped       2
```
kerasでVGG16のpoolingの私的メモ

#VGG16の引数`pooling`

```python
keras.applications.vgg16.VGG16(include_top=True, weights='imagenet', input_tensor=None, input_shape=None, pooling=None, classes=1000)
```

引数に`pooling`というのがある。
>pooling: 特徴量抽出のためのオプショナルなpooling mode，include_topがFalseの場合のみ指定可能．
・None：モデルの出力が，最後のconvolutional layerの4階テンソルであることを意味しています．
・'avg'：最後のconvolutional layerの出力にglobal average poolingが適用されることで，モデルの出力が2階テンソルになることを意味しています．
・'max'：global max poolingが適用されることを意味します．
>引用：https://keras.io/ja/applications/

`pooling='None'`の場合、出力が4階テンソルとなる。要は4次元のデータとなる。この場合、

```python
conv_base = VGG16(weights='imagenet', include_top=False, input_shape=(150,150,3))
 
model = models.Sequential()
model.add(conv_base)
model.add(layers.Flatten())
model.add(layers.Dense(256, activation='relu'))
model.add(layers.Dense(1, activation='sigmoid')) 
```
このようにflattenを用いて全結合をしないといけない。
それに対して、`pooling='avg'またはpooling='max'`のときは、

```python
conv_base = VGG16(weights='imagenet', include_top=False,pooling='avg', input_shape=(150,150,3))
 
model = models.Sequential()
model.add(conv_base)
model.add(layers.Dense(1, activation='sigmoid')) 
```
`global average pooling`によって全結合のようなものが行われるため、`flatten`はいらない。

#参考
https://keras.io/applications/#vgg16
https://qiita.com/mine820/items/1e49bca6d215ce88594a
【Laravel】Redirect時にトレイリングスラッシュが入った状態で遷移させる方法

Laravelでredirect()->to('/create/')のようにトレイリングスラッシュをつけた状態でリダイレクトさせても、「/create」のようにトレイリングスラッシュが消えた状態のURLが生成されてしまいます。
これは、UrlGeneratorクラスのtoメソッドのコードを見ればわかるのですが、第一引数に相対パスで入力されたものに対しては、スラッシュがtrimされるからです。
そこで、トレイリングスラッシュを付けた状態でリダイレクトさせる方法を２つご紹介します。
# 方法①：絶対パスでわたす
相対パスでだめなら絶対パスで渡しましょう！
例えば、以下のようにすればトレイリングスラッシュが入った状態で遷移されます。

```
return redirect()->to(config('app.url').'create/')
```
# 方法② 末尾スラッシュをエスケープする
末尾スラッシュをエスケープすることでtrimされる対象から外しましょう！
例えば、以下のような実装になります。

```
return redirect()->to('/create\/');
```
Raspberry Pi 4 Model B セットアップ

#1.用意したもの

参考にさせて頂いた
[Raspberry Pi 3 Model B+の初回セットアップ（購入から起動まで） - Qiita](https://qiita.com/Higemal/items/c817b96c3806f23b35f6)
の「準備1. Raspberryと周辺機器の準備」の書き方に合わせています。

|必須/あれば|デバイス|価格|備考|
|---|---|--:|---|
|必須|Raspberry Pi 4 Model B| 5,997円＋送料450円|RSオンラインで購入。技適対応版|
|必須|電源5V3A|約3,000円|家にあった|
||Raspberry Pi 4用オフィシャルケース|1,885円|Amazonマーケットプレイスで購入|
|必須|USB Type A-Cケーブル|約1,000円|家にあった。C-CでもOKのはずだけど技適対応版でないものはPDバグとかeMaker対応ケーブルが使えないという話がある|
|必須|キーボード|約1,000円|家にあった|
||マウス|約1,000円|家にあった|
||LANケーブル|約500円|家にあった。Wi-Fiでもいける|
|必須|microHDMI-HDMIケーブル|約1,000円|家にあった|
|必須|microSDカード Samsung EVOPlus 128GB|2,928円|Amazonで購入|
||カードリーダー BUFFALO BSCR27U3BK|約1,000円||
|必須|ネットに繋がったPC|うん万円||

#2.セットアップ

[Raspberry Pi 3 Model B+の初回セットアップ（購入から起動まで） - Qiita](https://qiita.com/Higemal/items/c817b96c3806f23b35f6)
の「準備3. SDカードにOSデータを配置」～「作業3. 初期設定」とだいたい同じことをしました。セットアップ時、液晶モニタに映すため、「オーバースキャン」を有効(初期値)から無効に変更してデスクトップ周りの黒枠をなくしました。しかし、その後画面端の表示が欠ける液晶テレビに繋ぎ変えたため、有効に戻しています。

microSDのFAT32フォーマットは、バッファローのDisk Formatterを使用しています。
最近のバージョンだとベンダーチェックがあるそうですが、バッファローのカードリーダーを使用したので問題ありませんでした。

但し、Raspberry Pi起動時に、「Error resizing existing FAT partition」のエラーが出ました。
![20191130.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/534247/a499f976-3782-0099-5e5b-01406ac38a7a.png)
・ボリュームラベル名に RASPBERRYPIを設定
→効き目なし
・Disk Formatterで物理フォーマット(これもする必要なさそう)
→ゴリゴリ鳴っているのを十数分待つと、ライトプロテクトされているというエラー
→管理者モードでdiskpartを実行して、microSDのドライブをclean
→フォーマットとファイルコピーし直し
でうまくいきました。最初からdiskpartをしておいたらやり直さなくて済むのではないかと思います。

参考：
[Raspberry Pi向けに64GB以上のmicroSDをFAT32にフォーマットする@windows7 - Qiita](https://qiita.com/Higemal/items/2034ef9f772416b4dbb7)
[DIYer Raspberry Pi を 128 GB の SD カードでセットアップする](http://twinklesmile.blog42.fc2.com/blog-entry-77.html)

#3.IPアドレス設定

eth0のIPアドレスを設定しました。

[この通りやれば出来る！Raspberry PiのIPアドレス固定化からSSHによるWindowsからのリモート接続の設定: ゆるガジェCHANNEL](http://yurugadge-channel.com/article/185920110.html)

#4.Wi-Fi無効化

うちは有線のみで使用するため、下記のページを参考にしてWi-Fiを無効化しました。

[raspberry pi のwifiを無効化する方法 - Qiita](https://qiita.com/hayate242/items/4f3d07d63a5b9577cb55)

#5.ssh有効化

[WindowsとRaspberry Piの間で簡単にファイル転送・フォルダ同期するには](https://denor.jp/windows%E3%81%A8raspberry-pi%E3%81%AE%E9%96%93%E3%81%A7%E7%B0%A1%E5%8D%98%E3%81%AB%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E8%BB%A2%E9%80%81%E3%83%BB%E3%83%95%E3%82%A9%E3%83%AB%E3%83%80%E5%90%8C%E6%9C%9F)

#6.xrdpのインストール

うちはVNCでなくリモートデスクトップクライアントで操作するため、xrdpをインストールしました。

[Raspberry PiをWindowsPCから操作する方法　【CUI・GUI】 - Qiita](https://qiita.com/SSAS3/items/31ea8def8c25ca86af9a)
Qiitaでの技術系の記事の書き方

###テスト
##目的
下記の3つの理解が目的（これは個人的な記事）
1.数式の書き方
2.Qiitaの記事の書き方
3.「2.」で理解した書き方により、pythonコードを添付

##数式の書き方
Qiitaでの数式の書き方はtexの書き方で、
$$の間に、e^{i\theta}=\cos{\theta}+i\sin{\theta}を書けば、

$e^{i\theta}=\cos{\theta}+i\sin{\theta}$

このように数式が書ける。

texの数式の書き方は以下を参照。
http://www1.kiy.jp/~yoka/LaTeX/latex.html

##Qiitaでの書き方
以降の書き方は下記のページを参考。
https://qiita.com/shizuma/items/8616bbe3ebe8ab0b6ca1

上記の添付より学んだことを活かして、以下のようにプログラムのソースコードを書いた。
内容は、「数値誤差」について。

##数値計算と誤差
数値計算する上で、避けることができないのが数値誤差である。
以下に代表的な数値誤差の例を一覧で示し、pythonコードで検証してみる。
検証例は「桁落ち」のみ示す。

|項目|説明|
|:--:|:--|
|桁落ち|値のほぼ等しいもの通しを減算するなどして、有効数字失われるなどによって生じる誤差。<br>例：$\sqrt{x+1}-\sqrt{x}$<br>下にpythonのプログラムで試行してみたので参考に。|
|丸め誤差|有限桁数の2進数で実数を表現することにより生じる誤差。<br>例：10進数での0.1$\longrightarrow$2進数では0.0001100110011$\cdot\cdot\cdot$|
|情報落ち|絶対値の大きく異なる数値同士の演算において、絶対値の小さな数値が演算に結果に反映されないために生じる誤差。<br>例：$10^{10}+10^{-8}+10^{-8}\cdot\cdot\cdot$|

###桁落ち検証
>$\sqrt{x+1}-\sqrt{x}=\frac{1}{\sqrt{x+1}+\sqrt{x}}$
とすることで数値計算上の桁落ち誤差を回避できる。

pythonを用いて実行してみる。
version:3.6.4
>pythonは下記よりインストールする。
https://www.python.org/downloads/

PC環境：windows10(64bit)
コマンドプロンプトで以下を打てば、test.py(下に示すコード)を実行できる。

```
python test.py
```


```python:test.py
import math
#main program
#case1:x=1e15
print("x=1e15の場合")
x=1e15
res_a=math.sqrt(x+1)-math.sqrt(x)
res_b=1/(math.sqrt(x+1)+math.sqrt(x))
#output result
print("通常通り計算した場合：",res_a)
print("式変形した場合：",res_b)

#case2:y=1e16
print("y=1e16の場合")
y=1e16
res_a=math.sqrt(y+1)-math.sqrt(y)
res_b=1/(math.sqrt(y+1)+math.sqrt(y))
#output result
print("通常通り計算した場合：",res_a)
print("式変形した場合：",res_b)
#end python
```
###結果
```
x=1e15の場合
通常通り計算した場合： 1.862645149230957e-08
式変形した場合： 1.5811388300841893e-08
y=1e16の場合
通常通り計算した場合： 0.0
式変形した場合： 5e-09
```
>値の差が小さいもの同士(case1の場合)での減算は通常通り計算すると0になってしまう。
式変形した場合は値が出力される。
この例のように、値の差が小さいもの同士での減算は避けるべきである。

###参考文献
[Pythonによる数値計算とシミュレーション](https://www.amazon.co.jp/Python%E3%81%AB%E3%82%88%E3%82%8B%E6%95%B0%E5%80%A4%E8%A8%88%E7%AE%97%E3%81%A8%E3%82%B7%E3%83%9F%E3%83%A5%E3%83%AC%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3-%E5%B0%8F%E9%AB%98%E7%9F%A5%E5%AE%8F-ebook/dp/B079L18P3T/ref=pd_sim_351_1?_encoding=UTF8&psc=1&refRID=5R67DCHA983SG0YYASK8)
構造体(Struct)のViewを配列にしてみる[Swift] - vol.2(データ挿入・表示まで)

# データ型Structの用意

- Tinderなどのプロフィールにあるデータをプロパティとして用意
- initで初期化

```Girls.swift
import UIKit

struct Girl {
    var name: String
    var age: String
    var type: String //職業など(ex. 学生, OLなど)
    var distance: String
    var image: UIImage
    
    //初期化 //Girl(name: String, age: String, type: String, distance: String, image: UIImage)という感じでインスタンスにして使う
    init(name: String, age: String, type: String, distance: String, image: UIImage) {
        self.name = name
        self.age = age
        self.type = type
        self.distance = distance
        self.image = image
    }
}
```

# Viewに代入

### 配列を用意

```swift

var girlsData: [Girl] = [] //初期化してからの配列

private func setGirlsInfo() {
        //データをセット
        girlsData.append(Girl(name: "あや", age: "18", type: "学生", distance: "6 km", image: UIImage(named: "aya.png")!))
        girlsData.append(Girl(name: "マイカ", age: "25", type: "OL", distance: "2 km", image: UIImage(named: "maika.png")!))
        girlsData.append(Girl(name: "emi", age: "40", type: "パート", distance: "56 km", image: UIImage(named: "emi.png")!))
        girlsData.append(Girl(name: "みゆ", age: "21", type: "大学生", distance: "10 km", image: UIImage(named: "miyu.png")!))
        girlsData.append(Girl(name: "リンゴ", age: "29", type: "事務", distance: "16 km", image: UIImage(named: "ringo.png")!))
}

override func viewDidLoad() {
        super.viewDidLoad()
        setGirlsInfo()
}
```

### Viewに配列の要素を代入

```swift
//girlsViewの要素にGirlのインスタンスの各要素を代入
private func setDataToGirlsView(girlsView: GirlsView, index: Int) {
        girlsView.nameLabel.text = girlsData[index].name
        girlsView.ageLabel.text = girlsData[index].age
        girlsView.typeLabel.text = girlsData[index].type
        girlsView.distanceLabel.text = girlsData[index].distance
        girlsView.girlsImageView.image = girlsData[index].image
}

override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        
        Array(0..<girlsViewArray.count).forEach {
            //省略
            view.addSubview(girlsViewArray[$0]) //$0は0 ~ girlsViewArray-1
            //省略
//girlsViewArrayの各要素にGirlのインスタンスを代入
            setDataToGirlsView(girlsView: girlsViewArray[$0], index: $0)
            //省略
        }
}
```

## 完成図
<img width="375" alt="girlsView-ex.jpeg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427937/be1b497c-f7e1-d958-ae10-a5fa6c660883.jpeg">

完成したらgithubに後ほどリンク載せます

## 参考
**・[Swiftで構造体を配列で扱う方法 | Swift4 Web入門書](https://swift.tecc0.com/?p=309)**
フォントサイズの異なるUILabelの下を揃える[Swift]

## 状況
UILabelにおいて、フォントサイズが異なると、上下の余白が異なるため
制約でbottomを揃えても文字の下が揃わないことがあります。

## 対策
- 揃えたいUILabel高さの制約を0以上にする
`height`を0にし、`Greater Than Or Equal`にする
- 制約で`Baseline`を揃える(`First`でも`Last`でも良い)
`bottom`ではなく`Baseline`を揃える

## 完成図
リンゴと29がきちんと下揃えされている。

<img width="375" alt="girlsView-ex.jpeg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/427937/f0c34515-abb6-a8e7-05b4-8f0997b424c2.jpeg">


## 参考
**・[iPad - 違うフォントサイズのUILabelを複数、横に並べて下揃えしたい｜teratail](https://teratail.com/questions/31049)**
Django Tutorialを始める　1

# 何をやったか

公式のDjango Tutorialの通りにアプリを作る
https://docs.djangoproject.com/ja/2.2/intro/tutorial01/

# 環境

* Windows 10 Pro
* Python 3.7.5
* Django 2.2.5
* conda 4.7.12

# Djangoのインストール

Anacondaで仮想環境にDjangoをインストールした。

```
> conda install django

> python -m django --version
2.2.5
```

# プロジェクトの作成

Django公式によると

>初めて Django を使うのなら、最初のセットアップを行う必要があります。通常は、 Django の プロジェクト (project) を構成するコードを自動生成します。プロジェクトとは、データベースの設定や Django 固有のオプション、アプリケーション固有の設定などといった、個々の Django インスタンスの設定を集めたものです。

早速プロジェクトを作る。

```
> django-admin startproject mysite
```

作ったプロジェクトを起動する。

```
> cd mysite
> python manage.py runserver
```

この状態で http://localhost:8000 にアクセスする。

![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/226452/1e7952ff-7bb1-bf0f-5ae7-3f9efd114495.png)

とりあえずDjangoがちゃんと今の環境で使えそうということは分かった。
Slack通知用のコマンドを作ってみた

#動機
　コマンドラインで時間のかかる処理を行う際に通知が来るようになれば時間の節約にもなり便利だなぁ、と思って実装してみました。

#手順
　１　Slackの「＋アプリを追加する」から「incoming-webhook」を追加する
　２　「Appディレクトリで確認する」などから設定に飛び通知を行いたいチャンネルを選択してWebhook URLをコピー
　３　先ほど取得したURLに対してPOSTリクエストでjson形式のpayloadを送信

今回はcurlコマンドを使ってPOSTリクエストを送ります。
#コード
　実装には以下の記事を参考にしました
・[シェルスクリプトでSlackに通知を送る方法](http://vdeep.net/shellscript-slack)
・[curlコマンドによるデータ送信あれこれ](https://www.wagavulin.jp/entry/2015/10/18/060938)

```shell
$ curl -sS -X POST --data-urlencode "payload={\"text\":\"message\",\"channel\":\"#channel\",}" {webhook_url} 
```
これで基本的にはメッセージを送ることができるのであとはコマンドライン引数でメッセージを指定できるようにすればいいので

```shell
#!/bin/sh

set -eu

message=$1
webhook="https://webhook.webhook"
channel=${CHANNEL:-'#notify'}
botname=${BOTNAME:-'notify-bot'}

payload="payload={\"channel\":\"${channel}\",
    　　　　　　　　\"username\":\"${botname}\",
    　　　　　　　　\"text\":\"${message}\"
　　　　　　　　　　　}"

curl -s -S -X POST --data-urlencode "${payload}" ${webhook}  > /dev/null
```

#参考
　今回はslackへの通知コマンドを作成しました。
　既に結構な人が似たようなことをやっていたようなので比較的簡単に実装できました。
Nuxt.jsのローカルサーバーでhttps使う

 なんやかんやでオレオレ証明書作成する


nuxt.config.js
<pre>  
server: {
    https: {
      key: fs.readFileSync(path.resolve(__dirname, 'server.key')),
      cert: fs.readFileSync(path.resolve(__dirname, 'server.crt'))
    }
  }
</pre>


<pre>
npm run dev
</pre>
Haskell コマンドライン引数を数値にする

今回初めてHaskellでコーディングをしたのですが、「コマンドラインから受け取った引数を数値にする」でつまづきました
# コマンドラインからの引数は　IO String配列
@taashi さんの記事をお手本にしました！　[Haskellでコマンドライン引数を受け取る](https://qiita.com/taashi/items/d48e6cb875930538a302)

```hs
import System.Environment (getArgs)

main = do
    args <- getArgs
    let str_num = args !! 0
        num = read str_num :: Int
    print num > 100
```
引数をStringからIntにして「100より大きい数か」表示したかったのですが、コンパイルエラー
~~コマンドラインからの入力はIO String型でString型とはちがうから~~
~~`num = read str_num :: Int`ではInt型になっていないようです~~
`print (num > 100)`としていないのが原因
`(print num) > 100`と解釈され、標準出力に表示してから（IO～型）100より大きいかを判定しようとしているからエラー
（@tezca686 さん教えてくれてありがとうございます）

```
>stack ghc test.hs
[1 of 1] Compiling Main             ( test.hs, test.o )

test.hs:15:5: error:
    ? Couldn't match expected type ‘IO b’ with actual type ‘Bool’
    ? In a stmt of a 'do' block: print num > 100
      In the expression:
        do args <- getArgs
           let str_num = args !! 0
               num = ...
           print num > 100
      In an equation for ‘main’:
          main
            = do args <- getArgs
                 let str_num = ...
                     ....
                 print num > 100
    ? Relevant bindings include main :: IO b (bound at test.hs:11:1)
   |
15 |     print num > 100
   |
```
# これでできた！
main関数では引数を受け取って結果を表示するだけにしました
doブロック内だとコンパイラーがIO～型として認識するのでしょうか？？

```hs
import System.Environment (getArgs)

-- StringからIntに変換
convert :: String -> Int
convert x = read x :: Int

-- 100より大きいか判定
compare_hun :: Int -> Bool
compare_hun x = 100 < x

main = do
    args <- getArgs
    let str_num = args !! 0
        num = convert str_num
        result = compare_hun num -- 判定結果を変数に保存
    print result
```
```
>stack ghc test.hs
[1 of 1] Compiling Main             ( test.hs, test.o )
Linking test.exe ...

>test.exe 100
False

>test.exe 101
True
```
# ちょっと応用
私がコーディングしたのは、コマンドラインから入力された「クリスマスプレゼントの予算」が
[2019年クリスマスプレゼントの平均予算（勝手に予測）](https://buto-dev-null.hatenablog.com/entry/2019/11/30/000000)と比較して高いか安いかを表示する関数です！
日本語だとUnicodeが表示されるのでメッセージを英語にしています
（`print`ではなく`putStr`だと日本語も表示できました！@mod_poppo さんありがとうございます）
コード、英語アドバイスお願いします

```hs
import System.Environment (getArgs)

convert :: String -> Int
convert x = read x :: Int

compare_to_avg :: Int -> String
compare_to_avg x =
    if x < 12477
      then "smart shopper!!"
    else if x < 15000
      then "GRATE sense of money!!!"
    else
      "How nice! Happy Holidays!"

main = do
    args <- getArgs
    let str_price = args !! 0
        price = convert str_price
        result = compare_to_avg price
    print "Budget of Holidays gift in 2019(avg):12,477JPY"
    print result
```
希望をこめて20,000円と入力しました　最高のホリデーシーズンをお過ごしください！！！

```
>xmas_gift.exe 20000
"Budget of Holidays gift in 2019(avg):12,477JPY"
"How nice! Happy Holidays!"
```
Xcode11から新しいXCFrameworksフォーマットの配布をサポート

## はじめに
Xcode11から新しいXCFrameworksフォーマットで配布できるとのことだったので、WWDC2019の以下のセッションを見て、その内容をまとめてみました。
参考：
[Session 416 Binary Frameworks in Swift](https://developer.apple.com/videos/play/wwdc2019/416/)

## XCFrameworksフォーマットの登場
Xcode 11は新しいXCFrameworksフォーマットを使ったバイナリライブラリの配布をサポートするとのことです。（拡張子「.xcframework」）
発表のあった、Project Catalyst（iPadアプリがMacOSでも動く）と関係していそうです。

### これまでのフレームワーク
以前は、SDK（.framework形式）を配布する場合、シミュレーター用のframeworkと、端末用のframeworkをそれぞれビルドしてから、各frameworkのバンドル内に含まれるバイナリをスクリプトで結合して1つのframeworkにしていました。

シミュレーター用というのは、Xcodeでデバッグできるように配布するのですが、App Store申請時にアプリに含まれるframeworkのバイナリにシミュレーター用が含まれていると、アプリのバリデーション時にエラーとなり、AppStoreにアップロードできないという問題があり、AppStoreにビルドをアップロードする際にはシミュレーター用を除去する必要がありました。

### XCFrameworkではどうなるのか
XCFrameworkでは、以前のframeworkのように結合スクリプトを実行する必要なく、iOSシミュレーター用とiOSデバイス用の両方を含めることができます。

![framework1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/361214/30d7eef4-2558-6add-d057-db00df54329e.png)

.xcframework形式では、複数の.frameworkを1つのディレクトリにまとめられる構造となっているため、iOSシミュレーター用とiOSデバイス用の両方を含めることができます。

###  XCFrameworkの使い方いろいろ

|イメージ|使い方|
| --- | --- |
|※左の図参照 ![framework2_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/361214/ae0062ef-ff33-b211-e04d-ec1f174136ce.png)|Staticライブラリ配布。（これまでStaticライブラリの静的ライブラリとそれに対応するヘッダーファイルである.aファイルと.hファイルの複数ファイルの配布でしたが、XCFrameworkとしてまとめられそうです。）|
|![framework2_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/361214/894f4ffb-d0dc-4e6c-f249-3a2b92ac58f0.png) | SwiftとCベースのバイナリも一緒に配布できる。 |
| ![framework2_3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/361214/e8bd0842-58d8-5c41-fee6-f993659be437.png)| 複数のプラットフォーム（iPhone、macOS、watch、tvOSなど）をまとめたものを配布できる。 |

## XCFrameworkの作り方
XCFrameworkの作り方の概要は次のとおりです。

### Build Libraries for Distribution をYESに
Build Libraries for Distribution という新しいBuild設定がが追加されています。
XCFrameworkにバンドルされているフレームワークはこれをYESに設定する必要があります。

![framework3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/361214/010fc726-e560-6078-20dc-a6c34268d45b.png)

### アーカイブする
XCFrameworksの作成は、xcodebuild -create-xcframeworkを使用してコマンドラインでの作成がサポートされているようです。
PyQ機械学習に関するメモ　pythonの文法

# 目的
pyqで学んだことを忘れないために、メモを残す

# pandas

#### 描画について
・ヒストグラムを描画するときは `plt.hist`


`plt.hist(df[df["y"] == 1]["x"], label="men 16years old", bins=100,
        range=(140, 187), alpha=0.3, color="green") `　(dfはcsvのデータ)
1. df[df["y"] == 1]["x"]
    dfにおいて、列が y==1 の時の行の値
2. label="men 16years old"
ラベルの説明
3. bins=100
階級の幅　1階級 = range / bins 
4. alpha=0.3
グラフの透明度

`plt.xlabel("height [cm]")` : x軸のタイトル
`plt.legend();` :データの説明を表示


・散布図を描画するときは`plt.scatter`
`plt.scatter(men["height"], men["weight"], color="green")`
第一引数に、データの中の横軸の値　　第二引数に、データの中の縦軸の値

・散布図行列を描画するときは
`pd.plotting.scatter_matrix(df)`


#### DataFrame
・列の値を抽出する
`df[["アルコール度数", "密度"]]` のようにカラムの名前を指定
`df.iloc(取り出す行, 取り出す列)` df.ilocを使う

・データをトレーニング用、評価（テスト）用に分割
train_test_splitを使う
`from sklearn.model_selection import train_test_split
(X_train, X_test,
 y_train, y_test) = train_test_split(
    X, y, test_size=0.3, random_state=0
)`
test_size=0.3　はデータの何割をテスト用にするか
random_state=0　データを分割する際の乱数のシード値　（普段は使わない）


# 決定木
決定木は、「自動で条件を学習するif文の連続」


# Numpy

**要素が同じ多次元配列の作成方法**
zeros(サイズ) : 全ての要素が0の多次元配列
ones(サイズ) : 全ての要素が1の多次元配列
full(サイズ, 値) : 全ての要素が値の多次元配列
zeros_like(多次元配列) : 要素が全て0の多次元配列
ones_like(多次元配列) : 要素が全て1の多次元配列
full_like(多次元配列, 値) : 要素が全て値の多次元配列

**連続データ**
arange([start,] stop[, step,], dtype=None) ：rangeと同じように連続データ作成
linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None) ：作成する範囲と個数numが決まっている場合の連続データ作成

**単位行列と対角行列**
numpy.eye：対角線が全て1の単位行列
numpy.diag：任意の対角行列

# 評価規準
評価規準は、物差しの種類である
評価基準は、物差しの目盛りである
Lua＋VSCodeでHelloWorldするまで

# Luaのダウンロード
- 以下のリンクからzipファイルをダウンロードする
- ひとまずlua-5.3.5_Win64_bin.zipでOKです
- https://joedf.ahkscript.org/LuaBuilds/

# Luaのインストール
- Documents下に「Lua」というフォルダをつくります
- Luaフォルダの中に、さきほどダウンロードしたzipファイルを解凍して、中身を置きます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206887/13308003-6f53-c9d2-60e0-f57a4208d324.png)
 
# VSCodeを起動
- さきほどのLuaフォルダの中で、右クリックして、「open with code」をクリック
- 起動後に、右下の「プレーンテキスト」を「Lua」へ切り替えておく
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206887/36eb02f6-30b6-73c2-58bd-adc306de66ef.png)

# プログラミングを書いたら保存
- ちゃんとDocuments下のLuaフォルダに保存されているかどうか確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206887/6673a5aa-7c45-b237-daa3-0b94ad9eecf5.png)

# VSCodeのエクステンション「Code Runner」をインストール
- エクステンション画面をひらく
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206887/4deffbc4-5566-3e98-bfa2-2942536b7ca0.png)
- Code Runnerを検索

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206887/d05d1777-6a23-0429-c37c-4d8179fa8102.png)
- Code Runnerをインストール
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206887/5386e191-4f91-bcad-a1a9-3bb2f578d084.png)

- VSCodeを再起動

# Code RunnerでLuaを実行
- 動作を確認したいLuaのコードを選択（基本的にはコード全体を選択でOK）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206887/ac6d9ad3-b79c-1cc2-6d9d-7463bbbd8ac8.png)

- F1ボタンを押す
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206887/7370f818-75fa-1fe7-c73a-936a4aa9eae8.png)

- 出てきた窓に「run code」と書いてEnter。これでコードが実行されて結果がみれます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206887/c2077ea6-c87c-1e0d-e22b-7be075100549.png)
技適通過版Raspberry Pi 4のUbuntuで、Karnelアップデートがコケる件

先日より日本国内で流通が始まった技適通過版Raspberry Pi 4。

この子にUbuntu 19.10を入れ、カーネルアップデートをしようとするとコケるので、その対策メモ。
たぶん、そのうち修正されると思うよ（他力本願）。

**12/3 補足**
all.dbの修正行数の誤りを修正しました（ご指摘有難う御座います！）
また、本件の問題はUbuntuバグトラッカーでトラッキングされており、近日中には修正されるのではないでしょうか。
https://bugs.launchpad.net/bugs/1854487
**補足ここまで**


初期インストール直後。

```shell
>uname -a
Linux ubuntu 5.3.0-1007-raspi2 #8-Ubuntu SMP Thu Oct 10 12:42:47 UTC 2019 aarch64 aarch64 aarch64 GNU/Linux
```

この「5.3.0-1007-raspi2」は、4GBメモリ版でUSBを認識しないという致命的バグを抱えているので速攻でカーネルアップデートしてあげたいところだが、残念ながら以下エラーが起きる。

```shell
>sudo apt-get update
>sudo apt-get upgrade

：
Processing triggers for initramfs-tools (0.133ubuntu10) ...
update-initramfs: Generating /boot/initrd.img-5.3.0-1007-raspi2
Unsupported platform.
run-parts: /etc/initramfs/post-update.d//flash-kernel exited with return code 1
dpkg: error processing package initramfs-tools (--configure):
 installed initramfs-tools package post-installation script subprocess returned error exit status 1
Errors were encountered while processing:
 initramfs-tools
E: Sub-process /usr/bin/dpkg returned an error code (1)
```

技適通過版は「Raspberry Pi 4 Model B Rev 1.2」と基板改良がされたばかりで新しく、どうやらflash-kernelが未対応の模様。

なので、以下のファイルの
`/usr/share/flash-kernel/db/all.db`
1669行目に
`Machine: Raspberry Pi 4 Model B Rev 1.2`
の1行追加する。

（追加例）

```
Machine: Raspberry Pi 4 Model B
Machine: Raspberry Pi 4 Model B Rev 1.1
Machine: Raspberry Pi 4 Model B Rev 1.2
Method: pi
Kernel-Flavors: raspi2
DTB-Id: bcm2711-rpi-4-b.dtb
U-Boot-Script-Name: bootscr.rpi
Required-Packages: u-boot-tools
```

そして、再アップデート＆再起動。

```shell
>sudo apt-get install linux-headers-raspi2 linux-image-raspi2 linux-raspi2
>sudo reboot
```



```shell
>uname -a
Linux ubuntu 5.3.0-1012-raspi2 #14-Ubuntu SMP Mon Nov 11 10:06:55 UTC 2019 aarch64 aarch64 aarch64 GNU/Linux
```

ばっちり！
Java(set)

【set】
ArrayListの要素を書き換える際に使用するメソッドである。
以下のように変更したい場所と値を入れて使用する。
変数名.set(インデックス,書き換える値)

Java（add）の回で使用したArrayList「array」に
setメソッドで指定した場所の要素を書き換える。

    ArrayList<String> array = new ArrayList<String>();
    
    array.add("日本語");
    array.add("英語");
    array.add("フランス語");
    array.add("中国語");
    array.add("ドイツ語");

    System.out.println(array);
    
    [日本語, 英語, フランス語, 中国語, ドイツ語]

インデックス3の「中国語」を「韓国語」に変更する。

    array.set(3,"韓国語");
    System.out.println(array);

リストの中を出力すると以下のようになる。

    [日本語, 英語, フランス語, 韓国語, ドイツ語]

指定した場所の値が書き換えられる。

addメソッド同様、存在しない場所を指定して値を書き換えようとすると
「IndexOutOfBoundsException」という例外が発生する。
より良いtypescriptのenumを考えてみた

```typescript:Type.ts
export namespace Type {
  export const normal = "Normal"
  export const fire = "Fire"
  export const water = "Water"
}
export type Type =
    typeof Type.normal
  | typeof Type.fire
  | typeof Type.water

export namespace Type {
  export const all: Type[] = [
    Type.fire,
    Type.normal,
    Type.water
  ]
}
Object.defineProperty(Type, "all", { enumerable: false })
```

```typescript:main.ts
import { Type } from './Type.ts'

// Usage
const anyType: Type = "Fire" // OK
// const illegalType: Type = "firee" // error
const all = Type.all;
console.log(all) //=> [ 'Fire', 'Normal', 'Water' ]
console.log(Object.keys(Type)) //=> [ 'normal', 'fire', 'water' ]
```

## ミソは、

- namespaceは同名のtypeを定義できること。
- definePropetyでenumerable: falseにしておくと列挙で余計なものが拾われないこと

## だめなところ

- 各itemごとに振る舞いを定義することはできない(swiftのenumみたいなレベルということですね)
- コードを読む人に多大な脳の負担を強いる
- 結局3度も手書きで列挙してるやんけ

## Typescriptのenumのだめなところ
- numberのバリデーションができない(必ずrawValueをstringにして運用しよう、というかenum使うのやめよう)
- rawValueのTypeがほしいのにできない
4K webcam について

** 2021年6月26日の追記 **

ELP社のカメラの売れ筋のものは現在はamazonで購入できるようになっています。

** 追記ここまで **


![IMG_1111.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13271/62dd3f2c-8d2d-c2eb-4e42-bf62353e61d4.jpeg)

最近いくつかの4K webcamを買って試したのでメモを残します。
2019年11月の情報です。

## 入手可能な4K webcam

webcamといえばとてもたくさんのものが出回っているのですが、4K (3840x2160)の解像度で30fpsをだせるものとなると実はあまりありません。2万円くらいで購入可能なものは以下のものです。

- ロジクール BRIO
- AliExpress で購入可能なELP社のUSBカメラ

BRIOとELP社のカメラ3種の合計4機種を試したので、それぞれについてコメントします。

## ロジクールBRIO

https://www.logicool.co.jp/ja-jp/product/brio

まず最初にみつかる4Kのwebcam はこれだと思います。
価格が2万円超で同社のフルHDクラスのwebcamの倍しますが、画質はよいです。きれいな発色です。
ディスプレイに引っ掛けて使うのにちょうどいいかたちをしています。~~意外なことに三脚穴はありません。~~ (2020.3.19追記: 三脚穴あります。下のコメント参照)
Jetson nanoにつないで使っていたのですが、ログをみるとごくたまに解釈できないMJPEGが流れてきているようなメッセージが出ます。使っていると熱くなります。短時間で使用する分にはよいのですが、1日中つけっぱなしで使うようなことは想定していない感じです。


## ELP社製IMX317センサーのカメラ

私も今回初めて知ったのですが、ELPという会社がすごくたくさんの種類のUSBカメラを出していて、AliExpress でそれを日本から買うことができます。そのなかでセンサーとしてソニーのIMX317を使っているものが4K 30fpsでます。
AliEcpressのサイトでIMX317 で検索してみるとよいでしょう。基本的にセンサーと制御基板は同一で、ケースとレンズが違うものがたくさん見つかります。
USB2.0で4KのMJPEGが出てきます。昼夜つけっぱなしで使ってみましたが安定して使えました。

IMX317センサーのカメラで3つ試したので紹介します。


![](https://ae01.alicdn.com/kf/HTB1P4xIVkzoK1RjSZFlq6yi4VXap/ELP-4-18K-USB-UVC-Pc-sony-IMX317-android.jpg_350x350.jpg)
ELP-USB4KHDR01-BL36
https://ja.aliexpress.com/item/33013268769.html

最初に買ったのがこれ。
レンズにたくさんの選択肢があるので、広角のものがよいだろうと思って一番焦点距離の短い3.6mmを選びました。
実際の映像をみると、真ん中は非常に高画質ですが、周辺部分が明らかに画質が落ちていました。
webcamのパラメータ設定で少しズームして使えば問題ないです。

ケースはプラスチックで、三脚穴もありません。
オートフォーカスできます。


![](https://ae01.alicdn.com/kf/HTB1B1D8V9zqK1RjSZFjq6zlCFXaw/4-18K-USB-3840-2160-Mjpeg-30fps-USB-Web.jpg_350x350.jpg)
ELP-USB4KHDR01-KL36
https://ja.aliexpress.com/item/33020119738.html

次はレンズをもう少しよいものにしようと買ったのがこれ。
レンズは No distortion lens を選びました。
ケースは金属製のしっかりしたもので、三脚穴があります。
オートフォーカスできます。


![](https://ae01.alicdn.com/kf/HTB1RUUbV5rpK1RjSZFhq6xSdXXa9/4-18K-IMX317-1-2-5-USB-3840.jpg_350x350.jpg)
ELP-USB4KHDR01-MFV
https://ja.aliexpress.com/item/33016736630.html

レンズを外せるタイプのものも買ってみました。
ケースは金属製で三脚穴があります。
説明には明記されていないのですが、大きさからみてCSマウントのレンズに交換できると思います。CSマウントレンズは監視カメラでよく使われている規格です。
2.8-12mm lens を選びました。
このレンズは焦点距離と絞りを手動で変更できます。その代わりフォーカスは自分で調整する必要があります。
レンズに詳しい人なら自分で他のレンズを見つけてきて交換したり、いろいろ試せると思います。

## おすすめ

私からのおすすめはAliExpressで買えるソニーIMX317センサーのカメラです。日本円で1万円ちょっとです。
これを4Kでなくて1080pや720p で使ったとしても、ロジクールの1万円クラスのwebcamよりも明らかに画質がよいです。センサーが新しいせいでしょうか。

webcamとして普通に使い勝手がよいのがこれです。
![](https://ae01.alicdn.com/kf/HTB1B1D8V9zqK1RjSZFjq6zlCFXaw/4-18K-USB-3840-2160-Mjpeg-30fps-USB-Web.jpg_350x350.jpg)
ELP-USB4KHDR01-KL36
https://ja.aliexpress.com/item/33020119738.html
レンズの選択に迷うので、いくつかちがうものをまとめ買いするのがよいと思います。まとめて一回で配送すると配送料が節約できます。納期は2〜3週間かかります。

なお、今回はマイクの性能は確認していません。