OmniAICreator/Qiita-1.07M huggingface dataset:
【RSpec】modelのscope

## ごあいさつ & はじめに

本日より、株式会社OCEAN GATEのイッカツ開発チームの一員として、Qiitaにどんどん記事を投稿していきます！

今はまだプログラミング初心者ですが、業務で学んだことをアウトプットしていきます！</br>
よろしくお願いします！

さて、本題に入ります。

modelにはscopeという、クエリをまとめられる書き方があります。</br>
そのscopeのテストの書き方を学んだのでまとめていきます。

## scopeのテスト

- model

```rb:models/place.rb
scope :deleted, -> { where(is_deleted: true) }
```

上記の`place.rb`の`deleted`に対し、次のようにSpecを書けます。

- spec

```rb:spec/models/place.rb
describe 'scope' do
  describe 'deleted' do
    let!(:place) { create(:place) }       # --①
    subject { Place.is_deleted }          # --②
    it { is_expected.to include place }   # --③
  end
end
```

ここで何をしているかを説明していきます。
①では、FactoryBotを使ってplaceのデータを作成しています。

②では、modelに書かれている`is_deleted`scopeをPlaceモデルに使っています。</br>
　そして、subjectとして設定しています。

③では、②のsubjectの配列が、①のデータの配列を含んでいることをテストしています。
　`include`はマッチャです。

非常にスッキリとしています！

## belongs_to のアソシエーションがある場合
`belongs_to`というアソシエーションがあるときのテストの書き方でかなり悩みました。

そのため、その内容も書いていきます。


- model

```rb:models/ornament.rb
belongs_to :place
scope :place_ornaments, -> (place_id) { where(place_id: place_id) }
```

今回は、placeにひもづくornamentモデルを使っていきます。

- spec

```rb:spec/models/ornament_spec.rb
describe 'place_ornaments' do
  let!(:place) { create(:place) }                      # --④
  let!(:ornament) { create(:ornament, place: place) }  # --⑤
  subject { Ornament.place_ornaments(place.id) }       # --⑥
  it { is_expected.to include ornament }
end
```

④では、FactoryBotを使ってplaceのデータを作成しています。
　そうしないと、ornamentが作れないためです。

⑤では、ornamentのデータ作成時に④の`place`を渡しています。
この`place:`を使えるの？と思うかもしれません。

実は、FactoryBotで定義していれば使えるのです！

```rb:spec/factories/ornaments.rb
factory :ornament do
  place
end
```
ornamentは`place_id`を持っているので、FactoryBotにはplaceが必要になります。

そのplaceに、④のplaceを渡しておけばbelongs_toのあるscopeのテストも実行できます。

## scopeで変数を使っている場合
上記の`place_ornaments`では、`place_id`が引数として渡されています。</br>
そのため、引数を指定しないとこのscopeが使用できません。

そこで、⑥のように、`place.id`をscopeの後に渡してあげればscopeを使用できるようになります。

## おわりに
このようにscopeのテストは意外と簡単に書けてしまいます！
テストはこわくない！

## 参考

