OmniAICreator/Qiita-1.07M huggingface dataset:
bashでプロンプトに関数を嵌め込んだ sagiritalk

# PS1
シェルの設定は基本ここで弄りますよね

```bash:~/.bashrc
export PS1='\! \t \w \$ '
```
それで

```bash
261 01:59:02 ~ $ 
```
こんな感じで表示されるわけですが、それでは次の例ではどうでしょうか？

```bash:~/.bashrc
export PS1='`echo "Hello World!"` \$ '
```

```bash
Hello World! $ 
```
はい、このようにちゃんとコマンドが実行されています。
しかしこれではechoがexport時に実行されているのか、プロンプトが表示されるたびに実行されているかはわからないため、次のようなものを用意します。

```bash:~/.bashrc
export PS1='`echo "Hello World!" $RANDOM` \$ '
```

```bash
Hello World! 7487 $ 
Hello World! 4278 $ 
Hello World! 160 $ 
```
結果はご覧の通り、エンターキーが押されるたびに数字が変動しています。
つまりプロンプトが表示されるたびに``で囲ったコマンドが実行されているのです！

# 使用例
```bash:~/.bashrc
export sgrpatt=`cat ~/Hacks/sagiritalk/sagiri.txt | grep -c ""`
export PS1='\! \w \n 紗霧「`~/Hacks/sagiritalk/sagiri.sh`」 \$ '
```
```bash:~/Hacks/sagiritalk/sagiri.sh
sgrno=$(($(($RANDOM % $sgrpatt)) + 1))
cat ~/Hacks/sagiritalk/sagiri.txt | head -n $sgrno | tail -n 1
```
```
265 ~ 
 紗霧「部屋を出たら負けだと思っているわ！」 $ 
265 ~ 
 紗霧「な〜に？にいさん」 $ 
265 ~ 
 紗霧「にいさんのばか！にぶちん！ラノベ主人公！！！」 $ 
```

# 使用例２
```bash:~/.bashrc
export PATH=$PATH:`find ~/Hacks -type d -name '*bin' | paste -s -d : -`
export PS1='\! \w \n 紗霧「`cat ~/Hacks/sagiritalk/log.txt`」 \$ '
```
```bash:~/Hacks/bin/sagiri
sgrpatt=`cat ~/Hacks/sagiritalk/sagiri.txt | grep -c ""`
sgrno=$(($(($RANDOM % $sgrpatt)) + 1))
cat ~/Hacks/sagiritalk/sagiri.txt | head -n $sgrno | tail -n 1 > ~/Hacks/sagiritalk/log.txt
```
```
266 ~ 
 紗霧「にいさん...どうしたの？ 」 $ sagiri
267 ~ 
 紗霧「にいさんご飯... 」 $ sagiri
268 ~ 
 紗霧「エッチなイラストは、仕事だし、好きだからいいの... 」 $ 
```

# まとめ
いかがでしたか？
プロンプトにご主人様とかマスターとか言わせている方々ならわかってくれるはず
【Java】２つのListから１つの配列リストへ

# はじめに

積み上げ棒グラフを作るのにタイトルのことをやる必要があるので検証しました。
最初はクラス固定で実装しましたが、ジェネリクスを使って汎用的にしようとしたら躓いたので忘れないようにメモ。

# 環境

java8

# ソース

２つのIntegerのリストからInteger配列の１つのリストへ
２つのリストはサイズが同じ前提です。

```java:Integer版
private List<Integer[]> convertTwoListToArray1(List<Integer> list1, List<Integer> list2) {
    List<Integer[]> list = new ArrayList<>();
    for (int i = 0; i < list1.size(); i++) {
        list.add(new Integer[] { list1.get(i), list2.get(i) });
    }
    return list;
}
```
　　
　　
汎用的にしようとしたジェネリクス版がこちら

```java:ジェネリクス版
@SuppressWarnings("unchecked")
private <T> List<T[]> convertTwoListToArray2(List<T> list1, List<T> list2) {
    List<T[]> list = new ArrayList<>();
    for (int i = 0; i < list1.size(); i++) {
        Object[] tmpArray = new Object[] { list1.get(i), list2.get(i) };
        list.add((T[]) tmpArray);
    }
    return list;
}
```

# 最後に

ジェネリクスの配列が作れなくて躓いたけど、Objectの配列をキャストすることで解決しました。

以上
TypeScript で Array.prototype.filter を推論したい

Array.prototype.filter の型推論は、条件式が複雑な場合があるため、配列の要素を絞り込むことができません。

```typescript
const n = [0, null].filter(item => item !== null)
// const n: (number | null)[]
console.log(n) // [0]
// number[] であって欲しい。。。
```

この程度の単純なプリミティブのフィルタリングならば、出来そうな予感がしたので試してみました。Array.prototype.filter の推論ではありませんが、Assertion 付き関数でそれっぽくなりました。実処理は typeof 演算子で比較しているので、プリミティブ型が一致する場合のフィルタリングです。

```typescript
type Primitive = boolean | number | string | symbol | bigint | null | undefined
type Unwrap<T> = T extends { [K in keyof T]: infer U } ? U : never
function filter<T extends Primitive[], U extends Primitive>(array: T, diff: U) {
  return array.filter(item => typeof item !== typeof diff) as Exclude<Unwrap<T>, U>[]
}
const n1 = filter([0, null], null)
// const n1: number[]
console.log(n1) // [0]

const n2 = filter([0, null], 0)
// const n2: null[]
console.log(n2) // [null]

const n3 = filter([0, false, null], 0)
// const n3: (boolean | null)[]
console.log(n3) // [false, null]

const n4 = filter([0, false, null], 1) // number型が絞られる
// const n4: (boolean | null)[]
console.log(n4) // [false, null]

const n5 = filter(filter(filter([0, false, null, undefined], undefined), null), false)
// const n5: number[]
console.log(n5) // [0]
```

# TypeScript 3.4 の場合

const assertion を利用することで、Tuple 宣言が楽です。
今度は typeof の比較でなくても良いため、実装と推論が近づきます。

```typescript
function filter<T extends readonly Primitive[], U extends Primitive>(array: T, diff: U) {
  return array.filter(item => item !== diff) as Exclude<Unwrap<T>, U>[]
}
const n1 = filter([0, 1, 2] as const, 0)
// const n1: (1 | 2)[]
console.log(n1) // [1, 2]

const n2 = filter([0, 1, 2] as const, 1)
// const n1: (0 | 2)[]
console.log(n2) // [0, 2]

const n3 = filter([0, 1, 2] as const, 2)
// const n1: (0 | 1)[]
console.log(n3) // [0, 1]
```
【Android】dependenciesをIDE補完で記述する

# はじめに
Androidアプリのdependenciesを下記のように記述していないでしょうか？

```build.gradle
...

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.android.support:appcompat-v7:27.1.1'
    implementation 'com.android.support.constraint:constraint-layout:1.1.3'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}
```

このように記述すると、バージョン変更時に一つずつ編集しなければならなかったり、そもそも可読性が低いように感じます。
そこで、buildSrcでこれらを保持する方法が良さそうだったのでメモしておきます。

