OmniAICreator/Qiita-1.07M huggingface dataset:
GoGuiをMacにインストール

GoGui は Go 言語のことではない。囲碁 （Go Game） の GUI のプログラムのこと。
Linux と Windows 向けはインストーラプログラムが用意されているが、Mac はソースコードからコンパイルをしなければならずちょっと面倒なので備忘として残します。 [※ ちょっと前は brew で入ったみたい。](http://tsuwabuki.hatenablog.com/entry/2015/08/04/072840)

## 0. 前提

macOS Mojave version 10.14.6

## 1. GoGuiのソースをダウンロード

[こちら](https://sourceforge.net/projects/gogui/) よりダウンロード (version 1.4.9) 。インストールの仕方は [install.html](https://github.com/Remi-Coulom/gogui/blob/master/INSTALL.html) に書いてある。

## 2. Javaのランタイムはバージョン11で

最新の Java SE12 だと後のコンパイルで失敗してしまったので 1 つ前のバージョンの Java SE11 を用意。

## 3. 必要なライブラリのインストール

libxsltproc が必要とのこと。libxslt に付いてくるのでそれを入れる。

```
brew install libxslt
```

## 4. 必要なファイルの用意

[docbook-xsl](http://sourceforge.net/projects/docbook/files/docbook-xsl/) と [docbookx.dtd](http://www.oasis-open.org/docbook/xml/4.2/) が必要とのことなのでリンク先からダウンロードし、適当なところに置いておく。

## 5. 後のコンパイルで `/Developer/Tools/SetFile` が見つからないとエラーを吐くのでリンクを貼る

```
sudo ln -s /usr/bin/setfile /Developer/Tools/SetFile
```

## 6. quaqua.jarをダウンロード

[こちら](http://www.randelshofer.ch/quaqua) よりダウンロードし、goguiのディレクトリ直下 `lib/quaqua.jar` に配置

## 7. コンパイル

gogui ディレクトリルートにて以下コマンドによりコンパイル実施。

```
ant gogui.app -Ddocbook-xsl.dir=/path/to/docbook-xsl -Ddocbook.dtd-4.2=/path/to/docbookx.dtd
```

## 8. GoGuiを立ち上げる際に、Java SE 6 ランタイムが必要と出るのでインストール

[こちら](https://support.apple.com/kb/DL1572?viewlocale=ja_JP&locale=en_US)からダウンロードしてインストール

以上
もうすぐAmazonDashButtonが使えなくなるのでNodeRedで違う使い方をしてみる

#はじめに
8月末でAmazonDashButtonが使えなくなってしまうのでどうにか活用しようとしたけれどどの方法も簡単じゃなかったので一番簡単にできそうなNodeRedで実装してみる。

#ボタンのmacアドレスを取得する
pcapとか使ってアドレスを調べている人が多かったけれどボタン単体で調べられるので紹介。

ボタンを長押しする
　　　↓
ボタン左横のLEDが青く光るのを確認する
　　　↓
光ったらAmazonConfigureMeというアクセスポイントが立ち上がるのでアクセスする。
　　　↓
アクセスしたらブラウザで192.168.0.1にアクセス
　　　↓
するとボタンの諸々の情報が見れる
後にmacアドレスが必要になるのでメモっておく

簡単にボタン単体でmacアドレスとか電池残量とか確認できるのでお試しください。

#NodeRedで処理を書く
NodeRedに**node-red-contrib-mydash**というノードがあるおかげで今回簡単に活用できました
**node-red-contrib-amazondash**もあるんですが別途前提ライブラリ?が必要で入れれなかったので断念

とりあえずボタンが押されたらSlackに通知が来るようにノードをつなげて実験してみる
<img width="617" alt="スクリーンショット 2019-08-18 20.31.23.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269207/8ad59436-b069-b05d-6d04-86c9a1c10f3e.png">

今回は柿の種のボタンを使ったのでSlackには柿の種と送ってみる

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">Dash Buttonで通知くるようにできた...<br>つかれた... <a href="https://t.co/wtEJb1h4c2">pic.twitter.com/wtEJb1h4c2</a></p>&mdash; Akijin(J.あらき) (@Akijin_araragi) <a href="https://twitter.com/Akijin_araragi/status/1163070950822146049?ref_src=twsrc%5Etfw">August 18, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

(本当はGIFで直張りしたかったけれどあきらめた。。。)



NodeRedからならHTTPリクエストも送れるしメールも送れるからあまりに出勤が遅い人に早く来いと催促できるボタンにもできそう。
IFTTTと連携させてLINEに通知させてもいいだろうしわりと活用の幅は広そうな印象。


NodeRedはDockerで入れると簡単に環境構築できるか初心者でも楽に開発に入れるからオススメ
ぜひ一度はNodeRed触ってみてほしいです。
【Vue.js + Firebase】ローソンがちゃでダイエットする

# できたもの

:point_down: こちらからガチャできます :point_down:
[ローソンがちゃ](https://calculatecalorie.web.app/)  
<img width="1198" alt="スクリーンショット 2019-08-18 19.57.33.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/148385/40951901-42c1-95bf-849d-c9b0f05b001a.png">

# はじめに
元々ダイエットしていたのですが、毎日同じものばかりで飽きてきたので作成しました。(豆腐+納豆ばかりだった)
あと家の近くにローソンができて嬉しかったので :kissing_heart:

# 構成
- フロントエンド
  - Vue.js + TypeScript
  - ElementUI
- バックエンド
  - Firebase

# つまづいたこと
Webアプリはフロントもバックも初心者なので、色々困りごとがありました :hatched_chick:

## そもそもVue.js初めてなので学習したい
- [Vue.js - はじめに](https://jp.vuejs.org/v2/guide/)

## UIコンポーネントをいい感じの見た目に統一したい
ElementUIを使いました

- [vue-cli-plugin-element](https://github.com/ElementUI/vue-cli-plugin-element)

## ライフサイクルに応じてゴニョゴニョしたい
- [Vue.js - ライフサイクルダイアグラム](https://jp.vuejs.org/v2/guide/instance.html#%E3%83%A9%E3%82%A4%E3%83%95%E3%82%B5%E3%82%A4%E3%82%AF%E3%83%AB%E3%83%80%E3%82%A4%E3%82%A2%E3%82%B0%E3%83%A9%E3%83%A0)

どのタイミングでFirebaseからデータを取ってくればいいのか分からなかったので、下記を参考にしました。
[Vuejs APIアクセスはcreatedとmountedのどちらで行う？](https://qiita.com/kimullaa/items/2bf8948dffb8c52d2b6b)

## Twitterの共有リンクを作成したい
- [Twitter Developer - Tweet Button](https://developer.twitter.com/en/docs/twitter-for-websites/tweet-button/guides/web-intent.html)

## Firebaseでデプロイしたい
- [Vue.js によるアプリを Firebase で Hosting する最短の道](https://qiita.com/Satachito/items/4a00b402970d657a88f3)

`firebase login`ができなかったので、下記を参考にしました。
[Firebaseコマンドが実行出来ない場合の対処法](https://qiita.com/ebichan_88/items/e3e30461ad4ddd9368f5)
 
# おわりに
(お盆前まで順調に体重が落ちてたのに、お盆を経て見事元の体重に戻りました :relieved:)

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">食べた👌 <a href="https://t.co/XKHRMIJ1xX">pic.twitter.com/XKHRMIJ1xX</a></p>&mdash; ちぇだ (@cheddar_dev) <a href="https://twitter.com/cheddar_dev/status/1156167432685285377?ref_src=twsrc%5Etfw">July 30, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
while文とfor文の違い

#while文やuntil文
「while」文や「until」文は指定した条件式によって繰り返しを継続するかどうかを判断している

ex)`num = 0
while num < 100 do
  puts num
  num += 1
end`

#for文は？
「for」文ではあらかじめ指定したオブジェクトから順に値を取り出しながら繰り返しを行います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463936/af2e130d-33ca-7df3-d3f8-df0657ff8357.png)

ex)`for num in 0..99 do
  puts num
end`
Windows ServerにOpenSSHを設定してつまずいたのでその解決方法

## OpenSSHの設定方法
設定方法は[こちらの記事](https://qiita.com/M_Nagata/items/722a9970dcc2a0b71612)を参照してください。
この通りにやったところ、なんとSSHで公開鍵認証できないという事故が起きました

## セットアップ環境
### クライアントＯＳ
Windows 10 Pro ビルド18362.295
### サーバー環境
ＶＰＳ：ConoHa for Windows Server WIN1GBプラン(１契約税抜￥1,800)
ＯＳ：Windows Server 2019 DataCenter ビルド17763.678

## OpenSSH導入のきっかけ
Windows Serverは、Windows NT系OSで、GUIベースなので、通常だとリモートデスクトップ接続になるんですが
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/94629/0768e153-7ef5-9c4c-9eb8-bd9df17cf8ae.png)
この通り、サインインしただけで物理メモリの消費量がこんななので、これだとこのVPSで運用しているサイト、特に[ときめきアイドルスコアランキングサイト](https://tokidolranking.site/)においてはかなり動作が重くなっちゃうのでメモリ消費量の少ないSSH接続をしたいと考え、導入することにしました

## つまずいた原因
- FixHostFilePermissions.ps1の結果は全てOK
- FixUserFilePermissions.ps1の結果も全てOK
- sshd_configのほうも公開鍵認証は有効になっている
- エラーログが出ない
- sc.exe query sshdを実行すると、RUNNINGになっている
- Windowsファイアウォールのポートも開いている
- 鍵のペアは合っている
- 鍵を作り直してもだめ
- 別のユーザーアカウントでもだめ

もう本当にできることは何もないという状態でした。

## 解決法
[yumetodoさん](https://qiita.com/yumetodo)と一緒にやってるVPSのSSHの設定と見比べ、１個ずつ同じにしては戻しというのをひたすら繰り返していった結果、一番下の

Match Group administrators

という項目をコメントアウトしたら、SSH接続ができるようになりました
最初これをコメントアウトすると管理者権限を使った操作ができなくなるんじゃないかと思いましたけど、そういう心配も一切なく、ちゃんと管理者権限を使って操作することができました

>## 追記１
>解決法についてなんですが、暫定的な解決法で、現在原因解明中です
>## 追記２
> [こちら](https://qiita.com/sekai/items/e053932512d6d43e06e4)に書いてあるんですけど、administrators_authorized_keysがないと認証でつまずくみたいです。でもぶっちゃけコメントアウトしてしまっても何ら問題ないらしいです
二次元いもす法

# 二次元いもす法

いもす法とは、要素の重複を効率よく数えるアルゴリズム。
詳細は[こちら](https://imoz.jp/algorithms/imos_method.html)

今回は2次元に拡張したいもす法をpythonで実装した。


```python

4 5 2
xoooo
oooox
ooooo
oxxoo

```

これらを入力とする。4 * 5のグリッド内でxのそれぞれを中心とする一辺5の正方形があると考える。
これらの正方形が重なり合ってグリッド上に存在すると考えた時、最も多くの正方形が重なっている座標では何個の正方形が重なっているか、という問題を考える。

```python

r, c, k = map(int, input().split())
grid = [input() for i in range(r)]
cumsum = [[0] * c for i in range(r)]
for y in range(r):
    for x in range(c):
        if grid[y][x] == 'x':
            cumsum[max(0, y - k)][max(0, x - k)] += 1
            if x + k + 1 < c:
                cumsum[max(0, y - k)][x + k + 1] -= 1
            if y + k + 1 < r:
                cumsum[y + k + 1][max(0, x - k)] -= 1
            if y + k + 1 < r and x + k + 1 < c:
                cumsum[y + k + 1][x + k + 1] += 1



for y in range(r):
    for x in range(c - 1):
        cumsum[y][x + 1] += cumsum[y][x]



for x in range(c):
    for y in range(r - 1):
        cumsum[y + 1][x] += cumsum[y][x]


print(cumsum)

```

```python
[[1, 1, 2, 1, 1], [3, 3, 4, 3, 2], [3, 3, 4, 3, 2], [2, 2, 3, 3, 2]]

```
答えは4とわかった。
MySQLでストアド, トリガー, イベントスケジューラーもフルバックアップする

# 前置き
小ネタになります:pushpin:
「MySQLでリストアしたらストアドが無くなった」という相談があり、実行した`mysqldump`のコマンドを聞いたら`mysqldump -u root -p --all-databases > dump.sql`のようなコマンドでした:confounded:
このコマンドは非常に多く紹介されていますが「全データベースのバックアップ」という紹介のされ方が多いので誤解されやすいのかもしれません。もしくは世間的にストアド、トリガー、イベントスケジューラーの存在は薄いのでしょうか:question:
mysqldumpのオプションを指定してストアド、トリガー、イベントスケジューラーをダンプする必要があります。

# `mysqldump`オプションを指定する
当初はストアドなどが無くても、いつの間に作成されたりするので、筆者は以下のオプションを常時付与してバックアップをしています。

| オプション | 備考 |
| ------- | --- |
| --routines | ストアドプロシージャー、ストアドファンクションをダンプする。 |
| --triggers | トリガーをダンプする。 |
| --events   | イベントスケジューラーをダンプする。 |

# コマンドの実行例
筆者はMySQL 8.0(InnoDB、レプリケーション無し)で以下のコマンドでフルバックアップしています。最終的には「全データベースのバックアップ」の定義はそれぞれだと思いますが:sweat_smile:、ストアド, トリガー, イベントスケジューラーはダンプされます:thumbsup:

```:Linux/macOSなど
mysqldump -u root -p --single-transaction --routines --triggers --add-drop-trigger --events --all-databases > dump.sql
```


```:Windows(特にPowerShellはこちらをお勧めします)
mysqldump -u root -p --single-transaction --routines --triggers --add-drop-trigger --events --all-databases --result-file="dump.sql"
```

# 補足
以下のオプションは改めて指定する必要が無いと考えています。

| オプション | 理由 |
| ------- | --- |
| --opt | デフォルトで指定されているため。 故に以下のオプションも改めて指定する必要はない。<br>--add-drop-table --add-locks --create-options --disable-keys --extended-insert --lock-tables --quick --set-charset|
| --skip-lock-tables | --single-transactionと--lock-tablesは排他利用であるため。 |

# 終わりに
筆者は`--routines`は知っていましたが、「`--triggers`や`--events`もあるのか」と思ったことがあります。ストアドなどを含めたコマンドが少しでも広まって、リストア時に「真っ青なる方々」が少なくなれば良いと思い記事にしました。
余談ですが、そろそろmysqlpumpに移行したいと考えています。
【MySQL 初心者ノート】- SQL, mySQLとは


# このページについて
個人的なSQL学習のノートとして残しています。
間違っている箇所などありましたら、ご指摘頂けると幸いです :bow:

第一回は、SQLとmySQLの概要についてざっとまとめてみました。

# SQL と mySQL について

下の図は私たちがSQLを使っている時に何が起きているのかを簡易的に表したものです。
このようなネットワーク構造をクライエント/サーバーアーキテクチャーと言います。
実際は、複数のサーバとクライエントが繋がっていたりするなど、もっと複雑になっていますが、ここではわかりやすいようにサーバーとクライエントの一対一と仮定して説明します。

**SQLは(Structured Query Language)** の略であり、クライエントがサーバーの持っているデータにアクセスしたいときに使う言語と考えてよいでしょう。サーバーは**DBSM(database management system)** と呼ばれるソフトウェアでデータの管理をしています。**mySQLはDBSM**の一つです。mySQL以外にも、Oracle、DB2、SQL Server など色々な種類がありますが、オープンソースであり、かつ様々なプラットフォームで利用できるmySQLは最もよく使われているDBSMでしょう。

<img width="700" alt="Screenshot 2019-08-18 at 8.59.43.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407366/b2f9abfe-6ad9-6db5-6d97-ed56a12a5a7a.png">


## Relational Database とは
mySQLではデータを **RDB (Relational database model)** というデータ構造で管理しています。簡単にいうと、**行(Column)と列(Rows)からなる表形式のモデル**を指します。舌の図にあるように、各列を示す値が入っている行を **PK(Primary Key)** と呼び、一つ一つの値が入っている枠を **Cell** と言います。一つの表に複数のPKを持たせることも可能です。そのようなケースを Composite Primary Keyと言います。更に、PKとは別で、各列を定義できる行を **Non-Priamry Keys** といい、mySQLでは **Unique Keys**という特別な名前を持っています。


<img width="792" alt="Screenshot 2019-08-18 at 9.34.29.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407366/9930f4a6-8373-89dc-c1e7-db47d9f2e298.png">


### 表内の関係性
表の中での Relations には様々な種類がありますが、One-to-manyが最も一般的でしょう。many-to-many は、複数の表があったときに、それぞれの表を他の第三者の表を介して関係性を表す際などに使用されます。

|タイプ |例 |
|----|---------|
|one-to-many| お客さんの名前 -to- [電話番号、住所、年齢]| 
|many-to-many|お客さんの名前と売った店員の関係を表した表 -to- お客さんの名前と住所の表|


## MySQL を触ってみる
MySQLを開き、ローカルのコネクションを選択します。

### Schema

mySQLを開き、ローカルホストを選択すると、下のような画面が出てきます。
この左のバーにある**scheme** というのは、データの定義や内容の入ったダイレクトリーのようなものです。

<img width="912" alt="Screenshot 2019-08-18 at 10.17.39.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407366/d295cc85-d5de-cac3-e65b-23c4f73e6e00.png">

表(テーブル)のアイコンをクリックすると、下のような画面がでてきます。
ここで表の性質を定義していきます。

<img width="1254" alt="Screenshot 2019-08-18 at 9.59.15.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/407366/f7650a72-a83f-7c94-1ca9-3d9b6466aa92.png">

||意味           |
|----------|----|
|PK|Primary Key (各列を一意に示す。) |
|NN|Not Null|
|UQ|Unique key(各列を一意に示し、かつ複数存在できる)|
|BIN|Binary|
|UN|Unsigned|
|ZF|ZeroFill|
|AI|Auto increment|
|G|Generated|
PageSpeed InsightsでドキュメントTTFBはSpeedIndexにしか影響しない

PageSpeedスコアを調べる中で、ドキュメントTTFBとスコアの関係に疑問がありました。

ドキュメントTTFBが遅いとその後のプロセスがすべて一様に遅れるので、最もスコアへの相関性が高いはずと思いきや、そうはなりませんでした。

> PageSpeed Insightsの改善にはまずJavaScriptのダイエットを
> https://qiita.com/miyanaga/items/b3d955a6fd70ef7d89ec

# 2020/6/3 追記

本家レポートより**PageSpeed Insightsのスコア改善が捗る裏レポートツール**を公開しました。合わせてご参考ください。
https://simulate.site/cheatspeed-insights/

# 検証

シンプルなHTMLを出力するPHPを用意し、`wait`パラメータの分`sleep`させてドキュメントTTFBを偽装します。

```php:index.php
<?php sleep($_GET['wait'] ?? 0) ?>
<!doctype html>
<html lang="ja">
<head>
  <meta charset="utf-8">
  <title>TTFB Test</title>
</head>
<body>
  <p>PageSpeedスコアとドキュメントTTFBのテスト</p>
</body>
</html>
```

## TTFB≒0秒の場合

`wait`パラメータに0を指定した場合です。予想通りというか当然100点になります。

![PageSpeed_Insights.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35178/a38b18d4-3527-4f2a-85bf-8a2786ea7e7d.png)

`ラボデータ`の各タイミングが`0.7秒=700ms`というのは謎ですが…

## TTFB≒3秒の場合

`wait`パラメータに3を指定します。

![PageSpeed_Insights.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35178/e07204ce-6aae-c733-86d1-1ac69781f82d.png)

スコアが91に下がりましたが、ラボデータは`速度インデックス(SpeedIndex)`しか変化していません(TTIの0.8秒は誤差ということにします…)。

延長したTTFBは3秒ですが、`速度インデックス`は4.8-0.7=4.1秒伸びています。

※ 速度インデックスの単位が秒というのはちょっと変なんですが、ここではスルーします。

## TTFB≒5秒の場合

`wait`パラメータに5を指定します。

![PageSpeed_Insights.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35178/c77e4bff-b337-801a-0623-07f2fe09394f.png)

スコアは80に下がりましたが、こちらもラボデータは`速度インデックス`のみが長くなりました。また同じくTTFB5秒延長に対し、7.4-0.7=6.7秒伸びています。

以上の結果から、次のことが確認できました。

* ドキュメントTTFBが遅くなっても`SpeedIndex`しか遅延しない
* `SpeedIndex`以外の指標はドキュメントTTFB以後のタイミングを起点に計測される

# SpeedIndexにしか影響しないのでスコアとの相関は低い

総合スコアは、コンテンツの初回ペイント`FCP`、意味のあるコンテンツの初回ペイント`FMP`、速度インデックス`SpeedIndex`、CPUの初回アイドル`FID`、インタラクティブになるまでの時間`TTI`を元に計算されます。

> PageSpeed Insightsの点数はどのように計算されているか。100点をとるための条件
https://qiita.com/miyanaga/items/d38124cdd64a1999fed9

`SpeedIndex`の総合スコアに対する影響力は`4/15`です。仮に`SpeedIndex`が0点評価でもほかが100点なら73点を獲得できます。

# Chrome DeveloperツールのAuditsタブはまた挙動が異なる

Auditsタブで、TTFB≒5(wait=5)を試してみたところ、次の結果になりました。

<img width="732" alt="DevTools_-_dummy_ttfb-test_rehearsal_lightfile_net_index_php_wait_5.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35178/51bf15a5-581a-05f3-8bc6-1de561efbe3a.png">

FCP、FMPなどのタイミングが軒並み5秒強となっています。当初予想した**「TTFBが遅れるとその後の処理が一様に遅れる」**状態です。

全体の指標が伸びてしまったのでスコアも大きく悪化しています。

ちなみに`npm`版の`Lighthouse`を単体で試したところ、前述の`PageSpeed Insights`と同じく`SpeedIndex`にしか影響しませんでした。

ChromeのAuditタブは実はLighthouseと違うという新たな謎を残してしまいました…
.NET DataGridViewのカスタムセルを実装する場合の注意点

# TL;DR(要約)

- DataGridViewのカスタムセルを実装する場合にはまりやすい点
- 関連付けるコントロール自体がユーザーコントロールの場合には、入力処理が反映されないことがある


# 課題1

## 課題：キーボードで移動した場合に、独自コントロールの処理が反映されない

独自コントロールで、Validatingイベントで、編集が終わった後に、値チェック（最大、最小）と書式の処理を行っていた。

しかし、キーボードで移動した場合は、Validatingイベントが発生するタイミングが異なるため、独自コントロールから、DataGridViewに値が反映されなかった。

マウスで別セルを指定して移動した場合には反映された。

### マウスで別セルを指定して移動

|イベント|Me.Textの値|
|:--|:--|
|OnTextChanged|1
|GetEditingControlFormattedValue|1
|OnTextChanged|12
|OnTextChanged|123
|OnLeave|123
|OnTextChanged|123.00
|OnValidating|123.00
|GetEditingControlFormattedValue|123.00
|GetEditingControlFormattedValue|123.00

### Enterキーで移動

|イベント|Me.Textの値|
|:--|:--|
|OnTextChanged|1
|GetEditingControlFormattedValue|1
|OnTextChanged|12
|OnTextChanged|123
|GetEditingControlFormattedValue|123
|GetEditingControlFormattedValue|123
|OnLeave|123
|OnTextChanged|123.00
|OnValidating|123.00

## 解決策：OnValidatingイベントで上書き

```vb
    Protected Overrides Sub OnValidating(e As CancelEventArgs)
        MyBase.OnValidating(e)

        _DataGridView.CurrentCell.Value = Me.Text
    End Sub
```
上記の``_DataGridView``は、EditingControlDataGridViewでセットされたもの。詳しくは、リソース参照。

```vb
   '編集するセルがあるDataGridView
    Public Property EditingControlDataGridView() As DataGridView _
        Implements IDataGridViewEditingControl.EditingControlDataGridView

        Get
            Return Me._DataGridView
        End Get
        Set(ByVal value As DataGridView)
            Me._DataGridView = value
        End Set
    End Property
```

# 課題2

## 課題：DataGridViewの表示書式を既定で変更したい

通貨型セルなどを実装した場合、既定で右寄せとしたい。

## 解決策：カスタム列のコンストラクタで指定する

既定値を設定するなどの方法があるが、カスタム列のコンストラクタで実装する方法が、紛れがない。（汎用性はなくなるが）

```vb
    Public Sub New()
        MyBase.New(New CcOldDataGridViewCurrencyCell())

        '初期化処理があればここに記載
        '右寄せ
        Me.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight
        Me.DefaultCellStyle.Format = "#,0"
    End Sub
```

# リソース

■DataGridViewにMaskedTextBoxを表示する
https://dobon.net/vb/dotnet/datagridview/maskedtextboxcolumn.html
ShellScript Bash コーディング規約

# 目的

- スクリプトファイルの品質を一定に保つ。
- ルールを決めておくことにより、書き方の変化を減らす。
※これは個人的なコーディング規約です。プロジェクトで決まっている場合や、個人的にもっと良い規約があればそちらを使用してください。もしもっと合理的な規約があれば教えていただきたいです！

# bashコーディング規約
1. shebang(シバン)は`#!/bin/bash`を使用する。
1. インデントは半角スペース二つ入れる
1. スクリプトの使用方法や用途、実行時に必要名引数をスクリプトの最初に記載する。
1. パイプの前後に半角スペースを一つづつ入れる。
1. 変数系
    - 格納される値が変化しないときはreadonly宣言をする。
    - 格納される値が変化しないときは変数名を全て大文字にする。
    - 格納される値が変化するときは変数名を小文字にする。
    - 複数の単語を用いて変数名をつけるときは単語と単語の間を`_`(アンダーバー)で繋ぐ。
    - ファイルパスを格納するときは格納される値の末尾に`/`(スラッシュ)をつけない
    - スクリプトを運用中に修正する可能性のある変数の定義は序盤で行う
    - スクリプトの運用中に修正為る可能性が著しく低い変数の定義は処理で使用する直前で定義する。

1. 関数系
    - 必ずfanction宣言を行う。
    - 関数名は小文字で命名する。
    - 複数の英単語を用いて関数名をつけるときは単語と単語の間を`_`(アンダーバー)で繋ぐ。
    - 必ずreturnする。returnのコードは正常終了時は0、異常終了時は1
1. if文
    - `if`と`then`は同一ステップ内に記載する。
    - `if`と`else`と`fi`はインデントを合わせる。
    - `;`(セミコロン)の後ろは半角スペースを一つ入れる
1. for文 while文
    - `for`と`while`はインデントを合わせる。
    - `do`と`done`はインデントを合わせる。
promiseについて

 Firebaseの関数には.then と .catch で「特定の処理に成功（失敗）したときに実行する処理」
なお、.then と .catch を使う、このような仕組みのことを Promiseという。
 コールバック関数とは「特定の処理が完了するのを待ち、その処理が成功したら○○を、失敗したら△△を実行する」という処理の書き方をしたときの○○や△△の処理のことをいう。
フィボナッチ数列

#再帰を使ったフィボナッチ数列
このアルゴリズムには一つの欠陥がある！
###計算量の大きさ
なぜなら、fibonacchi()をf()と表すと、例えばf(5)を求める際にf(4),f(3)が必要となるが、更にf(4)で再びf(3)を呼び出す必要がある。つまり。一度計算した値を再び計算するという無駄・欠陥がある！！

```c
#include<bits/stdc++.h>
using namespace std;

int fibonacci(int n){
    if (n==0 || n==1) return 1;
    else return fibonacci(n-2) + fibonacci(n-1);
}

int main(){
    int N,ans; cin >> N;
    ans=fibonacci(N);
    cout << ans;
}
```

#動的計画法を使ったフィボナッチ数列
このアルゴリズムでは、フィボナッチ数を小さいほうから計算していくので、F[i]を計算するときには既にF[i-1]とF[i-2]が計算されており、それらを有効利用できる！

```c
#include<bits/stdc++.h>
using namespace std;

int main(){
    int n; cin >> n;
    int F[50];
    
    F[0]=F[1]=1;
    for (int i=2; i<=n; i++) F[i]=F[i-1]+F[i-2];
    
    cout << F[n] << endl;
    return 0;
}
```

#メモ化再帰によるフィボナッチ数列
このアルゴリズムでは、一度計算したf[i]の値を配列の要素F[n]に記録しておくことで再計算を回避できる！

```c
#include<bits/stdc++.h>
using namespace std;

int fibonacci(int n){
    int  F[100]={0};
    if (n==0 || n==1) return F[n]=1;
    if (F[n]!=0) return F[n];
    
    return F[n] = fibonacci(n-2) + fibonacci(n-1);
}

int main(){
    int N,ans; cin >> N;
    ans=fibonacci(N);
    cout << ans << endl;
    return 0;
}
```

#注意 vectorを用いて処理するとTLになる
```c
#include<bits/stdc++.h>
using namespace std;

int main(){
    int n; cin >> n;
    vector <int> A(n);
    A[0]=A[1]=1;
    
    for (int i=2; i<=n; i++){
        A[i]=A[i-1]+A[i-2];
    }
    
    cout << A[n] << endl;//n=5までしか出力できない！
}
```
VBAでMediaPlayerを搭載させてみた 

VBAで音を鳴らそうと思った。

最初はフォームにMediaPlayerを張り付けてみたが、ActiveXのエラーが出たりするのでうんざり。
で、こうしてみた。

```vb:VBScript
    '' メディアプレイヤー設定
    Set WMP2_red = CreateObject("new:{6BF52A52-394A-11d3-B153-00C04F79FAA6}")
```

これでActiveXの問題は解決。

だが、いざ使ってみると、最初に音を出すときにディレイがある。
決して環境（スペック）の問題ではない。


仕方ないので、ダミーで音を出させた。

```vb:VBScript
    '' 最初の音にディレイがあるため、一度（ミュート状態で）音を出しておく
    WMP2_red.settings.mute = True
    WMP2_red.Controls.Play
```


これで（ある程度は）解決した。


ちなみに、Windows10 + Excel2000ですがね。
Arduinoでシャープ製 測距センサー(GP2Y0A21YK0F)を使用する方法

#用意するもの
・Arduino
・シャープ製(GP2Y0A21YK0F) http://akizukidenshi.com/catalog/g/gI-02551/
・ブレッドボード
・各種配線
#シャープ製 測距センサー(GP2Y0A21YK0F)について
![unnamed.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/393970/1e443fa9-2f79-945c-e887-61491e8b49b0.jpeg)

| 番号     |       意味 |   
|:-----------------:|:------------------:|
|     1      |              V0(信号線) |       
| 2           |            GND |      
| 3             |              Vcc（4.5-5.5V） | 
※色がややこしいので配線時は注意。
※測距範囲：10〜80cm

#とりあえず信号を見る。     
センサから来た信号を読み取り、シリアルモニタで表示させるPG。
        
```program
const int ANALOG = 5;

void setup() {
  Serial.begin(9600);
 
}

void loop() {
  int distance = analogRead(ANALOG);
  Serial.println(distance);
  
}
```

#配線
![Untitled Sketch_ブレッドボード.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/393970/ec93c05f-661e-220a-0e5c-9276777f3649.jpeg)
ArduinoはUSB給電。センサのみ外部電源使用。

#注意点
・測距センサVccにArduinoに搭載されている5Vを使用すると、一定間隔でノイズが入り、数値が乱れた。
→外部電源で測距センサを駆動させることで、ノイズを許容範囲に収めることができる。

検証状況：センサを天井に向け固定（天井テーブル間距離1.5ｍなので測定範囲外）

・Arduino5V使用時。一定間隔で数値が大きく変動する。コンデンサを突っ込んだりしても変わらず。
<img width="1440" alt="スクリーンショット 2019-08-16 16.28.27.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/393970/2b0f30b2-28ef-9596-fc96-e1894cc32217.png">
・外部電源使用時。変動小。
<img width="1440" alt="スクリーンショット 2019-08-16 16.29.28.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/393970/7a5fd8db-cb77-4f6f-2821-d827b0002ccb.png">

#せっかくなので、実距離にする。
```program
float Vcc = 5.0;//電源電圧
float distance_1;
float distance_2;
const int ANALOG = 5;//センサ信号入力

void setup(){
 Serial.begin(9600);//シリアル通信
  }
 
void loop(){ 
 distance_1 = Vcc*analogRead(ANALOG)/1023; //(5.0V*センサ数値/1023)1023は5V入力時の値
 distance_2 = 26.549*pow(distance_1,-1.2091); //距離換算
 Serial.println(distance_2); 
 delay(100); 
 } 
```

<img width="1440" alt="スクリーンショット 2019-08-16 22.57.21.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/393970/7985a293-83f4-7de7-03b0-ac5e693bef98.png">
cm換算になりました。精度的には結構正確に出てそう。要検証ですが・・・
他にも超音波測距センサーを手に入れたので後々比較したいと思います。
【Vue初心者向け】Vueで作るBMI計算アプリ

Vue.jsで作ったBMI計算機のサンプルコードです。

対象者は、Vueでハローワールドまで出せて、そのあと色々サンプルコードいじってみたい人です。

体重、身長を入力して、ボタンを押すとBMI値が計算されるシンプルな仕組みです。逆に、この仕組みだけのコードなので、構造がシンプルで初心者向けに理解しやすくなっています。

実際に動作はこちらで確認できます。

[BMI計算機サンプルコード](https://code.ameneko.com/bmi-maker)

(このサイトは、VueとFirebaseに特化したサンプルコード集にしていく予定です。詳しくは[ブログ](https://www.katonobo.com/entry/make-code-site)で)

##サンプルコード

```
<template>
  <div class="bmi-maker">
    <div><input v-model="weight" type="text" placeholder="体重">Kg</div>
    <div><input v-model="height" type="text" placeholder="身長">Cm</div>
    <div><button @click="calculate">計算する</button></div>
    <div v-if="result">結果：{{result}}</div>
    <div v-if="err">{{err}}</div>
  </div>
</template>

<script>
export default {
  name: 'bmi-maker',
  data(){
    return{
      weight: '',
      height: '',
      result: '',
      err: '',
    }
  },
  methods:{
    calculate(){
      //BMI ＝ 体重kg ÷ (身長m)2
      //身長をセンチで入力しているので、100で割る
      if(this.weight && this.height){
        this.height = this.height / 100
        this.result = this.weight / (this.height * this.height)
        this.err= ''
      }else{
        this.err = "体重と身長を入力してください！"
      }
    }
  }
}
</script>

<style scoped>
.bmi-maker{
  max-width: 1000px;
  margin:auto;
}
</style>
```
(追記8/19 BMIの計算式を間違えていましたの訂正しました。)

ポイントは、「計算する」ボタンを押したらmethodsのcalculate()が反応するところです。
「@click」はvueの「v-on:click」の省略方法です。よく見かけるはずなので覚えておいて損はないでしょう。

参考：
[イベントハンドリング](https://jp.vuejs.org/v2/guide/events.html)
moment.jsの使い方メモ

#moment.jsを使ったのでメモ
久しぶりの投稿となりますが、仕事でmoment.js（正確には、moment-with-locales.min.js）を利用したので、使った機能をメモしておくことにしました。全ての機能を使ったわけではありませんが、今後も使いそうなので、都度追記をしていこうと思っています。
（毎回調べていると時間がかかるばかりなので、自分用にまとめておこうと思って。）

## moment.jsの使い方
### 現在日時を取得する。
```js
var now = moment();
```

### 文字列に変換（書式指定可能）
```js
moment().format("YYYYMMDD");
```

| 指定文字 | 取得対象 |
|:---------:|:----------:|
|  YYYY   | 年     |
|  MM     |   月     |
|  DD     |   日     |
|  HH     |   時（24時間表記）|
|  hh     |   時（12時間表記）|
|  mm     |   分  |
|  ss     |   秒  |

### 日時の加算
現在から5日後、とか特定日時から5日後などを求められます。引数を変えると、月も時間も加算することができます。

```js
var addedDate = moment().add(5, 'd');
var addedDate = moment(targetDate).add(5, 'd');
```

### 月の最初の日を取得する。
カレンダーを作るのに使いました。（曜日の関係で前の月の最終週を表示するなど）

```js
var startOfMonth = moment().startOf('month');
```

### 指定した週の特定曜日の日時を求める
days()の引数に指定するのは0が日曜日で6が土曜日です。1-7とか指定する（-6でも良い）と前の週の月曜日が取得できます。

```js
var firstMonday = moment().startOf('month').days(1);
```

### 日時の差分を求める。
```js
var diffDays = endDate.diff(startDate, 'days');
```

## 参考資料
* [Moment.js（公式）](https://momentjs.com/)
* [全52項目！Moment.js日付データ取得・設定する（Setter, Getter）実例](https://blog.capilano-fw.com/?p=1033#day)
* [moment.js の使い方](https://qiita.com/ue5963/items/729c76fe5b821e5c504e)
* [日付処理が楽になる！Moment.jsの使い方](https://qiita.com/kyota/items/806da61fb8fffa34b695)

# Disclaimer
* この記事は個人的なものです｡私の雇用者とは全く関係はありません｡（一応つけておきます）
Gitリポジトリの歴史を書き換えた後のPull Requestはどうなるのか

Gitリポジトリに誤って機密情報をcommit/pushしてしまった場合には歴史から抹消しないとセキュリティリスクを抱えてしまいます。
歴史からの抹消は [git filter-branch](https://git-scm.com/book/ja/v1/Git-%E3%81%AE%E3%81%95%E3%81%BE%E3%81%96%E3%81%BE%E3%81%AA%E3%83%84%E3%83%BC%E3%83%AB-%E6%AD%B4%E5%8F%B2%E3%81%AE%E6%9B%B8%E3%81%8D%E6%8F%9B%E3%81%88#%E6%9C%80%E5%BC%B7%E3%81%AE%E3%82%AA%E3%83%97%E3%82%B7%E3%83%A7%E3%83%B3:-filter-branch) を使えばリポジトリの書き換えは簡単にできます。

さて、filter-branchで歴史を書き換えた場合にGitHub上のPull Requestはどうなるでしょうか？

## 検証

[こちらのリポジトリ](https://github.com/rizumi/FilterBranchTest)で以下の手順を検証

1. `config.txt` というファイルの追加と変更Pull Requestをマージ
1. `git filter-branch --tree-filter 'rm -f config.txt' HEAD --all` で歴史からconfig.txtを抹消
1. `git push -f origin --all` でリモートブランチのアップデート

## 結論

- リポジトリのログから見た場合
![Screen Shot 2019-08-18 at 18.19.06-fullpage.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/117503/9d3d637d-5899-bdf3-6dac-0dcfd6e9cbd5.png)

- マージ済みのPull Requestから見た場合
![Screen Shot 2019-08-18 at 18.20.08-fullpage.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/117503/de005af8-5361-e433-9e58-39aad70e226e.png)


現在積まれているcommitは書き換わりましたが、**マージ済みPull Requestのcommitは書き変わらないようです**😱
機密情報をプルリク経由でマージしてしまった場合、リポジトリを一度削除するしか無さそうですね...

## 備考
- GitHub以外のサービスでは検証していないので他のホスティングサービスでは挙動が違う可能性があります
Dockerを使用して静的コンテンツをデプロイしてみた

# はじめに
この記事はコンテナ勉強用として試したことまとめたものです。
仕事でDockerを使ったアプリケーションデプロイをしているので、理解を深めるために自分でも簡単なアプリケーションデプロイを試してみました。

# 手順
- CentOSをベースイメージとしてWebサーバに実行環境を構築する。
    - RUNコマンドでNginxをインストール
    - CMD命令でデーモンの実行
    - ONBUILDコマンドでWebコンテンツを配置

# イメージのビルド
* 以下内容でビルドを実行する。（Dockerfile.baseファイルとして保存）

```dockerfile

# イメージ設定
FROM centos:7

# リポジトリ追加
COPY ./nginx.repo /etc/yum.repos.d/nginx.repo

# Nginxインストール
RUN yum -y install nginx

# ポート指定
EXPOSE 80

# Webコンテンツ配置
ONBUILD ADD website.tar /usr/share/nginx/html

# Nginx実行
CMD ["nginx", "-g", "daemon off;"]
```

* コマンド実行

```shell

# docker build -t web-base -f Dockerfile.base ./
Sending build context to Docker daemon  717.3kB
Step 1/6 : FROM centos:7
 ---> 9f38484d220f
Step 2/6 : COPY ./nginx.repo /etc/yum.repos.d/nginx.repo
 ---> 663ac757cfe4
Step 3/6 : RUN yum -y install nginx
 ---> Running in accbe252a05c
Loaded plugins: fastestmirror, ovl
Determining fastest mirrors
 * base: ftp.tsukuba.wide.ad.jp
 * extras: ftp.tsukuba.wide.ad.jp
 * updates: ftp.tsukuba.wide.ad.jp
Resolving Dependencies

・・・（中略）・・・

Complete!
Removing intermediate container accbe252a05c
 ---> bef67394d4e0
Step 4/6 : EXPOSE 80
 ---> Running in e1f36112e98c
Removing intermediate container e1f36112e98c
 ---> 9c20f6dda90b
Step 5/6 : ONBUILD ADD website.tar /var/www/html/
 ---> Running in 5f1817472d21
Removing intermediate container 5f1817472d21
 ---> 69b8d93ce29e
Step 6/6 : CMD ["nginx", "-g", "daemon off;"]
 ---> Running in a22c79cffdc5
Removing intermediate container a22c79cffdc5
 ---> ab4088c1f974
Successfully built ab4088c1f974
Successfully tagged web-base:latest
#
```

# Webコンテンツを開発
* HTMLやCSSなどでwebsiteという形でtarファイルにまとめる。

# Webサーバ用のイメージ作成
* FROM命令で先ほど作成したイメージを指定する。（Dockerfileファイルとして保存）

```dockerfile
# Dockerイメージの取得
FROM web-base
```

* コマンド実行

```shell
# docker build -t photoview-image ./
Sending build context to Docker daemon  1.072MB
Step 1/1 : FROM web-base
# Executing 1 build trigger
 ---> 9f2e92d06358
Successfully built 9f2e92d06358
Successfully tagged photoview-image:latest
#
```

# Webサーバのコンテナ起動
* コマンド実行

```shell
# docker container run -d -p 80:80 photoview-image
01b50cdbfb99ad9ec78aa8182c691b8bdec080c83a18d8ae998b82a1f9095bef
#
```

* アクセス確認<br>
<img width="599" alt="キャプチャ3.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/466400/2344a6fb-bc6f-d6db-7133-d8ca93e8f7ed.png">

# まとめ
* 意外と簡単に構築できた。
* Dockerfileの記述方法について理解を深めていきたい。

# 参考
* https://qiita.com/sbut_sug/items/b7c92ca5c7215d294355
* https://www.shoeisha.co.jp/book/detail/9784798153223
LambdaでPythonの3rd-Partyライブラリを使用する方法

## 背景

standard-library等のLambdaに標準で同梱されているモジュール以外を使用する場合には、import対象のモジュールを含めたデプロイパッケージを作成しなければならない。

## 解決方法
pipでカレントディレクトリにライブラリをインストールし、まとめてzip化してアップロードすることでライブラリが使えるようになる。

```console
# 対象ライブラリのカレントディレクトリへのダウンロード
$ pip install requests -t ./
 
# ダウンロードしたファイルの確認
$ ls
bin                          chardet-3.0.4.dist-info  requests
certifi                      get_xbrl.py              requests-2.22.0.dist-info
certifi-2019.6.16.dist-info  idna                     urllib3
chardet                      idna-2.8.dist-info       urllib3-1.25.3.dist-info
 
# 不要なファイルの削除
$ rm -rf *.dist-info
$ rm -rf bin
 
# デプロイパッケージの作成
zip -r lambda_function.zip ./*
```

- Lambdaからzipでのアップロードを選択すると以下のようにコードが階層構造で作成され、対象のライブラリが含まれていることが確認できる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390688/540cd025-265b-1aa3-93bc-5514efee24f2.png)
pythonで使えるHTMLバリデータをつくった

### つくったわけ
一般ユーザ（大体は管理者だと思いますが）に対して、リッチテキストエディタを組み込んだ画面を提供してHTMLタグ込みの文章を入力可能としているシステムは多く存在しますよね。

ああいう感じの画面があるシステムを作っていたんですが、そのシステムの特性として、ひとつひとつの文章はそんなに長くないかわりに、文章数が多くなってしまいそうな予感がありました。
その時に「CSVインポートできたらおしゃれよなぁ・・・」と思い検索したものの、~~google先生に嫌われているのか、しっくりくるものを見つけられなかったので、つくりました。
（何かいいものがあってご存じの方は是非教えてください）~~
（2019/8/24追記）
エラーにしたかったので、「バリデーター」でばっかり検索してたので見つかりませんでしたが、「サニタイザー」で検索したら、より高機能なものがありました。  
[これ（bleach）](https://pypi.org/project/bleach/)  や [これ（html-sanitizer）](https://pypi.org/project/html-sanitizer/)です。  

今回作ったものは、シンプル、かつ作者が日本人ということで、そこに魅力を感じたらお使いください。。。



### できること
処理対象の文字列に任意の「HTMLタグ-属性」が存在するかをチェックすることができます。
つまり
`<a href='~'>リンク</a>  → OK
<a onclick='~'>リンク</a> → NG`

とすることが可能です。


やったね！お疲れさま！README読んで使ってね！
では記事にならないので、簡単に使い方を解説しようかと思います。


[ソースコード(github)](https://github.com/koan-u/custom_html_validator)


### はうつー
**インストール**

```
pip install custom_html_validator
```

**使い方**

```python
from custom_html_validator import CustomHTMLValidater

def main():
    # 許可する任意のタグ・属性の組み合わせ
    ALLOWED_TAGS = {
        # 'tag': ['attr1','attr2']
        'a':['href',''],
        'br':[]
    }

    # 処理対象の文字列
    target_str = '<a href = "xxx">link</a>'
    
    # 初期化と、許可するタグの設定
    parser = CustomHTMLValidater()
    # 設定しなければすべてのHTMLタグ・属性がNG扱い
    parser.set_allowed_tags(ALLOWED_TAGS)

    # 処理対象文字列のチェック
    parser.feed(target_str)
    results = parser.close()
    
    # チェック結果の確認例
    if results['status'] == 1:
        # チェックOK
    elif results['status'] == -1:
        # チェックNG
        # results['detail'] にエラーの理由の文章が格納されている

   next_str = '<b>晩飯食べにいく約束ドタキャンされたのでこの記事かいてる</b>'

   # 閉じタグのチェック処理の関係から、別の文字列をチェックするときはリセットが必要
   # 許可するタグリストは初期化されない
   parser.reset()

   # 許可するタグリストも初期化する場合はこっち
   parser.reset(True)
```

もしひとつのHTMLドキュメントが複数のStringに分かれて格納されるような感じなら、close()をするまえに、別のStringをfeed()すれば、たぶん大丈夫なはずです。
だめだったら、parserに食わせる文字列のほうを加工してください・・・

### ちなみに
テストをして大丈夫だと思ってるのは以下のパターンです。不足や変な挙動をとるものを発見した場合は教えてください...


- 単純な許可する/しない のタグ・属性セットがそれぞれ/どちらも含まれるパターン
- 開始/終了タグが存在しないパターン
- HTML構造がおかしいパターン（`<div><b>ミネソタ優勝</div><a>`みたいな)
- 空タグ系のHTML/XHTMLの形式(`<br>``<br />`)



モジュールの中身も軽く触れる予定でしたが、~~apexやりたくなってきたので~~、いったんおわります。
質問やらバグやらあればお気軽にコメントいただけると幸いです！
Ruby でベルマンフォード法をやってみたい

インプットが以下のように与えられるとする。有効グラフとしておく。

```
V E
a1 b1 c1
...
aV bV CV
```

V: 頂点数
E: 辺数
ax -> bx  に辺が存在していて、そのコストが cx

```text:example_input.txt
5 6
1 2 2
1 3 1
1 4 4
2 4 1
3 5 5
4 5 1
```

このときにたとえば、頂点1 -> 頂点5 の最短経路を知りたいモチベーションがあるとする。

以下のようにすればできる。

```rb:exec.rb
V, E = gets.chomp.split.map(&:to_i)
@edges = readlines.map{|m| m.chomp.split.map(&:to_i)}

# @param Integer s 頂点の番号（1 <= s <= V）
def shortest_path(s)
  d = Array.new(V, Float::INFINITY)
  d[s - 1] = 0
  while true
    update = false

    @edges.each do |e|

      from = e[0]
      to = e[1]
      cost = e[2]
      
      if d[from - 1] != Float::INFINITY && d[to - 1] > (d[from - 1] + cost)
        d[to - 1] = (d[from - 1] + cost)
        update = true
      end
    end

    break if !update
  end
  return d
end
```

たとえば、以下のような出力を得る。

```
shortest(1)
# => [0, 2, 1, 3, 4]
```

1 -> 5 への最短経路は 4
1 -> 4 への最短経路は 3
のようになる。
HaloCodeでエネルギーブレスレット

前回の記事 [halocode使ってみた！](https://qiita.com/48saaan/items/8d9a9db17121e8cee636)ではHaloCodeのセットアップやLチカのサンプルをやってみました

今回は加速度センサーを使ったサンプルを使ってみたいと思います

## エネルギーブレスレット作成
HaloCodeを振ってエネルギーを貯めていくと、LEDがどんどん光っていくプログラムです
### ブロック図
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208438/a42bcca8-91d8-2344-1cc5-9afda70d70ae.png)

### python code

```python:energy_bracelet.py
# generated by mBlock5 for HaloCode
# codes make you happy

import event, halo
# initialize variables
test = 0

@event.button_pressed
def on_button_pressed():
    global test
    halo.led.off_all()
    test = 1
    while not 'test' == 20:
        if halo.motion_sensor.get_shake_strength() > 20:
            halo.led.show_single(test, 255, 0, 0)
            test = test + 1
            time.sleep(0.4)
        elif test == 

    halo.led.show_all(208, 2, 27)
```



...
pythonistaのフォルダ内にクリップボードでコピーしたものを保存する


# 環境
- iPhone 7
- ios 12.3.1
- pythonista 3 ver. 3.2

# コード

```python
import clipboard

#nameは拡張子も含めて書く。
#同階層にあるphotosフォルダに保存したければ'photos/ex.png'で可能
name = 'ex.png'

image = clipboard.get_image()
image.save(name)
#image.show()で表示可能

```
なんとかできた自作キーボードの喜びを爆発させる記事

## この記事で書くこと :sunflower: 
はじめて自作のキーボードを作成してみたので、その体験をアウトプットしようとの試み。

## 自作キーボードを作るに至った経緯

①チームに自作キーボードをしている人がジョインした。←春ごろ
②自分はHHKBを使ってて、特に困ってなかったのですぐに作り始める、ということにはならなかった。
③でも、興味はあって、その会社の人にmeishiという小さなキーボードを作るのを教えて貰った。

![20190818_174042.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/71266/f44cb950-499d-63de-17e4-eeafe14452eb.jpeg)

④何事も経験だと思いつつも、時間が取れずに、ズルズルと時間が過ぎ、夏が来た。 :sunny: 
キー数の少ないキーボードに興味があり、作るなら以下のどれか、、と思っていた。

- [ErgoDash mini](https://github.com/omkbd/ErgoDash/blob/master/mini/Doc/build.md)
- [Corne cherry](https://github.com/foostan/crkbd/blob/master/corne-cherry/doc/buildguide_jp.md)
- [Claw44](https://github.com/yfuku/claw44)


踏み切れない日々が続いていたが、夏やすみを使って作成を開始。

## 実際にかかった時間 :watch: 

最後までClaw44と悩んでいたが、会社の人に、親指が遠くて苦しそうという助言をいただき、そうかと思ってcorneにした。
それ以降はずっとTwitterでCorne cherryと検索してイメトレをしていた。（役に立ったかは未だ解らない。

[遊舎工房](https://yushakobo.jp/) さんに14時すぎに到着し、閉店19時ギリギリまでやって、
残る作業は、スペーサをつけて、プレートをつける作業だけとなった。

半田付けという行為が人生で二回目だったこともあるので、慣れてる人、手先が器用な人はもっと早く作り終わると思う。 :smiley: 

## 難しかったところ
初心者は何が何だか解らず、スペーサも間違えた長さをつけたりして、ネジも回らなくなり、といったミスもそのままに進んでしまった。
キースイッチの足の部分がどこまで押し込んでいいのか解らずなかなかキーを押しても反応しなかった。

キーマップはまだ設定できていないので、早く整えていこうと思う。


## 分離キーボードで作業環境はこう変わる！!
before..

元々はぐちゃっとした机でした。



after..
先週末から会社で使用することができています。 :muscle_tone1: :sparkles: 
なんということでしょう、綺麗に整頓された作業環境になっています！！！　:tada: 


## ファッ、、　かっこよ、、、（自画自賛気味
![20190816_204022.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/71266/d88c93b7-b1bf-ab26-6f50-cbe065655d33.jpeg)
(↑チームの人にキーボード用のシールも貰いました。



- 背中がピシッとした状態になったことで、呼吸がしやすくなりました。
- 好きな色のキーキャップがはめられていることで、テンション高くキーを叩くことができるようになりました！
- エンジニア以外の人も、社内で分離キーボードに興味を持ち始めました！

皆さんもぜひ一つこの夏に作成してみてはいかがでしょうか？　:cat2:
PowerShell でファイル内の文字列をワンライナーで置換する

```powershell:コード例
(Get-Content /path/to/file) -replace "置換したい文字列","置換する文字列"
```

## 複数の文字列を置換したい場合
そのまま後ろに `-replace` を追加するだけ

```powershell:コード例
(Get-Content /path/to/file)
  -replace "置換したい文字列","置換する文字列"
  -replace "置換したい文字列2","置換する文字列2"
```

## 正規表現を使う場合
`-replace` 内でそのまま正規表現が使える

```powershell:コード例
(Get-Content /path/to/file) -replace "<body>.+?</body>",""
```

## 変換後の内容をファイルに保存
そのままリダイレクトすればいい

```powershell:コード例
(Get-Content /path/to/file) -replace "置換したい文字列","置換する文字列" > /path/to/file/replaced
```
httpからhttpsへのredirect設定

# 忘れちゃうので自分用メモ
## Script
.htaccess の始めにこれを書いておけば大丈夫。
ネット上に諸説あったけれど、これが一番シンプルだったので採用。
=301 を忘れずに。

~~~~
RewriteEngine On
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://example.com/$1 [R=301,L]
~~~~

## チェック
[Redirect Chacker](http://www.redirect-checker.org/index.php)でチェック。
> ###Result
> CONGRATULATION. Everything seems to be fine.
> http://www.ggcs.io
> 301 Moved Permanently
> https://ggcs.io/
> 200 OK
ドメインネットワークからパブリックネットワークに変わっている

##PC1台だけネットワーク接続出来ない・・
お客さんのところのシステムの環境でA店に通信が出来ないと盆休み中に連絡があり・・
その時は、とりあえずネット環境がなくて生きていけるシステム構成なので、盆休み明けに対応とさせてもらいました。
こういう時システム屋さんだとドキッとする〜。
##ネットワークは復旧
結論、原因としてはハブの劣化で、調子が悪かったみたいです。
ルータやルータに直で接続している機器は問題なく通信出来ていたので、納得の原因。
お客さんがネットワークまわりの機器について分かる人だったので、ハブの接続等々はお任せしてました。
pingも飛ぶしリモート接続も出来るしオッケーだ！これで終わりかと思いきや・・
数時間後、他の拠点から、A店へ通信が出来ない・・・と連絡がありました。
##pingだけ飛ばない謎の事態
お客さん先に繋ぐ時に使うリモートツールでは客先のPC画面見えるけど、
pingだけ飛ばない！！！
初めての事態だったので、自社のネットワーク担当者に見てもらいました。
##ドメインネットワークのはずなのにパブリックネットワークになっていた
正直原因は不明です。
お客さんの環境はWindows10で、弊社管理下のドメインネットワークに参加しています。

コントロールパネル＞管理ツール＞ローカルセキュリティポリシー＞ネットワークリストマネージャーポリシーから
識別されていないネットワークを選んで場所の種類を未構成にするも変わらず。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/175699/8acdab77-83e5-23c1-2abf-312f4442e9ef.png)
最終的には、コントロールパネル＞ネットワークと共有センター＞アダプターの設定変更＞ネットワーク接続から
イーサネットを選んで右クリック、まず無効化をして再度右クリックして有効化をして直りました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/175699/b94876e2-4c4b-5814-5191-58c33b2e41c3.png)
※PC再起動でも直るようですが、お客さんの環境的に再起動は難しい状態でした。
無効化をすると、インターネットから切断されてしまうので、
遠隔操作していると危険です。今回はお客さんがPCに関して指示があればあたふたしない方というのはわかっていたので、有効化にする作業はしていただきました。

参考サイト：[アクティブなネットワークがドメインネットワークにならない](http://yanor.net/wiki/?Windows%20Server/Active%20Directory/%E3%82%A2%E3%82%AF%E3%83%86%E3%82%A3%E3%83%96%E3%81%AA%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF%E3%81%8C%E3%83%89%E3%83%A1%E3%82%A4%E3%83%B3%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF%E3%81%AB%E3%81%AA%E3%82%89%E3%81%AA%E3%81%84)

私基本的にプログラマーのはずなんですけど、よくネットワークの対応もしているんですよね・・？
ネットワーク苦手だけど、どんどん覚えていくよ・・・
【Vue CLI】5分で作る！最軽量の開発環境！

# プロジェクトごとにVue CLIを導入するのが嫌

Vue CLIってすごく便利だけど、毎回コマンド叩いてプロジェクト作成するのって面倒。
コマンド打つだけならまだしも、大量のnode_moduleが毎回インストールされてしまう。
プロジェクトごとにnode_moduleが生成されるのって容量的にもストレス。

複数のプロジェクトを作る時に、一式のnode_moduleを使い回す方法を見つけたので紹介します。

### 普通にVue CLIを導入する
Node.jsとnpmを使用できる環境なら、すぐにインストールできる。

◆ Vue CLIをインストール

```sh
npm install -g vue-cli
```


◆ Vue CLIが使用できる環境になったかどうか一応確認
　（バージョンが表示されればOK）

```sh
vue --version
```



◆ Vue.jsの開発環境を作成する
　※ 今回の本題は↓コレをプロジェクト作成のたびにやりたくないということ

```sh
vue init webpack vue-cli   //(「vue-cli」の部分がフォルダ名になる)
```

このコマンドを実行すると色々質問を聞かれるが特にこだわりがなければ全てEnterでOK。
そうすると npm installが実行され必要なモジュール一式がインストールされる。


◆ 作成されたフォルダに移動

```sh
cd vue-cli
```


◆ 開発用のサーバーを起動してみる

```sh
npm run dev
```

ターミナルに表示されたURLにアクセスし、「Welcome to Your Vue.js App」というVue.jsのデフォルトの画面が表示されれば成功。
これで、Vue.jsの開発環境はとりあえず完成した。

### 作りたいディレクトリ構造

ここまでは普通にVue CLIを導入しただけ。もちろんもう開発に取り掛かることはできる。
が、今回やりたいのはコレ。

```js:ディレクトリ構造
'vue-cli'
  --'build'
  --'config'
  --'node_modules'
  --'package-lock.json'
  --'package.json'
  --'project01'
      --'src'
      --'index.html'
  --'project02'
      --'src'
      --'index.html'
  --'project03'
      --'src'
      --'index.html'
```
インストールしたパッケージを複数のプロジェクトで使えるようにしたい。使い回したいということだ。
調べに調べど、なかなかこの方法を書いている記事が見つからない。いや、もはや1つもなかった。

以下の手順でコレを実現することができた。

※ 「projectXX」の中に配置するsrcとindex.htmlは、とりあえずインストール時にディレクトリ直下にあるsrcとindex.htmlをそのままコピペすればOK。

◆ projectフォルダ内にsrcとindex.htmlをコピペしたら、ディレクトリ直下にある以下は邪魔なので削除

```js:削除するファイルとフォルダ
'src'
'index.html'
'README.md'
'test'
```

◆ webpack.configでエントリーポイントで呼び出すパスを変更
　「context:」の部分で対象のディレクトリを指定していると思ってもらえれば分かりやすいと思う。

```js:build　▶︎　webpack.base.conf.js
module.exports = {
  context: path.resolve(__dirname, '../01_project/'),  // ここを変更
  entry: { ....
```
もう1箇所。
簡単にいうと「@」で呼び出すパスがここに定義してあるっぽい。階層がずれるのでここも変更する。

```js:build　▶︎　webpack.base.conf.js
resolve: {
    extensions: ['.js', '.vue', '.json'],
    alias: {
      'vue$': 'vue/dist/vue.esm.js',
      '@': resolve('01_project/src'), // ここを変更
    }
  },
```
毎回開発するディレクトリ名に書き換える必要があるが、毎回パッケージをインストールするよりはよっぽどマシではないだろうか。

以下のコマンドを叩き直してもう一度以下を実行してみる。

```sh
npm run dev
```

先ほどと同じ画面が表示されれば成功！

試しにproject1のcomponentのデータを変更してみると自動的に画面がリロードされ更新される。


### 試しに別のプロジェクトも作ってみる
この流れでproject2を作成してみよう。
先ほど修正した以下「project1」にしていた部分を「project2」に変更すれば今度は「project2」が呼び出される。

```js:build　▶︎　webpack.base.conf.js
module.exports = {
  context: path.resolve(__dirname, '../02_project/'),  // ここを変更
  entry: { ....
```

```js:build　▶︎　webpack.base.conf.js
resolve: {
    extensions: ['.js', '.vue', '.json'],
    alias: {
      'vue$': 'vue/dist/vue.esm.js',
      '@': resolve('02_project/src'), // ここを変更
    }
  },
```

この手のやり方で、ローカルに作りたいVueの開発環境を作ることができた。
開発していく中で、色々不具合が出てきてしまうかもしれないが、とりあえず 完。

ローカルに何個も何個も「node_module」一式をインストールしている方、ぜひこの方法お試しあれ！
VisualStudioでビルドした時に includeファイルを開けません。No such file or directory と出る時の対処法 

![fileerror.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/368850/52b07eb4-5419-aa5e-febf-d8d614ccdd5f.png)

こんな感じのやつですね。コードを書いている時は何のエラーも起きないのに、ビルドしてみると起きてしまいました。
#状況
ファイルはこんな感じになってました。(色々省略してます)
![a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/368850/576784a4-7641-cbf3-d846-fa1194780d8b.png)

Engine.libを読み込んでGame.exeでプログラムを実行する感じですね。

Engineプロジェクトのincludeファイルパスに
![inc.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/368850/b7b46b06-b6c3-5030-631d-01a5a2bc98f7.png)
と設定して

```:Object.h
#include "Effect.h"

class Object {
    Effect* m_effect;
};
```
という感じでコードを書いていた所、ビルドしたらエラーが起きてしまいました。
#対処法
GameプロジェクトからEffect.hまでのファイルパスを設定したところ、エラーが消えました。
![o.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/368850/174f3700-0d88-c492-9be3-b1be2fb0ddba.png)
CI/CDについて調べたのでざっくりとまとめる

#CI
- Continuous Integration、継続的インテグレーション
- git pushやcronをトリガーにテストが自動で走る
- 自動で実行されたユニットテストやE2Eテストの結果が通知される
- テストで失敗したらここで止まる

#CD
- Continuous Delivery、継続的デリバリー
- テストが通ったら指定された環境へ最新のコードが配置される



この合わせ技がCI/CDと呼ばれているらしい。
テスト自動化による恩恵を受けつつ、問題が無ければ指定された環境に自動的にデプロイされるという美味しい組み合わせ。
実際にその現場に居たことは無いのですが、短期間に何度もリリースされる現場ではCI/CDは必須とのこと。
プロジェクト立ち上げ時にこの仕組みを作っておくと良いとか。
人の手による作業を減らすことは、掛かる時間もミスも小さくしてくれる。良い仕組みだなと思います。

今回の調べもので参考にしたページを以下に記します。
[アジャイル開発を支えるためのCI/CD](https://qiita.com/newta/items/64e3d2dfd8dad69a3185)
[E2Eテストの導入から学んだこと](https://qiita.com/mt0m/items/7e18d8802843d9f60d28)
[いまさらだけどCircleCIに入門したので分かりやすくまとめてみた](https://qiita.com/gold-kou/items/4c7e62434af455e977c2)
[ビルドとデプロイって結局なんやねん！？！？！？？？みたいな記事](https://qiita.com/isoyam/items/3d1fc5cf7403cdf4818d)
PythonでGmail経由でメール送る

Python、Gmail送れるソン！

```py:send_email.py

# coding: UTF-8
import smtplib
from email.mime.text import MIMEText
from email.MIMEMultipart import MIMEMultipart
from email.utils import formatdate

from email.mime.application import MIMEApplication
from os.path import basename

# 送り元のアドレスとパスワード
FROM_ADDRESS = 'hoge@gmail.com'
PASSWORD = 'hogepass'

TO_ADDRESS = 'piyo@gmail.com'
BCC = 'poyo@gmail.com'
SUBJECT = 'Python、Gmail送れるソン！'
BODY = 'ヒクソン、ドラ〜〜ム叩くソン！'

def create_message(from_addr, to_addr, bcc_addrs, subject, body):
    msg = MIMEMultipart()
    msg['Subject'] = subject
    msg['From'] = from_addr
    msg['To'] = to_addr
    msg['Bcc'] = bcc_addrs
    msg['Date'] = formatdate()
    msg.attach(MIMEText(body))

    path = "./foobar.png"
    with open(path, "rb") as f:
        part = MIMEApplication(
            f.read(),
            Name=basename(path)
        )
    part['Content-Disposition'] = 'attachment; filename="%s"' % basename(path)
    msg.attach(part)

    return msg

def send(from_addr, to_addrs, msg):
    smtpobj = smtplib.SMTP('smtp.gmail.com', 587)
    smtpobj.ehlo()
    smtpobj.starttls()
    smtpobj.ehlo()
    smtpobj.login(FROM_ADDRESS, MY_PASSWORD)
    smtpobj.sendmail(from_addr, to_addrs, msg.as_string())
    smtpobj.close()


if __name__ == '__main__':

    to_addr = TO_ADDRESS
    subject = SUBJECT
    body = BODY

    msg = create_message(FROM_ADDRESS, to_addr, BCC, subject, body)
    send(FROM_ADDRESS, to_addr, msg)
```

## 注意

- パスとかあってるのにログインに失敗してしまうときがある
    - Google側で怪しいアプリからのアクセスをリジェクトしてる可能性
    - https://support.google.com/accounts/answer/6010255
    - 上記リンクから「 [安全性の低いアプリの許可] 」をオンにすれば解決


ヒクソン、ドラ〜〜ム叩くソン！
MySQL 8 の `log_bin` を OFF にする方法

MySQL 8 から log_bin がデフォルトで有効になっているので、無効にしたい。

以下、 mysql-community-server をインストールして、特に何も設定を変更しない場合の直後の状態。

```
mysql> select @@global.log_bin;
+------------------+
| @@global.log_bin |
+------------------+
|                1 |
+------------------+
1 row in set (0.00 sec)
```

# 環境

- CentOS 7.6
- MySQL 8.0.17

# うまくいった方法

## `/etc/sysconfig/mysql` に `MYSQLD_OPTS=--disable-log-bin` を書く

いろいろ調べている過程で `/usr/lib/systemd/system/mysqld.service` を確認したところ、 `/etc/sysconfig/mysql` で mysqld の起動時のパラメータを渡せることがわかった。

```text:/usr/lib/systemd/system/mysqld.service
# Start main service
ExecStart=/usr/sbin/mysqld $MYSQLD_OPTS

# Use this to switch malloc implementation
EnvironmentFile=-/etc/sysconfig/mysql
```

ので、 `/etc/sysconfig/mysql` に下記の行を追加して、

```text:/etc/sysconfig/mysql
MYSQLD_OPTS=--disable-log-bin
```

mysqld を再起動したら、 log_bin は無効になった。

```
mysql> select @@global.log_bin;
+------------------+
| @@global.log_bin |
+------------------+
|                0 |
+------------------+
1 row in set (0.00 sec)
```

プロセスを確認したところ、ちゃんと `--disable-log-bin` 付きで mysqld が起動していた。

```
$ ps aux | grep [m]ysqld
mysql    13890  5.3 18.1 1971088 372208 ?      Ssl  16:38   0:01 /usr/sbin/mysqld --disable-log-bin
```

# 試したけどうまくいかなかった方法

## `/etc/my.cnf` に `disable_log_bin` を書く

MySQL v8 をインストールしたときに自動生成される `/etc/my.cnf` に下記のように書かれていて、 `disable_log_bin` の行頭の `#` を削除して設定を有効にしたけど、 log_bin は無効にならなかった。

```
# Remove the leading "# " to disable binary logging
# Binary logging captures changes between backups and is enabled by
# default. It's default setting is log_bin=binlog
# disable_log_bin
```

## `systemctl set-environment`

`systemctl set-environment` で環境変数を設定できるけど、 OS を再起動すると設定した変数は消えていた。（もしかすると永続化する方法があるのかもしれないけど、調べた限りでは見つけられなかった。）

なんらかの理由で OS を再起動した際に自動で起動した mysqld は log-bin が無効化されていないことになるので、この方法は却下した。

```
$ sudo systemctl set-environment MYSQLD_OPTS=--disable-log-bin
```
[Android]設定画面の設定項目をすべて一覧する

# 環境

- androidx.preference 1.0.0

# コード

以下の例では、設定のキーをすべてログ出力している。
キモになるのは、一覧した `Preference` に `PreferenceGroup` が紛れ込んでいるところ。

```java
PreferenceScreen prefScreen = getPreferenceScreen();
int prefCount = prefScreen.getPreferenceCount();

for (int i = 0; i < prefCount; i++) {
	Preference pref = prefScreen.getPreference(i);
	if (pref instanceof PreferenceGroup) {
		setupPrefsRecursive((PreferenceGroup)pref);
	} else if (!Strings.isNullOrEmpty(pref.getKey())) {
		Log.i(TAG, pref.getKey());
	}
}

private void setupPrefsRecursive(PreferenceGroup prefGroup) {
	int prefGroupCount = prefGroup.getPreferenceCount();
	for (int i = 0; i < prefGroupCount; i++) {
		Preference pref = prefGroup.getPreference(i);
		if (pref instanceof PreferenceGroup) {
			setupPrefsRecursive((PreferenceGroup)pref);
		} else if (!Strings.isNullOrEmpty(pref.getKey())) {
			Log.i(TAG, pref.getKey());
		}
	}
}
```

で以下のような設定があったとすると

```xml
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
                  xmlns:mozc="http://schemas.android.com/apk/res-auto">
    <PreferenceCategory android:title="@string/pref_cat_1">
        <CheckBoxPreference
            android:defaultValue="false"
            android:key="pref_key_1"
            android:title="@string/pref_title1" />

        <PreferenceCategory android:title="@string/pref_cat_1_1">

            <Preference
                android:key="pref_key_2"
                android:persistent="false"
                android:title="@string/pref_title2">
            </Preference>
        </PreferenceCategory>
    </PreferenceCategory>

    <PreferenceCategory android:title="@string/pref_cat_2">
        <CheckBoxPreference
            android:defaultValue="true"
            android:key="pref_key_3"
            android:title="@string/pref_title3" />
    </PreferenceCategory>
</PreferenceScreen>
```

以下のような出力になる。

```
pref_key_1
pref_key_2
pref_key_3
```

# 参考

特に無かったから書いた。
WSL2 にしたいのにエラーが出る問題

WSLのバージョン2が使えるということを聞いて、変更しようとしたのですがエラーが出てしまったので備忘録
環境: Microsoft Windows [Version 10.0.18963.1000]

#WSL2に変更時のエラー内容
- 仮想ディスク システムの制限により、要求された操作を完了できませんでした
- bsdtar: Write error 
- 0xC03A001A
- 0x80070040

この辺りのエラー解決策です。
原因はWSLのフォルダが圧縮対象であったことです。
お急ぎの方は下の解決策へ

# 余談
実は、このエラーの前に
`仮想ディスク システムの制限により、要求された操作を完了できませんでした`
というエラーも出てたりしてたんですが、Cドライブのオプション見ても圧縮してないしな～って思っていた自分がいました。

デフォルトバージョンを2にして再インストとかしたんですが、結局
`0xC03A001A`　とか　`0x80070040` のエラーに...

### WSL2への更新手順
1:（WSLを入れてないならWindows Storeからubuntuとかを入れて起動して初期設定）
2: PowerShellを管理者として実行して以下のコマンド
  $`wsl -l`
  ここで名前を確認（UbuntuとかUbuntu-18.04とか)
3:  $`wsl --set-version 名前 2`
完了！のはずだった...

# 解決策
WSLのフォルダの圧縮を外す。
WSLの格納フォルダは
`C:\Users\[name]\AppData\Local\Packages`の中にある
`CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc`みたいなやつです。
（`%localappdata%\Packages`をURLバーにいれるといい感じの場所に飛べます）

この長いフォルダを
右クリック -> プロパティ -> 詳細設定 -> 内容を圧縮してディスク領域を節約する
のチェックを外す。

サブディレクトリまではしなくていいらしいけど、自分はした。
後は再起動すれば無事変換できた。めでたしめでたし。

#参考
https://github.com/microsoft/WSL/issues/4103#issuecomment-504699751