OmniAICreator/Qiita-1.07M huggingface dataset:
モデルにテーブル定義をコメントしてくれるgem、annotateが動作しない

Rails の開発お役立ち gem として有名な [annotate_models](https://github.com/ctran/annotate_models).
`rails db:migrate` した時に自動的にモデルの頭のところに対応するテーブル定義をコメントで追加してくれるアレです。この動作のことってアノテーティングと言うようですね。
とても便利なので重宝しているんですが、導入済みのプロジェクトでいつの間にか動かなくなっていました。最近テーブル定義の変更やっていなかったんで気付きませんでしたが、アレ？何かやったかな？

結論を言うとこれは annotate_models のデフォルトの挙動が変わったため。バージョンが2.7.xまでと3.1.x以上で異なっているので、古いバージョンから使っていた人はこの問題に直面します。
理由と対処法も公式にちゃんと書いてあります。

[Upgrading to 3.X and annotate models not working?](https://github.com/ctran/annotate_models#upgrading-to-3x-and-annotate-models-not-working)

>In versions 2.7.X the annotate gem defaulted to annotating models if no arguments were passed in. The annotate gem by default would not allow for routes and models to be annotated together.

まあ、要するにデフォルトでモデルへアノテーティングするのをやめているんですね。ちゃんと model にアノテーティングする、と言う引数を与えるなり設定を追加するなりをやる必要が出てきたんです。
なのでこの解決策は簡単。

すでにこの gem を使っていた方なら、`lib/tasks/auto_annotate_models.rake` が存在するでしょう。ここに model の設定を追加します。

```lib/tasks/auto_annotate_models.rake
    :
    Annotate.set_defaults(
      'routes'                  => 'false',
      'models'                  => 'true',  # <- 追加
      'position_in_routes'      => 'before',
      'position_in_class'       => 'before',
       :
```

このあと `rails db:migrate` を実行すれば、無事にモデルに対してアノテーティングが実行されるようになります。


なお、これも公式に記載がありますが、gem インストール時に実行する `rails g annotate:install` をもう一度実行することで `lib/tasks/auto_annotate_models.rake` を再生成することができます。3.x 以上のバージョン用にデフォルト設定を組み込んだもので再生成されるので、他に足りない設定項目がないか不安な方は、こちらを実行しても良いでしょう。
ただしこの場合、既存の設定項目のうちご自身で変更していたものを、再生成後に最適用する必要があります。
また、`classified_sort` のデフォルトが `false` から `true` に変更されているため、改めて `rails db:migrate` を実行すると追加されるカラムの並びが違ってしまって戸惑うかもしれません。こちらも `false` に設定しておくと良いです。
[CSS]親要素を基準に子要素を position: fixed させる方法

https://myscreate.com/position-fixed-based-on-parent/

![lightsail01_header-2-1000x468.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/593842/7291d350-87a9-5bdf-2158-50bf3027e72e.png)
PycharmでGitHubにログインできなかったときの対処法

# 結論
　アクセストークン作ってログインすればいけるで

## 何があったか
PycharmでGitHubにログインしてプッシュしようとしたけど、ログインできなかった
様々な方法を試してみたけれど、どれも弾かれてしまった（Cookieがどうのこうので）

## 解決方法

それならばトークンを使ってログインすればいいじゃないということで

トークン作ってログインを試みてみました

あら不思議

かんたんにログインできたじゃありませんか

これからは何でもかんでもトークン使っていこう

参考にトークンの作り方がわかりやすく説明しているサイトを載せておくので覗いてみてください！


## 参考
https://docs.github.com/ja/github/authenticating-to-github/creating-a-personal-access-token
S3 SELECTでCloudTrail証跡オブジェクトを検索してみる

S3 SELECTを使ってCloudTrailの証跡オブジェクト（JSONでS3に吐かれる）をクエリーする必要に迫られたが、意外にサンプルがなかったのでまとめておく。

### やりたいこと
- CloudTrailのファイルの中身をサクッと見たい。
- ダウンロードはしたくない。Athenaを準備するほどでもない。

### S3 SELECTの入出力設定
|カテゴリー|項目|値
|:---|:---|:---|
|入力設定|フォーマット|JSON|
||JSONコンテンツタイプ|行|
||圧縮|GZIP|
|出力設定|フォーマット|JSON|

### サンプルクエリー

```sql:300行取得

SELECT * FROM s3object s LIMIT 300
```

```sql:指定したイベント情報を取得
SELECT s.eventTime, s.sourceIPAddress, s.userIdentity.arn, s.awsRegion, s.eventName, s.eventSource, s.eventType,s.eventCategory, s.errorCode, s.errorMessage FROM s3object[*].Records[*] s LIMIT 10
```

```sql:列名に別名を指定
SELECT s.eventTime as EventTime, s.sourceIPAddress as SourceIP, s.userIdentity.arn as UserID, s.userIdentity.sessionContext.attributes.mfaAuthenticated as MFA, s.eventName as EventName, s.eventSource as EventSource, s.errorCode as ErrorCode, s.errorMessage as ErrorMessage FROM s3object[*].Records[*] s LIMIT 10
```

```sql:特定のイベントソースのみフィルタリング
SELECT * FROM s3object[*].Records[*] s WHERE s.eventSource = 'ec2.amazonaws.com' AND s.eventName != 'DescribeInstances'
```

```sql:イベントを一覧表示して全体を把握
SELECT s.eventTime as EventTime, s.eventName as EventName, s.eventSource as EventSource FROM s3object[*].Records[*] s
```

```sql:特定のイベントソースのエラーの一覧化
SELECT s.eventTime as EventTime, s.sourceIPAddress as SourceIP, s.userIdentity.arn as UserID, s.errorCode as ErrorCode, s.errorMessage as ErrorMessage, s.eventName as EventName, s.eventSource as EventSource FROM s3object[*].Records[*] s WHERE s.eventSource = 'kinesis.amazonaws.com'
```

```sql:特定イベントの件数集計
SELECT count(s.eventName) as DynamoDBEventCount FROM s3object[*].Records[*] s WHERE s.eventSource = 'dynamodb.amazonaws.com'
```

### メモ
- 改行入れるとエラーになっちゃう。
GithubのRemote repository作り方

#はじめに
RemoteでRepositoryを作る．つまりGithubにてRepositoryを新規作成．


#方法1
Localにgit cloneする．1番簡単

```shell-session
git clone https://github.com/username/repositoryname
```

その後プロジェクトを作成．

#方法2
Localでgitディレクトリを作る
remoteのdefault branchがmasterのとき． mainならmasterをmainにする．

```shell-session
mkdir hoge
cd hoge
git init
git remote add origin https://github.com/username/repositoryname
git pull origin master
```

その後hogeディレクトリにてプロジェクトを作成．

#その後

```shell-session
git add .
git commit -m 'initial commit'
git push origin master
```
のように続いて行く．
Laravel基本用語集

Laravelフレームワーク
基本的な機能を備えた Webアプリケーションが作れる

IDE
(統合開発環境)
プログラミングに必要なツールが全て揃ったアプリケーション

エディタ
文章を編集したりするツール

ターミナル
キーボードからコンピュータを操作するためのインターフェース」なのですが、マウスやウィンドウを使わずにコンピュータを操作するために用意された方法

CUI
(Character User Interface)
キーボード入力と文字表示だけでコンピュータを操作するターミナルのようなインターフェース

GUI
(Graphical User Interface)
ボタンやウィンドウと言ったグラフィカルな部品から成り立つインターフェース

Linuxコマンド
LinuxというOSをCUIで操作するためのもの

OS
オペレーティングシステム（Operating System）の略で
・キーボードをタイプすると、その文字が画面に表示される
・マウスをクリックするとファイルが開かれる
のようにパソコンを動かす上で基本的な動作を制御するためのシステムです。
「Windows」「Mac」「ios」 「Android」などが挙げられ、LinuxもこのOSの1種です。

pwd
（Print Working Directory）
現在のフォルダ(ディレクトリとも呼びます)を調べるためのコマンド

mkdir
make directory(ディレクトリを作成しなさい)

cd
Change Directory(ディレクトリを変更しなさい)

ls
list(指定したディレクトリの中に何があるかを表示)

rm
remove　ファイルやフォルダを削除するコマンド
ディレクトリを削除するときには、rm のあとに半角スペースを入れて -r
＄　rm -r ディレクトリ名

パス(Path：通り道)
ディレクトリの階層を表現しているとき

リポジトリ
リポジトリとは、ファイルやディレクトリの状態を記録する場所

トラッキング状態
コミットするファイルは事前にトラッキング状態にしておく必要があります（addコマンドを使用）。一時的にステージング領域と呼ばれるところに保存されます。

JavaScript
JavaScriptはWebサイトでの「動き」の部分を担当（ボタンが動いたり）
JavaScriptはプログラミング言語（HTMLとCSSはマークアップ言語）

配列
$array = [2017, 2018, 2019, 2020];
連想配列
$animals = [
  "cat" => "猫",
  "dog" => "犬",
  "bird" => "鳥"
];

関数
厳密な関数の定義の仕方
function 関数名(仮引数) {
  実行する処理
}

composer
Laravelのバージョン管理ツール
Laravelをパソコンに入れるためにはhomebrewでcomposerをインストールしてLaravelを入れなければいけない！

artisan
職人
Laravelに関する操作の多くはartisanを利用

Action
Controllerが持つ機能のこと
ontroller内に実装した関数(メソッド) のことを指します

Routing
アクセスしたアドレスに応じて対応するControllerのActionを呼び出す仕組みのこと
Rails 5.2 でPaypalのSmartPaymentボタンがリロードしないと表示されない問題

Rails 5.2 でPaypalのSmartPaymentボタンがリロードしないと表示されない問題に悩まされていた。
ページをリロードしたら表示されるので後回しにしていたけど、

<strong>Turbolinksを切ったら解決した。</strong>
Windows10にUbuntu 20.04をインストールするWSL2


Windows10にUbuntu 20.04をインストールしたときの流れを示す

公式の説明↓
https://docs.microsoft.com/ja-jp/windows/wsl/install-win10

Microsoft StoreでUbuntuと検索し，ダウンロード
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/763301/cadf5eff-e86f-c2f9-a255-7b72074723ce.png)

アプリを開くとインストールが始まる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/763301/92bb3878-b072-4dda-85e9-89224f8887d2.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/763301/17d33140-3061-b3af-0625-9ca479a1ec21.png)

