OmniAICreator/Qiita-1.07M huggingface dataset:
[PHP]Composer超概要（初めの一歩）

皆さんこんにちは。

**PHP Advent Calendar 2020（Qiita）16日目**の記事を書かせていただきます。

今年から仕事でPHPを書くようになり（それまではずっとJavaエンジニア）PHPを書いているのですが、ずっとレガシーなPHPのシステムを触っていました。が、最近ふとLaravelで開発するようになり、Laravelを使う中で出てくるのが今回扱う「**Composer**」でした。正直、PHPで開発するならComposerないとしんどいなぁ・・というのを実感したので、改めてComposerはどういうものなのか、何が便利なのかを嚙み砕いて書いていければと思います。

# What's Composer?
- **「依存関係管理ツール」/ プロジェクト単位で管理できる**

>Composerとは「依存関係管理ツール」と呼ばれるソフトウェアで、PHPのプログラムで使用するパッケージの依存関係を管理する為に使用される。プロジェクト単位にパッケージを>管理できる。【引用】Composerの教科書 - 増井 敏克著

プロジェクト単位で管理できるので、複数プロジェクトで異なるバージョンのライブラリを導入したい場合でも他プロジェクトに影響を与えない かつ デフォルトでは「**vendor**」というディレクトリにインストールしたライブラリが一括で格納されるので、管理もしやすくわかりやすいです。

- **パッケージの依存関係を管理してくれる**
複雑なパッケージ管理もComposerが担ってくれます。導入したいパッケージに必要なライブラリ等もまとめてインストールしてくれるので、パッケージごとの依存関係を意識せずとも必要なパッケージを導入できます。

- **composer.jsonで同じバージョンのライブラリをすぐに共有できる**
複数の開発者で開発をする際には、composer.json = 「**Composerを管理しているファイル**」を共有→ composer.jsonがあるディレクトリ上でcomposer installとするだけで、依存しているライブラリを持ってきてくれます。このファイルを共有するだけでバージョンを同じに揃えられる・・・とても便利ですね。

- **オートローディング機能**
Composerでは、オートローディング（**スクリプト冒頭にrequireやincludeを個別に書かなくても、使用したいファイルを自動的に読み込める機能**）が使用できます。※オートローディングについてはまだ勉強中なので、また別の記事で詳しく書きます。

# Composerの導入
Composerのインストールについては、公式のWebサイトに詳しく載っているので割愛します。インストールしたいOSにPHPがインストールされていれば、あとは手順に沿ってインストールするのみです。

公式リンク: https://getcomposer.org/

# LaravelもComposer経由でインストールされる！？
Laravelで開発する際には、ComposerでLaravelをインストールする必要があります。

# まとめ
今回の記事では、Composerについての概要をざっくりとまとめました。まだまだ学習中で、理解できていないことも多いので、しっかりと知識を身に着けたうえで再度ComposerについてもQiitaにまとめていこうと思います。

明日は @thgm3116  さんです！
netsh advfirewall firewall show rule name=all の結果をソートする

分かる人にしか分らないタイトルを付けました。

この記事は、[PowerShell Advent Calendar 2020](https://qiita.com/advent-calendar/2020/powershell) の 6 日目（遅刻）の記事です。空いていたので、最近使った小ネタを投下させて頂きます。

# 本文

Windows のファイアウォールをエクスポートするときに、タイトルにあるようなコマンドを実行します[^1]が、
出力結果がソートされておらず、変更前後で比較したいときに困ることがあります。

[^1]: `Get-NetFirewallRule` を使うとソートすることはできますが、遅いので使いづらいです。。。

ソートして出力するオプションがあるのかも知れませんが、`/?` でそれらしい説明が見つけられなかったので PowerShell を使って出力結果のソートを試みます。

以下のようにします。

```powershell
netsh advfirewall firewall show rule name=all dir=in type=dynamic | out-string | set txt
$txt.Trim() -replace "\r\n\r\n", "`r`n@@@@@" -split "@@@@@" | sort
```

1行目で、`netsh` の出力を変数 `txt` に保存しています。普通に出力すると行毎に分割された文字列の配列になってしまうところを、`out-string` でまとめて１つの文字列にしています。
2行目で、空白行に `@@@@@` を入れてから `split` しています。特に `@@@@@` を入れなくても連続した改行で直接分割したら大丈夫だと思います。ただし、先頭に空白行があるので最初に `Trim()` しないと正しくソートできません。

以上です。
GinkgoのDesrcibeTableの使い方

Ginkgoには、DescribeTableというTable Driven Testの仕組みが用意されています。
DescribeTableを使わないでfor文でテストデータの数だけIt()を呼ぶ方法もありますが、テストデータをハードコーディングする場合はDescribeTableを使うと便利です。

以下、DescribeTableの使い方の例を示します。

## BeforeEach/BeforeSuiteの実行前にテストデータが作れる場合

公式のサンプルコードそのまま。

```go
import (
    . "github.com/onsi/ginkgo/extensions/table"

    . "github.com/onsi/ginkgo"
    . "github.com/onsi/gomega"
)

var _ = Describe("Math", func() {
    DescribeTable("the > inequality",
        func(x int, y int, expected bool) {
            Expect(x > y).To(Equal(expected))
        },
        Entry("x > y", 1, 0, true),
        Entry("x == y", 0, 0, false),
        Entry("x < y", 0, 1, false),
    )
})
```

## BeforeEach/BeforeSuiteの実行後でないとテストデータが作れない場合

bookという変数があり、テストデータを作るのにbookを作る必要があるが、bookはBeforeEachでないと作れない状況を考えます。

```go
var _ = Describe("Book", func() {
	// ここでは、テストデータを作るのに必要。BeforeEachでないと作れないとする。
	var book Book

	BeforeEach(func() {
		book = CreateBook()
	})

	type TestData struct {
		id       int
		expected bool
	}

	DescribeTable("Find",
		func(lazyTestData func() TestData) {
			// テストデータを生成する:
			testParam := lazyTestData()
			Expect(DoesExist(testParam.id)).To(Equal(testParam.expected))
		},
		// テストデータそのものではなく、テストデータを作る関数を渡す。
		// このコード実行時点では、テストデータを生成するのに必要なbookが作られていないため
		Entry("本が見つかること", func() TestData {
			return TestData{
				id:       book.ID,
				expected: true,
			}
		}),
		Entry("本が見つからないこと", func() TestData {
			return TestData{
				id:       -1,
				expected: false,
			}
		}))
})
```

最初に示した例のように、Entry()の引数に直接テストデータを渡すことはできません。DescribeTable()の実行時点では、BeforeEachが呼ばれていないので、テストデータを作れていないからです。

そこで、テストデータそのものではなく、テストデータを作成する関数をDescribeTableには渡します。最終的には、テスト実行時(DescribeTableの第2引数の関数の実行時)に、テストデータを作成する関数を呼び出すことでテストデータを作ります。このタイミングであれば、BeforeEachが呼ばれているので、テストデータは作れます。

示してみたもののこのパターンとのときは、素直にIt()を1つずつ書く、各Itの中でテストデータを作る、検証処理は関数化して各Itで呼ぶ、とした方が分かりやすいかと思います。
アドベントカレンダー13日目：SREを読んでみた「分散システムのモニタリング」編③

前回の内容を振り返ると、モニタリングシステムは、ユーザーに対して、何が、なぜ壊れたのかに答える必要がありました。その手法には、ホワイトボックスとブラックボックスあり、４大シグナル（レイテンシ、トラフィック、エラー、サチュレーション）に焦点を当てる必要があるということを学びました。
今回は、モニタリングシステムを構築する際の観点について、学びます。

## 0から作るモニタリングシステム
モニタリングシステムを0から構築するとしたら、何を考えるべきでしょうか？
前回の内容を踏まえると、４大シグナルをモニタリングする必要がまずありそうです。
レイテンシに注目した時、レイテンシの定義は、リクエストを処理して、レスポンスを返すまでの時間なので、その値を測定して、そのまま返せばとりあえずユーザーがレイテンシを観察することはできます。しかし、モニタリングシステムならば、何かしらの値をトリガーとして、通知しないといけないです。通知の基準はどのように設定すべきでしょうか？
最終的に以下のような機能をもつシステムになるかもしれません。

> * **さまざまなメトリクス、レイテンシの閾値、パーセントタイルによるアラート**
* **考えられる原因を検出して知らせるための追加コード**
* **考えられる原因のそれぞれに関連するダッシュボード**<sup>1</sup>

## 適切な粒度の選択
メトリクスやレイテンシ、パーセントタイルの計測にあたって、適切な粒度を選択する必要があります。
以下に過剰となりうる粒度で設定された例が挙げられます。

> * **1分ごとのCPUの負荷を観察しても、高いテイルレイテンシを生じさせるスパイクは、それが長時間であっても、見つけられないかもしれません。**
* **一方、年間で合計9時間未満の停止時間（年間稼働率99.9%）をターゲットとするWebサーバーの場合、200（成功）のステータスの確認頻度を1分間に1回か2回以上にするのは、やり過ぎでしょう。**
* **同様に、99.9%の可用性をターゲットとするサービスのハードドライブの空き容量のチェックは、1分から2分に1回以上にする必要はありません。**<sup>1</sup>

このように、モニタリングしたい値により、適した粒度は異なります。
CPUの負荷を毎秒計測することは、収集、保存、分析のコストが大きくなります。
それほど細かい粒度でなくてもかまわないのなら、粒度を大きくすることでコストを抑えることができます。

## シンプルにする、ただしやり過ぎない
モニタリングシステムに限ったことではないですが、システムの要件を積み上げていくと、とても複雑なシステムが出来上がります。
複雑すぎるシステムは、脆く、変更するには複雑で、メンテナンスコストが高くなっていきます。
そのため、モニタリング対象は以下のガイドラインが参考になります。

> * **本当のインシデントを最も頻繁に捉えるルールは、可能な限りシンプルで、予想しやすく、信頼できるものであるべきです。**
* **ほとんど実施されない（例えば、SREチームによっては、四半期に1回未満が目安です）データの収集、集計、アラートの設定は削除すべきです。**
* **収集されてはいても、事前に作成されたダッシュボードのいずれにも表示されず、どのアラートにも使われていないシグナルは、削除の候補です。**<sup>1</sup>

##まとめ
* モニタリングの粒度は適切に選択する
* モニタイングシステムは、シンプルに保つ

#### 参考文献
1. Betsy Seyerほか　SRE サイトリライアビリティエンジニアリング　オライリー　63-66
Google Cloud Platform(GCP)で確約利用割引を買った(クォータの増加申請が必要だった)

## 概要
- 何となく稼動しているCompute Engineのインスタンスに対してとりあえず1年くらいは動かしてみるか、と思い確約利用割引を購入した。
- 購入時に躓いた点があったので、手順を備忘録として記載する。
- ざっくりいうとコミットメントのクォータ増加の申請が必要だった。(必要でない人ももしかしたらいる？)

## 購入失敗
- Compute Engine の確約利用割引「コミットメントを購入」から購入を試すも下記エラーが出て購入できなかった。
    - Quota COMMITMENTS exceeded. Limit: 0.0 in region {リージョン名}.
- ホームの推奨事項に「推奨されるCompute Engineコミットメント」があったので、そこから購入を試すも同様のエラー。

## コミットメントのクォータ増加の申請
- どうやらクォータ(Quotas)が足りないらしい。(エラーメッセージが全てを語る)
- IAMと管理 > 割り当て で Commitments でフィルタリング
- サービス：Compute Engine API、上限名：Commitments の 「すべての割当量」リンクを押下
- 該当リージョンを選択し上部の「割り当てを編集」リンクを押下
- 新しい上限に入力し、リクエストの説明を記載。次へで進んで申請する。
    - 新しい上限は「1」とした。（後述するが結局2000まで増やされる）
    - リクエストの説明は「該当リージョンでの確約利用割引を利用したいため。」とした。
- すぐメールが届き「2000に増やしたよ！」「反映まで最大15分かかるよ！」とのこと。
- しばらく待って IAMと管理 > 割り当て で確認するとと2000に増えてた。

## 購入成功
- クォータ増加後に確約利用割引からコミットメントを購入したら成功した。
- まだステータスが「保留中」なのが気になるが良きタイミングで動いてくれるだろう。
xampp Error: MySQL shutdown unexpectedly で立ち上がらないときの対処法

初めて書くので記事のクオリティについてはご了承ください。

xamppでMySQLを起動しようとしたときに以下のようなエラーが出てMySQLがシャットダウンしたのでその時の対処法です。
![スクリーンショット 2020-12-16 015441.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/579639/8d3a837a-ddae-7dca-297f-328e64927875.png)
また同じ目にあってもいいように残しときます。

原因はおそらくmysqlを止めずにpcをスリープかシャットダウンをしたのが原因だと思われる。
ちゃんとstop押して終了してからシャットダウンしましょう(お前が言うな)。

## 環境
- windows10 Home  
- xampp ver3.2.4



## 対処法
https://webkaru.net/dev/xampp-error-mysql-shutdown-unexpectedly/
↑のページの通りにC:\xampp\mysql\dataのよくわからんファイルどもを消した。
※怖いので念のために別のところにコピーを作成した。

そしてDB内のデータがちゃんとあるか確認したときにエラーが。。

```
MariaDB [retas]> select * from product;
ERROR 1932 (42S02): Table 'retas.product' doesn't exist in engine
```

お？？　エンジン？？

とりあえずググってみてこの[サイト](https://www.366service.com/jp/qa/b5cb3e50f1496c11e7b46b3311bf5ee7)にこんなことが書いてた。

>私は同じ問題に直面し、以下のステップを使用してソートしました。

>1.MySQLの設定ファイルに移動します(私のファイルはC:\xampp\mysqlin\my.ini)
>2.innodb_data_file_path = ibdata1:10M:autoextend行をチェックする
>3.次に、ibdata1ファイルがC:/xampp/mysql/data/の下に存在することを確認します。
>4.ファイルが存在しない場合、ibdata1ファイルを場所C:\xampp\mysqlackup\ibdata1からコピーします。
>それが誰かに役立つことを願っています。

なんかibdata1を存在することをとかゆーことはこれは消したらあかんっぽいなということでコピペで元に戻す。(まじで念のために残しておいてよかった。)

もう一度SQLを実行すると動きましたとさ。めでたしめでたし
DataPortal: 新機能さかのぼり（整数パラメータの種類）

DataPortalのまだ知らない使えそうな機能を求めて、新機能の一覧を遡ってみました。

整数パラメータの種類
> 数値パラメータに整数のみを使用可能にするか、または小数（浮動小数点）も使用可能にするかを指定できるようになりました。これは、特定のデータベース クエリなど、整数値を必要とするユースケースに役立ちます。

早速試してみます。

BigQueryにInteger型とFloat型のカラムを持つ適当なテーブルを作成し、DataPortalからカスタムクエリを発行して、レポートに表を作成します。
カスタムクエリ内で整数パラメータ、小数パラメータを使い分けてデータを取得します。

## Integer型に対しての試行
### 整数パラメータ
![スクリーンショット 2020-12-16 1.21.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423506/aa1663c8-7785-46e4-2f6e-0d04c3121283.png)
表a)が全データです。
表b)は整数パラメータ(値:70)でカスタムクエリを作成し、Integer型のageに対してwhere句を記述した結果です。
ageが70以下の `しげる` が消えました。

