OmniAICreator/Qiita-1.07M huggingface dataset:
Windows365とはどんなサービスか（初中級者むけ）

お世話になります。

Windows365が発表されましたので、これまで仮想デスクトップやVDIとは何か、あまり聞いたことのなかった方向けに簡単に説明させて頂きます。

概要図は以下となります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/790864/ed025014-80cb-708f-e516-c1580db3026a.png)

Azureデータセンター内に無数のWindows10/11のOSテンプレートが用意され、ユーザーがサブスクリプションを開始したら割り当てられます。

これまではリモートデスクトップというアプリを利用する必要がありましたが、HTML5に対応したブラウザであればクライアントレスで実行できるのが大きな改善点です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/790864/925f26f6-0698-af2a-1dde-f9722c3d6eec.png)


なお、リモートデスクトップWebクライアントという技術自体は3年ほど前からGAされていて、オンプレミスAD環境下では構築することができていました。
![image1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/790864/bbafd2f5-073b-7391-b2f0-87d802547ede.jpeg)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/790864/e50d9d65-be08-d27b-3479-40b05b8b2a96.png)
参考サイト
https://forest.watch.impress.co.jp/docs/news/1114252.html

こうした環境をゼロから作るのは企業にとってかなりの知見と労力を必要しますが、今回、マイクロソフトが公式でMS365のサブスクリプションに組み込んだことで、仮想デスクトップの敷居が大幅に下げられることになります。

また、Azure Active Directory認証を必須とすることで、ユーザー企業はID管理をAADに一任することができるというメリットがあります。
![Office365-Manage00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/790864/b08bad88-97a5-a448-67d2-15803f5b5fa6.png)
参考サイト
https://itwork100.com/google-apps-office365/

それでは、Windows365のメリットを挙げていきます。

・端末を問わずいつでも職場のWindowsPCの操作に戻れる（iPhoneからでも）
・最短数十秒で、新規にPCが払いだせる（社員の入退社など）
・中古PCや、低スペックPCでも最新OSとしてよみがえらせられる


など、このあたりは仮想デスクトップの概念を理解されればすぐに想像がつくかと思います。
さらに企業のIT管理者向けのメリットとして、以下などが想定されます。


・AAD認証が必須のため、高度なセキュリティが担保される（二段階認証など）
・事前にテンプレートをカスタマイズし、アプリなどを組み込んでおける
・Azure上の仮想LANやファイアウォールなどと連携できる（Enterpriseプランのみ）

参考までに、以下のサイトにAzure Virtual Desktopとの比較がありました。
![AVD-vs.-Windows-1.2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/790864/b5a92b5e-f619-3034-3714-9f98baeb39dc.png)
https://translate.google.com/translate?sl=auto&tl=ja&u=https://getnerdio.com/academy-enterprise/microsoft-windows-365-vs-azure-virtual-desktop-avd-comparing-two-daas-products/

Windows365のデメリット

では、逆にデメリットを上げていきます。

・コストは高め
・GPU、3Dグラフィック機能が使えない
・安定したネットワーク回線が必須
・iOS、Androidからのユーザエクスペリエンスは過渡期
・プリンタやローカルデバイスの転送が完全ではない

これらを挙げると、まだまだ仮想デスクトップにおける使い勝手は、ローカルPCに及ばないことがわかります。
とくにブラウザやアプリでリッチコンテンツが増え、2D/3DアクセラレーションがPCの速度に及ぼす影響は増えてきていて、CPUだけでなくGPU速度が重要になっています。
また、ネットワークが途切れた時に何もできなくなるというのはリスクとしてあります。

以上ふまえると、簡単な事務作業やコールセンターでの入力、もしくはたまにExcelやPowerpointを使うだけ、といった特定用途での利用が最も適していると思われます。

（操作イメージ）
![Step-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/790864/d0351e42-6be6-8bff-be35-1259769ecebf.png)
![Step-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/790864/3a112cf3-8a4a-9320-f9d5-b8dcb7d35f05.png)
（動画）
https://www.youtube.com/watch?v=585HbRJ9YCc

また、ユーザー視点でのメリットとデメリットはそれぞれ存在しますが、IT管理者からするとほぼメリットのみということがいえると思います。

在宅ワークが増え、ユーザーPCの遠隔管理をどうするか、というのはIT管理者の苦労のひとつと思いますが、仮想PCにすることで物理的な制約にとらわれず一元管理ができます。
また、月額上限が決まっていて、MS365管理センターから気軽に導入できるのは中小企業にとって大きなメリットかと思います。
Linuxコマンドまとめ

Linuxコマンドを使えるよう奮闘中。

# vimの操作
- :set number 行数をだす
- コピー：yy 又は Y
- 貼り付け：p
- 削除：dd
※上記操作はinsertモードではないときに使える

# bash基本操作
- ctrl + a  行頭に移動
- ctrl + e  行末に移動
- ctrl + r  過去のコマンドの履歴を検索で見つけれる
- ctrl + k  カーソルより前の文字列を全て削除
- ctrl + u  カーソルより後の文字列を全て削除
- ctrl + l  コンソールクリア
- ctrl + y  貼り付け
 
# 実践編
- 

# grepコマンド
- grep '検索文字列' 対象ファイル
- -m 1　で１行に絞ることができる
- ^a 先頭がa
- a$ 最後がa
- ^[ab] 先頭がaかbを検索できる
- ^[a-d] 先頭がaからdのものを検索できる
- -n 行番号がつく
- -i 大文字と小文字の区別をつけない
 
