OmniAICreator/Qiita-1.07M huggingface dataset:
Ansibleでyamlのアンカーを利用し、重複表現を短縮する。

# 目的
- アンカーを利用し重複表現を減らす。
- 実装方法に若干癖があったので個人的にメモする。

# 具体的なコード

- 良くないケース

```
# hoge = 1
# fuga = 1

- name: hoge1
  debug:
    msg: "hoge1"
  when: hoge == fuga

- name: hoge2
  debug:
    msg: "hoge2"
  when: hoge == fuga

# ※ whenは変数展開に"{{}}"を使用しない、使用した場合は全部文字列になる。

```

- 改善版

```
# hoge = 1
# fuga = 1

# no_log: trueでアンカーを定義しつつplaybook実行時のlogを汚さない。
- debug:
  vars:
    - &anchor_hoge
      when: hoge == fuga
  no_log: true

- name: hoge1
  debug:
    msg: "hoge1"
  <<: *anchor_hoge

- name: hoge2
  debug:
    msg: "hoge2"
  <<: *anchor_hoge
```

# おまけ
- モジュール: 値 (when: hoge)をアンカーに定義するのではなく値のみ(hoge)をアンカー定義し呼び出す方法。
- `<<`の記述がいらない。
- (こちら間違ってたらすいません)

```
- debug:
  vars:
    - &anchor_hoge
      hoge: true
  no_log: true

- name: hoge
  debug:
    msg: "hoge"
  when: *anchor_hoge
```

# 補足
- 今回は概要程度なので大した重複ではなくメリットをそこまで感じにくいかもしれないが、<br>
  `when`だけでなく`with_items`なども同時に利用されるケースではセットで <br>
  アンカーに処理を突っ込めるので良いと思った。
今更ながらLaravel8のSailを試す

久しぶりに記事を書くのでリハビリがてら短めのものをまとめました。


普段Laravelを使う場合は基本的にLTSの6.x系を使っているのですが、さすがにLaravelもバージョンがどんどん進んでいって、LTSは安心といっても新しいバージョンも魅力的に見えてきます。
周りでLaravel8から追加されたSailが超便利という声を聞くので、自分もちょっと試してみました。
確かに超便利でした。


https://laravel.com/docs/8.x/sail


Laravel Sailとは、Laravelの開発環境をDockerで立ち上げ、簡単に開発環境を管理できる機能です。
Dockerの知識やdocker-compose.ymlの書き方などわからなくても大丈夫です(わかっていたほうがよりよいのですが)。
初心者向けといえば初心者向けですね。


# インストール

始めてみます。
既に存在するLaravelプロジェクトにSailをインストールする場合もドキュメントに載っていますが、今回は何もないところから始めます。
SailにはPHP7.4またはPHP8.0を利用する2種類があります。今回はPHP8.0を使いました。
尚、自分の環境はmacOSで、既にDocker Desktopはインストール済みです。


```sh
$ curl -s "https://laravel.build/example-app?with=mysql,mailhog" | bash
$ cd example-app && ./vendor/bin/sail up
```


MySQLとMailHogを使いたかったので、クエリーで指定しています。
これでブラウザでlocalhost(デフォルト80番ポート、環境変数でポートは変更可能)にアクセスすると、Laravelの画面が表示されます。
簡単ですね:relaxed:


Sailをバックグラウンドで起動したい場合は`-d`オプションを付けて実行します。

```sh
$ ./vendor/bin/sail up -d
```

私の環境では`sail up`の時にエラーが出てしまって、調べたら既に起動していた別のMySQLとMailHogのコンテナが3306と8025を使っていたので、それらを落としたら`sail up`が正常に実行できました。


# SailのWebサーバ

SailではWebサーバにPHPのビルトインサーバを利用しています。
ソースコードを調べると、
vendor/laravel/sail/runtimes/8.0/Dockerfile
で最後に
vendor/laravel/sail/runtimes/8.0/start-container
を実行していて、start-container内ではSupervisordを実行しています。
vendor/laravel/sail/runtimes/8.0/supervisord.conf
を見るとわかるように、PHPのビルトインサーバを永続化させています。
SupervisordはLaravelのキューワーカ用でした利用したことがなかったのですが、こういう使い方もあるんですね。


ただまあビルトインサーバは公式ドキュメントでも警告されている通りあくまでテスト用なので、たとえ開発環境であっても最初からNginxなどを使ってもよいのかなとは思います。


# まとめ

他にもSailのドキュメントやソースコード(それほど複雑ではない)を見ればコマンドがたくさん充実しているのがわかります。
現在の自分は独自のDocker環境で開発していて、それ以前はValetを使ったりしていたのですが、Sailがあれば開発環境構築の手間が一気に省けて楽になりますね。
実際に仕事で導入するとなると、本番環境との差異をどうやってなくすかなど工夫が必要になるはずですが、Laravelユーザには作りたいものを作ることに集中できるようになって、よりよい開発者体験に繋がる素晴らしい機能だと思いました。
n×n行列で、ｎ乗して初めてゼロ行列になる行列が存在するのをnumpyで確認する

## はじめに
n×n で、ｎ乗してゼロになる行列が存在するのをnumpyで確認する。
具体的には、対角成分の１つ上だけが１で、他が０の行列を、実際にｎ乗してみて、ゼロ行列になるのを示すプログラム。

## プログラム
変数nに作りたい正方行列の大きさを指定する。ここでは、n=5とした。

```python:power.py
import numpy as np

n = 5

O = np.zeros((n,n), dtype=int)#まずゼロ行列を作る

O = np.matrix(O)

for i in range(n-1):#対角成分の１つ上を１に
    O[i,i + 1] = 1

for i in range(n):#１乗からｎ乗までを出力
    print(O ** (i+1))

```

結果

```python:power.py
[[0 1 0 0 0]
 [0 0 1 0 0]
 [0 0 0 1 0]
 [0 0 0 0 1]
 [0 0 0 0 0]]
[[0 0 1 0 0]
 [0 0 0 1 0]
 [0 0 0 0 1]
 [0 0 0 0 0]
 [0 0 0 0 0]]
[[0 0 0 1 0]
 [0 0 0 0 1]
 [0 0 0 0 0]
 [0 0 0 0 0]
 [0 0 0 0 0]]
[[0 0 0 0 1]
 [0 0 0 0 0]
 [0 0 0 0 0]
 [0 0 0 0 0]
 [0 0 0 0 0]]
[[0 0 0 0 0]
 [0 0 0 0 0]
 [0 0 0 0 0]
 [0 0 0 0 0]
 [0 0 0 0 0]]

```
AMPのついてのリンク集


数年前にあるサイトをAMP対応した際に調査したページのリンク集。
参考までに。