整数パラメータに対して小数(値:73.5)を設定すると、システムエラーが発生しました。
![スクリーンショット 2020-12-16 1.22.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423506/8f0627ef-886b-f826-7b86-6b764a678ce7.png)

### 小数パラメータ
![スクリーンショット 2020-12-16 1.22.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423506/95437829-802a-5360-231a-9ba90b6d86f9.png)
表c)は小数パラメータ(値:74.5)でカスタムクエリを作成し、Integer型のageに対してwhere句を記述した結果です。
ageが74.5以下の `しげる` と `よしひで` が消えました。

小数パラメータに対して整数(値:80)を設定すると、正常にクエリが実行されました。
![スクリーンショット 2020-12-16 1.23.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423506/283e5de8-a167-f413-26e2-b79df4fa2bdd.png)


## Float型に対しての試行
### 整数パラメータ
![スクリーンショット 2020-12-16 0.33.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423506/8eb275a6-2b1b-ee75-7746-1e07188692d6.png)
表b)は整数パラメータ(値:3)でカスタムクエリを作成し、Float型のpowerに対してwhere句を記述した結果です。
powerが3以下の `しげる` が消えました。

整数パラメータに対して小数(値:3.3)を設定すると、システムエラーが発生しました。
![スクリーンショット 2020-12-16 0.59.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423506/11d274fa-6c7c-fe4d-424e-0314a6f6d50e.png)

### 小数パラメータ
![スクリーンショット 2020-12-16 0.34.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423506/7bec1a95-0256-ec44-85b5-3fb53015fa18.png)
表c)は小数パラメータ(値:3.3)でカスタムクエリを作成し、Float型のpowerに対してwhere句を記述した結果です。
powerが3.3以下の `しげる` と `よしひで` が消えました。

小数パラメータに対して整数(値:3)を設定すると、正常にクエリが実行されました。
![スクリーンショット 2020-12-16 1.01.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423506/8236176b-a41e-4558-a953-015789534b4c.png)

## まとめ
BigQueryに対して整数パラメータと小数パラメータを使ったカスタムクエリを発行して、データを取得してみました。

DBのカラムがもつデータ型とパラメータの型は数値型であれば特に問わないようでした。

|| 整数パラメータ  | 小数パラメータ |
|----------|---------|-------| 
| Integer型 | 受け付ける   | 受け付ける | 
| Float型   | 受け付ける   | 受け付ける | 

ただし、整数パラメータに小数値を設定するとシステムエラーとなりました。

|| 整数値      | 小数値    | 
|---------|-------|--------| 
| 整数パラメータ | 受け付ける | 受け付けない | 
| 小数パラメータ | 受け付ける | 受け付ける  | 

今回わかった範囲だと、小数パラメータを使っておけばシステムエラーにならないという事なので、敢えて整数パラメータを使う意味があるのか、ちょっとよくわからない感じです。
新機能の意味が理解できていないのかもしれません。
【FastAPI】FastAPIでwebサイトを作ってみる

# はじめに

仕事や個人でLambdaを使ったWebサービスを作成しています。
FlaskやResponderも使ってみましたが、今回はFastAPIに挑戦したいと思います。

# 作るもの

