OmniAICreator/Qiita-1.07M huggingface dataset:
M5Stackシリーズ M5.begin()の互換性

# 前提条件

記事執筆時点のM5Stackシリーズの以下ライブラリ(Arduino IDEで使用可能)を使用した場合で、将来的に変わってしまう可能性がある。（と、いうか変わってほしい。でも、バージョン間の互換性が保てないので大きく変わることはないとも考えている）

+ M5Stackライブラリ：バージョン 0.3.1
+ M5StickCライブラリ：バージョン 0.2.0
+ M5Atomライブラリ：バージョン 0.0.1

# M5StackシリーズはモデルによってM5.begin()の引数が異なる

M5StackシリーズのM5Stack Gray、M5Stick-C、Atom Liteを使ってサンプルで遊んでいる時に開始関数であるbegin()関数がそれぞれ違うことに気がついた。

```cpp:M5Stack.h
// M5Stack.h（M5Stack用）
void begin(bool LCDEnable = true, bool SDEnable = true, bool SerialEnable = true, bool I2CEnable = false);
```

```cpp:M5StickC.h
// M5StickC.h（M5Stick-C用）
void begin(bool LCDEnable=true, bool PowerEnable=true, bool SerialEnable=true);
```


```cpp:M5Stack.h
// M5Stack.h（ATOM用）
void begin(bool SerialEnable = true, bool I2CEnable = true, bool DisplayEnable = false);
```

各引数は対応デバイスを初期化するかしないかのフラグだが、モデルによって引数の数も順番も全く違う。見やすいようにまとめると、

|モデル|使用 ライブラリ|第1引数|第2引数|第3引数|第4引数|
|:---:|:-----------:|:-----:|:----:|:----:|:-----:|
|M5Stack Gray|M5Stack|LCD (省略時:**初期化する**)|**SD** (省略時:初期化する)|UART (省略時:初期化する)|**I2C** (省略時:**初期化しない**)|
|M5Stick-C|M5StickC|LCD (省略時:**初期化する**)|**AXP** (省略時:初期化する)|UART (省略時:初期化する)|なし|
|Atom Lite|M5Atom|UART (省略時:初期化する)|**I2C** (省略時:**初期化する**)|LED (省略時:**初期化しない**)|なし|

モデルに固有のデバイス（SDとAXP）はともかく、I2C用に引数があるモデル（M5Stack GrayとAtom Lite）と引数がないモデル（M5Stick-C）、I2Cの引数省略時に初期化されるモデル（Atom Lite）と初期化されないモデル（M5Stack Gray）まである。
また、LCDとLEDのようにデバイスは異なるがU/Iとしては似たようなデバイスに対して引数省略時に初期化されるモデル（Atom Lite）と初期化されないモデル（M5Stack Gray）がある、という風に非常に複雑怪奇（私見）になっている。

# M5.begin()の引数はどうしたらいいか？

M5Stackシリーズのライブラリに付属しているサンプルスケッチではおおむね次のようになっていた。

```cpp:M5Stack_sample.cpp
setup(){
    // M5Stackの場合
    M5.begin();
}
```

```cpp:M5StickC_sample.cpp
setup(){
    // M5Stick-Cの場合
    M5.begin();
}
```


```cpp:M5Stack_sample.cpp
setup(){
    // ATOMの場合
    M5.begin(true, false, true);
}
```

サンプルスケッチとはいえモデルごとにM5.begin()の引数は異なっている。

1つのモデルを使うだけならもちろんM5.begin()の引数が異なっていても問題ないのだが、例えば液晶が付いていてデバッグしやすいM5Stack Gray/M5Stick-Cで開発/デバッグしたスケッチを小型で低消費電力のAtom Liteで動作させようとするとM5.begin()の部分まで書き換える必要が出てくるのが悩ましい。書き換えるのはメンテナンス性も良くないし、バグの温床になる。書き換えるのは1行でも少ない方が良い。

とは言え、

+ ふんだんなリソースを持つわけではないM5Stackシリーズでは独自ライブラリを作るのはあまり得策ではない。(バイナリの肥大化、消費電力の増大、オーバーヘッド増大)
+ 実稼働させる場合は消費電力やオーバーヘッドを削るために不要なデバイスは動かしたくない（初期化したくない)ので、結局モデルごとに引数が異なってしまう。
+ 互換性を重視し引数を省略して実装したとしても、処理や接続するデバイスの組み合わせでモデルごとに引数を変更する必要が出てくる。

といった事を考えると**モデルごとに引数を変更するように実装せざるをえない**、というのが結論。（あくまで個人的、今のところだが・・・）
codedeploy-agentをUbuntu Server 20.04 に入れるとエラーが発生する件


```shell
ubuntu@ip-172-31-48-49:~$ sudo ./install auto
Traceback (most recent call last):
	8: from ./install:34:in `<main>'
	7: from ./install:34:in `new'
	6: from /usr/lib/ruby/2.7.0/logger.rb:389:in `initialize'
	5: from /usr/lib/ruby/2.7.0/logger.rb:389:in `new'
	4: from /usr/lib/ruby/2.7.0/logger/log_device.rb:18:in `initialize'
	3: from /usr/lib/ruby/2.7.0/logger/log_device.rb:83:in `set_dev'
	2: from ./install:22:in `method_missing'
	1: from ./install:22:in `map'
./install:23:in `block in method_missing': undefined method `path' for #<IO:<STDOUT>> (NoMethodError)
```

以下で対応

```shell
sudo apt-get update
sudo apt-get install -y ruby
sudo wget https://aws-codedeploy-us-east-1.s3.amazonaws.com/releases/codedeploy-agent_1.0-1.1597_all.deb
sudo mkdir codedeploy-agent_1.0-1.1597_ubuntu20
sudo dpkg-deb -R codedeploy-agent_1.0-1.1597_all.deb codedeploy-agent_1.0-1.1597_ubuntu20
sudo sed 's/2.0/2.7/' -i ./codedeploy-agent_1.0-1.1597_ubuntu20/DEBIAN/control
sudo dpkg-deb -b codedeploy-agent_1.0-1.1597_ubuntu20
sudo dpkg -i codedeploy-agent_1.0-1.1597_ubuntu20.deb
sudo systemctl start codedeploy-agent
sudo systemctl enable codedeploy-agent
```
iframeとcssのみで縦横比を維持させる（wrapper要素不要）

# 前提
YouTubeの埋め込みなどで、ウィンドウサイズによって縦横比を固定したままiframeを可変できるようにしたいのはよくある需要です。
それを実現させるためにiframeをdivで囲んで可変対応させる方法が有名ですが
クライアント案件などにおいては **「WordPressなどでクライアント担当者が更新するが、相手に生のHTMLを書かせられない（ただYouTubeの埋め込みコードをコピペするだけにさせたい）」** というところで、中々対応するのが難しい状況があります。

# 結論
`font-size` と `em` を組み合わせて高さを確保する!

```scss

iframe {
  display: block;
  max-width: 100%;

  // 【ポイント１】
  // iframeを常に親要素の横幅いっっぱいにしたい場合は width: 100%; を指定
  // 基本は iframe の width と height の大きさで
  // ウィンドウサイズがそれよりも下回った場合にだけ可変させたい場合は width をトル
  width: 100%;

  // 【ポイント２】
  // 仮にスマフォデザインが左右に10vwずつマージンを確保してるものとする [100vw - (10vw * 2)]
  // 「親要素横幅いっぱいにしたいから 100%だ」 は間違いです。
  // font-sizeの100%は「親要素のfont-sizeと同じ」の意味だからです。
  // そのため必ずvwやpx、remで指定しましょう。
  // レスポンシブデザインでブレークポイントによって左右のマージンが変わる場合は
  // font-sizeのみを各メディアクエリ内で上書きしてください。
  font-size: 80vw;

  // 【ポイント3】
  // 1em は font-size と同じになるので、 16:9の比率にしたい場合 [1em:X = 16:9] となり
  // X = 0.5625em になる
  max-height: 0.5625em;
}
```

# 従来の（divで囲む）方法
一応こちらも記載しておきます。
css自体は上記のようにデザインに左右されないので大変シンプルですね。

```scss
.wrapper {
  position: relative;
  padding-top: 56.25%;

  iframe {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
  }
}

