OmniAICreator/Qiita-1.07M huggingface dataset:
stylus-supremacyでStylusを整形する

Stylus Supremacy
https://thisismanta.github.io/stylus-supremacy/

# インストール

```bash
yarn add stylus-supremacy
```

# 設定

## scriptsの定義

```json:package.json
"scripts": {
  "supremacy": "stylus-supremacy format **/*.styl -p stylus-supremacy.json -r"
}
```

`**/*.styl` はすべてのStylusファイルを対象にする場合

## 整形ルール

`stylus-supremacy.json` を作成して以下のように設定を記述します。

```json:stylus-supremacy.json
{
  "stylusSupremacy.insertColons": false,
  "stylusSupremacy.insertSemicolons": false,
  "stylusSupremacy.insertBraces": false,
  "stylusSupremacy.insertNewLineAroundImports": true,
  "stylusSupremacy.insertNewLineAroundBlocks": true,
  "stylusSupremacy.insertNewLineAroundProperties": true,
  "stylusSupremacy.insertNewLineAroundOthers": false,
  "stylusSupremacy.preserveNewLinesBetweenPropertyValues": false,
  "stylusSupremacy.insertSpaceBeforeComment": true,
  "stylusSupremacy.insertSpaceAfterComment": true,
  "stylusSupremacy.insertSpaceAfterComma": true,
  "stylusSupremacy.insertSpaceInsideParenthesis": false,
  "stylusSupremacy.insertParenthesisAfterNegation": false,
  "stylusSupremacy.insertParenthesisAroundIfCondition": false,
  "stylusSupremacy.insertNewLineBeforeElse": false,
  "stylusSupremacy.insertLeadingZeroBeforeFraction": true,
  "stylusSupremacy.selectorSeparator": "\n",
  "stylusSupremacy.tabStopChar": "  ",
  "stylusSupremacy.newLineChar": "\n",
  "stylusSupremacy.quoteChar": "'",
  "stylusSupremacy.sortProperties": "grouped",
  "stylusSupremacy.alwaysUseImport": false,
  "stylusSupremacy.alwaysUseNot": false,
  "stylusSupremacy.alwaysUseAtBlock": false,
  "stylusSupremacy.alwaysUseExtends": false,
  "stylusSupremacy.alwaysUseNoneOverZero": false,
  "stylusSupremacy.alwaysUseZeroWithoutUnit": true,
  "stylusSupremacy.reduceMarginAndPaddingValues": true,
  "stylusSupremacy.ignoreFiles": ["node_modules/**"]
}

```

https://thisismanta.github.io/stylus-supremacy/#options

インデントを半角スペース2つにし、いくつか改行まわりで変更を加えています。
インデントはタブ指定がデフォルトですが、半角スペースにする場合は `tabStopChar` に必要な分のスペースを設定します。
対象外にするファイルは `ignoreFiles`で指定できます。

# 実行

```bash
yarn run supremacy
```
ほぼ初心者でバックエンド&インフラ屋見習いが所感をtweetするところ

1ヶ月経ったので、ある程度書き溜めてたものを放流。
また、それ以降で思ったこと、感じたことの遷移についても、なるべく思ったときに書いていく。

# 入社～1ヶ月 (2019/11/01～
本当に、前社8ヶ月で辞めてよかった。
いまの会社さいこお。

## 2019/11/01
入社

開発環境構築で手間取り、焦る。
ローカル環境自体はVagrant(Ansibleで調整)だが、Shellの環境はMacからそのまま持ってこられないので、
少しずつWindows固有、WSLやプロジェクトで使うディストロに寄せていく必要がある。
技術がほしい。

## 2019/11/07
AWSでログを取ることが始まる。
CloudWatch、insightsでのクエリの飛ばし方、やってみる

## 2019/11/11
プロジェクト固有なのか、一般論での問題なのかが切り分けできない。
あとSQL書けない。
ログはJSONででてくるが、検索の仕方など、界隈の常識がわからん

## 2019/11 中旬
業務でペアを組んで何かためになることを勉強する時間をもらう。
前々からやりたかった環境構築の最適化と、
型落ちPCをGentooやArchLinuxなどで再生して使うこと、やり始める。たのしいのかよ。

## 2019/12/05 (およそ1ヶ月経過)
メンター面談もあったのでまとめ。

1ヶ月やってきたが、これまでの人生で一番勉強になっているし、楽しいし、精神が穏やかで充実感に満ちている。
なんなら見た目の給料は前者より減ったが、実家から通っている分、財布に残る分は増えていたりする。
しかも新幹線通勤で歩いているだけで、割合運動になるときた。
心身ともに健康そのものである。

いまのところのポジティブな感想

