OmniAICreator/Qiita-1.07M huggingface dataset:
【AWS】セキュリティ関連ツール

# IAMとは
AWSアカウントのIDやアクセス権の管理ツールのこと。
「Identity and Access Management」の略。
個人で使う分にはそこまで意識する必要もないところではあるが、企業で複数の人が共同でアカウントを利用するときは必要。例えばプロジェクトのリーダーとメンバーで使える機能は違った方がいいし、派遣で参画した人に重要な機能の操作をできるような状態にしておくことは危険。その辺りを制御してくれるのがIAMである。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2665477/c6f39605-d806-7bd5-604b-13cbb3bd2db2.png)

実際にIAMアカウントを作っている様子を見ると一番イメージが湧きやすい。

https://hacknote.jp/archives/44404/

# IAMユーザー
1つのアカウント（企業アカウントをイメージすると分かりやすい）に対して作成されるユーザーのこと。
週末プロジェクトとかでは1つのアカウントのID/PWを裏で共有して使い回すことがあるかと思うが、会社のプロジェクトでは危険。IAMユーザーごとにID/PWが割り振られてログインを行うようにする。

# IAMポリシー
>「何に対して」「どのような操作を」「できるか（できないか）」の権限を記述したドキュメントのこと。これをIAMユーザーや後述のIAMロールに割り当てることで、「誰が」その権限を持つのかといったことを決定します。
ポリシーの例：
AdministratorAccess：管理者権限で全部許可
ReadOnlyAccess：見るだけ許可
AmazonS3ReadOnlyAccess：S3を見るだけ許可

# IAMロール
上記のIAMポリシーで定義された権限を束ねた概念的な名称のこと。
例えば「プロジェクトリーダー」は全ての権限が与えられるべきである。

>ロール：レジ係　→　ポリシー：レジシステムへのアクセス権など
ロール：在庫管理係　→　ポリシー：在庫システムへのアクセス権・更新権限など
ロール：オンライン注文係　→　ポリシー：オンラインシステムへのアクセス権・更新権限など



# KMS
AWS Key Management Serviceのこと。暗号化や復号のための鍵を管理するサービス。
CloudHSMというサービスもあるが、こちらはVPC内で専用のハードウェアを利用して鍵を管理するもので、相当大規模かつ法令遵守が求められるサービスでない限り利用されることはない。
一般的にはAWSで管理されるKMSが利用されることが多い。[こちらの記事](https://qiita.com/miyuki_samitani/items/c3c871e2312b9a47b9e2)が分かりやすかったです。ありがとうございます。



# 参考
https://dev.classmethod.jp/articles/aws-iam-beginner/

https://cloud5.jp/aws-signin-update/

https://qiita.com/miyuki_samitani/items/c3c871e2312b9a47b9e2
データ分析基盤の調査及び検証_part.1

# データ分析基盤の調査及びまとめ

データ分析基盤を構築するのに紆余曲折あったので、まとめていく
Part.1ではOSSツール用いて開発したが、途中で開発を中断した事について書く
Part.2では構築した際に用いたツールについて記載予定

## 背景
分析基盤が存在していなく、データ分析やAIの開発はローカル環境で実施しており、作業が非効率となっていた

## 目的
データ分析基盤を作る事で作業のスピードを上げ、DX推進を図る

## 構成図

ざっくりとした構成図は以下の図の通り
データレイク・DWH・データマートの3層構造でデータ活用を予定

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1064902/39702bce-2acb-93d7-700a-923d13d9e496.png)


データ分析基盤を構築する上で、以下3点を調査・検討する必要がある

①：クラウド(DWH)の選定
②：ETLツールの選定
③：ワークフローの選定




## 調査

### DWHの選定 (AWS or GCP どっちなのか？)
分析の要となるDWHを決める必要がある
様々な記事を見る限りどうやらRedShiftとBigQueryが2強らしい(snowflakeは記事が少なかった...)

|  |BigQuery  |RedShift  |
|---|---|---|
|環境設定有無  |無  |有  |
|スケーリング  |オート  |マニュアル  |
|料金  |分析量＆ストレージ量に応じた従量課金  |コンピューティングリソースに応じた従量課金
|データ加工  |加工前・後のデータを永続的に保持可能  |複雑なパイプラインをサービス上で定義可能  |
|データ連携  |サービス内でデータを保存  |サービス外でデータを保存  |

BigQueryのシンプルなUI/UXに惹かれて、**BigQueryを採用**

### ETLツールの選定
DWHは決まったが、データを移送するに何を使えば良いのか決まっていなかったので、洗い出した

|提供形態  |ツール名  |コネクタの機能性 |デバックのし易さ |
|---|---|---|---|
|オープンソース|Embulk,flutend,Apache Sqoop|△|◯|
|有償製品|DataSpider,ASTERIA,Talend|◯|✕|
|クラウド|AWS Glue,AWS DMS,GCP CDF,DCP DMS|◯|△|

有償ツールはどれも定額かつ高額で、作業に対して効果を出せないと感じていたのでOSSを選定
OSSの中でも多くの企業で採用されている？ **Embulkを採用**

### ワークフローの選定

Embulk単体だけでは定期的データを持って来れないので、Embulkを動かすワークフローが必要

|　ツール名 |概要  |言語 |
|---|---|---|
|Apache Airflow (OSS)|定期的(日次)に動かすデータパイプラインの記述に特化|Python|
|Luigi (OSS)|Pythonで書かれたデータフロー制御フレームワーク|Python|
|Digdag (OSS)|yamlでシンプルにワークフローを定義|yaml|
|Prefect(OSS)|Luigiの上位互換|Python|
|Argo (OSS)|ジョブをk8s上で動かすよう汎用的に記述|yaml|
|Kubeflow (OSS)|パイプラインを定義しそれらを管理、統合するためのツール|Python|
|Cloud Composer (GCP)|Apache Airflowと同様|yaml|

Embulkを軸して、参考記事を漁っていたら、**記事が多いDigdagを採用**


## 結果
実施したこととしては3つ
①：Embulk単体でデータ移送 (ローカル検証)
→検証成功
　DBデータの移送は非常に簡単！　
　しかし、他アプリケーションに対応しているケースが少なかったので別途でフルスクラッチ開発が必要

②：DigDagとEmbulkを組み合わせてデータ移送 (ローカル検証)
→検証成功
　DigDagとEmbulkはDockerを用いて検証
　DigDagの書き方に慣れる必要があり、保守・運用をするのは現状のメンバーだと厳しい

③：GCP上で②を実装
→検証失敗
　GCEで検証出来たが、費用とセキュリティ面で課題
　Cloud run は仕様理解が足りていなく、検証まで至らなかった

## 総括
OSSのEmbulkとDiddagを用いて分析基盤を作ろうとしたが、課題が想定以上に多く出たため開発を断念

[課題]
**1.費用面**
**2.セキュリティ面**
**3.学習コスト面**

今後は課題をある程度クリアするために調査を継続していく(Part.2に続きます)


## 参考
検証するに辺り各サイトを参考にさせていただきました

**[選定部分]**
https://boxil.jp/mag/a2392/
https://qiita.com/elyunim26/items/15db924e4c9833e5050a

**[実装部分]**
https://www.m3tech.blog/entry/2020/12/19/110000
https://engineer.blog.lancers.jp/sre/replace-digdag/
https://www.datacurrent.co.jp/column/embulk-on-docker20210519/
https://qiita.com/hoto17296/items/a7d69172050fa9aab045

**[公式ドキュメント]**
・Embulk
https://qiita.com/hoto17296/items/a7d69172050fa9aab045
・Digdag
https://docs.digdag.io/

**[書籍]**
実践的データ基盤への処方箋〜 ビジネス価値創出のためのデータ・システム・ヒトのノウハウ
https://amzn.to/3O1DRNW
MySQLの.mylogin.cnfを使ってみた

# 環境情報
OS : CentOS (Docker)
DB : MySQL8.0

# .mylogin.cnfとは
ログインファイルに認証情報を保存できます。
設定するとログインパスを指定するだけでMySQLにログインできるようになります。

このオプションファイルは暗号化されたファイルであり、mysql_config_editorユーティリティを使用して作成します。

# 使い方
## MySQL接続用のユーザーを追加と切り替え
まず、MySQLに接続するためのユーザーを作成し、ユーザーを切り替えます。`

```shell
sh-4.2# useradd -m hoge && 
sh-4.2# echo "hoge:hoge" | chpasswd && 
sh-4.2# echo "hoge ALL=(ALL) ALL" >> /etc/sudoers
```

```shell
sh-4.2# sudo su - hoge
```

## ログインパスを設定
mysql_config_editorユーティリティを使用してログインパスを設定します。

構文は以下の通りになります。

```shell
mysql_config_editor set --host=<接続するサーバ> --login-path=<ログインパス名> --user=<使用するMySQLのユーザー> --password
```

今回はローカルのMySQLにmysqlユーザーで接続できるように設定します。
コマンドを実行し、パスワードも入力します。
```shell
[hoge@2476896863b5 ~]$ mysql_config_editor set --host=localhost --login-path=myloginpath --user=mysql --password
Enter password:
[hoge@2476896863b5 ~]$
```

## 設定内容と確認
mysql_config_editorのprintコマンドを使えば、設定内容も確認できます。

```shell
[hoge@2476896863b5 ~]$ mysql_config_editor print --all
[myloginpath]
user = "mysql"
password = *****
host = "localhost"
```

## MySQLに接続

```shell
[hoge@2476896863b5 ~]$ mysql --login-path=myloginpath
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 20
Server version: 8.0.29 MySQL Community Server - GPL

