OmniAICreator/Qiita-1.07M huggingface dataset:
Docker runでportオプション（-p 8080:8080）や-dオプションする意味〜初心者向けにコマンドの解説〜

```
$ docker run sample-image --name sample-image-name -p 3000:8080 -d 
```

この記事では上記のコマンドのオプションの解説をします。

### docker run

```
$ docker run sample-image
```
sample-imageという名前のローカルのイメージを実行します。もしローカルに存在しない場合、docker hubからダウンロードしてきて実行します

### --name process-name
```
$ docker run sample-image --name sample-image-name
```
--name sample-image-nameで、docker run するイメージをプロセスにするとき、そのプロセスにsample-image-nameという名前をつけます。

### -p 3000:8080
```
$ docker run sample-image --name sample-image-name -p 3000:8080
```
-p オプションは外部のポートとコンテナ内部のポートを接続するオプションです。-p 3000:8080でローカルのポート3000(localhost:3000)にアクセスすると、dockerコンテナの内部でポート8080で動いているアプリケーションに接続できるようになります。

今回の例はあまり美しくないのですが、わかりやすさ重視のためにこのようにしました。

### -d
```
$ docker run sample-image --name sample-image-name -p 3000:8080 -d 
```
-dオプションでは、docker runして起動したプロセスをデーモンとして起動しバックグラウンドで動かすように指定します。


### まとめ
```
$ docker run sample-image --name sample-image-name -p 3000:8080 -d 
```
sample-imageというdocker imageを、sample-image-nameという名前をつけて、コンテナ内の8080番を使っているアプリにlocalhost:3000でアクセスできるようにバックグラウンドで動かします。
Scala入門備忘録_matchやforなどの汎用構文を避けた方が良いという話

Scala入門中です。大したことは書けないですが、勉強したことを整理するために備忘録的に書きます。
何か間違っていることや補足したい点があったら優しくマサカリを投げてください。

今回はメンターをやって下さっている方に教わった話を軽くまとめます。

## 汎用構文を避けたいきもちになった経緯
Scala入門した初期に学ぶforのループ処理やmatchを使ったパターンマッチは、簡単に書けるしあらゆる場面で使える。
とても便利だな〜Scalaわかってきた気がするな〜という気持ちで多用していたら、ある日メンターから「汎用的な構文は場合によっては避けた方が良いという考え方がある」と言われた。

## なぜ汎用構文を避けた方が良いのか
### 汎用構文のデメリット
何をしたいのかをコードを読んで理解しようとした際に、構文自体が汎用的であるが故にちゃんとコードを読まないと理解出来ない。
さらにパターンマッチやループ処理を使いすぎるとネストが深くなってコードの見通しが悪くなることも。
### 避けることによる嬉しみ
汎用的な構文を避けて、変わりに `fold` `map` `filter` などの意図を明確に表す高階関数を使うとコードを深く読み込まずとも関数の種類でどんなことがやりたいのかなんとなくわかる。
（もちろん関数の知識があることが前提だが）

さらに目的に特化した関数を使っていて処理を自前で組み立てているわけではないのだから、当然コード量も減る。

## 具体例
### パターンマッチをfoldにしてみる
```scala:パターンマッチ
anOptionValue match {
  case Some(v) => function(v)
  case None => default
}
```
```scala:fold
anOptionValue.fold(default)(function)
```

Optionのfoldが何をしてくれるのかは以下の通り。
>fold[B](ifEmpty: ⇒ B)(f: (A) ⇒ B): B
>Returns the result of applying f to this scala.Option's value if the scala.Option is nonempty.

https://www.scala-lang.org/api/2.12.4/scala/Option.html

### forを変えてみる
※後日更新したい

## 最後に
汎用的な構文を使うことが必ずしも悪、ということではないと思う。
他によりふさわしい関数が居るならその子を使ってあげようと言う話であって、逆にそういう子がいないときには汎用的な物を使って自前で実装する必要があるという認識。

ということで、そういった関数をちゃんと理解して使っていくことをこれからは積極的にやりたい所存。
バーチャル脱出ゲーム：バリデーションからの脱出（回答編）

