OmniAICreator/Qiita-1.07M huggingface dataset:
【AWS】VPCEについて

#VPCE（VPCエンドポイント）とは？
・DynamoDB、S3、Route53といったリージョンサービスに対してVPCからプライベート接続出来る仮想ネットワークサービスのことだよ！

**併せて覚えておきたい用語について**
・VPC内のENIからプライベートにリンク（接続）することを**プライベートリンク**と言うよ！

#VPCEは2種類ある？
・ゲートウェイ型　と　インターフェース型が存在するよ！

###＜ゲートウェイ型の特徴＞
・S3、DynamoDBがサービス対象！
・ルートテーブルに設定して使用！
・安価

###＜インターフェース型の特徴＞
・実体はENI（仮想ネットワークカード）
・セキュリティグループにアタッチして使用！
・サービス対象の更新スピードが早いので公式ページを要チェックだ！

**Point**
・インターフェース型に対応したAWSサービスをプライベートリンク対応したAWSサービスと呼ぶこともあるよ！
KPTからFDLに乗り換えても躓かない、たった一つのカイゼン点

はじめまして、よこけんです。
最近ふりかえりに FDL (Fun Done Learn) を取り入れてみました。

* [ファン・ダン・ラーン(FDL)ふりかえりボード](https://qiita.com/yattom/items/90ac533d993d3a2d2d0f)

終始ポジティブに臨めるこの手法は本当に素晴らしいなと感じているのですが、一つだけ悩ましい問題があります。
そう、**丸3つのベン図って意外と描くのが難しいんです。**
![FDL.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/413915/cf432522-b81c-6078-de5d-e3ae7f1efab0.png)
私のような絵心？の無い人間は、このベン図のせいで FDL を心の底から楽しめなくなってしまうのです。（大袈裟）

そこで今日は、どうにかこの忌々しいベン図（※個人の偏見です）を克服し、ニコニコ顔で FDL を楽しめないものかと捻り出した画期的な方法をお披露目します。
こちらです。

# こちら
![44F26CC9-15D8-4247-9C97-29E868A686FA.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/413915/31730e02-d374-5f18-bb93-648685ec3a63.jpeg)

チャオ図です。（命名：私）

**「ベンさんは置いてきた。修行はしたがハッキリ言ってこの戦いにはついていけない。」**

ついていけなかったのは私です。

チャオ図の良いところは、図形を重ねて描く必要が無いところです。だから<del>100人乗っても大丈夫</del> 絵心無くても大丈夫。ホワイトボードを使ってる場合、各エリアの大きさも気軽にいつでも調節できます。

# 描き方
とても簡単です。

1. まず、大きな丸を３つ、少し離して描きます。
2. 内側を線で三角形に繋ぎます。気持ち膨らませるとオニギリっぽいです。
3. 外側も同様に繋ぎます。
4. わかりやすく文字を入れて完成です。

All、D+F、D+L、F+L などの文字も入れておくと初めての人にも優しいですね。

# 超餃図 (スーパーチャオ図)
![chaozu_large.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/413915/6a731eb9-4098-b70b-0292-a31b50eeb5a8.png)


限界まで広く使いたい場合は、丸をぶったぎって内側だけオニギリで繋ぐと良いです。
これなら100人乗っても大丈夫。


# 終わりに
私が FDL を知ったのは、先日社内のアジャイル系イベントに社外講師としていらした森さん (@viva_tweet_x) によるご紹介でした。
私は最初、「問題にフォーカスしない FDL は学びをふりかえるために使う手法であり、チームが日々の開発をふりかえるために使うものでは無い」と思い込んでいたのですが、そうではありませんでした。

* [チームは問題解決を見てはいけない](https://qiita.com/viva_tweet_x/items/090015cc5e071927d0be)

懇親会で少しお話した時には、「なるほど、ふりかえりでは良いところを伸ばして、問題は自己組織化されたチームが自然に解決していくってことかー」などと理解したつもりになっていたのですが、そんな上辺だけの理解ではダメだと気付きました。
そもそも自己組織化というのが中々の難問。
FDL は今後も積極的に使っていこうと思いますが、いきなり盲信的に完全移行してしまうのは違うのかもしれません。定期的に KPT も使ってみたりして、試行錯誤しながらより良い方向を目指していきたいなと思う次第です。
【AWS】NATゲートウェイとENIについて

#NATゲートウェイとは？
・NATゲートウェイはプライベートサブネットのインスタンスをElasticIPやプライベートIPを持つことなくインターネットに接続させる為に必要だよ！

**＜使用上の注意＞**
・NATゲートウェイはパブリックサブネットにアタッチしよう！
・NATゲートウェイはプライベートIPをElasticIPに変換してインターネットゲートウェイに接続するので、ElasticIPがインターネットゲートウェイに向くようにルーティングが必要だよ！
・インターネットからプライベートサブネットのインスタンスへはアクセス出来ないよ！
・NATゲートウェイにはENI（後述）が自動でアタッチされているよ！
・NATゲートウェイ作成時に必ずENIにElasticIPを割り振らないと作成出来ないよ！

#ENIとは？
・Elastic Network Interface のこと。
・VPC内の仮想NIC（ネットワークカード）が実現出来るよ！
・ENIにはサブネットのIPレンジより自動でプライベートIPがアタッチされているよ！
円周率計算の高速化 (4) 並列化

- [円周率計算の高速化(1)](https://qiita.com/peria/items/97af2df9845decc108ae) 比較元の再構成と問題設定
- [円周率計算の高速化(2)](https://qiita.com/peria/items/01b4671fae70cbb2bc31) 計算の正しさの確認
- [円周率計算の高速化(3)](https://qiita.com/peria/items/f959b3a1a3f5b8d939ef) 無駄な計算の除去。約7％高速に
- 円周率計算の高速化(4) 並列化。60％の時間削減

円周率計算の高速化シリーズの4本目です。今回は並列化します。

# 理論

Binary Splittng の計算は

```math
M_k=\begin{pmatrix}z_k & y_k \\ 0 & x_k\end{pmatrix}
```

としたときの

```math
M_0M_1\cdots M_{n-1}
```
と実質的に同等という話をしました。つまり $M_0M_1\cdots M_{m-1}$ と $M_mM_{m+1}\cdots M_{n-1}$ の計算は独立に行うことができるわけです。なので使えるスレッドも半分ずつ担当させることにしましょう。例えば 8 スレッド実行できる環境で $M_0M_1\cdots M_{15}$ を計算しようとする場合、BS の最初の呼び出しでは

- $M_0M_1\cdots M_{15}$ (8 threads) → $M_0M_1\cdots M_7$ (4 threads) + $M_8M_9\cdots M_{15}$ (4 threads)

と分けます。以下同様に 2 分割ずつして行くことで 1 スレッドに 2 個の $M_i$ という形で各スレッドが独自に計算できる範囲が決まることになるので、それぞれこれまでと同じ通常の BS を適用することができます。

次は統合していく方向になります。基本的な計算ルールはこれまでの BS と同じで、両担当スレッドの仕事の結果得られた $M_i M_j$ をかけることになります。ただ多倍長計算そのものに GMP ライブラリを使っている以上、それらの中身をマルチスレッド化することはできないのでこの計算はシリアルに行う事になります。

# 実装
この方針に基づいて `parallel_drm()` を実装します。

```cpp
void Computer::parallel_drm(const int64_t n0,
                            const int64_t n1,
                            mpz_class& x0,
                            mpz_class& y0,
                            mpz_class& z0,
                            bool need_z,
                            const int number_of_threads) {
  // 1 スレッド割り当て時は元と同じ実装を使う
  if (number_of_threads == 1) {
    drm(n0, n1, x0, y0, z0, need_z);
    return;
  }

  int num_new_threads = number_of_threads / 2;
  int num_rest_threads = number_of_threads - num_new_threads;

  int64_t m = (n0 + n1) / 2;
  mpz_class x1, y1, z1;
  {
    auto clausure = [&] {
      parallel_drm(m, n1, x1, y1, z1, need_z, num_new_threads);
    };
    std::thread th(clausure);
    parallel_drm(n0, m, x0, y0, z0, true, num_rest_threads);
    th.join();
  }

  // このルーチンは元と同じ
  y0 *= x1;
  y1 *= z0;
  y0 += y1;

  x0 *= x1;
  if (need_z)
    z0 *= z1;
}

void Computer::compute() {
  const int64_t precision = config_.digits * std::log2(10) + 10;
  pi_.set_prec(precision);

  const int64_t n = terms(config_.digits);
  mpz_class x, y, z;
  parallel_drm(0, n, x, y, z, false, config_.number_of_threads);
  postProcess(x, y);
}
```

これで一応の並列化を行うことができました。コードの全体は[こちら](https://github.com/peria/misc/tree/5eee62c57c69c5a0bd611491e9d29bae9674dc66/qiita/gmppi)です。パラメータが増えたのでコマンドラインで指定できるように変更しつつ、`Computer::Configuration` にまとめました。

# 実験

ということで実験を行いました。これまでとは別の計算環境で 1 億桁の計算(基底変換と出力を除く)の時間をスレッド数別に計測した結果がこちらです。ちなみに 55 論理 CPU です。

|Threads    | 1 | 2 | 4 | 8 | 16 | 32 | 64 |
|-----------|--:|--:|--:|--:|--:|--:|--:|
|Time[sec] |112.137|71.296|51.719|42.743|39.078|37.345|38.562|
|並列度[%]|100|78.6|54.2|32.8|17.9|9.4|4.5|

基本的にスレッド数が増えれば計算時間は減っていますが、並列度(1スレッドでの時間/$n$スレッドでの時間/$n$)はあまり高くない形になりました。[理論]の最後に書いている辺りが原因だとは思いますが、まだ違和感もあるので後の投稿で対策を取ることにしましょう。
SQLのGROUP BYについて①

最近、GROUP BYについてまさかのド忘れをするという事態に陥ったので覚書。
よく使うものなので普通にしてれば忘れるようなことはないと思いますが……。

GROUP BYは、SUMなどの集計関数を使いたいときに必要になります。
たとえば個人別の総得点を調べる時なんかに使えます。
今回は以下のテーブルを使用します。

|name|subject | score | 
|:-----|:-----|:-----|
|鈴木   |国語   |70
|鈴木   |数学   |80
|田中   |国語   |90
|田中   |数学   |60
|田中   |英語   |80
|山田   |数学   |70

使用するSQLは以下の通り。

```ruby:SQL
SELECT name, SUM(score) FROM TABLE1 GROUP BY name;
```

実行結果は以下の通り。

|name| SUM(score) | 
|:-----|:-----|
|鈴木   |150
|田中   |230
|山田   |70

上記のように、個人別の総得点をSQLによって算出することができます。
様々な場面で使えるので、必ず覚えておいてください。普通は忘れないと思いますが……。
[Unity] 2秒でオブジェクトプールしたい君へ [Lean Pool]

## 謝罪

2秒ではできません、ごめんなさい。

## オブジェクトプールしたい

弾幕ゲーで弾Instantiateしてたら大変なことになったので、オブジェクトプールしたくなった。
簡単なオブジェクトプールくらいなら自分で書いてもそんなに時間はかからない気がするが、書きたくないのでアセットに頼りたい。

地獄。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/188872/dda0b47b-2619-d226-f29c-425344a91ca0.png)


## Lean Pool を使って楽しよう

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/188872/dd8ffbf4-0477-52c9-8e25-af36e237a311.png)
現在無料で一番人気のオブジェクトプールアセットである。

## 使いかた

ダウンロードしてインポートする。
プールしたいオブジェクトのInstantiateとDestroyを置換する。

`Instantiate(poolShitaiObject);` -> `Lean.Pool.LeanPool.Spawn(poolShitaiObject);`
`Destroy(poolShitaiObject);` -> `Lean.Pool.LeanPool.Despawn(poolShitaiObject);`

これだけでプールされるが、もう少しやることはある。

### 初期化

同じオブジェクトを使いまわす以上、以下のような普段やってる初期化は当てにならない。
AwakeとStartが都度呼ばれないのだ。

```cs
class Ahan : MonoBehaviour {
    public Ahahan ahahan;
    // 何もしてないので、再利用されるとき、値が引き継がれてしまう。
    public int ahanCount = 0;
    public int ahanAhanCount;

    private void Start() {
        ahahan = GetComponent<Ahahan>();
        // Startは一度は呼ばれるが、再利用時には呼び出されないので、値が引き継がれてしまう。
        ahanAhanCount = 10;
    }

    private void Update() {
        ahanCount++;
        ahanAhanCount++;
    }
}
```


変更される可能性のある値は全てOnEnableの中で初期化すべし。

```cs
class Ahan : MonoBehaviour {
    public Ahahan ahahan;
    public int ahanCount;
    public int ahanAhanCount;

    private void Start() {
        // 変化しない値はStartのままでいい。
        // 重たくない処理の場合は脳死で全部OnEnableにおいてもええで
        ahahan = GetComponent<Ahahan>();
    }

    // Spawn時に毎回呼び出されるため、値がリセットされる。
    private void OnEnable() {
        ahanCount = 0;
        ahanAhanCount = 10;
    }

    private void Update() {
        ahanCount++;
        ahanAhanCount++;
    }
}
```

#### OnEnableはStartの完全な代替にはなれない

なぜならStartはInstantiateされた次のフレームに実行されるが、OnEnableはSpawnされた時点で実行されるからだ。
どういうことかというと、
`Instantiate -> 変数にいろいろ代入 -> 次のフレームにStartが実行されて、代入された値をもとに準備ができる`
がStartは出来るのに対して、OnEnableは、
`Spawn -> OnEnableがその瞬間実行される -> 変数にいろいろ代入 -> OnEnableはもう実行済みのため、次のフレームでは実行されず、値が反映されない`
という感じになる。
普通に使っている分には脳死で`Start -> OnEnable`で問題ないはず。

### プールサイズを設定する

ただInstantiateとDestroyを置き換えただけでも高速化はされる。
しかしプールサイズが設定されていないため、弾が増える最初のタイミングはやはり重い。

こんな感じ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/188872/13b5591f-3073-0b46-423b-73aeb33330df.png)

最初から使いまわす用のインスタンスを用意しておくと、このコストもなくなる。
プールオブジェクトを作る。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/188872/ceac980b-b9a7-7202-8c85-c1331a8eb235.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/188872/c9fd9016-4a08-ec19-2c39-5f8e1e57eff2.png)
Prefabのところに弾のPrefabを置いて、Preloadに用意したい弾の数を入れる（適当に1000）。

こうなった。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/188872/af366b78-0937-58e4-38a1-6dd373831414.png)

## 比較してみる

Before
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/188872/dda0b47b-2619-d226-f29c-425344a91ca0.png)
After
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/188872/af366b78-0937-58e4-38a1-6dd373831414.png)