```
個人開発 :お笑いガシャで使用した技術まとめ（スクレイピング・Rails ・Heroku)

#開発コンセプト
自分の目の前にあるものや思いついたことを入力するとBoketeから最適なBokeを検索して表示してくれるガシャサービス。

世の中に情報があふれる中、整理してわかりやすくまとめることも大事だが、意外性やランダム性も同時に需要があり、今回は「お笑い＋ガシャ要素」が親和性が高そうなのでチャレンジしました。

ウェブアプリ を作るのも久しぶりなので、設計と開発だけでなく、集客や広告についても考えながらやろうと思いました。

お笑いガシャウェブサイト：http://www.owarai-gasha.site/

![top.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128165/ac376a08-b072-a1b7-e6c9-0c856ab71bbf.png)

↓

![coffe.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128165/44f00028-663b-ff6c-abe9-ba751e92c134.png)


#使用技術
・　Ruby on Rails
・　Heroku
・　スクレイピング(Mechanize)
・　お名前ドットコムで独自ドメインを取得

#詳細設計
以下の通りに設計しました。機能的にはキモの部分だけでほぼ９０％ですが見た目や、ユーザビリティーなどその他付帯要素または解説などユーザビリティーも非常に重要で、基礎技術部分が開発されたからと言って全体が開発された事にはならない。

ユーザーにとっては、基幹技術部分は１０%くらいで、残りの90%はUIやユーザーフレンドリーな解説などが重要視されていると感じた。

### （キモ）Mechanize を利用してBoketeをスクレイピングしてレンダリング
Mechanize やはりすごく便利です。以下の記事を参考にスクレイピング部分を完成させました。ポイントは、自分で入力したキーワードを元に対象サイトから情報を検索し表示させることでした。

参考：https://qiita.com/takuyanin/items/01256773e1cbfc84f51a

###　タグクラウド作成
こちらのCssを利用させていただきました。検索されたワードはDBに保存される設計にしたので、こちらが可能になりました。課題としてはNGワードを表示させないことですが、リスト作りは手作業になるのかな。。。

参考記事：https://296.co.jp/article/025815201928061430

###　上部に流れるテキスト作成
お飾りではありますが、これも必要かと思い作成しました。
参考記事：https://www.at-create.co.jp/staff-blog/css/180.html

###検索システムのエラー処理
変なキーワードだとやはり検索結果がゼロで帰ってきます。そのためRescue処理を実装し、表示されない場合のエラー画面を作成しました。このような細かな処理はユーザーにとっては重要で見慣れない英語のエラーなどは不審なサイトとみなされてしまいます。。。
参考記事：https://qiita.com/ngron/items/4c319ae7340b72c7e566

###Twitterに投稿したときのOgの設定
Twitterに投稿したときのカードの絵やテキストです。これも地味ながら非常に重要で、目につきやすくわかりやすいかなどがポイントです。やらないよりはやった方が１００倍いいです。
![スクリーンショット 2020-10-29 12.21.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128165/7300eeaf-84d4-c37f-ad98-93cc8e4abd9b.png)

参考記事：https://qiita.com/d0ne1s/items/8f0193ea45d50a20e3d2


#広告・公開
公開にはService Safari様を利用させてもらいました。
https://www.service-safari.com/posts/38644

個人公開なのでそんなに費用はかけませんが広告はGoogleではなく予算を決めてTwitterで挑戦してみようかと思います。始めてからこちらは需要があれば報告したいと思います。

今回は自分用のメモも兼ねてですがウェブアプリ お笑いガシャを作った事について大まかにまとめてみました。個別の技術の説明の方が需要があるかもしれませんが、自己満足も兼ねて投稿させていただきました（笑）スミマセン

よければ使ってみてご意見いただけましたら幸甚です。
UFT Oneのインストールする機能を変更したい

# はじめに

UFTってドキュメントを探しても中々出てこなかったりしますよね。
（私もそれで困っている人の一人です）
なのでどんな些細なことでも書き残していきたいと思い、この記事を書いています。
（UFTユーザの皆様もぜひ書いてください笑）


# UFT Oneのインストールする機能について

UFT Oneのインストール時に下記のような画面で、どのアドインをインストールするかを選択することができます。
![図1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/121319/7db35ea4-cd72-9ed5-17b1-8878c2828f0a.png)

こちらでは自分が使用するであろうアドインをインストールすると思いますが、
使っていくうちにあのアドインも入れておけばよかった！という場面に遭遇すると思います。
そのときにどうするかを記載します。


# UFT Oneのインストールする機能の変更方法

方法はとっても簡単な4ステップ。
アンインストールは必要ありません！

1. C:\Temp\Unified Functional Testing\setup.exeを起動（デフォルトのままインストールしてたらここにあります）
2. 「次へ」で進める
3. 「変更・修復・削除」の3択が出てきたら「変更」をクリック
4. 一覧の中からインストールしたい機能を選択・インストールし、「次へ」

たったこれだけです。
とても簡単。



ちなみに当然ながら、アドインはインストールすればするほど容量を食います。
またUFT起動時にどのアドインを使用するか、下記の画面で選択できます。
![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/121319/983a9cb1-3e4c-fcd6-192a-aceb9c74759a.png)
公式では**推奨3つ**。（3つ以上でも動きます）
が、使わないアドインは選択肢ないのが良いと思います。
RMagick4.1.2インストール時に発生したエラーの対応

## 問題
RMagick4.1.2インストール時にエラーが発生。エラーを取り除き、インストールしたい。

## 結論
ImageMagickが6.9.10だったので7.0.10に上げたらインストールできた。

## やったこと

```
# gem install rmagick -v '4.1.2'

Building native extensions. This could take a while...
ERROR:  Error installing rmagick:
        ERROR: Failed to build gem native extension.

    current directory: /usr/local/bundle/gems/rmagick-4.1.2/ext/RMagick
/usr/local/bin/ruby -I /usr/local/lib/ruby/2.6.0 -r ./siteconf20201029-30239-189vtpy.rb extconf.rb
checking for brew... no
checking for pacman... no
checking for Ruby version >= 2.3.0... yes
checking for pkg-config... no


ERROR: Can't install RMagick 4.1.2. Can't find pkg-config in /usr/local/bundle/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
```

ここでエラーが発生していた。
以下はバージョン情報。

```
# ruby -v
ruby 2.6.6p146 (2020-03-31 revision 67876) [x86_64-linux]

# apt list
imagemagick-6-common/stable,stable,now 8:6.9.10.23+dfsg-2.1+deb10u1 all [installed,automatic]
imagemagick-6-doc/stable,stable 8:6.9.10.23+dfsg-2.1+deb10u1 all
imagemagick-6.q16/stable,stable,now 8:6.9.10.23+dfsg-2.1+deb10u1 amd64 [installed,automatic]
imagemagick-6.q16hdri/stable,stable 8:6.9.10.23+dfsg-2.1+deb10u1 amd64
imagemagick-common/stable,stable 8:6.9.10.23+dfsg-2.1+deb10u1 all
imagemagick-doc/stable,stable 8:6.9.10.23+dfsg-2.1+deb10u1 all
imagemagick/stable,stable,now 8:6.9.10.23+dfsg-2.1+deb10u1 amd64 [installed]
```

### 既に似たようなIssueがあった

[LoadError:dlopen(/Library/Ruby/Gems/2.6.0/gems/rmagick-4.1.2/lib/RMagick2.bundle, 0x0009) · Issue #1247 · rmagick/rmagick · GitHub](https://github.com/rmagick/rmagick/issues/1247)

### ImageMagick7をインストールする

```
# apt remove imagemagick
# sudo apt update 
# sudo apt-get install build-essential
# wget https://www.imagemagick.org/download/ImageMagick.tar.gz
# tar xvzf ImageMagick.tar.gz
# cd ImageMagick-7.0.10-34/
# ./configure 
# make
# make install 

# ランタイムリンクの設定
# ldconfig /usr/local/lib

# 確認
# magick -version
Version: ImageMagick 7.0.10-34 Q16 x86_64 2020-10-29 https://imagemagick.org
Copyright: © 1999-2020 ImageMagick Studio LLC
License: https://imagemagick.org/script/license.php
Features: Cipher DPC HDRI OpenMP(4.5) 
Delegates (built-in): bzlib djvu fontconfig freetype jbig jng jp2 jpeg lcms lqr lzma openexr png tiff x xml zlib

```

### RMagickが入るかテスト

```
# gem install rmagick -v '4.1.2'
Building native extensions. This could take a while...
Successfully installed rmagick-4.1.2
1 gem installed
```
やったね。


### 追記

> ERROR: Can't install RMagick 4.2.2. Can't find pkg-config

4.2.2の場合には以下も必要でした。

```
apt install -y libmagick++-dev
```
TypeScriptであるオブジェクト型から一部のプロパティを取り除いた型を作る

TSで

```ts
type User = {name: string, age: number};
```

という型から、ageを取り除いた年齢なしユーザーの型を新たに作りたいとする。

これはOmitを使えば実現できる。

```ts
type UserWithoutAge = Omit<User, 'age'>;
```

年齢のない型はきっと女性に喜ばれるだろう。
RでRFM分析.2 (関数の作成)

# 記事の目的
この記事では、前回の記事[(RでRFM分析.1)](https://qiita.com/Tatsuki-Oike/items/4134dc3d5e370c05bd0b)のRFM分析の関数を作成します。
定期的に分析する場合に便利です。


# 目次

[1. 使用データ](#1-使用データ)
[2. RFM関数](#2-rfm関数)
[5. 関数の適用](#5-関数の適用)

#1. 使用データ
[前回](https://qiita.com/Tatsuki-Oike/items/4134dc3d5e370c05bd0b)と同じデータを使用します。

```R:
Data %>% head()
# 結果
        time customer_id price
