OmniAICreator/Qiita-1.07M huggingface dataset:
FFmpegでビデオキャプチャして静止画保存

# 何する？

[FFmpeg](https://ffmpeg.org/)を用い、[aitendo](https://www.aitendo.com/)で売られている「USBビデオキャプチャー」(Easier CAPなど、EasyCAPもどき)
から静止画を取得します。
他のキャプチャデバイスやカメラなどでも使えるかもしれません。

# 環境

Windows 10 Home x64

```
ffmpeg version git-2020-05-19-74dfc88 Copyright (c) 2000-2020 the FFmpeg developers
built with gcc 9.3.1 (GCC) 20200513
```

# やり方

```
ffmpeg -show_video_device_dialog true -show_video_crossbar_connection_dialog true -video_size 720x480 -f dshow -i video="OEM Device" -t 1 -r 30 "out%02d.png"
```

|オプション|解説|
|---|---|
|`-show_video_device_dialog true`|キャプチャの開始前にビデオ入力のフォーマットの<br>設定ダイアログを開きます。<br>設定は保存されるようなので、<br>毎回指定しなくてもいいかもしれません。|
|`-show_video_crossbar_connection_dialog true`|キャプチャの開始前にクロスバー(どこから入力するか)の<br>設定ダイアログを開きます。<br>残念ながら設定は保存されないようでした。|
|`-video_size 720x480`|入力の解像度を指定します。<br>指定しないと結果にゴミが入ることがあります。<br>適切な値は[OBS](https://obsproject.com/ja)のキャプチャのプロパティから得られます。|
|`-f dshow`|おまじないです。|
|`-i video="OEM Device"`|入力デバイスの名前を指定します。<br>名前はOBSのキャプチャのプロパティから得られます。|
|`-t 1`|キャプチャする時間(秒)を指定します。|
|`-r 30`|1秒あたり何フレームキャプチャするかを指定します。|
|`"out%02d.png"`|現在のディレクトリに、<br>`out01.png`、`out02.png`のような連番のファイル名で<br>保存することを指定します。|

# 補足

指定する名前はFFmpegを用いて

```
ffmpeg -list_devices true -f dshow -i dummy
```

というコマンドでも求めることができます。

キャプチャを開始した最初の数フレームはゴミになることがあるようです。

# 参考文献

* [Windowsで映像入力デバイスからの映像をffmpegでエンコードする - Qiita](https://qiita.com/niusounds/items/726fbee7d05cc3669d42)
* [ffmpegで動画から静止画を抜き出す - Qiita](https://qiita.com/matoken/items/664e7a7e8f31e8a46a60)
* [Issue capturing video within device specs from a USB Grabber with ffmpeg & directshow - Stack Overflow](https://stackoverflow.com/questions/58302267/issue-capturing-video-within-device-specs-from-a-usb-grabber-with-ffmpeg-direc)
* [Ubuntu Manpage: ffmpeg-devices - FFmpeg devices](http://manpages.ubuntu.com/manpages/cosmic/man1/ffmpeg-devices.1.html)
FactoryBotについて

今回が初めての投稿になります、自分の中で理解できたことなどを書いていこうと思います。
今回はテストコードのFactoryBotについて書いていきます。
FactoryBotとは簡単にいうとインスタンスをまとめてくれるGemです。

テストコードを書いていて it "~"とexampleをかなりの量を書くことがあり、その度にテーブルの情報を変数に代入する記述を書くのはかなり大変なのでそれを改善するためにFactoryBotは用いられます。
これを用いるにはまず別のファイルで各クラスのインスタンスに定める値を設定しておき、各テストコードで使用していきます。

例えとしてあるユーザーの情報をインスタンス生成するとしたら
user = User.new(nickname: "A", password: "qwer")
このような記述を毎回書くのは非効率ですのでFactoryBotを利用します。すると
user = FactoryBot.build(:user)と短く書くことができます。ですがこれでも毎回書かないのでインスタンス変数を利用するとさらに記述量が少なくなります。
@user = FactoryBot.build(:user)と設定して各テストコードに記述するときは
@user.nicknameと短く書くことができます。

FactoryBotを用いることによってよりプログラムが見やすい形になると思います。
【Dockerについて 復習】

こんにちは！
Docker！

#目次
[1.iamgeとコンテナの違い](#1-imageとコンテナの違い)

[2.DockerHubでimageの見方](#2-DockerHubでimageの見方)

[3.Docker-composeとは](#3Docker-composeとは)

[4.docker-compose.ymlの書き方](#4.docker-compose.ymlの書き方)

[5.phpmyadminの必要性](#5.phpmyadminの必要性)











#1.imageとコンテナの違い
**imageとは** 
・コンテナを作るためのタネみたいなもの

**コンテナとは**
・imageを元に生成される仮想環境の実行部分
・アプリケーションを管理するプログラムが組み込まれてる



#2.DockerHubでimageでの見方
下記の画像が、DockerHubで実際に検索した際に出てくるDockerfileです。
①〜③で書いてるように、複数Dokcerfileがありますよね？？
それについて解説していきます！

![スクリーンショット 2021-01-18 12.49.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/748934/63a05ca5-e2c0-5f41-c541-45cd75528d47.png)
###画像下線の**1.18.0**/**Stable**/**1.18** と3種類について
・これらは検索したimageのversionを示しています。

**1.18.0**のDockerFileを選んでも良いし、**stable**のDockerFileを選んでも良いということです！
（3番目もね!）


###1.18.0のそれぞれの意味

**`1`.18.0**
・Major Versionと言われて、これが変わるとガラッと機能が変わる
**1.`18`.0**
・Minor Versionと言われて、後方互換があり、便利な機能や記法が変わったりする
**1.18.`0`**
・Revision Versionと言われて、数値が上がるにつれて、バグの対応をしてくれる

###**stableの意味**
安定版だから、変化することがない。

###1.18の意味
・Major VersionとMinor Versionについては①と同じ
・Revision Versionが記載されていないので、改善されたバグは更新されない
###例えば
**・1.18.0**
1.18.0を選ぶと、version1.18.0のイメージしか使えないよね？？
もし仮にバグが見つかったとしても、変更できなくて、DockerHubから違うversion(最新版とか)を新しく
取得しなくてはいけない。
**・1.18**
1.18を選ぶと、Revision Version部のみ記述がないので
DockerHub側が1.18のバグを見つけて更新/改善してくれた時に、
自動的にバグ改善したversionを認識して取得してくれる（表現あってるか不明）

例えば
**2021/01/01**
DockerHub上のnginxイメージが
`1.18.0 stable 1.18`
とあるとする。

2日後にnginxイメージ1.18.0でバグが見つかって更新されました

**2021/01/03**
DockerHub上のnginxイメージ
`1.18.1 stable 1.18`
というふうに変わっていく

ここで、2021/01/01の**1.18.0**を選んでると
01/03に更新された1.18.1versionを使えずバグは残り続ける。
1.18を選んでると、自動的にRevision Versionが更新され続けていく



###赤線部Perl/Alpineについて

**`perl`**
・どのOSで開くか（下記の画像参考に）

**`-alpine`**
・軽量化されたパック（必要最低限のファイルしかない）
・都度カスタマイズする必要がある。
![スクリーンショット 2021-01-18 13.01.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/748934/e9edf610-2ea6-0265-0696-80fd33486bee.png)


#3.Docker-composeとは
・複数のコンテナで構成されるアプリケーションについて、
**Dockerイメージのビルド**や各コンテナの起動・停止などをより簡単に行えるようにするツールです。

**`Dockerイメージのビルドとは`**
・イメージに対して自分で
**docker-composer.yml**上にカスタマイズして、自分独自のイメージを作成すること

**`docker-compose.ymlとは`**
・複数のコンテナの定義をymlファイルに書き、それを利用してDockerビルドやコンテナ起動をすることで、
簡単なコマンドで複数のコンテナを管理できるようになります。


#4.docker-compose.ymlの書き方

`yamlの書き方のversion`

```

version: "3.7"  　　　　[ymlのversion
services:  　　　　　　　[serviceというコンテナを管理する
  nginx:               [nginxの名前は何でも良いが、アプリ名を書くのがベター
    build: ./nginx     [Dockerfileを使ってimageをカスタマイズする

    ports:             [右の80はローカル側のポート:左はDocker側のポート
      - "80:80"　　　　 [左のポート番号は、落としたいDockerFile内にポート番号が書かれてる(**画像1**)
  　　 volumes:         [localとコンテナ内を共通化する
        - ./infra/nginx/default.conf:/etc/nginx/conf.d/default.conf [ホストdefault.confを同期 
```

** 画像1 ** EXPOSEがDocker側のポート番号（Nginxの場合は80）
![スクリーンショット 2021-01-25 23.58.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/748934/1b4ee4dd-0eb6-9991-a736-56c1a0896ac4.png)

#5.勝手な復習なのでスキップしてください
![スクリーンショット 2021-01-26 0.23.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/748934/43627276-f57e-5e3f-5a42-8e855ba9f101.png)
【AT Command】APNアクティベート~ローカルIPの取得 (SIMCom: SIM7500JC)

# Memo

APNの設定方法は、SIM7000シリーズとは少し異なっています。
APNの設定は、PDP Contextを設定するだけではないみたいですね。
認証モードやユーザー名(認証ID)やパスワードを設定しないといけないようです。
SIMのキャリアによっては違うかもしれませんね。
soracomだと`soracom.io`のPDP Contextを設定するだけで良いようですが、OCNモバイルONEでは認証系について設定が必要です。

## 環境

- OS: windows10
- ターミナル: m-center v.02.03.00

## ハードウェア

- インターフェースモジュール: mini pcie usbアダプタ
- セルラー通信モジュール: SIMCom SIM7500JC
- SIM: OCN モバイル ONE for Biz Type COM 7GB (LTE)

## ログ

```
AT+CGDCONT=2, "IP", "fm.ntt.com"

AT+CGDCONT=2, "IP", "fm.ntt.com"

OK

AT+CGDCONT?

AT+CGDCONT?

+CGDCONT: 2,"IP","fm.ntt.com","0.0.0.0",0,0,0,0

OK

AT+CGAUTH=2,3,"bizfmobile", "bizfmid@bizfm.ocn.ne.jp"

AT+CGAUTH=2,3,"bizfmobile", "bizfmid@bizfm.ocn.ne.jp"

OK

AT+CGAUTH?

AT+CGAUTH?

+CGAUTH: 2,3,"bizfmid@bizfm.ocn.ne.jp","bizfmobile"

OK

AT+CSOCKSETPN=2

AT+CSOCKSETPN=2

OK
```

ここで通信モジュールを再起動。
再起動しないと設定したAPNでネットワークを探してくれないっぽい。
コマンドでの再起動のやり方がわからないので、一度電源供給を断って再起動させてます。

```
AT+COPS?

AT+COPS?

+COPS: 0,0,"NTT DOCOMO",7

OK

AT+CGPADDR

AT+CGPADDR

+CGPADDR: 1,0.0.0.0
+CGPADDR: 2,10.0.2.55

OK
```

### AT+CGAUTH

認証系について設定のコマンド。

`AT+CGAUTH=cid,auth_type,"passwd","user"`

※**パスワードとユーザー名の引数の順番に注意。"user", "passwd"の順でずっと入力していて、気が付かずにハマりました。**

- cid: APNのID。ログでは2番のIDを使用している。ここは認証系を設定したいAPNが設定されているIDを記述。
- auth_type: 認証モード
- passwd: 認証パスワード
- user: ユーザー名、認証ID

>認証モード
0    –    none 
1    –    PAP 
2    –    CHAP 
3    –    PAP or CHAP 

### AT+CGPADDR

おそらく、ローカルIPの表示。
FIXED関数

#__■前提__#
利用データは、以下のサイトにある「サンプル - スーパーストア.xls」をしております。
※DataSaberの試練で使うものです。
http://bit.ly/DSOrdealData

外観としては、3つのカテゴリ（家具、家電、事務用品）のいろんなメーカの商品を全国で販売している企業の取引データ（取引商品、売上、利益、など）というデータ内容になっております。

#__■今回の内容__#
エクセル、SQLで使う関数とTabaleauの関数は似てるものが多いのですが、
このFIXED関数は初見で最初は意図が分かりませんでした。
自分なりの理解の仕方を以下に示します。

##__①普通に「カテゴリ」別売上を出す__##
利用データをTabaleauに取り込み、カテゴリ別に売上状況を可視化した場合、以下の表現になると思います。
ここでの「合計（売上）」は、計算式で示すと「SUM([売上])」です。
![図1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1036899/98453bd4-fe77-a3b3-7334-60be0d35eb0f.jpeg)

__②FIXED関数を使って「カテゴリ」別売上を出す。（関数自体の説明は後で）__
計算フィールドを起こして、項目名と式を書いていきます。
![図3_計算フィールド.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1036899/318e7580-acc7-1495-5058-72100823a307.jpeg)
![図4_Fixed関数.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1036899/65f37a90-3194-5e6e-c3da-e1a5e5b1c315.png)
で、①と同じように「カテゴリ別」に売上を出します。（参考として普通に出した「カテゴリ別」売上を横に）
![図5_Fixedと普通.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1036899/3d58aaca-4fe0-42d8-b9ed-f71b15b63d51.png)
ここまでは値が一致していることがわかるかと思います。

##__③項目を追加した場合の挙動を比較__##
__普通の方（①）__で、「カテゴリ」と「合計（売上）」の間に「顧客区分」という新たなデータ項目を差し込むと、Tabaleauが計算してくれて、以下のように表現されます。（カテゴリ×顧客区分で合計（売上）を分解してくれる）
![図2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1036899/d2a7d0f6-fe82-2176-175a-f9448c3da17c.png)![図7_FIXED占有率.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1036899/f148ada1-81e8-da77-dccb-157daf0c41a1.png)

__FIXED関数を使うの方（②）__で、「カテゴリ」と「合計（売上）」の間に「顧客区分」を差し込むと、Tabaleauが計算してくれて、以下のように表現されます。
![図6_FIXED.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1036899/416f8d86-ce6e-c151-73ac-ad746ce5c6a3.jpeg)


なんと、こっちではカテゴリ×顧客区分で合計（売上）を分解してくれないんですね。
なぜこのような挙動になるのか、FIXED関数の自分の理解を踏まえ、次に展開します。


##__④自分の理解__##

FIXEDは、英語で「固定する」という意味で、今回使用した式は、__｛FIXED [カテゴリ]:SUM[売上]}__でした。つまり、カテゴリ別で売上を合計した値を固定してデータソースとは別に持っていてね、と宣言している、と理解しています。図にすると↓の感じです。
![図7_FIXEDイメージ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1036899/a9e67024-71f6-e673-b251-81c36dd3d344.png)

FIXED関数により切り出したデータを__固定__して持つ宣言をしてたため、途中でいろんなデータ項目を差し込んでも微動だにせず、固定された値を出し続けている。と理解してます。

##__⑤どういうシーンで使うのか__##
私はよく値をある観点で細分化していく足、それの占める割合って何%なのかをよく気にしていたり、業務上表現を求められることも多いため、FIXED関数を使って↓のように表現することが多いです。
![図7_FIXED_顧客区分占有率.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1036899/bd0a79ae-09d0-8424-3aaf-38837374b825.png)

※売上に占める割合　＝　売上　÷　FIXED_合計（売上）
※割合比較しやすいように、横に棒グラフを添えてます。

カテゴリ別の売上を固定して持っているため、それに占める〇〇の割合の〇〇の項目を差し替えるだけですぐその値をかしか知ることができます。

`〇〇をサブカテゴリにした場合`
![図7_FIXED占有率.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1036899/ccd5c280-7c4d-642c-2c78-de8d8de1915b.png)
`〇〇を地域にした場合`
![図7_FIXED_地域占有率.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1036899/cef29962-f508-f4a6-082a-c349826acebc.png)

ともにFIXED関数で切り出されたカテゴリ別売上合計を保持し続けてくれるので、過ぎに占める割合をだせることができる、というわけです。

##__⑥まとめ__##
`FIXED関数`
FIXEDで宣言（切り出）した値を固定（保有）し続けてくれる関数。絶対に値が変わることがない
`いつ使うのか`
私は〇〇に占める割合を出すときに便利でよく使います。

Tableau初心者の私だとまだこれぐらいしか使い道を見つけていませんが
おそらくはるかに次元の違う使い方が多くあると思いますが、それはおいおい見つけていきたいと思います。

以上！
最後までご覧いただき、誠にありがとうございました！:hugging:
AWS KMS とは

## 勉強前イメージ

key manage system で鍵を管理するところってイメージ
でもそれだとあんまりcloudHMSと何が違うんでしょう

## 調査

### AWS KMS とは

Amazon Key Management Service の略で、
データ暗号化に使用する暗号化キーを管理してくれるサービス
データの暗号化の鍵(データキー) と 暗号化のための鍵(マスターキー) を管理できます

### KSMが扱う鍵

基本的な暗号化のイメージは以下です。
鍵を使ってデータを暗号化します。

![元々の暗号化イメージAWS KMS - diagrams.net - Google Chrome 2021-01-21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/62d06eef-2154-f3b8-43ff-3027959f3eb7.png)
 

しかし、この鍵も盗まれかねないので、鍵を暗号化するようになりました。
すると構成図は以下のようになります。


![2重暗号化AWS KMS - diagrams.net - Google Chrome 2021-01-21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/fde289cd-926b-d0d9-deaf-5d42b156829f.png)


しかし、 `鍵` ・ `暗号化された鍵` ・ `暗号化されたデータ` をどっちにしても一緒に盗まれると復号化されてしますので、
元々の `鍵` を保管するのが `AWS KMS` です。


また、以下のように元々の鍵をマスターキー、
暗号化された鍵をデータキーとしてAWSで保存することができます。

![鍵の種類AWS KMS - diagrams.net - Google Chrome 2021-01-21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/9f61f258-aa17-7b59-23ee-755bf059e42c.png)

### cloudHMS との違い

- 鍵を管理するサーバはシングルテナントではない
- cloudHMS より安価
- サポートされる暗号鍵は、
	- KMS : 共通鍵
	- cloudHMS : 共通鍵と公開鍵

## 勉強後イメージ

惜しかった、、Key Management Serviceかー
あまり要件とか厳しくないとか、共通鍵使ってるよとかであればKMSで良いのかな。。


## 参考

- [10分でわかる！Key Management Serviceの仕組み #cmdevio](https://dev.classmethod.jp/articles/10minutes-kms/)
- [AWS】KMS ～ 入門編 ～](https://dk521123.hatenablog.com/entry/2020/02/27/232553)
投稿機能の実装方法

#目次
<b>①新規投稿ページに遷移可能にする</b>
<b>②データベースへ情報を登録可能にする</b>



##①新規投稿ページに遷移可能にする
投稿ページに飛べるようにnewアクションを呼び出すために、newアクションへのルーティングを設定する。

```
Rails.application.routes.draw do
 resoureces :human , only:[:new]
end
```
次にnewアクションを定義する

```
class HumansContorller < ApplicationController

  def new 
  end
```

そしてnew.html.erbに表示させたいようにビューを作成する。


form_withメソッドを使用すして、データの送信のビューを作成する

```
<%= form_with(model:モデルクラスのインスタンス)　do |f| %>
  <%= f.text_field :name ,placeholder:"niconicocareer" %>
  <%= f.text_area :text,placeholder:"career adviser" %>
  <%= f.submit "送信"%>
<% end %>
```

◯補足(form_withでよく使われるメソッド)

|メソッド|意味|
|:---|:---:|
|label|ラベルテキスト|
|check_box|チェックボックス|
|password_field|パスワード入力フィールド|
|submit|送信ボタン|
|text_area|複数行入力テキストエリア|
|text_field|テキスト入力フィールド|

##②データベースへ情報を登録可能にする
createアクションに遷移するように、ルーティングを記述する

```
Rails.application.routes.draw do
 resoureces :human , only:[:new,:create]
end
```
次はcreateアクションを記述していく
※入力されたデータがしっかりと受け取れるように記述をする

```
class HumansContorller < ApplicationController

  def new 
  end

　def create
   Humnan.crate(input_date)
  end

 private
 def input_datta
   params.require(:human).permit(:name,:text)
 end
```

最後に投稿後のaction.html.erbのビューを作成し終了。
getBoundingClientRect を使って要素の座標情報を取得

# 概要

## getBoundingClientRectの情報を見てみる

```TypeScript
let image = (<HTMLAnchorElement>document.getElementById("image"));
let image_domRect = image.getBoundingClientRect();
console.log(image_domRect)
```

上述のコードを実行するとConsoleに下記の情報が表示される。

```
DOMRect {x: 677.484375, y: 269, width: 143.015625, height: 15, top: 269, …}
bottom: 284
height: 15
left: 677.484375
right: 820.5
top: 269
width: 143.015625
x: 677.484375
y: 269
__proto__: DOMRect
```


## 使用例

image_dialogというダイアログがあるとする。
前述の座標情報をもとに、ダイアログが表示される位置を指定することができる。

```TypeScript
image_dialog.style.top = (image_domRect.top + 20) + 'px';
image_dialog.style.left = Math.abs(image_domRect.left - image_domRect.width - 100) + 'px';
$(image_dialog).show();
```
node.jsでgoogleapiのリダイレクトURIに任意の文字列（state）を追加する方法


#この記事について
バックエンドで Google API を使っています。
言語はNode.jsで書いています。
Google APIの使用には、[Google APIs Node.js Client](https://googleapis.dev/nodejs/googleapis/latest/calendar/index.html)
を使っています。

今回は、Google APIのユーザー認証後のリダイレクトURIに任意の文字列を指定する方法を記載します。

#事前準備
GCPコンソールにてGoogleプロジェクトを作成し、認証情報を作成し、何かしらのAPIを有効化しておいてください。
↓GCPコンソール（developers）
https://console.developers.google.com/apis

#やり方
リダイレクトURLに任意の文字列を含めたい場合は、__state__パラメータを認証URLに含めることで可能です。
https://developers.google.com/identity/protocols/oauth2/web-server#request-parameter-state

（ちなみに）stateパラメータの用途
>You can use this parameter for several purposes, such as directing the user to the correct resource in your application, sending nonces, and mitigating cross-site request forgery.
↓
日本語訳
stateパラメータは下記のような目的で利用されます。
・ユーザーをアプリの正しいリソースにリダイレクトするため
・乱数を送るため
・CSRF対策のため

#実際の認証URL例
公式ドキュメントにも書いてありますが、こんな感じで認証URLにstateを含めます。

```
https://accounts.google.com/o/oauth2/v2/auth?
 scope=https%3A//www.googleapis.com/auth/drive.metadata.readonly&
 access_type=offline&
 response_type=code&
 state=state_parameter_passthrough_value&
 redirect_uri=https%3A//oauth2.example.com/code&
 client_id=client_id
```

#Node.jsでの実装例
```useGoogleApi.js
const { google } = require("googleapis");

const oauth2Client = new google.auth.OAuth2(
  CLIENT_ID,
  CLIENT_SECRET,
  REDIRECT_URI
);

const scopes = "https://www.googleapis.com/auth/blogger";

const authUrl = oauth2Client.generateAuthUrl({
  access_type: "offline",
  scope: scopes,
  state: "abcdefghijklmnopqrstuvwxuz", // ←任意の文字列
});

console.log(authUrl)
```

```bash:useGoogleApi.jsがあるフォルダで下記コマンドを実行
node useGoogleApi.js
```

```bash:するとこんな感じでURLがコンソールに出力されるので、そのURLにアクセスする。
https://accounts.google.com/o/oauth2/v2/auth?access_type=offline&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fblogger&state=abcdefghijklmnopqrstuvwxuz&response_type=code&client_id=your_client_id&redirect_uri=your_redirect_uri
```

認証画面にてGoogleアカウントを選択すると
リダイレクトしたURLにちゃんとstateが渡されていました^^
<img align="center" width=60% src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/640981/b3e7ef63-c075-3863-df16-1a76ec78c45a.png">
Pythonで学ぶアルゴリズム　第21弾：並べ替え（クイックソート）

# #Pythonで学ぶアルゴリズム< クイックソート >

##はじめに
基本的なアルゴリズムをPythonで実装し，アルゴリズムの理解を深める．
その第21弾としてクイックソートを扱う．

##クイックソート
・**クイックソート**：リストから任意にデータを選択し，これを基準として小さい要素と大きい要素に
$\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ $分割し，それぞれのリストでまた同じような処理を繰り返してソートする方法．
・**ピボット(pivot)**：クイックソートで基準となるデータ．選び方は様々であるが，ここではリストの
$\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ $先頭としている．

以上のことを踏まえて，次にクイックソートの一連の流れ図を示す．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/951300/13a4f876-cdde-c089-75f9-6107ac94b130.png)

##実装
先ほどの手順に従ったプログラムのコードとそのときの出力を以下に示す．
今回は再帰を用いた方が非常に簡単にかけることが分かる．

#####コード
```python:quick_sort.py
"""
2021/01/25
@Yuya Shimizu

クイックソート
"""

def quick_sort(data):

    #分割できなくなる(リスト要素が1以下)であれば，そのままデータを返す(並べ替えの必要なし)
    if len(data) <= 1:
        return data

    pivot = data.pop(0)     #リストの先頭をピボットとして取り出す

    # ピボットより小さいものでリストを作る
    left = [i for i in data if i <= pivot]
    # ピボットより大きいものでリストを作る
    right = [i for i in data if i > pivot]

    left = quick_sort(left)       #入力に対する左側リストを形成する
    right = quick_sort(right)   #入力に対する右側リストを形成する

    #########再帰しきった結果のみ，quick_sort関数の出力として返される
    #########それ以外のreturnは上のleft = quick_sort(right), left = quick_sort(right)
    return left + [pivot] + right
    

if __name__ == '__main__':
    DATA = [6, 15, 4, 2, 8, 5, 11, 9, 7, 13]

    print(f"{DATA} → {quick_sort(DATA)}")
```

#####出力
```
[6, 15, 4, 2, 8, 5, 11, 9, 7, 13] → [2, 4, 5, 6, 7, 8, 9, 11, 13, 15]
```

##計算量
**ピボットの選択が重要!**うまく半分に分割できるようなピボットを選ぶことができると，マージソートと同様に**$O(nlogn)$**となる．ただし，ピボットをうまく選ぶことができないと，最悪な場合，**$O(n^2)$**となる．実用上は問題ないほど高速だが，多くのライブラリでは他のソートアルゴリズムと組み合わせるなど，高速化が図られているらしい．

##感想
とりあえず，基本的な並べ替えのアルゴリズムはある程度，学ぶことができたのではないかと思う．この並べ替えに関するアルゴリズムについてはあと２つ残っている．【処理速度の比較】と【ビンソート】である．どんどん進めていきたい．


##参考文献
Pythonで始めるアルゴリズム入門　伝統的なアルゴリズムで学ぶ定石と計算量
　　　　　　　　　　　　　　　　　　　　　　　　 増井 敏克　著　　翔泳社
Raspberry Pi 4 (Ubuntu Server 20.04.1 LTS ) で非公開SSIDのアクセスポイントに接続する

Ubuntu Server 20.04.1 LTSをインストールしたRaspberry Pi 4で非公開SSIDのアクセスポイントに接続する設定に関するメモです。
ちょっとハマったのでメモとして投稿します。

## 設定例

ポイントは netplan の設定ファイルで定義する `hidden: true` の部分です。
今回は **50-cloud-init.yaml** を修正せずに **90-wifi.yaml** を追加しています。

```yaml:/etc/netplan/90-wifi.yaml
network:
    version: 2
    wifis:
        wlan0:
            access-points:
                "MySSID":
                    hidden: true
                    # wpa_passphrase で暗号化したパスフレーズ
                    password: "8a98ace1117ee11811eb08759cb2bdc4d99f4cea433b86c4bcbd18ad0f9eed48"
            dhcp4: true
            optional: true
```

設定が終わったら以下のコマンドを実行し、設定ファイルの生成と適用を行いましょう。

```shell:検証・生成・適用
sudo netplan --debug try
sudo netplan --debug generate
sudo netplan apply
```

次のような設定ファイルが生成されます。

```configuration:/run/netplan/wpa-wlan0.conf
ctrl_interface=/run/wpa_supplicant

network={
  ssid="MySSID"
  scan_ssid=1
  key_mgmt=WPA-PSK
  psk=8a98ace1117ee11811eb08759cb2bdc4d99f4cea433b86c4bcbd18ad0f9eed48
}
```

以上です。

## 補足

そのほか、Wi-Fi設定関連で調べた内容も記載しておきます。

### パスフレーズを暗号化する

`wpa_passphrase ` コマンドで暗号化したパスフレーズも使用することができます。

```shell:パスフレーズの暗号化
wpa_passphrase "MySSID" "password"
```
```configuration:結果
network={
        ssid="MySSID"
        #psk="password"
        psk=8a98ace1117ee11811eb08759cb2bdc4d99f4cea433b86c4bcbd18ad0f9eed48
}
```

psk部分を netplan の設定ファイルで使用します。

### 非推奨（ハック）を用いた設定方法

SSID を `"MySSID\"\n  scan_ssid=1\n# \"hack!"` のように定義する記事もありましたが、今は netplan 側が非公開SSIDに対応しています。

参考リンク
https://bugs.launchpad.net/netplan/+bug/1866100
Databricks Community Editionにてurllibライブラリーにてdbfsにファイルを書き込む際のエラーへの対応方法

## 概要
Databricks Community Editionにてurllibライブラリーにて、Databricks ファイル システム（dbfs）にファイルを書き込む際に、下記のエラーとなってしまうため、その対応方法を共有します。urllibにてローカルディスクに書き込み後にdbutilsにてdbfsに書き込むことで対応できるようで、修正前と修正後のコードを後述します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/33c2ba17-71e7-fba8-5fad-8ad74bff11ed.png)

> FileNotFoundError: [Errno 2] No such file or directory


下記のサイトにて、urllibにてデータを直接書き込む場合にエラーとなると紹介されておりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/743d66a4-34ac-9d12-7227-d11b86880899.png)
引用元：[How to use Spark SQL: A hands-on tutorial | Opensource.com](https://opensource.com/article/19/3/apache-spark-and-dataframes-tutorial)

Azure Databricksでは、urllibにてdbfsにファイルを書き込めたため、Databricks Community Editionの制約のようです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/d3674eb2-70d2-c85b-64d3-0b96aa2237ac.png)

## コードの修正方法について
### 修正前
```python
import urllib

dbutils.fs.mkdirs('/tmp/')
urllib.request.urlretrieve("https://raw.githubusercontent.com/manabian-/databricks-notebook-test/main/README.md", '/dbfs/tmp/README.md')
```

### 修正後
```python
import urllib

dbutils.fs.mkdirs('/tmp/')
urllib.request.urlretrieve("https://raw.githubusercontent.com/manabian-/databricks-notebook-test/main/README.md", '/tmp/README.md')

dbutils.fs.mv('file:/tmp/README.md', 'dbfs:/tmp/README.md')
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/cad35ab4-66e3-b7ad-aee1-b8f5e953e07e.png)

## 注意事項
特になし
AWSのリソースを管理しやすくするVantageを試してみた


TechCrunchさんで紹介されていたVantageが気になったので、試してみました。
https://jp.techcrunch.com/2021/01/15/2021-01-12-vantage-makes-managing-aws-easier/

AWSを使ってると、インスタンス消し忘れて課金が発生したってことはありませんか？vantageはそんな問題を解消してくれるかもしれないサービスです。
https://www.vantage.sh/

# Vantageとは
Vantageは以下の画像のように、AWSで作成したリソースの一覧を表示してくれるサービスです。複数のリージョンをまとめて表示してくれて、1か月あたりのコストも出してくれます。サポートしているサービスとリージョンは[ここ](https://docs.vantage.sh/supported_services/)に載っています。

これはfreeプランの画面ですが、有料だとCloudwatch LogやCloudwatch Metricsをいい感じに出してくれるみたいです。


![screencapture-console-vantage-sh-2021-01-24-18_12_54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/600358/1a59be49-c67e-2e3e-30af-a799e9a19b7a.png)

ひとつひとつの項目はViewと呼ばれていて、自分で作成することもできます。

Topで「Create View」をクリックすると以下の画面でViewを作成できます。「Custom View」ではリソースごとに条件を指定したViewを作成できますし、「View from Tag」ではTagを指定したViewを作成できます。

アタッチされていないEBSや空のS3を表示するといったあらかじめ用意されているViewも追加できます。


![screencapture-console-vantage-sh-views-menu-2021-01-25-23_02_15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/600358/ec240ad4-87ae-8278-6389-52425a65e3d6.png)

「Custom View」は以下のように、表示するリソースの条件を指定します。

![screencapture-console-vantage-sh-views-new-2021-01-25-23_03_09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/600358/08b3caa0-69fa-edb2-0c56-fe817cb12de9.png)

このように、VantageはAWSのリソースとコストをいい感じに管理できるサービスです。

# 導入方法

ここでアカウントを作成します。
https://console.vantage.sh/users/sign_up

アカウントを作成すると、以下の画面が出るので「Connect Vantage to AWS」をクリックします。

![スクリーンショット (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/600358/458eec17-3ee4-9d39-44c9-c37ee0ceda94.png)

そうすると、Cloudformationスタックの作成画面に移動するので、「スタックの作成」を押します。これはクロスアカウントアクセス用のIAMロールを作成します。付与される権限の一覧は以下のページに書いてます。
https://docs.vantage.sh/permissions/

![スクリーンショット (3).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/600358/e357ae96-7b99-f653-5f8b-c4e47f2f3e1f.png)

設定はこれだけです。あとは以下の画面で「Continue」を押せば使えるようになります！
Viewは1時間に1回、自動で更新されます。また、右上の更新ボタンで更新もできます。

![スクリーンショット (7).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/600358/1933dda0-73e3-360d-afa4-88b28f607862.png)

# まとめ
今回は、AWSのリソースを管理しやすくするVantageを試してみました。

設定内容をいろいろと取得されるので、セキュリティ的に大丈夫かなという不安はありますが、readOnlyなのでたぶん大丈夫なんじゃないかと思います。（自己責任）

今後、Viewをシェアする機能やアラートを送る機能などがいろいろ追加されるようです。

気になった方は試してみてもよいかと思います。
[devise] 新規登録/ログイン [DBに値を保存するまで]


①Gemfileにgem 'devise'追記　→　bundle install　→　サーバー再起動
②% rails g devise:install実行で、devise関連ファイルを自動生成
③% rails g devise user実行で、Userモデル作成（同時にroutes.rbにdevise_for :users自動追記）
④マイグレーション作成（email, encrypted_password はデフォルトで設定されています）
⑤マイグレーション実行（usersテーブル作成）　→　サーバー再起動
⑥% rails g devise:views実行で、deviseにのビューファイルをコピーし、app/viewsに持ってくる
⑦持ってきたviewsを編集（form_withでモデルクラスのインスタンスを引数に指定）
⑧パスを指定し、ブラウザにviewsを表示（<%= link_to "テキスト", path %>）
⑨↓application_controller.rbでパラメーターを許可　

```application_controller.rb
class ApplicationController < ActionController::Base
  before_action :configure_permitted_parameters, if: :devise_controller?

  private
  def configure_permitted_parameters
    #新規登録時のストロングパラメータに「追加したいカラム」を設定
    devise_parameter_sanitizer.permit(:sign_up, keys: [:nickname])
  end
end
```
deviseでログイン機能を実装した場合は、paramsの他に、devise特有のパラメーターも受け取っているため、コントローラーで許可してあげる必要があります。
devise_parameter_sanitizerメソッドは、deviseにおけるparamsのようなメソッドです。
deviseの「ログイン」「新規登録」などのリクエストからパラメーターを取得できます。


before_action :configure_permitted_parameters, if: :devise_controller?は、
deviseのコントローラーだったら（devise_controller?というメソッドの返り値がtrueだったら）configure_permitted_parametersを呼び出すという意味の記述です。

application_controller.rbにdevise_parameter_sanitizerを書いているので、
before_actionで:configure_permitted_parameters, if: :devise_controller?を設定（全てのコントローラーでdeviseのコントローラーかどうかを事前に審査）します。

これでDBに値が保存できたのではないでしょうか？
SQL  DELETE, TRUNCATE, DROP

#【SQL  DELETE, TRUNCATE, DROP】

DELETE文とDROP文の違いを明確にしたくて学習しました。
業務でSQLを書けるのが楽しいです。
まずは、基本をしっかり習得していきます。

過去に投稿した記事。
[SQL 一般的には大きく3つに分類される。](https://qiita.com/uejima_haruki/items/632857ce7e21a4a8936d#dmldata-manipulation-language-%E3%83%87%E3%83%BC%E3%82%BF%E6%93%8D%E4%BD%9C%E8%A8%80%E8%AA%9E)


##DELETE文

<strong>DML</strong>である。

テーブル内のデータを削除する。
（WHERE句で条件指定しない場合には、全削除される。）

→1レコードずつ順番に削除されるイメージ（?）

```sql
DELETE FROM table_name;
```

##TRUNCATE文

<strong>DDL</strong>である。

テーブル内のデータを全削除する。
（WHERE句で条件指定出来ない。）

→一気に全レコード削除されるイメージ（?）
　そのため、DELETE文より高速なのか。

```sql
TRUNCATE FROM table_name;
```

##DROP文

<strong>DDL</strong>である。

テーブル内のオブジェクトを完全に全削除する。

```sql
DROP FROM table_name;
```

##まとめ 自分なりの使い分け。

DELETE文は、削除したいレコードがある時にWHERE句ありで使用する。削除条件がある時に使用する。
DROP文は、テーブルそのものを削除したい時に使用する。
TRUNCATE文は、テーブルそのものは残しつつ、レコードを全件削除したい時に使用する。
（最適な使いどきがわかっていない。。）

※まだまだ知識が浅いことは承知しております。
みなさま、もし何かありましたら<strong>ご指摘頂けるととても嬉しいです。</strong>
今後も自分で考えてみることを実践して学んでいきます。
【Qiita投稿作成のデザイン（小学生でも分かる解説）Markdownの無効化方法】

#Qiita投稿作成のデザイン
Qiitaの投稿作成が楽しいのは、`簡単だから！`

なぜ簡単か？
記号をつけるだけでデザインが変わってくれるから。
Markdown記法というらしい。

実はこれ、プログラミングと同じ。
でも、Qiitaの方が簡単な理由はこんな感じ。

・書く量が少なくてすむ
・１画面に収まる

例えば、文字の後ろ背景をグレーにしたかったとき。

**□プログラミングの場合**（ここではHTML・CSSもプログラミング言語として多めに見て。。）

```gray.html
<div class="gray">グレー</div>
```

```gray.css
.gray {
background-color:gray;
}
```

**結果**
`グレー`

**□Qiitaの場合**
\`グレー\`

**結果**
`グレー`

書く量が違いすぎて、、、
さらに違うところに書かないといけなかったり、、、（辛）

そして、この投稿を書いている中で学んだ。
上のQiitaの場合の「　\`グレー\`　」を書くと、後ろがグレー色に変換されてしまう。。。
つまり、勝手に変換されて、「　\`　\`　」この点々が消えてしまうと。。

この世界一大問題は、今までの人生でほとんど見たこともない、そしていまだにどうやってキーボードから入力できるのかもわからない記号

`「　\　」`

こいつで解決した。
「バックスラッシュ」っていうらしい。

これを記号の前に置いたら、その記号の効力をなくすことができる！（攻撃の無力化：遊戯王）

だからこう書いたら上手くいった。

```
\`グレー\`
```

あまりにも話が飛んでしまった。
とりあえず投稿にデザインつけるのは簡単で、
今のみたいなイレギュラーだけ調べられれば大丈夫。

その他のたいていの基本的な記述に関しては、公式が分かりやすい。

**[公式のMarkdown記法　チートシート]**
[公式のMarkdown記法　チートシート]:https://qiita.com/Qiita/items/c686397e4a0f4f11683d

それでは。
エラー「Application tried to present modally a view controller」の時

## 環境
・Xcode: 12.3
・Swift5

以下のようなエラーログがでてクラッシュしてしまった時

```swift:
libc++abi.dylib: terminating with uncaught exception of type NSException

*** Terminating app due to uncaught exception 'NSInvalidArgumentException',
 reason: 'Application tried to present modally a view controller <ProjectName.ViewController: 0x158331780> 
.that has a parent view controller <UINavigationController: 0x159877a00>.'
terminating with uncaught exception of type NSException
```

### こんなパターンがあるよ
![スクリーンショット 2021-01-25 23.26.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/656690/6677f818-394e-87eb-1ca5-671018f3083c.png)

上記のようにViewControllerに対してNavigationControllerがいる場合に、
ViewControllerを表示しようとしてしまっている可能性

```swift:

        let storyboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
        if let navigationVc = storyboard.instantiateInitialViewController() as? UINavigationController,
           let viewController = navigationVc.topViewController as? ViewController {
            // これは×
            // present(viewController, animated: true, completion: nil)
            // これは○
            present(navigationVc, animated: true, completion: nil)
        }
```

これに限らないかと思いますが、誰かの役に立てば。
開発環境構築

## まえがき

自前の開発PCと社用のPCでアプリケーション等を揃えるついでに記事にしました。

## アプリケーション

### homebrew

```bash
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
brew update && brew cleanup
```

※ githubがなんちゃらというエラーが出る場合は下記のコマンドを実行する。

```bash
git config --global --unset http.proxy 
git config --global --unset https.proxy
```

### homebrew-cask

CLIでアプリケーションをインストールできるようになります。

[https://qiita.com/swallowtail62/items/61244ea3c7d00f692823](https://qiita.com/swallowtail62/items/61244ea3c7d00f692823)

```bash
brew tap homebrew/cask
```

homebrewもcaskも含め、ここで検索できます。

[https://formulae.brew.sh/](https://formulae.brew.sh/)

### iterm2

ターミナルアプリです。

```bash
brew install --cask iterm2
```

### Google Chrome

```bash
brew install --cask google-chrome
```

### Google日本語入力

USキーボードでの簡単な切り替え方法は別途記事を用意しました。

[https://qiita.com/takeucheese0704/items/687ff9700280b221502c](https://qiita.com/takeucheese0704/items/687ff9700280b221502c)

```bash
brew install --cask google-japanese-ime
```

```bash
brew install --cask karabiner-elements
```

### JetBrains製のIDE

お好きなものをインストールしてください。

```bash
brew install --cask intellij-idea
brew install --cask phpstorm
brew install --cask goland
brew install --cask webstorm
brew install --cask datagrip
```

### Notion

メモとったり、タスク管理したりできます。

記事の外部公開もできるので是非。

```bash
brew install --cask notion
```

### Postman

APIクライアントです。開発時に使ったり外部のAPIを実行するのに使います。

```bash
brew install --cask postman
```

### SourceTree

Gitクライアントアプリです。CLIを使う強い理由がない場合はこちらを使っていきましょう。

```bash
brew install --cask sourcetree
```

### Sequal Pro

普通に入れるとちゃんと動かないので注意すべし。

[https://mom0tomo.github.io/post/sequel-pro-nightly/](https://mom0tomo.github.io/post/sequel-pro-nightly/)

[https://qiita.com/yasudanaoya/items/2112e13e2ba164bdf47c](https://qiita.com/yasudanaoya/items/2112e13e2ba164bdf47c)

```bash
networksetup -setv6off Wi-Fi
brew install --cask homebrew/cask-versions/sequel-pro-nightly
networksetup -setv6automatic Wi-Fi
```

### Visual Studio Code

JetBrains製のエディタとNotionあれば使うこと少ないですが、一応。

```bash
brew install --cask visual-studio-code
```

### Docker

ローカル環境構築に必要。

```bash
brew install --cask docker
```
JavaScript 関数の省略記法おさらい

引数を渡すと 1 足した数を返却する add 関数（以下）を例に説明する。

# 昔の基本系（未省略）

```JavaScript
function add(x) {
  return x + 1;
}
```

補足：JavaScript (ECMAScript) は年々仕様がアップされて便利になっています。これは昔の基本系で、2015 年（ ES2015 ）からアロー関数という記法が仕様策定されていますので、アロー関数を使いましょう。アロー関数は省略の意味があるだけでなく、よりバグが混入しにくい仕組みを備えています。

# 1. 基本系（省略）
アロー関数化（ ES2015+ ）により `function` 文字列が省略可能

```JavaScript
const add = (x) => {
  return x + 1;
};
```

# 2. 更成る省略
引数が 1 つの場合は引数の括弧が省略可能

```JavaScript
const add = x => {
  return x + 1;
};
```

# 3. 更成る更成る省略
関数内処理が `return` のみの場合は `return` 文字列と波括弧が省略可能

```JavaScript
const add = x => x + 1;
```

# おわりに

超サイヤ人もこんな感じだったような。
JavaScript 書き慣れていきましょう。
Salesforce force:auth:device:login is not a sfdx command

# 概要

sfdxの7.83.0（7.82.0は問題なし）から上記のエラーが表示されるようになりましたので、対処方法について以下にメモします。
また上記のエラーのみならず、`force:auth:xxx`の[すべてコマンド](https://developer.salesforce.com/docs/atlas.en-us.sfdx_cli_reference.meta/sfdx_cli_reference/cli_reference_auth.htm)が上記のようなエラーになります。

# 対象法

[authプラグイン](https://www.npmjs.com/package/@salesforce/plugin-auth)を別途追加すること、以上！

```
> sfdx plugins:install auth
```
shellプログラミングの書き方と実行、デバック方法

業務で覚えた知識を備忘録として記載していきます。

# 対象者
- 初めてshellスクリプトを書く人
- shellの実行方法とか忘れた人

shellスクリプトの書き方と実行方法について、少し間が空くとすぐに忘れてしまうので備忘録として作成。shellの基本的な書き方と実行方法について記載していきます。

# やりたいこと
+ ゼロベースでshellスクリプトを作り実行する。
+ 実行時にエラーが出た場合はエラー個所を把握して修正できるようになる。

# 作業環境
Ubuntu　VERSION="20.04.1 LTS (Focal Fossa)"
Windows環境でも簡単にLinuxコマンドが練習出来て便利ですね。

# 絶対に必要な記述
```sample.sh
#!/bin/bash
```
冒頭にこの記述は絶対に必要となります。
絶対に必要な割にコピペして作る機会が増えるとスペルミスが増えるので間違えずに！

先ほどの宣言の後は基本的に何を書いてもOKです。
Linuxのコマンドを打って実行できることは何でも実行可能になります。（多分）

```sample.sh
#!/bin/bash

echo "処理開始"
# echoで文字出力したりとか
date +'%Y%m%d'
# Linuxのコマンド結果は動作可能です。
```
ちなみに「#」で囲っている文字はshellの中では処理対象として認識されません。
これから実行するプログラムの説明概要を書いたり、一時的に記述した内容を無効にしたい場合などに利用します。
行いたい処理を記載したら名前を付けて保存します。
この時、拡張子はなくてもよいのですが、慣習的に「.sh」が使われる事がほとんどのようです。


# 実行、デバック方法
「.sh」でファイル保存したら次は実行方法についてです。
実行する場所はどこでもいいです。自分が今いる階層にファイルがなくても、実行時にパスを書いてあげれば動かすことは可能です。
実行方法は1つではありませんが、私がよくやるやり方は「sh -x sample.sh」といったやり方です。この実行方法だと、shellの中で定義した変数が確認できたりと色々と便利です。特に処理が複雑になってくるとどこのミスがあるのか見つけるのも大変なので実行結果が返ってくるよりも良いです。

```sample.sh
#!/bin/bash
TODAY=`date +'%Y%m%d'`
echo "処理開始"
$TODAY
```

shell実行

```
$user sh -x sample.sh
```

実行結果

```
+ date +%Y%m%d
+ TODAY=20210125
+ echo 処理開始
処理開始
+ 20210125
sample.sh: 4: 20210125: not found
+ exit
```
「+」以下の内容は通常の実行では見れない情報です。今回の処理では4行目の処理で異常があることがわかります。
こうした以上は実行結果の戻り値を拾ってもみることが出来ます。
コマンド実行した後に「$?」と打つと、実行したコマンドの戻り値が見れます。「0」以外は異常終了したことを示します。
逆に言えば「0」が出てれば正常に終了したことを意味します。
これを利用して処理の結果にif判定で「0」が返ってきたかを見て正常かどうかを判断することが出来ます。

```sample.sh
#!/bin/bash
TODAY=`date +'%Y%m%d'`
echo "処理開始"
$TODAY
if [ $? -ne 0 ];then
　echo "$TODAYは異常終了しました"
　exit 1
fi
echo $TODAY
exit
```
shell実行

```
$user sh -x sample.sh
```
実行結果

```
+ date +%Y%m%d
+ TODAY=20210125
処理開始
+ 20210125
sample.sh: 4: 20210125: not found
+ [ 127 -ne 0 ]
+ echo 20210125は異常終了しました
20210125は異常終了しました
+ exit 1
```

戻り値が「0」ではないので異常終了していることがわかりました。
ちなみにこの処理では4行目で「＄TODAY」と記載していることが原因です。
＄TODAYをecho ＄TODAYと直すと以下となります。

```sample.sh
#!/bin/bash
TODAY=`date +'%Y%m%d'`
echo "処理開始"
echo $TODAY
if [ $? -ne 0 ];then
　echo "$TODAYは異常終了しました"
　exit 1
fi
exit
```

```
+ date +%Y%m%d
+ TODAY=20210125
+ echo 処理開始
処理開始
+ echo 20210125
20210125
+ [ 0 -ne 0 ]
+ exit
```

どこが悪いのかがわかりやすいですね。
どこにでもあるのに、少し見ないとすぐ忘れてしまうshellの書き方と実行方法についてでした。
ElectronのcontextBridgeで値の受け渡し

# はじめに
備忘録として適当にここに載せておきます。
ElectronのcontextBridgeを使い、下記のコードでデータ(JSON等)の受け渡し等が出来るのではないかと思います。
この記事はElectronを始めて2日目に書いた記事です。
間違っているかもしれません。

#コード
```javascript:main.js
/*レンダラープロセス側
任意の値をpreloadへ渡す
*/
console.log(pr_test.show_data);
var button = document.getElementById('button1');
   button.addEventListener("click",function(){
       var test = "TEEEEEEEEST";//任意の値
       pr_test.api.add_glist(test);//preloadへ渡す
   })
```
```javascript:preload.js
//preload側
const fs = require('fs');
const { contextBridge, ipcRenderer} = require("electron");
contextBridge.exposeInMainWorld(
    "pr_test", {
      show_data: () => { return(fs.readFileSync(__dirname+'/json/test.json', 'utf8'))},//JSONをレンダラ側へ渡す
      add_data: (test) =>{new Notification(test);}//レンダラ側から受け取った値をOS側で通知する
    }
  );
```
Linuxコマンド　(初心者向け)

##Linuxコマンドとは
簡単に言えば、コンピューターに命令をする事。
それをターミナルとシェルを使って行う。
##シェルとターミナル
####ターミナル　　
ターミナルは主に画面担当。

####シェル
コマンドを解釈してLinuxとやりとりする担当。

###主な流れ

ターミナル上でコマンド入力すると、シェルが命令を解釈して、Linuxに伝え、Linuxがコマンドを実行して、シェルがコマンドの実行結果をターミナルで画面に表示させる。

##これだけは抑えておきたいコマンド


###lsコマンド
現在いるディレクトリの中のファイルなどを表示してくれる。

###pwdコマンド
今自分がいるディレクトリを表示してくれる。

###cdコマンド
ディレクトリを移動するコマンド。

###mkdirコマンド
mkdir+新規のディレクトリ名でディレクトリを作成する事ができる。

###touchコマンド
touch+新規のファイル名でファイルを作成する事ができる。

###echoコマンド
echo Hello > new
こうする事でnewファイルにHelloと書き込む事ができる。

###catコマンド
ファイルの中の記述を確認する事ができる。

###lessコマンド
catコマンドと同じでファイルの中の記述を確認する事ができる。
唯一の違いは、全画面で表示する事ができる。よって、ファイルの中身が長い時はlessコマンドを使う方が良い。

###mvコマンド
mv 古いファイル名　新しいファイル名
これで古いファイルを新しいファイルに変更する事ができる。

###rmコマンド
ファイルを削除する事ができるコマンド。
antilatecyというトラッカーについて

#antilatencyとは
![logo.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/939279/4ff32146-871f-6cd0-8e9c-a474ed87880e.png)
ロシアのベンチャー企業、antilatencyが開発したVR/AR用モーショントラッカー。
6DoFで様々なHMDやエンジンに対応し、スケールやシェイプに制限される事のない汎用性に優れた開発キットである。

###デバイス

###○ALT(AntilatencyTracker)
![alt.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/939279/5708c33a-cd9e-5c5d-1379-bec76b2b2d46.jpeg)
トラッカー本体。
カメラがマーカーから照射される赤外線レーザーを検知する。
約12gの超小型。ただし単体では使用不可。
###○Socket
ソケットにALTを装着して、マシンに接続することでトラッカーとして使用できる。
*使用する場合、最低一つのソケットは必ずマシンと有線接続してホストにする必要がある。
#####・Wired USB Socket
![usb.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/939279/7d42f771-0e9f-3095-9e9b-bf4fc1f10dc6.jpeg)
USBで繋いだまま使う有線式。
#####・HMD Radio Socket
![radio.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/939279/ec4126b0-b250-65de-510b-ce7ee964e42f.jpeg)
別ソケットとワイヤレスで接続できる送信用ソケット。
#####・Tag
![tag.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/939279/6cf89987-c298-58a4-97ca-dc875152965e.jpeg)
ワイヤレス受信用ソケット。
#####・Bracer
![bracer.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/939279/8d706275-6a5d-88c6-d024-f8143627a4b7.jpeg)
手をトラッキングするソケット。これを使うことで指の動きまで検知し、バーチャル空間のオブジェクトに触れたり掴んだりすることが可能になる。

#ALTトラッキングシステム
バーに赤外線レーザーを照射する位置マーカーが搭載されていて、決まった形で床に敷くとALTがマーカーから位置情報を読み取る。ユニットは組み立て式で、バーを追加することで領域を広げることができる。

#特徴
・コンパクトなユニット、屋外でも使えて持ち運びも便利。
・可動範囲の制限が実質無し。


これから触って動作など勉強するので、使用方法については後日まとめたいと思います。
詳しい情報が分かり次第、この記事でも随時更新していきます。
railsのバリデーション

#バリデーションとは
正当性を実証（確認）すること。
例えば、新規登録フォームでユーザー名が入力されていなかったら登録できない、
メールアドレスが正規の型でない等を検知する。

#新規登録時に名前、メールアドレスが入力されているか検証する
app/models/user.rbファイルに記入する。
validatesメソッドに presence:trueという引数を与えて使うことで検証できます。

```ruby:app/models/user.rb
class User < ApplicationRecord
  validates :name, presence: true
  validates :email, presence: true
end
```

#長さを検証する
上記のコードにlenghtを追加します。
今回は名前を50文字、メールアドレスを255文字を制限とします。

```ruby:app/models/user.rb
class User < ApplicationRecord
  validates :name,  presence: true, length: { maximum: 50 }
  validates :email, presence: true, length: { maximum: 255 }
end
```

#フォーマットを検証する
メールアドレスにおなじみのパターンuser@example.comに合っているかを検証します。
無効なメールアドレスにはマッチしない正規表現を組み立てる必要があります。
正規表現とは、一定の規則に従って特定の文字列（群）を集合の要素として表す表記法。
コンピューターで，テキスト処理に使われる。
正規表現がこちら。
/\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i

暗号みたいでわかりずらいので表を置いときます。

|正規表現|意味|
|---|---|
|/\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i|（完全な正規表現）|
|/|正規表現の開始を示す|
|\A|文字列の先頭|
[\w+\-.]+|英数字、アンダースコア（_）、プラス（+）、ハイフン（-）、ドット（.）のいずれかを少なくとも1文字以上繰り返す
|@|アットマーク|
|[a-z\d\-.]+|英小文字、数字、ハイフン、ドットのいずれかを少なくとも1文字以上繰り返す|
|\.|ドット|
|[a-z]+|英小文字を少なくとも1文字以上繰り返す|
|\z|	文字列の末尾|
|/|	正規表現の終わりを示す|
|i|	大文字小文字を無視するオプション|

```ruby:app/models/user.rb
class User < ApplicationRecord
  validates :name,  presence: true, length: { maximum: 50 }
  VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
  validates :email, presence: true, length: { maximum: 255 },
                    format: { with: VALID_EMAIL_REGEX }
end
```

#一意性を強制
メールアドレスの一意性を強制するために、validatesメソッドの:uniquenessオプションを使います。
uniquenessは登録されているメールアドレスは登録できないことを検証します。

```ruby:pp/models/user.rb
class User < ApplicationRecord
  validates :name,  presence: true, length: { maximum: 50 }
  VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
  validates :email, presence: true, length: { maximum: 255 },
                    format: { with: VALID_EMAIL_REGEX },
                    uniqueness:true
end
```

##email属性を小文字に変換してメールアドレスの一意性を保証
emailを小文字に変換はemail.downcaseを使います。
今回の場合は、オブジェクトが保存される時点で処理を実行したいので、before_saveというコールバックを使います。
ユーザーがデータベースに保存する前にemail属性を強制的に小文字に変換します

```ruby:app/models/user.rb
class User < ApplicationRecord
  before_save { self.email = email.downcase }
  validates :name,  presence: true, length: { maximum: 50 }
  VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
  validates :email, presence: true, length: { maximum: 255 },
                    format: { with: VALID_EMAIL_REGEX },
                    uniqueness: true
end
```
typescriptのtscコマンドが使えない時

```npm install -g typescript```でtypescriptをグローバルにインストールしたらtscコマンドが使えるらしいのですがnot foundになると言う洗礼を受けたのでエラーの対処法をシェアします。

#.bash_profileにパスを通す

結論から言うとpackage.jsonの```scripts```に```"tsc": "tsc"```を追加し、.bash_profileに対象プロジェクトのパスを通したら無事tscが機能しました。

下記のやり方を参考にしました。
>[【zsh, bash】macでPATHを通す方法 - not found と出てしまったら](https://qiita.com/k3ntar0/items/eb8cdbd8eba9da388def)

- 前提としてnode.jsはインストールされてるものとします。

1. まずpackage.jsonのscriptsに```"tsc": "tsc"```を追加します

2.```vi ~/.bash_profile```で.bash_profileを開きます。viとして開くのはコマンドが機能してるのが分かりやすいからです。

3.```export PATH=$PATH:対象プロジェクトのパス名```を追記して、```source ~/.bash_profile```で変更を反映させ、```:wq```で保存して終了させます。
直接入力したい場合はiでインサートモードにしてescでコマンドモードにして実行します。

>[viのコマンドについてはこちら](https://rat.cis.k.hosei.ac.jp/article/rat/serverliteracy/2004/vi.html)

これでtscコマンドが実行できるはずです！


#補足

グローバルでtypescriptをインストールすると後々パスを設定するのが面倒なのでcdコマンドで予めパスを指定してからインストールするのも一つの手ではあると思います。


下記サイトも参考にしました。
https://qiita.com/Yanase-Takuma/items/44c4d164dc134d0af939
モデルとテーブルについて

#目次
<b>①モデルとは</b>
<b>②テーブルとは</b>
<b>②モデルの作成方法</b>
<b>④テーブルの作成・編集方法</b>

##①モデルとは
MVCモデルの役割の一つ。データベースにアクセスすることができ、あらゆる情報に関する処理をすることができる。モデルがあることによって、データベースにあるテーブルも管理ができるようになる。各テーブルは各モデルに対応しており、モデルとにテーブルを管理できる。

##②テーブルとは
データベース内に作成されるデータを表形式で収納するもの。データベースに各用途におうじてテーブルが存在して、必要となればそのテーブルからデータを抽出することができる。

##③モデルの作成方法
```
rails g model person
#モデルの作成、モデルは単数形
```

##④テーブルの作成・編集方法
モデルを作成後、それに対応するテーブルは出来上がる。ただ、まっさらなテーブルの状態で、どのような情報を入れたいかなどの設計がなされていない状態である。それを設計するために、マイグレーションファイルに以下のように記述し、コマンドを実行するとテーブルに反映される

```
class CreateHumans < ActiveRecord::Migration
 def change
  create_table :humans do |t|
    t.integer :age ←記述
    t.name :name　←記述
    t.timestamps
   end
 end
end
```

上記のマイグレーションをテーブルに反映させるには以下のコマンドを実行する

```
rails db:migrate
#マイグレーションをテーブルに反映
```

もしテーブルの使用を変更したいときは、

```
rails db:rollback
```
をすると前の状態に戻るので、マイグレーションファイルを正しい情報に書き換えたのちにrails db:migrate
をするとまたテーブルに反映される。
【初心者向け】クラウドサービスの概要一覧(AWS, GCPの違い)

クラウドサービスの勉強にあたり、名前を聞いただけではどんな機能か想像がつかない…

…ということで、代表的なクラウドサービスであるAWS(Amazon Web Service)とGCP(Google Cloud Platform)で提供されている機能について、一覧表を作って概要を知ることにしました。

| 機能概要 |AWS | GCP | メモ |
| ------ | --- | --- | --- |
|アカウント管理・アクセス制御 | IAM<br>(Identity and Access Management） | IAM<br>(Identity and Access Management) | AWSもGCPも呼び名や機能概要は同じ |
| ストレージ | S3<br>(Simple Strage Service) | GCS<br>(Google Cloud Strage) | ファイルを保存できる |
|仮想マシン |EC2<br>(Elastic Compute Cloud) | GCE<br>(Google Compute Engine) |仮想サーバ。AWSで出てくるElasticは「伸縮自在」の意。柔軟に性能や台数を変えられる。|
| ロードバランサ |ELB<br>(Elastic Load Balancing) | CLB<br>(Cloud Load Balancinge) | 複数仮想マシンを使用する場合の負荷分散 |
|サーバ不要のプログラム実行環境 |laｍbda | GAE<br>(Google App Engine) | 得意な言語で関数を実行できる |
|データベース<br>(RDB) |RDS<br>(Relational Database Service) | Cloud SQL | MySQL,PostgreSQL,SQL ServerなどRDBMSを利用可能 |
| NoSQL |DynamoDB | Cloud Bigtable | NoSQLなので複雑な検索には向かないほうのデータベース |
| リソース監視 |CloudWatch | Monitoring | CPU使用率とかモニタリングできる |
| ログ収集 |CloudWatch Logs | Logging | ログを収集して閲覧できる |

AWS・GCPそれぞれ似た機能があるので、片方に慣れれば応用が効きそうですね。
他にもたくさん機能があるので、適宜追加しようと思います。
【RaspberryPi】起動確認用LEDをpython、systemctlを使って制御

#概要
RaspberryPiの起動が完了するとLEDが点灯する機能を追加
※LEDは11ピン（GPIO17)に接続

#実行環境
MCU：Raspberry Pi Zero W
OS：Raspberry Pi OS Buster

#回路
回路図省略
電流制限抵抗は明るさを抑えるために2.2kΩを使用

#実装
##pythonプログラム
LEDの点灯制御をするためのpythonプログラム

```terminal
$ sudo nano /home/pi/PowerLED.py
```

最終行にsleep()を入れるとpythonプログラムが終了してもLEDが点灯しっぱなしになる
綺麗な方法ではないが、バックグラウンドで動くプログラムを節約したいので暫定的にこれで実施

```python:PowerLED.py
#!/usr/bin/python3

import RPi.GPIO as GPIO
import time

LED_PIN = 17

GPIO.setmode(GPIO.BCM)
GPIO.setup(LED_PIN, GPIO.OUT)

GPIO.output(LED_PIN, GPIO.HIGH)
time.sleep(3)
```

##serviceファイル
systemctlで制御するためのserviceファイルを作成
パラメータは最低限にしているので、これより減らすと色々問題が起こるかも


```terminal
$ sudo nano /lib/systemd/system/PowerLED.service
```

他サイトではshebangを使用・serviceファイルのExecStart行ではファイル名のみを記載する方法も紹介されていたが、上手くいかなかったのでserviceファイル上でpython3を指定(フルパスで指定しないとエラーになる)
その他のパラメータについては別記事に記載

```PowerLED.service
[Unit]
Description = Power LED of Startup
After=multi-user.target

[Service]
ExecStart=/usr/bin/python3 /home/pi/App/PowerLED.py
Restart=on-failure
Type=simple

[Install]
WantedBy=multi-user.target
```

#serviceの設定
動作確認

```terminal
$ sudo systemctl daemon-reload
$ sudo systemctl start PowerLED
～LEDが点灯したらOK～
```

RaspberryPi起動時に自動起動するよう設定

```terminal
$ sudo systemctl enable PowerLED
```
社会人2年目終盤になってやっとQiitaを始めてみる

# 始めるに至った経緯
社会人になって気づけば2年、会社の業務をこなすことにも慣れてきて自分のスキルアップをしたくなってきたので備忘録としてQiitaを始めてみる

## Qiitaを使う目的
備忘録(今のところ)

## 専門
1. 電気電子
2. プログラミング(←仕事のメイン)
3. 機構設計

## 今までやってきたこと
- 電子工作
- 電子回路設計
- Python
- JavaScript
- C++

## やりたいこと
- 筋電取得による筋トレの負荷の取得
- 自分の本棚を管理するアプリ(LINEなどと連携できるとなおよし)
- 家の中のリモコンを携帯から操作可能にする
- 他にもいろいろ

## 目標
1週間に1回は記事を書く
udemy教材によるAWSの学習①

#udemyの教材
本記事を作成するにあたって、参考にしたudemyの教材は以下のものになります。

これだけでOK！ AWS 認定ソリューションアーキテクト – アソシエイト試験突破講座（SAA-C02試験対応版）
https://www.udemy.com/share/101WKk/

#受講の目的
私はアプリを開発して、始めたいサービスがあります。
そのアプリでは動画を保存する必要があり、堅牢なサーバが必要となります。

どうにかならないかと調査していた時に、AWSのS3というファイルサーバを使えば、セキュリティ的にも容量的にも解決できることを知りました。

本講座で、AWSについて情報収集をし、アプリ開発に生かす予定です。

#AWSとは
Amazon Web Serviceの略。
全部で175を超えるサービスがあり、毎年12月のイベントにて、新たなサービスの発表も行われている。

#AWSの仕組み
AWSはインフラ/システム機能をブロックパーツのようにオンライン上で組み合わせて、自分の好きな構成を実現する仕組み。

##アンマネージド型
スケーリング/耐障害性/可用性を利用者側で設定し、管理する必要がある。

###メリット
設定が柔軟に可能。

###デメリット
管理が面倒。

###サービス例
EC2(サーバ)

##マネージド型

###メリット
管理が楽。

###デメリット
設定が限定的。

###サービス例
Route53(DNS)

#クラウドの意義
AWSクラウドを利用することで、即座にインフラを構築することができる。
従来のオンプレミスに比べて、事業を始めやすくなった。
しかし、運用費はかかるため、注意が必要。

#AWSのグローバルシェア
AWSは長年3割以上のシェアをキープ。
圧倒的な存在である。
他サービスとしてはMicroSoftのAzureがある。

#①のまとめ
①ではAWSについてざっくりと記載しました。
【初心者でもわかる】縦横画面いっぱいに画像を綺麗に表示する方法

# どうも7noteです。画像が画面いっぱいに入っているファーストビューを作ります。

画面いっぱいに画像が入っているサイトって、オシャレじゃないですか？
ただ綺麗に作るためには画像の選別からCSSの書き方までちょっとした工夫や知恵が必要です。
そのような細かいところを解説できればと。

## 画像を画面幅と高さいっぱいにする方法

```index.html
<div class="first_view"><img src="image.jpg"></div>
```

```style.css
.first_view {
  width: 100vw;     /* 画面幅いっぱい */
  height: 100vh;    /* 画面高さいっぱい */
}
.first_view img {
  object-fit: cover;/* 要素いっぱいに画像を表示（はみ出た部分は削除） */
  width: 100%;      /* 親要素の幅いっぱい */
  height: 100%      /* 親要素の高さいっぱい */
}
```



※ IE非対応です。対応させるにはjsを導入するとOK。
過去に書いた[関連記事](https://qiita.com/7note/items/d8908d9eae046f40ad74)

### 気を付けるべきポイント

・人がメインの写真はトリミングされることを前提に考える
・元画像に切れてもいい余裕がない

これが一番あるあるです。この画像使ってくださいと言われた画像が、人物メインの写真だったり、淵の背景部分（切れてもいい部分）が短いとトリミングした時に上手く見れません。
特にPCとスマホで同じ画像の場合、PCは横長ですがスマホは縦長になってしまいます。

**うまくいかない例**

PC
![pc.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/661092/d0be5ebc-6718-0634-462d-b4c41b5666b4.png)


スマホ
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/661092/7acfa3eb-a1c3-bbbd-ea57-e4c0e20cc4f6.png" width="200"/>


これではスマホで見たときに顔の部分が切れてしまうかもしれません。
このようにPCで綺麗に見えていても、スマホでは悲惨なことになる場合も・・・
スマホだけは違う画像を使う等の対策が必要です。

他にも以下の点についても気をつけたいところです。

※画像サイズが極端に小さい
※綺麗に見せるポイント

## うまく見せるコツ

いろいろコツがあります。

**・トリミングの中心位置を指定する**
object-fitにはpositionの指定ができます。これで切れさせたくない位置を中心にトリミングができます。

**・荒い画像は、画像の上に半透明のフィルターをかます**
荒い画像をわざと荒く見せて、画像そのものの粗さを軽減させる手法です。

**・背景色を入れて切れても大丈夫なようにする**
切れてもいい場所は背景色として、画像の部分が切れないような加工した画像を使うといいですね。

**・画面いっぱいをあきらめて、画像の縦横比を固定する**
どうしてもこの写真で！ということがあるのであれば、全画面は諦めて縦横比を固定した要素を作って、その中に画像を入れましょう。


##まとめ

コーディングのときに気をつけたいポイントは、**どこまで想定して作り込めるか**だと思います。
パット見で製作環境のPCで見ていて綺麗にできていても、他の環境ではどうにもうまく見えていないなんてことにならないように、実機で確認したり、シミュレーションツールを使って細かく様々なパターンを検証して作り込んで行きましょう。

#### おそまつ！
~ Qiitaで毎日投稿中!! ~
[【初心者向け】WEB制作のちょいテク詰め合わせ](https://qiita.com/7note)
schema.rbの内容が変だと思ったら

削除したブランチで作っていたテーブルがschemaから消えない。。なぜ。。
パニックになりメンターに質問しました。

結論これを打てば直りました。

```言語:
rails db:migrate RAILS_ENV=test
```

データベースが3つ（開発環境、本番環境、テスト環境）ある中のテスト環境のデータベースと同じにしてくれるおまじないみたいなものだそうです。


そもそも、
テーブルの名前を変更するのはあまりよろしくない事！（壮大なアプリとかじゃない場合は作り直す事）
てかそもそもマイグレーションファイル作ってマイグレートしたらコミットしておく事！
マイグレーションファイルは手動では消しちゃダメな事！
と教わりました。


ちなみに

```言語:
rails db:rollback STEP=2
```



と打てば最新から数えて2つ目までのmigrationファイルを編集できるようにdownできる

ちょっと間違えちゃった時とかはこのコマンド打って、migrationの中変えられる


schema.rbがこうなることはよくあることだと聞きました。
スクール生の間にいい経験になりました。。
猫でもわかるコンテナと仮想化_ネコンテナ（１）

# 初めに
コンテナに関する技術本がいっぱい出ております。しかしどの本を見ても難しい。
必要な情報以上の情報が出ているためさらにわからなくなってしまっている状況です。そのため本記載では本当に簡単に最小限だけの知識でコンテナ技術に関する知識をつけていこうと思います。

## コンテナと仮想化で覚える３つ
1. コンテナというのは仮想化技術の一つ
2. コンテナという箱に分割するのは大変
3. コンテナといえばdocker


はい、コンテナと仮想化で覚える必要がある三つはこれだけです。ほかは今後考えてください。これから後は詳細を記載しますが、この回で覚える必要があるのは上の3つだけです。

## 1. コンテナというのは仮想化技術の一つ
コンテナというのは仮想化技術の一つです。はい難しい言葉ですが、仮想化です。クラウドとかVMとかいろいろな話が出てきます。イメージ重視でいきます。
![仮想化.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/590346/e6090e72-a39a-a736-5ad6-c6f92aacf786.png)

ゲーム機で昔のゲームが遊べると思います。今のゲーム機に物理的には入りません。これは一種の仮想化です。仮想化技術を使って今のゲーム機の中で昔のゲームができるようにしております。


## 2. コンテナという箱に分割するのは大変
コンテナという個別の箱に分割すればきれいに見えます。
しかし現在は棚がない状態で箱（コンテナ）が便利だという話をよくしています。段ボール箱みたいな箱が増えても実際には使いづらい状態なのでとても難しいです。
![コンテナの実情.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/590346/fe82a6d7-7d84-06f4-0227-3be49fbb44b4.jpeg)



さらに既存の状態は一つになっているのにそれを細かく箱詰めするため、大変です。
仕事場では同じことをするため決まった状態であることが望ましいですが、家ではある程度適当なほうがいい。

そのため基本的なスモールスタートをしたいときにはコンテナはすごく手間がかかるものになります。

## 3. コンテナといえばdocker
2021年1月現時点では「コンテナ」＝「docker」のことだと考えてください。
呪文を言うと、kubernets（k8s)、openshift,CRI-O,Docker-compose、aks,Fargate,GKE,AKS,docker swarm等いろいろな話が出ますが、
コンテナ＝dockerと考えてください。

**厳密には違う**かもしれませんが、別にいいのです。
学術的には困りますが、**実務**では困りません。

## 最後に
これからまだまだ話が続きます、コンテナを含んだシステムをつくるのはアーキテクチャの領域です。
とても難しいです。いきなり難しいことしてできないのしょうがないことです。

どうでもいいことですが、絵の緩音ヒグかわいい。