Copyright (c) 2000, 2022, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>
```

## 設定したログインパスを削除
設定したログインパスを削除するにはremoveコマンドを使用します。

```shell
[hoge@2476896863b5 ~]$ mysql_config_editor remove --login-path=myloginpath
[hoge@2476896863b5 ~]$ mysql_config_editor print --all
[hoge@2476896863b5 ~]$ 
```

ちなみに、以下のように--userなどの指定した部分だけを削除することもできます。

```shell
[hoge@2476896863b5 ~]$ mysql_config_editor remove --login-path=myloginpath --user
[hoge@2476896863b5 ~]$ mysql_config_editor print --all
[myloginpath]
password = *****
host = "localhost"
```

# 参考文献
https://dev.mysql.com/doc/refman/8.0/ja/mysql-config-editor.html
【C++】基礎を学ぶ⑦～cinで入力を受け取る～

# `cin`で入力を受け取る
`cin >> 変数`でキーボードからの入力を受け取ることができます

## `cin`の使い方
変数を宣言する
`cin >> 変数`で変数に値を代入する
```cpp
#include <iostream>

using namespace std;

int main(){
  int x;
  cin >> x;
  cout << "入力した値：" << x << endl;
  return 0;
}
```
入力
```
1
```
出力
```
入力した値：1
```

## 複数の値を受け取る
```cpp
#include <iostream>

using namespace std;

int main(){
  string x;
  int y;
  cin >> x;
  cin >> y;
  cout << x << y << endl;
  return 0;
}
```

### スペース区切りで入力する
入力
```
Hello, 1
```
出力
```
Hello,1
```
### 改行区切りでも入力できる
入力
```
Hello,
1
```
出力
```
Hello,1
```

## 次の記事
[【C++】基礎を学ぶ⑧～if文～](https://qiita.com/rapirapi/items/0b4af3fd65c169826ddd)
Linux上のVirtualBoxでUSBが認識しない問題の解決方法(MIDIキーボードとか)

私は普段ManjaroというLinuxディストロを使っています。
また、趣味でDTM(DeskTopMusic、つまりは作曲活動)を行なっているのですが、Linuxでの作曲は色々と難しいので仮想環境でWindowsを動かしてやろうと思ったわけです。
しかし、MIDIキーボードを接続したもののVirtualBox上でUSBが認識されないというトラブルが起きました。
そこでちっと作業をしてやれば上手くいったので、そのメモです。

自分の環境(ManjaroLinuxというArchLinuxベース)での話なので他のディストロとは具体的な作業内容が少し異なることもありますが、ご容赦下さい。

# 解決法
## 1.Extension Packを入れる
これを入れると機能が色々と増えます。
ただし、VirtualBox自体はオープンソースであるもののExtension Packはオープンソースでない、という点は気にする人は気にするかなと。
自分の環境だとAURヘルパーを用いて、
~~~:bash
yay -S virtualbox-ext-oracle
~~~
で入れることができます。

## 2.vboxusersグループに利用するユーザを追加
具体的には
~~~:bash
sudo gpasswd -a $USER vboxusers
~~~
で追加しておきます。
これを行なわないとrootでしかUSBを認識できないみたいです。

以上です。
これでLinuxでもなんとかDTMができそうですね。
【AWS】各種サービスのスケーラビリティについて

# DyanamoDB
AWSが提供するマネージドNoSQLデータベースサービスのこと。
Firebaseと同じ。Key-Value型のデータベースを提供しており、拡張性に優れている。

1. サーバーレス
>フルマネージドなのでプロビジョニングやパッチ、管理用のサーバーだけでなく、インストール、メンテナンス、または運用するソフトウェアも不要です。DynamoDBではテーブルを自動的にスケーリングして容量を調整し、パフォーマンスの維持ができます。

ちなみにプロビジョニングとは「必要に応じてネットワークやコンピュータの設備などのリソースを提供できるよう予測し、準備しておく」という意味合い。供給や設備等の意味を表すプロビジョン（provision）という単語がもととなって派生した言葉。

2.  高可用性設計
可用性とは「壊れにくい、復旧が早いなど耐障害性に強い、信頼性の高いシステム」といった意味合い。
単一障害点を持たない構成となっているので、サービス面の障害対応やメンテ時の運用を考える必要がない。

3. キャパシティユニット
簡単に言うと読み込み/書き込み容量のこと。従量課金性とは違い、設定したキャパシティ（DynamoDBに1s あたりどれくらい書き込めるか）に応じた「常時課金」システム。高機能なバケツを用意したら、その分常に高めの費用を払い続ける必要がある。

https://zenn.dev/motoyannn/articles/238c7860d3b280


# Lambda関数
サーバーをプロビジョニングしなくてもプログラムを実行できるコンピューティングサービスのこと。
アプリ作成において必要なソースコードを書き上げたとする。外部に公開する際に、EC2を使ったとしても、インスタンスを作成し各種ソフトウェアを自分でインストールしてあげる必要があった。Lambdaを使うとその辺りの手間隙いらずとなる。ソースコードを用意するだけであとは勝手にデプロイできるような環境が整備される。FirebaseのCloud Functionと同等サービス。


# APIゲートウェイ
APIの管理や実行を簡単にしてくれる仕組み。
オートスケール機能もあり可用性に優れている。


>例えば、1つのWebサービスに「決済サービス」「ショッピングカート」「メール機能」「レコメンド機能」といった複数のAPIが使われている場合、クライアントはそれぞれのAPIと個別に通信することになりこの例でいえば計4回の通信が発生します。
APIゲートウェイを使うと、クライアントはAPIゲートウェイと通信を行い、APIゲートウェイがそれぞれのマイクロサービスと通信するためクライアントはマイクロサービスを知る必要がありません。

ちなみにマイクロサービスとは、小さなサービスを集合させて組み合わせることで作り上げられたサービスのこと。例えば商品データベースやデータ分析機能をそれぞれ別で作成して、それを組み合わせて作り上げられたサービスとかは該当する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2665477/3a0f5c5d-371c-643d-b247-cb4ce28938e9.png)

上の図の右側の例のように、4つマイクロサービスが存在する場合、クライアントがそれぞれ４か所と通信を行う必要がある。それでは非効率だということでAPIを管理するゲートウェイの出番が発生する。



# 参考
https://www.wafcharm.com/blog/api-gateway-for-beginners/

https://www.sunnycloud.jp/column/20210228-01/

https://mercart.jp/contents/detail/85
新しい分野のスキル習得・学習方法（技術書籍の上手な活用の仕方）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/499546/5b109a57-a067-5d83-7c7d-829f3710024a.png)


エンジニアにとって新しい技術分野への取り組みは常に求められます。新規プロジェクトにアサインされた時や新しいプログラミング言語を習得する場面など様々です。
できるだけ短期間に速やかに新しい環境での稼働準備を整え、1日も早く継続的アウトプットを出せるような習熟メソッドを身につけることが良いエンジニアの条件として不可欠です。

# 何から着手するか？
新しく取り組むテーマがすでに明確であれば、どこから取り組んでいいものかまずは最初の手がかりを掴みたいところです。本屋に行ってその分野の書籍を何冊もめくってみてもいいし、Kindleなど電子書籍を検索してタイトルを眺めたり、まえがきなど冒頭の無料で読める部分をめくってみることもすぐにできる有効な一歩となります。特に電子書籍などは、すぐにその書籍が売れるように無料で読める部分にとっつきやすく面白い内容が集められていることが多いように思います。

@KatsuShin の場合は下記の方法で色々な情報にあたってみます。
### 適切なキーワードによるネット検索
- 〜入門:
    - 概念、基礎知識、トレンドなどバックグラウンドとなる全般的な最初の情報収集を行う場合（例: GCP入門、NFT入門、Cloud入門,,,etc.）
- チュートリアル
    - 開発環境の構築、最初のコンパイル、buildまでたどり着くことを目的とする場合（言われるがまま実行していけば最短で実践理解できる）
### e-learning
- チュートリアルと同様、環境構築や最初のとっかかり、手順習得に有効
### Youtube動画検索
- 別のことに取り組みながら音声だけでも片手間で情報収集できる（Youtubeプレミアムであればアプリを閉じてバックグラウド再生で寝ながら学習できる）
### 書籍
- 本屋でタイトルを眺める、好きなところだけ立ち読みをする
    - 内容がすんなり入ってくるまたは興味のマッチングが高ければ購入
### 電子書籍 
- 無料で読める「はじめに」や本書概要は最初のとっかかりとして読みやすく、引き続きチュートリアルなどにもそのまま入っていける

# 書籍は好きなところ・面白いところ・理解できるところからで良い（書籍と実践を行ったり来たりしよう）
特に書籍などを読むコツとしては最初から最後まで律儀に読了する必要はないということです。理解できる、または興味を持って読み進められる読みたい部分から読むでいいと考えます。
今のあなたの知識レベルによって興味を持って読み進められる場所が違うのです。これからその分野をはじめようという場合には「はじめに」「概要」がすぐ頭に入ってきやすいです。

逆にまだ開発環境の構築もできていない時ににデバッグ方法の効率化や特殊な問題の解決方法についての情報に触れてもあまり響いてきませんが、あとでデバッグを集中的に行うフェーズで実際にその問題にまさに遭遇した時には細部に渡る具体的な解決アプローチについて興味と集中力を持って読み進め理解できるようになるはずです。

### 何の情報が必要な時はどこに行けば良いか頭の中にindexを作っておこう
また、書籍全部を読破する必要はなく、逆にどこにどんなことが書かれているかおぼろげに記憶に留めて置くことだけでも、実際に業務中に問題にぶちあたった時などにまた書籍に立ち戻る場合に大変役に立ちます。
頭の中にindexだけでも留めておけると良いです。

# その後のステップ
### 1. チュートリアルに取り組んでみる
- 指示通りにステップを完了することでプログラミング開発環境や実行環境の構築や簡単なデバッグ手順の理解まで実践を通して完了できる
    - e-learningなども有効
### 2. 自分で課題を設定して取り組んでみる
- アプリケーション開発であればサンプルのUIについてワイヤフレームを引いてみる
- 動作させてみたい簡単な仕様をドラフトしてみる
- 上記についてサンプルコードやテンプレートを参考にしつつ実装してみる
- 開発環境に含まれているテンプレートをダウンロードして動作させてみる、改造してみる
    - 複数のテンプレートから実現したい機能抜き出してマージして1つのUI上で動作させてみる
### 3.　もう一度書籍に戻る
- 自分で設定した課題や実際に業務中に直面した課題を抱えた状態でもう一度書籍に戻ってみることで、以前とは全く違ったレベルの興味や集中力を持って読み込める部分が増えているはず
    - 解決したい答えを探すためにページをめくるのは、最初の入門や概要把握とは意識や集中度合いが異なる
    - 実践フェーズに入り経験をつんで行くことにより逆引き辞典のような技術書の内容もどんどん頭に入ってくようになる

ここまでの流れを1〜2、3週間で完了できれば、ある程度速やかに新しい技術分野の案件に入っていけるのではないでしょうか。人によってアプローチは様々かと思いますが是非参考にしてみてください。
【C++】基礎を学ぶ⑥～const定数～

# `const`定数
`const`定数を使用することで後から値の変更ができなくなる
複数人で開発する場合に後から値を変更できなくするために使うことができる

## `const`の使い方
```cpp
const int x = 10;
```

## 後から値の変更ができない
```cpp
#include <iostream>

