OmniAICreator/Qiita-1.07M huggingface dataset:
バッファの移動を上下左右自由に行う

バッファの移動を上下左右自由に行いたかったので設定を編集しました。
ショートカットを追加します。

```console
~/.spacemacs
```

```lisp
(defun dotspacemacs/user-config ()
  "Configuration function for user code.
This function is called at the very end of Spacemacs initialization after
layers configuration.
This is the place where most of your configurations should be done. Unless it is
explicitly specified that a variable should be set before a package is loaded,
you should place your code here."
  (bind-keys*
   ;; move buffer
   ("C-t h" . windmove-left)
   ("C-t j" . windmove-down)
   ("C-t k" . windmove-up)
   ("C-t l" . windmove-right)
   ("C-t C-h" . windmove-left)
   ("C-t C-j" . windmove-down)
   ("C-t C-k" . windmove-up)
   ("C-t C-l" . windmove-right)
   )
  )
```

これで設定したキーバインド通りにショートカットが効き
上下左右のバッファ移動が可能になります。
[Mac]Visual Studio Code(VS Code)にJavaをインストールする

#はじめに
今回行った環境は以下の通り

```
OS：MacOS Catalina（バージョン 10.15.4）
Java：14
```

#Javaのインストール
拡張機能にて「Java Extension Pack」をインストールします。
VS Codeで以下のコマンドを実行し、拡張機能インストール画面を表示します。
「Command + Shift + x」

検索画面にて「java」を入力し、「Java Extension Pack」を選択してインストール
<img width="1136" alt="スクリーンショット 2020-06-01 22.06.44.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/209503/ec69d20a-9e64-29e5-2557-cb089034bddc.png">

インストールした結果、↓の画面が表示された場合は「手動でダウンロード」を選択

<img width="453" alt="スクリーンショット 2020-06-01 22.10.14.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/209503/54d4c87b-a118-c676-8ff3-05b4244a7aa5.png">

手動でダウンロードすると、↓インストール完了が表示されます。
<img width="453" alt="スクリーンショット 2020-06-01 22.11.58.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/209503/53138936-5cc6-b658-d524-b56911fda65d.png">

#JDKのインストール
以下のサイトからJDKをダウンロードし、インストール（今回はversion14）
https://www.oracle.com/java/technologies/javase-jdk14-downloads.html
<img width="1372" alt="スクリーンショット 2020-06-02 22.10.10.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/209503/64354938-816a-2891-c491-560045d28d0f.png">

#Pathを通す
Javaのパスが通ってない場合は、JAVA_HOMEの設定が必要です。
以下のコマンドをターミナルで実行し、現在のJAVA_HOMEを確認しましょう。

```
/usr/libexec/java_home
```

実行結果をコピーし、VS Codeの設定画面を開いて「javahome」を検索する。
<img width="701" alt="スクリーンショット 2020-06-02 22.23.30.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/209503/d2393a8d-1913-7412-e872-1d0ffbc2dd52.png">

「settings.json で編集」を選択し、以下「java.home」へ貼り付け
<img width="701" alt="スクリーンショット 2020-06-02 22.25.01.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/209503/887bddab-9116-7255-f078-1e50dbd82d50.png">

#動作確認
適当なサンプルコードを入力し、デバック実行
<img width="701" alt="スクリーンショット 2020-06-02 22.28.40.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/209503/e6b6e9e7-a7f5-dfdc-6153-bef4ec6f657e.png">
For文の中にFor文を入れる二重ループについて

最近JavaSilverを学習しているYuheiです。

問題を解いてたら、二重ループについて理解できない部分がありましたので、調べてみました。

結果は下記の通りです。


# 二重ループとは

別名多重ループとも言い、For文の中に更にFor文を入れて、２つのループにしている状態をいいます。

下記は、九九を表示するためのコードです。

```
public class KuKu {
    public static void main(String args[]) {
        for (int i = 1; i <= 9; i++) {
            for (int j = 1; j <= 9; j++) {
                System.out.print(i*j + " ");
            }
            System.out.println();
        }
    }
}
```
↑
これを実行すると、結果は下記のようになります。

```
1  2  3  4  5  6  7  8  9 
2  4  6  8 10 12 14 16 18 
3  6  9 12 15 18 21 24 27 
4  8 12 16 20 24 28 32 36 
5 10 15 20 25 30 35 40 45 
6 12 18 24 30 36 42 48 54 
7 14 21 28 35 42 49 56 63 
8 16 24 32 40 48 56 64 72 
9 18 27 36 45 54 63 72 81 
```

外側のループ：九九の段が、「1の段、2の段、・・・、5の段」と増えながら繰り返されます。

内側のループ：各段（外側のループ（i））の中で掛ける数が「×1、×2、・・・、×9」と増えながら繰り返されます。


これらをまとめると、普通の九九と同じく「1×1=1、1×2=2、・・・、5×9=45」の順で処理が行われています。

多重ループの基本事項になります。

フローチャートやプログラムで多重ループを見た時、処理のイメージを浮かべることができればOKです。

多重ループの理解は”慣れ”なので、多重ループの問題を何回も解いてみることが重要です。

以上です。
Webmention Receiver を実装してみた

