OmniAICreator/Qiita-1.07M huggingface dataset:
PDO

PHPを用いてデータベースにアクセスするにはPDOを利用する。
##PDOとは
PDOとは PHP Data Objects の略。
データベースは種類によって、接続方法や操作方法が異なる。
PDOを用いれば、使用しているデータベースが異なっていてもコードの書き方を変える必要はない。

#使用例

```
//データベースへの接続
        try {
            $pdo = new PDO('mysql:host=' . $this->DB_HOST . ';dbname=' . $this->DB_NAME, $this->DB_USER, $this->DB_PASSWORD);
//プリペアドステートメントのエミュレーションを無効にする
            $pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
//例外がスローされるようにする
            $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
//接続を解除する
            $pdo = NULL;
        } catch (PDOException $e) {
            echo "エラーがありました。: " . $e->getMessage() . "<br />";
            die();
        }
```
WSL2をインストールしてUbuntu20を動かす。

もうすぐ公式リリースのためか、公式サイトからインストール方法が削除されていますので、
メモ代わりに載せておきます。

#OSバージョンの確認
[ここに入力して検索]からpowershellを入れて、管理者として実行するを押して、Powershellを起動します。ここから先は、管理者モードのほうが間違いないです。

```
systeminfo | Select-String "^OS"
```
OS バージョン:          10.0.18363 N/A ビルド 18363

Windows Builds 18917 以上が必要です。
ビルドバージョンが全然足りなかったので、インサイダープログラムに参加します。

https://insider.windows.com/en-us/

![2020-05-13 15_37_46-Register to become an Insider _ Windows Insider Program.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104300/cddeba2e-c648-cb11-1c3f-c08895559339.png)

SUBMITを押して参加します。

 Slow か Fast を選択します。

設定の更新とセキュリティの左から Windows Insider Programを開始します。

![2020-05-13 15_40_27-設定.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104300/5029a7ae-5ade-c153-70bb-a9fabf738f5d.png)

再起動後に、ウインドウズアップデートします。


一度入らなくて、再度インストールすると入りました。
OS バージョン:          10.0.19041 N/A ビルド 19041

#WSL1をインストール


```
Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Windows-Subsystem-Linux
```

#WSL2を有効化
```
dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart
dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart
wsl --set-default-version 2
```
終わったら再起動します。

#インストールUbuntu20
 Microsoft Storeを開いてUbuntuで検索します。
今回はUbuntu20をインストールしました。

#WSL2をセットする。

```
wsl --set-version Ubuntu-20.04 2
```
もし、BIOSがと言われたら再起動が必要です。


WSL 2 を実行するには、カーネル コンポーネントの更新が必要です。詳細については https://aka.ms/wsl2kernel を参照してください
すぐ、返答が返ってくるので、おかしいと思ったらカーネル更新パッケージが必要なようです。

#カーネル更新パッケージを当てる。
https://docs.microsoft.com/ja-jp/windows/wsl/wsl2-kernel

#再度実行する。
```
wsl --set-default-version 2
```
返答が返ってくるまでしばらく待ちます。
動いているか気になる場合には、タスクマネージャーで、Vmmemが上に来ているかで確認できるのと、tempファイルの作成で確認できます。

![2020-05-13 18_58_48-Window.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104300/f55297b9-f39c-0299-197a-59a929ac8b4d.png)



WSLバージョン確認

```
wsl -l -v
  NAME            STATE           VERSION
* Ubuntu-20.04    Stopped         2
```

これで、完了です。
あとは、ubuntuを起動すればWSL2で動かせます。


参考：
https://medium.com/@gmusumeci/linux-on-windows-totally-how-to-install-wsl-1-and-wsl-2-307c9dd38a36
【備忘録】APIで受け取ったデータの日本語（パスのファイル名）が文字化けしていた

思い出せそうな気はするけれど、一応残しておく。
###状態
Vue.js から rails のAPIを叩いてファイルパスデータを取得した。
####取得したデータ
```
[
  {
    id: 1,
    role: 'estimate',
    filename: '/uploads/sheet/file/%E6%A1%88%E4%BB%B6%E5%A4%89%E6%95%B0%E3%81%AE%E5%A4%89%E6%8F%9B%E3%83%86%E3%82%B9%E3%83%88.xlsx'
  },
  {
    id: 2,
    role: 'estimate',
    filename: '/uploads/sheet/file/test-excel.xlsx'
  }
]
```
filenameが本当は「テストエクセル.xlsx」なのにAPIから返ってくる値は文字化している。
英語でファイル名を設定している方は正常に返ってくる。

###対応
####Vue template
```
<div v-for="hoge in hoges">
  <div class="filename>{{ hoge.id }}：{{ decodeURI(hoge.filename) }}</div>
</div>
```
decodeURI()を使用してエンコードされた文字列を表示

####出力結果
```
１:/uploads/sheet/file/テストエクセル.xlsx
2:/uploads/sheet/file/test-excel.xlsx
```

###参考
- http://www.openspc2.org/reibun/JavaScript_technique/sample/09_string/008/index.html
- http://js.studio-kingdom.com/javascript/global/decode_uri
rails devise導入からflash設定まで　備忘録

🔳deviseを使ったユーザー機能実装
devise userでモデルを作成する
#
```
rails g devise user
```

マイグレーションファイルを編集する
#
```
class DeviseCreateUsers < ActiveRecord::Migration[5.0]
  def change
    create_table :users do |t|
      ## Database authenticatable
      t.string :name,               null: false
      t.string :email,              null: false, default: ""
      t.string :encrypted_password, null: false, default: ""
    end

    add_index :users, :name, unique: true
```
rails db:migrateする。

モデルにバリデーションを追加する
#
```
class User < ApplicationRecord
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable,  :validatable

  validates :name, presence: true, uniqueness: true

end
```
間違えたらrails db:rollback

application_controoler.rbを編集
#
```
class ApplicationController < ActionController::Base
  protect_from_forgery with: :exception
  before_action :authenticate_user!
  before_action :configure_permitted_parameters, if: :devise_controller?

  protected

  def configure_permitted_parameters
    devise_parameter_sanitizer.permit(:sign_up, keys: [:name])
  end
end
```
簡単に説明すると、サインアップ時に入力されたnameキーの内容の保存を許可

ログインビュー画面を編集（下記は例）
#
```
#account-page.account-page
  .account-page__inner.clearfix
    .account-page__inner--left.account-page__header
      %h2 Edit Account
      %h5 アカウントの編集
      = link_to "ログアウト", '#', class: 'btn'
      = link_to "トップページに戻る", :back, class: 'btn'
    .account-page__inner--right.user-form
      = form_for(current_user) do |f|
        .field
          .field-label
            = f.label :name
          .field-input
            = f.text_field :name, autofocus: true
        .field
          .field-label
            = f.label :email
          .field-input
            = f.email_field :email
        .actions
          = f.submit "Update", class: 'btn'
```
routesを設定
コントローラを編集
#
```
  def edit
  end

  def update
    if current_user.update(user_params)
      redirect_to root_path
    else
      render :edit
    end
  end

  private

  def user_params
    params.require(:user).permit(:name, :email)
  end
```

フラッシュにビューを追加
#app/views/layouts/_notifications.html.haml
```
.notification
  - flash.each do |key, value|
    = content_tag :div, value, class: key
```
#app/views/layouts/application.html.haml
```
  %body
    = render 'layouts/notifications'
    = yield
```
引数と標準入力の違い

引数（特にコマンドライン引数）と標準入力の違いがわかっていなかったのでまとめる。

#引数とは
> 引数とは、プログラム中で関数やメソッド、サブルーチンなどを呼び出すときに渡す値のこと。渡された側はその値に従って処理を行い、結果を返す。OSなどで利用者がコマンドを実行する際に指定するパラメータなどを指すこともある（コマンドライン引数）。
https://www.weblio.jp/content/%E6%A8%99%E6%BA%96%E5%85%A5%E5%8A%9B

引用の通り、引数とはプログラム中で関数やメソッド、サブルーチンなどを呼び出すときに渡す値のこと。
例えばrubyなどでは値を引数としてメソッドに渡すことができる。

コマンドライン引数は、コマンドを実行する際に指定する値。
rubyなどのプログラムを実行するときにコマンドライン引数を指定すると、そのプログラムに対して値を渡すということになる。

#標準入力とは
> 標準入力とは、コンピュータ上で実行されているプログラムが、特に何も指定されていない場合に標準的に利用するデータ入力元。コンピュータの入力装置やOSが提供するデータ入力機能・経路などを指し、多くのシステムではキーボード装置による利用者の文字入力が標準入力に設定されている。システム上では “stdin” の略号で表されることが多い。
http://e-words.jp/w/%E6%A8%99%E6%BA%96%E5%85%A5%E5%8A%9B.html

linuxなどシステムでは、ターミナル上での文字入力が標準で利用されているデータ入力元（標準入力）ということになる。
この標準入力でのデータを渡す相手は、コンピュータ上で実行されているプログラム（linuxなど）である。

またリダイレクトは、指定されたファイルの内容を、標準入力としてプログラムに渡しているということ。

