OmniAICreator/Qiita-1.07M huggingface dataset:
HTMLのclassとidの命名慣例 - 2022年の今、ベストプラクティスはあるのか？

はいさい！ちゅらデータぬオースティンやいびーん!

# 概要

今回の記事は、HTMLとCSSで使う`id`と`class`属性の命名のベストプラクティス（Best Practices）について解説します。

## 背景

仕事では、レガシーコードを改修する作業が度々発生しますが、毎度気になることがあります。

それは、HTMLおよびCSSの`id`と`class`属性の名前の付け方です。

どのプロジェクトでも、一貫性のある命名習慣を見た試しがないのです。

`<div id="hoge_hoge">`と名前をつける人もいれば、`<div id="HogeHoge">`の人もいるし、`<div id="_Hoge">`の人もいます。snake_caseやら、camelCaseやら、PascalCaseやら、あるとあらゆるパターンを見てきました。

そこで、今現在2022年において、明確なBest Practice、最善の命名方法はないのかとネットを漁りました。

そうすると、サンマと同じように、獲れはしたが、収穫はそんなになかったのです。

しかし！やはり、コンセンサスのようなものは見つかったので、ここでまとめたいと思いました。

# 全て小文字で書くこと

まず、第一の命名規則は以下の通りです。

```
alllowercaseletters
```

なんだか暗号みたいですが、`id`と`class`は全て小文字で書くことが一つの慣例になっています。

### Good

```html
<div id="alllowercaseletters">Hoge</div>
```

### Bad

```html
<div id="WhatstyleIsthisARGHHHH">Hoge</div>
```

# `_`ではなく、`-`を使うこと

次は、名前をシンボルで分けたい時に、アンダースコアではなく、ハイフンで分けることです。

### Good

```html
<div id="all-lower-case-letters-and-hyphens">Hoge</div>
```

### Bad

```html
<div id="youll_NEVER.UnderstandThis">Hoge</div>
```

# 数字を避けて英字を使うこと

こちらの規則は、極力英字[a-z]を使うようにすればいいということです。

そもそも、[0-9]で始まる`id`/`class`は不正なHTMLでもあるので、ご注意ください。

### Good

```html
<div id="section-two">Hoge</div>
```

### Bad

```html
<div id="h3llo_w0rld">Hoge</div>
```

# `.`を使わないこと

句読点の`.`を使って`special.element`のように分けることがありますが、こちらもやはり避けた方がいいです。

なぜなら、JavaScriptで`document.querySelector`を使うときに、`\`でエスケープする必要が生じるからです。

### Good

```html
<div id="section-two">Hoge</div>

<script>
 document.querySelector("#section-two");
</script>
```

### Bad

```html
<div id="horrible.coding">Hoge</div>

<script>
 document.querySelector("#horrible\.coding");
</script>
```

# まとめ

以上、いくつかの`id`と`class`の命名慣例とBest Practicesについて紹介しました。

実際、MDN、Vue.js、Reactなど、さまざまな公式ドキュメントを見ても、上記の規則を守って書いています。

上記の慣例を守ることも大事ですが、その上なく重要なのは、プロジェクトで書き方を統一することです。

個人個人の癖に任せるのではなく、Linter、フォーマッターを導入して、チームで書き方を統一することによって、オンボーディングしやすくなるし、迷いなく作業できるので、ぜひぜひコードの書き方についてチームメンバーで話し合って決めましょう！
【スクレイピング】テキストボックスに文字を入力

## 前提条件
#### インストール済み
1.python
2.pipは
3.anaconda
4.Jupyter Lab

## スクレイピングを始める4ステップ
1.ブラウザーのHTMLファイルから取得したいID（基本的にはinputタグ）
2.find_element（タグ名）などの引数の中に　1.のタグ名を加える
3.send_keys('入力したい文字入力')
4.ボタンに.onclickを加えて発火させる

# フロー
### 1.ブラウザーのHTMLファイルから取得したいID（基本的にはinputタグ）を確認する
＊検証画面→（使い方）https://skillhub.jp/blogs/269
![スクリーンショット 2022-08-27 17.26.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/714631/ea94aeda-3dc4-6eb9-e617-38119553bf59.png)

```html:htmlファイルの記述
<input id="username">
```

### 2.find_element（タグ名）などの引数の中に　1.のタグ名を加える
http://holiday-programmer.net/selenium_ver_check/#id
```
＃　旧　昔の書き方
from selenium import webdriver
target = browser.find_element_by_id("username")
＃　新　現在の書き方、こちらを参照すること
from selenium.webdriver.common.by import By
target = browser.find_element(By.ID,"username")
```
解説
1.selenium.webdriver.common.byから、Byというモジュールをインポートする
2.ブラウザに.find_element(By.ID,"ID名")を加える
＊参考資料
https://programmer-life.work/python/selenium-find_element_by_class_name-deprecated#import
https://qiita.com/syoshika_/items/288fc8bf552672589f4c

### 3.send_keys('入力したい文字入力')を加える
```
target = browser.find_element(By.ID,"username")
target.send_keys('書きたい文字')
```
### 4.ボタンに.onclickを加えて発火させる
```
btn = browser.find_element(By.ID,"login-btn").click()
```

## 参考資料
```
https://www.youtube.com/watch?v=VRFfAeW30qE
すごくわかりやすかったです。
```
AWSアカウントの多要素認証（MFA）設定手順

:::note warn
各画面は2022年8月現在のものです
:::

# スマホに認証アプリインストール
Google Authenticator などの認証アプリをインストールします

:::note info
iPhone用
https://apps.apple.com/jp/app/google-authenticator/id388497605
:::

:::note info
android用
https://play.google.com/store/apps/details?id=com.google.android.apps.authenticator2&hl=ja&gl=US
:::

# PCブラウザでの設定手順
AWS管理コンソール右上のアカウント名をクリックし、開いたメニューから【セキュリティ認証情報】をクリック
![a01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/200478/a16cd8be-5ce1-c3e3-1315-f421945d59c0.png)
AWS IAM 認証情報タブから【MFAデバイスの割り当て】をクリック
![a02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/200478/04b35436-ddad-5057-e302-96f5b17c42a5.png)
【仮想 MFA デバイス】を選択した状態で続行ボタンをクリック
![a03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/200478/7c3a8499-cf71-a8fc-a907-b1b388f41d2d.png)
アプリはインストール済みなので項番2から実施する
QRコードを表示させ、認証アプリでスキャンする
![a04-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/200478/47091499-2310-5366-ae41-f037c8f3d1eb.png)
AWSのアイコンとともに認証アプリに設定される（説明の都合上一番上に表示していますが、実際は一番下に追加されます）
※画面は Microsoft Authenticator (iOS版)
![IMG_5227.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/200478/1406de11-10b2-aa60-49fe-2dc7afb57d34.png)
認証アプリで表示されるコードを2回分入力し【MFAの割り当て】をクリック
![a04-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/200478/3d036c8a-08d9-54a5-beac-6b00c4c49343.png)
下記のような画面が表示されたら設定完了
![a05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/200478/14b5e2f5-b9c4-6b73-6f33-ddcfbdfc0a90.png)
# サインイン時の操作
いつものようにサインインすると、MFA設定が有効な場合はこのようにMFAコードを入力する画面が表示されるので、認証アプリに表示されるコードを入力しサインインする
![b02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/200478/1ee6d315-bb3d-1c56-493d-b848a734d97f.png)
Laravel初期設定でDB接続エラーが発生

Laravel9 を　マニュアルに沿ってインストール
php artisan migrate 


すると以下のエラーが発生（WinでもMacでも）

SQLSTATE[HY000] [2002] php_network_getaddresses: getaddrinfo for mysql failed: nodename nor servname provided, or not known (SQL: select * from information_schema.tables where table_schema = example_app and table_name = migrations and table_type = 'BASE TABLE')

.env の
DB_HOST=mysql
をいかに変更してリトライ
DB_HOST=localhost
すると、以下のエラーに
SQLSTATE[HY000] [2002] No such file or directory (SQL: select * from information_schema.tables where table_schema = example_app and table_name = migrations and table_type = 'BASE TABLE')

さらに
DB_HOST=127.0.0.1
としてリトライしたら成功！
DjangoのALLOWED_HOSTS

# ALLOWED_HOSTの意味
- クライアントからのリクエストを受け付けるサーバのアドレスを登録する環境変数。
- 値には、DjangoのWebアプリを提供するサーバーのホスト名をリストで指定する。


# ALLOWED_HOST役割
- HTTPのホスト・ヘッダー攻撃を防ぐため、つまりセキュリティ対策として設定する。
- クライアントからのリクエストに含まれるサーバアドレスがALLOWED_HOSTの値と異なる場合は、HTTPの400エラーを返す。
    - インターネット上のサーバを用いてWebアプリを公開する場合は、サーバに指定されているアドレスを登録することになる。

# 具体例
- 開発環境の場合、全てのホストを許可するワイルドカードを指定すると楽
    - ※本番環境では、セキュリティの問題から['*']を指定しないこと
```python:settings.py
 ALLOWED_HOSTS = ['*']
```

- サービスのドメインやIPアドレスを指定することも可
```python:settings.py
ALLOWED_HOSTS = ['www.example.com']

