OmniAICreator/Qiita-1.07M huggingface dataset:
【Rails】ActiveRecordのデータを暗号化しよう

active_record_encryptionというgemを使う

# 誰でも簡単3ステップで導入

## ①gemを導入

Gemfileに以下を追記

```Gemfile
gem 'active_record_encryption'
```

```
bundle install
```

## ②カラムを設定

blob型でカラムを設定します。例えばユーザーの本名、生年月日を暗号化するならこんな感じ

```ruby
class DeviseCreateUsers < ActiveRecord::Migration[6.0]
  def change
    create_table :users do |t|
      ## Database authenticatable
      t.string     :email,              null: false, default: ""
      t.string     :encrypted_password, null: false, default: ""
      t.string     :uid,                null: false
      t.string     :nickname,           null: false
      t.blob     :first_name,         null: false
      t.blob     :last_name,          null: false
      t.blob     :first_name_kana,    null: false
      t.blob     :last_name_kana,     null: false
      t.blob       :birth_date,         null: false
      t.references :organization,       foreign_key: true
```

## ③モデルに暗号化したカラムの元データを定義

モデルに以下のように記載します。

```ruby
encrypted_attribute(:first_name, :string, default: "")
encrypted_attribute(:last_name, :string, default: "")
encrypted_attribute(:first_name_kana, :string, default: "")
encrypted_attribute(:last_name_kana, :string, default: "")
encrypted_attribute(:birth_date, :date)
```

## ④暗号化方式を定義

config/initializers/active_record_encryption.rbに以下のように記述します。
暗号化key、saltについては知られちゃまずいので環境変数で設定します。

```ruby
ActiveRecordEncryption.default_encryption = {
  encryptor: :active_support,
  key: ENV['ENCRYPTION_KEY'],
  salt: ENV['ENCRYPTION_SALT']
}
```

## ⑤DBにデータを保存する

この状態でDBにデータを保存するとこんな感じの値が入ります。
![_MySQL_5_6_50__localhost_media_app_development_users.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/652172/bcba080c-c3b5-2604-e456-d7b2a83ed4e0.png)


見た目はなんのこっちゃわからないのですが、値を取り出すとちゃんと保存時に指定した値が取り出せます。

```ruby
[2] pry(main)> user.first_name
=> "山田"
```

## 感想
結構簡単に実装できてしまうのでセキュリティ的にどうなの？って感じもする。
SQLインジェクションとかで値を抜き取られたときとかに強そう
Automation 360でBot間のコピー

# はじめに
まだまだ、Automation360の勉強中です。
Automation Anywhere V11に比べて、Automation360ではBot間の行コピーが少し特殊なのでそのメモ。

# Bot間のコピーの仕方
「共有クリップボード」というものを経由します。

1. ブラウザのタブを使い２つのBotを開く


1. コピー元Botのコピーしたい行を選択し「共有クリップボードにコピー」ボタンを押す。
![clipin.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/632535/d1433ac5-ef86-22df-fdf4-9349d7d50dcc.jpeg)


1. コピー先Botの編集画面で「共有クリップボードから貼り付け」ボタンを押す
![clipout.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/632535/44a68905-6360-58c0-bde3-de5d4243637b.jpeg)

#よくあるエラー
コピー元とコピー先で、コピーしようとしているアクションのバージョンが違うとエラーになります。

![err1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/632535/864b54fb-3e6f-17af-71dd-ea8165ed2d14.jpeg)
![err2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/632535/8e5ae0e6-ae85-d726-2b74-f75c6786e37e.jpeg)
※バージョンが、元＞先でも、元＜先でも、エラーになります。

この場合、古いパッケージを使っているBotで該当パッケージのバージョンを新しくすると（バージョンを揃えると）エラーが回避できます。

# パッケージのバージョンを新しくする
1. 古いパッケージを使っているBotの編集画面を開く
1. 編集画面右上の縦３点から「パッケージ」を選択。
![package01.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/632535/6cecbc6c-d652-a122-c8bf-d2a3055688ca.jpeg)

1. 使っているパッケージの一覧から変更したいパッケージを選択
![package02.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/632535/7c0c1b97-a70d-8b6d-6a61-460643a85f70.jpeg)

使用しているアクションの数だけ、出ているのでコピーしようとしている行で使っているアクション（パッケージ）を選んでください。

1. 揃えたいバージョンを選択
![package03.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/632535/36f8da8c-c8c8-e39c-359e-cea304365f34.jpeg)

1. 「バージョンを変更」を押す。
![package04.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/632535/11b1d97f-0c58-a971-361a-d50db0d725d5.jpeg)
Before starting UiPath:シーケンスとフローチャートの使い分けについて

## 皆もすなるQiitaといふものを、儂もしてみむとてするなり。

と言う訳で、こん＊＊は！はなっち！です。

★★★この記事はUiPathブログ発信チャレンジ2021サマー、7/31の記事です。★★★

今回は、ちょっとしたシリーズです。UiPathを使うに当たって、UiPathの機能ではなく、コンピュータ言語を使う上での基礎知識を展開していこうと思います。

#シーケンスとフローチャートの使い分けについて

ロボットを組む時、「シーケンス」アクティビティを使うのか、「フローチャート」アクティビティを使うのか、悩まれる人が多いとおもいます。
同じ処理をするロボットになるには違いのですが、見栄えとか、他の人のわかりやすさを考えると、ますます悩んでしまいます。
更には、「フローチャート」アクティビティ内で使う専用アクティビティがあり、これを使い始めると、「シーケンス」がよかった！と思っても後の祭りです。

★「フローチャート条件分岐」、「フローチャートスイッチ」

「シーケンス」アクティビティ、「フローチャート」アクティビティの特長をみてみましょう。

「シーケンス」の特長
　　　　・記述した上部アクティビティから実行され、下部まで実行する。
　　　　・条件分岐で軽微な制御ができる。条件分岐の中に条件分岐を配置できるが、多岐になると読みにくくなる。
　　　　・ＷＥＢの画面制御などに向いている。

「フローチャート」の特長
　　　　・記述した上部アクティビティから実行され、結合線に沿って実行される。
　　　　・フロー条件分岐で複雑な制御ができる。多用すると、結合線が交差し、読みにくくなる。
　　　　・１ロボで、処理の状態で制御する事に向いている。

「シーケンス」の中に「フローチャート」、「フローチャート」の中に「シーケンス」
それぞれのアクティビティの中に、他方のアクティビティを配置することも可能です。
ですので、以下のような使い分けを試してみてはいかがでしょう

　　　　１．機能としての一括りは、「シーケンス」を配置する。
　　　　２．大きな制御は「フローチャート」を配置し、中に「シーケンス」と「フロー条件分岐」を配置する。
　　　　３．EXCELアプリケーションスコープ、繰り返し（各行）などの中は「シーケンス」を配置する。
　　　　　★これらの本体部分に、二個目のアクティビティを挿入すると、自動的に「シーケンス」化されますね。

どんな使い分けをしても、
　　　　・それぞれの「表示名」は、処理フロー(仕様書)と一致させる
これは大事ですよ。

##おわりに
いかがでした？

ロボットを作る時、○○でなければいけない！と言うようなルールはなく、○△でも実装できるし、△○でも実装できるというようなものです。
考えると、１）他の人が見たときに、分かりやすい。２）無駄な処理がない、３）適宜、注釈、コメントが設定、挿入されているのが、いいロボットかもしれませんね。

是非UiPathでのロボ開発の一助になればと思っています。

ありがとうございました！
Swiftエラー処理

Swiftエラー処理
--
swiftは静的型付け言語であり、安全性の高い言語　ではあるがエラーの発生は避けられないのでエラーを適切に処理する必要がある。

do-catch構文
---

書き方

```swift
do {
	try メソッドを書く
} catch {
	// エラーが発生した場合の処理を書く
}

```

tryは```try?```と```ｔｒｙ！```で機能が違う。？はエラーになっても無視して実行するが、！は強制アンラップをするのでアプリがクラッシュする可能性がある。
もしエラーが起こりうる関数を定義したらあわせて```thorows```キーワードを引数の後に書く必要がある


Result型のエラー処理
---
Result<Success、Failure>型のエラー処理は正確にエラー内容をかくにんすることができる
列挙型の形をとり、case .successとcase .failureのケースを持つ。
ライブラリでswitch文で条件分岐する書き方がよくある


```swift
public enum Result<Success, Failure: Error> {
    case success(Success)
    case failure(Failure)
}
```
下記の書き方でAlamofireで使用するイメージ

```swift
 switch result {
        case .success:
            print("成功")
        case .failure:
            print("失敗")
        }
```

assert,precondition
--
ある条件を満たした場合にプログラムを終了する。
ビルドの状態によって最適化されているが、基本preconditionでも同じ使用方法である。基本デバックで```assert```を使う

```swift
func method(_ arg: Int) {
//if文のように使用する
  assert(arg < 0, "プログラム終了")//assertがpreconditionでも同じ挙動をする

  print("処理実行されない")
}
method(-1)
```

assertionFailure
---
強制的にプログラムを終了させる

