OmniAICreator/Qiita-1.07M huggingface dataset:
Excel VBAで、Outlookの予定を追加してみた

#Excel VBAで、Outlookの予定を追加してみた
Outlookで予定表を入れるとき、Outlookの予定の入力画面が多機能すぎるので、入力時に間違えることが多い。単にシンプルにExcelで前回の入力も保存できたりするので、VBAでつくってみた。
###新規で予定を作成する
Excelのセルに、あらかじめ次のシートを準備しておく
![olvba.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634486/93bd51dc-4161-9337-9b17-c41f294a2f28.png)
このB1～B5に入力されたデータをOutlookの予定として新規登録するようにした

###新規でOutlookの予定を登録するマクロ
```vb:
Sub 予定の作成() 
    Dim objOL        As Object
    Dim objApp       As Object
    Dim strSubject   As String
    Dim strStart     As String
    Dim strEnd       As String
    Dim strLocation  As String
    Dim lngRemind    As Long
    Dim strBody      As String
    Dim olAppointmentItem As Integer

    olAppointmentItem = 1

    Set objOL = CreateObject("Outlook.Application")
    strSubject = Sheet1.Range("B1")
    strLocation = Sheet1.Range("B2")
    strStart = Sheet1.Range("B3")
    strEnd = Sheet1.Range("B4")
    lngRemind = Sheet1.Range("B5")
    strBody = Sheet1.Range("B6")
        
    Set objApp = objOL.CreateItem(olAppointmentItem)
    With objApp
        .Subject = strSubject
        .Location = strLocation
        .Start = strStart
        .End = strEnd
        .Body = strBody
        .ReminderMinutesBeforeStart = lngRemind
        .ReminderSet = True
        .Save
    End With
    Set objApp = Nothing
    Set objOL = Nothing
End Sub
```
###つづきは
定期的な予定の登録、なんぞこれから作ってみようと思います。
GitHub Actions で、あるステップが失敗した時だけ実行するステップを定義する

GitHub Actions で `あるステップが失敗した時だけ実行するステップ` を定義したいんだけど、ってことがありました。
具体的に言うと、フロントエンドのテストに失敗した時だけ、スクショを artifact として残しておいて、後からスクショを確認したいとか(例えばです)。

そんな時にどうしたらいいかが、あんまり調べてもなかなか出てこなかったので書いてみます。

## 結論
結論から言うとこうする

```yaml
    - name: fail step
      id: fail_step
      run: exit 1

    - name: run if fail_step failed
      if: failure() && steps.fail_step.outcome == 'failure'
      run: echo "${{ steps.fail_step.outcome }}"
```

## ちょっと解説
やることは主に下記の

1. `あるステップが失敗した時だけ〜` に当たるあるステップに `id` を振る
2. `失敗した時だけ実行するステップ` を定義して、 `if: failure()` で以前の step が失敗した時だけ実行するようにする
3. `steps.<job_id>.outcome` で step の実行結果が取得できるので、 if の条件に追加する

## サンプル
https://github.com/t0yohei/exec-step-when-another-step-failed-sample

## 参考
https://help.github.com/ja/actions/reference/workflow-syntax-for-github-actions
https://help.github.com/ja/actions/reference/context-and-expression-syntax-for-github-actions#job-status-check-functions
ServiceNowのClient Scriptでローディングダイアログを出してみる

#はじめに
Client ScriptでGlideAjaxを呼び出している間などユーザー操作を抑制するために読み込み中のダイアログを出したかったので、[こちら](https://community.servicenow.com/community?id=community_question&sys_id=99fe0ba1dbdcdbc01dcaf3231f961920)を試してみました。
※検証はOrlandoで実施しています
#やったこと
インシデントのonLoad時にダイアログを表示してみます。
showLoadingDialog()でダイアログを表示し、hideLoadingDialog()で非表示にするようなので、インシデントを表示した際にダイアログを一定時間表示してみました。
###Client Script作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/450412/b4b4177a-e465-1edf-76e2-336dc456216f.png)

ダイアログを表示し、5秒後に非表示にします。

```Javascript:Script

function onLoad() {
    //Type appropriate comment here, and begin script below
    showLoadingDialog();
    setTimeout(function() {
        hideLoadingDialog();

    }, 5000);
}

```
#実行結果
Loadingダイアログが表示されました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/450412/9e50b1fb-1fd2-6dc4-44fb-43e1de1575d8.png)
謎のスクロールバーが少し気になります・・・
動的にスタイルをいじれば消えそうなことはわかりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/450412/5b86aea1-9174-dfeb-8af8-062558457955.png)

そこまでやる必要はないと思いますが、気になる場合消してもいいかもしれません。
【無限大の期待値？】サンクトペテルブルクのパラドックスをRでシミュレーション

