OmniAICreator/Qiita-1.07M huggingface dataset:
ArgoCDのIngressをContourでローカル環境で公開する方法

# Helmfileでの指定

```yaml
releases:
  - name: argocd
    namespace: argocd
    createNamespace: true
    chart: argo/argo-cd
    version: 3.26.8
    values:
      - server:
          extraArgs:
            - --insecure
          ingress:
            annotations:
              kubernetes.io/ingress.class: contour
            enabled: true
            hosts:
              # 127.0.0.1.nip.ioを指定するとドメイン登録なしで希望のIPにドメインでアクセスできる
              - argocd.127.0.0.1.nip.io 
```

HelmfileでArgoCDをインストールしない場合でHelmを使っていれば同様にValuesに指定する。Helmを使っていない場合は下記のようなIngressリソースを作成する。Ingressの作り方はArgoCDのドキュメント[Ingress Configuration](https://argo-cd.readthedocs.io/en/stable/operator-manual/ingress/)を参照する。

# kindの設定

kindでKubernetesクラスタを起動する際に、ホストポートをContourが使用するコンテナポートにマッピングする指定を行う。

```yaml:clusterconfig.yaml
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
  kubeadmConfigPatches:
  - |
    kind: InitConfiguration
    nodeRegistration:
      kubeletExtraArgs:
        node-labels: "ingress-ready=true"
  extraPortMappings:
  - containerPort: 31080 # expose port 31080 of the node to port 80 on the host, later to be use by kourier or contour ingress
    hostPort: 80
    protocol: tcp
  - containerPort: 31443 # expose port 31443 of the node to port 443 on the host, later to be use by kourier or contour ingress
    hostPort: 443
    protocol: tcp
```

# 注意事項

KnativeでContourを使っている場合は、`contour-external`と、`contour-internal`にそれぞれインストールされているため、 `contour-external` を指定する。
「性別」の変数名をsexにしないで

# NG

これだとセックス感が強すぎます。

ふと目に入ったときにびっくりしてしまいます。

```javascript
class User {
  name: String
  age: Number
  sex: Number
}
```

しかも、enumで型が数値型になった日にはあらぬ誤解を生むかもしれません。

![Screenshot from 2021-11-19 20-33-51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151137/e2a4a94f-5c3a-55dd-d006-7d664b434070.png)

# Good

代わりに`gender`を利用しましょう。

```javascript
class User {
  name: String
  age: Number
  gender: Number
}
```

# 英語の意味

|sex|gender|
|---|---|
|生物学的な性別|社会的な性別|

というニュアンスの違いがあります。

一部の例外を除き、ほとんどのWebサービスにおいて扱われる人間の性別は、ユーザープロフィール的な用途で、英語の意味的にも`gender`が適していそうです。

# 追記

sexが適している場合もあるとのコメントをいただきましたが、書いた僕自身としても、全てのケースで一律にgenderで表記するべきという主張をしたかったわけではありません。

国際規格ISO 5218については、これは生物学的な性別を示す場合の規格ですので、社会的性別を表現する際にgenderを使うことを否定するものではないかと思います。

この記事を見てこれから命名する方も、記事及びコメントを参考で判断してもらえればと思います。
Windows10のフォルダ毎のでディスク領域を確認する

**課題**：WindowsPCのディスク領域が少なくなり始めている。ディスク領域を空けるためにフォルダ毎のディスク領域を調べる。
**手順**：
Window10には標準でフォルダ毎のディスク領域を表示する機能がある。その機能を利用してフォルダ毎のフォルダ毎のディスク領域を調べる。
1.左下のWindowsロゴをクリックして「設定」を選択する。<br/>![windows_disk_space_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698027/b02d22c0-c875-9491-8cdd-ccbb2256df60.png)
1.「システム」を選択する。<br/>![windows_disk_space_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698027/42685a61-4873-20a5-252f-b784f3b9c921.png)
1.「記憶域」を選択する。<br/>![windows_disk_space_3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698027/b81a9f6e-57f3-92fe-490c-a9f1bed47b6c.png) 
1.フォルダ毎のディスク領域が表示される。フォルダをクリックするとサブフォルダ毎のディスク領域が表示される。![windows_disk_space_4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698027/319f6c0f-e472-42cf-233d-b8d437111bfe.png)

以上
AttributeError: module 'pandas.io.common' has no attribute 'EmptyDataError'


read_csvで空のcsvを読むときにエラーが生じてしまうため、csvが空のときエラーを返す処理を入れた。

```:python
l=14 # number of files
for i in range(len(l)):
    try:
        file_name="./"+str(l)+"_test.csv"
    except EmptyDataError:
        print("ERROR: {} is empty".format(i))
```
しかし、
下記のエラーメッセージが出る。

```
EmptyDataError: No columns to parse from file

During handling of the above exception, another exception occurred:

NameError                                 Traceback (most recent call last)
<ipython-input-5-15b8cfd9c905> in <module>
      7 
      8         #print(tmp_df)
----> 9     except EmptyDataError:
     10         print("ERROR: {} is empty".format(i))
     11         next

NameError: name 'EmptyDataError' is not defined
```

AttributeError: module 'pandas.io.common' has no attribute 'EmptyDataError'
その対処法を調べたところ、pandas 1.1.5辺りから
参照先が変わったらしい。
https://ameblo.jp/altair265/entry-12644270493.html

from pandas.errors import EmptyDataError
の一文を入れて実行したら、エラーはでず、問題解決した。

```:python
from pandas.errors import EmptyDataError
l=14 # number of files
for i in range(len(l)):
    try:
        file_name="./"+str(l)+"_test.csv"
    except EmptyDataError:
        print("ERROR: {} is empty".format(i))

```

```
ERROR: 8 is empty
ERROR: 10 is empty
     max  width  n.sample  
0         0.439           -1.04     500.0   
1         0.490           -0.96     500.0   
2         0.439           -0.96     500.0   
```
Sync Gateway利用方法：アクセス確認

## アクセス確認


### 目的
管理REST APIを使用して、以下を確認することができます。

- ユーザーがアクセスできるチャネル

- ロールがアクセスできるチャネル

- ドキュメントが割り当てられているチャネル

### コンテクスト
ユーザーアカウントの`all_channels`プロパティによって、ユーザーがアクセスできるチャネルが決まります。その値は、次の和集合から導き出されます。

- 管理RESTAPIを使用して設定されるユーザーの`admin_channels`プロパティ。

- ドキュメントの現在のリビジョンに対して呼び出されたSync関数からの`access()`呼び出しによって、ユーザーがアクセスを許可されたチャネル。

- ユーザーが属するロールの`all_channels`プロパティ。これは、上記のルールを介して決定されます。

## エンドポイントの種類と利用法

### ユーザー

`/{tkn-db}/_user/{name}`エンドポイントにGETリクエストを送信します。

ユーザー`pupshaw`のアクセスを確認します。

```BASH
curl http://localhost:4985/db/_user/pupshaw
```

以下の出力からユーザー`pupshaw`は、以下のチャネルにアクセスできることがわかります。

- `all`チャネル（`admin_channels`設定を通じて）
- `hoopy`チャネル（`froods`ロールの`admin_channels`設定を通じて）

```JSON
{
    "admin_channels": [
        "all" 
    ],
    "admin_roles": [
        "froods"
    ],
    "all_channels": [
        "all",
        "hoopy" 
    ],
    "name": "pupshaw",
    "roles": [
        "froods"
    ]
}
```

### ロール

`/{tkn-db}/_role/`エンドポイントにGETリクエストを送信します。

ロール`frood`のアクセスを確認します。

```
curl http://localhost:4985/db/_role/frood
```

以下の出力からロール`frood`は、以下のチャネルにアクセスできることがわかります。

- `hoopy`チャネル（`froods`ロールの`admin_channels`設定を通じて）

```JSON
{
    "name": "froods",
    "admin_channels": [
        "hoopy" 
    ],
    "admin_roles": [
        "froods"
    ],
    "all_channels": [
        "hoopy" 
    ]
}
```

### ドキュメント

`/{tkn-db}/_alldocs`エンドポイントにGETリクエストを送信します。

キー`ourdoc`を持つドキュメントがどのチャネルにアサインされているかを確認します。

```
curl http://localhost:4985/ourdb/_all_docs?channels=true&keys=[ourdoc]" -H "accept: application/json"
```

以下の出力からドキュメント`ourdoc`は、`all`と`hoopy`チャンネルに割り当てられていることがわかります。
このドキュメントは、`hoopy`へ割り当てられているため、`froods`ロール、したがって、`pupshaw`ユーザーが利用することができることが分かります。


```json
{
  "id": "ourdoc",
  "key": "ourdoc",
  "value": {
      "channels": [ 
          "short",
          "hoopy"
      ],
      "rev": "1-86effb929acbf953905dd0e3974f6051"
  }
}
```

## 関連情報

https://docs.couchbase.com/sync-gateway/3.0/access-control-how-control-document-access.html
S3のオブジェクト一覧をaws-cliのワンライナーで取得する

# 概要
掲題の通りです。需要があるかはわかりませんが・・・。

# 経緯
どのオブジェクトが一番容量を食っているか (=どのオブジェクトが一番金食い虫か) をcliのみで手軽に調べるためのコマンドを書きました。
結果的には1バケットずつ見て行った方が早かった気もしますが・・・。

# 前提・動作環境
Windows10 + Git Bashで動作確認しています。

:::note warn
バケット数・オブジェクト数が多い場合のご利用は自己責任でお願いします。
また、このコマンドではオブジェクト名とサイズは判明しますが、所在までは明らかになりません。
:::

- Git Bash (Git)

```
git version 2.34.0.windows.1
```

- AWS CLI

```
aws-cli/1.22.6 Python/3.8.5 Windows/10 botocore/1.23.6
```

# コマンド

```
aws s3 ls --profile hoge | awk '{print $3}' | sed -r 's#(.*)#aws s3 ls s3://\1 --recursive --profile hoge#g' | bash | sort -k 3nr,3 > s3.txt
```

# 出力イメージ

```
2019-08-29 09:57:21  727810048 hoge.dmp
2019-08-02 16:47:55  144961536 fuga.dmp
...
```

# 雑な解説 (左から順に)

もっといい方法や出力を見やすくする方法などがあれば是非教えてください。

1. ```aws s3 ls```でバケットリストを出力する
1. ```awk```で1. の結果からバケット名だけ取得する
1. ```sed```でバケットの内容を表示するためのコマンドを生成する
1. 3. の結果を```bash```で実行する
1. 4. の結果をファイルサイズ (3番目) で降順ソートする
1. 5. の結果を適当なテキストファイルに出力する

以上、3年と9か月ぶりの投稿でした。
【新機能】OCI 証明書サービスを試してみる

2021/10/27、OCIの証明書サービス機能リリースのニュースが走りました。
AWSでは証明書サービス（ACM）があるのに、OCIでは証明書を外部発行しなくてはいけないのはもやもやポイントでしたので、個人的には嬉しいリリースです。
本記事ではサービス概要と、使い方を簡単に紹介します。
https://docs.oracle.com/en-us/iaas/releasenotes/changes/d4780264-da69-4ee6-9a9e-806562dbe0c6

## 証明書のサービス概要

まずは証明書のサービス概要について紹介します。
本サービスは今までOCIのサービス範囲外で実施していた、「証明書」、「認証局」に関する
「作成」と「運用/管理」のマネジメントサービスとなります。(CAバンドルも同様に作成/運用が可能)
また、CloudGurdやFLB等の他OCIサービスと連携しての利用も可能です。

![Certificates比較.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1946634/0ad07d4c-cc24-eb3e-e05a-3023ae28c44d.png)

　

# 証明書の作成手順
せっかくなので、Certificatesを利用してゼロから証明書を発行してみます。
発行手順ですが大まかに以下の流れとなります。

1. IAMリソースの作成
1. Voults作成→HSM作成(RSA!)
1. ルートCA作成　有効期間前にしない。削除の構成の内容を要確認
1. 証明書を作成


各内容についてちょっとだけ詳しくご紹介します。

###1. 【事前準備】IAMリソースの作成
証明局を新規で作成するためには、作成する認証局が**ボールト(Vaults)キー**を利用して
**Object Strage**を操作ができる必要があります。
（筆者は最初、この手順を忘れて権限エラーとなりました。）
この要件を満たすためには、以下タスク実施する必要があります。[【参考】公式マニュアル](https://docs.oracle.com/en-us/iaas/Content/certificates/managing-certificate-authorities.htm#:~:text=%E5%B1%80%E3%81%AE%E7%AE%A1%E7%90%86-,%E5%BF%85%E8%A6%81%E3%81%AAIAM%E3%83%9D%E3%83%AA%E3%82%B7%E3%83%BC,-%E3%82%B3%E3%83%B3%E3%82%BD%E3%83%BC%E3%83%AB%E3%81%AE%E4%BD%BF%E7%94%A8)

1. 証明書関連サービスを対象とする動的グループの作成
2. ValutsおよびObjectStrageの利用許可するポリシーの作成



**1. 証明書関連サービスを対象とする動的グループの作成**
    1. アイデンティティとセキュリティ => 動的グループを選択
    2. 動的グループの作成より、「一致ルール」で下記の通りにルールを定義

```resource.type ='certificateauthority'```


**2. ValutsおよびObjectStrageの利用許可するポリシーの作成**
    1. アイデンティティとセキュリティ => ポリシーを選択
    2. ポリシーの作成より、動的グループがVaults・objectstorageを操作するためのポリシーを作成
```Allow dynamic-group <DG名> to use keys in compartment DEF```
```Allow dynamic-group <DG名> to manage objects in compartment XYZ```


### 2. 【事前準備】Voultsの作成
証明局を作成するためには、鍵が必要となります。
このタスクを完了するためにはOCI ボールト(Voults)を構築して
ボールトで暗号化キーを作成する必要があります。

1. アイデンティティとセキュリティ => ボールトを選択
2. ボールとの作成より認証局を作成するコンパートメントを指定してボールトを作成
3. ボールトを作成したら,キーの作成よりHSMキーを非対称キーで作成<font color="Blue">（HSMの非対称キー(RSA/ECDSA)のみ利用可）</font>

### 3. ルートCAの作成
動的グループ、ポリシー、ボールトを作成したら、いよいよ認証局構築の準備整いました。
コンソールから作成する場合は、アイデンティティとセキュリティから認証局を選択して
画面指示に沿って進めれば迷うことはないはずです。


1. 基本情報　　　　： 認証局の作成よりルート証明書、認証局名を選択して「次」を選択
2. サブジェクト情報 ：任意のサブジェクト情報を入力
3. 権威の構成　　　  ：認証局の有効期限を設定し、作成したボールト、鍵を指定
4. ルール　　　　　 ：証明書の最大有効期間、下位CAの有効期間を入力
5. 失効構成　　　　 ：証明書失効リスト(CRL)を構成する場合は、保存先のObjectStrageを指定
6. サマリー　　　　 ：設定内容を確認して問題なければ作成


### 4.証明書の発行
プライベート認証局を作成できたので、証明書を発行します。
コンソールから作成する場合は、アイデンティティとセキュリティの証明書から「証明書の作成」を選択するか
作成済認証局から「証明書の発行」を選択することで証明書を作成できます。
今回は作成済認証局から「証明書の発行」の場合の手順を記載します。

1. 基本情報 　　　　　：証明書タイプを選択。作成したCAによって管理するか選択
2. サブジェクト情報　 ：任意のサブジェクト情報を入力
3. 証明書構成　　　　 ：プロファイルタイプ/有効期限を選択。OCI管理時は証明書キーペア情報を入力
4. ルール　　　　　　 ：更新間隔と拡張更新期間（有効期限が切れる何日前に更新可能か）を設定
5. サマリー　　　　　：設定内容を確認して問題なければ作成。証明書発行


## おわりに
今回は、念願の証明書サービスがリリースされたということで
サービスの超概要と、使い方をご紹介させていただきました。
OCIの独自サービス強化/追加も嬉しいですが、証明書等一般クラウドとして求められるサービスの充実もまた嬉しいですね。
新機能やOCI独自機能についても、また記事書いていきたいと思います。
C# for文を用いてテキストファイルを100個作成する方法

★「１つのフォルダには同じ名前のファイルは作れない」という基本のことに注意

```
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;

namespace for文 //ここはプロジェクト名なのでなんでもよい
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            for (int i = 0; i < 100; i++)
            {
                 File.CreateText($@"C:\Users\8100825\Documents\ファイル作成_{i.ToString()}.txt");
            }
        }
    }
}
```

「開始」→「button1」の順に押すと、画像のように、「ドキュメント」フォルダに「ファイル作成_0.txt」～「ファイル作成_99.txt」が作られる。

![スクリーンショット (26)_LI.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2207701/68c5818f-b91f-add3-baff-c191527cd6f1.jpeg)
npm start でファイルが多すぎて開けないと言われたときのエラー解決備忘録 (ubuntu18.04 x npm)

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

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

## 概要
npm start をしようとしたとき、

```
Too many open files
```

的なことでエラーを吐きサーバがスタートしない。
macでは問題なく通っていたのだが、ubuntuに開発環境を移してからこのエラーとなった。

## 問題となっていること
ubuntuで一度にユーザが開けるファイルの数に制限が設けられており、それに引っかかっている。

```
ulimit -n
ulimit -a
```

などで制限がいくつになっているか確認できる。

私の場合は、

```
ulimit -n
1024
```

となっており、npmが走らせるファイルの数が一時的にそれを超えていたものと思われる。


## 解決方法

制限の上限を上げてやれば良い。

ubuntu ulimit modify

などと検索すれば出てくるが、手順としては

`/etc/systemd/user.conf`
`/etc/systemd/system.conf` 

を sudo vim して、以下を追加。

```
DefaultLimitNOFILE=65535
```

`/etc/security/limits.conf`

を　sudo vim  して、以下を追加。

```
* hard nofile 65535
* soft nofile 65535
```

## 注意点
この２つのファイル修正後、ログアウトしてログインすると修正が反映されるということがどのウェブサイトにも書いてあったが、
自身の環境だと、一度電源を落として再ログインする必要があった。(restart ではなく、power off) --> なにが違う？？

編集するファイル自体はあっていたが、power off しなければならないことに気づかず、何が間違っているのか困ったため、
もし困った人がいたら試してみると良いかもしれない。



## まとめ

今回はubuntuにおけるulimit 、とりわけ最大オープンファイル数のリミット解除についてまとめた。


今回はこのへんで。

@kenmaro
Matter.jsでcanvas上でスクロールできる方法

案件だmatter.jsを使ったのでそこで詰まったポイント紹介いたします。

#スクロールできない
matte.jsではcanvas上でスクロールできないみたいです、、

#解決方法
removeEventListenerでスクロールできるようにする。

```javascript

//マウス操作
var mouseConstraint = MouseConstraint.create(engine, {
  element: container, //マウス操作を感知する要素を指定（DEMOでは生成したcanvasを指定）
  constraint: {
    render: {
      strokeStyle: "rgba(0, 0, 0, 0)", //マウス操作の表示を隠す
    },
  },
});
//以下のコードを記述
mouseConstraint.mouse.element.removeEventListener(
  "mousewheel",
  mouseConstraint.mouse.mousewheel
);
mouseConstraint.mouse.element.removeEventListener(
  "DOMMouseScroll",
  mouseConstraint.mouse.mousewheel
);


```
マウス操作を記述してるコードの下に、removeEventListenerを記述してください。

#まとめ
PCはこれでスクロールもドラックもできるようになるのですが、スマホはできないままです。。
スマホでもスクロールできる方法あれば教えてください。
Git 個人的取り消しチートシート

# はじめに
Gitでいろいろやらかしそうな僕のために、ワーキングツリー・ステージ（インデックス）・ローカルリポジトリ（コミット）ごとの取り消し方法をまとめます。  

# ワーキングツリーの変更取り消し

```
# 特定のファイル・ディレクトリの変更を取り消し
$ git checkout -- <ファイル名 or ディレクトリ名>

# カレントディレクトリ配下の全ての変更を取り消し
$ git checkout -- .
```

最新のステージ（インデックス）をワーキングツリーに反映することで、ファイル等への変更を取り消している。
`--`を付けるのは、`git checkout <ブランチ名>`によるブランチの切り替えと区別するため。ブランチ名とファイル名・ディレクトリ名が被っていなければ`--`は不要。
なお、2019年8月のGitのアップデートでversion 2.23.0がリリースされ、`git restore`コマンドが追加されたため、このコマンドでワーキングツリーおよびステージ（インデックス）の変更取り消しができるようになりました。

```
# 特定のファイル・ディレクトリの変更を取り消し
$ git restore <ファイル名 or ディレクトリ名>

# カレントディレクトリ配下の全ての変更を取り消し
$ git restore .
```

ちなみに、`git restore`と同時に追加された`git switch`でブランチの切り替え等ができるようになりました。

# ステージ（インデックス）の取り消し

```
# 特定のファイル・ディレクトリのステージングを取り消し
$ git reset HEAD <ファイル名 or ディレクトリ名>

# カレントディレクトリ配下の全てのステージングを取り消し
$ git reset HEAD .
```

最新のコミットをステージ（インデックス）に反映することで、ファイル等のステージングを取り消している。
上でも書いた通り、`git restore --staged` でも取り消し可能。

```
# 特定のファイル・ディレクトリのステージングを取り消し
$ git restore --staged <ファイル名 or ディレクトリ名>

# カレントディレクトリ配下の全てのステージングを取り消し
$ git restore --staged .
```

# ローカルリポジトリ（コミット）の取り消し

先ほども出てきた`git reset`コマンドでコミットの取り消しを行うこともできます。
`--mixed（デフォルト）`, `--hard`, `--soft` の各オプションでコミットを取り消す際の挙動を変更可能。


```
# 直前のコミットまで遡る
$ git reset HEAD^
```

また、こちらは取り消しというより修正ですが、間違った内容をコミットしてしまった後に、正しい内容に修正し、`git add`してから実行することで、直前のコミットを修正できます。
`git add`をせずに、これだけ実行することで、コミットメッセージだけ修正することも可能。

```
# 直前のコミットを修正
$ git commit --amend -m "コミットメッセージ"
```

そして、`git revert`を使うことで、他のコミットで行われた変更を元に戻す新しいコミットを作成できます。「間違った内容をコミットしちゃったけど、そのコミットを打ち消したよっ」という新しいコミットを行うコマンドです。

```
# コミットを取り消して、元に戻したよ、というコミットを作成
$ git revert <取り消したいコミットID>
```

# まとめ
似たようなスペルのコマンドがいくつもあって、僕のような初心者にはGitはとっつきにくいですね...

https://git-scm.com/docs/git

公式ドキュメントの「Reset, restore and revert」のところを読むと、
`git restore`と`git reset`の一番大きな違いは、
前者はブランチを更新しないが、後者はブランチを更新すること、と言えそうです。



あとで、`git rebase`も追記したいです。
私が技術ブログを書く理由

はじめまして、[booci bocci](https://boccibocci.com)を運営している@shoji-kaiと申します。
ITエンジニアの傍ら熊本県南阿蘇村にて水稲栽培をしている兼業農家です。

最近ではアグリテックという言葉が持て囃されております。
高齢化が顕著な農業の世界において、アグリテックの進歩はその大きな手助けになると思っているので、私も大変意義のあることだと感じています。
ですが、ドローンにしろ自動走行トラクタにしろ、現状においては基本的に大規模農業を想定して研究・開発が進められていると思います。

もちろん、それはそれで大いに意義のあることなのですが、私の住む南阿蘇のような中山間地であったり、個人や家族経営規模の小さな農家であったり、農薬や肥料を撒かない自然栽培にはコスト的にも規模的にもいささか大袈裟になってしまいます。

私は、研修期間から含めると今年で約6年間農業という世界の末席に加えさせていただいておりますが、そこで感じることは栽培作業自体よりもバックオフィス業務に非効率な部分がまだまだ多いということです。

栽培に関する作業の流れに関しては、本当に効率的です。
とにかく農作業は忙しく時間が足りないので、作業工程であったり、物の配置であったり、至るところで無駄のないように効率化の工夫がなされています。
私が研修を始めたときに、「農家ってこんなに効率的なんだ！」と一番衝撃を受けたことでありました。

一方で、バックオフィス業務になると途端に非効率な手作業メインの仕事が多くなります。
ですが、これは致し方のないところでもあります。
私の知る農作業に従事する方の多くは60代以降でパソコンやスマホなどに慣れておりません。
昔からやられている農家さんの多くにとってはそのやり方で特に困っていないわけで、むしろパソコンやスマホを覚えることのほうがストレスでしょう。
私がおすすめしたとしても「要らん」「分からない」「代わりにやって」と言われるのが目に見えています。

それでも私が技術ブログを書こうと思ったのは、「こういうものがあるんだ」「こういうことができるんだ」ということをなるべく身近に感じ取ってもらえればと思ったからです。
さすがにプログラミングを覚えるのは敷居が高いでしょうが、Google Appsをはじめ無料で使える便利なツールが世の中にはたくさんあります。
それらを取り入れるだけでも事務作業の効率化であったり、経費削減であったり、仲間内や集落での情報共有・情報伝達に役立てたり、いろいろと使い所はあると思います。

それらを使うかどうかは個人の自由ですが、そういうもの・やり方が世の中にあるということを知っておくだけでも、今後何かの役に立つかもしれません。
そういうわけで、bocci bocciは農業にも使えるニッチな技術ブログを書いていければと思っております。

以上
JAVA　基礎的メソッドの扱いと引数、返り値について。

現在会社でJAVA研修を受けているのでそのアウトプットとして残したいと思います。


##1. クラスとは、、

クラスとはオブジェクトの「状態・性質」と「機能」をまとめたもの。

「状態・性質」をあらわす情報を**フィールドまたはプロパティ**、クラスの「機能」をあらわす情報を**メソッド**といいます。

```Man.java
package test;

public class Man {
　　public static void main(String[] agrs) {
　　　　　
　　　 int age;
      String name;

     
	}
}

```

このコードはオブジェクトを作成するための Man クラスです。

変数二つが宣言されていますが、これらの変数が Man クラスの**フィールド**になります。

##2.オブジェクトの作り方

```Profile.java
package test;
public class Profile {

 public static void main(String[] args) {
  Man manData = new Man();

    manDate.age = 23;
    manData.name = "shun";
  
    System.out.println(name + "は" + age + "歳");

 }
}

```
オブジェクトは**Man manData = new Man();**になる。
クラスManをmanDateと名前を付けクラスProfileで使えるようにしている。
manDataにはクラスManのフィールドが入っているので**manDate.age = 23;**とすることで使用、代入することができる。


##3.メソッドについて、、

メソッドとは「処理」を 1 つの機能としてまとめたもの。
メソッドとして定義する事でコードの中で使いまわせることができる。

```Age.java
package test1;

public class Age {

int age;

void show() {
System.out.println(age);

   }
}

```

```Content.java
package test1;
public class Content {
 public static void main(String[] args) {

 Age showAge = new Age();
 
 showAge.age = 20;
 
 showAge.show();
 }
}

```


この部分がメソッドで機能としてはageをコンソールに表示させるものになる。

```Age.java
void show() {
System.out.println(age);
  }
```
メソッドには**返り値**と**引数**を設定できる。voidには返り値の型指定ができ、
メソッド名の（）には仮引数を指定できる。

##4.引数と返り値

端的に言えば返り値はメソッドの最終的な値で、引数は値を受け取るための受け皿になる。引数の場合、メソッドに設定できるのは仮引数と言い使うには変数に代入して使う。

```Jon01.java

package MyCode;
public class Jon01 {
	double point3(double shoot, double not) {

		double pro =  shoot / not * 100;

		   return pro;
     }
}

```


```Sam01.java

package MyCode;
public class Sam01 {
	  public static void main(String[] args) {

		  Jon01 Jon = new Jon01();

		  double pp = Jon.point3(6, 13);

		  System.out.println("3p成功率は" + pp);

     }
}

```
こちらのコードはバスケの3ポイントシュートの成功率をコンソールします。


Jon01.javaで定義されているpint3メソッドは**引数でshootとnot**を**返り値でpro**を返している。

Sam01でJon01をオブジェクト生成し使えるようにします。

変数ppにてpoint３に6と13を引数に渡します。この時引数を設定していないと値を受け取れません。

渡された値はpoint3のproで計算され、proが返り値によって返されます。
**double pp = Jon.point3(6, 13);**によりpoint3のリターンはppに代入されているので**System.out.println("3p成功率は" + pp);**で結果をコンソールできます。

####今の値の流れについて。

①変数ppからpoint3に(6, 13)を渡す。

②point3の引数で(6, 13)を受け取り変数proで計算。

③point3の返り値でproをリターン。

④リターンした値が最終的に変数ppに入る。

⑤コンソールでppを表示するとリターンした値が表示（計算結果）。
Couchbase Lite機能解説：ピアツーピア同期〜機能説明（セキュリティ、エラー処理など）

## はじめに

Couchbas Liteのピアツーピア同期の機能について解説します。

関連する記事は、以下で確認してください。

https://qiita.com/yoshiyuki_kono/items/6a5bbad1b02196a25417

## セキュリティ

### 通信のセキュリティ
Couchbase Liteのピアツーピア同期は、以下の複数のモードによる通信のセキュリティをサポートします。

- 暗号化のない基本認証

- CA証明書

- 自己署名証明書

- 自己署名証明書: IDが指定されていない場合、自動生成されたTLS IDが生成されます。これによって、認証なしの暗号化が実現されます。自動生成された自己署名証明書は、安全なストレージに保存されます。

また、レプリケータ（クライアント）は、証明書のピンニング（ピン留め）を処理できます。


### 認証

ピアツーピア同期は、基本認証とTLS認証をサポートします。サポートされているTLSの最小バージョンはTLS1.2です。

`URLEndpointListener`を使用したピアツーピア同期は、デフォルトでTLSを使用して暗号化されます。


### シークレット情報の管理
TLSを使用する場合、キーおよび証明書を保存する際には、セキュアなストレージを使用することが情報です。

このストレージの実装は、プラットフォームごとに異なります。 Androidでは、Android　KeyStore（Android API 18から導入）を使うことができます。

- Android　KeyStoreはされました。

- Android KeyStoreのセキュリティは、より安全なサポートを提供するために時間とともに進化してきました。詳細については、次のドキュメントを確認してください：

## エラー処理
リスナーが停止すると、接続されているすべてのレプリケーターにWebSocketエラーが通知されます。

アプリケーションは、一時的な接続エラーと永続的な接続エラーを区別する必要があります。

#### パッシブピア
アクティブピアとの接続が失われたパッシブピアは、そのピアに関連付けられているエンドポイント接続をクリーンアップします。アクティブピアは、パッシブピアへの再接続を試みる場合があります。

#### アクティブピア
パッシブピアとの接続を永久に失ったアクティブピアは、複製を停止します。

パッシブピアとの接続を一時的に失ったアクティブピアは、指数バックオフ機能を使用して再接続を試みます。

## その他の機能

### デルタ同期
デルタ同期サポートが提供されています（デフォルトではオフになっています）。

デルタ同期は、レプリケーションごとに有効にできます。

デルタとして送信されたリビジョンの総数など、デルタ同期の使用に関する統計が利用可能です。

### 競合解決
ピアツーピア同期の競合解決は、Sync Gatewayレプリケーションの場合と同じように機能し、カスタム解決と自動解決の両方を利用できます。







https://developer.android.com/training/articles/keystore

## 機能詳細に関する制約・留意点



## 関連情報

https://docs.couchbase.com/couchbase-lite/3.0/android/p2psync-websocket.html

https://www.digicert.com/jp/blog/certificate-pinning-what-is-certificate-pinning

> 証明書のピンニング（ピン留め）とは何ですか？

> 証明書のピン留めは、特定のWebサイトで有効と見なされる証明書を限定し、リスクを制限します。パブリック証明書ならどれでも使えるようにするのではなく、運用者は発行認証局（ CA ）、公開鍵、または選択したエンドエンティティ証明書さえも「固定」します。そのサーバーに接続するクライアントは、他のすべての証明書を無効として扱い、HTTPS接続の確立を拒否します。

> ピン留めにより、Webサイトは誤発行、 認証局の危殆化、中間者攻撃のリスクに対してコントロールが可能になります。ピン留めは、ユースケースに応じていくつかのやり方があります。クライアント機器のトラストストア内で唯一利用可能な証明書としてピン留めしたり、公開鍵ハッシュをコードに書き込んで、自分の鍵だけが信頼されるようにすることもできます。ピン留めが一般的になり始めたときには、複雑さを追加する過程が加わることで、悪意のある攻撃者が攻撃やなりすましに証明書を悪用することが困難になると期待されていました。


https://developer.android.com/training/articles/keystore

https://source.android.com/security/keystore
Qiitaアドベントカレンダーのバグを回避する方法

<font color="red">サンフランシスコ時間11月17 19:45に修正を確認しました。よかったよかった。</font>

Qiitaのアドベントカレンダーを見ていた。

https://qiita.com/advent-calendar/2021/iotlt

何かがおかしい。ふとそんな気がした。

![2021-11-15_18h29_09.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33704/ee655855-68f0-1499-6ac6-1cc8e06227e7.jpeg)

僕の知っているカレンダーとは何かが違う。いやもしかして僕がカレンダーという概念を間違って認識しているのでないか。

そう思い、１２月２日の前日の３０日をクリックして参加しようとしてみた。

![2021-11-15_18h29_56.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33704/ccecde24-acf2-4b3a-0758-9f7d6a72fd52.jpeg)

僕は確かに２日の前日である３０日をクリックし参加をしようとした。

![2021-11-15_18h30_25.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33704/389eca9a-d84c-400d-acbf-3b1f310f1eff.jpeg)

エラーになる。

いや、たしかに３０日は日付にあった。だけども、アドベントカレンダーという定義において３０日という日付は存在するのだろうか？

僕は多少の混乱をともないつつも、あれは３０日ではなく１日ではないのかという小さな疑問を晴らすためにChromeで検証することにした。

![2021-11-15_18h31_26.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33704/76bd3931-556a-e505-8d31-72e8fe1ed2fa.jpeg)

参加ボタンをクリックすると date: 30 というパラメータが飛んでいる。

![2021-11-15_18h32_23.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33704/c9a346a9-a41a-d7f4-6d4d-4d0bfca62086.jpeg)

graphql を右クリックし Copy -> Cpoy as fech とする。

![2021-11-15_18h32_59.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33704/19a6f179-57aa-9e46-d496-6e3811d5257a.jpeg)

それを Console に貼り付け date を１日に変更し Enter を叩いた。

![2021-11-15_18h49_13.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33704/3fec6c39-d60b-8c21-c1fc-a28f4e2f8cc6.jpeg)

無事に２９日のあとに１日が作られた。

これはなんなのだろうか。やはり Qiita に試されているのだろうか。この程度の問題を乗り切れないエンジニアには参加する資格はないと。

コーヒー豆焙煎機の記事書きます。おしまい。

https://qiita.com/advent-calendar/2021/iotlt
gh-pagesを使ってBitbucketで静的ページを公開する

Bitbucketで静的ページを公開する場合、GitHubとは異なりレポジトリ単位で柔軟に設定することはできません。(2021/11/16時点)
`<workspaceID>.bitbucket.io` というレポジトリを作成し、そこにファイルを置く必要があります。
しかしこのレポジトリ名スキームではワークスペース毎に1つしか作成できません。
また静的ページのソースを管理するレポジトリと公開用レポジトリが異なるため、デプロイが面倒という問題があります。
そこでGitHub Pagesにデプロイするときの定番(?)ツールである [gh-pages](https://github.com/tschaub/gh-pages) を使ってよしなにやってみます。

## 前準備

Bitbucketで `<workspaceID>.bitbucket.io` というレポジトリを作成します。

## 静的ページを公開したいレポジトリでやること

例として[Create React App](https://create-react-app.dev/)で作ったページを公開します。
`yarn create react-app hoge` のように作成した `hoge` というレポジトリがある前提です。

### 1. gh-pages をインストール

```
yarn add -D gh-pages
```

### 2. デプロイ設定

以下のようなコマンドを package.json の scripts に追加します。

```
gh-pages -d build --repo git@bitbucket.org:<workspaceID>/<workspaceID>.bitbucket.io.git --branch master --dest hoge
```

* `Create React App` で作成したプロジェクトであれば `build` ディレクトリに各種ファイルが出力されるため、 `build` を指定
* `--repo` で任意のレポジトリを指定(前準備で作成したレポジトリ)
* `--branch` でデプロイ先レポジトリ `<workspaceID>.bitbucket.io` のメインブランチを指定。昔は `master` がデフォルトでしたが、現在新規作成するレポジトリでは `main` がデフォルトとなっています。なお指定しない場合には `gh-pages` ブランチとなりますが、Bitbucketでは公開ブランチを設定できないため、メインブランチを指定する必要があります。
* `--dest` でデプロイ先のディレクトリを指定。指定しない場合はルートにデプロイされ、複数レポジトリの静的ページが同居できなくなるため、衝突しないように個別レポジトリ名を指定します。このディレクトリ名はURLの一部となります。

### 3. ビルド設定

`Create React App` で作成したプロジェクトをビルドすると、(Webpackの)デフォルトではjsやcssのパスが `/` からとなります。
しかしデプロイ先は `<workspaceID>.bitbucket.io/hoge` となるためパスが合わずに関連ファイルが取得できません。
そのためビルド時にパブリックURLを指定します。

package.json の `build` script を以下のように変更します。

```
PUBLIC_URL=/hoge react-scripts build
```

直接WebpackやParcel等を使用している場合は、それらのドキュメントを参照してください。

### 4. ビルド＆デプロイ

以上で必要な設定は終わりなので、あとはコマンドを実行するだけです。

```
yarn build && yarn deploy
```

成功すると `https://<workspaceID>.bitbucket.io/hoge/` でアクセスできます。
【AWS】CodeCommitでCloneの方法（ssh）【２通り】

１つ目のやり方でできなかったため、2通りの手順を用意しました。
①Linux及びGitBashを使用する
②SourceTreeを使用する

#Linux及びGitBasを用いたクローン（方法①）

##config 設定方法

```:ターミナル
$ touch ~/.ssh/config //config作成
$ vi ~/.ssh/config //config書き込み(直接書き込んでもOK)
```
<strong>configの中身</strong>

```config:config
Host git-codecommit.*.amazonaws.com
User <SSHキーID>
IdentityFile ~/.ssh/<秘密鍵のフォルダー名>
```

##GitBash起動時に秘密鍵を自動認証

<strong>Git Bash 起動</strong>

```:GitBash
$ vi ~/.bashrc
```
```:bashrc
eval `ssh-agent`
ssh-add -k ~/.ssh/id_rsa
```

<strong>Git Bash 再起動</strong>

```:GitBash
Agent pid 5898
Enter passphrase for /c/Users/<name>/.ssh/id_rsa:<秘密鍵のpass入力>
```


鍵なしの場合
pidを入力する（errorが出ても問題ないはず）

<strong>接続確認(この作業は無くてもいい)</strong>
成功の文字が出たらOK

```:GitBash
$ ssh git-codecommit.ap-northeast-1.amazonaws.com
//ap-northeast-1は使用するcodecommitに合わせる
```
:::note alert
この作業で下記エラーが発生した場合、下の別方法を試す。
:::

```:GitBash
Unable to negotiate with XX.XX.XX.XX port XX: no matching host key
type found. Their offer: ssh-rsa
```
※configに下記の値を追加したら、エラーは無くなるが、秘密鍵を無視しているので使用してはいけない。（他に解決方法があれば教えて欲しい）

```:config
  HostKeyAlgorithms ssh-rsa
  PubkeyAcceptedKeyTypes ssh-rsa
```

##Git Clone

```:GitBash
$ git clone git-codecommit.ap-northeast-1.amazonaws.com/v1/repos/<name>
```

##SourceTreeでのクローン（方法②）
<strong>PuTTYgenを起動</strong>

<strong>Prametersの設定</strong>
公開鍵を作ったときのデータに合わせる

```:(例)
$ ssh-keygen -t rsa -b 4096
//上記ならPrametersはRSAの4096に設定する。
```

「Load」で秘密鍵を選択する。
「Save private key」を押してppkファイルを保存する。
![Inkedスクリーンショット 2021-11-10 173243_LI.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/371642/d5700d29-53f3-17bb-5fff-83dd9fd19311.png)

<strong>SourceTreeの設定</strong>
「ツール」→「オプション」から先ほど生成したppkを設定する。
![スクリーンショット 2021-11-10 160703.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1217678/02cf5cd2-d928-fc2b-5a45-4f2ee6e2eb8f.png)

<strong>sshエージェントを設定する</strong>
「ツール」→「sshエージェントを起動…」をクリック
鍵が設定されているか確認する。

<strong>クローンする</strong>
SourceTreeの「Clone」→「元のパス/URL」にcodecommitのSSHを入力

```
ssh://<sshキーID>@git-codecommit.ap-northeast-1.amazonaws.com/v1/repos/<name>
```
[SourceTreeが途中で落ちたときはこちら（バージョンを下げた](https://madai21.hatenablog.com/entry/sourcetree-git-clone-failed)
SQL: <> の罠

先日SQLを書いていたところ、どうにも SELECTがうまくできていないようだったので、色々調べていたところ、 `<>` を誤って理解していたことに気づいた。

## TLDL;
- `<>` は **NULLではない値** に対して、左と右のオペランドを評価する
    - 参照: https://docs.microsoft.com/ja-jp/sql/t-sql/language-elements/not-equal-to-transact-sql-traditional?view=sql-server-ver15

## 勘違いしていたこと
例) 

```sql
SELECT * 
FROM user
WHERE company_id <> 100
AND is_admin = 1
```

ここで、company_idがnullも許可している。
想定ではcompany_idが100ではない admin ユーザを取得したい

### company_idがnullではない場合
`30 <> 100` が評価されるので、 `is_admin=1` のuserが全て取得できる

### company_idがnullの場合
通常のプログラミングと同様に `null != 100` とはならず、company_idがnullの場合はそのuserを取得できない。Not equalの演算は **nullではない値** に対して評価が行われる。

## 解決策

```sql
SELECT * 
FROM user
WHERE (company_id IS NULL OR company_id <> 100)
AND is_admin = 1
```

company_idがnullだったら取得するし、nullではなければ 100ではないかチェックする。
これで想定通りのselectができた。
C言語で文字列を区切り文字ごとに分割する

# 概要
- C言語で文字列を区切り文字ごとに分割したい
- よくあるサンプルだと元の文字列に変更を加えてしまう。今回はこれを防ぐために文字列のコピーを行う

# 参考
- [C言語で自作split関数 \- Qiita](https://qiita.com/fireflower0/items/dc54f3ec1b3698a98b14)
    - このままだと元の文字列に変更を加えてしまう、文字列のコピーが必要
- [C \- mallocを使って新しい配列に文字列をコピーしたい｜teratail](https://teratail.com/questions/264065)
- [C言語入門：文字列の長さを知る](https://www.geekpage.jp/programming/c/strlen-1.php)

# 実装
## 特定の文字で分割する関数

``` C
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// MARK: - Helpers For Spliting String

int isDelimiter(char p, char delimiter) {
    return p == delimiter;
}

char *copy_string(const char *a) {
    int i;
    char *c;

    // a の長さをiに求める
    for ( i = 0; a[i] != '\0'; ++i ) ;

    // 文字列のコピーに必要な領域をcに確保する
    c = (char*)malloc(sizeof(char) * (i+1)); // 終端文字を含んだ長さが必要
    char *result = c;

    // 文字列aをcにコピー
    while (*a != '\0') {
        *c = *a;
        c++;
        a++;
    }
    *c = '\0'; // '\0'で終端する

    return result;
}


int split(char *dst[], char *_src, char delim) {
    
    int count = 0;
    char *src = copy_string(_src);
    
    for(;;) {
        while (isDelimiter(*src, delim)){
            src++;
        }
        if (*src == '\0') {
            break;
        }
        dst[count++] = src;
        
        while (*src && !isDelimiter(*src, delim)) {
            src++;
        }
        if (*src == '\0') {
            break;
        }
        *src++ = '\0';
    }
    
    return count;
}
```

## 呼び出し例

``` C
// MARK: - Main

int main(int argc, const char * argv[]) {
    
    char src[] = "ヒトカゲ,リザード,リザードン";
    char *dst[100];  // 分割結果を格納
    int count = split(dst, src, ',');
    
    char pokemon_1[64];
    char pokemon_2[64];
    char pokemon_3[64];
    
    for(int i = 0; i < count; i++){
        unsigned long size = sizeof(char) * strlen(dst[i]);
        switch (i) {
            case 0:
                strncpy(pokemon_1, dst[i], size);
                break;
            case 1:
                strncpy(pokemon_2, dst[i], size);
                break;
            case 2:
                strncpy(pokemon_3, dst[i], size);
                break;
            default:
                break;
        }
    }
    printf("元の文字列: %s\n", src);
    printf("pokenon_1: %s\n", pokemon_1);
    printf("pokenon_2: %s\n", pokemon_2);
    printf("pokenon_3: %s\n", pokemon_3);
    
    return 0;
}
```

## 出力結果

```sh
元の文字列: ヒトカゲ,リザード,リザードン
pokenon_1: ヒトカゲ
pokenon_2: リザード
pokenon_3: リザードン
```
Dockerとは

#環境構築とは
環境構築とは、その名の通り、サービスを開発する環境を構築する、ということです。

開発に必要なアプリケ－ションを用意したり、ライブラリをインストールしたりする必要があるのでとても面倒です。しかもライブラリをインストールするときにエラーが出る場合も多いのでそのさいに対応しなければいけません。

人によってエラーがでたり、でなかったりするので同じ環境を用意することが大変でチームで開発するときには特に骨がおれます。
#Dockerがあれば
開発に必要なOS、アプリケーション、ライブラリが一つのパッケージになっているので環境構築がとても楽に行えます。

そのパッケージを共有することによって同じ環境を提供することができるのでチームでの開発にも適しています。
ダッシュボードにトップ10の取引先リストを表示するために使用できるレポートについて解説

こんにちは。
ダッシュボードに表示できる取引先でトップ10のみを表示させる方法をまとめましたので紹介します。

今回の内容は動画でも公開しています

https://youtu.be/EJwpqdv0GZY

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


####方法1
.表示する行が10に設定された表形式のレポート

方法１はレポートの「行制限」を行います。

※行制限の詳細はこちらのヘルプを参照
　※ヘルプにも記載のように「行制限」機能はClassic環境のみとなります
https://help.salesforce.com/s/articleView?id=sf.reports_limiting.htm&type=5

※2023年5月追記　現状はLightning環境からでも行制限を設定できます

つまり具体的な設定場所は下記となります

![行制限です.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/5f5b8346-8a73-d87e-25e4-f480698e6193.png)

こちらで「行制限」を「１０」に設定し「保存」をします。これでトップ１０に絞り込めます
![行制限10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/4132d8c1-8a06-5f6c-8c56-dfc307128b82.png)



このように10行に絞り込めました
![10制限されたよ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/9a64fccd-45e9-6f66-1ba9-71d802d97ad4.png)

そして、上記作成したレポートをダッシュボードにすることでトップ１０に絞り込むことが可能です
![ダッシュボード1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/9b9ee1af-d783-8b89-06df-18557cce1b62.png)


####方法2
サマリーレポートを作成しダッシュボードで絞り込み

サマリー（グループ化）したレポートもダッシュボードの設定でトップ10まで表示させることが可能です。
まずはサマリー（グループ化）します（設定は例と最終更新日をグループ化）
![サマリー１.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/30611552-8df8-119c-a4d6-cefd103093ad.png)


次にダッシュボードを上記作成したレポートを元にダッシュボード作成。
表形式を選んだあと下記画像のように「表示する最大グループ化数」を「10」に設定します。
![グループ数１.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/ad9b1046-b8d0-e48b-7d23-ddd7fa262b6e.png)

そうするとトップ10に絞り込んだ（10レコードしか表示されない）ダッシュボードが完成します。
方法１と方法２の大きな違いは
・方法１はレポートですでに10レコードに絞り込んでいる（よってダッシュボードでは絞り込んでいない）
・方法２はレポートで絞り込んでいないがその代わりダッシュボードで10レコードに絞り込んでいる

ということです。


なお、方法２で使用できるサマリーレポートは表示グラフの有無にかかわらず使用可能です。


###備考
・レポートで表示グラフが作成可能なのはサマリーレポート（グループ化されたレポート）のみです。
よってグラフ付きの表形式レポートは作成　することはできません
（下記画像のように表形式では「グラフを追加」ボタンが押せない＝グラフ作成ができない）
![グラフを追加.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/82d09742-2a39-fbb8-2534-c365c87384dc.png)


・下記画像のようにサマリーレポート（グループ化されたレポート）では行制限を設定することはできません
![行制限できない.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/97f90181-eb3e-48d9-cda0-d3c815bd1e1b.png)
Power Automateでフロー内のアクション名を日本語で設定すると実行結果がエラーになる場合がある

### Power Automateで行おうとしていた処理
「鑑テーブルを作成できたら明細テーブルも作成できる」という仕様(※参考ページは<a href="https://zezeze.hateblo.jp/entry/2020/01/09/004935"  target="_blank" rel="noopener noreferrer">こちら</a>)でPower Automateでレコードを作成しようとしていました。
▽このときに使用していたフロー↓
![Items1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2218676/c577a722-5d26-1b80-5dd5-b69470c196f6.png)


### 問題
▽2つのテーブルの更新結果は正しく機能しているように見えますが、更新できてもできなくてもPower Automateの実行結果が失敗になる現象が発生していました。↓
![Items2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2218676/5d07da3c-119d-f10e-4708-a542e2130969.png)

### 修正方法～アクション名はなるべく英語で！～
- MicrosoftのPower Platformサポートに問い合わせたところ、フローのアクション名を**日本語から英語に変換** すれば現象が解消されると回答いただきました。
- ※なお、この**日本語のアクション名はデフォルトで設定されてました。** <br>

##### 修正後のPower Automateでのフロー<br>
- Dataverseのアクション「変更セットを要求する」の名前を日本語から英語に書き換えています。
 ![Items3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2218676/9b278e2d-42e7-3186-9aee-19dd4eb4c821.png)

### 修正結果の確認
▽下図は解消後の実行結果のキャプチャです。16：56の実行結果が「失敗」となっている履歴は修正前のエラーです。
![Items4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2218676/989c3ad5-33d8-7d1e-a439-b5ee44638b68.png)

##### 修正後のフローの実行結果の確認
なお、この修正を行った後も、 鑑テーブルの更新が失敗すれば明細テーブルの更新は行われません。
![Items5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2218676/e8fdbbeb-f7cf-2dab-85b3-cb0f72e787ed.png)
この時の実行履歴結果は17：05時点での「失敗」ですが、こちらの結果は意図した通りのものになります。
![Items6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2218676/f83ee1ea-b73e-c7c9-6793-fcc8017230fa.png)
M1 MacにMagento2.4の開発用仮想環境を作る

M1 Pro/Maxを積んだMacbook proの販売が始まり、メモリ32GBがこれでやっと選べるという今日このごろ。
日々Magento　~~に泣かされている~~ と戦っている自分としては、ぼちぼちM1 Macを開発機の候補に入れるかなと思い始めました。
というわけで備忘録です。一切の保証はしませんのであしからず。

## M1 Macを買ってくる
とりあえず、四の五の言わずにM1 Macbook Airを買ってきました。
さすがにメモリ8GBはDockerを動かす上で不足なので、16GBモデルです。
あとはこだわるポイントとしてUSキー。これは他の端末も揃えているので譲れません。

## OSアップデートをする
Big surで検証しても良いのですが、新しいマシンは新しいOSを入れたくなります。
ということでMontereyをインストールします。
このへんまではお約束です。

## Docker for Macを入れる
Apple Silicon用のDocker for Macをダウンロードしてきてインストールします。
このとき、Rosettaを入れろと言われます。ネイティブ対応したんちゃうんかい！と思いはしますが、仕方ないので黙って入れます。

## Homebrewを入れる
gitやその他諸々を入れたいので、Homebrewを入れます。ここもまあ開発用に使う人はみんなやりますよね（たぶん）。
入れたあとは必要なパッケージ類をゴリゴリ入れます。
今回は動作検証だけなので、

- git
- composer

をとりあえず入れておきます。

## Magentoのソースを取ってくる
さて、ここでMagentoのソースを取ってきます。

- githubから開発版をcloneする
- composerで正式リリース版をインストールする

という2通りの方法がありますが、今回は後者でいきます。

### Marketplaceの認証情報を設定する
composerでインストールする場合は、公式Marketplaceの認証情報が必要です。
5年くらい前から手順的には変わっていないので、わからない方は

https://principle-works.jp/blog/how-to-install-magento2-via-composer

を読んでいただけると良いかな、と。

### PHPを8.0から7.4に変更する
現時点のMagentoはPHP8には対応していません。次の2.4.4でPHP8に対応する予定です。
が・・・。Montereyの標準PHPバージョンは8なので、composer create-projectしようとするとコケます。

仕方がないので、

```
brew install php@7.4
```

でPHP7.4をインストールし、

```
brew unlink php && brew link php@7.4
```

で切り替えます。切り替え時に.zshrcに追記する内容が示されるので、忘れずに実行しておきましょう。

### 気を取り直して、composer create-project
PHP7.4に切り替えたら、気を取り直してcomposer create-projectを実行します。

```
php composer.phar create-project --repository-url=https://repo.magento.com/ magento/project-community-edition <Magento2をインストールしたいディレクトリ>
```

## Magentoの動くDocker環境を作る
M1 Macといえば・・・

- Dockerは対応イメージなら動く
- VirtualBoxはだめ
- Parallelsは動く

という状況です。最近のプロジェクトはほとんどDockerで動かしているので、Dockerが動けばまあなんとかなりそうです。

### M1　Mac対応Wardenを入れる
MagentoやSymfony系の開発用Docker環境として「[Warden](https://warden.dev/)」というものがあります。

https://warden.dev/

Magento2系の開発環境を作るのはそれなりにめんどくさいので、ソースさえあればササッと作れるWardenは重宝しています。
が、公式にはM1 Macには対応していない模様。[Issue](https://github.com/davidalger/warden/issues?q=is%3Aissue+is%3Aopen+m1)も上がっていて、まだクローズされていないようです。

とおもったら、Issueの中にフォークプロジェクトの案内が。

https://github.com/drpayyne/warden-multi-arch

今回はこちらを試します。
readmeに書かれている手順通りに実行していけば基本OKですが、起動時に

- pub/mediaがホスト側からコンテナ側に共有されていないエラー
- pub/staticがコンテナ側に存在しないので書き込めないエラー

がでます。

まあ、それぞれ共有したりディレクトリ作成すればいいだけなんですが・・・。
（エラーメッセージを読めばすぐわかる話です）

コンテナ一式が起動したら、[warden公式のチュートリアル](https://docs.warden.dev/environments/magento2.html) に沿ってインストールを行います。
あとは指定したホスト名にアクセスして、MagentoのTOPページが出ればOK。

とりあえず・・・いけそうです。
ネットワークを冗長化構成にする

## STP
ループ検知し、検知した場合にはポートをブロックする機能
ネットワークを冗長化すると必ずループしてしまう
しかし、ループしてしまうと問題しかないので、一つの経路のパケットをブロックすることでループを回避する
だが、実際一つの経路をブロックするので、性能としては50％しかない

BPDU(Bridge Protocol Data Unit)と呼ばれるフレームを送信し、送信したポートに戻ってくることでループ検知している
STPを改良して高速(Rapid)収束を実現したプロトコルとなるRSTP(Rapid Spanning Tree Protocol)もある
トポロジーに変更があった場合、STPは最大50秒間で収束するのに対して、RSTPでは数秒以内で収束

### トポロジー
ネットワークの接続形態のこと
ネットワーク接続の図をイメージする

## リンクアグリゲーション
複数の物理ポートを論理化することで、冗長化と耐障害性を担保する機能
STPと異なる点としてパケットをブロックしないため、性能が100％発揮される
負荷分散が可能になる
メーカーによって呼び方が違う
Ciscoならイーサチャネル
DELLならポートチャネル


リンクアグリゲーション設定前はスイッチを冗長化してもSTPが優先される
（オレンジ色の部分がブロックしている箇所）
![スクリーンショット 2021-11-16 10.31.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1603537/56b957d3-6cf6-6d1b-9681-7f7156a8382c.png)

### 動的リンクアグリゲーション
LACP、特殊なプロトコル

スイッチ同士で設定することもあれば、スイッチとサーバーみたいな感じでリンクアグリゲーションを設定することもある
その時にLACPに対応していない機器もあるため、その時は静的リンクアグリゲーションを使用する

### 静的リンクアグリゲーション

基本的に動的リンクアグリゲーションを使う

### 設定方法

1.VLAN作成
2.物理ポート選択
3.リンクアグリゲーション構成
4.ポートチャネル選択
5.VLAN割り当て

論理的にまとめたいポートを選択する

```
channel group　ポート番号 mode active or auto or desirable or on passive
※activeが動的、passiveが静的
```
すでにある論理ポートにまとめるというイメージ

これでポートのスイッチのポートの論理化ができる

あとはVLANを割り当てればOK

設定が完了すれば全てリンクアップになる
![スクリーンショット 2021-11-16 10.57.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1603537/51551bcd-1019-f5f7-a782-38ff81ccb6d4.png)

さらに

```
show ethernetchannel summary
```

で確認した時にスイッチのポートの横に(P)という表示が出る

## スタック構成
L2スイッチを複数にし、耐障害性を担保する
メリットとしてはコンフィグを一つで管理することができるが、デメリットとして、一つのL2スイッチを再起動すると、スタック構成になっている他のスイッチも再起動になってしまう

リンクアグリゲーションでは経路の耐障害性を担保しているに過ぎず、スイッチの耐障害性については担保していない。
そこで、スイッチの耐障害性を担保するために、スタック構成を使用することがある。
M1のmacOSでUbuntuを3分で起動して使えるようにする方法

# はじめに

M1チップで動作しているmacOSで一番早く簡単にUbuntuを起動する方法を説明します。ツールにはCanonical社のMultipassを使います


# インストール

```bash
brew install multipass
```

# 起動

```bash
multipass launch --name myubuntu
```

# シェルを起動

```bash
multipass shell myubuntu
```

# 削除

```bash
multipass delete myubuntu
```

# 参考

- [Multipass orchestrates virtual Ubuntu instances](https://multipass.run/)
- [Running Ubuntu VM with multipass - Deepan Seeralan](https://www.deepanseeralan.com/tech/running-ubuntu-with-multipass/)
Azure ADでデバイスを管理する

## クライアント端末からAzureADに参加する方法

設定
![スクリーンショット 2021-11-16 10.21.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1603537/a597e8a7-9257-05dd-988c-1e392ea051da.png)

アカウントから職場または学校にアクセスする
![スクリーンショット 2021-11-16 10.21.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1603537/385cdc97-5f50-e0d4-e73b-de3705849b32.png)

接続をクリック
![スクリーンショット 2021-11-16 10.21.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1603537/3f752366-b064-0473-e423-3f06d130835a.png)

Azure ADのアカウント情報を入力する
（Azure ADのアカウントであれば、どのアカウントでもOK）

## ハイブリッドADを利用する
ハイブリッドADはオンプレのADとAADを連携して、オンプレのADにてドメイン参加した端末を自動でAADに登録することができる

Azure ADコネクトへアクセス

デバイスオプションの構成からハイブリッドAzure ADのオプションを追加

STPの構成でAzure A Dの情報を入力
AWS EC2にてPHPのRedis拡張機能を有効化する。

PHPのREDIS拡張機能を追加する。

手順はシンプル
・インストール
・有効化

**※以下、インストール**
インストールにはpeclを利用する。

## peclインストール

```
wget http://pear.php.net/go-pear.phar
php go-pear.phar
```

インストール時にオプション指定をいくつか設定できるが、
筆者はデフォルト設定にしたためEnterを押した。

## PATHの追加
```
export PATH=$PATH:/home/ec2-user/pear/bin
```

## redisのインストール
```
sudo pecl install redis
```

**※以下、有効化**
## php.iniに以下を追加
```
extension=redis.so
```

## Apache再起動
```
sudo service httpd restart
```

# 参考
https://pear.php.net/manual/en/installation.getting.php
https://self-development.info/%E3%80%90%E3%82%AD%E3%83%A3%E3%83%83%E3%82%B7%E3%83%A5%E5%88%A9%E7%94%A8%E3%80%91phpredis%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%A6php%E3%81%8B%E3%82%89redis%E3%81%AB%E3%82%A2%E3%82%AF%E3%82%BB%E3%82%B9/
文字列の結合の種類

RubySilverの勉強中、文字列の結合のメソッドがいくつか出てきたので備忘録として記していきます。
##文字列の結合
文字列を結合する方法は主に + 演算子とconcatメソッド、<< の3種類あります。
concatと << は破壊的メソッドなのに対し、 + 演算子は非破壊的メソッドです。

### + 演算子の使い方
```ruby:例
s1 = Leo 
s2 = Messi

puts s1 + s2
# => LeoMessi
```

### concatの使い方
```ruby:例
s1 = Leo
s2 = Messi

s1.concat(s2)

puts s1
# => LeoMessi
```

### << の使い方
```ruby:例
s1 = Leo
s2 = Messi

s1 << s2

puts s1
# => LeoMessi
```

参考記事
[【Ruby】concatを使って文字列や配列を結合する](https://style.potepan.com/articles/27074.html)
MiroとiPadでリモート会議を円滑化する！(もしくはiPadの液タブ化)

毎度、ググっても出てこない小ネタを取り扱っております。
本記事は個人的な見解であり、筆者の所属するいかなる団体にも関係ございません。

# 0. はじめに

すっかり世の中はリモート会議が一般的になりました。
外出や移動が辛かった私は個人的に歓迎しているのですが、対面で説明するときにホワイトボード等に
図を書いて説明するのが好きだった私としては、その方法が封じられてしまって会議進行能力が50%
ダウンぐらいのダメージになっておりました。

そこで、リモート会議でも図を書いて説明したい！というニーズを叶えるべく今はこんな風にやっているよ、
と言う説明もかねて対応方法を紹介したいと思います。

# 1. 歴史

実は、ペンで書いたものを直接取り込むことができるデバイスは昔から使っていました。
以下のAirpenは、紙と鉛筆の感覚で手軽にお絵かきできるよいツールでした。
(MVPenも持っていました)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15176/28ddd42d-364a-b9ee-2148-734b32b7552f.png)

しかし、転送速度の遅さやBluetoothでの接続の不安定さと書き込めるサイズが限られることにより使わなくなりました。

次に購入したのが、Wacom Bamboo Slateです

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15176/515236de-7fef-e19e-2e63-1907ac4d831a.png)

これもBluetoothで接続できなくなるトラブルが起きるので使用を断念しました。

# 2. iPadを液タブにする

そうこうしている間にもiPadを液晶タブレットにできないか、ずっと探していました。
MacOSなら[Astropad](https://astropad.com)もlunadisplayもあるのですが、Windowsで対応したものを見つけることができていませんでした。

2020年に見つけました。EasyCanvasです。

EasyCanvas｜Easy&Light 
http://www.easynlight.com/en/easycanvas/

# 3. 接続方法

WindowsとiPadは、USB-Lightingケーブルで接続していて、使っていないときには充電もされます。

EasyCanvasにはPro版もあります。Wifi接続でケーブルで接続する必要がありません。
それはそれで魅力的なのですが、やはり遅延が若干あります。その為、EasyCanvas Proは購入しませんでした。

私は、USBで接続でEasyCanvasを使っていますが、遅延もなく(ゼロではない)普通に書いている感じになります。

ライトニングケーブルは、Owltechの巻き取り式のが最高です。

巻き取り式 超タフストロング Lightningケーブル 120cm | 株式会社オウルテック 
https://www.owltech.co.jp/product/cbrklt12

# 4. Apple Pencilについて

EasyCanvasとiPadを使って満足していたのですが、iPadに何かを書きたいときに画面に手が触れてしまうとタッチした状態になり上手くかけないという問題が発生しました。それまでは、静電タッチペンを使っていました。これを回避するためにApple Pencilを買いました。

傾き検知とか筆圧感知とか全然関係なく、この為だけにApple Penを買いました。

# 5. Miroについて

ここまでで、自由にお絵かきできる環境が整いました。
お絵かきツールは世の中に一杯ありますし、各種Zoom,Teams,Google Hangout、WEBEXなどWeb会議にはホワイトボードがついています。それで十分かもしれません。

しかし、私の試してみた範囲では一番スムーズに書くことができます。
Miroの無料版で使える範囲を越えてしまったので、有償版を契約しました。

# 6. 問題点

使っていてもう少し改善が必要と思われる点もあります。

- 1. GPUの非力さによる操作の遅延の発生
- 2. EasyCanvasが時々見えなくなる

1ですが利用しているデスクトップPCのCPUがAMD Ryzen 4750GというGPU内蔵のCPUです。
普段使う分には何も問題ないのですが、Zoomを起動し、EasyCanvasでiPadに接続し、サブディスプレイをつないでOBS Studioで録画するとさすがにGPUがフルパワーで動いてEasyCanvasのペンの操作が遅くなります。

Zoomで相手のカメラがオフの場合は、まだ我慢できるのですが、相手のカメラがオンの場合には動作が重すぎてペンの動きに追従できずに文字が書けません。これは、EasyCanvasの問題ではなく、CPUとGPUの問題です。Lightingケーブルのスピードの問題もありますが、GPUをなんとかしないとどうしようもなさそうです。

次に2ですが、恐らくLightningケーブルの問題でしょう。頻度が高くないのでEasyCanvasをタスクマネージャから再起動して対応しています。

# 6. まとめ

EasyCanvas+iPad+Apple Pencilを使ってようやくWindows側のお絵かきアプリをストレスなく使えるようになりました。
zsh: command not found: vueの解決(WSL2 + zsh + asdf)

開発の都合でいろいろなバージョンの Node.js を使っているので、asdf でバージョンを切り替えているのですが、以前の環境(node v14.16.0 で) @vue/cli をインストールしたら、新しい環境(node v14.17.6) で vue コマンドが使えなくなっていました。

いろいろ試してとりあえず解決したっぽいので、備忘録として残しておきます。

# 環境

+ WSL2
+ zsh
+ asdf
+ Node.js: 14.17.6
+ @vue/cli 4.5.15

まず v14.16.0 を消しました。この手順が必要だったのかは不明

```shell
asdf uninstall nodejs 14.16.0
```

で @vue/cli をインストールしました。

```shell
yarn global add @vue/cli
```

バージョン確認

```shell
vue --version

zsh: command not found: vue
```
インストールしたやん……

どうもパスが通っていないようなので、find コマンドを使って vue のありかを探したところ
`/home/user/.config/yarn/global/node_modules/.bin/vue`
にいました。

ということでパスを通します。
`user` のところは自分のユーザー名に。

```shell
export PATH=$PATH:/home/user/.config/yarn/global/node_modules/.bin
source ~/.zshrc
```

再度バージョン確認

```shell
vue --version

@vue/cli 4.5.15
```

無事解決。
ただこれって asdf で管理する全部の node のバージョンで同じものを使うことになるんだけど、大丈夫なのだろうか。
そこが良く分かっていません。
PostgreSQL: Peer authentication failed というエラーの解決方法

次のようにユーザーがある状態でエラーが出る時の対策です。

```text
postgres=# select usename from pg_user;
 usename  
----------
 postgres
 scott
(2 rows)
```

エラーの状況

```text
$ psql -U scott city
psql: error: FATAL:  Peer authentication failed for user "scott"
```

pg_hba.conf を編集します。

```text:/etc/postgresql/14/main/pg_hba.conf
(省略）
#local   all             all     peer
local   all             all     trust
(省略）
```

PostgreSQL を再起動

```bash
sudo systemctl restart postgresql
```

問題が解決したことを確認

```text
$ psql -U scott city
psql (14.11 (Ubuntu 14.11-0ubuntu0.22.04.1))
Type "help" for help.

city=> 
```
VirtualBoxのUbuntuにssh接続する

VirtualBoxのUbuntu VMで作業をする際、いちいちVMのGUI（またはターミナル）を使うのは面倒で使い勝手も悪いので、ホストマシンのターミナルからssh接続してVM内で作業できるように設定する。

## 環境
- macOS Big Sur Version 11.6.1
- Intel Core
- VirtualBox 6.1.28
- Ubuntu 20.04.3 (VM Image)

## 前提条件
- VirtualBoxでUbuntuのVM起動済み
- VMのネットワーク周り設定済み
    - NAT
    - ホストオンリーアダプター

## 設定手順
以下、VMのターミナルにて作業を進める。

### ssh-serverのインストール

```bash
sudo apt install -y openssh-server
```

### ssh-serverの起動

```bash
systemctl status ssh
```

を実行すると、

```bash
ssh.service ......
.
.
.
Active: acctive (running) ......
.
.
.
```

と表示されればssh-serverが起動しているのでOK。

 もし起動してないようであれば、

```bash
sudo systemctl start ssh
```

で起動する。

また、VM再起動時にも自動でssh-serverが起動するように以下の設定をしておく。

```bash
sudo systemctl enable ssh
```

### ホストマシンからの疎通確認
ホストマシンのターミナルからsshの疎通確認を行う。

```bash
ssh <VMのユーザー名>@<VMのIPアドレスまたはホスト名>
```

まだ鍵を登録していないので、上記のコマンドを実行するとパスワードを尋ねられる。パスワードを入力するとVMのターミナルに入ることができる。

### 公開鍵の登録（オプション）
ssh接続のたびにパスワードを入力するのは面倒なので、公開鍵を登録してパスワード入力なしでssh接続できるようにする。

まず、ホストマシンで鍵を生成してVMに**公開鍵**を渡す。

```bash
ssh-keygen -t rsa
```

鍵のファイル名が求められるので、任意の名前を入力する。ここではデフォルトの`id_rsa`としておく。

次にscpを使ってVMに公開鍵を渡す。

```bash
scp ~/.ssh/id_rsa.pub <VMのユーザー名>@<VMのIPアドレスまたはホスト名>:~/
```

次にVMのターミナルで、ホストマシンから渡された公開鍵を登録する。
ホストマシンから渡された公開鍵があるディレクトリで次を実行。

```bash
cat id_rsa.pub >> ~/.ssh/authorized_keys
```

最後に、ホストマシン側でssh接続の際に指定した鍵を使うように`~/.ssh/config`に設定をする。
以下、設定例

```~/.ssh/config
Host ubuntu-vm
  IdentityFile ~/.ssh/id_rsa
  User <VMのユーザー名>
```

設定が正しければ、パスワード入力なしでVMにssh接続できるはず。

```bash
ssh ubuntu-vm

↓↓↓ こっからVM　↓↓↓

Welcome to Ubuntu 20.04.3 LTS (GNU/Linux 5.11.0-40-generic x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage

0 updates can be applied immediately.

<VMのユーザー名>@ubuntu-vm:~$ pwd
```
【JavaScript】非同期処理① 　同期処理と非同期処理


#はじめに

Udemyの[【JS】ガチで学びたい人のためのJavaScriptメカニズム](https://www.udemy.com/course/javascript-essence/)の講座の振り返りです。

前回の記事

https://qiita.com/nao0725/items/0df8e0e6d2be2d24a0b8

#目的

* 非同期処理についての理解を深める

#本題
###1. ブラウザとスレッド

**スレッド**
連続して実行される一本の処理の流れ
ex. Main thread

**Main Thread**
JavaScriptの実行とレンダリング（画像描写処理）

**FPS(Flames Per Second)**
1秒間あたりの画面（フレーム）更新頻度
ex. 1秒間に60回画面が更新：60fps
    →16.7m秒に1回画面更新
最近のテレビは全部60fps!

###2.同期処理と非同期処理

####同期処理

一つの処理が完了するまで次の処理が始まらない

#####例1

````js
// 関数を用意
// sleep関数が実行されるとms分だけメインスレッドを占有できる仕組み
// 実行されるとsleep doneと表示される
function sleep(ms) {
  const startTime = new Date();
  while (new Date() - startTime < ms);
  console.log('sleep done');
}

const btn = document.querySelector('button');
// ブラウザ上のボタンを押すとコンソール上にbutton clickedと表示される
btn.addEventListener('click', function(){
  console.log('button clicked');
});

// ここで3秒後に出力される
sleep(3000)
// この処理中にボタンを押してもsleep doneの後にbutton clickedが表示される
``````

同期処理では前の処理が終わってから次の処理が始まる

####非同期処理

一時的にメインスレッドから処理が切り離される
ex.setTimeout, Promise,  クリック etc.....

#####例1

setTimeoutで出力する

````js
function sleep(ms) {
  const startTime = new Date();
  while (new Date() - startTime < ms);
  console.log('sleep done');
}

const btn = document.querySelector('button');
btn.addEventListener('click', function(){
  console.log('button clicked');
});

// 2秒待ってからsleep実行する
setTimeout(function(){
  sleep(3000)
},2000)
// 上記のようにすると第二引数で与えた分だけメインスレッドが解放される
// ボタンを連続で押すと2秒後に処理が止まりsleep doneが出力された後、クリックした分が表示される
`````


今日はここまで！

#参考にさせて頂いた記事

* [【JS】ガチで学びたい人のためのJavaScriptメカニズム](https://www.udemy.com/course/javascript-essence/)
* [Let'sプログラミング JavaScript入門](https://www.javadrive.jp/javascript/)