OmniAICreator/Qiita-1.07M huggingface dataset:
AuroraServerlessを使うアーキテクチャ

AuroraServerlessを使う機会があったのでその過程で学んだことをメモ。

# AuroraServerlessの良さ

* サーバレス
* AutoScaling
* コスト削減
* Lambdaとの相性

まずサーバレスが助かる。
通常のEC2にDBを構築したりRDSを使ったりする場合、定期的にサーバの証明書更新が必要となる。後々の運用を考えると出来るだけ手離れはよくしたいし、メンテナンスの都度サービスを止めるということもしたくない。

次にAutoScaling
AuroraServerlessではDBの処理とストレージが分離されている。急激にアクセスが増加し処理が多くなった場合には勝手にスケーリングしてくれる。
そしてピークがすぎるとスケールインして最後は処理部分を完全に畳むことができる。(0にするかは設定次第で調整可能）

3つ目、コスト削減。
AutoScalingにより処理部分はリクエストが来ない間は完全に眠らせることが可能だ。つまりこの間にかかるコストはストレージ分のみ。
DBのアクセスが予め見積れる場合には通常のDBを使ったケースと比較すると安く利用できるメリットを受けることができる。

最後にLamdbaとの相性。最近はRDSプロキシなどが使えるようになり大丈夫なのかもしれないが、コネクションプーリング等の問題でRDSとLambdaは相性が悪いと言われていた。

# API Gatewayからの初回アクセスには注意が必要

DataAPIを介してSQL文を送り込む方法をとるとなると、API GAteway → Lambda → AuroraServerless構成が簡単にできる。→[以前の記事](https://qiita.com/Kept1994/items/157524e27e7742954f57)

ただしここには注意が必要。API Gatewayは最大でも29秒しか待てないのだ。

上記の通り、AuroraServerlessはリクエストに応じてスケーリングし、誰もリクエストしない時には完全に眠っていることになる。
この状態でアクセス（初回アクセス）するとサーバを起動するところから始めるのでまあまあ時間がかかる。10秒とかもう少しくらいはかかっているんじゃなかろうか。

APIを介して複数のデータ書き込みや時間のかかる処理を行おうとする場合、初回アクセス時にはタイムアウトするリスクが伴う。
また厄介なのはAPIは29秒で504を返のに、DBからレスポンスが来ると内部の処理はそのまま続行するクライアント側はもう一回実行しようとする。冪等性のない処理だったりすると危険。

# マイクロサービス化と疎結合の重要性に気づく

簡単な解決策としてはAuroraServerlessをどんなにアクセスがなくても最小のスケールで稼働させて寝かさないようにすること。
でもサーバレスの良さが損なわれてしまう。24時間付けっ放しなら普通のDBの方が安いじゃんってなる。

API GatewayとAuroraServerlessは合わせられないのか・・？

違う。今回の問題は内部の処理は続行しているのにAPI Gatewayがタイムアウトしてしまうからクライアント側の認識とバックエンドの処理にズレが生じることが問題。
なので、一度リクエストという形で受け取ったらその時点でAPIに返事をすることで解決される。(もちろん仕様や要件にもよると思う)

たどり着いた答えとしてはAPI Gateway → Lambda → SQS → Lambda → AuroraServerless

APIではリクエストを受けた時点でキューに積み202 Acceptedを返そう。SQSではエンキューをトリガーにしてこれまでのLambdaを呼んであげる。
こうすることで29秒が限度だった一連の処理をLambdaの上限値15minまで伸ばすことができる。

SQSで一旦受け止めるのはAPI GatewayとStepFunctionsを繋ぐ時にも有用なのではなかろうか？

# SQSにDLQは必須

SQSを使うからにはDLQの設定を確実にした方がいい。
なぜか？SQSでは処理中のメッセージは見ることができない（処理中のメッセージとなる）。

仮にSQSのLambdaトリガーで呼ばれたLambdaの内部で処理にコケた場合、通知等をして問題がわかってもそのメッセージをピンポイントにキューから取り出すのが困難になる。（再処理ポリシーを指定しないとSQS→Lambdaを無限に繰り返しうる。）

また、Lambdaトリガーで呼ばれるLambdaがタイムアウトした場合も同じで可視性タイムアウトを抜けると即座にリトライがかかるためそのメッセージを取り出してあげることができなくなる。

# DataAPIの返り値の整形

DataAPIの返り値は少し使いにくいので整形した方がいい。→[以前の記事](https://qiita.com/Kept1994/items/7422bdf38149e8248bb1)

# アーキテクチャ

この辺りがベストプラクティスになるのかな。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406130/1931b543-47d3-e293-9a6f-00d49ba84548.png)
rails×Docker導入でのエラー③「PG::ConnectionBad: fe_sendauth: no password supplied」


これは単純に、設定しているパスワードと
環境変数で指定したパスワードが一致していないからでした。

```:docker-compose.yml
  db:
    image: postgres
    ports: 
        - "5432"
    environment:
      - POSTGRES_DB=postgres
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=postgres
    volumes:
      - ./tmp/db:/var/lib/postgresql/data
```

```:database.yml
default: &default
  adapter: postgresql
  encoding: unicode
  host: db
  username: postgres
  password: postgres
  pool: 5

development:
  <<: *default
  database: myapp_development

test:
  <<: *default
  database: myapp_test
```

下記の部分ですね！

```:docker-compose.yml
      - POSTGRES_PASSWORD=postgres
```

```:database.yml
  password: postgres
```


以上！
Oracle Cloud Infrastructure Compute コンソール接続  (Windows)

#はじめに
Cloud上のインスタンスへの接続はSSHやRDPを使うのは一般的ですが、誤動作によってインスタンスに正常に接続ができなくなる場合あります。その場合、コンソール接続を使ってトラブルシューティングできます。
Oracle Cloud のWindowsインスタンスへのコンソール接続 を試してみました。

#準備
plink.exe
VNC クライアント（例：VNC Viewer）
SSH鍵ペア (秘密鍵はPuTTY形式）

#手順
##1　コンソール接続作成
###1.1　コンソール接続作成をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123679/045dd2f2-e338-00a8-75ad-b26dba53e2fc.png)

###1.2　SSH公開キーを選択、【コンソール接続の作成】をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123679/26bc968b-8cc3-8404-0c2d-5ec6c2ae9832.png)

###1.3　ステータスはアクティブになったら作成完了
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123679/edc2763f-6af0-ec4f-edd4-0b46247fcd8b.png)

##2　VNC接続
###2.1 【WindowsのVNC接続のコピー】をクリック、Powershellのコマンドをコピー
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123679/cd09c3ee-1c19-ea89-8fb3-b6fbbc6a8330.png)

###2.2　Powershellコマンド修正
コピーしたコマンドのppkファイルのパスを環境に合わせて修正（二箇所）
`$env:homedrive$env:homepath\oci\console.ppk`
↓
`秘密鍵ppkファイルのフルパス　例：D:\temp\id_rsa_p.ppk`

###2.3　Powershellで実行
plink.exeのフルパスをpathに追加(例：D:\tools)

```
$Env:Path+= ";D:\tools"
```

前のステップで修正したPowershellコマンドを実行

```
Start-Job { Echo N | plink.exe -i D:\temp\id_rsa_p.ppk -N -ssh -P 443 -l ocid1.instanceconsoleconne
n.oc1.iad.anuwcljsuvrz6sqc4s7spghqfsbud2gy25fo7mtqrl6bqgvi************ -L 5905:ocid1.instance.oc1.iad.anuwcljsuvrz6s
vph2ypqjindbaxxiuvg4lb3jr6l4yp************:5905 instance-console.us-ashburn-1.oraclecloud.com }; sleep 5; plink.exe
:\temp\id_rsa_p.ppk -N -L 5900:localhost:5900 -P 5905 localhost -l ocid1.instance.oc1.iad.anuwcljsuvrz6sqcjcvph2ypq
baxxiuvg4lb3jr6l4yp************
```
結果にエラーがなければ、接続が確立されている

```
Id     Name            PSJobTypeName   State         HasMoreData     Location             Command
--     ----            -------------   -----         -----------     --------             -------
4      Job4            BackgroundJob   Running       True            localhost             Echo N | plink.exe -i...
The server's host key is not cached in the registry. You
have no guarantee that the server is the computer you
think it is.
The server's rsa2 key fingerprint is:
ssh-rsa 4096 5e:95:c4:a7:52:06:1c:56:39:**:**:**:1a:b0:2a:f9
If you trust this host, enter "y" to add the key to
PuTTY's cache and carry on connecting.
If you want to carry on connecting just once, without
adding the key to the cache, enter "n".
If you do not trust this host, press Return to abandon the
connection.
Store key in cache? (y/n) y
Using username "ocid1.instance.oc1.iad.anuwcljsuvrz6sqcjcvph2ypqjindbaxxiuvg4lb3jr6l4yp************".
Access granted. Press Return to begin session.
```


###2.4　VNC クライアント使って接続
VNCクライアントを使って、ホスト：localhost、ポート：5900に接続

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123679/173a66e4-99ec-07ad-822c-05a32ae9e67e.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123679/edbadcbf-59d2-a65c-441b-bd231031cb39.png)