[Webmention](https://www.w3.org/TR/webmention/) （[和訳](http://www.asahi-net.or.jp/~ax2s-kmtn/internet/link/REC-webmention-20170112.html)）への理解を深めるために、 Webmention を受信するサーバを実装してみた。



https://github.com/kyanny/webmention-receiver

具体的な実装コードは [server.rb](https://github.com/kyanny/webmention-receiver/blob/master/server.rb) を参照。



## 実装した部分

- [3.2 Receiving Webmentions](https://www.w3.org/TR/webmention/#h-receiving-webmentions) （[和訳](http://www.asahi-net.or.jp/~ax2s-kmtn/internet/link/REC-webmention-20170112.html#receiving-webmentions)）内の `MUST` と明記されている仕様
  - 3.2.1 Request Verification
  - 3.2.2 Webmention Verification
  - 3.2.3 Error Responses
- 受信した Webmention データのメモリ内への保存
- メモリ内に保存した Webmention データを JSON 形式で返却する API

## 実装していない部分

- `SHOULD`, `MAY` と明記されている仕様
  - 非同期処理による Webmention の検証
- 受信した Webmention データの永続的ストレージへの保存

## テスト方法

- [webmention-testpinger](https://github.com/voxpelli/node-webmention-testpinger)
  - 全ての Webmention ping を正常に処理した
- [Webmention Rocks!](https://webmention.rocks/) の [Receiver Test #1](https://webmention.rocks/receive/1), [Receiver Test #2](https://webmention.rocks/receive/2)
  - いずれもパスした

## 感想・考察

- `MUST` と明記されている仕様だけであれば、実装は難しくない
- 非同期処理による Webmention の検証を行うのも、 Sidekiq や Amazon SQS を使えばさほど難しくなさそう
- 送信者が Webmention リクエストのステータスを確認するページを用意するのは手間がかかりそう
  - 非同期処理の進行状況をモニタリングするダッシュボードのような機能を作ることになるので
- 実用的なものにするためには、相応のボリュームの実装が必要そう
  - 非同期処理のほかにもセキュリティ対策など
  - すでにプロダクション用途のサービスが存在するので、一般ユーザーの立場ではそれらを利用するのが現実的
  - 以下の二つは OSS なので実装も参照できる
    - https://webmention.io/ (https://github.com/aaronpk/webmention.io)
    - https://webmention.herokuapp.com/ (https://github.com/voxpelli/webpage-webmentions)
[CSS]ヘッダー・フッターの基本

#ヘッダー
ヘッダーは上部に固定することが多い
その際には、下記をセットで記述する。

```css:css
.header {
  position: fixed;
  width: 100%;
}

.header{
height: 60px;
width: 100%;
position: fixed; 
  z-index: 1;
}
```

・上部に固定
・横幅は画面いっぱい
・重なりの順序を一番手前に

上記と合わせて、コンテンツにて
下記を記載して回り込みを防ぐ。

padding-top: 60px;

※高さはヘッダーと同じに

#フッター
最下層に絶対位置固定

```:css
position: absolute;
bottom: 0;
```
【30秒以下で可能！】phpMyAdiminの表示を日本語に変えよう！

僕のように最近プログラミングを始めた人は、「英語」単語が多くて困りますよね。データベースをもっとわかりたいなと思いつつも、例えばphpMyAdiminは最初の段階では全て英語で書かれている...

そんなこともあって、「うわ、僕にはわからんな。一生理解できない」と思っていました。

ところが理解の助けとして、phpMyAdiminの表示を「日本語」にできることを発見しましたので、メモとして残しますね！

## phpMyAdiminの表示を日本語にするための手順

まずphpMyAdminを開きましょう。

開いたら、左上にある「ホーム」をクリック！

![phpmyadmin.1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/437473/3f0e944b-8f2f-d7ee-3445-855ead8edc54.png)

そしたら、言語を変えられる項目が出ます！

![phpmyadmin.2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/437473/cc28e3af-bf0f-39e7-add2-e8f03211c49f.png)

なんとたったこれだけ！簡単。

## まとめ

本当は英語のまま、スラスラと作業できた方がかっこいいですよね...
でも作業をスムーズにこなすためには、手段を問いません！
ぜひ活用してくださいね。
【GitHub】コードブロック中で「```」をエスケープする

# 遭遇した問題
`GitHub`のPRコメントのコードブロック内で「\`\`\`」と打とうとした所、コードブロックが2つできてしまい、1つのコードブロックになってくれませんでした。

>\`\`\`kotlin
>\`\`\`
>    ヒアドキュメント 
>\`\`\`
>\`\`\`

# 解決方法
下記のサンプルを参考に、外側を「\`\`\`\`」と4つに増やせば正常に機能しました。

- [Remarkable demo](https://jonschlinkert.github.io/remarkable/demo/#md64=eyJzb3VyY2UiOiJcbiMjIyBCYWNrdGlja3MgaW4gYmFja3RpY2tzIGV4YW1wbGVcblxuPiBVc2UgbW9yZSB0aGFuIDMgdG8gc3RhcnQgdGhlIGV4YW1wbGUsIHRoZW4gb25seSB1c2UgMyBpbnNpZGUgdGhlIGV4YW1wbGUuXG5cbmBgYGBcbnNvbWV0aGluZyBoZXJlXG5cbmBgYFxubW9yZSBzdHVmZlxuYGBgXG5cbmBgYGBcbiIsImRlZmF1bHRzIjp7Imh0bWwiOmZhbHNlLCJ4aHRtbE91dCI6ZmFsc2UsImJyZWFrcyI6ZmFsc2UsImxhbmdQcmVmaXgiOiJsYW5ndWFnZS0iLCJsaW5raWZ5Ijp0cnVlLCJ0eXBvZ3JhcGhlciI6dHJ1ZSwiX2hpZ2hsaWdodCI6dHJ1ZSwiX3N0cmljdCI6ZmFsc2UsIl92aWV3IjoiaHRtbCJ9fQ==)


>\`\`\`\`kotlin
>\`\`\`
>    ヒアドキュメント 
>\`\`\`
>\`\`\`\`

ただし、この書き方はQiitaでは機能しないようです。

# 参考にさせて頂いたissue
- [How to escape backticks in code block ? · Issue \#146 · jonschlinkert/remarkable](https://github.com/jonschlinkert/remarkable/issues/146)

# ところで
`Kotlin`のヒアドキュメントは`"""`で囲むのが正しかったです。
localhostで開発中にGoogle Chromeで「この接続はプライバシーが保護されません」が出たときの対処法【NET::ERR_CERT_INVALID】

ローカル環境（localhost）で開発中にGoogle Chromeで「この接続はプライバシーが保護されません」という表示が出たときの対処法です。
【NET::ERR_CERT_INVALID】

<img width="630" alt="スクリーンショット 2020-05-31 16.14.43.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/559347/4af06763-d4c5-b954-f944-7873fafb37ae.png">

## 詳細設定をクリックする
詳細設定をクリックすると下記のように詳細情報が表示されます。
<img width="630" alt="スクリーンショット 2020-05-31 16.15.24.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/559347/476a6ea4-a91e-0f26-d89d-4698d8547bbc.png">

## 詳細情報が表示された状態で【thisisunsafe】と打つ

詳細情報が表示された状態で、`thisisunsafe`とキーボードで打ちます。
そうすると、接続ができるようになります。

ローカル環境（localhost)でssl化したときに少しハマったのでまとめました。
スコープについてのメモ


def 〜　endの処理に対して、
処理外から渡したい数値が存在する場合、
発生する。

最初に渡したい変数は何かを宣言、
受け取る変数に、その渡したい変数を追記するだけ。


#[スコープ発生例] 

```ruby

def show_review
    line = "---------------------------"
    puts "ジャンル : #{genre}\n#{line}\n"
    puts "タイトル : #{title}\n#{line}\n"
    puts "感想 :\n#{impression}\n#{line}\n"
  end

genre = "aaa"
title = "qqq"
impression = "ddd"
 
review.show_review
```

①「review.show_review」の中の「genre」「title」「impression」に
　　値を渡す
②スコープでエラーが出る
③「review.show_review」に(genre,title,impression)を加える
④合わせて、渡される側も(genre,title,impression)を加える
⑤渡せる！！


##<正しい書き方>
```ruby
def show_review (genre,title,impression)←②受け取る側も追加
    line = "---------------------------"
    puts "ジャンル : #{genre}\n#{line}\n"
    puts "タイトル : #{title}\n#{line}\n"
    puts "感想 :\n#{impression}\n#{line}\n"
  end

genre = "aaa"
title = "qqq"
impression = "ddd" 
review.show_review(genre,title,impression) ←①渡したい項目を追加
```
database.ymlファイルの主な役割を２つ述べてください

使い方はわかるけど、言葉で説明する際に
整理しておくシリーズ。


・rake db:createのコマンドを実行した時に作成されるデータベースの名称を指定する。
・RailsアプリケーションがSQLサーバーにアクセスするときのソケットファイルの位置を指定する
AtCoder 生活　72日目

[前回](https://qiita.com/flandrescarlet237/items/8526af4f24ca81cd59ae)

#72日目
今日は茶色diffの問題を2問解きました。

|問題|難易度|自力で解けた|かかった時間|
|:-:|:-:|:-:|---|---|
|CODE FESTIVAL 2014決勝|C|✕|249分10秒|
|CODE FESTIVAL 2014 予選A|C|◯|21分3秒|

##[CODE FESTIVAL 2014決勝_C](https://atcoder.jp/contests/code-festival-2014-final/tasks/code_festival_final_c)

```c++

#include <bits/stdc++.h>
#define rep(i,n) for(int i = 0;i < (n);i++)
using namespace std;
using ll = long long;
using pii = pair<int,int>;

const int INF = 2e9;

ll f(ll k){
    ll ret = 0;
    ll pow = 1;
    ll k2 = k;
    while(k2 > 0){
        ret += (k2 % 10) * pow;
        pow *= k;
        k2 /= 10;
    }
    return ret;
}

int main(){
    ll a;
    cin >> a;
    for(ll k = 10;k <= 10000;k++){
        if(f(k) == a){
            cout << k << endl;
            return 0;
        }
    }
    cout << -1 << endl;
    return 0;
}

```

解くのにかかった時間：249分10秒
感想：N進法ということに気づくのに手間取ってしまった


##[CODE FESTIVAL 2014 予選A_C](https://atcoder.jp/contests/code-festival-2014-quala/tasks/code_festival_qualA_c)

```c++

#include <bits/stdc++.h>
#define rep(i,n) for(int i = 0;i < (n);i++)
using namespace std;
using ll = long long;
using pii = pair<int,int>;

const int INF = 2e9;

ll f(ll n){
    ll o = n/4;
    ll p = n/100;
    ll q = n/400;
    return (o-p+q);
}

int main(){
    ll a,b;
    cin >> a >> b;
    ll s = f(a);
    ll t = f(b);
    bool res = false;
    if(a%4 == 0) res = true;
    if(a%100 == 0) res = false;
    if(a%400 == 0) res = true;
    if(res) cout << t - s + 1 << endl;
  	else cout << t - s << endl;
}

```

解くのにかかった時間：21分3秒
考え方:aがうるう年かどうかで計算方法を分ける事を考えて進めた

###最後に
茶色にかなり解けるものと全然解けないものがあるのが辛い
【Rails】gemのgoogle-cloud-visionでv1.0が出たので対応してみた

[以前に書いた記事](https://qiita.com/west2538/items/e94db445e22e6151718d)でコードを書き換える必要があったので対応してみました。

gem `google-cloud-vision`をv0.x系からv1.0.0にアップデートしたら要注意です。

基本的に

**Migrating to google-cloud-vision 1.0**
https://github.com/googleapis/google-cloud-ruby/blob/master/google-cloud-vision/MIGRATING.md

に書いてあるとおりなのですが`#safe_search_detection`については[こちら](https://googleapis.dev/ruby/google-cloud-vision-v1/latest/Google/Cloud/Vision/V1/ImageAnnotator/Client.html#safe_search_detection-instance_method)のほうがわかりやすかったです。

```ruby
    require "google/cloud/vision"
    image_annotator = Google::Cloud::Vision::ImageAnnotator.new
```
を

```ruby
    require "google/cloud/vision/v1"
    image_annotator = Google::Cloud::Vision::V1::ImageAnnotator::Client.new
```
に書き換えました。

Google Cloud Visionについては以前にも破壊的なバージョンアップがあったような...
複数の docker-compose 間で共通の Network を使い通信できるようにする

## 目的
docker-compose で起動したコンテナは共通の Network 上にあるのでお互いに通信が可能だが、起動したいコンテナの数が増えてくると、1枚の docker-compose が肥大してしまう。
管理のために docker-compose を分けたいが、お互いに通信はできるようにしたい。
また、各コンテナには固定IPアドレスを付与したい。

## 共有する Docker ネットワークを作成する
ここでは shared-nw と名付けています。
固定IPアドレスを付与させるため、subnet も合わせて定義させています。
※docker-compose.yml のバージョンが3以上になると、gateway は定義できなかったように思います（未確認）。

```
$ docker network create shared-nw --subnet=172.30.0.0/16 --gateway=172.30.0.254
$ docker network ls
NETWORK ID          NAME            DRIVER              SCOPE
53bd0dc361fe        shared-nw       bridge              local
```

## docker-compose.yml 内で共有ネットワークを使用するように宣言する
### 1つ目
1. コンテナ(services:)を定義する箇所で networks > shared-nw > ipv4_address と固定IPアドレスを付与します。
2. networks: を services: と同階層に定義し、使用するネットワーク(shared-nw) を宣言します。また、external: true とすることで、この docker-compose.yml 内ではなく、外部で定義されているネットワークを探すように指定します。

```
(省略)
services:
  {サービス名}:
    networks:
      shared-nw:
        ipv4_address: 172.30.0.2
(省略)
networks:
  shared-nw:
    external: true
```

### 2つ目
1つ目と同様に宣言していきます。
固定IPアドレスに1つ目とは違うアドレスを設定しています。

```
(省略)
services:
  {サービス名}:
    networks:
      shared-nw:
        ipv4_address: 172.30.1.2
(省略)
networks:
  shared-nw:
    external: true
```

両方の docker-compose を起動した上で通信確認してみます。
inet addr:172.30.1.2 のコンテナから、172.30.0.2 のコンテナに対して PING が通ることが確認できました。

```
$ docker exec spark-master101 ifconfig | grep "inet addr"
          inet addr:172.30.1.2  Bcast:172.30.255.255  Mask:255.255.0.0
          inet addr:127.0.0.1  Mask:255.0.0.0
$ docker exec spark-master101 ping 172.30.0.2
PING 172.30.0.2 (172.30.0.2): 56 data bytes
64 bytes from 172.30.0.2: seq=0 ttl=64 time=0.168 ms
64 bytes from 172.30.0.2: seq=1 ttl=64 time=0.111 ms
64 bytes from 172.30.0.2: seq=2 ttl=64 time=0.099 ms
```

## 結論
予め Docker network を作成しておく必要はありますが、docker-compose を分けて作成
しておけるメリットがあるので、ローカルで個人で管理する分には問題なさそうです。
Gitの使い方

gitの使い方

まずはclone
ネットからローカルに落とす

```
git clone リポジトリ
```

ブランチ作成

```
git branch ブランチ名
```

ブランチ切り替え

```
git checkout ブランチ名
```

変更したふぁいるをadd

```
git add 変更したファイル
```

変更したふぁいるをcommit

```
git commit -m 変更したファイル
```

ローカルのものをリモートにあげる（ブランチがリモートに無いとき）

```
git push --set-upstream origin ブランチ名
```

この後プルリクを送る


リモートにあるブランチをとってきて適用

```
git fetch && git checkout ブランチ名
```

gitの状況を確認する

```
git stutas
```

addを取り消す

```
 git reset ファイル名
```
ファイルを残したままgit上からファイル削除

```
git rm --cached　ファイル名
```
Java → Spring → Spring Boot

## この記事を書く理由 
javaを学習して、いざFrameworkを勉強するにあたっていろいろな壁にぶち当たっている私が経験した振り返りのための日記のようなものであり、見てくださった方の手助けになればと思って記していきます！

## 本環境
>- OS : MacOS
>- 言語 : Java8 (openjdk1.8.0)
>- Framework : Spring Boot

##　目次
- Javaの基礎学習はすごく大事であること
- Spring Frameworkは素晴らしいこと
- Spring Bootは素晴らしいこと

###**Javaの基礎学習はすごく大事！**
 大事：他のプログラミング言語もすごく参考になる考え方であると思う
 1. 基本的な環境
 2. どうゆう言語？
 3. 基本的な書き方
 4. すごく重要な考え方(オブジェクト思考)
 5. 他の機能を使える
gitでよく使うコマンド一覧

メモ用です。

```
#対象フォルダにgitをセット
git init

#今あるブランチの確認
git branch

#hogeのブランチに移る
git checkout hoge

#ブランチのマージ
git merge マージ先 マージさせるブランチ

#ブランチの削除
git branch -d 削除したいブランチ名

#gitのレポジトリに変更したファイルを追加
git add ファイル名

#新規作成、削除、変更全てを反映
git add -A

#新しく作られたファイルは反映せず、前のバージョンにあった変更のみ
git add -u

#新規作成と変更のみ反映で削除は反映しない
git add .

#現在のリモートレポジトリを確認
git remote -v

#gitのログを確認
git log

#masterブランチに戻るコマンドです。
git checkout master

#加えられたすべての変更を元に戻す新しいコミットを生成し、それを現在のブランチに適用するコマンドです。
git revert

#リモートレポジトリのmasterブランチにpushする。
git push origin master
```
mockClear()とmockReset()


以前`mockClear()`と`mockReset()`のリセットされている情報の違いによるハマりがあったので、メモ :pencil2:


#### それぞれの特徴

以下のような関数をテストするとする


```ts
// テストしたい関数
function main(str?: string) {
 user.get();

 // 引数があるときだけもう一度user.getを呼ぶ
 if(str) {
  user.get();
 }
}


// モック対象
function get(){
  // なにか処理
}

```



##### mockClear()
`mockFn.mock.calls` と `mockFn.mock.instances`の配列に格納されている全ての情報をリセット

```ts

const userSpy = jest.spyOn(user, 'get');
beforeEach(() => {
  userSpy.mockReturnValue(true);
}) ;
afterEach(() => {
  userSpy.mockClear();
})

test('1回呼び出されていることを確認', () => {
  main(); // テスト対象の関数
  userSpy.toHaveBeenCalledTimes(1);
});

test('引数が設定されている場合は2回呼び出されていることを確認', () => {
  main('OK'); // テスト対象の関数(引数あり)
  userSpy.toHaveBeenCalledTimes(2);  
})

```
もし、afterEach()でmockClear()をしていない場合は、1度目のテストの呼び出し回数を引き継ぐことになってしまうので期待した結果が得られなくなる
テストが実行されるタイミングにもよるけれど、上から順に実行された場合は
userSpyの呼び出し回数は3回になり、テスト失敗になる


##### mockReset()
mockReset()も`mockFn.mock.calls` と `mockFn.mock.instances`の配列に格納されている全ての情報をリセット
さらにモックされた戻り値、実装も削除する

たとえば…

```ts
const userSpy = jest.spyOn(user, 'get');
beforeEach(() => {
  userSpy.mockReturnValueOnce(true).mockReturnValueOnce(false); // １度目呼ばれたときと2度目に呼ばれたときと戻り値が異なる状況にしたい
}) ;
afterEach(() => {
  // userSpy.mockClear();
  userSpy.mockReset();
})

test('1回呼び出されていることを確認', () => {
  main(); // テスト対象の関数
  userSpy.toHaveBeenCalledTimes(1);
  // userSpyの戻り値 1度目…true
});

test('引数にOKが渡されている場合は2回呼び出されていることを確認', () => {
  main('OK');
  userSpy.toHaveBeenCalledTimes(2);
  //  userSpyの戻り値 1度目…true, 2度目…false
})

```

afterEach()でmockReset()ではなく、mockClear()をしていた場合、テストの実行順も影響するが
1つ目に書かれているテストが実行されたあとに、2つ目のテストが実行されると
userSpyの戻り値は `1度目…false, 2度目…true` となり、期待した結果でなくなる
afterEach()でクリアしているつもりだったけれど、mockClear()ではモックされた戻り値・実装は
リセットされないため、上記のような結果になってしまう


リセットされる内容を考慮しながら使う必要がある


##### おまけのmockRestore()
`mockRestore()`というのもあって
モック関数を利用していたものを本物のモジュールに戻したい時に便利
`jest.spyOn()`でモックが作成されたときにのみ使える
`jest.fn()`でモックしていた場合は、`mockRestore()`は使えないので注意
Spek FrameworkをアップデートしたらTestができなくなった

Spek Frameworkをアップデートしたらエラーが出て、困ったので、その対処を残します。

# エラー内容（Spek Framework 2.0.11-IJ2019.2）

バージョンを上げたら以下のようなエラーがでた（以前のバーションだと出なかった）

```
io/mockk/proxy/MockKAgentFactory
java.lang.NoClassDefFoundError: io/mockk/proxy/MockKAgentFactory
...

java.lang.NoClassDefFoundError: Could not initialize class io.mockk.impl.JvmMockKGateway
...
```

# 対処
根本的な問題の解決にはなっていないが、一時的な対処として以前のバージョンに戻してみた。

## Step1
事前に、Android StudioからSpek FrameworkをUninstallしてください。
まず、[Spek Framework](https://plugins.jetbrains.com/plugin/10915-spek-framework/versions)のページにて、赤丸のバージョンをダウンロードしてください。

<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/289190/fc4610b0-94c2-82e9-54e5-2def6ad60a06.png">

## Step2
Android StudioのPreferencesの`Plugin`を開き、歯車アイコンをクリックして、`Install Plugin from Disk`を選択する。
そして、Step1でダウンロードしたZipファイルを選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/289190/06c6c016-89e8-5431-b675-40686af12948.png)

## Step3
Step2を行うと、`Plugin`に以下のように表示されるので、インストールしてください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/289190/6ea96220-4d48-07c3-4665-6593dbf79db6.png)


# おわりに
なぜエラーが出るのかはわかっていません。
個人的に調べてますが、どなたか知っていたら教えて下さい。
【MySQL】条件によってVIEWの表示結果を分岐する ～ case when ～

条件によってVIEWの表示結果を分岐させる書き方のサンプル集です。

## 環境

- OS：Windows10
- RDBMS：MySQL5.7

## case whenサンプル

### 1. 条件によって表示結果を分岐する

合計得点に応じて、成績表記を分岐します。
テーブルとその関係性は以下の通り。
※実際にはこんなテーブルはないと思いますが、サンプルのためご容赦を。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356958/8a992fbb-220f-8f75-3eae-255bb17ae337.png)

``` sql:
create view score_reports
as select
sr.*,
case 
when sr.total_score >= 85 then '優'
when sr.total_score >= 70 then '良'
when sr.total_score >= 60 then '可'
else '不可' end as grade
from 
(select
st.student_name,
su.subject_name,
sc.score,
(select sum(score) from scores group by student_id and test_month) as total_score
from students st 
left outer join scores sc on st.student_id = sc.student_id
cross join subjects su) as sr;

```

### 2. 結果の有無によって表示結果を分岐する

対象が存在すれば1、なければ0を表示させます。
以下は、とあるユーザーの対象店舗に対するブックマークの有無になります。
テーブルとその関係性は以下の通り。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356958/7ed89535-580d-23f7-1ddb-75d262b46db9.png)

``` sql:
create view shop_informations
as select
si.*,
case when exists (select * from bookmarks b where b.shop_id = si.shop_id and b.user_id = si.user_id) then 1 else 0 end as is_bookmarked
from
(select
s.shop_id,
s.shop_name,
u.user_id
from shops s cross join users u) as si;
```

## 終わりに
case式を使えば、アプリケーションの実装をシンプル＆わかりやすくできそうですね。
DB負荷の考慮は必要ですが、うまく使っていきたいと思います。

## 参考
- [CASE式のススメ | Mick's Page](http://mickindex.sakura.ne.jp/database/db_case.html)
- [【SQL】サブクエリはWTIH句が最強。可読性こそ現場での正義。 | sampling2x](https://sampling2x.com/2019/03/25/sql-with/)
- [合計を求める (SUM) | MySQL関数リファレンス](http://db.yulib.com/mysql/000027.html)
「14日で作る量子コンピュータ」を読んでみる。3日目

# はじめに
　今回は重ね合わせの原理と、電子波束についてまとめる。

# 3 電子波束の観察
## 重ね合わせの原理
　重ね合わせの原理は、シュレディンガー方程式を満たす複数の解を、足し合わせてできる関数もまたシュレディンガー方程式の解となっていると言う原理です。例えば以下のようなある分布にしたがって、$\psi_k$を重ね合わせた波動関数を用意する。

$$
\psi(x,t)=\int_{-\infty}^{\infty}a(k)\varphi_k(x)e^{-i\omega(k)t}dk=\int_{-\infty}^{\infty}a(k)e^{ikx-i\omega(k)t}dk
$$

　これをシュレディンガー方程式に代入してみる、この時自由空間なのでポテンシャルは0したがって

$$
i\hbar\frac{\partial}{\partial t}\int_{-\infty}^{\infty}a(k) e^{ikx-i\omega(k)t}dk=\frac{\hbar^2}{2m}\frac{\partial^2}{\partial x^2}\int_{-\infty}^{\infty}a(k)e^{ikx-i\omega(k)t}dk
$$

$$
\int_{-\infty}^{\infty}a(k)\hbar \omega(k) e^{ikx-i\omega(k)t}dk=\int_{-\infty}^{\infty}a(k)\frac{\hbar^2k^2}{2m}e^{ikx-i\omega(k)t}dk
$$

$$
\int_{-\infty}^{\infty}a(k)\left[\hbar \omega(k)-\frac{\hbar^2 k^2}{2m}\right] e^{ikx-i\omega(k)t}dk=0
$$

全ての位置と時間にかかわらず左辺はゼロになる時重ね合わせの原理は成り立つことになるので、括弧の中身がゼロになる条件について調べると

$$
\omega(k)=\frac{\hbar k^2}{2m}
$$

これは$\omega$自体の定義と同じなので、常に成り立つ。つまり常に重ね合わせの原理が成り立つことが示された。

## 3.2 電子波束の観察
　$a(k)$はどのような分布でも良いので、適当な定数$k_0$を中心とするガウス分布とするとa(k)は

$$
a(k)=e^{-(\frac{k-k_0}{2\sigma})^2}
$$

　この時の波動関数をプロットしてみる。


### 3.2.1 定数
　ここで新たに必要となる定数は

```python
# 空間の分割数
NX = 500
# 空間分割サイズ
dx = 1.0e-9
# 計算区間
x_min = -10.0 * dx
x_max = 10.0 * dx
# 重ね合わせる数
NK = 200
# kの偏差
sigma = math.sqrt(math.log(2.0)) * 1.0e9
# kの分割
dk = 20.0 / NK
# 波束の中心エネルギー
E0 = 10.0 * eV
# 波束の中心
k0 = math.sqrt(2.0 * me * E0 / hbar ** 2)
omega0 = hbar / (2.0 * me) * k0 ** 2
# 計算時間の幅
ts = -50
te = 50
# 時間間隔
dt = 1.0e-16
# 虚数単位
I = 1.0j
```

### 3.2.2 関数の定義
　プロットを作るに当たって必要なのは、ある時点tにおけるグラフの配列を出力する関数が必要なので、

```python
def dist_t(xl, t):
    psi_real = []
    psi_imag = []
    psi_abs = []
    for x in xl:
        # スケーリング
        psi_c = psi(x, t) * dx * dk / 10.0
        psi_real.append(psi_c.real)
        psi_imag.append(psi_c.imag)
        psi_abs.append(abs(psi_c))
    return psi_real, psi_imag, psi_abs
```

　そして、(x,t)が与えられた時の確率分布を出力する関数psiを定義する。

```python
def psi(x, t):
    psi_sum = 0.0 + 0.0j
    for kn in range(NK):
        # 定数を取得
        k = k0 + dk * (kn - NK/2)
        omega = hbar / (2.0 * me) * k ** 2
        # 重ね合わせ
        psi_sum += cmath.exp(I * (k * x - omega * t)) * cmath.exp(-((k - k0) / (2.0 * sigma)) ** 2)
    return psi_sum
```

### 3.2.3 アニメーションのプロット
　これらを用いてプロットを行う。

```python
xl = np.linspace(x_min, x_max, NX)
# アニメーション作成用の配列
ims = []
fig1 = plt.figure(figsize=(10, 6))

for t in range(ts, te + 1):
    t_real = t * dt
    psi_real, psi_imag, psi_abs = dist_t(xl * dx, t)
    # コマの描写
    img = plt.plot(xl, psi_real, 'red')
    img += plt.plot(xl, psi_imag, 'green')
    img += plt.plot(xl, psi_abs, 'blue')
    # コマの追加
    ims.append(img)

# グラフの描画
plt.title("Gaussian wave packet(Spatial distribution)")
plt.xlabel("Position[nm]", fontsize=16)
plt.ylabel("Probability amplitude", fontsize=16)
# 描画範囲
plt.xlim([-10.0, 10.0])
plt.ylim([-0.3, 0.3])
# アニメーション生成
ani = animation.ArtistAnimation(fig1, ims, fontsize=16)
ani.save("g_wave_packet.html", writer=animation.HTMLWriter())

plt.show()
```

## 3.3 出来上がったアニメーション

　↓が出来上がった動画。時間が立つほど分布の幅が広がっているのが観察できる。
![g_wave_packet.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179010/d8c75b32-e636-5588-06d1-39dd704ee01f.gif)
Lubuntu 18.04で、ゴミ箱が使えないときの対処法。

数ヶ月前に、私はWindowsをきっぱりやめて、Lubuntu 18.04に移行したのであるが、そのとき、何故かゴミ箱が使えなかったので、当時の対処法をここに記述する。
#現象
ファイルをゴミ箱に移動しようとすると、何故かエラーが出て(肝心のエラーの内容をメモするのを忘れてしまった。)ゴミ箱にファイルを移動できない現象であった。
#至って簡単だった対処法
対処法は至って簡単だったのである。それは、rootでゴミ箱フォルダを消して、通常の権限でゴミ箱フォルダを再度作成するというものである。

###root権限で、ファイルマネージャーを開く
通常、ゴミ箱のディレクトリは、"~/.local/share" にあるため、そこをまずは開く。Lubuntuの場合、標準のファイルマネージャはPCManFMであるため、以下のようにすればよいだろう。

```shell
sudo pcmanfm ~/.local/share
``` 

###Trashフォルダを削除する。
そこには、「Trash」フォルダがある。それが問題のゴミ箱フォルダである。そのフォルダを削除する。このとき、ゴミ箱は正常に機能していないため、Shiftキーを押しながら、Deleteキーを押すことで、完全に削除できるため、この方法で完全削除する。

###Trashフォルダーを作り直す。
今度は、通常の権限で "~/.local/share" ディレクトリに移動する。
移動できたら、そこに「Trash」という名前のフォルダを作成する。これで終わり。

###動作するか試す。
一応一旦ログアウトし、再度ログインして、適当なファイルをゴミ箱に入れてみよう。正常に動いていれば、そこにデータがあり、ゴミ箱も空にできるはずだ。
Gitを使ったチーム開発のために【2020年6月現在】

初心者の初心者である僕が、Gitを使えるようになるためによく見た動画は以下の3つです。これらを見ながら、実際に手を動かすのがとっても効果的です！

## まずは基本を抑えよう！

https://www.youtube.com/watch?v=i1L3A0SLDyg&t=22s

https://www.youtube.com/watch?v=cdz-cs_kYto

https://www.youtube.com/watch?v=JispFS6zeDw&t=900s

https://www.youtube.com/watch?v=EjSgD1xb6zw

## まとめ

これらを実践すればGitの基本的なことは、わかりますよ。最近はYouTubeで駆け出しエンジニア用の有益な動画がたくさんあるので、助かりますね。

とりわけプログラミングは文字よりも、図や写真、動画がぴったりです。
homebrewを使ってPHPのバージョンアップグレード

# 概要
homebrewを使ってPHPのバージョンアップグレードを行います。
php7.2系　→　php7.3系

##homebrewのインストール

[Homebrew](https://brew.sh/index_ja)のインストールがまだの方は、以下の記事を参考に導入をおこなってください。

[MacでLaravel開発環境構築 -Qiita](https://qiita.com/gongyro/items/a87d1417f5299beb22e4)

##手順
現在のバージョンを確認します。

```sh
$ php -v
PHP 7.2.30 (cli) (built: Apr 23 2020 01:23:39) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.2.0, Copyright (c) 1998-2018 Zend Technologies
    with Zend OPcache v7.2.30, Copyright (c) 1999-2018, by Zend Technologies
```

現在バージョンはPHP 7.2.30であることが確認できました。

続いて```brew search```コマンドでインストール可能なPHPのバージョンを確認します。

```sh
$ brew search php@7
==> Formulae
php@7.2 ✔　　　php@7.3　　　php@7.4
```

現在インストールされているバージョンの横にチェックマークがついています。

```brew install```コマンドでphp@7.3をインストールしましょう。

```
brew install php@7.3
```

これでphp@7.3をインストールすることができました。

続いてPATHを通す作業をします。
さきほどのインストール実行文の中に、PATHをまだ通してなかったら以下のコマンドを実行してくださいと書いてあります。

```
If you need to have php@7.3 first in your PATH run:
  echo 'export PATH="/usr/local/opt/php@7.3/bin:$PATH"' >> ~/.bash_profile
  echo 'export PATH="/usr/local/opt/php@7.3/sbin:$PATH"' >> ~/.bash_profile
```

これをこのままコピー＆ペーストして実行します。

```
$ echo 'export PATH="/usr/local/opt/php@7.3/bin:$PATH"' >> ~/.bash_profile
```

```
$ echo 'export PATH="/usr/local/opt/openldap/sbin:$PATH"' >> ~/.bash_profile
```

こちらも実行文の中に書かれているのですが、
PHP を自動起動するよう設定をしてから再起動すればphp@7.3になるとのことです。

```
To have launchd start php@7.3 now and restart at login:
  brew services start php@7.3
Or, if you don't want/need a background service you can just run:
  php-fpm
```

以下のコマンドを実行します。

```
$ brew services start php
```

実行後、ターミナルアプリを開き直して　```$ php -v```　でバージョンを確認

```
$ php -v
PHP 7.3.17 (cli) (built: Apr 29 2020 17:27:16) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.3.17, Copyright (c) 1998-2018 Zend Technologies
    with Zend OPcache v7.3.17, Copyright (c) 1999-2018, by Zend Technologies
```

無事 php@7.2系 から php@7.3系 にバージョンアップすることができました。

以上でhomebrewを使ってPHPのバージョンアップグレードは終了です。
お疲れ様でした。
DockerでWebアプリ環境構築

#はじめに
本記事は動画( https://youtu.be/vY2z-fOOh6s )で説明に使用している
スライドを記事化したものです。動画と合わせて御覧ください。
[![vY2z-fOOh6s](http://img.youtube.com/vi/vY2z-fOOh6s/0.jpg)](http://www.youtube.com/watch?v=vY2z-fOOh6s)

※記事化する際に補足説明を加筆しており、内容は動画のスライドと異なります。
※本記事の内容は2020年3月時点の内容となります。OSやミドルウェア、Dockerのバージョンが異なることで記載通りの内容で完了しない場合があります。

---

#構築する環境の構成
 - O   S 　： Cent OS 7.7
 - Webサービス　： Apache 2.4.6
 - DBサービス    　：MariaDB 10.4.6
 - Webアプリ言語：PHP 7.3.x

---

#OSの準備
[前回の動画: https://www.youtube.com/watch?v=oT-GSZD8bE4] (https://www.youtube.com/watch?v=oT-GSZD8bE4 )
	前回の動画の概要：Dokcerインストール、CentOSのインストール。
 1. コンテナ起動

```
	dos > docker run --privileged -d -p 22:22 -p 80:80 -p 8080:8080 -p 443:443 --name [作成コンテナ名] [イメージ名] /sbin/init
	dos > docker exec -it [コンテナ名] /bin/bash
	コンテナ > yum update
```

 2. ユーザの追加

```
root > useradd [ユーザ名]
root > passwd [ユーザ名]
```

 3. SSHインストールと接続！

```
root > yum install openssh-server
root > systemctl enable sshd.service
root > systemctl start sshd.service
```

接続はTeraTermをインストールして接続。

---

#Webサービスの準備
1. Apacheをインストール

```
root > yum install httpd
```
※CentOS標準のapacheをインストール

---

#DBサービスの準備
1. MariaDBリポジトリの追加

```
root > curl -sS https://downloads.mariadb.com/MariaDB/mariadb_repo_setup |  bash
```

2.  MariaDBのインストール

```
root > yum install MariaDB-server

※MariaDBパッケージにアップデートがある場合は
root >  yum update MariaDB-server
```

3. DBサーバの設定

```
root > vi /etc/my.ini/
```

4. サーバ自動起動の設定とサーバ起動

```
root > systemctl enable mariadb
root > systemctl start  mariadb
```

5. ユーザの設定

```
root > mysql
mysql > GRANT ALL PRIVILEGES ON *.* TO 'ユーザー名'@'ホスト名' IDENTIFIED BY 'パスワード' WITH GRANT OPTION;
mysql > FLUSH PRIVILEGES;
```

---

#Webアプリ言語のインストール
1. リポジトリの追加

```
> yum -y install http://rpms.famillecollet.com/enterprise/remi-release-7.rpm
```

2.  バージョンの確認

```
> yum info --enablerepo=remi,remi-php73 php php-mbstring php-xml php-xmlrpc php-gd php-pdo php-pecl-mcrypt php-mysqlnd php-pecl-mysql
```

3. PHPインストール

```
> yum -y install --enablerepo=remi,remi-php73 php php-mbstring php-xml php-xmlrpc php-gd php-pdo php-pecl-mcrypt php-mysqlnd php-pecl-mysql
```

4. PHPのインストール確認

```
> php -v
```
---

#Webサービスの設定
1. ドキュメントルートの設定

```
root > mkdir /var/www/webapp
root > chown takemi:takemi webapp
root > vi /etc/group
```

takemi: x :1000: 	→	takemi : x : 1000 : apache
※takemiはadduser作成した一般ユーザです。adduserしたタイミングでユーザと同名のグループも作成されます。

```
root > systemctl restart httpd
user > vi /var/www/webapp/index.html
```

```index.html
<html>
	<head>
		<title>Takemi Index</title>
	</head>
	<body>
		<div>Test Page</div>
	</body>
</html>
```

```
root > vi /etc/httpd/conf/httpd.conf
```

``` httpd.conf
		DocumentRoot=/var/www/html		→	 DocumentRoot=/var/www/webapp
		<Directory “/var/www/html”>		→	<Directory “/var/www/webapp”>
		Options	Indexes FollowSymLinks		→	Options	Indexes FollowSymLinks	ExecCGI
		AllowOverride None			→	AllowOverride All
````

2. 設定の確認
	ブラウザでhttp://<コンテナのIP>にアクセスする	


2. PHPの動作確認
	ブラウザでhttp://<コンテナのIP>にアクセスする

3. PHPの動作確認

```
user > vi /var/www/webapp/info.php
```

```info.php
<?php phpinfo();
```

ブラウザで http://<コンテナのIP>/info.php にアクセスする。
  phpinfo()の内容が表示される。

---

以上です！
これでHTMLもPHPも動作し、Webアプリの環境が整いました！
おつかれさまでした～
[BEM]マークアップの仕分けルール※自分用メモ

以下のイメージでつけていく。

■Block header, footer, main, article, section, aside, div

■Element h, p, span, img, a, ul, ol, li, dl, dt, dd, figure, divなど

 注意1点目
div要素は、Block、Elementとどちらにもなりえる

注意2点目
dl要素、ul要素、ol要素は、Block、Elementどちらかも
あり得る時がある
【VMware】HorizonViewのクローン方式の種類3つ

# はじめに
現在、業務でVMware Horizonを扱っています。
最近、VMware Horizonのクローン方式について学んだので、こちらの記事にアウトプットしていきたいと思います。

# クローン方式

## フルクローン

マスターとなるOSイメージ(マスターOS)を元に仮想マシンの台数分クローンを作る方式。
**(vSphere上で実施する通常のクローン)**

**特徴**

- 作成したマスタOSと完全に同じ構成で展開
- ユーザー個別設定の管理に伴い、仮想マシンの運用管理が煩雑になる
- ユーザー情報をVMに保持

![フルクローン.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/636476/1af13945-4652-b0dc-68e7-9ac87d16eed0.jpeg)


## リンククローン

OS部分などの共通部分は全員で共有し、個人の設定や変更は差分として持つ方式

**特徴**

- ユーザー情報とクローン元VMを別々にバックアップ
- ユーザーデータを残し、全仮想デスクトップのイメージを一度に入替え可能
- OSやアプリのパッチ配布の効率化が可能
- 全ての仮想デスクトップを一括管理可能

![リンククローン.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/636476/ed97b70b-081d-d64f-a5d5-46f4e723138c.jpeg)


## インスタントクローン

ESXiホストのメモリ上に高速にクローンを作成する技術。
この技術を**「VMFork」**という。

※コンテナ技術のdockerに近い。


**特徴**

- 親仮想マシンの静止点(スナップショット)を取り、メモリ上で子仮想マシンとしてコピー(クローン)を作成
- 子仮想マシンは親仮想マシンのメモリとディスクを共有
- **30台の仮想デスクトップをわずか2分以内で展開可能**

![インスタントクローン.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/636476/cf1b389e-7b35-d982-9ac1-5d49f91bb386.jpeg)

# まとめ

|  方式  |  内容  |
| ---- | ---- |
|  フルクローン  |  クローン元VMを丸ごとコピーする方式  |
|  リンククローン  | クローン元VMとユーザー情報をリンクさせて展開する方式   |
|  インスタントクローン  |  ESXiホストのメモリ上に高速にクローンを作成する技術  |

# 参考記事
[「リンククローン×流動割り当て」方式とは？VDIの各方式とメリット・デメリット](https://ddreams.docomo-sys.co.jp/sworksquare/column/detail13.html)

[新卒 2 年目 SE が贈る 仮想デスクトップのキソ！・ 第 3 回 ～仮想マシンの作成　プールの作成　～](https://blogs.vmware.com/jp-euc/2015/05/euc_kiso03.html)

[VDIバックアップ講座～VMware View版～【応用編】](https://www.networld.co.jp/arcserve/sol_vdi02.htm)
【IE11】先頭にハイフン2つのclass名はCSSが効かない

表題の通りです。

class名の先頭にハイフンはひとつまで。
マルチクラスでハイフン2つ指定すると、モダンブラウザでは指定どおり表示されますが、
IEでは無効なので、ご注意ください。

##NG class名🙅

先頭にハイフン2つですと、IEでCSSが効きません。

```CSS:css
<div class="hoge --fuga">
```

##OK class名🙆🏻‍♂️

先頭にアンダースコア（_）、ハイフン1つ（-）ですとIEでバッチリCSSが効きます。

```CSS:css
<div class="hoge -fuga">

<div class="hoge _fuga">
```
##CSS仕様について

W3CによるとIEの動作の方が正しいようでした。知らなかったです。

>識別子は、数字、2つのハイフン、ハイフンの直後の数字で開始できない。

構文と基本データ型
https://momdo.github.io/css2/syndata.html#value-def-identifier
Sapperで npm run dev がコケる

Sapperというフレームワークで遊んでいたところ、ある日突然 `npm run dev` が起動できなくなっていて詰まりました。
（補足｜Svelteに対するSapperはReactに対するNextみたいな位置付け）

## tl;dr
nodeのバージョンが10以降であればコケませんが、バージョン8などに切り替わっているとと以下のようなエラーが出ます。

> SyntaxError: Invalid regular expression: /\p{Letter}/: Invalid escape. 

とりあえずこのエラーが出ている場合は、

### すぐにnodeのバージョンを確認
```bash
node -v
```
### バージョンが10以降でなければバージョンを上げる
例えばnというバージョン管理ツールをを使う場合は

```bash
brew  install n
n 10.14.0
```
を実行してください。
nodebrewなど他のnode管理ツールを使っている場合はそれを使ってバージョンを変更しましょう。

最後にもう一度

```bash
node -v
```

でバージョンが10以上であることを確認して、対応完了です。
sapperアプリのディレクトリでサーバー起動しましょう。

```bash
npm run dev
```

---

初歩的っぽいけどエラー文がヒントにならないのでめちゃくちゃ時間溶けました。
ググってもどうにもならないので諦めかけ、最後に公式のDiscordで検索かけたらヒントになりそうな投稿がありました。
同じような事故に遭った誰かが救われたら幸いです。
電子機器類がオンライン授業に対応しているか否か分類出来るかメモ

最近オンライン授業に使われているサービスを、少し書き並べてみます。

 + HTML5ブラウザを前提としたWebサービス
    + WebブラウザベースのLMS (moodleとか)
    + Web会議システム (zoom, WebExとか)
    + G Suite, MS Office365 のWebブラウザベースのもの
 + G Suite for Education Apps
    + Google Classroom
    + Hangouts Meet
    + Youtube ?
 + Microsoft Office365 Apps
    + Word, Excel, Powerpoint
    + Teams ほか
 + (サービスに紐づいた様々な)アプリ
    + zoom
    + Cisco WebEx
    + ほか
 
で、ご家庭でお持ちのハードウェアは何種類かに分かれ、このサービスが必ずしも満足に動作するとは限らないわけです。ちょっと分類してみます。

| PC系 | PC(Windows) | PC(macOS) | PC(ChromeOS) | PC(Linux系) | 
|:------------------:|:----------:|:----------:|:----------:|:----------:|:----------:|:----------:|
|代表的な機器| ノートPCなど | MacBook など | Chromebook など | 自作PC, 仮想PCなど |
|chrome ブラウザ  | 〇 | 〇  | ◎  | 〇  | 
|firefox ブラウザ | 〇 | 〇  | ×  | 〇  | 
|その他ブラウザ | ◎edge, IE | ◎Safari | △ | 多様 | 
|G Suite 系アプリ | chrome依存 | chrome依存 | OS標準 | chrome依存  | 
|Office系アプリ(Word, Excel, PowerPoint) | 〇  | 〇 | △ | × | 
|Office系アプリ(三種以外)                 | 〇  | 〇 | △ | △ | 
|その他アプリ                             | 〇  | 〇 | △ | △ | 

標準のWebブラウザに◎をつけてあります。ChromeOSの△の部分は、Google Play に対応していない、何らかの理由で対応出来ない場合は×になるという認識です。

ネイティブアプリの有無でサービスの利用感は大きく変わります。例えば、Chromebook で Webベースの Microsoft Teams を使うと、ビデオ会議などにうまく参加出来なかった経験があります。

また、Linux系のアプリ類はWin/Mac系とは文化が異なるので、必ずしも同じアプリが用意されているとは限りません。

|スマホやタブレット等|  Android 系(Google Play対応) | Android 系(Google Play非対応) | iOS系 |
|:------------------:|:----------:|:----------:|:----------:|:----------:|:----------:|
|代表的な機器|  国内のスマホなど |  kindle Fire, HUAWEIの最新機器など | iPhone, iPadなど |
|chrome ブラウザ  |  ◎  | ×  | 〇 |
|firefox ブラウザ |  〇 | × | 〇 |
|その他ブラウザ |  多様 | ◎機器依存 | ◎Safari |
|G Suite 系アプリ |  〇 | × | 〇 |
|Office系アプリ(Word, Excel, PowerPoint) |  〇 | △ | 〇 |
|Office系アプリ(三種以外)     |  〇 | × | 〇 |
|その他アプリ      |  〇 | △ | 〇 |

スマホ・タブレット、で一緒くたにしてしまいがちなのですが、まずchromeブラウザか否か、というだけで前提がだいぶ変わります。chromeで起こらなかった現象がsafariで起こるなんてことはよくあります。スマホに導入すべきWebブラウザを指定したほうが良いと思いました。

また、Google Playに対応していない Android 系デバイス には注意が必要です。個人的に kindle fire 系とHUAWEI(AppGallaryのみ対応)系が今後ますます罠になりそうで怖いです。Webブラウザからしてね……違うんですよ……。せめて AppGallary に mozilla firefox が登場してくれればなあと思うところです。（Amazonアプリストアにあるfirefoxは限定的すぎるので見なかったことにしました。）

kindle fire は Amazon のサービス専用だと思います。あれはゲーム機のようなものです。

というわけで、「PCありますか」「スマホとかタブレットとかありますか」で雑に調査すると、後で思わぬ罠を踏みそうなので、個人的に整理したメモでした。

特に、Google Classroom や Microsoft Teams など、一つのサービスに完全に依存してしまうのは、管理は楽ですがハードウェアには制限がかかる、と思った方がいいかもしれません。サービスによっては留学生がアクセス出来ないものもあります。

多様性の担保はサポートの辛さとセットなのかもしれません。
質問の仕方について

基礎的な事だが、せっかくスクールで習った
質問の型なので、メモ書きしておきます。


■解決したいこと
エラー文や、今起こっているトラブルを端的に書く

■自力で調べた内容
検索エンジンを用いた際の検索ワードについてや読んだ記事のリンクを書く

■仮説と検証作業の結果
検索して得た情報から立てた仮説と、その検証作業による結果を書く
StateNotifierProviderとbuilderの最小構成

flutter_state_notifier 0.4.0から、 StateNotifierProviderに新しくbuilderというパラメーターが追加されました。  
  
それを使うと、Providerを定義したすぐ下で、context.readやcontext.selectが使えて便利です。  
  
以下はその最小構成です。数字と、それを増やしていくボタンです。  
  

```dart:main.dart
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:state_notifier/state_notifier.dart';
import 'package:flutter_state_notifier/flutter_state_notifier.dart';

void main() {
  runApp(Demo());
}

class Demo extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Demo',
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Demo'),
        ),
        body: Center(child: Home()),
      ),
    );
  }
}

class Home extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return StateNotifierProvider<CounterNotifier, CounterState>(
      create: (context) => CounterNotifier(),
      builder: (context, child) {
        final count = context.select((CounterState s) => s.count).toString();
        return Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            RaisedButton(onPressed: () {
              context.read<CounterNotifier>().increment();
            }),
            Text(count),
          ],
        );
      },
    );
  }
}

class CounterState {
  CounterState(this.count);
  int count;
}

class CounterNotifier extends StateNotifier<CounterState> {
  CounterNotifier() : super(CounterState(0));

  void increment() {
    state = CounterState(++state.count);
  }
}


```
Sinatra を reload させる方法 2020 年版

[公式サイトの FAQ](http://sinatrarb.com/faq.html#reloading) によると、 [rerun](https://github.com/alexch/rerun) を使う方法が推奨されている。

```ruby
rerun 'ruby app.rb'
```



rerun はファイルの更新を検知してプロセスを再起動するツールで、要は [guard](https://github.com/guard/guard) みたいなもの。 `Guardfile` のような設定ファイル不要なので手軽に使える。

Sinatra の自動リロード用ツールとしては [Sinatra::Reloader](http://sinatrarb.com/contrib/reloader) が有名だが、 FAQ では推奨されていない。

## なぜ Sinatra::Reloader は推奨されていないのか

FAQ は「in-process のコードリロードは難しく、あらゆる状況で動作する解決策は無いので、 out-of-process リロードを推奨する」といっている。

rerun や guard はプロセスを再起動するので、 out-of-process リロードためのツールといえる。一方 Sinatra::Reloader は in-process リロードのためのツールといえる。

公式サイトの立場では、問題が起こる可能性の少ない手法を勧めているのだろう。

## rerun を使う場合の注意点

プロセスを再起動するため、ファイル保存からサーバ再起動完了までに若干のタイムラグがある。

アプリケーションが重厚になると起動時間が伸びるので、開発体験を損なう可能性がある。

タイムラグが許容範囲を超える規模のアプリケーションを開発する場合は、 Sinatra::Reloader を検討すべきかもしれない。
[CSS]リストに置いてのcssメモ書き


```css:css
ul {
  margin: 0;
  padding: 0;
  list-style: none;
}

li {
  float: left;
  padding-right: 10px;
}
```

※ポイント※

①「margin: 0;」「padding: 0;」は
　ul がデフォルトで持っている幅を消すためのもの。

②「padding-right: 10px;」は文字間に幅をもたせる。

③「 list-style: none;」で黒点を消す！
PEP 604 (Complementary syntax for Union[]) を読んだよメモ

Microsoft の Python 向け型チェッカーの [pyright](https://github.com/microsoft/pyright) が最新の仕様に対応していると聞いて README を流し読みしていたら、今までウォッチしていなかった [PEP 604 (Complementary syntax for Union[])](https://www.python.org/dev/peps/pep-0604/) というのがリストアップされていたので目を通してみました。
ちなみに次の記事で PEP-612 についても書く予定です。

## 概要

* 毎回 `Union[int, str]` って書くのうざくない?
* Scala みたいに `int | str` って書けるようにしようよ
* 型アノテーションだけじゃなくて、 `isinstance()` や `issubclass()` でも使えるようにしようよ

## アプローチ

* 型同士を `|` でつなぐと型集合をつくれるようにする

以上。

## 例

PEP にあるサンプルを見ると一目瞭然なので説明は省きます。

```py
# in place of
# def f(list: List[Union[int, str]], param: Optional[int]) -> Union[float, str]
def f(list: List[int | str], param: int | None) -> float | str:
    pass

f([1, "abc"], None)

assert str | int == Union[str,int]
assert str | int | float == Union[str, int, float]

assert isinstance("", int | str)
assert issubclass(bool, int | float)
```

## 感想

* 正直な感想としてキモい…
* Scala で見かけるとあんまり違和感はないのに、Python として見るとなんだかゾワゾワするのは単に慣れていないだけだろうか
* Union を書くのは楽になるけど `List[int | str]` を書くのにはあまりメリットないですね…
* まだ Draft なので採用は決まってません
プログラム基礎知識を勉強する際の考え方

自分はこんな感じでのイメージ学んだので、メモ書きです。

1. 作りたいプログラムの仕様を考える
2. プログラムをトリガーやイベントごとに分割して日本語で書き出す
3. コードを書く＆説明コメントをつけて理解出来ない部分を無くす
4. 小さいコードのプログラムを沢山書く
5. 少しづつ大きいプログラムを書いてみる


プログラムを書く際は、自分でコメント説明文を入れて
合っているかを確認してもらう！！
→自分で説明できるか？
　なぜ、そのコードを入れたのかを意識する


<仕様>
そのプログラムができる事を具体的に箇条書き
・
・
・


<プログラムでどんな処理をするか日本語で説明>
・登場する変数は？


・
・
・

実際にコードを書く！
※その際に、自分でコメントを入れて全て
　説明できるかを確認していく
mysql: VARCHARの列幅の差と TEXT型とでINSERT性能には殆ど違いない

# なにこれ (tl;dr)
mysql5.7にて、VARCHAR(10)とVARCHAR(30000)ではINSERTなどで差が出る、という話を聞いたのと、よく言われている TEXT型は遅い、という話をベンチマークしてみたら少なくともINSERTは全然差がないことがわかった、という話

ただしTEXT型は検索する場合は当然差が出て来るが、割愛。

# 測定用スクリプト
```ruby
    con = ActiveRecord::Base.connection

    # utf8mb4が検証環境のため 65535/4=16383
    length_set = [255, 4096, 16383, :text]
    string_set = [250, 4090, 16380]
    try_count = 10000

    demostr = "123456789A"

    raw_con = con.raw_connection

    Benchmark.bm 40 do |bm|
      length_set.each do |length|
        column_type = length == :text ? "text" : "varchar(#{length})"
        con.execute("create table length_test (str #{column_type})")
        insert_sql = raw_con.prepare("insert into length_test values(?)")
        begin
          string_set.each do |strlen|
            next if length != :text && strlen > length

            insertstr = demostr * (strlen / 10)
            bm.report "#{column_type} <-- string(#{strlen})" do
              try_count.times do
                insert_sql.execute(insertstr)
              end
            end
          end
        ensure
          insert_sql.close
          con.execute('drop table length_test')
        end
      end
    end
```

# 結果
INSERT10000回

|  | 文字列長250 | 文字列長4090 | 文字列長16380 |
|:--|--:|--:|--:|
| varchar(255) | 13.229861 |  |  |
| varchar(4096) | 13.623846 | 18.922998 |  |
| varchar(16383) | 13.380692 | 18.426866 | 45.27052 |
| text | 12.739086 | 18.534715 | 46.134611 |

# 考察
- varcharの列幅による有意な違いはない
- ただし、INSERTする文字列の長さには相関関係がある(正比例ではないのもやっかい)
- text型へのINSERT性能は悪くない (繰り返しになるが SELECT では別。WHEREの対象になるとさらに遅いかもしれない)
- 現状、1レコードの総バイト数が65535を超えることが出来ない? ようなので、こんな長さの文字列を複数持つことは出来ない
- utf8mb4 だと1文字表現するのに4bytes使うので、VARCHAR(65535)とは出来ない。4でdivすることになる
【Error】編集後に画面遷移しない事象の解消法

# 概要
タスクの編集画面を実装し、確認のため編集を行い、ボタンを押下したのですが画面が変わらず。。。。:confounded:

結果としては、「redirect_to」していなかった:sweat_smile:ということでしたが、エラー解決するまでの経緯を備忘録として残します！

# 確認方法
【前提】
編集画面で登録ボタンを押した後は、ボタンは押下できない状況にあった。
画面遷移もされない。
①MySQLに編集データが保存されているかを確認
→
変更されている:ok_hand:

②エラー画面が出ていないのであれば、ターミナルにエラー情報が記入されているのではないかを確認

```Terminal:terminal
No template found for TasksController#update, rendering head :no_content
Completed 204 No Content in 139ms (ActiveRecord: 3.4ms)
```

あった:rolling_eyes:
**No template**って記載されてた！！

③コントローラーを確認
→redirect_toが記載なし:scream:

# 修正箇所
**修正前**

```Ruby:tasks_controller.rb
def update
  @task.update(task_params)
  if @task.valid?
    @task.save
  else
    flash.now[:alert] = 'タスク名を入力してください'
    render :index
  end
end
```
**修正後**

```Ruby:tasks_controller.rb
def update
  @task.update(task_params)
  if @task.valid?
    @task.save
    redirect_to group_tasks_path(@group), notice: 'タスクが変更されました'
  else
    flash.now[:alert] = 'タスク名を入力してください'
    render :index
  end
end
```

皆さま、お気をつけください:bow_tone1:

# 参考
エラー204に関するURLです。
https://developer.mozilla.org/ja/docs/Web/HTTP/Status/204
[質問]Pythonでtxtファイル内の行を指定して上書きしたい

#Pythonでtxtファイル内の行を指定して上書きしたい
データベースとしてtxtファイルを使用しているのですが、ファイル内の指定した行の上書を行いたいです。
#やってみたこと
指定行の上書と言うのが分からなかったため、txtファイルの中身全体をreadlinesで行別にlist化し、特定の要素を書き換えてwritelines(list)で上書きしていました。

```test.txt
Hello
World
```

```code.py
import os

path = "/data/test.txt"
line_num = 1 # 上書きする行番号(場合によっては変わる)
temp = "Python" # 上書きしたい内容

with open(path) as file:
    list = file.readlines

print(list)
#Hello
#World

list[line_num] = temp
print(list)
#Hello
#Python

with open(path, mode="w") as file:
    file.writelines(list)
```
この様に。
流石にもう少しいい方法があるのではと思い、質問に至った次第です。
githubのはじめ方

<h2>メアドとユーザー名</h2>

まずgithubに登録済みのメアドとユーザー名をコマンドを用いて登録します。

```
ユーザー名とメールアドレスを設定する
Git上で使いたい情報を入力します。下記のコマンドで【ユーザー名】と【メールアドレス】の部分を、自分の情報に置き換えてください。

$ git config --global user.name "【ユーザー名】"
$ git config --global user.email 【メールアドレス】
以下のコマンドで設定を確認できます。

$ git config --list
user.name=【ユーザー名】
user.email=【メールアドレス】
...
```

【参考】
https://employment.en-japan.com/engineerhub/entry/2017/01/31/110000

<h2>SSHキーを設定</h2>

鍵を設定します。

```
１：鍵を作成する。
２：作成した鍵をコピーする。
３：gitghubに公開鍵を登録する。
４：configファイルを作成し直す。(接続確認）
```

【参考】
http://tusukuru.hatenablog.com/entry/2018/08/29/021651

<h2>ラスト</h2>
以下のコマンドを実行。

```
git init
git add README.md
git commit -m "first commit"
git remote add origin URL
git push -u origin master
```
C# 値型(列挙型：enum)

##C#値型（列挙型）
"列挙型" は、基になる整数値型の一連の名前付き定数によって定義された値の型です。 
列挙型を定義するには、enum キーワードを使用して "列挙型メンバー" の名前を指定します。

```
enum Season
{
	Spring,
	Summer,
	Autumn,
	Winter
}
```

既定では、列挙型メンバーの関連する定数値の型は int で、
0 から始まり、定義テキストの順序に従って 1 ずつ増加。
他の任意の整数値型を、列挙型の基になる型として明示的に指定も可能。

| Spring | Summer | Autumn | Winter |
|--------|--------|--------|--------|
| 0 | 1 | 2 | 3 | 

また、次の例に示すように、関連する定数値を明示的に指定することもできます。

```
enum Season
{
	Spring = 0,
	Summer = 1,
	Autumn = 100,
	Winter = 200
}
```


| Spring | Summer | Autumn | Winter |
|--------|--------|--------|--------|
| 0 | 1 | 100 | 200 | 

**int型以外での宣言**
:(コロン)を用いて型を指定。

```
enum Season:byte 
{
	Spring,
	Summer,
	Autumn = 100,
	Winter
}
```

| Spring | Summer | Autumn | Winter |
|--------|--------|--------|--------|
| 0 | 1 | 100 | 101 | 

**参考資料**
・Microsoft Build
・C#の絵本
ターミナルでよく使うコマンド集(ファイル操作編)


#
```:ターミナル
# カレントディレクトリのパスを表示する
$ pwd

表示例→/Users/ユーザ名/Desktop/sample
→print working directoryの略

# 今いるディレクトリの直下にあるファイルやフォルダの名前の一覧を表示します
$ ls

 →listの略

# ファイルのパーミッションの確認
$ ls -l

#移動したい時に使う 
$ cd ファイル名

change directoryの略。

#ホームディレクトリに移動する
$ cd ~/ 

#一つ上の階層のファイルに移動する
$ cd ..
```

### <移動の注意点>  

```:ターミナル
#相対パス
$ cd projects

#絶対パス
$ cd ~/projects

```
相対パスはフォルダ名(ファイル名)から初めて良い
絶対パスは/から始めます


##touch コマンド
中身が空のファイルを作る。

```
# test.htmlという中身が空のファイルを作る
touch test.html
```

## mkdir コマンド
新しい空のディレクトリを作る。（make directoryの略）

```  
#testというファイルを作る
mkdir test
```


## ディレクトリを削除

```  
#　ディレクトリを削除
rm -r ディレクトリ名
```

## viエディタの開始

```
#開始
$ vi
```
```
# ファイルを指定して開始
$ vi ファイル名
```

## コマンドモードと入力モード
コマンドモードでは文字入力ができない。入力モードのみで可能。
切り替えは・・

```
//カーソルの位置で入力モードに切り替え
i
//コマンドモードに切り替え
esc
編集の保存と終了
escでコマンドモードに切り替えて実行する
```

```
//保存
:w
//名前をつけて保存（新しくファイルをつくる）
:w ファイル名
//終了
:q
//保存して終了
:wq
```
MacのCPUコア数をコマンドラインから取得する方法

MacのCPUコア数をコマンドラインから取得する方法

```
$ system_profiler SPHardwareDataType | awk '/Total Number of Cores/ { print $NF }'
2
```

その他情報

```
$ system_profiler SPHardwareDataType
Hardware:

    Hardware Overview:

      Model Name: MacBook Pro
      Model Identifier: MacBookPro14,1
      Processor Name: Intel Core i5
      Processor Speed: 2.3 GHz
      Number of Processors: 1
      Total Number of Cores: 2
      L2 Cache (per Core): 256 KB
      L3 Cache: 4 MB
      Memory: 8 GB
      Boot ROM Version: 184.0.0.0.0
      SMC Version (system): 2.43f6
      Serial Number (system): C02W70QBHV22
      Hardware UUID: 8D8D4DA4-17B0-5B0A-9A47-A452EC690F38
```

# 参考
[Macでシステム情報を確認する方法](https://umatomakun.hatenablog.com/entry/2014/04/06/030426)
[About System Information on your Mac](https://support.apple.com/en-us/HT203001)
ブランチ名の命名規則でよく使うもの

#ブランチ名の命名規則
ブランチを切るときは頭に分かりやすい名前をつけると良い。
prefixを変更内容に沿ったものを選ぶこと。

【よく使うもの】
- dev: ごりっと開発したよ（新規開発とか）
- fix: バグを修正したよ
- change: 差し替えただけだよ
- add: 既存のものに追加しただけだよ


他のprefix参考URL▼
[【必須】Gitコミットの書き方・作法【prefix/emoji】](https://suwaru.tokyo/%E3%80%90%E5%BF%85%E9%A0%88%E3%80%91git%E3%82%B3%E3%83%9F%E3%83%83%E3%83%88%E3%81%AE%E6%9B%B8%E3%81%8D%E6%96%B9%E3%83%BB%E4%BD%9C%E6%B3%95%E3%80%90prefix-emoji%E3%80%91/)