1 2020-03-21           1   500
2 2020-03-19           2  7386
3 2020-03-03           3 21353
4 2020-03-28           4   500
5 2020-03-05           5  9022
6 2020-03-08           6  2338
```

#2. RFM関数
```R:
library(lattice)
rfm.function <- function(Data, r.c, f.c, m.c){
  
  #RFMデータ作成
  time <- Data$time %>% unique() %>% sort()
  recency <- 1:length(time)
  recency.tmp <- data.frame(time, recency)
  Data.rfm.tmp <- left_join(Data, recency.tmp, by="time")
  rfm <- Data.rfm.tmp %>% group_by(customer_id) %>% 
    summarize(r=max(recency), f=n(), m=sum(price))
  
  #ポイント設定
  rfm.point <- rfm %>% mutate(r.point = if_else(r<r.c[1],1,if_else(r<r.c[2],2,if_else(r<r.c[3],3,if_else(r<r.c[4],4,5)))),
                               f.point = if_else(f<f.c[1],1,if_else(f<f.c[2],2,if_else(f<f.c[3],3,if_else(f<f.c[4],4,5)))),
                               m.point = if_else(m<m.c[1],1,if_else(m<m.c[2],2,if_else(m<m.c[3],3,if_else(m<m.c[4],4,5)))))
  
  #R,F,M得点分布
  r <- rfm.point %>% group_by(r.point) %>% summarise(r.point = n()) 
  f <- rfm.point %>% group_by(f.point) %>% summarise(f.point = n()) 
  m <- rfm.point %>% group_by(m.point) %>% summarise(m.point = n()) 
  n.rfm <- data.frame(r, f, m)
  
  #総合得点
  point <- rfm.point$r.point+rfm.point$f.point+rfm.point$m.point
  n.rfm.sum <- point %>% as.factor() %>% summary()
  
  #k-means
  km <- kmeans(rfm.point[,5:7], 3, iter.max = 30)
  rfm.point$cluster <- km$cluster %>% as.factor()
  p1 <- bwplot(r.point~cluster, rfm.point, horizontal = FALSE)
  p2 <- bwplot(f.point~cluster, rfm.point, horizontal = FALSE)
  p3 <- bwplot(m.point~cluster, rfm.point, horizontal = FALSE)
  n.cluster <- rfm.point %>% group_by(cluster) %>% summarize(cout =n())
  
  return( list(n.rfm, n.rfm.sum, n.cluster, p1, p2, p3) )
}
```

#3. 関数の適用
r, f, mのポイントの基準(criteria→r.c, f.c, m.c)を設定して、データのカラムの名前をtime, customer_id, priceに設定すれば使用できます。
また、ここでは表示していませんが、クラスタ分析の箱ひげ図も表示されます。

```R:
r.c <- c(3, 8, 15, 22)
f.c <- c(2, 5, 11, 16)
m.c <- c(501, 10000, 50000, 100000)
rfm.function(Data, r.c, f.c, m.c)
# 結果
[[1]]
  r.point f.point m.point
1      35     710     264
2     112     109     371
3     191      99     275
4     216      50      68
5     446      32      22

[[2]]
  3   4   5   6   7   8   9  10  11  12  13  14  15 
 11  56 122 178 192 141  77  54  65  33  37  18  16 

[[3]]
# A tibble: 3 x 2
  cluster  cout
  <fct>   <int>
1 1         419
2 2         245
3 3         336
```
CakePHP フォームの利用

#フォームの利用の流れ
1. フォームが組み込まれたテンプレートファイルを表示する。
2. フォームに入力された値を、Httpリクエスでコントローラに受け渡す。
3. コントローラは受け取ったデータをもとに処理をする。処理結果をビューに渡す。
4. ビューは結果を表示する。

## フォーム

```php
<form method = "post" action = "hello/sendForm"> //httpメソッドとリクエスト先を指定
<input type="text" name = "text1"> 
    <input type="submit">
</form>
```


##送信情報を管理する$this->request

`$result = $this->request;`

AppControllerクラスにはrequestというプロパティが定義されている。
requestにリクエストの情報を管理するCakeRequestインスタンスが設定されている。
`request = new CakeRequest`


####$this->request（CakeRequetのプロパティ）一覧
**params** 送られた値全てをまとめたもの
**data** POST送信された値
**query** GETのクエリーテキストで送られた値。クエリーテキストはurlの？の後ろの値。?`キー=値`の様な形。

その他にもあるが、割愛する。
$this->requetを出力すればなにがあるかわかる。

##ビューへの変数設定

`$this->set(変数名,値);`

コントローラーでこの様に実行すると、第一引数の変数がビューで設定される。

`$this->set(compact(変数名));`
compact()を実行すると、引数に設定した変数名と一致する、変数とその値から配列を作ってくれる。

##フォームを作るときの注意点

フォームに`<script type"text/javascript"> 悪質なスクリプト </script>`などの悪質スクリプトを入力され場合、対策をしていなければスクリプトが実行されてしまい情報漏洩やデータの改竄につながることがある。

Sanitizeライブラリなどの利用で対策しておく必要がある。

#フォームヘルパー
htmlタグを使ってフォームを作成することもできるが、CakePHPではフォームをより簡単に作成することができる
フォームヘルパーというものを用意している。フォームヘルパーで記述したものは、結果的にhtml変換される。htmlでタグを記述して属性を設定してと細かな設定が必要な部分をより簡潔に済ませてくれる。

#フォームを作成する時の命名規則

text(名前）の引数は、モデル名.フィールド名にする必要がある。このように書くことで、テーブル構造と同じデータをコントローラに渡すことができて、`$this->save($this->data)`のテーブルにデータを保存する場合も
対応するテーブルのカラムにデータを保存できるようなクエリを作成することができる。
checkbox（名前）などの場合も同様に命名する。


```php

<?php 
//テンプレートファイル
 echo $this->Form->text("Board.id"); 
 echo $this->Form->checkbox("Board.name"); 

// コントローラ側にフォームから送られてきた形
// Array ( [Board] => Array ( [id] => 2 [name] => hoge ) )
?>

```
Herokuにデプロイしたあとの更新方法

※初心者に向けた記事です。

現在プログラミング学習中です。今回、Herokuへデプロイしたアプリケーションを、更新する方法を自分の備忘録としてメモ書きにてまとめました。

##Githubへの更新方法

①全ファイルをステージさせる

```ruby:ターミナル　
$ git add .
 ``` 

②ステージさせた変更をコミット

```ruby:ターミナル　
$ git commit -m 'メッセージ' 
```
 
③リモートリポジトリへプッシュ

```ruby:ターミナル　
$ git push -u origin master
```


##Herokuへの更新方法

①Herokuにログイン

```ruby:ターミナル　
$ heroku login -i
```

②Herokuにデプロイ

```ruby:ターミナル　
$ git push heroku master
```
少し時間がかかります。

③マイグレーション

```ruby:ターミナル
$ heroku run rails db:migrate
```

###参考にさせていただいた記事
herokuでデプロイした後の更新の仕方(2回目以降)：
https://qiita.com/MNK0910/items/5f47fed4a07b9f75944d
指定したディレクトリ内を再帰的に探索してファイルを見る

`os.walk()` を使って実装

```Python
import argparse
import os


def find_all_files(directory):
    for root, dirs, files in os.walk(directory):
        yield root
        for file in files:
            yield os.path.join(root, file)


def main():
    parser = argparse.ArgumentParser()
    parser.add_argument(
        "directory", type=str, help="directory that you hope to look into."
    )
    parser.add_argument(
        "-e", "--extension", type=str, help="specify files with extension"
    )
    parser.add_argument("-c", "--cat", help="cat the file", action="store_true")
    parser.add_argument("-w", "--wc", help="wc the file", action="store_true")
    args = parser.parse_args()

    for file in find_all_files(args.directory):
        if args.extension:
            extension = file.split(".")[-1]
            if extension != args.extension:
                continue

        if args.wc:
            os.system("wc " + file)
        else:
            print(file)

        if args.cat:
            print("##### HEAD OF THE FILE #####\n\n")
            for line in open(file):
                print(line, end="")
            print("##### END OF THE FILE #####\n\n")


if __name__ == "__main__":
    main()
```

使い方

```
$ python find_all_files.py --help
usage: find_all_files.py [-h] [-e EXTENSION] [-c] [-w] directory

positional arguments:
  directory             directory that you hope to look into.

optional arguments:
  -h, --help            show this help message and exit
  -e EXTENSION, --extension EXTENSION
                        specify files with extension
  -c, --cat             cat the file
  -w, --wc              wc the file