# コマンド一覧
|コマンド 　　　　| 挙動 | 備考 |
|:-----------|:------------|:------------|
|  |  ||
| cp [オプション] コピー元 コピー先 | -nで存在するファイルの上書きをしない,-v実行内容確認 ||
| mv 変更前のファイル名 変更後のファイル名 | ファイル名変更 ||
| grep 検索正規表現 ファイル名 | 検索する ||
| touch <ファイル名> | 空ファイル作成 ||
| cat <ファイル名> | ファイルの中身を出力 |-nで行番号をつけれる|
|pwd|カレントディレクトリを表示||
|ls *.html|拡張子htmlだけを表示||
|ls -l|詳細情報まで表示、権限まで確認したいときはこれまでする||
|ls -a|隠しファイルまで表示||
|ls -F|ファイル種別まで表示||
|mkdir -p test/2019/08|深いディレクトリを作成する場合は-pが必要||
|rmdir|空のディレクトリを削除する、空でないとエラーが出る||
|less ファイル名|長いファイルの中身を見たいときに使う||
|touch|空のファイルを作成するときに使う||
|rm ファイル名|ファイル、ディレクトリを削除する、ゴミ箱にいかない|-rでディレクトリを削除できる|
|mv|ファイル名の変更、ファイルの移動||
|cp|ファイルのコピー|-rをつけるとディレクトリーのコピーができる|
|ln|リンクを張る|なんもつけないとハードリンクになる、-sはシンボリックリンク|
|find -name ファイル名|ファイルを検索する、ワイルドカード使えるがその時はファイル名をシングルクォーテーションで囲む||
|curl --request GET --url \|HTTPをコマンドで叩ける、API取得などで必要|\をつけると改行しながら実行できる|curl --request GET --url 'APIのURL'|
|curl --request POST --url \|コマンドでAPI上にデータを登録できる|[ここに割と詳しく書いてる](https://weblabo.oscasierra.net/curl-post/)|curl --request POST --url 'APIのURL' --header "Content-Type: application/json" -data '{"title":"e11","body":"b11"}'|
|更新はPUT|||
|削除はDELETE|||
||||
||||

# grepコマンド
- grep –i 検索正規表現 ファイル名 : 大文字と小文字を区別せず検索　grep –i a work/*
- grep –E 検索正規表現 ファイル名 : |のor演算子を使える　grep –E 'p|e' work/*
- grep -f 検索文字列リスト テキストファイル 

 - なぜLinuxを学ぶのか→サーバのOSが9割以上Linuxだから
 - カーネルはOSの中核となるもの
 - ディストリビューションはカーネルにソフトウェアをインストールしたもの
 - ターミナルは画面を担当するソフトウェア
 - シェルはコマンドを解釈するソフトウェア
 - シェルの種類は3種類あり、sh、bash、zsh
 - 設定ファイルもテキストファイルとなっている
 - バイナリファイルとは、画像ファイル、音声ファイル、実行ファイルなど

## ディレクトリのしくみについて
 - 「/」のことをルートディレクトリという
 - windowsはドライブごとにツリー構造になっているが、linuxはルートディレクトリのみの1つからツリー構造になる
 - /binはLinuxに最低限必要な実行コマンドが格納されている
 - /devはデバイスファイルが格納されている
 - /etcは設定ファイルが格納されている
 - /homeはユーザーごとに個人で利用する
 - /sbinは管理者ユーザー向けのコマンドが格納されている
 - /tmpは一時的なファイルの保存先
 - /usrは各アプリケーションと付随のファイルを格納されている
 - /varは変化するファイル、ログファイルなど
 - カレントディレクトリ「.」→自分がいるディレクトリ
 
## コマンドについて

 - --versionのように長いオプションはロングオプションと呼ばれている
 - --helpでコマンドのオプション一覧を見ることができる
 - manコマンドでマニュアルを見ることができる
 - man -k 調べたいものでマニュアルがでる
 - lessコマンド使い方
 - /文字列で検索可能、nで下の検索結果を確認、Nで上の検索結果を確認
 - qで終了する、bで上スクロール、スペースで下スクロール
 
## リンクについて
リンクを張るとはLinuxではファイルに別名をつけることができる
- ハードリンク
1つのファイルに複数の実体名をつけることができる、すべてのハードリンクを削除したときに消える
- シンボリックリンク
リンク先のパス名を記載しているだけ
iMacrosでのマクロ処理中にポップアップを表示させる方法

今回はFirefoxを使ったiMacrosでの処理中にポップアップを表示させる方法について解説します。

#前提条件
- Windows10を使用
- PCはDELLを使用
- Firefoxを使用（Google chromeでも可）

#料金
iMacrosでは有料版と無料版が存在しており出来ることの幅がそれぞれ異なりますが、今回のやり方は無料版の範囲で実施可能となっており、料金は一切かかりませんのでご安心下さい。

#事前準備
- Google chromeまたはFirefoxでiMacrosの拡張機能を追加して下さい。

#手順
１、PROMPTを入力し、ダブルクォーテーションの間に表示させたい文字列を入力する。

```
PROMPT "マクロが正常終了しました。"
```

２、マクロを実行し下記のようなポップアップが表示されたら成功。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1408197/54a9c595-5a25-614c-5125-c653b6b574f9.png)

#終わりに
今回はiMacrosを使ってマクロ処理中にポップアップを表示させる方法について解説しました。
今後またiMacrosで新たに得た知識を身に着けたら随時Qiitaに投稿したいと思います♪
英語学習する前に英語学習の科学について学びませんか？という提案

# エンジニアと英語
当たり前ですが、エンジニアと英語というのは切り離せません。
これについては今更僕が述べる必要も皆無だと考えます。
ただ、少しだけ触れておくと英語がわかりませんという状態ではクラス名、関数名、引数などの命名に際してCodicなどのツールを使用しなければ正しい名前付けができません。
面倒ですよね。
まだまだ理由は挙げられますがこれまでにしておきます。


## 英語学習
ですが、そもそも日本人にとって英語というのは習得が難しい言語です。
文法が全然違いますし、発音も違います。
なので学習にはそれなりの時間を投下しないといけません。

そこで最初に効率的な戦略を確立しようという話です。
大幅な時間節約になります。

## 第二言語習得とは
そこで登場するのが第二言語習得です。
初めて聞いた方も多いかと思われますが、ざっくりいうと他の言語を習得する時ってどの方法が良くてどの方法が悪いの？を研究する分野です（すごく適当に言ってます。本当はもっと意味が広いので興味ある方はWikipediaとか覗いてみてください）
色々本だったりPDFだったりが存在するので、興味ある方はググってみてください。
英語だと SLA もしくは second language acquisition です。


軽く紹介しておきます。

### 第二言語習得から学ぶ英語学習のコツ
・基礎文法は重要である。学習最初期に学習すべき（文法を学習させてからインプットさせたグループといきなりインプットさせたグループで英語の流暢さに差が出た。やっぱり文法を先にやるのが良い。）
・人によって良い文法学習が異なる（文法の分析が得意な人は文法を重視した勉強、暗記が得意な人は暗記重視。）
・Input more, output less（アウトプットは少し。少しが良い。無しは駄目。聞けるど話せない人になる。）
・初期に大量のインプットをする（ある程度リーディング、リスニングができるようになればとにかく英語に触れる。難しすぎるのは駄目）

### 追加で
単語学習
・分散学習（spaced repetition）が有効
・例文、使用例を一緒に覚える（英語では共起表現（どの単語と一緒に使用するか）が重要

word up がおすすめ。（上級者向け）

## 終わりに
英語学習で重要なのは、普段の情報源を英語にしても困らないところまで持っていくことだと思ってます。
そこまで行けばあとは情報源を英語にしていればあとは殆どのインプットを英語にすれば自動的に上手くなります。

あと、TOEICは入門・基礎にはとても良い試験だと思ってます。あくまで入門・基礎ですが。パート５を8～9割取れてリーディング400近くみたいな人は実践的な英語学習に移ったほうが良いのではと考えています


### おすすめ本

中・上級者向け
TOEIC600は無いとあまり得られる物はないかもしれません
ただ、僕的には英語学習本の中で最高の本です
生涯学習していこうと思っている人に対しては絶対に買えと鬼気迫る勢いで詰められるぐらいにはいい本です。
<a target="_blank" href="https://www.amazon.co.jp/gp/product/B08WC9CKQY/ref=as_li_tl?ie=UTF8&camp=247&creative=1211&creativeASIN=B08WC9CKQY&linkCode=as2&tag=youyoko0e-22&linkId=bd5e2498b9b2be66cbfc3243b8e52cb8">英語独習法 (岩波新書)</a>

文法学習のおすすめ
品詞分解的アプローチで文法の基礎をしっかりと身に着けるための本
ハードだけれどもこれをやった後で初めて英語をちゃんと理解できるようになりました
基礎力が無いと英単語から意味を予想するだけになってしまうので、基礎文法はちゃんとやっておくことをおすすめします
後の学習効率に大きな差が出ます
<a target="_blank" href="https://www.amazon.co.jp/gp/product/4327451371/ref=as_li_tl?ie=UTF8&camp=247&creative=1211&creativeASIN=4327451371&linkCode=as2&tag=youyoko0e-22&linkId=e15e23606b756b2709891a043edfc09d">基本からわかる英語リーディング教本</a>
位置検知 Bluetooth 

# 前提
https://jellyware.jp/kuragemd/bluejelly/ble_guide.html


# Bluetooth AoA,AoD
Bluetooth 5.1で発表された「方向検知機能」の技術
https://emb.macnica.co.jp/tech_blog/12824/

# Tof

# 参考
https://www.quuppa.com/tags-are-not-beacons/
instapyでハマった振り返り

instapyというOSSを用いてインスタの自動操作を行っていた。
2021年6月ぐらいからインスタのアップデートにより、OSSが動作しなくなっていた。
instapyはpipを用いてインストールを行っていた。
pipはPyPIからライブラリを探してインストールする

instapyのgithubのページを見ると、2021年6月のインスタのアップデートによるソースコードの修正が行われているように見える。
しかし、pipでインストールしたinstapyは動作しない。
PyPIのinstapyのページ https://pypi.org/project/instapy/  のreleaseを見ると2021年1月の更新が公開されていた。
そのため、githubの最新リリース、修正がPiPIに反映されていないということである。

このことから、最新のソースコードで動作を確認したい場合は、Hubサイト(docker hub, PiPI, apt など）ではなく、ソースコードを管理しているサイト（gerrit, github, gitlab など）からインストールを行う
node.jsでsqlite3を利用する


node.jsでsqlite3を利用する機会があったのでメモ。

## 前提

* 私の環境はMac（なので最初からsqlite3が入っている）sqlite3 --versionで確認可能。
* node.jsがインストールされている

## 準備

### 作業場所やファイルの生成

作業場所を作る。名前は何でも良い。ここではindex.jsに実装していく。

```bash
mkdir node-sqlite3-test
cd node-sqlite3-test
npm init -y
touch index.js
```

### sqlite3をnode.jsから制御するためのモジュールをインストール

sqlite3と同名なのでややこしいといえばややこしい。

```bash
npm install sqlite3
```

>これはsqlite3をインストールしてるのではなく、制御モジュールのインストール。

## 基本（だが、悪い例）

早速実装。

### 実装例

モジュール読み込んで、newして、db.run()でいろいろ実行するのが基本。

>ただ、感の良い人は気づくと思いますが、db.run()は非同期で実行されます。

```js:index.js
const sqlite3 = require("sqlite3");
const db = new sqlite3.Database("./test.db");

// db.run("drop table if exists members");
db.run("create table if not exists members(name,age)");
db.run("insert into members(name,age) values(?,?)", "hoge", 33);
db.run("insert into members(name,age) values(?,?)", "foo", 44);
db.each("select * from members", (err, row) => {
    console.log(`${row.name} ${row.age}`);
});

db.close();
```

### 実行例

とりあえず実行してみます。

```bash
node index.js
```

いちおう期待通りの動き。

```bash
hoge 33
foo 44
```

### 実行例2

次に、// db.run("drop table if exists members"); をコメントインして実行してみます。
するとエラーが発生します。

>エラーは下記と異なる場合もあり、かつ、実行のたびに違うエラー（あるいは正常終了）になることもあります。

```bash
[Error: SQLITE_ERROR: no such table: members
Emitted 'error' event on Statement instance at:
] {
  errno: 1,
  code: 'SQLITE_ERROR'
}
```

上記エラーは、insert時にmembersというテーブルが無いよ！というエラーです。
つまり、テーブルは生成される前にinsertが実行されているということです。

## 順番（同期的）に実行する

矛盾なく順番に実行するにはdb.serializa()で処理を囲ってやるようです。

### 実装１

下記の通り。

```js:index.js
const sqlite3 = require("sqlite3");
const db = new sqlite3.Database("./test.db");

db.serialize(() => {
    db.run("drop table if exists members");
    db.run("create table if not exists members(name,age)");
    db.run("insert into members(name,age) values(?,?)", "hoge", 33);
    db.run("insert into members(name,age) values(?,?)", "foo", 44);
    db.run("update members set age = ? where name = ?", 55, "foo");
    db.each("select * from members", (err, row) => {
        console.log(`${row.name} ${row.age}`);
    });
    db.all("select * from members", (err, rows) => {
        console.log(JSON.stringify(rows));
    });
    db.get("select count(*) from members", (err, count) => {
        console.log(count["count(*)"]);
    })
});

db.close();
```

>こっそりupdateや全レコード取得,count処理を加えてます。

### 実行

実行すると期待通りの結果が得られるようです。

```bash
node index.js

hoge 33
foo 55
```

### 実装２

下記のようにチェーンメソッド的に書くこともできる（省略）。

```js
db.run("create table if note exists members(name,age)",[],(err)=>{
	db.run("insert into members(name,age) values("hoge",11)");
});
```

### メモ

* db.parallelize()関数もあり、明示的に並行処理させることもできます。
* sqlite3自体を直接操作する方法は[こちら](https://qiita.com/zaburo/items/ad690284f7430bdf5f9e)をご覧ください
Lognan Nanoその２（gd32vでシリアル通信）

# Lognan Nano gd32v Framework
[「Longan NanoをPlatoform IOで完結」](https://qiita.com/infinite1oop/items/a1f104b2038e9c170878)（その１）では、「Arduino」Frameworkを使った。ここでは、同じPlatform IOを用いて、「gd32v」Frameworkを用いて、シリアル通信を行う。

## 環境
[「Longan NanoをPlatoform IOで完結」](https://qiita.com/infinite1oop/items/a1f104b2038e9c170878)同様、シリアル接続されたPCにLognan Nanoボードからの出力を実施。

### platformio.ini
```c++:platformio.ini
[env:sipeed-longan-nano-lite]
platform = gd32v
board = sipeed-longan-nano-lite
framework = gd32vf103-sdk
upload_protocol = dfu
```

frameworkが「gd32vf103-sdk」となっている。

### ソースコード（C++）
あえてC++を用いて、てこずった。（下記serial.cppの記載参照。）

#### serial.cpp
シリアル初期設定など。[こちら](https://www.dalewheat.com/tag/risc-v/)のソースコードをほぼそのまま利用。

```c++:serial.cpp
extern "C" {
#include "gd32vf103.h"
}

int _put_char(int c) {
    usart_data_transmit(USART0, (uint8_t) c);
    while(usart_flag_get(USART0, USART_FLAG_TBE) == RESET);
    return c;
}

// initialize USART0
void serial_init(void) {
    rcu_periph_clock_enable(RCU_GPIOA);
    rcu_periph_clock_enable(RCU_USART0);
    gpio_init(GPIOA, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_9);
    gpio_init(GPIOA, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_10);

    usart_deinit(USART0);
    usart_baudrate_set(USART0, 9600);
    usart_parity_config(USART0, USART_PM_NONE);
    usart_word_length_set(USART0, USART_WL_8BIT);
    usart_stop_bit_set(USART0, USART_STB_1BIT);
    usart_hardware_flow_rts_config(USART0, USART_RTS_DISABLE);
    usart_hardware_flow_cts_config(USART0, USART_CTS_DISABLE);
    usart_receive_config(USART0, USART_RECEIVE_ENABLE);
    usart_transmit_config(USART0, USART_TRANSMIT_ENABLE);
    usart_enable(USART0);
}
```

「extern "C"」により、Cライブラリを使えるようにしている。ただし、Framework「gd32v」のC++環境ではBuildエラーになる。調べたところ、[この記事](https://ioprog.com/2019/11/24/longan-nano-risc-v-and-platformio/)にあるように「gd32vf103.h」に手を加える必要がある。

```c:gd32vf103.h
// 追記部分のみ

#ifndef __cplusplus
typedef enum {FALSE = 0, TRUE = !FALSE} bool;
#endif
```

#### main.cpp
メイン部分。Delay（delay_1ms()）については、[こちら](https://github.com/sipeed/platform-gd32v/blob/master/examples/longan-nano-blink/src/systick.c)のソースコードをそのまま利用。

```c++:main.cpp
extern "C" {
#include "gd32vf103.h"
}

#include <stdio.h>
extern void serial_init();

void delay_1ms(uint32_t count)
{
    uint64_t start_mtime, delta_mtime;

    // Don't start measuruing until we see an mtime tick
    uint64_t tmp = get_timer_value();
    do {
    start_mtime = get_timer_value();
    } while (start_mtime == tmp);

    do {
    delta_mtime = get_timer_value() - start_mtime;
    } while(delta_mtime <(SystemCoreClock/4000.0 *count ));
}

main () {
    int i = 0;

    serial_init();

    while (1) {
        printf("N = %i\n", i);
        i++;
        delay_1ms(2000);
    }
}
```

２秒毎にPCに出力する。

プログラムを書き込むためのボードのDFUモードへの入り方や、Platform IOから書き込む方法についても、[「Longan NanoをPlatoform IOで完結」](https://qiita.com/infinite1oop/items/a1f104b2038e9c170878)参照。

#### 出力の様子

![スクリーンショット 2021-06-26 16.27.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/98caa46b-b0c6-25cc-7c6e-8cbe9a5a3ba7.png)

成功。
Before starting UiPath:変数ってなんだ

##皆もすなるQiitaといふものを、儂もしてみむとてするなり。

と言う訳で、こん＊＊は！はなっち！です。

★★★この記事はUiPathブログ発信チャレンジ2021サマー、7/17の記事です。★★★

今回は、ちょっとしたシリーズです。UiPathを使うに当たって、UiPathの機能ではなく、コンピュータ言語を使う上での基礎知識を展開していこうと思います。

#変数ってなんだ
プログラミングにおける変数とは、
"高水準言語のプログラムのソースコードにおいて、扱うデータを読み書きする記憶域 (storage) のことであり、固有の名前（識別子）によって識別される。変数を用いることで、データを一定期間記憶し必要なときに利用することができる。"
と説明されています。

https://ja.wikipedia.org/wiki/%E5%A4%89%E6%95%B0_(%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0)

読み書きする領域。料理を載せるお皿とか、お酒を注ぐお猪口みたいなものでしょう。

変数を詳しく知るには、変数の「宣言」と「代入」と「参照」を理解しなければなりません。

・プログラムの中でどのような名前の変数を用いるのかを「宣言」します。
    一般的には「宣言」と言わず、「定義」と言います。
    UiPathでは、変数タブから「定義」したり、アクティビティのパラメタ部分でctrl+kをする事で「定義」する事が出来ます。
・「定義」した変数に対して実際にデータを関連付けることを「代入」と言います。
    UiPathでは、「代入」アクティビティが主な代入方法ですが、各アクティビティの出力パラメタに設定する事も「代入」と言えます。
・その変数に代入したデータを利用することを、変数の参照と言います。
    UiPathでは、各アクティビティの入力パラメタに設定する事が「参照」と言えます。
    また、「代入」アクティビティの右辺に記述する事も「参照」と言えます。

#変数には

変数には、そこに代入する値に相対した「型」が存在します。
    数値                Int32,Int64,Double,Single…
    文字                Char
    文字列              String
    二値(True/False)    Boolean
    日付                DateTime
    データテーブル      DataTable
    配列                型指定[]
    辞書型              Dictionary(Of キーの型指定, 値の型指定)
    リスト型            List(Of 型指定)
    ｡｡｡
    それぞれに型を使用する際には、型に応じた「代入」をする必要がある場合があります。

##おわりに
いかがでした？

変数は、基本の「キ」ですので、しっかりイメージできるようにしておきましょう！

是非UiPathでのロボ開発の一助になればと思っています。

ありがとうございました！
【UiPath】謎のハッカー風操作をしてみる＃2（コマンド操作）

# はじめに

この投稿は、RPAツール「UiPath」での フロー実装例 の記事です。

UiPathのコミュニティ「UiPath Friends」が企画する「UiPathブログ発信チャレンジ2021サマー」の 17日目の投稿でもあります。

企画の内容は [**こちら**](https://note.com/shumpei_w/n/n651cbdbec4e8) 。カレンダーのURLは [**こちら**](http://u0u1.net/sUwZ) です。

https://twitter.com/ShumpeiWatanabe/status/1405168150736359427?s=20

# 謎のハッカー風操作

前回に引き続き、よく映画で見る「ハッカーがやってそうな操作」をUiPathでしてみます。

それっぽく見えれば良いので、操作に意味はありません。

シリーズになっています。前回までの投稿はこちら。

https://qiita.com/miya_gis/items/a304d6d4600d63e98314

操作のイメージは以下のような感じです。

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




# 謎のコマンド操作

ハッカーっぽいと言えば「コマンドラインでの操作」です。
画面に文字を素早く流して、なんだかわからないけどスゴそうに見せます。

今回は有名な「dir /s /p」コマンドで画面に文字を流します。

```
dir：指定のディレクトリでファイル名・フォルダ名を一覧表示
/s：配下のディレクトリも対象
/p：1画面毎に停止
```

ドット絵（LinuxディストーションロゴやYeoman generatorみたいなの）があると面白いので、最初にUiロボット君（Receiving Robot）のAAをbatで表示します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154139/f6b8a442-429f-b59d-3476-7669bb97df20.png)

こちらのサイトを参考に、画像から作成しました。（作成後に文字をすべて#に変換）

https://tool-taro.com/image_to_ascii/


最後にフォームで「AccessDenied」アラートを表示すれば完成です。

作成したフローはこちらです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154139/54ad7237-955d-7937-b534-f4eb4e23ee1a.png)

実際に動かすと、以下のようになります。

https://twitter.com/miya_gis/status/1409742741236371458?s=20

# おわりに

いかがでしたでしょうか？
あまり役に立ちそうにないですが、UiPathではこんな 遊び方／見せ方もできます。

この記事が参考（？）になったら、LGTM をお願いします。
最後までご覧いただき、ありがとうございました。
Vue.js v-modelで更新された配列を随時ソートする

## ちょっとハマったところ
watchで自分自身を変更すると無限ループにハマるので新旧データを数を見比べて値の増減があったときのみソートとする。

## コード

```javascript
new Vue({
  el: '.app',
  watch: {
    checkedPrefectures(oldVal, newVal) {
      // このIFがないと無限ループが発生する
      if (oldVal.length !== newVal.length) {
        this.checkedPrefectures.sort((a, b) => b.code - a.code)
      }
    }
  },
  data: {
    checkedPrefectures: [], // 選択済み都道府県
    prefectures: [
      { "code": 1, "name": "北海道"},
      { "code": 2, "name": "青森県"},
      { "code": 3, "name": "岩手県"},
      // ...etc
    ]
  }
});
```

## 選択された都道府県をID降順で並び替えて表示するサンプル

<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="MWmmvWN" data-user="micro_jp_" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/micro_jp_/pen/MWmmvWN">
  </a> by MA (<a href="https://codepen.io/micro_jp_">@micro_jp_</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>
mbed TLSでHKDFを利用する

# 記事の概要
mbet TLSを用いてHKDFを利用します。

サンプルプログラムは以下に置いてあります。
https://github.com/matsuikosuke/mbedTLSTest

# HKDFとは何か
HKDFは、入力鍵から別の鍵を生成します。

派生キーを生成するために使用されます。 最初のステップである「抽出」は、入力キーマテリアルを取得し、

入力鍵から固定長の疑似ランダムキー（PRK）を生成し、PRKから任意の長さの別の鍵を生成します。 

HKDFを作成する目的は、共有鍵を暗号化鍵に変換することです。

# サンプルコード

`mbedtls_hkdf`関数を使用してHKDFを作成します。
引数の意味は以下のリンク先を参照ください。
https://tls.mbed.org/api/hkdf_8h.html#add9dfaeb0544fe502c0240c9f90618ed

以下のテスト関数では、生成したHKDF`hkdf_okm`が期待値`expected_hkdf_okm`と一致することを確認しています。

```C
int mbed_hkdf_test(void)
{
    nrf_crypto_hmac_context_t   context;
    unsigned char hkdf_ikm_len_22[22]   = { 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b };
    unsigned char expected_hkdf_okm[42]   = { 0x8d, 0xa4, 0xe7, 0x75, 0xa5, 0x63, 0xc1, 0x8f, 0x71, 0x5f, 0x80, 0x2a, 0x06, 0x3c, 0x5a, 0x31, 0xb8, 0xa1, 0x1f, 0x5c, 0x5e, 0xe1, 0x87, 0x9e, 0xc3, 0x45, 0x4e, 0x5f, 0x3c, 0x73, 0x8d, 0x2d, 0x9d, 0x20, 0x13, 0x95, 0xfa, 0xa4, 0xb6, 0x1a, 0x96, 0xc8 };
    nrf_crypto_hmac_context_t   hkdf_context;

    uint32_t i;
    int ret;
    size_t   ikm_len = 22;//sizeof(hkdf_ikm_len_22);
    size_t   okm_len = sizeof(expected_hkdf_okm);
    size_t   expected_okm_len = okm_len;

    unsigned char hkdf_okm[42];
    memset(hkdf_okm,  0xFF, sizeof(hkdf_okm));

    ret = mbedtls_hkdf(
        mbedtls_md_info_from_type(MBEDTLS_MD_SHA256),
        NULL, //const unsigned char * 	salt
        0, //size_t 	salt_len
        &hkdf_ikm_len_22[0], //const unsigned char * 	ikm,
        22, //size_t 	ikm_len,
        NULL, //const unsigned char * 	info,
        0, //size_t 	info_len,
        &hkdf_okm[0], //unsigned char * 	okm,
        okm_len //size_t 	okm_len 
    );

    printf("hkdf_okm=");
     for (uint16_t i=0; i<okm_len; i++) {
         printf("%02lX, ", hkdf_okm[i]);
     }
     printf("\r\n");

    //Verification: are the computed hkdf and the expected hkdf equal?
    ret = memcmp(&hkdf_okm, &expected_hkdf_okm, okm_len);
    if( ret != 0 )
        printf("error\r\n");

    return ret;
}
```

# 参照
[mbed TLSでAES-GCMを利用する](https://qiita.com/Kosuke_Matsui/items/340c6b906fed2c6ea40b)
[mbed TLSでRSAを利用する「RSA-OAEPの暗号化と復号」](https://qiita.com/Kosuke_Matsui/items/4c64c993e5979a65620d)
[mbed TLSでRSAを利用する「RSAの公開鍵と秘密鍵の作成」](https://qiita.com/Kosuke_Matsui/items/786e88eace7646c8a7e6)
[mbed TLSおよびOberonでECDHを利用する](https://qiita.com/Kosuke_Matsui/items/4390f5e58339e95dcdae)
[mbed TLSでHKDFを利用する](https://qiita.com/Kosuke_Matsui/items/93f25f47a6171fe94d30)
[mbed TLSでJWTを利用する](https://qiita.com/Kosuke_Matsui/private/915e6607b2b81de7f55d)
10G NICでnfs rdmaを有効にする

Broadcomの10Gネットワークカード、NetXtreme-E　BCM57416を安価で2枚手に入れたので、NFS　over　RDMAを有効にしてみた。
まだ、10000base-T対応のスイッチングハブを個人で買うにはちょっと高いので、2つのNICをLANケーブルで直結して試した。

### RDMA
RDMAとは、Remote Direct Memory Accessの略で、『ローカルのコンピュータのメモリから、異なるリモートのコンピュータのメモリへデータのDMA転送を行うこと』。OSをすっ飛ばしてデータ転送を行える。元々は、Infiniband上で高速転送を行うために開発されたようだ。

![Traditional Data Path vs RDMA](https://core.vmware.com/sites/default/files/traditional-vs-rdma.png)

* 画像：[The Basics of Remote Direct Memory Access (RDMA) in vSphere](https://core.vmware.com/resource/basics-remote-direct-memory-access-rdma-vsphere)より

### NIC用driver

まずはネットワークカード自体のドライバだが、bnxt_enが該当する。Ubuntu 20.04だと、自動で認識してくれた。

```
[    1.527556] bnxt_en 0000:01:00.0 eth1: Broadcom BCM57416 NetXtreme-E 10GBase-T Ethernet found at mem e0510000, node addr 9c:dc:71:b6:b5:d0
[    1.528469] bnxt_en 0000:01:00.0: 63.008 Gb/s available PCIe bandwidth (8.0 GT/s PCIe x8 link)
[    1.554613] bnxt_en 0000:01:00.1 eth2: Broadcom BCM57416 NetXtreme-E 10GBase-T Ethernet found at mem e0500000, node addr 9c:dc:71:b6:b5:d8
[    1.555833] bnxt_en 0000:01:00.1: 63.008 Gb/s available PCIe bandwidth (8.0 GT/s PCIe x8 link)
```

### RoCE　driver

続いて、RoCE(RDMA over Converged Ethernet、ロッキーと発音するらしい）用のドライバ。bnxt_reが該当する。こちらは、自動では入らないので、手動で行う。

```
$ sudo modprobe bnxt_re
```

このように認識される。

```
[  412.826559] bnxt_re: Broadcom NetXtreme-C/E RoCE Driver
[  412.898572] infiniband bnxt_re0: Device registered successfully
[  412.934539] infiniband bnxt_re1: Device registered successfully
```

さらに、RPC/RDMA Transportモジュールを突っ込む。

```
$ sudo modprobe rpcrmda
```

こちらはこのように認識される。

```
[   17.281994] RPC: Registered rdma transport module.
[   17.281997] RPC: Registered rdma backchannel transport module.
```

これら2のドライバは、`/etc/modules` へ書いておけば、次回起動時に有効にしてくれる。

```
bnxt_re
rpcrdma
```

### nfs server

nfsサーバー側は、 ``/export`` を公開としておく。なお、セキュリティとかは考慮していない。

```
$ cat /etc/exports
/export	192.168.0.0/255.255.255.0(rw,async,fsid=0,no_subtree_check,no_root_squash,insecure)
```

ここで、NFSサーバーを(再）起動する。

```
$ sudo systemctl start nfs-server
```

そして、RDMA転送用のポート番号を設定。20049がデフォルトのポート番号らしい。

```
# echo rdma 20049 > /proc/fs/nfsd/portlist
# cat /proc/fs/nfsd/portlist
rdma 20049
rdma 20049
tcp 2049
tcp 2049
```

なお、この設定を行っても、netstatの結果には20049番ポートは出てこない。

ここまでが、サーバー側の設定。

### nfs client

NFSクライアント側は、以下のようにマウントする。

```
# mount -o rdma,port=20049 192.168.0.1:/ /srv
```

これで、ファイルをコピーしてみると、1.1GB/sくらい出た。

```
$ dd if=/srv/100G of=/dev/zero iflag=direct bs=32M
3200+1 レコード入力
3200+1 レコード出力
107374182500 bytes (107 GB, 100 GiB) copied, 95.0471 s, 1.1 GB/s
```

----
#### 参考
- [Broadcom® NetXreme-C および NetXtreme-E
ユーザー マニュアル](https://downloads.dell.com/manuals/all-products/esuprt_ser_stor_net/esuprt_pedge_srvr_ethnt_nic/broadcom-netxtreme-adapters_users-guide3_ja-jp.pdf)
- [GPUDirect SQL on NFS-over-RDMAを試す]
(https://kaigai.hatenablog.com/entry/2021/07/05/182217)
Kotlin Multiplatform Javascript版 Day1

# 概要
(自分メモ)
NodejsやBrowser向けのKotlin Multiplatformプロジェクトのテンプレを作成
Kotlin/jsやKotlin MPP でJavasctiptのモジュールを使用する際のメモ


# ソース
https://github.com/kyoya-p/samples/tree/51f9cc7d69292f4e9430d21590f635a9ed928518/2024/KMPs/js1

# 実行
```sh:nodejs
gradlew jsNodeRun
```
標準出力に`Hello World!`が表示される。

```sh:browser
gradlew jsBrowserRun
```
開いたBrowserのConsoleに`Hello World!`が出力されている。

# 関数をexportするnpmモジュールを取り込む
例: is-sortedモジュール
```js:JavaScriptモジュール側の定義スタイル
//...
module.exports = function checksort (array, comparator) {
//...
```

```build.gradle.kts
//..
kotlin {
    js {
        nodejs {}
        binaries.executable()
    }
    sourceSets {
        val jsMain by getting {
            dependencies {implementation(npm("is-sorted", "1.0.5"))}
        }
    }
}
```
```Main.kt
@JsModule("is-sorted")
@JsNonModule
external fun <T> sorted(a: Array<T>): Boolean

fun main() {
    println("Is sorted: ${sorted(arrayOf(1, 2, 3))}")
    println("Is sorted: ${sorted(arrayOf(1, 3, 2))}")
}
```

# 比較
サンプル: net-snmp for javascript

```javascript:Javascriptでの記述
import { Session } from "net-snmp"; 
```

```kotlin:Kotlin/js
@file:JsModule("net-snmp")
@file:JsNonModule  // CommonJS の場合
external fun Session():dynamic
```

# Javascriptでexportされたクラス
```javascript:Javascriptでの定義
var Session = function (target, authenticator, options) {/*..*/}
Session.create = function (target, community, options) {/* クラスメソッド */}
Session.prototype.getNext = function (oids, responseCb) {/* オブジェクトメソッド */}
exports.Session=Session;
```
```javascript:Javascriptでの使用
import { Session } from "net-snmp"; 
const session=Session.create("192.168.11.5","public")

