OmniAICreator/Qiita-1.07M huggingface dataset:
Elastic Cloud の Schema の設定

## データの投入 ##

test-apr20 という engine を作成済とします。

投入するデータ

```json:all_data.json
[
{"name": "宇都宮", "population": "42761", "date_mod": "1957-2-20", "id": "t0921"},
{"name": "小山", "population": "17895", "date_mod": "1957-8-15", "id": "t0922"},
{"name": "佐野", "population": "71564", "date_mod": "1957-12-14", "id": "t0923"},
{"name": "足利", "population": "93672", "date_mod": "1957-5-9", "id": "t0924"},
{"name": "日光", "population": "72351", "date_mod": "1957-6-4", "id": "t0925"},
{"name": "下野", "population": "35187", "date_mod": "1957-3-21", "id": "t0926"},
{"name": "さくら", "population": "31246", "date_mod": "1957-10-23", "id": "t0927"},
{"name": "矢板", "population": "65792", "date_mod": "1957-8-26", "id": "t0928"},
{"name": "真岡", "population": "74139", "date_mod": "1957-2-15", "id": "t0929"},
{"name": "栃木", "population": "29831", "date_mod": "1957-8-7", "id": "t0930"},
{"name": "大田原", "population": "54927", "date_mod": "1957-5-12", "id": "t0931"},
{"name": "鹿沼", "population": "36842", "date_mod": "1957-4-24", "id": "t0932"},
{"name": "那須塩原", "population": "93875", "date_mod": "1957-2-9", "id": "t0933"},
{"name": "那須烏山", "population": "38254", "date_mod": "1957-3-21", "id": "t0934"}
]
```

```bash:http_insert.sh
HOST="https://mar29-project.ent.asia-northeast1.gcp.cloud.es.io"
PRIVATE_KEY="private-***********"
ENGINE="test-apr20"
#
http ${ENDPOINT}'/api/as/v1/engines/'${ENGINE}'/documents' \
	'Authorization: Bearer '${PRIVATE_KEY} < all_data.json
#
```

## スキーマの表示 ##

```bash:go_list.sh
HOST="https://mar29-project.ent.asia-northeast1.gcp.cloud.es.io"
PRIVATE_KEY="private-***********"
ENGINE="test-apr20"
#
http ${ENDPOINT}'/api/as/v1/engines/'${ENGINE}'/schema' \
	'Authorization: Bearer '${PRIVATE_KEY} | jq .
```

実行結果

```text
$ ./go_list.sh 
{
  "date_mod": "text",
  "name": "text",
  "population": "text"
}
```

## スキーマの設定 ##

```bash:go_update.sh
HOST="https://mar29-project.ent.asia-northeast1.gcp.cloud.es.io"
PRIVATE_KEY="private-***********"
ENGINE="test-apr20"
#
http ${ENDPOINT}'/api/as/v1/engines/'${ENGINE}'/schema' \
	'Authorization: Bearer '${PRIVATE_KEY} < schema01.json
```

```json:schema01.json
{
  "population": "number"
}
```

実行後、GUI で確認すると次のようになります。
![schema_apr20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/76d83585-434b-8eb8-ebdb-1119437c24a8.png)
dockerでコンテナ内にbundle installされない問題の解決策【M1特有、、かもしれない】

会社でDockerを初めて触り、環境構築をする際にエラーが出たので内容と解決策を解説しようと思います。
エラーの具体的な原因は分かりませんでしたので、内容と解決策を書いていきます。
# 前提
チップ : Apple M1 Pro
# エラーの内容
```
$ docker-compose up
```
をする際に
```
ERROR [5/7] RUN bundle install -j $(grep ^cpu\scores /proc/cpuinfo | uniq |  awk '{print $4}')
```
のエラーが出ました。RUN bundle install〜はDockerfileのコマンドですが、-jオプションが何を示しているのかわからずdocker-compose upでエラーが出てしまっていました。
# 解決策
Dockerfileにbundleをインストールするコマンドが入っていますがこちらのコードはオプションが指定されています。この-jオプション以降がエラーの原因だったらしく削除して、
```
RUN bundle install
```
とすると、無事環境構築できました。

# 余談
先輩のPC（M1ではない）では全く同じようにDockerで環境構築すると、無事できました。そして、もう一人の先輩のPC（M1Mac）で同じようにdocker-compose upするとエラーが出ました。完全な憶測ですが、M1Mac特有のエラーなのかなとも思いました。

Dockerでbundle instalできない方の力になれれば幸いです。
VS CodeでSF Monoを使う

## SF Monoに惚れた

Mac使いの方は一度は見たことがあるであろう定番フォントSF Mono、ターミナルとかXCodeの標準書体のアレです。

VS Codeでこのフォントを使うためには一筋縄ではいかないので以下🦑に記します。

## 手順

ターミナルで以下🦑を叩きます。

``` sh:
$ open /System/Applications/Utilities/Terminal.app/Contents/Resources/Fonts
```

Termnal.appのパッケージ内がFinderで開くはずです。

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/628782/095b60fd-fb0b-a9cd-4d3e-d4f85332947c.png)

ここの中のフォントを全部（じゃなくてもいいと思いますが入れて損はない）ドラッグで選択して右クリックから「開く」を押してフォントをインストールします。

あとは`Editor: Font Family`に`SF Mono`と記載するだけです。

## 完成！！

![スクリーンショット 2022-04-20 13.13.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/628782/702cabc1-3dec-c8be-159d-dc88cdc5586d.png)

とってもかわいいね😆
エンジニア面接の質問と回答例10個

# [<font color="#333">あくまで一つの回答例</font>](#-初歩的です)
初歩的ですが、意外と全てを正確に答えられないのでメモ


|　　　　　　　　  　　　　　　　　   　　　　　　　　　　　　　　　　　　　　　　　　　
|:-:|
|<img width="200" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/920917/4ca9eeeb-b038-6332-01d4-eb9cc2d447cb.png" >|

# [<font color="#333">1.URLが入力されてブラウザに表示されるまでの流れを説明をしてください。</font>](#-1.ブラウザにURLが入力されて表示されるまでの流れを説明をしてください。)

1、DNSサーバーにドメインを問い合わせる

2、DNSサーバーからブラウザにIPアドレスが返ってくる

3、そのIPアドレスのWEBサーバーにデータを要求

4、WEBサーバーからHTMLやCSS等のデータが返ってきて表示される。
# [<font color="#333">2.GETとPOSTについて説明してください。</font>](#-2.GETとPOSTについて説明してください。)
表面的な違いではURLにパラメータとして表示されるかされないかの違い
裏側ではGETは指定したリソースの表現（見た目）を転送するようにリクエストするメソッド。
何か検索したり取得したり。
POSTは指定したリソースをあらかじめ実装した機能に従って処理をするメソッド。
何かデータを更新したりする処理です。

# [<font color="#333">3.MVCモデルの処理の流れを説明をしてください。</font>](#-3.MVCモデルの処理の流れを説明をしてください。)
***M（モデル）***
データベースとデータのやり取りを行う機能を実装したり、データベースから取得したデータをプログラムで扱いやすい形式でデータを変換するというような役割を担っています。

***V（ビュー）***
ブラウザにHTMLを動的に表示させる役割

***C（コントローラー）***
クライアントから来たリクエストURLに応じて行う処理をあらじめ設定しておく場所。viewの振り分けも行う


# [<font color="#333">4.ポートフォリオのVue.jsとLaravelはなぜその技術を選定したのか？</font>](#-4.ポートフォリオのVue.jsとLaravelはなぜその技術を選定したのか？)
***回答例***
まずはLaravel・・・色々な機能やプラグインの開発が盛ん、データベース操作が簡単、コンポーザーでパッケージ管理が出来るのでライブラリ使用の利便性が向上する

Vue・・・これに関しては候補としてreactが挙げられると思いますが、必要なライブラリの情報がネット上でわかりやすいのでこの個人開発ではvueで十分と思いました。


# [<font color="#333">5.Vue3が最新のバージョンだが、なぜポートフォリオではVue2を使用しているのか？</font>](#-5.Vue3が最新のバージョンだが、なぜポートフォリオではVue2を使用しているのか？)
webサービスのターゲットの年齢層が比較的高めを想定していたので古いブラウザの
対応も気にして2で開発する事にした。

# [<font color="#333">6.JSのコールバック関数について説明してください。</font>](#-6.JSのコールバック関数について説明してください。)
高階関数に値やそのまま関数として渡して実行してもらう関数の事。具体的にはsetTimeout関数の中身の関数などがコールバック関数と呼ばれる。

# [<font color="#333">7.JSの無名関数、即時関数について説明してください。</font>](#-7.JSの無名関数、即時関数について説明してください。)
無名関数は変数に関数を代入して定義する。巻き上げが起こらない。定義する前に実行しようとするとエラーが出る。即時関数は無名関数を（）で囲って使う。スコープを限定したい時に使う。

