OmniAICreator/Qiita-1.07M huggingface dataset:
Railsチュートリアル第2章でユーザーページを探検どころか全然たどり着けなかった話


#はじめに
Ruby on Railsチュートリアル第２章にて、
「Scaffoldジェネレータというスクリプトを用いて
お手軽にアプリケーションが作れちゃうから１回だけやってみようよ。」
という演習があります。
<br>
Herokuにプッシュするところまでは第１章とほぼ同じで、その後こちらの

```
$ rails generate scaffold User name:string email:string
```
Scaffoldコマンドを用いることで、こんな感じの
![demo_blank_user_index.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864329/6d24bfc0-8bc2-6b62-95bf-e2a9c78cc45f.png)
ユーザー登録画面その他諸々が即出来るとのことで、早速トライ。

#やってみた
諸々のコマンドを実行して進めていくと、いきなりこんなことを言われます。
<br>
「（出来上がった）ユーザーページを探検しよう！」
「/userを表示すれば見れるよ！」
<br>

**・・・え・・・どこ・・・？？？**
<br>

urlどこ？どっかに書いてあるんだよね？どこ？　/userってどこ？

ユーザーページを探検しようにも、urlが分からないからアクセス出来ない。

ちゃんと出来てるのかどうかも分からない・・・どこに書いてあるんや・・・

と血眼になって探していたところ、[こちらの神記事](https://qiita.com/snaruse0608/items/843b8e77b6528314ce45)にたどり着きました。

<br>
どうやら

**Hello World!　のページのurlの後に、/userをつけるだけ**

らしい。（そこにいたんか、君・・・）




#まとめ

その後、例の[神記事さま](https://qiita.com/snaruse0608/items/843b8e77b6528314ce45)のおかげで幾多のエラーをくぐり抜け、
無事にユーザーページを表示することができました。

日記やん・・・
【Stereo Depth】CDN : Disparityのoffsetを推定する

<h1>Wasserstein Distances for Stereo Disparity Estimation</h1>

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482094/b0842a7d-026f-37ec-3423-06697b2f108e.png)

Depth Estimationの精度を向上する論文を見つけたので見ていきたいと思う。

<h1>新規性</h1>
<h2>offsetの推定</h2>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482094/eaecce2c-edf6-30ba-de2d-9f3e7efb8122.png)

それぞれのDisparityに対してoffsetを推定する。


<h1>結果</h1>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482094/b53f5ed4-9649-1292-6327-728a49fadf20.png)
offsetを学習したほうが精度が高い。

<h1>結論</h1>
・offsetを推定するのは面白いと思ったし、理にかなっていると思った。

<h1>参考文献</h1>
Wasserstein Distances for Stereo Disparity Estimation
https://arxiv.org/pdf/2007.03085v1.pdf
今日の積分

#はじめに

YouTubeで見かけた今日の積分に挑戦してみた。

```math
\begin{align}
I&=\int_0^{\frac{\pi}{4}}\sqrt{\tan(x)}dx
\end{align}
```

#解答例

$s=\sqrt{\tan(x)}$と置換積分すると有理関数化できる。

```math
\begin{align}
s&=\sqrt{\tan(x)}, x=\tan^{-1}s^2,\frac{dx}{ds}=\frac{2s}{1+s^4}\\
I&=\int_0^1\frac{2s^2}{1+s^4}ds
=\int_0^1\frac{2s^2}{(1-\sqrt{2}s+s^2)(1+\sqrt{2}s+s^2)}ds\\
&=\frac{1}{\sqrt{2}}\int_0^1\frac{s}{1-\sqrt{2}s+s^2}-\frac{s}{1+\sqrt{2}s+s^2}ds\\
&=\frac{1}{\sqrt{2}}\int_0^1\frac{2s}{1+(1-\sqrt{2}s)^2}-\frac{2s}{1+(1+\sqrt{2}s)^2}ds\\
&=\int_0^1\frac{\sqrt{2}s}{1+(1-\sqrt{2}s)^2}-\frac{\sqrt{2}s}{1+(1+\sqrt{2}s)^2}ds
\end{align}
```

前項で$1-\sqrt{2}s=t$、後項で$1+\sqrt{2}s=t$と置換積分すると、被積分関数が同形となる。

```math
\begin{align}
I&=\int_1^{1-\sqrt{2}}\frac{1-t}{1+t^2}\frac{-dt}{\sqrt{2}}
+\int_1^{1+\sqrt{2}}\frac{1-t}{1+t^2}\frac{dt}{\sqrt{2}}\\
&=\frac{1}{\sqrt{2}}\int_{1-\sqrt{2}}^{1+\sqrt{2}}\frac{1-t}{1+t^2}dt\\
&=\frac{1}{\sqrt{2}}\left[\tan^{-1}t\right]_{1-\sqrt{2}}^{1+\sqrt{2}}
-\frac{1}{2\sqrt{2}}\left[\log(1+t^2)\right]_{1-\sqrt{2}}^{1+\sqrt{2}}\\
&=\frac{\pi}{2\sqrt{2}}-\frac{\log(3+2\sqrt{2})}{2\sqrt{2}}\\
&=\frac{\pi-2\log(1+\sqrt{2})}{2\sqrt{2}}
\end{align}
```

$\tan^{-1}t$の計算を図解すると以下のようになる。
一辺が1の直角二等辺三角形に、半径$\sqrt{2}$の半円を重ねて描く。
$\tan^{-1}(1+\sqrt{2})$と$\tan^{-1}(\sqrt{2}-1)$は、図中の$\alpha$と$\beta$に対応し、
$\alpha+\beta$は直径に対する円周角$\pi/2$となる。

![circle3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192430/f2329d89-bb16-5ee1-11de-55d70e882297.png)

#数値計算による検算

scipyを使用すると簡単に数値積分が計算できる。

```python
import numpy as np
from scipy import integrate

y = lambda x: np.sqrt(np.tan(x))
s1 = integrate.quad(y, 0, np.pi/4)
s2 = (np.pi-2*np.log(1+np.sqrt(2)))/2/np.sqrt(2)
```

```python
>>> s1
(0.48749549439936096, 1.496580637194711e-13)
>>> s2
0.487495494399361
>>> s2 - s1[0]
5.551115123125783e-17
```

#おわりに

「integral root of tan」で検索すると、解答例がたくさん見つかる。
積分範囲を$[0,\pi/2]$としても、被積分関数は発散するが、積分は収束する。
積分値は$\pi/\sqrt{2}$。scipyでも計算可能。

```python
>>> integrate.quad(y, 0, np.pi/2)
(2.221441469078374, 4.1636782910359216e-10)
>>> np.pi/np.sqrt(2)
2.221441469079183
```
駅データ.jpのすゝめ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244632/ad622d92-9f1c-ea74-2d05-b80fe6228c67.png)
オープンデータって言って良いのかわからんが...（カテゴリ）

