OmniAICreator/Qiita-1.07M huggingface dataset:
ベン図を分かりやすくGIFアニメーションにしてみた

## AND回路
AND回路は以下のようになります。
AとBの入力があり重なった赤いCが出力になります。
![ベン図AND.gif](https://qiita-image-store.s3.amazonaws.com/0/335037/7da91fee-773a-5fef-4fbd-1b7c84dc1351.gif)

## OR回路
OR回路は以下のようになります。
AとBの入力がありAかつBの範囲Cが出力になります。
![ベン図OR.gif](https://qiita-image-store.s3.amazonaws.com/0/335037/eec12c85-2197-79a3-18f4-73309584d0d9.gif)

## NAND回路
NAND回路は以下のようになります。
初めに出てきたANDの否定です。(NOT AND)
赤いCの出力がANDの反転なのがわかります。
AとBが両方TRUEの時にFALSEを出力する回路です。
![ベン図NAND.gif](https://qiita-image-store.s3.amazonaws.com/0/335037/e5e11f6e-6145-d701-5bb4-02a2035ed3f3.gif)

## NOR回路
NOR回路は以下のようになります。
ORの否定です。(NOT OR)
![ベン図NOR.gif](https://qiita-image-store.s3.amazonaws.com/0/335037/3a7768d9-902b-8be6-62ae-0e37b28b482f.gif)

## XOR回路
XOR回路は以下のようになります。
AとBが両方TRUEもしくは両方FALSEの時にFALSEを出力します。
![ベン図XOR.gif](https://qiita-image-store.s3.amazonaws.com/0/335037/40675340-7f30-62fa-8e5f-709498b63ca2.gif)

## XOR回路の分解
XOR回路をNAND、OR、ANDを使って求めるには以下のようになります。
黄色いNANDと紫のORを重ねた時に重なる範囲(AND)がXORになります。(黄色と紫を重ねて白っぽくなっている範囲)

![ベン図1_03.gif](https://qiita-image-store.s3.amazonaws.com/0/335037/38b3810d-dcf5-649a-8018-9be7fb94e899.gif)

## XOR回路のJavaによる実装
上のXOR回路の分解で示した図をJavaで実装してみます。

```java:Main.java

public class Main {

    public static void main(String[] args) {
        // XOR回路の出力
        final boolean[][] AB = {
                    { true, true },
                    { true, false },
                    { false, true },
                    { false, false }
                };

        System.out.printf("XOR回路の出力\n");
        for (int i = 0; i < AB.length; i++) {
            boolean b = xor(AB[i][0], AB[i][1]);
            System.out.println("(A :" + AB[i][0] + ") + (B :" + AB[i][1] + ") = " + b);
            }
    }
    public static boolean and(boolean a, boolean b) {
        if (a && b) {
            return true;
        }
        return false;
    }

    public static boolean or(boolean a, boolean b) {
        if (a || b) {
            return true;
        }
        return false;
    }
    public static boolean nand(boolean a, boolean b) {
        return !and(a, b);
    }
    public static boolean xor(boolean a, boolean b) {
        if (and(nand(a, b), or(a,b))) {
            return true;
        }
        return false;
    }
}

//XOR回路の出力
//(A :true) + (B :true) = false
//(A :true) + (B :false) = true
//(A :false) + (B :true) = true
//(A :false) + (B :false) = false
```



## XOR回路のJavaによる実装　その2
上記のJavaのコードで使ってるxorメソッドの中身を下記に変えてもXOR回路が出来ます。
下記はaとnand(a, b)のandをとったaの右側が欠けた三日月のような出力と、bとnand(a, b)のandをとったbの左側が欠けた三日月のような出力をorで合体させるように出力します。

```java:Main.java

    public static boolean xor(boolean a, boolean b) {
        if (or(and(a, nand(a, b)), and(b, nand(a, b)))) {
	    	return true;
	    }
    	return false;
    }
```
kerasでMNIST_image CNN実装

```LeNet.py

import os
import keras
from keras.models import Sequential
from keras.layers.convolutional import Conv2D
from keras.layers.convolutional import MaxPooling2D
from keras.layers.core import Activation
from keras.layers.core import Flatten,Dropout
from keras.layers.core import Dense
from keras.datasets import mnist
from keras.optimizers import Adam
from keras.callbacks import TensorBoard

def lenet(input_shape,num_classes):
  model = Sequential()
  
  #extract image features by convolution and max pooling layers
  model.add(Conv2D(20,kernel_size=5,padding='same',input_shape=input_shape,activation='relu'))
  model.add(MaxPooling2D(pool_size=(2,2)))
  model.add(Conv2D(50,kernel_size=5,padding='same',activation='relu'))
  model.add(MaxPooling2D(pool_size=(2,2)))
  #classify the class by fully-connected layers
  model.add(Flatten())
  model.add(Dense(500,activation='relu'))
  model.add(Dense(num_classes))
  model.add(Activation('softmax'))
  return model

class MNISTDataset():
  
  def __init__(self):
    self.image_shape = (28,28,1) #image is 28*28*1 (grayscale)
    self.num_classes = 10
   
  def get_batch(self):
    (x_train,y_train),(x_test,y_test) = mnist.load_data()
    
    x_train,x_test = [self.preprocess(d) for d in [x_train,x_test]]
    y_train,y_test = [self.preprocess(d,label_data=True) for d in [y_train,y_test]]
    
    return x_train,y_train,x_test,y_test
  
  def preprocess(self,data,label_data=False):
    if label_data:
      #convert class vectors to binary class matrices
      data = keras.utils.to_categorical(data,self.num_classes)
    else:
      data = data.astype('float32')
      data /= 255 #convert the value to 0-1 scale
      shape = (data.shape[0],) + self.image_shape #add dataset length to top
      data = data.reshape(shape)
    
    return data

class Trainer():
  
  def __init__(self,model,loss,optimizer):
    self._target = model
    self._target.compile(loss=loss,optimizer=optimizer,metrics=['accuracy'])
    self.verbose = 1
    self.log_dir = os.path.join(os.path.dirname(os.getcwd()),'logdir')
    
  def train(self,x_train,y_train,batch_size,epochs,validation_split):
    if os.path.exists(self.log_dir):
      import shutil
      shutil.rmtree(self.log_dir) #remove previous execution
    os.mkdir(self.log_dir)
    
    self._target.fit(
        x_train,y_train,
        batch_size = batch_size, epochs=epochs,
        validation_split = validation_split,
        callbacks= [TensorBoard(log_dir=self.log_dir)],
        verbose = self.verbose
    )

#実装
dataset = MNISTDataset()

#make model
model = lenet(dataset.image_shape,dataset.num_classes)

#train the model
x_train,y_train,x_test,y_test = dataset.get_batch()
trainer = Trainer(model,loss='categorical_crossentropy',optimizer=Adam())
trainer.train(x_train,y_train,batch_size=128,epochs=12,validation_split=0.2)

#show result
score = model.evaluate(x_test,y_test,verbose=0)
print('Test loss:',score[0])
print('Test accuracy:',score[1])
```
Julia 1.0のdebugger

Juliaを他人にすすめる上で最大の障害といってよいのは（ちゃんとした）Debuggerがないことなんですが、簡易的なDebuggerはあります。

実は、公式でもちゃんとアナウンスされていないのですが、[ASTInterpreter2.jl](https://github.com/Keno/ASTInterpreter2.jl)と、[DebuggerFramework.jl](https://github.com/Keno/DebuggerFramework.jl)の#masterは、Julia v1.0で動作します。

# インストール
REPL上で、`]`キーでPkgモードに入って

```julia
(v1.0) pkg> add DebuggerFramework#master
(v1.0) pkg> add ASTInterpreter2#master
```

# 使い方

[このページ](https://github.com/Keno/ASTInterpreter2.jl/blob/5215f4bb390cecb00440f595090e6f3c6533fa15/README.md)を見てください。

簡単に言えば、

```julia
julia> using ASTInterpreter2
```
した後、

```julia
julia> @enter foo(20)
```
とすることで、`foo`関数の中身をステップ実行できます。
ブレークポイント機能がないことをのぞけば、デバッガとして必要な機能は、だいたい揃っているとは思います。上のページにも書いてありますが、デバッガのREPL上で、バッククオートキー（`` ` ``）を押すと、デバッグ中のコンテキストで任意のJuliaのコマンドを実行できます。

# IDE上でステップ実行したい
私は試していないですが、[IntelliのJulia Plugin](https://github.com/ice1000/julia-intellij#debugger-nightly-build)ではJulia v1.0でのステップ実行ができるようです。READMEによれば、このプラグインは、IntelliJ IDEAやPyCharmなんかのCommunity edition（無料版）でも動作するみたいです。

また、こちらも試していないですが、[Juno](http://junolab.org/)もv0.6時代にはASTInterpreter2.jl使ったステップ実行ができていたはずなので、v1.0でもできるのかもしれません。
⇒ [Junoでも動くそうです。](https://discourse.julialang.org/t/debugger-in-juno-for-julia-1-0/19727)
なぜかRustで言語処理100本ノック ～第5章 後編～

[前編はこちら](https://qiita.com/kbone/items/a1322e652113b7719d9f)

# 第5章: 係り受け解析
## 45. 動詞の格パターンの抽出
> 今回用いている文章をコーパスと見なし，日本語の述語が取りうる格を調査したい． 動詞を述語，動詞に係っている文節の助詞を格と考え，述語と格をタブ区切り形式で出力せよ． ただし，出力は以下の仕様を満たすようにせよ．

(一部抜粋)

長くなってしまいましたが、やっていることは、動詞を含む文節それぞれに対し係っている助詞を全て取り出しているだけです。
また、

> コーパス中で頻出する述語と格パターンの組み合わせ

のコマンドは`cat $FILE | sort --key=1 | uniq -c | sort -r --key=1`で、

> 「する」「見る」「与える」という動詞の格パターン（コーパス中で出現頻度の高い順に並べよ）

のコマンドは`cat $FILE | grep -e '^する' -e '^見る' -e '^与える' | sort --key=1 | uniq -c | sort -r --key=1`です。

<details><summary>実装コード</summary><div>

```rust
pub fn verbs(cabocha: &Vec<Vec<Chunk>>, out_file: &Path) {
    let file = OpenOptions::new().write(true).create(true).open(out_file);
    if file.is_err() { return; }
    let mut bw = BufWriter::new(file.unwrap());
    cabocha.iter().for_each(|sentence| {
        sentence.iter()
                .enumerate()
                .filter_map(|(index, chunk)|
                    chunk.morphs.iter()
                                .find(|m| m.pos == "動詞")
                                .map(|m| (index, m.base.clone()))
                ).for_each(|verb| {
            let kaku = sentence.iter()
                .filter(|chunk| chunk.dst as usize == verb.0)
                .filter_map(|chunk| chunk.morphs.iter().find(|m| m.pos == "助詞"))
                .map(|morph| morph.surface.clone())
                .collect::<Vec<_>>();
            kaku.sort();
            if !kaku.is_empty() {
                bw.write(format!("{}\t{}\n", verb.1, kaku.join(" ")).as_bytes()).unwrap();
            }
        });
    });
}
```

</div></details>

## 46. 動詞の格フレーム情報の抽出
> 45のプログラムを改変し，述語と格パターンに続けて項（述語に係っている文節そのもの）をタブ区切り形式で出力せよ．45の仕様に加えて，以下の仕様を満たすようにせよ．

45とほとんど一緒な上に長くなるので省略します。

## 47. 機能動詞構文のマイニング
> 動詞のヲ格にサ変接続名詞が入っている場合のみに着目したい．46のプログラムを以下の仕様を満たすように改変せよ．

これもかなり似ているので省略します。

## 48. 名詞から根へのパスの抽出
> 文中のすべての名詞を含む文節に対し，その文節から構文木の根に至るパスを抽出せよ． ただし，構文木上のパスは以下の仕様を満たすものとする．

(一部抜粋)

DOT言語として書き出したときと似て非なる感じです。

```rust
pub fn noun_to_root(cabocha: &Vec<Vec<Chunk>>) {
    cabocha.iter().for_each(|sentence|
        sentence.into_iter()
                .filter(|chunk|
                    chunk.morphs.iter().find(|m| m.pos == "名詞").is_some()
                    && chunk.dst != -1)
                .for_each(|chunk| {
                    let mut dst = chunk.dst;
                    print!("{}", chunk.get_text());
                    while dst != -1 {
                        print!(" -> {}", sentence[dst as usize].get_text());
                        dst = sentence[dst as usize].dst;
                    }
                    println!("");
                })
    );
}
```

## 49. 名詞間の係り受けパスの抽出
じつはここで諸事情あってしばらく中止してしまったので、第5章はちょっとここで終了します。恐らく48と似たような処理になると思うので、許してください。

# 第5章の感想
この感想を書いているのは、しばらく中止した後なので正直殆ど覚えていないのですが、第5章は特に後編で省略が多くなってしまいました。次章からは題材も変わるようなので、~~なんとか最後まで走りきりたいです。~~ むしろ題材が変わって`Python`依存が大きそうなので恐らくこの先はないです。申し訳ないです。
2019年スペシャルおみくじアプリ【あなたは何吉でしたか？】

#あけましておめでとうございます！
新年という節目を機に、この度Qiitaに投稿致しました。


もう初詣にいった方はおみくじを引きましたでしょうか？
引いた方も引いてない方も

新年の楽しみの一つにぜひ、
こちらの「スペシャルおみくじ」を引いていってください。



https://wakatakerutmt.github.io/2019omikuji/
![aaaa.JPG](https://qiita-image-store.s3.amazonaws.com/0/222588/18b9903c-b11f-a4d8-6688-ea867cce8e52.jpeg)





※PCの場合音を出していただくと、より良いかと思います。
※操作方法はクリックだけです。
※レスポンシブ対応しています。



新年、どうぞよろしくお願いいたします。




----------------


##開発環境
Windows 10 HOME
Atom

##使用したもの
・GitHub Pages
・HTML,CSS,JavaScript

##ソース
https://github.com/wakatakerutmt/2019omikuji

##きっかけ

手軽にページを公開できるGitHub Pagesを使ってみたかった。
新年一発目のギャグが思い浮かんだので。

##備考・まとめ


昔作ったおみくじアプリをちょっと改良しただけの数分で作った物なのでクオリティは低く、コードも適当です。
お付き合いありがとうございました。
Prime Square Sum

# [Prime Square Sum](https://www.hackerrank.com/contests/girigiri-happy-new-year-contest/challenges/prime-square-sum)

## コンテスト中

- とりあえず素数列挙。これは$O(N\sqrt{N})$
- 1000000以下の素数の個数は78498個だった。なので、愚直に３重ループでの実装は無理。
- ２重ループも考えたけどきつそう。行けたとしてもsqrt使わなきゃダメっぽい
- よくわかんなくなって終了



## 理想の考察

- とりあえず素数列挙する。計算量は$O(N\sqrt{N})$
- 素数の個数は78498個になる。なので、愚直に３重ループとかは無理。計算量減らしたい
- 素数の値が大きい場合、$A^2 + B^2 + C^2 = N$の左辺がめちゃくちゃ大きくなるのに気がつく。この辺で無駄な計算してるのでは？となる
- ここで、$A^2, N$のみに注目してみる。$A^2$と$N$の大きさの関係を考えてみる。$B^2 > 0, C^2 > 0$より、$A^2 < N$である。この式でルートをとると、$A < \sqrt{N}$ となる。よって、列挙する素数は$\sqrt{N}$未満で良さそうだ
- 念の為もう少し考えると$A \geq \sqrt{N}$の場合、両辺を2乗すると$A^2 \geq N$となる。なので、$A^2 \geq N$のとき、$B, C$をどれだけ小さくしようとしても$A^2 + B^2 + C^2 > N$となってしまう。なので、$\sqrt{N}$以上の素数を列挙しても計算に使わないため列挙する意味がないことがわかる



## 解法

1. $\sqrt{N}$以下の素数を列挙する
2. 列挙した素数で3重ループを回す



## コード

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

#define int long long

vector<int> prime;

void init() {
  prime.push_back(2);
  for (int ni = 3; ni*ni <= 1000000; ni++) {
    bool flg = true;
    for (int j = 2; j*j <= ni; j++) {
      if (ni % j == 0) {
        flg = false;
        break;
      }
    }
    if (flg) {
      prime.push_back(ni);
    }
  }
}

signed main() {
  init();
  int t; cin >> t;
  while (t--) {
    int n; cin >> n;

    int ans = 0;
    for (int i = 0; i < prime.size(); i++) {
      for (int j = i; j < prime.size(); j++) {
        for (int k = j; k < prime.size(); k++) {
          int a = prime[i], b = prime[j], c = prime[k];
          if (a*a + b*b + c*c == n) {
            ans++;
          }
        }
      }
    }
    cout << ans << endl;
  }


  return 0;
}
```





## 要点

- 無駄に計算している部分を見つける。
ElixirでHackerRankの問題を解いてみる【e^xの計算】

# あけましておめでとうございます！
こんにちは！fukuoka.exキャストのkoyoです！
2019年始まりましたね
今年はElixirしっかりやる年になるといいなということで、新春からElixirの記事投稿してみます

# HackerRank
今回はHackerRankという学習サイトを使って、オンラインでプログラミング問題を解いて自動採点しながらElixirを学んでいきたいと思います
競技プログラミングのサイトはAtCoderなどいろいろありますが、なかなかElixirには対応していないというのが現状です＞＜
しかしHackerRankはElixirに対応してます！すごい！

# やってみよう！
## 問題
今回は [Evaluating e^x](https://www.hackerrank.com/challenges/eval-ex/problem) という問題を使ってみます

![image.png](https://qiita-image-store.s3.amazonaws.com/0/201242/0d00cb68-e12f-b3b5-9f65-487344eeeb36.png)

英語ですが、大体サンプルのinputとoutputを見れば書けると思います
概要としては各行に入力されたxの値に対応して
`1+x+x^2/2!+x^3/3!+...`の第10項まで（つまり`x^9/9!`まで）を計算する問題です（精度は小数点以下４桁まで）
なお、入力の第一行は入力される行数になります

## 解法

```elixir:solution.exs
defmodule Solution do
  defp calc(x) do
    0..9 |> Enum.reduce(0.0, fn i, acc -> acc + :math.pow(x, i) / factorial(i) end)
  end

  defp factorial(n) when n > 0 do
    n * factorial(n - 1)
  end

  defp factorial(n) when n == 0 do
    1
  end

  def main() do
    # 最初の行は要らないので読み捨てる
    _ = IO.gets("") |> String.trim() |> String.to_integer()

    inputs =
      IO.read(:stdio, :all)
      |> String.split("\n")
      |> List.delete_at(-1)
      |> Enum.map(&String.to_float(&1))

    inputs |> Enum.each(fn x -> x |> calc() |> Float.round(4) |> IO.puts() end)
  end
end

Solution.main
```

解答はこんな感じにしてみました！
Solutionモジュールの中にmain関数を定義してその中に解答を書くイメージです

### 標準入力部

標準入力から`inputs`変数に入力する部分ですが、ここは難しいので解説します
標準入力から入ってきた文字列をいったん全部`IO.read`で、読み込みます
その後改行コード`\n`区切りで分割してListにします
このままだとHackerRankの入力の仕様上、最後だけ空文字がListに入ってしまうので[`List.delete_at/2`](https://hexdocs.pm/elixir/List.html#delete_at/2)で最後の要素だけ消します
入力された数値は文字列になっているので`String.to_float`で変換を忘れずに！

```elixir
    inputs =
      IO.read(:stdio, :all)
      |> String.split("\n")
      |> List.delete_at(-1)
      |> Enum.map(&String.to_float(&1))
```

あとは`inputs`の各要素に対して`Enum.each`を使って各要素に自作関数`calc`を作用させて、小数点第４位が残るように四捨五入して、`IO.puts`で出力します

### 自作関数calc

calcの中身はこうなっています
今回はモジュールの内部でしか使わないので`def`ではなく`defp`としてプライベート関数であることを明示的に示します
今回は10項まで計算すればいいので`0..9`という感じで[range](https://hexdocs.pm/elixir/Range.html)を生成して`Enum.reduce/3`に渡します
[Enum.reduce/3](https://hexdocs.pm/elixir/Enum.html#reduce/3)はElixirを極めるために必須の関数なので是非ドキュメントを読んでください！
※累乗を計算する部分は以下を参考にしました
[powの小話 - Qiita](https://qiita.com/yujikawa/items/3723393ee1a3b985c6be)

```elixir
  defp calc(x) do
    0..9 |> Enum.reduce(0.0, fn i, acc -> acc + :math.pow(x, i) / factorial(i) end)
  end
```

### factorial

ちなみに`calc`の中で`factorial`という自作関数を使っていますが、これは階乗を計算する関数です
Elixirでは同名の関数でも`when`で書かれた条件別に処理を分岐できるので、それを使って書くとスッキリ書けます！

```elixir
  defp factorial(n) when n > 0 do
    n * factorial(n - 1)
  end

  defp factorial(n) when n == 0 do
    1
  end
```

ちなみに再帰使わない場合はこんな感じでもOK

```elixir
  defp factorial(n) when n > 0 do
    1..n |> Enum.reduce(1, fn x, acc -> x * acc end)
  end

  defp factorial(n) when n == 0 do
    1
  end
```

# まとめ
こんな感じでやってみると色々発見がありますね
みなさんも是非やってみてください！

Elixirの書き方を学びたい場合は私が以前書いた、以下の記事がオススメです！
みなさんもElixirテク学んで是非記事書いてみてください！
[【doctestつき】AtCoder に登録したら解くべき精選過去問 10 問を"Elixir"で解いてみた](https://qiita.com/koyo-miyamura/items/9f224a3e56ea75939dca)
有害な人への対処法

この記事は、[Team Geek](https://www.amazon.co.jp/Team-Geek-―Googleのギークたちはいかにしてチームを作るのか-Brian-Fitzpatrick/dp/4873116309)を読んで面白かった部分を一部抜粋して紹介します。

最初に言っておきますが、「有害な人」という言葉は参考にした著書の[Team Geek](https://www.amazon.co.jp/Team-Geek-―Googleのギークたちはいかにしてチームを作るのか-Brian-Fitzpatrick/dp/4873116309)でも
> 「有害な人」という言葉は乱暴だし、「私たち(善人)」と「あの人たち(悪人)」の境界線を引いてしまう。この問題について考えるにはもっといい方法がある。普通の人たちを排除するようなエリート志向のフラタニティではなく、ネガティブな振る舞いを拒否するような文化を作る方が健全だ。排除するのはあくまでも **振る舞い** であり、特定の個人ではない。個人を「いい」とか「悪い」とかで考えるのは単純すぎる。目に余る **振る舞い** を特定して、そのことを批判するほうが建設的で実践的だ。

と強調していますので、タイトル以外では**「有害な振る舞い」**という言葉を使います。

# 有害の定義
頭のいいエンジニアがいれば、効率的で動きの速いチームになるかもしれないが、その人の「ある種の振る舞い」のせいで、かえって非効率で動きの遅いチームになるかもしれないし、会社が居心地が悪い場所になるかもしれない。あるいは、チームの絆が緩むかもしれない。そういった**「振る舞い」**を**「有害な振る舞い」**と呼ぶ

# 有害な振る舞いを追い出す
善人と悪人の境界線を引いて誰かを追い出すのではなく、**「有害な振る舞い」を追い出すのが重要。**

有害な振る舞いを排除すれば、**頭がいい人は生産性の高いメンバーになる。**

# どう判断する？
以下の2つの質問の答えが「ノー」であれば、できるだけ早くその振る舞いを中止する必要がある。

- 短期的にはチームの注意や集中を無駄にしても、**長期的にはプロジェクトにメリットがあるだろうか？**
- その衝突は有益な方法で解決できるだろうか？

# 技術的な貢献は大きいが、有害な振る舞いをする人に対して
技術的なメリットを理由にして、そうした振る舞いに目をつぶりたいという気持ちもわかる。しかし、HRTをベースにした文化はかけがえのないものであり、技術的に貢献できる人は**確実に交換可能**である。

**短期的なメリットのために文化を妥協する必要はない。** HRTの重要性を認めない「頭のいい」コントリビューターには気をつけよう。

# 意図的に文化を破壊しようとする人はいない
ロバート・J・ハンロンもこう言っている。

> 無能(無知)で十分説明されることに悪意を見出すな。

意図的に文化を破壊しようとする悪人などおらず、多くは誤解や見当違いが原因だ。あるいは人に認められたいのかもしれないし、社交性がないだけかもしれない。いずれにしても、よくわかっていない人をプロジェクトから追い出すのが仕事ではない。破壊的な振る舞いを受け入れず、HRTに対する自分の期待を明確にすることが仕事だ。そのためには、その違いを理解する頭と実際に行動するスキルが必要である。[^引用]
# TeamGeekを読んで
「Googleのエンジニアなんだから、さぞすごい(?)天才がいっぱいいるチームなんだろう！」みたいな偏見を持っていましたが、やはり人が集まると人の問題が起こるようで、これを軽視してはいけないようです。

何か問題が起こるとついつい善悪の境界線を引きそうになりがちですが、**「問題なのは振る舞いであって人ではない」**というのは納得したので、意識したいです。同じような例では「コードを憎んで人を憎まず」とかでしょうか。

[Team Geek](https://www.amazon.co.jp/Team-Geek-―Googleのギークたちはいかにしてチームを作るのか-Brian-Fitzpatrick/dp/4873116309)は、**エンジニアチームに起こりがちな「人の問題」とどう向き合うか？**というのが書かれた本なので、超おすすめです！まとめたのは一部ですが全ページ役に立つ本なので、ぜひお手にお取りくださいー。(回し者じゃないです

最後までお読みいただきありがとうございましたー。

[^引用]: TeamGeek 4章その5「最後に」から全文引用
多項分布とディリクレ分布の解釈メモ

##多項分布の解釈
###条件
試行回数$N$と事象$X_i$が発生する確率$p_i$は決まっている．
（この時，まだ事象は発生していないと考える）

多項分布からは，上記の条件のもと，各事象が何回起きるかをサンプリングできる（$n_i$をサンプリングできる）

###例
試行回数が6，事象が$X_1,X_2,X_3$の３つ，各事象が発生する確率を$1/2,1/3,1/6$とする．
この時，$n_1=3,n_2=2,n_3=1$が最も発生しやすいため，多項分布からサンプリングされやすい．

（だが，$n_1=2,n_2=2,n_3=2$や$n_1=1,n_2=3,n_3=2$なども，サンプリングされる回数は少ないが，サンプリングされることもある．）

##ディリクレ分布の解釈
###条件
各事象が起きる回数$\alpha_i-1$が決まっている．(自分で決める)

ディリクレ分布からは，上記の条件のもと，各事象が起きる確率をサンプリングできる（$\mu_i$をサンプリングできる）

###例
各事象が起きる回数$\alpha_1-1 = 3, \alpha_2-1 = 2, \alpha_3-1 = 1$，(つまり$\alpha-1=6$）とする．
この時，ディリクレ分布からは$\mu_1=1/2,\mu_2=1/3,\mu_3=1/6$が各事象が起きる回数から尤もらしいため，サンプリングされやすい．

（だが，$\mu_1=1/3,\mu_2=1/2,\mu_3=1/6$とかもサンプリングされることがある）


##ディリクレ分布は多項分布の共役事前分布
ベイズ推定より，尤度$p(x|\theta)$を多項分布，事前分布$p(\theta)$をディリクレ分布とすると，事後分布$p(\theta|x)$（$x$という新しい情報が入り，事象が起きる確率$\theta$の分布が更新されている）もディリクレ分布になる．
Kindle書籍すべてをブクログで管理する

ブクログは非常に良いサービスなのですが、Kindle書籍の登録に難があります。ブックマークレットがあったり、ブクログ側で、書籍を探して登録すれば登録されます。

しかし求めているのはそういうことじゃないのです。

購入したら、抜け漏れなく自動で登録されてほしいし、過去に購入した書籍も全部登録したい。ひとつも例外なく。すべてです。

# 今後の購入分

Kindleの購入メールを、HTML形式でメールを送ってもらうように設定します。

* HTML形式なら、Kindle書籍へのURLを含んでいて、URLからASINを切り出すことができるためです。テキスト形式だと、注文履歴へのURLまでで、ASINを切り出せません。
* 設定は、Kindle購入メールの下端に「 HTML形式でのEメール配信をご希望の場合は、以下のURLから設定を変更してください」というのがあるので、リンク踏んで設定。

以下記事を参考にGASを設置して、定期実行させます。

* http://tateren.hateblo.jp/entry/2016/10/03/025425
* https://rela1470.hatenablog.jp/entry/2018/02/05/205140

使うにあたって以下の調整しました。

* カテゴリなしにする
* ログはスプレッドシートに残らなくてよい
* トリガーは、1時間毎に実行とした

元記事は2016年で、ちゃんと動くのか不安だったものの、1冊購入、複数冊購入の両方が期待通り動作しました。すばらしい。

# 過去の購入分

2020年に以下記事が公表され界隈に激震が走りました(たぶん)。

* [Kindle蔵書一覧を取得する方法](https://qiita.com/taka_hira/items/8a9181c0733de2c9f8ee)

この方法で得た情報から ASIN または ISBN をブクログの一括登録ページから登録します。

* [ブクログ - web本棚サービス](https://booklog.jp/input)

# しばらく経過して

過去分はすべて登録できて、追加で購入している分ももれなく登録できていて、たいへん満足しています。

* https://booklog.jp/users/sasasinnet
ぼくがNES.cssから学んだこと(番外編)

本編はこちらになります。
「[ぼくがNES.cssから学んだこと(前編)](https://qiita.com/qei/items/9f18c36552366c881d90)」
「[ぼくがNES.cssから学んだこと(後編)](https://qiita.com/qei/items/895954f09efc945ed9d2)」

## 前回までの記事をアップした後...
[NES.css](https://github.com/nostalgic-css/NES.css)の作者である[ダーシノ](https://twitter.com/bc_rikko)さんよりコメントを頂きまして、以下記事を紹介してくれました。

[box-shadowを使ってCSSだけでドット絵を描き、アニメーションさせる](https://kuroeveryday.blogspot.com/2018/10/draw-and-animate-pixel-art-using-only-css.html)

`box-shadow`を使った描画の仕組みを詳細に解説していたり、ジェネレータコンテンツやアニメーションと幅広く網羅しているのでこちら参考になります。

## ドット絵をCSS手打ちで書くこと
A 「ドッド絵を作れる人がいるんですよ...」
B 「なぁーにーぃ、やっちゃまったなぁ!!」
A 「漢は黙って」
B 「点描ぉぉっ!!」
A 「気が狂いそうだよぉ...」
と、地道にCSS手打ちで書くのもありますが、作りたいドット絵が細かかったりすると位置がずれたりとかして、それなら最初から画像として作りたくなりそうです。

そこで、描いた絵をCSSスタイルとして変換してくれるツールを作りました。
その名も「Shadow Paint Generator」になります。

ダーシノさんも[DotGen.css](https://bcrikko.github.io/css-collection/tool/dotgen/index.html)というジェネレータ系のツールを作っていますので、二番煎じ感になってそうですが後学として自ら作ってみた次第です。

**DEMO**
[Shadow Paint Generator](https://qeita.github.io/ShadowPaintGenerator/index.html)
※Chrome推奨、スマホは未対応です。


このツールには、2つのモードがあります。

- お絵かきツールのようにCanvas上に描いたものを、`color`や`box-shadow`等上述の仕組みを使ってスタイルに変換する**[Paint]**モード
- 既存のドット絵画像をアップロードして、それらをドット絵調にしつつCSSスタイルに変換する**[Capture]**モード

後者の機能は、既存のドット絵や画像を取り込んでCSSとして扱う、もしくはそこからPaintモードで編集するケースも考えられそうだったので用意しました。
ちなみにボタンのUI、ホバーした時に四隅に角のついたラインも`box-shadow`, `color`で作っています。

細かいテストはしていないため動作や出力系で調整が必要そうではありますが、1からCSS手打ちで作る労力は省けそうではあります。
paramikoのコンテキストマネージャのクラス一覧

paramikoを書いてて、毎回`close()`するのめんどくさいので、コンテキストマネージャかどうか調べてみました。

## コンテキストマネージャとは

`with`が使えるオブジェクトのこと  
`__enter__()`と`__exit__()`を持つオブジェクト

## paramikoのコンテキストマネージャのクラス

`paramiko.util.ClosingContextManager`というクラスが定義されており、このクラスを継承していれば、コンテキストマネージャになる

[paramiko.util.ClosingContextManager](https://github.com/paramiko.paramiko/blob/7a8298f5eeea0b0fdd86e87ee2fbc5d8463e882b/paramiko/util#L296-L301)

```python
class ClosingContextManager(object):
    def __enter__(self):
        return self

    def __exit__(self, type, value, traceback):
        self.close()
```

以下のクラスがコンテキストマネージャになっている

- `paramiko.channel.Channel`
- `paramiko.client.SSHClient`
- `paramiko.file.BufferedFile`
- `paramiko.proxy.ProxyCommand`
- `paramiko.sftp_client.SFTPClient`
- `paramiko.sftp_handle.SFTPHandle`
- `paramiko.transport.Transport`

## 参考文献

- [パーフェクトPython (PERFECT SERIES 5) | Pythonサポーターズ, 露木 誠, ルイス・イアン, 石本 敦夫, 小田 切篤, 保坂 翔馬, 大谷 弘喜 |本 | 通販 | Amazon](https://www.amazon.co.jp/%E3%83%91%E3%83%BC%E3%83%95%E3%82%A7%E3%82%AF%E3%83%88Python-PERFECT-5-Python%E3%82%B5%E3%83%9D%E3%83%BC%E3%82%BF%E3%83%BC%E3%82%BA/dp/477415539X)
- [Welcome to Paramiko! — Paramiko documentation](http://www.paramiko.org/)
- [paramiko/paramiko: The leading native Python SSHv2 protocol library.](https://github.com/paramiko/paramiko/)
- [paramikoを使ってsftp - Misc Notes](http://y0m0r.hateblo.jp/entry/20121031/1351692579)
hetzner cloud構成メモ

### hetzner cloud
- https://www.hetzner.com/cloud
- ドイツのホスティングプロバイダhetznerのpublic cloud。なぜかフィンランドにもDCがある。
- isoインストールできるKVM VPSとして使える
- 同EUはフランス・オランダにDCのあるscalewayあたりを意識した価格設定で安価。2GBRAMが2.49EUR/mより。
- Digital Oceanなどと同様、リソースタイプが複数用意され、大抵のリソースが1時間単位で課金される
- プライマリストレージはNVMeとCephストレージを選択して性能と可用性と選択可能
- プライマリのスナップショットは0.01EUR/GB/m。fstrimと圧縮が効くので安価。qemu-guest-agentを入れればオンラインでも取得可能。
- ブロックストレージは10GB 0.4EUR/mから利用可能
- 帯域は20TB/mが付属

日本とのRTTさえ気にならない用途であればテスト環境としていろいろと嬉しい

### 基本構成
- 仮想環境: KVM
- CPU: Skylake以降の命令セットが使える(モデルはマスクされている)
- RAM: プランごと固定
- DISK: プランごと固定サイズのNVMe/Cephの選択制。どちらも同料金。


### ストレージ
ランダムIOはIOPS制限されているように見える。(グラフが提供されていて監視されていることは伺える)

4k random read/write 並行で
- NVMe: 34K/3K IOPSほど
- ブロックストレージ(ceph?): 8K/400 IOPSほど

Seq readは安定しないけれど数100MB/sはでているので実用的に困ることはなさそう。

Cephらしいブロックストレージは/dev/sdb以降にアタッチされる。
マウント関連のスクリプトがcloud-initで提供されているが挙動が怪しい。LVMにactivate任せたほうが楽だろう。

### ネットワーク
VMにグローバルIPアドレスが直接振られるものの、構成が一般的ではない。手動設定か、cloud-initを使う必要がある。

IPv4はDHCPで以下のように通知される。
- /32でグローバルIPアドレス1個
- 172.31.1.1/32 へのホストルートをens3へ
- 172.31.1.1をデフォルトゲートウェイ

このため、debian/ubuntuのインストーラはIP設定が不適切と判定するらしく、DHCP取得に失敗する。上記設定を手動で行うか、インストール後にDHCPを有効化する必要がある。

IPv6はRA/DHCPともに応答が無い。固定IPアドレスで以下のように設定する必要がある。
- /64のグローバルIPアドレス
- fe80::1へのデフォルトルート

cloud-initにはipv6アドレス範囲しか乗っていないので、いずれにせよDHCPv4は有効にする必要があり、v4/v6で非対称になってしまっている。

フローティングIPはv4/v6ともに1EUR/m。これも手動で設定が必要。スナップショットから復元時にVM内部からAPIを叩いて取得するとかしたほうが早そう。

特にファイアーウォール機能はなさそう。

### API・コンソール

hcloud CLIが提供されている。
複数アカウントで共有する「プロジェクト」という単位でVMやリソースを管理可能。

コンソールは大体の機能にアクセス可能。スナップショット取得進捗が出るなどUXは十分に思う。

ISOマウントできるものの、カスタムISOアップロードが提供されていないため、どうしても必要ならrescueでブートしてからネットワークインストールが必要。


### その他
アカウント作成にID要求あり。VATは0%として表示・適用された。

ドイツ語ページは多いもののの英語ドキュメントがあり、現状機能も多くはないので十分。
自分用Javaテキストファイル入出力

##テキストファイルの読み込み
小さなテキストファイルを一度に最後まで読み込む場合は`java.nio.file.Files`の`readAllLines`で読み込める。

```java:Puzzle.java
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.List;

public class Puzzle {
	public static void main(String[] args) {
		try {
			List<String> line = Files.readAllLines(Paths.get(args[0]), StandardCharsets.UTF_8);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}
```

ファイルサイズ不明のテキストファイルを一行ずつ読み込む場合は`java.nio.file.Files`の`lines`で読み込める。
いずれも文字コードを指定できる。
いずれも例外`IOException`を投げるので補足できるようにしておく。
WebAssemblyでカメラをリアルタイムにWebM動画に変換する

生のRGBAバッファをWebMに変換してくれる[webm-wasm](https://github.com/GoogleChromeLabs/webm-wasm)を使いました。

# デモ
Goボタンをクリック時に、カメラをリアルタイムにWebM動画に変換して、そのWebM動画をvideo要素で表示しています。
[chrome://flags/](chrome://flags/#enable-experimental-web-platform-features)から **Experimental Web Platform features** を有効にしないと動きません。Chrome Canaryを使ってください。
[デモ](https://github30.github.io/webm-wasm/demo/transformstream.html)
[ソースコード](https://github.com/GitHub30/webm-wasm/blob/master/demo/transformstream.html)
[![TransformStream webm wasm demo](http://img.youtube.com/vi/D9USwGZxrck/0.jpg)](http://www.youtube.com/watch?v=D9USwGZxrck)


## 1. ワーカーの準備をする

```javascript
    // ワーカーで`webm-wasm.js`ファイルをロードする
    const worker = new Worker("../dist/webm-transformstreamworker.umd.js");
    // `.wasm`ファイルのパスをワーカーに送る
    worker.postMessage("../dist/webm-wasm.wasm");
    // ワーカーの準備が出来るまで待つ
    await nextEvent(worker, "message");
```

## 2. フレームレートや画質などの情報を送る

```javascript
    worker.postMessage({
      timebaseDen: framerate,
      width: value.width,
      height: value.height,
      bitrate,
      // リアルタイムの場合はtrue
      realtime: true
    });
```

## 3. ストリームからRGBAバッファをWebMチャンクに変換する関数を定義する

```javascript
    const webmTransform = (await nextEvent(worker, "message")).data;
```

## 4. ストリームに3.を設定

```javascript
    const webmStream = stream
      .pipeThrough(map(imageData => imageData.data.buffer))
      .pipeThrough(webmTransform);
```

## 5. 動画を表示

```javascript
    const webmMediaStream = mediaSourceStream(webmStream, {
      mimeType: `video/webm; codecs="vp8"`
    });
    const video = document.createElement("video");
    video.src = webmMediaStream;
    document.body.append(video);
    video.play();
```
neovimをdockerにインストールしてpythonの開発環境を構築する

# やりたいこと
dockerを利用してpythonの開発環境を構築する
マシンが変わったときに逐一開発環境を構築するのがめんどうくさいため、
dockerで管理することで構築の手間を省きたい
また、他者と共有する場合でも便利なはず

python以外の開発環境もプラグイン揃えて強化して行く予定です（たぶん）

# 前提
ホストマシンの`/opt/pyenv`にpyenvおよびpyenvのプラグイン`pyenv-virtualenv`がインストールされていること
もしpyenvを利用していない方はDockerファイルのpyenvのPATH設定の部分を適宜変更してください

# Dockerfile
https://github.com/komorin0521/python_ide

上記にアップロードしているのでgit cloneしてください

# build

```
$ docker build -t python_ide .
```
なお、neovimで利用するプラグインの設定は少ないかもしれないので、お好きなものを追加してください

# RUN
```
$ docker run -it --rm -v /opt/pyenv:/opt/pyenv -v /home:/home python_ide $PWD/tmp.py
```

# 特に苦労した点
1. neovimの文字化け
    英語で検索するとneovimのissueに上がっていて解決策にguicursorを空で設定したらいいよって解決策が。めでたし、めでたし。

    https://github.com/neovim/neovim/issues/7049

2. vimにおけるpythonの設定
    neovimクライアントがシステムワイドのpythonにインストールされており、
    仮想環境に切り替わった時点で、neovimがpythonを認識しないという自体に.
    (`:echo has("python")` や `echo has("python3")P の出力が0になる）
    どうやらこれもneovimの設定で利用するPythonシステムワイドの方のpythonに固定を行えば良いとのことで、試してみたらうまくいった！

   [Pythonのvenv環境でneovimを使うときneovimのpython-clientやjediをどうしたらよいか？](https://teratail.com/questions/106798)

# 参考
1. [個人設定込みNeovimのDokcerイメージを作成した](https://qiita.com/succi0303/items/c2c3676f24e48161e6ff)
    ENTRYポイントなどDockerファイルについてはかなり参考にさせてもらいました。

2. [【Python環境整備】脱NeoBundle。超便利補完プラグインjedi-vimの環境をdeinで整えて快適になる設定までやる](https://qiita.com/bookun/items/125beff66e4106f7843c)
    jedi-vimの設定はここのページで記載されている内容を利用させていただきました。

3. [Pythonのvenv環境でneovimを使うときneovimのpython-clientやjediをどうしたらよいか？](https://teratail.com/questions/106798)

4. [https://qiita.com/yoshi65/items/fe1c17d87b3e43f22ef3](https://qiita.com/yoshi65/items/fe1c17d87b3e43f22ef3)
    pythonのテンプレートファイルの読み込みについては上記を参考にしました。
WebAssemblyでCanvasをWebM動画に変換する

生のRGBAバッファをWebMに変換してくれる[webm-wasm](https://github.com/GoogleChromeLabs/webm-wasm)を使いました。

# デモ
Goボタンをクリック時に、Canvasを動的に作成して、WebAssemblyでWebMに変換して、WebM動画をvideoタグで表示しています。
[デモ](https://github30.github.io/webm-wasm/demo/simple.html)
[ソースコード](https://github.com/GitHub30/webm-wasm/blob/master/demo/simple.html)
<p data-height="758" data-theme-id="0" data-slug-hash="vvWwOy" data-default-tab="result" data-user="04" data-pen-title="Simple webm wasm demo" class="codepen">See the Pen <a href="https://codepen.io/04/pen/vvWwOy/">Simple webm wasm demo</a> by John Doe (<a href="https://codepen.io/04">@04</a>) on <a href="https://codepen.io">CodePen</a>.</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

## 1. ワーカーの準備をする

```javascript
// ワーカーで`webm-wasm.js`ファイルをロードする
const worker = new Worker("../dist/webm-worker.umd.js");
// `.wasm`ファイルのパスをワーカーに送る
worker.postMessage("../dist/webm-wasm.wasm");
// ワーカーの準備が出来るまで待つ
await nextEvent(worker, "message");
```

## 2. フレームレートや画質などの情報を送る

```javascript
worker.postMessage({ timebaseDen: framerate, width, height, bitrate });
```

## 3. Canvasを描画し、フレームデータをワーカーに送信

```javascript
    const gradient = ctx.createLinearGradient(
      (1 / 4) * width,
      0,
      (3 / 4) * width,
      0
    );
    gradient.addColorStop(0, "#000");
    gradient.addColorStop(1, "#fff");
    const maxFrames = 2 * framerate;
    for (let i = 0; i < maxFrames; i++) {
      ctx.fillStyle = `hsl(${(i * 360) / maxFrames}, 100%, 50%)`;
      ctx.fillRect(0, 0, width, height);
      ctx.fillStyle = gradient;
      ctx.fillRect((1 / 4) * width, (1 / 4) * height, width / 2, height / 2);
      const imageData = ctx.getImageData(0, 0, width, height);
      // 生の画像データをワーカーに送信
      worker.postMessage(imageData.data.buffer, [imageData.data.buffer]);
    }
    // 全ての画像データを送信したらnullを送信
    worker.postMessage(null);
```

## 4. WebMに変換されるまで待機

```javascript
const webm = (await nextEvent(worker, "message")).data;
```

## 5. 作成したWebM動画を再生
```javascript
    const blob = new Blob([webm], { type: "video/webm" });
    const url = URL.createObjectURL(blob);
    const video = document.createElement("video");
    video.src = url;
    document.body.append(video);
    video.play();
```

### 5.1 またはWebM動画をダウンロード
a要素のdownload属性でダウンロード
> JavaScriptでファイルダウンロード処理を実現する
> https://qiita.com/wadahiro/items/eb50ac6bbe2e18cf8813

GUIからダウンロード
<img width="388" alt="スクリーンショット 2019-01-01 23.08.18.png" src="https://qiita-image-store.s3.amazonaws.com/0/208363/d74a699f-abce-22e6-9cbc-74878f00ea6d.png">
Mac OSにLaravel 5.7を導入する方法

#はじめに
Mac OSにLaravel 5.7のを導入したので、簡単にまとめてみました。

##環境
`Mac OS Mojave version 10.14`
 
##準備するもの
今回準備するものは次の3つです。全て事前にインストールしてしおきましょう。
インストールまだの方は手順をご参照下さい。（バージョンは本記事の執筆時点のものです）

- `Homebrew 1.8.6`
PHPとComposerをインストールするのに使います。※[手順](https://qiita.com/hanio820/items/286e8f6c4d78270ce8c7)
  
- `Composer 1.8.0`
Laravelをインストールするのに使います。※[手順](https://qiita.com/hanio820/items/5145195db34c29476c9e)
 
- `PHP7.2`
Laravelを動かすには、PHPの開発環境が必要です。※[手順](https://qiita.com/hanio/items/cbf876db509e6a427541)

#Laravelとは
そもそもLaravelとは何ぞや。一言で言うと、PHPの高速開発フレームワークです。

Microsoftで.NETの開発に携わっていたTaylor Otwell氏が最初は趣味で作ったものが、そのクオリティの高さにスポンサーが付き、コミュニティーの支援もあり、1年足らずで急速に大きく発展したんだとか。

#Larvelの特徴
あくまで、一般論にはなりますが以下特徴が挙げられます。

- 低い学習コスト
- 導入が容易
- 世界的にも人気上昇中

#他PHPフレームワークとの比較
PHPの代表的なフレームワークには、Laravelの他にもCakePHP、Symfonyなどがあります。

生憎、他のPHPフレームワークを使ったことが無いので、性能面や使い易さといった観点での比較は出来ませんが、注目度の観点で見ると、Laravelは世界的にも注目度の高いフレームワークです。

まず、Google TrendsによるとLaravelが圧倒的な人気を誇る様です。
<img src="https://qiita-image-store.s3.amazonaws.com/0/310353/1c8c9adc-478d-b7ef-490d-aa7154550ce1.png" width=80%>

また、GitHubにおいて、PHPフレームワークの中で、最も多くのGithubStarを獲得しています。（少し古いですが）

<img src="https://cdn-ak.f.st-hatena.com/images/fotolife/M/MasaKu/20171112/20171112005637.png">

#環境構築Step
何となくLaravelの全体感が分かったところで、Laravelローカル開発環境を構築して行きましょう。

[1. Laravelのインストール](1-laravelのインストール)
[2. PATHを通す](2-pathを通す)
[3. Laravelプロジェクトの作成](3-laravelプロジェクトの作成)
[4. 動作確認](4-動作確認)


##1. Laravelのインストール

ComposerでLaravelをインストールします。

```
$ composer global require "laravel/installer"
```
（しばらく待つと完了）


##2. PATHを通す
下記のコマンドでLaravelのPATHを通します。

```
echo export PATH=\"$HOME/.composer/vendor/bin:\$PATH\" >> ~/.bash_profile
```

ターミナルを再起動して、`open ~/.bash_profile`で<b>.bash_profile</b>次の１行が追加されたことを確認。

```
export PATH="/Users/Username/.composer/vendor/bin:$PATH"
```

##3.　Laravelプロジェクトの作成
`laravel new`コマンドで、新規プロジェクトを作成します。

```
$ laravel new {任意のプロジェクト名}
```

しばらく待ちます。最後に以下の記述が表示されればOKです。

```
Package manifest generated successfully. 
Application ready! Build something amazing.
```

##4.　動作確認

`cd（カレントディレクト）コマンド`で、作成したアプリケーションのディレクトリーに移動します。

```
$ cd {任意のプロジェクト名}
```

`$ php artisan serve`コマンドで、ローカル開発サーバーを起動します。

```
$ php artisan serve
Laravel development server started: <http://127.0.0.1:8000>
```


ブラウザで`http://127.0.0.1:8000`にアクセスします。

![](https://camo.qiitausercontent.com/a241cf6f74d296c53bd9258187055955d6ffde2d/68747470733a2f2f71696974612d696d6167652d73746f72652e73332e616d617a6f6e6177732e636f6d2f302f3234363834352f37616232306262342d316535372d373236622d316137382d3438366261616134666139652e706e67)

上記のLaravelスタート画面が表示されれば成功です。
git の使い方メモ

gitの概念すら曖昧な状態の今。

脳内整理のために書く。

・ローカルディポジトリに持ってきて（プル）作業して、変更したものをリモートディポジトリに反映（プッシュ）。
・ブランチはどんどん増えていく。加えた変更ごとにブランチを作る

・git init
 リポジトリを作る

・git add .
 全体のファイルをリポジトリに反映

・git commit
 viエディタでコメント入れる

・git branch
全てのブランチと今いるブランチを示す

・git checkout hoge
 今いるブランチからhogeに移動

・git branch hoge
 ブランチを新しく作る

・git checkout -b hoge
 ブランチを新しく作り移動する
MacのPostgreSQLアンインストール方法

# キッカケ

pgAdmin4だけアップグレードすると起動の度に警告が表示されるように。一度、PostgreSQLを再インストールしたいが、やり方が分からなかったので、メモとして残す事にしました。

```bash
open /Library/PostgreSQL/9.6/uninstall-postgresql.app
```

このコマンド実行だけではデータなどはされませんでした。
全て削除する場合は、アカウント削除などが必要で大変そうでした。
今回は、PostgreSQLの再インストールが目的なので逆に助かりました。
pgAdmin4を起動しても警告が出ずに無事に完了。

# References

+ [Uninstall PostgeSQL – Full Removal Guide for Mac Users](https://nektony.com/how-to/uninstall-postgesql-on-mac)
+ [PostgreSQL Download](https://www.enterprisedb.com/downloads/postgres-postgresql-downloads)
【cp -r/ rm -rf】ディレクトリ毎コピー/削除する[LINUX]

#**はじめに**
ディレクトリ毎コピー、削除する場合、オプションを指定する必要があります。
今回は、備忘録としてまとめておきます。

#**コピー/削除**

###**任意のディレクトリ以下をすべてコピー**
`cp`コマンドに`-r`オプションを付けて用いる。

```
$ cp -r original_dir/ next_dir/ 
```

###**ディレクトリ毎削除**
`rm`コマンドに`-rf`オプションを付けて用いる。

```
$ rm -rf original_dir
```

#**おわりに**
こちらの記事が役に立ったという方は、いいね、お願いします(^^)
deviseをいろいろカスタマイズする

# この記事でやりたいこと

deviseに下記のカスタマイズを加える。

* 新たなカラムを追加する
* userページを作成する

# 新たなカラムを追加する

## migartion

## Strong Parametersの設定も

deviseでは自動的にStrong Parametersの設定がされているため、新しいカラムを設定する場合、こっちの設定もしないと弾かれます。Strong Parametersについては下記が詳しい。簡単に言うと指定したparams以外を弾くようにする仕組みです。

https://qiita.com/mochio/items/45b9172a50a6ebb0bee0

ドキュメントはここ

https://github.com/plataformatec/devise#strong-parameters

modelの追加は普通に行い、下記を記述してStrong Parametersを許可する。

```ruby:ApplicationController
class ApplicationController < ActionController::Base
  before_action :configure_permitted_parameters, if: :devise_controller?

  protected

  def configure_permitted_parameters
    devise_parameter_sanitizer.permit(:sign_up, keys: [:username])
  end
end
```

# userページを作成する

マイページみたいなものを作ろうとした場合、できないわけではないのですがuser/配下でdeviseがいろいろ自動的に作っているのでuser/〜でルーティング設定する場合はそことバッティングしないように気をつけないといけません。

```
$ rake routes
```

でルーティングを調べてdeviseで使われていないことを確認してそこにルートを設定するようにしましょう。
git ignoreを後から

Unityの開発だと、だいぶローカルでコミットしたあと、プッシュしようとしたら、
アセットとかのめちゃ重いファイルコミットしてて、100mb以上でプッシュできませんよーと
言われること・・。
昔の状態まで戻すのは大変すぎるし、でも後から.gitignoreを編集しようとしても、
結局コミット段階に書いてないので、既にコミットしてしまっている。
そんなとき！！

```$ git rm --cached hoge.tmp```

https://qiita.com/yuuAn/items/b1d1df2e810fd6b92574

こちらの記事がより詳細です。
＝＝＝

と思ってたら、もっと難しかった件！

```git filter-branch --force --index-filter  'git rm --cached --ignore-unmatch libBulletPhysics.a' --prune-empty --tag-name-filter cat -- --all```

このコマンドを打ったのち、ほにょほにょしないといけないそうです。

https://qiita.com/aucfan-engineer/items/a1c2bdb9ec2109fc93bc
numpyのarangeとreshapeをよく忘れるので個人的メモ

![alt](https://user-images.githubusercontent.com/26253721/39765058-e8d0eae4-531b-11e8-9305-4c852f269517.png)
## arange

以下の記事から切り出しただけの個人メモ
https://deepage.net/features/numpy-arange.html

np.arrangeは、連番や、同差配列を生成する関数です。
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
のような配列を生成します。

```
numpy.arange([start, ]stop, [step, ]dtype = None)
```

```
パラメータ名
start = (省略可能)生成するとうさ配列の最小の項を設定します。
stop = 生成する等差配列の終点を指定します。
step = (省略可能) 初期値１　生成される数列一つ一つの項間における差を指定します。(公差)
```

例
```
import numpy as np
arr1 = np.arange(5)
arr1 #=> array([0, 1, 2, 3, 4])
bar = np.arange(2, 10, 2)
bar => array([2, 4, 6, 8])

なるほど。

## reshapeの-1
reshape = 要素数が変わらない範囲でndarrayの形状を変更することが出来る。
特に-1を引数に取るときの挙動を忘れるのでメモ。
第一引数が−１の時は、「第二変数の長さ」の配列を複数生成する。
つまり、
z = np.array([[1, 2, 3, 4],
         [5, 6, 7, 8],
         [9, 10, 11, 12]])
z.reshape(-1)
array([ 1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12])
z.reshape(-1, 1)
array([[ 1],
   [ 2],
   [ 3],
   [ 4],
   [ 5],
   [ 6],
   [ 7],
   [ 8],
   [ 9],
   [10],
   [11],
   [12]])
z.reshape(-1, 2)
array([[ 1,  2],
   [ 3,  4],
   [ 5,  6],
   [ 7,  8],
   [ 9, 10],
   [11, 12]])

-1が第二引数の時は、列と行が反対になる。
z.reshape(3, -1)
array([[ 1,  2,  3,  4],
   [ 5,  6,  7,  8],
   [ 9, 10, 11, 12]])


若いもんにはまだまだ負けん。
Rubyをソースからコンパイルするときの依存ライブラリ

`rbenv install`等でソースからコンパイルする場合、依存ライブラリおよびそのヘッダーをOSにインストールしておかないと標準ライブラリの一部がコンパイル出来ません。コンパイル出来なかった標準ライブラリはそのまま無視されて、Ruby本体のインストールまで終わってしまいます。インストールが終わって、いざ使おうとしたときに入ってなかったと言うことがないように各ライブラリについて依存ライブラリを調べました。

2.6.0で調査しています。古いバージョンでは標準ライブラリやバンドルされているソースが異なるため、必要な依存ライブラリも異なりますので注意してください。

|Rubyライブラリ|依存ライブラリ|備考|
|---|---|---|
|bigdecimal| | |
|cgi/escape| |cgiの一部|
|continuation| |非推奨|
|coverage| |実験的|
|data_core| |dateの一部|
|dbm|ndbm|互換ライブラリ可※|
|digest| | |  
|etc| |Windowsでは制限あり|
|fcntl| | |
|fiber| | |
|fiddle|ffi| |
|gdbm|gdbm| |
|io/console| | |
|io/nonblock| | |
|io/wait| | |
|json/ext/\*| |jsonの一部|
|nkf| |nkfのソースがバンドル|
|objspace| | |
|openssl|openssl| |
|pathname| | |
|psych| |yamlのソースがバンドル|
|pty| |UNIX/Linuxのみ|
|racc/cparse| |racc/parserの一部|
|rbconfig/sizeof| |rbconfigの一部|
|readline|readline| |
|ripper|bison|コマンドとして必要|
|sdbm| | |
|socket| | |
|stringio| | |
|strscan| | |
|syslog| |UNIX/Linuxのみ|
|win32/resolv| |Windowsのみ|
|win32ole| |Windowsのみ|
|zlib|zlib| |

※dbmが使用するndbm互換ライブラリは下記の通りです。

|ライブラリ|検索ヘッダー|説明|
|---|---|---|
|libc|"ndbm.h"|ndbm compatible library in libc.|
|db|"db.h"|Berkeley DB (libdb)|
|db1|"db1/ndbm.h", "db1.h", "ndbm.h"|Berkeley DB (libdb1)|
|db2|"db2/db.h", "db2.h", "db.h"|Berkeley DB (libdb2)|
|db6|"db2/db.h", "db2.h", "db.h"|Berkeley DB (libdb6)|
|db3|"db2/db.h", "db2.h", "db.h"|Berkeley DB (libdb3)|
|db4|"db2/db.h", "db2.h", "db.h"|Berkeley DB (libdb4)|
|db5|"db2/db.h", "db2.h", "db.h"|Berkeley DB (libdb5)|
|gdbm_compat|"gdbm-ndbm.h", "gdbm/ndbm.h", "ndbm.h"|GDBM since 1.8.1 (libgdbm_compat)|
|gdbm|"gdbm-ndbm.h", "gdbm/ndbm.h", "ndbm.h"|GDBM until 1.8.0 (libgdbm)|
|qdbm|"qdbm/relic.h", "relic.h"|QDBM (libqdbm)|
|ndbm|"ndbm.h"|Some legacy OS may have libndbm.|

bisonを除き、ライブラリ自体だけでは無くヘッダーが必要です。ライブラリのパッケージだけでは無く、ライブラリ開発のパッケージが必要になります。Ubuntu 18.04LTSであれば、次のようにインストールすれば良いでしょう。

```shell
$ sudo apt install build-essential bison libffi-dev libgdbm-dev libgdbm-compat-dev libreadline-dev libssl-dev zlib1g-dev
```

なお、Ruby本体にはコンパイル可能な環境であること以外に依存ライブラリは無かったはずです。

---

以下はメモです。

* 古いバージョンに含まれるcursesやtcl/tkはそれぞれライブラリが必要です。
* 古いバージョンではyamlのソースがバンドルされておらず、libyamlが必要かも知れません。
* Ubuntu 18.04LTSで2.3系以下をインストールする場合は、libssl1.0-devパッケージが必要です。このパッケージはlibssl-devと排他です。
Gitの初期設定と基本的な確認用コマンド



# 初期設定

```
# 個人情報の設定
git config --global user.name <ユーザ名>
git config --global user.email <メールアドレス>

# エイリアスの設定 （コマンドに別名をつける、お好みで）
git config --global alias.<コマンドの別名> <コマンド>

# 以下、エイリアス設定例
git config --global alias.co checkout
git config --global alias.st status
git config --global alias.br branch
git config --global alias.ci commit
```

`~/.gitconfig`に直接書いても設定できます。


# 確認用コマンド

### git status : 変更状況の確認

```
git status                       　# 全て
git status <ファイル名orディレクトリ名>  # 指定ファイルorディレクトリのみ
```

### git diff : 差分の確認

```
# ワークツリーとステージの差分
git diff                       　# 全て
git diff <ファイル名orディレクトリ名>  # 指定ファイルorディレクトリのみ

# ステージとリポジトリの差分
git diff --staged                       　# 全て
git diff --staged <ファイル名orディレクトリ名>  # 指定ファイルorディレクトリのみ
```

### git log : 変更履歴の確認
```
git log                       　# 全て
git log <ファイル名orディレクトリ名>  # 指定ファイルorディレクトリのみ

git log -n <取得数>     　# 最新のn個のみ
git log --numstat      　# ファイルごとの追加削除した行数
git log -p            　 # 変更差分を表示

git log --oneline　　　　　    # １行表示
git log --graph        　# グラフ形式
git log --decorate     　# ブランチ、タグ名を追記

# 組み合わせると見やすく表示できたりする
git log --oneline --graph --decorate
```
C++ Template and generic programming

C++ Templage and generic programmingの論文を検索。

IEEE Explore
https://ieeexplore.ieee.org/Xplore/home.jsp

C++ Templage generic
で検索。 72件。

一覧
https://researchmap.jp/jo04h18mt-1797580/#_1797580

参考文献の一覧作成中。

https://researchmap.jp/jozq2yey7-1797580/#_1797580

１０件中、citeceerxに原文があったもの１件。
researchgateに原文があったもの３件。
researchgateに参考文献があったのも３件
researchgateに参考文献がなかったもの２件。

Abstracting the Template Instantiation Relation in C++

```c++
template <typename P> struct extract_policies {
typedef typename P::type type;
};
template <typename... P> struct wrap_policies {
typedef policies<P...> type;
};
template <typename... P> struct wrap_policies<
policies<P...>> {
typedef policies<P...> type;
};
template <typename P> struct normalize_policy {
typedef typename mp::eval_if<
typename is_derived_policy<P>::type,
extract_policies<P>,
wrap_policies<P>>::type type
};
template <typename T, typename P>
class vector<T, P> : public vector_base<
T, typename normalize_policy<P>::type
> { };
```

Extension of Iterator Traits in the
C++ Standard Template Library

```c++
template <class T>
struct iterator_traits
{
typedef typename T::iterator_category
iterator_category;
typedef typename T::value_type
value_type;
typedef typename T::difference_type
difference_type;
typedef typename T::pointer
pointer;
typedef typename T::reference
reference;
typedef
__non_inserting_iterator_tag
inserter;
};
```

Dynamic Verification of C++ Generic Algorithms

# 作業中の資料

CPP Template Generic
で検索した文献の参考文献を一覧にして、surveyをかけるように資料を整理中。
ひとまず平に一覧表示し、年代順に並べ直し、関連の深いもの半分に減らす予定。

## PDF:
https://researchmap.jp/muo9gs7b1-45645/?action=multidatabase_action_main_filedownload&download_flag=1&upload_id=227625&metadata_id=25961

## TEX:
https://researchmap.jp/mutrupk4o-45645/?action=multidatabase_action_main_filedownload&download_flag=1&upload_id=227648&metadata_id=25961


# 参考文献(reference)
参考文献駆動執筆(reference driven writing)
https://qiita.com/kaizen_nagoya/items/b27b3f58b8bf265a5cd1

# 文書履歴(document history)
ver. 0.01 初稿　20181231
ver. 0.02 作業中の資料、参考文献、文書履歴追記 20190101
WebアプリにおけるJSPの役目【Java】


# Webアプリケーションとは
本記事では、Webアプリの作成において度々紹介される<font color="red">JSP</font>を簡単に説明します。

WebアプリケーションとはWebサーバ上で動作するアプリケーションのことです。
日常生活にWebアプリケーションは欠かせないものとなりました。
例えばWebブラウザを通じて、通販で買い物をしたり、ニュースを読んだりできますが、あれらのサービスはWebアプリケーションという形で提供されたシステムです。

# Webアプリの仕組み
Webアプリは大きく分けると、①Webブラウザ、②ネットワーク、③Webサーバの３つから構成されます。
まず、ユーザはWebブラウザを操作しながらネットワークを介して、自分が受けたいサービスのWebサーバへアクセスします（ユーザがWebサーバにアクセスすることをリクエストといいます）。そしてWebサーバがWebブラウザにレスポンスをネットワークを通じて返します。
    <img src="https://qiita-image-store.s3.amazonaws.com/0/245072/1e81e32f-9708-80e6-91d5-2120d8f0fc8e.png" width=60%>



# JSPの役割
JSPはWebサーバ上で動作するJavaプログラムのことです。その役割は<font color="red">画面表示</font>です。
JSPにJavaプログラムを記述することは可能ですので、画面表示以外の機能を持たせることは可能です。
しかし画面表示以外の機能はServletと呼ばれるファイルに任せることが一般的です。
ファイルの種類ごとに役割分担を明確にすることで、保守性が上がります。
PostgreSQLメモ

PostgreSQLについての学習

# インストール

## Windows

### Windows Server2016+PostgreSQL9.6.11

「postgresql-9.6.11-1-windows-x64.exe」を実行したら以下のエラーが表示され、インストールできなかった。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/187121/8ac3496a-3c5c-1e8d-cf41-05d7a41d55aa.png)


とりあえず「–-install_runtimes 0」オプションを付けるとインストールができた。

## Linux

### 1-1.インストールの準備

https://yum.postgresql.org/repopackages.php

OSの種類、バージョンとPostgreSQLのバージョンを確認してダウンロードして

### 1-2.インストール(RHEL6)
```sh
yum install postgresql96-server
```
依存関係もある以下もインストールされる。
postgresql96
postgresql96-libs

### 1-3.アンインストール(RHEL6.9)

```sh
yum remove postgresql96-libs
```
依存関係があるので、postgresql-serverも削除される。

### 1-4.インストールされているものの確認

```sh
yum list installed | grep postgres
```

# 2.起動と停止

## Linux

## 2-1.サービス起動
RHEL6(psql96)
初回のみinitdbが必要

```sh
service postgresql-9.6 initdb
service postgresql-9.6 start
```
initdbを行わないと以下のようなエラーになる。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/187121/c08838a3-a9e8-6a57-0bca-fbd88d531a29.png)
initdbを行うと、「/var/lib/pgsql/9.6/data」にファイルが作成される。


## 管理者で接続
psql -U postgres
rootユーザのシェルから接続すると以下のエラーが発生する。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/187121/054fe793-a725-8390-6510-433e9f73fa58.png)
peer認証とは「Peer認証とは、カーネルからクライアント上のシステムユーザ名を取得し、PostgreSQLデータベースユーザと同一である場合のみ接続が許可される仕組み」で、パスワード入力が不要。
pg_hba.conf(/var/lib/pgsql/9.6/data/にある)を編集し、パスワード入力で接続できるようにする。

## pg_hba.confファイルの編集
認証方式をpeerから変更する。
認証方式のドキュメント
https://www.postgresql.jp/document/9.6/html/auth-methods.html

### データベースの作成
create database testdb;


### ユーザの作成
create role testuser with login password 'testpassword';

### ユーザで接続
psql -U testuser -d testdb

#RHEL7

インストール

```sh
wget https://download.postgresql.org/pub/repos/yum/9.6/redhat/rhel-7-x86_64/pgdg-redhat96-9.6-3.noarch.rpm
rpm -ivh pgdg-redhat96-9.6-3.noarch.rpm
yum install -y postgresql96-server
/usr/pgsql-9.6/bin/postgresql96-setup initdb
systemctl start postgresql-9.6.service
```

テスト用のデータベースとユーザーの作成

```sh
su - postgres
psql
```

```sql:SQL
create database testdb;
create role testuser with login password 'testpassword';
```

テスト用ユーザーで、テスト用DBに接続

```text
-bash-4.2$ psql -U testuser -d testdb
psql: FATAL:  ユーザ "testuser" で対向(peer)認証に失敗しました
```
RakWireless WisLink Cellular BG96  STM32 キットを作ってみたよ

RakWireless WisLink Cellular BG96を入手しました。

BG96はCat.M1/NB-IoT通信モジュールで、LTE-MとNB-IOTが使えます。
https://www.softbank.jp/biz/mobile/solution/m2m/product/bg96/
このボードにはこのBG96とGPSが載っているArduino Shieldになります。

![WisLink-1.jpg](https://qiita-image-store.s3.amazonaws.com/0/285344/bfe89b31-fd7f-b221-26cb-8594baf9beab.jpeg)

元々はRenesas　Synergy用のAE-CLOUD2向けに作られたもののようですがArduino用のピンが出ています。
http://docs.rakwireless.com/en/Cellular/WisLink-Cellular/Hardware_Specification/WisLink-Cellular_RAK2011_Product_Brief.pdf

SeedStudioからはWio LTE M1/NB1(BG96)が出ていますが、Groveコネクタのみで、汎用GPIOが使えません。
RakWireless WisLink Cellular BG96はArduino準拠ですから、汎用GPIOが出ています。
今回は、手元に大量にあるSTM32のNucleoとのセットを考えてみましょう。
P-L496G-CELL02に近い構成となるようにCortex-M4である、NUCLEO-F401REを選択してみました。

P-L496G-CELL02
https://www.st.com/ja/evaluation-tools/p-l496g-cell02.html

STM32L496AG ：P-L496G-CELL02
ARM Cortex-M4 MCU 80 MHz 1 Mbyte Flash
STM32F401RE ：NUCLEO-F401RE
ARM Cortex-M4 MCU 84 MHz　512 Kbytes Flash
(キャッシュの容量が小さいなどグレードダウンとなります）

ちなみに、NUCLEO-L476RGは ARM Cortex-M4 80 MHz 1 Mbyte Flashと言うことでかなり似た構成になります。
こっちの方が良いでしょうね。

![WisLink-2.jpg](https://qiita-image-store.s3.amazonaws.com/0/285344/e87512db-8017-cb81-c264-ca330a204a28.jpeg)
![WisLink-3.jpg](https://qiita-image-store.s3.amazonaws.com/0/285344/75b8f1ba-869c-0591-f49c-a829e7ecc7af.jpeg)

接続は、RX,TXをシリアルで叩けば反応するようです。
https://github.com/RAKWireless/WisLTE_Arduino

SIMの設定は別途USBでやるようです。
https://www.rakwireless.com/en/download/Cellular/WisLink-Cellular#Tools
QCOM_Vxx.zipをDLして、設定するようです。

アドオンとしてセンサーボードなりを用意すれば完璧ですね。
【自分用】Goメモ　画像のアップロード

自分用に。
簡単なメモ。

#### 画像をアップロードするときに使えるメソッド。

##### ■import
import (
  "net/http"
  "io"
  "io/outil"
)

r.FormValue('hiddenで指定したname')

//html上で<input type="file">のnameを引数に入れてバイト列を取得。
//このときのformタグはenctype="multipart/form-data"
r.FormFile('filename')

//outilのReadAll()でFormFileで取得したファイルを読み取り返す。
outil.ReadAll(FormFileで返ってきたmultipart.File)

//WriteFileを使って取得したデータをファイルに書き込み
io.WriteFile('ファイルの名前', ReadAll()で取得したデータ, perm uint32)

#### 参考
https://www.oreilly.co.jp/books/9784873117522/
http://golang.jp/pkg/io-ioutil
https://golang.org/pkg/net/http/#Request.FormFile
Qiitaでいいねをつけないための努力｢いいねの壁｣とは？

# いいねの壁

- ユーザーの興奮度、感動レベルが80ポイントを超えると、いいねが付く｢いいねの壁｣｢いいねホライゾンライン｣のようなものがあると仮定する
- 人の興味関心、ユーザー単位のいいね沸点にもよるが、ユーザーの心が｢いいね！｣と感動したときに、はじめていいねが付くと仮定する
- もし自分の記事が誰の心の79ptも超えなければ、いいねが付くことは決してない、低い温度ではいくらヤカンを沸かしても、水がお湯になって沸かないように

# 80pt未満を狙い続ける

- 自分が渾身の力で書いてしまうと、いいねが1個でも付いてしまう可能性があるので、80%ぐらいの力で書く
- 自分が80%ぐらいの力で書くということは、人から見ると40%ぐらいの低品質な記事に見えるかもしれない
- こうして、いいねが付く沸点からはかなり遠ざかることが出来る

# いいねとは何なのだろうか…？

- 2進数のゼロイチのように、単にオンオフがつく、わりと絶壁のシステム
- 年末のモノマネ番組みたいに、必ず1点から10点をつけるシステムであれば、この｢いいねの壁｣は平準化されそうな気はする (あれって8点9点10点しか付きませんが‥)
- 仮に我々の脳髄に電波系をつけて、興奮度などを判定するデバイスがあれば、より定量的に否定せざる｢いいね｣が観測できるはずであるけれども、というようなことをたまに空想する‥閑話休題

---

- ところでMediumでは拍手システムがあって、1拍手から50拍手までを自由段階でつけられるようになっているので
- このいいねの絶壁からは少しだけ進んでいるが
- それでも｢そもそも、いいねをつけないユーザー｣と｢つけるユーザー｣｢つける記事｣｢つけない記事｣の圧倒的な差はそのまま残る

---

https://github.com/YumaInaura/YumaInaura/issues
https://github.com/YumaInaura/YumaInaura/issues/146








<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->