OmniAICreator/Qiita-1.07M huggingface dataset:
なぜiPhone 11 Pro では0.5の線が描画できないのか調べてみた

## 環境

- Xcode 11.3

## 何が起こったのか

いつもどおり 0.5 の線を引くために Storyboard の AutoLayout で `Height = 0.5` の制約を指定した。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8292/236f2f05-72e1-d2f8-f35f-95285b181af2.png)

すると、デザイナーから「線の太さにばらつきがあるので揃えてほしい」と指摘があった。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8292/84c6ed07-e194-f998-796d-1cb8b2d3e3c4.png)

↑たしかによく見ると上の線のほうが若干濃くも見える・・。両方とも 0.5 で指定しているが、念のため次のコードを書いて height を出力してみた。

```swift
print(separator1.frame.size.height) // 上の線
print(separator2.frame.size.height) // 下の線
```

すると、

```
0.66666666666666
0.33333333333333
```

と出力された！

目の錯覚ではなく、たしかに上の線のほうが濃いことがわかった。

## なぜ0.5で指定しているのに正しく描画されないか

Twitter にて[この疑問をつぶやいてみた](https://twitter.com/koogawa/status/1224257789775581186)ところ、 @kishikawakatsumi さんが回答をくださった。


> Frameの小数部分は実行時にPixel alignedになるように丸められるからですね。Scaleをかけて割る、みたいな処理が自動的に入ってます。 
https://twitter.com/k_katsumi/status/1224279359529205760

なるほど！

つまり、iPhone 11 Pro のような x3 でレンダリングされるデバイスは 1pt の線が実際には 3px で描画される。pxに小数を含むことはできないため、小数点以下は丸められてしまう。

例）0.5pt で指定された線は1.5pxで描画しようとするが、小数点が丸められ、1px（=0.3333pt）か2px(=0.6666pt)として描画される。

このとき、どう丸められるかはコントロールできない。 **このため、太さに差が出てしまっていた！**

参考：x2 や x3 についてはこのデバイス一覧表がわかりやすい
https://www.paintcodeapp.com/news/ultimate-guide-to-iphone-resolutions


## どうしたらよいか

やはり同じ悩みを持っている人がいた。
[ios \- How to create a line width of 0\.5 pixels \- Stack Overflow](https://stackoverflow.com/questions/21552115/how-to-create-a-line-width-of-0-5-pixels/21553495#21553495)

つまり、

- x3 デバイスでは 0.3 pt で指定するようにする
- x2 デバイスでは 0.5 pt で指定するようにする

このようにすると、確かにどのデバイスでもばらつきがなく線画描画されるようになった。

しかし、 Storyboard では 0.5 単位でしか height を指定できなので、次のようなコードを書いて線を実装する必要がありそう。

```
(1.0 / [UIScreen mainScreen].scale)
```

----

2020/2/4 追記：
1 / scaleの高さを制約に設定したSeparatorというCustom Viewを作る方法もあるそうです！@IBDesignable
にしておくとStoryboardに置くだけで使える
https://twitter.com/k_katsumi/status/1224503484822671360

----

なにかおかしなことを書いていたらコメントお願いします :pray:
C++からmruby/cを呼ぶ

先日、九州工業大学の[田中先生](https://github.com/kaz0505)にmruby/cのステッカーをいただきました。その条件がmruby/cを使うことだったので手元のMacで動かしてみることにします。
しかしただHello Worldを表示させるだけでは付属のSampleコードと変わらないので、C＋＋からmruby/cを呼べないか試してみたいと思います。

# 環境
Mac OS Catalina 10.15.2

```
$ cc --version
Apple clang version 11.0.0 (clang-1100.0.33.17)
Target: x86_64-apple-darwin19.2.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin
```

# C＋＋プログラムの作成

1. 本体の入手
https://github.com/mrubyc/mrubyc 2020年１月末頃のmaster

2. C++ファイルの作成

少しでも楽をするためにサンプルのコンパイル環境を借りることにします。
mruby/sample_cフォルダ配下に以下のソースコードを書いて下さい。

``` c++:sample_c/hello.cpp
#include <fstream>
#include <vector>
#include "mrubyc.h"
using namespace std;

#define MEMORY_SIZE (1024*40)
static uint8_t memory_pool[MEMORY_SIZE];

int main(int argc, char *argv[])
{
  ifstream file(argv[1], ios::in | ios::binary);
  vector<char> mrbbuf((istreambuf_iterator<char>(file)), istreambuf_iterator<char>());

  mrbc_init(memory_pool, MEMORY_SIZE);
  mrbc_tcb *task = mrbc_create_task((uint8_t *)&mrbbuf[0], NULL);
  mrbc_start_task(task);
  mrbc_run();
  return 0;
}
```
内容はファイルからmrubyバイトコードを読み込んで、mruby/cタスクを実行するだけの単純なプログラムです。
C＋＋だとファイル読み込みが二行で済むのが今回唯一の見所。

# コンパイル

sample_cのMakefileを間借りさせてもらいます。

``` Makefile:sample_c/Makefile
TARGETS = sample_scheduler sample_include sample_concurrent sample_myclass hello
CFLAGS += -g -I ../src -Wall -Wpointer-arith -lc++
LDFLAGS +=
LIBMRUBYC = ../src/libmrubyc.a

all: $(TARGETS)

sample_scheduler: sample_scheduler.c $(LIBMRUBYC)
	$(CC) $(CFLAGS) $(LDFLAGS) -o $@ sample_scheduler.c $(LIBMRUBYC)

sample_include: sample_include.c $(LIBMRUBYC)
	$(CC) $(CFLAGS) $(LDFLAGS) -o $@ sample_include.c $(LIBMRUBYC)

sample_concurrent: sample_concurrent.c $(LIBMRUBYC)
	$(CC) $(CFLAGS) $(LDFLAGS) -o $@ sample_concurrent.c $(LIBMRUBYC)

sample_myclass: sample_myclass.c $(LIBMRUBYC)
	$(CC) $(CFLAGS) $(LDFLAGS) -o $@ sample_myclass.c $(LIBMRUBYC)

hello: hello.cpp $(LIBMRUBYC)
	$(CC) $(CFLAGS) $(LDFLAGS) -o $@ hello.cpp $(LIBMRUBYC)

clean:
	@rm -rf $(TARGETS) *.o *.dSYM *~
```
三ヶ所追加修正
1. TARGETSにhelloを追加
2. CFLAGSに -lc++を追加
3. hello: hello.cpp ... を追加


あとはmakeするだけ

```
$ make
```

# mrubyバイトコードの生成

ここでHello Worldを書いて出力と行きたいのですが、残念ながらmruby/cにはバイトコードコンパイラが同梱されていないので、直接Rubyコードを実行することができません。そこでmruby(無印)内のmrbcコンパイラが必要になります。

2. mruby(無印)のインストール
幸いMacの場合は brew install mrubyコマンドでインストール出来るようです。

3. Rubyコードのコンパイル
なんとかmruby/bin/mrbcが実行できる環境が整ったら準備OK。

``` ruby:hello.rb
puts 'Hello mruby/c'
```

上記のRubyコードをバイトコードにコンパイルします。

```
$ mrbc hello.rb
```
hello.mrbcファイルが生成されました。
このファイルをmrubyc/sample_cフォルダにコピーしておきます。

# 実行

```
$ ./hello hello.mrb
Hello ruby/c
```

# 結論
C＋＋で書くことでコードはコンパクトになりましたが、生成された実行ファイルは259KBになってしまいました。同じようなCのサンプルが１９０KBだったので70KB増量です。
スペックに余裕がある環境だったらmruby/cじゃなくてmruby(無印)を使うだろうし。

# 参考文献
[mruby/cを導入してみた(Mac編) 課題11（１つ解決）](https://qiita.com/kaizen_nagoya/items/ae733370b5ca1b5b2e46)
インスタンスにteratermではログインできるのに、sshコマンドではできない

# 前提
windowsのputty genによって生成された秘密鍵をssh(mac)で使用しています。

# 解決策
puttygenコマンドでopenssh形式に変換する

```shell

$ brew install putty
$ puttygen id_rsa.ppk -O private-openssh -o id_rsa
```

# 原因：鍵ファイルのフォーマットが間違っている

### puttyによって作成されるppkファイルのフォーマット

```

PuTTY-User-Key-File-2: ssh-rsa
Encryption: none
Comment: rsa-key-20200128
Public-Lines: 6
xxxxxxx...
Private-Lines: 14
xxxxxxx....
Private-MAC: macアドレス

```

### 読み取り可能なフォーマット

```

-----BEGIN OPENSSH PRIVATE KEY-----
xxxxxxxxxxxxxx...

-----END OPENSSH PRIVATE KEY-----

```
[Shopify] App Chrome80でのサードパーティーCookie問題を解消する方法

2月4日(今日！) リリースされるChrome80ではデフォ挙動としてサードパーティークッキーを受け付けなくなります。ということで、簡単にまとめました。

Shopifyのまとめは下記を参照。
https://help.shopify.com/en/api/guides/samesite-cookies

Chromeがサードパーティークッキーを使用しない、というお知らせは下記を参照
https://blog.chromium.org/2019/05/improving-privacy-and-security-on-web.html

# `SameSite=None`に設定してください

Shopify Appを開発している方々にとっては、対応必須となります。管理画面上で動かくAppはサードパーティーコンテンツそのもの・

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241909/5ce86fe7-4100-22c4-af2c-4029aa718955.png)


ということで下記の対処が必要です。

新たにCookie設定で、`SameSite=None`と設定します。これはcorss-site access（＝サードパーティークッキーとしての利用）を許諾するという設定になります。

この設定をしない場合は`SameSite=Lax`と設定されています。セッションクッキーなどを使いShopify Appを構築している場合、このままではShopify Appsは下記のようにエラーを表示し使うことができません。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241909/82b7d886-4169-3977-b98c-86c4cd64fcbc.png)

注）SameSite=Noneに対応していないブラザーもあるそうなので下記を参照
https://www.chromium.org/updates/same-site/incompatible-clients

# 例
各開発環境での例が下記にあります
https://github.com/GoogleChromeLabs/samesite-examples


なぜか・・Shopifyのリンクがここにある・・のですが、普段から使っているASP.NETを見てみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241909/128bb267-1d64-a4c5-20b6-c1c5586723c5.png)

下記のように、SameSiteをC# Core2Xで設定します。

```csharp

Response.Cookies.Append("Key", "Value", new CookieOptions()
{
     SameSite = SameSiteMode.None,
     Secure = true,
});
```
Ｗｉｎｄｏｗｓ に miniconda いれて、jupyterlab を動かす。

# 目的
- Windows10 にmiconda をユーザ環境に入れ、jupyter を動かす。

# 目標
- 作業時間 20 分

# 作業
- ユーザディレクトリにインストール just me
- path は設定する（推奨されていない)

