OmniAICreator/Qiita-1.07M huggingface dataset:
ベイズの定理に入門してして検証時のデータセットのラベルの偏りを考察する

#0. 概要
ベイズとは、条件付確率に関する定理のことであり、ベイズ統計学やベイズ推定等を用いる上で基本的な定理となる。端的に説明すると、ある事象Aが発生した条件の下で、ある事象Bの確率を求めるということである。よくある例題だと「サイコロで3以上の目が出ていることは分かるが、それが5以上の確率は？」なんてのに利用される。「3以上の目が出ているということが分かっている」という部分が「事象Aが発生した条件」ということになる。「それが5以上の確率は？」という部分が「事象B」になる。

#1. 理論

事象Aが発生した条件の下、事象Bの確率を求める場合、以下の式となる。

``` math
P(B|A)=\dfrac {P(A|B)P(B)}{P(A)}\\
=\dfrac {P(A|B)P(B)}{\Sigma _{B}P(A|B)P(B)}
```

この時、各変数は以下の意味を持つ
<b>
$P(B|A)$: 事後確率という。 B given Aと読み、事象Aが発生した条件の下での事象Bの確率
$P(B)$: 事前確率という。事象Aが発生する前の、事象Bの確率
$P(A|B)$: 尤度(事象Bが発生した条件の下、事象Aが発生する確率)
$\dfrac {P(A|B)}{P(A)}$: 事象Bが発生した時に確率は$\dfrac {P(A|B)}{P(A)}$倍変動する
</b>

事前確率に対して、それが発生する頻度（尤度)を乗算することで事後確率を計算している。

すなわち、$P(A|B)$とは以下を示している。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/95636/2e2c6e9a-7a48-9158-10f3-27c273cb8725.png)

なお、$P(A)$は規格化定数のため、それを省いて以下のように表記する場合もある。

``` math
P(B|A)\propto P(A|B)P(B)
```

#2. 例題: テストデータの偏りと精度
・数字か文字かを識別する識別機の精度は98%
・テストデータに文字は5%しか含まれていない

このとき、ある1枚のテストデータを識別した結果「文字」だと識別された。
これが本当に文字である確率はどれくらいか？

``` math
P(B_1|A)=\dfrac {P(A|B_1)P(B_1)}{P(A|B_1)P(B_1) + P(A|B_2)P(B_2)}\\
=P(本当は文字|識別結果が文字)=\dfrac {P(識別結果が文字|本当は文字)P(本当は文字)}{P(識別結果が文字|本当は文字)P(本当は文字)+P(識別結果が文字|本当は数字)P(本当は数字)}\\
=\dfrac {識別機が文字を文字と正解できる確率×正解できる量(文字のデータセット量)}{識別機が文字を文字と正解できる確率×正解できる量(文字のデータセット量)+識別機が文字を数字と間違える確率×間違える量(数字のデータセット量)}\\
=\dfrac {正解度}{正解度+間違い度}\\
=\dfrac {0.98 * 0.05}{0.98*0.05 + 0.02*0.95}=\dfrac {0.049}{0.049 + 0.019}=0.72=72\%
```

この時、各パラメータは以下を意味する。
<b>
$P(B_1)＝P(本当は文字)$: テストデータに含まれている「文字」の確率(出現頻度)5%
$P(B_2)＝P(本当は数字)$: テストデータに含まれている「数字」の確率(出現頻度)95%
$P(A|B_1)=P(識別結果が文字|本当は文字)$: 本当は文字の画像を識別した結果、「文字」と識別された確率98%
$P(A|B_2)=P(識別結果が文字|本当は数字)$: 本当は文字の画像を識別した結果、「数字」と識別された確率2%
</b>


実際には98%の精度で「文字」だとは言えていないことが分かった。それが「文字」である確率は72%である。
与えられたデータの分布を加味しているともいえる。
<b>感覚的にはデータセットの「文字」と「数値」の比率が全く同じ場合は精度が98%になりそうである。</b>

テストデータが数字と文字50%:50%の場合

``` math
P(B|A)=\dfrac {0.98 * 0.5}{0.98*0.5 + 0.02*0.5}=\dfrac {0.049}{0.049 + 0.01}=0.98=98\%
```

このように確認できた。

<b>検証データの比率は全て同じにしましょう。</b>
was deprecated in iOS 10.0: Use UserNotifications Framework's UNNotificationSettings

'####' was deprecated in iOS 10.0: Use UserNotifications Framework's UNNotificationSettings

表題の変更について

##Swift3 Xcode10 以前

~~~Swift
UIUserNotificationSettings(types: [.alert, .badge, .sound], categories: nil)
~~~
↓↓↓

##Swift3 Xcode10 以降 

~~~Swift
if #available(iOS 10.0, *) {
            let center = UNUserNotificationCenter.current()
            center.requestAuthorization(options: [.badge, .sound, .alert]) { (granted, error) in
                if error != nil {
                    // エラー
                    return
                }

                if granted {
                    // 通知許可された
                } else {
                    // 通知拒否
                }
            }
        } else {
            let settings = UIUserNotificationSettings(types: [.badge, .sound, .alert], categories: nil)
            UIApplication.shared.registerUserNotificationSettings(settings)
        }
~~~


---


## 関連記事

