OmniAICreator/Qiita-1.07M huggingface dataset:
Docker+rails環境開発

※雑メモです

### はじめに

久しぶりです。私は相変わらずエンジニアをしています。ちなみにフロントエンドはReact + TypeScriptです。あとバックエンドもちょっと（rails）。私の現場のバックエンドがrailsなので、バックエンドについていろいろまとめようかなと。この記事では最初の肝である「**環境構築**」です。

※結構簡易的に書いてます。雑です。ご了承ください。

### 事前準備

#### Docker

[公式サイト](https://hub.docker.com/editions/community/docker-ce-desktop-mac)よりダウンロードしてください。

### 1.ディレクトリ作成

```shell
$ mkdir docker-rails-sample
$ cd docker-rails-sample
```

### 2.Dockerfile記述

```dockerfile
FROM ruby:2.6.3

# 必要なパッケージのインストール
RUN apt-get update -qq && \
    apt-get install -y build-essential \ 
                       libpq-dev \        
                       nodejs
RUN mkdir /docker-rails-sample
ENV APP_ROOT /docker-rails-sample
WORKDIR $APP_ROOT

ADD ./Gemfile $APP_ROOT/Gemfile
ADD ./Gemfile.lock $APP_ROOT/Gemfile.lock

RUN bundle install
ADD . $APP_ROOT
```

ここで以前、私が書いた記事でもあるのですが、Dockerのコマンドですが

- ENV ... 環境変数の設定
- WORKDIR ... ワーキングディレクトリの設定
- COPY ... ファイルをイメージにコピー 
- RUN ... コマンド実行

### 3.Gemfileを作る

```shell
$ vi Gemfile
```

``` Gemfile
source 'https://rubygems.org'
gem 'rails', '5.2.2'
```

### 4.空のGemfile.lockを作る

rubymineで作業していたら勝手に作成された？のですが、docker-buildする際に必要なので。

``` Gemfile.lock
$ touch Gemfile.lock
```

### 5.docker-compose.ymlを作成

`MYSQL_ROOT_PASSWORD`と`MYSQL_DATABASE`を設定

（私はpasswordとかいうやばいパスワードで）

```
$ vi docker-compose.yml
```

```docker-compose.yml
version: '3'
services:
  db:
    image: mysql:5.7
    environment:
      MYSQL_ROOT_PASSWORD: password
      MYSQL_DATABASE: root
    ports:
      - "3306:3306"

  web:
    build: .
    command: rails s -p 3000 -b '0.0.0.0'
    volumes:
      - .:/app_name
    ports:
      - "3000:3000"
    links:
      - db
```

### 6.railsを実行

```shell
$ docker-compose run web rails new . --force --database=mysql
```

### 7.database.yml

passwordとhostを設定する。

```database.yml
default: &default
  adapter: mysql2
  encoding: utf8
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: root
  password: password
  host: db
```

### 8.Docker起動

```shell
$ docker-compose build
$ docker-compose up
```

### 9.DB作成

```shell
$ docker-compose run web rails db:create
```

あとはlocalhost:3000にアクセスすればOK。

以上、雑メモでした。
gRPCがKotlinを公式でサポートしたようなので軽く調べた内容メモ

ちょうどこの記事を書く2週間ほど前に、Kotlin gRPCライブラリがリリースされたようなので調査してみました。

※ [2020/4/28のKotlin愛好会vol.21](https://love-kotlin.connpass.com/event/173821/) にて発表予定の内容です。詳細な情報が書かれたスライドはこちらにアップロードします。

# リリースについて

gRPC公式のライブラリが2週間前の2020/4/10にリリースされました（[v0.1.1](https://github.com/grpc/grpc-kotlin/releases/tag/v0.1.1)）。

Googleのブログからも少しだけ遅れて発表があったようです。
[『Kotlin, meet gRPC: a new open-source project for modern apps』](https://cloud.google.com/blog/products/application-development/use-grpc-with-kotlin)

リリースしてからまだ2週程度ですが、すでにGithubで241Star超えのようです。

また、gRPCの公式ドキュメントにも4/16に[Kotlinに関するQuickStart](https://grpc.io/docs/quickstart/kotlin/)ができました。

# gRPCとは？

他の記事でよく取り上げられる内容なので割愛します。

Microserviceの文脈でよく取り上げられる技術です。
国内だとMericari, AbemaTV, dowangoなどで利用されているそうです。

# 元々のKotlinにおけるgPRCのステータス

[awsome-grpc](https://github.com/grpc-ecosystem/awesome-grpc#lang-kotlin)なるドキュメントにてライブラリが4つ紹介されていました。
`grpc-kotlin`という同名の別ライブラリもあるのでご注意ください。（※今回の発表されたのは`grpc/grpc-kotlin`です）

またKotlinはJVM言語なので、当然JavaのgRPCライブラリを利用することもできます。

# 公式ライブラリのメリット

公式ドキュメントにて記載されているメリットは以下のとおりです。
* Kotlin製ライブラリなので、suspend functionやFlow APIを使い非同期プログラムがきれいに書ける
* GCPのCloud Runでも利用できる

まぁダントツで一番でかいメリットは、「gRPCが公式としてサポートしていること」だと思います。

# デモコード

gRPCの公式ドキュメント内の[QuickStart](https://grpc.io/docs/quickstart/kotlin/)や[gRPC Basics - Kotlin/JVM](https://grpc.io/docs/tutorials/basic/kotlin/#why-use-grpc)内に記載されているので割愛します。
Cypressで日本語が文字化けするとき

下記を`cypress.js`に追加すると解決する。

```javascript
{ "modifyObstructiveCode": false, }
```

詳しくは読んでないが、下記issueに書いてあった。
https://github.com/cypress-io/cypress/issues/1543

## 経緯
試しにCypress使ってお願いされたサイトのテストを書いていたら、特定の文字のみ文字化けする。
怪しいところがないか調べたところ、`<meta charset="Shift_JIS">`が指定されている。
超怪しい。
ということで、Charset周りのことを調べてたら上に行き着いて解決しました。
Avidaではじめる「人工生命」

# 人工生命とは?
人工生命(ALife)とは、コンピュータ上で人工的な生命を作り出してしまおう！
そして、そこから「生命とは何か」を考えようという深淵でスペクタクルな分野なのです。

人工生命の記事が少ない + Avidaを説明している日本語ページがないということで作ってみました。

# Avidaとは
人工生命プログラムの一つです。
個体それぞれが代謝速度をもち、それぞれの速度で自己複製していくのが特徴です。(詳しくは後述)

元論文: "Avida: A Software Platform for Research in Computational Evolutionary Biology" Charles Ofria
https://www.researchgate.net/publication/8598395_Avida_A_Software_Platform_for_Research_in_Computational_Evolutionary_Biology

また、もう一つ大きな特徴として、
Avida-EDという教育用のプログラムが、web上に公開され**誰でも簡単に実行**することができます。

# Avida-ED 始め方
習うより慣れろで、触ってみるのが一番いいと思います。
サイドバーにある個体を、ドラッグ&ドロップで持ってきて、Runを押すだけで人工生命世界が始まります。
<img width=600 alt="start world" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138863/350bf35f-d049-918c-8ffa-0fe80991f722.gif">

<実行環境>
https://avida-ed.msu.edu/app/AvidaED.html

<チュートリアル>
https://www.youtube.com/watch?v=x7pISK-eBE8&t=13s

# 3つのモードがあります。
- Populationモード: 集団全体をシミュレートするモード
![スクリーンショット 2020-04-25 19.05.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138863/018ffe65-b019-ba84-e073-20d79e5f4a5b.png)

- Organismモード: 1個体を詳しく見るモード
![スクリーンショット 2020-04-25 19.01.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138863/1b5db319-a977-e3ac-a814-3f460bb4a52e.png)

- Analysisモード: シミュレート結果を分析するモード
![スクリーンショット 2020-04-25 21.13.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138863/b9d96c19-fd10-3f2b-7437-94ef92c1a8ef.png)


# Avida-ED ざっくりアルゴリズム
- 個体はそれぞれ、50命令の文字列で構成されます
- 命令には、a-zの26種類があります
- 個体は、文字列に応じてFitness(適応度)が計算され、適応度が2倍ある個体は2倍早く増殖します
- 個体は複製されるときに、突然変異により命令が書き換わることがあります。(突然変異率は設定できます。)

↓(例)突然変異で11番目の命令がV=>Oに変化しています。
![スクリーンショット 2020-04-25 21.14.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138863/1f492267-62ac-8011-785e-8b7fc4525490.png)



# 実際に動かした所感
- 集団の適応度が、不連続に上がっていく様子がみられた。=> **進化してる〜〜〜！！！**
<img width=500 alt="shinka" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138863/b292db91-57f9-981f-707f-0a4f5de52e63.png">

- (適応度の計算と、それぞれの命令の意味が結構複雑でまだ理解できてないので、そのうち理解したい。)

- すぐに実行できるのは、人工生命が抜群に身近になって素晴らしい。

- 人工生命は見てて**ワクワク**する。今後もいろんな人工生命アルゴリズムを触ったり、作ってみたい！皆さまもよかったら是非！！
content_tagの使い方について

# 背景
見たこと無い記述が出てきて調べた際に便利だったので、備忘録として書きます。

##content_tagとは
Railsのビューヘルパーで、これを用いるとHTMLコードの要素を生成することが出来ます。
これを使うことでスマートなコードを書くことができます！

##使い方

```ruby

#通常
content_tag(:p)
#=> "<p></p>"

content_tag(:p, "テスト", id: "test", class: "test-class")
#=> "<p id="test" class="test-class">テスト</p>"

# 入れ子
content_tag(:div, id: "hoge") do
　content_tag(:p, "テスト")
end
#=> "<div id="hoge"><p>テスト</p></div>"

# ヘルパーに切り出して使う
def helper
　#処理
　hoge = 値
　content_tag(:div, hoge) 返り値
end
```
Socialiteでユーザー認証しようとしたら、InvalidStateExceptionが出たお話

https://readouble.com/laravel/5.5/ja/socialite.htmlを参考にして、Githubを使用したユーザー認証を書いていたが、InvalidStateExceptionというエラーが出た。

無効の状態の例外？という訳しか浮かばないが、、公式のドキュメントを見ると、statelessなやり方を推奨している。

そもそもstateとはなんぞや、ということで調べてみた。
https://milestone-of-se.nesuke.com/nw-basic/as-nw-engineer/stateful-and-stateless/

https://qiita.com/wind-up-bird/items/b210e294ecb147d67e2b

二つの記事を総合して考えると、
セッションの状態とは、一連のインタラクティブな操作(session)における各状態(state)のことであり、ステートフル（情報が保持されている）なら、情報が保持されているため、状態によってサーバーからのレスポンスが異なり、メールなどに使用される。

一方で、ステートレスなら、ステート（状態）がレス（保持されていない）ので、誰に対しても同じ反応をするので、HTTPやHttpsに使用される。

つまり、InvalidStateExceptionとは無効の状態の申し立てではないでしょうか？

ならば、こちらを変更しようと思い、以下のようにしました。

`$user = Socialite::driver($social)->user();`

を変更して

`$user = Socialite::driver($social)->stateless()->user();`

すると、エラーの内容が変わりました。

`Client error: GET https://api.github.com/user resulted in a 401 Unauthorized response: { "message": "Bad credentials", "documentation_url": "https://developer.github.com/v3" } `

調べてみると
https://developer.mozilla.org/ja/docs/Web/HTTP/Status/401

「HTTP 401 Unauthorized は、有効な認証資格が不足していることによりリクエストが適用されないことを示すクライアントエラーのレスポンスコードです。」

ん、、、、あ、そもそもGitHubの認証情報を得られていないということか。

```public function authCallback(){
        $social = basename(parse_url($this->getUrl(),PHP_URL_PATH));
        //ユーザー属性を取得
        $user = Socialite::driver($social)->stateless()->user();
        echo '<pre>'; print_r($user); echo'<pre>';exit;
    }```

こんな感じのコールバックの受け取り方だったのだが、変更することにした。
【GitHub】bitbucket,githubの両方をリモートリポジトリに設定する。


bitbucketをリモートに設定し開発する途中で、ふとGitHubにも同時にプッシュできるのか気になった。

[こちらの記事](https://snap.textfile.org/20170925200343/)に詳しく書かれていたので、順番に設定し気になった所を自分用に追加で記録する。

##GitHubでNew repository作成
<img width="235" alt="スクリーンショット 2020-04-23 17.59.11.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/597926/c9e512e3-0297-d135-4bab-8a8426a9d717.png">

###公開鍵を作成、設定する
こちらを参考にさせて頂いた。
[GitHubでssh接続する手順~公開鍵・秘密鍵の生成から~](https://qiita.com/shizuma/items/2b2f873a0034839e47ce)


##リモートの追加登録

<img width="643" alt="スクリーンショット 2020-04-23 18.04.21.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/597926/c412431f-994e-3354-97b9-f42b55c71d1a.png">

リポジトリ作成後の画面に表示される
git remote add origin https:〜〜
をターミナルで実行。

※開発途中で追加する場合、ここで**絶対にgit initは行ってはいけない。**ローカルのコミット情報等がすべて初期化され、消える事で大変面倒なことになる、多分。

---

リモートの追加は、直接.git/configに一行追加しても良い。

```
[core]
	repositoryformatversion = 0
	filemode = true
	bare = false
	logallrefupdates = true
	ignorecase = true
	precomposeunicode = true
[remote "origin"]
	url = git@bitbucket.org:ユーザー名/アプリ名.git
	url = https://github.com/ユーザー名/アプリ名.git←ここを追加
	fetch = +refs/heads/*:refs/remotes/origin/*
[branch "master"]
	remote = origin
	merge = refs/heads/master
```

###確認
```shell
git remote -v
```
で追加されていることを確認できる。




###終わりに。
転職の為、未経験の状態からRailsを学習しております。正しい知識を着実に身に着け、実力のあるエンジニアになりたいと考えています。継続して投稿していく中で、その為のインプットも必然的に増え、成長に繋がるかと考えています。
今現在、初心者だからといって言い訳はできないですが、投稿の内容に間違っているところや、付け加えるべきところが多々あるかと思いますので、ご指摘頂けると幸いです。この記事を読んで下さりありがとうございます。
OpenVPN server の server 指定の意味

※ 紹介記事の補足記事です。一般的には「こう書いてある理由を正しく理解していない」ことにより、勝手に自分流にアレンジすると「うまくいかない」事はよくある事。そこで、不足している情報の追記をしたいと思います。

参考:

- [OpenVPNのインストールとセットアップからインターネット接続までのガイドブック](https://qiita.com/noraworld/items/2fe6be489e1d93c748b8)

※ 結論的には `dev tun` = NAT/NAPT です。

## server で指定する IPv4 アドレス

これが一番謎でした。なんのアドレスなのか。

```/etc/openvpn/server.conf
server 10.8.0.0 255.255.255.0
```

答えは `tun0` 内に展開する、NAT/NAPT 空間用のネットワークアドレスです。

```sh
ku@ubunku:~$ ifconfig tun0
tun0: flags=4305<UP,POINTOPOINT,RUNNING,NOARP,MULTICAST>  mtu 1500
        inet 192.168.123.1  netmask 255.255.255.255  destination 192.168.123.2
        inet6 fe80::9cbf:7c2b:171a:6fca  prefixlen 64  scopeid 0x20<link>
        unspec 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00  txqueuelen 100  (不明なネット)
        RX packets 26  bytes 1956 (1.9 KB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 30  bytes 14751 (14.7 KB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
```

`dev tun` を使用している場合は: NAT/NAPT を使い OpenVPN サーバーの名義で LAN 内のホストと通信をします。

今回 OpenVPN server からは 192.168.123.6 を貰っています。そこで、会社のルーター 192.168.2.1 に ping してみましょう。

```sh
ping 192.168.2.1
```

tcpdump を用いて `tun0` 内部をダンプすると… 一見 192.168.123.6 というクライアントから、192.168.2.1 というルーターに直接 ping して応答を得ているかのように見えます。

```sh
ku@ubunku:~$ sudo tcpdump -i tun0 icmp
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on tun0, link-type RAW (Raw IP), capture size 262144 bytes
20:50:19.131993 IP 192.168.123.6 > LEDE.lan: ICMP echo request, id 1, seq 57, length 40
20:50:19.132421 IP LEDE.lan > 192.168.123.6: ICMP echo reply, id 1, seq 57, length 40
```

しかし実際は、ubunku (192.168.2.100) の IP アドレスから NAT/NAPT が掛かって出ていくことが判ります。

```sh
ku@ubunku:~$ sudo tcpdump -i eno1 icmp
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eno1, link-type EN10MB (Ethernet), capture size 262144 bytes
20:51:04.461825 IP ubunku > LEDE.lan: ICMP echo request, id 1, seq 58, length 40
20:51:04.462302 IP LEDE.lan > ubunku: ICMP echo reply, id 1, seq 58, length 40
```

というわけで、`server` に指定するアドレスは架空のアドレス空間を指定しないといけないのでありました。

```/etc/openvpn/server.conf
server 10.8.0.0 255.255.255.0
```
Djangoのクラスベースビュー

# はじめに

ここでは、djangoのクラスベースビュー（汎用ビュー）の基本について解説していきます。
アプリケーションディレクトリ下にある`views.py`に書いていきます。
モデルとして`models.py`の`SampleModel`を、フォームとして`forms.py`の`SampleForm`を利用するものとします。

# TemplateView

最もシンプルな形のクラスビューです。
いろいろなページの作成に使えます。

```python:views.py
from django.views import generic


class SampleTemplate(generic.TemplateView):
    template_name = 'app/app_template.html'
```

なお、テンプレートとするHTMLファイルを指定する`template_name`は、`アプリ名/アプリ名_view名.html`とすると、クラス定義時に明示しなくてもデフォルトで利用されるようになります。以下で説明する他のビューでも同様です。


# ListView

ブログの記事一覧ページなど、複数のレコードを一覧表示するページに使えます。

```python:views.py
from django.views import generic

from .model import SampleModel


class SampleList(generic.ListView):
    model = SampleModel
    template_name = 'app/app_list.html'
    paginate_by = 10 # ページネーションを入れる場合
```

`model`は、ページに表示するレコードを格納しているモデルを指定します。


# CreateView

ブログの新規記事の作成など、新しいレコードを作成するページに使えます。

```python:views.py
from django.urls import reverse_lazy
from django.views import generic

from .model import SampleModel
from .forms import SampleForm


class SampleCreate(generic.CreateView):
    model = SampleModel
    form_class = SampleForm
    template_name = 'app/app_create.html'
    success_url = reverse_lazy('app:app_list')
```

`form_class`で指定されたフォームに基づいて、フォーム画面が作成されます。
また、`success_url`は、記事作成に成功した後に遷移するページを指定します。詳しくは`urls.py`の記事で解説します。


# DetailView

ブログの記事の個別ページなど、レコードの詳細を表示するページに使えます。

```python:views.py
from django.views import generic

from .model import SampleModel
from .forms import SampleForm


class SampleDetail(generic.Detail):
    model = SampleModel
    template_name = 'app/app_detail.html'
```

# UpdateView

ブログの記事の編集画面など、一度作成したレコード内容を更新するページに使えます。

```python:views.py
from django.urls import reverse_lazy
from django.views import generic

from .model import SampleModel
from .forms import SampleForm


class SampleUpdate(generic.UpdateView):
    model = SampleModel
    form_class = SampleForm
    template_name = 'app/app_update.html'
    success_url = reverse_lazy('app:app_list')
```


# DeleteView

ブログの記事の削除画面など、作成したレコードを削除するページに使えます。

```python:views.py
from django.urls import reverse_lazy
from django.views import generic

from .model import SampleModel
from .forms import SampleForm


class SampleDelete(generic.DeleteView):
    model = SampleModel
    template_name = 'app/app_delete.html'
    success_url = reverse_lazy('app:app_list')
```


# まとめ

ここでは、djangoのクラスベースビューの基本について解説しました。
次回は、関数ベースビューについて解説する予定です。
Qiitaへの連続投稿数を取得する(Qiita Posting Streak)

## はじめに

この人はどのくらい連続でQiitaに投稿しているのだろう？ということを気軽に知りたいと思いました。

## 作ったもの
Qiita API v2のAPIを、Python 3.6.3で呼び出して整形・出力しています。
質素ですみません。

[aki-nasu/qiita-streak](https://github.com/aki-nasu/qiita-streak)

## 使い方
`qiita_streak.py`を実行すると、入力を要求されますのでユーザー名を入力してください。
私の場合ですと、`aki-nasu`です（`@`は要りません）。

- 実行例  
![](https://i.imgur.com/flYU3Xo.png)

`current streak`が、最新の連続投稿数です。
`most streak`が、今までで一番長かった連続投稿数です（longestのほうがよかったか）。

## 解説
非常に簡単にですが、一部解説です。

* 使用したライブラリ
    * `requests` : HTTPライブラリ
    * `datetime` : 日付型、時間型のPython標準ライブラリ

* 年月日が一致してるかどうかを返します（日付型の扱いが調べてもわからなかったので自前で無理やりです）。

```python
def compareYMD(d1, d2):
    return d1.year == d2.year and d1.month == d2.month and d1.day == d2.day
```

* Qiita APIの呼び出し部分です。今回使用したAPIのレスポンスは、記事の作成日時降順です。

```python
r = qiita_request.get_user_items(input('username : '))
```

↓ `qiita_request.py`

```python
import requests

URL = "https://qiita.com/api/v2/"

def get_user_items(user_id):
    return requests.get(URL + "users/" + user_id + "/items").json()
```

* 1つ目のデータ(その人の最新記事)の作成日時（`created_at`）が、今日もしくは昨日だったら`current_streak+=1`してます。
* 2つ目以降のデータは、1つ手前の作成日時と1日違いかどうかでstreakしてるか判断しています。

```python
if compareYMD(pre_date, r_created_at[0]) or compareYMD(pre_date, r_created_at[0] + inc_day): current_streak += 1
most_tmp += 1
most_streak = max(most_streak, most_tmp)

pre_date = r_created_at[0]

for i in range(1,n):
    if compareYMD(pre_date, r_created_at[i]): continue
    if compareYMD(pre_date, r_created_at[i] + inc_day):
        if current_streak > 0: current_streak += 1
        most_tmp += 1
    else:
        if current_streak > 0: current_streak *= -1
        most_streak = max(most_streak, most_tmp)
        most_tmp = 1
    pre_date = r_created_at[i]
most_streak = max(most_streak, most_tmp)

if current_streak < 0: current_streak *= -1
```

## おわりに
datetimeの扱いがよくわからず無理やりになっていると思います。
出来れば、ネイティブアプリにしてもっと手軽にStreakチェックしたかったですね。

ちなみに、最初の実行例は私のではありません。私は下記の通り連続投稿などしたことがありません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129204/4a15fe22-a914-3e04-b4bc-28f89500a99b.png)

ですが、今日からGW改めステイホームウィークですし、その間だけでも毎日投稿に挑戦してみます（4月25日～5月6日まで）。結果は最終日に追記します。出来ない気しかしません。

## 参考
- [QiitaAPI-v2 reference](https://qiita.com/api/v2/docs)
    - [(使用したAPI)/users/:user_id/items](https://qiita.com/api/v2/docs#get-apiv2usersuser_iditems)
- [Requests document](https://requests-docs-ja.readthedocs.io/en/latest/)

## 2020/05/01 追記
毎日投稿することに価値を感じなくなったので、Qiita連続投稿を引退します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129204/c1d0913e-833b-9056-51e8-c845b7ab8fd4.png)
flutterアプリをiPhone実機でビルドした際に画面が真っ白になったときの対処方法

## 現象

flutterをRunしたさいにandroidやiOSのシュミレータでは動くが、iOSの実機でビルドした際に画面が真っ白になる現象。XCode上では下記のようなエラーが出ていた。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107119/6ebd8866-51d0-16c8-dfde-35b94e824250.png)

## バージョン情報

```shell 
$ flutter --version
Flutter 1.17.0-3.2.pre • channel beta •
https://github.com/flutter/flutter.git
Framework • revision 2a7bc389f2 (3 days ago) • 2020-04-21 20:34:20 -0700
Engine • revision 4c8c31f591
Tools • Dart 2.8.0 (build 2.8.0-dev.20.10)
```

XCode 11.4.1
iPhone8 iOS13.3.1

## 対処法

iOSのバージョンを`13.4.1`にアップしたところ解消した。
DBからデータを取り出すメソッド

# 背景
データを取り出すメソッドとして「pluckメソッド」「mapメソッド」があります。
その２つをもう少し詳しく知りたかったので調べて簡単に解説します。


## pluckメソッドとは
pluckはRailsでデータベースからデータを取り出すメソッド。
pluckではデータは配列として取り出され、指定したカラムが2つ以上の場合は、配列の配列になる。

```
モデル.pluck(カラム名)
```

##使い方

```ruby

#1.データ作成
User.create(name:"広瀬すず")
User.create(name:"新垣結衣")
User.create(name:"浜辺美波")


#2.pluckメソッドを使って，nameのカラムの値を取り出す

User.pluck(:name)
# => ["広瀬すず", "新垣結衣", "浜辺美波"]
```

###問題点と解決法
以下のように記述してしまうと、配列の形のまま出力されてしまう。

```ruby

<%= User.pluck(:name) %>
# =>["広瀬すず", "新垣結衣", "浜辺美波"]
```

joinメソッドをチェーンさせることで解決できる。

```ruby

<%= User.pluck(:name).join(" ") %>
# =>広瀬すず 新垣結衣 浜辺美波
```

##mapメソッドとは
各要素へ順に処理を実行してくれるメソッド。

```
配列変数.map {|変数名| 具体的な処理 }
```

※ちなみに「.map!」とすることで破壊的メソッドというものになり、値を上書き保存してくれるようになります。
【Objective-C】JSONのシリアライズとデシリアライズ

#NSJSONSerialization
**NSJSONSerialization**はJSONを**シリアライズ・デシリアライズ**するためのクラスです。
このクラスを用いてNSDataとJSONの変換ができます。

※**シリアライズ**・・・プログラミングでオブジェクト化されたデータを、ファイルやストレージに保存したり、ネットワークで送受信したりできるような通信するのに適した形に変換することを言います。

※**デシリアライズ**・・・シリアライズの逆で、シリアライズされたデータをプログラミングで扱えるようにオブジェクトの型に復元することを言います。

#制約
変換するための制約として以下が挙げられます。

・トップレベルオブジェクトはNSArrayかNSDictionaryである
・全てのオブジェクトは, NSString, NSNumber, NSArray, NSDictionary, NSNull いずれかのインスタンスである
・全ての辞書のキーはNSString
・数値はNaNや無限でない

#NSDataからJSONオブジェクトの変換
変換には以下を用います。

```objective_c
(id)JSONObjectWithData:(NSData *)data options:(NSJSONReadingOptions)opt error:(NSError **)error
```
引数にはNSDataとオプション、NSErrorへのポインタを渡します。デシリアライズに失敗した時には、返り値がnilになり、errorにその理由が渡されます。そして以下にオプションに指定できるものの一覧を記載します。

| オプション |                       説明                         |
|:--|:--------------------------------------------------------------------------------|
| NSJSONReadingMutableContainers | 利用するオブジェクトをNSMutableArray, NSMutabileDictionaryで変換します                   |
| NSJSONReadingMutableLeaves | オブジェクトのキーとしてNSMutableStringを用います |
| NSJSONReadingAllowFragments | JSONのトップレベルオブジェクトとしてDictionary, Array以外を指定できます。( "hoge" のような文字列のみでも変換できます) |

**サンプルコード**
jsonデータ

```json
{"myfirends":[{"lastName":"Doe","firstName":"John"},{"lastName":"Smith","firstName":"Anna"},{"lastName":"Jones","firstName":"Peter"}]}
```
パースコード

```objective_c
NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding];
    id obj = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
    NSLog(@"%@", obj);
```
結果

```
{
    myfriends =     (
                {
            firstName = John;
            lastName = Doe;
        },
                {
            firstName = Anna;
            lastName = Smith;
        },
                {
            firstName = Peter;
            lastName = Jones;
        }
    );
}
```

#JSONオブジェクトからNSDataへの変換
変換には以下を用います。

```objective_c
(NSData *)dataWithJSONObject:(id)obj options:(NSJSONWritingOptions)opt error:(NSError **)error
```
JSONのトップレベルオブジェクト(NSArrayかNSDictionary)を引数として渡します。同時にオプションとエラーへのポインタを渡します。変換に成功したらUTF-8でエンコードされた文字列のNSDataが返されます。エラーがあったときはerrorにその内容が含まれます。

**サンプルコード**

パースコード

```objective_c
NSData *data = [NSJSONSerialization dataWithJSONObject:obj options:0 error:nil];
NSLog(@"%@", [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
```
出力結果

```json
{"employees":[{"lastName":"Doe","firstName":"John"},{"lastName":"Smith","firstName":"Anna"},{"lastName":"Jones","firstName":"Peter"}]}
```
#参考
パース関連
https://github.com/mixi-inc/iOSTraining/wiki/6.2-JSON%E3%81%AE%E3%82%B7%E3%83%AA%E3%82%A2%E3%83%A9%E3%82%A4%E3%82%BA%E3%81%A8%E3%83%87%E3%82%B7%E3%83%AA%E3%82%A2%E3%83%A9%E3%82%A4%E3%82%BA
http://blog.kmusiclife.com/p/objc-nsjsonserializatio/
（Swift)
https://qiita.com/yosi-q/items/7ad1db0dca7b2dd4c065

NSNull対処法
https://qiita.com/yusuga/items/adfb93bd73288e702d86
CentOS8 Docker/Docker Composeインストール

#はじめに
CentOS8にDockerをインストールするメモです。

#repo追加
`dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo`

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/346425/ee10c9fc-0c96-0d66-6894-ebdbfb6ba245.png)

#dockerインストール
`dnf -y install --nobest docker-ce docker-ce-cli`

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/346425/247290a4-e0a6-36ee-e23d-0b85dbc00f0c.png)


#自動起動有効化
`systemctl enable docker`

#docker起動
`systemctl start docker`

#docker-composeインストール
##ダウンロード
`wget https://github.com/docker/compose/releases/download/1.25.5/docker-compose-Linux-x86_64`

##/usr/local/bin/に配置
`mv docker-compose-Linux-x86_64 /usr/local/bin/docker-compose`

##実行権限追加
`chmod +x /usr/local/bin/docker-compose`

##バージョン確認
`docker-compose --version`
>docker-compose version 1.25.5, build 8a1c60f6


参考ページ：https://docs.docker.com/compose/install/


以上
お試しninja

# まえがき

ビルドツールのmakeよりも新しくて、しかも早いという噂のninjaを試してみました。基本的にはmakeとほとんど同じですが、暗黙のルールがなく明示的に記述する必要があるので、見返したときに読みやすいと感じました。

[公式サイト](https://ninja-build.org/)にも書いてある通り、build.ninjaは読みやすいが、手書きでは書きにくく、より高度なビルドシステム（makeでいえばAutotools）が生成するものです。今回は自分の理解のためにbuild.ninjaを少し手書きで書いてみました。

より高度なビルドシステムとしては、CMakeやMesonがあげられます。そのうち動かしてみようと思います。

## インストール

```sh
$ apt install ninja-build
$ ninja --version
1.8.2
```

## テスト用ソースコード

ninjaの実行のためにテスト用のソースコードを3つ用意しました。

```cpp
// main.cc 
#include <iostream>
#include "gcd.hh"

using namespace std;

int main()
{
    ll a = 10, b = 15;

    cout << gcd(a, b) << endl;
}
```

```cpp
// gcd.cc 
#include "gcd.hh"

ll gcd(ll x, ll y) { return y ? gcd(y, x % y) : x; }
```

```cpp
// gcd.hh 
using ll = long long;

ll gcd(ll x, ll y);
```

## build.ninja

makeで言えばMakefileがninjaではbuild.ninjaです。あまり手書きでbuild.ninjaを作成することは無いらしいのですが、理解のため書いてみました。基本的にはMakefileと変わらないようです。依存関係も解決できるように`-MMD -MF`を使っています。

```sh
$ cat build.ninja 
cc = g++
cxxflags = -Wall

rule obj
  depfile = $out.d
  command = $cc -MMD -MF $out.d $cxxflags -c $in -o $out

rule app
  command = $cc $ldflags $in -o $out

build main.o: obj main.cc
build gcd.o: obj gcd.cc
build main: app main.o gcd.o
```

## ビルド

このようなファイルがある環境です。

```sh
$ ls
build.ninja  gcd.cc  gcd.hh  main.cc
```

実行は`ninja`でできます。`make`コマンド相当ですね。
`-v`オプションを付けると、実行したコマンドを表示できます。

```sh
$ ninja -v
[1/3] g++ -MMD -MF gcd.o.d -Wall -c gcd.cc -o gcd.o
[2/3] g++ -MMD -MF main.o.d -Wall -c main.cc -o main.o
[3/3] g++  main.o gcd.o -o main
```

オブジェクトファイル、依存ファイル、実行ファイルが作成されました。

```sh
$ ls
build.ninja  gcd.cc  gcd.hh  gcd.o  gcd.o.d  main  main.cc  main.o  main.o.d
```

## クリーン

`-t`オプションで`clean`を指定すると生成したファイルを削除します。

```sh
$ ninja -t clean
Cleaning... 5 files.
$ ls
build.ninja  gcd.cc  gcd.hh  main.cc
```

## その他コマンド

ターゲットをすべて表示します。

```sh
$ ninja -t targets all
main.o: obj
gcd.o: obj
main: app
```

コマンドをすべて表示します。

```sh
$ ninja -t commands
g++ -MMD -MF main.o.d -Wall -c main.cc -o main.o
g++ -MMD -MF gcd.o.d -Wall -c gcd.cc -o gcd.o
g++  main.o gcd.o -o main
```

他のコマンドはヘルプで確認できます。

```sh
$ ninja --help
usage: ninja [options] [targets...]

if targets are unspecified, builds the 'default' target (see manual).

options:
  --version  print ninja version ("1.8.2")

  -C DIR   change to DIR before doing anything else
  -f FILE  specify input build file [default=build.ninja]

  -j N     run N jobs in parallel [default=8, derived from CPUs available]
  -k N     keep going until N jobs fail [default=1]
  -l N     do not start new jobs if the load average is greater than N
  -n       dry run (don't run commands but act like they succeeded)
  -v       show all command lines while building

  -d MODE  enable debugging (use -d list to list modes)
  -t TOOL  run a subtool (use -t list to list subtools)
    terminates toplevel options; further flags are passed to the tool
  -w FLAG  adjust warnings (use -w list to list warnings)
```
installing direnv

なんか公式ガイドには色々な記述があるけど go get でいけたくさいな

`% go get github.com/direnv/direnv`

```
% go get github.com/direnv/direnv
% direnv
direnv v2.21.2
Usage: direnv COMMAND [...ARGS]

Available commands
------------------
allow [PATH_TO_RC]:
  Grants direnv to load the given .envrc
deny [PATH_TO_RC]:
  Revokes the authorization of a given .envrc
edit [PATH_TO_RC]:
  Opens PATH_TO_RC or the current .envrc into an $EDITOR and allow
  the file to be loaded afterwards.
exec DIR COMMAND [...ARGS]:
  Executes a command after loading the first .envrc found in DIR
help [SHOW_PRIVATE]:
  shows this help
hook SHELL:
  Used to setup the shell hook
prune:
  removes old allowed files
reload:
  triggers an env reload
status:
  prints some debug status information
stdlib:
  Displays the stdlib available in the .envrc execution context
version [VERSION_AT_LEAST]:
  prints the version (2.21.2) or checks that direnv is older than VERSION_AT_LEAST.
```
優先度付きキュー（PriorityQueue）っぽいものをJSで実装する

優先度付きキュー（プライオリティキュー）がJSには無いので実装をしてみた。

整数の配列の中から最小のものを常に計算量O(1)で取り出せる。

pushするときにマイナスにして格納し、取り出すときまたマイナスを付けて元に戻すようにすれば最大のものから取り出すキューとしても使える。


```JavaScript
class PriorityQueue {
  constructor() {
    this.heap = [];
  }
  
　// 要素の追加
  push(item) {
    let heap = this.heap;
    let i = heap.length++;
    let j;

    while(i) {
      j = Math.floor((i - 1) / 2);
      if(heap[j] <= item) break;
      heap[i] = heap[j]
      i = j;
    }

    heap[i] = item;
  }
  
  // 最大値の削除
  pop() {
    let heap = this.heap;
    let top = heap[0];
    let popped = heap.pop();

    let i = 0;
    let k = Math.floor(heap.length / 2);
    let j;

    while(i < k) {
      j = (i * 2) + 1;
      if(heap[j+1] < heap[j]) ++j;

      if(popped <= heap[j]) break;

      heap[i] = heap[j];

      i = j;
    }

    if(heap.length) {
      heap[i] = popped;
    }

    return top;
  }
  
  // 要素数を返す
  size() {
    return this.heap.length;
  }
  
  // 先頭を返す
  top() {
    return this.heap[0];
  }
}

// 使用例
const pq = new PriorityQueue();
pq.push(10);
pq.push(30);
pq.push(2);
pq.push(-10);

console.log(pq.top()); // 30
console.log(pq.pop()); // 30
console.log(pq.top()); // 10
```
TECH CAMP 3週目

1〜2週目で基礎カリキュラムを終え、3週目からは応用カリキュラムへと入りました。
そういえば新型コロナの影響であらゆるスポーツが自粛となっていますが、野球好きな自分としては今年はシーズンが開幕出来るかどうか微妙なところで、特に（どの部活もそうですが）高校野球なんかは3年生は可哀想ですよね。ちなみにホークスファンです。

【学習内容】
・検索力、読みやすいコード
・JavaScript、jQuery基礎
・Git、GitHub
・SQL
・データベース設計
・Sass、haml

まず応用カリキュラムに入るにあたって、メンターへの質問方法が変わります。
これまではわからないことがあればエラー内容をそのまま教えてもらったり、ミスしている部分を修正してもらえたのですが、これからは検索して調べ、そこから仮説を立てて実践、それでもわからなければメンターへその内容を踏まえ質問をする、という形式です。（個人的にはこれまでもそのように質問していましたが、社会人経験あれば上司や先輩に質問する時は実際そうしますよね。）

**・検索力、読みやすいコード**
エンジニアに必要な検索力を身につけよう、ということで検索の際のキーワード選びや目的の情報が載っているサイトの選び方、あとは期間指定で新しい記事を探す方法を学びました。この能力はどれだけ数をこなしていくか、ですね。今の時代は知識力より検索力だな、思いますし。
あとは読みやすいコード・良いコードを書く、という意識をつけることを学びました。
命名規則、レイアウト、コメント、リファクタリング。やはりアプリケーションは自分だけで作るわけでなく共同開発をするもので、さらに後で見返してもすぐに理解が出来るように、という観点からも大事な部分だと思いました。

**・JavaScript、jQuery基礎**
Webアプリケーションを作る上で必要不可欠な言語。基礎的な部分のみですが難しく感じました。また、これまでの学習内容よりもさらっと流れていく印象でした。これは実際に実装していく中で覚えていこうと思います。jQueryは極めたら楽しそうですね。画面が動くっていうのは、やっぱりこれやりたくてプログラミング学んでいる、みたいな部分ありますし。

**・Git、GitHub**
共同開発していく上で必要なツールで、これからは課題を作成しながらメンターへ都度GitHubを用いて確認してもらいます。データの動きがイメージ出来るようになるまでは扱いが難しい‥。そうです、ここから自分自身の鬼門となっていったツールです‥。

**・SQL**
基礎カリキュラムでもRailsでアプリを作る際はMySQLを使用していました。ではそのSQLとは？データベースとは？からその構造の操作を学習しました。多少Excelに近い印象はあったので、入りやすかったですね。

**＜課題：Chatspace＞**
これからはChatspace作成に入ります。カリキュラムはほぼヒントのみで、あとはかなりの自走力を必要とします。まずはデータベース設計です。

**・データベース設計**
エンティティ、リレーション、あとはNOT NULL制約などを学び、実際に必要なテーブルを設計していきます。まずは機能とその関係性を紙に書き出して、あとは制約やキーを考えつつ設計していきました。ただ、ここで難しいのは中間テーブルと呼ばれるもので、例えば、ブログであればユーザーとブログは’1対多’、しかしチャットでのユーザーとグループの関係だと’多対多’となってしまい、その際に中間テーブルが必要になってきます。
とりあえず設計したものをGitHubでプルリクエストし、メンターへ確認してもらいます。

「中間テーブルについて調べてください。」
具体的におかしい箇所の指摘ではなくこういう感じなんだな、と。カリキュラムだけでは理解出来なかったので検索してその表記方法を学び、手直し。そして再度確認してもらいます。

「マージされています。元に戻してください。」
初めてGitHubを使う自分としては「‥？」状態です。なんだかとんでもことをしてしまったような気がして、そこから試行錯誤、検索して元に戻す方法を考えて四苦八苦です。結局はメンターへ聞き元へ戻りました。（というかリセットした感じですね。）そして再度プルリクエスト。

「LGTM」
ようやくデータベース設計完了です。

**・Sass、haml**
ここからはフロント画面の実装です。これまではCSSとHTMLで見た目の部分を作成していましたが、ここからはSass、hamlで作成していきます。個人的にはcssよりわかりやすくて好きです。親要素・子要素が見えてるんで。これに慣れたら戻れないかもしれません。
ここでもカリキュラムだけでは解けない課題がどんどん出てきます。ここはもう検索と、Chatspaceのサンプルがあるのでそこで検証ツールを確認して作成していきました。特にアイコンと投稿フォーム作成に苦労しましたね。ここはなかなかうまくいきませんでした。
この段階であることを忘れていることにこの時は気付いていません‥。実は、フロント画面実装に必要なブランチを作成していませんでした。

作成に着手したのが木曜日の昼過ぎあたり。カリキュラム的には2日間とってあるので、目標は金曜日に完成。細かいタイプミスや、&__や.の使い方だったりで詰まる事も多く苦労しました。しかし結果的には金曜日の21時過ぎに完成。メンターの締め切りが22時。1発でOKでなかったら目標クリアは厳しいかな、と思いつつプルリクエスト‥。あれ？これで良いのか？そうです、ブランチ作成を怠ったことでまたもよくわからない事態に。とりあえずブランチを作成してプルリクエスト。

「差分がわからないのですがpushをお願いします。」
またも「‥？」です。この時点で21時半。変な汗が出ます。そこからまたも検索。
GitHubの中身を地道に日本語訳しながら四苦八苦。21時45分。
そして、今回はメンターに頼らず自分で解決！
おそらく大丈夫だろうとプルリクエスト！

「LGTM」
22時まであと少しでした。ギリギリセーフ！

冒頭の野球の話に戻りますが、個人的には1塁へのヘッドスライディングって好きではありません。高校野球では特によく見ますよね。物理学的には滑り込む角度やタイミングが完璧でないと走り抜ける方が早いですし、怪我をする可能性が非常に高いのです。
でもこの時の自分は思わずヘッドスライディングする選手の気持ちがわかりました（笑）
実際この目標は自分の設定したもので、カリキュラム的には来週の火曜日に完成すれば良いのです。別に間に合わなくても土曜日の朝一でもそんなに進捗に影響ないですし。

だけど最後はそんなこと考えずにヘッドスライディングしてしまいましたね。
AWSへのrails:db seedでハマった件と対処法

#AWSへのrails:db seedでハマった件と対処法

##背景
AWS上のアプリに対してローカル環境からrails db:seedを実行したところ以下のエラーが発生し、
ハマったので記録しておきます。
*エラーは _task-appというroleがAWS上にありません_ というエラー

```bash
MAC: XXX$ bundle exec rails db:seed RAILS_ENV=production
rails aborted!
ActiveRecord::NoDatabaseError: FATAL:  role "task-app" does not exist
```

## 目次
* [動作環境](#動作環境)
* [結論](#結論)
* [経緯](#経緯)
* [原因](#原因)
* [おわりに](#おわりに)

---------------------------------------
## 動作環境
`OS : macOS Mojave 10.14.6`
`ruby : 2.6.3p62`
`rails : 5.2.4`

## 結論
AWS上で`/var/www/アプリケーション名/current`に移動し、以下を実行することでseedデータを生成できました。

```bash:aws
bundle exec rails db:seed RAILS_ENV=production
```

## 経緯

AWS上にtask-app名でroleは作成し、databaseも作成していました。
そのため、なぜ作成したはずのロール名でrole does not existエラーが出てしまうのかと原因がわからず格闘していました。

##　原因

メンターに確認したところ

>AWS上のデータベースのseedの実行は、AWS上のデータベースに対して実施、作る必要があります。
したがって、AWSにログインして、そこでrails コマンドを実行する必要があります。
Herokuの場合は、herokuコマンドによって、Herokuのサイトにあるデータベースを作りに行ってくれますが、、AWSの場合は、自分でログインして実行する必要があります。
ローカル、Heroku、AWSのデータベースはそもそも作成している場所が全く違います。

つまりエラーの原因は本番環境のデータベース操作をローカル環境から行おうとしていたこと。
Herokuではローカル環境からできていたので、AWSもローカル環境からできると思っていました。

実際、ローカル環境のロールを確認してみるとtask-appというロール名はありませんでした。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/526570/316d5aa3-8c26-d6a2-2610-0fdad1fe0162.png)


## おわりに

今回の件で以下のことを学んだ。
 1. AWSのデータベースに関する操作はAWSにログインして実行する
 2. ローカル環境・AWS環境のデータベースとロールは同じでないこと
cc1.exe: sorry, unimplemented: 64-bit mode not compiled inの解決(Windows)


# はじめに
Go言語の勉強中、`go get -u github.com/mattn/go-sqlite3`を実行しようと思ったらこんなエラーが

```sh
cc1.exe: sorry, unimplemented: 64-bit mode not compiled in
```
まーたこんなエラーだよ…とすべてを投げ出したい気持ちを抑えて、とりあえずエラー文で検索して解決まで至りました

# いざ解決
とりあえずこのまま調べるとgithubのこんなページを発見
<a href="https://github.com/golang/go/issues/29679">参考ページ</a>

どうやら**MinGWの64bit版**をインストールしろ、とのこと。
自分はMinGWはインストールしてたつもりだが、32bit版でこんなエラーが出たんだと思う
<a href="https://www.javadrive.jp/cstart/install/index6.html">MinGW-w64のダウンロード方法</a>
**注意！**
インストールの際、青で囲った部分に注意しましょう
![キャプチャ4.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/450534/30c59491-0197-fa25-7106-bd7125bc5d77.png)


インストールできたらpathを通します
`C:\Program Files\mingw-w64\x86_64-8.1.0-posix-seh-rt_v6-rev0\mingw64\bin`
(多分デフォルトだとこれ)

# もう一度トライ！！

ここまできたら、もう一度`go get -u github.com/mattn/go-sqlite3`コマンドを実行


・・・・


**デデドン！**

```sh
cc1.exe: sorry, unimplemented: 64-bit mode not compiled in
```
実は筆者はここでも失敗

あれー？ということで、gccのバージョンを確認してみた

```sh
gcc -v
```
すると、

```sh
COLLECT_LTO_WRAPPER=C:/Program\ Files/mingw32
#ログが残ってなかったから一部をざっくり表記しました…
```
と、前のmingw32のpathが優先されていました。ということで、mingw32のpathを消して、もう一度トライ。

これでできると思います。

# 最後に

goのこういったgithubのあれこれでトラブルを起こすのはもうこりごりです・・・
では


# 参考にしたページ
<a href="https://github.com/golang/go/issues/29679">github</a>
<a href="https://www.javadrive.jp/cstart/install/index6.html">MinGW-w64のダウンロード方法</a>
Mac LaravelでBootstrapを使おう！

# 目的

- LaravelでBootstrapを使う方法をまとめる。

# 実施環境

- ハードウェア環境

| 項目 | 情報 |
| --- | --- |
| OS | macOS Catalina(10.15.3) |
| ハードウェア | MacBook Pro (16-inch ,2019) |
| プロセッサ | 2.6 GHz 6コアIntel Core i7 |
| メモリ | 16 GB 2667 MHz DDR4 |
| グラフィックス | AMD Radeon Pro 5300M 4 GB Intel UHD Graphics 630 1536 MB |

- ソフトウェア環境

| 項目 | 情報 | 備考 |
| --- | --- | --- |
| PHP バージョン | 7.4.3 | Homwbrewを用いて導入 |
| Laravel バージョン | 7.0.8 | commposerを用いて導入 |
| MySQLバージョン | 8.0.19 for osx10.13 on x86_64 | Homwbrewを用いて導入 |

# 実施方法概要

1. style sheetのリンクをBootstrapに設定
1. 確認コードを貼り付けてチェック

# 実施方法詳細

1. style sheetのリンクをBootstrapに設定
    1. 下記のコードをBootstrap対応させたいビューファイルのhead内に記載する。

        ```html
        <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
        ```

1. 確認コードを貼り付けてチェック
    1. 下記コードを前述のstylesheetのリンクを記載したビューファルに記載する。

        ```html
        <nav class="navbar fixed-top navbar-light bg-light">
          <a class="navbar-brand" href="#">Fixed top</a>
        </nav>
        ```

    1. アプリを起動し当該ビューファイルをみた時に下記のように表示される事を確認する。
    
    <img width="600" alt="2306AFC9-D556-4F11-8897-9081C49ED35C.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/e446e35a-1b0f-5f3c-4067-c5d6cc239b82.png">
Ubuntu 20.04にOpenJDK 11をインストール（Amazon Corretto）

# はじめに

Amazon Correttoを利用してUbuntu20.04にOpenJDK11をインストール
親記事：[OpenJDKの各種インストール方法とEOLまとめ](https://qiita.com/witchcraze/items/b179202216aab50b7090)
参考：[Debian ベースおよび RPM ベースの Linux ディストリビューションで Amazon Corretto 11 をインストールする手順 - Amazon Corretto](https://docs.aws.amazon.com/ja_jp/corretto/latest/corretto-11-ug/generic-linux-install.html)

## サポート

本手法で導入した場合、[よくある質問 - Amazon Corretto | AWS](https://aws.amazon.com/jp/corretto/faqs/)より、2027-09がEOLになると思われる。
それ以降に報告された脆弱性や不具合への対応は実施されない可能性がある。

## LOG

### インストール

[Amazon Corretto 11 のダウンロード - Amazon Corretto](https://docs.aws.amazon.com/ja_jp/corretto/latest/corretto-11-ug/downloads-list.html)より適切なファイルを確認。
リンク先のファイルが古いときは[英語版ページ](https://docs.aws.amazon.com/corretto/latest/corretto-11-ug/downloads-list.html)を参照。

```shell-session
# cat /etc/os-release
NAME="Ubuntu"
VERSION="20.04 LTS (Focal Fossa)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 20.04 LTS"
VERSION_ID="20.04"
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
VERSION_CODENAME=focal
UBUNTU_CODENAME=focal

# apt update;apt install -y wget java-common
# wget -O jdk11.deb https://xxxx/11.xxxx/java-11-amazon-corretto-jdk_11.xxxx.deb && dpkg --install jdk11.deb
... 略
```

### 各種確認

```shell-session
# which java
/usr/bin/java

# java -version
openjdk version "11.0.7" 2020-04-14 LTS
OpenJDK Runtime Environment Corretto-11.0.7.10.1 (build 11.0.7+10-LTS)
OpenJDK 64-Bit Server VM Corretto-11.0.7.10.1 (build 11.0.7+10-LTS, mixed mode)
```
Windows 上で Electron の半透明ウィンドウを作る

Electron で半透明のウィンドウを作ってみたくなったので調べてみた。

大まかなやり方はパターンが２つあって、どちらにも異なる制約がある。

- opacity を使う
- transparent を使う

# 設定場所

BrowserWindow を作るときのオプションで設定できる。
ここでは、２つのやり方を両方とも設定してみてある。

https://www.electronjs.org/docs/api/browser-window#new-browserwindowoptions

```javascript
  const win = new BrowserWindow({
    transparent: true,
    opacity: 0.3,
    frame: false,
  });
```

# 1. opacity を使う

https://www.electronjs.org/docs/api/browser-window#winsetopacityopacity-windows-macos

この設定方法は、文字も含めて、ウィンドウ全体が半透明になる。
使えるよう場所は少ないように思う。

# 2. transparent を使う

こちらは部分的な半透明にも対応できる。
ただ、制約があって、Windows ではフレーム無しのウィンドウの場合にしか使えないらしい。

https://www.electronjs.org/docs/api/browser-window#new-browserwindowoptions

ここの transparent の項目で以下のような説明がある。

> transparent Boolean (optional) - Makes the window transparent. Default is false. On Windows, does not work unless the window is frameless.

なので、設定としては以下のような設定になる。

```javascript
  const win = new BrowserWindow({
    transparent: true,
    frame: false,
  });
```

ウィンドウを作った後は、css で透明度を設定すれば、設定した場所が設定した透明度になる。

```css
#main {
        background-color: rgba(0, 0, 0, 0.4);
}
```

box-shadow などでも半透明が効くようでかっこいい。
Ubuntu 20.04にOpenJDK 8をインストール（Amazon Corretto）

# はじめに

Amazon Correttoを利用してUbuntu20.04にOpenJDK8をインストール
親記事：[OpenJDKの各種インストール方法とEOLまとめ](https://qiita.com/witchcraze/items/b179202216aab50b7090)
参考：[Debian ベースおよび RPM ベースの Linux ディストリビューション用の Amazon Corretto 8 のインストール手順 - Amazon Corretto](https://docs.aws.amazon.com/ja_jp/corretto/latest/corretto-8-ug/generic-linux-install.html) 

## サポート

本手法で導入した場合、[よくある質問 - Amazon Corretto | AWS](https://aws.amazon.com/jp/corretto/faqs/)より、2026-05がEOLになると思われる。
それ以降に報告された脆弱性や不具合への対応は実施されない可能性がある。

## LOG

### インストール

[Amazon Corretto 8 のダウンロード - Amazon Corretto](https://docs.aws.amazon.com/ja_jp/corretto/latest/corretto-8-ug/downloads-list.html)より適切なファイルを確認。
リンク先のファイルが古いときは[英語版ページ](https://docs.aws.amazon.com/corretto/latest/corretto-8-ug/downloads-list.html)を参照。

```shell-session
# cat /etc/os-release
NAME="Ubuntu"
VERSION="20.04 LTS (Focal Fossa)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 20.04 LTS"
VERSION_ID="20.04"
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
VERSION_CODENAME=focal
UBUNTU_CODENAME=focal

# apt update;apt install -y wget java-common
# wget -O jdk8.deb https://xxxx/8.xxxx/java-1.8.0-amazon-corretto-jdk_8.xxxx.deb && dpkg --install jdk8.deb
... 略
```

### 各種確認

```shell-session
# which java
/usr/bin/java

# java -version
openjdk version "1.8.0_252"
OpenJDK Runtime Environment Corretto-8.252.09.1 (build 1.8.0_252-b09)
OpenJDK 64-Bit Server VM Corretto-8.252.09.1 (build 25.252-b09, mixed mode)
```
G Suiteのメール設定でハマった話

# はじめに
どうも‪✋(´･ᴗ･\` )‬
COVID-19で外出できなくてGW暇だろうし, どうせなら前から気になっていたG Suiteの検証でもして良さそうならめんどくさい移行作業なんかもGW中に済ませてしまおう!なんて思い立って意気揚々とG Suiteの試用を始めたら, 開始5分でハマってだいぶ時間を使ったので記事にしました。

# Gmailのメール受信設定
## 前提条件(再現条件)
- ドメインをGoogle Domainsで取得していること
- ドメイン取得にはG Suiteとは関係ない**通常のGoogleアカウント**を使用していること

## ハマった時の話
Google Doaminsで取得したドメインでGmailの設定をしようとすると, 「ドメインホストGoogle Domainsが検出されました。ログインして, ドメインの設定に確認コードを追加してください。」というメッセージと共にGoogle Domainsでの操作手順が表示されます。内容としては[Google Domains: G Suite の MX レコードを設定する - G Suite 管理者 ヘルプ](https://support.google.com/a/answer/6248174?hl=ja&ref_topic=4445319)に記載されている内容と同じです。
<img width="827" alt="スクリーンショット 2020-04-25 18.25.37.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319289/f9eff873-9843-ebf4-cbb3-8d3db04bb88a.png">

これに沿って設定していくと, [Google Domains: G Suite の MX レコードを設定する - G Suite 管理者 ヘルプ](https://support.google.com/a/answer/6248174?hl=ja&ref_topic=4445319)の「手順 3: ドメインの所有権を MX レコードで確認する(省略可)」というセクションに書かれている手順を実施した時, 「すでに使用されているレコードです」というエラーが出てきます。
(「省略可」と書かれていますが省略はできません。)
<img width="963" alt="スクリーンショット 2020-04-25 18.18.48.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319289/3996c52e-b289-c3b8-b7ee-5a0bdbabedb8.png">

こうなってしまう原因は, Google Domainsでドメインを取得したからと, G Suiteの設定手順に出てきた手順をそのまま実行してしまったことにあったようです。
次のセクションで説明する通り, G Suiteに特化した手順ではなく, [G Suite と Gmail 向けに MX レコードを設定する - G Suite 管理者 ヘルプ](https://support.google.com/a/answer/140034)に書かれている「一般的な」手順を踏んで登録する必要があります。

## ハマらない手順
① **ドメイン登録をしたアカウント**でログインし, [Google Domainsの管理ページ](https://domains.google.com/)にアクセスします。

② 「マイドメイン」からG Suiteに設定したドメインを選択します。
<img width="298" alt="スクリーンショット 2020-04-25 19.25.21.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319289/c9540b9a-d91f-bec3-cfc4-e07f963c3ac2.png">

③ [G Suite と Gmail 向けに MX レコードを設定する - G Suite 管理者 ヘルプ](https://support.google.com/a/answer/140034)に書かれている通り, のMXレコードを追加します。
Google　Domainsには「優先値」を設定するための専用フィールドはありませんので, `1 ASPMX.L.GOOGLE.COM` のように `<優先値>+半角スペース+<値>` のように入力していきます。

④ [G Suite と Gmail 向けに MX レコードを設定する - G Suite 管理者 ヘルプ](https://support.google.com/a/answer/140034)に記載されているレコードと, 確認用レコード(優先値が `15` のもの)を設定し終えたら「追加」をクリックします。
<img width="961" alt="スクリーンショット 2020-04-25 18.26.45.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319289/aa65d9d8-cabf-a795-2ed2-274d86d1a2cf.png">

⑤ ここまでの手順を実施したら, **G Suiteの管理用アカウントでアクセスしている(はずの)**G Suiteの設定画面に戻り, 「Gmailを有効化」ボタン(スクショ忘れましたすみません)をクリックすると, こんな画面と共に少しだけ待たされます。
<img width="846" alt="スクリーンショット 2020-04-25 18.28.10.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319289/abec17f5-7ebe-a728-238b-44f27dced768.png">

⑥ 「 `<ドメイン名>` でGmailが有効になりました」とメッセージが出たら完了です。
<img width="741" alt="スクリーンショット 2020-04-25 18.29.33.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319289/0fb856d3-18ce-1e47-fe16-03ada05bf5fd.png">

# さいごに
ググっても出てこないトラブルだったので手探りで解決策を探しました。
間違っている等ございましたら編集リクエストやコメントにてご指摘いただけるとありがたく思います。
MySQL5.7に入門してみる~InnoDBと仲良くなりたい~  

はじめに
===
前回MySQLのアーキテクチャについて調べていました。
その中でストレージエンジンがMySQLの理解を深めるのに重要そうだったので、ストレージエンジンともう少しお友達になりたいと思います。その中でも今回はInnoDBについてまとめます。

(前回のアーキテクチャに関する記事は [こちら]( https://qiita.com/nyankichikun/items/f6ac04db0470d632a23c) をご覧ください)

InnoDBの特徴
===
- クラッシュリカバリ
- トランザクション(ACID)
- 外部キー
- 主キーに基づいたクエリ最適化(データの整列)

割と当たり前だと思っていたトランザクション対応なんですけど、MySQLのストレージエンジンだと InnoDBだけなんですね。MySQLに詳しくないけど、トランザクションとか主キー、外部キーとかは知ってる方は多いのでは？と思います。

ただ、クラッシュリカバリ。。ね。。。。。。うん、わかるけど何してるんだ？って感じです。どんなことをやってるんですかね？

## クラッシュリカバリ
MySQLが起動しているサーバに障害が発生し再起動が発生しても、自動的にリカバリしてくれる優れものです。リカバリのプロセスは下記のような流れです。

- Redoログの適用(あれば)
- 未完了トランザクションのロールバック
- 挿入(変更)バッファのマージ
- パージ


### Redoログの適用
そもそもRedoログって話ですよね？Redoログとはクラッシュリカバリ中に、完全なトランザクションによる書き込まれるデータを訂正するためのデータです。
テーブルデータの変更の度にレコード単位でエンコードされ(このデータをまとめてRedoといいます)、`ib_logfile0, ib_logfile1`という名前が付けられ保存されます。**まずはログバッファ(メモリ)に書き込まれ、その後ログファイルに書き込まれます。**

`シャットダウン前にこのデータファイル(テーブルデータ変更を記録しているデータファイル)の更新が終了されていない = リカバリ後に再度実行する必要`があるって感じです。※似たようなログで binlog というのがあるのですが、用途やレイヤーが違うため今は言及しません

### 未完了トランザクションのロールバック
そのままなので特になし！

### 挿入(変更)バッファのマージ
これまた変更バッファとは？ってなります。**変更バッファとは、読みだすデータ(ページ)がメモリ(バッファープール内)に無い場合に、セカンダリインデックスエントリへの変更をキャッシュしているデータ**です。
このデータは`ページがメモリにロードされたタイミングでマージされ、最終的にはディスクに書き出されます。`呼び出されたタイミングでのマージだけではなく、サーバがほぼアイドル状態の時やクリーンシャットダウン(終了前にテーブルに全て適用させるシャットダウン)の際にもマージされます。

### パージ
ガベージコレクションの一種です。スレッドが別途立ち上がり、定期的に下記を実行します。

- 使われなくなったインデックスの削除
- DELETEステートメントの物理的な削除

`DELETEステートメントは即座にレコードの削除を行わず、「削除」とマークされるだけです(これ以降クエリから返されなくなります)。パージ処理によって「削除」とマークがついたレコードは削除されます。`

まとめ
===
いかかでしたかね？InnoDBの特徴についてなんとなくでもご理解いただけたでしょうか？(ほとんどクラッシュリカバリの処理を追っているだけな気もしますが)

ただ調べて思ったのはわからない用語が多すぎますね、ほんとに。なので次はまた少し脱線して用語についても自分なりにまとめたいなと思いました。

ではみなさん、またの機会があれば。。。

参考
===
[リファレンスマニュアル](https://dev.mysql.com/doc/refman/5.6/ja/)
ページネーション（該当ページの最初と最後のデータは全データの中で何番目か実装する）

##はじめに
下記画像のようにページネーションをしたときに該当ページの最初と最後のデータは全データの中で何番目か(N〜NN件/NNN件中のように)出したい時はありませんか。
<img width="329" alt="スクリーンショット 2020-04-25 18.54.06.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/384180/31393e07-2d6d-eb21-4cc6-afe9c1290310.png">
ControllerやModelなどで値をわざわざ取得しなくてもLaravelのフレームワークを用いて値を取得することができます。

##フレームワークを覗いて実装してみる
Laravelのフレームワークにはページネーションに必要な要素が元々実装されています。

※全体は[こちら](https://github.com/illuminate/pagination/blob/master/Paginator.php#L136)から確認してください。

```php:Illuminate\Pagination;
    /**
     * Get the instance as an array.
     *
     * @return array
     */
    public function toArray()
    {
        return [
            'current_page' => $this->currentPage(),
            'data' => $this->items->toArray(),
            'first_page_url' => $this->url(1),
            'from' => $this->firstItem(),
            'next_page_url' => $this->nextPageUrl(),
            'path' => $this->path(),
            'per_page' => $this->perPage(),
            'prev_page_url' => $this->previousPageUrl(),
            'to' => $this->lastItem(),
        ];
    }
```


ここにあるのを使って

```php:page.twig
data.firstItem()
data.lastItem()
data.total()
```

```php:page.blade.php
data->firstItem()
data->lastItem()
data->total()
```
と実装すると該当ページの最初と最後のデータは全データの中で何番目か取れます。

##おわりに
いかがでしたでしょうか。
フレームワークを使う場合はその特有の機能も使っていきたいですね。
python、クラスについて

Personのクラスについてメモ。

以下、Personクラスを作成してみる。

```.py
class Person:
 
 #初期設定
 def __init__(self, name,company,age):#selfはとりあえず必要
   self.name = name
   self.company = company
   self.age = age

 def say_hello(self,name):#selfはとりあえず必要
   print("こんにちわ{}さん。私ば{}です。".format(name, self.name))

 def __call__(self, name):#selfはとりあえず必要
   print("こんにちわ{}さん。私ば{}です。".format(name, self.name))
 
-------------------------------------------------------
Suzuki = Person("鈴木","ABC商事",45)
Suzuki.name
#鈴木

Suzuki.say_hello("加藤")
#こんにち加藤さん。私ば鈴木です。

Suzuki("田中")
#こんにちわ田中さん。私ば鈴木です。
#call関数はSuzuki.__call__("田中")としなくて良い（これでも可能だが適切ではない）

```
【Swift】式展開

#式展開
Swiftでの式展開の方法を紹介します。
バックスラッシュと小カッコで式展開が可能です。また、コメントアウトもかけます。

```swift
//式展開
var name = "Tanaka"
print("Hello \(name))" ///Hello Tanaka

//コメントアウト
var food = "lemon"
print("\(food  /* コメントも書ける */) is fruits") //lemon is fruits
```
aws-sdk-mockを使ってもS3がモックに差し替わらずに困りました

[aws-sdk-mock](https://github.com/dwyl/aws-sdk-mock)を使ってもS3（にアクセスするAWS SDK）がモックに挿し変わらずに困り果ててました・・。

明示的にaws-sdkのパスを指定することで解決しました。

```javascript:jestのテストコード
const awsMocker = require('aws-sdk-mock');

// 【ここがポイント】 以下のようにaws-sdkのパスを明示的に指定する必要がありました。
const path = require('path');
awsMocker.setSDK(path.resolve('node_modules/aws-sdk'));

const testee = require('テスト対象ファイルへのパス');

// その他 略

describe('S3の画像保存テスト', () => {
    describe('正常時', () => {
        it('putObjectを1回だけ実行する', async done => {
            let calledCount = 0;

            awsMocker.mock('S3', 'putObject', (params, callback) => {
                calledCount++;
                callback(null, {
                    "ETag": "00000000000000000000000000000000"
                });
            });

            await testee.putImage({ "filename": "test.txt", "file_base64": "YWJjZGVmZw==" });

            expect(calledCount).toBe(1);
            done();
        });
    });
});
```

おそらく、aws-sdkへのパスが明示的に指定されないと、aws-sdk-mockさんは差し替え対象のaws-sdkを正しく特定できないのでしょう。

その結果、本物のS3のSDKが動いてしまったのだと思います。

地味なところで時間を使ってしまったのでした・・。
Ubuntu 20.04にOpenJDK 14をインストール（Zulu Community）

# はじめに

Zulu Communityを利用してUbuntu20.04にOpenJDK14をインストール
親記事：[OpenJDKの各種インストール方法とEOLまとめ](https://qiita.com/witchcraze/items/b179202216aab50b7090)
参考：[Download OpenJDK Java Linux Windows macOS Alpine Java 11 Java 8](https://www.azul.com/downloads/zulu-community/)

## サポート

本手法で導入した場合、[Zulu Community Java OpenJDK free download TCK tested](https://www.azul.com/products/zulu-community/)より、2020-09がEOLになると思われる。
それ以降に報告された脆弱性や不具合への対応は実施されない可能性がある。

## LOG

### レポジトリ登録

```shell-session
# apt update; apt install -y software-properties-common
# apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 0xB1998361219BD9C9
# apt-add-repository 'deb http://repos.azulsystems.com/ubuntu stable main'
```

### インストール

```shell-session
# cat /etc/os-release
NAME="Ubuntu"
VERSION="20.04 LTS (Focal Fossa)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 20.04 LTS"
VERSION_ID="20.04"
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
VERSION_CODENAME=focal
UBUNTU_CODENAME=focal

# apt update; apt install -y zulu-14
... 略
```

### 各種確認

```shell-session
# which java
/usr/bin/java

# java -version
openjdk version "14.0.1" 2020-04-14
OpenJDK Runtime Environment Zulu14.28+21-CA (build 14.0.1+8)
OpenJDK 64-Bit Server VM Zulu14.28+21-CA (build 14.0.1+8, mixed mode, sharing)
```