```

```kotlin:Kotlin/jsでの外部型宣言
@file:JsModule("net-snmp") // import {...} from "net-snmp" の場合
@file:JsNonModule  // CommonJS Moduleの場合

external class Session {
    companion object {
        fun create(target: String, community: String, options: SessionOptions? = definedExternally): Session
    }
    fun getNext(oids:Array<String>,responseCb:(error:Error?, varbinds:Array<Varbind>)->Unit )
}
```
CH376SのパラレルIO

CH376SのパラレルIOでのアクセス方法は下記のように行います。

8Bitポートは2つあり、データとコマンドになります。

コマンドを書き込んでデータの読み書きをします。

```
	CMD	EQU	0FDH
	DATA	EQU	0FCH

WRITECMD:
	OUT	(CMD), A
	RET

WRITEDATA:
	OUT	(DATA), A
	RET

READDATA:
	IN	A, (DATA)
	RET

READCMD:
	IN	A, (CMD)
	RET
```

たとえばGET_IC_VER(01H)の場合、コマンド書き込むとデータポートでバージョンが読めます。

```
	GET_IC_VER	EQU	01H

	LD	A, GET_IC_VER
	CALL	WRITECMD
	CALL	READCMD
```

SET_USB_MODE(15H)の場合はデータポートにモードを書き込みます。

データーシートを見るとDISK_CONNECT(30H)以降はProduce
 interruptionとなっています。これらは割り込みで処理が終わった事が確認できます。

割り込みを使っていない場合は、コマンドポートを読むと割り込みの状態が7ビット目で確認できるので、これが0になって割り込みが上がった事を確認してRD_USB_DATA0(27H)でデータを読みます。

```
WAITINT:
	CALL	READCMD
	AND	A,80H
	JP	NZ, WAITINT
	RET
