OmniAICreator/Qiita-1.07M huggingface dataset:
CodePipelineの自動デプロイを一時停止する手順

CodePipelineを利用して自動デプロイ環境を利用している際、一時的に自動デプロイを停止させたい時があると思います。
簡単にですか書き残しておこうと思います。

## 方法
1．コンソールからトリガーとなるブランチを変更する。
2．コンソールから `移行を無効にする` を設定する。
3．CLIでコマンドを打つ。　←手っ取り早い

### 1．コンソールからトリガーとなるブランチを変更する。
1．該当のPipelineを開く
2．右上の `編集する`　→　Sourceの `ステージを編集する`
![hensyu.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/382072/f46a136d-df48-e9c6-de2c-74bf67767de1.png)
![stagehensyu.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/382072/a02d0115-4bbc-4602-9ca8-a5dd58356078.png)
3．Sourceの鉛筆マークをクリック。
![a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/382072/d13ed5b1-2134-3e7f-25fd-3b4ed8bf7ebe.png)

4．ブランチ名を変更する。
![buranti.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/382072/07c34119-4bc2-90b7-c9d6-16e65e96c68c.png)
5．保存する。

戻し作業
ブランチ名を変更前に戻す。

### 2．コンソールから `移行を無効にする` を設定する
1．該当のPipelineを開く
2．Source　と　Buildの間にある `移行を無効にする` をクリック
![iko.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/382072/80e8db99-46ee-b2af-6781-c37d75fb1208.png)
3．無効にする理由を英語で記載し、保存する。
![muko.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/382072/e87f4f25-e6b5-b1a4-84e0-2e32d16a2b88.png)

戻し作業
 `移行を有効にする` を選択し保存する。

### 3．CLIでコマンドを打つ。
以下例文
MyfirstPipelineという名前のPipelineで、Stagingというステージへの遷移を、My reasonという理由で停止させる。

```
aws codepipeline disable-stage-transition \
--pipeline-name MyfirstPipeline \
--stage-name Staging \
--transition-type Inbound \
--reason "My reason"
```

戻し作業

```
aws codepipeline enable-stage-transition \
--pipeline-name MyFirstPipeline \
--stage-name Staging  \
--transition-type Inbound
```