まずはアップデート
```
conda update conda -y 
```

- 最初はpandas + jupyter

```
conda install pandas lxml pyyaml jupyter matplotlib jupyterlab seaborn -y
jupyter notebook --generate-config -y
conda install -c conda-forge jupyter_contrib_nbextensions -y
```

.jupyter/jupyter_notebook_config.py jupyter の設定ファイルを編集

```
c.NotebookApp.notebook_dir='該当dir'
c.NotebookApp.ip = '*' # 外部からアクセス可能にする windows の場合は firewall 開ける必要あり
c.NotebookApp.password = 'sha1:8e7ab4a681bd:806aca97983ef712ebf3302ccac7d7975ad8773a'
# password は、xxx
```

```
conda install selenium beautifulsoup4  -y
conda install -c anaconda openpyxl -y
conda install pep8 -y
conda install -c conda-forge autopep8 -y
```
Studyplusで時短管理学習してみました。


# 目的、背景
> 仕事や家庭などでなかなか学習できない、そのような人向けとして、このStudyplusを社会人こそ使うと便利だと気づきました。また、今年は応用情報などの資格を取りたいという人向けにも良いです。

# 実践
## 0.社会人カテゴリーがあるので社会人でも気軽に参加できる。

## 1.教材登録できます！
![Screenshot_20200204_080843_jp.studyplus.android.app.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57249/9db04dfb-e0bf-2d0f-644c-47e1e0dd6e48.jpeg)


## 2.学習成果をグラフで視覚化
![Screenshot_20200204_080546_jp.studyplus.android.app.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57249/96e3c7a3-d1a0-bcfd-3519-2f280756650d.jpeg)

![Screenshot_20200207_081104.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57249/534c8706-6433-2d81-ac05-6dc4cfd7c66a.jpeg)


## 3. カレンダー管理で学習計画を立てられる
> 達成目標を設定でき、それに向けて学習できる。
![Screenshot_20200204_080557_jp.studyplus.android.app.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57249/820dbbe4-7b18-7bf7-f14a-baf9ae61a90c.jpeg)

## 4. SNS、通知機能ついてる

## 5. メモ機能もついてる
![Screenshot_20200204_082606_jp.studyplus.android.app.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57249/7e885e40-8ee2-3906-beb8-e450045cdecf.jpeg)


## さいごに
> 以上のことから、studyplus+qiitaなどを使うとさらに便利にエンジニアライフを送れるのではないでしょうか？
[コマンド] クリップボードに貼り付け pbcopy


公開鍵をサイトにコピペしたいときに

### [Mac]

```shell

$ pbcopy < ~/.ssh/id_rsa.pub
もしくは
$ cat ~/.ssh/id_rsa.pub | pbcopy
```

カレントディレクトリのパスをコピペする場合

```shell
 % pwd | pbcopy
```

### [Windows]

```shell

$ clip < ~/.ssh/id_rsa.pu
```
ElGamal暗号

### はじめに
ElGamal暗号というのをたまに聞くので、調べてみました。
この記事で出てくる数は全て整数です。

### 下準備
#### 位数
```p```が素数で```GCD(a,p) = 1```だとして、

```math
a^{k} = 1\bmod p
```
を満たす、最も小さい```k```。
#### 原始元

```math
a^{b} \bmod p
```
位数が```p-1```の```a```を原始元といって、原始元を```1```から```p-1```まで乗じていくと、```1```から```p-1```までの元が1度づつでてくるらしい。

### 鍵の作成
1. ランダムな素数```p```を選んで、その```p```の原始元を選ぶ（複数あるかもしれないので）
2. ```1```から```p-1```の間の数```x```をランダムに選ぶ。
3. ```y```を計算：

```math 
y=g^{x} \bmod p
```
4. ```(p, g, y)```を公開鍵、```x```を秘密鍵とする。

### 暗号化
mをメッセージ（1からp-1までの数）として、公開鍵```(p, g, y)```を使って以下を実行：

1. ```1```から```p-1```の間の数```r```をランダムに選ぶ。
2. 暗号文```(c1, c2)```を計算：

```math
c_1 = g^{r} \bmod p\\
c_2 = my^{r} \bmod p
```

### 復号化
秘密鍵```x```、公開鍵中の```p```を使って、暗号文```(c1, c2)```から復号化したメッセージ```m'```を計算：

```math
m'= \frac{c_2}{c_1^{x}} \bmod p
```

modの計算なので、フェルマーの小定理を使って、割り算部分を掛け算に直す：

```math
\frac{1}{c_1^{x}} = c_1^{-x} * c_1^{p-1} = c_1^{p-1-x}  

```
なので、

```math
m'= c_2 c_1^{p-1-x} \bmod p
```
#### メカニズム

```math 
c_2=m\bigl(g^{x}\bigl)^{r} \bmod p\\
c_1^{x}= \bigl(g^{r}\bigr)^{x} \bmod p
```

なので、```c2```を```c1^x```で割ると```m```になる

### サンプルコード

```python
import random

def genkeys(p, g):
  x = random.randint(1, p-1) # 秘密鍵
  y = (g ** x) % p
  pub = [p, g, y] # 公開鍵
  return [pub, x]

def encrypt(m, g, y, p):
  r = random.randint(1, p-1)
  c1 = (g ** r) % p
  c2 = (m * (y ** r)) % p
  encm = [c1, c2] # 暗号文
  return [encm, r]

def decrypt(c1, c2, x, p):
  m = (c2 * (c1 ** (p - 1 - x))) % p # <- c2 / (c1^x) mod p と同じ意味
  return m

[[p, g, y], x] = genkeys(7, 5) # 5は法7の原始元

print('Pub: p=%d, g=%d, y=%d' % (p, g, y))
print('Priv: x=%d' % x)

m = random.randint(1, p-1)
print('m = %d' % m)
[[c1, c2], r] = encrypt(m, g, y, p)

print('m (encrypted): c1=%d, c2=%d; r = %d' % (c1, c2, r))

m2 = decrypt(c1, c2, x, p)
print('m (decrypted): %d' % m2)

print('is success? -> %s' % (m == m2))
```

### 参考書籍
暗号技術のすべて／IPUSIRON著
FirebaseAuthで同時ログイン(二重ログイン)の禁止を実装してみる

# はじめに

