OmniAICreator/Qiita-1.07M huggingface dataset:
ゼロから作るDeepLearning3 フレームワーク編の感想をかく

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/248638/66ea69bf-7280-033e-bd46-09ae68d1c6b3.png)


　年末2、3日かけて、現在公開レビュー中の[ゼロから作るDeepLearning❸ フレームワーク編](https://note.com/koki0702/n/na9bf716aca97)（ゼロD3[^1]）をやってみました。個人的には、無印以上に良本だった気がするので、どこが魅力だったのか、どういう人が読むとハッピーなのかを書ければと思います。

# 内容と感想
　Numpyを用いたスクラッチ実装を通して、最近のフレームワーク（PyTorchやChainer）をコードレベルで理解する内容でした。フレームワーク編というだけあって、DLだけでなく、効率的なコードの書き方や、フレームワークの根幹であるDefine-by-runの設計思想などにもフォーカスされていました。

一通りやってみて、感じたこと、得られたことがいくつかありました。順番はテキトウです。

#### - Backpropの重要性
　無印以上に何度も出てきた気がします。全部で5ステージ（章）ありましたが、そのうち2ステージがBackpropに関するものでした。

　具体的には、基本的な微分とBackpropから、自動微分（AutoGrad）や高階微分、ニュートン法の説明、実装など無印では扱われていない新しい部分が結構ありました。まさしく、No Backprop, No Deep Learningなんだろうなと感覚的に思いました。

#### - Define-by-runとDefine-and-runの違い
　この説明が一番最初ではなく、ある程度読み進めた後に出てきたのが印象的でした。ノードやinput, creator, outputなどの説明の後にがあったので、両者の違いをスムーズに理解できる構成になっているなと思いました。

#### - フレームワーク（とりわけPyTorch）への入りがスムーズになる
　それを目的にしているから、そりゃそうですが、本書を読むとかなり意識されていることがわかります。PyTorchを触れたことがない場合、これは大きいのではないかなと思います。

　一例として、PyTorchの学習時に以下のようなコードを書くと思います。本書では赤線部に該当するコードが背後でどのように動いているのかを実装レベルでカバーしていました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/248638/8e7ebef6-c580-44b3-6c2a-1853b713e916.png)

　今春に出版される[PyTorch公式本](https://www.manning.com/books/deep-learning-with-pytorch)も読めるようになっていたので読んでみましたが、あくまで使い方の説明に留まっていた印象でした。その点で本書はユニークであり、著者が言うようにほとんど類書がないと思いました。[^2]

#### - Python自体の知識
　Pythonの特殊メソッドを使用する場面が度々あり、個人的には普段あまりみないメソッドも使われていました（ __ _rmul___など）。

　また、x * w + b で使われている演算子（+や*など）には使用条件がある話や、演算量が膨大になってくるため、どのようにメモリ管理を行うのかなどにも触れていました。

#### - 高揚感
　PyTorchなどのフレームワークを使ったことがある場合に限りますが、本書が後半になるにつれ、段々と見覚えのあるコードに近づいてきます。なんとなく理解していたPyTorch一行一行の背景が繋がっていく高揚感が個人的にありました。

　例えるなら、普段電車で行く目的地に徒歩で辿りついて、脳内のマップが拡張される感覚です（この道がここに繋がっていたのか、の方がイメージとして近いかもです）。


# ゼロDシリーズ内での位置付けを考える
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/248638/b1438c95-c4e3-5f85-2f15-ebb621c3b3af.png)

　本書はあくまでフレームワークがメインテーマなので、前半は細かいメソッド（transposeなど）の実装やメモリ管理手法などにも紙面が割かれていました。

　ただ、本書後半になってくると、フレームワークの土台が固まり、Optimizer、Loss、CNN、LSTMなどの実装に話が移っていきます。無印と内容の似る部分がそこそこ出てくるため、numpyやPythonの使い方がある程度わかっていれば、ゼロD3から初めてもそこまで問題ないかなというのが個人的な印象です。

　自然言語（NLP）に関してはノータッチでしたが、時系列分析と言う文脈でRNN、LSTMが紹介されていました。そのため、NLP自体をがっつり知りたい場合はゼロD2になります。

# どういう人が読むとハッピーなのか考える
　本書の特徴は、DL自体の説明だけでなく、"コードを通じてフレームワークそのものの成り立ちを理解する"だと思います。今までの書籍は、"DL自体の説明＋Numpy実装" or "DL自体の説明＋フレームワークの使い方"のどちらかを提供するものが多かった印象です（自身の少ないサンプルなので実態はそうではないかもしれないですが）。

　私自身が陥ったケースとして、DL、Numpy、フレームワークがざっくりとわかり、フレームワーク単体で動かす分にはそこまで問題ないが、実際の理解との間に隔たりがありました（橋渡しができていない状態）。

　そのため、PyTorchを使ったことがある方にとって本書は、Numpy or 数式とPyTorch間の結びつきを強める価値を提供しているのではないかと思います。

　一方、DLに興味はあるがフレームワークを使用したことがない方にとって本書は、スムーズにフレームワークに移行するtransition的な価値を提供していると思います。


# おわりに
　実用性関係なく、ブラックボックスを1つ1つ解き明かすこと、また既知のもの同士に関係性を見つけて両者を繋げる面白さがありました。まだ理解が十分でないこともあり、何周かしたいと思える一冊でした。