#参考資料
https://docs.oracle.com/cd/E97706_01/Content/Compute/References/serialconsole.htm
Emacsをcmdからバックグラウンドジョブとして起動するまで

#はじめに
Qiita初投稿となります。
ブログ投稿にも慣れていないので期待せず閲覧していただけると幸いです。

LINUXで使用するテキストエディタがEmacsでWindowsでも同じ使用感にできないかと思い、いろいろと試していました。
PCを変えた時にまた調べなおしたりするのも面倒だからメモ的な形で書いていこうかなというところです。

###参考記事
[Emacsをwindows10にインストールする。](https://qiita.com/imull23/items/8f228e7f91e91b71c8d0)
[Windows版Emacsに環境変数「Path」を設定してコマンドで実行できるようにする。](http://xn--u9j207iixgbigp2p.xn--tckwe/archives/5628)

#目次
1. Emacsのダウンロード＆インストール
2. PATHの設定
3. バックグラウンドジョブでの起動


#1.Emacsのダウンロード＆インストール
まずはEmacsをダウンロードしないと何も始まりません。
[こちら](http://ftp.gnu.org/gnu/emacs/windows/)からEmacsをダウンロードしましょう。
![emacs1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/649758/227f93dc-1b18-fe98-e8b6-f7a9027a5604.png)
emacs-26/をクリックしてください。紫色になっているところです。

![2020-06-13 (5).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/649758/0cd67ca1-f70f-6eb3-f552-d6c26a7185e9.png)
バージョンはお好みでダウンロードしましょう。
今回は「emacs-26.3-x86 64.zip」をダウンロードします。

![2020-06-13 (7).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/649758/8a47bde2-0281-6e91-ca29-c793cb5917a0.png)

ダウンロードしたzipファイルを展開してください。
展開場所はお好みで大丈夫ですがパスは後で必要になります。
これでインストール完了です。

#2.PATHの設定
次にEmacsをcmdからコマンドで開くための設定をします。
環境変数を設定していきましょう。

![2020-06-13 (14).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/649758/2e7a828b-8dde-02e6-b07d-64d1ec1a10bd.png)

設定から「環境変数を編集」を開いてください。

![2020-06-13 (16).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/649758/c0e3fd80-e22a-0adb-0294-61466bd96883.png)

Pathを選択し編集ボタンをクリック。

![2020-06-13 (18).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/649758/20ad44bd-25e1-1e0f-7523-e2602d410546.png)

新規をクッリクしてPathを追加します。
今回の場合は「C:\Program Files (x86)\emacs\bin」です。
emacsの保存場所に合わせて変更してください。

ついでにHOMEも設定しておきましょう。
これを設定することによって.emacs.dの場所を設定できます。
init.elで自分好みのEmacsを使いたい人は設定してください。

![2020-06-13 (20).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/649758/d79d7d8f-d6fd-93c6-6721-b960a25276ab.png)

先ほどの環境変数の設定画面で新規をクリックして画像のように設定してください。一応モザイクをかけてありますが、変数値のところには「C:\Users\ユーザ名」に設定しています。
この値も自由ですが、ほかの値にするとcmdを起動したときの初期ディレクトリが変更されてしまう可能性があるので注意。
入力出来たらOKボタンで環境変数設定画面を閉じて、PCを再起動してください。

![2020-06-13 (22).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/649758/f0bb53b3-7833-18ff-b806-5ba182baf59e.png)

cmdからemacsが起動できました。やったぜ！
起動したら初期ディレクトリに.emacs.dが生成されるので、皆様のこだわりのinit.elを入れてあげてください。
これでPathの設定は完了です。

#3.バックグラウンドジョブでの起動
これでemacsコマンドで起動できるようになったわけですが、LINUXではないので「emacs &」と入力してもバックグラウンドジョブで起動はできません。(startコマンドというものがあるらしいですが起動のたびにそんなもの入力するのめんどくさいわ)
これを解決していきましょう。

「emacs\bin」に「ema.cmd」という名前のファイルを作成してください。(.cmdなら名前は問いませんがcodeなどにするとVScodeとケンカすると思います。どうなるかは知りません。)

「ema.cmd」には以下を記述してください。

```
@echo off
setlocal
set EMACS_DEV=
set ELECTRON_RUN_AS_NODE=1
"%~dp0\runemacs.exe" %*
endlocal
```

これを保存すると、、、


![2020-06-13 (25).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/649758/27c921a8-ee70-723f-3a60-151851394b82.png)

emaコマンドでバックグラウンドジョブでの起動ができました。
init.elが編集されているのは気にしないでください。
これで完了です。

#おわりに
これでLINUXで使用していた時と同じようにEmacsを使えるようになりました。そういえばCUIならバックグラウンドジョブとか関係なく「emacs -nw」で起動できます。

何かご意見、改善点などあれば報告ください。
今回の記事がEmacs使いのお役に立てれば幸いです。
rails×Docker導入でのエラー②「django.db.utils.OperationalError: could not translate host name "db" to address: Name or service not known」


##エラー発生

rails newに成功し、各ファイルが増えたものの
下記のエラーが出てしまった。

<img width="653" alt="Docker-error01.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/635167/3d22ccb9-92b3-7315-7e97-28dce81fd123.png">

exited with code 1　はただアプリケーションエラーという意味らしい。

幸いにも、railsの起動は出来ていたので
そちらの方にヒントとなるエラー文が。

「django.db.utils.OperationalError: could not translate host name "db" to address: Name or service not known」


##解決策

環境変数を加えたら、解決しました。


###修正前
```:docker-compose.yml
  db:
    image: postgres
    volumes:
      - ./tmp/db:/var/lib/postgresql/data
```

###修正後
```:docker-compose.yml
  db:
    image: postgres
    ports: 
        - "5432"
    environment:
      - POSTGRES_DB=postgres
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=postgres
    volumes:
      - ./tmp/db:/var/lib/postgresql/data
```

パスワードなどの受け渡しがうまくいっていなかった？
ようで、しっかりと情報を明記したら通るようになりました！

以上。
react-routerを使ったルーティングをherokuで動かすために必要なこと

# 困ったこと
react-routerを使うことで、フロント側では1枚のhtmlファイルでルーティングをすることができます。
ただ、ローカル環境では問題なく動いたのですが、herokuにデプロイするとそのパスに応じたファイルを探してしまうようで動かず、少し嵌ってしまったので、記事にします。
# 解決方法
## heroku-buildpack-staticを導入
static.jsonが怪しいということはぐぐるとすぐに出てきたのですが、それを使うにはheroku-buildpack-staticを導入する必要があるということに気づくのに時間がかかってしまいました。

```
heroku buildpacks:set heroku/nodejs
heroku buildpacks:add https://github.com/heroku/heroku-buildpack-static.git
```

## static.jsonを追加
heroku-buildpack-staticを導入した上で、package.jsonと同じ階層にstatic.jsonを追加すれば、herokuでもしっかりとルーティングされるようになります。

```static.json
{
  "root": "public/",
  "clean_urls": false,
  "routes": {
    "/**": "index.html"
  }
}
```
# 参考
[Deploying to Heroku](https://www.gatsbyjs.org/docs/deploying-to-heroku/)
[React Routing works in local machine but not Heroku](https://stackoverflow.com/questions/41772411/react-routing-works-in-local-machine-but-not-heroku)
【AWS】EC2インスタンスでのBash設定をミスして、再起動しても実施されない件

#EC2インスタンスでのBashの設定のミスで、再起動しても実施されない
EC2の高度な設定でBashを用いる設定を行った。その際バケットの情報を取ってくる設定をしたのだが、そのバケット名を誤って指定していた。インスタンスを作成後に、アクション内にあるインスタンスの設定のユーザーデータの表示/変更で、高度な設定に書いていたバケット名を正しいものに変更したが、インスタンスを再起動しても実施されなかった。

#そもそもどうやってbashによる設定を行うのか？
[bashでEC2のインスタンスを設定する](https://qiita.com/roku28632/items/c0aa6991e7c36097f194)
詳しくは上記記事、参照。

#解決策
そもそもの原因としてBashスクリプトは、インスタンス作成時にしか起動されない。その後のインスタンスの再起動時には適用されないため、実行されずエラーとなる。解決策としてはまた新しくインスタンスを作り直すか、コマンドラインで実行すると上手くいく。
Windows Terminal (v1.0) で起動時に指定したタブ、ペインを開く方法

現在Windows Terminalは起動時に1つのプロファイルしか開くことができません。

v2.0までには起動時に複数タブ表示や、前回セッションの復元などの実装が予定されている[^1]ようですが、今できる代替方法を紹介します。

## 手順1. 任意コマンドライン引数を作成

ドキュメントはこちら: [Windows ターミナルのコマンド ライン引数 | Microsoft Docs](https://docs.microsoft.com/ja-jp/windows/terminal/command-line-arguments?tabs=windows)

これに関してはドキュメントに書いてあるので、くわしくは説明しませんが例を上げておきます。
このあとの作業のためにコマンドプロンプト向けに記述します。

```
wt wsl.exe ; split-pane -V wsl.exe ; new-tab -p "Windows PowerShell" ; split-pane -H -p "Windows PowerShell"
```

コマンドプロンプトで実行すると、1つ目のタブにはwslが左右に1つずつ、2つ目のタブにPowerShellが上下に1つずつ表示されます。

## 手順2. バッチファイル(*.bat)を作成

バッチファイルを作成し、`start`に続けて先ほどのコードを貼り付けます。

```
@echo off
start wt wsl.exe ; split-pane -V wsl.exe ; new-tab -p "Windows PowerShell" ; split-pane -H -p "Windows PowerShell"
```

保存したバッチファイルをクリックすると、Windows Terminalが設定どおりに開きます。

**解説**
`start`をつけずともターミナルは開きますが、コマンドプロンプトがターミナルの終了を待ってしまい、コマンドプロンプトが開いたままになります。 `start`をつけて実行することで、コマンドプロンプト自体はすぐに終了させています。


## 手順3. ショートカットを作成

手順2.まででやりたいことは実現できていますが、作成したバッチファイルのショートカットを作成すると
スタートバーやタスクバーにピン留めすることができるようなり、より使い勝手がよくなります。

またアイコンの変更もできるようになるため [terminal.ico](https://raw.githubusercontent.com/microsoft/terminal/v1.0.1401.0/res/terminal.ico) をダウンロードして設定するとそれっぽくなるのでおすすめです。



[^1]: Windows Terminal v2.0のロードマップ https://github.com/microsoft/terminal/blob/master/doc/terminal-v2-roadmap.md
Privateメソッドについて

# Privateメソッドとは
> [プロを目指す人のためのRuby入門]　著：伊藤淳一
>> 「クラスの外からは呼び出せず、クラスの内部でのみ使えるメソッド」だと言えます。

private配下にメソッドを記述すると、そのメソッドはPrivateMethodになり、そのクラス内からしか呼び出すことができなくなります。
つまり、
`他クラスから呼び出すことができなくなるので、予期せぬ結果を防ぐことができる`というイメージです。

(例)

```ruby
class Fuga
    def call_private_method
        # privateメソッドはクラス内から呼び出すことができる。
        private_hoge
        # => "呼び出せました！"
        #privateメソッドを呼び出す
        #(private_fugaメソッドは、privateのprivate_hogeメソッドを呼び出す。)
        private_fuga
        # => "呼び出せました！"        
    end
    private
    def private_hoge
      puts("呼び出せました！")
    end
    def private_fuga
      #privateメソッドからprivateメソッドを呼び出すことができます。
      private_hoge
    end
end
fuga = Fuga.new
fuga.call_private_method
# => "呼び出せました！"
# => "呼び出せました！"

#クラス外からprivateメソッドは呼び出せない
#(レシーバをつけて呼び出すことはできない)
fuga.private_fuga
# =>sample.rb:33:in `<main>': private method `private_fuga' called for <Fuga:0x0000000198a318> (NoMethodError)
# =>Did you mean?  private_methods
```

## privateメソッドは継承先から呼び出せる
privateメソッドはクラス外から呼び出せないと述べましたが、継承先のクラス内からは呼び出すことができます。

```ruby
class FugaBase
  private
  def private_hoge
    puts("呼び出せました！")
  end
end
class Fuga < FugaBase
  def hoge
    private_hoge
  end
end
Fuga.new.hoge
# => "呼び出せました！"
```

## まとめ
private配下にメソッドを記述すると、他クラスから呼び出すことができなくなるので、予期せぬ結果を防ぐことができる
githubのアカウント名とユーザー名を変更した時の設定変更

この度githubのアカウント名とユーザー名を変更したのでローカルの設定も合わせて変更する
修正前`rantaro`
修正後`GenkiMatsubara`

## 今回変更するもの
1.ユーザー名
2.ssh設定

## ユーザー名の変更

### まずは現在のユーザー名を確認する
ユーザー名確認するコマンドはこちら
`git config user.name`

メールアドレスの確認はこちらですが今回は変更していないので特に使用しない。
`git config user.email`

今回だと以前まで使用していた名前が出てきました。
`rantaro`

### こちらのユーザー名の設定を変更する
リポジトリ単位での修正ならこちら
`git config user.name "ユーザー名"`

グローバルで変更しても問題なければこちら
`git config --global user.name "ユーザー名"`

上記を実行後に`git config user.name`で確認すると変更できました。
`genki.matsubara`

## ssh設定の変更
アカウント名とユーザー名を変更しているのでssh-keyの設定を行わないとプッシュできない

```
remote: Invalid username or password.
```

***.ssh***を確認すると

`RantaroTech-GitHub`
`RantaroTech-GitHub.pub`



ssh-keyが古いままだったのでこちらを作り直します。

### ssh-keyを作りなおす
再設定についてはこちらの記事を参考に進めます。
https://qiita.com/shizuma/items/2b2f873a0034839e47ce

鍵の作り直しを行う
`ssh-keygen -t rsa`

鍵を作成

```
id_rsa
id_rsa.pub
```

作成した鍵をクリップボードにコピー
`pbcopy < ~/.ssh/id_rsa.pub`

![スクリーンショット 2020-06-13 17.47.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199085/2cbe1708-0b02-019f-aa19-349845ed1a66.png)

keyの欄にコピーしたkeyを記載する。
titleは書かなくても大丈夫です。

![スクリーンショット 2020-06-13 17.47.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199085/b900a2d5-76bc-724b-7fe9-7e96fa3cd058.png)

記載したら `Add SSH key` で設定を保存する

### githubとの接続確認
`ssh -T git@github.com`で接続確認する

```
genki:genki-blog matsubaragenki$ ssh -T git@github.com
Enter passphrase for key '/Users/matsubaragenki/.ssh/id_rsa': 
Hi GenkiMatsubara! You've successfully authenticated, but GitHub does not provide shell access.
```

接続確認できたので作成したリポジトリにプッシュしてみる


```
$git push
$Username for 'https://github.com': GenkiMatsubara
Password for 'https://GenkiMatsubara@github.com': 
Enumerating objects: 6, done.
Counting objects: 100% (6/6), done.
Delta compression using up to 4 threads
Compressing objects: 100% (5/5), done.
Writing objects: 100% (6/6), 772 bytes | 772.00 KiB/s, done.
Total 6 (delta 0), reused 0 (delta 0)
To https://github.com/GenkiMatsubara/genki-blog.git
 * [new branch]      master -> master
$ 
```

プッシュできました。

今まで使用していたssh-keyにgithubのユーザー名が含まれていたけど前回作成したのがもう2年くらい前なのでどうやって作成したか覚えていない…
CMake + Ninja + clang-cl で Windows C/C++ ビルドのメモ

## 背景

CMake + Ninja + clang-cl で C++ プログラムビルドしたい.

しかし, STL を使わない単純な C++ プログラムをコンパイルしようとしても,  cmake bootstrap 時に, linker が見つからないなどエラーが出てしまう.

## 解決方法

vcvars で, 一旦ビルド環境に入っていないとだめでした.

https://stackoverflow.com/questions/52760801/cmake-building-for-windows-clang-cl-using-ninja-generator

cmake が, いくらか環境変数を見て, コンパイラの振る舞いを判断しているっぽそうです.

vcvars で一旦環境に入るか, vcvars がやっていること相当を cmake 起動前に設定すればいけそうです.


## cross compile

通常 clang でいけるっぽい
(clang-cl は実態は clang のはず)

https://github.com/ProdriveTechnologies/clang-msvc-sdk

llvm repo に WinMsvc.cmake があるのでこれが参考になりそう.


## native(Windows)でビルドする.

LLVM の WinMsvc.cmake を少し修正すればいけます(`-imsvc` でのパスを quote で囲む)



## TODO

* [ ] llvm の repo にある WinMsvc.cmake を詳細に解読する.
* [ ] WSL 環境でビルドできるようにする.
ラズベリーパイ4でpuppeteerを動かす

ラズベリーパイ4で簡易自宅サーバを作ったので、定期的にwebクローリングさせてみました。
Node上で動く[Puppeteer](https://github.com/puppeteer/puppeteer)を使います。
Raspbian上で動かすには独自対応が必要だったので、その備忘録です。
※Node.jsの動作環境を構築できること、Puppeteerの使い方を知っている前提の記事となりますので、予めご了承ください。

# 動作環境

```
$ lsb_release -a
No LSB modules are available.
Distributor ID:	Raspbian
Description:	Raspbian GNU/Linux 10 (buster)
Release:	10
Codename:	buster
$ npm -v
6.13.4
$ node -v
v8.17.0
```

# Puppeteerをインストール
package.jsonに以下を追加し、 npm install

```
...
"dependencies": {
    "puppeteer": "2.0.0"
  },
...
```
# Raspbian上で動かす際に必要なこと
ここまでであとは普通にコードを書けばスクレイピングできるはずなのですが、うまくいきませんでした。
というのも、puppeteerが標準で動かしているヘッドレスブラウザはx86用なのでラズベリーパイのアーキテクチャ上では動きません。
そこで、ラズベリーパイのアーキテクチャ上で動くヘッドレスブラウザが必要です。
以下記事が参考になりました。
[Raspberry Piでpuppeteerを動かす方法](https://qiita.com/kwbt/items/420b3d02456fe24307ec)
[こちら](https://launchpad.net/~canonical-chromium-builds/+archive/ubuntu/stage/+build/14482955)から以下をダウンロード。
![スクリーンショット 2021-03-06 15.12.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/457333/3d5e4af8-6246-1697-42c8-111e1ea413d0.png)
ダウンロードしたファイルをscpでラズベリーパイに送り、インストール。

```
$ sudo dpkg -i <ファイル名>
$ which chromium-browser
/usr/bin/chromium-browser
```
あとはpuppeteer起動時に使うブラウザをインストールしたものに変更します。

```
    const browser = await puppeteer.launch({
        executablePath: '/usr/bin/chromium-browser'
    })  
```
これで無事にラズベリーパイ4上でスクレイピングできる環境が整いました。

## error while loading shared libraries: libX11-xcb.so.1: cannot open shared object file: No such file or directoryが出る場合
トラブルシューティングにある依存関係のあるものをインストールしてください

```
// 依存パッケージのインストール
// https://github.com/puppeteer/puppeteer/blob/master/docs/troubleshooting.md
// -yでインストール中全てイエスを答えてくれる
$ sudo apt install -y ca-certificates fonts-liberation gconf-service libappindicator1 libasound2 libatk-bridge2.0-0 libatk1.0-0 libc6 libcairo2 libcups2 libdbus-1-3 libexpat1 libfontconfig1 libgbm1 libgcc1 libgconf-2-4 libgdk-pixbuf2.0-0 libglib2.0-0 libgtk-3-0 libnspr4 libnss3 libpango-1.0-0 libpangocairo-1.0-0 libstdc++6 libx11-6 libx11-xcb1 libxcb1 libxcomposite1 libxcursor1 libxdamage1 libxext6 libxfixes3 libxi6 libxrandr2 libxrender1 libxss1 libxtst6 lsb-release wget xdg-utils
```
PowerShellで再起動の保留状態を確認する

## 概要
クラウド上でWindowsマシンを構築したりするときに役立ちそうなのでメモしておく。

## コマンド

### 再起動が必要であることを判定する

`RebootRequired` のキーは、再起動が必要な場合にキーが存在する。
何度か叩いてみるとインストール中にセットされることもあるので `RebootPending` とはまた役割が異なる。

```powershell
Test-Path 'HKLM:SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\RebootRequired'
```

### 再起動が保留中であることを判定する

`RebootPending` のキーは、再起動が保留中のときだけキーが存在する。

```powershell
Test-Path 'HKLM\Software\Microsoft\Windows\CurrentVersion\Component Based Servicing\RebootPending'
```

次のような画面が表示されるとき RebootPending が True になる。
Windows 10 2004 でいつもと違う再起動ダイアログが出たときは、なぜかこのキーが存在しないままであった。機能的に大きな改修が入るときは、例外があるのか？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/326797/0983475f-b659-3a73-1edd-58dd3490c201.png)


## 参考

* [How to check for a pending reboot (automated with PowerShell)](https://adamtheautomator.com/pending-reboot-registry-windows/)
* [Use PowerShell to test if a Windows server is pending a reboot – 4sysops](https://4sysops.com/archives/use-powershell-to-test-if-a-windows-server-is-pending-a-reboot/)
ghqでデフォルトディレクトリを変更する

## はじめに
ghqはリモートリポジトリを簡単に管理できてとても便利です。
ただ、リポジトリを管理するディレクトリがデフォルトで`~/.ghq`と隠しフォルダなため、時折不都合があります。
(※ `v0.99.0 (2020-01-01)`以降はデフォルトが`~/ghq`へ変更されています。)

なので、デフォルトを`~/.ghq`→`~/ghq`へ変更します。

## やり方
`~/.gitconfig`を編集することで、デフォルトディレクトリを変更できます。

```txt:.gitconfig
[ghq]
	root=~/ghq
	root=~/.ghq
```
`root`でデフォルトディレクトリを変更することができます。
`root`は複数設定することができ、`ghq`がリポジトリを検索する際は、ここで`root`に指定されたディレクトリを検索します。
以前`~/.ghq`にダウンロードしたリポジトリも検索に含める場合、`root=~/.ghq`も追加しておきます。


## 参考文献
[GitHub - x-motemen/ghq: Remote repository management made easy](https://github.com/x-motemen/ghq)
[Managing your git repositories with ghq - DEV](https://dev.to/ekeih/managing-your-git-repositories-with-ghq-3ffa)
EncodeURL メモ

#EncodeURL:Excel
workSheet : EncodeURL("たくわん和尚")
マクロ : Application.WorksheetFunction.EncodeURL("たくわん和尚")

#EncodeURL:VBScript
```VBScript:EncodeURL
'==================================================
' 64bit環境では、CreateObject("ScriptControl")が効かない為でした。32bit仕様で動かす。
'x:\>C:\Windows\SysWOW64\cscript test.vbs
'==================================================

WScript.Echo fnURLENCODE2013("たくわん和尚")
WScript.Echo UrlEncodeUtf8("たくわん和尚")
WScript.Echo URLDecodeUTF8(UrlEncodeUtf8("たくわん和尚"))

'==================================================
'fnURLENCODE2013: 文字列をUTF-8でエンコードするFunction
'たくわん和尚 -> %E3%81%9F%E3%81%8F%E3%82%8F%E3%82%93%E5%92%8C%E5%B0%9A
'==================================================
'strSource: 元の文字列
'返り値: エンコードされた文字列
'==================================================
Function fnURLENCODE2013(str)
    Dim xlApp: Set xlApp = CreateObject("Excel.application")
    fnURLENCODE2013 = xlApp.WorksheetFunction.EncodeURL(str)
    Set xlApp = Nothing
End Function

'==================================================
'UrlEncodeUtf8: 文字列をUTF-8でエンコードするFunction
'たくわん和尚 -> %E3%81%9F%E3%81%8F%E3%82%8F%E3%82%93%E5%92%8C%E5%B0%9A
'==================================================
'strSource: 元の文字列
'返り値: エンコードされた文字列
'==================================================
Public Function UrlEncodeUtf8(strSource)
    Dim objSC
    Set objSC = CreateObject("ScriptControl")
    objSC.Language = "Jscript"
    UrlEncodeUtf8 = objSC.CodeObject.encodeURIComponent(strSource)
    Set objSC = Nothing
End Function

'==================================================
'UrlDecodeUtf8: 文字列をUTF-8でデコードするFunction
'%E3%81%9F%E3%81%8F%E3%82%8F%E3%82%93%E5%92%8C%E5%B0%9A -> たくわん和尚
'==================================================
'strSource: 元の文字列
'返り値: エンコードされた文字列
'==================================================
Public Function URLDecodeUTF8(strSource)
    Dim objSC
    Set objSC = CreateObject("ScriptControl")
    objSC.Language = "Jscript"
    URLDecodeUTF8 = objSC.CodeObject.decodeURIComponent(strSource)
    Set objSC = Nothing
End Function
```

[物忘れ防止 VBScript Encode.vbs ](https://github.com/sugita0301/douzo)
tkinterを使ってmatplotlibによる図を外部表示する

#tkinterを使って図の外部表示
matplotlibで図を表示させるスクリプトの下に以下の部分を追加する．

```python:tkinter.py
def _destroyWindow():
    root.quit()
    root.destroy()
    
root = tk.Tk()
root.withdraw()
root.title("title")
root.geometry("770x500") 
root.protocol('WM_DELETE_WINDOW', _destroyWindow)  # When you close the tkinter window.

# Canvas
canvas = FigureCanvasTkAgg(fig, master=root)  # Generate canvas instance, Embedding fig in root
canvas.draw()
canvas.get_tk_widget().pack()
#canvas._tkcanvas.pack()

# root
root.update()
root.deiconify()
root.mainloop()
```

これで青い羽根マークの図が表示されればok
プロキシ環境下で仮想マシンを立ち上げる

#はじめに
組織（会社とか学校とか）のプロキシ環境下のWindowsPCに、
linuxの仮想マシンを立ち上げるときのやり方です。
その際、WindowsPCをプロキシサーバーにして（多段プロキシ）、
仮想マシンを外部ネットワークに繋ぎます。

![環境](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551719/c475fd86-08d2-575d-4455-435214674192.png)


#squidでプロキシサーバーを立てる
##squidのインストール
[ここのサイト](https://squid.diladele.com)からsquid.msi をダウンロードしてインストールする

![squid.msi をダウンロード](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551719/4e4196d1-cc8a-ae8d-072e-3062563aef56.png)

##squidの設定
ここで、組織のプロキシサーバー（2段目のproxyサーバー）のIPアドレスとポート番号を確認しておきましょう。
PACファイルで、プロキシサーバーを制御しているところは、PACファイル内の外部ネットワークに接続する際のプロキシサーバー情報を確認しましょう。		

C:\Squid\etc\squid\squid.confに以下を追記します。

```txt:squid.conf
cache_peer [proxyサーバーのIPアドレス] parent [proxyサーバーポート番号] 0 login=[ユーザ名]:[パスワード]
never_direct allow all
```

これで、2段目のproxyサーバーのプロキシサーバーの設定は完了です。
試しに、172.0.0.1:3128(squidのデフォルトのポート番号は3128)をプロキシサーバーにして、
外部ネットワークに繋がればOK

#Hyper-Vで仮想マシンを作成
##Hyper-Vの有効化
Hyper-Vで仮想マシンを作成していきます。
まずは、Hyper-Vを有効にします。
コントロールパネル->[プログラムと機能]->[Windows の機能の有効化または無効化]->[Hyper-V]を
チェック
![Hyper-Vの有効化](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551719/e22af50a-1483-7126-fdea-0c0fa41e6b69.png)

これで、Hyper-Vが使えるようになります。
![Hyper-Vマネージャー](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551719/609c90f6-2eaf-587b-3d4e-25574fbe6e53.png)

##仮想マシンの立ち上げ
Hyper-V マネージャーを起動して、
[操作]->[新規]->[仮想マシン]と順に押下して仮想マシンの新規作成していきます。
(画像無くてすいません。)

各設定は、OSに合わせて指定してください。ネットワークの構成は[Default Switch]にしました。	

##仮想マシンのプロキシ設定
仮想マシンを立ち上げたら、プロキシの設定をしていきます。
ここでアクセスするプロキシサーバーは、先ほどsquidで立ち上げたものです。
プロキシの設定は、各OSやバージョンによって多少変わるので、調べてみてください。(以下参照)
[Ubuntuのプロキシ設定](https://qiita.com/Fal318/items/338521feb42197a3aee5)
[Cent OSのプロキシ設定](https://qiita.com/hirohiro77/items/cdf6d8baa619c0e0e82d)

ここで設定するプロキシサーバのIPアドレスは、Default Switchのネットワークアダプタのものになります。
コマンドプロンプトで、ipconfigのコマンドを叩いて、
「vEthernet（Default Switch）」欄のIPv4アドレスがIPアドレスになります。
ポートは、3128です。

これで、仮想マシンでも外部ネットワークに繋がれば、成功です。

#さいごに
これで仮想マシン内で、yumとかaptとか使えるようになります。
UnityでWebカメラの切断を検知する

#はじめに
[前回の記事](https://qiita.com/lobmto/items/f85af1366db7f5210775)に続いて，Webカメラの切断を検知したときのメモを残しておく．

#環境
* Unity2019.2.9f1
* Webカメラ1台(Logicool)

#要点
本当は判定用のメソッド等があるのかもしれないが，分からなかったので自分なりに作った．

手法としては単純に`WebCamTexture.devices`の中に現在表示しているWebCamTextureのインスタンスがあるかどうかで判定している．
この記事ではWebCamTextureの`.name`が一致するか否かで判定を行う．

#手順
##前準備
今回もとりあえず適当なプロジェクトを作成して，表示用のPlaneを配置する．

##テスト用スクリプト
このコードは0番目のカメラを初期値として読み込み，接続・切断を毎秒ログに吐き出す．
`WebCamTest.cs`の名前でこのコードを記述して，先ほどのPlaneオブジェクトにセットする．

```C#:WebCamTest.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class WebCamTest : MonoBehaviour
{
	private WebCamTexture wct;
	private Renderer renderer;
    // Start is called before the first frame update
    void Start()
    {
		this.renderer = this.GetComponent<Renderer>();
		this.SetCamera(0);
    }

    // Update is called once per frame
    void Update()
    {
		if (Time.frameCount % 60 == 0)
			Debug.Log(this.IsConnecting() ? "接続中" : "切断済");
    }

	//前回の記事を参照
	private void SetCamera(int idx) {
		int len = WebCamTexture.devices.Length;

		try {
			wct.Stop();
		} catch { }
		this.wct = new WebCamTexture(WebCamTexture.devices[idx % len].name);
		this.wct.Play();
		this.renderer.material.mainTexture = this.wct;
	}

	bool IsConnecting() {
		if (wct == null) return false;
		//現在接続中のカメラの中に使用中のカメラはあるかを判定する
		for (int i = 0; i < WebCamTexture.devices.Length; i++)
			if (this.wct.deviceName == WebCamTexture.devices[i].name) return true;
		//無ければカメラは切断されているのでnullを代入してfalseを返す．
		this.wct.Stop();
		this.wct = null;
		return false;
	}
}

```
上のコードを実行中にカメラを引き抜くと実際に切断済みと表示されているのが確認できる．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/382909/80ee70c4-432d-9621-ad07-b75a027be389.png)
##スクリプトの概要
1秒に1度`WebCamTexuture.devices`を全探索して今使用中のカメラが接続中カメラの中に存在しているかどうかを判定している．
これでは瞬間的な切断に対応できないかもしれないが，今回の用途においては問題なかったためこの方法を採用した．

また，一度切断された`wct`は再利用できないのようなので`.Stop()`で停止させたのちにnullを代入している．もし再接続する機能を作りたいのであれば，wctがnullの間は毎秒カメラを探索する等の処理を記述すればいい．

`SetCamera`関数については[前回の記事](https://qiita.com/lobmto/items/f85af1366db7f5210775)で作成しているので，そちらを参照．

#おわりに
今回も，できるだけ単純な例にするために例外判定など色々省略しています．
なので実行中のログに赤文字が出るかもしれないですが，とりあえず動作はするはずです．

もっと賢い方法がありそうな気がしますが，苦肉の策として紹介させていただきました．
Unityで複数台のWebカメラを表示する

#はじめに
とある事情でUSBカメラを複数台搭載したロボットの操縦用ソフトを作ったので，その際のメモを残しておく．

#実行環境
* Unity2019.2.9f1
* Webカメラはlogicoolなど3台

#要点
複数台といってもやることは1台の時と同じなので`WebCamTexure wct = WebCamTexture.devices[i]`のように，好きなインデックスのカメラを取得して表示すればよい．

以下は詳しい手順．

#手順
##前準備
とりあえず適当なプロジェクトを作成して立ち上げておく．そして，カメラの映像を映し出すためのPlaneオブジェクトを配置する．

##描画用スクリプト
そして，配置したPlaneオブジェクトに今回使うスクリプト（ここでは`MultiCam.cs`とした）をアタッチする．

```C#:MultiCam.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class MultiCam : MonoBehaviour
{
	// Start is called before the first frame update
	private WebCamTexture wct = null;//カメラのテクスチャ
	private Renderer renderer;       //Planeのテクスチャを書き換えるために使う
	void Start()
	{
		//まずPlane自身のテクスチャ情報を扱えるようにRendererを取得しておく
		this.renderer = this.GetComponent<Renderer>();
	}

	// Update is called once per frame
	void Update()
	{
		//試しに3秒ごとにカメラを切り替えている
		if (Time.frameCount % 180 == 0) this.SetCamera(Time.frameCount / 180);
	}

	private void SetCamera(int idx) {
		// 現在接続中のカメラはWebCamTexture.devicesに格納されている．
		// したがってLengthがカメラの台数となる
		int len = WebCamTexture.devices.Length;
		if(len == 0) return;

		try {
			wct.Stop();
		} catch { }
		this.wct = new WebCamTexture(WebCamTexture.devices[idx % len].name);
		this.wct.Play();
		this.renderer.material.mainTexture = this.wct;
	}
}

```
実行すれば以下のような形でPlaneオブジェクト上に映像が投影される．
また，複数台設定されている場合は3秒ごとにカメラの映像が切り替わっていくはず．
![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/382909/5c2ee0dd-399d-2646-1b3c-f04e8d20d869.png)

##スクリプトの概要
ざっとこんな感じの流れ．

1. 再生中の`WebCamTexture`（この例では`wct`）を`wct.Stop()`で停止させる．※wctがnullだとまずいのでtry-catchで挟んでいる
1. `wct`に対象のカメラのテクスチャを格納する．
1. `wct.Play()`で映像の再生を開始.
1. Planeオブジェクト自身のテクスチャ（この例では`renderer`）にwctをセットすることでPlane上に映像を映す．

#最後に
実際の操縦用ソフトではUSBカメラの接続・切断を自動認識するように設計していた．
それについては[次の記事](https://qiita.com/lobmto/items/3a14f1f7a3c42618eab3)に~~書きたい~~書いた．
OpenCVを実行するとでてくるFailed to load module "canberra-gtk-module"というエラーの対処法

OpenCVを書いたプログラムを実行すると以下のようなエラーがでてきます。このエラーがでていても動かないことはないのですが、対処法を見つけたので紹介したいと思います。

```
Gtk-Message: 15:45:02.507: Failed to load module "canberra-gtk-module"
```
![o.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/616944/a61f8256-c39b-874c-0543-aae4fc031135.png)

これはズバリターミナルで以下のように実行し

```
sudo apt-get install libcanberra-gtk*
```

![o2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/616944/47c13bb2-cd31-dd2f-8bde-73b271ba65df.png)

このように終わればエラーはなくなります。
AzureAD B2B - 社外の人にAzureADアカウントを無償で払い出す

# これは
企業でAzureADを使っていて、無償で社外の人にアカウントを払い出したいときの方法

# 背景
企業でAzureADを使っていて、AzureADアカウントを委託先企業など社外の人に払い出したいときがあります。
具体例としては他の社内システムの認証をAzureADで行っていたりするときなどです。
このとき、通常アカウントを払い出すと当然コストがかかります。

# 課題
- 上記の背景においてコストがかかる
- 社外の人に多くのアカウントを払い出すと管理が大変
 - AzureAD上でどのアカウントが社外の人かわからない

# 解決のための機能
AzureAD B2B機能を使用することで、無償でアカウント払い出しが可能です。
かつ、動的ユーザ機能を使うと管理も楽になります。

- AzureAD B2B
    - これはAzureADのゲストアカウント機能になります。
- （オプション）グループの動的ユーザ機能
    - これを使うことでAzureAD上でどの企業の人かがわかりやすくなります

Azure Active Directory B2Bについて
https://docs.microsoft.com/ja-jp/azure/active-directory/b2b/what-is-b2b

# 手順
1. [AzureAD管理センター]-[ユーザ]に移動
2. **新しいゲストユーザ**をクリック
3. 情報を入力して招待する

    ![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155456/87c424d7-ecc1-89bd-fa5f-0f55334ecda9.png)

4. 招待した人に承諾してもらう
5. AzureADからの見え方

    ![eee.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155456/f7723164-a040-9730-320c-024eb75c0c03.png)


# （オプション）運用のためにやっておいたほうがいいこと
## 専用のグループを作成する
1社から多くの人をゲストアカウント登録する場合などは、専用のグループを作ったほうがよいです

1. [AzureAD管理センター]-[グループ]に移動
2. "新しいグループ"をクリック
   - [グループの種類]は**Office365**をオススメ
      - GSuiteにグループをプロビジョニングすることなどを想定したとき、**Office365**でないとプロビジョニングできないです。最初に**セキュリティ**で作って失敗しました。
   - [メンバーシップの種類]はここでは**割り当て済み**に設定しますが、あとで**動的ユーザ**に変更します。

    ![4444.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155456/1488172c-a28c-54fc-867b-d9197047f8db.png)


3. あとで動的ユーザに変更するのでグループ作成はこれで終わりです。もし割り当て済みで運用する場合は、手動でメンバー追加します。

## 動的ルールを設定しておく
アカウント追加されたときは自動でグループに参加できるようにしておくには、以下の手順が必要です。

1. ユーザのプロファイル画面に行きます。
2. [ジョブ情報]-[会社名]に委託先企業の名前を入力します（例としてAAAを入力）

    ![2222.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155456/06ed815a-bfe7-f944-002a-3c566b648841.png)

1. 先ほど作成した専用グループのプロパティに行きます
2. メンバーシップの種類を**動的ユーザ**に変更

    ![333.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155456/928d45e0-861a-4b84-11e3-35550de2bc4e.png)


3. 動的クエリで以下のように設定します
   - [グループの種類]に**companyName**を設定
   - [演算子]は**Equls**を設定
   - [値]は3.2で設定した委託先企業の名前を入力
    ![5555.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155456/d0ce04fc-8c4e-cc76-36b0-168f1f108bfb.png)

以上で、アカウント追加のとき、ユーザプロファイルの会社名プロパティに企業名を入力すれば自動でグループ参加してくれます。
graphql-codegeneratorで作るuse~ってどんな関数？

# 概要
apolloが詳しくないせいで、`graphql-codegenerator`で生成したコードが読めないから、`graphql-codegenerator`で使われるコードを追い、ついでにapolloを勉強する

# 結論
- `useMutation`が返すgraphql通信する関数とloadingを返却する関数
- 引数には`refetchQueries`や`fetchPolicy`など`<Mutation>`とかに使える値が設定できる

# この関数の基本形
```tsx
import * as ApolloReactCommon from '@apollo/react-common';
import * as ApolloReactHooks from '@apollo/react-hooks';

export function use~Mutation(
  baseOptions?: ApolloReactHooks.MutationHookOptions<
    ~Mutation,
    ~MutationVariables
  >
) {
  return ApolloReactHooks.useMutation<
    ~Mutation,
    
  >(~Document, baseOptions);
}
/*
- ~Document: クエリ
- ~Mutation: 返却値の型
- ~MutationVariables: クエリ実行時に必要な引数
*/
```

気になること

- 返り値（結局何が使えるの？）
- 引数（引数にどんな柔軟性があるの？）

# 返り値
`ApolloReactHooks.useMutation<~Mutation,~MutationVariables>(~Document, baseOptions)`

## `ApolloReactHooks.useMutation`
- `import * as ApolloReactHooks from '@apollo/react-hooks'`より`ApolloReactHooks`は`@apollo/react-hooks`であり、
- [ここ](https://qiita.com/setsumaru1992/items/0d8e140ee9b7a8e1f344)であるように、`@apollo/react-hooks`は`@apollo/client`

`@apollo/client`を探すと以下発見（厳密には`client`で読んでる`react/index.ts`）
https://github.com/apollographql/apollo-client/blob/c2698e5fdbd109a4765ce269d345b20cfccc0ec9/src/react/index.ts

```src/react/index.ts
export { useMutation } from './hooks/useMutation';
```

`useMutation`についてはこちら
https://qiita.com/setsumaru1992/items/3d77ba5ed883ca89b348

結局は以下2つの要素を含む配列を返却する関数

- `Promise<FetchResult<TData>>`を返却する関数
    - graphql通信する関数
- `MutationResult<TData>`
    - `data`とか`loading`とかapolloあるあるな値

# 引数
`use~Mutation(baseOptions?: ApolloReactHooks.MutationHookOptions<~Mutation,~MutationVariables>)`

## `ApolloReactHooks.MutationHookOptions`
`ApolloReactHooks.useMutation`欄にもあるように、`@apollo/client`を探すと以下発見
https://github.com/apollographql/apollo-client/blob/c2698e5fdbd109a4765ce269d345b20cfccc0ec9/src/react/types/types.ts#L202

``` src/react/types/types.ts
export interface MutationHookOptions<
  TData = any,
  TVariables = OperationVariables
> extends BaseMutationOptions<TData, TVariables> {
  mutation?: DocumentNode;
}
```

MutationHookOptionsについては[こちら](https://qiita.com/setsumaru1992/items/3d77ba5ed883ca89b348#%E5%BC%95%E6%95%B0%E3%81%A7%E6%8C%87%E5%AE%9A%E3%81%A7%E3%81%8D%E3%82%8B%E3%82%AA%E3%83%97%E3%82%B7%E3%83%A7%E3%83%B3mutationhookoptions)

`refetchQueries`や`fetchPolicy`など`<Mutation>`とかに使えるオプションが定義できる
【PHP】JSONを取得してデータを表示する

今回は、コロナウイルスのJSONのデータを取得して
データをブラウザに表示していこうと思う。

今回、使用するJSONは、以下の物になる。
「コロナウイルスの県ごとの感染数、死者数」
url↓
https://covid19-japan-web-api.now.sh/api/v1/prefectures

```php
[
  {
    "id": 1,
    "name_ja": "北海道",
    "name_en": "Hokkaido",
    "lat": 43.46722222,
    "lng": 142.8277778,
    "cases": 176,
    "deaths": 7
  },
  {
    "id": 2,
    "name_ja": "青森",
    "name_en": "Aomori",
    "lat": 40.78027778,
    "lng": 140.83194440000003,
    "cases": 8,
    "deaths": 0
  },
...
```

このJSONデータを取得していこうと思う。
まず、JSONデータをデコードしていく。

```php
<?php
$url="https://covid19-japan-web-api.now.sh/api/v1/prefectures";
$json=file_get_contents($url);
$arr=json_decode($json,true);
```

それぞれ解説していく。

```php
$url="https://covid19-japan-web-api.now.sh/api/v1/prefectures";
```
変数＄urlに先ほど掲載させてurlを入れ込む。

```php
$json=file_get_contents($url);
$arr=json_decode($json,true);
```
 次にfile_get_contents()関数に$urlを変数を入れる。
file_get_contents()は、ファイルなどを組み込む際に使う。
その後、json_decode()により
json形式のファイルから元の形式に変換する。

また、第二引数のtrueは、
falseにするとオブジェクトを返し、
trueにすると連想配列形式のオブジェクトを返します。

上記のコーディングによりjsonの取得が完了した。

次に取得したデータをブラウザ上に表示する。

```php
foreach($arr as $data){
    $ja= "都道府県名　".$data['name_ja']."\n"."<br>".PHP_EOL;
    $cases= "発生件数　　".$data['cases']."人\n"."<br>".PHP_EOL;
    $deaths= "死者数　　　".$data['deaths']."人\n"."<br>".PHP_EOL;
    $pcr= "pcr件数　　".$data['pcr']."人\n"."<br>".PHP_EOL;
   $virusData= array(
      $ja,$cases,$deaths,$pcr,
   );
```

foreach文を使用して、$arrを$dataに入れ、
それぞれのjsonのデータを

```php
 $ja= "都道府県名　".$data['name_ja']."\n"."<br>".PHP_EOL;
```
のように都道府県名、jsonの要素名、改行のエスケープシーケンス、
HTMLの改行タグ、PHP改行コードを記載している。
そして、それらのデータを一つの$virusDataという変数に配列にて格納する。

最後に、

```php
echo implode('',$virusData);}?>
```

配列の要素を結合して文字列にするimplode関数を使用することで以下のように表示される。

<img width="1440" alt="スクリーンショット 2020-06-13 17.02.32.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/612642/0907a552-f9d4-1e73-fd46-0a63cf1865d9.png">

全コードは、以下の通りである。

```php
<?php
$url="https://covid19-japan-web-api.now.sh/api/v1/prefectures";
$json=file_get_contents($url);
//$json=mb_detect_encoding($json,'UTF-8','ASCII,JIS,UTF-8,EUC-JP,SJIS-WIN');
$arr=json_decode($json,true);
foreach($arr as $data){
    $ja= "都道府県名　".$data['name_ja']."\n"."<br>".PHP_EOL;
    $cases= "発生件数　　".$data['cases']."人\n"."<br>".PHP_EOL;
    $deaths= "死者数　　　".$data['deaths']."人\n"."<br>".PHP_EOL;
    $pcr= "pcr件数　　".$data['pcr']."人\n"."<br>".PHP_EOL;
   $virusData= array(
      $ja,$cases,$deaths,$pcr,
   );
echo implode('',$virusData);
}
?>
```

完成系としては、jsonから取得したデータをgoogle sheet apiを使用して
更新出来るようなプログラムを作成したい。

また、プログラミング初心者なので、コードのフィードバック頂けたら嬉しいです。
よろしくお願い致します。
JMESPathを使ってJSONをパースするときにPython製ツールjmespath-terminalが便利だった

# はじめに
JMESPathはJSONをパースするためのクエリ言語で、イメージとしてはjqと似たような感じで使えます。例として、**AWS CLI**の`--query`オプションでは、JMESPathを指定します。
JMESPathを利用して、渡したJSONを解析するためのツールもあります。その中でも、クエリの結果が動的に表示される**jmespath-terminal**が導入も利用もカンタンでしたので、メモを残そうと思いました。

## 環境
- macOS Mojave 10.14.6
- シェル: bash
- python3.8

# jmespath terminal

[GitHub - jmespath/jmespath.terminal: JMESPath exploration tool in the terminal](https://github.com/jmespath/jmespath.terminal)


### インストール

```bash
pip install jmespath-terminal
```

### 使い方

- パイプでJSONを流すと、対話式の画面を開くことができます。

```bash
$ echo '{"foo": {"bar": {"name": "one"}, "baz": {"name": "two"}}}' | jpterm
```
![jmespath.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/480802/4f30f5e3-37c7-b8d6-3887-69c524af0b2c.gif)

- `control + c`で閉じます。閉じた後に、何をoutputするかは`control + p`で変更できます。
	1. quit : 何も表示しません。
	2. result : JMESPathをかけた結果を表示します。e.g.) `one`
	3. expression: 入力したJMESPathを表示します。 e.g.) `foo.bar.name`
![jmes-toggle.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/480802/0f832bc0-c92b-7b29-59e9-6b8d1a299702.gif)

# jmespath

[jmespath · PyPI](https://pypi.org/project/jmespath/)

- こちらはjqと同じ用に使えます。
- 自分は試してませんが、pythonとしてデータ構造をパースするコードも普通に書けるようです(リンク先).

### インストール

```bash
pip install jmespath
```


```bash
$ echo '{"foo": {"bar": {"name": "one"}, "baz": {"name": "two"}}}' | jp.py foo.bar.name

"one"
```

# 公式資料

- [JMESPath — JMESPath](https://jmespath.org/)
  - チュートリアルがめちゃくちゃわかりやすいです。

# その他感想
AWS CLIの `--query`オプションをなるべく使いこなしたい...ので、JMESPathに普段から慣れておきたいな、と思っています。
IBM CloudのBare MetalのWindows Serverにリモート接続できない時の復旧方法


要はKVMコンソールの使い方の手順です。

# 背景
今起こったことをありのまま話すぜ。

とある事情でIBM CloudのBare Metal(物理サーバー)を立てたんだけど、Hyper-V周りの設定を変えていて、アダプターチェックをポチッと外しちゃいました。

<img width="917" alt="スクリーンショット 2020-06-13 16.58.41.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3168/133bbfb0-41a5-a0c9-37a6-5ab1560b2b9d.png">


次の瞬間、無情にも落ちる、リモートデスクトップ画面。

あああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああああ。。。

気づいた時には時すでに遅し。

もちろん、普段使っているVPNのリモートデスクトップ接続では再ログインはできない。
こまった・・これは再構築か！？

と思った瞬間に思い出したのが、Windowsのネットワーク設定とは独立してリモート接続できるのが、KVMコンソール！

ところが、[仮想サーバーと同じ手順](https://qiita.com/drafts/803a9a330f0e19f36adc/) かと思いきや、すこし手順が違うので、ベアメタルのKVMコンソールログインの手順を説明します。

では、ネットワーク断絶したベアメタルサーバーをお手当しましょう！

# KVMコンソールを立ち上げ方が仮想サーバーと違う罠

KVMコンソールの一般的な立ち上げ方は、IBM Cloudの仮想サーバーの以下のメニューをクリックするだけ。

<img width="920" alt="スクリーンショット 2020-06-13 16.51.26.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3168/46321543-391d-bb16-1657-3486174f2c30.png">

下記のように出てくるダイアログに「続行」を選ぶだけ。

<img width="563" alt="スクリーンショット 2020-06-13 16.51.51.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3168/0f27b2fe-8270-ab28-ff3e-cf0d36544e24.png">

そうすると下記のようにウィンドウが立ち上がる。
が、ここから仮想サーバーの場合と違った。あれ？USERNAME/PASSWORDどこだ？


<img width="567" alt="スクリーンショット 2020-06-13 16.52.18.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3168/001b5827-cc70-8b47-8525-2f5212c4dd9f.png">


実はここ、「リモート管理」の画面です。
<img width="924" alt="スクリーンショット 2020-06-13 16.54.16.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3168/6d72883e-c99e-a969-e607-2a8f1b653241.png">

このUsername, Passwordを使ってログインしましょう。
<img width="878" alt="スクリーンショット 2020-06-13 16.54.40.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3168/3cbabb76-e81e-7c8f-5dd6-6d52f45e3f55.png">

その後で、「Remote Control」の「iKVM/HTML5」を選びます。
<img width="630" alt="スクリーンショット 2020-06-13 16.55.10.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3168/26991195-3b86-5328-4c8b-5a3c3c681fad.png">

この画面で「iKBM/HTML5」ボタンを押します。

<img width="650" alt="スクリーンショット 2020-06-13 16.55.40.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3168/d2250d77-700b-ebe5-7204-6006b69c0cbe.png">

ログイン画面にきました。

<img width="649" alt="スクリーンショット 2020-06-13 16.56.18.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3168/b57dd31f-704f-76c7-ff68-2ff414a95016.png">


# MacユーザーがTiger VNCでWindowsにログインする時の罠

ちなみに、Macユーザーの時に曲者となるのが、Ctrl+Alt+Deleteってどうやって入力するの？という罠にはまりました。

これは下記の入力で対応できます。

* fn + Control + Alt + Delete

これで、ログイン画面に遷移できます。

ログイン後、問題の設定を直せば、従来通りPrivate Networkをつかったリモートデスクトップログインができるようになるはずです。

それでは、お大事に！

ナンマンダブ、ナンマンダブ。
chromeリモートデスクトップでUbuntuがloopした時の対処

#問題

windowsをクライアントとしてUbuntuをリモートデバイスとしてchrome-remote-desktopで接続した後にリモートデバイスをシャットダウンするとログインループに陥ります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396969/d93df3d1-fb41-68b8-b283-bbbf154b7c61.png)
この画面が繰り返される。

#原因
ログインができない原因はUbuntuでログインしようとするとリモートでログインをしてしまうからである。

#対処
chrome-remote-desktopをアンインストールすることでログインができるようになります。

```
sudo apt-get autoremove chrome-remote-desktop
```

#解決策
Ubuntuの起動時にchrome-remote-desktopが起動しないようにする。

```
sudo systemctl disable chrome-remote-desktop
```

ログイン後にchrome-remote-desktopが起動するようにする

```
gnome-session-properties
```
スタートアップアプリケーションの設定で
/opt/google/chrome-remote-desktop/chrome-remote-desktop --start
と記述する。

#参考
https://xvideos.hatenablog.com/entry/chrome-remote-desktop-ubuntu1804
https://jkpe.net/ubuntu-20-login-loop-chrome-remote-desktop-rdp/
MVCモデルってなに？？？

Rails初学者の中には、**MVCモデルって何かよくわからない**という方が意外とたくさんいらっしゃいます。
MVCモデルがわからず、コードをひたすら書くことは果たしてrailsを理解していると言えるでしょうか？いいえ言えません！（反語
そんな方々にMVCモデルに対する苦手意識を無くして欲しいと思い、記事を書いてみました。
ぜひ最後までお付き合いください。

#MVCモデルについて
MVCとは、プログラムを構成している中身を**「モデル(Model)」**、**「ビュー(View)」**、**「コントローラ（Controller）」**の３つに分類したものを言います。
それらの頭文字をとってMVCモデルと呼んでいます。
####・モデル(Model)
モデルとは、データを扱う部分です。データベースに対してデータの登録・取得・更新・削除などの処理をします。
####・ビュー（View）
PCの画面(ブラウザ)に表示される部分を言います。実際に入力する処理を行ったりする部分です。HTMLの作り込みはここになります。
####・コントローラ(Controller)
ユーザからの要求に対して、Modelとの連携やどのViewを表示するのかといった処理を行う司令塔です。ユーザーと「Model」、「View」を繋ぐ橋渡し的存在と言われています。<img width="954" alt="スクリーンショット 2020-06-11 23.31.07.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/495367/432fde38-803b-f3a0-e78c-96cbd4f495b6.png">


##例えば...
ここまでMVCモデルについてざっくり説明してきました。
ここからは２つの事例を見ていきます。
１つ注意点です。下に例毎にMVCモデルの動きの流れが書いてありますが、これは**あくまでMVCモデルの動き**です。**システム全体から見た動きではない**ため、細かく見るともう少し複雑になるということはご認識ください。


- **例１:ブラウザでトップページへのリンクを押下した**

事前条件としてトップページへのリンクを押下し、URlにIDを持たないページへ遷移するとします。
**「ブラウザ」と「controller」、「View」の中**だけで行われています。
ここでは、controllerをHomeController、Viewはtop.htmlとします。

ブラウザでリンクを押下
↓
HomeControllerのtopアクションを探しだす。（正確には、Controllerを見つけるために先にrouteを通るが、ここでは割愛）
↓
Homeフォルダのtop.htmlを見つけ、ブラウザに表示させる

といった流れです。



- **例2:ブラウザで投稿をした**
 
今度はブラウザで新規投稿をするとします。今回はコメントの投稿としましょう。
**MVCとブラウザ、データベース全て**を使います。
controllerをCommentsController、ModelをComment、コメントを表示するviewはcommentフォルダのshow.html、コメントを入力して送信するviewはnew.html、コメントのデータが保存されるテーブルはコメントテーブルとします。

new.htmlでコメントを入力し送信ボタンを押下する
↓
CommentsControllerのcreateアクションが動き、入力内容がsaveされる
↓
コメントmodelを通り、コメントテーブルの適切なカラムに入力内容が保存される
↓
CommentsControllerのcreateアクションで指定されているリダイレクト先(今回はcommentフォルダのshow.html)へリダイレクトしようとする
↓
CommentsControllerのshowアクションを探し出す
↓
commentフォルダのshow.htmlがブラウザに表示される

といった流れです。

#最後に
MVCモデルについて、理解を深めることができましたでしょうか？
初学者の方にプログラミングを教えていると、ここのところの理解が追いついていない方をよく見かけるんです。
よくわかってなかったよーという方の知識が少しでも増えてくだされば幸いです。
MVCモデルの流れを知っていれば解決できるエラーもありますし、サイトの作成もしやすくなると思いますよ！

#　
最後までお読みいただきありがとうございました！
今後さらに詳しい記事や発展的な内容を書いていきたいと思いますので、読んでいただけると嬉しいです。
ツイッターもやってます。日常のつぶやきやごく稀に情報発信もしておりますので、フォローしてくださると喜びます☺️→@saketi_sei
VBでファイルカッターを作ってみました。

先日社内のストレージに問題があり、
外部のネットワークストレージはセキュリティを理由に使用不可
USBなどの外部媒体も使用禁止
メールの添付も10Mbの制限付き・・・

そんな時、大昔に大容量ファイルを分割し、複数のメールで添付して送付していた事を思い出し
使っていたファイルカットツールが欲しくなりました。

昔のソフトなので名前も覚えていない…

検索するとそのまま使えそうなソースコードが公開されていました。

VBの勉強もかねて
ソースを読み理解していきます。

参考サイト
http://tearspurelifestyle.blog102.fc2.com/?no=89#comment
参考元のソースを
読み解いて

test.binとなっている分割したいファイルをフォームから選べるように、OpenfileDialogを使い、
分割サイズをドロップダウンリストから選べるようにしました。
今後は出力ファイルのファイル名を自由にできるようにするとか色々できそうです。

	Imports System
	Imports System.IO
	
	Class BinarySplit
		Shared Sub cut()
			' バイナリ・ファイルの読み込み
			Dim src() As Byte = File.ReadAllBytes("test.bin")
			
			' 分割サイズ指定
			Dim FILESIZE As Integer = 1024 * 1000 ' 分割サイズ例　１MB
			
			' カウンタ初期化
			Dim num As Integer = 0
			
			' 変数remainに分割元ファイルの長さを登録
			Dim remain As Integer = src.Length
			' 変数remainが0以上の間（ファイルが0バイトよりも残っている場合）ループ
			While remain > 0
			
				' 作成する分割ファイルの実際のサイズ
				' FILESIZE と remeinどちらが大きいか(最終ループの為）
				' 変数length = 切り取るバイト数となる
				Dim length As Integer = Math.Min(FILESIZE, remain)
				
				' 分割ファイルへ書き出すbyte配列の作成
				Dim dest(length - 1) As Byte
				
				' リファレンス
				' Array.Copyメソッドでコピー
				' Array.Copy(a, i, b, j, n)
				' 配列aの(i+1)番目の要素を配列bの(j+1)番目の位置へと、順にn個をコピーする。
				
				' 配列src（元ファイル）のnum*FILESIZE+1(カウンタ×分割サイズ+1)【切り出し開始】から
				' 配列dest(分割ファイル書き出し配列)の0+1目の位置にlength個コピーする
				Array.Copy(src, num * FILESIZE, dest, 0, length)
				
				' 出力ファイル名指定（例out0001.bin、out0002.bin、……）
				Dim name As String = String.Format("out{0:D4}.bin", num + 1)
				
				' byte配列のファイルへの書き込み
				File.WriteAllBytes(name, dest)
				
				' カウントアップ
				num += 1
				' 変数remainから出力したファイルサイズを引く
				remain -= FILESIZE
			End While
		End Sub
	End Class

あと、
フォームの分割開始ボタンからサンプルのクラスを読み実行も成功しました。
分割後にMessageBox.Showを使って何個のファイルに分割できたのか表示できるようにしました。

分割したファイルはcopyコマンドで
copy /b out0001.bin + out0002.bin + ・・・out000x.bin test.bin
とすれば結合できます。