OmniAICreator/Qiita-1.07M huggingface dataset:
[CLI] AWS System Manager のパラメータストアにハイフン始まりのテキストを登録できない

# TL;DR

- aws-cli からパラメータストアに登録するとき、ハイフンが最初についてる値は失敗した
- マネジメントコンソールからは問題なく設定できた

# 経緯

AWS System Manager 内のパラメータストアはcliが使えます。
今回はput-parameterがうまく行かなかったのでメモ書きです。

https://awscli.amazonaws.com/v2/documentation/api/latest/reference/ssm/put-parameter.html


以下のバージョンを使用しています。

```shell
% aws --version
aws-cli/2.1.33 Python/3.8.8 Darwin/19.6.0 exe/x86_64 prompt/off

```

## 通常のパターン

AWSのパラメータストアに `name=foo, value=bar` のテキストを登録します。これは問題なし。

```shell
% aws ssm put-parameter --name "foo" --value "bar" --type "String"      
{
    "Version": 1,
    "Tier": "Standard"
}
% aws ssm get-parameter --name "foo"                              
{
    "Parameter": {
        "Name": "foo",
        "Type": "String",
        "Value": "bar",
        "Version": 1,
        "LastModifiedDate": "2021-05-07T21:26:04.671000+09:00",
        "ARN": "arn:aws:ssm:ap-northeast-1:ACCOUNT_ID:parameter/foo",
        "DataType": "text"
    }
}
% aws ssm delete-parameter --name "foo"      
%                      
```

## ダメだったパターン

この `value=bar` を `value=-bar` としてみると、失敗してしまいます。

```shell
% aws ssm put-parameter --name "foo" --value "-bar" --type "String"

usage: aws [options] <command> <subcommand> [<subcommand> ...] [parameters]
To see help text, you can run:

  aws help
  aws <command> help
  aws <command> <subcommand> help

aws: error: argument --value: expected one argument
```

`value=\-bar` として登録したら、しっかりとエスケープしてくれます(そうじゃない)

```shell
aws ssm put-parameter --name "foo" --value "\-bar" --type "String"
{
    "Version": 1,
    "Tier": "Standard"
}
% aws ssm get-parameter --name "foo"                             
{
    "Parameter": {
        "Name": "foo",
        "Type": "String",
        "Value": "\\-bar",
        "Version": 1,
        "LastModifiedDate": "2021-05-07T21:31:32.513000+09:00",
        "ARN": "arn:aws:ssm:ap-northeast-1:ACCOUNT_ID:parameter/foo",
        "DataType": "text"
    }
}
```

# 対応

マネジメントコンソールから手動で設定することは可能でした。

```shell
% aws ssm get-parameter --name "foo"   
{
    "Parameter": {
        "Name": "foo",
        "Type": "String",
        "Value": "-bar",
        "Version": 1,
        "LastModifiedDate": "2021-05-07T21:39:54.401000+09:00",
        "ARN": "arn:aws:ssm:ap-northeast-1:ACCOUNT_ID:parameter/foo",
        "DataType": "text"
    }
}
```
enebularでherokupostgres その2

#概要

enebularでherokupostgresに繋ぎたい。

#使ってみたフロー

node-red-contrib-postgrestor-next


#写真

![next.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/37ea3ad0-0973-5642-c9c3-79e1ac53ec3a.jpeg)


#結果

エラー。Error: self signed certificate

以上。
備忘録：git関連：RaspberryPiで学ぶROSロボット入門

GW連休中に引き続き「RaspberryPiで学ぶROSロボット入門」を進めていきます。

4.4.1章のMake installがうまくいかなかったのですが、Makefileの「install」と「uninstall」の間に空行を入れていなかったからみたいです。

