OmniAICreator/Qiita-1.07M huggingface dataset:
Kotlin入門:継承

##継承

```Kotlin
open class Person(var name:String = "山田"){
    open fun show():String{
        return "${this.name}です。30歳です。"
    }
}
class MagickPerson(name:String,var magick:String):Person(name){
    override fun show():String{
        return "${super.show()}得意魔法は${magick}です。"
    }
}
fun main() {
    val mp = MagickPerson("山田太朗","浮遊")
    println(mp.show())
}
```
継承を使用したコード例です。
クラス、メソッド共に既定がJavaで言う`final`となっています。
したがって、継承を可能にするには明示的に`open`修飾子の付与が必要です。

クラス宣言の後方に「**:継承するクラス名(引数)**」を記述します。
メソッドをオーバーライドするには`override`キーワードをつけます。

実行結果は以下の通りです。

```Kotlin
山田太朗です。得意魔法は浮遊です。
```

##抽象クラス・抽象メソッド
抽象メソッドとは、派生クラスで機能を上書きしなければならないように
することのできる仕組みです。

```Kotlin
abstract class Person(var name:String,var age:Int){
    abstract fun show():String
}
//抽象クラスの継承
class MagickPerson(name:String,age:Int):Person(name,age){
    override fun show():String{
        return "${this.name}です。年齢は${this.age}歳です"
    }
}
fun main() {
    val mp = MagickPerson("山田",30)
    println(mp.show())
}
```
`abstract`修飾子を使用することで、抽象クラス・抽象メソッドを定義できます。
抽象メソッドは`{}`を持たずシグニチャ※1のみで終了します。

※1シグニチャとはメソッドの名前、およびそのメソッドに対する引数の数と型のこと

抽象メソッドを含んだクラスのことを抽象クラスと言い、
抽象クラスには`abstract`修飾子をつけなければなりません。
抽象クラスを継承した派生クラスでは、抽象メソッドのオーバーライドが必須となります。
SublimeTextの日本語化手順

# はじめに
SublimeTextの日本語化手順です

# 環境
- OS：macOS Catalina v10.15.1
- SublimeText：V3.2.2

# パッケージコントロールのインストール
こちらに記載されている内容通りに進めます
https://packagecontrol.io/installation