名前とパスワードを設定する．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/763301/f5e94857-7dba-0783-143e-4456dd075c6a.png)

wslコマンドで確認してみる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/763301/dcf41eab-4ada-31f2-2549-99b1212d07ed.png)

Ubuntu 20.04は自分の環境では,はじめWSL1になっている．
なのでWSL2に変更する．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/763301/648c807e-692d-8286-78c4-43be8e412c8e.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/763301/c0eebe50-51e4-aa87-b0a4-684217c06a43.png)

OK
CloudFront でオリジンに Authorization ヘッダを送る設定をしようと思うとエラーが出て設定できない

# 経緯

CloudFront のバックにあるオリジンサーバーに対して `Authorization` ヘッダを送信する設定をしたい。 しかし、この設定を実施しようと Origin Request Policy の `Header: whitelist` とした後、Authorization を指定すると "The parameter Headers contains Authorization that is not allowed" というエラーになる。 

![SnapCrab_NoName_2021-2-11_2-45-40_No-00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502582/48bbe840-6536-40ed-27c0-df7aa673c855.png)

なお、これを CloudFormation でやると "Invalid Parameter" としか出てこないので原因の特定にものすごい時間がかかった。


# 対処方法

一応、公式でも説明されている。

https://aws.amazon.com/jp/premiumsupport/knowledge-center/cloudfront-authorization-header/

まとめると、

- **Origin Request Policy に Authorization ヘッダを含めることはできない**
- Authorization ヘッダをオリジンに渡したければ **Cache Policy の Header に whitelist として Authorization を含めることで解決可能**
  - 今回知った仕様だが、**[Cache Policyに含めている値は Origin Request Policy を指定しなくても自動的にオリジンへと送信される(!)](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/controlling-the-cache-key.html)** 仕様がある
  - 上記URLでは `The header must be a part of the cache key to prevent the cache from satisfying unauthorized requests.` と説明されているが、これは、適当な Cache Policy と `Authorization` を含む Origin Request Policy を組み合わせた場合 Authorization の値に関係なく Authorization ヘッダごとキャッシュしてしまう事故が起こりえるため、これを許可していないと考えられる
- あるいは Legacy Setting を使う

## 23/02/05 追記