参考情報「[Raspberry Piで学ぶ ROSロボット入門」の情報リポジトリ](https://github.com/ryuichiueda/raspimouse_book_info)」


6.3章で本の通りのいかないで困ってます。

```
ubuntu@ubuntu:~/catkin_ws/src/pimouse_ros$ git remote add origin git@github.com:*****/pimouse_ros.git
fatal: remote origin already exists.
```

このページが参考になりました：[fatal: remote origin already exists. と表示された場合の解決法](https://qiita.com/yu-ki0718/items/3c8aae2c81ca3f82f522)


次はこれに困りました

```
ubuntu@ubuntu:~/catkin_ws/src/pimouse_ros$ git pull origin master
fatal: Couldn't find remote ref master
```

これは次のページでfatalが出なくなったので良しとして進めてみます。
「[git pull origin masterしたら「fatal: Couldn't find remote ref master」となる](https://qiita.com/r-wakatsuki/items/095d5d88d1288df6f9c6)」

次はこれに困りました。

```
ubuntu@ubuntu:~/catkin_ws/src/pimouse_ros$ git commit -m "Add package files"
ブランチ master
nothing to commit, working directory clean
```

対処法がいまいちわからないので、次のページを参考に6章を最初からやりなおしてみます：ローカルファイル削除、リポジトリ削除
「[Git add できない場合の対処法](https://qiita.com/hmuronaka/items/29f54f65a6b26540698a)」

【次回】と思ったけど、githubにpushできているので、もう少し続けてみたいと思います
Unityでスクリプトのベンチマークをとる方法4選

# 概要
Unityでスクリプトのベンチマークをとる方法はいくつかあるが、その中で自分がよく使う ~~3つ~~ 4つを紹介する。

（2021/08/24 追記）
4つ目にTime.realtimeSinceStartupを紹介。

# 1. C#のStopwatchクラスを使う
C#にはStopwatchというクラスが用意されている。
https://docs.microsoft.com/ja-jp/dotnet/api/system.diagnostics.stopwatch?view=net-5.0

このStopwatchクラスを使うことで処理にかかった時間を手軽に計測することができる。

サンプルコードは以下の通り。

```c#
var sw = new System.Diagnostics.Stopwatch();

// 計測開始
sw.Start();

// 計測したい処理
...

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

// 計測結果を出力する
System.Console.WriteLine($"処理時間：{sw.Elapsed}");
```

Stopwatchはその名の通りただのストップウォッチでしかないため、自分でStart~Endした時間を出力するだけである。
そのため手軽にざっくり処理時間を調べたい場合に使うと良い。

ElapsedはTimeStamp構造体のため、Millisecondsなどの細かい表示も可能。
https://docs.microsoft.com/ja-jp/dotnet/api/system.diagnostics.stopwatch.elapsed?view=net-5.0

# 2. Unity ProfilerのBeginSampleを使う
UnityのProfilerにはBeginSample, EndSampleというメソッドが用意されている。
https://docs.unity3d.com/ja/current/ScriptReference/Profiling.Profiler.BeginSample.html

これらのメソッドを使うことで、BeginSampleとEndSampleで挟んだ処理をProfilerで表示することができる。

サンプルコードは以下の通り。

```c#
// 計測開始
UnityEngine.Profiling.Profiler.BeginSample("test_sample");

// 計測したい処理
...

// 計測終了
UnityEngine.Profiling.Profiler.EndSample();
```

こちらはProfilerでの計測になるため、Stopwatchと違い処理にかかった時間だけでなく確保したメモリ量等も計測することができる。
そのためより詳細に調べたい場合に使用すると良い。

BeginSampleの引数で渡した文字列がProfilerに表示されるため、Profilerで検索しやすい名前にしておくとベター。

# 3. Performance Testing Extensionを使う
UnityのTestRunnerには拡張機能としてPerformance Testing Extensionが用意されている。
https://docs.unity3d.com/Packages/com.unity.test-framework.performance@2.8/manual/index.html

これはTestRunnerのテストコードの中に処理を計測するコードを書いてTestReportとして出力することができるものである。

導入方法については別記事にて記載してあるため、そちらを参照のこと。
https://qiita.com/hashikei/items/4c4be59418fcf0c4e5bd

導入後のサンプルコードは以下の通り。

```c#
using NUnit.Framework;
using Unity.PerformanceTesting;

public class TestPerformance
{
    [Test, Performance]
    public void TestSample()
    {
        Measure.Method(() => { /* 計測したい処理 */ })
            .MeasurementCount(10)
            .Run();
    }
}
```

TestReportのサンプル
https://docs.unity3d.com/Packages/com.unity.test-framework.performance@2.8/manual/viewing-results.html

導入方法が少し複雑でとっつきにくいが、MeasurementCountで計測回数を指定したり、計測結果をグラフで可視化してくれたりと、わりと便利な機能である。

SampleGroupでSampleUnitを設定することで、処理時間以外の値も計測することができる。
https://docs.unity3d.com/Packages/com.unity.test-framework.performance@2.8/manual/measure-custom.html

# 4. UnityのTime.realtimeSinceStartupを使う
UnityのTimeクラスにはrealtimeSinceStartupというプロパティが用意されている。
https://docs.unity3d.com/ja/current/ScriptReference/Time-realtimeSinceStartup.html

このプロパティはゲーム開始からの経過時間を取得するものだが、Time.timeと違いTime.timeScaleの影響を受けないため、リアルタイムの経過時間として参照できる。

サンプルコードは以下の通り。

```c#
// 計測開始
var t = Time.realtimeSinceStartup;

// 計測したい処理
...

// 計測結果を出力する
System.Console.WriteLine($"処理時間：{Time.realtimeSinceStartup - t}");
```

用途としては1のStopwatchと同様だが、細かい表示が不要な場合はTime.realtimeSinceStartupの方が手軽でオススメ。
enebularでherokupostgres

#概要

enebularでherokupostgresに繋ぎたい。

#使ってみたフロー

node-red-contrib-re-postgres

#写真

![無題.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/d98e53a9-ad02-d56c-02ad-265e3584f3fc.jpeg)


#結果

```
[ empty ]
```

以上。
neovim + vim-lsp-settings で flow + flow-typedのjavascript環境構築

# TL;DR

1. flow-typedを使った設定だと `:LspInstall flow` しただけだとflowが起動しない
1. lspのインストール先にflow-typedを追加でインストールする
1. lspの起動スクリプトを修正してnpxで起動するようにする


# 環境

* Mac OSX
* neovim 0.5.0
* [vim-lsp](https://github.com/prabirshrestha/vim-lsp) + [vim-lsp-settings](https://github.com/mattn/vim-lsp-settings)

# 手順

*※vim-lsp と vim-lsp-settingsの設定予め済んでいる前提*

## flowをインストール

適当なjsファイルを開いてneovimで `:LspInstallServer flow` を実行する。

## flow-typedを追加

vim-lsp-settingsのサーバーのインストール先に移動してflow-typedを追加する

```bash
$ cd ~/.local/share/vim-lsp-settings/servers/flow
$ npm install flow-typed --save
```

## 起動スクリプトを置く

デフォルトだと `node_modules/.bin/flow` へのリンクが配置してあるので npxで起動するようなスクリプトを置いておく。

```bash
#!/bin/bash

npx flow lsp --from vim-lsp
```


以上

もっといいやり方あるかも。
AzureVMで外部からwebサーバーに接続できない場合の対処方法

この記事ではAzureVMでWindowsDockerを使用して建てたwebサーバーに外部から接続できない場合の問題の切り分けを行いながら対処する方法を載せています。

## 環境
Azure
VirtualMachines使用（WindowsServer 2019）
セキュリティグループを使用

## Docker内でつながるか

```python
docker ps
```

コンテナ名を確認します。

```python
docker exec -it <コンテナ名> bash
```

コンテナに接続します。

```python
curl http://localhost:8080/
```

エラーが帰ってきたり何もかえって気なかった場合はwebサーバーが起動していない
可能性があります。

## VM上でつながるか

VM上の適当なwebブラウザを開いてURLに [http://localhost:8080/](http://localhost:8080/)を入力し接続します。

```python
curl http://localhost:8080/
```
  D
でも大丈夫です

つながらない場合、dockerのポート設定ができてない可能性があります。
dockerコマンドの場合 -p 80:80等の-pオプションが入っているか確認します。

例

```python
docker run -d -p 8080:80 <コンテナ名>
```

docker-composeの場合はportsの記入漏れが無いか確認します。

例

```python
version: '3'

services:
  nginx:
    image: nginx:1.15
    ports:
      - "127.0.0.1:8080:80"
```

## 外部PCからつながるか

###・セキュリティグループの設定

AzurePortal上からセキュリティグループを開きます。
セキュリティグループ設定で対象のポートが解放されているか確認します。

![Untitled.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107518/3d7bb5bc-5fda-b358-53c9-38a3cf5b3e45.png)

###・WindowsDefenderの設定

WindowsDefenderで新規の受信の規則の設定を行います。

![Untitled.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107518/fee2ced2-9596-1af6-90c6-eddd7c04dd61.png)
受信の規則から新しい規則を選択します。

以上です。
AR Foundation オクルージョン・平面でキャラを隠す

キャラクターを配置しておく

ARDefaultPlaneにSpetialMappingColussionを設定する
![F06CE926-3758-4891-90AE-7C798301F62C.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/940521/698ea526-9c9b-7178-ed15-dedc841409db.jpeg)

LineRendererをRemoveComponentする
![852F85D2-E837-4344-947E-4C0D35D00D6A.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/940521/6ce4bad6-7326-100d-d936-4ebee779206f.jpeg)

キャラクターのインスペクターに移動する
![A86F6628-C14C-4A63-9CF5-424104F58FB9.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/940521/9d994279-bc98-a290-b8b1-226627cc8d21.jpeg)

Body、face、hatのTex_DefoのRenderQueue値を2001に変更する
![B4232B92-83DA-42C1-98C2-623F81345A20.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/940521/7651a00b-611f-2f88-aca6-da735227a5ee.jpeg)
![B7843C1B-CBE7-4463-88CF-12E5413EFE78.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/940521/3edbf370-8181-2a42-dca6-797a82a1f68a.jpeg)
![D5BC5868-801A-4275-BB91-9BD028C25F5B.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/940521/d90fe4cc-4019-c74f-6406-d99a2070d699.jpeg)
MacからComposerをアンインストールする

## 前書き
Dockerって便利ですよね。
最近Dockerメインで開発しているので、開発環境を汚さないって素晴らしいなと思うようになりました。

そこで自分のMac環境を整理しようと思い立ち、今回[Composer](https://getcomposer.org/)をアンインストールしたので、その際の手順をメモします。~~（いざアンインストールしようと思ったら、やり方がわからないことに気づいたのです。。）~~

これからComposerくんにはDockerの中でお世話になります！

## アンインストールする手順
```bash
// Composerの場所を確認する
$ which composer
/usr/local/bin/composer

// Composerの場所に移動し、ディレクトリごと削除する
$ cd usr/local/bin
$ rm -r composer

// 関連するファイルたちも削除する
$ cd /Users/<YourName>
$ rm -r .composer 
```

これでアンインストール完了です。お疲れ様でした！
【初心者でもわかる】ページ読み込み時に任意の位置までスクロールした状態にする方法

# どうも7noteです。ページを読みこんだら一番上でなくページの途中を最初に表示する方法です。

ページ遷移をするときに、特定のリンクからはページの途中を表示させることができます。
指定も1行で簡単。

## ページの途中から表示させる方法

例）「index.html」から「hogehoge.html」の途中へリンクさせる

```index.html
<a href="hogehoge.html#contentsC" >ページhogehogeのコンテンツCへリンクする</a>
```

```hogehoge.html
<div id="contentsA">コンテンツA</div>
<div id="contentsB">コンテンツB</div>
<div id="contentsC">コンテンツC</div>
<div id="contentsD">コンテンツD</div>
<div id="contentsE">コンテンツE</div>
```

![sample.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/661092/6e429b4b-a6be-a0d3-f439-4189829b499b.gif)

## 解説・ポイント

とび元（ページ遷移する前のページ）のリンクのURLの最後に【#(id名)】を指定し、
とび先のページにそのidを指定した要素（最初に表示させたい要素）を用意するだけ。

ピッタリ上にくっついてしまうので、それを避ける場合にはjavascriptなどで制御する方法があります。

https://webdesignday.jp/inspiration/technique/jquery-js/4022/

## まとめ

classではできず、**idでしかできません**のでご注意を。
同一ページ内でも移動させることが可能です。指定方法は一緒。

#### おそまつ！
~ Qiitaで毎日投稿中!! ~
[【初心者向け】WEB制作のちょいテク詰め合わせ](https://qiita.com/7note)
[Android 11] 起動しているActivity/Fragmentを表示するadbコマンド

Android 11になってdumpsysの出力が変わり、Android 10以前に使用していたコマンドでは、起動しているActivityやFragmentを取得できないようになっていました。
明確なドキュメントがなく、手探りで探したのですが、シェアします。
参考: https://developer.android.com/studio/command-line/dumpsys

# 今Focusが当たっているActivity
```shell
adb shell dumpsys activity | grep "CurrentFocus"
```

# ActivityのStack
```shell
adb shell dumpsys activity | grep "#[0-9]* ActivityRecord"
```
Android 10以前の `adb shell dumpsys activity | grep -B 1 "Run #[0-9]*:"` ポジション。

# 追加されたFragment
```shell
adb shell dumpsys activity top | grep 'Added Fragments' -A 5
```
`-A` の後の数字は表示する行数なので、fragmentがたくさんあって5行じゃ足りない場合は増やし、fragmentが少なくてより短く見たい場合は減らしてください。

# 最後に
情報提供いただけると幸いです！
GASでWebアプリ｢映画鑑賞記録｣を作る⑩ ／ Vue.jsでラジオボタンを使用する

# 今回やること
　ダイアログボックスの「初見」の入力項目を、ラジオボタンに変更します。

# ダイアログボックスの「初見」を変更
#### modalScript.html
　テキストボックス（`<input type="text"…>`）をラジオボタン（`<input type="radio"…>`×2）に変更します。
　本項目への入力値は、`1`が「**初めて観た**」で、`0`が「**既に鑑賞した事がある**」です。
　ラジオボタンのラベル（`<label>`タグ）は、前者を`はい`、後者を`いいえ`とします。
　データのバインドは、テキストボックスの時と同様に`v-model="cond.firstLook"`で行います。

```html
<script type="text/x-template" id="modal-template">
  <transition name="modal">
      ：
              <div class="form-group">
              <div class="input-group">
                <label for="first-look" class="col-form-label">初見：</label>
                <!-- <input type="text" class="form-control" id="first-look" v-model="cond.firstLook"> -->
                <input type="radio" name="first-look" class="form-control" id="first-look-yes" v-model="cond.firstLook" value="1">
                <label for="first-look-yes" class="form-control" style="border: 0px;">はい</label>
                <input type="radio" name="first-look" class="form-control" id="first-look-no" v-model="cond.firstLook" value="0">
                <label for="first-look-no" class="form-control" style="border: 0px;">いいえ</label>
              </div>
              </div>
      ：
  </transition>
</script>
```
　`<label>`タグは、`class="form-control"`により枠線が表示されるので、`style="border: 0px;"`を指定して非表示にします。
　　**◆**`style`指定なし
　　　　![radio1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510221/17f89e68-414a-2929-50f2-f44254d5b0db.png "style 指定なし")
　　**◆**`style`指定あり
　　　　![radio2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510221/1f85584c-72b7-9c57-c198-b6cb5783ffe3.png "style 指定あり")
　**◆参照サイト** Vue.js 公式サイト [フォーム入力バインディング](https://jp.vuejs.org/v2/guide/forms.html)

# 結果
　「初見」がラジオボタンに変更されました。
![radio3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510221/3ce04a5f-f927-1ef7-6a77-584468b72c18.png)

**◆前の記事** [GASでWebアプリ｢映画鑑賞記録｣を作る⑨](https://qiita.com/pump33/items/d46bad65f3a234152866)
**◆次の記事** [GASでWebアプリ｢映画鑑賞記録｣を作る⑪](https://qiita.com/pump33/items/016c73134eba6609d2f8)

**◆索引** [GASでWebアプリ｢映画鑑賞記録｣を作る《索引》](https://qiita.com/pump33/items/8ded0e6fd3c336e705f4)
STM32L010F4PxとCubeMXでhello world

## 動機

mbedライブラリでやってる人がいた。

[STM32L010のシリアルでHello Worldと出力 - Qiita](https://qiita.com/caa45040/items/3e5d7bab624051d69357)

ためしにCubeMXでもやってみた。

## 設定

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264452/91e43152-acba-09a0-0ec2-e28b6bc7fdc4.png)

USART2を有効にして、LEDのピンも定義。基本的に全部デフォルト。

## mainのループ

```c
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
    {
        const uint32_t tick = HAL_GetTick();
        char buff[30] = "hello world XXXX.XXX\n";

        buff[12] = tick / 1000000 % 10 + '0';
        buff[13] = tick / 100000 % 10 + '0';
        buff[14] = tick / 10000 % 10 + '0';
        buff[15] = tick / 1000 % 10 + '0';
        // ピリオド
        buff[17] = tick / 100 % 10 + '0';
        buff[18] = tick / 10 % 10 + '0';
        buff[19] = tick / 1 % 10 + '0';

        HAL_UART_Transmit(&huart2, (uint8_t *)buff, strlen(buff), 10);
    }

    HAL_GPIO_TogglePin(USER_LED_GPIO_Port, USER_LED_Pin);
    HAL_Delay(500);

    /* USER CODE END WHILE */
    /* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
```

適当なバッファを作って`hello world nnnn.nnn\n`の文字列を作る(`nnnn.nnn`はマイコン内の時間を秒で書き込む)。
あとはHALに丸投げしてUARTで転送。LEDチカチカも。

![2021-05-07_05-48-13_IMG_0381.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264452/ae476c28-6e76-43f0-a23f-ca42e1bf2b3b.jpeg)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264452/35f35735-d2be-3e5d-04ed-c32a629ce617.png)

1回毎に2ミリ秒ずつくらい時間がずれてる。
20バイトあまりを115.2kbaudで送ると1.8msほどかかるので、1回毎に2msずつずれていく。

***

バイナリサイズは7KBくらいになった。ROMは16Kなので、もう少しいろいろできそう。
sprintfで`"hello world %lu\n"`みたいに文字列化させるとバイナリは9KBくらいになる。

arm-none-eabi-objdump -h -wにELFを読み込ませると、.dataと.bssがそれぞれ0xC、0xE4と表示された。`-fstack-usage`で各関数のスタック使用量を出してみると、`SystemClock_Config`が104バイトで最多だった。
スタックが余裕を見て256バイト、dataとbss合わせて256バイト、として、512バイトが使用済み、1.5KiBの空き、ということかな? 結構余裕ありそうな気がしてきた。

試しにRTOSも入れてみたけど、CMSIS-v2ラッパーはメモリ不足でビルドすらできず、v1ラッパーならあちこち削ってかろうじてタスク3個くらいは最低限動くかも、くらい。100円未満のマイコンにRTOSなんてのせちゃいけない(戒め)。
100円以上のマイコンなら載せてもいいのかって? STM32G031J6MxならRAMが8Kと、STM32L010F4Pxの4倍もあるから、RTOSもそれなりに使い物になりそうな気がする。今度はGPIO少なすぎて何やればいいのかわからないけど。気が向いたら試してみよう。
[Git] ローカルのブランチが増えすぎて、まとめて消したい時に使うコマンド

## 概要

- ローカルのブランチが増えすぎて、まとめて消したい時に使います。
- master以外全部消します。

```bash
$ git branch | grep -v master | xargs git branch -D
```

以上です。あざました。
googleログインフォームが環境によって微妙に変わることへのe2e自動テストの対応

e2eのテストで「GoogleIDでログイン」的なのを書いてたときの気付き。

なんか、Google連携ログインするときのフォームが環境によって全然違う…
パスワード入れて確定するボタンが「次へ」の場合と「ログイン」の場合があるみたい。
(そもそも、アカウント1つで全てのGoogleサービスを。の画面は、ローカルPCではどうやっても出せなかった…)

### ローカルPCで実行した場合(よく見るヤツ)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/158169/f9140f76-e0b7-fdfb-52c9-63244d8324f6.png)

### CI環境で実行した場合(こんなのもあるんだ)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/158169/796be92d-1e1b-9289-777b-1d5fd7eeeeb7.png)

## 解決策(姑息)

`I.pressKey("Enter")`　(要素を取得する代わりにエンターキーを押してしまう作戦)

気づくまで結構時間がかかったけど、これで動いたぞ！
jib-maven-pluginでAzure Container RegistryにSpring Bootアプリのイメージを登録する

以下のクイックスタートを参考にSpring BootアプリのイメージをAzure Container Registryに登録してみました。

https://docs.microsoft.com/ja-jp/azure/container-registry/container-registry-java-quickstart

クイックスタートと以下の点で異なる手順を試しました。
- Azure Container RegistryはAzure CLIではなくダッシュボードで作成
- [Spring Initializr](https://start.spring.io/)で作成したプロジェクトを利用
- Azure Container Registryでアクセスキーを発行

以下まとめます。

# Azure Container Registryの作成

コンテナーレジストリを選びます。
![2021-05-07_20h15_29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47737/3cc3be15-fa2d-3e94-cee7-1629d7ce592e.png)

SKUはBasicにしました。

![2021-05-07_20h14_55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47737/496d994b-c2a6-104d-e202-410101d5a756.png)

作成後「アクセスキー」の管理者ユーザを「有効」にしました。クイックスタートの中ではAzure Container Registryの認証について特に書かれていないのですが、何もしないままだと認証エラーになってしまったので今回はこの手順を踏みました。

![2021-05-07_20h19_13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47737/311c7de4-6698-2da9-588e-0ff09e9adcc3.png)

Azure Container Registryの準備は以上です。

# Spring BootアプリとJibの準備

クイックスタートでは[Spring Boot on Docker Getting Started](https://github.com/spring-guides/gs-spring-boot-docker)のコードをCloneしていますが、私は[Spring Initializr](https://start.spring.io/)で作成したプロジェクトを使いました。依存性に加えたのはSpring Webのみです。

pom.xmlに[jib-maven-plugin](https://github.com/GoogleContainerTools/jib/tree/master/jib-maven-plugin)の定義を追加して、さきほどAzureで作成したAzure Container Registryのサーバを指定します。（ここでは作成するリポジトリ名をdemoにしました）

認証情報も設定します。


```xml
<build>
	<plugins>
		<plugin>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-maven-plugin</artifactId>
		</plugin>
		<plugin>
			<groupId>com.google.cloud.tools</groupId>
			<artifactId>jib-maven-plugin</artifactId>
			<version>3.0.0</version>
			<configuration>
				<to>
				    <image>xxxxxxxxxxx.azurecr.io/demo</image>
				    <auth>
				        <username>xxxxxxxxxx</username>
				        <password>xxxxxxxxxxxxxxx</password>
				    </auth>
				</to>
			</configuration>
		</plugin>
	</plugins>
</build>
```

あとは以下でビルドするだけです。これでSpring BootアプリのイメージをAzure Container Registryに登録してくれます。

```
mvn compile jib:build
```

リポジトリを確認すると無事作成されています。

![2021-05-07_20h27_27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47737/7f3e32cb-1959-31b2-0eab-2c64ef46eb55.png)

認証周りはもう少し理解を深めたいです。
【AWS】パブリックサブネットの作成方法

#プログラミング勉強日記
2021年5月7日

#パブリックサブネットの作成方法
　パブリックサブネットからインターネットに接続するためにはインターネットゲートウェイが必要になる。(サブネットについては[こちらの記事](https://qiita.com/mzmz__02/items/6151277d91ce3b4da82c)で詳しく扱ってる)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/642821/94b65ea5-58f6-892f-53c5-389449c2b426.png)


　このようにパブリックサブネットにするためにはインターネットゲートウェイのルートを作る必要がある。この設定を<b>ルーティング構成</b>という。インターネットゲートウェイへのルートがあるサブネットがパブリックサブネットで、そうでなければプライベートサブネットになる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/642821/a81ebb7b-74b9-649f-9b63-52158c4425f5.png)

　ルートテーブルはルーターの中に配置されていて、インターネットゲートウェイはインターネットとやり取りをするルーターの1つとなっている。そのため、インターネットゲートウェイにも自身を示すルートテーブルがある。サブネットにもデフォルトでルーターがあって、そこにルートテーブルが使われている。ルートテーブルを設定して、インターネットゲートウェイへのルートを付けるとルーティング構成が完了する。
　つまり、サブネットのルートテーブルにインターネットゲートウェイへのルートを設定することで、パブリックサブネットを作ることができる。
そういやmapメソッドってなんだっけ？

そういやmapメソッドって何だっけと、ふと疑問に思いまとめてみました。

## mapメソッドとは
**mapメソッドは配列の要素の数だけブロック内の処理を実行し、作成された配列を返すメソッド**です。
要素それぞれに指示した処理をしてくれます。
似たようなメソッドには**eachメソッド**がありますね。

eachメソッドは戻り値は元の配列、mapはブロック処理をした後の値を集めた配列を戻り値にします。
**配列を元に新たな配列を作成する場合はmapメソッド**を
**繰り返し処理をするだけの場合はeachメソッド**を使いましょう。

## mapメソッドの基本的な書き方
```ruby
配列.map { |変数| 実行する処理 }


# 実行する処理が複数行の場合
配列. map do |変数|
  実行する処理
end
```
#### 使用例

```console
irb(main):001:0> numbers = [10, 20, 30, 40]
=> [10, 20, 30, 40]
irb(main):002:0> new_numbers= numbers.map { |n| n * 2 }
=> [20, 40, 60, 80]
irb(main):003:0> new_numbers
=> [20, 40, 60, 80]
```

## map!メソッド
mapメソッドとは別でmap!メソッドというメソッドがあります。
mapメソッドとの違いはmapメソッドは元となった配列を変更しないのに対して、
map!メソッドは元の配列を書き換えます。破壊的メソッドと呼ばれるタイプです。

書き方はmapメソッドと同じで
## mapメソッドの基本的な書き方
```ruby
配列.map { |変数| 実行する処理 }


# 実行する処理が複数行の場合
配列. map do |変数|
  実行する処理
end
```
になります。

#### eachメソッドとmapメソッド、map!メソッドの実行結果

```ruby
numbers = [1,2,3,4,5]

puts "each"
numbers_each = numbers.each {|n| n*2}
# 返り値は元の配列なので、[1,2,3,4,5]が出力される
p numbers_each

puts "map"
numbers_map = numbers.map {|n| n*2}
# 返り値はブロック処理の結果を集めた配列なので、
# ２倍になった配列が出力される
p numbers_map

puts "map!"
numbers.map! {|n| n*2}
# 破壊的メソッドは元の配列を書き換える
p numbers
```

```console
each
[1, 2, 3, 4, 5]
map
[2, 4, 6, 8, 10]
map!
[2, 4, 6, 8, 10]
```
注目していただきたいのはmapメソッドは`numbers_map = numbers.map {|n| n*2}`として
処理をされたものを代入して出力されているのに対して
map!メソッドは代入せずに`numbers.map! {|n| n*2}`で`number`の値が変わっているところです。

### mapメソッドの省略形
mapメソッドは3つの条件が合えばブロックを渡す代わりに`&:メソッド名`を使って
省略して書くことができます。

1. ブロックの引数が1つであること
1. ブロックの呼び出すメソッドに引数がないこと
1. ブロック引数に対して、メソッドを呼び出す以外の処理がないこと

```ruby
# 通常の書き方
["RUBY", "RAILS", "VUE.JS"].map { |s| s.downcase }
=> ['ruby', 'rails', 'vue.js']

# 省略した書き方
["RUBY", "PHP", "JAVA"].map(&:downcase)
=> ["ruby", "rails", "vue.js"]
```


## mapメソッドの応用的な使い方

### データベースから特定の値だけを配列にする
mapメソッドはテーブルから特定のカラムを取り出したいときに便利です。
例えばUserテーブルからemailだけを取り出して新たに配列を作ることができます。

```ruby
users = Users.all
users.map { |user| user.name }
```
```console
=> ["Maria", "Jun", "Norah", "Lucas", "Sophia", "Chin", "Tom", "Taro"]
```

#### 注意
紹介しておいて何なんですが、mapメソッドはテーブル全体から取り出したものを配列に返すので
このように**データベースから特定の値だけを配列にする場合はpluckメソッド**を使いましょう。
**pluckメソッドはデータベースから取り出す段階で特定のカラムを取り出す**ため
パフォーマンスが上がります。

#####逆にpluckメソッドを使わずmapメソッドを使った方がいいとき
インスタンス化したオブジェクトからデータを取得する場合は、mapメソッドを使いましょう。
理由としては、**pluckメソッドはインスタンス化したオプジェクトに対しても毎回SQLを実行してしまいパフォーマンスの低下に繋がるから**です。



> 参考サイト
[Pikawaka ](【Ruby】mapメソッドの基礎から応用をマスターして、効率的なコードを書けるようにしよう！)
[TechAcademyマガジン Rubyのmap/map!メソッドの書き方を現役エンジニアが解説【初心者向け】](https://techacademy.jp/magazine/21362)
MacBook Pro 2016でDELLのP3421W（ウルトラワイドディスプレイ）を使う


現在使っている「MacBook Pro (13-inch, 2016, Four Thunderbolt 3 Ports)　 / MacOS Catalina 10.15.4」で、DELLのウルトラワイドディスプレイ（P3421W）を「USB-C」で使用したところ、解像度が「2560 x 1080」になってしまい、「3440 x 1440」にならない。

ざわざわ。。。まさか。。。

グラフィックスドライバの更新は、Appleのソフトウエアアップデートが必要っぽい。
インテルのサイト見ても、Windows版ドライバーのアップデートしかない。
ネットでいろいろみてみるも、BigSir（11.1）でも、ダメな模様。
自分はアプリケーションの環境都合で、OSのメジャーアップデートは、いろいろと動作確認の情報が確認できるまでやりたくないタイプ。

なんとかOSアップデートせずにできないかなぁ〜と思って、試行錯誤しました。

# 変換アダプタをいろいろ使ってみる

自分は物持ちがいい性分なので、いろいろ変換アダプタとか持ってます。
そこで、古いケーブル保管箱をあさって、アダプタとケーブルたちを組み合わせて繋いだところ、無事「3440 x 1440」で表示できたので、その方法をご紹介します。
誰かの役に立てれば幸い。

# 失敗した接続構成
MacBook Pro (13-inch, 2016, Four Thunderbolt 3 Ports)
↓
USB-C/HDMI変換アダプタ（ノーブランド）
↓
HDMIケーブル（モニタに付属）
↓
DELL P3421W（3440 x 1440）

解像度は「3440 x 1440」になったが、画面の色が虹色に。。。
なんだこりゃ？変換アダプタの問題かな。
ノーブランドだったのできっとしょぼいチップを使っているのだろう。
調べたところ、対応しているアダプタなら素直に表示できそうではあるが、HDMI-USB-C変換で、手元にあるのはこのノーブランドだけ。
買い直すのもちょっと。

何か組み合わせはないか。。。



# 成功した接続構成 
今さら？なケーブルではあるがDVI-Dの在庫があった。
DVIだとUSB-Cに変換するとPowerDelivery出来なさそうではあるが、目的は「3440 x 1440」で使えるレベルの表示！

変換に変換を重ねて試してみる。

MacBook Pro (13-inch, 2016, Four Thunderbolt 3 Ports)
↓
USB-C/DVI-D変換アダプタ（StarTech.COM CDP2DVIW USB Type-C-DVI変換ディスプレイアダプタ ホワイト）
↓
DVI-Dケーブル
↓
DVI-D/HDMI変換アダプタ（Appleのやつ）
↓
DELL P3421W（3440 x 1440）

解像度は「3440 x 1440」で表示され、カラーも問題なし！
ただし、周波数が30Hz!?

画面の動きがまぁまぁもたつくが、Youtubeとかみる分には我慢できるレベル。
チラつきも特には感じない。
動きの速い動画とかゲームは厳しいかもですが、iOSアプリ開発では、XCodeの画面のめちゃくちゃ広くなってGOODです！


## 最終的な構成
自分は、「MacBookPro」と「DELL Latitude 5310」ノートが２台あり、ディスプレイ２枚とノート２台を使い分けながら、トリプルディスプレイにしているので、以下のようなつなぎ方で、ディスプレイから２本線をはやして、必要に応じて挿し分けている。

### MacBookPro 2016 + DELL P3421W + IO DATAの20インチ
→USB-C/DVI-D変換アダプタ → DVI-Dケーブル → DVI-D/HDMI変換アダプタ（Appleのやつ）
　+ IO DATAの20インチ
　　→USB/DVI-D変換アダプタで追加接続
　　
### Latitude 5310 + DELL P3421W + IO DATAの20インチ
→ USB-Cで直
　+ IO DATAの20インチ
　　→USB/DVI-D変換アダプタで追加接続

という感じで使い分けてつなぎました。
デスク周り、全然スッキリしてないけどw


# 最後に
ケーブル関係って「何かで使うことがあるかも」と思って捨てられない性分なとこもあり、保管箱にD-Subやら、DVI-Dやら、HDMI変換やら、いろいろ持っていたので、組み合わせでなんとか繋げられました。

ケーブル、いろいろ持っててよかった！

(FireWireは、まだ使ってるけど、SCASIIはさすがに捨ててもいいかな（笑）


# p.s.
アップルのディスカッションサイトでも困っている人がいました。
OSバージョンは違えど、自分と同じ状況。
他にも困っている人がいると思うので、誰かの役に立てば幸いです。

# 余談
IO DATAの20インチワイドが余っているので、アーム買ってモニタ３枚にしようかな。
合計すると、20+20+34=74インチ+ノートの画面。
モニタ１枚は、datadog表示専用にできるw
.envファイルに#(シャープ)を含める

ECRのサービス起動時の環境変数の指定でenvファイルを切り替える試験をしている最中に設定した値がちゃんと認識されない。

原因はenvファイルの値に#(シャープ)が含まれていることだった。
以下のようにダブルクォーテーションで囲って解決。

```
HOGE_ENV="hoge#moge"
```

そもそも色々とenvファイルに書くのもよろしくないので
ルールを決めてAWS Systems Managerのパラメータストア使ったほうが良い。
あくまで#の回避方法のメモ。
※訂正済み Refinery CMSを日本語化する際の注意点

### ※ 2021/5/7 21:42追記
誤解だったので訂正いたします。
以下のようにスラッグのカスタマイズ（URLを自由な文字列に指定できる機能）を有効にしている場合、注意が必要です。

```config/initializers/refinery/pages.rb
config.use_custom_slugs = true
```
`seeds.rb`の文頭において以下のように日本語化の設定をしなければ、**トップページの初期データが日本語化せず、編集できなくなる問題**があるようです。

```seeds.rb
I18n.locale = ::Refinery::I18n.default_locale
```

こちらの問題を誤解しておりました。訂正いたします。


###参考ページ
https://www.farend.co.jp/blog/2019/01/refinerycms

<br>
<br>
###以下、訂正前の記事
※複数形のままでも問題なく動きます。
<br>

~~デフォルトの言語は当然英語であり、設定を`:en`から`:ja`へと書き換えるのですが、1点引っかかったので注意。
以下はミスの例です。~~

```config/initializers/refinery/i18n.rb
- # config.default_locale = :en
+ config.default_locale = :ja
- # config.current_locale = :en
+ config.current_locale = :ja
- # config.default_frontend_locale = :en
+ config.default_frontend_locale = :ja
- # config.frontend_locales = [:en]
+ config.frontend_locales = [:ja]
```
~~この状態で実行すると以下のようなエラーが出てしまいます。~~

```
ActiveRecord::RecordNotFound in Refinery::Admin::PagesController#edit
```

~~このエラーの原因は最後の行にあります。
`frontend_locales`は`:ja`の1つなので、複数形ではおかしいのです。
よって以下のように単数形へと修正します。~~

```config/initializers/refinery/i18n.rb
- # config.frontend_locales = [:en]
+ config.frontend_locales = [:ja]
```

~~4つある項目のうち`frontend_locales`だけデフォルトが複数形になっているので、気づきにくい落とし穴でした。~~




### Refinery CMS公式
https://www.refinerycms.com/guides/getting-started/
Rubyのメソッドについて

メソッドとは複数の処理を１つにまとめて扱いやすくしたものをいいます。

メソッドの構文は
`def メソッド名(引数1,引数2・・・)
   実行したい処理
  end`
と記述します。

例文としてHello Worldと出力したいメソッドを記述する時は

```ruby
def hello_world
  puts 'Hello World'
end

hello_world
```
引数を書かなくても実行することができます。
５行目でメソッドを呼び出し、putsで出力しています。

メソッド名の命名規則として先頭は必ずアルファベットで書きます。
先頭を数字にするとエラーが起こります。

引数を設定するパターン

```ruby
def add(a,b)
  a + b
end

puts add(1,2)
```
これはadd(1,2)の引数を1行目の(a,b)に渡し、２行目のa + bが実行されて戻り値が返され
結果３が出力されます。
ちなみにJavaScriptなんかでは戻り値をreturnで指定したりしますがrubyでは書く必要はありません。

応用編として
動物の種類によって鳴き声を返すcryメソッドを作成。
動物に種類がdogであれば戻り値'ワンワン'を返し
それ以外なら戻り値'？？？'を返します。

```ruby
def cry(animal)
  if animal == 'dog'
    'ワンワン'
  else
    '？？？'
  end
end

puts cry('dog')
```
この場合は引数dogをanimalに渡し、２行目の条件式が成り立つので結果'ワンワン'と出力されます。
別のインスタンスからメッセージを変更する


Vue.jsではルートVueインスタンスを作成することで起動されます。
**別のインスタンスからアクセスしてメッセージを変更するには関数を使って値を生成して代入してあげる。**


```vuejs
var vm = new Vue({ // オプション })
varvm=newVue({
  // オプション
})
```

*vmはViewModelの意味であり、MVVMパターンの影響を受けているとのこと。
*varは変数の宣言で「var 変数名 = 値」となる。


```vuejs
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script>
  <div id="app1">
     <p>{{message}}</p>
  </div>
  <div id="app2">
    <p>{{message}}</P>
    <button @click="changeMessage1">メッセージ変更</button>
 </div>
<script>
  var vm1 = new Vue({
    el: '#app1',
    data: {
      message: 'app1'
    }
  })

  var vm2 = new Vue({
    el: '#app2',
    data: {
      message: 'app2'
    },
    methods: {
      changeMessage1: function() {
        vm1.message = 'インスタン２から変えました'
      }
    }
  })
</script>
</body>
</html>
```

実行すると

![20210507-195333.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/960935/c557076f-855e-99b3-05b0-09c493366733.png)


![20210507-195314.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/960935/6f723666-ceec-8681-b85b-a2d3b095d9bb.png)
Kotlin で Javadoc の @link を書く

## どうするの

`[]` これで囲んでパッケージとか関数とか書く

```kotlin
/**
 * [{package}.{func}] を見ると真の使い方がわかる
 */
fun hoge(): String
```

## ref
https://kotlinlang.org/docs/kotlin-doc.html#kdoc-syntax

Markdown っぽく書けるらしい
Kotlin の場合は KDoc って名前がついてるのも今知った
Dateクラスで曜日を表示させる

#はじめに

アウトプット用に記述します。

# Dateクラスについて

DateクラスとはRubyの標準ライブラリの機能です。

```.rb
require "date"
```
下記で今日の日付を表示する事ができます

```.rb
require "date"

puts Date.today

#今日が2021年5月7日のため
=>2021-05-07
```
曜日を表す時は...

```.rb
puts Date.today.wday

=> 5
#数字？
```

数字が出てきますので、配列で曜日の配列もセットで作ります。

```ruby
day = Date.today.wday

week =["日曜日", "月曜日", "火曜日", "水曜日", "木曜日", "金曜日", "土曜日"]

#dayを添字にする
puts "#{week[day]}"

#今日が金曜日のため
=> 金曜日
```
中国剰余定理を証明とともに理解する

## はじめに
競技プログラミングで中国剰余定理（Chinese Remainder Theorem; CRT）を使う問題が出てきたので，証明を含む概要を備忘録として記した．

本記事は以下を参照して作成した．<br>
https://qiita.com/drken/items/ae02240cd1f8edfc86fd<br>
また，拡張ユークリッドの互除法を事前説明なしに用いている．

## 中国剰余定理とは

中国剰余定理は以下のように表される.

$m_1, m_2, m_3, \dots, m_n$をどの2つも互いに素な自然数とする．<br>
この時，任意の整数$b_1, b_2,b_3,\dots,b_n$に対して，

```math
x\equiv b_1 \ ({\rm mod}\ m_1)\\
x\equiv b_2 \ ({\rm mod}\ m_2)\\
\vdots\\
x\equiv b_n \ ({\rm mod}\ m_n)
```
を満たす整数$x$が存在する．また，$M=m_1m_2\dots m_n$とすると，上記を満たす0以上$M$未満の$x$はただ一つ存在し，特にそれを$r$とすると以下が成立する．

```math
x\equiv b_1 \ ({\rm mod}\ m_1)\\
x\equiv b_2 \ ({\rm mod}\ m_2)\\
\vdots\\
x\equiv b_n \ ({\rm mod}\ m_n)\\
\Leftrightarrow x\equiv r\ ({\rm mod}\ M)
```

この定理は法が互いに素である複数の合同式による条件を一つにまとめることができることを述べている．<br>
例えば，「3で割ると2余り，かつ7で割ると4余る」という条件を満たす整数は，$11,32,53,74,95$などである．つまり，

```math
x\equiv 2 \ ({\rm mod}\ 3)\\
x\equiv 4 \ ({\rm mod}\ 7)
```
という条件と
$$x\equiv 11 \ ({\rm mod}\ 21)$$
という条件が同値となる．


## 中国剰余定理の証明（2元ver. ）
ここでは，2元の場合である

```math
x\equiv b_1 \ ({\rm mod}\ m_1)\\
x\equiv b_2 \ ({\rm mod}\ m_2)
```
を満たすxが0以上$m_1m_2$未満の間にただ一つ存在することを示す．3元以上の場合も同様に示すことができる．<br>
ここでは，まず解の存在性を示し，その後，解の一意性を示す．

### 解の存在性
実際に解を構成することで存在を示す．
$m_1$と$m_2$は互いに素であるため，最大公約数は1である．したがって，拡張ユークリッドの互除法より，
$$m_1p+m_2q=1$$
を満たす整数の組$(p,q)$を構成できる．
この時，$m_2q=-m_1p+1,m_1p=-m_2q+1$なので，

```math
m_2q\equiv 1\ ({\rm mod}\ m_1)\\
m_1p\equiv 1\ ({\rm mod}\ m_2)
```
が成り立つ．
したがって，$x=b_2m_1p+b_1m_2q$とすれば，

```math
x\equiv b_1\ ({\rm mod}\ m_1)\\
x\equiv b_2\ ({\rm mod}\ m_2)
```
となる．したがって，この$x$を$m_1m_2$で割った余りが解なので存在が示された．

### 解の一意性
0以上$m_1m_2$未満の間に解が2つ存在したと仮定する．<br>
この解を$x,y\ (<m_1m_2)$とすると，

```math
x\equiv b_1,y\equiv b_1\ ({\rm mod}\ m_1)\\
x\equiv b_2,y\equiv b_2\ ({\rm mod}\ m_2)
```
が成立するので，$x-y$は$m_1$と$m_2$で割り切れる．
いま，$m_1,m_2$は互いに素なので，$x-y$は最小公倍数である$m_1m_2$で割り切れることとなり，
$$x\equiv y\ ({\rm mod}\ m_1m_2)$$
が成り立つ．$x,y<m_1m_2$より，$x=y$となるが，これは仮定に反する．
したがって，一意性が示された．

## 合同式をまとめる部分の証明
次に，

```math
x\equiv b_1 \ ({\rm mod}\ m_1)\\
x\equiv b_2 \ ({\rm mod}\ m_2)\\
\Leftrightarrow x\equiv r\ ({\rm mod}\ m_1m_2)
```
を示す．
### 必要性(→)
これまでの議論から，

```math
r\equiv b_1 \ ({\rm mod}\ m_1)\\
r\equiv b_2 \ ({\rm mod}\ m_2)
```
を満たす$r$が0以上$m_1m_2$未満の範囲にただ一つ存在する．<br>
ここで，この$r$とは異なる0以上$m_1m_2$未満の整数を$r'$とし，

```math
x\equiv b_1 \ ({\rm mod}\ m_1)\\
x\equiv b_2 \ ({\rm mod}\ m_2)\\
x\equiv r'\ ({\rm mod}\ m_1m_2)
```
を満たす$x$が存在したと仮定する．
この時，$x$は整数$x'$を用いて$x=m_1m_2x'+r'$と表すことができるので，

```math
x\equiv r'\equiv b_1 \ ({\rm mod}\ m_1)\\
x\equiv r'\equiv b_2 \ ({\rm mod}\ m_2)\\
```
となるが，これは$r$の一意性に反する．したがって，

```math
x\equiv b_1 \ ({\rm mod}\ m_1)\\
x\equiv b_2 \ ({\rm mod}\ m_2)\\
\Rightarrow x\equiv r\ ({\rm mod}\ m_1m_2)
```
である．

### 十分性(←)

0以上$m_1m_2$未満の整数$r$が

```math
r\equiv b_1 \ ({\rm mod}\ m_1)\\
r\equiv b_2 \ ({\rm mod}\ m_2)
```
を満たすとする．この時，
$$x\equiv r\ ({\rm mod}\ m_1m_2)$$
を満たす任意の整数$x$を考える．
$x$は整数$x'$を用いて$x=m_1m_2x'+r'$と表すことができるので，

```math
x\equiv r\equiv b_1 \ ({\rm mod}\ m_1)\\
x\equiv r\equiv b_2 \ ({\rm mod}\ m_2)
```
が成り立つ．
したがって，

```math
x\equiv b_1 \ ({\rm mod}\ m_1)\\
x\equiv b_2 \ ({\rm mod}\ m_2)\\
\Leftarrow x\equiv r\ ({\rm mod}\ m_1m_2)
```
である．
newインスタンスを２つ設置する


```vuejs
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script>
  <div id="app1">
     {{message}}
  </div>
  <div id="app2">
    {{message}}
 </div>
<script>
  new Vue({
    el: '#app1',
    data: {
      message: 'app1'
    }
  })

  new Vue({
    el: '#app2',
    data: {
      message: 'app2'
    }
  })
</script>
</body>
</html>
```

以下のようになります。

![20210507-192320.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/960935/08ba9149-dfc1-ccf2-8dd7-e040fca5948a.png)
【rails6】formの送信をしてもページが遷移しない問題の解決

こんにちは！

今日もアプリケーションの不具合を調べていたところ、思わぬミスを発見しましたので共有します

## 発生した問題
**アプリのform、送信ボタン（submit）を押しても画面が遷移しない**

実際に現象をご確認くださいませ

![444f81624bd826c9b1db4dd11ebed536.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1422262/98daa2d1-ea77-83d9-f21f-c3721522a518.gif)

見えていませんが、
「チャットを始める」のボタンを連打しています

このコードを確認くださいませ

```show.html.erb
<%= form_with model: @room do |f| %>
  <%= fields_for @entry do |e| %>
    <%= e.hidden_field :user_id, value: @user.id %>
  <% end %>
  <%= f.submit "チャットを始める", class:"mini-send-btn user-show-chat" %>
<% end %>
```

問題はこの箇所です

```
<%= form_with model: @room do |f| %>
```

実は、form_withにはturbolinksが関わっているそうです
私は諸々の事情でturbolinksを解除しておりますので、これでは画面遷移ができないのも納得ですね。

## 解決方法

解決法は下記２つあります

①turbolinksをオンにする

```app/javascript/packs/application.js
require("turbolinks")  // 初期設定ではONになってますが、ご確認ください
```

②このフォームでAjax通信を使用しない（local: trueを追記します）

```show.html.erb
<%= form_with model: @room, local: true do |f| %>   # local: trueを追記します
```

では、これでやってみましょう！
私は②の方法でやっていきますね

まずは先ほどのコードを直します

```show.html.erb
<%= form_with model: @room, local: true do |f| %>
  <%= fields_for @entry do |e| %>
    <%= e.hidden_field :user_id, value: @user.id %>
  <% end %>
  <%= f.submit "チャットを始める", class:"mini-send-btn user-show-chat" %>
<% end %>
```

![0d297d12cdd68910094cba1e15f8f0b7.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1422262/caeed698-da51-0c96-fd3a-fd52cb9e1c11.gif)

これで解決ですね！
今まで何気なく書いたり書かなかったりしていた記述ですが、とても大事なことだと認識しました。

※このGIFにあるもう一つのミスは見逃してください、これから直します
【JavaScript】繰り返し処理を利用し、九九を作成せよ。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/954863/c694c3d2-4ec8-ee7f-7881-7f14ed193397.png)

```javascript
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>九九</title>
</head>
<body>
    <script>
        var i = 0;
        var j = 0;
        var k;
        while (j < 9) {
          document.write("</br>");
          j++;
          i = 0;
            while (i < 9) {
              i++;
              k = j * i
              if ( k <= 9 ) {
                document.write( i + '✕' + j + '=' + '0' + k + '　' );
              }else {
                document.write( i + '✕' + j + '=' + k + '　');
              }
            }
        }
    </script>
</body>
</html>
```
v-forの利用上での注意点



**v-forディレクティブは要素の移動を最小限に抑えるアルゴリズムを使用し、可能な限りその場で同じタイプの要素を再利用しようとする。**

結論
######→v-forは予期しないエラーが起こるので必ずユニークなkey属性と共に用いましょう。

この内容をプログラムで表したいと思います。


```vuejs
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script>
<div id="app">
<ul>
  <div v-for="fruit in fruits">
   <p>{{fruit}}</p>
     <input type="text">
  </div>
</ul>
<button @click="remove">先頭を削除</button>
</div>
```

```vuejs
new Vue({
  el: '#app',
 data: {
    fruits: ['りんご','バナナ','キィウイ']
       },
    methods:{
    remove: function(){
      this.fruits.shift()
      }
    }
})
```

実行すると
![20210507-183959.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/960935/d024dcf8-54e2-eb8c-7fa4-f40c68a61dc7.png)

![20210507-183921.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/960935/5cfbc687-8a49-c584-f253-3c8293dee190.png)


問題点
-

インプットボックス内にそれぞれ上記を表す英語を入れて削除を実行すると
![20210507-184320.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/960935/ed9a3477-b205-6351-0a27-c03acc73269b.png)


![20210507-184340.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/960935/b17e7d28-f5c4-0e95-0291-bb489b61d958.png)

括弧内の表示が削除されずにずれます。

1.配列要素の'りんご','バナナ','キィウイ'についてはりんごが削除されて、りんごがバナナに置き換わり、バナナがキィウイに置き換わっている。

２.inputタグ内部は「可能な限り同じタイプ（inputタグ同士）の要素は再利用しようとする」でAppleが再利用され、Bananaが再利用されている。

この問題を解決する方法「Key」属性をあたえる
-

```vuejs
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script>
<div id="app">
<ul>
  <div v-for="fruit in fruits" v-bind:key="fruit">
   <p>{{fruit}}</p>
     <input type="text">
  </div>
</ul>
<button @click="remove">先頭を削除</button>
</div>
```

or

```vuejs
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script>
<div id="app">
<ul>
  <div v-for="fruit in fruits" :key="fruit">
   <p>{{fruit}}</p>
     <input type="text">
  </div>
</ul>
<button @click="remove">先頭を削除</button>
</div>
```


![20210507-184320.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/960935/21380fcb-fd57-98f3-8fa4-e2b2bf80a017.png)


![20210507-190045.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/960935/bfb48982-eeac-f415-6c13-0d1a8f882418.png)

利用上での注意点
-

（１）indexは使用しない。なぜか？りんごが削除されたときにバナナのインデックスが「１」から「０」になるのでユニークな値ではないため。

（２）テンプレートタグでは使用しない。テンプレートタグは表示されない「pisplay: noneの適用」だけで残っているため削除には用いない。

（３）配列内でりんごが２回登場する場合はユニークとならないので、配列ではなくオブジェクトとしてオブジェクト.idをkeyに利用することを考える。
レスポンシブ対応のハンバーガーメニューの作り方

https://pala-ghe.com/web/javascript/%E3%80%90%E7%B0%A1%E5%8D%98%E3%82%B3%E3%83%94%E3%83%9A%E3%80%91%E3%83%AC%E3%82%B9%E3%83%9D%E3%83%B3%E3%82%B7%E3%83%96%E5%AF%BE%E5%BF%9C%E3%81%AE%E3%83%8F%E3%83%B3%E3%83%90%E3%83%BC%E3%82%AC%E3%83%BC/
laravelアプリにGoogleログイン機能を追加し本番環境に反映させる

# 概要
Laraelアプリに追加でGoogleログイン機能を追加したので本番環境（Heroku）に反映させます。
https://qiita.com/u-dai/items/91df3b923dc82fed5b76
↑こちらの記事を参考にさせて頂きました。ありがとうございます。
ここからは、ローカル環境でGoogleログインが正常に動いている事を前提で進めていきます。

# 本番環境に反映

![eef9fb0ef38e38fe74d627a4c64cb109.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/851225/3ed9106b-4f7f-53ce-a4eb-2f57ae2d6ede.png)

本番環境のURIを追加します。

```php:URI
http://アプリケーション名.herokuapp.com/login/google/callback
```
Herokuの場合はこんな感じです。

そして最も大事な環境変数を設定していきます。
[記事](https://qiita.com/u-dai/items/91df3b923dc82fed5b76)通りに進めていくと、app/config/services.phpにて

```php:services.php
'google' => [
        'client_id' => env('GOOGLE_CLIENT_ID'),
        'client_secret' => env('GOOGLE_CLIENT_SECRET'),
        'redirect' => env('APP_URL') . '/login/google/callback'
]
```

このように記述したと思いますが、これら3つの環境変数をHerokuに設定していきます。

```php:terminal
% heroku config:set APP_URL=http://アプリケーション名.herokuapp.com
% heroku config:set GOOGLE_CLIENT_ID=○○◯○.apps.googleusercontent.com
% heroku config:set GOOGLE_CLIENT_SECRET=△△△△
```

後はデプロイすれば本番環境に反映されます。
めでたし、めでたし。

# おまけ
おまけというか個人的にはこちらが本題だったりします。
ローカルで動いたGoogleログインですが、本番で動かず焦った私は何を血迷ったのか、せっかく作った認証情報を削除して作り直してしまうのです。
それによりローカルでせっかく動いたGoogleログインにて、『エラー 401: deleted_client the oauth client was deleted.』と怒られる始末⤵︎
このエラーに半日費やしてしまうわけで…。

このエラーの解決方法は

```php:terminal
% php artisan clear-compiled 
% composer dump-autoload
% php artisan optimize
```

googleログインで他にもエラーが出ていたのですが、これらのコマンドで直った旨をメモしていたのが功を奏しました。このエラーにも使えるとは。
ありがたや、ありがたや。
Node.js の out of memory エラーが起きそうになったら例外を投げて通知する


## はじめに
Node.jsのバッチを保守していると、データ増加に伴いメモリー不足で処理が落ちてしまうことがありました。
エラー発生時にはChatworkに通知が飛ぶようにしていたのですが、そのときは通知が飛びませんでした。

そこで、メモリー不足で処理が落ちる前に、ある程度やばそうな量のメモリーを使っている時点で、警告を飛ばすようにしてみました。

## 処理内容
プログラムは次のような状態でした。

```yabaiyo.js
var メモリーを圧迫する変数 = []

function すごく繰り返す処理 (繰り返す回数) {
  for (var i = 0; i < 繰り返す回数; i++) {
    メモリーを圧迫する変数.push(new Array(10000))
  }
}

try {
  すごく繰り返す処理(1000000)
} catch (e) {
  チャットワークに警告を送信('やばいよ')
}

function チャットワークに警告を送信 (メッセージ) {
  console.log(メッセージ + 'をチャットワークに通知しました。')
}
```
これを実行すると、下記のようなログが出て処理が止まります。


```sh

<--- Last few GCs --->

[5414:0x100000000]     4874 ms: Mark-sweep 1824.4 (2051.4) -> 1824.4 (2044.9) MB, 692.6 / 0.0 ms  (average mu = 0.075, current mu = 0.014) allocation failure GC in old space requested


<--- JS stacktrace --->

==== JS stack trace =========================================

(省略)

FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory

(省略)

zsh: abort      node yabaiyo.js

```

やばいのにChatworkに通知が飛びません。


## 改善

これを防ぐために、次のような関数を用意しました。

```多分ほぼアウトオブメモリー.js
var v8 = require('v8')

function 多分ほぼアウトオブメモリー () {
  var stats = v8.getHeapStatistics()

  var 五百メガバイト = 500 * 1024 * 1024

  var ここを超えるとやばそう = stats.heap_size_limit - 五百メガバイト

  return stats.total_heap_size > ここを超えるとやばそう
}
```


「すごく繰り返す処理」の中に、「多分ほぼアウトオブメモリー」を判定する条件文を入れて、やばそうだったら例外を投げて「チャットワークに警告を送信」するようにしました。


```js
function すごく繰り返す処理 (繰り返す回数) {
  for (var i = 0; i < 繰り返す回数; i++) {
    メモリーを圧迫する変数.push(new Array(10000))
    // ↓ ここに追加
    if (多分ほぼアウトオブメモリー()) {
      throw new Error('多分ほぼアウトオブメモリー')
    }
  }
}
```

ファイルの全体像は下記になります。

```yabaiyo.js
var v8 = require('v8')

function 多分ほぼアウトオブメモリー () {
  var stats = v8.getHeapStatistics()

  var 五百メガバイト = 500 * 1024 * 1024

  var ここを超えるとやばそう = stats.heap_size_limit - 五百メガバイト

  return stats.total_heap_size > ここを超えるとやばそう
}


var メモリーを圧迫する変数 = []

function すごく繰り返す処理 (繰り返す回数) {
  for (var i = 0; i < 繰り返す回数; i++) {
    メモリーを圧迫する変数.push(new Array(10000))

    if (多分ほぼアウトオブメモリー()) {
      throw new Error('多分ほぼアウトオブメモリー')
    }
  }
}


try {
  すごく繰り返す処理(1000000)
} catch (e) {
  チャットワークに警告を送信('やばいよ')
}

function チャットワークに警告を送信 (メッセージ) {
  console.log(メッセージ + 'をチャットワークに通知しました。')
}

```


こうすることで、実行したときに次のように出力されます。

```sh
$ node yabaiyo.js

やばいよをチャットワークに通知しました。
```
python研修の振り返り②

python研修を終えたので、その備忘録としてメモ書きをしていきたい。
前回の①に続く形となります。
混乱しやすいところを中心に書きます。
誤りなどがあれば指摘いただければと思います


#エラーと例外処理
```error.py
my_list = [1,2,3]
my_list[4]

print("hello")
-----
IndexError  Traceback (most recent call last)
<ipython-input-3-edac7686cc0b> in <module>()
      1 my_list = [1,2,3]
----> 2 my_list[4]
      3 
      4 print("hello")

IndexError: list index out of range
```
```error2.py
my_list = [1,2,3]

try:
  my_list[4]
except:
  print("error")
print("hello")
----
error
hello
```
try~exceptを使用することで'error.py'ではエラーが返されたが、2つ目ではエラーが帰ってこず最後の"hello"が出力されていることが確認できる。エラー部分はexceptで処理が行われており、"error"が出力されている。

```エラー処理.py
try:
 実行したい処理
except:
 エラー時の処理
```

以下でエラー処理の例をもう1つ挙げておく。

```error3.py
try:
  r = 4/0
  print(r)
except ZeroDivisionError as err:
  print("error: ", err)
else:
  print("there's no error")
finally:
  print("all are done")

print("hello")
----
error:  division by zero
all are done
hello
```

上記のコードをみると4/0のため"0で割ることができない"というエラーが返ってくるはずである。そのためexceptではこのエラーが返ってきた時、エラーを出力するようにしている。もしエラーが返ってこなければelse文以下が出力される。最後のfinallyはエラーが起きても起こらなくても出力がなされる。

#クラス
クラスが自分(プログラミング初学者)にとって最も理解しづらかったところであった。自分は"同じものを何回も使い回すことができる便利なもの"と解釈している。
簡単な例を以下に示す。

```class.py
class food():
  def __init__(self, menu):
    self.menu = menu

mesi = food("rise")
main = food("meet")
drink = food("milk")

print(mesi.menu)
print(main.menu)
print(drink.menu)
----
rise
milk
meet
```


```class2.py
class greeting():
  def say_hello(self):
    print("hello")

Hi = greeting()
Hi.say_hello()
----
hello
```

def()内にある引数selfは慣習的なものらしい。ないとダメなようなので記載している。またclass.pyからわかるように「.」をつけることで、その内容にアクセスすることができる。また"__init __”は初期化メソッドであり必ず実行されるものである。

```car.py
class Car():
  def __init__(self, model ="None"): #modelの初期名はなし
    self.model = model
  
  def run(self):
    print("run")

class Toyota(Car):
  def run(self):
    print("fast")

class Tesla(Car): #Teslaの時のみmodelを先に宣言する
  def __init__(self, model="model S"):
    self.model = model

  def run(self):
    print("super fast")
  
  def auto_run(self):
    print("auto_run")

car = Car()
car.run()
print("----------")
toyota_car = Toyota("Lexus")
print(toyota_car.model)
toyota_car.run()
print("----------")
tesla_car = Tesla()
print(tesla_car.model)
tesla_car.run()
tesla_car.auto_run()
----
run
----------
Lexus
fast
----------
model S
super fast
auto_run

```
長々となってしまったが、ToyotaおよびTeslaの括弧の中のCarについて注目したい。各々はCarの特徴を受け取っており(今回であればmodel)、Toyota内でmodelの定義をしなくても、Carの特徴を引き継いでいることがわかると思う。

クラスに関して言えば自分の中で言語化できていないぶん、まだ理解しているとは言い難いのだとわかった。

研修におけるpythonの文法で気をつけなければいけないと思ったことは以上である。

最後までお付き合いいただきありがとうございました。
Mac 環境の Android Studio で実機が認識しなくてハマった。(iOS エンジニア with Flutter)

# 環境  
- MacOS Big Sur 11.3
- Android Studio 4.2 RC 1
- 実機 Google Pixel 5 (Android 11)

# 状況
スマホ側は開発者モードにもなっているし、USB デバッグも有効。
USB の設定も [ファイル転送] にしてあるが、全く認識しない。

#### adb devices
ググると `adb devices` コマンドで PC が認識している実機を確認せよと出てくるので、
試すと コマンドが無効と言われる。。
私は普段 Xcode を多用する iOS 側の人間だ。
色々調べて解決したのが以下の手順。

# 解決
#### PATH
Android SDK platform-tools の PATH を設定
`export PATH=$PATH:/Users/name/Library/Android/sdk/platform-tools`

#### adb devices
```
List of devices attached
HOGE012345678	unauthorized
```
adb コマンドは有効になったが unauthorized と出る。


#### file 削除
`/Users/name/.android/` 以下の２つの file を削除
`adbkey`
`adbkey.pub`

#### restart
`adb kill-server`
`adb start-server`

#### 実機接続
USB で実機を PC に接続すると、「接続を許可しますか？」のアラートが出る。

#### adb devices
再び `adb devices` を実行

```
List of devices attached
HOGE012345678   device
```
1台認識している。
削除した2つの file も再生成されている。
`adbkey`
`adbkey.pub`

#### Android studio
この状態で Android studio を見ると無事認識されました。
`Pixel 5(mobile)`
【Jest x TypeScript】モック関数jest.fn()の引数と戻り値に型をつける

jest.fn()は戻り値がundefinedの関数

```ts
const mockFn1 = jest.fn();

console.log(mockFn1()); // undefined
const r1 = mockFn1(); // mはany型
```

引数と戻り値の型だけを指定したい場合つぎのように書く。

```
jest.fn<戻り値の型, [第一引数の型, 第二引数の型]>();
```

## 例:

```ts
const mockFn = jest.fn<number, [string, number]>();
```

戻り値はundefinedのままだが、number型になっている。

```ts
console.log(mockFn('hoge', 1)) // undefine

const r= mockFn6('hoge', 1) // const r: number
```

正しい引数を渡さないとエラーになる

```
// Error: 2 個の引数が必要ですが、1 個指定されました。
// console.log(mockFn('hoge'))

// Error: 型 'boolean' の引数を型 'number' のパラメーターに割り当てることはできません。
// console.log(mockFn('hoge', true))
```

## [第一引数の型, 第二引数の型]と書くのはなぜか?

`mockFn.mock.calls`にモック関数を実行したときの引数が下のような形で格納される。この二重配列の要素である配列の型をタプル型で指定している。

```
[ 
　[ 関数を1回目に実行したときの第一引数, 第二引数 ], 
　[ 関数を2回目に実行したときの第一引数, 第二引数 ], 
]
```

```ts
console.log(mockFn.mock.calls); 
// [ [ 'hoge', 1 ] ]
```

## その他

調査したときのファイルまるごとコピペしておきます。

```ts
// jest.fn()は戻り値がundefinedの関数
const mockFn1 = jest.fn();

const mockFn2 = jest.fn((s: string):number => 100);

const mockFn3 = jest.fn<number, [string]>((s: string) => 100);

// Error: 型 '(s: string, n: number) => number' の引数を型 '(args_0: string) => number' のパラメーターに割り当てることはできません。
// const mockFn4 = jest.fn<number, [string]>((s: string, n: number) => 100);

const mockFn5 = jest.fn<number, [string, number]>((s: string) => 100);

const mockFn6 = jest.fn<number, [string, number]>();

test('', () => {
  // どのような引数でも渡すことができる
  console.log(mockFn1()); // undefined
  const r1 = mockFn1(); // mはany型

  // どのような引数でも渡すことができる
  console.log(mockFn1('hoge')); // undefined
  const r2 = mockFn1('hoge'); // mはany型
  
  console.log(mockFn2('hoge')); // hoge
  const r3 = mockFn2('hoge'); // m2はnumber型

  // Error: 1 個の引数が必要ですが、0 個指定されました。
  // const r4 = mockFn2();

  // Error: 型 'boolean' の引数を型 'string' のパラメーターに割り当てることはできません。
  // const r5 = mockFn2(true);

  const r6 = mockFn2('hoge');
  // r6はnumber型

  console.log(r6) // 100
  console.log(mockFn2('hoge')) // 100

  // Error: 2 個の引数が必要ですが、1 個指定されました。
  // console.log(mockFn5('hoge'))
  
  // Error: 2 個の引数が必要ですが、1 個指定されました。
  // console.log(mockFn6('hoge'))

  // Error: 型 'boolean' の引数を型 'number' のパラメーターに割り当てることはできません。
  // console.log(mockFn6('hoge', true))

  console.log(mockFn6('hoge', 1)) // undefined

  const r7= mockFn6('hoge', 1) // r7はnumber型

  type mockFnReturn = ReturnType<typeof mockFn6> // number

  console.log(mockFn6.mock.calls); // [ [ 'hoge', 1 ], [ 'hoge', 1 ] ]
});
```
v-forに整数値を置いてみた


```vuejs
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script>
<div id="app">
<ul>
  <li v-for="n in 10">{{n}}</li>
</ul>
</div>
```

![20210507-182414.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/960935/6df394dd-0a0e-f1d0-ed49-f92e83393aa6.png)

*in を　ofに変えてもきちんと動きます。