---

######こちらも参考にさせていただきました。

> https://qiita.com/angel_p_57/items/03582181e9f7a69f8168
jQuery基本学習

#簡単なjQuery
私自身の理解度を深めるために書いています。
徐々に改善していきたいと思います。

##基本
###jQueryメソッド
**jQueryオブジェクト**
jQueryオブジェクトは、以下のように$('セレクタ')とするだけで作成できます。

```
$('h1')
```
ここでいうh1はセレクタと呼ばれ、HTML要素をいれる（h1,p,.classなど）

**メソッドを使う**

```
$('h1').hide();
```
$('h1')オブジェクトに対してhide()メソッドを呼び出している。
これでh1要素を隠せる.

「メソッドとは便利な機能のことであり,
いろいろある。これ以降も紹介する。」

**既に表示されている要素を消す例**

```
$('セレクタ').fadeOut(1500);
```
()内に1500を入れている。
これによりアニメーションの速度を決めている。
1.5秒でセレクタが消える。

```
$('セレクタ').slideUP(1500);
```
1.5秒下から上へスライドする。

**表示されていない要素を表示する例**

```
$('セレクタ').fadeIn();
```

```
$('セレクタ').slideDown(1500);
```

###jQueryイベント
```
$('セレクタ').イベント名(function(){
\\イベント発生時に実行したい処理
});
```
**例**

```
$('#hide-text').click(function(){
 $('#text').hide();
});
```
'#hide-text'要素をクリックすると、'#text'要素が隠れる。

###cssメソッド
色を変えたり、隠したりできる。


```
$('#hide-text').click(function(){
 $('#text').css('color','red');
});
```
'#hide-text'要素をクリックすると、'#text'要素の色が赤に変わる。

```
$('#hide-text').click(function(){
 $('#text').css('display','none');
});
```
'#hide-text'要素をクリックすると、'#text'要素が消える。

###HTMLを変更する(text,html)
(text)

 ```
<p>こんにちは</p>
↓(上を下に変える)
<p>こんばんは</p>
```

```
$('p').text('こんばんは');
```
(html)

 ```
<p>こんにちは</p>
↓(上を下に変える)
<p><span>こんばんは</span></p>
```
```
$('p').html('<span>こんばんは</span>');
```

###this構文

```
$('li').click(function(){
 $(this).css('color','red)
});
```
クリックした'li'要素自体の色が赤に変わる

###変数の利用
変数使用前

```
$('div').css('color','red');
$('div').html('jQuery');
$('div').fadeOut();
```
$('div')三回も使っている。
めんどくさい

変数使用後

```
var $div=$('div');

$(div).css('color','red');
$(div).html('jQuery');
$(div).fadeOut();
```
今回の例ではあまり変わっていないが、、

###子要素の取得
`find('a')`全ての子要素の取得
`children('a')`一階層下の要素だけ取得

###hoverイベント
以前はclickイベントを紹介した
今回をhoverイベント

```
$('#hide-text').hover(function(){
 $('#text').css('color','red');
});
```
'#hide-text'要素にカーソルを重ねると'#text'要素の色が赤に変わる。
クラウド初心者のAWS入門(第3回)

# 第3回 パブリックサブネット構築(1／2)
今回は、VPCの中にパブリックサブネットを構築していきます。
パブリックサブネットは、インターネット網に接続するための論理ネットワークとして構築していきます。

## 1.今回の構築箇所

|![システム構成図_第3回目.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/626270/6c7b9ff1-c346-d790-0e2b-1e947c1530fa.png)
|:-:|

## 2.サブネットの作成
「VPCダッシュボード」の左ペインより、「サブネットの作成」を選択します。

|![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/626270/d88e082e-fe3d-377c-12e4-9d1c028d3eae.png)
|:-:|

サブネットの設定を行っていきます。

|![2_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/626270/63e48c41-c805-b002-53dd-9921aeff50b3.png)
|:-:|

  * 「名前タグ」　->　「Public_Subnet」を入力（任意）
  * 「VPC」　->　「VPC_AREA」を選択(前回作成したやつです)
  * 「IPv4 CIDRブロック」　->　「10.0.1.0/24」を入力

設定項目にある「アベイラビリティゾーン」、今回は「指定なし」です。

複数のサブネットを異なるアベイラビリティゾーンに配備する事で、冗長性を持たせたい時に指定するようです。
アベイラビリティゾーン(=AZ)は、リージョンをさらに小分けにした単位です。

* 東京リージョン
  - AZ①(ap-northeast-1a)　－＞　サブネット192.168.0.0/24
  - AZ②(ap-northeast-1c)　－＞　サブネット192.168.1.0/24

上のようにAZを分ける事で、AZ①がダウンした際に、AZ②側で運用を継続する事が可能となリます。
また、AZだけでなくリージョンを分ける事で耐障害性を更に向上させることも可能です。(お金と相談)

今回は以上となります。

インターネットへ接続する設定を行っていないため、次回設定をしていきたいと思います。
ありがとうございました～。