```swift
func method(_ arg: Int) {
  assertionFailure("プログラム終了")
  print("処理を実行されない")
}

```

fatalError
---
強制的にプログラムを終了させる（assetは条件を満たした場合のみ）

```swift:fatal.swift
func method() {
  fatalError("プログラム終了")
  print("処理実行されない)
}
method()
```
S3にホスティングしたSPAをCloudFrontで開くとAccessDeniedが出るとき対処法リスト※随時更新

## 問題
クラウドフロントで下記のようなエラーが表示されてページが閲覧できない


```xml

<Error>
<Code>AccessDenied</Code>
<Message>Access Denied</Message>
<RequestId>BASD5JKLZQBI8</RequestId>
<HostId>X9Slmr75bLv4sfgCm5Y3Fx+qys/MEk+8NfsdfbMy0t5Qc19oaV4XFea3vsB/A0nmWzdfgkRoq4tk=</HostId>
</Error>


```

## 対処法1

### エラーページで　404の時と403の時、ステータスコード　２００で/index.htmlを開くようにする。
なぜかというとSPAは基本的に一つのhtmlファイルでパスごとに表示を切り替えているので、Vue.jsなどで `/page` `/create` などを定義していたとしてもS3からファイルを見つけられることができないので403が帰ってしまう。
それを防ぐために403でも200で一度/index.htmlにリダイレクトさせて作成したVue.jsのrouterなどに開くページを制御してもらう必要がある。

![スクリーンショット 2021-07-30 13.32.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274030/25d2c2d7-31f3-2d12-da50-4a4e707a96ec.png)


## 対処法２

### S3のBucket policy  を CloudFront から参照できるように更新する

origins -> 対象を選択 -> edit で画像のような画面に遷移できる。

![スクリーンショット 2021-07-30 13.41.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274030/97c9e80e-ab63-a3ef-6f45-2aebbb8496b7.png)

OAIをなければ作成あれば選択して update の方を選択して保存をする。

## 最後に

Youtubeチャンネルはじめてます！
エンジニアの姿は十人十色。
今後も色んなエンジニア像を捉えて、それを目指す人たちの参考になる動画を作っています。

https://youtu.be/KRTo7MlOd9w

あと、プログラミングもメンタで教えているので興味があったらみてください。

https://menta.work/plan/1734
// でコメントアウトできる事知りませんでした...

▪️ コメントアウトとは

プログラミングはチームで各々担当分けして開発することが多いので、意思を伝えるためにコードの近くにコメントを残します。ですが、コメントをただ書いただけだと読み込まれエラーの原因になってしまいます。そこでコメントは残しつつ、エラーの原因にならないようにするためにコメントアウトを用います。

▪️ コメントアウトの書き方

普通のコメントアウトの書き方は、< !-- > という記号で囲むとコメントアウトされると思います。
e) <! -- コメントアウトです >

ですが、他にもコメントアウトのやり方があり綺麗なコードを書くプログラマーのコードを見ているとそれをよく多用しています。＜下記に記載＞

▪️ 他のコメントアウトの書き方　

他のコメントアウトの書き方としてコードの前に//を書くとコメントアウトすることができます。
e)  // コメントアウトです




今日の投稿は以上です。
他にもこんなコメントアウトの書き方があれば、是非教えてください。
wagaでした！
【C# / .NET】Newtonsoft.json とSystem.Text.Json で DBNull.Value と DateTime 型の値を変換した結果が異なる

# 前置き

Newtonsoft.json と System.Text.Json で、DBNull.Value と DateTime 型の値を変換する際の動作が異なっていました。

実行環境、コードは以下のような感じです。
といっても、両者の違いはメソッド名だけですが。

## 実行環境

- .NET Framework 4.8
- Newtonsoft.json 13.0.1
- System.Text.Json 5.0.2

## Newtonsoft.json
```
dynamic data = new ExpandoObject();
data.nv = DBNull.Value;
data.dt = DateTime.Now;
var serialized = JsonConvert.SerializeObject(data);
var deserialized = JsonConvert.DeserializeObject<ExpandoObject>(r);
```

## System.Text.Json
```
dynamic data = new ExpandoObject();
data.nv = DBNull.Value;
data.dt = DateTime.Now;
var serialized = JsonSerializer.Serialize(data);
var deserialized = JsonSerializer.Deserialize<ExpandoObject>(serialized);
```

# 結果
## Newtonsoft.json
### シリアライズ
`{"nv":null,"dt":"2021-07-31T06:30:38.8041996+09:00"}`

### デシリアライズ
![スクリーンショット 2021-07-31 5.50.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23789/d5647a26-b7fc-43af-e7c7-d50e7bfc2369.png)

## System.Text.Json
### シリアライズ
`{"nv":{},"dt":"2021-07-31T06:30:38.4280875+09:00"}`
### デシリアライズ
![スクリーンショット 2021-07-31 5.49.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23789/3a11e6d3-a429-2da3-a62f-147d9b294284.png)

|#|Newtonsoft.json|System.Text.Json|
|----|----|----|
|DBNull.Value | null | string 「"{}"」 |
|DateTime | DateTime | string 「"JSONの日付フォーマット"」 |

シリアライズ時、DBNull.Value は Newtonsoft.json では null に出力され、
System.Text.Json では "{}"（空文字）で出力され、
DateTime は双方"JSONの日付フォーマット"で出力されました。
dynamic型でデシリアライズした際、System.Text.Json は System.Text.Json.JsonValueKind というクラスにラップされ、DateTime も文字列で返されます。

この辺は状況によってどちらが適切か分かれると思いますが、私は Newtonsoft.json の仕様の方が素直な感じがして賛成。
というか　DateTime が文字列になってしまうのは辛いです。
マニアックな記事かもしれませんが、案件でハマったのでこの記事が誰かのお役に立てば幸いです。
Zone APEX とは

## 勉強前イメージ

APEXってゲームしか思い浮かばない・・・

## 調査

### Zone APEX とは

example.jp や example.co.jp など サブドメイン(wwwなど)を含まないドメイン名のことで、
APEXは頂点を意味し、ゾーンの頂点として意味するサブドメインを含まないドメインを意味します。
他にもネイキッドドメインやアペックスドメインなど呼ばれます。

### Zone APEXはCNAMEが設定できない

例えば 以下のように
XXX.com というドメインの主になるサイトに XXX.com というCNAMEレコードを振りたい場合がある

しかし、RFC1912 からZone APEXとCNAMEレコードはプロトコルエラーになるので、他のレコードと共存ができません。
理由として、プロトコルエラーになる他のレコードとは、Zone APEXにはNSレコードが設定されるため
CNAMEレコードとNSレコードは共存できないことから
Zone APEXにCNAMEレコードが追加できないということです。

AWSのRoute53では、独自にAレコードでエイリアスレコードという下記のように設定できるものがあり
これを使うと、

![2Route 53 Console Hosted Zones - Google Chrome 2021.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/a47ced75-8b80-3685-cb9b-1b1e0b5a99f7.png)


以下のようにELBをZone APEXに設定することができます。

![3Route 53 Console Hosted Zones - Google Chrome 2021.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/03c80f3f-a80e-5826-13c9-f9457c0952e0.png)


## 勉強後イメージ

今までちゃんと考えたことなかったけど、
Zone APEXにCNAMEレコードって設定できないのか・・・

## 参考