```

RD_USB_DATA0は最初バイトがデータ数を表しているので、その数だけ読みます。

RD_USB_DATA0でのデータ読み込みは1バイトでサイズが指定されるので、255が最大になります。

BYTE_READで255以上のデータを読み込む場合は最初にBYTE_READとRD_USB_DATA0で255バイト読み込み、次にBYTE_RD_GOとRD_USB_DATA0で次のデータを読み込みます。256のデータを読み込む場合は最初に255バイト読めて次に1バイトが読めます。

255バイト以下のリクエストでも、BYTE_RD_GOしないとおかしな動作になります。

"/"をFILE_OPENしてBYTE_READするとディレクトリのエントリーが読めます。"/"と"FILE.TXT"か"/FILE.TXT"をFILE_OPENしてBYTE_READするとファイルの中身が読めます。
"/"をFILE_OPENしてディレクトリの"DEMO"をFILE_OPENして"FOO.CMT"をFILE_OPENするとファイルの中身が読めます。この後FILE_CLOSEするとパスがすべて閉じるので、"/"を開くようにするのが良いかもしれません。
XCode　ショートカットキーまとめ

ビルド、実行関連
--
Cmd+R→実行
Cmd+B→ビルド
Cmd + Shift + K	クリーンビルド
Cmd + .	ストップ
Cmd + \	　ブレイクポイント設定するか解除
Cmd + Ctr + Y	ブレイクポイントで止まった処理を続ける

コード編集
--
Ctrl + I	インデント整理
Cmd + /	コメントアウト
Cmd + Click（※）	定義へ移動(ジャンプトゥデフィニション）
Cmd + Shift + J	表示しているファイルに移動
Opt + Click	Quick Help（リファレンス）
Cmd + Ctr + E	ファイル内変数のRename
Cmd + Ctr + ←	ジャンプ前のコードに戻る
Cmd + Ctr + →	進む（上記の逆）
Opt + ←	左の単語にカーソル移動
Opt + →	右の単語にカーソル移動
Cmd + [	インデントを下げる
Cmd + ]	インデントを上げる
Cmd + ←	カーソルを行頭へ移動
Cmd + →	カーソルを行末へ移動
Ctrl + D	右の1文字削除


検索・エリアの表示、非表示
----
Cmd + Shift + O	プロジェクト内検索
Cmd + F	ファイル内検索
Cmd + 0	ナビゲートエリア表示
Cmd + Opt + 0	ユーティリティーエリア表示
Cmd + Shift + y	デバッグエリア表示
Cmd + Opt + Ctr + Returnアシスタントエディタ表示/非表示

その他
---
Cmd＋０〜７→ナビゲータエリアのメニュー間移動

開発効率を上げていきたい。
High Velocity Salesライセンスがないと表示できないカスタムボタン

[まとめページに戻る](https://qiita.com/Keiji_otsubo/items/60afc2a8d211b6f7d89f)
[まとめA～M](https://qiita.com/Keiji_otsubo/items/f3ddedee6793bf1576f8)



High Velocity Salesは使ってないので、分からなかったですね。

[Sales cadence actions](https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000BqdQ8)

:::note
High Velocity Sales ユーザー ライセンスを持っていないため、ボタンが表示されませんでした。
:::
時間を溶かす素敵なサイトとすごい技術コレクション

https://qiita.com/official-events/be8c5ab5a9ddf90055cd

にあやかり、ちょっとした息抜きを。


## 時間を溶かす素敵なサイト

### 1. 顔画像生成技術
[8 Websites That You Should Definitely Check Out Once](https://theinsightfulcoder.com/8-websites-that-you-should-definitely-check-out-once) より、[Generative Adversarial Network](https://qiita.com/resnant/items/75543fb5047e90dd8202#generative-adversarial-network%E3%81%A3%E3%81%A6)
> Generative Adversarial Network（GAN）とは、DNNを用いた深層生成モデルの一つです。GANは生成モデルという名前の通り、新しいデータを生成することができる手法です。

で、このサイトでは人間の顔画像を見て、それがGANで生成されたものか、本物の顔かのクイズで遊ぶことができます。

https://www.whichfaceisreal.com/

https://labs.cybozu.co.jp/blog/akky/2019/02/this-person-does-not-exist-com/

https://thispersondoesnotexist.com/

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



以下もオマケ

https://ledge.ai/toyboyfan-disney/





### 2. 懐かしの色々のエミュレータ的な技術

https://www.atmarkit.co.jp/ait/articles/1603/04/news138.html

http://www.virtualdesktop.org/osonly/index.html

http://www.windows93.net/

![os.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93824/55692d0c-7b08-d20d-7fc3-1ae399e091d3.gif)

同記事で言及されている OS.js については以下に発見。

https://qiita.com/h-tko/items/fa6ec4a82fb7dfec30c8

https://www.os-js.org/

デモ: https://demo.os-js.org/
![osjs.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93824/1b29b734-f06b-0a8b-359d-0254ce303274.gif)



### 3. 地球の裏側へトンネルを掘るAR技術

Googleの数々の実験が公開されている https://experiments.withgoogle.com/ .

https://www.itmedia.co.jp/mobile/articles/2104/08/news057.html

https://experiments.withgoogle.com/floom




### 4. エジプトのピラミッドを3Dで探検できる技術

http://giza.fas.harvard.edu/

> ギザプロジェクトでは、エジプトのギザ台地にあるピラミッドとその関連遺跡について、これまでに集められた最大の情報、メディア、研究資料にアクセスすることができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93824/3f814132-8952-2ef6-3415-1b292622c8b5.png)

映像がきれいなのでこれだけでも楽しい。


### 5. 難しいと言われるスエズ運河の運行を体験できる技術


https://edition.cnn.com/interactive/2021/03/cnnix-steership/

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93824/c3aba422-3513-7da2-e750-c0da2af4765c.png)

さながらそういうゲームのようですが本当に難しい。座礁しそう。


### オマケ Win11, Win12 in Web

https://dev.to/blueedgetechno/windows-11-in-react-js-hd3

https://dev.to/piyush/windows-11-but-for-web-22h1

https://dev.to/abdulrrehman0/windows-12-but-for-web-4898



## まとめ

「すごい」なんていう語彙力のないタイトルでまとめてしまいました。在宅ワークでこんなのに没入しているといつの間にか時間が溶けます...。

https://qiita.com/e99h2121/items/cece7102a37c189778e8

以上と合わせてお楽しみいただければさいわいです。
github の指定したプロジェクトへコミットした（された）時に line に通知が来るようにする

別サイトで使用した記事の流用になります
メールをあまり開かずlineがメインの方は多いと思いますので（既知の技術ですが）メモとして残します
# 1 　 LINE Notify を開き line のアカウントでログインします

[LINE Notify はこちら](https://notify-bot.line.me/ja/)

# 2 　 github のアイコンを押します

<img width="859" alt="スクリーンショット 2021-07-17 4 46 46" src="https://user-images.githubusercontent.com/79749395/126001126-1b0bca74-a968-4078-9582-04dd6139ece8.png">

# 3 github を認証し

<img width="550" alt="スクリーンショット 2021-07-17 4 33 46" src="https://user-images.githubusercontent.com/79749395/126000545-f5d9b69b-3a95-43a5-b66d-771c1ba664fe.png">

# 4 　通知したいアカウント（Organization）とプロジェクト名、トークルームを選択します

自分の場合は

- kitutune
- bot5
- 通知専用の新規トークルーム LINE Notify

を選択し同意して連携しました
<img width="1023" alt="スクリーンショット 2021-07-17 4 40 57" src="https://user-images.githubusercontent.com/79749395/126000623-85919d6b-d367-4f25-8b2f-fc904fc54021.png">

<img width="1022" alt="スクリーンショット 2021-07-17 4 35 57" src="https://user-images.githubusercontent.com/79749395/126005763-fb831ffc-d15f-4946-9318-344768e979ea.png">


# 5 最後に

連携できたずなのに来ないぞというパターン

## 過去に LINE Notify をブロックしている可能性がありますので

<img width="798" alt="スクリーンショット 2021-07-17 5 19 23" src="https://user-images.githubusercontent.com/79749395/126004283-7aa0a1db-2105-41c5-a868-b24c84865da8.png">

## こちらから友達追加を確認してブロックしていたら解除してください

ちょっと気になるところとしては
github と vercel の連携をしているプロジェクトのケースですが

- github へのコミット
- vercel へのデプロイ

２つ分の通知がきます。ただ、デプロイが失敗した場合のケースも通知が来るのかもしれないので（未検証）ここは受け入れるべきなのかもしれません
AWS ワークショップ 【2021年版】

AWSについてもっと勉強したい、使いこなせるようになりたいエンジニア向けのAWS Workshopサイト(英語版)です。
※引用元が英語な為、Google 翻訳で訳したものを日本語で掲載します

# AWSワークショップとは？
このウェブサイトには、アマゾンウェブサービス（AWS）のチームによって作成されたワークショップがリストされています。ワークショップは、ビジネス上の問題を解決するために使用できる実践的なスキル、テクニック、または概念を教えたり紹介したりするために設計された実践的なイベントです。
上のツールバーを使用して、トピックでフィルタリングできます。

https://workshops.aws/

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/655364/13405107-b78f-0971-dcfb-0c2df14889d3.png)

### 100のワークショップと成長
新しいワークショップとコンテンツが常に追加されています

### 専門家によって作成されました
AWSおよびAWSパートナーの分野のスペシャリストによって作成されました

### 制限なしでグローバルに利用可能で、モバイルフレンドリー
どこからでもアクセス可能

# レベルについて

AWSが定めるWorkshop・ハンズオン・セッション動画視聴をしていく上で必要なレベルや基準である
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/655364/652d62bd-8409-a246-ae22-2a44fdc92541.png)
※ [AWS Summit Online 2021](https://aws.amazon.com/jp/events/summits/online/japan/) 参照

|レベル|対象| 
|:--|:--|
|Level 100|AWS サービスの概要に焦点を当てており、参加者は対象のトピックに関する知識が全くない方を対象としています。|
|Level 200|トピックの入門知識を持っていることを前提に、ベストプラクティス、サービス機能の詳細、およびデモを提供することに焦点を当てています。| 
|Level 300|対象のトピックの詳細を提供するセッションです。参加者はそのトピックにある程度精通している方が対象です。ただし、同様のソリューションの実装経験がない場合もあります。|
|Level 400|トピックに精通しており、既に独自ソリューションを実装している方が対象です。複数のサービス、アーキテクチャによる実装でテクノロジーがどのように機能するかを解説します。|

# サイト内の単語検索
Googleのリサーチャーによると、コンピューターユーザーのほとんどが、Command (Control) + Fを知らないそうです。
AWS Workshopsの探索を効率よくする為にやりましょう。

**Windows**
Control + F

**Mac**
Command + F

# 最後に
AWSの勉強をもっとやりたいエンジニア向けに掲載いたしました。
今後の研鑽になれば良いと思っております。

https://workshops.aws/
2021/07/15開催 Connpassイベントランキング

# 申込数TOP5

|順位|イベント名|グループ|申込数|定員|
|:---:|:---|:---|:---:|:---:|
|:one:|[情報検索/推薦 各社合同 論文読み祭 #1](https://m3-engineer.connpass.com/event/217338/)|[M3 Engineer](https://m3-engineer.connpass.com/)|400||
|:two:|[Nature Bath vol.13 『基礎から学ぶ 組込みRust』出版記念！Rust会](https://nature.connpass.com/event/217935/)|[Nature](https://nature.connpass.com/)|160|160|
|:three:|[Rakuten Commerce QA Night #4](https://rakuten.connpass.com/event/217046/)|[楽天](https://rakuten.connpass.com/)|116||
|:four:|[スタートアップReact LT](https://coralcapital.connpass.com/event/218552/)|[Coral Capital](https://coralcapital.connpass.com/)|116|140|
|:five:|[自律駆動するエンジニア組織の仕組み](https://lapras.connpass.com/event/218121/)|[LAPRAS](https://lapras.connpass.com/)|103||
Azure Update Management と パッチオーケストレーションオプション の組み合わせ

Azure には、Update Management という機能があります。
Update Management を使うと、Windows だけでなく Linux も含めて パッチ適用を一元管理できる点が特長として挙げられると思います。
さらには、Azure VM だけでなく オンプレミス環境や AWSなどの他社クラウド上のパッチも一元管理可能です。

この記事では、Windows Server の更新プログラム適用において、Azure VM をデプロイする際に影響するパラメーターである、「パッチオーケストレーションオプション」のベストプラクティスについて触れたいと思います。

# パッチオーケストレーションオプションとは
Azure VM を展開する時の設定値なのですが、以下の設定値があります。
(1) OSによる自動処理（Windowsの自動更新） = (English : AutomaticByOS)
(2) Azure オーケストレーション（プレビュー）= (English : AutomaticByPlatform)
(3) 手動で更新 = (English : Manual)
(4) イメージの規定値 = (English : ImageDefault)

パッチオーケストレーションオプションの詳細は、以下の私の記事にまとめましたので参照ください。

https://qiita.com/carol0226/items/7452616047c18020da86

# Update Management を利用する上での注意点
パッチを自動管理するので、Azure VM を展開する際に パッチオーケストレーションオプションは、規定値でもある「OSによる自動処理（Windowsの自動更新）」を選んでしまいそうですが、これば適切ではありません。
Update Management でスケジュールや 適用するパッチの指定を行ったとしても、それ以外のタイミングで、OS自身がパッチを適用してしまい、意図しない結果になってしまいます。

これについては、以下の公開情報に 問題点についての記載があります。

https://docs.microsoft.com/ja-jp/azure/automation/troubleshoot/update-management#scenario-updates-are-installed-without-a-deployment

【問題】
Update Management に Windows マシンを登録すると、展開なしで更新プログラムがインストールされます。
【原因】
Windows では、更新プログラムは、使用可能になるとすぐに自動的にインストールされます。 この動作が原因で、更新プログラムをマシンに展開するスケジュールを設定しなかった場合、混乱が生じる可能性があります。
【解決方法】
レジストリ キー HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU の既定値は、4: auto download and install に設定されています。
Update Management クライアントの場合は、このキーを 3: auto download but do not auto install に設定することをお勧めします。

# まとめ
ここまで記事を読んで頂ければ、おのずと結論は見えてきますが、Azure VM を展開する際の パッチオーケストレーション の選択肢は、「手動で更新」が正解です。
これについては、私も 実環境で 「手動で更新」と Update Management の組み合わせで検証を行って、問題無くパッチ適用されたことも確認していますので、ご安心ください。

もし、「OSによる自動処理（Windowsの自動更新）」で VM を展開してしまった後で Update Management を利用する場合には、以下の公開情報のコマンドを利用して 構成変更すると良いようです。
$WUSettings = (New-Object -com "Microsoft.Update.AutoUpdate").Settings
$WUSettings.NotificationLevel = 3
$WUSettings.Save()

https://docs.microsoft.com/ja-jp/azure/automation/update-management/configure-wuagent#pre-download-updates

# 関連URL

https://docs.microsoft.com/ja-jp/azure/automation/update-management/overview
SQLってなに？

#はじめに
データベースの勉強をしている時にSQLというものを知り、実態がよくわからなかったのでその備忘録に。
#SQLとは
SQlとはデータベース（RDBMS）を操作するための`言語`です。
データベースにデータを挿入したり、検索したり、削除する際に利用します。SQLは国際標準化されており、様々なデータベースで利用することができます。有名なデータベースとしては、Oracle、MySQL、PostgreSQL、SQLLiteなどがあり、いずれもSQlで操作することが可能です。
[SQlとは？基礎知識から具体例まで分かりやすく解説！](https://products.sint.co.jp/topsic/blog/sql)
#データベース言語とは
SQlは厳密にはプログラミング言語ではなく、データベースを操作するための`データベース言語`です。

- プログラミング言語
<br>
C言語や、Python、JavaScriptなどの言語があります。いずれもコンピュータを操作したり、アプリケーションを作成するための言語になります。
- データベース言語
<br>
一方、データベース言語はデータベースにのみ命令を実行することができます。
データベース言語はプログラミング言語と違い、ループ処理や、条件分岐などの複雑な処理を命令することはできません。書き方としては、SQLは基本的に一文ごとに結果を求めます。

#SQlの種類
SQLは主に3つの種類に分けることができます。

####データ操作言語(Data Manipulation Language)
データ操作言語は、データベースに対して追加・更新・削除・検索を行うための言語になります。
最近、私が勉強したのはこのデータ操作言語です。

- SELECT(データの検索)
- INSERT(データの追加)
- UPDATE(データの更新)
- DELETE(データの削除)

####データ定義言語(Data Definition Language)
データ定義言語は、テーブルなどを作成・削除、設定を変更するための言語になります。
これは初見です...

- CREATE(テーブルの作成)
- ALTER(テーブルの設定変更)
- DROP(テーブルの削除)
- TRUNCATE（テーブルデータの削除）

'DROP'はDELETEと同じ削除するための命令ですが、DELETEはテーブル内のデータを削除するのに対して、DROPはテーブルそのものを削除するので使い方には注意が必要だと思いました。

#論理削除と物理削除
先程のデータの削除に関して、論理削除と物理削除というものを知ったのでそれも記載します。
####論理削除
論理削除とは、実際にはデータを削除せずに、削除されたように振る舞うことができることを指します。
例えば、Twitterのアカウント削除ですが、あれは削除してから30日以内ならアカウントを復活させることができます。これには論理削除が用いられています。
[論理削除と物理削除とは](https://qiita.com/jonson29/items/4743409eda08fcdf5410)

####物理削除
物理削除とは、その名の通り（通りではないかもしれないが）実際にSQLでDELETEすることを指します。もちろん削除されたデータを復元したり参照することはできなくなります。

###論理削除のメリット
削除したかのように振る舞うだけなので、データの復元が可能です。また、処理速度も物理削除と比較して早いです。
###論理削除のデメリット
[1分でわかる論理削除-メリットとデメリットを考える-](https://qiita.com/wanko5296/items/f1af9c7bf020e867c2dd)
- データベースが若干複雑になる
- データに個人情報が含まれる場合は、削除データの保持に関して問題が発生する可能性がある
- レコードが肥大し続けるため、データベースのコストパフォーマンスを損なう

#最後に
自分なりに調べたことをざっとまとめてみました。
まだほとんど知識がないので実際に自分でデータベースを弄りながら学んでいこうと思います。

それでは、今日はここらで。。
このJavaScriptのコードの出力結果が本当に理解できないから頑張って解説

```javascript