#### 参考
[【AWS document】CodePipeline のステージ移行を操作する](https://docs.aws.amazon.com/ja_jp/codepipeline/latest/userguide/transitions.html#transitions-disable-enable-cli)
Python Tips

自分用に、少しずつ業務用ロジックをPythonでまとめて行きます。
## 1. 年度を求める
```
import pytz
import datetime
from dateutil.relativedelta import relativedelta

jst = pytz.timezone('Asia/Tokyo')
now = datetime.datetime.now(jst)
fiscal_year = (now + relativedelta(months=-3)).strftime("%Y")
```
現在から3カ月前の年を求めることで、年度が分かる。ここの年度というのは4月から3月までです。
Microsoft SQL Server 2008 R2 でバックアップ／CSVエクスポート

# 環境

- Microsoft SQL Server 2008 R2
- Windows 2003 Foundation


# 付属の SQL Server Management Studio での操作方法

## バックアップの場合

データベース単位です。

GUIのオブジェクトエクスプローラーから該当データベースを右クリック→タスク→バックアップ

## CSVエクスポートの場合

テーブル単位です。

GUIのオブジェクトエクスプローラーから該当データベースを右クリック→タスク→データのエクスポート

- 「SQL Server インポートおよびエクスポート ウィザードへようこそ」で「次へ」
- 「データソースの選択」で認証情報などを入力して「次へ」
- 「変換先の選択」で「フラット ファイル変換先」とし「ファイル名」を指定して「次へ」
- 「1つ以上のテーブルまたはビューからデータをコピーする(C)」を選んで「次へ」
- 「フラット ファイルの変換先の構成」でテーブルを選んで「次へ」
- 「すぐに実行する」にチェックを付けて「次へ」
-  内容を確認して「完了(F)」をすると出力されます

形式は以下のようなデフォルトでを使います。

- コードページは932
- 形式は区切り記号
- テキスト修飾子は<なし>
- 先頭データ行を列名として使用は「チェックしない」
- 変換先ファイルを区切る文字の指定は{CR}{LF}
- 列区切り記号はコンマ{,}
AWSソリューションアーキテクト-アソシエイト合格体験記

2月あたまにAWSソリューションアーキテクトーアソシエイトを受験してきました。スコアは788/1000で、合格ラインは公開されていないですが、720〜750という噂なのでかなりギリギリでした。正直も少し取れると思ってました。。AWSの公式模試を受けた時は正答率9割だったので、本番の試験は難易度1割増しくらいですかね。ちなみに私が受験した試験は2020年3月22日まで受験可能で、それ以降は改定版の試験になるようです。改定後は難しくなるのかな？とりあえず改定前に受けようと思いこのタイミングで受けてきました。このような記事はたくさんありますが、これから受ける方の参考に少しでもなれば幸いです。

# 受験までにやったこと
- AWSソリューションアーキテークトアソシエイトの黒本を読む（[黒本](https://www.amazon.co.jp/dp/B07M7S9GDL/ref=sspa_dk_detail_1?psc=1&spLa=ZW5jcnlwdGVkUXVhbGlmaWVyPUEzQ0xVVFQ1U1IxUk9LJmVuY3J5cHRlZElkPUEwNzI5MDc2MTFXRk5ZNDhXQ0UmZW5jcnlwdGVkQWRJZD1BMk1HOUpGVVdWUkFNViZ3aWRnZXROYW1lPXNwX2RldGFpbCZhY3Rpb249Y2xpY2tSZWRpcmVjdCZkb05vdExvZ0NsaWNrPXRydWU=)）
- 黒本の購入者特典の模試受験
- AWSの公式模試受験（2,000円）

簡単に私のAWS経験を紹介しておくと、会社の業務でIoTシステムのリフト＆シフトや、AWSネイティブのシステム開発などで約2年間程AWSを使ってきたので、前提知識は既にありました。ただ知識が断片的だったため、一度整理し直す為に黒本を読みました。基本的には読んで、章末問題を解く、章末問題でわからなかった部分は読み直す、これだけです。一通り読み終わったあと黒本特典の模擬試験を解き、よく理解できてない部分を重点的に黒本で復習しました。これだけでも十分かなと思ったのですが、試験料金が15,000円と高いこともあり絶対に落ちたくなかったので、念の為公式模試も受験しました。結果的には受けておいて良かったと思います。本番は似たような問題がたくさん出題されました。模試の内容を理解していれば7割くらいは解けるのではないかというレベル。ただ公式模試は、正答の割合しか教えてくれず、どの問題を間違えたのかがわからないため、復習に時間が掛かるのが難点です。その他には、Blackbeltなどは読んでいたのですが、業務で必要に応じて読んだ程度なので試験勉強としてやったことには含めていません。試験のための勉強時間はトータル20時間くらいでした。

# 試験当日
新宿駅前テストセンターというところで受けました。近くの吉野家でお昼を食べて、15分前に試験会場に行き、運転免許証と保険証を提示、署名や写真撮影などを済ませ（2〜3分）、ロッカーに荷物を預けたら準備完了です。あとはA4くらいのホワイトボードを渡されて試験室に入り、問題を解く。試験会場によっては、試験中に顔を触るだけで怒られる会場があるという噂を聞いていたのでビビっていましたが、この会場は全くそんなことはなくゆったり受けることができました。防音マフも快適でした。ホワイトボードの使い所はありません！1時間弱で解き終わり30分見直しして試験終了です。簡単なアンケートに答えたあとすぐに結果が表示されました。

# 翌日
ポータルからスコアを確認できますよ、というメールがきたので確認。冒頭にも書きましたがボーダーラインギリギリで結構ショックでした。IPAの某試験とは違い、何故か合格したから良いやという気持ちにはなれませんでした。あと知らなかったのですが、合格すると合格者限定ストアからグッズを買うことができるようです。ノートとか、帽子とかが売っているのですが個人的にあまり欲しいものはなかったです。その他には、別試験の模試がタダで受けられるコードなどの特典もありました。

# 最後に
業務で触ったことがないサービスも結構ありましたが、その辺は黒本の知識でもなんとかなりました。本を読んで初めて知ったことも多かったので、普段AWSを触っている人でも読んでおくことをおすすめします。知識の体系化にもなるので。次は他のアソシエイト資格を受験しようと思います。最終的に秋までにはソリューションアーキテクトプロフェッショナル取れるように頑張ります。
【JavaScript】書き方まとめ　全4種類

#JavaScriptとはどういうものか

簡単に言うとウェブページをリロードすることなく画面に変化を起こせるもの

例えばこの画面の左側（スマホの場合上）に記事をいいねするボタンやストックするボタンがあります
それらにカーソルを合わせると色が変わる、
クリックすると画像が変化するなどの処理はJavaScriptで書かれています

~~**LGTM**と**ストック**はチェックマークがついた状態がデフォルトです（すっとぼけ）~~
#1.HTMLファイルに直接書き込む \<script>
\<script>と\</script>の間にJavaScriptの処理を書き込みます
コンソールにHello Worldが表示されます


```html:html
<script>
console.log('Hello World');
</script>
```

#2.HTMLの要素の属性として書き込む(イベントハンドラ)
実行ボタンを押すとアラートが表示されます
実行のタイミングはイベントハンドラによって異なる


```html:html
<input type="button" value="実行" onclick="alert('Hello World')">
```


### イベントハンドラ例

| イベント<br>ハンドラ     |       動作    |  
|-----------------|---------------|
| onLoad|ページや画像の読み込みが完了した時に発生      
| onClick          |            要素やリンクをクリックした時に発生|       
| onSubmit         |フォームを送信しようとした時に発生          |        
|  onKeyDown              | キーを押した時に発生        |         
     
#3.外部ファイルに書き込む
拡張子が.jsのファイルを作り
JavaScriptファイルをHTMLファイルで読み込むことができます

```javascript:hello.js
function hello() {
 consol.log('hello');
}
```


```html:html
<!DOCTYPE html>
<html>
<head>
<title>任意のタイトル</title>
<script src="hello.js"></script>//ここでJavaScriptが実行される
</head>
・
・
</html>
```




#4.URL記述
`javascript:関数`と書くとJavaScriptの処理をURLのように扱うことができます
こんにちはをクリックするとコンソールにHello Worldが表示されます

```html:html
<a href="javascript:console.log('Hello World')">こんにちは</a>
```

#まとめ


４つ目のURL記述を初めて知り、これを機にJavaScriptの書き方についてまとめました
JavaScriptはHTML、CSSをやってきた人にとって初めての本格的なプログラミングになると思うので
書き方さえ覚えてしまえば
ググる→コピペ→うまく動く→書いてあることを理解する
の繰り返しで行けると思います！
頑張ってください:muscle:
最後まで目を通していただきありがとうございました！
![images.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/226884/1f747b12-afdb-f611-be3e-6c5894564ba0.jpeg)
421-4.7.28 [xxx.xxx.xxx.xxx] Our system has detected an unusual rate of unsolicited mail originating from your IP address.

# 背景

先日、メールサーバを切り替えたのだが、その際Gmailへの転送が一部失敗する現象に見舞われた。

解決できたので、調査の経緯含めて記載しておく。

「調査の経緯なんざどうでも良い、さっさと結論を教えろ!」な人は<a href="https://qiita.com/average_nobody/private/7f6523e5184f1083c3bf#%E8%A7%A3%E6%B1%BA">こちら</a>を見てください。

### メールの配送経路

他社MTA →　メールサーバ　→　Gmail(GSuite)

ユーザーのドメイン宛のメール自体は問題なくメールサーバに配送される。

ユーザーはGmail(GSuite)を導入しており[^1]、一部のアカウントでGmailへの転送設定が入っている。

全てではないが、Gmailへの転送メールの一部が421-4.7.28のエラーでメールの配送に失敗する。

### エラー内容抜粋(postfixのログ)

dsn=4.7.28, status=deferred (host gmail-smtp-in.l.google.com[64.233.189.26] said: 421-4.7.28 [xxx.xxx.xxx.xxx      15] Our system has detected an unusual rate of 421-4.7.28 unsolicited mail originating from your IP address. To protect our 421-4.7.28 users from spam, mail sent from your IP address has been temporarily 421-4.7.28 rate limited. Please visit 421-4.7.28  https://support.google.com/mail/?p=UnsolicitedRateLimitError to 421 4.7.28 review our Bulk Email Senders Guidelines.

※ xxx.xxx.xxx.xxxの箇所は切り替えたメールサーバのIPアドレスである。

# 調査および実施したこと

エラーメッセージからメールの流量がかなりあるようなので、単純にメールの流量を減らせばよいと思うのだが、それは難しそうである。

spamメールを含め、1日のメールの流量は7～8万通といったところ…

https://support.google.com/mail/?p=UnsolicitedRateLimitError

とりあえず、エラーメッセージ中の↑のURLの内容を読んで以下の対応をしてみた。

### DNSレコード確認

SPFレコードが正しく設定されているか改めて以下のURLで確認。

https://toolbox.googleapps.com/apps/checkmx/

→DKIM設定含め問題なし。

一応逆引きも問題ないか確認したが、問題なし。

### RBLチェック

構築時にも確認済みではあったが、切り替え後に改めてメールサーバのIPアドレスが不正中継やSPAMのブラックリストに載っていないか、以下のサイトで確認した。

http://www.anti-abuse.org/multi-rbl-check-results/
https://www.ers.trendmicro.com/reputations/index
http://www.reputationauthority.org/
https://sender.office.com/
http://www.blacklistmaster.com/check

→結果、いずれも問題なし。

### 別ドメインのGSuiteへ転送

弊社もGSuiteを導入しているので、転送先に自分のGmailのアドレスを追加。

→自分のメールは転送されるが、ユーザーのGmailは転送失敗することがある…

やはりGmailへの配送量が多すぎるのでは…

### GSuiteへ問い合わせ

サーバ側の設定、DNS周りに問題が見られないため、GSuiteのサポートへ問い合わせた。

# 解決

GSuiteのサポートより回答をもらい、GSuite側の以下の設定で問題回避できるとのこと。

受信メールのゲートウェイを設定する - G Suite 管理者 ヘルプ
https://support.google.com/a/answer/60730?hl=ja
※ [外部 IP を自動検出] をオンにされることをお勧めいたします

ユーザーに受信メールのゲートウェイを設定いただいたところ、キューに溜まっていたメールが徐々に配送されていき解決したのだった。

# 補足

受信メールのゲートウェイ設定前はSPAMメールもGmailへ転送されないようになっていたが、受信メールのゲートウェイを設定することによりSPAMメールも無条件に受け付けてしまうようになってしまいます。

所謂SPAMメールのログ

relay=gmail-smtp-in.l.google.com[108.177.97.26]:25, delay=1.7, delays=0.12/0.09/0.36/1.1, dsn=4.7.0, status=deferred (host gmail-smtp-in.l.google.com[108.177.97.26] said: 421-4.7.0 [xxx.xxx.xxx.xxx      15] Our system has detected that this message is 421-4.7.0 suspicious due to the nature of the content and/or the links within. 421-4.7.0 To best protect our users from spam, the message has been blocked. 421-4.7.0 Please visit 421 4.7.0  https://support.google.com/mail/answer/188131 for more information. l10si4307893pgi.19 - gsmtp (in reply to end of DATA command))

こちらの対策として、そもそもSPAMがメールサーバに来る前にTrend Micro Hosted Email SecurityやSymantec.cloudを導入してメールサーバに来るSPAMメールの絶対数を減らす以外なさそうだ。

[^1]: MXレコードをGSuiteに向けて、メールはGmailだけ使えばええやんというツッコミはなしで。
#Rails deny nill value but allow blank value validation / exclusion: { in: [nil] }

# Model

```rb
class User < ApplicationRecord
  validates :name, exclusion: { in: [nil] }
end
```

# 動作イメージ

```rb
User.create!(name: nil)

ActiveRecord::RecordInvalid: 名前 は予約されています

User.create!(name: "")
# 成功

```

# ガイド

![image](https://user-images.githubusercontent.com/13635059/74790955-7831fe80-52fc-11ea-9df5-6190fcd23008.png)


https://railsguides.jp/active_record_validations.html


# presence は？

空文字を禁止してしまう

>2.9 presence
>このヘルパーは、指定された属性が「空でない」ことを確認します。値がnilや空文字でない(つまり空欄でもなければホワイトスペースでもない)ことを確認するために、内部でblank?メソッドを使っています。

```rb
class Person < ApplicationRecord
  validates :name, :login, :email, presence: true
end
```

# allow_blank は？

値が未入力、空文字の時にバリデーションをスキップするためオプション指定であり、空文字を許容するわけではない

>3.2 :allow_blank
>:allow_blankオプションは:allow_nilオプションと似ています。このオプションを指定すると、属性の値がblank?に該当する場合（nilや空文字など）にバリデーションがパスします。


```rb
class Topic < ApplicationRecord
  validates :title, length: { is: 5 }, allow_blank: true
end
 
Topic.create(title: "").valid?  # => true
Topic.create(title: nil).valid? # => true

```

# Original by Github issue

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








<!-- Update From Qiita API -->

# チャットメンバー募集


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

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





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
Expo+Redux(+firebase)でログインフォーム①　〜概要・Expoの準備〜

# はじめに
フロントにReactNative、バックエンドにfirebaseを使ってログイン機能を作ってみたので記事を書いてみることにした。
完成形を紹介するだけではなく、実装した順に説明していきます。
Qiita初めてなので、わかりにくいのは大目に見てくれたら嬉しいです。
どんどんご意見お願いします！

# 作る機能とこの記事について
- ReactNativeによるサインアップ、サインインの画面
- ログイン、ログアウトに伴う画面遷移
- Reduxによるstate管理(ducksパターンを採用)
- Expoによる開発
- firebaseによる認証機能

このアプリの開発を、最初から順に書いていきたいと思います
今回は、概要とExpoの初期画面までを書きたいと思います。

# 使ったライブラリ
- Expo
- ReactNative
    - ReactNavigation(画面遷移)
    - ReactNativeDebugger(デバッグ)
    - Redux(state管理)
- redux ducksパターン
- firebase
    - Firebase Authentication(パスワード認証)

# ディレクトリ構成
```
root/
  ├ src/
      ├ App.tsx
      ├ store.ts
      ├ Styles.ts
      ├ components/
           ├ Counter.tsx
           ├ Signin.tsx
      ├ containers/
           ├ Counter.ts
           ├ Signin.ts
      ├ modules/
           ├ index.ts
           ├ CounterModule.ts
  ├ node_modules/
  ├ package.json
```
Expoはデフォルトでroot/App.jsを読み込みますが、root/src/App.tsxに移しています(詳しくは次回で)

# ハマったところ

### ReactNavigation
現時点での最新は5.x
ネットの情報は3.xや4.xの情報も混ざっているが、redux周りがかなり書き方に変更があり、注意が必要

### ReactNativeDebugger
この記事を参考にした
[ExpoアプリにReact Native Debuggerをセットアップする方法 [Mac OS用]](https://qiita.com/Tetsuya3850/items/e8d4450fcb3df5522b7a)

上の記事通りではうまく動かなかったので、少し修正した(詳しくは次回で)

# 作るときのオススメ
僕がこのアプリを作ろうとした時に、Qiitaの記事を集めてきて、組み合わせながら作ろうとしたところ、バグがいっぱいでかなり苦労しました。
結局公式のドキュメントを読むと解決したことが多いので、英語がしんどいですが公式ドキュメントを読むことをオススメします。
ドキュメントに載っているコードをベースに作っていくと、ハマりにくく進められますよ
[React チュートリアル(日本語)](https://ja.reactjs.org/tutorial/tutorial.html)
[Redux Basic Tutorial](https://redux.js.org/basics/basic-tutorial)
[ReactNavigation Fundamentals](https://reactnavigation.org/docs/en/getting-started.html)

# Expoの準備
こちらの記事を参考に
[誰でもアプリが作れちゃう！EXPOでreact-native入門](https://qiita.com/tommy96/items/448c87fd6950ec2b6265)

自分のデバイスで実行するためには、パソコンと同じwifiに接続する必要があるみたい
<img width="1440" alt="スクリーンショット 2020-02-20 15.40.49.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549051/d7844401-b9d0-8bff-39b3-77a4cf5499b9.png">
↑ yarn startしたところの画面

# 次回
今回は、Expoで開発を行う準備をしました。次回では、ReactNativeの開発をはじめ、Reduxを導入していきたいと思います。
[Expo+Redux(+firebase)でログインフォーム②　〜Reduxの導入〜](https://qiita.com/AtsushiNi/items/57851128a32020d2e1b8)
NSURLErrorDomainのコード一覧

[NSURLErrorDomain](https://developer.apple.com/documentation/foundation/nsurlerrordomain) のコード一覧を置いておきますね。ログでコードでてきてもすぐに結びつかないので...。

| name | value |
| --- | --- |
|NSURLErrorUnknown|-1|
|NSURLErrorCancelled|-999|
|NSURLErrorBadURL|-1000|
|NSURLErrorTimedOut|-1001|
|NSURLErrorUnsupportedURL|-1002|
|NSURLErrorCannotFindHost|-1003|
|NSURLErrorCannotConnectToHost|-1004|
|NSURLErrorNetworkConnectionLost|-1005|
|NSURLErrorDNSLookupFailed|-1006|
|NSURLErrorHTTPTooManyRedirects|-1007|
|NSURLErrorResourceUnavailable|-1008|
|NSURLErrorNotConnectedToInternet|-1009|
|NSURLErrorRedirectToNonExistentLocation|-1010|
|NSURLErrorBadServerResponse|-1011|
|NSURLErrorUserCancelledAuthentication|-1012|
|NSURLErrorUserAuthenticationRequired|-1013|
|NSURLErrorZeroByteResource|-1014|
|NSURLErrorCannotDecodeRawData|-1015|
|NSURLErrorCannotDecodeContentData|-1016|
|NSURLErrorCannotParseResponse|-1017|
|NSURLErrorAppTransportSecurityRequiresSecureConnection|-1022|
|NSURLErrorFileDoesNotExist|-1100|
|NSURLErrorFileIsDirectory|-1101|
|NSURLErrorNoPermissionsToReadFile|-1102|
|NSURLErrorDataLengthExceedsMaximum|-1103|
|NSURLErrorFileOutsideSafeArea|-1104|
|NSURLErrorSecureConnectionFailed|-1200|
|NSURLErrorServerCertificateHasBadDate|-1201|
|NSURLErrorServerCertificateUntrusted|-1202|
|NSURLErrorServerCertificateHasUnknownRoot|-1203|
|NSURLErrorServerCertificateNotYetValid|-1204|
|NSURLErrorClientCertificateRejected|-1205|
|NSURLErrorClientCertificateRequired|-1206|
|NSURLErrorCannotLoadFromNetwork|-2000|
|NSURLErrorCannotCreateFile|-3000|
|NSURLErrorCannotOpenFile|-3001|
|NSURLErrorCannotCloseFile|-3002|
|NSURLErrorCannotWriteToFile|-3003|
|NSURLErrorCannotRemoveFile|-3004|
|NSURLErrorCannotMoveFile|-3005|
|NSURLErrorDownloadDecodingFailedMidStream|-3006|
|NSURLErrorDownloadDecodingFailedToComplete|-3007|
|NSURLErrorInternationalRoamingOff|-1018|
|NSURLErrorCallIsActive|-1019|
|NSURLErrorDataNotAllowed|-1020|
|NSURLErrorRequestBodyStreamExhausted|-1021|
|NSURLErrorBackgroundSessionRequiresSharedContainer|-995|
|NSURLErrorBackgroundSessionInUseByAnotherProcess|-996|
|NSURLErrorBackgroundSessionWasDisconnected|-997|

出典) https://github.com/apple/swift-corelibs-foundation/blob/master/Sources/Foundation/NSURLError.swift
オンプレミスとの接続があるGCPネットワーク構成のサンプル

#はじめに

自社でデータセンターをお持ちな会社様で、GCP初めての方にNetwork設計のガイドをしていて、要件をヒアリングしていくとだいたい同じような構成をおすすめすることになるので、draw.ioで書いた[Network Diagram](https://drive.google.com/file/d/1Jl1n4m4GJ_8U03NUVJmBVtvnc9t0wMdY/view?usp=sharing)をサンプルとして置いておきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/78184/cddbe1d4-3f64-5205-b276-866acc2906dc.png)

各構成要素の説明は以下になります。

##Interconnect
VPCリソースに閉域網でアクセスしたいという要件をいただくことがよくあり、その場合はInterconnectをご紹介します。
また、DRについての相談もうけるため、99.99%の可用性を確保するためのマルチリージョン構成にしています。各リージョンごとに２つの線を引くため、経路が合計４本になります。

https://cloud.google.com/interconnect/docs/tutorials/dedicated-creating-9999-availability?hl=en

##Shared VPC
閉域網(Interconnect)アクセスが必要な場合、気にしなければならないのがVPCの設計です。GCPプロジェクトが作成されると、VPCが増えることになり、VCP単位でInterconnectの接続が必要なります。そうなると新規にGCPプロジェクトが追加になりVPCを作成した際に、オンプレミスのルータ側の作業やInterconnectの設定作業が必要になり、作業がオーバヘッドになります。Shared VPCを使えば、SharedVPCがネットワークハブとして使えるため、オンプレミスでの追加作業などが不要です。
Network Diagramの青色の部分です。
https://cloud.google.com/vpc/docs/shared-vpc?hl=ja

##Private Google Access for on-premises hosts
VPCの外にあるサービスに閉域網(Interconnect)経由でアクセスしたいという要件もよくいただきます。
その場合は、Private Google Access for on-premises hostsをお使いいただきます。
Network Diagramの紫の矢印のアクセス経路となります。
https://cloud.google.com/vpc/docs/configure-private-google-access

Private Google Access機能を使えば、VPC内のサービスからVPCの外にあるサービスにインターネットを経由せずにアクセスすることもできます。
Network Diagramの緑の矢印のアクセス経路となります。
https://cloud.google.com/vpc/docs/configure-private-google-access

##VPC Service Controls
VPCの外にあるサービスは、インターネット経由でネットワークアクセス可能です。認証認可の設定に不備があると、予期しないアクセスが発生する可能性があります。VPC Service Controlsを使うとアクセスを制限することができます。
Network Diagramの紫の点線と太字黒の矢印のアクセス経路となります。
https://cloud.google.com/vpc-service-controls/docs

#投稿内容は私個人の意見であり、所属企業・部門見解を代表するものではありません。
#Rails で nil は禁止するが blank ( 未入力/から文字の入力 ) は許容するバリデーション / exclusion: { in: [nil] } 

# Model

```rb
class User < ApplicationRecord
  validates :name, exclusion: { in: [nil] }
end
```

# 動作イメージ

```rb
User.create!(name: nil)

ActiveRecord::RecordInvalid: 名前 は予約されています

User.create!(name: "")
# 成功

```

# ガイド

![image](https://user-images.githubusercontent.com/13635059/74790955-7831fe80-52fc-11ea-9df5-6190fcd23008.png)


https://railsguides.jp/active_record_validations.html


# presence は？

空文字を禁止してしまう

>2.9 presence
>このヘルパーは、指定された属性が「空でない」ことを確認します。値がnilや空文字でない(つまり空欄でもなければホワイトスペースでもない)ことを確認するために、内部でblank?メソッドを使っています。

```rb
class Person < ApplicationRecord
  validates :name, :login, :email, presence: true
end
```

# allow_blank は？

値が未入力、空文字の時にバリデーションをスキップするためオプション指定であり、空文字を許容するわけではない

>3.2 :allow_blank
>:allow_blankオプションは:allow_nilオプションと似ています。このオプションを指定すると、属性の値がblank?に該当する場合（nilや空文字など）にバリデーションがパスします。


```rb
class Topic < ApplicationRecord
  validates :title, length: { is: 5 }, allow_blank: true
end
 
Topic.create(title: "").valid?  # => true
Topic.create(title: nil).valid? # => true

```

# Original by Github issue

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








<!-- Update From Qiita API -->

# チャットメンバー募集


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

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





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
docker メモ

# 概要
docker を使うたびに毎回ググっていて非効率的なので自分がよく使うものをまとめました。
そのうち内容を追加するかもしれないです。
本記事の任意の内容は暗黙的に (おれだったらこうする) の意を込めているので、参考にされる場合は適宜修正してもらえばと思います。

ベターな方法あるよ〜 / 間違ってるよ〜などあったら教えていただけると助かります。

# 前提
リモートサーバー上にコンテナを立てて中で機械学習したい。

# コンテナ編
## コンテナを立てる
コンテナを立てる時にすることは、

1. **コンテナに名前をつける**
    - `--name $CONTAINER_NAME`
2. **マウントするディレクトリを指定する**
    - `-v $DIR_SERVER:$DIR_CONTAINER`
    - マウントするディレクトリが前、コンテナ内にマウントしたディレクトリを配置する場所が後
    - ディレクトリの指定は絶対パスで行う
3. **ポートを指定する**
    - `-p $PORT_SERVER:$PORT_CONTAINER`
    - サーバーのポートが前、コンテナのポートが後

この3つ。**なお、これらの操作はコンテナを立てた後には変更できないので、変更したい場合はコンテナを作り直す必要がある。**

自分のいつも使っているコマンドはこんな感じ。

```
docker run --runtime=nvidia -it --privileged -v /home/$USER:/home/$USER -p 6006:6006 -p 8888:8888 --name $CONTAINER_NAME $IMAGE_NAME
```

① ホームディレクトリをマウントしつつ、② `6006` と `8888` のポートを外と繋げる。


## ポートを増やしたい or マウントするディレクトリを追加したい
前述の通り、これらの操作はコンテナを立てる時にしか実行できないので、

1. 新しくイメージからコンテナを立て直す
2. 現在使用しているコンテナをイメージ化して再びコンテナを立て直す

のどちらかを行う。前者は普通に `docker run` でOK。
後者は `docker commit` でコンテナをイメージ化して `docker run` する。

```
docker stop $CONTAINER_NAME
docker commit $CONTAINER_NAME $IMAGE_NAME
docker run ...
```


## コンテナに入りたい
バックエンドで起動しているコンテナに入りたい → `docker attach $CONTAINER_NAME`
終了しているコンテナに入りたい → `docker start $CONTAINER_NAME` ＋ `docker attach $CONTAINER_NAME`


## コンテナから抜けたい
バックエンドで起動したまま抜けたい → `ctrl + q + p`
コンテナ自体を終了させたい → `exit`

# サーバー編
## ポート設定
jupyter notebook や tensorboard をブラウザ上で使いたい場合、ローカルとリモートサーバを繋ぐ設定をする必要がある。

1. ローカルのポートとサーバのポートを繋ぐ
    - `ssh -L $PORT_LOCAL:$PORT_SERVER`
    - ローカルのポートが前、サーバーのポートが後
    - 踏み台サーバを経由する場合は、踏み台のポートも繋ぐ 
    - ex) `ssh -L $PORT_ROCAL:$PORT_VIA:$PORT_SERVER`
2. サーバのポートとコンテナのポートを繋ぐ 
    - `docker run -p $PORT_SERVER:$PORT_CONTAINER`

の2つをやればOK。

自分の場合、2. に関しては、サーバの `8888` とコンテナの `8888` を繋いだので、
1. はローカルの `18888` (任意のポート番号) とサーバの `8888` を繋げば、`localhost:18888` でコンテナの `8888` にアクセスできる。

```
ssh $SERVER_NAME -L 18888:8888 -L 16006:6006
```

ポートを複数繋げたいときは上記のように適宜 `-L` オプションを増やす。
Athena Presto SQLメモ（随時更新）

### はじめに
Athenaで日付を扱う場合は、元データの形式が`JavaのTIMESTAMP形式`が必須なので、違う形式の場合はsql側で処理する必要がある。

[Amazon Athena のテーブルにクエリを実行すると、TIMESTAMP の結果が空になる](https://aws.amazon.com/jp/premiumsupport/knowledge-center/query-table-athena-timestamp-empty/)

### iso8601形式の文字列をtimestamp型に変更

```sql
from_iso8601_timestamp(started_at)
```

### 経過時間(秒)を計算
```sql
date_diff('second', from_iso8601_timestamp(started_at), from_iso8601_timestamp(completed_at)) 
```

http://teradata.github.io/presto/docs/127t/functions/datetime.html

>date_diff(unit, timestamp1, timestamp2) → bigint
>Returns timestamp2 - timestamp1 expressed in terms of unit.

返り値の肩は`bigint`

### 経過時間を分に切り上げる
```sql
CEILING(cast(duration as DOUBLE) / 60)
```
Qiita bad request

Qiitaで画面を貼り付けようとすると、

```
![Bad Request]()
```

と出ることがある。

記事が小さくて、まず図から貼り付けようとした場合でも起きる。

原因は不明。よく使っているのはpngファイル。

対応は、いろいろ。

- 何度かやりなおす。
- 別の記事でやりなおす。
- 画像の形式pngからjpegに変える。
- ブラウザをchromeからsafariに替える

どこかでうまくいくことがある。
# 文書履歴(document history)
ver. 0.01 初稿 20200220
ver. 0.04 URL追記　20230302

### 最後までおよみいただきありがとうございました。

いいね　💚、フォローをお願いします。

####  Thank you very much for reading to the last sentence.

Please press the like icon 💚　and follow me for your happy life.
Rubyで配列の要素を検索置換する方法

WEB企業の研修中に学んだ事のアウトプットです。
配列の要素を検索し、その要素を別のオブジェクトで置換する方法です。
そういうメソッドがありそうですが、ないので工夫する必要があります。

一般的な方法
-

```ruby
array = ["foo","bar","baz"]

# arrayから"bar"を検索して"hoge"で置換します。
array.map!{|x| x=="bar" ? "hoge" : x}

puts array
#=> ["foo","hoge","baz"]
```




微妙な方法
-
 ※この方法でも検索置換できますが、検索ワードが配列に存在しない場合エラーになります。

```ruby
array = ["foo","bar","baz"]

# arrayから"bar"を検索して"hoge"で置換します。
array[array.index("bar")] = "hoge"

puts array
#=> ["foo","hoge","baz"]
```
非同期通信 Ajax　基礎文法 1

#はじめに
非同期通信を学んでいく上で、用語等を中心に整理していきます。
フレームワークはRailsを前提として進めております。
もうすでにご存知の方、省略の仕方等ご存知でしたら、ご教授願います。

#非同期通信（Ajax)とは
- リクエスト後にレスポンスが帰ってきた際、ブラウザが再読み込みされること無く通信が行われる通信方法
- 非同期通信　英語では（(Asynchronous JavaScript + XML)となる。　略称Ajax
- Ajaxでは、レスポンスのデータにJSONという形式が使われることが多い。

#JSON(JavaScriptObjectNotation)とは
- データ交換を行うためのデータ記述形式の一種
- Rubyのハッシュと同様、キーとバリューの組み合わせでデータを表現する形式

###今までの学習からの変化
- 今まではアプリケーションのレスポンスはHTML
   - その場合、ブラウザは全てのHTMLを書き換える。　→　画面が再読み込みされる。


###Ajaxの場合
- 主にJSON型でレスポンスが行われる。
- ブラウザではJavaScriptが動作する。
- JavaScriptはサーバーからJSON形式で返されたデータをHTMLに成形、ブラウザを書き換える。

    →　ブラウザの一部だけを更新することが可能になる。



#非同期通信の実装ポイント
#### JavaScriptを用いてリクエストを行う。
####デフォルトアクション
- HTMLの要素を操作した際に定められている挙動。

####JavaScriptのメソッドを利用してリクエストを送る。
- フォーム要素のデフォルトアクションを無効にする必要がある。
 
  　　→　この時、リクエストに対してのレスポンスはJSON形式で返して欲しい旨をリクエストに含む。

####コントローラでJSON形式のデータを用意するよう準備する。
- 同期通信の時は、特に指定もせずともHTML形式のデータを返すようRailsが動いてくれる。
- 非同期通信の時は、リクエストにJSON形式で返して欲しい旨の情報が含まれているため、その場合の対処をコントローラのアクションに明記する必要がある。

####レスポンスするためのJSON形式のデータを準備する。
- 同期通信の時は、viewsディレクトリの中に○○.html.erbという形式でHTMLのファイルを準備しておくことでレスポンスとしてHTMLを返すことができた。
- 非同期通信の時は、JSONのデータをレスポンスとして返す必要がある。
  - 短いデータであれば、コントローラ内に直接書くことができるが、同期通信の時と同じように、viewsディレクトリのなかにJSON形式のファイルを準備することもできる。
      
    →　この時のファイル名は、○○.json.jbuilderという形式となる。


####JavaScriptでレスポンスを受け取り、HTMLを操作して表示させたいJSONデータを追加する。
- 同期通信におけるレスポンスは、HTML形式であり、受け取ったHTMLを描画するためにブラウザは一度リロードされる。
- 非同期通信の場合は、ページがリロードされない。
  - 代わりに、レスポンスとして帰ってきたJSONのデータを利用して、HTMLを操作する。


#さいごに
日々勉強中ですので、随時更新します。
皆様の復習にご活用頂けますと幸いです。
sfdx force:source:deployで失敗したテスト結果を見やすく表示するワンライナー

CIでテスト失敗した時に不便だったのでワンライナーで工夫してみた。 [TL;DR](#ワンライナー)

# `force:apex:test:run`はテスト結果を見やすく表示してくれる

デフォルトだと `--resultformat human` で出力してくれます。[参考: コマンドリファレンス](https://developer.salesforce.com/docs/atlas.en-us.sfdx_cli_reference.meta/sfdx_cli_reference/cli_reference_force_apex.htm#cli_reference_test_run)

```
$ sfdx force:apex:test:run --tests HogeTest.test -w 10
=== Test Results
TEST NAME      OUTCOME  MESSAGE                                              RUNTIME (MS)
─────────────  ───────  ───────────────────────────────────────────────────  ────────────
HogeTest.test  Fail     System.AssertException: Assertion Failed: テスト失敗しました  12
                        Class.HogeTest.test: line 4, column 1
```

# `force:source:deploy`でテスト失敗したときは教えてくれない

`--json`以外に特に結果を出力するようなオプションが見当たりません。[参考: コマンドリファレンス](https://developer.salesforce.com/docs/atlas.en-us.sfdx_cli_reference.meta/sfdx_cli_reference/cli_reference_force_source.htm#cli_reference_deploy)
`--json`指定するとめっちゃ長い結果JSONが出力されてテスト結果の場所を見つけるのが大変です。
`force:source:deploy:report`しても`The metadata deploy operation failed.` くらいしか教えてくれません。
issueも立っていた https://github.com/forcedotcom/cli/issues/57

```
$ sfdx force:source:deploy -p "force-app/main/default/classes/HogeTest.cls" --testlevel RunSpecifiedTests --runtests HogeTest -w 10 --checkonly
Job ID | 0Af1y000002kGUICA2
SOURCE PROGRESS | ████████████████████░░░░░░░░░░░░░░░░░░░░ | 1/2 Files
$ sfdx force:source:deploy:report -i 0Af1y000002kGUICA2
Job ID | 0Af1y000002kGUICA2
SOURCE PROGRESS | ████████████████████░░░░░░░░░░░░░░░░░░░░ | 1/2 Files
ERROR running force:source:deploy:report:  The metadata deploy operation failed.
```

# ワンライナー

`--json`の結果を見やすく加工してみます。
※`force:source:deploy --json`の結果を `> result.json`というファイルに吐き出しています。

ワンライナーと言いつつ長いので見やすく改行しています。

```
if [ "$?" != "0" ]; then 
  cat result.json \
  | jq -r '.result.details.runTestResult.failures | if type=="array" then .[] else . end | [.name, .methodName, .message, .stackTrace] | @tsv' \
  | column -t -s $'\t' \
  | grep --color=auto -e '^.*$'
fi
```

## Travis CI上での結果表示はこんな感じになります

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/9490/1f8881cb-1b4b-1deb-757f-5e764b76b4cf.png)


## 解説

- `if [ "$?" != "0" ]; then `: テストに成功すると`force:source:deploy`が終了コード0を返すので成功した場合は特に何もしません。

### jqで結果のjsonをバラす
- `.result.details.runTestResult.failures`: resultの中のdetailsの中の
...と辿っていきます。
- `if type=="array" then .[] else . end`: **失敗が1つの場合はobject、複数の場合は配列で返ってくるというひどいフォーマット**なので型で判定して結果をバラします
- `[.name, .methodName, .message, .stackTrace]`: 欲しい属性だけを配列で取り出してレコード化
- `@tsv`: 最後にタブ区切りにして標準出力で次のパイプに繋げます

参考: https://qiita.com/Nakau/items/272bfd00b7a83d162e3a

## columnsコマンドで見やすく整形

- `column -t -s $'\t'`

## 色を付ける
- `grep --color=auto -e '^.*$'`: CIの結果で目立つようにエラー結果を赤で表示します。
Error: formula x.x is already installed To upgrade to x.x.x , run `brew upgrade formula`.

# brew update と set -e を一緒に使っていて処理が止まった
開発環境セットアップにて， `set -e` を使っていると，`brew install`の部分で処理が止まった．
よく観察してみると，`brew update`にて既存のアップデートがある場合にはerrorで返すことが見られた．

# 状況

```intialSetup.sh
set -e
brew install formula # 表題の出力とともにここで止まる．
echo  # brew install でエラー終了することにより実行されないことがある．
```

# 落ち着いた解法
packageがあるかどうかを確認してupgradeする．

```
if brew ls --versions ${formula} ; then 
  brew upgrade ${formula}
else
  brew install ${formula}
fi
```

# コミュニティで報告されていた解法
エラー出力を捨てる．

```
brew install ${formula} 2>/dev/null && true
```

# installだけ set +e 解除する

```
set +e
brew install ${formula}
set -e
```

# 参考
https://github.com/Homebrew/brew/issues/2491
brew側では，upgrade-if-installedみたいなオプションを実装する予定はないみたい
LTSVファイルのラベル一覧を取得する

LTSVで出力されたログファイルを BigQueryに食わせるのに
スキーマを決める必要があり
あれ、このLTSVってどんなラベルが存在するんだっけ？ というので調べたときのコマンド。

各行かならず同じ項目が出力されるなら1行みて調べればいいんだけど
状況によって項目が一部あったりなかったりするようなログだったので
ファイル全体をなめて調べたかった。

```
cat ltsv.log | sed "s/\t/\n/g" | cut -d":" -f1 | sort | uniq
```
Slack bot でコマンド実行するときに、スマート引用符にハマった話

社内で、Slack bot で AWS Lambdaを起動する仕組みがあり
「このコマンドで行けるよ」と教えられ、コマンドをコピペしてSlackに投稿したところ
以下のエラーが出た

```
@aws lambda invoke --payload {"foo": "bar"} --function-name awesome-function --region ap-northeast-1
but unfortunately the service returned an exception:
Could not parse request body into json: Unexpected character ('“' (code 8220 / 0x201c)): was expecting double-quote to start field name
```

しばらく意味がわからず悩んでいたのだが、`code 8220 / 0x201c` のあたりをみて
引用符が勝手に変換されてるのでは？と気づいた。
（Microsoft Wordとかでデフォルトで使ってるとなる、引用符を自動的に変換するやつ）

調べてみると予想通り、Slackにコマンドをペーストしたタイミングで、
Macの「スマート引用符」の機能がはたらいて
ASCIIのダブルクウォートではない文字に置き換わってしまっていたのが原因。

キーボードの設定から「スマート引用符とスマートダッシュを使用」をOffにしたら解決した。

<img width="664" alt="mac-keyboard-setting.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/105558/403aae32-2ec8-52f0-4bd0-2bafcf64be23.png">
python モジュールのインポートがVSCODEではできなくて、juoyterlab上で,できたため原因を探る話

先日、急にVSCODE上でpython モジュールであるpyqueryがimport出来なくなった事象が発生。エラー内容としては以下のようになる。

```python:qiita.rb
Traceback (most recent call last):
  File "c:\Users\name\Documents\excel_python\python_prg\today_stockinfo_toDB.py", line 1, in <module>
    from pyquery import PyQuery
  File "D:\Anaconda3\lib\site-packages\pyquery\__init__.py", line 7, in <module>
    from .pyquery import PyQuery  # NOQA
  File "D:\Anaconda3\lib\site-packages\pyquery\pyquery.py", line 11, in <module>
    from lxml import etree
ImportError: DLL load failed: 指定されたモジュールが見つかりません。
PS C:\Users\name\Documents\excel_python\python_prg> conda activate base
```

ただし、jupyterlab上では問題なくpyqueryのimporetが出来たので原因を探っていく次第。

まず、vscode上でモジュールが存在するかどうかを確認する。

```python:qiita.rb
$ py -m pip list
・
・
・
・
pyquery                            1.4.1
```
ありました。

次に、このpyqueryがどこに保存されているのかそのパスの確認を行います。

```python:qiita.rb
$ py -m pip show pyquery
・
・
・
Location: d:\anaconda3\lib\site-packages
```

このパスに存在していることまで確認が取れました。

続いてJupyterLab上で周回しているpathとVSCODE上で周回しているpathを見比べます。

まずはjupyterlabのもの

```python:qiita.rb
import sys
sys.path


['C:\\Users\\name\\Documents\\excel_python\\python_prg',
 'D:\\Anaconda3\\python37.zip',
 'D:\\Anaconda3\\DLLs',
 'D:\\Anaconda3\\lib',
 'D:\\Anaconda3',
 '',
 'D:\\Anaconda3\\lib\\site-packages',
 'D:\\Anaconda3\\lib\\site-packages\\win32',
 'D:\\Anaconda3\\lib\\site-packages\\win32\\lib',
 'D:\\Anaconda3\\lib\\site-packages\\Pythonwin',
 'D:\\Anaconda3\\lib\\site-packages\\IPython\\extensions',
 'C:\\Users\\name\\.ipython']
```

d:\anaconda3\lib\site-packagesは含まれています。

続いてVSCODE上のもの

```python:qiita.rb
import sys
sys.path

'c:\\Users\\name\\Documents\\excel_python\\python_prg', 
 'D:\\Anaconda3\\python37.zip', 
 'D:\\Anaconda3\\DLLs', 
 'D:\\Anaconda3\\lib', 
 'D:\\Anaconda3', 
 'D:\\Anaconda3\\lib\\site-packages', 
 'D:\\Anaconda3\\lib\\site-packages\\win32', 
 'D:\\Anaconda3\\lib\\site-packages\\win32\\lib', 
 'D:\\Anaconda3\\lib\\site-packages\\Pythonwin']
```

おや、どちらもd:\anaconda3\lib\site-packagesは含まれています。
おかしい、pyqueryは存在し、どちらもpathは通っているのにjupyterlab上は
起動できてvscode上は起動できないのか

ここにきてお手上げ、試しにVSCODEで通っていないパス 'D:\\Anaconda3\\lib\\site-packages\\IPython\\extensions','C:\\Users\\name\\.ipython'の二つをvscodeでも
追加してみましたが、症状に改善見られず。しばらくpyqueryを使うときはjupyterlab上で使用するのを余儀なくされそうです。
VSCodeでLaravelの「.env」ファイルをDotEnvに関連付ける

## 概要
開発、ステージング、商用、etc.など
環境によって「.env」を増やしたいことがあると思います。
VSCodeを使用している場合はDotEnvプラグインを入れると関連付けされて、見やすくなります。
しかし、関連付け対象のデフォルト設定にないファイル、例えば「.env.xxxx」など関連付けされません。
ここでは、デフォルトにないファイルへの関連付け方法を、簡単ですが記載させていただきます。

## コマンドパレットを開く

まずVSCodeコマンドパレットを開きます
- メニューの表示 > コマンドパレット
(macは「shift + command + p」で開きます)

## 以下のように入力します。
コマンドパレットに、setting.jsonと入力します。
![スクリーンショット 2020-02-20 9.15.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/297965/eb119f9c-7e2f-b0c5-9107-8b229821eb51.png)
## setting.jsonが開きます
![スクリーンショット 2020-02-20 9.51.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/297965/3b51393a-ed3b-d998-42db-a057aaa22742.png)
編集可能なsetting.jsonを選びます。
VSCodeの設定により、画面左にデフォルト、画面右に編集可能なsetting.jsonのペインが開きます。
setting.jsonのfiles.associationsに関連付けを追記します。

## files.associations
"files.associations": {
   ここに関連付けを書きます。
 }

### 例
    "files.associations": {
        ".env.dev01": "dotenv",
        ".env.dev*": "dotenv",
        ".env.management*": "dotenv",
        ".env.production.aws*": "dotenv",
        ".env.development*": "dotenv",
    },

以上です

## 補足：DotEnvのGitHub
[vscode-dotenvのGit](https://github.com/mikestead/vscode-dotenv)
【ふくだ学習録】アプリ制作part9【36日目】

# ふくだ学習録とは？
ふくだが学習したことの備忘録。
目に見える形で残すことによってやる気を出す個人的な作戦です。
他人に見せるように書いているわけではないので、すごく読みにくいです。

### 読了した本
[データベースエンジニア養成読本 [DBを自由自在に活用するための知識とノウハウ満載!]](https://www.amazon.co.jp/dp/4774158062/ref=cm_sw_r_tw_dp_U_x_FPphEbQFPPQRM )
[ゼロから作るDeepLearning](https://www.amazon.co.jp/dp/4873117585/ref=cm_sw_r_tw_dp_U_x_y3UiEbF3P6EG7)
[PHPフレームワーク CakePHP 3入門](https://www.amazon.co.jp/dp/4798048577/ref=cm_sw_r_tw_dp_U_x_.YIjEbS1K4JY2)
[SQLアンチパターン](https://www.amazon.co.jp/dp/4873115892/ref=cm_sw_r_tw_dp_U_x_XlokEbJQK2N7P )
[Docker入門](https://www.amazon.co.jp/dp/480071091X/ref=cm_sw_r_tw_dp_U_x_xVlmEbN8ZTHZK)


### 今読んでいる本

なし

# アプリ制作

### WebDriverWaitについて
seleniumは実行が早すぎるため、要素が表示される前にクロールしてしまう場合があり、クローリングが安定しない場合がある。`WebDriverWait`関数を用いることにより、任意のHTMLの要素が特定の状態になるまで待つことができるようになるので、クローリングが安定する。

使い方は下記のような感じ。

```python
def get_dom(query):
   dom = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.CSS_SELECTOR, query)))
   return dom
```

`WebDriverWait`の第一引数でWaitさせたいWebDriverを指定し、第二引数でタイムアウトさせる秒数を設定する。
`until`では「WebDriverをWaitさせ続け条件」を記載する。上の例では`query`で渡されたcssセレクタを持っているものが対象になる。
`EC`はexpected_conditionsをエイリアスで呼び出しており、`presence_of_element_located`関数でHTML要素の存在を確認している。この関数は何種類もあるので、設定したい条件に応じて別の関数を使用する。

[Seleniumのコードを安定して動かすためにWaitを使って要素を待つ](https://www.soudegesu.com/post/python/selenium-wait-element/)


### 動的に生成されるクラス名に対してのスクレイピング
動的に生成される静的なクラス名（ID名）の要素に対しては、スクレイピングで情報取得できるようになった。
ただ、動的に生成され、かつクラス名（ID名）も動的に生成される（毎回変わる）要素に関しては取得がうまくいかない。
次は下記の2つの方法を試してみる。

①固定IDで吐き出されるDOM要素からの相対パス指定。
②一定時間後にDOM全体をスナップショット（言葉遣いあってるかな？）して、その後解析
上記どちらがが良いのかな？っていう所感はある。

一旦は①を試してみて、難しそうならば②を試してみる。
（①で行けそうなんやけどなぁ）

# 今日の一言
早起き出来ひんくなってきた！あかん！朝型の体にする！
【Laravel】php artisan migrateをしたときに出くわしがちなエラー【ただのDBエラー】

Laravel: php artisan migrateをしたときに出くわしがちなエラー

# エラー例

## 外部キーの型が一致しない

外部キーを付けるフィールドの型と参照先フィールドの型が一致していないとデータベースエラーが起こります。
特にLaravel5.8以降では主キーの型はデフォルトでUNSIGNED BIGINTになっています。
外部キーの型がINTEGERのままだとこのエラーに遭遇します。

```
Illuminate\Database\QueryException  : SQLSTATE[HY000]: General error: 3780 Referencing column 〜
```

### 対策

マイグレーションファイルの型を揃える。

```
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('photos', function (Blueprint $table) {
            $table->string('id')->primary();
            // $table->unsignedInteger('user_id'); // user.idがINTEGERならこちら
            $table->bigInteger('user_id')->unsigned(); // user.idがUNSIGNED BIGINTならこちら
            $table->string('filename');
            $table->timestamps();

            $table->foreign('user_id')->references('id')->on('users');
        });
    }
```


参考: [Laravel 5\.8 にて\["SQLSTATE\[HY000\]: General error: 1215 Cannot add foreign key constraint"\]エラー \- Qiita](https://qiita.com/ktknj/items/6a3e1936da727dbd92b3)


## すでにテーブルが存在する

```
Illuminate\Database\QueryException  : SQLSTATE[42S01]: Base table or view already exists: 1050 Table 'photos' already exists 〜
```

中途半端にテーブルが残っているとよく出くわします。
`php artisan migrate`に失敗すると中途半端にテーブルができることがあります。
（私は上記の「外部キーの型が一致しない」の事例でまさに中途半端なテーブルができました。）

### 対策

「:fresh」をコマンドの最後に付けることで既存のテーブルを消して作り直すので回避できます。
**※全テーブルの中身が消えるので十分に注意してください**

```
php artisan migrate:fresh
```

参考: [Laravel の migrate で Base table or view already exists というときに、migrate:refresh した \- Qiita](https://qiita.com/pugiemonn/items/d3e2efe6dac4e6a760f7)

あるいは、直接テーブルを消してもよいでしょう。


## コントローラファイルが見つからない

```
ErrorException (E_WARNING)
include(/hogehoge/backend/vendor/composer/../../app/Http/Controllers/元のコントローラをコピーして作ったファイル名.php): 
failed to open stream: No such file or directory
```
CompaniesController.phpを複製して、CompaniesController-.phpを作りました。
オートローダーの設定が変になっていたので、プロジェクトルートから下記コマンドで修正しました。

```
composer dump-autoload
```

php artisan migrateの影響かはわかりませんが、コマンド実行後、もとのコントローラをいくらさわっても反映されないのでコピーしたファイルを消すと上記のエラーが発生しました。

下記に同じ現象の解決法が記載されていました。

[Laravel 5\.7でControllerのファイル名を少し変更（大文字）しただけなのに、Controllerファイルが見つからないエラーが出るようになった \- Qiita](https://qiita.com/shumiyao/items/0e0d6eac2dca5b83baa8)
【3分でできる】Herokuの無料プランでもスリープせずに高速化する方法【アドオン不要】

## 概要

Herokuの無料のdynoプランでアプリをデプロイしている人も多いかと思います。

その時の問題点は30分アクセスがなければ、Herokuがスリープしてしまい、次回アクセス時にレスポンスが返ってくるのに時間がかかるという点です。無料で使わせてもらっているとはいえ、やっぱりレスポンスは速くしたい！

そこで今回は、無料でもHerokuを24時間稼働させる方法を実践してまとめました。

## 結論

GAS(Google Apps Script)で定期的にHerokuの該当アプリにアクセスする。

## 具体的な内容

### 1. GASの設定

GASの新規プロジェクトを作成して以下のコードを準備します。シンプルに特定のurlにアクセスしているだけです。コードを設置したら一度デバッグして正常に動くか確認しましょう。なお、ファイル名はデフォルトのままでも構いません。

GASのプロジェクト作成はこちら
https://script.google.com/

```JavaScript:main.gs

function main() 
{
  // sleepさせたくないアプリのurl
  var url = 'https://kusutan.com';
  var data = UrlFetchApp.fetch(url).getContentText();
}
```

### 2. トリガーの設定

コードが正常に動くことを確認したら、トリガーを設定してGASの方でこのプログラムを自動で実行するように設定します。添付画像の赤マークを選択して、トリガー設定画面に移動します。

![スクリーンショット 2020-02-20 8.39.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/36927/0be961b8-f5fa-be11-a78a-60924597d68c.png)

「トリガーを追加」を押して添付画像の用に設定したのち、保存ボタンを押したら自動でプログラムが実行されます。つまり、15分おきにHerokuのアプリにアクセスしてくれるので、Herokuが常に起動している状態になるのです！

![スクリーンショット 2020-02-20 8.39.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/36927/ebf9b5db-4cd2-c2fc-8351-a28d6850b1c2.png)

## 注意点

現状だとこの方法でHerokuのフリープランを使えるのは1つのアプリのみになります。どうしても複数アプリを常時起動させたい場合は、有料プランを使うか、サーバを借りるかしましょう。

HerokuのFree Dynoについて
https://devcenter.heroku.com/articles/free-dyno-hours

## おまけ

この方法を使って、APIサーバとしてHerokuを使って簡単なAndroidアプリをリリースしました。
いつアクセスしてもすぐにレスポンスが来るようになっているのがわかるかと思います！

プログラミング勉強会検索＠鹿児島
https://play.google.com/store/apps/details?id=com.ksyst.connpass
継続的デリバリのための継続的テスト：mabl Japan 1  参加報告

#はじめに

#セッション内容
## "The Era of Intelligent Testing" “インテリジェントテストの時代”
先日と同じ話です


何回も何回もテストしたのにバグが出る
画面を見てユーザが何をしたいかを分析をする
そして、トラフィック、プライオリティを考えてそのカバレッジをとれるようにする


## JapanTaxi での mabl 活用事例の紹介


mablりましょう！


ソフトウェア品質と開発生産性を挙げ多くの施策案死してリリースできる仕組みを作る

戦略は「攻めの自動化」と「シフトレフト」


### 攻めの自動化

当たり前品質はソフトウェア技術でカバーする


* テストデータ作成
* リグレッションテスト
* レポーティング

### シフトレフト
バグを見つけるから作らない
要件定義参加を目指し手戻りを最小限
魅力的品質にかかわる足掛かり


複雑なシステムがあるのでテストが難しいのでテストトールを作っている

* テストするツールを作成している
* 繰り返し行われる手順をAPI化
* mablからもAPIステップを使う
* テストためなら基本的に何でもする

SaaS利用の理由

* ツールは改善され続ける
* 専門家のサポートが得られる
* 製品自体のミッションに専念できる
* 遅いステップやエラーが発生した箇所を把握
* シナリオを良しなに修正
* 機能改善スピードが速い
* データパターンの多いフォーム系でバグを発見
* デグレの不安がなくて機能追加に専念できる


品質は偶然の出来事ではない


## mabl を融和させるための取り組み in クラウドサイン


mablの導入理由
* プロダクトの特性
* 契約が行えないとダメで品質を高い状態を保つプレッシャー
* 画面操作のみでE2Eテストができる
* マルチブラウザに対応（webdriverに依存しない）


逐次リリースされる機能についてのテスト
リグレッションテスト


### 心理的ハードル
3つの心理的ハードルを下げた

||||
|---|---|---|
|難易度のハードル|どう使えばいいのか、使いづらい（習得までのハードル）　|mablを選択|
|情報伝播のハードル|属人化排除|開発メンバーを巻き込んで情報共有|
|自走のハードル|何をすればいいの、どうすればいいのか|メンバーがテストを作成する際の補助|

仮組み → テスト対象の画面の前後のテストを作成
本組み → テスト対象のテストを作りこみ


直接的なメリットは、確認作業が激減
副次的なメリットは、テストするとき俯瞰的に画面と向き変える

運用し続けて定期的に全件テスト




# 感想

実際にmablを利用しているプロジェクトの話を聞けてどのようなメリットがあるかを知ることができた。

少人数でテストを実施し品質をあげるためには、テスト自体に注力できるようにしなければいけないなというのも各セッションで同じようなことを言っていたのも納得できる。

あと関係ないけど、テストケースの管理で TestLink 使っているって言ったら、あのクソ使いにくいツール使っているんですか？って言われますたｗｗｗ
使いやすいとは言わないんですが、無料でより使いやすいもので替えることができるものを知りたい。。。

管理しづらいEXCELシートテストケースには戻したくはないし、BTSやユニットテストとある程度連携したいので。。。
LightGBMのスコアをベータ分布でフィッティングした

## 前置き
二値分類モデルの学習ではLightGBM一択な今日この頃。ですが、そこで吐き出されるスコアは必ずしも確率値を示していないと常々悩んでおりました。これを何とかしたいと色々試行錯誤していたらそれなりに良さそうなやり方を思いつきました。

## 二値分類とは
二値分類とはゼロかイチかを当てる機械学習のタスクです。用語としては正か負かという言い方のほうが機械学習っぽいかと思うので以下ではそうやって書きます。

よくあるのが病気の診断で、検査結果から受診者が罹患しているか（正）、罹患していないか（負）を判定する、という類のタスクです。二値分類モデルに受診者の性別年齢と各種検査を投入すると、その人が罹患している可能性をスコアとして出してくれるというのがモデルに求められる機能ですが、正か負かと二つに一つで判断するためには適当な閾値でスコアを区切る必要があります。スコアの順番に並べて適当な閾値で区切ればよいので、「罹患している可能性」は確率値でなくてもよいわけです。

しかし、「罹患している可能性」の高低でなくて、ずばり確率値で欲しい場合もあります。例えば、サービスAとサービスBがあったときに、ユーザに片方だけを訴求するなどちらがよいかといった場合です。これも二値分類の応用となりますが、加入確率の高いものを訴求、となるとA、Bそれぞれの二値分類スコアが比較可能でなくてはなりません。つまり、スケールやバイアスが同じである必要があるということです。

## 予測値の分布
### LightGBMによる学習
kaggleからsantanderのデータをLightGBMに放り込んでモデルを作りました。これは金融商品の購入をするか否かのデータセットで、正例割合が10%と程よく不均衡です。目的変数は1か0ですが、書きやすさのため1を正、0を負と書きます。

パラメータはこんな感じ。不均衡なデータだとis_unbalanceを入れておくと、正負が半々になるようにサンプリングして学習するので予測値が適度に広がります。

|  パラメータ  |  値  |
| ---- | ---- |
|  objective  |  binary  |
|  num_leaves  |  15  |
|  is_unbalane|  True|
|  num_boost_round  |  100  |

### スコアと正例割合
データ点ごとのスコアを0.01刻みにまとめて正例の割合をとってみます。そうするとスコアと正例割合の相関図を描くことができます。ちなみに、rmseは対角線からの誤差です。

![pr_plot_min.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/311070/c714444d-8403-eb60-1d3c-e0872f468049.png)


これが(0,0), (1,1)の対角線と重なると、予想値がそのまま正例割合を予測することになって、応用的にはいろいろとうれしいわけです。

### スコアの分布
正負別々に分布をみてみるとこんな感じ。

![score_hist_train_min.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/311070/1771c8b1-2461-2e8b-3e7b-44aa1888d84f.png)


正例と負例が重なる予測値の範囲では正例割合が0 
から1になります。重ならない範囲では負例のみであれば正例割合は0、正例のみの分布であれば正例割合は1になります。そんなわけで上のようなシグモイドっぽい相関図になるわけです。

### ベータ分布
ところでこの形、ベータ分布にそっくりです。形もベータ分布っぽいなら確率変数が0から1だということもベータ分布と同じです。というわけで、平均と分散からalpha, betaを求めましょう。

```math
e = \frac{a}{a+b}
```
```math
v = \frac{ab}{ (a+b)^2 (a+b+1)}
```

これを解いてやると、

```math
a = \frac{e^2 (1-e)}{v}-e
```
```math
b = \frac{(1-e)}{e}a
```

上記パラメータでベータ分布のランダムサンプリングを描くとこんな感じ。

![beta_random_hist_min.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/311070/dabe2fb2-ed82-1fff-c492-a94dbd81da1f.png)


0.1や0.9近辺では少し形が違いますが、まあいいでしょう。

## 正例割合の予測
正負それぞれのalpha, betaがあれば後は0から1の任意の確率変数から正負それぞれの確率密度が計算できます。さらに、元のデータの正負の数があれば、任意の確率変数での正負の割合が計算できます。


```math
Y = \frac{N_p\times Beta_p}{N_p\times Beta_p + N_n\times Beta_n}
```


LightGBMからの元々の予測値に対して、べーて分布からの予測値をプロットするとこんな感じ。

![score_cal_score_plot_min.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/311070/35e9dda9-7395-5545-9fb1-fa23bd4c90f2.png)



さらにベータ分布からの予測値と先ほどの正例割合との相関図はこんな感じ。

![cal_score_ratio_plot_min.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/311070/fa9fa569-fe73-9ca9-cca4-490b56d04a38.png)



対角線にかなり近づいていることがわかります。

というわけで、LightGBMとベータ分布の二段構えで、予測値と正例割合を対角線上に近づけることができました。

## まとめ
 * 二値分類モデルから出てくるスコアは正例割合とプロットしたときに対角線に乗らないことが多い。
 * スコアを適当なパラメトリックな分布にフィッティングできればスコアから正例割合を計算できる。

## あとがき
3/1に技術書典8で本を出す予定でしたが、例のウィルスのおかげで中止となってしまいました。
Blender2.8x 対称化がうまくいかないときの対処法

簡単に備忘録を

blenderを使っていて手足を片側だけつくってそれを対称化してしようとしたら
対称の軸がなんか変なことになって傾いてミラー（対称）化されることがあったため
やったことを

オブジェクトモードで対象物（オブジェクト）を選択して
Crtl + A
位置、回転、拡大縮小にチェックをいれる

それだけ

あとは、対称化してやればうまくいった。
Download Boot faild.AndroidTool_Release for RockChip. 下载Boot失败

I met the problem `Download Boot faild` when i use AndroidTool_Release_v2.71 to flash new OS with windows.
you can solve the problem. 
#####push the reset button on your rockchip product then RUN（执行）again.

it will be success.
![20200220_114936.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563531/68a2f758-d257-e5e3-bccb-52c898d27445.jpeg)


Source
https://dev.t-firefly.com/thread-12148-1-1.html

If you get another bug you can download latest version(2.71 or more) of AndroidTool_Release for rockchip product
https://github.com/rockchip-linux/tools
初心者によるプログラミング学習ログ 244日目

#100日チャレンジの244日目

twitterの100日チャレンジ#タグ、#100DaysOfCode実施中です。

すでに100日超えましたが、継続。

100日チャレンジは、ぱぺまぺの中ではプログラミングに限らず継続学習のために使っています。

244日目は、
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">おはようございます<br>244日目<br>・youtubeで、webサイト模写<a href="https://twitter.com/hashtag/%E6%97%A9%E8%B5%B7%E3%81%8D%E3%83%81%E3%83%A3%E3%83%AC%E3%83%B3%E3%82%B8?src=hash&amp;ref_src=twsrc%5Etfw">#早起きチャレンジ</a><a href="https://twitter.com/hashtag/%E9%A7%86%E3%81%91%E5%87%BA%E3%81%97%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%8B%E3%82%A2%E3%81%A8%E7%B9%8B%E3%81%8C%E3%82%8A%E3%81%9F%E3%81%84?src=hash&amp;ref_src=twsrc%5Etfw">#駆け出しエンジニアと繋がりたい</a><a href="https://twitter.com/hashtag/100DaysOfCode?src=hash&amp;ref_src=twsrc%5Etfw">#100DaysOfCode</a></p>&mdash; ぱぺまぺ@webエンジニアを目指したい社畜 (@yudapinokio) <a href="https://twitter.com/yudapinokio/status/1230218475047546880?ref_src=twsrc%5Etfw">February 19, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
マウスクリックをキー入力（FやＧなど）の代わりにしたい

こんにちは、私はUnityを初めて二カ月の初心者です。
D,F,G,H,J,の5つのキーを使ってリズムゲーを作っていましたが、
今日、Android用にビルドしたところ、スマホではこの5つの入力が使えない、という超初歩的なことに気づきました。

他のUIのクリックボタンは、当然タッチで出来ますが、キー入力で作ったものをタッチ入力に変える方法がどうしてもわかりません。

初心者なので、この対処法は、
①5つのGameObjectをつくる。
②これらにタッチすると、D,F,G,H,J,それぞれのキー入力をしたことにするスクリプトを書き、アタッチする。
という方法にしたいと思っています。

この実現の為、色々調べまして、様々な入力方法のコードの書き方は分かったのですが、その先の、
「このInputがあったらキー入力をしたことにするスクリプト」の書き方が全く分かりません。

知っているかたがいらっしゃましたら、ご教授いただけますでしょうか。
よろしくお願いいたします。
GCPでGitHubのレポジトリをソース管理として使用する方法

#概要

GCPでGitHubのレポジトリをGCPで利用するにはどうすればいいかという話。
AzureだとGitHubを直接利用するが、GCPではCloud Source Repositories（以降、CSR）というソース管理があるのでこれを使用する。
ベンダーロックインが気になるかもしれないが、GitHubとミラーリング設定をすればCSRを意識する必要はない。
GitHubにプッシュすれば自動でCSRに反映されるため、Azure同様にGitHubを唯一のソース管理として作業できる。

#手順

基本的に公式ドキュメントのGitHubのミラーリング手順をそのまま実施すればOK。
GitHubのレポジトリの指定と承認するだけなので引っかかることはないはず。
https://cloud.google.com/source-repositories/docs/mirroring-a-github-repository

いくつか補足しておく。

- プロジェクトは有効な課金アカウントに結びついておかなければならない。
    - これをタイプした当時の記憶がもうないが、Firebaseの無料プランから遷移した場合には使用できなかった？
- 新規のミラーリングについては数時間かかることもある模様。私の場合は3分程度で完了した。
    https://cloud.google.com/source-repositories/docs/troubleshooting?authuser=0#search_results_dont_match_expectations
- ミラーリングと聞くと遅延が気になるが、GitHubにプッシュしたらすぐにミラーリングされるようで気にしたことはない。


#その他参考にしたドキュメント

Cloud Source Repositories からの Cloud Functions のデプロイ（CSRの方のドキュメント）
https://cloud.google.com/source-repositories/docs/deploying-functions-from-source-repositories?authuser=0

Cloud Functionsへソース管理からのデプロイ（Functionsの方のドキュメント）
https://cloud.google.com/functions/docs/deploying/repo

クイックスタート: Cloud Source Repositories から Cloud Functions へのデプロイ
https://cloud.google.com/source-repositories/docs/quickstart-integrating-with-cloud-functions?hl=ja
Windows でカーソル移動を vi 風にする

# Windows でカーソル移動を vi 風にする

ホットキーの割当は様々なソフトでできると思いますが [AutoHotKey](https://www.autohotkey.com/) (AHK) でもできます。AutoHotKey はスクリプトを書くことで非常に柔軟なホットキーの割当が可能な Winodws で動作する GNU GPLv2 のオープンソースソフトで、現時点での最新版は v1.1.32.00 (November 24, 2019) です。

インストール方法は .exe ファイルをダウンロードしてダブルクリックするだけです。アンインストール方法は[ここ](https://www.autohotkey.com/uninstall/)をご参照ください。

スクリプトを作成するには[ここ](https://www.autohotkey.com/docs/Tutorial.htm#s11)にある通り単に .ahk の拡張子を持つファイルを作成するだけです。スタートアップのフォルダに入れておくと Windows ログイン時に自動的に起動します。

スクリプトと言っても今回は単純に Ctrl+Shift+ [H,J,K,L] にそれぞれ左下上右を割り当てるだけなので以下のような簡単なものとなります。


``` AutoHotKeys.ahk
;#####################################
;## 'ctrl+shift+h' # LEFT arrow key ##
;#####################################
^+h::
Send {Left}
return

;#####################################
;## 'ctrl+shift+h' # DOWN arrow key ##
;#####################################
^+j::
Send {Down}
return

;###################################
;## 'ctrl+shift+h' # UP arrow key ##
;###################################
^+k::
Send {Up}
return

;######################################
;## 'ctrl+shift+h' # RIGHT arrow key ##
;######################################
^+l::
Send {Right}
return
```

^ は Ctrl を示し + は Shift を示します。キーの割当の指定は[ここ](https://www.autohotkey.com/docs/commands/Send.htm)から一覧を見ることができます。

私は英語配列のキーボードを使用しているため Ctrl+Shift に割り当てていますが、日本語配列なら無変換キーなどに割り当てるのも手だと思います。日本語のキー配列に関しては[ここ](http://ahkwiki.net/KeyList)が参考になります。ただ一部情報が古いようで調べたら[ここ](https://freesoft-100.com/review/autohotkey.html)とか[ここ](https://qiita.com/kou0123/items/6f9d675a21643c7a5802)で Windows でカーソル移動を vi 風にする方法含めてもっと広範囲な説明がされていました。。

しかし意外と探しものをする際に記事のタイトル名は重要と思いますのでそのまま掲載します。

それでは良い Auto Hot Key 生活をお送りください！

参照:
AutoHotKey (本家):
[https://www.autohotkey.com/](https://www.autohotkey.com/)

freesoft 100 AutoHotkey:
[https://freesoft-100.com/review/autohotkey.html](https://freesoft-100.com/review/autohotkey.html)

ショートカットは覚えるものではなく、作るもの autohotkey編:
[https://qiita.com/kou0123/items/6f9d675a21643c7a5802](https://qiita.com/kou0123/items/6f9d675a21643c7a5802)
Docker Desktop for Mac でApacheのコンテナを立ち上げる

# 目的

- Docker Desktop for Mac導入後に確認としてApacheのコンテナを作りブラウザから接続を確認する方法をまとめる
- とにかくちゃんとDockerが導入できているかの確認なのでディレクトリマウントなどは行わない

# 実施方法

1. Docker Desktop for Macの入ったPCで下記コマンドを実行する。

    ```terminal
    $ docker run -d -p 8080:80 httpd
    ```

1. 下記にアクセスして「It works!」と表示されるか確認する。

- [http://localhost:8080/](http://localhost:8080/)