OmniAICreator/Qiita-1.07M huggingface dataset:
rust勉強中メモ

rustの勉強中メモを残してみる。

# 単純なループ

ここからスタート。

- 要素数を10で決め打ちにして
- main関数の中に全部実装

```rust
fn main() {
  let mut arr = vec![0;10];

  for i in 0..10 {
    arr[i] = i;
  }

  println!("{:?}", arr);
}
```

`[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]`


# 要素数を可変にするには？

## for inで配列を参照渡し？(NG)

for in で配列を参照渡し……しても変わらない。
いやそもそも、indexに相当するものがなくなってるから、これだけじゃダメ―。

```rust
fn main() {
  let mut arr = vec![0;10];

  for mut i in &arr {
    i = i;
  }

  println!("{:?}", arr);
}
```

`[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]`

## enumerateを使えばできる？(NG)

```rust
fn main() {
  let mut arr = vec![0;10];

  for (i, mut v) in arr.iter().enumerate()  {
    v = &i;
  }

  println!("{:?}", arr);
}
```

`[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]`

ちょっとサンプルコードを変えると、arr[0]などは書き換わらずに、それをコピーした値だけが変わっているっポイ。

```rust
fn main() {
  let mut arr = vec![1;2];

  for (i, mut v) in arr.iter().enumerate()  {
    println!("{}", v);
    v = &5;
    println!("{}", v);
  }

  println!("{:?}", arr);
}
```

```
1
5
1
5
[1, 1]
```

## for inで配列の長さでrange()を作る(OK)

無理せず、0..X で設定するのが良い。

```rust
fn main() {
  let mut arr = vec![0;10];

  for i in 0..arr.len() {
    arr[i] = i;
  }

  println!("{:?}", arr);
}
```

# 関数にしてみよう

## シンプルな方法

`arr: &mut Vec<usize>` は、引数arrは、Vec<usize>に対する、mutableな参照型になりますよ、の意味。

雑にテストも用意しておく。

```rust
fn set_i ( arr: &mut Vec<usize>  ) {
  for i in 0..arr.len() {
    arr[i] = i ;
  }
}

fn main() {
  let mut arr = vec![0;10];

  set_i(&mut arr);

  println!("{:?}", arr);
}

#[test]
fn test_set_i () {
  let mut arr = vec![0;10];
  set_i(&mut arr);
  assert_eq!( arr[0] , 0);  assert_eq!( arr[1] , 1);
  assert_eq!( arr[2] , 2);  assert_eq!( arr[3] , 3);
  assert_eq!( arr[4] , 4);  assert_eq!( arr[5] , 5);
  assert_eq!( arr[6] , 6);  assert_eq!( arr[7] , 7);
  assert_eq!( arr[8] , 8);  assert_eq!( arr[9] , 9);
}
```

# 構造体にしてみよう

次にこの管理しているデータを、構造体でまとめよう。ついでに、メソッドも用意する。

えっと、self.XXX でアクセスしないと怒られますね。

```rust

struct HArr {
  arr : Vec::<usize> // private的な扱い
}

impl HArr {
  fn set(&mut self) { // 書き換える必要がある場合
    for i in 0..self.arr.len() {
      self.arr[i] = i;
    }
  }

  fn show(&self) { // 書き換える必要が無い場合
    println!("{:?}", self.arr );
  }
}

fn main() {
  let mut harr = HArr { arr: vec![0;10] };
  harr.show();
  harr.set();
  harr.show();
}
```

今日はここまで。
SQL Server Management Studioをスクリプトで自動インストール/更新する

環境を構築しなおすときなど、ChocolateyやScoopなどでパッケージ管理していると非常に便利なのですが、SQL Server Management Studio（以降SSMS）はつぎの点からそれらで管理するのが難しいです。

- Chocolateyには日本語版がない
- Scoopには未登録

またSSMSは自動更新機能がないので（通知は来る）、更新するためには毎回ダウンロードしてきて実行するといった手続きが発生して煩雑です。

そこでSSMSをインストールまたは更新するためのPowershellのスクリプトを書いたので共有しておきたいと思います。

```powershell
Invoke-WebRequest -UseBasicParsing -Headers @{"Accept-Language" = "ja-jp"} -Uri https://aka.ms/ssmsfullsetup -OutFile SSMS-Setup-JPN.exe
Start-Process -FilePath SSMS-Setup-JPN.exe -ArgumentList "/install /passive /norestart /wait" -Verb runas -Wait
```

これでインストールも更新も自動で実行されます。

ちなみにインストーラーのパラメーターは以下の通りです。

|パラメーター|説明|
|---|---|
|/install or /repair or /uninstall|インストール、修復、アンインストールします。インストールが既定値です。|
|/passive or /quiet|プロンプトなしの最小限の UI を表示するか、または UI もプロンプトも表示しません。既定では、UI とすべてのプロンプトが表示されます。|
|/norestart|製品をアンインストールする|
|/log <ログ ファイルのプレフィックス>|SSMS セットアップ ログの先頭文字です。既定では、ログ ファイルは %TEMP%\SSMSSetup の下に作成されます。|
dired上で複製ファイルを生成

以前出した[ファイルのデュプリケート・コマンド](https://qiita.com/s-fubuki/items/5b46b2896791a9e7f627#%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%81%AE%E3%83%87%E3%83%A5%E3%83%97%E3%83%AA%E3%82%B1%E3%82%A4%E3%83%88)にマークをつくようにしてみました。
dired でポイントされているファイルのファイル名の日付部分を現在の時間にしてデュプリケートします。
複製されたファイルには dired 上で `W` マークがつきます。
ファイル名に日付部分が無ければ付け足します。
前の版だと秒の部分がなくて出来立てのファイルだと元の版と衝突してデュプれないとかあったので、秒もつけました。

![dup-file-cap.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/239081/f3034b98-c358-3c36-c625-1d7ded168041.png)


自分の場合プログラムの更新をするとき目的のファイルをまずデュプリケートして複製されたものをいじっていき公開する版ではじめて ci して版が更新されます。
公開されるものの間と間にもいくつものマイナー版があったりなかったりです。
そもそもリビジョン・コントローラの類いはこういう雑多な手間を省くことも目的のひとつなんですが、自分の場合目標を実現するためにいくつかの段階を経てそこに到達させる事も多いので、この方が気楽にいじれていいのです。

以下を `init.el` の中にそのまま入れるか `dup-file.el` 等として load するようにします。

```emacs-lisp:dup-file.el
(require 'dired)
(require 'dired-aux)
(defvar dup-regexp "[12][0-9][0-9][0-9][01][0-9][0-3][0-9]\\([0-9][0-9]\\)*")
(defvar dup-char   ?W)

(defun dup-date-part-update (file-name &optional date)
  "FILE-NAME に `dup-regexp' が含まれていれば、\
その部分を現在の日付に置き換えた文字列を返す.
含まれていなければノードとエクステンションの間に\
日付を挟んだ文字列を返す.
DATE が non-nil なら日付をその日にする."
  (let* ((node (file-name-sans-extension file-name))
         (ext  (file-name-extension file-name))
         (date (format-time-string
                "%Y%m%d%H%M%S" (or date (current-time))))
         (reg  dup-regexp))
    (if (string-match reg file-name)
        (replace-regexp-in-string reg date file-name)
      (concat node "-" date "." ext))))

(defun dup-file (file &optional date)
  "FILE 名に現在の日付を埋め込んだ複製を作ります.
DATE が non-nil ならタイムスタンプもコピーします."
  (let ((new (dup-date-part-update file date)))
    (if (string-equal file new)
        (error "デュプリケートが同じ名前になる")
      (copy-file file new nil date)
      new)))

;;;###autoload
(defun dired-dup-file (prefix)
  "ポイントのファイルを日付つきの名前にして複製します.
prefix 在りならタイムスタンプもコピーし名前の日付もその日にします."
  (interactive "P")
  (let* ((file (car (dired-get-marked-files)))
         (date (if prefix (nth 5 (file-attributes file)))))
    (dired-add-file (dup-file file date) dup-char)))

