OmniAICreator/Qiita-1.07M huggingface dataset:
エンジニアがデザインを正確に確認する方法

# 背景
自分はiOSのエンジニアである。

UI周りの実装を行うときには、デザイナーからデザインデータをもらい、デザインツールでMarginやFontなどを確認しながらデザイン通りに実装を行う。実装が終わったら自分で再度デザインが間違っていないかを確認して、最後にデザイナーに確認してもらう。

しかし、デザイナーの確認のときに高い確率で「元のデザインとここが違うよ〜」ってデザイナーから指摘を受けて修正を行うことが多い。

例えば、「LabelのTextのlign-heightが違う」や「アイコンのbaseLineが少しずれている」などである。デザインデータは細かく見ているつもりだが、見落としてしまうことがある。。。

何度もデザイン確認を行っていたら、実装とデザイナーの時間が勿体ない。

## 書くこと
**エンジニアがデザインを正確に確認する方法について**

# 方法
**デザインデータと実装したスクリーンショットを合わせて、違いがないかを確認する!!**

## 例
赤色の枠のCellを実装する。（[元データ - figmaresources](https://www.figmaresources.com/resources/figma-free-app-ui-kit)）
<img width="361" alt="スクリーンショット 2020-03-02 22.16.14.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/209811/fef9fdb1-ae4a-1863-c39b-4a4b000562af.png">

### ① まずはデザインデータを参考に実装
実装!💪💪💪
デザインツールにcssやnativeのコードが表示されるので、参考に実装。

### ② 実装したら、スクリーンショットを取る
<img width="290" alt="スクリーンショット 2020-03-02 22.29.52.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/209811/6ab786a9-5d96-f95e-73fc-0b8d2da28437.png">
完璧っぽい。。。


### ③ 実際に重ねてみる！！
![test5.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/209811/d86834e9-3d2e-5860-5aef-8290dac5264f.gif)
デザインデータの上にスクリーンショットを置いて、スクリーンショットのalphaを100から0に徐々に変化させている。
**この段階で、デザイナーに確認してもらわなくても実装がデザインと違うことが一目瞭然!!**

`実際に実装を間違えている箇所`
<img width="858" alt="スクリーンショット 2020-03-02 22.41.03.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/209811/7ab8f891-2ece-0705-7f00-2641ce8b8e18.png">
大体、ずれている箇所のデザインデータを見れば間違いがすぐにわかるはず。。。

わからなければ、デザイナーに相談しましょう。優しく教えてくれます。


## Tips
- デザインデータを違うworkspaceにコピーして行う。（エンジニアはデザインデータへのWrite権限は基本ないと思うので、別のworkspaceにデザインデータをコピーしないと、スクリーンショットと重ねることはできないと思います。）
- スクリーンショットを貼ったら、スクリーンショットのwidthをデザインデータのwidhtni揃える。（デザインデータのwidhtは一律決まっていると思うので、すぐにその値へ！）
- 画像やボタンなどwidhtとheightが決まっているものを目安に合わせると、合わせやすい。
- alphaを徐々に変化させていくと、違いに気付きやすい。
- Labelの確認時にデザインデータとスクリーンショットで文言が違うときは、デザインデータの文言をスクリーンショットの文言に変更する。


# 感想
この方法に変えたら、デザインの実装ミスが一気になくなりました。あと、ばっちりデザインが合ったときは、すごい気持ちが良いです！笑
たまにデザインデータのミス（Fontが違うなど）に、エンジニアが気づくことがあります。

一番よかったのは、デザイナーとの確認のときに**デザインデータとの違いについて**話すのではなく、**実際のシステムに実際のデータをデザインに適応したときにデザインが問題ないかについて**話し合うようになり、より良いUIを作れるようになりました！！
基本情報技術者試験の勉強計画　3月

## 基本情報技術者試験の勉強計画　3月
### 目標
・表計算とアルゴリズムをできるようにする
・午前問題の復習
・毎日行う
### 結果
・表計算は完璧とまではいかないがある程度はできるようになった、アルゴリズムがまだできるようにはならなかった
・午前問題は忘れているところもあったが、ある程度は復習できた
・毎日は旅行もあって難しかったが、できる限りは行った
## 振り返り
### keep
・少ない時間でも復習の時間にあてれた
・過去問道場をほぼ毎日開くようにした
### problem
・苦手としているところをなかなか手を付けられなかった
・時間がある日を睡眠時間にあててしまった
### try
・苦手なところを1日1問でも解くようにする
・時間がある日はカフェなどに行って寝ないようにして勉強の時間にあてる
## 週次報告
### [第20週(3/2週)](https://qiita.com/poohsan/items/fe49d1343728b8f48dea)
### [第21週(3/9週)](https://qiita.com/poohsan/items/e380c13a5a2a2dbdff12)
### [第22週(3/16週)](https://qiita.com/poohsan/items/e5ffedc53cbdecd1d0e0)
### [第23週(3/23週)](https://qiita.com/poohsan/items/e6a8d76b98e5b2aceffd)
AtCoder ABC157 D - Friend Suggestions

https://atcoder.jp/contests/abc157/tasks/abc157_d

# 概要
割愛しつつ。

まず、ある人に注目した時、SNS全体の人は以下のいずれかに分類される。
- a. 自分自身
- b. 友達
- c. 友達の友達のつながりで到達できる人
- d. 他人(友達経由で到達できない人)
※ブロックしうるのはc, dの人だけである。(条件より友達をブロックして/されていることはない)

各人について、ブロックしていないcの人数を述べよ。

# アプローチ
友達はいわばグループであるので、求めたい人数というのは、$自分の所属するグループの人数 - a - b - cのうちブロックしている人数$である。

まず、グループの分類はDFSで求められる。あるノードを取り、そのノードをそのグループ番号とする。そのノードからひたすらノードを追っていき、その番号を付与していくとともに数を数える。たどり終わったら、その番号のノード数を記録する。これをすべてのノードの探索が終わるまで繰り返す。
あるグループのノード数は$a+b+c$である。


ノード間の辺を読み取る際に、各ノードが辺を何本持つかをカウントしておく。これは$b$に他ならない。

これを、グループのノード数から引くことで、$c$を得られた。しかし、これにはブロックされている関係を含む。このため、ブロックされている関係x,yにおいて以下の処理を行う。`xとyが同じグループに所属しているなら、x,yのそれぞれの友達候補数を-1する`。
※尚、万一「友達関係であってもブロック」できてしまうと上記で数を減らしすぎてしまうが、今回は制約上、これは発生しない

# コード

```Python
from collections import deque
n, m, k =map(int, input().split())

directcount = [0] * n # node_iが直接接続しているノードの数
visited = [-1]  * n # nodeの色,
colorcount = [-1] * n # 各色が何個のノードを持つか
# グラフの初期化
g = []
for _ in range(n):
    g.append(deque(list()))

# グラフの生成
for i in range(m):
    a, b = map(int, input().split())
    a, b = a - 1, b - 1 # 1origin -> 0 origin
    g[a].append(b)
    g[b].append(a)
    # 直接接続されているノードの数
    directcount[a] += 1
    directcount[b] += 1

# dfs 連結したグラフごとにそのグラフの最初に探索したnodeの色に染める
q = deque(list()) #探索キュー
for i in range(n):
    q.append(i)
    color = i
    cnt = 1
    while len(q) > 0:
        nextnode = q.popleft() # 次の探索
        if visited[nextnode] != -1:
            continue
        visited[nextnode] = color
        q.extend(g[nextnode]) # nextnodeの辺を足す
        cnt += 1
    # 探索が終わったらその色のノードの数を記録
    colorcount[color]  = cnt - 1

# res[i] = ノードの色, その色のノードの数 - そのノードが直接接続しているノード数 - 自分自身(1)　で初期化する
res = [[visited[i], colorcount[visited[i]] - (directcount[i] + 1)] for i in range(n)]

# ブロックリスト
for i in range(k):
    c, d = map(int, input().split())
    c, d = c - 1, d - 1 # 1 origin -> 0 origin
    # ブロック関係が同じ色だとするなら
    if res[c][0] == res[d][0]:
        # 友達になれると思っていた数を1つ減らす
        res[c][1] -= 1
        res[d][1] -= 1

# 結果の表示
print(" ".join(list(map(lambda x: str(x[1]), res))))
```
https://atcoder.jp/contests/abc157/submissions/10492409
gitでローカルファイルをリモートリポジトリへpushする

# 概要

gitへpushする際のコマンドをよく忘れるのでメモ

[フォルダ移動](#フォルダ移動)
[ローカルリポジトリの作成](#ローカルリポジトリの作成)
[add](#add)
[commit](#commit)
[リモートリポジトリの追加](#リモートリポジトリの追加)
[リモートリポジトリの削除](#リモートリポジトリの削除)
[push](#push)

## フォルダ移動

対象のファイルがあるディレクトリへ移動

##### 詳細

```
$ cd [ディレクトリパス]
```

##### 実例

```
$ cd /root/test/playbooks/
```

## ローカルリポジトリの作成

```
$ git init
```

## add

gitに登録したいファイルをaddする

##### 詳細

```
$ git add [ファイル名]
```

##### 実例

```
$ git add *
```

## commit

##### 詳細

```
$ git commit -m [コミットコメント]
```

##### 実例

```
$ git commit -m "first commit"
```

## リモートリポジトリの追加

##### 詳細

```
git remote add [リモートリポジトリ名] [リモートリポジトリURL]
```

##### 実例

```
$ git remote add origin git@github.com:ichikawa0311/playbook-test.git
```

## リモートリポジトリの削除

誤ってリモートリポジトリを追加してしまった時の削除方法

##### 詳細

```
$ git remote rm [リモートリポジトリ名]
```

##### 実例

```
$ git remote rm origin
```


## push

##### 詳細

```
git push [リモートリポジトリ名] [ブランチ名]
```

##### 実例

```
git push origin master
```
Linux標準教科書(ver3.0.2)やってみた 第１章

土台として絶対勉強した方がいいと良く見るので、
やっていきます。
全部で12章あるので、できるだけすべてまとめていきたいです。
基本的にはワードの意味や、動作についてまとめていきます。


<h2>基本ソフトウェアと応用ソフトウェア</h2>
　コンピュータには、大きく分けると2つの部分があります。
・ハードウェア(ex.ゲーム基本)
・ソフトウェア（ex.ゲームのソフト）

この内のソフトウェアの方は、これまた大きく2種類に分けられます。
・基本ソフトウェア
・応用ソフトウェア

これらがどのようなものか見ていきます。
<h3>基本ソフトウェア</h3>
基本ソフトウェアとはOperating System(OS)のことを指します。ex) Windows、 Linux、 MacOSX etc...
<br/>


__役割__

1. 各応用ソフトが動作する際の共通機能、部品の提供

　応用ソフトウェア（wordやexcelをイメージ）には、ファイルを保存したりツールバーなど共通する機能、部分が存在するが、それをすべての応用ソフトウェアが保持するよう作成するのは大変です。よって、これらの共有機能、部分を基本ソフトウェアで提供しています。

２． ハードウェアという「資源」を管理するという役割

　ここで指す「資源」とはコンピュータが提供できる機能・能力を示します。
　ワープロや表計算の基本ソフトウェアが同時に動くことができるの、コンピュータがこれらの資源をうまく管理しているからです。本来コンピュータは一つの動作しかできません。それにも関わらず同時に操作できるのは、各ソフトウェアをものすごいスピードで切り替えているからです。この切り替えが管理にあたります。

<h3>応用ソフトウェア</h3>
応用ソフトウェアは基本ソフトウェア上で動くアプリケーションを指します。ex) Word、Excel、PowerPoint



<h2>UNIX</h2>

 1960年代の米国の通信会社AT&Tのベル研究所で誕生。だが、研究開発されていたMULTICSは頓挫し、KenThonpson氏が研究所の片隅にあったコンピュータに搭載したプログラムがUNIXの始まりとなった。


<h3>分離・統合</h3>
　商品化を考えられたいなかったためUNIXは自由に利用する許可出ていた。それにより、たくさんの団体や企業によって改造が施されます。するとUNIXのまとまりがなくなったため、AT&Tが正式にライセンス契約を始め、ライセンスを持つ「System V」と、結んでない組織が開発した「UNIX互換OS」とにUNIXは分かれました。


<h2>Linux</h2>
　1991年にネット上で「僕は今、（UNIXに似た）OSを作っている。」と当時大学生のLinusTorvalds氏が投稿。その後公開されます。それは基本設計はUNIXそっくり、ですが上記したそれぞれのUNIXの流れを持たないUNIX互換OSでした。それはさらなる機能拡張、ソフトウェア、ツールの導入しLinuxが誕生します。
<h3>特徴</h3>

Linuxの一番の特徴はGPLというライセンス形式です。
以下特徴を引用します。
>・プログラムを実行する自由
・ソースの改変の自由
・利用・再配布の自由
・改良したプログラムをリリースする権利
「Linux標準教科書」


このおかげかLinuxはデュストリビューターによって開発され、非常に多くのユーザーに使用されるようになりました。

もう一つの特徴は基本ソフトウェアが二つの領域に分かれることです。それは「カーネル」と「ユーザランド」です。
<h3>カーネル</h3>
　「カーネル」はオペレーションシステムの中核です。ハードウェアと直接やり取りし、それらの違いを把握しハードウェア上で動作する役割です。
<h3>ユーザランド</h3>
　OSで動作するために必要とする、カーネル以外の部分を指します。ex)ファイルシステム、ファイル操作コマンド、シェルなどのソフトウェア群。

<h2>その他</h2>
<h3>シェル</h3>
　Linuxはコマンドで操作します。「シェル」は対話型のコマンド入力環境のことです。「シェル」の機能は大きく２つあります。

1. コマンド入力を受け付けること
2. シェルスクリプトを実行すること

※「シェルスクリプト」とはコマンド入力を自動化するものです。
<h3>ディストリビューション</h3>
　当初のLinuxはインストール作業が困難で、スキルの高い人しか扱えませんでした。ですが、様々な団体がLinuxを使うのに必要なプログラムをまとめ簡単にしてくれたおかげで現在のように手軽行えるようになりました。これらの団体は__ディストリビューター__と言います。
 　そしてこれらの団体によって作られた「Debian Project」や「Red Hat」、「Ubuntu」などのLinuxを「__Linuxディストリビューション__」と言います。


<h3>パッケージ</h3>
　パッケージはLinuxに対して追加機能を提供します。従来は応用ソフトウェアの導入をLinuxで行うのは時間と手間がかかりました。これを簡単にするためディストリビューターが作成するようになったのパッケージです。

<h3>パッケージマネージャ</h3>
　Linuxでは応用ソフトウェアの導入に複雑な順序のインストールや、場所指定があり、更新にも手がかかりました。そこでパッケージの導入やアップデートを簡単にできるようパッケージマネージャーがLinuxディストリビュージョンに標準で用意されるようになりました。


<h2>新出単語</h2>
* 基本ソフトウェア
* 応用ソフトウェア
* GPL
* System V
* バークレー版UNIX（BSD）
* カーネル
* ユーザランド
* シェル
* シェルスクリプト
* ディストリビューション
* ディストリビューター

<h3>参考文献</h3>
「Linux標準教科書」
Github API v4を使って今日のコミットを1リクエストで取得する

# あれ、今日何したっけ...？
っていうのもあれなのでGithubに今日の自分の頑張りを聞いてみる。

# やってみる
以下を前提として、[Github GraphQL Explorer](https://developer.github.com/v4/explorer/)でリクエストしてみる。

- 今日 = 日本時間 2020/03/02
- 対象ブランチ = staging
- 今日、以下のコミットを積んだ
    - Repository1に `$ git commit -m "feature: A機能に〇〇を追加"`
    - Repository1に `$ git commit -m "fix: B機能のバグfix"`
    - Repository2に `$ git commit -m "refactor: C機能のリファクタリング"`

```graphql:Query
{
      user(login: "<ログインユーザー名>") {
        # (1) 今日ContributeしたRepositoryの取得
        contributionsCollection(from: "2020-03-01T15:00:00Z", to: "2020-03-02T15:00:00Z") {
          commitContributionsByRepository {
            repository {
              name
              ref(qualifiedName: "staging") {
                target {
                  # (2) 今日のCommitの取得
                  ... on Commit {
                    history(
                      first: 100, 
                      author: {emails: ["<ログインユーザーのEmailアドレス>"]},
                      since: "2020-03-01T15:00:00Z",
                      until: "2020-03-02T15:00:00Z"
                    ) {
                      nodes {
                        message
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
```
```javascript:結果
{
  "data": {
    "user": {
      "contributionsCollection": {
        "commitContributionsByRepository": [
          {
            "repository": {
              "name": "repository1",
              "ref": {
                "target": {
                  "history": {
                    "nodes": [
                      {
                        "message": "fix: B機能のバグfix"
                      },
                      {
                        "message": "feature: A機能に〇〇を追加"
                      },
                    ]
                  }
                }
              }
            }
          },
          {
            "repository": {
              "name": "repository2",
              "ref": {
                "target": {
                  "history": {
                    "nodes": [
                      {
                        "message": "refactor: C機能のリファクタリング"
                      }
                    ]
                  }
                }
              }
            }
          }
        ]
      }
    }
  }
}
```

# ポイントの概説
### (1) 今日ContributeしたRepositoryの取得
user.contributionsCollection.[commitContributionsByRepository](https://developer.github.com/v4/object/commitcontributionsbyrepository/)
でたどることができる

`from`、`to`パラメーターで範囲を指定できるが、`2020-03-01T15:00:00Z`の形式に準拠してないとエラーになる。

### (2) 今日のCommitの取得
repository.ref.targetとたどり、[Commit](https://developer.github.com/v4/object/commit/)を[Inline Fragment](https://graphql.org/learn/queries/#inline-fragments)で取得する
関数

#関数
関数を定義するには以下のように書きます。
`fn` `関数の名前` `(` `引数` `)` `->` `戻り値` `{` `関数の中身` `}`
最後に書いた式や変数は、戻り値となります。関数を呼び出した側で、関数が戻り値に置き換わります。

~~~rust
//addという名前の関数を定義
//引数は x:i32 と y:i32
//戻り値は i32型
fn add(x: i32, y: i32) -> i32 {
    x + y // 最後に書いた式が戻り値です。
}

//円周率を返す関数
//意味があるのかは分かりませんが、これもOKです。
fn PI() -> f32 {
    3.14 // 単に値を書くだけでもOK
}

fn main() {
    let answer = 1 + 4; //普通に計算する
    let answer_add = add(1, 4); //add関数を呼び出す
    println!("answer = {}", answer);
    println!("add = {}", answer_add);
    println!("PI = {}", PI()); //関数の引数に関数を書くこともできる
}


~~~

関数はコードをまとめて再利用するときに便利です。よく使うコードは関数にすることで何度も書かずに済みます。

[目次](https://qiita.com/tonesuke/items/52e469f18e747c794376)
[VirtualBox]MacにWindows10環境を構築

大学の設備（プリンター）を利用したいが、Windows版しかドライバがない。ParalleelsDesktopを買うお金がもったいない、WindowsとMac二代持ちは不便で荷物が嵩張るからMac（PC一台）にまとめたい人向けの記事です。

#VirtualBoxをセットアップ
1. [公式ホームページ](https://www.virtualbox.org/wiki/Downloads)から最新版をダウンロード
2. PCを再起動
3. 『commamd & R』を押し続け、セーフティーモードで起動
4. ユーティーリティー　→　コマンドライン
5. ```spctl kext-consent add VB5E2TV963```を打ち込み、OracleのDevelopperID(VB5E2TV963)を直接承認
6. 再起動
7. ダウンロードしたdmgファイルを展開、ドライバなどを自動でインストール
8. 完了！


#まとめ
　セキュリティが厳しくなり、Web上からドライバがインストールできずVirutalBoxが使えません。そのため、”spctlコマンド"でOracle社からインストールするプログラムはファイヤーウォールやウイルス対策を無視する処理をまとめました。今回の作業で初めて"spctl"コマンドを知り、調べたので後々記事にしたいと思います。


最後まで読んでいただきありがとうございました。
基本情報技術者試験の勉強計画　第20週（3/2週）

## 目標と結果
### 目標
・忙しくても毎日継続する
・表計算を理解する
・午前問題の復習
### 結果
・毎日継続した
・表計算少しだけだが理解できた
・過去問道場で主に復習した
## 振り返り
## keep
・毎日継続すること
## problem
・毎日継続することだけを考えてしまって、できる日も10~20分くらいしかやれていないこと
・苦手なとこも見ながら何となく流してしまうところ
## try
・朝、早起きして勉強する習慣を身に着ける
Salesforceで外部公開できるWEBページを作成する

Salesforceプラットフォーム上で外部公開ができる＝SalesforceにログインのないWEBページをホスティングして、エンドユーザに閲覧（フォーム入力とか）させたい場合があるかと思います。

そんな場合、下記２通りの方法がある。
※Salesforceプラットフォーム上でサイトホスティングできないんじゃね？（できなくなったという噂聞いていた）という認識だったのですが、いろいろ調べたらできるっぽいというのが判明。下記2通りの方法があるがClassic,Lightningで使えるやつと使えないやつがあるらしい。。。なので、個人的メモとして残す）


・Site.comを使う（Lightningで使えず、Classicでしか使えない）
・Force.comサイトを使う（Lightning、Classicでも使えるっぽい）

それぞれの場合のメリット・デメリットは下記。

##Site.comを使う
###Site.com is なに?
いわゆるSalesforceの外部公開WEBページのためのCMS機能。


###メリット

![FireShot Capture 010 - Site.com Studio_ - cunning-otter-vd6vo8-dev-ed.builder.salesforce-communities.com.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/242499/06da38ed-b8d2-8112-352d-26410c722066.png)

↑のような画面からドラッグ・アンド・ドロップで外部公開できるWEBページが作成できる
ドラッグ・アンド・ドロップでWEBページ作成が可能。主にマーケッター向け。

###デメリット
・VisualforceやApexでのカスタマイズしにくい（エンジニア向けではない。
・Lightningでは使えない（Lightning移行する可能性あるなら使いにくい
・Salesforceの組織上で、2ユーザまでしか本機能を使うことができないっぽい
・その他、負荷（ページビューや、データの帯域）に対する制限どこまであるかよくわらかない

##Force．comサイトを使う
###Force.comサイト is なに?
高度にカスタマイズされた外部公開の可能なWEBページを作成できる。
VisualforceやApexでカスタマイズできる。嬉しい。

###メリット
・VisualforceやApexによる高度なカスタマイズ可能
・Classic,Lightningのどちらでも使用可能（今のところ）
・Salesforceプロファイルであれば、ユーザ数の制限なく利用できる（Salesforceプロファイルがいくつかによるが）
・負荷に対する制限がある程度、公開されており、やりやすい

###デメリット
・エンジニアじゃないと追加要件実装できない
・トラフィックが一定以上ある仕様のWEBページだと、利用するのは難しい
→月間ページビューが50万以内じゃないとサイト落ちる。なお、3ヶ月間での累積値で判定するらしい。累積で超えそうな場合は、Salesforceから通知がいくらしい。通知を受けて、ページビューの容量を増やしたい場合は＋アルファのお金を払うことで、増やすこと可能。
→データ転送の帯域幅が1WEBページあたり、40GB超えると、WEBページ表示に対する信頼性が落ちる設計らしい（？）

#まとめ

それほどトラフィックないWEBページをSalesforce上にホスティングしたい場合は、Force.comサイトを使う。
Classic限定でも良いから、簡単なコンテンツだけエンドユーザに表示させたいね〜という場合には、Site.com使う。
【WKWebView】loadFileURLの取得元をBundleから変更したら、.jsファイルが読み込まれなくなった！

#結論
loadFileURL(_:allowingReadAccessTo:)の引数は確認しよう！

#環境
Xcode 11.3.1
Swift 5

#WKWebViewあるある
WKWebViewでローカルのHTMLを読み込もう！　と意気込んでGoogle検索した場合は、大抵こんな感じの答えが帰ってきます。

```swift
let localurl = Bundle.main.url(forResource: "hoge", withExtension: "html")!
webview.loadFileURL(localurl, allowingReadAccessTo: localurl)
```

とりあえず動きを見るだけならBundle参照の方が圧倒的に楽なので、非常に合理的なサンプルコードです。
また、正直WebViewは表示した後のJS-Swift間のやり取りがみんな気になるので、この辺は割とさらっと済ませてしまいます。


で、それなりに実装が進んでDocumentsとかLibraryにリソースを配置するぞおおおおおおとなった時に、横着するとソースはこうなります。


```swift
let localurl = URL(fileURLWithPath: NSHomeDirectory() + "/Library/hoge.html")
webview.loadFileURL(localurl, allowingReadAccessTo: localurl)
```
(実際はもっと丁寧に文字列定義するとは思う)
この時に、allowingReadAccessToの値をそのままにしちゃうと、JavaScriptとかCSSファイルが読み込めなくなっちゃいます。
<br>

```swift
let localurl = URL(fileURLWithPath: NSHomeDirectory() + "/Library/hoge.html")
let allowAccess = URL(fileURLWithPath: NSHomeDirectory())
webview.loadFileURL(localurl, allowingReadAccessTo: allowAccess)
```

こんな感じで、allowingReadAccessToに適切なアクセス範囲を指定してあげると、
Bundleから読み込んでいた時と同じ挙動になると思います。
Pandas.DataFrameの列順を任意に並び替える

# はじめに
PandasのDataFrameに列を追加すると末尾に追加されていくが、ファイル出力する際にDataFrameの列順を指定したい時がある。
DataFrameの並び替えと言えばsort_values()やsort_index()だが、どちらも行方向の並び替えで列方向の並び替えには対応していない。
頻繁に使う訳ではないが、忘れた頃に使いたくなるので備忘録として残しておく。

# 方法
Pandasのlocの引数に並び替えた列名をリストを渡すだけ。
[pandas.DataFrame.loc](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.loc.html)

indexでも同様に任意の順に適応可能。


## データ準備
```py
from sklearn.datasets import load_iris
import pandas as pd

# サンプルとしてirisデータを利用
iris = load_iris()
df_iris = pd.DataFrame(iris.data, columns=iris.feature_names)

# 各項目の平均値を求め、サフィックスで列名に"_mean"を付ける
for col in df_iris.columns:
    df_iris[col + "_mean"] = df_iris[col].mean()

df_iris.head()
```
![iris_01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167671/2a67d142-b6c8-2acb-062d-17abca00fe98.png)


## 並び替えの指定
```py
# 任意の列順となるリストを作成
# ここではDataFrameの列名リストを取得、昇順に並び替えて使用する
list_col_sorted = df_iris.columns.to_list()
list_col_sorted.sort()
list_col_sorted
```


```py
['petal length (cm)',
 'petal length (cm)_mean',
 'petal width (cm)',
 'petal width (cm)_mean',
 'sepal length (cm)',
 'sepal length (cm)_mean',
 'sepal width (cm)',
 'sepal width (cm)_mean']
```


## 結果
```py
# locの引数に並び替えたリストを設定
df_iris.loc[:, list_col_sorted].head()
```
![iris_03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167671/01bf138f-a0d6-e880-5db1-2282587fa6ef.png)


# おわりに
列名でソートしたことで、末尾が"_mean"の列名が元の列のすぐ後に並ぶようになった。

機械学習では数十以上の項目から数百、数千の特徴量を作成することもある。
他にも欠損値フラグを追加する際など、対応する項目が離れていると見辛いのでそうした場面で覚えておくと良い。
[VisualStudio]VisualStudio2019でリモートデバッグを行う(C++の場合)

**もくじ**
→https://qiita.com/tera1707/items/4fda73d86eded283ec4f

**リモートデバッグ関連**
- [VisualStudio2019でリモートデバッグを行う(C#の場合)](https://qiita.com/tera1707/items/5d70ebf96d03c1042b9e)
- [VisualStudio2019でリモートデバッグを行う(C++の場合)](https://qiita.com/tera1707/items/9c6d6960c295dc3ad86f)
- [リモートデスクトップに必要な設定](https://qiita.com/tera1707/items/84f0b487da73d20dafe6)

# やりたいこと
C#で行っていたリモートデバッグをC++でもやりたい。
以前やったことがあったのだが、メモを残しておらずやり方を忘れたのでメモしておく。

# 準備
準備や手順については、以前の記事[(こちら)](https://qiita.com/tera1707/items/5d70ebf96d03c1042b9e)を参照。  
この中の、
「[手順の4.](https://qiita.com/tera1707/items/5d70ebf96d03c1042b9e#4%E9%96%8B%E7%99%BA%E7%94%A8pc%E3%83%87%E3%83%90%E3%83%83%E3%82%B0%E3%81%97%E3%81%9F%E3%81%84%E3%83%97%E3%83%AD%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E3%81%AE%E8%A8%AD%E5%AE%9A)」が、C++の場合の特有のやり方となるので、下にメモする。
(それ以外(リモートデバッガのダウンロードやPCの共有の設定)は、以前の記事と同じ。)

# 前提
今回は、下記のようなPCの設定にした。

|設定内容|設定値|
|:--|:--|
|リモートPCのアドレス|`192.168.31.21`|
|リモートPCに作成する共有フォルダパス|`\\192.168.31.21\test`|
|アプリ名|`PInvokeTest.exe`|
|リモートデバッガのポート番号|4024(デフォルトのまま)|


# リモートデバッグのためのC++のプロジェクトの設定
リモートデバッグをしたいC++のプロジェクトを **[右クリック] > [プロパティ] を選択**する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352601/32aab4fc-bf36-342d-5c3a-9967acb55244.png)

[構成プロパティ] の中の [全般] を選択し、その中の**[出力ディレクトリ]**に、リモートPCの出力先としたい共有ディレクトリを入力する。(この例の場合「\\\192.168.31.21\test」に出力するものとする)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352601/4cc347ec-552a-24ec-80ef-9969fafae96f.png)

[構成プロパティ] の中の [デバッグ] を選択し、その中の**[起動するデバッガ]**のコンボボックスから、**[リモートWindowsデバッガー]**を選択する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352601/3900c409-248a-a304-038d-03ae00fd9c26.png)

リモートWindowsデバッガーの設定が表示されるので、その中で下記設定を行う。

- リモートコマンド  
**→`<リモートPCの共有フォルダパス>\<exeファイル名>.exe`**
- リモートサーバー名  
**→`<リモートPCのIPアドレス>:<リモートデバッガのポート番号>`**  

今回の例では、下記のようにした。

- リモートコマンド  
**→`\\192.168.31.21\test\PInvokeTest.exe`**
- 作業ディレクトリ  
**→`\\192.168.31.21\test\`**
- リモートサーバー名  
**→`192.168.31.21:4024`**  
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352601/fdae2c08-f77e-1c9e-2170-dd48d80f2744.png)



**以上で、C++のプロジェクトの特有の設定**はおわり。
あとは、リモートデバッガーをリモートPC側で起動して、**リモートWindowsデバッガー**ボタン(又はF5)を押して、プログラムを実行すればOK。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352601/99c5a737-e6ca-a3a0-8ff6-49e8240e22f3.png)

# 備考とおことわり

本当は、MSの[公式ドキュメント](https://docs.microsoft.com/ja-jp/visualstudio/debugger/remote-debugging-cpp?view=vs-2019#remote_cplusplus)によると、下記のような設定や「配置」をしたりしないといけないっぽい。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/352601/62a62301-c110-f3c4-b606-46a564427565.png)

が、これだとリモートPCのフォルダ構成を開発用PCと同じにしておかないといけないとかが確かあった(この記事書いたときには試してなくて、過去の記憶による。すみません)ので、上でやったような「出力フォルダを変えて、配置はしない」やり方でやることにした。
(作業ディレクトリの設定もせず、一時的なファイルは開発用PCに勝手にできたらええよといういい加減な感じ)

# 参考
プロジェクトのC++リモートデバッグ(MSDocs)
https://docs.microsoft.com/ja-jp/visualstudio/debugger/remote-debugging-cpp?view=vs-2019#remote_cplusplus
パーフェクトRubyをひたすらやってみた。（アウトプット用）＃２

前回のまでパーフィクトRubyは、１章から３章が終わった。

その段階でわからないところが以下のことである。

- 仮引数としてブロックを受けるところ
- Procオブジェトをブロックで渡す
- 例外処理

今回はここの復習と次の４章までやっていく。

##仮引数としてブロックを受ける

そもそも根本的にブロックが何かわからない。。。
なので、分解して理解していく。

###ブロックとは？
 簡単に言うと、do~end（もしくは{~}）で囲われた、引数となるためのカタマリ。

その中にyieldや変数が混ざったりしているが基本これだけ。

###ブロックの特徴
ブロック単体では存在することができなく、引数にしかなれない。

引数として渡されたブロックは、yieldによって実行される。

 ```ruby
def block_name
  yiled
end
block_name do
 puts "Hello world"
end
# "block_name内でyiledによりHello worldが出力される"
```

簡略した、yieldを使わずに書くと以下の通り。

```ruby
def block_name(&block)
  block.call
end
block_name do
 puts "Hello world"
end
# "Hello world"

```
`def block_name(&block)`ではブロック引数が受け取ることを示している。

###&blockの【&】とは？
&をつけることで、引数にブロックが渡ってきたときに、Procオブジェクトに変換している。


##Procオブジェトをブロックで渡す

ブロックはわかったでもProcオブジェクトってなに？

これも分解して解釈する。

###Procオブジェクトとは？

ブロックをオブジェクト化したものがProc。

ブロックがそれ単体では存在できないことを思い出す （→オブジェクト化してしまえばok）

ブロックをオブジェクトに変換することで、引き渡されたメソッド（block_name）内で扱えるようにする

Procオブジェクトは、callで呼び出すことが出来る

`block.call`の正体はこれ。

つまり、引数にブロックを受け取るメソッドに対して、ブロックの代わりにProcオブジェクトを渡すことができるということ。

普通の引数も渡せるがブロックも引数として渡せるなんて便利ですね。

以上が前回わからなかったところの復習。

次に第４章についてアウトプットしていきます。

##４章 クラスとモジュール

ここではクラスについて概念や記述の方法について書いてあります。
クラスはある程度しっているので問題ないでしょう。

###クラスメソッド・インスタンスメソッドとは？

>クラスメソッドとは、クラスオブジェクトから実行可能なメソッド
インスタンスメソッドとは、クラスのインスタンス(実体)に対して紐づけられるメソッド
引用元：コトバンク

なるほどさっぱりわかりません。

とりあえずコードをかいてみます。

```ruby
class Language
    def program(name)
         name
    end
end

program("ruby")
```
実行結果は`undefined method 'program' for Add:Class (NoMethodError)`とでた

これはクラスに中にインスタンスがあるので、「どこのprogramですか」となっている。

そのためクラスを指定してあげないといけない。

```ruby
class Language
    def program(name)
        name
    end
end

Language.program("ruby")
```

これでどうだ！

実行結果は`undefined method 'program' for Language:Class (NoMethodError)`
これでもエラー。

この原因は箱を作ってあげないのでクラス.newをしてからの箱に代入する。

なので、

```ruby
class Language
    def program(name)
        name
    end
end

language=Language.new
puts language.program("ruby")#ruby
```

これで`ruby`で出力された。

###つまりインスタンスメソッドは？

結論から言うとクラスの中にメソッドを作成するとそれがインスタンスメソッドになる。

```ruby
class クラス名

  def メソッド名(変数1, 変数2, ...)
    処理
  end

end
```

インスタンスメソッドは、クラスのインスタンスに機能として搭載されているものです。

先ほどの計算クラス(エラー)となってしまったコードは、インスタンスを作り、作ったインスタンスに対してメソッドを呼び出せばエラーを吐きません。

###クラスメソッドは？
クラスメソッドの定義に仕方としては

 ```ruby
class Language
    def self.program(name)
     name
    end
end
puts Language.program("ruby")

```
という形で定義します。



クラスメソッドの使い方としては、クラス名.メソッド という形で使います。

上記の例ですと

`Language.program`という感じになる。

###今回はここまで、

毎日アプトプットするのはプログラミングの勉強になりますが
、記事を作成に少し時間がかかってしまうので、今後はそこを改善したいです。

第４章の始めなので、しっかりRubyの構文になれていきたいですね。

また、gitのコマンド操作も今日は色々やらかしたので、gitの操作も慣れてきたいと思います。

周りに優秀なエンジニアがいる環境にいるのでガンガン聞いて、インプット、アウトプットしてきたいです。


**今日の名言**

`考えて、答えが出ることなら、しっかり考えましょう。考えても仕方のないことなら、意識的に考えるのをやめましょう。`

`石塚巌（実業家）`
AWS ディベロッパーアソシエイト資格（+α）に合格しました。

# はじめに

前回（SysOps）に引き続き、AWS Certified Developer - Associate（DVA）を取得しましたので、勉強した内容や試験の所管について書きたいと思います。
（ついでにCloud Practitioner（CLP）も取得しましたが、こちらはそれ専用の勉強はほとんどしていないので、結果（スコア）だけさっくり書きます）

※過去の記事
[AWS SAAに受かった話](https://qiita.com/kkino1985/items/85bcfa50686fcfe69c56)
[AWS SOAに受かった話](https://qiita.com/kkino1985/items/295509d3d94c726ae56a)


# 勉強期間

SOAを取ったのが2020/1/17なので、約1.5ヶ月ぐらいです。
とはいえ、試験範囲もSOAと重複する部分も多いので合算して2.5ヶ月と考えた方が良いかもしれません。

# 獲得スコア

|試験|受験日|スコア/合格点/満点|結果|
|:--|:--|:--|:--|
|Cloud Practitioner（CLP）|2020/2/29|846/700/1000|合格|
|Developer Associate（DVA）|2020/3/1|883/700/1000|合格|

CLPの方はともかく、DVAの方は試験中あまり手ごたえがなく、落ちたかもしれないと思いながら受けていたので、思ったよりスコアが良くて驚きました。

# DVA試験の勉強方法

AWSはアップデートが早いので書籍よりも公式ドキュメントで勉強する方が本筋になる、というのはAWS資格共通の話ですが、DVAは以下の難しい点がありました。

- 他のアソシエイト資格に比べて教材が少ない
- 試験範囲のサービス（CodeCommitやOpswork、API Gatewayなど）は開発をやっていないとイメージが付きにくい
　（特にCodeシリーズはインフラエンジニアだとあまり触る機会が無い）

開発をやっている人であればまた違うのかもしれませんが、自分のように開発経験がない場合の勉強の進め方としては、

1. サンプルや模擬試験、Whizlabsの問題を解く
2. わからなかった部分や、理解が曖昧だと思ったサービスについて公式ドキュメントで調べたり、チュートリアルをやったりする

という流れ（繰り返し）になると思います。

また、これはDVAに限らないですが、AWSは「多くのサービスから取捨選択して顧客が求めるものを提供する」がコンセプト（だと思っている）なので、類似サービスの用途や機能の違いは知っておいた方が良いです。
（たとえば、CloudTrailとX-Rayは何が違うのか？　もしくはCloudwatchやInspectorとは？　など）


# 学習で使った教材

## AWS公式

サンプル問題、模擬試験、Blackbeltオンラインセミナーの資料・動画は当然なので省略するとして、それ以外だとチュートリアルやハンズオンにだいぶお世話になりました。

今回の場合、DynamoDB、Lambda、SQSあたりはかなり頻繁に（かつ詳細に）出題されるので、そのあたりのチュートリアルをやっておくと良いと思います。

あとは「AWS Hands-on for Beginners Serverless 編」という、今回の試験範囲であるLambdaやAPI Gateway（他）の解説とハンズオンがセットになったオンデマンドセミナーもあるので、これを一通りやった方が良いです。

https://aws.amazon.com/jp/aws-jp-introduction/aws-jp-webinar-hands-on/

試験では「xxをするのに指定するパラメータは何か」的な細かい問題も出るので、とにかく実機作業の練習を積み重ねていくと本番の時に「そういえば」と引っかかる部分があったりします。
（その意味ではAWS試験はかなり実践的な問題が出る印象です）

またそれ以外だと、サービスのベストプラクティスもかなり参考になりました。

## 書籍

[「AWS認定アソシエイト3資格対策～ソリューションアーキテクト、デベロッパー、SysOpsアドミニストレーター～」](https://www.amazon.co.jp/dp/B07TT1N73K/ref=cm_sw_em_r_mt_dp_U_L0gkEbGY6R68D)

前回に引き続き。ただSOAを取った後はほとんど読まなかったのであまり役立ってはいないです。
（あくまでAWS初心者がサービスの大枠をさらうための本、と考える方が良さそうです）


## 問題集

「WHIZLABS」(https://www.whizlabs.com/)
試験問題を販売している海外のサイト。
今回は有料版を購入し、全体を2週ぐらいやりました。

前回はわからなかった翻訳のやり方ですが、トップページで日本語に翻訳し、そのままマイコースから問題にアクセスするとページ遷移時に自動で翻訳してくれるので、問題も日本語で解くことができます。（Google Chromeの場合。他のブラウザは未確認）

ここの問題がそのまま出た、ということはありませんが（一部模擬試験と重複する問題はありましたが）、わからないサービスを洗い出して勉強するきっかけになった、という点では今回一番お世話になったと思います。

# 試験を受けての所感

- 読んだ瞬間「これだ」とすぐにわかる問題は少なかった（ただし明らかにおかしい選択肢がまぎれているので、文章はよく読むべし）
- DynamoDB、SQS、Lambda、API Gatewayの問題がやたら多い（直接問われているかはさておき）
- 計算問題は得点源
- KMSというよりはSSL暗号化の仕組みを聞かれているような気分になった
- 意外とECSの問題が出た（あまり準備していなかったので「アカン」ってなった）
- 同じようなことを複数の問題で聞かれることがあるので、最初はわからなくても後の問題をやったらわかる場合もある

# 今後の予定

とりあえずエントリーとアソシエイト3つでAWS資格4冠になれて一安心、といったところです（SAAを取った時期からすると遅過ぎたぐらいですが）
次はAWS Solution Architect Professional（SAP）が本命ですが、仕事でAzureも触っているのでAzure Administrator Associate（AZ-103）に寄り道するかもしれません。
timeメソッドによる繰り返し

## 繰り返し処理を実装してみよう
while文やeach文など様々な繰り返し処理を行うメソッドは数多く存在しますが、
今回はtimesメソッドについて記載しようと思います。

## 問題
以下のような問題があったとします。
・要件を満たすプログラムを記述しなさい
・ユーザが数字を入力する
・入力した数だけHELLO WORLD!と出力する

私はことプログラムを以下のように実装しました。

```ruby
def say_hello(num)
  count = 0
  while count < num do
    puts "HELLO!"
    count += 1
  end
end

puts "数字を入力してください"
num = gets.to_i
say_hello(num)
```
say_hellowメソッドの中で変数countを定義し
HELLO WORLD！が出力されるたびにcountを+1して
ユーザーが入力した数がcountより少なくなったら出力をやめるというもの
要件は問題なく満たしております。
しかしこれ...長くないですか？

## timesメソッド
上記の要件をもっと簡単に実装する方法があります。
それがtimesメソッド！
timesメソッドを使用すると以下のようになります。

```ruby
def output(num)
  num.times{ puts "HELLO WORLD!" }
end

puts "何回表示させますか？"
num = gets.to_i
output(num)
```
とてもすっきりしていますよね？
timesメソッドは変数に対して使用すると後述する処理をその回数分実行します。
そのためユーザが入力した数だけ出力したということですね
while文を使用しなくてもすっきりとしたコードで実装することができます
Spring MVC の正式名称は Spring Web MVC

正式名称: Spring Web MVC
通称: Spring MVC

どっちがどっちなのか忘れてしまうので公式資料を参照する。

Spring Framework 5.2.4 のドキュメントより。

[Web on Servlet Stack](https://docs.spring.io/spring/docs/5.2.4.RELEASE/spring-framework-reference/web.html)

> The formal name, “Spring Web MVC,” comes from the name of its source module (spring-webmvc), but it is more commonly known as “Spring MVC”.
指定時間にコマンドを実行する'Vialarm'プラグイン

先日からお熱になっていた["Vimにcron相当のアラーム機能を追加する"話](https://qiita.com/astrorobot110/items/9bd417ad0012ed5e3472)のオチとして、[gitに公開](https://github.com/astrorobot110/vialarm)しました。詳細等のちほど…
あの PDO::PARAM_INT の挙動が変わった！

# (2020/3/27 追記)徳丸さんが記事書かれたので、リンクしときます！
[PHP 7.2以降におけるPDO::PARAM_INTの仕様変更](https://blog.tokumaru.org/2020/03/php-72-pdo-param-int.html)
さすが、検証の方法が、私のよりちゃんとしてますね＾＾；
float に関しての言及がないので、一応、以下は役に立つはず！

# 以下、元記事

あの何もしないことで有名な PDO::PARAM_INT の仕様がいつのまにか変わっていました。
が、解説記事が見当たらなかったので、検証とともに記事にしときます。
**多分、アップグレードガイドにも載ってない秘密の情報ですｗ[^1]**

# 何もしない PDO::PARAM_INT とは？
PDO 使用している人には結構有名な話ですが、こいつ、ほとんど働きませんでしたｗ
参考記事：[PDOでの数値列の扱いにはワナがいっぱい（2）](http://blog.a-way-out.net/blog/2013/12/18/pdo-prepare-statement-numeric-literal-part2/)

> PDO::PARAM_INTはboolをintに変換（他は何もしない）

つまり、int へキャストされることを期待して
`$stmt->bindValue(':test', 1.1, PDO::PARAM_INT);`
なんてぶっこんでも、普通に`1.1`が投入されます:sweat:
サボりすぎだろｗ

#何が変わったのか？
プリペアドステートメントのエミュレーションが ON な時、ちゃんと働くようになりました！
正しく、int へキャストされます:grinning:

本件は以下の変更で対応されたようです。
[Emulated statements let value dictate parameter type ](https://github.com/php/php-src/commit/32b6154a61fae820386527f3019f8c5937fc5d27)

**ただし、エミュレーションが OFF だと、まだサボりやがりますｗ**

# 検証
以下のサンプルをいくつかのバージョンで動かしてみました。

```php

<?php
try {
    $pdo = new PDO(
        'mysql:dbname=hoge;host=localhost;charset=utf8',
        '',
        '',
        [
            PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
            PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
            // PDO::ATTR_EMULATE_PREPARES => false,
            PDO::ATTR_EMULATE_PREPARES => true,
        ]
    );
    $stmt = $pdo->prepare('INSERT INTO test (php_v,test) VALUES (:php,:test)');
    $stmt->bindValue(':php', phpversion(), PDO::PARAM_STR);
    $stmt->bindValue(':test', 1.1, PDO::PARAM_INT);
    $stmt->execute();
} catch (PDOException $e) {
    exit($e->getMessage());
}
```

|php のバージョン|エミュレーション|値|
|:--:|:--:|:--:|
|7.1.33|OFF|1.1|
|7.1.33|ON|1.1|
|7.2.26|OFF|1.1|
|7.2.26|ON|1|
|7.3.13|OFF|1.1|
|7.3.13|ON|1|
|7.4.1|OFF|1.1|
|7.4.1|ON|1|

#影響
いくつかのトラブルを見ると、float にデータを突っ込む時に`PDO::PARAM_STR`を使うのを気持ち悪がって、`PDO::PARAM_INT`を採用したケースで被害が出ているようです。
まぁ、2択で INT を選ぶ気持ちはわかる！



これ、結構でかい問題になると思うので、バージョンアップ対応時には注意してください。

[^1]: [Binding value as PDO::PARAM_INT has different behaviour in PHP 7.2](https://bugs.php.net/bug.php?id=77954) で、なぜかアップグレードガイドに載せることがスルーされてます:sweat_smile:
スパルタキャンプPython編 2019 Day2　課題

動画上では課題の答えがわからなかったので自分なりに解いてみました。
スパルタキャンプのライブ動画で学習している方の参考になればと思い書きました。

#課題
オブジェクト指向プログラミングの初級問題です。
オブジェクト指向を使った良いコードの書き方というよりも、正しい文法で記述できるかを目的としています。

次のコードが正しくなるようなCircleクラスを実装してください。
areaは面積、perimeterは周囲長（円周の長さ）という意味です。

```python:circle.py
#半径１の円
circle1 = Circle(radius=1)
print(circle1.area()) #3.14
print(circle1.perimeter()) #6.28

#半径３の円
circle3 = Circle(radius=3)
print(circle3.area()) #28.26 ←恐らく動画での28.27は誤り
print(circle3.perimeter()) # 18.84 ←恐らく動画での18.85は誤り


#次のコードが正しく動作するようなRectangleクラスを実装してください
#diagonalは対角線（の長さ）という意味です。


rectangle1 = Rectangle(height=5, width=6)
rectangle1.area() #30.00
rectangle1.diagonal() #7.81

rectangle2 = Rectangle(height=3, width=3)
rectangle2.area() #9.00
rectangle2.diagonal() #4.24
```

#答え
雑なコードですが、自分が導き出した答えを参考までに載せておきます

```python
class Circle:
    def __init__(self, radius):
        self.radius = radius

    def area(self):
        return (self.radius ** 2) * 3.14

    def perimeter(self):
        return self.radius * 2 * 3.14

class Rectangle:

    def __init__(self, height, width):
        self.height = height
        self.width = width

    def area(self):
        area = self.height * self.width
        print(f'{area:.2f}')

    def diagonal(self):
        line = pow(self.height, 2) + pow(self.width, 2)
        line = line ** (1/2)
        print(f'{line:.2f}')
```


実行結果が以下のようになれば正解！

```
3.14
6.28
28.26
18.84
30.00
7.81
9.00
4.24
```
Pythonでクイックソートを書いてみたメモ

クイックソートについて自分用にメモを書いてみました。
# クイックソートとは
- 分割統治法に基づく高速なソートアルゴリズムで、大きなデータサイズに対応できる。
- 計算量はO(nlogn)
  - logn個の階層があり、各層ごとの計算量はO(n)であるため。
- ソートすると同じ値の順序が変わってしまう不安定なソート
- 一時的にデータを保存するメモリは必要ない

# コード
```python:quick_sort.py
def partition(A, p, r):
    x = A[r-1]
    i = p-1
    for j in range(p, r-1):
        if A[j] <= x:
            i += 1
            A[i], A[j] = A[j], A[i]
    A[i+1], A[r-1] = A[r-1], A[i+1]
    
    return i+1
    
n = int(input())
A = list(map(int, input().split()))


def quick_sort(A, p, r):
    if p < r:
        q = partition(A, p, r)
        quick_sort(A, p, q)
        quick_sort(A, q+1, r)
    return A
        
print(quick_sort([3, 1, 10, 2.5, 11, 3, 21,4, -1], 0, 9))
# [-1, 1, 2.5, 3, 3, 4, 10, 11, 21]
```

上記のアルゴリズムは基準の選び方が一定（最後尾の値）なので、データの並びによっては効率が悪くなる
計算量がO(n^2)になるかも
再帰が深くなりすぎてエラーになるかも
そのため、基準の選び方をランダムにする、中央値を選ぶなど工夫する必要がある。


# 参考
[ソートアルゴリズムと Python での実装](https://qiita.com/suecharo/items/30f5d817da4c948c3be6)
error messageにコロンをつけたらlintに怒られた


Goを書いている時に怒られて何のことかわからなかったので、調べた覚書です。

# 起こったこと
```
errors.New("Not found.")
```
サンプルの記述ですが、上記の記述だと、下記のメッセージが出て記述を直すように言われます。

```
error strings should not be capitalized or end with punctuation or a newline
```
エラーの文字列は大文字にしたり、句点、改行で終わらせたらいけないらしいです。
なぜ、そんな事になっているのか気になったので、公式のwikiで調べました。

> Error strings should not be capitalized (unless beginning with proper nouns or acronyms) or end with punctuation, since they are usually printed following other context.

https://github.com/golang/go/wiki/CodeReviewComments#error-strings

このメッセージだけじゃないからということみたいです。

# 結果
以下のように直しました。

```
errors.New("not found")
```

単純でしたが、色々作法があるんだなと。
記事を読んでいると、lintの設定次第なようなので、調整していくものなのかも。
https://kakakakakku.hatenablog.com/entry/2017/08/18/193946
[flutter] hot reload not working flutter な時

#　はじめに
VScodeでデバッグでホットリロードされなかったので調べました

# 解決方法

main関数内に直接記述した内容はホットリロード後に描画されないので、適当な関数を作って、それをmain関数で呼ぶ


```dart:before
import 'package:flutter/material.dart';

void main() {
  runApp(
    MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text("Hello world!"),
        ),
      ),
    ),
  );
}
```

```dart:after
import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text(
            "Hello world!",
          ),
        ),
      ),
    );
  }
}

```
初心者から始めるJava、変数と型

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

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

#変数とは
変数（Variable）とは、コンピュータが持つメモリを利用して、必要な値を記憶しておくための仕組み。**「格納するための箱」**として例えられる。

変数を扱うにあたっての必須ルール
**1、変数の[名前]を決めて**
**2、変数の[型]を指定してから**
**3、変数を[宣言]してから使う**

変数の命名に使うことのできる文字・数字の組み合わせを**識別子(Identifier)**と呼ぶ。ただし、Javaの規則により識別子になれない名前も存在する。

#１、識別子のルール
以下は間違った例と、その理由。

```Java:Wrong_Identifier.java
1forAll //数字から始めてはいけない。
class  //javaがほかの用途で使う予約をしている、いわゆる「予約語」
all-for^one //特殊文字は使えない。
```
識別子になれる名前の例も挙げておく。

one4all //頭がアルファベットなのでOK。
classOfOurs //スペースを挟まず予約語以外の言葉になればOK。
all_for_one //アンダーバーで繋がっているものはOK。

#２、型のルール
「型」とは「データ型」とも呼ばれ、名前を付けた変数は、その中に格納できる値をあらかじめ定められなければならない。
Javaの基本的な型は後述。ここでは間違えて代入した時の内容を記述する。

```Java:Wrong_DataType.java
char myCatName = "テト" //これは文字列、charは文字単体か数字のみ格納
byte characterLevel = 128 //byteは-128から127まで格納できる
```
型によって格納できる中身が決まるのと同時に、型によってコンピュータのメモリをどれだけ使うのかも決まっている。上の例でいえば、charは２バイト、byteは１バイト。最も大きくてもdoubleの８バイトとなる。

#３、変数の宣言
Javaにおいて、変数は宣言されなければ使えない。
以下は、変数の宣言と同時に変数に値を格納する**初期化(Initialization)**で書いたものである。

```Java:mistakeOfDeclaration.java
int moneyInMyPocket = 200;
int fleshJuice = 120;
moneyInMyHand = 80; //moneyInMyHand変数の型が宣言されていない
```
最後の一文について、
**int moneyInMyHand =moneyInMyPocket - fleshJuice**
とちゃんとint型で宣言して書くのが正解。一度宣言された残りの二つについては、型が変わらない限りは再度宣言する必要はない。 

#変数の代入
変数は他の変数にそのまま代入可能。ただし代入する方・される方の両方の型が同じである必要がある。型の変換を行えば入れることはできるが、ここでは割愛。

```Java:Wrong_Assignment.java
int oneMagicNumber = 33-4
int similarMagicNumber = 33.4
```
similarMagicNumberはint宣言をされたが、整数ではなく小数点を含む実数を代入されている。oneMagicNumberには、式の結果である29が格納されている。

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

[やさしいJava 第7版](http://mana.on.coocan.jp/yasaj.html)
xibで作ったtableViewCellにactionを加える。今回はsegueを実行する。

#問題
twtterクライアントを作っていて、timeline中の１ツイートをタッチすると、そのツイートのみを表示する画面に遷移する機能を作ろうしていました。
しかし、xibでtableViewのcellを作っていたので、

 - cellから他の画面へのsegueを繋げないこと
 - cell自体を@IBActionでつないでActionを設定すること

ができないことに気がつきました。(prototypecellを使うと、同storyboard内でsegueを繋げるんですけどね。cellを使いまわしたかったのです。)

#解決法
実は、tableViewControllerは、cellが選ばれたときの処理を各メソッドを用意しています。
それが、

```tableViewController.swift
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
}
```
です。
このメソッド内にかけばOK。

例えば、[このページ](https://capibara1969.com/229/)でManual Segueを"toDetailTweet"と言うidentifierで作っておいてから、、

以下のようにperformSegue()メソッドでsenderをcellに指定すればOK

```tableViewController.swift
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        performSegue(withIdentifier: "toDetailTweet", sender: tableView.cellForRow(at: indexPath))
    }
```
.htaccessでWordPress管理画面ログインページの変更しようとすると変更後404エラー時の対応メモ

# 使用環境

GCP（GCE）
Apache2.4.25
Debian9.11

# 背景

WordPressを使ったサイトで、管理画面をwp-adminのままにしているとセキュリティ的に危ないので、
Apacheのmod_rewriteを使って、.htaccessにRewriteRuleを記述して変更したかった。

WordPressのプラグインに<a href="https://ja.wordpress.org/plugins/siteguard/">SiteGuard Wp Plugin</a>なるものがあったので、それを使って管理画面ログインページを変更したものの、

なぜか変更後に試しに一度ログアウトしてみると、404 not foundになってしまう。

# 調査方法と対処法

##### ①そもそもmod_rewriteがインストールされていて、有効になっているか調べる

```zsh
$ cat /etc/apache2/mods-available/rewrite.load
LoadModule rewrite_module /usr/lib/apache2/modules/mod_rewrite.so
```
上記が表示されればインストールはされているので、次にa2enmodコマンドで有効化する
（a2enmodがnot foundになったら、```apt-get install a2enmod```でインストール）

```zsh
$ sudo a2enmod rewrite
Module rewrite already enabled
```
どうやら有効化もされているようなので、mod_rewriteは正常そう

##### ②変更後のURLでサーバーにアクセスはきているのかログをみてみる
```zsh
$ cat /var/log/apache2/access.log
```
404返しているログがあったので、こちらも問題なさそう

##### ③.htaccessの記述はされていて、正しいかどうかみてみる
```zsh
$ cat /var/www/html/.htaccess
```

```php
#SITEGUARD_PLUGIN_SETTINGS_START
#==== SITEGUARD_RENAME_LOGIN_SETTINGS_START
<IfModule mod_rewrite.c>
    RewriteEngine on
    RewriteBase /
    RewriteRule ^wp-signup\.php 404-siteguard [L]
    RewriteRule ^wp-activate\.php 404-siteguard [L]
    RewriteRule ^hogehoge(.*)$ wp-login.php$1 [L]
</IfModule>
#==== SITEGUARD_RENAME_LOGIN_SETTINGS_END
#SITEGUARD_PLUGIN_SETTINGS_END
```

こちらも問題なさそう

##### ④mod_rewriteのオーバーライド設定確認
```zsh
$ ls /etc/apache2/sites-available
000-default.conf
default-ssl.conf
wordpress.conf
```
これらのconfファイルのどこかに

```
AllowOverride All
```
の記述があればオーバーライドは許可されているはず。
そして結果記述がなかったので、wordpress.confに上記を追加してApacheを再起動したら、無事ログアウトでき、
/wp-admin/では404になり、変更後のURLを入力したらログイン画面が出てきた。
めでたしめでたし。

2020/03/11更新
---
/etc/apache2/apache2.confの172行目にAllowOverrideの設定があったので、それをAllに変更してあげるだけで大丈夫でした

# 参考
https://www.adminweb.jp/wordpress/permalink/index2.html
https://qiita.com/u-akihiro/items/c7a5bb38c34858d00c2a
http://www.bnote.net/kuro_box/apache2_mod_rewrite.shtml
https://teratail.com/questions/52734
solidityで疑似乱数を発生させる（Randomness Pattern）

# 記事の内容
solidityのデザインパターンの学習していると乱数生成に関するパターンがありました。
スマートコントラクトはインプットが同じであれば必ず同じ結果になることが設計思想としてあるため、solidityに乱数生成の処理はありません。

コードを見てみると、なるほどとなったのでメモ

# 参考
[Solidity Patterns Randomness Pattern](https://fravoll.github.io/solidity-patterns/randomness.html)

# Randomness Pattern
## やりたいこと
疑似的な乱数を生成し、乱数に応じた処理を行う

## コード
参考のサイトに掲載されているコードをv0.5.16用に修正しました。
コンパイルでエラーや警告は出ませんが、ちゃんと動かそうと思うともう少し修正が必要です。


~~~ Randomness.sol
pragma solidity ^0.5.16;

contract Randomness {

    bytes32 sealedSeed;
    bool seedSet = false;
    bool betsClosed = false;
    bool betMade = false;
    uint storedBlockNumber;
    address trustedParty = 0xdCad3a6d3569DF655070DEd06cb7A1b2Ccd1D3AF;

    event notification(uint);
    
    function setSealedSeed(bytes32 _sealedSeed) public {
        require(!seedSet);
        require (msg.sender == trustedParty);
        betsClosed = true;
        sealedSeed = _sealedSeed;
        storedBlockNumber = block.number + 1;
        seedSet = true;
    }

    function bet() public view{
        require(!betsClosed);
        // Make bets here
    }

    function reveal(bytes32 _seed) public {
        require(seedSet);
        require(betMade);
        require(storedBlockNumber < block.number);
        require(keccak256(abi.encodePacked(msg.sender, _seed)) == sealedSeed);
        uint random = uint(keccak256(abi.encodePacked(_seed, blockhash(storedBlockNumber))));
        // Insert logic for usage of random number here;
        seedSet = false;
        betsClosed = false;
        
        emit notification(random);
    }
}
~~~

ざっくり解説

このコードで重要なのは以下の１文だけです。

~~~
uint random = uint(keccak256(abi.encodePacked(_seed, blockhash(storedBlockNumber))));
~~~

引数で渡された値と内部で保持しているブロック番号を使ってハッシュ値の計算をしています。
そのハッシュ値をuint型に変換しています。

確かにこのやり方なら乱数っぽい値が取得出来そうです。

実際にハッシュ値をuintに変換すると、とんでもなくデカい数値になります。

~~~
43024703909572343858825294292226971941482925166023036904538878067806496940857
~~~

指定した間で乱数を生成したい場合、

~~~
random % 10;  //0~9の乱数
random % 100; //0~99の乱数
~~~

このように１０で除算した余りを取得すれば出来そうです。

# 感想
乱数生成がスマートコントラクトの思想的に良いか悪いかは判断が出来ませんが、ハッシュの特性を考えると疑似的に乱数を生成することが出来そうです。
参考にしたサイトにも記載されていましたが、ゲームなどでは使うことがあるかもしれませんね。
SSL routines:ssl3_get_record:wrong version number

#問題

```
SSL routines:ssl3_get_record:wrong version number:../deps/openssl/openssl/ssl/record/ssl3_record.c:332:\n'
```

serverless offline startにて、上記エラー発生


#解決
自PCのlocalhost:8000のDBに接続しに行っており、どうやらダメらしい
下記のようにリージョンがlocalhostになっていないか確かめる必要あり
https://kcf-developers.hatenablog.jp/entry/2018/10/11/114516
Remixでbyte32型の引数に値を設定する

# 記事の内容
Remixでbyte32型の引数に値を設定する方法です。
考えてみれば当たり前の内容ですが、地味に解決に時間を要してしまったのでメモ

# 失敗例
実装はこんな感じのコントラクトを呼び出そうとしています。

~~~
function reveal(bytes32 _seed) public payable returns(uint){
~~~

uintだと普通に「100」とか設定して通りますが、byte32で「"0x64"」だと以下のエラーが出力されます。

~~~
transact to Randomness.reveal errored: Error encoding arguments: Error: invalid bytes32 value (arg="", coderType="bytes32", value="0x64", version=4.0.44) 
~~~

# 解決策
考えてみれば当たり前な内容ですが、以下の設定方法で解決

~~~
"0x0000000000000000000000000000000000000000000000000000000000000064"
~~~
【Unity】 スクリプトの説明【入門編#1】

おい、ここは、ニセコイのクロード(玄人(くろうと))がくるところじゃねーよ！
だって、だって、だって、、、入門だから！！(灬˘╰╯˘灬)

#スクリプトの追加方法
今から、Unityを始めるあなたへ！
C#スクリプトを***Project***タブで追加してみよお！！
![Project](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/595600/be849b8e-2809-b3ea-70bc-211ebf8bc97c.png)
(色々ごちゃごちゃしてるのは、僕が追加したAssetなので、関係ないですww)
まず上ら辺にある***Create***ってやつを押したら、なんか、ズラあああって出てくるはず！！
出てきたら、上ら辺にある***C# Script***ってやつを押してね！そしたら、NewBehaviourScriptって書いてあるスクリプト(Script)が追加されます！これは、名前なのでそのスクリプトに何を書くのかを簡単に名前にしましょう！
##スクリプト名についての注意事項
- 日本語はだめ！中国語も！韓国語m...って全部言わせる気かよ！英語と数字(かな文字の数字はだめ)のみです！
- 空白はだめ！例えば、apple penって書くときに、空白になるやん！さっき、お前、"これは、名前なのでそのスクリプトに何を書くのかを簡単に名前にしましょう！"って言ってたやん！俺、このスクリプトに、apple penの内容書くのに！って人、いますよね！そんな時は、空白を使用せずに、大文字を使用しましょう！ApplePenとか！
- スクリプトとスクリプト名(スクリプトの名前)は一致させよう！
**これをしないと、エラーが出るよ！**

##スクリプトの中
さて、プログラムを書く部分のスクリプトを開いてみましょう！ダブルクリックで開きます！


```FirstScript.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class FirstScript : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        
    }
}

```


まず、上の三つの意味は、***using*** = ***使う*** なのでこの三つを用います！！ということです！
例えばこれに`using UnityEngine.UI;`を追加すると、UI(ボタンとか、イメージとかのこと)をスクリプトで操作できます！

```ScoreText.cs
using UnityEngine;
using System.Collections;
using UnityEngine.UI;

public class ScoreText : MonoBehaviour {


    public int score = 0829;

	void Start () {
	
	}
	
	// Update is called once per frame
	void Update () {
        this.GetComponent<Text>().text = score.toString();
	}
}
```

これを書いて、UIのテキストを追加して、スクリプトと繋げると、0829と画面に出ます！

でも、今は、入門なので、これやってとかのコメントを頂いた場合により、やります！

で、次は、さっきのスクリプトの、
    `void Start(){
        }`
この部分では、初期セットアップをするよ！
わかりやすく言うと、最初にしなければいけないことです。
例えば、`HPをMAXにしておく`とかをするのだ！

で、次は、
    `void Update(){
    }`
この部分では、Unityが画面を更新するごとに呼び出されるよ！
例えば、`攻撃をする`ということを毎フレームごとに更新するのだ！

#まとめ
- 最初は、自分でプログラムを書いていたら、ほぼエラーが出ます。でも、unityを使いこなしていったら、エラーが出ても、自分で治せるようになります。(英語が得意な人は、すぐ、エラーが何をいっているのかわかるよ！俺みたいに！)
- プログラミングは、自作のゲーム、アプリ開発ができるので、めっっっっっっっちゃいいよね！！！
- 最後は、みんなにお知らせがあるよ！！
- 俺は、イケメンだということです。

もし、この使い方わかんなーい！っていう人や、このゲームの作り方のやつやって欲しいです！っていう人がいるなら、コメントによろしくお願いいたします！！
でも、 Qiitaのアカウント持ってないって人は、ツイッターで、DMお待ちしておりまーす！
git clone したら、Permission denied (publickey).のエラー

# 事の発端
git clone したら、

```
Permission denied (publickey).
fatal: Could not read from remote repository.
```
とエラーが表示されました。

## 動作環境
クライアント側はMacOS
サーバ側はgithub

## 前置き
以下のサイトを見ても解決出来ない状況でした。
http://tusukuru.hatenablog.com/entry/2018/08/29/021651
結果として、鍵の設定自体は変更しないで解決できます。

# ~/.ssh/ のディレクトリの状況
.sshのディレクトリは、過去に別のサーバ等でsshの設定がいくつか存在しているので、以下のようになっています。

```
~/.ssh --- config　　　　　　　　　←このconfigファイルを修正しましょう
        |- id_rsa_sample1
        |- id_rsa_sample1.pub
        |- id_rsa_sample2
        |- id_rsa_sample2.pub
        |- known_hosts
```
(先に書いておくと、秘密鍵の名前を id_rsa_sample1 から id_rsa に変更したくない。変更しないでエラーを解消したいということです。)
また、githubに2アカウント持っていて両方ともsshで接続したいという状況です。 

## ~/.ssh/config の内容
以下のようにconfigファイルを設定して下さい。

```
host github-sample1
  hostname github.com
  IdentityFile ~/.ssh/id_rsa_github_sample1
  User sample1

host github-sample2
  hostname github.com
  IdentityFile ~/.ssh/id_rsa_github_sample2
  User sample2
```
ポイントは、host github-sample2のハイフンです。
host github-[ユーザ名] です。

# 実行したコマンドと、エラーの表示内容
```
$ git clone git@github.com:[アカウント名]/[リポジトリ名].git

Cloning into '[リポジトリ名]'...
git@github.com: Permission denied (publickey).
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.
```

### エラー発生時の状況
$ ssh -T git@github-sample1 を実行しても
Hi sample1! You've successfully authenticated, but GitHub does not provide shell access.
と表示される (つまり、sshの接続はできている)のに、sshで git cloneでき〜ん。 
ヽ(`Д´)ﾉ 「もうわからーん！！！」