# [<font color="#333">8.JSのPromiseについて説明してください。</font>](#-8.JSのPromiseについて説明してください。)
JSは非同期処理で処理の順番待ちが出来ないのでJSの処理の順番を制御させる為のオブジェクト。
resolvedとrejectedで正常に処理できたか、失敗したかメッセージを受け取る。

# [<font color="#333">9.SessionとCokkieの違いについて説明してください。</font>](#-9.SessionとCokkieの違いについて説明してください。)
セッション・・・サーバー側で保存
クッキー・・・ブラウザ側で保存

# [<font color="#333">10.Bastionサーバーの必要性</font>](#-10.Bastionサーバーの必要性)
踏み台サーバーを使用する理由は、中継サーバーを作ることでセキュリティ対策を強化する端末を限定し、監視対象の絞り込みを可能にするため。踏み台サーバーより先はプライベートな通信にする事で外部からの侵入を防ぐ。
# [<font color="#333">参考</font>](#-参考)
https://ayaka-weblog.com/job-change/career-change/
前回laravelでアプリを作ったσ(ﾟ∀ﾟ )ｵﾚが初DjangoでWEBアプリ公開「買ってよかったー」を作成したよ

Djangoを使って初めてWEBアプリを作成しました。
ログインなしで使えるのでよかったら試してみてね。

https://yokatter.quality-of-life1.com/

プログラミング初心者の方もアプリ作成の参考にどうぞ。
この記事では苦労した点などについて書いていこうと思います。

## なぜ作ったか
よくサイトにある「買ってよかったもの」まとめサイトなどが大好きだから。
他の人がどんなものを買っているのか気になる。いいものがあったら自分も欲しい。よかったものを自分もシェアしたい。在宅ワークでおうち時間を良くしたい。などの思いがあり作成しました。
前回laravelで掲示板を作ったが、djangoも同じようなものだろと思い、勉強もかねてdjangoで作りました。

## 初のdjango laravelと比べて

laravelと比べて、導入や環境開発は簡単なでした。
laravelではdockerの導入や、ubuntuなどいろいろ導入をしたが、pythonさえ入っていれば？コマンドちょちょってすればできました。

今回アプリ作成に関して一番大変だったのは、デプロイかなー。
xserverへのデプロイでしたがエラー連発の末、どうにかデプロイできました、herokuや、awsを使うのが定石らしいのですが、あまりお金をかけたくないことから普段使っているxserverへデプロイしました。デプロイ時詰まったところはこの後、共有します。

アプリ作成に関しては、今回はlaravelで作成したWEBアプリ時とは違い、ログインなしで作成しました。そのためか、作成自体割とすんなりできました。
詰まったところは、外部キーの取得方法位？英語サイトも頑張って巡り情報を探してそれも解決。

ただlaravelと比べて、djangoのほうが日本語では情報が少ないような気がしました。
laravelで作成したおかげもあってか、前回苦労したDB設計もすんなりいけました。

## Xserver Django初デプロイ、エラー連発
正直、Djangoデプロイ？日本語記事出てきたしいけるっしょーくらいに思ってました。
それが半日くらい詰まってしまった。

xserverにデプロイのためか、英語記事は出てきませんでした。。

参考にさせていただいた記事たち。

https://kazusa-pg.com/xserver-django/

https://workspacememory.hatenablog.com/entry/2021/05/07/015923

https://datacoach.me/data/dx-edu/xserver-homebrew

https://qiita.com/joshnn/items/244ca701c1bf9be8f350

https://datacoach.me/data/dx-edu/xserver-python-miniconda-env/

https://next-k.site/blog/archives/2022/02/15/727

### しょっぱなからエラー！
こんなにも記事があるのに！！エラーが解消できません。。
xserverにlinuxbrewをインストールする必要があるのですが、git、curlのバージョンが古いため、できませんと出る。
どうにか頑張って、git、curlのバージョンアップをしたが、gitエラーでremote-httpsが使えません？的なエラーが解消できず、結局minicondaを使って簡単デプロイ、ローカル開発でminicondaを使ってなかったためできれば、pipenvを使いたかったが、挫折。。下記リンクの方と同じところまで？いきました。

https://datacoach.me/data/dx-edu/xserver-homebrew

ただ、勉強になりました。
+ xserverにソフト？（gitやopensslなど）を落とすのに
+ ダウンロード
+ 解凍
+ configの設定？
+ make
+ make install 

この手順でビルドが必要になるのがわかりました。
また、ビルドしたものは、パスを通して「このソフトを使うよ宣言」の必要があります。

普段、黒い画面をいじることは少ないのですが、いろいろ勉強になりました。

### やっとデプロイ！！しかししかしの500エラー原因は改行コード
いろんな記事を見ると、500エラー、よくあることみたいです。
私の原因はcgiの改行コードでした。cgiはCRLFではなくLFにしなければいけないみたいで、ここで数時間かかった。。。
おそらくxserverに直接cgiを作成し、それをvscodeで作成したのが悪かった？
普段改行コードなど気にしないので全然気づかなかったが、たまにすごい悪さをする。

下記記事が参考になりました。

https://www.tohoho-web.com/wwwxx011.htm

※vscodeに拡張機能code-eol を入れると改行コードが可視化できるよ

## 終わりに
一度CRUDを自力で作ってみると、ほかの言語での作成もほぼ似たようなものなので、laravelの時ほど難しく感じなかった。（成長？）
djangoはパイソンベースなので今後はpythonで機械学習や、データ分析などもやっていきたいなと思いました。
まだ知識が浅いのもあり間違えてるところなどありましたらご指摘ください。
Vim 8.4にしたら右クリックでペーストできなくなったときの対処

# 環境
Windows 10 Pro
Cygwin (setup 2.918)
Vim 8.4

# 経緯
setup.exeでzip/unzipをインストール（なぜか入ってなかった）
した際にvimも自動アップデートされた
8.2.0486-1 → 8.4.4372-1

# 問題
右クリックでペーストができなくなった。
正確にはその前段階のコンテキストメニューが表示されなくなった

# 対処法
vimの設定ファイルに下記を記述（ファイルがなければ作成）
```~/.vimrc
set clipboard=unnamed,autoselect
```

# 参考
環境は違うけど状況が似ていたので参考になりました。感謝
https://qiita.com/VA_nakatsu/items/b92771fcda9023cb2bb6
QueueServiceClientの利用時の注意点

## はじめに
.NET Core 3.1のEOLを前に.NET6への移行中に「Microsoft.Azure.Storage」が非推奨になっていたことが明らかになったため、「Azure.Storage.Queues」でのサンプルを実装し、稼働確認を行いました。

## サンプル
#### エンキューのサンプル
``` Csharp
public class EnqueueFunction
{
    [FunctionName("EnqueueFunction")]
    public void Run([TimerTrigger("*/10 * * * * *")]TimerInfo myTimer, ILogger log)
    {
        var queueItem = "テスト";
        log.LogInformation($"[{queueItem}]でQueueにエンキューを開始します。。");
        new QueueServiceClient("{{ConnectionString}}").GetQueueClient("myqueue-items").SendMessage(queueItem);
        log.LogInformation($"Queueへのエンキューが終了しました。");
    }
}
```

#### キュートリガーのサンプル
``` CSharp
public class QueueTriggerFunction
{
    [FunctionName("QueueTriggerFunction")]
    public void Run([QueueTrigger("myqueue-items", Connection = "AzureWebJobsStorage")]string myQueueItem, ILogger log)
    {
        log.LogInformation($"[{myQueueItem}]を受信しました。");
    }
}
```

#### 実行ログ
```
###### エンキューのサンプルログ ######
[テスト]でQueueにエンキューを開始します。。
Queueへのエンキューが終了しました。

###### キュートリガーのサンプルログ ######
System.Private.CoreLib: Exception while executing function: QueueTriggerFunction. Microsoft.Azure.WebJobs.Host: Exception binding parameter 'myQueueItem'. System.Private.CoreLib: The input is not a valid Base-64 string as it contains a non-base 64 character, more than two padding characters, or an illegal character among the padding characters.
```
#### エラーの内容

```
System.Private.CoreLib: Exception while executing function:QueueTriggerFunction. 
Microsoft.Azure.WebJobs.Host: Exception binding parameter 'myQueueItem'. 
System.Private.CoreLib: 
The input is not a valid Base-64 string as it contains a non-base 64 character, more than two padding characters, 
or an illegal character among the padding characters.
```
Base64でエンコードされていないとのこと。
以前は、「CloudQueueMessage」でBase64されていたが、その部分を実装しなければいけないのか？そんなことはなく、より開発しやすくなっており、QueueServiceClientのオプション設定でよいことがわかりました。