## これで君もニッコリ

やったね！
【AWS】VPCでネットワークと通信する為に必要なこと

#１．VPCにIGWをアタッチしよう！
・IGW(※1)をVPCにアタッチすることでEC2インスタンスからインターネットへ接続することが可能になるよ！

※1：IGW（インターネットゲートウェイ）とは？
・VPCにアタッチして使用するネットワークコンポーネント（ネットワーク接続に必要なソフトウェア）

#２．ルートテーブルの設定をIGWに向けた設定にルーティングしよう！
・サブネットのルートテーブルの設定でIGWに向けた設定をルーティングすることでVPC内の通信はローカルルートを通り、それ以外の通信はIGWを通るようになるよ！

**併せて覚えておきたい用語について**
**・デフォルトゲートウェイについて**
→サブネットに設定されているルートテーブル内のIGWのIPアドレスがワイルドカード（全て0）で全てのIPアドレスを示しているルールのこと。
**・パブリックサブネットとプライベートサブネットについて**
→AWSではデフォルトゲートウェイにIGWが設定されているサブネットをパブリックサブネットと言うよ！逆にデフォルトゲートウェイが設定されていないサブネットのことをプライベートサブネットと言うよ！

#３．EC2インスタンスにIPアドレスをアタッチしよう！
・インスタンスに ElasticIP(※1) か PublicIP(※2) をアタッチしよう！

※1：ElasticIPとは？
・インスタンスにアタッチ／デタッチ可能な静的IPアドレスのこと。
（インスタンスが停止、再起動、終了した場合でも同じIPアドレスとなる）
注意：どこにもアタッチしていないと1時間当たり1円掛かるので注意！

※2：PublicIPとは？
・AWSのIPアドレスプールより割り当てられるインターネットへ接続出来るIPアドレスのこと。

#４．セキュリティグループとネットワークACLを設定しよう！
###＜セキュリティグループ＞
・インスタンス単位でアタッチして使用するよ！
・IPアドレスの接続範囲や他のセキュリティグループを指定して使用することも出来るよ！

###＜ネットワークACL＞
・サブネット単位にアタッチするファイヤーウォールのことだよ！
・設定したルールは上から適応されていくよ！
活動記録(2020.2.24)

#活動記録(2020.2.24)
週末(2/22〜24)の活動記録。

・Progate:Rails前半部〜中盤あたりまでの内容をQiitaにまとめつつ学習。

・MENTAにてメンター様と契約。これからは単なる独学作業ではなくなるプレッシャーもあるが、複数人での作業はやはり楽しみでモチベーションが一気に上がる。

・平日業務の空き時間にもメンターとのやり取りをしたいため、モバイルルーターとVPN(Surfshark)を契約。



#課題・不明点
・VirtualBoxのインストールが失敗ループに入ってしまう。

・Rails.new時にエラーが起こり中断してしまう。
やったことを洗い出してメンターに質問する。
→Udemyの「3日でできるRails入門」を参照しながらこの状態に陥ったので、深夜に発狂しつつ再現・格闘していたら下の記事で解決…
どうやらsudo(root権限)で実行したインストールが問題で一部のファイル権限がrootになっていたことが問題だった模様。

権限の書き換えコマンド

```
sudo chown -R username /Users/username/.rbenv
```

【Ruby on Rails】 Permission denied @ dir_s_mkdir の解消法：
https://dara-blog.com/about-rails-error01

Railsの「Yay! You’re on Rails!」までにここまでかかるとは…（感動的ではあった）

<img width="905" alt="スクリーンショット 2020-02-25 0.45.11.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/561657/6deb1052-a530-8655-7ebe-df515886a156.png">
ローカルでしか使わないファイルをGit管理から除外する方法

Git管理したくないファイルパスを `.git/info/excluede` に書き込め。

```sh
# local_only.sh をGit管理から外すぞ
$ git status
On branch master
Your branch is up to date with 'origin/master'.

Untracked files:
  (use "git add <file>..." to include in what will be committed)
	local_only.sh

nothing added to commit but untracked files present (use "git add" to track)

# .git/info/excluede に追記するぞ
$ echo localonly.sh >> .git/info/excluede

# やるやんけ
$ git status
On branch master
Your branch is up to date with 'origin/master'.

nothing to commit, working tree clean
```

これでうっかりコミットするようなことがなくなります。
2in1タブレットPC Chuwi UBook Proを レビュー

Chuwi UBook Proをクラウドファンディングで購入しました。
今回はUBook Proのレビューをしてみたいと思います。

なお、本レビューは当方の意見であること、およびクラウドファンディング版であり
今後の変更等がある可能性があります。

