OmniAICreator/Qiita-1.07M huggingface dataset:
Vagrantfileネットワーク設定


# 設定可能なネットワーク
設定可能なネットワークは下記の5種類です。

1. NAT（vagrantのデフォルト）
1. ホストオンリーアダプタ
1. 内部ネットワーク
1. ポートフォワーディング
1. ブリッジアダプター

# NAT
vagrantfileのデフォルト設定です。
NATではホストとは異なるネットワークがVMに割り当てられます。VirtualBoxがルーターの役割をし、ホストとVMをつなぐことでVMからインターネットの接続を可能にします。この設定ではVMごとに独立したネットワークが割り当てられるため、VM同士の通信はできません。

通信可否は下記表になります。

|  種別  |  VM→ホスト  |  ホスト→VM  |  VM→外部  |  外部→VM  |  VM↔VM  |
| ---- | ---- | ---- | ---- | ---- | ---- |
|  NAT  |  ○  |  ×  |  ○  |  ×  |  ×  |
※外部はホスト以外のネットワークを指します。
※「VM↔VM」は同じネットワーク内の仮想マシン同士の通信を指します。

# ホストオンリーアダプタ
ホスト↔VM間の通信が可能になります。
また、VMから外部へのアクセスが可能となります。

通信可否は下記表になります。

|  種別  |  VM→ホスト  |  ホスト→VM  |  VM→外部  |  外部→VM  |  VM↔VM  |
| ---- | ---- | ---- | ---- | ---- | ---- |
|  ホストオンリーアダプタ  |  ○  |  ○  |  ○  |  ×  |  ×  |

#### Vagrantfileの設定方法

```:Vagrantfile
# 固定 IP を割り当てる場合
config.vm.network "private_network", ip: "192.168.33.10"

# 動的に IP を割り当てる場合
config.vm.network "private_network", type: "dhcp"
```


# 内部ネットワーク
この設定では内部に指定したネットワークが作成されます。
同じ名前の内部ネットワークに所属するVM同士は通信可能となります。

通信可否は下記表になります。

|  種別  |  VM→ホスト  |  ホスト→VM  |  VM→外部  |  外部→VM  |  VM↔VM  |
| ---- | ---- | ---- | ---- | ---- | ---- |
|  内部ネットワーク  |  ○  |  ×  |  ○  |  ×  |  ○  |

#### Vagrantfileの設定方法

```:Vagrantfile
# virtualbox__intnet でネットワーク名を指定
config.vm.network "private_network", ip: "192.168.33.10", virtualbox__intnet: "mynetwork"
```

# ポートフォワーディング
ホストとVMの特定ポートを紐づけ、転送します。
ホスト 80 番ポートとVM 8080 番ポートを紐づけた場合、ホスト 80 番ポートの接続はVM 8080 番ポートへと転送されます。

通信可否は下記表になります。

|  種別  |  VM→ホスト  |  ホスト→VM  |  VM→外部  |  外部→VM  |  VM↔VM  |
| ---- | ---- | ---- | ---- | ---- | ---- |
|  ポートフォワーディング  |  ○  |  ×  |  ○  |  ×  |  ×  |

#### Vagrantfileの設定方法

```:Vagrantfile
# ホストマシン 80 番ポートへの接続を仮想マシンの 8080 番ポートへ転送する
config.vm.network "forwarded_port", guest: 80, host: 8080
```

# ブリッジアダプター
ホストが所属するネットワークのIPをVMに割り当てます。
外部からVMへの通信が可能となります。

通信可否は下記表になります。

|  種別  |  VM→ホスト  |  ホスト→VM  |  VM→外部  |  外部→VM  |  VM↔VM  |
| ---- | ---- | ---- | ---- | ---- | ---- |
|  ブリッジアダプター  |  ○  |  ○  |  ○  |  ○  |  ○  |

#### Vagrantfileの設定方法

```:Vagrantfile
# 固定 IP を割り当てる場合
config.vm.network "public_network", ip: "192.168.0.10"

# 動的に IP を割り当てる場合
config.vm.network "public_network"
```

# まとめ
#### 通信可否のまとめ

|  種別  |  VM→ホスト  |  ホスト→VM  |  VM→外部  |  外部→VM  |  VM↔VM  |
| ---- | ---- | ---- | ---- | ---- | ---- |
|  NAT  |  ○  |  ×  |  ○  |  ×  |  ×  |
|  ホストオンリーアダプタ  |  ○  |  ○  |  ○  |  ×  |  ×  |
|  内部ネットワーク  |  ○  |  ×  |  ○  |  ×  |  ○  |
|  ポートフォワーディング  |  ○  |  ×  |  ○  |  ×  |  ×  |
|  ブリッジアダプター  |  ○  |  ○  |  ○  |  ○  |  ○  |
[Ethereum]curlでアカウントの値を取得する

#はじめに
EthereumのDapp開発について勉強しながら色々試しています。
json-rpcを使用するとローカル環境からEthereumノードにアクセスすることが出来たので、その方法を残しておきます。


#概要
1. HTTP-RPCを有効化する
2. JSONデータを作成する
3. curlでEthereumノードにデータをPOSTする
4. Ethereumノードからの値を受け取る


#JSON RPC APIとは
公式によると、JSON形式で記述するステートレスかつ軽量なRPC(Remote Procedure Call)プロトコルで、HTTPやSocket等で使用することが可能。
HTTPプロトコルのPOSTメソッドでJSON形式のリクエストを送信し、同じくJSON形式のレスポンスを受け取る。

```bash:request
{"jsonrpc": "2.0", "method": "", "params": "", "id": ""}
```
```bash:response
{"jsonrpc":"2.0","id":"","result":""}
```

このようにJSON形式のデータを送受信する。
詳しくは下記公式を参照。


https://eth.wiki/json-rpc/API


#HTTP-RPCを有効にする
ローカル環境からEthereumノードのアカウントにアクセスするにはHTTP-RPCサーバーを有効にしておく必要がある。
Geth起動時に --rpcオプションを指定することでHTTP-RPCサーバーが有効になる。

```bash:bash
$ geth --networkid "20" --nodiscover --rpc --rpcaddr "localhost" --rpcport "8545" --rpcapi "eth,net,web3,personal,miner,admin" --datadir /work console 2>> /work/geth.log
```
・--rpc: HTTP-RPCサーバーを有効にする
・--rpcaddr: エンドポイントのホストアドレス。デフォルトは"localhost"
・--rpcport: エンドポイントのポート番号。デフォルトは8545
・--rpcapi: APIで受け付けるHTTP-RPCインターフェースの種類
詳しくは https://eth.wiki/json-rpc/API


#EOAの所持etherを確認してみる
今回はEOAの所持ether確認のリクエストを送ってレスポンスが返ってくるか試してみる。
gethコンソールでの

```bash:geth
> eth.getBalance(eth.accounts[0])
```
に相当する処理。


#JSONデータの作成
json-rpcの仕様に従い、ブロックパラメーターは eth_getBalance を使用する。

```bash:json-rpc
{"jsonrpc": "2.0", "method": "eth_getBalance", "params": ["0x9f9d52e422572aef077fa89ad9ef55044305ae4c", "latest"], "id": "2"}
```
"params"にはリスト形式で確認したいアカウントアドレスとオプションを記載する。
"id"はリクエストとレスポンスを紐付けるための値(任意)を記載する。
詳細は https://eth.wiki/json-rpc/API


#curlでJSONデータをPOSTする
次にcurlコマンドでこのJSONデータをPOSTする。

```bash:request
$ curl -X POST -H "Content-Type: application/json" --data '{"jsonrpc": "2.0", "method": "eth_getBalance", "params": ["0x9f9d52e422572aef077fa89ad9ef55044305ae4c", "latest"], "id": "2"}' http://localhost:8545
```
※参考サイトではcontent-typeの指定はされていませんでしたが僕の環境ではcontent-typeも指定してあげないとエラーが表示されたのでヘッダーに指定しています。


```bash:response
{"jsonrpc":"2.0","id":"2","result":"0x194312237619664600"}
```

レスポンスは成功なら"result"に値が格納されて返ってきます。
返ってきた値は16進数表記になっているので、10進数表記に修正。
0x194312237619664600 → 466001566183000000000
アカウント(0x9f9d52e422572aef077fa89ad9ef55044305ae4c)は
466001566183000000000weiを所持している模様。


#gethコンソールで確認
それでは実際にgethコンソールでgetBalance()を実行した値と比較して確認してみる。

```bash:geth
> eth.getBalance(eth.accounts[0])
466001566183000000000
```

同じ値が返ってきているので成功です。
curlでEthereumノードのアカウントにアクセスすることが出来ました。


#おわりに
次回はjson-rpcを使いスマートコントラクトへのcallを試してみます。
記事内で間違えている箇所やお気付きの点があればご指摘いただければありがたいです。


#参考サイト
今回json-rpcを使用するにあたり下記サイトを参考にさせていただきました。
ありがとうございます。