using namespace std;

int main(){
  const int x = 10;
  x = 15;
  cout << x << endl;
  return 0;
}
```
```
ビルドを開始しています...
C:\MinGW\bin\g++.exe -fdiagnostics-color=always -g C:\Git\C++\test.cpp -o C:\Git\C++\test.exe
C:\Git\C++\test.cpp: In function 'int main()':
C:\Git\C++\test.cpp:7:5: error: assignment of read-only variable 'x'
    7 |   x = 15;
      |   ~~^~~~

ビルドが完了しましたが、エラーが発生しました。
```

## 値の初期化をする必要がある
```cpp
#include <iostream>

using namespace std;

int main(){
  const int x;
  x = 10;
  cout << x << endl;
  return 0;
}
```
```
ビルドを開始しています...
C:\MinGW\bin\g++.exe -fdiagnostics-color=always -g C:\Git\C++\test.cpp -o C:\Git\C++\test.exe
C:\Git\C++\test.cpp: In function 'int main()':
C:\Git\C++\test.cpp:6:13: error: uninitialized const 'x' [-fpermissive]
    6 |   const int x;
      |             ^
C:\Git\C++\test.cpp:7:5: error: assignment of read-only variable 'x'
    7 |   x = 10;
      |   ~~^~~~

ビルドが完了しましたが、エラーが発生しました。
```

## 次の記事
[【C++】基礎を学ぶ⑦～cinで入力を受け取る～](https://qiita.com/rapirapi/items/1155e66fbbaad31ce3ab)
IAMユーザーで請求情報を確認する方法

# 概要

IAMユーザーで請求関連の情報を確認しようと思ったら確認できなかったので、
備忘録として書きました。

# アカウント設定

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2733779/322b800f-c54f-34eb-dddb-0222b80b4792.png)
まずはアカウントを選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2733779/6813fcec-4613-89ca-98bb-b947c8a16364.png)
次に編集を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2733779/15307cb3-508c-a700-14a3-1ff692b82dae.png)
IAMアクセスのアクティブ化にチェックを入れて、更新ボタンを選択します。

以上で請求ダッシュボードにアクセスできるようになります。
※IAMユーザーにAdmin権限が付与されていることが前提です。
【C++】基礎を学ぶ⑤～複合代入演算子、インクリメント～

# 複合代入演算子とは
プログラムを短く書くことができる演算子のこと
複合代入演算子を使うことによって`x = x + 1` を`x += 1`のように書くことができる

## 複合代入演算子`+=`を使ったプログラム
```cpp
#include <iostream>

using namespace std;

int main(){
  int x = 1;
  x += 1;
  cout << x << endl;
  return 0;
}
```
```
2
```

## `+=`以外の複合代入演算子
他の演算子についても同様に書くことができる
```cpp
#include <iostream>

using namespace std;

int main(){
  int a = 5;
  a -= 2;
  cout << a << endl;
 
  int b = 3;
  b *= 1 + 2;
  cout << b << endl;
 
  int c = 4;
  c /= 2;
  cout << c << endl;
 
  int d = 5;
  d %= 2;
  cout << d << endl;
  return 0;
}
```
```
3
9
2
1
```

# インクリメント・デクリメント

インクリメントは１増加させる操作
`x++`または`++x`と書く
デクリメントは１減少させる操作
`x--`または`--x`と書く
```cpp
#include <iostream>

using namespace std;

int main(){
  int x = 5;
  x++;
  cout << x << endl;
 
  int y = 5;
  y--;
  cout << y << endl;
  return 0;
}
```
```
6
4
```

# 糖衣構文（シンタックス・シュガー）
プログラミング言語において、読み書きしやすくするために導入される書き方のこと
「複合代入演算子」、「インクリメント」もそのひとつである

# 次の記事
[【C++】基礎を学ぶ⑥～const定数～](https://qiita.com/rapirapi/items/4594e17af0dfce01ccab)
3GPP V2X(車と何かの通信)アーキテクチャ　図解

# V2Xとは
車と何かの通信、V2V（車と車） 、V2歩行者、V2アプリ
今回調べているのはモバイルの標準を作る3GPPの仕様なので、5Gや4G(LTE)を使った物が対象です。
//作成中　TS 23.285 4.2.3まで読んだ。
//8/30 追記 TS 24.386

参考に要件レベルの超概要は下記のNoteにもまとめています。
https://note.com/shun_kane/n/n364206f790fb?magazine_key=m8f2b0f166a5e

# V2Xアーキテクチャ　概要
Vehicle to Everything(V2X) 。
LTE or 5Gの通信事業者網を通ったり、車間で直接通信したり。①自動運転　②隊列走行　③生データ送信　④遠隔操作。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2311625/3e8d08e9-498c-1786-eec0-2b069ceaf92d.png)


## 参考文献
[1] 3GPP TS 23.285 V17.0.0 Architecture enhancements for V2X services
[2] 3GPP TS 24.386 V17.0.0 User Equipment (UE) to V2X control function



# 詳細 TS 23.285 読み解き 38ページまで

## 3.2 Abbreviations　略語
~~~
AID：　　 Application Identifier
C-TEID：　Common-Tunnel Endpoint IDentifier
ITS：	  Intelligent Transport Systems
ITS-AID： ITS Application Identifier
PSID：	  Provider Service Identifier
RSU：　　  Road Side Unit
SIPTO@LN： SIPTO at the Local Network
USD：　　  User Service Description
V2X：　    Vehicle-to-Everything
MBMS：　　 Multimedia Broadcast and Multicast Service
PC5:　　　 V2V(車間の直接通信)のインターフェース
LTE-Uu　　 V2N(車とNetwork）間のインターフェース
~~~

## 4	Architecture model and concepts
・情報の送受信は1:1・多対多。
・V2X Application ServerとV2X Appliは(3GPPではスコープ外）

## 4.2.1.1	Non-roaming architecture for PC5 and LTE-Uu based V2X communication
PC5(車と車)とLTE-Uu(車とネットワーク）の通信アーキテクチャー　キャリア網側の装置かWebサーバ等の装置かわかりにくい。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2311625/4d2ea556-11fb-4b90-4be9-6f3c2c5c38f5.png)

もう少し位置関係を意識するとV2X(1対1)のアーキテクチャはおそらくこんな感じ？
基地局経由車間：LTE-Uu、直接車間：PC5、V2X Control経由:V3？
// LTE-Uuは、基地局（RAN）の誰がルーチングしてるのかわからない。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2311625/64a699d9-4571-ba62-c762-408edcc1659e.png)

## 4.2.3	Reference points
V1 : out of scope 端末内のV2XアプリとV2X アプリ server
V2 : V2X アプリserverとV2X コントロール間(V2Xコントロールはキャリア網内)。
V3 : UE(端末の通信機能)とV2Xコントロール間
V4 : V2X コントロールとHSS（キャリアの加入者管理）
V5 : out of scope V2Xアプリ間
PC5 : V2X UE（端末の通信機能間）
 

# 詳細 TS 23.386  読み解き 

The V2X messages can be transported using:
-	V2X communication over PC5; and
-	V2X communication over LTE-Uu.
PC5 は UE(この場合車)間 
LTE-Uuは、UE～V2X application server間（over LTE）
V3は、UE～V2X application server間（LTE非経由）

## 6.1	V2X communication over PC5
Both IP based and non-IP based V2X communication over PC5 are supported. For IP based V2X communication, only IPv6 is used. IPv4 is not supported in this release of the present document.
PC5 は non-IP base or  IPv6で通信する。
LTEを使う場合のメッセージの送り方は、TS 24.334 ProSe(LTEの中継)の10.4 One to manyと同じ。
SQL データの更新

#### 新規データを1件追加する insert

* 構文

```
insert into
  テーブル名 (列1, 列2, 列3, ・・・)