ちなみに、私以外の参考レビュー
https://qiita.com/drafts/07cc912dc2cc11d5afb8/edit
*重量がちょっと違います
##スペック
CPU：Intel Core m3-8100Y 
メモリ：８GB
HDD：SSD256GB
ディスプレイ：12.3インチ 
全重量（ペン、キーボード）：1101g〈約1.1Kg)
##開封
海外からくる荷物と一緒でいつものビニール袋に入って届きました。
（段ボールの箱ではないんですね）
中はしっかりとエアキャップで包れています。
![DSC_0113 (2).JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/5dab8688-e89d-f9a0-c7aa-1028f2201f0b.jpeg)
正直ギフトボックスがしっかりしていて拍子抜けするレベルです。
![DSC_0114 (2).JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/943bcee5-b745-1691-3328-0c0ab80b0b6e.jpeg)
![DSC_0115 (2).JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/b9678884-eaa9-4eee-84ea-0784bed0370f.jpeg)
ペンとキーボードが付属です。
![DSC_0116 (2).JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/acdbb50a-4441-8a82-7526-502eea41e8ba.jpeg)
PC本体はクッションで包まれており、非常に好印象です。
![DSC_0118 (2).JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/6346aced-9c58-d6a0-d8e7-0ba2f5068986.jpeg)
ギフトボックスはいいのですが、PCを包む袋は中国製の質が悪いもので、これはダメですね。
ここまでは、大手メーカー製と遜色ないどころか、良いですね。
![DSC_0120 (2).JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/ed0f8de6-c0f8-7e44-6056-f4d7a65e869d.jpeg)
この形態にするためには、スタンドを起こす必要があるのですが、硬くて折れるんじゃないかな？と思ってしまいます。
使い勝手が悪くて難ありですね。
##開封レビュー
液晶保護フィルムが貼られているようで、表皮を剥げばそのまま使用可能です。
##ペン
ペンはバッテリータイプです。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/b4d99518-47a8-7a3e-18b9-3f441c2c7bf3.jpeg" alt="" width="300"height="" border="0" />
バッテリーでないものは単６の電池で、入手性がわるいのが難点でしたのでスゴイ良いです。
ただし、キーボードのペン入れにペンを入れるとキツキツでいつか切れると思います。（抜けない方がいいのかな？）
##日本語入力対応
英語キーボードでそのままでは日本語の入力ができないので以下ソフトを入れました。
alt-ime-ahk
https://www.karakaram.com/alt-ime-on-off#usage
##キーボード
不良なのでしょうか？
下矢印↓のキーがケースに当たってうまく押し込めません。
個体の問題なのか？仕様なのか不明ですが、ここは改善すべきだと思います。
(Fnもダメなので全体が右斜め下に曲がっているようです）
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/283a5b02-4646-5835-dd3e-731a4f872cad.png" alt="" width="1000"height="" border="0" />
さらに、たわみが大きく使い勝手はよくありません。
Surface Goもこのタイプで非常に使い勝手が良くなかったです。
ここは改善してほしいところです。
Fxキーを設定する手法がわからず、苦戦しています。
Fn+ESCなど試したのですが駄目でした。
切り替える手法があるはずです。
##ACアダプター
ACアダプターは本体上部右側に取り付けます。
これが非常に位置が悪い本当に最低です。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/92d438af-8b31-e987-6553-30811e3d0a4a.jpeg" alt="" width="1000"height="" border="0" />
ケーブルをタイラップで止めているとはいえ、これでは使い勝手が悪く、危険です。
できるならばUSB Type-Cのマグネットタイプにする方が良いと思います。
（Magsafeではありませんが、外れないと危険です)
そして、反対側にはイヤホンジャックがついています。
大きさが一緒で、間違えて指してしまう事があります。
これデザインした人のセンスが悪すぎます・・・
##出力端子
USBと、USB-C、MicroHDMIです。
USB-Cで充電が可能なので、USBハブを使用してHDMI出力した方が良いですかね？
ただ、これも位置が悪いのでケーブルがだら～と落ちてしまい不格好です。
#総評
SurfaceGoは小さく軽いのですが、性能的にきつく使えない代物でした。
今回のUbookProは、サイズが若干大きく、重い割に性能的には大きな問題がなく値段もはるかに安いです。
ただし、キーボードが英語キーボードであり、慣れない人は全く使えないです。
SurfaceGoと同じくキーボードがやわやわなところも問題です。
また、Core i5の機種ではないので、性能的にすごくいいわけではないこと
さらに、現在の主流ノートパソコンよりも重いことがあげられます。

ただし、値段を考えればコストパフォーマンスが良い製品だと思います。
openVINOをバージョンアップする

#目的
openVINOをバージョンアップする必要があったので、バージョンアップした。
その方法を記す。

#バージョンアップ方法
##環境