# 参考文献
[Amazon Web Services 基礎からのネットワーク&サーバー構築](https://shop.nikkeibp.co.jp/front/commodity/0000/231260/)

# 後書き
2020年6月14日に記載内容を修正しております。
PDFKitを使ってみたら便利だった話

# PDFKitとは
簡単にいうと・・・iOS11から追加されたPDFを簡単に実装できるもの！
細かい使い方は参考のhttps://dev.classmethod.jp/articles/ios-11-pdfkit/
で詳細に記載されていてとってもわかりやすいのでぜひ見てみてください！

# PDFKitの便利な機能
- サムネイルが簡単に表示できる！
- 何もしなくても拡大/縮小ができる！
- 複数ページの表示が容易、スワイプの方向も指定できる！

拡大や縮小、その他ユーザーの動作を受け付けたくない時は

```swift:test.swift
   self.pdfView.isUserInteractionEnabled = false
```

で設定できるので、1ページのPDFをimageのように表示したい時も安心です！

# PDFKitで難しいなと感じたこと(ただの勉強不足です、ご存知の方教えてください！)
- 拡大/縮小率がなんとなく上手くいかない。(縮小率を1にしてもpdfView.autoScales = trueのサイズまで戻せない)
- サムネイルの挙動がたまにおかしい
- サムネイルを最後のページで選択した状態で別のPDFを開くと挙動がおかしくなる

**でもやっぱりPDFの表示が少しのコーディングでできるので便利！！**

# 参考
https://dev.classmethod.jp/articles/ios-11-pdfkit/
ソートアルゴリズムを一言でチートシート

自分的に実装時にコードを思い浮かべやすいような表現を心がけました（無印良品ぽい言い回し）。

[けんちょんさんの網羅的記事](https://qiita.com/drken/items/44c60118ab3703f7727f)を読みながら書きました。それぞれのソートアルゴリズムの原理と実装を知っている人向けです。

## O(N^2)

### 挿入ソート

左から順に1枚抜いて、それより左にあってかつ抜いたものより小さいものを右にずらすと、未ソート部の左端が空くのでそこに入れる。

### 選択ソート

線形探索して最小値と未ソート部の左端を交換していく。

### バブルソート

右端から2つずつ比較して入れ替えを繰り返すと未ソート部の最小値が泡のように左端に移動する。

## O(N log N)

### マージソート

要素数が1になるまで再帰的に2分割して、つなげるときに左右から1個ずつ取り出して小さい方を突っ込む。

### クイックソート

Pivot を選んで線形探索、pivot 未満を見つけたら左端に詰めて（交換して）いくと、pivot 未満と以上に分かれるので、pivot をふさわしい場所に入れてやり、あとは再帰的にやる。

### ヒープソート

配列にヒープを埋め込んで、最大値を右端に飛ばしてヒープのサイズを小さくしていく。
個別のツイートの前後のツイートを表示するブックマークレット

## これは何？
ブラウザでツイッターを使っています。
少し古いツイートを読んでいる時に、その前後のツイートを読みたいということがよくあります。
Twitterの検索コマンドを入力すればいいのですが、その手間すら省きたい、楽したいと思いませんか？
そういう時に使うと簡単にIDと期間を指定できるという、ものぐさな自分にぴったしなブックマークレットです。

## 使い方
特定のツイートが表示されている時に実行すると、日数を聞かれるので数字を入力します。
キャンセルした場合は当日（と前日）で検索した結果が表示されます。

```tw_let.js
(
    () => {
        const path = location.href.split('/');

        if (path[2].endsWith('twitter.com')) {
            const status = path[5].split('?')[0];// no referer
            const time = Math.floor(status/4194304) + 1288834974657;// convert rule
            const date = new Date(time);

            // number of days
            let start = prompt('How many days?', '3');
            let end = start;
            if (isNaN(start) || start < 1 || start === null || start === '') {
                start = 1;
                end = 0;
            }

            // since
            date.setDate(date.getDate() - start);
            const since = date.toISOString().slice(0, 10);
            
            // until
            date.setDate(date.getDate() - (-start - end));
            const until = date.toISOString().slice(0, 10);

            // url
            location.href = 'https://twitter.com/search?f=live&q=from:@' + path[3] + 
                            '%20since:' + since + 
                            '%20until:' + until;
        }
    }
)();
```

ネット上の JavaScript Minifier を使って短縮したものがこちらです。

```tw_let.min.js
(()=>{const t=location.href.split("/");if(t[2].endsWith("twitter.com")){const e=t[5].split("?")[0],o=Math.floor(e/4194304)+1288834974657,i=new Date(o);let s=prompt("How many days?","3"),n=s;(isNaN(s)||s<1||null===s||""===s)&&(s=1,n=0),i.setDate(i.getDate()-s);const a=i.toISOString().slice(0,10);i.setDate(i.getDate()-(-s-n));const c=i.toISOString().slice(0,10);location.href="https://twitter.com/search?f=live&q=from:@"+t[3]+"%20since:"+a+"%20until:"+c}})();
```

## まとめ
次の記事を参考にしました。感謝です。
https://qiita.com/riocampos/items/e5544325211976f2cfc1

以上、初投稿でした。
お疲れ様でした。
Excel VBA で、変更されたセルを色づけしてわかりやすくしてみた

#Excel VBA で、変更されたセルを色づけしてわかりやすくしてみた
シートのデータが多いとき、どこか１つセルを修正したかを探すのが大変なときがあります。

よくあるのが、Excelデータを更新して、メールで送り返してもらうときに、変更された箇所を、ハイライトでわざわざ色付けするのは手間がいる。

かなり簡易的だけど、セルを変更すると、セルに色を付け、変更したセルがわかりやすいようにしてみた。
![変更箇所.xls  [互換モード] - Excel 2020_05_13 18_17_41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634486/430ca0d4-46d2-9c7b-bd2a-3c70f4f2d920.png)
###VBAマクロ
```vb:
Dim refValue

Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
    refValue = Range(Target.Address).Value
End Sub

Private Sub Worksheet_Change(ByVal Target As Range)
    If refValue <> Range(Target.Address).Value Then
        With Range(Target.Address).Interior
            .Pattern = xlSolid
            .PatternColorIndex = xlAutomatic
            .Color = 65535
            .TintAndShade = 0
            .PatternTintAndShade = 0
        End With
    End If
End Sub
```
bash, cshどちらからでもsourceできるスクリプトの書き方

死んでも同じようなコードをふたつ書きたくないめんどくさがりな人向け。ネタです。

# 条件分岐
ifの文法が異なっていて使えないので、`test`と`&&`、`||`をつないで条件分岐する。

```
test 条件式 && 真の場合 || 偽の場合
```

# 変数の代入、出力
bashスタイルで代入してみて、エラーになったらcshスタイルで代入する。出力の仕方は同じ。

```
x=hoge >& /dev/null || set x=hoge
echo $x
```

# 環境変数の代入、出力
同じような感じ。cshでは変数と環境変数で名前空間が別のようだ。

```
export x=hoge >& /dev/null || setenv x hoge
printenv x
```

# bash / csh判定
psコマンドでプロセスIDからコマンド名を調べる。これができれば後はbash用のスクリプトとcsh用のスクリプトを別に用意してここでsourceすれば良い。

```
ps -p $$ -o comm= | grep csh  > /dev/null && echo これはcsh
ps -p $$ -o comm= | grep bash > /dev/null && echo これはbash
```

# ヘルプを表示
bashの場合、sourceされたスクリプトから抜けるにはreturnを使う。cshにreturnはなく、エラーになるのでexitで抜ける。

```
test "$1" = "-h" && \
  echo "Usage: source hoge [-h]" && \
  echo "  " && \
  return >& /dev/null
test "$1" = "-h" && exit
```
GCSのオブジェクトストレージ管理者でバケットが参照できない

# 事象
Rails_admin 上から carriewaveを経由してGCSにアップロードする際に以下のエラーが発生しました。

```
forbidden: hogehoge@hogehoge.iam.gserviceaccount.com(opens in new tab) does not have storage.buckets.get access to the Google Cloud Storage bucket.
```

今までは、オブジェクトストレージ管理者権限のサービスアカウントで問題なく動作していたのですが、同じようにサービスアカウントを作成してもうまくいきませんでした。

# 原因
どこかのタイミングで、オブジェクトストレージの権限周りが変わったっぽいです。
https://cloud.google.com/storage/docs/access-control/iam-roles?hl=ja#legacy-roles

権限周りのドキュメントを見ていると **以前の権限**(legacy-roles) とあるので、おそらくどこかのタイミングで `オブジェクトストレージ管理者` では `storage.buckets` 周りの権限はセットでつかなくなったみたいですね。


なので、上記のサービスアカウントに `ストレージバケット閲覧者` の権限をつけてあげることで動作ができるようになりました。
※実際に権限を付けるときは、 必要以上に権限を付けないように注意していただければと思います。


# 最後に
GCPの設定周りの変更って、既存サービスに影響ないように作ってくれることが多いので(それはかなりありがたいことなのだが)、新しく構築するときに今までと同じように作ってうまく行かないことが多々ありますよね。

コピペじゃなくて、ちゃんと根本を理解して環境構築することの重要性を再認識しました。
秘密鍵と自己署名証明書をopensslのコマンド1行で作成する方法

ウェブで検索してもなかなか見つからないので、備忘録として書いておく。

以下のコマンドで、パスフレーズなし秘密鍵と自己署名証明書を一度に作れる。引数の値は適宜変えること。

```
openssl req -newkey rsa:4096 -nodes -keyout example.key -x509 -days 3650 -subj "/C=JP/L=City/O=Organization" -out example.crt
```
HTMLのストレージ機能への配列の入出力でハマったこと

sessionStorageとlocalStorageに配列を保存するときにエラーがでて嵌ったので、同じような人がいれば参考までに。

## そもそも
詳細は下記をご参考ください。

sessionStorageをつかってみる
https://qiita.com/uralogical/items/ade858ccfa164d164a3b

## 失敗パターン
今回もVue.jsベースで話していきますが、他フレームワークでも同じです。

```vuejs:page1.vue
<template>
  <div>
    <div>
      <button @click="test">テスト</button>
      <ul>
        <li v-for="item in list" v-bind:key="item.id">
          {{ item.id }}/{{ item.name }} 
        </li>
      </ul>
    </div>
  </div>
</template>

<script>
export default {
    data() {
        return {
            list:[]
        }
    },
    methods: {
        test: function() {
            const data = [
                { id: 1, name: 'test1'},
                { id: 2, name: 'test2'},
                { id: 3, name: 'test3'}
            ]
            window.sessionStorage.setItem("data", data)
            this.list = window.sessionStorage.getItem("data")
        }
    }
}
</script>
```

## なぜ？
sessionStorageの格納情報を確認したところ、どうやら正しく情報が格納されていない様子。。。

## 対応方法
JSON配列に変換し使います。

```vuejs:page1.vue
<template>
  <div>
    <div>
      <button @click="test">テスト</button>
      <ul>
        <li v-for="item in list" v-bind:key="item.id">
          {{ item.id }}/{{ item.name }} 
        </li>
      </ul>
    </div>
  </div>
</template>

<script>
export default {
    data() {
        return {
            list:[]
        }
    },
    methods: {
        test: function() {
            const data = [
                { id: 1, name: 'test1'},
                { id: 2, name: 'test2'},
                { id: 3, name: 'test3'}
            ]
            window.sessionStorage.setItem("data", JSON.stringify(data))
            this.list = JSON.parse(window.sessionStorage.getItem("data"))
        }
    }
}
</script>
```

うまくいきました！
django-request で DRF のAPIリクエスト履歴を保存してみた

DRFで[django-request](https://django-request.readthedocs.io/en/latest/contents.html)を使ってみた話です

## できること

- APIリクエスト履歴の保存
    - 保存できる項目
        - ステータスコード
        - メソッド
        - パス
        - リクエスト日時
        - SSLかどうか
        - ajax通信かどうか
        - ipアドレス(**問題あり、後述**)
        - リファラ
        - ユーザーエージェント
        - 言語
        - ユーザーID
- django-adminで見れて、GoogleAnalyticsのようにグラフィカルに表示もできる
    - ただしあまり複雑なフィルターは無いようなので、その場合はクエリで対応する必要がありそう

## できないこと

- POSTパラメータなどリクエストbodyの内容の履歴
    - セキュリティ的な観点もあるので、POSTパラメータの保存はリスキーではありますね

## 手順

1 pip等でインストール

```
pip install django-request
```

2 `INSTALLED_APPS`に`request`追加

3 `MIDDLEWARE`に`request.middleware.RequestMiddleware`追加

4 マイグレーション実行

```
manage.py migrate
```

以上で、`request_request`テーブルにAPIリクエストが保存されるようになります

## カスタマイズ

### 除外パス

django-adminのリクエストまで保存されてしまうので除外設定した方がいいと思います
自分はこんな感じにしました（healthはヘルスチェック用のパス）

```python
REQUEST_IGNORE_PATHS = (
    r'^admin/', r'^docs/', r'^health$', r'\.ico$', r'^static/'
)
```

### IPアドレスについて

IPアドレスは`REMOTE_ADDR`を使ってるため、ロードバランサがあると正しく取れません
苦肉の策でこんな感じにしました（もっといいやり方があれば教えて欲しい）

```python
from request.middleware import RequestMiddleware

class XRequestMiddleware(RequestMiddleware):
    def process_response(self, request, response):
        # django-requestの中でREMOTE_ADDRをIPとして保存してしまっているので、無理やりだけどHTTP_X_FORWARDED_FORに変更する
        http_x_forwarded_for_ip = request.META.get('HTTP_X_FORWARDED_FOR')
        remote_addr_ip = request.META.get('REMOTE_ADDR')
        if http_x_forwarded_for_ip:
            request.META['REMOTE_ADDR'] = http_x_forwarded_for_ip

        response = super().process_response(request, response)

        if http_x_forwarded_for_ip:
            request.META['REMOTE_ADDR'] = remote_addr_ip

        return response
```

ちなみに`HTTP_X_FORWARDED_FOR`はIPアドレスがカンマ区切りで入ってくることがあるので、`REQUEST_IGNORE_IP`を使うなら以下のようにしたほうがいいですね

```python
http_x_forwarded_for_ip = request.META.get('HTTP_X_FORWARDED_FOR').split(',')[0]
```

## 所感

簡単に組み込めますし、データドリブンには必須じゃないでしょうか
あとは、データが溜まった時のバックアップが課題ですね
しかし、IPアドレスのところはアップデートして欲しいな・・・
bit全探索(python)

#bit全探索の考え方からソースコードまで

bit全探索は二択の選択の中の選択肢を全部列挙する為のアルゴリズムである。
例
みかん、りんご、ぶどうの3個の中から買い物する可能性の組み合わせは何通り有るか。
買う、買わないの二択が何通り有るかの組み合わせを求める問題である。

##考え方
###①何通りあるかを考える。
2択が3種類あるので2の3乗で8通りある。

```python
print(2**3)
print(1<<3) #1を2進数で考えて左に３シフトさせると３乗した事と同じになる

#8
#8
```

###②組み合わせを二進数で考える。
0は二進数で`000`なので何も買わない。
1は二進数で`001`なので3個目のぶどうの位置のフラグが立っているのでぶどうだけ買う。
2は二進数で`010`なので2個目のりんごの位置のフラグが立っているのでぶどうだけ買う。
3は二進数で`011`なので2個目のりんごの位置のフラグと3個目のぶどうの位置のフラグが立っているのでりんごとぶどうを買う。

以下同文

[![Screenshot from Gyazo](https://gyazo.com/5bf3a027ea5ab984e4453d63dd2c9ba7/raw)](https://gyazo.com/5bf3a027ea5ab984e4453d63dd2c9ba7)

###③3個選択肢があるので3回ループを回し、何bit目が1になっているか(フラグがたつ)を確認する。
i`bit`の位置のフラグを確認する為のコードは`if (i>>j)&1:`でわかる。

####例１：
i=1(001)
j=0

1を右に0回シフトさせると1番右にある数字は何か。またそれが１ならtureを返すという意味である。

####例2：
i=2(010)
j=1

2を右に1回シフトさせると1番右にある数字は何か。またそれが１ならtureを返すという意味である。


```python
for i in range(3):
    for j in range(3):
        if (i>>j)&1: #ここで何bit目のフラグが立っているかを確認する。
            print(str('i')+'の時は'+str('j')+'番目のフラグが立っているよ!')



# 1の時は0番目のフラグが立っているよ!
# 2の時は1番目のフラグが立っているよ!
# 3の時は0番目のフラグが立っているよ!
# 3の時は1番目のフラグが立っているよ!
# 4の時は2番目のフラグが立っているよ!
# 5の時は0番目のフラグが立っているよ!
# 5の時は2番目のフラグが立っているよ!
# 6の時は1番目のフラグが立っているよ!
# 6の時は2番目のフラグが立っているよ!
# 7の時は0番目のフラグが立っているよ!
# 7の時は1番目のフラグが立っているよ!
# 7の時は2番目のフラグが立っているよ!

```
###④フラグが立っている時処理の中でみかん、りんご、ぶどうをそれぞれ出力すれば終わり。

##atcoderでの実際の例題の答え(python)
167回ABCテスト-C問題
https://atcoder.jp/contests/abc167/tasks/abc167_c

```python
import numpy as np

n,m,x = map(int,input().split())
a = [list(map(int,input().split())) for i in range(n)]
c = [a[i].pop(0) for i in range(n)]
ans = []
for s in range(1<<n):
    cost = 0
    mi = np.array([0]*m)
    for i in range(n):
        if (s>>i)&1:
            cost += c[i]
            mi += np.array(a[i])

    if np.all(mi >= x):
        ans.append(cost)
if ans:
    print(min(ans))
else:
    print('-1')
作成したTwilio Autopilotのbotを別のアカウントに移動する方法

Twilio Autopilotで作ったbotを別のアカウントに移動する方法を紹介します。

[Twilio AutopilotのCLIのリファレンス](https://www.twilio.com/docs/autopilot/twilio-autopilot-cli)を見てると、あれ？ExportあるのにImportのタイプにGoogle AssistantとAlexしかなくね？という点に気づくと思います。

本記事では、そう思った方向けにTwilio Autopilotの移し方についてご紹介いたします。
※公式のやり方ではないので、そのうちできなくなるかもしれません。

## 事前準備
**注意事項：node 14系でやるとexportする際に以下エラーが表示されました。**

```
ERROR: TypeError [ERR_INVALID_ARG_TYPE]: The "path" argument must be of type string. Received an instance of NodeError
```

**なので本記事ではnode v12.16.3を利用しています。**

### Twilio CLIのインストール
```
# npmを使ってインストール
$ npm install -g twilio-cli

or

# homebrewを使ってインストール
$ brew tap twilio/brew && brew install twilio
```

### Autopilot pluginのインストール
```
$ twilio plugins:install @dabblelab/plugin-autopilot
```

### Twilioにログインする
以下コマンドを用いてTwilioにログインします。

```
# twilio cli v2.0.1では、Account SID、AuthToken、Friendry nameの順番で聞かれます。
$ twilio login
```

## botを移行する
以下手順でbotを移行します。
### botをexportする
以下コマンドでbotをexportします。

```
# exportしたいbotを聞かれるので、上下キーでbotを選択してエンターキーを押します。
$ twilio autopilot:export
```

exportが成功すると `bot名.json` ファイルが生成されます。

### uniqueNameを移動先のbot名に変更する
**事前に、移動先のプロジェクトにbotを作っておきます。**

`export`コマンドでexportした、`bot名.json`を開き、`uniqueName`を移動先のuniqueNameに変更します。

```
{
    "friendlyName" : "Manage appointment scheduling",
    "logQueries" : true,
    "uniqueName" : "move_test", // ここを変更する
    "defaults" : {
        "defaults" : {
            "assistant_initiation" : "task://greeting",
            "fallback" : "task://fallback",
            "collect" : {
                "validate_on_failure" : "task://collect_fallback"
            }
        }
    },
・・・・
}
```

### アカウントを変更する
twilio cliが移動先プロジェクトにlogin済みの場合は移動先のプロジェクトに移動します。

```
twilio profiles:use 'friendry name'
```

移動先のプロジェクトにログインできていない場合は、新しくログインします。

```
# twilio cli v2.0.1では、Account SID、AuthToken、Friendry nameの順番で聞かれます。
$ twilio login
```

使用したいプロジェクトにtwilio cliが設定されているか確認します。

```
$ twilio profiles:list
```

使用したいプロジェクトの`ACTIVE`が`true`になっていたらOKです。

### 移動先のbotへ反映させる
最後に移動先のbotへ内容を反映させます。

```
$ twilio autopilot:update -s=bot名.json
```

以上で移行完了です。

### まとめ
Twilio Autopilotってまだ日本では使えないんじゃないの？と疑問に思う方もいらっしゃるかもしれませんが音声系は残念ながらまだ日本語には対応していませんが、テキストベースだったら日本語でも利用可能です。
是非お試しください！
Coursera Machine Learningのまとめ(ロジスティック回帰編)

#はじめに
前回の[線形回帰編](https://qiita.com/KugeKuge/items/de18ebd2e658d7c56ea0)に引き続き、ロジスティック回帰の勉強内容をまとめる。
とりあえず動画見ただけでAndrew先生は要所要所で褒めてくれて嬉しい。

#ロジスティック回帰とは
回帰という名前が付いてるけど分類のアルゴリズム。

2つの値が存在する場合に、それぞれに属する確率を求めて、よりもっともらしい方を分類結果として返してくれる。

例えば、明日の天気が晴れか晴れじゃないか、という二値分類を考えると、

* 晴れの確率　　　　=　0.7 (70%)
* 晴れじゃない確率　=　0.3 (30%)

みたいに合計100%となる確率を返してきて、より可能性が高い方に分類する。
上記の例の場合は晴れに分類される。

#シグモイド関数
線形回帰で使った$h_\theta(x)$は、$h_\theta(x) = \theta^T x$だった。
これだと、xが大きくなったり小さくなったりすると、値が$\infty$や$-\infty$に発散してしまう。

これを0～1の確率に押し込めてしまう魔法の関数がシグモイド関数。

$$\sigma(x) = \frac{1}{1+e^{-x}}$$

グラフにするとこんな感じ、美しい…
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/633548/da81c701-93f0-c615-2783-c5f07dc09c0a.png)

#分類問題への適用
ロジスティック回帰では、シグモイド関数に元の$\theta^Tx$を代入して、$h_\theta(x)$を以下の通り定義する。

$$h_\theta(x) = \frac{1}{1+e^{-\theta^Tx}}$$

$h_\theta(x)$が求めているのは$y=1$の確率で、$y=1$の確率と$y=0$の確率の合計は1になる。

```math
h_\theta(x) = P(y=1|x;\theta) = 1 - P(y=0|x;\theta)\\
$P(y=0|x;\theta) + P(y=1|x;\theta) = 1
```

分類結果は以下のように考える。

```math
h_θ(x)≥0.5→y=1 \\
h_θ(x)<0.5→y=0
```

#損失関数
ロジスティック回帰の損失関数は以下のようになる。

```math
J(θ)=-\frac{1}{m}\sum_{i=1}^{m}\big[y^{(i)}log(h_θ(x^{(i)})) + (1-y^{(i)})log(1-h_θ(x^{(i)})) \big]\\
```

ちょっと調べたところによると、これは交差エントロピー誤差と呼ばれていて、負の対数尤度関数とのこと。
確率論もいずれちゃんと勉強しないといけないですね…

これをベクトル化して書くと、以下のようになる。
シンプルになった。

```math
\begin{align}
&h=\sigma(Xθ) \\
&J(θ)=\frac{1}{m}\big(-y^Tlog(h)-(1-y)^Tlog(1-h)\big)
\end{align}
```

#最適化
線形回帰と同じく、損失関数の微分を最急降下法で$θ$を更新していく。

```math
\begin{align}
&Repeat\bigl\{ \\
&θ_j \leftarrow θ_j- α \frac{1}{m}\sum_{i=1}^{m}(h_θ(x^{(i)})-y^{(i)})x_j^{(i)}\\
&\bigr\}
\end{align}
```

ベクトル化して書くと以下のようになる。

```math
\theta \leftarrow \theta - \alpha\frac{1}{m}X^T(\sigma(X\theta) - y) \\
```

#複数クラスの分類
ロジスティック回帰は二値分類を行うことができる。
複数の値に分類したい場合は、各値について、その値かそうじゃないかの確率を求めて、一番確率が高かったものを出力する。

```math
\begin{align}
&y\in\{0,1,...,n\}\\
&h_θ^{(0)}(x)=P(y=0|x;θ)\\
&h_θ^{(1)}(x)=P(y=1|x;θ)\\
&…\\
&h_θ^{(n)}(x)=P(y=n|x;θ)\\
&prediction=\underset{i}{\textrm{max}}(h_θ^{(i)}(x))
\end{align}
```

#正則化
線形回帰と同じく正則化によって過学習を抑制できる。

```math
\begin{align}
&\theta_0 \leftarrow \theta_0 - \alpha\frac{1}{m}\sum_{i=1}^{m}(h_θ(x^{(i)})-y^{(i)})x_0^{(i)}\\
&\theta_j \leftarrow \theta_j - \alpha\Big[\big(\frac{1}{m}\sum_{i=1}^{m}(h_θ(x^{(i)})-y^{(i)})x_j^{(i)}\big) + \frac{\lambda}{m}\theta_j \Big]　　j \in \{1,2,...,n\}
\end{align}
```

#まとめ
ロジスティック回帰は、シグモイド関数を使って確率を回帰して、より尤もらしい値に分類するもの、と理解した。
確かに中でやっていることは回帰っぽい。

途中の微分や確率論はすっ飛ばしているので、もっと数学勉強しないと…
PMP試験に出てくるthree dimension of complexityを覚えよう！

# three dimension of complexityとは
プロジェクトの複雑度に関する３つの要素のこと

## PMBOKのどこに出てくるのか
PMBOKガイドの`68ページ`の`3.5.4 Integration And Complexity`に出てくるぞ！

## ３つの複雑度

- System behavior (システム動作)
    - コンポーネント、システム間の依存関係
- Human behavior (人間動向)
    - 個人、グループ間のやりとり
- Ambiguity (曖昧さ) 
    - 突発的な問題の発生
    - 理解不足や混乱

----

よかったよかった
Tableau：ヘックスタイルマップでヒートマップを地図上に粗く表現する

今回は、<b>「ヘックスタイル(六角形)マップ」</b>という表現方法をご紹介します。

「ヘックスタイルマップ」は緯度経度情報を含む都道府県・州などの統計データを面積を考慮しない粗い形で表現するのに適しています。

↓これはヘックスタイルマップ
![10.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548159/51e5f898-e1ca-cf2d-159c-45dd3310de75.jpeg)
#使用するデータセット

今回は以下のサイトのデータを参考に作っていきます。

SuperDataScience『Tableau Custom Chart series』(https://www.superdatascience.com/pages/yt-tableau-custom-charts-series)

内容は「アメリカの年の推定人口」となってます。

#普通にマッピングしてみる

最初は特に何もカスタマイズせず可視化していきます。
![1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548159/588d4df9-c7f4-42f8-1a3d-c8953fd8622c.jpeg)
ジオメトリ情報を含むので、Tableau上ではマークに挿入すると自動でマッピングされます。
ですが、<b>点の数が多すぎて塗りつぶされてしまっています。</b>

試しに指標の１つ、「Estimated Population(推定人口)」でカラーリングしても粒度が細かすぎて見辛いです。
![2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548159/7f576b73-ba9d-2e6b-6da8-4686a9f593f3.jpeg)

#ヘックスタイルマップで粗く表現する

今回のマッピングですが、正確な位置情報はなくてもいい情報なので粗くマッピングしていきます。

##①使用する関数

ヘックスタイルマップを作るにあたり、<b>HEXBINX・HEXBINY関数</b>を使用します。
殆ど出番のない関数です。

><b>①HEXBINX(number,number)</b>
X、Y座標を最も近い六角形のビンのX座標にマッピング。ビンのサイズは1。
<b>②HEXBINY(number,number)</b>
X、Y座標を最も近い六角形のビンのY座標にマッピング。ビンのサイズは1。

「最も近い六角形のビンにマッピング」というのは下記のようなイメージです。
![3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548159/03f1a2d2-b27a-572e-a173-23b7d834489a.jpeg)
青の散在する点が六角形のビン、黒点に収束される感じです

##②計算フィールドを作成

今回は以下のように計算フィールドを作成します
<b>①HEXBINX(number,number)</b>
![4.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548159/e0166445-57ab-ec10-13eb-fc74332c0e58.jpeg)
<b>②HEXBINY(number,number)</b>
![5.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548159/7db9f874-c030-d113-d31a-8c00ab0314de.jpeg)

ここでは「粒度調整」というパラメータを使用しています。見栄えに応じて後でマッピングの粒度を調節します。
![6.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548159/9ffa76f0-6df2-c349-5c15-8558389be6aa.jpeg)
##③シートの挿入
素材ができたらシートに挿入していきます。

<b>HEBINXとHEBINYはどちらもディメンションです。</b>
また「六角形」は形状ではデフォルトに含まれていないので新しく追加しましょう。(六角形のアイコンはhttps://cdnl.tblsft.com/sites/default/files/blog/inverted_hex.png)

こんな感じになりました。
![7.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548159/3a4f136e-ebda-a383-536c-c99d792cc5ee.jpeg)

##④パラメーターを微調整
②で作成したマップのパラメーターは1でした。ついでにそれ以外の数値の時はどうなるか検証してみます。

「パラメーターが2の時」
![8.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548159/486bf70a-771d-1739-1ca7-1ac5a5909bbc.jpeg)
「パラメーターが3の時」
![9.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548159/b96e9c9e-2633-4f4c-b8ee-bc4a11390bda.jpeg)
パラメーターの数値を大きくするほど、細かくなります。
パラメーターが3の時は見づらい気がします。好みにもよりますが、パラメーターは1〜2ぐらいが良さそうです。

↓パラメーターを1にし、色でマッピングするとこんな感じ
![10.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548159/672fd871-fb38-7425-6407-49f069bd5554.jpeg)

粗くしている分、最初のより見やすくなっていますね。

西海岸と、ニューヨーク付近が人口が多めというのが相対的にわかります。
地理的な正確さが必要な時は適しませんが、そうでない場合に有効なヘックスタイルマップでした。

Tableau Publicの方に、ワークブックがあるので中身を見たい方はhttps://public.tableau.com/profile/.14716601#!/vizhome/HexbinChart_15544799993880/sheet0
aws-sdk-goでS3のオブジェクトを取得しようとして「SignatureDoesNotMatch」と言われたら

# signed urlを使っているわけでもないのにSignatureDoesNotMatchと言われる

ACLを設定していない、signed urlも使っていないバケットに対して接続してオブジェクトの取得をするコードを実装したら、 `SignatureDoesNotMatch: The request signature we calculated does not match the signature you provided. Check your key and signing method.` と言われてしまいました。
同じようなエラーにハマった人の手助けになれば幸いです。

## TL;DR

* バケット名に `/` を含めないようにする。

## コード

```golang:コードは適当ですが雰囲気はこんな感じです.go
func hogehoge() error {
	config := aws.Config{
		Region: aws.String(os.Getenv("REGION")),
	}
	sess := session.New(&config)
	d := s3manager.NewDownloader(sess)
	n, err := d.Download(file, &s3.GetObjectInput{
		Bucket: aws.String("hogehoge/"), //!!!!!!!
		Key:    aws.String("piyopiyo/year=2020/month=04/fugafuga.gz"),
	})
	if err != nil {
		return err //エラーになる
	}
	fmt.Printf("downloaded %d bytes", n)
}
```

## エラーになる場合と、ならない場合

コードに書いてある通りですが、バケット名の後ろに間違えて `/` をつけてしまっています。
このバケット名から `/` を取り除けばすべての場合において正しく動作します。
ただし、 `/` をつけていると、少し不思議な動作をしました。

### エラーにならない

* バケットに対して`ListObjects` を実行し、オブジェクトのリストを取得できる。
* 上記で取得したオブジェクトのメタ（keyとか）を参照できる。
* **keyに`=`を含まないS3オブジェクトをDLできる。**

### エラーになる

* **keyに`=`を含むS3オブジェクトがDLできない。**

直接的な原因はわかりませんでしたが、aws-sdk-go内部の実装を見る限りS3オブジェクトをDLする際はGETリクエストを発行しているようですので、パラメータのURLencode時に `=`が悪さしているのではないかなと考えました。
https://github.com/aws/aws-sdk-go/issues/3110
また、こちらのissueで言及されているように、「バケット名として `/` や `=` は使用できない。」というS3自体のルールがあります。
aws-sdk-goでもその前提に則って実装した結果、今回のように「DLできたり、できなかったりする」不思議な挙動が起きたのではないかと考えられます。:thinking:
[Rails]vendor/bundleオプションを用いたbundle installでデプロイ環境用のgemがinstallされなかったエラーの解消

# はじめに
・この記事はデプロイ作業についてある程度の知識があること、サイトを一度デプロイしていることが前提です。

#概要
デプロイ環境にあるポートフォリオサイトに次のような作業を行ったところ
「gemfileにmysql2を加えろ」という趣旨のエラーが発生し、ポートフォリオサイトが表示されなくなった。

### ローカル環境での作業
 1. ローカル環境でポートフォリオ用サイトのGemfileに変更を加える
 2. ローカル環境でgit push

### デプロイ環境での作業
1. [ec2-user@**-**-**-**<アプリ名>]$ git pull
2. [ec2-user@**-**-**-**<アプリ名>]$ bundle install --path vendor/bundle --without test development　を実行
3. [ec2-user@**-**-**-**<アプリ名>]$ rails s -e production実行時に下記のエラーが発生


```ruby:発生したエラー
Error loading the 'mysql2' Active Record adapter. Missing a gem it depends on? mysql2 is not part of the bundle. Add it to your Gemfile. (LoadError)
```
# 環境
Rails 5.2.4.2
ruby 2.5.7
Bundler 2.1.4
github
RDS
EC2
nginx
puma

#対応検討

###インストール済のgemを確認

下記のコマンドでインストールされているgemをアルファベット順に確認することができる

```
[ec2-user@**-**-**-**<アプリ名>]$ git list
```

```
*** LOCAL GEMS ***

（略）
mini_portile2 (2.4.0)
minitest (5.10.3)
net-telnet (0.1.1)　
（略）
```
**本番環境にmysql2がインストールされていないことがわかった。**
(アルファベット順のため、"mysql2"は"minitest"と"net-telnet"の間にあるh図）

###ローカル環境のGemfileの確認

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

ruby '2.5.7'

(中略）

group :production do
  gem 'mysql2'
end
```
**gem 'mysql2'の記載を確認した**

そのため、group :production内のデプロイ環境用のgemが何らかの原因でインストールされていないと思われた。

下記の記事によるとbundlerは、**「一度--path vendor/bundleオプションをつけてbundle install を行えば、次回からvendor/bundle 配下に読み込むよう設定が加わる」**とのことであり、
.bundle/configファイルに想定外の設定がされていると仮定して対応を行った。

>https://haayaaa.hatenablog.com/entry/2019/01/21/160504


#対応（成功例）
###.bundle/configファイルを確認

次のコマンドで.bundle/configファイルを確認できる

```
[ec2-user@**-**-**-**<アプリ名>]$ cat .bundle/config
```
```ruby:.bundle/config
BUNDLE_PATH: "vendor/bundle"
BUNDLE_DEPLOYMENT: "true"
BUNDLE_WITHOUT: "test:development:production"
```

`BUNDLE_WITHOUT: "test:development:production"`
上記コードのためにgemのインストールが阻害されていたため、これを削除することとした。

###.bundle/configファイルの編集
**vi コマンドを用いて修正する**

※viの操作については次の記事を参照
>https://qiita.com/Utree/items/a1539e77fe7705a020f8


次のコマンドを入力して編集をする

```
[ec2-user@**-**-**-**<アプリ名>]$　vi .bundle/config
```
```ruby:.bundle/config
BUNDLE_PATH: "vendor/bundle"
BUNDLE_DEPLOYMENT: "true"
（記述を削除）
```
記述を削除した後は、escキー、:wqを順に入力して保存する。

次のコマンドを実行

```
[ec2-user@**-**-**-**<アプリ名>]$ bundle install --path vendor/bundle --without test development
```

```
[ec2-user@**-**-**-**<アプリ名>]$ rails s -e production
```

**無事にポートフォリオサイトは復旧できた**

##参考：失敗例（直接bundle install)
####成功した方法の前に、デプロイ環境にgem mysql2を直接インストールする方法を試したが失敗した。

```
[ec2-user@**-**-**-**<アプリ名>]$ gem install mysql2
```
```
[ec2-user@**-**-**-**<アプリ名>]$ git list
```

```
*** LOCAL GEMS ***

（略）
mini_portile2 (2.4.0)
minitest (5.10.3)
mysql2 (0.5.3)
net-telnet (0.1.1)
（略）
```
環境内にインストール自体は可能だった

```
[ec2-user@**-**-**-**<アプリ名>]$ rails s -e production
```

```ruby:発生したエラー
Error loading the 'mysql2' Active Record adapter. Missing a gem it depends on? mysql2 is not part of the bundle. Add it to your Gemfile. (LoadError)
```
**--path vendor/bundleオプション**を使用している場合、この方法ではエラーは解消されなかった。
Herokuのデプロイ中にPrecompiling assets failed.のエラーが出る

#バグ
Herokuのデプロイ中にバグ起きてデプロイできない。

1、$ git push heroku master
2、Precompiling assets failed.と出る

#結論
＄　RAILS_ENV=production bundle exec rake assets:precompile

yarnが入ってなかった。のでインストールして解決。
画像分析サイトを20分で立ち上げる

IBM Cloud を使って、画像分析サイトを瞬時に立ち上げる方法をお伝えします。
デプロイまで15分前後でだいたいあげられてます。

この内容を実行するには、IBM Cloudアカウントが必要になります。
ライトアカウント（クレカ登録不要、期限なし）で実行可能です。
[→登録はこちら](<img width="289" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245231/0506de7a-79aa-59a3-fb3e-443c75cd04fa.png">)


**この手順で作成されるのは、次のサービスです。**
- Cloud Foundry Application Node.js
- Service(Continuous Delivery, Visual Recognition)
- Cloud Application(Visual Recognition)
- Toolchain 
*ライトアカウントの方は、メモリの制限にかからないか事前に確認してください

[IBM Cloud Login](<img width="289" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245231/0506de7a-79aa-59a3-fb3e-443c75cd04fa.png">)
##Watson Visual Recognition Basicを立ち上げる
1. 「カタログ」メニューから「ソフトウエア」「Webとアプリケーション」にチェックで対象のサービスを絞り込み、「Watson Visual Recognition Basic」をクリックします。
<img width="383" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245231/a5b7f543-2729-63fb-c6d7-74ce8091b162.png">

2. 画面下部の「はじめに」をクリック（または「作成」タブを選択で同じ画面に遷移します)
- アプリ名を書き換え（初期値でもOK、Uniqueにする必要があります)
<img width="410" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245231/84cdb910-4a2d-cf3a-02fb-5fe9ecc67316.png">
- 「作成」をクリックします。
- アプリが起動します。
<img width="548" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245231/a592c834-8993-0966-4d80-8e67a516a76a.png">

##アプリのデプロイ環境を構築立ち上げます
1. 「デプロイメント自動化」のパネルから「アプリのデプロイ」をクリックします。
<img width="708" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245231/9c9ec018-e389-3301-f0ac-cd195d183a1d.png">
- デプロイメント自動化のターゲットに「IBM Cloud Foundry」を選択します。
- IBM Cloud API キーの「新規」作成をします。
- 他の入力項目を確認し（初期値可）「次へ」をクリックします。
- 次ページでDevOps Toolchainの項目を確認し(初期値可)「作成」をクリックします。
- コードの生成を待ちます(BUILD・DEPLOY共に緑になれば作成ずみ)
<img width="385" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245231/af1c6645-3e4d-f0c8-8ee6-7a76ea205528.png">
- Delivery pipeline が表示されたら「名前」のリンクをクリックします。
<img width="624" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245231/0aa752a1-ee12-70fe-19aa-7154f9c852b3.png">
- DEPLOY パネルの最終実行の結果の「コンソールの表示」をクリックします。
<img width="709" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245231/b670adc1-1b1e-ec91-e5b4-6c52e48413da.png">
- （3）で指定した名前のアプリケーションが表示されるので**実行中**であることを確認し、「アプリURLにアクセス」をクリックします。

##作成したサイトで画像分析を試しましょう
<img width="635" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245231/e4baca2e-9652-d734-fa16-347259e25015.png">
- 左画面下部、青枠の画像を切り替えると、右画面の結果が変わります。
- 左画面下部、ピンク枠をクリックすると、画像のアップロードができ、結果が試せます。
<img width="1411" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245231/91b4d09f-87da-f6cc-29c3-ef5075e9667c.png">
こんな感じ！！
で、どうするのかって突っ込まれそうですが、ここからどうするかはまた改めて考えます。
【Solidity】estimateGas のブレによるガス不足エラー

**Solidity** にて 処理の分岐に **block.number** を使っていたのですが 、この値の変化により不定な **[Out of gas]** エラーがでていたので、忘れないよう内容をメモしておきます。

問題のあるコードは下記となります。

```solidity
// 前回のアクセス時間（※ログボのインターバル）
mapping (address => uint32) private _blockForNext;

// ログボの待ち時間（※テスト用に０）
uint32 constant private BLOCK_INTERVAL = 0;  // 24*60*4;

// ログボの受取り
function loginBonus() public{
    uint32 requestBlock = uint32( block.number );  // 現在時刻
 
    // 前回のアクセスから一定時間経過していない場合はエラー
    require( requestBlock >= _blockForNext[msg.sender], "block error" );

    // 次回の受取り時間の設定
    _blockForNext[msg.sender] = requestBlock + BLOCK_INTERVAL;

   // TODO:ログインボーナスの付与 
}
```

内容は、一度アクセスしたら一定時間アクセスできないログインボーナス的なもので、各プレイヤーのログボ受取り可能時間を **_blockForNext** としてストレージ変数に持たせています。

で、テスト用に待ち時間 **BLOCK_INTERVAL** の値を **０** にして動作確認していたところ、不定にガス不足のエラーが起こりました。この時、下記のように、**estimateGas** の値にブレがあり、見積もりが安くなる際にエラーとなっていました。

> // 正常終了する際の見積もり
> Gas limit: 273765
> 
> // ガス不足エラーが起こる際の見積もり
> Gas limit: 269565

色々試した結果、 **requestBlock** と **_blockForNext** が同じ値の場合に、見積もりが安くなっていました。どうやら、**requestBlock** が **_blockForNext** と同じ値の場合、**EVM** がストレージへの余分な書き込みをスキップすることで、ガスの消費を軽減してくれているようです。

で、お安い見積もりでトランザクションを発行するのですが、トランザクションがブロックに取り込まれるまでに **block.number** の値は見積もり時よりも進んでしまいます。これにより、実際の処理では  **requestBlock** と **_blockForNext** の値が不一致となってしまい、ストレージへの書き込みが発生してガス不足が起きていたようです。

対応としては、コントラクト内で **block.number** は使わず、呼び出し側でブロックを取得して関数の引数にすることとで、状況による変化が起こらないように修正しました。

```solidity
// ログボの取得
function loginBonus( uint32 requestBlock ) public{ 
    // 前回のアクセス時から一定時間経過していない場合はエラー
    require( requestBlock >= _blockForNext[msg.sender], "block error" );

    // 次回アクセス可能ブロックの設定
    _blockForNext[msg.sender] = requestBlock + BLOCK_INTERVAL;

   // TODO:ログインボーナスの付与 
}
```

不定なガス不足が起こる場合は **estimateGas** の値にブレがないかを確かめ、**block.number** のような流動的な値が悪さをしていないか調べてみるのがよいかもしれません。
Rubyの「？」「！」の整理メモ

表題の件です。

「！」は破壊的メソッドにする。
「？」は真偽値を返すメソッドにする。

という感じです。

例を↓

まずは「！」破壊的メソッド。

```ruby
#ファイルへの記述
name="taguchi"
puts name
puts name.upcase
puts name
puts name.upcase!
puts name
```

この場合のコンソールでの出力は

```ruby
ec2-user:~/environment/ruby_lessons $  ruby hello.rb
taguchi
TAGUCHI
taguchi
TAGUCHI
TAGUCHI
```

となります。

つづいて「？」真偽値を返すメソッド。

```ruby
#ファイルへの記述
name="taguchi"
puts name
puts name.empty?
puts name.include?("g")
```

この場合のコンソールでの出力は

```ruby
ec2-user:~/environment/ruby_lessons $ ruby hello.rb
taguchi
false
true
```

となります。


以上、メモです。
React NativeはWindows Appを対応しました。Mac Appはじきに対応するようです。

React NativeはWindows Appを対応しました。Mac Appはじきに対応するようです。

現在は Windows 10 SDKをサポートしており、時期にMacOS 10.12 SDKもサポートするようです。
新規プロジェクトはもちろん、既存プロジェクト(ReactNativeで実装しているiOS/Androidプロジェクト、Windows 10/MacOS 10.12プロジェクト)に簡単に導入できるそうです。

詳細はこちら↓
https://microsoft.github.io/react-native-windows/
200513学習記録：CSSを使ったレイアウト①基本 大きさと位置（block,inline）

TechAcademy losson3 10.webページのレイアウト

ボックスモデルのレイアウトとは何をするのか？
①HTML要素自体の大きさの変更
②HTML要素の位置の変更

**レイアウトに使うhtmlタグがデフォルトでblockか、inlineかを認識する。**

block→縦に並ぶ
　div , li ,p , h , section

inline→横に並ぶ
　span , a , img

**縦並び、横並びを変える**

blockデフォルトのタグを横並びにする
(inline-blockだとパディングも決められる)

```
li{
  display:inline-block;
}
```

inlineデフォルトのタグを縦並びにする

```
a{
  display:block;
}
```



**HTML要素の大きさや位置の変更**

divなどのhtml要素に、クラス指定したCSSで変更する。

▽HTML要素自体の大きさ は、 content area の witdh, height のプロパティを変更することで大きさを変更できるようになりました。
▽HTML要素の位置 は、 margin プロパティ（外側の余白）の値を変更することで変更することができるようになりました。
▽padding は内側の余白で、つまりHTML要素の内部の border と content area の距離に影響します。そのため border （境界線）や background （背景）が付与されたときに初めて padding の効果が現れます。

例えば次のようなプロパティで大きさの変更をする。
このボックスの縦は、（padding50px × 2）＋（height200px）＝300px

.box {
    margin: 50px;
    border: 5px solid pink;
    padding: 50px;
    background-color: skyblue;
    width:200px;
    height:200px;
}

※marginの相殺
２つのボックスが縦に並んでいる場合
上のボックスの下部マージンが50px、下のボックスの上部マージンが30pxとすると
大きいほうだけが適用されるためmarginは50pxとなる。
PHP配列表示

#はじめに
こちらではphpで配列の表示について書いていきたいと思います。
受け取ったものに対し内容が何であるかを把握するのはその後の処理において必要になると思います。

#環境
CentOS
PHP 7.3.17

#内容
具体的な内容・・・・と言っても基本的な内容ですが・・・
主に使うのは

var_dump
print_r
var_export

この三種類を使っていこうかとおもいます。
と言ってもやることはシンプルなんですけどね・・・

```html:index.html
<!DOCTYPE html>
<html lang="ja">
  <head> 
   <title>index</title>
  </head>
  <form action = "test.php" method = "post">
    <input type = "text" name ="comment"><br> 
    <select name="select">
     <option value="option1">option1</option>
     <option value="option2">option2</option>
     <option value="option3">option3</option>
    </select>
    <input type="submit" value="送信">
  </form>
</html>
```

```php:test.php
<?php
//入力チェック
  if(empty($_POST["comment"])){
    echo "未入力です。";
  }else{
    $comment=$_POST["comment"];
  }
  echo $comment;
  echo "<br>";
//入力チェック
  if(empty($_POST["select"])){
    echo "未入力です。";
  }else{
    $select=$_POST["select"];
  }
  echo $select; 
  echo "<br>"; 

//配列格納
  $arrey = [
		$comment,
		$select
	   ];
  echo "var_dump →　";  
  var_dump($arrey);
  echo"<br>";
  echo"print_r →　";
  print_r($arrey);
  echo"<br>";
  echo"var_ecport →　";
  var_export($arrey);
?>

```

実行結果
<img width="1186" alt="スクリーンショット 2020-05-13 17.32.48.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/608443/03eef069-180e-3534-b174-44a36b58d0fd.png">

<img width="1185" alt="スクリーンショット 2020-05-13 17.32.01.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/608443/68fc4af2-5b5c-5739-a001-dc5b547b3f72.png">

#まとめ
いかがだったでしょうか
それぞれ表示される内容が違うと思います。
その時々で使い分けていきたいですね。
Surface Book 2 が充電されてない！を解決した話

## SurfaceBook がシャットダウンした！

Surface、いいですよね！
ペンも合わせて使うといい感じです。
SurfacePro4 を使っていたのですが、昨年 SurfaceBook2 に変更して1年経ちます。

あまりにも使い心地が良かったので、[SurfaceDock](https://www.amazon.co.jp/%E3%83%9E%E3%82%A4%E3%82%AF%E3%83%AD%E3%82%BD%E3%83%95%E3%83%88-PD9-00009-Surface-%E3%83%89%E3%83%83%E3%82%AF/dp/B016ZYWG56)も合わせて快適に使う毎日でした。

ある日、Surfaceくんがいきなりシャットダウンし、電池がゼロな状態なのが判明しました。
いろんな方法を試しましたが、筆者が解決できた手段があったので、備忘的な記事です。

## 途方に暮れる・・・ことはなかった

ググってみると・・・難しいことなんてありませんでした。

ただ、**電源ユニットをリセットするだけ**！

### 復旧手順
1. Surfaceからコネクタを外す
2. ドックにつながってる電源ケーブル、USBを全部外す
3. **10秒待つ**
4. Surfaceとドックに電源を接続する
5. USB、LANケーブル等接続する

参考にしたサイト：[Surface の電源アダプターや充電ケーブルが動作しない場合の対処方法](https://support.microsoft.com/ja-jp/help/4484763/surface-fix-issues-with-your-power-supply)

- USBも外します！
- ユニットを電源系から外して10秒待ちます！

これらが重要だったようだ。
Surfaceくんは他にも電源系？トラブルが起きることがあるので電源つかない！とかいうことでお困りの方はこちらも参考にされると良いでしょう。

[Surface を強制的にシャットダウンし、再起動する](https://support.microsoft.com/ja-jp/help/4036280/surface-force-a-shut-down-and-restart-your-surface)

## コロナ大変だけど頑張ろう

今回、自宅勤務になり、会社ではWiFi接続していますが、自宅ではWiFi速度が遅く、作業にならんなーというところでDockのLAN接続ができない＆充電できない問題で四苦八苦していました。
新型コロナに負けず、楽しくリモートワーク生活していくため、ストレスはなるべく受けない環境を作っておきたいものですね。
Rubyからjavascript ~基本文法~

#Chromeのコンソールを使おう
Chromeのコンソールを用いると、どのページでもirbのような対話形式でJavaScriptのコマンドを実行することができます。

コンソールは、**command + option + J (Windowsの場合はCtrl + Shift + J )**
で立ち上げることができます。

#Hello worldと出力しよう
rubyでは以下のように**putsメソッド**を使いました。

```ruby
puts "Hello world"
```
javascriptでは以下のように記述します。

```javascript
console.log("Hello world");
```

Rubyと比べてみると、メソッドの違いはもちろんのことですが末尾に**セミコロン**が付いていることがわかります。JavaScriptでは、一つの処理の終わりにセミコロンをつける慣習があります。（実際なくても問題なく動く場合がほとんどですが）

またRubyでは**引数の括弧**を省略することができますが、Javascriptでは省略することができません

#変数を使ってみよう
Rubyでは以下のように変数を定義することができました。

```ruby
x = 1 # 定義
x = 5 # 代入
name = "onda"
array = [1, 2, "a"]
```
Javascriptでは以下のようになります。

```javascript
var x = 1;
x = 5;
var name = "shizuka";
var array = [1, 2, "a"];
```
変数を定義するときは、**var**をつける必要があります。varを省略して変数宣言をした場合、関数内での宣言であっても、その変数はグローバル変数になってしまいます。混乱を防ぐためにも変数を定義する際は**var**をつけるのが良い。

#関数を使ってみよう
Rubyでは以下のように関数を定義することができました。

```ruby
def 関数名(引数)
  処理内容
end
```
Javascriptでは以下のようになります。

```javascript
function 関数名(引数) {
  処理内容
}
```
関数の呼び出しも含めて見てみましょう。Rubyは以下のようです。

```ruby
def greeting(name)
  puts 'Hello ' + name
end
name = 'onda'
greeting(name)
```
Javascriptでは以下のようになります

```javascript
function greeting(name) {
  console.log('Hello ' + name);
}
var name = 'onda';
greeting(name);
```
関数の定義と呼び出しに関して、２つの間に大きな差はないことがわかります。
ただ、Rubyの場合では引数がない時にはメソッド名だけで定義と呼び出しができていたのに対し、JavaScriptでは、引数が無い場合も、以下のように空の括弧をつける必要があります。

```javascript
function printHello() {
  console.log("Hello");
}
printHello();
```
#オブジェクトを使ってみよう
Javascriptには**オブジェクト**という、キーと値がセットになったものがあります。
これはRubyでいう、**ハッシュ**と似ています。

Rubyでは以下のようにしてハッシュの定義と呼び出しを行います。

```ruby
hash = {key1: "value1"}
hash[:key1] = "value1"
```
javascriptでは以下のようになります。

```javascript
var hash = {key1: "value1"};
hash.key1 = "value1";
```
オブジェクトに関して、キーと値のセットのことをプロパティと呼びます。今回ではkey1といったキーがプロパティ名、それに対応するvalue1がプロパティの値、hashがオブジェクトになっています。また、"value1"を指す言葉として、「hashのkey1プロパティ」という呼び方をすることが多いです。

オブジェクトのプロパティにアクセスする時は、ピリオドを使って
**(オブジェクト).(プロパティ名)**とします。

また、JavascriptのオブジェクトがRubyのハッシュと異なる点は、**プロパティに関数（メソッド）を持つことができる**という点です。つまり数値や文字列と同様にプロパティに関数を持つことができ、引数として関数を渡すこともできるのです。

値の取得同様に、(オブジェクト).(メソッド名)で呼び出すことが出来ます。例えば、console.logは、consoleオブジェクトのlogプロパティのメソッドを呼び出していることを表します。
Thymeleaf @RestController, @Controllerの違い




# 概要
Thymeleafを扱う初心者が @Controller と ＠RestController の挙動の違いを知りたかったので，調べました．

#環境
- springboot 
- IntellJ CE
- Lombok

###はじめに
sprintboot を起動し，次のURLにアクセスします．
http://localhost:8080/〇〇

###  @ Controller


以下のようなコードで
http://localhost:8080/list
にアクセスすると，
main/resources/templates/list_display.html
のhtmlが画面に表示されます．（”list_display”という文字列がそのまま表示されるわけではない）


```java
@Controller
public class AppController {
    @GetMapping("list")
    public String from_list(){
        return "list_display";
    }
}
```

###  @ RestController

一方，以下のようなcontrollerのファイルを作成し， @RestControllerを用いて，
http://localhost:8080/person
にアクセスすると，


```java
@RestController
public class SampleController {
    @GetMapping("person")
    public Person person() {
        return new Person(123, "hogehoge", 40);
    }
}
```

以下の文字列がそのまま返されます．
{"id":123,"name":"hogehoge","age":40}



（以下のようなPerson クラスを別に作成しておいてください）

```java

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@NoArgsConstructor
@AllArgsConstructor
@Data
public class Person {
    Integer id;
    String name;
    Integer age;
}
```


###まとめ
- resource/ 内のhtmlファイルを画面に表示したいときは，@RestController
- 単に文字列を出力させたいときは，@Controller

を使いましょう.

- 簡単ですが，自分の備忘録のためにまとめました．
バリデーションについて

バリデーションとはデータベースにデータを登録する際に一定の制約をかけることを言います




バリデーションを設ける際はモデルに記載します

```hoge.rb
validates :カラム名, バリデーションの種類
```

以下にバリデーションの種類の一例を載せておきます。


#種類

空のデータはダメ(マイグレーションファイルにも記載）

```
validates :カラム名1, presence: true
```
```
 def change
    create_table :hoges do |t|
      t.カラム型 :カラム名1, null: falsenull: false
      t.カラム型 :カラム名2
      　　
      

      t.timestamps
    end
  end
```

既にデータベース上に存在しているデータ（重複しているデータ）はダメ

```
validates :カラム名, uniqueness: true
```

数値のみのデータでなければダメ

```
validates :カラム名, numericality: true
```

値の大小や長さの指定

```
validates :カラム名, length: { minimum: ~}          ←　　~文字以上
validates :カラム名, length: { maximum: ~}          ←　　~文字以下
```