QueueClientOptions#MessageEncodingにBase64指定するだけの様子。

##### 改修後
``` CSharp
public class EnqueueFunction
{
    [FunctionName("EnqueueFunction")]
    public void Run([TimerTrigger("*/10 * * * * *")]TimerInfo myTimer, ILogger log)
    {
        var queueItem = "テスト";
        log.LogInformation($"[{queueItem}]でQueueにエンキューを開始します。。");
        new QueueServiceClient("{{ConnectionString}}", new QueueClientOptions()
        {
            MessageEncoding = QueueMessageEncoding.Base64
        }).GetQueueClient("myqueue-items").SendMessage(queueItem);
        log.LogInformation($"Queueへのエンキューが終了しました。");
    }
}
```
実際に稼働確認を行うと以下の通り正常に動作しました。

### 実行ログ
```
###### エンキューのサンプルログ ######
[テスト]でQueueにエンキューを開始します。。
Queueへのエンキューが終了しました。

###### キュートリガーのサンプルログ ######
[テスト]を受信しました。
```

## まとめ
ちょっと焦りましたが、都度、CloudQueueMessageを経由してEnqueueする手間が省けるので、より一層使いやすいSDKになったなと感心しました。
AWS Amplify ホスティングで Next.js CSRをホスティングするっピ

AWS Amplify ホスティングで Next.js CSRをホスティングした備忘録的な

* アプリ
nextjs + CSR(SPA)
SPAとはいえ、htmlファイルはlamda-edgeで書き出される

* 手法
他にもapp runner / serverless-nextjsもある

* リリース
カッコイイ、マジで。そして速い。githubと連携すると走り出す、マジで。ちょっと 感動。

アプリがgit直下に無い場合は、monorepoをチェック入れる
https://aws.amazon.com/jp/about-aws/whats-new/2020/06/amplify-console-supports-deploying-and-hosting-web-apps-managed-in-monorepos/

* 構成
** 他のリソース
cloud-front / lamda / s3あたりが生成される
生成されたリソースはデプロイフェイズのログに出力される
```
[INFO]: Beginning deployment for application xxxxxxxxxxxxxx, branch:master, buildId 0000000001
[INFO]: Deploying SSR Resources. Distribution ID: xxxxxxxxxxxxxx. This may take a few minutes...
[INFO]: Deployed the following resources to your account:
[INFO]: - CloudFront Domain ID: xxxxxxxxxxxxxx
[INFO]: - SSR Lambda@Edge: xxxxxxxxxxxxxx
[INFO]: - API Lambda@Edge: xxxxxxxxxxxxxx
[INFO]: - Image Optimization Lambda@Edge: xxxxxxxxxxxxxx
[INFO]: - S3 Bucket: xxxxxxxxxxxxxx
[INFO]: Deployment complete
```

* キャッシュ設定
ルートディレクトリにcustomHttp.ymlを設定する
https://docs.aws.amazon.com/ja_jp/amplify/latest/ug/custom-headers.html

monorepoの場合、記述方法が異なるので注意
``` customHttp.yml (monorepo)
applications:
  - appRoot: app1
    customHeaders:
....
```

** index.htmlとかのhtml生成が遅い問題
SPRなのでただの空htmlを返すだけだが、なんか遅い。
700ms-1000msかかる
=> キャッシュする
【8行】Pythonでシステム音を録音する方法

# 概要
スピーカーやヘッドフォンから出力されるシステム音を録音します。

# デモ
<iframe width="560" height="315" src="https://www.youtube.com/embed/7xQAhQWhLHs" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

# 環境
Windows 10とUbuntu 18.04での動作を確認しました。

# インストール
SoundCardとSoundFileをインストールします。

```bash
pip install SoundCard
```

```bash
pip install SoundFile
```