CloudFront からオリジンに各種ヘッダを送付する場合、何も考えずに全てのヘッダを送付したいこともある。 その場合、標準で提供されている [AllViewer のポリシー](https://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/using-managed-origin-request-policies.html) を利用すると Authorization ヘッダを含めて全てのヘッダを送付できる。

ただし、例えば API Gateway をオリジンにする場合、Host をそのまま渡すと失敗したりするケースがあるので、全ての場合に AllViewer が利用できるわけではない点に注意のこと。
Svelte の日本語サイトが公開されました！

## 今までの Svelte の開発のハードルは高かった

軽量・高速であることを最大の特徴とするJSフレームワークである Svelte は、[State of JS 2020](https://2020.stateofjs.com/en-US/technologies/front-end-frameworks/) の結果などでもわかる通り、近年海外では高い評判を得ており、ここ日本でも興味を持つ人々が着々と増えつつあります。

しかしながら、日本語の情報やドキュメントの整備が圧倒的に不足しており、「話には聞いたことはあるけど試してみるにはハードルが高い」という状態が長い間続いていたフレームワークでもありました。

## しかし日本語での開発環境が整備されてきました

そんな Svelte でしたが、ついに公式サイトの日本語化プロジェクトが立ち上がり、そして先日より日本語版サイトが公開されることになりました！

[Svelte日本語版](https://svelte.jp/)

ちなみに自分が立ち上げたプロジェクトというわけではありませんが、私もリポジトリの管理者でありコントリビューターのひとりでもあります、多くの方々のご協力でこの日本語化プロジェクトは成り立っており、翻訳作業に協力していただいた方々には感謝の言葉もありません。

また日本語の Svelte ユーザーコミュニティも発足しており、日本語化プロジェクトもこのコミュニティが中心になって推進されてきました！

これにより日本語での Svelte の開発環境の整備が一気に進み、今までは「自分で使う分には凄く良いんだけど、他人には勧めにくい」といった状況が改善され、試しにさわってみるには非常に良い環境になってきましたので、是非とも一度 Svelte を試してみることをお勧めします。
【Git】特定のファイルやディレクトリの変更を取り消したい

特定のファイルやディレクトリの変更をなかったことにしたい。
そんなときに使えるコマンド。
メモしておきます。

```
$ git checkout -- <ファイル名>
```
これで、特定のファイルの変更を取り消すことができる。

```
$ git checkout -- <ディレクトリ名>
```
これは特定のディレクトリの変更を取り消せる。

```
$ git checkout --.
```
これで全ての変更を取り消せる。
もしくは、```$ git checkout .```これだけでも大丈夫。
【Git】Gitコマンドを短く入力しよう

## はじめに
チーム開発では欠かせないGit。
gitコマンドはたくさんあるが、特によく使うコマンドというものがあると思う。
例えば、git statusとかgit commitとか。
こういうものをもっと短く入力するための設定をまとめておく。

## gitコマンドにエイリアスをつける
```
$ git config --global alias.ci commit
commitをciに短縮

$ git config --global alias.st status
statusをstに短縮

$ git config --global alias.br branch
branchをbrに短縮

$ git config --global alias.co checkout
checkoutをcoと短縮
```

便利なのでぜひ。
macでruby on railsの環境構築

新しいMacが届いたので、rubyで開発環境を作ることにした

ruby ruby 2.6.3p62 
rails 6

rails new xxxx

でまずはプロジェクトを作った

rails s 

でロカールにアクセスしたら表示ができなかった。。。

ログを見たら

Please run rails webpacker:install Error:

が出てた

webpackが無いのね

rails webpacker:install

を実行したら

sh: node: command not found
sh: nodejs: command not found
Node.js not installed. Please download and install Node.js 　

が出た。。。

なかなか進まない

nodeのインストールの準備
brew install nodebrew
をやって
nodebrew -v
で確認

nodeのインストール

nodebrew ls-remote　でインストールできるバージョンの確認
nodebrew install-binary latest　で最新をインストール

Warning: Failed to create the file

こんなのが出た

mkdir -p ~/.nodebrew/src

でディレクトリーを作ってあげて再度

nodebrew install-binary latest

実行　うまくいった

nodebrew ls

でバージョンの確認
v12.10.0
current: none

none ってのは初期状態のnodeは使用がoffになってるから

nodebrew use v12.10.0

でonにしてあげよう

再度　nodebrew を実行すると

v12.10.0
current: v12.10.0

になった

$ echo 'export PATH=$HOME/.nodebrew/current/bin:$PATH' >> ~/.bash_profile

でパスを通して、ターミナルを再起動

rails webpacker:install

を実行すると次は

Yarn not installed. Please download and install Yarn from https://yarnpkg.com/lang/en/docs/install/

だって。。。

あーー　イラつく

brew install yarn

を実行

うん
うまくいった

yarnもインストールできたので、再度webpackerをインストール

rails webpacker:install

を実行

結果
Webpacker successfully installed

うまくいった

rails s

を実行

画面が表示された！

よかった
Google画像検索の各画像をスクリーンショットで保存する (Python, Selenium)

# はじめに
画像をたくさん集めたい場合、画像検索結果から画像のソースをスクレイピングして画像をダウンロードする、みたいな記事はいくつかありますが、今回はGoogleで画像検索をしたときの結果をその場でスクリーンショットして画像を集める処理を自動化することで、その目的を達成することにしてみます。つまり、Googleの画像検索結果ページに一度アクセスするだけのリクエストで済み、あとはそこにある画像をスクショしているだけという状態をブラウザの自動化ツールであるSeleniumを使って作り出します。

注意点としては、画面に表示されているものをスクショしているだけなので画像サイズ（ピクセル数）は200x200程度の場合が多いです。用途としては問題ないかもしれませんが、仕方ありません。

検索クエリによると思いますが、今回は3分無いぐらいで500枚程度の画像が保存されました

# 環境
- python 3.6.5

# 実装
SeleniumのChromeドライバーを使用しました。使用しているクロームと同じバージョンのドライバーをダウンロードしています

https://chromedriver.chromium.org/downloads

まず、検索結果からすべての画像を表示できるブラウザの状態を作ります。

```python
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.action_chains import ActionChains

def driver_with_scroll(url):
    options = Options()
    options.add_argument('--headless')
    driver = webdriver.Chrome('./chromedriver', chrome_options=options)
    driver.get(url)

    height = driver.execute_script("return document.body.scrollHeight")
    n_times = 1000 # スクロールをする回数（余裕を持ってこの値）
    total_height = 0
  
    for i in range(2): # 1回目: もっと表示ボタンが出るまで, 2回目: もっと表示ボタンを押してから
        for j in range(1, n_times):
            total_height += height
            driver.execute_script("window.scrollTo(0, " + str(total_height) + ");")
        if i == 1: continue
        time.sleep(1) # ボタンが表示される間
        driver.find_elements_by_xpath('//input')[-1].click()    
    return driver


q = '白文鳥'
url = f'https://www.google.com/search?q={q}&tbm=isch'
driver = driver_with_scroll(url)

```

ここまでで、このSeleniumのドライバーはGoogle画像検索結果のスクロールをして、さらにもっと表示ボタンを押した検索結果をすべて表示している状態にあります。ここから、このブラウザに表示されている検索結果の画像をスクリーンショットで保存していきます

検索結果から見るに、だいたいどの画像もwidthかheightが180以上であるようなので、その条件で足切りします

![スクリーンショット 2021-02-11 1.37.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/638747/76430b96-1818-df6e-a82c-311f4cca6ede.png)


```python

img_dir = './img/' # 適当に
for i, elem_obj in enumerate(driver.find_elements_by_xpath('//img')):
    min_size = 180
    if elem_obj.size['height'] < min_size or elem_obj.size['width'] < min_size: continue
    fname = f'{img_dir}{q}_{i}.png'
    try:
        elem_obj.screenshot(fname)
    except:
        continue
driver.close() 
```

結果的に実行時間3分弱で500枚以上の画像が集まりました

![スクリーンショット 2021-02-11 1.39.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/638747/b0352556-a35c-28c7-273b-23b27af146ac.png)

# おわりに
- メリット
    - imgタグであることと、widthかheightの指定のみに依存して画像を集めている
    - 各画像のsourceに対してrequestを送る必要がない

- デメリット
    - 画像が小さい
    - スクリーンショットを実際にブラウザが動かす挙動をするので（headlessであっても）時間がかかる
日本語版Easy Data Augmentation の効果検証（実装コードあり）

# やったこと
先日公開した下記の記事の続編となります。
[自然言語処理のかさ増し手法 Easy Data Augmentation の日本語版を実装する]
(https://qiita.com/tchih11/items/aef9505d26d1bf06a04c)

前回はEasy Data Augmentation(以下、EDA)という手法を使用して日本語の文章をかさ増しする関数を実装しました。今回はその関数を使ってデータセットかさ増しすることによって、実際にモデルの精度が向上するかを検証します。
# 検証方法
livedoorニュース分類モデルの作成を通じて検証しました。
###流れ
- 500件/1000件/2000件のtrainデータを用意
- それぞれでEDAなしモデル、EDAありモデルを作成
- 予め確保しておいたtestデータ（1471件、全体の2割）に当てはめ、accuracyを比較

###備考
- EDAパラメータはα=[0.05,0.1]、aug_num=[1,2,4,8,16]の組み合わせを試す
- モデルはBERTを使用し、パラメータはepoch数をearly stoppingにより決定する以外は全て固定

# 結果
全てにおいて、EDAありがEDAなしを精度を上回る結果となりました。（※差分は丸め込み誤差あり）
元データの件数が少ないほど効果は大きく、件数が多くなるにつれて効果は小さくなりました。

| データ件数 | EDAなし| EDAあり| 差分  | パラメータ   | 
| :--------- | :------ | ------- | ----- | ------------ | 
| 500        | 0.793   | 0.844   | +0.050 | α=0.1、n=16 | 
| 1000       | 0.840   | 0.871   | +0.031 | α=0.1、n=8  | 
| 2000       | 0.876   | 0.901   | +0.024 | α=0.1、n=16  | 


<details><summary>EDAのパラメータ別結果</summary><div>

### 【500件】
| alpha   | num_agg | accuracy | 差分  | 
| ------- | ------- | -------- | ----- | 
| EDAなし | EDAなし | 0.793    | ‐    | 
| 0.05    | 1       | 0.818    | +0.024 | 
| 0.05    | 4       | 0.816    | +0.023 | 
| 0.05    | 8       | 0.840    | +0.047 | 
| 0.05    | 16      | 0.827    | +0.033 | 
| 0.1     | 1       | 0.816    | +0.023 | 
| 0.1     | 4       | 0.828    | +0.035 | 
| 0.1     | 8       | 0.840    | +0.046 | 
| 0.1     | 16      | 0.844    | +0.050 | 

### 【1000件】
| alpha   | num_agg | accuracy | 差分  | 
| ------- | ------- | -------- | ----- | 
| EDAなし | EDAなし | 0.840    | ‐    | 
| 0.05    | 1       | 0.861    | +0.022 | 
| 0.05    | 4       | 0.853    | +0.014 | 
| 0.05    | 8       | 0.865    | +0.026 | 
| 0.05    | 16      | 0.867    | +0.027 | 
| 0.1     | 1       | 0.859    | +0.019 | 
| 0.1     | 4       | 0.863    | +0.023 | 
| 0.1     | 8       | 0.871    | +0.031 | 
| 0.1     | 16      | 0.861    | +0.022 | 

###【2000件】
| alpha   | num_agg | accuracy | 差分  | 
| ------- | ------- | -------- | ----- | 
| EDAなし | EDAなし | 0.876    | ‐    | 
| 0.05    | 1       | 0.888    | +0.012 | 
| 0.05    | 4       | 0.894    | +0.018 | 
| 0.05    | 8       | 0.891    | +0.014 | 
| 0.05    | 16      | 0.893    | +0.016 | 
| 0.1     | 1       | 0.891    | +0.014 | 
| 0.1     | 4       | 0.885    | +0.009 | 
| 0.1     | 8       | 0.895    | +0.018 | 
| 0.1     | 16      | 0.901    | +0.024 | 


</div></details>


# 実装コード
使用したコードを下記になります。
https://github.com/tchih11/qiita_eda

- 01_make_dataset.ipynb　→　livedoorニュースデータの前処理
- 02_make_eda_dataset.ipynb　→　EDAの実行
- 03_eda_verification.ipynb　→　モデリング及び効果検証

環境はgoogle colaboratoryです。
おかしな点があれば、ご指摘いただけますと大変ありがたいです。

# 感想
今回の検証では、EDAによるモデルの精度向上が確認できました。
前回実装時には文意が変わってしまうことを懸念していましたが、今回の検証においては許容範囲内だったようです。
若干出来すぎ感は否めないものの、データが少なく精度が上がらない場面で試してみる価値ありかなと思います。
アノテーション、めっちゃ大変ですからね（経験者）。

# 参考
[https://github.com/Bjarten/early-stopping-pytorch](https://github.com/Bjarten/early-stopping-pytorch)
[文書分類で自然言語処理に触れる](https://colab.research.google.com/drive/1IMjc-RTesapfNCEh0TPmg_ce_qAcV95b)
[【実装解説】日本語版BERTをGoogle Colaboratoryで使う方法（PyTorch）](https://qiita.com/sugulu_Ogawa_ISID/items/e522a38b812b8edb8a54)
【GAS】Googleドキュメントを装飾そのままHTMLメールに変換

##概要
Qiita質問に「ドキュメントの内容をそのままメールで送りたい」と言うのがあり、確かに出来たら便利だなぁ～と挑戦してみた。

Blobで変換したり、HTMLをgetTextすればサクっと解決するのかと思ったら、意外と面倒な手順が必要だったみたい。

質問者の方が納得する答えかどうかはさておき、割りと上手くできたので質問へ返信＆記事投稿^^

##ドキュメントと送信結果
とりあえずドキュメントで適当に文字を装飾してみた。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/708687/ddf3ccfd-ca7f-7d0f-42fc-b99df9f1790b.png)
このドキュメントを元にGASでメール送信したのがコチラ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/708687/c273bc60-c57f-51fb-3536-8e449383d5cc.png)
ちゃんと装飾もリンクも活きてる！
良いんでない？

##コード
ドキュメントのIDからHTMLファイルを出力するURLを作成 ⇒ OAuth対応してUrlFetchでgetContentText ⇒ HTMLメール送信。と言う流れ。

```javascript
function doc_mail() {

  var id = 'ドキュメントのＩＤ';
  var url = 'https://docs.google.com/feeds/download/documents/export/Export?id=' + id + '&exportFormat=html'; 

  var storageUsed = DriveApp.getStorageUsed(); //これが無いと認証エラー
  
  var param = { method: 'get', 
                headers: {'Authorization': 'Bearer ' + ScriptApp.getOAuthToken()}, 
                muteHttpExceptions: true}; //muteHttp～はエラー回避用

  var html = UrlFetchApp.fetch(url, param).getContentText(); 
  
  MailApp.sendEmail({ to: 'メールアドレス', 
                      subject: '件名',  
                      htmlBody: html}); 

}
```

HTMLタグが良く分からないから、メルマガとかリッチテキストで送りたい時に便利かも^^)b

###おしまい
コンポーネントのDOM要素の紐づけを制御する

毎日投稿57日目

GoogleReCPTCHAのコンポーネントを表示させるときに、うまく表示されるときもあればされない時があり、このムラを無くしたいと思ったので調べたところそれらしきものがあった。

外部のスクリプトファイルを読み込み、レンダリングを行う際に非常に役立つのでぜひ使ってください。

今回は特に説明は致しません。

コードをパパっとコピペしてください。

```App.vue
<template>
  <div id="app"></div>
</template>

<script>
import Vue from 'vue'
import Component from 'Component'
export default {
   mounted() {
    // 画面の読み込みが終わった時にコンポーネントを表示
    window.onload = () => {
      this.onloadCallback()
    }
  },
   methods: {
    onloadCallback() {
      const component = Vue.extend(Component)
      const instance = component()
      const element = document.getElementById('app')
      instance.$mount()
      element.appendChild(instance.$el)
    },
  }
}
</script>
```

ちなみにコンポーネントに``props``を追加したい場合は、以下のように設定することができます。

```
instance.props = {
  value: this.props
}
```

呼び出すときはいつもと同じように呼びます。

```
props: {
  value: {
    type: String
  }
}
```

以上、「コンポーネントのDOM要素の紐づけを制御する」でした！

良ければ、LGTM、コメントお願いします。

また、何か間違っていることがあればご指摘頂けると幸いです。

他にも初心者さん向けに記事を投稿しているので、時間があれば他の記事も見て下さい！！

Thank you for reading
【Rails】 初心者のためのコンソールの使い方

はじめに
---
プログラミングスクールに通い、日々勉強中の初心者です。
普段はコードを書き、いちいちサーバーを起動しては、エラーが表示され修正...なんてことを繰り返しています。
そんな時に、コンソールを使用するととても便利だということが最近身に染みて少しずつ分かってきたので、今回も自身と同じような初心者の方に向けた投稿をしようと思います。

開発環境
---
ruby 2.6.3
Rails 5.2.4.4

コンソールを立ち上げる
---
rails cのコマンドを実行すると、001 > と入力できる画面に切り替わります。

```terminal.
$ rails c
Running via Spring preloader in process 18895
Loading development environment (Rails 5.2.4.4)
2.6.3 :001 >

```

Userモデルを例に挙げて色々な動作を確認していきたいと思います。
普段コントローラーに記述している内容を、コンソールで確認・試すことができます。
<br>
①ターミナル上でユーザーを作成
必須情報のみを入力すれば、任意のカラムはnilで保存されます。
※NOT NULL制約がついているものは、入力しないとエラーになってしまいます。

```terminal.
2.6.3 :001 > User.create!(name: "test", email: "test@test.com", password: "111111")
=> #<User id: 1, email: "test@test.com", name: "test", created_at: "2021-02-10 15:45:42", updated_at: "2021-02-10 15:45:42"> 
```
<br>
②id = 1で作成したので、下記のコマンドで作成したユーザーを確認できます。

```terminal.
2.6.3 :002 > User.find(1)
=> ①の結果と同様
```
<br>
③インスタンス変数に代入して、内容を変更する
※@userの中には先ほど作成した、User id: 1の情報が格納されました。
以下のように変更したい内容だけを記述することで、その他のカラムの値はそのまま、変更したい内容だけをアップデートすることが出来ます。

```terminal.
2.6.3 :003 > @user = User.find(1)
=> ①の結果と同様

2.6.3 :004 > @user.update(name: "test2")
 => #<User id: 1, name: "test2", email: "test@test.com", created_at: "2021-02-10 15:45:42", updated_at: "2021-02-10 15:54:50"> 
```
<br>
④ユーザーを削除する


```terminal.
2.6.3 :004 >　@user.destroy
   (0.1ms)  begin transaction
  PostImage Load (0.1ms)  SELECT "post_images".* FROM "post_images" WHERE "post_images"."user_id" = ?  [["user_id", 4]]
  PostComment Load (0.1ms)  SELECT "post_comments".* FROM "post_comments" WHERE "post_comments"."user_id" = ?  [["user_id", 4]]
  Favorite Load (0.1ms)  SELECT "favorites".* FROM "favorites" WHERE "favorites"."user_id" = ?  [["user_id", 4]]
  User Destroy (3.3ms)  DELETE FROM "users" WHERE "users"."id" = ?  [["id", 4]]
   (5.3ms)  commit transaction
 => #<User id: 1, name: "test2", email: "test@test.com", created_at: "2021-02-10 15:45:42", updated_at: "2021-02-10 15:54:50", >

# 全削除のコマンド
2.6.3 :005 >　User.all.destroy_all
```

<br>
⑤検索方法

```terminal.
# 全てのユーザーを表示 
2.6.3 :006 > User.all

# id番号で情報を取得
2.6.3 :007 > User.find(1)

# id以外のカラムの内容で情報を取得
2.6.3 :008 > User.find_by(name: "test")

# idが最後の情報を取得（最新のデータ）
2.6.3 :009 > User.find_by(name: "test")

```
⑥最後に、cont + Dでコンソールから出ることができます。

---
特に初学者の方であれば、普段コントローラーの記述でよく見ているものばかりだと思いますし、すぐにでも試すことができるコマンドばかりです。
毎回、サーバーを起動させて一つ一つデータを作成したり確認するよりも、ターミナルを効率よく使用できれば作業時間も短縮できると思います。
私自身コンソールの存在を知った際には、大変感動した覚えがあります！

終わり
---
今回は以上になります。
私自身もプログラミング初心者ですが、同じ様な立場の方に少しでも参考になれば幸いです。
また、もし内容に誤りなどがございましたら、ご指摘いただけますと幸いです。
データベース設計　README 制約　編

# 制約とは？
制約はDBにおいて、保存するデータに制限をかけるために
カラムに設定できるもののこと。
バリデーションに似ている、DBに直接設定しているため
後になって変更すると、手間がかなりかかるっぽい、、、

そのため、設計の際にしっかり考えて置く必要がある

- NOT NULL制約
- 一意性制約/UNIQUE制約
- 主キー制約
- 外部キー制約

の順に紹介

# NOT NULL制約
データ保存の際に、空の状態で保存できないようにするための制約。
難しく言うと、テーブルの属性値にNULL（空の値）が入らないように制限する制約。
__記述例__

```rb:READMEファイル

| Column             | Type       | Options                        |
| ------------------ | ---------- | ------------------------------ |
| user               | references | null: false, foreign_key: true |
| name               | string     | null: false                    |
| info               | text       | null: false                    |

```



# 一意性制約/UNIQUE制約
テーブル内に、同じ情報のレコードの保存を制限するための制約。
emailアドレスやユーザー名など、被らせないように実装したいときに使う
__unique: true__と記述する。
 
# 主キー制約
notnull制約と一意性制約の合体のような制約。
空の状態、かつ重複しない情報のみを保存できる。
railsでは、idカラムに元々設定されているため、
あんまり使うことないのかなって感じ、、、まあそのうち使いそう（笑）


# 外部キー制約
外部キーの対応するデータが必ず存在しなくてはいけないという制約。
外部のテーブルを紐付けたいときに、references型と一緒に使うことが多いのかな。
マイグレーションファイルには
```t.references ：user, foreign_key: true```
のように記述する。
このように記述すると勝手にカラム名はuser_idになる。

# マイグレーションファイル記述例
```rb:マイグレーションファイル
class CreateMessages < ActiveRecord::Migration[6.0]
  def change
    create_table :messages do |t|
      t.string :content
      t.references :room, foreign_key: true
      t.references :user, foreign_key: true
      t.timestamps
    end
  end
end
```
yarn start でエラー　

## ReactCLIで作成した時のエラーと解決法

```npx create-react-app todo-app```を実行し、Success後、
```cd todo-app
yarn start```すると、

```/bin/sh: react-scripts: command not found   error Command failed with exit code 127.     info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this  　```
のエラー発生。
（以前は　yarn startでローカルサーバーの立ち上げに成功していたが、reactをgithub-pagesにデプロイできるようにいじってから、エラーがでるようになったと思われる、、）

***ネットに上がっているいくつかの解決法試して、　やっと解決できた方法↓***

```yarn install -g react-scripts```を実行後、　
```yarn start```でサーバーの立ち上げに成功。

[参考](https://stackoverflow.com/questions/47612580/react-scripts-command-not-found )
Mambaを使った高速condaパッケージ管理 (python)

# はじめに
Pythonのcondaパッケージ管理でmambaというツールが高速でよいよ！という話を耳にしたので自分の勉強のためにメモしてまとめてみました。

基本的に公式Readmeの内容をベースにしているので英語が読める方は直接どうぞ！
https://github.com/mamba-org/mamba

# mambaとは？
一言でいうと、**"C++で実装された高速なcondaパッケージマネージャー"**

大きな特徴として下記が挙げられます。
- クロスプラットフォーム対応
- マルチスレッドによるリポジトリ・パッケージの並列ダウンロード
- 最先端のライブラリ (libsolv)を使って高速に依存関係を解決
- コア部分をC++で実装
- `conda` とほぼ互換

# インストール
```sh
conda install mamba -c conda-forge
```

# condaパッケージのインストール

```sh
mamba install <インストールしたいパッケージ名> -c conda-forge
```
の形でインストールできます。

例：
```sh
mamba install pytorch -c conda-forge
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57724/9a656d21-5548-e335-1bb7-5c051e15c715.png)

# 速度比較
pytorchのインストールで、インストール時間にどの程度差があるのか比較してみました。
あくまで簡易的な比較で、キャッシュ等の影響を排除しきれていないので、あくまで参考程度でお願いします。

環境：
- WSL2
- anaconda3-2020.11

## anacondaの場合
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57724/d3626f41-1f1e-3d5f-a067-65b177213c43.png)
結果：約54秒

## mambaの場合
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57724/7acb913c-cd2a-abab-74a5-808859d8a88d.png)![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57724/d454b5d2-a0e3-7c8e-819e-b55f4644b350.png)
結果：**約28秒**
※一部anacondaでインストールしたものがキャッシュされているようです..

# まとめ
mambaを使うとcondaよりも高速にcondaパッケージをインストールできたようです（？）
mambaにはこの他、minicondaに相当する`micromamba`と呼ばれる実験的機能も存在します。
こちらも試してみた後にまとめてみたいと思います。

# 参考
https://github.com/mamba-org/mamba
カラーパレット

webアプリケーション作成に使えるおしゃれなカラーパレットのURL
https://www.happyhues.co/palettes/17

![スクリーンショット 2021-02-11 0.54.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1050099/c571f00b-19c0-0e3e-e093-878652ded567.png)
Go のそれぞれのデータ型メモリサイズを調べてみた！

# なぜ調べたか
できるだけメモリを取らない型って何かな〜と思って調べてみました。

# 書いたコード

```golang
package main

import (
	"fmt"
	"unsafe"
)

var (
	b bool

	u8  uint8
	u16 uint16
	u32 uint32
	u64 uint64

	i8  int8
	i16 int16
	i32 int32
	i64 int64

	f32 float32
	f64 float64

	c64  complex64
	c128 complex128

	by byte
	r  rune

	u  uint
	i  int
	up uintptr

	str string
)

func main() {
	fmt.Println("bool :", unsafe.Sizeof(b), "byte")

	fmt.Println("uint8 :", unsafe.Sizeof(u8), "byte")
	fmt.Println("uint16 :", unsafe.Sizeof(u16), "byte")
	fmt.Println("uint32 :", unsafe.Sizeof(u32), "byte")
	fmt.Println("uint64 :", unsafe.Sizeof(u64), "byte")

	fmt.Println("int8 :", unsafe.Sizeof(i8), "byte")
	fmt.Println("int16 :", unsafe.Sizeof(i16), "byte")
	fmt.Println("int32 :", unsafe.Sizeof(i32), "byte")
	fmt.Println("int64 :", unsafe.Sizeof(i64), "byte")

	fmt.Println("float32 :", unsafe.Sizeof(f32), "byte")
	fmt.Println("float64 :", unsafe.Sizeof(f64), "byte")

	fmt.Println("complex64 :", unsafe.Sizeof(c64), "byte")
	fmt.Println("complex128 :", unsafe.Sizeof(c128), "byte")

	fmt.Println("byte :", unsafe.Sizeof(by), "byte")
	fmt.Println("rune :", unsafe.Sizeof(r), "byte")

	fmt.Println("uint :", unsafe.Sizeof(u), "byte")
	fmt.Println("int :", unsafe.Sizeof(i), "byte")
	fmt.Println("uintptr :", unsafe.Sizeof(up), "byte")

	fmt.Println("string :", unsafe.Sizeof(str), "byte")

	p := &struct {}{}
	fmt.Println("struct pointer :", unsafe.Sizeof(p), "byte")
	fmt.Println("struct value :", unsafe.Sizeof(*p), "byte")

	f := func() {}
	fmt.Println("function pointer :", unsafe.Sizeof(&f), "byte")
	fmt.Println("function value :", unsafe.Sizeof(f), "byte")
}

```

# 実行結果

```terminal
bool : 1 byte

uint8 :  1 byte
uint16 : 2 byte
uint32 : 4 byte
uint64 : 8 byte

int8 :  1 byte
int16 : 2 byte
int32 : 4 byte
int64 : 8 byte

float32 : 4 byte
float64 : 8 byte
 
complex64 :   8 byte
complex128 : 16 byte

byte :    1 byte
rune :    4 byte
uint :    8 byte
int :     8 byte
uintptr : 8 byte

string : 16 byte

struct pointer :   8 byte
struct value :     0 byte

function pointer : 8 byte
function value :   8 byte

```
ちなみに

- ポインタ型はどれも 8 byte
- 配列は 型のメモリサイズ * 要素数 byte
- mapは 8 byte
- sliceは 24 byte
- structは要素のメモリサイズの合計

でした。

# (結論) 空の struct なら値が 0 byte
LaravelをHerokuにデプロイする方法

Herokuのデプロイのやり方で躓いてしまったので、メモとして書き残しておきます。

初めに、GitとHeroku CLIのインストールが必要です。

```
$ cd (デプロイするディレクトリ)

$ heroku login

$ heroku create --buildpack heroku/php
Creating app... done, ⬢ aaaaa-aaaaaa-11111　←アプリ名

$ git init

$ heroku git:remote -a herokuのアプリ名

$ git add .

$ git commit -m "コメント"

$ git push heroku master
[Ruby on Rails] 詳細画面に遷移

##詳細画面への遷移方法


まず、ルーティングの設定をします。
今回は仮に**items**とします。
　　

![スクリーンショット 2021-02-10 23.38.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1078698/29c50df4-848b-2a5e-8dc1-7b2607f240cb.png)

  
   　　
 
次に**index.html**に詳細ページへ飛ぶ為の記述を書いていきます。
![スクリーンショット 2021-02-10 23.49.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1078698/ce8775b6-7cf6-9fc7-4bac-6a5d46cbfb1d.png)

どのアイテムの情報か読み込めるようにパスには必ず**id**が必要になります。
　　
上記の**item_path**は削除機能などと同じ**Prefix**なので
それを見分けるために、link_toメソッドなどでリンクを設定する際には、HTTPメソッドを指定してあげます。


　
次はshowアクションをコントローラーに定義してあげます。
![スクリーンショット 2021-02-10 23.56.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1078698/baee4061-9129-b190-d820-ce94f2790fc8.png)
　　

あとは**viewsファイル**を作成してあげれば、show.htmlへ遷移されるはずです。


　<h3>追記

仮に**show.html**で画像を読み込みたいって時には
class名を記述してあげてから、
**@item.image**を追加してあげると読み込むようになります。

![スクリーンショット 2021-02-11 0.07.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1078698/bc0f9bcb-f9ac-3afd-2270-24d42822bb25.png)


**image_tag**は画像ファイルへのパスと、必要なオプションを指定して使用します。
自作のChrome拡張機能をManifestV3に移行してみた

##概要
ManifestV3が使えるChrome 88が少し前に正式リリースされたので試しに移行してみた時の感想や注意点を雑にまとめた記事です。
ちなみに移行したのはMouseGestureという自作のChrome拡張機能です。
##実際にManifestV3してみる
取り敢えず`manifest.json`の`manifest_version`を3に変更してみます。

```diff_json:manifest.json
- "manifest_version": 2
+ "manifest_version": 3
```
エラーが発生しました。
>~\projects\MouseGesture_Chrome-Extensions
The "background.scripts" key cannot be used with manifest_version 3. Use the "background.service_worker" key instead.
マニフェストを読み込めませんでした。

指示通り`background`の`scripts`を`service_worker`をに変更してみました。

```diff_json:manifest.json
     "background": {
-         "scripts": ["js/background.js"],
-         "persistent": false
+         "service_worker": "js/background.js"
      }
```
登録はできましたがまたエラーが発生しました。
>Service worker registration failed

色々調べてみて分かりましたがどうやら`service_worker`のスクリプトは`manifest.json`と同じフォルダにないと駄目みたいです。

```
├─css
├─html
├─icons
├─js
├─background.js
└─manifest.json
```
`background.js`を移動後

```diff_json:manifest.json
     "background": {
-         "service_worker": "js/background.js"
+         "service_worker": "background.js"
      }
```
しかしまだ他のエラーが発生します。
>'browser_action' requires manifest version of 2 or lower.

こっちの解決方法は単純で`browser_action`を`action`に変えればいいだけでした。

```diff_json:manifest.json
-     "browser_action": { "default_popup": "html/popup.html" }
+     "action": { "default_popup": "html/popup.html" }
```
**たったこれだけの修正でManifestV3に更新できました。**
##まとめ
バックグラウンドページやイベントページはサービスワーカーへ移行する必要があります。
その時ファイルの位置を`manifest.json`と同じディレクトリにします。
`browser_action`や`page_action`は`action`に変える必要があります。
移行に必要なことについては[Manifest V3 migration checklist](https://developer.chrome.com/docs/extensions/mv3/mv3-migration-checklist/)が参考になります。
##参考リンク
- https://developer.chrome.com/docs/extensions/mv3/intro/mv3-migration
- https://github.com/kentbrew/learning-manifest-v3/blob/master/ep_004.md
【Java】ArrayListについて

#記述方法
ArrayListを使う記述方法は、以下の様に`<>`の中に格納したい型名を記述します。

```Sample.java
import java.util.ArrayList;

public class Sample {
    public void main(String[] args) {
        ArrayList<String> array = new ArrayList<String>();
    }
}
```
#特徴
######宣言時のサイズ指定は不要
宣言時にサイズを指定しないため、データを追加しようとした時に自動的に追加されていく。

######インスタンスでないものは格納できない
例えば`int`型は使えないので、`Integer`を使用する。
Rails devise導入

ユーザー管理機能を簡単に実装するためにdeviseを導入する。

まずは、Gemfileを編集します。

```
gem 'devise'
```

次に,Gemをインストールします。

```
$ bundle install
```
Gemをインストールしたら、ローカルサーバーを再起動します。
理由は、インストールしたGemの反映するタイミングが、サーバー起動時だからです。

# deviseの設定ファイルを作成
deviseを使用するためには、Gemのインストールに加え、devise専用のコマンドで設定ファイルを作成する必要があります。

```
$ rails g devise:install
```

# userモデル作成

```
$ rails g devise user
```

マイグレーションファイルに必要な絡むを追加などして、migrateします

```
$ rails db:migrate
```
これで、usersテーブルが作成されました。

# deviseのviewを作成します

```
$ rails g devise:views
```
viewの作成が完了しました。
Java：「メインクラスを検出およびロードできませんでした」の解決法

#はじめに
当方はJavaの初学者で、今までは1つのソースコード内でクラスを作成しプログラミングを行ってきたが、学習が進むにつれてクラスの数が増えてきたため、パッケージを利用することにした。
しかし、パッケージを利用して同様の方法で実行しようとしたところ、少し手こずったため、備忘録として残しておく。
###現象
パッケージの利用で複数のソースコードをコンパイルし、実行しようとしたところ...
`・コンパイルはできるのに実行ができない！`
`・エラー: メインクラスを検出およびロードできませんでした`
`・原因: java.lang.NoClassDefFoundError: Sample2/Sample2 (wrong name: Sample2)`

#今までの実行方法


```Sample1.java
class Student {
    private String name;
    public Student(String _name) {
        this.name = _name;
        System.out.println(this.name + "は生徒です");
    }
}

class Sample1 {
    public static void main(String[] args){
        Student s = new Student("山田");
    } 
}
```

例えば、上記のソースコード(Sampleフォルダ直下）をターミナルでコンパイル・実行すると

```
****noMacBook-Pro:Sample ********$ javac Sample1.java
****noMacBook-Pro:Sample ********$ java Sample1
山田は生徒です
```
という結果になり、特に問題なく実行できる。

#パッケージ化されたものを同様の方法で実行すると...?
1つのソースコード内のクラスを複数のソースコードに分けて、1つのパッケージとするとき、先ほどと同様の方法で実行してみる。

なお、Sample1.javaはSample2.javaとStudent.javaに分割し、Sample2フォルダ内に格納した。
（ディレクトリ構造は以下の通り）

![スクリーンショット 2021-02-10 23.23.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/503230/6793eec2-e032-0376-f93a-dd0904538071.png)


```Sample2.java
package Sample2;

public class Sample2 {
    public static void main(String[] args){
        Student s = new Student("山田");
    } 
}
```
```Student.java
package Sample2;

public class Student {
    private String name;
    public Student(String _name) {
        this.name = _name;
        System.out.println(this.name + "は生徒です");
    }
}
```
これらのソースコードを先ほどと同様の方法で実行してみる
（パスはSample2フォルダに変更済み）

```
****noMacBook-Pro:Sample2 ********$ javac Sample2.java Student.java
****noMacBook-Pro:Sample2 ********$ java Sample2
エラー: メイン・クラスSample2を検出およびロードできませんでした
原因: java.lang.NoClassDefFoundError: Sample2/Sample2 (wrong name: Sample2)
```
この通り、コンパイルは滞りなくできたのだが、エラーとなってしまい実行ができない。
![スクリーンショット 2021-02-10 23.20.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/503230/2616451b-1dcf-48a5-1331-b9f2f89b3281.png)
（↑クラスは生成されている）

#原因とその解決
原因としては、コマンドの入力が違うというありきたりなもの。
起動しようとしているクラスの指定が間違っていることが原因らしい。
何も考えずに`java 〜`というコマンドで実行してきたが、パッケージを利用する際はそう簡単にはいかないらしい。

`java Sample2`というコマンドは、`デフォルトパッケージにあるSample2.classを実行する`という意味なので、こちらでパッケージを指定する場合は`○○パッケージの××クラスを実行する`というコマンドを入力しなければならない。

従って、正しくは...

```
****noMacBook-Pro:Sample2 ********$ cd /Users/********/Desktop/Sample
                                   (↑Sampleフォルダにパスを変えている)
****noMacBook-Pro:Sample ********$ java Sample2.Sample2
山田は生徒です
```
無事出力された。

#まとめ
今回のように、パッケージ内のファイルを実行するには
`java パッケージ名.クラス名`
というコマンドを入力する必要がある。

あと、余談だが、パッケージ名は全て小文字というのが慣習らしい。
なので今回のようなSample2というパッケージ名はあまり良くなくて、sampleという名前の方が好まれるとか。
次からはその辺りももう少し意識して名前をつけようと思う。
そうだ、SQLを勉強しよう⑥

#はじめに
基本となる部分はこの投稿の部分くらいまでかな…

##SELECT文固有の装飾

###集合演算子
2つのテーブルをくっつけたり、共通する項目や違いを明らかにしたりするときに使います。

- 選択列リストの列数とデータの型が一致していなければいけない。
- ORDER BY句は最後のSELECT文に記述する。
- ALLを付けると、重複している行が取り除かれなくなる。→付けなければ、重複している行は勝手に取り除いてくれる。

####和集合

```sql
SELECT 文1
UNION(ALL)
SELECT 文2
```

2つのテーブルの検索結果を足し合わせて返されます。

####差集合

```sql
SELECT 文1
EXCEPT(ALL)
SELECT 文2
```
2つのテーブルの違いを返します。
※文1の集合にあって、文2の集合にない項目を取得する。


####積集合

```sql
SELECT 文1
INTERSECT(ALL)
SELECT 文2
```
2つのテーブルに共通する行を返します。
Emulator: emulator: ERROR: unknown skin nameと言われたときの対処法

# 現象
エミュレーターを起動しようとしたらこのような`EvengLogウィンドウ`にメッセージが表示され、エミュレーターが起動しませんでした。

```console
Emulator: emulator: ERROR: unknown skin name 'pixel_2'
```

# 解決方法

一度AVDManagerで該当のエミュレータを編集(Edit)し、そのまま何も変えずに保存すると、あら不思議起動するようになります。

# その他

CatalinaにMacOSを今更ながらアップデートしたのですが、HDD直下のフォルダにはアクセス不可になったようで、開発環境が全てアウトになってしまいましたorz

恐らく上記のエラーも、パスを色々変えた影響かなあ・・・？

しかしCatalinaに上げたらビルドがむちゃくちゃ遅くなった気が・・・:fearful:

現場からは以上です。
Railsのビューにeachメソッドで取得したデータの中身が全て表示されてしまう問題解決

### 概要
ERB形式で作ったビューに、eachメソッドを使って下記のように複数のタグを表示出来るような記述を書きました。

```erb:ビューファイル
〜省略〜
<div class="card-tag">
    <%= card.tags.each do |t| %>
        <%= t.tag %>
    <% end %>
</div>
〜以下略〜
```

すると、ブラウザ上では

```erb:ブラウザ上での表示
タグのテスト [#<Tag id: 3, tag: "タグのテスト", created_at: "2021-02-10 08:56:05", updated_at: "2021-02-10 08:56:05">]
```

と、配列全体が表示されてしまい、
いやいや君は別に呼んでないんだよなんじゃらほい状態となってしまったので、
対処法を探す流れとなりました

### 結論
原因はミスです。ええ、しょうもない凡ミスです。

`<%= card.tags.each do |t| %>`
ではなく、正しくは
`<% card.tags.each do |t| %>`
と記述するのが正解でした。
要するに`<%`のあとに"="が付いたままだったことが原因で、
モデルから取得してきた情報を素材の味を生かしそのまま出力していたという訳ですね。

### 所感
あれ…この<%の後ろに=が付いているかいないかという凡ミス…**以前にもやった気がするなぁ**
たしかその時は、いつかまた同じミスを繰り返しそう…と思いましたが、案の定やらかしてしまいました。
こういった凡ミスの特効薬って何でしょうかね？
ヘルパーメソッドが出るたびにこのミスを思い出すしかないか…~~ああ、またやらかしそう~~
【Vuetify】Vuetifyでヘッダーを作る　真ん中に余白を　入れる

```index.html
      <v-toolbar color="red lighten-3" dark>
        <v-toolbar-title>App</v-toolbar-title>
        <v-spacer></v-spacer>
        <v-btn flat>menu</v-btn> 
      </v-toolbar>
```

### v-toolbar　
これがツールバーと呼ばれるものを表示するもの

### v-toolbar-title
これがこのツールバーのタイトルに関するもの

### v-spacer
これを入れることによって次のタグとの間に余白を入れることができる。

### v-btn
これがボタン
Raspberry Piで遅延を計ってみた。


ラズパイカメラと出力での映像遅延を確認したかったので、いまさらながら、こちらの本を参考に色々と。
　https://shop.cqpub.co.jp/hanbai/books/47/47101.html

結論から書くと、Raspi → UDP → Raspiは遅延130msほど。映像は1920x1080 30fps 12Mbps。
RaspiVidでの出力だと100ms程度なので転送部分で1Frame分の遅延が発生している計算。
で、気になったのでそのままの処理が作れないかなということで作ってみたのが以下のコード
　https://github.com/ryuqk/omxTest

とりあえず、使いまわしできるようにOMX部分をライブラリ化してみました。
カメラからのデータはVideo4LinuxでH264として読み出し。

だがしかし、このコードだと200msほどになってしまう。
H264にエンコードして、OMXでデコードしてるとはいっても本のコードも転送挟んでるだけで
やってることは基本同じはず。V4LとOMXの混在だからかもしれないが、原因不明。
OMXだけで書いてみるとか、これを分離してUDPで送ってみるとかRTPにしてみるとか
そのうちやってみようとおもいます。
JavascriptでURLの変更を検知したいなら、DOMの変化を検知しろ。

毎日投稿56日目

今日はJavascriptについて書いていきます。

ふと、URLの変更を検知したいなと思ったこと一度はありませんか？

このURLの時はこの処理を加えたいとか、入力画面ではページ移動するときに警告を表示したいとか誰しもが一度は思うこと。

そこで、今回はタイトルにも書いてある通りDOMの変化を検知します。

URLの変更を検知するのって結構めんどい。。。

また、大体はURLの変更を検知して、結局変更を加えるのって要素ですよね。

なら最初っからDOMで全部行ってしまいましょう！

それでは説明を一緒に見ていきましょう！

#MutationObserverの宣言#

皆さん``MutationObserver``と言う名のメソッドは聞いたことはあるでしょうか？

おそらくこの記事を見に来ている方は、ほとんどが知らないと思います。

実際僕も初耳でした。

これは指定したDOMの変更を検知するというものです。

これを使ってDOMの変更を検知します。

```index.js
const observer = new MutationObserver(function () {
  // 処理
})
observer.observe(document, { childList: true, subtree: true })
```

``observe()``の第一引数に**変更を検知したい要素**を指定し、第二引数には指定されたプロパティを入れます。

一応説明しておくと、``childList``は「対象ノードの子ノード（テキストノードも含む）に対する追加・削除を監視」、``subtree``は「対象ノードとその子孫ノードに対する変更を監視する場合」となっています。

って言っても説明はドキュメントからコピペしただけなので、下記のドキュメントを見て頂いた分かりやすいかと。

[https://developer.mozilla.org/ja/docs/Web/API/MutationObserver](https://developer.mozilla.org/ja/docs/Web/API/MutationObserver)

#使用例#

以下に使用例を載せておきます。

特定のページだけページを移動しようとすると警告を表示するようにしています。

```index.js
let nowOnbeforeload = null
const observer = new MutationObserver(function () {
  // 既にイベントを追加していたら処理を行わない
  if (nowOnbeforeload) {
    return
  }
  // 警告を表示する要素を取得
  const element = document.getElementsByClassName('onbeforeload')[0]
  if (element) {
    // 要素があればイベントを追加
    window.onbeforeunload = function (event) {
      if (event.target.activeElement.id === 'remove-beforeunload') {
        // クリックした要素がイベントを忠告しない要素だったら終了
        return
      }
      event.preventDefault()
      event.returnValue = ''
    }
    nowOnbeforeload = element
  } else {
    return
  }
})
```

このようにしてURLの変更（DOMの変更）を検知することで、自由自在にフロント部分を操れます。

めちゃ便利なのでぜひ使ってください！

以上、「JavascriptでURLの変更を検知したいなら、DOMの変化を検知しろ。」でした！

良ければ、LGTM、コメントお願いします。

また、何か間違っていることがあればご指摘頂けると幸いです。

他にも毎日初心者さん向けに記事を投稿しているので、時間があれば他の記事も見て下さい！！

Thank you for reading
AtCoder 生活111日目

[前回](https://qiita.com/flandrescarlet237/items/117aa6f38753ff6110fd)

#111日目
今日は、灰色を2問と茶色2問を解きました。

|問題|難易度|自力で解けた|かかった時間|
|:-:|:-:|:-:|---|---|
|ABC044|B|◯|12分56秒|
|AGC014|A|✕|77分2秒|
|ABC131|D|◯|13分43秒|
|ARC081|C|✕|123分14秒|


##[ABC044_B](https://atcoder.jp/contests/abc044/tasks/abc044_b)

```c++

#include <bits/stdc++.h>
#define rep(i,n) for(int i = 0;i < (n);i++)
using namespace std;
using ll = long long;
using pii = pair<int,int>;

const int INF = 2e9;

int main(){
    string s;
    cin >> s;
    sort(s.begin(),s.end());
    char r = s[0];
    int c = 1;
    bool ok = true;
    for(int i = 1;i < s.size();i++){
        if(s[i] == r)c++;
        else {
            if(c % 2 != 0)ok = false;
            c = 1;
            r = s[i];
        }
    }
    if(c % 2 != 0)ok = false;
    if(ok)cout << "Yes" << endl;
    else cout << "No" << endl;
}

```

解くのにかかった時間：12分56秒


##[AGC014_A](https://atcoder.jp/contests/agc014/tasks/agc014_a)

```c++

#include <bits/stdc++.h>
#define rep(i,n) for(int i = 0;i < (n);i++)
using namespace std;
using ll = long long;
using pii = pair<int,int>;

const int INF = 2e9;

int main(){
    ll a,b,c;
    cin >> a >> b >> c;
    rep(i,100000){
        if(a%2 || b%2 || c%2 ){
            cout << i << endl;
            return 0;
        }
        ll x = a/2;
        ll y = b/2;
        ll z = c/2;
        a = x+y;
        b = y+z;
        c = z+x;
    }
    cout << -1 << endl;
}

```

解くのにかかった時間：77分2秒
感想：なかなかに理解が進まなかった。


##[ABC131_D](https://atcoder.jp/contests/abc131/tasks/abc131_d)

```c++

#include <bits/stdc++.h>
#define rep(i,n) for(int i = 0;i < (n);i++)
using namespace std;
using ll = long long;
using pii = pair<int,int>;

const int INF = 2e9;

int main(){
    int n;
    cin >> n;
    vector<pii> x(n);
    rep(i,n){
        int a,b:
        cin >> a >> b;
        x[i].first = b;
        x[i].second = a;
    }
    sort(x.begin(),x.end());
    ll t = 0;
    rep(i,n){
        t += x[i].second;
        if(t > x[i].first){
            cout << "No" << endl;
            return 0;
        }
    }
    cout << "Yes" << endl;
}

```

解くのにかかった時間：13分43秒


##[ARC081_C](https://atcoder.jp/contests/arc081/tasks/arc081_a)

```c++

#include <bits/stdc++.h>
#define rep(i,n) for(int i = 0;i < (n);i++)
using namespace std;
using ll = long long;
using pii = pair<int,int>;

const int INF = 2e9;

int main(){
    int n;
    cin >> n;
    vector<int> v;
    map<int,int> mp;
    rep(i,n){
        int s;
        cin >> s;
        mp[s]++;
        if(mp[s] == 2){
            mp[s] = 0;
            v.push_back(s);
        }
    }
    sort(v.rbegin(),v.rend());
    ll ans = 0;
    if(2 <= v.size())ans = 1LL*v[0]*v[1];
    cout << ans << endl;
}

```

解くのにかかった時間：123分14秒
感想：mapの使い方を忘れていた。


###最後に
ABC以外がレートより少し難しくなってきた気がする
単射であることと同値な命題

# 例題 1.1.5
$f: A \to B$を写像とするとき、次の（１）、(2)が同値であることを証明せよ。
(1) $f$は単射である。
(2) 任意の部分集合$S\subset A$に対し、$f^{-1}(f(S)) = S$である。

# 証明

次の２命題が成り立つとき、(1)と(2)は同値である。

- (1) $\Rightarrow$ (2)
- (2) $\Rightarrow$ (1)

## (1)⇒(2)を示す。 
次の２命題が成り立つとき、(2)も成り立つ。

- $\forall S \subset A, \; S \subset f^{-1}(f(S))$ ・・・　①
- $\forall S \subset A, \; f^{-1}(f(S)) \subset S$ ・・・　②

### ①が成り立つことを示す。
$A$の任意の部分集合を$S$とする。
このとき、$S$の像は$f(S) = \\{f(a) \mid a \in S\\}$となる。
また、$f(S)$の逆像は$f^{-1}(f(S)) = \\{ a \in A \mid f(a) \in f(S)\\}$である。
$f(S)$の定義より、$f^{-1}(f(S))$は$S$の元$a$を含む。
したがって、次が成り立つ。つまり、①が成り立つ。

```math
 a \in S \Rightarrow a \in f^{-1}(f(S))
```

### ②が成り立つことを示す。
$A$の任意の部分集合を$S$とする。
逆像$f^{-1}(f(S))$の元を$a$とすると、$f^{-1}(f(S))$の定義より、$a$の像$f(a)$は像$f(S)$に属する。すなわち、次が成り立つ。

```math
 a \in f^{-1}(f(S)) \Rightarrow f(a) \in f(S)
```

f(S)の定義より、$f(a) = f(a')$となる元$a'$が$S$に属する。
(1)より$f$は単射なので、$a=a'$である。したがって、$a \in S$である。
すなわち、次が成り立つ。つまり、②が成り立つ。

```math
 a \in f^{-1}(f(S)) \Rightarrow a \in S
```

### ①、②が成り立つため、(1)⇒(2)も成り立つ。

## (2)⇒(1)を示す。

$A$の２元を$a,a'$とし、$f(a)=f(a')$が成り立つとする。
集合$\\{a\\}, \\{a'\\}$を(2)の$S$としてみれば、次が成り立つ。

```math
f^{-1}(f(\{a\})) = \{a\}, \; f^{-1}(f(\{a'\})) = \{a'\}
```

$f(a) = f(a')$より、$f(\\{a\\})= \\{ f(a) \\} = \\{f(a')\\} = f(\\{a'\\})$である。
したがって、$f^{-1}(f(\\{a\\})) = \\{a\\} = \\{a'\\}$である。
すなわち、$a=a'$である。
以上より、次が成り立つ。

```math
f(a) = f(a') \Rightarrow a = a'
```

### つまり、(2)⇒(1)が成り立つ。

## (1)⇒(2)、(2)⇒(1)が成り立つため、(1)と(2)は同値である。
urlのステータス一括チェック

# urlのステータス一括チェック

## 背景

web開発で対象urlをチェックする必要があったのですが、対象が50パターン程あって１つずつurlを実行するのは凄く時間がかかるので一括で出来る様にしました。

## コマンド
対象urlをurl_list.txtに記載している前提です。
1行ずつループしてcurlのステータスを取得しています。
最後にechoでurlとステータスをセットで表示しています。

``` sh
for url in `cat url_list.txt`; do curl -s -o /dev/null -w '%{http_code}' $url | xargs -I {} echo $url {}; sleep 1;done
```
xamppのエラーにハマった※zend_extensionのパス指定ミス

vscode でphpデバッグを行うため、
xdebugパッケージをvscodeへインストールした。

手順通りに
https://xdebug.org/wizard
で
http://localhost/phpinfo.php
の内容をコピペし、下記情報が表示された。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569318/1433e128-e772-ba91-17c0-7a4d151c03dd.png)

こちらも手順通りにdllファイルを\xampp\php\ext\へ格納
php.iniに
zend_extension = \xampp\php\ext\php_xdebug-3.0.2-7.3-vc15-x86_64.dll
を追記

ただ、apache再起動したところエラーになる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569318/1651a4ef-a741-641e-70d6-281022c7c232.png)

原因を色々調べたところ、
php.ini内に記述されている
extension_dir = "\xampp\php\ext"
が原因。

既に～\extまでのパス指定していたため、エラーとなっていた。
というわけで、zend_extension の記述を下記に訂正
zend_extension = "php_xdebug-3.0.2-7.3-vc15-x86_64.dll"
apache再起動したところ無事起動し、デバッグも行えました。
Stripe Billing(Subscription)ユーザー向けのニッチなメンテナンス対応の情報

Stripeからとあるカードブランドにおいて、システムメンテナンスのため一部決済が失敗する可能性がある連絡がありました。


> メンテナンス日時予定：
- 2021年2月18日(木) 日本時間 02:00 ~ 02:15
- 2021年2月18日(木) 日本時間 02:20 ~ 02:35

とのことだったので、この時間帯に定期課金の決済が発生する可能性があるか調べてみましょう。

ちなみに Smart Retries などのリトライスケジュールを組んでいるようであれば、翌日などに自動的にリトライをしてくれるため、そんなに気にすることはありません。

該当のユーザーに対して事前に「システムメンテナンスのため決済に失敗する可能性がありますが、自動的に再決済されるため特に操作などは不要です」とお伝えするだけで済むかと思います。




# 該当時間帯にcurrent_period_endがあるタイミングを調べるスクリプト

とりあえずざっくりと該当するSubscriptionのIDと契約更新のタイミング（ちゃんとJSTで意図した時間帯に該当するデータがあるかを確認するため）を表示するようにしてみました。


```
YOUR_SECRET_KEY=***YOUR_SECRET_KEY***
SUBSCRIPTION_LIMIT=10
START=`date -j -f "%Y-%m-%d %H:%M:%S" "2021-02-18 02:00:00" "+%s"`
END=`date -j -f "%Y-%m-%d %H:%M:%S" "2021-02-18 02:35:00" "+%s"`
date -r ${END}
RES=$(curl -s --globoff https://api.stripe.com/v1/subscriptions?limit=${SUBSCRIPTION_LIMIT}\&current_period_end[lt]=${END}\&current_period_end[gte]=${START} \
  -u ${YOUR_SECRET_KEY}: \
  -G)
END=`echo ${RES} | jq '.data[] | .current_period_end' | sort`
for TIME in ${END}
do
  date -r ${TIME}
done
RESULT=`echo ${RES} | jq -r '.data[] | .id'`
for ID in ${RESULT}
do
  echo ${ID}
done
```

# 結果

該当するデータはありませんでした！
ファイルの比較をする/結果をファイルに書き出す

前にやったことあるのに調べたので、ここにメモします


##ファイルを比較するコマンド：`fc` 

``` linux
fc aaa.txt bbb.txt
```

##結果をファイルに保存する：命令文のあとにファイル名を指定

``` linux
fc aaa.txt bbb.txt > diff.txt
```
配列を代入した変数の正体を暴いてみた

開発環境
Ruby 2.6.5

# 配列を代入した変数の正体
ある程度プログラミングを経験している方からすると当たり前のことだと思いますが、結構実装途中で意図しない挙動をするのでメモとして記録します。(一応技術書を参考にしてますが、違ったらご指摘ください)


## コード実行
まず下記のコードの実行結果を予想してみてください。

```ruby.rb
array = [1,2,3]

array2 = array

array2[0] = 124

puts array[0]

```


実行結果は

```
124
```
になります。

ここで大事なのは**配列の数字自体は変数に代入されていない**という点です。

## 配列を代入した時の裏側

このとき裏側で起こっているのは**配列の保存場所を示した番号**が変数として代入されています。
このように保存場所を示す番号を参照して値を呼び出す変数を参照型変数と言います。

参照型変数の特徴は参照する番号が変数に入るので、複数の変数で1つの場所を指すことがあります。
上記の配列の例は

```ruby.rb
array = [1,2,3]

array2 = array

array2[0] = 124

puts array[0]
```
配列の保存場所を参照する番号を代入したarrayをarray2に代入しているので2つの変数の指す配列が同じになっています。

そのため、array2の配列を変更したと思ってもarrayも変更されているということです。

## より詳しく
より詳しく伝えると、Rubyの場合すべてがオブジェクトであるので配列のみではなく整数なども参照型になります。

```ruby.rb
num = 1

array = [1,2,3]
```
上記のコードではnumには1というオブジェクトへの参照を代入されています。
arrayには1,2,3を参照したリストの参照を保存しています。

```ruby.rb
array = [1,2,3]

array2 = array

array2[0] = 124
```

このコードでは1,2,3を参照にしたリストオブジェクトに代入をしていることになります。
変数に直接代入をして参照先を変更するか
変数に入っているオブジェクトに代入をするか
この違いがあります。

### 追記

```ruby.rb
array = [1,2,3]

array2 = array

array2[0] = 124

puts array[0]
```

上記は参照型変数が代入されていると言いました。
もっとわかりやすく言うと通常の変数の代入とは全く違うということになります。

下記の2つは同じ意味になります。

```ruby.rb
array2[0] = 124

array2.[]=(0,124)
```

つまり**array2[0] = 124**は**array2.[]=(0,124)**を簡潔に表した糖衣構文(シンタックスシュガー)ということになります。

簡潔に表した時に代入と同じに見えますが、実際には違うという点が重要ですね

## まとめ

ここでまとめたことは当たり前すぎることだと思いますが、たまにおや？とおもうことがあるのでまとめておきました。
参考になることがあれば嬉しいです。
AWS  EC2インスタンスとは？

#  インスタンスとは？

インスタンスとはオンプレミス環境の上のサーバーに相当する。
インスタンスには様々なOSやタイプの選択が可能。

# インスタンスとして利用できるOS種類一覧

・Amazon Linux
・CentOS
・RedHat Enterprise Linux
・Ubuntu Server
・Fedora
・Debian
・Gentoo Linux
・FreeBSD
・Windows Server

# EBS-Backedインスタンス
OSを含むルートデバイス情報をEBSに格納したインスタンス。
AWSで**推奨**されている。
EC2インスタンス稼働中の変更はEBSに記録されるため、**インスタンスが停止しても変更内容は保持される。**

#インスタンス料金

インスタンスタイプに応じた時間毎料金に起動時間を乗じた従量課金制
例えばt2.microc($0.0152 /1 時間)を20日使用の場合

**$0.0152 /1 時間×  24時間 × 20日　＝　＄7.296**

となる。