function test(){alert("test1")};
{
  var a={};
  a.abc = test;
  test=()=>alert("test2");
  a.abc(); // =>test1
  a.abc = test;
  a.abc(); // =>test2
}

```

と実行結果がなるらしい。。。。。

なんでやねん！！！！！

```javascript

function test(){alert("test1")};
{
  var a={};
  a.abc = test;
  test=()=>alert("test2");
  a.abc(); // => test関数を上書きした感じだから、test2じゃないの？
  a.abc = test;
// なんでこのコードを
  a.abc(); // =>test2
}

```

function test(){alert("test1")};
と
  test=()=>alert("test2");
はおそらく異なる関数オブジェクトなのであろう。


だけど、んーなんか府に落ちない。
何が分からないのかが分からない。。。。

# 多分答えはこう

```javascript

function test(){alert("test1")};
{
  var a={};
  a.abc = test; 
// この時点でa.abcのtestの中身は{alert("test1")}
  test=()=>alert("test2");
// test関数を定義
// テスト関数の中身は確かに書き換わってるが
// a.abcのtest関数の中身に限定して言うと、
// a.abcのtest関数の中身は{alert("test1")}
  a.abc(); // =>test1
// a.abcのtestの中身は{alert("test1")}
  a.abc = test;
//   test=()=>alert("test2");
// この記述により確かにtest関数自体は書き換わってるので
// a.abcを再定義することによって
// a.abcのtestメソッドが書き変わる
  a.abc(); // =>test2
// 実行結果が変わる
}
```

考え方のコツとしては
ただのtest関数なのか、
a.abcのtestメソッドなのかを
しっかりと分けて考えるのが大切。

にしてもjs初学者の自分はなんか慣れない。。。。
これから慣れていこう。
Linuxのデバイスファイル

デバイスファイル
デバイスをファイルとして表現したもの。

UNIXは色々なものをファイルとして、表現しようとするところに端的に表れているように、端末もその例外ではなく、/dev以下に端末に対応するデバイスファイルが用意されている。
テストケースについて

（執筆途中）

#前提

完全無欠なバグのないソフトウェアは存在しない。

なぜなら完全無欠なテスト手法が存在しないから。

入力A：1～999まで数字
入力B：1～998までの数字
出力C：AとBを掛け合わせた数

999ｘ998　＝　997,002(約100万）

100万のテストケースが必要。複雑なソフトウェアならもっと多くのテストが必要になる。
100万のテストケースを行っても完全とは言えない。コンパイラやCPU自体にバグがあるかもしれないから。

本当に完全なソフトを作るなら、無限大の時間とコストがかかる。
なので、完全なソフトではなく、十分なソフトを目指すというのが費用対効果を考えると、現実的に重要な考え方である。

#テストの手法

#ホワイトボックステスト

プログラムの論理構造が正しいかどうか解析するテスト。
昔使われていた手法。人間の時間をたくさん使って内部構造を解析してテストする。
過去に活躍して研究されていたが、今現在有用で使われるわけではない。

／／ファイルサイズが巨大なソフトを2週間でテストしろと命じられたら、手法など考えずただやみくもに動作確認することになる。・・

テストは限られた時間で行う最大公約数的な仕事。プログラムも近いが間に合わなければ、機能を削除することができる。しかしテストはある機能をテストしないという選択肢はない。

ホワイトボックステストだけでテストを終了することはできない。
論理構造の正しさのみをテストするので、ソフトの仕様が間違っていることから起こるバグはテストできない。
なので、ブラックボックステストを併用する。

ブラックボックスとホワイトボックスの優劣は比較できない。

##具体的な手法

###制御パステスト法


カバレッジ率

#ステートメントカバレッジ

コード内の命令文（ステートメント）を少なくとも一度実行する。
（＊ステートメントは、
#include<stdio.h>
int main(){}
printf("hello")
if (){}
return 0
すべて。
ifの()の中身が条件分岐
if自体は、制御命令。）

しかし、漏れが多い。条件分岐を間違って書いていた場合、発見できない。
分岐によるエラーを発見できない。

ステートメントカバレッジは、非常に弱いテスト手法。

#ブランチカバレッジ

分岐のコードをチェックする方法

ブランチカバレッジは、分岐コードに対してそれぞれの判定条件がTRUE、FALSEの結果を少なくとも１つ持つようにテストケースを書く。

ブランチカバレッジは、網羅するという意味でステートメントカバレッジより強いが、テストケースがかなり増える点が問題点。
ステートメントカバレッジでテストを終えることは非常に危険とされている。なので、併用される。

プログラムのバグは、全体から平均的に出るのではなく、特定部分から発生しやすい傾向があるので、バグがたくさん出る部分に対してブランチカバレッジを実行するのも悪くない考え。

#カバレッジの基準

１００%が理想であるが、時間と費用からみて非現実的。
一般の商用ソフトウェアなら６０〜９０％で十分。

命などに関わる部分は１００％近くのカバレッジが要求される。（自動運転など）
どれだけのカバレッジを持ってくれば適切かという答えは学説的にもない。

ヒューレット・パッカード社のデータで言えば、高ければ８０％、低くて２０%しか網羅せず出荷することもある。

カバレッジテストを行った結果次のコードがカバーされない可能性がある。

エラー処理
使われていないコード

ほとんど起こり得ないようなエラーの処理もある。
mallocによるメモリの確保など。

なぜなら、最近のOSは仮想メモリなどを使っていて、本当にメモリのない状態を作り出すことが困難であるから。

#カバレッジテストで検出できないバグ

１００%は無理。

ループに関するバグ
要求仕様自体が間違っているバグ
データに関するバグ
タイミングに関するバグ

ループはテスト担当者よりも開発者自身が気にかけなければいけない。

#ブラックボックス

プログラムをブラックボックスと見立てて、さまざまな入力を行い、ソースコードを見ずにテストを行う手法。
現在は、殆どがブラックボックスが行われている。

テストは、４つの振る舞いを確認すれば良い。

入力の処理、出力の処理、計算、データの保存
それらに適切にテストすればほとんどのバグは発見される。

#ブラックボックステストの基本

同値分割法、境界値分析法が基本。

上記の２法で、入力処理、出力処理が適切に行われているかをテストする。

例：印刷するページを０ページから０ページを指定すると無効な範囲であると警告がでるのは、正しく同値分割、境界値分析を適切に行われているから。

#同値分割法

同値分割とは、入力領域を同値クラスとして、部分集合に分割し、その部分集合に入る入力値を等価とみなす作業。

格言：テストケースを省略するのはやむを得ないが、その省略されたテストケースでバグを出してはいけない。

テストケースの数を減らすには。。。

境界値とは、常にバグが潜んでいるので、詳しくテストする必要がある。

バグがでやすい４つのタイプ

＞と＞＝を間違える　閉包関係バグ
数字の書き間違い、スペックの読み間違いなど
境界がない。（条件文を書くのを忘れてしまった場合）
余分な境界線　不要な境界を加えてしまった場合。





参考　
知識ゼロから学ぶソフトウェアテスト改訂版　著　高橋寿一
1 入力と出力 Dif:5 ABC199 A：「AtCoder　凡人が『緑』になるための精選50問詳細解説」サンプル

**この記事は拙著「AtCoder　凡人が『緑』になるための精選50問詳細解説」のサンプルです**
価格：100円
kindle：https://www.amazon.co.jp/dp/B09C3TPQYV
booth(pdf)：https://sano192.booth.pm/items/3179185

次：https://qiita.com/sano192/items/467939ec8336d0bec380

https://atcoder.jp/contests/abc199/tasks/abc199_a

**【目標】**
・入力と出力のやり方を身につける

**【概要】**
典型的なA問題。ひねった部分はないので、入力と出力のやり方がわかれば解くことができる。

**【方針】**
入力を受け取り、条件を判定する。

pythonで入力を受け取る方法は以下の5つ。

(1)数字が1つ
入力例：N

```python:
N=int(input())
```

(2)数字が2つ以上で別々に受け取り
入力例：A B

```python:
A,B=map(int, input().split())
```

(3)文字列が1つ
入力例：S

```python:
S=input()
```

(4)文字列が2つ以上で別々に受け取り
入力例：S T

```python:
S,T=map(str, input().split())
```

(5)リストで受け取り
入力例：A1 A2 … An

```python:
A=list(map(int, input().split()))
```

上記の5つを使えれば入力の受け取りに困ることはない。この5つはいつでもコピペできるようにしておこう。

他にもやり方はいくつもあり、「競技プログラミング　入力」で検索するとどの方法が速い、遅いという意見が大量に出てくる。しかし入力の受け取りが原因でTLE(実行時間制限超過)＝不正解となることはありえないので気にしなくて良い。とにかく上記の5つだけ使えるようにしよう。

この問題の場合、
A B C
のそれぞれを受け取るのでパターンとしては
(2)数字が2つ以上で別々に受け取り
にあたる。

答えの出力については以下のように書く。

```python:
print(出力したいもの)
```

【実装】
まず入力を受け取ろう。

```python:
A,B,C=map(int, input().split())
```

これでA,B,Cに入力されたそれぞれの値を受け取ることができた。

あとは問題文の条件を満たしているか？判定して出力するだけだ。
つまりA^2+B^2<C^2となっているか？を判定する。
これはif文で記載すれば良い。
pythonの場合Aの2乗はA^2ではなくA**2と書くことに注意しよう。

```python:
if A**2+B**2<C**2:

else:
```

if、elseの中に処理内容を記載する。
・ifは条件を満たしている場合
・elseは条件を満たしていない場合
この問題の場合、条件を満たしていれば”Yes”、そうでなければ”No”を出力する。
出力の方法は
print(出力したいもの)
だったことを思い出そう。

提出するコードは以下のようになる。

```python:
A,B,C=map(int, input().split())

if A**2+B**2<C**2:
    print("Yes")
else:
    print("No")
```

コードが書けたら合っているかどうか、「入力例」を入力して確認する。
書けたコードを実行し、
「入力例１」
2 2 4
を入力してみよう。(入力例1をコピペすればよい)
出力例1の通り、「Yes」が出力されれば成功。入力例1については正解している。

エラーが出たらコードの見直しが必要だ。よくある間違いを2つ紹介しよう。
「よくある間違い1」

```python:
A,B,C=map(int, input().split())

if A**2+B**2<C**2:
print("Yes")
else:
print("No")
```

エラー内容は
IndentationError: expected an indented block
(インデントのエラー：インデントされたブロックが必要です)
要するにインデントを下げろと言っている。pythonでifを書いた後は必ずインデントを下げなければならない。printの前にカーソルを合わせ、Tabキーを押してインデントを下げよう。

「よくある間違い2」

```python:
A,B,C=map(int, input().split())