![lambda.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266407/83762ef7-6075-b25a-a7fb-e0e11adcd658.png)

- AWS APIGateway + Lambda + Python + FastAPI を使ったサービスが構築できます
- ServerlessFrameworkを使って構築していきます

# 対象読者

- サーバーレスアプリケーションに触れてみたい人
- ServerlessFrameworkを使ってみたい人
- FastAPIを使ってみたい人

# FastAPIとは

> FastAPI は、Pythonの標準である型ヒントに基づいてPython 3.6 以降でAPI を構築するための、モダンで、高速(高パフォーマンス)な、Web フレームワークです。
https://fastapi.tiangolo.com/ja/

Responderもそうですが、Starlette に乗っかったフレームワークになっています。
Starletteが強力なので、APIだけでなく、Webサイトも作ることができます。

非同期処理を簡単に実装できます。
※Flaskを使っていたときは、非同期処理が簡単には実装できなかったです。

自動でドキュメントを作ってくれるのも便利です。

---

# 実行環境を構築

**Github**
https://github.com/acronhub/sls-python3-fastapi

**ディレクトリ構成**

MVCっぽくなるように試行錯誤しています。
正解がわからないのですが、他のフレームワークを参考にしたりして分けてみました。

> app
┣ controllers/　･･･　コントローラ（Controller）
┣ init/　･･･　準備
┣ libs/　･･･　ライブラリ
┣ models/　･･･ データベース（Model）
┣ static/　･･･ 静的リソース
┣ templates/　･･･ テンプレート（View）
┣ main.py
┣ requirements.txt
┗ serverless.yml

## Docker環境を準備

Docker環境で用意しました。
Githubからクローン後は、以下2つの手順で環境は完成します。

- AWSのIAMアカウントのアクセスキーを環境ファイルに設定します。
  - Github上のコードでは **.env.example** を用意しているので名前を **.env** に変えて利用します。

```yaml:.env
AWS_ACCESS_KEY_ID=XXXXXXXXXXXXXXXXXXXX
AWS_SECRET_ACCESS_KEY=YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY
AWS_DEFAULT_REGION=ap-northeast-1
SERVERLESS_VERSION=2.15.0
```

- ビルド

```bash
docker-compose build
```

## ローカルPCで動作確認

- コンテナ起動

```bash
docker-compose up
```

- [localhost:8000](localhost:8000)

![sc_index.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266407/de18b02f-ff29-7065-56d6-b62675a6b2ef.png)

## ローカルPCでドキュメントを確認

- [localhost:8000/docs](localhost:8000/docs)

![sc_docs.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266407/c4eba39d-218f-69ce-d7ac-7f116e631182.png)


# AWSにデプロイ

- デプロイ

```bash
docker-compose run --rm app yarn run deploy
```

# 動作確認

- エンドポイントがログに出力されているので、そこにアクセスします。

```bash
https://b02w4yeoh5.execute-api.ap-northeast-1.amazonaws.com/dev/
```

# おわりに

自分はResponderとFastAPIの両方を使ってみて、どちらもベースにしているフレームワークが同じなので、出来ることは一緒だと思いました。
ただGithubの更新を見てみるとわかるのですが、活発なのはFastAPIになります。
ドキュメントも日本語が充実しているのと、検索でもヒットしやすくなってきていると思います。
ドキュメントが勝手に作られるのは、本当に助かるので今後も利用していきたいと思います。

今回はデータベースの実装を省きました。
時間があったら追記したいと思います。

# 参考サイト一覧

- Flask : https://flask.palletsprojects.com/en/1.1.x

- Responder : https://responder.kennethreitz.org/en/latest/

- FastAPI : https://fastapi.tiangolo.com/ja/

