OmniAICreator/Qiita-1.07M huggingface dataset:
Googleでのソーシャルログインを簡単に試してみる

APIの開発でGoogleログインを実装する必要がありました。
無知な私は当初、「画面(フロントサイド)がないとすぐ確認できないんじゃん？」と尻込みしていたわけですが。
意外と簡単に機能を試すことができたので、その手順を残しておきます。

## 前提
- googleアカウント取得済み
- 開発段階でgoogleログインの動きを確認したいレベル
- googleアカウントからemail情報を取得するのを目標とする


## Googleログインに必要な情報を設定する

- クライアントID
- クライアントシークレット
- リダイレクトURI

Googleログインの一連の流れを実現するために上記を設定・取得します。
私は個人のGoogleアカウントを使って試しましたが、組織のアカウントでも基本的に問題はないのではないかと思います。
今回の範囲では、特に課金の要求などはありませんでした。

### 1. プロジェクトの作成を行う
-  下記のURLの`プロジェクトを作成` ボタンから

https://console.developers.google.com/cloud-resource-manager

- プロジェクト名は自分が分かればOK
- 以下のような画面になればプロジェクトの作成は完了
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390780/55c1bd41-04de-6fa1-862d-49056cc1181d.png)


### 2. 認証情報を設定する
- メニューの`APIとサービス > 認証情報`より認証情報設定ページへ
- `認証情報を作成`ボタンから`OAuth クライアントID` を選択
- アプリケーションの種類を選んだら下記のような画面になる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390780/5d9499f7-226a-c6d6-3264-7307739893e5.png)
- 名前
  - わかりやすいもの
- 承認済みのリダイレクトURI
  - とりあえず試してみたい段階であれば、
      - googleの`https://www.google.co.jp/` を使わせてもらう
      - `http://localhost/`(動いている場合)
  - 本番運用するならきちんとしたURIを設定してください
- `作成`ボタンを押すと、「クライアントID」「クライアントシークレット」が取得できる

### 3.OAuth同意画面を設定する
- `APIとサービス > OAuth同意画面`より設定ページへ
  - ここで設定する内容が、よくソーシャルログイン画面で見る「〇〇が次の許可をリクエストしています」の画面に反映される
- アクセスできるユーザーのデータは、デフォルトでは「email」「profile」「openid」のみの模様
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390780/98afe9a0-9386-f221-1ec4-e195781cf119.png)
- `保存`ボタンを押して設定完了


## GoogleのAPIにアクセスする
設定が完了したので、実際に動きを確かめていきます。

### 1.codeの取得
- 以下のURLを組み立ててアクセスする
  - `https://accounts.google.com/o/oauth2/auth?response_type=code&client_id=<クライアントID>&redirect_uri=<リダイレクトURI>&scope=<スコープ>&access_type=offline&approval_prompt=force`
  - スコープには `email` `profile` などが入る(`%20`で複数連結も可能)
     - (参考) https://himakan.net/websites/how_to_google_oauth
- アクセスすると、以下のようなアカウント選択画面に遷移するので、選択して移動する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390780/335f2b5d-3393-1c86-e260-647893448866.png)

- リダイレクトURIに設定したページに遷移するので、`code` パラメータを取得する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390780/1544e19d-24c3-9837-8d8d-d91eb619ec00.png)

### 2.トークンの取得
- 以下のURLにPOSTでアクセスする
  - `https://www.googleapis.com/oauth2/v4/token`
  - Content-Type
     - application/x-www-form-urlencoded
  - Body
     - code:<コード>
     - client_id:<クライアントID>
     - client_secret:<クライアントシークレット>
     - redirect_uri:<リダイレクトURI>
     - grant_type:authorization_code
     - access_type:offline
- curlコマンド打つのは大変なので、 `ARC` というchrome拡張機能を使うのがおすすめ
  - https://chrome.google.com/webstore/detail/advanced-rest-client/hgmloofddffdnphfgcellkdfbfbjeloo?hl=ja
- 成功したら、 `access_token` が取得できる 

### 3.アクセストークンを使ってgoogleのユーザー情報を取得する
- 以下のURLにGETでアクセスする
  - `https://www.googleapis.com/oauth2/v1/userinfo?access_token=<アクセストークン>` 
- 後半の手順1.で設定したスコープの情報が取れれば成功！ 


## 最後に
以上、とりあえずGoogleログインの動きを確認したいよーという場合の実行手順でした。
開発の助けになれば幸いです。

## 参考
https://himakan.net/websites/how_to_google_oauth
https://qiita.com/kite_999/items/bddd62c395f260e745bc
https://developers.google.com/identity/protocols/OAuth2
https://developers.google.com/youtube/v3/guides/auth/server-side-web-apps?hl=ja
laravel view内でjQueryを使おうとしたら「$ is not defined」エラーが出た話

超超まぬけな話です。
同じことをやらかしそうな未来の私のために書きました。

# view内でjQueryを使おうとした
view内でjQueryを使おうとしていました。
jQueryはすでに読み込んであったので、 `@section('script')` からはじめて、スクリプトを書いていました。

```js
@section('script')
<script>
    // jQueryの中身
    $('.hoge').find('.hoge_hoge').blur(function(){
        hogeFunction();
    });
</script>
```
# $ is not defined！！
いざ表示を確認してみると、consoleタブにエラーが出ていました。
「$ is not defined」
jQueryの読み込みがおかしいか、jQueryが読み込まれる前に実行された場合に起きるやつです。

ソースを確認すると、↑に書いたスクリプト文が、`<!doctype html>`より上にいました。
それでjQueryが読み込まれてないのか！そう思い、私はviewのscriptを`window.onload = function(){}`で囲って対応しましたとさ。

そのすぐ後に、そんな対応が不要になりました。

# 原因
`@endsection`がなかった。

```js
@section('script')
<script>
    // jQueryの中身
    $('.hoge').find('.hoge_hoge').blur(function(){
        hogeFunction();
    });
</script>
@endsection // ← これ！！
```

# 結局
付け足したら、window.onloadなど書かなくても普通に動いてくれました。
ソースがおかしいと思った時点で、調べましょう、過去の私。
EC-CUBE4のDBのそれぞれのテーブルにあるdiscriminator_typeとは何なのか

この記事は私の理解を私の言葉で記したもので、情報が正確ではない可能性があります。
正確な情報はDoctrineのドキュメントなどを参考にしてください。

