OmniAICreator/Qiita-1.07M huggingface dataset:
みんな話すのが苦手

デッサンも
プログラミングも
必修じゃなくていいので
打ち合わせとか議論の訓練を必修にしてほしい

社会に出て感じたのは**大人数がいる場で話すのが下手な人が多いなー**という事。
それによって無駄な打ち合わせ・議論がたくさん見受けられる。


下手な人のケース
-

+ **一人で延々話し続ける**
割とよく居るパターンの人
考えながら話してるのか要点がまとまってない。
コメントのような関係ない部分まで話す。
なので、話が長い割に何言ってんのか良く判んない。

+ **伝わらない・理解されていない**
話した本人以外　？？？　状態にする人
伝わってないからもう一回話すが、
同じことを話すのでやっぱり伝わらない。
時間と酸素が浪費されてゆく

+ **流れをぶった切る**
自分が言いたい内容だけを言いたいので、発言できる隙を見つけては言いたいことだけ言う。
無理やり議題をそっちに移行させようとするので、進行している人がちゃんと制御しないと尻切れトンボが大量発生する

+ **話聞いてない**
話を聞いていないので、Aという事に決まった後に
で、これどうする？的な発言をするので、場が凍る。(え、今その話終わったじゃん・・・

+ **小規模な議論を始める**
全体の進行とは別に個別で相談事を初めてそっちに集中し始めてしまう。
邪魔にならないように話してるつもりかもしれないが、割とうるさい。
全体の進行で本人に振られると、話を聞いていないので即答できない。

+ **なるほど全部理解した**
誰かが話している最中に全部理解した気になって話を乗っ取ったり、終わらせたりする。
大体理解できてないので、最終的に最初に話してた人が訂正する。


原因
-
大体話す側聞く側双方に問題がある


+ **喋るスピード**
大体みんな早口。
早口だと聞く側も大変なのでインプットが追いつかない。
自分でもちょっとゆっくりかな？と思うくらいのスピードで話すと改善されることが多い。
例としては　国会議員の石破さん。
あれは極端な例だけどもあれくらいゆっくり話すと聞きやすい。

+ **句読点**
※2021/11/10追記
「AなんだけどもBって可能性もあるからCっていう対応を取るんですがその時にDという要素が出てきて～～～」
といった具合に全く区切りなく話してしまうと、1つの文章に込められた要素が多すぎて聞いてる側が処理しきれない。
喋りながら思いついたことをどんどん追加していく人にありがちで、話してる側も実は考えがまとまってない事が多い。
要素を詰め込み過ぎないように、喋るときも適度に区切って話すようにすると、話す側も聞く側も処理しやすくなる。
自然と話すスピードも落ち着く。
例) A　または B　という可能性がある。　そこでＣという対応を取る。　だがその際にＤという要素がでてきて～

+ **語彙力**
やたら漢語・横文字を織り交ぜて話す人がいるが、相手がそれらの意味を知っていないと無意味。
話す人が語彙力のレベルを上げて話すと良い。
ここで言う語彙力は**難しい単語を使うという事ではなく**、
10人が聞いて10人が同じ内容として理解できる説明をできるようになる事。
その為の語彙力。
文章を読んだり、落語を聞いたりとにかく多くの語彙に触れることで強化できる。
抽象的な表現を避け、主語・述語をしっかりと意識して話すだけでもかなり改善されることは多い。
追記(2021/06/09)：
意味を取り違えられやすい単語の使用は避けたほうが良い。
https://qiita.com/9boz/items/730abd05cfc628a922ae

+ **相手のリアクション**
聞いてる人のリアクションを見ていないことが多い。
相手のリアクション次第では話を続けても無駄なことがあるので、相手のリアクションを見ながら話を進めた方がいい。
場合によっては、相手に話を振るのもいい
例えば
**メモ取るのに一生懸命すぎる人**
大体メモが追いつかなくて話が聞けなくなるので、ペンなどの手元の様子をみて
落ち着くまで少し待ってみる。
**ぼーっとしてる人**
どう思います？とか話を振ってみる
**別の事やってる人**
なにかありました？とやんわり聞いてみる
**考え込んでる人**
何か気になる点ありました？と聞いてみる
**頷いてる人**
2パターン居て内容理解した上で頷いてる人と、理解しているように見せようとして頷いてる人も居る。
後者の場合は、本人が批判されてても頷いてるので見てると滑稽。
追記：出会った人はこの2パターンしかいなかったけど、批判されててもそれを納得した上で頷いている方もいる様子。気になったら、どう思います？って聞いてみればいい。


+ **話を最後まで聞かない**
最後まで聞きましょう。
言いたいことがあっても聞きましょう。
言いたいことがあるならメモっておきましょう。
自分の想像力に自信があったとしても、最後まで聞かないで想像で補うのは辞めた方がいい。大体間違ってる方が多い。

+ **理解できないときは言う**
話を聞いたうえで理解できなかった部分は遠慮なく言う。
言わないと　発言者は　このレベルの話し方で理解される　と認識して、以後改善されない。


+ **全体進行者**
不在だと大体収拾がつかなくなる。
全体を見渡して話を回し、全員の理解度を推し量りながら進めてくれる人が居ると良い。
この人は議論には積極的に加わらなくても問題ない。
人によっては、ちょっとあやふやな部分があったり　話が嚙み合ってないときなどには　理解できない人を演じて質問したりする。

ただ打ち合わせの数をこなすだけでは意味がなく、
質を高める為に色々やってみる事がお勧め

ブレインストーミングは明確にルールを設定して議論するので非常にお勧め

(´A)一人でやってもいいけど、啓蒙活動も行わないと改善されんのよねー

追記
原因と対処は自身で試してみて効果があったもの。
WindowsのVSCodeでGドライブ内のlatexコンパイルに失敗する話

# 対象の症状
OS: Windows
VSCodeのLatex Workshopを使用
Google Drive内のtexファイルをコンパイルするとコンパイルエラー
ログを確認するとファイルパスが文字化けしている

# 原因
LaTeX Workshopはそもそもファイル名が日本語のパスだとコンパイルできず、
Google Driveのデフォルトではマイドライブとかが日本語になっているため起きる症状らしい
報告: https://note.com/ojk/n/n6c8f6a30b67a