ALLOWED_HOSTS = ['20.0.0.0']
```
Google Compute EngineのCentos7を使ってLAMP環境のWordPress用サーバーを構築する

# Google Compute EngineのCentos7を使ってWordPressサーバーを構築する


## yumアップデート
※カーネルを除外したアップデート
```
yum -y update --exclude=kernel*
```

## apachのインストール
```
yum -y install httpd
```
バージョンの確認
```
httpd -version
```

自動起動の設定
```
systemctl enable httpd.service
```

起動
```
systemctl start httpd.service
```

状態確認
```
systemctl status httpd.service
```
参考
https://weblabo.oscasierra.net/apache-installing-apache24-yum-centos7-1/

## PHP7.4のインストール
初期状態のcentos7のphpは5.4という古いバージョンしか入っていない為、新しいphpをインストールします。
WordPressのプラグインでGatsbyを使用するのであればバージョンが7.4以上が必要になるので注意が必要です。

### Remiリポジトリの追加
```zsh
sudo yum -y install http://rpms.remirepo.net/enterprise/remi-release-7.rpm
```

### 古いphpの削除
```zsh
sudo yum remove php-*
```

### php7.4と周辺パッケージのインストール
```zsh
yum -y install --enablerepo=remi,remi-php74 php php-devel php-mbstring php-pdo php-gd php-mysqlnd
systemctl restart httpd
```
### バージョンの確認
```
php -v
```
https://www.rem-system.com/centos-php72-inst/#3_PHP

## MySQLのインストール
centOS7にはmariaDBが初期インストールされており、これが競合を起こす可能性がある為、事前に削除するのが推奨されているようです。

### mariaDBの削除

```
yum remove mariadb-libs
```

### MySQLリポジトリの追加
```
rpm --import https://repo.mysql.com/RPM-GPG-KEY-mysql-2022
```

### その他の設定
```
yum localinstall -y http://dev.mysql.com/get/mysql57-community-release-el7-7.noarch.rpm
```

### MySQLのインストール
```
yum -y install mysql-community-server
```

### wordpressに必要なものをインストール
```
yum -y install --enablerepo=remi,remi-php74 php php-mbstring php-xml php-xmlrpc php-gd php-pdo php-pecl-mcrypt php-mysqlnd php-pecl-mysql
```

### バージョン確認
```
mysqld --version
```

### 起動
```
systemctl enable mysqld.service
systemctl start mysqld.service
```

### MySQLの初期設定
#### 1.root ユーザーのパスワード確認
```
cat /var/log/mysqld.log | grep root
```

#### 2.mysql_secure_installation
```
mysql_secure_installation
y
※rootの新しいパスワードを設定
y
y
y
y
```

### MySQLにログイン
```
mysql -u root -p
```

### DB確認
```
show databases;
```

### DB作成
```
create database DB名；
```

## ディレクトリをwordpressを配置する場所に移動（任意）
```terminal
cd /var/www/html/
```

## wordpressのインストール

wgetのインストール
```
yum -y install wget
```

```
wget https://ja.wordpress.org/wordpress-5.9.3-ja.tar.gz
```

解凍
```
tar -zxvf wordpress-5.9.3-ja.tar.gz
```

圧縮ファイルの削除
```
rm -rf wordpress-5.7.2-ja.tar.gz
```

wordpressのオーナー変更
```
chown -R apache:apache wordpress
```
wordpressの権限変更
```
chmod -R 775 wordpress
```

## apacheのドキュメントルートを変更
```
vi /etc/httpd/conf/httpd.conf

*****以下ファイル内容*****
Documentroot /var/www/html/wordpress
```

### apacheの再起動
```
systemctl restart httpd
```

## gitのインストール
```:依存関係にあるものをインストール
sudo yum -y install gcc curl-devel expat-devel gettext-devel openssl-devel zlib-devel perl-ExtUtils-MakeMaker autoconf
```

```:インストールするディレクトに移動
cd /opt/
```
```:gitのダウンロード
sudo wget https://mirrors.edge.kernel.org/pub/software/scm/git/git-2.9.5.tar.gz
```
```:圧縮ファイルの解凍
sudo tar xzvf git-2.9.5.tar.gz
```
```:圧縮ファイルの削除
sudo rm git-2.9.5.tar.gz
```
```解凍先のディレクトへ移動
cd git-2.9.5/
```
```:makeコマンドでインストールする
sudo make prefix=/usr/local all
```
```
sudo make prefix=/usr/local install
```
```:バージョン確認
git --version
```
sedコマンドで、先頭にスペースをつけたい時の注意点など

※　centOSでやってるので、他のOSの方は同じ挙動をするかわかりません

```shell
 ❯ cat /etc/redhat-release 
CentOS Linux release 7.9.2009 (Core)
```

## 本文

sedコマンドは、テキストファイルに行を追加したり、文字を置き換えたりできる

```suzuki.txt
わたしは
すずきです
```

```shell
# 正規表現を用いた置き換え
$ sed -e "s/すずき/さとう/" suzuki.txt
わたしは
さとうです

# 行の追加（1行目の後に追加）
$ sed -e "1a さとうではなく" suzuki.txt
わたしは
さとうではなく
すずきです
```

前者では`すずき`を`さとう`に置き換えたが、この文字の先頭に半角スペースを2つ入れたい場合は以下の通り

（別に変数に入れる必要はないが、わかりやすいので使用する）

```shell
$ indent="  "
$ sed -e "s/すずき/${indent}さとう/" suzuki.txt
わたしは
  さとうです
```

これは別に迷うことはない。

ちなみに、インデントだけを入れて、`すずき`をそのままにしたい場合はこんな感じ

```shell
$ indent="  "
$ sed -e "s/\(すずき\)/${indent}\1/" suzuki.txt
わたしは
  すずきです
```

注意すべき点は以下の2つだろう。

- `()`はエスケープしないといけない（「`\(`」や「`\)`」としないといけない）
- `$1`ではなく、`\1`になっている

rubyなどの正規表現に慣れている人は、ここを間違いやすい（てか自分がそうだった）。


---

一方で、後者の「行の追加」場合は「`\`」をうまく使わうことで実現ができる

```shell
# 単純にスペースを入れるだけだとうまくいかない
$ sed -e "1a   さとうではなく" suzuki.txt
わたしは
さとうではなく
すずきです

# 文字列を「\」から始めて、そこから任意の数だけスペースを入れるとうまくいく
$ sed -e "1a \  さとうではなく" suzuki.txt
わたしは
  さとうではなく
すずきです
```

上記の例に変数を使わなかったのには理由があって、変数を使いたい場合は`「\」自体をエスケープしないといけない`ので、特に注意が必要。

今回の記事で一番言いたかったことはここ（意外と調べても出てこない）。

```shell
$ indent="  "

# 「\」が一つだけだと「$のエスケープ」という意味になってしまい、うまくいかない
$ sed -e "1a \${indent}さとうではなく" suzuki.txt
わたしは
${indent}さとうではなく
すずきです

# 「\」を使用して、「\」自身をエスケープするとうまくいく
$ sed -e "1a \\${indent}さとうではなく" suzuki.txt
わたしは
  さとうではなく
すずきです
```

以上、sedコマンドで、先頭にスペースをつけたい時に注意すべき点でした。
Windows10で誤編集防止用の設定が無いエクセルファイルを開く時の工夫

# 概要

エクセルの資料をちょっと開きたい。
でも、そのファイルには『読み取り専用属性』などの誤編集防止用の設定が全くない。
ちょっと開くだけだから誤って上書きとかしたくない…。

ファイルをコピーして開く方法だと、閉じた後にコピーしたファイルの削除が面倒。

もう少し簡単な方法で誤編集防止しつつエクセルファイル開きたい。

そんな時。

# 読み取り専用ではなく新規で開く

```Shift + ファイル上で右クリック``` で下記メニューが出る。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/4994beef-9cc2-bb75-d192-e53aa237d32e.png)

でもこの『読み取り専用で開く』だと読み取り専用で開かない。
なぜ…？

でも、別の方法で誤編集防止を実現できる。

```Shift + ファイル上で右クリック``` かつ『新規』で開く。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/0d792208-c3d3-0d00-0cbb-39e1c186342c.png)

すると **複製して別名ファイルを作成する** 状態で開く。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/9b128f21-412e-00cd-cbb8-51d4f501d885.png)

この状態だと、何か編集してしまった後、ファイルを閉じようとすると下記が出る。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/d2621e65-304d-ee3b-c49f-bbd3e10767f9.png)

『保存しない』を選択すれば、 **原本は上書きされず、別ファイルが作成されることもない** 。
誤って『保存』を選択しても **原本は上書きされず、別ファイルが作成されるだけ** 。

どちらに転んでも誤編集はされない。
ゴミファイルの削除に関わる面倒も多少は減る。

# 蛇足

エクセルの資料もGitとかでバージョン管理した方が楽。

# 参考サイトさん

https://amaotolog.com/excel/48

# バージョン

Windows 10 Pro 21H2 OSビルド 19044.1889
Microsoft Excel for Microsoft 365 MSO (バージョン 2207 ビルド 16.0.15427.20166) 32 ビット

TODO:エクセルを差分チェックできる形でGitでバージョン管理する方法調べる。
java ラムダ式によるソート処理

# ラムダ式とは？
- ラムダ式とは関数型インターフェイスを実装したクラスのインスタンスを、短いコーディング量で簡単に作れてしまう文法のこと

# ラムダ式の使い方

- ソート例

```java:sample.java

	List<SearchResult> pageList; //あるモデルのリスト
	List<SearchResult> newList = new ArrayList<SearchResult>();