values
  (値1, 値2, 値3, ・・・)
```

注意点:列リストと、values句の値リストは、列数が一致している必要がある

#### 列リストを省略して1件レコードを追加する。

* values句に列の定義順、カンマ区切りで、値を設定
* ただし、列を省略するには、条件がある。
* テーブルの全列に対して、値を指定する必要がある。

#### 行を複数追加する

* 構文

```
insert into
  テーブル名 (列1, 列2, 列3, ・・・)
values
  (値1, 値2, 値3, ・・・),
　(値1, 値2, 値3, ・・・),
　(値1, 値2, 値3, ・・・);
```

※MySQL,PostgreSQL, SQL Server, DB2では使用可能。Oracleでは使えない。

#### レコードの更新 update

* 構文

```
update テーブル名 set 列1 = 値1, [列2 = 値2...]
  [where 条件式];
```

#### 行の削除

* 構文

```
delete from テーブル名[where 削除条件];
```

※注意点

* deleteで削除したデータは、基本的には元に戻せない。
* 大量のデータをdeleteする時に予想外に時間が掛かる場合がある。
* うっかり、where句を指定し忘れると、テーブル全体が削除対象となる。

#### 削除条件にサブクエリを使う

* delete文を使用
* 削除条件にサブクエリを使う

※MySQL,PostgreSQL, Oracle, SQL Server, では動作する。DB2では動作しない。
Propsを使って画面表示を使い回す（React）

Reactの基礎を書籍を読みながら勉強しています

https://ebookjapan.yahoo.co.jp/books/656741/A002708884/

ネット上の記事だとすでに非推奨となっている機能を使っているものが多いので書籍に沿って公式の資料を確認しながら進めています。

今回はPropsについて試してみますが、一言で表現すると引数を使って表示を切り替えることだと理解しました。

## 内容
・ユーザーによってボタンの表示を変える機能を作る
・ボタンの表示は共通化してProps経由で表示を切り替える機能にする

### 構成
index.tsx
button.tsx
proptest.tsx

### 画面の大枠

```tsx:index.tsx
import { ButtonTest } from './button';
export default function Index() {
  return (
    <Container maxWidth="sm">
      <Box sx={{ margin: 3 }}>
        <ButtonTest />
      </Box>
    </Container>
  );
}
```

### 画面の表示とボタンの呼び出し元

```tsx:button.tsx
import { Propstest } from "./propstest";

export const ButtonTest = () => {
  return (
    <>
      <h1>こんにちわ！</h1>
      <Propstest name='check' value='props test 2022/07/09' />
    </>
  )
}
```

### ボタンの表示を引数を元に切り替える

```tsx:propstest.tsx
export const Propstest = (props) => {
  const contStyle = {
    name: props.name
  }
  const onClickButton = () => {
    alert(props.value);
  }
  return <input type='button' value={contStyle.name} onClick={onClickButton} />
}
```

**画面**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110457/4c646c0d-e8bc-9fdd-0967-8b729d8cea61.png)


実際に使ってみるとシンプルな仕組みですが、説明の文章を読むと動的に注入だとか無理矢理日本語に割り当てられているので、フロントエンドに触れて来ず理解力がすごく低い自分には難しい概念でした・・・。

他のフレームワークとの長所短所の比較だったり、Reactの仕組み上の疑問が色々ありましたが書籍をパラパラ流し読みすることで回答が得られて2022年7月時点ではすごく良い書籍でした。
Cred SSP認証 を有効にできない

CredSSP ：Credential　Security Support Provider
つまり、サーバーやPCにリモート接続する際の認証要求を処理します。

Hyper-Vからクラウド上のサーバーにアクセスする際に、いくつかクライアント側に設定をいれます。
その手順の中に、CredSSP をクライアント端末にて有効にする必要がありました。

CredSSP 有効化にするには、以下のコマンドをPowerShellにて実行します。

コマンド：enable-wsmancredSSP -role client -delegatecomputer 'クライアントIP'

※Hyper-Vからクラウド上のサーバーにアクセスするには、このコマンドだけでは完了しません。

しかし、エラーが発生。

![powershell enable-wsman credssp.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2206656/7049df0a-1e9b-3116-2d2c-5bd0d0418798.png)

設定を有効にできない、とのエラーメッセージでした。

PowerShellを管理者権限で開いたり、ログインユーザーの権限を確認しましたが、変化なしでした。


【解決策】

ドメインコントローラーと疎通をとれる環境にしたらいけた！

このクライアント端末は、ドメインに参加していました。
設定時、ドメインコントローラーと疎通できない環境でした。

実行するコマンドは、ローカルグループポリシーの設定を変更するものなのですが、
ドメインに参加している場合、グループポリシーの反映関連で、ドメコンと疎通が取れないとローカルグループポリシーの設定を変更できないようです。
enable-psremotingでエラーが発生する

Hyper-V上で、クラウドにあるサーバーに接続するための設定の中で、
enable-psremotingを実行しました。

【enable-psremotingとは】
WinRMサービスによるリモート管理を有効します。
つまり、Windowsリモートサービスを有効にします。ってことかな？


【エラー内容】

PowerShellにて管理者権限で実行したところ、以下のエラーが発生。

![enable-psremoting.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2206656/6024dd1e-04cf-8e1d-d192-22bbb4db61be.png)



ネットワークの接続の種類をドメインネットワーク、もしくはPrivateに変更する必要があるようです。


【解決策】

ドメインコントローラーと疎通をとれる環境にしたらいけた！

このクライアント端末は、ドメインに参加していました。
設定時、ドメインコントローラーと疎通できない環境でした。

実行するコマンドは、ローカルグループポリシーの設定を変更するものなのですが、
ドメインに参加している場合、グループポリシーの反映関連で、ドメコンと疎通が取れないとローカルグループポリシーの設定を変更できないようです。
GraalVMでネイティブイメージを作成 on Windows

# 概要
GraalVMを使うとJavaアプリケーションをネイティブイメージ化できます。（JVM不要で実行できる）
パフォーマンスなどJVMで実行するのとかなり異なる特性を持ちますが、ここでは触れません。
Windowsでビルドを試したので、その手順だけ書きます。

# 環境
* Windows 11
* Java 17
* Gradle 7.4（Kotlin DSL）

# 手順

## Javaアプリケーションを書く
もちろんビルド対象のアプリケーションを書く必要があります。試すだけならHello worldでいいですが、私は（機能限定版ですが）tailコマンドを作ってみました。

https://github.com/dhirabayashi/mytail

## Visual Studioをインストールする
ネイティブイメージ化はGraalVMからC++のコンパイラを呼んで実行されるようです。なのでそのためのコンパイラが必要です。
コンパイラはいくつかあると思いますが、Visual Studioをインストールするのがいいようです。

現時点で最新版のVisual Studio 2022の無料版でいいです。

インストールするコンポーネントを選べます。私はいろいろやりたくていくつか選んだのですが、とりあえず「C++によるデスクトップ開発」だけ選べばよいかと思います。
![vs_install.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/321705/3030412e-2cc1-04e7-ba32-2227dd55e251.png)


## gradle-graalプラグインの導入
GraalVMを直接インストールしてもいいですが、Gradleプラグインを使うと自動的にダウンロードしてくれて比較的簡単にできます。

以下のような感じです。

```build.gradle.kts
plugins {
    id("java")
    id("application")
    id("com.palantir.graal") version "0.12.0"
}