[Doctrineのドキュメント](https://www.doctrine-project.org/projects/doctrine-orm/en/2.7/reference/inheritance-mapping.html)
[ポリモーフィック関連について書かれている記事](https://qiita.com/suguru/items/d6d3ebe7b867c5009231)

EC-CUBE4の開発で `discriminator_type` のカラムをよく見かけるが、あまり深く考えないで使っていました。
新規テーブルを追加するときに少しハマったので調べてみました。

## `discriminator_type` の用途

`discriminator_type` はEntityを継承して拡張するときに利用される
例えばHogeクラスを継承したPiyoクラスを作成する場合は `discriminator_type` に `hoge`, `fuga` などが入り、管理される

## EC-CUBE4での `discriminator_type` 関連の設定

`discriminator_type` に関する設定はEntityにアノテーションで設定できる。
以下のBlockエンティティの例では`@ORM\DiscriminatorColumn()` がそれに当たる。
カラム内の文字列は `@ORM\@DiscriminatorMap()` で設定できる。
EC-CUBE4の場合は `@ORM\@DiscriminatorMap()` が省略されており、省略した場合にはクラス名が小文字になったものが設定される。
例えば以下の例では `block` が設定される。

```php:src/Eccube/Entity/Block.php
    /**
     * Block
     *
     * @ORM\Table(name="dtb_block", uniqueConstraints={@ORM\UniqueConstraint(name="device_type_id", columns={"device_type_id", "file_name"})})
     * @ORM\InheritanceType("SINGLE_TABLE")
     * @ORM\DiscriminatorColumn(name="discriminator_type", type="string", length=255)
     * @ORM\HasLifecycleCallbacks()
     * @ORM\Entity(repositoryClass="Eccube\Repository\BlockRepository")
     */
    class Block extends \Eccube\Entity\AbstractEntity
    {
    }
```

間違っているところがあれば指摘していただけますと助かります。
models_utils.Choices を便利につかう TIPS

# model_utils.Choices

Django, DRFをお使いの皆さん `model_utils.Choices` って使ってますか？
僕たちは便利に使っているのですが、基本的にはステータス管理でよく使います。

こんな感じですかね。

```python
class News(models.Model):
    STATUS = Choices(
        ('DRAFT',     '下書き'),
        ('CHECK',     'レビュー待ち'),
        ('PUBLISHED', '公開'),
    )

    status = StatusField(
        choices_name='STATUS',
        help_text="状態",
        default=STATUS.DRAFT,
    )

    title = models.CharField(
        max_length=1024,
        null=False,
        blank=False,
        default="",
        help_text="ニュースタイトル"
    )

    body = models.TextField(
        null=False,
        blank=False,
        default="",
        help_text="ニュースの詳細"
    )
```

## Choiceの説明（VALUE）って何に使うんだろう？

ChoiceではKEYとその説明を定義出来る（DBにはKEYが保存されている）のですが、この説明をどう使うと便利なのかって良く分からなかったりします。コメントで良いじゃん？って感じです。かつ、このChoiceフィールドはSerializerでそのまま出力するとKEYだけが出力されるので、さらに説明（VALUE）の使いみちがありません。

## VALUEの使いみち

例えば、↑の例で説明すれば、ニュースを管理する管理画面があるとして、その一覧ではステータスを表示したり、ステータス毎に検索したい事があると思います。その画面で `DRAFT` や `PUBLISHED ` ではなく、 `下書き` とか `公開中` とかで使いたいですよね。

そういう時に各プログラマがChoiceの出力シリアライズでKEYとVALUEを返すように都度実装するのはバカらしいので、僕たちはこんな拡張を作って運用しています。

```python
class MyChoiceField(serializers.ChoiceField):
    def to_representation(self, obj):
        choice = getattr(self, '_choices')
        key = str(obj)
        if key in choice:
            return {'key': key, 'val': choice[key]}
        else:
            return {'key': key, 'val': ''}


class MyModelSerializer(serializers.ModelSerializer):
    """
    シリアライザに自動展開されるフィールドを書き換え
    """
    serializer_choice_field = MyChoiceField
```

各シリアライザは MyModelSerializer を継承します。

```python
class NewsSerializer(MyModelSerializer):
    class Meta:
        model = News
        fields = "__all__"
```

これで `status` は key, valueが出力されるようになります。
[Node.js]フォルダを配下のファイルも含めて一括削除する(since 2019)


#Overview

フォルダを配下のファイルも含めて一括削除しようかと思ったら意外と過渡期であることが判明。
ググると古いコードが上位にいるため、2019年以降のフォルダ削除の方法を残しておく。

#Target reader

- Node.jsでフォルダをファイルも含めてスマートに削除したい方。

#Prerequisite

なし。

#Body

##Special thanks

今回はstack overflowの内容をなぞるだけなので、必要に応じてリンク先を確認してください。
Remove directory which is not empty
https://stackoverflow.com/questions/18052762/remove-directory-which-is-not-empty

##Node v12.10以降の場合

この回答がすべて。
https://stackoverflow.com/a/57866165

>
```javascript
fs.rmdir(dir, { recursive: true });
```

APIリファレンス見てみるとrecursiveのオプションはまだ実験段階。
https://nodejs.org/api/fs.html#fs_fs_rmdir_path_options_callback

時が解決するだろうが、問題なさそうならテストコードとともに投入してもいいでしょう。
ちなみに私はGoogle Cloud Functions（以降、GCF）のNode.jsとバージョンを合わせているため、これを試せていない…

##Node v12.10以前の場合

実はメインはこちらで、私の環境はGCFでNode.jsのバージョンがv10（しかもベータ）で使用できない:sob:
stack overflowに載っている再起で削除するのもなんとなく気乗りしない。
パッケージ導入もできることなら避けたい。
そんな中、Rashさんが載せていたOSのコマンド使う案が気に入った。
私のPJはクラウドとローカルの両方で実行可能で、今回のフォルダ削除はローカルのWindows環境でしか実行しない。
GCFもあと半年もすればv12になるだろうからそれまでの間、OSのコマンドでハマるリスクを回避するのがベストだろう。

Windowsのフォルダ削除コマンドrmdirをコールして、hogeというフォルダを削除するサンプルコード。
async関数の未捕縛例外は正常終了するため、catchして終了コードを書き換えている。

```javascript
const util = require('util');
const exec = util.promisify(require('child_process').exec);

(async () => {
    try {
        const path = 'hoge'; // Rewrite to your folder

        const { stdout, stderr } = await exec(`rmdir /s /q ${path}`);

        console.log('stdout:', stdout);
        console.error('stderr:', stderr);
    } catch (e) {
        console.error(e);
        process.exit(1);
    }
})();
```

注意点は以下の二点。

- child_processのexecメソッドはOSコマンドインジェクションのリスクがあるため、フォルダ名を指定可能にする場合には不正なコードが割り込まないようにすること。
- フォルダがないとエラーになるため、呼び出す前にフォルダの存在確認が必要。

#Conclusion

Node v12.10より、フォルダ削除をスマートに行える未来が来ていることを理解した。
APIリファレンスやバージョンアップ時の新機能は抑えないとだめだなと思った次第。
GCFにもv12はよ…

Have a great day!

#Appendices
なし

#References
本体に全て掲載
Docker初心者が、MacとAzureの仮想マシンでDockerを起動するまで

# 背景
Moodleのプラグインを開発するために、テスト環境の構築が必要になりました。

今までは、仮想マシンや開発用のマシン（自分のMacや会社のWindows）でテストしていましたが、
パーミッションのチェック、環境間の違いの調整、Cronの設定の変更などの細々したことが面倒になってきました。

# やってみたかったこと

* Dockerの使い方を知る
* 何ができるのか把握する
* どんな応用ができるか調べる

# やってみたこと
1. Macへのインストール
2. Windowsへのインストール

## 1. Mac へのインストール
まずは、Mac へのインストールですが、こちらは非常にスムースでした。

ダウンロードURL (https://docs.docker.com/docker-for-mac/install/) へ行き、
"Download from Docker Hub" からダウンロードします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/419296/a803b0ea-5c3e-007d-60e3-b46b751069f9.png)

ダウンロードには、アカウントの作成が必要でしたが、無料のようでした（良かった）。
個人のGmailのアドレスを使って、アカウントを作成し、ダウンロード・インストールしました。

## 2. Windows へのインストール
次は、会社のWindowsへのインストールですが、こちらは四苦八苦しました。

### トラブル１: docker-users
インストール後に、いざ開こうとすると、警告が出てきます。 
*'You are not allowed to use Docker, you must be in the "docker-users" group'.*
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/419296/7bce0387-f25c-b7a3-451b-c107bf9faad1.png)

ログインユーザが、"docker-group" のメンバーではないことが原因のようです。

1. コンピュータの管理を、管理者で開き、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/419296/237c4032-4da0-b0d2-5d0e-5cd194bb4810.png)

2. ユーザを追加して、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/419296/3be4d282-6b0e-e027-fd0d-7dadb9f99b4e.png)

3. そして、ログアウト、ログインをすればOKです。

### トラブル２: ネストされた仮想環境
上の手順だけで大丈夫と思ったのですが、更にエラーが...

開発用マシンでは、Azureの仮想マシンをリモートデスクトップで使っていました。
Hyper-Vがデフォルトでは無効になっていたようです。

以下のコマンドで有効化しました。
1. Powershell を管理者権限で開いて、
2. Hyper-V を有効化
```Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V -All -Verbose```
3. Windows コンテナを有効化
```Enable-WindowsOptionalFeature -Online -FeatureName Containers -All -Verbose```
4. Hyper-V を自動起動する
```bcdedit /set hypervisorlaunchtype Auto```
5. パソコンの再起動
```shutdown.exe /r /t 0```

### トラブル３： それでもうまくいかない！！
古いCPUを使っていたことも原因の１つでした。（Hyper-V のサービスのいくつかが起動しない）

以下、Microsoftのページにしたがい、virsion 3 のVMに変更。
 (https://docs.microsoft.com/en-us/azure/virtual-machines/windows/nested-virtualization)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/419296/3d60c799-9de1-7333-8ef9-9181c64c5158.png)

## 起動の確認
無事に起動が確認できました :clap:
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/419296/20b24eab-56dc-6b21-1e54-2e6c76761ebb.png)
プロジェクトマネジメント講座（元スクエニCTO 橋本善久 ）


#はじめに

http://www.jp.square-enix.com/tech/openconference/library/2011/dldata/PM/PM.pdf

2011年のPDFファイル。
上記をたまたま見つけて読んだら、面白かったので記録しておく。

#個人的に印象に残った部分メモ

調査、戦略、設計、計画から
逃げてはいけないのです。

当たり前の準備を地道にやる。
それが不確実性を乗りこなす秘訣です。

・不確実性を減らす
・不確実でもよいことにする（尻尾切りができるようにする）

地図や双眼鏡のメンテナンス

技術検証とバックアッププラン

不確定技術のマトリクス（重要度＊難易度=警戒度）
必ず作れる、たぶん作れる、わからない

商品の価値空間
品質、基本要素数、物量
UIImageを縦横回転させる

# はじめに
Exifを使わない状態でUIImageを縦横ごと回転させる。
例えば、W288*H352をW352*H288かつExifなしに変換したい。
検索すれば回転自体はたくさん出てくるが、
縦横は変わらないものしか見つからなかったため、自分で書き直した。

#参考