参考：
[Kotlin + buildSrc for Better Gradle Dependency Management](https://handstandsam.com/2018/02/11/kotlin-buildsrc-for-better-gradle-dependency-management/)

# やり方
### 1. buildSrcフォルダを作成
モジュールと同じようにプロジェクトルートに`buildSrc`という名前のフォルダを作成します。
<img width="212" src="https://qiita-image-store.s3.amazonaws.com/0/126115/e61ea7b4-b1e1-ebda-c226-d2f9264acf0f.png">

### 2. build.gradle.ktsを作成
作成した`buildSrc`フォルダに`build.gradle.kts`という名前のkotlin-scriptファイルを作成します。
この段階ではまだ何も記述しなくていいです。
<img width="230" src="https://qiita-image-store.s3.amazonaws.com/0/126115/c59ee180-e0d3-faab-cba6-be6504a66600.png">

### 3. Sync Gradle !
`sync gradle`しましょう。`buildSrc`内に以下のようなファイルが生成されれば成功です。
<img width="282" src="https://qiita-image-store.s3.amazonaws.com/0/126115/0fa9319c-c538-93a2-61dc-7c3f762fa505.png">

### 4. dslを記述
`build.gradle.kts`に以下を記述して`sync gradle`しましょう。

```build.gradle.kts
plugins {
    `kotlin-dsl`
}

repositories {
    jcenter()
}
```

### 5. Dependencyを保持するオブジェクトクラスを作成
`buildSrc`内にsrc/main/java/Dependencies.ktを作成します。
<img width="413" src="https://qiita-image-store.s3.amazonaws.com/0/126115/409dbd98-8dd7-991a-6b07-fd4df7d6f2b6.png">
一旦今のDependencyを全て保持させておきたいので、下記のようにします。

```Dependencies.kt
object Dependencies {
    object Version {
        val kotlin = "1.2.71"
        val support = "28.0.0"
        val constraint = "1.1.3"
        val runner = "1.0.2"
        val espresso = "3.0.2"
    }

    val kotlinLib = "org.jetbrains.kotlin:kotlin-stdlib-jdk7:${Version.kotlin}"
    val appCompat = "com.android.support:appcompat-v7:${Version.support}"
    val constraintLayout = "com.android.support.constraint:constraint-layout:${Version.constraint}"
    val junit = "junit:junit:4.12"
    val testRunner = "com.android.support.test:runner:${Version.runner}"
    val espressoCore = "com.android.support.test.espresso:espresso-core:${Version.espresso}"
}
```

### 6. 実際に使う
これで使えるようになりました！ 実際に`build.gradle`に適用しましょう！

```build.gradle
...

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation Dependencies.kotlinLib
    implementation Dependencies.appCompat
    implementation Dependencies.constraintLayout
    testImplementation Dependencies.junit
    androidTestImplementation Dependencies.testRunner
    androidTestImplementation Dependencies.espressoCore
}
```

以前と比べて何を読み込んでいるか分かりやすくなり、IDE補完が効くので編集もしやすくなったかと思います。

# サンプル
今回のプロジェクトをGitHubに上げたので、よければ参考にしてください。
https://github.com/TaigaNatto/BuildSorceSample
RPAっぽいノンプログラミングツール(vbs生成)を作ってみた。

## はじめに
今まで、VBとかで業務ツールの開発とかばっかりやってきました。
最近、Webアプリに関わることをちょっと仕事でやる機会に恵まれまして、なんか作れそうじゃね？って思ってここ数カ月コツコツと組み上げてWebツールなんか作ってみました。
一旦、満足いくところまで機能開発が進んだのでお披露目しようと思います。

## ノンプログラミングツール(RPA?)
開発言語の習得が難しい人でも、概念さえ掴んでデータフローが書ければ、それをプログラムとしてビルドして実行できる様にしますよっていうアプリのこと。
最近は、こういった物に独自の付加価値を付けた物がRPAソリューションとして巷で注目を集めているようです。
自分は、もともとVB系が得意だったのでWindows向けにWebツールとしてRPAもどきを作ってみました。
あんまり難しいこと考えず、vbsならテキストベースでコンパイルとかもいらないし保存して実行すりゃ大概の処理は自動化できそうだったのでチャレンジしてみた次第です。


## 概要
[vbsめーかー](https://yizm.work/rpa_vbs_maker/)
↓↓↓　こんなサイトです。
![vbs_maker.jpg](https://qiita-image-store.s3.amazonaws.com/0/360097/70655d54-5fde-dc1a-24aa-9f848332c9f6.jpeg)
### ① 条件分岐・アクション
* このエリアのリンクをクリックすると処理オプションのダイアログが出てきます。

![vbs_maker_dialog.png](https://qiita-image-store.s3.amazonaws.com/0/360097/dab1a172-085d-e06f-0f28-b0f423e2c0c7.png)

* 「処理名」は編集できる様になっていて、「確定」ボタンを押すとここで指定した処理名でボックスが生成されて③のタブエリアにステージが追加されます。
* 引数のところは、だいたい「値を指定」か「変数で指定」で選べる様になっています。
* 細かいアクションの作り込みは別途紹介することにします。今日は概要だけ。

### ② 変数一覧
![vbs_maker_var.png](https://qiita-image-store.s3.amazonaws.com/0/360097/1c19f3c8-2b09-6c34-3dfa-0bff0647257f.png)

* ここに定義された変数は、①の「変数を指定」プルダウンのリストに自動追加され、処理の中で引数として使えるようになります。
* ①で追加したステージで使うことになった変数が自動的に一覧に登録されます。
* (＋)のボタンを押すと空の行が挿入されて、ダブルクリックまたは、クリック選択で太枠にしてもう一度クリックするとセルが編集できて、独自に変数を定義できます。
* ２列目の「初期値」に文字を設定しておくと、その変数の初期値としてデータを扱うことができます。
* 編集していくうちに不要になった変数は、セルを選択状態にして(-)で削除することもできます。
* アクションや条件分岐の引数で使われる編集が初期化前に参照して使おうとすると、保存前に構文チェックが入りお知らせしてくれます。（やさしー！）

### ③ メインフロー
![vbs_maker_main.png](https://qiita-image-store.s3.amazonaws.com/0/360097/e8f6e815-c2a7-6f2b-ff51-60cce3177964.png)

* ここに①で確定したアクションなどが追加されていきますが、アイテムはドラッグ＆ドロップで並べ替えができるようになっています。
* 分岐処理の場合は、(開始)(分岐)(終了)といった複数のボックスが自動生成されるので、並べ替えをして条件に見合った処理だけが実行されるように整理して下さい。
* 追加されたアクションには、右側に(×)ボタンがついており、クリックするとアクションをフローから消すことができます。
* ダブルクリック または クリックしてボックスを選択状態にしてからもう一度クリックすると、①で編集したオプション画面を再表示することができ、処理オプションを再編集することができます。

### ④ 入出力ボタン
![vbs_maker_inout.png](https://qiita-image-store.s3.amazonaws.com/0/360097/67165506-88d9-a71b-5c6c-61eedb04ed28.png)

* 「プレビューする」を押すとダイアログに保存イメージが表示されます。作ったフローをvbsに変換した時にどんなソースになるのか、事前に確認することができます。（やさしーー！！）
![vbs_maker_prev.png](https://qiita-image-store.s3.amazonaws.com/0/360097/6d099008-5ff6-63d4-54de-516ce1340b48.png)


* 「保存する」でフローをvbsに変換したファイルをテキスト化してローカルにダウンロード保存できます。
* このサイトで生成したvbsファイルを「ファイルを選択」で取り込むと、フローと変数一覧が画面に復元され、再編集できるようになります。（べんりーーー♪）
* ※ 再編集の際は、画面で作業途中のフローは破棄されますのでご注意下さい。

## おことわり
GUIベースでスクリプトを組めるようにして保存できる様にしたWebツールですが、どういった処理を組むのかは使う方次第です。
作ったスクリプトで間違って大切なデータを消してしまったとか言われても責任は持てませんのでご理解の上、ご利用頂きたく思います。

## 今後について
ひとまず、ここまでできたらいーなーと想像したところまで機能を作った。という状態で、レイアウトとか拙い部分は多いと思います。

アドバイスは優しめにお願いしますね。。。

ですが、ちょこちょことファンクションを増やしていけば、なんやかんや結構使えるWebツールになるんじゃないかなーと思っているので、今後も育てて行こうと思います。
温かく見守って下されば幸いです。
微々たる爪痕を残したいという動機でサイトを作った話

# はじめに

初めてWEBサイトを公開してみたので、やったことや動機、感想など色々と書いていこうかと思います。
モチベーションの低い人間がチャレンジ精神で開発したものですので、優しい目で見てください。お願いします。

# 前段階
## 動機
自分用のアプリ開発はちょこちょことしていて開発ライフをエンジョイしていたのですが、先日漠然と自分の将来について感じた不安に対して思ったのです。

「このまま自分の存在がなくなったら何が残るのだろう」

何にもないなら何か作ってしまえ。と勢いで開発の下準備を始めることにしました。
自分がこのコンピュータの世界で生きていた爪痕をどこかに残しておきたかったのです。

## とりあえず勉強
何か開発すると決めたはいいけど、何の言語で開発をするか決めていなかったので、ネットで面白そうな技術書を探していたら、PHPの面白そうな本を見つけたので、すぐ本屋へ。(PHPは少し勉強していて業務でも短いですが開発経験があったので)
この本屋に行ったのが去年の10月ごろ。

本を買ってその日から約1か月の間、近所の公園に散歩したついでに読み耽っていました。
PHPの基礎からフレームワークの見本など色々書いてある本で、勉強になりました。

## アイデア
勉強しながら、ついでに空いた時間でどんなサイトを立ち上げるかアイデアを出していました。
あれもいい、これもいいと思いながらも、開発中に必ずモチベーションが無くなる時期があると思っていたので、つまづいて転んでしまうことを一番に嫌い、技術的難易度の高いものはドンドン排除することにしていました。

出したアイデアとしては、

- ランダムマッチングチャット
- 文字で遊ぶブログ
- 何か一つのグッズだけの画像を収集する
- 人を苦しめるお金

などなどをテーマに。

この中で「ほどよく難しくて」「ほどよく時間がかかりそうで」「ほどよく自分が楽しめる」「ほどよく継続できそうな」ものを選ぶことにしました。

悩んだ挙句、選んだものとしては「文字で遊ぶブログ」ということに。~~単純に自分がやりたいを重視した~~
初めてにしては、ちょっと難易度高いのかとざっくりイメージしていました。

# メイン
## 設計
アイデアも決まって次は全体的なイメージを決めるために、設計をすることに。

簡単な要件定義や概要を箇条書きにして、さらに事細かくアイデアを出すことにしました。
合わせて、画面の洗い出しと画面設計、テーブル設計も。

ですが、10日ほどで時間かかりすぎ！となってしまって「細かく」を撤廃することにしました。
画面設計は抽象的に一部を決めて、それを元に他のページを作成することにしました。
テーブル設計も開発中にカラムの追加、変更することは、常だと思うぐらいガバガバなので現時点で必要なもののみに。

画面を基に工数を計算もしましたが、だいだい3～4かげ...
ちょっと絶望したので見て見ぬふりをしました。

## 開発
基本的には、フレームワークを元に開発を行いましたが、JSやCSSで使用したものについて記述しようかと思います。

### フレームワーク
フレームワークの選定をすることに。
某フレームワークのようにセキュリティの問題が発覚した時が怖いので、のせないことにしたいと思います。

選定基準で一番大きかったのは、仕事関係でとあるフレームワークを扱う案件を見聞きする機会が多かったということです。

### 入れたもの
CSSには自信がないので、CSSのフレームワークを導入することにしました。
単刀直入に、bootstrapです。
これも初体験なのでよく分からず、調べながら感覚を頼りに。

JSは、jQuery、popper、code-prettify、js.cookieを使っています。

- jQuery
 - よく知られているJSを書きやすくするためのライブラリだと思いますが、これは頻繁に使ってるので多少なりとも。
- popper
 - bootstrapで必要になるため入れました。
- code-prettify
 - コードを綺麗に見せてくれるライブラリで入れています。
- js.cookie
 - JSでクッキーを操作しやすくなるために入れています。

## 結果
開発には、2か月ほどかかりました。
環境周りの構築は、2週間近く。

勉強期間を含めると3ヵ月以上のめりこむ結果となりました(まだ終わったわけではないですが)

人に使ってもらうということに多少恥ずかしいという感情があるので、集客はのんびりと、これからしようと思っています。SEO分からないので勉強します笑

現時点の自己評価としては、50点ぐらいです。CSSはまだ改善したいですし、機能もまだまだ追加したいです。

# 感想
Twitterでご存知の方もいらっしゃいますが、体調があまり良い方ではないので、ゆっくりまったりマイペースを意識していました。ですが、のめり込みすぎてほとんどSNSなどはしていなかったですし、生活のいろんなことが疎かになってしまう開発期間でした。私の性格が関係してますがこれは良くない。

よく個人開発の問題点となるモチベーション。色々ブログ拝見しました。
ブログを読んでいると、モチベーションを維持するためにドメインやサーバーなどお金がかかるものは、開発すぐにやってしまえというのが多かったですが、私は公開する直前にすることに決めていました。気持ちで焦りたくなかったですし、そこまで追い詰めるつもりもなかったです。人それぞれによるところだと割り切りました。

これをしておいて良かったというのは、紙に設計、アイデア、開発期間の目標などをメモとして書いていたことだと思います。○○したい、○○の方がいいなども、適当に書いてます。人に見せられるものではないです笑
このメモは常にPCの前に置いてて、少しの時間があるとすぐ追記できますし、必ず目に入るのでモチベーションの継続に大きな役割を果たしました。

作るサービスに名前を初期段階からつけておくというのもすごくいい効果があるとも思えました。口癖のように名前を呼んでました笑

開発を続けていたら、キリがないのでどこかで公開すると決めて置くことも必要なのかなと学べました。完成から公開ということを考えているとかなり後になると思うので、個人開発だとモチベーションが付いてこない気がします。

それとまだまだ技術的に拙いことは、痛感しました。開発の半分以上は分からなくて調べるが多かったです。特につまづいたのは、画像をJSで小さくしてサーバーに送信するという機能は大変でした。あってもなくても良かったのかなと思いましたが、チャレンジの気持ちで挑むことに。

これからもまだ開発をする予定ですが、とりあえず公開できるまで来たので、一区切りということでここでお話を公開することにしました。

ここまで読んでくださってありがとうございました。

# 開発したサイト
https://watatsuku.com
過去の時間を読みやすくする

`2019/02/14`みたいな具体的な日付を見せられても
直感的に現時点からどのくらい離れた時間なのかわかりにくいので、
`x日前`とか`x秒前`みたいに変換するクラスを書いた
とりあえずアプリで使う用に書いたので汎用化はそのうち

# 実装

```dart
import 'package:meta/meta.dart';
import 'package:intl/intl.dart';

class ElapsedTime {
  DateFormat formatter1 = DateFormat('yyyy/MM/dd');
  DateFormat formatter2 = DateFormat('MM/dd');
  ElapsedTime({String format1 = null, String format2 = null}){
    if (format1 != null) {
      this.formatter1 = DateFormat(format1);
    }
    if (format2 != null) {
      this.formatter2 = DateFormat(format2);
    }
  }

  String fromAt({@required DateTime from, @required DateTime at}) {
    final sec = from.difference(at).inSeconds;
    if (sec >= 60 * 60 * 24 * 30 * 12) {
      return formatter1.format(from);
    } else if (sec >= 60 * 60 * 24 * 30) {
      return formatter2.format(from);
    } else {
      return _ElapsedTimeDuration(seconds: sec).tostr();
    }
  }

  String fromNow({@required DateTime at}){
    return fromAt(from: DateTime.now(), at: at);
  }
}

class _ElapsedTimeDuration extends Duration{
  _ElapsedTimeDuration({int seconds}): super(seconds: seconds);
  String tostr() {
    final sec = this.inSeconds;
    if (sec >= 60 * 60 * 24) {
      return '${this.inDays.toString()}日前';
    } else if (sec >= 60 * 60) {
      return '${this.inHours.toString()}時間前';
    } else if (sec >= 60) {
      return '${this.inMinutes.toString()}分前';
    } else {
      return '$sec秒前';
    }
  }
}
```

# 使い方
```dart
var formatter = ElapsedTime();
formatter.fromAt(from: DateTime(2019,2,14,0,0,3), at: DateTime(2019,2,14,0,0,0)); // => "3秒前"
formatter.fromAt(from: DateTime(2019,2,14,0,3,0), at: DateTime(2019,2,14,0,0,0)); // => "3分前"
formatter.fromAt(from: DateTime(2019,2,14,3,0,0), at: DateTime(2019,2,14,0,0,0)); // => "3時間前"
formatter.fromAt(from: DateTime(2019,2,17,0,0,0), at: DateTime(2019,2,14,0,0,0)); // => "3日前"

var formatter = ElapsedTime(format1: 'yy-MM-dd', format2: 'MM-dd H');
formatter.fromAt(from: DateTime(2019,4,17,0,0,0), at: DateTime(2019,2,14,0,0,0)); // => "02-17 0"
formatter.fromAt(from: DateTime(2020,2,17,0,0,0), at: DateTime(2019,2,14,0,0,0)); // => "20-02-14"
```

# 今後の課題
`a month ago / 1 month ago / 2 months ago`とか考えると面倒だったので今回はスルーしたけどi18n対応したい。
現状だと未来の日付だと `-3日前`等になるので `x日後`系にも対応したい。

# リポジトリ
[github](https://github.com/rnitta/elapsed_time)
[pub](https://pub.dartlang.org/packages/elapsed_time/)
私のWSL環境構築

# 概要
私のWSL環境を構築するためのメモです。

# 手順
## 1. WSLインストール
こちらの内容はそのまま、Microsoft StoreからUbuntuを検索してインストールします

## 2. wsltty適応
インストール終了後、wslttyをインストールします。
wslttyは、「mintty」をベースに開発された端末エミュレータ－です。
細かい内容は省きますが、カラースキームなどが設定できたり、気の所為かもしれませんが、描画速度もデフォルトのターミナルよりは早い気がします。

インストール手順は、下記のURLからインストーラをダウンロードしインストールするだけです。
[「mintty/wsltty」のダウンロードページ（GitHub）](https://github.com/mintty/wsltty/releases)

## 3. homebrewのインストール
2019年2月2日から正式にサポートが開始されたhomebrewをインストールします。
ぶっちゃけaptでも十分なのですが、Macを使用している際はhomebrewを使用していることもあり、今後に期待ということでインストールします。

インストール手順は以下のコマンドを実行します。

```bash
$ test -d ~/.linuxbrew && eval $(~/.linuxbrew/bin/brew shellenv)
$ test -d /home/linuxbrew/.linuxbrew && eval $(/home/linuxbrew/.linuxbrew/bin/brew shellenv)
$ test -r ~/.bash_profile && echo "eval \$($(brew --prefix)/bin/brew shellenv)" >>~/.bash_profile
$ echo "eval \$($(brew --prefix)/bin/brew shellenv)" >>~/.profile
$ sh -c "$(curl -fsSL https://raw.githubusercontent.com/Linuxbrew/install/master/install.sh)"
```

## 4. zshのインストール
zshをインストールしてログインシェルを変更します。
zshは補完が強力なので非常に使いやすい。
最近、筆者の周りではfishを使っている人が多いですが、私は学生時代からzsh派です。
aptからでもインストール可能ですが、先程homebrewをインストールしたのでそちらからインストールしてみましょう。

```bash
$ brew install zsh
$ command -v zsh | sudo tee -a /etc/shells
$ sudo chsh -s "$(command -v zsh)" "${USER}"
$ touch ~/.zshrc
$ echo "setopt no_beep" >> ~/.zshrc
```

インストールとログインシェルの変更が完了したら、一度shellを再起動してみましょう。


## 5. openコマンド
私がMacでターミナルを使用するときに最も便利だと思うコマンドのopenコマンドをWSLからでも使えるようにします。
.zshrcに以下のaliasを追加します。

```vim
alias open="cmd.exe /c start"
```

こちらのaliasではWSL固有のファイルシステム上のファイルは開くことはできませんが、やはり便利です。


# まとめ
今後も有用なものがあれば追記していこうと思います。
もし、おすすめがあればお教えいただけると嬉しいです。
もっと良くなれWSL！

# おまけ(ぼやき)
docker周りが、特にdocker-composeがもっと使いやすくなってくれたらいいな…
あと、応答速度が早くなってほしいですね（aptもですがhomebrewの処理が非常に遅い…）
お願いしますMicrosoft様

# 参考文献
- [WSLのコンソールを便利で高機能な「wsltty」に置き換える](https://www.atmarkit.co.jp/ait/articles/1812/13/news031.html)
- [Linuxbrew](https://docs.brew.sh/Linuxbrew)
- [Mac YosemiteのTerminalのshellをzshにする](https://qiita.com/kpkpkp/items/c9d0345e5bbfffa71a15)
- [WSLでmacのopenコマンドみたいなこと](https://qiita.com/chez_sugi/items/603a0ba8016aaae9ef98)
パスカルの三角形（colab再帰版＋メモ化で高速化）

#はじめに
 フラクタル図形が表れるパスカルの三角形（絵文字で５０段分）をブラウザ上（Colaboratory）上で描画させてみました。

[ブラウザ（colab）上で描画を試したい場合はこちらから](https://colab.research.google.com/github/zaq9/pascal/blob/master/pascal.ipynb)

↓生成されるフラクタル図形（２０段分）
![image.png](https://qiita-image-store.s3.amazonaws.com/0/351020/28fd503b-6804-ea43-e90a-04a71dc8a866.png)




##参考：パスカルの三角形とは

>>パスカルの三角形（パスカルのさんかくけい、英: Pascal's triangle）は、二項展開における係数を三角形状に並べたものである ( [wikipedia](https://ja.wikipedia.org/wiki/%E3%83%91%E3%82%B9%E3%82%AB%E3%83%AB%E3%81%AE%E4%B8%89%E8%A7%92%E5%BD%A2) ）

>>この三角形の作り方は単純なルールに基づいている。まず最上段に 1 を配置する。それより下の行はその位置の右上の数と左上の数の和を配置する。例えば、5段目の左から2番目には、左上の 1 と右上の 3 の合計である 4 が入る。このようにして数を並べると、上から n 段目、左から k 番目の数は、二項係数 

>> ![image.png](https://qiita-image-store.s3.amazonaws.com/0/351020/56cb1534-59c8-6ade-9426-0f0c359f2953.png)

>>に等しい。これは、パスカルによって示された以下の式に基づいている。
負でない整数 n ≥ k に対して 

>> ![image.png](https://qiita-image-store.s3.amazonaws.com/0/351020/2e91192e-3725-93cd-8932-ff7d49aa4314.png)
>> が成り立つ

##描画用のソースコード（＆簡単な流れ）

再帰を使うとパスカルの三角形の漸化式はスムーズに書けます。

```python
def c(n,k): 
  return 1 if(k<=0 or n<=k) else c(n-1, k-1) + c(n-1, k)
```

テストとして上記の式を（リスト形式で）１０段分表示。

```python
for i in range(10):
  print([c(i,j) for j in range(i+1)])

'''OUTPUT:
[1]
[1, 1]
[1, 2, 1]
[1, 3, 3, 1]
[1, 4, 6, 4, 1]
[1, 5, 10, 10, 5, 1]
[1, 6, 15, 20, 15, 6, 1]
[1, 7, 21, 35, 35, 21, 7, 1]
[1, 8, 28, 56, 70, 56, 28, 8, 1]
[1, 9, 36, 84, 126, 126, 84, 36, 9, 1]
'''
```

少しだけアレンジし、剰余利用＋文字列でリスト展開表示

```python

def c(n,k): 
  return 1 if(k<=0 or n<=k) else ( c(n-1, k-1) + c(n-1, k) ) %4

for i in range(10):
  print(' '.join([ str( c(i,j)) for j in range(i+1) ] ))


'''OUTPUT:
1
1 1
1 2 1
1 3 3 1
1 0 2 0 1
1 1 2 2 1 1
1 2 3 0 3 2 1
1 3 1 3 3 1 3 1
1 0 0 0 2 0 0 0 1
1 1 0 0 2 2 0 0 1 1
'''
```

絵文字を使ったアレンジをすると…（遅いので２０段まで、結果はタイトル下の画像）

```python

e = ['🍈','🍎','🍇','🍊']
for i in range(20):
  print(' '.join([ str(e[c(i,j)%4]) for j in range(i+1)]))

```

##メモ化で簡単に超高速化
同じ計算が繰り返される再帰計算の場合、「メモ化」を行うと超高速化できます。
方法は一行追加するのみです。



```python

#50段ブラウザで描画させるソースコード（メモ化高速版）

from functools import lru_cache

@lru_cache(maxsize=1000)
def c(n,k): 
  return 1 if(k<=0 or n<=k) else ( c(n-1, k-1) + c(n-1, k) ) %4


e = ['🍈','🍎','🍇','🍊']
for i in range(50):
  print(' '.join([ str(e[c(i,j)%4]) for j in range(i+1)]))
```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/351020/4a0ebb0a-7cc4-344a-a8ae-eb75eb7ce298.png)


#参考:
- [１行追加するだけの超お手軽な高速化その１　メモ化](https://qiita.com/alchemist/items/c75174c41b0bcd31ecc6)

- [パスカルの三角形とフラクタル](https://qiita.com/YuukiToriyama/items/d5a3a4635640a860f0a7) (Ruby＋絵文字利用）

- [パスカルの三角形（wikipedia）](https://ja.wikipedia.org/wiki/%E3%83%91%E3%82%B9%E3%82%AB%E3%83%AB%E3%81%AE%E4%B8%89%E8%A7%92%E5%BD%A2)
機械学習1 scikit-learn mnistのデータを画面に表示

初投稿記事です。機械学習について知ったこと。
サンプルデータの中身を見てみます。
まずは取得します。

```python:mnist.py
# サンプル画像データのロード
mnist = datasets.fetch_mldata('MNIST original',data_home='image/')
```
mnistオブジェクトは辞書型に似たBunchクラスのオブジェクトでkeyとvalueを持つようです。
keyを見てみます。

```python
print('データのkeys:',mnist.keys())
# 結果
# データのkeys: dict_keys(['DESCR', 'COL_NAMES', 'target', 'data'])
```

targetには数字が入っていました。数字なので0～9がある。
dataには学習すべきデータ。
画像データの数は70000枚。

```python
print('データの中身：', mnist.data[20000])
print('データのラベル',mnist.target[20000])
# 結果
# (配列のため省略)
# データのラベル 3.0
```
機械学習の道が始まる

[ドキュメント](https://scikit-learn.org/stable/modules/generated/sklearn.datasets.fetch_mldata.html)
【データ分析、Kaggle入門】House Pricesの日本語チュートリアル記事4選

Kaggleの練習問題の1つである、House Pricesの日本語チュートリアルの有名どころをいくつか試してみたので、分析、スコアについてまとめてみました。

普段はアプリエンジニアをしており、データ分析に関しては入門者です😇
興味があり下記講座を受講したりしてデータ分析の勉強していました。
[【ゼロから始めるデータ分析】 ビジネスケースで学ぶPythonデータサイエンス入門](https://www.udemy.com/optworks_1/)
一通り基礎がわかったので、より実践的なスキルを身につけようと思いKaggleの練習問題のチュートリアルをやっていたのですが、素晴らしい記事が多かったのでまとめてみました。

入門者の参考になれば幸いです。


## 分析してみた記事まとめ

|                                          | [Kaggle 日本語チュートリアル:Prediction(予測) House Prices](https://www.kaggle.com/katotaka/kaggle-prediction-house-prices) | [Kaggleの練習問題（Regression）を解いてKagglerになる ](https://qiita.com/tags/python) | [不動産価格を機械学習で予測するKaggleに挑戦する [ベンチマーク編]](http://ochearno.net/kaggle_house_prices_benchmark-2) | [不動産価格を機械学習で予測するKaggleに挑戦する [発展編1:上位20%]](http://ochearno.net/house_prices_stacking-2) |
| ---------------------------------------- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ |
| 工夫（データの前処理）                   | ・外れ値を除く                                               | ・カテゴリ変数のエンコード（Label Encoder）<br />・欠損値の補完（欠損が多いものは列ごと削除、それ以外は中央値で補完）<br />・Feature Engineering（'...SF'をまとめたFeatureの作成）<br />・対数変換<br />・ランダムフォレストによるFeature重要度の可視化<br />・外れ値を除く | ・欠損値の補完（Data DescriptionよりNAやNoNで補完、欠損値が少ないものは最頻値で補完）<br />・カテゴリ変数のエンコード（One Hot Encoding） | ・カテゴリ変数のエンコード（One Hot Encoding）<br />・Feature Engineering（足したり、割ったり2乗したり）<br />・外れ値を除く（多変量の外れ値検知（Isolation Forest）法を使用） |
| 分析方法                                 | ・単回帰分析<br />・重回帰分析（変数2つ）                    | ・Stacking-Emsemble model<br />(XGBoost, Neural Network, Support Vector Regressor) | ・ラッソ回帰<br />・ランダムフォレスト<br />・SVR            | ・Stacking-Emsemble model<br />（SVR、xgboost、lightBGM）    |
| スコア（順位は目安です（2019/02 時点）） | 0.28783<br />（3982位/4364）<br />（単回帰分析によるもの）   | 0.12848<br />（1636位/4294）                                 | 0.15052<br />（2800位/4294）                                 | 0.12034<br />（1023位/4294）                                 |
| 難易度                                   | ★☆☆☆☆                                                        | ★★★☆☆                                                        | ★★☆☆☆                                                        | ★★★★☆                                                        |
django-allauthのテンプレートファイルをカスタマイズする手順

#　概要

django-allauth のテンプレートカスタマイズでやや手間取った（[公式ドキュメント](https://django-allauth.readthedocs.io/en/latest/templates.html)の記述だとカスタマイズ可能なのはわかるが具体的な設定や手順がわからなかった）ので記録しておきます。

- Django 2.1.4
- Python 3.6.7
- django-allauth 0.38.0


# やりたいこと

- allauthに用意されている画面を綺麗にしたい

django-authは認証機能を実現するライブラリなのでインストール時についてくる画面(ログイン、サインアップ等)は必要最小限になっています。例えば装飾は一切施されていません。（それぞれのシステムごとにカスタマイズすることが前提）　例えば以下はログイン画面ですが、さすがにこれでリリースはできないのでカスタマイズが必要です。

![](https://i.gyazo.com/7bd4420cd702176c2ea007a0e091c807.png)

# 手順

## 概要

1. allauthのテンプレートファイル群を自身のプロジェクトディレクトリ直下にコピーする。
    2. (2020.12.04 コメント欄より引用)『カスタマイズしたいテンプレートファイルだけをtemplates/accountの下に配置すればカスタマイズできる。』そうです!
2. コピーしたテンプレートファイルが利用されるようにsettings.pyのTEMPLATES定義でパスを通す
3. カスタマイズしたいテンプレートファイルを修正する

## allauthのテンプレートファイル群を自身のプロジェクトフォルダ直下にコピーする。

- まず自身のプロジェクトディレクトリ直下に templates/allauth を作成します。
- pipでインストールしている場合、<パッケージDIR（例えば/home/xxxx/.local/lib/python3.6）>/site-packages/allauthの下にtemplatesディレクトリがあり、その下に**account**,**openid**,**socialaccount**があるので、カスタマイズしたいものをtemplates/allauthディレクトリにコピーします。以下はaccountディレクトリをコピーした状態です。

![](https://i.gyazo.com/8d60cff3b04818eef424f9532147d225.png)

## コピーしたテンプレートファイルが利用されるようにsettings.pyのTEMPLATES定義でパスを通す

setting.pyのTEMPLATESのDIRSに★部分を追加します。

```
TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [
            os.path.join(BASE_DIR, 'templates'),
            ★os.path.join(BASE_DIR, 'templates', 'allauth')★
          ],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]
```
[テンプレート(公式ドキュメント)の詳細はこちら](https://docs.djangoproject.com/ja/2.1/topics/templates/)

## カスタマイズしたいテンプレートファイルを修正する

例えば、login.html を修正します。プロジェクトを実行してブラウザのアドレスバーで **localhost:8000/account/login** を入力して修正が反映されていれば上書き成功です。あとはお好みで。

```
・・・省略・・・

{% block content %}

<h1>{% trans "Sign In" %}</h1>

<h3>SUCCESS!!</h3>　　★ここ★
{% get_providers as socialaccount_providers %}

{% if socialaccount_providers %}
<p>{% blocktrans with site.name as site_name %}Please sign in with one

・・・省略・・・

```

![](https://i.gyazo.com/d66685a4a4b346802b4055810f278a44.png)

以上です。
Windows 10 Pro x64 + Python3 で selenium + chromedriver でFessの検索画面を操作してみる

#目的
ドロップダウンの操作もかねてFessの検索画面を操作してみる
Freeは[ローカルで動かしているもの](https://qiita.com/tabizou/items/b687e02bad188b032306)を使用
※公開されているデモ・サーバーはあるんだろうか？
※TODO：ローカルファイルもブラウザで開く気がしたんだけどDLになる
##サンプルコード
対象とするhtmlの抜粋
<pre>
&lt;h3 id="searchOptionsLabel"&gt;
	検索オプション
&lt;/h3
ドロップダウン
&lt;fieldset class="form-group"&gt;
	&lt;label for="contentNum"&gt;表示件数&lt;/label&gt;
	&lt;select name="num" id="numSearchOption" class="form-control"&gt;&lt;option value="10"&gt;
			- 表示件数 -
		&lt;/option&gt;
		&lt;option value="10" selected="selected"&gt;10&lt;/option&gt;
		&lt;option value="20"&gt;20&lt;/option&gt;
		&lt;option value="30"&gt;30&lt;/option&gt;
		&lt;option value="40"&gt;40&lt;/option&gt;
		&lt;option value="50"&gt;50&lt;/option&gt;
		&lt;option value="100"&gt;100&lt;/option&gt;&lt;/select&gt;
&lt;/fieldset&gt;
検索ワードの入力
&lt;div class="clearfix"&gt;
	&lt;div class="mx-auto col-10 col-sm-8 col-md-8 col-lg-6"&gt;
		&lt;input type="text" name="q" maxlength="1000" size="50" value="" 
		id="contentQuery" class="query form-control center-block"
		autocomplete="off"&gt;
	&lt;/div&gt;
&lt;/div&gt;
検索ボタンクリック
&lt;button type="submit" name="search" id="searchButton"
	class="btn btn-primary"&gt;
	&lt;i class="fa fa-search"&gt;&lt;/i&gt;
	検索
&lt;/button&gt;
検索結果
&lt;a class="link"
     href="file://var/export/web/fess/pgsql11/runtime.html"
     data-uri="file://var/export/web/fess/pgsql11/runtime.html"
	 data-id="1d87eea3d06a44beb5301018894d24f7" data-order="0"&gt;
	runtime.html&lt;/a&gt;
</pre>
コード

```python
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait, Select
from selenium.webdriver.support import expected_conditions as EC

driver = webdriver.Chrome('C:\\Dev\\tool\\webdriver\\chromedriver.exe')  
driver.get('http://xxx.xxx.xxx.xxx:8088/')
try:
    # 検索オプション 画面の表示
    element = WebDriverWait(driver, 10).until(
        EC.presence_of_element_located((By.ID, 'searchOptionsButton'))
    )
    element.click()

    # 表示件数の選択
    elms = WebDriverWait(driver, 4).until(
        EC.presence_of_element_located((By.ID, 'numSearchOption'))
    )
    elm = Select(elms).select_by_value('20')
    em = driver.find_element_by_name('num')
    print('表示件数:' + em.get_attribute('value'))
    # 表示件数:20

    # 検索ワードの入力
    element = WebDriverWait(driver, 10).until(
        EC.presence_of_element_located((By.ID, 'contentQuery'))
    )
    element.send_keys('Postgres')
    element.submit()

    # 検索ボタンクリック
    elm = driver.find_element_by_id('searchButton')
    elm.click()

    # 検索結果を取得する->classに記述されている属性のリストが作成される
    em = driver.find_elements_by_class_name('link')
    for item in em:
        print(item.get_attribute('data-order').rjust(2, '0') + ':' ￥
             +item.get_attribute('href')) 
    # 00:file://var/export/web/fess/pgsql11/app-pgrestore.html
    # ～
    # 19:file://var/export/web/fess/pgsql11/multibyte.html

    time.sleep(2) # 表示確認用のwait
finally:
    driver.quit()
```
複数Raspberry Pi間でメッセージを連携する

現在我が家には複数台のRaspberry Pi (Pi Zero w, wh)があり、node-red-dashboardを利用してWiFi接続したスマホからブラウザ経由で操作しています。しかし台数が増えるにつれてdashboardを複数管理するのは煩雑になりました。そこでdashboardを起動するのは1台にして、それ以外はこの1台とのメッセージ連携で操作することにしました。メッセージ連携の設定はNode-RED上の操作だけで可能ですので、自宅に複数台のラズパイをお持ちで統合的に管理したい方は是非試してみてください。

# MQTTブローカの導入
dashboardを起動する1台にはMQTTブローカを導入します（1台のみです）。導入手順は[こちら](https://qiita.com/zuhito/items/d8ac0f602e0f09b02eac)に分かりやすくまとまっています。ありがたく参照させていただくことにして、ここでは割愛します。

# MQTTブローカノードの配置
まずMQTTブローカノードを配置します。![mqtt_broker01.JPG](https://qiita-image-store.s3.amazonaws.com/0/317078/99057be4-ab15-3308-1924-2360e55af434.jpeg)
以下のような設定です。
![mqtt_broker02.JPG](https://qiita-image-store.s3.amazonaws.com/0/317078/1489e668-b0f9-db12-2bde-13b0cc964f42.jpeg)

# MQTT OUTノードの配置
以下ではMQTTブローカノードを配置しているラズパイのIPアドレスを192.168.1.10として記載します。適宜ご自身のIPアドレスに読み替えてください。メッセージを受信する側は同一のプライベートネットワーク上（例えばIPアドレス：192.168.1.20等）にあれば良く、受信側のIPアドレスは本件の設定には不要です。

まずメッセージ送信側のラズパイ（192.168.1.10）にはMQTT OUTノードを配置します（下の上から3つ目の「mqtt」と書かれたノード）。
![mqtt_broker05.JPG](https://qiita-image-store.s3.amazonaws.com/0/317078/6b101c00-9901-c76e-2a85-a95b23d66c79.jpeg)
![mqtt_broker06.JPG](https://qiita-image-store.s3.amazonaws.com/0/317078/1350e236-c9b0-9803-a250-8e7b43e48676.jpeg)
「新規にmqtt-brokerを追加」の右側のボタンをクリック、以下の画面が表示されます。
![mqtt_broker07.JPG](https://qiita-image-store.s3.amazonaws.com/0/317078/010c9736-e52d-f6e9-29a0-e3ff80aa8b25.jpeg)

サーバとポートの設定をして、クリックします。（設定するIPアドレスはMQTTブローカを起動しているサーバのIPアドレスなので、後ほど設定する**MQTT INノードでも同じ設定**をします。）
- サーバ：192.168.1.10
- ポート：1883

前の画面に戻り、トピックには以下を設定しておきます。
- トピック：test
※ 後ほど設定する**MQTT INノードでも同じトピックを設定する**ことで、このMQTT OUTノードから送信されるメッセージをINノードで受信することができます。

# MQTT INノードの配置
![mqtt_broker03.JPG](https://qiita-image-store.s3.amazonaws.com/0/317078/0c175f83-7227-445e-d643-7c3899815179.jpeg)
![mqtt_broker04.JPG](https://qiita-image-store.s3.amazonaws.com/0/317078/16006c82-dd3c-b024-089f-84f299156016.jpeg)

MQTT OUTノードのサーバ設定が済みであれば、サーバ欄には「192.168.1.10:1883」が選択できると思いますので、こちらを選択し、トピックには以下を設定します。
- トピック：test
※ MQTT OUTノードの説明に記載した通り、**メッセージ連携したいINノードとOUTノードのトピックが一致していれば良い**ため、トピックとして設定したtestは適宜置き換えてください。

以上でノードの準備は終了です。

# メッセージ連携
MQTT OUTノードにメッセージを入力すると、MQTT INノードで受信することができます。受信したメッセージはmsg.payloadに格納されてますので、後続の処理で利用可能です。今回はMQTT OUTノードをMQTTブローカが起動しているラズパイに配置しましたが、同一プライベートネットワーク上にあればどの端末間でもメッセージ連携が可能で、その時に設定するサーバも先ほどと同様です。なので一度サーバの設定をしてしまえば、以降は**トピックの一致するOUTとINを用意すればOUTからINにメッセージを連携することが可能**です。

# まとめ
長々と書きましたが、ポイントは以下の通りです。
1. MQTT INノードにもMQTT OUTノードにも、MQTTブローカが起動しているラズパイのIPアドレスを指定。
2. トピックを一致させることで必要なメッセージのみ受信可能。

# 参考にしたサイト
[1分でIoT環境を構築！Node-RED上でMQTTブローカを立ち上げる手順](https://qiita.com/zuhito/items/d8ac0f602e0f09b02eac)
Qiita初投稿です

### 概要

最近Web系に滑り込んだなんちゃってエンジニアです。
スキルアップのために、アウトプット出さないとなあと思ったので
自分が習得したスキルをQiitaに投稿していくことにしました。

本記事はその決意表明と言うかモチベーション的な意味合いが大きいので、技術的な話やためになる話を期待している方は申し訳ありません。

### そもそも、なぜアウトプットをするのか？
よく言われることですが、アウトプットをすることで頭の中を整理し、スキルアップを図りたいと思ったことが大きな理由です。前職の時はどちらかというとSIerのPM側で、

- このままではスキルが身につかないまま終わっていくのではないか
- SIerはこれから先がないのではないか

と考えて転職したのですが、現職で全く周りについていけず、、
「一体どうして？」と考えた時に以下の理由が浮かびました。

- もともと勉強好きで色々読んでいるけど、それを元に何かを作った経験があまりない
- 知識はたくさんあるけど、それがアウトプットに結びつかない
- 以上のことが原因で、本質的な理解に結びつかない

駄目なエンジニアですね…

エンジニアの成長には、「アウトプット」が欠かせないとよく言われます。
本とかでオブジェクト指向とか学んでも、大抵理解した気になっているだけで身に付いていないですよね？（僕がそうです）
本当の技術力というのは、実際に自分で触って動かして、さらにそれを「アウトプット」に繋げることで得られる物だと思うのです。

というわけで、今日から触ってみた技術や知見をQiitaに書きためていきたいと思います。
クォリティの高くない記事を書くことも多いかと思いますが、どうぞよろしくお願いします。
BitLockerで外部スタートアップ キー保護機能を使う

# 目的：BitLokerでも自動起動したい。

[BitLockerをゆるく使う](https://qiita.com/yamada3389/items/ea1893406490a8d30063)の続きです。

以下のやんごとなき理由で、BitLocker環境でも自動起動でないと手間だなということになりました。

1. やっぱり起動時にパスワードの入力が手間だ
2. 朝起きたら画面は青かった（Windows UPDATE後の自動再起動時にパスワード入力画面でとまってる）
3. 起動時のパスワード画面ではキーボードがUS配置になる（？）　_ を入力するには shift+= とか。

env:Windows10 Pro バージョン1803 ビルド17134.590


## 作業

### 前提条件

- C:\はすでに暗号化済み

### おおまかな流れ

1. システムドライブを暗号化、パスワードで解除可能の設定（済）
2. USBメモリを刺す（未暗号化）
3. Cドライブの暗号化解除方法に外部スタートアップ キー保護機能を追加
4. 確認
5. 再起動して実験

### やること

ドライブの暗号化解除用鍵ファイルをUSBメモリに保存する。

### 準備 
スタートアップキー保存用のUSBメモリをさした。
F:\　未暗号化

### Bitlockerの操作

```cmd:bitlocker.bat
# Manage-bde.exe -protectors -add c: -sk f:
BitLocker ドライブ暗号化: 構成ツール Version 10.0.17134
Copyright (C) 2013 Microsoft Corporation. All rights reserved.
追加されたキーの保護機能:
    ディレクトリ f: に保存されました
    外部キー:
      ID: {XXXXXXX-1111-2222-3333-ZZZZZZZZZZ}
      外部キー ファイル名:
        XXXXXXX-YYYYY-ZZZZ-111-222333444555.BEK

```

私が調べていた時にManage-bde.wsfを使う記事が多くありましたが、私の環境ではexeでできました。
さて、USBメモリの中身を一応見てみましょう。

```cmd:kakunin1.bat
# cd f:
# dir /a
 ドライブ F のボリューム ラベルは aaa-bbb-4g です
 ボリューム シリアル番号は 1111-333 です
 F:\ のディレクトリ
2019/02/14  20:10    <DIR>          System Volume Information
2019/02/15  00:10               XXXXXXX-YYYYY-ZZZZ-111-222333444555.BEK <--　！！！
```
隠しファイル属性で、外部キーファイルが作成されていました。
システムドライブの暗号化解除方式を一応確認しておきましょう。

```cmd:kakunin.cmd
# manage-bde.exe -status c:
BitLocker ドライブ暗号化: 構成ツール Version 10.0.17134
Copyright (C) 2013 Microsoft Corporation. All rights reserved.
ボリューム C: []
[OS ボリューム]
    サイズ:                 199.22 GB
    BitLocker のバージョン: 2.0
    変換状態:               完全に暗号化されています
    暗号化された割合:       100.0%
    暗号化の方法:           XTS-AES 128
    保護状態:               保護はオンです
    ロック状態:             ロック解除
    識別子フィールド:       不明
    キーの保護機能:
        パスワード
        数字パスワード
        外部キー     ＜－－－－ここが追加された

````

### 確認に再起動してみる。
USBメモリを指したまま再起動したら、パスワードを聞かれなかったのでセーフ。
お疲れさまでした。

### USBメモリの処遇
普段使わないですし、ドライブレターをはく奪しておきましょう。


## 初Bitlokerでスタートアップキーを使うからやった場合には？

C:\の暗号化時に、スタートアップキーを使うにするとパスワードがありません。
再起動後に以下のコマンドを打ちましょう。

```
# manage-bde -protectors -add c: -pw
ボリュームの保護に使用するパスワードを入力します:
パスワードをもう一度入力することで確認します:
追加されたキーの保護機能:
    パスワード:
      ID: {XXXX-YYYYY-ZZZ-SHINJUKU-HIGASHIGUCHI-BBS}

```
パスワードも追加されて、USBメモリが壊れても安心
FontAwesome 5のJSのCSSの自動挿入をやめさせる

FontAwesome 5のJSをブラウザで使っていると、head内にcssが自動挿入されます。

このCSS(`fontawesome.dom.css()`で取得できる)をほかの定義とまとめていると、この操作は不要です。
イケてないし、どうにかしてやめさせたいなぁ、と1年ぐらい思ってました。

https://misskey.xyz/notes/5c657596e852a2002762c1ee

さっき調べたら、なんとその方法があったんです……！(いや、なきゃ困る)

## やめさせ方
※TypeScriptをWebpackでバンドルしている場合の例です。

```typescript
import { config } from "@fortawesome/fontawesome-svg-core"
config.autoAddCss = false
```

## 結論
**APIドキュメントをちゃんと読もう！**

→ https://fontawesome.com/how-to-use/with-the-api/setup/configuration
ArgumentError in PostImages#show

<img width="1023" alt="スクリーンショット 2019-02-15 0.18.41.png" src="https://qiita-image-store.s3.amazonaws.com/0/317998/117c6d56-f8a7-648a-118c-81562703c694.png">
このようなエラーで出てしまいます。
<img width="517" alt="スクリーンショット 2019-02-15 0.21.30.png" src="https://qiita-image-store.s3.amazonaws.com/0/317998/63651930-aa6c-1635-10b9-5aa38eaa5310.png">
こちらはコントローラーです。
<img width="690" alt="スクリーンショット 2019-02-15 0.22.31.png" src="https://qiita-image-store.s3.amazonaws.com/0/317998/0149dfe0-cbb4-6545-4fc6-2620eab3085f.png">
コードを何度見直してもエラーがわかりません。

こんばんは、あまり良くないと思いつつもエラーを見ると口出してしまうのでヒントだけ、、、
showアクション内で変数の宣言とform_forで使用している引数がおかしい気がしますね。。。

<img width="1001" alt="スクリーンショット 2019-02-15 12.29.46.png" src="https://qiita-image-store.s3.amazonaws.com/0/317998/bfe3faa0-57b6-2cd9-aeca-05e4c064c8a9.png">
こちらのエラーです。
![Bad Request]()
WYSIWYGに入力したHTMLから画像だけ書き出す方法

記事サイトの構造化データに画像のパス一覧を入力するとき、どうするかなーと思って書いてみました。
やってることとしてはWPのデフォルトWYSIWYGに入力した内容からimgタグのsrcの中身だけ引っこ抜いて、ほしい形に整えて配列に入れて返す、みたいな感じです。


まずは本文を持ってきて、その中から`src=""`の中身を抽出。
正規表現に引っかからなかった場合は処理を終了します。

```php
    $conts = get_the_content();
    preg_match_all('/src="(\S+)(.jpg|.png|.gif)"/', $conts, $m);
    if(!$m) return;
```

正規表現で引っこ抜いてきた、パスの文字列部分と拡張子部分をそれぞれがっちゃんこします。
投稿時にWP管理画面でサイズをしていると、そのサイズ込みのパスになります。
オリジナルの画像のパスを取るために雑に`preg_replace()`で置換していますが、他に良さげな方法ありますかね。

```php
    $img_name_arr = $m[1];
    $img_ext_arr = $m[2];
    foreach($img_name_arr as $key => $img_name) {
        $img_path = $img_name.$img_ext_arr[$key];
        $origin_img = preg_replace('/-(\d+)x(\d+)(.jpg|.png|.gif)/', '$3', $img_path);
    }
```

構造化データに入れるとき、横幅が969px以上？でないといけないらしいので、基準となる`$border_width`よりオリジナルの画像サイズが大きいときに配列に入れる、という条件をつけました。まぁ、ここはお好みで。

```php
<?php
function get_img_list() {
    if(!is_singular()) return false;
    $border_width = 696;
    $img_arr = array();
    $conts = get_the_content();
    preg_match_all('/src="(\S+)(.jpg|.png|.gif)"/', $conts, $m);
    if(!$m) return;
    $img_name_arr = $m[1];
    $img_ext_arr = $m[2];
    foreach($img_name_arr as $key => $img_name) {
        $img_path = $img_name.$img_ext_arr[$key];
        $origin_img = preg_replace('/-(\d+)x(\d+)(.jpg|.png|.gif)/', '$3', $img_path);
        $origin_img_width = getimagesize($origin_img)[0];
        if($origin_img_width && $origin_img_width >= $border_width) {
            $img_arr[] = $origin_img;
        }
    }
    return $img_arr;
}
```


というか、WPデフォで投稿内容から画像だけ抽出する方法があったら教えてほしいです。(´・ω・｀)
picoCTF 2018 Reading Between the Eyes - Points: 150

#問題

https://2018game.picoctf.com/problems

![image.png](https://qiita-image-store.s3.amazonaws.com/0/17681/4e54ca82-60f3-e6bb-62de-0eccb322b618.png)


#解いてみた

ステゴザウルスが何か隠しているようです。
画像が添付されています。
ステガノグラフィでしょうか。

とりあえず画像をダウンロードしてみてみます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/17681/02b3989c-170c-dff6-4219-8cecbed7a8ad.png)

こんな感じの画像でしたよ。
サクラエディタで開いて「pico」で検索。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/17681/86316d86-76fa-2d68-878d-45dfc405e9ec.png)

そこまで単純ではなさそうです。
Bzで見てみます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/17681/432210ee-3e16-8dbe-46dd-fb251e7b217c.png)

簡単に見てみたところ特にそれっぽいものはありませんでした。

これまでに何問か拡張子をzipにしたら解凍できたりしたことがあったのでやってみます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/17681/f4d3486e-291b-4627-e911-ad5406fa3fa2.png)

ダメでした。
バイナリに埋め込んでるんじゃなくて画面上に埋め込んでるパターンですかね。

青い空を見上げればいつもそこに白い猫使ってみます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/17681/c4e4a8fa-6f4b-b3e8-0852-8c0701d67a90.png)

こういうのをあるやつ全部やってみましたが、特に何も出てこなかった。

ヒント見てみます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/17681/3259be20-dcd9-3c3d-d4a4-b944aedc20ac.png)

オンラインでデコーダーを見つけることができる？
ググるしかないですね。

[Steganography Tools - Alan Eliasen](https://futureboy.us/stegano/)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/17681/47779983-4145-6324-6ce3-05d689a70bf0.png)

ダメでした。


[ctf-tools/install at master · zardus/ctf-tools · GitHub](https://github.com/zardus/ctf-tools/blob/master/stegsolve/install)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/17681/467a60bf-555e-c497-48d2-87dc8bacb167.png)

使い方よくわからん。
でもダメそう。


[They Live Steganography - Decode Image - osric.com](https://osric.com/chris/steganography/decode.html)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/17681/ab63c845-4d09-5851-ad0e-4845198fda3f.png)

ずっと処理中。。。
たぶんダメ？

[steganography-png-decoder.py - GitHub](https://github.com/s373r/steganography-png-decoder/blob/master/steganography-png-decoder.py)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/17681/68d5d322-2c60-d157-9771-6d3e27ba36db.png)

ダメでした。


[Steganography Online](https://stylesuxx.github.io/steganography/)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/17681/0dd20b87-9066-77ab-386f-38136e11fdc3.png)

ダメでした。
Firefoxでやってみます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/17681/afa74ed8-d36d-75bb-a56e-44a7debaf2c3.png)

うしろに意味不明なノイズが入りましたが、一応解けました。
Chromeだとなんでダメなんだろう。。。
PHP  オブジェクトの考え メモ辞典


##静的メゾット
->インスタンスを生成しなくてもクラスから直接呼び出すメゾット
　　メゾット定義に　staticキーワードを加えるだけ

##静的プロパティ

　オブジェクト経由せずに、クラスから直接に呼び出すことができるプロパティです。
クラス内は、　self::プロパティ

##クラス定数
->classブロックの中で定義された定数のことです。

##カプセル化
 ->クラス機能のうち、必要ないものを隠す

##アクセス修飾子
　->public,protecd,privateの３つがある

　###public
 ->どこからでもアクセスできる

###protected
 ->現在のクラス、サブクラスのみアクセス可能

###private
 ->現在のクラスの中でのみアクセスできる


##アクセスメゾット


```php:qiita.rb
private xxx

public function getプロパティ名(): データdata {
   return $this->プロパティ名;

public function setプロパティ名(データ型　引数) {
    $this->プロパティ名= 引数;

```



##継承
　->継承元=スーパークラス　
　　　　継承の結果＝サブクラス


class サブクラス　extends スーパークラス名 {
}



##メゾットのオーバライド
 ->スーパークラスで定義された機能を、サブクラスで再定義すること

##オーバライトの禁止
 ->final修飾子使用

##ポリモーフィズム
  ->同名のメゾットで異なる挙動を実現する

##抽象化メゾット
　-> 空のメゾット
　　　　　オーバライドしてサブメゾットでやる


##継承のルール
->PHPで、多重継承が認められていない　
　　つまり一度に継承できるのクラスは、一度だけ

##インタ-フィイス名
->支配のメゾットがすべて抽象メゾットである.


・できること
　　　・抽象メゾット、定数
　　・多重継承が可能

親クラス

```php:qiita.rb
interface インターフェイス名　{
}
```

子クラス

```php:qiita.rb

class  実装クラス名　implements インターフェイス名 {

///クラス実装
}
```

##instanceof演算子

##無名クラス
　->名前を持たないクラス

##トレイト
　->再利用可能コード(メゾット、プロパティ)をまとめて切り出す

　　制約がある
　　　・定数はもてない
　　・クラスの継承、インターフェイスの実装はできない

##オブジェクトの代入

　オブジェクトは、代入できる

オブジェクトAからBに値コピーしたい場合
cloneを使う

##オブジェクトの比較

==
 ->同じクラスのインスタンスであること、同じプロパティと値を持つこと
　
===
 ->同じクラスの同じインスタンスを参照すること


##例外処理

スロー
->自分で発生させることもできる


Exceptionクラス
　->Exceptionクラスは、PHPが標準で提供する例外クラスであり、スーパークラスです。

エラーの扱い
 ->PHP7とPHP５では、エラー報告の扱いが違う

　PHP７では、Exceptionクラスの上位に、Throwableクラスが導入

名前空間
->namespaceを使う
  名前空間はファイルの先頭で定義すること

##クラスのインポート

use命令である
Route53で任意のHostedzoneのレコードの操作を禁止して、任意のHostedzoneレコード以外の操作を許可する設定


###IAMポリシーの例メモ

レコード変更のAPI「ChangeResourceRecordSets」と一覧表のAPI「ListResourceRecordSets」はリソースを定義できるので任意のHostedzoneを指定してDenyにする。任意のHostedzone以外の許可は、リソースを「*」にしてAllowにする。
https://docs.aws.amazon.com/ja_jp/Route53/latest/DeveloperGuide/r53-api-permissions-ref.html

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "route53:*"
            ],
            "Resource": "*"
        },
        {
            "Sid": "VisualEditor1",
            "Effect": "Deny",
            "Action": [
                "route53:ChangeResourceRecordSets",
                "route53:ListResourceRecordSets"
           ],
            "Resource": "arn:aws:route53:::hostedzone/ XXXXXXXXX"
        }
    ]
}
```

##お約束
投稿内容は私個人の意見であり、所属企業・部門見解を代表するものではありません。
flutter jsonの取得・表示

flutterで、localのjsonを元にリスト表示したい時のリファレンスが少ないので投稿いたします。

```yaml:pubspec.yml;
flutter:
   - assets/json/data.json
```

例えば下記のdata構造のjsonであるとする。

```json:data.json
[
 {'name': 'namae1'},
 {'name': 'namae2'},
 {'name': 'namae3'},
 {'name': 'namae4'}
]
```

配列や入れ子に関して、注意が必要なので[こちら](https://medium.com/flutter-community/parsing-complex-json-in-flutter-747c46655f51)を参考にclass構築を行う。

```dart:data.dart
class DataList {
  final List<Hobby> datas;

  HobbyList({this.datas});

  factory DataList.fromJson(List<dynamic> json) {
    List<Hobby> datas = new List<Data>();
    datas = json.map((i) => Data.fromJson(i)).toList();

    return DataList(datas: datas);
  }
}

class Data {
  final String name;

  Data({this.name});

  Data.fromJson(Map<String, dynamic> json) 
    : name = json['name'];

  Map<String, dynamic> toJson() => {
    'name': name
  };
}
```

DefaultAssetBundleかrooBundleかは[使い分けていく](https://flutter.io/docs/development/ui/assets-and-images#loading-text-assets)必要があるとのこと

```dart:hoge.dart
import 'package:hobbyapp/utils/data.dart';
import 'dart:convert';
~~
~~
class _Hoge extends State<Hoge> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: FutureBuilder(
          future: DefaultAssetBundle.of(context).loadString('{path}/data.json'),
          builder: (context, snapshot) {
            var fugaMap = jsonDecode(snapshot.data);
            QuestList fugas = QuestList.fromJson(fugaMap);
            return ListView.builder(
              itemCount: fugas.datas.length,
              itemBuilder: (BuildContext context, int index) {
                return Text(fugas.datas[index].name);
              },
            );
          },
        )
      )
    );
  }
```
Laravel × Infinite Scroll で無限スクロールを実装する

# 今回のお題
以前、このような記事を書きました。
[cakePHPのpaginateでinfinite scrollを使った無限スクロール](https://qiita.com/sanapon1020/items/7c4a91b4bde086392b2d)

スピンオフではありませんが、
Laravelでも同じようなことを実装することになりましたので
ぐるぐると備忘録として残していきます。

こういうのは別の技術を使うのも一つの手ではありますが
JSはあえて同じものを使おうと思います。
**決して手抜きではない。**


## Controller
```php:UserContoroller.php
$users = User::getUserByName($nane)->paginate($pageCount);

return view('user.index', compact('users'));
```

こんな感じでLaravel標準のpaginationで取得するのはCakePHPと変わらないですね。

## View(Blade)
```php:resourse/views/user/index.blade.php
<div class="search_result">
    <div class="result_users">
        <p class="number">全{{ $users->total() }}件</p>

        @foreach($users as $user)
            @component('layouts.user.list', ['user' => $user])@endcomponent
        @endforeach
        
        @if ($users->hasMorePages())
        <p class="button more"><a href="{{ $users->nextPageUrl() }}">もっと見る</a></p>
        @endif
    </div>
</div>
```

componentはユーザー情報を表示する共通レイアウトと考えていただけたらと。
「もっと見る」ボタンは初期表示時に次のページがないときは表示されません。


## javaScript
```js

<script src="/js/jquery.infinitescroll.min.js"></script>
<script type="text/javascript">
    var pageCount = {{ $users->lastPage() }};
    var nowPage = 1;
    $('.result_users').infinitescroll({
        navSelector  : ".more",
        nextSelector : ".more a",
        itemSelector : ".info",
        loading : {
            img : '',
            msgText : 'Now loading....',
            finishedMsg : '',
        },
    },
    function(newElements) {
        var $newElems = $(newElements);
        $("#infscr-loading").remove();
        if (nowPage < pageCount) {
            $(".more").appendTo(".result_users");  
            $(".more").css({display: 'block'});  
        }
        nowPage++;
    });
    
    // クリックでスクロールさせるためinfinitescrollをunbind
    $('.result_users').infinitescroll('unbind');
    // クリック時の動作
    $('.more a').click(function(){
        $('.result_users').infinitescroll('retrieve');
        return false;
    });
</script>
```

itemSelectorにある`.info`は表示するユーザー情報の大枠がそうなっている、
とお考えください。

今回も無限スクロールと言いながら、「もっと見る」をクリックして続きを表示されるようにしています。
ノークリックでスクロールしたら次が表示されるようにするには
`// クリックでスクロールさせるためinfinitescrollをunbind`
以下のスクリプトを削除すれば実現できるはずです。