OmniAICreator/Qiita-1.07M huggingface dataset:
AWS AppSync + GraphQL + AWS Amplify + Angular

AngularからGraphQLでAWS AppSyncと通信を行う基本方法を記述します

今回はサンプルなのでAWS AppSyncのデータソースはDynamoDBのテーブルを直接参照する形とします。

【前提条件】
　Angular側には既にAmplifyがインストールされていることとする

(1)AWS AppSyncでインターフェースを作成
　(a)AWS AppSyncの「データソース」を選択し、データソース画面を表示する
　(b)「データソースを作成」ボタンをクリックし、新しいデータソース画面を表示する
　(c)以下の通り入力し、「作成」ボタンをクリックする
　　　データソース名・・・適当な名前(ここではsampleとする)
　　　データソースタイプ・・・「Amazon DynamoDBテーブル」を選択
　　　リージョン・・・DynamoDBテーブルのあるリージョンを選択
　　　テーブル名・・・情報を取得したいテーブルを選択
　　　既存のロールを作成または使用する・・・適宜選択
　　　バージョン管理・・・今回は有効化しない
　　　GraphQL を自動的に生成する・・・「ON」を選択する
　(d)AWS AppSyncの「スキーマ」を選択し、Schema画面を表示する
　(e)スキーマの内容を確認し、データ取得リゾルバの定義がされていることを確認する
　　 ここではgetSample、listSampleが生成されているはず

　これでAWS AppSync側はひとまず完了

(2)Angular側でアクセス用プログラム作成
　(a)プロジェクトの直下で以下のコマンドを実行する
　　　　> amplify codegen
　　　→これによりAWS AppSyncにGraphQLでアクセスするクライアント側のコードが生成される
　(b)サーバーアクセス用Service作成

```
    import { Injectable } from '@angular/core';
    import API, { graphqlOperation } from '@aws-amplify/api';
    import * as Observable from 'zen-observable';
    import * as queries from '../../graphql/queries';

    @Injectable {
      providedIn: 'root',
    }
    export class SampleService {
      constructor() {}

      /**
       * HashKeyであるkeyに対応するデータを取得する
       * @param key HashKey
       * @return 取得データ
       */
      public async getSample(key:string):Observable<object> {
        return await API.graphql(graphqlOperation(queries.getSample, {
          key: key,
          })
        );
      }

      /**
       * keyに対応するデータをScanして取得する
       * @param key 検索キー
       * @return 取得データ
       */
      public async getSampleList(key:string):Observable<object> {
        return await API.graphql(graphqlOperation(queries.listSamples, {
            filter: {
              key: {
                eq: key,
              },
            },
            limit: 100,
          })
        );
      }
    }

```
　　※DynamoDBのScanは、通常のRDBのように取得時にSQLで絞り込むのではなく、全検索した後にfilterで絞り込む形となっているためlimitに十分な値を設定しておかないと取得件数ゼロとなってしまう。
　　　またlimitを超えるだけのデータが取得される場合、取得値は空となりnextTokenに値が設定される。

　　filterの演算子は以下を参考
　　　eq    : 等号
　　　ne    : 否定等号
　　　gt    : より大きい
　　　ge    : 以上
　　　lt    : より小さい
　　　le    : 以下

　(c)Serviceを呼び出す側のプログラム作成

```
    export class SampleComponent {
      constructor(private sampleService : SampleService) {}

      ngOnInit() : void {
        this.sampleService.getSample("001").then((h) => {
          const item = h.data.getSample;
          // ここにデータ取得処理を記述
        });

        this.sampleService.getSampleList("002").then((h) => {
          const items = h.data.listSamples.items;
          for (const item of items) {
            // ここにデータ取得処理を記述
          }
      }
    }

```
Ubuntu 16.04でSubversionのGUIベースクライアントを使う

Ubuntu 16.04でTortoiseSVNのような、SubversionのGUIクライアントが使いたい場合、下記のコマンドでインストールできます。
上から順番にコマンドを実行していってください。

```
sudo add-apt-repository ppa:rabbitvcs/ppa
sudo apt-get update
sudo apt-get install rabbitvcs-nautilus
```

上記３つのコマンドを打ったら再起動しましょう。

右クリックのコンテキストメニューに「RabbitVCS SVN」というSVNの機能が追加されます。
cookieについて

【概要】
----------------------------------------
<b>1.cookieとは</b>

<b>2.cookieを保存するプログラム</b>

<b>3.開発環境</b>



1.cookieとは
----------------------------------------

Webサーバーへ接続してきたWebブラウザに対して一連のやり取りや、その状態や情報を維持し管理する仕組みのことです！HTTPはステートレスなプロトコルなので、ステートフルにしたい問題を解決します！
検証ツールで開いて"Application"の"cookies"を開くと、Webブラウザで保存されている情報がみれます！
<br>
2.cookieを保存するプログラム
----------------------------------------

```ruby
<script>
function OnLinkClick(){
  window.location.href = '/';
}
  var btn_b = document.getElementById("btn-mode");
    btn_b.addEventListener("change", () => {
      if (btn_b.checked == true) {
        document.cookie = 'bgcolor=dark; path=/'; 
    dark();
      } else {
        document.cookie = 'bgcolor=light; path=/';
    light();
      }
});
<script>
```
ダークモードを作っている時に画面遷移すると過去の画面設定が外れて(ダークモードにしているのに画面遷移するとライトモードに戻る)しまいます。そのためにcookieでその設定を保存しました。
id要素である"btn-mode"を取得するとcookieにダークとライトを保存するようにしています。checkされていれば"dark"を取得し、されていなければ"light"を取得するようにしています！

参考にしたURL:
<a href="https://yukimonkey.com/data/cookie/">cookieをjavascriptで設定、取得、削除する簡単な方法</a>
<br>

3.開発環境
---------------------------------------
Ruby 2.6.5</br>
Rails 6.0.3.3</br>
Visual Studio Code 1.49.2</br>
2020/10/5朝アウトプット

#Rails 投稿アプリをつくる　ツイートの保存
- 続きから
- フォームからのデータの保存方法に関すること
- ストロングパラメーターの定義に使うメソッド
- requireメゾットとは送信されたパラメーターの情報を持つparamsが使用できるメソッド
- requireメソッドを使うことで、意図しないパラメーターであった場合にエラーとして返すことができ、原因特定やユーザーにエラーを示すなどの対応ができる
- permitメソッドを使用して、カラムに保存したいデータのみにする
- permitメソッドとはparamsが使用可能、取得したいキーを指定でき、指定したキーと値のセットのみを取得する
- プライベートメソッドとはクラス外から呼び出すことのできないメソッド
- メリット２店
- １ classの外部から呼ばれたら困るメソッドを隔離して、エラーを防止
- ２　コードをシンプルにできる

つづく
vue-toastedを使って通知を出す

 Vue.jsにはvue-toastedというプラグインがあり、画面上で通知をだすのにとても便利です。

少ないコードでピョコッといい感じに画面の右上に通知を出してくれます。

![スクリーンショット 2020-10-05 9.24.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47882/84f4acb5-f644-28b5-a593-2ae7096db6fb.png)

# 使い方

```JavaScript
import Toasted from 'vue-toasted';

Vue.use(Toasted, {
  duration: 3000,
  singleton: true
});

// 成功の通知の場合
this.$toasted.success('表示する文章');

// 失敗の通知の場合
this.$toasted.error('表示する文章');

```

簡単なので、ぜひ使ってみてください。
JavaScriptにおける演算子

# 基本

```javascript:qiita&nbsp;motto.js
val = num1 + num2;
val = num1 * num2;
val = num1 - num2;
val = num1 / num2;
val = num1 % num2;
```



```javascript:qiita&nbsp;motto.js
//pi
val = Math.PI;
//Napier's constant
val = Math.E;
//2 四捨五入
val = Math.round(2.4);
//3　切り上げ
val = Math.ceil(2.4);
//2　切り捨て
val = Math.floor(2.8);
//8
val = Math.sqrt(64);
//　絶対値
val = Math.abs(-3);

val = Math.pow(8, 2);
// 最小値のみ出力
val = Math.min(2,33,4,1,55,6,3,-2);

val = Math.max(2,33,4,1,55,6,3,-2);
val = Math.random();
```

1~20の範囲でランダムに出力

```javascript:qiita&nbsp;motto.js
val = Math.floor(Math.random() * 20 + 1);
```
Swift5でUIColorをUserDefaultでローカル保存する方法

#　初めに
アプリの着せ替えなどの機能でユーザがアプリの背景色を選ぶなどの機能があります。
そういった時に色のローカル保存が必要になります。
UiColorなので**あること**をしないとUserDefaultが使えません。
今回はその**あること**を紹介させていただきます。

## 実装
まずは保存側
以下の通りですがシリアライズ化しのちにUserDefaultを使います。


```swift:TestViewController.swift
// UIColorデータをシリアライズ化しユーザデフォルトに保存する
let SaveColor = NSKeyedArchiver.archivedData(withRootObject: UIColor.rgba(red: 97,green: 167,blue: 246,alpha: 1))
UserDefaults.standard.set(SaveColor, forKey: "SaveUIColor")
UserDefaults.standard.synchronize()
```

呼び出し側です。
保存先のKeyにデータが入っているか確認し、デシリアライズし使えるようにするのをやっているだけです。
背景色を変えるコードも入れています。