　[1 / 13まで公開レビューしている](https://note.com/koki0702/n/na9bf716aca97)ようなので、レビューしつつ読んでみると面白いかもしれません。




[^1]: 略称がわかってないです。ゼロD、ゼロDeep、ゼロつくどれなんでしょう。
[^2]: fast.aiの[Deep Learning from the Foundations](https://course.fast.ai/part2.html)が立ち位置としては近いかなと思います。こちらはPyTorchを用いてfastai libraryを実装するという内容です。ゼロD3より圧倒的に難しく、カバー範囲は広いです。
PRNet in PyTorch 1.1.0のテスト

PRNet_PyTorchのチュートリアルを一通り動かした時のメモです.

https://github.com/YadiraF/PRNet


#NVIDIA　CUDA環境で学習ー推論を一通り実行する.

minicondaを今回は使用

```
$ conda create -n prnet python=3.6
$ conda activate prnet
$ git clone https://github.com/tomguluson92/PRNet_PyTorch.git
$ cd ./PRNet_PyTorch 
```

パッケージをインストール

```
$ pip install -r requirements.txt 
```

##uv_pos_mapの生成


BFM.mapと300WLP_IBUGデーターセットのダウンロードを行います



```

$ cd ./utils
$ mkdir BFM
$ mv ./BFM_UV.mat  ./BFM
$ cd ./BFM
```
以下の.shでGドライブからBFM.matをダウンロードできるので./BFM内に落とす.

```bash
FILE_ID=1Bl21HtvjHNFguEy_i1W5g0QOL8ybPzxw
FILE_NAME=BFM.mat


curl -sc /tmp/cookie "https://drive.google.com/uc?export=download&id=${FILE_ID}" > /dev/null
CODE="$(awk '/_warning_/ {print $NF}' /tmp/cookie)"  
curl -Lb /tmp/cookie "https://drive.google.com/uc?export=download&confirm=${CODE}&id=${FILE_ID}" -o ${FILE_NAME}
```

```
cd ..
mkdir dataset
cd ./dataset
```

次は300WLPデーターセットを落とします
これも.shから実行可能です.



```bash
FILE_ID=16zZdkRUNdj7pGmBpZIwQMA00qGHLLi94
FILE_NAME=300WLP_IBUG.zip


curl -sc /tmp/cookie "https://drive.google.com/uc?export=download&id=${FILE_ID}" > /dev/null
CODE="$(awk '/_warning_/ {print $NF}' /tmp/cookie)"  
curl -Lb /tmp/cookie "https://drive.google.com/uc?export=download&confirm=${CODE}&id=${FILE_ID}" -o ${FILE_NAME}

```

```
unzip 300WLP_IBUG.zip 
mv 300WLP_TEST\ \(copy\) 300WLP_IBUG
```

pythonでデーター整形を行う.

```
 python generate_posmap_300WLP.py --input_dir ./dataset/300WLP_IBUG --save_dir ./300WLP_IBUG/
cd ..
```

これで学習の準備が整うはずなのでtrainします

```
python train.py --train_dir ./utils/dataset/300WLP_IBUG
```

40分ぐらいでデフォルトの設定だと終了します(GTX1080Ti+CUDA10.1)


```
python inference.py 
```


テスト用画像はデフォルトの設定で推論が可能です.
![Screenshot from 2020-01-01 03-04-10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/232732/368f34e4-c5db-6654-0699-95b296673ed8.png)
🔰blue prismの無料トライアルセットアップ方法や製品ドキュメントが公開されている場所

blue prismは外向けに情報がほとんど出ていないので、何ができるか迷うよね😣😥👎
なので、公開されている情報をひとまずまとめてみたよ😘✨

# 前提: Blue Prism ポータルへの登録方法

ポータルアカウントを入手してログインすると、製品ドキュメント、学習リソース、技術情報などを入手できるようになるよ😘✨

* [ポータルへの登録](https://www.blueprism.com/japan/resources/blog/blue-prism-onboarding-01/)

# トライアルへのセットアップ方法

大きく4種類準備されているから、用途に応じて申請してね😘✨

* AFT: [Blue Prism 無償評価版 on Azure Marketplace セットアップ方法](https://www.blueprism.com/japan/resources/blog/blue-prism-microsoft-azure-marketplace/)
* OFT: [Blue Prism 6.6オンプレミスでの無償評価版入手方法](https://www.blueprism.com/japan/resources/blog/blue-prism-v6_6-free-on-premises/?selected-locale=japan)
* LE: [Blue Prism Learning Editionオンプレミス](https://www.blueprism.com/japan/resources/blog/blue-prism-learning-edition/?selected-locale=Japan)
* 通常版: [Blue Prismに問い合わせる](https://www.blueprism.com/japan/contact/?selected-locale=Japan)

違いは「[Blue Prism を無料で試したい人への簡単なまとめ](https://www.ebocean.work/entry/2019/11/02/134626)」にまとまっているよ


>||AFT|OFT|LE|通常版|
|:--|:--:|:--:|:--:|:--:|
|費用|無償|無償|無償|有償|
|配置|クラウド|オンプレ|オンプレ|どこでも|
|インストール|なし|あり（簡易）|あり（簡易）|あり|
|最大同時実行|1|1|1|契約次第|
|開発可能プロセス|15|15|5|∞|
|利用期間|30日|30日|90日|契約次第|


# 製品概要

## 公式

* [公式ホワイトペーパー一覧](https://www.blueprism.com/japan/resources/additional-resources/?category=analystReports,whitePapers)
    * [Blue Prism 概要説明 2019年版 36p](https://rpa-bank.com/pdf/document-dl/blue_prism.pdf) (PDF)
    * [Blue Prism の特長 (日本語資料) 39p](https://www.blueprism.com/uploads/resources/white-papers/Blue-Prism-の特長-Web公開用.pdf) (PDF)
    * [はじめよう! Blue Prism - Blue Prism Onboarding資料](https://www.blueprism.com/japan/resources/additional-resources/blue-prism-onboarding-material-jp/)
    * [Blue Prism 製品概要チラシ2p](https://www.blueprism.com/uploads/resources/white-papers/Blue-Prism製品概要.pdf) (PDF)
    * [Blue Prism ハンズオン資料 1 (zip 形式圧縮ファイル)](https://pages.blueprism.info/rs/544-MLV-234/images/JP_Blue%20Prism_Hands-on_1.zip)
    * [Blue Prism ハンズオン資料 2 (zip 形式圧縮ファイル](https://www.blueprism.com/japan/resources/white-papers/blue-prism-handson-2/?selected-locale=Japan))
* [Blue Prism Japan YouTubeチャンネル](https://www.youtube.com/channel/UCvupYxgzBNmVAXCLrufx7_w)
    * [Blue Prism 6.5.0 開発デモ（基本編）](https://www.youtube.com/watch?v=iKQffL6sNI0)
    * [Blue Prism ハンズオン実演動画](https://www.youtube.com/watch?v=as6rzapmGqs)
* [Blue Prism ブログ](https://www.blueprism.com/japan/resources/blog/)

## 非公式

* [🔰blue prismの標準VBOとDXで入手できる主なVBO](https://qiita.com/KamiyaMT/items/67e81d8e74218b2f7fc6)
* [Enterprise Blue Ocean ◮  神谷町RPAブログ](https://www.ebocean.work/)
* [神谷町RPAブログ YouTube](https://www.youtube.com/channel/UCnGfQMBvbkbIJfW3_ifv9Fw)
* [じんさんのメモ: RPA「Blue Prism」の個人的な学習メモ。](https://jinsaan.hatenablog.com/archive)
* [はこふぐのメモ](https://www.hakofugu.work/archive)
* [RPAエンジニアの雑記](https://newgraduate19-rpa.hatenablog.com/)
* [ONE HUMAN UNIT](https://ciprogram.jp/tag/blueprism/)
* [Blue Prism - RPA Wiki](https://rpawiki.xsrv.jp/index.php?title=Blue_Prism)
* [Falcslab](https://falcslab.com/)
Zshでanacondaの仮想環境を使う（不具合対応）

# 概要
[pyenvでインストールしたanacondaのJupyter Notebookをzshで使う（不具合対応）](https://qiita.com/aohsaki/items/9fbd952aad6dbc6417a6)に続き，ZshでJupyter Notebookを使うための試行錯誤を備忘録としてまとめておく．

# 不具合状況
- `$ conda info -e`で仮想環境が確認できるにも関わらず，`$ conda activate <仮想環境名>`でアクティベートできない


# 環境
Mac OS Mojave


# 方法
#### 1. 仮想環境の実行をトライする
``` code:Terminal
$ conda activate <仮想環境名>
``` 

返ってきたエラーメッセージ

``` code:Terminal
CommandNotFoundError: Your shell has not been properly configured to use 'conda activate'.
To initialize your shell, run

    $ conda init <SHELL_NAME>

Currently supported shells are:
  - bash
  - fish
  - tcsh
  - xonsh
  - zsh
  - powershell

See 'conda init --help' for more information and options.

IMPORTANT: You may need to close and restart your shell after running 'conda init'.
```
#### 2. イニシャライズ
``` code:Terminal
$ conda init <SHELL_NAME>　※今回は”zsh”
```

#### 3.シェルの再起動
``` code:Terminal
$ exec $SHELL -l
```

### 余談. シェル再起動後の対応
シェルを再起動したら，プロンプトが`(base) <ユーザー名>%`となっていた．Pythonのベース環境内に入ってしまっているようだったので`$ conda deactivate`で仮想環境を終了．


# 参考にさせていただいたサイト
- [Pythonメモ-50 (conda 4.4.6 にしたら fish shell 上で activate 出来なくなった) (conda, activate, fish)](https://devlights.hatenablog.com/entry/2018/01/08/204810)
webpack outputプロパティ

# outputプロパティとは
バンドルファイルの**パス**と**名前**を設定するもの。

```js:webpack.config.js
const path = require('path');

module.exports = {
  entry: './src/index.js'
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'main.js'
  }
};

// ./dist/main.jsが生成される
```

`__dirname`⋯プロジェクトのルートディレクトリの絶対パスの文字列が入った特別な変数。

`path`⋯Node.jsモジュールでデフォルトで使える。
これは第一引数と第二引数のパスの文字列を繋げて、新たにパスを作る。
指定するパスがOSによって異なることを防ぐために使用する。
`/hoge/dist`のように展開される。[参考](https://nodejs.org/api/path.html#path_path_resolve_paths)
（```path: `${__dirname}/dist` ```このように指定してもいい）

# pathプロパティの省略
`path`プロパティを省略することもできる。
=> プロジェクトのルートディレクトリ直下の`dist`ディレクトリ配下に生成される。

```js:webpack.config.js
module.exports = {
  output: {
    filename: 'foo.js'
  }
};

// ./dist/foo.jsが生成される
```

# 複数のエントリーポイントをそれぞれ出力したい場合
```js:webpack.config.js
const path = require("path");

module.exports = {
  entry: {
    foo: './src/foo.js',
    bar: './src/bar.js'
  },
  output: {
    path: path.resolve(__dirname, "dist"),
    filename: "[name].js"
  }
};

// ./dist/foo.jsと./dist/bar.jsが生成される
```

`[name]`プレースホルダーには`entry`のキーがそれぞれ入る。
（この場合は`output`プロパティを省略しても結果は変わらない）

他には以下のようなプレースホルダーがある。

* `[id]`⋯`entry`オブジェクト内でのインデックス値
* `[hash]`⋯バンドル全体で生成されたハッシュ値
* `[chunkhash]`⋯エントリーポイントごとに生成されたハッシュ値
* [more](https://webpack.js.org/configuration/output/#outputfilename)

つまりこのような設定ファイルだと

```js:webpack.config.js
const path = require("path");

module.exports = {
  entry: {
    foo: "./src/bar.js",
    baz: "./src/qux.js"
  },
  output: {
    path: path.resolve(__dirname, "dist"),
    filename: "[id]-[name]-[hash].js"
  }
};
```

このように出力される。

![スクリーンショット 2020-01-01 15.44.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308460/611b9156-9d81-440d-ff68-32b7a3f45723.png)

`[hash]`と`[chunkhash]`は同時には使えない。
最新のAndroidXのライブラリをローカルのmavenリポジトリにpublishして使う

# 概要
前に以下の方法を紹介していたのですが、普通にもっとすごく簡単にpublishできたので紹介しておきます。
https://qiita.com/takahirom/items/2dc95780586f6114b825

# 下準備
以下の方法でローカルにソースコードをダウンロードできます。
https://qiita.com/yuichi_araki/items/a8db45e5aa1daad8152e

# ローカルのmavenリポジトリにpublish

ダウンロードした後に以下のコマンドでローカルのmavenにpublishできます。

```
cd frameworks/support
./gradlew publishMavenPublicationToMavenLocal
```

そうすると以下フォルダにAndroidXがpublishされていることが確認できます。

```
$ ls ~/.m2/repository/androidx/
activity              benchmark             contentpager ....
```

フォルダまで行けばpublishされたバージョンも確認できます。

```
$ ls ~/.m2/repository/androidx/work/work-runtime-ktx/
2.3.0-rc01
```

# 使い方

これを使うにはrepositoryに`mavenLocal()`を追加してあげて、使いたいライブラリ、例えば、`implementation 'androidx.work:work-runtime-ktx:2.3.0-rc01'`のようにdependenciesを追加してあげれば使うことができます。


```gradle
allprojects {
    repositories {
        google()
        jcenter()
        mavenLocal() ←　追加
    }
}
```
Bash の alias に date コマンドの結果をセットする

## エイリアス機能

[bash\(1\) — manpages\-ja — Debian buster — Debian Manpages](https://manpages.debian.org/buster/manpages-ja/bash.1.ja.html)

> エイリアス(alias) を使うと、 ある単語が単純なコマンドの先頭の単語として使われた場合に、 この文字列を別の単語に置換できます。

[bash\(1\) — manpages\-ja — Debian buster — Debian Manpages](https://manpages.debian.org/buster/manpages-ja/bash.1.ja.html)

> alias [-p] [name[=value] ...]
> 
> alias コマンドを引き数を付けずに (あるいは -p オプションを付けて) 実行すると、エイリアスのリストが 「alias name=value」の形で標準出力に出力されます。 引き数を与えた場合には、value を与えられた name それぞれに対するエイリアスが定義されます。

## alias に date コマンドの結果をセットする

alias コマンドで設定する際にダブルクォートで囲むと、エイリアスを設定したときの日時がセットされてしまう。

```
$ alias hello="echo $(date +%Y%m%d_%H%M%S)"

$ alias hello
alias hello='echo 20200101_151545'
```

シングルクォートで囲むと date コマンド自体がセットされる。
これでエイリアスを実行したときに date コマンドが実行されるようになる。

```
$ alias hello='echo $(date +%Y%m%d_%H%M%S)'

$ alias hello
alias hello='echo $(date +%Y%m%d_%H%M%S)'

$ hello
20200101_151630
```

## コマンド置換機能

$() とか バッククォートで囲む \`\` のはコマンド置換と呼ばれる機能。

[bash\(1\) — manpages\-ja — Debian buster — Debian Manpages](https://manpages.debian.org/buster/manpages-ja/bash.1.ja.html)

> コマンド置換 (command substitution) を用いると、 コマンド名をコマンドの出力で置き換えられます。 コマンド置換には以下の 2 つの形式があります:
> 
> $(command)
> 
> または
> 
> \`command\`
> 
> bash は command を実行し、 command の標準出力でコマンド置換の部分を置き換えます。
PowerShell でも名前空間を作りたい

本記事は PowerShell Advent Calendar 2019 の 12 日目です。

# はじめに

C# では `namespace` キーワードで名前空間を定義することができますが、
PowerShell ではそういった構文が提供されておらず、全ての変数、関数などの要素は
いわゆるグローバル名前空間に定義されています。

規模が小さいスクリプト群なら特に問題ないですが、
規模が大きくなると名前の衝突がしやすくなり、命名が面倒になってきます。

例えば、 Scoop の [scoop-install.ps1 - Scoop - GitHub](https://github.com/lukesampson/scoop/blob/master/libexec/scoop-install.ps1#L19) の箇所では、
他のファイルで定義された関数をドットソースで読み込んでいますが、
読み込んでいるスクリプトファイル間で同じ関数名を定義してしまうと、
意図しない関数を使ってバグが起きる危険性が潜んでいます。

# PowerShell Module の Prefix で疑似的に名前空間を作る

名前空間単位にモジュール化させ、それぞれのモジュールに Prefix を指定することで、
名前空間の宣言と似たようなことができます。

図でいうと以下です。

<img width="960" alt="ps_module_prefix.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114728/81ea330f-dc35-7672-eb57-b190f2ed99d7.png">

`Import-Module` の `-Prefix` に MyModule を指定することで、
`Get-Something` の名詞部分に接頭辞が付き、 `Get-MyModuleSomething` で呼び出すことができるようになります。

また、PowerShell モジュールマニフェストファイルで
`DefaultCommandPrefix` を指定することでも同じように Prefix を指定することができます。

この記事での説明はここまでですが、 [DockerCompletion](https://github.com/matt9ucci/DockerCompletion) でそういう実装がされているので、参考にしてみてください。

# おわりに

クラス構文だとこういうのできないので、どうすればよいものか。
C#書いて、 `Add-Type` するしかないのかな。
springでパターンにマッチする複数のResourceを得る

たとえば、クラスパス直下のすべてのxmlファイルの```Resource```を得る場合、以下のようにする。

```java
PathMatchingResourcePatternResolver resolover = new PathMatchingResourcePatternResolver();
Resource[] resources = resolover.getResources("classpath:*.xml");

for (Resource resource : resources) {
  System.out.println(resource);
}
```
AWS Cloud9の罠

## AWS Cloud9で引っ掛かかった地味な罠

#### Cloud9の仕様 (一部想像あり)
- Cloud作成時は作成者のIAM情報をOWNER情報として保持する(大体以下の何れかのはず)
  - IAMユーザ
    <br>`arn:aws:iam::<アカウントID>:user/<ユーザ名>`
  - ルートユーザ
    <br>`arn:aws:iam::<アカウントID>:root`
  - ロールを引き受けたユーザ(ロールを引き受けたフェデレーションユーザ)
    <br>`arn:aws:sts::<アカウントID>:assumed-role/<スイッチロール名>/<セッション名(スイッチ元ユーザ名)>`
- 複数人でCloud9を扱う場合、OWNER権限を持つ人が利用したいメンバーに許可を出す必要がある。
    <br>\# 権限を付与しない限り同一アカウントであれどIDEを開くことができない。

#### 何があったか
**前提：**
  - 自社のAWSアカウントで調査という名目でCloud9を弄っていた
  - Cloud9を弄っているのは私1人だった

**事件：**
- 社内で色々有り私のIAMユーザ権限が更新され、これまで利用していたロールが使えなくなった
- そのため、私のIAM情報が、環境に保持されているOWNER情報とは異なる状態になった
    <br>\# 諸事情で元のロールにスイッチできる権限は剥奪された
- 結果として私が構築したCloud9環境に接続できなくなってしまった。
    <br>\# GitにCommit出来ていないソースが有ったので泣いた

#### どう対応したか
結論だけで言えば泣きながら環境を作り直した。  
上述している物は作り直し終わった後に調べた結果分かったものである

#### 未Commitソースを失わないためにどうすればよかったか
以下のようにしてCloud9にアクセスできる状態にすると良かった。
- AWS CLIを利用して権限を付与したユーザ/ロールを引き受けたユーザを招待する。
  <br>\# CLIの実行環境で、AWSCloud9Administratorポリシーを持つロールを利用できる認証設定にしておくこと
  <br>\# create-environment-membershipさえ利用できればいいので、公式ポリシーをつけるのが嫌ならカスタムポリシーでも問題ない
<br>[公式より](https://docs.aws.amazon.com/ja_jp/cloud9/latest/user-guide/share-environment.html#share-environment-admin-user)

```
aws cloud9 create-environment-membership --environment-id <Cloud9のID> --user-arn <ユーザARN> --permissions <与える権限>
```
  - <Cloud9のID>： Cloud9コンソール > Environment ARN の[environment:]以降のランダム文字列
  - <ユーザARN>： 上述仕様のIAM情報の形式
  - <与える権限>： read-write, read-only のどちらか
- (私はダメだったが) Cloud9を作った時点のロールにスイッチできるようにIAM権限を戻す

#### 私と同じ悲劇を引き起こさないために
- ロールを引き受けたユーザがOWNERだと、権限変更が起きるとOWNER情報をロストして面倒なことになる場合があるため、スイッチロールしない素のIAMユーザでCloud9を作ってソイツにOWNER権限持たせておこう
- 自分1人しか使っておらず絶望することになっても、AWS CLIで何とかread-writeユーザを増やせるのであきらめるには早い
- 当たり前すぎるけど **定期的にCommitはしておこう！**
webpack4で複数のエントリポイントに応じたjs,cssファイルを出力する

複数のエントリポイントから一回のビルドコマンドで別々のjs, scss等のバンドルファイルを出力したい。

```ディレクトリ構成
root
│  package.json
│  package-lock.json
│  webpack.config.js
│
├─assets
│  │  
│  ├─dist
│  │  ├─ js   
│  │  │  ├─A.js    
│  │  │  └─B.js
│  │  └─ css    
│  │     ├─A.css 
│  │     └─B.css
│  │
│  ├─js
│  │  ├─A.js 
│  │  ├─B.js
│  │  └─modules
│  └─sass
│     ├─A.scss 
│     ├─B.scss
│     └─modules
│        
└─node_modules
```

modules以下を使用して構成される[name].js及び、[name].scssから、
distのjs,css配下に[name].js及び[name].cssをbundleとしてそれぞれ生成するイメージです。

ページ単位でレイアウトとフロントに持たせる機能が全く異なるアプリケーションを作っていて、適用させる静的ファイルを完全に分けたいケースに直面したのでメモ。

bundleをcssファイルとして出力したい場合、webpack4より前では[extract-text-webpack-plugin][1]を使用して実現することができましたが、4からはcssでの利用は非推奨になっております。
> Since webpack v4 the extract-text-webpack-plugin should not be used for css. Use mini-css-extract-plugin instead.
> <cite>[https://github.com/webpack-contrib/extract-text-webpack-plugin#usage]</cite>

そのため、[mini-css-extract-plugin][2]を使用します。

```webpack.config.js
const path = require("path");
const MiniCssExtract = require("mini-css-extract-plugin");
const assets = path.join(__dirname, "./root/assets/");
const dist = assets + "dist/";
const froms = {
  js: {
    A: assets + "js/A.js",
    B: assets + "js/B.js"
  },
  scss: {
    A: assets + "sass/A.scss",
    B: assets + "sass/B.scss"
  }
};

module.exports = {
  mode: "development",
  entry: {
    A: froms.js.A,
    B: froms.js.B,
    "A.css": froms.scss.A,
    "B.css": froms.scss.B
  },
  output: {
    filename: "js/[name].js",
    path: dist
  },
  module: {
    rules: [
      {
        test: /\.scss/,
        use: [
          MiniCssExtract.loader,
          "css-loader",
          "sass-loader"
        ]
      }
    ]
  },
  plugins: [
    new MiniCssExtract({
      filename: "css/[name]"
    })
  ],
};

```

ただしこれだと、dist/jsの配下にA.css.js, B.css.jsという余計なファイルまで出力されてしまって煩わしいです。

## webpack-fix-style-only-entriesを使用する

[webpack-fix-style-only-entries][3]というライブラリを使用します。
npmインストールしてライブラリの読み込み

```webpack.config.js
const FixStyleOnlyEntries = require("webpack-fix-style-only-entries");
```
pluginsに追記

```webpack.config.js
plugins: [
    new FixStyleOnlyEntries(),
    new MiniCssExtract({
      filename: "css/[name]"
    })
  ],
```

ビルド

```package.json
"scripts": {
  "build": "webpack"
}
```

```
$ npm run build
```
これで余計なjsのbundleファイルが生成されずに済みます。

[1]:https://github.com/webpack-contrib/extract-text-webpack-plugin 
[2]:https://github.com/webpack-contrib/mini-css-extract-plugin 
[3]:https://github.com/fqborges/webpack-fix-style-only-entries
[ABAP]半角・全角・混在チェックVer1.1(Whether Text is SBC only, DBC only or Mixed)


最初の投稿時以降に、もっと簡単な書き方を思い出しましたのでコードと記事を更新しました:smirk:


Unicode環境における半角・全角混在チェックとなります。
今回、CL_ABAP_LIST_UTILITIESのメソッドと、STRLENを使って
文字列の、「半角のみ」「全角のみ」「半角全角混在」をチェックします。

#####表1：コード内で使用している各文字数・バイト数算出コマンド・メソッドについて

|内容     |説明  |
|:-:|:-:|
|STRLEN|文字数|
|DYNAMIC_OUTPUT_LENGTH|入力された文字の総バイト数|
|DEFINED_OUTPUT_LENGTH|定義長(CHAR30は30)|
|MAXIMUM_OUTPUT_LENGTH|最大バイト長(CHAR30は30*2バイトで60)|


#####表2：判定条件

|条件  |判定  |
|:-:|:-:|
|文字数     ＝ バイト数  |半角のみ                 |
|文字数 * 2 ＝ バイト数  |全角のみ                 |
|上記以外               |半角全角混在             |

今回表2にあるチェックロジックは、CONDを使用して、文字数*2の変数Xを内部で定義して
判定し、そのままCL_DEMO_OUTPUT=>WRITEに書き込むという、ABAPDOCUのような書き方で書きました。

```ABAP:YTEST_SBCDBC_CHECK

REPORT YTEST_SBCDBC_CHECK.

PARAMETERS: P_STR TYPE CHAR30 lower case obligatory.

* 設定値の文字数
DATA(W_STR) = STRLEN( P_STR ). "設定値の文字数
* 設定値のバイト数
DATA(W_DYN) = CL_ABAP_LIST_UTILITIES=>DYNAMIC_OUTPUT_LENGTH( FIELD = P_STR ).
* 設定項目の定義長
*data(W_DEF) = CL_ABAP_LIST_UTILITIES=>DEFINED_OUTPUT_LENGTH( FIELD = P_STR ).
* 設定項目の最大バイト数
*data(W_MAX) = CL_ABAP_LIST_UTILITIES=>MAXIMUM_OUTPUT_LENGTH( FIELD = P_STR ).

CL_DEMO_OUTPUT=>WRITE( |{ P_STR } | ).
CL_DEMO_OUTPUT=>WRITE( | STRLEN { W_STR } | ).
CL_DEMO_OUTPUT=>WRITE( | DYNAMIC { W_DYN } | ).
*CL_DEMO_OUTPUT=>WRITE( | DEFINITION { W_DEF }| ).
*CL_DEMO_OUTPUT=>WRITE( | MAXIMUM { W_MAX }| ).

* 全角半角判定を行い、結果を書き込む
CL_DEMO_OUTPUT=>WRITE(
  cond #( LET X = W_STR * 2 in
    when w_str = W_DYN then | すべて半角です |
    when X = W_DYN then | すべて全角です |
    else | 全角と半角が混在しています | ) ).

CL_DEMO_OUTPUT=>DISPLAY( ).
```
結果サンプルです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/326392/fd49b27e-1469-2704-df97-20c08c41cc87.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/326392/e14bf42b-7111-d6cb-7936-b3e536df6782.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/326392/971ee475-eaa1-6781-21c2-df326d8f12f9.png)

前のコードも一応残しておきます・・・
<details><summary>1文字づつ文字が半角か全角かを確認するやり方</summary><div>

```ABAP:zcheck_1byte2byte

REPORT zcheck_1byte2byte.

parameters: p_str type string.

data(CHAR_NUM) = strlen( p_str ).

DO char_num times.
* 文字を1文字づつ取得
data(moji) =
  CL_HRPADJP_CHARACTER_UTILITIES=>GET_NTH_CHAR( IV_STRING = p_STR
                                                iv_pos = sy-index ).

data(moji_after) =  moji.
* mojiを1バイト分のみとする→半角文字：同文字、全角文字:null
call method CL_HRPADJP_CHARACTER_UTILITIES=>ADJUST_STR_LEN
  exporting IV_TAR_LEN = 1
  changing  CV_TXT     = moji_after.

if moji = moji_after.
* 半角
  cl_demo_output=>write( | { moji } { moji_after } 半角 | ).
else. "全角
  cl_demo_output=>write( | { moji } { moji_after } 全角 | ).
endif.

enddo.

* result display
cl_demo_output=>display( ).
```
</div></details>
眺めて覚えるGo言語 その8 PythonからGO言語を呼ぶ

# 今回は、PythonからGO言語を呼んでpythonの弱点である速度向上させるアプローチです。
## Pythonを語ったとき「コンパイラ」ではない。で炎上しました。
### javaでも「コンパイラ」ではないし、C#もコンパイラではないのです。
#### 中間言語に変換して実行するのは、スピード遅いし、第一電池がすぐ減るのです。

**GOは、本物っぽいコンパイラーです。**

**pythonから見ると計算部分を高速化できる可能性があります。**

[フィボナッチ数](https://qiita.com/tomobk0025/items/3cc39ac6a7fbbdb0bde6)を参考にしました。

- 1つがいの兎は、産まれて2か月後から毎月1つがいずつの兎を産む。
- 兎が死ぬことはない。
- この条件のもとで、産まれたばかりの1つがいの兎は1年の間に何つがいの兎になるか？

```fib_go.py
from ctypes import *
lib = cdll.LoadLibrary("./fib.so")
for i in range(40):
    print ("fib %d  %d" %(i, lib.fib(i)))
```
lib.fib(i)で下記の関数呼ぶだけ。

```fib.go
package main

import "C"
//export fib
func fib(n int) int {
    if n <= 1 { return n }
    return fib(n-1) + fib(n-2)
}

func main() {}
```
**Goで書いた関数をコンパイルする。**

```
> go build -o fib.so -buildmode=c-shared fib.go
```
**実行する**

```
>python fib_go.py
fib 0  0
fib 1  1  
fib 2  1  
fib 3  2  
fib 4  3  
fib 5  5  
fib 6  8  
fib 7  13 
fib 8  21 
fib 9  34 
fib 10  55
fib 11  89
fib 12  144
fib 13  233
fib 14  377
fib 15  610
fib 16  987
fib 17  1597
fib 18  2584
fib 19  4181
fib 20  6765
fib 21  10946
fib 22  17711
fib 23  28657
fib 24  46368
fib 25  75025
fib 26  121393
fib 27  196418
fib 28  317811
fib 29  514229
fib 30  832040
fib 31  1346269
fib 32  2178309
fib 33  3524578
fib 34  5702887
fib 35  9227465
fib 36  14930352
fib 37  24157817
fib 38  39088169
fib 39  63245986
fib 40  102334155
```
#10倍以上速くなる。
ABC024-D 動的計画法

#ABC024-D 動的計画法
 この問題が2020年新年初AC && 初自力黄色dificultyACだったので解説記事に書いてみることにしました。

##問題
https://atcoder.jp/contests/abc024/tasks/abc024_d

##問題の概要
![C_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/381337/2dbe96a2-1e89-fa20-6a57-d0da43f9bb35.png)
上図のように左のマスト下のマスを足した値をmod(10^9+7)で割った余りがそのマスの値となるような10^8×10^8の大きな方眼紙がある。この時「あるマス」の値(A)とあるマスの上のマスの値(B)とあるマスの左のマスの値(C)が与えられるのであるマスの座標を求めよという問題である。![C_3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/381337/7c07456c-dd4f-3692-cdde-2c8ecbd9ccb9.png)
例えばA=15、B=35、C=21の時は下図のような状態であるので(4,2)を出力すれば良い。

##考察
問題名に動的計画法とあるものの、動的計画法をそのまま使うことはできなさそう

→一旦modは忘れて考えてみる

→それぞれのマスを(x,y)とするとその値は$x+yCx$と表せることにすぐ気付く（これは最短距離と同じ要領で）

→つまり答えを(r,c)とすると$A=r+cCr$、$B=r+c+1Cr+1$、$C=r+c+1Cr$である。

→コンビネーションは前後の関係が深いので、これらの値の関係が気になる。

→コンビネーションの前後関係の等式などを示す時には定義に帰るの一般的なので、とりあいずコンビネーションの定義に返ってみる。

→$A=(r+c)!/r!c!$、$B=(r+c+1)!/(r+1)!c!$、$C=(r+c+1)!/r!(c+1)!$である

→これを変形すると
$(r+c+1)/(c+1)=B/A$
$(r+c+1)/(r+1)=C/A$

→これはただの連立方程式なので解けて(c,r)が求められる！！

→これを解いて
$r=(AC-CB)/(CB-AB-AC)$
$s=(AB-BC)/(BC-AC-AB)$
(B,Cの対称性)

→こうして無事modを考えない場合の解法ができた

→じゃあmodを考えたらどうなるか

→結局modでも4則演算は成り立つのでmodint(mod内での四則演算が使える構造体)を同じように使い計算できる！

→modintは[ei1333氏のライブラリ](https://ei1333.github.io/luzhiled/snippets/math/mod-int.html)を拝借して無事AC!!!

##自分の解答
https://atcoder.jp/contests/abc024/submissions/9267170

##最後に
初の黄色difficultyACなので嬉しくて記事化しました。読んでくれた方はありがとうございました。参考になれば幸いです。
pyenvでインストールしたanacondaのJupyter NotebookをZshで使う（不具合対応）

# 概要
事の起こりは2019年末，Jupyter Notebookを久しぶりに動かそうとしたら起動できなかった．
色々と調べた結果，ターミナルをbashからzshに変更したことで，パス設定を直さなければいけないことが分かったけれど，自分の場合はpyenvでanacondaを入れていたので，さらにややこしいことになっていた．


# 症状
- ターミナルから”Jupyter Notebook”と打つと，”zsh: command not found: jupyter”と返ってくる
- ターミナルからPythonのバージョンを確認すると，macにデフォルトで入っていた古いバージョンが出てくる
- anaconda navigaterからJupyter Notebookの起動はできる
- [jupyter notebookが起動しなくなった原因はconda init zsh? ](https://code-graffiti.com/the-reason-why-jupyter-notebook-does-not-start/)を参考にパスを設定するも，不具合が解決しない（そもそも，”Users/$$$（ユーザー名）/anaconda3/bin”のパスが参照するフォルダがない）

# 環境
Mac OS Mojave
anacondaをpyenvでインストール

# パスを設定する方法
####1. ".zshrc"を起動

```code:Terminal
$ open ~/.zshrc
```

####2. ".zshrc"にpyenvのパスを書き込む
```code:.zshrc
export PYENV_ROOT="$HOME/.pyenv"
export PATH="$PYENV_ROOT/bin:$PATH"
eval "$(pyenv init -)"
```

####3. シェルを再起動
```code:Terminal
$ exec $SHELL -l
```

####4. パスが通っていることを確認する

```code:Terminal
$ which python
```
”/Users/<ユーザー名>/.pyenv/shims/python”と返ってきたのでOK

####5. Jupyter Notebookの起動を確認
```code:Terminal
$ Jupyter notebook
```

#参考にさせていただいたサイト
- [jupyter notebookが起動しなくなった原因はconda init zsh? ](https://code-graffiti.com/the-reason-why-jupyter-notebook-does-not-start/)
- [macOS CatelinaにAnacondaをインストールする（zshでの不具合対応）](https://code-graffiti.com/install-anaconda-on-macos-catelina/)
- [pyenvを使ってMacにPythonの環境を構築する](https://qiita.com/1000ch/items/93841f76ea52551b6a97)
- [シェルを再起動させる簡単な方法](https://qiita.com/yusabana/items/c4de582c6f85a42817d8)
何もない画像を作る

簡単なテキストファイルなら`touch`コマンドを使うことで作成できるが、画像はそのやり方を知らなかったのでメモ

```bash:空のテキストファイルを作る
touch filename.txt
```

#TL;DR
ImageMagickを使います

```bash:背景が白の画像ファイルを作成
convert -size 128x128 xc:white output.png
```
背景が透明なら`xc:none`にします

```bash:背景が透明の画像ファイルを作成
convert -size 128x128 xc:none output.png
```
【Notch】AE＆C4Dユーザーが作るリアルタイムモーショングラフィックス #10 シェイプモーション編

#シェイプモーションとは
これは決まった名称があるわけではなくて主にシェイプレイヤー的というかベクター平面っぽいモーションデザインのことを僕は「シェイプモーション」とか「シェイプアニメーション」とか言ってます。
人によって呼び方が違うと思いますが
なんかこんなイメージ（※これはAEです）
![picture_pc_4821516276bb2e3cde5fb80cd3df4c69.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/243114/1dd4f7c7-1e1b-482f-028b-b0a5bab5c380.gif)

#Shape 3Dで作るシェイプモーション
プリミティブオブジェクトを扱う**「Shape 3D」**で基本作っていきます。
円、四角、三角等の調整に特化しているため。
できたパーツてきとーにタイムラインに並べたのがこんな感じ。
![Shape.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/243114/00b5fb86-bd81-92ea-8364-e347593a2823.gif)

#Shape3Dの問題点
###・円が広がる表現
「Shape 3D」のRingの中に外側と内側の半径を設定するパラメータがあります。スタートアングルなんかもある！
これで広がるアニメーションできる！と思ったわけですが。なんと、、、

###キーフレームが打てません。アニメーションできません。どうにかしてNotch！！！！
（公式へ機能追加のお願いしておきました...）
![Shape-01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/243114/d0225fee-b788-db48-437b-33be767010c0.png)

#Layar Precompを駆使する
キーフレームが打てるのは固有パラメータ以外
つまりは標準の**「位置」、「回転」、「スケール」のみで組む**必要がありました。

①「Shape 3D」のスケール値で広がる円を作る
![Shape04.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/243114/f4fbe517-e530-af6a-13de-a332b5eab957.gif)

②新規レイヤーを作成し「Layer Precomp」と「Image 2D」で①の絵を引っ張る（外側の円になる）
![Shape-0２.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/243114/70c36685-1a8e-a83a-fbe9-e8c1e65a3ebd.png)
③さらにもう一個「Layer Precomp」を複製し①を引っ張る（内側の円になる）
④「Composite Image」ノードをRootから繋ぎ、③の「Layer Precomp」を参照させる
⑤「Composite Image」内の「Blend Mode（RGB）」を「Difference」へ変更
![picture_pc_8ce2d32aced4cae8580c5c9d0a9aa9c9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/243114/9d805ab6-6f6b-67f3-87d8-3e8e33cbd3b0.png)

⑥タイムラインモード(F2)で後から作った③の「Layer Precomp」の時間を後ろへずらす
![Shape-03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/243114/7f3bc180-f870-7922-a5f0-d80b0159db93.png)

広がる円（外側）を広がる円（内側）で時間差でくり抜いている状態
この方法で四角形や三角形、星形、その他縦横移動、スケール、回転にも応用がききます。
![Shape03.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/243114/8226d416-2438-85d0-d9b1-4579330383b1.gif)

#その他Layar Precompと時間差を使用した例
![Shape05.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/243114/f0796e7e-194b-6469-595a-10df1cb211ac.gif)
![Shape06.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/243114/c62da54c-1d5d-0202-0f84-20c735cbdaef.gif)
#キーフレームの力技でやっている例
↓スケールXと位置Xのみでキーフレーム
![Shape07.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/243114/4d19381c-4cef-577a-960d-9fbff52ded33.gif)
↓Clonerで円形+時間差+イージングがやりたかったけどわからず。。。
一本ずつタイムラインに置いている力技状態
![Shape08.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/243114/1a889c87-fbff-a7c1-0cd4-05d2810357b6.gif)

#終わりに
これにてNotchにおけるモーショングラフィックスに関する一連の記事は終わりにしたいと思います。
ありがとうございました！！！

情報共有はこちらのグループで行っているのでぜひ参加してみてください。
Facebookグループ : https://www.facebook.com/groups/notchusergroupjapan/
Line オープンチャット : https://line.me/ti/g2/kJYmLLsvS2zNfR9PEiknMg

質問等あればお答えしますのでお気軽に
Twitter : https://twitter.com/shu1053
FB : https://www.facebook.com/profile.php?id=100009103327410
WebStorage と Cookie の違い

# はじめに
Local環境にてHTMLのコンテンツを動かしたいときに、Local環境でのCookieのように情報の共有をする方法があるかどうか調べました。

# Cookie / WebStorage とは
まずは言葉の意味を調べました。

#### 関連リンク
関連リンクを下記に載せておくので、参考にしてください。。

* Local環境でのCookie / WebStorage 挙動
    * https://qiita.com/syukan3/items/dd907b7cd3ed86025546
* Local上にて複数のHTMLコンテンツのデータを共有する方法（Store.js）
    * https://qiita.com/syukan3/items/c20ed695c1d676799a5a
* Local環境のXMLファイルからJavascriptを使って情報を取得する方法
    * https://qiita.com/syukan3/items/71c63cdccb6976e52f3d

## Cookie 
__cookie（クッキー）とは、見ているWebサイトからスマホやPCの中に保存される情報__。
HTTP cookie（エイチティーティーピークッキー、単にクッキーとも表記される）は、マジッククッキーの一種であり、RFC 6265などで定義されたHTTPにおけるウェブサーバとウェブブラウザ間で状態を管理する通信プロトコル、またそこで用いられるウェブブラウザに保存された情報のことを指す。ユーザ識別やセッション管理を実現する目的などに利用される。
（Wikiより　https://ja.wikipedia.org/wiki/HTTP_cookie）

そもそも、__local環境で使用することを想定していない__ことがわかる。。

## WebStorage
Web Storageは、ユーザーのローカル環境（ブラウザ）にデータを保存するための仕組み。
データの保存・上書き・削除・全クリアなどの操作は、__JavaScript__で行うことができる。

Web Storageを利用すると、ユーザーごとにカスタマイズされた情報を提供することが可能となる。
__この仕組みはクッキー（HTTP cookie）とよく似ている が、クッキーに比べて保存できる容量が大きい__。
そのため、例えば、オフラインでもウェブアプリケーションを動作させられるだけの 必要十分なデータをユーザーのローカル環境に保存することなどが可能となる。

Web Storageには、__sessionStorageとlocalStorageの２種類のストレージ__が用意されています。 
どちらもキー（key）と値（value）をペアにしたデータのリストを ユーザーのローカル環境に保存するkey-value型のデータ保存形式である点は同じですが、 データの有効期限などが異なるので目的に応じて使い分けます。

### SessionStorage
sessionStorageは、ウィンドウやタブ単位での一回限りのセッションで有効なストレージ。

### localStorage
localStorageは、オリジン単位でデータを永続的に保存するストレージ。

# まとめ
色々調べた結果として、参考リンクにまとめられているものが一番わかりやすかったです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308256/0ff463e7-c14e-4eec-710f-43bb3c4bba22.png)

# 参考
http://www.htmq.com/webstorage/

---
### 会社紹介

**株式会社 Mosaica**  
最先端テクノロジーで社会課題を解決し、持続可能な未来を創造する IT カンパニー。
AI ソリューション、クラウド統合、DX 推進、経営コンサルティングなど包括的なサービスでビジネス変革を支援しています。  

詳しくは [公式サイト](https://mosaica.co.jp/) までお気軽にご相談ください。
公式サイト： https://mosaica.co.jp/
[Ruby on Rails] ERB.Haml.Slimの書き方別


お疲れ様です！Rails書籍を読んでいると

ERBよりも、HamlやSlimがテンプレートエンジンとして現場で採用されているらしい？です。

今回は、備忘録も兼ねてそれぞれの記述方法を書いていきまーす。



```ERB
<html>
 <body>
  <h1><%= @title %></h1>
 </body>
</html>

```
↑ERB

```Haml
%html
 %body
  %h1= @title

```

↑Haml


```slim
 html
  body
   h1= @title 

```
↑Slim


こう見ると、Slimが断然効率よくかけそうですね。
どのパターンでもかけるようにして行きたいです。

不備がありましたら、コメントいただけたら幸いです！
ありがとうございました！


>参考書籍
>現場で使える Ruby on Rails 5速習実践ガイド
ARC059-E Children and Candies / キャンディーとN人の子供 解説

[ARC059-E Children and Candies](https://atcoder.jp/contests/arc059/tasks/arc059_c)の解説です。公式解説が少しわかりにくい気がしたので、是非こちらも参考にしてください。
# 問題概要
$N$ 人の子供たちに $C$ 個のキャンディーを、非負整数個づつ配る。（つまり、１つも配らない子供がいても良い。）
それぞれの子供たちは値 $x_i$ を持っており、子供 $i$ にキャンディーを $k$ 個配った時、子供の「うれしさ」は $x_i^k$ となる。幼稚園の活発度は、子供たちの嬉しさの積として計算される。 $x_i$ が $A_i$ から $B_i$ までの値をとる時、ありうる全ての $x_i$ とキャンディーの配り方について、活発度の総和を求めよ。
# 部分点解法
この問題は、満点解法も部分点解法と同様な発想をするので、部分点解法から解説します。
部分点では、$A_i=B_i$ から、$x_i$ の値が一意に定まっていることがわかります。
この問題は、次のようなDPで簡単に解けます。
定義:dp[$i$][$j$]= $i$ 番目までの子供たちに $j$ 個のキャンディーを配った時の、そこまでのうれしさの積としてありうるものの総和
初期値:dp[$0$][$0$]=$1$
遷移:dp[$i+1$][$j+k$]+=dp[$i$][$j$]*$x_i^k$
答え:dp[$N$][$N$]
dp[$i+1$][$j+k$]への遷移を計算する時、$i$,$j$以外の情報は必要なく、総和としてまとめて計算していいことさえわかれば、このDPが成立していることがわかると思います。
計算量は $O(NC)$ です。
ここまでは水色程度の人には少し厳しいかもしれませんが、思いついて欲しいところです。
# 満点解法
満点の制約では、$x_i$ の範囲が最大 $400$ なので、上のDPを全ての $x_i$ の組み合わせに対して行うと計算量が爆発します。
ここで、キャンディーの配り方を固定し、子供 $i$ に配る数を $c_i$ としてみます。
ここで、全ての $x_i$ の組み合わせについての活発度の総和を求めることを考えます。
実はこれの値は、次の値と等しいです。
$\prod_{i=1}^N \sum_{j=A_i}^{B_i} j^{c_i}$
なぜでしょうか。とりあえず可視化してわかりやすくしましょう。
$(A_1^{c_1}+(A_1+1)^{c_1} \cdots B_1^{c_1})(A_2^{c_2}+(A_2+1)^{c_2} \cdots B_2^{c_1}) \cdots(A_N^{c_N}+(A_N+1)^{c_N} \cdots B_N^{c_N})$
これを展開すると、全ての $x_i$ の組み合わせが1度ずつ現れるので、全ての組み合わせについての活発度の総和となります。
このような式変形はあまり珍しいものではないため、多少数学ができればわかると思います。
こう考えると、部分点のDPの遷移を少し変えるだけで満点解法へと拡張することができます。
つまり、dp[$i+1$][$j+k$]+=dp[$i$][$j$]*$(\sum_{l=A_i}^{B_i} l^k)$
とすれば良いです。
このシグマの部分をいちいち計算すると計算量は$O(NC\ max(B_i))$ となり、間に合いません。
そこで、ありうる全ての $l$ と $k$ について、$1^k$ から $l^k$ までの和を前計算で求めておけば、引き算によってシグマの部分の値が $O(1)$ で求まります。
よって、前計算に $O(C\ max(B_i))$,DPパートに $O(NC)$ かかり、合計 $O(C(max(B_i)+N))$ でこの問題が解けました。
# おわりに
ABCやAGCには出なさそうな雰囲気ですが、ARCや企業コンにバンバン出そうな雰囲気をした問題なので、企業コンでレート爆上げしたい人はちゃんと押さえておきましょう。
ありがとうございました。
Google提供のDataflowテンプレートとJavaScriptの話


# tl;dr

* GoogleはDataflowのテンプレートを提供しているよ
 * コードはGitHubで見られるよ
* いくつかのテンプレートはJavaScriptで変換の処理を書けるよ
* JavaScriptの処理はNashornを使っているよ


# Google提供のDataflowテンプレートとは
名前の通り、Googleが提供していてるDataflowのテンプレートです。
これを使うことで、コードを（あまり）書かずに一定の処理が行えます。

提供されているテンプレートは、GCPのストレージ（GCS・Pub/Sub・Datastore・BigQuery・Spanner）間の移動を行うものが多く、例えば、

* Pub/SubからBigQuery（ストリーミング）
* GCSからBigQuery（バッチ・ストリーミング両方）

などがあります。

ちなみに、GCPのストレージ間移動**以外**のテンプレートとしては、[Datastoreのデータ削除](https://cloud.google.com/dataflow/docs/guides/templates/provided-utilities?hl=ja#datastorebulkdelete)、[GCS上のファイルの解凍・圧縮](https://cloud.google.com/dataflow/docs/guides/templates/provided-utilities?hl=ja#bulkcompressgcsfiles)などがあります

また、ソースコードが[Githubで公開されている](https://github.com/GoogleCloudPlatform/DataflowTemplates)ので、実装を調べたりすることが出来ます。



# Google提供のDataflowテンプレートのJavaScriptとは

いくつかのテンプレートでは、入力（ソース）から出力（シンク）との間に、JavaScriptでの処理(UDF)を挟むことが出来ます。

例えば、[GCSからBigQueryでは](https://cloud.google.com/dataflow/docs/guides/templates/provided-batch?hl=ja#cloud-storage-text-to-bigquery)、入力と出力の間に、

* 各行を引数として受け取る
* 処理結果をJSONとして返す

JavaScript関数を経由させることが出来ます（使わないことも出来ます）。


全部のテンプレートでJavaScriptが使えるのではなく、これが出来るテンプレートは、例えば、

* [DatastoreからGCS](https://cloud.google.com/dataflow/docs/guides/templates/provided-batch?hl=ja#cloud-datastore-to-cloud-storage-text)
* [SpannerからGCS](https://cloud.google.com/dataflow/docs/guides/templates/provided-batch?hl=ja#cloud-spanner-to-cloud-storage-text)
* [GCSからBigQuery](https://cloud.google.com/dataflow/docs/guides/templates/provided-streaming?hl=ja#cloud-storage-text-to-bigquery-stream)

などがあります（実際にはもう少しあります）。


# どうやって処理しているの
DataflowやApache Beamの機能としてJavaScriptを扱える**わけではなく**、テンプレートはJavaで書いており、JavaScriptの部分はJava組み込みのJavaScriptランタイム[（Nashorn）](https://docs.oracle.com/javase/jp/8/docs/technotes/guides/scripting/prog_guide/api.html)で処理しています。

JavaScriptでパイプライン自体を書けるわけではないので、注意してください（2019年時点では）。


## 細かいのが気なる人向け
例えば、GCSからBigQueryのテンプレートでは、[ここらへんで](https://github.com/GoogleCloudPlatform/DataflowTemplates/blob/22f94fe61cbaaab07187c5545302a5b62fe6106f/src/main/java/com/google/cloud/teleport/templates/TextIOToBigQuery.java#L99)、GCSからの各行をJavaScriptの処理に渡しています。

JavaScript系の処理は[JavascriptTextTransformer](https://github.com/GoogleCloudPlatform/DataflowTemplates/blob/master/src/main/java/com/google/cloud/teleport/templates/common/JavascriptTextTransformer.java)クラスにまとめられており、

* [ここらへんで](https://github.com/GoogleCloudPlatform/DataflowTemplates/blob/22f94fe61cbaaab07187c5545302a5b62fe6106f/src/main/java/com/google/cloud/teleport/templates/common/JavascriptTextTransformer.java#L180)JavaScriptのコードを取得し

* [ここらへんで](https://github.com/GoogleCloudPlatform/DataflowTemplates/blob/22f94fe61cbaaab07187c5545302a5b62fe6106f/src/main/java/com/google/cloud/teleport/templates/common/JavascriptTextTransformer.java#L137)[ScriptEngineManager](https://docs.oracle.com/javase/jp/8/docs/api/javax/script/ScriptEngineManager.html)に渡して、JavaScriptランタイム（Nashorn）で処理する準備をしています
KYF37で「＋メッセージ(SMS)」をインストールしてみた

kyocera製au向けガラホ(フィーチャーフォン風スマートフォン)に「＋メッセージ(SMS) Version 2.0.21」をインストールしてみました。
## 注意
このアプリをインストール後にこれをアンインストールすると今まで送受信した**メッセージが消えて**しまいます。(データを＋メッセージ用に書き換えてしまうためのようです)
auのアプリ「データお預かり」でデータをバックアップした上でお試しください。
## インストール
apkファイルを入手した上で、ファイル閲覧アプリか、adbでインストールします。
`adb install -r com.kddi.android.cmail-520225.apk`
(-rはreplaceのrです。これをつけないと[INSTALL_FAILED_ALREADY_EXISTS]になります)
apkのパッケージ名: com.kddi.android.cmail
apkのファイル名: com.kddi.android.cmail-520225.apk
アプリのバージョン: 2.0.21
## 結果
使えませんでした。(2020/01/01現在)
タッチポインターのカーソルが現れないことと、
十字キーに対応していないため、メッセージが読めません。
## アンインストール
以下の操作でダウングレードできますが、送受信データは復活しません。
`adb uninstall com.kddi.android.cmail`
## 実験環境
OSバージョン: 5.1.1 API22 armeabi-v7a
ビルド番号: 104.0.2600
元のアプリ「SMS」com.kddi.android.cmailはバージョン26.20.00です。

![Screenshot_2020-01-01-08-01-14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/560016/3f777192-acc6-0692-606d-8577eacf22b8.png)
TomcatにWarファイルをSCP転送

#Tomcatフォルダの権限設定
前回、VPSにTomCatをインストールできたので、試しにEclipseでHelloWorldのようなWarファイルをエクスポートしてデプロイしようとしたらちょっとつまづいた。

/opt/tomcat/webapps/

直下にscpするだけでできるはずなのだが、permission deniedと言われた。

権限を確認するとroot以外読み込みのみになっていたので、

```
cd /opt/tomcat
chmod -R 766 webapps
```

を指定してやり直し、書き込むだけだからこれで行けるよね？
と思ったけどpermission denied.
なんで？

そこで、ユーザーアカウントにtomcatグループ属性を追加してみる。
permission denied.

・・んんん？？あ、もしかしてプログラマーはコピーするだけだけど、自動的にunzip展開されるし、コピーする人にも実行権限がいるとか？

で、

```
cd /opt/tomcat
chmod -R 777 webapps
```

してみたら無事コピーできて、ブラウザでアクセスしてみてもちゃんと動いた。

ただ、このままではこのフォルダ誰でも書き込みできてしまうので、アプリのデプロイユーザーをtomcatグループにして770にすればいいのかな。

#補足
tomcatにはwebコンソールでデプロイする仕組みがあるので本来はそれを設定してそこからやる方がいいらしい。
やってみたけど、設定箇所が足りないらしく403で入れなかったのでとりあえずSCPでデプロイしました。
code smell リファクタリング[lazy class編]

第四回のリファクタリングは、lazy classです。

## lazy classとは

怠け者のクラス。
クラスがほとんど振る舞いを持たずに怠けている状態のこと。（存在している意味がわからない）

## なぜ悪いのか

必要がない。
冗長になる。

## よくあるパターン

よくあるのは、以下のようなとりあえずserviceクラスを作って、そこに処理を投げている構造です。

```scala

package study.lazyclass

class PaymentController {
  def payment(amount: Int) = {
    val service = new Service
    service.pay(amount)
  }
}

class PaymentService {
  def pay(amount: Int): Unit = {
    paymentRepository.save(amount)
  }
}

```

payメソッドだけが、PaymentServiceクラスに定義されています。
Serviceクラスがpayメソッドと言う振る舞いしか持っていません。

## ソリューション

ソリューション自体は非常に簡単です。

関数のインライン化
必要な時に作ればいい。
クラスを作るタイミングとしては、二つ以上の箇所から呼び出されたりなど、関数をまとめるクラスが必要になった時に作ればいいだけです。

```scala

class PaymentController {
  def payment(amount: Int) = {
    paymentRepository.save(amount)
  }
}

```

PaymentControllerから直接、paymentRepositoryを呼び出すように変更しています。

これは、よく言われているYAGNIの法則にもそっています。

[https://ja.wikipedia.org/wiki/YAGNI:embed:cite]


## 考え方

ここからがこのcode smellの重要な観点です。

lazy classリダファクタリング自体は非常に簡単にできますが、**リファクタリングを実際にするのかどうかが開発手法によって変わってきます。**

レイヤードアーキテクチャでアプリケーション構成を考えていくなど、最初から適応するアーキテクチャを考えているならば、上記のようなリファクタリングをする必要はないです。

関数が一つしかない場合でも、きちんとレイヤーを分けて、定義する必要があります。


例えば、レイヤードアーキテクチャを採用しているなら、下図のように依存関係は上から下の一方通行になるように設計しないといけないので、
リファクタリングのコードのような、controller(presentation層)からrepository(infrastructure層)を呼ぶことはできない。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/150144/c1ade2f3-1b46-a4f7-0976-f32d562006b5.png)



なのである程度のcode smellを許容しながら、開発を進める必要があります。

しかし、**アーキテクチャを最初から考えていくと、そのアーキテクチャのルールに乗らないといけないので、コードを書くのが窮屈になる、と言う理由で、基本的に開発の序盤からアーキテクチャを考えるべきではないという開発者もいる。**


なので、どんな開発手法をとるかはチームで考えて開発ルールを決定すべき。


## まとめ

lazy classのリファクタリングを行いました。

最後までありがとうございます。


## 参考

- [clean code](https://amzn.to/38GalcX)
- [リファクタリング](https://amzn.to/38KuqPB)
Firefoxのエディションの違いとは？

# Firefox のエディション

デスクトップ向け Firefox を使っていると、通常の Firefox に加えて様々なエディション(チャネル)があることに気がつきます。Firefox Nightly、Firefox Developer、 Firefox Beta がそれに当たります。これらは何が違うのでしょうか？この記事では、それぞれのエディションの違いについて整理します。

なお、この記事は基本的に [Why are there Four Firefoxes?](https://youtu.be/qQ1oQJJn1nQ) というYouTubeビデオを参考にして書いています。

# Firefox
![firefox.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12152/016001bf-1802-5000-8a99-7d0cafcf9e79.png)


通常のエディションの Firefox です。PC に Firefox をインストールする際は、通常はこの Firefox が使用されます。

# Firefox Beta
![firefox_beta.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12152/d69b68b5-f8fe-16d4-f48c-d0531005fc08.png)


`Beta` という名前が示す通り、正式リリースされていない次期バージョンの Firefox です。例えば、現行の Firefox のバージョンが 70 であれば、Firefox Beta はバージョン 71 でリリースされる予定の機能を含んでいます。QA チームがテスト中の段階であり、動作が不安定になる可能性もあります。

# Firefox Developer
![firefox_dev.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12152/79d4d901-8f4d-9e20-1e08-29854cf7d097.png)


基本的には Beta と同じですが、これは Web 開発者向けのエディションであり、以下の点が異なります。

## セキュリティ要件が緩くなっている

開発者が Firefox プラグインを作成する場合、開発段階のプラグインを動作させたいケースは頻繁にあります。通常はセキュリティ上の理由から、プラグインが正式リリースされるまで Firefox 上で実行させることはできませんが、Developer エディションではそれが可能となります。

## スニペット

Firefox で新しいタブを開いた場合には、ページ下部にスニペット(メッセージ)が表示されて、新機能が紹介されたりします。Developer エディションでは、この内容がより開発者向けになります。

## Devtool

Firefox の Devtools では、ベータ機能をいち早く試すことができます。また、Developer エディションでは、Devtools のデフォルトのテーマがダークになっています。

# Firefox Nightly
![firefox_nightly.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12152/83951125-c13f-8a80-87b6-ae39904105cb.png)


Beta や Developer が 1 つ先のバージョンを示すのに対して、Nightly は **2 つ先のバージョン** を提供します。つまり、現行の Firefox バージョンが 70 であれば、Nightly によって提供されるのはバージョン 72 で提供予定の機能ということになります。搭載予定の機能が開発中のステータスであり、毎日の様にアップデートが行われます。Beta、Developerよりも不安定であり、正しく動作しない可能性もありますが、現時点で開発中の機能を試すことができます。

# 最後に

通常のエディションを除き、上述した各種エディションの Firefox は、どれも新しい機能を先行して提供しています。新たに対応する JavaScript や CSS、あるいは Devtools の機能をいち早く試したいというようなケースで役に立つのではないでしょうか。なお、Google Chrome や Microsoft Edge でも同じ様な開発サイクルとなっており、 `Chrome Canary`、 `Edge Canary` が、 Firefox の Nightly に相当します。

# 参考

- [Why are there Four Firefoxes?](https://youtu.be/qQ1oQJJn1nQ)
- [What are Firefox Nightly, Developer, Beta, and Aurora editions](https://www.thewindowsclub.com/what-are-firefox-nightly-developer-beta-and-aurora-editions)
- [Firefox Desktop](https://www.mozilla.org/en-US/firefox/channel/desktop/)
- [Firefox Developer](https://www.mozilla.org/en-US/firefox/developer/)
【linuxコマンド】lsコマンド/cdコマンド（絶対パス・相対パス）


ターミナルからのPC操作には、linuxコマンドと呼ばれる一連の命令群を用いる。

## lsコマンド
lsコマンドはlist(リスト)の略で、フォルダやファイルの一覧を表示するコマンド。カレントディレクトリの直下にあるファイルやフォルダの名前が一覧で表示される

## cdコマンド
cdコマンドはchange directoryの略で、ディレクトリを変える、つまりディレクトリを移動するときに使う。
使い方はターミナルで「cd (移動したいディレクトリのパス)」と打ち込んでエンターを押す。単に「cd」とするとホームディレクトリに移動する。

## ディレクトリのパスを指定する方法

### 絶対パス
絶対パスはルートディレクトリから指定するパス。絶対パスで指定するときにはパスの一番最初に/を指定する。

```terminal:
$ cd /Users/Desktop
# 絶対パスは/から始める
```

### 相対パス
相対パスは現在いるディレクトリ(カレントディレクトリ)から指定するパス。相対パスで指定するときにはパスの一番最初に/を書かない。

```terminal:
$ cd Users/Desktop
# 相対パスは始めに/をつけない
```
Macをクリーンアップして作業環境を構築した時の備忘録

年末にプライベートで使ってるMacBook Air（2014年に買ったそこそこ古いやつ）をクリーンアップして諸々設定したのでその時のメモ

やったことは
1. ハードディスク初期化
2. homebrewインストール
3. githubにssh登録
4. githubからmac設定用のansibleをcloneして実行
5. githubからdotfile落としてきてローカルに適用

# ハードディスク初期化
command + R 押しっぱなしで再起動してディスクユーティリティからHD初期化してOS入れ直して、後は画面通りに設定していけば終わる。
消したくないファイルはGoogle Drive、写真はGoogle Photo、メモはsimplenoteに全て入れておく

# homebrewインストール
[公式サイト](https://brew.sh/index_ja)で落としてくれば終わり

# githubにssh登録
```
$HOME/.ssh
で
ssh-keygen -t rsa
```
生成された鍵を[ここ](https://github.com/settings/keys)に登録

# githubからmac設定用のansibleをcloneして実行

まずansibleをmacにインストールする。
その後に[よく使うアプリをmacにインストールするansibleを作っておいた](https://github.com/ikeyu0806/ansible-mac)のでそれを実行した。
が、エラーメッセージが出て落ちた

```
failed: [localhost] (item=caskroom/cask) => {"ansible_loop_var": "item", "changed": false, "item": "caskroom/cask", "msg": "added: 0, unchanged: 0, error: failed to tap: caskroom/cask"}
```

ググったらhomebrewでGUI入れる機能が本体に統合されたようなのでここはansibleから消した。

# githubからdotfile落としてきてローカルに適用 
[設定ファイルをgithubにおいてある](https://github.com/ikeyu0806/dotfiles) のでそれをシェルでローカルに適用した。
- ansibleの前に実行しようとしたが、rbenv、ndenv、starshipがインストールされていること前提の内容になっていたので先にansible実行しないといけなかった
- シェルを実行して`ls -la $HOME`したけどbashrc、bash_profileがなかった。。macって最初ないんだっけ。。しょうがないのでtouchで空ファイル作って再実行したら動いた。


これで作業環境としては大分いつも通りになった感じあるけど、実際開発してみると足りないもの諸々あるんだろうなとか、、

そろそろmac買い換えたいので近いうちにまたやる気がする
CentOS7+Apache2.4+Python3.6でとりあえず動かす

捨ててもいいCentOSでとにかく動かしたいとき。

python3はvirtualenvでインストールした方が良い。

(追記)

最後にDockerfileを書いた。この手順をDockerfileに書き直しただけ。出来上がるイメージは600MBとかになるので、重すぎると思う。

alpineで作り直したらまだ軽くなるか。flaskをプロダクション環境で動かす時のベストプラクティスが知りたい。

# Versions

CentOS

```
CentOS Linux release 7.6.1810 (Core)
```

HTTPD

`httpd-devel`もインストールする。

```
httpd-tools-2.4.6-90.el7.centos.x86_64
httpd-2.4.6-90.el7.centos.x86_64
httpd-devel-2.4.6-90.el7.centos.x86_64
```

PYTHON

`yum install python3`で入れる

```
Python 3.6.8
```

# ポイント

* `mod_wsgi`は`yum`でインストールしない。
    * python27のものが入ってしまう。
    * `pip3 install mod_wsgi`でインストールする
    * これをインストールするときに`gcc`が必要になる。

```
yum install httpd httpd-devel python3 python3-devel gcc -y
pip3 install mod_wsgi
```

* HTTPDのconf
    * `LoadModule`で、上でインストールした物を指定する。これがApacheが動かすPythonのバージョンとなる。
    * `python-path`は`site-packages`まで含めたPathを指定する
    * 親玉confに`Listen 8080`をちゃんと指定しておく



```
[root@ryo httpd]# cat /etc/httpd/conf.d/userdir.conf
<VirtualHost *:8080>
    ServerName example.com

    LoadModule wsgi_module /usr/local/lib64/python3.6/site-packages/mod_wsgi/server/mod_wsgi-py36.cpython-36m-x86_64-linux-gnu.so
    WSGIDaemonProcess ml user=vagrant group=vagrant threads=5 python-path=/usr/local/lib64/python3.6/site-packages
    WSGIScriptAlias / /opt/tryml/ryo/wsgi.wsgi

    <Directory /opt/tryml/ryo/>
        WSGIProcessGroup ml
        Order deny,allow
        Allow from all
        Require all granted
    </Directory>
</VirtualHost>
```

* wsgiのファイルを作る

```python

import sys, os
sys.path.insert(0, os.path.dirname(__file__))
from sebserver import app as application
```

# 参考

* [Fatal Python error: Py_Initialize: Unable to get the locale encoding ImportError: No module named 'encodings' #336](https://github.com/GrahamDumpleton/mod_wsgi/issues/336)

# Dockerfile

```docker
FROM centos:7
COPY ["*.py", "wsgi.wsgi", "requirements.txt", "/var/www/html/"]
RUN yum install httpd httpd-devel python3 python3-devel gcc -y; pip3 install -r /var/www/html/requirements.txt; mkdir /var/www/html/static; chown apache:apache /var/www/html/*
COPY templates/sample.html /var/www/html/templates/
COPY docker/py.conf /etc/httpd/conf.d/
COPY docker/httpd.conf /etc/httpd/conf/
CMD ["/usr/sbin/httpd", "-DFOREGROUND"]
```
【Vuetify】`v-select`で任意の範囲の数字を選べるセレクトボックスサンプルコード

## はじめに
Vuetifyの`v-select`を使って、1歳から116歳までの年齢を選ぶことが出来るサンプルコードを作成しました。

## 環境
```yaml
OS: macOS Catalina 10.15.1
Vue: 2.6.10
vue-cli: 4.1.1
vuetify: 2.1.0
```
## 出力
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/483292/7d7c573b-9ed3-0e84-e0f0-0019857f64e1.png)
↓
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/483292/a19a63c3-dd07-f7ab-b9f5-d376bca824c7.png)


## コード

```vue:sample.vue
<template>
  <v-select
    v-model="age"
    :items="items"
    label="年齢"
  ></v-select>
</template>

<script>
  const maxAge = 117; //表示したい数字より+1で設定。
  const ageRange = [...Array(maxAge).keys()]

  export default {
    data() {
      return {
        items: ageRange,
          age: '',
        },
      }
    },
  }
</script>
```

さすがに
`[1,2,3,4,...117]`
とはしたくなかったのでやり方を調べたら、
`[...Array(数字).keys()]`で整数の連番が作成できるんですね。勉強になりました。:thinking:

Rubyなら範囲オブジェクトで`0..100`でOKなんですけどひと手間いりますね:sweat_smile:

## おわりに
最後まで読んで頂きありがとうございました:bow_tone1:

どなたかの参考になれば幸いです:relaxed:

## 参考にさせて頂いたサイト（いつもありがとうございます）
- [連番の数字の配列を作成（es2015 ver) - Qiita](https://qiita.com/sakymark/items/710f0b9a632c375fbc31)
jupyter labに拡張機能をcondaで導入する方法



検索すると、

```
curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.11/install.sh | bash

source ~/.bash_profile
```
と出てくるが、何だかできなかったので、

以下の公式ページを見ると、
https://jupyterlab.readthedocs.io/en/stable/user/extensions.html


```
conda install -c conda-forge nodejs
```
とかいてあるのでやったらできた。
その後は、サイドバーのパレット(Commands)でenable extension managerを検索して実行すると使えるようになる。