- [ResponderとFastAPIを実際に使って比較してみた](https://rightcode.co.jp/blog/information-technology/responder-fastapi-comparison)

- [Serverless Framework+mangum+FastAPIで、より快適なPython API開発環境を作る](https://tech.jxpress.net/entry/2020/03/29/170000)

- [ASGI（非同期サーバゲートウェイインターフェース）の概要 (Junya Fukuda) [PyCon JP 2020]](https://youtu.be/EwG5EWKu8nw)
bindのスクリプトでちょっとハマった話

# 事の発端
「[Tcl/Tkで湯婆婆を実装してみる](https://qiita.com/qoLop/items/11f0678eeb83003903b8)」を書いている時のことでした。

```tcl:yubaba.tcl
#!/bin/sh
#-*-mode:tcl;coding:cp932;tab-width:8-*-\
    exec wish -encoding cp932 "$0" ${1+"$@"}

grid [label .w1 -text "契約書だよ。そこに名前を書きな。"] -sticky w
grid [entry .w2 -textvariable name] -sticky w
grid [label .w3 -textvariable contract -justify left] -sticky w
bind .w2 <Key-Return> {    
    set contract "フン。${name}というのかい。贅沢な名だねぇ。"
    set newNameIndex [expr {[clock microseconds] % [string length $name]}]
    set newName [string index $name $newNameIndex]
    append contract "\n今からお前の名前は${newName}だ。いいかい、${newName}だよ。分かったら返事をするんだ、${newName}!!"
}
```
というコードを書いて実行してみるとエラー!
![yubaba_bug.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/165786/a218f61c-bf5f-bac9-6e6f-489d5f3e6356.png)
え? え? 何? どういう意味?? 剰余演算子%を書いてるのに\になってる??

# 何が起きたのか
Tkのいくつかのコマンドのイベントハンドラでは「%Wはウィンドウ名に置き換える」などといったプレースホルダが定義されているものがあります。

前述のスクリプトで使用したbindコマンドのイベントハンドラもそのひとつで、それゆえ[剰余演算子%は「%%」と記述しなければならなかった](http://tcl.tk/man/tcl/TkCmd/bind.htm#M24)というオチでした。

それにしても「Error: invalid character "\"」って、もうちょっと分かりやすく警告してくれてもいいだろうに。
MYSQLが起動できない　Can’t connect to local MySQL server through socket ‘/tmp/mysql.sock’ (2)

##前書き
作業していると突然画面が固まりMacが再起動した。（原因不明）
その後ポートフォリオを開こうとしたところ
Can’t connect to local MySQL server through socket ‘/tmp/mysql.sock’ (2)
と表示されてしまい動かなくなってしまった。（正直死んだと思いました）

##目標
MYSQLに接続する。


##解決策
ネットで検索しているとどうやらmysql.sockというMySQLへ接続するためのファイルが突然消えることがあるらしい（少なくとも自分は消えた）
そして先ほどのエラー文を見ると
Can’t connect to local MySQL server through socket ‘/tmp/mysql.sock’ (2)
翻訳するとこの文の意味はmysql.sockなるファイルが/tmp配下に無いよと言っているようなので作っていきます。

1.まずtmpディレクトリに移動します。

```
cd /tmp
```

2.そしてtouchコマンドで作成していきます。（ここでlsで本当にmysql.sockがないかを確認した方がいいかもです。）

```
touch mysql.sock
```

あとはサーバーをスタート起動させていきます。

```
mysql.server start
```
こんな感じになっていれば成功です！！

```
Starting MySQL
. SUCCESS! 
```

##以上です!
ポートフォリオが全く見れなくなってしまったので本当に焦りました。割とよくあるエラーのようなので自力で解決する経験を得ることができたのは良かったかなとポジティブに考えております。
参考にしたサイト様　https://medium.com/wado-jp/%E3%82%88%E3%81%8F%E3%81%82%E3%82%8Bmysql%E3%82%A8%E3%83%A9%E3%83%BC%E9%9B%86-a6dc33e77a9a
実は簡単！？HerokuにアップロードしたCleraDB（MySQL）をCLIで接続する方法

heroku上にアップロードしたCleraDB（MySQL）を接続する方法に凄く手間がかかったので、同じ境遇にいる人の助けになればなと思い、自分の備忘録も兼ねて書いていきます。

**開発環境**

- windows10

```
mysql --version
mysql  Ver 8.0.22 for Win64 on x86_64 (MySQL Community Server - GPL)
```

以下のコマンドを打ち、データベースのユーザー名、パスワード、ホスト名、データベース名を取得します。

```
heroku config:get CLEARDB_DATABASE_URL
```

すると、このようにデータベースの情報が返ってくると思います。

`「CLEARDB_DATABASE_URL: mysql://[ユーザー名]:[パスワード]@[ホスト名]/[データベース名]?reconnect=true」`

この情報を元に、CLIで接続を行っていきます。

<font color="Red">**注意：MySQLのコマンドプロンプトではなく、windowsに搭載されているコマンドプロンプトを使ってください（Macならターミナル）**</font>

```
mysql -u[ユーザー名] -p[パスワード] -h[ホスト名]
//末尾にダブルセミコロン（；）は付けないでください。付けるとエラーが出ます。
```

すると、以下のような実行結果が返ってきます

```
～
Your MySQL connection id is id名
Server version: 5.5.62-log MySQL Community Server (GPL)
～
```

最後にデータベースを選択してください。（これめっちゃ忘れる）

```
use [データベース名];
//ここ、ダブルセミコロン（；）付ける

Database changed
```

後は好きにMySQLの構文を打ってください

```
select * from users;
```

んね？実は簡単♪
// エラトステネスのふるいをC++で実装してみたかった

学校で素数を書き出す課題が出たので実装してみました。

2020/12/18 追記：これは試し割り法です。エラトステネスのふるいの実装例はコメント欄へお願いします。

## コード
```C++
#include <bits/stdc++.h>
#define rep(i,n) for(auto i=0;i<n;++i)
typedef  unsigned long long ull;

using namespace std;

// 2以上の整数値を引数に取り，素数のvector<ull>を返す
vector<ull> eratosthenes_sieve(ull max_num) {
    vector<ull> int_list;
    vector<ull> searched_list;
    vector<ull> prime_list;
    int_list.reserve(max_num-1);

    rep(i, (int)max_num-1) {
        int_list.push_back(i+2);
    }

    while(int_list[0]*int_list[0] < max_num) {
        ull prime = int_list[0];
        searched_list.push_back(prime);
        auto removeit = remove_if(int_list.begin(), int_list.end(), [&](ull value) {
            return value % prime == 0;
        } );
        int_list.erase(removeit, int_list.end());
    }
    merge(int_list.begin(), int_list.end(), searched_list.begin(), searched_list.end(), back_inserter(prime_list));
    return prime_list;
}

signed main(void) {
    auto prime_list = eratosthenes_sieve(10000000);
    for(const auto& i: prime_list) {
        printf("%llu", i);
        if(i != *(prime_list.end()-1)) printf(", ");
    }
    printf("\n");
    return 0;
}
```

## 新しい知見
- vectorの初期化はvector.reserve()でvectorの範囲を指定してからpush_back()すると高速
- remove_if()を使うと条件に一致したvector要素を高速に削除できる
- merge()で2つのvectorを1つのvectorにできる
- vectorの要素がが整数型のとき，*(vector.end()-1)で最終要素が取得できる

## よく理解ができなかった部分
- remove_if()が実際にどのような処理をしているのかが理解できなかった

## 改善していきたい点
- 現状ではシングルスレッド処理なので，並列処理に対応し高速化を図りたい(Arch Linux, Core i5 10210u, N=10^7で13秒程度)


## 参考文献
[vectorの初期化 | Qiita](https://qiita.com/chikashimiyama/items/b09b20d79fddb395e311)
[最速の素数列挙プログラム C# | Qiita](https://qiita.com/asksaito/items/8fe448d21b394eb35582)
[C++日本語リファレンス | cpprefjp](https://cpprefjp.github.io)
[【C++】簡単なvectorテクニック | msty開発メモ](http://msty.hatenablog.jp/entry/2016/10/19/214748)
マンガでわかる暗室栽培ミニアンチパターン

![AB6F2A94-8445-47C4-9C44-4EBEB657B91B.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/11525/0ee1d41f-532b-19ee-59fd-23fb0179fc5e.png)
http://wiki.c2.com/?MushroomManagement

開発者をエンドユーザーやドメインから隔離して、暗いキノコ栽培部屋に引きこもらせてしまうパターンです。開発者が作っている機能が業務全体でどういう位置付けなのか理解せず、仕様意図理解の精度向上やより正確な要求への変化への対応もしない場合、たいていは、開発しても受入テストに失敗します。

この問題は、要件は定まっているから仕様書どおりやればいい、自分はプログラマーをわかっている、プロダクトは技術力で良くなる、というような考えを持つ管理者あるいはチームのメンタリティによって引き起こされます。

そんなチーム内では、最終的な実装をする段階で、意図が不明瞭な箇所に対して憶測での分析が始まります。形になってこないと明確に言えない要求も多々あるので、初期の要求仕様の説明だけ見て暗室で推論を展開しても、そんなものはたいてい外れます。プロトタイプを見た顧客とともに、反復的に分析と設計を行うのが、満足度の高いソフトウェアを作るのに大切なことです。
Firebaseで座標を使った検索を実装する

## はじめに

medibaの創造推進Unitでフロントエンドエンジニアをしている川上です。

この記事は[mediba Advent Calendar 2020](https://qiita.com/advent-calendar/2020/mediba)の16日目の記事です

現在フロントエンドはNext、バックエンドはFirebaseでサービスの開発を行っています。

開発を行ううえでFirebaseで位置情報を使った検索を実装する機会があり、少し苦労したので紹介しようと思います。

## 想定するユースケース

今回は仮にカフェの情報を検索することができるサービスを作ることを想定します。

ユーザーは駅を指定し、指定した駅周辺にどのようなカフェがあるかを参照できるようなサイトを作成します。

## geofirestore

このようなユースケースでは[geofirestore](https://geofirestore.com/)を使って実装することで実現できました。

## Cloud Firestoreに追加する

geofirestoreを使って検索するデータはgeofirestoreで追加する必要があります。

以下のようなコードでCloud Firestoreにカフェのデータを追加します。

```Javascript
import firebase from "firebase/app";
import * as geofirestore from "geofirestore";

const firestore = firebase.firestore();
const GeoFirestore = geofirestore.initializeApp(firestore);
const geocollection = GeoFirestore.collection("cafes");

geocollection.add({
  name: "エクセルシオール カフェ 池袋二丁目店",
  coordinates: new firebase.firestore.GeoPoint(35.731955, 139.708306),
});
geocollection.add({
  name: "カフェ・ド・巴里池袋西口店",
  coordinates: new firebase.firestore.GeoPoint(35.731902, 139.710036),
});
geocollection.add({
  name: "カフェ フランジパニ 六本木",
  coordinates: new firebase.firestore.GeoPoint(35.661022, 139.732123),
});
geocollection.add({
  name: "アンティコカフェ アルアビス 六本木ヒルズ店",
  coordinates: new firebase.firestore.GeoPoint(35.660175, 139.728964),
});
```

池袋周辺のカフェ２店舗と六本木周辺のカフェ２店舗を追加しました。

各店舗のデータは店舗名を値としてもつ`name`と店舗の経度、緯度を使って生成したGeoPointを値としてもつ`coordinates`をフィールドとして生成しています。
実装例としてシンプルに２つのフィールドを定義していますが実際のアプリケーションでは店舗の電話番号や評価なども追加されるかもしれません。


## Cloud Firestoreをみてみる

Cloud Firestoreをみると以下のようになっていました
![スクリーンショット 2020-12-16 0.16.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244992/1c1abd07-1e3a-b8a6-0bd0-ae03b98a72ca.png)

無事に４店舗分のカフェのデータが保存されているのがわかります。

各店舗のフィールドに注目すると`g`という追加した覚えのないフィールドがあります。
この`g`はライブラリによって追加されてフィールドで`g.geohash`を使ってgeoqery生成します

## 六本木周辺のカフェをブラウザから取得する

いよいよブラウザからカフェデータ取得します。

今回は六本木駅周辺のカフェを探すことを想定しています。

```Javascript
const query = geocollection.near({
  center: new firebase.firestore.GeoPoint(35.666656, 139.729694), // 六本木駅の座標
  radius: 3,
});

query.get().then((value) => {
  value.docs.forEach((doc) => {
    console.log(doc.data());
    // {name: "アンティコカフェ アルアビス 六本木ヒルズ店", coordinates: t, g: {…}}
    // {name: "カフェ フランジパニ 六本木", coordinates: t, g: {…}}
  });
});
```

`geocollection.near`に渡している`radius`は検索の範囲が半径をキロメートル単位でどの程度にするかを指定しています。

実行した結果無事に六本木周辺のカフェ2店舗を取得することができました。

## おわりに

実装するまで難しそうだと考えていた座標を使った検索がgeofirestoreのおかげで実装することができました。
Firestoreを使った座標での検索をするうえで誰かの役にたてば幸いです。
enebularで爆速でリモートワークの 課題解決してみた

12/1に実施された[【オンライン】enebular developer meetup](https://enebular.connpass.com/event/193989/)でのLT内容を記事にしています。

2020年もあとちょっとで終わりですね。今年はコロナ禍で仕事も完全リモートワークになり、いろいろと変化を求められる年になりました。そんな中で在宅で仕事をしていると、今までなかった課題だったり、ミスだったりが出るようになりました。

リモートワークになってから、

・MTGが社内外合わせて3~4倍くらいの量になった（スケジュール管理が大変）
・周りの動きがないから、時間の流れがわかりにくくなった（ついつい作業に集中しすぎてしまう）

といったスケジュール管理の課題が見えてきたので、今回はenebularを使ってさくっと解決してみました。


#概要

作業に集中するあまり、MTGを飛ばしてしまうこともけっこうあったので、MTGに気づきやすくするためにスケジュールの時間になったらスマホにMTGのお知らせを通知するシステムを作ります。
簡単な技術の組み合わせなので、１５分くらいで実装できます。

使った技術
・enebular
・Google CalenderAPI
・LINE Notify
![スクリーンショット 2020-12-16 0.43.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/248994/39bea383-5e04-eaf9-e8cd-1b7b32927adf.png)


#enebular

enebular上のノードはこちらになります。

Google CalenderノードとLINEのNotifyノードをつなげて、通知の内容を制御するtemplateノードを間に挟めば完成です。
![スクリーンショット 2020-12-16 0.42.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/248994/f2ccbeda-3c76-e82a-15cb-edea1657b15a.png)


##Google Calender
まずはGoogle Calenderノードでカレンダー情報を取れるようにGoogleアカウントの認証をします。
Google Calenderノードの設定は[こちらの記事](https://qiita.com/satosiyonezawa/items/dd1d5628dd6e56eadc7b)が参考になります。

![スクリーンショット 2020-12-16 0.49.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/248994/91e775b2-66ae-55b2-bafd-292e6288cc59.png)

Client IdとSecretにGoogle APIsの認証情報を入れていきます。（今回省略します）
![スクリーンショット 2020-12-16 0.54.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/248994/41340760-2830-d781-1e0b-8d1086e16c41.png)


##templateノード

個人的には手元にあるスマホに通知＋通知音が届けば気がつくような状態だったので、templateノードの内容は基本的にシンプルに設定し、最低限の情報のみ伝えるようにしました。
![スクリーンショット 2020-12-16 0.58.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/248994/78b7b040-145c-bcbd-aa7b-e225416b1d76.png)

やりようによっては会議名とか出したり、MTG URL通知したりもできるかと
[Calender APIのリファレンス](https://developers.google.com/calendar/overview)

##LINE Notify
LINE NotifyノードにはNotify側で発行したAcces Tokenを入れれば完了となります。
![スクリーンショット 2020-12-16 1.01.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/248994/5a844e3d-ae45-3d8d-e701-208e8e08de7f.png)


うまくいけば、MTGの開始時に通知が届くようになります。
![スクリーンショット 2020-12-16 1.03.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/248994/55c2b168-7dca-01a9-60a9-27805cdf0c12.png)


通知タイミングを変えたい場合は、CalenderノードのタイミングをいじればOKです。
![スクリーンショット 2020-12-16 1.04.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/248994/5b0447af-b2c4-3a73-aca4-75106f996c6f.png)

##Herokuにデプロイ
いつでもフローが実行されるように、enebularのフローをHerokuにデプロイします。
デプロイは公式サイトのドキュメントがわかりやすいです。
[enebular公式ドキュメント - Herokuデプロイ](https://docs.enebular.com/ja/deploy/DeployFlow/Heroku/)



#終わり

あっという間に完成です。おそらくGoogleの認証周りで時間かかるかもですが、さくっと通知システムを作ることができます。[参考記事](https://qiita.com/satosiyonezawa/items/dd1d5628dd6e56eadc7b)わかりやすくて助かりました。


###余談
カレンダーアプリのデスクトップ通知使えばよくねって声もあるんですが、在宅になってクライアントと画面共有しながら話してる時に、他社案件のポップアップが出たりしてけっこう危ないので、基本的にデスクトップ通知切るようにしています。というわけで、代替え案として今回のものを採用しました。
strcpyもstrncpyも危険

## C言語の文字列は厄介
文字列は文字の配列で、Null終端で最後という仕様なので、
どうやっても番兵スタイルになる。
番兵とはNullのことで、処理の進め方として、Nullになるまで処理するというスタイルのこと。
単方向リストなどで使う。
Nullがないと処理がリークするので、Null保証する仕組みを作ったりする。

## strcpy関数は危険
strcpy関数は引数が2個のみでサイズを指定できないため、
Null終端があったとしても危険

```c
#define SRC_LENGTH 10
#define DEST_LENGTH 3

char src[SRC_LENGTH];
char dest[DEST_LENGTH];

strcpy(dest,src);
```

## strncpy関数も危険
strcpy関数は危険なので、strncpy関数を使うとサイズ指定ができるが、これも危険である。
以下のコードは危険コード。

```c
#define SRC_LENGTH 10
#define DEST_LENGTH 3

char src[SRC_LENGTH];
char dest[DEST_LENGTH];

memset(src, "aiueoaiue", SRC_LENGTH);
strncpy(dest,src, DEST_LENGTH);
```

このコードのstrncpy関数呼び出し後のdest変数の中身は

```c
dest[0] = 'a';
dest[1] = 'i';
dest[2] = 'u';
```
となるので、Null終端がない。

## 解決策はあるのか？

本質的には無理だと思う。C言語の特性なので、頑張る。

```c
strncpy(dest,src, DEST_LENGTH);
dest[DEST_LRNGTH-1] = '\0';
````
でとりあえずリークはしない。リークの是正目的だけは満たせる。

## Linuxカーネルに
strscpy関数なるものがある。

```c
ssize_t strscpy(char *dest, const char *src, size_t count)
{
	const struct word_at_a_time constants = WORD_AT_A_TIME_CONSTANTS;
	size_t max = count;
	long res = 0;

	if (count == 0)
		return -E2BIG;

#ifdef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
	/*
	 * If src is unaligned, don't cross a page boundary,
	 * since we don't know if the next page is mapped.
	 */
	if ((long)src & (sizeof(long) - 1)) {
		size_t limit = PAGE_SIZE - ((long)src & (PAGE_SIZE - 1));
		if (limit < max)
			max = limit;
	}
#else
	/* If src or dest is unaligned, don't do word-at-a-time. */
	if (((long) dest | (long) src) & (sizeof(long) - 1))
		max = 0;
#endif

	while (max >= sizeof(unsigned long)) {
		unsigned long c, data;

		c = read_word_at_a_time(src+res);
		if (has_zero(c, &data, &constants)) {
			data = prep_zero_mask(c, data, &constants);
			data = create_zero_mask(data);
			*(unsigned long *)(dest+res) = c & zero_bytemask(data);
			return res + find_zero(data);
		}
		*(unsigned long *)(dest+res) = c;
		res += sizeof(unsigned long);
		count -= sizeof(unsigned long);
		max -= sizeof(unsigned long);
	}

	while (count) {
		char c;

		c = src[res];
		dest[res] = c;
		if (!c)
			return res;
		res++;
		count--;
	}

	/* Hit buffer length without finding a NUL; force NUL-termination. */
	if (res)
		dest[res-1] = '\0';

	return -E2BIG;
}
```
コピーするだけでこのボリューム。さすがC言語。さすがLinuxカーネル。
これの解説はあとで。

使う側の利点としては
strscpy関数は

- コピー元がNull終端でなくてよい
- コピー先は必ずNull終端
- コピー先のサイズが足りない場合はエラーを返す

なので、うまくこれを使っていきたい。
ATTiny13Aでクリスマスイルミネーションを作ってみた

#クリスマスですね
　クリスマスツリーを買ったときに付いてきた乾電池で動く中華製のLEDストリングは電池ボックスに点滅用の回路が入っていたのですが、点滅速度が速すぎて家族に不評だったのと、乾電池駆動が個人的に嫌いだったので、USB給電に改造するついでにATTiny13Aを使ってじわっと点滅できるようにしました。
　パターンがいつも同じだと退屈なので空いているピンの浮動電圧を使って点滅周期が一定時間ごとにランダムに変わるようにしました。たまたま別のLEDストリングも余っていたので2チャンネルでそれぞれ独立したタイミングで点滅するようにしました。
 コンパイルにはbitDuino13を使用し、9.6MHzで動作するように設計しました。

* じわっと点滅LEDストリング用回路
* 独立2ch
* ランダムな周期

#結線
回路図は付けませんが5，6番ピン（PB0, PB1）からそれぞれ1KΩを介してトランジスタC1815のベースに接続して、VCCとコレクタの間に92Ωの抵抗を介してLEDストリングをつなぎました。明るさが欲しい人はもっと低い抵抗値でもいいかもしれません。LEDの数と相談して決めてください。USBケーブルから電源をとれるようにしているので電源電圧は5Vを想定しています。
点滅周期をランダムに変える乱数取得のために2番ピン(A3)の浮動電圧を取得して適当な数で割った余りを計算しています。

```cpp:Xmas2chLamp.ino
/* bitDuino13 9.6MHz  */
int led[2];           // the PWM pins the LED is attached to
/*int analogPin=3;      // the sensor pin to generate random number*/
analog_pin_t analogPin=A3; // analog_pin_t is needed to compile using MicroCore
int brightness[2];    // how bright the LED is
int fadeAmount[2];    // how many points to fade the LED by
int threshold[2];
unsigned int j=0;

// the setup routine runs once when you press reset:
void setup() {
  int i;
  for(i=0; i<2; i++){ // declear pins 0, 1 as output
    led[i]=i;
    pinMode(led[i], OUTPUT);
    brightness[i]=0;
  }
  pinMode(analogPin, INPUT); // declear analog pin
  fadeAmount[0]=5;
  fadeAmount[1]=10;
  threshold[0]=0;
  threshold[1]=0;
}

// the loop routine runs over and over again forever:
void loop() {
  int i;
  int k=j % 1000;
  int tmp;
  j++;
  if(k < 3){ /* 約30秒ごとに点滅周期を変更 */
    tmp=analogRead(analogPin) % 20;
    fadeAmount[k % 2]=(tmp*tmp/4+1)*constrain(fadeAmount[k % 2],-1,1);
    if(tmp > 15){ /* 点滅周期が早いのも楽しいがずっと続くと不快なので周期の変更を速めます */
      j+=600;
    }
  }else if(k < 5){ /* じわっと点滅ばかりでは退屈なのでときどきはぱっと消すための設定 */
    tmp=analogRead(analogPin) % 160;
    threshold[k % 2]=tmp - 60; /* thresholdがマイナスの時にはじわっと点滅 */
  }

  for(i=0; i<2; i++){
    if(brightness[i] > threshold[i]){
      analogWrite(led[i], brightness[i]);
    }else{
      digitalWrite(led[i], LOW);
    }

    brightness[i] = brightness[i] + fadeAmount[i];

    if (brightness[i] <= 0 || brightness[i] >= 255){
      fadeAmount[i] = -fadeAmount[i];
    }
    brightness[i]=constrain(brightness[i], 0, 255);
  }
  // wait for 30 milliseconds to see the dimming effect
  delay(30);
}
```
JavaScript,7,乱数（ランダムな数値）,Math.random,初心者向け

ランダムな数字
JS（JavaScript）で乱数（ランダムな数値）を出す方法と、それを活用した実例を紹介しています。
配列と組み合わせいきます。

```
const randomNumber =Math.random();
console.log(randomNumber);
```
０〜１未満の数値をランダムに生成する


console.log(randomNumber * 5);
0~4.9まで

(randomNumber * 5 +1);
1~5.9まで

console.log(Math.floor(randomNumber *5 +1));
小数点切り捨て

```
document.getElementById("test").textContent = "今日のラッキーナンバーは" + 
Math.floor(randomNumber *5 +1);
```
今日のラッキーナンバーは○ここの数字がランダム

```
const omikuzi =  ["大吉", "中吉","凶"];
const omikuzirandomNumber = Math.floor(Math.random() * omikuzi.
length);
document.getElementById("omikuzi").textContent = omikuzi[omikuzirandomNumber];
```

配列とランダムの組み合わせでおみくじ
macでbioawkを使用する

## 背景
bioawkはawkによる表形式ファイルのデータ処理をfastqやsam、gtfなどバイオデータのファイル形式に拡張したものです。-cオプションでファイル形式を指定することでそのファイル形式に対応した変数を使用することができます。

## 方法
Homebrewでインストールできます。

```sh
brew tap brewsci/bio; brew install bioawk
```

## 結果
helpが出ることを確認します。bioawkが対応する入力ファイル形式と各フィールド（列）の変数が表示されます。awkでフィールドは「$数字」ですがbioawkではこの変数を用いて処理を行うことができます。

```sh
bioawk -c help
bed:
	1:chrom 2:start 3:end 4:name 5:score 6:strand 7:thickstart 8:thickend 9:rgb 10:blockcount 11:blocksizes 12:blockstarts
sam:
	1:qname 2:flag 3:rname 4:pos 5:mapq 6:cigar 7:rnext 8:pnext 9:tlen 10:seq 11:qual
vcf:
	1:chrom 2:pos 3:id 4:ref 5:alt 6:qual 7:filter 8:info
gff:
	1:seqname 2:source 3:feature 4:start 5:end 6:score 7:filter 8:strand 9:group 10:attribute
fastx:
	1:name 2:seq 3:qual 4:comment
```
![root_cb6ba2bbd7c6___Users_tt.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363491/a163184e-bee5-93a3-a5e8-c151fdfffeff.png)

## 使用例
fastqファイルをfasta形式に変換します。
※ファイル及びコードは[Vince Buffalo著、片山俊明『バイオインフォマティクスデータスキル』（オライリー・ジャパン、ISBN978-4-87311-863-5、177頁）](https://www.oreilly.co.jp/books/9784873118635/)より。

```sh
#ファイルのダウンロード（下記で使用するfastqファイル以外も含まれます）
git clone https://github.com/vsbuffalo/bds-files.git

#fastqファイル
cat contam.fastq | head -n 8
@DJB775P1:248:D0MDGACXX:7:1202:12362:49613
TGCTTACTCTGCGTTGATACCACTGCTTAGATCGGAAGAGCACACGTCTGAA
+
JJJJJIIJJJJJJHIHHHGHFFFFFFCEEEEEDBD?DDDDDDBDDDABDDCA
@DJB775P1:248:D0MDGACXX:7:1202:12782:49716
CTCTGCGTTGATACCACTGCTTACTCTGCGTTGATACCACTGCTTAGATCGG
+
IIIIIIIIIIIIIIIHHHHHHFFFFFFEECCCCBCECCCCCCCCCCCCCCCC

#fastaファイルへ変換（#nameでヘッダー情報、$seqで配列情報を取得しています）
bioawk -c fastx '{print ">"$name"\n"$seq}' contam.fastq | head -n 4
>DJB775P1:248:D0MDGACXX:7:1202:12362:49613
TGCTTACTCTGCGTTGATACCACTGCTTAGATCGGAAGAGCACACGTCTGAA
>DJB775P1:248:D0MDGACXX:7:1202:12782:49716
CTCTGCGTTGATACCACTGCTTACTCTGCGTTGATACCACTGCTTAGATCGG
```
【Nuxt.js】コマンドメモ

Nuxt.jsとFirebaseを使ってWebアプリ開発中。

よく忘れるのでメモ。


ローカル開発環境立ち上げ

```
npm run dev
```

プロジェクトをビルド

```
npm run build
```

Firebaseに反映

```
firebase deploy
```


久しぶりにデプロイするとエラーになった。

```
Error: Failed to get Firebase project PJ名. Please make sure the project exists and your account has permission to access it.
```

再ログインする必要があるらしい。

```
firebase logout
firebase login
```


終わり
Vagrant を使い ubuntu16.04 に ngrok をインストール

　
<b>`VirtualBox`</b>に作った<b>`ubuntu16.04`</b>へ<b>`Vagrant`</b>を操作し<b>`ngrok`</b>をインストールしました。
　

| ソフトウェア               | バーション     |   
|:-----------------------|------------:|
| VirtualBox             | 6.1.16      | 
| ubuntu / xenial64      | 16.04.7 LTS | 
| Vagrant                | 2.2.14      | 
| ngrok                  | 2.3.35      |
　
 

###①　vagrant にて ngrokをインストール
　linux ( arm64 ) を zipファイルでインストール　

```
vagrant@ubuntu-xenial:~$ wget https://bin.equinox.io/c/4VmDzA7iaHb/ngrok-stable-linux-amd64.zip
```
###②　zipファイルを解凍
　`~＄　unzip ngrok-stable-linux-amd64.zip`って打ったら`unzip`そんなコマンドはねぇ!! って怒られたのでインストール


```
vagrant@ubuntu-xenial:~$ sudo apt install zip
vagrant@ubuntu-xenial:~$ sudo apt install unzip
```
早速、`unzip`コマンドを使って先ほどインストールしたファイルを解凍します。

```
vagrant@ubuntu-xenial:~$ unzip ngrok-stable-linux-amd64.zip
```
きちんと出来たかの確認をします。

```
vagrant@ubuntu-xenial:~$ ls
ngrok  ngrok-stable-linux-amd64.zip
```
大丈夫そうです:smiley:
　
###③解凍された`ngrok`ディレクトリを /usr/bin へコピー
　<b>※</b> 「/usr/bin」には、「シングルユーザモードで利用しない」かつ「RPMやdebなどのパッケージ管理システムによって、システムに管理されるコマンドやプログラム」が置かれます。非常時に利用するものではないが、システムを構成する重要なコマンドやプログラムはここに置かれることになります。

```
vagrant@ubuntu-xenial:~$ sudo cp ngrok /usr/bin
```
###④使えるようになったかの確認

```
vagrant@ubuntu-xenial:~$ ngrok -version
ngrok version 2.3.35
```
しっかりインストール出来ていて一安心 :blush:
　

###⑤起動する
起動させたい時は以下のコマンド

```
vagrant@ubuntu-xenial:~$ ./ngrok http 80
```
なにか知りたい時には以下のコマンドでわかります。

```
vagrant@ubuntu-xenial:~$ ./ngrok help
```

　
　

##参考

https://qiita.com/mininobu/items/b45dbc70faedf30f484e　　
https://qiita.com/RayDoe/items/8a68f40d165819b82463　
https://linuc.org/study/knowledge/544/
OperationalError: no such table:○○　エラーの解決方法

#はじめに
Djangoで記事投稿サイトを作っていた際に発生し、かなり長い間悩ませてくれたOperationalError: no such tableの解決方法を記事に残しておきます！

難しいことは抜きにして、プログラミング初心者でも分かるよう解決手段に特化して書いてみました。
Mac環境ですので、必要に応じてWindowsに読み替えてください。

#目次
①エラー内容
②エラー解決手順

#①エラー内容
投稿記事にカテゴリを付与すべくmodels.pyにカテゴリを追加した後、migrateをしたところ以下のエラーが

```python:python
django.db.utils.OperationalError: no such table: app_category
```
*app_categoryのappは僕が設定したappというフォルダ名で、categoryは僕が設定したクラス名です。
エラー発生時には皆さんが設定したフォルダ名およびクラス名が入ります。

上記エラーは、データベース上にapp_categoryというテーブル（データ）が入ってないよという意味。


#②エラー解決手順
正直エラー内容についてちゃんと理解できていませんが、以下手順をとることで解決しました。

1. 一度db.sqlite3ファイルを削除
2. pythonファイルをチェックし、categoryが関係しているコードを全てコメントアウト
3. python3 manage.py makemigrations app　をターミナルに入力（繰り返しですが、appは僕が設定したapp用のフォルダ名です）
4. python3 manage.py migrate をターミナルに入力
5. models.pyファイルのcategory関連コードを復活
6. 再度python3 manage.py makemigrations appを入力<br>
この時、「categoryがnon-nullableだ。デフォルト値を設定しろ」というようなメッセージが出る場合があります。その時は選択肢1を入力し、次の画面でデフォルト値として適当な数字(1でok)を入れます。
7. 再度python3 manage.py migrateを入力
8. python3 manage.py runserverでアプリページに移動
9. admin画面にログイン
10. categoryを設定（カテゴリを一つ追加し、何らかの名前をつける）
11. 記事を一つ作成し、categoryもつける
12. コードに戻り、2.でコメントアウトしていたコードを全て元に戻す



以上です！

同じ勉強グループの中で同様のエラーが出ていた人が複数名いたのですが、上記手順で全員解決できていました。

僕は最終的に3種類のカテゴリ機能を持たせたのですが、__2から12までの手順を行いながらカテゴリを一つずつ追加__していきました。
正直面倒だとは思いますが、先へ進めず困っている方は試してみてください！
docker-machine startで `Failed to create the host-only adapter`

docker-machine start すると以下のエラー。

```
Starting "default"...
(default) Check network to re-create if needed...
(default) Creating a new host-only adapter produced an error: /usr/local/bin/VBoxManage hostonlyif create failed:
(default) 0%...
(default) Progress state: NS_ERROR_FAILURE
(default) VBoxManage: error: Failed to create the host-only adapter
(default) VBoxManage: error: VBoxNetAdpCtl: Error while adding new interface: failed to open /dev/vboxnetctl: No such file or directory
(default) VBoxManage: error: Details: code NS_ERROR_FAILURE (0x80004005), component HostNetworkInterfaceWrap, interface IHostNetworkInterface
(default) VBoxManage: error: Context: "RTEXITCODE handleCreate(HandlerArg *)" at line 94 of file VBoxManageHostonly.cpp
(default) 
(default) This is a known VirtualBox bug. Let's try to recover anyway...
Error setting up host only network on machine start: The host-only adapter we just created is not visible. This is a well known VirtualBox bug. You might want to uninstall it and reinstall at least version 5.0.12 that is is supposed to fix this issue
```

最低5.0.12 以上にあげてって書いてありますが、VirtualBox 5.2.44 でも起きました。

# 解決編

結局、以下のコメントにある Kernel Extensions をロードし直すスクリプトを走らせたら直りました。

https://github.com/Homebrew/homebrew-cask/issues/39369#issuecomment-339118861

というかこのスクリプト見覚えありすぎて、MacBook不安定すぎて年2回は環境構築するんですが、このコメントへのリンクになってる自分の [GitHub Dockerfilesリポジトリ](https://github.com/iwag/dockerfiles)が一番役立ってるっていう。

以上です。
AWS-Certified-Machine-Learning-Specialty 合格記

# はじめに
2020年11月、AWS-Certified-Machine-Learning-Specialtyに合格しましたのでその記録を残しておきます。
機械学習系の業務経験としては、約一年間AI開発系の業務に携わっており、特にここ半年間はSagemakerを使ってモデルの開発をしたりしています。
また、学部生時代は人工知能について専攻しており、元々機械学習についてはそれなりの知識がありました。
しかし、今回改めて勉強する中で結構基礎的（適合率とか再現率とかごちゃごちゃになってた）なことも忘れていたので機械学習の経験があまりない方も参考になると思います。
# 試験概要
他の人も書かれていますが、AWS色が薄く、純粋な機械学習の知識が必要な問題が多かったです。
所感として4割くらいがAWSと全く関係ない機械学習関連の問題でしたね。
機械学習関連の問題としてはディープラーニングのハイパーパラメーターチューニング、混同行列、TF-IDF、ベイズ統計、その他さまざまな機械学習の手法とかなり広く聞かれた印象でした。
AWS関連の話題としてはS3、Kinesis、EMR、Glue等を使ったデータエンジニアリングから、Sagemakerの運用方法、Rekognition, Comprehend等のAWSのAI関連のサービスについて問われることが多かったです。

# 勉強方法
## おススメの教材
 - [AWS Certified Machine Learning Specialty 2020 - Hands On!](https://www.udemy.com/course/aws-machine-learning/)  
    - 個人的にかなりおススメ
    - 試験範囲の大半の部分をカバーできるし、特にAWSのサービスで押さえておくべき部分がかなり網羅されている
    - 機械学習関連に関しても押さえておくべき手法やチューニング方法が解説されている（ただこれだけだと不足かも・・・）
    - フルプライスだと高くつくがセールで9割引してる時があるのでその時を狙って買うのが良いかも
    - 全て英語なので注意
 - [ゼロから作るDeep Learning ―Pythonで学ぶディープラーニングの理論と実装](https://www.amazon.co.jp/%E3%82%BC%E3%83%AD%E3%81%8B%E3%82%89%E4%BD%9C%E3%82%8BDeep-Learning-%E2%80%95Python%E3%81%A7%E5%AD%A6%E3%81%B6%E3%83%87%E3%82%A3%E3%83%BC%E3%83%97%E3%83%A9%E3%83%BC%E3%83%8B%E3%83%B3%E3%82%B0%E3%81%AE%E7%90%86%E8%AB%96%E3%81%A8%E5%AE%9F%E8%A3%85-%E6%96%8E%E8%97%A4-%E5%BA%B7%E6%AF%85/dp/4873117585)
    - 試験関係なく、ディープラーニングを学ぶ人には読んでおいてほしい本
    - 難しい数式を使うことなくディープラーニングについて解説してあるので、初学者にもとっ付きやすい
    - これを読破することで、試験にも頻繁に問われるディープラーニングのハイパーパラメータチューニングに対する一通りの知識が身につくはず
 - [Coursera Machine Learning](https://www.coursera.org/learn/machine-learning)
    - こちらも試験関係なく機械学習を学ぶ人には押さえておいてほしい教材
    - Couseraでもトップクラスに人気のあるコースで無料で受講可能
    - 様々な機械学習の手法を丁寧に解説されており、それぞれの手法のイメージをつかみやすい
    - 全て英語だが、日本語での字幕あり(たまに訳が怪しいのでそこは気をつけた方がいい)
 - [Black Belt](https://aws.amazon.com/jp/aws-jp-introduction/aws-jp-webinar-service-cut/)
    - やはりサービスの細かい仕様をつかむ際はこれ

## 実践
以下の記事を参考に実際にSagemakerを使ってモデル構築～学習～推論までの流れを自分で実装してみるとなお良いと思います。
 - [[チュートリアル] Amazon SageMakerでの学習・デプロイ](https://qiita.com/ku2482/items/af187b427d941dee7ca0)
 - [Amazon SageMakerで独自アルゴリズムを使ったトレーニング(学習)の作り方](https://qiita.com/shirakiya/items/b43c190958331c9825d3)
 - [AWS SageMakerでモデルのデプロイから推論（バッチ変換ジョブ）までを行う](https://qiita.com/kurakura0916/items/8abf19a64cda74f00a79)

## 押さえておきたいAWSのサービス
 - Amazon S3
 - Amazon Kinesis Data Streams
 - Amazon Kinesis Data Analytics
 - Amazon Kinesis Video Streams
 - AWS Glue
 - Amazon Athena
 - Amazon Quicksight
 - Amazon EMR
 - Amazon ECR
 - Amazon Comprehend
 - Amazon Translate
 - Amazon Transcribe
 - Amazon Polly
 - Amazon Rekognition
 - Amazon Forecast
 - Amazon Lex
 - Amazon Sagemaker
   
# まとめ
試験を通して改めて機械学習関連の勉強を行って、不明だった部分が明瞭になったり、AI関連のAWSのサービスに詳しくなったり良い経験になったと思います。
🎄クラウドのネットワークでハマった2020🎄

こんにちは。TIG/DXユニットの[伊藤太斉](https://twitter.com/kaedemalu)です。さて、ついにクリスマス当日です。お仕事をいただけるのは非常にありがたいことですね。素敵です。
さて、私はフューチャーでクラウドエンジニアとしてGCP、AWSを使ってインフラを構築しています。ベンダーごとに良いところ、悪いところが分かってきました。喜ばしいことです。毎日使い続けていると、その分ハマることも多く、毎日障子の上を歩いてい気持ちになります。さて、２０２０年仕事をしてきた中で、これは忘れたくない、ハマりどころを供養していきます。自分の強みでもある、

- AWS
- GCP

の両方をここではあげていきます。

# AWS
## ロードバランサーとターゲットグループの制御
AWSのロードバランサーはアプリケーション向けのALB、TCP、UDPプロトコルの利用向けのNLBと２種類存在します。各々、

- LBそのものの設定
- ターゲットグループの設定
- リスナーの設定

の３点を設定することで利用出来ます（もう少しいうと、ターゲットグループとLBの紐付けの設定もあります）。同一VPC内で利用する場合であれば特段気にせず使うことが出来ます。しかし、以下のような構成だとどうでしょうか？

![2020_advent_aws.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/382465/08dea622-d114-6c8d-8c19-37040db4818c.png)

このパターンはALBを置くサブネット、VPCまでをDMZとして扱って、コンピューティングリソースと徹底的に分けたい場合に使うアーキテクチャの一部です。また、Transit Gateway経由でVPC Aやってきたトラフィックは、さらにピアリングで接続されているVPC Bにトラフィックは流せません。したがってこの問題を解決するためにも利用されます。
さて、このアーキテクチャを利用する時に、ALBとターゲット先になるリソースを別のVPCで作成した場合に、ターゲットグループをどちらに置くか悩むポイントだと思います。ここでの正解は、**ALB側のVPCのリソースとして扱う**のが正解です。したがって、以下の配置になります。

![2020_advent_aws (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/382465/c514345d-e9c0-4fa0-60b0-fd4398a1d249.png)

私の中でのターゲットグループの解釈は、ロードバランサーのEgressを制御するファイアウォール相当のものなのではと思っています。なので、ターゲットグループがリソースとして紐づいているのはVPC単位になっているのはそういった挙動を裏でなされているのではと感じました。
注意点として、この設計ではターゲットグループの設定を、

- ID
- インスタンス
- IP

の３つから指定できますが、VPCを越す時にはIP指定のみが利用できます。ネットワークレベルの世界の話なので言われてみれば納得できます。便利すぎるといざという時、悩みますね。

# GCP
## ファイアウォールの制御について
各種コンピューティングリソースを保護するために、ファイアウォールは必須であり、適切な粒度で守ることが必須です。例えば、踏み台サーバーであっても、`0.0.0.0/0`で開けるなんてことをせずに、会社からの出口になっているGlobal IPだけを許可したり、Cloud IAP（Identity Aware Proxy）を利用するなどして、Ingressは極力絞るべきです。
本題に入りますが、GCPのファイアウォールは

- IP
- タグ
- サービスアカウント

の３つでソースを制御できます（ターゲットに指定できるのはタグとサービスアカウントのみ）。タグについては汎用性が高く、コンピューティングリソースを容易に保護できるようにしている機能なので私としてはとても好みの機能です。ですが、このうち、**タグとサービスアカウントでは、異なるVPC間の制御が効かない**ということが学びでした。今回も図で示します。以下のようなパターンです。

![Untitled Diagram.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/382465/e109d0b6-dcc3-f22c-1bf9-b3562308255e.png)

上の図でEgressは省いていますが、GCEの通信を制御するために同一VPC内、異なるVPC間にそれぞれファイアウォールがあります。このときVPC Aの踏み台からVPC Bのインスタンスにsshしようとすると弾かれます。念のため、検証として、Network Intelligence CenterのConectivity Testを利用してみましょう。ソースを踏み台サーバー、ターゲットをVPC Bのインスタンスとして設定してテストしてみました。結果はこちら、VPC Bのファイアウォールがうまく効いていないことが分かります。

![スクリーンショット 2020-12-25 7.57.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/382465/6382fa92-9beb-ed1b-b511-1028ab65d9a1.png)

きちんとファイアウォールを作用せるために、VPC Bのルールをタグから踏み台の制御に変えてみます。

![スクリーンショット 2020-12-25 8.02.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/382465/f1a8fe82-2c6a-0319-573a-8ec59b41afb3.png)

このように、VPC Bのファイアウォールルールが適用されてリーチャビリティが確率されました。実際に踏み台からpingを叩いてもレスポンス返ってきます。
Connectivity Test自体はルールを確認してリーチャビリティがあるか否かを見ているので、実際にはドライランです。

## まとめ
クラウドの世界でネットワークの諸々を制御するときは各クラウドごとに便利な機能が実装されており、事故防止のためにも理解を深めて、最大限利用するべきだと思っています。しかし、自分が今いるネットワークの世界から別の世界にいくとき、結局のところIP制御が原始的ながらそれ以上のことはまだ出来ないのだな、というのが今年の感想です。
便利なものはどんどん使う、でも裏の挙動に仮説をもったり、そもそもの原理原則自体に目を向けないといけないと改めて思いました。

🎄🎄🎄🎄🎄みなさん、素敵なクリスマスをお過ごしください。🎄🎄🎄🎄🎄
vuetify-loader1.6にアップデートしてビルドできなくなった場合の対処法

LaravelMixを使ってビルドしている場合にvuetify-loaderをバージョンアップすると下記のようなエラーが出てビルドできなくなった。

```
Error: [VueLoaderPlugin Error] vue-loader 15 currently does not support vue rules with oneOf. at VueLoaderPlugin.apply
```
どうやらvue-loaderとvuetify-loaderの読み込み順があべこべになっているため発生しているようで、vuetify-loaderの読み込み方を変更する必要があるみたい。
# Before
```js:wepack.mix.js
mix.webpackConfig({
//~中略
  plugins: [
    new VuetifyLoaderPlugin(),
  ],
//~中略
})
```

#After
https://github.com/vuetifyjs/vuetify-loader/issues/144#issuecomment-659308887

```js:wepack.mix.js
mix.webpackConfig({
  plugins: [
    //ここで読み込まない
  ],
})
//ここで追って読み込む
mix.extend('vuetify', new class {
  webpackConfig (config) {
    config.plugins.push(new VuetifyLoaderPlugin())
  }
})
mix.vuetify()
```
Python pandasでExcel集計 その1

##モチベーション
Excelの情報を集計するのにシートに計算式かちゃかちゃいれると動き遅くなる。Python+Excel関連の本を本屋で見かけるようになってきたし、勉強しておこう。

##環境
windows10
python3.9
VS Code
Pandas
openpyxl

##準備
python、pandasのinstall(pip使ってね)は済んでる前提

##お題
こういうExcelがある。
特徴としては部署の列がシートによって異なる。(黄色の列です)
部署毎の人数を集計したい。

| sheet1 | sheet2 | sheet3 |
|:-:|:-:|:-:|
|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29032/64385743-d61d-f636-3d47-25177fa99849.png)| ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29032/dcb64e6f-3a01-428b-83d2-cdf5bbb26a6a.png) | ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29032/88297618-348e-1db6-a7e3-7a4dcfd2c6a5.png) |


## 早速答え

#### pandas_lib.pyで2関数定義
* countByKeyFromFileAndSheet:key列を集計する関数：pandas関数のvalue_counts()を使って集計し、to_dict()でdict型に変換します。
* concatenateDict:dictを2つ繋げる関数

``` pandas_lib.py
import pandas as pd # pandasは、Pythonにおいて、データ解析を支援する機能を提供するライブラリ
import numpy as np

# keyでGroupingしてカウント
def countByKeyFromFileAndSheet(filename, sheetname, key):
  df = pd.read_excel(filename, sheet_name=sheetname, engine="openpyxl")
  dict = df[key].value_counts().to_dict()
  print(dict)
  return dict

def concatenateDict(dict1, dict2):
  newdict=dict1
  for k in dict2:
    if k in newdict:
      newdict[k] += dict2[k]
    else:
      #newdict.update(k, dict2[k])
      newdict[k] = dict2[k]
  return newdict
```

#### pandas_main.py
countByKeyFromFileAndSheetでSheet1～3の部署名の列を集計し、dictに格納しておき、concatenateDictでdictを繋ぎdictを生成する。

``` pandas_main.py
import pandas_lib as pl

dict1 = pl.countByKeyFromFileAndSheet("./example.xlsx", "Sheet1", "部署")
dict2 = pl.countByKeyFromFileAndSheet("./example.xlsx", "Sheet2", "部署")
dict3 = pl.countByKeyFromFileAndSheet("./example.xlsx", "Sheet3", "部署")

dict = pl.concatenateDict(dict1, dict2)
dict = pl.concatenateDict(dict, dict3)

print(dict)
```

### 実行結果
dict1-3に集計後、最終的に3シート合計の集計ができていることが分かります。

```
{'営業部': 4, '開発部': 3, '総務部': 3}
{'営業部': 5, '開発部': 3, '経理部': 2}
{'開発部': 9, '経理部': 1}
{'営業部': 9, '開発部': 15, '総務部': 3, '経理部': 3}
```

### 最後に

concatenateDictの中for文使って泥臭く実装しましたが、他にもっとスマートな実装方法あったら、教えて頂きたいです。
【Nuxt】headに記述したJavaScriptが2回実行されてハマった話【SPA】



#症状
nuxt.config.jsに下記の設定をする

```js:nuxt.config.js
    mode: 'spa',
    head: {
        script: [
            {
                innerHTML: `(function(){console.log('HelloWorld!')}());`
            }],
        __dangerouslyDisableSanitizers: ['script'],
    },
```

起動してみる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569808/f552eb71-09b3-e8ef-468d-78064ed88cee.png)

なぜか`HelloWorld!`が2回出力される。

# 2回呼ばれる原因
1. ビルドされたhtmlに記載されてるScriptタグが読み込まれる(**1回目の出力**)
2. Scriptタグの比較を行われる  
「htmlに記載されてるScriptタグ」と「nuxt.config.jsに定義されているScriptタグ」 で比較され、差異があった場合にScriptタグが再配置される。  
この時に「nuxt.config.jsに定義されているScriptタグ」がフォーマットが書けられた状態の内容で比較される為、差分があったと見なされ、タグが再配置される

```js:htmlに記載されてるScriptタグ
(function(){console.log('HelloWorld!')}());
```

```js:比較に使用されるフォーマットされたScriptタグ
(function (){console.log('HelloWorld!')}());
```
3. 再配置されたScriptタグが読み込まれる。(**2回目の出力**)

# 対策
再配置されたScriptタグの内容をコピーし、nuxt.config.jsの内容を置き換える

```js:nuxt.config.js
    mode: 'spa',
    head: {
        script: [
            {
                innerHTML: `(function(){console.log('HelloWorld!')}());`
            }],
        __dangerouslyDisableSanitizers: ['script'],
    },
```