[RspecでModelに定義したScopeのテストを書いてみる](https://kossy-web-engineer.hatenablog.com/entry/2019/08/02/215130)

[使えるRSpec入門・その2「使用頻度の高いマッチャを使いこなす」](https://qiita.com/jnchito/items/2e79a1abe7cd8214caa5)
DevLOVE300 Journey 参加備忘録

# はじめに
オンライン開催になった [DevLOVE300 Journey](https://devlove.doorkeeper.jp/events/102926)に参加しました。
3時間という長丁場だったので途中集中が途切れたり、諸々家事をしたりしていて、
話の記憶が途切れ途切れですが、備忘録を残します。

```text
300回目の再会と、新たな旅立ちをともに！
2008年6月21日より始めたDevLOVEは実に300回目を迎えるに至りました。

1回目は、2008年12月17日 DevLOVE Bridge から、
100回目を、2012年12月15日 DevLOVE 2012Conference で、
200回目を、2017年6月18日 DevLOVE200 Bridge でそれぞれ迎えました。
300回目は、2020年3月7日 DevLOVE300 Journey です。

これまで数々のDevLOVEを重ねてきました。2008年にたった2人からはじめた時、まさかこのコミュニティが12年続き、300回を数えることになるとは想像もしていませんでした(100回目を越えたあたりで既に想像を越えてきています)。ふと考えたことがあります。「この旅はどこへたどり着くのだろうか？」と。

もう、とっくにたどり着いているといえるでしょうし、まだまだ旅の途中にあるとも言えます。この旅がどこに向かい、いまどこにあるのかは、DevLOVEに関わった人たちそれぞれによって異なります。コミュニティの役割とは、そうしたそれぞれの旅の途中にある人たちがひと所に集まる「理由」を作り出すことにあるように思います。

ときに同じ旅程を行き、またときに別れ、それぞれの旅を続ける。立ち止まるときも勿論あるし、また誰かと再び歩み始めることもある。そうやって私たちは、向かいつづけているのです。コミュニティとは、約束してなくても再会ができる場所。300回目の再会と、新たな旅立ちを。むかえましょう。

この場作りに力を寄せてくださった人たちに感謝を込めて。
300回目は、ファウンダが務めさせていただきます。
```

# 本編
[第1部と第4部の資料](https://speakerdeck.com/araitakeshi/devlove300falsedui-tan-di-1bu-todi-4bu)
[第2部と第3部の資料](https://speakerdeck.com/araitakeshi/devlove300falsedui-tan-di-1bu-todi-4bu)

第1部と第4部は対談、第2部と第3部は講演でした。

全体を通して、一番印象に残った言葉は
**「不確実性とは回避するべきものなのか」** です。

不確実性に対応するというのうが(おそらく)エンジニアリング組織論からワードとして定着して、
プロジェクトにおいてエンジニアは不確実さや分からないことを嫌がることが多いです(と思います)が、
全て回避していたらそれはつまらない道しか進めないのかもなと思いました。

あとは、ともに考え、正しく作るためにはどういうプラクティスがあるかの紹介ですが、
そこは今まで自分たちの当たり前と思っていることに対しての問いかけに溢れていました。

# まとめ
イベントに参加してみて一番大きかったのは、
プロダクト作りをもっと上手に不確実性に立ち向かって行こうと思えたことです。
あとは、「正しいものを正しく作る」を読もうと思います。
AtCoder Beginner Contest 158(A~D) どう解くか

#A Station and Bus
**理解できる部分を抜き出す**
と,下記のようになります.
>AtCoder 市には3つの駅があり、
>それぞれ鉄道会社A, Bのいずれかが管理しています。
>鉄道会社 A が管理している駅と、鉄道会社 B が管理している駅の間には、
>交通の便のためにバスを運行することになりました。
>実際にバスが運行することになる駅の組み合わせが存在するかどうかを判定してください。

組み合わせが存在する = A,B両社が管理する駅が存在する
{A,A,B},{A,B,A},{A,B,B},{B,A,A},{B,A,B},{B,B,A}の6通り

A,Bあり得る組み合わせはA,B２社^3駅で8通りなので、残りの2通りを探す方がコード短縮できる.

```c++
//A Station and Bus
#include <iostream>
using namespace std;
int main(void){
  string S;
  cin >> S;
  if(S=="AAA" || S=="BBB"){
    cout << "No";
  }else{
    cout << "Yes";
  }
  return 0;
}
```

#B - Count Balls
>根気のある高橋君は、次の操作を10^100回繰り返します。

面白い言い回しですね.今回の問題では私はこれを無限回として捉えました.
例えばA=B=1だった場合,青と赤のボールが交互に,無限に続くと仮定して問題なし.
A=3,B=4だったら,青のボール3個と赤のボール4個の**グループ**が続くわけです.

回答（青のボールの個数）を数える際は,下記のように考えられる.
①先頭からN個のボールに,**グループ**がいくつ含まれるか計算
②①の結果に一つの**グループ**が含む青ボールの数を掛ける.
 ※(N/(A+B))*A;の部分が該当

③あとはあまりの部分が,Aより多いなら回答にAを足す
 Aより少ないならあまり数(N%(グループのボール数))だけ足す

```c++
//B - Count Balls
#include <iostream>
using namespace std;
 
int main(void){
  long long int N, A, B;
  cin >> N >> A >> B;
  
  long long int ans=0;
  ans += (N/(A+B))*A;
  if(A<(N%(A+B))){
    ans+= A;
  }else{
    ans += N%(A+B);
  }
  cout << ans;
  return 0;
}
```
#C - Tax Increase
商品の税抜き価格**X**が存在するとき,以下の２式が成立すればOK
ただし,integer型の割り算やキャストを使って小数点は切り捨て.
・X*0.08=A
・X*0.1=B

この式を逆算してXを求めたいところですが,**小数点切り捨て**の問題が大きく
逆算が難しくなるだろうと予測するのがポイント.

ここではXを1からインクリメントしながら評価していく.
そんな事をすると計算量・計算時間は大丈夫かと心配しますが大丈夫.
1<=A<=B<=100のため,Xは1000強くらいまでしか上がらないから.

```c++
//C - Tax Increase
#include <iostream>
using namespace std;
 
int main(void){
  int A, B;
  cin >> A >> B;
  
  for(int i=0; i<10000; i++){
    if((int)(i*0.08)==A && (int)(i*0.1)==B){
      cout << i;
      return 0;
    }
  }
  cout << "-1";
  return 0;
}
```

#D - String Formation
問題文の通りにクエリを実行していては,処理が時間内に終わらない.
正直に処理していると時間をくう処理は下記の二つ
①文字列の反転
②文字列の前に文字を入れる処理
 (その度に文字全体の保存場所をずらす処理が発生)

①は反転フラグをしかけて,最後に反転することで解消.
②は文字列の前後に入るものを別管理して,最後にくっつける事で改善.

##コードの前に少し余談
ここにきて,**includeするライブラリを変えた**.
\<iostream>　→ \<bits/stdc++.h>
stringとかvectorとか,色々と一緒にインクルードしてくれて便利である.
コンパイル時間まで気にするレベルに達していないなら,使う価値はあるはず.
おそらく中身は下記記事のようになっている.

[AtCoderなどの競プロでよく使われる #include <bits/stdc++.h> を導入する](https://qiita.com/flowerrr__lily/items/28a20062e957fa10b7a7)

```c++
//D - String Formation
#include<bits/stdc++.h>
using namespace std;
 
int main(void){
  string S, front="", back="";
  int Q, D, F;
  char C;
  cin >> S;
  cin >> Q;
  bool rev = false;

  //①クエリの処理
  for(int i=0; i<Q; i++){
    cin >> D;
    if(D==1){//反転フラグ変更
      rev = !rev;
    }else if(D==2){//front,またはbackに文字追加
      cin >> F >> C;
      if(rev){
        if(F==1){
          back = back+C;
        }else if(F==2){
          front = front+C;
        }
      }else if(!rev){
        if(F==1){
          front = front+C;
        }else if(F==2){
          back = back+C;
        }
      }
    }
      
  }

  //②フラグの処理
  reverse(front.begin(),front.end());//frontは順番逆なのでreverse
  S = front + S + back;              //frontとbackの結合
  if(rev)reverse(S.begin(), S.end());//フラグに応じて全体を反転
 
  cout << S;
  return 0;
}
```
Flask-RESTPlus から Flask-RESTX に移行した

# 結論

- Flask-RESTPlus はメンテナンスを止めるもよう、今後も使い続けるならその fork である Flask-RESTX がよさそう
- 既存コードに関しては`flask_restplus` を `flask_restx` に置換するだけで動作はした
- config の設定を反映するためにはパラメータ名も変更が必要だった

# きっかけ

ちょっとした Web API サーバを Flask で開発していて、API の仕様を Flask-RESTPlus を使って Swagger ドキュメント化していた。ここ1ヶ月ほど Flask 側の開発は落ち着いていて触ってなかったのだが、ちょっとした修正を加えて動作を確認しようとするとエラーが発生。

ログを確認すると werkzeug のパッケージでコケている。修正箇所近辺ではなくそもそもレベル。

```bash
../../../../.pyenv/versions/3.6.9/envs/testenv/lib/python3.6/site-packages/flask_restplus/fields.py:17: in <module>
    from werkzeug import cached_property
E   ImportError: cannot import name 'cached_property'
```

たしかにこの１ヶ月ほどの間に諸事情で手元の virtualenv をいちど削除していて、今回の修正のタイミングで再作成していた。pip の requirements.txt でパッケージを入れ直しているが、バージョン依存関係で何か発生している可能性はある。

# 調査

## 原因
ググったら Github の issue がヒット。これっぽい。
[flask-restplus is broken by Werkzeug 1.0.0 #777](https://github.com/noirbizarre/flask-restplus/issues/777)

Werkzeug が2020年の2月上旬にバージョン 1.0.0 になった際に `cached_property` が `werkzeug` の下から `werkzeug.utils` の下に移動。`flask_restplus` は `cached_property` をインポートして利用してる箇所があったので上記のようなエラーが発生したもよう。
Flask のパッケージ依存関係には `Werkzeug>=0.15` という書かれ方をしているので、ゼロから pip のモジュールたちをインストールすると Werkzeug のメジャーバージョンアップの影響をうける、という。

## Flask-RESTX を知る

改めて [Flask-RESTPlus の Github ページ](https://github.com/noirbizarre/flask-restplus) の README.md を見ると先頭に以下のような記述が。2020年の1月上旬頃に追記されている。

> **IMPORTANT NOTICE**:
> 
> This project has been **forked** to `Flask-RESTX <https://github.com/python-restx/flask-restx>`_ and will be maintained by by the `python-restx <https://github.com/python-restx>`_ organization. **Flask-RESTPlus should be considered unmaintained**.

もう Flask-RESTPlus はメンテしないよ、fork である Flask-RESTX が今後はメンテされるよ。とのこと。

# Flask-RESTX の利用

## 使ってみる
Werkzeug のバージョンを手動で下げればいいのだろうけど、もうしばらく開発は続くしな、と思い Flask-RESTX を試してみることに。Flask-RESTX のページをみる限り、使い方は Flask-RESTPlus とほぼ同じでよさそうな印象。ということで単純置換でとりあえず動かしてみた。コードはこんな感じ。

```python:flask_restplus
from flask_restplus import Namespace, fields, Resource
from flask_restplus.namespace import HTTPStatus
```

```python:flask_restx
from flask_restx import Namespace, fields, Resource
from flask_restx.namespace import HTTPStatus
```

これだけでとりあえずエラー出力することなく動作するようになった。
Flask-RESTX は PyPI の最新である 0.1.1 を利用。これには werkzeug (<=0.16.1) という制限が書かれているので、よろしく pip のパッケージを再インストール等すれば問題が解消する感じ。

Github の最新コードを確認したところ、import の書き方も修正して Werkzeug 1.0.0 で大丈夫になっているもよう。いずれ PyPI にもこのバージョンが反映されることを期待。

## もう少し細かい確認

config で設定をデフォルトか少し変えていたのだけれど、これもさすがに dict のキー名を変えないと設定の反映はされなかった。 これも `RESTPLUS_` を `RESTX_` に変えるだけなので機械的でよいのは助かる。

```python:flask_restplus
app.config['RESTPLUS_MASK_SWAGGER'] = False
app.config['RESTPLUS_JSON'] = {'ensure_ascii': False}
```

```python:flask_restx
app.config['RESTX_MASK_SWAGGER'] = False
app.config['RESTX_JSON'] = {'ensure_ascii': False}
```
ftpでレンタルサーバーにテキストファイルをアップロード

ラズパイで温湿度データをテキストファイルに保存することができたので、
今度はそれを定期的にレンタルサーバーにアップできるかどうか、試してみた。

ちなみに自分が試したレンタルサーバーは、
「スターサーバー フリー」だった。
問題なくアップロードできた。

```python
import ftplib
def ftp_upload(filename):
  ftp = ftplib.FTP('サーバーのホスト名')
  ftp.set_pasv('true')
  ftp.login('ユーザー名','パスワード')
  ftp.cwd('/rp/')
  f = open(filename,'rb')
  ftp.storbinary('STOR ' + filename, f)
  f.close()

ftp_upload('data.txt')
```

こういう温湿度データのような、一定時間ごとにずっと溜まっていくテキストデータというのは、
テキストファイルではなく、MySQLで管理をしていった方がいいのだろうか？
Jetson Nanoを使って画像解析に挑戦

# Jetson Nanoについて
jetson Nanoは画像の分類、オブジェクトの検出、セグメンテーション、および音声処理のようなアプリケーションにおいて複数のニューラル ネットワークを並列に実行できる、小型なコンピューターとなっている。また、様々な機能がわずか20ワットの消費電力で稼働が可能となっている。

# 目標
Jetson Nanoにカメラを取り付け、そのカメラから取得した画像を解析しその結果をWebページに表示することを目標とする。

# 使用するもの
- Jetson Nano
- keres 2.2.5
- django 3.0.4
- tensorflow 1.14.0
- OpenCV v3


# 実装
簡単に実装してみる
先ずテキトーにモデル作成
Colaboratoryで学習させておく

```
import os

from keras.applications.mobilenet_v2 import MobileNetV2
from keras.preprocessing.image import ImageDataGenerator
from keras.callbacks import EarlyStopping, ModelCheckpoint

SIZE = 224
BATCH_SIZE = 256
EPOCH = 300

generator = ImageDataGenerator(
    rescale=1.0/255,
    horizontal_flip=True,
    brightness_range=(0.8, 1.0))
train_generator = generator.flow_from_directory(
    directory="resized",
    target_size=(SIZE, SIZE),
    batch_size=BATCH_SIZE,
    seed=0
)
num_classes = train_generator.num_classes

model = MobileNetV2(
    input_shape=(SIZE, SIZE, 3),
    alpha=0.5,
    weights=None,
    classes=num_classes)
model.compile(
    loss='categorical_crossentropy', optimizer="Adam", metrics=['accuracy'])

es = EarlyStopping(monitor="loss", patience=10)
best_path = "best.hdf5"
mc = ModelCheckpoint(best_path, monitor="loss", save_best_only=True)

history = model.fit_generator(
    train_generator,
    epochs=EPOCH,
    verbose=1,
    callbacks=[es, mc]
)
model.load_weights(best_path)

output_model_path = "/content/drive/My Drive/Colab Notebooks/best.hdf5"
model.save(output_model_path)
```

サンプルの人物準備
ここからjetson nanoのdjangoプロジェクト内の処理(views.py)

```
CLASSES = [
    'Aaron Eckhart',
    'Abhishek Bachan',
    'Adam Sandler',
    'Adriana Lima',
    'Alberto Gonzales',
    'Alec Baldwin',
    'Alex Rodriguez',
     .....
    ]
```

画像処理

```
from django.shortcuts import render
from keras.applications.mobilenet_v2 import MobileNetV2
import cv2
import numpy as np

def index(request):
    # モデルの読み込み
    model = MobileNetV2(
        input_shape=(224, 224, 3),
        alpha=0.5,
        weights=None,
        classes=201
    )
    model.load_weights("/home/hogehoge/django_prj/django_app/deep_learning/best_weights.hdf5")

    # 画像取得とリサイズ
    capture = cv2.VideoCapture(0)
    ret, frame = capture.read()
    frame = np.array(frame)[:, 280:1000]
    img = cv2.resize(frame, (224, 224))
    array = np.array(img).reshape(1, 224, 224, 3)

    # 予測
    pred = model.predict(array)
    alike = CLASSES[np.argmax(pred)]

    # 取得画像の保存
    cv2.imwrite("/home/hogehoge/django_prj/django_app/static/face_cnn/result.jpg", img)

    context = {"result":alike}
    return render(request, "face_cnn/index.html", context)
```


# 結果
カメラから画像取得
![IMG_9597.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/588477/795feae5-869c-6700-ba5e-9b3a6efc0a54.jpeg)

結果画面
ノートpcのwebブラウザで確認
<img width="960" alt="無題.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/588477/07fdb82c-6a30-2f00-b918-ef39f67daf99.png">

Faith Hillと判定、、、
あれ、Faith Hill？

今後は精度を上げていきたいなー


# 参考
- [モダン AI のパワーを数百万のデバイスへ - NVIDIA Jetson Nano]
(https://www.nvidia.com/ja-jp/autonomous-machines/embedded-systems/jetson-nano/)
Xamarinを勉強し始めたので覚えたことを記録するメモ

#はじめに
Xamarinを使ってマルチプラットフォーム開発をやってみたくなったので、勉強したことを記録として残す（徐々に追記）

## Xamarinとは
iOS | Android | Windows など複数のプラットフォームで動作するアプリをC#を使って構築することができるライブラリ

- Xamarin.iOS
- Xamarin.Android

を導入すると、iOSとAndroidのマルチプラットフォーム開発ができる。例えばVisual Studioに導入すれば、ついでにUWPアプリも作れる。

## Basic Class Library
各プラットフォーム間で共通的に使えるライブラリ。
基本的には、このライブラリを使ってアプリを構築し個別の対応が必要なものについて、個々のプラットフォームのライブラリを使うことで共通化を目指すようだ。

## iOS版のアプリについて
やはりiOS版のアプリについてはMacとXcodeが必要であった。
Mac上のiOSシミュレータは`Xamarin.iOS Build Host`によりペアリングすることでWindows上のVisual Studioから起動できる。

## プロジェクトの構造
(プロジェクト名).iOSや.Android配下には固有のUIレイアウトとロジックを配置する。各プラットフォーム専用にUIを作成することにより、そのプラットフォームのユーザに適した操作感のアプリを提供できる。
(プロジェクト名)配下には各プラットフォームで共通とするものを配置する。アプリケーションのコアロジックなどがこれに該当する。

注意）
iOS部分のUIはInterface Builderを使用してstoryboardにXML形式で保存したものを使用する。
Railsで複数の環境を同時に走らせる方法

# この記事について
Railsにはデフォルトでdevelopment, test, productionの３つの環境が用意されていますが、今回はそれらに加えて

1. 独自の環境を定義する
2. 複数の環境を同時に走らせる

方法を書いてみます。使っているOS, Sever, Railsのバージョンは以下の通りです。

> CentOS Linux release 7.6.1810 (Core)
Server version: Apache/2.4.6 (CentOS)
Phusion Passenger: 5.3.5
Rails 5.1.7

# 独自環境を定義する
`config/environments`以下に `<new env>.rb` というファイルを新しく作ります。`<new env>`の中身は定義したい環境の名前に置き換えてください。内容は特にこだわりがなければ`production.rb`のコピペでいいと思いますが、`relateive_url`の設定は新しい環境のパスに合わせて変更しておきましょう

```rb
Rails.application.routes.default_url_options = { host: 'localhost', port: 3000, relative_url_root: '/<new env>' }
config.relative_url_root = "/<new env>"
```

続いて、`config`フォルダ内の以下のファイルに新しい環境の設定を追加しましょう。書き方はすでに登録されている３つの環境を見ながら書けば、問題ないです。

+ config/cable.yml
+ config/database.yml
+ config/secrets.yml (`$bundle exec rake secret`であらかじめキーを生成しておく)
+ config/settings.yml

使っているアプリによってはほかにも設定ファイルを定義しているかもしれません。その場合はそのファイルも同様に更新します。

最後に、本番環境用にデプロイする場合はアセットをプリコンパイルしておきましょう

```
$bundle exec rake assets:precompile RAILS_ENV=<new env>
```

# データベースの作成
新しい環境用にデータベースを作成します。DBのユーザー名やパスワードは設定ファイルで定義されたものが使われます。


```
$bundle exec rake db:create RAILS_ENV=<new env>
$bundle exec rake db:migrate RAILS_ENV=<new env>
```

# Passenger への登録
ここまでできたら、次はpassengerに新しい環境のURLを登録します。編集するのは`/etc/httpd/conf.d/<app name>.conf` というファイルです。以下の３つの項目を追記します。

```
 <Location /<new env>>
    PassengerRuby /usr/local/rvm/gems/ruby-2.4.1/wrappers/ruby
    PassengerHighPerformance off
    PassengerBaseURI /
    PassengerAppRoot /var/www/<new env>
    RailsEnv <new env>
</Location>

Alias /customenv /var/www/<new env>/public
    
<Directory /var/www/<new env>/public>
    Allow from all
    Options -MultiViews
    # Uncomment this if you're on Apache >= 2.4:
    Require all granted
</Directory>
```

ディレクトリのパスをすでに登録されているものと別のものにしないといけないので`$ln <old env> <new env>`などして、シンボリックリンクを作成し、便宜上パスを別物にしておきます。

# デプロイ
apacheを再起動しましょう。

```
$sudo apachectl restart
```

先ほど定義したパスでアプリケーションをリクエストすると、正常に起動しているはずです
一度アクセスした後であれば`$passenger-status`で新しい環境がデプロイされていることが確かめられます。
おすすめアプリ mac

## 注意
無料のアプリのみ紹介していますが、値段は記事を書いた時のものです。
自己責任でお願いします。
# アプリ
## resolutionator
Macの解像度を上限以上にするアプリ
3360x2100まで設定できる。
## Google Chrome
今までは、Firefoxを使っていたのですが、QuantamになってからVimiumが使えなくなったため、chromeに乗り換えた。
## Twitter
macのtwitter公式アプリが出たので、tweetdeckから乗り換えた。
## HyperSwitch
Command+Tabのアプリ切り替えを拡張する
## CopyClip
クリップボードの履歴を見れる
## SourceTree
git管理
## Atom
エディタ。
## LanScan
ネットワーク内の機器をスキャンできる。
raspiに繋ぐ時に、よく使う。
## YT Music
音楽。
Spotifyから乗り換えた。
## Docker
dockerをguiで管理できるアプリ
## Cyberduck
FTPクライアント
## Slack,Discord,Skype
チームコミュニケーションツール
## Dash
スニペット。今日プロの時に使う
## SimpleNote
ノートアプリ。
Windowsと同期できて、便利。
## LINE
lineのmac版
## Hotspot Shield, windscribe, protonvpn
VPN接続アプリ。全て容量制限があるので、4つ使っている。
## Karabinder elements
キーカスタマイズ。
これがないと、pcをまともに使えない。
## TownWifi
自動でwifiに繋がり、ログイン不要の便利アプリ。
## justcolorpicker
webデザインに使うカラーピッカー。
## download shuttle
分割ダウンロード
ambientから最新データを取得してGmailでメール送信

※pythonでgmailを送るには、下準備が必要。
「python gmail」で検索すると方法が出てくる。

```python
# -*- coding: utf-8 -*-
import smtplib
from email.mime.text import MIMEText
from email.utils import formatdate
import ssl
import datetime


#ambientから最新データ取得（ここでは日付、温度、湿度）
import ambient
import json
am = ambient.Ambient(ID,"ライトキー")
d = am.read(n='1')
DATA_NEW =  "Date:" + str(d[0]['created']) + "\n"
DATA_NEW += "Temperature:" + str(d[0]['d1']) + "C\n"
DATA_NEW += "Humidity:" + str(d[0]['d2']) + "%\n"


'''
dt_now = datetime.datetime.now()
NOW_DATE = dt_now.strftime('%Y年%m月%d日 %H:%M:%S')
'''

#メール作成
FROM_ADDRESS = 'gmailアドレス'
MY_PASSWORD = 'googleパスワード'
TO_ADDRESS = 'データを受け取るメールアドレス'
BCC = ''
SUBJECT = 'メールタイトル'
BODY = DATA_NEW



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


def send(from_addr, to_addrs, msg):
    #context = ssl.create_default_context()
    smtpobj = smtplib.SMTP_SSL('smtp.gmail.com', 465, timeout=10)
    smtpobj.login(FROM_ADDRESS, MY_PASSWORD)
    smtpobj.sendmail(from_addr, to_addrs, msg.as_string())
    smtpobj.close()


if __name__ == '__main__':

    to_addr = TO_ADDRESS
    subject = SUBJECT
    body = BODY

    msg = create_message(FROM_ADDRESS, to_addr, BCC, subject, body)
    send(FROM_ADDRESS, to_addr, msg)
```
【JavaScript】同期処理と非同期処理

##同期処理とは
同期処理では上から下へとプログラムが記述されたとおりに実行されます。
処理1、処理2、処理3と順に実行され、処理2や3は前の処理が終わるまでは絶対に実行されません。
処理と処理の間には待ち時間が発生します。




##非同期処理とは
非同期処理ではプログラムの記述順と処理順は異なります。

```javascript
console.log('処理1')
setTimeout(()=> console.log('処理2'),3000)
console.log('処理3');
```

```:実行結果
処理1
処理3
処理2
```
上記の例では実行結果が上から下の順で処理されていないことが確認できます。
処理の流れとしては、以下のようになります。

⒈console.log('処理1')がキューに登録される（処理1が表示される）
⒉setTimeout()がキューに登録され、タイマーにconsole.log('処理2')が登録される
⒊console.log('処理3')がキューに登録される（処理3が表示される）
⒋2の3000ミリ秒後にconsole.log('処理2')がキューに登録される（処理2が表示される）

1から3までは順に（同期的に）キューに登録されます。
その後、setTimeout()が実行されたタイミングに（非同期的に）4が行われます。
DockerでMongoDB

ローカルでMongoDBを使ったアプリを開発する際に、dockerを使うと便利.

## docker-compose

開発環境で利用する `docker-compose.dev.yaml` を準備する.

### Port

mongodbのデフォルトのポートは `27017` だが、コンテナ外からアクセスするためにローカルの `27018` をポートフォワードしておく.

### Volumes

* `./mongo/db:/data/db` `./mongo/configdb:/data/configdb` はデータの永続化に必要.
* `./mongo/init:/docker-entrypoint-initdb.d` にデータベースの初期化のための `.js`ファイルを入れておく. 後述.


### Environment

* MONGO_INITDB_ROOT_USERNAME: rootユーザの名称
* MONGO_INITDB_ROOT_PASSWORD: rootユーザのパスワード
* MONGO_INITDB_DATABASE: コンテナ作成時に初期化されるデータベース 

```dokcer-compose.dev.yaml
  mongo:
    container_name: mongo
    restart: always
    image: mongo:4.2.0
    ports:
      - "27018:27017"
    volumes:
      - ./mongo/db:/data/db
      - ./mongo/configdb:/data/configdb
      - ./mongo/init:/docker-entrypoint-initdb.d
    environment:
      MONGO_INITDB_ROOT_USERNAME: <root_user_name>
      MONGO_INITDB_ROOT_PASSWORD: <root_password>
      MONGO_INITDB_DATABASE: <database_name>
      TZ: Asia/Tokyo
```

## 初期データ

`.js` か `.sh` を `./mongo/init` 以下に置いておくことで、初期データが投入される.  
以下の記事にてそれぞれのファイルが読み込まれる仕組みが詳述してあります.
https://qiita.com/homines22/items/038dc08fca6405813e0b

### 認証用ユーザの作成

docker-composeで立ち上げたmongoコンテナに、ローカルからアクセスするユーザを作成する. 
ユーザはアクセスできるデータベースが割り当てられている.（authenticationDatabase）

```1-mongo-init.js

var users = [
  {
    user: "<user_name>",
    pwd: "<pass_word>",
    roles: [
      {
        role: "dbOwner",
        db: "<db_name>"
      }
    ]
  }
];

for (var i = 0, length = users.length; i < length; ++i) {
  db.createUser(users[i]);
}
```

### Jsonファイルのインポート

ユーザデータだけでなく、手元のJsonデータを適当なcollectionに投入しておきたいケースもある.

```2-mongo-init.sh
mongoimport --db <db_name> --collection <collection_name> --drop --file /docker-entrypoint-initdb.d/<your_json.json> --jsonArray
```

* `--drop` オプションをつけることで、実行時に対象のcollectionが存在した場合にそれを削除して初期データを投入する.
* `--jsonArray` オプションをつけることで、array形式になっているJsonファイルも読み込める. （insertManyする感じ.）

## コンテナ外からのアクセス

作成されたユーザを使って、以下のコマンドでローカルのターミナルからmongoに入れる.

```bash
$ mongo -u <user_name> -p --port 27018 --host 127.0.0.1 --authenticationDatabase <db_name>
```
Pythonの__dict__の使われ方

#目的
Pythonで、**\_\_dict\_\_の使い方が、よくわからなかった。**
いい例をみかけたので、
示す。


#__dict__の使われ方
以下のサイトで、
**\_\_dict\_\_**を使って、
len 関数を引数に取ることができるオブジェクトの一覧
の調べ方が示されていた。

https://python.ms/len/#_1-len-の考え方

```
>>> builtin_sized_types = []
>>>
>>>
>>> for val in __builtins__.__dict__.values():
...     if isinstance(val, type):
...         if hasattr(val, '__len__'):
...             builtin_sized_types.append(val)
...
>>> print(*builtin_sized_types, sep='\n')
```

実行結果

```
<class 'memoryview'>
<class 'bytearray'>
<class 'bytes'>
<class 'dict'>
<class 'frozenset'>
<class 'list'>
<class 'range'>
<class 'set'>
<class 'str'>
<class 'tuple'>
>>>
```




#今後
ちょっと、慣れないとこんな感じでは、使えませんが。。。
勉強にはなった気がする。
アドバイスなどあればお願いします。
【jupyterlabインストール】jupyterlabインストールしようとしたら、Dead kernelエラーが出る。

# 注意
この、記事で起きたいかなる問題も、筆者は責任を負いません。
自己責任でお願いします。
# 目次
 - jupyterlabインストール
 - jupyter用rubyインストール
 - jupyterlabインストール

```
pip install jupyterlab                                                                                              
jupyter serverextension enable --py jupyterlab --sys-prefix
sudo jupyter lab --allow-root
```

これで、問題なく実行までできました。
rootなしだと、エラーが出たのですが、rootにするとエラーが解消されました。
## jupyter用rubyインストール

```
sudo gem install iruby
iruby register
sudo jupyter notebook --allow-root
```
ってやると、立ち上がり、rubyが選択できます。
これで、rubyが使えるようになります。
### なりません。
エラーが出てしまいます。
[![https://gyazo.com/1116b15b41f967d9369dcacfe9926323](https://i.gyazo.com/1116b15b41f967d9369dcacfe9926323.png)](https://gyazo.com/1116b15b41f967d9369dcacfe9926323)

### 😭
ネットで、検索してみたところ、zeromq,czmqが原因のようです。

```
brew uninstall --ignore-dependencies zeromq
brew uninstall czmq
brew install zeromq --HEAD
brew install czmq --HEAD
sudo gem install cztop
sudo gem install specific_install
sudo gem specific_install https://github.com/SciRuby/iruby.git
iruby register --force
```
これで、解決したはずです。

```
sudo jupyter notebook --allow-root
```
[![https://gyazo.com/a7ddaefd8f8e1f7f4dde969ec746ab9c](https://i.gyazo.com/a7ddaefd8f8e1f7f4dde969ec746ab9c.png)](https://gyazo.com/a7ddaefd8f8e1f7f4dde969ec746ab9c)

labでもできます。

```
sudo jupyter lab --allow-root
```

できました。
最後まで、ありがとうございました！
OpenBlocks IoTを工場出荷時に戻す手順のメモ

[OpenBlocks IoT](https://www.plathome.co.jp/product/openblocks-iot)ファミリのBX1を、工場出荷時の状態に戻す手順（**ファクトリーリセット**という）を調べたので、自分の作業用にメモする。

# シリアル接続
BX1とWindows端末を、USB-UART変換ケーブルで接続し、シリアル通信ができるTeraTermなどのターミナルソフトでコンソールにログインする。ボーレートやデータビットの設定は下図の通り。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236222/788535e9-8b1c-3ceb-8b2e-465565965d97.png)

# Wi-Fiの設定
BX1のWi-Fiには、Client Mode（既存Wi-Fiネットワークに接続）と AP Mode（BX1自体がアクセスポイントになる）がある。一般のWi-Fiルータと同じだ。
工場出荷時のファームウェアをダウンロードしたいので、Client Modeでインターネットに接続する。

## パスフレーズをPSKで暗号化

```:コマンド
wpa_passphrase [SSID] [パスフレーズ]
```

```:標準出力
network={
    ssid="[SSID]"
    #psk="[パスフレーズ]"
    psk=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
}
```

## ネットワークの設定
上述のSSIDと暗号化キーを設定する。

```:/etc/network/interfaces
auto wlan0
iface wlan0 inet dhcp
    wpa-ssid [SSID]
    wpa-psk XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    wpa-ap-scan 1
    wpa-key_mgmt WPA-PSK
    wpa-proto WPA RSN
    wpa-pairwise CCMP TKIP
    wpa-group CCMP TKIP
```

## NICの再起動

```
ifdown wlan0 && ifup wlan0
```

# ファームウェアのダウンロード
[ぷらっとホーム社のサイト](https://www.plathome.co.jp/software/factory-reset-ex-bx-fw2-1)に、**Intel Edison** の最新カーネルに対応するファームウェアのイメージデータがあるのでダウンロードする。

```sh
cd /root
wget http://ftp.plathome.co.jp/pub/BX1/wheezy/3.10.17-17/bx1_userland_web1.0.14-1.tgz
```

なお、どのBX1のバージョンをダウンロードすれば良いかは、Web UI の出力で確認する。

```sh
curl -sL localhost:880 | grep Version
```

# RAMディスクモードで起動
BX1には、ストレージを使わないRAMディスクモードと、ストレージを使うストレージ併用モードがある。
`df`コマンドの表示で、`/.rw`にマウントされているのが、`/dev/mmcblk0p10`ならストレージモード、`tmpfs`ならRAMディスクモードということになる。

```sh
e2label /dev/mmcblk0p10 ""
reboot
```

リブート後は `root`/`root` でログインする。

# ファームウェアを置くパーティションをフォーマット

```sh
yes | mkfs -t ext4 -L DEBIAN /dev/mmcblk0p10
sync
```

# 工場出荷イメージの展開
３分ほど掛かる。

```sh
mount /dev/mmcblk0p10 /mnt
tar zxf /root/bx1_userland_web1.0.14-1.tgz -C /mnt 2> /dev/null
umount /mnt
rm -f /root/bx1_userland_web1.0.14-1.tgz
```

# ストレージ併用モードで起動

```sh
e2label /dev/mmcblk0p10 DEBIAN
reboot
```

# Wi-Fiに接続できない場合
**Debian GNU/Linux** からWi-Fi接続できない場合、Intel Edison の組み込みLinuxである **Yocto Linux** から接続する。 

PCとシリアル接続し、次の操作を行う。

1. 電源を落とした状態にする
1. INITスイッチを押しながら電源スイッチを押し続け、LEDが一瞬点滅したら電源スイッチを離す

```
******* PSH loader *******
PCM page cache size = 192 KB
Cache Constraint = 0 Pages
Arming IPC driver ..
Adding page store pool ..
PagestoreAddr(IMR Start Address) = 0x04899000
pageStoreSize(IMR Size)          = 0x00080000

*** Ready to receive application ***
```

と表示されたら、スペースキーを連打し、bootプロンプトになったら、次のコマンドを入力。

```
boot > run bootYocto
```

デフォルトの低消費電力モードではシリアルコンソールの１文字目を取りこぼす場合があるため、シリアル通信の電源を常時ONにする。

```
echo on > /sys/devices/pci0000:00/0000:00:04.3/power/control
```

既存Wi-Fiに接続する。

```
wpa_passphrase [SSID] [パスフレーズ] > /etc/wpa_supplicant/wpa_supplicant.conf
wpa_supplicant -i wlan0 -c /etc/wpa_supplicant/wpa_supplicant.conf &
udhcpc -i wlan0
```
初心者から始めるJava、入れ子・break・continue

#はじめに
この記事は備忘録である。
参考書レベルの内容だが、本記事に掲載するコードについては、
**間違えた**ものが中心となる。これは実際にコーディング中に間違えた部分を掲載し、自分で反省するために投稿するという目的によるもの。
また、後日にJavaSilver試験問題の勉強を兼ねて復習するため、深い部分の話はここでは触れない。

##環境
言語：Java11、JDK13.0.2
動作環境：Windows10

#入れ子
マトリョーシカ人形を見たことがあるだろうか。サイズが違う相似の物体をたくさん重ねたものだ。ここで扱う入れ子は**制御構造のネスト（入れ子）**である。
`if` `for` `while`の文が。処理の中にまた制御構造を内包する状態になっており、二重ループ・三重ループなど階層的な処理を行うのに向いている。

##break
`break`自体は`switch`文のときに触れたが、入れ子の後で説明するなら**「今処理しているネスト（入れ子）を中断し、上位のループに入る」**動きになる。仮に無限ループに入っていたとしても、break文の条件を満たせば抜けることが出来る。
以下、参考の**黒本**からの引用

> ```java:breakの使用例
int num = 0;
while(true){
  num++;
if(num == 3){
  break;
}
System.out.println(num);
}
```

##continue
`continue`は`break`とよく間違えるのだが、**`continue`した場合は`continue`以下の繰り返し処理を丸ごとスキップして更新文に移行する**。
continueの実例は後日追記。思いついたコードがどれもコンパイルエラーでうまくいかなかった。特に練習が必要だ。

#実践
失敗例を見てみよう。

```Java:nestingTwo.java
class nestingTwo
{
    public static void main(String[] args)
    {
        int forLoop = 0;
        int whileLoop = 0;
        //合計回数は9回のはず

            for(; forLoop < 3; forLoop++){
                while(whileLoop < 3){
                    whileLoop++;    
                }
            }
        System.out.println("処理は終了しました。");
        System.out.println("最終結果は、for文が" + forLoop + "回、While文が" + whileLoop + "回でした。"); 
        }
            
    }



/* 処理は終了しました。
   最終結果は、for文が3回、While文が3回、合計で3回、でした。 */
```
`whileLoop`はforの入れ子内で一度3になった後は条件を満たしており、forが一度回っただけでそれ以降の変更がなされていない。
forの回数×whileの回数　にするため、今回はこうした。

```Java:after
(省略)
        int totalCounter = 0;
        //合計回数は9回のはず
        int whileLoopTemporary =0;
        
            for(; forLoop < 3; forLoop++){
                while(whileLoop < 3){
                    whileLoop++;    
                    totalCounter++;
                    whileLoopTemporary = whileLoop;
                }
                whileLoop = 0;
            }
        System.out.println("処理は終了しました。");
        System.out.println("最終結果は、for文が" + forLoop + "回、While文が" + whileLoopTemporary + "回、合計で" + totalCounter + "回、でした。"); 
        }
            
    }

```
while内でたまった回転数を逃がす`whileLoopTemporary`を作り代入し、後からfor文内で`0`に初期化している。
もっとスマートな方法があるはず。
#終わりに

ラベルという、**ラベルを張った処理へ制御を移す**機構もあるようだが、ここでは割愛。どこかで見た`go to`と同じものだろうか。

#参考
出来るだけ自分で変数や式を書いてコンパイルしているので、完全に引用する場合はその旨記述する。

[やさしいJava 第7版](http://mana.on.coocan.jp/yasaj.html)
[Java SE11 Silver 問題集](https://book.impress.co.jp/books/1118101186)（通称黒本）
【GitHub】Milestone, Issue, Pull Requestを関連付けて扱う

## この記事は
GitHubの次の機能を関連付けて扱う方法について書いた記事です。

- Milestone
- Issue
- Pull Request

大まかな流れは次の通りです。

- **Milestone**を設定し、その中に**Issue**を作成
- 作成した**Pull Request**に**Issue**を紐付け、**Pull Request**が閉じると同時に**Issue**も閉じる

特に転職活動用に個人開発でオリジナルアプリを作っている方は、これをやっておくと**擬似チーム開発経験ができ、面接で強いアピール材料になります**のでぜひトライしてみてください。

## 1. Milestoneの設定

その名の通り、マイルストーン（開発期限）を設定します。
「〇〇プロジェクト」とか「〇〇アプリの開発」とかですね。

画像左上のIssuesのタブを開き、**Milestones**をクリックします。
<img width="600" alt="スクリーンショット_2020-03-07_21_25_08.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/465401/a09ff749-df19-0676-ab29-29c25e2897c6.jpeg">

**New milestone**か**Create a Milestone**をクリックします（どちらも同じ）。
<img width="600" alt="スクリーンショット_2020-03-07_21_27_08.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/465401/a5881e72-2848-2f84-e053-659691f13e68.jpeg">

Title(タイトル）、Due Date（期限）、Description（説明）を記入し、**Create milestone**をクリックします。
<img width="600" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/465401/948a04f2-f4eb-91d5-7371-07a3eb1de3d1.jpeg">

これでMilestoneは完成です。
<img width="600" alt="スクリーンショット 2020-03-07 21.30.26.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/465401/26fbddf6-5bec-c187-d944-e6ce5822bbcb.png">

## 2. Issueの作成
先ほどの画面から、**New Issue**をクリックします。
![https___qiita-image-store_s3_ap-northeast-1_amazonaws_com_0_465401_11a441b5-eef6-b96d-e5be-ae43d673df8d.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/465401/aa17cb74-9d3c-0d8f-5029-1a48b25b1ecf.jpeg)

Issueの作成画面になり、右枠のMilestoneが先ほど作ったものに設定された状態になっています。

名前とコメント（任意）を記入し、**Submit new issue**をクリックします。
名前は、Issueなので〇〇機能とか〇〇作成などが一般的かと思います。
<img width="600" alt="スクリーンショット_2020-03-07_21_39_14.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/465401/119d675c-eee2-e3d1-a3c1-6f98ed37e69d.jpeg">

ちなみに別画面からIssueを作成し、Milestoneを後から付けたい場合は、次のようにMilestoneの歯車マークから選択して付与することができます。
<img width="600" alt="スクリーンショット_2020-03-07_21_35_48.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/465401/ac36e8d9-fd3f-d719-8704-cf3732414734.jpeg">

## 3. Pull RequestとIssueを紐付ける
ローカルで変更を加えたブランチをリモートリポジトリにプッシュすると、GitHub上に次のような表示が現れます。
この**Compare & pull request**をクリックすると、プルリクエストの作成画面になります。
<img width="600" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/465401/7cdeff7e-0135-71c4-33de-3cff80c7e9c4.jpeg">

プルリクエストの作成画面において、まずは送り元と送り先を確認します。
下の画像だと、**compare:xxブランチからbase:masterブランチへのプルリクエスト**であることを示しています。

<img width="600" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/465401/ccdaac4c-d607-160a-c92a-91f8a52dd5c1.jpeg">

そしてタイトルと説明を書きます。
この説明のところに、**Closes #n<紐付けたいIssueの番号>**と書くことで、プルリクエストとIssueを紐付けることができます。
上の画面では、Issue #1と紐付けています。

この状態で**Create pull request**を押します。
すると、表示されたページの**Linked issues**の項目にIssueが紐付いていることが確認できます。
<img width="３00" alt="" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/465401/56783b1b-d6cc-6633-6b28-971c2be55e09.jpeg">

このプルリクエストをマージし、プルリクエストが閉じると紐付いていたIssueも同時に閉じることができます。
ちなみにプルリクエストをマージせずに閉じると、Issueは閉じられずにOpenのまま残ります。

以上です！
My SQL が起動できない問題

#ERROR! The server quit without updating PID file (/var/lib/mysql/＊＊＊（マシン名）.local.pid)
##1.はじめに
homebrewでmysqlをインストールした当初はこのようなエラーは出ませんでしたが、突如この現象に陥った感じなので、具体的な発生要因はわかりません。

ですが、最終的には解決に至ったので、備忘録として残します。

##エラー発生から参考にした記事
###①エラー発生
```mac:ターミナル
sudo mysql.server start

=>
Starting MySQL
. ERROR! The server quit without updating PID file (/var/lib/mysql/MBP-4.local.pid).
```
##②とりあえず記事を調べるか
>mysqlがどうしても起動しない =>
>https://qiita.com/_natsu_no_yuki_/items/ae4c94187093e4ab3cdc
>
>socketのエラーでmysqlが起動できない時=>
>https://qiita.com/fukamiiiiinmin/items/a358498b8adb37a7c251

##③とりあえず試すか
これらの記事を足がかりに、参考記事やその内容を元に試せることはすべて試してみました。
・mysqlの再インストール
・sockファイルの作成
・/etc/my.cnf の修正
・/usr/local/etc/my.cnf
・権限の変更
の修正などなど
##結論（エラー解決手順）
###＊＊＊（マシン名）.local.errのエラーをみる、修正するを繰り返す
```mac:ターミナル
手順
①エラーログの確認
cd /usr/local/var/mysql
vim ＊＊＊（マシン名）.local.err

②mysqlの起動
sudo mysql.server start
=>
Starting MySQL
. ERROR! The server quit without updating PID file (/var/lib/mysql/MBP-4.local.pid).
```
ターミナル上のエラーは、「ERROR! The server quit without updating PID file (/var/lib/mysql/MBP-4.local.pid).」が表示されますが、エラーログをみると、その都度メッセージが変わると思います。
結果、これを繰り返して解決いたりました。

振り返ってみると、記事を元に色々試しすぎて、不要な内容が「/etc/my.cnf」と「/usr/local/etc/my.cnf」に記述されていたために、起動できなかったようです。
エラーログがしっかり残っていたので、解決できたので、ログを早く見れば。。。。と思いました。
以上です！！
Raspberry pi 3B にLCDモニタ導入（ILI9488） 

Raspberry pi 3Bに3.5インチのモニタを導入してみました。

と言っても、
https://trickiknow.com/raspberry-pi-3-complete-tutorial-2018-lets-get-started/
のサイトにあるコマンドを入力しただけなので良くわかっていませんが、日本語の情報が少なかったので備忘録として投稿します。

## 環境
raspbian

```
pi@raspberrypi:~ $ cat /etc/debian_version
10.0
```

LCDモニタ
アリペイで購入。DriverはILI9488らしいですが詳細は不明
https://ja.aliexpress.com/item/32906213419.html?srcSns=sns_Copy&tid=white_backgroup_101&mb=gEvW59xBO21WqQB


## 導入
正直よくわかってませんが、ラズパイ上でコマンドを実行するだけでできました。
自己責任でお願いします。

```
sudo rm -rf LCD-show 

git clone https://github.com/goodtft/LCD-show.git # なんかいろいろドライバあるようです。

chmod -R 755 LCD-show 

cd LCD-show/

sudo ./LCD35-show # これ実行するとラズパイが再起動します。
```

上記を実行すると、LCDモニタに出力されますが、HDMI側に生じされなくなるかもしれません。
今回はHDMIを基本使うことはしないので良かったのですが、戻すときは以下を実行するようです。

```
cd LCD-show/
sudo ./LCD-hdmi
```

以上です。
Docker DesktopをWindows 10 Homeから使えるようにする

こんにちは、@0yanです。2020年3月6日に窓の杜から「Windows 10 HomeでもDocker Desktopが使えるようになった」という記事が出ましたので、早速試してみました。

>[「Docker Desktop」が「Windows 10 Home」の「WSL 2」に対応、プレビュー版が公開](https://forest.watch.impress.co.jp/docs/news/1239275.html)



#環境
- Windows 10 Home（バージョン：10.0.19041 ビルド 19041）
- Windows Subsystem for Linux 2（WSL2）
- Ubuntu 18.04
- Visual Studio Code（バージョン：1.42.1）

WSL機能の有効化、Ubuntuのインストール及びWSL2への切替方法については、本ページ最下部の参考記事をご覧くださいませ。



#Docker Desktopを使えるようにするまでの手順
[Docker Desktop for Windows Edge Release notes](https://docs.docker.com/docker-for-windows/edge-release-notes/)からDocker Desktop Community 2.2.2.0をダウンロードします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/373977/7f7fd7d1-ef4a-ec7e-07aa-929030039fb5.png)

Configuration画面で「Enable WSL 2 Features」にチェックが入っていることを確認し、OKボタンをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/373977/afbc4c2c-427b-520a-4d96-fa5104aa884a.png)

インストールが成功すると、Windowsからログアウトを求められるので「Close and log out」をクリックしてログアウトします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/373977/44d7baec-98c8-2b1d-544c-8d1d3659439a.png)

再度ログインすると、Docker IDでログインするよう求められるのでログインします（まだIDを作成していない場合は作成します）。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/373977/4d7dc535-65bc-9870-1f7c-0a2f77076ad1.png)

Visual Studio Codeを起動し、リモートエクスプローラーをクリックします。そこに「docker-desktop」が表示されていれば使う準備は完了です！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/373977/fe900185-6924-297d-4056-661239d72be8.png)

【補足】
万が一、Visual Studio Codeにリモートエクスプローラーが表示されていなかったら、Remote Developmentをインストールしてください。

>[Remote Development](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.vscode-remote-extensionpack)



#参考記事
①Windows 10 Insider Preview ビルドのインストール方法
[Windows Insider Program ユーザー ガイド](https://insider.windows.com/ja-jp/how-to-pc/)

②WSL1の有効化とUbuntuインストールまでの手順
[【備忘録】Windows 10にUbuntuをインストールするまでの手順](https://qiita.com/0yan/items/57e27a95fe4e2cb59e23)

③WSL2への切り替え手順
[WSL2の環境構築手順](https://qiita.com/poramal/items/3562472d52fe60f61c56)
Gatsbyのデブロイがうまくいかないのはパッケージ管理ツールのせいかもしれません

ちょっとしたブログが必要になったのですが、いちいちログインするのも億劫なので、
静的サイトジェネレーターを試そうという話になり、Gatsbyを入れることになりました。

Reactは未経験のうえに、1からデザインするのもめんどうということもあって[gatsby-starter-lumen](https://www.gatsbyjs.org/starters/alxshelepenok/gatsby-starter-lumen/)  というGatsbyのスターターをベースにカスタマイズしてGitHubに保存して、Netlifyにデブロイという王道の手法を使ったのですが、なぜか失敗します。調べると下記のエラーが出ています。

```
Build script returned non-zero exit code: 127 
```

これは、ビルドコマンドに誤りに起因しているそうです。

　今回はnpmでダウンロードし、ローカルでは問題なくビルドされていましたがnetlify.toml という Netlify でのビルド時にカスタム設定を使う際に必要になるファイルがあり、それがyarnを使う仕様（yarn build）になっていました。

「よし、npmにすればいいんだろう」ということで　npm run build　に変更してもまだエラーが起こります。

なんだよyarnってソーラン節かよ（怒）（実際にはヤーレンじゃなくヤーンと読む）

よくよく調べると、ビルドコマンドをnpmにしてもパッケージの一部がyarnが動いています。

というわけで、もし **あるパッケージ管理ツールで動かない場合にはパッケージを含め別のツール（今回はyarnに統一）でスターターを入れるのが賢明**だとおもいます。

node.jsを入れれば自動的にインストールされるnpmとちがってyarnはインストールが必要ですが、コマンド画面から

```
npm install -g yarn
```
でとりあえず**非推奨ですが** 数秒でインストールができますし、併存もできるので使いたくなければ使わなければいいのです。
初学者 React学習記録 ~前置きとかReactの特徴

## 前置き
この記事は、昨年度Vue.jsを勉強しはじめ、その後Nuxt.jsで作品制作に取り組んでいたがそろそろ新しいフレームワークに触れてみようかなと思い、最近自分の中で熱いReactの勉強を始めようと決意した男の学習記録です。
学習を進めながらSNSアプリケーションを作ろうと思います。

## Reactとは...
![](https://ja.reactjs.org/logo-og.png)
自分の中で熱いと言っても他のフレームワークと比べてどんな特徴を持っているのか具体的に理解できてないところもあるので調べてまとめてみた。
(フロントエンドフレームワークリッチ化しすぎてどれがどうすごいのかわからんくなってくる...)

一般的にWEBページ、WEBアプリケーションを制作するときHTMLとJavascriptはセットで使い分けて書きますが、開発規模が大きいものの開発や複雑な処理をしなければならない場合、Javascript側の処理が複雑化してしまう。
じゃあ最初からJavascriptがベースで開発できればいいよねってことでFacebookが開発したのがReactらしい。
WEBのUIを作ることに特化されていて、細かいコンポーネントの組み合わせでWEBアプリケーションを形作っていくという考え方を用いているので、大規模なアプリケーション制作に向いてるよ！

## Typescriptについて
それでは早速Reactを触ってみよう！と言いたいところなのですが、今回は成果物としてSNSアプリケーションを作りたいので保守・運用を考え、Typescriptを使っていきたいと思います。
ここだけの話、Reactを使っている人の7割がTypescriptを使って書いているとか。
恥ずかしながらTypescriptに触れたことがない雑魚なのでそこから始めます...

Typescriptを導入することで得られるメリットとか書き方とかとにかく色々わかりやすくまとめてくださってる方がいたので貼らせていただきます。

https://qiita.com/uhyo/items/e2fdef2d3236b9bfe74a

では今回はこのへんで！
reCAPTCHAをRailsに導入

#reCAPTCHAについて
recaptchaとはボットなどによる悪質なアクセスからWebサイトを守るための機能です。
今回はRubyOnRails環境でreCAPTCHA V2を追加してみます。
（※最新はV3ですが、今回は馴染みのあるものと言う点と実装し易かったのでV2にしました。）

ログイン画面などでよく見るこんなのですね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510412/72a73261-35ba-9d8d-d855-25d0f81b535b.png)
では、
[GooglereCAPTCHA](https://www.google.com/recaptcha/intro/v3.html)からGoogleアカウントで登録していきましょう。

1.　Adomin consoleボタンをクリック。
2.　➕　ボタンをクリック。
3.　ラベルにapp名など入力。
4.　reCAPTCHA タイプ選択。（今回はV2）
5.　ドメイン登録。appのドメイン、IPアドレス等、使用したいものを登録。（開発でも使う場合はlocalhostも登録。）
　（　➕　ボタンで追加、　✖️　ボタンで削除）
6.　オーナー登録。使用者のメールアドレス入力。複数可共同開発者なども登録。
7.　チェックボックスにチェック。
　- [×]reCAPTCHA 利用条件に同意する。　必須
　- [×]アラートをオーナーに送信する。　任意
8.　送信ボタンを押して登録完了。

これで登録完了です。
歯車マークを押し設定にいき、 **reCAPTCHA のキー**　をクリック。
すると、　**site_key**　と　**secret_key**　と登録情報等が確認出来るようになってます。

続きまして、
Railsに組み込んで行きましょう。

#1. インストール
```ruby:Gemfile
 gem 'recaptcha'
```
```
 bundle install
```
#2. site_keyとsecret_keyの追加
以下のファイルを追加

```ruby:config/initializers/recaptcha.rb
Recaptcha.configure do |config|
  config.site_key = ENV['RECAPTCHA_PUBLIC_KEY']
  config.secret_key = ENV['RECAPTCHA_PRIVATE_KEY']
end
```
#3. Deviseの登録画面に組み込む
```ruby:app/views/devise/registrations/new.html.erb
  <%= recaptcha_tags %>
```
を、登録フォームの任意の場所に追加
hamlの場合
```= recaptcha_tags```
#4. Devise登録時にreCAPTCHAバリデーションを組み込む
こちらを参考にDeviseのRegistrationsControllerを継承したコントローラを追加し、createメソッドにreCAPTCHAバリデーションを組み込む

```ruby:app/controllers/registrations_controller.rb
class RegistrationsController < Devise::RegistrationsController
  prepend_before_action :check_captcha, only: [:create]
  prepend_before_action :customize_sign_up_params, only: [:create]

  private
  def customize_sign_up_params
    devise_parameter_sanitizer.permit :sign_up, keys: [:username, :email, :password, :password_confirmation, :remember_me]
  end

  def check_captcha
    self.resource = resource_class.new sign_up_params
    resource.validate
    unless verify_recaptcha(model: resource)
      respond_with_navigational(resource) { render :new }
    end
  end
end
```

#5. reCAPTCHAのエラーメッセージのi18n対応
以下のファイルを追加

```ruby:config/locales/ja.yml
  recaptcha: 
  errors: 
  verification_failed: 'reCAPTCHA認証に失敗しました。' 
```

細かい設定等はappによって異なるとは思いますが、私はこの流れでreCAPTCHAを導入致しました。
間違いや不動作等ありましたら申し訳ございません。
[reCAPTCHA](https://github.com/ambethia/recaptcha)のGitHubを確認して下さい。
d3.v5.js で地図を描画

次のような地図を作成します。
>[栃木県　地図](https://ekzemplaro.org/data_base/doc/graphics/d3v5/map/)

![tochigi_map.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/c66933f0-f210-5413-5beb-23a0ae9ac0ad.png)

次のページを参考にしました。
>[D3.jsで地図を描画](https://www.excellence-blog.com/2018/04/06/d3-js%E3%81%A7%E5%9C%B0%E5%9B%B3%E3%82%92%E6%8F%8F%E7%94%BB/)

フォルダーの構造です。

```text
$ tree 
.
├── index.html -> map_pref.html
├── map_pref.css
├── map_pref.html
├── map_pref.js
└── tochigi.json
```

```html:map_pref.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta http-equiv="Pragma" content="no-cache" />
<meta http-equiv="Cache-Control" content="no-cache" />
<meta http-equiv="CONTENT-TYPE" content="text/html; charset=utf-8" />
<link href="map_pref.css" rel="stylesheet">
<script src="/js/jquery-3.4.1.min.js"></script>
<script src="/js/d3.v5.min.js"></script>
<script src="map_pref.js"></script>
<title>Map Tochigi</title>
</head>
<body>
<h2>Map Tochigi</h2>
<svg id="map"></svg>
<p />
Mar/08/2020<p />
</body>
</html>
```

```css:map_pref.css
/* -------------------------------------------------------------- */
/*
	map_pref.css

					Mar/08/2020
*/
/* -------------------------------------------------------------- */
.area {
    fill: silver;
    stroke: white;
}
.popup {
    fill: black;
    font-size: 10pt;
}

/* -------------------------------------------------------------- */
```

```js:map_pref.js
// ------------------------------------------------------------------------
//	map_pref.js
//
//						mar/08/2018
// ------------------------------------------------------------------------
const file_json = "tochigi.json"

jQuery.getJSON(file_json,function (data)
	{
	jQuery("#outarea_aa").text ("*** start ***")
	draw_map_proc(data)
	jQuery("#outarea_hh").text ("*** end ***")
	})

// ------------------------------------------------------------------------
function draw_map_proc(data_in)
{
	const WIDTH = 700
	const HEIGHT = 560

	var svg = d3.selectAll("#map")
		.attr("width", WIDTH)
		.attr("height", HEIGHT);

	var gg = svg.append("g");

        var projection = d3.geoMercator()
            .scale(25000)
            .center(d3.geoCentroid(data_in))
            .translate([WIDTH / 2, HEIGHT / 2])

        var path = d3.geoPath()
            .projection(projection)

        gg.selectAll('path')
            .data(data_in.features)
            .enter()
            .append('path')
            .attr('d', path)
            .attr('class', 'area')
}
// ------------------------------------------------------------------------
```

次から　栃木県の地図情報をダウンロードします。
>[国土数値情報　行政区域データ](http://nlftp.mlit.go.jp/ksj/gml/datalist/KsjTmplt-N03.html)

ダウンロードした zip ファイルから、tochigi.json を作成します。

```bash
unzip N03-190101_09_GML.zip
ogr2ogr -f GeoJSON tochigi.json N03-19_09_190101.shp
```
自己紹介 

#Qiitaでログを残す
こんにちは,akairoです.
自動車メーカでプロマネをやってます.

なかなか勉強する時間がなく,しかし
知識はないと迷惑がかかる.

じゃぁ自分でやるしかないじゃん！と
ひとつアウトプットを始めた次第です.

記載内容としては
・AtCoderの参加記録
・AWSの勉強
・Optixの開発
などを予定しています.


拙いですが,よろしければお付き合いください.
Django　アプリケーションをプロジェクトに登録

#■環境

　windows10home
　Pycharm　Community　2019.3
　Python3.7

#■前提条件

Djangoプロジェクト、アプリケーション作成していることを前提。以下参照
　![ターミナルでDjangoアプリケーション作成まで](https://qiita.com/oporimaster/items/4ec4809284cddd8b4ba0)


#■Djangoアプリケーション
　アプリ作成するたびにプロジェクトに登録し、有効化する必要がある。

#■手順

##　①Pycharmで、「setting.py」　を開いて、「INSTALL.APPS」リストに追加。

　　プロジェクトビューで、「プロジェクト名」ー「プロジェクト名」ーsetting.py

　　INSTALLD_APPS　に行追加（Ctl＋Sで保存）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547159/16b08bc8-8f3e-e9d0-7bf2-084c05119481.png)

　（アプリケーション名）.apps.（apps.py　のクラス名）

##　②時刻　修正

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547159/3bdf129e-e46d-d826-66d1-6f7dc4a27cff.png)


以上
---------------------------------------
INSTALL_APPS追加時のファイル名に注意。
Splunk SmartStoreを用いたリモートストレージの活用

## 1. 目的

SmartStoreとは***Splunk Enterpriseのみ***で利用可能な機能であり、リモートのオブジェクトストレージ（Amazon S3など）をIndexの格納先として指定することができます。SmartStoreを利用することで以下利点が生まれます。

- Reduced storage cost. Your deployment can take advantage of the economy of remote object stores, instead of relying on costly local storage.
- Access to high availability and data resiliency features available through remote object stores.
- The ability to scale compute and storage resources separately, thus ensuring that you use resources efficiently.
- Simple and flexible configuration with per-index settings.
- A bootstrapping capability that allows a new cluster or standalone indexer to inherit data from an old cluster or standalone indexer.


![Cache_manager.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482612/49b6e724-df98-e6fc-ae9c-9b7997149442.png)



本投稿では、Splunk SmartStoreの設定手順について解説します。[How to Deploy Splunk SmartStore](https://www.hurricanelabs.com/splunk-tutorials/how-to-deploy-splunk-smartstore)を参考にしました。

## 2. 設定方法


まず、```$SPLUNK_HOME/etc/system/local/indexes.conf```に以下を編集したファイルを作成します。以下の設定ではIndexer内に保存された全てのIndexがAmazon S3への保管対象となっていますが、個別に指定することも可能です。詳細は[こちら](https://docs.splunk.com/Documentation/Splunk/8.0.2/Indexer/ChooseSmartStorestoragelocation)を参照してください。再起動すると設定が反映されます。


```bash:indexes.confにバケット情報やAWSアカウントの情報を書き込みます。
[default]
# Configure all indexes to use the SmartStore remote volume called
# "remote_store".
# Note: If you want only some of your indexes to use SmartStore,
# place this setting under the individual stanzas for each of the
# SmartStore indexes, rather than here.
#remotePath = volume:remote_store/$_index_name

# Configure the remote volume
[volume:remote_store]
storageType = remote

# On the next line, the volume's path setting points to the remote storage location
# where indexes reside. Each SmartStore index resides directly below the location
# specified by the path setting. The <scheme> identifies a supported remote
# storage system type, such as S3. The <remote-location-specifier> is a
# string specific to the remote storage system that specifies the location
# of the indexes inside the remote system.
# This is an S3 example: "path = s3://mybucket/some/path".

path = s3://<your S3 bucket and path>

# The following S3 settings are required only if you're using the access and secret
# keys. They are not needed if you are using AWS IAM roles.

remote.s3.access_key = <access key ID>
remote.s3.secret_key = <secret access key>
remote.s3.endpoint = https://s3.<your AWS region>.amazonaws.com
```

以上
【Rails】カラムの追加と削除

#カラムの追加と削除

```rb
rails generate migration クラス名 カラム名:データ型( カラム名:データ型)
```
上記の様にコードを記載することでカラム名を追加や削除をすることができます。
クラス名は`AddXXXToYYY`または`RemoveXXXFromYYY`とすることで作成や削除を指定することができるが、
複数のカラムを同時に追加する場合などは指定できません。

##カラムの追加

```rb
rails generate migration AddDetailsToTitles price:integer author:string
```
上記のコードでinteger型の`price`とstring型の`author`のマイグレーションファイルが作成されます。

```db/migrate/20120416072618_add_details_to_titles.rb
class AddDetailsToTitles < ActiveRecord::Migration
  def change
    add_column :titles, :price, :integer

    add_column :titles, :author, :string

  end
end
```
`rails db:migrate`を実行してデータベースにカラムを追加します。

```
AddPasswordDigestToUsers
```
もしUserテーブルにpassword_digestカラムを追加したい場合は上記のようにクラス名を記載する。
##カラムの削除
先ほどの`author`を削除してみます。

```rb
rails generate migration RemoveAuthorFromTitles author:string
```

```db/migrate/20120416074444_remove_author_from_titles.rb
class RemoveAuthorFromTitles < ActiveRecord::Migration
  def up
    remove_column :titles, :author
      end

  def down
    add_column :titles, :author, :string
  end
end
```
追加の時と同様に`rails db:migrate`を実行します。
クラス名で指定したテーブルに対してカラムを削除するための文が記述されています。
(この場合はchangeメソッドではなくupメソッドとdownメソッドを分けて記述する必要があります)。
Google Drive File Steamを使ってみる

# Google Drive File Steamを使ってみる
- ファイルダウンロード＆インストール（下図のa.とb.を実施する）
![google-drive-install-01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551056/ed1a0f5b-c25d-b21d-a643-038ef28b0444.png)

- ログイン（普通のアカウントでログインできない）
![google-drive-install-02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551056/6f6d3036-0835-544a-2750-374887ca305e.png)

- 「G Suite」専用のアカウントを作成する
![google-drive-install-03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551056/95e1d18b-6d1e-b51f-cd57-09829c25e829.png)

- 「Google Drive File Steam」へログイン成功
![google-drive-install-04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551056/fccb2025-e70c-e6fc-0b24-4b6301864402.png)

- ブラウザから見ると３０ギガの容量がありますが、windowsに見ると９ギガしかないです
![google-drive-install-06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551056/1b7cf39d-d480-d1e7-0afc-330b704ddfe8.png)
![google-drive-install-05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551056/acf09216-0369-a0ea-d5c3-7f36f36f7611.png)