# エラーの原因
~/.ssh/config の設定でgithubに2アカウントでもログイン出来るようにするための設定をしていたため、git clone git＠github.com:[アカウント名]/[リポジトリ名].git と実行したのが、sshで接続出来ない原因でした。

# 正解のコマンド
```
# ↓ これが正解
$ git clone git@github-sample2:[アカウント名]/[リポジトリ名].git

# ↓ これだとエラー
$ git clone git@github.com:[アカウント名]/[リポジトリ名].git
```

つまり、~/.ssh/config の内容を設定している場合、githubで標準で表示される以下のような
git clone git@github.com:[アカウント名]/[リポジトリ名].git
だと、タイトルのようなエラーが出る。

# sshで接続する確認
```
$ ssh -T git@github-[アカウント名]
つまり
$ ssh -T git@github-sample2

Enter passphrase for key '/Users/xxxxx/.ssh/id_rsa_github': 
Hi sample2! You've successfully authenticated, but GitHub does not provide shell access.
```
このようにして、ssh接続の確認ができます。


# まとめ
解決方法として、① ~/.ssh/config の内容を修正して 1アカウントのみでsshの設定を指定する、② $ git clone git@github .com ではなく、 git clone git@github-sample2 としてコマンドを実行する、③ 秘密鍵の名前を~/.ssh/id_rsa に変更するか、の３択だと思われます。
Rails migrationで指定できるデータ型

##概要

railsではdb:migrationでmigrationファイルに記述されたデータ型をRDBに追加できる。

今回はmigrateに定義できるデータ型の種類についてまとめていこうと思います。

##そもそもmigrationって何？
rails側からDBの設定（カラム、テーブルなど）を変更するためのファイル。

migrationを使うことでSQL文を使うことなく、DBの設定を変更することができる。

##migrationコマンド

```
rails g migration sample
```

上のコマンドを打ち込むことでdb/migrateにsampleクラスのmigrationファイルが作成される。


```[migration作成日時].rb
class CreateSamples < ActiveRecord::Migration[5.2]
  def change
    create_table :samples do |t|
      t.strings :name
      t.timestamps
    end
  end
end
```

こちらが作成されたmigrationファイル。

tの後に続いているstringsやtimestampsがデータ型になる。

##migrationで指定できるデータ型は？

migrationはあくまで**rails側で行うDBの操作**

**Mysql2などで使えるデータ型の中にはmigrationで指定できないものもある。**

- string
- text
- integer
- binary
- boolean
- date
- datetime
- time
- timestamp
- decimal
- float
- primary_key

以上がmigrationで指定できるデータ型になります。