```

次のようにすると、指定したディレクトリ内の .py ファイルを再帰的に探索して全部中身が見れます。

```
python find_all_files.py directory -e py -c
```

参考にしたサイト

https://qiita.com/suin/items/cdef17e447ceeff6e79d
vertical-alignについて

## ■ はじめに

CSSプロパティのvertical-alignについて記事にしました。
この記事で得る内容は以下の通りです。

・CSSの基礎知識が増える

## ■ vertical-alignとは
行中のテキストや画像などの内容の上下方向の揃え方向を指定するプロパティで、インライン要素と
テーブルセルにのみ適用することができる。

例えば、以下の場合の様に微妙に特殊文字と文字列がずれてしまっている場合

![スクリーンショット 2020-10-29 11.36.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/772631/100aad0c-a08f-0f32-eb26-bbb45834b3f1.png)

`vertical-align: sub;`を特殊文字に適用させる事できれいに表示することができます
（値）sub：テキストを下付き文字の位置にする（文字サイズは変わらず・テーブルセルには無効）

![スクリーンショット 2020-10-29 11.41.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/772631/78e2ce3d-9cd4-25f0-35c3-a2a180dacd40.png)

指定できる値として、指定要素が対象のtop,middle,bottom
テキストが対象のtext-top,text-bottom,super,sub,長さも指定できる。実際に検証で試した方が良さそう

<font color=#fff>ヴァーティカル・エアレイド！</font>
package.jsonを正しく操作。パッケージの削除はyarn removeで。


`package.json`はJSONファイルなので直接不要なモジュールを削除できてしまうのですが、
そのやり方はよくないです。

自分は手動で消して、新しく発生してしまったエラーを見過ごすというミスをやらかしました。



### 手動で消してはいけない理由
`package.json`の変更履歴を管理している`yarn.lock`や、
`node_modules`に、削除の操作の履歴が反映されない。
同じリポジトリで作業している他のチームの人に変更を正しくつたえられない、という事態にもなる。


### 操作方法 
```
yarn remove {削除したいやつ}
```
というかんじで操作するように気をつけたいと思いました


###  え？でも自分の手元ではエラーでてないけど？
そういうときは一度`yarn`してみてください。
たぶんエラーになるんじゃないかな


### ついでに
`package.json`からあるパッケージを直接削除して、自分の手元のnude_modulesにはそのまま削除前の情報がのこっている状態での挙動になります。
挙動の違いや、新たに発生したエラー、もしくはエラーが解除できたのか、などの状態をただしくみることができません。
.NET 5 で Microsoft Store のアプリ内課金の API の呼び方

試してみたら動きそうレベルの内容です。

アプリ内課金の API を MSIX 化した WPF や WinForms などのアプリから呼ぶには `IInitializeWithWindow` というインターフェースを自分で作ってキャストして `Initialize` メソッドを読んでやる必要があると以下のドキュメントに書いてあります。

https://docs.microsoft.com/ja-jp/windows/uwp/monetize/in-app-purchases-and-trials#desktop

アプリ内課金 API を実際に試すのはちょっと荷が重いので、.NET 5 で WPF アプリを作って Target Framework Monikers に net5.0-windows10.0.19041.0 を指定して呼び出すのに同じ手順が必要な FileOpenPicker クラスで試してみたところ `IInitializeWithWindow` インターフェースへのキャストに失敗してしまいました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70288/6972924e-da6a-743e-80be-af72f59f4dd2.png)

ではどうするのか？という感じなのですが `using WinRT;` を追加して `As<T>` メソッドで `IInitializeWithWindow` にキャストしてやればいいです。

```csharp
using System;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Interop;
using Windows.Storage.Pickers;
using WinRT;

namespace WpfApp2
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private async void Button_Click(object sender, RoutedEventArgs e)
        {
            var picker = new FileOpenPicker();
            // It doesn't work on .NET 5
            // ((IInitializeWithWindow)(object)picker).Initialize(...);
            var w = picker.As<IInitializeWithWindow>();
            w.Initialize(new WindowInteropHelper(this).Handle);

            picker.FileTypeFilter.Add(".png");
            var file = await picker.PickSingleFileAsync();
            MessageBox.Show(file?.Name ?? "not selected");
        }
    }

    [ComImport]
    [Guid("3E68D4BD-7135-4D10-8018-9FB6D9F33FA1")]
    [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    public interface IInitializeWithWindow
    {
        void Initialize(IntPtr hwnd);
    }
}
```

同じ要領でアプリ内課金の API も叩けそうだという雰囲気。
Redmine を Mac の docker 上で使ってみる

# 概要
Mac mini で Redmine が動作する環境を構築した時のメモ


# 環境
- macOS Catalina 10.15.7
- Mac mini(2018)
- メモリ 8GB 2667 MHz DDR4
- グラフィックス Intel UHD Graphics 630 1536 MB


# Docker インストール

Docker Desktop をインストール

```
$ brew cask install docker
```
[Docker公式](https://www.docker.com)

# Redmine インストール

以下の記事を参考にインストール
[[Docker] Mac 上の Docker で Redmine 環境を構築する](https://blog.hiros-dot.net/?p=9007)


# 参考リンク
- [Docker公式](https://www.docker.com)
- [[Docker] Mac 上の Docker で Redmine 環境を構築する](https://blog.hiros-dot.net/?p=9007)
その他タスクで出てきたリンク

###npm パッケージの作成
https://karuta-kayituka.hatenablog.com/entry/2020/04/05/124531

###APIをたたく
jq json
postman
https://www.postman.com/
ダウンロード
https://www.postman.com/downloads/
使い方
・使用方法
①左上のnewを押す
②Requestを選択
③requestnameを入れ、フォルダーを作成し、save to xxxを押下する
④getの左に対象のurlを入れ、sendを押下する
※何度も繰り返し押下する必要があることもあるらしい。

・json整形
Body→raw→Textをjsonに変える→加工したいjsonを貼り付けを行い、
Beautifyを押下する。
様々なジェネレータのまとめ

webやアプリを作成する場合にボタンやアニメーション、色合いなど様々なことを迷われると思います。
今ではフレームワークがあるのでそこまで考えなくてもそれらを使用すればいい感じのものを作成してくれます。
しかしやはり用意されているものなのでどこか違うんだよなーってのが少なからずあると思います。
ただ作成するのはめんどくさい、どう作ればいいんだろうなど考えてしまいます。
そこでそういう時に役に立つ様々なジェネレータをご紹介したいとお思います。


##グラデーションのジェネレータ
グラデーションの色や角度、位置、透明度まで指定してオリジナルのグラデーションを作成することができます。
また、グラデーションを作りたいけどどんな色合いのグラデーションを作ればいいのかわからない時はグラデーションのギャラリーがあるのでそちらから参考にして作成することもできます。

http://www.ourownthing.co.uk/gradpad.html
![スクリーンショット 2020-10-29 10.21.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536289/c6970f5c-58c8-fdbd-c618-e4b46072a8ea.png)


##border-radius角丸のジェネレータ
シンプルな角丸でしたら自分自身やフレームワークなどを利用すれば済む話だと思うのですが、
複雑な角丸でしたらこちらのジェネレータを使うととても便利に作成することができます。

https://9elements.github.io/fancy-border-radius/
![スクリーンショット 2020-10-29 10.19.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536289/6e6943f5-477d-af44-c57c-bde496e8691d.png)


##flex layout generator
Flex boxのジェネレータです。
親要素、子要素でタブが別れていますので、とてもわかりやすく使いやすいです。

https://suiq.jp/flex-layout-generator/
![スクリーンショット 2020-10-29 10.19.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536289/89c0d6f4-4c20-e5ff-4253-4865beaf4566.png)


##三角形ジェネレータ
三角形を作成できるジェネレータです。
地味に三角形って作成するの面倒くさいのでとてもとても便利です。

http://apps.eky.hk/css-triangle-generator/
![スクリーンショット 2020-10-29 10.20.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536289/84df6b9f-1126-e952-5ff5-4e346b961918.png)


##ローディングジェネレータ
シンプルなローダーはフレームワークとかであると思うのでいいのですがちょっと違ったローディングを採用したい時はこちらを使うとちょっと違ったものになります。
cssのみでもいいですし、またはvueのコンポーネントとしても実装することができます。

https://epic-spinners.epicmax.co/
![スクリーンショット 2020-10-29 10.45.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536289/21a6ee9d-b906-547d-bd90-9cd6f0a93007.png)


##ボタンジェネレータ
様々なボタンのテンプレートが用意されていて、さらにそのテンプレートを自分好みに細かく設定することができます。

https://www.bestcssbuttongenerator.com/
![スクリーンショット 2020-10-29 10.20.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536289/20d9d514-68e2-1938-c75e-c6a547145d36.png)

##グリッドジェネレータ
グリッドをGUIで操作でき自分の好きなようにレイアウト作成することができます。
最近ではグリットレイアウトのページは少なくなってきているので使う場面は少ないとは思いますが、
それでもこれはすぐに見た目を確認することができるのでとても便利なジェネレーターだと思います。

https://cssgrid-generator.netlify.app/
![スクリーンショット 2020-10-29 10.22.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536289/3ef83fb2-d057-e1a3-1031-603a2ba62187.png)


##アニメーションジェネレータ
回転や色、向き、バウンドといった様々なアニメーションを自分の好みのもの見つけて細かく設定することもでき、作成することができます。

https://animista.net/
![スクリーンショット 2020-10-29 10.18.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536289/91c7763d-972e-68a4-ff61-16d51d60bf12.png)
ライブ会場のステージに複数の視聴者を投影するサンプル

コロナの影響で、無観客ライブ配信の開催が多く見られるようになってきました。
この場合は基本的に1方向での配信になり、演者と視聴者の一体感が生まれません。

その代替として、ライブの視聴者の映像をステージ上の壁に投影するケースが生まれてきました。
この記事ではそのシステムを簡易に実現できるサンプルコードについて解説します。
このシステム名”FanWall”と呼んだりしています。

[SDKv3系のサンプルはこちら](https://github.com/fu-jimoto/AgoraIO-FanWall)
[SDKv4系のサンプルはこちら](https://github.com/fu-jimoto/AgoraIO-FanWall/tree/v4)

##構成イメージ
###ライブ会場のイメージ
![ステージのイメージ(1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/300377/ebb47bb6-9773-d6e3-2a3b-743b5b01fa50.png)

###視聴者が見ている画面
![視聴画面.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/300377/a11cce08-cbc7-94de-f3e8-4185157cdfe9.png)

###FanWallの画面
![FanWall.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/300377/4358dd0f-ff3c-f4f8-811d-e33081810095.jpeg)

##システム構成
![システム構成.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/300377/36511a35-0a64-7159-ce7b-a4ac2f633f4b.png)

[視聴者](https://github.com/fu-jimoto/AgoraIO-FanWall/blob/main/audience.html)は同時に２つのチャンネルに接続します。
会場からのライブ映像を受け取る専用のチャンネルと、FanWallに対して映像を送るチャンネルになります。運営者から選択された視聴者はライブ配信用のチャンネルに音声が流れます。


[配信者](https://github.com/fu-jimoto/AgoraIO-FanWall/blob/main/host.html)は一方的にライブ映像を配信するチャンネルに接続します。


[FanWall](https://github.com/fu-jimoto/AgoraIO-FanWall/blob/main/operator.html)は視聴者の映像を受け取って表示をしています。
また、サンプルでは視聴者をクリックする事で、ライブ配信のチャンネルに音声を流す事が可能です。


##実装の解説
視聴者のチャンネル接続は[２箇所になります。
[L54](https://github.com/fu-jimoto/AgoraIO-FanWall/blob/main/audience.html#L54)
[L112](https://github.com/fu-jimoto/AgoraIO-FanWall/blob/main/audience.html#L112)
ライブ配信用にはマイクだけ取得、FanWall用にはカメラだけ取得しておきます
又、初期の段階では音声は配信しません。
運営者側からの操作で音声が配信されます。
[L142](https://github.com/fu-jimoto/AgoraIO-FanWall/blob/main/audience.html#L142)

配信側のチャンネル接続は１箇所になります。
[L48](https://github.com/fu-jimoto/AgoraIO-FanWall/blob/main/host.html#L48)
又、全体的に複雑な実装はなく、単純なライブ配信のロジックになります。

FanWallのチャンネル接続も１箇所になります。
[L48](https://github.com/fu-jimoto/AgoraIO-FanWall/blob/main/host.html#L48)
視聴者の映像をクリックする事で該当者の音声をライブ側のチャンネルに流します。
[L144](https://github.com/fu-jimoto/AgoraIO-FanWall/blob/main/operator.html#L144)

##実運用で出てきた課題
FanWallの各チャンネルに視聴者をランダムに振り分けた際、すべての枠が視聴者の映像で埋まらないケースがでてきます。
そこで、FanWallの操作で、映像を送ってきてくれているユーザを特定のチャンネルに移動させるサンプルを追加しました。
(こちらはSDKv4のサンプルに実装しています）
[Fanwall側](https://github.com/fu-jimoto/AgoraIO-FanWall/blob/v4/operator.html#L116)
[視聴者側](https://github.com/fu-jimoto/AgoraIO-FanWall/blob/v4/audience.html#L97)
FanWall側で特定の視聴者を特定のチャンネル(mainチャンネルへ移動も可能）できる処理を追加しています。
（実際には、裏側のオペレータ専用の画面で操作することになるかと思います。）




##最後に
[**agora.ioに関するお問い合わせはこちらから**](https://jp.vcube.com/lp/agora?utm_campaign=Agora&utm_source=Qiita&arc_id=a33bda03c1d85dc79a05)
[<img width="912" alt="スクリーンショット 0001-08-15 13.41.56.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/300377/5d815376-9b89-08fa-9434-6fa7e8e67bcf.png">](https://jp.vcube.com/lp/agora?utm_campaign=Agora&utm_source=Qiita&arc_id=a33bda03c1d85dc79a05)
【Ruby On Rails】RSpecを用いたテストのエラー MySQL client is not connected

備忘録です。

#エラー内容
```terminal
OrderForm
  商品購入
    商品購入がうまくいく時
      次の7項目が存在すれば購入できる→zipcide, prefecture_id, city, address, phone_number, user_id, item_id
      建物名が空でも購入できる
    商品購入がうまくいかない時
      郵便番号が空では購入ができない
      郵便番号にハイフンがないと購入できない
      電話番号にハイフンがあると購入できない (FAILED - 1)
      電話番号が11桁以内じゃないと購入できない (FAILED - 2)