ヨビノリたくみさんの動画「[期待値が無限大な賭け(サンクトペテルブルクのパラドックス)](https://www.youtube.com/watch?v=B__gzT-rQjw)」を見て面白そうだったのでシミュレーションしてみました。

## 問題設定
問題のゲームは、
確率1/2のコインを表が出るまで投げて、k回目に表が出たら2^(k-1)円賞金がもらえるというゲームです。

例えば、裏裏裏表、つまり４回目に表が出たら
2^(4-1) = 8　（円）
になります。

このゲーム、半分の確率で1円、1000円以上もらえる確率は0.1%にも満たない。
一回10万円でできると言われても絶対にやりたくない賭けなんですが、
期待値を計算すると無限大で、明らかに直感に反しています。

この問題を解決するために様々な方法が考えられましたが、
ウィリアム・フェラーは「標本抽出」という統計学の概念を用いました。
期待値は「母集団の平均値」であり、実際に獲得する賞金額は「標本平均」であると考えることで、
参加回数nによって標本平均が変化することを示しました。

## シミュレーション
今回シミュレーションするのは、[冒頭の動画](https://www.youtube.com/watch?v=B__gzT-rQjw)の20:30くらいから描いているグラフです。

n回参加するときの一回当たりの獲得賞金はnを大きくするとlog2(n)に近づく（正確には確率収束）らしいのでやってみます。

```R:
# サンクトペテルブルクのパラドックス

# 賞金を出力する関数を作る
reward <- function(){

      k <- 0 # 試行回数のカウント
	result <- 0 # コイン投げの結果：0を裏、1を表とする

        ## 成功するまで処理を繰り返す 
        while (result == 0) {
            k <- k + 1

            ##　コイン投げ
            result <- sample(0:1, size = 1, replace = TRUE, prob = c(0.5, 0.5))
	}
	return(2^(k-1)) # 賞金
}

# 賭けをやってみよう
cat("賞金は", reward(), "円")
# >>賞金は 2 円
```
```R:

# 賭けにn回参加した時の一回当たりの利得(S(n)/n)を計算する関数
rew_per_game <- function(n){
	S_n <- 0 # 合計利得
	for (i in 1:n){
		S_n <- S_n + reward()
	}
	return(S_n/n)
}

# グラフ描画

plotGraph <- function(m, n, ylim, by){

	par(new =F) # 新しいグラフを描画
	
	plot(log2(0:n+1), type = "l", col = "red", xlim = c(0,n+1), ylim = c(0,ylim),
		 xlab = '', ylab = '', pch = 20) # 理論値log2(n)のグラフ
	par(new = TRUE) # 次に描画するグラフを重ねる
	part = seq(1,n+1,by=by) # シミュレーションする参加回数のベクトル
	df <- data.frame(part = part, rew_per_game = 0, mean = 0) # シミュレーション結果を入れるデータフレーム
	for(i in 1:m){
		
		df <- data.frame(part = part, rew_per_game = 0, mean = df$mean) # データフレームの初期化

		df$rew_per_game <- lapply(df$part ,rew_per_game) # 各参加回数に対してシミュレーション
 
		plot(df$part, df$rew_per_game, xlim = c(0,n+1), ylim = c(0,ylim), pch = 20, cex = 0.01,
	 		xlab = '', ylab = '', axes = FALSE) # 結果のプロット
		par(new = TRUE)

		df$mean <- unlist(df$mean) + unlist(df$rew_per_game)/m # 平均値の計算
	}
	plot(df$part, df$mean, type = "b", col = "blue", xlim = c(0,n+1), ylim = c(0,ylim),
		 xlab = '', ylab = '') # 平均値のグラフ
}

# パラメータの設定
m = 10 # サンプル数
n = 1000 # 参加回数をn回まで描画
ylim = 30 # y軸最大値の設定
by = 100 # 参加回数何回ごとにシミュレーションするか

plotGraph(m, n, ylim, by)

```

m, n, ylim, by のパラメータをいじることでいろいろ遊べます。
![m=500.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/504259/b4597340-07ca-5c2d-7778-611dd352d4bc.png)

↑これはm=500, n=10000, ylim=50, by=1000

![m=10_n=100000_by=100.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/504259/dbc06247-be0c-a4e4-045f-2cc9db6bae90.png)
↑時間かかりますがこんなのもできます(m=10, n=100000, ylim=30, by = 100)

実際にシミュレーションするとばらつきが大きすぎて全然結果が安定しないことが実感できます。
ところでこれ、mを増やしたら一回当たりの獲得賞金も増えてしまうように思えるんですがどうなんでしょうか。
arduino+VSCode+Ubuntu18.04で開発環境を構築する

#はじめに
久しぶりにArduinoを使いたくなったので、せっかくなのでVSCodeで開発環境準備した

## arduino IDEのインストール
https://www.arduino.cc/en/Main/Software
からLinux 64bitsを選択

```bash:bash
cd ~/Download
tar Jxfv arduino-1.8.12-linux64.tar.xz
cd arduino-1.8.12
 ./arduino-linux-setup.sh $USER
sudo reboot # rebootしろって言われたら
```
![Screenshot from 2020-05-20 00-18-26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/133206/a46f7a49-d51d-26bf-2439-07e38b4633ec.png)
デスクトップにこんなアイコン（はじめは別のアイコンが表示されるかも）ができたらインストールOK

## VScode の設定
`Ctrl+Shift+x`で拡張機能のタブを開き検索で`arduino`を選択してインストール
![Screenshot from 2020-05-20 00-21-10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/133206/fe321dd8-5b9a-4f5b-f8a7-fbce4027f4ba.png)

インストールできたら、`Ctrl+Shift+P`でコマンドパレット開いて、`Arduino:Board Manager`を選択
![Screenshot from 2020-05-20 00-23-23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/133206/959e7572-e09b-d4dd-cd4f-2177792abbad.png)
こんな感じで起動できたらOK

## Lチカまでの道のり
`コマンドパレット -> Arduino:Change Board Type`
使いたいBoardを選択する
![Screenshot from 2020-05-20 00-37-34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/133206/68608268-2784-d58d-d4c6-85dec80a89ee.png)

ちなみに私が購入したArduino互換ボードはHiLetgoのやつです(ArduinoUNO互換)
https://www.amazon.co.jp/gp/product/B013QV28CW/ref=ppx_yo_dt_b_asin_title_o00_s00?ie=UTF8&psc=1
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/133206/15820d94-5b21-7beb-81ca-968adb391b93.jpeg" width="50%">

`コマンドパレット -> Arduino:Select Serial Port`
PCに接続したBoardのシリアルポートを選択する
（私の環境はttyUSB0でした）
![Screenshot from 2020-05-20 00-39-54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/133206/b0247a4d-17fe-e0b4-15f5-f1026cf45136.png)

`コマンドパレット -> Arduino:Examples -> Built-in Examples -> 01.Basics -> Blink`
選択すると新しいwindowでBlinkのコードが開く
![Screenshot from 2020-05-20 00-44-29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/133206/98b66e2a-f30c-f060-5abc-53d640fb3637.png)

`コマンドパレット -> Arduino:Upload`
実行するとBoardにサンプルコードが転送され、実行される

以上！
面倒臭い実行ポリシーの変更なしに，conda activate のエラーを解消する方法

# ほかの記事との違い
``PowerShell``環境で``Anaconda``や``Miniconda``を利用するためには，ひと手間かかります．
[この記事](https://qiita.com/8128/items/877caf785b20758ba7e0)や[この記事](https://qiita.com/yniji/items/668f805a72a6ced6a2bd)や[この記事](https://www.gesource.jp/weblog/?p=8254)のように，「開発しよう」と思う度に，面倒な実行ポリシーの変更が必要です．
もしくは，セキュリティ上での危険を承知で，毎回コマンドを入力する手間を省くことができます．
あるいは，``PowerShell``をあきらめて，``cmd``をデフォルトのターミナルに設定する手もあります．

この記事では，
・**面倒なコマンドを毎回打たずに**，
・**セキュリティも担保でき**，
・それを**``PowerShell``で実現できる**
方法を紹介します．

0. ``VSCode``を起動する．
0. ターミナルに，``conda init powershell``と打って実行．
0. 左側の``Extension``（ブロックのようなアイコン）をクリックする．
0. ``PowerShell``と打って一番上に出てくるものを``Install``する．
0. 念のため，``VSCode``を再起動する．
0. 左側に``PowerShell Command Explorer``（``PowerShell``のアイコン）が追加されているはずなので，クリックする．
0. ターミナルが立ち上がり，下記のような表示が出れば，成功．

```

                  =====> PowerShell Integrated Console <=====


(base) PS C:\Users\ほにゃらら\Documents\ほげほげ\src> 
```

# 実行ポリシーの確認
```
$ Get-ExecutionPolicy -List

        Scope ExecutionPolicy
        ----- ---------------
MachinePolicy       Undefined
   UserPolicy       Undefined
      Process          Bypass
  CurrentUser       Undefined
 LocalMachine       Undefined
```
``Process``単位なので，セキュリティ上も問題ないですね．

# さらに欲張りな人のために
現在の状態だと，普通に``PowerShell``を使いたいとき，``profile.ps1``がロードできないだなんだ言われて邪魔なはずです．
それを解消します．

0. ``$env:USERPROFILE\Documents\WindowsPowerShell``配下に移動する．
1. 前の工程で``profile.ps1``が作成されているはずなので，``Microsoft.VSCode_profile.ps1``にリネームする．

# 補足情報
筆者のOSは
Windows 10 64bit
Laravel Commandを実装する(超初歩) 

# 目的

- Laravelにてコマンドを作成する方法をまとめる

# 実施環境

- ハードウェア環境(下記の二つの環境で確認)

| 項目 | 情報 |
| --- | --- |
| OS | macOS Catalina(10.15.3) |
| ハードウェア | MacBook Pro (16-inch ,2019) |
| プロセッサ | 2.6 GHz 6コアIntel Core i7 |
| メモリ | 16 GB 2667 MHz DDR4 |
| グラフィックス | AMD Radeon Pro 5300M 4 GB Intel UHD Graphics 630 1536 MB |

- ソフトウェア環境

| 項目 | 情報 | 備考 |
| --- | --- | --- |
| PHP バージョン | 7.4.3 | Homwbrewを用いて導入 |
| Laravel バージョン | 7.0.8 | commposerを用いて導入 |
| MySQLバージョン | 8.0.19 for osx10.13 on x86_64 | Homwbrewを用いて導入 |

# 概要

- ターミナルに「Test」と文字列を出力するだけのLaravelコマンドを作成する。
- コマンド名は「app:test」とする。

1. クラスの作成
1. コマンドの内容の実行内容記載
1. 確認

# 詳細

1. クラスの作成
    1. アプリ名ディレクトリで下記コマンドを実行してクラスを作成する。(クラスの命名方法はキャメルケースを用いる)

        ```terminal
        $ php artisan make:command TestCommand
        ``` 
    1. 下記にクラスが記載されているファイル「TestCommand.php」が作成されている事を確認する。
        - `アプリ名ディレクトリ/app/Console/Commands` 
1. コマンドの内容の実行内容記載
    1. アプリ名ディレクトリで下記コマンドを実行してクラスが記載されているファイルを開く。

        ```terminal
        $ vi app/Console/Commands/TestCommand.php
        ```
    1. 開いたクラスファイルを下記の様に修正する。

        ```terminal
        <?php
        
        namespace App\Console\Commands;
        
        use Illuminate\Console\Command;
        
        class TestCommand extends Command
        {
            /**
             * The name and signature of the console command.
             *
             * @var string
             */
        //    protected $signature = 'command:name';
           //上記の行をコメントアウト、もしくは削除して下記の行を追加
            protected $signature = 'app:test';
        
            /**
             * The console command description.
             *
             * @var string
             */
        //    protected $description = 'Command description';
            //上記の行をコメントアウト、もしくは削除して下記の行を追加
            protected $description = 'ターミナル上に"Test"と出力するコマンド';
        
            /**
             * Create a new command instance.
             *
             * @return void
             */
            public function __construct()
            {
                parent::__construct();
            }
        
            /**
             * Execute the console command.
             *
             * @return mixed
             */
            public function handle()
            {
                //下記を追加
                $this->info('Test');
            }
        }
        ```
1. 確認
    1. アプリ名ディレクトリで下記コマンドを実行して現在使用可能なコマンドの一覧を表示する。

        ```terminal
        $ php artisan list
        ```
    1. 先のコマンドを出力結果の中に下記の記載が存在する事を確認する。

        ```
        app
         app:test             コマンドの実装方法を確認するコマンド
        ```
    1. アプリ名ディレクトリで下記コマンドを実行してターミナル上に「Test」と出力される事を確認する。

        ```
        $ php artisan app:test
        Test
        ```
【Unity：C#】null条件演算子（?.）

null条件演算子
if文書かずに１行ですっきりするから結構使用してるんだけど

```C#:sample
Action callback;
callback?.Invoke();
```

Unityのオブジェクトに関しては使用してはいけない

```C#:sample
// 例として面倒だから定義直下で判定してるけどメンバ変数として持って使用してる場合を想定
GameObject gobj;
gobj?.name;
```

明示的にnull代入すればセーフだけど
どこかでGameObjectの参照が切れた場合
gobjには"null"が入ってる
nullではなくて"null"

これはnull条件演算子が対応してないので普通にnull参照でエラーになる
※厳密には「== null」での判定はUnity側がoperatorを拡張してくれているから判定できるらしい（そのうち?.も対応されるかも？？）

Unityのオブジェクトには普通にnullチェックしよう
ターミナルとは？-絶対パス＆相対パス-

###ターミナルとは

ターミナルとは、コマンドラインの一つで、PCに命令を与えるためのツールです。記述したコードのファイルを実行するのに必要となります。
コマンドラインとは、コマンドラインインターフェース(CLI)の略で、PC対してキーボードからコマンドという文字を打ち込んで操作を行う方法です。
これとは対照に、グラフィックを用いてPCの操作を行う方法をグラフィカルユーザーインターフェース(GUI)と言います。

<br>
####コマンド

ターミナルでよく使うコマンドを紹介します。
<br>
`cd`コマンド
デイレクトりを移動するコマンドです。

`ls`コマンド
現在いるディレクトリの<strong>直下</strong>にあるファイルやフォルダを表示します。

<br>
#####ディレクトリとは

- ディレクトリとはファイルの入れ物のようなものでフォルダを指します。
ディレクトリのは階層構造になっており、
その一番上の階層のディレクトリのことを<strong>ルートディレクトリ</strong>と言います。
自分が現在いるディレクトリのことを<strong>カレントディレクトリ</strong>と言います。
また、ターミナルを開いた時に表示されるディレクトリのことを<strong>ホームディレクトリ</strong>と言います。Macでのデフォルトのホームディレクトリは<strong>/Users/ユーザー名</strong>です。


<br>
話戻ります。
`cd`コマンドを使ってディレクトリを行き来できるわけですが、`cd`コマンドに続けてパスを入力することによって目的のディレクトリに辿り着くことができます。

そのパスに記述の仕方には２通りあります。
・絶対パス
・相対パスです

####絶対パス
- 絶対パスとはルートディレクトリから記述するパスのことです。
`/`から記述するのが決まりです。


```ターミナル.
$ cd /

###これでルートディレクトリに移動できます
```
MacのデフォルトのルートディレクトリはMacintosh HDだと思いますので`cd /`でMacintosh HDに移動します。
`ls`コマンドで直下のディレクトリを確認すればパスがわからなくても確認して移動できます。

####相対パス
相対パスは先頭に`/`をつけません。
現在いるディレクトリの直下にあるディレクトリから記述することによって移動することができます。


この記事を読んでいただきありがとうございました。
HTTP APIでLambda関数にPOSTしたbodyの値が '[object Object]' になる時の解決法

AWS Lambdaの関数にHTTP APIで値をPOSTする際につまづいたのでメモ。

# 環境
- macOS
- AWS Cloud9
- Node.js 12


# 問題

Node.jsのfetch()メソッドで、自作したAWS Lambda関数にPOSTで値を送信しました。
Lambdaの呼び出しはAPI GatewayのHTTP APIを用いています。

## Lambda関数のコード

デバッグするために、Lambda関数では一旦eventを返すようにしています。
console.logで出力してCloudWacth Logsで確認しても良いと思います。


```Javascript
exports.handler = async(event, context) => {
    console.log(event)
    ...
    return event
};
```

## 実行コード

```Javascript
require('dotenv').config()
const env = process.env

var fetch = require("node-fetch")
    
fetch(env.LAMBDA_URL, { // Lambda関数のAPI URL
        method: 'POST',
        headers: {
            'Content-type': 'application/json'
        },
        body: {
            "massage": "test massage"
        },
    })
    .then(function(res) {
        return res.json();
    })
    .then(function(event) {
        console.log(event);
    })
```

eventの中身を確認すると、

```
{
version: '2.0',
routeKey: 'XXXXXXXXXX',
...
body: '[object Object]',
isBase64Encoded: false 
}
```

bodyの値が`'[object Object]'`になっています。

# 解決方法

どうやら、Lambda関数に渡すPayloadは、文字列として渡す必要があるようで、JSON形式のデータはJSONの文字列に変換した状態で送る必要があるようです。
Payloadに指定した値は文字列に変換されるので、JSONオブジェクトをそのまま指定すると、`[object Object]`に変換されてしまいます。
**※オブジェクトにtoString()メソッドを適用すると、返り値は`[object Object]`なる**

POSTするbodyの値を、JSON.stringify()で文字列に変換して送ることで解決できます。

## 修正後のコード

```Javascript
fetch(env.LAMBDA_URL, {
        method: 'POST',
        headers: {
            'Content-type': 'application/json'
        },
        body: JSON.stringify({ // JSONを文字列に変換する
            "massage": "test massage"
        }),
    })
    .then(function(res) {
        return res.json();
    })
    .then(function(event) {
        console.log(event);
    })
```

出力を見てみると、

```
{
version: '2.0',
routeKey: 'XXXXXXXXXX',
...
body: '{"massage":"test massage"}',
isBase64Encoded: false 
}
```

POSTしたbodyの値をきちんと確認できました。
Kotlin で一般化した二分探索（めぐる式二分探索）

[Kotlin 標準ライブラリの binarySearch](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/binary-search.html) が競技プログラミング用には微妙に使いづらいので自作した。

参考: [二分探索アルゴリズムを一般化 〜 めぐる式二分探索法のススメ 〜](https://qiita.com/drken/items/97e37dd6143e33a64c8c)

### コピペ用

```kotlin
fun myBinarySearch(begin: Int, end: Int, isOk: (key: Int) -> Boolean): Int {
  var ng = begin
  var ok = end

  while (Math.abs(ok - ng) > 1) {
    val mid = (ok + ng) / 2
    if (isOk(mid)) {
      ok = mid
    } else {
      ng = mid
    }
  }

  return ok
}

fun <T> List<T>.myBinarySearch(isOk: (T) -> Boolean): Int {
  return myBinarySearch(-1, size) { index -> isOk(get(index)) }
}

fun <T> Array<T>.myBinarySearch(isOk: (T) -> Boolean): Int {
  return myBinarySearch(-1, size) { index -> isOk(get(index)) }
}
```

### 使い方

```kotlin
// 一般化した二分探索の例
myBinarySearch(0, 100) { it * it > 50 } // -> 8

// 逆からも探索可能
myBinarySearch(100, 0) { it * it < 50 } // -> 7

// List の拡張関数として使う例 （Array も同様）
val list = listOf(2, 4, 6, 8, 10)
list.myBinarySearch { it >= 5 } // -> 2
```

### 備考

- [Kotlin 標準ライブラリの binarySearch](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/binary-search.html) は何が使いづらいのか？
    - 等しい要素が複数存在する場合どれを返すかが不定（lower_bound 的な事ができない）
    - List や Array の拡張関数として実装されているので、[一般化した二分探索](https://qiita.com/drken/items/97e37dd6143e33a64c8c#2-%E4%B8%80%E8%88%AC%E5%8C%96%E3%81%97%E3%81%9F%E4%BA%8C%E5%88%86%E6%8E%A2%E7%B4%A2%E6%B3%95)に使えない
        - ex: [年齢当てゲーム](https://qiita.com/drken/items/97e37dd6143e33a64c8c#4-1-%E5%B9%B4%E9%BD%A2%E5%BD%93%E3%81%A6%E3%82%B2%E3%83%BC%E3%83%A0)
- 関数名が `binarySearch` ではない理由
    - List 等の拡張関数として実装しようとした際にシャドーイングされるからです…
    - IntelliJ とか IDE の補完で余計な候補を出さないようにする効果もある（わりと大事）
- AtCoder での実装例（[ABC077 C - Snuke Festival](https://atcoder.jp/contests/abc077/tasks/arc084_a)）
    - 一般化した二分探索を使った回答 [提出 #13412420](https://atcoder.jp/contests/abc077/submissions/13412420)
    - List の拡張関数として二分探索を使った回答 [提出 #13412486](https://atcoder.jp/contests/abc077/submissions/13412486)
Railsで「Could not find a JavaScript runtime」というエラーが出てrails s ができなくなった

#rails s ができない
久しぶりにRailsを触り、rails sでサーバー起動させると
長文のエラーが発生し、一番下に「Could not find a JavaScript runtime」と書いてありました。

#解決策
調べたところ解決策は２つあるみたいです。
・`gem 'therubyracer'` をGem fileに追記し `bundle install`を実行する。
・Node.jsを[https://nodejs.org/en/](https://nodejs.org/en/)からインストールする。

GitHub ExecJS
[https://github.com/sstephenson/execjs](https://github.com/sstephenson/execjs)
<img width="949" alt="スクリーンショット 2020-05-16 1.42.21.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549752/497eb97e-d50c-6023-ada3-fd5c93ec1407.jpeg">

私はNode.jsをインストールし
「rails s」できるようになりました。
Angularの公式ドキュメントをざっくり読む（はじめてのアプリ～ルーティング）

こんばんは。社会人になりましてフロントエンド周りの勉強を始めまして、
まず<b>Angular</b>というフレームワークを勉強し始めました。
手始めに公式ドキュメントの「入門」の「はじめてのアプリ」から「ルーティング」までを読んでみて、理解したことなどをメモってみました。

[Angularの公式サイト](https://angular.jp/)

## 中の人について

* エンジニアで採用され、まずはフロントエンドの担当に
* 昔pythonは書いていたが、スキル is 低い
* まずはここからということで公式docを読んでる　←ｲﾏｺｺ！

という訳で、
Qiitaヤクザ
造形の深い皆様は、
「まったく分かってないやん･･･」とキレずにコメントなどで
お手柔らかにご教授くださいませ（わがまま）

## Angularってなに？

調べた内容をまとめてみました。 

* フレームワーク
* 画面まわりを作成する際に便利
* <b>HTML, CSS, JavaScriptの見た目に関する機能</b>に加えて<b>ページ移動に関すること(ルーティング)などの機能もある</b>
　↑比較ででてくるVueとかReactとかは後者がない模様。
* JavaScriptの上位互換である<b>TypeScript</b>が使用されている
　↑型の宣言ができる点で上位互換とのこと

といった感じで、すごい便利そう（小並感）
では、実際に読んで分かったことなどをまとめていきます。

## はじめてのアプリ

基礎が書かれています。が基礎だけにめちゃ大切なことが書かれてます。

分かったこと

*  <b>「プロパティ」</b>･･･ざっくりと変数のこと
*  <b>「属性」</b>･･･ざっくりと数値や文字列のこと。
*  <b>「バインド」</b>･･･プロパティに数値・文字列をいれるようなもの
 (紐づけてバインドするっていう連想が分かりやすそう)
* **インプット**と**アウトプット**の概念  
中々理解しづらい感じですが、以下リンクのボタン呼び出し側(親要素）に対して色・形（子要素）を渡す、という例がとてもいい感じ！  
[**Angularの@Input(), @Output()を理解する。**]
(https://qiita.com/masaks/items/677195b78379e0877e24)  
**☆インプット：親→子へ属性を渡す & []を使用  
☆アウトプット：子から親へ考え(ロジック)を渡す & ()を使用**  
といった感じ･･･？

## ルーティング

そもそも**ルーティング**とは複数のページがあるときに、このページには**このルートで行けば辿りつくよ、という道しるべの情報のこと**（ざっくり）

ここからは、実際にコードを書く際にどんな流れなのかを書いてみました。
**①コンポーネントを作成**
※**「コンポーネント」**･･･tsファイル, htmlファイル, cssファイル, scssファイルをまとめたもの。  
**②tsファイル内にpathとコンポーネント名のペアをつくる**  
こんな感じです。

```ts:src/app/app.module.ts(公式ドキュメントより引用)
RouterModule.forRoot([
{ path: '', component: ProductListComponent },
{ path: 'products/:productId', component: ProductDetailsComponent },
])
```

**③htmlファイルにリンク先の設定をします。**

```html:src/app/product-list/product-list.component.html(公式ドキュメントより引用)
    <a [title]="product.name + ' details'"
       [routerLink]="['/products', productId]">
      {{ product.name }}
    </a>
```

ここで、②のpathと、③の[routerLink]の内容が同じになるように設定するようです。 
これでルーティングの登録が完了しました。 
以後はルーティング情報を使う流れになります。

**④tsファイルでimportによって各種道具類をもってきます。**


```ts:src/app/product-details/product-details.component.ts(公式ドキュメントより引用)
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';

import { products } from '../products';
```

importで使えそうなイメージがありますが、以下の⑤を実行しないと使えない?ようです。
イメージとしては、
キャンプ場で金網やトングを借りてきました！（だけど持ってきただけで洗ってないので使えない･･･）みたいな感じかなと思います。

**⑤tsファイルでexportによってクラス名を定義する**

ここでウラス名を定義しますが、②のコンポーネント名と同じな点が重要。

```ts:src/app/product-details/product-details.component.ts(公式ドキュメントより引用)
//⑤の部分
export class ProductDetailsComponent implements OnInit {
  product;
  
  //⑥の部分
  constructor(
    private route: ActivatedRoute,
  ) { }

}
```

**⑥tsファイルでコンストラクタで初期化して使えるようにする**

上記コードのconstructorからの部分です。
これによって④で持ってきた道具類を初期化している、とのこと。
キャンプのたとえの場合、金網やトングを洗うことによって使用が可能になるイメージですね。

## まとめ&今後の目標
そんなこんなで、初学者がドキュメントを読んで書いてみました。
公式ドキュメントが丁寧で分かりやすい（概念は少し難しいけど）のでこのまま続けていこうと思います。
今後は**データがどういう流れになっているのか？**を図示したいところです。
PHPの正規表現でHTMLタグ”以外”の検出

##HTMLタグ”以外”の検出
PHPの正規表現でHTMLタグ”以外”を検出するために少々調べたのでまとめます。

与えられた文字列に
**「HTMLタグが含まれていなければオッケー」**
みたいなことをしたかったわけです。

アホみたいな書き方せずにもうちょっとちゃんと書くと、
与えられた文字列にHTMLタグが含まれていなければ
**`preg_match()`が`1`を返す**
ということです。

パッと調べてみた感じ、HTMLタグをみつける正規表現はすぐでてきたのですが、
”以外”となると意外とみつからなかったです。いがいなだけにね。うん。

で、結果を先に書くと以下の通り

```
^(?!.*<("[^"]*"|'[^']*'|[^'">])*>).*$
```

正直、正規表現むっず〜となって途中で理解を断念したので、
完璧には理解できていませんが分かってることだけ書いておきます。

##HTMLタグの検出
これは調べたらすぐに出てきました。

```
<(".*?"|'.*?'|[^'"])*?>
```

参考: [iPentac.com](https://www.ipentec.com/document/regularexpression-html-tag-detect)

説明は参考に飛んでいただければすぐ出てくるのでそちらで。
要は`<>`に囲まれていて、中になにか書いてればそれはHTMLタグだ！っていうことです。

##”以外”の検出
こちらも調べたら色々出てきましたが、`否定先読み`という言葉があるようですね。
詳しく知りたい方は`正規表現　否定先読み`で調べていただければもりもり出てくると思います。

こちらを参考にというかもうコピペして完成しました。
参考: [taketiyo.log](https://tkzo.jp/blog/regex-negative-condition-tips/)


##確認のために使用したサービス
確認に使ったサービスはこちら。
[PHP Live Regex](https://www.phpliveregex.com/)
同様のページはたくさんありますが、
見やすくてなんだかかっこよかったので今後はこれを採用します。
おめでとう！ありがとう！

**(追記 2020/05/21)**
このサービスすごい。
[Regexper](https://regexper.com/)
アホな自分でも視覚的に一発で理解できました。

今回適用した正規表現だとこんな感じになりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/178035/7ad0a602-78be-34fc-6d06-a27846352368.png)
下の問題点にも挙げてますが、このままだと`<>`だけでも認識してしまいますね。
ということが一発でわかっちゃうのでとっても便利。

##問題点
どうやらこの書き方だと`<>`だけでもHTMLタグとして認識するようです。
なんとなくもう少し良い書き方あるんじゃないかと思うのでなにか分かったら追記します。

##まとめ
以下でHTMLタグ”以外”を検出できちゃ〜う！

```
^(?!.*<("[^"]*"|'[^']*'|[^'">])*>).*$
```
正規表現あんまわからん。
精進します。
[rails]deviseのヘルパーメソッドbefore_action :authenticate_user!の使い方

#before_action :authenticate_user!について
deviseを簡単に説明すると、ログイン系をやってくれるgemです。

そのdeviseのヘルパーメソッドauthenticate_user!メソッドは、コントローラーにbefore_actionで記載することで、そのコントローラーで行われる処理はログインユーザーのみ実行可能とすることができるメソッドです。

##before_action :authenticate_user!の使い方
authenticate_user!メソッドはコントローラーに記載します。
例

```
class PostsController < ApplicationController
  before_action :authenticate_user!

  def index
  end

end
```

このように記載するとposts_controllerでの処理をすることができるのはログインユーザーのみとなります。

##一部の処理を未ログインユーザーでも行えるようにする
例

```
class PostsController < ApplicationController
  before_action :authenticate_user!, only: [:show]

  def index
  end

  def show
  end

end
```
このように記載することで、showアクションのみを未ログインユーザーが使用できないようにできます。

間違いなどがありましたらご指摘いただければ幸いです。
最後までご覧いただきありがとうございました。
AWSの学習を始めたので出てきた基礎単語をまとめてみた


今回は、自分の覚書としてQiitaを投稿します。（基本いつもそう...）


**IPアドレス**
web上の住所
プライベートIPアドレスとパブリックIPアドレスの二つがある
32ビット構成で、8ビット×4で、数字は0~255

プライベートIPアドレスの範囲

  + 10.0.0.0 ~ 10.255.255.255
  + 172.16.0.0 ~ 172.31.255.255
  + 192.168.00 ~ 192.168.255.255

IPアドレスの乗数は、2のn乗で区切る（よく使うのは、256個と65536個）

**CIDR 表記**
ネットワーク部のビット数を[/ビット数　→prefix]で表す方法
IPアドレス範囲をCIDR表記する場合、その範囲をCIDRブロックという
ex) 192.168.0.0 →　192.168.0.0・16
**サブネットマスク表記**
プレフィックスのビット数だけ2進数の[1]を並べ、残りは[0]を記述した表記
ex) 192.168.0.0~192.168.255.255 →　192.168.0.0/255.255.0.0

**リージョン**
地域に存在するデータセンター郡のこと(世界16箇所)
...なぜか初期でのAWSのリージョンが、東京ではなくオハイオになってました...

**アベイラビリティー**
物理的に距離が相当離れた、独立したファシリティ。
→地震などの自然災害などが発生した場合に備えたリスクヘッジ。

**VPC(Virtual Private Cloud)**
仮想的なネットワーク

**EC2(Elastic Compute Cloud)**
仮想的なサーバー

**サブネット**
細分化したCIDRブロックのこと。
使う理由としては、社内LAN構築などの物理的な隔離とセキュリティ上の理由がある。
プライベートサブネットとパブリックサブネットの二つがある。
違いは、インターネットをアクセスするかしないか。

**パケット**
データを送受信するための単位。
ヘッダー情報(宛先IPアドレス)や、データの実体を含む


参照
>[Amazon Web Services 基礎からのネットワーク&サーバー構築 改訂版](https://www.amazon.co.jp/Amazon-Web-Services-%E5%9F%BA%E7%A4%8E%E3%81%8B%E3%82%89%E3%81%AE%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF-%E3%82%B5%E3%83%BC%E3%83%90%E3%83%BC%E6%A7%8B%E7%AF%89/dp/4822237443)
PodsディレクトリをGit管理するならBitriseのキャッシュ対象外にしよう

## はじめに

BitriseでiOSアプリのビルドを実行した時に、Build Phasesで行われるCocoaPodsのチェックで以下のようなエラーとなるケースがありました。結論としてはBitriseのキャッシュの影響でしたが、そのエラーとなるケースと解決策についてまとめます。

```
error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.
```

## 前提条件

このエラーが起きるのに関係していた前提条件はこちら。

- パッケージマネージャーにCocoaPodsとCarthateを併用している
- **CocoaPodsの成果物であるPodsディレクトリもGit管理対象にしている**
- Carthageの成果物であるCarthageディレクトリはGit管理対象外にしている
- Carthageの成果物をキャッシュするために Bitrise.io Cache Pull/Push ステップを使用している
  - キャッシュ対象としてCarthageディレクトリのみを明示

## なぜエラーになったのか

特に指定はしていないのですが **暗黙的にPodsディレクトリがキャッシュ対象** になっていました。つまり、Git管理下にあるPodsディレクトリはキャッシュにより上書きされてしまうことになり、Pods/Manifest.lockが前回実行時のものとなってしまうのです。結果、CocoaPodsのライブラリを更新したプッシュの後に、最初に書いたとおりのエラー(Podfile.lockとManigest.lockが一致しない)になっていたのでした。

## 解決策

Bitrise.io Cache Push ステップの **bitrise_cache_exclude_paths** にPodsディレクトリパスを指定してキャッシュ対象にならないようにしましょう。

bitrise_cache_exclude_pathsのデフォルト値は `$BITRISE_CACHE_EXCLUDE_PATHS` になっているので、Env Vars に BITRISE_CACHE_EXCLUDE_PATHS を定義してPodsディレクトリのパスを指しておけば、すべてのワークフローで有効になりますね。
MYDNSにIPアドレスを自動通知する（失敗）

#MYDNSにIPアドレスを自動通知する
自分の備忘録用に、失敗した

```
pi@raspberrypi:/ $ sudo mkdir /etc/cron.everyday/
pi@raspberrypi:/ $ sudo nano /etc/cron.everyday/mydns.sh
pi@raspberrypi:/ $ sudo crontab -e
no crontab for root - using an empty one

Select an editor.  To change later, run 'select-editor'.
  1. /bin/nano        <---- easiest
  2. /usr/bin/vim.tiny
  3. /bin/ed

Choose 1-3 [1]: 1
crontab: installing new crontab
pi@raspberrypi:/ $ sudo chmod +x /etc/cron.everyday/mydns.sh
pi@raspberrypi:/ $ /etc/cron.everyday/mydns.sh
‘http://ID:pass@www.mydns.jp/login.html’: スキームがありません.
pi@raspberrypi:/ $ sudo nano /etc/cron.everyday/mydns.sh
pi@raspberrypi:/ $ /etc/init.d/cron reload
[ ok ] Reloading configuration files for periodic command scheduler: cron.

```


結論：スキームがありませんって言われた　時間あるとき、また更新してみて進捗載せます

参考記事：[MyDNSにIPアドレスを自動通知](https://ong-net.com/mydns%E3%81%ABip%E3%82%A2%E3%83%89%E3%83%AC%E3%82%B9%E3%82%92%E8%87%AA%E5%8B%95%E9%80%9A%E7%9F%A5/)
ゼロから始めるLeetCode Day30「234. Palindrome Linked List」

#概要
海外ではエンジニアの面接においてコーディングテストというものが行われるらしく、多くの場合、特定の関数やクラスをお題に沿って実装するという物がメインである。

その対策としてLeetCodeなるサイトで対策を行うようだ。

早い話が本場でも行われているようなコーディングテストに耐えうるようなアルゴリズム力を鍛えるサイト。

せっかくだし人並みのアルゴリズム力くらいは持っておいた方がいいだろうということで不定期に問題を解いてその時に考えたやり方をメモ的に書いていこうかと思います。

[Leetcode](https://leetcode.com/)

[ゼロから始めるLeetCode 目次](https://qiita.com/KueharX/items/6ee2502c3b620c795b70)

前回
[ゼロから始めるLeetCode Day29「46. Permutations」](https://qiita.com/KueharX/items/6885be4c1da6e6a2b9a0)

基本的にeasyのacceptanceが高い順から解いていこうかと思います。

[Twitter](https://twitter.com/kueharx)やってます。


# 問題
[234. Palindrome Linked List](https://leetcode.com/problems/palindrome-linked-list/)

単方向の連結リストが与えられるので、回文であるかをチェックしてください。

>Example 1:

>Input: 1->2
Output: false

>Example 2:

>Input: 1->2->2->1
Output: true


# 解法
最も簡単な方法としては、与えられた連結リストをひっくり返したものと一致すれば`True`を、一致しなければ`False`を返すというものです。


```Python
# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def isPalindrome(self, head: ListNode) -> bool:
        value = []
        while head:
            value.append(head.val)
            head = head.next
        return value == value[::-1]
# Runtime: 92 ms, faster than 15.28% of Python3 online submissions for Palindrome Linked List.
# Memory Usage: 24.1 MB, less than 11.54% of Python3 online submissions for Palindrome Linked List.
```

今回は少し時間がなかったため、他の人の解答をdiscussから持ってきます。

例えばO(1)の解答とかですね。

```Python
# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def isPalindrome(self, head):
        rev = None
        fast = head
        while fast and fast.next:
            fast = fast.next.next
            rev, rev.next, head = head, rev, head.next
        tail = head.next if fast else head
        isPali = True
        while rev:
            isPali = isPali and rev.val == tail.val
            head, head.next, rev = rev, head, rev.next
            tail = tail.next
        return isPali
# Runtime: 92 ms, faster than 15.28% of Python3 online submissions for Palindrome Linked List.
# Memory Usage: 24.1 MB, less than 11.54% of Python3 online submissions for Palindrome Linked List.
```
>https://leetcode.com/problems/palindrome-linked-list/discuss/64500/11-lines-12-with-restore-O(n)-time-O(1)-space


わかりやすい解説としてはこのdiscussの内容がおすすめです。
視覚的に分かりやすいのすごい・・・

https://leetcode.com/problems/palindrome-linked-list/discuss/324358/O(n)-time-and-O(1)-space-with-explanation-(Python-and-C)


後、この本の連結リストの章にも複数の解法が載っていました。

[世界で闘うプログラミング力を鍛える150問](https://www.amazon.co.jp/dp/4839942390/ref=cm_sw_em_r_mt_dp_U_51-WEbFT6VWNV)

時間がある人はチェックしてみると良いかもしれません。
駆け出しエンジニアのためのRuby便利メソッド

# はじめに
**駆け出しエンジニアの私が、AtCoderやpaizaでアルゴリズム問題を解いていく中で、とても便利だったメソッドを書き残す。**

# puts, p, printの違い
自分の言葉で説明しようと思ったが、web上に山ほど記事があったので、止めることにする。

【Ruby超入門】print、puts、pの違い
https://yukimasablog.com/ruby-print-puts-p
【Ruby】p, puts, printメソッドの違い
https://qiita.com/rkkmshde/items/daf75aca9675f5a01d17

デバッグの時に使いこなせると、複雑なコードを書く時にかなり効率よくエラーやその原因に気づける。

# 三項演算子
if 〜 else 〜 end
をもっと効率よく書くことができる。

```ruby
number = 24
if number.even? 
    n = "偶数"
else
    n = "奇数"
end
puts n  
# => 偶数

```
この処理が、、、

```ruby
number = 24
n = number.even? ? "偶数" : "奇数"
puts n  
# => 偶数
```
こうなる。


**条件 ? (条件がtrueだった時の処理) : (条件がfalseだった時の処理)**

という構造だ。

# map

```ruby
# 入力値
# 12 30 40
input = gets.split.map(&:to_i)
# 出力値
# [12, 30, 40]
# という風な配列になる。
```

入力値の数値や文字列を一つ一つの要素に分けて配列にしたい時に使うことができる。

**"&:"**メソッドの説明については、今回は割愛させていただく。
詳しくは、
https://qiita.com/soma_sekimoto/items/a828b8f88b78aac2e7df
こちらの記事を参考に。

# any? と all? と one?
**繰り返し処理を使って条件を満たしているかどうか**を確かめたい時に、これらのメソッドがとても役に立つ。

これを知らなかった頃は、全てeachで代用しようとしていたので、コードがとんでもないことになってしまっていた。

```ruby
array = [30, 14, 23, 15]
array.any? {|num| num % 7 == 0} # 7で割り切れる要素(14)がある
# => true  
```
**any?**: 各要素の中で、1つでも条件に合うものがあればtrueを返す。

**all?**: 全ての要素が条件に合えばtrueを返す。

**one?**: 各要素の中で、条件に合うものが一つだけであればtrueを返す。

# reduce
```ruby
(1..10).reduce(5) {|a, n| a + n}
# => 5 + 1 = 6, この6が次の処理のaとなる。
# つまり、2回目の処理は、6 + 2となる。
# 処理結果 => 60
```
reduceメソッドでは、ブロック処理内の引数を2つ(aとn)設定する。
aは初期値(ここでは5)、nは各要素(ここでは、1から10の整数)になる。

# between?
```ruby
23.between?(0, 30)
# => true

'G'.between?('A', 'F')
# => false
```
指定した値(ここでは、23 と 'G')が範囲内(0〜30 と A〜F)に入っているかどうかを判断するメソッド

# index
```ruby

array = ["ruby", "java", "php"]
p array.index("java")
# => 1
# "java"のindex番号が返される。
```
# transpose
**配列に要素として他の配列が格納されている場合**に、**配列を行列と見なし**、行と列を入れ替えるメソッド

```ruby
array = [[1,2,3,4], [5,6,7,8], [9,10,11,12]]
p array.transpose
# => [[1,5,9], [2,6,10], [3,7,11], [4,8,12]]
```

行と列の考え方を使うアルゴリズム問題でとても活躍してくれた。


# chars
```ruby
greeting = "hello"
p greeting.chars
# => ["h", "e", "l", "l", "o"]
```

上記のように、**文字列を１文字ずつに分割して配列**として返す。

また、こういう書き方もできる。

```ruby
num = "19800".chars.map(&:to_i)
p num
# => [1, 9, 8, 0, 0]
```

桁ごとの数字を処理したい時などに使える。
# zip
複数の配列を同時に処理したい時は、このzipメソッドが便利だ。

```ruby
number = [1, 2, 3, 4, 5]
alphabet = ["a", "b", "c", "d", "e"]
p number.zip(alphabet)
number.zip(alphabet) do |num, alpha|
    p num
    p alpha
end

# => [[1, "a"], [2, "b"], [3, "c"], [4, "d"], [5, "e"]]

# => 1
# => "a"
# => 2
# => "b"
...
# => 5
# => "e"
```

上記のように、配列として返すこともできるし、複数の配列にeachメソッドを用いたような処理の仕方もできる。

# select, reject
**select**: {}ブロック内の式がtrueになる要素だけを抽出する。
**reject**: {}ブロック内の式がfalseになる要素だけを抽出する。

```ruby
p [1, 2, 3, 4, 5, 6].select { |n| n % 2 == 0 }
p [1, 2, 3, 4, 5, 6].reject { |n| n % 2 == 0 }
# => [2, 4, 6]
# => [1, 3, 5]
```
# おわりに

rubyは他の言語と比べると、メソッドの数が多いので、直感的なコードが書けることに気がつき、さらにrubyが好きになった。

皆さんもぜひ、rubyを用いてアルゴリズムを書く際は、参考にしてもらいたい。
【備忘録】複数の公開鍵管理とSSH接続方法

# この記事について

自分用です。

SSH接続を久しぶりに使おうとしたら忘れてしまったので備忘録。

GitHubとGitLabそれぞれの鍵を生成し、どう設定ファイルを書けばいいのかメモする。


# 環境
MacBookPro Catalina


# 前提知識
* `~/.ssh`内にSSH関連のファイルがある

* 基本的に、known_hosts、秘密鍵、公開鍵、configという4つのファイルがある。

```
$ ls ~/.ssh
```


# 流れ
1. 鍵（秘密鍵と公開鍵）を作る
2. 設定ファイルを書く
3. 接続コマンドを実行して、接続を確認する。


## 鍵を作る

`ssh-keygen`コマンドを使う。

`-f`はファイル名で、例えばgithub用の鍵を生成しようと思ったら、わかりやすい名前を書く。

ここでは`id_rsa_github`とする。

```
$ ssh-keygen -t rsa -f id_rsa_github
```

すると`~/.ssh`に公開鍵`id_rsa_github.pub`と秘密鍵`id_rsa_github`が生成される。

公開鍵`id_rsa_github.pub`はGitHubのページに、秘密鍵`id_rsa_github`は`~/.ssh/config`内の設定で記述する。

今回は、github用とgitlab用で、複数個の鍵ペアを作るから、フォルダ分けしておく。

```
$ cd ~/.ssh
$ mkdir for_github
$ mv id_rsa_* for_github/
```


## 設定ファイルを書く

`~/.ssh/config`内に設定を書いていく。

このファイルはgithubとgitlabで分ける必要はない。

複数の設定を一つのファイルに書くことができるので、`~/.ssh`に置いておく。

以下のように内容を記述する。

```~/.ssh/config
Host github
    HostName github.com
    User git
    identityFile ~/.ssh/for_github/id_rsa_github
```

分かりやすいように、
① Host github
② HostName github.com
③ User git
④ identityFile ~/.ssh/for_github/id_rsa_github
としよう。

Host、HostName、User、identityFile以外にも設定できるけど、今回はこの4つだけ説明。

最終的にこのあと、

```
$ ssh -T github
```
というコマンドを打って、接続を確認する。

この時の-Tの後のgithubが①Hostで設定したものに対応している。
ここではgithubにしてるけど、分かりやすい名前であればなんでもいい。

どこに繋ぐかというと、

```
User@Hostname
```
すなわち、

```
git@github.com
```
に接続しようとする。
GitHubでもGitLabでもいいが、マイページで自分のリポジトリをCloneするときにコピーする文字列が、git@github.comで始まっていると思う。
githubに繋ぐんだったら、全ユーザ、②と③の設定で良い。

④identityFileは、秘密鍵。`.pub`がついてない`id_rsa_github`を指定する。


## 接続コマンド

上記でも説明したが、

```
$ ssh -T github
```

## GitLabも同じように設定していく

```terminal
$ cd ~/.ssh
# 先にディレクトリを作成してその中に鍵ファイルを作る。
$ mkdir for_gitlab
$ ssh-keygen -t rsa -f for_gitlab/id_rsa_lab

# GitLabのマイページで公開鍵(.pub)の中身を追加
$ vi -b ~/.ssh/config
```

以下のように、中身を追加していく。

```~/.ssh/config
Host github
	HostName github.com
	User git
	identityFile ~/.ssh/for_github/id_rsa_hub

Host gitlab
	HostName gitlab.com
	User git
	identityFile ~/.ssh/for_gitlab/id_rsa_lab
```


```
# 接続確認
$ ssh -T github
$ ssh -T gitlab
```

# メモ
1回目の接続では、本当に繋いでいいですか？という確認のメッセージが出る。

１度繋いだら`~/.ssh/known_hosts`に記録され、2回目以降はメッセージが出なくなる。
JS(rails)で404 (Not Found)が出た時の一時対処法

クイズアプリを作成してる時にJSをrailsで読み込もうとしても404 (Not Found)が出て、読み込まれない時の話。
## 結論


```
assets/views/index.html.erb
<%= javascript_include_tag 'fuga.js' %>
```
さらに

```
config/initializers/assets.rb
Rails.application.config.assets.precompile += %w( fuga.js )
```
で再起動して表示はできるようになりました。
　
404 (Not Found)が出るときは基本的にrails側がJSを読み込めていないよということのようなので、
アセットパイプラインに個別で表示して欲しい内容を記載、というか追加することでそれを個別で読み込んでくれるようになったようです。
Google Colabのリージョンを調べる

# 概要
Google Colabにおいて、ノートブックが動いているリージョンを調べます。Colabから使用するCloud Storageのバケットをノートブックと同じリージョンにすることで、価格の低減やデータ転送の高速化が図れます。さらにDeep Learningなどの学習においてはデータ読み込みが高速化され、学習時間を短くすることができます。

# 調査
Google Colabのセルにおいて`gcping`を実行することで、各リージョンからのレイテンシが調べられます。

```
!curl https://storage.googleapis.com/gcping-release/gcping_linux_amd64_0.0.3 > gcping
!chmod +x gcping
!./gcping
```
以下の結果から、確認したノートブックは最もレイテンシが小さい`us-central1`のリージョンで動いていることがわかりました。実際にCloud Storageのバケットを`asia-northeast1`から`us-central1`に変更したところ、データ転送時間が短くなり、DeepLearningの学習時間が約1/6になったことを確認できました。

```
 1.  [us-central1]              1.527713ms
 2.  [global]                   4.838736ms  (10 errors)
 3.  [us-east4]                 51.927976ms
 4.  [northamerica-northeast1]  57.970435ms
 5.  [us-east1]                 66.479917ms
 6.  [us-west2]                 68.485033ms
 7.  [us-west1]                 70.99003ms
 8.  [europe-west2]             189.84392ms
 9.  [europe-west1]             204.61113ms
10.  [europe-west4]             210.959809ms
11.  [europe-west3]             215.961598ms
12.  [europe-west6]             228.518708ms
13.  [asia-northeast1]          245.375997ms
14.  [asia-northeast2]          261.963207ms
15.  [europe-north1]            274.588144ms
16.  [southamerica-east1]       278.956365ms
17.  [asia-east1]               307.425311ms
18.  [asia-east2]               331.961357ms
19.  [australia-southeast1]     340.603328ms
20.  [asia-southeast1]          406.555719ms
21.  [asia-south1]              513.717495ms
```

# まとめ
今回は`gcping`を使用して、Google Colabが動作しているリージョンを調べました。Colabのリージョンに合わせて、Cloud Storageのバケットのリージョンを変更することで、データ転送およびDeep Learningの学習の高速化が出来ました。さらに、リージョン外への通信がなくなることから、コスト低減も期待できます。

# 参考
- [Accessing external data from Google Colab notebooks](https://ostrokach.gitlab.io/post/google-colab-storage/)
- [gcping](https://github.com/GoogleCloudPlatform/gcping)
Railsでグループ機能（掲示板）を作ってみた

# Railsでグループ機能（掲示板風）の作成

＜開発環境＞
1. ruby 2.6.3
2. Rails 5.1.6
3. AWS Cloud9
4. GitHub
6. sqlite3(develop環境)

## 設計構想
ユーザーは自由にグループを作成でき、また他のユーザーが作成したグループに所属することもできます。
また、グループに参加したメンバーはグループ内で自由に発言することも可能になります。

この仕組みをテーブルに落とし込むと、
ユーザーとグループは多対多の関係になるので中間テーブルを用いることとします。
そして、ユーザーとグループ内での投稿も多対多の関係となる為、こちらも中間テーブルを用います。
![IMG_8162 (1).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618929/22954c46-4071-0c12-60c9-f1b056543ec6.jpeg)

ER図はこんな感じになりました。（手書きですいません・・・）

### モデル

先ほどのER図は以下のようなアソシエーションとなりました。

```ruby:group.rb
class Group < ApplicationRecord
  validates :name, presence: true, uniqueness: true
  
  has_many :group_users
  has_many :users, through: :group_users
  has_many :groupposts
  accepts_nested_attributes_for :group_users
end
```

```ruby:group_user.rb
class GroupUser < ApplicationRecord
  
  belongs_to :group
  belongs_to :user
end
```

```ruby:grouppost.rb
class Grouppost < ApplicationRecord
  belongs_to :group
  belongs_to :user
end
```



### コントローラー
```ruby:groups_controller.rb
class GroupsController < ApplicationController
  def new
    @group = Group.new
    @group.users << current_user
  end
  
  def create
    if Group.create(group_params)
      redirect_to groups_path, notice: 'グループを作成しました'
    else
      render :new
    end
  end
  
  def index
    @groups = Group.all.order(updated_at: :desc)
  end
  
  def show
    @group = Group.find_by(id: params[:id])
    
    if !@group.users.include?(current_user)
      @group.users << current_user
    end
    
    @groupposts = Grouppost.where(group_id: @group.id).all
  end
  
  private
  def group_params
    params.require(:group).permit(:name, :user_id [])
  end
  
  def grouppost_params
    params.require(:grouppost).permit(:content)
  end
  
end
```

基本的な設計はユーザー周りと同じです。

```
def show
.
.

  if !@group.users.include?(current_user)
   @group.users << current_user
  end
end
```

このようにグループのリンクを踏んだ人がそのグループに所属できるようにしています。


```ruby:grouppost_controller.rb
class GrouppostsController < ApplicationController
  
  def new
    @grouppost = current_user.groupposts.new
    @group = Group.find_by(id: params[:group_id])
  end
  
  def create
    @group = Group.find_by(id: params[:group_id])
    @grouppost = current_user.groupposts.new(grouppost_params)
    @grouppost.group_id = params[:group_id]
    if @grouppost.save
      redirect_to group_path(@group.id)
    end
  end
  
  private
    def grouppost_params
      params.require(:grouppost).permit(:content)
    end
end
```

こちらも以前作成した投稿機能と同じ形にしています。


以上で2chちっくなグループ機能（掲示板風）が完成しました。
今後の課題としては、グループ作成時に鍵をかけることができ、招待制のグループを作ることができるようにしたいと考えています。
結局for文を使うのか？while文を使うのか？for文とwhile文の使い分け

※この記事はCやJavaなどCライクな構文のfor文を持つ言語向けの記事です。Python等foreachな言語は対象外です。

今更のようですが、for文とwhile文の使い分け、プログラミングを始めたての頃には誰しも疑問に思ったことでしょう。

世の中の一般的な文献には、**for文は繰り返し回数が明らかなときに使用する**などと書かれていることが多いようです。

しかしながら、自分としてはこの説明があまり腑に落ちませんでした。

今日プログラムを書いていて、この違いについてやっと自分の中で一つの落としどころが見つかったので、ここに記録しておこうと思います。

以下、JavaScriptで記述します。

```javascript
class Iterator {
  index = 0;
  constructor(list) {
    this.list = list;
  }
  next() {
    return this.list[this.index++];
  }
}

const iterator = new Iterator([1, 2, 3, 4, 5]);
```

以上のような実装の`Iterator`クラスを用意します（実際にはファイルリストなどをイメージしてもらえれば良いです）。ここで、すべての要素を出力しつつ、要素の個数を数える処理を記述したいとします。当初、私は次のようなコードを書きました[^1]。

```javascript
let count = 0, item;
while (item = iterator.next()) {
  console.log(item);
  count++;
}
console.log(`個数: ${count}`);
```

コードをより読みやすくするため、以下のように書き換えてみます。

```javascript
let count, item;
for (count = 0; item = iterator.next(); count++) {
  console.log(item);
}
console.log(`個数: ${count}`);
```

書き換えてみたのですが・・・このコード、確かに短くはなっているのですが、非常に読み辛いと感じませんか？

恐らくこの理由は、私たちが

```
for (A; B; C) {}
```

という文を見たとき、無意識に

```
For A, while B, do C.
```

つまり**Aについて、Bの間、Cしなさい**と読んでいるためだと思うのです。このため、実際の式をここに当てはめたとき、文章として成り立たないと強い違和感を覚えます。

もう少し踏み込んだ表現をするのであれば、**意識する必要があるのはAの文、つまり初期設定式**です。「for」という単語（＝～について）が使われている以上、BやC、そしてブロック内の文は嫌でもこのAの部分に束縛を受けます。

先ほどのfor文の例に違和感があったのは、初期設定式は変数`count`の初期化に使用されているにもかかわらず、継続条件式やブロック内の文が`count`と全く関係のないものだったからなのです。

# まとめ
while文で表現可能な繰り返しのうち、for文で表現するべきものは

* 繰り返し初期に実施すべき式が存在する
* その式の主たる対象が継続条件や再設定式、ループ内の処理においても主要な要素である

を満たすものだということができると思います。

# 極端な例
逆に言えば、上のルールを満たしさえしていれば、一般に言われる「繰り返し回数がわかっている」を満たさない場合においても、for文を使って書けるものが存在することになります。以下の例はどうでしょうか。

```javascript
class Iterator {
  index = 0;
  constructor(list) {
    this.list = list;
  }
  get currentItem() {
    return this.list[this.index];
  }
  next() {
    this.index++;
  }
}

let count = 0;
for (
  const iterator = new Iterator([1, 2, 3, 4, 5]);
  iterator.currentItem;
  iterator.next()
) {
  console.log(iterator.currentItem);
  count++;
}
console.log(`個数: ${count}`);
```

あまり違和感はない・・・ですよね？？？

[^1]: JavaScriptでは、配列の範囲外のインデックスにアクセスがあった場合、エラーとはならず`undefined`というfalsyな値を返します。このため、`next`メソッドは実行されるたびに要素を1つずつ返却し、全て終わると`undefined`を返すという挙動を示します。
自作GitHub Actionsを公開するときのタグ付け

自作したGitHub Actionsを公開するときにv1.0.0などとタグ付けをします。

[こちらのドキュメント](https://help.github.com/en/actions/reference/workflow-syntax-for-github-actions#jobsjob_idstepsuses)に書いてあるように、Github Actionsを利用する側は`@v1`という風にメジャーバージョンだけを指定して使うといった使い方がよく使われます。

```yaml

steps:    
  - uses: actions/setup-node@74bc508 # Reference a specific commit
  - uses: actions/setup-node@v1      # Reference the major version of a release   
  - uses: actions/setup-node@v1.2    # Reference a minor version of a release  
  - uses: actions/setup-node@master  # Reference a branch
```

この説明だけ見ると、`@v1`と指定すると`v1.x.x`の最新版が自動で使われそうに見えます。

しかし、GitHub Actionsを提供している側がなにもしないと`@v1`と指定しても`not found`になってしまいます。GitHub Actionsが自動で最新バージョンを見つけてくれるわけではないのです！（2020/05/19現在）

GitHub Actionのversioningについては[こちらのドキュメント](https://github.com/actions/toolkit/blob/master/docs/action-versioning.md)に記載があります。

GitHub Actionsを提供している側は、`v1`, `v1.1`などといったタグを用意しなければなりません。(たとえばactions/scriptは[こう](https://github.com/actions/github-script/releases)なっています)そして、マイナーバージョンやパッチパージョンを上げるたびにこれらのタグを付け替えなければならないのです。すごいめんどくさいですね・・

これを解決するGitHub Actionsがあり、https://github.com/nowactions/update-majorver です。
これを使うと自動でメジャーバージョンのタグを更新してくれるみたいですので、GitHub Actionsを公開している人は使うと便利かもしれません。

GitHub Actionsを使う側の人は、使おうとしているGithub ActionsのGitHubのreleaseを見て、v1とかv1.xに対応しているか確認して指定すると間違いはないです。
Float計算回路のVerilog-HDL実装について -その３(積算回路)

#Float計算回路のVerilog実装
~ FPGA に載せたい ~
オレオレ実装なので間違っていても知りません

加算回路編
[Float計算回路のVerilog-HDL実装について -その１](https://qiita.com/Soleiyu/items/5bbb991de443e61e318e)

デバッグツール作成編
[Float計算回路の(ry-その１.１(float値の16進数表記)](https://qiita.com/Soleiyu/items/1fbdc78c68ad69a6d34d)

補足とLeadingZeros編
[Float計算回路のVerilog-HDL実装について -その1.5 (LeadingZeros)](https://qiita.com/Soleiyu/items/2fbd44883cfb1cdd253d)

減算回路編
[Float計算回路のVerilog-HDL実装について -その2(減算編)](https://qiita.com/Soleiyu/items/b56d3db666bd93f9ef75)

回路共通化とタイミング調整編
[Float計算回路のVerilog-HDL実装について -その2.1(加算回路の共通化とタイミング調整)](https://qiita.com/Soleiyu/items/85e9543463f068fe5047)

共通化編
[Float計算回路のVerilog-HDL実装について -その2.5(共通化)](https://qiita.com/Soleiyu/items/5751c226d1e8008a3231)

0対応編
[Float計算回路のVerilog-HDL実装について -その2.7(0対応)](https://qiita.com/Soleiyu/items/23e1df40e67b05025990)

## 目的
floatの勉強
float32のハードウェア実装

0 に対応しない積算回路の実装を行う
前回までの加減算回路との共通化は行わない（つもり）

## 今回のHW
![mul_timing.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253609/6ff9338c-64ae-c563-1795-e041aa02e8db.png)

## コード
```
module float_mul(
	input wire clk,
	input wire [31:0] v1,
	input wire [31:0] v2,

	output wire [31:0] vres
);

	assign vres = res;

	// TIM1
	reg [7:0] v1e;
	reg [7:0] v2e;
	reg [23:0] v1v;
	reg [23:0] v2v;
	reg v1o;
	reg v2o;

	// TIM2
	reg [7:0] re;
	reg [47:0] rv;
	reg ro;

	// TIM3
	reg [31:0] res;

	always @(posedge clk) begin
	// TIM1
		v1e <= (v1[30:23] - 8'h7F);
		v2e <= (v2[30:23] - 8'h7F);
		v1v <= {1'b1, v1[22:0]};
		v2v <= {1'b1, v2[22:0]};
		v1o <= v1[31];
		v2o <= v2[31];

	// TIM2
		re <= v1e + v2e;
		rv <= v1v * v2v;
		ro <= v1o ^ v2o;

	// TIM3
		if (rv[47]) begin
			res <= {ro, re + 8'h80, rv[46:24]};
		end else begin
			res <= {ro, re + 8'h7F, rv[45:23]};
		end
	end

endmodule
```
### 127 と 128 
計算中に繰り下がりが起きてるからだよ

## シミュレーション結果と誤差

|値１| 値2| 結果|| 正答|誤差|
|:-:|:-:|:-:|:-:|:-:|:-:|
|7.25|123.4|894.64996||894.65|0.00004|
|7.25|0.00123| 0.0089175||0.0089175|0|
|0.725|123.4| 89.465004||89.465|0.000004|
|0.725|0.00123| 0.00089175004||0.00089175|0.0000000004|

## プチ改良（？）
```
// TIM3
	if (rv[47]) begin
		res <= {ro, re + 8'h80, rv[46:24] + {22'b0, rv[23]}};
	end else begin
		res <= {ro, re + 8'h7F, rv[45:23] + {22'b0, rv[22]}};
	end
```
四捨五入の導入
多分大丈夫だけど OF しても知らない

## シミュレーション結果と誤差

|値１| 値2| 結果|| 正答|誤差|
|:-:|:-:|:-:|:-:|:-:|:-:|
|7.25|123.4|894.65||894.65|0|
|7.25|0.00123| 0.0089175||0.0089175|0|
|0.725|123.4| 89.465004||89.465|0.000004|
|0.725|0.00123| 0.0008917501||0.00089175|0.0000000001|

誤差が大きくなったり小さくなったり変わらなかったり
paizaランクDの達成方法

#はじめに
***paizaランクD***を達成するにはどうすれば良いか？
目安を解説しました。
#前提
筆者がRubyを主に学習しているので、Rubyで解説しています。
#実行
例えば、好きな数値を入力して、それを出力するには次のようなコードを書きます。

```ruby
x = gets.chomp.to_i
puts x
```

二つ以上の数値を入力するには、`gets`を少し書き換える必要があります。

```ruby

x = gets.split().map(&:to_i)
puts x
```


`split`メソッドを使えば、複数の入力値を配列として取得できます。
```map```メソッドを使えば、配列の中身を簡単に変換することができます。
引数を```&:to_i```とすれば、入力値を全て数値として取得できます。

ここで、入力した値を二つの場合、一つ目の入力値と二つ目の入力値の差を求めるには次のようにします。

```ruby

x = gets.split().map(&:to_i)
puts x[0] -x[1]
```

xは配列として取得されているので、入力された値の差を計算するには、配列の要素同士の演算子を利用すれば良いです。

以上の事が使いこなせれば。***paizaランクD***の達成するのは目前です。
Nuxt.js + Sentry の本番運用での設定に戸惑った

フロントエンドのエラーを検知するのは、バグの早期発見、場合によってはリリースバージョンを切り戻しの判断をしたりする上で非常に重要です。

[Sentry](https://sentry.io/)を使えば、かなり簡単にフロントエンドのログ収集の仕組みを実現出来ます。また、他の同様のツール(Rollbarなど)に比べてモダンなUIかつ、ドキュメントやTipsが豊富な気がします。また、nuxt-community にて sentry-module が提供されてる点もgood。

SentryにはReleaseという機能があり、運用環境へのデプロイとログを紐付けることが出来ます。また、SourceMapを一緒にアップロードしておくことで、本番環境でも stack trace を追えるようになります。

しかし、今回`@nuxtjs/sentry`を使ってReleaseしようとした際、公式の記述がさらっとしていてちょっと困ったので備忘録として残しておきます

## やりたかったこと

NustからSentryにReleaseを作成する。

Releaseの際にはSourceMapをSentryにアップロードする。

本番環境側ではSourceMapは見えないようにしたい。

## 解決方法

※ Sentry Project 立ててある前提です

### Sentry側で用意しておくべきもの

- DSN: Project Settings の Client Keysから確認
- Auth Token: アカウント設定の Auth Tokens から作成 (Projectの書き込み権限をもつTokenを発行する)
- Organization Name: Organization Settings から確認
- Project Name

### 設定

```bash
$ npm i @nuxtjs/sentry
```

build時に sentry cli が使うオプションファイル `.sentryclirc` を準備

```plaintext:.sentryclirc

[defaults]
org = organizarion-name
project = project-name
```

何も考えずに config

```javascript:nuxt.config.js
{
  modules: [
    '@nuxtjs/sentry',
  ],
  sentry: {
    dsn: process.env.SENTRY_DSN,
    publishRelease: true,
    sourceMapStyle: 'hidden-source-map',
    config: {
      release: process.env.GIT_SHA,
    },
  },
  // ***
}
```


`release` はtag名やpackages.json に記載してるバージョンなど何でもいいのですが、とりあえずリリース時点のコミットハッシュをいれておきました。

`sourceMapStyle` は webpack の sourcemap を設定するプロパティです。 デフォルトの値は `"source-map"` になってるので、本番運用では `"hidden-source-map"` を指定してあげるとクライアント側では SourceMap を隠してくれます。[README](https://github.com/nuxt-community/sentry-module#sourcemapstyle)にも書いてあります。

## 困ったこと

最初はReleaseの実行に必要な環境変数がわからなかったり、本番運用で必須な SourceMap の隠し方が分からず結構時間を取られてしまいました。解決するために [こちらの記事](https://medium.com/@tkdn/next-js-%E6%9C%AC%E7%95%AA%E9%81%8B%E7%94%A8%E3%81%AB%E3%81%8A%E3%81%91%E3%82%8B-tips-of-next-config-js-3e0d3d950b2d) などを参考にさせていただき、SourceMapを除去する Webpack Plugin 書いたりとかしてました。

が、今回記事をまとめるにあたって改めてドキュメントを読んでみたらしっかりと書いてあるんですよね… 残念な英語読解力を痛感しました。

初めて Nuxt と Sentry を使われる方の参考にしていただければ幸いです。

## 参考

- [How to Use Sentry with Nuxt.JS](https://lucas.love/how-to-use-sentry-with-nuxt-js)
- [Next.js : 本番運用における Tips of next.config.js](https://medium.com/@tkdn/next-js-%E6%9C%AC%E7%95%AA%E9%81%8B%E7%94%A8%E3%81%AB%E3%81%8A%E3%81%91%E3%82%8B-tips-of-next-config-js-3e0d3d950b2d)
- [CircleCiのビルドでSentryのreleaseを更新しSourceMapを追加(Nuxt.js編)](https://qiita.com/sot528/items/f46a3bc1c18f145ec411)
- [Sentryを使ってエラー監視](https://qiita.com/e_tyubo/items/4d886d02de04e9456893)