* [AMPについて](https://www.suzukikenichi.com/blog/accelerated-mobile-pages-amp/)
* [AMPのチェック方法](https://www.suzukikenichi.com/blog/three-ways-to-inspect-amp/)
* [構造化データ(Article)の追加方法](https://www.mitsue.co.jp/knowledge/blog/frontend/201612/27_1611.html)
* [構造化データ(Article)の詳細](https://developers.google.com/search/docs/data-types/articles#type_definitions)
* [構造化データのテスト](https://search.google.com/structured-data/testing-tool/)
Dockerfileからカスタムイメージを作成する

# はじめに
業務でDockerを利用したことはあるが、社内配布されたイメージを利用するだけで
自分でイメージを作成したことがなかった。
Dockerの学び始めでの最初の疑問が「一体どのようにイメージを作成するのか」だった。

# Dockerfileからカスタムイメージを作成する
カスタムイメージを作る方法は2つあり、
コンテナから作るパターンとDockerfileから作るパターンがあるが、
今回はDockerfileからカスタムイメージを作成し、DockerHubにアップする。
## Dockerfileからの作成で必要なもの
### ベースイメージ
自分が作りたいものに近い既存のイメージをベースとして、そこに変更を加えていく。
実用的なイメージを使ってもいいが、改良しにくいというデメリットもあるため
まずはシンプルでサイズの小さいLinuxイメージから作成することが多い。

既存イメージはDockerHubから取得するのが一般的で、公式イメージなども配布されている。
### Dockerfile
ベースイメージに対する変更指示をまとめたファイル。
他人が作ったイメージもDockerfileを変更するだけで手を加えられる。
また、これを見れば誰がどのような変更を加えたかが把握できる。

# httpdイメージを利用してカスタムイメージを作成する
httpdイメージをベースにして、カスタムイメージを作る。
## カスタムイメージの作成
**公式のhttpdイメージをDockerHubから取得する**
バージョンを指定しなければ最新バージョンがpullされる。

```
docker pull httpd:2.4
```

**httpdコンテナを起動する**

```
docker run -dit --name {container-name} -p 8080:80 httpd:2.4
```

**Dockerfileを作成する**
Windowsなら`copy nul Dockerfile`
今回は適当な`index.html`を作成し、それをコンテナ内にコピーする、
という内容で作成。
（※Dockerfileの記述については別記事にて）

```
FROM httpd:2.4
COPY index.html /usr/local/apache2/htdocs/
```
上記の内容は下記のコマンドと同じことを行っている。

```
docker cp index.html {container-name}:/usr/local/apache2/htdocs
```

**イメージをビルドする**

```
docker build -t {image-name}:{tag} .
```

**イメージが作成されたか確認する**

```
docker image ls     

REPOSITORY    TAG       IMAGE ID       CREATED         SIZE
imagename     1.0       ac2070100932   3 minutes ago   138MB
```

変更履歴を見たい場合は `docker history`

```
docker history imagename:1.0

IMAGE          CREATED         CREATED BY                                      SIZE      COMMENT
ac2070100932   5 minutes ago   COPY index.html /usr/local/apache2/htdocs/ #…   47B       buildkit.dockerfile.v0                                             
```

`docker run` で変更が反映されたものが問題なく表示されればOK！

##DockerHubへカスタムイメージをアップロードする

ログインしていない場合はまず`docker login`

**DockerHub用のイメージを生成**

DockerHubにイメージをアップロードするには、
「DockerHubのアカウント名/イメージ名」にタグ付けする必要がある。

```
docker tag {image-name}:{tag} {user-name}/{image-name}:{tag}
```

**DockerHubへアップロードする**

```
docker push {user-name}/{image-name}:{tag}
```

Repositoriesに無事アップロードされたら、
`docker pull`して改めて確認する。

お疲れさまでした！

##カスタムイメージ作成時に困ったこと
###デバッグしたい！

`docker run`時にオプションで`-it`をつけることで、
コンテナ内に入ることができる。
終了は`exit`

```
docker run --rm {image-name} /bin/bash
```

`--rm`をつけると、docker run終了時に合わせてコンテナを削除してくれる。
デバッグ時は指定しておくと便利。
R 言語とIDEインストール

## 想定環境
- macbook
- R 4.0.5

## 準備

### R 言語インストール

https://cran.r-project.org/

Step | Image
---|---
1: アクセス| ![スクリーンショット 2021-04-19 20.13.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/355926/80c9dc7a-dd81-cb82-2672-8af226c8ee4a.png)
2: PKG ファイルをダウンロード | ![スクリーンショット 2021-04-19 20.18.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/355926/30efd5b0-e519-88b5-0317-cc04f228ad59.png)
3: インストーラ起動 | ![スクリーンショット 2021-04-20 23.46.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/355926/4c9a6ae7-848a-64d2-9363-f52937e34a10.png)

### IDE インストール

https://www.rstudio.com/products/rstudio/download/

Step | Image
---|---
1: ダウンロード|![スクリーンショット 2021-04-20 23.50.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/355926/3cfed4b8-142a-60cd-5692-8b21e653b975.png)
2: Applications に取り込み | ![スクリーンショット 2021-04-20 23.53.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/355926/4a66818e-c6ea-d4b6-f0f0-5d3203483f44.png)
3: IDE 起動確認 | ![スクリーンショット 2021-04-20 23.55.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/355926/0f8be91f-c243-e580-ecb8-3e5cba48f186.png)
AnsibleでJSONデータの定義方法

# 前提
version Ansible 2.8

# 目的
set_factを利用し、dictやlistを定義する方法。

# 背景
半構造データは`vars/main.yml`やインベントリでyaml形式で定義出来るが、
動的にこういったデータを作成したい場合の文献がパッと出てこなかったので記事を書いた。

# 留意点
そもそも静的な変数の場合、varsやdefault変数として定義して方が良い。
あくまでregisterなどを使った後、動的な変数を作成したい場合にset_factは利用される。
set_factは変数としての優先度が高く、他のtask、roleなどを跨いだ場合も有効。
影響範囲が大きいので極力vars、defaultか、インベントリに定義した変数を利用すべき。

# 具体的なコード

- dictの場合
  - defaultフィルターを利用し空のdictを定義、そのdictに対し値を定義していく。
  - defaultフィルターを利用せず`dict_hoge`に値を入れようとするとundefinedのエラーが発生するので注意。
  - combineフィルターを利用し、空のdictに対し値を適用させていく。

```
- name: define dict
  set_fact:
    dict_hoge: "{{ dict_hoge: | default({}) | combine( {"key1": "value1", "key2", "value2"} ) }}"
```

- listの場合
  - defaultフィルターを利用し空のlistを定義、そのdictに対し値を定義していく。
  - defaultフィルターを利用せず`dict_hoge`に値を入れようとするとundefinedのエラーが発生するので注意。


```
- name: define list
  set_fact:
    list_hoge: "{{ list_hoge: | default([]) + ["value1", "value2"] }}"
```

## おまけ
構造データ作成時のタイポでなぜかjsonではなくunicodeになる。
単純ミスからえぐいハマり方をした。

```
- name: define list
  set_fact:
    list_hoge: "{{ list_hoge: | default([]) + ["value1"] }}"


- debug:
    msg: " {{ list_hoge}}"
#         ^ ここに半角スペースが入ってるせいでunicodeになる、つまりlist_hoge[0]などするとエラーが出る。

```


# 参考文献
https://www.atmarkit.co.jp/ait/articles/1610/05/news013_2.html#:~:text=%E3%81%AA%E3%81%8A%E3%80%81defaults%E3%81%A8vars%E3%81%AE,%E5%90%8C%E3%81%98%E5%84%AA%E5%85%88%E5%BA%A6%E3%81%A8%E3%81%AA%E3%82%8A%E3%81%BE%E3%81%99%E3%80%82
undefined method `update_attributes' と言われたら

ちょっとびっくりしたのでメモ

## 環境
Rails 6.1

## 内容
エラー
> undefined method `update_attributes'

## 結論

`update_attributes` は、

- Rails 6.0 → 非推奨
- Rails 6.1 → 廃止

となったようです。

代わりに `update` を使いましょう、とのことでした。

https://github.com/rails/rails/commit/5645149d3a27054450bd1130ff5715504638a5f5
【Java】Firebaseから取得して来たドキュメントからほしいデータを取り出す方法

複数件取得して来た場合はfor文で取り出しましょう

```java
Query query = testNotification
                .whereGreaterThanOrEqualTo("random", Math.random()*max)
                .orderBy("random", Query.Direction.ASCENDING)
                .limit(1);

ApiFuture<QuerySnapshot> future = query.get();
List<QueryDocumentSnapshot> documents = future.get().getDocuments();

for (DocumentSnapshot document : documents) {
    token = document.getString("token");
    uid = document.getString("uid");
}
```

取得してくるデータが一件しかない時はif文で。。。

```java
if (documents.iterator().hasNext()) {
    var document = documents.iterator().next();
    token = document.getString("token");
    uid = document.getString("uid");
}
```

っていう感じです。
[Windows] VSCodeのSettings Syncを新しく作り直す方法

# 環境
windows 10 
Ubuntu20.04 wsl
VSCode

# はじめに
wlsでvscodeのsyncがうまく行かず作り直そうとしたときのメモ

# 方法

## 古いgistを削除する

[https://gist.github.com/](https://gist.github.com/)

cloudSettings > Delete

## 新しいトークン作成
github > settings > developer settings > personal access tokens > generate new token 

Note >  トークンの名前を入力
Select scopes > gist をチェック

generate token

## トークンを再設定

ctrl + shift + p > sync advance option > Edit Extension Local Settings 

```syncLocalSettings.json 
    "ignoreExtensions": [],
    "gistDescription": "Visual Studio Code Settings Sync Gist",
    "version": 343,
    "token": "ここに新しいトークンを設定",
    "downloadPublicGist": true,
    "supportedFileExtensions": [
        "json",
        "code-snippets"
    ],
```

shift + alt + u でアップロードして完了

## 更新されているか確認

[https://gist.github.com/](https://gist.github.com/)
cloudSetttingsが作成されいればok
【UiPath】データスクレイピングしたデータテーブルの中身を素早く簡単に確認する方法

# UiPathでデータスクレイピング結果をすぐに確認したい

データスクレイピングした際に正常に抽出できているか簡単に確認する方法をご紹介します。

# 結論

素早く確認したい方が多いと思いますので、記事もさくっと書きます。
使用するアクティビティは下記のとおりです。

***
[データスクレイピング]
　　⇩
[データテーブルの書き込み]
　　⇩
[１行を書き込み]
***

全体図は以下のようになります。

![2021-04-22_10h10_08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/878537/398aa190-6375-1291-a3b9-15980f4f9bf3.png)


# アクティビティのプロパティとか
※データテーブルの使用方法はここでは割愛します。

データスクレイピングしたデータを出力するために、データが格納されているDataTableをStringに変換します。

[アクティビティ（データテーブルを出力）]
![2021-04-22_10h29_06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/878537/be8cbbe8-7449-500f-770a-5dfeef68ad16.png)

[プロパティ（データテーブルを出力）]
![2021-04-22_10h23_30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/878537/2bccafee-da95-55fc-2055-92b5c678cedf.png)


続いて、Stringに変換したデータを出力します。

[アクティビティ（１行を書き込み）]
![2021-04-22_10h29_19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/878537/58112e39-5a40-d4a9-a200-b745b447646b.png)

[プロパティ（データテーブルを出力）]
![2021-04-22_10h30_54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/878537/b3c63e4c-876a-8c9a-2800-294ce987f39c.png)

# 実行結果
実行すると出力ウィンドウにデータテーブルの中身が表示されます！
データスクレイピングで問題なく抽出していることを確認できました。
![2021-04-22_10h32_10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/878537/6ca5c842-b2a4-0d06-c32a-7a725afcbf2e.png)

# まとめ
データスクレイピングが正常に動作しているか、さくっと確認したいときにおすすめです。
Googleグループで共有ラベルの設定ができない時の解決法

## 目的
業務において、Googleグループで共有ラベルの設定をしたがすんなり使用できなかったのでその解決方法です。
公式にも書いていなかった（と思う）のでここに備忘録として残します。

## 経緯
グループ設定から共有ラベルの項目にチェックを入れ、ラベルの作成はできるようになった。
![スクリーンショット 2021-04-22 10.30.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364469/cf1e89a2-06c1-429f-f973-1a934e338064.png)

しかし、実際に会話にラベルをつけようとすると「ラベルを更新する権限がありません。」と表示されラベルをつけることができなかった。
![スクリーンショット 2021-04-22 10.32.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364469/e68ff421-96bc-6fb2-2b63-6bbbc2aa0dac.png)


公式には以下の記載があったが、権限はすでに付与されている。
![スクリーンショット 2021-04-22 10.24.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364469/f1743a19-6880-2362-f54c-8cfaa5d8a9e3.png)



## 解決
投稿ポリシーの「メタデータを管理できるユーザー」権限を付与したところ会話にラベルをつけることができるようになりました。
![スクリーンショット 2021-04-22 10.36.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364469/d52dd1dd-b802-975f-c0cb-5fe4ec39970c.png)

「メタデータを管理できるユーザー」について公式には以下のようにしか記載がない！いじわる！
![スクリーンショット 2021-04-22 10.42.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364469/07242ec8-4b64-8757-b478-fa4be117125c.png)


## おしまい
というわけで解決できたのでなにはともあれめでたしめでたし。
ImageMagick・MiniMagick・ImageProcessingの導入方法

# 概要
### ImageMagick・MiniMagick・ImageProcessingをRailsに導入し、Webサイトで画像投稿を行えるようにする。導入の仕方を忘れがちなのでここに記述します。

### ※この記事はあくまで導入方法なのでソフトフェア・Gemの説明は省きます。

# 手順
###1.ImageMagickをインストール
### 2.MiniMagick・ImageProcessingをインストール
### 3.ローカルサーバーを再起動
### 4.Active Storageをインストール
### 5.マイグレートする。

# 1.ImageMagickをインストール
### ターミナルで以下のコマンドを実行する。
### ※ImageMagickはソフトウェアなのでHomebrewからインストールします。
```ターミナル.
% brew install imagemagick
```

# 2.MiniMagick・ImageProcessingをインストール
### GemfileにMiniMagick・ImageProcessingを記述する。
```ruby.Gemfile
# Gemfileの一番下に記述する
gem 'mini_magick'
gem 'image_processing', '~> 1.2'
```
### ターミナルでbundle installする。
```ターミナル.
% bundle install
```
### Gemを新しくインストールしたのでローカルサーバーを再起動する
```ターミナル.
% rails s
```
# 3. Active Storageをインストール
###  Active Storageを使えるようにターミナルで以下のコマンドを実行
```ターミナル.
% rails active_storage:install

```
# 4.マイグレートする。
```ターミナル.	
% rails db:migrate
```

### 以上の手順で導入を行い、データベースに表示されていれば成功
アドミニストレーター認定試験に向けた学習 ⇒ アドミニストレーター認定の準備: アプリケーション、活動、モバイル ⇒ サービスアプリケーションとサポートアプリケーションの準備

１．Salesforce 認定アドミニストレーター試験のうち、「サービスアプリケーションとサポートアプリケーション」セクションが占める割合は何パーセントですか?
２．Salesforce 認定アドミニストレーター試験の「サービスアプリケーションとサポートアプリケーション」セクションで取り上げる主なトピックはどれですか?
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634241/74b4d2eb-c23c-28ee-afb5-02651ced6a3e.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634241/c2868a2d-fcbf-ff5e-6c20-3d78d468c830.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634241/ef6d81bd-c5ab-be2d-e969-34d9efcb196a.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634241/ebc4b4ff-588b-b2e3-523b-f2e8c94b4d3b.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634241/fce662af-dc54-4f9f-d785-efe56ce83e8b.png)
plunkerでopenjscad

# 概要

plunkerでopenjscadやってみる。

# 参考にしたページ

https://joostn.github.io/OpenJsCad/


# 写真

![無題.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/5ea593a2-1d68-52a2-d556-13a47c9b889f.jpeg)


# サンプルコード


```
function main() {
  var b = CSG.sphere({  
    radius: 1.35,
   	center: [0, 0, 0],
  	resolution: 32 
  });
  return b;
}
```

# 成果物


https://embed.plnkr.co/plunk/dsw9dtwJ3CaAoSay


以上。
Juliaで要素が分数の行列を扱う

## はじめに
Juliaは簡単に分数を扱えると聞いていて、実際にやってみたら確かに強かった、という記事です。
本記事では線形計画問題の基底を変更する操作をします。

## 扱う問題
$$
\begin{align*}
  \text{minimize} ~ & ~ z = -x_1 -x_2\\\\
  \text{subject to} ~ & ~ 5x_1 + 8x_2 + x_3 = 96\\\\
                      & ~ 7x_1 + 4x_2 + x_4 = 84\\\\
                      & ~ x_1, x_2, x_3, x_4 \geq 0
\end{align*}
$$
この問題の基底を$x_1$と$x_2$にします。
計算をするために式を行列にしておきます。
$$
x = \left(
    \begin{array}{c}
        x_1\\\\
        x_2\\\\
        x_3\\\\
        x_4\\\\
    \end{array}
\right), ~~
A = \left(
    \begin{array}{cccc}
        5 & 8 & 1 & 0\\\\
        7 & 4 & 0  & 1\\\\
    \end{array}
\right), ~~
b = \left(
    \begin{array}{c}
        96\\\\
        84\\\\
    \end{array}
\right), ~~
c = \left(
    \begin{array}{c}
        -1\\\\
        -1\\\\
        0\\\\
        0\\\\
    \end{array}
\right)\\\\
\begin{align*}
  \text{minimize} ~ & ~ c^Tx\\\\
  \text{subject to} ~ & ~ Ax = b\\\\
                      & ~ x \geq \bf{0}
\end{align*}
$$
$x_1, x_2$を基底にするので$A$の1,2列を取り出して$B$を定義します。
$$
B = \left(
    \begin{array}{cc}
        5 & 8\\\\
        7 & 4\\\\
    \end{array}
\right)
$$

## Juliaでの計算
まずは計算に必要な行列などを一通り定義します。

```Julia
b = [
    96
    84
]
A = [
    5 8 1 0
    7 4 0 1
]
c = [
    -1
    -1
    0
    0
]
B = [
    5//1 8//1
    7//1 4//1
]
```
`B`の型は`Matrix{Rational{Int64}}`になります。
`B`に関する計算では浮動小数ではなく分数で計算してくれます。

変形後の成約の部分$B^{-1}b$と$B^{-1}A$を計算します。

```Julia
display(B \ b)
display(B \ A)
```
```
2-element Vector{Rational{Int64}}:
 8//1
 7//1
2×4 Matrix{Rational{Int64}}:
 1//1  0//1  -1//9    2//9
 0//1  1//1   7//36  -5//36
```
目的関数から基底変数を消去して、定数部分も計算します。
$c = (-1 ~ -1 ~~ 0 ~~ 0)^\text{T}$なので$B^{-1}A$の1行目と2行目に1をかけて足します。

```Julia
display(c + vec(sum(B \ A, dims=1)))
display(-sum(B \ b))
```
```
4-element Vector{Rational{Int64}}:
 0//1
 0//1
 1//12
 1//12
-15//1
```
~~`(inv(B)A)[1, 1:4]`の部分は行列の1行目を取り出したものですが、これは**ベクトル**`Vector{Rational{Int64}}`型になります。行で取り出しても縦に要素が並ぶベクトルになるので少し注意が必要です。~~

コメントにて推奨いただいたコードに変更して、1行4列の`Matrix`を返す`sum`を`vec`でベクトルにするコードに変更しました。

## 変形後の形
Juliaでの計算で変形後の線形計画問題が書けます。
$$
\begin{align*}
    \text{minimize} ~ & ~ \frac{1}{12}x_3 + \frac{1}{12}x_4 - 15\\\\
  \text{subject to} ~ & ~ x_1 - \frac{1}{9}x_3 + \frac{2}{9}x_4 = 8\\\\
                      & ~ x_2 + \frac{7}{36}x_3 - \frac{5}{36}x_4 = 7\\\\
                      & ~ x_1, x_2, x_3, x_4 \geq 0
\end{align*}
$$

## まとめ
```Julia
B = [
    5//1 8//1
    7//1 4//1
]
```
のようにして`Matrix{Rational{Int64}}`型の変数が定義できる。

## バージョン等
- Docker Image jupyter/datascience-notebook 2eac078be835  
Jupyter Labを使用
- Julia 1.6.0

## 参考ページ

https://docs.julialang.org/en/v1/manual/complex-and-rational-numbers/
Pythonでコマンドライン引数を辞書型の変数として扱う

## Namespace to dict

argparseのArgumentParserを使った場合、パースした後はNamespace型のデータとして吐き出されます。

```python
import argparse

parser = argparse.ArgumentParser()
parser.add_argument("test", type=str, help='test')

args = parser.parse_args() # ⇦これがNamespace型
```

Namespace型を辞書型に変換するためには`vars()`を用います。

```
args_dict = vars(args)
```

以上です。

## 参考
- [What is the right way to treat argparse.Namespace() as a dictionary?
](https://stackoverflow.com/questions/16878315/what-is-the-right-way-to-treat-argparse-namespace-as-a-dictionary/16878364#16878364)
- [Pythonのargparseのパース結果のvars()を使うとdictにできる](https://scrapbox.io/nwtgck/Python%E3%81%AEargparse%E3%81%AE%E3%83%91%E3%83%BC%E3%82%B9%E7%B5%90%E6%9E%9C%E3%81%AEvars()%E3%82%92%E4%BD%BF%E3%81%86%E3%81%A8dict%E3%81%AB%E3%81%A7%E3%81%8D%E3%82%8B)
- [組み込み関数 - Python 3.9.4 ドキュメント](https://docs.python.org/ja/3/library/functions.html#vars)
- [Pythonのvars()とdir()の違い](https://minus9d.hatenablog.com/entry/2016/11/13/222629)
C++ | 小技

## Use std::vector::reserve whenever possible
https://www.geeksforgeeks.org/using-stdvectorreserve-whenever-possible/

## Use torch::NoGradGuard no_grad_guard when inference
Disabling gradient calculation is useful for inference, when you are sure that you will not call at::Tensor::backward. It will reduce memory consumption for computations that would otherwise have requires_grad() == true.

## use std::size_t and ++i when loop
## When you don't need to use index in the loop, using range-based for is recommended

Suggested change 
```
  for (std::size_t roi_i = 0; roi_i < image_rois.size(); roi_i++) {
    const auto & roi = image_rois.at(roi_i).feature.roi;
->for (const auto & image_roi: image_rois) {
    const auto & roi = image_roi.feature.roi;
```

## get type
```
#include <typeinfo>

std::cout << typeid(in_Msg).name() << std::endl;
```

## variadic templates
```
template <typename... Ts>
class FusionNode : public rclcpp::Node
{
public:
  explicit FusionNode(const std::string & node_name, const rclcpp::NodeOptions & options);
  static const std::size_t value = sizeof...(Ts);
  using in_Msg = typename std::tuple_element<0, std::tuple<Ts...>>::type;
  using out_Msg = typename std::tuple_element<value - 1, std::tuple<Ts...>>::type;
```
もう無駄にfor文書くのやめようや...。

# はじめに
Java8以降で何も考えずに「**for文を用いた繰り返し処理**」を使うのはやめましょう。
書き手、読み手にとっても良くないし、特別な理由がなければ積極的に新しい技術を使うべきです。
良くない理由としては様々ありますが、主な理由としては以下の点が挙げられます。

* 処理の内容をパッと見て把握しづらい
* 不具合のトリガーになる
* ソースコードの肥大化


では具体的な例を次に示します。

# 具体例1
### NGパターン
```java:例1
		List<String> nameList = Arrays.asList("Taro", "Jiro", "Saburo", "Shiro", "Goro");
		for (int i = 0; i < nameList.size(); i++) {
			System.out.println(nameList.get(i));
		}
```

### OKパターン
```java:例2
		List<String> nameList = Arrays.asList("Taro", "Jiro", "Saburo", "Shiro", "Goro");
		// ① せめてこちらのパターン
		nameList.forEach(name -> System.out.println(name));
		// ② こっちだとなおよし
		nameList.forEach(System.out::println);
```
こちらは`nameList`の値を繰り返し取得して表示するだけの単純なコードになっています。
ではNGパターンで記載している例1が何故**NG**なのかを説明します。
従来のfor文の書式は次のような構成になっていますが、

```java:for文の書式
		for (初期化式； 条件式； 変化式) {
			実行する処理；
		}
```

私はこの書式でコードを書く際は

私「初期化式は `i=0;` だったかな？、`i=1;` だったかな？」
私「条件式は初期化式を `i=0;` にしたから、`i <= nameList.size();` かな？」
私「ちがうちがう。`i < nameList.size();` やわ！」

などを毎回考えてしまいます。。

人によっては、

「これくらいは一瞬で考えれる。」
「絶対間違えへんわ！」

のような方も、もちろんいらっしゃると思いますが、私のように毎回「うーん。」と考える人がいるのも事実です。
したがって、これらを毎回考えること自体が、うっかりミスのトリガーになると考えています。
[こちら](https://www.oreilly.co.jp/books/9784873117041/) の書籍ではこの書式を「**自殺点パターン**」と呼んでいましたが、まさにその通りですね。絶対いつか間違える。。

一方、例2の`forEach()`を使うパターンだと

* 一行で簡潔に書ける!
* 条件式などを記載する必要も無い!
* 読み手も理解しやすい！

皆で幸せになれますね。
②のパターンでは「**メソッド参照**」を用いて①より簡潔に記載しています。

※ メソッド参照については本記事では解説しません。
※ 気になる方は分かりやすく説明して頂いている方の記事がありますので、[こちら](https://qiita.com/tech_newbie/items/2588970f3d2ce08a1b16)を参照してくさい。

# 具体例2
次の例は1~10の数値が格納されている`numList`の中で、偶数の合計を表示するコードになります。
### NGパターン
```java:例3
		List<Integer> numList = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
		int evenSum = 0;
		for (int i = 0; i < numList.size(); i++) {
			if (numList.get(i) % 2 == 0) {
				evenSum += numList.get(i);
			}
		}
		System.out.println(evenSum); // -> 30
```

### OKパターン
```java:例4
		List<Integer> numList = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
		int evenSum = numList.stream()
				.mapToInt(Integer::intValue)
				.filter(num -> num % 2 == 0)
				.sum();
		System.out.println(evenSum); // -> 30
```

NGパターンの理由としては例1の時と同じ理由ですが、OKパターンの良い点は上から下へ順番に読むだけで処理が理解できることです。実際に読んでみると、

1. マップ処理を行い
2. 偶数の値のみフィルタして
3. それらを合計する

やりたいことを上から順番に記載していくだけなので、「**コード = 設計書**」のような形になります。
やっぱり、従来のfor文で書くより良いですね。


# 参考文献
* [Javaによる関数型プログラミング――Java 8ラムダ式とStream](https://www.oreilly.co.jp/books/9784873117041/)
* [【第三回】Stream APIを使う前にラムダ式とメソッド参照を理解する](https://qiita.com/tech_newbie/items/2588970f3d2ce08a1b16)



# さいごに
Javaは現在(2021/04/21時点)では16までリリースしており、より便利な形へと日々進化しています。
面倒という理由のみで、新しい技術を使わないのは書き手の怠慢だし、本日紹介した構成はjava8以降なら使えますので皆で頑張りましょうー。(Java8のリリースは2014/03)
LogicApps / PowerAutomate から、クライアント証明書の必要なHTTPリクエストを発行する

# 想定読者
自分。備忘録
# 前提
LogicAppsで、クライアント証明書の必要なWebAPIを呼び出し。
1年後に証明書が更新されるが、どうやって設定していたのか、1年前のことなので思い出せない。
# Howto
pfxファイル全体を、base64エンコードでテキスト化
それを、クライアント証明書の内容としてペタッと貼る。
M1macでgatsby + netlify + shopify + contentfulで連携しながらサイトを作成してみよう！

# 概要
今回の記事では、「gatsby」、「netlify」、「shopify」、「contentful」の連携をする手順をみていきたいと思います。

実務のバイトで上記４つの連携をしたところ意外と簡単にできたので、アウトプットがてらこの記事の手順と解説をまとめていきます。

具体的には「gatsby」でサイトを作成し、「netlify」でデプロイします。

その後「shopify」と「contentful」と連携して、商品や記事を「gatsby」のサイトに表示します。

最後に商品や記事が追加されたら「gatsby」で構築したサイトが自動で更新されるようにします。

これだけ聞くと難しそうですが、意外と簡単にできるので１からみていきましょう！

# 謝罪

画像が多めなので、下記のサイトでわかりやすく手順を解説しています。
参考になれば幸いです🙇‍♂️

https://chaldene.net/make-site
SyntaxError: Cannot use import statement outside a moduleをtransformIgnorePatternsで解消した

Vue Test Utilsとjestでテストを書いていたら、以下のエラーが出ました。

```
FAIL  tests/unit/Step2/template.spec.js
  ● Test suite failed to run

    Jest encountered an unexpected token

    This usually means that you are trying to import a file which Jest cannot parse, e.g. it's not plain JavaScript.

    By default, if Jest sees a Babel config, it will use that to transform your files, ignoring "node_modules".

    Here's what you can do:
     • If you are trying to use ECMAScript Modules, see https://jestjs.io/docs/en/ecmascript-modules for how to enable it.
     • To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config.
     • If you need a custom transformation specify a "transform" option in your config.
     • If you simply want to mock your non-JS modules (e.g. binary assets) you can stub them out with the "moduleNameMapper" config option.

    You'll find more details and examples of these config options in the docs:
    https://jestjs.io/docs/en/configuration.html

    Details:

    /Users/okada/src/front/node_modules/@vueform/multiselect/dist/multiselect.js:1
    ({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){import{toRefs as e,ref as l,computed as t, …
                                                                                             ^^^^^^

    SyntaxError: Cannot use import statement outside a module

      36 | <script>
      37 | import { computed } from "vue";
    > 38 | import Multiselect from "@vueform/multiselect";
         | ^
      39 | import Condition from "./Condition";
      40 | 
      41 | export default {

      at Runtime.createScriptFromCode (node_modules/jest-runtime/build/index.js:1350:14)
      at Object.<anonymous> (src/components/Step2/MultiSelect.vue:38:1)

Test Suites: 1 failed, 1 total
Tests:       0 total
Snapshots:   0 total
Time:        5.226 s
Ran all test suites matching /\/Users\/okada\/src\/front\/tests\/unit\/Step2\/template.spec.js/i with tests matching "Step2\.vue".
```

``@vueform/multiselect``が問題のようです。
おそらく以下をやればよいのかなと思うものの、いまいち書き方がわからない。

```
• To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config.
```

jestのドキュメントを読むが難しい…

https://jestjs.io/ja/docs/configuration#transformignorepatterns-arraystring

検索してこのページをみつけました。

https://cloud6.net/so/jestjs/924125

真似して、jest.config.jsに以下を追記すると解決しました。

```
transformIgnorePatterns: ["/node_modules/(?!@vueform/multiselect)"],
```

jest.config.js全文はこんな感じです（関係ない記述もあります）


```
module.exports = {
  preset: "@vue/cli-plugin-unit-jest",
  setupFiles: ["./jest.setup.js"],
  transformIgnorePatterns: [
    "/node_modules/(?!@vueform/multiselect|vue3-carousel/dist/carousel.css)",
  ],
};
```
NAS とは

## 勉強前イメージ

ネットワークで接続するHDDのイメージ

## 調査

### NAS とは

Network Attached Storage の略でIPアドレスを持っており、ネットワークに接続して使われます。
コントローラーとHDDならファイルサービス専用のコンピュータみたいなもので
OSもファイルサービス用に独自で開発されていたりします。

### NASの特徴

- 競合を気にせず使用できる

NAS自体がファイルシステムを構成しています。
なので、ファイル単位での処理を内部で行い、同時アクセスがある場合には順に処理していき
必要に応じてロックを行うため基本的には競合は発生しません。

### NASのプロトコル

NASはネットワークで通信を行うため、プロトコルでの通信を行います。
主なプロトコルは以下です。

- CIFS
	- Common Internet File System の略
	- Windows OSで利用するプロトコル
- AFP
	- Apple Filing Protocol の略
	- Mac OSで利用するプロトコル
- NFS
	- Network File System の略
	- Linux OSで利用するプロトコル


通信方法としては以下になります。

![2021-04-20# NAS とは - diagrams.net - Google Chrome 2021-04-20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/49c9da8b-0854-d901-319a-a65134a8a408.png)

## 勉強後イメージ

通信プロトコルまであるのか・・・
まぁそうだよね、そもそも考えたことなかったからなぁ
OS事によっても違うらしいけど、売ってるNASって全部のプロトコルに対応してるってことかな？
なんかOSによって動かないとかありそうだなーって。

## 参考

- [NAS ( Network Attached Storage )](https://www.infraexpert.com/study/networking5.html)
- [【図解】良くわかる DAS / NAS / SAN ストレージの違い～接続方法やメリット/デメリット～](https://milestone-of-se.nesuke.com/sv-basic/architecture/das-nas-san-storage/)
Seeeduino XIAO 同士をI2Cで接続

#はじめに
Arudino Leonardo同士をI<sup>2</sup>Cで接続する場合は 5V とGND, SDA, SCL の4本をお互いに接続するだけで動作したので Seeeduino XIAO も同じかと思っていたら動作しなかった

#1. 通信できなかった回路
LeonardoをXIAOに置き換えただけの回路では通信できなかった

確認に使用したスケッチ

| 種別 | スケッチ |
|:--:|:----:|
|primary(master)|スケッチ例の master_writer|
|standby(slave)|スケッチ例の slave_receiver|

![before.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570185/29430bd4-a5d7-3721-6997-061d3a837b38.png)

#2. 通信できた回路
~~5V間とSDA間 5V間とSCL間に それぞれ10kΩのプルアップ抵抗を追加した回路
これで問題なく通信を確認できました
プルアップ抵抗の容量が10kΩの理由はわかっていません~~ @MergeCells さんから『ロジックレベルは3.3V』とのご指摘を頂き修正

3.3VとSDA間 3.3VとSCL間に それぞれ4.7kΩのプルアップ抵抗を追加した回路
これで問題なく通信を確認できました
プルアップ抵抗の容量が4.7kΩの理由はわかっていませんが 10kΩから下げていって安定して通信してくれたのがこの辺りなので採用しました
![xiao-i2c-xiao_2021-07-08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570185/bd8633d3-4d9b-28a6-ef25-62eec06f138d.png)

#おわりに
余りにも当たり前すぎて記事にすらならないのだろうけど
fritzing がいつの間にか事実上有料アプリとなっていたのがショック
かわりに kicad の回路図エディタを使用

#謝辞
@MergeCells さん ご指摘ありがとうございました！
semantic uiのform validationの設定

# はじめに

Web サイトのフォームによくある、値がないときにフォームが赤く変わり入力を促す機能を semantic ui を用いて実装したので、忘備録として書き残しておきます。

# 環境

- Rails 6.1.3
- semantic_ui 2.4

# 使用方法

```ruby:application.js
$('.ui.form').
  form({
    fields: {
      name: 'empty',
      password: ['empty','minLength[6]','match[password_confirmation]'],
      password: 'empty'
      })
```

input タグの id,name,data-validate のどれかの要素と fields の識別子と一致しないと動かないです。

# Validation Rules

主なバリデーションのルールを書いておきます

|     name     |                     description                     |
| :----------: | :-------------------------------------------------: |
|    empty     |             フィールドの値が空であるが              |
|    email     |               有効なメールアドレスか                |
|     url      |                 入力した値が URL か                 |
| minLength[n] |          入力した値が n 以上の長さであるが          |
|   match[n]   |      引数で指定したフィールドと値が一致するか       |
| minCount[n]  | 複数選択フィールドで少なくとも n 以上の選択があるか |

# エラーメッセージ

デフォルトでは、エラーメッセージが英語のため書き換える必要があり、prompt を書き換えてください

```javascript
$('.ui.form').
  form({
    fields: {
      name: 'empty',
      password: ['empty','minLength[6]','match[password_confirmation]'],
      password: 'empty'
      },
    prompt: {
     empty: '{name}が入力さていません。',
     match: '{name}が{ruleValue}は一致しません。'
   }
  )
```

ちなみに、エラーメッセージが表示されない場合は form 内にエラーメッセージの HTML を設置する必要があります

```html:view
<div class="ui error message"></div>
```

# 参考

[semantic ui form validation](https://semantic-ui.com/behaviors/form.html#/usage)
Javaのパッケージ化について

# Javaのパッケージ化について

##パッケージとは?
Java言語では、様々なクラスが提供されています。

**それら多くのクラスを整理するための役割**がパッケージです。

パッケージを利用することによって、どのクラスを利用するのか。同じ名前のクラスが存在しても、
名前の衝突を避けそれぞれのクラスを利用することができます。

##パッケージ文の書き方

パッケージ文は以下のように記述します。

```
package パッケージ名;
class X{ ・・・ }

```

パッケージ化するには、ソースファイルの先頭に**package文**を記述します。

ルールとしては、package文は必ずファイルの先頭に記述する必要があります。

また、パッケージ名を階層する場合は「.(ドット)」で区切りながら名前をつけます。

```
//(例) パッケージ名:com.se.sales.sales1の場合
package com.se.sales.sales1;

```

## パッケージ化されたクラスのコンパイル

コンパイル時、「javacコマンド」を使用しますが、パッケージ内のクラスをコンパイルする際は「-d オプション」を使用します。

```
javac -d パッケージのルートディレクトリを格納するディレクトリ ソースファイル名

```

「-d オプション」の後に、パッケージのルートディレクトリを格納する場所を指定します。

```
javac -d . Test.Java //現在いる場所(カレントディレクトリ)にTest.javaをコンパイルする。
```

## importキーワードの使用
ソースコードの先頭にimport文を記述して、利用したいクラス名をパッケージ名を含めて記述します。

```
import com.se.ren.Foo //パッケージ名とクラス名を記述
import com.se.ren.* //「*」を利用することで、指定されたパッケージに属するすべてのクラスを利用できる。
```

注意点として、package文とimport文を両方記述する場合は、**package文を先頭に記述します。**

## まとめ

・パッケージはクラスを分類するための機能
・package文を先頭に記述する
・「-d オプション」を指定してコンパイルを実施する
・利用したいクラス名にimport文を記述する
・import文とpackage文の両方記述する場合は、package文を先頭に記述する。
XR開発時の参考資料集

# XR関連
XR開発初心者は、先ずここを見よう！的な資料をまとめました。
## VR
[VR等のコンテンツ制作技術活用ガイドライン2020（経済産業省）](https://www.vipo.or.jp/u/VR-guideline-2020.pdf)
[How to make VR content（映像産業振興機構）](https://www.vipo.or.jp/u/I-2_How-to-make-VR-content.pdf)
[コンテンツ制作に向けて（ 映像産業振興機構 ）](https://www.vipo.or.jp/u/II_SenshinContents_ContentProduction.pdf)

## AR
[AR等のコンテンツ制作技術活用ガイドライン（映像産業振興機構（VIPO）](https://www.vipo.or.jp/news/26004/)

---
# デバイス別 Unity向け開発環境構築
手早く開発環境を作るときの参考用、詳細を知りたい場合はメーカーのページを参照すること。

## OculusQuest(2)
https://framesynthesis.jp/tech/unity/oculusquest/

## VIVE(Pro)
https://framesynthesis.jp/tech/unity/htcvive/
Emacs po-mode wコマンド(po-kill-ring-save-msgstr)のmsgid版

# 使い方
https://gist.github.com/kuma35/e82253d20aa8f5964b62040adfddb6d4

を Emacs の int.el にでも入れてください。

# 機能
wコマンド(po-kill-ring-save-msgstr)はmsgstr文字列をkill-ringにコピー(元は消さない)するコマンドです。

同様にpo-kill-ring-save-msgigはmsgid文字列をkill-ringにコピーするコマンドです。

画面上でそのままコピーすると改行とか引用符が余分に入るのでこのコマンドを使った方がたぶんラクです。

# 作り方
^Jコマンド(po-msgid-to-msgstr)とwコマンド(po-kill-ring-save-msgstr)のニコイチです。

# 動作確認
GNU Emacs 26.3 (build 2, x86_64-pc-linux-gnu, GTK+ Version 3.24.14) of 2020-03-26, modified by Debian
STM32CubeProgrammerのSWV(Serial Wire Viewer)でSWO(Serial Wire Output)を覗く

ちょっと前に、STM32CubeProgrammerでSWOが表示できるようになったらしい。

[SWO viewer for STM32CubeProgrammer?](https://community.st.com/s/question/0D50X0000BytYGO/swo-viewer-for-stm32cubeprogrammer)

やってみよう。

***

マイコン側では

```c
inline void ITM_SendStr(const char *str)
{
    while (*str)
    {
        ITM_SendChar(*str++);
    }
}
```

のような関数を作り、`ITM_SendStr("hello world\n");`のようにすれば文字列を出力できる。

GUIの場合は、画面をポチポチしたら見える。

CLIで使う場合は以下のような感じで起動する(bashの場合とcmdの場合)。

```
"/mnt/c/Program Files/STMicroelectronics/STM32Cube/STM32CubeProgrammer/bin/STM32_Programmer_CLI.exe" -c port=SWD mode=hotplug -swv freq=168 portnumber=0
"C:\Program Files\STMicroelectronics\STM32Cube\STM32CubeProgrammer\bin\STM32_Programmer_CLI.exe" -c port=SWD mode=hotplug -swv freq=168 portnumber=0
```

SWOにはSWDが必要だが、SWOを指定したからと言ってSWDの指定が不要になるわけではない。
`mode=hotplug`を指定しないとSWD接続時にリセットがかかるので注意。逆に、起動直後から見たいなら指定しないでリセットしてもいい。

SWVモードに入っても直ちにビューアが起動するわけではなく、`r`キーを入力してreseptionを開始する必要がある。また、`s`を押せば受信を中止し、`r`で再開できる。他に、`e`を押すとSTM32_Programmer_CLI.exeを終了できる。
この`r`の入力を省略する方法は今の所存在しないようだ(たとえば`echo r|"/mnt/c/Program Files/(以下略`のようにすると、SWD接続を確立した段階でハングアップする)。

`STM32_Programmer_CLI.exe -c port=SWD -d build/*.hex -s  -swv freq=168 portnumber=0`のようにすれば、HEXの書き込みを行ってから直ちにSWVを起動することもできるが、やはり`r`の入力が必要になる(`r`の入力は、人間の反射速度であれば任意のタイミングでいい)。

自動で受信を開始してくれればコマンド1発で書き込みからビューア起動までできて便利なのだが。

なお、SWVで受信した内容はすべて`$USER_HOME/STMicroelectronics/STM32Programmer/SWV_Log/swv.log`にログが残る。セキュアな情報を流すときは要注意(そんな使い方するやつがいるかは別として)。ヘルプファイルにはログファイルを変更できると書いてあるんだけど、使い方はわからなかった。全部swv.logに追記されるっぽい。

***

ちなみに、SWOの通信プロトコルは、なんの変哲もない2MbaudのUARTらしい。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264452/c0db66c9-557c-7caa-38cc-2854bd97c6a8.png)

SWOは文字列の出力以外にもいくつかの機能があるので、用途に応じて01hのヘッダが変化するんであろう。文字1バイトにヘッダが1バイトついているので、実効速度は1Mbaud程度になる。通信速度はそれほど早くない(一般的なUARTやI2CやCANよりは早いけど)。FIFOとかも入ってはいないだろうし、ITM_SendStrは文字数に応じて(1文字あたり10マイクロ秒くらい)プログラムがブロックされる。タイミングクリティカルな部分だと「printfを入れると動く」みたいな事象になる可能性がある。

例えばSPIであれば21Mbit/s(SPI1@168MHzコア)で通信できるし、STLINK-V3ならUARTで15Mbaudの通信ができるので、SWOより26倍や15倍の速度で通信ができる(さらに、SPIなら4byteまではほぼノーウェイトで転送できる)。

正直、SWOをprintfの出力として使うのは、ペリフェラル初期化コードが不要以外のメリットが見えない(そして、ペリフェラルの初期化は難しいことではない)。
他の機能と組み合わせたらプロファイラみたいな使い方とかできるのかな?

## 追記

SWOは最大で100Mbaudオーダーの速度で通信できるらしい。2MbaudはST-Linkの都合らしい。今後サポートが拡充されればさらに高速な通信ができるようになるかも。
ReactのuserEffectでsetIntervalした時の、インターバルが無限に定義される問題に対処する

# はじめに
React上でsetIntervalを使うとき、そのsetIntervalの処理が副作用を生む場合、無限ループに陥ることがあります。
本稿では、その対処法について紹介します。

# 環境/前提
![<LABEL>-<MESSAGE>](https://img.shields.io/badge/node-14.15.0-<COLOR>) ![<LABEL>-<MESSAGE>](https://img.shields.io/badge/npm-6.14.8-<COLOR>)

- 上記ライブラリがインストールされていること。

使用ブラウザ：Chrome

# 実装
## 無限ループに陥るコード

```typescript
    React.useEffect(() => {
        // インターバルを作成
        window.setInterval(() => {
          hasSideEffectFunction();
        }, 5000);
    }, [someState]);
```

上記のコードでは、```hasSideEffectFunction()```が副作用を引き起こし、実行されるたびにレンダーされます。

さらにレンダーされる度に、setInterval()が実行され、インターバルが無限に増えていきます。

## 解決策
```typescript
    // インターバルIDを保持する為のref変数(レンダーされても値を保持する)
    const intervalNo = React.useRef(0);

        React.useEffect(() => {
           // インターバルが作成されていない時のみ、setInterval()する
           if (intervalNo.current == 0) {
              // インターバルを作成
              intervalNo.current = window.setInterval(() => {
                 hasSideEffectFunction();
              }, 5000);
           }
        }, [someState]);
```

上記のように、setInterval()の返り値を、useRefを使って保持することで、レンダーされるたびにインターバルが作成されるのを防ぐことができます。

これでレンダーを通してインターバルを1つに保つことはできました。
しかし、画面遷移などのコンポーネントの呼び出しをされると、useRefが再び0に定義され、インターバルが作成されてしまいます。

```typescript
 for (let i = 1; i < 1000; i++) window.clearInterval(i);
```

その対策として、setInterval()を実行する前に、上記のコードにより、定義されているであろうインターバルをfor分で回して削除するようにしてます。
これで画面遷移を通してもインターバルを1つに保つことができます。

(正直無理やり対応してる感が否めないので、定義済みのインターバルを取得できるような知見がある方がいたら教えてほしいです。。。)
[競プロ]繰り返し2乗法【Java】【Python】

久々の競プロ記事です。

今回は**繰り返し2乗法**についてです。Javaで書いてみます。また、繰り返し2乗法を使用した問題をJava, Pythonで解いてみます。

# 繰り返し2乗法とは

べき乗の計算量を減らすテクニックです。以下のように、指数を2のべき乗表記をして累乗計算をします。
N乗の計算がO(N)からO(logN)になります。

# 計算方法

3^10を求めます。
10 = 2^3 + 2^1と表せるため、
3^10 = 3^(2^3 + 2^1) = 3^(2^3) * 3^(2^1)と表せます。

きれいに書くと以下のとおりです。

```math
3^{10} = 3^{2^3} * 3^{2^1}
```

「それはわかるけどなんでそう考えると計算量が減るの？」という声が聞こえて来そうです。
もうちょっと丁寧に説明しますね。
2進数のbit演算を使用しています。
こんな感じです↓

![スクリーンショット 2021-04-21 9.05.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/504218/be349d7e-941e-2817-db6f-12f67c847a58.png)


計算の過程は以下のとおりです。
tmp・・・一時変数
ans・・・3^10の解が入る変数

|#|今参照しているbit|説明|
|---|---|---|
|1|最下位bit|bitが0のため、ansの更新はしない（ans=1）<br>tmpにtmpをかけて9とする（3*3=9）|
|2|下から2番目|bitが1のため、ans*=tmpとする（ans=1*9=9）<br>tmpにtmpをかけて81とする（9*9=81）|
|3|下から3番目|bitが0のため、ansの更新はしない（ans=9）<br>tmpにtmpをかけて6561とする（81*81=6561）|
|4|下から4番目|bitが1のため、ansの更新をする（ans=9*6561=59049）|

こんな感じです。
tmpが重要ですね。最初は3だったのですが、上位bitを参照していくたびに2乗ずつして増えていきます。
2進数の桁が増えるのと同様、tmpも増えていく感じです。

# 実装
では、実装してみます。

```java
	public static long myPow(long a, long n) {
		// a^nを計算
		long ans = 1l;
		long tmp = a;

		// わかりやすくfor文の中ですべて処理
		for (;;) {
			// すべての桁を見終わったら終了
			if (n < 1l) {
				break;
			}

			// 最下位bitが1かどうかの判定
			if (n % 2l == 1l) {
				ans *= tmp;
			}

			// tmpの更新
			tmp *= tmp;

			// nのbitを一つずらす
			n = n >> 1;
		}
		return ans;
	}
```

はい。こんな感じです。

`myPow(3,10)`を呼ぶとしっかり59049が返ってきます。


# 問題演習
2021/04/17（土）のAtCoder、第二回日本最強プログラマー学生選手権のD問題、[Nowhere P](https://atcoder.jp/contests/jsc2021/tasks/jsc2021_d)を解いてみます。

問題はリンクのとおりですが、答えは

```math
(P-1)(P-2)^{n-1} mod 1000000007
```

を計算すれば良いです。
ただ、nの制約は最高で10^9で、単純にやるとTLEになる可能性が高いです。
なので繰り返し2乗法の登場です。

## Javaの回答例

``` java
import java.util.Scanner;

public class Main {

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);

		long n = sc.nextLong();
		long p = sc.nextLong();
		long MOD = 1000000007l;

		long ans = (p - 1) * modPow(p - 2, n - 1, MOD) % MOD;

		System.out.println(ans);
	}

	public static long modPow(long a, long n, long mod) {
		// a^nを計算
		long ans = 1l;
		long tmp = a;

		// わかりやすくfor文の中ですべて処理
		for (;;) {
			// すべての桁を見終わったら終了
			if (n < 1l) {
				break;
			}

			// 最下位bitが1かどうかの判定
			if (n % 2l == 1l) {
				ans *= tmp;
				ans %= mod;
			}

			// tmpの更新
			tmp *= tmp;
			tmp %= mod;

			// nのbitを一つずらす
			n = n >> 1;
		}
		return ans;
	}

}

```

先程のmyPow関数をちょっと変えてmodPowにしました。計算の途中でmodとってるだけですね。
これで問題が解けました。

## Python の回答例
ちなみに、Pythonのpow関数は繰り返し2乗法が実装されているので特に気にせず実装が出来ます。
また、　powの第三引数に値を入れるとmodPowの実装になります。

実装例（公式の解説とほぼ同じですが）

``` python
N, P = map(int, input().split())
MOD = 1000000007
ans = (P-1) * pow(P-2, N-1, MOD) % MOD
print(ans)
```

こんな感じです。

逆に競プロ以外で繰り返し2乗法や　modPowが必要な場面を教えてほしいくらいですが・・・。

割と簡単なアルゴリズムだったので覚えておきたいですね。

繰り返し2乗法を紹介しました。今回の記事はここまでです。
Pythonで少数点のデータを標準入力で入力する方法

Pythonで少数点のデータを標準入力で入力する方法です。

```python
num = float(input())
```

間違えて

```python
num = double(input())
```

でコードを書かないようにしてください。（私はやりました。調べてfloatの方に変更しました)
ログイン機能

ゲームのログイン機能の実装の備忘録です。

今回は、ユーザーが既に会員登録済みという想定で実装していきます。
ソースは以下のようになります。

```index.html
<section>
    <h1 class="title">入室許可証</h1>
    <form  action= "room.html" id="log" class="log" name="login">
      <input  type="text">
      <input  type="password">
      <input  class="btn" type="submit" name="date" value="送信">
    </form>
  </section>
  <script>
    document.getElementById('log').onsubmit = function() {
      // event.preventDefault();
      console.log('送信');
      // window.confirm('入室しますか？？');
      if (window.confirm('入室しますか？？')) {
        console.log('ゲームを開始します');
      } else {
        console.log('ゲームを終了します');
      }
    }
  </script>
```

フォーム入力されたら、room.htmlに入室できるようaction＝room.htmlとします。
更に、フォームのname(サーバーに送られたときにデータベースで判別できるように)を付けます。
フォームイベントと同時にJSが発動してほしいので、id="log"とします。

JS側の実装を行っていきます。
document.getElementByIdでHTML側でセットしたidを取得します。
更にイベントを設定するため、onsubmitにfunctionを代入します。
そして、テスト用のためにconsole.logで送信確認を行います。

今回は、ユーザーに入力の有無を問うため、window.confirmで入室するか聞きます。
ここでif文で、条件分岐を実施します。

最後に、実際に処理が実施されているのか確認したいので、ページ変移を防ぐため、functionパラメータにeventを引き渡します。
event.preventDefaultメソッドを追加します。
そうすることで、イベントが終わった後にログにconsole処理がされているか確認することができました。

*追記
やりたいこと▶confirmで入室を問うた後にいいえなら終了、はいなら入室。

```index.html
 <script>
    document.getElementById('log').onsubmit = function() {
      // event.preventDefault();
      console.log('送信');
      const answer = window.confirm('入室しますか？');
      if (answer === true) {
        console.log('ゲームを初めます');
      } else {
        window.alert('終了します');
      }
    }
    
    </script>
```

定数answerにwindow.confirmを代入（保存）。
条件分岐で、answerがtrueなら入室　実行可能
falseならアラートが出て終了　アラートは出たが、okボタンを押すとページが変移してしまった。

考えたこと▶ページ変移の記述をif文内で行うべきなのか？
実施後▶window.location.href記述したが、ページ変移しなかった。
【Javascript】関数宣言よりなるべく関数式を使う。その理由について

# 初めに
javascriptを学習していて疑問に思っていた関数と関数式について学習した内容をまとめてみました。両方の違いから関数式が推奨される理由についても考えてみました。

※内容に間違いなどがある場合はご指摘をよろしくお願いします。

#関数宣言とは
関数宣言（function declaration）とは一般的にjavascriptで関数を使用するために、処理したい内容を記述していつでも呼び出せるように定義することです。無名関数や即時関数、アロー関数など形によっていくつか種類があります。

#関数式とは
関数式（function expression）とは定義した関数を変数や定数に代入したものです。

#関数宣言と関数式の違いは？
一見、同じように見える関数宣言と関数式ですが、「巻き上げ」が起こるかの違いがあります。「巻き上げ」とは関数を宣言する前からでも関数を呼び出すことが出来るということです。

❶関数宣言の場合

```javascript
//関数の呼び出し
test();

//関数宣言
function test() {
  document.write("テストです!");
}
```
実行結果
>![スクリーンショット 2021-04-22 7.24.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/966135/bb671493-5241-9c87-46fd-ab11dcc19c32.png)

このように関数を先に呼び出してから関数を宣言しても関数が実行されてしまいます。

❷関数式の場合

```javascript
//関数式の呼び出し
test();

//関数式を定義
const test = function test() {
  document.write("テストです!");
};
```
実行結果
>![スクリーンショット 2021-04-22 7.28.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/966135/bd076652-ceb4-2b8a-ce2f-94131556291f.png)

ブラウザーが真っ白で何も出力されないのが分かります。このように関数式は「巻き上げ」が起こりません。つまり定義した後からでないと呼び出して実行されません。

# 「巻き上げ」はバグの元になる&原因探しが難しい
関数宣言の場合、後から宣言しても関数が実行されてしまいます。便利そうに見えますが、バグの原因になる可能性があります。昔よく使われていた変数宣言の「var」が非推奨になり、「let」を使うようになったのと同じです。また、宣言された関数を探すのが難しくなるので、バグの修正に時間と手間が掛かってしまいます。googleでも「関数式」を使うようにとコーディングルールで決まっているようです。 

#参考記事
https://www.fenet.jp/dotnet/column/language/3161/
https://www.yamagome.net/journal/8cb45a-javascript-%E9%96%A2%E6%95%B0%E5%BC%8F-%E3%83%A1%E3%83%AA%E3%83%83%E3%83%88
https://it-biz.online/web-design/function-expression/
【初心者】FTPプロトコル

#はじめに
FTPに関して備忘録としてまとめました。内容は初学者向けになります。

#FTP
・FTPとは「File Transfer Protocol」のことで、ファイルを転送するための通信規格。__クライアントとサーバー間で、ファイルのアップロードやダウンロードに使われるプロトコル__。

・ファイル転送を行う際、データの容量が大きいとそのまま送ることはできないため、パケットと呼ばれるものにデータを分解する。このパケットをどのように分解し、どのように送受信するのか、どのように復元するのかということを決めたルールである。

・FTPサーバはインターネット側に位置して、Webサーバーと繋がっている。そのため__FTPサーバーを操作することにより、Webサーバ内のファイルを制御できる。__

＊ファイルを転送する通信プロトコルとしてHTTPもある。「HyperText Transfer Protocol」の略であり、HTMLで記述されたファイルをサーバーからクライアントへ転送する。利用するポートは80番が基本。

#FTP通信の仕組み

![ftp.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/969534/8083755b-f64a-ef97-ba45-07f24c3b2a85.png)

・PIとDTPが揃って初めてファイル転送が実現することができ、これらはサーバー側とクライアント側の両方にあり常に相互通信している。

・PI(Protocol Interpreter)は指示内容をプロトコルにインタプリンタ（翻訳）している。FTPクライアントによる操作が、直接FTPサーバーに影響するわけでなく、インタプリンタと呼ばれる中継ぎが存在しており、指示内容を自動で分解して伝えてくれる。

・DTP(Data Transfer Process)は使用されるファイルシステムのアクセス部分を指す。ファイル転送時に転送先のOSが転送元のOSと異なっていたとしても、DTPが転送時にモジュール化して使い分けることで、様々なOSにも対応する機能もある。


#コントロールコネクションとデータコネクション
先述したようにFTPはサーバー側・クライアント側共にPIとDTPの2種類の仕組みが動いている。

||PI(プロトコル・インタプリタ)|DTP(データ転送プロセス)|
|:--:|:--:|:--:|
|コネクション分類|コントロールコネクション|データコネクション|
|ポート番号|21|20|

クライアント側のPIは、サーバー側のPIに対してコネクションを発行する。この時に、サーバーでは21番ポートを開放して使用できるようにし、クライアント側からのアクセスを待つ。これを__「コントロールコネクション」__と呼び、クライアントからのコマンドを実行し、結果ステータスなどを返す。

一方で、実際のファイルデータの転送などはDTPが受け持つ。これを__「データコネクション」__と呼ぶ。データコネクションに使用するポートはコントロールコネクションと異なるため。FTPでは2つのポートを使用している。
__データコネクションを別に発行している理由はデータ転送をスムーズに行うため__である。

プログラムは単一処理の連続で成り立っているため。もし、一つのポートで命令系統と転送を同時に行った場合、大量のデータを転送中にはそのデータの転送終了まで別の処理は実行できない。
これを分けることで転送途中でも別の命令を判断でき、__同時にいくつものファイルを転送できるようになっている。__






#FTPのデメリット
FTPはクライアントとサーバー間でファイル転送のやり取りを行うが、その通信は__暗号化されていない。__つまり、悪意がある第三者にIDやパスワードなどのログイン情報が盗まれれ__通信内容が外部に漏れてしまう危険性__がある。
対応として、SSHというプロトコルを使って暗号化された通信を利用する「STPS」であれば安全性が高く。最近のサーバーはSFTPを利用していることが多い。
##FTPS
FTPのセキュリティのデメリットを改善したファイル転送プロトコルで、SSHを用いており、ユーザー名やパスワーなどの認証情報を暗号化してファイル転送できる。

参考：
https://it-trend.jp/file_transfer/article/104-0004
https://it-trend.jp/file_transfer/article/protocol
性悪説でモノをコントロールし、性善説でひととかかわりたい

リモートワークでも「雑談」をもっとしないとな、と思い、そのノウハウを考察したものです。端的には参考にしたいのは以下のような話。

https://qiita.com/viva_tweet_x/items/dd9d3353d1b961fd1c71

https://qiita.com/kojimadev/items/4b28f801863cf4e8f0da

https://qiita.com/kojimadev/items/9f54d2d1e67d73ccfecb

> 休憩は積極的に取る
毎日1回以上Zoomのビデオ通話を誘う
分報とポジティブフィードバック
朝会(デイリースクラム)
相手へのメッセージは語尾に気を付ける
リモートワークだからこそペアプロ/モブプロ
Zoomの通話は顔が見える状態にする

等など。そして**「ザッソウ」**。

https://www.itmedia.co.jp/business/articles/1908/30/news004_4.html

ということで、自発的にザッソウが芽生える性善説の関わり合いをしたいなと言う話。
結論としては以上のいくつかを実践してみたいなというお話です。

## 悩み

- 先輩や周りへの相談
- 1on1 
- etc. 

それらって、管理されて、やらされてやるものなのだろうか？という疑問があった。

## それらへの解決策

しかしどうしたら**自発的なそれ**が定着するかなと考えた時に、**「ホウレンソウ」ではなくて「ザッソウ」** という考え方があることを読んだ。以下解釈。

- ホウレンソウ = 性悪説 のマネジメント
- **ザッソウ = 性善説 のマネジメント**

性悪説のマネジメントの何がイマドキでないか。それは「管理する人目線」のマネジメント手法であり、人はどうせ失敗する、という考え方にあるからだと思う。自分が部下目線で、始めから失敗すると思われていたらどうかということ。人を見て泥棒と思うような管理の仕方を上司にされたら、やる気が無くならないかどうか。

誤解してはいけないのは我々開発者、モノやコトに対しては性悪説で良いということだ。プログラムの型チェックだValidationだlintだみたいなこと、TODOリストやスケジュール、あるいは必達納期。各種ツールやマネジメント手法は忘れがちなものを補完し、失敗を未然に防ぐことを目指す。それに大いに学ぶべき。

だがチームの人間と人間との関わりみたいなものは、機械的なルールにしても得たい結果にはなかなかならない。「それをやるのは自分が得をするためである」と**自発的に**皆自身が納得できるように場をつくらないといけない。

- 相談とか1on1とか。やると何が良いかと言うと、自分が得だから。
- 予め上司や先輩が自分の案件のマズイところを把握してくれるし、気にかけてくれる。
- こういう事を考えているんだなと理解してくれる。

それはお得だからだと思うのだが、でもそれができるのは周りを信用しているからであり、話しやすい関係がつくれているからこそ、でもある。だからね。うまく 1on1 できてないな、管理できてないな、と悩む上司の皆さんって、その原因の1つは話しづらい場を作ってしまっているアナタ自身かもよということですね。

当記事の表題: エンジニアリングと言ってよいのか迷ったので「コントロール」とした。マネジメントというのかこれも迷ったので、「ひととのかかわり」とした。


## 性善説

https://qiita.com/noto/items/982d42f086f527881990#%E3%81%93%E3%81%93%E3%81%A7%E8%A8%80%E3%81%86%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%8B%E3%82%A2%E3%83%AA%E3%83%B3%E3%82%B0%E3%83%9E%E3%83%8D%E3%82%B8%E3%83%A1%E3%83%B3%E3%83%88%E3%81%A8%E3%81%AF

> 人を管理・コントロールする
> というより

> 性善説に基いて信頼して仕事を任せられるメンバーを集める
> その人たちがエンジニアリングに集中できるようあらゆる問題解決を行う
> 問題を感じる時、声を上げられるように心理的安全性を確保する
> 仕事の成果と、メンバーの成長を重ね合わせられるよう目標設定/評価する
> 他部門、他職種の人との調整・対話を行う/促進する
> **ここにあげたようなことを自然と実現できるような仕組みづくり、意思決定をする**


https://qiita.com/yasuoyasuo/items/37cc24440b278363339e

> 商用システム開発プロジェクトに関わる限り、ある一定範囲で社外パートナーに協力を得ることが一般的です。その場合、正社員とパートナーさんをどう扱うか問題になるわけですが、当然限られた時間と環境で最大の生産性を上げて頂くことが、発注側にとって得たい状態であることは間違いありません。
そう考えると、原則発注者側は道徳倫理上は勿論のこと、経済合理性の観点でも、**横柄な態度を取ったりして心理的安全性を阻害するようなチームの空気を作ることは、全く得策ではありません。
コミュニケーションの黄金律は「自分がそうしてもらいたいように振る舞う」ことにあります。**もし性悪説にならざるを得ないとしたら、パートナー選定時点で間違っていると考えたほうが良いでしょう。

性悪説でモノをコントロールし、性善説でひととかかわりたい、ということだ。

https://qiita.com/moritanzania/items/a1b87223a0be4a9ae07f

> PART1 性悪説に基づいたルール作り
> PART2 性悪説で考える必要がないなら、性善説で考えよう


## まとめ

https://gendai.ismedia.jp/articles/-/59797?imp=0

https://www.flierinc.com/interview/interview128

> **ザッソウ**によって相互理解が深まり、心理的安全性が生まれる。さらには、率直に意見を言い合えることで成果が出やすくなり、新しいアイデアが生まれていく

なるほどなー、ということで結果報告はまた後日となる。ですが以上、各種の記事たちとやりたいこと整理。参考になればさいわいです。