graal {
    mainClass("com.github.dhirabayashi.mytail.MyTail")
    outputName("mytail")
    graalVersion("22.1.0")
    javaVersion("17")
    windowsVsVersion("2022")
    windowsVsEdition("BuildTools")
}
```

全体はこれです。実行可能Jarを作るための定義もありますが、もしかしたら必須じゃないかもしれません。
https://github.com/dhirabayashi/mytail/blob/master/build.gradle.kts

## ビルドの実行
あとはGradleから `nativeImage` タスクを実行すればOKです。
ただ、普通に実行するとGradleがC++コンパイラを見つけられなくて失敗します。Visual Studioをインストールしたときに追加される専用のコマンドプロンプトを使うと解決します。

これです。
![vs_cmd.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/321705/6d8d450b-5705-9d31-4811-ac63df1ef1be.png)

```cmd
> set JAVA_HOME=C:\Users\****\.jdks\corretto-17.0.3
> gradlew nativeImage
```

これで問題なければ `build/graal` ディレクトリの下にバイナリが生成されます。

# 参考リンク
* https://blog.johtani.info/blog/2020/02/28/kuromoji-cli/
* https://megascus.hatenablog.com/entry/2021/12/08/153020
* https://github.com/palantir/gradle-graal/issues/399
Salesforceのレコードデータ一括で全削除する簡単な方法

本橋孝昭です

Salesforceのレコードデータを簡単に全削除できる方法をお伝えします

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

https://www.youtube.com/watch?v=Bl56-MOYhOw

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


標準機能で「一括削除」もありますが、こちらはリードや取引先など削除できるオブジェクトが限定的です


![一括削除２.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/c74d048f-c2fd-7f15-e927-b0b8d46870c4.png)

※参考ヘルプ
複数のレコードおよびレポートの削除
https://help.salesforce.com/s/articleView?id=sf.admin_massdelete.htm&type=5

この機能では例えば商談オブジェクトレコードなどの削除はできません。

また、データローダを使えば削除も可能ですが、データローダ削除はSalesforceIDが必要なので削除の手間がかかります。

今回は簡単なデータ削除方法をご紹介します

例　商談オブジェクトレコードデータ全削除方法）

ステップ１
歯車マークをクリックし「開発者コンソール」をクリック
![S1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/ff2a642e-2879-6954-5485-e164bc2855b6.png)

ステップ２
「Debug」をクリックし
「Open　Execute Anonymous　Windouw」をクリック
![S2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/ab99093a-5376-7489-6d64-7d5050294241.png)

ステップ３
コードを記載し「Execute」をクリック
コードについて例えば商談オブジェクトレコードを全削除したい場合

delete [Select Id FROM Opportunity];

とします
![S3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/5225e0c9-a8a6-027f-c4aa-cd33fad7f7d4.png)


これで終了です。
Statusが「完了」になれば成功です
![S4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/5398003c-647e-b677-97af-8a1097cf9656.png)

このオブジェクトのレコード削除はカスタムオブジェクトはじめ様々なオブジェクトに応用可能です。

例えばケースオブジェクト削除の場合コードは
delete [Select Id FROM Case];

カスタムオブジェクトAAA（API参照名AAA__c）削除の場合は
delete [Select Id FROM AAA__c];

となります。

データ全削除をしたい機会があればぜひお試しください。
Container StationでPortainerを作成後、CPUリミットなどを設定すると起動に失敗する

# はじめに

QNAPのContainerStationでPortainerのコンテナを作成後、「CPUリミット」や「メモリー利用量」を変更すると、設定内容を適用するためのコンテナ再起動で、起動に失敗する。対症療法を示す。

:::note info
本事象を確認した環境
- ContainerStationのバージョンは、V2.6.0.483
- Portainerのバージョンは、2.14.0
:::

# Container StationでPortainerのコンテナを作成

![共有フォルダ設定.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2729778/856aa515-793e-eabb-ff2b-507ce50b1541.jpeg)

QNAPのContainerStationでPortainerのコンテナを作成する場合、「共有フォルダ」にDockerにSocket接続するための"/var/run/docker.sock"を設定しようとしても、フォルダツリーに現れず、直接入力もできないため、設定できない。

![CLIで作成a.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2729778/f951f7d6-08b8-296e-5c58-c80224e256c2.jpeg)

対処法を検索してみると、QNAPにssh接続してコマンドラインからコンテナを作成する手順が見つかる。

![Socket接続.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2729778/fbb91c8b-5bd3-f325-854a-83b9c549d135.jpeg)

実際、この手順でコンテナを作成してみる。作成後、Portainerに接続して、"local"のパネルの右下を見ると、"/var/run/docker.sock"を介して接続していると表示される。

# Container Stationで設定変更すると再起動に失敗

![CPUリミットなどの設定.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2729778/e0f63535-8a1b-b464-df24-c2d0bd1af2eb.jpeg)

Container Stationでは、「設定」のパネルで、「CPUリミット」や「メモリー利用(量)」の設定ができる。先のCLIでのコンテナ作成では、この部分は"CPUは100%"、"メモリーは全量"の設定になっている。これを変更し、「適用」ボタンを押すと、コンテナは再起動される。

![再起動に失敗a.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2729778/1cd3acb3-4349-dbac-0d38-abe87a166c1d.jpeg)

実施すると再起動に失敗する。メッセージによるとdocker-composeに失敗しているようである。

# 対症療法

とりあえずの回避策としては、dockerへのSocket接続をAgent経由の接続に変更する。

![agent作成a.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2729778/c4cf1fa0-e341-0a62-fcd3-4d6e428006f6.jpeg)

QNAPにssh接続してコマンドラインから"portainer/agent"のコンテナを作成する。作成したAgentのコンテナは、Container Stationから「設定」の変更を行っても再起動に失敗しない。

![要約.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2729778/d022d20b-bcfa-f88a-d016-ac89f731f907.jpeg)

次いで、Container StationのGUIでPortainerのコンテナを再作成する。この時、ホストとの共有フォルダとして"/var/run/docker.sock"を指定しない(そもそもできないが)。

![Agent接続.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2729778/718743e2-3c37-54a8-f78b-940e69e23233.jpeg)

Portainerに接続して、"Environments"からDockerにAgent経由で接続する。"nas332x_arm64"がそれだがパネルの右下を見るとAgent経由で接続している。

![コンテナ設定3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2729778/6a5d5d39-13d8-1976-74e0-4572126eff9f.jpeg)

このPortainerコンテナは、Container StationのGUIで作成したものであり、「CPUリミット」や「メモリ利用(量)」などの設定を変更しても、変更内容適用のための再起動に失敗しない。
miroのアイコン表示名の変え方（未検証）

miroでのログイン後のユーザー表示名変更についての手順です。

### 1 共有されたURLのホワイトボードにアクセスする。  
（初回アクセス時にはメールアドレスとユーザー名の登録が必要です。）
  
  
### 2 画面の左上のアイコンからダッシュボードに移動する  
![SS 2318.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565043/a1d8eabb-5d25-eaa6-8a3f-4eb8b9a2b80b.png)
  
  
### 3 ダッシュボード右上のアイコンをクリックし、設定画面へ  
![SS 2319.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565043/61d522c4-3414-13b4-56c5-e9c26e61c0d7.png)
  
  
### 4 名前を変更し、ダッシュボードに戻る  
![SS 2320.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565043/2b02e4e8-ff7b-4c0d-e9df-133628af7877.png)
  
  
### 5 ダッシュボードから該当のホワイトボードに参加する

という手順でできると思います。
[Salesforce] OAuth 2.0 ユーザ名パスワードフローで"authentication failure"が出たとき

Salesforceの認証に「OAuth 2.0 ユーザ名パスワードフロー」を使って下記のエラーが返ってきた場合、どこを確認し、どう対応すべきか？について書く。
```json
{"error":"invalid_grant","error_description":"authentication failure"}
```

### 問題

[ステップ 1: 認証を設定する | REST API 開発者ガイド | Salesforce Developers](https://developer.salesforce.com/docs/atlas.ja-jp.api_rest.meta/api_rest/quickstart_oauth.htm)
上記ページにcurlコマンドで認証するサンプルがあったので、これを例に説明する。

```
curl https://MyDomainName.my.salesforce.com/services/oauth2/token \
-d 'grant_type=password' \
-d 'client_id=consumer-key' \
-d 'client_secret=consumer-secret' \
-d 'username=my-login@domain.com' \
-d 'password=my-password'
```

このコマンドを叩いた時に冒頭に書いたエラーが返ってくる場合がある。
（ちなみに、レスポンスのステータスコードは「400 Bad Request」）

[OAuth 2.0 認証エラー](https://help.salesforce.com/s/articleView?id=sf.remoteaccess_oauth_flow_errors.htm&type=5)
上記ページにエラーの原因がいくつか挙げられているが、単に「認証エラー（authentication failure）」で理由が明確でない。少なくとも「無効なユーザ」や「IP 制限または無効なログイン時間帯」ではないのか？となると、あと考えられるのはパスワードが間違っているくらいか？と考えてしまいがちである。

### 調査

しかし、Salesforceにログイン（この時点でパスワードは間違ってなかったことが確定）し、設定 > ID > ログイン履歴 を確認すると、「失敗：APIセキュリティトークンが必要です」というログが残っていた。

この場合curlコマンドでログインできなかった原因は、「コマンドを叩いたPCのIPが信頼済みIPアドレス（設定 > セキュリティ > ネットワークアクセス で確認可能）でなかったから」となる。

### 対応

仮にセキュリティートークンが"12345"だった場合、`-d 'password=my-password'`ではなく`-d 'password=my-password12345'`としてリクエストする。

公式ドキュメントによる解説は以下の通り。
[特別なシナリオの OAuth 2.0 ユーザ名パスワードフロー](https://help.salesforce.com/s/articleView?id=sf.remoteaccess_oauth_username_password_flow.htm&type=5)
> セキュリティトークンは、信頼されないネットワークから Salesforce にログインするためにパスワードの末尾に追加する必要のある鍵で、自動生成されます。認証要求を渡すときに、パスワードとトークンを連結します。

まあ、これも「パスワードが間違っていた」と言えなくもないのか...
セキュリティ的な都合上、あまり明確な理由を返せないからこのような表現になっているのかもしれません。

以上
mnbcard - マイナンバーカード PYTHON Lib

## 概要

マイナンバーカードのPython用ツール・ライブラリーです。


## できること

- 券面確認 AP・券面入力補助 AP の読み取り
  - 4 属性の取得（名前、住所、生年月日、性別）
  - 個人番号の取得
- 公的個人認証の各種証明書の読み取り
  - 認証用証明書の取得
  - 認証用証明書 CA の取得
  - 認証用証明書の取得
  - 署名用証明書 CA の取得
- 公的個人認証の署名
  - 認証用秘密鍵による署名
  - 署名用秘密鍵による署名

## ソースコード
https://github.com/lanesky/mnbcard

## 使用例

```python
#! /usr/bin/env python3

import logging
import sys
sys.path.append('./../mnbcard')

from reader import get_reader, connect_card
from api import *
from helper import *

# ログレベルを設定する
root = logging.getLogger()
root.setLevel(logging.DEBUG)

