OmniAICreator/Qiita-1.07M huggingface dataset:
シェルスクリプトのまとめ


# bashの基礎
1. シェルとはなにか  
ユーザーのコマンドラインをOSの命令に変換するためのもの     
2. bashの使用法   
 - ユーザーインターフェイスとしての使用   
 - プログラミング環境としての使用   
3. bash   
*GNUプロジェクトで使用するために作成されたもの*   
 - - -
#### システムにbashが含まれているか確認する方法
```
$ echo $SHELL
```
/bin/bashが返ってくる.
bashを起動させるには
```
$ bash
bash-3.1$   
```
をすればよい.
 - - -   
#### bashがどのディレクトリにインストールされているか調べる方法
```
$ grep bash /etc/passwd | awk -F: '{print $7}' | sort -u
```
を入力すると/bin/bashが返ってくる.
 - - -
#### bashをログインシェルとして設定する方法
```
$ chsh bash-name(grepコマンドで表示された名前を指定)
```

4. 対話形式でのシェルの使用
対話形式で使用するにはログインセッションを張ればよい.   
#### ログインセッション
ログインしたときにはられる.   
exit or logout or Ctrl+Dで切断   
ログインセッションが張られている間はコマンドラインを入力することになる.
5. ファイル
 - 通常ファイル   
 - 実行可能ファイル(プログラムとも呼ばれ、コマンドとして呼び出される)  
 - ワイルドカード

| ワイルドカード | 一致対象 |   
|----------- | -------- |  
| ?          | 任意の１文字 |    
| *          | 任意の文字列 |   
| [set]      | setに含まれる文字 |   
| [!set]     | setに含まれない文字 |   

6. 標準入出力   

|ユーティリティ|目的|
|------------|--------|  
|cat|入力を出力にコピー|   
|grep|文字列を検索|   
|sort|行を並べ替える|   
|cut|列を取り出す|   
|sed|編集操作を実行する|   
|tr|文字を他の文字に置換|   

7. バックグラウンドジョブ   
シェルでは１つのログインセッションで同時に複数のコマンドを走らせることができる   
バックグラウンドで複数のコマンドを走らせるとき、優先度を考える必要がある   
`nice コマンド名`を使うと優先度を下げることができる   

8. コントロールキー   

|コントロールキー|stty名|機能|   
|--------------|----------|----------|   
|Ctrl+C|intr|コマンドを中止する|   
|Ctrl+D|eof|入力を終了|   
|Ctrl+\|quit|コマンドを中止する|   
|Ctrl+S|stop|画面への出力を停止|   
|Ctrl+Q||画面への出力を開始|   
|Ctrl+？|erase|最後の文字を削除|   
|Ctrl+U|kill|コマンドライン全体を削除|   
|Ctrl+Z|susp|コマンドを一時停止|   

# コマンドライン編集   
 - emacsモード   
 - viモード   

#### 編集モードを切り替える方法
```
$ set -o emacs
または
$ set -o vi
```

# 環境のカスタマイズ   
### .bash_profile / .bash_logout / .bashrc   
**.bash_prolile**   
bashはシステムにログインするたびにこのファイルを読み込み、定義されているコマンドを自校する   
### エイリアス　　　
.bash_profileに``alias ''='' ``と指定することができる   
長いPASSを短く指定することもできる   

### historyコマンドを利用したときに日時を追加する
```
bash-3.2$ HISTTIMEFORMAT="%y/%m/%d %T "   
bash-3.2$ history   
  ...
  501  18/10/24 23:06:20 HISTTIMEFORMAT="%y/%m/%d %T "
  502  18/10/24 23:06:23 history
```   
# シェルスクリプト   
### シェルスクリプトの実行   
```
$ source script-name
```
### 関数を定義する形式   
```
function <関数>{
  <シェルコマンド>
}
```
または
```
<関数>(){
  <シェルコマンド>
}
```
### 関数定義の削除   
```
$ unset -f <関数>
```
### コマンドの優先順位
1. エイリアス   
2. function   
3. 関数   
4. 組み込みシェル   
5. スクリプト、実行可能ファイル   

- - -
[参考]入門bash3
vimのコマンド

#### viモード(制御モード)の基本コマンド
|コマンド|意味|
|--------|--------|   
|h|左に１文字移動|   
|l|右に１文字移動|   
|w|右に１ワード移動|   
|b|左に１ワード移動|   
|W|次のノンブランクワードの先頭へ移動|   
|B|前のノンブランクワードの先頭へ移動|   
|e|現在のワードの末尾へ移動|   
|E|現在のノンブランクワードの末尾へ移動|   
|O|コマンドラインの先頭へ移動|   
|^|コマンドラインの最初のノンブランク文字へ移動|   
|$|コマンドラインの末尾へ移動|   

#### vimモードの入力モードへ移行するコマンド   
|コマンド|意味|   
|--------|--------|   
|i|現在の文字の前にテキストを挿入|   
|a|現在の文字の後ろにテキストを挿入|   
|I|コマンドラインの先頭にテキストを挿入|   
|A|コマンドラインの末尾へテキストを挿入|   
|R|既存のテキストを上書きする|   

#### viモードの削除コマンド   

|コマンド|意味|
|--------|--------|   
|dh|後方に１文字削除|   
|dl|前方に１文字削除|   
|db|後方に１ワード削除|   
|dw|前方に１ワード削除|   
|dB|後方に1ノンブランクワード削除|   
|dW|前方に１ノンブランクワード削除|   
|d$|コマンドラインの末尾まで削除|   
|dO|コマンドラインの先頭まで削除|
emacsモードのコマンド

#### emacsモードの基本コマンド

|コマンド|意味|
|--------|--------|   
|Ctrl+B|後方に１文字移動|   
|Ctrl+F|前方へ１文字移動|   
|BACKSPACE|後方に１文字削除|   
|Ctrl+D|前方に１文字削除|   

#### emacsモードのワードコマンド

|コマンド|意味|
|--------|--------|   
|ESC+B|後方に１ワード移動|   
|ESC+F|前方へ１ワード移動|   
|ESC+DEL|後方に１ワード削除|   
|ESC+D|前方に１ワード削除|   

#### emacsモードのラインコマンド   

|コマンド|意味|   
|--------|--------|   
|Ctrl+A|コマンドラインの先頭へ移動|   
|Ctrl+E|コマンドラインの末尾へ移動|   
|Ctrl+K|コマンドラインの末尾まで削除|   

#### emacsモードの履歴ファイル内移動コマンド   

|コマンド|意味|
|--------|--------|   
|Ctrl+P|前の行へ移動|   
|Ctrl+N|次の行へ移動|   
|Ctrl+R|後方検索を実行|   
|ESC+<|履歴ファイルの先頭へ移動|   
|ESC+>|履歴ファイルの最終行へ移動|   

#### emacsモードの補完コマンド   

|コマンド|意味|
|--------|--------|   
|TAB|標準的な補完を試す|   
|ESC+?|補完候補の一覧を表示|   
|ESC+/|ファイル名としての補完|   
|Ctrl+X/|ファイル名補完候補の一覧を表示|   
|ESC+$|変数としての補完を試みる|   
|ESC+X$|変数としての補完候補一覧を表示|   
|ESC+!|コマンドとしての補完を試みる|   
|ESC+X!|コマンドとしての補完候補一覧を表示|    

- - -
[参考] 入門bash オライリー・ジャパン
ARKitで光を当てるときはひとつよりも複数が良い

今日新しい発見をしたので忘れない様にメモしておく。

### 困ってたこと
ARKitで配置した3Dオブジェクトにomniタイプ(電球の光)のSCNLightを設定して、光を当てたときに影が強すぎると感じていた。
具体的にはこんな感じ。