【About】(http://qiita.com/sunstripe) - サンストライプ

---

## 制作チーム：サンストライプ

[![sunstripe_logo.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80600/322f2d60-f19d-af9e-2b6f-7290ca546848.png)](http://sunstripe.main.jp/)
http://sunstripe.main.jp/

(月１WEBコンテンツをリリースして便利な世の中を作っていくぞ！！ボランティアプログラマー/デザイナー/イラストレーター/その他クリエイター声優募集中！!)

### 地域情報 THEメディア
THE メディア 地域活性化をテーマに様々なリリース情報も含め、記事をお届けしてます！！
https://the.themedia.jp/

### ゼロからはじめる演劇ワークショップ
多様化の時代に向けて他者理解を鍛える

https://workshop.themedia.jp/

### プログラミングワークショップ・ウェブ塾の開講！！！
様々なテーマでプログラミングに囚われずに取り組んでいきます。
詳しくはこちら　↓　↓　↓　↓　↓　↓　↓　↓
[プログラミングサロン 月１だけのプログラミング学習塾](https://workshop.themedia.jp/posts/7057553?fbclid=IwAR32CfRQ7RvDOhvuogoSwqxDLMOU7Jvuzljlnx-TMc27qBPX1BnWsfLcBR8
)

### 協力応援 / 支援者の集い
## チーム：サンストライプ
#### プログラミングラボ
https://twitter.com/sunstripe2011

一緒にポートフォリオを作りませんか？現場の体験やそれぞれの立場から年齢関係なく作品を作りたい方々と一緒にチームを作って、作品を作っています。現場に行きたい人には、職場紹介や職場の体験や悩み相談なども受けております。
様々な職種からプログラミングの知識を得たい、デザインの知識を得たい、データーベースの知識を得たいという人が集まっております。
週１のミーティングにそれぞれの近況と作業報告して、たまにリモート飲み会などをしております！！

興味がある方は、DMに話しかけてみてください。

## トラストヒューマン
http://trusthuman.co.jp/
私たちは何よりも信頼､人と考えてます｡

｢コンサルティング｣と｢クリエイティブ｣の両角度から｢人材戦略パートナー｣としてトータル的にサポートします！！

キャリア教育事業
広域学習支援プラットフォーム『のびのび日和』
https://slc-lab.amebaownd.com/

#スポンサー募集
CameraXのコードサンプルをエミュレータで実行したら落ちた

# はじめに
先日Jetpackに追加されたCameraXの[公式コードサンプル](https://github.com/android/camera/tree/master/CameraXBasic)を試してみようと
実行したところ、実機では動いたがエミュレータでは強制終了してしまった。
結論から言うとちょっとした対応でエミュレータでも起動できるようになった。
大したことはしてなくてぶっちゃけ対処療法だけど、まだ情報がそんなに出回ってないと思うので一応まとめておく。
そもそもCameraXってなんぞやって人は[こちら](https://developer.android.com/jetpack/androidx/releases/camerax)をどうぞ。

# やること
CameraFragmentのL301で行っているbindToLifecycleの引数からimageAnalyzerを消すだけ。

```kotlin:CameraFragment.kt
        CameraX.bindToLifecycle(
                this, preview, imageCapture /*, imageAnalyzer*/)
```
当然消しちゃったのでAnalyze系のことは出来ない。
もしかしたら何かうまいこと設定したら行けるのかもしれないけどそこまで深く見てないので不明。
実機では消さなくても動くので
# 結論
カメラだし実機使いなさいってことなのかなって思った。
Androidの鬼門でお馴染みカメラ周りが簡単に書けるようになるっぽさは感じたので今後に期待したい。
Angularでinput type="date"を使うべきではない！？

Angularでのシステム開発を行っているが、テスト中に`<input type="date">`に関する意味不明な不具合に遭遇したためメモ。
※この時のAngularバージョンは7.1.3

# 現象
通常、input type="date"にフォーカスした場合は半角入力となるが、以下のような入力フォームで、

```index.html
<form [formGroup]="formGroup">
    <input type="text" formControlName="name">
    <input type="email" formControlName="email">
    <input type="date" formControlName="date">
    ・・・
</form>
```
```index.component.ts
formGroup = new FormGroup({
    'name': new FormControl('', [Validators.required]),
    'email': new FormControl('', [Validators.required]),
    'date': new FormControl('', [Validators.required]),
});
```
①nameを全角入力
②tabでemailに切り替え（勝手に半角入力に切り替わる）
③メールアドレス入力
③tabでdateに切り替え（勝手に全角入力に切り替わる）
④全角のまま入力
（Chromeにて動作確認）

という操作をすると、dateのFormControlに値が設定されなくなるという現象が発生する。
半角に切り替えて再度dateを入力しても値は設定されず、常に必須チェックに引っかかってしまっていた。
  
※単純にtype="date"に全角入力すると起こるっぽい

# 原因

input type="date"の項目に全角で入力すると、フォーカスが外れてしまうらしいのでそこら辺が原因だとは思うが、なぜ半角に切り替えた後もFormControlに値が設定されなくなるのかは不明。。。

この辺の知見がある方がいたらぜひ教えていただきたい。。。

# 回避策
今回はngx-bootstrapのDatePickerを使い、type="date"を使わないことで回避することにした。
https://valor-software.com/ngx-bootstrap/#/datepicker

そもそも、デフォルトのtype="date"だとブラウザによってUIが変わるのが気持ち悪かったので、ちょうど良かったかも(笑)

# 参考
[\<input type="time">で全角入力するとフォーカスが外れてしまう](https://teratail.com/questions/126638)
AWS CloudFrontの概要

# 概要
- AWS CloudFrontについて説明していきます。
- 「CloudFrontってなんだろう？？」「CDN(Content Delivery Network)ってなんだろう？？」という人向けに記載していこうと思います。
- 各IT用語もなるべく噛み砕いて記載していこうと思います。

# CDNとは
- 静的コンテンツをキャッシュして、オリジンサーバの負荷を軽減することができるもの。
    - コンテンツ = リソースのこと（例：画像、動画ファイル、pdfファイル、等々）。
    - 静的 = ユーザからサーバへのリクエストに対して、レスポンス内容が変化しないもの。
    - キャッシュ = 一時的にリソース/データを保存しておくこと。
    - オリジンサーバ = キャッシュの元ファイルが格納されている場所

- CDNの何が便利なの？？ 使い道は？？
    - 例えば、サーバに動画ファイルは格納されていて、複数のクライアントからその動画へアクセスがあった場合、アクセスリクエストがあるたびにサーバが応答するのはサーバに全ての負荷がかかる。
    - 上記の負荷軽減のため、各地に配置してあるキャッシュサーバにコンテンツをキャッシュすることによって、オリジンサーバの負荷を軽減することができる。
![CDNを使わない場合.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/413372/ddc4e1bd-8b69-c2b9-ce85-ae70e8a99367.png)
![CDNを使った場合.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/413372/b3ea26f7-c339-70c5-6268-98883b9678a5.png)

# CloudFrontとは
- AWSが提供しているCDNサービス [AWS公式URL](https://aws.amazon.com/jp/cloudfront/)
- 世界中の至る所にCloudFrontのキャッシュサーバが配置されており、ユーザは一番近いキャッシュサーバに自動的にアクセスするようになっています。
- CloudFrontの料金は、
```インターネットへ出力されたデータ量(GB 単位) × インターネットへ出力されたHTTPリクエスト数(1 万件単位)``` [Amazon CloudFront の料金URL](https://aws.amazon.com/jp/cloudfront/pricing/?nc=sn&loc=3)
    - AWS EC2を使用する場合、```インターネットへ出力されるたデータ量(GB 単位)```分は、CloudFrontでは発生しない。<br;>（AWSサービスは、基本的にAWS範囲からインターネットに出力されたときに料金が発生する。）<br;>つまり、CloudFrontの使用で発生する料金は、```インターネットへ出力されたHTTPリクエスト数(1 万件単位)```のみとなる。
    - 例えば、東京リージョンで1ヶ月で600万HTTPSリクエストがある場合<br;>```1万件リクエストあたり = 0.0120USD```<br;>となり、<br;>```月間600万PV / 1 万件 = 600```<br;>```600 * 0.0120 = 7.2USD```<br;>となります。（HTTPリクエストの場合、0.0090 USDとなるので、もっと安くなります。）<br;>上記の条件を5/11時点で日本円に換算すると、1ヶ月で約792円の支払いになります。
    - 上記のように、低レイテンシーかつ低価格を実現することができるAWSサービスなので、1度使ってみる価値はあると思います。
【一日目】Unityでモブプログラミング[B03_PostBird]

# 取り組み概要
2019年4月20日に行われた勉強会にて、Unityでモブプログラミングをやってみました。この日は3チームに分かれて各チームそれぞれがミニゲームを完成させました。
そのチームの１つである［B03_PostBird］の記録です。ちなみにこのチームは初心者を集めたチームとなり、操作方法を真似てもらいながらミニゲームを作ることになりました。
そのため実際にはモブプログラミングでなくなったため、モブプログラミングを期待されている方には申し訳ありません。ちなみに他２チームはしっかりとモブプログラミングをやり切りました。そちらの記事については後ほど投稿します。

# 開発を始める前
初心者だけを集めてUnityに慣れてもらうカンジにしました。できれば作りたいモノが理想だと思うので作成したいアプリのイメージを挙げてもらいました。いろいろ出てきたイメージをまとめると以下のカンジに。

### 皆さんに考えてもらったイメージ
- Flappy Birdのようなピョンピョン跳ねる
- どんどん上に飛び上がってクリアする
- 飛び上がる途中に敵がジャマをする
 
# より具体的なイメージに
考えてもらったイメージを少し具体的にしてみました。

- 鳥を主人公にして手紙を届けることをクリア条件にする
- 空の上にポストがあり、そこまで辿りついたらクリア
- 画面をタップしたらピョンピョン飛び上がる（Flappy Birdに準拠）
- 飛び上がるまでの間に左右から矢が飛んできて当たったらゲームオーバー
- クリアすると一目でわかるように演出を加える

# 実際に作ったアプリ
### タイトル画面
UIとかまで手が回らなかったので最低限。タップするとプレイ画面に遷移。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412322/64caa11b-8e8e-52a6-555f-db71cf560489.png" width=50%>

### プレイ画面
ポストに到達してクリアあるいは矢に当たって失敗すると結果画面に遷移します。プレイの結果は結果画面に受け渡されます。
画面をタップするとピョンピョンと上に跳ねて行きます。無事にポストまで到達するとクリア演出が。ハートはクルクルと回転します。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412322/3eb5f37a-e746-6e10-04b3-4c4e9d298a8f.gif" width=50%>

### 結果画面

##### クリア画面
クリアした場合の画面。こちらもハートがクルクルしますが以下は静止画です。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412322/b457b4e4-c0dd-19e3-3a98-6c3ca0a31722.png" width=50%>

##### 失敗画面
矢に当たって失敗したときの画面。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412322/4f4f678e-d767-4290-b5b7-cdf80b279887.png" width=50%>

#振り返り
モブプログラミングとは違ってますが以下のような振り返りになります。

- 初心者でも上手く作れました
- 少し調子に乗って作り過ぎた
- 他チームの様子を見るのが遅くなったのでサポートするのも遅くなってしまった
- つまり、もうちょっと時間に余裕を持たせよう

作成したモノはGitLabにソースか、他のストレージサービスでパッケージとしてエクスポートしたモノをアップロードしようかなとおもってます。
matplotlibの日本語文字化け解決

偉大な先駆者さまの手順（下記のリンク）から、色々試行錯誤して解決しました。
やることは先駆者さまのページに書かれている通りで、一部悩んだところなどを備忘録として書き留めておきます。

https://qiita.com/ldap2017/items/f014f1c22de269012273
https://qiita.com/MuAuan/items/1c1c2ef12a903c77217b
https://qiita.com/f0o0o/items/c2f74ac1d27e48d0fed1

# 解決するためにやること（概要）

1 日本語用fontをダウンロード
2 matplotlibの設定ファイルのfontの指定変更
3 （重要!!）キャッシュ削除

## 1. 日本語用fontをダウンロード
フォントのダウンロードページから明朝体かゴシック体好きな方のフォントをダウンロードする。
（作業時は両フォントをダウンロードした。）

https://ipafont.ipa.go.jp/node193#jp 

## 2. matplotlibの設定ファイルのfontの指定変更
matplotlibの設定ファイル（matplotlibrc）に下記を追加する

```
font.family : IPAexGothic
```

## 3. （重要!!）キャッシュ削除
2.の設定ファイルを変更するだけでは、`UserWarning: findfont: Font family ['IPAexGothic'] not found. Falling back to DejaVu Sans.`　とフォントが見つからないというエラーメッセージが出る。

原因はキャッシュファイルなので、キャッシュファイルfontlist-v300.jsonを削除する。

```
$ find . -type f -name fontlist-v300.json
./.matplotlib/fontlist-v300.json

$ rm ./.matplotlib/fontlist-v300.json
```

再度、試すと日本語を表示できた。

おわり
active_hash[gem]でデータの入ったテーブル作成

# active_hashとは
都道府県データのように今後増えたり減ったりする可能性が低いデータのテーブルは、active_hashでつくるほうがいい。
 
active_hashをつかうと、modelのファイルに適切な記述をすることによって、テーブルをつくることができる。ApplicationRecord（のようなもの）を継承するので、リレーションもOK。

# 都道府県テーブルをつくってみよう

以下、都道府県テーブルをつくる流れです。

### 1. gemをインストール
```:Gemfile
gem 'active_hash'
```
```:ターミナル
$　bundle install
```

### 2.prefecture（都道府県）モデルを作成
こちらはファイルから作ります。

```ruby:app/models/country.rb
class Prefecture < ActiveHash::Base
  self.data = [
      {id: 1, name: '北海道'}, {id: 2, name: '青森県'}, {id: 3, name: '岩手県'},
      {id: 4, name: '宮城県'}, {id: 5, name: '秋田県'}, {id: 6, name: '山形県'},
      {id: 7, name: '福島県'}, {id: 8, name: '茨城県'}, {id: 9, name: '栃木県'},
      {id: 10, name: '群馬県'}, {id: 11, name: '埼玉県'}, {id: 12, name: '千葉県'},
      {id: 13, name: '東京都'}, {id: 14, name: '神奈川県'}, {id: 15, name: '新潟県'},
      {id: 16, name: '富山県'}, {id: 17, name: '石川県'}, {id: 18, name: '福井県'},
      {id: 19, name: '山梨県'}, {id: 20, name: '長野県'}, {id: 21, name: '岐阜県'},
      {id: 22, name: '静岡県'}, {id: 23, name: '愛知県'}, {id: 24, name: '三重県'},
      {id: 25, name: '滋賀県'}, {id: 26, name: '京都府'}, {id: 27, name: '大阪府'},
      {id: 28, name: '兵庫県'}, {id: 29, name: '奈良県'}, {id: 30, name: '和歌山県'},
      {id: 31, name: '鳥取県'}, {id: 32, name: '島根県'}, {id: 33, name: '岡山県'},
      {id: 34, name: '広島県'}, {id: 35, name: '山口県'}, {id: 36, name: '徳島県'},
      {id: 37, name: '香川県'}, {id: 38, name: '愛媛県'}, {id: 39, name: '高知県'},
      {id: 40, name: '福岡県'}, {id: 41, name: '佐賀県'}, {id: 42, name: '長崎県'},
      {id: 43, name: '熊本県'}, {id: 44, name: '大分県'}, {id: 45, name: '宮崎県'},
      {id: 46, name: '鹿児島県'}, {id: 47, name: '沖縄県'}
  ]
end
```

各データをハッシュで配列に格納します。

PrefectureモデルはActiveHash::Baseを継承させてください。
これによりApplicationRecord（ActiveRecord）のメソッドが使えるようになります。

```:ターミナル
[2] pry(main)> Prefecture.find(1)
=> #<Prefecture:0x007f838b2fad30 @attributes={:id=>1, :name=>"北海道"}>
```

ひとまずテーブルは完成です。

# 関連するテーブルに紐づける

今回はproductsテーブルとアソシエーションを組みます。

productsテーブルは以下の通りです。

|id|name|prefecture_id|
|:--|:--|:--|

```ruby:app/model/product.rb
class Product < ApplicationRecord
  extend ActiveHash::Associations::ActiveRecordExtensions

belongs_to_active_hash :prefecture

end
```
extend ActiveHash::Associations::ActiveRecordExtensions
belongs_to_active_hash :prefecture
以上、ふたつが追加されています。

これで完了です。
Prefectureモデルのファイルには特にアソシエーションを明示するものはありません。

アソシエーションをターミナルで確認します。

```:ターミナル
pry(main)> product = Product.find(10)

pry(main)> product.prefecture
=> #<Prefecture:0x007f838b2fad30 @attributes={:id=>1, :name=>"北海道"}>
```

紐づくデータをとれました。

# まとめ
データベースの数を増やさないためにも、今後増えたり減ったりする見込みのないデータのテーブルはactive_hashをつかってつくった方が良さそうです。
5/10 勉強記録　Ruby　クラスメソッド

**クラスメソッド**
クラスから直接呼ぶことができるメソッド

```rb

class Car
 @@count = 0
 def initialize(name)
  @name = name
  @@count += 1
 end
 
 def hello
 puts "Hello, I am #{@name}. #{@@count} instance(s)"
 end
 
 def self.info #クラスメソッドを書くときは「self」をつける
  puts"#{@@count} instance(s)."
 end
 
end

Car.info
```
上記を実行すると、
`0 instanve(s).`
と出力される。
これは、インスタンスを生成せず、直接infoメソッドを呼び出しているため。

```rb
class Car
 @@count = 0
 def initialize(name)
  @name = name
  @@count += 1
 end
 
 def hello
 puts "Hello, I am #{@name}. #{@@count} instance(s)"
 end
 
 def self.info
  puts"#{@@count} instance(s)."
 end
 
end

kitt = Car.new('Kitt')
# kitt.hello
Car.info

karr = Car.new('Karr')
# karr.hello
Car.info


hogehoge = Car.new('Hogehoge')
# hogehoge.hello
Car.info
```
上記を実行すると、
`
1 instance(s).
2 instance(s).
3 instance(s).`
と出力される。
インスタンスを生成してからinfoメソッドを呼び出しているからだ。

クラスから直接呼ぶことでどのようなメリットがあるか良くわからないが、多分便利な機能なんだろうな。

---
`self`のことを少し調べてみたら、クラス内部で書かれる場合、インスタンス変数の参照に利用されるらしい。

```rb
class Car
def initialize(name)
    # self.nameに引数name を代入する
    self.name = name
  end
  def my_name
    p "私の名前は#{self.name}です。"
  end
end
```

```
class Car
 def initialize(name)
  @name = name
 end
 def my_name
  p "私の名前は#{@name}です。"
 end
end
```
とは何が違うんだろう？

---
おまけ

**クラスと定数**

```rb
class Car
 REGION = 'USA'
 @@count = 0
 def initialize(name)
  @name = name
  @@count += 1
 end
 
 def hello
 puts "Hello, I am #{@name}. #{@@count} instance(s)"
 end
 
 def self.info
  puts"#{@@count} instance(s). Region: #{REGION}"
 end
 
end

kitt = Car.new('Kitt')
# kitt.hello
Car.info

karr = Car.new('Karr')
# karr.hello
Car.info


hogehoge = Car.new('Hogehoge')
# hogehoge.hello
Car.info
```
を実行すると、
`1 instance(s). Region: USA
2 instance(s). Region: USA
3 instance(s). Region: USA`
が出力される。

定数は大文字。

```rb
class Car
 REGION = 'USA'
 @@count = 0
 def initialize(name)
  @name = name
  @@count += 1
 end
 
 def hello
 puts "Hello, I am #{@name}. #{@@count} instance(s)"
 end
 
 def self.info
  puts"#{@@count} instance(s). Region: #{REGION}"
 end
 
end

kitt = Car.new('Kitt')
# kitt.hello
Car.info

karr = Car.new('Karr')
# karr.hello
Car.info


hogehoge = Car.new('Hogehoge')
# hogehoge.hello
Car.info

puts Car::REGION
```
を実行すると、
`
1 instance(s). Region: USA
2 instance(s). Region: USA
3 instance(s). Region: USA
USA
`
と出力される。
定数を出力したい場合、　**「クラス名::定数名」** と書く。
AWS workspacesを使用して、開発担当者からの情報漏洩を防止したガッチガチの開発環境を作る（序章）

#はじめに
ある開発案件にて定められたセキュリティ要件をクリアするために、情報漏洩を防止する目的でAWSのworkspacesを使用して開発担当者のオペレーション可能な範囲を限定した環境を作成した。
その作業工程とポイントをまとめます。

#達成要件
今回達成すべき要件としては以下5点であった。
1. workspacesの環境はウィルス対策ソフト（ウィルスバスター）が備えられていること（Windows10相当のOS環境を前提)
2. workspacesからのインターネットへのアクセスを必要最低限のみ許可する
3. workspacesからインターネットアクセスしたログを一定期間保存する
4. workspacesとローカルPC間について、コピーペスト等を ローカルPC→workspacesへの一方通行とする（＝送り込めるが持ってこれない）
5. workspacesへ接続できる環境(PC)を限定する

#各要件の達成方法の想定
>1 . workspacesの環境はウィルス対策ソフト（ウィルスバスター）が備えられていること（Windows10相当のOS環境を前提)

これは単純で、ウイルスバスターが同梱されているworkspacesを生成すれば良い。
>2 . workspacesからのインターネットへのアクセスを必要最低限のみ許可する

これはVPCからインターネットへのアクセス経路をプロキシ経由に限定し、プロキシのホワイトリストで管理する。

>3 . workspacesからインターネットアクセスしたログを一定期間保存する

上記2の対応で使用するプロキシのログをS3等に保存することで対応する。

>4 . workspacesとローカルPC間について、コピーペスト等を ローカルPC→workspacesへの一方通行とする（＝送り込めるが持ってこれない）

workspacesにはそんな機能は無い。
調べた結果、ActiveDirectory管理でグループポリシーを使用すれば対応できる模様。
仕方がないので、workspacesのディレクトリでSimpleAD管理をし、EC2でAD管理用のインスタンスを立ち上げることとする。

>5 . workspacesへ接続できる環境(PC)を限定する

これはworkspacesのアクセス制御で証明書を使用することで対応できる。

#システム構成図
各要件の達成方法をベースにシステム構成図をまとめた。
(一部表現が正しくないかも）
![システム構成.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405875/82b8ad95-34d7-160c-fccf-eea025310946.jpeg)

外部とのネットワークアクセス制御はセキュリティグループおよびVPCのルートテーブルで解決する。

具体的な手順や設定内容は次回の記事から記載します。
C#でREST APIにアクセスする（JSONでparameterをやりとりしたい）



# 内容
rest if 通信、rest if アクセス
たまにしかC#を使わないので自分のためのメモ

C#でrest fullなAPIにアクセスしようとするとなかなかめんどくさい。

phpやpythonでjsonを使うことに慣れていると、いちいちクラス作ったりとてもめんどくさい。
理想はクラスを経由してaccessするのがいいんだけど・・やっぱりめんどくさい。
クラスを前提に作らなきゃいけないＣ＃ではphp,pythonで作られたサービスの癖についていくのがキツイです。
キーの存在確認とかできないとか。。Ｃ＃のがお行儀のよいＪＳＯＮばかりでね。:joy:


# 環境

パッケージマネージャで以下を実行

```
Install-Package DynamicJson -Version 1.2.0
Install-Package Newtonsoft.Json -Version 12.0.2
Install-Package RestSharp
```

# コード

Elasticsearchにアクセスするコード
指定時刻を超えるdocumentを持ってくるサンプル

``` C#
using Newtonsoft.Json;
using RestSharp;
using Codeplex.Data;


/////////////////////////

RestClient client = new RestClient("http://ここにURL.co.jp");
//client.Authenticator = new HttpBasicAuthenticator("username", "password"); 認証が必要な場合

RestRequest request = new RestRequest("/ここにresourceのURL/",Method.POST);

//リクエストJSONは無名で作った方が楽
object x = new { query = new { range = new {
                   occurred_at = new { 
                     gt = "2017-08-16 16:18:00+0900", lte = "now", 
                     format = "yyyy-MM-dd HH:mm:ssZ" } } } };

request.AddJsonBody(x);
request.RequestFormat = DataFormat.Json;

var response = client.Execute(request);

//ここにドキュメントを処理するコード
var jsonObj = DynamicJson.Parse(response.Content);
var total=jsonObj.hits.total;

foreach (var hit in jsonObj.hits.hits)
{

    var at=hit._source.occurred_at;

}


```


文字列でアクセスする
添え字でよかったんか・・

``` C#
dynamic djson=DynamicJson.Parse(cjson)
string name=djson["name"]
```


キー存在の確認

``` c#

        private bool contains(dynamic value, string index)
        {
            foreach (string key in value.GetDynamicMemberNames())
            {
                if (index.Equals(key))
                {
                    return true;
                }
            }
            return false;
        }

```

キー存在の確認がIEnumerableではできないからGetDynamicMemberNames()で反復して検索するしかなった。
もっといい方法があればだれか教えてください。
（ICollectionに食わせればいいんだろうなぁ～）
追記：IsDefinedが使えることが分かった
rb-inotifyを使う際の注意点

## ▼結論

inotifyはLinux特有のAPIであるため、macOS上ではrb-inotifyは動作せず、Railsを立ち上げようとするとエラーとなる。
エラー解消方法としてはGemfileからrb-inotifyを削除してbundle installを実行する。

ただ、これって回避策であって解決策じゃないんだよなぁ。。。

## ▼エラーメッセージ

rb-inotifyが入った状態でrailsサーバーを立ち上げると以下のようなエラーメッセージが表示される。

```
Function 'inotify_init' not found in [libc.dylib] (FFI::NotFoundError)
```

### ●FFIって何？

> Foreign function interface (FFI)とは、あるプログラミング言語から他のプログラミング言語で定義された関数などを利用するための機構。主に高水準言語からC/C++などの関数やメソッドを呼び出し、OS固有の機能などを利用するために使用されることが多い

[Foreign function interface](https://ja.wikipedia.org/wiki/Foreign_function_interface)

どうやらRubyがLinuxのAPIであるinotifyを呼び出そうとしており、inorifyがLinux特有のAPIとしてCなどの言語で定義されているため、LinuxであればinorifyのFFIがいるはずだが、macOSにはいないためエラーになっているらしい。

### ●rb-inotifyって何？

> A thorough inotify wrapper for Ruby using FFI.

[guard/rb-inotify](https://github.com/guard/rb-inotify)

Rubyでinotifyを使うためのgemで、FFIを使っていると説明されている。

### ●inotifyって何？

> Linux2.6から追加されたinotifyというAPIは、ファイルやディレクトリーでオープン、クローズ、移動/名前変更、削除、作成、属性の変更などといったファイルシステムイベントを監視することができます。

[inotify-toolsでファイルやディレクトリを監視する](https://qiita.com/stc1988/items/464410382f8425681c20)
多対多　更新時にバリデーションに引っかかりたい



多対多のアソシエーションになっています。
real_shopテーブル----real_shop_expert_collectionテーブル（中間）----expert_collectionテーブル

作成時は↓のバリデーションに引っかかったのに更新時は引っかからなかったのはなぜだろうか。


```expert_collection.rb
    enum is_shop: { limited: 0 , altogether: 1 }

    with_options if: :limited? do
      validates :real_shop_ids, :presence => {:message => 'を選択して下さい'}
    end
#is_shopというカラムが　"limited"だったらアソシエーション先のカラムである :real_shop_ids が必ず必要だよっていうバリデーション
```

##作成

```expert_collections_controller.rb

  def new
    @expert_collection = ExpertCollection.new
  end

  def create
    @expert_collection = ExpertCollection.new(params[:expert_collection])
    @expert_collection.site_id = current_site.id
    @expert_collection.real_shops = RealShop.find(params[:shop_ids]) if params[:shop_ids].present?
    if @expert_collection.save　　　#←saveの時に上記で書いたバリデーションに引っかかってたらエラーメッセージが表示される
      redirect_to  ar_admin_expert_collections_path, :notice => "エキスパートコレクションを作成しました。"
    else
      render :new
    end
  end

```



##更新


```expert_collections_controller.rb
#旧コード

   def update
     @expert_collection = ExpertCollection.site(current_site.id).find(params[:id])
     @expert_collection.site_id = current_site.id
======
     @expert_collection.real_shops = RealShop.find(params[:shop_ids]) if params[:shop_ids].present?
======
     @expert_collection.attributes = params[:expert_collection]
     if @expert_collection.save
       redirect_to ar_admin_expert_collections_path, notice: "エキスパートコレクションを更新しました。"
    else
      render :edit
    end
  end

```

```expert_collections_controller.rb
#新コード
   def update
     @expert_collection = ExpertCollection.site(current_site.id).find(params[:id])
     @expert_collection.site_id = current_site.id
=================
    if  params[:shop_ids].present?
     @expert_collection.real_shops = RealShop.find(params[:shop_ids])
    else
      @expert_collection.real_shops.destroy_all
    end
=================
     @expert_collection.attributes = params[:expert_collection]
     if @expert_collection.save
       redirect_to ar_admin_expert_collections_path, notice: "エキスパートコレクションを更新しました。"
    else
      render :edit
    end
  end
```



========で囲っている部分が変更したコードです。

##原因
原因は、　`params[:expert_collection]`に`real_shop_ids`の値が渡ってないので更新されず、作成の時に登録された`real_shop_ids`の値がそのまま入っちゃっていることです。

なので`destroy_all`というメソッドを使って配列の中身を空にします。


```console
[14] pry(#<ArAdmin::ExpertCollectionsController>)> @expert_collection.real_shop_ids
=> [1, 2, 3, 4, 5]　　

#配列に５個要素が入ってるのを要素が選択されなかった場合にdestroy_allメソッドで消す
[15] pry(#<ArAdmin::ExpertCollectionsController>)> @expert_collection.real_shop_expert_collections.destroy_all
=> [] 
#空配列ができる！ので中身必要だよ！っていうバリデーションにひっかる
```

ExpertCollectionテーブルの中から選択されたレコードに`アソシエーション先のモデル名 _ids`と指令を出すことでアソシエーションされてる`real_shop`のidが配列で返される
(`@expert_collection.real_shops`だと、レコードの内容が全て表示される)


###参考
https://qiita.com/kamelo151515/items/0fa7fb15a1d2c1e44db2
Ubuntuにプロキシの設定をする

#1. はじめに
- 以下は個々の環境に合わせて読み替えてください

 - server : プロキシサーバーのアドレス
 - port : プロキシサーバーのポート
 - user : 認証用のユーザー名
 - password : 認証用のパスワード
 - url : プロキシを通さないでアクセスするurl(ローカルのサーバーなど)



#2. 一時的に設定したい場合
###2-1. ~/にproxy.shを追加

```bash
cd ~
nano proxy.sh
```
- 認証無しの場合


```bash
#! /bin/bash
proxy="server:port"
export http_proxy="http://$proxy"
export https_proxy=$http_proxy
export ftp_proxy=$http_proxy
export no_proxy="127.0.0.1, localhost, url"
``` 

- 認証ありの場合

```bash
#! /bin/bash
proxy="user:password@server:port"
export http_proxy="http://$proxy"
export https_proxy=$http_proxy
export ftp_proxy=$http_proxy
export no_proxy="127.0.0.1, localhost, url"
```
###2-2. /etc/sudoersを編集 
これを忘れると`sudo apt update`などをするときに`sudo -E apt update`にしないとプロキシの設定が反映されないので注意

```bash
sudo visudo
```
以下を`Defaults env_reset`のあとに追記

```bash
Defaults env_keep="http_proxy"
Defaults env_keep+="https_proxy"
Defaults env_keep+="ftp_proxy"
Defaults env_keep+="no_proxy"
```

###2-3. 実行権限を与える
```bash
chmod +x proxy.sh
```

###2-4. 実行
新しいターミナルを開くたびに実行しないと設定が反映されないので注意

```bash
source proxy.sh
```

#3. 一時的ではない場合
###3-1. /etc/profile.d/以下にproxy.shを追加
認証の有無で記述する内容が変わるので注意

```bash
sudo nano /etc/profile.d/proxy.sh
```
- 認証無しの場合

```bash
#! /bin/bash
proxy="server:port"
export http_proxy="http://$proxy"
export https_proxy=$http_proxy
export ftp_proxy=$http_proxy
export no_proxy="127.0.0.1, localhost, url"
``` 
- 認証ありの場合

```bash
#! /bin/bash
proxy="user:password@server:port"
export http_proxy="http://$proxy"
export https_proxy=$http_proxy
export ftp_proxy=$http_proxy
export no_proxy="127.0.0.1, localhost, url"
```

###3-2. 実行権限を与える
```bash
sudo chmod +x /etc/profile.d/proxy.sh
```

###3-3. /etc/sudoersを編集 
これを忘れると`sudo apt update`などをするときに`sudo -E apt update`にしないとプロキシの設定が反映されないので注意

```bash
sudo visudo
```
以下を`Defaults env_reset`のあとに追記

```bash
Defaults env_keep="http_proxy"
Defaults env_keep+="https_proxy"
Defaults env_keep+="ftp_proxy"
Defaults env_keep+="no_proxy"
```
###3-4. 再起動

```bash
reboot
```


## 2020/9/16 追記
以下のように`~/.bashrc`に追記することでターミナル起動時に特定のSSIDだった場合にプロキシを設定することができます。この場合でも`/etc/sudoers`の編集は必要です。

- SSID1, SSID2は設定したいSSIDに置き換えてください

```bash
ssid=`iwgetid -r`
targets=("SSID1" "SSID2")
proxy="server:port"
if [ $ssid ]; then
    for target in "${targets[@]}" ; do
        if [ $ssid = $target ]; then
            export http_proxy="http://$proxy"
            export https_proxy=$http_proxy
            export ftp_proxy=$http_proxy
            export no_proxy="127.0.0.1, localhost, url"
        fi
    done
fi
```

#4. おわりに
お疲れ様でした！
5/10 勉強記録　Ruby　クラス変数

**クラス変数＊＊
そのクラスの全てのインスタンスで共有される変数。
クラス自体に値を保持することができる変数。

```rb
class Car
 @@count = 0
 def initialize(name)
  @name = name
  @@count += 1
 end
 
 def hello
 puts "Hello, I am #{@name}. #{@@count} instance(s)"
 end
end

kitt = Car.new('Kitt')
kitt.hello

karr = Car.new('Karr')
karr.hello

hogehoge = Car.new('Hogehoge')
hogehoge.hello
```
`@@count`がクラス変数。
`@@count　+= 1`でインスタンスが作成された回数をカウントする。

 上記を実行すると、
`Hello, I am Kitt. 1 instance(s)
Hello, I am Karr. 2 instance(s)
Hello, I am Hogehoge. 3 instance(s)`
と出力される。



①

```rb
class Car
 @@count = 0
 def initialize(name)
  @name = name
  @@count += 1
 end
 
 def hello
 puts "Hello, I am #{@name}. #{@@count} instance(s)"
 end
end

kitt = Car.new('Kitt')
kitt.hello

karr = Car.new('Karr')
karr.hello
karr.hello

hogehoge = Car.new('Hogehoge')
hogehoge.hello```


```rb
class Car
 @@count = 0
 def initialize(name)
  @name = name
 end
 
 def hello
 @@count += 1
 puts "Hello, I am #{@name}. #{@@count} instance(s)"
 end
end

kitt = Car.new('Kitt')
kitt.hello

karr = Car.new('Karr')
karr.hello
karr.hello

hogehoge = Car.new('Hogehoge')
hogehoge.hello
```
上記を実行すると、
`Hello, I am Kitt. 1 instance(s)
Hello, I am Karr. 2 instance(s)
Hello, I am Karr. 2 instance(s)
Hello, I am Hogehoge. 3 instance(s)`



②

```rb
class Car
 @@count = 0
 def initialize(name)
  @name = name
 end
 
 def hello
 @@count += 1
 puts "Hello, I am #{@name}. #{@@count} instance(s)"
 end
end

kitt = Car.new('Kitt')
kitt.hello

karr = Car.new('Karr')
karr.hello
karr.hello

hogehoge = Car.new('Hogehoge')
hogehoge.hello
```
上記を実行すると、
`Hello, I am Kitt. 1 instance(s)
Hello, I am Karr. 2 instance(s)
Hello, I am Karr. 3 instance(s)
Hello, I am Hogehoge. 4 instance(s)`
と出力される。

①はinitializeメソッドのなかに`@@count += 1`があるので、インスタンスが作成された回数の数字がでる。
②はhelloメソッドのなかに`@@count += 1`があるので、helloメソッドが呼び出された回数の数字がでる。
【2019年5月】無理やり flutter web を動かしたメモ

# 本家サイトをあんまり見ないで適当にやってみた。

良い子はまねしちゃダメなパターンの Flutter の動かし方です。
FlutterやDartの一切入っていない環境に、Flutterを新規インストールしてみます。

# 対象環境

OS: Windows 10 Pro

# Flutter のインストール

以下のサイトからFlutter一式のzipをまずダウンロードしてきます。

- https://flutter.dev/docs/get-started/install/windows

適当なフォルダに解答します。"スペースはやめてね" とあるので案内に従って "C:\apps\flutter" に解凍いたしました。

続いて `C:\apps\flutter\flutter_console.bat` をダブルクリックで起動します。

よくわかりませんが、準備OKとのことです。(いや、全然OKじゃないけどね・・・)

# PATH の設定

以下の PATH を追加します。長いのでまず、flutterのインストールフォルダを `FLTR_HOME` とかにしてしまいます。

- FLTR_HOME = C:\apps\flutter

続いて以下の3か所をパスに追加します。

- %FLTR_HOME%\bin
- %FLTR_HOME%\bin\cache\dart-sdk\bin
- %FLTR_HOME%.pub-cache\bin

ついでに MINGW64 を使っている人はお好みで `MSYS2_PATH_TYPE=inherit` もつけちゃいましょう。

# doctor に怒られてみる。

コマンドプロンプトで以下のように診断ツールを起動します。

```
> flutter doctor
```

Android の開発環境がないと issue がいろいろ出てきますが、Webなのでガン無視でOKです。

Visual Studio のプラグインは表示されたURLコピペでインストールしておきましょう。

# 新規プロジェクトの作成

Visual Studio でコマンドパレット `shift+Ctrl+P` を開き、

```
Flutter: New Web Project
```

を実行します。適当なフォルダにプロジェクトを作成してください。
たぶん、エラーが出ます。(ぉ
エラーメッセージでどうもローカルに clone したリポジトリが見れないと騒いでいるので手動でやってみます。
VS Code のターミナルから、flutter_webをcloneします。

```
git clone --mirror https://github.com/flutter/flutter_web.git
```

# webdev のインストール

以下のコマンドでwebdevをインストールします。

```
flutter packages pub global activate webdev
```

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

続いて依存パッケージをインストールします。

```
flutter packages pub get
```

# 試しに webdev を叩いてみる。

以下のコマンドで webdev を叩いてみます。

```
webdev serve
webdev could not run for this project.
Could not find a file named "pubspec.yaml" in "C:\Users\xxxxx\AppData\Roaming\Pub\Cache\hosted\pub.dartlang.org\protobuf-0.13.11".
```

なんだか Protobuf がないと怒られましたね。。。
インストール方法は以下のページにありました。

- https://pub.dev/packages/protobuf#-installing-tab-

案内に従って pubspec.yaml に `protobuf-0.13.11` を追加します。

```yaml:pubspec.yaml
...
dependencies:
  flutter_web: any
  flutter_web_ui: any
  protobuf: ^0.13.11
...
```

そして再度、依存パッケージのインストールを行います。

```
flutter package pub get
```

# 再チャレンジ

今度はどうでしょう？

```
webdev serve
[INFO] Serving `web` on http://localhost:8080
[INFO] Running build completed, took 37.5s
[INFO] Caching finalized dependency graph completed, took 283ms
[INFO] Succeeded after 37.8s with 548 outputs (3169 actions)
```

動いたようです。
めちゃくちゃな手順でしたが動いてしまったのでメモしておきます。

引き続き `lib/main.dart` いじってみますか。

間もなくリモートでVS Codeが動かせるようになる([VSCode公式の機能で、リモートサーバにSSHして編集する【Insiders Preview】](https://qiita.com/suzuki_sh/items/245b9817536eba808842))]ということなのでローカル環境をまじめに作る気力もなくなってしまいました。
早くリモートで動かしたい～！
swagger(open api) をはじめる

## このページについて

Macとvscode に swagger の開発環境を構築し、api document を作るまでが書いてあります

## 背景

api仕様書を書くのにblueprintを使っていますが、他のも試してみたくなったからです(私が選定していないため)  

[agreed](https://github.com/recruit-tech/agreed)という定義を簡単にかけるやつ使ってみましたが
制約などの書き込みができなかったので採用を見送りました(必須制約入れられないの辛い)


## ゴール

こんなドキュメントが作れるようになります

![スクリーンショット 2019-05-10 14.09.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47896/2f203122-924f-57fa-6308-e67a05946c0b.png)



## 手順

### vscodeの設定

- [yaml extention](https://marketplace.visualstudio.com/items?itemName=redhat.vscode-yaml) のインストール
- 設定ファイルに追加記述

```json
"yaml.schemas": {
    "https://raw.githubusercontent.com/kogosoftwarellc/open-api/master/packages/openapi-schema-validator/resources/openapi-3.0.json": ["*swagger.yaml", "*swagger.yml"],
},
```

- swagger viewer のインストール
    - Shift + Alt + P でyamlに記述したdocのpreviewが可能になります


### 書き方

- [認証周り](https://swagger.io/docs/specification/authentication/bearer-authentication/)
- [レスポンスやschema定義など](https://qiita.com/rllllho/items/53a0023b32f4c0f8eabb)
- [query parameterなど](https://swagger.io/docs/specification/describing-parameters/#query-parameters)


### yamlの内容をhtmlにしたい

誰かに渡すときに必要ですよね

```
$ docker run -i yousan/swagger-yaml-to-html < your-swagger.yml > ./build/index.html
```

### swagger-codegenのインストール

**(クライアントなど必要であれば)**

```
$ brew cask install adoptopenjdk8 && \
brew instal swagger-codegen
```


## 参考

- [VSCodeでswagger 2.0のyamlドキュメントを快適に書きたい](https://qiita.com/k3nNy_51rcy/items/4ff27df02cad77de544a)
- [OpenAPI (Swagger) 超入門](https://qiita.com/teinen_qiita/items/e440ca7b1b52ec918f1b)
- [SwaggerのSpecのYAMLファイルをHTMLに変換する](https://qiita.com/yousan/items/185638e94a063ca24e00)
【GCP/AWS】インスタンスのシャットダウンし忘れを防ぐ

クラウド上のインスタンスで作業をする際、夜中に処理回すために手動でシャットダウンが出来ないorそもそもシャットダウンを忘れてしまうことが度々ある。
インスタンス稼働の無駄を防ぐ為に、**決まった時間にCPUが稼働していなければ自分を停止**させる。

# 環境
CentOS 7.6

# タイムゾーンの変更（UTC->JST）
```$ timedatectl set-timezone Asia/Tokyo```
このコマンドで一発で変更可能のよう

# 定期実行するジョブを指定
```$ crontab -e```

vimで編集する。

書き方の基本ルールはこう。
``` 分　時　日　月　曜日　実行コマンド ```

## 定時で強制停止

稼働の有無に関わらずシャットダウンする場合はcronをこう編集。
```0 0 * * * /usr/sbin/shutdown -h now```

## CPU稼働状況を見て停止

計算中はシャットダウンしたくない！とかなら、cronには以下を記載し、別にシェルスクリプトを用意する。
```0 0 * * * /PATH/shtdwn.sh```

gitのリンクは[こちら](https://github.com/Gri-Gra/instance_shutdown)

自分で作る場合は以下のコマンドで
```$ vi ./shtdwn.sh```

稼働率が一定以下ならインスタンスを停止する。閾値はよしなに。
（今回はひとまず10%に）

```shell:shtdwn.sh
#!/bin/bash

cpuused=`cat /proc/loadavg | cut -d ' ' -f 1`
thresh=0.10

LIMIT=`echo "$cpuused <= $thresh" | bc`

if [ $LIMIT -eq 1 ] ; then
  echo "インスタンス停止"
  sudo /usr/sbin/shutdown -h now
else
  echo "インスタンス稼働中"
fi
```

実行権限を設定
```$ chmod +x ./shtdwn.sh```

# 参考にさせていただいたページ
https://eng-entrance.com/linux-command-crontab
https://qiita.com/toshihirock/items/461da0f60f975f6acb10
VsCodeのおすすめ拡張機能 その1

# TL;DR
* VSCodeを入れ直す機会があったため、実際に使用している拡張機能やおすすめの拡張機能を列挙してみた
* js系は設定中なので未掲載
* いつかその2を書く予定

## おすすめ拡張機能一覧
### Auto Close Tag
HTML/XMLの終了タグを挿入してくれます。
(開始タグの > を入力したタイミングで終了タグが挿入されます。)
*https://marketplace.visualstudio.com/items?itemName=formulahendry.auto-close-tag*

### Auto Rename Tag
対になったHTML/XMLのタグ変更を反映してくれます。
開始・終了のどちらかを修正するだけで済むので、無駄手間が減ります。
*https://marketplace.visualstudio.com/items?itemName=formulahendry.auto-rename-tag*

### Bracket Pair Colorizer2
対になった括弧に対して自動的に色付けを行ってくれます。
もちろんデフォルトの色が気に入らなければ好みの色へ変更可能です。
(現在Beta版となっていますが、筆者環境では問題なく動いています。)
*https://marketplace.visualstudio.com/items?itemName=CoenraadS.bracket-pair-colorizer-2*

### Color Highlight
CSSのカラーコードに対して色付けをしてくれます。
色の表示方法は外枠・背景など様々な形で設定できます。
https://marketplace.visualstudio.com/items?itemName=naumovs.color-highlight

### Color Info
カラーコードにカーソルを合わせると、各種色情報をポップアップ表示してくれます。
(Color Highlightで色付けをした上で、詳細な情報が見たい場合はColor Infoを使用しています。)
![color_info.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/122221/c28e8ed9-204f-fdac-b5ae-9662af0827e0.png)
*https://marketplace.visualstudio.com/items?itemName=bierner.color-info*

### CSS Peek
HTML/CSSのClassとIDがどこで定義されているのか確認できます。
ファイル全体から検索するような手間をかけている人にはおすすめです。
*https://marketplace.visualstudio.com/items?itemName=pranaygp.vscode-css-peek*

### Image preview
CSS等で書かれた画像パスにカーソルを合わせると、その画像のプレビューを表示してくれます。
いちいち別タブで開く必要が無くなるのが嬉しいところ。
*https://marketplace.visualstudio.com/items?itemName=kisstkondoros.vscode-gutter-preview*

### indent-rainbow
インデントをレインボーに彩ってくれます。
![indent_rainbow.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/122221/d2230ed1-d565-21ed-6345-76b5c752f314.png)
*https://marketplace.visualstudio.com/items?itemName=oderwat.indent-rainbow*

### Japanese Word Handler
日本語の場合、デフォルトではかなり貧弱な単語移動を大分改善してくれます。
*https://marketplace.visualstudio.com/items?itemName=sgryjp.japanese-word-handler#review-details*

### Markdown All in One
Markdownで書きたい人はとりあえずインストールしましょう。
下手なMDエディタより強力な機能が追加されます。
*https://marketplace.visualstudio.com/items?itemName=yzhang.markdown-all-in-one*

### Paste JSON as Code
JSONに対して型を設定し、指定した言語に合わせた定義コードを生成してくれます。
*https://marketplace.visualstudio.com/items?itemName=quicktype.quicktype*

## テーマ
### Pop Theme
筆者おすすめのテーマ。その名の通りポップな色合いですが、比較的淡い色設定がされているため見やすいです。
*https://marketplace.visualstudio.com/items?itemName=ArtisanByteCrafter.poptheme*
![pop_dark_theme.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/122221/c4041eb1-d391-4ea3-ba17-aa6934ebf3f7.png)
Rubyのat_exitとParallel(マルチプロセス処理)でおかしなことを起こしてしまった話

# at_exitとは
Rubyには[`Kernel#at_exit`](https://docs.ruby-lang.org/ja/latest/method/Kernel/m/at_exit.html)というメソッドがあります。
これは、Rubyの処理の終了時に実行する処理を追加出来るようなメソッドで、使い方によっては非常に便利に使えるものです。
(よく調べてないですが結構色々なGemで使用されているらしいです)

# Parallelとは
Rubyにおいてマルチプロセス/スレッドの処理を簡単に使えるようにしてくれるGemです。
Rubyで並列処理を行いたい場合はよく使うと思います。

# 今回起きちゃった問題
`at_exit`とParallelによるマルチプロセス処理を同時に使ったことで、おかしな挙動が置きました。

具体的にはこんな感じ↓

```rb:test.rb
at_exit do
  puts "run at_exit!"
end

Parallel.each(1..4, in_processes: 4) do |num|
  sleep num
  puts "sleep done! #{num}"
end

```

このファイルを実行した結果が↓

```bash
$ ruby at_exit_and_multi_process_test.rb
sleep done! 1
run at_exit!
sleep done! 2
run at_exit!
sleep done! 3
run at_exit!
sleep done! 4
run at_exit!
run at_exit!
```

***`at_exit`が5回も走ってる！！:fearful:***

基本的に`at_exit`を使用する場合、処理の最後に1回だけ走って欲しいという感じの使い方をすると思うのですが、これだとよろしくないですね。

原因はまあなんとなく察しがつくと思います。
`at_exit`内の処理はrubyの処理の終了時にフックされるわけですが、その「rubyの処理の終了」が、各子プロセスで発生してしまい、親プロセスの状態をforkしている子プロセスでも同じ`at_exit`の処理が走ってしまったという話ですね。(多分)
さらに親プロセスの終了分まで含めて5回も走ってしまったわけです。

ちなみにマルチスレッド処理では問題なく動作し、結果は下記のようになります↓


```bash
$ ruby at_exit_and_multi_thread_test.rb
sleep done! 1
sleep done! 2
sleep done! 3
sleep done! 4
run at_exit!
```

多分`at_exit`とParallelを同時に使用している人があまりいないのか、ググってもあまりヒットしなかったので記事にしてみました。

考えてみれば全然わかることではあるのですが、特に意識せずにやってしまって挙動がおかしくなってしまったので皆様ご注意を:wave:

# 参考
https://docs.ruby-lang.org/ja/latest/method/Kernel/m/at_exit.html
https://techracho.bpsinc.jp/hachi8833/2018_05_22/56171
https://qiita.com/sekido-ts/items/5dc9c88d877bb2a1df0b
https://qiita.com/Kohei909Otsuka/items/26be74de803d195b37bd
AWSアクセスキーを管理するためのベストプラクティス完全に理解した

AWSにプログラムからアクセスするときは、アクセスキーが必要。
とはいえ、アクセスキーの管理は非常に困難なのだ。

そこで下記を参考に、ベストプラクティスを自分なりにまとめた。
https://docs.aws.amazon.com/ja_jp/general/latest/gr/aws-access-keys-best-practices.html

## ベストプラクティス

### 1. ルートユーザーのアカウントアクセスキーを削除する
   - ルートユーザーのアクセスキーはなんでも見れちゃうから持たないほうがよい、削除せよ。
   - IAM User に必要な権限を付与して、アプリケーションからはそのユーザーを使う。

###  2. 一時的なセキュリティ認証情報(IAMロール)を使う
   - IAMユーザーのアクセスキーのような期限のない長期アクセスキーは悪用リスクがある。
   - 管理コストもかかる。
   - IAMロールを作成すれば時間制限付きの一時認証情報がを利用できる。
   - AWSへの問い合わせの度に自動取得する。

###  3. IAMユーザーを適切に管理する
   - アクセスキーを直接コードに埋め込まない。
   - 異なるアプリケーションには、異なるアクセスキーを。
   - アクセスキーを定期更新せよ。
   - 使用してないアクセスキーを削除せよ。
   - 多要素認証を設定せよ。
      - https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/id_credentials_mfa.html

# 最後に

IAMユーザーを適切に管理するのって大変そうだな。
アプリケーションから利用する際はIAMロールを使おう。

完全に理解した。

# おわり
#django で import 時に ModuleNotFoundError: No module named って出てきてなにこれって時の対処法

# 実行ファイルの例

```
from myproject.app.models import *
```

# エラーの例

```
ModuleNotFoundError: No module named 'myproject.app.models'
```

# 何が！

# 何の！

# 階層で！

# パスだよ！

![image](https://user-images.githubusercontent.com/13635059/57505120-15094980-7332-11e9-887a-5ec4eda64c73.png)


# 解決 - ディレクトリに合わせて python / django 的なパスも割り振られるらしい

`myproject/app/models.py` というファイルが存在するなら `myproject.app.models` から import できる的な。

# フレームワークのレールに乗るのって

大変なんですよ…。

# Stack Overflow

[python - ModuleNotFoundError: No module named 'mysite.core' - Stack Overflow](https://stackoverflow.com/questions/47787991/modulenotfounderror-no-module-named-mysite-core)

# Original by Github issue

https://github.com/YumaInaura/YumaInaura/issues/1761








<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
【Rails API】Advanced REST clientを使ってみる

[前記事](https://qiita.com/disk131/items/10f33c666fcc952fcef7)でdeviceを実装したので、外部ツールを使ってちゃんと実装されているかどうか確認します。
外部ツールは、[Advanced REST client](https://chrome.google.com/webstore/detail/advanced-rest-client/hgmloofddffdnphfgcellkdfbfbjeloo?hl=ja)を使用してユーザー登録、サインイン、サインアウトの動作確認をしていきます。
[前記事](https://qiita.com/disk131/items/10f33c666fcc952fcef7)でdeviseを実装した前提で書いていきます。

**記事の完成データはこちら**
https://github.com/daisuke131/devise_token_auth_rspec
## CSRF対策
外部操作すると弾かれるのでCSRF対策を施してあげる必要があります。
これがないとcreateなどの処理で**エラー422**になる。

```application_controller.rb
class ApplicationController < ActionController::Base
  include DeviseTokenAuth::Concerns::SetUserByToken
  # CSRF対策
  protect_from_forgery with: :null_session
end
```
**※動作確認後はこの記述は削除しておきましょう。**
## 外部ツールで確認
### ユーザー保存
<img width="684" alt="スクリーンショット 2019-05-10 16.23.28.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399745/785a9779-cce3-4f13-8da9-cf0a2f35572b.png">

```
{
  "name": "名前A",
  "email": "sample@example.com",
  "password": "password"
}
```
上の画像のようにやると保存されると思います。
### 続いてサインイン
<img width="654" alt="スクリーンショット 2019-05-10 16.45.44.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399745/7bc35606-794d-bd46-807a-c804428d8a07.png">
`sign_in`をURLに追加して`name`を消して実行してあげるとサインインできます。
サインインしたときに下の方に以下のように表示されていると思います。
<img width="538" alt="スクリーンショット_2019-05-10_16_45_08.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399745/61c5b861-a334-ddcb-bb6f-303b0b2f68d9.png">
`access-token`と`client`と`uid`をheadersに追加していきます。
<img width="718" alt="スクリーンショット 2019-05-10 16.52.16.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399745/fdf16f80-811a-daa0-2e5e-af841d47c2e8.png">
赤文字で`ADD HEADER`と書いてあるところをクリックするとheaderを追加できるようになります。
画像のようにしてあげるとサインアウトできるはずです。
## おわり

次は、Rspecを使ってdeviceのテストをしていきます。

[Rspecテスト編](https://qiita.com/disk131/items/a801e4bc11c8d64fed9a)
【Ubuntu】起動時にドライバを認識せず、解像度が崩れたときの原因と対策

##環境
・ubuntu 18.04.2

##現象
起動時に画面の解像度が崩れてしまった(今までは普通だったのに…)。

##仮説
ドライバが認識されていないのでは？

##調べたこと
まずはドライバが認識されているか確認。

```
$ nvidia-smi
```

すると

```
NVIDIA-SMI has failed because it couldn't communicate with the NVIDIA driver. Make sure that the latest NVIDIA driver is installed and running."
```

と返ってきました。
起動前まではちゃんとドライバの状態が返ってきたので、再起動時にドライバが認識されなくなってしまったのかも？

##原因
linuxのkernelのバージョンが勝手にアップグレードされてしまい、
古いバージョンで紐づけていた設定が新しいバージョンに変更されたことで
反映されなくなってしまったようです。

##対策
まずkernelのログを確認。
ログの場所はこちら。

`/var/log/kern.log`

履歴を見てみると、

* 再起動前 : Linux version 4.18.0-__17__-generic
* 再起動後 : Linux version 4.18.0-__18__-generic

と、バージョンが変更されていました。

なので、以下の手順でバージョンを下げます。

* 再起動する。
* 立ち上がる前にESCボタンを押し、ブート選択メニューを立ち上げる。
* Advanced option for Ubuntuを選択。
* 再起動前のkernel(今回であればLinux version 4.18.0-17-generic)を選択。

これで無事にドライバを読み込んで起動し、解像度も元の状態に戻りました！

##参考
UbuntuのOSやCPU, GPUの情報を確認するコマンド
https://qiita.com/sabaku20XX/items/97db2c0bf7298e3a645c

Ubuntuでnvidiaドライバーが動作しない
https://qiita.com/bohemian916/items/7637b9b0b3494f447c03

ubuntuにてNVIDIAドライバが認識されない
https://qiita.com/moroku0519/items/234f1c53a3187e32bae5

UbuntuでNVIDIAのディスプレイドライバが動作しない場合のチェック項目
https://qiita.com/gm3d2/items/8346c76961d3fdb257b7


めっちゃ助かりました、ありがとうございました！
npm-scripts:imageminを導入してみた

# 前提
- Windows環境
- フロントエンド初学者
- Node.js(v8.11.2)とnpm(v6.9.0)導入済
- gulpでimagemin使ってた
- タスクランナーをnpm-scriptsに乗り換えたかった

# 早速やってみる
必要なパッケージをまとめてインストール

```
npm install --save-dev imagemin imagemin-keep-folder imagemin-mozjpeg imagemin-pngquant imagemin-gifsicle imagemin-svgo onchange
```


```javascript:package.json

{
  "name": "sample-npm-scripts",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "start": "npm run imagemin:watch",
    "imagemin": "node index.js",
    "imagemin:watch": "onchange \"src/images\" -- npm run imagemin"
  }, //Win環境ではエスケープした上でダブルクォーテーションでパスを括る
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "cpx": "^1.5.0",
    "imagemin": "^6.1.0",
    "imagemin-gifsicle": "^6.0.1",
    "imagemin-keep-folder": "^5.3.2",
    "imagemin-mozjpeg": "^8.0.0",
    "imagemin-pngquant": "^7.0.0",
    "imagemin-svgo": "^7.0.0",
    "npm-run-all": "^4.1.5",
    "onchange": "^5.2.0",
    "rimraf": "^2.6.3",
    "watch": "^1.0.2"
  }
}
```


```javascript:index.js

const imagemin = require('imagemin-keep-folder');
const imageminMozjpeg = require('imagemin-mozjpeg');
const imageminPngquant = require('imagemin-pngquant');
const imageminGifsicle = require('imagemin-gifsicle');
const imageminSvgo = require('imagemin-svgo');

imagemin(['src/images/**/*.{jpg,png,gif,svg}'], {
  plugins: [
    imageminMozjpeg({ quality: 80 }),
    imageminPngquant({ quality: [0.65, 0.8] }), //'65-80'←この書き方だとエラー出た
    imageminGifsicle(),
    imageminSvgo()
  ],
  replaceOutputDir: output => {
    return output.replace(/images\//, './dist/images/')
  }
}).then(() => {
  console.log('Images optimized');
});

```
あとは実行

```
npm start
または
npm run imagemin
```

# 感想

エラーが何度か出て一発では動かなかったのですが、やりたかったことができました。
pngquantの画質設定を配列かつ小数点で指定するのとかは情報がすぐ出てこなかった。
https://www.npmjs.com/package/imagemin-pngquant
でもこれでディレクトリ構造を維持したまま、画像が追加されたら自動でdist以下に圧縮保存されます。

> **参考サイト**
https://qiita.com/minase_tetsuya/items/986feac7150ed74e13d8
https://techblog.lclco.com/entry/2018/08/31/180000
Thymeleaf 3で属性値へ動的に値を埋め込み＆テキストを追加したい場合

# 概要
概ねここに書いてある通りなのだけど、JavaScriptの引数が文字列のパターンではまったので。

[Thymeleaf3で属性値へ動的に値を埋め込み＆テキストを追加したい場合](https://qiita.com/alpha_pz/items/3ea4754c5f274d44e564)

# JavaScriptと関連する属性の場合

シングルクォーテーションを円マークでエスケープしてあげればよい。

```html
<a href="#" th:attr="onclick='alert(\'aaaa' + ${page} + '\');'" >
```

と書く。
この時に、エスケープする前後に見やすいからとスペースを入れると、入れたスペースも忠実に反映されるので注意。
Running via Spring preloader in process. Could not find generator 'devise'の原因と解決策

###開発環境
・MacOS
・Ruby -v 2.6.0
・Rails 5.1


###やりたいこと

deviseとdevise_inivitableで招待機能を実装したい。
deviseを入れて、devise_invitable入れて、実装する。

そのために、deviseのUserモデルを作りたい
参照文献：https://qiita.com/kera/items/6fab6ef0661824d0fa0d

###エラー

```
$ rails g devise User
Running via Spring preloader in process 65446
Could not find generator 'devise'. Maybe you meant 'mailer', 'task' or 'helper'
Run `rails generate --help` for more options.
```

###試したこと

####①`$spring stop`

```
$ spring stop
Spring stopped.
```

```
$ rails g devise User
Running via Spring preloader in process 65482
Could not find generator 'devise'. Maybe you meant 'mailer', 'task' or 'helper'
Run `rails generate --help` for more options.
```

####②Gemfileを確認

`gem 'device'`になっていて、typoでした。

`gem 'devise'`に変更して、`$bundle install`して、`$ rails g devise User`やったら、無事にUserモデルできました。

参照:https://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q10164373290
Unityでモブプログラミングやってみよう【発足】

# みんなとUnityでゲームを作りたい！
社内の勉強会で初心者から上級者までみんなで作りたいのがキッカケです。複数人での作業になるとキチンとするならGitとかで管理した方がよいのです。
ただし１日で完結させるカンジじゃないとみんなのテンションも続かないので、作りやすいスタイルを模索した結果行き着いたのがモブプロでした。

### モブプロって何？
モブプログラミングの略です。小さなグループを作ってプログラミングする人を交代しながら１つのプログラムを組み上げる開発手法です。
２人体制でやる場合はペアプログラミングになるようです。

よく非効率やんけ～って言われたりするわけですが、技術を共有する目的などの場合はモブプロやペアプロの方が向いているかなと思ってます。特に勉強会では技術共有というところ押していきたい！

今回の場合は一人15分くらいパソコンを操作してもらい、操作担当者を交代しながら開発を進めていくカンジです。

# そもそもUnityで複数人で作業するのムズくない？
はい、ちゃんと役割やルールを決めないとタイヘンなことになります。小さなチームで分業したり、作業が被らないようにルールを決める必要があります。
テキトーにやると他の人の作業と重複して、あげくには他人の作業内容を上書いて揉めたりします。

# ではどうやって作っていけばいいの？
モブプロで分かれたチームごとにミニゲームを作っていく形にします。ミニゲームにすれば独立して自由に作れ、勉強会の１日で作り切ることが出来ます。上記の重複する問題は次に記載する内容で回避できればイイなと・・・。
最終的には作ったミニゲームを結合してゲーム集的なアプリとして完成することが目標！

# ミニゲーム作成のルール
他のミニゲームに重複しないようする。

- 各ミニゲームは独立したフォルダで管理
- 基本的に共通のスクリプトは使わない
 - （ソース自体をコピーして専用のスクリプトにする）
- 同じスクリプトファイルがあるとエラーになるので被らないような仕組みにする

### 【ルール】概要
- 作成するミニゲームは2Dとする
 - 初心者も2Dの方が馴染みやすいはず 
- 作成するミニゲーム以下の命名規則の接頭辞をつける
 - A01_Action、A02_Puzzle、A03_Bomber
- 接頭辞についてはゲーム作成前に予め決めておく
- もしグループが分かれたりして新しいゲームを作成する場合は
接頭辞の使用を宣言して重複しないようにする
- 最初のアルファベットの部分については勉強会ごとにA→B→Cと切り替えていく

### 【ルール】接頭辞の付与

以下の項目について必ず接頭辞をつける

- トップのフォルダ名（例：A01_GameTitle）
 - 接頭辞がついたフォルダごとにミニゲームが作成されます
- フォルダの下の構成はゲーム毎に自由
- 作成するスクリプト（例：A01_PlayerScript）
 - 接頭辞がつくことで他のスクリプトと競合しなくなる
 - 同じコードの記述で煩雑になるがフォルダごとで分離するので
他への影響がないことを優先する
- レイヤーなど他に影響を与えるもの接頭辞を追加する

### 【ルール】その他
- タグやレイヤーの設定はインポートで設定が引き継がれないの
で、テキストファイルに設定内容を記載してゲームフォルダに
格納してほしい
- アセットを利用したい場合は要相談
できるだけ入れて楽はしたいのでできれば入れたい！
- どうしても共通化したい処理がある場合はCommonフォルダの
導入を考える
- 画面は縦型のportraitで1920×1080のサイズで作成する

### 実際に作成したサンプル
- 1つ目のミニゲーム

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412322/25acb6ca-0a31-d7a6-5a08-1f2b0104a1ca.png" width=30%>

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412322/7802f02e-fc67-823b-dda4-5857c18cd133.png" width=70%>

- 2つ目のミニゲーム

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412322/08e21fac-e2ae-56aa-3dcb-b6f6d6be9cde.png" width=30%>

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412322/e64e7df9-65ab-61df-64ce-05a2582df1c9.png" width=70%>


それぞれのミニゲームでフォルダが分かれているのでぶつからない。フォルダの下の構成は最悪異なっても大丈夫。スクリプトは同じモノがあるとエラーになるので接頭辞を付けることでエラーを回避（重複することを「競合」っていう風にいうとカッコよさげですね）。

# 上記の手法をAZML-Projectとして発足
接頭辞がアルファベットの「A」から始まって「B」→「C」と進んでいくのでA to Z（amazonのパクリ・・・）。あとミニゲームゲームを結合して大きなゲームにするのでMinimal to Large。それぞれの頭文字を取ってAZML-Projectとして発足してレポートに残していきます。関連するQiitaの記事のタグには「AZML」と付けていきます。
Web制作時のコピペ用テンプレート

Web制作時のコピペ用テンプレ置き場として。
随時更新。

# 基本マークアップ
```sample.html
<!DOCTYPE html>
<html lang="jp">
<html>
<head>
<meta charset="UTF-8">
<title>〇〇へようこそ！</title>
<link rel="stylesheet" href="style.css">
<style></style>
</head>
<body>

</body>
</html>
```

# ラベル

```html:label.html
<h1>こんにちは</h1>
```
```style.css
h1{ 
	position: relative;
	padding: 1em;
	background: pink;
}
h1::before{
	position: absolute;
	content: 'Label';
	top: 0;
	left: 0;
	font-size: 0.5em;
	color: white;
	padding: 0.2em;
	background: black;
}
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281259/02ca229c-1843-d77a-e638-0d633ea75f49.png)