OmniAICreator/Qiita-1.07M huggingface dataset:
15日目。HTML&CSS初級編のコーディングをやってみました。

プロゲートもだいぶ進んできました！
###今日はHTML&CSS初級編のコーディングにチャレンジ。

まずは初心者マークの「ようこそ」を確認。
仕様書にしたがって見本と同じホームページを作る、というものです。
これができると、デザインしたページをホームページとして完成させることができるってわけですね！
課題は一度やったページなので簡単簡単・・・とおもったら、あれれ？
何が何だかわからないっ！

言われた通りに手取り足取り進めるのと一味違うって感じです。
いったん解説ページにもどって説明書をよく読みます。

###検証ツール（デベロッパーモード）の使い方
https://prog-8.com/docs/html-dev

ふむふむ・・・Chromeの「検証」を使うんですね。
カーソルを合わせるだけで、コードと画面が一対一対応しているところがわかる！
画面を見ながら簡単に見た目を変更できる！
画面と一対一対応でCSSがわかる！コードの入れ子構造がわかる！
状態変化がわかる！
すごいツールです。ってかこれ。ソースをコピペすれば完成するじゃん。

いやいやそれじゃつまらないので、手討ちにしてくれましょう。

「検証」で開くとコードの文字がちっちゃくて見にくいのでどうにかする方法を探しました。

####Chromeデベロッパーツールの文字サイズ拡大縮小・リセットする方法
https://tech.qookie.jp/posts/chrome-develop-font-size/

>デベロッパーツールの文字サイズ拡大縮小
* 		拡大：command + ^
* 		縮小：command + -
* 		リセット：command + 0
拡大はプラスじゃなくて右上の ~ キーだった。shift も使わない。なぜショートカットキーが異なるのかは分からないが、これを知らずハマっていた

ありがたや。どうにかなりました。
では早速！

#####ヘッダーを作ろう
10分で完成。ぴったりその通りにできているはずなんだけど、何回判定してもヘッダーリストの位置が違うってでる。何回みても数字はあっているはず。違いがさっぱりわからない。試しに見本のコードをコピペしたらこれは通った。何が違っていたんだろう。（30分）

#####トップ部分を作ろう
わーっと書いて、でも赤文字が赤くならなかったり，h2の文字が大きくならなかったりでつまずく。よく見たらタグが閉じていなかったり、一文字間違っていたり・・・汗 （15分）

#####コンテンツ部分を作ろう
①`<h1>`と`<h2>`はタグの外で`<div class=…>`でクラスを定義したのに`<h3 class=…>`とここはタグの中でクラスを定義。この違いがわからない。とりあえずコーディングする。
②イメージを４つならべたいのに、どうしても３つしか並ばず。Paddingを見直したら並びました！
(15分）

#####お問い合わせフォームをつくろう
①フォームの線、ボタンの背景の設定がわからず四苦八苦。
②何回やっても高さがあわない！と思ったら<div>の入れ子構造を一つ見落としていました。
（18分)

#####フッターを作ろう
コンテンツの中にフッターを作っているのに気がつくのに手間取った。
（10分）

###完成！
簡単そうに見えて結構大変でした。ふうふう。
http://appdays.herokuapp.com/Day15/
(所要時間 2時間)
OpenShiftMeetup#2に参加してきた

# 概要

ツイッター・ブログ枠で参加してきました。

ハッシュタグは#openshiftjpです。

conpassのURL： https://openshift.connpass.com/event/118831/

# 内容ざっくり

- ユーザー事例
- Roadmap
- AWX/Ansible Tower on OpenShift
- kubernetes networkの話
- kubevirt
- CodeReady Workspaces
- Prow
- JBoss EAP on OpenShift

# 所感

一番参考になった、というか勉強になったのはnetworkの話かな〜
ネットワークは畑違いにはけっこう辛いというかわからんから大変。
触り始めて1年くらいたって最近ようやく把握できるようになってきた。

CodeReadyはなんだかエンタープライズなお上の方々に受けがよさそうな製品だな〜と思った。
とりあえず最近またAWS触ってるのでOpenShift3.11入れる予定。
CodeReady、もといEclipseCheとあとProwあたり入れてみようかな。
プログラミング学習記録13〜コメントアウトは簡単にできる〜

##今日やったこと
- Udemyの「Web開発入門完全攻略コース - プログラミングをはじめて学び創れる人へ！未経験から現場で使える開発スキルを習得！」のセクション3の19~21

パートごとにとったメモです↓
####19.コメント
コメントの使い方に関する動画。
Atomでは「commandキー+/キー」で簡単にコメントのオンオフを切り替えることができます。
時短のために使いましょう。

####20.基本的なタグ
基本的がタグに関する解説動画。

タグの中で改行したい時

```html
<p>段<br>落１</p>
```
<br>
強調したい時

```html
<p><strong>段落２</strong></p>
```
<br>
斜体にする

```html
<p><I>段落３</I></p>
<p><em>段落４</I></p>
```

