OmniAICreator/Qiita-1.07M huggingface dataset:
ESP32-CAMをArduino Unoで書き込む

AmazonでFTDI232買ったけど壊れてたのが送られてきたのでArduino Unoで書き込んだよ:relaxed::relaxed::relaxed::relaxed::relaxed:

##1.以下のように配線しよう:thumbsup:
(TX-TX,RX-RX,5V-5V,GND-GND,RST-GND,IO0-GND)
![uno-esp32cam_ブレッドボード.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202086/7bbddb87-a45c-ba25-8efc-3c72115abe7d.png)

##2.:raised_hand:Arduino IDEで初めてESP32を使う人だけ↓
環境設定のボードマネージャのurlに
https://dl.espressif.com/dl/package_esp32_index.json,http://arduino.esp8266.com/stable/package_esp8266com_index.json
を追加してね！！:laughing:
その後は、ツールのボードマネージャでESP32をインすこ:kiss_ww:

##3.スケッチを変更しよう！！
スケッチ例→ESP32→Camera→CameraWebServerを開いて
CAMERA_MODEL_WROVER_KITをコメントアウトして,
CAMERA_MODEL_AI_THINKERを有効にしよう！:v:
に変更して、
const char* ssid
const char* password
の中身を自分のWiFiのものに変更:bangbang:


```cpp:CameraWebServer.ino
// Select camera model
//#define CAMERA_MODEL_WROVER_KIT //コメントアウトしてね！！
//#define CAMERA_MODEL_ESP_EYE
//#define CAMERA_MODEL_M5STACK_PSRAM
//#define CAMERA_MODEL_M5STACK_WIDE
#define CAMERA_MODEL_AI_THINKER //ここを有効にしよう！

#include "camera_pins.h"

const char* ssid = "君のSSIDだよ！！";
const char* password = "君のパスワードを入力してね！";
```

##4.ボードの設定をしよう！！:ferry:
これ
![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202086/a1fb2433-660b-4f04-b283-7406fe52de22.png)


##5.マイコンボートに書き込もう！:pencil2:
Arduino UnoにUSB接続して、左上の:arrow_right:を押すとコンパイルと書き込みが始まるよ！
コンパイルが終了すると...
<font color="LightSalmon">Connecting......_______</font>
ってログに出てくるから...
![ESP32-CAM_BACK.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202086/31fa56ce-2591-7614-567e-8bcfb959de72.png)
RSTボタンをタイミングよく押そう:bangbang::bangbang::bangbang::bangbang::rage::angel:
大体3回ぐらい押したり離したりすると成功するよ！！:relaxed:

もし失敗してぇ...
<font color="Red">Timed out waiting for packet header</font>
デデドン(絶望)
となってもめげずにもう一回「書き込み→RSTボタンを押したり離したりする」やってみよう:hugging:
何回かやれば絶対に成功するよ:moyai:

書き込みには時間:stopwatch:がかかるから注意しよう！！

##6.カメラが動作してるか確かめよう！！:movie_camera:
まず、ESP32-CAM側のIO0-GNDのジャンパワイヤを外して動作モードに変更してね！:punch:
もしまたスケッチを書き込みたいなら、IO0-GNDにジャンパワイヤを再度接続しよう！！！！！！！

そしたらシリアルモニタを表示させた状態でRSTボタンを押すとWiFiに接続、サーバの立ち上げが始まって...
Camera Ready! Use 'http://192.168.xx.xx' to connect
って表示されたらOKだよ:ballot_box_with_check:

http://192.168.xx.xx にブラウザからアクセスしてStart Streamを押してみよう！！
ストリーミングが開始してカメラの画面が映し出されるはずだよ
![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202086/a0d8c1ec-0e88-ff93-e498-33501ebab818.png)
###とっても綺麗な画面だね！！:heart_eyes:
[Blue Prism] 正規表現の名前付きキャプチャを使う

はじめに
---------------------

Blue Prism で、一定の書式に従った文字列をパースする際に、正規表現を使いたい場面があり、「名前付きキャプチャ」を利用する方法を調べてみました。

