OmniAICreator/Qiita-1.07M huggingface dataset:
[Flutter]Widgetの使い方

AndroidStudioでoptionキー + Enterキー　→　widgetの追加や削除が可能

---

Scaffold　・・・　画面全体を表す（配下にボタンやナビゲートバーなどを配置）

Text("xxx"),　・・・　画面にxxxと表示される

actions: <Widget>[Icon(Icons.add), Icon(Icons.share)],　・・・　アイコンを配置できる

Column()　・・・　Columnの中身の要素が縦並びになる
ex.

```
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'aaa:',
            ),
            Text(
              'bbb',
            ),
            Text(
              'ccc',
            ),
          ],
        ),
```

↓

```
aaa
bbb
ccc
```

Row()　・・・　Rowの中身の要素が横並びになる
ex.

```
        child: Row(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'aaa:',
            ),
            Text(
              'bbb',
            ),
            Text(
              'ccc',
            ),
          ],
        ),
```

↓

```
aaabbbccc
```

Padding()　・・・　Padding内の要素に対し空白を設ける
Container()　・・・　Container内をブロック化（この中で`color: Colors.red`とすることでブロックを赤色にすることができる）
`height: double.infinity`にするとContainerの高さをbody全体にすることができる
<img width="407" alt="スクリーンショット 2020-05-27 17.10.53.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/397642/fbafe426-274d-9e54-a45d-2ee85b257e69.png">
<img width="487" alt="スクリーンショット 2020-05-27 17.09.50.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/397642/26e06fd7-32c3-9784-8536-06f9f7fcb6e5.png">
2020年6月　グループウェアの検討（費用比較）

# 概要

突然ではありますが、グループウェアの導入について検討することになりました。
無料のものから有料のものまで、世の中にはたくさんのグループウェアがあります。
グループウェア製品自体の評価などは、いろんなサイトで公開されておりましたが、自分たちが求める機能要件に合わせて、費用比較が欲しくて、自分で作りました。

この記事は、あくまでも自身の事情に合わせた機能要件を前提として、独断と偏見で選出したグループウェア製品の費用比較を行っております。

# グループウェアの調査

## 前提条件

私の事情として、以下の条件を前提としてグループウェアの費用比較を行うための調査を実施しました。

- 利用者の規模は160名規模とする
- 利用する機能
    - 掲示板やメッセージなどの情報配信を行う機能
    - ファイル管理機能
- グループウェアに標準的に存在するようなスケジュール機能（グループウェアといったらスケジュール管理が中心だろう。。。）やポータル機能などは必須の機能要件ではない。
- 重要なのはなるべく低コストで運用できること。ミニマムスタートできること。

## グループウェア調査

無料から有料までのグループウェアで

- 完全無料のSaaSグループウェア
- 無料でオープンソースなグループウェア
- 有料のSaaSグループウェア

を調査して、160名規模で利用する場合、どの程度費用がかかりそうなのか、まとめてみました。