- [CNAMEレコードにZone Apexをマッピングできない件について](https://blog.serverworks.co.jp/tech/2016/07/07/zone-apex-cname/)
- [Zone Apexに対するALIAS(ANAME)レコードとその動作](https://kiririmode.hatenablog.jp/entry/20210124/1611468228)
2021/07/29開催 Connpassイベントランキング

# 申込数TOP5

|順位|イベント名|グループ|申込数|定員|
|:---:|:---|:---|:---:|:---:|
|:one:|[駆け出しから即戦力になるためのデザイン講座【前編】](https://tokyofreelance.connpass.com/event/219556/)|[東京フリーランス](https://tokyofreelance.connpass.com/)|1584|1600|
|:two:|[【好評につき増席！】フリーランスエンジニア会議〜 Flutter開発の最新トレンド〜](https://findy.connpass.com/event/218669/)|[ファインディ／Findy](https://findy.connpass.com/)|317|350|
|:three:|[夏だ！3社のアクセシビリティー取り組み事例から考える傾向と対策](https://connpass.com/event/218780/)||303|350|
|:four:|[みんなのPython勉強会外伝 〜センサー・フュージョン＆MLOps編〜](https://tier4.connpass.com/event/217726/)|[Tier IV／ティアフォー](https://tier4.connpass.com/)|223||
|:five:|[1年で社員数が2.3倍に?!人事が足りない!採用・制度の現状を公開するので入社してもらえませんか?祭](https://smarthr.connpass.com/event/217050/)|[株式会社SmartHR](https://smarthr.connpass.com/)|148|160|
echoで改行を反映させ正しくエンコードする

# はじめに
`echo`コマンドを使って改行を含む文字列をエンコード/デコードした際、正しく復元できない状態に陥りました。
原因はエンコードする際にエスケープ文字を認識してくれないという点にあり、調べたところ、`-e` というオプションを加えることで、エスケープ文字を認識できるということが分かりました。

# 結論
* echoコマンドにオプション `-e` をつけることでエスケープ文字(`\n: 改行`,`\t: タブ` 等)が有効になる

```bash
$ echo -e "Hello\nWorld"
=> Hello
   World
```

## 環境
* macOS Catalina 10.15.5
* bash


# 出力の確認
### 「-e」なしの場合
-eのオプションを追加しないと 「\n」がエスケープ文字ではなく単純な文字として認識され改行が反映されません。

```bash
$ echo "Hello\nWorld"
=> Hello\eWorld
```

### 「-e」ありの場合
すると、「\n」がエスケープ文字として認識され正しく出力されることが分かります。

```bash
$ echo -e "Hello\nWorld"
=> Hello
   World
```

### ダブルクォーテーション("")なしの場合
""をつけない場合は「\n」ではなく 「\\\n」 をつけないと認識してくれません。


```bash
$ echo -e Hello\nWorld
=> HellonWorld

$ echo -e Hello\\nWorld
=> Hello
   World
```

# エンコードしてみる
「-e」オプションでエスケープ文字が有効になり改行が反映されるようになったので実際にエンコードしてみます。

* エンコード/デコードは`base64`コマンドにより実行できます。

```bash
# エンコード
echo "文字列" | base64

#デコード
echo "文字列" | base64 -D
                      (--decode)
```

※ base64コマンドはGNU coreutilsと呼ばれるパッケージ（`echo`, `cat`, `ls` 等のUNIX系のOSで使われることが多い基本的なコマンドが格納されている）に含まれているそうです。

### 「-e」なしの場合
改行が反映されないので復元した結果も改行されていません。

```bash
# エンコード
$ echo "Hello\nWorld" | base64
=> SGVsbG9cbldvcmxkCg==

# デコード
$ echo "SGVsbG9cbldvcmxkCg==" | base64 -D
=> Hello\nWorld
```

### 「-e」ありの場合
改行が反映され正しく復元できていることが分かります。

```bash
# エンコード
$ echo -e "Hello\nWorld" | base64
=> SGVsbG8KV29ybGQK

# デコード
$ echo "SGVsbG9cbldvcmxkCg==" | base64 -D
=> Hello
   World
```
2021-07-30 Qiita の Python 用 API の概要


`qiita_v2` は Qiita の Web API の Python 用のラッパです。触り始めたところですけれど、簡単に利用できます。ただ、利用できるメソッドが多いのとドキュメントがほとんどないので、自分なりに整理してみました。

# 情報源

- [Web API のドキュメント](http://qiita.com/api/v2/docs)

- [GitHub](https://github.com/petitviolet/qiita_py)


# インストール

~~~
pip install qiita_v2
~~~


# Python 用 API について学ぼう

Python に特化した技術文書はなさそう。[Web API のドキュメント](http://qiita.com/api/v2/docs) を読みながら想像するのが正しそうだけれど、Python の doc string で学ぶ手抜きをしました。

まず Python に API を読み込みます。

```py
from qiita_v2.client import QiitaClient
```

ここで `QiitaClient` の doc string を見てもよいかもしれないけれども、情報密度が低く、一覧性に乏しいので今ひとつ。

ひとまず、`QiitaClient` クラスのインスタンスのメソッド一覧を眺めてみました。

~~~
>>> QiitaClient(config_file='/Users/wakita/.qiita-vim').__dir__()
['access_token', 'team', '__module__', '__doc__', 'create_access_token', 'delete_access_token',

 ... 中略 ...

 'delete_reaction_project', 'HOST', 'USER_AGENT', 'ACCEPT', 'HEADER', '__init__', '_url_prefix',

 ... 中略 ... ]
~~~

メソッド一覧のなかから気になるメソッドの使い方を調べるには `help(QiitaClient.list_user_items)` のように `help` 関数に頼りましょう。

~~~
Help on function list_user_items in module qiita_v2.client:

list_user_items(self, user_id, params=None, headers=None)
    特定のユーザの投稿一覧を返します。
~~~

上のメソッド一覧は煩雑なので、整理しました。

~~~
header, get, post, put, patch, delete, request,

get_{authenticated_user{, _items},
     comment{, _likes, _reactions},
     item{, _likes, _reactions, _stock},
     project{, _likes, _reactions},
     tag{, _following},
     template,
     user{, _following},

{create, delete}_{access_token, item, item_comment, project}

list_{item_{comments, stockers}, items, projects, tag_items, tags, teams, templates,
      user_{followees, followers, following_tags, items, stocks}, users}

{like, update, delete}_{comment, item, project},
{, delete}_reaction_{comment, item, project},

{create, update, delete}_template,
create_expanded_template

{, un}{follow_{tag, user}, {lgtm_item, stock_item, thank_comment}}
~~~
【Flutter】「ボタンを押してもダイアログが消えない」の対処法



Flutter で「ボタンを押してもダイアログが消えない」なんてことはありませんか？

私はありました。

結論、以下でうまくいきました。

正直言って、自分用メモです。うまく動かなかったらゴメンナサイ。

```
  // How to dismiss dialog in flutter
  Future<Null> showChangePasswordDialog() async {
    String str= await showDialog(
      context: context,
      builder: (_) {
        return AlertDialog(
          title: Text('DialogFTitle'),
          content: Text('Yes or No?'),
          actions: <Widget>[
            OutlinedButton(
              child: Text('No'),
              onPressed: () => Navigator.of(context, rootNavigator: true).pop('No'),
            ),
            OutlinedButton(
              child: Text('Yes'),
              onPressed: () => Navigator.of(context, rootNavigator: true).pop('Yes'),
            ),
          ],
        );
      },
    );

    if(str == 'No'){
      // No
    }
    else if(str == 'Yes') {
      // Yes
    }
    else {
      // 
    }

```
SQL入門①

# はじめに
気づいたら大学3年生の前期も終わってました。あと会社辞めました。

SQLって結構コーディングテストのtrackに出てきたりして知ってるといいこといっぱいですよね。

今回は ~~友人の星野くんのために~~ 文系エンジニア志望の大学生に向けてSQLの入門レベルくらいの内容をまとめてみたいと思います。
SQLの記事っていっぱいあるけどね、、、ハンズオン形式っぽくまとめてみます。


# 環境
mac os 11.2 Big Sur
CPU Apple M1
MySQL 8.0.26

MySQLでやりたかったので今回はもうローカルでやってしまいたいと思います。
初心者向けだとDockerとか使いたくないですしね。
~~Docker苦手だから使わなかったわけではないですよ決して~~

# DBの作成
環境構築は各々のpcによって違うと思いますのでご自分でお願いします。

select文とかから入るもんだと思いますがまずは簡単にDBの作成からいきいましょう。
```create database [database name];```
このコマンドだけでDBが作れます。
``` create database firstdb; ```
とかで最初のDBを作成しましょう！

```
--------------
create database firstdb
--------------

Query OK, 1 row affected (0.00 sec)

```
この表示がでれば成功です。hello worldみたいなノリです。

# DBの削除
作成したら一応削除のコマンドも知らないとダメですね。
```show databases;```
で自分のDB一覧が観れるので表示してみましょう。

```
+--------------------+ 
| Database           |
+--------------------+
| firstdb            |
| information_schema |
| mydb               |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
```
こんな感じのがでてくると思います。そしたら
```drop database firstdb;```
で先ほど作ったdbを削除してみてください。
もう一度show tablesをやってなくなっていれば成功です。

# DBにテーブルを追加
もう一度任意の名前でdbを作成しましょう。
その後```use [db名]; ```を実行してください。

```
Database changed
```
が出れば問題なく実行できています。
これがでたらいよいよテーブルの作成です。
テーブルを作成するコマンドは``` create table [table名]([列名] [型]); ```になります。

```sql
create table user (
id integer,
name varchar(100)
);
```
を実行してみましょう。(primary key,not null とかは今回は無視します。)
varchar(100)は後の記事で解説します。

```
Query OK, 0 rows affected (0.15 sec)
```
これが出ればオッケーです。

# テーブルに値を追加
いよいよ今回の最終セクションです。
テーブルに値を追加するコマンドはinsert文です。
```insert into [table name] values (...value); ```
分割代入の構文を使っていますが(js知ってる人向け感がすごい)valueにはtableで必要な引数を入れています。
今回は

```sql
insert into user values (1, "Yuta");
```
を実行してみましょう。

```
--------------
insert into user values (1, "Yuta")
--------------

Query OK, 1 row affected (0.01 sec)
```
これが出れば成功です。

# まとめ
今回は

```
create database [database name];
show databases;
drop database [database name];
use [db名];
create table [table名]([列名] [型]);
insert into [table name] values (...value);
```
を勉強しました。
次回part２ではdbの値の抽出と簡単な設計について学んでいきます！！！
頑張っていきましょう。
~~半端じゃないテキスト感~~
jQueryで文字数チェッカーを作成してみた

css

```css:style.css
.input {
    position: relative;
    display: block;
    padding: 20px;
    width: 100%;
    background-color: #eee;
    -webkit-box-sizing: border-box;
    box-sizing: border-box;
}
.lest-count {
    position: absolute;
    bottom: 5px;
    right: 5px;
    font-family: Helvetica;
}
.red {
    color: red;
}
```

html,jquery

```html:index.html
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<meta name="format-detection" content="telephone=no">
<title></title>
<link rel="stylesheet" href="css/reset.css">
<link rel="stylesheet" href="css/base.css">
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<input type="text" class="input" value="">
<span class="lest-count">30</span>
<script type="text/javascript" src="js/jquery.js"></script>
<script type="text/javascript">
// .input に文字を入力し、文字を入力した段階でその文字数に応じて .lest-count の値が減っていき、
// 最大文字数である30文字以上入力すると .lest-count に .red クラスが追加されて文字色が赤くなり、
// 30文字以内になると、.red クラスが外れ、文字色が元に戻る。（ちなみに改行は文字数に含まない。）

// keyup 文字入力後に発火されるイベント。
// .replace(/\s+/g,'').length 改行を含まない文字数を取得します。
// .val() input要素のvalueを取得します。
$(function(){
  var lc = $(".lest-count");
  $(".input").keyup(function(){ //文字が入力されたらイベントスタート
    var num = $(this).val().replace(/\s+/g,'').length;//val()でインプットの値を取得し、
    //replace(/\s+/g,'').lengthで改行とスペースを含めない文字数を取得
    lc.text(30-num);//inputの文字数文.lest-countの文字を減らす
    if(num > 30){
      lc.addClass("red");//numが30より上なら文字を赤くする
    }else if(num <= 30){
      lc.removeClass("red");//numが30以下なら文字を黒に戻す
    }
  });
});
</script>
</body>
</html>

```
jQueryでマウスに追従するツールチップを作成してみた

css

```css:style.css
.tooltip {
    position: absolute;
    padding: 20px;
    background-color: #fff;
    border-radius: 10px;
    border: 2px #CCC solid;
}
.tooltip-body {
    position: relative;
    line-height: 1.5;
    margin: 20px;
    cursor: pointer;
}
```

html,jquery

```html:index.html
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<meta name="format-detection" content="telephone=no">
<title></title>
<link rel="stylesheet" href="css/reset.css">
<link rel="stylesheet" href="css/base.css">
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<div class="tooltip-body">Lorem ipsum dolor sit amet, consectetur adipisicing elit.<br>Accusamus, provident harum commodi nam fugiat blanditiis natus similique odio minima eius tenetur, facilis sit amet, alias nemo pariatur modi ab facere.</div>
<script type="text/javascript" src="js/jquery.js"></script>
<script type="text/javascript">
// .tooltip-bodyにマウスが乗ったら、
//<div class='tooltip' style='display: none;'>description</div>
// がfadeInし、マウスが外れたらfadeOutする。
// その際に.tooltipがマウスに追尾する。
// mousemove マウスの移動座標を取得できる
// .hover() ホバー時の処理を指定
// prepend()要素内の先頭に要素を追加
$(function(){
  var ttb = $(".tooltip-body");
  ttb.prepend("<div class='tooltip' style='display: none;'>description</div>");//.tooltip-body内の先頭に.tooltipを追加
  var tt = $(".tooltip")
  ttb.hover(function(){ //ホバー時の処理
    tt.stop(true,false);//アニメーションを止める。stop(現在のアニメーションをゴールまでジャンプさせるか否か,待機状態のアニメーションを破棄するか否か)
    tt.fadeIn(); //.tooltipを表示
    $(this).mousemove(function(e){//mousemoveでマウスの座標を取得
      tt.css({
        top : e.pageY,//縦軸をtopに設定
        left : e.pageX//横軸をleftに設定
        //これでツールチップがマウスに追従する
      });
    });
  },function(){
    tt.stop(true,false);
    tt.fadeOut();//マウスが離れたら非表示
  });
});

</script>
</body>
</html>
```
git configのincludeIfを使ってgithubアカウントを複数使い分ける

githubでメインアカウント、サブアカウントがあるとして
アカウントを使い分けられるように設定していきます。

## githubのssh接続先を分ける

.ssh/configの接続先を分けます。

```ssh
Host github # メインのgithubアカウント用
  HostName github.com
  User company-user
  IdentityFile ~/.ssh/id_rsa_github_company
  IdentitiesOnly yes
Host github-sub # サブ用。github.com以外の任意のHost名
  HostName github.com
  User private-user
  IdentityFile ~/.ssh/id_rsa_github_private
  IdentitiesOnly yes
```

上記の接続先の設定で接続テストができるか確認。

```
$ ssh -T git@github-sub
Hi {githubのID}! You've successfully authenticated, but GitHub does not provide shell access
```

これでサブのアカウントでgit cloneできるようになりました。

```
$ git clone git@github-sub:{githubのID}/{リポジトリ名}.git
```


## 作業ディレクトリ単位でアカウントを切り替える

git clone、git pushはssh接続先を複数設定することで出来るようになりましたが、
これだとuser.nameとuser.emailの設定が足りないので、コミットにそれぞれのuser.name、user.emailが追加されません。
メインアカウントとサブアカウントとでuser.nameとuser.emailの設定も切り替えられるようにしたいところ。

ただ、`git config --global`だと共通の設定になってしまうし、
`git config --local`だと対象リポジトリ内のみで都度設定するのは手間なので
メインとサブの作業ディレクトリを分けて、それぞれの作業ディレクトリ下でgit cloneしたリポジトリには
ユーザー情報がメインとサブでそれぞれ設定されるようにしたい。

作業ディレクトリはこういうイメージ。

```
/user/to/path/
├ workspace-main/ # メインアカウントのリポジトリはこっちにgit cloneしたい 
└ workspace-sub/ # サブアカウントのリポジトリはこっち
```

### .gitconfigでディレクトリ毎の設定を分ける

下記のような.gitconfigファイルを設置します。

```
~/
├ .gitconfig
├ .gitconfig-main # メイン用設定ファイル
└ .gitconfig-sub # サブ用設定ファイル
```

仕事用githubユーザー情報を.gitconfig-mainに、
同様にプライベートのgithubユーザー情報を.gitconfig-subにそれぞれ設定。

.gitconfig-main

```
[user]
  name  = main-user
  email = main-user@example.com
```

.gitconfig-sub

```
[user]
  name  = sub-user
  email = sub-user@example.com
```

.gitconfigに `includeIf` で作業ディレクトリ毎に読み込むファイルを追記。

```
[user]
  [includeIf "gitdir:/user/to/path/workspace-main/"]
    path = ~/.gitconfig_main

  [includeIf "gitdir:/user/to/path/workspace-sub/"]
    path = ~/.gitconfig_sub
```

各作業ディレクトリ下でgit cloneしたリポジトリで設定したユーザー情報が確認できたら完了です。

```
$ cd /user/to/path/workspace-sub/nanika-no-repository/
$ git config --list
user.name=sub-user
user.email=sub-user@example.com
```
MagikEye DK-ILT001 の特性

先日国内発売されたMagikEye ILT開発キット（DK-ILT001）の特性を調べました

## なぜ調べた？

前に「[MagikEyeをROS1で動かすまで](https://qiita.com/nisshan_/items/88c60049e31a82f6e366)」を書きました。次に動かせるようになったセンサーを早速応用したいのですが、あれ？ 検知可能範囲に関する仕様を知りません。[公式サイト](https://support.magik-eye.com/ILT001/)や[販売サイト](https://www.switch-science.com/catalog/7281/)にスペックを見つけることができなかったです(2021/07/30現在)。とはいえ、センサーの検知範囲を知らずには使えないので、ざっくり調べました。

【2021/07/31更新】
[プレスリリース](https://prtimes.jp/main/html/rd/p/000000006.000083311.html)に記載がありました。

```
測距可能距離（弊社開発環境による）
- プロジェクター発光到達距離： 1500mm
- 弊社推奨測距距離： 150〜800mm（測定精度±3¥%）
- 高精度測距距離： 150〜500mm（測定精度±1.5¥%）
- 測距有効視野角（FOV)： 約55度×約43度（弊社開発環境による）
- 測距速度： 約120fps（弊社開発環境による）
```

![IMG_9404.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/630585/81ee3cd8-d66f-0d95-e9f3-0dc89ba5109a.jpeg)

## 距離

フラットな壁に向かってセンサーを近づけていきました。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">MagikEye ILT001 検知距離を測ってみました。<br>壁から2.5m離れた位置から少しずつ壁に近づいています。 <a href="https://t.co/ewdQ7clX2H">pic.twitter.com/ewdQ7clX2H</a></p>&mdash; nisshan にっしゃん (@nisshan_) <a href="https://twitter.com/nisshan_/status/1421135429768671232?ref_src=twsrc%5Etfw">July 30, 2021</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

近ければ近いほど精度が良く、逆もしかり、という特性ですね。このセンサーで物の形を捉えるような精度を求める使い方ならばかなり近づける必要があります。30cm〜50cmぐらいですね。

ざっくり「何か障害物がある/なし判定ができれば良い」という用途なら、(アルゴリズムにも寄りますが)1〜2mの距離は見えている、という感じですね。

2m以上離れるとノイズみたいに拡散するので、むしろ邪魔になります。ROSなら出力されたpointcloudをbox cropのフィルタでバッサリ切っちゃうのが良いでしょう。

## 画角(垂直方向)

![magikeye_fov_virtical.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/630585/ba9e5018-e48b-01a7-c206-b5f59709643c.png)

ざっくり55°です。realsense D435iの縦FOVが58°なのでほぼ同等ですね。

## 画角(水平方向)

![magikeye_fov_horizontal.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/630585/7d4131a4-de78-b313-69ba-03864291bb84.png)

横方向のFOVはざっくり43°。realsense D435iが87°なのでその半分ですね。垂直方向よりも狭いとは想定外でした。

「走行するロボットにmagikeyeを乗せて周りの障害物を見る」という使い方の場合、動かし方によっては何か対策を考える必要があるかもしれません。例えば、旋回するときはゆっくり進むか、旋回半径を大きくするように制限かけるとか。MagikEyeは安いので、複数台載せて死角をなくすというのもアリかもしれません。

垂直方向よりも水平方向の広く見たい場合は、90°向きを変えて取り付け、ソフト処理で90°戻してやる方法が取れますね。

## さいごに

まだまだ市場供給量が少ないので入手困難なMagikEye DK-ILT001ですが(2021/07/31現在)、購入前の検討に役立てば幸いです。
【CentOS Stream 8】上がってしまったカーネルを削除する

`dnf update`でカーネルがバージョンアップしたらVMwareのモジュールインストールに失敗したため、展開するカーネルを前のバージョンに戻す。また新しいカーネルは不要なので削除する。その手順。

起動時のデフォルトカーネルを変更する
---

使えるカーネル一覧の取得

```
$ sudo grubby --info=ALL | grep ^kernel
kernel="/boot/vmlinuz-4.18.0-326.el8.x86_64"
kernel="/boot/vmlinuz-4.18.0-310.el8.x86_64"
kernel="/boot/vmlinuz-4.18.0-305.0.1.el8.x86_64"
kernel="/boot/vmlinuz-0-rescue-92bb0dc1443e47dea719ff9b9652c249"

```

現在のgrubのデフォルト表示

```
$ sudo grubby --grub2 --default-title
CentOS (4.18.0-326.el8.x86_64) 8
```

326から310にデフォルトを変更

```
$ sudo grubby --set-default "/boot/vmlinuz-4.18.0-310.el8.x86_64"
```

参考

https://www.golinuxcloud.com/change-default-kernel-version-rhel-centos-8/

新しいカーネルを削除する
---

古いカーネルでリブートして最新のカーネルを削除
その他一式もまとめて削除

```
$ sudo dnf remove $(rpm -qa | grep ^kernel | grep 326)
```

参考

https://unix.stackexchange.com/questions/600455/how-do-i-remove-a-kernel-from-fedora-for-good

最後に、dnfの設定でカーネルを除外する。
モンティ・ホール問題をベイズの定理を使って解く

<h2>モンティ・ホール問題とは？</h2>
<p>3つのドア1,2,3のうちある1つのドアの奥にはアタリの車、他の二つのドアの奥にはハズレのヤギがいる。回答者が1つドアを選ぶと答えを知る司会者は回答者が選ばなかった2つのドアから奥にヤギがいるドアを1つ開ける。回答者は開けるドアを変更することができるが、回答者は開けるドアを変更するべきかどうかという問題。</p>
<p>下の画像を例にすると、例えば回答者が初めに1番のドアを選択した時に司会者が外れの3番のドアを開けます。この3番のドアが外れという事実を知った上で回答者は最初に選んだ1番のドアを開ける方がアタリの確率が高いか、それとも2番のドアを選んだ方がアタリの確率が高いかという問題です。</p>
![モンティ・ホール問題](https://upload.wikimedia.org/wikipedia/commons/thumb/3/3f/Monty_open_door.svg/500px-Monty_open_door.svg.png)
>参考、引用
[Wikipedia(モンティ・ホール問題)](https://ja.wikipedia.org/wiki/モンティ・ホール問題)

<p>私はこの問題を初めて知った時、「ドアを変更しようがしまいが確率は</p>
```math
\frac{1}{2}
```
<p>だろ〜」と思いました。しかし皆さんの予想通り、そんなに単純な問題ならばここまで有名な問題にはなりません。結論から申しますとアタリのドアの確率は</p>
```math
ドアを最初選んだままにした時：\frac{1}{3} \hspace{15px}\\
ドアを最初選んだものから変更した時：\frac{2}{3}
```
<p>となります。これの説明としてはよくドアを1000000個までに増やした場合を考えると〜みたいなものが多いのですが、私はその説明では心の底からは納得できませんでした。しかしこの間、ようやく納得のいく説明に出会うことができました。それがベイズの定理を使ったものです！</p>
<h2>ベイズの定理</h2>
```math
P(\theta|X)=\frac{P(X|\theta)P(\theta)}{P(X)}
```

<p>この数式は、</p>
```math
P(原因|結果)=\frac{P(結果|原因)P(原因)}{P(結果)}
```
<p>と解釈することができます。上の図で1のドアを選んだ場合に車が1のドアにある確率をベイズの定理に当てはめてみると、</p>

```math
P(1=車|3=ヤギ)=\frac{P(3=ヤギ|1=車)P(1=車)}{P(3=ヤギ)}
```
<p>と書くことができます。この式の左辺は「3のドアがハズレ(ヤギ)という情報が与えられた時の、1にアタリ(車)が入っている確率」と解釈できます。この数式の右辺の一つ一つに実際の確率を代入してみます。</p>

```math
P(3=ヤギ|1=車)=\frac{1}{2}
```
<p>1のドアが車である場合に3のドアがヤギである条件付き確率は、2のドアか3のドアを司会者がランダムに選ぶはずなので$ \frac{1}{2} $となります。</p>
```math
P(1=車)=\frac{1}{3}
```
<p>何も知らない状態ではそれぞれのドアに車がある確率は等確率と考えられるので確率は$ \frac{1}{3} $となります。</p>
```math
P(3=ヤギ)=P(3=ヤギ|1=車)P(1=車)+P(3=ヤギ|2=車)P(2=車)\\
=\frac{1}{2}\times\frac{1}{3}+1\times\frac{1}{3}=\frac{1}{2}
```
<p>この確率は周辺確率という考えを使うと求まります。</p>
>参考
[Wikipedia(周辺分布)](https://ja.wikipedia.org/wiki/%E5%91%A8%E8%BE%BA%E5%88%86%E5%B8%83)

<p>よって</p>
```math
P(1=車|3=ヤギ)=\frac{\frac{1}{2}\times\frac{1}{3}}{\frac{1}{2}}=\frac{1}{3}
```
<p>この結果より</p>
```math
P(2=車|3=ヤギ)=1-P(1=車|3=ヤギ)=\frac{2}{3}
```
<p>以上より自分が1のドアを選んだ場合には2のドアに変更したほうが2倍も高い確率でアタリの車を手に入れられます！</p>
<h2>まとめ</h2>
<p>ベイズの定理を使うことでスッキリと確率を求めることができました！シミュレーションなどで頻度論的に確率を求めてみるのも面白いかもしれません。</p>
<h2>終わりに</h2>
以上がベイズの定理を用いたモンティ・ホール問題の解き方でした！次回は今回深く触れられなかったベイズの定理についてもっと詳しく書ければと思います。間違い、わかりにくい点などございましたら是非コメントをお願いします！
【Unity】エディター拡張の右クリック


# 概要

エディター拡張時に右クリックのメニューをやってみました。
新しいUIElementsとGUI システム (IMGUI)の両方のパターンがあります。

### UIElementsの場合

```cs
// ラベルを右クリックした時の動作
VisualElement label = new Label("Hello World! From C#");
label.RegisterCallback<MouseDownEvent>((evt) =>
{
　　if (Event.current.button == 0)
    {
        // 左クリック
    }
    else if (Event.current.button == 1)
    {
        GenericMenu menu = new GenericMenu();
        menu.AddItem(new GUIContent("右クリックメニュー"), false, () => Debug.Log("右クリックメニュー"));
        menu.ShowAsContext();
    }
});

```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/175167/003d0c2b-60fe-e6e4-92d6-027f8ba18267.png)

### UI システム (IMGUI)の場合

```cs
if(GUILayout.Button("ボタン"))
{
    if (Event.current.button == 0)
    {
        // 左クリック
    }
    else if (Event.current.button == 1)
    {
        // 右クリック
        GenericMenu menu = new GenericMenu();
        menu.AddItem(new GUIContent("右クリックメニュー"), false, () => Debug.Log("右クリックメニュー"));
        menu.ShowAsContext();
    }
}
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/175167/853760af-ddd1-522a-c1bc-38f9134eab47.png)


# 終わりに

どちらにしても判定の後に`Event.current.button`で分けるみたい。
if 文の中括弧の位置はなぜ K&R 派が増えたのか

先に結論だけ書いておきますが、なぜ K&R 派が増えたのかはよくわかりませんでした。

## もういい加減あんたのコードを読む気になれない

``` c
if (((g_flagA == false) && (g_conditionA != 1)) ||
	(g_flagB == true) ||
	(g_oldData1 != g_newData1) ||
	((g_flagC == true) && (g_conditionC == 0)) ||
	((g_flagD == true) && (g_conditionD == 0)) ||
	(g_oldData2 != g_newData2)) {
	HogehogeFugafuga_function();
	PafupafuMomimomi_function();
	HogehogeFugafuga_changeData();
	HogehogeFugafuga_copyData();
	g_flagF = true;
}
```
こんな感じの if 文が出てきました。`g_` はグローバル変数に付ける規約なので仕方なし。
まずとりあえずこれがどういう条件文でどこからが命令文なのか、ぱっと見で分からないところが怖い。
こういうソースコードならせめて中括弧は改行くらいすまいか？

## ところでどうして中括弧を右に付けたいのだ？
古い VC で C++(C言語) を始めた自分は当時の参考書を読みながらそれを真似して書いてました。多分その影響なのか中括弧はすべて改行します。
関数定義では改行するのに if 文で改行しない人はどういう基準でそうしてるのかよくわかりません。

``` c
if( a == b )
{
	hoge( a * b );
}
```
こんな感じに、広大にスペースを入れまくり、中括弧はほぼ左にします。その反面 case 文とかはなるべく1行で書きます。

``` c
switch( condition )
{
	case C_1: { Hoge_function_1(); }; break;
	case C_2: { Hoge_function_2(); }; break;
	case C_3: { Hoge_function_3(); }; break;
	case C_4: { Hoge_function_4(); }; break;
	default: break;
}
```
整然と並んでいる方がおかしいところに気づきやすいというメリットを優先します。機械的に改行すべきとか言う人はなんでそんなに行数を増やしたがるのでしょうか。

## 職場のコーディングスタイルが気がつくと K&R の方が多い
うちの職場はコーディングスタイルについては自由なんです。命名とかの規約はあります。
ぶっちゃけ自分のスタイルは MFC などの影響を受けているので割と新しくて流行っている方、と思っていたのですがどうやらそうでも無いらしい...
仕事のコードを見ても if 文の中括弧は右端に書く人が多いらしいです。

## BSDスタイルを推す理由
### 可読性は確実に高い
まず最初の例文がわかり易い例でしょうか。いや、分かりにくいという例でもあります。if 文が複雑になるほどに、肝心の中身との分離が見にくくなりますね。
これを bool変数で置き換えるべきだ、という意見も出るのでしょうがそれはそれです。関係ありそうで関係ないと思います。

### ブロックはどうする？
if でも for でもないただのブロックを書くときは左側に中括弧を書かざるをえません。ならば一貫性を保つために常時左が良いのです。

### プリプロセッサでの切り替えもしやすい
``` c
#if X
	if( a )
#elif Y 
	if( b )
#else
#endif
	{
		f();
	}
```
ちょっとアレな例文ですがあくまで例ということで。
if 文自体を無かったことにも出来るわけです。

### else の扱いが自動で統一される
実は K&R な人の一部は else と中括弧の関係がまちまちだったりします。

``` c
} else {
...
}
else {
```
左揃えならこれはまず統一されます。

## ついでだけど、どうして if ( の間にスペース入れるの？
if と ( の間のスペースってどうして入れるんでしょう？
というのも関数名と括弧にスペース入れる人ってほとんどいませんよね？なのに if の後にスペース入れる意味がわからない。

``` c
if (a)		// 好きじゃない
if( a )		// これが好き
func( a );	// これと統一感
```

if を見て関数と間違える奴はいない、と断言しても良い気がします。間違えたならまず先に関数の方をどうにかしろ！
関数と間違えず、見やすさも別に損なわれないのに人気がないんですよね。

感覚的には `if (a)` と書いてしまうと `if ○○` 的に見える、つまり「a を括弧でくくっている」ように見えるのです。
`if( a )` と書けば「if() の中に a が有る」気分です。
規格上も () は省略できないので離す意味がないと思うんです。

## 怒られそうだけど実は有り
最後に嫌がられそうだけど慣れれば使えるスタイルをご提案。

``` c
if( data < 0 )
{
	hoge();
}
else switch( data )
{
	case 0:
	{
		fuga();
	}
	break;

	default: break;
}
```
else 文に switch を直結するやり方です。
まあ else if と本質的には同等なのですがほとんどやる人いないですよね。
でも評価対象が同じだと一貫性もあるので個人的に好きです。

##### 最初の例文を自分流で書く
``` c
if(  ( !g_flagA && ( g_conditionA != 1 ) )
	|| g_flagB
	|| ( g_flagC && ( g_conditionC == 0 ) )
	|| ( g_flagD && ( g_conditionD == 0 ) )
	|| ( g_oldData1 != g_newData1 )
	|| ( g_oldData2 != g_newData2 )
)
{
	HogehogeFugafuga_function();
	PafupafuMomimomi_function();
	HogehogeFugafuga_changeData();
	HogehogeFugafuga_copyData();
	g_flagF = true;
}
```
こうなりました。なるほど、全体としては or で構成された条件文ですね。このように書くと分かりやすいです。
ここで一つ自己矛盾に思える箇所が if( は改行しないのか、というところですね。でもそこで改行を入れると 2行改行が入ります。

``` c
if
(
	   ( !g_flagA && ( g_conditionA != 1 ) )
	|| g_flagB
)
{
	// 中略
}
```
これは...むしろ見にくいと思いません？さじ加減というか塩梅というか、過ぎたるはうにゃららですよね。
railsチュートリアルを始める前0章〜スタートライン

某プログラミングスクールで半年間勉強を続けて最近カリキュラムが終了。
2021/1~2021/7　の期間

半年間という期限付きで急いで勉強しないといけない焦りからかあまり頭の中に入っていない。

復習がてらに
テックピットでrailsなどの基礎教材を買おうかと思い、いくつか説明やレビューを見たところ・・・
railsチュートリアルという無料で学習できるものがあるという情報を拾う。

https://www.techpit.jp/


なんとなくページを開くと、本格的なサンプルアプリを作り（SNSページ）
herokuへデプロイするところまで行うという代物、しかもすべて無料である！
プログラミング初心者の挫折原因の８割強が環境構築であるが
本チュートリアルでは環境構築は一切不要（AWSのcloud９を利用）

https://railstutorial.jp/

チュートリアルはとにかく読み飛ばさないで見てください。
読み飛ばさずしっかり読むことが近道です。ということで
ページを追うごとに所々、解説動画があり、
関係動画を見終わるとだいたい半日が経過してしまった。

本チュートリアルはプロゲートと提携されて非常にわかりやすい内容であり、
以下のweb開発パスを取得してから先にすすめるよう促されるので、
初心者の方でも比較的に参入できるようになっている。

軽くweb開発パスを見たところ、、、
結構な量！！
本章のチュートリアルに入る前に基礎的知識、復習を叩き込めるので
やりごたえはおおいにありそう。

https://prog-8.com/paths/rails

次回はこの開発パスが終わった頃にもう一度、状況をまとめて報告できればと思う。

###次回

https://qiita.com/ak-matsu/items/78f809644c1b870b4052
githubでissueのテンプレートを作成する方法

# 概要
ポートフォリオ作成にあたり、開発タスクをissueを使って管理することにしたので
issueのテンプレートを作成し、楽にissueをかけるようにしたかった。

## 作成方法

### Settingsへ移動する
まずはissueを作成したいプロジェクトへ移動し、
settings -> Optionsを選択
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/601125/cf12536d-6698-495e-23e6-4ec0d30a5eba.png)

### テンプレートを作成する準備
FeaturesのIssuesの`Set up templates`をクリック
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/601125/55fc2c51-2458-f9e5-09a4-4403c39b6fd5.png)

### 作成画面
`Add template: select`をクリックし、任意のテンプレートを選択する。
![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/601125/a71549b8-5d52-4d46-0e30-0f1d09d6b96c.png)

今回は`Custom template`を選択します。
![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/601125/3ca36a01-de94-c4e7-2ca6-3749aa7351a6.png)

次に`Preview and edit`をクリック
![5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/601125/f50087d8-80fb-7993-0e53-f78312f755e9.png)

クリックするとカスタムテンプレートを作成する画面が表示されます。鉛筆横のマークをクリックします。
![6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/601125/79b677fb-db27-af90-7283-853d60df52ed.png)

編集画面が表示されるので、必要な項目を入力していきます。
今回は`Template name`と`About`、`Template content`を入力します。
![8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/601125/12e137e9-3328-8adc-0609-6570cdf9926c.png)

入力が完了したら、右上の`Propose changes`をクリックします。
![8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/601125/0f5ad44c-8034-f8dc-1ffe-f2460e05e5d1.png)

### コミットする
Issue　Templateをコミットする画面に遷移するので、コミットメッセージを記載して、`Commit changes`をクリックします。
![9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/601125/26abd7a2-972f-059b-e5fc-ee44bf98e0a9.png)

これで、概要のリポジトリのIssue Templateが完成です。

## 使い方
### issue作成画面へ移動
issues -> New issue をクリック
![10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/601125/b8bfc21e-a5ba-d034-9ee7-b5cd459fd566.png)

### templateを選ぶ
いくつかテンプレートを作成できるので、自分が使いたいテンプレートを選択し、`Get started`をクリックします。
![11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/601125/20f12b41-b692-c159-99fc-cf701bf17168.png)

### issueを作成する
先ほど作成したIssue templateの内容が書かれています。
![12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/601125/899396d3-f4be-265b-0f3d-21418ce96c06.png)

## 今回作成したテンプレートの内容
まずは作ってみることが先決だと思うので、コピペできるようにテンプレートの内容を置いておきます。
チームや自分の作成したい仕様に合わせて変更してみてください。

```
// Template name
issue template

// About 
Here is a template for creating an issue

// Template content
## Overview
Please provide an overview of the issue you are creating.
ex) I want to adapt the style of the header.

## Purpose
Describe the purpose of this issue
ex) To style it.

## Task
Break down and manage your tasks.
- [ ] XXXX
- [ ] XXXX
- [ ] XXXX
```
'The model backing the 'XXXXXX' context has changed since the database was created. のエラーが出たとき

.NET MVCで簡単なアプリを作っているときに、題のようなエラーが生じたので、このエラーが起こった時の解決方法についてまとめた。

なお、今作っている簡易アプリはEntity Frameworkを使用しており、コードファーストでModelを作成している。

## エラーの意味は、モデルの内容が変更されてしまっているので、マイグレーションをする必要があるというもの

このエラーは作成途中でモデルに変更を加えると起こるようだ。

## 解決方法
### 「Enable-Migrations」を叩く

そうすると

~~~
Migrations have already been enabled in project 'XXXXXXXXX'. To overwrite the existing migrations configuration, use the -Force parameter.
~~~

のメッセージが表示された。
すでにマイグレーションがある的なメッセージだろうか。


### 「Add-Migration AddStaffRequiredConstraint」を叩く

そうすると、

~~~
The Designer Code for this migration file includes a snapshot of your current Code First model. This snapshot is used to calculate the changes to your model when you scaffold the next migration. If you make additional changes to your model that you want to include in this migration, then you can re-scaffold it by running 'Add-Migration AddStaffRequiredConstraint' again.
~~~

というメッセージが表示された。
これでもうまくいってないっぽい。

### 「Update-Database」を叩く

そうすると、

~~~
Specify the '-Verbose' flag to view the SQL statements being applied to the target database.
Applying explicit migrations: [202107301524230_AddStaffRequiredConstraint].
Applying explicit migration: 202107301524230_AddStaffRequiredConstraint.
Running Seed method.
~~~
が表示された。
そうすると、Migrationsディレクトリにマイグレーションが作成されたので、成功したっぽい？

デバッグも動いて成功。

## 所感
Controllerの.csファイルなどで、元々作成したModelを継承して新しいモデルを作成作ったりすると今回のようなエラーが起こるんだそうだ。

ひとまず、継承なり、何なり、何かモデルをいじった場合は「Update-Database」を叩けば解決するのだろうか。


## 参考文献
https://kaji-3.hatenablog.com/entry/2012/06/28/230753
Pandas DataFrameをリストに入れて都合よく使っちゃおう

本日、私的には大変ありがたい学びがあったのでここに記すことにしました。

タイトルに示した通り、リストの中にPandas DataFrameを格納して必要に応じて呼び出して使うことができました。
また、リストに入れたDataFrameの名前は同一のもので良いことが大変ありがたいと感じました。

素人の私はpandasでDataFrameを作るたびになんだかよくわからないDataFrameの名前を用意してdf1,df2・・・などと名前を変えて作成しておりました。それが、listに格納する順番が決まっている場合はわざわざdfにまどろっこしい名前をつけることなく、リストから呼び出すことが可能です。
文で説明するのも大変なのでコードを示します。

例えば以下のように変数名が一緒で中身のみ違うdfを用意して、
リストにappendを繰り返すとlistにデータフレームを格納することができています。

```py
dflist = []
df = pd.DataFrame([1,2],[3,4])
dflist.append(df)
df = pd.DataFrame([5,6],[7,8])
dflist.append(df)

dflist
```

```
[出力]
[   0
 3  1
 4  2,
    0
 7  5
 8  6]
```

リスト内のdfはインデックスで呼び出すことができ、例えば以下のように引き出して使うことができます。

```
dflist[0][0]
```
とすると

```
[出力]
3    1
4    2
```
となり、

```
dflist[1][0]
```
とすると

```
[出力]
7    5
8    6
```

となります。


数値の部分はfor分を回すことで繰り返し取り出して使用することが可能です。
例えば以下のようにして表現すると取り出すことができています。

```py
files = ["1.csv", "2.csv"]

for i in range(0,len(files)):
    print(dflist[int(i)][0])
```
```
[出力]
3    1
4    2
Name: 0, dtype: int64
7    5
8    6
Name: 0, dtype: int64
```

玄人の皆様にとっては当たり前のことかと思いますので生暖かい目で眺めていただければ幸いです。
私と同じビギナーの方にはこんな失敗例もあるのかと興味を持って見ていってください。
私はこの発想がなかったため、どのように実装するかグダグダと調べたり考えたりして貴重な時間をどっぷり溶かしました。
【UiPath】謎のハッカー風操作をしてみる＃5（メッセージを受け取る）

# はじめに

この投稿は、RPAツール「UiPath」での 実装例 について記事です。

UiPathのコミュニティ「UiPath Friends」が企画する「UiPathブログ発信チャレンジ2021サマー」の 31日目の投稿でもあります。

企画の内容は [**こちら**](https://note.com/shumpei_w/n/n651cbdbec4e8) 。カレンダーのURLは [**こちら**](http://u0u1.net/sUwZ) です。

https://twitter.com/ShumpeiWatanabe/status/1405168150736359427

# 謎のハッカー風操作

前回に引き続き、よく映画で見る「ハッカーがやってそうな操作」をUiPathでしてみます。

それっぽく見えれば良いので、操作に意味はありません。

シリーズになっています。前回までの投稿はこちら。

https://qiita.com/miya_gis/items/a304d6d4600d63e98314

https://qiita.com/miya_gis/items/e78b03923954ff4920f1

https://qiita.com/miya_gis/items/0676d0c48201e2aee78f

https://qiita.com/miya_gis/items/f00443d9ed0086135a5e

操作のイメージは以下のような感じです。

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


# 謎のメッセージ

映画で見たような、何かのミッション指示を受けているように見せます。
メモ帳にメッセージを記入し、それっぽい動画を表示します。

作成したフローはこちらです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154139/62c686fa-78aa-ef31-30c5-35f026f6cf8a.png)

途中でmp4動画を再生しています。
メモ帳はそのまま閉じると「変更内容を保存しますか？」が表示されてしまうため、プロセスを強制終了させます。

実際に動かすと、以下のようになります。
![uianime9.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154139/a2c84dc9-6f93-3991-0620-168494e9233f.gif)


# おわりに

いかがでしたでしょうか？
あまり役に立ちそうにないですが、UiPathではこんな 遊び方／見せ方もできます。

この記事が参考（？）になったら、LGTM をお願いします。
最後までご覧いただき、ありがとうございました。
[Android]Jetpack Composeってナニ？？？

# Stableに！
最近、Jetpack Composeがstableになりました。
これで、やるやる詐欺をしていたのも、ここで終止符を打たねばと。

とはいえ、今まで、色々なAndroiderの方がJetpack Composeの事を口にしていましたが、正直何なのかそんなに分かっていです・・・
初学者の方は、特にそう思っているかなと・・・
行列ができているけど、その先に何があるのか分からん笑。

この記事では、行列の先頭まで辿っていきます！

# KotlinでUI書ける！
Jetpack Composeの何が凄いかというと・・・・
今まで、xmlファイルで書いていたUIの記述がKotlinで書けるようになりましたー！
自分は、去年の9月からAndroidの学習を始めたのですが、こんなも大きな変化が起きたのは初めてでした。
Android開発の歴史の中でも割と大きな変化だと思います。

#なにが良いの？
Kotlinで書けるJetpackComposeの何が良いのでしょうか？
ドキュメント先輩に聞いてみましょう

色々恩恵はありますが、一番分かりやすいもので言うと
###コード量が少なくなる！

>Jetpack Compose は、Android のネイティブ UI を構築するための最新のツールキットです。宣言型のプログラミング モデルに基づいているため、UI の外観をシンプルに記述できます。

宣言型というのは、プログラミングの「目的」だけ表現するもので、手段は裏側（主にコンパイラ=書いたプログラミングコードを機械語に翻訳してくれる奴）が担います。
二項対立として手続き型や命令型があります。
これらは、「手段」を書きます。

よく用いられる比喩として、「〇〇を食べる」を書くのが宣言型で、「〇〇の作り方」を書くのが命令型というのが分かりやすいでしょう。

宣言型の具体例としては、DataBidingやDaoの操作とかですかね。
あれらは、具体的な手順は記述せずにデータをバインドする！、データをインサートする！等の目的だけ書いていると思います。

逆に、命令型は、まぁ大体の言語がそうですね。
例えば、if文やfor文で具体的にどう処理していくのかを書く事です。

DataBindigやDaoを書いたことがあるなら、結構記述するコードが少なくなるのは、実感しているかなと思います。
なぜなら、裏側で根幹の処理をよろしくやってくれるからですね。

>Jetpack Compose は、Android のネイティブ UI を構築するための最新のツールキットです。宣言型のプログラミング モデルに基づいているため、UI の外観をシンプルに記述できます。

Composeさんが、裏で色々やってくれるので、記述量が少なることによる恩恵を言っているのでしょう。



#終わりに
まだ、Jetpack Composeをまともに使用してないので、もっと恩恵を感じ取る為にカキカキしたいと思います！！
そして、また記事をカキカキしたいと思います！！

#参考

https://developer.android.com/jetpack/compose/documentation?hl=ja
Google Cloud Certified Professional Cloud Developer 合格しました

先日、Google Cloud認定資格Professional Cloud Developerの試験を受験し、合格しました！
その記録を残しておきます。

Google Cloudの試験としては2つ目でした。前回（2週間前）の記録はこちら。

- [Google Cloud Certified Professional Cloud Architect 合格しました - Qiita](https://qiita.com/suzuki-navi/items/9b6d21a668225d9d21e5)

Developerと名の付く試験としては、同じく2週間前にAWSの試験も受けています。

- [AWS Certified Developer - Associate 合格しました - Qiita](https://qiita.com/suzuki-navi/items/dfb343130da83d560ce4)

都合、今月(2021年7月)は3つ目の資格試験となりました。（Qiita投稿が遅れたので、すでに次の試験も受験済みですが、それは[別記事](https://qiita.com/suzuki-navi/items/51c3cd0a1a4a154fc0e5)で投稿します）

# 勉強方法

試験の2日前の夜に、公式の模擬試験を解いてみました。正解数を数えていませんが、たぶん5割ぐらいです。解いたあと、正答と解説を見ながら1つずつ理解します。

その翌日、つまり試験の前日に、これまでの試験と同じくUdemyの模擬試験を買って勉強しようと考えました。しかし、前夜の段階で、日本語の模擬試験がUdemyにないことに気が付いたのです。だいぶ迷った挙げ句、いまさら他に勉強手段を思いつかなかったので英語版を買いました。英語版の模擬試験集はいくつかありましたが、問題数が一番少ないものの、レビュー数の最も多いものにしました。AWSも含めるとクラウドベンダーの試験は7回目となりますが、英語で勉強するのは初めてです。しかし、やってみると意外と英語でも読みやすかったです。たまにわからない単語をググるか、一部を自動翻訳にかけるぐらいで済みました。

Udemyの模擬試験には2回分ありました。模擬試験をやってみて、その後正答と解説を見て理解するのを2回やりました。ちなみに1回目が正答率72%、2回目が正答率50%でした。2回目は深夜でたぶん眠たかったかもしれません。Udemyの正答や解説に納得感のないものはありました。

# 試験当日

前回と同じ会場で受験しました。

60問120分。80分ぐらいで全部解き終わり、そのあと30分ぐらいで全問題を見直しました。前回のProfessional Cloud Architectよりも難しい印象です。

# 結果

合格。スコアは開示されないみたいです。

# 所感

AWSと同じく日本語が読みづらいところもありますが、AWSと違い、翻訳前の英語の問題文を読むボタンがありません。前回もそこは不便だと思ったのですが、日本語に違和感が少し大きかったです。

AWSのDeveloper、Google CloudのArchitect、Developerと連続で受けたせいで、どんな問題があったか記憶がすでに曖昧です。AWSのDeveloperとも似た観点の問題はありましたし、Google CloudのArchitectとも出題範囲は重なっているところ多かったです。

以下は出てきた印象のあるサービスです。記憶が曖昧で「印象」なので、勉強しただけで出題されなかったのも混ざってるかもしれません。

- コンピューティング
    - Compute Engine
        - Preemptible Virtual Machines
    - Kubernetes Engine
    - App Engine
    - Cloud Run
    - Cloud Functions
- ストレージ/データベース
    - Cloud Storage
    - BigQuery
    - Bigtable
    - Cloud SQL
    - Spanner
    - Datastore
    - Cloud Firestore
    - Cloud Memorystore
- 開発者向け
    - Cloud Build
    - Cloud Shell
    - ほかも出てたか覚えていない
- APIを公開する系
    - Cloud Endpoints
    - Apigeea
    - API Gateway
    - Cloud Load Balancing
- 他
    - Pub/Sub
    - Cloud Logger
    - Cloud Monitoring
    - Cloud Profiler
    - Identity-Aware Proxy
【基本】AWSでRDS(mysql)に接続してみた

# 概要
AWSのRDSを使ってMySQLへ接続をしてみました。

# 前提事項
RDSの作成で行うパラメータ設定は、基本的にはすべてデフォルトで行っています。
また、接続方法はEC2インスタンスの踏み台サーバを使ってRDSへ接続します。

# MySQLで接続してみる
### EC2にMySQLクライアントを入れる
・mysql8.0がインストールされているか確認する

```
[root@ip-10-0-1-10 ~]# yum info mysql
Loaded plugins: extras_suggestions, langpacks, priorities, update-motd
Error: No matching Packages to list
```

インストールできないのでmysql8.0のリポジトリを追加します

```
[root@ip-10-0-1-10 ~]# yum localinstall -y https://dev.mysql.com/get/mysql80-community-release-el7-3.noarch.rpm

Installed:
  mysql80-community-release.noarch 0:el7-3                                      

Complete!
```

mysql8.0のリポジトリを有効化にしていきます

```
yum-config-manager --disable mysql57-community
yum-config-manager --enable mysql80-community
```

mysql-community-clientをインストールする

```
[root@ip-10-0-1-10 ~]# yum install -y mysql-community-client

Installed:
  mysql-community-client.x86_64 0:8.0.26-1.el7                                  
  mysql-community-libs.x86_64 0:8.0.26-1.el7                                    
  mysql-community-libs-compat.x86_64 0:8.0.26-1.el7                             

Dependency Installed:
  mysql-community-client-plugins.x86_64 0:8.0.26-1.el7                          
  mysql-community-common.x86_64 0:8.0.26-1.el7                                  
  ncurses-compat-libs.x86_64 0:6.0-8.20170212.amzn2.1.3                         

Replaced:
  mariadb-libs.x86_64 1:5.5.68-1.amzn2                                          

Complete!

```

### RDSへ接続する

```
[root@ip-10-0-1-10 ~]# mysql -h database-1.c5jqncbegdvz.ap-northeast-1.rds.amazonaws.com -P 3306 -u admin -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 22
Server version: 8.0.23 Source distribution

Copyright (c) 2000, 2021, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>
```

# 参考
[MySQLクライアントで接続する方法](https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/USER_ConnectToInstance.html)
Mac のローカルで Web アプリを HTTPS で動かす

:::note info
**(2024.10 追記)** SAN に対応した新しい記事を書いたのでこちらを見たほうがいい
[OpenSSL コマンドで自己署名 SSL/TLS サーバ証明書を作成する (SAN 対応) - Qiita](https://qiita.com/hoto17296/items/b93187da939ef6f1cbb9)
:::

「Mac のローカルで Web アプリの開発環境を作りたいけど諸事情により HTTPS (TLS/SSL) が必須」という場合にシュッと作るためのメモ。

これを書いたときは macOS Big Sur でやった。

## 自己署名証明書を作成
``` console
$ openssl req -x509 -newkey rsa:4096 -sha256 -days 3650 -nodes -keyout local.key -out local.crt -subj "/CN=*.local"
```

秘密鍵 `local.key` と自己署名証明書 `local.crt` が作成される。

※ Common Name (CN) は指定しなくてもいいのかもしれない。

## 証明書を信頼する
作成した自己署名証明書をキーチェーンアクセスに追加して「SSL」と「X.509基本ポリシー」を「常に信頼」するように設定する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16369/62c01501-1045-bdf5-6ca7-0ff10954f5fa.png)


## 名前解決できるようにする
今回は開発環境を作りたいだけなので hosts ファイルをいじる。

``` :/etc/hosts
127.0.0.1       example.local
```

## Web サーバを動かす
ここは動かしたい Web サーバごとに異なるが、今回は試しに Node.js 製の http-server で静的なサイトを動かしてみる。

``` console
$ brew install http-server
```

```
$ http-server -p 443 -S -C <証明書ファイル> -K <秘密鍵ファイル>
```

Web ブラウザから `https://example.local/` にアクセスすれば見れるはず。