Failures:

  1) OrderForm 商品購入 商品購入がうまくいかない時 電話番号にハイフンがあると購入できない
     Failure/Error: _query(sql, @query_options.merge(options))
     
     ActiveRecord::StatementInvalid:
       Mysql2::Error::ConnectionError: Lost connection to MySQL server during query
```

Mysqlでエラーが起こっているとのこと。
おそらくですが、先に読み込まれるべきデータより前に、後のものを読み込んでしまってエラーが起きている可能性があります。

#対処法

```Ruby
require 'rails_helper'
describe OrderForm do
  before do
    @order = FactoryBot.build(:order_form)
    sleep(1)
  end
```
先に読み込まれるものが無いように、１秒毎にテスト処理を行うことにしました。
テストの記述にsleep(1)を追記してあげることで、エラーを回避することができました。
hyperlinking formula field not working

#ハイパーリンクの数式の問題

参考URL
https://success.salesforce.com/answers?id=9063A000000lZyFQAU

https://success.salesforce.com/answers?id=9063A000000ph0jQAA

解決策
I was able to fix this issue! When I changed the URLs from a Classic URL to a Lightning URL (without spaces: https:// yourdomain.lightning.force. com/lightning/r/{recordId}/view), it hyperlinked again for everyone. :)

どうも、ハイパーリンクに設定するURLをLightningフォーマットにすると動くとある。
eslintにjsファイル以外を無視させる

tslintがでprecatedになっていることから、eslintへの移行を最近しています。
めんどい…

基本的には公式ドキュメントを読めばわかることだったのですが、
TSLintからESlintからに移行する記事を読みあさって、そこに書いてあることを適当に導入した結果、
あまりよくない設定をしていた結果を招いてしまったので、なおしました。

### 公式ドキュメント該当箇所はこちら
https://eslint.org/docs/user-guide/configuring#ignoring-files-and-directories


# 設定系のjsファイルにeslintをかけたくない

### BEFORE
`package.json`に以下のように設定していました。

```package.json
// （その他の設定、たぶんdependenciesなど）
..
  "eslintIgnore": [
     "/.eslintrc.js"
   ],