# ログをコンソールに出力
handler = logging.StreamHandler(sys.stdout)
handler.setLevel(logging.INFO)
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
handler.setFormatter(formatter)
root.addHandler(handler)

# カードリーダー取得
reader = get_reader()
# カードに接続する
connection = connect_card(reader)

# 署名PIN入力（署名秘密鍵による署名をする場合は必要）
sig_pin = input("Please input the signature PIN: ")
# 券面補助PIN入力（券面情報読み取り場合は必要）
profile_pin = input("Please input the profile PIN: ")
# 認証PIN入力（認証秘密鍵による署名をする場合は必要）
auth_pin = input("Please input the authentication PIN: ")

# カードインスタンス作成
card = Card(connection)

# 認証用証明書取得
save_to_file(filename ="Auth_Cert.der", data = card.get_cert_for_auth())
# 認証用証明書CA取得
save_to_file(filename ="ca.der", data = card.get_ca_for_auth())
# 署名用証明書取得(署名PIN必要)
save_to_file(filename ="SigCert.der", data = card.get_cert_for_sign( sig_pin))
# 署名用証明書CA取得(署名PIN必要)
save_to_file(filename ="Sign_CA.der", data = card.get_ca_for_sign( sig_pin))

# 個人番号取得(券面補助PIN必要)
print(card.get_my_number(profile_pin))
# 基本４情報取得(券面補助PIN必要)
for iter in card.get_basic_info( profile_pin):
    print(iter)

# 署名秘密鍵によるファイル署名(署名PIN必要)
save_to_file(filename ="testfile.file.sig", data = card.sign_file_with_sign_key(sig_pin, "testfile.txt") )
# 認証秘密鍵によるファイル署名(認証PIN必要)
save_to_file(filename ="testfile.auth.sig", data = card.sign_file_with_auth_key(auth_pin, "testfile.txt"))
```

## 参考
- [規約：密着型ICカードの実装規約](https://www.nmda.or.jp/nmda/ic-card/iso10536/sec4.html)
- [記事：マイナンバーカードとAPDUで通信して署名データ作成](https://tex2e.github.io/blog/protocol/jpki-mynumbercard-with-apdu)
- [WIKI: Smart card application protocol data unit](https://en.wikipedia.org/wiki/Smart_card_application_protocol_data_unit)
- [記事：マイナンバーカードでSSHする](https://www.osstech.co.jp/~hamano/posts/jpki-ssh/)
- [記事：マイナンバーカード検証#2 - 利用者証明用電子証明書](https://qiita.com/gebo/items/fa35c1f725f4c443f3f3)
- [Git: LL-Smartcard](https://github.com/mit-ll/LL-Smartcard)
- [記事：APDUコマンドの返り値をメッセージで表示する](https://tex2e.github.io/blog/protocol/apdu-return-status-msg)
【競プロ】だれでもかんたん座標圧縮

## はじめに
みなさん座標圧縮（略して座圧）という言葉はご存じですか、私はつい最近知りました。というのも以下の操作に「座標圧縮」という立派な名前がついていると知らなかったんですよね。
例えば下のような配列Aがあったとき
```python
A = [4, 90, 25, 30, 30, 8, 90, 90]
```
これを座標圧縮するというのは配列の各数字が何番目に大きいかを1から[^1]順にナンバリングしていくという操作です。つまり配列Aに座標圧縮を施すと
```python
A_zaatsu = [1, 5, 3, 4, 4, 2, 5, 5]
```
となります。ただし配列`A`のなかで同じ数字は`A_zaastu`の中でも同じ数字が割り当てられることに注意してください。今回はこの座標圧縮という処理を簡単に書けるようになろうというのが本題です。
## いざ本題
もう最初に答えを書いちゃいます。座標圧縮はこう書けば簡単です。
```python
A = [4, 90, 25, 30, 30, 8, 90, 90]
S = sorted(list(set(A)))
ranking = {x:i+1 for i,x in enumerate(S)}
A_zaatsu = []
for a in A:
  A_zaatsu.append(ranking[a])
print(A_zaatsu)  ## [1, 5, 3, 4, 4, 2, 5, 5]
```

はい、いかがでしょう。何をしているかを説明します。
このコードで肝となるのは「**`A`の各要素が小さいほうから何番目なのかを知りたい！**」ということです。今回のコードではそれが`ranking`にあたります。`A`の各要素`a`に対して`ranking[a]`は`a`が配列`A`の中で小さいほうから何番目かを表しています。
その`ranking`をつくるにあたって`S`という、`A`から重複を取り除いて昇順ソートした配列を用意しています。
ここまでの説明を踏まえてもう一度コードを見てみましょう。
```python
A = [4, 90, 25, 30, 30, 8, 90, 90]
S = sorted(list(set(A))) ## [4, 8, 25, 30, 90]
ranking = {x:i+1 for i,x in enumerate(S)} ## {4: 1, 8: 2, 25: 3, 30: 4, 90: 5}
A_zaatsu = []
for a in A:
  A_zaatsu.append(ranking[a])
print(A_zaatsu)  ## [1, 5, 3, 4, 4, 2, 5, 5]
```

「**`A`の各要素が小さいほうから何番目なのかを知りたい！**」という気持ちになれば自然に理解できると思います。最後まで読んでいただきありがとうございました。
## おまけ
座標圧縮の手法がつかえる問題を貼っておきます。
[C - 座圧](https://atcoder.jp/contests/abc036/tasks/abc036)
[C - Reorder Cards](https://atcoder.jp/contests/abc213/tasks/abc213_c)
[^1]:もちろん1からじゃなくてもいいです。そのあたりは問題に合わせて適宜変更してください。
【C++】基礎を学ぶ④～変数の宣言と値の代入、変数の型～

# 変数の宣言

変数の宣言は、「変数の型」と「変数名」を書きます

```cpp
int value;
```

# 値の代入

宣言した変数に値を代入する方法です
```cpp
value = 10;
```

# 変数の初期化

変数の宣言と値の初期化を同時に行います

```cpp
int value = 10;
```
## プログラム
```cpp
#include <iostream>

using namespace std;

int main(){
  int value1;
  value1 = 10;
  cout << value1 << endl;

  int value2 = 20;
  cout << value2 << endl;
  return 0;
}
```
```
10
20
```


# 変数の型について

変数の「型」とは、変数の「種類・データの大きさ」を表す
「データ型」とも呼ばれる

### `int`型の場合
種類は「整数」
データの大きさは「4バイト（最大値は2147483647、最小値は-2147483648）」

## よく使う型

|        | 大きさ   | 種類 | 
| ------ | -------- | ---- | 
| char   | １バイト | 文字 | 
| int    | ４バイト | 整数 | 
| double | ８バイト | 小数 | 

# 型変換（キャスト）について
型変換とは、データ型を変数の宣言時と別の型にすることです
変数の前に変換先の型を`()`で囲って書く

### `double`から`int`に変換する場合
```cpp
#include <iostream>

using namespace std;

int main(){
  double value = 1.5;
  cout << value << endl;
  cout << (int)value << endl;
  return 0;
}
```
```
1.5
1
```
# 次の記事
[【C++】基礎を学ぶ⑤～複合代入演算子、インクリメント～](https://qiita.com/rapirapi/items/4b1bb48a5f324e5cc064)
cscの作法 その234

# 概要
cscの作法、調べてみた。
msbuildやってみた。

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/4e32e43e-7a55-e46c-dfae-f5cbce446e66.png)


# コンパイル手順

```
>set PATH=C:\Windows\Microsoft.NET\Framework\v4.0.30319;%PATH%

>msbuild

```

# サンプルコード

MainWindow.xaml

```
<Window x:Class="MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
	Title="test" Height="350" Width="525">
	<Grid>
		<TextBlock Text="Hello, World!" FontSize="48" HorizontalAlignment="Center" VerticalAlignment="Center" />
	</Grid>
</Window>



```
App.xaml

```
<Application x:Class="App" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
	StartupUri="MainWindow.xaml">
</Application>

```
app.csproj

```




<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
	<PropertyGroup>
		<AssemblyName>app</AssemblyName>
		<Platform>AnyCPU</Platform>
		<OutputType>WinExe</OutputType>
		<OutputPath>.</OutputPath>
		<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
	</PropertyGroup>
	<ItemGroup>
		<ApplicationDefinition Include="App.xaml">
			<Generator>MSBuild:Compile</Generator>
			<SubType>Designer</SubType>
		</ApplicationDefinition>
		<Page Include="MainWindow.xaml">
			<Generator>MSBuild:Compile</Generator>
			<SubType>Designer</SubType>
		</Page>
		<Reference Include="PresentationCore" />
		<Reference Include="PresentationFramework" />
		<Reference Include="WindowsBase" />
		<Reference Include="System" />
		<Reference Include="System.Xaml">
			<RequiredTargetFramework>4.0</RequiredTargetFramework>
		</Reference>
	</ItemGroup>
	<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