if A**2+B**2<C**2:
    print(Yes)
else:
    print(No)
```

エラー内容は
NameError: name 'Yes' is not defined
(名前のエラー：名前 “Yes” が定義されていません)
Yes,Noにダブルクオーテーション(“”)が入っていないとエラーになる。
文字を出力するときはpythonに「これは文字だよ」と教えてあげないといけない。そのため、Yes、Noを”Yes”、"No"と書き換えよう。

入力例1を試して問題がなければ入力例2,3についても試してみる。
全ての入力例について出力結果が出力例と合致したら提出だ。

問題ページ下部にある出力フォームにコードをコピペし、言語「python」を選択して「提出」しよう。
![image60.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700383/049c1b3c-a34c-1588-e1c3-a006ab2dd061.png)


**【コード全文】**

```python:
A,B,C=map(int, input().split())

if A**2+B**2<C**2:
    print("Yes")
else:
    print("No")
```

**この記事は拙著「AtCoder　凡人が『緑』になるための精選50問詳細解説」のサンプルです**
価格：100円
kindle：https://www.amazon.co.jp/dp/B09C3TPQYV
booth(pdf)：https://sano192.booth.pm/items/3179185
Railsのテーブル要素にリンクをつけた

## tableのtr(行ごと)にリンクを貼る
### viewにリンクを追加
```erb:index.html.erb
<tbody class="institution_index_table_tbody">
  <% @institution.each do |institution| %>
    <%# data-hrefにリンク先を記述する %> 
    <tr class="institution_index_tbody_tr" data-href="/institutions/<%= institution.id%>">
      <td class="institution_index_td name_td"><%= institution.name %></td>
      <td class="institution_index_td postcode_td"><%= institution.postcode %></td>
      <td class="institution_index_td address_td"><%= institution.address %></td>
      <td class="institution_index_td intro_td"><%= institution.introduction%></td>
    </tr>
  <% end %>