[ドキュメント](https://pysoundfile.readthedocs.io/en/latest/)によると、LinuxでSoundFileを使うためには**libsndfile**をaptなどのパッケージマネージャーでインストールする必要があるようです。

# ソースコード
[GitHub](https://github.com/tez3998/loopback-capture-sample)にも置いてあります。

```Python
import soundcard as sc
import soundfile as sf

output_file_name = "out.wav"    # 出力するファイル名
samplerate = 48000              # サンプリング周波数 [Hz]
record_sec = 5                  # 録音する時間 [秒]

with sc.get_microphone(id=str(sc.default_speaker().name), include_loopback=True).recorder(samplerate=samplerate) as mic:
    # デフォルトスピーカーから録音
    data = mic.record(numframes=samplerate*record_sec)
    
    # マルチチャンネルで保存したい場合は、"data=data[:, 0]"を"data=data"に変更
    sf.write(file=output_file_name, data=data[:, 0], samplerate=samplerate)
```

# 説明

```Python
with sc.get_microphone(id=str(sc.default_speaker().name), include_loopback=True).recorder(samplerate=samplerate) as mic:
```

get_microphone().recorder()で録音をするインスタンスを取得します。include_loopbackをTrueにすると、スピーカーやヘッドフォンなどから録音するインスタンスを取得できます。idとして、SoundCardが定めるデバイスのID（int型）かデバイスの名前（str型）が使えます。今回は現在システム音を出力しているデバイスから録音したいので、idをシステムのデフォルトのデバイスの名前にします。

```Python
data = mic.record(numframes=samplerate*record_sec)
```

record()でデバイスから録音します。1秒間にsamplerateフレームだけ録音されます。今回はrecord_sec秒間だけ録音したいので、numframesをsamplerate*record_secとします。録音したデータはnumpyの配列として、変数に格納されます。

```Python
sf.write(file=output_file_name, data=data[:, 0], samplerate=samplerate)
```
write()を使ってnumpyの配列をwavファイルとして出力します。モノラルで保存したい場合はdata=data[:, 0]とします。マルチチャンネルで保存したい場合はdata=dataとします。

# 上手く動かない条件
プログラムを開始するときに無音だと、プログラムが指定した秒数を待たずに終了してしまいます。現在、原因は不明です。ライブラリのバグかもしれないため、Issueを開きました（ https://github.com/bastibe/SoundCard/issues/166 ）。追記：Windowsにおけるこのバグはmasterブランチでは取り除かれました。リリースはまだです（ https://github.com/bastibe/SoundCard/pull/167 ）。
Profileable apkを使ってリリースapkで起動時に実際に何が時間がかかっているのかを確認する

# モチベーション

デバッグではランダムに時間が増えてしまうので、基本的にデバッグが有効の場合でプロファイルしても実際にかかっている時間は取れないです。ですが、これまではデバッグでしかプロファイルが取れなかったので、正確なものを見るには[OSごと書き換えたり](https://github.com/uber/nanoscope)とかしかなかったです。

ランダムに時間が増える図

<img src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27388/780a0171-ecb4-9e8d-3bfb-c5e1aa5c14a9.png width=400 />

https://www.youtube.com/watch?v=RgIxYwKNE88

それがAPI level 30で、Android Studio Bumblebee (2021.1.1) からProfileable apkが利用できるようになりました。

https://android-developers.googleblog.com/2022/01/android-studio-bumblebee-202111-stable.html

> Using the profileable flag instead of the debuggable flag has the key advantage of lower overhead for performance measurement; however, certain profiling features are not available for Profileable builds, such as the Event timeline, API initiated CPU profiling, heap dumps, or live location recordings.

# どうやってやるか

基本的には以下の通りなんです。

https://developer.android.com/studio/profile


ただこれは、すでにプロセスが起動している場合の手順なので起動時のパフォーマンス計測には使えません。Android StudioのEdit configuration -> Profileを使った方法も動かなかったです。 (Android Studio Bumblebee | 2021.1.1 Patch 2で確認)

そこでググってみると、以下のようなドキュメントが見つかります。

https://android.googlesource.com/platform/system/extras/+/master/simpleperf/doc/android_application_profiling.md

## アプリ側の設定
**この節のコードを入れてリリースしないようにしてください**

デバッグと同じキーストアを使って

```kotlin
    create("release") {
      storeFile = rootProject.file("keystore/debug.keystore")
      storePassword = "aaaa"
      keyAlias = "...."
      keyPassword = "aaaa"
```

お好みで、難読化だけ外します。

```kotlin
      postprocessing {
        isRemoveUnusedCode = true
        isRemoveUnusedResources = true
        isOptimizeCode = true
        // for profile
        isObfuscate = false
        proguardFile("proguard-rules.pro")
      }
````

以下をAndroidManifest.xmlのapplicationタグの下にいれます。

```xml
    <profileable android:shell="true"/>
```

あとはリリースビルドをしてapkを端末にインストールしておきます。 


## 実際のとり方

ここのtgzからtgzファイルをダウンロードして解凍します。

https://android.googlesource.com/platform/system/extras/+/master/simpleperf/scripts/

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27388/33897e6d-3586-4be9-a1bf-c07a2ebace3f.png)


以下のコマンドを打ち込むとアプリが起動するので、起動が終わったらCommand + Cで終了します。起動時のパフォーマンスのファイル `perf.data` を作ることができます。

```
 ./app_profiler.py -p パッケージ名 -a Activity名
```

これを表示するには基本的には./report.pyなどを動かすだけです。

## M1 Macで動かない？

この`perf.data`はAndroid Studioで使うことができません。変換する必要があります。
この変換は./report.pyなどで行われているのですが、M1 Macだと動かないバイナリがあり、現状動かないようです。以下のようにしてAndroid側で変換しちゃうことができます。

```
// Androidに送る
adb push perf.data /sdcard/Download/perf.data
// Android上で変換
adb shell /data/local/tmp/simpleperf report-sample --protobuf --show-callchain -i /sdcard/Download/perf.data -o /sdcard/Download/perf.trace
// 端末からpullする
adb pull /sdcard/Download/perf.trace
```

## Android Studioで読み込む

あとはAndroid StudioのProfilerからプラスボタンを押して、Load from fileでpullしたperf.traceを読めばプロファイルを見ていくことができます。これで具体的にこのメソッドが遅い！と特定していくことができます。

# まとめ

起動時のプロファイルを見ていくことができました。
もっとこうしたほうがいいよという方法がある方はぜひお教えください。 :pray:
IBMCloud DNS NSレコードの編集

## 目的
IBMCloudでドメインを購入し、NSレコードの編集が必要になった場合の変更方法を記載する。
一見、ポータル上では編集できないように見えるが厄介。

例えばCISを利用する場合、NSレコードをCIS指定のサーバにする必要があるので編集が必要


## 編集方法
はじめに、IBMCloudで購入したドメインの一覧があるページに移動する
https://cloud.ibm.com/classic/services/domains

1. **Lock Domain**を<font color=red>Unlocked</font>に変更
2. ドメイン名左の**▽**をクリックする。
3. **Add/Edit DNS**を選択 
![貼り付けた画像_2022_04_20_12_12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/703043/b83ff7fa-e83e-9c7a-bfce-b8d0d63c0e3e.png)

ポップアップ画面が開くため、**登録したいサーバ名を入力**する。
問題なければ、**Valid**が表示されるので、**Associate**をクリックして終了
![貼り付けた画像_2022_04_20_12_20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/703043/98675830-3ab2-186f-e14a-8e8619afdc71.png)
[備忘録]Dockerコマンド一覧

### イメージ取得/一覧/削除

```shell
・イメージ取得
docker image pull NAME[:TAG]

・イメージ一覧
docker image ls

・イメージ削除
docker image rm IMAGE_ID

・イメージ全削除
docker image prne
```
### コンテナ実行/一覧/停止/削除
```shell
・コンテナ実行　※イメージがローカルにない場合、DLから始める
docker container run -d NAME[:TAG]

・コンテナ一覧　※実行中のコンテナのみ
docker container ls

・コンテナ一覧
docker container ls -a

・コンテナ停止
docker container stop NAME

・コンテナ削除
docker container rm CONTAINER_ID

・コンテナ全部削除
docker container prune

```

### 省略コマンド
#### イメージ

|項目  |通常  |省略  |
|---|---|---|
|ビルド |docker image build |docker build |
|一覧  |docker image ls |docker images |
|取得  |docker image pull |docker pull |
|削除  |docker image rm |docker rmi |

#### コンテナ

|項目  |通常  |省略  |
|---|---|---|
|実行 |docker container run |docker run |
|停止  |docker container stop |docker stop |
|一覧  |docker container ls |docker ps |
|削除  |docker container rm|docker rm |

### イメージのビルド

```shell
docker build [OPTION] PATH
#  [OPTION] -t <NAME>[:<TAG>], -f <Doclerfile名>
```

### Docker Hub 公開
```shell
docker build -t <DockerHubのUsername>/<NAME>[:<TAG>] PATH

docker login
 Username: DockerHub_ID
 Password: 

docker push <DockerHubのUsername>/<NAME>[:<TAG>] 

#必要に応じて以下を実施
docker tag SRC_NAME[:TAG] TRG_NAME[:TAG]
# SRC_NAME タグづけしたいDockerイメージ
# TRG_NAME 追加したいタグ
```
コマンドがパイプされているかどうかをチェックする

# aptコマンドをパイプすると警告がでる

Ubuntuなどで apt コマンドをパイプすると, こういうWARNINGが出ます.

```
$ apt list --installed | grep apt

WARNING: apt does not have a stable CLI interface. Use with caution in scripts.
```

スクリプトやDockerfileなどでaptコマンドを使いたいなら, 安定したapt-getコマンドを代わりに使うべき, ということになります.



# コマンドがパイプされているかどうかの判定方法

ところで, コマンドの実行結果がパイプされているかどうかって, どう判定するのでしょうか.


## aptの実装

aptの実装は次のようになっています.

```cpp
if(!isatty(STDOUT_FILENO) &&
   _config->FindB("Apt::Cmd::Disable-Script-Warning", false) == false)
{
   std::cerr << std::endl
             << "WARNING: " << flNotDir(argv[0]) << " "
             << "does not have a stable CLI interface. "
             << "Use with caution in scripts."
             << std::endl
             << std::endl;
}
```

有り体にいうと, `isatty` 関数で判定しています.
これが false なら, パイプされているという意味.


## pythonで実装するなら?

file like object が でisatty が使えるので, それで判定できます.
```python
import sys

if not sys.stdout.isatty():
    print("warning", file=sys.stderr)
```


## シェルでやるなら?

とりあえずbashで.

testコマンドで判定できます.
`-t` にファイルディスクリプタを渡すと, それがターミナルに関連付けられているかどうかをチェックできます.
(false ならパイプされている)
(標準出力のファイルディスクリプタは 「1」)

> -t FD  file descriptor FD is opened on a terminal

```bash
if ! test -t 1; then # [ ! -t 1 ] も同じ
    echo "warning" >&2
fi
```
【Terraform】AWSにてRDSを作成する際の名前指定(aws_db_instance)

# はじめに
TerraformでRDSを作成する際に`aws_db_instance`を指定する際にDB名指定で引っかかったので、備忘録として記事にしたいと思います。

# 環境

|  項目  |  バージョン  |
| ---- | ---- |
|  Terraform  |  1.1.8  |
|  provider registry.terraform.io/hashicorp/aws  |  4.9.0  |
|  provider registry.terraform.io/hashicorp/random  |  3.1.2  |

```bash:バージョン
satsuton:Test ma-sato$ terraform -v
Terraform v1.1.8
on darwin_amd64
+ provider registry.terraform.io/hashicorp/aws v4.9.0
+ provider registry.terraform.io/hashicorp/random v3.1.2
satsuton:Test ma-sato$ 
```

# 経緯
Terraformにて以下のようにコードを作成し、`terraform plan`を実行。(リソース作成前の確認)
※実際のコードから一部抜粋しております。

```terraform:RDS作成コード
resource "aws_db_instance" "mysql_standalone" {
  engine         = "mysql"
  engine_version = "8.0.20"

~~省略~~

  name              = "tastylog"
  parameter_group_name = aws_db_parameter_group.mysql_standalone_parametergroup.name
  option_group_name    = aws_db_option_group.mysql_standalone_optiongroup.name

~~省略~~

  tags = {
    Name    = "${var.project}-${var.environment}-mysql-standalone"
    Project = var.project
    Env     = var.environment
  }
}
```

以下のWarningが表示される。

```bash:Warning
│ Warning: Argument is deprecated
│ 
│   with aws_db_instance.mysql_standalone,
│   on rds.tf line 76, in resource "aws_db_instance" "mysql_standalone":
│   76:   name                 =   "tastylog"
│ 
│ Use db_name instead
│ 
│ (and one more similar warning elsewhere)
```

# 対処方法
`name`を`db_name`に変更して`terraform plan`を再実行。

```terraform:RDS作成コード
resource "aws_db_instance" "mysql_standalone" {
  engine         = "mysql"
  engine_version = "8.0.20"

~~省略~~

  db_name              = "tastylog"
  parameter_group_name = aws_db_parameter_group.mysql_standalone_parametergroup.name
  option_group_name    = aws_db_option_group.mysql_standalone_optiongroup.name

~~省略~~

  tags = {
    Name    = "${var.project}-${var.environment}-mysql-standalone"
    Project = var.project
    Env     = var.environment
  }
}
```

**Warning**が表示されないことを確認。

# 解説
`aws_db_instance`にて`name`でDB名を指定することは非推奨で`db_name`でDB名を指定することを推奨しています。(2022/04/20現在)
そのため、`db_name`でDB名を指定したところ、Warning分が消えたということになります。

Terraformの公式ドキュメントにも`db_name`で指定する旨記載されております。

>db_name - (Optional) The name of the database to create when the DB instance is created. If this parameter is not specified, no database is created in the DB instance. Note that this does not apply for Oracle or SQL Server engines. See the AWS documentation for more details on what applies for those engines. If you are providing an Oracle db name, it needs to be in all upper case. Cannot be specified for a replica.

参考記事にも参考にしたZennの記事と公式ドキュメントのリンクを載せてあります。
そちらも併せてご覧下さい。

# 参考記事
https://zenn.dev/jun2021/articles/e752f436a6d9bb

https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/db_instance
Alpineコンテナの中でエイリアスを自動設定する

# はじめに

普段Railsを扱うことが多いのですが、他の方が作成したRails環境を触ったところRailsコマンドや、Rspecなどを実行するときに、最初に`bundle exec`をつけないと実行できなかったためかなりストレスに感じて、手入力でエイリアスを張っていましたがこれを自動化するにはどうすればよいのだろうと考え、できるようになったためまとめます。

# 問題

実際に動作していたRailsコンテナの中で起動時にエイリアスをはる設定をする障害になっていたのが

- Alpine Linuxを利用していた (.bashrcが存在しない)
- コンテナの中にはいるとrootユーザーではないユーザーでログインすることになる (/root以下をみることができない)

というところでした。またbashコマンド自体は入っていないので、どうすればエイリアスを張ればよいのだろうという状況でした。

# 解決方法

`/env/profile`を用いてエイリアスを張ることでうまくいきました。

まず`.alias`を作成しました。この中にはエイリアスのコマンドを書いておきます。

```.alias
alias rspec='bundle exec rspec'
alias rails='bundle exec rails'
alias rubocop='bundle exec rubocop'
```

このファイルをコンテナにコピーして、`/etc/profile`に追記するような処理を`Dockerfile`に追加します。

```Dockerfile:Dockerfile
ENV ENV="/etc/profile"
COPY .alias ./
RUN cat .alias > "$ENV"
```

ちなみに以下はエイリアスが効いていませんでした

```Dockerfile:Dockerfile
COPY .alias ./
RUN cat .alias > /etc/profile
```

# おわりに

Alpineを利用したRailsプロジェクトの場合起こることがあると思ったのでまとめてみました。
ネットの情報があるようでなく、思ったよりも時間がかかりましたが無事時間の短縮ができるようになりました。
そもそも`bundle exec`をつけないようにバージョン管理はしたいところです。
Nodeのコアモジュール名についている「node:」プレフィックスとは何か

## これはなに

Node.js 18 がリリースされましたね！

https://nodejs.org/ja/blog/announcements/v18-release-announce/

変更の中には、`node:test`というコアモジュールが追加されていたりしますが、そもそも`node:`ってなんなんだと思ったので、調べてみました。

## `node:`って何？

Node.js のコアモジュールを`require` / `import`する際に、`node:`プレフィックスをつけ、Node のコアモジュールであることを明示できるものです。
以下のような感じです。

```js:CommonJS
// 以下2つは同じ
const fs = require("fs");
const fs = require("node:fs");
```

```js:ESM
// 以下2つは同じ
import fs from "fs";
import fs from "node:fs";
```

Node.js のコアモジュールに対してつけることができ、 **`node:`をつけるつけないで動作は変わりません**。

また、`node:`プレフィックスは、Node.js 14 のマイナーバージョンアップによって追加されたようです。

https://github.com/nodejs/node/blob/master/doc/changelogs/CHANGELOG_V14.md#2021-09-28-version-14180-fermium-lts-targos

https://github.com/nodejs/node/issues/36098

## `node:`プレフィックスはつけたほうがいいのか？

結論、つけれるのであればつけたほうが良さそうです。

コアモジュールであることが明示的になるのもそうですが、Node.js 18 の変更点に含まれている`node:test`は **`node:`プレフィックスが必須** のモジュールです。
（初の`node:`プレフィックス必須のモジュールらしい）

> https://nodejs.org/ja/blog/release/v18.0.0/
> The node:test module facilitates the creation of JavaScript tests that report results in TAP format. To access it:
> import test from 'node:test';
> This module is only available under the node: scheme.

今後も`node:test`のようなモジュールが増えてくることを考えると、今から慣れておくのが良いかもしれません。

## さいごに

調べてみると、かなり前から`node:`プレフィックスが存在していたようで、驚きました。
今回の`node:test`を期に、広まっていくといいですね。

## Refs

- Node.js 18 リリースについて
  - https://nodejs.org/ja/blog/announcements/v18-release-announce/
  - https://nodejs.org/ja/blog/release/v18.0.0/
- `node:`プレフィックス追加について
  - https://github.com/nodejs/node/blob/master/doc/changelogs/CHANGELOG_V14.md#2021-09-28-version-14180-fermium-lts-targos
  - https://github.com/nodejs/node/issues/36098
- `require.cache`の動作について
  - https://nodejs.org/dist/latest-v18.x/docs/api/modules.html#requirecache
aws light sail に bitnamiを使わずにSSL設定

今回は yomiplus.com のドメインを利用。

https://qiita.com/ma7ma7pipipi/items/c995d581d73ec7711c00

上記を参考にした方が良いかも。

bitnamiがバグって上手く動かないので。
```

Bitnami installation directory

Please type a directory that contains a Bitnami installation. The default 
installation directory for Linux installers is a directory inside /opt.

Bitnami installation directory []: /opt/bitnami

```
の連続。心折れたので以下の方法でインスコ。

・nginx

# certbot をインスコ
```
sudo rpm -ivh https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
sudo yum install -y certbot
```


# nginxを止めて証明書発行

ここはスタンドアロンではなくwebrootモードでインスコしたほうがいい。
https://qiita.com/ma7ma7pipipi/items/adc96f41cd491a3219fe

```
service nginx stop
certbot certonly --standalone -d yomiplus.com ?webrootのがいい
```

1 メアドを入力してね(期限切れとか教えてくれる)
2 メルマガ送っていい？N

# これで成功。

そしてAAAAレコードにも設定してねと出るので、
awsのngworkingからAAAAレコードにもドメインを設定しておこう。

# nginxの設定
vim /etc/nginx/conf.d/default.conf

```
server {
    listen 443 ssl http2;
    server_name yomiplus.com;
    ssl_certificate     /etc/letsencrypt/live/yomiplus.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/yomiplus.com/privkey.pem;
}
```

# nginx restart
```
service nginx start
```
LS_COLORSを設定する気にならなかったのでvividをいれてみた


wslをつかってみようとWSLでUbuntuを入れてみたが、lsの色が目に刺さるので、変更方法を探していた。
LS_COLORSという環境変数で変更するらしい。

だが、設定方法を覚える気にならないのといい感じの色で出したいだけなので、`ls LS_COLORS theme` でググったら、vividというのを見つけた

https://github.com/sharkdp/vivid

使い方は気に入ったテーマを探して、.bashrcとか.bash_profileとかで以下のようにLS_COLORSを設定すればよいとのこと

```bash
export LS_COLORS="$(vivid generate molokai)"
```

プレビューはないが、設定しながらlsしてくださいみたいなスニペットがあるので、それで確認する。
背景色が苦手なので、snazzyというのに落ち着いた。

設定はfiletypes.yamlというファイルで拡張子毎にカテゴリー分けされているようで、カスタマイズも簡単そうな気がする。
crystal の AtCoder における Deque の使用による速度改善

# はじめに
AtCoder さん、いつもお世話になっております。

私は、下記のトランスパイラを夢見ている者ですが、`Deque`の使用により実行時間の改善が見られましたので、ここに投稿いたします。

https://github.com/superrino130/crystal-on-paiza.cloud
# 003 - Longest Circular Road（★4）
https://atcoder.jp/contests/typical90/tasks/typical90_c

```diff_crystal
n = read_line.to_i
- ab = Array.new(n + 1){ [] of Int32 }
+ ab = Deque.new(n + 1){ [] of Int32 }
- f = Array.new(n + 1, 0)
+ f = Deque.new(n + 1, 0)
(n - 1).times do
  a, b = read_line.split.map(&.to_i)
  ab[a] << b
  ab[b] << a
end
- que = [] of Int32
+ que = Deque(Int32).new
f[1] = 1
que << 1
while que.empty?.!
  r = que.shift
  ab[r].each do |x|
    if f[x] == 0
      f[x] = f[r] + 1
      que << x
    end
  end
end
que << f.index(f.max).not_nil!
- f = Array.new(n + 1, 0)
+ f = Deque.new(n + 1, 0)
f[que[0]] = 1
while que.empty?.!
  r = que.shift
  ab[r].each do |x|
    if f[x] == 0
      f[x] = f[r] + 1
      que << x
    end
  end
end
puts f.max
```
ここでは、何も考えずに`Array`を`Deque`に書き換えます。

||Array|Deque|参考(Ruby)|
|:--:|--:|--:|--:|
|実行時間(ms)|664|84|249|

`Array`版では、トランスパイル前の`Ruby`版より遅かったのですが、それが改善されました。
# crystal#Deque
https://crystal-lang.org/api/0.33.0/Deque.html

> Deque has a subset of Array's API. It performs better than an Array when there are frequent insertions or deletions of items near the beginning or the end.
Dequeには、ArrayのAPIのサブセットがあります。最初または最後の近くでアイテムの挿入または削除が頻繁に行われる場合は、配列よりもパフォーマンスが向上します。

公式の通り`push`/`pop`/`shift`/`unshift`で速くなる様です。
デメリットは、分かる範囲ですが、`sort`メソッドがないことです。
# D - Cylinder
https://atcoder.jp/contests/abc247/tasks/abc247_d

```diff_crystal
q = read_line.to_i
- a = Array(Array(Int64)).new
+ a = Deque(Array(Int64)).new
q.times do
  que = read_line.split.map(&.to_i64)
  if que[0] == 1
    a << [que[1], que[2]]
  else
    ans = 0i64
    t = que[1]
    while t > 0
      b = a.shift
      if t >= b[1]
        t -= b[1]
        ans += b[0] * b[1]
      else
        ans += t * b[0]
        a.unshift([b[0], b[1] - t])
        t = 0
      end
    end
    puts ans
  end
end
```
`Array`版では`TLE`になりますが、`Deque`版は高速です。
||Array|Deque|参考(Ruby)|
|:--:|--:|--:|--:|
|実行時間(ms)|TLE|119|356|
# まとめ
`crystal`の`Deque`使用により実行時間が改善される場合があることが分かりました。
繰り返し二乗法で行列のべき乗の高速化


**【例題】 以下の行列の$10^8$乗を剰余 100007で求めよ**

```math 
\large 
\begin{pmatrix} 
2 & 2 & -2 & 1\\
1 & 0 & 0 & 0\\ 
0 & 1 & 0 & 0\\ 
0 & 0 & 1 & 0
\end{pmatrix}
```

まずは素直にnumpyのmatrixを用いて書いてみますが、これでは$10^6$までが精いっぱい。

```python 
import numpy as np
N, M = 10**6, 100007
m = np.matrix([[2,2,-2,1],[1,0,0,0],[0,1,0,0],[0,0,1,0]], dtype='object')
print(m**N % M)
#[[87688 87212 96356 67590]
# [67590 52515 52039 31522]
# [31522 4546 89478 15076]
# [15076 1370 74401 19623]]
```
行列の高速化としては対角化等の技法があるようですが、今回はNが大きいのと剰余を取るので繰り返し二乗法を使います。アルゴリズムは以下のような簡単なものです。

1. 与えられた行列を$2^k$がnを超える直前まで$k$回2乗を行う
1. 残った$n-2^k$に対して1.を繰り返す、これを残りが１になるまで続ける。

関数**powmtx**は引数に、行列**mtx**、べき乗の数**n**、剰余**M**を与えると答えの行列を返します。

```python 
import numpy as np
def powmtx(mtx,n,M):   # mtx: matrix, n: power, M: modulo
  if n == 0: return np.eye(len(mtx), dtype='object')
  if n == 1: return mtx
  m2, p2 = mtx, 2
  while p2 < n:
    m2 = (m2*m2)%M
    p2 *= 2
  return powmtx(mtx,(n-p2//2),M)*m2 % M
```
この**powmtx**を使って例題を解くと$10^8$も問題なく解くことが出来ました。どこまで出来るか試してみましたが$10^{100}$位までは楽勝でした。

```python
N, M = 10**8, 100007
m = np.matrix([[2,2,-2,1],[1,0,0,0],[0,1,0,0],[0,0,1,0]], dtype='object')

print(powmtx(m, N, M))
#[[81734 3148 15339 71658]
# [71658 38425 59846 58648]
# [58648 54369 21136 77135]
# [77135 4385 106 75399]]
```
（開発環境：Google Colab）
Lightning Implementation Specialist



[Lightning Implementation Specialist Badge: Developer Edition Org doesn't have custom object](https://trailhead.salesforce.com/ja/trailblazer-community/feed/0D54S00000G5OyJ)

サポート付きの電話がありました。新しい開発組織を再作成し、オブジェクトがそこにあったため、一時的な問題であった可能性があります（以前にもこれを行いました）。ですから、これを解決する唯一の方法は、あとがきを再試行することだと思います。
Tableau CRM and Einstein Discovery Insights Specialist 


最近できたのかな？見たことなかった。

[Tableau CRM and Einstein Discovery Insights Specialist](https://trailhead.salesforce.com/fr/content/learn/superbadges/superbadge_analytics_insights_specialist)


# Step 5

+ [Tableau CRM and Einstein Discovery Insights Specialist - Step 5 - Deliver a Solution to Reduce Subscriber Attrition](https://trailhead.salesforce.com/ja/trailblazer-community/feed/0D54S00000A8eBLSAZ)
+ [Tableau CRM and Einstein Discovery Insights Specialist Challenge 5](https://trailhead.salesforce.com/ja/trailblazer-community/feed/0D54S00000Bs6eN)

# Step 6

**We can't confirm you mapped the correct fields on the Tenure model. Make sure you only have one model under your prediction, check the model fields, avoid using fields that may cause data leakage, and try again.**

[Tableau CRM and Einstein Discovery Insights Specialist - Challenge 6](https://trailhead.salesforce.com/ja/trailblazer-community/feed/0D54S00000H0HWQ)
UbuntuにDockerをインストールする手順

# 事前知識

- [【2019年最新】VirtualBoxでUbuntuの仮想環境を作る方法](https://qiita.com/ryome/items/56e8ee3d5e27bf514e60)
- [wsl2のインストール方法【windows】](https://qiita.com/ryome/items/240f36923f5cb989da27)

# UbuntuにDockerをインストールする手順

1.パッケージをアップデートする
- コマンド
```
sudo apt-get update
```

- 実行例
```
$ sudo apt-get update
[sudo] password for ユーザ名:
ヒット:1 http://jp.archive.ubuntu.com/ubuntu focal InRelease
```

2.必要なパッケージをインストールする
    - `Do you want to continue? [Y/n] ` が表示されたら、 `y` を入力する
- コマンド
```
sudo apt-get install apt-transport-https ca-certificates curl gnupg-agent software-properties-common
```

- 実行例
```
$ sudo apt-get install apt-transport-https ca-certificates curl gnupg-agent software-properties-common
パッケージリストを読み込んでいます... 完了
依存関係ツリーを作成しています
状態情報を読み取っています... 完了
```

3.キーを登録
- コマンド
```
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key
```

- 実行例
```
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
OK
```

4.ダウンロードサイトをaptリポジトリに登録
- コマンド
```
$ sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
```

- 実行例
```
$ sudo add-apt-repository \
> "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
> $(lsb_release -cs) \
> stable"
ヒット:1 http://jp.archive.ubuntu.com/ubuntu focal InRelease
取得:2 https://download.docker.com/linux/ubuntu focal InRelease [57.7 kB]
ヒット:3 http://jp.archive.ubuntu.com/ubuntu focal-updates InRelease
```

5.Docker Engine一式をインストール
- コマンド
```
sudo apt-get update
sudo apt-get install -y docker-ce docker-ce-cli containerd.io
```

- 実行例
```
$ sudo apt-get update
ヒット:1 http://jp.archive.ubuntu.com/ubuntu focal InRelease
ヒット:2 http://jp.archive.ubuntu.com/ubuntu focal-updates InRelease
ヒット:3 http://jp.archive.ubuntu.com/ubuntu focal-backports InRelease
ヒット:4 https://download.docker.com/linux/ubuntu focal InRelease
ヒット:5 http://security.ubuntu.com/ubuntu focal-security InRelease
パッケージリストを読み込んでいます... 完了
```

```
$ sudo apt-get install -y docker-ce docker-ce-cli containerd.io
パッケージリストを読み込んでいます... 完了
依存関係ツリーを作成しています
状態情報を読み取っています... 完了
以下の追加パッケージがインストールされます:
  docker-ce-rootless-extras docker-scan-plugin git git-man liberror-perl pigz slirp4netns
```

6.Dockerを利用できるようにする
- コマンド
```
sudo gpasswd -a ユーザ名 docker
```

- 実行例
```
$ sudo gpasswd -a ユーザ名 docker
Adding user ユーザ名 to group docker
```

7.ログオフする
- コマンド
```
exit
```

8.Dockerのバージョン確認
- コマンド
```
docker -v
```

- 実行例
```
$ docker -v
Docker version 20.10.12, build e91ed57
```

## wsl2のUbuntuを使用してDockerコマンド実行時にエラーが出た場合
以下のエラーが発生した場合、Docker再起動を行う。

```
Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?
```

### Docker再起動
- コマンド
```
service docker stop // Docker停止
service docker start // Docker開始
```

- 実行結果
```
$ sudo service docker stop
 * Docker already stopped - file /var/run/docker-ssd.pid not found.
$ sudo service docker start
 * Starting Docker: docker
```
Docker Compose作成方法

# 1. 事前知識
- [Dockerファイル構築]()
- [Dockerコマンド一覧]()

事前知識として、上記リンクの内容が必要です。

# 2. Docker Compose作成方法

- Docker Composeインストールコマンド

```
sudo curl -L "https://github.com/docker/compose/releases/download/1.27.4/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
```

- Docker Composeバージョン確認

```
docker-compose --version
```

- Docker Compose起動
    - `docker-compose.yml` ファイルがある場所でコマンドを打たなければならない
```
docker-compose up -d 
```

- Docker Compose状況確認

```
docker-compose ps 
```

- Docker Compose停止

```
docker-compose down 
```

---

### docker-compose.yml の基本書式

- `docker-compose.yml` の書き方

```
version: "バージョン値"
services:
  コンテナ名:
    build: Dockerfileのパス 
    ports:
      - "ホスト側のポート:コンテナのポート"
  コンテナ名:
    image: "イメージ名"
    ports:
      - "ホスト側のポート:コンテナのポート"
```

- `docker-compose.yml` の例

```
version: "3.8"              ── 1 
services:                   ── 2 
  myweb:                    ── 3
    build: .                ── 4
    ports:                  ── 5
      - "8080:80" 
  apache:                   ── 3
    image: "httpd:latest"   ── 6
    ports:                  ── 5
      - "80:80" 
```

**【説明】** 
1.  version ········· docker-compose.yml のバージョン。 
2.  services ········ 起動するサービス群。以下ネストした要素でコンテナを定義 
3.  コンテナ名 ···· 任意の名前（例：  mysample、busybox） 
4.  build ············· Dockerfile からビルドする場合、ビルドコンテキストのディレクトリを指定 
5.  ports ············· ポート転送を指定 
6.  image ··········· イメージからコンテナ生成する場合、イメージ（リポジトリ、タグ）を指定 

- よく使うコマンド

| 項目           | 意味                                                                                                    |
| -------------- | ------------------------------------------------------------------------------------------------------- |
| image          | 利用するイメージ                                                                                        |
| ports          | ポートのマッピングの設定                                                                                |
| build          | docker-compose.ymlファイルを実行し、ビルドされるときのpath                                              |
| volumes        | マウントするボリュームを指定する                                                                        |
| environment    | 環境変数を指定                                                                                          |
| restart        | コンテナの起動に失敗したときの再起動ポリシーの設定 (always:どんな終了ステータスでもいつも再起動する等） |
| networks       | 接続するネットワークを指定                                                                              |
| logging        | ログ出力先を指定する                                                                                    |
| dns            | DNSサーバーを指定する                                                                                   |
| container_name | コンテナ名の指定                                                                                        |

---
Dockerファイル構築

# Dockerファイル構築

- ベースイメージを指定

```
FROM <image>

または

FROM <image>:<tag>
```

---

- Dockerfile 内で使用する変数を定義

```
ARG <name>[=<default value>] 
```

---

- イメージの構築中に実行するコマンドを指定

```
RUN <command> 

または

RUN ["executable", "param1",  "param2"] 
```

---

- イメージにファイルやディレクトリを追加

```
ADD <src>… <dest> 

または

ADD ["<src>",… "<dest>"] 
```

---

- イメージに、ローカルホスト上のファイルやディレクトリを複製

```
COPY <src>… <dest> 

または 

COPY ["<src>",… "<dest>"] 
```

---

- コンテナ実行時にリッスンするポート番号を指定

```
EXPOSE <port> [<port>…] 
```

---

- 環境変数を定義

```
ENV <key> <value> 

または 

ENV <key>=<value> …
```

---

- コンテナ実行時にデフォルトで行う処理を指定

```
CMD ["executable", "param1", "param2"] 

または 

CMD ["param1", "param2"] 

または 

CMD <command> <param1> <param2>
```

- コンテナ実行時に実行する処理を指定

```
ENTRYPOINT ["executable", "param1", "param2"] 

または 

ENTRYPOINT <command> <param1> <param2>
```

---

- Dockerfile のコメント

```
# <comment> 
```
Docker汎用コマンド集

# Docker汎用コマンド集

- Apacheコンテナを作成、実行

```
docker container run --name myapache -d -it -p 8000:80 -v /tmp:/usr/local/apache2/htdocs httpd
```

--- 

- コンテナ内にファイルをコピー

```
sudo docker cp コンテナID:コピー先パス コピー元パス
sudo docker cp コピー元パス コンテナID:コピー先パス
```

--- 

- コンテナにボリュームをマウント

```
docker run -it --mount source=ボリューム名,target=マウント先パス イメージ名:Tag名
```

--- 

- コンテナをすべて削除

```
docker rm -f $(docker ps -a -q)
```

--- 

- イメージをすべて削除

```
docker rmi -f $(docker images -q)
```

--- 

- ボリュームをすべて削除

```
docker volume rm $(docker volume ls -q)
```

--- 

- 起動中のコンテナにコマンドを実行する 

```
docker exec -it コンテナ名 /bin/bash
```
【WSL2】WSL2側からホストのlocalhostで立っているAPIサーバーのAPIをcURLで叩く方法

# 概要

WSL2側からホストのlocalhostにアクセスする方法です。  
WSL2側からホスト側に立てたAPIサーバーに、cURLでAPIを叩きたいと思った際にハマったので備忘録として残しておきます。

# 手順

## 1. nameserverのIPアドレスを取得する

### ホスト側で`ipconfig`を実行し、確認する方法

ホスト上のコマンドプロンプト等で`ipconfig`を実行し、`WSL`の`IPv4`アドレスを確認します。

```cmd
イーサネット アダプター vEthernet (WSL):

   接続固有の DNS サフィックス . . . . .:
   リンクローカル IPv6 アドレス. . . . .: foo::bar:foo:bar:foo
   IPv4 アドレス . . . . . . . . . . . .: 172.***.***.1
   サブネット マスク . . . . . . . . . .: 255.255.240.0
   デフォルト ゲートウェイ . . . . . . .:
```

### WSL2上側で確認する方法

`/etc/resolv.conf`の`nameserver`のIPアドレスを確認します。

```bash
$ cat /etc/resolv.conf

# This file was automatically generated by WSL. To stop automatic generation of this file, add the following entry to /etc/wsl.conf:
# [network]
# generateResolvConf = false
nameserver 172.***.***.1
```

## 2. nameserverのIPをもとにWSL2側でcurlを使用し、APIを叩く

あとはWSL2側からcurlコマンドを使用し、APIを叩くだけです。

```bash
$ curl -X GET http://172.***.***.1/foo
```

# 参考文献

- [Accessing network applications with WSL -Accessing Windows networking apps from Linux (host IP)-](https://docs.microsoft.com/en-us/windows/wsl/networking#accessing-windows-networking-apps-from-linux-host-ip)
- [WSL2からWindowsホストで動作しているアプリケーションにアクセスする](https://logico-jp.io/2019/08/26/access-an-app-running-on-windows-host-via-wsl2/)
jQueryのアコーディオンメニュー作成

# 概要
案件でjQueryを使用してアコーディオンメニューを作成したのでメモ

```html:index.html
<div class="">
	<p class="">a</p>
	<p class="">b</p>
	<p class="">c</p>
</div>
<div class="accordion close">閉じる</div>
```
```js:accordion.js
$(function(){
    $('.accordion').click(function(){
        $(this).toggleClass('close open');
        if ($(this).hasClass('open')) {
            $(this).text('詳細');
        }
        if ($(this).hasClass('close')) {
            $(this).text('閉じる');
        }
        $(this).prev('div').slideToggle();
    });
});
```
toggleClass()はカンマ区切りで複数のクラスを制御できるらしい
A2 hostingを検討する

# 目的

Xサーバの代替サーバを求めて検討

# サーバの応答速度

https://www.a2hosting.com/about/data-center

A2 Hostingはアメリカの会社だけど、スピードにこだわっていて、データセンターを以下から選択ができる

* USA - Michigan (75.98.175.109)
* USA - Arizona (68.66.224.6)
* Europe - Amsterdam (68.66.248.31)
* Asia - Singapore (103.227.176.4)

でも、実際にスピードがどうなの？ってのはあって、気になっていましたが、こちらのサイトで各データセンターとのダウンロード、アップロード、PING応答などが確認できるそうです。

# メール配信

メールアカウントを作ると、SPFやDKIMの設定までしてくれます。
配信は1アカウント1日に1000通ぐらいがリミットみたいです。

PHPBBを運用していたら1日1000通以上のメールはでなくて、通知が止まったという相談
=> https://www.phpbb.com/community/viewtopic.php?f=661&p=15805371

一斉配信には未対応です。
=> https://www.a2hosting.com/kb/does-a2-hosting-support/do-you-support-sending-bulk-mail
Safie APIとTensorflowjs で物体検出モックアップを作った話の続き

**@kenmaro**です。
普段は主に**秘密計算、準同型暗号などの記事について投稿しています**。
秘密計算に関連するまとめの記事に関しては以下をご覧ください。

> - [秘密計算エンジニアを始めて２年半が経った。](https://qiita.com/kenmaro/items/48059dd60f79e80f5ef8)
> - [秘密計算エンジニアを始めて3年が経った。](https://qiita.com/kenmaro/items/a1d90a074d552b7bf886)


## 忙しい人のために最初に宣伝
**この度我々が個人開発する「YorimichiApp」はAndroid版を正式リリースしました。**

アンドロイドユーザの方は、ぜひこちらからアプリをダウンロードしてみてください。

https://play.google.com/store/apps/details?id=com.agrimetal.yorimichi2

また、iOSユーザの方でまだダウンロードしていない人は、ぜひこちらからどうぞ。

https://apps.apple.com/jp/app/yorimichiapp/id1596625712


また、アプリ紹介のためのランディングページはこちらから。

http://yorimichiapp.com/


## この記事の概要
この記事は、

https://qiita.com/kenmaro/items/1a10611392bd23da7620

この記事の続きとなります。

基本的には、このモックアップで行ったコードを

https://github.com/kenmaro3/safie-image-recieve-nextjs

ここにプッシュしました、というだけです。

簡単ではありますがレポジトリの内容を少しだけ書き留めておきます。

## レポジトリの内容

Nextjs, Tensorflowjs　を用いて、
SafieAPIを用いて取得した画像に対して、クライアントサイドで物体検出のAI推論を実行するモックアップです。
取得した画像をCanvasに表示したりするところは多くの場面で使いまわせると思います。
アプリケーションによって、適用するモデルの種類を変えたりすればいろいろな面白いことができそうですね。
また、Tensorflowjsを用いることで、クライアントサイドでAIを使えるため、わざわざPythonなどのバックエンドを構築しなくて良いですし、非常に構成がコンパクトになって良い気がしました。

```bash

yarn install
yarn dev

```

を実行すると、以下の画面が見えます。

![Screen Shot 2022-04-20 at 10.30.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/519792/4bea2b70-e59b-113c-c68d-49d524299482.png)


#### FrontCamera 

FrontCamera はテストのために、
PCのフロントカメラから動画を取得してCanvasに描画、
その動画のフレームに対してTensorflowjsを用いてクライアントサイドで物体検知を行います。

#### SafieCamera
SafieCamera の方は、safie APIの画像取得APIを使うことで、
Safie カメラで取得した画像に対して同じようにクライアントサイドで物体検知を行います。

## 注意点

大体のことはコードをそのまま見てもらえるとそのまま転用できると思いますが、
Safie APIを呼ぶのはバックエンド、つまり　Nextjs において　`api/`
でAPIを呼ぶ必要があります、そうしないとCOR問題が発生しました。

```api/ai_safie.ts
export default async function handler(req: NextApiRequest, res: NextApiResponse) {

    console.log('here1')
    res.setHeader('Content-Type', 'image/jpeg')

    var instance = axios.create({
      'responseType': 'arraybuffer',
      'headers': {
        'Content-Type': 'image/jpeg'
      }
  });

    const tmp = await axios.get('https://openapi.safie.link/v1/devices/xxxxxxxxxxxxxx/image', { // xxxxxxxxxxx にデバイスIDを書く
        headers: {
            Authorization: `Bearer yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy`, // yyyyyyyyyyyy にbaarer トークンを書く

        },
        responseType: "arraybuffer"
    })

    
    console.log('here2')
    console.log(tmp);

    // res.setHeader('Content-Length', tmp.data)
    //res.send(base64Encode(tmp.data))
    res.send(base64Encode(tmp.data))
    res.status(200).end()


}
```

上の箇所がAPIを読んで画像を取得していること路ですが、2ヶ所のコメントのところに自分のデバイスのID,
及び取得したtokenを記載すると、うまく画像取得ができるかと思います。



## 最後に

簡単ではありましたが、このように

Nextjs, Tensorflowjs　を用いて、
SafieAPIを用いて取得した画像に対して、クライアントサイドで物体検出のAI推論を実行するモックアップ

を簡単に作った時のコードを公開したので、使いまわせるところは使いまわせたらなと思っています。


今回はこの辺で。


@kenmaro
多能工と専門家

Agile開発には、開発対象の機能（ストーリーという）の単位で一人でこれを受け持って開発して（コーディングしたり）試験して本番環境にデプロイして、と全工程を完結できる多能工「フルスタック・エンジニア」と呼ばれる人々で開発チームを組成して臨む、という哲学があります。今回はこの件について書こうと思います。

<b>専門家と呼ばれる人たち</b>

音楽などの芸術家、スポーツ関連の選手、そしてITの専門家も不思議なもので、その後それで「生活ができる」という次元に能力を高めている方々というのは、20歳よりも若い段階で自ら、自発的に動いて何らかの専門的分野に取り組み始めているという経験則があります。

私自身で言うと今こうしてIT系の分野で専門家として仕事をしていますが、この分野について一番最初に取り組んだのは、1年間の浪人が明けたすぐ後のタイミングから（20歳になる年の春でした）自作パソコンに関しての本を読んで秋葉原に出向き、部品をそろえて自分のマシンを組み上げたという経験があります。この自作PCは、当時まだマニアックだった3DCGの制作をやるにはビデオカードにそれなりに拘った、メモリも潤沢に積み、光線の挙動計算にも対応できるそれなりにCPUパワーのあるマシンというのはプリセットの筐体ではなかなか手に入らなかったので、自分で組み立てるしかなかったということがありました。そのために組み上げたマシンでした。

どれだけ教育のカリキュラムが充実していたとしても、この手の「自発性」を持った人以上に専門性を高めた人間を量産するというのは至難の業で、ITに関してそもそも興味を持ってない人に対してどんなに充実したカリキュラムのIT系の専門学校に通ってもらってもホントに育ちません。カリキュラムで受け身で学習できるのはせいぜい、1日4－5時間。しかし専門家足りうるにはこのインプットの時間に加えて自分なりに試行錯誤して何かを組み上げたりといった「自学」の時間がそのインプットの時間以上に必要になります。この時間を持つことに何らの苦を感じない、むしろ楽しんで取り組むというのがもはや「才能」と呼べる領域になり、専門家になるにはこの有無が決定的に重要になります。

<b>得難いAgileの多能工</b>

ひとつ、これという専門分野があれば御の字なのですが（例えばJavaが書ける、ネットワークの構築ができる、DBが構築できるといったこと）Agileで必要になってくるのは一人で複数の専門分野を跨いでシステムを組み合わせてサービスと呼べる次元にまで仕立ててしまうという人間です。いたら間違いなく助かるし、「これができる」「あれができる」ということでそのスキルセットを定義することも可能なのですが、必要な能力を増やせば増やすほど級数的にその人材というのはレアな存在になっていきます。

そんな多能工でチームを組んでシステムを作るのですから、それは間違いなく効率がいいし素晴らしいものができるであろうことは想像に難くないのですが、いかんせんそういう人たちは「得難い」のですべてのプロジェクトがそんな恵まれたリソースをそろえて体制が組めるはずもありません。

<b>現場はどうか</b>

フルスタックエンジニアだけをそろえてチームが組めるかというと現実はそうならず、そうなるとチームのメンバーは自ずと「DBが得意」「コーディングが得意」という形で職能というか専門性でどうしても別れたチームになります。こうなると、一人でストーリー（バックログのチケット）を担当して完結するということは現実的に難しくなる。結局、複数人数で「バーチャルな一人の多能工」的なものを作り上げて担当するしかありません。

理想は間違いなく一人ですべてを完結できるエンジニア。しかし、そういう天才的な人材をそろえて開発できるというのはよほどの高収益を上げるソフトウェアを売っているかそれでサービスを提供しているかという事業体であって、ここでもまた、Agileの哲学というのは現実に直面して補正を余儀なくなれます。