```

以上。
laravel Featureテストコードで自らにリクエストを送信する方法

# 概要

- laravelのテストコードにてリクエストを送る方法をまとめる。

# 方法

1. `vendor/laravel/framework/src/Illuminate/Foundation/Testing/TestCase.php`を継承しているFeatureのテストコードを用意する。（`$php artisan make:test テストクラス名`でテストクラスを生成すれば良い。）
1. Featureテストのテスト関数内に下記のように記載することでGETのリクエストを送信する事ができる。レスポンスが返される。

    ```php
    $response = $this->get($url, $requestBody, $header);
    ```
1. `$url`にはルーティングで定義しているパス部分（ドメイン以外）を格納して渡す。例えば`http://localhost/index`のエンドポイントにGETのリクエストを送りたい場合、`$url = '/index';`とする。`$url`は必須で渡す必要がある。
1. `$requestBody`にはその名の通りリクエストボディーを配列で定義・格納して渡す。`$requestBody`の受け渡しは任意である。
1. `$header`にはその名の通りヘッダー情報を定義して渡す。`$header`の受け渡しは任意である。
1. その他のHTTPメソッドに対応するリクエストを送信する関数をまとめる。

    | HTTPメソッド | 関数 |
    | --- | --- |
    | GET | `$this->get($url, $requestBody, $header);` |
    | POST | `$this->post($url, $requestBody, $header);` |
    | PUT | `$this->put($url, $requestBody, $header);` |
    | PATCH | `$this->patch($url, $requestBody, $header);` |
    | DELETE | `$this->delete($url, $requestBody, $header);` |

1. 上記の関数は`vendor/laravel/framework/src/Illuminate/Foundation/Testing/Concerns/MakesHttpRequests.php`にて定義されている。
1. MakesHttpRequestsクラスは`vendor/laravel/framework/src/Illuminate/Foundation/Testing/TestCase.php`のTestCaseクラスでuseされ、このTestCaseクラスを継承して`アプリ名ディレクトリ/tests/TestCase.php`のTestCaseクラスが定義され、このTestCaseクラスを継承してFeatureテストのクラスが定義されているため今回の関数を使用する事ができる。
1. リクエストを送る関数を見ているとgetJson()などの関数が存在する。こちらはちょっと処理を追ったらリクエストを投げる時パラメーターを配列のまま渡すのではなくJSONに一回変換してから「raw body data」としてエンドポイントに渡しているようだ。laravelのドキュメントにも記載があった。
    - [https://readouble.com/laravel/8.x/ja/http-tests.html#testing-json-apis](https://readouble.com/laravel/8.x/ja/http-tests.html#testing-json-apis)
Yarnのインストール方法(Mac)

## はじめに

`yarn` コマンドを実行したら、以下のエラーが発生しました。

```shell-session
$ yarn
bash: yarn: command not found
```

## 環境

- OS：macOS Monterey 12.4
- Node.js：v16.15.1

## 原因

Yarnはサードパーティ製のCLIツールであり、Node.jsにはプリインストールされていないためです。

## 解決策

npmでインストールすればOKです。

```shell-session
$ npm install yarn --location=global

added 1 package, and audited 2 packages in 377ms

found 0 vulnerabilities

$ yarn --version
1.22.4
```

私はNode.jsをnodebrewで管理しているので、yarnをグローバルインストールしました。
これでプロジェクト配下のみでなく、Node.jsの同じ環境を使うときには常にパスが通ります。

## おわりに

`yarn` コマンドが使えるようになりました。
これでnpmでなくYarnを使ったNode.jsのプロジェクトの開発ができます :relaxed: 

## 参考リンク

- https://twitter.com/the_uhooi/status/1545579709458956294
どんな変数名が良いか

# 変数の統一
| 記述方式 | 例 | 
|:-----------|:------------|
| キャメル記法 | totalPrice  |
| スネーク記法 | total_price |
| パスカル記法 | TotalPrice  |

:::note warn
趣味の範囲では、どの記述方式を選んでもよいが、統一しないと分かりづらい。
スネーク記法を用いて、定数はTOTAL_PRICEといった大文字にする方式を採用しようと思う
※職場での納品物は各現場のコーディング規約に従いましょう。
:::
C#基礎まとめ①

# 経緯
次案件がC#(Blazor)になりましたので、勉強がてら記事としてまとめていこうと思います。

## 参考資料
Udemy「一週間で身につくC#言語 / 亀田 健司」
https://www.udemy.com/course/c-nmavhi/

## 基本動作環境
・OS：Windows10
・IDE: Visual Studio 2017
（上記参考資料のUdemyコースのものに合わせた形になります)

## 基本コマンド
・標準出力(コンソール出力)
~~~標準出力(コンソール出力))
Console.Write("Hello World.");　　　　//改行なし
Console.WriteLine("Hello World.");　　　//改行あり
~~~

・コメント
~~~
/* */ ブロックコメント
// 行コメント
~~~

## 確認方法
以下より
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/434961/f5cdb0c6-5d56-68f7-d2f0-c1e07edae189.png)

## まとめ
・名前空間(namespace)：プログラムを分類する「入れ物」の名前を決める
~~~
namespace Sample101
~~~

・usingステートメント：利用する名前を指定
~~~
using System;
~~~

・クラス名：プログラムのまとまった処理の単位
~~~
class (クラス名)
~~~

・エントリーポイント：C#は原則的にこの中の処理が実行される
~~~
static void Main(string[] args){}
~~~
pybind11で作成したPythonモジュールのインポートでDLL load failed while imorting...と表示された時の対処方法