「名前付きキャプチャ」とは、例えば Python では[「名前つきグループ」](https://docs.python.org/ja/3/howto/regex.html#non-capturing-and-named-groups)と呼ばれているもので、下記のように名前を指定した「マッチ部分」の文字列を取り出して利用できるようにするものです。

```python
>>> m = re.match(r'(?P<first>\w+) (?P<last>\w+)', 'Jane Doe')
>>> m.groupdict()
{'first': 'Jane', 'last': 'Doe'}
```

Utility - Strings::Extract Regex Values の使い方を調べる
--------------------------------------------------------

インストールするとついてくる Utility 系のVBO に、「Utility - Strings」があり、その中のアクションの「Extract Regex Values」が名前的にも使えそうです。
VBO のマニュアルをみてみます。

<img width="950" alt="extract_regex_values.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/564576/261fc2ba-2321-e110-54d1-d91e76cda052.jpeg">

なるほど、わからん。。。

仕方がないので、Utility - Strings VBO の本体をみてみると、オブジェクトに用例としてデータアイテムの初期値が入っており、テスト実行して動きが確認できるようになっています。これは助かりますね！

<img width="881" alt="extract_regex_values_00.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/564576/bc6b5fbd-0383-3bbe-f580-0884c6cb7221.jpeg">


使い方のポイントは、引数の コレクション```Named Values``` にあります。
列名に ```Name``` ```Value``` をもつコレクションを準備し、その ```Name``` 列に、正規表現で設定した名前付きキャプチャの「名前」を指定します。

用例での正規表現は下記の通りです。設定されている名前付きキャプチャは ```Lower``` と ```Upper```です。

```
(?<Lower>\d+)\s*(-|to)\s*(?<Upper>\d+)
```

```Lower``` と ```Upper``` を ```Name``` 列に設定します。

<img width="701" alt="Named_Value_initial.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/564576/fa8702ee-cd31-11b9-5948-72b1ccc6c708.jpeg">


実行すると、結果が ```Value``` 列に入る仕組みになっているようです。

テスト対象の文字列は、下記の通りなので、意図通りのキャプチャができています。

```
100-200
```

<img width="702" alt="Named_Value_result.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/564576/a6d35d40-eb6a-5d70-02d4-ee971d0b3715.jpeg">


これで使い方がわかりました。

Utility - Strings::Extract Regex Values を使ってみる
--------------------------------------------------------

試しに使ってみます。

テスト対象の文字列を下記のように設定し、角括弧の中身と、角括弧に続く文字列をそれぞれ別にキャプチャしてみます。

```
[場所] 東京都品川区西五反田
```

使うパターン文字列は下記の通りです。角括弧の中身を ```Tag```、角括弧に続く文字列を ```Content``` としてキャプチャしようとしています。

```
^\[(?<Tag>\w+)\]\s*(?<Content>.+)$
```

プロセスの全体像は下記のようになります。
<img width="824" alt="try00.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/564576/526dd037-3f57-80b0-d55d-eb9d4da596d0.jpeg">


ポイントとなるコレクション ```Named Values Input``` は下記のように ```Name```列、```Value```列を設定し、```Name```列の初期値に、名前付きパターンの ```Tag```、```Content``` を設定します。

<img width="702" alt="try_named_value.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/564576/28566055-1ae5-7f2f-69f7-25a7e080f033.jpeg">


実行すると、意図通りキャプチャできたことがわかります。

<img width="582" alt="try_named_value_result.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/564576/aeef07d7-d66c-00df-078e-859635ffba11.jpeg">



まとめ
---------------------
VBO のマニュアルをみても使い方がわからない場合も、本体をみると分かることがある！
Deadlineのサブミッションの追加方法

# はじめに
Deadlineは映像屋さん（特に大規模になればなるほど）必要になるパイプラインツールの根幹を作れる一つのシステムです。
中身はオープンソースか！と思うほど改造ができる、なんとも頼れるツールです。
ただ、結構解説もわかりづらく「おい！！」ってなることもあったので、特によく使うサブミッションするときのプラグインツールのインストール方法を書きます。

## システム概要
Deadline 10.0.21.5
Windows10 Pro
AfterEffect 2018

#手順
注意）前提として、該当のコンピュータにDeadline Clientが入ってることを前提にしてます。
1. Deadlineサーバのファイル共有場所までアクセス
2. 次の場所にアクセス` \\共有フォルダ\DeadlineRepository10\submission\ソフトウェア\Installers` (今回はAfterEffectで行ってます。)
3. `.exe`はwindows用、`.app`はmac用なので選択、インストール。（次へ次へで基本終わり）
4. ソフトウェア側のプラグインのところにサブミッターができるはずなので、アクセスする。
生産性が高いとはどう言うことか


普段のお仕事を言語化してみるシリーズの第2段です。前回、[普段のスプリントを言語化してみる](https://qiita.com/ababup1192/items/be52d6637dfb49950826)と言う記事を書かせていただいたのですが、あれから2ヶ月以上経ち生産性という言葉が何なのかが腑に落ちたため改めてそこだけをフォーカスして記事にしてみました。

## 生産性とはリリース頻度・量が多い状態を指すのだろうか？

以前の記事でリリース回数が1日2回ぐらい出来ており生産性が高いぜ　イエーーーイ・・・と思っていたのですが、思わぬ落とし穴がありました。βリリース時にリリーススプリントをしてしまったのです。リリーススプリント(スクラムでは名前が付いている行為は大体アンチパターンです。)とは、機能追加が行われないスプリントになります。代わりに行われるのは機能の修正です。リリーススプリントは別名バーンスプリント日本語訳すると、**炎上期間**になります。つまり身の丈以上にリリースをしたとしても後にしっぺ返しが来てリリーススプリントや慢性的にバグチケット(プロダクトバックログアイテム)がバックログに存在し続け、機能追加が行えず生産性が低い状態を招いてしまっていたのです。また、リリース後にバグを抱え続けるということは低品質なプロダクトをユーザに提供することになり、ユーザが離れて行ってしまうリスクを抱えることになりビジネス的には大打撃であるということを自覚しなければなりません・・・。

## なぜ、リリーススプリントを引き起こしてしまったのか

開発では、バックエンドのテストはほぼ完璧に行っており、フロントエンドでは出来うる限り単体テストを導入していました。しかし、リリース直前では検証環境を開発者が何となく正常系を一本通すだけの状態になっており、QAに依頼するテストはテスト設計がリリースの次のスプリントから開始され、実際のテスト実施は2スプリント(2週間)以降に行われていました。その間、発見されたバグはPOが判断し対応可否を判断し対応が必要なのであればバックログに乗るというフローになっていました。リリースを焦る余りそれが後に集約されリリーススプリントを引き起こしたと言う訳です。

## 対策と現状

その後、同じ問題を引き起こさないために対策が行われました。スクラムでは技術品質に関するタスクは、リリース前に行うことが鉄則となります。しかし、QAテストの実施が2スプリント掛かる状態でそれを実行することになればリリースは不可能になってしまいます。

そこで行ったことは、**探索的テスト**の採用です。スクラム開発では一つの課題に対して、MVP(Minimum Viable Product)で提供することを推奨しています。それは、大きなテストを行わず限りなく最小の変更で、その変更範囲の周辺のみを重点的にテストすることで問題を短い時間であぶり出すことが出来ます。(※ 探索的テストに関しては、詳しくないため言及は避けます)。この対策により、リリース前の段階で問題を発見することができ、その場で手を打つことが可能になりました。またテストはQAと開発者のペアでテストを行うことで、仕様の確認がスムーズに行えたり、問題があったときに開発者がすぐ目星を付けられたり、テストの観点を学びとれたりなどの利点も享受しています。(本当にQA様様です・・・。)

もう一つは、**e2eの自動化**です。e2eテストは作成も実行も時間が掛かるため、正常系のみを行う最小限の導入ですが、検証環境に反映する前に開発が滞りなく行えたかを人間に依存せず確認が行えるため、とても効果があると実感しています。また、探索的テストではカバーできない今までの提供した価値が損なわれていないか(デグレがないか)の確認が簡単に行えるため、e2eテストが育てば育つほど効果は高いと実感しています。よくあるe2eテストの維持コストが高い問題ですが、正しくテストを設計してMVPを徹底すれば、問題は余り起きないと思っています(同僚がその記事を書いてくれるはずです)。

この二つの武器を備えることで、そもそも不完全な状態でプロダクトを提供すると言う事態を招くことが減り安定した開発・運用が行えると思います。まだまだ新しい試みのため、他の問題や改善できるポイントが出てくると思います(楽しみ)。一方で、数値上の生産性は以前より落ちてしまっているので、その底上げをどうするかも新たな課題として挙げられますが、これは本来の実力通りの数値になっただけなので、上げていけばいいだけです。今年も楽しいプロダクト開発になりそうです。

## まとめと新たな課題

元々、品質面にはとてもうるさい性分であると自負していますが、リリーススプリントを招いてしまったことで、より強固にしていくことが生産性に繋がることだと痛感できました。さらに生産性が高いと実感できたとしても、ユーザにとって良い価値を提供できているかどうかはまた別問題になります。開発者は市場の変化にも敏感になり、ユーザへの価値とは何なのかを意識し続ける難しい職であるなと再実感しました。これからも精進し続けたいです。
dplyr::selectとdplyr::filterをmagrittr::extractで代用（困ったときの小技）

# dplyrが使えないけど、[]で要素の抽出をしたくないときに
バージョンやらインストールやらの問題でdplyrが使えないときには、`dply::select`や`dplyr::filter`が使えない。そうするとデータフレームからの要素の抽出には`[]`を使わざるを得なくなり、コードが見にくくなる。

そんな時にはパイプでおなじみのmagrittrが活躍する。
[magrittrには演算子やオペレータのエイリアスが多く用意されている](https://cran.r-project.org/web/packages/magrittr/magrittr.pdf)ので、これを使うことで足し算やら論理演算やら要素の操作やらをfunctional sequenceのなかに組み込めるようになる。
`magrittr::extract`は`[]`に対するエイリアスであり。`magrittr::extract`を使えば、

```R
{抽出対象データフレーム}[{選択する行}, {選択する列}]
```
を

```R
magrittr::extract({抽出対象データフレーム}, {選択する行}, {選択する列})
# ベクトルに対しても使用可
```
と書くことができる。


これを生かせば、`magrittr::extract`を`dplyr::select`と`dplyr::filter`の代わりとして使うことができる。

※ magrittrが入っていないときには、`install.packages("magrittr")`でインストール
※ **`extract`はtidyrからマスクされるので、`magrittr::extract`と書くことを推奨**
※ 以下パイプを使いますが、`magrittr::extract`はパイプと連結しなくても使えます

# dplyr::selectの代用
例：irisでSeapal.LengthとSepal.Widthを抽出


### 通し番号による抽出
```R
# base
iris[, c(1, 2)]
# dplyr 
iris %>% dplyr::select(1, 2)
# magrittr
iris %>% magrittr::extract(., , c(1, 2))
```

### 列名による抽出
```R
# base
iris[, c("Sepal.Length", "Sepal.Width")]
# dplyr 
iris %>% dplyr::select(Sepal.Length, Sepal.Width)
# magrittr
iris %>% magrittr::extract(., , c("Sepal.Length", "Sepal.Width"))
```

### 列名の一致による抽出
```R
# base
iris[, grep("Sepal", names(iris))]
# dplyr
iris %>% dplyr::select(contains("Sepal"))
# magrittr
iris %>% magrittr::extract(., , grep("Sepal", names(.)))

```
第一引数に`.`を渡し、第2引数（選択行）に` `を渡す。列名の場合は`""`で囲う必要があるので注意。
`contains`のような選択をしたい時には、`grep`で列名の中から一致するものの位置を取得する。

# dplyr::filterの代用
例：irisでPetal.Lengthが6より大きいかつSpeciesがvirginicaである行を抽出

```R
# base
iris[iris$Petal.Length > 6 & iris$Species == "virginica", ]

# dplyr 
iris %>% dplyr::filter(Petal.Length > 6 & Species == "virginica")
 
# magrittr
iris %>% magrittr::extract(., iris$Petal.Length > 6 & iris$Species == "virginica", )
iris %$% magrittr::extract(., Petal.Length > 6 &  Species == "virginica", )
```
第一引数に`.`を渡し、第3引数（選択列）に` `を渡す。
`iris$`を省略したい場合は、`%>%`を`%$%`にする（右辺で列名が参照できるようになる）。
dplyrの場合は`rownames`がリセットされるが、baseとmagrittrの場合には元の`rownames`が引き継がれるので注意。

# 参考

- [Package ‘magrittr’](https://cran.r-project.org/web/packages/magrittr/magrittr.pdf)
- [magrittrの使い方](http://delta0726.web.fc2.com/packages/programming/00_magrittr.html#extract)
- [列の選択 - select関数](https://kazutan.github.io/kazutanR/hands_on_170730/select.html)
- [行の選択 - filter関数](https://kazutan.github.io/kazutanR/hands_on_170730/filter.html)
Spring Data のマイルストーンリリースを試用する方法

[4 月にリリース予定](https://github.com/spring-projects/spring-data-commons/wiki/Release-Train-Neumann)の Spring Data JDBC 2.0.0 で、enum とかのパラメータがちゃんと変換されたり、PagingAndSortingRepository を継承できるようになるみたいなので、試しにマイルストーンリリースを使ってみようと思いましたが、使い方を完全に忘れていたのでメモを残しておきます。

- https://github.com/spring-projects/spring-data-jdbc/pull/186
- https://github.com/spring-projects/spring-data-jdbc/pull/183

まず build.gradle にマイルストーンリポジトリを追加。

```gradle:build.gradle
repositories {
	mavenCentral()
	maven { url "https://repo.spring.io/libs-milestone" }
}
```

次に gradle.properties に利用するマイルストーンを指定。

```properties:gradle.properties
spring-data-releasetrain.version=Neumann-M3
```

以上です。
GitHub Actions 上で svlint を走らせる

## はじめに

~~ゴミコード生産者を吊るし上げる~~ コーディングルールの大切さを啓蒙するには、コーディングルールに則っているか、リントチェックを高い頻度で行うことが大切です。

[svlint](https://github.com/dalance/svlint) を使えば、RTL 等 SystemVerilog で書かれたソースコードのリントチェックを行うことが出来ます。GitHub Actions を使って、push 時に自動でリントチェックを実行できるようにしてみました。

## 設定方法

やることは簡単です。`.github/workflows` に実行したい処理の流れを書いた YAML を置くだけです。作者様謹製の [svlint 用の Action](https://github.com/marketplace/actions/systemverilog-linter) が公開されています。これを使えば、簡単に GitHub Actions 上で svlint を実行することが出来ます。

例として、筆者が使用している YAML ファイルを載せておきます。

```yaml
name: svlint

on: [push, pull_request]

jobs:
  svlint:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v2

      - name: Run svlint
        uses: dalance/svlint-action@v1
        with:
          filelists: |
            rtl/common/compile.f
            rtl/router/compile.f
            rtl/fabric/compile.f
            rtl/axi_adapter/compile.f
        env:
          TNOC_HOME: ${{ github.workspace }}
```

## 実行例

上記の YAML を GitHub のリポジトリ上に置いておくと、push や Pull Request が開かれた時に、自動的に svlint を実行し、リントチェックを実施できます。ソースコード上に不適切な記述があると、以下のように指摘され、GitHub 上の通知欄にも通知されます。

![workflow.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144465/f34fb3d8-1b72-fd31-43b8-f713356c4150.png)
【Vue.js】URLに直接アクセスすると404 Not Foundになる問題の解消方法

# 困ったこと
`npm run build` で生成した `dist` ディレクトリの静的ファイルを公開ディレクトリに設置したら、一部の画面遷移で404 Not Foundが発生するようになりました。また、ルーティングを設定しているURLに直接アクセスしても、設定していた画面が表示されずに404 Not Foundとなってしまいました。
Vue RouterはHistory Modeを設定しており、開発用に `npm run serve` で立ち上げていた環境では発生しません。

# 原因
RewriteRuleを設定していなかったことが原因でした。

# 解決方法
RewriteRuleの設定をWebサーバかコンテンツに設定します。今回はコンテンツ側で制御したかったので `.htaccess` ファイルを設置することにしました。
`dist` ディレクトリにそのまま設置したいファイルは `public` ディレクトリに設置します。Vue Routerのドキュメントを参考に `public/.htaccess` を設置しました。

```txt:public/.htaccess
<IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteBase /
  RewriteRule ^index\.html$ - [L]
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteRule . /index.html [L]
</IfModule>
```
これでビルドすると `public/.htaccess` が `dist/.htaccess` にコピーされるようになります。`dist` 以下の生成ファイルを公開ディレクトリに設置し直すと、404 Not Foundが発生しなくなりました。

# 参考
* [HTML5 History Mode | Vue Router](https://router.vuejs.org/guide/essentials/history-mode.html)
* [HTML and Static Assets | Vue CLI](https://cli.vuejs.org/guide/html-and-static-assets.html#static-assets-handling)
* [vue.js - In Vue, how to include .htaccess to production using npm run build? - Stack Overflow](https://stackoverflow.com/questions/52397542/in-vue-how-to-include-htaccess-to-production-using-npm-run-build)
Javascriptでhtml要素の順番を入れ替える。

#はじめに

ちゃんとした説明を一度書いてみようと思った。



#実際の動き

Jsのコマンドに、`appendChild`、`insertBefore`というヤツらが存在する。
この２つは、特定の要素を最後尾、または要素の前に挿入する関数なのだが……

さて、問題である。**既に存在する要素を再び追加すると何が起きるのだろうか。**


ちなみに、初期状態はこちら。
![1582104043515.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416995/30e0256d-d5f7-4265-f7a4-04dbb98257a2.jpeg)

なお、正しい順番は以下のものとなる。
![DG-4BA_UAAAGvIL.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416995/30b44b07-63ef-cdb3-501f-93cf4770d535.jpeg)



HTMLそのもののソースはこちら。

```html:html

<!DOCTYPE html>
<html lang="ja">
<head>
	<meta charset="utf-8">
	<title>無題</title>
</head>
<body>

<style>
#pipimi{
    border: 2px solid black;
    padding: 10px 20px;
    margin: 0;
    max-width: 200px;
}
#pipimi p{
	font-family: serif;
    margin: 0 0 0.5em 0;
}
</style>

<div id="pipimi">
	<p>なんとも低い</p>
	<p>クオリティ</p>
	<p>まあひどい</p>
</div>

<script type="text/javascript">
var tag = document.getElementById('pipimi');
var taglist = tag.getElementsByTagName('p');

var p01 = taglist[0]; // なんとも低い
var p02 = taglist[1]; // クオリティ
var p03 = taglist[2]; // まあひどい

</script>
</body>
</html>
```

scriptを以下のように変えてやると……

```html:html

<script type="text/javascript">
var tag = document.getElementById('pipimi');
var taglist = tag.getElementsByTagName('p');

var p01 = taglist[0]; // なんとも低い
var p02 = taglist[1]; // クオリティ
var p03 = taglist[2]; // まあひどい

tag.appendChild(p02);

</script>

```

こうなる。

![1582104656370.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416995/3fdb7403-ab3c-10e3-68c1-3161816fe1c1.jpeg)

そう、既に存在する要素を「追加」すると、元の位置からは消えて、新しい位置に追加される。つまり移動するのだ。
同じ要領で、insertBeforeのほうもためしてみよう。

```html:html

<script type="text/javascript">
var tag = document.getElementById('pipimi');
var taglist = tag.getElementsByTagName('p');

var p01 = taglist[0]; // なんとも低い
var p02 = taglist[1]; // クオリティ
var p03 = taglist[2]; // まあひどい

tag.appendChild(p02);

tag.insertBefore(p03, p01);

</script>

```

結果はこのとおり。完成である。
![1582105232515.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416995/a7cffe11-300d-8b47-eec0-8c4f9a08a0e9.jpeg)


#おわりに

不明な点などありましたら編集リクエストおねがいします。
fishのaliasについてメモ

##確認

```
alias
```
で使用できるaliasの一覧を表示する

##登録
```
alias rmi='rm -i'
alias rmi 'rm -i'
```
どちらの書き方でもよい

以下を実行すると、`~/.config/fish/functions`内に`rm.fish`として保存され、ターミナル起動時に読み込まれるようになる

```
funcsave rmi
```





##削除
`~/.config/fish/functions`内にある`rm.fish`を削除するか

```
functions -e rm
```
を実行する
SDL_mixerを使ったプログラムでMIDIがならないときの確認点

[Simutrans](https://www.simutrans.com/en/)というゲームではBGMがMIDIファイルになっており、そのBGMがならなくて困ったので解決策を探していたらLinuxでSDL_mixerを使っている際に共通する(と思われる)解決策で解決でき、また日本語情報が見つからなかったので共有します。

# 動作環境
上記の通り、今回は一つのゲームでしか試していません。そのうえで今回上手く動作した環境は以下です。

* OS: Arch Linux (Linux 5.5.4-arch1-1)
* SDL_mixer: libSDL_mixer-1.2.so.0.12.0
* サウンドフォント: FluidR3_GM.sf2
* Simutrans: Simutrans 121.0

また、PulseAudio環境下での話です。

# 確認点

## TiMidity++またはFluidSynth
まずそもそも、LinuxでMIDIを再生するためにこれらのうちの少なくとも一方を入れる必要があります。今回の場合どちらも入っている状態で片方ずつ確認しましたが、それぞれ正常に動作したのでどちらでも良いと思われます。また、単に導入するだけでも駄目で、`timidity -iA`や`fluidsynth -a pulseaudio -m alsa_seq -o midi.autoconnect 1 [SOUND_FONT]`等でデーモン化させておく必要があります。個々のオプションは環境に合わせて調節してください。

## サウンドフォント
OSにより異なると思いますが、少なくともArchLinuxではTiMidity++やFluidSynthを導入してもサウンドフォントは入らないため、別に入れる必要があります。導入したサウンドフォントはデーモン化する際にTiMidity++の場合は`/etc/timidity++/timidity.conf`等、FluidSynthの場合は引数に指定してください。

## `SDL_SOUNDFONTS`
SDL_mixerを使ったプログラムを実行する際に、上で設定したサウンドフォントのパスを`SDL_SOUNDFONTS=/path/to/soundfont.sf2 ./program`のように指定してください。試していないですが、恐らく`.bashrc`等で設定しても大丈夫だと思います。

## ミュート
ここまでの作業で再生されるはずですが、もし再生されない場合は念の為ミュートになっていないか確認してください。今回の場合はここまでで上手く再生されました。

# 最後に
`SDL_SOUNDFONTS`の情報が見つからずに嵌ってしまい、また見つかった際もFluidSynthをSDL_mixerと組み合わせる場合の情報として書いてあったので、探しづらかったです。なお、動作環境にも書きましたが、**SDL2ではなくSDLでの話**なのでSDL2では変わっている可能性があります。

# 情報元
* ArchWiki (英語版): [https://wiki.archlinux.org/index.php/FluidSynth#SDL_Mixer](https://wiki.archlinux.org/index.php/FluidSynth#SDL_Mixer)
[wijmo] flexgridで列ヘッダを非表示とレイアウト変更

# はじめに
完全に備忘録。wijmoのflexgridを使うことが多いのですが、いつもレイアウトでつまるわりに、検索してもあまりいい記事がないので。(wijmo5 & Angular8を使ってます。)

# 列ヘッダ非表示

```html
<wj-flex-grid #grid [itemsSource]="data" [headersVisibility]="'None'">
  <wj-flex-grid-column  binding="hoge" [width]="30"></wj-flex-grid-column>
</wj-flex-grid>
```
headersVisivilityプロパティをNoneにするだけ。
[HeadersVisibility 列挙型](https://demo.grapecity.com/wijmo/api/enums/wijmo_grid.headersvisibility.html)
もっと「wijmo flexgrid 列ヘッダ非表示」でひっかかってほしい…

# レイアウト変更
ヘッダーだけ文字を中央よせにしたいとか、gridの罫線を消したいとかいうとき。
htmlに[itemFormatter]をかくのは共通。

```html
<wj-flex-grid #grid [itemsSource]="data" [itemFormatter]="itemFormatter">
  <wj-flex-grid-column  binding="hoge" [width]="30"></wj-flex-grid-column>
</wj-flex-grid>
```

## ヘッダー文字中央寄せ

```typescript
import { WjFlexGrid } from '@grapecity/wijmo.angular2.grid';

@ViewChild('grid', {static: true}) private grid: WjFlexGrid;
 /** gridヘッダー文字列のみ中央寄せ */
    itemFormatter = (panel, r, c, cell) => {
      if (panel.cellType === this.grid.columnHeaders.cellType) {
        cell.style.textAlign = 'center';
      }
    }
```

## 罫線消したい

```typescript
  /** grid縦罫線削除 */
  itemFormatter = (panel, r, c, cell) => {
    if (panel.cellType === this.grid.cells.cellType) {
      cell.style.borderRight = 'none';
    }
  }
```

panel.cellTypeで検索したらわりと検索にヒットした。

# まとめ
ナレッジベースという質問受付サイトがあるとはいえ、もう少し検索でヒットするとうれしいですね。

# 追記
グリッドの行幅を大きくしたい！垂直方向で真ん中揃えにしたい！ということがあったので、そちらを追記

## グリッドの行幅変更
上のItmeFormatter内に以下を追加したらできた。

```this.grid.rows.defaultSize = 50;```

## セル垂直方向の真ん中揃え

HTML側

```html
<wj-flex-grid #grid [itemsSource]="data" [itemFormatter]="itemFormatter"
  (formatItem)="onFormatItem(theGridFormatItem, $event)">
  <wj-flex-grid-column  binding="hoge" [width]="30"></wj-flex-grid-column>
</wj-flex-grid>
```

component側

```typescript
/** grid垂直方向中央寄せ */
  onFormatItem(flexGird, e) {
    const style = e.cell.style;
    style.display = 'flex';
    style.alignItems = 'center'; // vertical alignment
}
```
AWS SageMaker Studioにアクセスできなくなった

# 事象
ユーザを選択して、SageMaker Studioを起動しようとすると
「このページは動作していません」と先に進めなくなってしまった。

# 解決法
AWS CLIを使います。
[delete-domain](https://docs.aws.amazon.com/cli/latest/reference/sagemaker/delete-domain.html) コマンドでSageMaker Studioのドメインごと消して作り直す方法もありますが、
Notebookは残したいと言った要望があるかと思います。
その場合はSageMaker Studioで立ち上がっているアプリだけ立ち上げ直すことができます。

[list-apps](https://docs.aws.amazon.com/cli/latest/reference/sagemaker/list-apps.htm) で使用中のアプリを表示

```
aws sagemaker list-apps --domain-id-equals <domain_id> --user-profile-name-equals <profile_name> --region us-east-2
```
```JSON
{
    "Apps": [
        {
            "Status": "InService",
            "DomainId": "<domain_id>",
            "AppType": "KernelGateway",
            "AppName": "datascience",
            "CreationTime": <time>,
            "UserProfileName": "<profile_name>"
        },
        {
            "Status": "InService",
            "DomainId": "<domain_id>",
            "AppType": "JupyterServer",
            "AppName": "default",
            "CreationTime": <time>,
            "UserProfileName": "<profile_name>"
        }
    ]
}
```

[delete-app](https://docs.aws.amazon.com/cli/latest/reference/sagemaker/delete-app.html) で、全てのアプリを削除

```
aws sagemaker delete-app --domain-id <domain_id> --user-profile-name <profile_name> --app-type KernelGateway --app-name datascience --region us-east-2
aws sagemaker delete-app --domain-id <domain_id> --user-profile-name <profile_name> --app-type JupyterServer --app-name default --region us-east-2
```

後はコンソールから再度起動してみてください。
復活するはずです！

まだプレビュー段階だからこういったログインできなくなるような事象が発生するんですかね。。(2020/02/19時点）

# 参考URL
https://qiita.com/KC_NN/items/5037400655fecf5e80d6
php-fpmとfastcgiを使ってphpを実行する 

# 恒例
FastCGIに関して
https://ja.wikipedia.org/wiki/FastCGI

FPMに関して
http://php.net/manual/zh/install.fpm.php
https://php-fpm.org/

# php-fpm Installation
Yumでインストールする

```bash
yum install php55w-fpm #php5.5の場合
yum install php56w-fpm #php5.6の場合
yum install php70w-fpm #php7.0の場合
```

自分でcompileでインストールする
--enable-fpmというペラメタつけてphpをコンパイルする
例えば

```bash
./configure --prefix=/usr/local/php --with-apxs2=/usr/local/httpd/bin/apxs --with-zlib --with-mysql=mysqlnd --with-mysqli --enable-mbstring --enable-ftp --with-xsl --with-gd --with-jpeg-dir=/usr/local/libjpeg --with-png-dir=/usr/local/libpng --with-freetype-dir --with-pdo-mysql --with-openssl --enable-soap --with-mcrypt --enable-zip --with-tidy --with-curl --enable-gd-native-ttf --enable-bcmath --enable-sockets --enable-exif --with-gettext --with-ldap --enable-fpm --with-fpm-user=fpm-user --with-fpm-group=fpm-group
```

--enable-fpm 
--with-fpm-user=fpm-user 
--with-fpm-group=fpm-group

fpm-userとfpm-groupをサーバーのユーザーに替えてください


# FastCGI Installation

Yumでインストールする
```bash
yum install fcgi-devel fcgi
```

自分でcompileでインストールする
https://httpd.apache.org/mod_fcgid/　からmod_fcgidをダウンロードする

```bash
tar zxf mod_fcgid-2.3.9.tar.gz
cd mod_fcgid-2.3.9/
APXS=/usr/local/httpd/bin/apxs ./configure.apxs
make
make install
```

# httpd.confを編集する

```vim

#追加する
LoadModule fcgid_module modules/mod_fcgid.so 
LoadModule proxy_fcgi_module modules/mod_proxy_fcgi.so

#追加する
<IfModule fcgid_module>
　AddHandler fcgid-script .php
　FcgidWrapper "/usr/local/php/bin/php-cgi" .php 　#自分のphpのpathに替えてください
</IfModule>

#追加する
<IfModule fcgid_module>
　AddHandler fcgid-script .php
　AddHandler fcgid-script .fcgi
　FcgidWrapper "/usr/local/php/bin/php-cgi" .php　 #自分のphpのpathに替えてください
　<FilesMatch \.php$>
　　SetHandler "proxy:fcgi://127.0.0.1:9000"
　</FilesMatch>
</IfModule>
```

# php-fpm.confを編集する

```vim
; Unix user/group of processes
; Note: The user is mandatory. If the group is not set, the default user's group
; will be used.
user = fpm-user
group = fpm-group

listen = 127.0.0.1:9000
; listen = /usr/local/php/var/run/socket

#socket と port 2つlisten方法がある、一つを選んでください

```

# php-fpmをスタート

```bash
/usr/local/php/sbin/php-fpm
```
# phpinfo()で確認する

Server API は　FPM/FastCGIで表示されると成功！
プレゼンテーション関連書籍まとめ

#諸言
　学習履歴全体のリンク
　https://qiita.com/shigural/private/444b991293e5ab1b40af
## TEDスピーカーに学ぶ「伝える力」
相手を変えようとするプレゼンはするべきでない
何を伝えるのか先に決める
脳内で考えず、紙かPCに書いて考える
つかみ→メイン→メインの終わりでメインを超える最後の話題　と構成する
自分が立っている側と逆側を優先的に見てプレゼンする
ビデオを取って確認する

## TEDトーク世界最高のプレゼン力
伝えたいメッセージを1つに絞る
なんのために（最初）→なにをするか（最後）
3-12語のキャッチフレーズを考える
プレゼンは自分の経験から始める。感情を揺さぶる。なぜでたずねる
終わる少し前に終わるということを伝える
終わるとき結論は明確にする
自分は失敗者として、他の誰かをヒーローにして物語を構成する（あくまで自分は一般人）
苦難を乗り越え、ハッピーエンドのストーリーにする
「みなさん」、「あなたたち」ではなく「あなた」と個人を指す表現をつかう
→「○○されたことがある方ってどのくらいいらっしゃいます？」（手を上げながら）
フォントを統一
要素の少ないスライド
全体で5色まで

## TEDトーク実践編
1分間に4回程度「あなた」「あなたの」を使う
ビデオは30秒以下にする
聴衆よりすこしだけフォーマルな服装を選ぶ

## スティーブ・ジョブズのプレゼン技術を学ぶ本
過去を否定しない
詳細はいらない。どんな恩恵があるかだけ
デモを見せる
驚きを与える
最もいいものを最後に見せる
1位2位...じゃなく3,2→1位
毎回の説明で反復と要約を入れる
「過去に言ってることを使う」「感性的である」「新しいことをださない」フィニッシュにする
真っ暗なスライドで印象づける
聴衆分析→プレゼン目的の設定→プレゼン用の資料収集
めっちゃ大きいフォントサイズ
箇条書きは順々に見せる


## 世界最高のプレゼン力
プレゼンの始め方は3種類「質問する」「数秒の間を置いてはじめる」「ショッキングなデータ」
イラストは原則自分で作る（100%イメージ通りに作れて権利問題を考えなくて済むため）
手は広げておく
過去の話、現在の話、未来の話に合わせて自分の位置を（聴衆から見て）左から右に移動する
質問で主張を伝える
cscの作法 その40 スクリーンセーバー

#概要

cscの作法、調べてみた。
スクリーンセーバー作ってみた。

#サンプルコード


```
using System;
using System.Drawing;
using System.Windows.Forms;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing.Drawing2D;

public class Form1: Form {
	public Form1() {
		this.FormBorderStyle = FormBorderStyle.None;
		this.WindowState = FormWindowState.Maximized;
		this.KeyDown += new KeyEventHandler(this.MyKeyDown);
		this.MouseDown += new MouseEventHandler(this.MyMouseDown);
		this.ClientSize = new Size(640, 480);
		Opacity = 0.3;
		Timer timer = new Timer();
		timer.Interval = 1000; 
		timer.Tick += new EventHandler(timerTick);
		timer.Start();
	}
	private void MyMouseDown(object sender, MouseEventArgs ev) {
		Application.Exit();
	}
	private void MyKeyDown(object sender, KeyEventArgs ev) {
		Application.Exit();
	}
	protected override void OnPaint(PaintEventArgs e) {
		Graphics g = e.Graphics;
		g.TranslateTransform(ClientSize.Width / 2, ClientSize.Height / 2, MatrixOrder.Append);
		Pen BPen = new Pen(Color.Blue, 5);
		Pen GPen = new Pen(Color.Green, 5);
		Pen RPen = new Pen(Color.Red, 3);
		Point center = new Point(0, 0);
		DateTime time = DateTime.Now;
		double secAng = 2.0 * Math.PI * time.Second / 60.0;
		double minAng = 2.0 * Math.PI * (time.Minute + time.Second / 60.0) / 60.0;
		double hourAng = 2.0 * Math.PI * (time.Hour + time.Minute / 60.0) / 12.0;
		int r = Math.Min(ClientSize.Width, ClientSize.Height) / 2;
		int secHandLength = (int) (0.9 * r);
		int minHandLength = (int) (0.9 * r);
		int hourHandLength = (int) (0.7 * r);
		Point secHand = new Point((int) (secHandLength * Math.Sin(secAng)), (int) (-secHandLength * Math.Cos(secAng)));
		Point minHand = new Point((int) (minHandLength * Math.Sin(minAng)), (int) (-minHandLength * Math.Cos(minAng)));
		Point hourHand = new Point((int) (hourHandLength * Math.Sin(hourAng)), (int) (-hourHandLength * Math.Cos(hourAng)));
		g.DrawLine(RPen, center, secHand);
		g.DrawLine(GPen, center, minHand);
		g.DrawLine(BPen, center, hourHand);
	}
	void timerTick(object sender, EventArgs e) {
		this.Invalidate();
	}
	[STAThread]
	static void Main(string[] args) {
		if (args.Length == 0 || string.Compare(args[0], "/s", true) == 0)
		{
			Form form = new Form1();
			form.ShowDialog();
		}
		Application.Exit();
	}
}



```


以上。
Kaggle:Tuning Automated Feature Engineering (Exploratory)

https://www.kaggle.com/willkoehrsen/tuning-automated-feature-engineering-exploratory

https://qiita.com/qrat/items/731f628cab2e72242d8f

の続き。どんな便利機能があるのだろうか。

## pandasでdateをtimestampに変更。

```
# Establish a starting date for all applications at Home Credit
start_date = pd.Timestamp("2016-01-01")
start_date
```


> If we were doing manual feature engineering, we might want to create new columns such as by subtracting DAYS_CREDIT_ENDDATE from DAYS_CREDIT to get the planned length of the loan in days, or subtracting DAYS_CREDIT_ENDDATE from DAYS_ENDDATE_FACT to find the number of days the client paid off the loan early. However, in this notebook we will not make any features by hand, but rather let featuretools develop useful features for us.


なるほど、確かに日付データも自動でパパっと作ってくれるならそれに越したことはないか。


```
time_features, time_feature_names = ft.dfs(entityset = es, target_entity = 'app_train', 
                                           trans_primitives = ['cum_sum', 'time_since_previous'], max_depth = 2,
                                           agg_primitives = ['trend'] ,
                                           features_only = False, verbose = True,
                                           chunk_size = len(app_train),
                                           ignore_entities = ['app_test'])


```
`time_since_previous`でよしなに作ってくれる・・のか？


## seed feature
よくわからなかった。

https://docs.featuretools.com/en/stable/guides/tuning_dfs.html

> By using seed features, we can include domain specific knowledge in feature engineering automation.

domain specificな情報も追加できるということ。

上記ページの例でいうと

```
In [4]: expensive_purchase = ft.Feature(es["transactions"]["amount"]) > 125

In [5]: feature_matrix, feature_defs = ft.dfs(entityset=es,
   ...:                                       target_entity="customers",
   ...:                                       agg_primitives=["percent_true"],
   ...:                                       seed_features=[expensive_purchase])
   ...: 

In [6]: feature_matrix[['PERCENT_TRUE(transactions.amount > 125)']]
Out[6]: 
             PERCENT_TRUE(transactions.amount > 125)
customer_id                                         
5                                           0.227848
4                                           0.220183
1                                           0.119048
3                                           0.182796
2                                           0.129032
```

es["transactions"]["amount"]が多いというのがドメイン知識的に重要なので、それをseedとして与える、ということだろうか。

## Conclusion

> In this notebook we explored some of the advanced functionality in featuretools including:
>
>    Time Variables: allow us to track trends over time
    Interesting Variables: condition new features on values of existing features
    Seed Features: define new features manually that featuretools will then build on top of
    Custom feature primitives: design any transformation or aggregation feature that can incorporate domain knowledge

とはいうものの・・まだ理解が追いついていない。とにかく最初にぶん回す時に楽ができそう感。
fork()関数、execve()関数について


- 自分用メモ
- カーネルのプロセス生成について学んだことを残しておく 
- C言語で実行

## fork()関数について
- fork()関数を実行すると、親プロセスから子プロセスを生み出す

```c:fork.c
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <err.h>

static void child()
{
    printf("Child. pid: %d.\n", getpid());
    exit(EXIT_SUCCESS);
}

static void parent(pid_t pid_child)
{
    printf("Parent. parent's pid: %d. child's pid: %d\n", getpid(), pid_child);
    exit(EXIT_SUCCESS);
}

int main()
{
    pid_t pid;
    pid = fork();
    
    if(pid == -1) err(EXIT_FAILURE, "fork() failed");
    
    //子プロセスは返り値が0
    if(pid == 0)
        child();
    //親プロセスが返り値が子プロセスのプロセスID(> 0)
    else 
        parent(pid);
}
```

- 実行結果

```shell-session
Parent. parent's pid: 27701. child's pid: 27702
Child. pid: 27702.
```
親プロセスから子プロセスが生成され、それぞれ別のプロセスIDを持っていることが分かる

## execv()関数について
- 以下の流れでカーネルはプロセスを実行する

1. 実行ファイルを読み込む
2. 現在のプロセスのメモリを新たなプロセスのデータで上書き
3. 新しいプロセスを実行

```c:execve.c
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <err.h>

static void child()
{
    char *args[] = {"/bin/echo", "こんにちは", NULL};
    printf("child. child's pid: %d.\n", getpid());
    execve("/bin/echo", args, NULL);
    err(EXIT_FAILURE, "execve() failed");
}

static void parent(pid_t pid_child)
{
    printf("parent. parent's pid: %d. child's pid: %d\n", getpid(), pid_child);
    exit(EXIT_SUCCESS);
}


int main(void)
{
    pid_t pid;
    pid = fork();
    if(pid == -1)
        err(EXIT_FAILURE, "fork() failed");
    
    if(pid == 0)
        child();
    else
        parent(pid);
    
}
```

- 実行結果

```
parent. parent's pid: 28034. child's pid: 28035
child. child's pid: 28035.
こんにちは
```
fork()関数でプロセスが分岐したあと、子プロセスでexecve()関数によって、/bin/echoが実行されていることが分かる
深夜にDockerコンテナ使ってるとslack経由でデスクトップに通知が届くようにしてみた

深夜に`docker-compose up -d`してるとデスクトップに「GO TO BED」と通知が来るようにしてみました。

cronを稼働させるためのコンテナを用意し、自動的にcurlコマンドでのslack投稿を行うようにすることで実装しています。お試しで作ったので実用性は低いです。

## **cronとは**
指定したコマンドやシェルスクリプト等を日時指定で自動実行するための常駐プログラム(デーモンプロセス)。

内部では、1分毎に起動、_/etc/crontab_ などに置かれているcrontabファイルを調査、該当する時刻の場合処理を実行、という処理が行われているようです。
crontabファイルの置き場所やデーモンとして起動するか否かなど、細かい違いがあるようですが今回そこまでは調べてません。

## **設計**
docker-compose.ymlにcron稼働用のコンテナを追加し `cron -f` コマンドでcronタスクを常駐させるだけです。

## **slack側でWebhookの設定**
slack側で _Incoming Webhook_ を設定して、HTTPリクエストでslack投稿できるようにします。
なお、 _Incoming Webhook_ は認証がないのでURLが漏れると悪意のあるユーザーからも投稿できるようになってしまいます。

実際の手順については、以下を参考にさせていただきました。
[参考：SlackのWebhook URL取得手順](https://qiita.com/vmmhypervisor/items/18c99624a84df8b31008)

URLを取得したらcurlコマンドで投稿できるか確認してみましょう。

```shell
curl -X POST --data-urlencode "payload={\"channel\": \"#general\", \"username\": \"testuser\", \"text\": \"Hello\"}" https://hooks.slack.com/services/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
```

## **実装**
深夜0時から6時まで、5分毎に「GO TO BED」と投稿されるようにしてみました。

```:構成
.
├ cron_alert/
│  └ Dockerfile
│  └ midnight_alert.sh
└ docker-compose.yml
```

```docker-compose.yml
cron:
  build: ./cron_alert
  volumes:
    - ./cron_alert:/cron_dir
  ports:
    - "3456:3456"
```

```docker:Dockerfile
FROM ubuntu:latest

# TimeZone設定
ENV TZ Asia/Tokyo
RUN DEBIAN_FRONTEND=noninteractive

RUN apt-get update && apt-get install -y cron sudo curl vim tzdata

RUN echo '*/5 0-6 * * * root /cron_dir/midnight_alert.sh' >> /etc/crontab

CMD ["cron", "-f"]
```

```shell:midnight_alert.sh
#!/bin/sh

CHANNEL="#general"
USERNAME="webhookbot"
TEXT="GO TO BED   GO TO BED   GO TO BED   GO TO BED   GO TO BED   GO TO BED   GO TO BED   GO TO BED   GO TO BED   GO TO BED   GO TO BED   GO TO BED"
PAYLOAD="payload={\"channel\": \"$CHANNEL\", \"username\": \"$USERNAME\", \"text\": \"$TEXT\"}"

curl -X POST --data-urlencode "${PAYLOAD}" https://hooks.slack.com/services/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
```

[参考：Docker コンテナ内でタスクを cron 起動する](https://qiita.com/rerofumi/items/fc0126c4e985b78f769b)
[参考：Dockerコンテナのタイムゾーン変更方法](https://qiita.com/rururu_kenken/items/972314402d588e073d40)

## 最後に
深夜に`docker-compose up -d`してるとデスクトップに通知が来るのを確認して満足しました。
変なこと書いてたら指摘してくださるとうれしいです。
2/19 第一回テスト対策ノート<基礎>

これらを声に出して読めばとりあえず合格点にはたどり着けるはず…。

#HTML分野
・HTMLの正式名称
　→Hyper Text Mark-up Language
・HTML5のバージョン情報を完全な形で記述
　→```<!DOCTYPE HTML>```
・```<!DOCTYPE html>```の事をDTD(Document Type Definition＜文書型定義＞)と呼ぶ
　→文書のバージョン情報を記述するすることができる
・head要素→ページ全体の情報(文字コードやキーワードなどの補足情報、検索エンジン向けの情報など)を記述。
　ブラウザに表示されない
・body要素→ページの中身を記述。ブラウザに表示される
・pxとは：相対単位の一つ。モニタの画素(ピクセル)を１とする単位
　ex:)代表的な画面解像度は1280×720(px)
・セクション要素(教科書P208～)
　→見出しとそれに伴うコンテンツのひとかたまりのこと。
　　文書の「アウトライン」を生成し、情報の階層構造尾を明示する役割を持っている。
・文字コードをメタ情報として完全な形で記述
　→```<meta charset=”utf-8”>```
・順番の無い箇条書き
　→```<ul><li></li></ul>```
・順番付きの箇条書き
　→```<ol><li></li></ol>```
・```<li>```にリンクを貼る時
　→```<li><a href=”#”>aaa</a></li>```
・説明型リスト
　→```<dl><dt></dt><dd></dd></dl>```
・HTML5文書にてスタイルシート”style.css”(同ディレクトリCSSフォルダ内)へのリンクを記述
　→```<link rel="stylesheet" href="css/style.css">```
・属性を３つ以上記述
　→src,name,lang,href,border,charset,content...
・要素を３つ以上記述
　→html,h1,head,title,base,link,meta,style,body...
　**☆要素と属性の違い**
　　　**要素：特定の文字列の前後を開始タグと終了タグで囲って意味や役割を与えるもの**
　　　ex:)html,h1,head,title,base,link,meta,style,body,nav,header,footer...
　　　**属性：要素に対するオプション設定のような役割を持つ**
　　　ex:)src,name,lang,href,border,charset,content,id,style...
　　　※styleは要素と属性それぞれに存在するので注意

**header/footer/nav要素**
・header/footer要素(P216)
　→セクションのヘッダー/フッターを表す。**outlineとして認識されない**
　　header要素の中には通常h1～h6要素が入ることを想定しているが、なくても間違いではない
　　footer要素の中には通常は著作権情報、連絡先などが入る
　　1ページ内に複数のheader/footer要素が存在しても良い
・nav要素(P214)
　→WEBサイトのナビゲーションを表す。**outlineとして認識される**


#CSS分野
・**CSS(Cascading Style Sheets)**：HTML文書に装飾・レイアウトを施すための言語のこと
・CSSの基本書式
　→「セレクタ{プロパティ:値;}」という流れで書く。
　ex:)```h1{color: #ff0000;}```
　　☆h1部分→セレクタ、color部分→プロパティ、#ff0000部分→値と呼ぶ
・padding：ボックスの内側の上下左右の余白
・margin：ボックスの外側の上下左右の余白
・グループセレクタ＝CSS内で複数のセレクタに共通する装飾をまとめて記述すること
　ex:)```h1,h2,p{…}```
・横幅Apx、親Boxに対して上下余白0、中央揃えのdivをCSSで記述
　→```div{width:Apx; margin:0 auto;}```
・ハイパーリンク
　→```<a href=”#”>text</a>```
・コピーライトは何要素でマークアップするか
　→small要素
　ex:)```<p><small>Copyright;</small></p>```

#共通
・HTMLとCSSの違い
　**HTMLはコンテンツに意味づけをして文書構造を作る
　CSSはコンテンツに対して見栄えを作る**
Kaggle Titanic 0.62200

次のページを参考にしました。
[Kaggle事始め](https://qiita.com/taka4sato/items/802c494fdebeaa7f43b7)

Arch Linux でのライブラリーのインストール

>```bash
sudo pacman -S python-pandas
sudo pacman -S python-scikit-learn
```

Ubuntu 19.10 でのライブラリーのインストール

>```bash
sudo apt install python3-pandas
sudo apt install python3-sklearn
```

```py:titanic01.py
#! /usr/bin/python
#
#	titanic01.py
#
#					Feb/19/2020
# --------------------------------------------------------------------------
import sys
import pandas as pd
#import csv
from sklearn.ensemble import RandomForestClassifier

# --------------------------------------------------------------------------
# [2]:
def read_train_proc():
	train_df = pd.read_csv("train.csv", header=0)

# Convert "Sex" to be a dummy variable (female = 0, Male = 1)
	train_df["Gender"] = train_df["Sex"].map({"female": 0, "male": 1}).astype(int)

# Complement the missing values of "Age" column with average of "Age"
	median_age = train_df["Age"].dropna().median()
	if 0 < len(train_df.Age[train_df.Age.isnull()]):
		train_df.loc[(train_df.Age.isnull()), "Age"] = median_age

# remove un-used columns
	train_df = train_df.drop(["Name", "Ticket", "Sex", "SibSp", "Parch", "Fare", "Cabin", "Embarked", "PassengerId"], axis=1)
#
	return	train_df

# --------------------------------------------------------------------------
# [4]:
def read_test_proc():
	test_df = pd.read_csv("test.csv", header=0)
	test_df["Gender"] = test_df["Sex"].map({"female": 0, "male": 1}).astype(int)

# Complement the missing values of "Age" column with average of "Age"
	median_age = test_df["Age"].dropna().median()
	if 0 < len(test_df.Age[test_df.Age.isnull()]):
		test_df.loc[(test_df.Age.isnull()), "Age"] = median_age

# Copy test data's "PassengerId" column, and remove un-used columns
	ids = test_df["PassengerId"].values
	test_df = test_df.drop(["Name", "Ticket", "Sex", "SibSp", "Parch", "Fare", "Cabin", "Embarked", "PassengerId"], axis=1)
#
	return ids,test_df
# --------------------------------------------------------------------------
# [8]:
def submit_proc(ids,output):
	file_submit = "titanic_submit.csv"
#
	dft = pd.DataFrame({'PassengerId': ids, 'Survived': output})
	dft.to_csv(file_submit,index=False)
# --------------------------------------------------------------------------
# [6]:
def predict_proc(train_data,test_data):
# Predict with "Random Forest"
	model = RandomForestClassifier(n_estimators=100)
	output = model.fit(train_data[0::, 1::], train_data[0::, 0]).predict(test_data).astype(int)
#
	return output
# --------------------------------------------------------------------------
sys.stderr.write("*** 開始 ***\n")

train_df = read_train_proc()

ids,test_df = read_test_proc()

train_data = train_df.values
test_data = test_df.values

train_df.to_csv("train01.csv")
test_df.to_csv("test01.csv")

output = predict_proc(train_data,test_data)

submit_proc(ids,output)

sys.stderr.write("*** 終了 ***\n")
# --------------------------------------------------------------------------
```

Submit した結果です。　0.622 です。

![kaggle_feb19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/394238af-8b4f-299b-db29-4f6fc0ddbcf9.png)
valueで設定している初期値が表示されないつまずき

# Before
```html
<ul>
    <li>{{name}}</li>
    <li><input type="date" v-model="start" value="2020-01-01"></li>
</ul>
```
`v-model`はvalueの値を無視するようです。
> v-model は任意の form 要素にある value、checked または selected 属性の初期値を無視します。

# After
```html
<ul>
  <li>{{contract.label}}</li>
  <li><input type="date" v-bind:value="2020-01-01" v-on:input="start = $event.target.value"></li>
</ul>
```
軸の増やし方

# pytorch
`unsqueeze()`を使う．

```python
a = torch.rand((3, 3))
a.size() # -> [3, 3]

a = a.unsqueeze(0)
a.size() # -> [1, 3, 3]

a = a.unsqueeze(1)
a.size() # -> [3, 1, 3]

```

# numpy
`reshape`, `newaxis`, `expand_dims`を使う方法がある．
`reshape`か`newaxis`を使えば複数同時に増やすことも可能．
`reshape`はめんどくさいから`newaxis`かな〜．

```python
a = np.random.normal(size=(3,3))
a.shape # -> [3, 3]

# reshape
b = a.reshape(1, 3, 3)
b.shape # -> [1, 3, 3]

c = a.reshape(3, 1, 3)
c.shape # -> [3, 1, 3]

d = a.reshape(1, *a.shape)
d.shape # -> [1, 3, 3]

# newaxis
b = a[np.newaxis]
b.shape # -> [1, 3, 3]

c = a[:, np.newaxis]
c.shape # -> [3, 1, 3]

# expand_dims
b = np.expand_dims(a, 0)
b.shape # -> [1, 3, 3]

c = np.expand_dims(a, 1)
c.shape # -> [3, 1, 3]
```
自分用　プルリク（PR）の際の注意点



自分が作成したブランチだけでなく、masterブランチの方のgitignoreファイルも編集する

コードが反映されない際、例えばgitignoreに記述しているのにファイルに差分が生まれてしまう際には.masterブランチの方の.gitignoreにも、gitignoreを編集する必要がある。

参考URL
https://wiseloan-cash.com/gitignore/
GCPのGPU付きのCompute Engine上で、Dockerの中で、Tensorflowを動かす方法。

GCPのGPU付きのCompute Engine上で、Dockerの中で、Tensorflowを動かす方法。作業メモ的な感じです。

実現できること

- GPU + TensorflowでDeep Learning
- 環境構築がかんたんで、いつでもゼロからやりなおしができる

## やり方

### Compute EngineでGPUとGPU Driver付きのインスタンスを作る

https://cloud.google.com/compute/docs/gpus/add-gpus?hl=ja
これに従うとできます。

Ubuntu 18.04で試してうまくいきました。

### Dockerインストール

https://qiita.com/myyasuda/items/cb8e076f4dba5c41afbc

### Tensorflowが動くdocker imageを動かす

```bash
docker run -it --rm tensorflow/tensorflow bash
```

参考 https://www.tensorflow.org/install/docker#gpu_support

## 参考資料

GCPでGPU付きのインスタンスを作る方法
https://cloud.google.com/compute/docs/gpus/add-gpus?hl=ja

compute engineのContainer optimizedイメージにnvidea driverを入れる方法。
https://github.com/GoogleCloudPlatform/cos-gpu-installer

dockerでtensorflowを使う方法
ホスト側にgpu driverさえ入っていれば動くらしい。
https://www.tensorflow.org/install/docker#gpu_support
【Git】GNU nanoエディタに閉じ込められたときの脱出法


初心者はターミナル以外のエディタの使い方がわからないのである。というか、「ターミナルがなんか違う感じになった！」くらいしかわからないのでエディタが変わったこともよくわからない。
そんな過去の自分が幾度となく泣かされたので、この通りにすればとりあえず何とかなる、というのを書いておきます。

##閉じ込められてしまった！

体感として、一番多かったのは`$ git commit --amend`ではないかなと思います。
このコミットをさっきコミットした分に含めたい、というときに使うコマンドです。
`--no-edit`というオプションを付ければ、勝手にエディタが開くことはありません。が、コミットメッセージを変更したいときもあります。オプションを付け忘れることもあります。
<img width="733" alt="スクリーンショット 2020-01-12 13.06.16.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/322882/4633d1cf-2b6e-63f0-679a-07a0f73a1e78.png">

### 特に変更しない場合

`^X`（control + X）を押せば、無事エディタを閉じてコミットできます。
エディタで特に操作をしなくても、ちゃんとコミットは統合されています。

### コミットメッセージなどを変更する場合

このように変更した状態で`^X`を押すと`Save modified buffer (ANSWERING "No" WILL DESTROY CHANGES) ?`と確認されます。
<img width="756" alt="スクリーンショット 2020-01-12 13.07.46.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/322882/ee3385f3-0a24-5183-4b37-ea477c033e1e.png">
変更を保存したいので、`Y`を押す。
<img width="762" alt="スクリーンショット 2020-01-12 13.08.14.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/322882/c6bb9950-c042-98e1-33a0-cc03f0d4d410.png">
この画面に戻るので、そのままエンターキーを押せば、変更を保存してエディタから脱出できます。

または、`^O`(control + O)で保存する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/322882/efb84030-0458-1f8b-0303-ca77d7e809af.png)
このような画面が出るのでエンターキー。その後`^X`でも脱出可能です。

## デフォルトエディタを変更する

gitのデフォルトエディタを変更する場合は`~/.gitconfig`、`~/.zprofile`などからできる。
Developers Summit 2020に参加して

毎年2月はDevelopers Summitに参加するのが当たり前になっています

この記事では、Developers Summitの概要、参加にあたってのアドバイスとどのセッションを聞いたかについて記します
セッションの詳細は別記事で投稿します


## Developers Summit とは

今年のサイトはこちら [Developers Summit 2020](https://event.shoeisha.jp/devsumi/20200213)
サイトを見ただけではピンとこないですよね
私自身の所感は、国内最大規模の開発系イベントで、開発のあらゆる分野のトレンドと知見を得られる、開発に関わっている人全員参加すべきイベントです
[タイムテーブル](https://event.shoeisha.jp/devsumi/20200213/timetable) を眺めているだけでワクワクしてきませんか？


## 参加するにあたって

#### 参加するセッションは前もっての登録が必要
参加するにはセッション事前登録が必要です
人気セッションはすぐ埋まります
当日飛び込み参加も可能ですが、それ用の列に並ぶ必要があるみたいです
なので、セッションの説明をよく読み、期待している内容なのかをしっかり調べて予定を組みましょう
聞きたいセッションがなければ、休憩スペースや、ブース、出張本屋巡りもできます
前もってのスケジュールを組んでおいたほうが絶対に実り多きデブサミとなります

#### すごく混む
休憩時間の会場から会場への移動は素直に出来ません
どのセッションもほぼ満席となり、会場からの退出も行列待ちとなります
会場間の通路も人で溢れかえり、素直に移動出来ません
入場待ちの列も何重となって出来ます
それなりの覚悟で参加してください

#### 個人スポンサーで参加する
個人スポンサー制度が出来てから、毎年そちらで参加しています
- 電源付きの個人スポンサー席が会場前方に一定数確保してもらえる
- 優先的に会場に入れる(==並ばなくて良い)
- 事前予約なしでもセッションに参加できる
の特典は、お値段以上の価値があります
お財布と相談して、許されるなら是非とも個人スポンサーでの参加を検討してください

一つ注意しておかないといけないのが、個人スポンサー席も数に限りがあります
人気セッションだと個人スポンサー席がなくなってしまいます
今年はt_wada氏のセッションでは、個人スポンサー席も満席でした


## どのセッションを聞いたか
私のメインの仕事はAWS環境での開発ですので、それに何かプラスとなる何かを得られるかを基準に選びました
また、就業場所も特に縛りがないので、そこら辺にもフォーカスされたものを選んでいます

### 2/13
|SessionID|Title|Speaker|
|:-----------------:|:------------------|:------------------|
|13-A-1|出勤から企業開発者を解放し、エンジニアの働き方改革を実現するリモート開発環境構築|増渕 大輔[日本マイクロソフト]|
|13-E-2|doda開発者が語る IoT＆サーバレスでビジネスサイド変革に挑戦した話～イノベ観点のダッシュボタン＆負債から進化したアーキテクチャ～|上源 勇朗[パーソルキャリア]|
|13-E-3|常識を破壊するティール組織とエンジニアリング組織論|片岡 俊行[ゆめみ]|
|13-B-4|質とスピード|和田 卓人[タワーズ・クエスト]|
|13-A-5|楽天がモノリス→マイクロサービス & オンプレ→クラウドで経験した光と闇|柳本 浩一[楽天]/新井 庸介[日本マイクロソフト]|
|13-D-6|テストエンジニアが教える　テストコードを書き始める前に考えるべきテスト|風間 裕也[ビズリーチ]|
|13-7|お仕事||
|13-8|お仕事||

### 2/14

|SessionID|Title|Speaker|
|:-----------------:|:------------------|:------------------|
|14-B-1|「ともにつくる」を実践するドメイン駆動設計|成瀬 允宣[GMOインターネット]|
|14-D-2|エンプラアジャイル導入の守破離|小俣 剛貴[Pivotalジャパン]/安西 結[Pivotalジャパン]|
|14-A-3|A retro on agile ー アジャイルをふりかえる|Jason Wong[Atlassian]|
|14-A-4|問題から目を背けず取り組んでいく ･･･ 一休のこれまで（仮）|伊藤 直也[一休]|
|14-B-5|グランブルーファンタジーを支えるサーバーサイドの技術|小松 美穂[Cygames]/大橋 庸[Cygames]|
|14-6|お仕事|||
|14-A-7|TOYOTA x Serverless x Microservices 〜 グローバル展開のコネクティッドカーを支えるアーキテクチャとエンジニアリングチーム|浦山 雄也[トヨタ自動車]/松本 崇之[トヨタコネクティッド]/内海 英一郎[アマゾン ウェブ サービス ジャパン]|
|14-C-8|雲の中心で愛を叫ぶ！ クラウド横断パネルディスカッション|濱田 孝治[クラスメソッド]/松村 優大[オルターブース]/高野 遼[クラウドエース]/【司会】近藤 佑子[翔泳社]|


全体を通しての所感ですが、とりたてて新しい知見は得られませんで
ですが、銀の弾丸はない、基本に立ち戻って目の前のことをひとつづづ対応していこうといったメッセージを頂きました
[Flutter] Unsupported operation: Cannot set value in unmodifiable Map の対処方法

## 何が起きた
Flutterで多言語化設定をしたかったので、次のようなコードを書いたところ、エラーが出ました。

```dart
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      supportedLocales: const [
        Locale('en'),
        Locale('ja'),
      ],
      localizationsDelegates: [
        GlobalMaterialLocalizations.delegate,
        GlobalWidgetsLocalizations.delegate,
        GlobalCupertinoLocalizations.delegate,
      ],
    );
  }
}
```

```sh
Unsupported operation: Cannot set value in unmodifiable Map
```

## 原因
次のようにアプリを起動していたのですが、どうも多言語化設定と`initializeDateFormatting()`が衝突しているらしく(多言語化設定時に、`initializeDateFormatting()`相当の処理が行われる)、これが原因でした。

```dart
void main() {
  initializeDateFormatting().then(
    (dynamic _) => runApp(MyApp()),
 );
}
```

## 対処方法
`initializeDateFormatting()`を呼び出すのをやめるだけで、解決します。


## 参考資料
[Flutterの多言語対応を試してみた | backport](https://backport.net/blog/2019/05/02/flutter_i10n/)
[Dart/Flutter での多言語対応あれこれ - Flutter 🇯🇵 - Medium](https://medium.com/flutter-jp/intl-beb5b9e8ee73)
[Issue with showDatePicker and locale · Issue #16304 · flutter/flutter · GitHub](https://github.com/flutter/flutter/issues/16304)