OmniAICreator/Qiita-1.07M huggingface dataset:
[JavaScript]開発で使いそうな配列操作

#自己紹介
現在都内の企業でWebエンジニアのインターン生としてお世話になっている大学２年生です！
インターンや個人開発で学んだことや苦労したことを記事にしています！
よろしくお願いします🙇🏻‍♂️

#はじめに
今回は開発で使いそうな配列操作についてアウトプットしていこうと思います！

#スプレッド構文(...Array)
###配列の展開
```javascript
const array1 = [1, 2];
const sum = (a, b) => console.log(a + b);
sum(...array1); //配列を順番に処理
//コンソール:3
```
###配列のコピー、結合
```javascript
const array2 = [1, 2];
const array3 = [3, 4];
const array4 = [...array2, ...array3];
console.log(array4);
//コンソール:[1, 2, 3, 4]
```
#map関数
###returnされた結果によって新しい配列を生成
```javascript
const nameArray = ["鈴木", "佐藤", "田中"];
const nameArray2 = nameArray.map((name) => {
  return name;
});
console.log(nameArray2);
//コンソール: ['鈴木', '佐藤', '田中']
```
###配列をループして処理をする
for文をよりスマートに書ける

```javascript
const nameArray = ["鈴木", "佐藤", "田中"];
nameArray.map((name, index) =>
  console.log(`${index + 1}番目は${name}です。`)
);
//コンソール:
// 1番目は鈴木です。
// 2番目は佐藤です。
// 3番目は田中です。
```

第２引数を使わない場合は省略可能

```javascript
const nameArray = ["鈴木", "佐藤", "田中"];
nameArray.map((name) => console.log(name));
//コンソール:
// 鈴木
// 佐藤// 田中
```
#filter関数
###条件にあった要素だけ取り出す
```javascript
const numArray = [1, 2, 3];
const numArray2 = numArray.filter((num) => {
  return num % 2 === 1; //奇数だけ取り出す
});
console.log(numArray2);
//コンソール:[1, 3]
```
#終わりに
今回は配列操作について書きました！
この記事がJavaScript初心者の方の役に立てたら嬉しいです！
ではよいJavaScriptライフを😇
リモートからのファイル転送を自動化

#やりたいこと
リモートにあるファイルを本宅のサーバ（ClrLinux)に取り込みたい。作業は自動化したいけれどある程度のセキュリティーは担保したい。（少なくともパスワードをどこかに書いておくなんてことはしたくない）
公開キーを使ってパスワード入力すせずにSSHでリモートのUbuntuサーバにアクセスできそう。

リモートの映像が本宅のサーバでもこんな感じで見えるように。
![スクリーンショット 2022-02-09 1.05.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/92380/f1a3c8e5-eb07-72f9-afec-4102be6bc7e5.png)