[EthereumノードにJSON-RPC API経由でアクセスする]
(https://qiita.com/kanehara/items/5f09401813b52a326ac5)

[[Ethereum] スマートコントラクトを呼び出してみよう(call編)]
(https://medium.com/nayuta-inc/ethereum-%E3%82%B9%E3%83%9E%E3%83%BC%E3%83%88%E3%82%B3%E3%83%B3%E3%83%88%E3%83%A9%E3%82%AF%E3%83%88%E3%82%92%E5%91%BC%E3%81%B3%E5%87%BA%E3%81%97%E3%81%A6%E3%81%BF%E3%82%88%E3%81%86-call%E7%B7%A8-3c6eaf289be7)
VirtualBox + VagrantでCentOS7を構築する

# 1. はじめに
windows10に「VitrutlBox + Vagrant」でLinux仮想環境(CentOS7)を構築することを目的とします。

# 2. VirtualBoxとは
使用しているPC上に仮想環境を構築し、別のOSをインストールできる仮想化ソフト。
Oracleが開発しているフリーソフトです。
今回はWindows上にLinux仮想環境を構築します。

# 3. Vagrantとは
仮想マシンの管理するためツール。読み方は「ベイグラント」
Vagrantfileという設定ファイルによって 仮想マシンを作成、起動、停止したりすることができます。
Vagrantを使うメリットは環境構築の自動化、Vagrantfileを配布することで開発環境の共有が可能などがあります。

# 4. 準備
 
### 4-1. VirtualBoxインストール
VirtualBoxは下記記事の手順を参考にインストールしてください。
<a href="https://qiita.com/taketakekaho/items/e76d65b9232f38299b5b" target="_blank" rel="noopener noreferrer">Windows10にVirtualBoxをインストールする</a>

### 4-2.Vagrantインストール
Vagrantは下記記事の手順を参考にインストールしてください。
<a href="https://weblabo.oscasierra.net/install-vagrant-onto-windows/" target="_blank" rel="noopener noreferrer">Windows10にVagrantをインストールする</a>

# 5. 仮想マシン作成

### 5.1 Box追加
任意のディレクトリに「cd」コマンドで移動します。

```:ディレクトリ移動
// ここにVagrantfileが作成されます
$ cd C:\Users\test\workspace\Linux\CentOS
```

次のコマンドでBoxを追加します。

```:box追加コマンド
$ vagrant box add {VM名} {boxファイルダウンロードURL}
```

VM名は「centos7」としてますが任意でオッケーです。
boxファイルダウンロードURLは<a href="http://www.vagrantbox.es/" target="_blank" rel="noopener noreferrer">こちら</a>から取得します。
今回はCentOS7を取得しました。

```:box追加コマンド実行
$ vagrant box add centos7 https://github.com/tommy-muehle/puppet-vagrant-boxes/releases/download/1.1.0/centos-7.0-x86_64.box
```

Boxが追加されていることを確認します。
「centos7」が表示されていれば成功です。

```:box確認
$ vagrant box list
centos7                   (virtualbox, 0)
```

### 5.2 仮想マシン初期化
次のコマンドを実行して現在のディレクトリにVagrantfileを生成します。

```:Vagrantfile生成コマンド
$ vagrant init {VM名}
```

VM名に「centos7」を指定して実行します。

```:Vagrantfile生成コマンド実行
$ vagrant init centos7
```

現在のディレクトリに「Vagrantfile」が生成されていれば成功です。

### 5.3 仮想マシン起動
Vagrantfileの生成ができたので、起動します。
Vagrantfileがあるディレクトリで次のコマンドを実行してください。

```:起動コマンド
$ vagrant up
```

起動を確認します。runningであればオッケーです。

```:起動確認
$ vagrant status
default                   running (virtualbox)
```

停止したい場合は次のコマンドを実行

```:停止コマンド
$ vagrant halt
```

### 5.4 仮想マシン接続
起動ができたので仮想マシンにSSH接続します。
次のコマンドを実行してください。

```:SSH接続
$ vagrant ssh
```
```:SSH接続成功
[vagrant@localhost ~]$
```

デフォルトでは「vagrant」ユーザーでログインされます。
初期のユーザーとパスワードは下記です。

|  ユーザー名  |  パスワード  |
| ----      | ----        |
|  vagrant  |  vagrant    |
|  root     |  vagrant    |
CentOS8.4&PHP7.4&mariaDBでWordpress5.8用の環境構築メモ

WordPress最新バージョン（2021年8月現在）5.8環境を、Linux（CentOS8）上に構築した際のメモです。

- システム要件
    - CentOS Linux release 8.4.2105
    - Apache/2.4.37 
    - PHP 7.4.21 
    - mysql  Ver 15.1 Distrib 10.3.28-MariaDB, for Linux (x86_64) using readline 5.1
    - WordPress 5.8


- 対象読者
    - 基本的なコマンド操作とvim操作は把握している前提とします。

## おまじない

```shell
yum -y update
```

### リポジトリの追加
```shell
yum -y install https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm
yum -y install https://rpms.remirepo.net/enterprise/remi-release-8.rpm
```

### OS設定、必須ツールインストール
```shell
localectl set-locale LANG=ja_JP.UTF-8
timedatectl set-timezone Asia/Tokyo
yum -y install vim-enhanced
yum -y install mod_ssl
yum -y install git
```

## rootユーザーのSSH接続を禁止にする

### 専用ユーザーの作成
```shell
useradd <ユーザー名>
passwd <ユーザー名>
<パスワード入力>
```

### sshd_configの編集
```shell
cp /etc/ssh/sshd_config /etc/ssh/sshd_config.org
``` 

```shell:/etc/ssh/sshd_config
# yesからnoへ修正
PermitRootLogin no
```

```shell
# sshdを再起動して設定反映
systemctl restart sshd
```

専用ユーザーでSSH接続できるか確認しましょう。

## Apache

### Apacheのインストール
```shell
# インストール
yum install httpd -y
# 起動
systemctl start httpd.service
# OS起動時に自動起動
systemctl enable httpd.service
```

### 設定ファイル（httpd.conf）の編集
```shell
# 元の設定ファイルはリネームして保存しておき
cp /etc/httpd/conf/httpd.conf /etc/httpd/conf/httpd.conf.org
# vimコマンドで設定ファイルを開く
vim /etc/httpd/conf/httpd.conf
```

```shell:/etc/httpd/conf/httpd.conf
# indexファイルの拡張子に.phpを追加
DirectoryIndex index.php index.html

# Non を Allへ変更 (数カ所ある)
AllowOverride All 
```

```shell
# 設定ファイルの構文チェック
httpd -t
# エラーが出なければ再起動
systemctl restart httpd.service
```

## PHP


### PHP7.4のインストール
```shell
dnf -y install dnf-utils
dnf -y module install php:remi-7.4
yum install -y php-cli php-devel php-common php-mbstring php-fpm php-gd php-opcache php-pdo php-xml php-intl php-zip php-pear php-bcmath php-mysql
```

### 設定ファイル(php.ini)の編集
```shell
cp /etc/php.ini php.ini.org
```

```shell:/etc/php.ini
#最低限
date.timezone = "Asia/Tokyo"
```

## mariaDB

### mariaDBインストール
```shell
# インストール
yum install -y mariadb-server
# 起動
systemctl start mariadb
# 自動起動を有効化
systemctl enable mariadb
```

### セキュリティ強化(おまじない）
```shell
mysql_secure_installation
Enter current password for root (enter for none): 空でエンター
Set root password? [Y/n]　
<Yを入力して、rootパスワードの入力>

以降の質問は全部Y
```

### 文字コード設定
```shell
cp /etc/my.cnf.d/mysql-clients.cnf /etc/my.cnf.d/mysql-clients.cnf.org
cp /etc/my.cnf.d/mariadb-server.cnf /etc/my.cnf.d/mariadb-server.cnf.org
```

```shell:/etc/my.cnf.d/mysql-clients.cnf
[mysql]
default-character-set=utf8mb4
```

```shell:/etc/my.cnf.d/mariadb-server.cnf
[mysqld]
character-set-server=utf8mb4
```

```shell
# 再起動で設定反映
systemctl restart mariadb
```

### rootにログイン
```shell
mysql -u root -p
<パスワード入力>
```

### 文字コード確認
```shell
show variables like "%char%";
```

### DBと専用ユーザー作成、全権限付与
```shell
# DBを作成
create database <データベース名>;
# 全権限を持つDB専用ユーザーを作成
GRANT ALL PRIVILEGES ON <データベース名>.* to <ユーザー名>@localhost IDENTIFIED BY "<ユーザーパスワード>";
# 反映
FLUSH PRIVILEGES;
```
Windows10でセキュアチャネルをps1で修復する

AD環境で、「このワークステーションとプライマリドメインの信頼関係に失敗しました」
上のエラーが出た時に毎回ドメイン再参加するのか大変なので作ってみました

#zipファイル
<p><a href="https://github.com/yyoshizu/Securechannel_repair/releases/download/ps1/Securechannel_repair.zip"download="https://github.com/yyoshizu/Securechannel_repair/releases/download/ps1/Securechannel_repair.zip">zipファイルをダウンロード</a></p>
#ソースコード

```ruby:Securechannel_repair.ps1
#$Checkへセキュアチャネル状況結果を代入(ture、false)
$check = Test-ComputerSecureChannel

#$Checkの結果出力
write-output $check

pause

#$Checkの結果で条件分岐
if("True" -eq $check){

#Ture処理
echo Domain-OK
pause
exit

}Else{

#False処理
#「domainname\username」は利用している「ドメイン名\監視者アカウント名」に変更すること。
echo Domain-NG
Test-ComputerSecureChannel -Repair -Credential domainname\username

pause

#1分後に再起動
shutdown /r /t 60

}


exit


#$Checkへセキュアチャネル状況結果を代入
#出力結果を目視確認後、ture or falseで処理変更
#tureの場合：Domain-OKを返して終了
#Falseの場合：ドメイン名\監視者アカウント名でログインスクリプト起勁
#　　　　　　 パスワードを入力後、Enterで60秒後に再起動

```

#使い方

①Securechannel_repair.ps1をメモ帳等で開き以下を修正する。

　　修正前：Test-ComputerSecureChannel -Repair -Credential domainname\username
　　修正後：Test-ComputerSecureChannel -Repair -Credential 利用中のドメイン名\ドメインの管理者アカウント名

　■以下記入例(ドメイン名：test01.local　管理者アカウント名：administratorの場合)
　　記入例：Test-ComputerSecureChannel -Repair -Credential test01.local\administrator

②エラーが出ているPCにて「.\administrator」または、
　NWを切断し他状態で「該当のドメインユーザ」でログインする。
　　※「.\administrator」はローカルのadministratorアカウントになります。

③Securechannel_repair.ps1を右クリックし「powershellで実行」を押下する。

④-①セキュアチャネルに異常がない場合は「Domain-OK」が表示され終了する、
　※異常がない場合はここまで

④-②セキュアチャネルに異常がある場合は「Domain-NG」が表示され、ログインスクリプトが起動する。

⑤以下の画面が表示されるので、ドメインの管理者パスワードを入力する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/475419/409ce223-9340-9ee9-97ce-b5b077503701.png)

⑥修復完了後、「True」と表示され60秒後に再起動される。
　※パスワードを打ち間違った場合は「False」と表示されるので、
　　先に進まずps1を閉じて再度実行してください。

⑦再起動完了後に該当のドメインユーザでログインを行う。

以上

#2021/8/21追記
たまたま気づいたんですが
「このワークステーションとプライマリドメインの信頼関係に失敗しました」
上は、AD登録されてるコンピュータに対して
別ユーザが同時にアクセスしてるとセキュアチャネル破損するみたいですね、、


根本原因はHDDの入れ替えとかでホスト名が競合して同じsidのpcが乱立してる可能性もあるので、発生頻度が多ければ確認してみてもいいかもしれません。
同人誌のまとめ裁断、まとめスキャン

#1. はじめに

同人誌を大量にスキャンするため、1冊ずつ裁断・スキャンするのではなく、まとめて行って効率アップさせる話です。1冊づつセットするよりも時間がかからず、作業が減って疲れません。
使用機材は下記の通りです。

- Canon DR-X10C
- 富士通 fi-7700S(フラットベッド部を使用)
- DURODEX 200DX(裁断機)

スキャナの設定は下記のページに記載しています。
[自炊(本のスキャン)向けスキャナ設定 - Qiita](https://qiita.com/mayo00/items/7a2e85b3afd67c9439d0)

A5コミックの場合については下記のページにまとめています。
[A5コミック約200ページの裁断と600dpi PNGスキャンを合わせて1冊あたり3分24秒で実施した手法 - Qiita](https://qiita.com/mayo00/items/d62c3af3bd55394907c2)

#2. 裁断

表紙＋裏表紙を剥いて、本文を1～7冊程度裁断機にセットし、まとめて裁断します。

#3. スキャン

スキャナに10～30冊程度まとめてセットし、ADFでスキャンします。
あとで分割しやすいように、最後のページが分かりやすい本を途中にします。分かりにくい本は最後にするか、単独でスキャンします。

ADFでスキャン中に、表紙＋裏表紙をA3フラットベッドスキャナでスキャンします。

#4. 実績

B5同人誌12冊(厚めの本あり)、本文267枚(DR-X10Cに一度にセット。同人誌の紙厚だと300枚くらいが限界？)で、表紙＋裏表紙を剥くのと裁断に5分程度？(きっちり測っていません)、重送・紙詰まり等のエラーなしでADFスキャン(600dpiグレースケールPNG)に11分弱です。
チェックは後で行います。

ADFスキャンの待ち時間が長いので、DR-X10Cをもう一台使ってさらにパイプライン処理をすると効率が上がりますが、あまり大量に一度にスキャンすると、縦線があった場合に原稿を探すのが大変になるので、いまのところやっていません。

約7時間で84冊裁断・スキャン・チェック・リネームを行いました。

#5. スキャン結果の分割

[画像ビューア ImageTest1 - Qiita](https://qiita.com/mayo00/items/cb5d1f49464f69191efd)(自作)の「複数ファイル移動(現在のファイルまで)：Ctrl+M」を使用して、チェック中に分割しています。

#6. フォルダ名のリネーム

フォルダ名のリネームには下記のブックマークレットを使います。(自作)
[駿河屋の商品ページまたは買取商品ページから同人誌のサークル名とタイトルを取得するブックマークレット GetCircleTitle - Qiita](https://qiita.com/mayo00/items/556c2c3d7a14759d088f)
List EditorというSalesforceのAppExchangeを試してみた！～関連リストからレコードを一括編集のアプリ～

※今回の内容は動画でも解説してます

https://www.youtube.com/watch?v=3EZ0p2fDnOI

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


みなさん。こんにちは。
Salesforceを使っているといろいろ運用面で考えることがありますよね。

よくある悩みとしては
####「関連リストからレコードを一括編集したい」
ですね。
例えば取引先（顧客）から商談を一括して編集したい。ということありませんか？

しかし、そのような機能はSalesforceの標準には無く、今まではコードによる開発をするしかなかったです。


ところが！List EditorがAppExchangeに掲載されました。
https://appexchange.salesforce.com/appxListingDetail?listingId=a0N3u00000PFXi6EAH

List Editorを使用すれば、ノンサポートですが無償で
####「関連リストからレコードを一括編集」が可能となりました。
つまり下記画像のように親オブジェクト（取引先レコード）から子レコード（商談レコード）の一括編集が可能です！
![完成１.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/2ddcdc7e-3c80-222a-610e-462077bc4634.png)




それでは、List　Editorはどのように設定すればいいか。ここで記載します！

※注意１※　本番環境でいきなりList Editorをインストールするのではなく、まずはSandboxやplaygroundで試しにインストールして仕様をご確認ください

※注意２※　今回はplaygroundにList　Editorをインストールします。AppExchangeの
Playgroundのインストール方法は割愛しますので下記Trailheadをご参照ください
https://trailhead.salesforce.com/content/learn/modules/trailhead_playground_management

※注意３※　今回は一例としてLightning環境で「取引先Lightnigレコードページから商談レコードの一括編集(金額や完了予定日など)」を設定する手順を示します。

###ステップ１ list Editorが正しくインストールされたか確認
まずは「インストール済みパッケージ」に正しくインストールされているか確認しましょう
他の環境にインストールしないか注意しましょう！
![listeditor1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/20ead959-0e1b-297f-e1bc-bca891550f86.png)



###ステップ２ 取引先レコードページに進みます
取引先lightningレコードページから右上歯車マークをクリックし「編集ページ」をクリックします
![取引先１.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/962941f3-a1b7-cf03-1b6e-6246f785fe56.png)

###ステップ３　コンポーネントから「List Editor」を選択しドラッグ＆ドロップ
![list2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/d083c0f4-1c2a-62b6-0177-e3212f5a0cb5.png)

###ステップ４　コンポーネントの設定をする
設定部分は大きく２つです
①何のオブジェクトをLightningレコードページで表示したいか？
今回は商談なので商談オブジェクトのAPI参照名「Opportunity」を記載します

②上記①のオブジェクトの何の項目を編集したいか？
今回は商談オブジェクトの金額項目および完了予定日を一括編集したいです。
なので項目のAPI参照名を
「Name,Amount,CloseDate」
と記載します。（Nameを入れる理由はレコード名が表示されたほうが編集対象レコードが分かりやすいためです）
つまり下記画像のような設定となります
![list3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/39dd4e0b-6289-a58d-cea3-45009cb74094.png)

注意点としては「API参照名が一文字でも異なればエラーになる」ことです。
なのでこの設定は慎重におこなってください。
とはいえ、API参照名を記載中は画面上でリアルタイムで反映されますので、誤りがあっても気づきやすいかと思います。

さて、設定が完了しましたらあとは通常のLightningレコードページの設定と同じ右上部の「保存」ボタンや「有効化」ボタンをクリックしてください。

以上で設定は完了です。では一括編集方法の手順をご説明します！

###手順1 鉛筆マークをクリック
取引先のLightningレコードページから鉛筆マークをクリックします
![手順１.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/8852fcde-55ea-8b1a-38e5-61fe8b5c096f.png)

###手順２　一括でレコード編集しSAVEボタンをクリック

下記のような画面になりますので一括編集をします。
編集する画面は項目により異なります。（例として日付項目だとカレンダー画面が表示されます）
一括編集後SAVEボタンをクリックします

![手順２.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/449d0c4d-22cd-c847-7e58-f271ab4b8c69.png)


いかがでしたでしょうか！
List Editorの設定方法は難しい部分はあなりなく、容易に設定可能です。
しかし、Salesforceがより入力しやすくなるかと思います！
MeCabを使って姓名の分かち書きを試してみる

# はじめに
[株式会社hokan](https://www.corp.hkn.jp/)にて代理店様の導入をお手伝いしています。既存のシステムからhokanへ大切なデータを移行することがメインのタスクとなっています。
その中で氏名が姓名や住所が一つのカラムとして連携されたりしてくるのでそれを分割するのが課題となることがあります。
今回は[MeCab](https://taku910.github.io/mecab/)を使って姓名の分かち書きを試してみたいと思います。

# MeCabのインストール
まずはMeCabと辞書をインストールします。

```
$ brew install mecab
$ brew install mecab-ipadic
```

# ひとまず何も考えずのそのまま分かち書きを試してみる
テストデータは[Faker](https://faker.readthedocs.io/en/master/)を使って10件程度で実験します。以下のようなファイルを作成しました。

```Ini:test.txt
佐々木さゆり
伊藤裕太
吉田花子
小林里佳
長谷川直人
池田知実
山崎英樹
加藤智也
吉田加奈
三浦智也
```

早速実行してみます。

```
$ mecab -O wakati test.txt > output.txt
```

その結果です。これだけでもそれっぽい結果が返ってきますが、もう少し精度を上げたい。

```Ini:output.txt
佐々木 さゆり
伊藤 裕 太
吉田 花子
小林 里佳
長谷川 直人
池田 知 実
山崎 英樹
加藤 智也
吉田 加奈
三浦 智也
```

# 人名辞書を作成して使ってみる
人名の辞書を作成してそれを使って実行を試してみます。
人名の元データは下記から適当にダウンロードして使わせてもらいました。

* [http://www.mwsoft.jp/programming/munou/ime_dictionary_link.html#person](http://www.mwsoft.jp/programming/munou/ime_dictionary_link.html#person)

辞書を作成するにあたり、まずは下記フォーマットのCSVに変換します。

```
表層形,左文脈ID,右文脈ID,コスト,品詞,品詞細分類1,品詞細分類2,品詞細分3,活用形,活用型,原形,読み,発音
佐々木,,,８５00,名詞,固有名詞,人名,名,*,*,ささき,ササキ,ササキ
```

表層形は対象の単語そのものです。コストが比較的重要な気がしました。コストは低い方が基本的には優先されるようですので、今回は適当に「10000 - 単語の文字数 * 500」とかで設定しました。うまくいかない場合はこの辺りを調整すると良いのかもしれません。
次に下記のコマンドでCSVを辞書に変換します。jinmei_dict.csvをoriginal.dicに変換をかけています。パスについてはそれぞれの環境に合わせて修正してください。

```
$ /usr/local/Cellar/mecab/0.996/libexec/mecab/mecab-dict-index -d /usr/local/lib/mecab/dic/ipadic -u original.dic -f utf-8 -t utf-8 jinmei_dict.csv
```

そして作成された辞書を/usr/local/lib/mecab/dic/originalを作成し、そこにコピーする。

```
$ cp original.dic /usr/local/lib/mecab/dic/original
```

最後に/usr/local/etc/mecabrcに以下の一文を追加する。

```
userdic = /usr/local/lib/mecab/dic/original/original.dic
```

作成した辞書を使って再度分かち書きを実行してみます。

```
$ mecab -u /usr/local/lib/mecab/dic/original/original.dic -O wakati test.csv > output2.csv
```

```Ini:output2.csv
佐々木 さゆり  
伊藤 裕太  
吉田 花子  
小林 里佳 
長谷川 直人  
池田 知実  
山崎 英樹  
加藤 智也  
吉田 加奈 
三浦 智也
```

想定通りの結果が出ました！

# 最後に
テストデータを10,000件ほどに増やして実行してみましたが、まだまだ完璧と言うわけでありませんでした。ただ、これまでの手順で辞書を更新していけば精度は上がってくることがわかりました。
こんな感じで住所なんかも都道府県、市区郡、町村とかにうまく分割できそうですね。
たった1日で基本が身につく!Docker/kubernetes超入門2章のAnsibleの設定ファイルについて

# はじめに
「たった1日で基本が身に付く! Docker/Kubernetes超入門」を勉強しているのですが、色々と説明不足な個所がありつまづいたため記事を書きました。

この本超入門という割には本当に初心者にできるのというくらいに内容の一部が省略されていますので、この記事で挫折しない人が1人でもいればよいなと思います。

今回はAnsibleの設定ファイルをどのように作成した仮想環境の上に用意するかということです。

# 問題

Hyper-Vを利用してdockerの環境を3つ作ったあとansibleをインストールしました。
そのあと以下のコマンドが再現できずに困りました。

```
# ls
id_rsa id_rsa.pub pb_centos7.yml ssh_config
```


なぜ、いきなりファイルが仮想環境にあるのでしょうか。
いままでホストのファイルを仮想環境にコピーしたり、ファイル共有をする操作はありませんでした。

また、Hyper-Vのファイル共有も調べましたが、いまいちよくわからずどうしてよいかと困りました。

# 解決方法

ファイル共有するまでに調べたり試したりで時間がかかりそうだったので以下で対応しました。

ダウンロードを仮想環境内で行いました。

```
$ yum install wget
$ wget https://gihyo.jp/assets/files/book/2020/978-4-297-11428-2/download/sample_code.zip
$ unzip sample_code.zip
$ cd sample_code/chap2/ansible/dockerhost/
$ ls
```

# おわりに

1日でできるシリーズですが、すでに10時間以上をかけてしまっています。
ある程度Dockerはやっているつもりでしたが、こんなに時間がかかるとは。。。

再度勉強したときに同じところでつまづかないように解決したことは今後もまとめていきます。
Docker Desktop for Windowsで/var/lib/docker/containers/コンテナIDの場所を特定する

# はじめに

「たった1日で基本が身に付く! Docker/Kubernetes超入門」という本を勉強していたところ、書籍ではHyper-vで作成したCentos環境で説明していたところを、Docker Desktopでやっていて書籍通りに行うことができかなったため記事にしました。

やりたいことはコンテナから出力されたログを`cat`で確認することです。

# 問題

標準入力/標準エラーのログを直接確認するため、以下の手順で確認を行おうとしました。

```
$ docker container inspect <コンテナ名>
```

`LOGPATH`を参照して、アクセスログの場所を特定します。
そこにcdで移動して、ログの内容を確認します。

```
$ cd /var/lib/docker/containers/<コンテナID>/
$ cat <コンテナID>-json.log
```

ここで以下のようなエラーがでて移動でエラーになりました。
(ファイルがないので当然です)

![bandicam 2021-08-08 17-40-08-394.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/810513/25e68a72-2200-3d46-bd2c-05d00097ea93.jpeg)

# 解決方法

では、書籍で行われているこの動作はどのように再現できるのでしょうか。
Docker DesktopではWSLが利用されており、ローカルのフォルダにマウントされています。
ですので、WSLと対応しているローカルフォルダにまず移動する必要があります。

場所は以下になります。

```
# cd /var/libに対応
$ cd \\wsl$\docker-desktop-data\version-pack-data\community\
$ cd /docker/containers/<コンテナID>
$ cat <コンテナID>-json.log
```

こちらで書籍どおりのログの確認ができるようになりました。

# おわりに

書籍がHyper-Vで作成した環境でDockerを動かしていますが、私はDocker Desktopを使って同じことをしていたため、やはり違う箇所ができてます。色々書籍通りにいかないことが多く、1日で終わる本をかなり長い時間かけて勉強しています。やはりインフラ系は普段やらないため難しいです。
Linux: パスからファイル名、ディレクトリ名、親ディレクトリパスを切り出す方法

たまに必要となるのでメモ。

###### 実施環境：

```Linux:Linux
[testuser@testhost ~]$ uname -a
Linux testhost 4.18.0-147.8.1.el8_1.x86_64 #1 SMP Thu Apr 9 13:49:54 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
[testuser@testhost ~]$ echo $SHELL
/bin/bash
```

ファイルやディレクトリのパスから、ファイル名のみやディレクトリ名のみ、あるいは親ディレクトリのパスのみを切り出したい場合があります。
そのような時に使用するのが、basenameコマンドとdirnameコマンドです。

ファイル名、ディレクトリ名のみを切り出す場合はbasenameコマンドを使用します。
拡張子を同時に指定することで、ファイル名から拡張子を除外した文字列も取得可能です。
ルートディレクトリを指定した場合は、ルートディレクトリが表示されます。

```Linux:Linux
[testuser@testhost ~]$ basename /var/log/boot.log
boot.log
[testuser@testhost ~]$ basename var/log/boot.log
boot.log
[testuser@testhost ~]$ basename boot.log
boot.log
[testuser@testhost ~]$ basename /var/log/boot.log .log
boot
[testuser@testhost ~]$ basename /var/log
log
[testuser@testhost ~]$ basename /var/log/
log
[testuser@testhost ~]$ basename /
/
```

親ディレクトリ部分を切り出す場合はdirnameコマンドを使用します。
こちらもルートディレクトリを指定した場合、ルートディレクトリが表示されます。
また、ファイル名、ディレクトリ名のみを指定した場合はカレントディレクトリを表す.が表示されます。

```Linux:Linux
[testuser@testhost ~]$ dirname /var/log/boot.log
/var/log
[testuser@testhost ~]$ dirname var/log/boot.log
var/log
[testuser@testhost ~]$ dirname boot.log
.
[testuser@testhost ~]$ dirname /var/log
/var
[testuser@testhost ~]$ dirname /var/log/
/var
[testuser@testhost ~]$ dirname /var
/
[testuser@testhost ~]$ dirname /
/
```

無論、これらのコマンドを使用せず、/を区切り文字として地道に切り分けて取得することも可能です。

```Linux:Linux
[testuser@testhost ~]$ echo "/var/log/boot.log" | awk -F/ '{print $NF}'
boot.log
```
System.Text.Jsonでお行儀の悪いJsonを読み込む

Stringとして定義されている項目に数字が引用符無しで入ってたり (Number扱いで死ぬ)
Arrayとして定義されているのに値が1つだけの場合にObjectで返ってきたり (当然型違いで死ぬ)
するJsonを読み込みたい、でもConverterこさえるのも面倒、ってな時に。

やってること自体は一度JsonElementで受けてプロパティ呼ぶ時に変換するだけという単純なもの。

```json:読み込みたいJson
{
    "item1": "item"
}
{
    "item1": 100
}
```

```cs:Json定義
public class JsonData
{
    [JsonPropertyName("item1")]
    public JsonElement? Item1Value { get; set; }

    string item1; // 一度読んだ値は保持しておく
    [JsonIgnore]
    public string Item1
    {
        get
        {
            if (item1 != null) return item1;
            if (!Item1Value.HasValue) return null; // null値の場合はGet~すると死ぬのでここで返す
            // 任意の変換処理
            return item1 = Item1Value.Value.ValueKind switch
            {
                JsonValueKind.String => Item1Value.Value.GetString(),
                JsonValueKind.Number=> Item1Value.Value.GetInt32().ToString(),
                // object,arrayのコード例
                // JsonValueKind.Object => new[] {  JsonSerializer.Deserialize<HogeHoge>(ItemValue.Value.GetRawText()) },
                // JsonValueKind.Array => JsonSerializer.Deserialize<HogeHoge[]>(ItemValue.Value.GetRawText()),
                _ => throw new NotSupportedException()
            }
        }
    }
}

```

```cs:デシリアライズ
public void Deserialize()
{
    var text = (Json読み込み);
    var json = JsonSerializer.Deserialize<JsonData>(text);
}
```

~~とりあえずstringにしたいだけならNewtonsoft.Json使ってしまう方が早い気がする。~~

参照: [JsonValueKind 列挙型](https://docs.microsoft.com/ja-jp/dotnet/api/system.text.json.jsonvaluekind?view=net-5.0)
LPIC303体験記

普段からQiitaにお世話になっているくせに、どう書いて良いかわからないままここまできましたが、練習がてらやっと初投稿してみます。これからがんばります（多分）。

## 受ける理由

お家騒動（LinuCとの分裂）とか、今までならエンジニアが手を出していた部分がクラウド化の中でマネージドサービスとし取り揃えられるようになったとか、受ける価値が微妙になりつつあるのを感じながらも、メインフレーム畑から逃れるきっかけになった資格でもあることから、一番上も受けようと。
ちなみにレベル1、レベル2は2018年に取得してて、だいぶご無沙汰。

## 300？303？304？

当初、普段からdocker使ってるしね、と304を受けようと思ってたけど、たまたま業務でAD触ったこともあり、今の時代、セキュリティやって損はないか、と303に変更。

## 期間と勉強方法

- 3ヶ月くらい
- まず、手を動かしながら黒本を一巡
- 受験まで1ヶ月のタイミングで、ping-tに取り掛かる
- やり初めは黒本の内容が全然思い出せなくて半分も正解できず
- 仕事や子供の相手の隙間で問題を繰り返すことに
- 結局暗記に終始したことを恨みつつ試験日を迎える

## 結果

- 合格
- 700点（合格ライン：500点）


## 感想

レベル1、レベル2で多少やったはずのBINDとかiptablesは全然忘れてるし、結局暗記大会になったしで、受験から1週間経っただけで、もう取れる気しません...四十路の記憶力恐るべし。
受験と通して感じたのは、問題を難しくするために仕方ないのかもしれないけど、細かい、かつ間違えやすいオプションを問う問題が目立つ印象。勉強しながら、「実務直結にはならんなぁ」と感じた次第。
多分、303と300をまとめてやると、仕事に活きそうだなと思ったり。
とは言え、AD関係（303の場合、ADというよりFreeIPAだが）は苦手だったので勉強する良い機会になった。

## 今後

2018年にレベル1、レベル2を取った関係で、おまけのLinuC1、2も持っているのだが、さすがに受けないかな。。気が変わったら300やってみるかも。
それより業務で受けろと言われているAWS SAPを受けねば。。。
Z3Py　例題　エイト・クイーン問題

# 問題
8×8 のボード上に，8つのチェスのクイーンのコマを置く．
8つのクイーンが互いに取られないように配置することはできるか?
([エイト・クイーン](https://ja.wikipedia.org/wiki/%E3%82%A8%E3%82%A4%E3%83%88%E3%83%BB%E3%82%AF%E3%82%A4%E3%83%BC%E3%83%B3))

# 回答
```example_8_Queen.py
from z3 import *

X = [[Int("x_%s_%s" % (i, j)) for j in range(8)]for i in range(8)]

s = Solver()
s.add([And(0 <= X[i][j], X[i][j] <= 1) for i in range(8) for j in range(8)])
s.add([Sum([X[i][j]for i in range(8)]) == 1 for j in range(8)])
s.add([Sum([X[i][j]for j in range(8)]) == 1 for i in range(8)])
for a in range(-6, 7):
    diag = []
    for i in range(8):
        if (0 <= i+a) & (i+a <= 7):
            diag.append(X[i+a][i])
    s.add(Sum(diag) <= 1)

for a in range(-6, 7):
    diag = []
    for i in range(8):
        if (0 <= i+a) & (i+a <= 7):
            diag.append(X[i+a][7-i])
    s.add(Sum(diag) <= 1)

print(s.check())
m = s.model()
for i in range(8):
    tmp = []
    for j in range(8):
        tmp.append(m[X[i][j]])
    print(tmp)
```
出力

```terminal
sat
[0, 0, 0, 0, 0, 1, 0, 0]
[0, 0, 0, 1, 0, 0, 0, 0]
[0, 1, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 1]
[0, 0, 0, 0, 1, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 1, 0]
[1, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 1, 0, 0, 0, 0, 0]
```

## 解説


# 他の例題
[Z3Py個人的ポータル](https://qiita.com/Ganesha/items/7a606ffc8a7c2504c143) へ
ProxmoxでElasticsearch7.3.2をクローンして使う

単純にクローンして使えなったのでメモ

# host名の変更
クローン直後ではIPが被ったりしているので、ネットワークに接続しない状態で立ち上げてIPやらホスト名などを変更する。
ホスト名だけでは足りない場合は、/etc/elasticsearch/elasticsearch.ymlのnode.name:を変更する
discovery.seed_hostsなど記入はしなくてよい。
心配なら記入しておく。
master_nodesのクローンでmaster_nodesにしたいなら書いといたほうがいい。

# データ削除
Elasticsearchのデータにサーバなどの情報が格納されていて、対象のクラスタに拒否されるのでデータを消す。

``` sh
cd /var/lib/elasticsearch
rm -fr *
```

# 起動
起動すればOK
[Blender 2.9] ウェイトペイントモードでボーンが選択できないとき

#ボーンではなく面や頂点が選択されてしまう
![img.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/953829/074595de-f25c-2c22-e4f8-5a2c040656e7.png)
このようにどちらの選択も外して
`Ctrl + 左クリック`
`Cmd + 左クリック`
しましょう。
RealSense D455(librealsense2)使ってみた -基礎編-

# お詫び
:::note alert
記事が分散して見つけづらくなっていたので以下に移動しました．
ご了承ください :bow:
:::

https://zenn.dev/yosse95ai/books/6fea5a9a44dfaf/viewer/84ac04

シリーズをすべて一冊の本としてまとめたので，見やすくなりました．
TerraformでAmazon Auroraクラスタを自動構築する(クライアント接続用ユーザ作成編)

# はじめに
Amazon Aurora記事第3弾。

今回は作成したAuroraクラスタにIAMポリシーを作成し、ポリシーベースで認証を行う。
MySQL/PostgreSQLのユーザID/パスワードを使わない、よりセキュアなアクセス方法だ。

今回の記事も第2弾同様、前回記事で作ったTerraformのHCLに付け加える前提であるため、実際に触ってみる場合はまずは前回・前々回記事から読んでいただきたい。

- [TerraformでAmazon Auroraクラスタを自動構築する(基本編)](https://qiita.com/neruneruo/items/a7c5f7fa80fbf9d6a828)
- [TerraformでAmazon Auroraクラスタを自動構築する(RDSプロキシ編)](https://qiita.com/neruneruo/items/db137bd15cf1af6decdc)

なお、今回参考にしたのは[公式のユーザガイド](https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/AuroraUserGuide/UsingWithRDS.IAMDBAuth.html)なので、先に目を通しておくと良い。

# MySQLユーザの作成
AuroraのIAM認証では、IAMポリシーとDBMSのユーザを紐づける。
まずはMySQLのユーザを作成しておこう。
今回はリーダインスタンスに接続する前提のユーザであるため、```GRANT```には```SELECT```のみ指定しているが、必要に応じて変更しよう。

```SQL
CREATE USER app_user IDENTIFIED WITH AWSAuthenticationPlugin AS 'RDS'; 
GRANT SELECT ON COMPANY.* TO app_user;
```

Terraformでまとめてユーザを作りたい場合は、第1回の記事のaurora_create_db.sqlに追記をする。

# IAMポリシー
上記で作ったユーザについて、以下のIAMポリシーを作成する。
これを、ローカル接続する場合は接続するIAMユーザー、ECS等のAWSリソースに設定する場合は、各サービスの信頼関係ポリシーを持ったロールにアタッチすれば良い。

```HCL
resource "aws_iam_policy" "aurora_authentication" {
  name   = local.iam_aurora_authentication_policy_name
  policy = data.aws_iam_policy_document.aurora_authentication.json
}

data "aws_iam_policy_document" "aurora_authentication" {
  statement {
    effect = "Allow"

    actions = [
      "rds-db:connect",
    ]

    resources = [
      "arn:aws:rds-db:${data.aws_region.current.name}:${data.aws_caller_identity.self.account_id}:dbuser:${aws_rds_cluster.example.cluster_resource_id}/app_user",
    ]
  }
}
```

# その他注意すること
アプリケーションから各種SDKのBuildAuthTokenのAPIを使って接続する場合、[公式のユーザーガイド](https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/AuroraUserGuide/UsingWithRDS.SSL.html)に記載された証明書をインポートしておく必要がある。

例えば、DockerでGolangのSDKで接続をする場合、以下のようにDockerfileでビルド時に証明書をダウンロードする。

```Dockerfile
RUN mkdir /usr/local/share/ca-certificates
RUN wget https://truststore.pki.rds.amazonaws.com/ap-northeast-1/ap-northeast-1-bundle.pem -P /usr/local/share/ca-certificates
RUN apk add --no-cache ca-certificates && \ 
    update-ca-certificates
```

これで、セキュアなで冪等性の高い認証方法でAuroraへのアクセスができるようになった！
[Ruby] AtCoder 過去問　B - 200th ABC-200

##はじめに
AtCoderのB問題 200th ABC-200を解いてみました。
他のやり方やもっと容量の良いやり方などあれば教えてください！

問題はこちらからご確認ください！

https://atcoder.jp/contests/abc200/tasks/abc200_b

それではよろしくお願いします。

##B - 200th ABC-200

まず入力の受け取りです。

```ruby
n, k = gets.split(' ').map(&:to_i)
```

まず、問題文にそって条件分岐をしていきます。
Nが200で割り切れたら(200の倍数であれば)、200で割ってNに代入します。

```ruby
n, k = gets.split(' ').map(&:to_i)

if n % 200 == 0
  n /= 200
```

続いて割り切れなかった場合、Nの後ろに200を付け足して、Nに代入します。
ここで注意したいのは、これは数値の計算ではないということです。ただ単にNの後ろにNを付け足すだけです。
例えばNが1だったら1200になるのです。

要するにこれは文字列の足し算と考えられます。
ですので、200の倍数でなかった時の処理では、まずはじめにNを文字列に変換します。
```n = n.to_s```

そしてNに文字列の200を足します。
```n += "200"```

そして最後に数値に戻してやります。
```n = n.to_i```

これでif文の完成です。

```ruby
n, k = gets.split(' ').map(&:to_i)

if n % 200 == 0
  n /= 200
else
  n = n.to_s
  n += "200"
  n = n.to_i
end 
```


この処理をK回繰り返すのでtimesメソッドを使って繰り返します。


```ruby
n, k = gets.split(' ').map(&:to_i)

k.times do
  if n % 200 == 0
    n /= 200
  else
    n = n.to_s
    n += "200"
    n = n.to_i
  end
end
puts n
```
docx2pdfでdocxをpdfにコマンドラインで変換

Windows環境でdocxをコマンドラインでまとめてpdfに変換する方法はいくつかあるようですが、docx2pdfというツールを見つけたのでメモ。

前提条件：
- Microsoft Wordがインストールされている（Word 2016を使用）
- Python がインストールされている（3.9.6を使用）

開発サイト（GitHub）： [https://github.com/AlJohri/docx2pdf](https://github.com/AlJohri/docx2pdf)

インストール：pipを使用して入れる。
```> pip install docx2pdf```

実行：docxのあるフォルダ（例：docx）を指定するとその中のファイルが変換される。
```> docx2pdf docx```

さっくりメモ。
console.logを一括削除するコマンドを作ってみた

# コマンド
### バックアップを作成し、console系関数が記述された行を削除

```
find . -name "*.js" -type f -exec perl -ni.rbak -e 'print if !/console.*/' {} \;
```

### バックアップファイルを削除

```
find . -name "*.rbak" -type f -exec rm -f {} \;
```

# 注意
このままターミナルに入力すると、現在の階層以下に存在する全てのJavaScriptファイルに対して"console."の記述がある行が削除されます。特定のファイルにのみ適用したい場合は、-nameオプションに正しくファイル名を指定して下さい。

また、仕組みは単純なコマンドですが、暇つぶしで作ったものなので、正しく動作しない恐れもあります。必ず差分を確認しながら実行するようにして下さい。

最後に、Perlという言語の正規表現を使っております。大抵のPCには最初からインストールされていると思いますが、もしない場合はこちらをインストールしてから実行して下さい。

## 開発経緯
JavaScriptのデバッグ方法は凄まじく種類がありますが、VSCode等でユーザースニペットを充実させていけば、一番使いやすいのはconsole系の関数だと思うのです。ブレークポイントは仕込むと毎回処理が止まる上に値がとても見づらいので、ちょっと使いづらいというのが個人的な意見です。

しかしconsole系関数のデメリットは、色んな場所に差し込みまくると、後で消すのが面倒なことにあります…。そして意外にも、こういうconsole系関数を一括で削除する方法がなかなか見つかりませんでした。そこで今回は、JavaScriptファイルに対して拡張子"rbak"のバックアップファイルを作成した後、"console."の記述がある行を一括で削除するコマンドを作ってみました。

参考資料は以下の通りになります。Linuxコマンドは基本的なものしか使っておらず、Perlに関しては興味がある人は少ないと思うので、ここでの説明は割愛します。

https://hole.sugutsukaeru.jp/archives/21

https://qiita.com/ohtsuka1317/items/92c339a65533e1e6c6fc
Windowsでdockerを使用する

WindowsでDockerを動かす場合、別途アプリケーションのインストールが必要です。
LinuxやMacの場合はCLIにてDocker Engineをインストールすれば使用できますが、Windowsの場合はDocker Desktopというアプリケーションをインストールします。

#システム要件
[公式](https://docs.docker.jp/docker-for-windows/install.html)の文献を確認しますと、以下の要件を満たしている必要があるようです。

```
OS:Windows10 64bit ※pro版以上を要求していますが、有志の方の情報によりhomeでもインストール出来たようです
有効が必要な機能:Hyper-V , Windowsコンテナ機能
CPU:64bit Second Level Address Translation対応プロセッサ
RAM:4GB～
その他:BIOSにてハードウェア仮想化の有効化の設定が必要
```

#インストール
Docker Desktopは以下からダウンロードできます。
[Docker-Desktop](https://www.docker.com/products/docker-desktop)

インストール自体は簡単で、「OK」または「NEXT」で進んでいけばOKです。
以下の画面が表示されたらインストール完了で、「Close and restart」をクリックしますとWindowsが再起動されます。
ボタンクリックした瞬間に再起動されますので、作業途中のタスクがありましたら必ず保存してからクリックしてください。
![dd01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/858317/da839987-e7f2-9a16-dcb1-29abac6a779f.png)
Windowsを再起動しますと、以下のような画面が表示されます。
ここでは「Restart」や「Cancel」をクリックせずに、ウィンドウ内にあるURLをクリックします。
URL:https://aka.ms/wsl2kernel
![dd02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/858317/8e3ac187-e90f-c4d4-1b7b-80d1ceb4dc74.png)
リンク先にある更新パッケージをダウンロードし、インストールします。
特にWindowsの再起動は必要ありませんので、インストール完了後は上記ウィンドウに戻り、「Restart」をクリックします。
以下のような画面が表示されたらDocker Desctopのインストールは完了です。
![dd03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/858317/79056a84-c5d5-b2b7-d5ec-20b1a0c784ff.png)
Docker DesktopにはDocker Engineだけではなく、Kubernetesもインストールされるようです。
Kubernetesについては近いうちに少しずつ学習していく予定なので、以降触れてみたいと思います。
今回は以上です。
MySQL とマイグレーションファイル

##マイグレーションの実行状況を確かめる
```
$rails db:migrate:status
```
statusがup=マイグレーションが正常に実行された
##rails db:resetとrails db:migrate:reset
###マイグレーションファイルを編集しても、その内容は反映されない。
スキーマファイルだけを利用する

```
$rails db:reset
```
マイグレーションファイルを直接利用する

```
$rails db:migrate:reset
```
一つ前まで戻す

```
$rails db:rollback
```
現在よりx個前までなかったことにしてくれる

```
$rails db:rollback STEP=x
```

##mysqlのエラー
エラーメッセージ

```
MySQL2::Error Table `users` already exists
```
解決方法
usersテーブルが存在しているのでマイグレートが実行できない
ので既に存在するusersテーブルを削除し、再びマイグレート
##解決手順1.usersテーブルの確認
```
$rails db:
mysql>SHOW TABLES;
```
##解決手順2.usersテーブルを削除
```
mysql>drop table users;
```
Arduino UNOで脈拍センサー,AE-NJL5501Rので赤外線の脈拍を見る(IR)


目的
気が向いたから
赤外線の成功例が私の知る限りないのでやってみた

結果
感度が悪すぎてたまたまかどうかすらわからない
なんか変
グラフから4カウント分の波高しかない

1.センサーの接続
2.下記のソースコードを書き込む
3.コンパイル実行で表示されたら終了
4.Arduinoプロッターで開く
5.おわり

秋月のセンサー
ＮＪＬ５５０１Ｒ搭載　パルスオキシメータ用・反射型センサ　ＤＩＰ化モジュールキット
[AE-NJL5501R]
通販コード　K-09433
発売日　2015/07/01
メーカーカテゴリ　株式会社秋月電子通商

delay(1); -> delay(10);へ変更した。

秋月の脈拍センサー,AE-NJL5501Rで脈拍を見る NJL5501R
https://qiita.com/caa45040/items/f3a5674e825c9ac542fb


安静時に普通に測定

![njl5501_ir_s1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/d34aa607-1afb-4f2c-2c8c-ac8e2e005367.jpeg)

息を止めてみた　感度が悪すぎでダメ例　本来なら正常時と微妙差

![njl5501_ir_t1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/4348ee20-da50-0e64-e36f-55367038e63b.jpeg)


参考　mcp3425 16bit adc で　ダイレクト　20ms毎
max 2048000uV 28400-> 28.400mV 揺れ幅は、約800uV
この参照では、98と96を見分けるのは、難しいのか

![njl5501_ir_mcp1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/f799373c-ae47-a190-8950-c57a62c93b8b.jpeg)



```c++


/*
  AnalogReadSerial

  Reads an analog input on pin 0, prints the result to the Serial Monitor.
  Graphical representation is available using Serial Plotter (Tools > Serial Plotter menu).
  Attach the center pin of a potentiometer to pin A0, and the outside pins to +5V and ground.

  This example code is in the public domain.

  http://www.arduino.cc/en/Tutorial/AnalogReadSerial
*/

// the setup routine runs once when you press reset:
void setup() {
  // initialize serial communication at 9600 bits per second:
  Serial.begin(9600);
}

// the loop routine runs over and over again forever:
void loop() {
  // read the input on analog pin 0:
  int sensorValue = analogRead(A0);
  // print out the value you read:
  Serial.println(sensorValue);
  //delay(1);        // delay in between reads for stability
  delay(10);

}



```
GitHub 備忘禄

## ブランチ作成
ブランチは基本的にレポジトリのコピーで、元のファイルを触らずに新しいコードを書くなど、自由に変更や実験を試すことができる。
通常、親レポジトリは`master`ブランチと呼ばれ、トピックブランチ（短期間だけ使う一時的なブランチ）は`checkout`と`-b`フラグを使って作成する

```bash
git checkout -b modify-master
#Switched to a new branch 'modify-README
git branch
#  master
# *modify-README
```

リモートブランチをローカルにcheckoutする場合は下記コマンド

```bash
git branch -c {local_branch_name} {origin/remote/branch_name}
```

### 注意事項

下記のようなエラーがでた場合は、リモートリポジトリの最新情報がローカルに反映されていないために起きるエラーです。

`fatal: 'origin/feature/REHASAKU-231_base' is not a commit and a branch 'feature/REHASAKU-231_base' cannot be created from it`

以下コマンドで、リモートリポジトリから最新情報を取得し、再度リモートブランチをローカルにチェックアウトしてやればOKです。--pruneオプションをつけてやることで、すでにリモートリポジトリに存在しないブランチをローカルから削除してくれます。

```
# リモートブランチから最新情報を取得する
$ git fetch --prune
```

## マージ
トピックブランチの変更を切り元のブランチにマージする

```bash
# 元のブランチに切り替える
git checkout master
# 変更をマージする
git merge modify-README
# 変更をマージした後にトピックブランチを削除する
git branch -d modify-README
```

`-D`オプションを指定した場合は、変更をマージしていなくてもブランチを削除してくれる
ブランチでミスをした場合にトピックブランチ上の変更を破棄する場合に使用する

## 作業をもとに戻す
コミットする前に作業内容を前回のコミット時の内容に戻すときに使うコマンド
`-f`は強制的に上書きして元に戻すためのフラグ

```bash
git checkout -f
```
MySQL  CSVやTSVファイルからインポートする方法

## BULK INSERTが使えない。
SQL Serverで普通に使っていたBULK INSERTは使えない。

```
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that 
corresponds to your MySQL server version for the right syntax to use near 
'BULK INSERT `Sample`
```

##LOAD DATA INFILE 構文を使う
https://dev.mysql.com/doc/refman/5.6/ja/load-data.html

```
LOAD DATA LOCAL 
INFILE 'C:\\ProgramData\\MySQL\\MySQL Server 8.0\\Uploads\\ファイル名.tsv' 
INTO TABLE `テーブル名`
FIELDS TERMINATED BY '\t'
LINES TERMINATED BY '\r\n'
IGNORE 1 LINES;
```

【ポイント】
・ファイルの格納場所は隠しフォルダになっているので、設置する際は見えるようにする
・クライアント側とサーバー側の「--local_infile」を「1（ON）」にする。（本記事後述）
→MySQL8.0からの仕様で、設定しないと、ERROR 3948 (42000)が発生する。

・ファイル拡張子は何でもOK！！
・条件指定は「`」バックではなく「'」シングルクオートを利用すること。
→ERROR 1064 (42000)が発生する

・'\t'は正規表現のタブを表す
・'\r\n'はWindowsの改行コード
・IGNORE 1 LINES; は1行目無視の意味。(今回１行目がフィールドの為)

https://www.infoscoop.org/blogjp/2014/07/23/about-load-data-infile/


##--local_infileの設定
###①クライアント側
ログイン時に「--local_infile=1」を指定。

```:sql
-u root -p --local_infile=1
```

###②サーバー側
ログイン後に「--local_infile=1」を指定。

```:sql
-- 設定の確認（初期値：0）
SELECT @@local_infile;

-- 設定変更
SET PERSIST local_infile= 1;
```

https://qiita.com/yes_dog/items/57c1a8c03aff8bb177de


##実行結果 サンプル
```:sql
mysql> select * from game;
+---------+----------------------------------------------+--------+--------------------------+------------+-------------+
| ranking | title                                        | model  | maker                    | sales_2021 | sales_total |
+---------+----------------------------------------------+--------+--------------------------+------------+-------------+
|       1 | モンスターハンターライズ                     | Switch | カプコン                 |          2 |           2 |
|       2 | 桃太郎電鉄 ?昭和 平成 令和も定番！?          | Switch | KONAMI                   |          1 |           2 |
|       3 | スーパーマリオ 3Dワールド                    | Switch | 任天堂                   |        820 |         820 |
|       4 | リングフィットアドベンチャー                 | Switch | 任天堂                   |        623 |           2 |
|       5 | マリオカート8 デラックス                     | Switch | 任天堂                   |        475 |           3 |
|       6 | あつまれ どうぶつの森                        | Switch | 任天堂                   |        454 |           6 |
|       7 | Minecraft                                    | Switch | 日本マイクロソフト       |        370 |           2 |
|       8 | 大乱闘スマッシュブラザーズ SPECIAL           | Switch | 任天堂                   |        336 |           4 |
|       9 | 牧場物語 オリーブタウンと希望の大地          | Switch | マーベラス               |        281 |         281 |
|      10 | New ポケモンスナップ                         | Switch | ポケモン                 |        259 |         259 |
```
Proxmoxで使用済みディスクを完全初期化する方法

Proxmox7.0からGUIでディスクを初期化できるようになりましたが、アンマウントとインベントリ削除はコマンドが必要です。（右のツリーに残ってしまう）

```
df
umount /dev/nvme0n1p1
nano /etc/pve/storage.cfg
```
で該当のインベントリ情報を削除すると完全に消えます。
Apacheを使用したリバースプロキシでのHttpヘッダ・インジェクション予防メモ

※Apacheやセキュリティについてそこまで詳しくないため、参考程度でよろしくおねがいします。

#Httpヘッダ・インジェクション
[HTTPヘッダ・インジェクション](https://ja.wikipedia.org/wiki/HTTP%E3%83%98%E3%83%83%E3%83%80%E3%83%BB%E3%82%A4%E3%83%B3%E3%82%B8%E3%82%A7%E3%82%AF%E3%82%B7%E3%83%A7%E3%83%B3)
> 動的にHTTPヘッダを生成する機能の不備を突いてヘッダ行を挿入することで不正な動作を行なわせる攻撃手法のこと。また、その攻撃を可能とする脆弱性のこと。


#前提
以下のような構成でシステムを構築している場合にApacheの設定を追加することでアプリケーションを改修せずに予防した。
クライアント - Apache(リバースプロキシ) - Webサーバ

ヘッダーを改変することで予期しないURLへ遷移させることができる状態だった。
リダイレクトされるURLへのアクセス時にHostを書き換えることで想定外のURLへリダイレクトさせることができる状態だった。

#事象と対応内容

Hostを書き換えていない状態だと想定するURLがヘッダーのLocationに記載されているが、
以下のようにHostヘッダーに改ざん先URLを指定すると変更されていた。(-Lを追加するとリダイレクトまで実行されます。)

```
curl -v -H "Host: 改ざんURL" "リダイレクトするURL"
```

Apacheの場合を以下の設定1つを追加することで、一先ず事象抑制できた。

```apache:追加設定
UseCanonicalName On
```

> UseCanonicalName On の場合は、ServerName ディレクティブで指定されている ホスト名とポート番号を使って、その正規名 (自己参照の名前) を生成します。

UseCanonicalName ディレクティブ
http://httpd.apache.org/docs/2.2/ja/mod/core.html#usecanonicalname

ServerNameディレクティブでホスト名を設定することでホスト名を固定できるため、ホスト名改ざんを予防しています。

#その他調べる過程で読んだ参考になった記事とか
Apache httpd 2.4 を CentOS 7 に yum でインストールする手順
https://weblabo.oscasierra.net/apache-installing-apache24-yum-centos7-1/

攻撃を受ける前に見直すApacheの基本的なセキュリティ10のポイント
https://www.rem-system.com/apache-security01/

ディレクティブ一覧
https://httpd.apache.org/docs/2.4/ja/mod/directives.html

mod_proxy再入門 – ProxyPassとProxyPassReverse
https://dev.classmethod.jp/server-side/server/introduction_mod_proxy/

ProxyPass ディレクティブ
http://httpd.apache.org/docs/2.4/ja/mod/mod_proxy.html#proxypass

ProxyPassReverse ディレクティブ
http://httpd.apache.org/docs/2.4/ja/mod/mod_proxy.html#proxypassreverse

リバースプロキシ（Reverse Proxy）
https://www.atmarkit.co.jp/ait/articles/1608/25/news034.html
Paizaとかで使える長さが可変の文字列から数値を取得する関数の実装

# PaizaでC言語使ってて困ること
みなさんこんにちは。
Paizaなんかではよくデータの長さを標準入力で与えられて,
それにもとづいてデータ列が標準入力から
入ってくるなんてことがあります。
データの長さが不定なので,sscanfに引数を与えようにもいくつ用意したらいいかわからない。
そういうこともあると思います。

そこで本記事で紹介するような関数を実装しました。

# 実装した関数
``` c
#include <stdio.h>
#include <string.h>

void splitStringToInt(char* src,int* array,int num)
{
    int i = 0;
    char* head = src;
    char* tail;

    while (i < num){
        if ((tail = strstr(head," ")) != NULL){
            *tail = '\0';
            sscanf(head,"%d",&(array[i++]));
            head = tail + 1;
        }
        else {
            sscanf(head,"%d\n",&(array[i++]));
        }
    }
}
```

# 軽い解説
データ列は最後のデータ以外は空白で区切られているということで上記のような実装を行いました。
また配列のオーバーランを防ぐため念の為個数で管理するようにしています。
インクリメント演算子が後置になっているので,代入後にカウントアップすることにも注意してください。

# 追記（2021/08/09　14:24）

@fujitanozomuさんから次のような実装のほうがシンプルなのではとのご指摘がございましたので紹介いたします。

```c
void splitStringToInt(char* src,int* array,int num)
{
    for (int i = 0; i < num; i++) {
        char* token = strtok(src, " ");
        if (token == NULL || sscanf(token, "%d", &array[i]) != 1) {
            array[i] = /*error*/INT_MIN;
        }
        src = NULL;
    }
}
```

僭越ながら解説させていただきますと,Cの標準ライブラリにあるstrtok関数を用いて,区切り文字によって文字列をトークンに分割する処理を行うことで
私の実装で行っていた文字列のポインタ管理を,ライブラリに任せることができるようになっています。
その結果としてコードの信頼性が上がり,またシンプルになっていることが特徴です。
またwhile文をfor文に変更することでループがシンプルになっていることも特徴です。
上記2つの結果としてコードが短くなり,保守性が向上しています。

さらにもう一つのコードもご提案いただきましたので紹介いたします。

```c
int splitStringToInt(char* src, int* array, int num)
{
    int count = 0;
    for (int i = 0; i < num; i++) {
        char* token = strtok(src, " ");
        if (token != NULL && sscanf(token, "%d", &array[i]) == 1) {
            count++;
        } else {
            array[i] = /*error*/INT_MIN;
        }
        src = NULL;
    }
    return count;
}
```

こちらはトークンの個数を返り値として与えるようにさらに変更したものとなります。


@fujitanozomuさん,コメントで良い実装をご提案いただきありがとうございます。
【Laravel/Docker】Nginxの502エラー（upstream sent too big header ）

# 解決法

DockerのNginxコンテナの設定ファイル(nginx.conf)に以下記載。

```docker/nginx.conf
fastcgi_buffers 8 32K;
fastcgi_buffer_size 32k;
fastcgi_busy_buffers_size 64k;
```

コンテナを立ち上げ直す

```
$ docker-compose down
$ docker-compose up -d
```

これで直りました。

# 原因

**PHP側のFPM：Nginxではなく、PHP自体が停止の原因？**
大きなヘッダサイズの応答をする場合は、必要になるようです。

別の可能性もあるとは思いますが、上記のパターンで解決されている方が多いのではないかと思います。

# 参考

https://oxynotes.com/?p=12011

https://www.php.net/manual/ja/install.fpm.php
TypeScript + Node.jsで書くTwitterBotの作り方

# はじめに
おはようございます。こんにちは。こんばんは。
Watatakuです。
今回の内容はTypeScript + Node.jsで書くTwitterBotの作り方です。

この記事の対象者は以下のとおりです。

# 対象者

- 初学者
- モダン環境でTwitterBotが作りたいって方

#書かないこと

- TwitterAPIキーの取得方法

# プロジェクト作成
作業ディレクトリに行き、以下のコマンドを入力する。

```console
$ mkdir twitter-bot
$ cd twitter-bot
$ touch index.ts
$ npm init
```

## typescriptを使えるようにする

```console
$ npm install -D typescript
$ npm install -D @types/node
$ npx tsc --init

$ npm install -D ts-node
```

ts-nodeはjsのトランスパイルなしにtsコードを実行してくれます。
sc --initでtsconfig.jsonも生成しておきます。

## その他必要なモジュールのインストール

```console
$ npm install express
$ npm install -D @types/express

$ npm install twitter
$ npm install -D @types/twitter
```

# Twitter Botを作る

```ts:index.ts
import express from "express";
import Twitter from "twitter";
import {
  customerKey,
  customerSeacret,
  accsessTokenKey,
  accsessTokenSeacret,
} from "../seacretDirectory/seacret";

const app: express.Express = express();

app.use(express.json());
app.use(express.urlencoded({ extended: true }));

//CROS対応（というか完全無防備：本番環境ではだめ絶対）
app.use(
  (req: express.Request, res: express.Response, next: express.NextFunction) => {
    res.header("Access-Control-Allow-Origin", "*");
    res.header("Access-Control-Allow-Methods", "*");
    res.header("Access-Control-Allow-Headers", "*");
    next();
  }
);

// 型定義
type Message = {
  message: string;
};
type Params = {
  status: string;
};

const client: Twitter = new Twitter({
  consumer_key: customerKey(),
  consumer_secret: customerSeacret(),
  access_token_key: accsessTokenKey(),
  access_token_secret: accsessTokenSeacret(),
});

const message: Message = {
  message: "Bad Request",
};

//get
app.get("/api", (req: express.Request, res: express.Response) => {
  res.send(JSON.stringify(message));
});

//post
app.post("/api", (req: express.Request, res: express.Response) => {
  const detail_id = req.query.id;
  if (detail_id === "") {
    res.send(JSON.stringify(message));
  } else {
    const params: Params = {
      status:
        "ツイートしたいこと。"
    };

    client.post("statuses/update", params, (tweet: Twitter.ResponseData) => {
      if (tweet) {
        res.json(tweet);
      } else {
        res.json("ツイートできませんでした。");
      }
    });
  }
});

//put
app.put("/api", (req: express.Request, res: express.Response) => {
  res.send(JSON.stringify(message));
});

//delete
app.delete("/api", (req: express.Request, res: express.Response) => {
  res.send(JSON.stringify(message));
});

const port: string | number = process.env.PORT || 8080;
app.listen(port);
console.log("ポート番号" + port + "でWebサーバが立ち上がりました");
```

## 実行

```console
$ npx ts-node index.ts
```

localhost:8080/apiにpostメソッドでアクセスのみツイートされ、その他メソッドのアクセスでは「Bad Request」

# 最後に
もし間違いとかあればご連絡いただけると幸いです。

以上がTypescript + node.jsでのTwitterBotの作り方でした。TwitterBotを作る際の参考になれば幸いです。