..
// (その他の設定、scriptsなど)
```
※jsonファイルでコメントいれれないのに無理やり書いてるので赤くエラーになってるけど…説明のためなのでご容赦ください


これだとほかの設定系ファイルではリンターが作動してエラーがでちゃってました。
`{なんちゃら}.config.js`みたいなやつです。

あとESLintの設定は`.eslintrc.js`にまとめられている方がベター。

なので以下のように書き換えることで、設定ファイル系jsファイルはすべて除外、としました。



### AFTER

```..eslintrc.js
// （extendsやpluginsなど）
..
 "ignorePatterns": ['/*.js'],
 "rules": {
..
// (ESLintのルールがざーっとかかれてる)
```

これで、`.eslintrc.js`だけをESLintの対象から除外するのではなく、
他の設定系ファイルも除外できてエラーがでなくなりました。
S3に置いたActiveStorageをローカルに移す

あまり使うことは無さそうですが、RailsのActiveStorageで管理しているファイルを、S3からローカル(disk)に移しました。

やり方を忘れないようにメモ。

## ディレクトリ構造

S3では、ファイルは```SU61LeyW6YcZtZaoNHSL2CTu```のような名前でbucketに格納されています。

ローカルのディレクトリに置く場合は、```storage/SU/61/SU61LeyW6YcZtZaoNHSL2CTu```のようになっています。つまり、2階層のディレクトリが作られていて、1階層目はファイル名の先頭の2文字、2階層目は3文字目と4文字目がディレクトリ名になっています。

## 手順 

### S3からファイルをコピーする

tmpの下のstorageというディレクトリにコピーします。

```
$ mkdir tmp/storage
$ aws s3 cp s3://<bucket-name> ./tmp/storage --recursive
```

### ActiveStorageのディレクトリに移す
次のRubyスクリプトで2階層のディレクトリを作りながらコピーします。
アプリケーションのルートディレクトリで実行します。

```ruby
require 'fileutils'

src = "tmp/storage"
dst = "storage"

Dir.glob("#{src}/**/*").each do |source|
  next unless File.file?(source)
  file = File.basename(source)
  dir1, dir2, = file.scan(/\A(?<dir1>..)(?<dir2>..)/).flatten
  target = "#{dst}/#{dir1}/#{dir2}/#{file}"
  FileUtils.mkdir_p(File.dirname(target)) unless File.exist?(File.dirname(target))
  FileUtils.cp(source, target)
  puts target
end
```

### 後始末

コピーしてきたファイルや、作業用のディレクトリを削除します。
2022年10月の質問の中から整理します

[まとめページに戻る](https://qiita.com/Keiji_otsubo/items/60afc2a8d211b6f7d89f)



# カスタムリンクボタンのフォーマット
VFとLightningでは違う。

The format for URL hacking is different in lightning. Your VF page will need to change to the format:
/lightning/o/Lead/new?defaultFieldValues=LastName=Unknown

+ [Lightning Conversion Issue](https://success.salesforce.com/answers?id=9063A000000aFFC)
+ [How to add table in an email template?](https://success.salesforce.com/answers?id=9063A000000ecO4)

# モバイルアプリをアップする方法

[hello i want to upload and take photo from camera at the same time through custom field.how can i do that ?](https://success.salesforce.com/answers?id=9063A000000leL0)


# モバイルアプリで遷移するボタンを作る

[how to add button in a lightning component that redirects the user from salesforce1 app to a browser on click?](https://success.salesforce.com/answers?id=9063A000000ecI1)
[UE4]Level BlueprintをDiffする（差分を見る）方法について

# はじめに
UE4の**BlueprintのDiff機能**を使うことで特定のバージョン間におけるBlueprintの差分を見ることが可能です。この機能は通常のBlueprintだけでなくAnimation Blueprintにも対応しています。
![DiffTool-1009x542-719850393.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363889/f6f186a9-a679-5cf6-db19-81cd67e8f3ea.png)
アンリアルのアセットを DIFF する
https://www.unrealengine.com/ja/blog/diffing-unreal-assets
【UE4】BPの差分ツールの紹介
https://logicalbeat.jp/blog/5290/

このツールはとても便利で、ブループリントの不具合が発生した際の調査などで役に立ちます。なお、ソースコントロール機能を使ってアセットのバージョン管理をしないとこの機能を使うことができません。

ソースコントロール
https://docs.unrealengine.com/ja/Engine/UI/SourceControl/index.html


また、UE4.23からはWidget Bluperintの差分も見ることができるようになりました。
![image_36.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363889/89bf0e25-fd17-ce4a-1b40-6d89f97d9165.jpeg)
UE4.23リリースノート
https://docs.unrealengine.com/ja/Support/Builds/ReleaseNotes/4_23/index.html

と、ここまではググると出てくるのですが…Level BlueprintのDiffに関する日本語情報が見つからないことに気づいたので記事にしてみます。なお、**Levelの差分ではなくLevel Blueprintの差分**です。Level上のActor配置情報などの差分は見ることができませんのでご注意ください。

# Level Blueprintの差分を見る方法
まずはじめに、Levelアセットの右クリックメニューやHistoryからLevel Blueprintの差分を見ることはできません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363889/acc7ca91-5a5b-56c4-5450-e285a7faf7ef.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363889/4615591d-bdb7-c22c-257b-b10584fcc7b4.png)

通常のBlueprintなどであれば上記の項目から差分を見れますが、Level Blueprintの場合は以下のようなワーニングや
```LoadErrors: Warning: Title_C /Temp/Diff/Temp-4-Rev-3-Title.Title:PersistentLevel.Title_C_1: class /Temp/Diff/Temp-4-Rev-3-Title.Title_C has been deprecated.```

```Unable to load assets to diff. Content may no longer be supported?``` というエラーダイアログがでます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363889/88ba24f6-836e-ceb5-6c5c-a518f7ad9614.png)

そのため、**Level Blueprintの差分を見るためには Level Blueprintの編集エディタにおけるツールバーの File/Diffを選択する必要があります**。この方法であればLevel Blueprintでも他のBPと同様に差分を確認することができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363889/96493685-3a26-790c-9171-19e61534b6ac.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363889/484fdd74-a88e-0b6c-c224-33c7af513121.png)

簡単な内容ですがご参考になれば幸いです。
Postgresのpsqlので良く使うコマンド（仮）

## DB接続

### 接続
```
psql -h ホスト名 -p ポート番号 -U ロール名 -d データベース名
```

### 切断

```
\q
```

## アプリ管理系

## テーブル一覧表示

```
\dt public.*
```

## データファイルの場所を確認

```
SHOW  data_directory;
```
AtomのTeletypeを使ってファイルを共同編集する

# Atomのファイル共同編集機能
VSCodeのLive Shareと同様の機能

1. 共同編集用のリンクを発行
2. そのリンクをslackとかで共有
3. 共同編集者が、そのリンクをクリックして開始

という流れ。

https://teletype.atom.io/

に約1分の動画があるのでそれを見ればすぐに理解できる。

# 前提
Atomインストール済み
GitHubのアカウントを持っている
リンクの共有は本記事ではslackを使用(なんでもいい)

# 準備

以下の手順を共同編集をする人全員で行う。

## Teletypeのインストール

パッケージ > Settings View > Open
で設定を開き、以下のパッケージをインストールする。

![スクリーンショット 2020-10-25 23.39.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/113504/7397e401-5f63-801c-0e30-63019b7aca47.png)

すると、Atomに右下に電波っぽいアイコンができる。

![スクリーンショット_2020-10-29_10_45_12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/113504/3649bf36-623e-1403-a570-da7c2cf681ee.png)

最初にこのアイコンを押すときには、「GitHubアカウントと連携してトークンを発行し、そのトークンを入力してください」って言われるので、登録

![スクリーンショット 2020-10-29 10.25.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/113504/dbd2ff53-f23f-5522-63e0-94cd9fb1c5e0.png)

![スクリーンショット_2020-10-29_10_25_29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/113504/6354d2b3-b07f-7d0d-ffdb-6fed759519c8.png)

すると、アイコンを押した時に、Shareボタンが出るようになる

![スクリーンショット 2020-10-29 10.54.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/113504/f249bd04-fbbf-3900-35c1-6bd3ae1df5e0.png)

# ファイルの共有

まずは共有したいファイルをAtomで開く。

teletypeでshare。しばらくするとリンクが発行される

![スクリーンショット 2020-10-29 10.58.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/113504/86763b2a-0d8f-8104-83ec-8ff696ae13c8.png)

このリンクをslackで共有

あとは共同編集者がそのリンクを開くとAtomが起動して共同編集できる状態になる

# まとめ

機能、UIがシンプルでVSCodeのLive Shareよりもわかりやすい (どっちも簡単だけど)
議事録をGoogle Documentで管理してるけど、markdownで書きたい、履歴をgit管理したいって場合には良い選択肢になりそう！
Visual Studio CodeがRaspberyPiに対応したのでインストールしてみた

Twitterをみていたら、以下のツイートが飛んできたので早速やってみた。
これで、RaspberryPiからでもAzure開発がはかどりますね。

<blockquote class="twitter-tweet"><p lang="en" dir="ltr">ICYMI: VS Code now officially supports <a href="https://twitter.com/Raspberry_Pi?ref_src=twsrc%5Etfw">@Raspberry_Pi</a> too! 🍰<br><br>➡️ Download the Linux ARM and ARM64 builds here: <a href="https://t.co/aMc3pDFkDu">https://t.co/aMc3pDFkDu</a> <a href="https://t.co/gsATu20K4X">pic.twitter.com/gsATu20K4X</a></p>&mdash; Visual Studio Code (@code) <a href="https://twitter.com/code/status/1315371339012739072?ref_src=twsrc%5Etfw">October 11, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

# ダウンロード
以下の公式サイトよりダウンロードします。
https://code.visualstudio.com/#alt-downloads

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/658425/20ccbbd5-25a3-e21d-55c4-40157a35c02e.png)

Rasbianの場合は、ここを選択してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/658425/69073512-33d2-cdd0-9493-9cd10e034dc8.png)

しばらくすると、インストーラーが降ってきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/658425/611ec2e0-ba2a-982e-1e5d-8e904cdc5ff3.png)

# インストール
ダウンロードが完了したら、ファイルを開きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/658425/019976b8-e77f-3d3b-e8d1-67da7571adff.png)

Installを選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/658425/06557fb2-7975-c407-ec33-b03bfda4790f.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/658425/e45c356f-cc63-a426-dcd0-31383e3852ac.png)

認証を求められるので、素直にログインパスワードを入力します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/658425/10ebf5c6-b0c6-6d61-1e26-1d380d9e6c14.png)

インストールが始まります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/658425/1beb80bc-0ef8-c7c8-fa34-d933f3084aca.png)

# 起動してみる
インストールが完了したので早速起動してみましょう
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/658425/7bd1c03d-57f2-d9e1-9e45-6f2d10df9bca.png)

無事起動ができました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/658425/daded4ef-1cf3-e848-02b4-1b9b04336bdd.png)
UEFI とは

## 勉強前イメージ

GRUBの後継機
GRUBよりいろいろ追加された感じ

## 調査

### UEFIの概要

Unified Extensible Firmware Interface の略
ざっくり、マザーボードの不揮発性メモリ(ROM)に組み込まれているもので
PCの電源がはいると一番最初に呼び出されるプログラム。
BIOSの後継機になります。
しかし、UEFIでも一般的にBIOSと呼ばれることが多いです。

### そもそもBIOSってなに？

Basic Input Output System の略
UEFIと同様、マザーボードのROMに組み込まれているプログラム
OSを起動する前にCPUなどの管理や制御を行います	
UEFIと比べて、レガシーBIOSとも呼ばれます

### UEFIの特徴、 BIOSの違い

- 2TB以上のHDDでのOS起動が出来るようになった

BIOSで使用するディスクのパーティション方式のMBR(Master Boot Record)は単一のパーティションの大きさが2TBに制限されている
GPT(GUID Partition Table)方式を使用すると8ZBまで使用できるが、GPT方式はBIOSでは起動できず
UEFIを使用するとGPT方式を使用することが出来る

|  BIOS方式  |  パーティション方式  |
| ---- | ---- |
|  レガシーBISO  |  MBR(Master Boot Record)方式  |
|  UEFI  |  GPT(GUID Partition Table)方式  |


- マウスでの操作が可能になった

レガシーBIOSでは白と青の画面でキーボードのみの操作でした
UEFIを使用するとユーザにとってわかりやすい画面・操作ができるようになりました

- 起動・シャットダウンのスピードが速くなった

UEFIを使用することによってメモリ空間へのアクセス容量が大きくなったので
起動にかかる時間が短縮されます

- セキュリティ機能が追加された

遠隔診断や起動前の確認などが追加された

## 勉強後イメージ

BIOS → UEFI に変わることによってパーティション形式もいろいろ変わるのかー
BIOSのイメージってよくある青と白の画面だけど、すごい進化なんだな....

## 参考

- [UEFIとは？BIOSとの違いとは？](https://pcinformation.info/pcparts/uefi.html)
- [BIOS](https://www.pc-master.jp/mainte/bios.html)
- [UEFI と BIOS の違いとは](https://nettble.com/uefi-bios-chigai.html)
- [Windows 10 BIOSのブートモード(BOOT MODE)~レガシBIOSとUEFIモードの違い](https://www.billionwallet.com/windows10/ueif-bios.html)
- [HDDの制約 2TBの壁](https://www.torutk.com/projects/swe/wiki/HDD%E3%81%AE%E5%88%B6%E7%B4%84_2TB%E3%81%AE%E5%A3%81)
- [UEFIとBIOS：確認の方法と違い完全解説](https://jp.easeus.com/partition-manager/uefi-bios-differences.html#:~:text=UEFI%E3%81%A8BIOS%E3%81%AF%E3%80%81%E3%83%9E%E3%82%B6%E3%83%BC%E3%83%9C%E3%83%BC%E3%83%89,%E3%82%92%E5%AE%9A%E7%BE%A9%E3%81%97%E3%81%A6%E3%81%84%E3%81%BE%E3%81%99%E3%80%82&text=UEFI%E3%81%A8BIOS%E3%81%A8%E3%81%AE%E9%81%95%E3%81%84%E3%81%A8%E3%81%84%E3%81%88%E3%81%B0%E3%80%81%E9%81%95%E3%81%86%E6%96%B9%E6%B3%95,%E3%81%A8%E3%81%84%E3%81%86%E3%81%93%E3%81%A8%E3%81%AB%E3%81%AA%E3%82%8A%E3%81%BE%E3%81%99%E3%80%82)
- [UEFI と BIOS の違いのまとめ](http://tooljp.com/windows/chigai/html/BIOS/UEFI-BIOS-chigai.html)
- [UEFIマザーが高速に起動する仕組みを調べてみる](https://freesoft.tvbok.com/tips/efi_installation/how_uefi_boot_works.html)
3分アジャイル 完成の定義

## 完成の定義

- Doneの定義
- 全員がその意味を理解できること
- PBI（Issue）やインクリメント（スプリントの成果）で定める

---

インクリメントの「完成」の定義が開発組織に存在しない場合は、スクラムチームの開発チームはプロダクトに適した「完成」を定義しなければいけない。

---

## 具体的に

- Issueで「何をするか」
- Issueで「何ができるようになっているか」（完成の定義）

---

## デイリー

- 昨日やったこと
- 今日やること
- 困っていること

---



プロダクトバックログアイテムやインクリメントの「完成」を決めるときには、全員がその「完成」の意味
を理解しておかなければいけない。スクラムチームによってその意味は大きく異なるかもしれない
が、作業の完了についてメンバーが共通の理解を持ち、透明性を確保しなければいけない。これ
は、スクラムチームの『「完成」の定義』と呼ばれ、プロダクトインクリメントの作業が完了したかどうか
の評価に使われる。
この定義は、開発チームがスプリントプランニングでプロダクトバックログアイテムをいくつ選択する
かの指針にもなる。各スプリントの目的は、そのときの「完成」の定義に合ったリリース判断可能な
機能のインクリメントを届けることである。
開発チームは、スプリントごとにプロダクトインクリメントを届ける。インクリメントは実際に利用可能な
ものであり、プロダクトオーナーがすぐにリリースすることもできる。インクリメントの「完成」の定義に
関して、開発組織の慣例・標準・ガイドラインが存在する場合は、スクラムチームは最低でもそれを
守らなければいけない。
インクリメントの「完成」の定義が開発組織に存在しない場合は、スクラムチームの開発チームはプ
ロダクトに適した「完成」を定義しなければいけない。複数のスクラムチームがシステムやプロダクト
のリリース作業をする場合は、すべてのスクラムチームの開発チームが共通の「完成」の定義を使
用しなければいけない。
インクリメントは、それまでのインクリメントに追加されたものであり、すべてが正常に動くように十分
にテストされたものである。
スクラムチームが成熟していくと、「完成」の定義にさらに厳しい品質条件を追加することもある。新
しい定義を作り、それを使用していくと、以前に「完成」したインクリメントにも手を加えなければい
けないことが明らかになる可能性がある。あらゆるプロダクトやシステムは「完成」の定義を備えるべ
きである。それがあらゆる作業の完了基準となる。

https://www.scrumguides.org/docs/scrumguide/v2017/2017-Scrum-Guide-Japanese.pdf
副問い合わせによる問い合わせの解決方法

現在勉強しているオラクルマスターブロンズ（SQL）についてまとめたものです。
自分のアウトプット用なので見やすさなどは期待しないでください。

# 副問い合わせの基本

## 副問い合わせとは

Oracleサーバーでは、SQL文の中に別の問い合わせ（SELECT文）を入れ子にすることができ、この文を**副問い合わせ**という（外側のSQL文もSELECT文の場合**主問い合わせ**という）。

副問い合わせの部分を**（）**で囲んで指定すると、副問い合わせの実行結果をもとに外側のSQL文を実行できるため、通常のSQL文では複数のSQL文に分けて実行しなければならない処理でも、１つのSQL文で実行できるようになる。

通常はSQL文を読みやすくするために、副問い合わせは比較演算子の右辺に記述するが、**左辺に記述しても実行できる**。

## 副問い合わせの色々な使用方法

Oracleサーバーでは、**主問い合わせと副問い合わせのFROM句に異なる表を指定できる**。
また、1つの主問い合わせに**複数の副問い合わせを指定できる**。

副問い合わせはWHERE句だけでなく、**HAVING句やFROM句などでも使用できる**が、**GROUP BY句では使用できない**。

FROM句に副問い合わせを使用すると、実行したSELECT文の結果セットが1つの表のように扱われる。
この方法は、データベースオブジェクトの1つであるビュー（SELECT文に名前を付けOracleデータベースに保存したもの）と似ているため、**インラインビュー**と呼ばれることもある。

## データを1件も戻さない副問い合わせ

副問い合わせの実行結果が０件の場合、主問い合わせには**NULL値が戻される**ため、主問い合わせの実行結果も**０件**になる。
SQL文の構文としては正しいのでエラーにはならないが、データは1件も返されないので注意が必要。

副問い合わせは、別の副問い合わせの中にネストでき、**WHERE句では２５５レベルまで、FROM句では無制限**にネストできる。
なお、一般的にはネストレベルが深くなるとSQL文が分かりにくくなり、またパフォーマンスも悪くなるため、副問い合わせのネストは可能であれば表の結合などに変換することが推奨されている。

# 単一行副問い合わせと複数行副問い合わせ

副問い合わせは、主問い合わせに戻すデータの件数によって以下の2つに分類される。

| 分類 | 説明 |
|:-:|:--|
| **単一行副問い合わせ** | データを1件だけ戻す副問い合わせ。<br>比較演算子には**単一行演算子**（>, =, >=, <, <>, <=）を使用する。 |
| **複数行副問い合わせ** | 複数件のデータを戻す副問い合わせ。<br>比較演算子には**複数行演算子**（IN, ANY, ALL）を使用する。 |

複数行演算子の内容

| 複数行演算子 | 説明 |
|:-:|:--|
| IN | リスト内の**いずれかの値と等しければ**TRUE。 |
| 単一行演算子 + ANY | リスト内の**いずれかの値が条件を満たす**とTRUE。<br>**直前に単一行演算子を使用する**。 |
| 単一行演算子 + ALL | リスト内の**全ての値が条件を満たす**とTRUE。<br>**直前に単一行演算子を使用する**。 |

複数行副問い合わせと比較する比較演算子に**単一行演算子のみを使用するとエラーになる**一方、**複数行演算子は単一行副問い合わせと比較する主問い合わせの条件でも使用できる**。

そのため、副問い合わせが戻すデータの件数を事前に把握できない場合などは、主問い合わせの副問い合わせと比較する条件に、複数行演算子を使用し副問い合わせが戻すデータ件数に依存しない、汎用的なSQL文を記述できる。

## 副問い合わせにおけるIN演算子とNULL値

NOT INは**<>ALL**と同等になるため、戻された値の**すべての値に対してFALSE**にならない限り、主問い合わせの実行結果は０件になる。
しかし、列値とNULL値を比較すると結果もNULL値になるため、副問い合わせからNULL値が戻される場合、実行結果は常に０件になる。

副問い合わせは、1つの列だけを戻す**単一列副問い合わせ**、複数の列を戻す**複数列副問い合わせ**の２種類に分類されることもある。

**EXISTS演算子**は、表に特定の行が存在するか否かによって問い合わせの結果が変化する問い合わせ（**存在チェック**）で、**主問い合わせの各行に対して1回ずつ副問い合わせが実行される**。

**主問い合わせで参照している表の列名を副問い合わせの条件で使用する**と、主問い合わせで取り出される行ごとに副問い合わせを実行する**相関副問い合わせ**と呼ばれる副問い合わせになる。

なお、EXISTSの直前にNOTを追加することで、主問い合わせで取り出した各行で副問い合わせを実行し、条件に合う行がなかった場合にTRUEを返すこともできる。

一般的に、相関副問い合わせは負荷が高くなるため、IN演算子を使用した問い合わせや、FROM句の副問い合わせを使用した結合処理などで書き換えたほうがよい。
開発メモ帳

前端开发
https://ja.taiwebs.com/windows/download-bootstrap-studio-2053.html
http://lowcode.magicalcoder.com/magicalcoder/index-element.html
http://www.geejing.com/
https://grapesjs.com/##
http://www.onemysoft.com/pb/index.html
http://pikock.github.io/bootstrap-magic/app/index.html#!/editor

画图工具
https://app.diagrams.net/
https://cacoo.com/signin

环境构建
https://www.bt.cn/linuxpro.html?invite_code=MV9wcGJuaWI=&sdclkid=A5fi15fGA6DlAJDsbg
https://www.xp.cn/

管理后台
https://www.laraveladmin.cn/open/index

学习网站 
https://laravelacademy.org/

基本設計における成果物一覧と書き方（基本設計書サンプルあり）
https://pm-rasinban.com/bd-write
https://sites.google.com/site/itohshiryo/yao-jian-ding-yi-shusanpuru
ドシロウトが人工音声ポッドキャストメーカーをJSで作ってみた話

フロント側のJavaScriptだけで人工音声（合成音声）のポッドキャストを作成＆MP3変換・結合するツールを作ることにトライした話です。

ニーズ無いと思いますが一応載せときます…

### 1.説明スライド

元々別の場所で使おうと思っていたので、外部にスライドを作ってました。

[人工音声ポッドキャストメーカーを作ってみた](https://tokyopwa.bitbucket.io/slidemake/remarkkokai1.html?slideb=ffffff&slidem=000000&slidet=2&slidef=jinkoslide.txt&slideg=6bbf7c52872f019152d36aab9e524234#1)

### 2.作ったもの

[人工音声ポッドキャストメーカー - https://podcastmaker.bitbucket.io/](https://podcastmaker.bitbucket.io/) 

### 3.終わりに

滑舌が悪い、私には意外と便利です。

以　上
Railsで月間カレンダーを表示する

# はじめに
オリジナルアプリに月間カレンダーを表示するまでを記録しておく。
カレンダー機能はSimpleCalendarやFullCalendarを使う方法がある。
今回は、SimpleCalendarを導入していく。

# 目次

1.Simple Calendarをインストール
2.Simple CalendarのViewの生成
3.カレンダーに予定を追加
4.カレンダーを表示

### 1.Simple Calendarをインストール

`Gemfileに「gem ‘simple_calendar’, ‘~> 2.0’」を追加`
![スクリーンショット 2020-10-29 8.57.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/828524/82dec0cb-33d8-831d-3f9a-d339e55ff61e.png)

`アプリののディレクトリでbundle installを実行 `
<br>

### 2.Simple CalendarのViewを生成する
Gemをインストールしただけではカレンダーを表示させることができないため、viewを生成させる。

`コマンドを実行 `

```
$ rails g simple_calendar:views
```

フォルダ、ファイルが生成される。

`カレンダーにCSSを適用させる `
application.css のファイルに  **\*= require simple_calendar** を追記する
![スクリーンショット 2020-10-29 9.12.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/828524/4063151d-554b-9025-e08d-3239dea7f6c0.png)

### 3.カレンダーに予定を追加

scaffoldを使用してeventというモデルを作成

`コマンドを実行 `

```
$ rails g scaffold Event name start_time:datetime
```

`データベースを変更させるため、マイグレーションを実行 `

```
$ rails db:migrate
```
<br>

### 4.カレンダーを表示
scaffoldを使用したため、index.html.erb のファイル内にコードが記述されているが、編集していく。
eventsフォルダ内の index.html.erb のファイルを書き換え。

```~/views/events/index.html.erb
<%= month_calendar events: @events do |date, events| %>
  <%= date %>

  <% events.each do |event| %>
    <div>
      <%= event.name %>
    </div>
  <% end %>
<% end %>
```

<br>
見た目を修正し、月間カレンダーの表示に成功

![スクリーンショット 2020-10-29 9.45.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/828524/2a6ddd4c-5a17-72c7-efd8-1b1a31f0e576.png)


# 参考
[【公式ドキュメント】simple_calendar](https://github.com/excid3/simple_calendar)
[【rails】simple_calendarを使ってカレンダーつきのブログ機能を作ってみた。](https://qiita.com/isaatsu0131/items/ad1d0a6130fe4fd339d0)
[[Rails] Simple Calendarでカレンダーを表示させよう!](https://www.web-knowledge-info.com/wp/ruby_on_rails12/)
[DB] どのDBを使うべきか？ CAP理論

# はじめに

現在の世の中には数多くのデータを保存できるシステムが出ています。 私が作るシステムはどのDatabaseを使うべきでしょうか？ 拡張性はどの程度持っていくべきか、使用できる費用はどのくらいか、チームの技術熟練度はどうなのか… などなど色々考えなければなりません。 今日は、皆さんのdatabase選択の一つの尺度として、お役に立つCAP理論について話してみたいと思います。

## CAP理論

CAP理論（またはBrewers theorem）とは、Networkで連結された分散データベースシステムは一貫性（Consistency）、可用性（Availability）、and分断耐性（Partition Tolerance）の3つの特性のうち、2つの特性のみを満たすことができ、3つとも満たすことができない理論です。 それでは、各構成要素について見ていくことにしましょう。

## 一貫性(Consistency)

一貫性を持つということは、全てのデータを要求する時の応答として最新の変更されたデータをリターンまたは失敗をリターンするということです。 つまり、すべての読み取りに対してDBノードが常に同じデータを持っていなければならないという意味です。

DB が 2つのインスタンスを維持している場合は、A に要請しても、B に要請しても、同じ値が返されることを意味します。 これは、AでupdateしてもBでupdateした場合、誰かが同期される前にREADをするならすぐに返すのではなく、すべて同期化してREADになる必要があります。

## 可用性(Availability)

可用性は、すべての要請に対して正常に応答するということです。 つまり、クラスターのノードの一部で障害（Downなど）が発生しても、READやWRITEなどの動作は常に成功裏にリターンされなければならないということです。

## 分断耐性(Partition Tolerance)

分断耐性とは、Node間の通信障害が発生しても動作しなければならないということです。 Instacne AとBがあります。 この時、AとBのインスタンス間のネットワークに障害が発生しました。 ユーザーはADBでクエリーをしました。 インスタンス Aは Bの状態を知りませんが、Aだけで動作します。 これを分断耐性といいます。

## 可用性VS分断耐性

可用性と分断耐性の概念が紛らわしいかもしれません。 個人的に確認した際に可用性はノードに障害が発生してDownされた時、分断耐性はノード間の通信が正常に行われない時であることを確認しました。

クライアントの立場で見ると差があります。 前者の場合はclientaとbがある場合も同じ障害が出ないノードを利用しますが、後者の場合はclient別に見ているノードが異なることがあります。

## 実際のDB比較

![CAP DB.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619610/f80b5da4-dec4-6fae-b542-7fd2e6dcd00e.png)

CAP理論に合わせてDBがどのような特性を2つ持っているかを確認した三角形のグラフです。 例を挙げて確認してみましょう。

## MySQL

MySQL は、上の三角形のグラフで CA に属するとされています。 しかし実質的には設定次第でCPまたはCAに属することができます。 デフォルトでは、MySQL をそのまま使用する場合は CA に属することになります。 なぜなら、mainになるmasterノードがあり、そのノードを複製して使うslaveがあるパラダイムを使うからです。 このときMySqlは可用性と一貫性を満足させることができます。

しかし、MySQLはクラスタの設定をサポートします。 クラスタの設定をすると、MySQLはCPを満足するシステムになります。 なぜなら、データを保持するほどのクラスタノードが存在しなければクラスタは終了するからです。

## DynamoDB

DynamoDB は、aws でサポートする keyValue の NoSQL で、AP に属すると言われています。 Dynamoはキー値をhashingし、またこの値をmodして、正しいサーバーに保存しておきます。 そして、全ノードの中の一部のノードに複製しておきます。 そして、データversioningも行います。

DynamoDB には、strongly consistent の設定をすることができます。 この設定をすると、DynamoDBはCPに変わります。 この設定をすると最新のデータをリターンします。 そのため、すべてのノードを探すので可用性は少し落ちることになります。

## まとめ

CAP理論のように完璧なCP、APシステムはなく、ほとんどCPとAPの中間くらいに存在します。 そして上記の例題でも見たように、コンフィギュレーションによって変わる部分でもあります。 また、理論そのものに幾つかの限界点が存在します。 最も問題となるのが、Pに対する明確な定義が足りないことです。 こんな問題点を乗り越えるためにPACELC理論が出たりしました。 は、あくまで参考としてご覧ください。

しかし、CAPの中から2種類を選択できるということは、DataBaseを選択する際の基準になる重要なことと思われます。