##公開鍵の設定
ClrLinux　→　SSH →　Ubuntu(21.10）
①鍵を作成
②公開鍵をリモート側に移す
③リモート側のユーザーホームの下に公開鍵を追加

```
clear~ $ ssh-keygen -t rsa
clear~ $ ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/home/hoge/.ssh/id_rsa): 
/home/hoge/.ssh/id_rsa already exists.
Overwrite (y/n)? y
Enter passphrase (empty for no passphrase): （ここでは何も入れず空エンター）
Enter same passphrase again: （ここも空エンター）
Your identification has been saved in /home/hoge/.ssh/id_rsa
Your public key has been saved in /home/hoge/.ssh/id_rsa.pub
The key fingerprint is:
SHA256:SDIzjDfL77V81M4GN**********GGW8kHlfXQ hoge@clear
The key's randomart image is:
+---[RSA 3072]----+
|                 |
|   o      .      |
|  . O .  o . .. E|
|   o O .+ o .ooo.|
|    o ..S+ o.*.o+|
```
＊このときパスフレーズを聞かれるが、何か入れてしまうと、アクセス時に結局そのパスフレーズを聞かれるので、ここでやりたいことではないため空エンターすることに注意

~/.sshの下に作られたid_rsaが秘密鍵で、id_rsa.pubが公開鍵ということで、公開鍵の方をリモートのログインするユーザ（この場合はhoge）のホームの下 .ssh にあるauthrized_keyというファイルに追加する。

```
ubuntu:~/.ssh$ ls -la
合計 20
drwx------  2 hoge hoge 4096 Feb  8 23:38 .
drwxr-xr-x 21 hoge hoge 4096 Feb  9 00:01 ..
-rw-------  1 hoge hoge 1743 Feb  9 00:11 authorized_keys
ubuntu:~$ cat id_rsa.pub >> ./.ssh/authorized_keys 
```
としておくと、SSH系のコマンドをたたいたときに、パスワードなしでそのままログインできる！

```
clear~ $ ssh -4 -p 65xxx hoge@your_domain.mydns.jp
Welcome to Ubuntu 21.10 (GNU/Linux 5.13.0-28-generic x86_64)　　←　（パスワードなしでｌこうなる）

 * Documentation:  https://help.ubuntu.com
```
ssh -4　とした理由はこれを入れないとIPｖ６でつなげようとしてつながらないので。理由はリモート側のポートにはV4にしか穴を開けていないから。

##リモートからコピーするスクリプト
前提：
/home/hoge/image/の下にYY-MM-DDの形式のDIRがあって、その下に定点観測の映像が保存されている。
その写真映像を日にち単位でコピーする
そのスクリプトがこれ↓

```
#!/bin/sh
# copyimage.sh
#
localpath=/home/clear/share/image
remotepath=/home/hoge/image
dn=$(date +%Y-%m-%d)
SERVER=your_domain.mydns.jp
PORT=65xxx
USER=hoge
if [ $# -eq 1 ]; then
	echo "Dir = " $1
	dn=$1
fi
echo "Copying image from " ${remotepath}/${dn}
mkdir ${localpath}/${dn}
sftp -4 -P ${PORT} ${USER}@${SERVER} <<END
get ${remotepath}/${dn}/* ${localpath}/${dn}
END
```
あとはこれを一日一回CRONで回せばいいかな。

今回参考にした記事：
http://safe-linux.homeip.net/network/OpenSSH_rsync-03.html
他
論理演算子(||,&&,!)の意味

#自己紹介
現在都内の企業でWebエンジニアのインターン生としてお世話になっている大学２年生です！
インターンや個人開発で学んだことや苦労したことを記事にしています！
よろしくお願いします🙇🏻‍♂️

#はじめに
今回は論理演算子(||,&&,!)の意味についてアウトプットしていこうと思います！
論理演算子はtruly（trueと判定される値）か falsey（falseと判定される値）かの結果で値が決まります。

#||の意味
`||`は左項がtrueなら左項を、左項がfalseなら右項を返す

```javascript
const name = null;
const nameShow = name || "名前を入力してください";
console.log(nameShow);
//コンソール:名前を入力してください
```
#&&(アンパーサンド)の意味
`&&`は左項がfalseyなら左項を、左項がtrulyなら右項を返す

```javascript
const name2 = null;
const name2Show = name2 && "名前を入力してください";
console.log(name2Show);
//コンソール:null
```
#!の意味
!は否定を意味する
左項がtrulyならfalseを、左項がfalseyならtrueを返す

```javascript
const name3 = true;
console.log(!name3);
//コンソール:false
```

```javascript
> !undefined
true
> !null
true
> !0
true
> !123
false
> !""
true
> !"hello"
false
> ![]
false
> !{}
false
```
テンプレート文字列の使い方

#自己紹介
現在都内の企業でWebエンジニアのインターン生としてお世話になっている大学２年生です！
インターンや個人開発で学んだことや苦労したことを記事にしています！
よろしくお願いします🙇🏻‍♂️

#はじめに
今回はJavaScriptのテンプレート文字列についてアウトプットしていきます！

#使用例
```javascript
const nameArray = ["鈴木", "佐藤", "田中"];
//今までの書き方
nameArray.map((name, index) =>
  console.log((index + 1) + "番目は" + name + "です。")
);
//テンプレート文字列を用いた書き方
nameArray.map((name, index) =>
  console.log(`${index + 1}番目は${name}です。`)
);
```
テンプレート文字列を用いることで簡潔で見やすいコードが書ける。
[Apex] Set<SObject> より Map<Id, SObject> を使おう

## `Set<SObject>`を使うべきでない理由
重複のないコレクションを作成するためにSetを使うことがありますが、同じ使い方をSObjectで行うと想定と異なる結果になることがあります。
Apex開発者ガイドにはSObjectのSetについて下記のように記述されています。

> セットには一意の要素が含まれます。sObject の一意性は、オブジェクトの項目の比較によって判断されます。

SObjectが同一とみなされるかどうかは「項目が一致しているかどうか」になります。

### 別のインスタンスでも項目が一致していれば重複とみなされる
新たにnewしても項目が同じであれば重複とみなされてしまいます。

```apex
Account acc1 = new Account(Name = 'テストA');
Account acc2 = new Account(Name = 'テストA');

Set<Account> accSet = new Set<Account>{ acc1 };
System.assertEquals(true, accSet.contains(acc2)); // 項目が一致しているので重複とみなされています
accSet.add(acc2);
System.assertEquals(1, accSet.size());
```

### 同一IDのインスタンスでも同一とみなされない
同じIDのSObjectインスタンスを重複とみなしたいことがあるかと思いますが、項目が異なる場合、Idが同じでも別のものとみなされてしまいます。

```apex
Account acc = [SELECT Id FROM Account LIMIT 1];
Account acc1 = new Account(Id = acc.Id, Name = 'テストA');
Account acc2 = new Account(Id = acc.Id, Name = 'テストA', Phone = '03-0000-0000');

Set<Account> accSet = new Set<Account>{ acc1 };
System.assertEquals(false, accSet.contains(acc2)); // Idが一致していても他の項目が異なれば重複とみなされません
accSet.add(acc2);
System.assertEquals(2, accSet.size());
```

### addしたあとの項目変更が反映されないケースがある
`Set<SObject>`重複してSetに追加された場合、1つ目のインスタンスがSetに格納されるようです。そのため、2つ目以降のインスタンスの項目を変更してもSetの内容には反映されません。

```apex
Account acc1 = new Account(Name = 'テストA');
Account acc2 = new Account(Name = 'テストA');
Set<Account> accSet = new Set<Account>();
accSet.add(acc1);
accSet.add(acc2);
System.assertEquals(1, accSet.size());

// acc1の項目を変更します
acc1.Name = 'テストB';
System.debug(accSet); // 当然、Setの要素に変更が反映されます： {Account:{Name=テストB}}
System.debug(acc2); // acc2の値は変わりません: Account:{Name=テストA}
System.assertEquals(false, accSet.contains(new Application(Name = 'テストA')));
```
```apex
Account acc1 = new Account(Name = 'テストA');
Account acc2 = new Account(Name = 'テストA');
Set<Account> accSet = new Set<Account>();
accSet.add(acc1);
accSet.add(acc2);
System.assertEquals(1, accSet.size());

// acc2の項目を変更します
acc2.Name = 'テストC';
System.debug(accSet); // Setの要素に変更が反映されません!： {Account:{Name=テストA}}
System.debug(acc1); // acc1の値も変わりません: Account:{Name=テストA}
System.assertEquals(true, accSet.contains(new Account(Name = 'テストA')));
```

## 代わりに`Map<Id, SObject>`を使う
同一Idのインスタンスを同じものとして扱いたいときは`Set<SObject>`の代わりに`Map<Id, SObject>`を使用できます。

```apex
Map<Id, Account> accMap = new Map<Id, Account>();
for (Opportunity opp : oppList) {
    if (opp.IsSomething__c && opp.AccountId != null) {
        accMap.put(opp.AccountId, new Account(Id = opp.AccountId, IsSomething__c = true));
    }
}
update accMap.values();
```

## 参考
- [オブジェクトのセット | Apex開発者ガイド](https://developer.salesforce.com/docs/atlas.ja-jp.apexcode.meta/apexcode/apex_set_sobject.htm)
Why You Should Focus on Tattoo Community Websites

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2524607/65a7505e-9e14-1330-4f39-16e2946c64d1.png)
If you are really love the Tattoo and want to get more and more Tattoos Ideas then You Should Focus on Tattoo Community Websites Or can get more samples at -    https://www.thetattoopedia.com/
ROSAをcluster-wide proxyオプションを付けてインストールする

## やりたいこと

* ROSAはこれまでL3のルーティングでインターネットにアクセスできる環境上でないとインストールできなかった
* ROSA CLIのv1.1.7のリリースノートに`ROSA: Support editing cluster-wide proxy`が含まれており、HTTP PROXY経由でのインストールができるようになった。これを試したい。
* また、ROSAのインストールコマンドの発行もHTTP PROXY配下で実施したい。

## 前提条件

* 1つのVPCにPublic SubnetとPrivate Subnetを作る
* NAT Gatewayは作らずに、Public SubnetにForward Proxy(Apache)を構築する
* Private SubnetにEC2を作り、ROSA CLIを実行し、ROSAのインストールを試みる

```apache:/etc/httpd/conf.d/proxy.conf
Listen 3128
<IfModule proxy_module>
  ProxyRequests On
  ProxyVia      On
  ProxyTimeout  300
  AllowCONNECT 443
  CustomLog logs/proxy_log combined

  <Proxy *>
    Order allow,deny
    Allow from all
  </Proxy>
</IfModule>
```

## ROSA のインストール

以下は、Private Subnet内に配置したEC2からの操作

```bash
# rosa cliのダウンロード
wget https://mirror.openshift.com/pub/openshift-v4/clients/rosa/latest/rosa-linux.tar.gz

# 解凍する
tar zxvf ./rosa-linux.tar.gz

# 配置する
sudo mv rosa /usr/local/bin/

# 権限をつける
sudo chmod +x /usr/local/bin/rosa

# oc commandのダウンロード
rosa download openshift-client

# 解凍する
tar zxvf ./openshift-client-linux.tar.gz

# 配置する
sudo mv ./oc /usr/local/bin/

# 権限をつける
sudo chmod +x /usr/local/bin/oc

# rosa loginする（トークンは `https://console.redhat.com/openshift/token/rosa/show` から）
rosa login --token="eyJ...snip...WN4"

# 諸々の権限が充足しているか確認する
rosa verify permissions

# Account Rolesを作成する
rosa create account-roles --mode auto --prefix rosaproxy -y

# クラスタのインストールをする
rosa create cluster --cluster-name rosaproxy \
--sts \
--role-arn arn:aws:iam::68xxxx92:role/ManagedOpenShift-Installer-Role \
--support-role-arn arn:aws:iam::68xxxx92:role/ManagedOpenShift-Support-Role \
--controlplane-iam-role arn:aws:iam::68xxxx92:role/ManagedOpenShift-ControlPlane-Role \
--worker-iam-role arn:aws:iam::68xxxx92:role/ManagedOpenShift-Worker-Role \
--operator-roles-prefix rosaproxy-xxxx \
--region ap-northeast-1 \
--version 4.9.18 \
--compute-nodes 2 \
--machine-cidr 10.0.0.0/16 \
--service-cidr 172.30.0.0/16 \
--pod-cidr 10.128.0.0/14 \
--host-prefix 23 \
--private-link \
--subnet-ids subnet-04ca01c59deaff573 \
--etcd-encryption \
--http-proxy http://10.0.0.27:3128 \
--https-proxy http://10.0.0.27:3128

# Operator Roleを作成する
rosa create operator-roles --cluster rosaproxy --mode auto -y

# RHのOPと信頼関係を結ぶ
rosa create oidc-provider --cluster rosaproxy --mode auto
```

## 結果

```bash
rosa logs install -c rosaproxy | tail -n 1
time="2022-02-08T15:22:58Z" level=info msg="install completed successfully" installID=5xxxxxx9
```

## よかった

* 多分、VPC内にROSAを構築しないといけないような企業って、L3のルーティングでインターネットには出れないと思う。
* そんな中、ROSAがインストールパラメータでPROXYの設定をもてるようになったのは嬉しい
* ~~もっと早くリリースしてほしい~~
Javaのインターフェースについて学んだのでメモ

Javaのインターフェースについてとりあえず軽く調べたので、とりあえずまとめてみようと思います。

#interfaceとは

interfaceは定数とメソッドの定義しかすることができません。
そして、宣言する場所ですが、これはクラスの外で定義をします。つまり、クラスの中で宣言をしてしまうとコンパイルエラーになってしまうので注意が必要です。
そして、interfaceで宣言した定数はどこでも使えるというわけではなく、その定数を使う場所を宣言しなくてはいけません。
そのやり方については、次の場所で説明します。

# interfaceの書き方

```
interface インターフェース名{}
```

と書きます。
具体的には

```
interface HogeInterface{}
```

のようにして宣言します。
いまインターフェースの宣言のやり方を宣言したので、次から実際にインターフェースで定数を宣言して、実際にそれを使えるようにするまでやっていきます。

今手元には、interfaceであるhogeInterfaceと、hogeクラスがあります。

まず最初に、interfaceの宣言のやり方から説明していきます。

```
interface HotgeInterface{
　//ここで宣言されているものは、すべて定数になる。
  int a = 4;
  int b = 3;
  //そしてこの行で上で宣言した定数を使う関数を宣言します
　void Hoge();
}
```

こうすることで関数hogeの中で定数aと定数bを使うことができるようになりました。
そして、宣言したinterfaceをどうやって別の関数の中で使っていくかというと、関数の親であるクラスにimplementsをつけて上げるだけです。

```
class Hoge implements HogeInterface{}
```

のようにimplementsをクラス名の後につけて宣言したインターフェースの名前をつけることで、hogeInterfaceの中で宣言した内容をhogeクラスの中で使うことができます。

#interfaceを使うメリット

自分なりに調べてみたのですが、取り合えずわかったのは以下です。

```
様々なクラスで、処理や定数を共通化して使うことができる。
```

というのがメリットだと思います。

よくあることとして、
「クラスAで使っている変数をクラスBでも使いたい。」
「クラスAとクラスBで処理を共通化できるところがあるから共通化して保守性を上げたい。」

ということだと思います。
なんとなくThymeleafでいうフラグメントみたいなものかなと思いました。

共通の関数で使える関数を宣言してインターフェースに置くことで色んな場所(クラス)で使うことができるというメリットが有るように思いました。

もう一つのメリットとしては、同時に複数のインタフェースを継承できることです。

クラスの継承では親クラスを子クラスに継承する場合，
その継承する側の子クラスは1つの親クラスしか指定できないはずです．

しかし、インターフェースを使えば複数のインターフェースを一つのクラスに対して扱うことができます。
これにより、クラス継承よりも処理の共通化がしやすいというメリットがあります。

以上になります。指摘やコメント等ありましたら教えて下さい!!
何分初心者なので指摘していただけるとありがたいです。
SIGGRAPHレイトレーシング講座の紹介

#はじめに
この記事では[SIGGRAPH](https://s2021.siggraph.org/program/frontiers/)のレイトレーシング講座であるIntroduction to Ray Traicingの内容や、実際にやってみて気づいたことを紹介しています。

レイトレーシングを学習し始めようという人、もしくはすでにしている人の一助となれば幸いです。拙い部分が多々あるとは思いますがご容赦ください。

#目次
- [概要](#概要)
- [内容](#内容)
- [使用言語・動作環境](#使用言語動作環境)
    - [ShaderToyの注意点](#shadertoyの注意点)
        - [VScodeでShaderToy](#vscodeでshadertoy)
- [さらなる高みへ](#さらなる高みへ)
- [おわりに](#おわりに)

#概要
レイトレーシングの基礎を学べる講座で、スライド形式の資料と動画があります。

リンク↓↓
[スライド資料](https://drive.google.com/drive/folders/11cQDkO0fPLakZO0WaK2zrhxzUxm7F_e2)
[動画(Youtubeのリスト)](https://www.youtube.com/watch?v=3xMeKal2-Ws&list=PL1PdIP1lGMJKx7-r8kckk41E8eFBYJH_F)

内容としてはタイトル通り入門編といった感じで、レイトレーシングの基礎を1から説明してくれます。ただし**全部英語(日本語版無し)**です。資料はともかく動画は字幕無いと厳しいかもしれない。あとある程度プログラミングや数学の知識は必要です。

一方、回によってはサンプルプログラムも配布されてて、資料と照らし合わせれば十分学べるような構成にもなっていますので、英語苦手でもおそらく大丈夫です(かくいう筆者も英語は苦手…)。

#内容
全7回で、ざっくりと

1. レイトレーシングの概要
1. 球の描画
1. 球の描画+(色の)明るさ+テクスチャマッピング
1. マテリアル(ランバート反射・スペキュラー反射)
1. マテリアル+PDF
1. マテリアル+PDF
1. 影+ライト+等々

というような構成になっています。Class3のテクスチャマッピング等ほんの少ししか触れられていない内容もありますのでご注意ください。

ここでPDFはもちろん文書のフォーマットではなく確率密度関数を意味していて、大体レイトレだと反射したレイが各方向にどのくらいの確率で向かうかの分布だと思っています(違ってたらすみません)。

また、これはこの教材に限った話ではないと思いますが、初見かつ英語だと調べてもあまり出てこなかったりしてめんどくさい数学表現がいくつかありますので以下に少しだけ記載します。

- dot(A . B) = AとBの内積
- where = ここで、
- PDF = 確率密度関数
- normal = 法線

ちなみに第五回ともなると結構きれいな画像を作るだけの知識が得られます。例としてサンプルプログラムを実行したものを以下に載せます。

![Sample1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2512885/334e2bfc-d5f8-2dc6-f354-1e7493d30976.png)

サンプルプログラムいじって遊ぶだけでも楽しいです。

#使用言語・動作環境
使用言語はGLSL(シェーダー用の言語)で、[ShaderToy](https://www.shadertoy.com/)というWebサイト上で動かすことを前提としています(アカウント登録が必要)。

配布されているサンプルプログラム(スライド資料にリンクが記載)もShadertoy上にあります。

##ShaderToyの注意点
ShaderToyでは一度の処理ですべてのピクセルを描画します。なのでmain関数(ShaderToyではmainImage関数)でwidth*heightのようなfor文を書く必要はありません(最初ひっかかった)。

このようなShaderToyの基礎知識や使い方に関しては[こちらのサイト](https://www.hanachiru-blog.com/entry/2020/10/15/120000)が参考になりました。

次に、ShaderToyはweb上で直接コーディング&実行出来て非常に便利なんですが、わりと重かったりします。加えてサイト自体が異様に重くなって何もしてないのにコーディングすらままならなくなったこともあります(原因不明、おま環？)。

なのでコーディングのしやすさ等も鑑みて、VScodeを使っている人はVScode上でShaderToyを動作させるといいかもしれません。以下に詳細を書きます。

###VScodeでShaderToy
1. 拡張機能を入れます。検索ボックスに「ShaderToy」と入力すれば出てくるはず。
![2022-01-25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2512885/16984faf-b78c-02d3-26b3-ac53547fa146.png)

2. 何かコードを書きます([サンプルプログラム](https://www.shadertoy.com/view/7ts3WN))。GLSLの拡張子は特に決まってない？らしいですが、ここでは.vsとしています。

3. コード書いたファイルを開いた状態でF1を押すと、一番上に「Shader Toy: Show GLSL Preview」と出てくるのでEnterを押すと右側にプレビューウィンドウが出てきます。以上です。
![2022-01-25 (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2512885/932a74cc-5b34-3797-b816-12fb30c90b90.png)

#さらなる高みへ
この資料をある程度修了したら、有名ですが[週末レイトレーシング](https://booth.pm/ja/items/2186534)をやるのがおすすめです(学生版は**無料**!)。全体はまあまあ長いのですが、こちらは日本語版があるので意外とサクサクいけるかもしれません。

使用言語がC++なので使ったことない人はまずそこからになってしまうかもしれませんが、長いだけあって説明も丁寧なので今回の資料では物足りない人やしっかり復習したい人は是非やってみてください。

注意点として、しばしばプログラムに誤植があるのでエラーが出たときは資料記載の本人のコードを参照しつつコーディングすると良いかもしれません。

#おわりに
筆者自身レイトレーシングに特別詳しいわけでもない上初投稿なので、何か気になる点および間違っている点がありましたらコメントにて教えていただけると幸いです。

最後まで読んでいただきありがとうございました。
LiveServer で Go Live を押しても「このページは動作していません」と表示されてしまう現象の解決法

# はじめに
VSCodeを用いてHTML,CSS,JavaScriptを学習しようと思い、テストページのHTMLをLiveServerで表示しようとしたときに今回の現象に遭遇してしまったので、試したことと対処法をメモ。

# 試したこと
## 1. (効果なし) VSCodeで資材を置いているフォルダーを開いてGo Liveで表示する
LiveServerが起動しない関連の対処法自体そこまでなく、頻出している本対処策を行ってみた。
### 結果
依然として「このページは動作していません」と表示される。（何度も見てきたので早く何とかしたい...

## 2. (効果なし)VSCodeの再起動
もちろんやりますよね。
### 結果
依然として「このページは動作していません」と表示される。（そんな気がしてた

## 3. (効果なし) 表示するブラウザを変更してみる
もしかしたらChromeで表示したときだけかもしれないという淡い期待を胸に...
### 結果
別のブラウザでも「このページは動作していません」と同じような内容が表示される。
これでブラウザが原因ではないことは明らかに。
そもそもVSCodeのステータスバーは「Port:5500」と表示されており、間違いないく動作しているはず...
この時点でPCの環境自体が原因かもしれないという疑惑が。
VSCodeの拡張機能の設定からLiveServerの設定を見ていてもしかしたらと思い次の対処法を行ってみた。

## 4. (効果あり) VSCodeのLiveServerの設定から`Settings: Host`を変更する
デフォルト値が 127.0.0.1 になっていたため、試しに 127.0.0.2 にしてみた。
### 結果
なんと表示された！


# おわりに
今回は何とか1時間程度で解決できましたが、なぜ127.0.0.1では使用できなかったのだろう。。。
既に使用している何かと競合していた？んでしょうか。
【JavaScript関数ドリル】を毎日やる【勉強用】

#【JavaScript関数ドリル】初級編のzipObject関数の実装のアウトプット



##zipObject関数の課題内容


https://js-drills.com/blog/zipobject/

##zipObject関数に取り組む前の状態

・少し調べればすぐにできそう
・学習のメインのFrontHacksでは非同期処理まで進んでいるので簡単にできるはず

##zipObject関数に取り組んだ後の状態

・これまでの学習の復習（アウトプット）が全く足りていないことを痛感した
・初日から実装できずに終わるのが嫌で、かなり時間をかけてしまった
・console.log内で関数を実行すれば良いものをわざわざ変数に代入して表示してしまった
・白紙から実装したことで少し自信がついた

##zipObject関数の実装コード

```
const zipObject = (props = [], values = []) => {
    const zippedObj = {};
    for (let i = 0; i < props.length; i++) {
        const prop = props[i];
        const val = values[i];
        zippedObj[prop] = val;
    }
    return zippedObj;
};

const result = zipObject(['a', 'b'], [1, 2]);
console.log(result);
// => { 'a': 1, 'b': 2 }
```



##zipObject関数の解答コード

```
function zipObject(props = [], values = []) {
  const zippedObject = {};
  for(let i = 0; i < props.length; i++) {
    const prop = props[i];
    const value = values[i];
    zippedObject[prop] = value;
  }

  return zippedObject;
}

console.log( zipObject(['a', 'b'], [1, 2]) );
// => { 'a': 1, 'b': 2 }
```
ABC225 C問題(python)

#C - Calendar Validator

*留意事項
取り出した短形領域Bの各行は、
1,2,3,4,5,6,0 mod(7)の順番から
抜き出した並びになっている必要がある。

```
b=[]
l=True
k=0
n=0
s=0
N,M=map(int,input().split())
for _ in range(N):
    b=list(map(int,input().split()))
    if ((k!=0) and (b[0]!=(n+7))):
        l=False
        break
            
    n=b[0]
    for i in range(M-1):
        if s==1:
            l=False
            break
        if  (b[i+1]-b[i])!=1:
            l=False
            break
        if b[i]%7==0:
            s=s+1
    k=k+1
if l:
    print("Yes")
else:
    print("No")
```
三流窓際エンジニアがやる初めてのSlack Bot開発 〜IntegromatのHTTPモジュールで作ってみる編 〜

前回：[三流窓際エンジニアがやる初めてのSlack Bot開発 〜サーバーサイド開発と思いきやIntegromatでイキナリ完成編 〜](https://qiita.com/kaba_U1/items/4bb825b8a3500de58ef1)

前回はBeta版なモジュールを使い、思いっきり横着して作ったので、
参考にさせていただいているサイトの手順に従い、HTTPモジュールで作ってみようと思う。

<h1>今日の目標</h1>

今回もサーバー側を作る。

参考にしたサイト：
[誰でも分かるはず！本気でSlackBotの作り方を解説してみた！](https://belltree.life/slack-bot-hands-on/)

引き続き、上記の記事を参考にさせていただきます！

<h1>シナリオを追加してHTTPモジュールでSlackBot！</h1>

![スクリーンショット 2022-02-08 21.38.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201583/b8738ae0-c822-60ba-fa3e-0403455457a8.png)

"Create a new scenario"ボタンを押して、シナリオを追加する。

![スクリーンショット 2022-02-08 21.39.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201583/6d6e45d4-a389-420f-f550-5d16649a05c8.png)

画面中央の"+"ボタンから"HTTP"を選択する。

![スクリーンショット 2022-02-08 21.40.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201583/fefb8dcc-79bd-090b-0765-2f15043f13c5.png)
今回もメッセージの投稿を実装したい。
なので、"Make a request"を選択する。

![スクリーンショット 2022-02-08 21.55.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201583/b08ef9c3-7196-3736-975b-3e0c5334eb34.png)

こんな感じで設定。(たぶん、"Parse response"はオフでいい)
tokenにはSlackのBotのTokenを、channelには投稿先のSlackのchannelのID(下画像の赤枠)を入れる。

![スクリーンショット 2022-02-08 21.50.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201583/e5afdc70-e3ea-65f2-f164-5d46aefe90c8.png)

![スクリーンショット 2022-02-08 23.42.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201583/bfb324c7-500d-5de6-c32f-a7f170244199.png)

"Run once"ボタンで実行！
POSTには成功したが、Slackには投稿されず…。
なぜだ！？素直にSlackモジュール使っとけってことなのか？！
列を増やすことなく、特定の列に対して任意の文字列を追加する方法

列を増やすことなく、特定の列から任意の文字列を抽出するのは、簡単である。
(あらかじめ変換タブに用意された「抽出」ボタンを利用するだけでOK)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/684495/e178f2d4-4e49-8375-6d1e-bedf53ee54c8.png)

一方で、列を増やすことなく、特定の列に対して任意の文字列を追加するのは、簡単ではない。
(あらかじめ専用のボタンが変換タブに用意されていないことから、ワンボタンで完了できない。)

この点について、2つの方法が考えられる。

- 「カスタム列の追加」を利用する
- Table.ReplaceValue関数(値の置換)を利用する


# 「カスタム列の追加」を利用する
1. 「カスタム列の追加」を利用して、`[追加元の列] & "任意の文字列"`を返す列を新規生成する
2. 追加元の列を削除する

この方法の場合、ボタンポチポチでできるので実装が簡単な反面、ステップ数が２つになってしまう。


# Table.ReplaceValue関数(値の置換)を利用する
以下のとおり記述する
※詳細エディターに慣れていない方は、「値の置換」ボタンを利用してあらかじめステップを用意しておくと良い

```
        Table.ReplaceValue(
            前のステップ名, 
            each [追加元の列], 
            each [追加元の列] & "任意の文字列",
            Replacer.ReplaceText,
            {"追加元の列"}
        ),
```
この方法の場合、M言語に抵抗があると実装が難しい反面、１つのステップで処理を完了することができる。
※「もっと良い方法があるよ」という方がいらっしゃいましたら、コメントいただけますと幸いです。
bashのaliasをシェルスクリプト内では意識せずに使う方法

こちらの記事の結論で書いてある通り、Bashのaliasをシェルスクリプト内に引き継ぐキレイな方法は見つかりませんでした。

https://qiita.com/dark-space/items/e599981f2325a652fabd



ワークアラウンド的ですが、シェルスクリプトに修正を入れずに使える方法が見つかったので残しておきます。

# シェルスクリプト内でaliasを使えない
`~/.bashrc` でaliasを設定しているとします。

```sh
alias foo=date
```

```sh
# aliasのfooが設定されていることを確認
$ alias
alias foo='date'
$ foo
Tue Feb  8 14:31:20 UTC 2022

# aliasのfooを実行するシェルスクリプトを作成
$ cat <<EOF > a.sh
> foo
> EOF

# シェルスクリプト内ではaliasが展開されていない
$ bash a.sh 
a.sh: line 1: foo: command not found
```

# シェルスクリプト内でaliasを使う
上記の `a.sh` のスクリプトファイルには変更を加えずにaliasを認識させる方法です。

`~/.bashrc` のどこかに `shopt -s expand_aliases` の一行を入れます。

```sh
shopt -s expand_aliases
alias foo=date
```

`-l` オプションを入たbashで実行すると、シェルスクリプトには修正を入れないでも、aliasを展開して実行できます。

```sh
# -l オプションを入れるとaliasが実行可能
$ bash -l a.sh 
Tue Feb  8 14:36:03 UTC 2022

# -l オプションを無しだとaliasが展開されていない
$ bash a.sh
a.sh: line 1: foo: command not found
```

もちろんshebangに書いても良いです。

```a.sh
#!/bin/bash -l
foo
```


`-l` オプションの説明は以下の通りです。ログインシェルとして扱うので展開されるみたいです。

```
 -l        Make  bash  act as if it had been invoked as a login shell (see INVOCATION below).
```
【Heroku】 error: failed to push some refs to "URL"が治らない....

#Herokuを用いたデプロイ時のエラー原因が、「メインブランチ以外で作業を行なっていたこと」だった件

チーム開発でGithubを用いながらWebアプリケーションの開発を行なっていた時に行き詰まってしまったエラーを共有します

###状況
Ruby on Railsで作成したアプリケーションをherokuにデプロイしたい！！

```:terminal
voclabs:~/environment/railsアプリ名 (testbranch) $ git push heroku main
```

Herokuを用いてRailsのアプリケーションをデプロイするときに何回やっても下記のようなエラーが出てしまう

```:terminal
 ! [rejected]        main -> main (non-fast-forward)
error: failed to push some refs to 'URL'
hint: Updates were rejected because a pushed branch tip is behind its remote
hint: counterpart. Check out this branch and integrate the remote changes
hint: (e.g. 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
```

###環境

Cloud9(Amazon Web Service)
Rails 5.2.6
ruby 2.6.3p62 (2019-04-16 revision 67580)

###試してみたこと

errorと表示されている「error: failed to push some refs to 'URL'」について色々調べてみた。
しかしながら調べて出てくるコマンドを実行してみても治らなかった。



### 原因

自分が現在作業しているブランチが原因だったことがわかりました。
自分はずっと頑張って変更してもいないmainブランチをherokuにデプロイしようとしていたのです...泣
下記の記述方法だとマスターまたはメインブランチ​から heroku​ リモートにコードをデプロイしようとするみたいです。

```:terminal
voclabs:~/environment/railsアプリ名 (testbranch) $ git push heroku main
```


### 解決方法

ローカルリポジトリの非 main​ ブランチ (testbranch​ など) から Heroku にコードをデプロイする場合、次の構文を使用して、リモートの main​ ブランチにプッシュされるようにすること

```:terminal
voclabs:~/environment/railsアプリ名 (testbranch) $　git push heroku testbranch:main
```

上記の「testbranch」は現在自分が作業し、commitなどを行なっているブランチ名を指定しましょう


###参考元
https://devcenter.heroku.com/ja/articles/git

###最後に

ここまで読んでくだりありがとうございます。
拙い文章で申し訳ないのですが、自分のエラー解決方法が誰かのためになればと思います。
Vue3で再利用可能なコンポーネントを作るのに苦労した話

## 記事の目的

Vue.jsコンポーネントの実際の開発で得た経験のまとめ。

### 開発の目的

自社で開発しているタブレットアプリの設定項目を１画面のWeb Formで登録更新する機能があるのですが、これが膨大な数に及ぶためFormのHTMLテンプレートだけで300kbを越えており、人力保守では限界に達しているためFormの自動生成をVue.js化することにしました。

どうせなら専用機能としてではなくFormの自動生成部分をOSS化して再利用できたらいいなと思い、作り始めたわけですが。いや、大変でした。

実際に開発したライブラリはこちらです。

- vue-json-form
  - https://github.com/kanryu/vue-json-form


## 課題

### template上でHTML上のデザインと分離できない

通常、サーバーサイドでHTMLを生成する系のHTMLテンプレートの場合、固定部分のHTMLの一部にプログラムで動的に変化するところを部分的に挿入する形で作り込むと思います。

ところがVue.jsでは通常のHTMLタグの中にVue.jsで作ったコンポーネントのタグを直接埋め込む方式で、bootstrap等画面デザインに関わるHTMLタグと完全に混在した形での定義となってしまい、本質的にコンポーネントタグとHTMLタグが分離不可能となっています。

この問題はすぐには解決不能だと感じたため、OSSのパッケージとしてはForm画面全体のvueファイルは再利用しないことにしました。

### 親から見て子のコンポーネント上で指定する孫コンポーネントを動的変更することは可能

Vueでは汎用Vueタグとして `<component>` というタグが使用可能であり、`<component :is="someComponent"/>`と記述することで例えば`someComponent='FoodPanel'`の場合、実際には`<FoodPanel />` タグを記述したのと同じレンダリングが行われます。

当然ながらレンダリングする際に子のコンポーネントが孫のコンポーネントを知っている（登録済み）必要があるので、親が子コンポーネントのcomponentsを書き換える必要があります。例えばこういう実装内容になるでしょう。

```javascript
import MainForm from './components/MainForm.vue'
import RadioType from './components/InputTypes/RadioType.vue'

export default {
  name: 'App',
  components: {
    MainForm,
  },
  setup() {
    // 子のcomponentsを親が書き換える
    MainForm.components = {
      RadioType,
    }
    ...
  }
}
```

ただし欠点があって、一応全体としては動くのですが、`yarn serve` でモニターさせている場合、稼働中に `MainForm` を書き換えると `MainForm` が再初期化され、孫コンポーネントを知らない状態に戻ってしまうため稼働不能になります。仕方がないので毎回ブラウザをリロードしています。


### 親、子、孫と3世代のコンポーネントを定義した場合、子のコンポーネントの設計が困難

Vueでは `v-model`の形で親コンポーネントのcontext(コンポーネントのプロパティまたはその一部)を引き渡します。

Vue2では`value`、Vue3では`modelValue`という名称のプロパティ(props)です。

親子構築は特に問題なく実装できるのですが、子から孫に再びcontextを引き渡す場合、

この `modelValue` の一部を渡そうとするとエラーになってしまいました。

やむをえず、バッドノウハウではありますが `data()`実行時に `modelValue`のクローン(`myvalue`)を作成し、`myvalue`を孫の `v-model` として引き渡す形で実装せざるを得ませんでした。

当然ながら `modelValue` と `myvalue` は本来一体のものですから、子コンポーネントの責任で値の変更を同期する必要があります。

### コンポーネントのロジック部分の外部化が困難

従来の Options API方式でコンポーネントを定義する限りでは、どのみちロジック部分の外部化はほぼ不可能です。

Vue3では新たに Composition APIによるコンポーネントの定義が可能になっており、こちらはPlain JavaScriptでロジック設計が可能になります。

コンポーネントの動的な部分を全部 `setup()` での定義に再実装したあと、外部の jsファイルに移動させてimportさせたところ、すんなりと移植が完了しました。ちょっと感動した。


### 終わりに

以上、Vue3 のコンポーネントを OSS化する際にぶつかったいくつかの課題と解決法についてまとめました。

`vue-json-form` については今後も開発を続けていきますので、また新たな課題を克服したときには記事を更新したいと思います。
JavaScriptの関数宣言

#関数

##通常の関数
ごく普通の関数の定義と呼び出し
宣言場所が、呼び出しの後でも機能する（巻き上げが起こる）

```javascript
//構文
function 関数名(){
  //処理
}

//例
function AAA(aaa){
  console.log(`引数は${aaa}`)
}

AAA('引数');//関数呼び出し
```

##無名関数　（関数式）
関数名が無い関数
他の関数の引数に指定したり、変数に格納して使用することができる
宣言場所が、呼び出しの前でなければ機能しない（巻き上げが起こらない）

```javascript
//構文
const 変数名 = function(引数){
  //処理
}

//例
const sum = function(a,b,c){
  return a + b + c;
}

const total = sum(1,2,3);//関数呼び出し
```

##アロー関数
無名関数の　function　を　=>　で表現したもの
IEでは使用できない


```javascript
//構文
引数=>処理

const 変数名 = (引数)=>{
  //処理
}

//例
const sum = (a,b,c)=>{
  return a + b + c;
}

const total = sum(1,2,3);//関数呼び出し
```
```javascript
//関数の中身が１行のみ（return　◯○）の場合{}を省略して１行で書ける
const sum = (a,b,c) => a+ b + c;

//さらに、引数が一つの場合、()も省略できる
const sum = a => a + 2;

//ただし引数がない場合は（）を省略できない
const sum = () => { 処理 };
```

##即時関数
関数宣言と同時に実行する

```javascript
//構文
(function (仮引数) {
  //処理
})(引数);

//例
(function (name) {
  console.log(`こんにちは、${name}`);
})('まい');
```
```javascript
//こんな使い方もあり
//ユーザーエージェントでデバイスの判定
const device = (function() {
  if (navigator.userAgent.match(/iPhone|Android.+Mobile/){
    return 'mobile';
  } else {
    return 'pc';
  }
})();

```




アロー関数は慣れないと暗号にしか見えませんが、(引数)=>{処理}となっているので
この引数でこの処理してね〜と言っているように見えなくもない。。。かもしれません。
Windows標準機能だけで高速置換する

Qiitaで初めて書いてみる記事です。

バッチファイルでテキストを置換する記事がいくつかあるけど
10000行とかのテキストファイルを置換するときに結構時間がかかるので改善してみました。

AAA.txtに「before」という文字があって、それを「after」に
置換して、BBB.txtに出力するだけの処理です。

``` old.bat
@echo off

setlocal enabledelayedexpansion

for /f "delims=" %%r in (D:\AAA.txt) do (
	set line=%%r
	echo !line:before=after! >> D:\BBB.txt
)

```

``` new.bat
@echo off

setlocal enabledelayedexpansion

(
for /f "delims=" %%r in (D:\AAA.txt) do (
	set line=%%r
	echo !line:before=after! 
)
)>> D:\BBB.txt
```

あまり違いがないかもしれないですが、()が増えたのとBBB.txtに出力するタイミングが変わります。

old.batでは1行ごとにファイルハンドルをオープンクローズしていますが
new.batではいったん全部置換してから最終的にファイル出力しています。

10000行くらいのファイルでold.batでは1分くらいかかっていましたが、
数秒で同じ結果が出力できます。
makefile ってなに？

## 勉強前イメージ

実はよくわかってないの・・・
なんか記事に書いた気がするけど残ってないしわかってないので
やったとしても書く

## 調査

### makefileとは

コンパイルやインストールなどのルールを記載しておくファイルのことを指します。
読み込むのはmakeコマンドというものが読み込んで処理を行います。
元々はビルドツールで、ライブラリや実行ファイルのビルドで使われています。

### makefile作ってみる

- makeのインストール

コマンドがないって言われたので入れてみました。

```
yum install make
```

- 動作させるファイルの作成

5回、hello worldを表示させるスクリプトを置いてみました。

```
vi hello.sh
```

```
#!/bin/bash

for ((i=0; i<5; i++)); do echo "hello world!"; done
```

- makefileの作成

基本は以下のように使います。
また改行する場合は `\` を使います。

```
ターゲット名:
	呼び出すコマンド
```

makefileを作ります。

```
vi Makefile
```

```
# hello worldを5回表示
display_hello:
	bash hello.sh
```

- makefileの実行

実行は `make ターゲット名` で実行できます。

```
make display_hello
```

以下のように結果が出ました。
ちゃんとhello worldが5回表示されています。

```
[root@localhost ~]# make display_hello
bash hello.sh
hello world!
hello world!
hello world!
hello world!
hello world!
```

## 勉強後イメージ

ややこしいかなって思ってたけど、案外そんなことないのね。
ビルド必要でもいっぱい書いてあったら自動的にやってくれるもんね。

## 参考

- [自動化のためのGNU Make入門講座 - Makefileの基本：ルール](http://objectclub.jp/community/memorial/homepage3.nifty.com/masarl/article/gnu-make/rule.html)
- [「Makefile」ファイル](https://linuc.org/study/knowledge/542/#:~:text=%E3%80%8CMakefile%E3%80%8D%E3%81%AF%E3%80%81%E3%82%B3%E3%83%B3%E3%83%91%E3%82%A4%E3%83%AB%E3%80%81,%E9%96%A2%E4%BF%82%E3%82%92%E8%A8%98%E8%BF%B0%E3%81%97%E3%81%BE%E3%81%99%E3%80%82)
強化学習の基礎

#強化学習概論
参考図書↓
https://www.amazon.co.jp/%E3%81%93%E3%82%8C%E3%81%8B%E3%82%89%E3%81%AE%E5%BC%B7%E5%8C%96%E5%AD%A6%E7%BF%92-%E7%89%A7%E9%87%8E-%E8%B2%B4%E6%A8%B9/dp/4627880316/ref=sr_1_1?adgrpid=117246922755&hvadid=536136974632&hvdev=c&hvqmt=e&hvtargid=kwd-333184464214&hydadcr=16039_13473667&jp-ad-ap=0&keywords=%E3%81%93%E3%82%8C%E3%81%8B%E3%82%89%E3%81%AE%E5%BC%B7%E5%8C%96%E5%AD%A6%E7%BF%92&qid=1644327855&sr=8-1

![スライド1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1820910/ef51cb7c-c444-bf21-0f53-580d9abcc9e0.png)



![スライド2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1820910/c2fd32be-eb7e-a0cf-23a4-abbd722c747b.png)
![スライド3.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1820910/2f5bfce9-c4e0-87b1-3332-703faa1698e3.png)
![スライド4.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1820910/531ceede-6bd0-f5d0-0a14-355864643918.png)
![スライド5.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1820910/9dac8716-bcb3-2d46-b70c-2b22d5b4a450.png)


![スライド6.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1820910/f885dfb6-7da9-dd28-3d1b-d78f0c499d8e.png)
![スライド7.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1820910/70d2a78b-040d-a879-b49c-ed1f8a720b57.png)
![スライド8.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1820910/bd4c2f2d-10bb-9046-d1f7-9b4810b37563.png)


![スライド9.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1820910/20376127-69eb-7651-5c0b-8e755e36c5b8.png)
![スライド10.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1820910/68851638-fe00-48a7-1e43-a29d04df11d1.png)
![スライド11.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1820910/a1fa8f53-7de5-5025-66b1-9a7c6f6c9a75.png)
【C#】超初歩のDictionary

個人(初学者)の勉強メモになります。

# Dictionaryとは？
「キーと値のコレクションを表します。」

https://docs.microsoft.com/ja-jp/dotnet/api/system.collections.generic.dictionary-2?view=net-6.0

# 宣言

```c#
Dictionary<string, float> dictionary = new Dictionary<string, float>() { {"key1", 0}, {"key2", 1} };
```

# 追加
```c#
// 同じKeyの値の要素を追加するとこはできない
dictionary.Add("key3", 2);
```

# 削除

## Key指定で削除
```c#
dictionary.Remove("key3");
```

## 全削除
```c#
dictionary.Clear();
```

# 値の取得

## key名から
```c#
dictionary["keyName"];
```

## 値からkeyを取得
```c#
KeyValuePair<string, float> res = dictionary.FirstOrDefault(v => v.Value.Equals(1));

// keyだけ取得
string res = dictionary.FirstOrDefault(v => v.Value.Equals(1)).Key;
```

## indexでのアクセス
```c#
dictionary.ElemenntAt(index).Value;
```

以上です。

# 参考
https://www.sejuku.net/blog/41326
https://www.fenet.jp/dotnet/column/language/c-sharp/8164/
anyenv + goenv + vscodeの環境で正しくlocalのバージョンを参照しない

最近、Goの環境の管理をanyenv + goenvに移行したhk220です。こんばんわ。

anyenv + goenvの環境で、vscode + Goプラグインを使うとちょっと困ったことが起きたので、忘備録として残します。

# 動作を確認した環境

- Windows 11 Pro
- WSL2 Ubuntu 20.04
- Visual Studio Code 1.64.0
- Goプラグイン v0.31.0
- Remote WSL v0.64.2
- bash 5.0.17(1)
- anyenv 1.1.4
- goenv d59c0489a133e0233b9bddfd2c1fb29b1e898198

# そもそも何が起きたか？

anyenv + goenvを導入したWSLの環境で、goenv localでバージョンを指定しているリポジトリをvscode + Remote WSLで開いてGoプラグインによる自動ツールインストールを実行したところ、goenv globalで指定したGoのバージョンでビルド＋インストールが実行された。

# 原因

パスの順番が以下になり、shimsにあるgoではなく$GOROOT/binにあるgoバイナリが実行されてしまうため。

```
# WSL内で起動させるbashによって、二回目のeval "$(goenv init -)"の実行によってshims以外のパスが追加される。
$GOENV_ROOT/bin
↓
# WSL内で起動させるbashによって、二回目の~/.bashrcの実行によって以下が追加される。（１回目と同じもの）
$HOME/.anyenv/bin
↓
# Remote WSLによって実行されるvscode-serverkで動くGoプラグインは、goenv globalによって設定されたGOROOTを参照してパスを追加する
# GOROOT=$HOME/.anyenv/envs/goenv/version/[global]
$GOROOT/bin
↓
# vscodeのあれ
$HOME/.vscode-server/bin/[hash]/bin/remote-cli
↓
# 一回目のeval "$(goenv init -)"の実行によって、以下のパスが追加される。
$GOENV_ROOT/shims
$GOENV_ROOT/bin
↓
# 一回目の~/.bashrcの実行によって以下が追加される。
$HOME/.anyenv/bin
↓
/usr/local/binとか・・・
```

bashrcで`eval "$(anyenv init -)"`が複数回呼ばれ、それに伴い`eval "$(goenv init -)"`が複数回呼ばれたときに、goenvが新たにPATHに`$GOENV_ROOT/shims`をパスに追加しない仕組みになっているため、shimsではなく$GOROOT/binにあるgoバイナリを参照してしまう。

# 対処

`eval "$(anyenv init -)"`の実行のあとに、`$GOENV_ROOT/bin`を追加するようにする。

```bash
# anyenv
export PATH="$HOME/.anyenv/bin:$PATH"
eval "$(anyenv init -)"

# goenv
export PATH="$GOENV_ROOT/shims:$PATH"
```

これにより、$GOENV_ROOT/shimsが先に来るためそちらのgoバイナリを呼ぶようになる。

# あとがき

これで、anyenv + goenv + vscodeの環境ができました！

みなさんもよきGo言語ライフを！
XAMPPのapacheがスタートしない件が二日かけて解決

定番な解決法として、サーバーネームが異なるため、ローカルホストの80を8080に変えるといった様々なことを試しても解決しませんでした。

そこで、たまたま私が見つけた解決法があったので紹介します。。

それは、xamppのファイルを右クリックし、アクセスを許可するのところから、アクセスを削除する。

たったこれだけで、apacheが起動しないのが解決しました。あの二日間は何だったのか。。

起動しないで悩んでいる方、（ほぼいないと思う）ぜひ検討してみてください。何かあった時の保証はできません！

では！引き続き勉強を頑張っていきたいです！
macOS の VSCodeで、⌘ + [のショートカットが効かない問題への対処

[Shortcuts containing "cmd" + "\[" (left bracket) does not work](https://github.com/microsoft/vscode/issues/114075)のissueでも報告されているが、
特定の環境下で"cmd" + "["を含むショートカットが機能しないという不具合がある。

およそ1年前に自身のMacでも発生し、解決せず買い替えにまで至ったが、なんと会社から貸与されたマシンでも起きてしまい
これでは仕事にならないのでなんとか解決法を探すことにした

## 結論
**`~/Library/Preferences/com.apple.symbolichotkeys.plist `を削除して再起動する**

issueでも「OS側でキーバインド設定してんじゃね？」という指摘があり、
そんな設定した覚えないんだけどな…と思いつつ
システム環境設定からリセットかけるもうまくいかなかったが、設定ファイル削除すると無事機能するようになった。

はなからVSCode側の不具合と考えていたが、解決法を見るに、
BigSur側が何かの拍子で勝手にキーバインドを設定してしまうという不具合があるのかもしれない。
とにかく解決できてよかった
[Laravel]with()とload() ~備忘録~

##はじめに
この記事はプログラミング初学者による備忘録用の記事であり、また、少しでも他の初学者のお役に立てればと思い書いています。

今回は、Laravelのwith()とload()について再考したので、備忘録としてまとめておきたいと思います。

間違いなどがございましたら、ご指摘のほどよろしくお願い致します。

##どちらもN+1問題を解決する
with()とload()、両者共に特定のモデルに関連するモデルをロードする際に、N+1問題を解決しつつロードすることが可能です。

ドキュメントでは、
with()が``Eager Loading``、
load()が``Lazy Eager Loading``と呼ばれています。

両者ともに、実行するクエリの内容は同じであり、最終的にはどちらも同じ結果を取得することができますが、クエリを実行する際の流れに違いがあります。

##

##with()
``特徴:``
with()は、**Eager Loading**と呼ばれ、最初のクエリ (all(), first(), find() など) の直後に特定のモデルに関するモデルを事前にロードします。

``記述例:``

```.php
<?php
namespace App\Models;

class User extends Authenticatable
{
 public function getUserData()
 {
 $users = $this->with('posts')->get(); 
 }
}

```

``実行されるクエリ``

```.sql
select * from `users`
select * from `posts` where `posts`.`user_id` in (1, 2, 3)
```
上記の実行されるクエリは、同一のアクション内で実行されます。
また、データを取得後、Userモデルにpostsデータを関連付けたモデルのコレクションが完成するので、posts側のデータをカラム指定などで取得することができます。

###・with()他の使用例
``複数のテーブルからデータを取得``

```.php
$this->with(['posts','users'])->get(); 
//with()の中で[]を使い複数指定します
```
``特定のカラムのデータを取得``

```.php
$this->with('users:id, name')->get(); 
//コロン(:)を使い、特定のカラムを指定します(IDは必ず含める必要があります)
```
``ネストした先のテーブルのデータを取得``

```.php
$this->with('posts.comments')->get(); 
//ピリオド(.)で繋げてネスト先のテーブルを指定します
```

``取得するデータに条件付与、並び替えが可能``

```.php
$this->with('posts')->where('user_id', $id)->get(); 
```

##load()
``特徴:``
load()は、**Lazy Eager Loading**と呼ばれ、特定のモデルに関連するモデルを取得する際に、実行するクエリを2つに分割します。

例えば、親モデルが既に取得された後に、リレーションシップをEager Loadingする必要があるかもしれません。
そのような場合に、特定のモデルに関連するモデルのデータを取得することが可能です。
つまり、動的な条件に基づいて後で決定するオプションを提供しています。

``記述例:``

```.php
<?php
namespace App\Models;

class User extends Authenticatable
{
 public function getUserData()
 {
 $users = $this->get();

if($someCondition)
{
 $users = $users->load('posts');
 }
}
}
```
``実行されるクエリ``

```.sql
select * from `users`

-- 2回に分けて実行される
select * from `posts` where `posts`.`user_id` in (1, 2, 3)
```
load()は、2回目のクエリを実行する必要があるかどうかを、動的な条件に基づいて後で決定するオプションを提供します。

``制約を付けることが可能``
with()と同様に、追加でクエリを発行することが可能です。

```.php
$author->load(['books' => function ($query) {
    $query->orderBy('published_date', 'asc');
}]);
```

##終わりに
関連するモデルの全ての項目にアクセスする必要があると予め分かっている場合などは、 with()を使用すべきなのかのと思っています。
[Laravel]$request->input() or $request->get() or others... ~備忘録~

##はじめに
この記事はプログラミング初学者による備忘録用の記事であり、また、少しでも他の初学者のお役に立てればと思い書いています。

今回は、Laravelには``$request->get()や$request->input()``といった、LaravelのControllerにおけるリクエストの受け取り方が複数あり、どれを使用すれば良いのか分からなかったので、解決する為に調べたことを備忘録としてまとめておきたいと思います。

間違いなどがございましたら、ご指摘のほどよろしくお願い致します。

##入力値を取得する様々な選択肢がある
下記のような入力値を取得するメソッドは、似たような働きをしますが1つずつ微妙な違いがあります。

```
public function store(Request $request) {
  $example = $request->input('example');
  $example = $request->get('example');
  $example = $request->example;
  $example = request('example');
  etc...
}
```
他にも、クエリストリングからの入力値を取得したり、入力データの一部を指定して取得することもできますので、詳細は、[Laravel6.x HTTPリクエスト](https://readouble.com/laravel/6.x/ja/requests.html#retrieving-input)を確認して下さい。

##"$request->input()"
``$request->input()``は、公式ドキュメントでも説明されていますので簡単にまとめておきます。

``特徴:``
・input()メソッドは、Illuminate\Http\Requestインスタンスのメソッドであり、**全てのリクエストのHTTP動詞に対してユーザー入力値を取得できます。**

・**全入力値を連想配列として取得するため**に、引数を渡さずにinputメソッドを呼び出すことも可能です。

・input()メソッドは、リクエストのペイロード全体(**クエリ文字列を含む**)から値を取得します。

・リクエストボディ＋クエリストリングを取得し、**リクエストボディが優先**されます。

```example.php
$user->name = $request->input('name');

$input = $request->input();
```

##"$request->get()"
``$request->get()``は、基本的に使わないようにしています。
理由は、下記の特徴があるからです。(間違いがあればご指摘ください)

``特徴:``
・$request->get()では、配列から値を取得することができません。

・引数を取らない場合、input()は値を連想配列で返しますが、get()は引数が必須です。

・リクエストボディ＋クエリストリングを取得でき、クエリストリングを優先して入力値を取得できますが、クエリストリングからデータを取得したい場合は``$request->query('example');``といったように、queryメソッドを利用するので使う必要がない。

##"$request->example"(動的プロパティの使用)
``$request->example``は、Illuminate\Http\Requestインスタンスに対する動的プロパティとして、ユーザーインプットにアクセスすることも可能です。

``特徴:``
・**動的プロパティ**を使用すると、まず初めにリクエストパラメータの中で名前が一致するものを探し、なければ次にルーティングのパラメータを探しに行きます。

```example.php
$name = $request->name;
```
##"request()ヘルパ"
``request()ヘルパ``は、現在のリクエストインスタンスを返したり、入力項目を取得したりします。基本的には、$request->input()と同じ働きをします。

``特徴:``
・引数を空にすると``Illuminate\Http\Request``のインスタンスが返ってきます。

・フォーム・パラメータを取得する場合は第１引数でキーを指定します。

・第２引数にはデフォルト値を指定することもできます。

```example.php
$request = request();

$value = request('key', $default);
```

##まとめ
基本的には、公式ドキュメントにも書かれている``$request->input()``を使用して入力値を取得するのが無難だと思いました。

また、controllerクラスのメソッド内では複数の入力値を指定して使用したいケースが多いと思うので、そのような場合は``only``を使うことで可読性が担保されたままコード綺麗に書けるのではないかと思います。

他にも、``$input = $request->all();``を利用することで、全入力値を配列で取得することができますが、受け取りたくない値まで受け取ってしまう可能性もあるので基本的には使わないようにしたいと思いました。

##参考文献
[Laravel6.x HTTPリクエスト](https://readouble.com/laravel/6.x/ja/requests.html)
[Laravel6.x ヘルパ](https://readouble.com/laravel/6.x/ja/helpers.html)
Routingは問題なさそうだが、404エラーになる

# Routingは問題なさそうだが、404エラーになる
##　現象
・laravel初期画面は表示される（「http://localhost/」で）
・web.phpにRouginを追加しているが、404エラーになる
・調べて出てくるlaravel側の解決策はだいたい行ったが変わらない

##　結果
laravel側ではなく、nginxがおかしいようでした
調べる中でApache用の修正方法も多かったため、nginxと区別して進めていくことが重要と感じました

##　原因
nginx.confの設定が間違っている
下記2つを書き換える

```
root　C:/User/アカウント名/server/htdocs/プロジェクト名/public

location / 
{
　　try_files $rui$uri/index.php?$query_sting;
}
```

以上です。


locationが違うと常時index.phpが表示される状態になったり、rootが設定とずれていたりして時間をかけてしまいました。

nginxを始めたばかりで違うところがあればご指摘いただけますと幸いです。
自分用の記録としても投稿させていただきます。

最後まで読んでいただきありがとうございました。
vagrantでNode.js 環境の作成

# 前提条件
vagrantが既に準備してあること

# 作業directoryの作成

```shell:ディレクトリの作成と移動
mkdir my_vagrant_sample
cd my_vagrant_sample
```
my_vagrant_sampleのところはなんでもいい

# 新しいボックスの作成、起動とログイン

```shell:起動と作成
vagrant init centos/7
vagrant up
vagrant ssh
```

# もしディレクトリの共有をしたい場合
まず共有機能を使うためにはゲスト側にGuest addtionというものをインストールしないといけない。
そのために必要な準備が２つある。

１つ目はvbguestというvagrant用のプラグインのインストール

```shell:vagrant-vbguestのインストール
vagrant plugin install vagrant-vbguest
```

2つ目はゲスト0S側でguest addtionをインストールするためパッケージのインストール。

```shell:ログインと必要なパッケージのインストール
vagrant ssh
sudo yum -y remove open-vm-tools
sudo yum -y install gcc make kernel-devel kernel-headers dkms bzip2 perl
sudo yum -y updateCopy
```

ボックスのリロード
一回ログアウトしてreloadコマンドを使用する。

```shell:
exit
vagrant reload
```

[参考にしたサイト](https://linuxfan.info/virtualbox-guest-additions)

# nodenvのインストール

```shell:gitのインストール
vagrant ssh
sudo yum -y update
sudo yum -y install git
```

```shell:nodenvインストールとシェルの再起動
git clone https://github.com/nodenv/nodenv.git ~/.nodenv
echo 'export PATH="$HOME/.nodenv/bin:$PATH"' >> ~/.bash_profile
echo 'eval "$(nodenv init -)"' >> ~/.bash_profile
exec $SHELL -l
nodenv -v
nodenv 1.4.0+3.631d0b6
```

ちゃんとインストールされていれば最後のメッセージ(ver番号)が表示される。

# nodenv installを使うための準備をする
node-buildをインストール

```shell
mkdir -p "$(nodenv root)"/plugins
git clone https://github.com/nodenv/node-build.git "$(nodenv root)"/plugins/node-build
```

# nodenv updateを使えるようにする

```shell
mkdir -p "$(nodenv root)"/plugins
git clone https://github.com/nodenv/nodenv-update.git "$(nodenv root)"/plugins/nodenv-update
```

# nodeをインストール
使用可能なバージョンの確認とインストール

```shell
nodenv install -l
nodenv install 17.4.0
nodenv local 17.4.0
node -v
v17.4.0
```
ここまで正しくできていれば最後のver番号が表示されます。
これでnodeの環境を作成できました。

あとは

```shell
vagrant snapshot save node_env
```
でこの状態を保存できます。

また

```shell
vagrant snapshot restore node_env
```

でもう一度さっきの状態に戻ることができます。

またボックスとして保存したい場合は下記のコマンドでできます。
またpackage.boxはaddしたら削除してしまって構いません。

```shell
vagrant package
vagrant box add node_env package.box
```

また使いたければこうすればよし。

```
vagrant init node_env
vagrant up
```

以上になります。

# 補足
nodenvの公式サイトだとpathを通すのにシェル毎にスクリプトを容易してくれてるのでそれを見るといい
また使っているシェルの確認方法

```shell:シェルの種類を確認
echo $SHELL
```

[nodenv git](https://github.com/nodenv/nodenv)


また途中で間違って.sshを消してしまうとvagrant sshコマンドでアクセスできなくなってしまうので注意する。解決方法はあるようだが正直わざわざ初心者には面倒だと思うのでディレクトリごと消して最初からやった方がいい気がする。
パスワードの1文字目に「~(チルダ)」を使って痛い目にあった

何を言っているんだと思われるかもしれないですが、気軽にパスワードの1文字目に「~」を使わないほうがいいというお話です。

## 起こった問題

踏み台サーバー経由でサーバーAに接続して作業をしていた時の話です。
いわゆる多段 ssh 接続というもので、リモートワークになってからは結構使われる方も多いかと思います。
サーバーA上で root 権限になろうと `sudo su -` してパスワードを入力したら `Connection to xxx.xxx.yyy.zzz closed.` の文字とともにサーバーAから追い出されてしまいました。

なにかの間違いだろうと何度か挑戦していたのですが、結果はサーバーAから切断され踏み台サーバーに戻る羽目に。。。

そのときに入力していたパスワードが `~.xxxxxxxxxx` のような `~` から始まるものでした。

## 調査

`~` って何か意味があったよなーと思ってどう調べようかと考えましたが、どうも今回は ssh の動作が原因っぽい。

そこで `man ssh` でマニュアルを確認すると、下記のような記述がありました。

> ESCAPE CHARACTERS
When a pseudo-terminal has been requested, ssh supports a number of func‐
tions through the use of an escape character.
A single tilde character can be sent as ~~ or by following the tilde by a
character other than those described below. The escape character must
always follow a newline to be interpreted as special. The escape charac‐
ter can be changed in configuration files using the EscapeChar configura‐
tion directive or on the command line by the -e option.
The supported escapes (assuming the default ‘~’) are:

**`~` チルダさん、エスケープ文字じゃないっすか！**

さらに `man ssh` さんは静かに語ります。

> ~.          Disconnect.

**`~.` は Disconnect...** なるほど。。。

## 原因

レアケースだけど起きうる、今回の流れを整理しました。

1. 踏み台 (bastion) サーバー経由でサーバーAに多段 ssh 接続
2.  `sudo su -` で root 権限になる際に、パスワードを求められる
3. **パスワードが `~.` で始まるものであった**
4. **`~.` は ssh 接続を閉じるコマンド**😇
5. パスワードを入力しているつもりなのに、2文字目の `.` を入力した途端 ssh がサーバーAの接続を閉じて踏み台サーバーに戻る

結果、パスワード入力中に接続が閉じられる奇妙なことに。。。
(ちなみに、パスワードの途中というか2文字目以降に `~.` の文字があっても問題はありません。)

## 対応策

今回は `~/.ssh/config` にエスケープ文字を変える設定を追加して逃げました。

```bash
Host ServerA
    # エスケープ文字を @ に変更
    EscapeChar @
```

これで無事、パスワード入力でも接続を閉じられることはなくなりました。
当然、変更したエスケープ文字 `@.` を入力すると接続は切れます😇

他にも `man ssh` さんいわく、 `-e` オプションでエスケープ文字を都度変えることも可能だそうです。
今回は次回接続時に同じ罠にはまらぬようファイルに設定として書きました。

これはなんかゴリ押し感が。。。なんか他に正しい解決策があるような気がします。。。

## 感想

悪いことは言わない。 `~` チルダから始まるパスワードは止めとけ。

…という気持ちになりました。
ssh の `~` エスケープ文字は `~.` だけでなく、 `~B` や `~C` などいろいろありますので。。。

今回は手作業でログインしていましたが、自動化を考えるとやはりパスワードでこのような動きをされるのは困ります。
いっそ、記号から始まるパスワードは念の為止めておいたほうがいいのかもしれません。

皆様のパスワード設定規則の一つの考慮案になれば幸いです。
slackのEvent apiを使ってチャンネルのメッセージをchatworkに転送する


slackのチャンネルにメッセージが投稿されたことをトリガーにしてGASでchatworkに転送する実装で
slackのEvent apiを使っての連携にてこずったのでおさらい用記事。
色んな記事みてごちゃごちゃになったけど結構簡単にできた:sweat_smile:

##slackのチャンネルとGASの連携

古い記事はWebHookを使って実装すると簡単にできる！みたいな記事が多かったのですがslackのapiでは非推奨・・でした
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/543815/d09199fa-9880-3a66-5eb7-ce81b1c1d7a3.png)

:::note alert
将来的には非推奨となり、削除される可能性もあります。使用することはお勧めしません。
:::
みたいなことが書かれてます:confounded:WebHookは使えないなぁ・・・
という事でSlackの[EventAPI](https://api.slack.com/apis/connections/events-api)を使ってGASと連携することにしました！


###Event api
Event APIのEvent Subscriptionsは、Slackへの投稿やリアクションなどのコマンドがあった場合、
用意したサーバにSlackからほぼリアルタイムにリクエストが飛んできて、それに対しての処理を行うことができる。

https://api.slack.com/apis/connections/events-api


###まずはGASでプログラムを書いていく
[GASでプロジェクト作成](https://blog-and-destroy.com/35768)

```test.gs
function doPost(e){
  var params = JSON.parse(e.postData.getDataAsString());
  return ContentService.createTextOutput(params.challenge);
}
```
↑これをウェブアプリケーションとして公開
デプロイの方法:point_right_tone4:（https://auto-worker.com/blog/?p=3565）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/543815/37c8da22-710b-969e-2d62-a20952084191.png)

URLをコピーしておく


###Slackアプリを作る

:point_down_tone5:ここから作成

https://api.slack.com/apps

:point_down_tone3:アプリを作成（Create New App）してEvent Subscriptionsを選択、流れはこちらの記事が一番わかりやすかったです

https://www.pnkts.net/2020/03/28/slack-event-api

####つまずいたところ

:::note warn
連携したかったチャンネルはプライベートチャンネルだったためプライベートチャンネルのメッセージが取得できる
eventを選択していなかった。
:::
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/543815/15608977-2865-8667-0f3e-299499434f49.png)
:pencil2:message.groups は「プライベートチャンネルにメッセージが投稿されることがトリガー」



https://api.slack.com/events?filter=Events

#####:point_up_2_tone5::point_up_2_tone3::point_up_2_tone1:ここから自分のやりたい事に関するEventを探してください

###メッセージを取得したいチャンネルに作ったSlackアプリを追加する

チャンネルのところで右クリック
　　　↓
チャンネル詳細を開く
　　　↓
インテグレーション
　　　↓
アプリを追加


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/543815/be6edde8-75d6-0aef-ddaf-dc46203e43db.png)

#####先ほどのつまずいたところの部分で、何がきっかけで気づけたかというと・・・
:::note warn
連携したかったチャンネルはプライベートチャンネルだったためプライベートチャンネルのメッセージが取得できる
eventを選択していなかった。
↓　↓　↓
作ったSlackAppのEventapiは何が設定されているか確認できる
:::

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/543815/3becda93-9b93-7203-b1aa-937221d98029.png)
先ほど追加したAppの設定を押すと↓の画面が出てくる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/543815/51d842a5-4182-646f-ee17-fbc19f167c9a.png)

連携できない場合何ができるか、設定されているか書かれているので自分がやりたい事がちゃんと設定されているか確認してみて下さい！



##ChatWorkとGASの連携

記事は古いですがチャットワークは割と簡単に実装できました！

https://ameblo.jp/youcomehome/entry-12423380528.html

##完成コード
```test.gs
function doPost(e){

 var params = JSON.parse(e.postData.getDataAsString());
 notifyToChatwork(params.event.text);

 return ContentService.createTextOutput(params.challenge);
}

function notifyToChatwork(message) { 
  var client = ChatWorkClient.factory({token: "チャットワークAPI"});　
  client.sendMessage({
  room_id:ルームID, 
  body: message});
}
```


出来てしまえばすごく簡単だと思いましたが、、、、なかなかてこずりました。:sweat_smile:
【Rails】form_withで送信した値をparams[:◯◯◯]を使ってコントローラーで取り出す方法。

フォームに入力した値をコントローラーで取り出したいことがよくあるのですが、いつも忘れてググっているのでメモに残しておきます。

##結論
###送信したデータ一式

```
params[:<送ったモデル名>]
```

###特定のカラムのデータ

```
params[:<送ったモデル名>][:<カラム名>]
```

##具体例

例えば、フォームが以下のような場合。

```
<%= form_with(model: @glider_flight, local: true) do |f| %>
  # フォームの各パーツ
<% end %>
```

`glider_flight`というモデル宛てにデータを送信したら、コントローラーでは

```
　　params[:glider_flight]
```

と記述する。

binding.pryで処理を止めて中身を確認すると、次のようなデータが取れていました。

```
=> #<ActionController::Parameters {"date"=>"2022-02-08", "departure_and_arrival_point"=>"", "glider_type"=>"", "glider_ident"=>"", "is_winch"=>"true", "flight_role"=>"機長", "takeoff_time"=>"21:02", "landing_time"=>"21:09", "release_alt"=>"400", "number_of_landing"=>"1", "takoff_and_landing_place"=>""} permitted: false>
```

また、この中の`takeoff_time`カラムに入った値を取り出したいときは

```
> params[:glider_flight][:takeoff_time]
=> "21:02"
```

同様に、`date`カラムは

```
> params[:glider_flight][:date]
=> "2022-02-08"
```

間違っていたらやさしく教えてください。

##参考サイト

https://railstutorial.jp/chapters/sign_up?version=5.1
VSCodeのブレークポイントを使ってC#スクリプトのデバッグをする

###ブレークポイントとは
ブレークポイントは、コンピュータプログラムを実行する際に、開発者の指示で強制的に実行を一旦停止する箇所のこと。実行中のプログラムの状態を確認し、デバッグするのに使う。


###やり方
以下の記事にまとまっているため、この記事では割愛する。
https://qiita.com/sawasaka/items/47d480f55ffde0448876

###役に立った場面

以下の場面で、indexSpeedがnullでだったので、ブレークポイントを打って実行中の状態を確認した。
![スクリーンショット 2022-02-08 21.05.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/671703/2e48bf1d-0dec-677d-dcec-740b3b35e407.png)
indexTipにカーソルを合わせると、以下のように実行中の状態を確認することができる。こちらの画像は修正済みのものだが、デバッグ時にはnullと表示され、問題の原因が判明した。
![スクリーンショット 2022-02-08 21.11.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/671703/9e018be4-638d-0de6-618b-861c6501050a.png)





###参考サイト
https://e-words.jp/w/%E3%83%96%E3%83%AC%E3%83%BC%E3%82%AF%E3%83%9D%E3%82%A4%E3%83%B3%E3%83%88.html