OmniAICreator/Qiita-1.07M huggingface dataset:
Nuxt.jsをVue.jsに解体するTips(Plugin編)

# 背景

- Nuxt.jsで動いているSPAアプリをVue.jsに解体してほしい的な話があり、部分部分をTipsとして投稿します。
- APIはLaravel(6.x)です。なおLaravelとNuxt.jsは同一リポジトリです(なぜ)
- Nuxt.jsは2.9。Vueは2.6.10
- 今回はPlugin編です。

## Nuxt.jsでコンテキストに注入している場合

### Nuxt.jsの書き方の例

[Nuxt.js公式ドキュメント](https://ja.nuxtjs.org/guide/plugins/)より抜粋

```plugins/combined-inject.js
export default ({ app }, inject) => {
  inject('myInjectedFunction', string => console.log('That was easy!', string))
}
```

### Vue.jsでの解体例

- Vue.prototypeで[インスタンスプロパティを追加](https://jp.vuejs.org/v2/cookbook/adding-instance-properties.html)。

```resources/js/combined-inject.js
const MyInjectedPlugin = {}
MyInjectedPlugin.install = function (Vue) {
  Vue.prototype.$myInjectedFunction = string => console.log('That was easy!', string)
}
export default MyInjectedPlugin;
```

```resources/js/app.js
import Vue from "vue";
import router from '~/router'
import App from '~/App.vue'

import MyInjectedPlugin from '~/plugin/combined-inject'

import DefaultLayout from '~/layouts/default'
import NoAuthLayout from '~/layouts/noauth'

Vue.use(MyInjectedPlugin) //Vue.useでpluginを追加

Vue.component('default-layout', DefaultLayout)
Vue.component('noauth-layout', NoAuthLayout)

new Vue({
  router: router,
  render: h => h(App),
}).$mount('#app')
```

## PluginからVue Routerを使いたい場合

### 導入例

```resources/js/app.js
import Vue from "vue";
import router from '~/router'
import App from '~/App.vue'

import RouterPlugin from '~/plugin/router-plugin'

import DefaultLayout from '~/layouts/default'
import NoAuthLayout from '~/layouts/noauth'

Vue.use(RouterPlugin, router) // Vue.useの引数にrouterを渡す

Vue.component('default-layout', DefaultLayout)
Vue.component('noauth-layout', NoAuthLayout)

new Vue({
  router: router,
  render: h => h(App),
}).$mount('#app')
```

```resources/js/plugin/router-plugin.js
const RouterPlugin = {}
RouterPlugin.install = function (Vue, router) {
  Vue.prototype.$hoge = () => {
    router.push("/")
  }
}
export default RouterPlugin;
```

## PluginからVuexを使いたい場合

```resources/js/app.js
import Vue from "vue";
import router from '~/router'
import App from '~/App.vue'

import StorePlugin from '~/plugin/store-plugin'
import store from '~/store/store' // Vuexを定義しているモジュールをimportする

Vue.use(StorePlugin, store) // Vue.useの引数にstoreを渡す

Vue.component('default-layout', DefaultLayout)
Vue.component('noauth-layout', NoAuthLayout)

new Vue({
  store
  router: router,
  render: h => h(App),
}).$mount('#app')
```

```resources/js/plugin/store-plugin.js
const StorePlugin = {}
StorePlugin.install = function (Vue, store) {
  Vue.prototype.$fuga = () => {
    store.dispatch('~~')
  }
}
export default StorePlugin;
```

## 参考

- [Nuxt.js公式ドキュメント](https://ja.nuxtjs.org/guide/plugins/)
- [Vue.js公式ドキュメント](https://jp.vuejs.org/v2/cookbook/adding-instance-properties.html)

## 関連リンク

- [Nuxt.jsをVue.jsに解体するTips(JavaScriptコンパイル編)](https://qiita.com/ProjectEuropa/items/824eb8e0902ee8d93178)
- [Nuxt.jsをVue.jsに解体するTips(Layout編)](https://qiita.com/ProjectEuropa/items/467f043b5ddf1f6c4cdb)
人のPull Requestを見るのを少しでも楽にする

## 概要

ターミナルでgit操作している場合、PRレビューお願いしますと言われ、やらなきゃいけないのは山々だけど今から見るのは作業中ファイルもあるし、面倒だなぁということがあります。

そんな問題を解決できる方法を考えてみました。


## PRレビューデバッグまで

まず、共通作業であるGithubでPRを見てブランチをコピペするところから始まります。

### 作業中ディレクトリでブランチを切り替えて見るケース

- git stash
- git fetch
- git checkout ブランチ名
- yarn dev

いいところ
- ディレクトリをひとつにできる
- 頻繁に更新されているのでpullやfetchがあまり必要ない

つらみ一覧
- 現在の作業を保存してブランチを変えるのがだるい


### そもそもレビュー用ディレクトリを分けて見るケース

test-projectというリポジトリの場合、test-project-reviewのようにわかりやすいディレクトリを切り管理する
もしくは、作業ディレクトリのgitignoreでignoreしてディレクトリごと入れる？

いいところ
- 現在の作業が干渉しない

つらみ一覧
- pull, fetchがだるい
- エディタをもう1個開くのが面倒(ターミナルなら楽な気もする)


### 作業中ディレクトリで見る場合の便利なスクリプト

.zshrcなりにコピペしてsourceすれば使えるようになる
branchdebugの略です
`bd fix/pages/remove-unused-variable` のような感じで実行すると

- このブランチに移動したときのファイルだよという名前付きgit stashを行う
- git fetch
- git checkout
- yarn dev

を一連のセットで行います。

なんか間に処理入れたい人は自分でカスタマイズしてください。

```shell
 function bd () { git stash save -u "some files when checkout $@ branch" && git fetch && git checkout $@ && yarn dev  }     
```

## 感想

githubで任意のブランチ名のローカルホスト上げられたらなぁ〜〜〜〜〜〜〜


レビュー終わった後に作業用ブランチに戻る用コマンドもあったら楽そう。
- git checkout
- git stash apply

のセットで。
gormでcsvをdatabaseに入れる

仕事で今だにexcelファイルを何枚も用意して管理をしているデータがあったので
管理システム作ることにしました。
その際に現状のデータをcsvに変えてgoでデータベースへぶち込んだ際の備忘録兼個人メモです。
至らぬところばかりですが、ご了承ください。

gormを用いてmysqlに入れてます

```
go get -u github.com/jinzhu/gorm
```

```sample.csv
佐藤,24,神奈川
向井,19,香川
田中,44,長野
```

tree

```
csv_to_db
├── db_connect
│   └── db_connect.go
├── sample.csv
└── main.go
```

```db_connect.go
package database_connect

import (
	"github.com/jinzhu/gorm"
	_ "github.com/jinzhu/gorm/dialects/mysql"
)

func GormConnect() *gorm.DB {
	DBMS := "mysql"
	USER := "root"
	PASS := "You Pass"
	PROTOCOL := "tcp(0.0.0.0:3306)"
	DBNAME := "DB name"

	CONNECT := USER + ":" + PASS + "@" + PROTOCOL + "/" + DBNAME
	db, err := gorm.Open(DBMS, CONNECT)

	if err != nil {
		panic(err.Error())
	}
	return db
}
```

```main.go
package main

import (
	"encoding/csv"
	"fmt"
	"github.com/jinzhu/gorm"
	"github.com/sudyusuk/csv_to_db/db_connect"
	"os"
	"strconv"
)

type Databases struct {
	UserDatabase *gorm.DB
}

//データベース側は複数系じゃないといけない　e.g.:table_names
type TableName struct {
	Name      string    `gorm:"column:name"`
	Age       int       `gorm:"column:age"`
	Address   string    `gorm:"column:address"`
}

func main() {

	user_db := database_connect.GormConnect
	databases := Databases{user_db()}

	if err := databases.readJson("./sample.csv");err != nil {
		fmt.Println(err)
	}

}

func (d *Databases) readJson(path string) error {

	csvFile, err := os.Open(path)
	if err != nil {
		return err
	}
	defer csvFile.Close()

	reader := csv.NewReader(csvFile)
	reader.FieldsPerRecord = -1

	csvData, err := reader.ReadAll()
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	for _, data := range csvData {
		age ,_ := strconv.Atoi(data[1])
       //intに変換

		oneLine := CreateOneLine(data[0],age,data[2])
		d.CreateDatabase(*oneLine)
	}
	return nil
}

//ここ作らなくてもいいけど、分かりやすく見やすいから。
//レコードを作る
func CreateOneLine(name string,age int ,address string) *TableName {
	return &TableName{name,age,address}
}

//保存
func (d *Databases) CreateDatabase(oneLine TableName) {
	d.UserDatabase.Create(&oneLine)
}
```

以上です。。
陳腐なコードですので気になるところばかりだと思いますが、その際はご教授いただけると嬉しいです。
goは楽しい
Community EditionからIQ Botへの入り口

[Automation Anywhere のコミュニティ版](https://qiita.com/IQ_Bocchi/items/63cc4ec70d1c73a8b280)ではIQ Botが利用可能なんですが、そもそもIQ Botの入り口を探せずにつまづいています！　という意見をちらほら聞いたので紹介しておきます。

■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
2021/8/23 現在 Community Editionの IQ Bot では帳票言語で日本語が選択できなくなっています。
■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■


#ズバリ、ここです！

![CEの入り口.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/2245f408-772b-db4d-f698-4ac6933be9ea.jpeg)

最新版(2021年1月時点)では、画面左側に「IQ Bot」というタブが表示されています。
ここをクリックしても同じ画面に行きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/640d1dd4-a6f8-76f9-1738-a9ca6908c459.png)

製品版を知っている方は、この画面にちょっとびっくりするかもしれません。
というのは、上記の画面は製品版とは違う画面だからです。

このまま素直に右上の紺のボタン「Create Learning Instance」を押すと、次世代エンジン用のインスタンス作成画面が起動してしまい、日本語の帳票の設定ができません。（次世代エンジンについては、後日記事を書こうと思います）

日本語の帳票の設定を行う場合は、その下の白いボタン「Train other documents」をクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/33a84be1-14c0-a1fa-01fb-f9a45407226c.png)

すると、こんな画面が出てきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/a20b5107-4421-1606-c3b8-8faff6f2bff3.png)

画面右上の地球のマークをクリックすると、言語を日本語にできます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/d1670f25-c670-f1d7-807b-31945c813b88.png)

#ここまでたどり着けたら……

あとは、[こちら](https://qiita.com/IQ_Bocchi/items/26c4a7065e4c8e64a427)のページを参考にIQ Botを作ってみましょう！
Rubocopの実行が遅い時に見直すべきポイント

Rubocopの実行で遅くて困っている方は除外ディレクトリに`.git/**/*`を真っ先に含めましょう。爆速になります。
バージョンは 0.83.0です。

```
AllCops:
  Exclude:
    - vendor/bundle/**/*
    - bin/*
    - db/**/*
    - config/**/*
    - lib/*
    - Gemfile
    - public/**/*
    - tmp/**/*
    - log/**/*
    - .git/**/*
```

私の環境では2分近くかかっていたのが6秒で終わるようになりました。これで頻繁に実行できます。
役に立てば幸いです。
【AWS】EIP、パブリックIPアドレス、プライベートIPの違いとは？

# はじめに
現在、AWSソリューションアーキテクトアソシエイトの資格について勉強をしています。
今回は、EIP/パブリックIPアドレス/プライベートIPの違いについて学んだのでアウトプットしていきたいと思います。

# EIP/パブリックIPアドレス/プライベートIPとは？

## EIP

**「Elastic IP Address」**の略になります。
**AWSアカウントに紐づけられた静的なグローバルIPアドレスです。**

**特徴**

- 再起動してもIPアドレスが維持される
- 利用していない場合に課金される


**課金されるパターン**

- EIPがEC2に関連付けられているが、EC2が停止している場合
- EIPが付与されているが、どこにも関連付けられていない場合
- 稼働しているEC2に2つ目のEIPを関連付ける場合


## パブリックIPアドレス

**インスタンス起動時に自動的に割り当てられる動的なグローバルIPアドレスです。**

**特徴**

- ランダムに割り当てられるためIPアドレスを指定できない
- インスタンスを再起動すると別のIPアドレスが割り当てられる
- IPアドレスを自動で割り当てないことも可能
- インスタンス内では確認できない。(プライベートIPアドレスのみ)



## プライベートIPアドレス

**インスタンス作成時に割り当てられる静的なIPアドレスです。**
内部ネットワーク内で割り当てられたIPアドレスですね。

**特徴**

- インスタンス作成時に必ず割り当てられる
- インスタンス作成時にIPアドレスを指定できる
- 再起動しても同じIPアドレスが割り当てられる
- 内部ネットワーク内のIPアドレス


# EIP/パブリックIPアドレス/プライベートIPの違い

| IPの種類 | 静的/動的 | 内部/外部|端末からの接続|IP割り当て|
| :--- | :---: | ---: |:---: | ---: |---: |
| EIP 　| 静的 | 外部 | OK | 自動 |
| パブリックIPアドレス 　　　　　| 動的 | 外部 | OK | 自動 |
| プライベートIPアドレス 　　　　| 静的 | 内部 | NG | 自動/手動  |

**静的と動的の違い**

| 種類 | 内容 | 
| :--- | :---: |
| 静的(Static) 　| 固定のIPアドレス。再起動しても変更されない。 |
| 動的(dynamic)　| 暫定的に割り当てられているIPアドレス。再起動したら変更される。 |

## 実際に「Amazon Linux」で作成したEC2にWindows端末から接続

**・EIP**

サーバー内ではEIPの確認は不可。

![EIP.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/636476/b2e76195-f1e2-cdda-977c-5686a8b1ab22.jpeg)

**・パブリックIPアドレス**

サーバー内ではパブリックIPアドレスの確認は不可。
![1.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/636476/fc9379ce-3063-aba1-eb0e-2ddc5fe8faba.jpeg)

**・プライベートIPアドレス**

端末からのSSHは不可。赤枠の部分がプライベートIPアドレス。
![プライベートIPアドレス.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/636476/d2b85f7d-2f0e-6dc2-31e0-e0941f71d93b.jpeg)



# 参考

[この１冊で合格！　AWS認定ソリューションアーキテクト - アソシエイト テキスト&問題集 Kindle版](https://www.amazon.co.jp/gp/product/B07VFFX6V1/ref=ppx_yo_dt_b_d_asin_title_o00?ie=UTF8&psc=1)


[EC2 における Public IP と Elastic IPの違いに関して](https://awsjp.com/AWS/hikaku/Elastic-IP_Public-IP-hikaku.html)
python-ffmpegでmp4動画のトリミングをする

# やりたいこと
mp4形式の動画の特定領域を切り出したい。

# 手段
pythonのffmpegライブラリを使用した。

# コード
入力ファイルパス、トリミング領域を指定すると入力ファイルと同じ階層にトリミングされたファイルが生成される。

```python:trimming.py
import ffmpeg

def video_trimming(input_file_path, start_x, start_y, w, h):
    """
    input_file_path # ファイルの絶対パス
    start_x = 850  # 切り取りたい区画のx座標（px）
    start_y = 500  # 切り取りたい区画のy座標（px）
    width = 700  # 切り取りたい区画の幅（px）
    height = 580  # 切り取りたい区画の高さ（px）
    """

    # トリミングファイル・パラメータ指定
    stream = ffmpeg.input(input_file_path)
    stream = ffmpeg.crop(stream, start_x, start_y, w, h)

    # 出力ファイル名生成
    output_file_str = input_file_path.split(".")
    output_file_name = output_file_str[0] + "_trimed." + output_file_str[1]
    stream = ffmpeg.output(stream, output_file_name)

    # 実行(ファイルがあると上書き)
    ffmpeg.run(stream, overwrite_output=True)

    return
```
Vim [検索, 置換]

# 参考にした文献,サイト
今回の記事は以下の文献を参考にして記述しています。

- 新しいLinuxの教科書(https://www.amazon.co.jp/dp/B072K1NH76/ref=dp-kindle-redirect?_encoding=UTF8&btkr=1)
- vimtutor
- もためも(Vim:確認しながら置換する方法)(https://motamemo.com/vim/vim-tips/replace-confirm/)

#　検索

| コマンド | 内容 |  
|:------:|:-------:|  
| /<文字列> | 上から順に<文字列>を検索 |  
| ?<文字列> | したから順に<文字列>を検索 |  
| n | 次の検索結果に移動 |  
| N | 前の検索結果に移動 |

#### 上から検索
#####書式
```
/<検索したい文字列>
```

##### 例
![top_search.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256678/8d66f2f3-ade3-3b85-95ae-51b32cf825f2.gif)


#### 下から検索
##### 書式

```
?<検索したい文字列>
```

##### 例
![bottom_search.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256678/ef84f84b-87a6-1aa4-71bf-ac15a6efcfd1.gif)



#### 次の検索結果へ移動
##### コマンド
`/<文字列>` または、`?<文字列>`を行った後に次のコマンドを入力する

```
n
```
##### 例

![next_search.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256678/2555bf30-529e-6dc7-c003-3043102254f5.gif)

#### 前の検索結果へ移動
##### コマンド
`/<文字列>` または、`?<文字列>`を行った後に次のコマンドを入力する

```
N
# shift + n
```
##### 例
![prev_search.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256678/0c546533-8267-eea1-c0b1-04a1b5c7bedf.gif)

# 置換
##　1行内での置換
#### はじめに見つかったものを置換
##### 書式
```
:s/<置換前>/<置換後>/
```
##### 例
![replace.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256678/a98a8ba0-c109-0320-f031-53df4893c3e3.gif)



#### 全て置換
##### 書式
```
:s/<置換前>/<置換後>/g
```

##### 例
![replace_g.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256678/d075d80b-c795-9334-154b-7dfd943adf79.gif)
## 複数行で置換
#### 置換する行を指定して範囲内を全て置換
##### 書式
```
:<開始行番号>,<終了行番号>s/<置換前>/置換後/g
```
##### 例
![replace_s_e_g.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256678/6f752fff-1f52-5ca6-f8d5-52c6c224d916.gif)

#### ファイル全体で置換
##### 書式
```
:%s/<置換前>/<置換後>/g
```
##### 例
![replace_g_all.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256678/e99406f9-c1fb-8a30-0565-5cc9e1e7679d.gif)


#### ファイル全体で確認をしながら置換
##### 書式
```
:%s/<置換前>/<置換後>/gc
```
##### [vim]置換時のコマンド
| コマンド | 内容 |  
|:------:|:-------:|  
| y | 現在のマッチを置換する |  
| n | 現在のマッチを置換しない |  
| l | 現在のマッチを置換して置換終了 |  
| \<Esc\> | 置換終了 |
| a | 現在のマッチと、それ以降の結果を全て置換する |
| q | 置換を終了する |
| ^E (ctrl + e) | 画面を上にスクロール |
| ^Y (ctrl + y) | 画面を下にスクロール |


##### 例
![replace_y_n.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256678/c36f78ca-d441-995e-d36b-1e1dc59ef9e4.gif)
VercelでLINE BOTを動かす 2020年5月版


よく使う記事(↓)のソースコードを元にVercel（旧: now.sh）にLINE BOTをデプロイします。

> https://qiita.com/n0bisuke/items/ceaa09ef8898bee8369d

ちなみに、Vercelはnow時代から仕様がちょくちょく変わる印象があるのであくまでも現時点版だと思った方が良さそうです。

## 事前準備: LINE BOTを作成し、ngrokで動作確認

参考記事のSTEP3のngrokでトンネリングさせるところまで進めます。

> 参考: [1時間でLINE BOTを作るハンズオン (資料+レポート)](https://qiita.com/n0bisuke/items/ceaa09ef8898bee8369d)

> <img src="https://qiita-user-contents.imgix.net/https%3A%2F%2Fi.gyazo.com%2Fabaf8f06efea5d9b3840c4aa1c8b1932.png?ixlib=rb-1.2.2&auto=format&gif-q=60&q=75&w=1400&fit=max&s=62e5da3b3631ab1c6e67e65464eee20c"  width="300px">

## 1. Vercelコマンドのインストール

```
$ npm i -g vercel
```

既にインストールしている人はこの手順はスキップしましょう。

> 参考: [爆速！Vercelとfreenomで独自ドメインのサイトを無料で作成する](https://qiita.com/n0bisuke/items/901154531ea14f978bd4)


## 2. プロジェクトのファイル微修正

Vercelにデプロイするにあたりちょっとした修正を3箇所行います

### 2-1. server.jsをapiフォルダへ

プロジェクトのルート（package.jsonがある階層）に`api`という名前でフォルダを作成します。

`api`フォルダ内に、もともLINE BOTで作成した`server.js`を移動させます。

> <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35387/e1f2f547-2a76-99aa-309a-6ef971932bbb.png" width="200px">

Vercel上ではapiフォルダ内に置いたプログラム(`.js` or `.ts`)をNode.jsで実行する模様です。

### 2-2. vercel.jsonを作成

プロジェクトのルート（package.jsonがある階層）に`vercel.json`という名前でファイルを作成します。

```vercel.json
{
    "version": 2,
    "routes": [
        { "src": "/", "dest": "api/server.js" },
        { "src": "/webhook", "dest": "api/server.js" }
    ]
}
```

### 2-3. server.jsを更新

`server.js`の末尾を以下に変更します。

```server.js
・
・
(省略)
・
・

// app.listen(PORT);
// console.log(`Server running at ${PORT}`);
(process.env.NOW_REGION) ? module.exports = app : app.listen(PORT);
console.log(`Server running at ${PORT}`);
```

## 3. デプロイ

あとはプロジェクトのルートでvercelコマンドを実行するだけです。デプロイ時に対話式に質問が来ますが全てエンターで進めます。

> Vercelの利用が初めての場合のみログイン認証があります。

```
$ vercel
```

デプロイが成功すると`https://<アプリ名>.now.sh`というURLが発行されます。

この時点で、このURLにブラウザでアクセスし、`Hello LINE BOT!(GET)`の文字が表示されれば問題なくデプロイできています。

## 4. LINE Developersの管理画面でWebhook URLを更新

LINE DevelopersのWebhook設定の管理画面から`https://<アプリ名>.now.sh/webhook`というURLを設定します。

> ![](https://i.gyazo.com/1dae13be77656f0a708073d424500540.png)

これで完成となります。

## 更新する際

デプロイし直す場合はvercelコマンドだけでデプロイ可能です。

```
$ vercel
```

ローカルでngrokで試す際はapiフォルダにserver.jsを移動させてあるので

```
$ node api/server.js
```

という実行の仕方に変えましょう。

## 所感 now時代と違うところなど

割と軽微な変更でデプロイできました。一回感覚を掴むと問題ないですが、初見だとちょっと戸惑う人いるかもなぁという印象です。

vercel.jsonは基本的にはnow.jsonと同じような書き方でしたが、buldsが非推奨っぽくなってたり、apiフォルダに入れると認識されるなど微妙に変わってるところがありうまく行くまでなんどかやり直しが発生しました。

今回はもともとローカル起動させるnode.jsプログラムの記述をあまり変えずにVercelにデプロイするやり方ですが、Vercelのドキュメント的にはapiフォルダにhoge.jsを設置すると `/api/hoge`という形で[アクセスできるようになるみたい](https://vercel.com/docs/runtimes#official-runtimes/node-js)ですね。

詳細は[この辺](https://vercel.com/docs/configuration#introduction/configuration-reference)を見ると良さそうです。
MDN Web Docs を初心者目線で読んでみる

>強いエンジニア言いて曰く、ルークよ、Codeを読め、Issueを読め、公式Docを読め。

Webエンジニアになりたい人です。はじめまして、こんにちは。周りの強いエンジニアの皆様は、コードを読めと宣うのですが、初心者からしたらコードが読めないから初心者なんだよ、ばっきゃろーだし、そもそもIssueってなんだよ、それが問題だし、わからんし、公式Docって？？DocってDocument、文章ね、と言うか公式とか非公式とかあるんすか？よくわかんなーいですよね。

今回はWeb技術を学ぶために[MDN Web Doc](https://developer.mozilla.org/ja/) を初心者目線で眺めていきたいと思います。

## 開発者による開発者のためのリソース

なんかタイトルがカッコいい。トップメニューに「ウェブ技術」「ウェブ開発について学ぶ」「開発者ツール」とあります。

さっそく、Webエンジニアになりたい人なので、「ウェブ開発について学ぶ」の項目をみていくことにします。

## ウェブ開発を学ぶ

まず目標が明示されています。

>ウェブ開発が全くの初心者にとって、シンプルなウェブサイトのコーディングを始めるのに必要な全てを提供すること

浮かんだ疑問としては、シンプルなウェブサイトって、どうシンプルなの？シンプルじゃないウェブサイトがあるの？ウェブサイトって所謂ホームページのことなの？コーディングってなに？プログラミングとは違うの？

あくまでここの学習リソースでは、初心者から中級程度までの支援のようなので、そこからは別のことを学んでいく必要もあるようです。

とは言え、とりあえず出発地点はここで良いようです。
Flutterでアプリアイコンを設定する

## 画像の用意
今回は[AndroidAssetStudio](https://romannurik.github.io/AndroidAssetStudio/index.html)で作成
## 画像の設置
`assets/images/[アイコンのファイル名]`に画像を設置する・

設置するファイルは以下ディレクトリのもの（別にどれでもいい）
`ic_launcher/res/mipmap-hdpi/ic_launcher.png`

## flutter_launcher_iconsのインストールするために記述
ライブラリをインストールするので、pubspec.yamlに記述した。
バージョンは[公式](https://pub.dev/packages/flutter_launcher_icons#-installing-tab-)で確認してね。

```pubspec.yaml
dependencies:
  flutter:
    sdk: flutter``
  flutter_launcher_icons: ^0.7.5 #追加
```

## flutter_launcher_iconsの設定

```pubspec.yaml
dependencies:
  flutter:
    sdk: flutter
  flutter_launcher_icons: ^0.7.5 #追加
dev_dependencies:
  flutter_test:
    sdk: flutter

# 追加
flutter_icons:
  android: "launcher_icon"
  ios: true
  image_path: "assets/images/ic_launcher.png"
  adaptive_icon_background: "#212121"
  adaptive_icon_foreground: "assets/images/ic_launcher.png"
```

## flutter_launcher_iconsをインストールして、実行する

```zsh
flutter pub get
flutter pub run flutter_launcher_icons:main
```

これでおしまい。
【Laravel】キャッシュをクリアするコマンド一覧

#はじめに
開発をしている中でコードの変更が反映されないことがあります。
初学者なら、なんで変更が反映されないの？？ってなりますし、経験を積んだ今でもキャッシュクリアのコマンドを調べてるので一覧にまとめたいと思います。

#キャッシュクリアするコマンド一覧

###キャッシュクリア
コード変更したのに反映されない場合は、とりあえずこのコマンドを実行しろ的な基本コマンド

```
$ php artisan cache:clear
```

###ルートキャッシュ
web.phpファイルなどでルートを変更したのに反映されないって時はルートキャッシュを使えば上手くいくはずです。

```
$ php artisan route:cache
```

###configキャッシュクリア
envファイルを変更したらconfigキャッシュをクリアしてあげないと反映されないことが多いです。

```
$ php artisan config:cache
```

###viewキャッシュクリア
bladeファイルやvueファイルを編集したのに反映されない時はviewキャッシュをクリアします。

```
$ php artisan view:cache
```

###Seederファイルを作った時
Seederでダミーデータを作成した場合、```php artisan db:seed```コマンドを実行する前に下記を実行します。

```
$ composer dump-autoload
```

開発中にわりと実行するコマンドはだいたいこんなもんかなって思います。
rails CSV.open とCSV.generateの使う場面の違い CSV

## CSV.open とCSV.generateの使う場面の違い


- csvの使い方を調べると、`CSV.open` が多い
- 会社の実装を見てみると`CSV.generate`が多い気がする


## なぜ場面によって違うのか？

csvの出力先を【ディレクトリ配下に置く】のか。【export】するのか（railsで）によって異なるのかな。


```ruby
## CSV.open
### これはopenの第一引数の指定先（output.csv）に出力する事を想定している
### 実行 すると同じディレクトリ配下に ls csv_ruby.rb output.csvみたいになる

csv_ruby.rb # ファイル名

lists = [["1","2","3"],["4","5","6"]]

CSV.open("./output.csv", "w") do |row|
  lists.each do
    row << list 
  end
end

## CSV.generate


lists = [["1","2","3"],["4","5","6"]]

csvs = CSV.generate do |row|
  lists.each do |list|
    row << list 
  end
end

## これは出力結果を なにかしらの変数に入れて中身を確認する必要がある

## 最終的にsenddataの引数に渡してダウンロードする

def index
 format.csv do
   sendata(csvs, type: :csv, failename: "ファイル名")
 end
end
```

## まとめ

こんな感じで、最終的な期待結果に応じて、csvの作り方が異なる
Dockerビルドで git cloneで証明書エラーが発生するときの対応

# DockerでPHPの環境作っていたらエラーに遭遇

```bash
Using version ^3.1 for laravel/installer
./composer.json has been created
Loading composer repositories with package information
Updating dependencies (including require-dev)
Package operations: 16 installs, 0 updates, 0 removals
  - Installing symfony/process (v5.0.8): Downloading (failed)       
Downloading (failed)       
Downloading (failed)    Failed to download symfony/process from dist: The "https://api.github.com/repos/symfony/process/zipball/3179f68dff5bad14d38c4114a1dab98030801fd7" file could not be downloaded: SSL operation failed with code 1. OpenSSL Error messages:
error:1416F086:SSL routines:tls_process_server_certificate:certificate verify failed
Failed to enable crypto
failed to open stream: operation failed
    Now trying to download from source
  - Installing symfony/process (v5.0.8): Cloning 3179f68dff


Installation failed, deleting ./composer.json.

                                                                                                                                           
  [RuntimeException]                                                                                                                       
  Failed to clone https://github.com/symfony/process.git via https, ssh protocols, aborting.                                               
                                                                                                                                           
  - https://github.com/symfony/process.git                                                                                                 
    Cloning into '/composer/vendor/symfony/process'...                                                                                     
    fatal: unable to access 'https://github.com/symfony/process.git/': server certificate verification failed. CAfile: none CRLfile: none  
```

どうやら、以下でソースをgitからcloneしてくる処理でコケたらしい。
`composer global require "laravel/installer"`

## 対策

DockerfileのRUNコマンドに`export GIT_SSL_NO_VERIFY=1`を追記

```dockerfile
RUN export GIT_SSL_NO_VERIFY=1 \
  && composer global require "laravel/installer"
```

ちなみに`export`コマンドはターミナルからログアウトもしくはexitするまで保持される。
Linux：ファイルとディレクトリ

#はじめに
**Linixは全てファイルとして表現されている**

つまり、文書や画像もファイルとして保存されている事はもちろん、

システム全体もファイルでそれぞれ構成されている。

Linuxカーネルも、ハードウェアもキーボードも入出力が全てファイルに当てられ、そのファイルを介して機器を操作できる。

#Linuxの各ディレクトリの役割
##/bin
**Linux動作に最低限必要な、重要度の高いコマンドを記載する**

##/dev
デバイスファイルを格納するディレクトリ。
ハードウェアをファイルとして扱える様にした特殊なファイル

#/etc
各種アプリケーションや、Linux自体の設定の記載されたファイルを格納するディレクトリ。

##/home
Linuxユーザーごとに割り当てられるホームディレクトリ。

##/sbin
実行ファイルを置くディレクトリ。

#カレントディレクトリの表示

カレントディレクトリを表示するコマンド。

```
$ pwd
/home/Mac
```

#カレントディレクトリのファイルとディレクトリの表示

```
$ ls
bin home games ....
```

```
$ ls / /home => 複数ディレクトリの指定もできる
```

#相対パスでの移動もできる

```
$cd .. =>　一つ上の階層へ
```

#Tabキーで補完もできる
```
$ cd ho
```

ここでTabキー

```
$ cd home
$ cd home/local
```

とパス名が補完できる。

#ホームディレクトリへの移動
```
$ cd
```

#*と?

hoで始まるファイルの一覧表示

```
$ ls *ho

home homeground hoge
```

```
$ ls *.html

index.html hoge.html
```

hoで始まり長さが4文字のファイルを探す

```
$ ho??

home
```

#lsコマンドのオプション
```
$ ls -l =>　ファイル属性の表示
$ ls -a =>　隠しファイルの表示 
```

オプションは組み合わせて、つなげて書く事も出来る。
yarnを使うプロジェクトでnpm installを禁止する方法

yarnを使うことになっているプロジェクトでは、npm installを禁止したい場合があります。

この投稿では、プロジェクト単位でnpm installを禁止する方法を紹介します。

## npm installを禁止する設定

まず、package.jsonに`engines.npm`フィールドを追加し、そこに`"please_use_yarn_instead"`と書きます:

```package.json
{
  "engines": {
    "npm": "please_use_yarn_instead"
  }
}
```

次に、package.jsonがあるディレクトリに.npmrcを作り、内容を下記のとおりにします:

```toml:.npmrc
engine-strict=true
```

設定は以上です。仕上がりファイル構成はこうなります:

```
.
├── .npmrc
└── package.json
```

## npm installを実行してみる

この設定をした上で、`npm install`を実行するとエラーになります。

![carbon (6).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/889/96cb6e8a-f9fe-48ec-87dc-d69f4a8d9cc5.png)

## おまけ: 「yarn.lockを大事にしてください(切実)」

package.jsonの`engines.npm`に指定する値は、npmとして存在しないバージョンなら何でもいいので、次のようにしても大丈夫です:

> :warning:【お願い】npmではなくyarnを使ってください:bow:yarn.lockを大事にしてください(切実)

```package.json
{
  "engines": {
    "npm": "⚠️【お願い】npmではなくyarnを使ってください🙇yarn.lockを大事にしてください(切実)"
  }
}
```

![carbon (7).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/889/4b33ee15-9806-514f-08f3-30bbdaf7f5f4.png)

## 関連

* [only-allowを用いてプロジェクトでYarnの使用を強制する方法 - Qiita](https://qiita.com/suin/items/e0fbdd9af1150138a65c)
* [package.jsonに"engines"を設定すると「このバージョンのNode.jsでしか動かない」を表明できる - Qiita](https://qiita.com/suin/items/994458418c737cc9c3e8)

---

最後までお読みくださりありがとうございました。Twitterでは、Qiitaに書かない技術ネタなどもツイートしているので、よかったらフォローしてもらえると嬉しいです:relieved:→[Twitter@suin](https://twitter.com/suin)
細かすぎて伝わらないLookerTips

##これはなに
単体で記事にするほどではないが地味に詰まった課題を解決した際のTipsを書き残したもの。随時更新。
もっと良いやり方があれば教えて欲しい。

####Table Visualizationで複数列をキーにしたソートをしたい
まずは第一キーの列名をクリックしてソートしたあと、シフトを押しながら第二キーにしたい列名をクリックする
（ChatSupportで聞いたらPieterが一瞬で解決してくれた）

####日次累計を集計した際、未来の数字がずっと同じ値で出てしまう
now()とdate dimensionの比較を行い、超えた分についてはnullを返す式を作ってあげる

```
if(${daily_hoge.day_month}=trunc_months(now()),
    if(
        diff_days(date(extract_years(${daily_hoge.day_month}),extract_months(${daily_hoge.day_month}),${daily_hoge.day_day_of_month}),now())>=1,
        running_total(${daily_hoge.number_of_hoge}),
        null
    ),
    running_total(${daily_hoge.number_of_hoge})
)
```
PRML　演習問題  3.10（標準）　解答

## はじめに
本記事は, 機械学習の教科書の決定版ともいえる, **Christopher Bishop先生**による[**『Pattern Recognition and Machine Learning （パターン認識と機械学習）』**](https://www.microsoft.com/en-us/research/people/cmbishop/prml-book/), 通称**PRML**の演習問題のうち, 私が解いた問題の解答を記したものです. これは, 私の所属する[生物測定学研究室](https://www.ut-biomet.org/)の輪読会で**PRML**を取り扱っており, その勉強の一環として演習問題を解いたときのものです. なお, 他の演習問題の解答例に関する記事については, [PRML　演習問題　解答集　まとめ](https://qiita.com/Lab_of_Biomet/items/15e38ca34fafa8176d89)をご覧ください.


## 問題
> $$
\begin{align*}
p(\mathbf y)= \mathcal { N } \left (\mathbf y ~ | ~\mathbf A \boldsymbol \mu + \mathbf b, ~ \mathbf L^{-1} + \mathbf A \boldsymbol \Lambda^{-1} \mathbf A ^ \textrm { T } \right) 
\tag{2.115}
\end{align*}
$$
の結果を用いて,  
$$
\begin{align*}
p \left (t ~ | ~ \mathbf t,\alpha,\beta \right ) = \int p \left (t ~ | ~ \mathbf w,\beta \right ) p \left (\mathbf w ~ | ~ \mathbf t,\alpha,\beta \right )\textrm d\mathbf w
\tag{3.57}
\end{align*}
$$
の積分を評価し, ベイズ線形回帰モデルの予測分布が
$$
\begin{align*}
p \left (t ~ | ~ \mathbf x,\mathbf t,\alpha,\beta \right ) = \mathcal { N } \left (t ~ | ~ \mathbf m^\textrm T_N \boldsymbol \phi (\mathbf x),\sigma ^2_N (\mathbf x) \right ) 
\tag{3.58}
\end{align*}
$$
で与えられることを確かめよ. ただし, 入力に依存する分散は, 
$$
\begin{align*}
\sigma ^2_N (\mathbf x) = \frac{1}{\beta}+\boldsymbol \phi (\mathbf x)^\textrm T \mathbf S_N \boldsymbol \phi (\mathbf x)
\tag{3.59}
\end{align*}
$$
で与えられる. 


## 解答
(3.57)の条件付き分布と事後分布は, それぞれ以下の式で表されます. 

```math
\begin{align*}
p \left (t ~ | ~ \mathbf w,\beta \right ) = \mathcal { N } \left (t ~ | ~ \mathbf w^\textrm T \boldsymbol \phi (\mathbf x),\beta^{-1} \right ) 
\tag{3.3, 3.8}
\end{align*}
```

```math
\begin{align*}
p \left (\mathbf w ~ | ~ \mathbf t,\alpha,\beta \right ) = \mathcal { N } \left (\mathbf w ~ | ~ \mathbf m _ N,\mathbf S_N \right )
\tag{3.49}
\end{align*}
```
ここで, (2.115)の式は, 

```math
\begin{align*}
p \left (\mathbf x \right ) = \mathcal { N } \left (\mathbf { x } ~ | ~ \boldsymbol \mu ,\boldsymbol \Lambda^{-1} \right ) 
\tag{2.113}
\end{align*}
```

```math
\begin{align*}
p \left (\mathbf y ~ | ~ \mathbf x \right ) = \mathcal { N } \left (\mathbf y ~ | ~ \mathbf A \mathbf x + \mathbf b,\mathbf L^{-1} \right ) 
\tag{2.114}
\end{align*}
```

が与えられた際の周辺分布だったことに注意して, (2.113)から(2.115)について, 

```math
\begin{align*}
\mathbf y \rightarrow \textit t, \quad \mathbf x \rightarrow \mathbf w, \quad \boldsymbol \mu \rightarrow \mathbf m_N, \quad \boldsymbol \Lambda^{-1} \rightarrow \mathbf S_N,\quad  \mathbf A \rightarrow \boldsymbol \phi (\mathbf x)^\textrm T,\quad \mathbf L^{-1}→\beta^{-1}
\end{align*}
```
と置き換えると, (3.57)を評価できます. 

したがって, (2.115)にそれぞれを代入すると, 

```math
\begin{align*}
p \left (t ~ | ~ \mathbf x,\mathbf t,\alpha,\beta \right ) = \mathcal { N } \left (t ~ | ~ \mathbf m^\textrm T_N \boldsymbol \phi (\mathbf x),\sigma ^2_N (\mathbf x) \right ) 
\tag{3.58}
\end{align*}
```
と求まります. 
ここで, 入力に依存する分散は, 

```math
\begin{align*}
\sigma ^ 2 _ N (\mathbf x) = \frac{1}{\beta}+\boldsymbol \phi (\mathbf x)^\textrm T \mathbf S_N \boldsymbol \phi (\mathbf x)
\tag{3.59}
\end{align*}
```
です.
外部にアクセスせずにルータのWAN側IPアドレスを取得してみる(HGW)

#ルータのWAN側アドレスを知りたい

DDNSを使うには、自分のWAN側アドレスを知る必要がある。

よくあるのは

```shell
#!/bin/bash
ip=$(curl -s https://ipv4.icanhazip.com/)
```

という感じだが、5分おきとかに確認したいときは毎回外部のサーバにアクセスするのはちょっと気が引けるので、ルータにアクセスして取得してみる。

下は我が家のHGW(PR-S300HI)の設定画面である。
![status.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/577966/05e6af4a-7c07-67fd-bf29-a95eaffcebed.png)

curlでルータのページアクセスしてgrepで抽出する。
アドレス、ユーザ名、パスワードは適宜変えてほしい。
他のルータでも基本的な考え方は同じだと思う。

```shell
ip=$(curl -Ss -u user:password \
  http://【ルータのアドレス】/cgi-bin/Now_Information.cgi |\
  grep -A 10 "メインセッション" | grep -A 1 "WAN側" | \
  grep -Eo '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}')  
```

うまくいったけど、LANにルータのパスワードが平文で流れるので、気をつけないといけないかも。
![Screenshot from 2020-05-22 10-47-47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/577966/aad7d8e9-27c8-9531-c3e4-48d96602ffec.png)

最近のルータはWAN側アドレスが変わるとメールで知らせたりしてくれるらしいので、早く取り替えてほしいものである。
[AndroidStudio] ActionBarDrawerToggleのハンバーガーメニューの色変更

タイトルの通りです。
自分用メモ。

ハンバーガーメニューを白色にしたい場合

``` Java:MainActivity.java
        ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
                this, drawer,toolbar,
                R.string.drawer_open,
                R.string.drawer_close);
        /* ハンバーガーメニューのdrawableをtoggleから取得 */
        DrawerArrowDrawable arrowDrawable = toggle.getDrawerArrowDrawable();
        /* 色の変更 */
        arrowDrawable.setColor(getResources().getColor(R.color.colorWhite));
　　　　 /* 色を変更したdrawableを再びセット */
        toggle.setDrawerArrowDrawable(arrowDrawable);

```

以上です。

他にいい方法があれば教えてください。
AWS CLI設定のアレコレ

# 環境
macOS

# AWS CLI インストール

```console
$ brew install awscli --upgrade --user
```

`hostname doesn't match ` というエラーが出た場合は？
=> 確認: Python のバージョンは 2.7.9 以上か

# アクセスキーの作成

AWS CLIには
使用している環境でAWS認証情報が設定されている必要がある。

AWSの認証情報を設定するには、使用するIAMユーザーにてアクセスキーを作成する必要がある。
ダッシュボードのここ。

<img width="1117" alt="スクリーンショット 2020-05-22 10.35.58.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449552/70653c90-6bfd-b5f6-b8aa-1af8c068ed96.png">


`AWS Access Key ID`と`AWS Secret Access Key`が発行されるので保存する。

# プロファイル設定方法

① コマンドで自動設定する方法
② ローカルの`~/.aws`ディレクトリに手動で設定する方法

以上、2通りの設定方法があります。

コマンドでの設定は一発で終わりますが、既に設定してある場合に情報が上書きされてしまいます。
複数のプロファイル管理を行う場合は手動で設定します。

## ①コマンド一発設定

`$ aws configure`を実行するとAWS CLI によって

1. **アクセスキーID**
2. **シークレットアクセスキー**
3. **AWSリージョン**
4. **出力形式**

以上、4つの情報の入力が求められます。

- これらは自動的に`default`という名前のプロファイル設定群に保存されます。
- 👆**既に設定してある場合は上書きされるので注意してください⚠**
- よくわからない場合は、手動設定が無難です。

```console
$ aws configure
AWS Access Key ID [None]: 🆔*****
AWS Secret Access Key [None]: 🔑*****
Default region name [None]: ap-northeast-1
Default output format [None]: json
```

## ②手動設定 (複数プロファイル管理可能)

AWS認証プロファイルの設定を行います。

- `~/.aws`以下のconfigとcredentialsファイルで確認可能。
- 手動修正するなどして、複数プロファイル管理も可能。

```console
$ cd ~/.aws
$ ls
config		credentials
```

### config

設定項目
1. プロファイル名
2. 出力形式
3. AWSリージョン

```console
$ cat config 
```

```conf:config
[profile don.suwa3.me]
output = json
region = ap-northeast-1
```

### credentials

設定項目
1. アクセスキーID
2. シークレットアクセスキー

```console
$ cat credentials 
```

```conf
[don.suwa3.me]
aws_access_key_id = 🆔*****
aws_secret_access_key = 🔑*****
```

# AWS認証プロファイルの設定を有効化

`$ export AWS_PROFILE=${プロファイル名}`で、現在のセッションに指定したプロファイルの設定が効きます。

```console
$ export AWS_PROFILE=don.suwa3.me
```

現在のセッションにのみ適用されます。

```console
$ env
AWS_PROFILE=don.suwa3.me
```

わたしはセッションごとに忘れずexportする運用をしています
理由
- 仕事用と個人用でAWS CLIを複数アカウント運用しているため(本当はダメかも)
- 環境変数を`bash_profile`に固定してしまうと、あとでそのことを忘れそう

ツールでディレクトリごとAWS認証プロファイル設定ができるものもあるらしいです。
Catalina で El Capitan の usb 起動ディスクを作成

# 自用のメモ

* El Captain の[公式マウントイメージ](http://updates-http.cdn-apple.com/2019/cert/061-41424-20191024-218af9ec-cf50-4516-9011-228c78eda3d2/InstallMacOSX.dmg)をダウンロード
* ターミナルを開く
* チェンジディレクトリ 
 
  ```sh
   $ cd ~/Desktop
   ```
* 作業用ディレクトリ作成

   ```sh
   $ mkdir installCapitan && cd installCapitan
   ```
* dmg イメージをダブルクリックしてマウントする
* dmgイメージを解凍

   ```sh
   $ xar -xf /Volumes/Install\ OS\ X/InstallMacOSX.pkg
   ```
* ```InstallMacOSX.pkg``` 配下に、```Payload```, ```Scripts```, ```InstallESD.dmg``` が存在することを確認
* ```Payload``` を解凍

   ```sh
   $ tar xvzf InstallMacOSX.pkg/Payload
   ```
* __Install OS X El Capitan.app__ が生成されたことを確認
* インストール用のデータを __.app__ 配下に移動

    ```sh
    $ mv InstallMacOSX.pkg/InstallESD.dmg Install\ OS\ X\ El\ Capitan.app/Contents/SharedSupport/
    ```

​       mv先はTab補完が効かないが突き進めば良し

* usb boot を作成

    ```sh
    $ sudo Install\ OS\ X\ El\ Capitan.app/Contents/Resources/createinstallmedia \
            --applicationpath ./Install\ OS\ X\ El\ Capitan.app \
            --volume /Volumes/my_install_volume
    ```
* ついでにこのusb boot で普通にGUIのインストールをやっても、不正やら改ざんやら言われ、インストールさせてくれないので、以下で回避可能（進捗が表示されないので、とにかく辛抱強く待つのみ）

    ```sh
    $ installer -pkg  /Volumes/Mac\ OS\ X\ Install\ DVD/Packages/OSInstall.mpkg -target /Volumes/"XXX"
    ```

# Reference:

* [How do I create El Capitan installer on a Catalina (or post-El Capitan) installed Mac for use on USB boot installer](https://apple.stackexchange.com/questions/379603/how-do-i-create-el-capitan-installer-on-a-catalina-or-post-el-capitan-installe)
* [This copy of the Install OS X El Capitan application can't be verified. It may have been corrupted or tampered with during downloading](https://apple.stackexchange.com/questions/216730/this-copy-of-the-install-os-x-el-capitan-application-cant-be-verified-it-may-h/232016#232016)
ログイン機能

１．Gemをインストールしてサーバーを再起動しよう
　Gemfileに以下のコードを追記
　追記する場所は、Gemfileの最後の行にgem 'devise'
　その後ターミナルでbundle install
  ローカルサーバーを再起動しましょう
   rails s

２．コマンドを利用してdeviseの設定ファイルを作成しよう
 deviseを使用するためには、Gemのインストールに加えてdevise専用のコマンドを利用して設定ファイルを作成

 ターミナルでrails g devise:install

 config/initializers/devise.rb
 config/locales/devise.en.ymlが作成される。

３．コマンドを利用してUsersモデルを作成しよう
　deviseを利用する際にはアカウントを作成するためのUserモデルを新しく作成します。作成には通常のモデルの作成方法ではなく、deviseのモデル作成用コマンドでUserモデルを作成

　ターミナルでrails g devise user

　app/models/user.rb
　db/migrate/20XXXXXXXXXXXX_devise_create_users.rb
　test/fixtures/users.yml
　test/models/user_test.rbが作成される
　routes.rbにdevise_for :usersが自動で追記される

　先ほどのrails g devise userコマンドで作成されたマイグレーションファイルを実行します
　ターミナルでrails db:migrate
　これで、usersテーブルが作成される
　ルーティングが変更されたので、サーバーを再起動してお
　rails s
html.erbでナンバリング（番号をふる）をする方法


HTMLの表示側で例えば、

* 特徴1
* 特徴1、特徴2
* 特徴1、特徴2、特徴3…

のように内容によって、数値が変わるように番号をつけるときに使うコード。
（とくに利用が多いのはこういうときだった）

# with_index(1) を利用する

こちらを利用することで、 ナンバリングスタート時の値を（）内の値からスタートすることができ、 
`+1` と書く必要がなくなる。

```erb

<% ....map.with_index(1) do |a, i| %>


<p><%= i %></p>
```

# each.with_index

こっちだと、 `0` スタートになってしまうので、 `+1` と書く必要が発生する。

```erb

<% ....map.each_with_index do |a, i| %>

<p><%= i + 1 %></p>
```
スティッキーズでクォート( ' " )が左右閉じ( ‘’ “” )に変換されちゃうのはmacのスマート引用符のせい

タイトルのまんまです。

スティッキーズはmacOSにデフォルトでインストールされている付箋アプリで便利なんですけど、
等幅フォントでコードを貼り付けても、 **コード内のシングルクォート、ダブルクォートが、
左右閉じのシングルクォート、ダブルクォートに変換されてしまってめちゃくちゃ不便でした** 。

もうスティッキーズじゃなくて、代わりのアプリを探そうかと思ってたんですけど、
ちょっとだけ調べたら、スティッキーズ濡れ衣でした。

macのキーボード設定で、 **スマート引用符とスマートダッシュを使用** という機能があり、
これが有効だと、勝手に引用符が左右閉じに変換されてしまうというのが原因でした。

![キーボード、ユーザー辞書設定](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/10332/450a4511-5a78-9f98-7e0e-2428fffa4ee7.png)

ON/OFFしたときの入力の様子：

<img width="463" alt="スティッキーズ、見比べ" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/10332/1eff202a-9f69-2085-fd01-c1650e5ea727.png">

スティッキーズ、疑ってごめんよ！
「プログラマに優しい現実指向JVM言語 Kotlin入門」で勉強して、、、（その３）

[その２](https://qiita.com/guijiu/items/8375e6813881cc7237b2)から引き続き、
「[プログラマに優しい現実指向JVM言語 Kotlin入門](https://gihyo.jp/dev/serial/01/jvm-kotlin)」でKotlinを勉強しはじめました。
　説明が丁寧で、分かりやすいです。ただ一部、ソースコードの動作を確認しようとしたときに、mainルーチンがなかったりしたので、その部分を追記しました。（自分で悩まなかった部分は、飛ばしています。）
　説明など有益な情報を、ぜひ[原文：クラスを学ぶ](https://gihyo.jp/dev/serial/01/jvm-kotlin/0004?page=2)でご確認ください。
---
##リスト13　抽象クラスの例 と　リスト14　具象サブクラスの例　まとめ
```Kotlin:AbstraKlass.kt
//https://gihyo.jp/dev/serial/01/jvm-kotlin/0004?page=2
//抽象クラス

//リスト13　抽象クラスの例
abstract class Greeter {
    abstract val name: String
    abstract fun greet()
}

//リスト14　具象サブクラスの例１
class JapaneseGreeter(override val name: String): Greeter() {
    override fun greet() {
        println("こんにちは,私は${name}です。")
    }
}

//具象サブクラスの例２
class EnglishGreeter(override val name: String): Greeter() {
    override fun greet() {
        println("Hello,I'm ${name}.")
    }
}

//メインメソッド
fun main(){
    val jg = JapaneseGreeter("鈴木")
    jg.greet()
    
    val eg = EnglishGreeter("Jhon")
    eg.greet()
}
```

##リスト15　インターフェースの例 と　リスト16　インターフェース実装の例
```Kotlin:InterfKlass01.kt
//https://gihyo.jp/dev/serial/01/jvm-kotlin/0004?page=2
//インタフェスクラスクラス

//リスト15　インターフェースの例
//trait Greeter { //マイルストーンM12でtraitキーワードからinterfaceキーワードへ変更
interface Greeter {
  val name: String
  fun greet()
}

//リスト16　インターフェース実装の例１
class JapaneseGreeter(override val name: String): Greeter {
    override fun greet() {
        println("こんにちは,私は${name}です")
    }
}

//インターフェース実装の例２
class EnglishGreeter(override val name: String): Greeter {
    override fun greet() {
        println("Hello,I'm ${name}.")
  }
}

//メインメソッド
fun main(){
    val jg = JapaneseGreeter("鈴木")
    jg.greet()
    
    val eg = EnglishGreeter("John")
    eg.greet()
}
```
逐次更新中
[漏洞通告]Apache Tomcat Cluster集群不安全配置导致反序列化远程代码执行漏洞

### 漏洞描述
当Apache Tomcat在集群模式下使用了自带session同步功能,并且没有使用EncryptInterceptor,或者处于不可信的网络环境中,攻击者可能可以构造恶意请求,进行反序列化攻击.该漏洞利用方式已在网络上公开并传播,请广大客户尽快检查`conf/server.xml`中相关配置.

### CVE编号
Apache官方已忽略该漏洞

### 漏洞威胁等级
高危

### 影响范围
由于官方忽略该漏洞,全版本Tomcat在不安全配置的情况下均受影响

### 漏洞验证
由于Tomcat本身的安全性良好,并无除了JDK/JRE以外的gadgets可利用

这里采用JRE8U20的gadget验证
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/491410/428abf75-d6ed-cfd6-1a0f-d2098789761b.png)

### 修复建议
1.若Tomcat启用了session同步功能,配置EncryptInterceptor对通信进行加密(参考文末)
2.禁止Tomcat集群端点对不可信网络开放（只能防范外网攻击,内网依旧有风险,建议监听IP修改为localhost或者127.0.0.1）
3.升级JDK > JDK7U21/JDK8U20

不安全配置参考示例(`conf/server.xml`):

```
<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster">
        <Channel className="org.apache.catalina.tribes.group.GroupChannel">
        <Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver"
                        address="0.0.0.0"
                        port="5000"
                        selectorTimeout="100"
                        maxThreads="6"/>
        </Channel>
</Cluster>
```

### 时间轴
[0] 2020/05/22 亚信安全网络攻防实验室分析&复现该漏洞并发布漏洞通告

### Reference
http://tomcat.apache.org/tomcat-10.0-doc/config/cluster-interceptor.html#org.apache.catalina.tribes.group.interceptors.EncryptInterceptor_Attributes
https://github.com/threedr3am/tomcat-cluster-session-sync-exp
http://tomcat.apache.org/tomcat-10.0-doc/cluster-howto.html
http://tomcat.apache.org/tomcat-9.0-doc/cluster-howto.html
http://tomcat.apache.org/tomcat-8.5-doc/cluster-howto.html
http://tomcat.apache.org/tomcat-7.0-doc/cluster-howto.html
[悟り] 才能ないからリバースエンジニアリングを学ぶ

[リバースエンジニアリングバイブル ~コード再創造の美学~](https://amzn.to/3bSalah)
[リバースエンジニアリング ―Pythonによるバイナリ解析技法 ](https://amzn.to/3ec0eyK)
[メカ屋のための脳科学入門-脳をリバースエンジニアリングする](https://amzn.to/36jt7Ge)
Lpsolveをmacにインストールする

## 学校の授業でlpsolveが必要になった
- がインストール方法がよくわからない

## 以下で解決
``` shell
brew tap brewsci/science
brew install lp_solve
```

## homebrew/scienceが廃止されててうまくいかないのが原因らしい
- 新しいのは上記のbrewsci/scienceみたいです

## 補足:使い方
``` shell
lp_solve hogehoge.lp
```

- vimでコーディング→コマンドで実行できるのでとても楽ですね!(宗教戦争)
yarn addでバージョンを指定する

yarn addでバージョンを指定してNPMパッケージをインストールする方法です。

```
yarn add [パッケージ名]@[バージョン指定]
```

例: reactのバージョン^16.13.1をインストールする

```
yarn add 'react@^16.13.1'
```
systemctlってめちゃくちゃ便利なんだな...

nodeのアプリをforeverでデーモン化しようと思っていたところ、そもそもsystemctl使えば必要なかったという話です。

## 前提

- ts-nodeのexpressアプリをデーモン化したい
- サーバー起動時にも起動したい
- AWSのEC2

## systemctlの設定を書く

systemctlは昔のserviceコマンドに替わるものですがだいぶ便利になっています。

昔はinit.dにややこしい起動スクリプトを書く必要がありましたが今では、

```/usr/lib/systemd/system/foo.service
[Unit]
Description=foo

[Service]
Type=simple
ExecStart="/home/ec2-user/repo/script/start.sh"

[Install]
WantedBy=multi-user.target
```

これだけで

```
$ sudo systemctl enable foo
$ sudo systemctl start foo
$ sudo systemctl stop foo
```

できます。

start.shには、普通にyarn startが書かれています。
もちろんパスを通したりする必要はありますが。
こんな感じで書いてます。

```start.sh
#!/bin/bash

set -e

cd /home/ec2-user/repo

export PATH=/home/ec2-user/.nvm/versions/node/v14.3.0/bin:/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/ec2-user/.local/bin:/home/ec2-user/bin:$PATH

export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"

/home/ec2-user/.nvm/versions/node/v14.3.0/bin/yarn start
```

便利な世の中になりましたね。

どうでもいいけどserviceコマンドと違って

```
$ service foo start
$ systemctl start foo
```

逆なのがなかなか慣れない...
JavaScriptで二分探索(UpperBound, LowerBound)をしてみる

## :book: LowerBound,UpperBoundとは
[二分探索](http://e-words.jp/w/%E4%BA%8C%E5%88%86%E6%8E%A2%E7%B4%A2.html)の一種のようなもの。

-lowerboundは、指定された要素以上の値が現れる最初の位置を返す
-upperboundは、指定された要素より大きい値が現れる最初の位置を返す

## 例
分かりにくいので具体例
***前提として二分探索と同じくソート済みの配列に対して使います***

```JavaScript
[2, 4, 20, 22, 30, 34]
```

こんな配列があったします。
例えばlowerBound(15)で得られるのは「２」です。
他にはupperBound(15)で得られるのは「3」です。

boundっていう名前の通り境界の位置を返してくるイメージだと分かりやすいかもしれません。

### :computer: コード
```JavaScript
const lowerBound = (arr, n) => {
    let first = 0, last = arr.length - 1, middle;
    while (first <= last) {
        middle = 0 | (first + last) / 2;
        if (arr[middle] < n) first = middle + 1;
        else last = middle - 1;
    }
    return first;
}

const upperBound = (arr, n) => {
    let first = 0, last = arr.length - 1, middle;
    while (first <= last) {
        middle = 0 | (first + last) / 2;
        if (arr[middle] <= n) first = middle + 1;
        else last = middle - 1;
    }
    return first;
}
```
【swift】singleton(シングルトン)とその代替案について

# はじめに
今回は、シングルトンについて書いていこうと思います！
シングルトンとはなんぞやと言うところから、シングルトンを使う場面やメリットについて公式ドキュメントを元に書いていきます！

公式doc:[Managing a Shared Resource Using a Singleton](https://developer.apple.com/documentation/swift/cocoa_design_patterns/managing_a_shared_resource_using_a_singleton)

# 共有リソースの管理者：シングルトン

公式ドキュメントのタイトルにある通り、シングルトンは共有リソースにアクセスします。
ざっくり言えば、**インスタンス内の値を変更後、別のインスタンスを生成しても前者のインスタンスの更新内容が反映されるどういった処理が可能になります。**

つまり、**インスタンスが1個しか生成されないことを保証します。**

イメージとしては、こちらの記事がとても参考になるので一読をお勧めします！
[シングルトンについて　swift](https://qiita.com/sachiko-kame/items/85c2b4163b05ed2cc872)

まず、コードでみていきます！


```Swift
class single {
    var name = "singletonのお勉強"
    static let singleton = single()  //staticキーワードでsingle()をsingletonに代入
    private init(){}
}

var test = single.singleton  //最初のインスタンス
print(test.name)  //出力：singletonのお勉強
test.name = "singleton実装"

let singleton = single.singleton  //値更新後のインスタンス
print(singleton.name)  //出力：singleton実装
```

見ての通り、`static let singleton = single() ` の部分で`singleton`を作ります。
そうすることで、複数のスレッドで同時アクセスされた場合でも、1回だけ遅延して初期化されることが保証されます。

また、初期化以外の設定を実行する必要がある場合は、以下のようにクロージャーを用いることもあります。

```Swift
class singleton{
  static let sharedInstance: singleton = {
    let instance = singleton()
    //追加設定処理
    return instance
   }()
}
```

# シングルトンの使う場面

この機能についてはおおよそわかったが、では一体どのような場面でシングルトンを使うのだろうか、、

[Swift におけるシングルトン・staticメソッドとの付き合い方](https://medium.com/swift-column/singleton-398078bcc58d)

こちらの記事によると、

- `delegate`にシングルトンインスタンスしか渡せない場合
- インスタンスメソッド実装が必要な既存のプロトコルに準拠させたい場合
- その他、大体の場合`static`プロパティ・メソッドを束ねたstructで代用できる

え、`singleton`使う場面、めっちゃ少ないやん

この記事の筆者曰く、**swiftの場合、`singleton`の実装が簡単なので必要なくても使ってもいいのでは**と。



# シングルトンは大抵、`static`プロパティ・メソッドを束ねたstructで代用できる

実際にコードで見ていきます

```Swift


struct MyStruct{
  private init(){}
  static var value = "original"
  static func foo() { print("foo") }
}

var myStruct = MyStruct.self
myStruct.foo()

myStruct.value = "シングルトンもどき"
print(myStruct.value)  // シングルトンもどき
print(MyStruct.value)  // シングルトンもどき
```

確かに、、シングルトンと同じだ、、
iPhoneからの転送時のエラー

iPhoneとPC（Windows）をUSB接続し、写真や動画などをコピーする際に、
「システムに接続されたデバイスが機能していません」／「A device attached to the system is not functioning（英語OSの場合）」
というエラーが出る場合は、

iPhone側で、設定-写真-「MACまたはPCに転送」項目で、「自動」を「元のフォーマットのまま」に変更してみる
Chromeを強制ダークモードとテーマ変更でPowerShellみたいなダークモードにしてみた

風の噂でChromeのデフォルト機能でダークモードにできると聞いてマイナビニュースさんの記事を参考にしながらポチポチ設定してみました。

## 強制ダークモードの手順

[マイナビニュース:Chrome 78で使える「強制ダークモード」に注目](https://news.mynavi.jp/article/20191025-913975/)

試験的機能
`chrome://flags`

有効(Enabled)
`Force Dark Mode for Web Contents`

これで外部拡張機能無しで強制ダークモードにできます。


## Chromeのテーマも合わせてみる

[The Chrome team:Slate](https://chrome.google.com/webstore/detail/slate/cmhmcmgkegfffbbfobhjpdbimgmoohap)

これもまた公式さんの方で良い感じのテーマが公開されていたので追加してみました。

## こんな感じ
### ホーム
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535916/0ba758ca-3cfb-54f7-7880-f2198627de1b.png)

### Qiita
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535916/e37e2a8d-807d-ebb2-e3f5-57251e7a9391.png)

## 触った感じ
ダークモードの完成度は高いですがやはりベータ版の機能なところやWebページのガラパゴス化で少し不格好なところがあります。それでも公式標準機能でここまでダークモードにすることができるのは圧巻されます。近年各種サービスでダークモード化の動きが大きくなってきているのでWeb開発もこれまで以上にダークモードを気にかける必要があるかもしれませんね。
ドメインを取ったけど、メールサーバーにお金は払いたくないし、カスタムドメインでGmailで送受信したい

![header.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16757/8752f121-8e30-0950-5c2f-10ddffe74d7e.png)


# 問題

素のドメインを取っただけだとwebサーバーもないし、メールサーバーもない。
webサーバーは探せばフリーが多いが、メールは ... Gmailを使いたい、カスタムドメインでやりたい。

# 解決方法

ざっくり流れを説明すると、

1. ドメインを取る
2. @yourdomain.comで受けるメールを[forwardemail.net][1]（[OSS][2]）を使って、自分のgmailアカウントに転送する
3. gmailからの送信はGoogleでの設定で@yourdomain.comアカウントで送信出来るようにする

# 受信

ドメインは既に取っておく。ドメインのDNS設定画面を開いておく（CNAME、MX、TXTとかを設定する画面）。

[FAQ][3]に全部書いてあるが、最初に下の図のようにドメインと自分のメールアドレスを入れて進めると、全部コピペでいける。

![FAQ___Forward_Email.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16757/981318ad-e0fe-9ae5-b7ab-bce3922536cb.png)

## まずMXレコードを変更する

既にMXレコードが設定されていればまず**全部消す**
そしてこういう感じでMXレコードの追加

![FAQ___Forward_Email-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16757/888b2797-17e9-302f-bbef-778a54d08976.png)

## 転送アカウント設定

![FAQ___Forward_Email-3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16757/252fa92a-bbf9-2574-4c6b-a689f9cb8943.png)

OptionがAからFまであるが、要は@yourdomain.comで受け取るアカウント名の設定

− Aが一番緩い。@yourdomain.comで受け取るどんなアカウントでも転送する
- Bはアカウントを1つだけ指定した場合
- Cはアカウントを複数指定した場合（ただし255文字以内で）
- Dは同じでアカウントを複数指定した場合だけど、255文字以上増える場合複数のTXTを設定している
- Eはメールアカウント直でなく、別のメールサーバードメインへ転送するタイプ
- Fはwebhookの通知が欲しい場合（コピペすると今すぐにサーバーを用意して無くても、`requestbin.com`で通知の内容が見れる）

因みに転送先のアドレスは固定じゃないので、

- account1@ => account1@gmail.com
- account2@ => account2@gmail.com

という風に設定してもいい


## もう一つのTXT

これ追加

![FAQ___Forward_Email-4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16757/525bd409-65da-33b8-99f9-f2d0edba1b7f.png)

もし既に**v=spf1**的な設定がある場合、`include:spf.forwardemail.net`が他の`include: ...`か`-all`より前に来るように書き換える。（まーとにかく最前列に置く）

![FAQ___Forward_Email-5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16757/8d495fbf-8dc2-f0b4-cf1c-e97653e5891a.png)

## DNSのpurge

settingsからいけるが、

- [Cloudflare][4]
- [Google][5]

でドメイン名を入れて、MXとTXTのキャッシュを更新してもらうよう通知する。
### [これで5分ぐらい待ってからメールを送ってみて届けば成功][10]。


![https___forwardemail_net_en_my-account_domains_mardigrasbeadsfactory_com.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16757/75842fa7-a86a-b4cd-72fa-7b49acbfedf9.png)



# 送信

[基本はこの通り][6]だが流れとしては

1. Googleアカウントに行って、2段階認証をONにする
2. [アプリパスワードなるものを作る][7]
3. 出来たパスワードを元にgmailで@yourdomain.comアカウントを追加
 1. [エイリアスとして扱います][9]を外す
 1. SMTP smtp.gmail.com
 1. ポート 587
 2. ユーザー名はgmailのアカウント
 3. パスワードはさっき作ったもの

これで追加出来て送信出来れば完了。



[1]: https://forwardemail.net
[2]: https://github.com/forwardemail/forwardemail.net
[3]: https://forwardemail.net/en/faq
[4]: https://1.1.1.1/purge-cache/
[5]: https://developers.google.com/speed/public-dns/cache
[6]: https://forwardemail.net/en/faq?domain=yourdomain.com&email=youraccount%40gmail.com#how-to-send-mail-as-using-gmail
[7]: https://support.google.com/accounts/answer/185833?hl=ja
[8]: https://support.google.com/mail/answer/22370?hl=ja&authuser=0
[9]: https://support.google.com/a/answer/1710338?ctx=gmail&hl=ja&authuser=0&visit_id=637257006939075116-2930008642&rd=1
[10]: https://forwardemail.net/en/faq?domain=yourdomain.com&email=youraccount%40gmail.com#why-am-i-not-receiving-my-test-emails
アロー関数と通常の関数の違い（JavaScript ES6）

#Thisの範囲の違い

 - 普通の関数
  - Thisは呼び出したオブジェクトのものになる。つまり呼び出し元のオブジェクトによってThisは変わる。
 - アロー関数
  -　宣言された関数は、宣言された時点でのThis。この場合はグローバルオブジェクトであるnum =1がThisになり決定される。呼び出し元のオブジェクトによってThisは変わることはない。

```
num = 1　//// JavaScriptでvarやletを付けずに宣言された変数はグローバルオブジェクトというオブジェクトのプロパティになる

const obj1 = {
 num: 444,
 fn: function() {
  console.log(this.num);
 } 
};

const obj2 = { 
 num: 888,
 fn:()=>{
  console.log(this.num);
 }
};
obj1.fn(); // 444 
obj2.fn(); // 1

```