```swift:MainViewController.swift
if let SetColor = UserDefaults.standard.object(forKey: "SaveUIColor") as? Data {
  // UIColorのローカルデータをデシリアライズし、UIColorローカルデータをUIColorオブジェクトに代入できるようにする
  if let reloadColor = NSKeyedUnarchiver.unarchiveObject(with: SetColor) as? UIColor {
       //背景に保存した画像をセットする
       view.backgroundColor = reloadColor
   }
}

```

#　終わりに
やっていることは簡単です。
今回の**あること**とはシリアライズのことでしたね。
引っ張ってすいません。
シリアライズについては位置情報取得するときとかによく出てくる単語なので説明は割愛させていただきます。
ここまでご視聴いただきありがとうございました。
anyenvでマルチリンガルなプロダクト群に対応する

# はじめに

実際に開発環境を動かしたりする事は無いけれど、
その周辺ツールや、ちょっとした検証で複数のバージョンの複数の言語を使い分けたい事ってあると思います。

> このプロダクトはPHP製なのかー
> フロントエンドのビルドにNode.js使ってる。
> PHPのバージョン\*.\*.\*で、Node.jsのバージョンは\*.\*.\*との事。
> npmの依存関係にPythonが必要で、古めの\*系しか対応してないみたい。

上記のように複数の言語に依存していてかつ、その条件が異なるプロダクトを複数扱う場合などに、
ささっと動かせたら良いのになぁ。というケースはあると思います。

今回は、そんな時に便利なanyenvを使ってみたいと思います。

# anyenvについて