// pageListをソートする
// ソート条件は次の通り。ファイル更新日付 desc, ファイル名 asc, ページNo asc　
	pageList.stream().sorted(Comparator.comparing(SearchResult::getUpdate_dt_is).reversed()
			.thenComparing(SearchResult::getPureFileName)
			.thenComparing((s1, s2) -> Integer.parseInt(s1.getPageNo()) - Integer.parseInt(s2.getPageNo()))
			.forEach(i -> newList.add(i));
			
```

このように、ソート用のクラスを作成せずに、4,5行でソートすることができる。

ラムダ式を使った他の例はまた次回。
Python,Ruby,PHP,Java,JavaScript,Perlの多次元データ構造の比較 | プログラミング言語比較


<a href="https://qiita.com/yuki_kimoto/items/f9c2454e7f9130ddb003">Qiita > プログラミング言語の比較</a>

プログラミング言語Python,Ruby,PHP,Java,JavaScript,Perlの多次元データ構造の比較

# Python

https://qiita.com/ko0821/items/4c8a557ec88f2a10bd55

# Ruby

https://qiita.com/vzvu3k6k/items/1705c7f4b29c08787ea0

# PHP

https://qiita.com/shuntaro_tamura/items/784cfd61f355516dfff0

# Java

https://qiita.com/panda-chibi/items/e57799c047be69fe5b79

# JavaScript

https://qiita.com/Stack_up_Rising/items/cb71842d7c3510daf9f0

# Perl

https://perlzemi.com/blog/20100930127859.html
SCD30から取得した湿度情報が100%を上回ることがある

（備忘録）

### 現象
SCD30を使用して環境情報の測定を行っているが、湿度が非常に高いときなどに取得する湿度が101%～110%になることがある。
CO2や温度はおおよそ正しい値の為、故障しているというわけではなさそう。

### 結論
恐らく温度のオフセットが原因

### 理由
湿度は　__水蒸気圧 / 飽和水蒸気圧 * 100__　の計算式で求められる。
このうち飽和水蒸気圧は温度をもとに算出、水蒸気圧はSCD30が計測した値から算出していると思われるが、
恐らくここでの計算にオフセットでの温度の変化が考慮されていないと思われる。

SCD30には基盤の温度を考慮するため、[0.01℃単位の温度オフセット機能が存在している](https://sensirion.com/media/documents/D7CEEF4A/6165372F/Sensirion_CO2_Sensors_SCD30_Interface_Description.pdf)。
このオフセットを高ければ高くするほど、SCD30が取得する温度が __低くなる__

飽和水蒸気圧は温度の高さに比例して大きさが変わるため
| 温度 | 飽和水蒸気圧 |
|:-:|:-:|
| 100  | 1021.938317  |
| 50   | 123.3504215  |
| 20   | 23.38093514  |
| 10   | 12.27892033  |
| 0    | 6.1078       |
| -10  | 2.857093169  |
| -20  | 1.246220485  |

温度にオフセットをかけた状態で __取得したままの水蒸気圧の値で計算すると、異常な湿度が算出される可能性がある。__ 

例えば現在の温度が20℃で湿度が50%であった場合、取得される水蒸気圧はおおよそ11.69となる。
この状態で温度オフセットを20℃かけ、それを水蒸気圧の計算で考慮しない場合
計算式は __11.69 / 6.10 * 100__　となってしまい、結果 __湿度が191%__ となる。

### 備考
問い合わせを行ったわけではないので確定ではない。
ただ実際に取得したデータを見てみるとおおよそ上記の推測通りの値を取得してくるため、ほぼ間違いないと思われる。
【スクレイピング】Jupiter Labを使うまで

## 用意するもの
#### 1.python:今回使用する機械学習に適したプログラミング言語
#### 2.pip:pythonのライブラリを取りまとめるパッケージ管理ツール
#### 3.anaconda:必要なライブラリをまとめてインストールしてくれるツール
#### 4.ジュピターラボ:ノートにプログラミングを記述→瞬時に結果を返してくれる（コードの成否を確認しながら進めることができる）
→毎回ターミナル開いて実行、、また実行、、ということをしなくても良くなる
https://ai-inter1.com/jupyter-lab/#st-toc-h-1

#### 5.pip:パッケージ管理ツール
https://www.python-izm.com/tips/pip/
#### 6.anaconda:必要なライブラリをまとめてインストールしてくれる
https://www.javadrive.jp/python/install/index5.html

#### 7.selenium→ブラウザー自動化を可能にし、それを支えるツール群とライブラリー群プロジェク ブラウザ操作の時はこちらの方が向いているとのこと
＊BeautifulSoup→htmlのコードを解析する　値をとっていくだけ

#### 8.クロムドライバー:chromeにアクセスするための設定（MAC）＊windowsはWEB経由でインストールするみたい
https://valmore.work/how-to-use-selenium-webdriver/#:~:text=ChromeDriver%E3%81%A8%E3%81%AF%E3%80%81Google%20Chrome,%E3%83%89%E3%83%A9%E3%82%A4%E3%83%90%E3%82%92%E9%81%B8%E3%82%93%E3%81%A7%E3%81%8F%E3%81%A0%E3%81%95%E3%81%84%E3%80%82

## フロー
### jupiterを立ち上げる
```python:jupyterlabをインストールする 
pip install jupyterlab
```
```:インストールしたjupiterを立ち上げる
jupyter lab　立ち上げる
```
→勝手に立ち上がる
![スクリーンショット 2022-08-25 18.27.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/714631/2c0bb038-4f66-0792-96e2-4222729dda8b.png)
### jupiter lab内でターミナルを実行する
例）!pip install jupyterlab
jupiter labでターミナルを実行する🌟！をコマンドの先頭に忘れないこと
![スクリーンショット 2022-08-25 17.01.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/714631/e00dd2d7-d420-948d-8c30-fc6cae758b1a.png)

### seleniumをインストール→モジュール化
```:インストール
!pip install selenium
```
```:モジュール化(seleniumからwebdriverを取り出しましょう)
from selenium import webdriver
```
### chromedriverをインストール→モジュール化
```:インストール（chromedriverはpythonだけのものではないのでbrewにてインストールしましょう）
!brew install chromedriver
```
## クロムを開く
```:インストール（chromedriverはpythonだけのものではないのでbrewにてインストールしましょう）
browser=webdriver.Chrome()
```

## 参考資料
```
https://www.youtube.com/watch?v=VRFfAeW30qE
すごくわかりやすかったです。
```
【Go】Go言語入門①ーGo言語の第一歩

# はじめ

　**Mac** でgo言語を勉強しはじめました。
　自分の成長を記録したいので、記事をアップロードしました。

　macOS Big Sur : 11.6.1

# インストール
HowmebrewでGoをインストールする。
```
$ brew install go
```

### バージョン確認
インストールをしてから、バージョンを確認する
```
$ go version
go version go1.19 darwin/amd64
```

# goファイルを作成
テストファイル（hello.go）を作成する。
```
$ touch hello.go
```

hello.goファイルに下記のソースコードを記入する。

``` go
package main

import "fmt"

func main() {
	fmt.Println("hello world!")
}
```
　
編集してから、実行する。

# 実行

## 実行方法1
ビルドして実行する。
```
$ go build hello.go
```
同じディレクトリにバイナリデータ（hello）が生成される。
次に、**バイナリデータ（hello）** 実行する。
```
$ ./hello
hello world!
```

## 実行方法２
ビルドせずに、**hello.go** を実行する場合、「**go run**」コマンドを使用する。（バイナリデータを生成しない）
```
$ go run hello.go
hello world!
```

![実行分析](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/684879/9fc514f5-e714-05ac-ff92-e654d053641c.png)


# 補足
- ビルドはうまく行けない場合、PATH問題（未設定か、設定ミス）かもしれません。
あの頃のマージのコンフリクトを起こしたい

## 経緯
チームのメンバーに「少し前にマージした時にコンフリクトしたファイル一覧を知りたい」と質問された時に、僕は「どうやったら良いんやろ、、、」と思いました。そこで調べている中でマージログの見方を初めて知ったので記事にしようと思います。
解決方法はあの頃のコンフリクトをもう一度起こしてコンフリクトしたファイル一覧を調べました。

## 手順
- マージコミットを特定する
- マージ前の親ブランチと作業ブランチを作成する

親ブランチ：　取り込むブランチ
作業ブランチ：　今いるブランチ
### マージコミットを特定する
```shell
# マージログ一覧表示
git log --merges 

# ログをワンラインで表示する
git log --oneline
```
どちらかのコマンドを流して、コミットを特定します。
あの頃マージした時、マージコマンドで`--no-ff`オプションをつけていない場合はマージコミットが残らないです。
–no-ff オプションを付け忘れたマージをやり直す方法
https://oki2a24.com/2016/02/18/redo-git-merge-with-no-ff/

### マージ前の親ブランチと作業ブランチを作成する
```shell
# 特定したマージコミット
commit cccccccccccccccccccccccccccccc
Merge: aaaaaaaa bbbbbbbb
Author: qiita.taro <mail adoress>
Date:   Wed Aug 10 13:30:59 2022 +0900

    コミットメッセージ

```
マージログの2つのコミットIDは以下のコミットです。
aaaaaaaa：　親ブランチのマージ前の最新コミットID
bbbbbbbb：　作業ブランチのマージ前の最新ミットID

これよりマージ前のブランチを作成します。

```shell
# あの頃のブラントを作成
git chechout -b [作成するブランチ名] [コミットID]
 
# マージ前の作業ブランチを作成
git checkout -b old_working_branch bbbbbbbb
# マージ前の親ブランチを作成
git checkout -b old_parent_branch aaaaaaaa
```
作成後もう一度マージするとあの頃と同じコンフリクトが起きるので、ファイル一覧やコンフリクトの内容が確認できます。
## 最後に
このやり方以外でいい方法があればぜひコメントお願いします。
#1 32歳エンジニア未経験の就活とは〜言語以外の知識も必要と悟ったあの日〜

こんにちは。

ご覧いただきありがとうございます。

まずは簡単に自己紹介をさせていただきます！！

# 初めに自己紹介
はじめまして。

IT業界未経験で32歳フルスタックエンジニア志望の **田原** と申します！

前職は航空業界に7年身を置いており、全く異なる畑に挑戦しています。

言語は

- フロントエンド：HTML/CSS/JavaScript
- バックエンド：PHP

を職業訓練校とプログラミングスクールで身につけました。

現在、React.jsを勉強しており、Classコンポーネントと関数コンポーネントの違いがわかってきたレベルです。

そして絶賛就活中という状況です。


# Qiitaを書くきっかけ

結論からお伝えすると「アウトプットのため」です。

2022年8月上旬から始めた就活。

本格的に書類→面接のフェーズに入って早2週間が経ちました。

面接していただいているなかでたまにわからない用語があり、それがブログを書き始めようと思ったきっかけです・・・。

面接の中で気づきました・・・。

エンジニアは、言語はもちろん
- 　データベース
- 　インフラ
- 　ソフトウェアエンジニアリング（CI/CD）
- 　バージョン管理
- 　コミュニケーションツール

などなど、エンジニアとして開発作業をする中で使用するツールの知識や開発を支える作業の知識が必要だと・・・。

ある面接の際、質問のなかでGithubについて面接の方が触れられたのでGithubは使いますか？と今思うと勇者の質問をしたのですが・・・　**未経験者でも就職前にアップロードや他の方のコードを読めるようになってた方が当社で縁があった場合は良い**　とアドバイスをいただきました。


そもそも、勉強している中でGithubを参照してフレームワークやライブラリの解読をしていましたがアウトプットとして使いこなせていませんでした！


# 対象者

- エンジニア未経験で就活中の方

を対象に、面接で感じたことをきっかけにアウトプットして行きます。

私が初心者なのでおこがましいですがエンジニア未経験で就活をされている方は少なからずいらっしゃると思います。

同じ境遇の方などに少しでも参考になれば嬉しい限りです。

# 勉強すること

これから、まずGitやGithubの勉強を始めます。

もうすでに起動からつまづいたので、シェアしたいところです。

他の方のブログのおかげでなんとか峠を乗り越えました。

# これから

第1章としたのは、就職ができてからも続けれるように思いも込めて。

Qiita初心者でもあるので、他の方をブログを参考にしながらわかりやすく記事を投稿できればと思います。

もしご覧いただいた方で、ぜひお気づきの点や間違っている点などご教示いただけると幸いです！

以上、これからよろしくお願いします。
gitHub Pagesでアプリ公開

# 序
---
## こんなことありませんか？
- 言語を覚えて頑張ってアプリ作った
- けどlocalhost:3000はダサい！(別にダサくない)
- →公開、したくね？
---
## こうも思いませんか？
- アプリを公開するためにはサーバを立てればいい。なるほどね。
- で、なにすればいいの？Nginx？コンテナ？ふぇぇ。。。
- 😫。○(言語で精いっぱい…もう体力の限界)
---
# ということで、簡単にアプリを公開しよう
---
## 注
- gh-pagesで公開できるのは静的なアプリだけです
- サーバとかDBとか色々使いたい人は自分でサーバを立ててみましょう(インフラないがしろにするといつかエンジニア人生詰む気がします。。。)。
- さくっと半自分用。スライドモードのテストも兼ねているため、割と説明粗めです
---
## 手順
- 手順1.gitHubアカウントの用意
- 手順2.アプリケーションの用意
- 手順3.リポジトリ作成
- 手順4.gitHub Pagesの設定
---
## 手順1.gitHubアカウントの用意
---
- まずはgitHubアカウントを用意しましょう
  - https://github.com/
- 色々なエンジニアサイトのアカウントを登録するときに連携できてべんり。Qiitaアカウントはgitに紐づけていたような気がします。
- gitって何？や、細かい設定方法についてはこちらを見てください。
  - https://qiita.com/b150005/items/508009234bf9813b230f
---
## 手順2.アプリケーションの用意
---
- 上げたいアプリを選びましょう
- 何でもいいので用意しましょう。「~.html」ファイル用意して```<div>test</div>```だけでもOKです
---
## 手順3.リポジトリ作成
---
- 超簡単に言うと、アプリの単位みたいなものです。
  - https://qiita.com/ucan-lab/items/d594404d0d2c64a85a38
  - できたらファイルをアップロードしましょう
    - https://docs.github.com/ja/repositories/working-with-files/managing-files/adding-a-file-to-a-repository
- コマンドでやる人向け
  - https://qiita.com/tanoken729b/items/b71db702624977c29be9
---
## 手順4.gitHub Pagesの設定
---
- gitHubアカウントページ＞作ったリポジトリ＞「Setting」タブ＞左側メニューの「Pages」をクリック
- 「Branch」の欄が「None」になっていたら、masterとかmain(ブランチ名)に変更してSaveボタンを押しましょう
---
### 以上で操作は終了です。
- 数分待ってから公開されたアプリを見てみましょう
---
# 終
---
- reactアプリで作ってみたものの、割と使いやすげ。サクッとこんなん作りました～と見せられるのもポイント高い
- firebaseとかも似たようなことができたような。あんま調べてないけど次そっちやりますか
---
# 参考文献と追記
- ReactアプリをGitHub Pages(Project Pages)で公開する
  - https://qiita.com/EisKern/items/15dcf7864fa49df8f247
- 超編集後記なんですが、この記事初心者向けでとても分かりやすい…(この記事いらなくね…)
  - https://prog-8.com/docs/github-pages
ubuntuのディスクトップで設定画面が出せなくなった

# ubuntuのディスクトップで設定画面が出せなくなった

## 電源マークをクリックしたときのプルダウンメニューに出ていた「設定」の項目がなくなっていた。

## 直近にしたこと
apt-get で未使用のプリンタドライバを削除した。プリンタは使わないので、ついでにインストール済みになっているプリンタードライバーを全て削除した。

## 原因
プリンタドライバの削除行為により`「システム設定(unity-control-center)」`が破損

## 対応

```
sudo apt-get --reinstall install unity-control-center
```

で、再インストール

## 所見
プリンタドライバは「システム設定」の画面から選択削除ができるのでそちらで行いましょう。
Falco Ruleを紹介するシリーズ - Polkit Local Privilege Escalation Vulnerability (CVE-2021-4034)

本シリーズでは、ランタイム脅威検知のデファクトスタンダードである<a href=https://falco.org/ target=new>Falco</a>の検知Ruleを、１つの記事で１つ簡単に紹介していきます。
ランタイムセキュリティやFalco自体の概要を知りたい方は<a href=https://sysdig.jp/blog/intro-runtime-security-falco/ target=new>こちらのブログ記事</a>をご参照ください。
今回ご紹介する検知Ruleは<b>「Polkit Local Privilege Escalation Vulnerability (CVE-2021-4034)」</b>です。
# Rule記述
```
- rule: Polkit Local Privilege Escalation Vulnerability (CVE-2021-4034)
  desc: "This rule detects an attempt to exploit a privilege escalation vulnerability in Polkit's pkexec. By running specially crafted code, a local user can leverage this flaw to gain root privileges on a compromised system"
  condition:
    spawned_process and user.uid != 0 and proc.name=pkexec and proc.args = ''
  output:
    "Detect Polkit pkexec Local Privilege Escalation Exploit (CVE-2021-4034) (user=%user.loginname uid=%user.loginuid command=%proc.cmdline args=%proc.args)"
  priority: CRITICAL
  tags: [process, mitre_privilege_escalation]
```
# Rule概要
プロセス権限を管理するPolkitの一部である、SUIDセットプログラム”pkexec”のローカル特権昇格のバグ（CVE-2021-4034）を利用した攻撃の試みを検知します。
CVE-2021-4034 の詳細については<a href=https://sysdig.jp/blog/detecting-mitigating-cve-2021-4034-sysdig/ target=new>こちらのブログ記事</a>をご参照ください。
攻撃者は、引数を渡さずに環境変数を操作することで”pkexec”を騙し、スーパーユーザー権限で任意のコードを読み込んで実行することができますが、このRuleを使うことで検知可能です。

# Condition（条件）
`spawned_process`
新規プロセスが生成され、

`user.uid != 0`
ユーザーUIDが0（root）ではなく、

`and proc.name=pkexec`
プロセス名がpkexecで、

`proc.args = ''`
プロセスの引数が空の場合

# Output（出力）
Polkit pkexecのローカル特権昇格の攻撃を検知しました(CVE-2021-4034) 

`%user.loginname`
ユーザーログイン名

`%user.loginuid`
ユーザーのログインUID

`%proc.cmdline`
コマンドライン

`%proc.args`
プロセス引数
【Rails】.env に定義した環境変数が反映されないときの解決方法

## はじめに
今回は、`dotenv-rails`を使って環境変数を管理していて、
`.env `に環境変数を定義して、コンソールで試したけど反映されないときに試すことを書きました。

`dotenv-rails`の設定などは以下の記事が参考になるかと思います！

https://pikawaka.com/rails/dotenv-rails

## 結論
・`spring`を再起動する
・`docker-compose`を使用している場合は、`docker-compose.yml` ファイルにも定義しているか確認する

## `spring`を再起動する
[Railsで環境変数の変更が反映されないときはspring stopを試す](https://qiita.com/metafalse/items/7294afa3d1be3315e999)
↑の記事を参考にさせていただき、試してみてください。


## `docker-compose.yml` ファイルにも定義しているか確認する
`docker-compose`を使用している場合は、
`docker-compose.yml` ファイルにも定義しているか確認してみてください！
下記のようなイメージです！

~~~.env
ENVFILE=12345678
ENVFILE2=abcdefg
~~~

~~~docker:docker-compose.yml
 app:
    build:
      dockerfile: Dockerfile
...
    environment:
      - TZ=Asia/Tokyo
      - RAILS_ENV=development
      - ENVFILE=${ENVFILE}
      - ENVFILE2=${ENVFILE2}
...
~~~
Herokuの無料枠が廃止に伴い、移行先render.comの性能比較とベンチマークをしてみた

# Herokuの無料枠が廃止に伴い、移行先render.comの性能比較とベンチマークをしてみた

## Herokuのフリープラン廃止
個人開発者界隈では、嘆きの声が聞こえていますが  
私も嘆きました  
血眼で移行先を探した結果[render](https://render.com/)というサービスを見つけたので共有します

## デプロイ方法
基本的にはGithubからクローンしてビルドされるっぽいです  
privateリポジトリでも可能だったので、ここらへんは、Herokuと遜色ないと思いました  
デプロイ方法の詳細はそのうち誰かが上げてくれる（調べれば出てくるし）と思うので割愛します

## 基本的な性能比較（Freeプラン）
|   | Heroku  |  render.com  |
| ---- | ---- | ---- |
|  メモリ  |  512MB  | 512MB  |
|  利用可能時間（月）  |  550時間(クレジットカード登録で1000時間)  |750時間  |
|  アクセスがない場合のスリープまでの時間  |  30分  | 15分  |
|  CPU  |  **Shared**  | **Shared** |

## CPUの性能比較
CPUがSharedでよく分からない上に、render.comの方が遅そうだったので、時間計測してみます

計測には[PyFuncApi](https://qiita.com/HawkClaws/items/14032426758cd04f739d)と下記コード(円周率の計算　1000万回計算する)を使用します

``` python
import random

incount = 0

def GenerateRandom():
  x, y = random.random(), random.random()
  number = x ** 2 + y ** 2
  return number

iteration = 10000000

for ite in range(iteration):
  check = GenerateRandom()
  if (check < 1):
    incount += 1

quadrant = 4

exec_result = str(incount * quadrant / iteration)
```

[Pythonで円周率を求めてみる](https://zenn.dev/kota_yata/articles/a0c9f55bf118dd7711cf)を参考にさせていただきました

### 計測範囲
Postmanから叩いてレスポンス時間を計測します（POSTMANに表示されるレスポンスタイム）  

それぞれ3回ずつ実行した結果です（sharedなので、実行する時間帯によっても違うのかもー）

### 1000万回計算する
- Heroku
    - 6.64s
    - 6.60s
    - 6.73s
- render
    - 計測不可（30.49s）

**あららー**
何度実行しても502エラーが出てしまったので計算回数を落とします


### 100万回計算する
- Heroku
    - 1.18s
    - 0.81s
    - 0.95s
- render
    - 6.53s
    - 7.16s
    - 6.89s


## fly.ioも計測

1000万回計算する で
7.65s
7.38s
7.63s
でした
herokuとほぼ同じくらいの性能
ただしメモリが256MB...


## 総括
renderのCPU性能は**Herokuと比べ6～7倍低い**ことがわかりました  
とはいえ、クレカ登録せずに750時間使える上、CPU性能を重視しないサービスであれば使えるのではないでしょうか！！こちらからは以上です！

### どうでもいいこと
renderというサービス名が色々なものと被りまくって調べづらい、MVCのrenderであったりね、、、  
タグもどうすればいいかわからん。。。
ubuntuにdockerをダウンロード

# はじめに
UbuntuにDockerをダウンロードするときに調べた記事をまとめます。

# 実施したこと
以下の記事を参考にダウンロードを進めました。
https://www.digitalocean.com/community/tutorials/how-to-install-and-use-docker-on-ubuntu-20-04-ja

以下のコマンドを実施したら、エラーが発生してできませんでした。
```
sudo systemctl status docker 
```

以下の記事を参考にエラーを解消し、Dockerをダウンロードしました。

https://github.com/arkane-systems/genie

https://qiita.com/kawaichi0228/items/a1238128fdf974b42579

https://eng-entrance.com/linux-root#root-3

https://zenn.dev/fehde/articles/103560f2a7065f
Salesforce認定アドミニストレーター試験の公式練習問題を解説してみた-その009

こんにちは。本橋孝昭です。

Salesforce認定アドミニストレーター試験の公式練習問題があるのはご存じでしょうか。
Trailheadにフラッシュカードとして何度も解ける練習問題がございます。

今回はTrailhead
アドミニストレーター認定の準備: 構成、設定とオブジェクト
構成と設定の学習　にある練習問題9問目をご紹介します。
https://trailhead.salesforce.com/ja/content/learn/modules/administrator-certification-prep-setup-and-objects/study-up-on-org-setup

なお、こちらの内容はYouTubeでも公開しております

https://www.youtube.com/watch?v=rHBHjpEjIH8

<iframe width="560" height="315" src="https://www.youtube.com/embed/rHBHjpEjIH8" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>




問題はこちらです

![009.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/6e46fc1f-9bf4-b818-575b-3e3c3282ae87.png)

正解はAです


設定はこちらネットワークアクセスから可能です
![ネットワークアクセス.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/56f07194-780e-101e-98e5-b7b1f8440fe8.png)


こちらでネットワークアクセスの範囲外の場合、このような本人確認をしないとログインすることができないです
![メール.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/c05efab4-a084-d3c8-a6f2-f9d1eeabd2bd.png)






なお、組織のネットワークアクセスで設定されるIP範囲では、
完全にアクセスを制限することはできませんので気をつけてください。

もしも特定のIP範囲でアクセスを完全に制限したい場合、
IPアドレスの制限などがあります

ネットワークアクセスの詳細についてはこちらをご確認ください
https://help.salesforce.com/s/articleView?id=000333031&type=1


今日の内容はここまでです。
皆さん楽しく元気にSalesforceを学びましょう！
論文 Item2Vec: Neural Item Embedding for Collaborative Filtering

word2vecをレコメンドに応用した以下の論文について、少しメモ書きを残しておきます。

https://arxiv.org/abs/1603.04259

# 内容
## 前提
書くの面倒なのでこれからは以下の略語を使います。

- w2v: word2vec
- i2v: item2vec
- CF: Colaborative Filtering(協調フィルタリング)

## Abstract
- NLP分野のw2v(別名SGNS: **S**kip-**G**ram with **N**egative **S**ampling)をレコメンドでも使い、item2vecと名付けている
- i2vはユーザ情報なくても使える(後述されるがユーザIDなしでOrderをユーザ代替)
- i2vはSVDに対してCometitive

## 1. INTRODUCTION AND RELATED WORK

- 多くの推薦アルゴリズム(多分、CF)はアイテムの類似度計算が目的。i2vで旧来の方法の見落としていた点に対応
- CFは今まで成果をあげていた
- user-item のアプローチは認証ない場合など使えないこともある

## 2. SKIP-GRAM WITH NEGATIVE SAMPLING
w2vの解説。w2v知っている人はスキップ可能。ここでは解説省略。
私は[「言語処理100本ノック」](https://qiita.com/FukuharaYohei/items/6f0af3c4e270d8af2d99#%E7%AC%AC9%E7%AB%A0%E3%83%99%E3%82%AF%E3%83%88%E3%83%AB%E7%A9%BA%E9%96%93%E6%B3%95-i)である程度学びました。(この章に書かれている数式レベルでは理解できていなかった)。

## 3. ITEM2VEC – SGNS FOR ITEM SIMILARITY

- itemとuserのひもづきできない場合があり(後述)
- w2v でのsequence of words をset/ basket of items に代替

setは論文内ではspatialおよび時間の長さを無視。basket単位にすると、１回の注文でのアイテム数が多い場合に使えるデータが少なくなりすぎるし、ユーザ単位にすると、どのくらいの期間以内であれば連続したものとして見なすかが検討点。

## 4. EXPERIMENTAL SETUP AND RESULTS
比較のためのベースラインにitem-item SVDを使用。

### 4.1. Datasets
以下の2種類データを使用。

1. XBox 音楽
    - 9M events, 732k users, 49k artists(曲ではなくartists)
1. MS Stroe orders
    - 379 orders, 1706 items, no user data(オーダー単位にしている) 

### 4.2. Systems and parameters

- SVG で最適化
- 20 epochs で学習
- Negative sampling value の Nは15
- データサイズに応じて以下のハイパーパラメータにした

||音楽|order|
|:-:|:-:|:-:|
|dimension m|100|40|
|subsampling ρ|$10^{-5}$|$10^{-3}$|


### 4.3. Experiments and results
ベクトル化した結果をT-SNEで2D可視化。音楽はジャンル情報を付加して色付け。左(a)がi2vで右(b)がSVD。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134273/17d66f53-a4ff-6579-cc44-2765447b09cc.png)

KNNでベクトルを音楽ジャンルの分類をさせて精度比較。Top q アーティストでSVDと精度比較。qの値が大きいほどi2vの精度が相対的に良い。これはi2vでは人気のあるアイテムをサブサンプルしているため(正確にd理解できていないが、多いアイテムをDownsamplingしているっぽい)。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134273/06a95a7c-f06d-dd80-1d27-c9e8e39ac97a.png)

## 5. CONCLUSION
i2vはSVDより良い。

## 6. REFERENCES
特記事項なし

# 参考リンク
## この論文の解説
https://ohke.hateblo.jp/entry/2017/12/02/230000

## Yahooの論文
https://arxiv.org/abs/1606.07154

## Airbnbの論文
https://dl.acm.org/doi/10.1145/3219819.3219885
【Rails】params[:id]の:idって何？

## 今更ながらparams[:id]の:idって何？
show,edit,updateアクションが呼ばれるといきなり下記のような表現が出てきます。
```
  def show
    @user = User.find(params[:id])
  end
```

この:idが何なのか、Railsチュートリアルでは以下のようにありました。
※Railsチュートリアル7章より引用
> このid: '1'は /users/:id から取得した値です。この値を使って
> User.find(params[:id])
> 上のコードでid=1のユーザーを検索できる、といった仕組みになっているのです

そして/user/:idの:idの部分は自動的にDBに生成されるカラムで、
以下のようにgenerateコマンドを実行した際に自動で作られる一意の値(主キー)です。
詳細はRailsチュートリアル2章を参照してください。
```
$ rails generate scaffold User name:string email:string
```

以上、復習までに
【Ruby on rails】Dockerを用いてRuby on railsの環境構築をする

![スクリーンショット 2022-08-30 16.34.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2737303/221a9676-b273-3166-a843-6001d50e58b5.png)
Dockerを使ったRuby on railsの環境構築をしました。なかなか苦労したので、備忘録的にまとめます。
# ①超基礎
そもそもDockerが何か全く知らなかったので、とりあえずYoutubeで動画を見ました。本当のさわりだけ、という感じですが掴みにはいいと思います。
* [【Docker超入門 #1】Dockerって何？何が良いの？](https://www.youtube.com/watch?v=DNnW4I43wyU)
* [【入門者も理解】Dockerとはなにか？【専門用語少なめ】](https://www.youtube.com/watch?v=dsWCjj8M4es)

ちなみに１本目の動画を出している山浦さんは、Dockerに限らず分かりやすい動画を色々とアップされているのでオススメです。

# ②基礎
この記事を読みました。前編、中編、後編とシリーズ化されていますがとりあえずは前編だけでいいと思います。

* [【図解】Dockerの全体像を理解する -前編-](https://qiita.com/etaroid/items/b1024c7d200a75b992fc)

↓Dockerを使うとどんなメリットがあるか？についてはこのように解釈しました。
> チームで開発をするとき、ソースコードを共有しても各々のマシンはOSなどに違いがあるためうまく動作しないことがある。このような場合は実行環境を共有する必要がある。
Dockerを使うとImageを元にコンテナと呼ばれる仮想的な実行環境を起動することができる。Imageを共有することで、マシンに差異があっても同じコンテナ(実行環境)を起動することが可能になる。

# ③Docker Desktopのインストール
Docker Desktopは、自身のPCでDockerを使うために必要なものです。
下記の記事を参考にしました。Windows版とMac版があります。
* [Docker Desktop インストール手順](https://qiita.com/R_R/items/a09fab09ce9fa9e905c5)
![スクリーンショット 2022-08-30 16.35.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2737303/4ceed7fd-3a00-880c-78f0-fe258087da75.png)
ここまでは特に問題なく進みました。

# ④Ruby on railsの環境構築
いよいよここから本格的な環境構築です。…が、ここでかなり苦労しました。
下記の記事を参考にして進めました。
* [Dockerを用いてRuby on Railsの環境構築をする方法( Docker初学者向け )](https://qiita.com/Yusuke_Hoirta/items/3a50d066af3bafbb8641)

### 発生したエラーその１：docker-compose -vがcommand not foundになる
うまくインストールできていないのかな？と思い、いろいろ試してみたがダメでした。
結局、再起動&アンインストールで解消。

### 発生したエラーその２：docker-compose upのエラー
「Gemfileにnokogiriが無い」旨のエラーが出た為、nokogiriを入れたところ解消。

かなり時間はかかってしまいましたが、環境構築が完了して開発を始めることができました。
全く知らなかったのですが、MacM1チップが影響して環境構築が上手くいかない場合もあるらしいです。。


# 学んだこと
* エラーメッセージに答えがある
* どうしてもうまくいかないときは再起動もしくは再インストール

今回に限った話では無いのですが、ここを意識することでエラーの解消スピードがアップすると感じました。

# コマンドの理解
```php:ターミナル
    docker-compose build
```
Dockerfile(Imageの設計書のようなもの)を実行してImageを立ち上げます。仮想環境を作成するイメージです。
```php:ターミナル
    docker-compose up
```
docker-compose.ymlを実行してコンテナを起動します。開発環境を整えるイメージです。
このコマンドが通れば、localhost:3000でページにアクセス可能になると思います。
コンテナ起動しているかは、Docker Desktop「Containers」の「STATUS」で確認できます。

# おわりに
今回はDockerを用いたRuby on railsの環境構築についてまとめました。先輩方や先人達の知恵に頼り、環境を整えることができました。いつか自力で環境構築できるようになるといいなあ…
この記事が参考になると嬉しいです(￣▽￣)
【Rubyなど】学習したことまとめ

最近Rubyを使った開発を始めたので、周辺も含め学んだことを色々とまとめていきます。

# ルーティングと.erbファイルの関係性
URLのリクエストをroutes.rbでコントローラのアクションに割り当てて、コントローラで定義されているアクション名を元にしてどのviewを起動し、erbファイルを実行してHTMLを生成するかを決めています。

例えば、
```php:routes.rb
    root 'users#index'
```
の場合は
```php:app/controllers/users_controller.rb
    def index
        @users = User.all
    end
```
にルーティングされ、
app/views/users/index.html.erbが実行されてHTMLとして表示されるようになリます。
つまり省略されているが、アクション名＝view名(erbファイル名)となっています。

# unless文
ruby特有というわけでは無いですが、今まで使ったことがありませんでした。
if文は「条件式が真の場合に実行する処理」を書きますが、unless文はその逆です。
```
unless 条件式
  条件式が偽の場合に実行する処理
else
  条件式が真の場合に実行する処理
end
```

# CSS：指定した箇所を非表示にする
CSSで display: none; を使うことで、その部分を非表示にできます。

例えばこのような表示のとき、
![スクリーンショット 2022-08-30 16.01.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2737303/02d2d51e-287a-0132-d0e6-71f13a1190e8.png)
こう指定すると
```php:HOME.html
  <p class="code1">表示する</p>
  <p class="code2">表示しない</p>
```
```php:style.css
  .code2{
  display: none;
  }
```
こうなります。
![スクリーンショット 2022-08-30 16.05.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2737303/38ca99e6-c6c3-3fd9-a8d1-752c8ebaedfb.png)

# .erbのクラス内でif文を書く
```php:view.html.erb
  <div class="form1 <%= "form2" if @user.name='たかし' =%>">
```
userの名前が「たかし」なら、form2が適用されます。
下記の記事を参考にしました。
* [Railsの.erbで条件によってclassを変更](https://qiita.com/zukakosan/items/b613145512880095a2de)

# コードが意図した通りに動かない時にやってみること
ログを仕込んで、処理が通過している部分やデータの中身を確認することが大切だと学びました。また、そもそもコード自体が間違っている可能性を考えることも必要です。

# 競合の解決
プルリクを出した際の競合を解消しました。
#### ブランチA→ブランチBにマージしようとして競合した場合
>ローカルブランチでの作業になります。
まず、ブランチAに移動します。
続いてブランチBをpullします。
競合している箇所が表示されるので、解消させます。
その後は、いつも通りコミットしてpushします。

今回発生した競合は簡単なものでしたが、基本は掴めたのではないかと思います。


# おわりに
Rubyの開発で学んだことを色々と記しました。開発と一口に言っても様々な要素が折り重なっていて、日々知識不足・勉強不足を痛感しています。
今後も学んだことがあれば、随時追記していきたいです。
この記事が参考になると嬉しいです(￣▽￣)
アソシエーションした項目をselectプルダウンで並び替え

まずはモデルで関連付けを行います。
`dependent: :destroy`はbuildingが削除されたらroomも削除するといったメソッドです。
scopeメソッドを使うとコントローラで呼び出すだけで並び替えができるようになります。

```model/building.rb
class Building < ApplicationRecord
  has_many :rooms, dependent: :destroy

  scope :latest, -> {order(created_at: :desc)}
  scope :old, -> {order(created_at: :asc)}
  scope :short, -> {order(station_minute: :asc)}
  scope :long, -> {order(station_minute: :desc)}
```

```model/room.rb
class Room < ApplicationRecord
  belongs_to :building
```
viewでパラメーターを`params[:keyword]`として送信します。
参考:https://qiita.com/kurawo___D/items/7604f709a9ec28808540

```buildings/index.html.haml
%dl
  %dt 並び替え
  %dd
    = form_with model: @building, url: @building, method: :get, local: true do |form|
      = form.select :keyword, [ ['新しい順', 'latest'],
                                ['古い順', 'old'],
                                ['賃料が高い順', 'high'],
                                ['賃料が低い順', 'low'],
                                ['駅が近い順', 'short'],
                                ['駅が遠い順', 'long'],
                              ]
      = form.submit 'save'

```
コントローラーではこのように記述してあげるとviewのプルダウンで選択された値とマッチした並び替えが行われます。
`includesメソッド`を使ってbuildingとroomsのテーブルをつなげてあげることによりbuilding_controllerでroomsの並び替えを行うことができます。
[includesメソッドについて](https://pikawaka.com/rails/includes)

buildingはscopeを使用しているのでコントローラーではorderを宣言しなくても並び替えが行われます。
roomsはscopeを使用していないのでorderメソッドを使用しています。
```controllers/buildings_controller.rb
def index
    if 'latest' == params[:keyword]
      Building.all.includes(:rooms).latest
    elsif 'old' == params[:keyword]
      Building.all.includes(:rooms).old
    elsif 'short' == params[:keyword]
      Building.all.includes(:rooms).short
    elsif 'long' == params[:keyword]
      Building.all.includes(:rooms).long
    elsif 'high' == params[:keyword]
      Building.all.includes(:rooms).order("rooms.rent desc")
    elsif 'low' == params[:keyword]
      Building.all.includes(:rooms).order("rooms.rent")
    else
      Building.all.includes(:rooms).latest
    end
    @buildings = @q.result(distinct: true).page(params[:page]).per(10)
  end
```
以上のやり方でアソシエーションをしたカラムの並び替えができると思います。
参考になれば幸いです。
Monte-Carlo積分と期待値に関する備忘録

## はじめに

初歩的な内容であるため，備忘録として簡単にMonte-Carlo積分と期待値に関してまとめる．

## 定義
まず，本記事において以下の定義を使用する．
1. 関数 $f$ の定義域: $\mathcal{X} \subseteq \mathbb{R}^D$
2. Riemann積分可能関数: $f: \mathcal{X} \rightarrow \mathbb{R}$
3. 適当な確率密度関数: $p: \mathcal{X} \rightarrow \mathbb{R}_{\geq 0}$

## 期待値
まず，$f(x)$ の期待値計算は以下のように行われる．
$$
\int_{x \in \mathcal{X}} f(x) p(x) dx \approx \frac{1}{N} \sum_{i=1}^N f(x_i)
$$
ただし，$\\{x_i\\}_{i=1}^N \sim p(x)$ であるものとする．

## Monte-Carlo 積分

上記の方法を利用する．
```math
\begin{align}
\int_{x \in \mathcal{X}} f(x)dx &= \int_{x \in \mathcal{X}} \frac{f(x)}{p(x)} p(x) dx \\
&= \frac{1}{N} \sum_{i=1}^N \frac{f(x_i)}{p(x_i)} 
\end{align}
```
このように $f(x)/p(x)$ というように変形し，$p(x)$ からのサンプリングで期待値を取る方法を重点サンプリングと呼ぶ．

## 検証

```python
import numpy as np

lb, ub = -1, 3
x = np.random.random(10 ** 6) * (ub - lb) + lb
y = x ** 2
res = np.mean(y) / (1.0 / (ub - lb))
ans = 28 / 3
print(f"answer: {ans}, result: {res}, diff: {np.abs(ans - res)}")

>> answer: 9.333333333333334, result: 9.344802755374523, diff: 0.011469422041189503
```
VanillaJSでイージング付きのSmoothScrollを実装する

# TL;DR
scroll-behavior便利ですね。

https://developer.mozilla.org/ja/docs/Web/CSS/scroll-behavior

・・・とかいいつつ、うまくスムーススクロールが動かなかった（おそらく自分の実装が悪い気もする）ので、
バニラでスムーススクロールを実装しました。

よくあるサンプル、動きが直線的で気持ち悪いですよね。
なんでイージングつけました。

# ソースコード
https://github.com/rockinruuula1227/js-smooth-scroll/blob/main/smoothScroll.js

適当にコピペしてimportしたら使えるかと思います。

# ソース説明

メインのソースはよくあるSmoothScrollと一緒です。

```js

// clickイベント取得して、aタグのハッシュを取得する用。
export const smoothScroll = (event) => {
  event.preventDefault()
  smoothScrollWithHash(event?.target?.hash ?? "html")
}

// 直で”#id”と指定する用
export const smoothScrollWithHash = (hash) => {
  const el = document.querySelectorAll(hash)[0]

  // 目的地と開始地の座標取得
  const targetPosition = el.offsetTop
  const startPosition = document.scrollingElement.scrollTop
  let currentPosition = startPosition

  // 上スクロールか下スクロールか
  const goDown = currentPosition < targetPosition

  const interval = setInterval(function() {
    // Sin関数でイージングをつけた移動量を計算する
    const mp = movingPosition(startPosition, targetPosition, currentPosition)
    // mpの返り値が0だと無限ループになるので、最低限移動する値を加減算する
    currentPosition += goDown ? mp + 5 : - mp - 5

    if (goDown && currentPosition > targetPosition
      || !goDown && currentPosition < targetPosition) {
      clearInterval(interval);
      document.scrollingElement.scrollTop = targetPosition
    }
    document.scrollingElement.scrollTop = currentPosition
  }, 10);
}
```

今回イージングを実現するために、Sin関数で移動量を計算しています。

`Math.sin(Math.PI)`の時は移動速度が上がって下がる。
`Math.sin(Math.PI/2)`の時は移動速度がギュインと上がります。

```js
const movingPosition = (start, target, current) => {
  const sin = Math.sin((current - target) / (start - target) * Math.PI)
  return sin * 50
}
```

`(current - target) / (start - target)`は開始時は1で、
currentがtargetに近づくにつれ0に近づきます。

ですので、画像x軸のπの位置から0の位置まで移動量を変化させながらスクロールされるイメージです。

![22364374.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/288273/44dc9916-b1a4-78c8-91d4-1f64c232745d.png)

# まとめ
はとくにないよ。
【個人開発】作るのも、答えるのも簡単なWebアンケート「ankeyto」を作りました！

# 2つ目の個人開発サービス公開
アプリケーションのモダン化を勉強しようと個人開発を始めて、以下の記事のように公開していました。もう振り返ると1年経つんですね…　こういった個人開発活動を続けることにより、少しずつ知識も身についてきて、開発スピードも上がってきていました。

- Github Issuesをキレイに外部公開するサービス「2go」作ってみた
    - https://qiita.com/nice2have/items/28449ae4ef45fef2c671

- 海外進出を目指して、ProductHuntへ個人開発サービスを投稿するまでにやったこと&やった結果を全面的にシェアする
    - https://qiita.com/nice2have/items/f59a27c266efb9b8821c

実際には公開していないのですが、atodyという<b>「Twitterでいいねしたツイートに含まれるリンク・画像だけを自動でまとめてブックマーク化できるサービス」</b>を開発したのですが、いまいちサービスの完成度に納得がいっていなく、開発したサービスとしては3つとなったのですが、公開したサービスは２つとなります。

![ogp.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1997184/3f2dbeed-c2cb-8437-164e-78a8797ea9df.png)

# 簡単Webアンケート
今回は会社の一定の範囲で簡単にアンケートを取りたいときに、Google FormｓやMicrosoft Formsを作るのは手間だな、もっとライトな感じで反応を知りたいなと思ったのがきっかけです。

また、アンケートの回答を得るまでのハードルが結構高いと思ったんです。アンケートURLにアクセスして、回答を入力して、、、となると、答えてくれる人が少なくなってしまって、アンケートの価値が薄まってしまうような気がしたんですよね。

# 機能を最小限に絞ったアンケートをリリースしよう
これらの課題を解決しようと、ankeytoというアンケート機能を最小限に絞ったサービスを開発しようということに至りました。ankeytoはアンケートのモジりで<b>「アンキート」</b>と名付けることにしました。ちなみに、先程のatodyも「あとで」のモジりで<b>「アトディ」</b>と名付けています。

https://ankeyto.com

開発する前の大まかなコンセプトは、A3ノートにまとめる用にしているのですが、汚い字で申し訳ないですが、公開してみます。
![IMG_1337.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1997184/8871aa10-08b9-76f6-447b-42611f8a02a4.jpeg)
サービスのコンセプトは以下の２つと設定しました。
+ 最大３つまでの選択肢
+ 選択肢ごとのURLにアクセスすればもう回答済みになる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1997184/ec5dcfde-7952-6f6b-2aa7-679b603afbd2.png)
そのため、選択肢を表示して回答ができるページをSNSでシェアするのではなく、アクセスしたら回答できるURLをSNSでシェアするだけで良くなるのです。例えば、<b>「これが良いと思ったら、このURLにアクセスして！」</b>と言えば良くなり、アンケート回答のステップとハードルを減らすことができるのです。つまり、個人個人で対象への「いいね」を調査・獲得できるイメージです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1997184/29d7fd65-e416-566f-3b3c-9345e146f755.png)

# 画面イメージ
こちらのようにアンケート回答がリアルタイムにグラフやUIに反映されるので、回答が多いと変化を楽しめるかもしれません。例えば、プレゼン最中の意見を軽く聞きたいときや、勉強会のフィードバックを簡単に得たいときなどに利用できるかもしれません。
![demo.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1997184/12cb36a5-f89b-8aad-dded-dffcc5f7c223.gif)

アンケートを作るときの画面も極力シンプルにしています。こちらもログインが必要だと手間が増えてしまったり、入力項目数が多いと途中で離脱してしまう可能性が高くなってしまうので、最小限にすることを意識しています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1997184/737aa90d-06ef-4ebc-a439-1dcfc31e9e66.png)

# 利用技術
個人開発者としてはまだまだペーペーなので、利用技術も運用負荷が最小限になることを意識しています。 
- Firebase(Firestore/Functions/Hosting)
- Vue.js
- Tailwindcss
- Slack

サービス自体がとてもシンプルなので、HostingでWebページを表示し、質問作成や回答をFunctionsで処理し、結果をFirestoreでリアルタイムに反映しているだけです。一応、モチベーション維持のために、質問が作成されたり、回答されたりしたら、FuncitonsからSlackに通知されるようにしています。

# 将来に向けて
最後に、将来は以下のロードマップを考えています。
- URLにアクセスするよりもさらにハードルを下げるために、URLをQRコード化できるように。
- Cookie等を利用した重複回答者の防止機能
- 質問IDをランダムでなく、わかりやすいIDを提供できる機能
- API機能（UIだけでなく、いいねAPIを提供）
- 英語対応

# 最後に。
まさにこのankeytoを利用して、このWebサービスってどうですか？とアンケートを取って終われればと思います。以下が質問ページから、SNS共有用にコピーできる文章になります。「いい！」か「まあまあ」のURLにアクセスすれば回答が完了しますので、ぜひよろしくお願いします！
> Q. このWebサービスってどうですか？
> https://ankeyto.com/q/BbDJA3P11
>
> いい！ : https://ankeyto.com/BbDJA3P11/1 
> まあまあ : https://ankeyto.com/BbDJA3P11/2 

また、個人開発の進捗などを垂れ流すTwitterもやっていますので、こちらもよろしければフォローお願いします。
https://twitter.com/jnakajima1982
都道府県名称をマスタのコード番号で割り当てる(SPSS Modeler データ加工逆引き6-6)

# 都道府県名称をマスタのコード番号で割り当てる

![スクリーンショット 2022-08-10 9.56.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/58b9adb1-1e4d-d20a-b888-333efd3a4685.png)

## 1.想定される利用目的

・顧客分析のための前処理
・店舗分析のための前処理
・移動体/設備情報の精査

## 2.サンプルストリームのダウンロード

https://github.com/yoichiro0903n/blue/blob/main/master_table.str?raw=true

## 3.サンプルストリームの説明
![スクリーンショット 2022-08-10 9.57.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/8bebdfd4-bdfe-42de-1a50-5019a15600d4.png)

a.入力するデータひとつ目は以下の通りです。コード番号に応じた都道府県名称を割り当てます。
![スクリーンショット 2022-08-10 9.58.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/97ecefb4-bc70-7599-695e-a81095166e4b.png)

b.入力するマスタは以下の通りです。47レコードの都道府県名称マスタです。
![スクリーンショット 2022-08-10 9.58.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/9353062f-6035-5ef2-e20f-360ce3889ff7.png)

c.[レコード結合]ノードを編集します。[レコード結合方法]は[キー]を選択し[都道府県コード]を[キー]して[内部結合]します。
![スクリーンショット 2022-08-10 9.59.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/583e9284-1d7c-d6b6-be06-aa4d97a1a068.png)

[テーブル]を実行します。
![スクリーンショット 2022-08-10 9.59.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/b26c64fa-eab2-3292-d11e-b919ef334c00.png)

d.[データ分類]ノードでも同じ結果を求められます。
![スクリーンショット 2022-08-10 10.00.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/ce8b6946-ebc9-7c14-3eb3-4189974c6984.png)

#### 注意事項

コード番号2桁は文字型として扱っています。整数にすると1桁になるものが生じるので注意します。結合時には型を揃えることも留意してください。またdを行う場合にもあらかじめ入力の[データ型]タブで[値の読み込み]ボタンを押して型を確定する必要があります。

## 4.参考情報

#### レコード結合の解説記事

https://qiita.com/416nishimaki/items/be61a82c12cd83558def

#### SPSS Modeler ノードリファレンス目次

https://qiita.com/416nishimaki/private/503037195081d3323eee

#### SPSS Modeler 逆引きストリーム集（データ加工）

https://qiita.com/416nishimaki/private/4bf813e6cba84b2a1008
dockerでActiveStorageを用いてS3に画像をアップロードする方法

こんにちは。今回はs3に画像をアップロードし、画像を表示させるのにかなり苦労しましたので次回からは沼らないように自分が成功した方法を備忘録として残しておきます。ここではdockerの構築方法は割愛します。

# やりたいこと
ActiveStorageを用いてS3に画像をアップロードし、画像を表示したい。

# 前提
dockerを用いてアプリを開くことができる。

# 参考にしたサイト

https://zenn.dev/kurao/articles/ce8e583450c76e

https://qiita.com/tsubasan1122/items/0171fe04754a760f7e4a

基本的にはこちらのサイトを参考にして作成した。

# つまづいたところ

## dockerfile

credentials.yml.encを編集するためにvimで編集する必要があるのですが、自分のdockerでは初期状態ではvimを開くことが出来なかったので

```dockerfile
RUN apt-get update
RUN apt-get install vim
```

としたところエラーが発生。対処としては

```
RUN ["apt-get", "update"]
RUN ["apt-get", "install", "-y", "vim"]
```

とすることで無事vimをインストール出来た。

## カラムを用意する必要はない

```app/models/user.rb
class User < ApplicationRecord
  has_one_attached :avatar
end
```
ActiveStorageでは、ファイルデータを保存するためにそれぞれのテーブルに個別にカラムを用意しなくても上記の記述を追加するだけでデータの保存ができる。

以上で無事画像を表示することが出来ました。carrierwaveでは画像を表示することが出来なかったので今後はActiveStorageを使っていこう。
Dockerについてのメモ

仕事ではDockerを利用していないため、個人的に利用するためのメモとして記録する。

https://www.docker.com/

# Docker
・アプリを実行するためのプラットフォーム
・作成した開発環境を共有できる
・バージョン等の差異による開発環境の問題を解決する

## Dockerコンテナ
・Linux上のプロセス（仮想マシンを起動するわけではない）
・Dockerイメージで作成されるアプリを含む実行環境
・Dockerはコンテナの中でアプリを実行する
・マシン上の他のプロセスに影響を受けない

## Dockerイメージ
・実行環境をテンプレート化したファイル
・ソース、ライブラリ、バイナリ、設定ファイル等をまとめたもの
・Dockerイメージを使ってDockerコンテナを実行する
・Docker Hubから他者のDockerイメージを取得できる

https://hub.docker.com/

## Dockerfile
・Dockerイメージを自動構築するための設定ファイル
・Dockerイメージの作成手順を定義する

## Dockerボリューム
・Dockerコンテナで利用するファイルやディレクトリを共有する場所
・Dockerコンテナから分離されているため、コンテナ削除で消えない
・コンテナ間やホスト側のディレクトリやファイルと共有できる
・名前付き、名前なし、ホストのマウント(bind mount)

## Docker Engine
・Dockerイメージをコンテナとして実行するプログラムやライブラリ群を指す

## Dockerネットワーク
・Linuxのbridge機能を通して外のネットワークを利用する
・コンテナ上のサービスを公開するにはホスト側のポートに割り当てが必要

## Docker Compose
・Dockerコンテナ、Dockerイメージ、Dockerボリューム、DockerネットワークをYAMLファイルで管理するツール
・docker-compose.yml

## Dockerを使うとは
・Linux上で動作するDocker Engine（デーモン）でアプリを扱うこと
・Docker EngineがLinuxカーネルを制御する

## Dockerの学習
・Play with Docker(PWD) …無料で使えるサンドボックス環境（制限あり）

https://www.docker.com/play-with-docker/

## Reference
https://docs.docker.com/get-started/overview/

https://docs.docker.jp/index.html