OmniAICreator/Qiita-1.07M huggingface dataset:
はじめてのDocker compose

## はじめに

以下のような構成で記事を執筆していますが、
どこからでも読めるような構成になっています。

1. [ゼロから始めるDocker入門](https://qiita.com/suzu12/items/315fba934de11af826bd)
1. [はじめてのDockerfile](https://qiita.com/suzu12/items/c4bc47c0df6ec9b9290b)
1. [はじめてのDocker compose](https://qiita.com/suzu12/items/4ec2cc8c1a7c23aa112b) ←今回はここ

## 対象読者

- `Docker` の使用に慣れてきた方
- `docker-compose.yml` でなにをしているのか知りたい方

## 目次

- [はじめに](#はじめに)

- [対象読者](#対象読者)

- [目次](#目次)

- [Docker Composeとは](#docker-composeとは)

- [Docker compose](#docker-compose)

    - [ディレクトリ構造](#ディレクトリ構造)

    - [docker-compose.yml](#docker-composeyml)

    - [Dockerfile](#dockerfile)

- [Compose コマンド](#compose-コマンド)

- [おわりに](#おわりに)

- [参考文献](#参考文献)


## Docker Composeとは

`docker-compose.yml` という `yml` 形式のファイルに
複数のコンテナを定義し実行することができるツールです。

## Docker compose 

どのように書いていくのか確認していきます。
(**※ 最低限の設計です**)


### ディレクトリ構造

```shell
.
├── docker
│   └── Dockerfile 
└── docker-compose.yml
```

### docker-compose.yml

```yml:docker-compose.yml
# バージョンの指定
version: '3.9'

# サービス定義
services:
  app:                              # サービス名(コンテナ名)
    build:                          # build
      context: .                    # build context
      dockerfile: docker/Dockerfile # Dockerfile の指定
    ports:                          # port指定(ホストのポートをコンテナのポートにつなげる)
      # host:container
      - "8000:80"
    volumes:                        # マウント(ファイルシステムの共有)
      # host:container
      - '.:/var/www/html'
```

### Dockerfile

```Dockerfile:docker/Dockerfile
# php のイメージ
FROM php:7.4-fpm

# コマンド実行ディレクトリ
WORKDIR /var/www/html

# パッケージインストール
RUN apt-get update \
  && apt-get install -y libonig-dev libzip-dev unzip

```


## Compose コマンド

使用頻度の高いコマンドです。

|　コマンド | 意味 |
|:-:|:-:|
| docker-compose build  | コンテナをbuildする |
| docker-compose up -d  | デタッチドモードで立ち上げ |
| docker-compose stop  | 実行中のコンテナを停止  |
| docker-compose down  | 実行中のコンテナを停止し削除 |
| docker-compose restart  | コンテナを再起動  |
| docker-compose exec [サービス名（コンテナ名）]　[command（bash）]  | コンテナに対しコマンド実行。bashを書くとコンテナ内に入ることができる。  |

## おわりに

今回3部構成で記事を執筆いたしました。
すべて読みすすめたら `Docker` に対して困ることは少なくなるのかなと思います。

もちろんすべてを網羅したわけではないですし、説明不足な点もあるかもしれませんが、
**「Dockerって何？」** というところから抜け出すきっかけになりましたら幸いです。

記事で足りない点は調べて補いつつ、さらに理解を深めたいときは
教材など購入、公式ドキュメントなど読みながら手を動かしてみると深く学ぶことができるのではないでしょうか。

## 参考文献

- [Docker Compose](https://docs.docker.jp/compose/index.html)
- [docker と docker-compose の初歩](https://qiita.com/hiyuzawa/items/81490020568417d85e86)
- [Docker compose ことはじめハンズオン](https://qiita.com/TsutomuNakamura/items/7e90e5efb36601c5bc8a)
- [マウント (mount)](https://wa3.i-3-i.info/word13188.html)
[Python3]　初心者の初心者による「リスト」基礎解説

#リストとは
**複数**の値を格納することができる機能です。
VBAでいえば、配列と同じようなものです。

#リストの作成方法
```python:リストの作成
# 以下がリストの書式です
[値1,値2,値3,....]

# 以下が実際のリスト作成方法です
RandomNumbers = [1,2,3,4,10,15]                      # 数値の場合

Fruits = ["orange" , "peach" , "banana" , "apple"]   # 文字列の場合

Mixed = ["aaaa" , 10 , "bbbb" , 20]                  # 混在の場合
```

リストの話とは関係ありませんが、**文字列**を格納する場合は**""**の中に記載することを忘れずに！！

上記以外に、組み込み関数の**list()**を使うことでもリストを作成することができます。

```python:list()を使用する場合
NumberList = list(range(-5,6))

# 出力結果
[-5,-4,-3,-2,-1,0,1,2,3,4,5]

# 空のリストを作成する場合
EmptyList = list()

# 出力結果
[]
```
#リストの要素参照

次は、実際にリストに格納した値を出力してみましょう。

```python:リスト内の値出力
# リストの作成
numbers = [10 , 20 , 30 , 40 , 50]

# 10を出力する場合
print(numbers[0])

# 30を出力する場合
print(numbers[2])
```

上記の様に、
**変数[インデックス番号]**　で指定することができます。
※**インデックス番号**は先頭から**0,1,2...**の様に数えます。
　その為、最初の値を取得したい場合のインデックス番号は1ではなく**0**になります。

#リスト内の要素変更

リスト内の値を指定し出力が可能になったので、
次はリスト内の要素を変更する方法を紹介いたします。

```python:リスト内の要素変更
# リストの作成
Fruits = ["orange" , "peach" , "banana" , "apple"]   

# orangeをgrapeに変更する場合
Fruits[0] = "grape"                  

# 出力結果
Fruits = ["grape" , "peach" , "banana" , "apple"]   
```

上記の様に変更したい要素のインデックス番号を指定し代入することで
要素の変更が可能になります。

#最後に
今回はリストの作成、要素取得、要素変更を記事にしました。
リストでは様々なことが行えます。
今回紹介できなかった、「要素の追加・削除」「リストのスライス」「内包表記」などは
次回の記事にて説明いたします。
まだまだ初心者ですが、皆様の役に立てれば幸いです。
間違い等ありましたら、ご教授お願いいたします。
Rails コンテナの docker build を高速化してみる

BuildKit を有効にして docker build した場合、どのくらい高速になるのか確認しました。

## BuildKit
詳細まで理解していませんが、ざっくりまとめると、

* 依存関係のない命令を並列実行できる
* コンパイラやパッケージマネージャのキャッシュディレクトリを保持できる

これらの仕組みにより、ビルドを高速化しているようです。

https://www.slideshare.net/AkihiroSuda/buildkit

## 利用方法
BuildKit は `docker v18.06` から使えます。
環境変数 `DOCKER_BUILDKIT=1` を設定するだけで有効になります。


## BuildKit 無効のとき

BuildKit を無効化。

```
$ export DOCKER_BUILDKIT=0
```

中間レイヤ削除とキャッシュ不使用のオプションを付けてビルド。

```
$ docker build . --rm --no-cache -t rails_app -f dockerfiles/rails/Dockerfile 
```

ビルド時間は `4m27s` でした。

## BuildKit 有効のとき

次は有効にしてビルドしてみます。

```
$ export DOCKER_BUILDKIT=1
```

```
$ docker build . --rm --no-cache -t rails_app -f dockerfiles/rails/Dockerfile 
```

ビルド時間は `2m54s` でした。

約35%のビルド時間削減になりました！（もちろん環境やイメージの内容にも依りますが） 

## ビルド時間の短縮以外で嬉しかったこと

ビルド中の画面出力が見やすくなっていました。
従来のビルドでは膨大な長さになる上に内容も分かりにくかったです。

BuildKit では、ステータスがレイヤ毎にまとめられています。
また、並列に処理が進んでいることが見て分かるようになってます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619762/c83e2e4a-5a18-0b61-e1b1-ad7d9b337562.png)

## まとめ
BuildKit を有効にしてビルド時間が短縮できることが確認できました。

BuildKit にはこの他にも機密情報をコンテナに渡すためのオプションや、SSH エージェントによる接続を許可するオプションなどが追加されているようです。またの機会に試してみたいと思います。

https://matsuand.github.io/docs.docker.jp.onthefly/develop/develop-images/build_enhancements/

ちなみに、ビルドした Dockerfile はこちらです。

https://github.com/sasamuku/vacabook_api/blob/master/dockerfiles/rails/Dockerfile
[Jexcel]Excelで開けるUTF-8ファイルを作る

※いわゆる「//なぜか動く」もので、個人の覚え書きです。

いまはJexcelでなく「[Jspreadsheet](https://bossanova.uk/jspreadsheet/v4/)」に改名したようですね。
設置方法については他の方の記事をご参照ください。

# CSVダウンロードすると当然のごとくUTF-8で落ちてくる
CSVビューアーを使ってくれればいいのですが、だいたいの企業の人間はCSVファイルを開くのにExcelを使います。
Excelで直接CSVファイルを開くと、文字コードがSJISでないと日本語が文字化けします。

# ダウンロード文字コードを変える
jexcel.jsの5926行目あたりにある以下の記述を変える

```javascript:jexcel.js
var blob = new Blob(["\uFEFF"+data], {type: 'text/csv;charset=utf-8;'});
```

↓

```javascript:jexcel.js
var blob = new Blob(["\uFEFF"+data], {type: 'text/csv;charset=sjis;'});
```

これだけで「Excelでそのまま開けるがテキストエディタでUTF-8と判定されるCSVファイル」が落ちるようになります。

「\uFEFF」はBOMです。
SJISでは本来不要ですが、これ外すとExcelで文字化けします。
いまのところCSVビューア勢からもExcel勢からも特に何も言われていませんが、バイナリレベルで操作すると何か不具合を起こすかもしれないため、自己責任で。
初めてのデザイン思考

#デザイン思考ってなぁに？#
クリエイティブな問題解決のための考え方
本質的には問題解決の方法を考えこと

**大切なのは、日常でやくに立てること、いかせること**


#有名なdスクールの５つのプロセス#
共感、問題定義、創造、プロトタイプ、テスト
＝＞ちょっと難しい

#簡略版３つのプロセス#
アイディア、試作、フィードバック
**アイディア**：困りごとに共感し、発想を得る
**試作**：アイディアを形にする、検証する
**フィードバック**：試作を確かめ、次に繋がる学びを得る

３つのプロセスを回しながらいいものを作っていく
**失敗を恐れずに試す！**


#デザイン思考を生かすマインドセット#
①面白いことがあるかもしれない　怖がらない
②まず試す。実験する。失敗してもいいじゃない
③アイディアはみんなで育てるもの　一人で悩まない


#アイディアを生む３ステップ#
①素材を集める（アンケート、ヒヤリング）
②発想する（フィルターインプット、アナロジー）
③クリエイティブモード（自分の枠に囚われない）

#自分の枠に気がつくための３つのトリガー#
①こんなのでいいのかな・・・？（失敗を恐れているかも？）
②それはないだろ・・・（自分の枠で考えてないか？）
多様性、ユーザー視点
③どうすればいいかな・・・？（問題ありきになってないか？そもそも本当に問題か？）
新しい発想で考える（もし〜ならどうか？）


#アイディア発見の３つのトリガー#
①動作のバグ（一連の動作の中で通る無駄な動き）はないか？
自分で普段やっていると気付きにくい
②愛のあるクレーマー（いちゃもんをつける＝＞改善案）
批判する＝＞問題が眠っているかも
③五感で考える（実際に動く、体験する）



#アイディア発想法#
##①機能分解##
対象の構成要素（機能、パーツ、できること、など）を洗い出し、パーツごとに進化させる
構成要素を洗い出し、その一つ一つを変化させ何かできるか？を考える
##②フィルタインプット##
対象に対し、何か（形容詞、名詞、など）を掛け合わせる
アイロンX軽い、アイロンX早い、アイロンX短い、アイロンX本、など
詰まった時はオズボーンのチェックリスト
できるか、できないかは後回し
##③アナロジー##
何かをたとえて、例えた世界で考える
似ているものに例える
バスケ＝＞サッカー
サッカーの世界にはオフサイドがある
ではバスケの世界にオフサイドがあったら？

それぞれを組み合わせる
マーカーペンの機能を分解してみる
・書ける
・消せる
・インクを入れる
似ているものに例える
・インクを入れる＝＞ペットボトル（水を入れる）
例えたものを分解する
・潰せる
・なんでも入る
・ラベルを貼る
元の世界に戻し、掛け合わせてみる
・マーカーペンX潰せる
・マーカーペンXなんでも入る
・マーカーペンXラベルを貼る



#試作しよう#
##マインドセット#
・まずはやってみる。失敗したっていいじゃない（失敗＝出来ない方法を知ること）
・試作は質問
・アイディアが一つでもあったら試し、質問してみる。フィードバックをもらえばさらに別のアイディアが生まれる
・試作は完成じゃない
・Fail Fast Learn Lost：早く失敗し、多くを学べ
・良質転換：まずは量、量をこなせばいつか質が上がる


##試作の進め方##
###コンセプトを作る（ユーザーの理想を明確にする）
・ターゲットは誰か？
・ターゲットにどう感じて欲しいのか？
###コンセプトを作ったらストーリーで肉付けする（ユーザーに共感し、こだわりを生み出す）
・ストーリーを作ることで、コンセプトがイキイキしてくる
・感情を動かすのがストーリー
・感情の起伏をイメージする
・ターゲットが困っている、だから改善の施策を行った、結果コンセプトが達成できた
###アイディアを具体的に形にしていく
####①絵で作る（イメージで直感的に表現する）
・説明する内容を絵で描き起こす
・絵を試作品としてフィードバックをもらう
・絵を描くうちに「気づき」が出てくる。発想が進む
####②紙で試作する（システムの動きを先に絵で体感する）
・絵を描き、動きを体感する
・新しい「気づき」やアイディアが生まれる
####③その場で考える（手法にとらわれず、最短最速で検証できるかを考える）
・施策の方法はなんでもいい
・質問でもフィードバックをもらえるのであればOK
####④こだわりを磨く（アイディアを育てる※アナロジー的思考）
・どうやって〇〇を作るか？（拘り、思いを込める）
・どうやって〇〇していくか？（理想の状態を考える）


##フィードバック
###仲間を作り、次に繋がる学びを得る
####①作った人目線
・ノリのいい人を探すして意見をもらう（否定しない人から建設的な意見をもらう）
・目撃者を作る（周りを巻き込み細かくフィードバックをもらう）
・アイディアを理解してもらう（評価してほしい部分を的確に伝える）
####②評価する人目線
・否定しない（Yes And を意識する）
・アイディアに対してフィードバックする
・ユーザー視点でフィードバックする
Nuxt jsデータからバインディングした値で画像を表示させる

#はじめに
タイトルの日本語があってるのかわかりませんが、やりたいのはこういう事👇です。ソースを見てわかってください。。。

```js:assets/js/data.js
export const resultsData = [
    {
        id: "00",
        text: "熱中する人",
        img: "charmander.png"
    },
    {
        id: "01",
        text: "達成する人",
        img: "caterpie.png"
    },
    {
        id: "02",
        text: "挑戦する人",
        img: "charmeleon.png"
    },
 ]
```

ここで定義したデータに画像が入ってます。

それを

```html
<h2>{{ result.text }}</h2>

<script>
import { resultsData } from "~/assets/js/data.js";

 computed: {
    result() {
      return resultsData.find(
        (result: { id: string }) => result.id == (this as any).answerKey
      );
    },
  },
</script>
```

みたいな感じで画像を取得するにはどうしたら良いか？
というお話です！

#バッククオートが重要

```html
<h2>{{ result.text }}</h2>
  <div class="mt-3">
        <img
          :src="require(`@/assets/images/type/${result.img}`)"
          class="contentImg"
        />
      </div>

<script>
import { resultsData } from "~/assets/js/data.js";

 computed: {
    result() {
      return resultsData.find(
        (result: { id: string }) => result.id == (this as any).answerKey
      );
    },
  },
</script>
```

この部分がなんて書いたら良いか分からず、、色々と試行錯誤した結果このようになりました！

```html
        <img
          :src="require(`@/assets/images/type/${result.img}`)"
          class="contentImg"
        />
```


requireを`""`で囲って、（）内のpathの部分はバッククオートで囲うのが正解なようです！
【Laravel】マイグレーションで外部キーを設定する場合の注意事項

マイグレーションでよく失敗する、

* カラムの型問題
* マイグレーションファイルの実行順問題

についてまとめておきます。

##カラムの型問題
外部キーを設定する場合は、参照先のカラムと同じ型にする必要があります。

一般に、プライマリーキーには以下のようにincrementsを指定しますが、これは自動的にunsigned int型のカラムを生成します。

```php:migrationファイル
$table->increments('id');
```

よって、外部キーを設定する際にもunsigned型を指定する必要があります。
※以下のどちらでも可。

```php:migrationファイル
//方法1
$table->integer('user_id')->unsigned()
//方法2
$table->unsignedInteger('user_id');

//共通
$table->foreign('user_id')
  ->references('id')->on('users')
  ->onDelete('cascade');　　　　　　//親テーブルで行削除された場合、子テーブルの対応する行も削除する
```


##マイグレーションファイルの実行順問題

外部キー参照先のマイグレーションファイルが実行されていない状態で、外部キーを設定したマイグレーションファイルが実行されると、参照するテーブルがないとエラーを返される。

```
SQLSTATE[42000]: Syntax error or access violation: 1072 Key column 'medium_id' doesn't exist in table (SQL: alter table `teaching_materials` add constraint `teaching_materials_medium_id_foreign` foreign key (`medium_id`) references `media` (`id`))
```

マイグレーションはファイルを作成した順（ファイル名になっている作成日時順）に実行される。
例えば、postsテーブルの外部キー参照先にusersテーブルを設定したい場合は、usersマイグレーションの作成後にpostsのマイグレーションファイルを作成し、マイグレーションを実行する。
Nucleo-F303K8 PIO STM32 でLチカ

Nucleo-F303K8
VScode + PlatformIO
framework は stm32cube を頑張って使ってみる。

# サンプルを修正して使う場合

サンプルコードを普通に手に入れて実行するけど，Lチカしない... 当たり前だよね... 以下の通り変更。



```cpp:platformio.ini
[platformio]
default_envs = nucleo_f303k8

[env:nucleo_f303k8]
platform = ststm32
framework = stm32cube
board = nucleo_f303k8
build_flags = -DF3
```

ビルド対象を nucleo_f303k8 にセット。

次に main.c で，LEDの定義を変更。PB3に修正。

```cpp:main.c
#define LED_PIN                                GPIO_PIN_3
#define LED_GPIO_PORT                          GPIOB
#define LED_GPIO_CLK_ENABLE()                  __HAL_RCC_GPIOB_CLK_ENABLE()
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533274/56d43bd4-0f19-6052-d70e-d76e48f33250.png)

できた！

# 簡略化してみた

platformio.ini はそのままでも...

```cpp:main.c
#include "stm32f3xx_hal.h"

void SysTick_Handler(void)
{
  HAL_IncTick();
}

int main(void)
{
  HAL_Init();

  // init PB3

  __HAL_RCC_GPIOB_CLK_ENABLE();
  GPIO_InitTypeDef GPIO_InitStruct;
  GPIO_InitStruct.Pin = GPIO_PIN_3;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

  while (1)
  {
    HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_3);
    HAL_Delay(1000);
  }
}

```
#おまけ

普通にデバッグできる。素晴らしすぎ。

PERIPHERALSを展開していくと，レジスターが見える。以下はGPIOB - ODR3 が 1 つまりLEDが点灯しているところ。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533274/881156cc-000a-375f-e23e-cd2ed781786f.png)
クラウドは計り売り、ラズパイは官給品

UNVT の特に能力構築関係で Raspberry Pi を使う意義を考えてみました。

1. AWS EC2 のようなクラウド環境は、計り売りです。
1. 他方で、Raspberry Pi は最初に買い切って愛護節約していくべきものです。つまり、官給品のような性質を帯びています。

特に能力構築や教育の分野では、努力をすればするほどコストがかかる計り売りモデルはやや不利です。米国で使われる教科書のように、官給品にしておいて愛護節約していくモデルの方が、能力構築や教育の分野には向いているのであろうと思いました。

クラウドは使えば使うほどコストになります。Raspberry Pi は使えば使うほどコストが回収されます。

使わせて鍛錬を積みたいのであれば、官給品モデルは悪いモデルではないのかもしれません。
ネストしたwithでリレーション先の情報取得するカラムを指定する方法

Laravelが提供するリレーションでは、`with`メソッドを使うことでJOINを使うことなく関係するテーブルに情報を取得できます。

### withの基本の使い方

```php
// 商品情報を出品ユーザー情報と一緒に取得する
$products = Product::with('user');
```
### withでのカラム指定
withを使う時は、`.`の後にカラムを記述することで、取得するカラムだけを指定することができます。
うっかり出品者のメアドやパスワードもレスポンスに含めてしまわないようにするためにも基本設定した方がいいですね。
(画面に表示してなくても、デベロッパーツールでレスポンスの見方を知ってる人には筒抜け)

```php
// 商品情報を出品ユーザー情報(名前のみ)を取得する
// リレーション参照のために、参照カラム(idやproduct_idなど)を含める必要あり
$products = Product::with('user.id,name');
```

### withでネストリレーション
商品情報とユーザー情報、さらにユーザーの画像情報(正規化して別テーブルに保存されている)と一緒に取得したい時は、ネストしたリレーションで取得することができます。

[公式リファレンス:ネストしたEagerロード](https://readouble.com/laravel/8.x/ja/eloquent-relationships.html)

```php
// 商品情報を出品ユーザー情報と一緒に取得する
$products = Product::with('user.image');
```

### ネストされたwithを使いつつ、参照カラムを指定する

・カテゴリーをメインに商品情報を参照
・さらに商品の出品者情報(usersテーブル)も参照したい
・usersテーブルにはemailなどのプライベートな情報があるので、カラム指定で取得するようにしたい

このパターンでは下記のように書く必要があります。

```php
// OK
$categories = Category::with('products', function($products) {
    // ユーザーの画像URLを取得
    $products->with('user:id,name');
});
```
＊ちゃんと確認してはいませんが、少なくとも5.8系以降では使用可能

ちなみに、↓のように書くとエラーになります。

```
// NG
$categories = Category::with('product.user:id,name');
```

withは便利ですが、不要なカラムは参照しないというセオリーを忘れずに使っていかなきゃですね！
rails s で An error occurred while installing pg (1.2.3), and Bundler cannot continue.が出た

##概要
macを買い替え、以前のPCで技術書を参考に自作したアプリケーションを立ち上げようとrails s をしたら、表題のエラーが出た。

##開発環境
`MacBook Pro (13-inch, M1, 2020)`
`macOS Big Sur バージョン 11.5.2`


##rails sでエラーが出た
```terminal:terminal
$ rails s
~
An error occurred while installing pg (1.2.3), and Bundler cannot
continue.
Make sure that `gem install pg -v '1.2.3' --source 'https://rubygems.org/'`
succeeds before bundling.
```

素直にやってみる。

```terminal:terminal
$ gem install pg -v '1.2.3'
```


```terminal:terminal
$ rails s
Ignoring bootsnap-1.7.3 because its extensions are not built. Try: gem pristine bootsnap --version 1.7.3
Ignoring bootsnap-1.7.1 because its extensions are not built. Try: gem pristine bootsnap --version 1.7.1
Ignoring bootsnap-1.5.1 because its extensions are not built. Try: gem pristine bootsnap --version 1.5.1
Ignoring eventmachine-1.0.9.1 because its extensions are not built. Try: gem pristine eventmachine --version 1.0.9.1
Ignoring ffi-1.14.1 because its extensions are not built. Try: gem pristine ffi --version 1.14.1
Ignoring ffi-1.13.1 because its extensions are not built. Try: gem pristine ffi --version 1.13.1
Ignoring ffi-1.12.2 because its extensions are not built. Try: gem pristine ffi --version 1.12.2
Ignoring msgpack-1.3.3 because its extensions are not built. Try: gem pristine msgpack --version 1.3.3
Ignoring nio4r-2.5.5 because its extensions are not built. Try: gem pristine nio4r --version 2.5.5
Ignoring nio4r-2.5.4 because its extensions are not built. Try: gem pristine nio4r --version 2.5.4
Ignoring sqlite3-1.4.0 because its extensions are not built. Try: gem pristine sqlite3 --version 1.4.0
Ignoring thin-1.8.0 because its extensions are not built. Try: gem pristine thin --version 1.8.0
Ignoring thin-1.5.1 because its extensions are not built. Try: gem pristine thin --version 1.5.1
=> Booting Puma
=> Rails 5.2.4.5 application starting in development 
=> Run `rails server -h` for more startup options
Puma starting in single mode...
* Version 3.12.6 (ruby 2.6.6-p146), codename: Llamas in Pajamas
* Min threads: 5, max threads: 5
* Environment: development
* Listening on tcp://localhost:3000
Use Ctrl-C to stop
```

一応サーバーは立ち上がったが、Ignoringが気になるので消したい。

```
$　gem install bundler
```
```
$　bundle install
```
で消えました。

##参考
https://tsubasa0105.hatenablog.com/entry/2018/11/29/180051
https://qiita.com/ROY_M/items/43fd1370e3d89ae50074
https://teratail.com/questions/139925
Apacheの再起動、MySQLポート番号、バージョン確認


#再起動
```
sudo systemctl restart httpd.service
```
```
sudo systemctl restart mariadb
```

# mysql port番号
```
$ mysql> show variables like 'port';
```


#バージョン確認
```
yum info httpd

mysql --version
mysqladmin version
```

```
mysql> select version();
mysql> status
```

*[Linux2にLUMPインストールチュートリアル](https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/ec2-lamp-amazon-linux-2.html)
rust-analyzerで`unresovled import`が出たときの対処法

## 結論

自分のケースでは、rust-analyzerがattribute macrosを正しく読み込めていないことからエラーが発生していたため、settings.jsonに以下を追記したら治りました。

```
"rust-analyzer.experimental.procAttrMacros": true
```

## 参考

https://rust-analyzer.github.io/manual.html

> rust-analyzer.experimental.procAttrMacros (default: false)
Expand attribute macros.
応用情報技術者を取得するためのメモ

応用情報技術者を取得するための自分のための投稿です。

随時参考にさせていただいたURLを更新するだけです。

・応用情報技術者試験公式HP
　https://www.jitec.ipa.go.jp/1_11seido/ap.html
　https://www.jitec.ipa.go.jp/1_13download/syllabus_ap_ver6_1.pdf

・応用情報技術者試験ドットコム
ここでは無料で過去問を受けることができます。
また、解説も詳しくとてもありがたいHPとなっております。
(TOEICとかもこうしてくれればいいのに。。。)
https://www.ap-siken.com/

・応用情報技術者試験にギリギリ合格したので、追い込まれた人向けの勉強法をまとめてみた
　@c60evaporator さんが2021年06月25日に更新したものです。
応用情報って何っていう部分やわかりやすい分析を掲載されています。
　https://qiita.com/c60evaporator/items/0bbda34eead71c9e38d9


なお、私こちらの記事が初投稿でありまして、
ガイドラインに反しているなどありましたら教えていただければ幸いです。
ネットワークがわかる４つのポイント

ネットワーク界隈でご飯を食べてそろそろ１０年の私が、ここさえおさえておけばネットワークって大体理解できるよねって感じたポイントを解説します。

:::note info
注意：
説明のために技術的な正確性は大分犠牲になっています。
ふーん、ほんとかよって思ったら出てくる単語をぐぐって頂くといいかと思います。
:::

#目次
１．ネットワークは色々なプロトコルが連携して動作することで形成される
２．ETHERNET
３．IP
４．ETHERNETとIPの組み合わせ

##１．ネットワークは色々なプロトコルが連携して動作することで形成される
よくOSI参照モデルがどうのという言葉で説明されていますが、今日のネットワークは色々なプロトコルが連携して動作することで形成されています。
プログラミング界隈の人に伝わりやすい単語でいうと、「疎結合」とか「マイクロサービス」みたいなイメージです。

例えば、WEBサービスを作るときにはWEBサーバ(apacheなど)とDBサーバ(Mysqlなど)は少なくとも分かれていると思いますが、これらを単一のコードで作りたいと思う人なんて誰もいませんよね？
ネットワークも同じで、機能ごとにプログラムを分けることで見通しを良くしており、色々なプログラムを組み合わせて通信という目的を実現しています。

機能毎に分けられたプログラムをプロトコル（決まり事）と呼んでいます。
ネットワーク回りのプロトコルには有名どころでTCP・IPなどほとんどシェアの100%を獲得しているようなものから、IPX,appletalkなどもう今は使われなくなったものまで様々です。

その中で超重要なプロトコルを二つだけ選び、解説します。
それが、ETHERNETとIPです。

##・ETHERNET
現代の機器は9割以上がETHERNETを使って通信しています。ほぼ100%といってもいいかもしれません。
このプロトコルの考え方は単純で、とりあえず全方向に通信をぶん投げるというものになります。
中継器に知らないアドレス宛の通信が来たら全方向[^1]にぶん投げます。次の中継器でも同様にします。
そうしていくと、いつかは目的の相手に届くよね、というのが基本的な考えになります。[^2]

この単純な方式は絶大なメリットがあって、相手先のアドレスを知らなくても通信が成立します。
いちいちPCに相手のアドレスはこれで。。。などと設定しなくても済むのです。

ただ、デメリットもあります。
全方向に通信を投げると、無駄な通信も発生します。
例えば、PC1からみたらPC2～PC10宛ての通信はいらない訳ですが、とりあえず全方向に通信をぶん投げるものですから、こういった通信も必然的に届くことになります。
10台規模ならいいですが、数万台規模になるともう無理です。
ETHERNETだけでやっていこうとすると、関係ない通信であなたのPCのLANケーブルは埋め尽くされるでしょう。

##・IP
規模が大きくなるとETHERNETだけでは無理が出ることがわかりました。
そこで出てくるのがIPです。

IPの考え方はETHERNETとは逆です。
知らないアドレス宛の通信が来たら、すべて捨ててしまいます。
全方向に投げるような通信も嫌うので、自分のところに来ても通しません。
知っているアドレス宛の通信だけ、適切な経路からのみ通ってよしとする頭の固い門番です。
また、古くなった通信も捨ててしまいます。断捨離うまそうですね。
このような性質からIPの世界には必要でフレッシュな通信のみが流通し、不要な通信はでないようになっています。

この性質は裏返せば、IPだけで通信するには目的のアドレスがどこから通っていくべきなのか、一つ一つ設定する必要が出てきます。
数台のPCで数通りの宛先ならやってもいいかもしれませんが、数万の宛先となると考えることすらしたくありません。

##・ETHERNETとIPを組み合わせる
ETHERNETがあるおかげで、ルータに通信を届けるのに相手のMACアドレスが何でどこのポートから。。。などと細かいことを気にする必要がなくなります。
IPがあるおかげでルータどうしは不要な通信で埋め尽くされることはなくなり、目的地まで適切なルートで通信を届けることができます。

実際はETHERNETとIPを連携させるARPというプロトコルや、知っているIPアドレスの情報を交換するRIP,OSPF、EIGRP,BGPなどといったプロトコルがあったり、まだまだ色々なプロトコルがあるおかげで通信が成り立つのですが、今回はこの辺にしておきます。

#結論
考えた昔の人って頭いい！


[^1]: 厳密には着信ポート以外のすべてのポートです。これをフラッディングといいます。本当に全方向に投げたら大変なことになります。
[^2]: 知っている方にはわかりますが、ブロードキャストの説明のみになります。本当はユニキャストだったり効率よく通信するための仕組みがありますが、本質ではないので割愛します。
letとlet!とbeforeの使い分け

こんにちは、プレイライフの熊崎です。
最近野菜をとれていなかったので、この土日はいっぱい野菜を食べたいと思います。

本日3本目はletとbeforeの使い分けについてアウトプットしていきます。

## let
メモ化されたヘルパーメソッドを定義する。同じexampleの中ではキャッシュされるが、異なるexample間ではキャッシュされない。
**遅延評価される。letが定義するメソッドが最初に呼び出されるまで評価されない。**

```sample_spec.rb
let(:user) { User.create(name: "田中太郎") }

# letは遅延評価されるため、userが呼び出されるまで、Userにはレコードが作られていない状態になる。そのためテストが通らない。
it 'ユーザーが取得できること' do
  expect(User.find_by(name: "田中太郎")).to eq user
end
```

## let!
**各exampleの実行前に**、定義されたメソッドを呼び出すことができる。

```sample_spec.rb
let!(:user) { User.create(name: "田中太郎") }

# let!にすることで、以下のテストケースの前に、userメソッドが呼ばれるため、Userにレコードが存在する状態になる。そのため、テストには通る。
it 'ユーザーが取得できること' do
  expect(User.find_by(name: "田中太郎")).to eq user
end
```


## before
テストケースの前に、行いたい処理をブロック内に書くことで、テストケースが実行される前にブロック内の処理が行われるようにする。

```sample_spec.rb
before do
  User.create(name: "田中太郎")
end

# この場合はuserがテストコードにないので、let(:user)を使用する必要がない。
it 'ユーザーが取得できること' do
  expect(User.count).to eq 1
end
```


## それぞれの使い分け
先ほどまでの実例から、以下のように使い分けるのが適切だと感じた。

let：テストコード内に、定義したヘルパーメソッドが存在する場合

let!：テストコード内に、定義したヘルパーメソッドが存在し、かつテストの実行前にヘルパーメソッドを実行したい場合

before:テストコード内でヘルパーメソッドを定義する必要がない場合

## 最後に
それぞれの挙動を理解していないと、テストコードに存在しないヘルパーメソッドをletで用意している。といった状況になり、レビュワーや数ヶ月後の自分が混乱するので使い分けを徹底していく必要があると感じた。


## 参考記事

https://relishapp.com/rspec/rspec-core/v/3-10/docs/hooks/before-and-after-hooks

https://relishapp.com/rspec/rspec-core/v/3-10/docs/helper-methods/let-and-let
wicked_pdf 本番環境で動かない問題

## 起きたこと
wicked_pdfをEC2にデプロイしたところ表示されず‥
ログを見ると以下エラー

```
ActionView::Template::Error (The asset "number_pages.js" is not present in the asset pipeline.
```

## 対処法

以下の部分を削除

```
<!doctype html>
<html>
  <head>
    <meta charset='utf-8' />
    <%= wicked_pdf_stylesheet_link_tag "pdf" -%>
   #--------------削除-------------------------------------
    <%= wicked_pdf_javascript_include_tag "number_pages" %>
  #----------------------------------------------------------
  </head>
  <body onload='number_pages'>
    <div id="header">
  #--------------削除--------------------------------
      <%= wicked_pdf_image_tag 'mysite.jpg' %>
  #-------------------------------------------------
    </div>
    <div id="content">
      <%= yield %>
    </div>
  </body>
</html>
```

## 原因
公式のこの部分

```
<!doctype html>
<html>
  <head>
    <meta charset='utf-8' />
    <%= wicked_pdf_stylesheet_link_tag "pdf" -%>
    <%= wicked_pdf_javascript_include_tag "number_pages" %>
  </head>
  <body onload='number_pages'>
    <div id="header">
      <%= wicked_pdf_image_tag 'mysite.jpg' %>
    </div>
    <div id="content">
      <%= yield %>
    </div>
  </body>
</html>
```
をそのまま持ってきてたので`wicked_pdf_javascript_include_tag "number_pages"`の部分は今回は使ってなかったからエラーが起きたのだと思われ

現に`wicked_pdf_javascript_include_tag "number_pages"`の部分を削除したら今度は
以下のエラーが出たのでここも今回は不要ってことでこれも削除

```
ActionView::Template::Error (The asset "mysite.jpg" is not present in the asset pipeline.
```

## その後
その後無事PDF出力はしたが今度は英語と数字部分は出力されるが日本語部分が出力されず‥

## 対処法
Linuxには日本語が入っていないらしいので
以下をcurrent内でインストール

```
$ yum install -y ipa-gothic-fonts
$ yum install -y ipa-mincho-fonts
```

これで無事表示された！


## 参考

https://github.com/mileszs/wicked_pdf

https://qiita.com/yutackall/items/a41d2f70cbeca2fe8a0a
好きな画像を実際に物体検知させてみよう！



[PyTorch Hub](https://pytorch.org/hub/)において、学習済みの最先端モデルが簡単にダウンロードできます。
これを初学者でも簡単に使えるようにコードを書きました。[GitHub](https://github.com/u-shiori/DLtemplate2021)にも公開しています。
コード内の画像URL部分を好きに変えて実行してください！
（URLを貼り付けること。URLの最後が`.png`等の拡張子で終わっていること。）

## 開発環境
- Python : `3.9.0`
- PyTorch : `1.7.1`




## 画像分類
画像に写っているものは何なのかを分類してくれる技術です。
ResNeXtのモデルを使用します。

```python
import os
from PIL import Image
import urllib.request

import matplotlib.pyplot as plt
import torch
from torchvision import transforms

from utils.imagenet_labels import idx2label 

# モデル読み込み
model = torch.hub.load('facebookresearch/WSL-Images', 'resnext101_32x8d_wsl')
model.eval()

# 画像
url = "https://github.com/pytorch/hub/raw/master/images/dog.jpg" # <- 自由に変更してね
save_dir = "../result/resnext"
os.makedirs(save_dir, exist_ok=True)
filename = f"{save_dir}/{os.path.basename(url)}"
try: urllib.URLopener().retrieve(url, filename)
except: urllib.request.urlretrieve(url, filename)
input_image = Image.open(filename)

#前処理
preprocess = transforms.Compose([
    transforms.Resize(256),
    transforms.CenterCrop(224),
    transforms.ToTensor(),
    transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),
])
input_tensor = preprocess(input_image)
input_batch = input_tensor.unsqueeze(0) 

#推論
if torch.cuda.is_available():
    input_batch = input_batch.to('cuda')
    model.to('cuda')
with torch.no_grad():
    output = model(input_batch)

#可視化
idx = torch.nn.functional.softmax(output[0], dim=0).argmax().item()
print(idx2label[idx])
plt.imshow(input_image)
plt.title(idx2label[idx])
plt.savefig(filename)
```


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269839/c7d7a4bf-5cbe-4d1a-3643-537c6671dfee.png)


## 物体検知
画像内にうつる物体の場所と分類をしてくれる技術です。
YOLOv5sを使います。

```python
import os
from copy import deepcopy

import torch

# モデル読み込み
model = torch.hub.load('ultralytics/yolov5', 'yolov5s', pretrained=True)

# 画像
imgs = ['https://ultralytics.com/images/zidane.jpg']  # <- 自由に変更してね！
img_paths = deepcopy(imgs)

# 推論
results = model(imgs)

# 可視化
save_dir = "../result/yolov5"
os.makedirs(save_dir, exist_ok=True)
results.save(save_dir) 
xys = results.pandas().xyxy
for xy, img in zip(xys, img_paths):
    basename = os.path.splitext(os.path.basename(img))[0]
    xy.to_csv(f"{save_dir}/{basename}.csv")
    print(xy)
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269839/ca1bd0dd-6f27-ee37-597c-823d7cd16813.png)
Railsチュートリアルの振り返り

「Railsチュートリアル」を14章まで終わらせたので、自分の解釈を進めるために記事を書いていきます。

まずはじめに、GemFile

```ruby:Gemfile
source 'https://rubygems.org'
git_source(:github) { |repo| "https://github.com/#{repo}.git" }

ruby '2.6.8'

gem 'rails', '~> 6.1.4', '>= 6.1.4.1'

gem 'pg'

gem 'puma', '~> 5.0'

gem 'sass-rails', '>= 6'

gem 'webpacker', '~> 5.0'
gem 'turbolinks', '~> 5'
gem 'jbuilder', '~> 2.7'

gem 'bcrypt'
gem 'minitest', group: :test
gem 'minitest-reporters', group: :test
gem 'rails-controller-testing'
gem 'faker'
gem 'will_paginate'
gem 'bootstrap-will_paginate'
gem 'active_storage_validations'
gem 'image_processing'
gem 'mini_magick'
gem 'rmagick'
gem 'aws-sdk-s3', '~> 1.87', require: false
gem 'rails_12factor', group: :production

gem 'bootsnap', '>= 1.4.4', require: false
gem 'bootstrap-sass'

group :development, :test do
  # Call 'byebug' anywhere in the code to stop execution and get a debugger console
  gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
end

group :development do
  gem 'web-console', '>= 4.1.0'
  gem 'rack-mini-profiler', '~> 2.0'
  gem 'listen', '~> 3.3'
  gem 'spring'
end

group :test do
  gem 'capybara', '>= 3.26'
  gem 'selenium-webdriver'
  gem 'webdrivers'
```
Rails6ではWebPacker,Yarnがある前提との事なので、最初にインストールしました。その後進行するにつれ、bcrypt~rails_12factorまで要求されたので、順次インストールしました。
minimagick,rmagickはどちらか一方でいいかもしれません。
（詳しい人よかったら教えて下さい）
上記のGemfileですが、#でコメントアウトになるはずの部分は見出しレベルの文字の大きさに巨大化されるので、削除しています。
この投稿以降は順次、
・メソッドの動作
・MVCモデルに沿った作成手順
などを、自分の解釈も混ぜて書いていけたらと思います。

改善点などあったら指摘していただけると助かります。
PytorchによるDeepLearningの動作環境（PyTorch＋Torchvison＋OpenCV）をRaspberryPi4に構築する方法

# PytorchによるDeepLearningの動作環境（PyTorch＋Torchvison＋OpenCV）をRaspberryPi4に構築する方法

書籍「[つくりながら学ぶ! PyTorchによる発展ディープラーニング](https://www.amazon.co.jp/%E3%81%A4%E3%81%8F%E3%82%8A%E3%81%AA%E3%81%8C%E3%82%89%E5%AD%A6%E3%81%B6-PyTorch%E3%81%AB%E3%82%88%E3%82%8B%E7%99%BA%E5%B1%95%E3%83%87%E3%82%A3%E3%83%BC%E3%83%97%E3%83%A9%E3%83%BC%E3%83%8B%E3%83%B3%E3%82%B0-%E5%B0%8F%E5%B7%9D%E9%9B%84%E5%A4%AA%E9%83%8E/dp/4839970254)」を参考にして作成したDeepLearningのプログラムをRaspberryPi4上で動作させるために、<b>PyTorch</b>、<b>Torchvision</b>、<b>OpenCV</b>の3つをインストールする必要がありました。

この記事には、これら3つのモジュールのインストール手順のメモを掲載します。
ただし、Raspbian上で実行したものであり、Raspberry Pi OS上で実行した場合に動作するかを確かめていない点、ご容赦ください。

## 環境

2020/4/3時点で最新のRaspbianを使いました。
（このメモを作成時はRaspberry Pi OSが公開されていませんでした・・・）

OS：Raspbian Buster(Release date:2020-02-13)
Python：3.7.3


## インストール
### 1. Pytorchをインストール

GitHubに掲載されている手順にを参考に、インストールします。
ただし、後述する①②に注意してください。

[__PyTorchのインストール手順__](https://gist.github.com/akaanirban/621e63237e63bb169126b537d7a1d979#file-gistfile_pytorch_rpi4-md)

<b>①最新のバージョンを使用できない</b>

最新のバージョンはインストールできませんでした。（ビルドエラーになりました）
Optionally・・・の箇所に記載されている

```
git checkout v1.0.1
```
を実施すると、無事にインストールできました。
git checkout XXXのXXX部分は、[GitHub](https://github.com/pytorch/pytorch)のBranch名称に対応しています。

<b>②PyTorchとTorchvisionのバージョンの組み合わせ</b>
PyTorchとTorchvisionのバージョンの組み合わせは、以下のリンク先のページから選択する必要があります。
[PyTorchとTorchVisionの組み合わせ](https://pytorch.org/get-started/previous-versions/)
今回は、Pytorch：v1.0.1、Torchvision：v0.2.2の組み合わせでインストールすることにしました。



### 2. Torchvisionをインストール

Torchvisionをインストールします。
__root__ で以下を実行してください。

```
git clone https://github.com/pytorch/vision.git
cd vision
git checkout v0.2.2_branch
python3 setup.py setup build
python3 setup.py setup install
```

- 参考ページ：https://gist.github.com/akaanirban/621e63237e63bb169126b537d7a1d979


### 3. OpenCVをインストール

次のコマンドを実行すると、OpenCVがインストールされます。

```
sudo pip3 install opencv-python
```

## 動作確認

ターミナルからpythonを起動し、次のコードを実行してください。
PyTorch、Torchvision、OpenCVのバージョンがそれぞれ表示されればOKです。

``` python
import torch
import torchvision
import cv2
torch.__version__  # Pytorchのバージョンを表示
torchvision.__version__ # Torchvisionのバージョンを表示
cv2.__version__ # OpenCVのバージョンを表示
```
SQL コマンドリスト

## 環境（利用するソフトウェア）
- MySQL (RDBMS：リレーショナルデータベース管理システム)
- Apache (Webサーバー)
- php (プログラム言語)

## SQLとは
- データを作るときの「create table ･･･」やデータを挿入するときの「insert intto ･･･」などデータベースに対して処理する内容を指定するコマンドをクエリという。このクエリを書くときの規則が、SQLという言語です。

# 作成編

## SQLコマンド
- データベースの作成
  - 'create database データベース名;'
    > コマンドの最後には、「;」(デミリタ)をつける

- テーブルの作成
  - 'create database テーブル名 (カラム名 データ型, カラム名　データ型, カラム名 データ型 ･･･);'
  - 例）'create database users (id INT AUTO_INCREMENT PRIMATY KEY, name VARCHAR(25), email VARCHAR(50), password VARCHAR(50));'
    > idカラムに、データ型(INT), AUTO_INCREMENT(連続番号1,2,3,4,5,･･･を宣言), PRIMATY KEY(主キーを設定)
    > nameカラムに、データ型(VARCHAR(25))を指定。VARCHARは、文字データの保管。(25)は、文字数制限をしていて２５文字までの文字が入るようになる。passwordカラムも同様。

- テーブルのデータの作成
  - 'insert into テーブル名 values(データ, データ, データ ･･･);'
  - 例）'insert into users(name, email, password) values('yyy', 'yyy@example.com', 'whywhywhy');'
    > usersテーブルのnameに'yyy', emailに'yyy@example.com', password に'whywhywhy'というデータを作成している。
  - 複数データの作成
    - 'insert into users(name,email,password) values('yyy','yyy@example.com','whywhywhy'),('zzz','zzz@example.com','zzzzzzzzzz'),('xxx','xxx@example.com','xxxxxxxxxxx');'
      > usersテーブルに３つのレコード作成している。作成したいデータを「,」で繋げる。･･･,(),(),･･･

- インデックスの作成
  > インデックスとは、テーブルの索引のこと。膨大なデータから必要なレコードの情報を調べるときに使う。
  - 'create index インデックス名 ON テーブル名(カラム名)'
  - 例）'create index my_ind on users(name)'
    > usersテーブルのnameカラムに、'my_ind'というインデックスを設定している。

# その他
- 作成したデータベースの確認
  - 'show databases;'
- 使うデータベースを指定する
  - 'use データベース名;'
- 現在しようしているデータベースの表示
  - 'select database();'
- 内部結合（複数のテーブルを結合して表示する）
  - テーブル構成
    > usersテーブル(id, name, email, password)
    > articlesテーブル(id, title, body, created_at, updated_at, user_id)
  - 今回は、articlesテーブルの title と created_at, usersテーブルの name を結合して表示する。
  - 'select カラム名 from テーブル１ join 結合するテーブル２ on テーブル１のカラム=テーブル２のカラム;'
  - 'select articles.title, articles.created_at, users.name
       from articles
       join users
       on articles.user_id=user.id;'
【Flutter】社内向け入門講座の内容公開

インドネシアの[PT.AQ Business Consulting Indonesia](https://aqi.co.id/)でFlutterのエンジニア兼アドバイザーをしております菊池と申します。

Zennで本を出版しております[flutter chips](https://zenn.dev/tetsukick/books/06ee607e30e243)(30,000字程度)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261934/5183aafc-d1d7-534f-f618-031f10790fdc.png)

## 本記事で伝えること
- Flutterを用いた簡単なアプリ開発デモ
- 開発効率をあげるTips
- デバッグ方法
- おすすめパッケージ
- アーキテクチャ紹介
- やっておいたほうが良いこと
- 知っておいて損しないこと
- 情報収集源

## 本記事を読む前に
本記事を読む前提として以下を実施済みですと、より内容が理解しやすいかと思います。
- Flutterの環境構築
以下の弊記事を参考にして環境構築を進めていただければと思います。
[【Flutter】アプリ開発入門 Flutter環境構築 Hello Flutter!!](https://qiita.com/tetsukick/items/cdecf64172c5f4a126d6)

## 簡単なデモ
webviewアプリ作成
<img width="350" alt="デモGIF" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261934/9b766b7d-00e9-6ccb-b232-d8e6705a0230.gif">

ソースコード

https://github.com/Tetsukick/flutter_webview_app

## 開発効率あげる方法
### AndroidStudio プラグイン
詳細な内容は弊記事[【Flutter】モバイルアプリ高速開発プラットフォームをさらに爆速化するTips](https://qiita.com/tetsukick/items/8cbb3cc53bac60f713d5)を参照ください。
### おすすめプラグイン
- FlutterSnippets
- Flutter Enhancement Suite
- Flutter Pub Version Checker
- flutter-img-sync
- FlutterJsonBeanFactory

### 静的解析
詳細な内容はこちらの記事[Dart/Flutter の静的解析強化のススメ](https://medium.com/flutter-jp/analysis-b8dbb19d3978)を参照してください。
#### 実装方法
1. インストール
[pedantic_mono](https://pub.dev/packages/pedantic_mono)パッケージをインストール。

```dart:pubspec.yaml
dev_dependencies:
  pedantic_mono: any
```

2. analysis_options.yamlの配置

https://github.com/mono0926/pedantic_mono/blob/master/example/analysis_options.yaml をプロジェクトのルートに置く。以上。

## デバッグ方法
### break point
break pointを用いて、ソースコード実行中の途中で停止させることで、各変数に格納されている値を確認できます。デバッグ時に必須の手法になります。以下の記事などで詳しく紹介されています。

https://minpro.net/check-variables-at-a-breakpoint

### debug tool
詳細は弊記事[【Flutter】インターフェース開発に強いFlutterで、さらにUI開発を加速させるテクニック](https://qiita.com/tetsukick/items/f3c0744a0b6e40a53cc1)を参照してください。

## おすすめパッケージ
### flutter_svg
SVG画像をFlutter内で扱う際に必須のパッケージ。
アイコンなどはPNG等のピクセル画像で入れると画像がボケたりしてしまうので、極力ベクター画像を使うようにしましょう。

https://pub.dev/packages/flutter_svg

https://qiita.com/ikemura23/items/5671bba76136d940b618

### auto_size_text
テキストのサイズを動的に変更。端末の横幅によって収まらない場合や長いテキストの入力値に対しても、ほとんど意識せずに適応してくれる。

https://pub.dev/packages/auto_size_text

## やっておいたほうが良いこと
### FVMでのFlutterのバージョン管理
Flutterはアップデートが頻繁に行われ、複数人でプロジェクトを進行する上では、Flutterのバージョンを合わせて開発する必要があります。

その上で、Flutterのバージョンをローカル上に複数共存させて、簡単に切り替えを行えるようにできるツールがFVMです。

↓↓↓使用方法は弊記事を参考にしてください↓↓↓

https://qiita.com/tetsukick/items/b4b11bdacbddd0467d44

## 情報収集源
### 公式関連

https://medium.com/flutter

https://twitter.com/FlutterDev

https://medium.com/flutter-community

### monoさん Medium

https://mono0926.medium.com/

## 知っておいても良いこと
### DartPad
DartやFlutterのコードをブラウザ上で実行できるサイト。
ちょっとしたコードの確認などを行う際に便利です。

https://dartpad.dev/?null_safety=true

### クローンアプリ系
TwitterやWhatsApp,Slackなどのクローンアプリを作成して公開してくれている方がいます。
参考にできる点も多いかと。

https://qiita.com/masa_mf3/items/f077a37815bb2a7c139d
herokuのmysqlにログインするメモ

#はじめに
herokuにデプロイしたアプリのメンテナンスでmysqlにログインしようと思ったが
heroku環境久しぶりだったので、

次回以降この記事をもとに作業するための個人的なメモです。

#herokuのアプリ環境を確認する

```
$heroku config -a アプリケーション名
```
これでアプリのDB情報(ホスト名・DBユーザー名・パスワードが取得できる。)や環境変数などが確認できる。

```
CLEARDB_DATABASE_URL: ほげほげ
DB_HOSTNAME:          ほげほげ
DB_NAME:              ほげほげ
DB_PASSWORD:          ほげほげ
DB_USERNAME:          ほげほげ
```

これがわかればいつもどおりmyslqにログインできる

```
$mysql -h [DB_HOSTNAME] -u [DB_USERNAME] -p 
```

```
#データベースの一覧確認
$show databases;

#使用するデータベース選択
$use データベース名

#テーブルの構造確認
$desc テーブル名;

#create ddl取得
$show create table テーブル名;

```
LaravelでVue.jsのチラつきをv-cloakを使わずに防止する方法


## 背景
#### Vue.jsのチラつきとは

Vue.jsの「マスタッシュ表記（{{ data }}のような表記）」や「v-if」などで表示を制御している場合、ページ読み込み直後に**一瞬だけVueデータが反映される前のコードが表示されてしまう**ことがある。これを経験した人は少なくないと思う。

#### v-cloakでの対策と問題点

このチラつきの解決策をネットで検索すると、「v-cloakを使いましょう」という記事が出てきて、下記のようなサンプルコードを提案される。

```html:index.html
<!DOCTYPE html>
<html lang="ja">
<head>
  <style type="text/css">
  [v-cloak] {
    display: none;
  }
  </style>
</head>

<body>
  <div id="app" v-cloak>
    <p>{{ message }}</p>
  </div>

  <script type="text/javascript">
    new Vue({
      el: '#app',
      data: {
        message: "メッセージ",
      },
    });
  </script>

</body>
</html>
```

ただの html や php 環境ならこの方法で解決できる。**しかし、Laravel の blade で Vue.js を使用している場合、この方法では解決しないことがある。**
（条件や原因を特定できていないので、もし知っている人はコメントいただけるとありがたいです。）

## v-cloakを使わない解決方法
#### サンプルコード

v-cloakと同様の処理を下記サンプルコードのように自作してしまえば解決できる。

```php:index.blade.php
<!DOCTYPE html>
<html lang="ja">
<head>
</head>

<body>
  <div id="app" style="display:none"><!-- (1)html読み込み時はcssで非表示 -->
    <p>@{{ message }}</p>
  </div>

  <script type="text/javascript">
    new Vue({
      el: '#app',
      data: {
        message: "メッセージ",
      },
      mounted: function () {
        const targetElement = this.$el;
        this.$el.style.display='block'; // (2)vueマウント完了後に表示させる
      },
    });
  </script>
</body>
</html>
```
#### 解説
1. まず、Vueの制御対象のコンテンツ全体を「style="display:none"」で非表示にしておく。こうすることで、Vueと連動する部分はページ読み込み直後であっても表示されない。
1. Vueインスタンスが生成され、エレメントのマウントが完了後（＝Vueインスタンスのデータがhtmlコード側に反映された後）に、非表示を解除する。

同様の問題で困っている人の参考になれば幸いです。
[Kotlin/Java] KotlinのデータクラスをJava で利用するには

## 記事でわかること
KotlinとJavaが併存するプロジェクトでJavaのクラス内でKotlinのデータクラスを利用する方法を記載します。

## 背景
現在関わっているサーバーサイドのプロジェクトではJavaからKotlinへの移行を行っています。
新規クラスはKotlinで記述することで少しずつKotlinへの移行を進めています。

その際にKotlinのデータクラスをJavaから呼び出す際にどうすればいいのだろうと少し迷ったので、備忘のために記載します。

## JavaでKotlinのデータクラスを利用するには
結論から言うと Kotlinのクラスを利用側のJavaクラスでimportして、普通に`new`することで利用できます。
 
```kotlin
data class User(
val id: Int,
val name: String,
val mailAddress: String
)
```

例えば、上記のKotlinのデータクラスをJavaで利用する場合には下記のように記述します。

```java
import User;
public User createUser(Integer id, String name, String mailAddress) {
 User user = new User(id, name, mailAddress);
 return user;
}
```

## Kotlinのデータクラスをデコンパイルしてみる
KotlinのデータクラスをJavaにデコンパイルしてみると、コンストラクタは下記のようになっています。

```java
public User(int id, @NotNull String name, @NotNull String mailAddress) {
      Intrinsics.checkNotNullParameter(name, "name");
      Intrinsics.checkNotNullParameter(mailAddress, "mailAddress");
      super();
      this.id = id;
      this.name = name;
      this.mailAddress = mailAddress;
   }
```
### [ポイント]
* Intはprimitiveのintに、StringはそのままStringに変換されている
* JavaでもKotlinで記述したっとり必要な引数を取得するコンストラクタが生成されている
* `val`指定すると、パラメーターには`NotNull`の制約が付与される
 
## まとめ

* KotlinのデータクラスをJavaで利用する場合は普通に`new`すればOK
* コンストラクタにvalを指定した場合はKotlinの言語仕様通り、null 制約が付与されるので渡すパラメーターには注意が必要
* Kotlinのプリミティブな型(Int,String,Booleanなど)を利用している場合はJava側でどのクラス/プリミティブな型に変換されるのか確認したほうが良い

それでは素敵なKotlinライフを！
【Go】シングルクォーテーションとダブルクォーテーションの型

シングルクォーテーションはrune型、ダブルクォーテーションはstring型で違う型になる

```go
package main

import "fmt"

func main() {
	fmt.Print('A' == "A") // invalid operation: 'A' == "A" (mismatched types untyped rune and untyped string)
}
```

シングルクォーテーションはint32型でUnicodeの値をとる

```go
package main

import "fmt"

func main() {
	s := 'A'
	d := "A"
	fmt.Printf("%v %T %v %T", s, s, d, d) // 65 int32 A string
}
```
AWS SSMでFTPソフトを使用して、ローカルマシンからPrivate EC2へファイル転送

## これは何

AWS SSMでCyberduck(FTPクライアントソフト)を使用して、Private EC2へファイル転送してみました。
FTPソフトはWinSCPとか他のでもいけると思います。（動作検証はしてませんが）

## 早速やってみた

**IAMロールを作成**
AmazonSSMManagedInstanceCore ポリシーを含むロールを作成

![スクリーンショット 2021-09-10 16.26.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1740345/028bf891-92f7-dc59-7be4-65904bdd9ef0.png)


**EC2へアタッチする**

先ほど作成したロールをEC2にアタッチします。

**AWS CLI v2のインストール、configureコマンドで情報入力**
今回は、direnvを使用し、環境変数を定義しました。
こんな感じで

```
export AWS_ACCESS_KEY_ID=""
export AWS_SECRET_ACCESS_KEY=""
export AWS_DEFAULT_REGION=""
```

**Session Manager pluginのインストール**
以下より、マシンに合わせて選択し、インストール。
https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/session-manager-working-with-install-plugin.html

**鍵ファイルのパーミッションを変更**

```
$ chmod 600 CMS秘密鍵
```

**AWS CLIで利用するIAMユーザーを作成**

**IAMポリシーの作成**

以下のポリシーでSSHが可能。

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Action": [
                "ssm:StartSession",
                "ssm:TerminateSession",
                "ssm:ResumeSession",
                "ssm:DescribeSessions",
                "ssm:GetConnectionStatus"
            ],
            "Effect": "Allow",
            "Resource": [
                "*"
            ]
        }
    ]
}
```

**IAMユーザーの作成**
上記のポリシーを付与したIAMユーザーを作成。

プログラムによるアクセスを許可。
生成されたアクセスキーとシークレットアクセスキーを先ほどの環境変数に定義する。

**ポートフォワーディングをする**


```
$ aws ssm start-session --target 【インスタンスID】 --document-name AWS-StartPortForwardingSession --parameters "portNumber=22,localPortNumber=10220(任意)"
```

すると、以下の文字を吐きます。

```
Starting session with SessionId:xxxxx
Port 10220 opened for sessionId xxxxx
Waiting for connections...
```

**Cyberduckでファイル転送**

```
サーバー名 : localhost
ポート名 : 10220
ユーザー名 : OSユーザー名
SSH Private Key : 秘密鍵のFull Path
```

ターミナルがこんな文字列を吐くようになったら、接続成功です。

```
Connection accepted for session xxxxx
```

## 参考

```
https://hikari-blog.com/ec2-session-manager/
https://blog.denet.co.jp/ssm-winscp-upl/
https://qiita.com/hayao_k/items/78b5bfe030ad8a053e93
```

参考にさせていただきました。ありがとうございます。
Amazon s3 にIPアドレス制限をかけるときの注意点


##目的

災害対策として、オンプレサーバのバックアップを、クラウドにも保存する。いわゆるディザスタリカバリ。

###クラウドサービスの選定

Amazon s3を選定。理由は、オンプレサーバのバックアップ先(NAS)にs3と連携できる機能が標準で付いていたため。

###ざっくりな流れ
AWS側でs3バケット作成
↓
オンプレ側でs3への接続設定

##s3バケット作成

妙な言い回しでひっかかる設定項目があったが、既に先人の知恵がございましたので、ここでの説明は割愛。

そして先人に盛大なる感謝。

[S3のブロックパブリックアクセスが怖くなくなった](https://zenn.dev/ymasutani/articles/019959e7c990b1)

セキュリティを確保するため、オンプレサーバのグローバルIPからs3へのアクセスのみ許可するようなポリシーを設定します。(JSON形式で)

```
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Deny",
            "Principal": "*",
            "Action": "s3:*",
            "Resource": "arn:aws:s3:::bucket-name",
            "Condition": {
                "NotIpAddress": {
                    "aws:SourceIp": [
                        "xxx.xxx.xxx.xxx/32"
                    ]
                }
            }
        }
    ]
}
```


**注意すべきはこのときです！**

グローバルIPを間違えて入力してしまったもんなら、もうそのバケットに対して**何も操作出来なく**なります。
もしバケット操作不可になった場合は、ルートユーザでAWSマネジメントコンソールにログインすれば、ポリシー変更なり削除なりの操作が可能です。

なんらかの代行サービスを経由してAWSアカウントを取得している場合は、ルートユーザでの操作ができない場合がありますので、ご注意ください。


私の場合はまさにルートユーザでの操作ができないタイプのサービスでしたので、バケットがずーっと残ったままになっていますorz

##オンプレ(NAS)からS3への接続設定
NASの機種によると思いますが、必要なのはたいてい
　1.アクセスキーID
　2.シークレットアクセスキー
　3.バケット名
くらいかと思われます。
1と2は、IAMユーザのキーになります。**間違ってもルートユーザのキーは作成しないように！**


##おわりに
VPCやらサブネットやらセキュリティグループやらの設定に比べたら、S3の設定は全然難しくありませんでした。
でも、一歩間違えるとバケット操作できなくなる可能性がありますので、ご注意ください。
使えそうなGコードとMコード

基本のGコード
https://nc-program.s-projects.net/jis/g-code.html
基本のMコード
https://nc-program.s-projects.net/jis/m-code.html
数値の扱い方
https://nc-program.s-projects.net/numerical.html

```
G00 位置決め
G01 直線補間
G04 ドウェル
G28 リファレンス点復帰
G90 アブソリュートディメンション
G91 インクレメンタルディメンション

M02 エンドオブプログラム
M03 主軸時計方向回転
M04 主軸反時計方向回転
M05 主軸停止
M06 工具交換
M30 エンドオブデータ
アクチュエーターの駆動と停止は新たにMを割り当てる

X 座標値 小数点つきでmm単位、小数点なしでum単位
Y 座標値 小数点つきでmm単位、小数点なしでum単位
Z 座標値 小数点つきでmm単位、小数点なしでum単位
T 工具番号
F 直線補間速度 mm/min
S 主軸回転速度 rpm
P ドウェル時間 小数点つきで秒単位、小数点なしでミリ秒単位
() 注釈
```
VMware ESXi上の仮想マシンでディスク拡張できない

1. 事象
-
パワーオン状態の仮想マシンにて、HDDの容量を拡張する。
vCenterにアクセスし、対象仮想マシンを右クリック>設定の編集を選択。
HDD容量の部分を確認すると、グレーアウトしていた。
そのため、拡張ができない。

※ディスク拡張はパワーオン状態でも可能であることを他マシンで確認済み。


2. 原因
-
対象仮想マシンがsnapshotを保持していた。

3. 対応
-
対象仮想マシンにログインしシャットダウン。
※シャットダウンする必要があったのかは不明。。。

対象仮想マシンを右クリック>スナップショットの管理>スナップショットマネージャを開く。
対象スナップショットを削除した。

4. 結果
-
ディスク拡張が可能になった。

5. まとめ
-
あまり触らなくなった機器の技術(今回でいうとVMware)は、絶対に忘れてしまいます。
なのでいつでも見直すことができるメモが大切だということです。
delegateについて

こんにちは、プレイライフの熊崎です！

昨日の夜食べたラーメンのせいで、若干胃もたれ気味です。
学生の頃はラーメン+ライスでも全然平気だったのに、、、
時の流れを感じますね笑

そんな僕の話は置いておいて、delegateについての記事を書いていきたいと思います。

## deledateとは
> delegateマクロを使って、メソッドを簡単に委譲できます。
https://railsguides.jp/active_support_core_extensions.html?version=6.0#delegate

→ あるクラスに存在するメソッドを他のクラスで使用できるようにする

## どんな時に使用するか？
関連付けられているモデルのメソッドを直接使用したいとき。

## 基本の使い方

```sample.rb

class SampleUser < ApplicationRecord
  has_one :sample_plan

　　　　# delegateには複数のメソッドを指定できる。
  delegate :free_plan?, to: :sample_plan
end

# SamplePlanモデルはname属性を持っていると仮定
# 有料プランはnameが”有料プラン”
# 無料プランはnameが”無料プラン”

class SamplePlan < ApplicationRecord
  belongs_to :sample_user

  def free_plan?
    name == "無料プラン"
  end
end

# ユーザーが無料プランかどうかを確認したい時

# delegateを使わないとこんな感じ。冗長だしパッと見で意味がわかりづらい。
sample_user.sample_plan.free_plan?

# delegateを使用することで、SamplePlanモデルのメソッドを直接実行できる。簡潔だし、意味も明快
sample_user.free_plan?
```

## オプション

### :allow_nil
上記の例で、あるsample_userに、sample_planが紐づいていない場合`sample_user.free_plan?`を呼び出すと`NoMethodError`を返す。
`allow_nil: true`にすることで、nilを返すようにできる。


### :prefix
メソッド名を変更したいときに使用する。

```sample.rb

class SampleUser < ApplicationRecord
  has_one :sample_plan
  delegate :free?, to: :sample_plan, prefix: :plan
end

# SamplePlanモデルはname属性を持っていると仮定
# 有料プランはnameが”有料プラン”
# 無料プランはnameが”無料プラン”

class SamplePlan < ApplicationRecord
  belongs_to :sample_user

  def free?
    name == "無料プラン"
  end
end

# ユーザーが無料プランかどうかを確認したい時

sample_user.sample_plan.free?

# prefix: :planとしたことで、free?メソッドの名前がplan_free?に変更された。
sample_user.plan_free?
```

## まとめ
- delegateを使用することで、関連するモデルのメソッドを直接参照できる。
- delegateを使用することで、より可読性の高いコードを書くことができる。

## 参考URL
- [https://railsguides.jp/active_support_core_extensions.html?version=6.0#delegate](https://railsguides.jp/active_support_core_extensions.html?version=6.0#delegate)
- [https://api.rubyonrails.org/classes/Module.html#method-i-delegate](https://api.rubyonrails.org/classes/Module.html#method-i-delegate)
[Docker]Ubuntu20.04でのmecab及びmecab-ipadic-neologdの利用

- shellで、あるリストを単語ごとに分割しようとした矢先、[mecab](https://taku910.github.io/mecab/)というライブラリを発見。
- そのライブラリ及び専用の辞書ツールを試しにGoogle Colabで利用して便利であったため、Linux環境にも導入したい。
- そこで今回はDockerのUbuntu20.04内に導入する方法を記録する。

## 環境
- Mac OS 11.2.3
- Docker version 20.10.8

## 手順
- 任意のディレクトリに以下でDockerfileを作成する。

```bash
# workディレクトリ内にmecab-conディレクトリを作成
mkdir ~/work/mecab-con; cd $_

# mecab-con内にDockerfileを作成
touch Dockerfile
```

- 作成後、`mecab-con/Dockerfile`の中身を以下にする。

```dockerfile:~/work/mecab-con/Dockerfile
FROM ubuntu:20.04

# 日本設定
ENV TZ Asia/Tokyo
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
ENV LANG ja_JP.UTF-8

# パッケージインストール
RUN apt update -yqq && \
    apt install -y --no-install-recommends \
    build-essential curl ca-certificates \
    file git locales sudo \
    mecab libmecab-dev mecab-ipadic-utf8 && \
    locale-gen ja_JP.UTF-8 && \
    apt clean && \
    rm -rf /var/lib/apt/lists/*

# mecab-ipadic-neologdインストール
WORKDIR /tmp
RUN git clone --depth 1 https://github.com/neologd/mecab-ipadic-neologd.git && \
    ./mecab-ipadic-neologd/bin/install-mecab-ipadic-neologd -n -y && \
    sudo mv /usr/lib/x86_64-linux-gnu/mecab/dic/mecab-ipadic-neologd /var/lib/mecab/dic/ && \
    sed -i 's/debian/mecab-ipadic-neologd/' /etc/mecabrc && \
    rm -rf ./mecab-ipadic-neologd && \
    echo "完了"
```

- 内容を記述後、以下のコマンドでコンテナの立ち上げ及び起動を行う。

```bash
# ビルド
docker build -t mecab-con .

# 起動及び接続
docker run -it mecab-con
```

- コンテナの中へ接続後、以下でmecabが利用できることを確認できたら完了。

```bash
# バージョン確認
mecab -v

# 解析
echo "せっかちなかたつむり" | mecab

せっかち	名詞,形容動詞語幹,*,*,*,*,せっかち,セッカチ,セッカチ
な	助動詞,*,*,*,特殊・ダ,体言接続,だ,ナ,ナ
かたつむり	名詞,一般,*,*,*,*,かたつむり,カタツムリ,カタツムリ

# 辞書指定
echo "白石麻衣" | mecab -d /var/lib/mecab/dic/ipadic-utf8

白石	名詞,固有名詞,人名,姓,*,*,白石,シライシ,シライシ
麻衣	名詞,固有名詞,人名,名,*,*,麻衣,マイ,マイ

# 読み
echo "薔薇" | mecab -O yomi

バラ

# 分かち書き
echo "せっかちなかたつむり" | mecab -O wakati

せっかち な かたつむり

# 指定のtsvから解析して名詞のみを抜き出す。
cut -f1 ＊＊.tsv | mecab | grep '名詞' | cut -f1
```

## まとめ
- Linux環境への導入したことで標準出力や任意のデータの解析や分解が容易になった。
- 様々な利用の仕方があると思われるため、用途によって積極的に活用していく。

## 参考
- https://taku910.github.io/mecab/
- https://github.com/neologd/mecab-ipadic-neologd
- https://www.kkaneko.jp/tools/ubuntu/ubuntu_mecab.html
Drogon (web frame work) を使ってみた C++

# Drogon 
C++のウェブフレームワーク Drogon を使ってみたので感想などなど
フレームワークのリンクは以下に貼っておきます。

https://drogon.docsforge.com/master/getting-started/

これ使って（バックエンドのみ）作ったサイトは以下になります。

https://find-que.com/


# 所感
普通に使いやすかった。
バックエンドとして使用するには十分。（基本的にバックエンドとしてしか使ってないので）
ほかのライブラリーの導入もしやすかった。CMakeファイルを理解する勉強になった。
ソースコードの内部でデータベースのテーブル定義とかはできない。（外部モジュールを利用すれば可能かも）
テーブルは独自にSQLクライアントを使って作っておく必要あり。
対応データベースは**PostgreSQL**、**MySQL**、**Sqlite3**
macOSだとMySQLでは**mariaDB**を使うことになる。

# 遭遇したエラー１
https://drogon.docsforge.com/master/database-general/database-dbclient/#execsqlasync
にあるような感じで

```ruby
auto f = clientPtr->execSqlAsyncFuture(R"(insert into questions (user_id,title,text) values (2, "'", "'"))","default");
```

テーブルに値を追加するとき、
（titleとtextはchar型のカラム）シングルクォーテーションを追加するとtitleのカラムだけ'default'という値に変わってしまう。textはちゃんとシングルクォーテーションが挿入される。

MySQLクライアントで以下のような挿入をすると正しく実行されるのにも関わらず

```ruby
>> insert into questions (user_id,title,text) values (2, "'", "'");
```

## 原因
例に従って末尾に書いていた"default"という文字。

```ruby
auto f = clientPtr->execSqlAsyncFuture(R"(insert into questions (user_id,title,text) values (2, "'", "'"))","default");
```

execSqlAsyncFutureの内部で問題が起きている。

## 解決方法
末尾の"defaul"を削除する

```ruby
auto f = clientPtr->execSqlAsyncFuture(R"(insert into questions (user_id,title,text) values (2, "'", "'"))");
```

# 遭遇したエラー２

前述したようなSQL文では、ダブルクォーテーションを挿入するとエラーになる。

## 原因
MySQLのシーケンス文字を追加していないから

## 解決方法
正規表現を使って、シーケンス文字を挿入するべき文字にシーケンス文字を添付する
詳細はほかの記事にまた書く。

https://qiita.com/take_o/items/a34764d24ef89d20afcf