FirebaseAuthを利用してWebサービスを作成している際
同一アカウントへの同時ログイン(二重ログイン）を制限したい要望がありました。

テスト的に
(少々強引に)
実装してみた手法についてのメモです

# 記事の対象の環境について

サーバサイド処理はcloud functionsにて
クライアントサイドは[Vue.js](https://www.npmjs.com/package/vue) + [firebase](https://www.npmjs.com/package/firebase)にて構築しています。

# 方針


[revokerefreshtokens](https://firebase.google.com/docs/reference/admin/node/admin.auth.Auth.html#revokerefreshtokens)を呼び出して、ログインの処理を行うときに過去にログインしていた状態を破棄するようにしてみる

# サーバサイド実装

```js
const admin = require('firebase-admin');
admin.initializeApp();
export const func1 = functions.region('asia-northeast1').https.onCall(async (data, context) => {
    const uid = data.uid

    await admin.auth().revokeRefreshTokens(uid)
    return 'OK'
});

```

# クライアント実装

```vue
<template>
<div>
<input type="email" v-model="email"/>
<input type="password" v-model="password"/>
<button @click="login">login</button>
</div>
</template>

<script>
import firebase from "firebase";

async function sleep(sec) {
  return new Promise(resolve => setTimeout(resolve, sec * 1000));
}

export default {
  name: "SignIn",
  data: [
    email: "",
    password: ""
  },
  methods: {
    async login() {
      try {
        // ログイン処理１回目
        const result = await firebase
          .auth()
          .signInWithEmailAndPassword(this.email, this.password);

          // cloud functionに定義したfunc1を呼び出す
          const func1 = firebase.app().functions("asia-northeast1").httpsCallable('func1');
        
          await func1(result.user.uid);

　　　　　　// @todo クラウドファンクションの処理を待つためにsleepさせている
          await sleep(2); 

          // ログイン処理2回目
          const result2 = await firebase
            .auth()
            .signInWithEmailAndPassword(this.email, this.password);

          this.$router.push('/private/space');
        }
      } catch (e) {
        alert("ログインに失敗しました");
      }
    }
  }
```

# 最後に

これらの方法でとりあえずの同時ログインの禁止(以前にログインしたセッションは強制ログアウトする)を実装することはできました。
sleepさせている処理など、タイミングによって問題になりそうな処理ではあるので
なにかいい方法があればいいのですが。
言語処理100本ノック-20(pandas使用):JSONデータの読み込み

[言語処理100本ノック 2015](http://www.cl.ecei.tohoku.ac.jp/nlp100/)[「第3章: 正規表現」](http://www.cl.ecei.tohoku.ac.jp/nlp100/#ch3)の[20本目「JSONデータの読み込み」](http://www.cl.ecei.tohoku.ac.jp/nlp100/#sec20)記録です。
1年以上前にやった内容の復習なのですが、ほとんど覚えていなかったです。正規表現は、必要な時に毎回ググりながらやっていたのですが、少なくても記事などにアウトプットしないと私には意味が小さいと痛感しました。
20本目は正規表現課題の準備としてJSONファイル読込で、非常に簡単です。`pandas`を使って読み込んでいますが、改めて`pandas`の便利さを実感します。

# 参考リンク

|リンク|備考|
|:--|:--|
|[020.JSONデータの読み込み.ipynb](https://github.com/YoheiFukuhara/nlp100/blob/master/03.%E6%AD%A3%E8%A6%8F%E8%A1%A8%E7%8F%BE/020.JSON%E3%83%87%E3%83%BC%E3%82%BF%E3%81%AE%E8%AA%AD%E3%81%BF%E8%BE%BC%E3%81%BF.ipynb)|回答プログラムのGitHubリンク|
|[素人の言語処理100本ノック:20](https://qiita.com/segavvy/items/dc1e63fd8f7bd5d99eea)|多くのソース部分のコピペ元|
|[ゼロから覚えるPython正規表現の基本とTips](https://qiita.com/FukuharaYohei/items/459f27f0d7bbba551af7)|当ノックで学習した内容を整理しました|
|[正規表現 HOWTO](https://docs.python.org/ja/3/howto/regex.html#regex-howto)|Python公式の正規表現How To|
|[re --- 正規表現操作](https://docs.python.org/ja/3/library/re.html)|Python公式のreパッケージ説明|

# 環境

|種類|バージョン|内容|
|:--|:--|:--|
|OS|Ubuntu18.04.01 LTS|仮想で動かしています|
|pyenv|1.2.15|複数Python環境を使うことがあるのでpyenv使っています|
|Python|3.6.9|pyenv上でpython3.6.9を使っています<br>3.7や3.8系を使っていないことに深い理由はありません<br>パッケージはvenvを使って管理しています|

上記環境で、以下のPython追加パッケージを使っています。通常のpipでインストールするだけです。

|種類|バージョン|
|:--|:--|
|pandas|0.25.3|

# [第3章: 正規表現](http://www.cl.ecei.tohoku.ac.jp/nlp100/#ch3)
## 学習内容
> Wikipediaのページのマークアップ記述に正規表現を適用することで，様々な情報・知識を取り出します．
>> 正規表現, JSON, Wikipedia, InfoBox, ウェブサービス

## ノック内容
> Wikipediaの記事を以下のフォーマットで書き出したファイル[jawiki-country.json.gz](http://www.cl.ecei.tohoku.ac.jp/nlp100/data/jawiki-country.json.gz)がある．

> - 1行に1記事の情報がJSON形式で格納される
> - 各行には記事名が"title"キーに，記事本文が"text"キーの辞書オブジェクトに格納され，そのオブジェクトがJSON形式で書き出される
> - ファイル全体はgzipで圧縮される

> 以下の処理を行うプログラムを作成せよ．

### [20. JSONデータの読み込み](http://www.cl.ecei.tohoku.ac.jp/nlp100/#sec20)
> Wikipedia記事のJSONファイルを読み込み，「イギリス」に関する記事本文を表示せよ．問題21-29では，ここで抽出した記事本文に対して実行せよ．



# 回答
## 回答プログラム [020.JSONデータの読み込み.ipynb](https://github.com/YoheiFukuhara/nlp100/blob/master/03.%E6%AD%A3%E8%A6%8F%E8%A1%A8%E7%8F%BE/020.JSON%E3%83%87%E3%83%BC%E3%82%BF%E3%81%AE%E8%AA%AD%E3%81%BF%E8%BE%BC%E3%81%BF.ipynb)

```python
from pprint import pprint

import pandas as pd

df_wiki = pd.read_json('./jawiki-country.json', lines=True)
pprint(df_wiki[(df_wiki['title'] == 'イギリス')]['text'].values.item())
```

## 回答解説
`read_json`関数でJSONファイルを読み込んでいます。`lines`パラメータにTrueを渡すことで[JSON Lines](JSON Lines)というフォーマットを読み込めます。

```python
df_wiki = pd.read_json('./jawiki-country.json', lines=True)
```
読み込んだ`DataFrame`はこんな感じ。`title`に国名が入っています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134273/b127b21e-09c9-ba87-e1b1-b486d7e26b52.png)

結果を最後に出力します。改行したかったので`pprint`関数使っています。

```python
pprint(df_wiki[(df_wiki['title'] == 'イギリス')]['text'].values.item())
```

```bash:出力結果
('{{redirect|UK}}\n'
 '{{基礎情報 国\n'
 '|略名 = イギリス\n'

中略

 '[[Category:君主国]]\n'
 '[[Category:島国|くれいとふりてん]]\n'
 '[[Category:1801年に設立された州・地域]]')
```
Intellijでvueを扱う時の初期設定

Intellijでvueを使う時、設定方法をいつも忘れるので、備忘録として残しておく。

# ESLint
vue create appで

```
? Pick a linter / formatter config: 
  ESLint with error prevention only 
  ESLint + Airbnb config 
  ESLint + Standard config 
❯ ESLint + Prettier 
  TSLint (deprecated) 
? Pick additional lint features: (Press <space> to select, <a> to toggle all, <i> to invert selection)
❯◉ Lint on save
 ◯ Lint and fix on commit
```
これで保存時にLintが効くようになる。(誤った構文を記載するとwarningで教えてくれる

# Prettierの設定

```
npm add --dev prettier eslint-config-prettier eslint-plugin-prettier
```

```js:.eslintrc.js
module.exports = {
  root: true,
  env: {
    node: true
  },
  extends: [
    'plugin:vue/essential',
    'eslint:recommended',
    '@vue/typescript',
    'plugin:prettier/recommended'
  ],
  rules: {
    'prettier/prettier': ['error', { singleQuote: true, semi: false }],
    'vue/mustache-interpolation-spacing': ['error', 'always' | 'never'], // マスタッシュ構文は空白をいれる
    'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off',
    'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off'
  },
  parser: 'vue-eslint-parser',
  parserOptions: {
    parser: '@typescript-eslint/parser'
  },
  overrides: [
    {
      files: ['**/__tests__/*.{j,t}s?(x)'],
      env: {
        mocha: true
      }
    }
  ]
}
```

File Watchersを以下のように設定
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47132/947f066f-6fd1-3db0-2a9c-279c3279a049.png)

```
Program: $ProjectFileDir$/app/node_modules/.bin/eslint
Arguments: --fix $FilePathRelativeToProjectRoot$
Output paths to refrash: $FilePathRelativeToProjectRoot$
Wroking directory: $ProjectFileDir$
```

これで自動的に誤った構文を正してくれる（超便利！
(※intellijのcode style設定と競合する場合がある時は、適宜、warningを除外する設定を追加する。今回の設定ではセミコロンはつけないというESlintを設定している。「Unterminated statement」でwarningが出たが、これを除外設定した。


```
【注意】
"eslint": "^5.16.0",
"eslint-plugin-prettier": "^3.1.1",
"eslint-plugin-vue": "^5.0.0",
"prettier": "^1.19.1",
```
ここらへんのバージョンにしないと、よくわからないエラーが出るようになった。
(分かり次第追記します。

# 実行設定
Run/Debug Configrationsでnpmを選択し、package.jsonにpathを、scriptにserveを設定することで実行が行えるようになる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47132/454f93db-80e0-79ae-a5cc-e318b07c9a48.png)

# vuetifyの導入
```
vue add vuetify
```

typescriptの場合エラーが出るので以下で修正

```ts:tsconfig.json
...
    "sourceMap": true,
    "baseUrl": ".",
    "types": [
      "webpack-env",
      "mocha",
      "chai",
      "vuetify" #追加
    ],
    "paths": {
...
```
これでエラーなくvuetifyを起動できる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47132/e64e7e77-399f-d139-846e-14310f18b732.png)

# おわりに
なんか良い設定あったら随時更新していく！
ECL Readlineを有効化した状態でのCFFI-LIBFFIのコンパイルエラーについて

# ECL Readlineを有効化した状態でのCFFI-LIBFFIのコンパイルエラーについて

## はじめに

インストールしているパッケージのコンパイルキャッシュを全て削除してプログラムをビルドしようとしたところ、`GROVEL-ERROR`というものが発生して途中で止まってしまいました。
根本的な原因はわかっていませんが、ECL Readlineを使用している環境だとこの問題が発生する感じです(途中でECL Readline環境にしたため、気付かなかった)

### 環境

- Debian GNU/Linux buster
- ECL 16.1.3
- [ECL Readline 0.4.1](https://common-lisp.net/project/ecl-readline/)

## cffi-libffiのエラー

CFFIパッケージに含まれるcffi-libffiのコンパイルで次のようなエラーが出ます。

```common-lisp
CL-USER[1]> (asdf:load-system :cffi-libffi)
; pkg-config libffi --cflags

; gcc -o /home/hiro/.cache/common-lisp/ecl-16.1.3-unknown-linux-x64/home/hiro/deepspace/share/deepspace/quicklisp/dists/quicklisp/software/cffi_0.20.1/libffi/libffi-types__grovel-tmpUWNGR0DC.o -c -Wdate-time -D_FORTIFY_SOURCE=2 -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -g -O2 -fdebug-prefix-map=/build/ecl-IeawtT/ecl-16.1.3+ds=. -fstack-protector-strong -Wformat -Werror=format-security -fPIC -D_THREAD_SAFE -Dlinux -fPIC -I/home/hiro/deepspace/share/deepspace/quicklisp/dists/quicklisp/software/cffi_0.20.1/ /home/hiro/.cache/common-lisp/ecl-16.1.3-unknown-linux-x64/home/hiro/deepspace/share/deepspace/quicklisp/dists/quicklisp/software/cffi_0.20.1/libffi/libffi-types__grovel.c

Condition of type: GROVEL-ERROR
:INPUT argument to RUN-PROGRAM does not have a file handle:
#<two-way stream 000055be22c0e5a0>
```

`INPUT argument to RUN-PROGRAM does not have a file handle〜`と出るんですが、何か悪いのかわからない状態で、ひとまず`--norc`オプションで何も設定ファイルを読み込まないECLだと問題なくcffi-liffiをコンパイルできることがわかりました。

使用しているeclrcを確認して色々試していると、ECL Readlineの有効化によってこの問題が発生していることがわかりました。

## 使用しているeclrc

```common-lisp
(defparameter *deepspace-home* (si:getenv "DEEPSPACE_HOME"))
(load (concatenate 'string *deepspace-home* "/lib/asdf.lisp"))
(require 'asdf)
(setf asdf:*asdf-verbose* nil)
(setf *load-verbose* nil)
(asdf:initialize-source-registry
`(:source-registry
   (:tree ,(concatenate 'string *deepspace-home* "/share/deepspace/quicklisp/dists/quicklisp/software"))
   (:tree ,(concatenate 'string *deepspace-home* "/lib/"))
   (:tree ,(namestring *default-pathname-defaults*))
   (:tree ,(concatenate 'string (namestring *default-pathname-defaults*) "lib"))
   :inherit-configuration))
(asdf:initialize-output-translations
 '(:output-translations
   :enable-user-cache
   :ignore-inherited-configuration))
(asdf:load-system :ecl-readline)
(ecl-readline::enable)
```

この中で、ECL Readlineを有効化している`(ecl-readline::enable)`を一時的にコメントアウトしREPLを起動し、その上でcffi-libffiをロードすると、問題なくコンパイルされることを確認済です。
Vueの子コンポーネントでpropsの変更を検知する

```parent.vue
<template>
  <childComponent name="foo">
</template>
// 略
```

```child.vue
<template>
  <div>{{ awesomeName }}</div>
</template>
<script>
export default {
  props: {
    name: String
  },
  data () {
    return {
      awesomeName: this.name
    }
  }
</script>
```

こういう時、親から渡す値が変更された際に検知するにはpropsをwatchで監視する。

```child.vue
// 略
<script>
export default {
// 略
    watch {
      name (newName) {
        this.awesomeName = newName;
      }
    }
// 略
</script>
```

おういえ🤩
PodmanでphpMyAdminを起動してみる

# 環境

Fedora CoreOS 31.20200113.3.1
Podman 1.7.0
Podman Compose 0.1.5
phpMyAdmin 5.0.1
MariaDB 10.4.12

# 準備

```
$ sudo sed -i --follow-symlinks 's/SELINUX=enforcing/SELINUX=permissive/g' /etc/sysconfig/selinux
$ sudo reboot
$ sudo rpm-ostree install python3 -r
$ sudo pip3 install podman-compose
$ mkdir -p ~/.local/bin
$ curl -o ~/.local/bin/podman-compose https://raw.githubusercontent.com/containers/podman-compose/devel/podman_compose.py
$ chmod +x ~/.local/bin/podman-compose

$ mkdir -p mariadb/data
$ chmod 777 mariadb/data
$ mkdir -p phpmyadmin/sessions
$ chmod 777 phpmyadmin/sessions
```
# ファイル

```docker-compose.yml
version: '3.7'

services:
  mariadb:
    container_name: mariadb1
    hostname: mariadb1
    image: mariadb:10.4.12
    volumes:
      - ./mariadb/data:/var/lib/mysql
    env_file:
      - ./.mariadb.env
  phpmyadmin:
    container_name: phpmyadmin1
    hostname: phpmyadmin1
    image: phpmyadmin/phpmyadmin:5.0.1
    env_file:
      - ./.phpadmin.env
    depends_on:
      - mariadb
    ports:
      - 4040:80
    volumes:
      - ./phpmyadmin/sessions:/sessions
```

```:.mariadb.env
MYSQL_ROOT_PASSWORD=root
MYSQL_DATABASE=test
MYSQL_USER=test
MYSQL_PASSWORD=test
```

```:.phpmyadmin.env
PMA_ARBITRARY=1
PMA_HOST=mariadb
PMA_USER=test
PMA_PASSWORD=test
```
# 実行

```
$ podman-compose up -d
$ podman ps

CONTAINER ID  IMAGE                                  COMMAND               CREATED        STATUS            PORTS                 NAMES
b0cb4cdcbd81  docker.io/phpmyadmin/phpmyadmin:5.0.1  apache2-foregroun...  7 seconds ago  Up 6 seconds ago  0.0.0.0:4040->80/tcp  phpmyadmin1
48b33e725e80  docker.io/library/mariadb:10.4.12      mysqld                8 seconds ago  Up 8 seconds ago  0.0.0.0:4040->80/tcp  mariadb1
```
![1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208807/2d653229-5710-2ca0-081e-1215c7171926.png)
Yahoo映画から近日公開映画名をスクレイピングする

スクレイピングに興味あったのでやってみた。
urllibでスクレイピング対象のURLを開く、BeautifulSoupでHTMLから欲しい情報を取得。

```py

import urllib.request
from bs4 import BeautifulSoup

def scraping():
    # アクセスするURL
    url = "https://movies.yahoo.co.jp/movie/soon/"
    # htmlの取得
    html = urllib.request.urlopen(url)
    bs = BeautifulSoup(html, "html.parser")

    # 各映画の情報
    movies = bs.findAll("div", {"class":"thumbnail__caption"})

    # 出力
    for movie in movies:
        title = movie.find("a").string
        date = movie.find("span", {"class":"label bgcolor-B"}).string
        print(title, date)

if __name__ == "__main__":
    scraping()
```

Python3じゃないと`from bs4 import BeautifulSoup`でエラーでるし、
Python3だと`import urllib2`ではなく`import urllib.request`にしないとだめっぽい。


実行するとこんなかんじ。

```
犬鳴村 2020年2月7日公開
ヲタクに恋は難しい 2020年2月7日公開
アントラム　史上最も呪われた映画 2020年2月7日公開
ハスラーズ 2020年2月7日公開
ザ・ピーナッツバター・ファルコン 2020年2月7日公開
グッドライアー　偽りのゲーム 2020年2月7日公開
37セカンズ 2020年2月7日公開
ファンシー 2020年2月7日公開
静かな雨 2020年2月7日公開
侍の名のもとに～野球日本代表 侍ジャパンの800日～ 2020年2月7日公開
アンストッパブル 2020年2月7日公開
グリンゴ／最強の悪運男 2020年2月7日公開
ロニートとエスティ　彼女たちの選択 2020年2月7日公開
スキンウォーカー 2020年2月7日公開
プロジェクト・グーテンベルク　贋札王 2020年2月7日公開
DRONE/ドローン 2020年2月7日公開
```
スクレイピング、思ったより取得するだけならかんたんだった。
今後は概要を取りたい。ページをまたがないと。

#### メモ
今回Python初めて触ったので`if __name__ == "__main__":`こいつが何者か謎だった…

以下がとてもわかりやすかった。感謝。
https://qiita.com/homines22/items/edf7a2309f3421723550
select2 v4で日本語対応してtagsのバグを回避した方法（根治ではない

#select2 v4で日本語対応してtagsのバグをたまたま回避した

他に情報が出ないので同士の時間を溶かさないようにメモしておく。

##select2で要素を自動追加したかったので、tags:true にしたらバグ発生した。

「バッグ」と入力したら、「ばｇｇう」となってしまう。

ちょっと調べると、chrome特有の現象とか？

解決した人が、ruby gemでインストールしたら解決したとか。
https://masayuki031.com/2019/06/23/select2-rails/

なんだそりゃって思って見たら、select2の4.0.1.1が入ってる。

というわけで、バージョン疑って下げていったら、4.0.2までバグ発生しない。4.0.3でバグ発生する。

#結論。ver4.0.2を使おう。
以上、解散。

下記は、ねんのため tags:true で動く例。（どこかのコピペをバージョンだけ変更

```html
<!-- Select2.css -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.2/css/select2.min.css">
<!-- jquery & iScroll -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<!-- Select2本体 -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.2/js/select2.min.js"></script>
<!-- Select2日本語化 -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.2/js/i18n/ja.js"></script>
<script>
$(function() {
  $('.test-select2').select2({
    language: "ja",
    tags: true
  });
	//tagsを使うと、4.0.3以降はバグる
})
</script>
<style>
.test-select2 {
  width: 50%;
}
</style>
<select class="test-select2" multiple="multiple">
<option>リンゴ</option>
<option>ゴリラ</option>
<option>ラッパ</option>
</select>
```
Windows (NTFS) 滅多に使わないファイル操作

ほぼ自分用メモです。
主に元システムパーティションだったドライブを綺麗にするときに必要

**以降の処理を実行すると、所有者変更の時点でゴミ箱が壊れます。必ず事前に整頓を**
もし壊れた場合、[本記事の後ろの方](#ゴミ箱を破損させてしまった場合)を参考にしてください

あと、管理者権限のコマンドプロンプト上で実行してください。

## まずJUNCTION SYMLINK SYMLINKD を消す

消さないと、後述のコマンド実行時に盛大に事故る可能性がある（実際に事故ってC:\Usersを壊した・・・）

```powershell
cd /d D:
for /f "tokens=*" %a in ('dir /s /b /al') do rmdir "%a"
```

一部変な消え方することがあるみたい（リンク以外のものを消そうとしてる？）ので重要なフォルダには使わないでください。責任負えません。
（recursiveにしてないので空じゃないフォルダは消えないし、rmdirなのでファイルは消えないし、大丈夫だとは思いますが・・・）

## Windowsフォルダとか消す

### 所有者をAdministratorsにする

```powershell
takeown /f D: /a /r /d y
```

自分は`>nul`をつけてログ無しで実行してるが、システムパーティションに対して実行すると大概こける上に
どこでこけたかわからないので`>nul`外して実行せざるを得ないような・・・（ログ出す分遅くなる）

実行順とか気をつければどうにかできるのかもしれない。

### ACLをリセットする

```powershell
icacls D: /reset /t /c /l /q
```

エラー時続行オプション(`/c`)つけてるので必要に応じて外してください。
ルートフォルダ(`D:\`)への処理だけエラーになりますが問題ありません。
（ドライブのルートフォルダは権限の継承元がないため、リセットすると誰もアクセスできなくなってしまうのでエラーになるようです）

### 隠しファイル・読み取り専用・システムファイル属性を消す

Windowsフォルダを消すこと自体に対して必須ではないですが、その後のファイル整頓考えてやっておいてもいいと思います。

```powershell
cd /d D:
attrib -r -s -h /s /d /l
```


### Windowsフォルダを削除する

独自に入れたドライバ等を確認したい場合は、ここで確認をしてください。
レジストリを取り出したい場合もここで確認する必要あり？（自分は不要だったので未確認）
あと忘れがちなのが、`drivers/etc/hosts`

```powershell
cd /d D:
rmdir /s /q Windows
```

## その後

以下ソフト使ってファイル整頓してます
おすすめ、というわけでもないんですが参考になるなら。

WinDirStat - ディレクトリ毎の使用容量把握
https://windirstat.net/

FastCopy - ファイルコピー
https://fastcopy.jp/

WinMerge - 差分確認
https://winmerge.org/

dupeGuru - 重複ファイル検索
https://dupeguru.voltaicideas.net/

#### `System Volume Information`の容量が大きすぎて困っている場合

`コントロール パネル` => `回復` => `システム復元の構成`から
当該ドライブの`構成`を開いて復元ポイントが作成されていないか確認してみてください。

#### ショートカット・インターネットリンクを消す

InternetExplorer等のブラウザを使用している場合、**お気に入りが消えてしまう**ので、`*.url`は対象から外してください

```powershell
cd /d D:
del /f /s /a *.lnk *.url
```

#### 空フォルダを消す

junction系と同様、**rmdirの仕様が変わった場合予期しないファイルが削除される**ことがあるので十分注意してください。

```powershell
cd /d D:
for /f "tokens=*" %a in ('dir /s /b /ad ^| sort /r') do rmdir "%a"
```


## ゴミ箱を破損させてしまった場合

まず、フォルダ構造としては次のような形になっています

> $RECYCLE.BIN　　　　　　　　　　：　ゴミ箱のルートディレクトリ
> ┣ S-1-5-21-\<machine sid\>-\<rid\>　：　各ユーザごとのゴミ箱
> ┃┣ $RXXXXXXX　　　　　　　 　 ：　削除したファイルの実体
> ┃┣ $IXXXXXXX　　　　　　 　 　 ：　削除したファイルのメタデータ(場所とか削除日時とか)

※ machine sid: 00000000-00000000-00000000 (1～10桁の10進数3つをハイフンで繋いでいる)
※ rid: 1001 (ユーザを識別する4桁程度の10進数)

そして、`S-1-5-21-...`のフォルダ名を自分のIDに書き換えた上で、
所有者を自分に変更すれば、エラーも回避できますしゴミ箱を開くだけで中身を参照できます。
(数が少なくGUIから対処したのでコマンドは確認していません)
自分のSIDは、`whoami /user`で確認できます。

※参考：https://superuser.com/questions/1506219/how-to-decode-file-names-in-recycle-bin

ちなみに`.0000`から始まるファイルがいくつかあったのですがこちらは謎（未調査）です・・・
追記：
`.0000`から始まるファイルについて、中身を確認したらすべてexeまたはdllファイルでした。
また、msys2系のファイルが多かったこと・mintty.exe等と思しきファイルが多かったことから、
msys2で`pacman -Su`を実行した際に生成されている可能性があります。

## あとがき

自分用と言いながら、なにか改善要望等あれば取り入れますのでご指摘頂ければ幸いです。
寝る直前に備忘で走り書きしてるので、内容間違えてたりしたらごめんなさい。
Planckで簡単にMacとWin共通の全角半角切替キーを作る

## はじめに
MacとWinどちらも使用するplanckユーザーにとって全角半角切替は最初ぐらいの関門だと思います。
その一つの解決方法として以下に記載しておきます。


## 目的
MacとWin共に同じ操作方法が可能な全角半角切替キーを作成します。
ついでに切替キーだけだと勿体ないので長押しでRaise/Lowerレイヤーへの切替機能も付与します。
レイヤー切替の速度も任意で変更できるようにします。

## やること
やることは単純で、MacとWinで切替ショートカットを同じにしてそれを実行する処理を書くだけです。
難点は端末側でこの処理を行う必要ことです。

- Macの全角半角のショートカットをCtrl + Spaceに設定する
- Windowsの全角半角ショートカットをCtrl + Spaceに設定する
- keymap.cへの実装
- キーボードへの書き込み


## Macの全角半角のショートカットをCtrl + Spaceに設定する
Mac元々の機能を使用して変更します。超簡単
1. 左上のリンゴマークからシステム環境変数を開く
2. "キーボード"を押下
3. "ショートカット"タブから"入力ソース"を選択
4. "前の入力ソースを選択"でCtrl + Spaceに設定
5. おわり

## Windowsの全角半角ショートカットをCtrl + Spaceに設定する
こちらは普段使いのIMEの設定を変更する必要があるので各自調べてください。
…と言いたい所ですが説明にならないので[Google日本語入力]()を例に変更します。

1. google日本語のツールからプロパティを開く
2. "キー設定"からことえりを選択 > 編集を開く
3. 編集で"Ctrl Space"を探し下記のパターンを作成する

|モード|入力キー|コマンド|
|----|---|---|
|直接入力|Ctrl Space|IMEを有効化|
|入力文字なし|Ctrl Space|IMEを無効化|
|変換前入力中|Ctrl Space|IMEを無効化|
|変換中|Ctrl Space|IMEを無効化|

 参考エントリ
[Google 日本語入力でctrl spaceで半角全角の変更を出来るように変更したときのメモ](https://ang65.hatenadiary.org/entry/20110409/1302316109)

## keymap.cへの実装
行う事は下記の4点です
- 自作変換キーコードをRaiseとLowerの2種類定義
- 計測時間格納用の変数定義
- メインレイヤーキーマップへの自作キーコードの記述
- process_record_user()へのcaseの追加

### 自作変換キーコードをRaiseとLowerの2種類定義
下記2行が追加したキーコードの定義(名前は適当)

``` c#:keymap.c
    enum planck_keycodes {
    QWERTY = SAFE_RANGE,
    COLEMAK,
    DVORAK,
    PLOVER,
    BACKLIT,
    EXT_PLV,
    CONV_LOWER,
    CONV_RAISE
    };
```


### 計測時間格納用の変数定義
planck_keycodes{}の下辺りに記述します。

``` c#:keymap.c
static uint16_t key_timer;
```

### メインレイヤーキーマップへの自作キーコードの記述
追加した定義をキーボードのデフォルトのRaise、Lowerの位置に指定

``` c#:keymap.c
[_QWERTY] = LAYOUT_planck_grid(
    KC_TAB,  KC_Q,    KC_W,    KC_E,    KC_R,    KC_T,    KC_Y,    KC_U,    KC_I,    KC_O,    KC_P,    KC_BSPC,
    KC_ESC,  KC_A,    KC_S,    KC_D,    KC_F,    KC_G,    KC_H,    KC_J,    KC_K,    KC_L,    KC_SCLN, KC_QUOT,
    KC_LSFT, KC_Z,    KC_X,    KC_C,    KC_V,    KC_B,    KC_N,    KC_M,    KC_COMM, KC_DOT,  KC_SLSH, KC_ENT ,
    BACKLIT, KC_LCTL, KC_LALT, KC_LGUI, CONV_LOWER,   KC_SPC,  KC_ENT, CONV_RAISE,   KC_LEFT, KC_DOWN, KC_UP,   KC_RGHT
),
```


### process_record_user()へのcaseの追加
process_record_user()は既存のメソッドでこちらに追記する形になります。
caseに指定されたキーがrecord->event.pressedでキーが押されたか検知します。
押されると計測値がkey_timerに入り指定のレイヤーに切り替わります。

else以下はキーを離すを処理でレイヤーもとに戻します.
ここでもし離すまでの時間が120ms以下ならCtrl + Spaceを送信します。
tap_code16()はプレスイベントとリリースイベントを両方送信します。
これで実装は終わりです。

``` c#:keymap.c
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
  switch (keycode) {
    //   ここから上省略
    case CONV_LOWER:
      if (record->event.pressed) {
        key_timer = timer_read();
        layer_on(_LOWER);
      }else{
        layer_off(_LOWER);
        if(timer_elapsed(key_timer) <= 120){
          tap_code16(LCTL(KC_SPC));
        }
      }
      return false;
      break;
    case CONV_RAISE:
      if (record->event.pressed) {
        key_timer = timer_read();
        layer_on(_RAISE);
      }else{
        layer_off(_RAISE);
        if(timer_elapsed(key_timer) <= 120){
          tap_code16(LCTL(KC_SPC));
        }
      }
      return false;
      break;
  }

```

## おわりに
端末側に変更を加える必要がありますが、MacとWinで同じ操作で切替できるのは便利です。
良かったらためしてみてください。
tmux環境でenhancd実行時にパネルが分割されるのを防ぐ

# はじめに

最近新たにTerminal環境を作り直した際に表題の現象に遭遇しました。当初は何らかの設定ミスが悪さをしているものだと思っていたのですが、至ってenhancdの想定内の挙動というオチでした。簡単にまとめておこうと思います。

# 環境

* macOS
* tmux
* fish shell
* fisher
* enhancd
* fzf

# 問題

下の動画のように、tmux環境下でenhancdを実行するとfzfが実行されるものの、パネルが分割されています。

![demo_tmux-enhancd.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/135313/8747d7d8-fdfa-3b66-1528-c04ddf6eba8d.gif)

# 原因

**enhancdはデフォルトでは検索にfzfよりもfzf-tmuxコマンドが優先的に実行されるため**です。fzf-tmuxは動画のようにfzfをtmuxの別パネルで実行するコマンドであり、macのhomebrewではfzfのインストールに同封されています。

enhancdではフィルタリングを行うコマンドに複数対応していますが、初期化スクリプト内に各コマンドの優先順位が記載されています。
<https://github.com/b4b4r07/enhancd/blob/master/init.fish#L35>

これによると確かにfzfよりもfzf-tmuxが先に記載されて優先度が高く指定されていることがわかります。

# 解決策

enhancdにはちゃんとフィルタリングコマンドを指定することが可能です。

* 公式Doc: <https://github.com/b4b4r07/enhancd#configurations>/ENHANCD_FILTER
* 開発者ブログ記事: <https://qiita.com/b4b4r07/items/2cf90da00a4c2c7b7e60#enhancd_filter>

次のように環境変数を指定する1行をfishの設定ファイルに追記することで、fzf-tmuxが実行されないようにしました。(デフォルトの検索コマンドリストからfzf-tmuxを消しただけ)

```fish:~/.config/fish/config.fish
# 下行を追加
set -gx ENHANCD_FILTER "fzy:fzf:peco:percol:gof:pick:icepick:sentaku:selecta"
```


# 終わりに

tmuxのパネル分割のショートカットを別キーに設定した後だったこともあって、それが影響していると思い込んでいたのですが全くの勘違いでした。至って想定どおりの挙動。思い込みって怖い。

# 参考文献

* <https://github.com/b4b4r07/enhancd#configurations>
* <https://qiita.com/b4b4r07/items/2cf90da00a4c2c7b7e60#enhancd_filter>
* <https://wonderwall.hatenablog.com/entry/2017/10/06/063000#fzf-tmux>
UITableViewCell の高さを UIImage のアスペクト比を元に決定する方法

# はじめに
UITableViewCell にセットする画像のアスペクト比が固定ではない場合、セルの高さの決め方を工夫する必要があります。今回はその方法の一つとして、 AutoLayout を用いた解決策を示します。

# 解決策
```swift
final class CustomTableViewCell: UITableViewCell {
     @IBOutlet private weak var mainImageView: UIImageView!

     private var aspectConstraint: NSLayoutConstraint? {
         didSet {
             if let value = oldValue {
                 mainImageView.removeConstraint(value)
             }
             if let constraint = aspectConstraint {
                 mainImageView.addConstraint(constraint)
             }
         }
     }
     
     func prepare(image: UIImage) {
         setImage(image)
     }

     private func setImage(_ image: UIImage) {
         let aspect = image.size.width / image.size.height

         let constraint = NSLayoutConstraint(
             item: mainImageView as Any,
             attribute: .width,
             relatedBy: .equal,
             toItem: mainImageView,
             attribute: .height,
             multiplier: aspect,
             constant: 0.0
         )
         constraint.priority = UILayoutPriority(rawValue: 999)
         aspectConstraint = constraint

         mainImageView.image = image
     }
 }
```

`aspectConstraint: NSLayoutConstraint?` ではセルの再利用を考慮して制約の削除も行っています。また、セルに対して複数回画像がセットされる可能性がある場合（セルのイニシャライズが行われてから破棄されるまでの間に複数回 `setImage()` が呼ばれる場合）にも対応します。

実際に制約を作成して UIImageView に適応するのが `setImage()` になります。 `priority` に関しては、構築している UI に応じて臨機応変に設定してください。

# 参考文献
[Dynamic UIImageView Size Within UITableView
](https://stackoverflow.com/questions/32281886/dynamic-uiimageview-size-within-uitableview)
[AtCoder Beginner Contest 152-D問題]を解く！

#記事の概要
今回解くのは[ABC152-D問題](https://atcoder.jp/contests/abc152/tasks/abc152_d)。最初問題を読んでも全く意味がわからず、解説を読んでも理解することに時間がかかった。今は理解しているが少し経てばどうせ忘れるので自分の考えをまとめておこうという魂胆である。

#問題
正の整数 N が与えられます。
N 以下の正の整数の組 (A,B)であって、次の条件を満たすものの個数を求めてください。

**[条件]**
A,Bを先頭に 0 のつかない 10 進数表記で表したときに、 A の末尾の桁が B の先頭の桁に等しく、 A の先頭の桁が B の末尾の桁に等しい

**[制約]**
- 1≤N≤2×105
- 入力はすべて整数である。

**[入力]**
N

#考え方
まず条件を見てみよう。数字の最初の一桁と最後の一桁を入れ替えたやつがペアになる(間は何だろうと関係ない)ということなので例えば(12,21)や(102,221)になる。少し特殊な例だと(1,1)や(1,11)もペアである。要するには最初の一桁(1~9)と最後の一桁(0~9)を管理して、同じものをひとまとめにすれば良い。例を挙げると(12,102,112,122,132)はどれも最初が1で最後が2なので区別する必要がないのである。なら二次元配列[最初の数字][最後の数字]で管理できると考えられる。

```c++
for(int i = 1 ; i <= n ; i++){
        int v = static_cast<int>(log10(i)); 
        int max = i / pow(10,v); //最初の一桁
        int min = i % 10;  //最後の一桁
        number[max][min]++;
    }
```

最後の一桁は10で割ればあまりで出てくるから簡単。最初の一桁は少しめんどくさくて、まずlogで桁数-1を求めて、10の桁数-1乗で割れば商で出てくる。二次元配列には最初の一桁と最後の一桁が同じ数字の個数がカウントされていく。
しかしこれではまだ答えになっていない。number[1][2]とnumber[2][1]をペアにしないといけない。Nを150と考えるとnumber[1][2]には(12,102,112,122,132,142)の6が格納されている。一方number[2][1]には(21,201,211,221,231,241)の6が格納されている。ペアの総数は組み合わせで出るので6*6=36ということになる。要するにnumber[max][min] * number[min][max]の総和である。

#解答例
```c++:handstand2.cpp
    #include <bits/stdc++.h>
    using namespace std;
     
    int main(){
        int n,ans;
        cin >> n;
        int number[10][10];

        for(int i = 0 ; i < 10 ; i++){
            for(int j = 0 ; j < 10 ; j++){
                number[i][j] = 0;
            }
        }

        //最初の一桁と最後の一桁が同じ数字をひとまとめにして個数を格納
        for(int i = 1 ; i <= n ; i++){
            int v = static_cast<int>(log10(i)); //最初の一桁
            int max = i / pow(10,v); //桁数計算
            int min = i % 10; //最後の一桁
            number[min][max]++;
        }

        //ペアの総数計算
        for(int i = 0 ; i < 10 ; i++){
            for(int j = 0 ; j < 10 ; j++){
                ans += number[i][j] * number[j][i]; //組み合わせ
            }
        }
     
        cout << ans;
        return 0;
    }
```

#最後に
書いている時はすごく考えがまとまっているけど、時間が経って読み直す時は何言ってんだこいつってなりそう。ちょっとしたら読み直して修正します。読んでくれたみなさんありがとう。
【Android】〜 AndroidStudioのテンプレート「Basic Activity」の構成要素を調べる 〜

#Basic Activityのアーキテクチャ
![basicactivity.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/249786/69844085-a19b-6b0e-7055-08a85f67b157.png)


###①　ステータスバー

Activityからステータスばーへアクセスすることができて，このバーを非表示にすることができる．

###②　アクションバー/アプリバー

このようにナビゲーションを提供します．

###③　アプリ名

`AndroidManifest.xml`というファイルから，`android:label="@string/app_name"`の要素から変更できます．
（`@string/app_name`は，`string.xml`の`app_name`の要素という意味）

###④　オプションメニュー

検索を配置するときもあります．

###⑤　Coordinatorレイアウト

アプリのUIは，`content_main.xml`に定義されていて，ViewGroupのように相互に作用するものになっています．

###⑥　TextView

`TextView`のようなアプリのUIとなるビューは，すべて`content_main.xml`に定義されています．

###⑦　フローディングアクションボタン（FAB）

`activity_main.xml`で定義され，FABのリスナーは`MainActivity.kt`のonCreate内で定義されます．

#アプリをカスタマイズする

###Snackbarの表示を変更する
これを行うには，ボタンのリスナーを変更する必要があるので，`MainActivity.kt`を開いてこのように修正してみましょう．

```
fab.setOnClickListener { view ->
   Snackbar.make(view, "This FAB needs an action!", Snackbar.LENGTH_LONG)
       .setAction("Action", null).show()
}
```

###FABのcolorを変更する

FABのcolorは，アクセントカラーを使用するため，アクセントカラーを変更してあげることが一つの方法です．

`res`>`value`>`color.xml`より，ファイルを開き，`colorAccent`属性を変更します．

```
<color name="colorAccent">#1DE9B6</color>
```

![1-4-9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/249786/c1967510-b11a-a2c8-ae5c-629655070067.png)


アプリを実行すると，SnackbarのテキストとFABのColorが変更されていることが確認できます．


#参考資料
###CodeLabs by Google
https://codelabs.developers.google.com/android-kotlin-fundamentals/
<img width="1206" alt="スクリーンショット 2020-01-31 3.41.00.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/249786/e3064461-649d-8535-4fc3-79a68f40709a.png">
Dockerのコンテナ内でmigrateを実行した際の「 failed: Name or service not known」に関して


DockerでLaravelの環境構築をしてコンテナないで、php artisan migrateを実行すると下記のエラーが発生したので、解決策を忘備録として残しておきます。

##エラー内容
```
root@a65fb3be52e4:/var/www# php artisan migrate

   Illuminate\Database\QueryException  : SQLSTATE[HY000] [2002] php_network_getaddresses: getaddrinfo failed: Name or service not known (SQL: select * from information_schema.tables where table_schema = todos_app and table_name = migrations and table_type = 'BASE TABLE')

  at /var/www/vendor/laravel/framework/src/Illuminate/Database/Connection.php:669
    665| // If an exception occurs when attempting to run a query, we'll format the error
    666| // message to include the bindings with SQL, which will make this exception a
    667| // lot more helpful to the developer instead of just the database's errors.
    668| catch (Exception $e) {
  > 669|  throw new QueryException(
    670|  $query, $this->prepareBindings($bindings), $e
    671|  );
    672| }

  Exception trace:

  1   PDOException::("PDO::__construct(): php_network_getaddresses: getaddrinfo failed: Name or service not known")
      /var/www/vendor/laravel/framework/src/Illuminate/Database/Connectors/Connector.php:70

  2   PDO::__construct("mysql:host=mysql;port=3306;dbname=todos_app", "root", "", [])
      /var/www/vendor/laravel/framework/src/Illuminate/Database/Connectors/Connector.php:70

  Please use the argument -v to see more details.
```

`failed: Name or service not known` と言われているので設定ファイル内が怪しいということで確認してみることに。

##各種設定ファイル

```:.env
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=todos_app
DB_USERNAME=root
DB_PASSWORD=root
```

```docker-composer.yml
  db:
    image: mysql:5.7
    container_name: db-host_2
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: todos_app
      MYSQL_USER: root
      MYSQL_PASSWORD: root
      TZ: 'Asia/Tokyo'
    command: mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
    volumes:
      - ./docker/db/data:/var/lib/mysql
      - ./docker/db/my.cnf:/etc/mysql/conf.d/my.cnf
      - ./docker/db/sql:/docker-entrypoint-initdb.d
    ports:
      - 3306:3306
```

.envファイル内で設定している`DB_PORT`, `DB_DATABASE`, `DB_USERNAME`, `DB_PASSWORD`　はdocker-compose.ymlで設定しているものと同じなので問題はなさそう。。

と思っていたのですが、[こちらの記事](https://tech.pjin.jp/blog/2018/02/27/docker%E3%81%A7php%E3%82%A8%E3%83%A9%E3%83%BC%E3%80%8Cphp_network_getaddresses-getaddrinfo-failed-name-or-service-not-known%E3%80%8D/)によると、`DB_HOST`はIPアドレスではなくて、service名を指定するとのことでした。

そのため.envファイルを下記に修正したら、無事にmigrateが実行されました。

```:.env
DB_CONNECTION=mysql
DB_HOST=db
DB_PORT=3306
DB_DATABASE=todos_app
DB_USERNAME=root
DB_PASSWORD=root
```
Javaで同一階層のファイルをimportする

packageって考え方が必要らしい。

package = directory と思うと楽そうだ。

mainの .java ファイルをとあるフォルダに入れる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24737/18347cc6-4b90-a7fa-7843-c1bea6dc6fec.png)

main()がある `Test1.java` の先頭にこれを入れる

```java
package test1;
```

そうすると、何もimportせずに同一階層の **MyTest1Exception.java** が読み込める。

```java
	void runSample() throws MyTest1Exception {
                    ...
			throw new MyTest1Exception("独自の例外です"); 
```

ふむ


reference
https://itsakura.com/java-dokuji-reigai
コミュニケーションについて本気出して考えてみた

## ０．はじめに

コミュニケーションについて、ベンズで考えてみた。
よく本とかにある情報が、きっと頭の隅に残っているのだろうけど、
一応自分の中から捻出してみたつもり。まずはβ版的な。
（次は、コミュニケーションの質を濃度で表現したい）

## １．基本系

まずは定義から。こんな感じです。

　　　![01_説明.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/384185/7063df0c-fa72-876f-1e81-1b14fa9fe97a.png)


で、最大化する方法は２つあります。
　　　![02_method01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/384185/5e3fa30b-fac9-eb6a-db37-6dc5a49cbb74.png)
　　　![03_method2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/384185/6ae372b3-a53d-48a4-9592-4ba98eb34848.png)



多分、方法１の方が楽です。でも方法２の方が、効果的だと思います。
複数人のケースを後で示しますが、きっと**方法２の方が汎用性あり**かと。
方法２は情報バリエーションを出しまくって、**プライベートとかガンガン出していこう**、っていうアプローチです。

## ２．注意したい事

注意したいことは、あまり近づきすぎるのもダメということ。

　　　![04_WARN.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/384185/91216c14-4c5e-201e-a90c-178d7e263a21.png)


人には心理的にもパーソナルスペースがあります。
ここを侵すと磁石でいうＮ極同士のように、一気に離れてしまう。

## ３．１対１のベストプラクティス

きっと、これが理想ですね。
　　　![05_best.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/384185/9c231ce1-d98d-1a5e-4151-f165a2106e78.png)


## ４．複数人のケース

複数人になると＆が厳しくなります。注意しないといけないことは、
特定の個人に近づくと、近づかなかった方が良いくらい、＆が狭まる。

　　　![06_multi.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/384185/7249e582-ba64-2be1-c194-9b691d63f4d1.png)
　　　![07_multiWARN.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/384185/c28c24a5-e5b3-1fb2-4995-88794fd34f1e.png)



で、ベストはきっとこれ。めちゃくちゃ楽なはず。

　　　![08_MultiBEST.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/384185/1bdae779-e41e-162e-ac63-1126a600144a.png)


## ５．組織の関係は案外これ

組織で意外と多いのは、このように非接触なケースかと。

　　　![09_Unknown.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/384185/a932d66f-52b2-0cd8-a676-7f54493f3b04.png)


で、それを解消するためには、こういう人材が必要なんです。

　　　![10_Bridge.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/384185/d0154ec6-cbc1-d564-a06c-5be812663e54.png)


## ６．総括

何が言いたかったか。

かっこつけすぎずに自己開示をしていけば、
結構うまく物事進んでいくのでは？っていうことです。
ただ、それが無理な人もいるので、かっこつける人のために橋渡ししてあげよう。

肩の力を抜いて、楽しく人生やっていきたいです（笑）
Java Error Handlingの基礎 - catch は一番手前でしか拾われないという話

エラーをどこで拾うかはほんとに迷う。

subroutineの中でうかつにtry-catchしてしまうと、拾いたいところまで届かなかったりする。

javaも同じだった

# 届かない例

同じExceptionを多段なsubroutineでかけると、内側のsubroutineでしか拾えない。

```java
public class MyException {
	final private static int[] M = {1,2,3}; 
	public static void main(String[] args) {
		try {
			subroutine(M);
		}
		catch ( ArrayIndexOutOfBoundsException e ) {
		   System.out.println("[SECOND] catch : " + e.getMessage());
		}
	}

	public static void subroutine(int[] M) throws ArrayIndexOutOfBoundsException {
		try {
			System.out.println(M[4]);
		}
		catch ( ArrayIndexOutOfBoundsException e ) {
		   System.out.println("[FIRST] catch : " + e.getMessage());
		}
	}
}
```

## result
```ruby
[FIRST] catch : Index 4 out of bounds for length 3
```

# 届く例
内側のcatchの中で再度 throw させると、外側でも拾える。
throwするときは引数 e をいい感じにして渡す。eのままだとエラーになった。よくわかってない。

```java
public class MyException {
	final private static int[] M = {1,2,3}; 
	public static void main(String[] args) {
		try {
			subroutine(M);
		}
		catch ( ArrayIndexOutOfBoundsException e ) {
		   System.out.println("[SECOND] catch : " + e.getMessage());
		}
	}

	public static void subroutine(int[] M) throws ArrayIndexOutOfBoundsException {
		try {
			System.out.println(M[4]);
		}
		catch ( ArrayIndexOutOfBoundsException e ) {
		   System.out.println("[FIRST] catch : " + e.getMessage());
		   throw new ArrayIndexOutOfBoundsException(e.getMessage());
        <--- throwさせる
		}
	}
}
```

## result
```ruby
[FIRST] catch : Index 4 out of bounds for length 3
[SECOND] catch : Index 4 out of bounds for length 3
```

というわけで、何が言いたいかというと
- errorを拾うところはできるだけまとめたほうが見やすい
- けどそれぞれのmoduleの役割もあるので、責任範囲で区切るのも大事
- 区切るときに、安易に Exception/RUntimeException を拾っちゃうと外側まで届かない
- 内側ではできるだけ細かく、ちゃんとした xxException を拾ってかないといけない
- そのためには、何をしたら何のexceptionが出るのかしっかりわかってないといけない
- if & throw　するのがベストなんだろう
    - ( if == 0: throw new DivededByZeroException みたいな）


reference
http://math.hws.edu/javanotes/c8/s3.html

ここの最後のコードも、 if + throw で成り立ってる。そうしよう的なことを書いてる、と思うんだが、眠すぎてもう理解できないので寝る。

まあそんな感じのメモ
AWS CLI を入れたときにfishでパスを通すときに詰まったのでメモ

忘れないようにメモ

## 概要
自分の使用しているシェルはfishです。

[公式ドキュメント](https://docs.aws.amazon.com/cli/latest/userguide/install-macos.html#awscli-install-osx-path)にfishの対応が書いてなくて困ったのでメモ

## AWS CLIを導入
手順はドキュメントを見てください

```
$ pip3 install awscli --upgrade --user
```

## awscliがどこに入っているのか確認
```
$ pip3 show awscli
```
これにより、`/Library/Python/3.7/lib/python/site-packages`に入っていることを確認できた。


## パスの通し方 
`.config/fish/config.fish`に下記を記述した

```
set -x PATH $HOME/Library/Python/3.7/bin $PATH
```

## 参考文献
https://qiita.com/plum_shiga/items/5214510f9786898c987f
Echo middleware 実行順

## 概要

Echo の middleware の実行順が気になったので試した。

## コード

```go
func main() {
	e := echo.New()
	e.Use(middleware.Hoge()) // fmt.Println("Hoge")
	e.Use(middleware.Foo()) // fmt.Println("Foo")
	e.Use(middleware.Bar()) // fmt.Println("Bar")

	e.GET("/", func(c echo.Context) error {
		var err error
		defer func() {
			if err != nil {
				e.Logger.Errorf("%+v", err)
			}
		}()

		fmt.Println("Request recieved")
		return c.String(http.StatusOK, "Hello, World")
	})
	e.Logger.Fatal(e.Start(":8080"))
}

// 実行結果
// Hoge
// Foo
// Bar
// Request recieved
```

予想通り、 Use した順に実行された。
以上
変数で計算結果を保管

### 変数
- PHPの場合、変数名を`$`から始める必要がある
  - 変数は`$`から初めて、英語や英語_数字などで作成する
  - 例：`$abc`、`$abc_123`
     - `$合計` などの日本語も一応使えるけど基本的に使わない
- 記号や空白が含まれていたり、先頭が数字の場合は使えない
- 大文字小文字の設定は自由だけど、基本的にPHPの変数は小文字で書いたほうがいい
  - 変数名は小文字と大文字を完全区別するので、一部でも異なると「別の変数」と見なされてしまうので注意
  - 例えば全て小文字の場合、一部を大文字にすると別の変数となってしまう
- 変数は、最初に『代入』と言う操作を行う

```
<?php $sum = 100+1050+200; ?>
```
- 変数名(上記の場合は$sum)の次に`=`を書き、その後に記憶したい内容や、保管したい内容を記述する
- ルールはprintのパラメーターと同じで`'`(クォーテーション記号)を入れてあげるとそのまま文字列として記憶される
  - クォーテーション記号がなければ計算式として「計算結果」を代入してくれる
- 格納した変数を使いたい場合は`=`を使わず変数名だけを記述する
- 変数を使うメリット
  - 何度も同じ計算式を使う場合にわかりやすくなる
  - 計算式が何を意味しているのわかりやすくなる
オブジェク指向

### オブジェクト
- 関連する変数（値）と関数（動作）が一つにまとまり、そのまとまりに名前がついたもの。
  - 関連した変数や関数を「一つのオブジェクト内」で宣言することで、管理しやすくなる。
  - オブジェクトには「クラス」「インスタンス」と言う２つの側面がある。
- クラス
  - 設計図。オブジェクトを作るには、まずクラスを宣言する必要がある。
  - 設計図なので、どんな変数（値）でどんな関数（動作）にするのか考えて、クラス内部で宣言する。
  - 関連した変数や関数はこの時点（クラス）で決定。
- インスタンス
  - クラス（設計図）から生成された実体。モノ。
  - 設計図だけあっても関数を使うことができないので、クラスから実体を生成する。


- メモ

```
<?php
$today = new DateTime();
print($today -> format('G時 i分 s秒'));
?>
```

- $today と format は `->` で繋がっている
  - これは$todayと言うDateTimeメソッドの、インスタンスのメソッドを使っている
- formatメソッドの使い方
  - dateとだいたい同じ
  - ()の中のパラメーター（例の場合は時間）をそれぞれ求めてフォーマット化してくれるメソッド