OmniAICreator/Qiita-1.07M huggingface dataset:
テキスト解析・生成手法 メモ

# まとめ

* [(Qiita, 2017) Seq2Seq+Attentionのその先へ](https://qiita.com/ymym3412/items/c84e6254de89c9952c55)

# トークナイズ

* [SentencePiece](https://github.com/google/sentencepiece)
    - [(公式Qiita) Sentencepiece : ニューラル言語処理向けトークナイザ](https://qiita.com/taku910/items/7e52f1e58d0ea6e7859c)
* [MeCab](https://taku910.github.io/mecab/)

# Embedding

* BERT
    - [(paper) BERT: Pre-training of Deep Bidirectional Transformers forLanguage Understanding](https://arxiv.org/pdf/1810.04805.pdf)
    - [(公式TF実装) google-research/bert](https://github.com/google-research/bert)
    - [(実装) huggingface/transformers](https://github.com/huggingface/transformers)
        - [(日本語BERT) cl-tohoku/bert-japanese](https://github.com/cl-tohoku/bert-japanese)
    
# 生成・変換

* Seq2Seq
  - [(paper) Sequence to Sequence Learning with Neural Networks](https://arxiv.org/pdf/1409.3215.pdf)
  - [(PT実装) PyTorchチュートリアル](https://pytorch.org/tutorials/intermediate/seq2seq_translation_tutorial.html)
  - [(PT実装) AuCson/PyTorch-Batch-Attention-Seq2seq](https://github.com/AuCson/PyTorch-Batch-Attention-Seq2seq)
      - batched

* SeqGAN
  - [(paper) SeqGAN: Sequence Generative Adversarial Nets with Policy Gradient](https://arxiv.org/pdf/1609.05473.pdf)
  - [(公式TF実装)  LantaoYu/SeqGAN](https://github.com/LantaoYu/SeqGAN)

* TextGAN
  - [(paper) Adversarial Feature Matching for Text Generation](https://arxiv.org/pdf/1706.03850.pdf)
  - [(PT実装) TextGAN-PyTorch](https://github.com/williamSYSU/TextGAN-PyTorch)

* MaskGAN
  - [(paper) MaskGAN: Better Text Generation via Filling in the______](https://arxiv.org/pdf/1801.07736.pdf)
  - [(公式TF実装) tensorflow/models/research/maskgan](https://github.com/tensorflow/models/tree/master/research/maskgan)

* RelGAN
  - [(paper) RelGAN: Relational Generative Adversarial Networks For Text Generation](https://openreview.net/pdf?id=rJedV3R5tm)
  - [(公式TF実装) weilinie/RelGAN](https://github.com/weilinie/RelGAN)
  - [同名の画像に関するGAN](https://arxiv.org/abs/1908.07269)も存在するので注意。
gnuplotだけで、任意区間のみを使ったデータフィット



下の図にあるように、実験データ(data)から特定の領域(fitting-area)を使って、バックグラウンドの関数をフィット(background)し、その関数を使ってバックグラウンド減算した実験データ(subtracted)を表示したい。
`gnuplot`だけを使って、さくっとできたので、投稿する。

<img width=500sp src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221968/25c55abd-c88b-c54a-0be7-5a99f2783fba.png>


### データファイル
`data.txt`に、x, yの順で座標が並んでいるとする。

```
4.08	13189 
4.10	12800 
4.12	12550 
4.14	12909 
4.16	12853 
...(略)...
114.90	8348 
114.92	8368 
114.94	8498 
114.96	8334 
114.98	8526 
```

### 目標

今回は、指数関数と二次関数の重ね合わせである
$$ bg(x) = A exp(-B(x-C))+ D x^2 + E x + F $$
をフィット関数に用いて、データ点のうち、$$x<15, 105<x$$を使ってフィッティングしたいとする。


### gnuplot code

```gnuplot
bg(x) = A * exp(-B*(x-C)) + D*x**2 + E*x + F 
fit bg(x) "<awk '{if (($1<15)||($1>105)) print $0}' data.txt " via A,B,C,D,E,F
```

1行目は、bg(x)の関数の定義。
2行目は、`fit`でフィッティングしている。
`"<awk ...(略)... data.txt"`で、外部コマンドである`awk`に`data.txt`を読み込ませていて、
その条件がif文の中に入っている。

なお、`gnuplot`で階乗は`**`

もし、$$0<x<15$$を使う、といったように一つの区間で表せれるなら、2行目は`awk`を使うまでもなく、

```
fit [0:15] bg(x) "data.txt " via A,B,C,D,E,F
```
のように、`fit`のオプションで指定して、書くこともできる。


### グラフ表示

実はこのやり方が調べてもわからなかったので、ハマってしまった。

```
plot "data.txt" using 1:($2-bg($1)) w l
```

`using`の中にbg(x)をいれる。
xに代入するのは、`using`オプションでx軸を意味する`$1`
ポータブル版Electronは実用するには厳しい


# ポータブル版とは
electron-builderで作れる、全ファイルを1つのEXEに纏めたもの。Electronでexeのビルドまでやったことのある人なら分かると思いますが、そのままだとファイル数がかなり多く、移動するならフォルダ単位になってしまうので魅力的ですね:thumbsup:

# 問題点
**最小構成でも起動が7秒前後かかる上に、原理上スプラッシュスクリーンも出しようがないこと**:scream:
Exeを起動した後、内部では以下のような処理が行われます。

1. Tempフォルダに全ファイルをコピー
2. 1ファイルに圧縮状態のため展開
3. Electron起動（このため、app.getPath("exe")でExeファイルのパスを取得しようとすると、Tempフォルダ内の実際に動作しているファイルのパスが取れてしまうというトラップがある）
4. アプリを落とすとTempフォルダにあるファイルが削除される

この1～2がネックとなっており、Electron自体の準備に時間がかかっているため、Electronの仕組みではスプラッシュスクリーン（起動準備中に表示する画像）の出しようがないという。検索した限り、ネイティブ言語でこの処理にフックして画像表示するスクリプトを書く等するツワモノもいましたが、うーん:sweat_smile:

# 対処方法
調べた結果、ビルドオプションでちょっとだけ緩和できます。

- asar:trueにする（デフォルト設定）
- useZip:trueにする

~~asmr~~asarは自前のファイル類を1つの.asarファイルに圧縮する設定ですね。詳しいことは省きますが早くなります。useZipは上のフローで言うところの2の部分ですね。1つのExeに固めるのをお馴染みのzipで行うことにより高速化を図ります。
また、対処方法ではないですが、2回目以降の起動はキャッシュが効くので初回だけ我慢してもらうというのもあります。

# 各オプション個別適用によるガバガバ計測
## マシン
CPUはHaswell世代でHDD搭載

## ビルドに用いたもの
Electron ver8系/electron-builder ver22系

## テストアプリについて
自作の小さなアプリをビルドする設定を詰めるために行ったので、純粋なhallo,world系のアプリではないですが、かなり軽めのアプリのため結果には大差ないと思います。
なおElectron起動した直後はウィンドウ表示せず、1回目のDOM描写が終わった後に発動するready-to-showイベントを拾ってウィンドウ表示する一般的なフローとなります。（Electron起動直後に素直にウィンドウ表示すると、DOM描写の前で一瞬真っ白画面になる現象への対策）

## 計測方法
Exeダブルクリック→画面表示までの所要時間を計測。面倒だったのでWindowsのストップウォッチ機能使ってのアナログ計測。このため誤差1秒はあるかと。

## 結果（単位:秒）
|portable|useZip |ASAR   |1回目|2回目|
|--------|-------|-------|-----|----|
|TRUE    |TRUE   |TRUE   |6    |7   |
|TRUE    |TRUE   |FALSE  |8    |7   |
|TRUE    |FALSE  |TRUE   |6    |7   |
|TRUE    |FALSE  |FALSE  |**9**|7   |
|FALSE   |TRUE   |TRUE   |**3**|0   |
|FALSE   |TRUE   |FALSE  |2    |0   |
|FALSE   |FALSE  |TRUE   |4    |0   |
|FALSE   |FALSE  |FALSE  |4    |0   |

見てのとおり**ポータブルにしない方がいい**ですね。理論上、結果がおかしいところがありますが誤差で流せるレベルかと。
個人的には全部Trueの約6秒コースならまだ我慢できなくもない感じはしましたが、実際はSPAフレームワーク使って、起動時にCSSや画像も読み込んで、ついでに通信やらローカルファイル読み込み等行うと思うので、Exe叩いて6秒後にようやくローディング表示して云々では苦痛でしょうね:pensive:

# その他の問題点
ポータブル版に限った話ではないですし、今更ですが、Electronの仕組み上、Chromiumを丸々乗せてるので最小構成でも容量がデカいですね。ver8系だと未圧縮で100MB、フル設定で60MB前後が目安。ますます小さなアプリには採用し辛い……
職場のチック症さんが出す音が・・せや！コードでなんとかしたろ

# 背景

 - ボールペンのカチカチカチ
 - 貧乏ゆすりの椅子の軋みギチギチギチ
 - 両足を揺らす音カサカサカサ

### 止めてクレメンス・・


# 考察

アンガーマネジメントにイラっときたらメモして**意識を怒りの対象から遠ざける**方法がある。
ただ、暗黒面にのまれて呪いに拍車がかかってしまう危険性も。藁人形＆五寸釘のように。
**手でカウント**するのがまずそう。

自動でメモして音バリアを張れたらストレス純減しないだろうか？


# 結果

### 倒せませんでした！

咳払いとか突発的な音ではうまいとこ動いてはくれませんでした。
ピー音みたいな連続音は閾値のチューニングで動いた。

しかも逆位相音は消したい音とタイミングがズレてると**”元の音”**と同じように聴こえるのです。
つまり、**ツールによって自分へのバイキルトが発生！**

素直に耳栓しょ。。


# コード

![tic.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189193/ba147e71-4f60-0a16-cdec-f0a812e8f29a.gif)

[ここです](https://github.com/yasutakatou/tic)


# なんでMFCCじゃないの？

以前sklearnでサンプル量が少ないと精度出なかった。(たしか)
スペクトログラムなら画像をマージしていくことで苦手音の重ね合わせができるかな。
カスタマイズできるノイズキャンセラーってあったら欲しくないですか？


# 参考情報

### 音の長さ
[Get .wav file length or duration](https://stackoverflow.com/questions/7833807/get-wav-file-length-or-duration)

### pybudのバックグラウンド再生
[Playing audio in the background #160](https://github.com/jiaaro/pydub/issues/160)
[Pythonでmp3のバックグラウンド再生する方法](https://qiita.com/hotstaff/items/26d76a18635e3fe5ad07)

### 画像の類似度
[Pythonで類似度検出③ 特徴点マッチング](http://sh0122.hatenadiary.jp/entry/2018/02/04/172426)

### 逆位相音作成
[音声分析ド素人が逆位相ミュージックを聞いたら、そこに訪れたのは混乱とそして静寂だった](https://qiita.com/usk81/items/8284ff74e79bdbd7dbae)

### スペクトログラムの作成
[Pythonで音声解析 ? 音声データの周波数特性を調べる方法](https://jorublog.site/python-voice-analysis/)

### 録音
[【Python】マイクの音を録音してwaveファイルに保存](https://algorithm.joho.info/programming/python/pyaudio-record/)

### 装飾文字
[ASCII art library for Python](https://github.com/sepandhaghighi/art)
指定のディレクトリに一発で移動するssh configの書き方

sshした際、必ずhomeでカレントディレクトリが開始することになると思いますが、
毎回同じ場所にcdしないといけないのが面倒なのでssh configに設定してみました。

```
Host project1_ssh
    HostName api2.project1.com
    User amasok
    Port 2222
    RemoteCommand cd /var/source/current/; $SHELL -il # ←これと
    RequestTTY yes # ←これ
```

こんな感じでやったらssh時に指定のディレクトリに移動してくれました。
パーミッション色々(wordpressの「ディレクトリを作成できませんでした。」エラーの為の学習)


先日、dockerでwordpressのローカル環境を構築して、プラグインを使おうと思ったら
困ったエラーに遭遇しました。

**ディレクトリを作成できませんでした。**

色々調べてみると権限周りの問題だったみたいです。
パーミッションについてあまり詳しくなかったので、これを機にちゃきちゃき学習してみようと思います。

## そもそもパーミッションとは

パーミッション（権限)がファイルごとに割り当てられています。
まずはその確認方法から。


```
$ ls -l
```

のコマンドで、上記のような出力が確認出来ます。

```
drwx------+   5 irico  staff         160  9 17 09:15 Pictures
drwxr-xr-x   25 irico  staff         800  3 10 13:38 Project
```

## パーミッション　読み方
先頭の文字列がパーミッション方式を表示してる。

### 1文字目
**ファイルの種類**を表している。

| 1文字目 |         意味        |
|:-------:|:-------------------:|
|    -    |     通常ファイル    |
|    d    |     ディレクトリ    |
|    l    |  シンボリックリンク |


### 2~10文字目
ここが肝心要のパーミッションを示していて、3文字ずつで３つのグループに別れている。

**2~4文字目** ・・・ユーザークラス
**5~7文字目** ・・・グループクラス
**8~10文字目** ・・・その他のユーザークラス

ユーザークラスとはファイルやディレクトリや所有者を指し、
グループクラスは同じサーバーを利用できるユーザー全体、
その他は上記以外の全ての第三者を指す。

| 文字位置 |      意味     |
|:--------:|:-------------:|
|  1文字目 | リード(r / -) |
|  2文字目 | ライト(w / -) |
|  3文字目 | 実行(x / -)   |

- **リード**はファイル・ディレクトリを読む権利。`r`表記があれば許可される。
- **ライト**はファイル・ディレクトリの変更権利。`w`表記があれば許可される。
- **実行**はファイルの実行権利・ディレクトリに入り中のファイルにアクセスする権利。`x`表記があれば許可される。

###11文字目（ない場合もある)

|   11文字目  |           意味           |
|:-----------:|:------------------------:|
|  (スペース) |      通常のUnixのみ      |
|  .(ドット)  |     SELinuxアクセス可    |
|  +(プラス)  | その他のアクセス権もあり |

ここは本件にあまり関係なさそうだったのでさらっと見ておいた。後ほど調査。

### 例

```
drwx------
```

この場合は、
1文字目で**ディレクトリ**である事がわかり、
2~4文字目で**ユーザークラスにリード/ライト/実行の権利がある**事がわかり、
5~10文字目で**グループクラス/その他ユーザークラスに何も権利がない**事がわかる。

## パーミッションを変更しよう
`chmod`コマンドを使用します。
細かいコマンドについての説明は、[こちら](https://qiita.com/ntkgcj/items/6450e25c5564ccaa1b95)がわかりやすかったです。

```
$chmod 権限の設定　ファイルパス
```
で指定でき、権限設定は数値3桁で指定していきます。

| 数値 | パーミッション |
|:----:|:--------------:|
|   0  |       ---      |
|   1  |       --x      |
|   2  |       -w-      |
|   3  |       -wx      |
|   4  |       r--      |
|   5  |       r-x      |
|   6  |       rw-      |
|   7  |       rwx      |

例えば `777`　だったら、 `rwxrwxrwx`となるので、
全てのユーザーに全ての権限を許すということになります。

実際に、wordpressの今回のエラー解決法をググっていたら、下記のような記事がでてきました。
https://www.dreamhive.co.jp/201706/3929
>755かそれ以上（一部のサーバーでは777）に設定する必要があります。

なかなかセキュリティ的に危険なコマンドでもあるかと思うので、慎重に使っていきたいですね。


## 参考にさせていただいたリンク
https://qiita.com/shisama/items/5f4c4fa768642aad9e06
https://eng-entrance.com/linux-permission-basic
https://blue-red.ddo.jp/~ao/wiki/wiki.cgi?page=%A5%D1%A1%BC%A5%DF%A5%C3%A5%B7%A5%E7%A5%F3%A4%CErwx%A4%CE%B8%E5%A4%ED%A4%CE%CA%B8%BB%FA
https://qiita.com/ntkgcj/items/6450e25c5564ccaa1b95
GAS カスタムダイアログサンプル

メニューをやったら次はダイアログだろう。と。
こちらの[サイト](https://officeforest.org/wp/2018/11/29/google-apps-script%e3%81%a7%e3%82%a6%e3%82%a7%e3%83%96%e3%82%a2%e3%83%97%e3%83%aa%e3%82%b1%e3%83%bc%e3%82%b7%e3%83%a7%e3%83%b3%e4%bd%9c%e6%88%90%e5%85%a5%e9%96%80/#HTMLGAS)が参考になりました。
そのうち、ある程度簡単なやり方はこれよ、ってのを書いておきます。
スプレットシート側からGASに入った人はHTMLとかは「？」の場合が多いので最初は簡単なところから手をつけましょう。

#1.非同期なので細かいことやるとハマる
上記サイトにもある通り、GASとダイアログの間は非同期通信なので、気をつけないと見た目ぎょっとする動きをします。（GASの反応が遅い、というのも原因）
ダイアログの設計の段階でやることを絞って置くのがはまらなくていいかも。

#2.HTMLを準備
スクリプトエディター側でファイル→New→HTMLでHTMLを作成します
Claspを使ってる場合は、ローカルで作成してpushでも可。

#3.HTMLの中でGASからデータをとる
HTML側でGASのデータを呼ぶ場合は、以下の非同期なメソッドをつかいます

```javascript
      function init(){
        google.script.run.withSuccessHandler(result).getSomethingFromGAS();
        function result(data){
            document.getElementById('test').value = data;
        }        
      }

```
getSomethingFromGAS（GAS側の関数）
この実行が成功すると
result（HTML内に自分でつくった関数）
が呼ばれます。
データの受け渡しは、
getSomethingFromGASの戻り値　＝　resultの引数（この場合data）
です。

***この処理も非同期なため、一旦この処理がされる前のHTMLが表示され、処理終了後書き換えられます***


#4.ダイアログのOKボタンからGASを呼び出す
HTML上のJavascriptでOKボタンが押されたときのハンドラ関数を用意し、その中でGAS関数を呼び出します。
以下はフォームのデータをGAS側に引き渡すときのサンプルです。

this.parentNodeがformに相当します
HTMLの部分は以下

```
    <Form>
      <input name="hiddenValue" type="hidden">
      <input name="XXXName"><BR>
      <button onclick="onOK(this.parentNode)">作成</button>
      <button onclick="onCancel(this.parentNode)">キャンセル</button>
    </Form>

```
Javascriptは以下

```javascript
      function onOK(form){
        var result = {
          hiddenValue : 0,
          strName : form.XXXName.value
        }
        google.script.run.withSuccessHandler(function(){
            google.script.host.close();
        }).OnOKDialog(result);
      }
```

GAS側

```javascript
function OnOKDialog(result)
{
  console.log(result.strName);
}
```

上２つはHTMLファイルの一部、下はGAS内のメソッドとして用意します

#5.注意点

これはグローバル変数などを使っちゃってるとハマるかもだけど、GAS的には上のサンプルのOnOKDialogは、ダイアログを出した時のセッションとは別セッションのようです。
ログが別々にでますし、グローバル変数（があれば）は初期化されてます

あと、HTMLとか久しぶりに書いたので動的に埋め込むやり方とかすっかり忘れてた（笑
IntersectionObserverで画像と動画の遅延

```js
import 'intersection-observer'
↑ IE対応

/****
<img
  class="lazy"
  src="表示前の画像"
  data-src="表示させる画像"
  alt=""
/>
 */

export default function() {
  const lazyImages: any = [].slice.call(document.querySelectorAll('img.lazy'))

  if ('IntersectionObserver' in window) {
    let lazyImageObserver = new IntersectionObserver((entries, _observer) => {
      entries.forEach(entry => {
        if (entry.isIntersecting) {
          let lazyImage = entry.target

          if (lazyImage.dataset.hasOwnProperty('src')) {
            lazyImage.src = lazyImage.dataset.src
            lazyImage.dataset.src = ''
            delete lazyImage.dataset.src
          }

          if (lazyImage.dataset.hasOwnProperty('srcset')) {
            lazyImage.srcset = lazyImage.dataset.srcset
            lazyImage.dataset.srcset = ''
            delete lazyImage.dataset.srcset
          }

          if (typeof lazyImage.dataset.srcset === 'undefined') {
          } else {
            lazyImage.srcset = lazyImage.dataset.srcset
          }

          lazyImage.classList.remove('lazy')
          lazyImageObserver.unobserve(lazyImage)
        }
      })
    })
    lazyImages.forEach(lazyImage => {
      lazyImageObserver.observe(lazyImage)
    })
  }
}


```

あるがままなので、コードのみ載せます。

遅延ロード系のライブラリがありますが、使わなくてもよいかもしれません。
scopeを使いまわしたい

# scopeを使いまわしたい

複数のモデルに対して同じスコープを使いたい…しかし一々コピペして同じスコープを定義するのは嫌だったので調べてみたところ、スコープ用のモジュールを切り出すのが良いらしい

## 実現したいこと


```ruby:こんな動きがしたい.rb
scope :recent, -> { order(created_at: :desc) }
```

こんなスコープを複数のモデルで使いまわしたい

## 結論

```ruby:app/models/concerns/common_scope.rb
module CommonScope
  extend ActiveSupport::Concern
  included do
    scope :recent, -> { order(created_at: :desc) }
  end
end
```
このモジュールをモデル側でincludeしてやると使えるようになる

`ActiveSupport::Concern`をextendし、includedブロック内に記述することでscopeをクラスメソッドとして使える

## 失敗談

```ruby:ダメな例.rb
module CommonScope
  scope :recent, -> { order(created_at: :desc) }
end
```

最初はextendする意味が分からずこんな感じで書いてみたが、このままだとscopeがインスタンスメソッド扱いになるので`NoMethodError`が発生

##  参考

https://www.techscore.com/blog/2013/03/22/activesupportconcern-%E3%81%A7%E3%83%8F%E3%83%83%E3%83%94%E3%83%BC%E3%81%AA%E3%83%A2%E3%82%B8%E3%83%A5%E3%83%BC%E3%83%AB%E3%83%A9%E3%82%A4%E3%83%95%E3%82%92%E9%80%81%E3%82%8B/

こちらに詳しく書いてあります

おかしな点があればご指摘ください
Jupyter NotebookでKernel errorが出てしまう件

# 背景
ここ２～３年の間、AIのプログラムに手を出したいと思いつつも、トライしては挫け、トライしては挫け…。要するにAI挫折組にとって、プログラム云々よりも「環境を整える」ことが難しいのですよ。おまけに「下手の横好き」で、色んな物に中途半端に手を出してるせいで、PCシステム内が荒れ放題…。そんなだから、すんなり進まないんだよ。。

# 使用環境
- PC：Win10 ノートパソコン(SSD)
- 開発環境：Anaconda
- 現状：Jupyter Notebookを起動すると"Kernel error"の赤ランプが点灯
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/374906/ac7552c7-a28c-88b4-9e63-ce905a7d9e97.png)
　↓　詳細："FileNotFoundError：[WinError 2] 指定されたファイルが見つかりません。" 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/374906/089b43b8-6e75-5daa-3b64-5ed27a6428b6.png)

**《備考》**
『なんでJupyter Notebook使わなあかんの？』と思われた方、はい その通り。別に”Jupyter Notebook”にこだわる必要はなくて、別のエディタを使えば良いのだけど、教科書通りにやりたい初心者ごごろです。そのおかげで多少システム内に詳しくなれたかな？

# 推測と確認
Google先生に聞いてみると同様の問題に直面している方々が少なからずいる模様。明確な解決策まで示されてないけどさ。どうやら”コマンドプロンプト”氏のPython.exeのパス認識と"Jupyter Notebook"氏のパス認識が違っているというのが最有力説です。

<h4>確認① "コマンドプロンプト"氏のパス認識</h4>
コマンドプロンプトで下記の操作をします。

```
(UserName)>python           ’Pythonを起動
*****                       '~pythonの起動メッセージ~
>>> import sys
>>> sys.executable
'C:\\Users\\(UserName)\\Anaconda3\\pyhon.exe'    '←知りたいパス
>>> exit()                  'Pythonを終了しておく
```

<h4>確認②："Jupyter Notebook"氏のパス認識</h4>
コマンドプロンプトで下記の操作をします。

```
(UserName)>jupyter kernelspec list
Available kernels:
  python3  C:\Users\(UserName)\AppData\Roaming\jupyter\kernels\python3   '←知りたいパス
```

"Jupyter Notebook"氏の場合は、上記のパス先に"kernel.json"というファイルがあって、その中でPython.exeのパス指定をしています。メモ帳などで開いて確認してみましょう。

```kernel.json
{
 "argv": [
  "C:\\ProgramData\\Anaconda3\\python.exe",       '← そんなファイル、無いって！
  "-m",
  "ipykernel_launcher",
  "-f",
  "{connection_file}"
 ],
 "display_name": "Python 3",
 "language": "python"
}
```

# 対処方法
ココまで説明したら、もう言わずもがなですよね。上記の"kernel.json"内のパス指定を編集しましょう。これで解決してくれるはず。少なくとも私の環境は解決できました。
agora.io クイックスタートガイド macOS SDK用

#概要
この記事はSDKに内包されているサンプルのビルドガイドです。

##STEP1. Agora Accountの作成とApp IDの取得
1.https://sso.agora.io/signup?source_id=3 からデベロッパー登録をします
2.ダッシュボードから新規プロジェクトを作成します。
<img width="2284" alt="appid_1.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/300377/5bbe45d6-19e6-5032-2a43-05f127fdd9b8.jpeg">
3.プロジェクト名を入力してSubmitボタンをクリックします。
4.作成したプロジェクトが一覧に表示されます。
<img width="2276" alt="appid_2.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/300377/aa129684-2364-9fbf-0020-fd82c93bbe0f.jpeg">

##STEP2. Agora macOS SDKの取り込み

**SDK＆サンプルファイルを取得**
1.[ダウンロードページ](https://docs.agora.io/en/Agora%20Platform/downloads)からmacOS SDKをダウンロードします。
![download.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/300377/c2497deb-b0e5-636d-91a2-ca058853aaca.png)
2.フォルダ構成は以下のようになっています。
<img width="1224" alt="スクリーンショット 0002-03-11 14.00.10.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/300377/62e5a844-898e-1abf-07f8-84bf264bec47.png">

3.Xcodeでプロジェクトを開きます。

4.さきほど取得したApp IDをAppID.swiftに追記し、実行します。
<img width="1512" alt="スクリーンショット 0002-03-11 13.43.40.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/300377/d7d83650-3108-5e04-2626-40ce323730e0.png">

5.ビデオ通話が開始します。
<img width="912" alt="スクリーンショット 0002-03-11 14.08.25.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/300377/7e6f85fc-dec6-c05d-4003-f714b66e46fd.png">

##STEP3.実装
SDKに内包されているサンプルか、[APIドキュメント](https://docs.agora.io/en/Video/API%20Reference/oc/docs/headers/Agora-Objective-C-API-Overview.html)を参考に実装を開始します。


---
##最後に
[**agora.ioに関するお問い合わせはこちらから**](https://jp.vcube.com/lp/agora?utm_campaign=Agora&utm_source=Qiita&arc_id=c0ffb43a87f028dda684)
[<img width="912" alt="スクリーンショット 0001-08-15 13.41.56.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/300377/5d815376-9b89-08fa-9434-6fa7e8e67bcf.png">](https://jp.vcube.com/lp/agora?utm_campaign=Agora&utm_source=Qiita&arc_id=c0ffb43a87f028dda684)
---
Unityで作ったアプリをApp Storeへ公開するまで

私が通う就労移行支援事業所「GFTD WORKS」にて、ミニゲームコンテストが開催された。
初の開催で、主催側も応募側も調べながら動いていた。
そのときの、Unityで作ったアプリをApp Storeへ公開するまでの覚書を残しておく。
UnityとAppleのアカウントは、主催側が用意したものを使用。
公開作業を行ったのは、2020.01下旬頃。
Version: Unity 2018.4.12f1, xcode 11.3.1

---

[iOSアプリをリリースする際のプロビジョニングの設定 | 知の壺](https://chinotsubo.com/ios-provisioning-config/)
実機テスト時のsigning設定。developerとdistributionの混合がキモ。

[Bulk Resize Photos](https://bulkresizephotos.com)
スクリーンショットのリサイズに大活躍した。ただし、スクリーンショットの差し替えにはAppのバージョンアップが必要で、「とりあえず全機種間に合わせで突っ込んどいて後でちゃんと綺麗なの撮ろう」と構えて見栄えが死んだ。

[waifu2x](http://waifu2x.udp.jp/index.ja.html)
アイコンを高画質拡大し、AppStore用を作成。他にもサービスはあるのだろうが、以前Twitterで見かけたのを思い出して。

[iOSアプリを登録、申請して公開するまで](https://i-app-tec.com/ios/app-release.html)
一連の手順を参照した。足を向けて寝られない。

しかし、"アカウントは主催側用意"の罠がここに。
[ios distribution certificates 複数台 - Google 検索](https://www.google.com/search?q=ios+distribution+certificates+%E8%A4%87%E6%95%B0%E5%8F%B0)
Macは各人が有するものを使っていた。しかし、アカウントに紐付いたMac、つまり証明書をコピってくる親機が、ない。否、探せばあるのだろうが、応募者全員へコピってくる手段も時間もない。
最終的に、エラーを吐かれてしまうTARGETSのSigningを、Automaticallyで押し通してビルド。これがStore公開までいけてしまったので、仕組みを理解できていないままになっている。キーチェーン周りも全然把握できていない。私は感覚でビルドをしている……。

[エラーがないはずなのに「1個のローカリゼーションでエラーが発生しました」 - Qiita](https://qiita.com/VeyronSakai/items/9d1d5a6fb667ca4f5ddb)
iPad Pro(第2世代)の存在。なぜこんな階層に隠してあるのか。~~悪意しか感じられない。~~

提出したアプリは、2つとも運良くRejectなしに公開された。のでその辺りについては書けない。

---

振り返って。やるのは実機テストまで、からのコレだったので、ひたすらに手間が掛かる、という感想の他を抱けなかった。まあ、手続きというのは得てしてそういうものだ。
先生は「iOSは本当に面倒くさい、Androidは超簡単だから」と言っていた。いつかやってみたい。
公開作業は遂げたが、肝心の"いいゲーム"を作れなくて無念。

<img width="465" alt="bf1ce954-5ae5-4810-9b1a-fc09acc2672b.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/584430/70538423-1c9f-03ac-c276-2b73b64c3e4c.png">
[leaf](https://apps.apple.com/jp/app/leaf/id1496304111)
<img width="465" alt="4225786c-ecec-44a1-8576-d04f9c221b1d.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/584430/4fcafbf6-c94f-b004-9f57-891cad1816c7.png">
[sugarcoffee](https://apps.apple.com/jp/app/sugarcoffee/id1496079545)
入賞条件であるVoodooレベルのクオリティには至らなかったが、作ったゲームはこれらです。よかったら遊んでみて下さい……と言いたいのだが、お借りしたアカウントのメンバーシップが期限切れになっている(2020.03.11現在)ので、DLができない。無念。
2020.03.12追記: メンバーシップが更新され、復帰してます。よければどうぞ。
自分用：laravel 権限の設定の勉強で使用したサイト

念の為、備忘録として残しておく用なので
適当に記載しております。

https://www.ritolab.com/entry/56
あとはlaravel公式を参照。
https://readouble.com/laravel/7.x/ja/authorization.html

https://github.com/so-suke/tutorialRole

実施事項

- それぞれ別の権限をもったユーザを3種類作成
- それぞれのユーザごとにアクセスできるルーティングに違いを持たせる。
- それぞれのユーザごとに実行できるアクションに違いを持たせる。
- 管理者専用ボタンを押せるのは管理者以上のひとだけ。
- php側で例外処理する
- もし、アクションユーザの権限が足りない場合は、403送信
- 403ページ作成
- リダイレクトする
- 権限をログイン後、表示
- ポリシーの設定
- 投稿ボタンを押せるのはpost権限をもった人だけ
- ポストモデル作成
- ポストコントロラー作成
- 作成関数は、成功したら作成ページへ飛ぶ。
- 駄目なら403
- ポストマイグレーション、シーディング作成
- 投稿作成ボタン作成
【Git】pushまで 一連コマンドまとめ

<br>
初心者が初心者目線で書いた備忘録
---

### 【初期設定】Git初期設定などで検索し、ユーザー名とメールアドレスなどを設定

(SSHの設定とか分からない人いたらこちらが分かり易かったです)
http://monsat.hatenablog.com/entry/generating-ssh-keys-for-github

### 【初期化】

`git init`

### 【初回】リモートリポジトリから新規作成する場合

`git clone URL`

---

### 【更新】リモートリポジトリの内容を取得反映

`git pull ブランチ名`

---

### 作業ブランチを作成する

- branchを作成しチェックアウト
`git checkout -b 作成ブランチ名`

- ローカルブランチを作成しリモートブランチをpull
`git checkout -b 作成ブランチ名 origin/リモートブランチ名`

- 作成したbranchをリモートに登録
`git push -u origin 作成したブランチ名`

#### ローカルの差分をリモートへ反映させる
##### リモートリポジトリの最新情報がローカルに反映されていない場合、エラーが発生する

- ローカルブランチのリストを確認
`git branch`

- リモートブランチのリストを確認
`git branch -r`

- リストを更新
`git fetch --prune`

---

### ファイルをインデックス領域へアップ

リモートリポジトリにプッシュするためには、インデックス領域へアップする必要がある


- サブディレクトリも含めてアップ(差分全て)
`git add .`

- ファイルを指定して個別にアップする場合
`git add ファイル名`

- tigを使うことで効率的にaddもできる（参考↓）
https://qiita.com/suino/items/b0dae7e00bd7165f79ea

- 直後のgit addを取り消したい場合
`git rm --cached -r .`

#### add内容を確認する

commit前に内容を確認する

- 状態を表示<br>
`git status`

#### ローカルリポジトリへコミット

`git commit -m "任意のcommitメッセージ"`

#### ブランチの内容をリモートリポジトリへアップロード

`git push origin ブランチ名`

---

### ブランチを削除する

- マージされていないブランチを削除しようとするとエラーが出る
`git branch --delete ブランチ名`

- どんなブランチも削除
`git branch -D [ブランチ名] # mergeを無視`

---

### その他

- 現在のローカルブランチのcommit履歴を表示する
`git log`

- リモートブランチのcommit履歴を表示する
`git log origin/master`

`git reset --soft "HEAD^"`

- 直前のcommitを修正する
`git commit --amend`
Let's encryptよりもっと恐ろしいバグ（未定義動作）はC++で防げるのか？

# はじめに

Rustの素晴らしさを啓もうする記事でC++の恐ろしさ（未定義動作）が露呈してしまっていたので、C++でどうチェックすればいいのか解説します。

https://qiita.com/komasayuki/items/02785730d486ec4b397f

# 未定義動作

Let's encryptのバグを再現したというC++のコードですが、これはスコープが切れてしまっているループ変数のアドレスを使用しているので未定義動作です。

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

int main() {

    std::vector<int*> out;

    for (int i = 0; i < 3; i++) {
        out.push_back(&i);
    }

    std::cout << out[0] << std::endl;
    std::cout << out[1] << std::endl;
    std::cout << out[2] << std::endl;

    std::cout << *out[0] << std::endl;
    std::cout << *out[1] << std::endl;
    std::cout << *out[2] << std::endl;

    return 0;
}
```

# Visual Studio Lifetime Profile

Visual Studio 2019には上記のようなオブジェクトの生存期間に関するバグを警告してくれる[Visual Studio 2019 Lifetime Profile](https://devblogs.microsoft.com/cppblog/lifetime-profile-update-in-visual-studio-2019-preview-2/)という機能が付いています。この機能を使用して上記のコードを解析してみます。

デフォルトではオフなので機能を使用するためにプロジェクトのプロパティで以下の設定を行います。

1. "Code Analysis >> Enable Code Analysis on Build"を"Yes"
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12045/43135fb3-31be-1591-472f-5a020ee41b40.png)

2. "Code Analysis >> Microsoft >> Active rules"を"C++ Core Check Lifetime Rules"に設定。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12045/dd0d6f40-dc25-8bf4-9ad8-9cd95976124a.png)

Lifetime Profileで上記のコードを分析すると、`std::cout`をしている問題の行で2種類の警告(C26486とC26489)が表示されるようになります。

C24686は不正なポインタを関数に渡しているという警告です。上記のようにベクタに保存されているポインタはループ変数iへのポインタでiの生存期間が終わっているので不正なポインタになってしまっています。そのため不正なポインタ`out[0]`、`out[1]`、`out[2]`を関数`operator<<`へ渡しているのでこの警告が表示されます。

2つ目のC26489は不正なポインタをdereferenceしようとしているという警告です。C24686と同じ理由で`out[0]`は不正なポインタのため、それをdeference(`*out[0]`)しようとしているという警告です。

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

int main() {

    std::vector<int*> out;

    for (int i = 0; i < 3; i++) {
        out.push_back(&i);
    }

	std::cout << out[0] << std::endl; // warning C26486: Don't pass a pointer that may be invalid to a function.
    std::cout << out[1] << std::endl;
    std::cout << out[2] << std::endl;

    std::cout << *out[0] << std::endl; // warning C26489: Don't dereference a pointer that may be invalid
    std::cout << *out[1] << std::endl;
    std::cout << *out[2] << std::endl;

    return 0;
}
```

# 最後に

一度コンテナに保存されたポインタの生存期間に関する解析をしてくれるVisual Studio Lifetime Profileは素晴らしいですね！

普通にC++を書いていると生ポインタを扱うことは少ないかと思いますが、新しいツールやライブラリを使用してより安全なC++を書きましょう！
TypeScript + React + WebpackでCSSを使う

1. css-loaderとstyle-loaderパッケージをインストール

    ```bash
    $ npm install style-loader css-loader --save-dev
    ```

1. webpack.configにcssのためのルールを追加。

    ```bash
    ...
    rules: [
      ...
      { test: /\.css$/, loader: ['style-loader', 'css-loader'] }, # この行を追加。
    ```
上の様に書くと、`*.css`のファイルが、`入力 -> css-loader -> style-loader -> 出力`の形で処理される。
css-loaderが入力のcssファイルの`@import`や`url()`を解決して一つにまとめたものを、style-loaderが、以下のようにstyleタグの中に入れて、出力先のhtmlのheadタグ中に挿入する。

    ```html
    <head>
      <style type="text/css">
        #gigantic {
          font-size: 1000px;
        }
      </style>
      ...
    ````

1. cssファイルを用意して、srcの下あたりに置く。例えばstyles.cssを以下の内容で作る。

    ```css
    #gigantic {
      font-size: 1000px;
    }
    
    .crazy-small {
      font-size: 2px;
    }
    ```

1. cssを使いたいコンポーネント（例えば、app.tsx）で、cssファイルをインポートして、webpackに、このコンポーネントのHTMLにCSSを挿入するよう指示する。相対パスはモジュールと同じ形で指定すればOK。

    ```javascript
    import "../../css/styles.css"
    ```

1. HTMLにStyleがリンクされてる場合と同じように、idやclassでスタイルを適用する。

    ```html
    <div id="gigantic">Tokyo</div>
    <div className="crazy-small">Olympic</div>
    ```
Keras 任意の層の出力を取りたい!!

# はじめに
Kerasでネットワーク中の任意の層の出力を得る方法を記述します. 

## 実装例
```python:predict.py
from keras import backend as K
get_1st_layer_output = K.function([model.layers[0].input],
                                  [model.layers[5].output])

layer_output = get_1st_layer_output([img,])
img_layer_5 = layer_output[0][0,:]
```

# 実装例 (解説)
K.finction()の引数に入力層と得たい層を指定し. 関数を作成します. 
その関数に入力(ここでは画像)を引数として与えると得たい層の
出力が得られます!!
RaspberryPi4でONNX Runtimeをビルドする

#ONNXRuntimeとは
ONNXモデル向け推論エンジンです。
開発はマイクロソフトです。ossとしてリリースされています。

公式は[こちら](https://github.com/microsoft/onnxruntime)

バイナリパッケージはx86,x64向けしか提供されていないので、ARM向けはソースコードからビルドする必要があります。

今回はRaspberryPi4上でPython用Wheelパッケージをビルドしてみました。（直接ビルドする以外にDockerコンテナを使う方法もあります。）

ただ、公式の説明ではOSのバージョンがStretchを前提としているため説明文通りではビルドできませんでした。

後の手順でビルドはできています。

#環境
Raspberrypi4 4GBモデル
Raspbian Buster Fullバージョン （2020年2月5日リリース版）

#ビルドの手順
Raspbianインストール直後の状態から

```
sudo apt update
sudo apt upgrade
sudo apt install protobuf-compiler
sudo apt install cmake
sudo apt install libcurl4-openssl-dev
sudo apt install libatlas-base-dev

mkdir code
cd code

git clone --recursive https://github.com/Microsoft/onnxruntime

cd onnxruntime
```

そのままだとビルド中にエラーが発生するので、次の修正を行う。
・onnxruntime/cmake/CMakeLists.txtの最後に次の文を追加。

```
set(CMAKE_CXX_LINK_FLAGS "${CMAKE_CXX_LINK_FLAGS} -latomic")
```

修正後にビルドスクリプトの実行（Wheelパッケージの作成を指定）

```
./build.sh --config MinSizeRel --arm --enable_pybind --build_wheel
```

無事ビルドが完成したらonnxruntime/build/Linux/MinSizeRel/dist/にWheelパッケージがあるので、pip3でインストールするとonnxruntimeが利用できます。

#おまけ
今回はRaspberryPi4を使ってみましたが、Raspberrypi3+(Raspbian Buster)でも問題なくビルド出来るのを確認しています。

Widows(ARM32v7,ARM64)も対応しているようだけど、HoloLens2でも動作するんでしょうか。
実機がないので試せないですが・・・
シェルスクリプトで環境変数の値をファイルに出力する際の注意点（echo $hogeとecho "$hoge"の違い）

# はじめに

CI/CDパイプラインを組んでいて、ライセンスファイルの中身をGitHubでいうところのSecretsに置き、`echo 環境変数 > ライセンスファイル`でファイルを生成することがあると思います。

そこで認証が上手くいかなかった場合、真っ先に認証方法のミスを疑いドキュメントを見直したりしますが、意外にも原因はライセンスファイルの生成方法自体だったりします。

これに自分も何度かハマったことがあり、その度に共有しようと思うものの忘れてしまうので、今回忘れる前に投稿したいと思います。

# `echo $hoge`と`echo "$hoge"`の違い

変数の値をファイルに出力したい場合、`echo $hoge`と`echo "$hoge"`の違いを理解しておかないと、想定と違った動作を見せることがあります。

具体的に見ていきましょう。

`echo $hoge`の場合

```hoge.yaml
a:
  - b: hoge
```

```sh
$ hoge=$(cat hoge.yaml) # hoge.yamlは上記のもの
$ echo $hoge
a: - b: hoge # 改行が消える
```

`echo $hoge`の場合だと、**変数内に含まれる改行やタブはスペースに変換されてしまいます。**

この挙動により、例えばライセンスファイルを生成しようとすると、改行なしのファイルが生成されてしまい、正しく認証されなくなってしまいます。

変数の値に含まれる改行も一緒に出力したい場合は、**変数をダブルクオーテーションで囲う必要があります。**

`echo "$hoge"`の場合

```sh
$ hoge=$(cat hoge.yaml) # hoge.yamlは先ほどのものと同じ
$ echo "$hoge"
a:
  - b: hoge
```

# まとめ

APIキーやbase64エンコードしたものなど改行が含まれないものをSecretsに置くことが多いので、たまにこういったことをやろうとすると、うっかりハマってしまうことがあります。

記事にすることで、ハマらなくなったり、ハマってもすぐに気づけるようになれると嬉しいです。

GitHub: [@yukiarrr](https://github.com/yukiarrr)
Twitter: [@yukiarrr](https://twitter.com/yukiarrr)
C言語　フィボナッチ数を求めるコード

##問題
__n番目のフィボナッチ数を返すコードを作成せよ。__

- 引数が０より小さい場合は、-1を返す。
- 再帰的に実装する。
- 関数は以下の形を取ること
    - int fibo(int index);

- 禁止事項
    - ライブラリの使用は禁止
    - for、do...while、caseは禁止

##自作コード

```c
int fibo(int index)
{
    if(index < 0) return -1;
    if(index == 0) return 0;
    if(index == 1) return 1;
    if(index > 46) return 0;
    return fibo(index - 1) + fibo(index -2);
}
```

##Aさんのコード
```c
int fibo(int index)
{
    if (index < 0)
        return (-1);
    if (index == 0)
        return (0);
    if (index == 1)
        return (1);
    if (index > 46)
        return (0);
    return fibo(index - 1) + fibo(index - 2);
}
```
##テストケース

```c
#include <stdio.h>

int main()
{
    int i = 1;
    int x = 0;
    for(x = -3; x < 50; x++){
        i = fibo(x);
        printf("%dのフィボナッチ数：%d\n",x,i);
    }
    return (0);
}
```


##所感

- 最初、int型の最大値を考慮したコードになっていなかった。intの最大値は常に意識する必要がある。
- メモ化再帰を使いたかったが、関数の形が決められているため使えなかった。
    - 試しにメモ化再帰で実装してみたら速さがあまりに違うので驚いた。

- テストケースで考慮したこと
    - マイナスの数の場合の挙動
    - 0,1のときの挙動
    - 46前後の挙動


##おまけ　メモ化再帰を使用したフィボナッチ数を求めるコード

```c
int fibo(int index, int a[])
{
    if(index < 0) return -1;
    if(index == 0) return 0;
    if(index == 1) return 1;
    if(index > 46) return 0;
    if(a[index] != 0) return a[index];
    return a[index] = fibo(index - 1, a) + fibo(index -2, a);
}
```


##追記
2020/04/14
一ヶ月ぶりに似たような問題を解いたので戻ってきた。
書いてみたけど、うまく行かない。
メモ化再帰の部分で、staticをつけていなかった。
前回、ちゃんと理解できていなかった。
staticをつけることによって静的領域に値が保持され、計算結果が引き継がれる。
ここを理解できていなかった。復習大事。

```c
// ここ重要！
static int A[46 + 1] = {0, 1};
```


```c
#include <stdio.h>

int fibo(int n)
{
    static int A[46 + 1] = {0, 1};

    if (n < 0)
        return -1;
    if (n > 46)
        return 0;
    if (n >= 2 && A[n] == 0)
        A[n] = fibo(n - 1) + fibo(n - 2);
    return A[n];
}

int main(void)
{
    int N;

    scanf("%d", &N);

    printf("%d\n", fibo(N));
    return 0;
}
```
styled-componentsで生成したコンポーネントに独自propsを渡したい

#やりたいこと
liタグをstyled-componentsでStyledLiに変換して
中身である変数(propsにstateを渡して)に応じて
true or falseに応じて背景色をオレンジにしたり、灰色にしたりしたい。

こんなイメージ

```typescript
const StyledLi = styled.li`
  background-color: ${props =>
    props.isSelected ? orange : white
  };
`;
```

#初手
こんなふうに書けばいけんじゃね？
*下の例だと、必ずハイライトされないけどsetIsSelectedを切り替える機構が
どっかにあると思って読んでください。

```react
const MyComponent = () => {
  const [isSelected, setIsSelected] = useState(false);

  return (
    <ul>
      <StyledLi isSelected={isSelected}>test</StyledLi>
    </ul>
  );
};

const StyledLi = styled.li`
  background-color: ${props =>
    props.isSelected ? orange : white
  };
`;
```

無理でした。styled.liにisSelectedなんてPropsが存在しない。

#第２手
じゃあ、コンポーネントの中でStyled定義して、isSelectedのスコープ内に入れ込んじゃえば
propsで渡す必要がそもそもなくなるんじゃねーか？

```react
const MyComponent = () => {
  const [isSelected, setIsSelected] = useState(false);

  const StyledLi = styled.li`
    background-color: ${isSelected =>
      isSelected ? orange : white
    };
  `;
  
  return (
    <ul>
      <StyledLi isSelected={isSelected}>test</StyledLi>
    </ul>
  );
};
```

お、動いた！・・・がコンソールをみると
**styledは外出ししろ、アホが！**
的なお叱りを受けた。（しかも、StyledLiを１０こくらい表示してたから１０回怒られた）

とはいっても、外に出すとスコープ的にisSelectedなんて渡せるはずもなく・・・困った

#解法
interfaceを使って自分で定義すればいけるっぽい

```react
const MyComponent = () => {
  const [isSelected, setIsSelected] = useState(false);
  
  return (
    <ul>
      <StyledLi isSelected={isSelected}>test</StyledLi>
    </ul>
  );
};

interface MyProps {
  isSelected: boolean;
}

const StyledLi = styled.li<MyProps>`
  background-color: ${props =>
    props.isSelected ? orange : white
  };
`;
```

わーい。

#まとめ
Styledの中を変数で動的に変えたい場合は、
Interfaceで独自Propsを作ってあげれば、結構融通が効くようになるっぽい。
あるStateに応じてスタイルを変えられると、実装の幅も広がりそうですね
ラズパイ公式「Raspberry Pi Imager」がようやく

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/543063/ab881bb1-ace2-9680-7c30-85d573687c32.png)

若干遅れ気味の話です。
ラズパイの書き込みツールがようやく公式から出たっていう話。
何十年も待っていたよ。。
# ダウンロード
公式からだと落とすの遅いのでやはりミラーから。
http://ftp.jaist.ac.jp/pub/raspberrypi/imager/
公式はここ
https://www.raspberrypi.org/downloads/


Raspbian,NOOBSを書き込むのにようやく楽なツールがでた。

# 利点等
### 今までの書き込み方(Windows)
OS、SDカードの準備
　→　OSを事前ダウンロードしておく・・・手間！！
↓
SDカードのフォーマット
　→　64GB～だとexFATになるのでBuffaloのDisk Formatter とかを使う必要・・・手間！！
↓
Imagerとかで書き込みor解凍でコピー
　→　EtcherとかのImager・・・手間！！
SDカードをラズパイに差して起動

今までだとソフトを駆使してやらないといけなかったから面倒。
まぁWindowsは面倒くさいっす。。

### Raspberry Pi Imager が出てから
SDカードの準備
↓
Imager起動からのSDカードのフォーマット Erase
![スクリーンショット (11).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/543063/39808a88-f2d6-305d-f299-6a82f86d1a09.png)
Eraseで容量問わずFAT32フォーマットできる・・・！
↓
OSのダウンロード（選択）
![スクリーンショット (9).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/543063/4b1a9c4e-b30b-60e4-a11d-98254e0552a4.png)

![スクリーンショット (10).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/543063/3976e34e-77d9-e0d5-dc6d-a4da3be9296e.png)
Raspbian,LibreELECなどがImagerから直で落とせる。
もちろんVolumioなど事前にダウンロードしたものを選択できる。Use custom
![スクリーンショット (11).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/543063/b22d5260-93f1-bc6b-c0e6-cd42a8e485d6.png)
↓
SDカードセレクトしてフラッシュ

Raspberry Pi Imagerが登場してソフトこの一本で楽に書き込みできるようになった。

# まとめ
書き込みが楽になりました。
有効時間でNetflix、アマプラでアニメを見よう見よう
go modules での メジャーバージョンのあげ方

## v2以上にアップデートするにはコツがいる
golang でライブラリを作ったとき、破壊的変更をしてメジャーバージョンをアップデートするには少しコツが必要です。
サンプルの構成は以下の通りです。

```tree
/hello
├── go.mod
└── hello.go
```

```go.mod
module github.com/example/hello

go 1.14
```

```hello.go
package hello

func Hello() string {
	return "hello"
}
```


### vX.0.0 を作る
機能に破壊的変更を加え、コミット、プッシュします。
このコミットに対して `vX.0.0` タグ(X には任意のバージョンが入る) をつけてください。
**この時点では他リポジトリから利用できません**


```hello.go
package hello

func HelloV2() string {
	return "hello v2"
}
```


### vX.0.1 を作る
`go.mod` のモジュール名を修正します。

```go.mod
module github.com/example/hello/vX

go 1.14
```

`go get github.com/example/hello/vX` で利用可能になります。

## まとめ
- メジャーバージョンを上げるときは一旦`vX.0.0` というバージョンを作ってから モジュール名を変更する必要があります。
  - `vX.0.0` でいきなりモジュール名も変更してしまうと go get できません。
  - `vX.0.1` を作った後も `vX.0.0` は利用不可能なバージョンとして残ります。
- ちょっと変な感じ。。。
- もっといい方法があれば教えてほしいです。

## 参考
- https://github.com/rsc/quote/
[vue,googlemapapi]google.maps.event.addListenerの中でdataオブジェクトに代入しても反映されない



```
method: {
  hoge_func() {
　　　〜〜〜
      google.maps.event.addListener(map, 'click', function () {
        this.data.hoge = event.latLng.lat()
        console.log(this.data.hoge) 
　　　　　// 値が返ってくる
　　　　　// でもDOMで再描画されない
　　　　　// というか抜けると元の値に戻っている?初期化されてる?
      })

　　　 // 例えばmethodに、ListenerAct1 (event, map, marker) {} を作っておく
      let Listenerfunc = this.ListenerAct1
      google.maps.event.addListener(map, 'click', function (event) {
        let ev = event
        Listenerfunc(ev, map, marker)
      })

　　　これならtemplateに反映される。methodの中で呼ばれたオブジェクトでthisはスコープが異なるから

```



詳しい人解説求ム
Cypressでcy.click()がnot visibleやhideでクリックできないときに考えること

Cypressでcy.click()がnot visibleやhideでクリックできないときは、htmlのdomを、Cypressがどのように探していくかをよく考えてみると良いです。

```html
<!DOCTYPE html>
<html>
<head>
<title>My app</title>
</head>
<body>
 <table border="1">
    <tr>
      <th>Who</th>
      <th>Age</th>
    </tr>
    <tr>
      <td>Nick</td>
      <td>27</td>
    </tr>
    <tr>
      <td>John</td>
      <td>42</td>
    </tr>
  </table>
</body>
</html>
```
みたいなhtmlがあったとして `<th>`をクリックしたければ

```
cy.get('table > tr > th').first().click({force: true})
```

するとできる。

大切なのは `table`　ここ。 `table` すると、html全体から、上からコードを読んでいって、一番最初に出会った 
`table`から下へ調査する。なので、もし仮に

```
cy.get('table > th').first().click({force: true})
```

とかってやると、`th` まで辿り着けなくてクリックできない。

最初にスタートする地点から、一段一段降りていくのが大切。
本番環境のクローラーをテストする方法

# これはなに？

クローラーは外部サービスに依存するため、テストが大変です。
ここでは、その方法について考察します。

# 方針

考えられる方法は以下の2つです

* 外部サービスをモックする
* 外部サービスに実際にデータを入れる

しかし、前者の方法では、外部サービスの仕様変更に追従することができません。
今回は、後者の方法でテストを行います。

# 手順

1. [この投稿](https://qiita.com/nunukim/items/42d6014f93bdd7feb207) を作成します。
2. クローラーを走らせます。
  `poetry run crawler --url=https://qiita.com/nunukim/items/42d6014f93bdd7feb207`
3. 本番環境にこの記事が反映されていることを確認します。

# まとめ

いかがでしたでしょうか？
こうすることで、外部サービスに依存したクローラーのテストを行うことができます。
Minecraft Mod開発環境構築

# Minecraft Mod開発環境構築

IntelliJ IDEAでMinecrtft Modの開発環境を整える過程で、躓く点があったので忘備録として書く。

2020/3/15追記 

- Gradleで利用する文字コードをUTF-8を指定する方法について追記しました。
- runServerの起動方法について追記しました。

## 開発環境

- Windows 10 Pro
- IntelliJ IDEA 2019.3.3 (Ultimate Edition)
- Minecraft 1.12.2
- Minecraft Forge 1.12.2-14.23.5.2838

## 手順

1. Mod開発用のForgeをDLする(MDKを選択する)
2. DLしたForgeを解凍し、このディレクトリで`gradlew setupDecompWorkspace`をCMDで実行する  
BUILD SUCCESSFULを表示されれば成功
3. 次に、`gradlew idea genIntellijRuns`をCMDで実行する  
BUILD SUCCESSFULを表示されれば成功  
上記のコマンドでなく`gradlew genIntellijRuns`を実行したときに私の環境では`java.lang.NullPointerException`が発生して正常には完了しませんでした。
4. IntelliJで作業ディレクトリを開き、Buildタブの作業が完了するのを待つ。  
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152941/fcb9d6d0-4c26-5714-ca85-ba65840386ee.png)
5. `Gradle -> Tasks -> forgegradle`から`runClient`か`runServer`を選択し起動する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152941/078afda6-ef5d-8603-00a6-1b56df68a9dc.png)

## 文字コード指定

プロジェクトディレクトリ直下にある`build.gradle‘ファイルに下記を追記してください。

``` build.gradle
tasks.withType(JavaCompile) {
    options.encoding = 'UTF-8'
}
```

## Serverの起動方法

一度`runServer`を起動する。
この段階で起動しないのはeulaに同意していないためである。
`run/eula.txt`に同意することで起動できるようになる

## 最後に

どこのサイトに行っても`java.lang.NullPointerException`を解決する方法についての言及はありませんでした。
[Github](https://github.com/MinecraftForge/ForgeGradle/issues/533)のイシューも開いたままです。
なので、この手順で正しいのかも現状ではわかりません。
しかし、少しで同じような現象で悩まされている方の助けになれば幸いです。
お家でできるもん！～スクラムチームで一週間リモートワークをやってみた～　1/2


みなさんお仕事はかどってますか～？:star2:

私が所属するスクラム開発チームでは **一週間（ほぼ）全員でリモートワーク** に挑戦してみました！
これまでもチームの中の誰かが一日だけリモートをする事はよくあったのですが、大半のメンバーで長期間のリモートワークを行う機会は無かったので、記録を兼ねて試したことをまとめておこうと思います。
なお、スクラム開発ならではのイベントはこの一週間では行わなかったので、今回はチーム開発のコミュニケーション面に絞った内容を投稿します。

## まずは先人の知恵を借りる

 **複数ロケーションに跨るチームでのリモート開発** を実践したチームが、経験をもとに役立つ情報をまとめてくれた記事があったので参考にしました！

[複数ロケーションに跨るチームでのリモート開発実践ガイド](https://fintan.jp/?p=1377)


## 実際にやってみる

### その1 『働く環境を整える』

リモートワークをするために使用したツールは以下の通りです。
注釈にツールの簡単な紹介と公式サイトへのリンクを記載しています。

|用途 |ツール名|
|:--|:--|
|リモート接続|RemoteWorks Browse版[^1]|
|チャット|Slack[^2]、Microsoft Teams[^3]|
|Web会議|Zoom[^4]|
|タスク管理|Redmine[^5]|

[^1]: SaaS型リモートアクセスサービス。Browse版だと自宅PCへの設定は不要で、windowsでもMacでも使用できる点が便利。公式サイト：https://www.tis.jp/service_solution/ki_RemoteWorks/

[^2]: リアルタイムコミュニケーションが可能なチャットツール。1対1のチャットだけでなく複数人でのグループチャットも行える。絵文字のカスタマイズが行えるのが :thumbsup: 公式サイト：https://slack.com/intl/ja-jp/

[^3]: Microsoft製のチャットツール。会社のセキュリティ規則の関係で、SlackではなくTeamsしか使用できないチームメンバーがいるために併用。公式サイト：https://products.office.com/ja-jp/microsoft-teams/group-chat-software

[^4]: PCでもスマホでも会議に参加できる点がとても便利。共有された画面上に文字を書き込むことができるなど、単なるテレビ会議以上の機能を持っている。公式サイト：https://zoom.us/jp-jp/meetings.html

[^5]: オープンソースのプロジェクト管理ツール。タスク管理以外にもwiki作成機能などがあり、チームで作業を進める上での情報をまとめるのに役立つ。公式サイト：http://redmine.jp/overview/

まずは会社のセキュリティ規約に則った **リモートワーク環境の準備** が必要です。
私たちはRemoteWorksというツールを使用して、自宅PCから会社にあるPCにリモート接続しています。

次に必要になるのが **デジタルなコミュニケーション手段** です。
リモートワークをする場合は、隣に座っている人に声をかけることはできません。他のメンバーと気軽にコミュニケーションをとれるようにするためには、メールだけではなくチャットツールやWeb会議ツールを準備しておくと良いです。
また、誰がどのタスクを行っているかパッと分かるようにタスク管理ツールがあると便利です。
（リモートワークに限らず通常業務でも使えますよ！）

他にも、自宅PCがノートPCで画面が小さいなど、普段仕事をしている環境と異なる部分があると作業効率が落ちやすいので注意が必要です。
家で仕事をしているとミーティングでの移動も無く、気づけば一日座りっぱなし…という事も。適度な休憩を心がけましょう。


### その2 『自分の状況を発信する』

リモートワークを行う場合に限らず、チームで開発を行う際には互いの作業の進捗状況を把握し、困ったことがあれば早めに相談できる環境が必要です。
チームメンバーが同じ場所にいる際に声を掛け合い作業を進めるのと同様に、リモートでは **意識的に自分の状況を発信する** ことで「あの人何しているかわからないから連絡しづらいな～」という状況を避けるようにすると良いです。

おすすめは、各メンバーがチャットツールで作業状況や困りごとについてつぶやくための **個人チャンネル** の作成です！
以下の記事がとても参考になります。
[Slackで簡単に「日報」ならぬ「分報」をチームで実現する3ステップ〜Problemが10分で解決するチャットを作ろう](http://c16e.com/1511101558/)

「いつ来るかわからないつぶやきを追うのはキツい」という場合には、**時間を決めてオンラインミーティングを行う**と良いです。
私たちのチームでは1時間に1回、Zoomを使用してチームメンバーと顔を合わせて進捗報告や困りごとの共有を行っています。


### その3 『ミーティングは少人数で行う』

Web会議でミーティングを行う場合、参加者が多いと発言の音声が被りやすくなったり、誰が発言したか分かりづらくなります。
情報共有を目的とした発言者が限られているミーティングであればそれほど気になりませんが、**何かを議論する必要があるミーティングは最低限の人数で行う**ようにすると良いです。

また、**Web会議は顔出しで行った方が表情が伝わり話しやすい**です。
「顔出しだと自宅の様子が見えてしまうので恥ずかしい！」という場合は、Zoomで用意されている『バーチャル背景』機能を使用するのがオススメです！（オフィスの画像を使えばまるで職場にいるように見えますよ…）

## 感想

#### 家での開発は集中力が増す＆ペアプロもしやすい！
一週間のリモートワークを実施する前は「対面でのコミュニケーションを行わないと生産性が下がってしまうのでは…」という懸念がチーム内から上がっていたのですが、結果的には予定していたタスクを余裕をもって終わらせることができ、進め方さえ工夫すれば（少なくともコーディング作業においては）問題なく在宅勤務が行えることが分かりました。
在宅勤務で何よりも実感できたことは、ストレスの少なさです。満員電車に乗って出社する必要がなく、作業中に話しかけられることが少ないため、精神的にも肉体的にも負担が少なく仕事がはかどりやすいと感じました。
また、ペアプロを行う際には物理的に2人で1つのモニターをのぞき込むよりも、それぞれのモニターにZoomで共有した画面を映したほうが楽になるという気づきを得ました。（Zoomは共有画面に書き込みを行うことができるので、指摘箇所が分かりやすくなるのもメリットです！）

次の一週間では、対面でなければ難しそうなスクラムイベントにリモートワークで挑戦してみようと思います。
Unityでスマホアプリ開発環境を構築(1)

# Unity 環境構築

## 環境

- macOS 10.15.x


## インストール
### Unity Hubインストール

### Unity インストール

### ソースコード管理

### .gitignore ファイル追加
> Finderで任意のテキストを編集しづらいのでVSCodeで操作する。

1. Automater起動
2. クイックアクション
3. ユーティリティ > シェルスクリプトを実行 を追加
4. シェルに `/bin/zsh`、シェルスクリプトを以下を追加

```sh
for f in "$@"
do
    open -a 'Visual Studio Code' "$f"
done
```

5. ワークフローが受け取る現在の項目:「ファイルまたはフォルダ」、検索対象:「Finder.app」を指定
6. ファイル名に「Visual Studio Codeで開く」を指定して保存


# 参考文献

- Mac Finder のコンテキストメニューから`VSCode`を開く  
https://qiita.com/hiroyuki7/items/a3fcdf943c313473ecee
manaca localkitでアップロードすると[必要な処理の実行中にエラーが発生しました]と出てアップロードできない

タイトルの通りです。

対処方法：至ってシンプルで、monacaLocalkitを再起動したらアップロードできるようになりました。

これだけですが、誰かのお役に立つことを願ってます<(_ _)>
AndroidStudio3.6 Release実行時のNoSuchMethodException

- AndroidStudio 3.6 系が正式にリリースされましたね。
- その際以下の問題に問題にぶちあたったので、情報を残しておきます。

## 問題動作

- Android Studio 3.6 系にアップデート
- Android StudioからのDebug実行は問題なく動作
- Releaseビルドして実行
    - あれ？なんだか動かないぞ:frowning2:

## 問題点

- アプリ起動時によくあるAPIから`json`取得し、クラスオブジェクトに変換といった処理で以下のExceptionが出ている。

```
Caused by java.lang.NoSuchMethodException
parameter type is null
```

## とりあえずの対策
- `jackson` や `Moshi` といった JsonPerser のOSSで議論されており、現状の対応としては以下の対応を入れることで回避できました。

``` proguard-rules.pro
-keep class kotlin.Metadata { *; }
```

## 本対策は？

- 使用しているOSSで議論されており、OSSの更新が必要なのか、`R8`を更新すれば問題が発生しなくなるのかは、検討中のようです。
- 使用しているOSSの動向をチェックして対応していきましょう。

## 参考

https://github.com/square/moshi/issues/1049
https://medium.com/@AthorNZ/kotlin-metadata-jackson-and-proguard-f64f51e5ed32

それでは、楽しいアプリ開発を:dancer_tone1:
Railsのコールバックを用いてtextカラムに自動で記述を追加する方法


もし、ツイートの最後に定型文などをつけたい場合ってどうすればいいんだろう。
今日はそんなことを書きます＾＾

# コールバックとは

・オブジェクトの生成・更新・削除のタイミングで呼び出されるメソッド
・イベント（create, save,destroy）をトリガーとして登録可能
・トリガに対してメソッドを共通化できて便利

情報を変更や削除した時に呼び出せつメソッドですね。

# before_createで最後に！！を足してみる

では、before_createを使ったコードを書いていく。

```
  before_create :change_tweet

   def change_tweet
     self.text = text + "！"
   end

 end
```

## 処理の流れ

before_createが作動
↓
change_tweetメソッドが呼び出される。
↓
change_tweetメソッドの中に定義してあるself.textの処理
↓
self.textの中には、text + "！"という処理が代入されている
↓
textとは、Tweetクラスのインスタンスである


textとは、ユーザーが投稿ツイート内容のことを意味している。 + "！"の記述により、text の最後に"！！"を加える処理が加えて行われる。

今日は以上です＾＾


### 参考記事

https://morizyun.github.io/ruby/active-record-callback.html

http://ruby.studio-kingdom.com/rails/guides/active_record_callbacks
PHPができないなりに、お問い合わせフォームに動きをつけてみた 

#はじめに
現在ポートフォリオサイトを作っており、そちらに掲載するためのサイトを作成しているのですが、自分はPHPが使えないので、お問い合わせフォームに実際に送信させる機能をつけることができないのですが、それではあまりにも寂しいなと思ったので、入力して送信ボタンを押した後、また、入力して欲しい項目が未入力だった時に、JavaScriptを使って何か反応が起きるようにしてみました。

#JavaScriptのコード
```js
$(function(){
  $('#formlink(送信ボタン）').on('click', function(){
    if($('.formcheck（入力してほしい項目）').val() === ''){
      alert('未入力の項目があります！');
      $('.formcheck').focus();
      return false;
    }
    alert('送信完了！');
  });
});
```
上記のコードにより、お問い合わせフォームで、入力がすべて完了し、
送信した場合は『送信完了です！』
入力してほしい項目が未入力である状態で、送信した場合には『未入力の項目があります！』というアラートがそれぞれ出るようにしてみました。

#まとめ
PHPなどが使えないと実際にフォームを送信させることはできません。
しかし、JavaScriptを使用すれば、送信できる状態なのか、送信できない状態なのかを表示させることくらいは、可能であるということがわかりました。
今後は、PHPも勉強し、実際にフォームが送信できるようにしていきたいです。
WPFのおすすめ日時選択コントロール

WPFって日時選択部品ないよね
使いたいときにいつも忘れてしまっているので
毎回タダで使えるやつをぐぐって使うのだけど
今回見つけたやつが良かったので今後はこれにする

![demo](https://raw.githubusercontent.com/WaToI/DateTimePicker/master/tmp/demo.gif)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/145884/18604e56-5c63-8a26-49c7-420bb9da8ee7.png)

時間編集で24個ボタンが出るのがいい。分も同様に60個ボタンが出るｗ
実にシンプルで好感がもてる。
無駄にオシャレにくるくる回るコントロールつかいにくいよね

本家はhttps://github.com/jiangyan219/DateTimePicker
なのだけど、中国語だと日本人にはツライのでフォークして英語っぽい表記にした。だいたい雰囲気で伝わるはず
https://github.com/WaToI/DateTimePicker/releases

| 中国 | 日本 |
|:-:|:-:|
| 日期时间 | Calender |
| 小时 | Hour |
| 分钟 | Minute |
| 秒钟 | Second |
| 当前 | Now |
| 时间 | Time |
| 零点 | Zero |
| 确定 | OK |

グーグル先生の中⇒日翻訳はあやしい・・・
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/145884/049cad44-656f-1e4f-702c-2a86f4684698.png)
AWS認定不合格体験記（SAA-C01）



##あらまし

"勝ちに不思議の勝ちあり、負けに不思議の負けなし"ということで。
AWS認定(SAA-01)に臨んだものの返り討ちに遭いましたので、
失敗体験を分析して得られるであろう経験と、今後の策を示せればと思います。

こちらの記事に大きく影響を受けております

[10ヶ月勉強してもAWS認定ソリューションアーキテクト-アソシエイト-に合格できないので、勉強方法を振り返る](https://qiita.com/riekure/items/df84a24adaea4bf6c15b)

##結果

先ず試験結果ですがトータルのスコアは以下の通りです

596/1000（合格基準は720）

|回復性の高いアーキテクチャを設計する|再学習の必要あり|
|:-----------|------------:|:------------:|
|パフォーマンスに優れたアーキテクチャを定義する| 再学習の必要あり|
| セキュアなアプリケーションおよびアーキテクチャを規定する    | 十分な知識を有する       | column       |
| コスト最適化アーキテクチャを設計する     | 再学習の必要あり   | will         |
|   オペレーショナルエクセレンスを備えたアーキテクチャを定義する     | 再学習の必要あり          

セキュリティ以外、水準に届かずでした。。
バランスよくとらないと、トータルスコアが達していてもダメだという情報を調べるうちに聞きましたが、真偽はわかっていません。

補足ですが、スコアの算出は
TOEICのように、問題難易度の調整で点数が変動するという情報があり、
公式のFAQを確認すると、オフィシャルでアナウンスもされているようです。

>AWS Certification の合格スコアは、統計的分析を使用して設定されており、変更される可能性があります。試験のコンテンツが変更されると、試験形式に変更内容が反映され、試験問題と合格スコアも更新されるため、AWS では試験の合格スコアを公開していません。 

#敗因

試験前の対策期間は3週間でした、その間、以下のようなことをしていました。

1)AWS認定界隈で黒本と呼ばれているサイト、
[AWS 問題集で学習しよう]
(https://aws.koiwaclub.com/)のゴールドプランでSAAの問題を、1.5週。復習問題も数えると、1,200問くらい解いた状態でした。

2)そのほか、Udemyの[AWS認定ソリューションアーキテクトアソシエイト模擬試験問題集(5回325問分)](https://www.udemy.com/course/aws-knan/learn/quiz/4632478#overview)を1週。

3)AWS公式の模擬試験を受験(結果スコア:68%)

■反省点
以上、一応の準備はしたものの、大きくスコアが届かなかった原因は
**SAA-01が3/22でretireすることへの焦り**[^1]
の為、強引にその前に受験したことが挙げられます。

[^1]: AWS認定ソリューションアーキテクトアソシエイトは3/23以降、SAA-C01のバージョンが受験できなくなるのですが、SAA-C01自体、2018からの新バージョンでもあります。2018に参考書を買って勉強を進めていた時期があっただけに強引に受験した背景です。SAA-C02も殆ど内容は変わらないとあとで知って、性急な判断であったなと振り返るところです

[^2]: 模擬試験の結果が68%と同じ方が、Whizlabsの問題を解いて合格している記録をみつけたのがきっかけです

[^3]: SAA-C01とSAA-C02の差異は、出題分野の観点ではには【オペレーショナルエクセレンスを備えたアーキテクチャを定義する 】（6%を占めていた分野）が削除。スコアの重み付もコスト最適に重点が置かれるようです。セキュリティは2%減ってしまうようで、残念。


1)や2)は1週ではなくて、2週,3週と、こなすべきでした。
また、参考書もSAAは市販のものがそろっているので、購入し付属の模擬試験を併せて解くべきだったように思います。


#今後の対策

本を1~2冊取り組もうとしておりますが、
それ以上によさそうな方法がヒットしましたので、
こちらの[Whizlabs](https://www.whizlabs.com/)を中心に進めていこうかと思います。

[AWS 認定試験勉強の後半戦は Whizlabs で問題を解きまくるといいぞ](https://qiita.com/TaigoKuriyama/items/296cab6978f00df0556e) [^2]


#まとめ

AWSのサービスはEC2/lambda/dynamodb/API GATEWAY/S3の経験のみでしたが、
認定試験の勉強通じて、権限（mandate）や暗号化のサービス（KMS、Trusted Advisor）
の勘所が養えてよかったです

また下図のような
2層（two-tier）の構成を繰り返し問題として解いて、VPCやサブネットの構成、ネットワークACLの設定、ルーティングなど、
ネットワークまわりの知識が充填できます

今回の失敗を糧に
近いうちにSAA-C02 [^3]にトライします！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/198177/63df75f4-4725-4998-1bf4-b940aed1ea17.png)
https://docs.aws.amazon.com/ja_jp/vpc/latest/userguide/vpc-nat-gateway.html


#参考
[1]https://iwasiman.hatenablog.com/entry/20191015-aws-certified-saa-4challenger
C#で複素数を扱う

# 背景
C#で複素数を扱うことがありまして、調べたのでメモ書き。
やりたかったことは、Real/ImaginaryからMagnitude/Angleへの変換。
Complexクラスに放りこむだけで簡単に変換できるので超～楽ちん！

# やり方
1. プロジェクトの参照設定にSystem.Numericsを追加する。<br>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/374906/e7190524-4bab-ef8c-3058-66ada27a617d.png)
2. Complex形式でコンストラクタを使って変数定義する。

```
using System.Numerics

double Re = 1.0;      // Real
double Im = 1.0;      // Imaginary

Complex z = new Complex(Re, Im);

// z.Magnitude    <= 1.41421356
// z.Phase        <= unit:radian
```