- [anyenv](https://github.com/anyenv/anyenv)
    - [anyenv-install](https://github.com/anyenv/anyenv-install)
    - [anyenv-update](https://github.com/znz/anyenv-update)

各プログラム言語のバージョン管理ツールに`*env`というツールがありますが、
それらを一元管理出来るツールです。

# 実行環境

- macOS: 10.15.7
- anyenv: 1.1.2
    - [goenv](https://github.com/syndbg/goenv): 2.0.0
    - [jenv](https://github.com/jenv/jenv): 0.5.3
    - [nodenv](https://github.com/nodenv/nodenv): 1.4.0
    - [phpenv](https://github.com/phpenv/phpenv): 0.9.0
    - [pyenv](https://github.com/pyenv/pyenv): 1.2.20
    - [rbenv](https://github.com/rbenv/rbenv): 1.1.2

# インストールする

- [Manual git checkout](https://github.com/anyenv/anyenv#manual-git-checkout)

```console
$ git clone https://github.com/anyenv/anyenv ~/.anyenv
$ echo 'export PATH="$HOME/.anyenv/bin:$PATH"' >> ~/.bash_profile
$ echo 'eval "$(anyenv init -)"' >> ~/.bash_profile
$ ~/.anyenv/bin/anyenv install --init # Do you want to checkout ? [y/N]: y
$ mkdir -p $(anyenv root)/plugins
$ git clone https://github.com/znz/anyenv-update.git $(anyenv root)/plugins/anyenv-update
$ exec $SHELL -l
```

ホームディレクトリにanyenvとpluginをインストール
シェルを再読み込み

# 各envをインストールする

```console
$ anyenv install -l
$ anyenv install goenv && \
anyenv install jenv && \
anyenv install nodenv && \
anyenv install phpenv && \
anyenv install pyenv && \
anyenv install rbenv
```

各envをインストール

# 各envでバージョンを管理する

```console
$ goenv install -l
$ goenv install 1.15.2
$ goenv local 1.15.2
$ goenv rehash
$ go version
```

各envの使用方法と同じ手順で、各プログラム言語をインストール

# さいごに

Webアプリケーション向けのモダンなフレームワークだと、依存言語が複数の場合があるので便利です。
※phpenvは、ビルドオプションの指定が必要なのでご注意を...。
【Unity】Visual Effect GraphのPointCacheを使って少しリッチに表現してみる



<img src=https://user-images.githubusercontent.com/144386/94933045-d070e600-0504-11eb-8b9e-8ef5bb2c90ed.png width=450 />

本記事ではVFXGraphを使って馬のメッシュから発生するパーティクル表現を作っていきます。

## メッシュを用意

[![](https://api.assetstore.unity3d.com/affiliate/embed/package/93089/icon)](https://assetstore.unity.com/packages/3d/characters/animals/low-poly-animated-animals-93089?aid=1100lNUQ)

今回は以前Unity Asset Storeで購入していた[LowPolyAnimatedAnimals](https://assetstore.unity.com/packages/3d/characters/animals/low-poly-animated-animals-93089?aid=1100lNUQ)の中にある馬メッシュを使わせてもらいます。

<img src=https://user-images.githubusercontent.com/144386/94930960-1d06f200-0502-11eb-9711-c9e23798b127.png width=450 />

今回はこの馬のメッシュからパーティクルを発生させていくために、**ポイントキャッシュ(PointCache)**を使っていきます。

**※ポイントキャッシュとは、頂点座標や法線情報が焼き込まれたテクスチャです。**

## VFXGraph付随のPoint Cache Bake Toolを使用

任意のメッシュからポイントキャッシュを作成するツールはVFXGraphをインストールすると付いてきます。

![image](https://user-images.githubusercontent.com/144386/94913997-2c2b7700-04e5-11eb-9178-740388d39698.png)

`Window > Visual Effects > Utilities > Point Cache Bake Tool`から`Point Cache Bake Tool`を開きます。


<img src=https://user-images.githubusercontent.com/144386/94936272-ff895680-0508-11eb-9ecf-be89be1d7122.png width=250 />


Meshにポイントキャッシュにするメッシュをセットします。
<img src=https://user-images.githubusercontent.com/144386/94944054-a4109600-0513-11eb-9621-f831cfa953a2.png width=550 />

ここで言うメッシュは、画像のように`Horse_Rig.fbx`の中の`actor:Horse`を使います。

そして`Save to PCache file...`をクリックしてポイントキャッシュファイルを保存します。

## ポイントキャッシュをVFXGraphで使う

<img src=https://user-images.githubusercontent.com/144386/94944622-78da7680-0514-11eb-98ab-54d169d0cd4b.png width=250 />


VFXGraphエディタ上で右クリックして`Create Node`から`Point Cache`を選択してPoint Chacheノードを作成します。

もしVFXGraphエディタの開き方が分からない方はこちらを参考にどうぞ
[【Unity】そろそろVFXGraphを始めてみる](https://zenn.dev/ohbashunsuke/articles/20201001002-helloworld-vfxgraph#5.-visual-effect-graph%E3%82%A8%E3%83%87%E3%82%A3%E3%82%BF%E3%81%A7%E7%B7%A8%E9%9B%86%E3%81%99%E3%82%8B)


<img src=https://user-images.githubusercontent.com/144386/94944822-c2c35c80-0514-11eb-874e-18bf0c02eceb.png width=450 />

Assetに先程作成したポイントキャッシュファイルをセットします。
するとノードの接続プロパティが表示されます。


<img src=https://user-images.githubusercontent.com/144386/94945012-0322da80-0515-11eb-9ac8-116a8a3d4714.png width=550 />

Point Cacheノードの`AttributeMap:Positionプロパティ`を`Set Position from Map`の`Attribute Map`に接続します。

![](https://gyazo.com/387c23b1160d86005e40b708532491f2.gif)

すると、このように馬メッシュ内の各座標が各パーティクルの座標にアサインされ、その座標からパーティクルが発生するようになります。



重要なポイントは今回作られたポイントキャッシュの座標は**頂点座標ではない**ということです。
ポイントキャッシュ作成時に座標が補間される形でベイクされているため今回のような**ローポリモデルでもイイ感じ**になります。これが頂点座標だけだと**スカスカ**な見た目の馬になったでしょう。


という事でポイントキャッシュ凄く便利です。


## 最後に

一応Update Particle Contextノード以降のキャプチャも貼っておきます。

<img src=https://user-images.githubusercontent.com/144386/94945515-c1466400-0515-11eb-8855-17b18f6a2fff.png width=450 />


## 環境

- Unity2020.1.6f1
- macOS Catalina 10.15.5
- Visual Effect Graph 8.2.0


## 参考

[VFX Graph でなんか作る（4月16日号） - Unityステーション](https://www.youtube.com/watch?v=6Ff7S4ocNGs)
[Swift] むしろ初期値の代入に分岐がある場合にこそ、varを避けてletで宣言する意義がある

前提環境：
- Xcode 11.7
- Swift 5.2.4

Swiftに限らず、「変数への再代入を（なるべく）避ける」ことは、安全なコードを書くためのセオリーとして広く理解されています。

関連リンク：
[変数への再代入を避けたいのは何故か](https://qiita.com/jwhaco/items/6851a0a88a35c5a54fc0)

とはいえ実務上、以下のように初期値の代入に分岐があるケースでは、再代入コードは書かざるを得ないと考えがちです。

```swift:サンプルA
// 変数fooは「"hoge" or "fuga"どちらかが初期設定され、以降は変化しない」という意図
var foo = ""
if isHoge {
    foo = "hoge"
} else {
    foo = "fuga"
}
```

上のコードですと、変数`foo`への再代入を防止できません。
`foo`がどこかで ("hoge" or "fuga") 以外の値に設定される可能性が残ります。

上のコードは以下のように改善できます。

```swift:サンプルB
let foo: String
if isHoge {
    foo = "hoge"
} else {
    foo = "fuga"
}
```

**初期化されないパスがある場合はコンパイラがエラーにしてくれます**ので、「いったん初期値を設定したら以降は再代入しない」という意図の場合は、

- 変数の初期化漏れを防止できる。
- 初期化後は値が変化しないことを保証できる。

という点で、サンプルBのコードの方がより安全であると思います。
[iOS] Carthageの読み方

今更な話題、そして取り止めもない話題なのですが…

Swift製のライブラリ管理ツール [Carthage](https://github.com/Carthage/Carthage) の読み方ついて、他社の方と話すたびにお互いに違っていることが多くて戸惑います。
ツール自体は定着して結構経つのに、読み方が統一されていない感じですね（笑

# 「カルタゴ」派

Google翻訳に"Carthage"と入力して日本語に変換すると「カルタゴ」が出ます。
[Wikipediaによると古代都市の名前](https://ja.wikipedia.org/wiki/%E3%82%AB%E3%83%AB%E3%82%BF%E3%82%B4)だそうです。

その辺りの背景で「カルタゴ」派は少なくない印象です。
弊社でも「カルタゴ」と読んでいます。

でも、ちょっと字面から想像しにくい読み方ですよね…

# 「カーセッジ」派

英語の発音を調べますと、カタカナでの発音（の目安）は「カァー（ル）シィヂュ」だそうです。
https://en.hatsuon.info/word/Carthage

それに近い**「カーセッジ」**と読む人は、割と多いような気がします。

"Carthage"という字面を素直に読んでいる感じがするので、「カルタゴ」派の私にも違和感はありません。

でも、こちらの派閥には「カーセージ」などの分派もいらっしゃるようで…

# 結論（？）

日本人にとっては、困った命名をしてくれたもんですね。:sweat_smile:

まぁ文脈で伝わるのでどうでもいいと言えばどうでもいいんですが…
初対面のiOSエンジニアと話す時には、『「カルタゴ」「カーセッジ」どちらで読んでます？』と探りを入れるのが良いかも知れませんね（笑
Djangoを使ったWEBアプリケーションの開発【管理画面からデータ追加編】

管理画面を使ってみる
-
管理画面でアプリケーションが使えるようになったので、実際にデータを追加してみます。
Postの追加からデータの入力画面へ
![データの追加.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/313621/cb69de63-dd49-61a6-7674-911b610199d4.png)
ここでは、models.pyで定義したPostクラスのTitle・Published・Image・Bodyが表示されています。
それぞれに入力しデータを追加します。今回、テスト用で２つのデータを追加。
![追加したデータ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/313621/8e313c05-3fcf-bdbb-28b3-99a6fd8a2c63.png)
２つのデータが保存されました。
次に、追加データの名前が「Post object」になっているので、Titleを表示させてみます。

```models.py
class Post(models.Model):
    title = models.CharField(max_length=100)
    published = models.DateTimeField()
    image = models.ImageField(upload_to='media/')
    body = models.TextField()

    def __str__(self):
        return self.title #管理画面でTitleを表示させる。
```
models.py内のPostクラスにプログラムを追記します。
![Titleを表示.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/313621/5349bce4-3f93-afd5-6f60-4981ec7d7a9a.png)
無事、Titleが表示されるようになりました。
Gitの使い方

#前提条件

- GitHubに既にレポジトリを作成済み
- "first commit"は実施済み
- PCにgitがインストールされている

#手順

1. ステージングする
2. コミットする
3. プッシュする

##ステージングする

例えば、ファイルを更新した場合、以下のようにステージングします。

```bash
git add style.css
```

更新したものを忘れてしまったときは、以下で確認できます。

```bash
git status
```
表示例：

```bash
On branch master
Your branch is up to date with 'origin/master'.    

Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        modified:   style.css
```

##コミットする

ファイルを変更した後は、コミットします。必ずコメントをつけて変更内容がわかるようにします。

```bash
git commit -m "自己紹介のタイトルの下の余白を調整しました"
```

この時点では、まだローカル環境で変更されただけです。

##プッシュする

最後にリモートレポジトリを更新します。

```bash
git push
```
表示例：

```bash
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 8 threads
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 358 bytes | 358.00 KiB/s, done.
Total 3 (delta 2), reused 0 (delta 0), pack-reused 0        
remote: Resolving deltas: 100% (2/2), completed with 2 local objects.
To https://github.com/takeyu1013/portfolio.git
   c312d2e..c0fa916  master -> master
```

このように、`push`の後に何も指定しないと、自動的に`master`に`push`されます。
Dockerのインストール

記事を読んで、「いいじゃね？」って思ったらLGTMお願いします。

# 前提条件
・[公式サイト](https://docs.docker.com/engine/install/centos/)を参考にしています
・CentOS Linux release 7.8.2003 (Core)
・centos-extrasリポジトリが有効になっていること
以下で確認可能

```
$ less /etc/yum.repos.d/CentOS-Extras.repo
```

・古いdockerをアンインストールしていること
以下を実行

```
$ sudo yum remove docker \
                  docker-client \
                  docker-client-latest \
                  docker-common \
                  docker-latest \
                  docker-latest-logrotate \
                  docker-logrotate \
                  docker-engine
```

# Dockerリポジトリを設定する

```
$ sudo yum install -y yum-utils

$ sudo yum-config-manager \
    --add-repo \
    https://download.docker.com/linux/centos/docker-ce.repo
```
これで、`/etc/yum.repos.d/docker-ce.repo`が追加されます。

# Docker Engineをインストールする

```
$ sudo yum install docker-ce docker-ce-cli containerd.io
```
これで、dockerの最新バージョンがインストールされます。
特定のバージョンをインストールしたい場合は以下を実行し、対象を見つけてインストールします。

```
$ yum list docker-ce --showduplicates | sort -r
$ sudo yum install docker-ce-<VERSION_STRING> docker-ce-cli-<VERSION_STRING> containerd.io
```

# Dockerを起動する

```
$ sudo systemctl start docker
```
これで、dockerが起動します。
正常に起動しているかを確認します。

```
$ sudo systemctl status docker
```

# 正常にインストールされているかを確認する

hello-worldイメージを実行して、確認する。

```
$ sudo docker run hello-world
```

以下のような出力がされたら完了

```
$ sudo docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
0e03bdcc26d7: Pull complete
Digest: sha256:4cf9c47f86df71d48364001ede3a4fcd85ae80ce02ebad74156906caff5378bc
Status: Downloaded newer image for hello-world:latest

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (amd64)
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 https://hub.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/get-started/
```
非英語国家ユーザー向け・macOS版LTspiceの罠

# 気をつけるべきこと


## 経由するフォルダと編集するファイルの全ての名前に非ASCII文字を使わない
絶対パスが全てASCIIで表記できるようにしましょう
一度閉じれば**二度と開けなくなる**どころか**上書き保存すらできなくなる**まであります
必ずちゃんと純粋なASCIIを使いましょう

### 検証環境
+ macOS Catalina 最新版
+ LTspice macOS版 最新版

### 検証言語
+ 日本語
+ ドイツ語(非ASCII文字含む)
+ ギリシャ語
+ ヘブライ語


## 原因(妄想)

### ファイル指定用のスクリプトがASCIIのみ対応しているせい
でもなぜか「Save as...(=別名で保存)」だけはできちゃいます
そのせいでこの罠に気づくのに3時間もかかった，悔しいです

### エイリアスはどうか
ファイルを呼び出すだけならエイリアス名は全く関係ないようです
(その場合は絶対パスを取得するだろうし，LTspiceもわざわざエイリアスは使わないと思います)

が，LTspice内の動作として扱うパスの表記に日本語を使うとどうなるかは未検証です，が多分ダメだと思います

### 日本語化パッチについて
2020年度版がなさそうだし本体のスクリプトまでカバーできるかどうかもわからないし日本語で無理にやりたい理由もないので，私は導入するのはやめておきます



# その他 雑記

## macOS版での「μ」
デフォルトで既に「μ」は「u」で入力できるようになっているしちゃんと「μ」で表示されます
Windows版と違い設定は不要です(Windows版は全く知りませんが)

## macOS版で解析実行
「右クリ」→「Draw」→「Spice Directive」→「`(コマンド) (引数1[ 引数2 引数3 ...])`」→「左クリ(配置)」
これでコマンドを埋め込んでRunすると実行されます
Windows版のウィンドウから検索みたいな便利機能はないんですね
解析コマンドはggったら色んなサイトに載ってると思います

## macOS版で素材の参照ファイル指定
色々方法があるっぽいですが
「右クリ」→「Draw」→「Spice Directive」→「`.lib (ファイルのパス)`」→「左クリ(配置)」
とかで呼び出せるらしいです
デフォルトパーツとかだと`User/(username)/Documents/LTspice`と`Applications/LTspice/Resources`から勝手に探してくれるっぽいです
今じゃmacOSが堅すぎてユーザーがそこら辺を弄れなくなったから`User/(username)/Document`にオプションデータを入れて弄ってくださいませという感じでしょうか


## 権限はどうなっているの
LTSpiceに与えられる権限は`User/Documents`だけで，勝手に`examples`フォルダ(デモンストレーション用の回路？)を作るだけっぽいです
それ以外は全てユーザーが逐次に動作させるので問題はないかと思われますが，`examples`は**消しても必ず復活してきます**

## LTSpiceのプロセス名が空欄
これは流石にどうにかして頂きたいなぁと思っています
ちなみに「システム環境設定」の「セキュリティとプライバシー」でもプロセス名が空欄です
~~検索除けかと思っちゃいました~~


## Model Updateが必ずエラーを吐く
`Error downloading release.log.gz`と言われます
SoftWare Updateで全部やるから死に機能になったしサーバーも落としたってことなんでしょうか
旧 MacBook Early 2008 (MB402*/A, MB403*/A, MB404*/A) に Ubuntu MATE 20.04 LTS をインストールする

旧 MacBook の名機、MB402, MB403, MB404 に Ubuntu MATE 20.04 LTS をインストールするというお話です。

### 0. 条件
0.1 セットアップ ディスクを DVD-R に焼いておく。
0.2 メモリは 2 GB 以上。正直、4 GB にしないと厳しいです。
0.3 ディスクはぜひ SSD に換装を。
0.4 有線 LAN につないでおく。

### 1. セットアップ ディスクの起動
18.04 のときは起動するのが大変でしたが、今回は大丈夫。改善されていますね。

1.1 電源を入れたら速攻で DVD を入れて、[option] を押し続けます。

1.2 ブート セレクタが表示されたら、光学ディスクの "Windows" を選んで起動します。

### 2. セットアップ

2.1 "Ubuntu のインストール中にアップデートをダウンロードする" は必ず ON にします。ON にしていればサクッとインストールは終わりますが、OFF だとインストール完了後に言語関連で泥沼にはまって、たぶんその問題を解決するよりも入れ直すほうが楽という結論になるでしょう。

2.2 セットアップは特に問題なく普通に実行できます。残念なことに内臓 Wi-Fi は使えません。"グラフィックスとWi-Fiハードウェアと追加のメディアフォーマットのサードパーティ製ソフトウェアをインストールする" を選んでも使えません。

2.3 インストールの種類では、ディスクを削除してインストールするのがいいでしょう。これ以上に簡単なオプションはないです。

### 3. 内蔵 Wi-fi 用モジュールのインストールにチャレンジするが失敗する

Broadcom ではおなじみのインストールを実行してみます。

```
sudo apt install firmware-b43-installer
sudo apt install bcmwl-kernel-source
reboot
```

これで、ルーターに接続できて万歳と思いきや、Firefox でサイトを開こうとしても開けません。ping を実行するとわかるのですが、パケットの送信ロスが半端なく多くて使えたものではありません。問題が解消される日がくるのかもしれませんが、とりあえずは諦めましょう。

今の時代とあっては、Ethernet to Wi-Fi bridge を使うほうが楽勝かと思います。数千円で買えるし、Macbook は外に持ち出さないだろうし。

### 4. アップデートをやって仕上げます。

```
sudo apt update
sudo apt upgrade
sudo apt autoremove
sudo snap refresh
sudo reboot
```

### 5. 最後に
Wi-Fi の問題を除けば楽勝かと思います。MATE で使っている分には 20.04 になって何が変わったのか見た目では全然わからないというオチがありますが。黒 Mac も換装増設すれば、まだまだ健在で使えるのかもしれません。
IP アドレスとサブネットとCIDR について

# 概要
主に自分の知識の補填のために投稿します。
間違っている部分が多分にあると思われますので、その際はご指摘いただけると幸いです。

## 参考資料
以下を参考とさせていただきました。
[参考資料](https://wa3.i-3-i.info/word11989.html)  
[参考資料]
(https://www.amazon.co.jp/dp/B07L9QXX9J/ref=dp-kindle-redirect?_encoding=UTF8&btkr=1)  
[参考資料](https://www.nic.ad.jp/ja/newsletter/No26/090.html)  
[参考資料](https://www.nic.ad.jp/ja/basics/terms/cidr.html#:~:text=CIDR%E3%81%AF%E3%80%81%E3%82%AF%20%E3%83%A9%E3%82%B9%E3%82%92,%E3%81%8C%E7%94%9F%E3%81%98%E3%81%A6%E3%81%97%E3%81%BE%E3%81%84%E3%81%BE%E3%81%99%E3%80%82)  
[参考資料](https://qiita.com/mogulla3/items/efb4c9328d82d24d98e6)

では下記より本題に入ります。

# Internet Protocol 
Internet Protocol はインターネットに接続されたコンピュータ同士がやり取りするための通信規約。特徴として以下3点。  

1. データを小分けにしてパケットと呼ばれる単位に分割  
2. ルータという機械を通してバケツリレー式に通信している。
3. コンピュータに IP アドレスを割り当てて管理している。  


## IP アドレス
コンピュータの住所や電話番号のこと。一意なもの。 


2進数表記を8ビットごとに四つに区切って10進数に直し、ピリオドで区切った表記が広く用いられます。

```
192.168.0.1 (10進数に直した状態)  
```

IPアドレスにはネットワーク部とホスト部がある。

ネットワーク部 = どのネットワークに所属しているか地域(LAN)の指定  
ホスト部 = どのコンピュータか指定  

```
192.168.0.1 

で言えば、

192.168.0 (ネットワーク部).1 (ホスト部)

訳：
192.168.0 番地にいる 1 番コンピュータ
```


現在 IP アドレスはバージョン４(IPv4)とバージョン６(IPv6)があるが、IPv4 が主流。移行が大変で IPv6 に中々切り替わらない。  

IPv4アドレスは2進数32桁で、アドレス総数は2の32乗個、つまり約43億個。  

## IP アドレスのクラス
使うネットワークの規模によってクラス分けされている。  

※ 以下は IPv4 での説明  

32ビットのアドレスの何ビットをネットワーク部に割り振るかによって、使用できるホスト部（コンピュータ）が上限する。  

クラスには、クラス A, クラス B, クラス C の3つがある。  

クラス A が一番扱えるホスト数が多く、クラス C が一番少ない（254台）  

このように、IPアドレスのネットワーク部とホスト部を決められたブロック単位 で区切る方法をクラスフルという。  

### サブネットマスク

クラス C でも254台のホストを扱えるが、「そんなにいらないから、さらにネットワークを細かくして扱いたい」場合、サブネットマスクを使用してネットワークをさらに細かく分割できる。

サブネットマスクを使用することにより 32 ビットから 2 ビット増えて34ビットの IP アドレスを扱えるようになった。

※ 以下から私が自分で理解するために考えた解釈。

IP アドレスにサブのネットワーク（２ビット分）を被せる（マスク）ことによって、扱える IP アドレスが拡張している。  

サブネットマスクについていろいろ調べたけど、資料によって解釈がいろいろで難しかった。。。

結局よくわからなかったので、私はこの解釈で押し通します。

※以上までが、私の解釈。参考にしないでください。

サブネットマスクを用いると 62 台ずつ4つのサブネットに分割できる。

### CIDR
Classless Inter-Domain Routing  

決められたブロック単位で区切られているクラスフルに対し、ネットワーク部へのアドレスの割り振りが区切らない方法をクラスレス(CIDR)という。

34 ビット中  
(ネットワーク部) : (ホスト部)  
24 : 10  
でもいいし、  
28 : 6  
でもいい。  

クラスを使わない CIDR (クラスレス)では、任意のブロック単位で区切ることができるため、IPアドレス空間を効率的に利用することができる。

#### CIDR 表記
```
198.51.100.xxx/24 ← CIDR
```

上記だと、２進数表現で 24桁目までがネットワーク部でそれ以外がホスト部として使用可能という意味。
AzureでスナップショットからOS領域のディスクを復元する

## AWSとの違い
- AWSではAMIイメージとして取得するものがAzureのスナップショットにあたる
    - ただ、AMIでは仮想マシン構成情報も取得されるが、Azureではそのような機能はない
- Azureでもディスクイメージを取得できるが、それはあくまで汎用化して展開するためのイメージ
    - イメージをキャプチャした瞬間に、VMが破棄される
    - WindowsOSの場合、マシンIDの関係でsysprepをしていないイメージから起動しようとするとできないことがある

## スナップショットを取得
- ディスクを選択し、`スナップショットの作成`を選択する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293481/d0c83b68-1e0a-854e-0a3d-0061b097bb7a.png)

## スナップショットからの復元
- ディスクを作成し、ソースを`スナップショット`変更する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293481/bb5b45d8-fef7-3019-24d7-64f554c29baa.png)

### OS領域の場合、ディスクをスワップする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293481/67d6b032-b457-1564-8257-dcdf33db93d1.png)
Goの変数定義の仕方

# 変数定義の仕方

Bo☆Be☆Ro☆Ku
n番煎じ

```Go:sample.go
// 宣言、代入
var s string
s = "string"

// 型宣言と代入を一緒に
var s string = "string"

// 型省略
var s = "string"

// var省略
s := "string"

// 同じ型で複数宣言
var s1, s2 string
s1, s2 = "s1", "s2"
// 同じ値を代入はNG
s1, s2 = "s"

// 同じ型で複数代入
s1, s2 := "s1", "s2"

// 別々の型複数宣言
var (
  i int
  s string
)

// 別々の型複数代入
var (
  i = 1
  s = "s"
)

```
今日の勉強の記録　コンピュータリテラシについて

1.基本編
　(1)ハードウェア
　　・ハードウェアとはコンピュータを構成する機械的な部分のこと
　　・入力装置からの命令で、主記憶装置内のプログラムが演算装置によって実行され、
　　　制御装置によって、その結果が出力装置に転送される。
　　・制御装置と演算装置を併せてCPUという。
　(2)ソフトウェア
　　・ソフトウェアとはコンピュータの中身のこと
　　・OSはユーザーやアプリケーションとの仲介役を担う
　(3)その他
　　・コンピュータの処理手順のことをアルゴリズムという。
　　　プログラミングをする前に、まずはアルゴリズムを考える必要がある。
　　・アルゴリズムには順次処理、分岐処理、反復処理の３種類がある。
　　・コンピュータは０か１しか認識できない
　　・コンピュータのネットワークは物理的なレベルから、抽象的なレベルまで、複数の階層によって、
　　　構成されている。

2.応用編(ハードウェア)
　(1)CPUについて
　　・CPUが内部で機械語をの命令を実行する時は、
　　　(1)メモリからの読み込み→(2)命令の解読→(3)命令の実行→(4)結果の出力の
　　　順で、行う。
　　　①命令の実行を行う時は、命令を実行する部分であるALUと、データを一時的に記憶しておく
　　　　レジスタに分かれる。
　　・また、CPUは、外部の他に内部にもメモリを持っている。
　　　このメモリをキャッシュメモリという。ある程度の量のデータを、メインメモリから
　　　キャッシュメモリにコピーし、処理を実行する。
　(2)メモリについて
　　・メモリはRAMとROMの２種類に大別される。
　　　①RAM：なんども自由にデータを読み書きできるが、コンピュータの電源が切れるとデータが
　　　　　　　消える。
　　　②ROM：電源が切れてもデータが保存されるが、読み込み専用で書き込みできない。
　(3)補助記憶装置について
　　・補助記憶装置とは、コンピュータ本体の外部に接続して、プログラムやデータなどを記録する装置
　　・外部記憶装置に記憶されたデータやプログラムは、一旦メインメモリに読み込まれ、その後、
　　　CPU内のキャッシュに読み込まれて処理される。このようにして、コンピュータは、
　　　容量とスピードの違う記憶装置を階層的に使い分け、ユーザーにとって使いやすい環境を
　　　実現している。

参照：
http://sevendays-study.com/computer-literacy/index.html
ActiveStorageでアップロードした画像を自前で表示するURLを用意する


## やりたかったこと
WYSIWYなどのエディターで、画像URLを含むHTMLをそのままDBへ保存してrawで表示したかった。

## 問題
直接`service_url`を保存した場合に、アクセストークンが有効期限切れになってしまい、以下のようなエラーが吐かれる。

```xml
https://storage.googleapis.com/xxx/6qk30zadasnfkansfalksj34gq?GoogleAccessId=...

<Error>
  <Code>ExpiredToken</Code>
  <Message>The provided token has expired.</Message>
  <Details>Request signature expired at: 2020-09-30T19:07:20+00:00</Details>
</Error>
```

![スクリーンショット 2020-10-05 2.29.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114895/a3f71759-a43b-8494-e909-5e7c8eeefeaa.png)

## 生成用のURLを用意する
アクセストークン付きのservice_urlを生成して表示するURLを用意するため、アセット用のモデルを作成。


```ruby:asset.rb
class Asset < ApplicationRecord
  has_one_attached :image
end
```

controllerのshowで画像データを送信するように変更。

```ruby:assets_controller.rb
class AssetsController < ActionController::Base
  # GET /assets:id
  def show
    asset = Asset.find(params[:id])
    send_data asset.image.download, filename: asset.image.filename.to_s, content_type: asset.image.content_type
  end
end
```

以下のようなURLをDBに保存することで、アプリケーションのサーバーを経由し、有効期限が切れないで画像を表示することができた。

```html
...
<img src="http://localhost:3000/assets/2" alt="Image">
...
```
集合知プログラミングの理解メモ

# 概要
機械学習アルゴリズムを勉強するため、
『集合知プログラミング』（ISBN-13 : 978-4873113647）を読んだ際に、
プログラム内で出てくる式が何をしているのかがよく分からない部分があったので、
調べた内容をメモに残します。

~~ヘヴィな数学だったのでライトに読むなら追わなくてよかったかも...~~

久々に統計学を勉強しなおしたので、
間違いが多いかもしれません。ご指摘いただけると助かります。


## 6章ドキュメントフィルタリング
### 6.6.2 確率を統合する
- この節は、メールのスパム判定の大詰め
- キーワード（トークン）ごとに、スパムっぽいかの確率が求まっていること前提
- キーワードごとの確率から、フィッシャー法を用いて、ドキュメント全体で見た時にスパムかどうかを計算

----
アルゴリズム ⇒ 著者さんが [githubで公開](https://resources.oreilly.com/examples/9780596529321) してくれています。
個人的に分かりづらかったポイント（下記`(1)`と`(2)`と`(3)`）のメモを残します。


```python
  def fisherprob(self,item,cat):
    p=1
    features=self.getfeatures(item)
    for f in features:
      p*=(self.weightedprob(f,cat,self.cprob))
    
    # (1) ・・・ fscoreとは何を計算している？
    fscore=-2*math.log(p)
    
    return self.invchi2(fscore,len(features)*2)

  # (2) ・・・ invchi2は何を計算している？    
  def invchi2(self,chi, df):
    # (3) ・・・ 逆関数が計算できている？
    m = chi / 2.0
    sum = term = math.exp(-m)
    for i in range(1, df//2):
        term *= m / i
        sum += term
    return min(sum, 1.0)
```

- (1) `fscore` とは何を計算している？
    - [fisher's method](https://en.wikipedia.org/wiki/Fisher%27s_method) によると、`k`個の独立な`p-value`（確率のようなもの）をかけて、`log`をとって`-2`をかけると、自由度`2k`のχ二乗分布の`p-value`が計算できるとのこと
        - ~~証明はまだ追えてないです~~
        - `p-value`については [統計手法のχ二乗検定](https://logics-of-blue.com/chi-squared-test/) などをご参照ください
        - [χ二乗分布の詳細はこちら](https://ja.wikipedia.org/wiki/%E3%82%AB%E3%82%A4%E4%BA%8C%E4%B9%97%E5%88%86%E5%B8%83)

    
- (2) `invchi2` は何を計算している？
    - χ二乗分布の累積分布関数の逆関数
    - χ二乗検定だと`p-value`を求めて、`0.05` より小さい（χ二乗値が十分に高い）場合を基準として判断することが多いようですが、スパムの分類のテーマでは高いスコア＝スパムとしたいので逆関数でχ二乗値（χ二乗分布に従う値）に戻している模様
    - 引数
        - `chi` ・・・ `p-value`（`0 ≦ chi ≦ 1`）
        - `df`  ・・・ χ二乗分布の自由度
    - 出力
        - χ二乗値（χ二乗分布に従う値）。ただし`1`を超えないようにしている。
- (3) 逆関数が計算できている？
    - χ二乗分布の累積密度関数を見てもらうとわかる通り、逆関数が数式で出せないです
    - 逆関数を計算するために、[逆関数定理](https://ja.wikipedia.org/wiki/%E9%80%86%E5%87%BD%E6%95%B0%E5%AE%9A%E7%90%86) を使って微分方程式に持ち込み、べき級数（n次方程式みたいなもの）を使って近似解を得るなどするようです。
    - 累積分布関数の逆関数を精度良く計算す方法は日々研究されている様なので、精度のよい計算手法を採用したアルゴリズムで実装したんだと思われます。
        - `Quantile Chi-Square` などのキーワードで論文を調べると様々な手法が検索できます
        - `Inverse Chi-Square` とすると、逆χ二乗分布 という似て非なるものがヒットするのでお勧めしません

## 関連情報メモ
- フィッシャー法は、日本語論文では Robinson-Fisher方式 と呼ばれている？
- フィッシャー法は、Robinson方式 から求められる
WKNavigationDelegate-decidepolicyfornavigationactionでページ読み込み後に呼び出される時の解決法

# はじめに

[webView(_:decidePolicyFor:decisionHandler:)](https://developer.apple.com/documentation/webkit/wknavigationdelegate/1455641-webview)ではWKWebViewで初期ページを読み込んだり、ユーザーがリンクをタップした時に呼び出されます。
そこでWKNavigationActionにアクセスすることでURLRequestを取得でき、ページ読み込むかどうかを処理することができます。

ではなぜ、タイトルが**WKNavigationDelegate-decidepolicyfornavigationactionでページ読み込み後に呼び出される時の解決法**なのかというとwebView(_:decidePolicyFor:decisionHandler:)では、通常通りloadをviewdidloadなどで行っただけでは、初回だけ読み込み前に呼ばれ、その後のWebPage内遷移ではページ読み込み後に呼び出されることがあります

例としてはYouTubeの動画ページに遷移した場合ではページ読み込み後に呼び出され、Appleではページ読み込み前に呼ばれます。

# 解決法

なぜ読み込み後に呼ばれるかというと、おそらく読み込むURLが相対URLの場合は読み込み前に呼び出されなく、そのページを読み込んだ後に呼び出されます。

例としてはYouTubeの動画ページにタップした時に動画を読み込むまえに呼びだれるようにします

```swift:
import UIKit
import WebKit

class ViewController: UIViewController {

    @IBOutlet weak var webView: WKWebView!
    
    private var _observers = [NSKeyValueObservation]()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        webView.navigationDelegate = self
        webView.load(URLRequest(url: URL(string:"https://www.youtube.com/")!))
        
        _observers.append(webView.observe(\.url, options: [.new, .old]){ [weak self] _,change in
            guard let newValue = change.newValue, let oldValue = change.oldValue else { return }
            guard let newURL = newValue, let oldURL = oldValue else { return }
            
            if newURL != oldURL {
                //読み込み前にDelegateでキャッチしたい読み込み後にDelegateで呼ばれるページの時だけ再読み込みする
                if newURL.absoluteString.contains("/watch"){
                    self?.webView.load(URLRequest(url: newURL))
                }
            }
        })
    }
}

extension ViewController: WKNavigationDelegate {
    func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
        decisionHandler(.allow)
    }
}
```

なのでこのような形でwebViewのURLが変更されるたびに、URLを確認して、oldと違った場合(ページ遷移の場合)再度loadを絶対パスで行い、webView(_:decidePolicyFor:decisionHandler:)でキャッチします。

# まとめ
これで意図した通りに動くようになったのですが、乱暴な解決法ということは否めません。
もっといい解決法をご存知の方いましたら、コメントしていただけると幸いです。

ありがとうございました

# 参考リンク
[wkwebview-decidepolicyfor-gets-called-after-page-loaded](https://stackoverflow.com/questions/61504681/wkwebview-decidepolicyfor-gets-called-after-page-loaded)
【VanillaJS】Nパーセントの確率でtrueを返すメソッド

#これ

```Java
function Nパーセントの確率でtrueを返すメソッド(n) {
    return Math.random() < n / 100;
}
```

必要なら引数の型チェックなり範囲チェックなりしてください。

#チラ裏

何故、Nパーセントの確率でtrueになるのか？
**数学初心者未満**がにわかながら考えてみた。

`Math.random()`は[0, 1)の範囲の値を返す。
※ [a, b)はa以上b未満という意味
面倒くさいのでNは0以上100以下の整数とする。

```math
\begin{align}
[0, 1) &= [0, \frac{1}{100})\cup[\frac{1}{100}, \frac{2}{100})\cup \cdots\cup[\frac{99}{100}, 1)\\
&=\bigcup_{n=0}^{99}[\frac{n}{100}, \frac{n}{100} + \frac{1}{100})
\end{align}
```

[0, 1)内の任意の値は100個ある互いに素な集合[n/100, n/100 + 1/100)(n ∈ {0,1,...,99})のいずれかに含まれる。
そして[0, 1)からランダムに取り出した値（以下takosuとする）が、ある集合[a/100, a/100 + 1/100)(a ∈ {0,1,...,99})に含まれる確率は同様に確からしい。（知らんけど）
このとき、takosuが互いに素なN個の集合[a/100, a/100 + 1/100)(a ∈ {0,1,...,99})のいずれかに含まれる確率は100個の中のN個なので、N/100（※1）
また、takosuがN/100よりも小さい確率は、takosuが[0, N/100)に含まれる確率と同じ。（※2）

```math
\begin{align}
[0, \frac{N}{100}) &= \underbrace{[0, \frac{1}{100})\cup[\frac{1}{100}, \frac{2}{100})\cup \cdots\cup[\frac{N-1}{100}, \frac{N}{100})}_{N個}
\end{align}
```
（※1）（※2）より、`Math.random() < N / 100`はNパーセントでtrueを返す。（証明終了）

多分こんな感じ
Nが無理数の場合の証明とかどうなるんでしょうね。
外部URLに接続時HTTPステータスコード302が発生した時の対応

## 概要
例えば外部のサイトにあるファイルをダウンロードして取ってくるようなプログラムを書く場合、サイトによってはブラウザではダウンロード出来るけど、コードからURL接続するとエラーになるということがあります。実際に、ChromeのDevToolsなどでブラウザでどのようにダウンロード出来ているか確認してみると、アクセスしにいったURLではHTTPステータスコード302が返されてます。
今回はこのHTTPステータスコード302についての対応についてメモ書きします。

## HTTPステータスコード302とは
[HTTPステータスコード「302リダイレクト」とは](https://blog.hubspot.jp/http-302)の記事にある通り、302とは「一時的なリダイレクト」が起こっているとされています。302の場合はブラウザに表示されるURLは変わらないので、DevToolsなどを使用しない限りはユーザはリダイレクトされていることに気付きません。

## プログラムでどうやって対応すれば良いのか
302のレスポンスが返ってくる時に、ヘッダーの`Location`にリダイレクト先のURLが格納されています。そのため、このLocationに格納されているURLに再度接続すれば良い、という対応になります。
[こちら](https://stackoverflow.com/questions/3786161/cant-get-response-header-location-using-javas-urlconnection)のStackOverflowの記事で、Javaでの実装が紹介されています。

## 実装サンプル
上記のStackOverflowの記事のほぼコピーですが、実装のサンプルになります。

```Sample.java
public class Sample {

  // PhishTankからCSV情報を取得
  public void urlSample() {
    try {
      // リダイレクト前のURLに接続
      URL url = new URL("https://xxxx/xxxxxx");
      HttpURLConnection conn = (HttpURLConnection) url.openConnection();
      conn.setInstanceFollowRedirects(false);
      String redirectLocation = conn.getHeaderField("Location");
      conn.disconnect();
      // リダイレクト先のURLで再度接続
      URL afterRedirectUrl = new URL(redirectLocation);
      InputStreamReader in = new InputStreamReader(afterRedirectUrl.openStream());
      // この後は受け取ったデータの処理
    } catch (Exception e) {
      // エラー処理
    }
  }
}
```
[rails] deviseのデフォルトについて

#deviseの導入とデフォルトについて
* deviseの導入
* deviseのデフォルト

##Why
###deviseに関する記事を調べた時にdeviseのコントローラーを作る記事しかなく、<font color="Red">application.controller</font>のみで完結させたかったから。また、その際にdeviseがデフォルトで持つ範囲を知らなく、余計なカラムやvalidationを記述していた為エラーの解決に時間がかかったのでこれを参考にしていただければと思います。
#devise導入
```java:Gemfile(最後の行）
gem 'devise'
```
```java:ターミナル
# 現在のディレクトリが~/projects/pictweetであることを確認
% pwd

# Gemをインストール
% bundle install
```
```java:ターミナル
# サーバーを起動
% rails s
```
```java:ターミナル
# deviseの設定ファイルを作成
% rails g devise:install
```
```java:ターミナル
# deviseコマンドでUserモデルを作成
% rails g devise user
```
###以下のように<font color="Red">devise_for :users</font>が入っていればOK！
```java:routes.rb
Rails.application.routes.draw do
  devise_for :users
  root to: 'tweets#index'
  resources :tweets
end
```
###次はテーブルの作成
```java:ターミナル
# マイグレーションを実行
% rails db:migrate
```
###データベースにテーブルが作成されていればOK!
###最後に下記も忘れずに！
```java:ターミナル
# 「ctrl + C」でローカルサーバーを終了

# 再度、ローカルサーバーを起動
% rails s
```
##これで一通りdeviseの導入が終わったので、あとは好きなように実装するだけです。
#<font color="Red">今回はデフォルトについてです!!!</font>
![c5f52229a3b1938b4297854ebbd2d440.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/725167/b762cb20-bc5d-82c3-9275-d39fd30a0f34.png)
##こちらはあまり関係ないのですが、validatesでname,email,passwordしかかけておらずデータベースを確認するとpasswordの部分が<font color="Red">encrypted_password</font>でカラムとして登録してあります。「validatesにencrypted_passwordがないよ？」と突っ込みたいところですがencrypted_passwordは<font color="blue">パスワードを暗号化してテーブルに保存する</font>というものなのでvalidatesはpasswordをかけるだけでok。ちなみに<font color="blue">password_confirmation</font>とかもvalidatesをかけなくてok。

#話が脱線してしまいましたがこちら
![a23f24d4b5f8cf20bd382f240b123723.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/725167/1bc7d4a8-c8b6-b983-ca2b-248cf7f02f9d.png)
##13行目に注目。
###deviseをインストールすることで<font color="Red">devise_parameter_sanitizerメソッド</font>が使えるようになります。deviseでユーザー登録をする場合に使用でき、「特定のカラムを許容する」メソッドになります。このメソッドに<font color="blue">devise_parameter_sanitizerメソッド</font>を定義します。
##devise_parameter_sanitizerメソッド
###permitメソッドを組み合わせることにより、deviseに定義されているストロングパラメーターに対し、自分で新しく追加したカラムも指定して含めることができます。なのでノーマルな新規登録、ログイン機能くらいであればわざわざdeviseのコントローラーを作らなくてもapplication.contoroller内で完結できちゃいます。（新規登録などで複数ページに渡って遷移させる場合ちゃんとcontrollerを作った方がいい）
```java:application.controller.rb
private
def configure_permitted_parameters  # メソッド名は慣習
  # deviseのUserモデルにパラメーターを許可
  devise_parameter_sanitizer.permit(:deviseの処理名, keys: [:許可するキー])
end
```
##14行目に注目！
```java:application.controller.rb
devise_parameter_sanitizer.permit(:sign_up, keys: [:name])
```
###keys:の後に続く[ ]内に:nameの他に本来<font color="blue">:email</font>や<font color="blue">:password</font>などを入れなければいけません。ですがdeviseのデフォルトで裏で勝手に処理してくれているのでここは<font color="red">:name</font>だけでok!

#余談
##バリデーションのデフォルト解除方法
##これを
```java:application.controller.rb
devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :validatable
```
##こうするだけ！
```java:application.controller.rb
devise :database_authenticatable, :registerable,
         :recoverable, :rememberable
```

#まとめ
deviseは簡単に導入できて、簡単に新規登録やログイン、ログアウト機能を実装できる素晴らしいgemですが、それだけ便利すぎる裏では様々なデフォルトが勝手に反映されてしまって余計なエラーなどが起きやすくなるのでせめてもの簡単なデフォルトの紹介をさせて頂きました。
yukicoder に自動で解答を送信するツールを作った

## 概要
yukicoder の問題にソースコードを提出する機能を持つ、コマンドラインツールを作成した。
https://github.com/koba-e964/contest/blob/7129c735c3e5cfd0e57702ad66748af986296a89/yukicoder/submit.py

## 作成した経緯
もともと提出を手動でやるのが面倒だと思っていた。
yukicoder が API を公開していることを知り、せっかくだから Python での開発の練習がてら自動で提出できるようにしてみた。

## 仕様
### 設定ファイル
`yukicoder_config`: yukicoder 用の秘密情報ファイル (自分のプロフィールの「APIキー (β)」の情報を格納する)

```yaml:yukicoder_config
api_key: 'API-KEY-XXXX'
```

[`languages.yml`](https://github.com/koba-e964/contest/blob/master/languages.yml): 言語ごとの設定情報 (言語名、yukicoder での管理名、拡張子、AtCoder での管理名などを格納する。すべてのジャッジで共用)

```yaml:languages.yml
- name: C++
  extension: cpp
  yukicoder_name: cpp17
- name: Rust
  extension: rs
  yukicoder_name: rust
- name: Python3
  extension: py
  yukicoder_name: pypy3
```

### 使い方

```
./submit.py [問題番号].[拡張子]
```

使用例

```bash
./submit.py 1245.rs
```

![使用例 スクリーンショット](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/67404/0a918c94-1c36-c5b1-ebdf-e570fdc412d8.png)


## 工夫した点
### 設定ファイル
設定ファイルのフォーマットとして、大まかに以下の2通りが存在する:

1. Python の式そのものが書けるようにし、読み込みの際は設定ファイルを直接実行し、必要な値が読まれている状態にする
2. YAML, JSON, TOML, XML などの設定ファイル記述言語で記述する。読み込みの際はライブラリを使用し、設定ファイルをパースして値に変換し、その値から必要なデータを読み込む。

これらには以下のようなメリット・デメリットが存在する:

- 1. 
  - メリット
     - ファイルを読み込んで、式や文として評価すればよいので、実装が楽 (Python なら `exec` 関数、Ruby なら `Module.module_eval` など)
     - 任意の値を計算して設定できる。
  - デメリット
     - チューリング完全である (表現力が高すぎる) ため、設定ファイルの読み込みが停止する保証がなく、また理論的には読み込みが停止するかどうかの判定もできない
     - 同じく、表現力が高すぎるため、正しい情報を与えるような設定ファイルかどうかを事前に検証できない
     - 一部のスクリプト言語以外の言語では、そもそも記述できない
         - 実行時に式をパースして実行する機能がない場合があるため
     - 設定が言語に縛られる
         - これは 2. の形式でも、 例えば [RON](https://github.com/ron-rs/ron) や [Starlark](https://github.com/bazelbuild/starlark) や [Erlang の file:consult/1 で読める形式](https://erlang.org/doc/man/file.html#consult-1) などで起こり得る[^do-you-know-about-json]
- 2.
  - メリット
     - 表現力が制限されるため、読み込みは必ずいつか停止する
     - 同じく表現力が制限されるため、正しい情報を与えるような設定ファイルかどうか事前に検証できる (スキーマに従っているかどうかを検証できる)
     - (YAML, JSON, XML などの汎用的な設定記述言語を使っている場合) 言語によらずほとんど同一の手間で読み込みができる
         - リファクタリングで言語を変えたり、協調するためのツールを別の言語で書く場合に役に立つ
  - デメリット
     - 表現力が弱いため、設定ファイル内部で計算を行うことはできない
     - 設定ファイルをライブラリを使って値に変換し、そこから必要な値を取得する手間が発生する

以前作った [AtCoder 用の提出ツール](https://github.com/koba-e964/contest/blob/2eef5531b3fd95225c67e679450bf3041da25b98/atcoder/submit.rb)では 1. を採用した。これは以下の理由がある:

- 当時は技術力が低く、設定ファイルの表現力を制限することによるメリットを知らなかった
- 当時は技術力が低く、設定ファイルの実現方法としてこれしか思いつかなかった (JSON や YAML についての知識が乏しかった)
- 当時は技術力が低く、設定ファイル用のスキーマを定義することのメリットを知らなかった

今回は 2. を採用した。理由は上記の逆および個人の好みである。
なお、スキーマ定義および検証には [Cerberus](https://docs.python-cerberus.org/) を使用した。[^why-not-json-schema]

[^do-you-know-about-json]: JSON が JavaScript 由来なのを知ってますか?
[^why-not-json-schema]: スキーマ定義言語として JSON Schema を使用しなかった理由は、JSON Schema は JSON 用であり YAML に使うためには微妙に追加の手間が必要であるため、そして今回の設定ファイルの規模 (数項目) に対してスキーマがかなり大きくなってしまい管理が大変になることが予測されたためである。Cerberus を使うとスクリプト内にスキーマを埋め込む格好になり、今回の規模であれば楽。
Ubuntu 20.04 の PHP 7.4 から MS SQLServer に接続する

## 環境
* Ubuntu 20.04.1 LTS (Focal Fossa)
* PHP 7.4.10

## Microsoft のドキュメント
* [PHPドライバのインストール](https://docs.microsoft.com/ja-jp/sql/connect/php/installation-tutorial-linux-mac?view=sql-server-ver15)
* [ODBCドライバのインストール](https://docs.microsoft.com/ja-jp/sql/connect/odbc/linux-mac/installing-the-microsoft-odbc-driver-for-sql-server?view=sql-server-ver15)

## インストールの流れ
先にODBCドライバをインストールした後、PHP側のpeclでドライバをインストールする。
ODBCドライバがない状態では、peclでのインストール時にビルドに失敗する。

## ODBCドライバのインストール
マニュアルから

```bash
sudo apt-get update
sudo ACCEPT_EULA=Y apt-get install msodbcsql17
# optional: for bcp and sqlcmd
sudo ACCEPT_EULA=Y apt-get install mssql-tools
echo 'export PATH="$PATH:/opt/mssql-tools/bin"' >> ~/.bash_profile
echo 'export PATH="$PATH:/opt/mssql-tools/bin"' >> ~/.bashrc
source ~/.bashrc
# optional: for unixODBC development headers
sudo apt-get install unixodbc-dev
```

### 問題発生
マニュアルでは``optional``になっているが、PHPのドライバをビルドするには``unixodbc-dev``が必要。
しかし、素直にインストールしようとすると失敗する。

```bash:エラー
以下のパッケージには満たせない依存関係があります:
 unixodbc-dev : 依存: unixodbc (= 2.3.7)
                依存: odbcinst1debian2 (= 2.3.7) しかし、インストールされようとしていません
E: 問題を解決することができません。壊れた変更禁止パッケージがあります。
```

``apt list``してみると

```bash
$ apt list unixodbc*
一覧表示... 完了
unixodbc-dev/bionic,focal 2.3.7 amd64
unixodbc-dev/focal 2.3.6-0.1build1 i386
unixodbc/bionic,focal 2.3.7 amd64
unixodbc/focal 2.3.6-0.1build1 i386
$ apt list odbcinst1debian2
一覧表示... 完了
odbcinst1debian2/bionic 2.3.7 amd64
odbcinst1debian2/focal 2.3.6-0.1build1 i386
```

``amd64``版は``focal``向けのバージョンが合っていない。

### 解決策
同じバージョンで指定して、同時にインストールする。

```bash
sudo apt install unixodbc-dev=2.3.6-0.1build1 libodbc1=2.3.6-0.1build1 odbcinst1debian2=2.3.6-0.1build1
```

### 失敗する方法
* ``i386版``ならバージョンが合っているので``unixodbc-dev:i386``をインストール &rArr; 後に続く``pecl install sqlsrv``に失敗する。
* ``unixodbc-dev=2.3.6-0.1build1``をインストール &rArr; 依存関係をインストールしてくれない。

## PHP用のドライバインストール
上記の方法で``unixodbc-dev``のインストールに成功していれば、マニュアル通りに問題なくインストールできる。

```bash
sudo pecl install sqlsrv
sudo pecl install pdo_sqlsrv
sudo su
printf "; priority=20\nextension=sqlsrv.so\n" > /etc/php/7.4/mods-available/sqlsrv.ini
printf "; priority=30\nextension=pdo_sqlsrv.so\n" > /etc/php/7.4/mods-available/pdo_sqlsrv.ini
exit
sudo phpenmod -v 7.4 sqlsrv pdo_sqlsrv```
Rails6でapiを書くときのcorsの設定での躓きについて

## この記事で書くこと
以下のようなアプリケーションを作ろうとしたときに、CORSの設定で本番反映後にエラーが発生してしまったので、同じミスをしないように情報をきちんとまとめておく。

![Component 1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/71266/33b5c3c6-1fe7-dd5e-ffcc-340cd1ed7670.png)

## 結論
firebaseでホスティングされたnuxtアプリケーションのurlが、 `https://xxxx.web.app` だった場合、

```config/environments/production.rb
Rails.application.configure do
  # 中略
  config.hosts << 'xxxx.web.app'
end
```

```config/initializer/cors.rb
Rails.application.config.middleware.insert_before 0, Rack::Cors do
  allow do
    if Rails.env.production?
      origins 'https://xxxx.web.app'
    else
      origins 'http://localhost:3000'
    end
    resource '*',
      headers: :any,
      methods: [:get, :post, :put, :patch, :delete, :options, :head]
  end
end
```

## 何が起きたか

```
Access to XMLHttpRequest at 'API側のurl' from origin 'アプリ側のurl' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
```

apiへリクエストがエラーになってしまう。 :cry:  

## うまく行ってなかったときの状況
Ruby: 2.7.1
Rails: 6.0.3.3
rack-cors: 1.1.1

### rack-corsの設定
```config/initializer/cors.rb
Rails.application.config.middleware.insert_before 0, Rack::Cors do
  allow do
    if Rails.env.production?
      origins 'https://xxxx.web.app/'
    else
      origins 'http://localhost:3000'
    end
    resource '*',
      headers: :any,
      methods: [:get, :post, :put, :patch, :delete, :options, :head]
  end
end
```

### config/environments/production.rb
[Railsガイド](https://guides.rubyonrails.org/configuring.html#configuring-middleware)

```config/environments/production.rb
Rails.application.configure do
  # 中略
  config.hosts << 'https://xxxx.web.app'
end
```


なぜ？？？間違ってないはず。。。
となったが、firebaseの
`Hosting URL: https://xxxx.web.app` という記述を見直していると最後の `/`がないのでは！？？？？と気づく。


```config/initializer/cors.rb
Rails.application.config.middleware.insert_before 0, Rack::Cors do
  allow do
    if Rails.env.production?
      origins 'https://xxxx.web.app' # 最後の/を削除する
    else
      origins 'http://localhost:3000'
    end
    resource '*',
      headers: :any,
      methods: [:get, :post, :put, :patch, :delete, :options, :head]
  end
end
```

```
Access to XMLHttpRequest at 'API側のurl' from origin 'アプリ側のurl' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
```

そうすると、corsのエラーがなくなった。 :tada: 

## 戦いはまだ終わってなかった。

次は、apiがstatus403で返ってきた。

```config/environments/production.rb
config.hosts << 'xxxx.web.app'
```

「こうだよ！！」とresponseで親切に教えてくれていました。。。 ありがとう、、
:pray:
キーワードで勉強しよう！ - アジャイル（Agile）開発

##Agile開発とウォーターフォール開発
アジャイル開発とウォーターフォール開発は開発方法やスキルなどを話すことではなく、プロジェクト全体の管理方法を意味する。

##ウォーターフォール開発
既存の普通の管理方法って「ウォーターフォール開発」とよく言うが、これはプロジェクト全般の機能を対象にして要件定義→設計→開発→テストの順で工程を進む。この「ウォーターフォール開発」は前段階の工程に漏れや間違いがないことが前提として次の工程が行われますが、下記の頂点と弱点を持っている。

<dl>
  <dt>頂点</dt>
  <dd>１．プロジェクト全体のスケジュールを立てやすい</dd>
  <dd>２．各工程ごとにタスクを担当者に割り振れるので、プロジェクト開始後の進捗を比較的管理しやすい</dd>
  <dd>３．ロジェクトの開始当初に見積もった計画通りに各工程を遂行していきます。そのため、開発のための費用や、SE（システムエンジニア）やプログラマーの必要人員数が予測できる</dd>
  <dt>弱点</dt>
  <dd>１．プロジェクト進行中や成果物を見た後に仕様変更が生じた際には大きな手間がかかってしまう</dd>
  <dd>２．各工程の成果物が必要となります。そのため、プロジェクトの規模が大きければ大きいほど書類の量は膨大なものとなる</dd>
</dl>

##Agile開発
アジャイル（Agile）開発は従来のウォーターフォール開発よりも開発期間の短縮が可能。
アジャイル開発では、ソフトウェアの計画段階で厳密な仕様を決めずに、だいたいの仕様と要求だけを決める。これは「開発途中に仕様や設計の変更があることは当たり前」とのことを前提にする。クライアントが求めるニーズに最大限応えることが可能。小さな単位に分けられた開発を「計画」→「設計」→「実装」→「テスト」と行いながら、機能のリリースを繰り返します。

<dl>
  <dt>頂点</dt>
  <dd>１．不具合が発覚した際に戻る工数が少ない</dd>
  <dd>２．計画段階で綿密な仕様を決めないため、開発途中でユーザーとコミュニケーションを取りながらフィードバックできる</dd>
  <dd>３．仕様変更や追加に対応可能なため、ユーザーのニーズに最大限応えることができ、高い満足度が得られる</dd>
  <dt>弱点</dt>
  <dd>１．計画段階で厳密な仕様を決めていないため、開発の方向性がブレやすい</dd>
  <dd>２．良くしようと改善を繰り返し、テストやフィードバックで変更・追加を加えていくことで、当初の計画からズレてしまう可能性があり</dd>
  <dd>３．スケジュールや進捗具合が把握しにくくコントロールが難しくなる</dd>
</dl>

##参考
[参考１]
(https://hnavi.co.jp/knowledge/blog/agile_software_development/)
[参考２]
(https://backlog.com/ja/blog/advantages-and-disadvantages-for-waterfall-model/)
[K8s] minikube podの立ち上げ

## 概要

本投稿は`minikube`を使用し、K8sの基本動作を抑えることを目的とした個人メモです。

## 前提条件

* MacOSに`minikube`, `kubectl`がインストール済みであること。
* K8sクラスタが起動していること

```
$ minikube start
```

## クラスタ構成の確認

以下コマンドでは`K8sマスタIPアドレス`と、内部DNSエンドポイントが表示される。
kubectlコマンドがマスターと通信できない場合はエラーとなるため、`minikube stop`実行後、再度クラスタを立ち上げること

```
$ kubectl cluster-info
Kubernetes master is running at https://192.168.99.100:8443
KubeDNS is running at https://192.168.99.100:8443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
kubernetes-dashboard is running at https://192.168.99.100:8443/api/v1/namespaces/kube-system/services/kubernetes-dashboard/proxy

To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'
```

nodeの確認方法は以下の通り。
マルチノード構成の場合はマスタの他にワーカーノードも表示される。

```
$ kubectl get node
NAME       STATUS    ROLES     AGE       VERSION
minikube   Ready     <none>    9m        v1.4.5
```

## ポッドの実行

今回は`hello-world`イメージを使用し、ポッドの立ち上げを行う。

```
$ kubectl run hello-world --image=hello-world -it --restart=Never
```

また、既に同じポッドが立ち上がっている場合は以下のようなエラーとなる。

```
$ kubectl run hello-world --image=hello-world -it --restart=Never
Error from server (AlreadyExists): pods "hello-world" already exists
```

ポッドの状態は以下コマンドで確認することが可能。

```
$ kubectl get pod
NAME          READY     STATUS      RESTARTS   AGE
hello-world   0/1       Completed   0          3m
```

ポッドを削除する場合は`delete`を行う。

```
$ kubectl delete pod hello-world
pod "hello-world" deleted
```

削除後はポッドが起動していないことを確認できる。

```
$ kubectl get pod
No resources found.
```

ログを確認する場合は以下の通り。

```
$ kubectl logs hello-world
```
【CakePHP3】クエリービルダーでint型とvarchar型を連結させた文字列の出力方法

学生のuser_idには、ユーザーIDが格納されている。
そこから、ユーザーIDとユーザー名を連結させた文字列を出力させたい。

**学生 (student)**

|id|user_id|
|:---|:---|
|1|3|
|2|2|
|3|3|

**ユーザー (user)**

|id|user_name|
|:---|:---|
|1|山田太郎|
|2|佐藤花子|
|3|中村次郎|

**【結果】**

|学生リスト|
|:----------|
|001　山田太郎|
|002　佐藤花子|
|003　中村次郎|

ここで私が失敗した例と、上司の方に教えてもらって解決した内容を以下に書いてきますね〜。

<hr>

**【失敗例】**

``````PHP:StudentsController.php
public function showStudentsList {
 $query = $this->Students->find()
 ->select([
      'user_id' => '(SELECT CONCAT(user.id, 3, 0), " ", user.name) FROM user WHERE id = Students.user_id'
      ])->all();
}
```

カラムuser_idのデータ型はintのため、IDと名前を連結させて表示させたいクエリ文を書いても、ユーザーIDしか表示してくれなかった。

**【成功例】**

``````PHP:StudentsController.php
public function showStudentsList {
 $query = $this->Students->find()
 ->select([
      'user_id_text' => '(SELECT CONCAT(user.id, 3, 0), " ", user.name) FROM user WHERE id = Students.user_id'
      ])->all();
}
```

エイリアス名の末尾に`_text`を書き加えると、希望通りの文字列を表示してくれました。
<hr>
これってそもそもエイリアス名を、データベースと同じカラム名'user_id'にしたのがいけないのかな...
ご存知の方いらっしゃったら教えてください。

## 追記
- エイリアス名を`_text`以外に書き換えてみても使えました！要するにデータベースと同じカラム名だったのがいけなかったみたいです。(2020/10/21)