####21.文法チェック
HTMLの文法が間違っていないかは以下のサイトでチェックできます↓
(https://validator.w3.org/)

1. URLを打ち込む
2. HTMLファイルをアップロードする
3. HTMLのコードを直接打ち込む

の３種類の方法で文法間違えをチェックすることができます。

<br>
今日はあまり進みませんでしたが、明日からも引き続きプログラミング学習を頑張っていきます。

おわり
C# .NET Core RSACryptoServiceProvider でXML文字列形式の鍵を読み込む


## .NET Core では RSACryptoServiceProvider.FromXmlString メソッドで例外が発生します

.NET Core では RSACryptoServiceProvider クラスの FromXmlString / ToXmlString メソッドがサポートされていません。PlatformNotSupportedException がスローされます。

```c#:秘密鍵の読込
// using System.Security.Cryptography;

var privateKey = "<RSAKeyValue><Modulus>yT12/iqZLN....Q==</D></RSAKeyValue>";
var rsa = new RSACryptoServiceProvider();

// ここで PlatformNotSupportedException がスローされます。
// 'Operation is not supported on this platform.'
rsa.FromXmlString(privateKey);
```

## 対処法

FromXmlString / ToXmlString の代替メソッドを公開している方がいらっしゃいました。
[【GithubGist】Jargon64/RSACryptoServiceProviderExtensions.cs](https://gist.github.com/Jargon64/5b172c452827e15b21882f1d76a94be4/)

```c#
var privateKey = "<RSAKeyValue><Modulus>yT12/iqZLN....Q==</D></RSAKeyValue>";
var rsa = new RSACryptoServiceProvider();

// 鍵を読み込むことができます。.NET Core 2.1 で確認。
// シグネチャが同一である場合は拡張メソッドではなく本体に実装されているメソッドが優先されるため、メソッド名は変更しました。
rsa.FromXmlStringEx(privateKey);
```
ChromeでJupyer-labをDebugする方法

###  正確には、Jupyter-labの拡張機能を作成するときにchrome上でデバッグする方法となります。

## 背景
Jupyter-labに関するドキュメントがまだまだ少ない。
インターンシップで触ったのでその記録のために

## 必要なもの
chrome
VSCode
jupyter-lab 0.33.12
Debugger for Chrome(vscodeの拡張機能)

## 手法
- 準備
デバッグしたいファイルの何処かにconsole.logを入れて出力を確認できるようにしておく(任意)
- Jupyter-labをwatchモードで開く
- 拡張機能を開発してるローカルフォルダのルートディレクトリちょっかに.vscode/launch.jsonというファイルを作成する。これがデバッガーの設定ファイル。
- 内容はこんな感じ（環境によって変わります）

```json
{
    "version": "0.1.0",
    "configurations": [
      // ローカルにあるファイルをデバッグ
      {
        // デバッグ設定の名称
        "name": "Launch local file",
        // デバッグ種別を指定（chrome/node/monoなど）
        "type": "chrome",
        // lanunchまたはattachを指定
        "request": "launch",
        //URL
        "url":"ここにjupyer-labで起動したlocalhostから始まるurlを入れる",
        // 読み込むHTMLファイルを指定（プロジェクトからのパスを指定）
        "webRoot": "${workspaceFolder}",
          "sourceMapPathOverrides": {
            "webpack:///..//../../../*": "${webRoot}/src/*"
          }
      }
    ]
}
```

- 拡張機能のフォルダ内でnpm run buildをする
- VSCode上でshift+command+Dを押してデバッグ画面を開く。console.logのところにブレイクポイントをおいて、左上の再生マークでプログラム実行する
- chromeが新たに起動して、Jupyterlabが開く、デバッグしたい拡張機能を実行すると　VSCODEの方のコンソールログに出力がされるのでその右端にあるファイル名をクリックすると、VSCODE上でそのコードのところに飛べる。後は気になるところにブレイクポイントをおいてステップを進める。
- コードを修正したときは、一度デバッガを終了してからコードを修正して、npm run buildをしてからデバッガをもう一度起動する


何か疑問があればコメント欄にてお願いします。
xrdp + Windows7 ではまった件

# 起こったこと
xrdp(http://www.xrdp.org/) を CentOS に yum で何も考えずにインストールしたら、Windows7からつながらなくて怒られた
(xrdp-0.9.8-2.el7 です)

# 解決法
/etc/xrdp/xrdp.ini を下記のように変更する

変更前:
security_layer=negotiate
変更後:
security_layer=rdp

なお、Windows10はデフォルト設定の security_layer=negotiate でつながるので Windows10 しか使わない場合はセキュリティ的にデフォルト設定のままのほうがよいと思われます
Ruby$_の意味と競プロでの実例

> variable $_ 
最後に Kernel.#gets または Kernel.#readline で読み込んだ文字列です。

https://docs.ruby-lang.org/ja/latest/method/Kernel/v/_.html

AOJで
http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=ITP1_4_C

http://judge.u-aizu.ac.jp/onlinejudge/review.jsp?rid=3405210#1

```
puts eval($_.chomp) while !gets["?"]
```


# 参考

- [AOJ](hhttp://judge.u-aizu.ac.jp/onlinejudge/index.jsp)

# 次にやること

AOJ解き直す
RailsでCSVファイルのデータをDBに取り込む

これまで「CSVファイルのデータを取り込んで表示する」という経験がなかったのですが、とある課題の中で必要になったので備忘録。

Ruby 2.5.1
Rails 5.2.2

##RubyのCSVライブラリを利用する
「使いたい/欲しいと思った機能は大抵既に実装されている」みたいなことは勉強していく中でよく聞く言葉だが、CSVファイルを扱う機能もそれに違わず実装済み。

https://docs.ruby-lang.org/ja/latest/library/csv.html

CSVライブラリはその名の通りCSVファイルを扱うライブラリ。

CSVライブラリには例外クラスも含めると5つのクラスがあるが、今回は割愛。

##CSVクラス
https://docs.ruby-lang.org/ja/latest/class/CSV.html

>このクラスは CSV ファイルやデータに対する完全なインターフェイスを提供します。

CSVにあるデータを取り込む場合には、CSVクラスを使う。

CSVクラスには特異メソッドとして以下のものがある
`filter` `foreach` `generate` `generate_line` `instance` `new` `open` `parse` `parse_line` `read` `readlines` `table`

```:特異メソッドとは
クラスではなくある特定のオブジェクトに固有のメソッドのこと
```

###CSV.foreachメソッドでCSVファイルを読み取る
CSVクラスにはCSVファイルを読み込んだり書き込んだりする特異メソッドが複数あるが、CSVファイルを読み込む場合は主にCSV.foreachを使う

```:CSV.foreachメソッド
foreach(path, options = Hash.new) {|row| ... } -> nil**
->CSVの各行が、与えられたブロックに渡される
```

**・path**
CSVファイルが格納されているパスを指定する。

```:相対パス
相対パスとは、起点となる位置からみたディレクトリ及びファイルの表現方法。
起点となる位置から階層を1つ上がる場合には`../`を使い、特定のディレクトリに入る場合には`ディレクトリ名/`を使う
```

**・options**
CSV.foreachのオプションには、CSV.newと同じオプションを取ることができる。
-> https://docs.ruby-lang.org/ja/latest/method/CSV/s/new.html
特に使うケースが多そうなのがheadersオプション。

以下[リファレンスマニュアル](https://docs.ruby-lang.org/ja/latest/method/CSV/s/new.html)からの引用です。
>:first_row というシンボルか真を指定すると、CSV ファイルの一行目をヘッダとして扱います。

headers: trueをオプションに渡せば１行目はヘッダとして読み込まないようになる。
CSVファイルでは１行目には各カラムの名前などを入れるケースも多いので、このオプションを使うことも多そう。

##db/seeds.rbでCSVファイルを読み込ませ、データを取り込む
CSV.foreachでCSVファイルのデータを取り込めるようになったら、そのデータをseeds.rbからデータベースに取り込む。

CSV.foreachメソッドではCSVのデータを１行ずつブロックに渡していくので、以下のようなコードで対応するテーブルに値を渡す。

```:user.csv
ID, Name, Email, City
1, Sato, hoge@example.com, Tokyo
2, Suzuki, foo@example.com, Osaka
3, Tanaka, bar@example.com, Fukuoka
```

```ruby:db/seeds.rb
require 'csv'

CSV.foreach(*path, headers: true) do |row|
  User.create(
      username:     row['Name'],
      email:        row['Email'],
      city:         row['City']
  )
end
```
上記のコードで、CSVのデータがDB上に読み込みできるようになる。
ここまで書いたら`bin/rails db:seed`でデータを読み込ませれば完了。

他に何か方法あるのかも調べたい。
【Handsontable】別セルの値に応じてドロップダウンリストを連携させる

#概要
県名→市町村名等、前のセルの入力値に応じて後ろのセルのドロップダウンリストを変えたい場合の対応方法を記述する。
以下のコード例で、1列名のメーカー名の値に応じて、2列目の車種名の選択肢が変わる例を紹介する。

#コード例
<p class="codepen" data-height="500" data-theme-id="0" data-default-tab="js,result" data-user="hk0n" data-slug-hash="OqMQrw" style="height: 110px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid black; margin: 1em 0; padding: 1em;" data-pen-title="OqMQrw">
  <span>See the Pen <a href="https://codepen.io/hk0n/pen/OqMQrw/">
  OqMQrw</a> by HK0n (<a href="https://codepen.io/hk0n">@hk0n</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

#コード説明
以下3つの要素を利用している。

* afterChange
* setDataAtCell
* setCellMeta


##afterChange
https://handsontable.com/docs/6.2.2/Hooks.html#event:afterChange
セルのデータが変更された場合のイベント。
"changes"には[["変更された行","変更された列","変更前の値","変更後の値"]]という形でデータが格納されている。
今回は、変更された列が車種(1列目(changes[0][1]=0))の場合に、後述のsetDataAtCellとsetCellMetaを実行する。


##setDataAtCell
https://handsontable.com/docs/6.2.2/Core.html#setDataAtCell
セルのデータが書き換えるためのメソッド。
>setDataAtCell("対象の行","対象の列","書き換える値")

コード例では、メーカー名が変わった場合に、車種の値を空白にする処理を入れている。
これが無いと、メーカー名、車種名を入力した後にメーカー名を変更した場合、意図しない組み合わせになってしまう。
(無い場合の例)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/162686/42949121-aafb-f0ad-4a73-40afd67ce548.png)![image.png](https://qiita-image-store.s3.amazonaws.com/0/162686/e5a9e712-4d37-1c15-4820-d77b83efe7d5.png)

##setCellMeta
https://handsontable.com/docs/6.2.2/Core.html#setCellMeta

セルのメタデータを書き換えるためのメソッド。
>setCellMeta("対象の行","対象の列","対象のプロパティ名","変更後の値")

コード例では、メーカー名の値に応じて車種のselectOptionsを書き換える処理を行っている。
Linux PC内のパケット経路を確認するならip route getで

## はじめに

Linuxでルーティングを確認する際によく使うのはtracert, tracepathだと思います。
が、実際に知りたい経路ってPC内の外に出るまでの経路が知りたい場合の方が個人的には多いんですよね。
ググっていつも引っかかるのは`tracert`, `tracepath`だったりしますが、こちらはPCから抜けた先がメインなのでちょっと違う。

そんな時用のコマンド、以前に一時期使ってから忘れてしまって困ってたんですが、今日再び発見したので覚書

## 自PC内のルーティングが知りたい、そんな時には`ip route get`

使っていたコマンドはこれです。`ip route get IPアドレス`。
こんな感じでどのデバイス・アドレス宛にルーティングが組まれているかが分かります。

```
$ ip route get 192.168.1.233
192.168.1.233 dev br0 src 192.168.1.1
```

## Androidのように細かなルーティングを組んでるシステムだと便利

Android OS上のルーティングって、ip routeのルーティングだけじゃなくip ruleを組み合わせた構成になっています。
通常は意識しないからいいけど、ここに自前でローカルネットワークを追加しようとなるとすぐ「あれ？この場合はどこに抜けるんだ？」みたいになりがち。

`tracert`でも追えなくはないけどnetwork unreachableになると追いにくかったりしたので、単純に「このIPはどこに抜けるのか？」が分かるこのコマンドが非常に便利でした。
インドの郵便番号APIを作ってみた

GitHub Pagesの力を借りて超いい加減インド郵便番号APIを作りました。たくさんの人に使ってもらいたいという思いは全くありません。使ってもいいですけど。

GitHubにプロジェクト作ってありますので使い方はこちらのREADMEを読んでください。

https://github.com/yuigahamak/postcode

仕様はREADME読んでもらって、以下は作ってみた日記です。技術的なことは全く書いていません。暇な人は読んで時間を無駄にしてください。

インド郵便番号APIを探す
----

これが見つからないんすよ！なんかいくつかあるんだけど役に立ちそうにない。今回はクライアントからJSで取得したかったのでCORSに対応しているAPIが必要なのだが見つからない。というかCORSじゃなくても使えそうなのはほとんどない。インドどうなってるんじゃー。

まともにデータが返ってくるAPIはこれ（[http://postalpincode.in/Api-Details](http://postalpincode.in/Api-Details)）ぐらい。でも郵便番号から郵便局を探すAPIのようで同じ郵便番号でも郵便局の数だけデータがある感じ。そしてCORSに対応していない。


じゃあ作るよ
----

あきらめて作ることにしました。日本の郵便番号検索は以下のようなものがありましてGitHub Pagesで費用ゼロで運用している。素晴らしい、これを真似よう。

https://github.com/madefor/postal-code-api

作ってみた
----

インドの郵便番号データは下記のサイトで入手しました。

https://www.geonames.org

中身をみると同じ郵便番号の行が複数あってなんかおかしい。どうも上に書いた郵便局APIのデータを使っているみたい。なので郵便番号6桁なのにリストは15万件以上ある。

データを設計するにあたってインドの住所に対する理解を深めようと、住所と郵便番号のリストをたっぷりと睨んだが、全く意味がわからない。インドって難しいな…

ファイル15万件も作成してデプロイするのがいやなので、郵便番号の上3桁毎にファイルを作成することにした。これなら郵便番号が100から始まるとして最大で900件なので扱いやすいだろう。

だいたい考えがまとまったので手書きで一つファイルを作成してGitHub Pagesにデプロイしてみる。CORSどうするのかと思ったらGitHub Pagesからのレスポンスは全てレスポンスヘッダに「access-control-allow-origin: * 」が付いているっぽい。今回は助かったけどそれでいいのか？

ファイル作成するスクリプトもJSで作ってブラウザから操作するようにしてみた。JSでローカルファイルを扱うのは初めてだったけど、これは面白いぞ。なんか可能性を感じたっす。ファイルを何百個も一度に作成しようとしたら途中で止まってしまったのでsetInterval()で0.5秒毎にファイル作成（ダウンロード）という謎ハックで切り抜け、403個のJSONファイルが誕生しました。こいつらをGitHubにプッシュして完了じゃー。いやーいい汗かいてない。

反省
----

JSONのサイズが大きい。郵便番号上3桁でまとめたので一番大きいファイルは303KBもある。そこらの画像ファイルより全然大きいよ。改善策は思いつくが、時間が惜しいのでやりません。ごめんなさい。

そして結局役に立つのかこれ？というところ。インドの住所の仕組みがよくわからない。州と県まではいいんだけどその先は使えそうにない。インド広すぎる。州の一つ一つが人口も面積も普通の国サイズ。郵便番号6桁じゃ無理でしょ。郵便番号体系の見直しが必要や。日本でも20年ぐらい前にありましたよね。

そしてさらにこのAPIのデータは信用できるのか？というところ。データを更新する仕組みを作ってないのでなんつうかいい加減すぎるだろと我ながら思います。

なんか締らないけれどこの辺で了。ありがとうございました。
プルリクエストした複数コミットをsquash(rebase -i)でまとめた話

## 経緯
とある有名ツールに小さな機能追加を提案したときのお話。
typoがあり（ひどい）、コーディングルールにも気づかず（論外）、ありがたくあたたかい指摘を複数回頂いた後、コミットのsquashを頼まれた。

## 手順
強い人には常識かもしれないけど、具体例を交えて弱い人に共有したい。
以下、最新の2コミットをまとめた手順です。

1. git rebase -i HEAD~2
1. エディタ上部に並ぶコミットの一番上以外のpickをsに変更して保存
1. コミットメッセージをよしなにまとめて保存
1. git push origin ブランチ名 -f
1. 同じ方法でプルリクエスト

これでまとまりました。
最新のnコミットをまとめたいときは、手順1. のHEAD~2をHEAD~nに変えればいいと思います。

## まとめ
日本人同士で英会話してた（たぶん）
Python-Selenium-Chrome でユーザープロフィールを指定してChromeを起動させたい


Python-Selenium-Chromeで、下記のページを参考に、既にChrome上で設定済みのユーザープロフィールを指定してChromeを起動させたいです。

【参考ページ】
[Python + Selenium + Chrome で自動ログインいくつか](https://qiita.com/memakura/items/dbe7f6edadd456da1c5d)
の『既存のユーザプロファイルを使う』の部分

しかし、以下のようなコードでChromeを起動させると、下記のエラーが出てしまいます。

何が原因か、ご教示いただけたら幸いです。
よろしくお願い致します。

```
from selenium import webdriver

chrome_user_data_dir_path = 'C:\\Users\\[UserName]\\AppData\\Local\\Google\\Chrome\\User Data'
chrome_user_profile_directory = 'Profile 1'
options = webdriver.ChromeOptions()
options.add_argument('--user-data-dir=' + chrome_user_data_dir_path)
options.add_argument('--profile-directory=' + chrome_user_profile_directory)
browser = webdriver.Chrome(options=options)
```




```
[14396:9608:0301/174908.325:ERROR:cache_util_win.cc(19)] Unable to move the cache: 0
[14396:9608:0301/174908.328:ERROR:cache_util.cc(140)] Unable to move cache folder C:\Users\[UserName]\AppData\Local\Google\Chrome\User Data\ShaderCache\GPUCache to C:\Users\[UserName]\AppData\Local\Google\Chrome\User Data\ShaderCache\old_GPUCache_000
[14396:9608:0301/174908.329:ERROR:disk_cache.cc(184)] Unable to create cache
[14396:9608:0301/174908.333:ERROR:shader_disk_cache.cc(622)] Shader Cache Creation failed: -2
Traceback (most recent call last):
  File "create_new_account.py", line 105, in <module>
    browser = webdriver.Chrome(options=options)
  File "C:\Users\[UserName]\Anaconda3\envs\py37\lib\site-packages\selenium\webdriver\chrome\webdriver.py", line 75, in __init__
    desired_capabilities=desired_capabilities)
  File "C:\Users\[UserName]\Anaconda3\envs\py37\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 156, in __init__
    self.start_session(capabilities, browser_profile)
  File "C:\Users\[UserName]\Anaconda3\envs\py37\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 251, in start_session
    response = self.execute(Command.NEW_SESSION, parameters)
  File "C:\Users\[UserName]\Anaconda3\envs\py37\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 320, in execute
    self.error_handler.check_response(response)
  File "C:\Users\[UserName]\Anaconda3\envs\py37\lib\site-packages\selenium\webdriver\remote\errorhandler.py", line 242, in check_response
    raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.InvalidArgumentException: Message: invalid argument:
user data directory is already in use, please specify a unique value for --user-data-dir argument, or don't use --user-data-dir
```

【バージョン】
OS：Windows 7（64 ビット）
Python 3.7.0
Chrome:72.0.3626.119（64 ビット）
Qiitaのページング仕様が変わった

タグで検索したときの記事一覧のページングが、これまでのRESTで`items?page=2`のようにページ遷移する方式から、GraphQLを使って動的に書き換える方式に変更になった。

![01.png](https://qiita-image-store.s3.amazonaws.com/0/26088/771fbc42-502a-1ee6-bd7c-4f36176c6ffa.png)

そのこと自体はまあいいのだが、それに伴い多大な不都合が発生した。

・適当に[タグで検索](https://qiita.com/tags/javascript)。
・次ページへの遷移ボタンを10連打。
・適当な記事を表示
・ブラウザバック

1ページ目に戻る。

さっきまで11ページ目を見てたんですけど？
続きを見るには10回クリックしなおさないといけないんですけど！！

何も考えずSPA化したときの典型的な弊害じゃん。
`history.pushState`って突っ込むだけで回避できるのに。
新技術の導入によってユーザエクスペリエンスが劣化するのって、ほんと技術者の自己満足でしかないよね。

さらに、これまで使用されていた`https://qiita.com/tags/javascript/items?page=2`のようなURLは早々に使用できなくなっている。
つまり、2ページ目以降を直接URL指定で表示する方法がない。

スラドにも[ずっと前から言ってる](https://srad.jp/~hylom/journal/608701/)んだけどさ、どうして普通のページングを用意してくれないんですかね[^1]。
そんなに古い記事は見せたくないんですかね。


あと記事タイトル長によって『次ページ』ボタンの位置がずれるから、次ページに行くつもりでうっかり記事を押して死ぬ可能性もある。
1記事の縦の長さを固定するか、ボタンの位置が一定になるよう調節するか、一覧の上にもボタンを付けるなどしたほうがいいだろう。


ちなみに一番見せたくないんじゃないかと思っている[全記事一覧](https://qiita.com/items)は、いまだ[直接ページ指定](https://qiita.com/items?page=2)に対応している。





[^1]: スラドは[改善される予定](https://test.srad.jp/)。
MySQLとPostgreSQLのALTER TABLEによるカラム型変更時の既存レコードの扱いの違い

どっちがどっちか忘れるので

#  問

`ALTER TABLE`後の型に変更前のレコードが相応しくない場合にどうなるか。

# <i class="fa fa-graduation-cap" aria-hidden="true"></i> 結論

* MySQLはキャストを行う。(文字長なら切り詰めを行う)
* PostgreSQLはエラーを吐く

# <i class="fa fa-cogs"></i> 検証環境

```
mysql --version
mysql  Ver 14.12 Distrib 5.0.67, for unknown-linux-gnu (x86_64) using readline 5.1

psql --version
psql (PostgreSQL) 9.2.18
```

# <i class="fa fa-code"></i> コマンド

```
mysql db -e "ALTER TABLE users CHANGE username username varchar(100) not null;"
# 30文字以上のユーザー登録
mysql db -e "ALTER TABLE users CHANGE username username varchar(30) not null;"
# エラーなし(ユーザー名は30文字まで右辺切り捨て)

psql db -c "ALTER TABLE users ALTER COLUMN username TYPE varchar(100);"
ALTER TABLE
# 30文字以上のユーザー登録
psql db  -c "ALTER TABLE users ALTER COLUMN username TYPE varchar(30);"
ERROR:  value too long for type character varying(30)
# ユーザー削除
psql db  -c "ALTER TABLE users ALTER COLUMN username TYPE varchar(30);"
ALTER TABLE
# または、明示的なキャストを行うと、mysqlのように切り詰められる
psql db  -c "ALTER TABLE users ALTER COLUMN username TYPE varchar(30) USING username::varchar(30);"
ALTER TABLE
```


# <i class="fa fa-book"></i> 参考

検索ノイズが多めだったのでここに残すことが目的

* [MySQL :: MySQL 5.6 リファレンスマニュアル :: 13.1.7 ALTER TABLE 構文]

>
CHANGE または MODIFY を使用してデータ型を変更すると、MySQL は、既存のカラム値を新しい型にできるだけ変換しようとします。
警告
>
この変換によって、データが変更される可能性があります。たとえば、文字列カラムを短くすると、値が切り捨てられる可能性があります。新しいデータ型への変換によってデータが失われる場合は操作が成功しないようにするには、ALTER TABLE を使用する前に厳密な SQL モードを有効にします (セクション5.1.7「サーバー SQL モード」を参照してください)。


* [PostgreSQL 8.4.4文書 テーブルの変更]

>これは、その列の既存の項目が新しい型に暗黙的キャストにより変換できる場合にのみ成功します。 より複雑な変換が必要な場合、古い値から新しい値をどのように計算するかを指定するUSING句を付けることができます。 

切り捨てはしてくれても良さそうだけど。

[PostgreSQLで管理するカラムの型変換（CAST）に関するメモ - QuzeeBlog@Hatena]
など

[MySQL :: MySQL 5.6 リファレンスマニュアル :: 13.1.7 ALTER TABLE 構文]:https://dev.mysql.com/doc/refman/5.6/ja/alter-table.html
[PostgreSQL 8.4.4文書 テーブルの変更]:https://www.postgresql.jp/document/8.4/html/ddl-alter.html


[PostgreSQLで管理するカラムの型変換（CAST）に関するメモ - QuzeeBlog@Hatena]:http://quzee.hatenablog.com/entry/2016/09/21/163217
SW4STM32でFPUによる単精度浮動小数点演算を行う

# はじめに
ARM Cortex-M4FシリーズのMCUは単精度のFPUを搭載していて，浮動小数点演算を行うことができる．

Cortex-M4FシリーズであるSTM32マイコンをSystem Workbench for STM32 (SW4STM32)で扱うときに，FPUを使って演算を行うためのメモ．

なお，環境はmacOS Mojave，SW4STM32 v2.8．ボードはNucleo F411REとした．

また，C Standard Libraryのmath.hを使うこととする．

# 環境整備
まず，SW4STM32でFPUを使うための設定を行う．

## MCU設定
Project Explorerでプロジェクトを選択し，メニューバーの"Project">"Properties"をクリックする．

"C/C++ Build">"Settings"をクリックする．

"MCU Settings"にて，"Floating point hardware"を"fpv4-sp-d16"に，"Floating-point ABI"を"softfp"に設定する．


![Screenshot 2019-03-01 at 19.00.38.png](https://qiita-image-store.s3.amazonaws.com/0/320451/5daef063-d006-22f2-e447-f9a265ed955e.png)

## リンカ設定

C Standard Libraryのmath.hを使うため，"MCU GCC Linker">"Libraries"にて，"m"を追加する．
(本来は"-lm"だが，"-l"は自動的に付加される)

![Screenshot 2019-03-01 at 19.04.10.png](https://qiita-image-store.s3.amazonaws.com/0/320451/093fc79f-1f49-20e9-8b2b-01f398c2c8cd.png)

# コーディング
## math.hのインクルード
これはいつもと同じ．

```c:main.c
/* Private includes ------------------------------------------*/
/* USER CODE BEGIN Includes */
#include <math.h>
/* USER CODE END Includes */
```

## 演算部分
演算するコードを書く際は，**扱う全ての値をfloatにする**こと．

数値リテラルは，末尾にfをつけておく．例えばfを付けずに100.0と記述すると，doubleとして演算されてFPUが使われない．当たり前だが，定数はdefineではなく，const floatを使えば自動的にfloatになるので安心である．

もちろん変数はfloatにする必要があるが，関数もfloatを返すものにする．例えば正弦関数ならsinf()となる．

```c:main.c
// Global ///////////////////////////
// 定数はconst floatが無難．
const float Scale = 0.5;
// #defineを使う場合は以下．
// #define Scale (0.5f)

// 変数ももちろんfloatにする．
float SinTable[500];

// main /////////////////////////////
// 円周率は"M_PI"で定義される．
const float dt = 2.0f * M_PI / 500.0f;
for( uint32_t i = 0; i < 500; i++ ){
    // sinはsinfなど単精度のものを使う．
    SinTable[i] = 100.0f * sinf( dt * i );
}

/////////////////////////////////////
// 定数にはfをつける．
float result = Scale * SinTable[10] + 100.0f;
```

# FPUが使われていることの確認
SW4STM32に逆アセンブルリストを吐かせることで，FPUが使われているかを確認することができる．

[SW4STM32で逆アセンブルリストを出力する - Qiita](https://qiita.com/BitPositive/items/54bd368116c8a61da76c)

生成された逆アセンブラリストを開き，Cのソースに該当する部分のアセンブラ命令を確認する．

例えば，VMUL，VMLA，VMLS，VNMUL，VNMLA，VNMLSなどは浮動小数点乗算および積和を行う命令であるから，以下のようになった場合，FPUを使った演算が行われていることが確認できる．

![Screenshot 2019-03-01 at 19.38.49.png](https://qiita-image-store.s3.amazonaws.com/0/320451/cbf5b187-637a-3ab5-93f0-e854c344f9af.png)

以上．
Access VBA コードモジュールのプロシージャ一覧を取得する

[すべてのプロシージャ名を取得する例 officetanaka ](http://officetanaka.net/excel/vba/vbe/05.htm)
このExcelをAccessに変えたものです

```vb
 Sub AccexportFunction()
Dim buf As String, ProcNames As String, i As Long
Dim VBCs As VBComponents, VBC As VBComponent
Set VBCs = Application.VBE.ActiveVBProject.VBComponents
With VBCs("Module/Class").CodeModule '<<<標準モジュールやClassの名前を入れます。
        For i = 1 To .CountOfLines
            If buf <> .ProcOfLine(i, 0) Then
                buf = .ProcOfLine(i, 0)
                ProcNames = ProcNames & buf & vbCrLf
            End If
        Next i
End With
Debug.Print ProcNames
End Sub
```
SoXコマンド覚書

# 手軽に形式変換したい

音声認識を行う際、ビットレートやサンプリング周波数や形式などを考えなくては正確な結果が出ません。というかそもそもアルゴリズムが叩けなかったりします。

なので当然集音に際してはそこを合わせるわけですが、既存音源を無理やり変換してやってみよう（みろ）なんてことも、仕事をしてるとあります。そんな時 [Audacity](https://www.audacityteam.org/) などのソフトでちまちまやるのは大変です。

ということでちょっと探したら`sox`というコマンドがあったので覚書。

# SoXとは
 
[SoX](http://sox.sourceforge.net/sox.html)  : Sound eXchange, the Swiss Army knife of audio manipulation  

→ 手軽に音声ファイル変換できるコマンド


# 操作
 
### sox基本コマンド

- wavからrawに変換

```
$ sox input.wav output.raw
```

### sox形式指定コマンド

- `-b`でbit指定 / `-r` でサンプリングレート指定 / `-c` でチャンネル数（ステレオ・モノラル）指定

```
$ sox input.wav -b 16 -r 16000 -c 1 output.raw
```

### ディレクトリ内まとめて変換

- `find`コマンドと併用すると便利

```
$ find . -name "*.wav" -exec sox -b 16 -r 16000 -c 1 {} {}.raw \;
```

#### ※ findで検索した結果を利用する

- `-name`でクエリ指定、`-exec`以降に実行したいコマンド、実行対象の場所には`{}`を書く
- まとめて`curl`でAPI叩くなんて時に使えます

```
$ find raw -name "*.raw" -exec <command> {/* here is the result */}
```

 
## 参考
 
https://qiita.com/mountcedar/items/a04ebc4f8c27c226bbff
https://qiita.com/scapegoat_11_/items/abedab01d099f536e2a0
https://qiita.com/kaz-mintan/items/aea24072d3901a060c0e
http://www.xucker.jpn.org/pc/sox_raw.html
https://eng-entrance.com/linux-command-find
ノスタルジアpc-9801 その9

#概要

整理していたら、フロッピーディスクが出てきた。
せっかくなので、エミュで動かしてみた。

#環境

- windows vista
- t98-next
- disk explorer

#n88basicでマンデルブロ表示

![ma.jpg](https://qiita-image-store.s3.amazonaws.com/0/18104/a8771570-c433-7ff5-d2aa-c82e49864217.jpeg)

#サンプルコード

```
100 DEFSNG A-Z
110 CLS 3
120 KS = 400
130 RST = -1.9
140 RED = .5
150 IST = -1.35
160 IED = 1.35
170 WINDOW (RST, -IED) - (RED, -IST)
180 DR = (RED - RST) / KS
190 DI = (IED - IST) / KS
200 FOR CR = RST TO RED STEP DR
210  FOR CI = IST TO IED STEP DI
220   ZR = 0:ZI = 0
230   FOR K = 1 TO 7 
240    R = ZR * ZR - ZI * ZI + CR
250    I = 2 * ZR * ZI + CI
260    IF (R * R + I * I) > 4 THEN PSET (CR, CI), K:K = 7
270    ZR = R:ZI = I
280   NEXT
290  NEXT
300 NEXT
```


以上。
openCV pythonチュートリアルの画像中の注目領域(ROI)において

opencv チュートリアル　[「画像上の基本的な処理」](http://labs.eecs.tottori-u.ac.jp/sd/Member/oyamada/OpenCV/html/py_tutorials/py_core/py_basic_ops/py_basic_ops.html#basic-ops
)のチュートリアル内の

画像中の注目領域(ROI)におけるNumpyのインデックス指定で少し戸惑ったので備忘録書きます。

>ball = img[280:340, 330:390]
img[273:333, 100:160] = ball

[opencvは左上原点らしく](https://kazunori-ohmori.blog.so-net.ne.jp/2014-02-04)、なので
![animal_syougarago.png](https://qiita-image-store.s3.amazonaws.com/0/209670/6bbe1b88-bc6d-42ad-4ccb-ef72c546e604.png)
この画像だとimg[Xa:Ya,Xd:Yd]だと勘違いしました。
実際はimg[Ya:Yd,Xa:Xd]だったみたいです。

チュートリアルで実行してると？？？となったので書いときます。

以上！
2019年の今 Mithril.js を使うためのTips

最近めっきり話を聞かなくなったJSフレームワーク、 Mithril.js に関する Tips をつらつらと書いていきます。
決して下火になったわけじゃあないんです。

## Mithril.js とは
https://mithril.js.org/

いわゆる仮想DOMフレームワークの一つ。メジャーな React や Angular と比べ、軽量・シンプル・高速なことを謳う。

フレームワークの機能としては、React, Vue と比べても決して不足していないうえ、実際のプロダクトにも採用例があり十分ポテンシャルはある。はずです。

前述の通りバズってはいないですが、現在も活発に開発が続けられており、[Ver.2のリリースも予定されています](https://mithril.js.org/change-log.html#v200-rc)。

### Mithril 情報を集めるために
重要な点として、Mithril は **v0.2 系と v1.x 系で大きくAPIが異なっています**。 v1.xの方が正式となり、v2でも大きな変更は入らないようなので、この点だけは覚えておいてください。

早い話が、 Controller あるいは m.props が話題に出る記事は **古いです**。これからは参考にしてはいけません。

じゃあどうなったかと言うと、現在はよりシンプルかつ賢くなって、m.props を使わずとも変更が検知されるし、controller を使わずともライフサイクルに応じたフック処理を実行できます。より簡単かつ高速になった純粋な上位互換と言えるものなので、この点でも今から v0.2 系の知識を仕入れる意味はありません。

ここまで分かればあとは公式サイトなり、新し目の記事なりを漁って導入は出来るかと思うので、そのフェーズは他の記事に譲ります ~~手抜きともいう~~ 。

以下は使っていく上で気づいたポイントを書き連ねたものです。

## vdom.state は使わない
基本的に view に state をもたせるのは99%アンチパターンです。状態に類するものは model のオブジェクトとして分離し、 view 側ではそれを読みに行くだけにしましょう。

例: テーブルの各列コンポーネントに状態をもたせるのではなく、元データにその状態をもたせて、コンポーネントは filter をかけるなどして出し分ける。

## arrow function 最強説
arrow function はどんどん活用しましょう。

```js
// 普通に書いてみる
const Component = {
  view: function(vdom) {
    // ...
  }
}

// arrow function で書いてみる
const Component = {
  view: vdom => {
    // ...
  }
}

// 値を返すだけのfunctionはもっと短くできる
const Component = {
  view: v => m("button", { onclick: model.incCount }, "+1"),
}
```

これに加えて `map` `filter` `reduce` などのメソッドや、三項演算子を組み合わせることでよりコンポーネントをスマートに書けます。楽しくかっこよくコーディングしましょう。

## form の取扱い
結論から言うと、 *formは使わずformっぽいスタイルを使って実現します* 。 (bootstrap なら `.form-group` が使えます)

```js
const FormLikeComponent = {
  view: v => [
    m(".form-group", [
      m("input[type=text]", { value: model.textData, oninput: e => model.textData = e.target.value }),
      m("button", { onclick: model.submit }, "送信"),
    ]),
  ],
}

let model = {
  submit: e => {
    m.request({
      url: someUrl,
      data: {text: model.textData},
    })
    .then( /* some handling */ );
  },
}
```

form が使えないとはいえ十分シンプルに書けます。ポイントは、

* `oninput` イベントなどを用いて入力値を補足します。入力値を得るには、イベントオブジェクトの `target.value` を参照します。ここで得た値は例によって state ではなく model のどこかに持たせるべきです。
* form 内の button なりなんなりで、submit 相当のイベントを発火します。そこでは Mithril らしく `m.request` を使います。要は普通のリクエストですね。フォームだからと特別な処理は必要ありません。

input 要素を見てもらえれば分かる通り、こんな感じで双方向バインディングな処理が簡単に書けるのが Mithril の素敵ポイントですね。formっぽいスタイルがないときは頑張ってください。

## request まわり
request について書きたかったけど力尽きたので一旦ここまでで。

## TypeScript まわり
TypeScript について (ry
FileMaker エクスポート機能の罠（リレーション先データの出力時）

# はなしの結論
## あたりまえのこと
* データ取込処理はちゃんと作りましょう（テストしよう）
* データメンテもちゃんとしましょう。

## FMのこと
* FileMaker はやっぱりRDBじゃない（再確認）
* FileMaker 「レコードのエクスポート」はエクセル仕様に近い。

## 話の経緯
社内の事業担当から「レコードがエクスポートされない」と相談を受けた。
曰く、「画面には500件ほど表示されているが、エクスポートすると50件しか出力されない」とのこと。

まったく担当外のファイルだったのと「そんなわけあるか」という思いで、よく分かりませんでしたが、
詳しく聞いてみるとこういう構成だと分かりました。

### 構成（テーブル・レイアウト）
* 親テーブルと子テーブルでリレーションしている
* 画面（レイアウト）は親テーブルとリンクしていて、子テーブルはポータルになっている

#### イメージ画像
**テーブルイメージ**
![親子テーブルイメージ.png](https://qiita-image-store.s3.amazonaws.com/0/16382/3b618bca-0348-70f2-5583-16375b1ab02a.png)

**画面イメージ**
![サンプル画面.png](https://qiita-image-store.s3.amazonaws.com/0/16382/ce5808a0-65ff-04ba-f6f6-6aa4551d9645.png)
※FM17のサンプルファイルから拝借

### 担当者がやりたかったこと
* 画面上で対象レコードを絞り込み、子テーブルの情報も含めてエクスポート！

### 相談に来たこと
* 画面上で対象レコードを検索すると 500 件が検索される
* なのに、レコードのエクスポートをすると、なぜか50件しか出力されない・・？
* 増えることはあっても、なぜ減った？？

## 確認したこと・対応したこと
とりあえず手がかりを得ようとデータを見ていると、子テーブルに空レコードが多いことが気になりました。

正確には **親テーブルとの紐づけ情報** だけ入っていて、子テーブルの管理情報（イメージテーブルでいうと **タスク名** など）が入っていないレコードが多かった。

その時点で原因が見えた気がしたが、念のため担当者に同じ作業をしてもらい、一緒に検証することにしました。

### 検証したこと
担当者が問題に気づいた時と同じように操作をしてもらうとこんな感じでした

1. レコードの絞り込み　（⇒500件表示される）
2. レコードのエクスポート（Excel）
3. ファイルを見ると50件しかない！

ここで操作を引き取り行った作業はこんな感じ

4. ctrl + ↓
5. 続きのデータを発見！！

ようするに、、50件した出力されていなかったのではなく、空行が大量に出ていました。
（目に見える範囲は空行で埋め尽くされていた！）

## どういうこと

### FileMaker の仕様
親子テーブルが１：ｎの関係にある時に、レコードのエクスポートをすると

**親テーブルのデータは１行目にしか出力されない。** 

という仕様があります。

たとえば、親テーブル１行に対して、子テーブルｎ行が紐づく場合は、こんな感じです。

| 親ID       |子．name |子．メモ    |
|:------------|:------------------|:------------------|
| 123          |タスク１  |明日までに終える       |
|　|タスク２|終わるまで帰れない|
|　|タスク３|終わる見込みが立たない|
| 124          |タスクA  |5分で終わる       |
|　|タスクB|寝てても出来る|
|　|タスクC|タスクAにより作業不要！|

一般的な RDB の Join なら親テーブルの情報も出力されますが、FileMaker は RDB じゃないですから仕方がない。
昔、エクセルで管理表を作った時のことをおもいだします。。


### 別に困らないよね？
普通は困ることはなと思います。
出力したエクセルを使って集計・・とか、たぶんないと思うので。（それならFMでやればいいので）

ただ、今回は子テーブルのデータがメンテ出来ていなかった（というかどうやって作った・・？）ため、親ID しかないテーブルが大量にありました。

そうすると・・

| 親ID       |子．name |子．メモ    |
|:------------|:------------------|:------------------|
| 123          |タスク１  |明日までに終える       |
|　|||
|　|||
|　|||
|　|||

こんな出力になり、目に見える範囲では「１件しかない！」と見えたわけです。



しょうもなさすぎて久々にQiitaに書くモチベーションになったので、よかったことにしよう。
Azure Data Factoryの個別アクティビティの失敗をLogic Appでメール通知する

## はじめに
Azure Data Factoryはパイプラインの失敗を監視してアラートメールを送る機能があるが、メールを送るための専用のアクティビティは無い。個別のアクティビティが失敗したらメールを送りたい場合はLogic Appが簡単で便利。

## 設定方法
### Logic App
Logic Appで下図のような構成を作ればOK。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/144789/ed5b6d5a-d406-3a47-fda6-f7f12e7727f6.png)

When a HTTP Request is receivedの中身は受け取るデータのスキーマを定義しておく。HTTP POST URLは作成した後に設定される。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/144789/7a4928ab-e94e-301c-1dd9-b3458c5ecc31.png)

```json
{
    "properties": {
        "DataFactoryName": {
            "type": "string"
        },
        "EmailTo": {
            "type": "string"
        },
        "ErrorMessage": {
            "type": "string"
        },
        "PipelineName": {
            "type": "string"
        }
    },
    "type": "object"
}
```
Send a Email部では設定したスキーマの項目が選べるようになっているので、例えばこんな風に設定しておく。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/144789/9f60dbb2-7ed7-41ca-de7b-5e2a2db299e6.png)

Logic Appで設定するのはこれだけ。

### Data Factory
前のアクティビティが失敗した場合の線を引いてWebアクティビティにつなげておく。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/144789/870d0608-0ee6-e5fb-f083-3a789e8f5fa7.png)

Settingsのところに、Logic Appで作成したHTTP POST URLを貼り付け、Body部には下記のJSONを記述。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/144789/d4e1c6a5-2d1f-ac66-0708-f1faca4d8185.png)

```json
{"DataFactoryName":"@{pipeline().DataFactory}","PipelineName":"@{pipeline().Pipeline}","ErrorMessage":"@{activity('Notebook1').Error.message}"}
```

これで設定はOK。Data Facotryのパイプラインで設定した前段のアクティビティ（ここではDatabricks Notebook）の実行が失敗したときに、エラーメッセージ等拾ってLogic AppのAPIにPOSTしてメールが発射されるようになる。
PysparkのDataFrameで横持ちデータを縦持ちに変換する

# はじめに

PysparkのDataFrameで縦→横の変換は簡単だけど、逆は結構難しいので備忘のために記載。

# 解決策

PySQLのbuldin関数のstackを使う。
引数は、`stack(行数, クエリ1, クエリ2, ...)`。
stackで指定した行数分、後続のクエリで指定した列を集計して、行数を膨らませるような処理を行う。

このstack関数は、pysparkのfunctionでは提供されていない？ようなので、selectExprでSQLのselectクエリを記述して実行する。

## サンプル

```python:横持ち→縦持ち
from pyspark.sql import functions as F

# 横持ちで各列のNull値の件数を集計
null_count_pivot = df.select([F.count(F.when(F.col(c).isNull(), c).otherwise(None)) for c in df.columns])

# 横持ちを縦持ちに変換
null_count_unpivot = (
  null_count_pivot
  .selectExpr(
    f"""
    stack(
      {len(df.columns)},
      {', '.join(f'"{c}", {c}' for c in df.columns)}
    ) as (column, null_count)
    """
  )
)
```

# 参考
- [Functions - Spark SQL, Built-in Functions](https://people.apache.org/~pwendell/spark-nightly/spark-master-docs/latest/api/sql/index.html#stack)
- [Unpivot in spark-sql/pyspark](https://stackoverflow.com/questions/42465568/unpivot-in-spark-sql-pyspark)
VisualStudio CodeでNode.jsを実行するときに.envに定義したものをロードする

Node.jsでアプリを作るときに、プログラム上には埋め込みたくない情報を、.envというファイルを作って管理する事が多いです。
例えば、以下のようなものがあるでしょうか。

```sh:.env
# Postgresql ENV
DATABASE_URL=postgres://postgres:password@localhost:5432/db

# Session Secret
SESSION_SECRET=KNLCKSO+JPOSJPOS

# NODE Environment
NODE_ENV=development

# JWT Secret
JWT_SECRET=@ofpowegldmvpvnp
```

# 今までのやり方
今までは、dotenvパッケージをインストールし、プログラム上に以下のように記述し、.envの内容をロードしていました。

```typescript:sample.ts
import * as dotenv from 'dotenv';
dotenv.config();
```
これでもいいのですが、いちいちこう記述するのもめんどくさい。
Herokuにデプロイする事を考えると、そもそも必要ないことだし(Herokuでは、コンソールから環境変数を予め定義しますので、.envファイルそのものが必要ありません)

# これは便利
何か他にいい方法はないものかと模索していましたら見つけました。
VisualStudo Codeに.envをロードする機能があるのです。
.vscodeフォルダにlaunch.jsonというプログラムの実行を定義するファイルがあります。
その定義の中に、envFileを追加し、.envのファイル名を指定すると、実行するときに.envの内容をロードしてくれます。

```json:launch.json
{
    "version": "0.2.0",
    "configurations": [
        // nodeによるnode.jsのデバック設定
        {
            "type": "node",
            "request": "launch",
            "name": "node",
            "program": "${workspaceFolder}\\dist\\server\\server.js",
            "envFile": "${workspaceFolder}/.env", // ←　ココ！！
            "sourceMaps": true
        }
    ],
}
```

これでコードを書くことなく、.envに定義したものを、process.env.XXXXXとして使えるようになります。
便利！！
Raspberry Piでfstab弄ったら起動できなくなった場合の備忘録

外付けのHDDを繋げて、fstab弄って再起動・・・
あれ？SSH繋がんなくなった・・・。しばらく経っててログインできるはずなのに。

と思ってHDMIケーブルを繋いで起動チェックしたところ、Emergency Modeに入っていました。Enterキー押してもうまく動かなかった。

ぐぐってたらこんな記事を発見。

https://www.rocher.kyoto.jp/arbr/?p=1378

早速これを基に作業を実施。

# SDカードを別Linuxマシンにマウント

肝心のデータファイルはext系(多分ext4)のフォーマットなので、Windowsマシンでは認識してくれません。ですので仮想マシンとかでいいのでLinuxを使用します。私はサブマシンがUbuntuだったのでそちらを使用しました。

Ubuntu Desktopでは基本的に自動マウントしてくれますので、ファイルブラウザに載っています。
名前は```rootfs```っていう名前のはずです。

# fstabを弄る

rootfs内は至って普通のLinuxディレクトリ形式なので、```etc/fstab```を弄くります。sudo使って編集しなければいけません。

今回は簡単にoptionsにnofailと付けて保存。

ちなみにoptionsのnofailはマウントに失敗しても起動してくれるオプションです。
外付け系のハードディスクは基本的にこれを使ったほうが安心です。

特にヘッドレスセットアップしているときはnofailを付けるべきです。今回の私のようになってしまいます。

# 起動

あとはそれをラズパイに戻すだけ。きっと起動するはずです。
unityゲームビューが勝手に拡大される。


# 問題

unityでスマホアプリ開発を行っていた際、ゲームを実行すると

Scaleが勝手に拡大される。

 





2018.2.12f1から2018.3.6f1に更新した後に起こったという話しや

スマートフォン向けのビルドで起こっていたという話もありました。

 

他に不具合が起こっていた人の記事を見ると2018年6月あたりから2019年３月現在までのものが多くみられました。

unity2018.3あたりからの不具合なのかもしれません。


# 解決策
unity右上にあるレイアウトを変更する。
rgbaで背景色を半透明にする方法


ヘッダーの背景色を半透明にしたらかっこいいなと思い調べて見ました

RGBAとは？
赤（R）緑（G）青（B）にアルファという透過度という情報を加えたもの
RGBは1~255の数値で色を指定し、A（透明度）は0（完全に透明）~1（不透明）という数値で指定します。

```ruby:example.rb
background: rgba(10,10,100,0.2);
```

![スクリーンショット 2019-03-01 18.38.48.png](https://qiita-image-store.s3.amazonaws.com/0/333735/1c13e5b4-f288-de11-b715-b9b2cad087f7.png)

こんな感じの青透明なヘッダーができました。


rgbaで半透明にするメリット

opacityでも半透明にすることができるが、中のテキストも透過するらしい

rgbaなら背景色のみを透過できるというメリットがある

参考

[RGBA値で背景を半透明にする](http://0start-afiri8.sakura.ne.jp/html-study/css-box/rgba.html)
[CSS：CSS3の「rgba()」で背景色を透過する方法](http://raining.bear-life.com/css/css3%E3%81%AE%E3%80%8Crgba%E3%80%8D%E3%81%A7%E8%83%8C%E6%99%AF%E8%89%B2%E3%82%92%E9%80%8F%E9%81%8E%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95)
【AWS】ポリシーを付与しても、マネジメントコンソールでEC2インスタンスが表示されない時の解決方法

忘れた頃にユーザー追加やMFAで登録していた端末を変更した時によく陥る現象。
原因も対策もなんてことはないけど、ググってもあんまりそれっぽいのが出てこないので備忘録として残します。

## 直面する問題
ユーザーにアクセス権限（ポリシー）を付与しているのにAWS マネジメントコンソールでアクセス権がないと言われ、インスタンスなど表示してもらえない。

↓↓↓どういう現象かというとこんな感じ↓↓↓
<img width="1099" alt="スクリーンショット 2019-02-27 16.13.25.png" src="https://qiita-image-store.s3.amazonaws.com/0/300773/6db96113-5b39-dbae-ece8-51e866f17ec7.png">


「you are not authorized to ~」　なので権限がないと言われているっぽい。
ユーザーを追加した時に、全ての権限を付与したはずなのに・・・？と思ったけど、よくよく考えて見たらポリシーにMFAデバイス認証つけてた。

ちなみに自分たちで追加したMFAデバイス認証はこんな感じ。（検索すると公式も出てくる）

```
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AllowAllUsersToListAccounts",
            "Effect": "Allow",
            "Action": [
                "iam:ListAccountAliases",
                "iam:ListUsers",
                "iam:GetAccountSummary"
            ],
            "Resource": "*"
        },
        {
            "Sid": "AllowIndividualUserToSeeAndManageOnlyTheirOwnAccountInformation",
            "Effect": "Allow",
            "Action": [
                "iam:ChangePassword",
                "iam:CreateAccessKey",
                "iam:CreateLoginProfile",
                "iam:DeleteAccessKey",
                "iam:DeleteLoginProfile",
                "iam:GetAccountPasswordPolicy",
         　　　　　　　 　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　 ・・・中略・・・
        {
            "Sid": "BlockAnyAccessOtherThanAboveUnlessSignedInWithMFA",
            "Effect": "Deny",
            "NotAction": "iam:*",
            "Resource": "*",
            "Condition": {
                "BoolIfExists": {
                    "aws:MultiFactorAuthPresent": "false"
                }
            }
        }
    ]
}
```

## 原因
アクセス権限（ポリシー）は付与していたけど、MFAデバイスの割り当てをまだ設定していなかったから、EC2インスタンス等の表示がブロックされていたみたい。


## 対策
ログイン後に「IAM→ユーザー→認証情報→ MFA デバイスの割り当て」でMFAのデバイスを登録する。
（こちらに詳しい設定方法が記載されてます → [「AWSでMFA(二段階認証)を有効にする方法を超丁寧に説明するよ」](https://qiita.com/viptakechan/items/6d19aee635b2ab189e47)）

しかし、そのままEC2のダッシュボードに行ってもまだ権限がないと言われる。
一度サインアウトして、MFAデバイス認証を突破しないと見せませんよ、ってことらしいです。

もう忘れない。


### 参考
参考にさせていただきました。ありがとうございます。

[チュートリアル: ユーザーが自分の認証情報および MFA を設定できるようにする]
https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/tutorial_users-self-manage-mfa-and-creds.html

[MFA 条件を指定したサンプルポリシー]
https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/id_credentials_mfa_sample-policies.html

[AWSでMFA(二段階認証)を有効にする方法を超丁寧に説明するよ]
https://qiita.com/viptakechan/items/6d19aee635b2ab189e47
SlackとCloud Functionsで迅速に障害の初動対応をする

突然障害が起きると何をしたらいいか慌ててしまいませんか？
今回それを解決するために、１アクションで障害の初動対応をするslash commandを作りました。

# 概要
障害対応の初動を早めるために

1. Slackで/hogeと打つ
2. チャンネルが作られる
3. チームメンバーがinviteされる
4. タスクリストがpostされる

という仕組みを用意しました。
![usage.gif](https://qiita-image-store.s3.amazonaws.com/0/108210/33538c35-495e-222f-914b-8d78292b2227.gif)
上の例は誰もいないスペースでテストしています。
スペースにメンバーがいるとき、Slack Appのレスポンスはこのようにチャンネル名と、招待したメンバーが出力されます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/108210/a26e1bb9-1fdd-e3eb-7023-97b02771b357.png)

# 環境
- serverless 1.37.1
- Node.js 8
- Google Cloud Functions
- Slack

# 背景
障害対応のとき

- 突然のアラートに何をすればいいかわからない
- チームの誰が何の対応をしているかわからない
- ベテラン1人しか対応できないので時間がかかる
- チーム外から作業状況が見えない
- 社内Wikiで状況をまとめているがリアルタイム性が低い

というようなことがあると思います。

# コンセプト
アラート検知後、以下のようなことを目指します。

- 障害の初動を迅速に行う
- チームメンバーの習熟度に関係なく全員で障害に当たることができる  
タスクリストを表示することで突然の障害にも最低限何をすればいいかわかる
- 作業状況をオープンにする  
パブリックチャンネルを作ることで見たい人が情報を参照できる  
slackのリアクションで何をやっているかわかるようにする
- 作業状況がリアルタイムにわかるようにする

あくまで初動のための仕組みです。アラートの種類によって調査手段は変わります。
タスクリストはチームごとに適宜更新していく想定です。

# 仕組み
SlackとGoogle Cloud Functionsを使って概要にある仕組みを構築しました。
フレームワークはServerlessを使いました。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/108210/3e5eb28e-d0eb-1bb2-4b3c-d9d32c0e415e.png)

1. slash commandsでCloud FunctionsのHTTPトリガーを叩きます。
2. slash commandは3秒のタイムアウトがあるのでまずはレスポンスを返します。  
3. 非同期でSlack APIを叩きます。
4. Slack APIの結果を取得します。
5. API呼び出しの結果をresponse_urlにPOSTします。

チャンネル名のprefix、招待するユーザ、タスクリストはyaml形式の設定ファイルに書きます。
チャンネル名は設定ファイルのprefixと時刻のsuffxが合わせて作られます。
（障害対応を想定して作ったので、チャンネル名を一覧したときわかるように時刻を入れてみました。）

# ソース
https://github.com/tom-256/emergency-slack

# まとめ
メンバーの習熟度にかかわらず、チーム全体で透明性のある障害対応をおこないましょう。

今回の挙げた例はあくまで一例です。
チームに合った障害対応策を考えてみてはいかがでしょうか？

# 参考
https://about.gitlab.com/2017/02/10/postmortem-of-database-outage-of-january-31/
GitLabのデータベースの事件は記憶に新しいでしょう。
対応状況をYouTube配信やGoogleDocsで外部に公開するのは難しいかもしれませんが、
関係部署など適切な範囲でオープンにできるといいですね。
【Python】インストール方法 (Anaconda)

# 概要
Pythonのインストール方法について説明する．
データ分析などに使うことを考え，Anacondaディストリビューションを利用する．
Pythonを直接インストールする場合は，他のサイトを参考にして頂きたい．

# Pythonとは
**Python**は，プログラミング言語の一種である．プログラミング言語のうち**スクリプト言語**という種類に分類される．Pythonは以下のような長所を持つ．
1. **文法**(=プログラミング言語が持つルール)がとてもシンプルである．　➡覚えやすい・使いやすい．可読性が高い．
2. **標準ライブラリ**，**外部ライブラリ**が充実している．　➡簡単に高度なプログラムを作ることができる．

# Pythonのインストール
### バージョン
Pythonには，2系と3系という2つのバージョンが存在する．この二つには互換性(厳密には後方互換性)がなく，Python 3系で書いたプログラムがPython 2系では実行できないといったことが起こる．よって，**Python 3系**を使うことをおすすめする．

### ディストリビューション
ユーザが一括してインストールできるように，ライブラリなどがひとつにまとめ上げられたものを**ディストリビューション**という．ここでは，データ分析に重点を置いた**Anaconda**というディストリビューションを利用する．Anacondaには**NumPy**(＝数値計算のためのライブラリ)や**Matplotlib**(＝グラフ描画のためのライブラリ)など，データ分析に有用なライブラリが含まれている．[リンク](https://www.anaconda.com/distribution/)より，ディストリビューションをダウンロードし，インストールを行う．



# 参考文献
1. 斎藤 康毅, "ゼロから作るDeep Learning -- Pythonで学ぶディープラーニングの理論と実装," 株式会社オライリー・ジャパン, 2016
2. 柴田淳, "みんなのPython 第3版," SBクリエイティブ株式会社, 2012
mlflowコマンドが見つからない時の解決方法

# 問題
[この記事](https://qiita.com/panda531/items/9074d7ce8679a09cc1ed)でも書いたんですが、macOSにpyenvとanacondaを使ってインストールしたMLflowのmlflowコマンドが見つからないという問題です。

```bash
$ mlflow ui
-bash: mlflow: command not found
```

# 結論
パスが通ってないだけでした。。。

# 今回の対処手順
しょうがないから再インストールしてみるか、ということで再インストールしました。

```bash
$ pip --no-cache-dir install -I mlflow --user
```

そしたら以下のような表示が！

```bash
The script chardetect is installed in '/Users/panda531/.local/bin' which is not on PATH.
Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location.
```

完全に見落としてました…

ということで`~/.bashrc`に以下の記述を追加しました。

```
export PATH=$PATH:/Users/panda531/.local/bin
```

そして

```bash
source ~/.bashrc
```

これで無事にパスが通るようになりました。

ただ、`~/.local/bin`じゃなくて仮想環境の下(`~/.pyenv/versions/anaconda3-5.0.1/envs/envname/bin/`)に入ってほしいんですけどどうなんでしょうか。。。
[JS]配列に配列をpushしたら、勝手に二次元配列になる件

#はじめに
配列に配列を追加しようと、定番のpushメソッドを使ってみたら、

```javascript:失敗例①
let base = [];
let add1 = [ 1, 2, 3 ];
let add2 = [ 4, 5, 6 ];

base.push(add1);
base.push(add2);
console.log(base);
```
```text:実行結果：失敗例①
[ [ 1, 2, 3 ], [ 4, 5, 6 ] ]
```
・・・こうなりました。

間違ってはないけど、もうちょっと綺麗に並べたい・・・
ってなったので、調べた結果を共有します。
#今回のコード
```javascript:成功例
let base = [];
let add1 = [ 1, 2, 3 ];
let add2 = [ 4, 5, 6 ];

base = base.concat(add1);
base = base.concat(add2);
console.log(base);
```
```text:実行結果：成功例
[ 1, 2, 3, 4, 5, 6 ]
```
きれいに並んだ！

#失敗例
##その１　pushをフツーに使ったパターン
```javascript:失敗例①
let base = [];
let add1 = [ 1, 2, 3 ];
let add2 = [ 4, 5, 6 ];

base.push(add1);
base.push(add2);
console.log(base);
```
```text:実行結果：失敗例①
[ [ 1, 2, 3 ], [ 4, 5, 6 ] ]
```
はじめに書いた通り、普通にpushしたらこうなる。

.lengthで個数を調べたりしたら、
「中身2個ですよ」とか返ってくる始末です。

##その２　concatをというメソッドを知り、希望を託すも惨敗したパターン
```javascript:失敗例②
let base = [];
let add1 = [ 1, 2, 3 ];
let add2 = [ 4, 5, 6 ];

base.concat(add1);
base.concat(add2);
console.log(base);
```
```text:実行結果：失敗例②
[]
```
もう、なんも入ってませんやん。
一周回って、笑えるやつ。

#ざっくり解説
pushは、元の配列に値を追加するときによく使われるメソッドです。
しかし、追加する値が配列だった場合、失敗例①のように、二次元配列になって追加されてしまいます。
どうも、かゆいところに手が届かない。

そこで、他のメソッドを調べたら、出てくるのがconcatメソッド。
これは、追加するというより、結合するというメソッドだそうです。

しかし油断するなかれ。
そのまま、失敗例①のpushメソッドをconcatメソッドに書き直しても、失敗例②のようになります。

一周回って笑うしかありません。
僕は、笑いました。

これは、pushが破壊的メソッドと表現されるのに対して、concatは非破壊的メソッドと表現されるものだからだそうです。

つまり、pushメソッドは、base変数に付くとともに、元の空配列であったbase変数を破壊し、add1変数やadd2変数が追加された変数へと姿形を変えてしまいます。これに対して、concatメソッドは、元の空配列であるbase変数を破壊しません。そのままです。

なので、失敗例②は元の空配列であるbase変数が出力されて、こうなってしまったんですね。
base変数自体を変えたいのであれば、成功例のように書いて頂くと良いかと思います。

#さいごに
走り書きで恐縮ですが、読んでいただいてありがとうございました。
間違いや、分かりにくい部分があれば、お気軽に編集リクエスト出していただければ幸いです。
ドット絵基本

# ドット絵を表示する

```py
enemy_img = [[0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0],
             [1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1],
             [1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1],
             [1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1],
             [0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0],
             [0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0],
             [0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1]]

for line in enemy_img:
    # print(line)
    for dot in line:
        if dot == 1:
            print('#', end='')
        else:
            print(' ', end='')
    print()  # 改行のための空のprint
```
[Oracle Cloud] OCI IaaS 個人的重要アップデートまとめ（2019年）

2019/03/01 新規作成
2019/03/28 更新
2019/06/11 更新
2019/08/26 更新
2019/10/13 更新
***

Oracle Cloud Infrastructure(OCI)のIaaSに関連するアップデートを、独断と偏見でピックアップして並べてみました。（一部IaaSじゃないものも含んでますが…）

※利用可能なもののみに限定しています（〇〇を提供することを発表、みたいのは除外）。

公式のOCIリリース情報はこちら
https://docs.cloud.oracle.com/iaas/releasenotes/

過去のはこちら
[[Oracle Cloud] OCI IaaS 個人的重要アップデートまとめ（2017年）](https://qiita.com/feifo/items/e1e5204a369e35922018)
[[Oracle Cloud] OCI IaaS 個人的重要アップデートまとめ（2018年）](https://qiita.com/feifo/items/15a3fa8d0423fb921bbd)

### 2019年

| 月 | アップデート | コメント |
|:-----------|:------------|:------------|
|01|**Trontoリージョンオープン**|OCI 5つめのリージョン(Gov除く) |
|01|管理コンソールアップデート|Service Limits引き上げをコンソールから可能に、他|
|01|Load BalancerにHTTPヘッダー編集機能追加|バックエンドサーバーにSSL終端を知らせるなどが可能に|
|02|**Regional subnetリリース**|SubnetがADを跨いで構成できるように|
|02|OCI版マーケットプレースオープン||
|02|**Notificationsサービス提供開始**||
|02|**Monitoringサービス提供開始**||
|02|**Resource Managerサービス提供開始**|terraformでリソースを管理するためのサービス|
|02|Streamingサービス提供開始||
|02|**Autoscalingが可能に**|computeインスタンスのスケールアウト・インが可能に|
|03|Internet Intelligence提供終了||
|03|**Service GatewayがObject Storage以外にも対応**|ADW/ATPやOracle Linux Yumなど|
|03|管理系機能のアップデート|コンパートメントへのデフォルトtag設定、billingにbudgetや通知の設定、csv出力など|
|03|IAM認証のアップデート|パスワードポリシーの変更が可能、二要素認証などIDCSのみで可能なだったものが徐々に取り込まれつつある|
|03|管理コンソールアップデート|日本語対応、Object Storageのアップロード制約解除、Volume Group管理など|
|04|**東京リージョンオープン！**||
|04|テナンシーをまたいだObjectのコピーが可能に||
|05|Colt, NTTcom, TOKAIコミュニケーションズが東京リージョンとの接続サービスを提供開始||
|05|ソウルリージョンオープン！||
|05|IPsec VPNでDRGサポート||
|05|Market PlaceにOracle DB, Oracle EMが登録||
|06|**MS Azureとインターコネクトが可能に**|ashburnリージョンからスタート|
|06|Autonomous DatabasesでCPUのAuto Scaleが可能に||
|06|ATPにDedicated Deploymentsが登場|Autonomous Databasesの占有マシンバージョン|
|07|ほとんどのcore serviceがcompartment移動可能に||
|07|**Network security groups機能リリース**|Security Listとは異なり、vNICをグルーピングしてセキュリティルールを適用させる仕組み|
|07|**Compartment単位でリソースの制限を設定可能に**||
|07|Oracle servicesへのtransit Routeingが可能に|OnPからObject StorageなどへDRGとService Gatewayを経由してプライベートアクセスが可能|
|07|コスト・トラッキング・タグでBudgetの設定が可能に||
|07|**Eventサービス提供開始**||
|07|**Functionサービス提供開始**||
|07|インドMunbaiリージョンオープン！||
|07|スイスZurichリージョンオープン！||
|07|GovernmentリージョンでIPv6対応||
|08|ブラジルSao Pauloリージョンオープン！|
|08|WAFにCaching Rules、Custom Protection Rules機能追加||
|08|**"Dedicated virtual machine hosts"提供開始**|HVの管理が不要で仮想マシンを利用できる占有サーバー（BM）|
|08|オーストラリアにSydneyリージョンオープン！||
|09|**RDMAを利用したクラスタネットワークをHPCインスタンスで利用可能に**||
|09|管理コンソール画面を一新|PaaSとIaaSが統合|
|09|NotificationsでWebHookやWeb APIsを通してメッセージを通知することが可能に||
|09|Oracle Data Safeサービス提供開始||
|09|**Autonomous DB, Compute, LB, Block Volume, Object Storageなどが一定リソース分無料で利用可能に（Always Free）**||
|09|Windowsイメージのexportが可能に||

※2月にはEdgeサービスとして、WAFサービス、Health Checkサービス、Traffic Management Steering PoliciesサービスなどがGA。これらとDNSサービスと組み合わせて災対時の切り替えなども出来るようになりました。

以上
Dockerのボリューム先を削除してコンテナが立ち上がるようにする

# ボリューム位置を知りたくなった経緯
Growiのバージョンアップをしたらdocker-compose upできない
原因はバージョンをあげる前のelasticsearchコンテナが作ったnodeの0番。恐らく以前のnodeが残っていてかつ、Dockerfileの設定では１つのnodeしか作られないようになっているにも関わらず、バージョンアップしたGrowiをdocker-compose upする時に新たなnodeを立てようとしていたからだと思われる。


# 解決策

**それなら、ボリュームされたこいつを削除してやればいいじゃん！！**

## どこだァ！！ボリューム！！

```docker-compose.yml
volumes:
      - es_data:/usr/share/elasticsearch/data
```

これではホストのどこにボリュームされてるか分からねぇぞぉ！！

```
$ docker volume ls
```

こうしてあげると、

```
local               growi_es_data
local               growi_es_plugins
local               growi_growi_data
local               growi_mongo_configdb
local               growi_mongo_db
```
こんな感じで、ボリュームされているボリューム名がリストされます。今回はelasticsearchに用があるので、growi_es_dataちゃんにご同行願いましょう。ふへへへへへ・・・

```
$ docker volume inspect growi_es_data
```

こうしてあげると、

```
[
    {
        "CreatedAt": "2019-02-28T09:37:54Z",
        "Driver": "local",
        "Labels": {
            "com.docker.compose.project": "growi",
            "com.docker.compose.volume": "es_data"
        },
        "Mountpoint": "/var/lib/docker/volumes/growi_es_data/_data",
        "Name": "growi_es_data",
        "Options": null,
        "Scope": "local"
    }
]
```

詳しいボリュームの内容が分かります。見えちゃってるゼェ〜、君の全部がヨォ〜・・・ヘッヘッヘ・・・

## ディレクトリを削除・・・と思いきや・・・
当初は、これで分かったボリューム先まで行ってそのパスの先にある_dataを丸ごと削除してあげれば問題ないと思っていたんですが、

```
$ docker volume rm growi_es_data
```

上記のように、volume名を指定してそこを吹っ飛ばすことができるコマンドをvolume lsなどを調べていた時に見つけたので、これで削除しました。

# 解決！
この作業の後に、docker-compose upしたら、ちゃんと動いてくれました。
無人島に持っていくvimrc

vimの特徴といえば「どのLinuxにも入っている」ことですが、そうは言っても素のvimをいきなり使うと辛い部分が多々あるので、最低限の設定だけは持っていきましょう。

持っていく方法自体は [sshした先に.bashrcや.vimrcを持って行きたい人のためのsshrc](https://qiita.com/ikuwow/items/ba4ca57fd67c06fd1b19) の記事に譲ります。

## これを持っていけ!
```viml
" 日本語エンコード対応
set encoding=utf-8
set fileencoding=utf-8
set fileencodings=utf-8,cp932,euc-jp

" 環境を汚さない設定
set nobackup
set noswapfile

" 古いvimでも出来る見た目の改善
" 入力途中のコマンドを表示
set showcmd
" 括弧をハイライト
set showmatch
" デフォルトのハイライト時間が長すぎるので短くする
set matchtime=1

" インデントを維持するなど挙動を改善する
set smartindent

" バックスペースの挙動を普通にする
set backspace=eol,indent,start

" 画面に余裕をもたせてスクロールする
set scrolloff=5

" 素早くウィンドウ移動(まさかカーソルキーを使ってる人はいませんよね?)
nnoremap <Left> <C-w>h
nnoremap <Down> <C-w>j
nnoremap <Up> <C-w>k
nnoremap <Right> <C-w>l

" Backspace キーを使う
" なおかつレジスタを汚さない
noremap <BS> "_xh
```

逆にこれはなくてもいいなと思う設定もあります。

```viml
" カーソル位置ハイライトは重くなりがち
set cursorline
set cursorcolumn

" 行番号は出さないのが出来るvimmerのやり方
set number
" 相対行番号は重くもなるのでなおさら
set relativenumber
```

## 無人島での戦い方
プラグインがないときにこそ光る機能のご紹介。

* `<C-o>` `<C-i>`: カーソルを戻る/進む。ファイル履歴をまたいで移動できるので、vimを開き直した後でも `<C-o>` 連打でさっき開いたファイルに戻ったりできます。
* `^` `$`: 行頭/行末に飛ぶ。素早く移動するなら必須でしょう。
* `%`: 対応する括弧に飛ぶ。関数の始めから最後まで飛ぶなど応用が効く。
* `cgn`: 検索ワードを置き換える (`c`が置換で、`gn`が検索ワードという意味の対象)。`n`で次のワードに飛びながら実行したり、`n`なしで`.`で繰り返すだけでも次々と置き換えていけるのでかなり捗ります。

以上、入門記事にはあまり取り上げられない機能のご紹介でした。

## おことわり
> VSCodeでリモート編集すればいいじゃんってのは言わない約束です