趣味で[TrainLCD](https://trainlcd.tinykitten.me)という位置情報と連動して電車のLCDを再現するアプリを[Android](https://play.google.com/store/apps/details?id=me.tinykitten.trainlcd)/[iOS/iPadOS](https://apps.apple.com/jp/app/trainlcd/id1486355943)向けに作ってる[TinyKitten](https://tinykitten.me)といいます。。

アプリのバックエンドとしては、鉄道の元データとして[駅データ.jp](https://ekidata.jp)というサイトからデータをダウンロードしたものをゴニョゴニョしてMySQLに保存してNestJSのAPIでJSONで返しています。

そこで、駅データ.jpを使って困ったところとかその解決方法を残していきたいと思います。

## 都道府県がたまに入ってない

例えば東京都豊島区のデータには住所のフィールドに東京都豊島区と入っているべきですが、**唐突に豊島区と入っているときがあります**（これは例で、実際豊島区のデータでそういうデータが入っているか執筆時に確認したわけではありません）

これは都道府県のIDが入っているのでPythonでちゃちゃっと都道府県が入っていないデータを洗い出してIDから取ってきた都道府県を付与するだけです。

[実際にやってるコード](https://github.com/TinyKitten/SAPIPref)

## 路線・駅データのローマ字表記が不十分

例えば越谷レイクタウン駅のローマ字表記が「koshigayareikutaunn」的な感じに入ってます。
これは仕方ないので**全部手作業で治してます**。自動翻訳で回そうとも思ったのですが翻訳ではどうにもできず。（東武動物公園駅とか無理。Tobu Zoological Parkみたいになる）
令和の時代に一週間ほどかけて手作業でコツコツ治すのはなかなかつらい。

## 成田エクスプレスがソートしてもおかしな並びになる

これはもうデータを返さないようにしてるので実際の並びは覚えてないのですが、渋谷の隣に高尾とか来ちゃってた気がします。
これに関しては対応する気も起きなかったのでAPI側のSQLで返さないようにしました。
[結果にN'EXが入らないようにした(コミット)](https://github.com/TinyKitten/StationAPI/commit/a2d8a319d21687e00eec0ba79b442d09f65d0bad)

## まとめ

だいたいこんな感じの苦労がありました。割と頑張って作ったので皆さん使ってください。お願いします。なんでもしますから。

## 関連
[前自分で主催したイベントで発表したスライド](https://www2.slideshare.net/TsubasaSekiguchi/trainlcd)
[TrainLCDソースコード](https://github.com/TinyKitten/TrainLCD)
[StationAPIソースコード](https://github.com/TinyKitten/StationAPI)
【Angular Universal SSR】HammerJS導入時にwindow is not definedとなる場合の対処法

HammerJSを用いたプロジェクトにAngular UniversalでSSR対応を試みた結果、下記のエラーに遭遇したのでメモ。

```bash
})(window, document, 'Hammer');
ReferenceError: window is not defined
```

SSRでwindow周りのエラーが起きることはよくあるが、今回はHammerJSの内部の問題なので、`isPlatformBrowser`などでサーバーでの実行時に処理を飛ばすことができない。

どうやら`hammerjs`をフォークした`@egjs/hammerjs`を用いると良いらしい。
ドキュメントには`server friendly`と書いてある。

具体的には下記のように修正した。

```src/main.ts
- import 'hammerjs';
+ import '@egjs/hammerjs';
```

```src/app/app.module.ts
import { 
  HammerModule, HammerGestureConfig, 
  HAMMER_GESTURE_CONFIG, HAMMER_LOADER 
} from '@angular/platform-browser';
import Hammer from '@egjs/hammerjs';

@Injectable()
export class MyHammerGestureConfig extends HammerGestureConfig {
  buildHammer(element: HTMLElement) {
    const mc = new Hammer(element, this.options);

    mc.get('pinch').set({enable: true});
    mc.get('rotate').set({enable: true});

    for (const eventName in this.overrides) {
      mc.get(eventName).set(this.overrides[eventName]);
    }

    return mc;
  }
}

@NgModule({
  ...
  providers: [
    { provide: HAMMER_GESTURE_CONFIG, useClass: MyHammerGestureConfig },
    { provide: HAMMER_LOADER, useValue: () => import('@egjs/hammerjs').then(m => (window as any)['Hammer'] = m) },
  ]
})
export class AppModule { }

```

これでビルドが通る。
Raspberry Pi4&UbuntuでOpenVINO環境構築

# はじめに
Raspberry Pi4のUbuntu環境でOpenVINOをPythonで動かすための環境構築でめちゃくちゃ手こずったので備忘録も兼ねて記録していきます。
手こずった話は最後に書きます。

# 注意点
Intelによると、ラズパイでのOpenVINO対応環境はRaspbian/RaspberryPi OSとなっております。
Ubuntuでの対応は非公式ですので、お気をつけ下さい。
また、本構築手法ではOpenCVのOpenVINO対応は行っていません。

# 用意する環境
- Raspberry Pi4(4/8GB)
- Ubuntu18.04/20.04
- Python3.6(Ubuntu18.04)/Python3.8(Ubuntu20.04)

# 環境構築
## はじめの一歩
手始めにライブラリを最新版にしておきましょう。

```sh
sudo apt update && sudo apt upgrade -y
```
OpenVINOのGithubから最新版を取ってくるために、gitが必要になります。
また、Python3のライブラリを取ってくるのにpipも必要です。

```sh
sudo apt install git python3-pip
```
## ビルドツールの準備
ビルドツールであるbuild-essentialとcmakeを入れましょう。

```sh
sudo apt install build-essential cmake
```
## ソースコードのダウンロードと依存ライブラリの準備
OpenVINOを公式からクローンしましょう。
softwareというディレクトリを作ってその中に置くようにしてますが、無くてもいいです。

```sh
mkdir software
cd software
git clone https://github.com/openvinotoolkit/openvino.git
```
サブモジュールがあるので、それをフェッチしましょう.

```sh:
cd openvino/inference-engine
git submodule update --init --recursive
```

ビルド関係で必要なものがいくつかあるので、bashファイルを実行します。

```sh:
cd ..
sh ./install_build_dependencies.sh
```
数分かかります。

## Python3環境の準備
Python3はUbuntu18/20に標準で付いているものを使うので、
Ubuntu18であればPython3.6, Ubuntu20であればPython3.8になります。
cythonのバージョン0.29.21とnumpyが必要になります。

```sh
sudo -H pip3 install numpy
sudo -H pip3 install cython==0.29.21
```

## ビルド
Python環境含めて、ビルドしましょう。

```sh
mkdir build && cd build
cmake -DCMAKE_BUILD_TYPE=Release \
-DENABLE_OPENCV=OFF \
-DENABLE_PYTHON=ON \
-DPYTHON_EXECUTABLE=/usr/bin/python3.6 \
-DPYTHON_LIBRARY=/usr/lib/python3.6/config-3.6m-aarch64-linux-gnu/libpython3.6m.so \
-DPYTHON_INCLUDE_DIR=/usr/include/python3.6m ..
```
cmake実行後に、PythonのLibやらがちゃんと指定されていることを確認してください。
確認できれば、

```sh
make -j4
```
でビルドします。
大体2～3時間かかります。

## PYTHONPATHの設定
ビルドされたPython APIのラッパーは```/openvino/bin/```の中にあります。
以下を```.bashrc```を開いて記載しましょう。

```sh
sudo vim ~/.bashrc
...
export PYTHONPATH=$PYTHONPATH:~/software/openvino/bin/aarch64/Release/lib/python_api/python3.6/
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:~/software/openvino/bin/aarch64/Release/lib/
```

## ちゃんとimportできるか確認
ターミナル上でいいので、Python3を起動して確認してみましょう。

```sh
python3
...
# パスが通ってるかまず確認
# 出力に~/software/openvino/bin/aarch64/Release/lib/python_api/python3.6/が含まれていることを確認
# 無ければ、.bashrcを確認する
import sys; import pprint
pprint.pprint(sys.path)
# OpenVINOの確認
from openvino.inference_engine import IECore
# エラーがでなければ完了
```

# めちゃくちゃ手こずった話
本来は、手動で構築したPython3.7上にOpenVINOを作りたかったのですが、何度ビルドしてもPython上でimport時に

```sh
Segmentation fault (core dumped)
```
と出て、Pythonがクラッシュしてしまいます。
色々探った結果、```apt install```で入れたcythonが悪さをしているのではないかと思い、```apt remove```で消した後に```pip```で入れたcythonを参照するようにしたのですが、それも原因ではなかったようです。
また、Python3.7をインストールする際に

```sh
sudo make install
```
をしていたせいで、3.6系と3.7系がごちゃごちゃになってしまったのではないかと思い、

```sh
sudo make altinstall
```
にしましたが、それもダメ…
結局3.7上で構築するのは諦めて、Ubuntuに最初から付いているPythonでOpenVINO環境構築したところうまくいきました。
ただ、Intelの中の人は自分で構築したPython環境にビルドできたようです。
https://community.intel.com/t5/Intel-Distribution-of-OpenVINO/When-I-import-openvino-inference-engine-I-faced-crash-the-python/m-p/1229283#M21472
ちなみにIntelの方々は非常に丁寧に対応して頂けます。この一件でめちゃくちゃIntelのファンになりました。Intel入ってます。
Python 3.9 で pylint を使用すると typing で誤ったエラーが表示される

# 環境

- Python 3.9.0
- pylint 2.6.0（2020/12/13 時点で最新）

# 問題

pylint を実行したときに、typing モジュールの使用箇所に誤ったエラーが表示される。

例：

```console
$ pylint module
************* Module module
module.py:213:35: E1136: Value 'Union' is unsubscriptable (unsubscriptable-object)
```

`typing.Union` は `typing.Union[int,str]` のように型を示すために使うもので、これが unsubscriptable というのは明らかな誤りです。

# 対処法

Python のバージョンを 3.8.6 まで下げたら直りました。

なお、GitHub 上の [Pull Request](https://github.com/PyCQA/pylint/pull/3905) を見る限り、pylint の Git リポジトリ上の master ブランチでは直っているようです。（pylint の最新リリースの後に修正された模様。）どうしても Python 3.9 で使いたい方は、Git リポジトリからインストールすることでも直せるかもしれません。

# 感想

Python は最新リリースの手前くらいのマイナーバージョンの方が、パッケージまで安定していて良いと思いました。
さくらVPSでハニーポットcowrieを導入する.ubuntu18.04を利用

## はじめに
この記事は自分の遊びのメモとして残しています.所属企業や所属大学などとは一切関係ないのでそちらを最初に記させていただきます.
※ハニーボットの導入に際しては,調べた限りさくらVPSを利用して導入すること自体に問題はなさそうですが今後または,今現在完璧に問題ありません！と断言できるものでもないので自己判断で導入されることをお勧めします.その際に本番SSHのセキュリティを固くすることを強くお勧めします.
## 今回導入するハニーポット
こちらを導入します.<b>cowrie</b>

cowrieとは...
>Cowrieは不正アクセスの情報を知るためのハニーポットです。Cowrieは、sshやtelnetといったサーバーを遠隔操作するためのソフトウェアに対する不正アクセスの情報を記録できます。
参照:https://procspace.net/blog/security/21/

## 導入
以下のドキュメントをもとに導入しました
参考:https://cowrie.readthedocs.io/en/latest/INSTALL.html

### 0,専用のアカウントを作成しましょう！（非root権限で！）

```
$ sudo adduser username
```

このあとパスワードを決めるアナウンスをされます.
それを決めたら全てenterで問題ありません.

### 1,関連ライブラリを導入

```
$ sudo apt-get install git python-virtualenv libssl-dev libffi-dev build-essential libpython3-dev python3-minimal authbind virtualenv
```

### 2,githubからコードをインストール

```
$ sudo su username
$ git clone http://github.com/cowrie/cowrie
```

### 3,仮想化の導入（python）
機械学習とかでも良く個人的にはやります.本番環境のpythonを壊すとめんどくさいことになるのでpythonは仮想環境を作りましょう.
「必要な機能を必要最低限の権限で！」

```
$ cd hogehoge/cowrie
```

```
$ virtualenv --python=python3 cowrie-env
```

```
$ cd cowire-env/bin
```

```
$ source activate
```


### 4,パッケージインストール

```
$ cd ../../
```

```
$ pip install --upgrade -r requirements.txt
```

### 5,構成ファイルの設定

```
$ cd etc
```

```
$ cp cowrie.cfg.dist cowrie.cfg
```

```
$ vim cowrie.cfg
```

SSHの設定

```
# Endpoint to listen on for incoming SSH connections.
# See https://twistedmatrix.com/documents/current/core/howto/endpoints.html#servers
# (default: listen_endpoints = tcp:2222:interface=0.0.0.0)
# (use systemd: endpoint for systemd activation)
# listen_endpoints = systemd:domain=INET:index=0
# For both IPv4 and IPv6: listen_endpoints = tcp6:2222:interface=\:\:
# Listening on multiple endpoints is supported with a single space seperator
# e.g listen_endpoints = "tcp:2222:interface=0.0.0.0 tcp:1022:interface=0.0.0.0" will result listening both on ports 2222 and 1022
# use authbind for port numbers under 1024

listen_endpoints = tcp:2222:interface=0.0.0.0
```

```
#listen_endpoints = tcp:2222:interface=0.0.0.0を
#listen_endpoints = tcp:22:interface=0.0.0.0に変更
```

### 6,cowrieを実行

```
$ cd ../bin coweie start
```

### 番外編:ポート22を使う場合の設定

ポートリダイレクションをする方法もあるが個人的には,非root権限に例外的リッスンするのが良い気がします.
※特にさくらVPSで導入する場合には...

#### Authbindの利用

```
$ sudo apt-get install authbind
$ sudo touch /etc/authbind/byport/22
$ sudo chown cowrie:cowrie /etc/authbind/byport/22
$ sudo chmod 770 /etc/authbind/byport/22
```

こんな感じで導入することができます.

### 最後に
これからハニーポットの分析系の記事もあげていきたいと思いますので宜しくお願い致します.
それでは...
アドベントカレンダー10日目：SREを読んでみた「トイルの撲滅」編

今回から新しい章に入ります。
新しい内容は、タイトル通りトイルの撲滅についてです。

## トイルの定義
トイル（toil）とは、直訳で「労苦」という意味ですが、SREにおいては、どのような意味を持つのでしょうか？何がトイルに分類されるのでしょうか？
トイルは、単につまらない仕事というわけではありません。例えば、行わなければならない管理上の作業（チームのミーティングやタスクの報告）は、これはオーバーヘッドにあたります。長期的な価値のあるつまらない仕事もあります。例えば、サービスのアラートの設定全体をクリーンアップするなどです。これは、トイルには当たりません。
トイルに関しては、以下のようなものであると説明されています。

> **トイルとは、プロダクションサービスを動作させることに関係する作業で、手作業で行われ、自動化することが可能であり、戦術的で長期的な価値を持たず、作業量がサービスの成長に比例するといった傾向を持つものです。**<sup>1</sup>

開発という視点からすれば、このトイルへ対処することがSREの主な仕事になると思います。
すべてを満たす必要はないですが、タスクがトイルと判断される以下は観点になります。

* 手作業であること<br>見逃しがちだと思いますが、何らかのスクリプトを実行させるのに必要な時間もトイルとなります。
* 繰り返されること<br>一回や二回程度では、トイルにはならず、何度も繰り返される作業のことです。ただ、ミーティングのようなそれが何かの解決策になっている場合は、これにあたりません。
* 自動化できること<br>マシンが自動で行える作業やそのタスクを行う必要性をなくせる仕組みが作れるのならば、トイルになります。人間の判断が必要な物はトイルとは言えないです。
* 戦術的であること<br>戦略的、計画的に行われることではなく、割り込みなどから生じたものへの対応として、行うことはトイルになります。この手のタスクは完全になくすことはできないですが、少なくする様に努める必要があります。
* サービスの成長に対して、O(n)であること<br>サービスが成長するごとに作業が増すものです。

トイルに対処しなければ、サービスが成長するごとにトイルの量が増し、やがて作業の内の100%がトイルになってしまいます。
従来のシスアド方式のように、シスアドチームを肥大化させないためには、トイルを見つけ出し、自動化することが重要です。

## タスクの分類
トイルかそうでないかという観点が持てれば、システムにおいて、必要な作業を見極めることができます。
典型的なSREの活動は、以下のようなものがあります。

* ソフトウェアエンジニアリング<br>コードの作成や修正を含む作業であり、設計やドキュメント作成作業も含みます。
* システムエンジニアリング<br>プロダクションの設定、設定の変更、システムに関するドキュメントの作成などです。一回の作業で改善効果が持続する方法で行われます。
* トイル
* オーバーヘッド<br>サービスを稼働させるのに直接関係のない管理的な作業

## トイルが及ぼす悪影響
トイルは、完全になくすことができるものではなく、少量ならば、手っ取り早く達成感をえることができるかもしれません。
しかし、トイルが多すぎる場合には、注意必要です。
トイルが多すぎることによる悪影響は、たくさんありますが、例として以下のようなものが挙げられています。

> * **キャリアの停滞<br>つまらない仕事からは、キャリアを生み出すことはできません。**
* **モラルの低下<br>多すぎるトイルは、燃えつきや倦怠、不満につながります。**<sup>1</sup>

やりがいの感じられない仕事とは、トイルの多い仕事と言い換えることができるかもしれません。逆を言えば、トイルを減らすこと自体を仕事へのやりがいに変換できるとも考えられます。

##まとめ
* トイルとは、手作業で繰り返し行われるもののこと
* トイルを減らさないと、やりがいも減っていく

#### 雑記
* 一日のタスクを分類してみる。

#### 引用
1. Betsy Seyerほか　SRE サイトリライアビリティエンジニアリング　オライリー　51-56
Boot CampのWindows10で「英数」「かな」キーを有効化

##環境
・Windows 10 Home
・20H2

##手順
IMEの設定を開く。設定の検索欄にIMEって入力すると出てくる[日本語IMEの設定]をクリックすると開ける。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/905735/a6f58206-e476-7e8a-4e6c-b1a031827443.png)

[キーのカスタマイズ]をクリックして[各キーに好みの機能を割り当てる]をオンにする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/905735/3949f3ff-d1bb-3594-bb6a-47b5a7ed7d7a.png)

そうすると下のプルダウンが変更可能になるので以下のように変更する。
無変換キー：IME-オフ
変換キー：IME-オン
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/905735/8dc549fa-1483-df72-f851-af9fedc3cee3.png)

完了！
node.jsでscssの変数を動的に変更する方法

テンプレートに含まれるSCSSに対してカスタマイズの余地を作りたい場合に、変数定義のファイルを直接編集しても良いが、出来るだけ簡単にプログラムから変数を上書きしたいことがある。

そのような場合にはSCSSの@importを使えばグローバル変数を書き換えるのはそれほど難しくないが、@importは将来的に廃止される可能性があるため@useで同様のことができないか試してみた。

dart-sassパッケージの文字列からSCSSを生成するAPIを使うことで自由にグローバル変数を変更できる程の自由度はないものの実用上問題ないレベルで実現可能と言える。

ポイントは既存のSCSSファイルを@useするSCSSを新たに生成し、withブロックで変数を上書きしてしまうことである。

|ソフトウェア|バージョン|
|:--|:--|
|macOS|10.15.7|
|node.js|14.14.13|
|TypeScript|4.1.3|
|sass(dart-sass)| 1.30.0|

```scss:variables.scss
// 変更可能な変数には !defaultを付ける
$width: 0 !default;
$height: 0 !default;
```

```scss:sub_style_1.scss
@use 'variables' as v;

div.a {
  background-color: red;
  width: v.$width;
  height: v.$height;
}
```

```scss:sub_style_2.scss
@use 'variables' as v;

div.b {
  background-color:green;
  width: v.$width;
  height: v.$height;
}
```
トップになるSCSSファイルでは、変数ファイルを先頭に全てのSCSSファイルを@forwardする。

```scss:style.scss
@forward "variables";
@forward "sub_style_1";
@forward "sub_style_2";
```

上記のSCSSファイルを用意した上で、以下のTypeScriptを実行すると

```typescript:index.ts
import * as fs from 'fs';
const sass = require('sass');
const result = sass.renderSync({
  data: "@use 'style.scss' with ($width: 200px, $height:300px);",
  outputStyle: 'expanded',
  outFile: 'style.css'
});
fs.writeFileSync("style.css",result.css);
```

次のCSSファイルが生成される

```css:style.css
div.a {
  background-color: red;
  width: 200;
  height: 300;
}

div.b {
  background-color: green;
  width: 200;
  height: 300;
}
```

dart-sassで生成する文字列中の変数を変更すれば、renderSyncで生成されるCSSの内容も変化することが確認できた。
【Swift5】指定したクラスのSuperviewを取得するメソッド


どうもこんにちは、エクステンション小僧こと@Zhalen（ツァーレン）と申します

#Extension

```swift

extension UIView {
    func firstSuperview<T>(of _type: T.Type) -> T? {
        guard let superview: UIView = self.superview else { return nil }
        return type(of: superview) == _type ? superview as? T : self.superview!.firstSuperview(of: _type)
    }
}

```
#Usage

こんな時にお使い下さいませ。

```swift:かきかき
button.addTarget(self, action: #selecter(tapped(_:)), for: .touchUpInside)
```
( ^_^) <あ、そうだ。ボタンかなんか押したときに上の階層から何か表示したいな

( ^_^) <えーとえーと、UITableViewを取得したいな

```swift:かきかきかきかき
func tapped(_ sender: UIButton) {
   sender.superview?.superview?.superview?.superview as! UITableView
}
```

( ^_^) <う〜んどうしよう困ったな困ったな、superviewって取得すんのめんどくさいや

<( ^_^)> <こんな時は〜、```firstSuperView(of _type:)```!

```swift:ドーン！

button.firstSuperview(of: UITableView.self)!
```

```swift:一般的な使い方

button.firstSuperview(of: クラス.self)!
```

これで、上の階層に最初に存在する任意のクラス（タイプ）のビューを取得できます。
そのクラスのビューが存在しない場合は```nil```を返すので注意！
実機ビルド時に「iPhone is not available. Please reconnect the device」

実機ビルド時に「iPhone is not available. Please reconnect the device」と
ダイアログが表示され、Xcodeから実機にアプリが送れなくなることがあったため対処法をメモ。

原因はXcodeが実機のOSのバージョンに対応していなかっただけだった

Xcodeをアップデートすると無事解決:smiley:  


## 参考
https://stackoverflow.com/questions/61863826/iphone-is-not-available-please-reconnect-the-device
[無料] AWS EC2 + RDS + Flask でWebアプリを作り HTTPS 化する [その3: EC2インスタンス作成]

[その2](https://qiita.com/nozomiyamada/items/1998744d138a29751556) からの続きです。EC2インスタンスを作成し、環境の設定を行います。

## EC2 インスタンスの作成

**EC2 Dashboard** から **Instances** に入り、**Launch instances** を選びます。
![Screen Shot 2563-12-13 at 01.29.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/727634/6e450b93-7093-5e78-1115-32d1f7926c21.png)
左の **Free tier only** をチェックすると、無料で使えるものが一覧で出ます。正直違いがあまりわからないので、一番最初の Amazon Linux でいいと思いますが(一応CentOS系ではあるらしい)、どうしても `apt` じゃなきゃ嫌だ！という人のために Ubuntu も用意されています。あと Windows Server もあるようです。
![Screen Shot 2563-12-13 at 01.32.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/727634/c1bbee9b-b062-f6bf-bc52-8f6a5ecd2ad6.png)
インスタンスタイプの選択肢は、無料なら **t2.micro** のみですがこれで十分です。**Configure Instance Details** へ進みます。
![Screen Shot 2563-12-13 at 01.54.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/727634/cd3dae40-262e-3ce2-ccfa-275ca5a8d657.png)
**Step 3: Configure Instance Details** は無料だとほぼ設定の余地がないのでそのまま次に行きます。

**Step 4: Add Storage** で容量の設定ができます、初期設定は 8GB ですが、最大 30GB まで増やせます (ただ、他の部分で使えなくなります)。メモリが 1GB しかないので、あとでストレージをスワップ利用することも考えて設定してください。ここではとりあえず初期設定のまま 8GB で進めます。
![Screen Shot 2563-12-13 at 01.57.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/727634/6fbbee84-0b11-334c-caa4-132483a0cd3b.png)

**Step 5: Add Tags** はただのタグ付けなので飛ばしても構いません。

**Step 6: Configure Security Group** で、**Select an existing security group** から先ほど設定しておいたセキュリティグループを選択します。
![Screen Shot 2563-12-13 at 02.04.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/727634/5402151d-0a25-cc1f-fa16-808a23006f18.png)
**Review and Launch** をクリックして進むと、知ってるIPアドレスだけに限定しないと危ないよ、と警告されますが、不特定多数がアクセスするWebアプリを作るのならば仕方ありません。無視して **Launch** します。
![Screen Shot 2563-12-13 at 02.06.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/727634/0a6188d3-5f6e-845f-34b7-1a2891a256c5.png)

## キーペア作成

**Launch** を押すと、SSH認証で使うキーペアを選ぶ画面が出ます。当然まだないので新しく作成します。Create a new key pair を選び、キーペアの名前を入力してダウンロードします。ここでは keypair という名前にしたので、`keypair.pem` という秘密鍵のファイルがダウンロードされます。これはホームディレクトリに置いておくと後々通信するときに楽かと思いますが、くれぐれも無くしたり流出しないように気をつけて下さい。
![Screen Shot 2563-12-13 at 02.09.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/727634/f7e24034-9a33-1cce-091e-6a966ea50dc7.png)
![Screen Shot 2563-12-13 at 02.16.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/727634/a63dedd9-c389-528d-3c1c-395fda06b896.png)

**Launch Instances** で設定完了です。


[その4](https://qiita.com/nozomiyamada/items/b7a0e41f8117a34ba3fa) に続きます。
【Swift5】少数を整数かどうか判断するメソッド


#Extension

```swift
extension FloatingPoint {
    func isInt() -> Bool {
        return floor(self) == self
    }
}
```

Swiftで少数というと```Double```やら```Float```やら``` CGFloat```やら色々ありますが、実はそれらをまとめて```FloatingPoint```と記述することができます。なのでそれに、```isInt```というどっかで見たことありそうな名前のメソッドをExtensionで作りました。

#Usage

このようにお使い下さいませ。

```swift

print((1.0).isInt())//true
print((1.1).isInt())//false
print((3.14159_26535_89793_23846_26433_83279_50288).isInt())//false

```
Gradle Kotlin DSLでversions.gradleのように依存ライブラリのバージョンを記述する

Gradleのマルチモジュールで構成されるプロジェクトの依存ライブラリのバージョン定義について。

従来のGroovy DSLだとversions.gradleのようなファイルに依存ライブラリのバージョンを記述して、各モジュールのbuild.gradleから参照することで、モジュールで使用している依存ライブラリのバージョンを統一できた。

Kotlin DSLでは、versions.gradleを定義する方法は使えない模様。ただし、別のやり方があるので、それを述べる。ファイルパスは、プロジェクトのルートフォルダ起点で示す。

## Step 1. 「buildSrc/build.gradle.kts」を作る

内容は以下のようにする。

```kotlin:build.gradle.kts
plugins {
    `kotlin-dsl`
}

repositories {
    jcenter()
}
```

## Step 2. 「buildSrc/src/main/java/Versions.kt」を作成する

例

```kotlin:Versions.kt
object Versions {
    const val kotlin = "1.4.20"
    const val appcompat = "1.2.0"
}
```

やりたければ、objectを入れ子にしたりしてライブラリのグルーピングもできる。普通のkotlinファイルなので。


## Step 3. 「build.gradle.kts」から参照する

後は、Step 2で定義した定数を参照すればよいだけ。以下、参照例。

```kotlin:build.gradle.kts
buildscript {
    repositories {
        ...
    }
    dependencies {
        ...
        classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:${Versions.kotlin}")
    }
}
```

```kotlin:module/build.gradle.kts
...

dependencies {
    implementation("org.jetbrains.kotlin:kotlin-stdlib:${Versions.kotlin}")
    implementation("androidx.appcompat:appcompat:${Versions.appcompat}")
    ...
}
```

## 注意事項

verisons.gradleだと、依存ライブラリに新しいバージョンがあれば警告が出るが、この方法だと出ない
[無料] AWS EC2 + RDS + Flask でWebアプリを作り HTTPS 化する [その2: セキュリティグループ]

## セキュリティグループ設定

[その1](https://qiita.com/nozomiyamada/items/1d18d87a85b798f5eaf5) からの続きです。EC2インスタンスを作成して仮想サーバーを構築する前に、セキュリティグループの設定をしておきます。

Services から EC2 を選択するとこんな画面になります。当然まだ何も無いかと思いきや、**Security groups** が既に一つあります。これは簡単に言えばファイアウォールみたいなもので、ポートを開けたりアドレスの指定を行います。まずはこれを弄ります。
![Screen Shot 2563-12-13 at 01.01.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/727634/cb2e836f-4321-8ac2-7c45-39fb88f8f69f.png)

**Name** が無いのは寂しいので、とりあえず `securitygroup1` とでも命名します。
![Screen Shot 2563-12-13 at 01.07.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/727634/877d43c4-6dcf-cb18-8e86-47d11f97910b.png)
下の方の **Inbound rules** から **Edit inbound rules** をクリックし、**Type** は HTTP を選択して80番ポートを開け、**Source** は 0.0.0.0/0 にします。こうしないとどこからでもアクセスできるようになりません。逆に言えば、不特定多数からのアクセスを前提としない、自分や身内だけのアプリケーションなどを作る場合には、IPアドレスを指定しておくと安全になります。
![Screen Shot 2563-12-13 at 01.12.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/727634/6b471b93-20a8-15ce-1067-5c04d8bf8863.png)
![Screen Shot 2563-12-13 at 01.15.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/727634/9159c82b-f39d-7a30-b1a1-4492d244e798.png)
**Add rule**から、 SSH(22), HTTPS(443) とデータベース用のポートも開けておきます。この例ではMySQLを使っているので 3306 番が開いてますが、PostgreSQL を選べば自動的に 5432 番が開きます。
![Screen Shot 2563-12-13 at 01.18.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/727634/7943b2df-4132-ba9a-3a31-a550ec72827b.png)
右下の **Save rules** で保存し、**Outbound rules** の方も同様に設定します。
![Screen Shot 2563-12-13 at 01.51.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/727634/61a0ae20-c4a7-aa61-7f8b-587859a1a5e6.png)

[その3](https://qiita.com/nozomiyamada/items/0be5844568eeceeca51d) EC2インスタンスの作成に続きます
Docker環境構築メモ

# インストール手順
## 公式ドキュメント
> https://docs.docker.com/engine/install/ubuntu/<br>

## 古いバージョンのアンインストール
```
sudo apt-get remove docker docker-engine docker.io containerd runc
```

## 新しいバージョンのインストール
```
sudo apt-get update
sudo apt-get install \
    apt-transport-https \
    ca-certificates \
    curl \
    gnupg-agent \
    software-properties-common

# 公式DockerのGPGキーを追加
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
sudo apt-key fingerprint 0EBFCD88

# x86_64/amd64を使用している場合
sudo add-apt-repository \
   "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
   $(lsb_release -cs) \
   stable"

# Docker Engine のインストール
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io

# バージョンの確認
docker --version
```

# テストイメージの実行
```
sudo docker pull hello-world
sudo docker run hello-world
sudo docker image ls
```
# rootユーザ以外にDockerコマンドの許可
```
# dockerユーザーグループを作成
sudo groupadd docker

# 現行ユーザをdockerグループに所属させる
sudo gpasswd -a $USER docker

# docker サービスの再起動
sudo service docker restart

# pcを再起動（ログアウト後、再ログインでも可）
sudo reboot now
```

# チュートリアル
```
# Git Clone
git clone https://github.com/dockersamples/node-bulletin-board
cd node-bulletin-board/bulletin-board-app

# Dockerイメージのビルド
sudo docker build --tag bulletinboard:1.0 .

# ビルドしたイメージをベースにしてコンテナを起動
sudo docker run --publish 8000:8080 --detach --name bb bulletinboard:1.0

# ブラウザで、localhost:8000へアクセス

# 起動中のコンテナを削除
sudo docker rm --force bb
```
## Nvidia-Docker2 インストール
```
distribution=$(. /etc/os-release;echo $ID$VERSION_ID) \
   && curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | sudo apt-key add - \
   && curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list | sudo tee /etc/apt/sources.list.d/nvidia-docker.list
sudo apt-get update
sudo apt-get install -y nvidia-docker2
sudo service docker restart
sudo reboot now
```
## Docker-Compose インストール
```
sudo apt-get update
# いろんな環境で都合がいいのでpython3.7を利用。他バージョンでも可。
sudo apt-get install python3 python3-pip python3.7
python3.7 -m pip install pip
python3.7 -m pip install docker-compose
sudo curl -L --fail https://github.com/docker/compose/releases/download/1.28.2/run.sh -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
docker-compose --version
```
勉強でOneNoteなどを活用してみた

　※投稿遅れましまい申し訳ございませんでした。

#動機について
　私は文字を書くのが苦手で、板書で時間を掛けていました。
後期に差し掛かってから、書くことが増えて書ききれないことありました。
ですが、１か月前からOneNoteを使ってみたところ、思いのほか便利でした。
今回は、少ないですがOneNoteを使用した際に実際活用したことを紹介します。

#使用環境
・Windows8.1 Pro
・Microsoft Office Home and Business Premium

#実際に活用したこと
　・数式の入力
　　挿入→記号と特殊文字→数式をクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/869424/e88a2b85-5123-a654-bb35-0e5e8b2dad11.png)
　　リボンがこんな風になる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/869424/29b89719-077d-bb63-f250-a203c60f6867.png)
　分数、上付き/下付き文字など数式で使われる表現ができます。　　
　現在、私が使っている環境だと、数式の入力中にひらがなから英語に切り替える際に
　入力モードが半角英数になってしまうのがネックです。
　　実際の使用例：
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/869424/4319b529-4074-a189-1d8f-e7908a482fe5.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/869424/13ea48e7-86eb-6b02-d87c-a862a73900be.png)

　・PowerPointで描いた図形を貼り付ける。
　　PowerPointで図形を選択してOneNoteのページに貼り付ける。
　　他のOfficeの製品に頼ってしまっているが、フロチャートや図解を描きたい時に使えます。
　　Excelでも図形を描けるが貼り付ける際にセルが邪魔で不向きです。
　　実際の使用例：
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/869424/eb1d6717-b590-0201-b57d-228eed400388.png)

#最後に
　初めての技術記事投稿だったというのもあり、当初は少し凝ったテーマにしようと考えました。
しかし、思いついたプログラムを書こうとしても、うまくいかず模索し続けた結果、担当日に間に合えませんでした。
　OneNoteの扱いに関しても、ノートシールなどまだ使ってない機能もあり、まだまだです。
学習効率を少しでも上げるためにも、今後も使っていきたいと思います。
マンガでわかる入力クラッジミニアンチパターン

![936D4C12-56F0-4336-9190-8B17EE0D783C.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/11525/f34f9ed4-1833-2d49-dae9-2759e7b9bbc5.png)

(http://wiki.c2.com/?InputKludge 現在エラー)

クラッジというのは、もともと同時利用を考えて作られたものでなかったため正常に機能しない、とりあえずで採用してしまった複数の装置の組み合わせのことを意味します。

入力クラッジパターンの場合、本来は内部で整合性を取らなければならない不具合が起きている状況なのに、入力の時点で付け焼き刃な取り繕いをしてしまうことで起きる問題を表します。

特定の入力値だけに施した当て布だと、他のバリエーションには効果がありません。入力段階で全てきちんとするには、内部の仕様を網羅しなければいけない、知りすぎ問題が発生します。また、もしその後内部を修正しようとすると、こんどはクラッジから来た入力値が、ユーザーの意図しない不正なデータとなって別の不具合を生んでしまうため、内部のバグを修正できない状況が発生してしまいます。

アンチパターン本が出版された時点ではまだ認識がなかったかもしれませんが、PHP の [Magic Quote](https://www.php.net/manual/ja/info.configuration.php#ini.magic-quotes-gpc) は世界一有名な入力クラッジの例でしょう。こんな露骨なアンチパターンを選択せざるをえなかった当時の SQL インジェクションの惨状が伺えます。(マトモなユーザーは当時でも使いませんでしたし、現在は完全に廃止されました)
コピペしてスタートアップフォルダに追加するVBSファイルを簡単に(プログラミング能力低いので8時間かかった)つくったので練習用備忘録

そもそもVBSとは？
簡単に言えばwindows上で動作するプログラミング言語です。C言語やJAVAなどとは違ってコンパイルが必要なくサクッと書ける言語です。
メモ帳で書けるので開発環境なども用意しなくていいのでほんとにすぐ書けます。
PCを使っていてめんどくさいなーって思うルーティン作業を自動でやってくれるので便利です当たり前ですが。
拡張子は.vbsです。
↓↓↓↓こんな感じ
![スクリーンショット 2020-12-13 023916.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/826735/e2611ac3-525e-9170-ace3-af8f93ad831f.png)

今回自分が作るVBSファイルはスタートアップフォルダにお気に入りのwebサイトを簡単に登録されるものです。
一部参考にしたソースコードなどもあります。
使い方はvbsファイルをクリックし、発生したダイアログ内にURLを張り、OKをしたら完了です。次回の起動時に好みのWEBサイトが立ち上がります、ただ、ブラウザが別々に立ち上がるので使い勝手は悪いです( ´∀｀ )
今後もコードを書き換えていきますが、VBSの練習として作ったものなのであとから精度を上げていきたいと思います。

以下ソースコードです。

```
Option Explicit

Dim objShell: Set objShell = CreateObject("WScript.Shell")

'ユーザー側が入力するオブジェクト
Dim userlikeurl

'ファイル名のオブジェクト
Dim userfilename
'httpsのフラグ変数オブジェクト用意しておく
Dim httpsname 
httpsname = ("https:")

userlikeurl = InputBox ("検索エンジンからコピーしたURLをペーストしてください。")

'userlikeurlの中身が空の場合.vbsの処理を終了させる。そうしないと32行目で存在しないパスですよ！！と怒られるので,,
If IsEmpty(userlikeurl) Then
    MsgBox("処理がキャンセルされました。")
    WScript.Quit
Else  
    MsgBox("urlの処理を開始します。")
    MsgBox(userlikeurl)
End If

'ここからファイル名の分岐をする先に"/"をreplaceでとる
userfilename = replace(userlikeurl,"/","")
MsgBox userfilename
If InStr(userfilename,httpsname) > 0 Then
   userfilename = replace(userfilename,httpsname,"")
   MsgBox userfilename
ElseIf InStr(userfilename,"http") > 0 Then
    userfilename = replace(userfilename,"http","")  
End If

MsgBox userlikeurl
' ショートカットを作成する
Dim newShortcut
'urlを指定して、ファイルを生成してnewsShortcutに代入
Set newShortcut = objShell.CreateShortcut( objShell.SpecialFolders("Startup") + "\" + userfilename +".url")
MsgBox newShortcut
newShortcut.TargetPath = userlikeurl
newShortcut.Save
CreateObject("Shell.Application").Explore(objShell.SpecialFolders("Startup"))
' オブジェクト解放
Set newShortcut = Nothing
Set objShell = Nothing
Set userlikeurl = Nothing
Set userfilename = Nothing
Set httpsname = Nothing
```

結構粗が目立つソースコードなのでのせるか悩んだのですが、、
同一オリジンポリシーを理解する

# はじめに

```
Access to XMLHttpRequest at 'http://example.com ' from origin 'http://sample.jp ' has been blocked by CORS policy:
No 'Access-Control-Allow-Origin' header is present on the requested resource
```

JavaScriptを使用している方は、上記のエラーを目にしたことがあると思います。
エラー内容を要約すると「あなたのサイトからのリクエストは許可していません」といった意味で、JavaScriptで`XMLHttpRquest`や`Fetch API`を使ってAJAX通信をする際に起こりうるものとなります。
これは同一オリジンポリシー（Same-Origin Policy）という規約に違反していることが根本の原因なのですが、この同一オリジンポリシーというものを理解するべく、なるべく簡潔にまとめたいと思います。


# 同一オリジンポリシーとは

ウェブブラウザに実装された、リソース取り扱いに関するセキュリティ上の仕組みで「同一生成元ポリシー」や「同一源泉ポリシー」とも呼ばれます。
スキーム（プロトコル）、ホスト、ポートの3つの組み合わせをオリジンと呼び、これらが同じ場合は同一のオリジンとみなし、同じ保護範囲のリソースとして取り扱うというものです。
つまり、異なるオリジン（クロスオリジン）からのリソースへのアクセスを制限するという仕組みになります。


# オリジンとは

スキーム（プロトコル）、ホスト、ポートから構成されるもので、それぞれはURLの一部分を指しています。

`http://store.example.com:80/foo`

上記のURLを例に挙げた場合は以下のようになります。
- スキーム（プロトコル） = `http`
- ホスト = `store.example.com`
- ポート = `80`

これらが1つでも異なる場合は**異なるオリジン**として判断されます。


# メリット

同一オリジンポリシーが存在しない場合どうなるのか。
例えばユーザーがECサイトにログインしている状態で別の悪意あるサイトを閲覧した場合、ECサイトに登録された個人情報を悪意あるサイトから取得できてしまいます。
このようにサイトをまたがった攻撃は「受動的攻撃」と呼ばれ、代表的なものにクロスサイト・スクリプティング（XSS）やクロスサイト・リクエストフォージェリ（CSRF）があります。
同一オリジンポリシーによって受動的攻撃を防止していますが、もちろん完璧ではなく、Webサイト・アプリケーション自体に脆弱性があれば受動的攻撃を受ける場合があります。


# 制限の対象となるもの・ならないもの

「異なるオリジンからのリソースへのアクセスを制限する」と説明しましたが、別オリジンの画像やJavaScriptの読み込みができることから分かるように、同一オリジンポリシーによって制限されるもの・されないものが存在します。


## 制限の対象となるもの

- **JavaScriptでの非同期通信**  
  厳密には「リクエストはできるがレスポンスを取得できない」という制限で、クロスオリジンでは許可された場合にしかレスポンスを取得することはできません。
- **Canvas**  
  異なるのオリジンから読み込まれた画像・データをCanvas内に描画するとCanvasは汚染（taint）されます。
  汚染されたCanvasではデータへのアクセス（`getImageData()`、`toBlob()`、`toDataURL()`）が制限されます。
- **Web Storage**  
  Web Storageなどのブラウザー内部に保存されるデータへのアクセスはオリジン単位で権限が分かれているため、異なるオリジンに属するストレージを読み書きすることはできません。
- **X-Frame-Options**  
  レスポンスヘッダーに`SAMEORIGIN`が設定されている場合、異なるオリジンでは`<iframe>`などを使った別サイトコンテンツの埋め込みができません。


## 制限の対象とならないもの

- `<scrip>`で読み込まれたJavaScript
- `<link>`で読み込まれたCSS
- `@font-face`で読み込まれたWebフォント  
  注）クロスオリジンでは許可されないブラウザもあります。
- `<img>`で読み込まれた画像（PNG、JPEG、GIF、BMP、SVGがサポート対象）
- `<video>`、`<audio>` タグで読み込まれたメディアファイル
- `<object>`、`<embed>` タグで埋め込まれたリソース
- `<iframe>`、`<frame>`での別サイトコンテンツの読み込み  
  注）コンテンツの読み込みは許可されますが、コンテンツ内のドキュメントにはアクセスできません。


## オリジン以外をベースに制限を設けているもの

- Cookie  
  Cookieに関してはスキーム、ポートは関係ありません。
- HTTP認証


# クロスオリジンのアクセスを許可するには

異なるオリジンへのアクセスを許可するにはオリジン間リソース共有（CORS）を使用します。
詳細は割愛しますが、CORSを使用することで特定のオリジンからのリクエストに対してはリソースへのアクセスを許可する、といったルールの制定が可能になります。


# 参考URL
- 同一オリジンポリシー（MDN）
  https://developer.mozilla.org/ja/docs/Web/Security/Same-origin_policy

- 同一生成元ポリシー（Wikipedia）
  https://ja.wikipedia.org/wiki/%E5%90%8C%E4%B8%80%E7%94%9F%E6%88%90%E5%85%83%E3%83%9D%E3%83%AA%E3%82%B7%E3%83%BC

- Same-Origin Policy とは何なのか。
  http://hasegawa.hatenablog.com/entry/20130330/p1

- 画像とキャンバスをオリジン間で利用できるようにする（MDN）
  https://developer.mozilla.org/ja/docs/Web/HTML/CORS_enabled_image
Webアプリ開発者のための、Flutter（モバイルアプリ開発）入門

Ateam Group Manager ＆ Specialist Advent Calendar 2020の13日目は株式会社エイチーム引越し侍のアシスタントマネージャー、小堀が担当します！

# はじめに

普段はWebアプリ開発をメインでやっております。
だた、このご時世、いつ何時モバイルアプリ開発のノウハウが必要になるかはわかりません。
そこで、この記事を書こうと思いました。

この記事では、Flutterの概要やReact Nativeとの比較にフォーカスをあてます。
具体的な開発（コード）については触れないので、ご了承ください。

普段はweb開発をしているけど、モバイルアプリの知識も欲しいという方はぜひみていってください！

# 2020年のモバイルアプリ開発事情とFlutter

Webの移り変わり同様、モバイルアプリもここ数年で大きく変わっていっています。
JavaとObjective-Cでモバイルアプリ開発をしていた時代から、
ネイティブのモバイルアプリ開発で用いられるのは、KotolinやSwiftへ移り変わり、
クロスプラットフォームとしては、ReactNativeやFlutterとさまざまな選択肢が出てきました。

その中でも今回取り上げる「**Flutter**とは何者なのか？」とよく比較される「React Nativeとの違い」を順に説明します。

## Flutterとは？

Googleが2018年に公開した、モバイルアプリフレームワークになります。
大きな特徴は以下の5点です。

1. クロスプラットフォームで動く
2. Dartという言語を用いて書く
3. ホットリロードで高速開発できる
4. UIライブラリが豊富
5. ネイティブと同等のパフォーマンス

### 1. クロスプラットフォームで動く

iOS、Androidそれぞれでコードを管理し、記述量も2倍となってくると目に見えて大変なので、クロスプラットフォームはとても魅力的に思えます。

デメリットとして、一部、ライブラリ等で対応できていないネイティブ機能があるようですが、Google製ということもあり、ライブラリも拡充しており、おおよそのことはネイティブのコードを書かなくても実現できそうです。

### 2. Dartという言語を用いて書く

モバイルアプリを作ることをメインに作られた言語のため、
UI作りに最適化されています。
Flutterのサンプルアプリをざっとみてみると、言語の特徴はある程度掴めるかと思います。
https://flutter.dev/docs/get-started/codelab

### 3. ホットリロードで高速開発できる

モバイルアプリ開発では、ビルドに時間がかかるという課題を長らく抱えていました。
ただ、FlutterはホットリロードでリアルタイムにUIを確認しながら開発することができます。

Webアプリでフロントエンド開発をしている方は、ホットリロードに慣れているかと思うので、この機能はありたいですね。

### 4. UIライブラリが豊富

標準コンポーネントとして、マテリアルデザインのUIが用意されています。
![Material-Components-widgets-1536x1173.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/136353/37054874-f60f-4022-2300-cffd8d26730f.jpeg)

もちろん完全にカスタマイズすることも可能です。

### 5. ネイティブ同等のパフォーマンス

Flutterでは、Dartのネイティブコンパイラにより、ネイティブマシンコードにコンパイルされるため、
ネイティブアプリ同等のパフォーマンスがあります。

## React Nativeとの違い

クロスプラットフォームにおいて、React Nativeは大きな選択肢の一つです。
特にWebアプリ開発のノウハウを最大限に生かせるReact Nativeはとても魅力的に思えます。

会社の状況や個人のスキルに応じて変わってくる部分も多いと思うので、
単純な比較でできる限り個人的な感情は排除して比較していきます。

### 1. 人気

それぞれ良い点が違うので、単純な人気で測れない部分もありますが、
コミュニティの活発やライブラリの拡充などに寄与してくるので、
Githubスター数やGoogle検索トレンドをみておきます。
人気度や勢いはFlutterの方が強そうです。

**Githubスター数**

Flutter： 109k
React Native： 92.1k

**Google検索トレンド**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/136353/34c15e9b-272f-03a5-ced6-8182d90d9c80.png)

### 2. パフォーマンス

Flutterは上に記載した通り、ネイティブ同等のパフォーマンスを持っており、
React Nativeよりもパフォーマンスは良いとされています。

### 3. 開発体験

ホットリロードはどちらも対応しており、エディタもネイティブアプリと比べると共に自由度が高くなっています。

### 4. 技術的難易度

こちらは、今までの経験によって変わってくることかと思います。

FlutterはDartという言語を用い、React Nativeはjsやtsを使えるため、
Webアプリ開発でReactを用いていた人にとっては、React Nativeの方が難易度は低く、
Flutterの方がハードルがあるかもしれません。
ただ、そこまでFlutterに特殊な構文があるわけではなく、アプリに特化した言語のため、チャレンジする価値はありそうです。

### 5. デプロイ

React Nativeはjsのため、ストアを通さずにUIの変更をすることも可能です。
ストア審査は厳しく、時間もかかるため、FlutterよりもReact Nativeの方が優れているかと思います。

## おわりに

普段Webアプリ開発をやっていて、なかなかモバイルアプリの知識を仕入れる機会がなかったので、
今回はFlutterについて色々調べてみました。
皆さんのご参考になれば幸いです。
Seleniumエラー一覧

# まえがき
Selenium webdriver(java)のエラー内容を簡単に参照できる場所がなかったのでこちらにまとめることにしました。

https://www.guru99.com/exception-handling-selenium.html
を機械的に翻訳しつつ、自分の経験を織り交ぜて加筆、修正しました。
元サイトの記載がどれほど正確かも不透明で、全ての例外に対してSeleniumのコードをしっかりと読んで書いたわけではないので完全な厳密性は保証できないですが、有用な情報も多く含んでいると思います。

#例外
全てではないですが、よく発生する例外を中心に記載しています。

## 操作対象を見つけられない系の例外
よく遭遇するやつ。操作をしようとした要素やフレームなどが見つからなかった場合に発生する例外。

|例外名|説明|
| ---- | ---- |
|NotFoundException|操作対象が存在しない場合に発生します。NoAlertPresentException, NoSuchContextException, NoSuchCookieException, NoSuchElementException, NoSuchFrameException, NoSuchWindowExceptionのスーパークラス|
|NoAlertPresentException|javascriptによるアラートが表示されていないにもかかわらずアラートを操作しようとした場合に発生|
|NoSuchContextException||
|NoSuchCookieException|現在閲覧しているドキュメントの関連づけられたCookieの中に、指定されたパス名と一致するCookieが見つからない場合に発生します。|
|NoSuchElementException|操作対象の要素が存在しない場合に発生|
|NoSuchFrameException|存在しないframeを選択しようとした場合に発生|
|NoSuchWindowException|存在しないウインドウターゲットを選択しようとした場合に発生|
|StaleElementReferenceException|操作対象の要素がDOMから削除された場合に発生します。|

## 要素に対して処理ができなかった系の例外
よく遭遇するやつ。操作をしようとした要素の状態が期待したものと違っていて操作できなかった場合に発生。

|例外名|説明|
| ---- | ---- |
|InvalidCoordinatesException|無効な座標を指定して操作を行った場合に発生します。|
|InvalidElementStateException|操作対象の要素がアクションを実行できない状態であるにもかかわらず操作しようとした場合に発生します。ElementNotInteractableException, ElementNotSelectableExceptionのスーパークラス|
|ElementNotInteractableException||
|ElementClickInterceptedException|操作対象の要素が別の要素に隠されていてクリックできなかった場合に発生します。|
|ElementNotVisibleException|操作対象の要素が非表示状態にあるために発生する例外|
|ElementNotSelectableException|操作対象の要素がDOMに存在するものの選択できない場合に発生する例外|

## それ以外(頻出)
上記以外でよく発生する例外。

|例外名|説明|
| ---- | ---- |
|TimeoutException|指定時間待機したものの、処理が成功しなかった場合に発生します。例えば、WebDriverWaitのuntilを利用して、ある要素を指定時間内検索したものの見つからなかった場合に発生します。|
|JavascriptException|ユーザーがWebDriverを通じて実行したJavaScriptにて例外が起きた場合に発生します。|
|SessionNotCreatedException|新しいセッションを正常に作成できなかった場合に発生します。|
|WebDriverException|Seleniumの例外の基底クラス。RuntimeExceptionのサブクラス。既存の例外で分類できないエラーは大概これだと思う。|

## それ以外

|例外名|説明|
| ---- | ---- |
|ConnectionClosedException|このタイプの例外は、ドライバーが切断された場合に発生します。|
|ImeActivationFailedException|IMEエンジンのアクティブ化が失敗した場合に発生します。|
|ImeNotAvailableException|IMEが利用できないにもかかわらず利用を試みた場合に発生します。|
|InsecureCertificateException|TLS証明書が無効または期限切れであること等が原因で証明書の警告が表示された場合に発生します。|
|InvalidArgumentException|不正な引数が渡された場合に発生します。|
|InvalidCookieDomainException|現在のURLとは異なるドメインでCookieを追加しようとしたときに発生します。|
|JsonException||
|ScreenshotException|画面キャプチャの取得ができなかった場合に発生します。|
|UnableToSetCookieException|ドライバーがCookieを設定できない場合に発生します。|
|UnexpectedTagNameException|対象要素のtag名がSelectではない場合に発生します。|
|UnhandledAlertException||
|UnknownServerException||
|UnreachableBrowserException|ブラウザまたはSeleniumサーバーとの通信に問題があったことを示します。|
|UnsupportedCommandException|実行したコマンドがサポートされていないことを示します。|
【教材】JavaScriptの教材を作ってみました1

※当方駆け出しエンジニアのため、間違っていることも多々あると思いますので、ご了承ください。また、間違いに気付いた方はご一報いただけると幸いです。

半人前のくせに、偉そうに教材を作ってみました。

##実装要件

イメージ
![e2ea8a0dc84c8e10827f07b63e5d5944 (1).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547556/f41f620f-47d2-f12d-6008-4e533e86a59a.gif)

###css
- 文字は中央に配置してください。
- カードは横並びで配置してください。

###javascript
- スタートボタンを押すと、初期カードが2枚配られる。
- 配られたカードの内、1枚があたり。
- あたりを引くと1枚追加される。
- あたりはランダムで配置される。
- 外れを引くと、1枚にリセットされて、成功した回数が表示される。
- 成功した回数は、失敗後1000ミリ秒経過してから表示される。
- 検証ツールで見た時、Elementsであたりが分からないようにしてください。
- その場合、検証ツールであたりがわかる方法を考えてください。

####注意点
DRYを意識して、コンパクトに記述してください。
 
####学べる技術

####css
- flexbox
- テキストの中央配置

####javascript
-　条件分岐（三項演算子)
-　繰り返し
-　コールバック関数
-　setTimeout構文
-　イベントリスナー
-　DOMの操作
-　ランダム関数
-　文字列への変数組み込み

###回答例(あまり鵜呑みにしないでください)

```html
<!DOCTYPE html>
<html lang="ja">

<head>
  <meta charset="utf-8">
  <title>JavaScript Practice</title>
  <style>
    #btnFlame {display: flex;}

    .box {
      width: 100px;
      height: 100px;
      background-color: skyblue;
      margin: 0 8px 8px 0;
      text-align: center;
      line-height: 100px;
    }
  </style>
</head>
<body>
 <div id="btnFlame"></div>
<script>この位置に下記のjsファイルを記載</script>
</body>
</html>
 ```

```js
const btnFlame = document.getElementById("btnFlame");  //枠組みノードを変数に格納
let num = 1;
const word = (word) => {  //カードに文字を入れる関数
  const box = document.getElementsByClassName("box");
  box[0].textContent = word;
}
const restart = () => {  //外れカードを引いた時の処理
  let result = num - 3;
  num = 1;
  make();
  setTimeout(function () { word(`結果：${result}`) }, 1000);  //遅れて結果を表示する処理。
}
const divide = () => { //あたりとハズレカードを作る関数
  let bingoNum = Math.floor(Math.random() * num);  //ランダムな数字を取得する関数。
  for (let i = 0; i < num; i++) {  //現在のnumの数に応じてカードを作成
    const div = document.createElement('div');
    div.classList.add("box");
    i === bingoNum ? div.addEventListener("click", make) : div.addEventListener("click", restart);
//三項演算子。ランダムに取得した数値と一致した場合、あたりのイベントリスナーつける。
    btnFlame.appendChild(div); //btnFlameの子要素として追加
  }
}
const deleteChild = () => { //btnFlameの子要素を削除する関数。
  while (btnFlame.firstChild) {
    btnFlame.removeChild(btnFlame.firstChild);
    }
  }
const make = () => { //カードを作成する関数。
  deleteChild();
  divide();
  num++;
}
make(); //スタートカードを作成。
word("スタート");
```

検証ツールであたりを確認する方法。
検証ツールのEvent Listenersタブから、紐づくイベント名を確認できる。
dockerで試しにコンテナを起動して停止時に削除する

dockerで試しにコンテナを使う場合、コンテナ停止時にゴミが残らないよう一緒に削除することが可能。
--rmオプションをつけることでコンテナ停止時にコンテナが削除される。
-dオプションを付けないとコンテナがフォアグラウンドで起動するのでcontrol + cで閉じればコンテナが削除される。

```
$ docker run --rm イメージ名
```
docker nginx起動する

nginx起動時にdaemon offを指定することでフォアグラウンドでnginxが起動するようにする。
デーモンで起動するとコンテナが直ぐにストップする。

```Dockerfile
FROM centos:centos8

RUN dnf install -y nginx

CMD ["nginx", "-g", "daemon off;"]
```

docker buildでイメージを作成し、docker runでコンテナ実行。-dをつけることでコンテナがバックグランドで起動する。-pでホストのポート8001にきたリクエストをコンテナの80ポートに転送してくれる。

```bash
$ docker build -t nginx_test .
$ docker run -d -p 8001:80 nginx_test
```

↓結果
http://localhost:8001
![スクリーンショット 2020-12-13 2.08.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278474/3dddc949-7c28-12ae-4839-b2073415a086.png)
TypeScriptのジェネリクスについて（初心者向け）

# はじめに

[TypeScript Deep Dive](https://typescript-jp.gitbook.io/deep-dive/)を読み学習したことを残します。

普段の開発では主にPHPを使っていますが、ジェネリクスという概念がPHPにはなく、どういったものなのか備忘録を兼ねて投稿します。

# ジェネリクスとは

https://typescript-jp.gitbook.io/deep-dive/type-system/generics

クラスのインスタンスメンバや、関数の引数や戻り値などに、型の制約を設けるためのパラメータを指定できる機能です。
引数に渡した配列の1つを返す `shift` 関数を例にすると、以下のように記述します。

```ts
// <T> の部分がジェネリクス。
function shift<T>(items: T[]): T {
  return items[0];
}
```

# どういったメリットがあるのか

上記の `shift` 関数では、引数と戻り値の型を強制できます。

```ts
// <T> の部分がジェネリクス。引数に渡した配列の1つを返す。
function shift<T>(items: T[]): T {
  return items[0];
}

let num = shift([1, 2, 3]); // num は number 型
let str = shift(['one', 'two', 'three']); // str は string 型

num.replace(); // Error
str.toFixed(); // Error
```

# まとめ

以上、ジェネリクスについてでした。
ジェネリックを使ったデザインパターンについても色々テクニックがありそうですので、いずれ記事を投稿したいと思います。
Raspberry Pi 日本語化 + 日本語入力

# 前提

Raspberry Pi 4

# 日本語化

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224453/520173f8-262f-efa0-d65e-66b93f6f603c.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224453/e8347758-be6d-4c77-ebad-f149bf372ebc.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224453/45693373-e06f-a174-fb0c-7ebcc03a593a.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224453/c117410a-bc27-d46e-51ee-53e6f1a992b4.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224453/ad5a2d3a-8752-de53-40d5-4425ca97c898.png)

再起動する。

# 日本語入力

### キーボード設定

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224453/9c7539f9-e936-1f7d-ce01-2479cabf99d8.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224453/6e6a6b08-8bd9-d553-b8d3-7c69bc75b603.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224453/e53114d9-525b-9c08-5c9a-d3acf681a963.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224453/8c694097-b1d9-2828-897e-a47ed3a8f476.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224453/feff51e1-7cbe-cf6e-5e30-93d7b1af113a.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224453/166eba4e-dd01-b2e1-060d-7db8f258105e.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224453/cde87cc4-d8fd-383d-dcb1-ed03f9620262.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224453/ae3bb1de-e064-11e4-fe42-435fd6d51fad.png)


### ibus mozcインストール

```
sudo apt install ibus-mozc
```

※結構時間かかる

再起動する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224453/2d6d781d-38da-db97-63ea-7be187a011cd.png)

Mozcは日本語になっているけど、IBusはEnglish・・・

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224453/45c2eed9-4745-4ce6-5ad5-4c7d0b71067c.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224453/ea0c6570-8bd3-ee65-7681-b12eccbb6175.png)
↓↓↓
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224453/22672312-b105-3e13-445e-602c276fca14.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224453/3b58f1cd-584c-647a-6024-775842032de9.png)

# 参考

https://qiita.com/sukinasaki/items/426068d6e87169fa3d88
https://www.ratocsystems.com/products/triple_r/blog/?x=entry:entry200521-092107;comments:1
https://www.indoorcorgielec.com/resources/raspberry-pi/raspberry-pi-input-japanese/
Ruby シンボルと文字列の違い

#ハッシュの書き方

Rubyのハッシュの書き方が3つ程あるのは最初に習うと思います。
なんで3つあるの？そもそもシンボルって？となったので文字列とシンボルの違いを見ていきます。そして自分は調べてシンボルで書く事に納得しました。

```ruby
country = { 'japan' => 'Tokyo', 'usa' => 'washington'}
country = { :japan => 'Tokyo', :usa => 'washington'}
country = { japan: 'Tokyo', usa: 'washington'}
```


##シンボルと文字列の特徴の違い
大きく分けて3つの違いがあります。
1,クラス
2,内部処理
3,オブジェクトID
4,ミュータブルかイミュターブル

###クラス

```ruby 
'example'.class
 => String
:example.class
 => Symbol
```
###内部処理
Rubyでは文字列は文字列として扱われます。ですが、シンボルは整数として管理されます。表面上文字列に見えますが、整数の為文字列より高速に処理されます。
###オブジェクトID
同じオブジェクトを複数作ります。文字列はそれぞれ別のオブジェクトとして生成されますがシンボルは同じシンボルであれば同じオブジェクトとして扱われます。その為メモリの使用効率がシンボルの方が良くなります。

```ruby
'example'.object_id => 70235159966100
'example'.object_id => 70332409696280
'example'.object_id => 70332409696200
:example.object_id => 1058268
:example.object_id => 1058268
:example.object_id => 1058268
```

###ミュータブルかイミュターブル
ミュータブルとは変更可能という意味でミュータブルなオブジェクトは破壊的な変更ができると言う事
イミュータブルは変更出来ない事です。
文字列はミュータブルでシンボルはイミュターブルです。その為シンボルは破壊的な変更がされないように出来るということになります。

##まとめ
シンボルのメリットとして
・**整数として扱われるので文字列より処理が速い**
・**同じシンボルは同じとして扱われるのでメモリ効率が良い**
・**イミュターブルな為破壊的な変更が出来ない**
MYSQL備忘録

プログラミング初心者です。個人的なメモとして活用しています。

#1環境構築をしたものの、アプリが立ち上がってもログインできない！
IDとPWが配られていない！
今までそう思っていましたがDBにIDとPWを突っ込んだらログインできたので記録として残します。


DBの接続が完了し、ID/PWが格納されているテーブルが特定されている状態とする。
```UPDATE 'ID/PWが格納されたテーブル名' set 'passwordが格納されてる箇所' = md5('使用したいパスワード') where id = 'ID名';```

これでログインできる。

#2DB関連のクエリの書き方
1.テーブルの作成
```create table db名.table名 (id int,name varchar(254));```

2.テーブルのデータ挿入
```insert into table名(id,name)
values (3,"Kate");
```

3.テーブルのデータ型の確認
```show columns from table名```

4.テーブルの中身の確認
```select * from table名```

5.テーブルへのAuto_incrementの追加
```alter table table名 add primary key (id);
alter table table名 change id id int(11) auto_increment;```