# 解決策1
バックアップと同期ではなく、
__[デスクトップ版Google Drive](https://support.google.com/a/answer/7491144/%E3%83%91%E3%82%BD%E3%82%B3%E3%83%B3%E7%89%88-google-%E3%83%89%E3%83%A9%E3%82%A4%E3%83%96%E3%82%92%E5%B0%8E%E5%85%A5%E3%81%99%E3%82%8B)__なるものを使用する。
[この記事](https://dev.classmethod.jp/articles/pc_google_drive_personal_use/)に詳しく書いてあるのでがんばってインストールしてください。

インストールをしたら、ファイルを英語名にするよう設定を変更する。
[ドキュメント](https://support.google.com/a/answer/7644837/%E3%83%91%E3%82%BD%E3%82%B3%E3%83%B3%E7%89%88-google-%E3%83%89%E3%83%A9%E3%82%A4%E3%83%96%E3%82%92%E8%A8%AD%E5%AE%9A%E3%81%99%E3%82%8B?hl=ja)によるとDisableLocalizedVirtualFoldersをTrueにすれば良いらしい

# 解決策2
luaTexのオプションで回避できるらしい？(未検証)
https://qiita.com/moinslut/items/bc1d1b1e13cb38377406
### これでコンパイルできるはず...!

# 余談
筆者は解決策1でコンパイル通ったのですが、よくよくみたらドライブ内のファイル名にも日本語名をつかっていた。
なぜできたのかよくわかっていません... マイドライブの全角空白が良くなかったのか...？
Laravel ヘルパ関数のconfigを使って連想配列からキーとバリューを取得する方法

こんにちは、JeffTechです。

# 説明
今回は、configディレクトリの中に自作した`words.php`の連想配列から、データを取り出す方法を書いていきます。

コード内にてハードコードで書くよりも、こちらに必要な文字データをまとめておいて、config()で取得するとメンテナンス等しやすくなるので、とてもおすすめです。

# 開発環境
OS: MacOS
PHP: 7.3.11
Laravel: 6.2

# 実装
今回自作した`config/words.php`は以下の通りです。

```php:words.php
<?php

return [
    'fruits' => [
        'apple' => ['APPLE' => 'りんご'],
        'banana' => ['BANANA' => 'ばなな'],
        'grape' => ['GRAPE', 'ぶどう'],
    ],
    'snack' => [
        'chips' => [
            'potato' => ['POTATO' => 'ポテトチップス'],
            'sweetPotato' => ['SWEET POTATO' => 'さつまいもチップス'],
        ],
        'gumi' => [
            'soft' => ['SOFT' => 'やわらかいグミ'],
            'hard' => ['HARD' => 'ハードグミ'],
        ]
    ],
];
```

この中から値を取得するためには、PHPのビルトイン関数である`key()`とLaravelのヘルパ関数である`config`の２つを使用して取得できます。

ControllerやModelなどで下記のようなコードを記述することで、`config/words.php`のデータを取得することができます。

今回は例として、Controller内で取得しています。
※適当に作成したConfigCheckControllerで動作確認を行っております。

```php:ConfigCheckController.php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class ConfigCheckController extends Controller
{
    public function index()
    {
        // BANANA と出力される
        $keyTest1 = key(config('words.fruits.banana'));

        // SWEET POTATO と出力される
        $keyTest2 = key(config('words.snack.chips.sweetPotato'));
        
        // ばなな と出力される
        $valueTest1 = config('words.fruits.banana.BANANA');
        
        // さつまいもチップス と出力される
        $valueTest2 = config('words.snack.chips.sweetPotato.SWEET POTATO');

        // 取得確認用
        dd($keyTest1, $keyTest2, $valueTest1, $valueTest2);
        return view('welcome');
    }
}
```

しっかり取得できましたか？

# 最後に
少しでも役に立った！という時は、いいねをポチッとして
フォローしてくださると嬉しいです、、、笑

役に立たなかった時は、怒らないでコメント頂けますと幸いです笑

Twitterもやってますので、よかったら見てみてくださいね！
https://twitter.com/jefftechsaku
jsonnetでkubernetesのyamlファイルを環境ごとに管理する

## jsonnetを使う意味
- yamlだと値がダブってしまう
- 環境ごとで使い分けるためにkustomizeというのがあるが難しい

## ソース
- jsonnetコマンドに引数で環境変数を渡せるので、分岐させて環境ごとの変数を埋め込むようにする
- std.manifestYamlStreamを使うことで、リソースの区切り文字(---)も出力してくれるので、ひとまとまりで１つのファイルで管理することができる
    - https://jsonnet.org/ref/stdlib.html
- env.jsonnetファイルをvar変数にimportすることで、var.portみたいな感じで使える
- local appnameとすることでそのファイル内で変数として使える

```env.jsonnet
if std.extVar('ENV') == 'dev' then
{
  port: 80,
  allow_ipaddress: ['12.34.56.78/32', '87.65.43.21/32'],
}
else if std.extVar('ENV') == 'stag' then
{
  port: 80,
  allow_ipaddress: ['22.34.56.78/32', '87.65.43.21/32'],
}
else if std.extVar('ENV') == 'prod' then
{
  port: 80,
  allow_ipaddress: ['32.34.56.78/32', '87.65.43.21/32'],
}
```


```nginx.jsonnet
local var = (import 'env.jsonnet');

local appname = 'nginx-nlb';

local development = {
  apiVersion: 'apps/v1',
  kind: 'ReplicaSet',
  metadata: {
    name: 'nginx-replicaset-nlb',
  },
  spec: {
    replicas: 3,
    selector: {
      matchLabels: {
        app: appname,
      },
    },
    template: {
      metadata: {
        labels: {
          app: appname,
        },
      },
      spec: {
        containers: [
          {
            name: appname + '-container',
            image: 'nginx:1.12',
            ports: [
              {
                containerPort: 30082,
              },
            ],
          },
        ],
      },
    },
  },
};

local service = {
  apiVersion: 'v1',
  kind: 'Service',
  metadata: {
    name: 'aws-nlb',
    annotations: {
      'service.beta.kubernetes.io/aws-load-balancer-type': 'nlb',
    },
  },
  spec: {
    type: 'LoadBalancer',
    ports: [
      {
        name: 'http-port',
        protocol: 'TCP',
        port: var.port,
        targetPort: var.port,
        nodePort: 30082,
      },
    ],
    selector: {
      app: 'nginx-nlb',
    },
    loadBalancerSourceRanges: var.allow_ipaddress,
  },
};

std.manifestYamlStream(
  [development, service],
  indent_array_in_object=false,
  c_document_end=true
)
```

## 使うとき
- --ext-strにつなげる

```
jsonnet -S nginx.jsonnet --ext-str ENV=dev
```

出力

```
---
"apiVersion": "apps/v1"
"kind": "ReplicaSet"
"metadata":
  "name": "nginx-replicaset-nlb"
"spec":
  "replicas": 3
  "selector":
    "matchLabels":
      "app": "nginx"
  "template":
    "metadata":
      "labels":
        "app": "nginx"
    "spec":
      "containers":
      - "image": "nginx:1.12"
        "name": "nginx-container"
        "ports":
        - "containerPort": 30082
---
"apiVersion": "v1"
"kind": "Service"
"metadata":
  "annotations":
    "service.beta.kubernetes.io/aws-load-balancer-type": "nlb"
  "name": "aws-nlb"
"spec":
  "loadBalancerSourceRanges":
  - "12.34.56.78/32"
  - "87.65.43.21/32"
  "ports":
  - "name": "http-port"
    "nodePort": 30082
    "port": 80
    "protocol": "TCP"
    "targetPort": 80
  "selector":
    "app": "nginx-nlb"
  "type": "LoadBalancer"
...
```

### kubectl applyするとき
```
jsonnet -S nginx.jsonnet --ext-str ENV=dev | kubectl apply -f -
```
【C#】リフレクションによる速度劣化の改善アプローチ

## 【C#】リフレクションによる速度劣化の改善アプローチ
### はじめに
実運用で使用しているアプリがリフレクションを頻繁に使用しているので、処理速度を改善出来る余地があるかどうかサンプルプログラムを作成して確認しました。
改善ポイントはループ内でリフレクションを行っていた点をループ外で行うようにしました。

## 環境
* Window10 64bit
* .NET Framework 4.7.2
* Windows アプリケーション

## サンプルプログラムの概要
![リフレクション画像1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1577269/650bcd00-0172-0208-a73b-05149b927e38.png)

計測①ボタンは1000万回繰り返すループ内でリフレクションによるクラスの型取得とインスタンス化を行い、インスタンス化したクラスのメソッドを呼び出します。
ループを抜けた後は処理時間を計測②ボタンの隣のラベルに出力します。
計測①ボタンのコードは下記の通り。

```Form1.cs
		/// <summary>
		/// 計測①：ループ内でクラスの型取得とインスタンス化を行い、メソッドを実行する
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		private void button1_Click(object sender, EventArgs e)
		{
			var sw = new Stopwatch();
			// 計測開始
			sw.Start();

			for (int i = 0; i < 10000000; i++)
			{
				// クラスの型取得
				Type cType = Type.GetType("UI_Module.TestFunc");

				if (cType != null)
				{
					// クラスのメソッド取得
					MethodInfo m = cType.GetMethod("Func1");

					if (m != null)
					{
						// インスタンス化
						object obj = Activator.CreateInstance(cType);
						// メソッド実行
						m.Invoke(obj, null);
					}

				}

			}

			// 計測終了
			sw.Stop();

			// 結果表示
			var ts = sw.Elapsed;
			label_Msg.Text = string.Format(
				"計測①" + Environment.NewLine
				+ "{0}秒{1}ミリ秒", ts.Seconds, ts.Milliseconds);
		}

```

計測②ボタンはループの外でクラスの型取得とインスタンス化を行い、ループ内ではインスタンス化したオブジェクトを使いまわしてメソッドを実行します。
計測②ボタンのコードは下記の通り。

```Form1.cs
		/// <summary>
		/// 計測②：ループの外でクラスの型取得とインスタンス化を行い、ループ内ではメソッド実行のみ行う
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		private void button2_Click(object sender, EventArgs e)
		{
			var sw = new Stopwatch();
			// 計測開始
			sw.Start();

			// クラスの型取得
			Type cType = Type.GetType("UI_Module.TestFunc");
			MethodInfo m = null;
			object obj = null;

			if (cType != null)
			{
				// クラスのメソッド取得
				m = cType.GetMethod("Func1");

				if (m != null)
				{
					// インスタンス化
					obj = Activator.CreateInstance(cType);
				}

			}

			for (int i = 0; i < 10000000; i++)
			{
				if (m != null && obj != null) 
				{
					// メソッド実行
					m.Invoke(obj, null);
				}
			}

			// 計測終了
			sw.Stop();

			// 結果表示
			var ts = sw.Elapsed;
			label_Msg.Text = string.Format(
				"計測②" + Environment.NewLine
				+ "{0}秒{1}ミリ秒", ts.Seconds, ts.Milliseconds);
		}
	}
```

## 結果
処理速度を比較した結果、計測②が速くなっていました。

| 計測①  | 56秒240ミリ | 
|:-----------|------------:|
|**計測②**       |**20秒694ミリ**|
|**改善率**     |**63%**|

サンプルプログラムは１クラス１メソッドの構成のため、劇的に速くなることはありませんでしたが、実運用で使用しているアプリの場合はクラスやメソッドの数が膨大であるため、さらに効果が上がるのではないかと感じました。

##終わりに
これまでにも処理速度改善のアプローチとしてループ内で行っている重い処理をループ外に移動することで処理速度の改善を図ってきた経験はありましたが、リフレクションにおいても実際にサンプルプログラムを作成してみて効果があることが実感できました。
[Ruby] ハッシュについてまとめる

## はじめに
前回配列についてまとめてみて、個人的に配列とハッシュは組み合わせると力を発揮するセットのように思っていますので、前回の続きではないですが、今回はハッシュについてまとめたいと思います。

## ハッシュとは
ハッシュはデータとその名前の2つを1セットの要素として持つ値です。

ハッシュではデータを**バリュー**、その名前を**キー**と言います。
ハッシュも配列のように複数のデータを持つことができますが、配列は順番でデータの管理をしていたのに対し、ハッシュはキーで管理します。

またこの管理方法をキーバリューストアと言います。


## なぜハッシュを使うのか
配列でデータを管理をするには限界があります。
例えば、身長を管理している配列があるとします。
そこにはたくさんの身長が入っていますが、誰の身長かはわからないですよね。

そこで名前も保存しようとして、そこに名前を放り込むと、余計ごちゃごちゃになってしまうのが明白です。

```Ruby
height = [ 160, 165, 162, 170, "花子", "太郎" ]
```

↑めちゃくちゃです 笑

ハッシュはこう言うデータを扱うときに力を発揮します。

## ハッシュを生成
ハッシュの生成方法は{}を使います

```
変数 = {}
```

これで空のハッシュは完成です。配列同様初めから要素を持って生成させることも可能です。
ハッシュはキーとバリューの2つで1セットなので記述の仕方も少々違います。

```
変数 = { キー1 => バリュー1, キー2 => バリュー2, キー3 => バリュー3}
```

こんな感じで書きます。キーとバリューを =>（ロケットハッシュ）でセットにして記述します。

で、毎回思うのですが、紹介しておきながらあまりこの書き方しないんですね。
どの参考書でも結構この書き方をこってり説明してから、**シンボル**の説明があって、基本的にはこっち使いますって言われて、先に言って！て言いたくなります 笑

ただ、様々な書き方があると言うことは知っておかないと、そういうコードに出会ったときに戸惑ってしまうので、知っておいた方がいいのはいいでしょう。



そのシンボルってものなんですが、
見た目は文字列のようですが中身は数値になっている値だそうです。
シンボルを宣言するときは先頭に:コロンをつけます。

シンボルをハッシュに用いる場合、このように書きます。

```
hash = { name: "John"}
```

ハッシュに具体的な情報を与えて生成してみます

```Ruby
student = { "name" => "John", "age" => 10 }
teacher = { name: "Mike", age: 25 }
```

## ハッシュに値を追加

配列で言えば、 <<を使って値を追加しました。
ハッシュの場合、配列で添字を指定するように[]の中にキーを記述して、バリューを代入します。

```
ハッシュ[追加するキー] = 値
```

先ほどのteacherに担当教科を示す値を追加します。

```Ruby
student = { name:  "John", age: 10 }
teacher = { name: "Mike", age: 25 }

teacher[:subject] = "English"
```

これでteacherに新たにsubjectというキーが追加されました。

## 指定したハッシュの値を取り出す

ハッシュではキーを指定することでバリューを取り出します。
配列でいう添字の代わりにキーを指定する感じですね

今までのstudent,teacherの例で先生の名前を取り出したいときは

```Ruby
puts teacher[:name]
```

これでteacherの名前、Mikeが表示されます

## ハッシュの値を書き換える

これも配列と似てますね。
添字の代わりにキーを指定します。

teacherの名前を変えましょう

```Ruby
teacher[:name] = "Emma"

puts teacher[:name]
```

これでEmmaが表示されるはずです。

## ハッシュの限界
ハッシュはキーでバリューが管理でき、これはこれで大変便利なんですが、ハッシュにも限界があります。

ハッシュを指定するために変数を用意するのですが、増えるとその分変数を用意しなくてはならないので、変数名が一貫せず管理しにくいのです。

そこでハッシュと配列の合わせ技で解消できます。

## 配列とハッシュの合わせ技

配列の中に複数のハッシュを入れてあげることで、取り出すときに添字とキーを指定してあげることで特定の値を取り出せるようになります。

```Ruby
students = [{ name: "太郎", height: 160}, { name: "花子", height: 154}, { name: "次郎", height: 166}]
```

といった具合で組み合わせます。
もし花子の身長が欲しかったら　students[2][:height]と記述することで取り出すことができるのです。


## 最後に
配列とハッシュの理解はデータを管理して扱う上でとても重要な役割を果たしています。高度なアルゴリズムを作れるようになるためにも今一度復習しておきたいものです。
【Nuxt.js】Duplicate named routes definitionが出たときの対処法

Nuxt.jsで`yarn dev`したときに`Duplicate named routes definition`のWARNが出てしました。
そのときに対処した備忘録です。

開発環境
多言語対応: nuxt-i18n
HeadressCMS: microCMS
での状況です。

```
 WARN  [vue-router] Duplicate named routes definition: { name: "seminar___en", path: "/en/seminar/page/:p" }                                                                                10:22:18


 WARN  [vue-router] Duplicate named routes definition: { name: "seminar___ja", path: "/ja/seminar/page/:p" }                                                                                10:22:18


 WARN  [vue-router] Duplicate named routes definition: { name: "seminar___ja___default", path: "/seminar/page/:p" }      
```

原因はrouterの定義でpathとnameが同じ名前になっているからのようでした。

```nuxt.config.js
  router: {
    extendRoutes (routes, resolve) {
      routes.push({
        path: '/seminar/page/:p',
        component: resolve(__dirname, 'pages/seminar/index.vue'),
        name: 'seminar'
      })
    }
  },
```
nameを変更すればWARNはでなくなりました。

```nuxt.config.js
  router: {
    extendRoutes (routes, resolve) {
      routes.push({
        path: '/seminar/page/:p',
        component: resolve(__dirname, 'pages/seminar/index.vue'),
        name: 'seminarpage'
      })
    }
  },
```

microCMSでrouterを増やしていくときはこの辺の注意を！
APIベースで管理画面作っててBasic認証つけたらsafariで・・・

変なわかりにくいタイトルつけてしましました。

この問題が起きた経緯です。

 * 今風にヘッドレスで管理画面つくる フロントはVueでバックエンドはLaravel
 * ログインはJWTでやるよ！ Authorization: Bearer xxxxxxでAxiosでおくるよ
 * 実装できたよ
 * 管理画面全体にセキュリティのためにBasic認証かけてほしいよ
 * .htaccessで管理画面領域だけかけたよ。APIにはかけてないよ （WebもAPIも同じドメイン）
 * safariだけ管理画面の挙動がおかしいよ

ってな感じになりました。

要は以下にかかれていることですね。↓

https://qiita.com/ksakiyama134/items/efad0e48464e0f501d76

これは罠でした。
対処法は何かいいのがあるかもなのですが、ない場合、APIのトークンはAuthorizationを使わずカスタムヘッダー使うか、パラメータにいれるかですかね。やだやだ。

管理画面はBasic認証つけてとかなりがちなので、Vueとかでヘッドレスな開発をしている場合は、気をつけましょう。
Node バージョン管理ツール n インストール時にエラー


## 問題

```
$ brew install n
$ n lts
```

をすると、以下のエラーが出ました。

```
Error: sudo required (or change ownership, or define N_PREFIX)
```

## 解決法

`.bash_profile` に以下を追加する。

```
export N_PREFIX=$HOME/.n
export PATH=$N_PREFIX/bin:$PATH
```

ターミナルを閉じて、開き直して確認。

```
$ which node
/Users/[your-user]/.n/bin/node
```

## 参考

https://github.com/tj/n#optional-environment-variables
IBMCloud Host Migration/Lincense更新に必要なFW許可

##目的
IBMCloudでホストマイグレーション（今あるVSIやVPXを違うハイパーバイザーに移す）や
ライセンスの更新など、IBMCloud側の管理通信が発生する場合に必要なFW許可を記載

##許可対象
下記ドキュメントに記載があるが、ちょっとわかりにくい
https://cloud.ibm.com/docs/hardware-firewall-dedicated?topic=hardware-firewall-dedicated-ibm-cloud-ip-ranges#back-end-private-network

###対象プロトコル
https://cloud.ibm.com/docs/hardware-firewall-dedicated?topic=hardware-firewall-dedicated-ibm-cloud-ip-ranges#-
・ICMP – ping (トラブルシューティングをサポートするため)
・すべての TCP/UDP ポート

###対象セグメント
https://cloud.ibm.com/docs/hardware-firewall-dedicated?topic=hardware-firewall-dedicated-ibm-cloud-ip-ranges#-

**許可対象は４つ必要**
***DAL01/DAL10/DAL12/WDC04 + 自分が使っているデータセンタのセグメント***
ドキュメントにはDAL12は記載がないが、許可しておく必要がある。

DAL01:10.0.64.0/19
DAL10:10.200.80.0/20
DAL12:10.200.112.0/20
WDC04:10.3.160.0/20 および 10.201.0.0/20

+

TOK02:10.3.64.0/20
TOK04:10.201.176.0/20
TOK05:10.201.192.0/20
Rails + Vue.jsでHello Vue! できなくなった（Webpacker::Manifest::MissingEntryError）

RailsとVue.jsの組み合わせ方を学習したいと思い、Techpitさんでこちらの教材を学習。
<a href="https://www.techpit.jp/courses/123">
Rails × Vue.js でメモアプリを作成しながらモダンな開発を学ぼう！
</a>

1回目に学習した際は何の問題もなく構築できたのですが、約２週間後に復習しようと思い2回目の学習を実施したところ、Hello Vue!と出力する部分で

![スクリーンショット 2021-06-03 22.07.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/626568/6e035543-241f-43aa-02a1-5cd5c14123e8.png)


苦労しましたが、何とか解決できたのでメモします。

<h2>エラーが出た箇所</h2>
rails webpacker:install:vue してルーティング、コントローラー、ビューをいじり、Hello Vue!とブラウザに表示する

<h2>エラー内容</h2>
<font color="red">Webpacker::Manifest::MissingEntryError</font>
<font color="red">webpacker can't find hello_vue in ~/memo-app/public/packs/manifest.json. Possible causes:
1. You want to set webpacker.yml value of compile to true for your environment
   unless you are using the webpack -w or the webpack-dev-server.
2. webpack has not yet re-run to reflect updates.
3. You have misconfigured Webpacker's config/webpacker.yml file.
4. Your webpack configuration is not creating a manifest.
</font>


1回目に作成したmemoアプリを確認したところ、どうもpublicフォルダ以下にpacksフォルダとmanifest.jsonファイルが生成されていないことが原因のようでした（上の４）。

![スクリーンショット 2021-06-03 22.16.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/626568/b149f34c-9cd7-64bb-af17-81b0dbc5db0d.png)


なので、「vue.js manifest.json」「Webpacker::Manifest::MissingEntryError manifest.json」と思いつく限りのキーワードで検索をかけ、日本語・英語問わず調べ、

①
解決方法として提示されていることを試す
↓
②
<font color="red">Webpacker::Manifest::MissingEntryError</font>
<font color="red">webpacker can't find hello_vue in ~/memo-app/public/packs/manifest.json
</font>のエラー表示
↓
③
アプリ削除
↓
①に戻る
と、ひたすら試したのですが、無常にも全く解決しませんでした・・・。
無限ループに陥り、もうダメかと思っていたところ、
・コマンド実行のたびにwebpackのバージョンが云々みたいな内容が何回も表示されていたのに気づいた
・何かしらのバージョンが変わったことでできなくなったのでは？（RailsチュートリアルにGemのバージョンが変わると動かなくなることがよくあると書いてあったので）
と思い、Gemfileのwebpackerのバージョンを変えてみるかと思い立つ。

<h2>解決法</h2>
webpackerの最新バージョンはv6.0.0みたいですが、これはベータ版みたいなので、とりあえず5.0.0~5.1.0にしてみました。<a href="https://techracho.bpsinc.jp/hachi8833/2021_04_16/107187">
Webpacker v6.0.0.beta.6の現時点の変更点について
</a>

```:Gemfile
# gem 'webpacker', '~> 4.0'
gem 'webpacker', '~> 5.0'     # 4を5に変える
```
その後、再び下記コマンドを実行

```:ターミナル
$ bundle install
$ rails webpacker:install
$ rails webpacker:install:vue
$ rails server
```

publicの下にpacksとmanifest.jsonが生成されました。
![スクリーンショット 2021-06-03 22.32.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/626568/676eb8ac-ce07-2e2a-16c4-d7327a6500d3.png)

localhost:3000/homeに移動すると、、、

![スクリーンショット 2021-06-03 22.27.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/626568/c5b594be-7cbf-7878-4474-8cc55ea7e6a6.png)

無事Hello Vue！が表示されました！！

<h2>原因</h2>
詳しい原因は正直よくわかりません。すみません。
ただパッケージ間のバージョンの問題なのかなと推測します。
ちなみにエラー解決に要した時間は15時間でした笑
心折れそうでしたが、とりあえず自力で解決できていい経験になりました。
エンジニア未経験者がエンジニアになるまでにやってたこと

目次
1. 最初に
2. 自分の過去について
3. エンジニア転職するまでにやってたこと
   　・プログラミングを学習するまで
   　・プログラミング学習に使用していた教材　　　　
4. 最後に

　　


初めに

今回初のQiita記事になります！、この記事以降から定期的に投稿していくので、良かったら見に来てください！
見に来てくれると、とても嬉しいです！
では、本題に入ります。２０２０年６月にエンジニア転職を目指してから半年、２０２１年１月にエンジニアとして都内のWeb系の企業に転職することができました。

ちなみに自分は才能や頭が特別良かった訳では有りません、ただの一般人です。

そんなごく普通の一般人の自分が、エンジニアに転職するまで半年間やってきたことの過程を紹介するお話です。


自分の過去について
　　・　20代前半
　　・　専門学校卒
　　・　プログラミング経験無し（中学の頃にゲーム機の改造をしてたぐらい）
　　・　物流会社

　　といった感じでした。



エンジニア転職するまでにやってたこと
　

プログラミングを学習するまで
まず自分がプログラミングを学習するキッカケについて　２紹介
１つ目は、父親がIT企業で働いていて、昔から父親の仕事の話を聞いてIT企業に興味を持っていたこと

２つ目は、前職の物流会社で新しい大型システムを導入した時に、システムを導入したエンジニアさんが、自分の目の前でプログラムをいじっていて、それを見て「かっけー！！！」ってなったこと（これが一番でかい）

ここで一つ、この記事を見てくれた人に疑問を浮かぶかもしれません。
この記事を見た人「なんで昔からIT企業に興味があったのに物流会社に入ったんだよ！」という疑問の声が聞こえてきます。
その理由は、学生時代の頃のバイト先が物流会社で、物流業界に慣れていたことによって物流会社で働いていたというのが理由です。



プログラミング学習で使用していた教材
自分がプログラミング学習で使用していた教材は、ドットインストール、公式ドキュメントです。

自分の勉強過程を凄くざっくりと説明します。
まず初めにドットインストールでHTML、cssを学びました。一通りやり終えた後に直ぐに、ドットインストールでrubyを勉強しました。（自分が何をやっているか全く分かりませんでした。）
自分が何をやっているか全く分からないまま、Ruby on rails を触りました。
ですがドットインストールは、動画学習教材なので、全く分からない状態でもなんとか一通りやりきりました。

ドットインストールある程度学んでから、Rubyの公式ドキュメントの説明を見ながら学習していたが、動画学習では無くなった瞬間コードを書く度にエラーが発生していました笑
コードを打つ度にエラーが発生する状態なので、めちゃくちゃ心が折れかけました。　誰も教えてくれる人が居なかったので、エラーを解消するまでに、３日〜４日掛かってた覚えがあります笑
エラー続きで諦めようとしたときも有りましたが、エラーを一つでも解決すると凄く達成感を得られて、なんとかモチベーションを保つことが出来ました笑

そんな感じで公式サイトドキュメントをやりきり、次は自分でなにかしら機能実装をしてみたいと思い、初めて実装した機能がクレジットカード決済機能でした。
なんでクレジットカード決済機能なのか、と言いますと日頃からネットショッピングしており、クレジットカード決済の仕組みがどんな感じか凄く気になっていたのがキッカケです

正直クレジットカード決済機能は、プログラミング始めたての人が実装するものでは無いです笑、控えめに言ってコードを書くことが嫌になりますよ笑
ちなみに実装までに、自分は一ヶ月掛かりました笑
しかし、クレジットカード機能の実装をやり遂げたことによって、プログラミングの理解度やモチベーションがかなり向上し、プログラミングにドハマリし、エンジニア転職を決意しました。


最後に
自分の勉強法は、かなり特殊で何も参考にならないと思いますが、取りあえずなんでも良いから１つ機能実装やサービスを作ると、プログラミングに対する興味がグッと上がることでしょう。
次回は、自分が今でも使用しているRuby on rails での開発の大まかな流れを何段階で説明する記事を書きます。

その記事で一人でもプログラミングの楽しさを感じていただければ幸いです。
すごいざっくりな説明で参考にならないと思いますが、ここまで見てくださった方有難うございます！
WordPress で Twitter Card を使う

こちらの記事にあるのと同じことを行いました。
[プラグイン不要でTwitterカードをコピペでサクッと設置する方法｜WordPressカスタマイズ](https://nelog.jp/wp-twitter-cards-custom)

```php:twitter-card.php
<!-- Twitter Card -->
<meta name="twitter:card" content="summary">
<?php
if (is_single()){//単一記事ページの場合
if(have_posts()): while(have_posts()): the_post();
  echo '<meta name="twitter:description" content="'.mb_substr(get_the_excerpt(), 0, 100).'">';echo "\n";//抜粋を表示
endwhile; endif;
  echo '<meta name="twitter:title" content="'; the_title(); echo '">';echo "\n";//単一記事タイトルを表示
  echo '<meta name="twitter:url" content="'; the_permalink(); echo '">';echo "\n";//単一記事URLを表示
  } else {//単一記事ページページ以外の場合（アーカイブページやホームなど）
  echo '<meta name="twitter:description" content="'; bloginfo('description'); echo '">';echo "\n";//「一般設定」管理画面で指定したブログの説明文を表示
  echo '<meta name="twitter:title" content="'; bloginfo('name'); echo '">';echo "\n";//「一般設定」管理画面で指定したブログのタイトルを表示
  echo '<meta name="twitter:url" content="'; bloginfo('url'); echo '">';echo "\n";//「一般設定」管理画面で指定したブログのURLを表示
}
$str = $post->post_content;
$searchPattern = '/<img.*?src=(["\'])(.+?)\1.*?>/i';//投稿にイメージがあるか調べる
if (is_single()){//単一記事ページの場合
  if (has_post_thumbnail()){//投稿にサムネイルがある場合の処理
    $image_id = get_post_thumbnail_id();
    $image = wp_get_attachment_image_src( $image_id, 'full');
    $img_url = $image[0];
    echo '<meta name="twitter:image" content="'.$image[0].'">';echo "\n";
  } else if ( preg_match( $searchPattern, $str, $imgurl ) && !is_archive()) {//投稿にサムネイルは無いが画像がある場合の処理
    $img_url = $imgurl[2];
    echo '<meta name="twitter:image" content="'.$imgurl[2].'">';echo "\n";
  } else {//投稿にサムネイルも画像も無い場合の処理
    $ogp_image = get_template_directory_uri().'/images/og-image.jpg';
    $img_url = $ogp_image;
    echo '<meta name="twitter:image" content="'.$ogp_image.'">';echo "\n";
  }
} else {//単一記事ページページ以外の場合（アーカイブページやホームなど）
  if (get_header_image()){//ヘッダーイメージがある場合は、ヘッダーイメージを
    $img_url = get_header_image();
    echo '<meta name="twitter:image" content="'.$img_url.'">';echo "\n";
    
  } else {//ヘッダーイメージがない場合は、テーマのスクリーンショット
    $img_url = get_template_directory_uri().'/screenshot.png';
    echo '<meta name="twitter:image" content="'.$img_url.'">';echo "\n";
  }
}
//ドメイン情報を$results[1]に取得する
preg_match( '/https?:\/\/(.+?)\//i', admin_url(), $results );
//画像の縦横幅を取得
list($width,$height) = getimagesize($img_url);
?>
<meta name="twitter:domain" content="<?php echo $results[1] ?>">
<meta name="twitter:image:width" content="<?php echo $width ?>">
<meta name="twitter:image:height" content="<?php echo $height ?>">
<meta name="twitter:creator" content="@ekzemplaro">
<meta name="twitter:site" content="@ekzemplaro">
<!-- /Twitter Card -->
```

このコードを themes の中に入れます。
例えば次のフォルダーへ
wordpress/wp-content/themes/habakiri


```php:wordpress/wp-content/themes/habakiri/header.php
（省略）
<?php get_template_part('twitter-card');?>
</head>
（省略）
```

[Card validator](https://cards-dev.twitter.com/validator) で確認
![card_validator_jun0401.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/87a43f16-a530-071e-416c-4fb5eb80172a.png)

2021年の段階では「TwitterにTwitter Cardsの申請」は不要です。
【Javascript】Strings(1)学習ノート

# 初めに
Stringについて学習した内容のoutput用記事です。

※内容に間違いなどがある場合はご指摘をよろしくお願いします。
※こちらの記事はあくまでも個人で学習した内容のoutputとしての記事になります。

# 文字列から文字を取得
文字列から単一の文字を取得するには、配列と同じように[]の中に添字を入れます。左から順番になっていて、0番から始まります。

```javascript
  const train = "Yamanotesen";

      console.log(train[0]);
      //Y

      console.log(train[1]);
      //a

      console.log(train[2]);
      //m
```

# stringのメソッド
文字列の長さはlengthメソッドで求めることができます。

```javascript
      console.log(train.length);
      //11
```
文字列の特定の文字が何番目にあるのか調べるには、indexOf()メソッドを使います。0から順番に左から数えていきます。

```javascript
     const railwayCompany = "Japan Railways Group";
     console.log(railwayCompany.indexOf("R"));
     //6
```

これと同じように何番目に文字があるのか調べるlastIndexOf()メソッドがあります。indexOf(0)メソッドと違う点は調べる文字が複数あった場合に、一番最後にある文字の位置を表示するところです。
"Japan Railways Group"にはaが3つあり、その最後のaの位置が分かります。

```javascript
     console.log(railwayCompany.lastIndexOf("a"));
     //11
```
探す文字列がある場合にはその文字列の位置を左から順番に数えて表示してくれます。小文字と大文字を区別するため、下記のように大文字のRではなく小文字のrにしてindexOfメソッドを使った場合-1と表示されます。
これは小文字のrで始まるrailswaysは見つからないからです。

```javascript
   console.log(railwayCompany.indexOf("Railways"));
   //6
   console.log(railwayCompany.indexOf("railways"));
   //-1
```
文字列のstartする位置を決めるにはsliceメソッドを使います。左から0なので、6を入れれば7番目から文字列が出力されます。

```javascript
   console.log(railwayCompany.slice(6));
   //Railways Group
```
sliceメソッドは文字列の終わる位置も指定できます。

```javascript
   console.log(railwayCompany.slice(6,14));
   //Railways
```

indexOfメソッドとlastIndexOfメソッドと組み合わせれば、"Japan Railways Group"からJapanとGroupだけを抽出することができます。

```javascript
      console.log(railwayCompany.slice(0, railwayCompany.indexOf(" ")));
      //Japan
      console.log(railwayCompany.slice(railwayCompany.lastIndexOf(" ") + 1));
      //Group
```

# 参考サイト
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/String/indexOf
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/slice
3
WordPressのContact Form 7を使いAPI経由でフォームと送信する


CMSサービス、フォームメールのバックエンドサービスが出始めていますが、クライアントの都合でなかなかそういったサービスを使えないこともあります。
Wordpressを使いつつ、HeadlessCMSとして使う想定の中でフォーム送信機能もWordpress側で持たせてあげたい、という要件はきっとある(はず)。

※ Wordpress全般に言えることですが、Contact Form7はちょこちょこ脆弱性が見つかって攻撃されているなどの問題もあります。そういうところも含めてWordPressでの運用を愛せる方が自己責任で行ってください

### なんでこの記事をかいたのか
Contact Form7のAPIを叩く記事はQiitaにもあったが、記述が片手落ちでそのとおりにやってもうまくいかなかった。
よりシンプルに十全な記事を書くことを目的としています。

### 参考にしたURL
https://css-tricks.com/headless-form-submission-with-the-wordpress-rest-api/


### 前提
- WordpressにContact Form7が入っている
- 実装サンプルはReact typescript fetchですがなんでも

### URL エンドポイント
Contact Form 7のエンドポイントはこちらになります。

```
https://<サイトのURL>/wp-json/contact-form-7/v1/contact-forms/<FORM_ID>/feedback
```

FORM_IDには、フォームのショートコードに書かれているIDを入れてあげます
```[contact-form-7 id="<この数字>" title="コンタクトフォーム"]```


```html
<form onSubmit={this.handleSubmit}>
  <input type="text" placeholder="" name="your-name" value={this.state.name} onChange={this.handleChange} />
</form>
````
Reactの場合、formのonSubmitのイベントで処理するとかんたんです。
name属性には、Contact Form7のフォームに指定したnameを入れてあげましょう

```react
const API_URL = 'https://<サイトのURL>/wp-json/contact-form-7/v1/contact-forms/<FORM_ID>/feedback'
handleSubmit = async (event) => {
    event.preventDefault();
    const formElement = event.target;
    const body = new FormData(formElement);
    const res = await fetch(API_URL, {
      method: 'POST',
      body: body,
    })
  }
```

あとはサーバーサイドのバリデーション結果や送信完了はレスポンスで返ってきますので、そのあたりをうまく処理してあげたら完了です
phpmyadminインストール（備忘録）

#はじめに
centOS8にphpMyAdminをインストールしたので、備忘録として記録に残す。
この記事の内容
・phpmyadminのダウンロード
・ダウンロードしたzipファイルの解凍
・zipファイルの削除
・ブラウザからphpmyadminにログイン

#phpMyAdminの導入
[phpMyAdmin](https://www.phpmyadmin.net/downloads/)からダウンロードする。
今回、wgetでダウンロードしようとしたら、wgetコマンドが使えない状態だったので
wgetコマンドのインストールも別の記事で書こうと思う。
（2021年3月下旬の時点でphpMyAdminの最新版は5.1.0）
以下のコマンドをDocumentRootで実行

```実行コマンド:phpmyadmin導入
wget https://files.phpmyadmin.net/phpMyAdmin/5.1.0/phpMyAdmin-5.1.0-all-languages.zip
unzip phpMyAdmin-5.1.0-all-languages.zip
mv phpMyAdmin-5.1.0-all-languages phpmyadmin
rm -rf phpMyAdmin-5.1.0-all-languages.zip
```




#ブラウザからアクセス（動作確認）

http://IPアドレスorドメイン/phpmyadmin
って感じのURLを入力して動作しているか確認
【Kotlin研修3日目】ConstraintLayoutの制約とチェイン機能

# ConstraintLayout
[参考: 研修1日目](https://qiita.com/b150005/items/07475f27129a1a820fea)
`Android Studio`標準の`レイアウト部品(ビューグループ)`。
`ビュー(ウィジェット)`の`相対的配置`を可能にするレイアウト。

> `RelativeLayout`は、**任意**の`ビュー`を基点とし、基点を基にした相対配置を行う。
> `ConstrainLayout`は、**全て**の`ビュー`を相対指定して配置を行う。

## 制約(Constraint)
`ビュー`の`x`/`y`方向に存在する`ビュー(親ビューも指定可能)`の指定。
`制約`は、`x`/`y`方向に対して**1つ以上**の`ビュー`を指定する。

### 制約の属性(attribute)

|属性|内容|
|:--|:--|
|`app:layout_constraintTop_toTopOf`|`上`方向のビュー<br>親部品: `parent`<br>それ以外: ビューの`id`|
|`app:layout_constraintTop_toBottomOf`|`上`方向のビュー<br>親部品: `parent`<br>それ以外: ビューの`id`|
|`app:layout_constraintStart_toStartOf`|`左`方向のビュー<br>親部品: `parent`<br>それ以外: ビューの`id`|
|`app:layout_constraintEnd_toEndOf`|`右`方向のビュー<br>親部品: `parent`<br>それ以外: ビューの`id`|

## ConstraintLayoutにおけるlayout_width/height
`親ビュー`の上限サイズまで拡張する場合は、`layout_width/height`属性に`0dp`を指定する(=`Match Constraints`)。
または、`Design`モードの`Constraint Widget`アイコンで変更することができる。
※`ConstraintLayout`では`match_parent`が使用不可

### 3種類のlayout_width/height

|アイコン(属性値)|内容|
|:--:|:--|
|![WrapContent.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/673880/5e92ed82-6652-5889-fd31-e4d38a219ca2.png)|`Wrap Content`<br>`ビュー`の表示に必要な最小サイズ|
|![Fixed.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/673880/cad5ea0f-c069-2eb0-3c08-87e869485027.png)|`Fixed`<br>具体的なサイズ単位|
|![MatchConstraints.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/673880/28e75ca0-ff8f-2c6f-1868-4bd35a43cd7a.png)|`Match Constraints`<br>`制約`内での最大サイズ<br>※設定値: `0dp`|

## ベースライン
`ビュー`間で、`文字列`の位置を制約できる線。

## ガイドライン
`ビュー`間で、`ビュー`の位置を制約できる線。

## チェイン機能
互いに`制約`し合う、複数の`ビュー`のグループ化。

### チェインスタイル(chain style)

|スタイル|内容|
|:--|:--|
|`spread`|`均等`配置|
|`spread inside`|親レイアウト境界に対して、<br>`両端ビュー`が接する`均等`配置|
|`packed`|`各ビュー`が接する配置|
|`weighted`|`spread`/`spread inside`配置のうち、<br>`Match Constraints`を適用した配置|
Laravel：部分的に使用しているreactにview変数を受け渡す方法

# Laravel：部分的に使用しているreactにview変数を受け渡す方法

## 構成

基本はbladeを使用し、reactは特定画面の指定div要素内のみで使用

# 目的

controllerから渡されたviewの変数をreactで使用したい

# 対応方法

javascriptのglobal変数として渡すことも可能だが、今回はdata属性にパラメータを指定して受け渡す。

受け渡し変数

```php:HogeController.php
$fuga = json_encode([
	['key' => 'key1', 'value' => 'hoge1'],
	['key' => 'key2', 'value' => 'hoge2'],
	['key' => 'key3', 'value' => 'hoge3'],
]);

return view('home', compact('fuga'));
```

```php:hoge.blade.php
<!-- idおよびblade部分は任意の文字列-->
<div id='react' data-blade={{$fuga}}/>
```

```typescript:app.tsx
componentDidMount() {
	const element = document.getElementById('react');
	if (element && element.dataset.blade) {
	    const object = JSON.parse(element.dataset.blade);
	    console.log(object);
	}
}
```

## 所感

javascriptのglobal変数に持たせるやり方もありますが、個人的にはこちらのほうが管理しやすいと思います。
vueのv-bindは便利ですね。
bin/rails app:update で routes.rb をキレイに上書きしてしまった話

# 概要
- Rails を 6.0.0 から 6.1.3 にバージョンアップしようとしていた
- ``bin/rails app:update`` を実行し、出てくるプロンプトを脳死で全て Y で許可した
- 結果、config/routes.rb をまっさらなものに上書きしてしまった

# 参考記事
- [How to Upgrade Rails app](https://redgreenrepeat.com/2020/07/03/how-to-upgrade-rails-app/) 
 
"Warning, there can be breaking changes to your application if you accept all changes suggested. (i.e. getting a new clean routes.rb file.)
Be careful with your choices!"

この記事はこの 2 文に尽きます。

# 詳細
Rails をバージョンアップする際に config 周辺のファイルの更新をしようと``bin/rails app:update``を実行しました。

実行して、もしファイルに conflict が発生した場合には

```
    conflict  config/routes.rb
Overwrite /sample/config/routes.rb? (enter "h" for help) [Ynaqdhm] 
```

と聞かれます。脳死で Y を押すと聞かれている通り Overwrite されてしまいますので、
差分を見て上書きしても問題ないか確認する必要があります。

記載の通り ``h`` で help を見ると

```
        Y - yes, overwrite
        n - no, do not overwrite
        a - all, overwrite this and all others
        q - quit, abort
        d - diff, show the differences between the old and the new
        h - help, show this help
        m - merge, run merge tool
```

と説明がでるので、``d`` で

```
--- /sample/config/routes.rb   2021-05-31 15:57:03.000000000 +0900
+++ /sample/config/routes.rb20210604-77510-10uw86v     2021-06-04 09:46:51.000000000 +0900
@@ -1,3 +1,3 @@
 Rails.application.routes.draw do
-  root 'application#hello'
+  # For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html
 end
Retrying...
Overwrite /sample/config/routes.rb? (enter "h" for help) [Ynaqdhm] 
```
と差分が確認できます。
更新したくない場合は ``n`` でスキップすればよいのですね。

# まとめ
何か聞かれたらちゃんと内容を聞きましょう。
ファイルパスを取得するVBScript

VBSにてファイルのフルパスを取得する対応を行ったので備忘録的に。
Windows10にて動作確認しています。
引数に渡したファイルをクリップボードに入れますので、SendToコマンドとして利用するのがよき。
ドライブマウントしているファイルについては、マウント先のパスに変換して取得します。

```vbscript
Dim i, arg, wsh

set arg = WScript.Arguments
set wsh = CreateObject("WScript.Shell")

if arg.count = 0 then wscript.quit

arg = exchangeDrivePath(arg)

if arg = ":::" then
  for i = 0 to 100
    if wsh.appactivate ("argument is as follows") then Exit for
  next
  wsh.sendkeys "^c{ENTER}"

else
  wsh.run "wscript.exe """ & WScript.ScriptFillName & """ :::"
  inputbox "argument is as follows","argument is as follows",arg
end if

Function exchangeDrivePath(path)
  Dim driveName, mountPath, exPath, i
  set WIN = WScript.CreateObject("WScript.Network")
  set oDrives = WIN.EnumNetworkDrives

  exPath = path
  for i = 0 to oDrives.Count -1 step 2
    driveName = oDrives.Item(i)
    mountPath = oDrives.Item(i+1)

    set objRegExp = New RegExp
    objRegExp.Pattern = driveName
    exPath = objRegExp.Replace(exPath, mountPath)
    set objRegExp = Nothing
  next
  exchangeDrivePath = exPath
End Function
```
FlaskでWeb上に文字を表示させるまで

#はじめに
プログラミング初心者の私ですが、まず始めの一歩目としてFlaskを使ってみました。
まず今回は最も簡単なWeb上に文字を表示させるまでの説明です。

#Flaskとは
FlaskとはPythonのWebアプリケーションフレームワークの一種です。比較的小規模で簡単なWebアプリケーションを作るのに適しています。また搭載されている機能が少なくシンプルなためプログラミング初心者の学習にも広く利用されています。

#Flaskをインストールする
Pythonのパッケージ管理ツールである「pip」を使ってインストールします。ターミナルに以下のコードを入力します。(pythonを起動していない状態)

```
pip install Flask
```


#スクリプトを記述
とりあえず定番のHello Worldを表示させるため、以下のコードを保存します。

```python:hello.py
#Flaskモジュールのインポート
from flask import Flask

#Flaskインスタンスの生成
app = Flask(__name__)

#URLが'/'のリクエストを受けた場合の処理
@app.route('/')
def hello_world():
    return 'Hello World!'
```
「@app.route('/')」部分はデコレーターと呼ばれ、関数やメソッドの前に記述し、その関数がどういう性質のものかを設定する働きがあります。

#実行
Macの場合は以下のように実行。

```
export FLASK_APP=Hello.py
flask run
```
windowsの場合は、以下のように実行。

```
set FLASK_APP=Hello.py
flask run
```

ブラウザを立ち上げ、http://localhost:5000 にアクセスし、「Hello World!」が表示されていれば無事成功です。

参考：https://flask.palletsprojects.com/en/0.12.x/quickstart/
🔰 [Kotlin] 基礎 androidstudio　変数宣言と条件式メモ

「作って楽しむプログラミング　Androidアプリ超入門」の勉強をまとめていきます。

###環境
java: 1.8.0_281
kotlin:1.5.10


##Class

構文　クラスのインスタンス化
`クラス名（）`
基本はこれだけ。
中身を定義するときには（）必要
Javaと違いインスタンス生成に`new`は不要。

```sample.kt
class Empty

val instance = Test()

val customer = Customer("Name")

```

##varとval
Kotlin で変数を定義するには、val キーワードまたは、var キーワードを使用します。 変数定義時に値を初期化する場合は、コンパイラが型を判断してくれるので、多くの場合は型の記述を省略することができます（この機能を型推論 (type inference) と言います）。

**`val`**:再代入できない参照を保持するための変数 (immutable reference)。Java の final 変数に相当。value の略。

**`var`**: 再代入可能な変数 (mutable reference)。variable の略。

```sample.kt
 //var:変数　val:固定
 var str = "大吉" //=> var str : String = "大吉"
 //乱数を得るためのRandomクラスを、インスタンス化し、クラス型変数rndに初期値として代入している
 val rnd = Random()
 //nextIntメソッドに引数として（3）を渡し、戻り値として整数の値を得ている
 //nextIntメソッドは乱数を整数で返すメソッド。乱数の範囲は指定した数字の-1
 val number = rnd.nextInt(3)

```

##ifとwhen
条件分岐のための構文
制御構文を用いることで、処理を分けることができる

```sample.kt
        if (number == 0) {
            str = "吉"
        }
        else if (number == 1) {
            str = "凶"
        }
        //if文をwhenで置き換えると
        //when (number) {
        //0 -> str = "吉"
        //1 -> str = "凶"
        //}

        //when式で書き換えると
        //val str = when(number){
        //0 -> "吉"
        //1 -> "凶"
        //else -> "大吉"
        //}
        //式として用いる場合は、戻り値が必要。したがってelseは省略不可
```

##配列の種類と特徴
Kotlinの配列には大きく分けて2つの種類があります。
``基本型(プリミティブ型)の1つとしての配列``： Arrayが該当します
``コレクションパッケージの1つとしての配列``： ListやArrayListなどArray以外のほとんどが該当します

Kotlinで複数の要素を扱う際は、基本的にコレクションパッケージで用意されているListやMutableListなどのクラスを使用します。

Arrayはライブラリなどで明示的に使うことを指定されている場合に使用すると良いでしょう。またListは読み取り専用のクラスであり、要素や要素数を変更する可能性がある場合はMutableListを使用します。

MutableListと同等のクラスにArrayListがあります。両者の違いは可変(Mutable)であることを明示しているか、です。通常はMutableListを使用し、Javaとの互換性などで明示的に使うことを指定されている場合にのみArrayListを使用すると良いでしょう。

##サンプルコード
要素の確率を変更したい時は、if,whenなどの条件分岐ではなく、配列を用いるほうがベター
if,whenのサンプルコードは[こちら](https://qiita.com/nipp/items/b1c6179abdd19c3a6ac8)

今回は吉:大吉:凶を18:1:1に設定したい。
また、今回使用するArrayクラスでは、宣言と同時に配列要素の初期化を行うことができる。
初期化処理には各要素に設定したい値を返す式を書く。今回は「吉」という文字列で初期化。
インデックス番号を指定して、「大吉」「凶」を代入する


``` sample.kt
        //文字列型が20個分入った配列を宣言する
        val omikujiShelf = Array<String>(20,{"吉"})
        omikujiShelf[0] = "大吉"
        omikujiShelf[19] = "凶"
```

##for文で配列にアクセスする
要素数が増えてきても、要素1つずつ指定するのは非効率なのでfor文の範囲式を使用する
javaで言うと拡張for文みたいなイメージ
上記のコードを範囲式で書き換える

``` sample.kt
        //文字列型が20個分入った配列を宣言する
        for (i in 0 .. 19 ) {
        omikujiShelf[i] = "吉"
　　　　　　　　　　　　　　　　}
```



``参考``
https://techacademy.jp/magazine/32265
AWS CloudWatchイベントのルールにおけるインスタンスIDの設定フォーマット

# 要約
- CloudWatchルールにインスタンスIDを設定する時のフォーマットの備忘

```
["i-999999","i-888888"]
```

# 動機
- 設定後の値を見ると、JSONフォーマットになっているが、それで入力するとエラーになる。
- 入力画面を見ると、ただのカンマ区切りで良さそうなのに、それで入力するとエラーになる。

以上
【Docker】ホストのポートとコンテナのポートをつなげる no.9

![パンプキン カフェ (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011305/f5999ae6-f32e-871a-1252-9cc2acdd7ad2.png)


こんにちは、まゆみです。

Dockerについての記事をシリーズで書いています

[前回の記事](https://qiita.com/Mayumi_Pythonista/items/483173ee900035a9f59b)では、簡単なWebアプリを作りつつWORKDIR とCOPYについて解説させていただきました。

ただ、ディフォルトのままでは、

あなたの<font color="Red">ローカルホスト(パソコン)からは、Container の方に関連付けられていません。</font>

今回の記事では、<font color="Red">ローカルホストとContainerのポートをつなぐ(publishという)には</font>どうしたらいいのかということについて書いていこうと思います

![Local host.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011305/4f4fde3b-10b7-05bb-6ff0-cb77c7febc9f.png)

ではさっそく始めていきますね。(前回の記事からの続きの内容になります。)

#『-p』を使ってポートマッピングする

![docker run -p localhostcontainer (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011305/8b9c4d21-1b37-6a1a-d097-8521ca4e6f0f.png)
ローカルホストのポート番号も、Container のポート番号も8080なので(Docker hostのデフォルトのポート番号は8080になります)


![2021-06-04_9-07-51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011305/bfb9b3d1-c216-5d0d-da4f-74ce76941535.png)
引用元：[docker docs](https://docs.docker.com/config/containers/container-networking/)


```
docker run -p 8080:8080 <imageID>
```
を実行してみます


![2021-06-04_8-53-16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011305/0ccbba9d-5f33-c3eb-151b-ec6a7f9ba1af.png)


![2021-06-04_8-54-04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011305/261c2536-52cc-f2d2-f003-4ce906797a91.png)

#今回の記事で分かった事
では、今回の記事で分かった事をまとめておきます

<ul>

<li>Dockerから『外の世界に対して』アクセスするには制限はない(Dockerfileを作るさい、『RUN npm install』と書いて、外の世界にアクセスして、npm をインストールしていますが問題なくできています)</li>


<li>Dockerの『中に』アクセスする場合は、デフォルトのままではアクセスできない</li>


<li>Containerの中にアクセスするには『-p』を使って、ローカルホストとContainerのポートをつなぐ必要がある</li>

</ul>
moment.jsからdayjsに移行：曜日の表示

日本語の曜日表示の作業メモです

## 移行前

- updateLocaleでlocaleをjaに更新
- updateLocaleでlocaleの曜日表示を設定（ここがjaのデフォルト設定と同じなので、実は要らなかった）

```js
import moment from 'moment';

// momentの言語設定
moment.updateLocale('ja', {
  weekdays: ['日曜日', '月曜日', '火曜日', '水曜日', '木曜日', '金曜日', '土曜日'],
  weekdaysShort: ['日', '月', '火', '水', '木', '金', '土'],
});
```

## 移行後

- `dayjs/locale/ja`のインポートが必須
- dayjsのプラグインを特にnpm install必要がない
- ロケールjaで十分なのでupdateLocaleしない

```js
import dayjs from 'dayjs';
import 'dayjs/locale/ja';

dayjs.locale('ja');
```

## 動作確認

```js
console.log(dayjs().format('YYYY/MM/DD(ddd) HH:mm')); // 2021/06/04(金) 08:58
```
CakePHPで実行されたSQL文を表示する

CakePHPで実行されたSQL文を表示する方法です。

# はじめに
CakePHPでORMを用いる際など、クエリの実行結果のみならず **実行されたSQL文を知りたい** ケースは多々あると思います。

今回はCakePHPの3系と4系それぞれで、実行されたSQL文をdebugログに表示する方法をお伝えします。

## CakePHP 3.X

```php
$connection = \Cake\Datasource\ConnectionManager::get('default'); // DB接続を取得
$connection->logQueries(true); // SQL Queryのログ出力を有効化
$this->Model->find()->all(); // SQL文を確認したいSQLを実行
$connection->logQueries(false); // SQL Queryのログ出力を無効化
```

## CakePHP 4.X

```php
$connection = \Cake\Datasource\ConnectionManager::get('default'); // DB接続を取得
$connection->enableQueryLogging(true); // SQL Queryのログ出力を有効化
$this->Model->find()->all(); // SQL文を確認したいSQLを実行
$connection->disableQueryLogging(); // SQL Queryのログ出力を無効化
```

## 出力先
debugログの出力設定に応じたファイルへSQL文が出力されます。
デフォルトでは`(CakePHPインストールフォルダ)/cakephp/logs/debug.log`となっています。

## 注意点
- `\Cake\Datasource\ConnectionManager::get('default');`では指定するDBを間違えないようにしましょう
    - （レプリカサーバを利用していたのに`get('default')`を`get('replica')`と変更し忘れて「動かない！」と騒いでしまった思い出があります・・・）

# 参考
https://jmatsuzaki.com/archives/18839

### 公式リファレンス
#### CakePHP 4.X
https://api.cakephp.org/4.0/class-Cake.Database.Connection.html#enableQueryLogging()

#### CakePHP 3.X
https://api.cakephp.org/3.1/class-Cake.Datasource.ConnectionInterface.html#_logQueries
Prism とか コンテナを Microsoft.Extensions.DependencyInjection 化できないけど IServiceCollection 使いたいときに使うライブラリ DryIoc.Microsoft.DependencyInjection.Extension を作りました。

必要があったので DryIoc に IServiceCollection ベースで登録する為の DryIoc.Microsoft.DependencyInjection.Extension を作成しました。

[DryIoc.Microsoft.DependencyInjection.Extension 1.0.0.2](https://www.nuget.org/packages/DryIoc.Microsoft.DependencyInjection.Extension/1.0.0.2)

# できること

このライブラリでできることは DryIoc で DryIoc.Microsoft.DependencyInjection 拡張を使えない環境でもできるかぎり IServiceCollection を登録できるようにするということです。

具体的に見ていきましょう。

Prism だと次の様に登録に使います。

```cs
using DryIoc.Microsoft.DependencyInjection.Extension
// ...
Registry.GetContainer().RegisterServices(v =>
{
    v.AddTransient<IA>(v => new A1());
});
// ...
```

使い方のアイディア的には [Prism.Container.Extensions](https://github.com/dansiegel/Prism.Container.Extensions) の [Prism.Microsoft.DependencyInjection.Extensions](https://www.nuget.org/packages/Prism.Microsoft.DependencyInjection.Extensions) と同じです。

ただし、こちらは Xamarin じゃなくても動きますし、そもそも Prism 自体をターゲットにしているわけでもないです。（というか Xamarin じゃないと動かないとあったのでこれを作ったので。

# 制限事項

現在わかっているのは DryIoc のコンテナを作成する際に `WithConcreteTypeDynamicRegistrations` しているとコンストラクタインジェクション時に登録していないオブジェクトを挿入してしまう為、想定されないコンストラクタを選択されてしまうということですね。例えば ILoggerFactory とか。
なので、登録する前あたりに 想定されたコンストラクタで呼び出す様に登録してやってください。

以上。

不具合等ありましたら。[issues](https://github.com/juner/Prism.Extensions.ServiceCollection/issues) まで。
DatabricksとMATLABによる大規模データにおける洞察の抽出

[Gaining Actionable Big Data Insights for MATLAB and Simulink with Databricks](https://databricks.com/blog/2020/02/19/actionable-insight-big-data-scale-databricks-mathworks.html)の翻訳です。

本日、我々は世界中のエンジニア、サイエンティストに使用されているMATLAB、Simulink製品ファミリーを有するMathWorksとのパートナーシップを発表しました。

医療機器から、ジェット機、自律自動車に至るまで、数多くのエンジニア、サイエンティストが、物理システムと相互作用するシミュレーションモデルを用いて自律システムを構築、テストするためにMATLABとSimulinkを使用しています。しかし、これらのモデルをクラウドの規模で動作させようとすると、計算資源を設定し、複雑なデータパイプラインを構築し、モデルやシミュレーションを実行するために新たなプログラミング言語を学ぶ必要があり、ドメインの専門家は様々な運用上の課題に苦悩することになります。これは、本来の目的であるシミュレーション、研究、そして、大規模データから得られる洞察、発見を妨害することになります。

# クラウドにおけるMATLABシミュレーションをシンプルに

DatabricksとMathWorksのパートナーシップによって、ドメイン専門家は普段から使用しているMATLABのインタフェースを介して、Databricksの[レイクハウスプラットフォーム](https://databricks.com/jp/product/data-lakehouse)で大規模データを分析し、クラウドにおける大規模データ計算、シミュレーションをシンプルなものにし、上述した課題を解決します。

このパートナーシップによって、エンジニアリング部門のMATLABユーザーは、ITによって管理される中央データリポジトリにアクセスし、MATLABを使用して高速に正確な結果を取得し、仮想マシンやコンテナーなどの専門知識を必要とすることなしにDatabricksのクラスター上でアルゴリズムを実行することができます。ITや他の部門のDatabricksユーザーにとっては、MathWorksのMATLABユーザーとともに、クラウドで効率的にデータサイエンス、データエンジニアを実行するための新たなユーザーコミュニティを活用できるというメリットが生まれます。

## 1. 大規模データ処理のためにMATLABアルゴリズムをDatabricksにデプロイ

合同のソリューションによって、データエンジニア、データサイエンティストが大規模データセットから洞察を得るためのデータ処理、データ分析に活用できるように、MATLABアルゴリズムをDatabricksにデプロイすることが可能になりました。Databricksのレイクハウスプラットフォームによって、アルゴリズムを大規模データに適用するために普段からお使いのMATLAB環境を維持しつつも、高速、大規模、シンプルさを提供し、クラウドの複雑性を低減します。このソリューションによって、MATLABのコマンドラインやアルゴリズムコードから、フルマネージドのApache Sparkクラスター、ジョブスケジュールを設定することができます。

## 2. 企業規模のデータサイエンスコラボレーションの実現

Databricksに対し、馴染みのあるMATLABインタフェースを維持することで、ドメイン専門家はビジネスロジックに集中でき、スクラッチからプログラムを書くのではなく検証済みのツールボックスを活用できます。業界に特化されたMATLAB、 Simulinkのディープラーニング、予兆保全、財務分析などのツールボックスを活用することで、エンジニアはコーディングことなしに、それらのモデルやアプリケーションをシンプルにデプロイできます。

## 3. Delta Lakeを通じて大規模データへの高速アクセスが可能に

DatabricksのDBコネクトを活用することで、専門家は[Delta Lake](https://delta.io/)内のデータを活用することができます。信頼性の高い大規模データレイクを提供するオープンソースプロジェクトであるDelta Lakeによって、エンジニアはMATLABのビルトインインタフェースから、ストリーミングデータや蓄積データなど様々なデータに対して処理を行うことが可能になります。Delta LakeのACIDトランザクションやスキーマ適用の機能によって、クラウドのデータ規模でもMATLABアルゴリズム、Simulinkモデルが一貫性を維持できるように、データの破損を防ぎつつも大規模データへのアクセスを可能にします。

# DatabricksでMATLABとSimulinkの利用を始める

DatabricksとMathWorksパートナーシップの詳細に関しては、ウェビナー[Big Data for Engineers: Processing and Analysis in 5 Easy Steps webinar](https://databricks.com/p/webinar/big-data-for-engineers-processing-and-analysis)を確認してください。

このウェビナーでは、DatabricksのISVソリューションディレクターNauman PrasadとMathWorksのチーフソリューションアーキテクトArvind Hosagraharaが、詳細なインテグレーションのデモを通じて、どのようにこのソリューションが企業におけるMATLABビッグデータ処理を助けるのかを議論します。

### Databricks 無料トライアル

[Databricks 無料トライアル](https://databricks.com/jp/try-databricks)
PythonでHTML生成、WEBサーバ起動、ブラウザ参照を自動で実行

#はじめに
Pythonであるシステムに画面を組み込む話があったのだが、テスト時にシステム全体をインストールしたくなかったので、単体で画面を表示するドライバを作ってみた。

#環境
- python 3.6

#ソース
こんな感じ。

```python
import argparse
import http.server
import socketserver
import webbrowser
import threading

def main():
    PORT = 8009
    Handler = http.server.SimpleHTTPRequestHandler
    socketserver.TCPServer.allow_reuse_address = True    
    server = socketserver.TCPServer(("", PORT), Handler)
    server_thread = threading.Thread(target=server.serve_forever)    
    server_thread.daemon = True
    server_thread.start()
    print("Web server running in thread:", server_thread.name)
    webbrowser.open("http://localhost:{0}/html/test.html".format(PORT))

    import time
    from datetime import datetime
    try:
        while(True):
            time.sleep(10000)
    except KeyboardInterrupt: 
        print("closing")
        #server.shutdown()
        server.socket.close()                   
        import sys
        sys.exit()
        

if __name__ == "__main__":
    main()
```

## 解説
- コマンドを実行すると、WEBサーバを立ち上げ、ブラウザを開き、プログラムの直下のhtmlフォルダの下のtest.htmlを表示する。
- WEBサーバを立ち上げた後にブラウザを開けるよう、WEBサーバはスレッドで立ち上げている。
- 途中でCtr-Cによりキャンセルできるようにしている。

VisualStudioのLive Serverでいいじゃんという話もあるが、これだとPythonしかない環境に配布を行うことができる。

#参考
- [pythonでWebサーバを書いてみる](https://www.magata.net/memo/index.php?python%A4%C7Web%A5%B5%A1%BC%A5%D0%A4%F2%BD%F1%A4%A4%A4%C6%A4%DF%A4%EB)
- [Python で Ctrl-C をキャッチする](https://qiita.com/keisuke-nakata/items/e77b123d75d4b52aac77        )
いわゆるＱ＆Ａサイトの、まとめ的なサイト

いわゆるＱ＆Ａサイトの、まとめ的なサイトを発見しましたので共有します。

https://stackexchange.com/sites

ポチポチＧＵＩを触ると、アイコンが入れ替わって楽しい！
（この画面だけでも、すごい技術だなあと感心します）

![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212914/278eb8fd-8c62-d5a3-8da4-785b3218b327.png)
TestCafe を試してみる


# はじめに
ブラウザの動作確認を目視確認するとか眠たくなる作業はやりたいので自動化しておきたい。
Selenium とか知っているけど webdriver でプログラム組む面倒な作業はしたくないというめんどくさがり。

# ダウンロード

https://www.devexpress.com/products/testcafestudio/#


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/304109/40f9517a-7de9-957f-d4e7-245525b5049d.png)


# Test Cafe Studio のインストール
ダウンロードしたファイル「DevExpressTestCafeStudioSetup-win-1.4.0.exe」をダブルクリックするとインストールが始まる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/304109/021265b6-1c88-89db-7e3b-e4605f4ebb73.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/304109/9f552303-0b2d-2581-4650-d533def27383.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/304109/d1978f8c-e865-329d-92f5-037c290c0c5f.png)


# TestCafe のインストール

## npmをインストール
以下から node.js をダウンロードしてインストール
https://nodejs.org/ja/download/


## npm を使って TestCafe をインストール

```batchfile

npm install -g testcafe
testcafe -b
```

# TestCafe のコマンドを試してみる

```batchfile

C:\Users\Administrator>testcafe -b
ie
edge
chrome
firefox
edge-legacy
```

Test Cafe Studio で作成した js を利用して実行する。

```batchfile
C:\Users\Administrator>testcafe edge "C:\Users\Administrator\TestCafeStudio\10-1-5-11-8080\New Test.js"
 Running tests in:
 - Microsoft Edge 88.0.705.74 / Windows 10

 test000
 √ New Test (screenshots: C:\Users\Administrator\screenshots)


 1 passed (55s)

C:\Users\Administrator>
```