# 問題編
まだ見ていない方は[こちら](https://qiita.com/zifre/items/2cdf09ec360c7eb72452)からどうぞ

# 回答編
今回の問題は、見て分かる通りいかに on_ident を呼ばせないかというものでした
つまりローカル変数っぽくなければよいため、抜け道は結構いろいろあります

今回書くのは私が思いついたものだけですが、他にもいくらでもありそうな気がします

```ruby
$><<"escape!"
```

まずは記号プログラミングでおなじみ$>を使用した方法です
$>には標準出力が入っているため、ここに直接文字をを流し込めば、標準出力へ反映されます
$> はグローバル変数を表すon_gvarが、<<は演算子を表すon_opがそれぞれ呼ばれるため、実行可能となります

```ruby
`touch escape!`
```

…… 見ての通り、としか言いようがない気もしますが
` で呼ばれるのは on_backtick なので普通に通ります

```ruby
alias Puts :'puts'
Puts('escape!')
```

これは少し説明が必要ですかね
alias は見た目だけならローカル変数っぽいですが、予約語なのでon_kwが呼ばれます
Puts も引っかかりそうな気がしますが、大文字で始まっているため定数扱いされて on_const が呼ばれます

一方 alias のキーワードの puts は普通に書くとon_identが呼ばれてしまうため、シンボル経由でごまかします、が
単に :puts と書くと : が on_symbeg、putsがon_identとなりやっぱり引っかかってしまうため、:'puts' として更に迂回しています

```ruby
def false.+
  yield(self, 'puts "escape!"')
end
false.+(&%i[instance_eval][0])
```

最後に、alias以外の予約語を用いたパターンとなります
def false yield self が予約語扱いでon_identを回避して
+ は演算子扱いで回避しています
で、Symbol#to_proc を経由してinstance_evalを呼び出して、コード実行に至る、と

以上が私が考えた範囲での回答です

多分これ以外にもあると思うので、余裕がある方はぜひ グローバル変数 / on_constの対象 / バッククォート（%xを含む）/ alias def false yield self を使用しない方法を考えてみてください
見つけたらコメントに残しておいていただけると嬉しいです

ありがとうございました
Azure認定資格 AZ-203を取得しました

Azureの資格体系が2019年に変わりました。

[資格ロードマップ](https://query.prod.cms.rt.microsoft.com/cms/api/am/binary/RE2PjDI)

2019年6月くらいから徐々に日本語対応がされてきたので、「AZ-203 Developing Solutions for Microsoft Azure」を受験してみました。
旧資格でいうと「MCP-532」に該当する試験ですね。

# 試験の傾向は？

* 問題：50問
MCP-532/533/534と同じく、「ケーススタディ」「1問1答」「2択問題」が出題されました。各セクションを先に進めると前のセクションに戻ることができないのも同じですね。
「ケーススタディ」がやけに多く、要件を把握するのに時間を要しました。

* 時間：150分
公式では180分となっていますが、実際は150分です。おそらく事前の同意書の確認とかの時間で30分取っているのでしょう。

# 公式サイトの試験範囲を確認する

まずは範囲を把握しましょう。

[Developing Solutions for Microsoft Azure](https://www.microsoft.com/ja-JP/learning/exam-az-203.aspx)

* Azure のサービスとしてのインフラのコンピューティングソリューション開発(10-15%)
* Azure のサービスとしてのプラットフォームのコンピューティングソリューション開発 (20-25%)
* Azure ストレージの開発 (15-20%)
* Azure セキュリティの実装 (10～15%)
* ソリューションの監視、トラブルシューティング、最適化 (10-15%)
* Azure サービスとサードパーティサービスの連携と活用 (20-25%)

MCP-532のときも思いましたが、試験範囲広いですねー
ASP.NET CoreやAzure SDKの問題などもバンバン出てくるのでインフラエンジニアにとっては難しかったです。

# 学習方法

MCP-532を持っているのと、普段からAzureを触っているため、資格勉強というのはほぼやっていません。
試験範囲の各サービスの概要を公式ドキュメントから調べたくらいです。
結果合格でしたが、かなりギリギリでした。

この広い試験範囲のサービス全てを深く知っている人は正直あまり多くないかなと思います。
一応どのサービスがどういうものかの概要は全て知っていたものの、3割くらいのサービスは触ったことがないものでした。

ここで名前の出てくる各サービスのチュートリアルとCLI操作は最低限やっておいたほうがよかったなと思いました。
やはり実際に触ったことあるなしだと全然違います。

# まとめ
時間は150分ギリギリでした。ケーススタディが多く、要件の把握に時間が掛かったためです。

日本語で受験しましたが、変に日本語訳をしている箇所があり、絶対に英語表記じゃないと答えられないなという問題がありました。
試験中に表示を英語に切り替えられるため、怪しいと思ったら英語表記も確認したほうがよいです。

2年前に受けたMCP-532のときに比べて、PowerShellよりCLIの割合が多かったように思います。AzureがCLIの方を推奨し始めているからでしょうか。
あと、2年前には一切出なかったコンテナ関連も多く出題されて、時代の流れを感じました。
SentryとVueの組み合わせでイベントログを収集

## 目的
circleCIでデプロイ時の通知はできたものの、今度はerrorの時に何がおきているのかを知りたくなったので、sentryを突っ込みます。
Sentry自体はエラーに限るわけではないですが、今回の目的はエラーが起きた時にログを追うために実装をします。


## Sentryとは

https://sentry.io/welcome/
Sentryはイベントログを収集してくれるツールです。
2019年7月現在では以下のプログラミング環境下で使用ができます。

![sentry.io_platforms_.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191638/f2d1d068-c57c-94f2-657c-c889d54714dc.png)

JSのフレームワークでは、Reactをはじめ、今回実装するVueやAngularなどで使用ができます。

![sentry.io_for_javascript_.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191638/a8e9f37e-7d65-9395-91cf-9e8c07edc6fd.png)

## 登録

まずはSentryに登録をします。

https://sentry.io/signup/

2019年7月現在では登録方法としては現在以下があります。

- github
- Azure DevOps
- Emailなどを入力

今回はgithubで登録を行います。
「Sign up with Github」をクリックし認証を行います。

## プロジェクト登録

登録が完了したらProjectを作成します。
今回はvueを選択し、project nameを設定してやります。

今回は名前を「blog」にしました。
![sentry.io_organizations_tomopict_projects_new_ (3).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191638/3837ebf2-c8b8-3880-f1ad-c18f3a58ab83.png)

## Vueのプロジェクトの追加する

以前はraven-jsだったようですが、今は変わっているようです。
基本的には`@sentry/browser`と`@sentry/integrations`をインストールすれば問題なさそう。

```shell
# Using yarn
$ yarn add @sentry/browser

# Using npm
$ npm install @sentry/browser
```

```shell

# Using yarn
$ yarn add @sentry/integrations

# Using npm
$ npm install @sentry/integrations
```

## Vueのなかで呼び出し

インストールが済んだら、極力早い段階でSentry.initでinitializeを行います。
denの`io/xxxxxxx`の箇所には固有のidが入ります。

```js
import * as Sentry from '@sentry/browser';
import * as Integrations from '@sentry/integrations';
Sentry.init({
  dsn: 'https://b360938dff664cdf9166f2d92f1f5976@sentry.io/xxxxxxx',
  integrations: [new Integrations.Vue({Vue, attachProps: true})]
});
```

ここまで準備が終われば、あとは実際にSentryにイベントを送って見ます。

## ブラウザからエラーを確認

イベントを送りたい箇所に以下のコードを入れるとクライアントからイベントがSentryに向けて送信されます。

[https://docs.sentry.io/platforms/javascript/](https://docs.sentry.io/platforms/javascript/)

```js
Sentry.captureException(new Error("Something broke"));
```


なおユーザー情報を追加した状態でイベントレポートを送信したい場合は以下のようにして設定できます。

[https://docs.sentry.io/enriching-error-data/scopes/?platform=javascript](https://docs.sentry.io/enriching-error-data/scopes/?platform=javascript)

``` js
    Sentry.configureScope((scope) => {
      scope.setTag("test-tag", "test-value");
      scope.setUser({
        id: 42,
        email: "john.doe@example.com"
      });
    });
```

## 管理画面でイベントを確認

該当のプロジェクトの画面に移動して、作成したプロジェクトでイベントを確認します。

<img width="1417" alt="スクリーンショット 2019-07-21 23.15.18.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191638/98a0771d-80d0-3a59-f332-387cdbd22040.png">

ユーザー情報を付与した場合は該当のイベントログに、ユーザー情報もきちんと入っています。

![スクリーンショット 2019-07-21 23.15.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191638/4a5428e3-0895-1644-af74-4ca4af7ff339.png)


## まとめ
まずは導入までというところですが、簡単にイベントを送信することができました。
実際にはエラーが起きた際にslackに通知したり、どのようなデータが入っていたのかstoreの中のデータを送信したり工夫は必要そうです。
slack通知などを導入したらまた追記したいと思います。

### 参考にさせていただいた記事
[Sentryでイベントログ収集をしよう！ - Vue.js編 -](https://qiita.com/ferretdayo/items/1aef9f1724ab701bb95f)
Ruby on Rails でレビュー機能を実装する

Railsでレビュー機能を実装する方法をまとめておきます。

# 対象者
- 初心者
- MVCは理解している

# 手順
1. scaffoldで雛形作成
2. レビュー投稿機能実装
3. レビュー表示

# 1. scaffoldで雛形作成

```
$ rails new review-sample
$ cd review-sample
$ rails g scaffold shop name
$ rails db:migrate
```

# 2. レビュー投稿機能実装
## 2-1. データベース作成
```
$ rails g model review shop:references body:text
$ rails db:migrate
```

## 2-2. shopsコントローラ実装
```app/controllers/shops_controller.rb
def show
  @review = Review.new  #追記
end
```

## 2-3. ビュー実装
```app/views/shops/show.html.erb
<%= form_for @review do |f| %>
  <%= f.hidden_field :shop_id, value: @shop.id %>
  <%= f.text_field :body, class: "text-field" %>
  <%= f.submit '投稿', class: "submit-btn" %>
<% end %>
```

## 2-4. reviewsコントローラ実装
### 2-4-1. reviewsコントローラ作成
```
$ rails g controller reviews
```
### 2-4-2. コントローラ実装
```app/controllers/reviews_controller.rb
class ReviewsController < ApplicationController
  def create
    @review = Review.new(review_params)
    @review.save
    redirect_to shop_path(@review.shop)
  end

  private
    def review_params
      params.require(:review).permit(:shop_id, :body)
    end
end
```

## 2-5. ルーティング
```config/routes.rb
Rails.application.routes.draw do
  resources :shops
  resources :reviews  #追記
end
```

# 3. レビュー表示機能
## 3-1. アソシエーション実装
```app/models/shop.rb
class Shop < ApplicationRecord
    has_many :reviews
end
```

## 3-2. コントローラ実装
```app/controllers/shops_controller.rb
def show
  @review = Review.new
  @reviews = @shop.reviews  # 追記
end
```

## 3-3. ビュー実装
```app/views/shops/show.html.erb
<% @reviews.each do |r| %>
  <%= r.body %>
<% end %>
```

# 動作確認

```
$ rails s
```
http://localhost:3000/shops
にアクセス
GitHubアクションでエラーハンドリングしたかったら自作するしかなさそう

# 注意
2020/02/08追記
この記事はGitHub Actions v1の話で、今のv2とは全く違う内容になっておりますm(_ _)m
エラーハンドリングについてもv2になってからは`if: failure()`とかで失敗時にタスクを実行みたいな設定が出来るようになりました！これでSlack通知のためにエラーハンドリングをしなくて良くなりました＾＾

https://github.com/homoluctus/slatify

---

# 始めに
今までCircleCIやCodeBuildを使ってきましたが、最近GitHubアクションも使ってみました。その際にエラー通知を実装しようとしたらかなり苦戦してしまったためそれについて記事にしました。

# エラーハンドリングする術がない
GitHubアクションのステータスはWeb上では確認でき、`check_suite`などのイベントでフックできると書いてあります。

https://qiita.com/1915keke/items/8b18097d2981e88eca93

`push`イベントでビルドとデプロイを実行し、`check_suite`でステータスをみてSlack通知する方法を考えていたのですが、なぜか`check_suite`のイベントはフックされませんでした。
結論から言うと**GitHubアクションで実行した処理はイベントのフック対象にはならない**です。`push`イベントでgh-pagesブランチにpushしても再度`push`イベントはフックされないといった感じです。

http://yasuharu519.hatenablog.com/entry/2018/12/10/231819

アクションが失敗した場合は次のアクションは実行されませんので、**エラーをハンドリングする方法はない**と思った方が良さそうです。
ちなみに`check_suite`は他のCIを実行した時にイベントをハンドリングすることはできました（あんまり意味がない気がしますが・・・）

# それでもエラーハンドリングをしたい場合
アクションを順番に実行するとエラーハンドリングできなくなってしまうので、一つのアクションで全部書くしかないかなと思っています。
僕は以下のようにアクションを自前で定義してそれだけを呼ぶようにしています。自前でshellを書くとtrapを使ってtry-catchっぽくかけるので、それで成功とエラー通知をすることができます。

https://cloudpack.media/532

```workflow:.github/main.workflow
workflow "Build and Deploy" {
  on = "push"
  resolves = ["main"]
}

action "main" {
  uses = "./.github/action/"
  secrets = ["AWS_ACCESS_KEY_ID", "AWS_SECRET_ACCESS_KEY"]
}
```

```sh:.github/action/entrypoint.sh
#!/bin/bash

# ========== メソッドとエラーハンドリングの設定 ===========

# Slack通知メソッド
function notify() {
  if [ $1 = "SUCCESS" ]; then
    STATUS_COLOR="good"
    STATUS_TEXT="SUCCESS"
  else
    STATUS_COLOR="danger"
    STATUS_TEXT="FAILED"
  fi

  JSON=$(cat << EOS
{
  "attachments": [
    {
      "title": "${GITHUB_REPOSITORY}",
      "title_link": "${ACTION_URL}",
      "color": "${STATUS_COLOR}",
      "fields": [
        { "title": "STATUS", "value": "${STATUS_TEXT}", "short": "true" }
      ]
    }
  ]
}
EOS
)

  RES=`curl -s -X POST -H 'Content-Type: application/json' -d "${JSON}" ${SLACK_WEBHOOK_API_URL}`

  echo $RES
}

# catchメソッド
function catch() {
  notify ERROR
}

# エラーした時にcatchメソッドを呼ぶように設定
set -e
trap catch ERR

# ========== メイン処理 ==========

# Slack通知のURL
SLACK_WEBHOOK_API_URL=[WebHook URL]

# ActionのURL
ACTION_URL=https://github.com/$GITHUB_REPOSITORY/actions

# インストールとビルド
yarn install
yarn build

# S3にアップロード
aws s3 sync ./dist/ s3://bucket-name --exact-timestamps --delete

# Slackに成功を通知する
notify SUCCESS
```

# 終わりに
GitHubアクションはやり方が分かると結構使いやすそうな印象でしたが、エラーハンドリングはかなり厳しそうでした。エラーハンドリングをするなら他のアクションを使うのはほぼ無理な気がしました。
小さなモジュールを組み合わせていくという発想は良さそうに見えますが、その分毎回Dockerの起動をさせられてオーバーヘッドがかかったり、ちょっとした文字列加工をしてもその変数を引き継ぐ術がなかったり、細かいことをやろうとすると結構やりづらかったです。
こういった問題はアクションを自作して一つのshellにしてしまえば解決するのですが、GitHubアクションの特徴を殺してしまっている気がしてならないですね・・・。
Fedora30へのTidalCycles導入について

ノートPCはThink Padしか持っていないのでMacという選択肢が無いことと、普段使いのディストリビューションとしてFedoraに拘りがある僕としてはどうしてもFedoraに入れたかったので少し遠回りになりました。Ubuntuならもう少し楽だったかもだが。

Live Codingをしようと思った時、最初はFoxDotでやるつもりで環境作っていろいろ試していました。でも少し音的に物足りないなぁと思って色々Youtubeを漁っているとだいたい出てくる人皆のコードからTidalCycles使っているということが分かってきて乗り換えることにしました。

FoxDotを動かすことに大して苦労は感じませんでした。(ただAtomのプラグインは何故か上手く動かなったw)
でも必須の

*JACK
*SuperCollider

は入っていたのであとはTidalCyclesのみ。
でも色々ハマりました。

今日は少し時間がないのでポイントだけ。またいつかしっかり加筆していきたいです。何如んせんFedoraに入れている人が少なかったので少しでも情報をと。

何はなくともここを。
[Planet CCRMA repo](http://ccrma.stanford.edu/planetccrma/software/planetccrma.html)
このリポジトリをまず登録。

ここから上記のJACK,SuperColliderも楽にインストールできます。

__Haskell__

```
$ sudo dnf install haskell-platform
```
色々要るようだけど、上記でOKのよう。

__TidalCycles__

```
cabal install tidal
```
でOK。

__SuperDirt synth__
こちらは単にSuperCollider上で

```
include("SuperDirt")
```

__sc3-plugins__
これに悩まされた。でもよく見るとエラーメッセージにしっかり明記されててw
先程のPlanet CCRMA repoに用意されてて、

```
$ sudo dnf install supercollider-sc3-plugins
```
でOK。

__Atom plugin__
tidalCyclesと検索するとパッケージとして出てくる。
インストールして、拡張子.tidalのファイル作って開く。
パッケージ->TidalCycles->Boot TidalCycles
でTidalCyclesを使えるようになる。
*※もちろん Boot TidalCycles の前にSuperCollider上で「SuperDirt.start」で待ち受けておくことをお忘れなく。*

ところで…
このFoxDotの時もそうだったのですが、Atom Pluginを呼ぶと最初に

```
/bin/sh: switchml: 行 1: 構文エラー: 予期しないファイル終了 (EOF) です
/bin/sh: `switchml' の関数定義をインポート中にエラーが発生しました
/bin/sh: module: 行 1: 構文エラー: 予期しないファイル終了 (EOF) です
/bin/sh: `module' の関数定義をインポート中にエラーが発生しました
/bin/sh: scl: 行 1: 構文エラー: 予期しないファイル終了 (EOF) です
/bin/sh: `scl' の関数定義をインポート中にエラーが発生しました
/usr/bin/sh: switchml: 行 1: 構文エラー: 予期しないファイル終了 (EOF) です
/usr/bin/sh: `switchml' の関数定義をインポート中にエラーが発生しました
/usr/bin/sh: module: 行 1: 構文エラー: 予期しないファイル終了 (EOF) です
/usr/bin/sh: `module' の関数定義をインポート中にエラーが発生しました
/usr/bin/sh: scl: 行 1: 構文エラー: 予期しないファイル終了 (EOF) です
/usr/bin/sh: `scl' の関数定義をインポート中にエラーが発生しました
/usr/bin/sh: switchml: 行 1: 構文エラー: 予期しないファイル終了 (EOF) です
/usr/bin/sh: `switchml' の関数定義をインポート中にエラーが発生しました
/usr/bin/sh: module: 行 1: 構文エラー: 予期しないファイル終了 (EOF) です
/usr/bin/sh: `module' の関数定義をインポート中にエラーが発生しました
/usr/bin/sh: scl: 行 1: 構文エラー: 予期しないファイル終了 (EOF) です
/usr/bin/sh: `scl' の関数定義をインポート中にエラーが発生しました
```
が出てくるのですが…
今のところ動作に支障は無いれど、でも気になるので。色々調べたけど未だに解決策を得ず。。。
この記事を見られた方でどなたか解決方法わかる方、教えてください<(__)>
【自分用メモ】 Progate 2日目

# 学習コース Git Ⅰ


## コース概要
Gitの基本的な使い方を学ぶ


### 学んだこと
- 更新履歴や更新時のメッセージを確認することができる
- git commit **-m** "メッセージ" でaddで選択したファイルをメッセージ付きで記録する

Gitって便利。開発するようになったときGitHub使えるようにしておこう。
Vim が辛すぎるから VS Code で Linux に SSH してファイル操作する

[![Image from Gyazo](https://i.gyazo.com/c9e642fe52e613eb542277d248c27131.png)](https://gyazo.com/c9e642fe52e613eb542277d248c27131)

Azure VM や AWS EC2 に SSH 接続してコマンド上でファイル操作するのは大変じゃないですか？ Vim に慣れていないとコマンドを検索するだけで時間がかかってしまいます。そんなときは MS が提供している `Remote Development` 拡張機能を使いましょう！

## インストール

vscode の拡張機能から `Remote Development` をインストールします。
SSH 接続用の `Remote - SSH` や、 Container 接続用の `Remote - Containers` も一緒にインストールされます。

[![Image from Gyazo](https://i.gyazo.com/72cba89784f0f45d1e1b4559b126090e.png)](https://gyazo.com/72cba89784f0f45d1e1b4559b126090e)

## 使い方

公式ドキュメントの [Developing on Remote Machines using SSH and Visual Studio Code](https://code.visualstudio.com/docs/remote/ssh) を見るのが一番よいのですが、ざっくりと簡単に説明します。

### 前提条件

SSH Config (~/.ssh/config) に接続情報を設定します。

Windows は PowerShell を管理者で開いて `SSH Agent` をインストール＆起動してください。 SSH Key にパスフレーズがついている場合、これがないと動きません。

```powershell
# Make sure you're running as an Administrator
Set-Service ssh-agent -StartupType Automatic
Start-Service ssh-agent
Get-Service ssh-agent
```

### 使い方

左側の Remote-SSH を開きます。接続情報の一覧が表示されます。

[![Image from Gyazo](https://i.gyazo.com/d2f77e5c4104dc0b208c2e023c1a07f0.png)](https://gyazo.com/d2f77e5c4104dc0b208c2e023c1a07f0)

接続先をクリックします。接続が完了すると左下に接続しているホスト名が表示されます。※画像は `Remote Development` の readme.md からの引用です。

[![Image from Gyazo](https://i.gyazo.com/c0ed07a4f537eedb9bf4b3d70f8e4bc3.png)](https://gyazo.com/c0ed07a4f537eedb9bf4b3d70f8e4bc3)

ファイルエクスプローラからフォルダを開いて、あとは煮るなり焼くなり自由にファイル操作してください。

## QA (使ってて困ったこと)

Q1. root ユーザーなどに切り替えができないけどどうしたらよい？

A1. SSH 接続したあとに vscode の terminal を開いて、 terminal からコマンドを打ってください。 cp コマンドなどでファイルを自分の作業フォルダに持ってくれば、 vscode でファイル編集できます。

Issue [Changing User on Remote Machine · Issue #690 · microsoft/vscode-remote-release · GitHub](https://github.com/microsoft/vscode-remote-release/issues/690) に上がっているので、そのうち RemoteCommand を SSH Config の設定にかけるようになって terminal からの作業が減ると思います。

Q2. 踏み台がある場合はどうしたらよい？

A2. こんな感じで SSH Config を書いてあげれば接続できます。気をつける点は ProxyJump ではなく ProxyCommand を使うことと、 Windows の場合は ssh.exe をこんな感じできちんとパスで書いてあげる (`ProxyCommand C:\Windows\System32\OpenSSH\ssh.exe -q -W %h:%p jump-box`) ことです。

```
Host jump-box
  HostName <jump box address>
  IdentityFile ~/.ssh/jump-box
  User <user>

Host target-machine
  HostName <same address as tagret-machine>
  IdentityFile ~/.ssh/target-machine
  User <user>
  ProxyCommand ssh -q -W %h:%p jump-box
```
AtCoder ABC問題の進捗早見表

自分の為のAtCoderの進捗早見表

#AtCoder Beginner Contestを主とした進捗リスト

AtCoder Beginner Contest 1 ～ から解いてゆく。
周りの色んな人が何かとOUTPUTしていて感心したので、自分もやってみる。

##AtCoder Beginner Contest

###ABC 1-10
| No               |                進捗|    備考　　　　　    |
|:-----------------|------------------:|:------------------:|
| 001              |[ABC001](https://qiita.com/mitsupon/items/fa8f38c7fd8b2fec65a9) |        C問題躓き中        |
| 002              |[ABC002](https://qiita.com/mitsupon/items/d8d9f8ecac1369ad0239) |                          |
| 003              |[ABC003](https://qiita.com/mitsupon/items/4316412d3522465840c0) |                          |
| 004              |                                                                |                          |
| 005              |[ABC005](https://qiita.com/mitsupon/items/aa984f5a45836a0cb229) |                          |

###ABC 11-20

###ABC 21-30

###ABC 31-40

###ABC 41-50

###ABC 51-60

###ABC 61-70

###ABC 71-80

###ABC 81-90

###ABC 91-100

###ABC 101-110

###ABC 111-120

###ABC 121-130
Pythonで有理数以外の数を扱う話

# はじめに

タイトルは嘘です。
「Pythonで (**ある程度**) 有理数以外の数 (**の近似値**) を扱う」というのが正しいタイトルです。

[前々回](https://qiita.com/sakabe/items/60e5042ec406c02c3d04)、[前回](https://qiita.com/sakabe/items/0333f06cc6064a70cc93)と有理数を扱う話をしたので、
今回は有理数以外の数、無理数と虚数(複素数)を扱う方法を調べてみました。

無理数とは、整数比で表すことが出来ない数のことを指します。

つまり

```math
\frac{a}{b}\scriptsize\qquad(a,bは整数、bは0でない数)
```
と表せます。
もっと言えば平方根やπ等のことです。

# 平方根
調べた中だと一番よくお世話になる関数です。

```python
import numpy as np
import math

np.sqrt(2)
# 1.4142135623730951

math.sqrt(2)
# 1.4142135623730951
```

mathのほうが計算速度が速いようです。
[参考サイト様](https://www.tech-tech.xyz/python_sqrt.html)

# 複素数
複素数は専用の型が標準で用意されているようです。

```python
a = 1j
print(a)
# 1j
print(type(a))
# <class 'complex'>
```
 ***数値j*** で複素数の虚部を表します。
なぜか ***i*** ではなく ***j***

## 複素数の計算
```python
a = 1 + 2j
b = 3 - 4j

print(a + b)
# (4-2j)
print(a * b)
# (11+2j)
```

## 規定値以下の虚部を無視する
虚部がごく小さい場合、虚部をはずしてくれるモジュールです。

```python
import numpy as np

print(np.real_if_close([2.1 + 4e-14j], tol=1000))
# [2.1]
```

[マシンイプシロン](https://qiita.com/yoshi1406/items/9ac6cacf253d1c74e900) * tol(第二引数)以下の虚部を無視した数(ndarray型)を返します。

[参考サイト様](https://docs.scipy.org/doc/numpy-1.15.1/reference/generated/numpy.real_if_close.html)

# 円周率
mathで用意されている円周率は小数点以下15桁です。

```python
from math import pi

print(pi)
# 3.141592653589793
type(pi)
# float
```

# ネイピア数
円周率と同じく、mathで用意されているネイピア数は小数点以下15桁でした。

```python
from math import e

print(e)
# 2.718281828459045
type(e)
# float
```

# 終わりに

Pythonで (**ある程度**) 有理数以外の数 (**の近似値**) を扱う方法をまとめてみました。

複素数とか今後扱う気はしませんが、
他はたまに使うような気がするので、覚えておこうと思います。
[Sphinx]code-blockの言語ごとに異なる書式を設定する

# やりたかったこと

ターミナルに入力するコマンドをcode-blockで表記することが多いと思います。
OSによって入力するコマンドが異なるため、Windowのコマンドの場合は何色、Linuxのコマンドの場合は何色など、OSによって異なる書式を設定したcode-blockを書きたくなりました。

# やったこと

Sphinxでは独自のCSSを埋め込めます。

https://docs.readthedocs.io/en/stable/guides/adding-custom-css.html

## conf.pyの修正

`html_static_path` (静的ファイルのpath)と`html_css_files` (cssファイルの相対path)を `conf.py` に追記します。 `html_static_path` のほうはデフォルトで記述されているかもしれません。今回はCSSファイルを `css/custom.css` としました。

```python:conf.py
html_static_path = ['_static']
html_css_files = ["css/custom.css"]
```

## CSSファイルを作成

`_static`ディレクトリ配下にCSSファイルを作成します。今回はpowershellとbashのシンタックスハイライトの書式を変更します。今回は背景色を上書きしています。

```css:_static/css/custom.css
.highlight-powershell pre {
    background: #AFEEEE;
}
.highlight-bash pre {
    background: #E9967A;
}
```

## code-blockに言語名を指定する

あとは原稿(reStructuredText)の `code-block` ディレクティブに先程CSSのclassで定義した言語名を指定するだけです。せっかくなので `:caption:` オプションも追加してキャプションを表示させます。

```reStructuredText:xxx.rst
Windows
-------

.. code-block:: powershell
   :caption: Win

   Get-Command

Linux
-----

.. code-block:: bash
   :caption: Linux

   ls

```

## HTMLにビルドする

`make html` コマンドなどでHTML形式にビルドするとこのようになります。ぱっと見でどっちのOSのターミナルなのかわかりやすくなりました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22023/56d4f29d-c09b-33f1-5115-2a96719d7914.png)
【Heroku】デプロイ手順

# 準備：Herokuログイン
Herokuのサイトに登録して、
ターミナルにてCLIでHerokuにログイン

```shell-session
$ heroku login
```

# 準備：Gemfile修正
- production(Heroku)で`sqlite3`を利用しないように修正しておく
- production(Heroku)で`pg`を利用するように修正しておく

```ruby:Gemfile
# Use sqlite3 as the database for Active Record
gem 'sqlite3', group: [:development, :test]
gem 'pg', group: :production
```

# 準備：git commit
ソースをコミットしておく

```shell-session
# アプリのディレクトリに移動する
$ cd rails-app

# 初期化
$ git init

# ディレクトリ配下のファイルをコミット対象にする
$ git add *

# コミット
$ git commit -m "Release to heroku"
```

# Herokuアプリ作成

Herokuアプリを作成して、URLとGitリポジトリを取得する

- `<アプリ名>`は省略可能。省略するとアプリ名が自動で払い出される
- 払い出されたURLがHerokuアプリのURL、Gitリポジトリとなる

```shell-session
# アプリのディレクトリに移動する
$ cd rails-app

# Herokuアプリを作成する
$ heroku create <アプリ名>

Creating app... done, ⬢ xxxxx-xxxxx-xxxxx
https://xxxxx-xxxxx-xxxxx.herokuapp.com/ | https://git.heroku.com/xxxxx-xxxxx-xxxxx.git
```

# リモートリポジトリの確認・登録

リモートリポジトリ**heroku**が作成されてることを確認する

```
# リモートリポジトリを確認
$ git remote
heroku
```

リモートリポジトリ**heroku**が存在しない場合は、`heroku create <アプリ名>`コマンド実行時に払い出されたgitリポジトリをリモートリポジトリ`heroku`として登録する

```shell-session
# リモートリポジトリを追加
$ git remote add heroku https://git.heroku.com/xxxxx-xxxxx-xxxxx.git
```

> 補足：ローカルリポジトリ作成(`git init`)後に`heroku create`コマンドを実行した場合はリモートリポジトリ**heroku**が自動で追加されますが、 `heroku create`コマンド実行後にローカルリポジトリを作成(`git init`)した場合は、手動でリモートリポジトリ**heroku**を追加する必要があります。

# デプロイ

ローカルの`master`ブランチをリモートリポジトリ`heroku`へpushする

```shell-session
$ git push heroku master

...
To https://git.heroku.com/mighty-beyond-37933.git
 * [new branch]      master -> master
```

# アクセス確認
`heroku open`コマンドを実行すると自動でブラウザが開き、HerokuアプリのURLにアクセスする

```shell-session
$ heroku open
```

または、HerokuアプリのURLにブラウザでアクセスする
https://xxxxx-xxxxx-xxxxx.herokuapp.com/
GitLabアカウント作成手順

##アカウント作成画面

<a href="https://gitlab.com/users/sign_in" target="_blank">GitLabのSign Inページ</a>で、**Register**タブをクリック。

![キャプチャ1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/314115/4248f287-b646-a04a-69c1-67990ede6ae1.png)

・Full name
・Username(他人に公開されるID)
・Email
・Email confirmation
・Password

以上の必要項目を入力。

・I accept the Terms of Service and Privacy Policy
・私はロボットではありません

にチェックを入れ、**Register**ボタンをクリック。

![キャプチャ2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/314115/b7025fe6-a74a-a7e2-aab4-b1350f686d68.png)

##確認メール

登録したメールアドレスに確認メールが来るので、**Confirm your account**をクリックしてアカウント作成完了。
テンプレートエンジンを使ってMVC

#はじめに
おはようございます。こんにちは。こんばんは。
ワタタクです。
今回はテンプレートエンジンの使い方について見ていきましょう。
#テンプレ−トエンジンとは
WEB開発において主流の作成法には「MVC」が採用されている場合がほぼ多いです。
ですが、Javaにはjspと呼ばれるものが存在し、MVCができますが、
PHPではjspみたいなのが存在しないため、MVCが出来ません。（やろうと思えば多分できる）
そこで出てくるのがテンプレートエンジンです。
つまり、テンプレートエンジンはコントローラーとビューを分けるものです。
#テンプレートエンジンの使い方
テンプレートエンジンにはいくつか種類があり、PHPで手っ取り早くMVCを実装させるためにCakePHP,Laravel,codeigniter
などのフレームワークを使えば簡単に実装できます。（気が向けば、各フレームワークの解説記事を書きます。）
ですが、今回はそういったフレームワークは使わず、Smartyというテンプレートエンジンを使います。
#Smartyの使い方
[公式ドキュメント](https://www.smarty.net/docsv2/ja/)を見れば全部書いてあるので、公式ドキュメント見ろ！！
って言えば良いのですがそれだと面白くないので書いていきます。
##1.準備
Smartyを扱うにはある準備をしないと動きません。
まずはその準備から。

*1.[公式サイト](http://www.smarty.net/)から最新版のSmartyのZipファイルを入手する。*
*2.入手したZipファイルを解凍し、中にある「libsフォルダ」を丸ごと作成プロジェクト「smartytest」に配置する*
*3.smartytestフォルダ直下に「templates_c」、作成したテンプレートファイルを格納する「templates」を作成<font color="orange">（Mac、Linuxの場合「templates_c」に対してPHPからの書き込み権限を与えておく。）</font>*
**書き込み権限の与え方**

```
$chmod 777 〜/template_c
```
または、右クリックし``「情報を見る」``をクリックし、書き込み権限を与える。
※templates_c フォルダは、テンプレートをPHPにコンパイルされたファイルを配置するフォルダ。

##2.コントローラー(PHP)で行うこと。
###1.「libsフォルダ」の中の「Smarty.class.php」を読み込む

```php
require_once $_SERVER['DOCUMENT_ROOT']. '/smartytest/libs/Smarty.class.php';
```

###2.Smartyオブジェクトを生成する

```php
$smarty = new Smarty();
```

###3.テンプレートが格納されているディレクトリを設定する。

```php
$smarty->setTemplateDir($_SERVER['DOCUMENT_ROOT'].'/smartytest/templates/');
```
###4.コンパイルされたテンプレートが保存されているディレクトリを設定する。

```php
$smarty->setCompileDir($_SERVER['DOCUMENT_ROOT'].'/smartytest/templates_c/');
```

###5.テンプレートを呼び出し、表示する

```php
$smarty->display(「templates」からの相対パスでテンプレート名(〜.tpl));
```

###6.コントローラー(PHP)で作った変数をテンプレートに持っていく

```php
$smarty->assign('テンプレートで使う変数(テンプレート変数)', コントローラー(PHP)で作った変数);
```
これぐらい知っておけばいけるかな？後はドキュメントで。
次はテンプレートの方を見ていきましょう。

##3.テンプレート(.tpl)
ここではテンプレート(Smarty)で扱うことのできる構文について見ていきたいと思います。
構文についてはたくさんあるので必要最低限書きます。
それ以上の事はドキュメント参照でお願いします。
###1.assignで持ってきた変数の使用方法

```
{$テンプレート変数}
```
####[TIPS]
*テンプレート変数は表示時に以下の書式で加工できる*=<font color="Red">**修飾子**</font>

```
{$テンプレート変数|修飾子}
```

- $message中の改行を改行タグに置き換える

```
{$message|nl2br}
```

- 日時データをフォーマットして表示

```
{$date|data_format:'%Y年%m月%d日 %H:%M:%S'}
```

- 初期値設定

```
{$message|default:''}
```
また、assignされたものがオブジェクトでそのメソッドを実行するまたはそのプロパティを取り出すとき

- メソッド

```
{$foo->bar()}
```
- プロパティ

```
{$foo->bar}
```

###2.条件分岐

```
{if 条件}
〜
{elseif 条件}
〜
{else}
〜
{/if}
```
<img width="609" alt="{if}_{elseif}_{else}___Smarty.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116696/6107006c-ad71-4253-d59f-c1d0da25fd2b.png">


####[TIPS]
smartyでの変数の存在判別

```html
{if isset($var)}
　変数は存在してます
{else}
　存在してません。
{/if}
```
phpと同じくissetが使えます。
このようにPHP関数も組み込むことも出来ます。

###3.ループ

```
{foreach from = テンプレート変数(配列) item = 各要素を格納する変数名 (name = ループの名前)}
〜
{foreachelse}
ループが回らなかった場合
{/foreach}
```
最後にコメントは以下のように書きます。

```
{* ここにコメントを書く *}
```
こんなものかな？

もし、何か間違い等がございましたらご連絡下さい。
最後まで読んでいただきありがとうございます。
MacにNode.jsインストール

とても簡単にインストール出来ます。情報はたくさんありますが、
MacでNode.js開発環境を作りたかったため自分なりのメモです。

※ターミナルにて作業。

## Homebrewをインストールしておく
```bash
インストール
$ /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

確認
$ brew -v
```

## Nodebrewインストール
```bash

インストール
$ brew install nodebrew

確認
$ nodebrew -v
```

## Node.jsインストール
```bash
ディレクトリを作成しておく。
※インストールディレクトリがないと怒られる場合があるため。
$ mkdir -p ~/.nodebrew/src

最新版インストール
$ nodebrew install-binary latest

利用可能バージョンな確認
$ nodebrew ls
例) v12.6.0と表示される。

表示されたバージョン指定
$ nodebrew use v12.6.0
```

## その他設定
```bash

パスを通す
echo 'export PATH=$HOME/.nodebrew/current/bin:$PATH' >> ~/.bash_profile

読み込み
. ~/.bash_profile
```

## 確認
```bash

node -v
npm -v
※バージョンが表示されたらインストール完了。
```

## お試し実行
```bash
vi hello.js
※以下記載。
console.log('Hello, World!'); 

実行
$ node hello.js
Hello,World!
```
実務経験無しでTwitter転職をしてみた

## はじめに
最初は軽い気持ちで呟いたのですが、予想以上に拡散していただき、転職に本腰をいれることになりました。

リプ・ＲＴ・ファボしていただいたみなさまに改めてお礼申し上げます。

６月末から活動を始め、約１か月ほどでTwitter経由で転職することができました。

自分にとってTwitter転職は未知のもので情報もあまりなかったので、Twitter転職をしているときに感じたことや活動内容を書いていきたいと思います。

## 私のことについて
### 職歴
- 飲食業界（約１年）
- 車業界（約１か月）
- 建築業界（約９カ月）
- IT業界（約３か月）

年齢は２５歳で既に４社渡り歩いています。自分で見てもやばい奴としか思えません。

**こういった背景もあって普通の転職は厳しいだろうと思っていたので、Twitter転職ならポートフォリオなどを見て判断してもらえるかなと考えたわけです。**

なので今回はTwitter転職のみで、エージェントを使ったり、転職サイトを使ったりした転職は行っていません。
### スキル感
私がプログラミングを始めたきっかけは職業訓練校です。６か月通いました。

言語はJavaで、ECサイトをフルスクラッチ（JSP、サーブレット）で開発したり、Webソケットを使ってリアルタイムチャットアプリを作ったり、アンドロイドアプリを開発したりしました。

そのほかにもL2・L3スイッチを使ってネットワークを構築したり、Linuxの基礎を勉強したりと、Web開発に必要な基礎を学びました。

おそらくプログラミングスクールでここまで教えているところはほとんどないと思うので、かなり恵まれたスタートだったと思います。

職業訓練校を卒業した後は、Web系のSES会社に就職しましたが現場に出る前に退職しました。約３か月ほどいましたがほとんど自習です。

この会社でPHP（Laravel）、JS（Vue）をメインに学習し、このときに[ポートフォリオサイト](https://wim-site.herokuapp.com )と本管理サイトを作成しました。

インプットとして読んでいた本はこんな感じです。
![mybook-app43.herokuapp.com_public_wim (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/431346/0d384944-d177-dc94-5186-6293c5e39a9d.png)

## Twitter転職
### ツイートによる効果
実際にツイートした内容やインプレッションなどはこちらです。
![twitter_tensyoku.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/431346/f1d58f3f-99cf-5bf4-e132-93d8204a4bf2.png)
声をかけて頂いた企業は約１０社です。内訳は**SES２割、自社３割、受託５割**といった感じです。私の場合、転職エージェントから声がかかることはほぼ無かったです。
### 自分が思っていたこととのギャップ
自己紹介の箇所にも書いた通り職歴が壊滅的すぎるため、普通の転職（転職サイト、転職エージェント）では厳しいと感じていました。

その点Twitter転職では、

- **アウトプットしたものを見た上で声をかけてもらえる**
- **カジュアル面談で人となりを伝えられる**

このようにある程度こちらを知ってもらったうえで面接を受けられるので、なんとか挽回できるであろうと考えていました。

たしかにカジュアル面談はあるのですが、面談する相手はほぼエンジニアの方で人事の方ではありません。**つまり面接ではゼロベースから始まるということです。**

また、ポートフォリオも見ていないかったり、そこまで深く見てもらえてなかったりと、**「とりあえず声をかけてみた」**という温度感が大半だと感じました。

### 転職活動の進み方
まずはリプやDMで「こんな会社なのでどうですか？」みたいな感じで声がかかるので、興味があればカジュアル面談に進むといった流れになります。

私の場合は、とりあえずいろんなところから話を聞いてみたかったので全ての会社とカジュアル面談をしました。

カジュアル面談の内容は、その会社がどのようなことをやっているか、会社の雰囲気や福利厚生、私の今までの経歴やエンジニアになろうと思ったきっかけなどです。**面談相手が人事よりもエンジニアの方が多かったので、残業や有休、技術面など少し突っ込んで聞いていました。**

カジュアル面談を終えて選考に進みたいと感じたところにその旨を伝え、本格的に選考に進むといった流れになります。
面接の回数は１～２回のところがほとんどでした。

最終的に受けたのは５社で**内定を頂いたのは２社**という結果になりました。
### 面接の内容
面接の内容についてはTwitter転職だからといって特別なことはなかったです。

- 志望理由
- 退職理由
- なぜエンジニアになりたいのか
- 将来どんなエンジニアになりたいのか
- どんな勉強をしてきたか（制作物はあるか）
- 興味のある技術

このへんの質問はどの会社でも聞かれました。逆に技術的な質問をしてきたところは少なかった印象です。

２社ほどその場でコーディングするということがありましたが、１社はFizzBuzzで難易度的には高くなかったです。

**やはり未経験なので、技術面よりはポテンシャルであったり、会社にフィットするかどうかを重要視しているようでした。**

## さいごに
Twitter転職を最大限活用できるのは、ある程度スキルがある人か、エンジニアの知り合いがフォロワーにそれなりにいる人だと感じました。Twitter転職はあくまでも選択肢の１つとして考えておくのがよさそうです。

しかし、Twitter転職で声をかけてくださったほとんどが自社・受託の会社だったので、そちらの方面を考えている方はやってみるのもよいかもしれません。

実務経験無しで転職を考えている人もいると思いますが、こんな職歴のやつでもなんとかなったので地道にやっていけばきっと大丈夫です。
VueやNuxtでcodemirrorを使うときにはvue-codemirrorが便利

## VueやNuxtでcodemirrorを使うときにはvue-codemirrorが便利
結論から言うますと、こちらのリポジトリで公開されているスクリプトが便利です。
https://github.com/surmon-china/vue-codemirror/

CodeMirrorは色々な言語・デザインテーマに対応したエディター機能をWebサイトに搭載できるJavaScriptです。

本家のレポジトリのGitHubのスター数は18000を超えており、こちらのVueコンポーネントバージョンもスター数は1000を超えています。
Nuxtのプロジェクトで実際に使いましたが、特に不具合もなくつかています。ぜひ参考になれば幸いです。

この記事が参考になれば幸いです。
## 終わりに
私は現在、Web3のサービスの開発をしています。詳しくはこちらの記事をご覧下さい。
        [無料でイーサリアムが当たる、Web3時代の寄付サイトを作った話](https://note.com/kenroda/n/n814347fbdcd7)
v-bindとpropsを使って子コンポーネントに動的な値を渡す

Mustache記法で展開していた値をpropsを通じて子コンポーネントに渡したいみたいなことがたまにある。
けれど、下みたいなノリの書き方ができない。

```html
<div message="{{ message }}"></div>
```

そういう場合は`v-bind`でpropに渡す要素をデータバインディングしてやる。

## 親コンポーネント側のtemplate
　注意点として、htmlは大文字を認識してくれないので、`v-bind:`の属性名で単語をつなげる場合は、ケバブケースで書いてやる。

```html
<my-component v-bind:skill-duraion="duration"></my-component>

<!-- 蛇足だけどv-bindは省略できる-->
<my-component :skill-duraion="duration"></my-component>
```

## 子コンポーネント側のpropsで受け取る

　Vueは、propsでデータを渡すときにケバブケースをキャメルケースに変換してくれる。
　なぜなら、受け取ったJavascriptでは、ハイフンを変数名に使えないから。

　よって受け取るには以下のように、

　Arrayで属性名をString指定したり、

```
props: ['skillDuration']
```
　とか

　Dictionary(属性名: 検証要件)で受け取る。

```
props: { skillDuration: Number } 
```

## propsで受け取った値を使う

* `this.skillDuration`のようにして使う。
Visual Studio Codeに超絶便利な Remote Development を入れる

# はじめに

Microsoft が提供している、 Code Editor の Visual Studio Code に、画期的なエクステンションの VS Code Remote Development が出ました。

これは、手元のラップトップ環境から、リモートの環境に接続して、IDE環境を活用したプログラミングを行うことが出来るようになります。これによって解決する課題は、以下のものだと考えています

- ラップトップがWindowsで、開発環境の準備が大変だった(Linuxエコシステムが強力でWindowsで実現するのは大変)
- ラップトップの性能が低く、プログラミング効率が落ちていた



特に、1個目の課題は日々感じていたので、とても便利になって感動をしています！
それでは、導入手順を以下に記載していきます。



# Visual Studio Code Install

以下のURLから適切にインストールします
https://azure.microsoft.com/ja-jp/products/visual-studio-code/



# VS Code Remote Development

## Install

以下のURLでInstallをクリックし、手元のVS Code上へインストールします

https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.vscode-remote-extensionpack



## Configure

SSHリモート先の情報を設定します。Configureをクリックします。

![1563710976394.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104247/4b476c8f-1e93-57ff-1bcd-512344dd4ffa.png)



好きな場所を選択します

![1563711054443.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104247/72145041-7017-1bc6-9648-c901f979e347.png)



config書式例

```
# Read more about SSH config files: https://linux.die.net/man/5/ssh_config
Host name
    HostName xxx.xxx.xxx.xxx (IPアドレスなど接続先)
    Port 22
    User hoge (ログインするユーザ名を書く)
    IdentityFile ~/.ssh/hoge_rsa (鍵認証に使う鍵ファイルを記述)
```



元々使用していた RSA KEY を `C:\Users\susugiya\.ssh` に格納して、以下のconfigファイルを作成します

```
# Read more about SSH config files: https://linux.die.net/man/5/ssh_config
Host centos_javaok
    HostName XXX.XXX.XXX.XXX
    Port 22
    User opc
    IdentityFile "~/.ssh/id_rsa"
```



## Connect

Configureが完了すると、CONNECTIONSの配下に、定義したHostの名前が見えてきます。+マークのついか画像をクリックします。

<img width="630" alt="1563713018213.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104247/8e3bca45-0ae0-887c-4c5f-3a6acf6b3457.png">



新しく VS Code が立ち上がり、SSHトンネル処理が走ります。一定時間後、接続完了になればリモート環境側のファイルシステムが見える状態となります。

左のファイルメニューを選択して、Open Folder を選択します。

![1563713201943.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104247/09c26e66-45bc-d70d-680b-27d8fc428580.png)



開きたい Path を選択します。Default のまま OK をおします

![1563713233670.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104247/a5780499-27e1-61c9-08ba-f5e604fdecc0.png)



リモート先には、javaのソースコードが保存されており、これをローカル側の VS Code で開きます。Runボタンが現れているので、押してみます。

![1563713649964.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104247/21171d64-302f-7e9b-377b-b05c8b7a09d1.png)



デバッグメニューから、ターミナルを開き、Javaの実行結果を確認することが出来ます。

![1563713833443.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104247/983b8ca2-5819-e80e-98d6-859d69c9b83d.png)



また、Remoteの Terminal をローカルの VS Code 上で開くこともできます。

![1563713997921.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104247/9e8e63da-f71e-f80a-f4fa-9905e95ea9ed.png)



# 参考URL

https://code.visualstudio.com/docs/remote/troubleshooting

https://code.visualstudio.com/docs/remote/wsl
vimのタブ化

### vim標準のタブ機能

元々vimには１プロセスで複数ファイルをバッファで管理するという機能があります。これをタブで表示するという事も出来ちゃいます。

[tabpage - Vim日本語ドキュメント](https://vim-jp.org/vimdoc-ja/tabpage.html)

ですが、help見てもらえれば分かる通り、タブ操作のコマンドが煩わしい。。と感じた方がいて、とても便利なrc scriptを公開してくれている方がいます。

[vimのすごい便利なのにあまり使われていない「タブページ」機能](https://qiita.com/wadako111/items/755e753677dd72d8036d)

頻繁に使用するであろう以下の機能が簡易キー入力で操作できるようになる。これはいい。
<img width="456" alt="201907212220.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/466853/d82ed168-642b-26b4-6b42-54bfb4b5f0e2.png">

以下のvim scriptを.vimrcに追記すれば使えるようになります。

```vim:.vimrc
"------------------------------------------------------------
"Tab pages Scripts

" Anywhere SID.
function! s:SID_PREFIX()
    return matchstr(expand('<sfile>'), '<SNR>\d\+_\zeSID_PREFIX$')
endfunction

" Set tabline.
function! s:my_tabline() "{{{
    let s= ''
    for i in range(1, tabpagenr('$'))
        let bufnrs = tabpagebuflist(i)
        let bufnr = bufnrs[tabpagewinnr(i) - 1]  " first window, first appears
        let no = i  " display 0-origin tabpagenr.
        let mod = getbufvar(bufnr, '&modified') ? '!' : ' '
        let title = fnamemodify(bufname(bufnr), ':t')
        let title = '[' . title . ']'
        let s .= '%'.i.'T'
        let s .= '%#' . (i == tabpagenr() ? 'TabLineSel' : 'TabLine') . '#'
        let s .= no . ':' . title
        let s .= mod
        let s .= '%#TabLineFill# '
    endfor
    let s .= '%#TabLineFill#%T%=%#TabLine#'
    return s
endfunction "}}}
let &tabline = '%!'. s:SID_PREFIX() . 'my_tabline()'
set showtabline=2 " 常にタブラインを表示

" The prefix key.
nnoremap    [Tag]   <Nop>
nmap    t [Tag]

" Tab jump
for n in range(1, 9)
  execute 'nnoremap <silent> [Tag]'.n  ':<C-u>tabnext'.n.'<CR>'
endfor

" t1 で1番左のタブ、t2 で1番左から2番目のタブにジャンプ
map <silent> [Tag]c :tablast <bar> tabnew<CR>
" tc 新しいタブを一番右に作る
map <silent> [Tag]x :tabclose<CR>
" tx タブを閉じる
map <silent> [Tag]n :tabnext<CR>
" tn 次のタブ
map <silent> [Tag]p :tabprevious<CR>
" tp 前のタブ

"---------- End tab pages Script
```


コマンドモードの時に

* tc = タブページの追加
* tx = タブページの削除
* t<number> = 表示するタブの切り替え

タブの表示位置の切り替えとか、他にも機能はありますが、それは正直ほとんど使用しないと思われます、現時点では。
GO言語　めちゃくちゃ初歩的なところで躓いた点をまとめてみる。

自分用に躓いた点をメモ。
どんどん追記していく予定です。


##まず＄GOPATHって？
GOを勉強してまず最初に躓きました・・。
表題にもある**＄GOPATH**ってなに？ってことです。

一言で言えば、
**＄GOPATH**はGO言語の開発を行う**ワークスペース**である！

少し詳しく説明すると、
GOを使ったプログラムのソースコードや
コンパイルされたバイナリのパッケージを置くためのフォルダーを指すために、
GOPATHという環境変数を設定する必要がある。

GOプログラムの中で**importコマンド**が記述されていると、
GOPATHで指定された対象のパッケージを探すこととなる。

##ディレクトリ作成

独特のプロジェクト構成があるので、覚えるためにも記載。

**myprojectディレクトリ（例）**を作成しそこを起点に，
**bin**，**pkg**，**src**という3つのディレクトリを作成。
３つのディレクトリの役割としては以下参照。

```bin → go install時の格納先```
```pkg → 依存パッケージのオブジェクトファイル```
```src → プログラムのソースコード```

##環境変数GOPATHで指定する

**myprojectディレクトリ**のパスを**GOPATH**という環境変数を指定する。

```$ cd myproject```
```$ export GOPATH=`pwd`  # myprojectをGOPATHに登録```


##ゴルーチン（goroutine）って？
並行処理を実現するために必要な処理で、
Go言語の代表的な機能のうちの１つ。

**goroutine**として並列実行させたい処理は、関数として実装する。
```go 関数の呼び出し```　頭に**go**とつけるだけ！

呼び出し元とは別の実行単位で動作を開始して、
呼び出された関数が終了すると、その**goroutine**も同時に終了する。
この辺の動作、頭だけで理解しようとするとよくわからずパニックになったので
調べてみると沢山わかりやすくまとめられている記事がありました！
**「ゴルーチン　とは」**で出てきます。






2019/07/24　ゴルーチンって？　追記
MySQLの備忘録190721

知識0でMySQLをはじめたので、つまづいたところを含めた備忘録。
昨日と実際に実行して動いた構文をただ連ねるだけです。
オタクなので、テンション上げるためにヒプノシスマイクのキャラ名が出てきます。



・まずデータベースを作る
create datebase データベース名；

```
mysql> create database test1907;
```

・使いたいデータベースを指定する
use データベース名；

```
mysql> use test1907;
```



・テーブルの作成
create table テーブル名（
列名 文字型１,
列名 文字型１,
・・・
）；

```
mysql> create table table1(
    -> no int,
    -> name varchar(20)
    -> );
```


・値の追加
inset into テーブル名（列名,列名) values(値,値）
※自分の入れたい値だけ追加することも可能
※値が入ってないセルがでた場合は「NULL」になる

```
mysql> insert into table1(no,name) values(1,'伊奘冉一二三');
```

```
mysql> insert into table1(no) values(2);
```

・データベース中のデータの取り出し
select * from データベース名

```
mysql> select * from table1;
+------+--------------------+
| no   | name               |
+------+--------------------+
|    1 | 伊奘冉一二三       |
|    2 | NULL               |
+------+--------------------+
```

.テーブル構造の参照
desc テーブル名;

```
mysql> desc table1;
+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| no    | int(11)     | YES  |     | NULL    |       |
| name  | varchar(20) | YES  |     | NULL    |       |
+-------+-------------+------+-----+---------+-------+

```

特定の列を指定して取り出す
select 列名 from テーブル名
※複数列指定する場合はカンマで繋げる

```
mysql> select no from table1;
+------+
| no   |
+------+
|    1 |
|    2 |
+------+
```

・行を絞り込む
select 列名 from　テーブル名　where 条件式　
※「*」は、テーブル全体を指定する書き方
※= 等しい、<>　等しくない

```
mysql> select * from table1 where no=3;
+------+-----------------+
| no   | name            |
+------+-----------------+
|    3 | 観音坂独歩      |
+------+-----------------+
1 row in set (0.00 sec)

mysql> select * from table1 where no<>2;
+------+--------------------+
| no   | name               |
+------+--------------------+
|    1 | 伊奘冉一二三       |
|    3 | 観音坂独歩         |
+------+--------------------+
2 rows in set (0.00 sec)
```

・NULL値の検索
select 列名 from テーブル名　wehere　列名　is null

```
mysql> select * from table1 where name is null;
+------+------+
| no   | name |
+------+------+
|    2 | NULL |
+------+------+
1 row in set (0.00 sec)
```
Leetcode #166: Fraction to Recurring Decimal

```swift
func fractionToDecimal(_ numerator: Int, _ denominator: Int) -> String {
    if numerator == 0 {
        return "0"
    }
    let isPositive = (numerator < 0 && denominator < 0) || (numerator > 0 && denominator > 0)
    var numerator = abs(numerator)
    var denominator = abs(denominator)
    let num = numerator / denominator
    var remainder = numerator % denominator
    if remainder == 0 {
        return isPositive ? "\(num)" : "-\(num)"
    }
    var dict = [Int: Int]()
    var ar = [Int]()
    var index = 0
    var answer = isPositive ? "\(num)." : "-\(num)."
    while remainder != 0 {
        if let value = dict[remainder * 10] {
            for i in stride(from: 0, to: value, by: 1) {
                answer += "\(ar[i])"
            }
            answer += "("
            for i in stride(from: value, to: ar.count, by: 1) {
                answer += "\(ar[i])"
            }
            answer += ")"
            return answer
        }
        ar.append(remainder * 10 / denominator)
        dict[remainder * 10] = index
        index += 1
        remainder = (remainder * 10) % denominator
    }
    for n in ar {
        answer += "\(n)"
    }
    return answer
}
```
ruby: to_iメソッドについて

rubyを勉強していてto_iメッドについて学んたことをまとめる。
##to_iメソッドの使い方
to_iメソッドは、文字列を10進数の表現と見なして整数に変換します。
文字列の先頭から10進数と見なせる部分を切り取って変換します。
＊１０進数とは
数値の表現形式のうち、「0」から「9」までの10種類の数字を使って数値を表現する形式

```sample.rb
string = '1993'
number = string.to_i
puts number
````

・結果

```
1993
```

10進数と見なせない部分は０を返す
ex)'はじめまして', nullなど

```sample.rb
string = 'はじめまして'
number = string.to_i
put number
```

・結果

```
0
```

１０進数と１０進数と見なせない部分が混合している時

```sample.rb
string = '12 apple'
number = string.to_i
put number
```

・結果

```
12
```
OAuth 2.0 for Browser-Based Apps

[OAuth 2.0 for Browser-Based Apps (Draft 2)](https://tools.ietf.org/id/draft-parecki-oauth-browser-based-apps-02.html) ざっくりまとめ

5 First-Party Applications

* First-Party ApplicationにOAuth (OpenID Connect) を適用する場合もPassword GrantではなくAuthorization Code Flowを使うことが強く推奨される (RECOMMENDED)
  * 認可サーバーをリダイレクトで切り離しておくことで、多要素認証や、シングルサインオン、外部IDP認証といった拡張をしやすくなる。

6 Architectural Considerations

* ブラウザアプリ（クライアント）とAPI（リソースサーバー）が同じドメインで提供される場合は、OAuth (OpenID Connect)  の利点を享受できないため、セッションベースの認証の方がセキュリティリスクが低く適する
* ブラウザアプリのバックエンドでトークン処理を行う場合は、バックエンド自体はConfidential Clientになるが、アプリ全体としてはPublic Clientになる可能性もある

7 Authorization Code Flow

* ブラウザアプリはPKCEを実装しなければならない (MUST)
* ブラウザアプリはstateパラメータでCSRF対策をしなければならない (MUST)
* 認可サーバーはリダイレクトURIを完全一致で検証すべきである (SHOULD)

8 Refresh Tokens

- 認可サーバーはブラウザアプリに対してRefresh Tokenを発行すべきでない (SHOULD)
- Refresh Tokenを発行する場合はRefresh Token Rotationに対応しなければならない (MUST)

9 Security Considerations

* 認可サーバーはブラウザアプリをPublic Clientとして登録しなければならない (MUST)
* 認可サーバーはブラウザアプリに1つ以上のリダイレクトURLの登録を要求しなければならない (MUST)
* ブラウザアプリを共有鍵（Client Secret）で認証することは、クライアントIDをリクエストパラメータに入れる以上の意味を成さないため推奨されない (RECOMMENDED)
* 共有鍵でブラウザアプリを認証する場合も、認可サーバーはブラウザアプリをPublic Clientとして扱わなければならない (MUST)
* クライアントのIdentityを保証できない場合、認可サーバーは認可要求を（以前の同意に基づいて）ユーザー操作なしに処理すべきでない (SHOULD)
  * リダイレクトURIをHTTPSの固定URLとすることをクライアントのIdentity証明とみなしてもよい (MAY)
* Mix-up攻撃を防ぐために、クライアントは認可サーバーごとに異なるリダイレクトURIを使い、認可要求時にリダイレクトURIをセッションに保存して、認可レスポンスの送信元を検証しなければならない (MUST)
* 認可サーバーはブラウザアプリに必要なCORSヘッダをサポートしなければならない (MUST)
* ブラウザアプリはContent-Security-Policyなどの仕組みで特定の静的にホストされたスクリプトのみ実行できるように制限すべきである (SHOULD)
* （9.8章に記載されるImplicit Grantに対する脅威については省略）
PanelからMultiIndexに変換する(時系列データ)

# なんでやるの
Pandas Ver0.24.2の時点でPanelにFutureWarningで

```
/Users/.../IPython/core/interactiveshell.py:3296: FutureWarning: 
Panel is deprecated and will be removed in a future version.
The recommended way to represent these types of 3-dimensional data are with a MultiIndex on a DataFrame, via the Panel.to_frame() method
Alternatively, you can use the xarray package http://xarray.pydata.org/en/stable/.
Pandas provides a `.to_xarray()` method to help automate this conversion.

  exec(code_obj, self.user_global_ns, self.user_ns)
```

<font color="Red">**Panelが廃止？**</font>される様なので時系列データのPanelのKeyから推奨のMultiIndexに変換するのを試してみました。
もっとうまいやり方がありそうな気がしなくもないのであれば教えていただけると喜びます。

# `.to_frame()` でやってみる
因みにWariningの中に
「`.to_xarray()`とか`.to_frame()`で変換しな。」
って書いてあるんでやってみた結果。

![スクリーンショット 2019-07-21 21.16.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318424/563a757c-97c5-d75e-dc39-a5ae22f5b824.png)

なんか思ってたのと違う。

こっから色々やれば行けそうな気もするけど面倒なのでPanelのItemsとIndexのDateをMuliti-Indexとして持つDataFrameを作ってくれる関数を自作します。

# 今回変換するもの
株のデータになります。（別に株のデータじゃなくてもindexが時系列のPanelなら何でも使える筈。）
始値・終値・高値・低値・出来高の5個のItems、時系列のMajor_axis、銘柄のMinor_axisといった形です。
具体的には以下の画像のよう
![スクリーンショット 2019-07-21 20.18.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318424/1b48324c-9731-8a4e-88e3-5dd12dac09a4.png)
このPanelを

```convert_to_multi.py
def convert_to_multi(panel_or_dict):
    """convert_to_multi:dictやpanelをPandasのMultiIndexにKeyを元に変換する

  詳細な説明:dictやpanelのkeyを元にPandasのMultiIndexを作成する、panel_or_dictはPanel型かdict型である必要があります。

  Parameters
  ----------
  panel_or_dict : Panel
    MultiIndexに変換したいPanelもしくはDict
  
  Returns
  ----------
  mi_res: MultiIndex
    よくよく考えたらDictはそのままpdでやればいい
    
    
    """
    for num, key in enumerate(panel_or_dict.keys()):
        panel_or_dict[key]['val'] = key
        panel_or_dict[key]['date'] = panel_or_dict[key].index
        if num == 0:　# ここいつも納得行かない、forの最初だけ何か行うみたいなのあったら教えてください、、、後述のelseみたいな。
            df_tmp = panel_or_dict[key]
        else:
            df_tmp = pd.concat([df_tmp, panel_or_dict[key]])
    else:
        mi_res = df_tmp.set_index(['val', 'date'])
    return mi_res
```

この関数にPanelを渡すことで以下の様なMultiIndexに変換します。
(ご自由に改造したり、お使い下さい)
![スクリーンショット 2019-07-21 20.24.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318424/6cbb052a-2926-ab5c-793e-28c1c89ca49b.png)

(中略...)
![スクリーンショット 2019-07-21 20.24.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318424/d7a42f69-55f8-40bc-048c-cace52d6595d.png)
実際の中身は権利関係上伏せています。
廃止される前にpickle等にしているPanelデータは変換しておきましょう。ではでは。

# データの抽出（おまけ）
### 終値`close_price_adj`のDataFrameだけ抽出したい場合

```.py
df_cp = mi_all.xs('close_price_adj', level = 'val')
```

### 具体的に`2013-01-07`の`close_price_adj`を抽出したい場合

```.py
mi_all.xs(['close_price_adj', '2013-01-07'], level = ['val', 'date'])
```

### 指定期間の`close_price_adj`と`close_price_adj`を抽出したい場合

```.py
mi_all.loc[(['close_price_adj', 'open_price_adj'], ['{指定期間のlist}']), :]
# Sliceでもうちょい上手くかけそう。。。
```
これに関してはどなたか教えていただけると。。。

# 追記：辞書から直接作成する
そもそもvaluesがDataframeの辞書が準備できているのであれば

```.py
 multi_index = pd.concat(dict.values(), keys=dict.keys())
```

これで良い。関数いらね。
Windows 10 で Apache + PHP + PostgreSQL をする

時間がないので急いで書きます。
また暇ができたら、修正しようと思っています。
おかしいところや、足りないところがあったら、コメントください。

## 環境

OS: Windows 10
Apache 2.4.39
PHP 7.3.7
PostgreSQL 10.6
httpd のパス: `D:\skytomo\Apache\Apache24\bin`
php のパス: `D:\skytomo\php-7.3.7`
psql のパス: `D:\skytomo\PostgreSQL\pg10\bin`

## Apache のダウンロードとインストール

@Komugi-R さんの [Windows10 にApacheを導入する](https://qiita.com/Komugi-R/items/bd9ee47aa8814683fb07)を参考にしてください。

## PHP のダウンロードとインストール

同じく、 @Komugi-R さんの [Windows10にPHPを導入し、Apacheで利用できるようにする。](https://qiita.com/Komugi-R/items/466fa58c5ee8743df238)を参考してください。

## PostgreSQL のダウンロードとインストール

@hidetoshi_n_cograph さんの [Windows10のLocal上でPostgreSQLをインストール](https://qiita.com/hidetoshi_n_cograph/items/9561b47f66d0c4b0ec10)を参考してください。

## Apache + PHP + PostgreSQL

はい、ここまでで、Apache、PHP、PostgreSQLを個別にダウンロードし、インストールしました。
また、Apache + PHP はもうすでにできたので、次は PostgreSQL を連携しましょう。

### php.ini を探す

あなたの`php.ini`がどこにあるか探すには、コマンドプロンプトで`php -r phpinfo(); | findstr php.ini`をしましょう。

```:コマンドプロンプト
$ php -r phpinfo(); | findstr php.ini
Configuration File (php.ini) Path => C:\WINDOWS
Loaded Configuration File => D:\skytomo\php-7.3.7\php.ini
```

`Loaded Configuration File => パス名`になっているはずです。

### php.ini が見つからない場合

`php.ini` が見つからない場合は、作りましょう。
`php`コマンドの場所にある`php.ini-development`をコピーして、名前を`php.ini`に変更しましょう。


### php.ini を設定する

`php.ini`の `;extension_dir = "/ext/"`みたいになってるところを、コメントアウトを外して、extがあるディレクトリのパスを書きます。僕の場合なら、`extension_dir = "D:/skytomo/php-7.3.7/ext/"`です。
だいたい、僕のでは、753行目のところにありました。

```ini:php.ini
; Directory in which the loadable extensions (modules) reside.
; http://php.net/extension-dir
;extension_dir = "./"
; On windows:
extension_dir = "php/ext のパス（人によって違うので注意）"
```

また、`;extension=pgsql`もコメントアウトを外しましょう。
だいたい、僕のでは、924行目のところにありました。

```ini:php.ini
;extension=pdo_odbc
;extension=pdo_pgsql
;extension=pdo_sqlite
extension=pgsql
;extension=shmop
```

### httpd.confの追加

```conf:
Loadfile "php/ext/php_pgsql.dll の パス（人によって違うので注意）"
```

を追加しましょう。

```conf:httpd.conf
LoadModule php7_module "D:/skytomo/php-7.3.7/php7apache2_4.dll"
Loadfile "D:/skytomo/php-7.3.7/php7ts.dll"
Loadfile "D:/skytomo/php-7.3.7/libpq.dll"
Loadfile "D:/skytomo/php-7.3.7/ext/php_pgsql.dll"
PHPIniDir "D:/skytomo/php-7.3.7"
AddHandler php7-script .php
AddType application/x-httpd-php .php
AddType application/xhttpd-php-source .phps
```

このようになるはずです。

## 動作確認

そしたら、動作確認をしましょう。
[PostgreSQLのインストール for Windows](https://www.be-webdesigner.com/technotes/server/install/postgresql.htm)の「動作確認をしてみる」を参考にしてください。

……うまくいきましたか？