![IMG_0304.png](https://qiita-image-store.s3.amazonaws.com/0/200963/cb8ef018-20f3-6180-7ccc-05b2eb259732.png)

しかし、影が強すぎるからといって光を当てないと、のっぺりした様に見えリアルさが欠けてしまう。
具体的にはこんな感じ。

![IMG_0303.png](https://qiita-image-store.s3.amazonaws.com/0/200963/c8de674c-30b2-f03c-4ca2-50a17b844901.png)

### そんなときはライトを組み合わせよう！
ARKit(SceneKit)では複数SCNLightを配置できるらしく、ambientタイプ(全ての面を一定に照らす光)とomniタイプのSCNLightを配置するといい感じになった。
具体的にはこんな感じ。

![IMG_0302.png](https://qiita-image-store.s3.amazonaws.com/0/200963/3925ee53-f010-e41b-79b3-6a17c15f8c16.png)

omniタイプのSCNLightは位置によって影のつき方が変わるためpositionをちゃんと設定しないといけないが、ambientタイプのSCNLightはどこに配置しても光の当たり方は変わらないので自分はrootNodeのプロパティに設定してしまっている。

``` Swift
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // Set the view's delegate
        sceneView.delegate = self
        
        // Show statistics such as fps and timing information
        sceneView.showsStatistics = true
        
        // Create a new scene
        let scene = SCNScene()
        
        // Set the scene to the view
        sceneView.scene = scene
        
        // Setup Omni Light
        let omniLight = SCNLight()
        omniLight.type = .omni
        omniLight.intensity = 0
        omniLight.temperature = 0
        omniLight.castsShadow = true

        let omniLightNode = SCNNode()
        omniLightNode.light = omniLight
        omniLightNode.position = SCNVector3(0,10,1)
        sceneView.scene.rootNode.addChildNode(omniLightNode)
        
        // Setup Ambient Light
        let ambientLight = SCNLight()
        ambientLight.type = .ambient
        ambientLight.intensity = 0
        ambientLight.temperature = 0
        sceneView.scene.rootNode.light = ambientLight
    }
```

SceneKitを使ってARアプリ開発をしたい方向けに情報をまとめていますので、[こちら](https://www.nsunrise.work/p/index.html)もご参照ください。
Udemyで爆発的に技術力を向上させる

※大げさなタイトルですみません

私はサーバーサイドの開発を中心に経験してきました。
しかし、今の現場でフロントサイドの開発を求められました。
HtmlやJavascriptはちょこちょこ改修はしたことがあるものの、かなり苦手意識がありました。
これは勉強しないとマズイと思ったので、 `Udemy` というサービスを利用して勉強をしたところ、とても良かったので紹介したいと思います。

## この記事を読んでほしい方
- 新人や若手エンジニア
- 未経験やあまり経験のない言語を使うことになった方
- 参考書での学習が長続きしない方


## Udemyとは
https://www.udemy.com

Udemyは世界最大級のオンライン学習プラットフォームです。
動画を購入してPCやスマホから講義を受講することができます。
動画は基本的には有料ですが無料のものもあるようです。
英語の教材が多めのようですが日本語教材も一定数あります。


## Udemyの良いところ
「Udemyの良いところ」というよりは、オンライン学習サービスの良いところかもしれませんが。。。
### 場所を選ばず受講できる
Udemyはスマホでも受講することができます。それによって通勤時に電車内で立ちながらでも学習することができます。
参考書だとスペースを取るので少し混んでいると出すのが億劫。という言い訳のもと勉強が進まなかったりしませんか？スマホなら参考書よりかは気軽に取り出せます。
（電子書籍だとあまり関係ないかもですが）

### 高速再生やスロー再生ができる
Udemyは0.5倍速から2倍速の再生が可能です。
私は下記のように使い分けています。
- 既知の部分や結果が予想できる部分は1.5〜1.75倍速
- 難しい部分は1倍速で繰り返し聞く
社会人はまとまった時間を確保するのが難しいと思うので、高速再生は重宝しています。

### 参考書と同じくらいの金額で購入できる
Udemyは割引セールを定期的に開催していて、安いものだと1,800円のものもあります。
参考書を購入すると2,000円は超えてくるかなと思います。
そう考えると1度試してみてもいいかなと思い、私は購入してみました。


## 私が行った学習方法
1. 朝、通勤時にUdemyを受講。
2. 業務中に学んだことを積極的に使ってみる。
3. 有識者にレビューしてもらい、実務での使用方法を知る。

実務で使用している言語を学び、すぐに使用する。という
`インプット→アウトプット` を繰り返すことで身に付いている実感があります。
幸運なことにコードレビューを丁寧に行っていただける現場のため、フィードバックを受けられ学習効率が更に加速しています。


## Udemyオススメコース ※随時更新
- [速習＋詳細＋実例 jQuery講座](https://www.udemy.com/jquery-kouza/)
- [手を動かしながら2週間で学ぶ AWS 基本から応用まで](https://www.udemy.com/aws-14days/)

増えてきたら別記事にしたいですね。
【Graphviz 】dotファイルを画像ファイルに変換する。(for Windows)

#概要#
多くは語らないつもりですのでご辛抱を。。。
GraphvizをはじめてWindowsに導入して、「dotファイルをどうすればいいのか分からない！」となった経験から、dotファイルを他の画像ファイルに変換する方法を書いておきます。バッチファイルを使いますので、作ったバッチファイルをデスクトップに置いておくことで、ドラックアンドドロップしただけでdotファイルをpngファイルなどに変換できるようになります！
##Graphvizとは##
下のようなテキストを、

```
graph { 
  X -- Y
  X -- Y
  Y -- Z [color=green]
} 
```
画像に変換してくれます。↓ こんな感じ。
![test.png](https://qiita-image-store.s3.amazonaws.com/0/305299/29d19f4a-1831-5580-bbf1-4ed0b6cc0d60.png)

つまり、テキストで記入することで、キレイなグラフ画像が作れるようになるツールです。
###導入から記入法までを押さえておきたい方向け###
Windowsの方はこちら [[Windows で Graphviz のインストール](https://www.kunihikokaneko.com/dblab/toolchain/graphviz.html)] を参考になさってください。
また、こちら [[Graphvizとdot言語でグラフを描く方法のまとめ](https://qiita.com/rubytomato@github/items/51779135bc4b77c8c20d)] で丁寧に記法について解説してくださっています。感謝！
#バッチファイル作成#
早速ですがバッチファイルを作っていきましょう！
##"dot.exe"のパスを取得##
インストール時にインストール先の変更をしていなければ、以下の場所にある (はず)。
```-64bitOSの場合-
C:\Program Files (x86)\Graphviz2.38\bin\dot.exe
-32bitOSの場合-
C:\Program Files\Graphviz2.38\bin\dot.exe
```
これが見つからないと始まらないので、頑張って探してください。見つけたら、dot.exeのパスをコピーしておいてください。
##バッチファイルを作るぞー！##
まずメモ帳(テキストエディタならなんでもいいですが)を開いて、先ほどコピーしてきたパスを貼り付け。
このとき、貼り付けたパスが、～～dot.exe で終わっていることを**必ず**確認してください。

バッチファイルの中身はこんな感じでどうでしょう? (デキる方はどんどんカスタマイズしていってください！) 
**先ほど貼り付けたパスは、6行目の "C:\Program Files (x86)\Graphviz2.38\bin\dot.exe" の部分ですので、お使いのパソコンの環境に合わせて書き換えてください。**[以下の内容は64bitOSの方向けです。]

```
@echo off
pushd "%~dp1"
echo dotファイル専用
echo;
set /p type="変換先拡張子の入力  ＞＞＞  "
"C:\Program Files (x86)\Graphviz2.38\bin\dot.exe" -Kdot -T%type% %1 -o%~n1.%type%
```
ダブルクォーテーションなどを忘れるとうまくいきません。
とりあえず、よく分からなかったらコピペしてもらってもいいです。
書き終わったら、名前をつけて保存(文字コードはShift_JIS(Windowsのメモ帳ではANSIと呼ばれています)推奨)して、拡張子をtxtからbatに変えてください。アイコンが下の画像と同じものに変わったら成功です。
![bat.png](https://qiita-image-store.s3.amazonaws.com/0/305299/3430db53-9185-2716-42cd-bf8babb59342.png)
##使い方##
今作ったバッチファイルをデスクトップにでも置いておいて、作ったdotファイルをその上にドラッグアンドドロップすると、```変換先拡張子の入力  ＞＞＞  ```と出るはずなので、変換したい拡張子(pngなりpdfなり)を入力して、Enter。
これで少し待てば、dotファイルと同じ場所に、新しいファイルができあがっていると思います。
#####拡張子について#####
いちおう、よく使いそうな拡張子(jpg,jpeg,png,gif,bmp,tif,png)を一通り試してみましたが、おすすめはpngかpdfです。(pdfが一番キレイです。)

続き＞＞[Wordに関連付けられているdotファイルを、テキストエディタで編集したい！](https://qiita.com/NumLocker/items/e4bb664a65ab62a54a0b)
micro:bitがobniz経由でInternetにつながった

#概要
micro:bitは色々なセンサー（２個のボタン、加速度センサー、磁力センサー、明るさセンサー）を持っているがInternetに繋がっていないためIoTと呼ぶのはいまいちな感じがしたので、obnizを使用してInternetにつなげてみました。

子供学習の際にも、簡単にmicro:bitをInternetにつなげることが出来るので活用の幅が広がると思います。

一方obnizも2000円程の費用で色々なセンサーを使うことが出来るので、これも活用の幅が広がりそうです。

趣味でスピーカーハック（タイマー、検査機等のスピーカーに繋げて「音が鳴る」＝トリガーとして利用する）をするのですが、
機材→micro:bit→obniz
とmicro:bitを挟んだ方が過電圧等での破壊の被害コストが少ない（壊れるのは2000円のmicro:bitだけ。obnizは6000円なので壊したくない）ので、リスク低減にも役立ちます。

#デモ
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">ついにmicro:bitがobniz経由（シリアル通信）でInternetにつながりました。子供の工作の幅が広がりそう！<br><br>動画は<br>A+B：光センサーの値<br>A:OK<br>B：NG<br>を送っています。<br><br>詳細はこちら<a href="https://t.co/IShVAkE4nM">https://t.co/IShVAkE4nM</a><a href="https://twitter.com/hashtag/obniz?src=hash&amp;ref_src=twsrc%5Etfw">#obniz</a> <a href="https://twitter.com/hashtag/microbit?src=hash&amp;ref_src=twsrc%5Etfw">#microbit</a> <a href="https://t.co/AWPb2mBgWA">pic.twitter.com/AWPb2mBgWA</a></p>&mdash; keicafeblack (@keicafeblack) <a href="https://twitter.com/keicafeblack/status/1055110958874411009?ref_src=twsrc%5Etfw">2018年10月24日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>


#配線
| micro:bit        |obniz
|:-----------------|------------------:|
| P0             |P1 rx| 
| P1             |P0 tx| 
| GND             |P3 gnd| 

#プログラム
##obniz
```helloMicrobit.html
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <script src="https://obniz.io/js/jquery-3.2.1.min.js"></script>
  <script src="https://unpkg.com/obniz@1.13.0/obniz.js" crossorigin="anonymous"></script>
</head>
<body>

<div id="obniz-debug"></div>
<h1>micro:bit IF</h1>
<div id="print"></div>



<script>
var obniz = new Obniz("OBNIZ_ID_HERE");
obniz.onconnect = async function(){
  var uart = obniz.getFreeUart();
  uart.start({tx: 0, rx: 1, gnd:2 });

  uart.send("Hello")

  while(1){
    if(uart.isDataExists()){
        console.log(uart.readText());
    }
    await obniz.wait(10);
  }
}
</script>
</body>
</html>
```
参考にしたサイト：[UART: 受信する←obniz本家のサンプル](https://obniz.io/doc/lessons_obnizjs_uart_receive)

##micro:bit（JavaScript表示版）
```obniz2microbit.js
input.onButtonPressed(Button.B, () => {
    serial.writeString("NG")
    basic.showString("NG")
})
input.onButtonPressed(Button.A, () => {
    serial.writeString("OK")
    basic.showString("OK")
})
input.onButtonPressed(Button.AB, () => {
    serial.writeNumber(input.lightLevel())
    basic.showNumber(input.lightLevel())
})
serial.redirect(
SerialPin.P0,
SerialPin.P1,
BaudRate.BaudRate115200
)
basic.forever(() => {
	
})

```
参考にしたサイト：[マイクロビットの端子を使おう(シリアル通信)](https://news.mynavi.jp/article/makeprogram-14/)

#その他参考サイト
[・micro:bitの端子の説明](https://microbit-micropython.readthedocs.io/ja/latest/pin.html)

[・クリエイター手抜きプロジェクト［555］IoT　obniz編　シリアル通信でデータを送信する](http://bn.dgcr.com/archives/20180903110100.html)
>obniz.uart0.start({tx:1, rx:0, gnd:2});

でGNDにもつなげないといけない事に気付く
なろうリーダー(仮) 1日目: 要件定義

# 前書き
スマホでネット小説(主に小説家になろう)を読むのが好きなのですが、**なろう小説API**なるものが公式で存在していることを知りました。

https://dev.syosetu.com/man/api/

興が乗ったので、小説をスマホにダウンロードする(接続が途切れた場合でも小説が読める)ツールを自身の勉強を兼ねて作りたいと思います(むかーし作ったアプリの改修だったり。)
~~似たようなアプリが星の数ほどある点は気にしない方針とします。~~

今後、当該Androidアプリが完成するまでのTIPSなどを記載していきたいと思います。
なお、本日の記事にはコーディング要素はありません。
(筆者のAndroid知識はICSから停滞している為、)

#アプリ開発時に~~無駄に~~利用してみたいライブラリ／機能など
先行調査時に気になった機能／記事をスクリーニングしてみました。
ここら辺の技術を利用したいと思います。

- [BottomAppBarにめり込んだFloatingActionButtonを設置する](https://qiita.com/furusin_oriver/items/d7b3c6504b892c353d63)
(@furusin_oriver氏)
- [Android のリストをスワイプして削除する](https://qiita.com/shts/items/042f57c3451b9375db1d) (@shts氏)
- [ButterKnifeを使ってみたまとめ](https://qiita.com/takenoki/items/42d3c8c0bb3809fff1a0) (@takenoki氏)
- [RecyclerViewでスクロールが一番下まで行ったらロードする実装](https://qiita.com/konifar/items/e57c47bfb93d0d40ef59) (@konifar氏)
- [いい感じのチュートリアル画面を5分で実装する](https://qiita.com/masaibar/items/f155cd1c7b6a795377f6) (@masaibar氏)
- [SnakeYAML で YAML を扱う](https://qiita.com/toastkidjp/items/66ddd8daa3c625afc351) (@toastkidjp氏)
- OkHttp3

# 1日目: 要件定義
ということで、まずはアプリでやりたいことを要件定義の形でまとめてみます。
- 以下の~~欲望~~要件を満たすこと。

## 機能要件
### 小説検索機能
- 本家の[検索](https://yomou.syosetu.com/search.php)と類似の検索ができること。
    - フリーワード検索/除外検索
    - キーワード検索
    - ジャンル選択
    - 読了時間／文字数
    - 総合評価ポイント
- 本家の[ランキング](https://yomou.syosetu.com/rank/genretop/)と類似の検索ができること。
    - 日間/週間/月間/四半期/年間ごとのランキングが表示できること
    - ジャンル別にランキングが表示できること
- 本家の[特殊検索](https://yomou.syosetu.com/search.php)と類似の検索ができること。
    - 未評価作品一覧
    - 未感想作品一覧
    - 平均点順作者一覧
- 表示結果から単一および複数の小説を選択してダウンロード機能に引渡しできること。
    - Gmailみたいに選択できること。
- 各小説の更新頻度が確認できること(更新頻度が低くて完結が遠い小説は個人的に読む気が起きない…)

### 小説ダウンロード機能
- 指定された小説をストレージに保存できること。
- ダウンロード中は`Notification`に進捗を表示すること。
- ダウンロード結果は`Toast`で表示すること。
- ストレージの保存先は内部ストレージとSDカードを選択できること[TBD]
- ダウンロード時の保存形式はHTML+CSSとすること[TBD]
- SDカード保存時はダウンロードファイルをブラウザで表示できること。

### 小説ビューアー機能
- 保存済みの小説内容を1話単位で画面に表示できること(`WebView`を想定)。
- 文字だけでなく挿絵画像も表示できること。
- 文字色、背景色、文字の大きさを変更できること(CSSを想定)
- 音量ボタンでスクロールできること**(これ最も重要)**
- 広告は表示しないこと。
- スワイプで前話・次話に移動できること。
- １画面で複数話の表示に対応すること[TBD]
    - 一番下まで表示したら次の話を読みこむ…実装をするかどうかは未定。

### 小説更新機能
- 保存済みの小説の更新有無を確認し、更新があった場合はダウンロードできること。
- 手動更新および自動更新の両方に対応すること。
- 更新中は`Notification`に進捗を表示すること。
- 手動更新時は`Toast`で更新結果を表示すること。
- 自動更新時は`Notification`に更新結果を通知できること。
    - 更新結果の`Notification`が重複した場合の動作はTBD
        - 「案1: 複数の`Notification`を表示」
        - 「案2: 後発優先で先発`Notification`は削除」
        - 「案3: 先発と後発の結果をマージして`Notification`を表示」

### 小説管理機能
- 保存済みの小説の一覧を表示できること。
- 小説を選択して削除、および更新ができること。
- ダウンロード済みの全小説の手動更新ができること。
- ソートに対応すること。
    - 最終更新日時
    - 作者名
    - ダウンロード順
    - タイトル名
- フィルタリングに対応すること。
    - ジャンル
    - フリーワード

### 小説目次表示機能
- 保存済みの小説の目次を表示できること。
- 作者として同一作者の別の作品を検索できること。
- 章節表示に対応すること。
- 1話ごとに最終更新日時が表示できること
- 「未読」「既読」「既読だけど改稿された」が区別できること。

### 設定機能
- 上記の各機能における設定項目を管理する機能(`PreferenceFragment`を想定)
- 回線状況によって小説を更新するかどうか
    - Wi-Fi
    - モバイル回線(ホーム網)
    - モバイル回線(ローミング利用時)
- 小説更新を確認する頻度
- ビューア用項目
    - フォントサイズ
    - フォントカラー (作者推奨値優先とか)
    - 背景色 (作者推奨値優先とか)
- 対象サイト選択
    - ノクターン／ミッドナイト

### チュートリアル機能
- 使い方を表示＋プロビジョニング初期設定

## 今後の進め方
今後は画面構成／クラス設計を検討していきたいと思います。
FortranでHello Worldまで(gfortran)

以前投げ出したgfortran導入が上手くいったので、忘れない用に備忘録がてらに

#環境
windows 10 Home 64bit

#インストーラーの入手
ちなみに私はこの方法ではうまくいかなかったです
最初にarchitectureで1敗、exceptionで1敗
おそらくこの方法でも行けるはず(なーにがいけなかったんでしょうかねぇ?)
[こちら](https://sourceforge.net/projects/mingw-w64/files/)のリンクから最新版をダウンロードして実行

1.ウェルカム的なアレが出てくるのでさっさとNext
2.設定が出てくるので
    version        :そのまま
    archtecture    :x86_64(i686は32bit?)
    threads        :posix(win32は読んで字のごとく~~だと思う~~)
    exception    :sjlj(dwarfは32bitっぽい?)
    build version    :0(というかそれ以外に選択肢がなかった)
![inst2.PNG](https://qiita-image-store.s3.amazonaws.com/0/251535/f69926d0-7289-b274-6ef1-a6bf9c1c36f5.png)
3.インストール場所を聞かれるのでお好きな場所に、特にこだわりがなければそのままでNext

まぁ上手くいかなかったんですけどね…
#うまくいかないときに
1．[さっきのリンク](https://sourceforge.net/projects/mingw-w64/files/)のページのFilesタブの下部にあるx86_64-posix-sjljをダウンロード
2．任意のフォルダを用意して7zipで解凍
3．完了！

あれ・・・インストーラーいらなかったんじゃ・・・？:sweat_drops:
まぁ結果オーライ
#Pathを通す
先ほどインストールしたフォルダのパス`*\mingw64\bin`をpathに追加
追加したらちゃんと**okを押して設定を閉じる(1敗)**

確認するためにコマンドプロンプトを閉じてもう一度起動
`gfortran -v`を入力

```
C:\>gfortran -v
(中略)
Thread model: posix
gcc version 8.1.0 (x86_64-posix-sjlj-rev0, Built by MinGW-W64 project)
```
パスが通りました。
お疲れさまでした、ではありませんね

#FortranでHello World
1．まず適当なプログラムを書きます

```fortran:hello.f90
program hello
 print *,'Hello World!'
end program hello
```
2．hello.f90のあるディレクトリをcdにしてから、`C:\~\ > fortarn hello.f90`するとa.exeができるので実行`C:\~\ > a.exe`を実行

```
Hello World!
```

以上で設定は終了です、お疲れさまでした。:joy:
N+1問題の実験

##include?メソッドを使ったN+１問題の実験をしてみましょう
今回はUserモデルがEventを投稿する
その投稿された一覧を取得する時間がinclude?メソッドの有無でどれほど違うか計測する
が今回の目標です。
#必要なもの

１）seedを使ってイベントを1000件投稿させましょう

```ruby:db/seed
1000.times do |index|
	Event.create(:eventname =>'実験サンプル', :when => '10/14 9:00',:where => 'ゴンザのパソコン',:user_id => '1',:text => 'N+1問題解決しよう！')
end
```

2)Gemfile rack-mini-profilerを使って処理速度を計測できるようにする

```ruby:Gemfile
gem 'rack-mini-profiler', require: false
```
config/initializers/rack_mini_profiler.rbファイルを作成

```ruby:config/initializers/rack_mini_profiler.rb
if Rails.env.development?
  require 'rack-mini-profiler'

  # initialization is skipped so trigger it
  Rack::MiniProfilerRails.initialize!(Rails.application)
end
```
これで準備は完了です
#include?メソッドなしの場合
```ruby:app/controller/event_controller.rb
class EventsController < ApplicationController
  #何もしない場合
  def index
   #投稿された全イベントを最新順に取得
   @events = Event.all.order("id DESC")
  end
```


<img width="581" alt="スクリーンショット 2018-10-24 23.36.47.png" src="https://qiita-image-store.s3.amazonaws.com/0/239663/87d51442-18ae-52a9-7ca5-b5b3d9230f18.png">
###Rendering: events/index	3744.9のとこを見ればわかりますが、3744.9ととてつもないですね

@events = Event.all.order("id DESC").includes(:user)
#include?メソッドありだと？
```ruby:app/controller/event_controller.rb
class EventsController < ApplicationController
  #include?メソッドありの場合
  def index
   #投稿された全イベントを最新順に取得
   @events = Event.all.order("id DESC").includes(:user)
  end
```
<img width="507" alt="スクリーンショット 2018-10-24 23.41.26.png" src="https://qiita-image-store.s3.amazonaws.com/0/239663/795a05bd-4278-6f04-8516-6f494f3f55a7.png">
##Rendering: events/index	1164.4と書かれており、およそ処理が３倍以上になりました！

投稿数が１００００件を超えてinclude?なしで全データを取得など考えたらゾッとしますね笑
まだ他にも改善しなければいけないところはありますが、今回の実験でN+1問題を実感できました！

ではでは、、、
[pd.read_csv] IsADirectoryError: [Errno 21] Is a directory: '[パス名]/.AppleDouble'

for文の中でpandasのpd.read_csvを使ってディレクトリ内全てのcsvファイルを逐次読み込もうとしたら

```
IsADirectoryError: [Errno 21] Is a directory: '[パス名]/.AppleDouble'
```
とかいうエラーに出会ったので解決方法をシェアします．

#原因

調べてみると，macで自動生成される.AppleDoubleとかいうファイルが原因でcsv読み込みの際に邪魔をしていたみたいです．
http://ozawa.edoblog.net/memorandum/.appledouble%E3%81%A8%E3%81%8B%E9%82%AA%E9%AD%94%E3%81%AA%E4%B8%8D%E5%8F%AF%E8%A6%96%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%82%92%E6%B6%88%E3%81%99

上のリンクにしたがって，.AppleDoubleを消したいファイルにcdで移動して，

```
find . -name .AppleDouble -exec rm -rf {} \;
```
と入力すれば，エラーが消えて実行できました！
React Nativeのビルドエラー 'config.h' file not foundが発生する問題

## 問題
MacのOSのバージョンを上げると、ビルドが通らない問題が発生。ビルドすると、 `'config.h' file not found` とエラーがでる。

## 解決策

手動でスクリプトを実行する必要がある。

```
 rm -rf node_modules/ && yarn cache clean && yarn install
 node_modules/react-native/scripts/ios-install-third-party.sh
 cd node_modules/react-native/third-party/glog-0.3.x
 ./configure
```

## 参考
https://github.com/facebook/react-native/issues/19529#issuecomment-423898864
pyenv installでこけて途方に暮れた話 (on MacOSX mojave)

# 事象
標題の環境にてpyenv installしたところ、下記のようなエラーを吐いて失敗した。

```
zipimport.ZipImportError: can't decompress data; zlib not available
make: *** [install] Error 1
```

[こちら](https://github.com/pyenv/pyenv/wiki/Common-build-problems#build-failed-error-the-python-zlib-extension-was-not-compiled-missing-the-zlib)を参考に、xcode-select --installを実行したところ、以下のエラーを吐かれた。

```
xcode-select: error: command line tools are already installed, use "Software Update" to install updates
```
さぁ、どうしよう、、。

# 解決策
以下を実行。

```
sudo installer -pkg /Library/Developer/CommandLineTools/Packages/macOS_SDK_headers_for_macOS_10.14.pkg -target /
```
再度 pyenv install実行したところ、無事インストール完了した。

誰かのお役に立てれば幸いです。

参考
https://github.com/pyenv/pyenv/issues/1219
Pythonでinstallしたモジュールが使えない、とか、importできない人向け（PYTHONPATHの話）

# モジュール入れたのに認識してくれないよぉー

## そんな時は、

pythonを実行している環境で、↓を実行しましょう。
※IDEとかから起動してたらブレークしてから、↓を実行。コマンド起動してる人はpdbでブレークだ！

```python
>>> import sys
>>> sys.path
```

パスの一覧が出てくると思うのですが、一覧の中に使いたいモジュールのフォルダの親フォルダが入っていますか。。？

例）使いたい hoge_module が↓に入ってる時、
C:\Users\xxxxx\AppData\Local\Programs\Python\Python36\Lib\site-packages\hoge_module
sys.pathの一覧の中に
C:\Users\xxxxx\AppData\Local\Programs\Python\Python36\Lib\site-packages
っていうのがあるかっていうこと。

ここを見てるっていうことは無いんじゃないかと思うのですが、そういう時は環境変数にPYTHONPATHを設定して、使いたいモジュールの親フォルダを設定しましょう。


windowsなら、（使いたいモジュールが、c:\hoge\hoge_module にいる場合）

```
set PYTHONPATH=c:\hoge
```

linuxなら、（使いたいモジュールが、/home/hoge/hoge_module にいる場合）

```bash
export PYTHONPATH="/home/hoge"
```

↑を実行した状態で、もう一度、

```python
>>> import sys
>>> sys.path
```

パスの一覧の中にPYTHONPATHで設定したパスが出てくるはず。
そして使いたいモジュールが使えるようになっているはず。

## まーでも、、

意図的にやってるわけじゃないのにPYTHONPATH設定しないと上手く動かない時は、自分の環境が正しい状態なのか振り返ってみた方が良いでしょう。。

## 参考リンク

[公式のモジュール検索パスについての説明](https://docs.python.jp/3/tutorial/modules.html#the-module-search-path)
正規表現(JavaScript)

##概要
正規表現とは文字列の集合を一つの文字列で表現する方法の一つである。
`スラッシュ`で囲むことで正規表現と認識される。
文字検索やバリデーションなどで使用される。

##記号早見表
| 記号 | 説明 | 例 |例でマッチする文字列|
|:-----------|:------------|:------------|:------------ |
| . | なんでも良い一文字 | /x.z/  |“<font color=#FA6681>xyz</font>“ |
| * | 直前の1文字の0回以上の繰り返し | /xyz*/ |“<font color=#FA6681>xyzzzz</font>“ |
| ^ | 先頭にマッチ | /^x/ |“<font color=#FA6681>x</font>yz“|
| $ | 末尾にマッチ | /x$/ |“zy<font color=#FA6681>x</font>“|
| \\　| 次の文字を単なる文字として認証 | /\\^x/ | “<font color=#FA6681>^x</font>yz“ |
| [ ] | カッコ内の任意の1文字にマッチ | /[0-9]/| “xyz<font color=#FA6681>7</font>“ |
|( )| パターンをグループ化する | /(xyz)*/  |“<font color=#FA6681>xyzxyz</font>“|
| {n} | 直前の文字がちょうど n 回出現するものにマッチ | /x{3}/ | “<font color=#FA6681>xxx</font>yz“ |
| ? | 直前の文字が0個または1個 | /xyz?/ |“<font color=#FA6681>xyz</font>"または"<font color=#FA6681>xy</font>"|
|&#124;| 直前、直後どちらかにマッチ | /x&#124;z/|“<font color=#FA6681>x</font>y<font color=#FA6681>z</font>"|


##よく使うパターン例

半角数字

```
/[0-9]/
または
/\d/
```
全角数字

```
/[０-９]/
```
半角数字か全角数字のいずれか

```
/[0-9０-９]/
```

英数字（アンダースコア含む）

```
/[A-Za-z0-9_]/
または
/\w/
```

郵便番号（ハイフン有り無し両方対応）

```
/^\d{3}-?\d{4}$/
```

携帯番号（ハイフン有り無し両方対応）

```
/0[7-9]0-?\d{4}-?\d{4}/
```

日付

```
/^[12]\d{3}/(0?[1-9]|1[0-2])/([12][0-9]|3[01]|0?[1-9])/
```
クレジット（VISA）

```
/4(?:\d{15}|\d{12})/
```
Apacheのrewritelogの出力方法(Apache2.2とApache2.4で違います)

`RewriteCond`や`RewriteRule`の条件をデバッグするときによく使うのですが、
その都度方法を調べてしまっているので備忘も兼ねて書いちゃいます。

`Apache2.2`と`Apache2.4`でやり方が全然違くなってしまいました。
これからはほとんど2.4になると思うので、先に2.4の方法を記載します。


## Apache2.4 での設定方法

### 設定方法
Apacheのconfに以下の記述を追加します。

```apache
LogLevel debug rewrite:trace8
```

### 軽く説明

`Apache2.4`からは`RewriteLog`という独立したログはなくなり、
coreモジュールの`Loglevel`ディレクティブを使って指定する方法に変更されました。
出力ファイルは指定できず、他のログと一緒に`error_log`に出るようになります。
レベルは`trace1 ～ trace8` までで、数値が大きくなるほど冗長になります。
膨大にログが出て重くなるので、デバッグ以外の目的で trace2 以上を使うのは止めた方がよいです。

### 公式ドキュメント
http://httpd.apache.org/docs/2.4/mod/mod_rewrite.html


## Apache2.2 での設定方法

### 設定方法
Apacheのconfに以下の記述を追加します。

```apache
RewriteLog "/tmp/httpd.rewrite.log"
RewriteLogLevel 9
```

### 軽く説明
`RewriteLogLevel`は`0～9`まであり、ログの詳細レベルを指定します。
`9`が一番詳細で、`0`だと何も出力しません。

## 注意点(2.2と2.4共通)
- 基本的には`VirtualHosts`内に書くことが多いと思います。僕は`VirtualHosts外`に書いたことがありません。
- `.htaccess`では書けません。書いちゃうとInternal Server Errorになります。
- Logが肥大化しすぎてサーバーのパフォーマンス低下を引き起こすため、デバックが終わったら設定を戻しましょう。
自分で書いたコードを自分でリファクタリング

###はじめに
最近「プロを目指す人のためのruby入門」を読み直しているものです。

[[Ruby][解答募集]文字列に出現する単語の個数を数えてみよう
](https://qiita.com/jnchito/items/c4a56046be1096c19b1c)
三ヶ月くらい前にこちらの記事を読んで自分が書いたコードが汚く見えてきたので自分が今まで学んだことでできる範囲でリファクタリングしてみました。
まずは元のコード

```ruby
def count_word(string)
  words_array = string.split(' ')
  uniq_words = words_array.uniq
  hash = {}
  uniq_words.each do |word|
    hash[word] = words_array.count(word)
  end
  hash
end
```

リファクタリングしようと思えばより高速で短くする方法はいくらでもあると思いますが、今回は**ローカル変数の宣言が多い**という問題点に絞ってロジックそのものは変えずその点を改良できるようなリファクタリングを行いました。

##uniq_array
uniq_arrayを定義しなくても、hash[word]で同じキーの要素があれば更新されるのでいらないのでは、と考え、まずこの宣言を削除。このリファクタリングだと同じ単語の数だけ処理が行われてしまうので、よりよいリファクタリングはまだまだ追求できそう。

```ruby
def count_word(strings)
  words_array = strings.split(' ')
  hash = {}
  words_array.each do |word|
    hash[word] = words_array.count(word)
  end
  hash
end
```

###   hash = {}
このハッシュの宣言も折りたたみ演算としてinjectを使えば削除できます。

```ruby
  words_array.inject(Hash.new) do |hash, word|
    hash[word] = words_array.count(word)
    hash
  end
```

###最終的に
最後になりましたがcount_wordというメソッド名も良くないですね。count_by_wordのほうが何をするメソッドなのかわかりやすいです

```ruby
def count_by_word(string)
  words_array = string.split(' ')
  words_array.inject(Hash.new) do |hash, word|
    hash[word] = words_array.count(word)
    hash
  end
end
```

結局まだ一回変数宣言してますね… group_byしたりハッシュのバリューを増やしていく方法を使えば省略できそうですが今回はメインのロジックは変えない形でのリファクタリングなのでこれ以降はなかなか思いつきませんでした。もしまだまだイケる！という方いればぜひご教授ください。

###まとめ
リファクタリングする際には昔書いたテストが役に立ちました。やっぱりテストは大事。
課題の記事のコメント欄にある回答例をみるとtapを使っていたり、group_byを使っていたりと目からウロコのやり方のコードを見れて勉強不足の身ながら感心しております。
みんなで一つの課題に対してコードを書いてお互いに見せ合うみたいな勉強会参加したいなぁ（欲望）ということで今回の記事はおしまいです。
最後まで読んでいただきありがとうございます。
クロスサイト・スクリプティング(XSS)について

#クロスサイト・スクリプティング(XSS)
クロスサイトスクリプティング（XSS）とは、エンドユーザー側がWebページを制作することのできる動的サイト（例：TwitterなどのSNS、掲示板等）に対して、その脆弱性を利用して悪意のある攻撃者が制作した不正なスクリプトを挿入することによりその発生するサイバー攻撃です。
参考URL：https://cybersecurity-jp.com/security-measures/18427

#XSS対策
エンジニアとしては下記を年頭に置く
 - HTMLタグやスクリプトタグを無効にする

例：下記のタグを登録項目に入力する
 - `<script>alert("hoge")</script>`
 - `<p style="font-size:100px">大きくならないこと</p>`

上記を登録画面などで入力し、プレビュー画面などでXSS対策がされていれば
スクリプトが発生することも文字が大きくなることはありません。

今回は簡単な例によって紹介しましたが、実際にはブラウザのバージョンを上げたり、
セキュリティーソフトを導入したりしたほうがよいとのことです。

XSS対策をすることは、
**非常に危険なサイバー攻撃を防ぐ**
ことにつながるので必須知識であると感じます。

もっとこういうことをするべきなどがあればコメントいただけると幸いです！
tmux を捨てて Emacs Daemon で生きる

Emacs 使いが tmux を使うのは邪道な気がするので、Emacs Daemon で生きる。

~~~sh
emacs --daemon
~~~
でバックグラウンドで Emacs を起動し、

~~~sh
emacsclient -t
~~~
でターミナルからアタッチする。これでセッションが切れても安心。

Emacs Deamon の終了方法は Emacs の中から

    M-x kill-emacs
   
かターミナルから

    emacsclient --eval '(kill-emacs)'
   
で行う。

あとは Emacs の中で生きていく上での tips をいくつか。

## root 権限でファイルの編集

標準機能の [TRAMP](https://www.gnu.org/software/tramp/tramp-emacs.html) で行う。

    C-x C-f /sudo::/etc/passwd

で sudo 経由でファイルが開ける。もしくは、

    C-x d /sudo::/etc

で `/etc` を Dired で開ける。


## Emacs の中で仮想ターミナルを開く

`M-x shell` や `M-x eshell` で不十分なら `M-x term` か  `M-x ansi-term` でターミナルを開く。ansi-term のほうが `C-x` が標準の Emacs が解釈してくれるので使いやすいように思う。


## 参考

* [Emacs as tmux replacement – Łukasz Korecki – Medium](https://medium.com/@lukaszkorecki/emacs-as-tmux-replacement-2acd10d7dfc8)
reduce

#reduce
```javascript:
<script type='text/javascript' >
var plus = function(x,y){
	console.log(x,y);
	return x + y; 
}
var a = [1,2,3,4,5,6,7,8,9,10].reduce(plus);
console.log(a);

var d = {'A':10,'b':11,'c':12}.reduce(plus);
console.log(d);
</script>
```

連想配列は
SCRIPT438: オブジェクトは 'reduce' プロパティまたはメソッドをサポートしていません。


```javascript
<script type='text/javascript' >
var plus = function(x,y){
	return x + y; 
}

var minus = function(x,y){
	return x - y; 
}

var kome = function(x,y){
	return x(1,2) * y(3,4); 
}

var a = [plus, minus].reduce(kome);
console.log(a);
</script>
```
これはできた
データドリブン業務におけるスクラム実践で感じたこと

# はじめに

私は、社内のデータ分析部門で業務を行っていますが、その際にスクラムライクなチーム運用を行っています。
分析という業務はスクラムと親和性が高いと感じていますので、所感をまとめてみました。

なお、私はスクラムに対する知識は不十分なので、おかしい点がありましたら是非ご指摘ください。

# メリット

 - (週1、隔週などで行われる)定例の分析報告会議などとスプリントが相性が良い
 - 業務都合などで方向性が変わりやすい分析業務を柔軟に対応することができる
  - PoCなどを行いながら段階的に進めるAI開発とも親和性が高い
 - レビューにより、属人化しやすい分析結果のナレッジがチーム内に共有される
  - 一方で、ナレッジを統一的に蓄える仕組みづくりが重要 
 - レトロスペクティブ(振り返り)で、技術的負債を返済する
  - 分析業務は、ツールの導入やマートの作成などで効率化できる部分が多い
  - メンバーの分析時のProblemに対し、他メンバーのノウハウできることもある
  - KPTの実践がPDCAに通じるものがある


# 注意したことや実践したこと

- スクラムについての基礎説明を行う
 - どういう意図でスクラムを行うか、何故各会議体を設置するのか等
 - 分析やってる人はスクラムの言葉自体知らないことがあるので、自己組織化のためには必須
- タスクの終了条件と厳密に定義する
 - モデルを作るのか、評価までするのか、結果を資料にまとめるまでなのか
 - 「結果を見て深掘り」など、前段結果を踏まえた動きは、柔軟にタスク化する
- ナレッジ共有と効率化のために、分析の一連資料をある程度フォーマット化する
 - おおまかには、目的、分析設計、分析内容、結果など 



# 参考

 - [【スクラム入門】認定スクラムマスターの俺が正しいスクラムの理論をまとめる](https://qiita.com/gold-kou/items/90ba982a14ca79d843c9)
 - [スクラムをざっくり説明するときのスライド
](https://qiita.com/halhorn/items/5cf7d28034ad9132d311)
ubuntu 18.04 時刻とタイムゾーン設定

# タイムゾーンの設定

18.04新規インストール時はデフォルトではUTCになっていて9時間ずれていたので設定する。  
(というか、OSインストール時にタイムゾーンを設定するタイミングがなかったような…)

```
root@epoisses:~# date
Sat Oct 20 01:07:35 UTC 2018
root@epoisses:~# timedatectl
                      Local time: Sat 2018-10-20 01:07:58 UTC
                  Universal time: Sat 2018-10-20 01:07:58 UTC
                        RTC time: Sat 2018-10-20 01:07:59
                       Time zone: Etc/UTC (UTC, +0000)
       System clock synchronized: yes
systemd-timesyncd.service active: yes
                 RTC in local TZ: no
root@epoisses:~# timedatectl list-timezones | grep -i tokyo
Asia/Tokyo
```

設定

```
root@epoisses:~# timedatectl set-timezone Asia/Tokyo
root@epoisses:~# timedatectl
                      Local time: Sat 2018-10-20 10:09:15 JST
                  Universal time: Sat 2018-10-20 01:09:15 UTC
                        RTC time: Sat 2018-10-20 01:09:16
                       Time zone: Asia/Tokyo (JST, +0900)
       System clock synchronized: yes
systemd-timesyncd.service active: yes
                 RTC in local TZ: no
root@epoisses:~# date
Sat Oct 20 10:09:18 JST 2018
root@epoisses:~#
```

# 時刻の設定

メモが残ってたので張り付けておく。。

```
root@cheddar:~# timedatectl set-time "2018-08-15 07:20:00"
Failed to set time: Automatic time synchronization is enabled
root@cheddar:~# timedatectl status
                      Local time: Wed 2018-08-15 16:21:29 JST
                  Universal time: Wed 2018-08-15 07:21:29 UTC
                        RTC time: Wed 2018-08-15 07:21:28
                       Time zone: Asia/Tokyo (JST, +0900)
       System clock synchronized: no
systemd-timesyncd.service active: yes
                 RTC in local TZ: no
root@cheddar:~# timedatectl set-ntp no
root@cheddar:~# timedatectl set-time "2018-08-15 07:22:00"
root@cheddar:~# timedatectl set-ntp yes
root@cheddar:~# timedatectl status
                      Local time: Wed 2018-08-15 07:22:04 JST
                  Universal time: Tue 2018-08-14 22:22:04 UTC
                        RTC time: Tue 2018-08-14 22:22:05
                       Time zone: Asia/Tokyo (JST, +0900)
       System clock synchronized: no
systemd-timesyncd.service active: yes
                 RTC in local TZ: no
root@cheddar:~# 
```
deviseで複数のモデルを作る時の参考者

見出し
## Devise議事録（複数モデルを作るときのメモ）

```rails5.1.6
devise
```
**モデル**
User,Customerの２つで話を進めていきます

#準備

```
・gem　'devise'　をインストールした
・deviseでUserモデルを作成した。
・deviseで２つ目のCustomerモデル（Customerでなくても大丈夫です!
）を作成した。
```

のを前提に進めていきます。

#モデルの作成
そもそも、deviseでは

```
$ rails g devise モデル名(Tom　のように大文字から始めなければいけない)
```

で好きな名前のモデルを作ることができます。（２つでも３つでも）

```
$ rails g devise User
$ rails g devise Customer
```
でUserモデルとCustomerモデルを作成


これで

```
current_user,current_customer,customer_singed_in?user_signed_in?
```
のメソッドが使えるようになりました！

#一般化してみましょう

```
current_モデル名、モデル名_signed_in?
```

メソッドなどが使えるようになります！
Spring Boot でコンポーネント自身のプロキシインスタンスを取得する

#前提
`RequestScope`などがついたコンポーネントから、（手を出せないところで同値チェックされているという理由で）プロキシのほうを保持したクラスを返す必要があった。

#解決方法
こんなんでよかったのかわからないが、自分自身を`Autowired`して実現できた。

```java
@Component
@RequestScope
public class Hoge {
  private final Hoge proxyInstance;
  @AutoWired
  public(Hoge proxyInstance) {
    if (!(proxyInstance instanceof ScopedObject)) {
      throw new IllegalArgumentException("プロキシを渡して");
    }
    this.proxyInstance = proxyInstance;
  }

  public Fuga getFuga() {
    return new Fuga(proxyInstance);
  }
}
```
Weblogicの探査行為？(CVE-2018-3252)

10月16日に、Oracle Fusion Middleware の WLS Core Components
において、任意のコードが可能な脆弱性が公開(CVE-2018-3252)されました。
[Oracle Critical Patch Update Advisory - October 2018](https://www.oracle.com/technetwork/security-advisory/cpuoct2018-4428296.html)

本発表の約1週間後、本脆弱性の発見者の「Zhiyi Zhang of 360 ESG Codesafe Team」氏は22日、[ブログ](https://paper.seebug.org/721/)の方で情報を公開しています。

#脆弱性のポイント
weblogicのユーザ認証をバイパスして、コード実行を試みる脆弱性みたいです
basic認証を突破して、コード実行できる脆弱性みたいですので、最悪という感じではない印象です。
発見者ブログにあるパスにアクセスした結果を記載します。
①GET /bea_wls_deployment_internal/DeploymentService HTTP/1.1
![aaaaaaa.JPG](https://qiita-image-store.s3.amazonaws.com/0/254131/50626d86-12a8-df42-fc38-c8dfbbed9a97.jpeg)

コンテンツが存在していた場合、サーバからはコンテンツサイズ0の、200 OK が返ってきます。

②POST /bea_wls_deployment_internal/DeploymentService HTTP/1.1
![bbbbbbbbbb.JPG](https://qiita-image-store.s3.amazonaws.com/0/254131/df0977f6-5ce6-54d4-8afd-3eefe4e0ccf5.jpeg)

content-length:0で、正しいusernameとpasswordを付けてあげると、500エラーが返ってきました。

#ハニーポットでの検知
本脆弱性に関係するかは不明ですが、/bea_wls_deployment_internal に対して、oracleのCritical Patchより早い12日から検知し始めています。
400以上のIPアドレスから合計2000回ほどのアクセスでした。
ただ、/bea_wls_deployment_internal/DeploymentServiceが存在しても、/bea_wls_deployment_internalは404を返します。
何か深い理由でもあるんでしょうか。

![キャプチャ.JPG](https://qiita-image-store.s3.amazonaws.com/0/254131/8d330ff7-ca46-8682-c6bf-5b93f3cfe2c7.jpeg)

#最後に
今回の脆弱性は、basic認証が必要そうなので、そこまで影響は高くないですが、
公開していたら閉じましょう。
tshark でフィルタを組み立てるときは json 表示が便利

トラブルシューティングなどでキャプチャしたパケットを詳細に見たいとき、(キャプチャするときには tcpdump を使っても)見るときは各種プロトコルを詳細にデコードできる Wireshark/tshark 等を使うことが多いと思います。

Wireshark は GUI の上からパケットの各フィールドを選択して、"Apply as Filter" などのコマンドを選ぶことで簡単にフィルタを組み立てることができますが、環境によっては pcap ファイルを簡単に Wireshark の使える場所まで持っていけない場合もあるかと思います。
ただ、その場合に使える tshark の 詳細表示モード (```-V```) から Filter として使えるフィールド名に読み替えるのはちょっと面倒です。

```terminal
$ tshark -nr test.pcap -V | less
<中略>
Internet Control Message Protocol
    Type: 8 (Echo (ping) request) 
    Code: 0
    Checksum: 0xc536 [correct]
    [Checksum Status: Good]
    Identifier (BE): 28260 (0x6e64)        ← が 28260 であることを表現するフィルタは 
    Identifier (LE): 25710 (0x646e)          icmp.ident == 28260 だけど、覚えていないと
    Sequence number (BE): 1 (0x0001)         なかなか出てこない
    Sequence number (LE): 256 (0x0100)
    Timestamp from icmp data: Oct 24, 2018 12:16:36.000000000 UTC
    [Timestamp from icmp data (relative): 0.381598000 seconds]
    Data (48 bytes)
<省略>
```

そういうときは tshark 2.1.0 以降のみですが、```-T json``` で json 出力するとわかりやすくなります。
json のキーがそのままフィルタに使えるフィールド名になっているのです。

```terminal
$ tshark -nr test.pcap -T json | less
<中略>
        "icmp": {
          "icmp.type": "8",
          "icmp.code": "0",
          "icmp.checksum": "0x0000c536",
          "icmp.checksum.status": "1",
          "icmp.ident": "28260",
          "icmp.ident": "25710",
          "icmp.seq": "1",
          "icmp.seq_le": "256",
          "icmp.data_time": "Oct 24, 2018 12:16:36.000000000 UTC",
          "icmp.data_time_relative": "0.381598000",
<省略>
```

これで、tshark しか使えない環境でも簡単に Filter を組み立てることができます。
```-V``` でざっくり眺めて ```-T json``` でフィルタに使うフィールド名を確認して、とやると tshark だけで完結して楽です。

```terminal
$ tshark -nr test.pcap -Y "icmp.ident == 28260"
   41  10.032921    127.0.0.1 → 127.0.0.1    ICMP 98 Echo (ping) request  id=0x6e64, seq=1/256, ttl=64
   42  10.032985    127.0.0.1 → 127.0.0.1    ICMP 98 Echo (ping) reply    id=0x6e64, seq=1/256, ttl=64 (request in 41)
   51  11.032635    127.0.0.1 → 127.0.0.1    ICMP 98 Echo (ping) request  id=0x6e64, seq=2/512, ttl=64
   52  11.032711    127.0.0.1 → 127.0.0.1    ICMP 98 Echo (ping) reply    id=0x6e64, seq=2/512, ttl=64 (request in 51)
   53  12.032624    127.0.0.1 → 127.0.0.1    ICMP 98 Echo (ping) request  id=0x6e64, seq=3/768, ttl=64
   54  12.032693    127.0.0.1 → 127.0.0.1    ICMP 98 Echo (ping) reply    id=0x6e64, seq=3/768, ttl=64 (request in 53)
   63  13.032637    127.0.0.1 → 127.0.0.1    ICMP 98 Echo (ping) request  id=0x6e64, seq=4/1024, ttl=64
   64  13.032726    127.0.0.1 → 127.0.0.1    ICMP 98 Echo (ping) reply    id=0x6e64, seq=4/1024, ttl=64 (request in 63)
<省略>
```
Hyper-VのVHDXを容量可変→容量固定に

Hyper-VでVMを作成する際にVHDXのディスクの種類がどうあるべきかを本気で考えたのでメモメモ。

## 容量可変ディスクの問題点
##### ファイルサイズが自動縮小されない
最初はコンパクトに始めても、データが増えるに従ってディスク容量が勝手に拡張される。その後にデータを削除してもファイルサイズは縮小されない問題。対応策は[このリンク](https://www.ipentec.com/document/windows-hyper-v-trim-vhdx-file)の通りだが、運用が面倒。
##### 容量固定ディスクよりも読み書きが遅い
##### フラグメンテーションする可能性が高くなる
##### 「Block Allocation Table」がディスクに追加されるため固定のディスクよりサイズが大きくなる
「Block Allocation Table」の詳細は[このサイト](https://www.altaro.com/hyper-v/hyper-v-guest-design-fixed-vs-dynamic-vhd/)を参考にしてください。
##### オーバーコミットされる環境下ではディスク容量が枯渇し、他の問題を引き起こす可能性がある

## 容量固定ディスクの問題点
##### 使っていないディスクの領域を取られる
##### 大きいサイズのVHDXはVMのポータビリティーを損なう

## 容量可変→容量固定にすることに、、、
滅多に容量が変化しないことが想定されるVMなので、容量固定のVM(VHDX)を作成することになった。既に作成していた容量可変のVM(VHDX)があったので容量固定として作り直すことに。

## やり方
### DiskPartコマンドラインユーティリティ起動
コマンドプロンプトで

```
DiskPart
```
から起動する。

### 容量可変のVHDXを容量固定のVHDXにコピー
直接コンバートすることはできないのでVHDXを新規作成しコピーする処理が必要が。流したコマンドは以下の通り。

```
create vdisk file="新規作成する固定のVHDX" source="容量可変として作成していたVHDX" type=fixed
```
容量可変時に設定した最大サイズでコピー先のVHDXはできるのでディスクサイズの枯渇に注意。
MaximumSizeを指定できたらいいのになー。

### Hyper-Vから仮想マシンを作成
作成した容量固定VHDXをHyper-Vに食わせて仮想マシンを作成する。Ｃドライブには容量可変時に設定したフルフルのサイズとしてディスクサイズが割り振られている。

### 仮想マシンのＣドライブに割り当てられた領域を未割り当てにする
明らかに余りがあるのに、未割り当てにできない場合や「ディスク容量が足りない」と怒られる場合はデフラグしてから実行すると状況の改善が見込まれます。

### 容量固定のVHDXのサイズの縮小
仮想マシンのドライブを未割り当てにすると、ホスト側のHyper-Vの「ディスクの編集」でディスクの縮小ができるようになります。今回作成した容量固定VHDXを選択しディスクの縮小を行います。

## 容量可変のVHDXのサイズを最適化（圧縮）する方法
ちらっと上に書きましたが、以下のサイトにやり方が載ってました。

* https://www.ipentec.com/document/windows-hyper-v-trim-vhdx-file

ちなみに私の仮想マシンは手順の実行で２０ＧＢ減らすことができました。
Optimize-VHD　コマンドレットは２回実行すると良いみたいな記事も見ました。


## 感想
地味にメンドくさかった。

## 参考
容量固定と容量可変のトレードオフについて

* https://www.altaro.com/hyper-v/hyper-v-guest-design-fixed-vs-dynamic-vhd/
* https://serverfault.com/questions/412813/do-i-create-a-fixed-size-or-expandable-vhd-if-i-know-the-contents-size-in-advanc
C# 自前でイベントハンドラを作って使う一番簡単な例

C# 自前でイベントハンドラを作って使う一番簡単な例

コードは以下にあります。
https://github.com/kumokumocc/WORK_/tree/master/EventTest

フォームアプリケーションで、ボタンが1個だけあります。
ボタンをクリックすると、Testというクラスをインスタンス生成し、Runというメソッドを呼び出します。
その中で5秒ウェイトしてイベントOnTestを実行します。
イベント発生すると、FoirmクラスのTestHandlerが呼び出され、"イベントハンドラが呼び出されました"というメッセージボックスを表示します。

TestクラスとForm1クラスを全く別の人が作る場合を考えると、イベントの意味が分かります。


```
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace EventTest
{
    public class Test
    {
        public void Run()
        {
            System.Threading.Thread.Sleep(5000);//5秒待つ
            OnTest(this,EventArgs.Empty);//イベントハンドラ呼び出し
        }
        public event EventHandler OnTest;
    }

    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            Test t = new Test();
            t.OnTest += TestHandler;//イベントハンドラ追加
            t.Run();//実行
        }

        private void TestHandler(object sender,EventArgs e)
        {
            MessageBox.Show("イベントハンドラが呼び出されました");
        }
    }
}
```
x86_64のUbuntuでarm64のdockerイメージを動かす (クロスでdocker実行)

[クロスDockerのためのDockerfile](http://d.hatena.ne.jp/embedded/20140820/p1)という記事を以前書いたのですが、現在のバージョンのdockerではDockerfileを書かなくてもすむようになっていました。

Ubuntu 18.04 を使用しています。

# docker run を実行

```
$ docker run -it arm64v8/ubuntu:18.04
standard_init_linux.go:195: exec user process caused "no such file or directory"
```

これはアーキテクチャが異なるので実行はエラーになります。

# スタティックリンクされたqemuをコンテナの中にコピーする

まずはコンテナIDを確認。

```
$ docker ps -a
CONTAINER ID        IMAGE                  COMMAND             CREATED             STATUS                      PORTS               NAMES
388345ce4956        arm64v8/ubuntu:18.04   "/bin/bash"         19 minutes ago      Exited (0) 39 seconds ago                       goofy_agnesi
$
```

そのコンテナの中に`qemu-aarch64-static` をコピーする。これはx86_64の実行ファイル。

```
sudo apt install qemu-user-static
docker cp /usr/bin/qemu-aarch64-static 388345ce4956:/usr/bin/qemu-aarch64-static
```

# コンテナをcommit してdocker image を作成

```
$ docker commit 388345ce4956 arm64v8/ubuntu:18.04_cross
sha256:2ae592d2c21dd0f77954f83152e26fb17816e83aa94855a59bfe0e18ac8fe963
```

# docker run を実行

今度は正常に実行できます。

```
$ docker run -it arm64v8/ubuntu:18.04_cross
root@828eebd24c03:/# ls
bin   dev  home  media  opt   root  sbin  sys  usr
boot  etc  lib   mnt    proc  run   srv   tmp  var
root@828eebd24c03:/# uname -a
Linux 828eebd24c03 4.15.0-36-generic #39-Ubuntu SMP Mon Sep 24 16:19:09 UTC 2018 aarch64 aarch64 aarch64 GNU/Linux
```
masterではgit commit出来ないようにhooks/pre-commitを設定する

# masterではcommit出来ないようにしたい
- git hookで設定する
- $project/.git/hooks/pre-commit におくと、そのプロジェクトのみで有効。
- 下のように templatedirを設定しておくと、今後git cloneしたプロジェクトではすべて有効。

```
git config --global init.templatedir '~/.git_template' 
```

- `~/.git_template/hooks/pre-commit` or `$project/.git/hooks/pre-commit` に置くファイル

```
# ブランチがmasterならば
branch="$(git symbolic-ref HEAD 2>/dev/null)" || "$(git describe --contains --all HEAD)"
if [ "${branch##refs/heads/}" = "master" ]; then
    # コミット履歴があるならばmasterへのCommitはfail
    # コミット履歴がないならばmasterへのFirst Commitだけは許す
    git rev-list --max-parents=0 HEAD > /dev/null 2>&1
    if [ "$?" = "0" ]; then
        echo "Do not commit on the master branch!"
        exit 1
    fi
fi
```

- 実行には権限追加が必要。

```
chmod 744 .git/hooks/pre-commit
```

- 実際にmasterブランチでcommitしてみる...OK!

```
git commit -av

# => Do not commit on the master branch!
```
Eclipseでコンソールの出力を色分けする方法

System.out.println()などを使ってコンソールにログを出力するようにしていると、コンソールログを確認したいときにログが埋もれて探すのが大変なことがあります。

```Java:Sample
public class Sample {
	public static void main(String[] args) {
		for (int i=0; i<10; i++) {
			if (i == 5) {
				System.out.println(i+"回目のループです。");
			}
			if (i%3==0) {
				System.out.println("Hoge Hoge");
			} else if (i%3==1) {
				System.out.println("Huga Huga");
			} else {
				System.out.println("Moku Moku");
			}
		}
	}
}
```

![a.PNG](https://qiita-image-store.s3.amazonaws.com/0/284567/4a628ece-2218-6fc0-472d-c34a788c1b11.png)

そういうときは**System.err.println**を使うと確認したい項目を赤色で表示することができます。Eclipseでは標準エラー出力は赤色で出力されるようになっているようです。（ちなみに標準入力は緑）

```Java
if (i == 5) {
    System.err.println(i + " times");
}
```

![aa.PNG](https://qiita-image-store.s3.amazonaws.com/0/284567/2f32f2a8-d370-7e71-e7c5-ba722c2bb1de.png)
Python3でHello Qiita World!

#今回はPythonでHello Qiita World!を出力するコードを書いてみる。

```python:HelloQiitaWorld.py
# coding: utf-8
print("Hello Qiita World!")
```

今回は前回と違って[paiza.io](https://paiza.io/ja)で正常に出力されることを確認済。
border-collapseが効かない

#border-collapseが効かない
tableを普通に作るとセルとセルの間に隙間ができてしまう。
それを防ぐために

```css
table{
  border-collapse: collapse;
}
```
を書くのだが、なぜか隙間がうまらなかった。
たくさん調べたのだが、<div>タグを使って場合はcollapseは無効になるらしい。
だが今回は何の変哲もないtableだった。

#separateとborder-spacingを併用して隙間をなくす
こうすればよい。
あえて隙間を作って(seprate)、隙間をなくす(border-spacing)

```css
table{
  border-collapse: seprate;
  border-spacing:0px;
}
```
簡素な記事ですみません。
AnacondaによるKeras-TensorFlowインストール(Win10, CPU版)

Keras,TensorFlowの記事は、たくさんあるのであまり需要は無いと思いますが、毎回やり方を忘れて調べることになるので、備忘録のために書きました。

condaだけで構築しており、比較的簡単に仮想環境上に、インストールできると思います。
pipの記事は多いですが、pipとcondaを混ぜると、バージョンのコリジョンなど、結構な確率でトラブるので、Windowsユーザーには多少需要があるかなと思い、公開しました。

## 環境
- OS:Windows10 Home
- 仮想環境:Anaconda (Miniconda)
- Python3.5
- TensorFlow 1.10
- Keras 2.2.2

## 手順
Anacondaは、インストールが済んでいる前提です。

1. 仮想環境構築
2. TensorFlowインストール
3. Kerasインストール
4. Jupyterカーネルの登録  
5. 動作確認

## 1.仮想環境構築

仮想環境を構築します。

```
> conda create -n keras_work
```

作成した仮想環境を有効にします。
※必ず、activateを忘れずに行いましょう。

```
> activate keras_work
(keras_work) conda install python=3.5 numpy matplotlib jupyter
```

## 2.TensorFlowインストール

2018/10/24時点では、1.11が最新でしたが、condaでは1.10が入りました。
condaが、すべてバージョン管理してくれるので簡単です。

```
(keras_work) conda install tensorflow
```

## 3.Kerasインストール
以下のコマンドを打つだけです。
バージョンを指定したい場合は、keras=2.2.0など、指定しましょう。

```
(keras_work) conda install keras
```

## 4.Jupyterカーネルの登録
Jupyterから、kernelを変更できるようにします。
仮想環境の名前と異なりますが、わかりやすいようにバージョンを名前に入れました。
仮想環境にもバージョン情報を入れたかったのですが、構築時点で、どのバージョンがインストールされるのかわからなかったので、keras_workとしていました。

```
(keras_work) ipython kernel install --user --name keras222_tf110 --display-name keras222_tf110
```

## 5.動作確認

jupyter-notebookを立ち上げて

```
import numpy as np
import tensorflow as tf
hello = tf.constant('Hello TensorFlow!')
sess = tf.Session()
print(sess.run(hello))
```

以下のように表示されれば、okです。

```
b'Hello TensorFlow!'
```

## おまけ：トラブル
・importエラー
import numpyを行うと、importエラーが発生していました「ImportError: No module named 'numpy'」。root環境にjupyterが入っているので、仮想環境にJupyterを入れないでいたら、モジュールが正常にインポートできませんでした。
対応としては、「(keras_work) conda install jupyter」でインストールして、カーネルを再登録して「(keras_work) ipython kernel install --user 、、、」、jupyter-notebookを立ち上げなおしたら、正常に動作しました。
Railsでのログの出し方

#はじめに
エンジニア1年生です。
日々の学びのメモとしてコツコツと記事を書こうと思っています。
今回はRailsでのログの出し方について書いていきます。

#そもそもログとは？？
ログとは、コンピュータの利用状況やデータ通信など履歴や情報の記録を取る事、また記録そのものを指します。
例：勤怠ログ、アクセスログ

#ログの必要性
エラー発生時はエラーメッセージを読んで原因を探すかと思います。
開発の過程でプログラムの処理をログファイルに書き出すように実装していればどこまで処理が動いたのか、
処理に使用された値などが明確になり原因の特定が迅速に行えます。
また、開発でも想定通りに処理が動いているかをログを確認しながら進めることでより効率的に開発が進められます。

#Railsでのログの種類
Railsではログを行うためにloggerというオブジェクトが標準で用意されています。
loggerオブジェクトには5つのメソッドが用意されています。


| メソッド 　　　|役割 　　　　　　　| 
|:-----------|-------------|
| unknown    | 不明なエラー　　　 | 
| fatal     　　| 致命的なエラー |
| error      | エラー     　　　 | 
| warn       | 警告     　　　　　 |
| info       | 情報     　　　　　 | 
| debug    　　　　| デバッグ    　　　| 

上から優先順位の高いログになっています。

#書き方

```ruby:controller.rb
logger.メソッド(メッセージ内容)
```
です。

errorのログを出力したい場合は
logger.error(メッセージ内容)
と書くだけです。

#具体例
簡単な具体例を書きます。
createしたユーザーの名前をログに出力する。

```ruby:users_controller.rb
def create
    @user = User.new(users_params)
    @user.save
    ＃ここにログを仕込む
    logger.info(@user.name)
end
```

これでUserの名前がログとして出力されます。
環境によって異なるかとは思いますが、
ログの出力内容はlog/development.logに記録されます。

以上です。
PHPで文字列を分割する

# シングルバイト

## 等分

### [chunk_split](http://php.net/manual/ja/function.chunk-split.php)

```php
var_dump(chunk_split("ab\nadefqp", 2, '/'));
```

```
string(14) "ab/
a/de/fq/p/"
```

### [str_split](http://php.net/manual/ja/function.str-split.php)

```php
var_dump(str_split("ab\nadefqp", 2));
```

```
array(5) {
  [0]=>
  string(2) "ab"
  [1]=>
  string(2) "
a"
  [2]=>
  string(2) "de"
  [3]=>
  string(2) "fq"
  [4]=>
  string(1) "p"
}
```

# マルチバイト

## 等分

```php
preg_match_all('/[\s\S]{1,2}/u', "ああ\n😂defqp", $matches);
var_dump($matches[0]);

preg_match_all('/[\s\S]{1,5}/u', "ああ\n😂defqp", $matches);
var_dump($matches[0]);

preg_match_all('/[\s\S]{1,6}/u', "ああ\n😂defqp", $matches);
var_dump($matches[0]);
```

```
array(5) {
  [0]=>
  string(6) "ああ"
  [1]=>
  string(5) "
😂"
  [2]=>
  string(2) "de"
  [3]=>
  string(2) "fq"
  [4]=>
  string(1) "p"
}
array(2) {
  [0]=>
  string(12) "ああ
😂d"
  [1]=>
  string(4) "efqp"
}
array(2) {
  [0]=>
  string(13) "ああ
😂de"
  [1]=>
  string(3) "fqp"
}
```

## 指定数で分割

20180102 ⇒ 2018/01/02

```php
$string = '20180102';

// mb_substr
$list = [
    mb_substr($string, 0, 4),
    mb_substr($string, 4, 2),
    mb_substr($string, 6, 2),
];

var_dump(implode('/', $list));


// regular expression
preg_match('/([0-9]{4})([0-9]{2})([0-9]{2})/u', $string, $matches);
array_shift($matches);

var_dump(implode('/', $matches));
```

```
string(10) "2018/01/02"
string(10) "2018/01/02"
```

## 特定文字で分割

2018/01/02 23:59:00 ⇒ 2018 01 02 23 59 00

### [mb_split](http://php.net/manual/ja/function.mb-split.php)

```php
$string = '2018/01/02 23:59:00';

var_dump(mb_split('[/ :]', $string));
```

```
array(6) {
  [0]=>
  string(4) "2018"
  [1]=>
  string(2) "01"
  [2]=>
  string(2) "02"
  [3]=>
  string(2) "23"
  [4]=>
  string(2) "59"
  [5]=>
  string(2) "00"
}
```

### [preg_split](http://php.net/manual/ja/function.preg-split.php)

```php
$string = '2018/01/02 23:59:00';

var_dump(preg_split('/[\/ :]/u', $string));
```

```
array(6) {
  [0]=>
  string(4) "2018"
  [1]=>
  string(2) "01"
  [2]=>
  string(2) "02"
  [3]=>
  string(2) "23"
  [4]=>
  string(2) "59"
  [5]=>
  string(2) "00"
}
```

### [explode](http://php.net/manual/ja/function.explode.php)