|#|グループウェア|月額料金（160名）|スマホ対応|掲示板／メッセージ系機能|ファイル管理機能|その他機能|備考|
|:--|:--|:--|:--|:--|:--|:--|:--|
|1|[R-GROUP](https://jp.r-group.com/)|0円（完全無料／無制限）|Web版対応|○|○|タイムライン，メール，タイムカード，無料通話，名刺管理，チャットなど|SaaSで提供<br>ディスク容量も無制限|
|2|[GroupSession](https://groupsession.jp/products/index.html)<br><br>オープンソースグループウェアを自前で環境構築する場合|0円<br>**※別途費用発生**|有償オプションでアプリ／Web版対応|○|○|施設予約，メール，稟議，チャットなど|オープンソースのグループウェアなので別途インフラが必要。|
|3|[GroupSession](https://groupsession.jp/products/index.html)<br><br>byCloudプランをを利用する場合|48,000円<br>byCloudスマートプラン300円/月×160名＝48,000円|有償オプションでアプリ／Web版対応|○|○|施設予約，メール，稟議，チャットなど|byCloudスマートプランを利用すると、別途発生する費用（サーバーなどのインフラ費用）が掛からず、サポート費用なども300円に含まれる。|
|4|[Aipo](https://aipo.com/)|32,000円<br>掲示板＋フォルダ＝200円/月 × 160名＝32,000円/月|Web版対応|○|○|カレンダー，ポータル，タイムカード，タイムライン，ワークフロー，ToDo，プロジェクト，WiKi，報告書など|アプリ単位で月額100円〜<br>ミニマムスタートが可能<br>~~無料お試しをするとカレンダーがデフォルトでセットされるので、カレンダーが不要な場合、除外できるのか確認中。(2020/6/7時点）~~<br>カレンダーアプリも必須ではないので、本当に自由にアプリ単位で利用が可能。|
|5|[サイボウズOffice](https://office.cybozu.co.jp/)|80,000円<br>スタンダードコース500円/月×160名＝80,000円|アプリ／Web版どちらも対応|○|○|スケジュール，施設予約，アークフロー，メール，電話メモ，アドレス帳，報告書，プロジェクト，ToDoリスト，タイムカードなど|グループウェアといったらサイボウズだと思いますが、他のグループウェアと比較してもそこそこの費用。|

### GroupSession補足

GroupSessionに記載している**別途費用発生**というのは、他のSaaS形式のサービスに対して、ソースや実行モジュール（.warファイル）のみが提供されている。
そのため、別途インフラとして次のようなものが必要になります。

- サーバー
    - さくらVPSやAWS EC2などでサーバーを用意するか、オンプレ環境でサーバーを用意するか。
- グローバルIPアドレス
    - グループウェアにアクセスするためのグローバルIPアドレスが必要。
    - さくらVPSなどを利用する場合は、グローバルIPは基本料金に含まれて払い出されるのでOK。
- ドメイン名
    - グローバルIPでアクセスするのであれば不要だが、名前解決が必要名場合はドメイン名を取得する必要あり。
- SSL証明書
    - やりとりする情報によるかもしれませんが、基本的にはSSL証明書は必要になる。

概算ですが、上記を全て用意する場合、費用だけでも年間15,000円〜数万円程度は掛かると思います。
※構築するサーバーのスペックや、SSL証明書をやっすいところで取得するのか、ベリサインみたいなところで取得するのかにもよる。

また、SaaSで提供されていないということは、定期的なメンテナンスも自前でやる必要があります。

- バックアップ
- サーバーOSやミドルウェアなどのパッチ適用
- ドメイン名や証明書の更新手続き
- など

この点も色々考慮して決めていく必要がありそうですね。

# 所感

あとは検討する必要がありますが、

- コスト最重要視なら `GroupSession`の自前で用意（#2）
- 自分たちの運用コストを最小限にしつつ、コストも考慮するなら`Aipo`(#4)
- 運用コスト＋グループウェアのコストに加えて機能もやっぱり充実してた方がいいなら`GroupSession`のbyCloud版(#3)
- コロナ不況で企業の今後が不安。サービスが途中で終了することは怖い。ということであれば、ネームバリューも高く、おそらく今後もサービス継続される`サイボウズOffice`(#5)

がいいかなと思います。
~~※Aipoについては、デフォルトでどうしても「カレンダー」アプリは契約する必要がある。ということであれば、さらに月額一人当たり200円が追加になってしまうので、それであれば他の機能も充実するGroupSessionのbyCloud版がいいかなぁと思います。~~

上記で挙げたグループウェア以外にも、たくさんのグループウェアが世の中に存在します。
なので、あくまでも私自身の事情に合わせて検討した内容をメモしたものですのであしからず。
Python open() mode='w' で FileNotFound になった話

Python 3.x でファイルを扱う時は主に open(), with を使用するのだが、他の言語同様 書き込みモードというのが存在する。
ほかにも読み取り専用や追記モードなどもあるが割愛

```python:sample1.py
file_path = 'sample1.txt'
with open(file_path, mode='w') as f:
    print('Hello Py!!')
```

同じ階層にファイルを作る場合、通常はこれで問題ないのだがWindows系の場合 **文字数制限** が存在する
[長過ぎるパス名にご用心 - AtFILE_Guide](https://secure01.blue.shared-server.net/www.yes-online.jp/atfile_guide/Filer_PathNameLength.html#:~:text=Windows%E3%81%AE%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E5%90%8D%E3%81%AE,%E6%96%87%E5%AD%97%E3%81%A8%E3%81%84%E3%81%86%E5%88%B6%E9%99%90%E3%81%8C%E3%81%82%E3%82%8A%E3%81%BE%E3%81%99%E3%80%82)
[Windows10 home 64Bit のパスの文字数制限解除 - マイクロソフト コミュニティ](https://answers.microsoft.com/ja-jp/windows/forum/all/windows10-home-64bit/6b3f9844-f4ae-445e-9b12-21510a8db2d0)

そんな深い階層にフォルダ作って作業することなんて無いという方もいるかもしれないが、OneDrive for bussiness で個人のフォルダは結構深い階層に生成される（た気がする）

`C:\Users\%username%\OneDrive - 株式会社〇〇〇〇〇〇\` 
うん、これ会社名とユーザ名が長くなければ普通にぶち当たらないな。。。

だが FileNotFoundError を生んでしまった。
ググってみても 直上のフォルダが存在しないから といった理由ばかり記載されておりこれは違うなぁってのしかなかった。
（もしかしたらあったのかもしれないが見落としてるかも）

ふと、そういえばWindowsってファイル名制約あったけ てことを思いファイル名文字数制限てのを見つけた。
そういや、いつも長いファイル名なんてつけないから忘れてた

例えばファイル名に日付情報を付加した場合（まさに今回）はファイル名が長くなるので注意が必要かもしれない。

`ログ_株式会社〇〇〇〇〇〇〇〇〇〇〇〇様_〇〇〇〇〇〇拠点_設定変更_最終ログ_yyyymmdd.txt`というファイルからshow run と show start抜き出すプログラム書いてて思ったことでした。
ログ_株式会社〇〇〇〇〇〇〇〇〇〇〇〇様_〇〇〇〇〇〇拠点_設定変更_最終ログ_yyyymmdd.txt_show running-config_yyyymmdd.txt
ログ_株式会社〇〇〇〇〇〇〇〇〇〇〇〇様_〇〇〇〇〇〇拠点_設定変更_最終ログ_yyyymmdd.txt_show startup-config_yyyymmdd.txt

ちなみにpathlib.touch() やってみても error してた
Windows10：タッチパッドの有効／無効を切り替えるショートカット

2020年の初売り（12,020円）で買ってきた Lenovo の tablet 10。メモリ4GBのモデルでそこそこ使えます。キーボード操作の途中で触れてしまうと予期せぬ箇所にカーソルが移動してしまうので、タッチパッドを無効にしていましたが、 Windows 10 pro のバージョン 2004 にしたのがきっかけでタッチパッドが有効にもどってしまいました。この機会に、デバイスマネージャのGUIからではなくてコマンドからタッチパッドの有効無効を切り替える方法を調べてみました。

# GUIからだと面倒：devconが使えるらしい

すいません、いきなり結論です。 ```devcon``` （※１）を使うとコマンドプロンプトからタッチパッドの有効無効を切り替えることができるので便利。

# コマンド例

自分が使っている Lenovo tablet 10 のショートカットでいえば

```
タッチパッド＿オフ：
devcon /r disable "HID\VID_17EF&UP:0001_U:0002"
```

```
タッチパッド＿オン：
devcon /r enable "HID\VID_17EF&UP:0001_U:0002"
```

'"HID\VID_17EF&UP:0001_U:0002"' はデバイスマネージャでしらべておいたタッチパッドのデバイスID。念の為、 
```devcon hwids "HID\VID_17EF&UP:0001_U:0002"```
 でアクセスできることを確認しておいた。

ただし、

* devconはOSとは別にインストールが必要
* devconを実行するユーザに管理者権限がないとデバイスを検出できても有効無効を切り替えられない。

（※１）https://docs.microsoft.com/ja-jp/windows-hardware/drivers/devtest/devcon-examples#ddk_example_31_disable_devices_by_device_instance_id_tools

（参考）

* https://www7390uo.sakura.ne.jp/wordpress/archives/705
* https://www.youtube.com/watch?v=c9LaYVVigTQ
* https://qwerty.work/blog/2015/03/wdkdevconbatcommand.php

自分が使ったcabファイルは

* https://download.microsoft.com/download/1/4/0/140EBDB7-F631-4191-9DC0-31C8ECB8A11F/wdk/Installers/787bee96dbd26371076b37b13c405890.cab

# 追加

スクリプトをショートカットにしておくだけだと、ダブルクリック／タップで実行しても管理者権限の確認が必要になってしまう。管理者として実行、を選択しておいても効果はないみたい。タスクスケジューラに設定して”最上位の特権で実行する”を設定しておくとうまくいきました。

* タスクスケジューラの”タスクの作成”で任意のタスク名を設定：（例）```touchpad_off``` 
* 全般： `”最上位の特権で実行する”` を設定
* トリガー：（なにも設定しなくてよい・・・手動実行するので）
* 操作／プログラム/スクリプトの欄： ```devcon.exeのフルパス```
* 操作／引数の追加の欄：その続き。上記のタッチパッド＿オフの場合なら以下；

```

/r disable "HID\VID_17EF&UP:0001_U:0002"
```

これでスケジューラにタスクが設定されました。そのトリガを手動で実行します。 ```touchpad_off``` という名前をつけてあるので；

```

schtasks /run /tn touchpad_off
```

長いですね。これを覚えておけるとはおもえないので、結局ショートカットに登録しておくことに。さらにOFFと同じ方法でONも登録できました。ショートカットに『ショートカットキー』も設定できるので楽々。

ミッション完了！
HTMLで複数のclassを指定する方法

慣れないうちは、毎回調べてしまうのでアウトプットします。

##結論は半角スペースを入れる

```
<div class="sample1">....sample</div>
```

半角スペースを入れて複数指定できる。

```
<div class="sample1 sample2 sample3">....sample</div>
```
Consoleを利用したコードの間違いの探し方

プログラミングを学習する際、うまく動作しないときの対処を紹介します。
また、このプログラミングの間違いのことを”バグ”と呼びます。
それを取り除く作業を"デバッグ"と呼びます。
今回はGoogle Cromeを利用して、バグを見つける方法を紹介します。

1　ブラウザの右上のメニューから「その他のツール」を選択

2　「デベロッパーツール」を選択

3　Consoleのタブを選択

4　赤字の英文を読む

Consoleで間違いを見つける癖をつけることで、より効率的な学習に気かづけるでしょう。
MQL4の学習-001.　コメント・識別子・予約語

# MQL4の学習
以前からFXの自動売買に興味があったので、MQLを学ぶことにした。
学習は、[公式サイト](https://www.mql4.com/)を[Google翻訳](https://translate.google.co.jp/?hl=ja&tab=TT)を活用してまとめていく形で行ってみる。
翻訳が正しいのかどうか分からないので記事の内容に自信は持てないが、『やるだけやってみて間違ってたら訂正すればいいや』という気楽なスタンスで頑張ろうかと思う。
# MQL4とは？
MQL4は、自動化されたトレーディング戦略や金融市場の分析のためのテクニカルインジケーターを記述することを目的とした、オブジェクト指向のプログラミング言語なのだそうだ。リアルタイムで動作するように設計された様々な自動プログラムを作成できるだけでなく、取引の意思決定の判断材料となる独自のグラフィカル表示を作成する事が出来たりします。
この言語の継承版としてMQL5というものもあるのだが、ネット情報によるとMQL4とは別ものと考えた方が良いらしく、これが原因でMT4で使用してきたプログラムが使用できないので、MT5への移行が進まなかったそうだ。ちなみにMQL5の学習については、MQL4の後にやろうかと思ってます。
前置きはココまでとして、そろそろ言語の内容について学習して行きます。
# コメント
コメントはスペース内でいくつでも使用することができます。コメントの記述はプログラムに関与しません。
単一行コメントは、**『 / 』**記号のペアで始まり、改行文字で終わります。
複数行コメントは、**『 /* 』**記号のペアで始まり、**『 */ 』**記号で終わります。
以下に例を書いておきます。

```
// １行のコメントはこんな感じ。
/*
    複数行だとこんな感じ。
    以上です。
*/
```

# 識別子
識別子は、変数と関数の名前として使用されます。識別子のルールは以下の通りです。
 - 長さは63文字を超えることはできません。
 - 識別子で記述できる文字は半角英数字で、アルファベットは大文字と小文字が使用できます。
 - 半角アンダーバー**『 _ 』**も使用可能です。
 - 先頭の文字に数字は使用できません。
 - 識別子は予約語と一致してはなりません。

```
NAME7
name7
Total_Price
Cost
```

# 予約語
以下に挙げる識別子は予約語として扱われているので、それぞれが特定のアクションに対応しており、別の意味では使用できません。
####①データ型
||||||||
|:-:|:-:|:-:|:-:|:-:|:-:|:-:|
|bool|char|class|color|datetime|double|enum|
|float|int|long|short|string|struct|uchar|
|uint|ulong|ushort|void|

####②アクセス指定子
||||||
|:-:|:-:|:-:|:-:|:-:|
|const|private|protected|public|virtual|

####③メモリクラス
||||
|:-:|:-:|:-:|
|extern|input|static|

####④オペレーター
|||||||
|:-:|:-:|:-:|:-:|:-:|:-:|
|break|case|continue|default|delete|do|
|dynamic_cast|else|for|if|new|operator|
|return|sizeof|switch|while|

####⑤その他
||||||
|:-:|:-:|:-:|:-:|:-:|
|false|strict|template|this|true|
|typename|#define|#import|#include|#property|


とりあえず記念すべきQiita初投稿となるこの記事は、この辺りで終わります。次回からは『データの型』について触れてきます。
ゼロから始めるLeetCode Day49 「1323. Maximum 69 Number」

#概要
海外ではエンジニアの面接においてコーディングテストというものが行われるらしく、多くの場合、特定の関数やクラスをお題に沿って実装するという物がメインである。

その対策としてLeetCodeなるサイトで対策を行うようだ。

早い話が本場でも行われているようなコーディングテストに耐えうるようなアルゴリズム力を鍛えるサイト。

せっかくだし人並みのアルゴリズム力くらいは持っておいた方がいいだろうということで不定期に問題を解いてその時に考えたやり方をメモ的に書いていこうかと思います。

[Leetcode](https://leetcode.com/)

[ゼロから始めるLeetCode 目次](https://qiita.com/KueharX/items/6ee2502c3b620c795b70)

前回
[ゼロから始めるLeetCode Day48 「26. Remove Duplicates from Sorted Array」](https://qiita.com/KueharX/items/f234d8beab96328a171a)

今はTop 100 Liked QuestionsのMediumを優先的に解いています。
Easyは全て解いたので気になる方は目次の方へどうぞ。

[Twitter](https://twitter.com/kueharx)やってます。

# 問題
[1323. Maximum 69 Number](https://leetcode.com/problems/maximum-69-number/)

難易度はEasy。
Goodの数の方が多く、面白そうな問題だと思ったので紹介します。

6と9のみで構成された正の整数である`num`が与えられます。
一桁だけ数字を6から9,もしくは9から6に変えても良いので、`num`を変えることのできる最大値にして返すようなアルゴリズムを設計してください、という問題です。

>Input: num = 9669
Output: 9969
Explanation: 
Changing the first digit results in 6669.
Changing the second digit results in 9969.
Changing the third digit results in 9699.
Changing the fourth digit results in 9666. 
The maximum number is 9969.

>Input: num = 9996
Output: 9999
Explanation: Changing the last digit 6 to 9 results in the maximum number.

>Input: num = 9999
Output: 9999
Explanation: It is better not to apply any change.

# 解法

桁が多いところを6から9に変えればより大きな数値になることがわかると思います。

なので、replace関数を使って考えました。

replace関数では、引数が(置換される対象、置換する要素、最大値間回数)となっているので、文字列の要素を前から調べ、一回だけ置換したものを返せば実際にうまくいくのではと考え、以下のように書きました。

```Python
class Solution:
    def maximum69Number (self, num: int) -> int:
        return int(str(num).replace('6','9',1))
# Runtime: 28 ms, faster than 73.29% of Python3 online submissions for Maximum 69 Number.
# Memory Usage: 13.8 MB, less than 58.88% of Python3 online submissions for Maximum 69 Number.
```

なかなか良さげですね。
なお、replace関数では文字列のみ受け取るので、一度文字列に変換したものをreplace関数にかけ、その後返す際にintにしなければなりません。

今回はここまで、お疲れ様でした。
Jupyter notebookでsisterを使った自然言語処理の開発環境をDockerで構築する

## 概要
コマンド2行で、jupyter notebookと自然言語処理のライブラリ[sister](https://pypi.org/project/sister/)を使っての開発環境が起動します。

普通に設定すると、Docker起動毎に、[sister](https://pypi.org/project/sister/)の辞書ダウンロードが発生するので、辞書データを __永続化__ する設定を加えた `docker-compose.yml` を書きました。

## きっかけ
ふだんはRubyメインの開発で、pythonは自然言語処理をする時にしか触らない。
開発環境の構築で楽をしたいので、すぐに使えるrepositoryをつくりました。

## コード
https://github.com/junara/docker_sister_jupyter


## 使い方
* dockerをインストール
    * https://docs.docker.com/compose/install/

* dockerのメモリを増加
    * これしないとsisterが使えません。
    * Docker preferences -> Resources
    *  >= 6.00 GB to Memory.
    *  ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/124445/3b9e7b45-c534-5602-23fb-9645f30bc705.png)


* ダウンロード

好きなところでレポジトリをクローンします。

```shell
git clone https://github.com/junara/docker_sister_jupyter.git
```

フォルダに移動します。

```shell
cd docker_sister_jupyter
```

* 始める
  
```shell
docker-compose build
docker-compose up -d
```

* 終了する

```shell
docker-compose down
```

いやー、Dockerだと簡単ですね。

## 確認

http://localhost:8888/?token=jupyter にアクセスしてください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/124445/ade46d64-2e8f-f2fd-0672-7b1b7114d1fc.png)

sampleは以下です。  http://localhost:8888/notebooks/work/SampleEnglish.ipynb 

```python
      import sister
      
      sentence_embedding = sister.MeanEmbedding(lang="ja") # Need long time to download data at first time.
      
      sentence = "私はうさぎです。"
      vector = sentence_embedding(sentence)
      
      print(vector)
```

こんなかんじ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/124445/e80b3487-49d4-91f2-5640-139441518807.png)


## 解説
sisterのcahceを以下でlocalに [volumesで永続化](https://docs.docker.com/compose/gettingstarted/#step-5-edit-the-compose-file-to-add-a-bind-mount)しています。これで、docker環境作り直し毎の辞書のダウンロードが発生しなくなります。

https://github.com/junara/docker_sister_jupyter/blob/4631cb4e77165aa49a5400e4cbc33968c462a684/docker-compose.yml#L13

```docker-compose.yml
    volumes:
      - ./cache/.sister:/home/jovyan/.sister:delegated
```

Dockerfileはこんなかんじ。 [jupyter/scipy-notebook](https://hub.docker.com/r/jupyter/scipy-notebook/) をベースにして require.txt でライブラリを追加できるようにしています。


```Dockerfile
FROM jupyter/scipy-notebook
COPY requirements.txt /home/jovyan
RUN pip install -r /home/jovyan/requirements.txt
```

require.txtにsisterを追加してインストールされるようにしています。追加のライブラリがありましたらこちらにいれてください。 `docker-compose exec jupyter pip install -r /home/jovyan/requirements.txt` をすれば追加のライブラリをインストールされます。

```require.txt
sister
```

以上。
gobuffaloのベーシック認証で401を返す最小の方法

# 公式ページを基に実装すると
- こちらの[公式ページ](https://github.com/gobuffalo/mw-basicauth)を基に実装すると、失敗時にhttp500が返却される。
- 外部向けサイト等であれば、これで良いと思われる。
- 但し、社内システム等で、一回失敗するとブラウザ再起動だと面倒。

# リトライ出来るようする
- 以下は例です。

```
auth := func(c buffalo.Context, u, p string) (bool, error) {
	if u == "username" && p == "password" {
		return true,nil
	}else{
		c.Response().Header().Set("WWW-Authenticate", `Basic realm="Basic Authentication"`)
		return false,c.Error(http.StatusUnauthorized, errors.New("Unauthorized"))
	}
}

app.Use(basicauth.Middleware(auth))
app.Middleware.Skip(basicauth.Middleware(auth), HomeHandler)

app.GET("/", HomeHandler)
app.GET("/add", AddMessage)
app.GET("/get", GetMessage)

```

# 本当にやりたい事はn回リトライさせる設定
- そこまではやっていません。申し訳ございません。
[基礎] ファイルハンドル

# はじめに

◯◯ハンドル、〇〇ハンドラーなど色々ありますが、ハンドルネームが一意とか固有の名前って意味だから、そんな感じの意味なんだろうなあと思って、ちゃんと理解していなかったので調べました。

↓こちらとても分りやすくて参考になりました。
[コンピュータシステムの理論と実装](https://amzn.to/3eSukHy)


# ハンドラ

何かと何かの間に立って橋渡しをするもので、通常のプログラムの流れには組み込まれずに、何らかの処理要求が発生したときに起動される。

[現実世界の例]

- お金
 - 物々交換しなくて済みます!
- キャッシュカード
 - 現金のせいで部屋が狭くて困っていたので預かってもらえて幸いです!
- ATM
 - 現金をどこでも引き出せる!
 - 窓口の手続きがなくなってWINWINですね。
- 自動販売機
 - お金を入れれば飲み物が出てきます!
 - ジュース補充係の人には頭が下がります。
- ガソリンスタンド
 - サウジまで油を買いに行かなくても大丈夫です！
 - 油がなくなりましか。もう自分で油田を掘らなくてもOK!
- etc...

**数えたらきりがないです。世の中ハンドラで溢れています。**


[プログラミング界の例]

- 例外ハンドラ
- イベントハンドラ
 - ファイルハンドラ (一番馴染みのあるハンドラだと思います)
- 割り込みハンドラ



# ハンドリング

ハンドラが行うことをハンドリングと呼ぶ。


# ハンドル

複数のハンドリングを行いたい時に、個々のハンドリングが識別できるよう各々のハンドリングに一意の番号をつける。この番号をハンドル、あるいはポインタのポインタとも呼ばれる。

## なぜポインタのポインタなのか？

例えばハンドラAに複数のハンドリングを行いたい時

ハンドリングが幾つかのポインタをもっている場合を想像してみると分かると思う。

#### 例) Webブラウザのウィンドウを多重起動

[ディスプレイ]

ウィンドウ1: HackerNews, ProductHunt
ウィンドウ2: Qiita
ウィンドウ3: Xvide◯s, P◯rnTube, YouP◯rn

[内部処理]

ハンドラAのハンドリング１(ポインタ: 1000,1001)
ハンドラAのハンドリング２(ポインタ: 1002)　
ハンドラAのハンドリング３(ポインタ: 1006,1007,1008)　
etc...


# ファイルハンドル

いよいよ本題のファイルハンドルです。もう説明不要だと思いますが。

プログラムからファイルの読み書きを便利に便利にこなしてくれるイベントハンドルのひとつであるファイルハンドラの固有識別番号です。


# まとめ

普段使っているハンドルネームの意味がプログラムの視点で理解できました、ポインタのポインタの理解も深まりました。
mvvm構成図

### mvvm構成図のメモ

<img width="535" alt="スクリーンショット 2020-06-07 9.40.51.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/296847/18a45cdf-69b1-561a-1511-ce1a11bb1e07.png">
Gitでshallow cloneしたリポジトリのdepthを保ったままpullするには

# はじめに
`git clone` 時に `--depth=N` （Nは自然数）オプションをつけると、履歴を最新N件だけしか保持しない作業ツリーを取得することができる。

ただし、その後でオプションなしで `git pull` すると、それ以降の履歴はふつうに取得できる。

これに対して、最初にcloneしたときのdepthを保ったままpullする、ということをやりたいと思ったが、検索しても中々やり方が見つからなかったので、手元で試行錯誤した。

# 動作環境

- Ubuntu 18.04
- git v2.17.1[^1]

[^1]: aptで入れてるので最新ではない

# 結論（2020-06-25時点）

今のところ、安全に `git pull` するやり方が見つかっていない。後述のように、どうしてもCONFLICTが発生してしまうことがある。
そのため、作業ツリーのdepthを維持するには、次のようにやや強引にbranchを作り直すしかなさそう:

```sh
# 前提: originからmasterをcheckoutしているものとする
git fetch --depth=N
git checkout origin/master
## masterを削除してorigin/masterからcheckoutし直す
git branch -D master
git checkout -b master
## （オプショナル）元の状態に戻すため、追跡ブランチを設定しておく
git branch -u origin/master
```

# 駄目だったやり方
## git pull --depth=N

最初、シンプルにこれで行けるんじゃないかと期待したのだけど、どうもエラーが出る。
動いてはいたので、実は問題ない？

```sh:実行例
$ git pull --depth=1 [--update-shallow]
:
 + f22f6e5...caec91c master     -> origin/master  (forced update)
error: Could not read 843b95a87c496da6eac6160744854af3070db0fd
error: Could not read 843b95a87c496da6eac6160744854af3070db0fd
First, rewinding head to replay your work on top of it...
```

NOTE:

- `--update-shallow` は `.git/shallow` の更新を許可するオプションだが、ここでは付けても付けなくても結果は同じだった

## git fetch --depth=N; git rebase origin/BRANCH

これは上手く行くときもあったが、CONFLICTすることもあった。

```sh:実行例
$ git fetch --depth=1; git rebase origin/master
First, rewinding head to replay your work on top of it...
Applying: add baz.txt
Using index info to reconstruct a base tree...
Falling back to patching base and 3-way merge...
Auto-merging baz.txt
CONFLICT (add/add): Merge conflict in baz.txt
error: Failed to merge in the changes.
Patch failed at 0001 add baz.txt
Use 'git am --show-current-patch' to see the failed patch

Resolve all conflicts manually, mark them as resolved with
"git add/rm <conflicted_files>", then run "git rebase --continue".
You can instead skip this commit: run "git rebase --skip".
To abort and get back to the state before "git rebase", run "git rebase --abort".
```

## git fetch --depth=N && git pull

```sh:実行例
git fetch --depth=N
git pull
```

これなら大丈夫そうだと思ったのも束の間、やはりCONFLICTしてしまうことがあった。

## git fetch --depth=N; git merge orgin/BRANCH --squash

単純にmergeしても駄目そうな気がしたけど、 `--squash` を付ければひょっとしたら行けるかな、と思ったけど、やっぱり駄目だった。

```sh:実行例
$ git fetch --depth=1; git merge origin/master [--squash]
fatal: refusing to merge unrelated histories
```

# 参考

- https://git-scm.com/docs/git-clone
- https://git-scm.com/docs/git-fetch
- https://git-scm.com/docs/git-pull
- https://git-scm.com/docs/git-merge
Azureではディスクの容量を減らすことができない

VMにアタッチしていたデータディスクの容量が余るようになったので、費用削減のため容量を減らそうと思ったができなかったのでメモ。

そもそも公式のドキュメントにできないと書いてある。
https://docs.microsoft.com/ja-jp/azure/virtual-machines/windows/expand-os-disk
> 新しいサイズには、既存のディスク サイズより大きい値を指定する必要があります。

元のサイズから拡張するのは問題なくできるが、減らすことはできない。

## ディスク容量の変更方法（Azureポータル）
1. ディスクがVMにアタッチされている場合、VMを停止またはディスクをデタッチする。
2. 「ディスク」にアクセスし、構成から新しい容量を入力する。

その際に元の容量より小さい数を入力すると、
> 新しいディスクのサイズは ○○ GiB よりも大きくする必要があります。ディスクはより大きなサイズに変更することしかできません。

と怒られてしまう。

## でもなんかやり方があるんじゃないか？
考えた方法は、
1. 対象ディスクのスナップショットをとる
2. スナップショットからディスクを新しい容量で作成する

試した結果、できませんでした。
やはり元のディスク容量を同じかそれ以上にする必要がありました。

## 結局やったこと
VMに新ディスクをアタッチし、ファイルをそっちに移すという原始的な方法をとった。
データ保管用のディスクだったのでこの方法で特に問題はなかったが、これがOSディスクだった場合はもっと面倒くさいんだろうなー。
ディスクのご利用は計画的に、というお話でした。
pipでabortエラーが出た場合の復旧方法

## 環境
macOS Catalina
Python3.7

## 背景
homebrew でインストールしたパッケージが増えてきたので、使っていないものをアンインストールしていた。
後日pipを使おうと思ったら下記のエラーが出た。

```
% pip3 freeze
 zsh: abort      pip3 freeze
```
普段はvirtualenvで環境を作っておりそこでは問題なかったのだが、ローカルでpipを使おうと思ったら使えず。
zshからbashに変えて再度チャレンジしてみるも似たようなエラーが出てしまう。

```
% pip3 -V
 Abort trap: 6
```
pythonはhomebrew経由でインストールしていたのだが、再インストールを試してみるも状況変わらず。

## 原因
homebrewの整理時に、誤ってopensslも削除していた。
ググったところ以下のページにある方法で復旧できました。
https://forums.developer.apple.com/thread/119429

```
brew update && brew upgrade && brew install openssl
 ##note: some people report that the dylib files needed in #3 are in the 1.0.2t folder, rather than the lib folder. adjust your path in #2 as needed.
 cd /usr/local/Cellar/openssl/1.0.2t/lib
 sudo cp libssl.1.0.0.dylib libcrypto.1.0.0.dylib /usr/local/lib/
 cd /usr/local/lib
 sudo ln -s libssl.1.0.0.dylib libssl.dylib
 sudo ln -s libcrypto.1.0.0.dylib libcrypto.dylib
```
【Day80】積み上げ日記

##学習内容
■React
・JSX
・イベント
・state
・コンポーネント
・props

##学習ポイント
###■JSX
・JSの中に部分的にJSXが記述されている。
・JSXを記述するときは、`<div>`でグループ化する
・JSXの中にJS要素を入れるときは、{ }で囲む

###■イベント
・onClick
・アロー関数で（JSなので、{ }で囲む。）

###■state
ユーザーの動きに合わせて変わる値

####①stateの定義
constructor(props)内に、以下コード記述する
this.state = プロパティ名：値

####②stateの表示
HTMLタグを使って表示する

####③stateの変更
setState：切り替える
アロー関数内に記述する

###■コンポーネント
サイト内のパーツのこと。
コンポーネントごとにクラスを作成する。

####①Reactのインポート

####②React.Componentを継承するクラスを定義

####③JSXを戻り値とする、renderメソッド

###■props
コンポーネントの中身を変えるためのデータ。
コンポーネントを受け取るクラスで編集可能。

##参考記事
■電卓作り方
https://qiita.com/yamazaki3104/items/b5351f589fb6644bf910
2020-06-07 PYNQ-Z1 > Pmod_ADCを試した > Pmod_ADC(2)でエラー > ライブラリがpynq.iopからpynq.libに変更されて、使い方も変わった

```txt:動作環境
Windows 10 Pro (v1909) 
PYNQ-Z1 (Digilent) (以下、PYNQと表記)
Vivado v2019.1 (64-bit)
```

### Pmod_ADC(2) => エラー

Pmod_ADCを使った例が下記にある (二つ目のIn [4]の例)。
http://xph.necst.it/2017/hardware/sensors-cheatsheet.html

pynq.iopで実装しているが、最新版ではpynq.libに変更する必要がある。
pmod_adc.read()まで試したところ、下記のエラーとなった。

> TypeError: 'int' object is not subscriptable

![コメント 2020-06-07 080927.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32870/91ba96aa-863a-0a48-06b9-6935738f063a.png)


### 別の参考例 > pynq.libで実装

- [PYNQ中MicroBlaze程序文件的加载过程](http://m.elecfans.com/article/885372.html)

こちらの方はpynq.libで実装している。
試してみた。

```py
from pynq.overlays.base import BaseOverlay
from pynq.lib.pmod import Pmod_ADC
import time
import matplotlib.pyplot as plt

base = BaseOverlay("base.bit")
#pmod_adc = Pmod_ADC(2)
pmod_adc = Pmod_ADC(base.PMODA)
value = pmod_adc.read(0)
print("Current voltage: " + str(value) + "V")
```

```
Current voltage: []V
```

まだ値は取れていないが、Pmod_ADC()の使う部分は成功した。

### 関連

- [2020-05-30 PYNQ-Z1 > PMODA > pynq.lib.pmodからimportする (pynq.iopは古い) > pynq.lib.pmodを使う](https://qiita.com/7of9/items/8a70302265180ba1619f)
encfs面倒くさいからbashで短いスクリプト書いた

脳波とかの研究をしているので、個人情報のグレーゾーン的な所を何とかするために、
僕はencfsを使っています。[^kanpeki]
でも、encfs自身を毎回叩くのはクソだるいです。だるい要因を列挙します。

- アンマウントする度にfusermount -uと打つのが直感的じゃないし長い
- 毎回２つのディレクトリを指定しなきゃいけない(僕はいつも同名の隠しディレクトリを使っています)
- 絶対パスじゃないと受け付けない

特に最後のが、間違って相対パス投げて怒られるのが激ダルです。
そこで、bash書きました。

[^kanpeki]: encfsははっきり言って安全面では完璧ではないのですが、上記の通りグレーゾーンな所はあって、まぁ、encfsでも良いかなって所はあるのです。



```bash
ENCFS_TIMEOUT=30

emount () {
  DIRNAME=$(cd $(dirname $1); pwd)
  BASENAME=$(basename $1)
  encfs $DIRNAME/.$BASENAME $DIRNAME/$BASENAME -i $ENCFS_TIMEOUT
}

eumount () {
  DIRNAME=$(cd $(dirname $1); pwd)
  BASENAME=$(basename $1)
  fusermount -u $DIRNAME/$BASENAME
}
```


emountとかeumountとかで開け閉め出来る。
emountで特定のディレクトリを指定すると、同じ名前の隠しディレクトリを探してきて、
それがencfsの暗号化ディレクトリとして展開します。こんな感じ。

```bash
emount encdir
```
相対パスでもいけます。便利。
OSSに初めてissueを立ててみた

# はじめに
大学からコンピューターサイエンスを専攻し、今年でエンジニア歴6年目となるにも関わらず、
私は今までOSSにコントリビュートした経験が無い。。

エンジニアとしてコントリビュート経験が無いのはまずい気がするため、まずはissueを立てることからやってみた。
# OSSのコントリビュートはそこまでハードルが高くないらしい
OSSのコントリビュートと聞くと、つよつよエンジニアしかできないんでしょ。と思っていたがそうでもないらしい。
issueを立てたり、ドキュメントのタイピングミスを修正するだけでもコントリビュータになれるとのこと。
[意外ととっつきやすいOSS開発参加方法まとめ](https://qiita.com/shunsuke227ono/items/94dd6e707d34a1da2617)
[超絶簡単OSSコントリビュート術](https://qiita.com/taigamikami/items/fa21c6c50bff9a6674d9)

私でもこれくらいだったら出来そうな気がしてきたぞ！！


# issueを見つける
issueを立てるためには、当然ですがissueを見つける必要があります。
ちょうどAWS CLIでバグを見つけたところだったので、こちらの内容をissueとして立てようと思います。
## rds-db:connectのCondition制約にaws:CurrentTimeコンテキストキーが使えない
### 前提知識
#### IAM認証によるRDS接続
rds-db:connectはIAM認証によるRDS接続で必要な権限です。
IAM認証を行うことで、RDS接続時のパスワードを固定化する必要がなくなり、よりセキュアになります。

IAM認証によるRDS接続の詳細な説明はクラスメソッドさんのブログが大変参考になります。
[IAM認証でRDS PostgreSQLに接続してみた](https://dev.classmethod.jp/articles/iam-db-auth-to-postgresql/)

#### グローバル条件コンテキストキー
AWS CLIなりでAWSにリクエストを行うと、様々な情報をコンテキストとして付与します。
付与されたキー値とポリシーで指定した値を比較して、アクセスの許可拒否を判定できます。

[AWS グローバル条件コンテキストキー](https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-currenttime)

### やりたかっとこと
IAM認証によるRDS接続ができる時間帯を制限したかった。
そのため、こんなIAMポリシーを作りました。

```json:IAM認証によるRDS接続できる時間帯を制限したポリシー
{
   "Version": "2012-10-17",
   "Statement": [
      {
         "Effect": "Allow",
         "Action": [
             "rds-db:connect"
         ],
         "Resource": "*",
         "Condition": {
             "DateGreaterThan": {
                 "aws:CurrentTime": "2020-03-27T00:00:00Z"
             },
             "DateLessThan": {
                 "aws:CurrentTime": "2020-03-27T23:59:59Z"
             }
         }
      }
   ]
}

```
こうすることでDateGreaterThanとDateLessThanの時間範囲だけ接続できることを期待しました。
でも、このポリシーだと時間範囲内だろうが範囲外だろうが接続できませんでした。

```接続できなかった時の実行コマンド
$ RDSHOST=【DBクラスターID】.cluster-XXXXXXXX.ap-northeast-1.rds.amazonaws.com
$ export PGPASSWORD="$( aws rds generate-db-auth-token --hostname $RDSHOST --port 5432 --username jane_doe )"
$ psql "host=$RDSHOST dbname=postgres user=jane_doe"
psql: FATAL:  PAM authentication failed for user "jane_doe"
FATAL:  pg_hba.conf rejects connection for host "10.0.0.202", user "jane_doe", database "postgres", SSL off
```

サポートに問い合わせた所、
>rds-db:connectに関するリクエストをする時は__コンテキストキーにaws:CurrentTimeが含まれない__ため、
代わりにaws:TokenIssueTimeで代用してほしい

とのこと。
ご指摘通りaws:TokenIssueTimeを使ったら時間範囲内の時間帯のみ接続することができました。

ただし、公式ドキュメントにはaws:CurrentTimeコンテキストキーがリクエストに乗る条件としてこんな記載でした。
>このキーは常にリクエストコンテキストに含まれます。

つまり、例外無くaws:CurrentTimeコンテキストキーはリクエストに乗るべきにも関わらず、IAM認証でのRDS接続時は含まれていないということです。

説明が長くなったがこれをissueとして立てよう!

# issueを立てる
DeepL翻訳をフル活用してissueを立てました！
[IAM database authentication with a global conditional context key:aws:CurrentTime can not allow only within Specific dates](https://github.com/aws/aws-cli/issues/5271)

# 対応報告
一旦issueを立てるところまで行いました。issueに対して何かアクションがあれば追記していきたいと思います。今後の目標はプルリク出して自分で修正できるようになること！
[初心者向け]vscodeで書き終わったファイルの閉じ方

[初心者向け]vscodeで書き終わったファイルの閉じ方

1,左上の「file」を選択

2,その中の下の方にある「close folder」を選択する

自分も少し忘れていたので、参考になれば幸いです。
高位合成言語Polyphony (windowsでiverilog その14）

#概要

windowsでiverilogやってみた。
polyphony、やってみた。
半加算器、書いてみた。

#サンプルコード


```
import polyphony
from polyphony import testbench, module, is_worker_running
from polyphony.io import Port
from polyphony.typing import bit

@module
class ha:
	def __init__(self):
		self.a = Port(bit, 'in', protocol='valid')
		self.b = Port(bit, 'in', protocol='valid')
		self.c = Port(bit, 'out', protocol='valid')
		self.s = Port(bit, 'out', protocol='valid')
		self.append_worker(self.worker)
	def worker(self):
		while is_worker_running():
			a0:bit = self.a.rd()
			b0:bit = self.b.rd()
			c0:bit = a0 & b0
			s0:bit = a0 ^ b0
			self.c(c0)
			self.s(s0)

@testbench
def test(m):
	print("a b c s")
	m.a.wr(0)
	m.b.wr(0)
	cc = m.c.rd()
	ss = m.s.rd()
	print("0 0", cc, ss)
	m.a.wr(1)
	m.b.wr(0)
	cc = m.c.rd()
	ss = m.s.rd()
	print("1 0", cc, ss)
	m.a.wr(0)
	m.b.wr(1)
	cc = m.c.rd()
	ss = m.s.rd()
	print("0 1", cc, ss)
	m.a.wr(1)
	m.b.wr(1)
	cc = m.c.rd()
	ss = m.s.rd()
	print("1 1", cc, ss)

m = ha()

test(m)




```

#python実行結果


```
a b c s
0 0 0 0
1 0 0 1
0 1 0 1
1 1 1 0
```

#iverilog実行結果


```

a b c s
0 0 0 0
1 0 0 1
0 1 0 1
1 1 1 0
  480:finish


```

以上。
ゴルーチン⑧DefaultとSelection

#ゴルーチン⑧DefaultとSelection
Golangの基礎学習〜Webアプリケーション作成までの学習を終えたので、復習を兼ねてまとめていく。 基礎〜応用まで。

```
package main 
//Default Selection と for break
//for select ループから抜ける

import (
	"fmt"
	"time"
)

func main() {
	//time.Tick,After 時間のchannelを返す
	tick := time.Tick(100 * time.Millisecond)
	boom := time.After(500 * time.Millisecond)


//名前はなんでもいい
OuterLoop:
    for {
		//3-1 あまり良くない例だが
		//isBreak := false
		select {
		//1
		//<- tick  変数がいらない場合はこのように書ける
		case <- tick:
			fmt.Println("1秒")
		case <- boom:
			fmt.Println("5秒")
			//3-1
			//isBreak = True

			//3-2
			//抜ける
			/*
			returnにするとmain()から抜けてしまうため####が表示されない。
			breakだけだと、selectにはbreakがないため、無限ループになる。
			break OuterLoopにすると全ての処理が終わったら抜ける

            同様のことを、ifでやること(3-1)もできるが、望ましくない
			*/
			break OuterLoop
			// return
			
		//2
		//どちらでもない場合
	    default:
			fmt.Println("     .")
			time.Sleep(50 * time.Millisecond)
		}
		//3-0 ここでbreakすると抜けられる。これをやる方法が3-1
		//break

		//3-1 このようにもできるが、3-2へ
		/*if isBreak{
			break
		}*/
	}
	fmt.Println("##############")
}
```
macOSでgitのエイリアスを設定

## 自分メモ用
2年間くらいSourcetree使ってた
新しい職場では基本gitはコマンド操作でとのお達し
コマンド慣れてきた
コマンド全部打つのめんどくさくなってきた
コマンドは省略できると聞いていたので職場のwindowsで設定
自宅macでもgit使う機会増えてきた
設定どうやるんだっけ
ググる
見つける↓

### 参照
http://www.yabi-blog.xyz/mac_git_alias/


## 下記ファイルを編集

`/Users/{userName}/.bash_profile`

## 編集内容
```
alias bn="git branch"
alias st="git status -s"
alias dif="git diff"
alias pus="git push origin"
alias pul="git pull origin"
alias cmm="git commit -m"
alias add="git add"
alias cko="git checkout"
alias fet="git fetch"
```


#### 内容保存後、ターミナル再起動 or `source ~/.bash_profile`
中身は消さずにディレクトリだけ消したい

![SS 192.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565043/a41cd967-f549-8677-1efa-2e99bf69518d.png) 　ディレクトリがマトリョーシカみたいになっちゃった。

##やること
```
[A]親ディレクトリ
　└[B]削除したいディレクトリ
　　　└[C]子ディレクトリ
```
となっている時に、[B]を外して、

```
[A]親ディレクトリ
　└[C]子ディレクトリ
```

とする。

##環境

- Linux

##やり方
```sh:
$ cd　[A]親ディレクトリ
```
まず [A]親ディレクトリ の中に移動する。
この時、$ ls とすると [B]削除したいディレクトリ が見えているハズ。


```sh:
$ mv ./[B]削除したいディレクトリ/* ./
```

次に、[B]の中身全部（つまり[C])を、[A]の直下に移動する。
[B]と[C]が同じ階層に並ぶ。

```sh:
$ rm -rf　[B]削除したいディレクトリ
```

空になった[B]を削除する。
[注意] ワイルドカード*で拾えないファイルがあった場合はそれも削除されるので注意。
[エラー]docker-compose: mysqlとSequel Proの接続時に, 'caching_sha2_password' cannot be loaded: dlopen(/usr/local/lib/plugin/caching_sha2_password.so, 2): image not foundが起きた

## 何をしようとしたか
docker-composeを使って、local環境にmysqlを立ち上げて、Sequel Proを接続する

docker-compose: 3.3
mysql: 8.0.20

## 何が起きたか
docker-composeでmysqlを立ち上げた後に、クライアントからSequel Proでmysqlに接続する。
<img width="572" alt="Screen Shot 2020-06-07 at 4.53.18.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/195876/292a3d78-41b5-50c1-1109-0576e0b791f9.png">


接続の際に以下のエラーが表示された。

<img width="416" alt="Screen Shot 2020-06-07 at 1.54.29.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/195876/8b2afb3c-d094-1b94-6b80-52ef271cdb87.png">

## 何をしたか
docker-composeに`command: --default-authentication-plugin=mysql_native_password`を追加

``` docker-compose.yaml
# mysqlをdockerで立ち上げる
# command: sequel proの場合ログイン認証がデフォルトに対応していないための変更処置
version: "3.3"
services: 
    mysql:
        container_name: mysql-container
        hostname: mysql-server
        image: mysql         
        environment:
            MYSQL_DATABASE: "local"
            MYSQL_ROOT_PASSWORD: "root"
            MYSQL_USER: "user"
            MYSQL_PASSWORD: "user"
            MYSQL_ALLOW_EMPTY_PASSWORD: "true"
        ports: 
            - "4306:3306"            
        command: --default-authentication-plugin=mysql_native_password 
```

## 参考文献
https://www.wakuwakubank.com/posts/596-mysql-8-with-docker/
videoタグを使ってiPhoneで自動再生する

# プログラミングの勉強日記
2020年6月7日　Progate Lv.83
ウェブページ制作中
Windowsのブラウザ上では自動再生ができたが、iPhoneではできなかった。

##video属性

| 属性 | 効果 | 
|:---:|:---:|
| src | 動画ファイルの指定 |
| controls | 操作パネルの表示 |
| autoplay | 動画の自動再生  |
| loop | 繰り返し再生 |
| muted | 無音再生 |
| preload | 動画をあらかじめ読み込む |
| poster | 動画のヒントとなる画像を表示する |
| width | 幅を指定する |
| height | 高さを指定する |
| playsinline | インライン再生の対応(safari) |
| onclick=”this.play();” | android端末の対応 |



###Safariで自動再生する
　Safariではautoplay属性だけでは自動再生ができない。インライン再生で自動再生させるためには<font color=blue>muted属性を用いて音を消す</font>必要がある。muted属性を追加したうえで、<font color=blue>動画自体に音が入っててはいけない。</font>そのため、動画の音を消す必要がある。

```html
<video src="movie.mp4" loop autoplay muted></video>
```
<font color=blue>playsinline属性を追加しないと自動再生できない。</font>
![S__522018818.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/642821/763b91ec-ee34-a81b-5a0a-1457315c0897.jpeg)


```html
<video src="movie.mp4" loop autoplay muted playsinline></video>
```
autoplayとautoplay、muted属性をそれぞれ追加していて、かつ動画の音声も消したのに自動再生ができなかった…

![S__522018821.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/642821/5f759408-0a4b-9fe7-b0ec-b31dd97bf7ff.jpeg)

<font color=blue>※iPhoneの設定で「低電力モード」がオンになっているとこうなってしまいます！！</font>
低電力モードをオフにすると、chromeでもsafariでも自動再生できました。

![S__522035202.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/642821/c9a2d518-e5da-d17b-9e9d-34c98c10363a.jpeg)



##参考文献

https://web.runland.co.jp/blog_cate2/post-2567
http://www.htmq.com/html5/video.shtml
https://www.it-swarm.dev/ja/iphone/safari%E3%80%81iphone%E3%80%81ipad%E3%81%A7html5-video%E3%82%BF%E3%82%B0%E3%81%8C%E6%A9%9F%E8%83%BD%E3%81%97%E3%81%AA%E3%81%84/1042491604/
初心者によるプログラミング学習ログ 337日目

#100日チャレンジの337日目
twitterの100日チャレンジ#タグ、#100DaysOfCode実施中です。
すでに100日超えましたが、継続。
100日チャレンジは、ぱぺまぺの中ではプログラミングに限らず継続学習のために使っています。
337日目は、
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">おはようございます<br>336日目　1.5h<br>・ポートフォリオ作成<br>・navの領域外クリックでハンバーガメニュー閉じる<a href="https://twitter.com/hashtag/%E6%97%A9%E8%B5%B7%E3%81%8D%E3%83%81%E3%83%A3%E3%83%AC%E3%83%B3%E3%82%B8?src=hash&amp;ref_src=twsrc%5Etfw">#早起きチャレンジ</a><a href="https://twitter.com/hashtag/%E9%A7%86%E3%81%91%E5%87%BA%E3%81%97%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%8B%E3%82%A2%E3%81%A8%E7%B9%8B%E3%81%8C%E3%82%8A%E3%81%9F%E3%81%84?src=hash&amp;ref_src=twsrc%5Etfw">#駆け出しエンジニアと繋がりたい</a><a href="https://twitter.com/hashtag/100DaysOfCode?src=hash&amp;ref_src=twsrc%5Etfw">#100DaysOfCode</a></p>&mdash; ぱぺまぺ@webエンジニアを目指したい社畜 (@yudapinokio) <a href="https://twitter.com/yudapinokio/status/1268997596875419648?ref_src=twsrc%5Etfw">June 5, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
【Swift】Realm DatabaseでのDB操作方法について



iOSのアプリ開発時に設定画面で使用したRealmについてまとめました。

# Realm Database
Realm Databaseは、SQLiteと違いSQL文は使用せずにデータの追加等を行います。
Realm Databaseを使用する場合、DB用にファイルを作成しデータの追加等を行います

# DBの作成
Objectを継承させて、カラムを追加します。
カラムの追加には初期値の入力が必要になります。

```swift:RealmDB.swift
import UIKit
import RealmSwift

//Relam
class GPSConfig: Object {
    
    //Int型
    @objc dynamic var column1 = 0
    //String型
    @objc dynamic var column2 = ""

}
```

# データの追加
realm.add(RealmDB(value: object)) でDBにデータを追加できます。

```swift
let realm = try! Realm()
let object = RealmDB()
object.column1 = "data1"
object.column2 = 1

try! realm.write {
     realm.add(RealmDB(value: object))
}
```


# データの更新
登録したデータを変更する場合、以下のようにします。
firstで最初に登録したデータを取得できます。

```swift
let realm = try! Realm()
let object = realm.objects(RealmDB.self).first
    
try! realm.write {
     object?.object2 = 2
}
```

# データの削除
realm.delete(object) で指定したデータを削除することができます。
データをしてする際は、filterで特定のデータを取得できます。

```swift

let realm = try! Realm()
let object = realm.objects(RealmDB.self).filter("column1 == \"data1\"")
try! realm.write {
     realm.delete(object)
}
```

# カラムを追加した場合
DBにカラムを追加した場合、そのままだとエラーになるため、スキーマバージョンを上げる必要があります。

```swift

_ = Realm.Configuration(
     schemaVersion: 1,
     migrationBlock: { migration, oldSchemaVersion in
          //if (oldSchemaVersion &lt; 1) {}
     })
```
2020/06/06 プログラミング(フロントエンド)学習7日目 メモ

# 本日の学習範囲
### 模写コーディング
【無料練習素材】あなたはできる？模写コーディング腕試し！｜東京フリーランス｜note
https://note.com/tokyofreelance/n/n4baf7dd10306
（学習時間：5時間）
## 学習メモ
### デベロッパーツールを開くショートカット
[command]+[option]+[I]
### inputタグ
`<input type="○○">`
入力コントロールを表示する
### type属性
`<input type="○○">`
input要素におけるtype属性は、入力コントロールの種類を指定する
`<input type="text">`
の場合、1行テキストの入力フォームとなる
`<input type="submit">`
の場合、送信ボタンとなる
### placeholder属性
`<input placeholder="文字">`
初期表示内容を指定する
### value属性
`<input value="○○">`
入力コントロールの初期値を指定する
`<input type="submit" value="○○">`
の場合、value属性の値は表示されるボタン名になる
### outlineプロパティ
`{outline: ○○;}
ボックスの輪郭線をまとめて指定する
`{outline: 0;}`
の場合、ブラウザの既定のフォーカス表示は削除される
### box-shadowプロパティ
`{box-shadow: 水平方向の距離 垂直方向の距離 ぼかし距離 広がり距離 影の色;}`
ボックスに影をつける
水平方向の距離…正の値の場合は右へ、負の値の場合は左へ影が移動する
垂直方向の距離…正の値の場合は下へ、負の値の場合は上へ影が移動する
ぼかし距離…正の値のみ設定可能、値が大きいほど影の端のぼかしが強くなり、値が0の場合は端がくっきりとした影となる
広がり距離…正の値の場合は影の形状が全方向に拡大、負の値の場合は縮小する
## その他
note書いてあった目標時間の4時間で作成できたのがこちら↓
![模写コーディング1作目.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647063/ed200f61-28db-a5fa-96e9-4aecfac37d5a.png)
フォントの大きさや間隔調整はもう少し必要。
ドットインストールでまだフォームの作成方法などは勉強していなかったため、
Progateを確認しつつ、ググって作成。
ググって使ってみたタグ・プロパティがいくつかあった。
2020/06/07 勉強

#Clibor
　■参考サイト
　　https://chigusa-web.com/clibor/
　　https://www.vector.co.jp/soft/winnt/util/se472890.html

#VMWARE（MAC）
　■参考サイト
https://www.growst.jp/member_blog/2020/02/27/vmware%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%A6windows%E4%B8%8A%E3%81%A7macos%E3%82%92%E5%8B%95%E3%81%8B%E3%81%97%E3%81%9F%E3%81%84%EF%BC%81%EF%BC%81/

#ハードコピー
Windows10 「Windows」＋「Shift」＋「S」
　■参考サイト
https://forest.watch.impress.co.jp/docs/shseri/win10oct/1160522.html

#Raspberry Pi
　■参考サイト
https://www.sejuku.net/blog/48510#:~:text=Raspberry%20Pi%E3%81%AF%E3%83%AF%E3%83%B3%E3%83%9C%E3%83%BC%E3%83%89,%E3%81%99%E3%82%8B%E3%81%93%E3%81%A8%E3%81%8C%E5%87%BA%E6%9D%A5%E3%81%BE%E3%81%99%E3%80%82

#サクラエディタ
　重複行削除
　■参考サイト
http://write-remember.com/archives/5168/
react&gh-pagesでカスタムドメイン設定がリセットされる

# 概要
Reactで作成したページをgh-pagesパッケージを使って公開していたが、`npm run deploy`を実行する度にカスタムドメイン設定がリセットされてしまった。
[ReactアプリをGitHub Pages(Project Pages)で公開する](https://qiita.com/EisKern/items/15dcf7864fa49df8f247)

# 解決策
`public`ディレクトリ下に、カスタムドメイン名を記載した`CNAME`ファイルを配置すると解決

```
public
├── CNAME
```
SeleniumIDEでローカルのファイルをアップロードできないときの対処法

ChromeのseleniumIDEを使ってテストの自動化を行っていた際、ファイルアップロードまわりでハマったポイントがあったので記録します。

#### 環境について
OSはWindows10、Chromeのバージョンは81、seleniumIDEのバージョンは3.17.0  
を使用していました。

## 事象
seleniumIDEを使ってフォームのテストを自動化しようとしたら、
```<input type="file">```でローカルのファイルをアップロードするのに失敗した。

## 詳細
開発していたのはユーザー登録画面でした。  
HTMLで組んだフォームの入力をPOSTで送信するという単純な機能です。  
その中でローカルのファイルをアップロードするフォームがありました。  

```HTML:form.html
<input type="file" name="upload_file" id="upload_file">
```
テストを自動化しようということになり、seleniumIDEでChromeの自動操作を行います。  
動作をseleniumIDEで記録してテストを作成します。
それが終わったら、テストを実行して各フォームに自動で値を入力していきます。  
すると、上記のフォームに入力する際エラーが発生しました。

```
Failed:
{"code":-32000,"message":"Not allowed"}
```

## 原因と解決法
### 1
原因を調査したところ、まずVauleに入力するパスが間違っていました。

RECを使ってユーザーの動作を直接記録すると、入力したファイルのパスは```C:\fakePath```から始まるものとなっています。  
これをローカルにおけるパスに変更しました。

しかし、それでもまだエラーは出ました。
### 2
権限が原因なのかと考え、ローカルファイルの権限を調べるも問題はありませんでした。
### 3（解決）
原因はChrome拡張機能の設定にありました。

アドレスバーに```chrome://extensions```と入力すると、インストールされている拡張機能の一覧が表示されます。  
seleniumIDEの詳細を選択し、**ファイルのURLへのアクセスを許可する**の項目を確認したところ無効になっていました。

これを有効にしてテストを実行したところ、無事ファイルのアップロードをすることができました。

おそらくデフォルトで無効になっているのだと思います。  
なかなか気づかないですよね。

## 参考資料
[\`type\` command on \`input type=file\` broken for Chrome 72 #569](https://github.com/SeleniumHQ/selenium-ide/issues/569)
[Unity]Motion Blurで勘違いしてたこと・完 ～Post Processing Stack はヤッパリ素晴らしい～

▼モーションブラー無し
![モーションブラー無し.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184294/f198fe25-eed5-0cc4-5fbf-f7dc4e19e3c2.gif)
これが…

▼モーションブラー有り
![モーションブラー有り.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184294/5a2cb470-3e7d-1c28-234c-7be6fa5a88cd.gif)
こうなりました

# Post Processing Stackさんディスってすみません
※[前回の記事](https://qiita.com/flankids/items/c0cd04bc50bd3b902982)

望んでた絵が作れました。
結論、 **Post Processing StackのバージョンをV2にしたら解決しました。** （なんという恥ずかしい…）

これで **「カメラが不動でもオブジェクトが激しく動けばブレる」** という状態が作れました。

注意点として、`Renderer` の  **Motion Vectors**  が **「Per Object Motion」** になっていないとダメです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184294/c880d5fa-8dfb-2701-a567-9d8511b86cd3.png)

* Camera Motion Only：カメラの回転や移動でのブラーのみ反映
* Per Object Motion：Renderの移動や回転によってもブラーが発生
* Force No Motion：ブレない

という感じかな？
これで特撮っぽい絵が作れるヤッター
AWSでLaravelのフォーム送信が出来なかった

ローカルでLaravelアプリをDocker環境に移行し、AWSのEC2へそのままデプロイしました。
EC2上で```docker-compose up -d```をして立ち上げ、サイトにアクセスしたら、
表示はされるのですが、ログインフォームや登録フォームを送信したら、こんな状態に。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/596140/248a50b8-1cc8-98d3-a83f-d5153053ff46.png)
かなり対処に苦労したので、記録しておきます。

#環境

Mac OS Catalina 10.15.4
PHP: 7.2.24
Laravel: 5.5.48
Docker: 19.3.６
Docker-compose: 1.16.1
AWS: AMI: Amazon Linux2
     EC2: t2.micro（無料枠のやつ）

#どういうことか

画像の文字の意味的には「このページは期限切れだから更新してみて」的な感じ。
これが出る時は多くがCSRFトークンの期限切れだそうです。

え？セッション切れるほど放置してないけど...

#試してみたこと

##セッションの有効時間を確認してみる。

Laravelの```.env```ファイル内に、

```
SESSION_LIFETIME=120
```
があると思いますが、これがセッション有効期限です。（分）
```session.php```にも記述があるそうですが、```.env```ファイルの記述が優先されるみたいです。

しかし私の場合はそんなに放置してない。

##sshでログインしてEC2のタイムゾーンを確認してみる。

```
[ec2-user@ ... ]$ date
2020年  6月  6日 土曜日 xx:xx:xx UTC
```
なるほど。UTCになってますね。
つまり時間差が出来てしまったからセッション切れたようになってしまったのか？
[こちらの記事](https://qiita.com/azusanakano/items/b39bd22504313884a7c3)を参考にタイムゾーンを変更します。

```
[ec2-user@ ... ]$ date
2020年  6月  6日 土曜日 xx:xx:xx JST
```
JSTになりました。
再度動作確認。

...変わらない。

##コンテナ内でもタイムゾーン確認してみる。

```
$ docker exec -it [コンテナ名] bash

/var/www# date
Sat Jun  6 xx:xx:xx UTC 2020
```
おっと、UTCになってますね。こっちが原因なのか？
[こちらの記事](https://qiita.com/rururu_kenken/items/972314402d588e073d40)
を参考にさせて頂き、```docker-compose.yml```内へタイムゾーンを力技で捻じ込む。

```docker-compose.yml
...
    environment:
      TZ: 'Asia/Tokyo'
...
```
再度確認してみます。

```
/var/www# date
Sat Jun  6 xx:xx:xx JST 2020
```
変わりましたね。これで大丈夫か...？

ダメでした。

##CSRFトークンの記述漏れか確認する。
どうもこれがパターンとしては多いそうです。この記述漏れがフォーム内に無いか確認する。

```
Laravel 5.5 以前
  {{ csrf_field() }}
Laravel 5.6 から
  @csrf
```

あります。ちゃんと書いてます。自分えらい。
でもこれが原因でもない。

##セッションドライバをcookieにしてみる

[“The page has expired due to inactivity” - Laravel 5.5
](https://stackoverflow.com/questions/46141705/the-page-has-expired-due-to-inactivity-laravel-5-5)
stackoverflowにこんな記事がありました。
ここのコメントによると、
「セッションドライバをファイルにしていると、storage_pathのパーミションでこの表示が出る時がある」
らしいです。
セッションドライバとは、
>セッションドライバ(driver)はリクエスト毎のセッションデータをどこに保存するかを決めます。

だそうです。

```
.env

SESSION_DRIVER=file
```
じゃパーミッション変更したらええやん、って思いましたが、[別の記事](https://stackoverflow.com/questions/39997180/laravel-5-3-tokenmismatchexception-in-verifycsrftoken-php-line-68/45354029#45354029)で結構言われていたので、まぁ確かにと思いつつ、[公式の日本語訳ページ](https://readouble.com/laravel/5.5/ja/session.html)を参考にしながら、

```.env
SESSION_DRIVER=cookie
```

に変更してみました。

そうしたらやっと動いてくれました。
でもローカルではエラー出なかったのになぜ？
AWSに移行すると変更されちゃうのか？

理由をご存知の方いましたらぜひ教えていただけたら幸いです。

#参考記事
[【Linux】タイムゾーン(Timezone)の変更](https://qiita.com/azusanakano/items/b39bd22504313884a7c3)
[Dockerコンテナのタイムゾーン変更方法](https://qiita.com/rururu_kenken/items/972314402d588e073d40)
[“The page has expired due to inactivity” - Laravel 5.5
](https://stackoverflow.com/questions/46141705/the-page-has-expired-due-to-inactivity-laravel-5-5)
[Laravel 5.3 - TokenMismatchException in VerifyCsrfToken.php line 68:](https://stackoverflow.com/questions/39997180/laravel-5-3-tokenmismatchexception-in-verifycsrftoken-php-line-68/45354029#45354029)
[Laravel 5.5 HTTPセッション](https://readouble.com/laravel/5.5/ja/session.html)

非常に勉強になりました。ありがとうございました。
【Rails】seedで初期データ作成

# seedで初期データ作成

### 目次
1. 初期データ作成にあたって
2. seedファイル作成

## 1. 初期データ作成にあたって
ユーザー機能に管理者権限を追加することになりました。
管理者ユーザーを作成するため、私は ```rails c``` から管理者ユーザーの作成を行いました。
他の開発メンバーにも、管理者ユーザーの作成を行ってもらいたいのですが、 ```rails c``` から各々、作成するとなると手間になったり、忘れてしまう可能性を考慮し、seedファイルを作成して管理者ユーザーを作成してもらうことにしました。

## 2. seedファイル作成
今回は管理者ユーザーのデータを作成します。
```db``` 以下に ```db/seeds/admin_user.rb``` を作成します。
以下のようにseedファイルを作成します。

```db/seeds/admin_user.rb
User.create(admin: 1, email: "admin@admin.jp", password: "123456")
```

ターミナルで以下のコマンドを入力します。

```
bundle exec rails r db/seeds/admin_user.rb
```

データベースを確認すると、管理者ユーザーが作成されています。

また、seedファイルでeach文を利用すると、複数のデータを簡単に作成することができます。

以上で、seedでの初期データ作成となります。
Web APIについて個人的まとめ

##そもそもWebAPIとは何か？
機能を外部から呼び出すための仕様。
つまり外部インタフェース。

なおWebAPIはプロトコルとしてHTTPを使用するので、エンドポイントはURIによって指定される。

WebAPIの例）
・Twitterの特定ユーザのタイムラインを提供するAPI
・Amazonの商品を購入するためのリンクを他のWebページに貼りつけるAPI
・FaceBookのいいね！を外部のページから直接できるAPI

##APIを公開するにあたって心がけること
まず第三者が利用することが前提となるからきちんとしたドキュメントを公開すること。
だれでも分かりやすいように使いやすい設計を心がけること。（⇐これが一番、大変かもしれんが・・・）

##WebAPI公開のメリット
APIを公開することで、要は外部に向けて入口が開かれるわけなので、他のサービスと連携するなどして、サービスの利便性、拡張性を高め、しいてはサービス自体の価値を高めていくことになる。
またあるサービスに機能を追加したいと思ったとき、そのほしいサービスが既に存在していて、しかもそれがAPIで公開している場合にはそこにつなぎこんだりできる。

##API公開のリスク
運用方法による。
「APIを公開すること＝情報へのアクセスを無限に受け付けること」ではないので、ユーザーごとのアクセス制限を設けたり、その制限を超えて大量のアクセスを行う場合は提携関係を結んで利用料を払うようになっていたり、そもそも一定以上のアクセスができない仕組みになっていたりする。

##APIエコノミー
Web APIを公開することで外部サービスとの連携を容易にして、新たな価値が生まれ、ビジネスが発展していくこと。

##APIでは何を公開すべきなのか
そのサービスに存在する機能すべて
もう少し限定するならば、サービスのコアとなる部分
例）ECサイトなら購入、検索

##API公開で得られるもの
公開したAPIを企業や個人が他のサービスに紐づけたり活用してくれることでサービスの価値や情報の質が上がる可能性がある。
またAPIを公開すれば、欲しかった機能やまったく思いつきもしなかった機能を誰かが作ってみてくれるかもしれない。
結果としてサービスの価値を上げていってくれる（はず）。

そうして、もしそうした機能がサービスに大きな価値を与えているのであれば、同等の機能を自ら提供することもできる。
例）Titterで写真を公開するTwitpicや公開されているTweetをまとめてカスタムインラインを作るTogetterなどの登場の後に、同等の機能をTwitterは本家の機能として公開している。

逆にサービスの質を著しく下げているものがあればAPIの提供を止めるなどして対応すべき
（もちろんただ気にくわないとかいう、差別的な理由だけで提供を止めるのは、サービス自体の評判が下がるのよくないが・・・）
）
そういった対応をきちんと行えるようにAPI公開時には利用規約を公開し、問題となる行動をとった場合の対処を明記する。


##APIを美しく設計する
重要な原則は以下の二点

・仕様が決まっているものは仕様に従う
・仕様が存在していないならデファクトスタンダードに従う

仕様は、これまでにたくさんの人が、いろいろな視点からの検討を経て決まっている。
したがってそうした仕様に従うことを理にかなっている。

デファクトスタンダードについても同様。
これまでの歴史の中で現在、スタンダートなっているものにはそれなりの理由があるのだから。

こうしたルールに従うことには大きなメリットがある。
それはこれまで他のAPIを開発してきた人があなたのAPIを見たときにも、利用方法が簡単に推測できたり、既存のクライアントライブラリの流用ができる

##APIの設計思想
以下二つは、APIがターゲットとする開発者がなにかを表すために使われる

###LSUDs(large set of unknown developers)
意味：未知のたくさんの開発者
ターゲットとするAPIは公にAPIをドキュメントともに公開し、だれでも登録して使えるようにしたもの。
多くの人に使われる分、あらゆるユースケースを想定して汎用的にしてかなければならない

###SSKDs(small set of known developers)
意味：既存の小数の開発者
ターゲットは例えば、自社サービスのスマホクライアント向けのAPIなど、APIを利用する開発者が限られている場合に使用する
特定の開発者やエンドユーザにとって利便性が高いものしなければいけないはずなので、「美しい設計」の定義がときどきによって大きく違う。

##APIを利用したサービス
様々なAPIを集めてその情報を公開しているAPIディレクトリサービス
[Programming Web](https://www.programmableweb.com/apis)


##参考書籍
[Web API: The Good Parts](https://www.amazon.co.jp/Web-API-Parts-%E6%B0%B4%E9%87%8E-%E8%B2%B4%E6%98%8E/dp/4873116864/ref=sr_1_1?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&dchild=1&keywords=Web+API&qid=1591442609&sr=8-1)
yabai + skhdの設定周りについて


過去に以下のchunkwmに関する記事を書いたのですが、今はyabaiというやつを使うのが推奨されています。
僕もちょこちょこ自分で設定はいじっていたのですが、そこまでchunkwmと変更が無さそうだったので設定には困っていませんでした。

https://qiita.com/mitubaEX328/items/a08842ddc4f764882d15

なので今回はskhdの設定、debug周りを書くだけにしようと思います。
yabaiに関してはリンクを貼っておくだけに留めておきます。

## yabaiの設定

各種commandは以下のwikiを見れば大体chunkwmから移行はできると思います

https://github.com/koekeishiya/yabai/wiki/Commands#display-commands


## skhdの設定

これも公式のexampleを見てもらうのが速いと思います

https://github.com/koekeishiya/skhd/blob/master/examples/skhdrc

## skhdのマッピング確認

skhdでどういうマッピングされているかを `skhd -V` で確認することができます。
このコマンドを実行するためには、一旦 `brew services stop skhd` でskhdを止めて `rm /tmp/skhd_<username>.pid` でpidが記載されているファイルを削除してから行ってください。
これをしてからじゃないと、以下のようなエラーが出ました。

`skhd: could not lock pid-file! abort..` 

[issue](https://github.com/koekeishiya/skhd/issues/74)も参考

## skhd -V時にエラーがでていないか

僕の場合は以下のようなエラーが出ていました

`#45:8 expected ':' followed by command or ';' followed by mode` 

エラーなのかwarningなのかよくわからん出方をするので、注意深く見て直してあげましょう

## 終わりに

そこまで凝った使い方はしていませんがwmがあると捗る部分もあるので、オススメです。

## 付録

- yabaiの設定
    - https://github.com/mitubaEX/dotfiles/blob/master/.yabairc
- skhdの設定
    - https://github.com/mitubaEX/dotfiles/blob/master/.khdrc