- インフラはわりと全社的にAWS
- Github (そらそうよね
- PHPのつかいかた
  - タイプヒンティングつかわれてる
  - コーディング規約しっかりある
  - コミットにhookしてformatter走る
- CIにJenkinsくんが使われてる
- PHPStormライセンス貰った
- Slackの活用率たっっっかい
  - 分報すごい。ほんとためになる。どこでもやるべき。
  - webhookしっかり使われてて、情報が大体slackに集約されてきてる
  - Slackでの交流たのしい。Botとかスタンプつくりたい。
- コードレビュー文化しっかりある
- メンバー多めなので割と質問しやすい
- 社員への還元をものすごく考えてくれる会社
- INM語録でコミュニケーションが取れる(迫真(重要

感想のレベル感が低すぎる。

ネガティブな感想

- Null
- (何一つ) ないです。

実際の業務については、まだまだわからないことしか無いが、
人数が居ることもあり、Slackでの質問の仕方についてもぼんやり分かってきたような気がする。
ので、わからないことについては助けを求めて居るつもりである。
殆どの時間をコードリーディングに充てさせて頂き、コードの把握からMVCの概念から、様々学習をつづけている。

技術の興味範囲については、色んな人が居ることがわかった。
メンターさんにも言われたが、本当の意味でのフルスタックな人は、ほぼいないんだろうなぁと感じた。
それぞれ、突き抜けたところがある人達で、色々な考えを持っている。話を聴き比べて、cherry-pickしていきたいものだと思った。

雑感でした。

# 2ヶ月経過 (〜2019/12

光陰矢の如し。2ヶ月が経ち、ふわふわした気持ちが落ち着いてきた。
率直に言うと、現状なかなかにイキっていると思う。
そして同時に、自分の現状に焦っていると思う。
少し落ち着こう。

まず、入社当初から、いろいろな技術の話題がやり取りされ、憧れは抱く。
しかしながら、私にその技術の本質を味わう力はない。
基礎がとてもじゃないがボロッボロである。
昔から大枠を掴むことについては自信があるので、ざっくりとした知識は持ち合わせがある。
中学校教員なんて最たる例で、週1の45分授業で、4つ(情報、電気電子、材料加工、生物育成)の極意を伝えるなどという到底無理なことをやっているため、
大枠でこれらを把握する、ということはできているが、深い理解についてはさっぱりである。
広く浅くの典型である。

さて一方の現在の状態。
いまやWeb技術の、さらにバックエンドの専門屋見習いとしているわけである。
深い専門性を求められ、周りは他所で修羅場をくぐり抜けてきた中堅〜エキスパート。
最初からクライマックスなわけで、周囲はそれを分かっていて話が進む。
狭く深く。

その状態でいるため、現在27歳の私としては、内心将来やっていけるのか相当不安に感じているのだろう。

そうなると目先で自分が得意だと思っている分野、やれば形ができる簡単なことに走りがち。
アイデンティティと優位性がなにもない。これについては、私はプライドが相当高いのとこだわりがある程度強いので、なかなかストレスである。

かの博多華丸大吉のネタにこのようなものがある。
「低い低いと思って高いのが尿酸値とプライドですな！」
本当にそうだと思ってはいるものの、自分のことは棚に上げがち。

それでも基礎がなっていなくて将来的にプロジェクトに迷惑を掛けるぐらいならば、
プロジェクトの人々のやりかたを忠実にトレスして、いい方法を模索して行ったほうがいい、と思うようにしていきたい。

何に於いても100%の技術を持っている、という人はいないかもしれない。
ただ99%の技術を持っている人は、この会社にはゴロゴロいる。
その人たちのやり方を何人もトレスすることで、99.999...%にしていきたい。

「よその子とオクラは育つのが早いですな！」
そのように思ってもらえるよその子になるために、
今は凸凹の基礎を、まーるく収めていきたい。

その第一歩として、情報処理基礎の勉強を使ってみようとおもう。
年末年始、どの程度できるかはわからないが、やってみよう。
RTX1210　L2TP/IPsecを利用したリモートアクセスVPNの設定

RTX1210に複数ユーザからのリモートアクセスができるよう、設定します。

参考
https://network.yamaha.com/setting/router_firewall/vpn/vpn_client/vpn-smartphone-setup_rtx1200

#環境
- 利用機器：Yamaha RTX1210
- VPNプロトコル：L2TP/IPSec

- L2TPクライアント
 - 接続元IPアドレス：不定
 - 5ユーザ同時接続

- ネットワーク設定
 - ルータのLAN側NW：192.168.100.0/24
 - ルータのLAN側IPアドレス:192.168.100.1
 - クライアント割り当てIPアドレス：192.168.100.10 - 20/24


#RTX1210設定

【】内は環境に合わせて設定が必要です。

###・デフォルトGW設定
```
ip route default gateway 【XX.XX.XX.XX】
```

###・LAN側NW設定
```
ip lan1 address 192.168.100.1/24
ip lan1 proxyarp on
```

###・WAN側NW設定
```
ip lan2 address 【XX.XX.XX.XX/XX】
ip lan2 nat descriptor 100
```

###・L2TP接続の受け入れ設定
```
pp select anonymous
 pp bind tunnel1-tunnel5
 pp auth request mschap-v2
 pp auth username 【ユーザ名1】 【パスワード1】
 pp auth username 【ユーザ名2】 【パスワード2】
 pp auth username 【ユーザ名3】 【パスワード3】
 pp auth username 【ユーザ名4】 【パスワード4】
 pp auth username 【ユーザ名5】 【パスワード5】
 ppp ipcp ipaddress on
 ppp ipcp msext on
 ppp ccp type mppe-any
 ip pp remote address pool dhcp
 ip pp mtu 1280
 ip pp nat descriptor 100
 pp enable anonymous
```

###・L2TP接続で使用するトンネルの設定
tunnel設定はトンネルテンプレートで展開します
http://www.rtpro.yamaha.co.jp/RT/manual/rt-common/ipsec/tunnel_template.html

```
tunnel select 1
tunnel template 2-5
 tunnel encapsulation l2tp
 ipsec tunnel 1
  ipsec sa policy 1 1 esp aes-cbc sha-hmac
  ipsec ike keepalive use 1 off
  ipsec ike local address 1 192.168.100.1
  ipsec ike nat-traversal 1 on
  ipsec ike pre-shared-key 1 text 【事前共有鍵】
  ipsec ike remote address 1 any
 l2tp tunnel disconnect time off
 l2tp keepalive use on 10 3
 l2tp keepalive log on
 l2tp syslog on
 ip tunnel tcp mss limit auto
 tunnel enable 1
```

トンネルテンプレート適応外の設定は個別で設定します

```
tunnel select 2
ip tunnel tcp mss limit auto
tunnel select 3
ip tunnel tcp mss limit auto
tunnel select 4
ip tunnel tcp mss limit auto
tunnel select 5
ip tunnel tcp mss limit auto
```

###・NATの設定
NAT処理の外側IPアドレスは、**ip** interface **address** コマンドで設定されている IP アドレス利用のため
primaryに設定します。
http://www.rtpro.yamaha.co.jp/RT/manual/rt-common/nat/nat_descriptor_address_outer.html

```
nat descriptor type 100 masquerade
nat descriptor address outer 100 primary
nat descriptor address inner 100 auto
nat descriptor masquerade static 100 1 192.168.100.1 udp 500,4500
nat descriptor masquerade static 100 2 192.168.100.1 esp
```

###・DHCP設定
```
dhcp service server
dhcp server rfc2131 compliant except remain-silent
dhcp scope 1 192.168.100.10-192.168.100.20/24 gateway 192.168.100.1
```

###・IPSecトランスモード設定
こちらもテンプレートを利用します。
http://www.rtpro.yamaha.co.jp/RT/manual/rt-common/ipsec/ipsec_transport_template.html

```
ipsec auto refresh on
ipsec transport 1 1 udp 1701
ipsec transport template 1 2-5
```
###・L2TPの設定
```
l2tp service on
```

###・保存
```
save
```
#接続端末設定（Windows10の場合）
ネットワークとインターネット → VPNから設定します。

- VPNプロバイダー：Windows（ビルトイン）
- サーバ名またはアドレス：ルータIPアドレス
- VPNの種類：事前共有キーを使ったL2TP/IPsec
- 事前共有キー：ルータに設定した事前共有鍵
- サインイン情報の種類：ユーザ名とパスワード
- ユーザ名：ルータに設定したユーザ名
- パスワード：ルータに設定したパスワード
![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/514852/6025c626-c368-c626-e2e6-0e4760e8443e.png)

保存して接続します。
正しく接続できていれば、リモート接続した端末からルータのLAN側NWへアクセス可能です。
mysqlimportでドはまりした

# はじめに
スクリプトからmysqlimport処理をやろうとしてドはまりしたので解決法を残すことにした。

# エラー

```:
# 対処2が必要なエラー
mysqlimport: [Warning] Using a password on the command line interface can be insecure.

# 対処1が必要なエラー
mysqlimport: Error: 1045 Access denied for user 'username'@'localhost' (using password: YES)

# 対処3が必要なエラー
mysqlimport: Error: 1064, You have an errr in your SQL syntax: check the manual that corresponds to your MySQL server version for the right syntax to use near 'xxxxxxxxx' at line 1, when using table:xxxxxxx
```


# 1. File処理権限が必要

GRANT ALLではユーザにFILE権限が付与されない為、明示的な権限付与が必要になるらしい。

```sql:
> GRANT FILE *.* 'username'@'localhost';
> flush privileges;
```

# 2. スクリプトから直接認証情報を渡しちゃいけない

タイトルのまんま。読込をしたいスクリプト配下にmy.confなどを介することで認証情報を直接スクリプトに記述しないことで回避できた。

```sql:my.conf
[mysqlimport]
user = username
password = password
```

# 3. mysqlimport処理にて

色々オプションを指定するうえで、使い方を間違えている箇所があった。

```bash:
mysqlimport --defailts-extra-file=./my.conf --fields-terminated-by="," --fields-enclosed-by='"' --local {databasename} {csv file} 
```

# 参考
- MySQLでmysqlimportが出来ない問題を解消 https://qiita.com/Hirata-Masato/items/86a4d566983ddf44ed6f
- MySQL - csvデータをデータベースに格納する方法 https://qiita.com/makaaso/items/df591e753074b715a3e7
モンテカルロ木探索で作るクアルト専用対戦AI

本記事では私が作成したクアルトAIについて解説を行っていく。

手法としてモンテカルロ木探索を用いているため、内容の解説は主にモンテカルロ木探索に関する内容が主体である。

## クアルトとは
ちょっとマイナーなゲームなので少し説明すると、クアルト(Quarto)は、スイスの数学者ブレイズ・ミュラーによって1991年に考案された2人用のボードゲームである。by Wikipedia
ルールの説明には[この動画](https://www.youtube.com/watch?v=EeE3Rz6sCHo)がわかりやすいので、このあとの解説のためにも一度見てほしい。

## なぜクアルトのAIにモンテカルロ木探索を選んだか
クアルトのAIを作ることになったとき、当初は将棋などに使われている評価関数の概念をうまく実装できないか検討していたが、クアルトのコマは敵味方の区別がなく、ある時点の盤面を見たときにどちらのプレイヤーが有利か判断が難しいと思ったのでこれを断念。
そんな中なにか良い方法は無いかとネット上を探し回ってモンテカルロ木探索という手法を発見。
理屈が比較的簡単なうえ、クアルトは適当にプレイしても最大16手(コマ選択も含めると32手？)で必ずゲームが終了するという点からも相性がいいと考えてこの手法を採用。
最終的に１ヶ月強しかなかった開発期間でかなりの性能が発揮できたのでこの選択はあたりだったと思う。

## モンテカルロ木探索の仕組み
モンテカルロ木探索は以下のステップを繰り返すことで最適解を見つけ出すアルゴリズムである。

1. ノードの選択
    展開済みのゲーム木のノードの中からプレイアウトを行うノードを選択していく。葉ノードに到達するまで選択を繰り返す。

2. ゲーム木の展開
    １で選択した葉ノードからゲーム木を展開する。これを無制限に行うと膨大なゲーム木を生成してすぐにメモリを食い潰してしまうので実際に行う際は『５回以上プレイアウトが行われた場合』のように無駄に展開されないよう制限をかける

3. プレイアウト
    乱数によるシミュレーションを行う。要は適当に手を進めてゲームを終了させる。

4. プレイアウト結果の伝達
    葉ノードで行ったプレイアウトの勝敗をゲーム木の根の方へ伝達させる。

これらのステップを決まった回数、または時間が許す限りひたすら繰り返し、勝率の高い手を見つけ出す。

自分がクアルトAIを作成した時は、イベントのルールでAIの応答時間に制限があったため、シミュレーションは時間制限の中できる限り行うようにした。

## プレイアウトの制度を上げる
アルゴリズム手順3.プレイアウトをクアルト用に最適化する
１回のプレイアウトの制度が上がればより少ない回数で最適解を見つけることができる。
クアルトのプレイアウトでは具体的に以下の制御を組み込むことでプレイアウトの制度を上げた。

- 自分から負ける手を選択肢から外す
    クアルトの特徴としてコマを選んで相手に渡すというルールがある。つまりリーチになっている種類のコマを選んで相手に渡すと負けとなる。実際のプレイでこのコマを選択することは無いのでプレイアウトでも選択肢から外す。

- 必ず勝てる手があるときはその選択肢を選ぶ
    リーチとなっている種類のコマを相手から渡された場合当然その場で勝利が確定する。実際のプレイでこれをわざわざ見逃すことは無いのでプレイアウトでも必ず勝利する選択肢を選ばせる。

## バランスよくノードを選択する（UCT）
アルゴリズムの手順1.ノードの選択では勝率が高いノードにできるだけ多くのプレイアウトを行いつつ、試行回数の少ないノードにもある程度プレイアウトを行いたい。
これをバランスよく行う手法にUCT（Upper Confidence Tree）というものがある。
これは木探索にUCB1(Upper Confidence Bound 1)というアルゴリズムを組み込んだものだ。
UCB1値は以下の計算式で求めることができる。これを各ノードで計算し、一番数値が高くなったものを選択していくことでバランスを良くノードを選択できる。

```math
\begin{align}
UCB1 &= \frac{勝利数}{プレイアウト数} + 定数\sqrt{\frac{2*\log{総プレイアウト数}}{プレイアウト数}}\\
\end{align}
```

定数は必要に応じて調整する。
この数値を低くするとより勝率の高い手が選ばれやすくなり、
高くすればプレイアウト回数が少ない手が選ばれやすくなる

## 作成したAI「クトゥアルト」と対戦する
GitHub Pagesに作成したAIを公開している。ぜひ対戦してみてほしい
[対戦ページ](https://keyhole0.github.io/Ktuarto/)
はじめての electron-rebuild 使い方

モジュールをインストールするときに
`npm i -D serialport`
のように、`--save-dev` オプションをつけているとうまくいかない。

`electron-rebuild`は`package.json`の`dependencies`を参照するため、`--save-dev` オプションで書き込まれる`devDependencies`のモジュールはリビルドできない。

`dependencies`にリビルドしたいモジュールが書かれていることを確認したら、
`$ ./node_modules/.bin/electron-rebuild`
`$ npm start`

で解決した。
WSL anaconda jupyter でSpark遊び (2)

#[前回](https://qiita.com/lin_shubin/items/88cdc0c4ac2dce043ccd)環境設定の続き
*いよいよSpark RDDのHellowordを実装しようと、*

```
rdd = sc.parallelize(['A', 'B', 'C', 'A'])
keyvalues = rdd.map(lambda x: (x, 1))
counts = keyvalues.reduceByKey(lambda a, b: a + b)
counts.collect()
```
*エラー発生!!*
*IllegalArgumentException: 'Unsupported class file major version 55'*

*急遽Googleに聞きました。*
*Javaのバージョンに問題があったみたいです。*

```
(base) xxxx:~$ sudo update-alternatives --config java
alternative java (/usr/bin/java を提供) には 2 個の選択肢があります。

  選択肢    パス                                          優先度  状態
------------------------------------------------------------
* 0            /usr/lib/jvm/java-11-openjdk-amd64/bin/java      1111      自動モード
  1            /usr/lib/jvm/java-11-openjdk-amd64/bin/java      1111      手動モード
  2            /usr/lib/jvm/java-8-openjdk-amd64/jre/bin/java   1081      手動モード
```

*Java 8に切り替え、update-alternativesで２を選択*

```
(base) xxxx:~$ sudo update-alternatives --config java
alternative java (/usr/bin/java を提供) には 2 個の選択肢があります。

  選択肢    パス                                          優先度  状態
------------------------------------------------------------
* 0            /usr/lib/jvm/java-11-openjdk-amd64/bin/java      1111      自動モード
  1            /usr/lib/jvm/java-11-openjdk-amd64/bin/java      1111      手動モード
  2            /usr/lib/jvm/java-8-openjdk-amd64/jre/bin/java   1081      手動モード

現在の選択 [*] を保持するには <Enter>、さもなければ選択肢の番号のキーを押してください: 2
update-alternatives: /usr/bin/java (java) を提供するためにマニュアルモードで /usr/lib/jvm/java-8-openjdk-amd64/jre/bin/java を使います
(base) xxxx:~$ java -version
openjdk version "1.8.0_222"
OpenJDK Runtime Environment (build 1.8.0_222-8u222-b10-1ubuntu1~18.04.1-b10)
OpenJDK 64-Bit Server VM (build 25.222-b10, mixed mode)
```
*Jupyter再起動　成功しました!!*
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111216/69d75047-299b-5e52-cf37-bb05c434fd56.png)

*備考：JAVA_HOMEの設定と無関係*
svelte-spa-routerを使ってみる

#svelteとsvelte-spa-routerでSPAを作る

[Svelte](https://svelte.dev/)
[Svelte-spa-router](https://github.com/ItalyPaleAle/svelte-spa-router)
[Svelteテンプレート](https://github.com/sveltejs/template)



```bash:degetをインストール
$ npm install -g degit
```

```bash:degetでテンプレートをダウンロード
$ degit sveltejs/template svelte-app
```

```bash:起動してみる
$ cd svelte-app
$ npm install
$ npm run dev
```

```bash:svelte-spa-routerのインストール
$ npm install svelte-spa-router
```

### app.svelteにRouterタグを設置
```svelte:svelte-app/src/app.svelte
<script>
  import Router from 'svelte-spa-router' #svelte-spa-routerをインポートする
</script>

<body>
    <Router {routes}/> #パスに対してマッチしたコンポーネントを描画
</body>
```

### app.svelteにコンポーネントとルーティング設定を追加
```svelte:svelte-app/src/app.svelte
<script>
import Router from 'svelte-spa-router'
import Home from './routes/home.svelte'
import Showpage from './routes/showpage.svelte'

const routes = {
    '/': Home,
    '/showpage/': Showpage,
}
</script>

<body>
    <Router {routes}/>
</body>
```

### home.svelteを作成しshowpageへのリンクを設置
```svelte:svelte-app/src/routes/home.svelte
<script>
  import {link} from 'svelte-spa-router' #svelte-spa-routerのlinkをインポートする
</script>

<h1>Homepage</h1>
<a href="/showpage" use:link>showpageへ</a>
```

### showpage.svelteを作成しhomeへのリンクを設置
```svelte:svelte-app/src/routes/showpage.svelte
<script>
  import {link} from 'svelte-spa-router' 
</script>

<h1>showpage</h1>
<a href="/" use:link>Homeへ</a>
```

```bash:起動してみる
$ npm run dev
```
WEB分離化についての考察

#はじめに
WEB分離化は2010年頃よりマルウェアによる甚大な被害が世界的な問題となり、日本でも2015年5月、**日本年金機構に対し外部から「標的型攻撃メール」**が送られ、その結果年金管理システムに保管されていた**125万人分の個人情報が漏洩**しました。この問題の発生を受けて、**WEB分離化が注目**され特に機密情報を所有する国家機関や省庁、地方自治体で導入が進んでいます。
####WEB分離化とは
以下に示すのは**「自治体情報システム強靭性向上モデル」**というもので、これまで多くの自治体は、LGWAN（統合行政ネットワーク）接続系ネットワークと、インターネット接続系ネットワークを同一ネットワーク内に設置していました。今回の総務省の通達を受けて、各自治体はこれらのネットワークを分離する必要があります。（アシスト社のHPより引用）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/296178/b21d3e32-d3d1-4d8b-6e0d-657c62766f96.png)

####WEB分離化が出来る組織は恵まれている
この分離化が出来る組織は良いのですが、社内の全員がインターネットに接続しないと業務が成り立たない企業はどうなるか？そこで、登場したのが**「WEBの仮想化と無害化」**でした。以下の図はMenlo SecurityのHPからお借りしました。

**Menlo Securityは**WEB分離化の二つの方式の**レンダリング**に該当し速度も十分に速く好評です。一方、**画面転送の方式**は遅いのですが、確かに安全性は高いと言えます。WEB分離化を採用できる企業はラッキーで恵まれていると言えるでしょう。

######１．WEB分離化の二つの方式
- WEBサイトに別のコンピュータでアクセスし、画面を自分のコンピュータに表示する仮想化。
- アクセスしたWEBサイトのレンダリングを行い安全化して自分のコンピュータに表示する無害化。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/296178/f0161f50-47f4-c96d-dd12-db06678aafd3.png)

######２．WEB分離化を導入しない組織とは

**（動かない機能がある）**
- 2019年11月現在の話ですが解決出来ていない例を実際に認知しています。運営しているサービスがWEB分離化の各社の方式では動作しない場合があります。同様にそのサービスを利用している企業ではWEB分離化を導入できなくなっています。
**（システムの複雑化）**
- WEB分離化は仮想化などシステムが複雑化し、レンダリングサーバに問題が発生するとWEB接続が切れます。
- コストの問題とメンテナンスの問題が無視出来ない場合は導入出来ないようです。
**（リモート環境の問題）**
- リモート環境でのWEB分離化はMenlo Securityについては可能ですが、困難な場合が多く外でPCを多用する組織では片手落ちとなってしまいます。その不完全さが理由で採用しない場合も現在は多いようです。
**（盲点がある）**
- 指摘されている一つはファイルの取扱いの問題です。プレビューしたメールの添付ファイルやWEBファイルをクラウドの安全な領域で扱わずにPCへダウンロードしてしまうという問題はゼロでは無いようです。
- もう一つは画面に表示された情報を信用するかしないかは読んだユーザ次第です。フェイクな情報かは分離化でも解決はできませんので、屁理屈に近いですが、そこは一つの問題として残ってしまいます。
####マルウェアの侵入経路を完全に塞げるか
マルウェアの概要については触れませんが、侵入経路は以下が主なものになる事は一般に認知されています。

- メールの添付ファイル
- WEBからダウンロードされる各種ファイル
- 閲覧したWEBサイトからの書き込み
- USB等の記憶メディア

この中で「閲覧したWEBサイトからの書き込み」は分離化で完全に近く防止できますが、その他についてはユーザレベルでは完全に扱えないようにしてしまう以外には侵入は100％無いとは言えません。持ち込む気になれば持ち込める、ダウンロードする気になればダウンロード出来るのでは危険です。
####本当に安全な分離化とは全てのファイルを仮想領域で扱える事
GoogleのGメールではメールの添付ファイルをプレビューするのと同時にGoogleのドライブで安全に扱う事が推奨されています。またMicrosoftのクラウドでも同様の機能を持っています。最近はDropBox等も追従しているようですので、クラウドサービスそのものは安全対策が充実して来ていると言えます。
####課題はWEB分離化、クラウドストレージ、クラウドアプリの連携
少々ベタな表現になりますが**「WEB分離化+クラウドストレージ+クラウドアプリ」を今後は３本の矢**として考える必要を強く感じています。この３本の矢がマルウェアの侵入経路全てにローカルPCを介さずに対応する事が重要だと思います。その場合はUSB等の記憶メディアは使用禁止にするか、クラウドのドライブに直接転送できる外部ストレージというのも考える必要がありそうです。
####ファイルフォーマットの問題
現在「WEB分離化+クラウドストレージ+クラウドアプリ」では大半がオフィス系のデータのみに対応してます。最近の報告で、検知することが非常に難しいランサムウェア「SODINOKIBI」は「zip」ファイルで送り込まれるという事を考慮しますと、圧縮されたファイルに対応する事も重要でしょう。これは時間の問題で解決はしそうですが、３本の矢と同様に早急な対策をWEB分離化をサービス化している各社にはお願いしたいと思います。
[Apple] iOS向けにB2B業務アプリを配信する手続きまとめ

# これはなに？

App Storeへ公開しない、B2B業務向けカスタムAppを配信する方法が分かりづらかったのでまとめました。

# 必要な要件

* アプリを使いたい組織への要件
  * Apple Business Managerを契約していること
* アプリを開発する組織への要件
  * Apple Developer Programへ登録していること
  * App Store Connectへ登録するアプリを特定組織向けに配信するように設定すること

ちなみにApple Business Managerは無料です。

# 手続き全体

手続き全体は下記の図のようになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59475/0e8d42d7-636d-dac6-741b-3ff9b6401658.png)

図の作成には、とても便利で使いやすい https://draw.io/ を使いました。
感謝！

# 気をつけること

Apple Business Managerで購入したアプリは、その組織内でしか利用できません。
パートナー企業等に提供してはいけません。

# 参考リンク

* [Apple Business Managerユーザーガイド](https://support.apple.com/ja-jp/guide/apple-business-manager/welcome/web)
* [VPPでカスタムB2B Appを配信する際について](https://qiita.com/miyae/items/426b8819a4f16f740d02)
* [カスタムB2BアプリをVPPで配信する方法について　ざっくりなメモ](https://qiita.com/hosso/items/6333a2e840fb52af037d)
* [ややこしいiOSアプリ配布方法の俯瞰とケースバイケースの配布方法選定](https://qiita.com/cross-xross/items/a5a9fceff706e3e740c3)
ESXi 6.7上で、FirePro W7100をPCIパススルーしたゲストWin10の再起動をすると、ゲストがハングアップする問題を解決する方法 (How to solve the issue that the guest Win10 in ESXi 6.7 with PCI-passthru-ed FirePro W7100 hangs up when restart the guest)

# 詳細 details
ホスト再起動後一発めはゲスト起動できるのに、ゲスト再起動時にゲストが立ち上がってこない。
デバイスリセットがかからないためではないかと推測し調べてみると、デバイスリセット方法を指定できるとのこと。
defaultで何になっているのかわからないが、`d3d0`にしてみると動くようになった。

Although the guest can be started for the first time after rebooting the host, the guest does not start up when the guest is restarted.
I guessed the device reset did not take place and investigated about that, then I found the VMWare document how to specify the device reset method.
I don't know what the default is, but it works when I set it to `d3d0`.

## 追記 P.S.
W9100でも有効な模様。

This tip seems to work with W9100 too.

# 解決法 Solution
以下の行を`/var/vmware/passthru.map`に追加。
Add these lines to `/var/vmware/passthru.map`.

> \# AMD FirePro W7100
> 1002  692b  d3d0     false
> 1002  aad8  d3d0     false

# 注意 Notice
あなたの問題がこれで解決する保証はないです。
This information do not guarantee that you will be able to solve the problem you have.

# References
[VMware vSphere VMDirectPath I/O: Requirements for Platforms and Devices (2142307)](https://kb.vmware.com/s/article/2142307)
Pythonの例外処理（Python学習メモ⑥）

## 例外の処理
ポイント

* まずtryを実行し、例外が発生されなければそのまま終了
* 例外が発生した時点でtry節の残りがスキップされ、exceptで該当の型が定義されていればそのexcept節が実行される
* 例外の型がexceptで定義した名前と一致しない場合、例外はさらに外側にあるtry文に渡される
* ハンドラが見つからない場合は例外のメッセージを表示し、実行終了する
* except節は例外名を省略するとき、全部の例外を対象にすることができる(あまり良い方法ではない)

```python
import sys

try:
    f = open('myfile.txt')
    s = f.readline()
except OSError as err:
    print("OS error: {0}".format(err))
except ValueError:
    print("データが整数に変換できません。")
except:
    print("予期せぬエラー: ", sys.exc_info()[0])
    raise # 呼び出し元でキャッチできるように例外を再送出

```

* タプルを使うと1つのexcept節で複数の例外を指定することができる 

```python:複数の種類の例外をキャッチ
except(RuntimeError, TypeError, NameError):
    pass
```

* else節を使用することでtry節で例外が発生しなかった場合のみ実行する処理を書くことができる 
* また、`except 例外名 as err`のように記載すると`err`には例外インスタンスが渡される
* 例外名は`err.__str__()`で参照可能

```python:else節を追加
import sys

try:
    f = open('myfile.txt')
    s = f.readline()
except OSError as err:
    print("OS error: {0}".format(err))
except ValueError:
    print("データが整数に変換できません。")
except:
    print("予期せぬエラー: ", sys.exc_info()[0])
    raise # 呼び出し元でキャッチできるように例外を再送出
else:
    print(s)
    f.close()

```

## 例外を起こす
ポイント

* `raise 例外名(引数)`で例外を強制的に発生させられる
* except節内で単に`raise`と書くと例外を再送出できる

## 例外を定義する
ポイント

* 例外クラスを作成すると独自の例外を定義できる
* 通常はExceptionクラスから派生したクラスとする

```python:例外クラス

class MyError(Exception):
    def __init__(self, value):
        self.value = value
    def __str__(self):
        return repr(self.value)
    
try:
    raise MyError(2*2)
except MyError as e:
    print('My exception occurred, value:', e.value)
# 出力
# My exception occurred, value: 4

raise MyError('oops!')
# 出力
# Traceback (most recent call last):
#   File ".\exception_class.py", line 12, in <module>
#     raise MyError('oops!')
# __main__.MyError: 'oops!'

```

## try-finallyでクリーンアップ処理
ポイント

* finally節は、例外発生の有無にかかわらず、tryを抜けるときに必ず実行される
* try文内の他の節からbreak, continue, return文によって抜けるときも実行される

```python:finallyの例

def divide(x, y):
    try:
        result = x / y
    except ZeroDivisionError:
        print("ゼロ除算エラー")
    else:
        print('答え: ', result)
    finally:
        print('in finally')

divide(2, 1)
# 答え:  2.0
# in finally

divide(2, 0)
# ゼロ除算エラー
# in finally

divide("2", "1")
# in finally
# Traceback (most recent call last):
#   File ".\divide.py", line 15, in <module>
#     divide("2", "1")
#   File ".\divide.py", line 3, in divide
#     result = x / y
# TypeError: unsupported operand type(s) for /: 'str' and 'str'
```

## withでクリーンアップ処理
ポイント

* オブジェクトには標準のクリーンアップ動作が定義してあるものがある(例えばファイルオブジェクトなど)
* with文を使う事でデフォルトのクリーンアップ処理が自動的に実行される

```python
with open('workfile', 'r') as f:
    read_data = f.read()

print(f.closed)
# True
```
繰り返し2乗法、行列累乗

# 繰り返し2乗法

繰り返し2乗法とは、指数を2の累乗の積に分解し、計算を効率化するテクニック。
例えば、$3^{50}$が与えられたとき、
$14 = 2^3 + 2^2 + 2^1$と表せるため、$3^{14} = 3^{2^{2^{2^2}}} × 3^{2^{2^2}} × 3^{2^2}$ と変形できる。

愚直に計算した場合、$O(n)$の計算量になるころを、繰り返し2乗法を使って計算することにより、$O(logn)$の計算量になる。

```python
def pow(x, n):
    ans = 1
    while n:
        if n % 2:
            ans *= x
        x *= x
      # ここの処理でx→xの2乗→xの4乗、、、と指数が倍になっていく
        n >>= 1
    return ans
```

注: ただ、pythonの場合、累乗の組み込み関数のpowで繰り返し2乗法が実装されているため、
実際のところこうした実装を自前でする必要はない。

https://atcoder.jp/contests/abc129/tasks/abc129_f

# 行列累乗(F - Takahashi's Basics in Education and Learning)

このテクニックを使い、行列の累乗も効率化できる。
行列の累乗への拡張は以下のようにする。

```python



def mat_mul(a, b) :
    I, J, K = len(a), len(b[0]), len(b)
    c = [[0] * J for _ in range(I)]
    for i in range(I) :
        for j in range(J) :
            for k in range(K) :
                c[i][j] += a[i][k] * b[k][j]
            c[i][j] %= m
    return c


def mat_pow(x, n):
    y = [[0] * len(x) for _ in range(len(x))]

    for i in range(len(x)):
        y[i][i] = 1

    while n > 0:
        if n & 1:
            y = mat_mul(x, y)
        x = mat_mul(x, x)
        n >>= 1

    return y


l, a, b, m = LI()
d0 = 0
ret = [[0], [a], [1]]
for i in range(1, 19):
    if 10 ** i - 1 - a < 0:
        continue
    d1 = min((10 ** i - 1 - a) // b + 1, l)
    mat = [[10 ** i, 1, 0], [0, 1, b], [0, 0, 1]]
    ret = mat_mul(mat_pow(mat, d1 - d0), ret)
    if d1 == l:
        break
    d0 = d1


//　行列計算の順番によって答えが変わる
// 上の例だと、正方形の右側に縦一列の行列がある
// 正方形の中で入力が横、出力が縦のイメージ。行列の順番が逆
//　だと逆になる

print(ret[0][0])
```
レーベンシュタイン距離から言語間の類似度を比較してみた

# はじめに

昔ヨーロッパに住んでいたことがあるのですが、マルチリンガルな方が多くて驚かされた経験が沢山あります。一方で、例えばパイナップルという単語がフランスでもオランダでもイタリアでもAnanasだったりという共通点もあり、各国の言葉は結構似てるのかしらと不思議に思ったものです。
そこで今日は、レーベンシュタイン距離のお勉強の題材として各国の言語をチョイスし、それらを比較してみることにします。

# レーベンシュタイン距離とは？

レーベンシュタイン距離とは、編集距離とも言うのですが、2つの文字列がどの程度異なっているかを示す距離の一種です。具体的には、1文字の挿入・削除・置換によって、一方の文字列をもう一方の文字列に変形するのに必要な手順の最小回数を計算します。
例えば"analytics"と"analysis"の間の距離を計算するとしましょう。この場合、①analyticsのtをsへ置換　②analyticsのcを削除　の2回の操作によって"analytics"を"analysis"に変換できるので、レーベンシュタイン距離は2となります。

analytics
↓ ①tをsへ置換
analysics
↓ ②cを削除
analysis

この距離を使って最近傍の単語を検索・置換することで、スペルミスを修正したりすることができます。

# 環境

MATLAB R2019bを使用しています。レーベンシュタイン距離の計算のためにText Analytics Toolboxも使います。

# 計算のステップ

### データの読み込み

今回はお試し版として[中1英単語・名詞1](http://www.eigo-duke.com/tango/chu1.html)にある50語のみをピックアップ。英語をベースにして、Google翻訳にてオランダ語、ドイツ語、イタリア語、フランス語へ翻訳します。
（翻訳結果が正しいかは確認できていません）

データは下記の感じです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/521542/f031559e-3876-58b9-9f3a-0b58e7a007f7.png)

例えば5行目のtomorrowを見ると、オランダ語とドイツ語が同じ綴りだったり、イタリア語とフランス語が見た感じ似ていたり、という特徴がわかります。

### レーベンシュタイン距離の計算

それでは早速レーベンシュタイン距離を計算していきます。Text Analytics Toolboxにある[editDistance](https://jp.mathworks.com/help/textanalytics/ref/editdistance.html)という関数を使います。

例えば英語とドイツ語の距離を計算させると、下記のように、各単語間の距離が50個分ずらっと計算されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/521542/b8489957-40bf-4a38-b959-49685d171677.png)

### 言語間の距離を可視化

50単語しかないのでデータ数としては少ないのですが、手っ取り早く50語分の距離を平均し、heatmapにて可視化してみます。コードは下記。

```MATLAB
load LanguageMat % table型で事前に用意しています。「データの読み込み」欄の画像を参照。

for ii = 1:width(LanguageMat)
    for jj = 1:width(LanguageMat)
        DistanceMat(ii,jj) = mean(editDistance(table2array(LanguageMat(:,ii)),table2array(LanguageMat(:,jj))));
    end
end

figure;
h = heatmap(LanguageMat.Properties.VariableNames,LanguageMat.Properties.VariableNames,DistanceMat);
```

結果はこちら。距離の値が小さいほど類似度が高いです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/521542/28520361-27df-16f9-08ab-e8caf752daf8.png)

[LanguageMat](https://qiita.com/drafts/a8769100068e6e7f973b/edit#%E3%83%87%E3%83%BC%E3%82%BF%E3%81%AE%E8%AA%AD%E3%81%BF%E8%BE%BC%E3%81%BF)を見て直観的に感じる通り、レーベンシュタイン距離からも、
・英語とオランダ語が似ている
・オランダ語とドイツ語が似ている
・イタリア語とドイツ語はあまり似ていない
・フランス語とイタリア語は比較的似ている
などといった特徴を見て取ることができました。

# おわりに

ヨーロッパの言語分布から見てみると（参考：ディルケ世界地図帳）、
・英語・オランダ語・ドイツ語＝ゲルマン系言語
・イタリア語・フランス語＝ラテン系言語
なので、なかなか腑に落ちる結果になったかなと思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/521542/926f45fc-06ed-c93d-8b9f-230a1b4658ea.png)

他の言語でも試してみると、また面白い結果が得られそうですね。
#Rails で options リクエストに対して ルーティングする例

# 注意

OPTIONS request の役割とか考えてない例

# routes.rb

こんなん

```
Rails.application.routes.draw do
  root to: 'roots#main', via: :options
```

# controller

```rb
class RootsController < ApplicationController
  def main
    head 200
  end
end
```

# curl で確認

```
curl -s -v -X OPTIONS http://localhost:3000/ 
```

# rspec

ちなみに rspec で options のリクエストをする方法がわからんとです。


# Original by Github issue

https://github.com/YumaInaura/YumaInaura/issues/2715








<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
laravel5.3 500エラーがでる（storageとviews権限の問題だった）

# laravelでの500エラーを解決する
##環境
laravel 5.3
php 5.5
dockerの仮想環境内

## 一番最初:"Fail not found"のエラー
nginxに原因があると考え[こちら](https://qiita.com/tech31/items/8ab2ec43bdf48ad15bac#2nginx%E3%81%AE%E8%A8%AD%E5%AE%9A)を試しました。
containers\nginx\default.confを修正。


《結果》
"このページは動作していません　HTTP ERROR 500"
エラーは変わった！

## "このページは動作していません　HTTP ERROR 500"
[こちら](https://saba.omnioo.com/note/2328/laravel5-%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E5%BE%8C%E3%81%AB%E3%81%97%E3%81%A6%E3%81%8A%E3%81%8F%E3%81%93%E3%81%A8/)を参考にしました。
service/storage
service/resources/views
この２つのディレクトリ下のファイルの権限を777にしたら解決できました。
各ディレクトリに移動後、
```chmod -R 777 storage/
chmod -R 777 views/
```
をたたく。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/528764/309d0721-52dd-3c4f-ae43-0fe73f334d3f.png)

わぁ☝(⇑⇑)☝！！
BitbucketのMercurialのリポジトリをGitへ移行する

# BitbcuketのMercurialのサポートが2020年に終了するようなので移行しないといけなくなった
[参考:bitbucket.orgでmercuialのサポート終了のお知らせ](https://bitbucket.org/blog/sunsetting-mercurial-support-in-bitbucket)

概要：2020/2/1に新規でリポジトリ作成ができなくなり、2020/6/1にMercurialのリポジトリが削除されるらしい。

## それで引き続きBitbucketを使い続けたい場合
これを機にBitbucketからGitHubへ移りたいという場合は別の記事を参照ください。ここではBitbucket内でのリポジトリの変換をする場合の手順について書きます。

## 主な手順は下記リンクの通り
[Gitとその他のシステムの連携-Git-へ移行する](https://git-scm.com/book/ja/v2/Git%E3%81%A8%E3%81%9D%E3%81%AE%E4%BB%96%E3%81%AE%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0%E3%81%AE%E9%80%A3%E6%90%BA-Git-%E3%81%B8%E7%A7%BB%E8%A1%8C%E3%81%99%E3%82%8B)

## 変換の概要
上記の手順はUbuntu16.04上で実行することになっているので、その環境を準備する。
変換手順はリポジトリ名を同じにしたいので、Bitbucket上のMercurialのリポジトリの名前を変更する。（sampleというリポジトリ名の場合、sample-Hgのようにする）
そして、変換後のGitのリポジトリを予め作成しておく。

1. sample-Hgリポジトリ(Mercurial)からクローン
2. ローカルでGitに変換
3. sampleリポジトリ(Git)へpushする。

という手順とする。

## 手順通りにやってもうまくいかない
まず、取得するようになっている、fast-exportがエラーを吐いて動かないので、一旦説明通りにcloneした後、下記コマンドで動くrevを取得

    git checkout tags/v180317
 
次に手順通りだと、authorsファイルが作成され、Gitの記述方に沿った書き方でない場合、変換する必要がある。とあるがそのまま書いたのではエラーになるため、下記の書き方にする必要がある。

    (誤) bob=bob Jones <bob@company.com>
    (正) "bob"="bob Jones <bob@company.com>"
つまり、ダブルクォートで左右の文字列を囲むようにということのようだ。

上記の点を踏まえると、Bitbucket内でプロジェクトの変換ができた。
Laravelのファイルパーミッションの問題

## 問題発生！！
会社の仕事でアプリケーションの速度を改善するためにDBからマスターテーブルのModelを取得してCacheに格納する方法を利用しました。ウェブの速度はかなりよくなりCacheを使ってよかったと思いましたが、問題が発生！！OTZ

### ユーザーの構成
- バッチ実行ユーザー：ec2-user
- ウェブ（Apache）ユーザー：apache
- ec2-userのサブグループにapacheを入れている

作ったCacheを同じくバッチで使用するとパーミッションエラーが出ますね。読み込みは問題ないですが（？）、作成されるディレクトリがウェブで作成したものだと「755」で、バッチ実行ユーザーで新しくファイルを作れないエラーが発生しました。

## 解決方法
### ログファイル
詳しく：https://qiita.com/FattyRabbit/items/fff02397647d54458871

```php:config/logging.php
        'single' => [
            'driver' => 'single',
            'path' => storage_path('logs/laravel.log'),
            'level' => 'debug',
            'permission' => 0664,
        ],

        'daily' => [
            'driver' => 'daily',
            'path' => storage_path('logs/laravel.log'),
            'level' => 'debug',
            'days' => 14,
            'permission' => 0664,
        ],
```
### Storageファサードを利用する場合
Laravel は Flysystem という PHPパッケージを使用しているらしいので、見てみましょう！
https://flysystem.thephpleague.com/docs/adapter/local/

```
$adapter = new Local(
    __DIR__.'/path/to/too',
    LOCK_EX,
    Local::DISALLOW_LINKS,
    [
        'file' => [
            'public' => 0744,
            'private' => 0700,
        ],
        'dir' => [
            'public' => 0755,
            'private' => 0700,
        ]
    ]
);
```
こうらしいです。
vendor/laravel/framework/src/Illuminate/Filesystem/FilesystemManager.phpのcreateLocalDriverメソッドにpermissionsが突っ込まれるようなので「config/filesystems.php」を修正しました。

```php:config/filesystems.php
        'local' => [
            'driver' => 'local',
            'root' => storage_path('app'),
            'permissions' => [
                'file' => [
                    'public' => 0764,
                    'private' => 0700,
                ],
                'dir' => [
                    'public' => 0775,
                    'private' => 0700,
                ]
            ]
        ],
```
### それ以外（手っ取り早くやる場合）
AppServiceProvide.phpとかにumaskを書くちょっと気に喰わない方法ではありますね。

```php:app/Providers/AppServiceProvide.php
    public function boot()
    {
        umask(0002);
    }
```
こんな感じです。先頭で話はCacheの問題はこちらの方法で解決はしました。***残念！！！！！！***

cacheは「Illuminate\Cache\CacheManager::createFileDriver」で「FileStore」を利用してますが、設定ファイルのpathのみ渡して、「\$this->files->makeDirectory」や「\$this->files->put」等を利用しています。makeDirectoryはパーミッションを設定していますが、umaskに影響される様子です。
:relaxed::relaxed::relaxed::relaxed:

*** 追加：2019.11.14
[Laravelのキャッシュファイルのパーミッション設定](https://qiita.com/FattyRabbit/items/693b367bfb2b27e0e4a1)
最大値を探そう python(改良)

前回書いた記事([最大値を探そう python (修正ver)](https://qiita.com/banana19980702/items/06db0f8fdb1ac175651c))についてアドバイスをいただいたのでさらにリファクタリングをしてみました。今回は可読性に重点を置きコードを改変してみました。
##変更点
 ・for文のループ処理の時の変数の設定の仕方
***
コードは以下の通りです。

```python
num = int(input("何個数値を代入しますか?"))
value_list = [] #数値を格納する配列を用意する

for i in range(num):
    value = int(input("数値を代入して下さい"))
    value_list.append(value) #用意したリストに値を追加していく


max_value = value_list[0] #リストの要素で初期化

for value in value_list:
    if value > max_value:
        max_value = value

print(max_value) #最大値を出力
```
##変更したコード

```python:変更前
for i in range(num):
    if value_list[i] > max_value:
        max_value = value_list[i]
```

```python:変更後
for value in value_list:
    if value > max_value:
        max_value = value
```
***
こっちのコードの方がシンプルでよりわかりやすいですね。
記事を書けば書くほどいろいろな発見があり、とても勉強になります。
VSCodeでMagic xpa マージWebアプリケーション開発を快適に行うスニペット設定

## Magic xpaって？

**Magic xpa**は、Web、モバイル、およびデスクトップのビジネスアプリケーションを簡単かつ迅速に作成できる超高速開発ツールです。

> [引用元]
> https://www.magicsoftware.com/ja/app-development-platform/xpa/

古くは**dbMagic**という名称で親しまれていた(?)かと思います。

Magic xpaには**マージ**と呼ばれる機能があり、テンプレートとなるHTMLに埋め込みした特殊なタグに対して動的に値を反映することができます。この機能を利用して、Webアプリケーションを作成することも可能です。

> [参考]
> マージ
> http://www.magicsoftware.co.jp/service/support/manual/magicxpa3/Mastering%20Magic%20xpa.pdf#page=555
> マージWeb アプリケーションを作成するには
> http://www.magicsoftware.co.jp/service/support/manual/magicxpa3/Mastering%20Magic%20xpa.pdf#page=573

## <!$MG_...>とか書くのが面倒くさい

Magic xpaで使用する特殊なタグというのは`<!$MG_xxx>`とか`<!$MGINCLUDE>`のように記述します。(※初期設定の場合)
でもいちいち手打ちするのは面倒くさいので、VSCodeのスニペット設定を使用して入力作業を簡略化しようと思います。
尚、スニペット設定はGit管理して VSCodeで開発する他技術者も活用できるようにします。

### 1. スニペット設定の雛形ファイルを作成する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/78896/5ab3de37-25a3-1f34-8ba1-52fa6d606a27.png)

VSCode上で[File]-[Preferences]-[User Snippets]を押下します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/78896/25cac7d7-91ca-ab6f-be56-159defe8b623.png)

今回はスニペット設定をGit管理したいと思っているので`./.vscode`ディレクトリ上に設定ファイルを生成します。
[New Snippets file for 'xxx'…]を押下します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/78896/c5a9c8c5-e294-ca0d-5646-0ff4e0a16a51.png)

スニペット設定ファイルの名前を指定します。今回は`project`という名前にしますが、皆様お好きな名前でどうぞ！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/78896/a92152c6-b99d-bc7b-dd6f-5a3b05fcddb9.png)

すると、`./.vscode/project.code-snippets`という雛形ファイルが生成されました。


### 2. 雛形ファイルを編集してスニペット設定を登録する

次のようなスニペットを登録してみました。

```json:project.code-snippets
{
  "<!$MG_xxx>": {
    "scope": "html",
    "prefix": "mgtag",
    "body": "<!\\$MG_$1>",
    "description": "<!$MG_xxx>"
  },
  "<!$MGIF_xxx?>": {
    "scope": "html",
    "prefix": "mgif",
    "body": "<!\\$MGIF_$1?><!\\$MGELSE><!\\$MGENDIF>",
    "description": "<!$MGIF_xxx?>"
  },
  "<!$MGREPEAT>": {
    "scope": "html",
    "prefix": "mgrepeat",
    "body": "<!\\$MGREPEAT>$1<!\\$MGENDREPEAT>",
    "description": "<!$MGREPEAT>"
  },
  "<!$MGINCLUDE>": {
    "scope": "html",
    "prefix": "mginclude",
    "body": "<!\\$MGINCLUDE>$1<!\\$MGENDINCLUDE>",
    "description": "<!$MGINCLUDE>"
  },
}
```

`"scope":`は どの言語にスニペットを利用するか指定します。今回は`"html"`で動作すれば十分です。
`"prefix":`は インテリセンスからスニペットを選択する際に使用する接頭語を指定します。`"mg..."`で統一しています。
`"body":`は スニペットを利用した際に展開される文字列を指定します。`$`は特別な記号で、`$1`とした箇所にカーソル位置が位置付きます。単純に`$`と入力したい場合は`\\$`とバックスラッシュ2つでエスケープします。`\$`のように1つではエスケープしないので注意！
`"description":`は スニペットの説明を指定します。未指定でも大丈夫です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/78896/a367be5d-3386-8a07-aa2a-548575144dde.png)

これで、画像のようにスニペットが登録できました！！

VSCodeのスニペット設定ってもっと小難しいと思い込んでいましたが、実際はとても簡単です。
一度やってみてください！

## 参考文献 他

> ■記事を書こうと思ったきっかけ
> マルチカーソルで、VSCodeのスニペットをもっと便利に。
> https://qiita.com/Yametaro/items/40b6c37437056f2a3ed5

> ■スニペット内での\$マーク エスケープ方法
> vscodeのスニペットで\$をエスケープする
> https://qiita.com/kunken308/items/df891b67b06f5250403e
PowerPointで画像を透明にしたのに印刷したらアレじゃんっていうときー！悲しいときー！

#チラシをPPTで作成し、紙に印刷してみたら…
ロゴ周りが背景から浮いてました

```bash:それってどんな画像？
良い質問ですね！
それは、ロゴの形くり抜かれており、
その周りが透明になっている、という画像です
```

#透明にしたのに！
ロゴ画像の透明部分が、なんだかうっすら白茶けていました
そういうときはどんなときですか
嬉しくはないですよね
悔しいというかんじでもありますが
つまり、**悲しいときー！**

>現物は守秘義務でお見せできませんので想像してください
すみません

Office365を会社から与えていただきましたので…
#`透明にしたのに印刷すると変な感じになるアレ`の回避方法
をここで

まず、ロゴ画像 -*ロゴの周りが透明な画像*- を
`写真ブラウザー`から、PPTに挿入します

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/528622/8e1ab648-e198-586f-216f-5228c32c0001.png)

このまま印刷 -`おそらくレーザープリンタでプリンタの機種にもよるが`- すると
ロゴ周りがうっすら白茶けます

#貼り付けた画像を`Ctrl+x`でカットして`形式を選択してペースト`します

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/528622/bea877f3-c55a-7b3a-d19d-8aeb7c37cbdc.png)

するとこんな↓ウィンドウが出ませんか？
出ますよね

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/528622/ed20f61f-c41d-3393-4db6-777b76a4fb6c.png)

#画像（TIFF）を選択します

これで印刷してみてください
うっすら白茶けたものはなくなっていませんか？
なくなっていますよね！

思った通りの結果が出たときってどんなときですか？
少なくとも悲しいときではありませんよね？
むしろその逆のときですよね？
それはどんなときですか？

#嬉しいときー！
python個人メモ

# はじめに
Pythonはほとんど覚えていない！
しかし、度々使用する必要があり、同じ事を何度も調べている気がするので、今後は備忘録を残そうと思います。
調べるごとに追加していこうと思います。

個人メモなため役に立たないかもしれませんが、よかったら使ってみてください。

# 型変換

```python
test_str = '100'
int(test_str)
```

# print()で改行なし

```python
print('text', end='')
```

# PATHの生成
```python
# add path
path = './'
path = os.path.join(path, 'dir')
# generate path
path = ['./', 'dir']
path = os.path.join(*path_list)
```

# インデックス番号と共にループ
`enumerate()`を使うと、カウンタの加算を書かなくてもループ時に取得できる。

```python:
test_list = ['test1', 'test2', 'test3']
for idx, test in enumerate(test_list):
  print('{} : {}'.format(idx, test))
```

# 文字列操作
## 文字列の分割
```python:
test_str = 'Hello World'
test_str.split() #スペースなどで区切る → ['Hello', 'World']
test_str.split('o') #'o'で区切る → ['Hell', ' W', 'rld']
```

## 文字列の結合
```python:
test_str = 'Hello World'
test_list = test_str.split()
test_join = ''
test_join = test_join.join(test_list) #間に`test`を入れて結合 → 'HelloWorld'
test_join = ' '
test_join = test_join.join(test_list) #間に`test`を入れて結合 → 'Hello World'
```

## 文字列の置換
```python:
test_str = 'Hello World'
test_str.replace('o', 'p') #'o'を'p'に変換 → 'Hellp Wprld'
test_str.replace('o', 'p', 1) #1回だけ'o'を'p'に変換 → 'Hellp World'
```

# 辞書
## キーの削除
削除するだけなら２行目のみで良いが、キーが存在しない場合も考えると、２行にしておいた方が安全そう。

```python
if 'key' in dic:
  del dic['key']
```

ループ内でキーを削除しようとするとエラーが発生するので、以下のようにする

```python
for key in list(dic):
  if ...: # 好みの条件
    del dic[key]
```

# math
## インポート
```python
import math
from math import * ## math.をつける必要がなくなる
```

## 数式
```python
math.sin(radian)
math.cos(radian)
math.tan(radian)
math.exp(x)
math.log(x)
math.pow(x, y)
math.sqrt(x)
```
## 定数
```python
math.pi
math.e
```

# numpy
## インポート
```python
import numpy as np
```

## 行列生成
```python
# ゼロ行列生成
zeros_array = np.zeros((row, column))
# イチ行列生成
ones_array = np.ones((row, column))
# 数値行列生成
value_array = np.full((row, column), value)
```

## 内積
```python
np.dot(A, B)
```

# OpenCV
## インポート
```python
import cv2
```
## 画像を読み込み
```python
img = cv2.imread(path)
```
## 画像を描画
```python
cv2.imshow('img', img)
cv2.waitKey(0) # 引数は描画時間
cv2.destroyAllWindows()
```
## 画像を書き込み
```python
cv2.imread(path, img)
```

# 参考
- https://docs.python.org/3/reference/
[javascript]URLを取得する正規表現

今後も何かで使いそうなのでメモ。
http://example.com?keyword=hogehoge&limit=25
のようなクエリパラメータにも対応してます。

- 英字のみのURL

```
/https?:\/\/[-_.!~*\'()a-zA-Z0-9;\/?:\@&=+\$,%#]+/g
```

- 日本語を含むURL

```
/https?:\/\/[-_.!~*\'()a-zA-Z0-9;\/?:\@&=+\$,%#\u3000-\u30FE\u4E00-\u9FA0\uFF01-\uFFE3]+/g
```

でいける。ちなみにimgタグなどの画像のURLを取得したい場合は

```
/(src=)["|'](.*?)["|']+/g
```

でsrcの部分だけ先に取得して上記のURLの正規表現をとってこればいけるはず。
37歳未経験者が脱サラして本気でプログラマーを目指したらこうなるVol.1

#1.プログラミングを初めて１ヶ月が経ちました！

３７歳のおっさんが脱サラしてプログラミングをやってみた。
という感じで日々の成長日記を記録していこうと思います。

今日この１ヶ月を振り返ってみたいと思います。
会社を辞めたのが９月中旬で、バタバタと色々決める半月を過ごし、
プログラミングスクールに通い始めたのが、１０月。
授業に付いていくのがやっとで本当にプログラマーになれるのだろうか…

最初に書いたコード（笑）

```javascript:text.html

console.log("hello world!");
```

同期のみんなは凄くて何度、心が折れそうになった事か・・・

でもこれは順調に来ていた自分の人生で初めての試練、
必死でやろうと思ってます！


ここまでの実績👉
スクールに通い初めて１週間の作品
【チーズアカデミー】
[http://imappa.sakura.ne.jp/kadai_teisyutu/01/lab_8_24/index.html](http://imappa.sakura.ne.jp/kadai_teisyutu/01/lab_8_24/index.html)


しょぼい。。。
今覚えばこれを作るのでも必死でしたー
でも周りの同期達は物凄いものを作っていて、正直この先大丈夫か？って思いました。

その次は
【じゃんけんアプリ】
http://imappa.sakura.ne.jp/kadai_teisyutu/02/kadai/janken_tpl.html

これはJavaScriptを学んで３日くらいで作ったアプリですね。
まず授業で「if文」、「ランダム関数」などを簡単に学んで「はい作って」って言われて作りました。
そんな。。。
JavaScriptで何ができるか、自分で色々調べながら何とか作った作品です。
これも目も当てられない…


【メモアプリ】
http://imappa.sakura.ne.jp/kadai_teisyutu/03/kadai/fusen.html

ローカルストレージの使い方、配列や色々な構文を学んで作った作品。
モチベーションがなかなか上がらなかったなぁ。
ここからさらにみんなのレベルが上がっていく…


【チャットアプリ】
http://imappa.sakura.ne.jp/kadai_teisyutu/04/auth/main.html

Firebaseを使ってメモリしたりID管理やリアルタイム通信などを行う手法を学ぶ。
これにより正式に実装できるようなレベルまで教えたという流れ、、
もしかしてこれで終わり！？


【MAPアプリ】
http://imappa.sakura.ne.jp/kadai_teisyutu/06/sample_map/bingo.html

bingAPIを使って地図の位置情報の取得やそれを使ったサービスの開発を学ぶ。
これにより貴重な位置情報を取得できるように。
ここからさらにみんなのサービスが実用的にー

【JS選手権】
ここまで習った集大成として、何を作ってもいいよ。
という形でサービスの開発に取り掛かる。
これまで、４日間に一つという日程で作成してきたが、
この作品は１週間の期間が与えられる。
みんなこだわった作品が登場して、改めてみんなのレベルの高さを痛感しました。。

スロット吉宗をアプリで再現
<img width="380" alt="skitch.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510286/a7593745-0acd-7476-2832-a4ddaca6c386.png">


作品としての完成度はまだまだですが、
ただ、自分の作品も分からないながらでもよく頑張って作ったな〜って思います。
["if"]と["onclick"]書きまくりました（笑）
初めて作品作りの楽しさを感じられた気がします。
これは少し成長できた証拠でしょうか。

卒業まであと５ヶ月。
どれ程のスキルが身に付くか分かりませんが、
全力で取り組もうと思います！！
AR.jsでマーカー認識時にマーカーレスのオブジェクトを生成する

#1.AR見立て遊びアプリを作った
マーカーベースで乗り物のオブジェクトを表示して見立て遊びができるアプリを作りました。
いや〜素晴らしいですね。(病気)
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510923/c83825c0-e3be-6ea4-b8fd-21d0f1d954a9.png" width=500px height="">

制作当初は建物の配置もマーカーベースで考えていましたが、乗り物用のマーカーで隠れてしまい遊びづらかったので、建物用のマーカー認識時にマーカーレスのオブジェクトを生成する処理を考えてみました。


#2.使用するアセットの登録まで
まずはGooglePolyからparkingと検索しアセットをダウンロードしたら、objファイルとmtlファイルをプロジェクトフォルダ内のobjフォルダに保存します。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510923/9a2d588d-473f-f5d4-8d33-747c3ddfd2b7.png" width=500px>


今回はindex.htmlファイル内に書いていきます。
AR.jsの使用にはA-Frameが必須のため、body要素内で読み込んでおきます。

```javascript:index.html
<!-- A-Frame ライブラリの読み込み -->
<script src="https://aframe.io/releases/0.6.1/aframe.min.js"></script>
<!-- AR.js ライブラリの読み込み -->
<script src="https://jeromeetienne.github.io/AR.js/aframe/build/aframe-ar.js"></script>
```

a-scene要素のなかに
```embedded arjs="debugUIEnabled:false;```
属性を追加します。これによりA-FrameとAR.jsが紐付けられます。

加えて
```<a-asset-item id="parkingObj" src="obj/parking/parking.obj">
<a-asset-item id="parkingMtl" src="obj/parking/parking.mtl">```
で使用するobjファイルとmtlファイルのパスを指定します。

```javascript:index.html
<a-scene id="scene" embedded arjs="debugUIEnabled:false;">
  <a-asset-item id="parkingObj" src="obj/parking/parking.obj">
  </a-asset-item> 
  <a-asset-item id="parkingMtl" src="obj/parking/parking.mtl">
  </a-asset-item>
<a-scene>
```

これでライブラリの使用と3Dオブジェクトの使用が可能となりました。
次はマーカーレスでオブジェクトを配置するためのマーカーを登録しておきます。
a-marker要素には使用するマーカー（今回はプリセットのhiroマーカーを使用）と、マーカーを認識した際に処理を実行するため```registerevents```を記述します。

```javascript:index.html
<a-marker preset="hiro" id="island" registerevents></a-marker>
```

a-sceneの最後の部分にはcameraを追加します。

```index.html
<a-entity camera></a-entity>
```

これで準備完了です！あとはscript要素内にマーカー検出時の処理を書いていきます。

#3.マーカー検出時の処理
最後にマーカー検出時の処理を書いていきます。

```javascript:index.html
AFRAME.registerComponent('registerevents', {
  init: function () {
  var marker = this.el;
  // 以下、マーカーを検出時のイベント
  marker.addEventListener('markerFound', function () {
    var markerId = island.id;
    //a-obj-model要素を生成する
    let parkingIns = document.createElement("a-obj-model");
    parkingIns.id = "parkingIns";
    let scene = document.getElementById("scene");
    //a-obj-modelをa-sceneに追加する
    scene.appendChild(parkingIns);
    //objファイルとmtlファイルをa-obj-model要素に追加する
    parkingIns.setAttribute("src", "#parkingObj");
    parkingIns.setAttribute("mtl", "#parkingMtl");
    //position、scale、positionの設定
    parkingIns.setAttribute("position", "0 0 -0.07");
    parkingIns.setAttribute("scale", "0.01 0.01 0.01");
    parkingIns.setAttribute("rotation", "0 270 -20");
    });
  }
});
```

アセットの元の設定がおかしかったのでposition,scale,rotationがおかしなことになっていますが...

完成！
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510923/c7e64a89-c9c0-ddec-0379-c019e067310f.png" width="500px">

やった−！！
これでマーカーを動かしても同じ位置にオブジェクトを配置した状態になります。
IT初心者がピンとこないJSON

入社後の研修でやらなかった範囲が苦手すぎて毎度躓きます。

当たり前のように現場ではJSONが使われていて
当たり前のように人名のイメージしかわかなかった人レベルのメモまとめです。

# JSONとは
"JavaScript Object Notation"
**「JavaScriptの中でオブジェクトを記述する書式」**
データフォーマット（データを扱う際の決まりごと、CSVやXML）の一種。
特に表で表しにくい構造のデータに適している。
拡張子は`.json`

## 書式
基本的に`key（名前）:value（値）`の形で記述。
このかたまりを**メンバー**という。
メンバーを`[]`（配列）や`{}`（オブジェクト内）で括る。
そうすれば、名前を指定することでデータを呼び出せるようになる。

```json:sample.json
[
  "user01:{
    "id":0001,
    "name":"ヤマダ タロウ",
    "age":24
  },
  user02:{
    "id":0002,
    "name":"スズキ ハナコ",
    "age":32
  }
]
```
例えば、「user01の年齢(age)」を指定すると"24"が返ってくるといった感じ。
上記のJSONをXMLで書き換えると以下のようになる。

```xml:sample2.xml
<users>
  <user01>
    <id>0001</id>
    <name>ヤマダ タロウ</name>
    <age>24<age>
  </user01>
  <user02>
    <id>0002</id>
    <name>スズキ ハナコ</name>
    <age>32<age>
  </user02>
</users>
```
行数は同じでも記述量が違うため、JSONの方がすっきりして見えるし、
XMLをJSONにすることで通信時のデータ量削減もできる。

※ XMLについては[こちら](https://qiita.com/nanatsu/items/7242934048135f3bf879)でざっくりまとめています。

## key（名前）
コロン`:`の左側に書くひと
XMLのタグと同様、任意の情報名を指定できる。
`"name"`のように囲う。
プログラミング言語の変数名的な使い方をするイメージ。

## value（値）
コロン`:`の右側に書くひと
keyよりもルールが細かいため注意。

### ■ 文字列　- string
`"apple"`など、任意の情報を`""`で囲んだ記述

### ■ 数値　- number
`1`や`5.55`など、数値をそのまま書いた記述

### ■ 真偽値　- boolean
`true`もしくは`false`を表現する記述

### ■ ヌル値　- null
`null`（値が空っぽ）を表現する記述

### ■ オブジェクト値　- object
`{}`でオブジェクトを指定する記述
階層構造を持つことができる

```
{
  "user":{
    "id":1,
    "name":"George"
  }
}
```

### ■ 配列値　- array
`[]`で配列を指定する記述
配列要素の種類は一致していなくてもよい
配列内にオブジェクト（後述）や配列が入っているパターンもある
配列内の要素はインデックスで取り出す

```
{
  "color_list":["red", "blue", "green", "yellow"],
  "number_list":[1, 28, 396],
  "object_list":[
    {"id":1, "name":"George"},
    {"id":2, "name":"Nancy"}
  ]
}
```
（個人的には、情報を持っているのがオブジェクト`{}`、値を持っているのが配列`[]`というイメージで判断しています）

# おわりに
今回は「初めてJSONにぶち当たったときの読み方」といったところでまとめました。
使い方についてはまだまとめきれていないので、追々やっていければと思います。

# 参考
1. [JSONの形式を完全理解して読み書きできるようになるための記事](https://www.sejuku.net/blog/80617)
2. [JSONとはなにかpackage jsonやjson shcemaなども含めて解説！](https://www.sejuku.net/blog/79873)
3. [JSONってなにもの？](https://thinkit.co.jp/article/70/1)
4. [非エンジニアに贈る「具体例でさらっと学ぶJSON」](https://dev.classmethod.jp/etc/concrete-example-of-json/)
5. [JSON入門](http://www.tohoho-web.com/ex/json.html)
Rails で module とか method とかの定義場所を知りたい時の魔法


# 迷子

> 「この module/method の定義場所を教えてください」

##　解決方法

`source_location`
というメソッドで場所を特定します。

以下、使い方

### method の定義場所が知りたい

この場合は、 `new` というメソッドの場所

```
pry(main)> 'hoge'.method(:new).source_location
```


### module の定義場所が知りたい

この場合は、 `Hoge::Fuga` というモジュールの場所

```
pry(main)> Hoge::Fuga.new.method(:dump).source_location
```

## 終わりに

これがあれば、自分が定義した（つもりになってる）
method/module がちゃんと定義できてるかってところまで、確認ができますね！！！

したつもり、ってのが一番危険

## 参考
[Rubyでメソッドの定義場所を見つける方法](https://qiita.com/jnchito/items/fc8a61b421d026a23ffe)
[Rails moduleの定義場所を探す方法について](https://teratail.com/questions/81925)
bashでパスワード自動生成

パスワードを一括生成してコピペしたいことがあったのでメモ
## サンプル
### 数字8桁で先頭が0でない文字列を10個生成
#### コマンド
```
$ cat /dev/urandom | tr -dc '0123456789' | fold -w 8 | grep -v '^0' | head -n 10
```
#### 実行結果
```
74101604
15854326
24370649
78490829
36276057
70422352
94393920
82691490
34135561
48386263
```

### 数字/英小文字/英大文字/記号12桁で必ず記号を含む文字列を10個生成
#### コマンド
```
$ cat /dev/urandom | tr -dc '0123456789abcdefghijkmnpqrstuvwxyzABCDEFGHIJKLMNPQRSTUVWXYZ,.+\-!' | fold -w 12 | grep -E '[,\.+\-\!]' | head -n 10
```
#### 実行結果
```
zD,JXJdHQ,gC
15zwLb7HVh,W
3CG,64,,yQbR
XX7E.ejM9.R,
ebysijGSpfZ,
,XHtcyi4G.UN
Y38MX3c.bhnp
w4,dRUjrpby!
JJUrH3eW5H,r
.WWDp84.w5Ds
```

## shellscript化
```
$ cat generate_password.sh
#!/bin/bash

# 引数チェック
if [ $# -ne 1 ]; then
  echo "Usage:sh generate_password.sh password_num"
  echo "Example:sh generate_password.sh 10"
  exit 1
fi

# 生成したい数
generate_num=$1

# 数字8桁で先頭が0でない文字列を引数の数だけ生成
cat /dev/urandom | tr -dc '0123456789' | fold -w 8 | grep -v '^0' | head -n ${generate_num}
```
```
$ sh generate_password.sh 10
74948144
55446718
50202090
54395135
40939495
78852681
71060205
39155894
19875823
24833084
```