パソコン：ideapad 320S
CPU: Intel Core i3-7100U CPU @ 2.40GHz
OS：　Windows10 バージョン1803(OSビルド 17134.829)
利用したソフト:openvino_2019.1.148(<- これを、2019.3に上げた）

##バージョンアップ方法
単に、
**openVINOのサイトから、
欲しいバージョンを選択して、インストールするだけ。**
インストールするとそのバージョンのフォルダが追加されます。
openVINOのサイトでは、**最新バージョンのインストールのリンクが示されるが、それをクリックすると、あっさり、欲しいバージョンがリストから選べる。**

(https://docs.openvinotoolkit.org/latest/_docs_install_guides_installing_openvino_windows.html)
<img width="765" alt="openvino_install.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/342207/8a38e92f-2023-9c20-f9f0-51e5ff4d4a45.png">

#　リリースノート
リリースノートは、以下にあります。
https://software.intel.com/en-us/articles/OpenVINO-RelNotes

⇒　ディレクトリが、**articles**なのが、すごく気になるのですが、
　　単純に日本語にすると、「記事」、「論説」だと思うですが、
　　なんで、リリースノートが。。。？？？
　　（英語なので、Intelの人のほうが詳しいんですが。。勉強しますっ。）


余談ですが、例えば、インストールするPCがWindowsだとして、
Windows関連の部分のみ探すと、リリースノートには、たどり着けません。
**openvinoの最初の入り口**、
https://software.intel.com/en-us/openvino-toolkit
からだと、あっさり、たどり着きます。

# 古いバージョン
latest以外のバージョンもあっさりたどりつくと書きましたが、
古いのは、見えなくなっているのかもしれません。
2018があるはず。以前は、表示されていたかも。

（出典：上記のダウンロードでたどり着くページ）
<img width="623" alt="intel_latest.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/342207/9da7c4e1-0b3c-d6c5-1abf-258e26e0f716.png">


#今後
特にありません。
コメントなどあれば、お願いします。
(~~バージョンアップのリリースノートみたいなの、どこかにあるんですかね。。。？？何が変更されたのかを知りたいという意味です。~~）
リリースノートの場所、教えて頂きました（検索で自分でも見つけてました。。）
仕様変更の分類。仮説（200）

仕様変更という言葉で意思疎通が難しい場合の条件分岐の候補を列記してみる。

＜この項は書きかけです。順次追記します。＞
# 作業
これから作業が必要な仕様変更と、
これからの作業を省略するための仕様変更（現状で収める）とがあるかもしれない。
# 費用
新たな費用が発生する仕様変更と、
新たな費用が発生しない仕様変更があるかもしれない。

後者の場合は、他に文書等で合意済みの事項が、仕様に記載されていなかった場合にありうる。
# 納期
納期を期日より前に納品するための仕様変更と
納期を遅らせることを含む仕様変更があるかもしれない。
# 範囲
範囲を狭くする仕様変更と、
範囲を広くする仕様変更があるかもしれない。

範囲を広くする場合に、作業、費用がかかるとは限らない。
基本設計の範囲が広く、範囲を狭めるためには、設計変更が必要になる場合には、範囲を狭くする方が大変な場合がある。
# 発案
第一者からの発案か、第二者からの発案か。

発案側に利益があるとは限らないかもしれない。
# 外部の制約条件の変化
法律（和暦、税率、各種制限金額・料金等）の改定にともなう変更
契約の両社に責任のないハードウェア・ソフトウェア・サービスの廃止・終了に伴う変更
# 文書履歴(document history)
ver. 0.01 初稿 20200224
ver. 0.02 外部の制約条件の変化　追記 20200225
### 最後までおよみいただきありがとうございました。

いいね　💚、フォローをお願いします。

#### Thank you very much for reading to the last sentence.

Please press the like icon 💚　and follow me for your happy life.
AIの検討に使える動画をダウンロードする

#目的
AIの物体検出等を検証する際に動画が必要となる。
ノートパソコンのカメラで適当に撮影することは可能であるが、第三者との共有等も考えると、もう少し別の素材を使いたい。
**無料で取得できる動画は沢山あるハズであるが、意外と簡単には、思った動画が取得できない。
以下、検討結果を示す。**

#結果
以下のサイトの動画は取得しやすいのではないかと感じた。

https://mazwai.com/stock-video-footage


特徴は、以下、3点。

+ **登録的なものが不要。(すぐ、ダウンロードできる）**
+ **権利が明確（Creative Commons 3.0 (CC-BY 3.0) と、もっとフリーなのどちらか）**
+ **質が良い**




<img width="806" alt="video.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/342207/ccafeb9f-fa24-d358-4f0e-c4f7344efca1.png">


ライセンスについては、以下のように説明されている。
https://mazwai.com/license-details
から抜粋


<img width="619" alt="license1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/342207/5dd0721e-fa43-6d42-01f0-2def11d5c020.png">


#まとめ

ご参考になれば。
（コメントなどあれば、お願いします。）
【AWS】パブリックサブネットとプライベートサブネットの違いとは

# はじめに

AWSを最近ちょくちょく触るようになったのですが、

プライベートサブネットってなんだ？
パブリックサブネットとの違いってなんだ？

となったので、自分の中で整理しながらまとめたいと思います。

私の勘違いによる誤記があるかもしれません、気軽に指摘していただけると嬉しいです。


## 基本的な違い
基本的な違いは、グローバルネットワークから通信できるかどうかです。

|サブネット|グローバルネットワーク to サブネット|
|---|---|
|パブリック|OK !!|
|プライベート|<font color="red">NG</font>|

逆の通信（サブネットtoグローバルネットワーク）では区別されません。
設定次第ですが、プライベートサブネットからもグローバルネットワークへは通信可能になります。

|サブネット|サブネット to グローバルネットワーク|
|---|---|
|パブリック|OK !!|
|プライベート|OK !?|

## よくある構成
よくある構成だと、以下のように区別されます。

|サブネット|構成例|
|---|---|
|パブリック|APサーバー（アプリケーションサーバー）|
|プライベート|DBサーバー|


## 具体的な違い
続いて、AWSでの設定が具体的にどうのように違っているかです。

### 1. 通信先
まず通信先（ゲートウェイ）が異なります。

|サブネット|通信先|
|---|---|
|パブリック|インターネットゲートウェイ（インターネット繋ぐマン）|
|プライベート|<font color="red">NATゲートウェイ</font>（プライベートIPをパブリックIPに変換するマン）|


**（3/1 追記）**
プライベートサブネットにNATゲートウェイを通信させるかはオプションになります。
NATゲートウェイに繋がっていなくとも、
インターネットゲートウェイをアタッチしてないサブネットはプライベートサブネットと呼べそうです。


### 2. パブリックIP
次にパブリックIPを持つかどうかが異なります。

|サブネット|パブリックIP|
|---|---|
|パブリック|持つ|
|プライベート|<font color="red">持たない</font>|

一方プライベートIPはどちらも所有しています。

|サブネット|プライベートIP|
|---|---|
|パブリック|持つ|
|プライベート|持つ|

プライベートサブネットはパブリックIPを持たない代わり、
NATゲートウェイに通信を行うことでパブリックIPに変換をしてもらってグローバルネットワークに接続できるようになります。
（正確には、NATゲートウェイからインターネットゲートウェイに通信します。下図参考）

NATゲートウェイはプライベート側からの通信を通しますが、逆に外からプライベート側への通信は行いません。
そのようにしてプライベートに保っています。

<img width="360" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533841/c95834fc-0849-f4ea-5d4b-01eace96a508.png">


# まとめ
最後に違いをまとめて終わります。

### 基本的な違い

|サブネット|グローバル to サブネット|サブネット to グローバル|構成例|
|---|---|---|---|
|パブリック|OK !!|OK !!|APサーバー|
|プライベート|<font color="red">NG</font>|OK !?|DBサーバー|

### 具体的な違い

|サブネット|通信先|パブリックIP|プライベートIP|
|---|---|---|---|
|パブリック|インターネットゲートウェイ|持つ|持つ|
|プライベート|<font color="red">NATゲートウェイ</font> (※Option)|<font color="red">持たない</font>|持つ|

# 最後に

じゃあプライベートサブネットってどう作るのよって手順を、次回まとめようかなと思います。

# 参考
- [パブリックサブネットとプライベートサブネットの違い](https://josys-memo.com/public-private-subnet/)
- [NATゲートウェイを使ってインターネットへ接続する方法](https://tech-dive.xyz/2019/01/03/post-1716/)
Arch Linux における Btrfs の基本的な使い方

# はじめに

主に [ArchWiki](https://wiki.archlinux.jp/index.php/Btrfs) と [btrfs Wiki](https://btrfs.wiki.kernel.org/index.php/Main_Page) を参考にしました。

# インストール

[btrfs-progs](https://www.archlinux.jp/packages/?name=btrfs-progs) をインストールしてください。

# ファイルシステムの作成

## ラベルの指定

ファイルシステムの作成には `mkfs.btrfs` コマンドを使用します。必須の引数はパーティションだけですが、`-L` オプションを使用することでラベルを設定できます。

```console
# mkfs.btrfs -L mylabel /dev/partition
```

## RAID の使用

`-m` オプションでメタの RAID モードを、`-d` オプションでデータの RAID モードを指定します。

```console
# mkfs.btrfs -m raid1 -d raid1 /dev/sda /dev/sdb
```

`/etc/fstab` を編集してマウントオプションを設定し、`mount -a` でマウントします。

```config:/etc/fstab
UUID={uuid}	/data		btrfs		noatime,compress-force=lzo,space_cache	0	0
```

| Option         | Description                                                    |
| -------------- | -------------------------------------------------------------- |
| noatime        | 最終アクセス日時を記録しません。パフォーマンス改善が目的です。 |
| compress-force | ファイルサイズが増加する場合を除いて透過圧縮機能を使用します。 |
| space_cache    | フリースペースキャッシュを有効にします。                       |

実際に RAID が機能していることを確認するには以下のような方法があります。

```console
# btrfs filesystem df /data
Data, RAID1: total=1.00GiB, used=512.00KiB
System, RAID1: total=8.00MiB, used=16.00KiB
Metadata, RAID1: total=1.00GiB, used=112.00KiB
GlobalReserve, single: total=3.25MiB, used=0.00B

# btrfs filesystem show /data
Label: {label} uuid: {uuid}
Total devices 2 FS bytes used 640.00KiB
devid    1 size 1.82TiB used 2.01GiB path /dev/sda
devid    2 size 1.82TiB used 2.01GiB path /dev/sdb
```
F#でのコンソールの入出力

# 出力

```F#:出力
open System

[<EntryPoint>]
let main argv =
    // その1
    printfn "Hello World from F#!"
    // その2
    Console.WriteLine("Hello World from F#!")
```

# 入力

```F#:入力
open System

[<EntryPoint>]
let main argv =
    let line = Console.ReadLine()
```
【ARKit】配置した3Dモデル（アニメーションつき）を削除する

# はじめに
[別記事](https://qiita.com/c_geru/items/6b48dffef7f0aa454a2b)で書いたアニメーションつきの3DモデルをARKitに追加するのに引き続き、ARKItに追加した3Dモデル（アニメーションつき）を削除するときにも躓いたので、そのメモ。

以下のサイトを参考に、長押しで3Dモデルを消そうとしたが削除できませんでした。このサイトではプリミティブなオブジェクト（cube）を配置しているので、今回使う3Dモデル（アニメーションつき）と何が違うのか？

- [ARKitで３Dオブジェクトを操作する](http://artteknika.hatenablog.com/entry/2018/07/31/231604)

# 実行環境
- Xcode 11.2.1

3DモデルはMagicaVoxelで作って、Mixamo でアニメーションをつけたものを使用しました。

- [MagicaVoxel](https://ephtracy.github.io) 0.99.4
- [Mixamo](https://www.mixamo.com)


# .scnファイルの構造
.scnファイル（sitting.scn）を開いてみると、直下に「sitting」ノードがあって、その中に3Dモデルとボーンの設定が含まれています。
 [^1]:
![cap01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106624/39fbb718-ee80-4fc4-3716-f5ee8606ded4.png)

# アニメーション付き3Dモデルの配置時
配置するスクリプトは、直下の「sitting」のノードを取得して、self.mainSceneView.scene.rootNode に追加するようになっていますが、追加するノードに名前がないため、名前をつける処理（node.name = selectedItem）を追加しました。

※削除する際に、どのノードか判断するためです。


```Swift:アニメーション付き3Dモデルの配置

    var selectedItem: String? = "sitting"

    //（中略）

    /// アイテム配置メソッド
    func addItem(hitTestResult: ARHitTestResult) {
        if let selectedItem = self.selectedItem {

            // .scnファイルから新しい3Dモデルのノードを作成
            let scene = SCNScene(named: "art.scnassets/\(selectedItem).scn")
            let node = (scene?.rootNode.childNode(withName: selectedItem, recursively: false))!

            // 現実世界の座標を取得
            let transform = hitTestResult.worldTransform
            let thirdColumn = transform.columns.3

            // 3Dモデルの配置
            node.position = SCNVector3(thirdColumn.x, thirdColumn.y, thirdColumn.z)
            
            // 3Dモデルのサイズを変更
            node.scale = SCNVector3(0.05, 0.05, 0.05)
            
            // 3Dモデルに名前をつける
            node.name = selectedItem
            
            // シーンに追加
            self.mainSceneView.scene.rootNode.addChildNode(node)
        }
    }
```

# アニメーション付き3Dモデルの削除

[.scnファイルの構造](#scnファイルの構造)で見たように、配置したモデルは「sitting」というノード名で、その中に3Dモデル（unamed）とボーン（mixamorig_Hips）が含まれています。

長押しでのオブジェクトが存在するかどうかの判定は、[ARSCNView.hitTest(_:types:)](https://developer.apple.com/documentation/arkit/arscnview/2875544-hittest)で行いますが、このときの検出対象は3Dモデル（unamed）になるため、ノード全体を削除するには親である「sitting」ノードを削除する必要があります。

削除の処理は以下のようになります。

```Swift:アニメーション付き3Dモデルの削除

    // ロングプレスイベントハンドラの登録
     let longPressGesture = UILongPressGestureRecognizer(target: self, action: #selector(longPressView))
     self.mainSceneView.addGestureRecognizer(longPressGesture)

    //（中略）

    // 長押しでキャラクタを削除する
    @objc func longPressView(sender: UILongPressGestureRecognizer) {
        print("----長押し！")
        
        if sender.state == .began {
            let location = sender.location(in: self.mainSceneView)
            let hitTest  = self.mainSceneView.hitTest(location)
            
            if let result = hitTest.first  {
                
                // 3Dアニメーションモデルは、複数パーツで構成されるため、親ノードの名前で判定・削除する
                if result.node.parent!.name == selectedItem
                {
                    result.node.parent!.removeFromParentNode();
                }
            }
        }
    }

```

# まとめ
ノードを扱う際には、常に階層構造を意識しないとダメってことですね（わかってみれば当然ですが）。

他にもっといい方法があれば、教えてください。
rails アプリ立ち上げで最初にやること

アプリ立ち上げで最初にやるのはターミナルを開いて
rails new アプリケーション名 -オプション名
私が使ってるオプション名はmysqlなので
rails new mangasuki -d mysql
となる。
バージョン指定するときは
rails _5.2.3_ new mangasuki -d mysql
という風に記述すればバージョンの指定ができる。
数字の前後にアンダーバーをつける。
フロント実装

Editボタン
= link_to "Edit", "#", class: 'btn'
で出来た。
scssの変数化がなんとか出来た
$text-color: #ffffff;
$btn-color: #38aef0;
$list-color: #434a54;
$date-color: #999999;

@mixin circle($size) {
  width: $size;
  height: $size;
}
カラーの部分がメインでwidth,heightうまく出来なかったけど、チャレンジだけはしてみた。
ざっくりDocker

Dockerをしっかり無理解状態で`docker-compose`や`Kubernetes`を学ぼうとしていて結果的にえらい回り道をしている気がしたので、まずはDockerについてざっくりでも理解するために書き残す。

※ちなみに`docker-compose`や`Kubernetes`、`ECS`などは復数のDockerを扱うための技術とのことで、`Docker`のメリットを享受できていない内に学ぼうとしても頭に何も残らなかった。。。

Dockerに関する記事はたくさんあるので、とりあえず、イメージとコンテナの二つを理解したら何となく使えるようになった。

※Dockerfileの書き方はそのうち追記します

### イメージ
コンテナの元。コンテナを使うにはまずイメージがなければいけない。
イメージはダウンロードするか、人からもらうか、自分で作るかで手に入れたりできる。
シンプルなイメージなら公式からダウンロードで取得できるが、会社と同じ環境を自宅で再現したいとかであれば自分で作るか誰かが作ったのをもらうしかない。

### コンテナ
イメージから作成した別の環境

シンプルに自分のPC環境に別のPC環境を作る技術と理解している。
このおかげでぶっ壊しても平気なのでとにかく色々試せるし、人と共有も簡単にできるんだな〜ってこと。

### Dockerfile

 `Dockerfile`はイメージを作成するためのファイル。
公式イメージから自分で手を加えて、自分専用のイメージを作成したりできる。


## コマンド

#### イメージ関連コマンド


```:イメージを検索。使いたいOSや言語などを検索すれば大抵の公式イメージが存在する
docker search イメージ名
```
```:イメージを取得
docker pull イメージ名
```
```:DockerFileからイメージを作成する
# イメージ作成基本コマンド。この場合イメージ名はランダムにつけられる
docker build (DockerFileのある)パス

# イメージ名を独自につける
docker build -t 名付けたいイメージ名 (DockerFileのある)パス

# イメージ名とタグを独自につける
docker build -t 名付けたいイメージ名:タグ (DockerFileのある)パス

# 例
docker build -t sample:1 .
・
・
・
# 省略
Successfully built 1234abcdefgh ←作成されたイメージID
Successfully tagged sample:1  ←イメージ名とタグがつく。オプションつけなければこの表記されない
```


```:保有するイメージ一覧を確認する
$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
sample              1                   1234abcdefgh        8 minutes ago       1.97GB

# REPOSITORYがイメージ名
```
```:dockerイメージの作成履歴を確認
docker history イメージ名
```
```:イメージを削除する
# 対象を指定する際はイメージ名、イメージ名:タグ、イメージIDのどれかで指定する
docker rmi イメージ名
docker rmi イメージ名:タグ
docker rmi イメージID
```

#### コンテナ関連コマンド

```:コンテナの中でbashを利用して起動
docker run -it イメージ名 bash

# 作成するコンテナに名前をつける場合
docker run --name 名付けたいコンテナ名 -it イメージ名 bash
```
※`-i`はコンテナの標準入力を有効化
※`-t`はttyを有効化

※ ちなみにイメージを未取得で`docker run イメージ名`とコマンドを叩くと自動的にpullしてからrun(起動)してくれる

```:コンテナの状態確認
# 起動コンテナのみ表示
docker ps
# 停止コンテナも含めて表示
docker ps -a
# 停止コンテナも含めてコンテナIDのみ表示
docker ps -aq
```
```:コンテナを起動
docker start コンテナ名
```
```:コンテナを停止
docker stop コンテナ名
```
```:バックグランドで起動しているコンテナに入る
docker attach コンテナ名
```
```:dockerコンテナを削除
docker rm コンテナ名 or コンテナID
```
```:dockerコンテナの標準出力のログを確認
docker logs コンテナ名 or コンテナID
```
#### ネットワーク関連コマンド

```:dockerネットワークを表示
docker network ls
```
```:dockerネットワークの詳細を確認
docker network inspect ネットワーク名 or ネットワークID
```
```:dockerネットワークを作成
docker network create --attachable -d ネットワーク名 --subnet=172.17.0.0/16 作成ネットワーク名
```

#### Docker for Mac

```:Macでvolumeに保存されているVMに入る
screen ~/Library/Containers/com.docker.docker/Data/vms/0/tty
```

[参考リンク](https://y-ohgi.com/introduction-docker/)
学習記録（４日目）#相対パスから絶対パスを取得する方法

# 学習内容
* 相対パスから絶対パスを取得する方法
* Python基本文法

## 相対パスから絶対パスを取得する方法
HTMLでリンク先が相対パスで記述されていた際には、`urllib.parse.urljon()`を利用して絶対パスを取得する。

##### 記述例

~~~python
from urllib.parse import urljoin

base = "http://exsample.com/html/a.html"

compurl = lambda q: print(urljoin(base,q))
compurl("b.html")
compurl("sub/c.html")
compurl("../index.html")
compurl("../img/hoge.png")
~~~
実行結果
>http://example.com/html/b.html
>http://example.com/html/sub/c.html
>http://example.com/index.html
>http://example.com/img/hoge.png

## Python基本文法

### `pass`文
Pythonではインデントによって処理ブロックを定義するので、処理を行う必要のない時には処理ブロック自体がなくなってしまう。そこで、何も処理を行うことを明示的に記述するために`pass`文を用いる。

~~~python
with open('exsample.txt', 'w'):
    pass
~~~

### 条件分岐
`if`、`elif`、`else`を用いて記述する。また、一つの条件式によって2通りの処理ブロックに分岐する場合は三項演算子を用いて記述することもできる。

~~~python
if 条件式１:
    ＜処理ブロック１＞
    # 条件式１がTrueのときに実行される処理
elif 条件式２:
    ＜処理ブロック２＞
    # 条件式１がFalse、かつ条件式２がTrueのときに実行される処理
else:
    ＜処理ブロック３＞
    # 条件式１がFalse、かつ条件式２がFalse、かつ条件式３がTrueのときに実行される処理

# 三項演算子による条件分岐
# 条件式がTrueのとき値１、Falseのとき値２
値１ if 条件式 else 値２
~~~

### イテレータ
データを表す値そのものではなく、一連のデータを生成することができるルールとしてデータを保持する。大量のデータが必要なときには、イテレータを用いた方がメモリ効率が良い。以下に`range`型のイテレータの記述例を示す。

~~~python
# 以下3つのrange()は,0から9まで、1ずつ増えるイテレータを返す
range(0, 10, 1)
range(0, 10)
a = range(10)

print(a)
print(a[0])
~~~
実行結果
>range(0, 10)
>0

`range()`は、Pythonでは使うことができないインクリメント演算子（`++`）の機能を備えている。デクリメント（`--`）は`reversed()`というイテレータを用いて行う。

### `break`文と`continue`文
ループ文の処理ブロック内に記述することで、実行中のループ文を制御することができる。

##### `break`文  
現在実行中のループを中断してループの外に抜ける。


~~~python
b = 0
while True:
    b += 1
    if b > 5
        break    # b = 6　となった時点でループから抜けて処理が終了する。
    print(b)
~~~
実行結果
>1
>2
>3
>4
>5

##### `continue`文  
実行中の処理ブロックを中断して、ループの条件式評価まで処理を移動する。

~~~python
c = 0
while True:
    c += 1
    if c < 5
        continue    # b = 6　となるまでこの先の処理は実行されない。
    print(c)
    break
~~~
実行結果
>6

# まとめ
利用しているスクレイピングに関する参考書のコードの理解に苦労し始めたので、再びPythonの基礎文法についての学習を始めることにした。`C`や`Java`では非常に便利だったインクリメント・デクリメントが使えないことには驚いたが、累算代入（`+=`, `-=`）やイテレータを用いてうまく対応していけるようにしたい。

## 参考書
参考にした書籍から公開されているGitHubを添付しておきます。
[増補改訂Pythonによるスクレイピング&機械学習 開発テクニック](https://github.com/kujirahand/book-python-scraping)
Pythonでリストにデータを追加するときのappend()と"+="演算子の挙動の違い

Pythonでリストにデータを追加するときの`append()`と`+=`演算子の挙動の違いを確認したのでメモ。

## `append()`の場合

いずれの型（文字列型、数値型、辞書型、配列型など）であっても、指定したデータのまま1要素として配列に追加される。

```py
>>> d_list = []
>>> d_list.append('Hello')
>>> d_list.append(123)
>>> d_list.append({'a':1, 'b':2, 'c':3})
>>> d_list.append([1, 2, 3])
>>> d_list
['Hello', 123, {'a': 1, 'b': 2, 'c': 3}, [1, 2, 3]]
```

## `+=`の場合

イテレータとしての動作をし、指定したデータのイテラブル（iterable）のすべての要素が配列に追加される。
動作としては`extend()`と同じとなる。

文字列型のデータは各キャラクターが1要素として追加される。

```py
>>> d_list = []
>>> d_list += 'Hello'
>>> d_list
['H', 'e', 'l', 'l', 'o']
```

数値型のデータはiterableではないのでエラーとなる。

```py
>>> d_list += 123
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'int' object is not iterable
```

辞書型のデータは各要素のキー名がそれぞれ1要素として追加される。

```py
>>> d_list = []
>>> d_list += {'a':1, 'b':2, 'c':3}
>>> d_list
['a', 'b', 'c']
```

配列型のデータは各要素がそれぞれ1要素として追加される。

```py
>>> d_list = [1, 2]
>>> d_list += [3, 4, 5]
>>> d_list
[1, 2, 3, 4, 5]
```

## 参考

- https://docs.python.org/ja/3/tutorial/datastructures.html#more-on-lists

> 5.1. リスト型についてもう少し
> 
> list.append(x)
> リストの末尾に要素を一つ追加します。a[len(a):] = [x] と等価です。
> 
> list.extend(iterable)
> イテラブルのすべての要素を対象のリストに追加し、リストを拡張します。a[len(a):] = iterable と等価です。

以上
Raspberry Pi のvi編集モードで入力ができない事象の解消

Raspberry Pi において、viコマンドでファイル編集しようとしても、編集モードでキーボードで意図した入力ができない事象を解消します。

「vi互換モード」で動いている時に発生する事象のようなので互換モードを無効にします。

以下を参考にしています。
Vimで方向キーを押すとABCDが出る問題を直す
http://marupeke296.com/IKDADV_PI_ABCDProb.html

#環境
macOS High Sierra 10.13.6
Raspberry Pi Zero WH（Rasbian）

#設定ファイルの作成
macで以下のファイルを作成し、Raspberry Pi にSCPでコピーします。

```
$ vi .vimrc
$ cat .vimrc

set nocompatible

$ scp .vimrc pi@192.168.10.110:/home/pi/
$ ssh pi@192.168.10.110
$ ls -l .vimrc

-rw-r--r-- 1 pi pi 17 Mar 15 14:39 .vimrc

$ cat .vimrc

set nocompatible
```
エクセルvbaの覚書

#忘備録
##Office 2019でも印刷プレビューコマンド使えるのかやってみた。
結果⇒問題なく動作

```
Sub 印刷()
Sheets("Sheet1").PrintOut Preview:=True
End Sub
```


##②vbaでvlookup的なコマンド

```
hogehoge = Application.VLookup(検索値, 探すエリア, 行数, 近似or完全)
```

##③ラベルを動的に動かす

```
Label1.Caption = "hogehoge"
```


##④入力値を日付に変換する

```
hogehoge = CDate(TextBox1.Value)
```


##⑤日時の差を求める（日付同士の引き算的な感じ）

```
hogehoge = DateDiff("d", 開始日時, 終了日時)
```

##⑥シートのある範囲をコンボボックス化

```
Dim lRow As Long
Dim i As Long, myCnt As Long
Dim hogehoge

With Worksheets("Sheet1")
     lRow = .Range("A" & Rows.Count).End(xlUp).Row
     hogehoge = .Range("A2:A" & lRow).Value
End With

With ComboBox1
     .ColumnCount = 1
     .ColumnWidths = "50"
     .List = hogehoge
End With
```

##⑦エラーが発生した行の次から続行する
```
On Error Resume Next
```

##⑧フォームをアンロード（解放？）
```
Unload UserForm1
```

##⑨Excel Windowsを表示・非表示にする
```
Application.Visible = True '表示
Application.Visible = Flase '非表示
```

##⑩シートをSheet1表示・非表示にする
```
Sheets("Sheet1").Visible = True '表示
Sheets("Sheet1").Visible = Flase '非表示
```

##⑪エラーは発生したらエラー処理コードにジャンプする
```
On Error GoTo Errlbl
  'エラーが発生しそうなコード
　 Exit Sub 'エラーが発生しそうなコードが正常に終わったら抜ける
Errlbl:
　'エラー処理時の対応
```

##⑫Excelマクロのフォームを初期化する
```
Private Sub UserForm_Initialize()
'宣言
Dim hogehoge as xxx

' Excelウィンドウを非表示にする
    Application.Visible = False
End Sub
```

##⑬チェックボックスの使い方
```
CheckBox1.Value = True 'ONのとき
CheckBox1.Value = False 'OFFのとき
```

##⑭オプションボタンの使い方
```
OptionButton1.Value = True '選択されているとき
OptionButton1.Value = False '選択されていないとき
```

##⑮A列がIDと見立てたDBみたいな使い方しているとき空白の行に新規レコードを追加する動き
```
'この処理でoffsetが２行目以降頭がゼロのため、右にずれて記録してくれる。
Sheets("Sheet1").Range("A1").End(xlDown).Offset(1, 0).Value = hogehoge
Sheets("Sheet1").Range("A1").End(xlDown).Offset(0, 1).Value = hogehoge
Sheets("Sheet1").Range("A1").End(xlDown).Offset(0, 2).Value = hogehoge
```
DB2-SQLチューニング　想定通りのインデックスに当たらない時に確認すること

DB2でSQLチューニングをしていた際にはまったことを書き溜めていきます。

SQLチューニングをいきなり任されて全然わからん、インデックスを作ったはいいが全然当たらないよ！、という方のお役に立てればと思います。

※もし、情報が間違っていたらご指摘いただけると幸いです。

##Q.そもそもインデックスとは
索引のこと。本の冒頭に書かれている目次を想像してもらえればいいです。

##Q.インデックスにはどんな役割があるのか
データに高速でアクセスができる。
どういうことかというと、
例えば、あなたはある本の中から必要な情報を見つけようとしています。
目次がなかった場合、最初のページから必要な情報があるページまですべてに目を通す必要があります。
これでは物凄い時間と労力がかかってしまいます。

これに対して目次がある場合はどうでしょうか。
下記のような目次があるとします。

1. 生きる方法
    2. 食べる
    3. 寝る
    4. あきらめる
2. 稼ぐ方法
    3. 投資をする
    4. スキルアップする
        21. 資格を取る
        22. 講習に参加する

もし”資格を取る”という情報が欲しい場合は”稼ぐ方法 - スキルアップをする - 資格を取る"というように辿れば、短時間かつ労力を使わずに必要な情報にたどり着けます。

これと同じでデータベース（本）にアクセスし、必要な情報（資格を取る）を取得する際に、インデックス（目次）を使用することで高速（短時間）かつCPU負荷（労力）を抑えて取得することができます。

##Q.インデックスの作り方
基本的には上で説明したような目次を作っていけばいいです。
例えば、下記のようなSQLがあったとします。

```SQL:findMember.sql
SELECT TC.MEMBER_NAME FROM T_COMPANY TC 
 WHERE TC.COMPANY = ? 
  AND TC.BUSHO = ?
  AND TC.MEMBER_BIRTHDAY >= ?
  AND TC.MEMBER_BIRTHDAY <= ?
;
```
各項目のデータバリエーション数は下記の通りとします。
- 全レコード件数：100,000
- COMPANY(会社名)：10,000
- BUSHO(部署名)：20
- MEMBER_BIRTHDAY：18,250(50年分)

この場合は、データがより絞れる順 = データバリエーションが多い順に項目を並べたインデックスを作成すればいいです。
・INDEX(COMPANY,BUSHO,MEMBER_BIRTHDAY)

このインデックスにより、データの絞り込みは下記のように進みます。
100,000 × (1/10,000) × (1/20) × (xxx/18,250)
※日付は入力値に依る

##Q.インデックスを作ったけど当たらないんだけど！
インデックスが当たらない原因はいくつかありますが、ざっと以下の通りです。（他にもあるかもしれません）
①データバリエーション、データ件数が少ない
②データの作り方が悪い
③絞り込まれる順にインデックス項目が並んでいない
④インデックス項目が多すぎる

ひとつずつ解説していきます。
###①データバリエーション、データ件数が少ない
データのバリエーションが少ないとインデックス項目が当たった時に絞り込める割合も必然的に少なくなります。
先ほどのSQLの例で行けば、COMPANY(会社名)の種類が3つしかない場合は、全体の33%にしかなりません。この絞り込める割合が小さいとDB2が「インデックス使っても大して絞り込めないから、使わなくていいや」と判断し、使われなくなります。
インデックスが使われるかどうかはDB2しかわかりませんが、目安として全体の25%以下に絞り込めると使用されるみたいです。

###②データの作り方が悪い
インデックス項目で絞り込んでいった時に、データバリエーションが少なくなると当たらなくなります。例えば下記のようなデータを作成した場合です。
・理想データ：COMPANY(10,000種類)で絞り込んだ時点でBUSHOが20種類存在。
・ダメなデータ：COMPANY(10,000種類)で絞り込んだ時点でBUSHOが2種類存在。(本来は20種類あるはず)
ダメなデータで作成した場合はCOMPANYで絞った時点で2種類しかないので50%にしかならず、BUSHOというインデックス項目にはヒットしません。

なので、インデックス項目全部に当てたい場合は絞り込まれた時点でもデータ種類が多く存在するデータを作成する必要があります。
もちろん、絞りこまれた時点で2種類になるのがデータとして正しい、という場合は問題ありませんが、インデックス項目を見直す必要があります。

###③絞り込まれる順にインデックス項目が並んでいない
これはそのままの意味です。
DB2のオプティマイザは"より絞り込まれる項目を選ぶ"という性質があるため、その通りにインデックス項目が並んでいないと、うまく当たらないことになります。

###④インデックス項目が多すぎる
インデックスの項目が多すぎると当たりにくくなるみたいです。これには私も驚きでした。
例えば下記のような場合は当たりません。
当てたい項目:COMPANY,BUSHO
想定：INDEX(COMPANY,BUSHO,BUSHO_SUB,YOSAN,YOSAN_SUB,MEMBER_BIRTHDAY)
実際：INDEX(COMPANY,MEMBER_BIRTHDAY)

上記のように項目が多いとダメで下記のように項目を減らすと当たります。
INDEX(COMPANY,BUSHO,MEMBER_BIRTHDAY)

以上です。
複雑さが理由で選ばれないと言うことは珍しいことではない

https://qiita.com/Rwf-9DH3/items/fe65756c0485f095cc98

ここまで悲惨ではないところの話として。

まるっと江添氏のブログエントリを紹介するだけになってしまうのだけど。

Linus(慣例に従って敬称略)がC++を選ばないことについては、Cのその移植性だとか、当時のC++コンパイラの性能だとか、複雑さ以外にも色々他にもっと厳密な世界での価値判断もあったと思うので、それと同等の価値判断・選別が常に行われているわけではないのだけど。

参照: https://cpplover.blogspot.com/2013/05/linus-torvalsc.html

GitもLinux kernelもC++ではなくCを選んでいる。(kernelについてはなかなかC以外の言語を選ぶという判断が難しそうと言うのはあるかも知れないけど)

その人が管理しているプロジェクトにおいて、何らかのポリシーでもって、それを使わないという選択をするのは間違ってはいない。そのポリシーを無遠慮に他へと押しつけることが間違っている。

「是非その技術を使いましょう、今時使っていないと **時代遅れですよ** 」と推していくのも「そのような難解な技術は一切使うべきではありません、自分の足を打ち抜く **愚か者のやることです** 」と否定していくのも、そのどちらも大きなお世話である。他者に対していちいち言葉が強い。

モダンなやり方でやっていきたい人は様々なことにトライするでしょうし、保守的にやっていきたい人はその人が思う安定性を得る代償として古いやり方に縛られるだけである。


そういえば、プロジェクトメンバーのデザイナーさんがgitを一切使えず、それどころか過去に起きた操作トラブルが原因でgitアレルギーを起こしてるまであるくらいの人材だったので、最終的なmasterはタイムスタンプフォルダによるスナップショットコピーでのバージョン管理をしていたことあったっけな、と言うのを思い出しながら書いた。

選ぶ理由、選ばない理由、それは星の数だけある。選ぶこと、選ばないことが単なる無知によるものであると決めつけるのであればそれは間違っている。
Raspberry Pi の起動前にSSH、無線LAN設定を行う

Raspberry PiでGUIを使用しないで、無線LANでSSHログインまで行う設定メモです。

#環境
macOS High Sierra 10.13.6
Raspberry Pi Zero WH

RaspbianをSDカードに書き込みするまでの手順は以下にメモがあります。
https://qiita.com/nikofu501/items/26c14c25f38b88ad2685

以下を参考にしています。
Raspberry Piの無線LANをmicroSDで設定する
https://qiita.com/mascii/items/0d1a280ac58ed8f6f999

#SSHログインの有効化
デフォルトでSSHログインが無効になっているため、イメージファイルを書き込んだmacOS上で有効化します。

bootディレクトリが作成されていることを確認します。

```
# ls -l /Volumes/boot/

total 105929
drwxrwxrwx  1 _unknown  _unknown       512  3 15 17:18 .Spotlight-V100
drwxrwxrwx  1 _unknown  _unknown       512  3 15 22:42 .fseventsd
.....略
```

SSHファイルを作成します。ファイルを作成するとSSHが有効になります。

```
# touch /Volumes/boot/ssh
# ls -l /Volumes/boot/ssh

-rwxrwxrwx  1 _unknown  _unknown  0  3 15 22:48 /Volumes/boot/ssh
```
#無線LANの設定
起動時に無線LANを有効にするためには、以下のファイルを作成する必要があります。
Raspberry Pi Zero WHは2.4GHz帯しか対応していません。
　ssid・・・無線LANのSSID
　psk・・・無線LANのパスワード
ハードコーディングがセキュリティ上問題のある場合は、SSIDとパスフレーズの組をハッシュ化した256bitのキーをpskの値に設定することもできます。

```
# vi /Volumes/boot/wpa_supplicant.conf

# cat /Volumes/boot/wpa_supplicant.conf
country=JP
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1
network={
    ssid="musenlan"
    psk="123456"
}
```

SDカードをRaspberry Pi に挿入し、SSHログインできることを確認します。
Raspberry Pi のデフォルトアカウントはpi、パスワードはraspberryです。
DHCPで払い出しをしている場合はDHCPサーバのログで払い出したIPアドレスを確認してください。
無線LAN設定の時点で固定でIPアドレスを設定する方法もあるかもしれません。

```
$ ssh pi@192.168.10.110

pi@raspberrypi:~ $ 
```
vue cliでmixinを作成し、インポートする方法

備忘録です。

### したいこと
・vue cliでmixinを作成し、componentファイルで使いたい

同じ動作を複数箇所で使用したい場合は、mixinが便利です。SCSS/SASSで使うmixinと同じ役割です。

### Step 1: mixinはjsファイルに書く

mixinはvueファイルではなく、jsファイルに書きます。ここではmyFirstMixin.jsという名前のファイルを作りました。

補足：**src** のフォルダー内に **mixinフォルダー** を作成し、その中に **mixinを書いたjsファイルたち** を保存しておくと管理しやすそうです。

書き方はVueファイルで作ったコンポーネントの、scriptタグの中身と一緒です。ここではcomputedを使ったmixinを書いています。mixinしたい内容を書きます。

#### myFirstMixin.jsファイル内

```
export default {
    computed: {
        filteredBlogs: function(){
            return this.blogs.filter((blog) => {
                return blog.title.match(this.search);
            })
        }
    }
}
```

### Step 2: コンポーネントファイルで読み込む

#### component.vueファイル内

```
<script>
import myFirstMixin from '../mixins/myFirstMixin';//ここでインポートする

export default {
  data() {
    return {
        //
    }
  },
  methods: {
  //
  },
mixins: [
    myFirstMixin
]
}//ここで登録する
</script>
```

これで使えるようになりました:grin:
初心者なので、何か誤解・勘違いがあれば、ご指摘いただけると幸いです:bow:
Pythonの機械学習に関して初学者が超簡潔にまとめてみた。

<h2>Pythonの機械学習に関して超簡潔にまとめてみた。</h2>
Pythonでできることとして今話題の<span style="color: #ff0000;"><strong>機械学習/人工知能(AI)に関して</strong></span>まとめました。

<strong><span style="color: #ff0000;">機械学習とは、あらかじめ用意されたデータなどをもとに学習を行い、それに基づいて新たに提示されたデータの予測を行うという技術です。</span></strong>

ですので、データの前処理やアルゴリズム(問題を解くための手順)の選定などが重要になります。

手法に関しては2種類。

①教師あり学習→学習データとセットで正解の情報(ラベル)も用意。既存の情報から、パターンを作成し、未知のデータを予測。

②教師なし学習→正解データを持たない方式。データの特徴を分析し、データをいくつかのグループに分類化。

これを実現するライブラリの一例がscikit-learn(初学者おすすめのライブラリ)やTensorFlow(Googleが開発)です。

【機械学習の一例】
犬の写真の見極め→与えられたデータが犬の写真かどうか判定して正解だった率などを求めるなど。(判断基準には学習記録されたモデルを用いる。)
発展して、迷惑メールの見極めや人の顔の認証などにも用いられているそうです。

要するに、機械学習はモデルの選定や前処理(データを学習しやすい形にする)が重要で、それによって結果も変化します。

こういった前処理など、本質的な理解を得るために微分積分・線形代数・行列・統計学などの知識が必要になるとのことです。
(NumPyやmatplotlibなども活用して計算→可視化の実現など。)

※補足※

ディープラーニングをざっくり説明すると、機械学習からさらに発展させて、自ら見極めポイントなどを定めて学習していく技術みたいです。(おもろい)
<h2>おわりに</h2>
データ分析に興味があり、Pythonの学習を始めましたが、データ分析と機械学習は切っても切れないということがやっとわかりました。。。

追加して、本質を理解するためには数学の知識がマストということも。<del>(本当に高校・大学時代ちゃんと数学を勉強しておくべきだった。。。)
</del>

よし、頑張るぞ！！

ってことで、データ分析やら機械学習に関して興味があって、概要だけでも知りたいといった初学者の方々の参考になれば幸いです。

※僕も初学者なので間違いがある可能性があります。都度修正していく予定ですので、何か間違いございましたらご教示いただけますと幸いです。

おしまい

<h2>追記</h2>
現在、こちらを参考に学習をしていこうと考えております。
とても参考になる記事ですのでリンクを記載しておきます。

【保存版・初心者向け】独学でAIエンジニアになりたい人向けのオススメの勉強方法
https://qiita.com/tani_AI_Academy/items/4da02cb056646ba43b9d

P.S.

4か月間一人でもくもくと勉強していたので、モチベーション維持に限界を感じてきています。
現状打破、また同じ境遇の方と交友できることを期待して、学習記録を投稿しています。
一緒にもくもく会、勉強会の企画や共同ポートフォリオ制作など面白いことしたい！！って方おりましたら、お気軽にTwitterなりご連絡ください。(切実な願い)
__call__についてのメモ

#はじめに
python、kerasともに初学者です。自分用の忘備録です。

#この書き方はなんだろう
Keras functional APIなるものを使うと、keras Sequential APIよりも複雑なニューラルネットワークを使うことができるとのことです。

そこで出てくるのが以下のような書き方です。

```001.py
import keras
from keras import layers

inputs = layers.Input(shape=(784,))
dense_hoge = layers.Dense(64, activation='relu')
x = dense_hoge(inputs)# これ!
```
dense_hoge は keras.layers.core.Dense クラスのインスタンスなのですが、インスタンス名に続けてカッコがあり、中に変数名_inputs_が書いてあります。

しかも最後の2行は、

```002.py
x = layers.Dense(64, activation='relu')(inputs)
```
とも書けるとのことです。変数名1(変数名2)という書き方は、これまで見たことがありません。

一体これは、何をどう処理しているのでしょうか？

#調べた結果
クラスの中で定義された\_\_call\_\_関数が処理しているとのことでした。

簡単なクラスを書いてみます。

```003.py
class A:
    def __init__(self):
        print("ClassA __init__")
    
    def __call__(self):
        print ("ClassA __call__")
```
クラスAのオブジェクトを作ってaに格納。

```003.py
a = A()
#ClassA __init__
```
インスタンスaに()をつけて呼んでみる。

```003.py
a()
#ClassA __call__
```
というわけで、インスタンス名に()をつけると、\_\_call\_\_で定義した処理が実行されるということがわかりました。

\_\_call\_\_が定義されていないクラスではどうでしょうか？

```004.py
class B:
    def __init__(self):
        print("ClassB __init__")

b = B()
#ClassB __init__
b()  #以下のエラーが表示される
#Traceback (most recent call last):
#  File "<stdin>", line 1, in <module>
#TypeError: 'B' object is not callable
```
'B' objectはcallableではないと、表示されました。
callableかどうかはcallable()で調べられるとのことですので、実行してみました。

```004.py
callable(a)
#True
callable(b)
#False
```
\_\_call\_\_を定義していないClass BではFalseになりました。

インスタンスではなくてクラスを指定するとClass AでもClass Bでもtrueになりました。

```005.py
callable(A)
#True
callable(B)
#True
```

#連続して呼べるのか？
\_\_call\_\_はオブジェクトを返り値にできるということでした。それでは、\_\_call\_\_がcallableなオブジェクトを返す場合は次の\_\_call\_\_を連続して呼べるでしょうか？
以下のClass CはClass Aのインスタンスを返します。Class Aのインスタンスはcallableで、\_\_call\_\_を呼ぶとClassA \_\_call\_\_と返すはずです。

```006.py
class C:
    def __init__(self):
        print("ClassC __init__")
    
    def __call__(self):
        print ("ClassC __call__")
        return A()

c = C()
c()()
#ClassC __call__   
#ClassA __init__    #class Cの__call__でClass Aをインスタンス化した時の出力
#ClassA __call__
```
....連続して呼べました。コードが見にくくなりそうなので、あまり使うべきではないように思いますが、連続して使えることがわかりました。

#変数名として既存の関数名を使うとどうなるのか？
変数名()という書き方ができることがわかりました。pythonでは、関数名として使われている文字列であっても、変数名として利用できるのでした。例えばprintという変数名です。print()とした場合、呼ばれるのは\_\_call\_\_でしょうか？それとも、通常のprint関数でしょうか？

```007.py
print = A()
print('123') #以下のエラー表示
#Traceback (most recent call last):
#  File "<stdin>", line 1, in <module>
#TypeError: __call__() takes 1 positional argument but 2 were given
```
\_\_call\_\_の方が呼ばれました。

#考察
変数名()という書き方ができることがわかりました。

クラスで\_\_call\_\_を定義して使うのと、関数hoge()を定義して使うのと、どう違うでしょうか？変数名(引数)と変数名.hoge(引数)との違いはなんでしょうか？

変数()の書き方のデメリットとして、
1. これまで、カッコの前にあるのは関数名と決まっていたのが、必ずしもそうではないことになる。コードの可読性を低下させる。
2. 知らずに既存の関数名と同じ変数名を使用した場合に、その関数が使えなくなる。

の2点が考えられます。\_\_call\_\_を使うメリットはあるんですかね？

\_\_call\_\_のようなメソッドは特殊メソッドと呼ばれているようです。色々便利に使えそうですが、解説ページがたくさんあるようなので、ここではここまでにしたいと思います。
2020#1 G検定にチャレンジしてみて

# この記事について

2020年3月14日（土）に実施された、G検定2020#1を受験してみて、
1. 受験してみた感想
2. 勉強方法
について簡単にシェアできればと思い、Qiita初投稿ですが書きます。

## 0. 簡単な自己紹介と受験した理由
元々広告業界で3年ほど働いて2019年の12月にAIベンダーに営業として転職しました。
広告→ITと全く別業界へのチャレンジなので、仕事をしながら業界について、AIについて勉強しています。

G検定を受験した理由としては、知識の整理と補強を行いたかったからです。
日々の仕事ではAIの技術者に向けて営業活動をしておりますが、未経験なので話についていけない、文脈/背景が分からないことが多々あり、その度に自分で調べていました。

ただ、そもそもAIって？機械学習?モデル？みたいな前提知識が足りてなかったので、日々分からないことを調べて埋めていくだけだと効率が悪く、それならばまず全体像を把握できるといいなと考え、G検定を受けてみようと思いました。

## 1. 受験してみた感想

G検定を受験してみて、主に以下の3点が受験してみて良かったなと思いました。

- AI/機械学習についての知識が整理されて、なんとなく自信がついた。
- 機械学習に対してもっと学びたいと思えた。
- 社会人になってきちんと勉強して望んだ試験だったので達成感がある。

中でも、やっぱり断片的だった知識が整理、補強されたことでなんとなく自分の中で自信をもつことができたのが良かったかもしれません。
AIや機械学習の複雑さ、課題、面白さについて気づけたことも今後の仕事に生かせるなと思います。

## 2. 勉強方法

今回のG検定を終えた直後一番に思ったことは、「難しかった...」です。
Twitterで"G検定"で検索してみると、受験したみなさんも同じような感想だったようです。

僕の勉強方法としては、次の流れで行いました。

- 「人工知能は人間を超えるか ディープラーニングの先にあるもの」を読む 
（https://amzn.to/39SFIkR）
- G検定公式テキスト（白本）を1周読む
（https://amzn.to/2TPvEUa）
- Study AI模試を受ける
- Study AI模試の解説動画を見て復習する
（https://youtu.be/9_5NqeW6gc4）
- G検定問題集（黒本）をやって復習する
（https://amzn.to/38TSoGE）
- 上記を踏まえ大切な用語を整理、分類したシートを用意して試験に活用

です。

「難しかった...」理由は、G検定の過去の傾向として白本、黒本から大体出題されていたので、対策としてそれらをメインに行っていたのですが、今回の試験では対策していた箇所以外の内容が多かった印象です。
具体的には、最新の事例（自動運転）とか法律の問題が試験冒頭から出題されて、かなり時間を取られてしまったと思います（他の受験者の方もTwitterをみる限り同じような感想を呟いている人がちらほらいました）

正直合格している自信は五分ですが、このチャレンジは自分に取って良かったと思っているので
この記事が次回以降、G検定を受験される方のためになればと思います！
（特にStudyAI模試の動画解説がおすすめです）
djangoでGmailから登録完了メールを送ろうとしてみた。

先日Djangoを学び始め、ユーザー登録機能の実装にtryしています。
[Djangoで、メールを送信](https://narito.ninja/blog/detail/42/)←概ねこちらの記事に則ってプログラムを書いています。
何度かエラーが出てしまったので、備忘録として残します。
##TemplateDoesNotExist
最初に直面したのが上記のエラーでした。
ユーザー登録時に送信されるメールのタイトル・本文のテンプレートが見つからず、エラーになってしまいました。
下記の通りディレクトリを修正したところ解決しました。
mail_templatesフォルダもtemplatesの中に入れておかなければならなかったようです。

×修正前
users（アプリ名）
├mail_templates
|　└create
|　　└subject.txt(メールタイトルのテンプレート)
└templates

〇修正後
users
└templates
　└mail_templates
　　└create
　　　└subject.txt(メールタイトルのテンプレート)

##[WinError 10061] 対象のコンピューターによって拒否されたため、接続できませんでした。
拒否されてしまいました。
これは私のGmailから登録者へメールしようとしたにもかかわらず、プログラム中にGmailのユーザ名、パスワード等を書いていなかったのが原因でした。
settings.pyに下記の通り加筆したら解決しました。

```settings.py
EMAIL_HOST = 'smtp.gmail.com'
EMAIL_PORT = 587
EMAIL_HOST_USER = 'メアド'
EMAIL_HOST_PASSWORD = 'パスワード'
EMAIL_USE_TLS = True
```

##SMTPAuthenticationError at /user_create/
続いては上記のエラーが生じるとともに、本プログラムで送信元として使用予定だったGmailから「誰かが不正ログインしようとしています」の注意喚起メールが届きました。
これはエラーに表示されていたGoogleのアドレスに飛び、安全性の低いアプリへのアクセスを有効にすることで解決しました。（安全性のしょぼいアプリでごめんね…）

##BadHeaderError 
使用していたAtomでファイル末尾に自動で改行が挿入されてしまうため、「改行できないsubject.txtが二行になっているよ！困った！」とエラーが発生してしまいました。
下記サイトを参考に、自動で改行する機能をストップして解決しました。
[【Atom】ファイル末尾に自動改行させない設定](http://2lat.net/it/atom-save-whitespace)

以上を解決したら無事にDjangoアプリを利用してメールを送信できました！わーい！
【今日のアブストラクト】Delving Deep into Rectifiers: Surpassing Human-Level Performance on ImageNet Classification【論文 ほぼ Google 翻訳 自分用】

1 日 1 回 (努力目標) 論文の Abstract を Google 翻訳の力を借りて読んでいきます.

この記事は自分用のメモみたいなものです.
ほぼ Google 翻訳でお送りします.
間違いがあれば指摘していだだけると嬉しいです.

翻訳元
[Delving Deep into Rectifiers: Surpassing Human-Level Performance on ImageNet Classification](https://arxiv.org/abs/1502.01852v1)


# Abstract

### 訳文

整流された活性化ユニット(整流器)は, 最先端のニューラルネットワークに不可欠です. この作業では, 2 つの側面から画像分類のための整流器ニューラルネットワークを研究します. 最初に, 従来の整流ユニットを一般化するパラメトリック整流線形ユニット (PReLU) を提案します. PReLU は, 追加の計算コストがほとんどゼロであり, オーバーフィットのリスクがほとんどなく, モデルフィッティングを改善します. 次に, 整流器の非線形性を特に考慮した堅牢な初期化方法を導き出します. この方法により, 非常に深く整流されたモデルを最初から直接トレーニングし, より深いまたはより広いネットワークアーキテクチャを調査できます. PReLU ネットワーク (PReLU-nets) に基づいて, ImageNet 2012 分類データセットで 4.94% のトップ 5 テストエラーを達成しました. これは, ILSVRC 2014 の勝者 (GoogLeNet, 6.66%) に対して 26% の相対的な改善です.

### 原文

Rectified activation units (rectifiers) are essential for state-of-the-art neural networks. In this work, we study rectifier neural networks for image classification from two aspects. First, we propose a Parametric Rectified Linear Unit (PReLU) that generalizes the traditional rectified unit. PReLU improves model fitting with nearly zero extra computational cost and little overfitting risk. Second, we derive a robust initialization method that particularly considers the rectifier nonlinearities. This method enables us to train extremely deep rectified models directly from scratch and to investigate deeper or wider network architectures. Based on our PReLU networks (PReLU-nets), we achieve 4.94% top-5 test error on the ImageNet 2012 classification dataset. This is a 26% relative improvement over the ILSVRC 2014 winner (GoogLeNet, 6.66%). To our knowledge, our result is the first to surpass human-level performance (5.1%, Russakovsky et al.) on this visual recognition challenge.