# はじめに
少し前にPythonを3.7から3.8に変更しました。環境依存かもしれませんが、[mingw64](https://www.mingw-w64.org/)と[pybind11](https://github.com/pybind/pybind11)で作成したPythonモジュールをインポートしようすると、"DLL load failed while importing ..."となり、インポートができなくなりました。[githubのissues](https://github.com/pybind/pybind11/issues/2010)に対処方法が書かれていたので、そのメモです。

# 環境
- Windows 10 home
- Python(3.8.10)
- pybind11(2.4)
- mingw64(gcc6.3)

# うまくいかない状況
うまくいかない状況を記載しておきます。
以下のサンプルコードをmingw64とpybind11でythonモジュールを作成しました。インポートしようとするとDLL load failed...とでて、モジュールのインポートができませんでした。
```C++
#include <pybind11/pybind11.h>
int add(int i, int j){
	return i+j;
}

PYBIND11_MODULE(example, m){
	m.doc() = "pybind11 example plugin";
	m.def("add", &add, "A function that adds two numbers");
}

```
 
pybind11を置いているincludeパス、Pythonのincludeパス・libsパスを指定して、コンパイルします。

```powershell
g++ -shared -std=c++14 example.cpp -o example.pyd -I"D:\include" -I"C:\Users\username\AppData\Local\Programs\Python\Python38\include" -L"C:\Users\username\AppData\Local\Programs\Python\Python38\libs" -lpython38
```

作成モジュールのインポートするとエラーが出力されます。
```Python
import example
```
エラー出力
![fail.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/585573/1f798967-c50c-6d45-2363-d049b7c094e6.png)

# 対処方法
[githubのissues](https://github.com/pybind/pybind11/issues/2010)によるとmingw64\binのパスがうまく読めていないようです。`os.add_dll_directory`を使ってmingw64\binを指定します。
```Python
import os
os.add_dll_directory("C:\\mingw64\\bin")# MinGWをフォルダのbinを指定
import example
example.add(10,8)
```
結果
![succeed.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/585573/8614a841-e7ec-ec31-1f23-217ff288065c.png)

# 参考
 - https://github.com/pybind/pybind11/issues/2010
【Python】辞書から部分辞書の作製

## やりたいこと
ある辞書から、キー指定で一部の要素を抽出した辞書を作成したい。

具体的にはdic_motoからlist_keyを使ってdic_kekkaを作成する。

```python
dic_moto = {'A':1, 'B':2, 'C':3}
list_key = ['A', 'B']
dic_kekka =  {'A':1, 'B':2}
```

## 方法
```python
dic_moto  = {'A':1, 'B':2, 'C':3}
list_key  = ['A', 'B']
dic_kekka = {key:value for key, value in dic.items() if key in list_key}
```


## おわりに

ググっても見つからなかったので、メモ代わりに。

辞書内包表記ができることを初めて知った。

他に良い方法があれば是非教えてください。
[Laravel]クエリビルダからget()したのにプロパティが取得できない

# はじめに

Laravel学びたてはDBデータを扱う際はCollectionメソッドが非常に充実していることから

```php
$users = User::all(); // 一旦Collectionで取得

$hoge = $users->map(function () {
  // 何かしらの処理
});
```

みたいに一旦Collection取得→何かしら処理する、という無駄なDB取得クエリを書いてよく注意されていました。。。

そこでLaravelはSQLのSELECT句以外にもEXISITS句やCOUNT句などが使えるクエリビルダという機能がありますが、このクエリビルダ使う際に個人的に直感とは違った挙動を最近見つけたのでメモ。

# 具体的な挙動

## よくあるクエリビルダの使用例

クエリビルダはクエリを発行するベースみたいなものなので例えば、

以下の様に`$usersBuilder`というクエリビルダを作成し、`count()`で対象レコード有無をチェックしてから`get(['id', 'name'])`でid, nameを持つUserモデルが集まったCollctionを取得

なんてことは結構あると思います。

```php
public function index()
{
    $ids = [1, 2, 3, 4, 5, 6, 7, 8];
    $usersBuilder = User::whereIn('id', $ids);
    if ($usersBuilder->count() !== 0) {
				$users = $usersBuilder->get(['id', 'name']);
    }

    return view('users.index', compact(['users']));
}
```

※あくまで例なのでわざわざCOUNT句のクエリ発行しなくてよくない？というお声は一旦無しでお願いします。。。

## 実際に直面した挙動

今回、※のところで追加機能の実装をします。

今回の機能追加するにあたって、既存の`$usersBuilder->get(['name'])`で取得しているnameだけでは機能が足りないため、いっそこと`$usersBuilder->get();`をしています。

```php
$ids = [1, 2, 3, 4, 5, 6, 7, 8];
$usersBuilder = User::whereIn('id', $ids);
if ($usersBuilder->count() !== 0) {
    // $usersBuilderがあるときの処理
		...
}

$userNames = $usersBuilder->get(['name'])->map(function($user){
    return $user->name;
});

// ※機能追加のため別でSelect分追加
$users = $usersBuilder->get();

return view('users.index', compact(['userName', 'users']));
```

ここの`$users`で取得できる想定は以下のイメージのCollectionでした。

※実際のCollectionの形と違うかもですがイメージですのでご了承ください

```php
$usersBuilder->get()
>>> \Illuminate\Database\Eloquent\Collection {
	items: array(5) {
        App/Models/User: {
			...
			attributes (4) {
				id: 1,
				name: hoge,
				email: hoge@test,
				password: ytmsi#ei2@
			}
        }
    }
}
```

ただ実際はこうでした

```php
$usersBuilder->get()
>>> \Illuminate\Database\Eloquent\Collection {
	items: array(5) {
        App/Models/User: {
			...
			attributes (1) {
				name: hoge,
			}
        }
    }
}
```

nameしかattribute(プロパティ)に入っていない…

## 原因

どうも`$usersBuilder->get();`の前に実行している`$usersBuilder->get(['name'])`によって取得できるプロパティが制限されてしまっているらしい。

## 対策

じゃあもういっその事、最初から`get()`してしまえということでこうしました

```php
$ids = [1, 2, 3, 4, 5, 6, 7, 8];
$usersBuilder = User::whereIn('id', $ids);
if ($usersBuilder->count() !== 0) {
    // $usersBuilderがあるときの処理
		...
}

// 追加：先にuserのプロパティ全て取得してくる
$users = get();
$userNames = $users->map(function($user){
    return $user->name;
});

// $usersをbladeに渡す
return view('users.index', compact(['userName', 'users']));
```

まあ最初からそうしろよ、というお声も届きそうですが、そういう挙動もあるんだということが知れてよかったということで。。。笑

# おわりに

当初の自分の書き方では`get()`を2回実行しているのでSELECTクエリが2回発行しているので無駄ですよね。

なのでLaravelも`get()`が１つのクエリビルダから2回以上実行されることなんてあまり想定していないのかもしれない、とも思いました。

Laravelとしては
> 「え、１つのクエリビルダから2回もSELECT句実行するの？いいけど想定通り取得できないよ？挙動は保証しないよ？」

みたいな挙動でしょうか。

なので、`get(['name'])`のようにカラムを指定してDBからのデータ取得量を制限できるのはいいかもしれないですが、今回の様に今後の機能追加時に結局「`get()`でいいじゃん」ってことになることは多いかもですね。

個人的には後々の修正は簡単なので、最初は`get(['name'])`などで取得カラム制限、必要に応じて`get()`に切り替えるという形でいいのかなと思います。

最後までお読みいただきありがとうございました。
【#23 エンジニア転職学習】DB入門　アーキテクチャ

# はじめに
富山県に住んでいるChikaといいます。
毎日投稿を目標に、バックエンドエンジニア転職に向けた学習内容をアウトプットします。

DBの入門をざっくり学習していきます。
昨晩投稿できなかったので本日は2回投稿します。

バックエンドエンジニアになるまでの学習内容は以前投稿した以下の記事を基にしています。


https://qiita.com/Chika110/items/ef54dddd565a0193ef44

# 本日の学習内容
本日の学習内容は、アーキテクチャ概要とDBMSを構築する上で考えることを学習しました。

* **アーキテクチャ概要　←Topics!!**
* MySQL環境構築（途中）

# アーキテクチャ概要
学習している教材では「**アーキテクチャ＝システムを作り上げるためのハードウェア・ミドルウェア等の組み合わせ**」という意味で使われていました。
システムを作る際は「目的」や「使用方法」はもちろん、**可用性を限りなく上げる**ようなアーキテクチャにすることが重要だそう。

現代主流のWeb3層構成（Webサーバ、アプリケーション、データベース層の3つのレイヤ）において、データベースだけデータを長期間保存する媒体を必要とする点で他2サーバ層と違います。
そのため冗長化を難しくしているとのことです。（現在の主流は変わっているかもしれませんが）

以上を踏まえた上でDBのアーキテクチャパターンは大きく5パターンになるようです。
* クラスタリング
    * **シェアードナッシング -①**
    * シェアードディスク
        * **Active-Active -②**
        * **Active-Hot-Standby -③**
        * **Active-Cold-Standby -④**
* **レプリケーション -⑤**


使用している教材はこちら↓


https://www.amazon.co.jp/%E3%81%8A%E3%81%86%E3%81%A1%E3%81%A7%E5%AD%A6%E3%81%B9%E3%82%8B%E3%83%87%E3%83%BC%E3%82%BF%E3%83%99%E3%83%BC%E3%82%B9%E3%81%AE%E3%81%8D%E3%81%BB%E3%82%93-%E3%83%9F%E3%83%83%E3%82%AF-ebook/dp/B00TTRZFDC/ref=tmm_kin_swatch_0?_encoding=UTF8&qid=1657112653&sr=8-1


# おわりに
最後までお読みいただきありがとうございました。
アドバイス・応援コメント等いただけますと幸いです。
`npm install` でエラー｜Ubuntu on WSL1, in Another Drive (/mnt/g)

# `npm install` でエラー
## System
- Ubuntu 20.04.4 LTS
- WSL 1
- nvm　0.35.2
- nodejs v16.16.0
    - `which node`の結果は `~/.nvm/versions/node/v16.16.0/bin/node`
- npm  8.13.2
    - `which npm` の結果は `~/.nvm/versions/node/v16.16.0/bin/npm`

## Issue
### Run Out of Home Directory
`/mnt/g/<subdirectories>`下にgitでnodejsプロジェクトを持ってきて
```bash
cd /mnt/g/<subdirectories>/
git clone <project>
cd <project>
npm install
```

としたらめっちゃエラーが出てきた。
```output
npm ERR! code EPERM
npm ERR! syscall symlink
npm ERR! path ../prebuild-install/bin.js
npm ERR! dest /mnt/g/<subdirectories>/<project>/node_modules/.bin/prebuild-install
npm ERR! errno -1
npm ERR! Error: EPERM: operation not permitted, symlink '../prebuild-install/bin.js' -> '/mnt/g/<subdirectories>/<project>/node_modules/.bin/prebuild-install'
npm ERR!  [Error: EPERM: operation not permitted, symlink '../prebuild-install/bin.js' -> '/mnt/g/<subdirectories>/<project>/node_modules/.bin/prebuild-install'] {
...
```

### Ron in Home directory
以下は問題なく成功
```bash
cd ~
git clone <project>
cd <project>
npm install
```

## Solution
`--no-bin-links`をつけて再実行
```bash
npm install --no-bin-links
```
以下の議論的に `ln -s`をwindowsのsystemfileに張ろうとしてるのが悪いっぽい？

- https://github.com/microsoft/WSL/issues/3
- https://github.com/MicrosoftDocs/WSL/issues/26
- https://github.com/microsoft/WSL/issues/14

しかし、https://github.com/microsoft/WSL/issues/3#issuecomment-272824865
の曰く、`--no-bin-links`でよいとのことなので試したらうまくいった。
そのほかに微妙に違う問題でうまくいかない人がいるようで、その場合はいくつか別のオプションやら設定をして解決しなければならないようだった。




###
STM32G031と温度センサーS-8120Cで温度をシリアル出力(浮動小数点)



x PA2をGPIOにがわかる人むけ

目的
安価に温度を測る。

v = -8.2 * t + 1705

式の変形

t = (v - 1705.0) / -8.2;


![o_con569.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/ec3368d2-393f-dd17-aea2-dc06bd506137.jpeg)



![o_con568.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/4037e082-1b2a-e92d-97d5-99d95edbe7e7.jpeg)



```c++



//SER_S-8120C_float_031_1

#include <Arduino.h>

//初期化処理
void setup()
{

  delay(3000); //not delete

  //シリアルの初期化
  Serial.setTx(PA2_ALT1);
  Serial.setHalfDuplex();
  Serial.begin(9600);

} //setup

//メインループ
void loop()
{

  //センサーの値を読み込む
  analogReadResolution(12); // ADC 12bit mode
  int s = analogRead(A9);   // PB7  PIN1 031 センサーの読み取り値

  //センサーのADC値を電圧に変換
  float v = s * (3300.0 / 4096);

  //センサーの電圧を温度に変換
  // v = -8.2 * t + 1705  =>  t = (v - 1705.0) / -8.2;
  float t = (v - 1705.0) / -8.2;

  //温度の表示
  Serial.println(t);

  //1秒の待ち
  delay(1000);

} //loop



```

https://paiza.io/ja/projects/new?language=c


テストプログラム


```c++



//0.82で割る 0から400までは、正しい
#define DIV082(n) ((n*4996)>>12)

#include <stdio.h>
int main(void){
    
    int s;
    float v;
    float t;
    
    for(int ii=1000;ii<=4096;ii++){
        printf("[%d]= ",ii);
        
        s = ii;
        
        v = s * (3300.0 / 4096);
        
        printf("V[%f]= ",v);
        
        t = (v - 1705.0) / -8.2;
        
        printf("T[%f]= ", t );
        
        //printf("[%d]= ",DIV082(ii) );
        
        //printf("[%d]= ",(ii*4996) >>12 );

        
        printf("\r\n");
    }
    
}



```