[【Swift】切り抜かずにUIImageを回転させる](https://qiita.com/taji-taji/items/4f01273b303edec45d46)

[Swift - UIImageをCoreGraphicsで回転させる](https://qiita.com/mugmug-dev/items/c29de8ae2b838a633512)


# ソース(Swift5)
```swift:rotate.swift

extension UIImage {
    func rotatedBy(degree: CGFloat) -> UIImage {
        let w = self.size.width
        let h = self.size.height

        //写し先を準備
        let s = CGSize(width: h, height: w)
        UIGraphicsBeginImageContext(s)
        let context = UIGraphicsGetCurrentContext()!
        //中心点
        context.translateBy(x: h / 2, y: w / 2)
        //Y軸を反転させる
        context.scaleBy(x: 1.0, y: -1.0)

        //回転させる
        let radian = -degree * CGFloat.pi / 180
        context.rotate(by: radian)
        
        //書き込み
        let rect = CGRect(x: -(h / 2), y: -(w / 2), width: h, height: w)
        context.draw(self.cgImage!, in: rect)

        let rotatedImage = UIGraphicsGetImageFromCurrentImageContext()!
        UIGraphicsEndImageContext()
        return rotatedImage
    }
}
```

# 使い方
uiimage = uiimage.rotate(0) //反時計回りに90度回転
uiimage = uiimage.rotate(180) //時計回りに90度回転
競技プログラミングにおけるインタラクティブ問題の手元検証方法

## 概要

競技プログラミングのインタラクティブ問題でジャッジ疑似コードを書いて提出コードを検証する場合、次のようにすれば良いです。

```bash
$ mkfifo fifo
$ ./a.out < fifo | ./judge  > fifo
```

ここでは、提出コードの実行可能ファイルを `a.out`, ジャッジ疑似コードの実行可能ファイルを `judge` としています。

## 背景

競技プログラミングではまれに「インタラクティブ」な問題が出題されます。

インタラクティブな問題とは、コンテスタントの提出コードとジャッジが対話的に情報をやり取りしてAC/非ACを決定するような形式の問題のことです。

インタラクティブな問題の提出コードを手元で検証するには、提出コードに加えてジャッジの挙動を擬似するプログラムもあわせて書き、ジャッジ疑似コードと提出コードの標準入出力をお互いに接続して実行させる必要があります。これは、所定のデータを入力として提出コードを実行するだけで良い、インタラクティブでない問題での検証と比較すると、やや手間がかかります。

## 詳細

ジャッジ疑似コードは仕様に従って愚直に実装するしかないのですが、「提出コードとジャッジ疑似コードの標準入出力をお互いに接続して実行する」方法については専用プログラムを書く方法以外、あまり広く知られていないように思います。

Unix系OSの対話シェルにはリダイレクトやパイプと呼ばれる標準入出力を操作する仕組みが備わっていますが、

```bash
$ ./a.out | ./judge | ...
```

のようにパイプでつなげたくてもパイプだけでは judge からの出力を a.out の入力に戻すことができません。一旦ファイルを介してデータを中継しようとしても、通常のファイルでは「データが入力されるまで待つ」ことができないので、うまく動きません。

「提出コードとジャッジコードの標準入出力をお互いに接続して実行する」には、再掲になりますが名前付きパイプを利用して次のように実行するのが簡単です。

```bash
$ mkfifo fifo
$ ./a.out < fifo | ./judge  > fifo
```

`mkfifo` は名前付きパイプを作成する基本的なコマンドで、macOS, Linuxを含むUnix系OSであれば、ほとんどの場合デフォルトでインストールされています。 名前付きパイプはその名の通り、ファイルシステム上にファイルとしての名前を持ったパイプです。 Unix系OSのシェル環境におけるパイプ（コマンドラインでは `|` で表されるシェルの特殊な文法）と同様、書き込まれたデータを書き込まれた順に読み出すことができ、読み込み側は書き込み側がクローズしない限り未到着のデータを待つことができます。


## 応用

各プログラムの出力を覗き見したい場合は、適宜 `tee /dev/stderr` を挟むと良いです。

```bash
$ ./a.out < fifo | tee /dev/stderr | ./judge | tee /dev/stderr > fifo
```

次のように、どちらか片方だけに挟んでもOKです。

```bash
$ ./a.out < fifo | ./judge | tee /dev/stderr > fifo
```

```bash
$ ./a.out < fifo | tee /dev/stderr | ./judge > fifo
```

対話の1ラウンドごとに実行を停止して確認したい場合は、例えば次のようにすればOKです。

```bash
$ ./a.out < fifo | tee /dev/stderr | \
      ./judge | tee /dev/stderr  | \
      ( while read x ; do read y < /dev/tty ; echo $x ; done ) > fifo
```

これは、間に `read y < /dev/tty` を挟むことで端末からの入力待ちを実現しています。

さらに、提出コードの出力とジャッジ疑似コードの出力を見分けやすくするには、次のようにしても良いです。
まず出力用ターミナルで次のコマンドを実行します。

```bash
$ mkfio out1 out2
$ ( sed -e 's/^/C: /' < out1 & sed -e 's/^/J: /' < out2; wait)
```

次に別ターミナルで次のコマンドを実行します。

```bash
$  ./a.out < fifo | tee out1 | \
       ./judge | tee out2  | \
       ( while read x ; do read y < /dev/tty ; echo $x ; done )  > fifo
```

## 補足

名前付きパイプが必要なので、 Windows 系OSでは動かないと思います。 WSL 環境ではもしかしたら動くかもしれません。
Basic認証とBearer認証を一緒にすると 403エラーになる

### 背景
- ステージング環境用にBasic認証を導入
- Bearer認証が必要なapiにリクエストするとエラー

### 原因
- corsエラーを回避するためにorigin urlからリクエストを送るようにしている
- Basic認証を導入するとAuthroizationにBasic認証のtokenが設定される

### 解決策
- Bearer認証が必要なURLの場合は、Basic認証を付けない


例)

```
/api apiを送るURL
/^\/(?!api).*$/ 
↓
/apiが含まれるURLを除外する
```

例のようにBasic認証を外したいURLを除外するようにする。
Btreeを雑に書く

# これは何？
OCamlで Btree実装やってみた（やってみた系記事）。

# なんで書こうと思ったか
下記の記事でGo言語によるbtreeの実装があり、おぉ！と思ったのとOCamlで実装したら確か楽に実装できたな、と思ったので。
https://qiita.com/Tommy_/items/6af8f820a3a692e5cde3

# Btreeとは
この記事にまとまっているので、見てね（上と同じ記事やが）
https://qiita.com/Tommy_/items/6af8f820a3a692e5cde3

# 注意
ポエムなので雑に書く。
今後、このようなクソ記事を表示させたくない皆さまに置かれましては、
検索キーワードで "やってみた" を除外すると幸せになれる。

# 一般的？なbtree実装

```
type 'a bt = Empty | Node of 'a * 'a bt * 'a bt
let rec member x bt = 
  match bt with
  | Empty -> false
  | Node (y, left, right) ->
    if x = y then true
    else if x < y then member x left else member x right
let rec insert x bt =
  match bt with
    | Empty -> Node(x, Empty, Empty)
    | Node (y, left, right) ->
      if x <= y then Node(y, (insert x left), right)
      else Node(y, left, (insert x right))
```

`'a bt` は多相ヴァリアントといい、`'a`は任意の型を受け取るためのおまじない。
だから int型でもstring型でも入れれるbtreeができたわけ。

`type 'a bt = Empty | Node of 'a * 'a bt * 'a bt` は btreeを構成するコンポーネントを表現していて、

葉であれば、 `Node (x, Empty, Empty)` といった具合にかける。
ノードであれば、 `Node x, (Node (y, Empty, Empty)), (Node (z, Empty, Empty)) ` といった具体だ。
※これは、ノードがxという値を持ち且つ子にyとzの葉を持つ、という形を表している。

## 実行例
こんな感じで実行できる。`utop[x]> ` はプロンプト。

```
    utop[9]> let bt = Node (3, Node (1, Empty, Empty), Node(4, Empty, Empty)) ;;
    val bt : int bt = Node (3, Node (1, Empty, Empty), Node (4, Empty, Empty))
    utop[10]> member 1 bt ;;
    - : bool = true
    utop[11]> member 2 bt ;;
    - : bool = false
    utop[12]> insert 2 bt ;;
    - : int bt =
    Node (3, Node (1, Empty, Node (2, Empty, Empty)), Node (4, Empty, Empty))
```

# ちょっと変わった実装
こんなふうにbtreeの型を書いてもよい。

```
type 'a t = Leaf of 'a | Node of 'a t * 'a t
```

この時の find と insertはこんな感じになる。

```
exception Node_format_error
let rec find2 v (t:'a t) = match t with
  | Leaf x -> if x = v then true else false
  | Node (Leaf x, Leaf y) -> if x = v || y = v then true else false
  | Node (Leaf x, Node (y, z)) 
  | Node (Node (y, z), Leaf x) -> if x = v then true else
    if x >= v then find2 v y else find2 v z
  | _ -> raise Node_format_error

let rec insert2 v (t:'a t) = match t with
  | Leaf x -> if x <= v then Node(Leaf x, Leaf v) else Node (Leaf v, Leaf x)
  | Node (Leaf x, Leaf y) -> Node (Leaf x, (insert2 v (Leaf y)))
  | Node (Leaf x, Node (y, z))
  | Node (Node (y, z), Leaf x) -> if x >= v then Node (Leaf x, Node ((insert2 v y), z))
    else Node (Leaf x, Node (y, (insert2 v z)))
  | _ -> raise Node_format_error
```

`Node` が `'a t` のタプルで表現されているため、前後のどちらに `Leaf` 型が来るかわからないため、パターンマッチにてごちゃごちゃする必要がある。

型を少ない要素で実装できた分、これを操作するためのmethodが複雑になってしまった。
ただし、データ構造はかなりスッキリした形で見える。

## 実行例
スッキリ見えるではないか！

```
    utop[16]> let t = Node (Leaf 3, Node (Leaf 1, Leaf 4)) ;;
    val t : int t = Node (Leaf 3, Node (Leaf 1, Leaf 4))
    utop[20]> find2 1 t ;;
    - : bool = true
    utop[21]> find2 2 t ;;
    - : bool = false
    utop[22]> insert2 2 t ;;
    - : int t = Node (Leaf 3, Node (Node (Leaf 1, Leaf 2), Leaf 4))
```

# まとめ
特に無し。後で自分のブログに移すかも（その時はちゃんと書く）。
コメントやマサカリ待ってます
DB2_EXTSECURITYが”YES”場合

Windows10にDB2 Connect PEを入れた時の備忘録です。
Windows7からの10への移行で改めて、DB2 Connect PEをインストールしたら、グローバル・レジストリの値が**DB2_EXTSECURITY**が`YES`になっていました。
因みに構成アシスタントは管理者で実行して設定しています。
インストール・オプションの指定が違うせいか、Win7ではレジストリ設定そのものが有りませんでした。
これが原因で、Apacheサービス起動（systemユーザー）のZendServerだと正常なPHPのibm_db2関数が、CLI実行（ユーザー権限の場合ＮＧで管理者権限ならＯＫ）だと軒並みエラーになりました。
```
SQL1031N 指定されたファイル・システムには、データベース・ディレクトリーが見つかりません
```
[その他の変数 - DB2_EXTSECURITY](https://www.ibm.com/support/knowledgecenter/ja/SSEPGG_9.7.0/com.ibm.db2.luw.admin.regvars.doc/doc/r0005669.html)
```
DB2_EXTSECURITY
- オペレーティング・システム: Windows
- デフォルト: YES。値: YES または NO
- DB2 オブジェクト (システム・ファイル、ディレクトリー、および IPC オブジェクト) のロッキングにより、DB2 への無許可アクセスを防ぎます。 問題を未然に防ぐため、 このレジストリー変数はオフにしないでください。 DB2_EXTSECURITY を設定しないと、この値は DB2 データベース・サーバー製品では YES、クライアントでは NO にそれぞれ解釈されます。
```

以下に幾つか解決方法がありますが、最も簡単なのは該当ユーザーに`DB2ADMNS`を追加する事です。
グループ設定後は再起動で問題が解決されます。

- [DB2ADMNS および DB2USERS ユーザー・グループへのユーザー ID の追加 (Windows)](https://www.ibm.com/support/knowledgecenter/ja/SSEPGG_9.7.0/com.ibm.db2.luw.qb.server.doc/doc/t0011930.html)
- [db2extsec - DB2 オブジェクトの許可の設定コマンド](https://www.ibm.com/support/knowledgecenter/ja/SSEPGG_9.7.0/com.ibm.db2.luw.qb.server.doc/doc/t0011930.html)
MySqlのバージョン5.6→5.7に上げたらfixtureがエラーになった

## 事象

DBUnitでfixtureの読み込みをしている箇所で、
MySQLのバージョンを5.6から5.7に上げたところ以下のエラーになりました。

 ```
Fuel\Core\Database_Exception: Column set to default value; NULL supplied to NOT NULL column 'XXXXX' at row 1 [ LOAD XML LOCAL INFILE 'XXXXX.xml' REPLACE INTO TABLE XXX_table; ]
```

## 原因

mysql5.7からstrict modeという厳密モードがデフォルトでONになっていました。
https://dev.mysql.com/doc/refman/5.7/en/sql-mode.html#sql-mode-strict
厳密モードがオフの場合はfixtureの定義がない場合にカラムのデフォルト値をよしなに入れるみたいですが、
オンの場合は値が欠落として扱われるようです。

``STRICT_TRANS_TABLES``

### Mysql 5.7

```
mysql> select @@global.sql_mode \G
*************************** 1. row ***************************
@@global.sql_mode: ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
1 row in set (0.00 sec)
```

### Mysql 5.6

```
mysql> select @@global.sql_mode \G
*************************** 1. row ***************************
@@global.sql_mode: NO_ENGINE_SUBSTITUTION
1 row in set (0.00 sec)
```

## 対策

``STRICT_TRANS_TABLES``を外すか、もしくはfixtureをテーブル定義に合わせて明示的に指定することで解決しました。
ORA-00904: : 無効な識別子です。となった時の対応方法

- 環境
    - SQL*Plus: Release 12.2.0.1.0 Production
    - Oracle Database 12c Standard Edition Release 12.2.0.1.0 - 64bit Production


# 事象 : テーブルを作ろうとしたら怒られた
```sql
SQL> CREATE TABLE ファイルマスタ (
  2      ID          NUMBER(10,0)        NOT NULL,
  3      ファイル名  VARCHAR2(32)        NOT NULL,
  4  )
  5  PCTFREE 5
  6  ;
)
*
行4でエラーが発生しました。:
ORA-00904: : 無効な識別子です。
```

# 原因 : 「,」が余計についているから
日本語を「"」で囲っていないとかいろいろ悩んだがよく見たら気が付いた。
初歩的過ぎてエラーメッセージでググっても見つからなかった・・・
きっとエラーメッセージの「: :」がポイントでカラム名とかがエラーになったら`ORA-00904: 列名: 無効な識別子です。`とか`ORA-00904:列名が無効です。　無効な識別子です。`っていうメッセージになるのだろう。


## 対応 : 無駄な「,」を削除する
```sql
SQL> CREATE TABLE ファイルマスタ (
  2      ID          NUMBER(10,0)        NOT NULL,
  3      ファイル名   VARCHAR2(32)        NOT NULL
  4  )
  5  PCTFREE 5
  6  ;

表が作成されました。
```
X+Yのモーメント母関数がX, Yのモーメント母関数の積ならX, Yは独立か？

## Introduction : モーメント母関数
確率変数$X$の**モーメント母関数**(moment generating function)とは、$M_{X}(t) := \mathbb{E}\left[\exp tX\right]$と定義されます。モーメント母関数を考えるモチベーションの1つは以下の定理でしょう。

**定理** : 確率変数$X,Y$のモーメント母関数が等しいならば、確率変数$X,Y$が従う確率分布は等しい。

要するに、モーメント母関数と確率分布との間には1:1対応があります。この定理は、再生性の証明を行う際など、とてもよく使うものです。

**Remark** : 確率分布によってはモーメント母関数が存在しないような例もあります。代表例はCauchy分布（自由度1のt分布など）や対数正規分布です。


## 1. 問題
ところで、再生性をモーメント母関数を用いて証明する際、以下の命題をよく用います。証明も難しくないので、付せて紹介しましょう。

**命題** : $X,Y$が独立ならば、$M_{X+Y}(t)=M_{X}(t)M_{Y}(t)$が成り立つ。

**証明** : 
$X,Y$が独立であれば$\exp(tX),\exp(tY)$も独立であるため、

```math
\begin{eqnarray*}
M_{X+Y}(t)&=&\mathbb{E}\left[\exp t(X+Y)\right]\\
&=&\mathbb{E}\left[\exp tX\exp tY\right]\\
&=&\mathbb{E}\left[\exp tX\right]\mathbb{E}\left[\exp tY\right]\\
&=&M_{X}(t)M_{Y}(t)
\end{eqnarray*}
```

が従います。■

今回のテーマは、**この命題の逆は成り立つか？**というものです。

**問題** : $M_{X+Y}(t)=M_{X}(t)M_{Y}(t)$が成り立つならば、$X,Y$は独立か？


## 2. 解答
結論から言うと**成り立ちません**。例えば、Flury(1986)による次のような反例が知られています。

**反例** : 確率変数$X,Y$の同時確率質量関数が以下のように定義されているものとします。

|X\Y|1|2|3|
|:-:|:-:|:-:|:-:|
|1|1/9|1/18|1/6|
|2|1/6|1/9|1/18|
|3|1/18|1/6|1/9|

確率変数$X,Y$のモーメント母関数をそれぞれ計算しましょう。確率変数$X,Y$はともに任意の$x,y=1,2,3$に対して$\mathbb{P}[X=x]=1/3$, $\mathbb{P}[Y=y]=1/3$を満たします。これから

```math
\begin{eqnarray*}
M_{X}(t) &=& \mathbb{E}[\exp tX]\\
&=& \frac{1}{3}\exp t + \frac{1}{3}\exp 2t + \frac{1}{3}\exp 3t 
\end{eqnarray*}
```
が成り立ちます。同様に$M_{Y}(t)=\frac{1}{3}\exp t + \frac{1}{3}\exp 2t + \frac{1}{3}\exp 3t$です。

確率変数$X+Y$の確率質量関数は、以下の表のようになります。

|X+Y|2|3|4|5|6|
|:-:|:-:|:-:|:-:|:-:|:-:|
|確率|1/9|2/9|3/9|2/9|1/9|

これから

```math
\begin{eqnarray*}
M_{X+Y}(t) &=& \mathbb{E}[\exp t(X+Y)]\\
&=& \frac{1}{9}\exp 2t + \frac{2}{9}\exp 3t + \frac{3}{9}\exp 4t + \frac{2}{9}\exp 5t + \frac{1}{9}\exp 6t
\end{eqnarray*}
```

が成り立ちます。以上から、$M_{X+Y}(t)=M_{X}(t)M_{Y}(t)$が成り立つことがわかりますが、同時確率質量関数の定義から$X,Y$は独立ではないので反例が構成できたことになります。

## 3. 考察
Fluryの例は、$X,Y$が同じ定義域上の一様分布に従っているとき、$M_{X+Y}(t)=M_{X}(t)M_{Y}(t)$を満たすならば、$X+Y$は三角分布に従っているという事実をヒントに作られています。（この事実は2の計算, モーメント母関数と確率分布の1:1対応から難しくなく示すことが出来ます。）反例を作るためには、

**問題** : $X,Y$が$x,y=1,2,3$を実現値に取るような離散一様分布に従うとき、$X+Y$が三角分布になるような$(X,Y)$の同時分布をすべて求めよ。

を解いて、そこから$X,Y$が独立でないケースを選べばよいわけです。結論だけを述べると、この問題の解となる$(X,Y)$の同時分布は1つのパラメータ$0\leq t\leq\frac{2}{9}$を用いて、以下の形で尽くされます。

|X\Y|1|2|3|
|:-:|:-:|:-:|:-:|
|1|$\frac{1}{9}$|$t$|$\frac{2}{9}-t$|
|2|$\frac{2}{9}-t$|$\frac{1}{9}$|$t$|
|3|$t$|$\frac{2}{9}-t$|$\frac{1}{9}$|

ここで$t=1/9$の場合は$X,Y$が独立なので、それ以外の$t$の値を選べば独立でない例を作ることが出来ます。例えば、$t=1/18$の場合はFluryの例になっているわけです。

**Remark** : 要するに、$X,Y$が$x,y=1,2,3$上の離散一様分布になるような同時分布のパラメータ空間は4次元、そのうち無相関（⇔ $\mathbb{E}[XY]=\mathbb{E}[X]\mathbb{E}[Y]$）をみたすような部分空間は3次元、さらに$M_{X+Y}(t)=M_{X}(t)M_{Y}(t)$をみたすような部分空間は1次元、最後に$X,Y$が独立になるのは1点（0次元）という包含関係になっています。

## Acknowledgement
<a href="https://sugakubunka.com/">すうがくぶんか</a>の伊集院先生とモーメント母関数の話をしていたときに教えてもらった話が、この記事を書くきっかけになりました。いつも面白い話を教えてくれてありがとうございます。
Azure認定資格 AZ-301を取得しました

Azureの認定資格 [ロードマップ](https://query.prod.cms.rt.microsoft.com/cms/api/am/binary/RE2PjDI) のうち、[AZ-301](https://docs.microsoft.com/ja-jp/learn/certifications/exams/az-301?wt.mc_id=learningredirect_certs-web-wwl) を取得しました。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180335/c8127e21-207a-cd86-c129-2d5481ddf262.png)

以前、 [AZ-300](https://qiita.com/shingo_kawahara/items/7d1c217e2588c5a232e3) を取得していたので、合わせ技でAzure Solutions Architect Expertに認定されました。

試験傾向など纏めます。参考になればと思います。

# 試験の傾向は？

* 問題：49問
問題数は毎回変わるかもしれません。私が受けた時は49問でした。
これまでのAssociate試験やMCP試験と同じように「2択問題」「1問1答」「ケーススタディ」は出題されました。各セクションを先に進めると前のセクションに戻ることができません。
AZ-300のときは実技試験にかなり苦労したので今回も覚悟していたのですが、AZ-301は実技なしでした。（実技ありなしってどこかに書いてるのかな？見当たらない...）

* 時間：180分
申込みでは210分になっていますが、そのうち30分は事前の同意書などの時間なので、実際は180分です。

# 試験範囲

* 負荷分散必須要件の特定 (10-15%)
* アイデンティティとセキュリティの設計 (20-25%)
* データプラットフォームソリューションの設計 (15-20%)
* ビジネス継続性戦略の設計 (15-20%)
* デプロイメント、マイグレーション、インテグレーションの設計 (10-15%)
* インフラストラクチャ戦略の設計 (15-20%)

幅広そうですね。具体的にどのサービスを学習すればよいかいまいち分かりません。

# 学習方法

今回時間もなくぶっつけで受けてみたのですが、730点とかなりギリギリでした。
受験後に気付いたのですが、[試験概要ページ](https://docs.microsoft.com/ja-jp/learn/certifications/exams/az-301?wt.mc_id=learningredirect_certs-web-wwl) が変わっており、この試験に必要なMicrosoft Learnが紐づいて表示されています。
これは分かりやすい！

自信がない項目はMicrosoft Learnで学習するのがよさそうです。

# まとめ
180分のうち、80分くらいで終わったので時間は余裕です。
そういえば今回英語表記に切り替えなかったので、試験問題の日本語翻訳精度も上がってきている気がします。

次はAZ-400を目指したいと思います！

# 参考

[Azure認定資格 AZ-203を取得しました](https://qiita.com/shingo_kawahara/items/551ac6b880a4a59e4291)
[Azure認定資格 AZ-300を取得しました](https://qiita.com/shingo_kawahara/items/7d1c217e2588c5a232e3)
基本情報2月の勉強計画

#目標と結果
### 目標
- 基本情報技術者試験ドットコムを活用する。
- 午後問題11分野の中から出来そうな分野を5〜7分野ほど見つける。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/514786/dbfefb23-85dd-e7a4-59dd-ca3c1e2995d4.png)

出典(https://www.ipa.go.jp/about/press/20190124.html)

###確実にやる必要があるもの(高配点)
- 情報セキュリティ(問1)
- データ構造およびアルゴリズム(問6)
- アセンブラ、表計算、Pythonのどれか
    - 対策講座で解説されるのでそれで決めたい

###選択問題、合わせて2問解答
- 5分野中3分野出題(テクノロジ)
    - ソフト、ハードウェア
    - データベース
    - ネットワーク
    - ソフトウェア設計
    - データベース
- 4分野中1分野出題(ストラテジ、マネジメント)
    - プロジェクトマネジメント
    - サービスマネジメント
    - システム戦略
    - 経営戦略、法務

###今後の予定
- 2月
    - 情報セキュリティとアルゴリズムに集中する。
- 3月
    - プログラミング2種類(保険をかけておく)
        - 表計算とpythonかアセンブラ
    - 選択問題はテクノロジ系を重視

### 結果
- 講座を3つ(2日間)受講した。
    - アルゴリズム
    - 表計算
    - アセンブリ言語

# 振り返り
### keep
- アルゴリズムの勉強

### Problem
- 講座がコロナの影響で中止になった
- アルゴリズムが苦手

### Try
- アルゴリズムの勉強
    - 数をこなして苦手意識をなくす。

# 週次計画
###[16週目(02/03)](https://qiita.com/Yuya_nakano/items/2900fd205041ba756573)
###[17週目(02/10)](https://qiita.com/Yuya_nakano/private/f180b23d68c87cd97a68)
###[18週目(02/17)](https://qiita.com/Yuya_nakano/items/7bf80082044c10b3ec8e)
###[19週目(02/24)](https://qiita.com/Yuya_nakano/private/443416a851661cf0f28c)
初めてPythonを学ぶ人は結局どんな環境構築をすればいいのか

SeleniumでGUIテスト自動化をするためにPythonを使いはじめて１年になります。

最初にPythonを学ぼうと思ったときに大きく躓きそうになったのが環境構築。見る本やサイトや動画によって、Pythonのインストール方法が色々ある点でした。

業務で使う場合は別ですが、個人で何か学習をしようという場合の結論としては、「公式のインストーラで入れておけば大丈夫」です。

## Pythonのインストール方法複数

### 【△】Anacondaで入れる

[Anaconda | The World's Most Popular Data Science Platform](https://www.anaconda.com/)

Udemyの動画とか、Webの解説記事とかを見ていると「色々便利なものがついてくるから」「複数のバージョンを入れられるから」「管理するのに便利だから」Anacondaを使ってPythonを入れよう、と説明しているものがあります。

が、わからないうちは使うのやめときましょう。

実際、Python使って２，３ヶ月もすれば、結果的にパッケージの管理やらバージョン違いやらで面倒を経験する機会があります。その面倒を解消するためにAnaconda等を使う、という流れがお勧めです。何もわからない、必要性もわからない、といううちから手出しすると混乱のもとです。

### 【△】pyenvで入れる

Anacondaと同様、ちょっと勉強してみっか！くらいの人は不要です。

お仕事で必要な方はどうぞ。

### 【△】Dockerを使う

たとえば[DockerでPythonの環境構築を行う - すくすくすくらっぷ](https://blauthree.hatenablog.com/entry/2019/07/13/000839)のように、DockerでPython用の環境を作るパターン。

これも最初に選ぶ選択肢ではないです。他の言語とDockerの両方に慣れていて、という方はやってもいいですが、そういう方はそもそもコレ読んでないはずなので。

### 【おすすめ】公式のインストーラで入れる

[Welcome to Python.org](https://www.python.org/)

プログラミング初めてなんです、という方や、いままでJavaずっと書いててRuby触ったことないです、な方はコレが一番迷いがなくてオススメです。

特定のバージョンのみをお使いのPCに入れる、というシンプルな、一般のソフトウェアと同じ方法です。

DockerやAnacondaを勧める情報源の多くは

- バージョンの切り替えができるから
- よく使うモジュールがセットで入るから
- なにかあったときにローカルのPCに影響せずに済むから

などを理由にそれぞれのやり方をお勧めしていますが、全部**こなれてからでOK**です。


## 参考

- [pyenvが必要かどうかフローチャート - Qiita](https://qiita.com/shibukawa/items/0daab479a2fd2cb8a0e7#%E3%83%84%E3%83%BC%E3%83%AB%E3%81%AE%E7%B5%84%E3%81%BF%E5%90%88%E3%82%8F%E3%81%9B)
【Python 初心者メモ】python の文字列、パス操作

python を勉強していて、色々と調べますが、いつも同じことを調べるので、自分用メモ的にまとめようと思います。

初投稿です。何かおかしなことがあれば、ご指摘いただけると嬉しいです。

ここでは、python の文字列、パス関連の関数についてまとめます。

## os.path.join

join() は、配列などを結合してくれる関数として一般的だと思いますが、
os.path.join() は パスをつなげてくれる関数と理解しています。

たとえば、

``` python
osp.join("dir1/", "dir2")
osp.join("dir1",  "dir2")
```

ともに、

```
dir1/dir2
```

を返します。

主な使い方として、以下の2通りがあるようです。

``` python
osp.join(path1,  path2)
osp.join(path1 + path2)
```

引数の先頭に「/」が来ると動作が変わるようです。

``` python
path1 = "path1"
path2 = "/path2"
osp.join(path1,  path2) # /path2 を返す
osp.join(path1 + path2) # path1/path2
 
```

ちなみに、ある本ではこれを使い分けていましたが、その恩恵はまだわかっていません。。。

リストを使いたい場合は、アスタリスクをつけるとよいそうです。
参照：https://www.sejuku.net/blog/64408

python のアスタリスクについては、以下を参照しました。
https://qiita.com/LouiS0616/items/1bbe0a9bb93054f6c380

## format

{} で定義した場所に、format()の引数を置換します。

``` python
print("{} は {} 円です".format("ビール", 1000))
# > ビール は 1000 円です
```

キーワードを指定することもできます。

``` python
print("{item} は {price} 円です".format(price=2000, item="刺身"))
# > 刺身 は 2000 円です
```


dict 型も使えます。

``` python
price_list = {"item":"水", "price":500}
print("{item} は {price} 円です".format(**price_list))
# > 水 は 500 円です
```

## % 演算子

あまり推奨されていないという記述もみられますが、本などの記述であったので、残しておこうと思います。

%s、%i などで定義されたものを、% の後の変数で置換します。
sprintf みたいなものだと理解しています。

``` python
test_template = "%s は %i 円です"
print((test_template % ("ラーメン",1050)))
# > ラーメン は 1050 円です
```

## おわりに

また調べたことを更新していこうと思います。
nuxtでaxiosのbaseURL 設定(dotenv使用時)

nuxt.config.js

ソースに

```
  if (process.env.API_URL) {
    options.baseURL = process.env.API_URL
  }
```

と書いてあるので


/nuxt.config.js の頭に下記定義を追加して

```

require('dotenv').config()
```

.envに

```
API_URL=http://192.168.99.100:8000/api
```

とか書いとけばいいっぽい

nuxt.config.js内の axios {} 内はとくにいじらなくていいっぽい

参考
https://omiend.hatenablog.jp/entry/2019/04/18/191449
Deviseにユーザーネームを追加する方法

初めての投稿です。Deviseにユーザーネームを追加する方法ということでrailsを触っている方なら知っている方も多いと思われますが、自分が分からなくなってしまっていた部分だったので改めてまとめてみました。

#1 Deviseのインストール
まず、RailsにDevise Gemをインストールします。

```ruby:Gemfile
    gem 'devise' #追加
```

```
    $ bundle install
    $ cd [railsアプリケーションのフォルダ]
    $ rails g deivse:user    # usersテーブル作成
    $ rails g deivse:views   # deviseの編集用ビューファイル作成
```

#2 データベースにカラム追加
マイグレーションファイル作成。マイグレートしてデータベースに登録。

```
    $ rails g migration AddUsernameToUsers username:string
    $ rails db:migrate
```

#3 ビューファイル編集
デフォルトのビューファイルにはusernameを追加するフォームがないためそれを追加します。

```erb:app/views/devise/registrations/new.html.erb
    <h2>Sign up</h2>

<%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>
  <%= render "devise/shared/error_messages", resource: resource %>
  
  <%# 以下を追加する %>
  <div class="field">
    <%= f.label :username %><br />
    <%= f.text_field :username, autofocus: true %>
  </div>
  <%# ここまで %>

  <div class="field">
    <%= f.label :email %><br />
    <%= f.email_field :email, autofocus: true, autocomplete: "email" %>
  </div>

  <div class="field">
    <%= f.label :password %>
    <% if @minimum_password_length %>
    <em>(<%= @minimum_password_length %> characters minimum)</em>
    <% end %><br />
    <%= f.password_field :password, autocomplete: "new-password" %>
  </div>

  <div class="field">
    <%= f.label :password_confirmation %><br />
    <%= f.password_field :password_confirmation, autocomplete: "new-password" %>
  </div>

  <div class="actions">
    <%= f.submit "Sign up" %>
  </div>
<% end %>

<%= render "devise/shared/links" %>
```

#4 configure_permitted_parametersメソッド
deviseでは、初期状態で許可されたパラメータのみをストロングパラメータとして設定してあるため、任意で設定したパラメータはこのメソッドを用いて追加する必要があります。

```ruby:app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
  before_action :configure_permitted_parameters, if: :devise_controller?

  protected
  def configure_permitted_parameters
    devise_parameter_sanitizer.permit(:sign_up, keys: [:nickname])
  end
end
```

---

以上でdeviseをカスタマイズしてusernameを追加する方法について説明しました。もちろんこれ以外のパラメーターを任意に設定する際の手順も同じです。
また、そのパラメーターを参照する際には、deviseのuser_idを外部キーに設定してアソシエーション（紐付け）するなどして参照するようにします。これについては別記事で書こうと思います。
iTerm2 + bash でカーソルの単語移動を簡単にする方法

# 動機
bash コマンドラインでは

カーソルを1単語先に進める： `ESC + F`
カーソルを1単語前に戻る　： `ESC + B`

で単語移動ができるが、 **ESCキーを使ったショートカットは押しづらく、連続入力ができない** ので簡単にできるように設定したい。

# 設定方法
![Preferences_と_bash.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114828/0ea2d12e-193e-c7b6-ea70-44754e64ac73.png)

1. [Preferences] -> [Profiles] -> [Profile Name] -> [Keys] の順で選択する
2. [Right Option Key:] を [ESC+] に変更する
※Left Option Key も同じ用に変更するかはお好みで

これで **Option + F/B で単語移動** ができるようになります。

# まとめ
これで長いコマンドを一部だけ修正したいときも簡単

# 参考
[Bashのコンソールで単語移動するショートカット](https://qiita.com/odacoh/items/b94be0deecaaa27b0263)
[【Mac】iTerm2のMetaキー(メタキー)をEscからOption(Alt)に変更する方法](https://qiita.com/nishina555/items/911343f195974faea474)
AutoHotKey で、マウスカーソルの座標を調べる

##概要
グラフィックアプリの操作で欠かせないのが、画面の座標を調べることです。同じ位置にウィンドウを表示させたい時などに、マウスカーソルとAutoHotKey を使って座標を調べ居ます。

##AutoHotKey とは何か
Windows のマウスやキーボード操作などを自動化できるスクリプト

##AutoHotKey のダウンロード

ここからダウンロードしてください。
AutoHotKey
https://www.autohotkey.com/

インストール方法についてはこちらを見てください。
【Windows】AutoHotkeyのインストール・アンインストール・使い方まとめ！キーカスタマイズにオススメ！
https://clrmemory.com/windows/autohotkey-install-matome/

##現在のマウスの座標を調べるスクリプト
###check_coordinates.ahk

```SetTimer, WatchCursor, 100 ;サブルーチンを指定間隔で実行する
Return
  #Persistent ;スクリプトを常駐状態にする
 WatchCursor:
  CoordMode,Mouse,Screen ; マウスカーソルでスクリーン上での絶対座標をとる
  MouseGetPos, xpos, ypos ; マウスカーソルの座標を格納する
  ToolTip, X%xpos% Y%ypos%. ;ツールチップで現在の情報を表示
Return
ESC::
  ExitApp ; アプリを終了
  Exit ; AHK を終了```

##準備
- Windows で「右クリック＞新規作成＞AutoHotKey Script」で新規にAutoHotKey ファイルを作成します。名前は"check_coordinates.ahk"と付けます。
- 次にメモ帳アプリ(もしくはお使いのテキストエディタ)を開きます。
作成した"check_coordinates.ahk" をメモ帳にドラッグして、テキスト編集できるようにします。
- 上記のスクリプトを貼り付けます。(元からある記述はすべて削除します。)
- 上書き保存して閉じます

##使い方
- "check_coordinates.ahk"をダブルクリックして開くと、マウスの近くにツールチップでその座標が表示されます。
  - 目標の座標を調べてメモに書きとります。
- 終了するときは、"ESC"キーを入力してください。
初心者にWebシステム開発環境をざっくり詰め込む絵

Web初心者を集めてWebアプリを開発することになった。

#状況
 - 今回はAngularとDjangoで開発
 - なんらかのシステム開発経験はある
 - スキルセットがバラバラ

#問題
###初めて聞く用語が多すぎる！
　　- 製品名なのか言語の名前なのか仕組の名前なのか区別できない
　　- それぞれの公式ドキュメントやチュートリアルでは、その関係性が見えづらい


#そこでざっくりした絵
![初心者にWebシステム環境を説明する絵.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/467228/504ea309-4616-a2de-7237-b314e520fc48.png)
　※枠付きはハードや種類を表していて、枠無しは製品名などを表しています。製品名はあくまで例です。

#注意
この絵はイメージを掴むためのものです。
端折っている部分や、厳密に言えば違う部分もあると思いますので、詳しいところはそれぞれの公式ドキュメントを参照してください。
BIGLOBE(mesh.ad.jp)のHOST名が変わったっぽい

`***.○○.mesh.ad.jp` は BIGLOBE の HOST 名です。

これまでは `○○` の部分が、例えば新潟なら `nig` で兵庫なら `hyg` のように県単位で割り当てられていたのですが、2020 年 1 月下旬頃よりこのルールが変わったっぽいです。

私が現在確認しているのは…

- `fl1-***.nig.mesh.ad.jp` ⇒ `flh2-***.tky.mesh.ad.jp`
- `fl1-***.hyg.mesh.ad.jp` ⇒ `flh3-***.osk.mesh.ad.jp`

…といったパターンです。

固定 IP アドレスでアクセス制限をかける事ができず、仕方なくHOST 名で制限をかけているような方はご注意ください。

--------------------------------------------------------------------------------

BIGLOBE 利用者の方で、それまではアクセスできていた管理画面などが急に…

> 403 Forbidden
> You don't have permission to access...

…のようなメッセージが出てアクセスできなくなった時は、上記が原因の可能性があります。

`403 Forbidden` というのは「アクセス許可がない」というエラーですので、アクセス制限をかけている管理者に連絡を取ると良いでしょう。
これから学習される方へ（Rails学習まで）

## これから学習を始める方へ
あくまで一個人の感想ですので参考までに。
Railsまでの勉強と試験を行ったので、後続の方に
少しでもお役立ていただければと思い、今回記事にします（できる人には物足りない内容です。プログラミング学習に不安がある方向けです）。

### 学習の方法論
　👉人それぞれです。
できる人から学習法を教えてもらったとしても、それが必ずしも自身に当てはまるとは限りません。参考程度にするべき。


### 学習の進め方
　👉座学勉強のイメージとは少し違うかも。
ほぼ独学状態でぐんぐん進んでいけるのはある程度のバックグラウンドやセンスのある方かもしれません。
重要事項やどうしても理解できないところは素直に教えてもらったり質問をしましょう。ある概念に対しての自分の認識が合っているのか、ずれていないのか確認するのでもいいんです。そうすることで効率よく学習が進んでいきますし、アウトプットになって頭にも残りやすくなります。


### 学習内容を項目ごとに整理しながら進める
　👉学習を進めていくと、いまどこの何を勉強しているのかよくわからなってしまう、という状況に遭遇します。全くの初学者の場合、特にそうだと思います（自分がそうでした）。
例えば、「□□をするには△△が必要で、いま△△の内容を理解しようとしている。□□は〇〇の中の一つなのだな」のように進めていくと少し遠回りのようですが、
「△△ってこういうものなんだな〜」と漫然と学んでいくことより実は近道です。


## 先生に習おう
　👉ザッキーさんやスナカワさんは皆さんよりもはるかに多くを知っています。
一つの部分の学習にこだわりすぎずに、まずはひと通り学習範囲を網羅してから細部の復習をしよう、と指導してくれてるのもしっかりと理由があってのことなんです。そうすることで以前の学習した内容を上から俯瞰して見ることができます。私たちの疑問点に対する回答もワンランク高い視点で答えてもらえますよね（だからこそ聞き方は失礼のないように）。メンターのメンターが先生です。先生のアドバイスに従って学習を進めていけば絶対大丈夫です！
この記事で少しでも不安が軽減される方がいらっしゃれば嬉しいです！！
もっと先まで学習したあとに、その時の視点でまた記事を書ければと思っております！
Xcode11でCollectionViewの画像がはみ出る件

# はじめに
久しぶりにCollectionViewを使って、写真を横一列表示させようと思ったら、cellサイズをはみ出して表示されてしまい、少しハマったので、備忘録として...

# 参考
- https://stackoverflow.com/questions/59181037/uicollectionviewlayout-not-working-with-uiimage-in-swift-5-and-xcode-11
- https://stackoverflow.com/questions/56840665/why-on-xcode-11-uicollectionviewcell-changes-size-as-soon-as-you-scroll-i-alre

# 環境
- Xcode11.3
- Swift5

# 現象
こうしたい！
![スクリーンショット 2020-02-03 10.28.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/9961/4ea746ea-36d7-1bc9-930d-33dd4a6d0a00.png)

のにこうなってしまう
![スクリーンショット 2020-02-03 10.28.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/9961/818bb739-a4a9-c821-6569-4e372198ba78.png)

# 確認
- UIImageViewのContent Modeは「Aspect Fill」
- Clip to BoundsはTrue

# 修正方法
Collection Viewのinspector内のEstimate Sizeをnoneにする。
これだけ....

![スクリーンショット 2020-02-03 10.54.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/9961/643186f2-c0b7-bff5-60a2-32c5c2978a9d.png)
Ruby　コーティング規約について　構文編　1

# はじめに
[レイアウト編はこちらをクリック願います。](https://qiita.com/raigakun/items/7416db5b4d70ea93046e)
Rubyの基礎を学習中の方に向けて記載致します。
私自身これからチーム開発を行う上で大事にしたい。知っておきたいことをOutputします。

#構文について
① 条件式の周囲を括弧で括らないようにする。
　　私はこれをしておりました・・・

```qiita.rb
#悪い例
if (x > 10)
  # 処理省略
end

# 良い例
if x > 10
  # 処理省略
end
```

② 判定メソッドを使う。

```ruby:qiita.rb

# x = 数字とし、偶数か奇数かを判定したい時

# 悪い例
if x % 2 == 0   # 偶数と判定できるが・・・
end

if x % 2 == 1   # 奇数と判定できるが・・・
end

# 良い例 
if x.even?     #偶数か判定できる。evenが4文字なので、偶数と覚えました。
end

if x.odd?      #奇数か判定できる。oddが3文字なので、奇数と覚えました。
end
```

#さいごに
毎日更新します。
皆様の復習等にご活用頂けますと幸いです。
Oculus Quest で ハンドトラッキング を実装する方法（手のコントローラーを出すまで）

<img width="50%" alt="スクリーンショット 2020-02-03 12.49.28.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264248/f6073e64-790a-26c1-fd9a-afd1fd1c4d6b.png">

# はじめに
Oculus Quest でハンドトラッキングを実装するために
まずはアプリに手を出すところまでの方法です。

この記事を読めば、
ハンドトラッキングとコントローラーを表示するだけの簡単なアプリを作成し、
Oculus Quest にインストールできます。

色々な方が既に記事にしてくださっているので
ほぼそれをなぞっていくだけの簡単な作業です。

# 環境
* macOS Catalina 10.15.2
* Unity 2019.2.16f1
    * Oculus Integration 12.0
* Oculus Quest 12.0.0.226.469.188362025

# 事前の環境設定
まずは ハンドトラッキングを実装する前に
コントローラーを表示する簡単なアプリを作成する。

## Unity で Quest 用にビルドできるようにしておく

@pira さんの良記事をなぞるだけの簡単なお仕事
[Unityで作ったアプリをOculus Questで動かす \- Qiita](https://qiita.com/pira/items/1c935f30d5ba6c020333)


簡単に手順をまとめると

1. Unity で新規に ３D プロジェクトを作成
2. VR（Quest)向けのビルド設定
3. コントローラーを追加
4. ビルドして Quest にインストール

Unity のバージョン違いか設定か、異なる箇所があるので気を付ける点だけメモ

### 異なる点
Build設定 で "Player Settings" をクリックしても
Inspectorウィンドウ に設定項目が出ず別ウィンドウが表示された。

しかもBuild Settings ウィンドウが手前で邪魔…
Android に Switch Platform したら
Build Settings ウィンドウは閉じてOK！

"Player" タブを選択して "Other Settings" と "XR Settings" に
それぞれ設定すべき項目がある。
<img width="75%" alt="スクリーンショット 2020-02-01 14.58.06.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264248/b451f954-73ab-332b-0058-26c4807434d1.png">

Graphics APIs のリストにある "Vulkan" を ➖ボタンで削除する。
<img width="75%" alt="スクリーンショット 2020-02-03 9.53.04.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264248/43b13419-0d6d-8a9b-de1c-4912e8675218.png">

### ハマった点
記事通り進めてもビルドエラーが止まらないので色々試行錯誤するハメに。
どれが効果があったか不明だが、
ビルド環境を最新にして Unity のプロジェクトを新規作成しなおせば解決した。

* Android Studio をバージョンアップ
    * Android SDK Build-Tools をバージョンアップ
<img width="1024" alt="スクリーンショット 2020-02-03 10.11.54.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264248/1602f514-346d-3d1a-7ff4-16f0eea0b5a5.png">

* Visual Studio をバージョンアップ
* Unity はバージョンアップしない
* 上記をすべてバージョンアップ後に、Unity のプロジェクトを新規作成しなおす

# ハンドトラッキングの対応
ついに本題！
これも
めーぷるさん([twitter](https://twitter.com/MapleSyrupCS6)) の良記事をなぞるだけ！
超簡単！

[【Unity】OculusQuestのハンドトラッキングの実装をする〜導入編🐼〜 \- めーぷるのおもちゃばこ](https://www.wwwmaplesyrup-cs6.work/entry/2019/12/29/214958)

簡単に手順をまとめると
1. Hierarchy の OVRCameraRig - Left/RightHandAnchor に OVRHandPrefab を追加
2. RightHandAnchor 側の OVRHandPrefab の設定を Left から Right に変更

OVRCameraRig の 設定を HandsOnly から Controllers And Hands に変更すると
Quest 側の設定によって、コントローラーとハンドコントローラーを切り替えられる。

## おわりに
先人たちのおかげでめちゃくちゃ簡単に手がでました！感謝！
ここまでだと手（コントローラー）が表示されるだけなので
次は手で何かを掴めるようにしたい。

もっと実践的なパフォーマンス調整にこだわりたくなったら
こりんさん([twitter](https://twitter.com/korinVR))の記事を読む 

[Unity＋Oculus Quest開発メモ \- フレームシンセシス](https://framesynthesis.jp/tech/unity/oculusquest/)

Oculus Integration も全部 Import しないで Oculus-VR だけ
インポートするとビルドも高速化できるらしい！

VR 以下のサブのチェック項目がオンにできないんだけど
All 選んでもオンにならないし、そんなもんかな
<img width="347" alt="スクリーンショット 2020-02-03 11.15.49.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264248/a32a3f9d-dcc1-e976-e981-86d9bfb33f22.png">
Nuxtjsの <a> と <NuxtLink> の使い分けについて。

# はじめに
Nuxtjsを使い始めて約６ヶ月経ちました。
使い始めの頃に疑問に思ったことをまとめて行きます

# aとは
HTMLのタグ
リンク飛ぶのに使う。

~~~ a.html
<a href="https://google.com">Googleに飛ぶよ！</a>
~~~

まあHTML書いたことがある人は、誰でも書いたことあるよね
(ちなみにanchorのaらしいです)

# NuxtLinkについて
Vuejsの`router-link`を拡張しているもの
だから`router-link`と同じ使い方ができる。

``` nuxt-link.vue
<NuxtLink to="/sample">サンプルに飛ぶよ！</NuxtLink>
```

# じゃあ明確に何が違うの？
`<a>`は<b>外部ページ</b>、`<NuxtLink>`は<b>内部ページ</b>
と言うことです。
なので、

```nuxt-link-2.vue
<NuxtLink to="https://google.com">Googleに飛ぶよ！</NuxtLink>
```
これは使えないと言うことです。

# NuxtLinkを使うメリット
じゃあ全部`<a>`でよくない？と思いますよね。
僕も思いました。
どうやら<a href="https://ja.nuxtjs.org/api/components-nuxt-link/">Nuxtjsの公式ドキュメント</a>によると・・・
>このコンポーネントは、ページコンポーネント間のナビゲーションを提供し、賢い prefetching（先読み）でパフォーマンスを高めるのに使用します。

とのことです。
なので、同じアプリケーション内に飛ばせる時は、`<nuxt-link>`を使った方が、いいと言うことですね。

# 使い始めに思ったこと

```nuxt-link-3.vue
<template>
<li v-for="(link, i) in links" :key="i">
 <!-- けどここにどうやって書けばいいか分からない。 -->
</li>
</template>
<script>
export default {
 data() {
  return {
   links: [
    { label:"これは内部ページです。", path: '/sample'},
    { label:"これは外部ページです。", path: 'https://google.com'}
   ]
  }
 }
}
</script>
```

これね。すごい困りました。
２つぐらいなら、いいんですけど、`links`が増えてくると、割とだるいループさせたいってなるよね。

```nuxt-link-4.vue
<template>
<ul>
 <li v-for="(link, i) in links" :key="i">
  <template v-if="isInternalLink(link.path)">
   <NuxtLink :to="link.path">{{ link.label }}</NuxtLink>
  </template>
  <template v-else>
    <a :href="link.path">{{ link.label }}</a>
  </template>
 </li>
</ul>
</template>
<script>
export default {
 data() {
  return {
   links: [
    { label:"これは内部ページです。", path: '/sample'},
    { label:"これは外部ページです。", path: 'https://google.com'}
   ]
  }
 },
 methods: {
  isInternalLink (path) {
   return !/^https?:\/\//.test(path)
  }
}
</script>
```

で解決しました。
同じ感じで詰まってる方がいたら参考にしてみてください。

# 終わりに
最近全然書いてませんでしたね。
学校がそれなりに忙しくて忘れてました。
あけましておめでとうございます。
今年の恵方巻きの方角は西南西らしいです。
JavaScript　基礎文法　3

#はじめに
[前回の続きです。](https://qiita.com/raigakun/items/23a0285ab18801498786)
JavaScript(以下、JS)を学んでいく上で、1つずつ整理していきます。
私はVScodeでコードを書き、ブラウザでHTMLファイルを開いております。
そして、検証（ブラウザ上で右クリック）のconsole項目に反映されているのか確認しております。
もうすでにご存知の方、省略の仕方等ご存知でしたら、ご教授願います。




#オブジェクト

[JavaScript 基礎文法 2](https://qiita.com/raigakun/items/23a0285ab18801498786)で記事にしました「配列」は順番でデータを管理します。
オブジェクトは、データを名前と値をセットで管理します。
このセットをプロパティといいます。

```qiita.js

//使用する定義
let 変数 = { プロパティ名: 値 };

//①オブジェクト作成し、出力まで実践してみます。
let obj = { name: "raiga" }; 
console.log(obj);
 
//②プロパティを追加してみます。（ , で追加します。）
let obj = { name: "raiga", age: 5, address: "Fukuoka"};

//③プロパティの値を取得（nameプロパティの取得）
console.log(obj.name);

//④プロパティの値を変更(nameプロパティの変更し、変更したnameプロパティのみ取得)
let obj = { name: "raiga", age: 5, address: "Fukuoka"};
obj.name = "kirin";
console.log(obj.name);
```

【結果】
①コンソールにraigaと出力されているかとお思います。
②の後に、console.log(obj); で出力していれば、全プロパティが出力されているとお思います。
③raigaのみ出力されていると思います。
④kirinと出力されているかと思います。


#繰り返し処理

for文を用います。


```qiita.js
//基本となるfor文(i = i + 1の部分は変数iを1増やすという意味です。)
for (let i = 0; i < 繰り返す回数; i = i + 1) {
  // 繰り返す処理の内容
};


//実践してみます。10回目まで〜回目の出力と表示されるようにコードを記載します。
num = 1
for (let i = 0; i < 10 ; i += 1){
  console.log(num + "回目の出力");
  num += 1
};
```

【結果】
以下、写真のように出力されていれば、成功です。

<img width="1278" alt="40b01961eaeb42e815ea6661c184e942.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/576541/4285a37e-2733-5807-88c5-279b13cd3f91.png">


★【捕捉】
Rubyと同様に、i += 1と表現することも可能です。


#さいごに
日々勉強中ですので、随時更新します。
皆様の復習にご活用頂けますと幸いです。
基本情報16週目(02/03週)

# 目標と結果
### 目標
- 参考書をみる。
- [基本情報技術者試験ドットコム](https://www.fe-siken.com/)を使う。
- 午後で通用する様に内容を理解する。
- 情報セキュリティの勉強をする。

### 結果
- パケットフィルタリング
    - ポート番号(特にメール)の扱い
        - 25、110
        - 転送(25)は自社側とネット側の2パターン必要
    - https://www.fe-siken.com/kakomon/21_haru/pm04.html
- ネットワークセキュリティ
    - ルータの設定
        - どれがどこに繋がるのかを見る
    - https://www.fe-siken.com/kakomon/26_aki/pm01.html
- SSHによる通信
    - 公開鍵
        - セキュリティの目的と効果を覚えておく
    - https://www.fe-siken.com/kakomon/29_aki/pm01.html

# 振り返り
### Keep
- 道場を継続。

### Problem
- なし。

### Try
- 情報セキュリティの勉強をする。
Dockerとは？　Docker初心者　

# そもそもDocekrって何よ？？
![docker_icon.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/522222/d660d946-12b8-27a4-5027-e34685ac399b.png)

・アプリケーションの開発・実行するための仮想環境を作る仕組み

・アプリケーションを「コンテナ」にパーケージングして、デプロイ、実行という流れをコード化できる

・アプリケーションの実行に必要な環境を一つのイメージにまとめて、様々な環境でアプリケーション実行環境を構築/運用するためのもの

・Docker は部品（コンポーネント）から迅速にアプリケーションを組み立てるため、コードの移動による摩擦を無くします。Docker はコードのテストやプロダクション（本番環境）に対する迅速な展開をもたらします。

＊＊自分がわかりやすいのでイメージすると良い！！＊＊

###コンテナって何よ！
![4e6a3a3a6ce12b12fc74df0e4dfea271e9241cb5.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/522222/78231a31-0003-e0a1-6424-74d51b977b6b.jpeg)

アプリ本体、必要なライブラリをパッケージングした物
例：Ruby＋Rails＋Mysql＝コンテナ

#dockerの特長を３つ
###①コンテナ型の超軽量サーバ仮想化製品

OSの内部に独立したアプリケーションの実行
環境＝コンテナを生成することができる
リソース消費量が非常に少なく１台に物理サー
バに多くのコンテナを稼働させられる

##②コンテナ内は実行環境として独立している

コンテナを利用することでOS内に多面の実行環
境を構築することができる
環境も独立しているため、コンテナで分離して
いればファイルやバージョンの競合や、設定や
ポートの競合が回避できる

##③コンテナはリソース消費量が少ない
同一OSのコンテナを多数起動する場合、各コンテナの差
分データのみがハードディスク上に保持されるため、
ハードディスクの消費量が大きく削減できる

#Dockerの仕組み
##①Dockerエンジン
####Dockerそのもの！！
・イメージの生成やコンテナの起動などを行うためのコア機能
・コンテナ実行のプラットフォーム

##②Dockerコンテナ
コンテナとは、ホストOS上に論理的な区画（コンテナ）を作り、アプリケーションを動作させるのに必要なライブラリやアプリケーションを一つにまとめ、あたかも個別のサーバーのように使うことができるようにしたもの！

##③Dockerイメージ
Dockerコンテナを作るためのレシピのことで、このイメージを元にコンテナが生成される。
アプリケーションを実行に必要なファイル群が格納されたディレクトリです。

##④Dockerレジストリ
コンテナの元になるDockerイメージを公開・共有するための機能です！
Dockerイメージを保管しているところ！

#Dockerのメリット
・Dockerイメージがあれば、簡単に環境構築できる


#最後に
私自身が初心者であり勉強中のため、わかりやすくイメージつきやすいようにまとめました。

次回は実際にイメージ生成からコンテナの起動等の動きをまとめてみたいと思います。