</tbody>
```
### jsの設定
```js:app/javascript/packs/institutions.js
jQuery(document).on("turbolinks:load", function() {
  $(".institution_index_tbody_tr").on('click', function() {
      window.location = $(this).data("href");
  });
});
```
institution_index_tbody_trクラスをクリックしたら、data-hrefのリンクに遷移する。

```js:app/javascript/packs/application.js
import "packs/institutions.js"
```

## tableのtd(セルごと)にリンクを貼る
ほとんど一緒
### viewにリンクを追加
```erb:index.html.erb
<tbody class="institution_index_table_tbody">
  <% @institution.each do |institution| %>
    <tr class="institution_index_tbody_tr">
      <td class="institution_index_td name_td" data-href="/institutions/<%= institution.id%>"><%= institution.name %></td>
      <td class="institution_index_td postcode_td"><%= institution.postcode %></td>
      <td class="institution_index_td address_td"><%= institution.address %></td>
      <td class="institution_index_td intro_td"><%= institution.introduction%></td>
    </tr>
  <% end %>
</tbody>
```
### jsの設定
```js:app/javascript/packs/institutions.js
jQuery(document).on("turbolinks:load", function() {
  $(".name_td").on('click', function() {
      window.location = $(this).data("href");
  });
});

// institution_index_tdにリンク先を設定しない<td>をクリックするとエラーになる
jQuery(document).on("turbolinks:load", function() {
  $(".institution_index_td").on('click', function() {
      window.location = $(this).data("href");
  });
});
```
```js:app/javascript/packs/application.js
import "packs/institutions.js"
```
## 参考資料
[railsでテーブル要素の一つ一つにリンクを貼る方法](https://qiita.com/Kohei_Kishimoto0214/items/2e56985552926d025c35)
[how to make a whole row in a table clickable as a link?](https://stackoverflow.com/questions/17147821/how-to-make-a-whole-row-in-a-table-clickable-as-a-link)