コマンドパレットを開く
<ショートカットキー>
　Win/Linux : ctrl+shift+p
　Mac : cmd+shift+p
<メニューから選択>
　メニューバー > Tools > Command Paletteを選択
![sublimeText#package1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/90440/a60f3ac9-1220-fa5d-d36c-567548d6b460.png)

「Install Package Control」を入力してEnter
![sublimeText#package2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/90440/a5604abb-f2f6-d6e3-f237-cef03297dfa5.png)

以下のようなダイアログが表示されればインストール完了です
![sublimeText#package3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/90440/5c7efdf7-36e0-23d5-aaf8-901cff5fecc9.png)

# 日本語化パッケージのインストール
コマンドパレットを開いて「Package Control: Install Package」を入力、選択してEnter
![sublimeText#ja1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/90440/03e8dafd-a7a1-0d7d-5c2f-9d91562a326c.png)

「Japanize」を入力、選択してEnter
![sublimeText#ja2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/90440/7daeb3a1-3b3e-1791-3015-1a62c7e76076.png)

インストールが完了すると日本語化パッケージの適用方法のテキストが開きます
※この時点でメニューバーは日本語化されています
![sublimeText#ja3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/90440/d5a32efa-a9b3-8fc8-4643-3ea8de483a08.png)

# 日本語化パッケージの適用
適用手順にはWindows版のためMacは以下を参考にして下さい

「/Users/{ユーザ名}/Library/Application Support/Sublime Text 3/Packages」へ移動します
![sublimeText#ja4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/90440/3a085145-29af-addf-5553-17f9281d1eb7.png)

Defaultフォルダを作成します
![sublimeText#ja5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/90440/af949fd5-e6b8-8774-e8e0-66189e42a9c7.png)

Japanizeフォルダ内の拡張子「.jp」の11ファイルをDefaultフォルダへコピーします
![sublimeText#ja6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/90440/b9762fc2-d41f-f227-5a19-a39ff0d38daf.png)
![sublimeText#ja7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/90440/cffbb5a6-08e3-3343-ae51-4fde165f5b55.png)

Defaultフォルダにコピーした11ファイルの拡張子を消します
![sublimeText#ja8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/90440/c9bb2331-1f38-5463-7343-f0fa707da8c7.png)

Japanizeフォルダ内の「Main.sublime-menu」ファイル（拡張子が付いていない方）をUserフォルダへコピーします
![sublimeText#ja9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/90440/cdf1cc33-de71-e884-c727-d84d5ea5da63.png)
![sublimeText#ja10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/90440/456055ab-cab9-933a-e32b-24afba658136.png)

以上でSublimeTextの日本語化は完了です。

※メニューバーの「Sublime Text」と「Window」は英語のままでした
GASの実行でパーミッションがあるはずなのにないと怒られてハマった

#要旨
GASでパーミッションのエラーになった場合、一度パーミッションを消してから追加すると「なぜか」直ることがある。

#詳細
GASのプログラムを実行して快調に仕事していたが、このようなエラーが出て躓くことがある。

>SpreadsheetApp.getActiveSheet を呼び出す権限がありません。必要な権限: (https://www.googleapis.com/auth/spreadsheets.currentonly || https://www.googleapis.com/auth/spreadsheets)（行 7、ファイル「コード」）

これはプロジェクトのプロパティのスコープに問題があり、マニフェストファイルをいじれば権限を付与することができる。
以下の記事に詳しい。（上のエラーメッセージも同記事から引用させてもらいました）

>GASのエラー”呼び出す権限がありません”はマニフェストファイルに問題あり
https://qiita.com/h-sto/items/fdde0905d0a4070d18fc

普通はじめてGASのプログラムを実行すると、REVIEW PERMISSIONというダイアログが出て、ユーザーが許可すれば先に進めるはずである。

>【初心者向けGAS】スクリプト実行時の「承認」でびっくりしないために 
https://tonari-it.com/gas-script-approval/

ところが、快調に使えていたスクリプトが「なぜか」パーミッションがありません、と、ダイアログではなくてエラーメッセージが出て実行が阻まれることがある。
しかも、プロジェクトのプロパティを確認しても、appsscript.jsonを確認しても、エラーメッセージに表示されている必要な権限はすでに付与されている。

困る。

本当の原因はぼくにも追いきれていない。
どうも、GASの開発と使用を平行で行うとなるっぽい。
でも、そうとばかりも言えない気がするんだよなー。。
勉強中だ。

さて、ワークアラウンド（弥縫策）として、パーミッションを消してまた追加すればいいことが分かった。
以下のその方法を紹介する。

1. Chromeを起動する
2. https://www.google.com/にアクセスする（ぼくはChromeのHomePageをこれにしているので、新規タブを開くだけ
3. 右上の自分のアカウントのアイコンをクリック
4. Googleアカウントを管理をクリック
5. 左からSecurityを選ぶ（英語で使っているので日本語は違うかも
6. 画面を下にスクロールしてThird-party apps with account accessというのを探す
7. 問題の自作GASのアイコンがあるのを確認
8. 下のManage third-party accessという青色のリンクをクリック
9. さっき確認した自分のGASプロジェクトをクリック
10. [REMOVE ACCESS]というアイコンが出るので、これを押す
11. Googleのページは閉じて大丈夫
12. GASを実行したいスプレッドシート（だかなんだか。。）を開いて、やりたかった動作を行う
13. [REVIEW PERMISSION]が出てくる
14. 自分のアカウントを選択する
15. 下端の[Allow]というボタンをクリックする（権限が多い場合は下にスクロール場合がある

これでOK。
（スクショを貼った方が良かったかもしれないが、いろいろプライバシーがややこしいので割愛しました；；；

以上で解決。

本当は、なぜこういう意図しない権限の喪失とエラーメッセージが出るのかも突き止めて書くべきかもしれないが、とりあえず今日の仕事に支障があるケースがあるかもしれないので、ワークアラウンドだけ書いた。
なにか知っている方は教えてクダサイ。

__（この項終わり）__
【Terraform】S3が存在しているのに、terraform initがエラー出る問題



##コード


```
resource "aws_ecr_repository" “XXXXimage" {
    name = “XXXXmage"
}
```


```
terraform {
  backend "s3" {
    bucket = "ston-terraform-container"
    key    = “XXXXXterraform/ecr/terraform.tfstate"
    region = "ap-northeast-1"
  }
}

provider "aws" {
    region = "ap-northeast-1" 
}

```

##エラー

##Error inspecting states in the "s3" backend:
S3 bucket does not exist.
The referenced S3 bucket must have been previously created. If the S3 bucket
was created within the last minute, please wait for a minute or two and try
again.
Error: NoSuchBucket: The specified bucket does not exist
        status code: 404, request id: xxxxxxxxxhost id: xxxxxxxxxxxxxx

##結論
失敗した際のXXXX.tfstateファイルが残っていると、差分が起きてしまうらしいので、ファイルを削除して、再度initコマンドで解決しました！

詳細はわかっていないので、わかり次第追記します！
##参考記事
[StackOverFlow-Error inspecting states in the “s3” backend: NoSuchBucket: The specified bucket does not exist](https://stackoverflow.com/questions/50844085/error-inspecting-states-in-the-s3-backend-nosuchbucket-the-specified-bucket)
responder 2.0.0 以降で jinja2 の filter を追加する

## TL;DR

Responder が Ver 2.0.0 になって api から jinja_env が消えて custom filter が使えず困ったので、取り敢えず動作するように解消する話

### cutom filter と html

```custom_filters.py
def css_filter(path):
    return f"./static/css/{path}"
```
```_layout.html
...
<link rel="stylesheet" href="{{ 'style.css' | css }}">
...
```

### 1.3.2 まで

1.3.2までは以下の書き方でfilterの追加が行えていた

```app.py
import responder
import custom_filters

api = responder.API()


api.jinja_env.filters.update(
    css=custom_filters.css_filter
)
```



### 2.0.0 以降

2.0.0 以降は `jinja_env` がいないので、取り敢えず以下のように編集した

```app.py
import responder
import custom_filters

api = responder.API()


api.templates._env.filters.update(
    css=custom_filters.css_filter
)
```
_ 付きなので responder 的には、あまり参照することを推奨していないかもしれない...
docker run -it の「-it」とはなにか

Docker, コマンド操作の初心者向けに書いています.

Docker コンテナを起動するとき, `docker run -it ubuntu:18.04 bash` と入力したりする……,
`-it` とはいったい何か, という話です.

# -it は オプション -i と -t の指定

`-it` と入力した場合,
`-i or --interactive` と `-t or --tty` 2つのオプションを指定したという意味です.

(標準化されたものか分かりませんが一般的に)
`-i` はショートオプション, `--interactive` はロングオプション
と呼ばれます.

`docker run -it ...` と `docker run -i -t ...`
この2つの指定は同じです.

docker run コマンドに限らず, 多くのコマンドでこういったオプション指定ができるようになってます.
(たとえばgrep. 大文字小文字を無視, ディレクトリ再帰, バイナリを無視を指定する場合の `grep -irI` は `grep -i -r -I` と同じ)

# interactive (-i, --interactive) オプションは入力のこと

interactive オプションは, 「入力」のことです.
もうちょっと具体的には「標準入力」のことです. 次のものが相当します.

* キー入力
* パイプされたデータ
* ファイルからのリダイレクト

例を出します.

「seqコマンドの結果を, DockerのUbuntuイメージに入っているawkコマンドを使って偶数だけ出力するようフィルタしたい」
とします.

```shell
# seqコマンドの結果
$ seq 10
1
2
3
4
5
6
7
8
9
10
```

その場合は, パイプと `docker run -i` コマンドを組み合わせれば実現できる, ということになります.


#

```shell
$ seq 10 | docker run -i ubuntu:18.04 awk '$1 % 2 == 0'
2
4
6
8
10
```

もうちょっと実用的な例をだします.

「作成したPythonスクリプトを, DockerのPythonイメージを使って実行したい」

ほとんどの場合は, volumeオプションでローカルPCのディレクトリを, Dockerコンテナに共有させて実行させますが,
場合によっては, リダイレクトが使えます.

```shell
# Pythonスクリプトの中身
$ cat hoge.py
print("hello")

# PythonスクリプトをDockerコンテナのPythonにリダイレクトして実行
$ docker run -i python:3.7 python < hoge.py
hello
```


# tty (-t, --tty) オプションは疑似端末

ここ, ちょっとちゃんと理解できてないところもあるのですが, ttyは「端末」のことです.
ここでいう端末は, たとえばプロンプトが表示されたbash/zsh などのインタラクティブシェルのことです.
REPLを備えたPythonなどもそうです.
コマンドを入力できて, 実行できて, 即座に実行結果が表示されるアレです.

たとえば, Ubuntuのコンテナを起動すると同時に top コマンドを実行して監視してみたい

`-t` オプション指定がないと, 「TERM環境変数が設定されていない」というエラーがでて
起動すらできません.

```shell
$ docker run --rm ubuntu:18.04 top
TERM environment variable not set.
```

docker run に `-t` オプションを指定すると, topを起動できるようになります.
ちなみに, `-t` だけの指定で `-i` がないとキー入力が受け付けられなくなるため,
Qキー押下で終了できません.
(topコマンドはCtrl-C で割り込んで止められましたが,
起動するインタラクティブシェルによっては, それすらできないません.
別のターミナルでdockerコマンドを使ってコンテナを終了/停止する必要があります)

類似のオプションは他のソフトウェアにもあったりします.

たとえば, sshで接続した先でコマンドを実行する場合,
`ssh $xxx_host program` のように実行コマンドを指定します.

この実行コマンドがインタラクティブシェル/REPLである場合は (インタラクティブシェルとして使いたい場合は), `-t` を指定する必要があります.
`ssh -t $xxx_host python` のように.


# まとめ (というほどではないけど)

* `-i` オプションだけ指定することが有用なケースはそれなりにある
* `-t` オプションだけ指定する状況はちょっと思いつかない

# 参考資料

http://docs.docker.jp/engine/reference/run.html
ファイル名一括変換

#はじめに
フォルダ構造が複雑であり、リネームしたいファイルが散らばっているときに有効なリネーム方法。

詳しい解説とコードは[【Bash】ファイル名一括変換](https://www.aiprogrammers.net/entry/2020/04/19/012442)をご覧ください。
Python3.7系でvimやzshにエラーが出た

## 起きた問題

zshはPythonのトレースバックメッセージが表示され、vim（私の場合SpaceVim）がinsertしようとすると、大量にエラーを吐かれて使いものにならなかった。vimの方のエラー内容は忘れてしまいました...

## 解消方法

Pythonのバージョンを3.6.0に戻してプラグインをそれぞれ再インストールしました。

### vim

私はSpaceVimを使っているので、vimを開いて、`:SPUpdate`を行いました。

### zsh

zplugでプラグインを管理しているため、`zplug update`で再インストール

上記で解決しました。
かなり内容が薄くなってしまいましたが、とりあえずバージョンを戻せば元のように動くようになるようです
User AgentからAndroidの端末モデル名を取得

# 趣旨
最近ユーザーエージェントが話題です。
流行に乗ってUser AgentからAndroidの端末モデル名を取得する方法を試してみました。
これで気になるあの子がどの端末を使っているかも丸わかり :dancer: 

早速ですが、こちらです。

```
ua="{User Agent}"
echo $ua | sed -e "s/; wv//" |  sed -e "s/^.*; //"  | sed -e "s/ Build.*//" | sed -e "s/[)].*//"
```

具体的には、
`; wv` を空文字に置換
`^.*; `を空文字に置換
` Build.*`を空文字に置換
`[)].*`を空文字に置換


# 解説

AndroidのUser Agentは

`Mozilla/5.0 (Linux; U; Android 8.0.0; {Model} Build/xxxx.xxxxxx.xxx; wv) AppleWebKit/....`

みたいな感じ。
最初の()の中にある{Model}を取得したい。
ただし、この()が色々パターンがあって・・・

wsがついていなかったり
`(Linux; U; Android 8.0.0; {Model} Build/xxxx.xxxxxx.xxx)`
Build番号が入っていなかったり
`(Linux; U; Android 8.0.0; {Model})`
言語コードが入っていたり
`(Linux; U; Android 8.0.0; ja-JP; {Model} Build/xxxx.xxxxxx.xxx; wv)`

などなど
そこで・・・・

1. `; wv`を除去（2の処理でこの;が邪魔になるので）
2. 先頭から`;`までを全部除去（これで先頭がModel名になるはず。Model以降に;が無いことを祈る（今の所無さそう））
3. Build番号以降を除去→これでModel名だけ残る
4. )以降を除去（Build番号がないケースの対応）

取得したモデル名を下記のページで照会すればブランド名も丸わかり :dancer: 

http://storage.googleapis.com/play_public/supported_devices.html

# おことわり
本来であればUser Agentの構文をちゃんと理解して着手するべきですが、脳みそが足らなかったので、実際のUAを眺めながら帰納的に対応。

どうせUAから取得する意味もなくなるし、もしかしたらもっと楽に取得できるのかもしれないですね。
https://wicg.github.io/ua-client-hints/#http-ua-hints
rubyXLでexcelデータを出力する際に悩んだこと。

備忘録な意味合いで残します。

**1. テンプレートとするExcelで完全にブランクなセルに値をセットしようとするとエラーになる。**
 ・罫線などの情報を一切もっていないセルには、
　　**file[sheet_name][row][col].change_contents(value)**
　こういう指定ができない。
　もしこれで、nil:NilClassのエラーがでるようなら、該当のセルにスペースを一度いれておく。とかで取得できるみたい。

**2. insert_rowで値を挿入すると、その下のセル結合などが壊れる。**
・仕様のようなので仕方がないが、UIで操作する単純な行の挿入のイメージとは処理が違う。挿入する行の前後は、セル結合などは極力してない方がベスト。
docker コマンドだけで起動する proxy サーバ

[proxy](https://www.npmjs.com/package/proxy) という npm パッケージを node コンテナで実行するだけでお手軽に proxy サーバが起動できる。

## コマンド

```terminal
$ docker run --rm -p 8888:3128 node npx proxy 
```

* proxy コマンドはデフォルトで `3128` ポートをListenするのでそれをホスト側の `8888` にポートマッピングしている

## ブラウザの設定(Firefoxの場合)

[![Image from Gyazo](https://i.gyazo.com/2eb1934ca5363809fe8d8e68da81b73b.png)](https://gyazo.com/2eb1934ca5363809fe8d8e68da81b73b)

* Manual Proxy setting でホスト名を `localhost`、ポート番号を先のコマンドでポートマッピングしたportに設定 

## 参考

* [npm 5.2.0の新機能！ 「npx」でローカルパッケージを手軽に実行しよう](https://qiita.com/tonkotsuboy_com/items/8227f5993769c3df533d)
* [proxy - npm](https://www.npmjs.com/package/proxy)
VScodeにSourceHanCode JPを追加した。(文字フォント、windows10)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/444886/861bfe10-e0f7-b75b-13c5-2164fa213a8e.png)
#目的
<dl>
<strong>VS code</strong>に見やすい日本語フォントを追加する。
<dd>※ 今回は<strong>Source Han Code JP</strong>（源ノ角ゴシックJP）</dd>
</dl>
#手順
###１．GitHubからフォントを取得
・**GitHubの[リンク](https://github.com/adobe-fonts/source-han-code-jp#download-the-fonts)**にある**Download the fonts**の**Latest release** をクリック
・**Assets**の**Source Code（zip）**をクリック。※保存先はどこでも良いです
・保存したzipファイルを解凍する。
###２．フォントをインストール
・Ｗindowsの設定を開く。（ショートカット：win + i ）
・個人用設定をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/444886/6aadf8d3-a581-de89-7c4c-3add0c042c0b.png)

・左の項目からフォントをクリック
・解凍したフォルダ内のOTCフォルダを開き、**ttcファイル**をドラッグ＆ドロップする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/444886/5c4668cc-0c73-87e5-78c1-d29ea2791dc6.png)
###３．VScodeでフォントを設定
・**VScodeを起動**して設定を開く（メニューのファイル - 基本設定 - 設定）。（**ショートカット**：ctrl + , ）
・**Editor：Font Family** にカンマ区切りで**Source Han Code JP**と追加（ "family"で検索可能 ）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/444886/45d515a4-e2c1-3e62-8064-68b29dfbe76e.png)
※文字フォントは左端が一番優先される。（今回はMonaco）

---
###最後に
全角がはっきり見えるようになった。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/444886/1bbc943d-9e6d-dc36-a941-2deb1ab8351e.png)
nuxt generateで静的サイトをつくる時の開発環境について（ファイル監視など）

#はじめに

皆さんこんにちは。
Nuxt.js、とてもいいですよね。煩雑な設定が少なくすぐに実装に取りかかれるので、アウトプット速度がすごく向上します。

今回は、nuxt generateコマンドで静的サイトをビルドする際の開発環境構築で感じた課題と、その解決方法について軽めの記事を書きたいと思います。

ツッコミどころや改善案などあればぜひコメントお願いします。

#TL;DR
- 単一ファイルコンポーネント等を使ったVueでの開発をしつつ静的なHTMLを書き出せるnuxt generateはとても便利で使い所も多いが、開発中のファイル監視と自動更新は自前で実装せねばならず、したとしても毎回generateをすることになるので時間がかかる。
- 上記を解決するために、開発時は静的ファイルを生成せずnuxtコマンドで開発を進め、静的ファイルを生成したい時のみnuxt generateを叩くという開発方法を検討した。
- その際、画像ファイル等の参照でハマった


#nuxt generateについて
nuxt.jsそのものに比べ、こちらのコマンドは比較的新しい機能ということもあり知名度がやや落ちるかと思ったので、概要について触れておきます。

前述の通りnuxt generateは、nuxt.jsで実装した内容を、静的なHTMLとjsファイルとして書き出して、そのまま静的Webサイトとして使用できるようにしたAPIプロパティです。

これを使うメリットとして、クライアントサイドでの描画がなくなるためSEO上安心ということ、パフォーマンスがやや向上することがあげられます。

また個人的には、多言語サイトを構築する際に、SSRを実装しなくてもjsonから文言を取得して、手軽に各言語のHTMLを書き出せる点に大きなメリットを感じています。（nuxt-i18n使用時）

ディレクトリ構造自体は通常のnuxt開発と同じように、以下のような形で組めば、pagesの中身のvueファイルが全てHTMLで吐き出されるイメージです。

```
> components
> assets
> static
> pages
package.json
nuxt.config.js
```

#nuxt generateの弱点
nuxt generateは、一括でファイルを生成するという機能である以上、変更箇所に応じて部分的にビルドをするような監視機能は備わっていません。

そこで、自前でsrcファイルの監視をして更新をしなければならないのですが、毎回nuxt generateを叩かなければいけないため、ビルドに多くの時間がかかってしまいます。

npm scriptsやその他ビルドツールであればscssが変更されればそこのみ、jsが変更されればそこのみビルドするといった形で細かく監視ができるので、その点においてはnuxt generateの弱点と言えそうです。

#実装
##解決案
そこで、開発時には通常のnuxtコマンドを使ってホットリロードサクサクナウヤングな開発をしつつ、実際に静的HTMLとしてテストしたい時のみnuxt generateを使えばいいんじゃないか、と思い当たりました。

そこで最初に書いたpackage.jsonは以下のような形です。

```js
"scripts", {
  "dev": "nuxt",
  "build": "run-s mock:**",
  "build:clean": "rimraf ./dist/**",
  "build:gen": "nuxt generate",
  "build:browse": "browser-sync start --config bs-config.js"
}

```

npm run devコマンドでは単にnuxtコマンドを実行し、
npm run buildコマンドでは一旦distディレクトリを綺麗にしてからnuxt generateし、それが完了したらbrowser-syncでローカルサーバを立ち上げています。

##つまづいたところ
当初assetsフォルダとstaticフォルダの違いがよくわかっておらず、画像等は適当にassetsに突っ込んでいました。


しかし、nuxt開発においてassetsファイルの参照は、

```html
<img src="~assets/images/hoge.png">
```

のように記述しなければならず、そのままnuxt generateをしても参照ができません。
面倒だけどパス置換のスクリプトを挟むか・・・？とも思いましたが、よくよく調べるとstaticフォルダ内の参照は、/staticを省いて以下のようにかけるようです。（直接は関係ありませんがassetsの中身はwebpackでコンパイルするものを突っ込むようです）

```
<img src="/images/hoge.png">
```

しかも、nuxt generateでファイルが書き出されるdistフォルダにはしっかりとimagesフォルダができており、どうやらnuxt generateではstaticに全ての参照ファイルを突っ込むのが正解のようです。

#余談
これで開発環境は構築できたのですが、よくみると、distフォルダの中のHTMLが想定通りのものになっていません。

```
//想定したもの
index.html
hoge.html

//書き出されたもの
index.html
hoge
|__index.html
```

これは、nuxt.config.jsでgenerateプロパティのsubFoldersをfalseにすると解決できました。

```nuxt.config.js
export default {
  //省略
  generate: {
    subFolders: false
  },
}
```
[Vue warn]: `createComponent` has been renamed to `defineComponent`.

# 概要

バージョンをアップグレードしたら `Vue warn` が出るようになったのでメモ

# 対応

```diff
-import { createComponent } from '@vue/composition-api'
+import { defineComponent } from '@vue/composition-api'

-export default createComponent({
+export default defineComponent({
```

警告にある通りリネームしたら警告が消えた

# まとめ

* 警告の通りリネームで解決
* 親切な警告は助かる
[Terraform]S3は事前に作成しておく問題


#*自分の戒めとして*

```Error: Failed to get existing workspaces: S3 bucket does not exist.  The referenced S3 bucket must have been previously created. If the S3 bucket was created within the last minute, please wait for a minute or two and try again.  Error: NoSuchBucket: The specified bucket does not exist```     

###翻訳するとこんな感じ
S３バケットは存在していません。参照されるS３バケットは事前に作成されている必要があります。もし、1分以内にバケットが作成されたなら、もう１〜2分待ってください。

###結論
手動で事前に作成しておきましょう。
ローカル5Gと自営BWAについてのメモ

# ローカル5G
携帯電話通信事業者が提供しようとしている5Gとは異なり、特定の範囲やエリアで利用する回線網のことで、各自治体や企業が整備して提供する新しい仕組みです。外部ネットワークの影響を受けない為、高いセキュリティを確保できる面で注目が集まっています。但しシステム上導入当初は、4Gシステムと組み合わせての利用が必須になります。
また、利用は屋内または施設内が原則になります。

# 自営BWA
ローカル5Gと合わせて導入される、4G（LTE）のプライベートネットワークを構築できる制度です。
地域BWAを基に検討されました。※ BWA：Broadband Wireless Access

### 地域BWA
2.5GHz帯の周波数の電波を使用して、地域の公共サービスの向上やデジタル・ディバイド（条件不利地域）の解消、地域の公共の福祉の増進に寄与することを目的とした電気通信業務用の無線システムです。

### なぜ自営BWAが制度化されたのか
5Gネットワークが、導入当初4Gネットワークを利用するNSA構成となることが背景にあります。※NSA：Non-Standalone
4Gネットワークが無いとローカル5Gが利用できず普及が進まないことから、自前で4Gネットワークを構築できる制度が検討されました。

# 免許の適用範囲
申請受付は2019年12月から始まっています。
また、全国MNOがサービスを補完する目的でローカル5Gを利用することは不可とされており、且つ免許の適用範囲に全国MNOは含まれません。全国MNOはdocomo、KDDI:au、softbank、楽天モバイル、UQコミュニケーションズ 等を指します。

- 当分の間、全国MNOはローカル5G帯域の免許取得は認められない
- 全国MNOの子会社等の関連企業の免許取得は可能
- システム構築を依頼された者は、依頼を受けた範囲内にて免許取得が可能 (骨子案なので、実運用では変わる可能性あり） 

# 電波法の適用関係
1. 無線局開設の申請が必要
ローカル5Gを導入する場合は、無線局の免許の申請が必要です。標準的な処理期間は約1か月半とされています。また、導入当初はNSA構成となるため、28GHz帯の無線局開設手続きに加えて、自営BWAの無線開局手続きが必要になります。

2. 技術基準適合証明の適合
必要に応じて技術基準適合証明を受けることができます。

3. 無線従事者の資格要件
ローカル5Gおよび自営BWAの基地局を扱う従事者は、一般的には第三級特殊無線技士の資格者が適用されます。但し空中線電力100Wを超える場合など、取扱う操作の内容によっては異なる資格要件が必要になります。

# 利用できる周波数
以下が想定されており、先行して28.2 - 28.3GHzの100MHzを利用する際の技術要件整備が行われています。（2020年6月時点）
その他の周波数は2020年内に検討されるようです。

- 4.6 - 4.8 GHz
- 28.2 - 29.1 GHz

<img width="800" alt="ローカル5Gの候補帯域の状況" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/550425/231d8a1f-48c9-733d-aef3-8c9ede025bd0.png">
[ローカル５Ｇに係る検討状況等（総務省）](https://www.soumu.go.jp/main_content/000604577.pdf)

# 電波の利用料

- ローカル5G（28.2 - 28.3 GHz）
基地局 ：2,600円/局
陸上移動局（包括免許）：370円/局

- 自営等BWA（2575-2595MHz）
基地局 ：19,000円/局
陸上移動局（包括免許）：370円/局


# 参考
- [地域広帯域移動無線アクセス（地域BWA）システム](https://www.tele.soumu.go.jp/j/adm/system/ml/area_bwa/)
- [ローカル５Ｇに係る検討状況等（総務省）](https://www.soumu.go.jp/main_content/000604577.pdf)
- [ローカル5G導入に関するガイドライン - 総務省](https://www.soumu.go.jp/main_content/000659870.pdf)
axiosのcatchでerror objectの中身を見れない

## 問題
axiosのレスポンスを `console.log()` で表示した時
`.then` のレスポンスはうまくオブジェクトとして取れるのに
`.catch` のレスポンスは下記のように表示されてしまう

```
Error: Request failed with status code 422
    at createError (createError.js:16)
    at settle (settle.js:17)
    at XMLHttpRequest.handleLoad (xhr.js:59)
```

## 結論

catchのerrorオブジェクト？が文字列として表示されてしまっている。
なのでerror.responseと指定すればOK

```javascript
axios.post('/test/create', this.formData)
  .then(response => { 
	console.log(response)
  })
  .catch(error => {
    console.log(error.response)
  });
```

or 

```javascript
axios.post('/test/create', this.formData)
  .then(response => { 
	console.log(response)
  })
  .catch(({response}) => {
    console.log(response)
  });
```


### 参考
https://katuo-ai.com/axios-error/
https://github.com/axios/axios/issues/960
enumのRSpecの書き方

## はじめに
enumのテストコードを書いたので、備忘として残します。</br>
`shoulda-matchers`を使用しています。

## ソースコード

```app/models/hoge.rb
class Hoge < ApplicationRecord
  enum status: {
    hoge: 0,
    huga: 1
  }
end
```

```spec/models/hoge_spec.rb
RSpec.describe Hoge, type: :model do
  describe 'enum' do
    it { is_expected.to define_enum_for(:status).with_values(hoge: 0, huga: 1) }
  end
end
```

## 解説
`shoulda-matchers`の`define_enum_for`を使うと上のように書けます。
`with_values`ではなく、`with`でもテストは通りますが怒られます。

簡単ですね！

## 参考
[【RSpec】shoulda-matchersでenum，delegateのテスト](http://izumin.hateblo.jp/entry/2015/02/10/215059)
日本版 Windows10 を英語環境にする

日本語設定で動かないアプリなどのために。
テストした環境　Windows10 Pro バージョン1903 確認した日付は2020/02/28

Windowsキー＋Sを押して「言語の設定」とタイプし呼び出します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/d01e790f-5a9d-6f3b-2730-fc5bd6687441.png)
「優先する言語を追加する」を押して
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/8aa9e864-8b09-1a32-4808-b8c5bcb0d1c5.png)
English　(United Status)を選んで「次へ」
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/d7761da4-e3bf-7ca9-6eb0-a9cdadb5252c.png)
上2つだけ選んで
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/8df79978-400c-0332-7ab5-b93a79da0184.png)
再起動すれば英語環境になります。

# 日本語入力

Microsoft IMEに切り替えることで日本語入力ができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/35044361-a50e-e9ff-0b9b-5d616cd10ad1.png)


# 元に戻すには

Windowsキー＋Sを押してLanguageとタイプし呼び出します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/9df5682a-db8e-ce76-5df3-81e4805d3d03.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/9389703f-7678-eb18-3d6b-97c6b077238a.png)


日本語を選び再起動すると元に戻ります
GitLab-CI + Cypressで自動テストを実行すると、レンダラーのクラッシュで異常終了

# 背景

[以前の投稿](https://qiita.com/itTkm/items/3a58d394e83be277f2a6)で[GitLab-CI](https://docs.gitlab.com/ce/ci/)と[Cypress](https://www.cypress.io/)を連携して、Webアプリケーションの自動テスト環境を構築した。

当初は何ら問題なく動いていたが、ある時から以下のエラーを吐いてパイプラインが`Failed`になるようになってしまった。

本投稿では、その対処方法を掲載する。

```
We detected that the Chromium Renderer process just crashed.

This is the equivalent to seeing the 'sad face' when Chrome dies.

This can happen for a number of different reasons:

- You wrote an endless loop and you must fix your own code
- There is a memory leak in Cypress (unlikely but possible)
- You are running Docker (there is an easy fix for this: see link below)
- You are running lots of tests on a memory intense application
- You are running in a memory starved VM environment
- There are problems with your GPU / GPU drivers
- There are browser bugs in Chromium

You can learn more including how to fix Docker here:

https://on.cypress.io/renderer-process-crashed
```

# 環境

* CentOS 7.5.1804
* GitLab CE 11.11.3
* gitlab-runner v12.6.0
* Cypress v3.7.0


# 調査

ヒントは、エラーメッセージ末尾に書かれていた。
> You can learn more including how to fix Docker here:
> https://on.cypress.io/renderer-process-crashed

リンクを辿ると最終的にGitHubのIssueスレッドにたどり着く。
スレッドを読むと、[この投稿](https://github.com/cypress-io/cypress/issues/350#issuecomment-549115501)に解決策が記載されていた。

# 対処

## 1. gitlab-runnerのconfigを修正

修正すべきファイルは、gitlab-runnerのコンテナの中であれば`/etc/gitlab-runner/config.toml`、コンテナ作成時にvolumesを指定してホストOS側のパスをマウントしている場合は、そのファイルを直接編集すると良い。

```toml:config.toml
[[runners]]
  ...
  executor = "docker"
  ...
  [runners.docker]
   ...
    volumes = ["/dev/shm:/dev/shm", ...other volumes...]
  ...
  [runners.cache]
```

## 2. gitlab-runnerを再起動

```bash
# ホストOSから実行する場合
docker exec gitlab-runner-docker gitlab-runner restart

# コンテナにログイン後に実行する場合
gitlab-runner restart
```
[Dart/Flutter] MapからListへ、ListからMapへ変換

適当なModelクラスを使用する

```dart
class Person {
  Person(this.name, this.age);

  String name;
  int age;
}
```

# MapからListへの変換

適当なMap<String, int>を用意これをList\<Person\>に変換

```dart
final persons = {'Takahashi': 23, 'Hamasaki': 27, 'Kawasaki': 25};
```

### 1. forEachを使う

```dart
final list = [];
persons.forEach((k, v) => list.add(Person(k, v)));
```

### 2. Iterable forEach()を使う

```dart
final list = [];
persons.entries.forEach((e) => list.add(Person(e.key, e.value)));
```

### 3. Iterable map()を使う

```dart
final list = persons.entries.map((e) => Person(e.key, e.value)).toList();
```

# ListからMapへの変換

適当なList\<Person\>を用意これをMap<String, int>に変換

```dart
final persons = <Person>[]
..add(Person('Takahashi', 23))
..add(Person('Hamasaki', 27))
..add(Person('Kawasaki', 25));
```

### 1. Map.fromIterables()を使用する

```dart
final map = Map.fromIterables(persons.map((e) => e.name).toList(),persons.map((e) => e.age).toList());

```

### 2. Iterable forEach()を使用する
```dart
final map = {};
persons.forEach((person) => map[person.name] = person.age);
```

# まとめ
MapからListへの変換なら、Iterable map()を使うと一行で変換できる。
ListからMapへの変換なら、Map.fromIterables()を使うと一行で変換できる。
aws cli でcloudwatch log group の保持期間をまとめて設定する

備忘録

- 1. ロググループ名を列挙する

```bash
# 保持期間(retentionInDays)が設定されていないロググループを列挙する
# 数が多くて1回で取り切らない場合は --log-group-name-prefix で絞り込むとか
aws logs describe-log-groups \
--query 'logGroups[?!(retentionInDays)].logGroupName' \
--output text
```

- 2. 保持期間を設定する

```bash
aws logs put-retention-policy \
--log-group-name <ロググループ名> \
--retention-in-days <保持日数>
```

- 1. と 2. の合わせ技

```bash
# 保持期間が設定されていないloggroupの保持期間を7日間に設定する
for lg in `aws logs describe-log-groups --query 'logGroups[?!(retentionInDays)].logGroupName' --output text`
do
  aws logs put-retention-policy --log-group-name $lg --retention-in-days 7
done
```
QVTKOpenGLWidgetでマウスイベントをカスタム/無効化する方法

# デフォルトのマウスイベント動作
QVTKOpenGLWidgetではマウス操作に関して以下の動作がデフォルトで実装されている。

- 左ボタンドラッグ：回転
- 右ボタンドラッグ：拡大縮小
- 真中ボタンドラッグ：平行移動
- Ctrl+ホイール回転：拡大縮小

拡大縮小はホイール操作のほうが直感的なのと、自分で定義したマウス操作を実装するのに邪魔なので、
デフォルトの右ボタンドラッグを無効化して、独自のマウス操作を実装したい。

# Qtでのマウスイベント処理を変更して対応(うまくいかない)
このような場合すぐ思いつくのは、QVTKOpenGLWidgetを継承したクラスを作成し、QVTKOpenGLWidget::eventをoverrideして実装する、という方法である。例えばMyWidgetクラスを以下のようにして、右クリックイベントを実装する。

``` c++:MyWidget.cpp
class QVTKOpenGLWidget;
class MyWidget : public QVTKOpenGLWidget
{
    Q_OBJECT
public:
    MyWidget(QWidget *parent): QVTKOpenGLWidget(parent){;}
protected:
    bool event(QEvent *ev) override;
};

bool MyWidget::event(QEvent *ev)
{
    if(ev->type() == QEvent::MouseButtonPress 
      && static_cast<QMouseEvent*>(ev)->button() == Qt::RightButton) {
        qDebug() << "Right button click event!!!!";
        // 適当な処理
        return true;
    } else {
        return QVTKOpenGLWidget::event(ev);
    }
}
```

これで右クリック時に"Right button click event!!!!"が表示され、一件うまく行くように見える…が、QVTKOpenGLWidgetのデフォルト動作は無効化されず、自分の定義した処理と、拡大縮小の両者が実行されてしまう。

# vtkデフォルト動作の無効化
これはQVTKOpenGLWidgetではマウスイベント処理をQtベースではなく、VTKベースのvtkInteractorで実装しているため。従って

``` c++:
bool MyWidget::event(QEvent *ev)
{
    if(ev->type() == QEvent::MouseButtonPress 
      && static_cast<QMouseEvent*>(ev)->button() == Qt::RightButton) {
        this->GetInteractor()->Disable();        
        qDebug() << "Right button click event!!!!";
        // 適当な処理。イベント処理後にthis->GetInteractor()->Enable();で再度有効化する。
        return true;
    } else {
        return QVTKOpenGLWidget::event(ev);
    }
}
```
のようにiteractorを一時的に無効化する必要がある。
スプレッドシートの名簿で個々にGmailを送る GAS

## 名簿に記載されている方の個人別にメールを送りたい
　Google Spreadsheet に名前とメールアドレスなどがまとめてある場合、Bcc：などで一斉メールを送ることもできますが、本文中にお名前を入れて個々に送りたい時がありますね。
　コピペするのも手ですが、せっかくなので Google Apps Script で自動化できると嬉しいと思ってスクリプトを書いていましたが、今回それを使おうとしたら、「このプロジェクトは Chrome V8 を搭載した新しい Apps Script ランタイムで実行しています。」というメッセージが出ていて、動作しませんでした。困った！

　そこで、Chrome V8について調べると、
https://developers.google.com/apps-script/guides/v8-runtime
に説明があったので、この際、V8対応で書いてみました。

## 準備するもの
#### Google Document ファイル
 メールの本文となるテキストを書いておきます。
氏名など置き換え用に {宛先名} などのキーワードを書いておきます。
またドキュメント名を Subject: に使用するようにしました。
#### Google Spreadsheet
　送信相手の名前とメールアドレスなどが入っているもの。
　1行目はタイトル行として無視しています。
列番号はA列が[0],B列が[1] のようになります。

## ソース
　onOpen でスプレッドシートにメニューが追加されますので、メニューの「メール送信」から「リストからメール送信」を選ぶと行ごとにメールを編集して送信します。

```Javascript:sendEmail.js
function onOpen() {
  var ui = SpreadsheetApp.getUi(); // Or DocumentApp, SlidesApp, or FormApp.
  ui.createMenu('メール送信')
      .addItem('リストからメール送信', 'menu.item1')
      .addToUi()
}

var menu = {
  item1: function() {
    sendEmail();
  }
}  

function sendEmail() {
  // Googleドキュメントからメールの件名と本文を取得
  var doc = DocumentApp.openById('＜ドキュメントのID＞');
  var subject = doc.getName();    // ドキュメント名を subject とする
  var text = doc.getBody().getText();

  // Googleスプレッドシートからデータ取得
  var spreadsheet = SpreadsheetApp.getActive();
  var sheet = spreadsheet.getActiveSheet();
  var range = sheet.getDataRange();
  var rangeValues = range.getValues();

  for(var i = 1; i < rangeValues.length; i++) {   // 1行目[0]は対象外としている
    // メール本文の置き換えとメール送信の処理
    var name = rangeValues[i][1];    	// 本文の置き換え用氏名のカラム
    var email = rangeValues[i][2];      // 送信先メールアドレスのカラム
    var replacedText = text.replace('{申込者名}', name);
//  送信前の確認処理（不要なら if文まで削除）
    var ui = SpreadsheetApp.getUi();
    var result = ui.alert(
      '送信の確認(Press OK to SendEmail)',
      (name + '\n' + email + '\n' + replacedText),
      ui.ButtonSet.YES_NO);
    if (result == ui.Button.YES) {
      GmailApp.sendEmail(
        email,
        subject,
        replacedText,
        {
          from: '＜送信元メールアドレス＞',
          cc: '＜Cc:のメールアドレス＞',
          noReply: false,
          replyTo: ''
        }
      );
    }
  }
}

```
laravel6のbladeファイル内で変数・配列を新規作成する。

# bladeファイル内で変数・配列を新規作成する。
```php
{{-- laravel6標準ではphpタグでしかできない。(blade構文を拡張して追加・作成する方法はある) --}}
<?php    $v[0]='hogehoge';    ?> 

{{-- 配列の場合は、値の確認もphpタグで --}}
<?php    dump( $v );    ?> 


{{-- 配列の場合下記ではエラーになる。恐らく後からblade内で追加した配列だからだと思われる。 --}}
{{ dump( $v ) }}

{{--しかし下記はエラーにならない --}}
{{ dump( $v[0] ) }}
```
### 参考情報
- [Laravel5.4ではbladeファイル内で`{{--*/ $hoge = 'hoge' /*--}}`といった書き方で変数代入できない - Qiita](https://qiita.com/madayo/items/667beaec1121ec6dd13a)
- [php - Bladeテンプレートで変数を設定したい - スタック・オーバーフロー](https://ja.stackoverflow.com/questions/11588/blade%E3%83%86%E3%83%B3%E3%83%97%E3%83%AC%E3%83%BC%E3%83%88%E3%81%A7%E5%A4%89%E6%95%B0%E3%82%92%E8%A8%AD%E5%AE%9A%E3%81%97%E3%81%9F%E3%81%84)

### なぜ記事を書いたか
laravel6で配列をbladeで新規作成して確認する方法がまとまった記事が見つけられなかったから。
特に確認方法でハマりやすく入門時はできないと勘違いしていた。



### その他
laravel入門にはこの記事おすすめですよ！
[Laravel 5.7で基本的なCRUDを作る - Qiita](https://qiita.com/sutara79/items/ef30fcdfb7afcb2188ea)
laravel6でもほとんどそのまま動きました。
配列の奇数と偶数の和を出力するプログラム(Java)

#手順について
配列の奇数の和と偶数の和をそれぞれ求め、その結果を表示するプログラムです。
以下の手順で記述していきます。

1. 数字の配列を管理するための変数を定義
2. 偶数と奇数を管理するための変数を定義
3. for文で繰り返し処理を記述
4. if文で奇数と偶数の条件分岐を記述
5. 結果を出力ための記述

#数字の配列を管理するための変数を定義

```Main.java
class Main {
 public static void main(String[] args) {
   // 変数numbersに、与えられた数字の配列を代入
   int[] numbers = {1, 4, 6, 9, 13, 16};
 }
}
```
#偶数と奇数を管理するための変数を定義
```Main.java
class Main {
 public static void main(String[] args) {
   int[] numbers = {1, 4, 6, 9, 13, 16};
   // 変数oddSumを定義し0を代入しておく(これが奇数)
   int oddSum = 0;
   // 変数evenSumを定義し0を代入しておく(これが偶数)
   int evenSum = 0;
 }
}
```
#for文で繰り返し処理を記述
処理の手順としてfor文で配列をすべて出しつつ、if文で条件分岐させます。
以下のように記述することで変数numberに配列numbersの各要素が順に代入されます。

```Main.java
class Main {
 public static void main(String[] args) {
   int[] numbers = {1, 4, 6, 9, 13, 16};
   int oddSum = 0;
   int evenSum = 0;
    // for文を用いて、配列numbersを繰り返す
   for (int number : numbers) {
  }
 }
}
```
#if文で奇数と偶数の条件分岐を記述
(number % 2 == 0)の記述で偶数であるかを判断させます。

```Main.java
class Main {
 public static void main(String[] args) {
   int[] numbers = {1, 4, 6, 9, 13, 16};
   int oddSum = 0;
   int evenSum = 0;
   for (int number : numbers) {
    // if文で条件分岐を記述
     if (number % 2 == 0) {
      evenSum += number;
   } else {
      oddSum += number;
   }
  }
 }
}
```
#結果を出力ための記述
for文の外に記述します。
for文の中に書いてしまうとnumbersの各要素を呼び出す毎に出力されてしまいます。

```Main.java
class Main {
 public static void main(String[] args) {
   int[] numbers = {1, 4, 6, 9, 13, 16};
   int oddSum = 0;
   int evenSum = 0;
   for (int number : numbers) {
    // if文で条件分岐を記述
     if (number % 2 == 0) {
      evenSum += number;
   } else {
      oddSum += number;
   }
  }
  // for文の外に記述
  System.out.println("奇数の和は" + oddSum + "です");
  System.out.println("偶数の和は" + evenSum + "です");
 }
}
```
以上になります。
VLC プレイリストを PCとAndroidで共有使用する

## 概要
NAS内の音楽ファイルをPCとAndroid両方で同じプレイリストを使用したかった。

今回は、VLC でプレイリストファイルの「xspf」で作成する。

PCでプレイリストを 作成してAndroidにそのまま使用としても「その場所 file:/// は再生できません」とエラーが出て利用できない。

色々調べてみた結果、プレイリストのファイルパスを**相対パス**にするとPC、Androidどちらでも開けるようになった。

* 相対パスは「../music.mp3」の「../」部分のこと
* ちなみに、相対パスにすると「m3u」でも使用できた。

## プレイリスト作成手順
1. プレイリストを保存するフォルダを作成する
   この時には出来るだけ目的のファイルがある場所に近いところに作っておくと後でファイルを書き換えるときに相対パスを考えるのが楽になる。
![プレイリスト作成説明図1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/248394/4cdca298-c413-5871-938c-005ba94de5af.png)

1. PCのVLCに動画ファイルをドロップ&ドラッグなどで読み込み
1. プレイリストを保存する
1. 保存したプレイリストを開いて相対パスに書き換える
   ここは書き換える量が多いのでスクリプトなどでやる
1. PCとAndoridで使用できるようになる
1. めちゃ便利になる


## 手順 3 で使用する相対パスに書き換えるPython
![プレイリスト作成説明図2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/248394/78f3a32d-3815-f983-892c-bd2d59a05045.png)
PCの方で作成した「xspf」を開くとファイルパスは「絶対パス」で書かれているので、「相対パス」に書き換えるために、Pythonで行うようにした。

「xspf」内の書き換える前のパスは``E://music/アルバム01/music.mp3``となっていて、これを上記のフォルダ位置で相対パスにすると``../アルバム01/music.mp3``となる。

今回はファイルパスが``E://``となっているが**共有IPアドレス**でも同じ用に書き換えると、そのままで使用できる。

それで、下記のPythonを**Playlistフォルダに作成**して、実行すれば相対パスに書き換えてくれる。

```
import shutil
import os
from pathlib import Path

def replace(file_path):
    file_name = file_path
    # バックアップファイルの作成
    print('path: ', file_path)
    back_name = str(file_name) + '.bak'
    print('back_name: ', back_name)
    shutil.copy(file_name, back_name)

    with open(file_name , encoding=`utf-8`) as f:
        data_lines = f.read()


    # 文字列の置き換え
    # 「[」と「]」を「%5B」と「%5D」に置き換えないと「vlc:nop」になって読み込まない
    data_lines = data_lines.replace('file:///E://music/', '../').replace('[', '%5B').replace(']', '%5D')

    # 同じファイル名で保存
    with open(file_name, `w`, encoding=`utf-8`) as f:
        f.write(data_lines)

# 自身のpy が在るフォルダを取得
p_temp = os.path.dirname(__file__)
# フォルダ内でxspfファイルを一覧取得
for f in Path(p_temp).glob(`**/*.xspf`):
    replace(f)
```
CentOS8でexaを使いたい

ある日(今日)、Qiitaにアクセスするとトレンドに以下の記事が上がっていた。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/584615/d3147af7-2f10-c745-5b8c-41ff5df3b6b0.png)
(ちなみに私は「たけのこの里」派です。記事、面白かったです)

[ls よりも exa を使おう！モダンな Linux コマンド達を紹介](https://qiita.com/navitime_tech/items/c249269a3b47666c784b)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/584615/6332394a-d940-d17a-07ee-410985b02edf.png)




はー…すっごいカラフル…。
別に派手なものが好きというわけではないですが、入れてみたくなったので入れてみましょう。

## 導入方法を確認

まずは該当のGitへアクセスし、導入方法を確認してみましょう。

…これは、`$ yum install`で出来ないタイプじゃな？
Linuxに触り始めて間もない身ではありますが、仮想環境に立てたCentOSですし、やりたい放題にしちゃいましょ。

というわけで、ソースからビルドして`/usr/local/bin`へ配置する方法でいきます。

## Rust実行環境の整備

今回入れようとしている`exa`は、Rustで書かれています。
なので、Rust実行環境の整備から始めます。

公式より提供されている、rustupを使います。

```:terminal
$ sudo curl https://sh.rustup.rs -sSf | sh
```
curlコマンドを使って、対象URIへGETリクエストの発行。
進捗は出さなくてもいいけど、エラーは出してね。(-sS)
宛先からエラーが返ってきたら、長い文章じゃなくてステータス「22」を返してね(-f)
そしてそのままshコマンドで実行するね。

```:terminal
…
Rust is installed now. Great!

To get started you need Cargo's bin directory ($HOME/.cargo/bin) in your PATH
environment variable. Next time you log in this will be done
automatically.

To configure your current shell run source $HOME/.cargo/env
```
「インストール終わったよ。やったね！」と言われたのでたぶんおっけー。
PATHを通してね、と言われたので通します。
(今すぐ使いたいなら、直でsourceコマンド叩いてね)

```:~/.bash_profile
export PATH="$HOME/.cargo/bin:$PATH"
```
```:terminal
$ source ~/.bash_profile
```
terminalを再起動してー、バージョン確認。

```:terminal
$ rustc --version
rustc 1.41.1 (f3e1a954d 2020-02-24)
```
おっけおっけ。

## cargoを使ってインストールする
当初の想定だと、Gitからexaのソースを入手して、それをビルドと考えていたのですが、`cargo install`でいけそうな気がしてきた。やってみる。

```:terminal
$ cargo install exa
```
cargoにより、`exa`のバイナリをもってきて、それをビルドする。

```:terminal
…
Installed package `exa v0.9.0` (executable `exa`)
```
やったね！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/584615/bd08187e-27f4-c184-f87b-96f822625a66.png)
すっごいカラフル！
公式によると、「--no-user」というUserフィールドを非表示にするオプションがあるようですが、そんな引数ないよと怒られてしまいました。

```:terminal
$ exa -lh --no-user
Unknown argument --no-user

$ exa -l --no-user
Unknown argument --no-user

$ exa --no-user
Unknown argument --no-user

$ exa --no-user -l
Unknown argument --no-user
```
よくわかんない。

## 参考リンク
[ls よりも exa を使おう！モダンな Linux コマンド達を紹介](https://qiita.com/navitime_tech/items/c249269a3b47666c784b)

[Rust公式のインストール手順](https://doc.rust-jp.rs/book/second-edition/ch01-01-installation.html)
Delegation7レベルを表にまとめてみた

![Delegation7Level.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/40689/99ce1666-da18-305c-e6ee-42b8d06ccaf7.jpeg)

- 権限を与える方をボス、与えられる方をメンバーとしています

## 参考にした記事

- [Management 3.0 Module: Delegation and Empowerment](https://management30.com/empower-teams/delegation-empowerment/)
- [Delegation Pokerで権限移譲について学ぶ – Ryuzee.com](https://www.ryuzee.com/contents/blog/3669)
- [Leading Agile Developers: The Seven Levels of Authority (Part 1) | Anarchy Versus Governance | InformIT](https://www.informit.com/articles/article.aspx?p=1675545)
- [Leading Agile Developers: The Seven Levels of Authority (Part 2) | Situational Leadership | InformIT](https://www.informit.com/articles/article.aspx?p=1675546)
React Nativeでシミュレータを指定して起動する

`react-native run-ios` だけだと起動するシミュレータが固定されてしまいます。
シミュレータを指定したい場合は`--simulator`オプションを使うことができます。

```
react-native run-ios --simulator="iPhone 5s"
```

利用可能なシミュレータを調べたい場合は以下のコマンド。

```
xcrun simctl list devices
```
複数列のデータを縦に並べる方法【SQLServer】

#複数列のデータを縦に並べる

この横に並んでいるデータを

| CD | RANK1 | PRICE1 | RANK2 | PRICE2 | RANK2 | PRICE3 |
| --- | --- | --: | --- | --: | --- | --: |
| 1 | A | 100 | B | 200 | C | 300 |
| 2 | A | 120 | B | 220 | C | 320 |
| 3 | A | 130 | B | 230 | C | 330 |

このように縦に並べます。

| CD | RANK | PRICE |
| --- | --- | --: |
| 1 | A | 100 |
| 1 | B | 200 |
| 1 | C | 300 |
| 2 | A | 120 |
| 2 | B | 220 |
| 2 | C | 320 |
| 3 | A | 130 |
| 3 | B | 230 |
| 3 | C | 330 |

列が1つであれば UNPIVOT を使用することでできますが、
複数あると、 UNPIVOT を使いながら、 JOIN したり面倒です。

CROSS APPLY を使用することで少ないコードで実行できます。

```sql
SELECT CD
      ,v.NO
      ,v.RANK
      ,v.PRICE
FROM TABLENAME
CROSS APPLY
(values ('01' ,RANK1 ,PRICE1),
        ('02' ,RANK2 ,PRICE2),
        ('03' ,RANK3 ,PRICE3),
) v(NO
   ,RANK
   ,PRICE)
```

上記では行NOを付けているので、実行結果として以下のようになります。

| CD | NO | RANK | PRICE |
| --- | --- | --- | --: |
| 1 | 01 | A | 100 |
| 1 | 02 | B | 200 |
| 1 | 03 | C | 300 |
| 2 | 01 | A | 120 |
| 2 | 02 | B | 220 |
| 2 | 03 | C | 320 |
| 3 | 01 | A | 130 |
| 3 | 02 | B | 230 |
| 3 | 03 | C | 330 |
HTML CSS フレックスボックスレイアウト(display: flex;)を使って header, footer を作ってみる（最小？）サンプルコード

# HTML CSS フレックスボックスレウアウト(display: flex;)を使って header, footer を作ってみる（最小？）サンプルコード

みなさまこんにちは、[ハーツテクノロジー](https://www.hearts-tech.co.jp/)の山崎です。

HTML でヘッダー(header)を作るのは難しくないのですが、フッター(footer)を作るのって意外にも難しくて、ハマりポイントもあり、いろんな方法を紹介してくれるページもたくさんあります。でも、最近のブラウザでは CSS のフレックスボックス [flex] （注意：flexboxではない）がサポートされていて「いまとなってはこの方法がベストじゃん」と思うものの、ググってみても情報が多すぎて、最小構成のサンプルがみつからず、、、「ならばわしがっっ！」といった気持ちで到達記念魚拓を残すのです。

まぁ、たいした情報じゃないけど、忘れちゃうので（忘れたいので）備忘録です。

[flex]:https://developer.mozilla.org/ja/docs/Web/CSS/CSS_Flexible_Box_Layout


## リサイズしたときのスクロールバーに注目！

表示画面を小さくリサイズしていくと、まずコンテンツ部分にスクロールバーが出て、隠れ始めます。「ヘッダ」「フッタ」が表示され続けています（ここがポイント）。さらに小さくリサイズしていくと、全体にスクロールバーが表示されます。

![flex-header-footer.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107592/56b9d5d0-7b2f-d234-273d-81fef389df28.gif)


## コードの解説

解説するほど情報は無いのですが、ポイントを挙げると、メインになるのは以下の４つ。逆に言えば、たったこれだけ。

    ・display: flex;            /* flex を指定 */;
    ・flex-direction: column;   /* 縦方向に並べ */;
    ・flex-grow: 1;             /* この div をがんばって広げる指定 */;
    ・overflow: auto;           /* コンテンツが増えても、フッタが隠れないようにスクロールを指定 */;

あとは、罠が２つほどあるので、

    ・html tag も body tag も縦サイズ height が最小になるようにデフォルトで設定されている
    ・body tag にはご丁寧に margin がデフォルトで設定されている

これを回避する指定をすれば目標に到達できます。

CSS の詳細を知りたいひとはこちら[flex]へどうぞ。

## 全コード

```html
<!DOCTYPE html>

<!-- HTML CSS display: flex; を使って header-footer を作ってみるテスト -->

<meta charset="UTF-8">
<html style="height: 100%;  /* まず html タグを広げる必要がある、ってなかなか気が付かない */;">
<body style="
    margin: 0;      /* body のデフォルト margin が 0 以外になっているのも罠だよなぁ、、、 */;
    height: 100%;

    display: flex;              /* flex を指定して */;
    flex-direction: column;     /* 縦方向に並べます */;
    ">
    <div style='background-color: hsla(29, 52%, 72%, 0.5);'>ヘッダ<br>ヘッダ</div>
    <div style='background-color: hsla(106, 23%, 63%, 0.5);'>コンテンツ1タイトル</div>
    <div style='
        flex-grow: 1;       /* この div をがんばって広げる指定 */;

        overflow: auto;     /* コンテンツが増えても、フッタが隠れないようにスクロールを指定 */;

        background-color: hsla(106, 23%, 63%, 0.7);
        '>
        コンテンツ1<br>
        コンテンツ1<br>
        コンテンツ1<br>
        コンテンツ1<br>
    </div>
    <div style='background-color: hsla(202, 32%, 60%, 0.5);'>フッタ<br>フッタ</div>
</body>
</html>
```

## 動作を確認したブラウザ

2020-02-28の時点で動作確認したブラウザは以下です。Windowsのみ。MacOS は機会があったら追加します。

### Google Chrome 80.0.3987.122

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107592/c7dc0eb0-9c2b-3cfc-ba9e-850dbc080e13.png)

### Firefox 73.0.1
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107592/dd3bb402-13b2-e5b7-818e-5f1a6982eafe.png)


### Microsoft Edge 44.17763.8831.0

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107592/51d96729-1eeb-b329-af98-7004099503b7.png)

### IE 11.1039.17763.0
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107592/8755a0f3-7b28-bf0d-7b04-31ea09492ed0.png)

みなさまのプログラミングライフの一助になれば幸いです。
AWS CLIでパラメーターストアにパラメーターを保存する方法

# パラメーターストアに文字列値をセット

```bash
# プロファイルを指定
$ export AWS_PROFILE=<プロファイル名>

# 値をセット
$ aws ssm put-parameter \
  --type String \
  --name キー \
  --value 値
```

# パラメーターストアに安全な文字列値をセット

```bash
# プロファイルを指定
$ export AWS_PROFILE=<プロファイル名>

# 値をセット
$ aws ssm put-parameter \
  --type SecureString \
  --name キー \
  --value 値
```
GCP アップデート (2/28-3/5 2020)


### Compute: [Feb 27, 2020](https://cloud.google.com/compute/docs/release-notes#february272020)
- 色々新しいマシンタイプが使えるように!
  - E2: us-west2-a,b,c, europe-west2-a,b,c, europe-west3-b,c, asia-northeast1-a,b,c
  - N2: europe-west3 a,b
  - C2: us-central1-a
  - M2: asia-south1-a
- OSのパッチ状況が確認/管理出来る[OS Patch Management](https://cloud.google.com/compute/docs/os-patch-management)がベータに。

### GKE: [Feb 27, 2020](https://cloud.google.com/kubernetes-engine/docs/release-notes#february_27_2020)
- k8sのノード経由ではなく、直接コンテナと通信するContainer Native Load Balancingで、ingressから接続しない、standalone NEGがGAになったよ。
  - コンテナとかVMとか混在させるようなケースに有効そう(Traffic Directorはstandalone NEGを利用。)
- Ingress for Anthosが1.14.x、RapidとRegularチャネルでベータになったよ。
  - Anthos用のGoogleが管理するMulti Cluster Ingress。
  - クラスタ間でLBもですが、クラスタのバージョンアップとかでも使えそう？

### IAM: [Feb 28, 2020](https://cloud.google.com/iam/docs/release-notes#February_28_2020)
- 時間や接続元等のコンテキストベースの条件でIAMを付与できるIAM ConditionsがGAに！
- IAM conditionsでリソース名をIAMの名称から取得できるextract()が使えるようになったよ。
  - IAM Conditionsの名称は[これ](https://cloud.google.com/iam/docs/release-notes#February_21_2020)参照

### CloudSQL: [Feb 27, 2020](https://cloud.google.com/sql/docs/release-notes#February_27_2020)
- MySQL 5.6.42がGAになったよ！

### GCS: [Feb 28, 2020](https://cloud.google.com/storage/docs/release-notes#February_28_2020)
- IAM ConditionsがGCSでもGAになったよ。

### Billing: [Mar 2, 2020](https://cloud.google.com/billing/docs/release-notes#March_02_2020)
- コストテーブルが階層で表示されるようになったよ。
  - グルーピングやフィルタが設定可能に。

### BigQuery: [Mar 2, 2020](https://cloud.google.com/bigquery/docs/release-notes#March_02_2020)
- Storage APIがGAになったよ！
- GCS上のORC、Parquetにアクセスする機能がGAに!
- GCS上のhiveパーティションされたデータのロードやクエリがGAに！
- 制限されたPIIに対する正常なアクセスがaudit logsに書かれる際に隠されなくなったよ。

### Composer: [Feb 28, 2020](https://cloud.google.com/composer/docs/release-notes#February_28_2020)
- 新しいバージョンcomposer-1.9.2-airflow-1.10.1, composer-1.9.2-airflow-1.10.2, composer-1.9.2-airflow-1.10.3, composer-1.9.2-airflow-1.10.6)のお知らせ。
  - デフォルトがcomposer-1.9.2-airflow-1.10.2に。
  - 1.6.0から1.8.2にアップグレードできない問題を修正
    - ノード数変更は将来のリリースで修正予定。
  - 1.10.6のhookでPython2に制限されてた問題が解消されて、Composerと同じバージョンを利用するように修正されたよ。

### Compute: [Mar 2, 2020](https://cloud.google.com/compute/docs/release-notes#march22020)
- コンソールでOSイメージをGCSにエクスポートする機能がGAになったよ。

### VPC: [Mar 3, 2020](https://cloud.google.com/vpc/docs/release-notes#March_03_2020)
- パケットミラーリングがGAになったよ！

### Compute: [Mar 3, 2020](https://cloud.google.com/compute/docs/release-notes#march32020)
- E2マシンタイプが全リージョン、全ゾーンで利用できるようになったよ。

### GKE: launch anouncementから。
- 6/6/2020からGKEのマスタが$0.1/h課金されるようになるよ。
  - SLAがつくようになる。
  - 1ビリングアカウントにつき、1 zonal GKEクラスタ分は無料。

### ディスクレーマ
- アップデートの内容はあくまでも個人の理解していることを書いています。正しい内容はリリースノート等を確認下さい。
- リリース内容できるだけ拾うようにしているのですが、抜けていそうなリリースノートが追加するのでぜひ教えて下さい！(一覧[ここ](https://qiita.com/kenzkenz/items/ac18a359b803dbb6b490)で更新してます。)
自分の技術まとめ

~~約2年やっていたプロジェクトの棚卸しのために~~常にアップデートしていきます。自分の技術を棚卸してみた。インフラ周りとフロント周りを強化したい。
採用ではなく(採用でもあると嬉しいですが)プロジェクトでエンジニアを面談するときに経歴書とかよりもこういうのがあると嬉しいなと思うので他の人も作ってみては？

## 習熟度のイメージ
- 教えられる > できる > 時間をかければできる > 経験がある > 知識がある > できない

## ソフトウェア開発
- スクラム開発に関する基本的な知識がある
- スクラム開発の経験(約2年)がある
- 社内でスクラム研修をした経験がある
- スクラムマスターの経験(約1年)がある
- スクラムに関する勉強会に登壇したことがある
- ペアプロ・モブプロで開発をした経験がある
- CCPMに関する基本的な知識がある
- 予算管理は除いたPMとしてCCPMでマネジメントした経験がある
- TDDの外部トレーニング(Scrum Developer Technical Training)と社内勉強会を実施したことがある
- SPA(フロントVue.js, バックRailsやLambdaなど)で開発できる

## Ruby on Rails
- 1人で仕様の調整を行い、実装できる
- コードレビューを通して、若手エンジニアにRailsを教えられる
- 勉強会に参加したり、登壇したことがある
- アプリアーキを設計した経験がある
  - ドメインモデルではなくトランザクションスクリプトで設計

## JavaScript
- ES2015の基本的な文法を知っている
- jQueryで教えられる
  - 自作でアーキテクチャを考えたことがある
     - 結局JQueryでは地獄でしたがw
- Node.jsで実装した経験がある
  - Expressで実装した経験がある
- Vue.jsで実装した経験がある
  - Vuexを使って実装できる
  - Rails + Vue(SPA)で実装できる

## HTML/CSS
- 時間をかければ一人で実装できる
- Adobe XDを元に時間をかければ一人で実装できる
- CSSフレームワークはFLOCCSで実装した経験がある
  - Atomic Designは知識だけで経験はない
- プロジェクトにコードを真似して実装できる
- デザインテンプレートはMaterializeとBootstrapを使った経験がある
- デザイン設計は出来ない

## DB
- SQLの基本的な知識がある
- パフォーマンスを意識したSQLを読める(LateralとかDistinct onとか)
    - 書いたことはないですが、読めるので多分書くこともできます
- RDBMSの実行計画が少しだけ読める
- 概念モデルから考えることができる
- AWS DynamoDB + AWS AppSync(GraphQL)を使って設計・開発できる

## インフラ
- AWS ElasticBeanstalkを使ってRuby on Railsのインフラ環境を構築した経験がある
- GCP、Azureは未経験

## 開発環境
- AWS Amplify(Vue.js + AppSync(DynamoDB) + Lambda)を使って開発環境を構築できる
  - Aurora Serverlessを使って実装しようとしましたが、Appsyncとの相性がまだまだの部分があり断念
- Gitlab周りの環境を整えられる
  - Issue/MRテンプレート機能など
- CI/CD環境をコードベースで構築できる
- 静的解析（Lint）の設定をした経験がある

## コーチング・ファシリテーション
- スクラムマスターとしてチームをコーチングした経験がある
- 各メンバと1 on 1をした経験がある
- スプリントプランニングやふりかえりでファシリテーションをすることができる
- メンターを依頼された経験がある

## その他
- リリースにあわせてGitのブランチ運用を提案できる
- Management3.0のプラクティスを利用してチームビルディングをした経験がある
- ETLで実装ができる
  - SAS Enterprise Guideを経験
- BIで実装ができる
  - SAS Visual Analyticsを経験

## 興味のあること
- チーム・組織を一緒に改善していくこと（継続中）
  - 心理的安全性
  - ティール組織
- 新しい言語の習得（Java, Golang, Reactなど）
- DDD
- 働き方の改善
Dockerコンテナ内でpingを実行するための備忘録

pingコマンドが実行できなかったため、以下でインストールしようとしましたが、できませんでした。

```
apt-get install iputils-ping
```

エラー、、、

```
E: Unable to locate package iputils-ping
E: Unable to locate package net-tools
```

以下で、インストール可能なパッケージの一覧を最新にしたのち、再びインストールを行ったらできました。

```
apt-get update
```
再帰を用いて基本的な関数をPythonで書いてみたメモ

再帰を理解するのに苦労したので自分用にまとめておこうと思い書いたメモです。今後も追加するかもしれません。
言語はPython3です。

# 再帰関数とは
- 再帰関数とは、関数の中で自分自身を呼び出すような関数
- 必ずどこかで終了するように実装しなければならない
- 大きな問題を小さな問題に分割して解決する**分割統治法**で使われる手法

# 1からnまでの和を求める再帰関数
```python:sum.py
def sum(n):
    if n <= 1:
        return n
    return n + sum(n-1)
    
print(sum(100))    # 5050
```
```python:sum.py
def sum(n):
    res = 0
    if n >= 1:
        res = n + sum(n-1)
    return res

print(sum(100))    # 5050
```

# nの階乗を求める再帰関数
```python:factorical.py
def fractorial(n):
    if n <= 1:
        return n
    return n * fractorial(n-1)
    
print(fractorial(5))    # 120
```

```python:factorical.py
def factorial(n):
    res = 1
    if n >= 1:
        res = n * factorial(n-1)
    return res
   
print(factorial(5))    # 120
```

# リストの各要素を2倍にしたリストを求める再帰関数

```python
def double_list(lst):
    if lst == []:
        return []
    
    first = lst[0]
    rest = lst[1:]
    
    return [first*2] + double_list(rest)
    
print(double_list([1,2,3]))    # [2, 4, 6]
```
分かりやすい解説は、[こちら](https://qiita.com/dhirabayashi/items/2f079e62fa2e286f1766#fnref1)

# ユークリッドの互除法
```python:euclidean.py
def gcd(m, n):
    r = m % n
    if r == 0:
        return n
    return gcd(n, r)

print(gcd(1071, 1029))   # 21
```



# 参考
[再帰関数を理解するための最もシンプルな例](https://qiita.com/jumpyoshim/items/20e6b5e70efa466699b4)
[Pythonで理解する再帰関数]
(https://qiita.com/dhirabayashi/items/2f079e62fa2e286f1766)
[Pythonで再帰関数を理解する]
(https://note.com/shimakaze_soft/n/nf17633fe257c)
[ループを再帰関数にする考え方](https://qiita.com/ozwk/items/4ffdba8e83df1171ac39)

# 感想
再帰ってなかなかイメージしずらくて今も苦労してます…
コードの見た目はシンプルになる気がするのですが、どう動いているのかを理解するのに時間がかかってしまいます。その点for文はわかりやすいですよね。
20200228 Learning Plan

1.javaに関する、基本的な知識をまとめる
  ①Java知識
　②Java　各バージョン　特徴

2.Spring Framework
　①特徴をまとめて
　②project 構築

3.JavaScript Framework
   ①vue.js project 構築

4.DBに関する基本的な知識をまとめる

5.ビジネス日本語