;; 任意のキーにバイド
(add-hook 'dired-mode-hook
          (lambda ()
            (define-key dired-mode-map "\C-cd" 'dired-dup-file)))

;; 単独のファイルにする場合は以下もつける
(provide 'dup-file)
```

# Changes
- Sat Jan 23 10:04:43 2021

prefix をつけて実行するとタイムスタンプも複製され、 生成される日付もそのファイルのタイムスタンプのものになります。
【Swift5】Dictionary→Arrayへの変換をしたい

DictionaryのValueだけ取り出してArrayつくりたいとき。
Swift5.2.4。

```swift
Array(dictionary.values)
```

これでイケます。
※試してみたらArrayにしなくてもイケました。後述します。

```swift:サンプル
let children = ["Taro": 20, "Jiro": 19, "Saburo": 18]
let familyAge = [80, 79, 40, 40]
let years = familyAge + Array(children.values)
print(years.max()!) // 80
```

`values`の型は`Dictionary<Key, Value>.Values`なので、`Array`に変換しないとダメ……と思ったのですが、

```swift
let years = familyAge + children.values
```

これでもイケました。
どうやら`Dictionary<Key, Value>.Values`は`MutableCollection`というprotocolに準拠しており、`Array`と互換性があるようです。

`Dictionary<Key, Value>.Keys`はどないやねんと試してみました。

```swift
let children = ["Taro": 20, "Jiro": 19, "Saburo": 18]
let names = children.keys + ["Shiro", "Goro"]
print(names) // ["Saburo", "Jiro", "Taro", "Shiro", "Goro"]
```

Keysは`Collection`に準拠していて、これもこれでArrayと互換性あるようにつくられている模様。
型は合わせなきゃ行けないという先入観でArray()にしてましたが、割とキャストしなくてもイケそうでした。
AWS Blackbelt Fargate(入門）

以下の講演メモをつらつらとまとめました。
https://www.youtube.com/watch?v=VDPI91bHN-Q&feature=youtu.be

コンテナの利点

- portability
    - 再現可能な環境を自由度高く容易に定義できる
    - 特定イメージはいつどこで実行しても同じ環境
- Fast＆Rapid
    - 起動が早い
    - CI/CDパイプライン構築が可能
    - トライ＆エラーしやすい
- Efficient
    - リソースの有効活用
    - 弾力性の高いシステムが構築できる

#コントロールプレーン/データプレーン
- コントロールプレーン・・・コンテナを管理する場所
    - どこでコンテナを動かす？いつ止める？
    - デプロイ時にどういうふうに配置？
    - ECS, EKS
        - サーバが増えるとコンテナ管理が大変なので便利。
- データプレーン・・・コンテナが稼働する場所 
    - 各種状態をコントロールプレーンにフィードバック
    - AWS Fargete/EC2

#Amazon ECS
本番環境用の機能を充実させている。
- VPCネットワークモード
- オートスケーリングなど
- EC2へのTask配置が柔軟に設定可能
- データプレーンとしては当初EC2しか利用できなかった。
    - EC2の管理をしたくないという要望があった。→Fargateの登場へ

#Fargate
フルマネージドなデータプレーン→コンテナに集中できる
- インスタンス管理不要
- タスクネイティブAPI
- リソースベースの価格
    - 実行時間の秒単位で課金
    - タスクリソースに関する課金
        - CPUとメモリの組み合わせ

##構成
- Task Definition
- Cluster
    - 同一クラスタ内でFargateとEC2の移行が用意
- Task
    - コンテナの実行単位
- Service
    - ロングランニングアプリ用スケジューラ
        - 例. Taskの数を希望した数で維持
    - ELBとの連携

###VPC統合
VPC ネットワーキングMode
- FargateのタスクはVPC内で実行される
- セキュリティグループ
- Public IPのサポート
    - Elastic IPはサポートされないのかな？

###インターネットアクセス 
- TaskとやりとりするすべてのネットワークトラフィックにはTask ENIを利用

###LB
ELBとの統合はServiceでサポート
ALBとNLBをサポート

###パーミッションのタイプ
- Cluster Permission
    - 誰がタスクを実行できるか
- Application Permission
    - アプリがアクセス可能なAWSリソースはどれか？
- HOusekeeping Permissions
    - ECSに操作を許可したいパーミッションは何か？

##Fargeteモード、EC2モードどちらを選べば良い？
Fargateでは難しいもの

- Windows
    - Fargate 起動タイプは、現在 Windows コンテナではサポートされていません。起動タイプの詳細については、「Amazon ECS 起動タイプ」を参照してください。
    - https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/ECS_Windows.html
- GPU Support
    - https://www.acrovision.jp/service/aws/?p=774
- CPUとメモリの組み合わせがFargateにない。
- docker execのようなインタラクティブなデバッグ
    - docker execを使うとコンテナ内でプロセス実行できる
    - https://qiita.com/yosisa/items/a5670e4da3ff22e9411a
- スポットインスタンスやRIの価格モデル

##Lambdaを使うほうがいい場合
- イベントドリブン
- ミリ秒単位のコンピュート
- ランタイム管理をしたくない
    - ラムダはランタイムも管理してくれる。
- 分散バッチコンピューティング
    - ラムダは実行時間に5分という制限があるのでバッチはFargateやEC2

###ユースケース　メトリクスに応じてコンテナの数を自動スケールさせたい
Target Trackingとの連携

- Fargateの場合
    - サービスのスケールに応じて自然にコンテナが起動・終了
- EC2
    - インスタンスのリソースもうまくスケールさせる必要があり煩雑

#EKS
EKSを立ち上げることでK8Sのコントロールプレーンを作るのがかんたんになった。
vistaでquartus その25

#概要

vistaでquartusやってみた。
iverilog、modelsimは、動くのに実機では動かない問題。
signaltapでは、慣れていないので、捕らえられない。
一週間、悩んだ。

#結果

リセットで、ｎｎをクリアしていなかっただけ。
iverilog、modelsimは、最初だけしか見ない。
実機は、50mhzで動いてる。


```
module agent(input clk, input rst, input busy, output reg start = 0, output reg [7:0] char);
	reg [4:0] nn = 0;
	reg [3:0] state = 0;
	reg [23:0] cnt = 0;
	wire clk2 = cnt[13];
	always @(posedge clk)
	begin
		cnt <= cnt + 1'b1;
	end
	always @(posedge clk2 or negedge rst)
	begin
		if (!rst)
		begin
			state <= 0;
			nn <= 0;//ここ
		end
		else
		begin
			case (state)
			0:
			begin
				if (busy == 1'b1)
				begin
					if (nn != 5'd10)
					begin
						char <= 8'h40 + nn;
						start <= 1'b1;
						nn <= nn + 5'b1;
					end
					state <= 1;
				end
			end
			1:
			begin
				start <= 0;
				state <= 0;
			end
			endcase
		end
	end
endmodule


```

以上。
日付テーブルには 1月1日 から 12月31日 までを含めるのですぞという話。Power BI 謎マナーではありません。

守らないなら一向にかまわない。タイムインテリジェンス関数がまともに使えなくなって苦労するだけ。と説明をすることはありますけどね。でも、もっと大事なことことから考えれば 1/1 から 12/31 まで含めないとならないことに気づくと思うのです。

# どういうことか
ファクトテーブルがこんな感じになっているとき

|日付|値|
|:--:|:--:|
|2019-03-25|10,000|
|2019-04-15|10,100|
|...|...|
|2020-07-10|9,000|
|2020-08-15|8.000|

日付テーブルをこんな感じにしてしまう人が割といらっしゃる。

|Date|Year|Month|Day|
|:--:|:--:|:--:|:--:|
|2019-03-25|2020|3|25|
|2019-03-26|2020|3|26|
|...|...|...|...|
|2020-08-14|2020|8|14|
|2020-08-25|2020|8|15|

連続した日付は持っているから日付テーブルとして定義することは可能っぽいんだけど、とてもよろしくないのだ。

# なぜよ
モデリングやメジャーを勉強していると必ず日付テーブルは用意しましょうね。Power BI Desktop で自動で用意される日付テーブル使う場合はこうですよとか、独自に用意するときはこうですねってなっていて、このとき 1/1 から 12/31 までを含めてねって言われるはずだ。
自動で用意される日付テーブルが便利な時はあるとしても、フォーマットを変更できないのだから独自に日付テーブルを用意するわけで、このときおかしなことを始める人がいるんだよね。教えた人が悪いのか、教わった人が悪いのか、それはわかりかねるのだけど、いずれにしても不幸な話ではある。

## タイムインテリジェンス関数が必要としている
タイムインテリジェンス関数はとても便利だ。ましてやよく使われる集計や分析であるから便利な関数が用意されているわけである。最適化ということもあってもおかしくない。
で、タイムインテリジェンス関数は日付テーブル存在している日付列の値から結果を導き出しているので、よろしくないものとした例でいうと2019-03-24 以前の集計ができなくなってしまうのである。タイムインテリジェンス関数を用いて、2019-01-01 から 2019-03-24 と 2020-08-26 から 2020-12-31 を扱うことができなくなるんですよ。DATEADD でも STARTOFYEAR でも 試してみるとよい。
タイムインテリジェンス関数の扱う一番大きな間隔は "年" だから 1/1 から 12/31 を含めてよって話。

## データモデルに存在しないデータの集計はできない
そもそもデータモデルに存在しないデータを用いた集計することができないのだから、ディメンションテーブル(ここでは日付テーブル)には集計に利用される行をすべて用意しなければならないのだ。ファクトテーブルにはその名の通り事実だけが必要で、ファクトテーブルに存在しないディメンションデータをもれなく用意しておくことでデータモデル本来の価値を達成できるというものだ。データモデルに存在さえすれば、それを用いて集計ができるということである。

|日付|値|
|:--:|:--:|
|2019-03-25|10,000|
|2019-04-15|10,100|
|...|...|
|2020-07-10|9,000|
|2020-08-15|8.000|

というとき、本来の機能が実現する 日付テーブルを用意すれば、

|Date|Year|Month|Day|
|:--:|:--:|:--:|:--:|
|2019-01-01|2020|1|1|
|2019-01-02|2020|1|2|
|...|...|...|...|
|2020-12-30|2020|12|30|
|2020-12-31|2020|12|31|

こんな感じの集計ができるわけだ。

|年|月|メジャー|
|:--:|:--:|--:|
|2019|1||
|2019|2||
|2019|3|10,000|
|2019|4|10,100|
|...|...|...|
|2020|8|8,000|
|2020|9||
|2020|10||
|2020|11||
|2020|12||

メジャーが BLANK を返す時、なにを指し示しているか、だ。
2019 と 2020 の年単位で集計したときその結果(見た目)は変わらない。でも、月単位で集計をし表示したときはじめて有意な表示ができるようになるよね。2020-01 の集計結果として BLANK を得たということは、ファクトテーブルには 2020-01 のデータが存在しないことを明示できるということ。ないものはないものとした集計結果、存在するものは存在するものとした集計結果 いずれも明示できることがデータモデルには必要なのだ。

# 思ったこと🙄
Power BI はデータの可視化ツールだ。と思っている人が多いのだけど、ビジュアル(可視化)は機能の一部でしかないですからね。ビジュアルのためにデータを意図的に絞り込んだり改ざんをしてはいけませんよ。ということに繋がってしまいそうだなと。


# その他
- [Power BI 勉強会 - connpass](https://powerbi.connpass.com/)
- [Power BI Desktop を使い始めるには](http://qiita.com/PowerBIxyz/items/6c4735cb5b5712e70981)
- [Excel で Power Query を使い始めるには](http://qiita.com/PowerBIxyz/items/52e563037b855a099ca9)
【Objective-C】複数回タップの抑制と処理設定

#複数回タップの禁止
以下ではwebviewに対してのダブルタップを抑制しています。
UIWebViewやWKWebViewで表示した画面をダブルタップすると、画面が拡大されてしまうのでそれを抑制しています。
抑制するのではなく何かタップ回数によって処理を設定したい時は、最下部のデリゲートメソッドを利用すれば解決できます。

```objective_c
// UITapGestureRecognizerを初期化
UITapGestureRecognizer *doubleTap = [[UITapGestureRecognizer alloc]initWithTarget:self action:nil];

// デリゲートを設定
doubleTap.delegate = self;

// タップ回数を設定(ここの数値を変えれば、任意のタップ回数の挙動を設定できます。
[doubleTap setNumberOfTouchesRequired:2];

// 対象のviewに対して反映
[self.webView addGestureRecognizer:doubleTap];

// ダブルタップがされた際はこのメソッドが呼ばれます。抑制とは逆に任意の処理を設定したい時は、この中に処理をかけば実行されます。
-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRequireFailureOfGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
  NSLog(@"ダブルタップ");
  return true;
}
```
anyenv+pyenvでの環境構築(pyenvのみから移行(Mac))

#書いてること
pyenvのみの環境からanyenv+pyenvの環境への変更方法
（pyenvのアンインストール、anyenv+pyenvのインストール）
目新しいことはない（自分用）

#pyenv→anyenv+pyenv
結論、pyenvを削除してanyenvをインストール、anyenvでpyenvをインストールして、必要な環境を作り直す
[こちら](https://dev.to/m_yoshimo/xxenv-anyenv-install-1igm)によると単純にフォルダ移動するだけだと問題が起こるようなことが書いてあったので削除して作り直すことにした。

pyenvでインストールしたものを確認して削除

```
% pyenv versions
% pyenv uninstall 削除するもの
```

続いてpyenvのアンインストール

```
% brew uninstall pyenv
```
.zprofileに以下のような３行の記述があると思うので削除もしくはコメントアウト(以下のようにコメントアウトした)

```
#export PYENV_ROOT="$HOME/.pyenv"
#export PATH="$PYENV_ROOT/bin:$PATH"
#eval "$(pyenv init -)" 
```
また、/User/ユーザー名/内に.pyenvという隠しフォルダがあるが、もういらないので削除しておく。（残ってても問題なはいがすっきりさせておこう）

#anyenvのインストール

```
% brew install anyenv
```
.zprofileに以下を追記

```
% echo 'export PATH="$HOME/.anyenv/bin:$PATH"' >> ~/.zprofile
% echo 'eval "$(anyenv init -)"' >> ~/.zprofile
```

ターミナルの再起動すると以下のように言われるので

```
% source ~/.zprofile    
ANYENV_DEFINITION_ROOT(/Users/ユーザー名/.config/anyenv/anyenv-install) doesn't exist. You can initialize it by:
> anyenv install --init
```
指示に従う。

```
% anyenv install --init
Manifest directory doesn't exist: /Users/ユーザー名/.config/anyenv/anyenv-install
Do you want to checkout ? [y/N]: y
Cloning https://github.com/anyenv/anyenv-install.git master to /Users/ユーザー名/.config/anyenv/anyenv-install...
Cloning into '/Users/ユーザー名/.config/anyenv/anyenv-install'...
remote: Enumerating objects: 48, done.
remote: Total 48 (delta 0), reused 0 (delta 0), pack-reused 48
Receiving objects: 100% (48/48), 6.66 KiB | 3.33 MiB/s, done.
Resolving deltas: 100% (2/2), done.

Completed!
```
#pyenvのインストール

```
% anyenv install pyenv
/var/folders/s5/67jvmwk14ss73fj1x4368sym0000gn/T/pyenv.20200815051616.35266 ~
Cloning https://github.com/pyenv/pyenv.git master to pyenv...
Cloning into 'pyenv'...
remote: Enumerating objects: 7, done.
remote: Counting objects: 100% (7/7), done.
remote: Compressing objects: 100% (6/6), done.
remote: Total 18140 (delta 0), reused 3 (delta 0), pack-reused 18133
Receiving objects: 100% (18140/18140), 3.62 MiB | 2.63 MiB/s, done.
Resolving deltas: 100% (12334/12334), done.
~

Install pyenv succeeded!
Please reload your profile (exec $SHELL -l) or open a new session. 

指示に従って以下のようにシェルを再起動
% exec $SHELL -l
```

#pyenvの確認

```
% pyenv versions
* system (set by /Users/ユーザー名/.anyenv/envs/pyenv/version)

% pyenv install 3.7.8
python-build: use openssl@1.1 from homebrew
python-build: use readline from homebrew
Downloading Python-3.7.8.tar.xz...
-> https://www.python.org/ftp/python/3.7.8/Python-3.7.8.tar.xz
Installing Python-3.7.8...
python-build: use readline from homebrew
python-build: use zlib from xcode sdk
Installed Python-3.7.8 to /Users/ユーザー名/.anyenv/envs/pyenv/versions/3.7.8

% pyenv global 3.7.8
% python
Python 3.7.8 (default, Aug 15 2020, 05:17:58) 
[Clang 11.0.3 (clang-1103.0.32.59)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>>
```
ちゃんと切り替わっている

#参考
https://note.com/digiangler777/n/n16c2853e7287
https://qiita.com/kai_kou/items/f54931991a781b96bb9c
https://qiita.com/koooooo/items/b21d87ffe2b56d0c589b
https://stangler.hatenablog.com/entry/2019/01/18/161956
それらを作るSEOツールはあらゆる状況で機能します

さまざまな目的を果たすために必要な <a href="https://www.easkme.com/2018/12/seo-tools.html">SEOツール </a>にはさまざまなタイプがあります。最も一般的に知られているものは次のとおりです.
キーワード研究のためのSEOツール
    ランク追跡のためのSEOツール
    コンテンツ最適化のためのSEOツール
    バックリンク分析のためのSEOツール
    ビデオSEOのためのSEOツール
    リンク構築のためのSEOツール
    技術的なSEOのためのSEOツール
macOS 10.15でiTunes 12.6.5を使う

[macOS 10.14でiTunes 12.6.5を使う](https://qiita.com/wasnot/items/e3fa2e8a0210d44affa7)記事の 10.15版になります。



# 結論

pkgファイルを展開して、中身のpayloadを直接コピーしました。
最後にiTunesのバージョンを偽装して終わりです。

```bash
# 前回同様dmg内のpkgを展開する
$ pkgutil --expand path-to/iTunes.pkg  ./tmp

# 必要そうなpkgディレクトリのBomやPayloadからファイルを展開
$ cd tmp

# iTunesAccess
$ ditto -x --bom iTunesAccess.pkg/Bom iTunesAccess.pkg/Payload iTunesAccess/
# ディレクトリ構造ごと展開されるので、ルート直下から同じ場所に移動します。
$ sudo mv iTunesAccess/System/Library/PrivateFrameworks/iTunesAccess.framework /System/Library/PrivateFrameworks/

# iTunes.app(iTunesX)
$ ditto -x --bom iTunesX.pkg/Bom iTunesX.pkg/Payload iTunesX/
$ sudo mv iTunesX/Applications/iTunes.app /Applications/
$ sudo mv iTunesX/Library/Frameworks/iTunesLibrary.framework /Library/Frameworks/iTunesLibrary.framework
# Documentationとかもあるので必要に応じてコピー

# 他にもCoreADI, CoreFP, MobileDeviceが含まれていましたが、自分の環境だと移動先に既に存在したので今回は移動しませんでした

# 最後に前回同様Info.plistのバージョンを書き換えて完了。10.14の時より新しいバージョンを指定しないと起動できませんでした。
$ sudo sed -i '' 's/12.6.5/13.6.5/g' /Applications/iTunes.app/Contents/Info.plist
```

Systemsディレクトリへのコピーがうまくいかない場合は、SIPの無効化やボリュームの再マウントを試してください。
（全部やった状態だったのでどこまで必要かわかってない）

# ハマったところ

## SIPを無効化しても/Systems以下には書き込めない

管理者権限でも書き込めなくなりました。
(`sudo installer -pkg /path/to/package.pkg -target /`としてもだめ)

再マウントすればとりあえず書き込めるようになっています。
https://ameblo.jp/jochi-masaharu/entry-12564076509.html

これをしないとインストーラー内で/Systems以下への書き込みがあると、そこで弾かれてしまいます。
再マウントすることで「このままインストールする」ボタンが現れました。

## MobileDevice等が既に存在する？

書き込み可能にしたり管理者でinstallerを起動したりしましたが、インストール後の検証で落ちます。
おそらく、Finder.appにMobileSync等の機能が追加され、各種frameworkが既にインストール済みのため、うまく上書きできないのかと考えて、iTunesAccess.frameworkとiTunesX(iTunes.app)のコピーだけ行うことにしました。

# 参考
- [macOS CatalinaでApp Storeが使えるiTunes 12.6.5をインストールする方法](https://ichitaso.com/mac/itunes-12-6-5-install-on-macos-catalina/)
    - betaの時は前回の方法でインストールできたっぽいです
- [Installer fails on installing into /Applications on Catalina](https://developer.apple.com/forums/thread/120314)
    - 該当エラーがsystemsディレクトリへの書き込みのある場合に出ることが言及されてました
- [Package is incompatible with this version of macOS](https://georgegarside.com/blog/macos/package-incompatible-installer/)
    - 解決方法の3つ目にパッケージ展開してファイルをコピーする、とあったので今回の方法を思いついました
- [Catalinaでシステムファイルを書き換える方法](https://ameblo.jp/jochi-masaharu/entry-12564076509.html)
- [Mac OS Xのパッケージファイルを操作する](https://blog.niw.at/post/16690761384)
windowsでiverilog その64

#概要　

windowsでiverilogやってみた。
regの初期化、調べてみた。

#サンプルコード


```
module test(input clk, input rst, output reg led = 0);

endmodule
```


```
module test(input clk, input rst, output led);
    reg led = 0;
endmodule
```


```
module test(input clk, input rst, output reg led);
    initial
    begin
        led = 0;
    end
endmodule
```

以上。
EC2で自分のPCからssh接続する流れを書いてみる

一応、手順書通りにやればできるが脳死コピペマンだとやばいので流れをかいてみる。

1. vpcで仮想ネットワークを作成して、サブネットでvpcを分割する。
2. インターネットゲートウェイ(igw)をvpcに接続してインターネットに接続する準備をする。
3. 作成したサブネット内にEC2を作成する。この時にsshに接続する際のキー（pemファイル）をダウンロードしておく。
4. ec2にセキュリティーグループを設定してsshに繋ぐ設定をする。
5. ec2にルートテーブルを接続すると、igwを通して自宅のpcに接続する準備ができる。
6. 下記コマンドでssh接続できる。

```bash
 ssh -i "pemFilePath" ec2-user@publicIP
```

何かアドバイスあればよろしくお願いします。
DjangoのDBをmongodbに設定する方法　visual studio 2019

DjangoのDBをmongodbに変更する。

#環境
Django 2.2.15
mongodb 4.0.3
djongo 1.3.3
visualstudio 2019

#手順
djongoをインストール
```
pip install djongo
```
setting.pyのDatabeseを変更。hostにmongodbのURIを指定。

```setting.py
DATABASES = {
    'default': {
        #'ENGINE': 'django.db.backends.sqlite3',
        #'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
        'ENGINE': 'djongo',
        'NAME': '{your_dbname}',
        'CLIENT': {
           'host': 'mongodb://{user_name}:{pass}@{ip_adress}:{port_num}/{your_dbname}',
        }
    }
}
```

参考　https://github.com/nesdis/djongo

一度、全て保存してVSを閉じる。
VSを立ち上げて、
プロジェクト名を右クリック、
python
スーパーユーザーを作製
をクリック
![名称未設定 1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/175440/32cfca15-8954-76cf-b960-d3ceb61ce5a9.jpeg)

対話型ウィンドウの指示に従ってスーパーユーザーを作製。
プロジェクトを起動してadmin画面に入れることを確認する。
mongodbのGUIソフトを立ち上げ、指定したDBにdjango関係のコレクションが作製されていることを確認する。
![コレクション.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/175440/8331589b-f52a-192c-be0d-141e6770220f.jpeg)

以上。
【iOS】Pythonista3で共有シートを使う。

# はじめに
iOSの共有メニューからPythonista3のスクリプトを起動する方法のメモ。

# 共有メニュー
 iOSには他のアプリにデータを受け渡すことができる共有メニューがあり、次のようなアイコンを様々な場面で見かけます。
<img width="100" alt="share" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280129/21543800-00fc-7ede-33e7-b742a29c50fb.png"> 
 これをタップすると出てくるメニューには、標準の**AirDrop**、**メッセージ**、**メール**の他にインストールされているアプリで**共有シート**に対応したアプリが並び、そしてその時の操作に対応した**アクション**も表示されます。
# Run Pythonista Script
 **Pythonista3**をインストールすると、共有メニューの**アクションの欄**に**Run Pythonista Script**というメニューが追加されます。

このメニューをタップすると、あらかじめ登録しておいたスクリプトのアイコンが並びます。

<img width="400" alt="share" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280129/0dcc33bf-1467-6bd1-a3c9-639f7e9ef9d3.png"> 
これはあらかじめ**./Examples/Extension**にプリセットされているスクリプトです。
ここに自分で作ったスクリプトを登録することができるので、ほかのアプリからデータを受け取り、加工してから保存するという使い方もできます。

次のサンプルは受け取った画像を時計回りに90度回転してコンソールに表示します。

```python:test.py

import appex
import console

def main():
  if not appex.is_running_extension():
    console.hud_alert('共有シートから実行して下さい。','error',2)
    return

  image = appex.get_image()
  if not image:
    console.hud_alert('イメージが見つかりません。','error',2)
    return
  
  # 画像を回転してコンソールに表示する。
  image = image.rotate(270, expand=True)
  image.show()
  
if __name__ == '__main__':
  main()
```
共有メニューから呼び出さないと実行できないようにしてあるので、次はこれを共有メニューから実行できるようにします。

# Share Extension Shortcuts

**Pythonista**の設定画面から**Share Extension Shortcuts**の登録ができますが、写真アプリなどの共有メニューからも可能なので、写真アプリからやってみます。
1. 画像を開いた状態で共有メニューを開きます。
2. **Run Pythonista Script**をタップします。
3. **Edit**をタップすると出てくる「⊕」アイコンをタップします。
4. ファイル選択ダイアログが表示されるので、登録したいスクリプトを選択します。動画では`Examples/Extension/test.py`を選択してます。
5. いろいろ設定できますが、今回は登録するだけなので、**Add**をタップします。
6. いま登録したスクリプトのアイコンが追加されてれば登録成功です。
7. アイコンをタップすればスクリプトが実行されます。
![A18DCF13-7504-4514-8E2E-DB7373B23A45.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280129/1e8e46f1-5c71-c68d-2195-d02719ac98c7.gif)

上のGIFのもとの[動画のリンク](https://twitter.com/maboysan/status/1294471764332802049?s=21)です。
Laravelの失敗談をまとめてみる

# Laravelでひっかかったことまとめ

## 目次
1. Ajaxを利用してPUTを送信しようとしてRequestが空


### 1.Ajaxを利用してPUTを送信しようとしてRequestが空

#### 概要
```php
	$.ajax({
		url: url,
		type: 'PUT',
		data: data,
		cache: false,
		contentType: false,
		processData: false,
		dataType: "json"
	}).done(function (data, textStatus, jqXHR) {
```

こういうプログラムを準備してデータを送信。
F12のdeveloper toolsではformのデータをきちんと飛ばしているのに受け取り側のlaravelで

```php
dd($request->all());
```

とやっても空

#### 原因

type: 'PUT' じゃなくて、_methodを利用して送信する。すっかり忘れていたよ。(;´д｀)トホホ

```php
	data.append('_method', 'PUT');
	$.ajax({
		url: url,
		type: 'POST',
		data: data,
		cache: false,
		contentType: false,
		processData: false,
		dataType: "json"
	}).done(function (data, textStatus, jqXHR) {
```

これで送信。
VSCode の Remote-Containers Extension v0.131.0 から、選べる Java の Configuration は1つになりました[追記あり]

_2020/09/30 追記_
v0.138.0 から，Java 8 の Configuration が復活しました。

https://github.com/microsoft/vscode-dev-containers/pull/517

---

Java を Remote-Containers 拡張でやろうと思って導入したら、いきなり詰まったのでメモ。

# 詰まった点

`VSCode Remote Containers Java` とかのキーワードでググると、いくつか記事が出てくる。
参照すると、「`Remote-Containers: Add Development Container Configuration Files` から `Java (8|11|14)` を選んで〜〜」というように説明されているが、実際に試すとバージョン別のConfigurationが見つからない。
下図のように、`Java` だけがあり、あとは Azure Function 向けの Configuration だ。

![スクリーンショット 2020-08-15 0.39.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/66988/5e7f4c71-52ad-7c7f-176f-fa38c2b7f0d4.png)

これを選ぶと、JDK 11 の `.devcontainer` が取得されるのだが、
今回は8系の環境を作りたかったので少し困った。

# 理由

[vscode-java が Java 11 以上を要求するようになった](https://github.com/redhat-developer/vscode-java/wiki/JDK-Requirements#jdk11.requirement)ことを受けて、Predefined Configurations に対して以下の PR が行われたため（今回詰まった点に対応する部分を太字にしています）。

> 1. **Removes `java-8` and `java-8-tomcat`**
> 2. **Consolidates `java-11` and `java-14` into one definition with a build arg to pick the version.**
> It uses `buster` as the distro since there's no Oracle one for 11.
> 3. Adds args to let people opt into installing their preferred version of Maven or Gradle with just a tweak to `devcontainer.json`
> 4. Resolves the issues with cleanup highlighted in #422
> 5. Improves layering so that maven or Gradle can be enabled without having to also re-do the common script

> https://github.com/microsoft/vscode-dev-containers/pull/456

「`java-8` と `java-8-tomcat` の Configuration をなくして、`java-11`と`java-14`のConfigurationを統合したよ」と。

で、これは v0.131.0 から有効になっています。

# 11 未満をどうにかする場合

以下の2通りかなと思います。

- v0.131.0 未満の Remote-Containers 拡張をバージョン指定でインストールする。
- JDK 11 で、コンパイルオプションの `--source` とか `--target` を使って頑張る。

# 11 以上にする場合

上記の 2. に書いてあるとおり、build argument でバージョンを変更できます。
`devcontainer.json` の以下です。

```js:devcontainer.json
		"args": {
			// Update the VARIANT arg to pick a Java version >= 11
			"VARIANT": "11",
			// 略
		}
```
Snowflakeにてクエリ実行時にキャッシュを利用しないようにパラメータを設定する方法

## 概要
Snwoflakeにて、Snowflakeのキャッシュ機能を利用しないように設定する手順を紹介します。
他ツールからのパフォーマンス検証を実施するために実施しました。

本手順では、サーバーのパラメータを変更してしまうため、本番環境には設定しないように注意してください。

## 手順

### 1. 現在のキャッシュのパラメータ設定（"USE_CACHED_RESULT"）が、"true"となっていることを確認

```sql
SHOW PARAMETERS LIKE '%USE_CACHED_RESULT%'
```
参考リンク:[パラメーター - USE_CACHED_RESULT](https://docs.snowflake.com/ja/sql-reference/parameters.html#use-cached-result)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/fdcddc47-c347-fd96-56b5-ba6cc7e160f8.png)

#### 2. キャッシュのパラメータ設定（"USE_CACHED_RESULT"）の設定を、"false"に変更
```sql
use role accountadmin;
ALTER ACCOUNT SET USE_CACHED_RESULT = false;
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/523b2a5b-730d-f07b-77eb-13e54b72acb7.png)


### 3. 現在のキャッシュのパラメータ設定（"USE_CACHED_RESULT"）が、"false"となっていることを確認

```sql
SHOW PARAMETERS LIKE '%USE_CACHED_RESULT%'
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/38ed8026-b3de-c12e-1ff1-96f6d7641247.png)


## 設定の確認
"History"にて、設定前後に同じクエリを複数回実行することで、キャッシュを利用しているかを確認できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/83a0a2cb-51d0-fecf-76dc-f2f96984a9c7.png)

```sql
/* TPC_H Query 9 - Product Type Profit Measure */
USE "SNOWFLAKE_SAMPLE_DATA"."TPCH_SF10";

SELECT
    nation
    ,o_year
    ,SUM(amount) AS sum_profit
FROM
    (
        SELECT
            n_name AS nation
            ,YEAR(o_orderdate) AS o_year
            ,l_extendedprice * (1 - l_discount) - ps_supplycost * l_quantity AS amount
        FROM
            part
            ,supplier
            ,lineitem
            ,partsupp
            ,orders
            ,nation
        WHERE
            s_suppkey = l_suppkey
        AND ps_suppkey = l_suppkey
        AND ps_partkey = l_partkey
        AND p_partkey = l_partkey
        AND o_orderkey = l_orderkey
        AND s_nationkey = n_nationkey
        AND p_name LIKE '%green%'
    ) AS profit
GROUP BY
    nation
    ,o_year
ORDER BY
    nation
    ,o_year DESC
;
```


## 参考リンク

- [パラメーター - USE_CACHED_RESULT](https://docs.snowflake.com/ja/sql-reference/parameters.html#use-cached-result)
- [SHOW PARAMETERS](https://docs.snowflake.com/ja/sql-reference/sql/show-parameters.html)
Go1.15改訂版、Go言語アプリのDockerイメージをscratchから作る

こんばんは、ねじねじおです。

Go言語アプリの Docker イメージを scratch からつくるとき、builder ステージから `/usr/share/zoneinfo` ディレクトリをコピーしていますか？
それとも、 `/usr/local/go/lib/time/zoneinfo.zip` ファイルをコピーしていますか？
あなたはどちら派ですか？

もう、そんなことで争う必要はないのです。Go 1.15 がリリースされたから。

## Go 1.14 まで

Go 1.14 までは、タイムゾーンを解決するためにbuilderステージからタイムゾーンデータベースをコピーする必要がありました。
下記の最後の行です。

```Dockerfile:Dockerfile
FROM golang:1.14.7 AS builder
WORKDIR /go/src/app
COPY ./ ./
RUN go mod download
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o ./server ./server.go

FROM scratch AS production
WORKDIR /go/bin
COPY --from=builder /go/src/app/server ./
COPY --from=builder /usr/share/zoneinfo /usr/share/zoneinfo
```

環境依存でなんだか無粋ですね。

## Go 1.15 では

Go 1.15 では、タイムゾーンデータベースをコンパイル後のバイナリの中に組み込むことができるようになりました。

[Go 1.15 Release Notes / New embedded tzdata package](https://golang.org/doc/go1.15#time/tzdata)

方法は2つあります。検証してみましょう。

### 準備

以前の記事で使った echo の小さな WebAPI を使います。
[Go言語アプリのDockerイメージをscratchで軽量化してみた](https://qiita.com/nejinejio/items/77355ee8e7f6b4894fbd)

結果がわかりやすいように、プログラムを変更して Go のバージョンも出力するようにしました。
 
```golang:server.go
	e.GET("/", func(c echo.Context) error {
		return c.JSON(http.StatusOK, []string{
			"Hello, World!",
			time.Now().Format(time.RFC3339),
			runtime.Version(),
		})
	})
```

では、Dockerfileから
`COPY --from=builder /usr/share/zoneinfo /usr/share/zoneinfo`
を削除して、ビルドして実行してみます。

```sh
$ docker build ./ -t example
$ docker run -e TZ=Asia/Tokyo -p 1323:1323 example ./server
$ curl http://localhost:1323/
["Hello, World!","2020-08-14T15:28:16Z","go1.15"]
```

予想どおり、タイムゾーンが効いていないです。

### 方法① ビルド時に -tags timetzdata オプションを付ける

```Dockerfile:Dockerfile
FROM golang:1.15.0 AS builder
WORKDIR /go/src/app
COPY ./ ./
RUN go mod download
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 \
    go build -tags timetzdata -o ./server ./server.go

FROM scratch AS production
WORKDIR /go/bin
COPY --from=builder /go/src/app/server ./
```

ビルドして実行してみます。

```sh
$ docker build ./ -t example
$ docker run -e TZ=Asia/Tokyo -p 1323:1323 example ./server
$ curl http://localhost:1323/
["Hello, World!","2020-08-15T00:37:14+09:00","go1.15"]
```

タイムゾーンが反映されています！

### 方法② プログラム内で、time/tzdata パッケージをインポートする 

先ほどのDockerfileの go build コマンドから `-tags timetzdata` を削除します。

```Dockerfile
# RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 \
#     go build -tags timetzdata -o ./server ./server.go
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 \
    go build -o ./server ./server.go
```

代わりに、プログラム内に `import _ "time/tzdata"` を追加します。


ビルドして実行してみます。

```sh
$ docker build ./ -t example
$ docker run -e TZ=Asia/Tokyo -p 1323:1323 example ./server
$ curl http://localhost:1323/
["Hello, World!","2020-08-15T00:49:39+09:00","go1.15"]
```

OK !
タイムゾーンが反映されています。

## そして、新たな火種が

OK。
と終わりたいところですが、 選択肢が2つ増えたことで論争の火種が増えてしまってますよね。

ねじおは、プログラム側は実行環境を知り得ないというスタンスで「ビルド時に `-tags timetzdata` オプションを付ける」を選択します。

OK。
ねじねじおでした。
Cloud Functions を Node.js 10 移行する

久しぶりに Cloud Functions のコンソール画面を開いたら下記のような警告が来ていました。どうやら Node.js 8 が非推奨になり2021年の3月中旬には全面的にサポートされなくなるとのことなので、Node.js 10 へ移行します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/292456/55bda261-ff67-2d9f-58d4-2c711d65b39c.png)


https://cloud.google.com/functions/docs/migrating/nodejs-runtimes?hl=ja


## 移行していく

まずは Node.js 10 にバージョンアップするので、Deploy・エミュレーションができるように最新の Firebase CLI をインストールします。

```
$ npm install -g firebase-tools@latest
```


次に `functions` > `package.json` で `engines` ブロックの **node**  ターゲットを 10 に変更します。

```json
"engines": {
  "node": "10"
}
```


ほとんどの場合 Node.js 8 と Node.js 10 ではコードが変更されることはありませんが、自動的にセットされる環境変数が変更されたみたいなので、詳しくは下記リンクを参照してください。

https://cloud.google.com/functions/docs/env-var#environment_variables_set_automatically



## テストしてみる

`firebase emulators:start` でエミュレートをスタートさせ、`View in Emulator UI` で表示されたローカルポートで  Emulator Suite を開きます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/292456/b6d35985-0396-5012-1e64-0e1816eb45e0.png)



emulator がインストールされていない場合は下記コマンドでインストールします。

```
$ npm install -g @google-cloud/functions-emulator
```


`http://localhost:5001/{project_name}/us-central1/{関数名}`のように HTTP関数でリクエストを実行すれば、ローカル環境でテストを行うことができるようになります。

https://firebase.google.com/docs/functions/get-started?hl=ja#emulate-execution-of-your-functions



テストが完了したので最後にデプロイします。

```
$ firebase deploy --only functions
```
【Firebase】Google認証情報 Firestore 保存

# 目標
**Firebase AuthenticationでGoogle認証後、認証情報をFirestoreに保存したい**

# 前提
- React環境
- Firebase Authentication、Firestore組込み済み
- FirebaseUIを利用した認証

# 処理
1.  Firebase Authenticationで認証
2.  FirebaseUIのcallbackを利用してFirestoreへ認証情報を保存

# 実装

```jsx:signin.jsx

import 'firebase/auth';
import '@firebase/firestore';
import firebase from 'firebase/app';
import MyApp from '../components/MyApp';
import React from 'react';
import StyledFirebaseAuth from 'react-firebaseui/StyledFirebaseAuth';


export default function SignIn() {
  const db = firebase.firestore();

  const uiConfig = {
    signInFlow: 'popup',
    signInSuccessUrl: '/mypage',
    signInOptions: [
      firebase.auth.GoogleAuthProvider.PROVIDER_ID,
    ],
    callbacks: {
      signInSuccessWithAuthResult: (authResult) => {
        const user = authResult.user;
        const isNewUser = authResult.additionalUserInfo.isNewUser;

        // 初回Google認証時のみDB保存
        if (isNewUser) {
          writeNameToDB(user);
        }

        return true;
      },
    },
  };

  // usersコレクションにuidをドキュメントIDとして、
  // displayName(Googleアカウント名)をnameフィールドに保存
  const writeNameToDB = async (user) => {
    db.collection('users').doc(user.uid).set({
      name: user.displayName,
    });

    // 3秒程待たないとDBに保存できない...
    await new Promise((resolve) => setTimeout(resolve, 3000));
  };

  return (
    <MyApp>
      {/* firebaseui-web-reactを使用(便利ラッパーありがてぇ〜) */}
      <StyledFirebaseAuth
        uiConfig={uiConfig}
        firebaseAuth={firebase.auth()}
      />
    </MyApp>
  );
}
```

# まとめ
- FirebaseUIのcallbackを利用すると簡単に認証情報をDB保存できる
- DB保存後、3秒程待機すると上手くDB保存ができた（ここ、もっと良い実装あるはず。。。


# 参考文献
- [【stackoverflow】 Add firebase users using social login to user database?](https://stackoverflow.com/questions/49662489/add-firebase-users-using-social-login-to-user-database)
- [【Github】 firebase/firebaseui-web](https://github.com/firebase/firebaseui-web)
- [【Github】 firebase/firebaseui-web-react](https://github.com/firebase/firebaseui-web-react)
- [【Firebase公式】 FirebaseUI でウェブアプリに簡単にログイン機能を追加する](https://firebase.google.com/docs/auth/web/firebaseui?hl=ja)
【Flutter】Flutterの複数バージョンを共存させる方法 (fvm の使い方)

## この記事で話すこと
FlutterのバージョンをStableやMasterなど複数共存させる際に数秒で切り替える方法をお伝えします。

## 背景
Flutter 1.2.0がリリースされて、アップデートしたが、あるプロジェクトで動作しないライブラリがあったため、
Flutter 'Stable'と'1.17.4'を同居させる必要がありました。

毎回アップグレード、ダウングレードを実施しているとその度に10分程度失うことになるので、何かないかと探していたところfvmというものがあるらしかったので、使用したらいい感じだったので紹介です。

## fvmとは
[fvm](https://github.com/leoafarias/fvm)

>Flutter のバージョン管理。Flutter SDK のバージョンを管理するためのシンプルな cli です。

>FVM は、プロジェクトごとに使用される Flutter SDK のバージョンを参照することで、一貫したアプリビルドの必要性をサポートします。また、複数の Flutter バージョンをインストールしておくことで、毎回 Flutter のインストールを待つことなく、アプリで今後リリースされる Flutter の検証やテストを迅速に行うことができます。

## 手順
1. Dartをインストールする
2. fvmをインストールする
3. fvmを使ってFlutterのバージョンを複数インストールする
4. IDEに設定する

## 1 Dartをインストールする
**Flutterにバンドルされているものではない素のDartを入れる必要**があります。

```text:Dartインストールコマンド
brew tap dart-lang/dart
brew install dart
```

pubのパスを通しましょう。

ルート直下の`.zshrc`や`.bash_profile`ファイルに以下を追記しましょう。
[Macのパスの通し方](https://qiita.com/k3ntar0/items/eb8cdbd8eba9da388def)

```
export PATH="$PATH":"$HOME/.pub-cache/bin"
```

## 2 fvmをインストールする
以下のコマンドでfvmをインストールします。

```text:fvmインストールコマンド
pub global activate fvm
```

## 3 複数バージョンのflutterをインストールする

```text:複数バージョンのflutterのインストールコマンド
fvm install stable
fvm install 1.17.4
```

以下のようにディレクトリにインストールされます。
`/Users/{username}/fvm/versions/1.17.4`

## 4 IDEに設定する

### Android Studio の場合
`Preferences -> Languages & Frameworks -> Flutter -> SDK`に上記のインストール先のパスを設定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261934/1ef1357e-088c-4c7c-1207-1a5100fa61e6.png)

### VScode の場合
`.vscode/settings.json`に以下を書き込みます。

```text:.vscode/settings.json
{
    "dart.flutterSdkPaths": [
        "fvm"
    ]
}
```

fvmのバージョンの切り替えを行います。

```
fvm use 1.17.4 //インストール済みのバージョン名又はチャンネル名
```

## その他: FVMのアップデート

```
brew install dart
```

```
brew upgrade dart
```

```
pub global activate fvm
```

上手くいかなければ（パスが通らなければ、、）↓↓こちらでも問題ないかと

```
dart pub global activate fvm
```

## 参考記事

- [fvmを使ってFlutter SDKのバージョンを切り替える](https://qiita.com/Kurusu_ima/items/2dfd067f6e79f520198f)
[Go言語]構造体の型入力で処理を分ける

# はじめに
go言語でintefaceを使えば、C言語などのポインタ渡しに似た処理を行うことができます。
そのやり方について、覚書の意味で記載します。
# ソースコード
本資料では、入力した構造体の型別で別の処理を行うように関数を作ってプログラムをします。
また、行列にした構造体で複数にわたって異なる構造体が入っていた時の処理別方法についても関数で作ってみます。

```golang:maing.go
package main

import (
	"fmt"
	"reflect"
)

type User struct {
	Name string
	Age  string
	Sex  string
}
type User2 struct {
	Name string
	Age  string
	Sex  string
}
type TextBord struct {
	Name string
	Text string
}
//個別処理
func Output(v interface{}) {
	switch reflect.TypeOf(v) {
	case reflect.TypeOf(User{}):
		fmt.Println("Userの型")
	case reflect.TypeOf(User2{}):
		fmt.Println("User2の型")
	case reflect.TypeOf(TextBord{}):
		fmt.Println("TextBordの型")
	default:
		fmt.Println("Other")
	}
}
//配列処理
func Outputs(v []interface{}) {
	for _, tmp := range v {
		Output(tmp)
	}
}

func main() {
	Output(User{})
	Output(User2{})
	Output(TextBord{})
	var tmp []interface{}
	tmp = append(tmp, int(0))
	tmp = append(tmp, User2{})
	tmp = append(tmp, User{})
	Outputs(tmp)
}
```

実行する以下の結果が得られます。

```bash:
Userの型
User2の型
TextBordの型
Other
User2の型
Userの型
```
django mariadbに接続時、mysqlclientがあるのにないと怒られる

起動時エラー

```
django.core.exceptions.ImproperlyConfigured: Error loading MySQLdb module.
Did you install mysqlclient?
```

バージョン

```
[root@hoge]# mysql --version
mysql  Ver 15.1 Distrib 10.5.5-MariaDB, for Linux (x86_64) using readline 5.1
```
これが全部いるっぽい
MariaDB-sharedをインストールすると、libmysqlclient.so
が入ってくるっぽい

```
yum list installed | grep mariadb
MariaDB-client.x86_64                   10.1.37-1.el7.centos           @mariadb 
MariaDB-common.x86_64                   10.1.37-1.el7.centos           @mariadb 
MariaDB-devel.x86_64                    10.1.37-1.el7.centos           @mariadb 
MariaDB-server.x86_64                   10.1.37-1.el7.centos           @mariadb 
MariaDB-shared.x86_64                   10.1.37-1.el7.centos           @mariadb 
galera.x86_64                           25.3.24-1.rhel7.el7.centos     @mariadb
```
GitLab上でCIでDockerイメージを作って別のCIに使う

似たような記事は複数見つけられたのですが、現状はもっと簡単なようなのでメモ。最大の罠は公式ドキュメントの探しにくさ。

# やること

GitLab上のCIでdocker buildして、GitLab上のDocker registryにdocker pushする。

更に作ったdocker imageを他のGitLabのプロジェクトでCIのランナーとして利用する。

同じプロジェクト内でイメージを作って使うこともできますが、ある程度汎用なイメージを作れるのであればプロジェクトは分けたほうが良さそうです。

自前でDockerイメージを作るのは、例えばマイコンの開発環境とかで必要な共通ライブラリ郡をコンパイル済みにしておいて、CIしたい側でCIにかかる時間を減らせるとかとかの理由で。

# イメージをつくるほう

## Dockerfile

これは普通に必要なように作ります。特別な設定などはありません。

## CIの設定

基本は[公式ドキュメント](https://docs.gitlab.com/ee/user/packages/container_registry/index.html#build-and-push-images-using-gitlab-cicd) のとおりです。

このドキュメントがCIの項目になくて、registryの項目にあるのが最大の罠だと思う。

ちなみに自分は公式ドキュメントからほんの少しだけ変えて下のような感じにしています。

```yaml
image: docker:19.03.12
services:
  - docker:19.03.12-dind

stages:
  - build
  - test
  - release

variables:
  IMAGE_NAME: "hoge"
  TEST_IMAGE: $IMAGE_NAME:mr-$CI_COMMIT_SHORT_SHA
  RELEASE_IMAGE: $IMAGE_NAME:latest

before_script:
  - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY

build:
  stage: build
  script:
    - docker build -t $CI_REGISTRY_IMAGE/$TEST_IMAGE .
    - docker push $CI_REGISTRY_IMAGE/$TEST_IMAGE
  only:
    refs:
      - merge_requests

run-test:
  stage: test
  script:
    - docker pull $CI_REGISTRY_IMAGE/$TEST_IMAGE
    - docker run --rm -w /work -v $PWD:/work $CI_REGISTRY_IMAGE/$TEST_IMAGE /work/runtest.sh
  only:
    refs:
      - merge_requests

release-image:
  stage: release
  script:
    - docker pull $CI_REGISTRY_IMAGE/$TEST_IMAGE
    - docker tag $CI_REGISTRY_IMAGE/$TEST_IMAGE $CI_REGISTRY_IMAGE/$RELEASE_IMAGE
    - docker push $CI_REGISTRY_IMAGE/$RELEASE_IMAGE
  only:
    - master

```

主な変更点は、

- ビルドをマージリクエストに関係するイベントでしか行わないようにしたこと
- イメージのタグにコミットハッシュをつけることで、マージリクエスト上でイメージが残るようにしたこと
- プロジェクト名≠イメージ名にしたかった(ここではhogeになってる)

という点です。

自前開発をしているとしても、masterは健全に保ちたく作業の見通しを良くするのに変更は必ずマージリクエストで行いたいので、マージリクエストでイメージを作り、masterにマージされたらタグを付け直してlatestしてregistryに登録しています。

こんな感じの設定ファイルをおいて、マージリクエストを作ってそこにDockerfileをpushすればpipelineが走り、成功すればイメージが作られ、Container Registryに登録されているはずです。

次の段階に移る前にまずは、自分のローカル環境にDocker pullしてみてちゃんと目的のイメージが作れているか確認してみると良いでしょう。

ローカルにpullするのは[公式ドキュメントのこのあたり](https://docs.gitlab.com/ee/user/packages/container_registry/#use-images-from-gitlab-container-registry)を見ればできる。

注意するのはイメージ名で、 ```registry.gitlab.com/group/project/image:tag``` となります。```group``` は、プロジェクトのグループ名(ユーザ名)、```project``` は各プロジェクト名、```image``` は上のyamlでいうところの ```hoge``` になる。プロジェクトがサブグループ以下にあるなら当然 ```group``` と ```project``` の間に含めます。

Container Registry上に表示されているCLI Commandsからコピペしたものは、上記でいうところの ```project``` までしか含まれていないため、上で例示したyamlみたいに独自にイメージ名を設定している場合は、自分で ```image``` を追加しなくてはいけないです。

# イメージを使うほう

使う方は特に難しくないです。[公式ドキュメントのとおり](https://docs.gitlab.com/ee/ci/docker/using_docker_images.html#extended-docker-configuration-options)です。

```.gitlab-ci.yml``` で利用するイメージ名を上記で作ったものにするだけです。具体的には、yamlファイルに

```yaml
image: "registry.gitlab.com/group/project/image:tag"
```

で利用するイメージ名を指定します。

同じグループ内であれば、それぞれプライベートリポジトリであっても内部でトークンを利用してくれるため、特に設定は必要なく利用できます。
REAPERをProToolsライクの操作にカスタマイズするメモ

# REAPERをProToolsライクの操作にカスタマイズするメモ

## こんな人向け
・ReaperをProToolsライクに操作したい！
・Reaperショートカットってどうカスタマイズするの？

## カスタマイズ方法
1.メニューバー＞アクション(A)＞アクションリストを開く(A)…　でアクションリストを開きます。
2.任意のアクションを選択して「追加」ボタンを選択、割り当てたいショートカットキーを押下すれば設定完了です。
![キャプチャ.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/692194/52d9a915-3f9b-9ea8-77c8-8e2c4d6d0a2d.jpeg)
## ProToolsライクな カスタマイズサンプル
| カテゴリ | 割当キー | Reaperアクション名 |
|:-----------:|:------------:|:------------|
| 表示| MouseWheel| 表示：垂直スクロール（マウスホイール/相対的MIDI CC）|
| 表示| R| 表示：水平ズームアウト|
| 表示| T| 表示：水平ズームイン|
|マーカー| Enter| マーカー：現在位置でマーカーを挿入/編集|
| トラック|Shift + R | トラック：選択トラックを録音待機（切替）|
| トラック| Shift + S| トラック：トラックをソロ（切替）|
| トラック| Shift + M| トラック：トラックをミュート（切替）|
手っ取り早く使いたい場合は、.ReaperKeyMapをアップしましたのでインポートして使ってみてください。
https://drive.google.com/file/d/1o23HibzaGRk8IGMCZmmqEoLiTdke20h0/view?usp=sharing
~~ProToolsはしばらく(7,8年)触っていないので、ショートカットキーの間違いがあるかもしれません。~~

## おわりに
とりあえず基本操作だけカスタマイズしましたが、慣れるまでひとつひとつの操作に手間取りますね、、
ゆくゆくはスクリプト系の記事も書いていこうと思いますー。

***
>その他メモ
ミキサーのドッキング解除 ：ミキサーを右クリック＞Dキー
ミキサーの表示／非表示：Ctrl + Mキー
トラックの拡大／縮小　：Ctrl + Shift + ↑ or ↓キー
iOS13でUILabelからSystem fontを取得するとTimes New Romanとして表示される

## 事象
iOS13でNSAttributedStringでフォントを装飾してUILabelにセットする際にフォントがSystem FontからTimes New Romanにレンダリングされ、結局何をすればいいのか困ったので記事にしました。(iOS13未満は期待動作です)

具体的には以下のようなコードです。
動作としてはHTMLのテキストをNSAttributedStringで加工し、`fontName`, `fontSize`自体は、labelに設定されているプロパティから取得しようとしています。

```swift
label.setHTMLFromString(htmlText: "<span>純粋はちみつ<br></span><span style=\"font-size : small\">風味豊かな純粋はちみつです。</span>"

extension UILabel {
    func setHTMLFromString(htmlText: String) {
        let modifiedFont = String(format:"<span style=\"font-family: '\(self.font.fontName)'; font-size: \(self.font.pointSize)\">%@</span>", htmlText)
        guard let data = modifiedFont.data(using: .unicode, allowLossyConversion: true) else { return }
        do {
            let attrStr = try NSAttributedString(
                data: data,
                options: [.documentType: NSAttributedString.DocumentType.html, .characterEncoding:String.Encoding.utf8.rawValue],
                documentAttributes: nil)
            self.attributedText = attrStr
        } catch {
            print("error: ", error)
        }
    }
}
```


### Times New Romanになるとこんなに変わります。

|           System Font          |          Times New Roman          |
|:------------------------:|:------------------------:|
| <img width="380" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276894/c19bbac3-4eef-2102-7404-24723f50c4df.png"> | <img width="380" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276894/b6889004-2848-8fe5-d561-2f43a6a9f090.png"> |

画面内の他のラベルとフォントが一致していないととても違和感があります🙃

## 原因
なぜか`self.font.fontName`で取得しているフォントがiOS12とiOS13では異なり、systemFontとして認識されていないのが原因？

|           iOS12          |          iOS13          |
|:------------------------:|:------------------------:|
| <img width="380" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276894/1a90a3c0-424a-3c18-3a0b-4d261c3356f2.png"> | <img width="380" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276894/afc7cc3b-dc30-60d0-6e6e-e4b098a9d9ca.png"> |

`.SFUI-Regular`がsystemFontのFamily Nameとして認識しない？？😫

## 結論

#### 解決策1
フォントを上書きする。全体が上書きされる。少し強引。

```swift
label.font = UIFont.systemFont(ofSize: 17)
```

#### 解決策2
formatに `'-apple-system'`を加える。

```
   let modifiedFont = String(format:"<span style=\"font-family: '-apple-system', '\(self.font.fontName)'; font-size: \(self.font.pointSize)\">%@</span>", htmlText)
```

`font-family:`のあとに`'-apple-system',`を追加することによって、`.SFUI-Regular`が無事に`system Font`として認識されました☘️

今回の場合、HTMLの一部の部分を`太字`にしたかったので、2番目の方法で対応しました。

Appleのバグ？かもしれないので今後も動向を追っていきたいと思います。

少しでも参考になれば幸いです😌

## 参考
- [rdar://6153065: System font renders as Times New Roman in certain contexts](https://openradar.appspot.com/6153065)
- [xcode - System font renders as Times New Roman on iOS 13 - Stack Overflow](https://stackoverflow.com/questions/58236483/system-font-renders-as-times-new-roman-on-ios-13)
csvファイルの文字コードをUTF-8で保存するやり方

# 経緯
エクセルで保存したcsvファイルを使ってphpで出力処理をする際に、文字化けが起きました。
原因がcsvファイル自体の文字コードが(エクセルで保存していたことが原因で）Shift_JISという文字コードになっているためでした。
対応策として、csvファイル保存する時点でUTF-8で保存する方法をこちらの記事で紹介致します。

# まずエクセルファイルをcsvへ変換
保存時点でcsv拡張子を選択して保存します
例として地方区分のファイルを使います。
![スクリーンショット 2020-08-15 0.04.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/574173/f5b24354-e39b-e345-c8ac-255b8269fc08.png)




# テキストエディタをダウンロード
文字コードを指定して保存できるものであれば問題ないです。
私は以下のリンクの「mi」というテキストエディタを使用しました。
[macOS]
https://www.mimikaki.net/
[windowsOS]
https://www.mimikaki.net/download/alpha.html

# 文字コードを選択できるテキストエディタを開く
csvファイルを開き、文字コードを「UTF-8」に選択し、保存します。
![スクリーンショット 2020-08-15 0.09.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/574173/b8c01c32-12de-ed89-afab-9e56f9aa205d.png)
これで完了です。
こちらで保存したcsvファイルを使うことで文字化けすることがなくなりました。

# まとめ
文字化けするのは文字コードが違うために起きます。UTF-8という文字コードはもっとも多くの言語に対応しています。
普段あまり意識してない部分でしたので、気をつけていきたいと思います。
Windows ServerとフリーのLinuxと商用Linuxの比較

サーバーOSである「Windowsサーバー」、「フリーのLinux」、「商用Linux」の３つを比較してみた。

|             | Windows Server | 商用Linux | フリーのLinux|
|:-----------:|:------------:|:------------:|:------------:|
| 初期費用       | ×        | △               |           〇        |
| 運用の手間     | 〇         | △               |              ×  |
| ネットでの情報の探しやすさ |  △   | △             |            〇     |

#初期費用について

- Windows ServerはOSのライセンス料に加えて、クライアントまたはユーザー数分のCAL(**C**lient **A**ccess **L**icenseの略で、クライアントからWindows Serverの利用を許可するためのライセンスのこと)の費用が重くのしかかってしまう。

- 商用Linuxは、サーバーライセンスの料金が必要とはいえ、年間サポートの保守料金を加えてもWindowsほどではないことが多い。

- フリーのLinuxは、初期投資は必要なく自分の力で始められることが魅力である。

#運用の手間について

- 初期費用とほぼ反比例する。

- Windows Serverは使い慣れたWindowsベースで作業できるので、運用が比較的簡単であることが多い。

- 商用Linuxは有償サポートの契約をしていれば、運用にそれほど困ることはない。

- フリーのLinuxは自己責任で利用するOSなので、基本的には何が起きても自力で解決することが求められる。運用にはそれなりの手間やコストがかかる。

#ネットでの情報の探しやすさについて

- Windows ServerはMSDNやTech NETというドキュメントライブラリを参照できるので、フリーのLinuxほどではないが、それなりの情報量を確保できる。

- 商用Linuxは、OSの提供元であるディストリビューターの情報がそれほど多くないので、フリーのLinuxユーザーの知見もある程度参考になることから、Windows Serverと同じ程度という評価である。

- フリーのLinuxが強みを発揮する。無償で利用できるので様々なユーザーが活用しており、それぞれの知見を簡単に探し出せるというメリットがある。
ゼロからVSCode+WSL+Java+Gradle環境を構築する

# WindowsにJDKをインストールする
- JDKがインストール済みかコマンドラインから確認する

```
C:\Users\ユーザ名> javac -version
javac 11.0.7
```

- JDKがインストールされていない場合、インストーラーでインストールする

https://adoptopenjdk.net/
「OpenJDK 11 (LTS)」「HotSpot」
※インストール時に環境変数「JAVA_HOME」を設定するようにチェックを入れる

- 環境変数「JAVA_HOME」が設定されているか確認する

```
C:\Users\ユーザ名>echo %JAVA_HOME%
C:\Program Files\AdoptOpenJDK\jdk-11.0.7.10-hotspot
```
空欄が出力された場合は、環境変数「JAVA_HOME」を設定する

# WindowsにVSCodeインストール
- インストーラー
https://azure.microsoft.com/ja-jp/products/visual-studio-code/

# VSCodeでJavaを扱えるように拡張機能をインストールする

| 拡張機能名 | コード |
|:-----------|:------------|
|Java Extension Pack|vscjava.vscode-java-pack|
|Lombok Annotations Support for VS Code|gabrielbb.vscode-lombok|
|Gradle Extension Pack|richardwillis.vscode-gradle-extension-pack|
|Markdown All in One|yzhang.markdown-all-in-one|
|Remote - WSL|ms-vscode-remote.remote-wsl|

# WindowsにWSLをインストール
- 参考記事
https://qiita.com/oyngtmhr/items/a098e2da50bc7b58d75a

# WSL上でJavaを使えるようにする
- 参考記事
https://qiita.com/sakamoto66/items/bf49584fa9f56a9fb808

# WSL上でGradleを使えるようにする
- 参考記事
https://qiita.com/fedorax/items/40052e150865267d1fa0

# VSCode経由のWSL上で開発するため、WSLにVSCodeの拡張機能をインストールする
1. VSCodeの左下の「><」からWSLを開く
![run-wsl.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482013/0d5e1184-3bb0-6209-63be-563c3f8aec47.png)
2. VSCode画面端のツールバーから拡張機能のアイコンを選ぶ
3. もっている拡張機能すべてWSLにインストールする
![vscode-java.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482013/69dbba3f-d372-5474-615c-ad4c28146a9a.png)