OmniAICreator/Qiita-1.07M huggingface dataset:
簡単ログイン機能実装のエラー原因はauthenticate_user!だった

# はじめに
こちらの記事を参考に実装しましたので、コードで不明な点はこちらの記事を見にいってください。
[ゲストログイン・簡単ログイン機能の実装方法（ポートフォリオ用）](https://qiita.com/take18k_tech/items/35f9b5883f5be4c6e104)

# 発生している問題・エラーメッセージ
簡単ログイン機能の実装で、ログイン画面に「簡単ログイン」ボタンを設置したが、ボタン押してもログインできない。

```:ターミナル
Processing by HomesController#new_guest as HTML
Parameters:{"authenticity_token"=>"c1Qc02T4i6+77OtxhGDwxJwEQUYO8d9cIncoNjZ/hXa5c3IzxHPjFAr2QleTBCuMpnxd5+1Sk+HRa9RNXLGSkg=="}
Completed 401 Unauthorized in 1ms (ActiveRecord: 0.0ms)
```

# ソースコード

```ruby:routes.rb
post '/homes/guest_sign_in', to: 'homes#new_guest'
```

```ruby:homes_controller.rb
class HomesController < ApplicationController

  def new_guest
    user = User.find_or_create_by(email: 'guest@example.com') do |user|
      user.password = SecureRandom.urlsafe_base64
    end
    sign_in user
    redirect_to root_path, notice: 'ゲストユーザーとしてログインしました。'
  end
end
```

```ruby:devise/sessions/new.html.haml
(省略)
.easyLogin
  = link_to 'かんたんログイン', homes_guest_sign_in_path, method: :post, class:"btn btn-lg btn-success center-block"
```

# 考えたこと
- sessionで保持しているものとauthenticity_tokenをキーとして送られたコードが異なる？
- authenticity_tokenはログイン画面のフォームのinputタグの中にあったので、フォーム外に簡単ログインボタンを設置すれば、authenticity_tokenが関係なくなり解決される？

→結果的にどちらも間違っていた

# うまくいった時のソースコード

```:ターミナル
Processing by Users::SessionsController#new_guest as HTML
Parameters: {"authenticity_token"=>"2UEwYr4gIvtHF4GqHNPaXIiWgQSbEXPVjI9kneVS27oTZl6CHqtKQPYNKIwLtwEUsu6dpXiyP2h/k5jmj5zMXg=="}
  User Load (4.0ms)  SELECT  `users`.* FROM `users` WHERE `users`.`email` = 'guest@example.com' LIMIT 1
  ↳ app/models/user.rb:31
Redirected to http://localhost:3000/
Completed 302 Found in 10ms (ActiveRecord: 4.0ms)
```

```ruby:routes.rb
devise_scope :user do
  post 'users/guest_sign_in', to: 'users/sessions#new_guest'
end
```

```ruby:user.rb
(省略)
def self.guest
  find_or_create_by!(email: 'guest@example.com') do |user|
    user.password = SecureRandom.urlsafe_base64
  end
end
```


```ruby:sessions_controller.rb
class Users::SessionsController < Devise::SessionsController
  def new_guest
    user = User.guest
    sign_in user
    redirect_to root_path, notice: 'ゲストユーザーとしてログインしました。'
  end
end
```

```ruby:devise/sessions/new.html.haml
(省略)
.easyLogin
  = link_to 'かんたんログイン', users_guest_sign_in_path, method: :post, class:"btn btn-lg btn-success center-block"
```

# エラー原因

```ruby:homes_controller.rb
class HomesController < ApplicationController
(省略)
end
```
`homes_controller`は`applicatoin_controller`を継承していました。

```ruby:applicatoin_controller.rb
(省略)
before_action :authenticate_user!

protected

def configure_permitted_parameters
  devise_parameter_sanitizer.permit(:sign_up, keys: [:name])
end
```
`before_action :authenticate_user!`は、ログイン済みのユーザーだけを許可するので、これが原因で弾かれていました。

`before_action :authenticate_user!`をコメントアウトしたら、`homes_controller`でも問題なく画面遷移しました。

`sessions_controller`の方が自然なので、実装は`homes_controller`ではなく`sessions_controller`で設定しました。

# 参考記事
[ゲストログイン・簡単ログイン機能の実装方法（ポートフォリオ用）](https://qiita.com/take18k_tech/items/35f9b5883f5be4c6e104)
JetsonNanoへのdarknet(YOLOv3)インストール ＆ デモ

※JetsonNanoに入れたくて試したけど、設定を環境に合わせればPCにインストールする時もほぼ同じ感じでいけるはず

##darknetインストール
  1.以下からdarknetを取得 
  `git clone https://github.com/AlexeyAB/darknet.git` 
  2.darknetのフォルダへ移動 
  3.Makefileを編集 
  　※GPUなどの使用有無に合わせてフラグのON/OFFをセット
　　(以下はGPU/cuDNN使用有り、画像扱いたいのでOpenCVもON、とした場合)
  　`GPU=1`
  　`CUDNN=1` 
  　`CUDNN_HALF=1`
  　`OPENCV=1` 

  　以下をコメントアウト 
  　※ARCH= で５列記載のあるうちの一番最後
  　`# -gencode arch=compute_61,code=[sm_61,compute_61]`
![Screenshot from 2020-06-16 15-47-01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/207722/c3f1faa3-c0e0-3167-aa51-4db20aee5644.png)

  　以下を有効化
  　※「# For Jetson TX1 ・・・」のコメントのある行のARCH設定
　　(JetsonNanoでも有効)）
　　`ARCH= -gencode arch=compute_53,code=[sm_53,compute_53]`
![Screenshot from 2020-06-16 15-48-35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/207722/a3db6301-740a-9733-25b9-a49627331ded.png)

  4.ビルド 
  　・GPU使用有りの場合
  　　`PATH=/usr/local/cuda/bin:$PATH make -j4`
  　　※PATHは事前に.bashrcに記載しておくでもOK
  　・GPU使用無しの場合
 　　`make -j4`

##YOLOのデモ確認
  YOLOv3の学習済みファイルをダウンロードする
  `wget https://pjreddie.com/media/files/yolov3.weights`

  darknetのフォルダで以下を実行
  `./darknet detect cfg/yolov3.cfg yolov3.weights data/dog.jpg`
  モデル読み込みに時間がかかるが、以下の結果が見れればOK
  ![predictions.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/207722/9d10b391-b4ac-2b5f-804c-d13febcbb0c1.jpeg)

##Webカメラでのリアルタイム検出デモ
  `./darknet detector demo cfg/coco.data cfg/yolov3.cfg yolov3.weights`
  …でもJetsonNanoだと1.5FPSくらいしかでない(>_<)
  →tinyモジュールで試す 
  tiny用のYOLOv3の学習済みファイルをダウンロードする
　`wget https://pjreddie.com/media/files/yolov3-tiny.weights`
　tinyモジュールにて同様に実行
　`./darknet detector demo cfg/coco.data cfg/yolov3-tiny.cfg yolov3-tiny.weights -c 0`
  …それでもなんとか6FPSくらい(ToT)
　　パフォーマンス出したいならちゃんとカスタマイズしなさいってことネ(^^;
【Rails】UrlHelperを拡張する

# 独自のUrlHelperを定義したい

`Rails.application.routes.url_helpers` を include したClassを作成するとよいです。

```ruby

class MyUrlResolver
  class << self
    include Rails.application.routes.url_helpers
  end

  # 独自定義したhelper
  def self.custom_users_path(user)
    if user.admin?
      admin_users_path
    else
      users_path
    end
  end
end
```

これで、

```
> MyUrlResolver.admin_users
=> "/admin_users"
> MyUrlResolver.users_path
=> "/users"
```

標準のUrlHelperに加えて、

```
> MyUrlResolver.custom_users_path(admin_user)
=> "/admin_users"
> MyUrlResolver.custom_users_path(normal_user)
=> "/users"
```

独自定義したUrlHelperも使うことができます。
macOSでクリップボードにある文章の文字数を数える

# 背景
* 文字数をカウントしてくれるwebサービスを使うことがあった．
* でもいちいちブラウザに切り替えてコピペして文字数みてまた書き直して…という作業がめんどくさい．
* MS Word とかいう邪悪なソフト使いたくない．
* 文章の一部をいちいち別のファイルにコピペして `wc` コマンド叩くのもめんどくさい．
* Neovim で文章を書くことが多いからターミナルだけで作業を完結させたい．
    * 具体的には[これ](https://phonypianist.sakura.ne.jp/convenienttool/strcount.html)と同じ機能をターミナルだけでやりたい

# 方法
```
pbpaste | wc -m
```

## 解説
* `pbpaste`: クリップボードのデータを標準出力する．テキストならテキストが出力される． Finder でファイルをコピーしたならファイル名が出力される．
* `wc -m`: 文字数を数えてくれる． `-m` オプションでマルチバイト文字にも対応してくれる．
* パイプを使って `pbpaste` の出力を `wc -m` の入力として受け取り，最終的に `wc -m` の結果を出力する．

## 応用例
### 行数も含めた文字数を数えたい
`-l` オプションを追加します．

```
pbpaste | wc -ml
```
2個の数値が出力されるようになり，1個目が行数，2個目が文字数に対応します．

### 改行を削除した文字数を数えたい
`tr` コマンドで改行文字を削除します．

```
pbpaste | tr -d '\n' | wc -m
```

### 改行と空白を削除した文字数を数えたい
`tr` コマンドで空白と改行文字を削除します．

```
pbpaste | tr -d '\n' | tr -d ' ' | wc -m
```

### 他の文字コードにエンコードして文字数を数えたい
適当なオプションを付けて `nkf` コマンドを間に挟みます．
#### ISO-2022-JP
```
pbpaste | nkf -j | wc -m
```

#### Shift_JIS
```
pbpaste | nkf -s | wc -m
```

#### EUC-JP
```
pbpaste | nkf -e | wc -m
```

#### UTF-16
```
pbpaste | nkf -w16 | wc -m
```

# 参考文献
* [コンソールで文字数をカウントする - Qiita](https://qiita.com/skkojiko/items/79672b42aa87ed15b9ac)
Laravelでintervention/imageを使う

# intervention/imageをインストール
composerでインストールします。

```
composer require intervention/image
```

# 初期設定
インストールが完了したら、`app\config\app.php`を編集します。

`providers`に以下を追記。

```app.php
'providers' => [
...
Intervention\Image\ImageServiceProvider::class,
],
```

`aliases`に以下を追記。

```app.php
'aliases' => [
...
'Image' => Intervention\Image\Facades\Image::class,
],
```

これにより、`use Image;`でライブラリを読み込むことができます。
以上で初期設定は完了です。

# 写真の加工
試しに写真を反転するように加工してみましょう。

**[加工する素材]**
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/644759/9fbee058-5a02-4f74-fee5-fc02e19f6f98.jpeg" width=50%>


コントローラーを作成します。

```
php artisan make:controller PhotosController
```

作成したコントローラーを編集します。

```PhotosController.php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
use Image; // intervention/imageライブラリの読み込み

class PhotosController extends Controller
{
    // 写真を読み込み加工する
    public function retouch()
    {
        // 読み込み
        $path = storage_path('app/images/rabbit.jpg');
        $img = Image::make($path);
        
        $img->flip(); // 写真を反転させる
        
        //保存
        $save_path = storage_path("app/images/rabbit_flip.jpg");
        $img->save($save_path);
    }
}
```

実行後はこのようになります。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/644759/1c52885c-fdb0-cf00-e4e5-27055cf15c85.jpeg" width=50%>

他にもモザイクをかけたり

```php
 $img->pixelate(50);
```

グレースケールにしたりと、何かと高機能なライブラリです。

```php
$img->greyscale();
```


<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/644759/58d951b8-ef2a-c14d-e25d-2de80f65330d.jpeg" width=50%><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/644759/0e4b6702-4e2e-496b-07be-234b087da9f7.jpeg" width=50%>

[参考]
http://image.intervention.io/
https://blog.capilano-fw.com/?p=1574
PHPからJavaScriptへの配列データ渡し

#環境
PHP7系
jQuery3系

環境はdockerで構築


##きっかけ
ajax不可環境！！！
そこでPHPでAPIからレスポンス取得
取得したデータをJavaScriptに渡し判定後modalを表示したい

Guzzleを使用してサクサクっとレスポンスは取得したものの、
さあこれからどうやってJavaScriptへ渡そうか・・・
※以前も同じような事をやっているのにおぼろげにしか覚えてないので備忘録として残す


###早速コード

```sample.php
$result = json_encode($apiRespons);
```

```sample.js
var api_result = <?php echo $apiResult; ?>;
```

##たったのこれだけ
もちろん受け渡されたJavaScript側で
decodeしてゴリゴリ処理もできちゃう。
そして念願のモーダルも表示出来る


##終えてみて
サーバーサイドばかり見ることが多く、フロントが若干忘れがちになってしまう
傾向にあるため、備忘録としてこれからも常に忘れそうな（思い出したもの）を
残していくことにする。
それがどこかの誰かに１mmでも役に立てば良い。

最後になりましたが、
もう少しここ聞きたい等有りましたらコメント？ください

あと、こんなふうに書くと見やすいよ！等のアドバイスも受け付けます
（心が受け止められるかはわかりませんが；；）


最後までご覧いただきありがとうございました。
PG::ConnectionBad:   could not translate host name "db" to address: Temporary failure in name resolution

##GitHubActionsにて
オリジナルアプリにGitHubActionsを入れるべく悪戦苦闘する中
こんなエラーが発生

```
PG::ConnectionBad:
  could not translate host name "db" to address: Temporary failure in name resolution
```

むむむ。。
データベースに接続できない。。

色々と調べた結果、以下を参考にし、修正しました。
https://qiita.com/kajirikajiri/items/bf0ead854bba58131040
https://stackoverflow.com/questions/3582552/postgresql-connection-url/20722229#20722229
Postgresqlのポートを指定し、DATABASE_URLを明示しました。

修正前

```yml:.github/workflows/ruby.yml

name: Ruby

on:
  pull_request:
    branches:
    - master
    

jobs:
  run_spec:
    name: Run spec

    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v1 
    - name: Set up Ruby 2.6
      uses: actions/setup-ruby@v1 # https://github.com/actions/setup-ruby/blob/master/action.yml
      with:
        ruby-version: 2.6.x
    - name: Test with Rspec
      run: |
        gem install bundler
        bundle install --path vendor/bundle --quiet --jobs 4 --retry 3
        bundle exec rspec
```

修正後

```yml:.github/workflows/ruby.yml
name: Ruby

on:
  pull_request:
    branches:
    - master

jobs:
  run_spec:
    name: Run spec

    runs-on: ubuntu-latest

    services:
      postgres:
        image: postgres:10.3
        ports: ["5432:5432"]
        options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5
    steps:
    - uses: actions/checkout@v1 
      uses: actions/setup-ruby@v1 
      with:
        ruby-version: 2.6.x
    - name: Test with Rspec
      env:
        RAILS_ENV: test
        DATABASE_URL: postgresql://postgres@localhost:5432/postgres?encoding=utf8&pool=5&timeout=5000
      run: |
        gem install bundler
        bundle install --path vendor/bundle --quiet --jobs 4 --retry 3
        bundle exec rspec

```

<img width="670" alt="スクリーンショット 2020-07-01 17.43.13.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/660132/2f3ded2d-b540-b306-b71f-2c77f4593451.png">
無事に成功しました！
master.keyが見つからない問題 [初見殺し] - はじめてのデプロイで嵌るポイント(Rails 5.2以降)


# master.keyが見つからない問題 [初見殺し] - はじめてのデプロイで嵌るポイント(Rails 5.2以降)

デプロイ環境構築の過程で`master.key`なるものが必要に
（2020.9.28: これで悩む方は多そうなので補足追記しました ）

Railsアプリのローカル環境にも`config/master.key`がみつからない
(これは私の環境、経緯によるところが大きいかと)

## 環境
Rails 6.03

## 原因

`master.key`は`.gitignore`に含まれており、`git clone`の過程で失われたと思われる
- 私の環境では開発途中で環境を変化(Cloud9 >> ローカル)に移行した際のgit cloneで失われたかと
- **その他多いのが、開発環境 -> デプロイ環境移行時に`master.key`が失われるケース**


## 解決

### ①`master.key`の中身がわかる場合
ローカル環境には`master.key`がある場合など、`master.key`の中身を知ることができる場合は`master.key`を新規作成することで解決できます

```
vi config/master.key
```
で新規作成、一行目に`master.key`の中身を追記してエディタを閉じる

デプロイ環境で`master.key`が無いと言われているのであれば、EC2なりデプロイ先のサーバーに`master.key`を配置しましょう


### ②`master.key`の中身がわからない場合
`credentials.yml.enc`に機密情報を追記した覚えがない、運用するつもりもない、
または記述した内容が消えてしまっても再現可能な場合にこの方法を試してください

一旦`credentials.yml.enc`を削除して、
`master.key`も`credentials.yml.enc`もない状態をつくる

そして次のコマンドを入力

```
sudo EDITOR="vi" rails credentials:edit
```

すると
`credentials.yml.enc`と`master.key`が新たに生成される

ただし

```
$ vi config/master.key
```

では中身が空っぽ

```
$ sudo vi config/master.key
```

とするとようやく中身が確認できました


この方法はデプロイ環境で`credentials.yml.enc`を運用しない場合にも有効で
サーバー上でも同様にmaster.keyがない状態で
一旦`credentials.yml.enc`を削除し
アプリのルートディレクトリでローカルでやったことと同様に

```
sudo EDITOR="vi" rails credentials:edit
```
とすると同様に`credentials.yml.enc`と`master.key`が生成されます

## そもそも`credentials.yml.enc`ってなんぞ
機密情報の不用意な公開を防ぐための仕組みだそうです
`credentials.yml.enc`は鍵穴、`master.key`が鍵の関係にあって、
正しい`master.key`を用意することで、暗号化された`credentials.yml.enc`の中身を復号化し利用することができるようになる

DBのパスワードなどをcredentials.yml.encに記述して暗号化保護、運用するように想定されていると理解

以下の記事で`credentials.yml.enc`にAWSのaccess_key_id, secret_access_keyを追記したり、
それを取り出す方法を試みています
[[Rails6対応, 公式SDK] AWS SESを使ってRailsから送信元が独自ドメインのメールを送ってみた - Qiita](https://qiita.com/naokit-dev/items/4668ec379fbe6dcb45cd)

**ただしこのような運用をするのであれば、`master.key`を本番環境にポンと置いておくのもどうかと思うので
環境変数で渡すなりの運用方法が必要そうです**
次の記事参考になりそうです
[Railsのcredentials.yml.encは、どういった運用ができるか？ - LiBz Tech Blog](https://tech.libinc.co.jp/entry/2018/11/27/101347#linux%E3%81%AE%E7%92%B0%E5%A2%83%E5%A4%89%E6%95%B0)



## 参考
[Rails5.2から追加された credentials.yml.enc のキホン - Qiita](https://qiita.com/NaokiIshimura/items/2a179f2ab910992c4d39)
[【Rails】「credentials.yml.enc」と「master.key」の使い方について詳しく解説！｜TechTechMedia](https://techtechmedia.com/credentials-masterkey-rails/#masterkey-2)
yarn install ができない

## 前提
- ruby on rails 6.0.0 を使用。
- エラー文における/~/表記はフォルダ名やアプリ名などのディレクトリ構造として読み替えること。
- 細かい条件は把握しきれていないので同じ症状が起きた場合の解決策の1候補として考えること。

## 発生したエラー
*git clone* で持ってきたアプリを編集する際、 *yarn install* をしようとしたところ、下記のようなエラーが発生した。(全文は長すぎるため直接エラーが出ている箇所のみ記載)
>  <font color="DarkKhaki">warning</font> Error running install script for optional dependency: "/Users/~/node_modules/fsevents: Command failed.

~

> <font color="Red">error</font> /Users/~/node_modules/node-sass: Command failed.

## 解決方法
*yarn upgrade* というコマンドを実行することで正常にインストールすることができた。

## 最後に
明確な原因は不明なままだが、解決法から考えるにclone元と自分の環境にバージョンの違いがあったのかと思われる。
いつか自分が成長した頃にもう一度エラー文を読んでみようと思う。
画像処理 100 本ノック Q9, Q10 (フィルタ) の高速化

最近画像処理 100 本ノックというのを始めました。
https://qiita.com/yoyoyo_/items/2ef53f47f87dcf5d1e14

最近画像処理にちょっと興味があって numpy を上手に使いたいなぁ〜と思っていたので非常にありがたい問題集なのですが, Q.9. ガウシアンフィルタ, Q.10. メディアンフィルタ の解答例に不満があった(python で for 文を使いたくない！)のでなるべく numpy を使う処理を書いて速度を比較しました。

今回書いたコード:

```
def gaussian_filter(_img, filter_matrix):
    # assume that fY and fX is odd number
    (fY, fX) = filter_matrix.shape
    mY = (fY - 1) // 2
    mX = (fX - 1) // 2

    (Y, X, C) = _img.shape
    img = np.zeros((Y + mY*2, X + mX*2, C))
    img[mY:Y+mY, mX:X+mX, :] = _img

    out_img = np.zeros_like(_img, np.float32)
    for dy in range (fY):
        for dx in range(fX):
            out_img += filter_matrix[dy][dx] * img[dy:Y+dy, dx:X+dx, :]
    return out_img.astype(np.uint8)
```

画像の y, x ではなく `filter_matrix` の y, x を for で回すことで画像における足し算は numpy の for を使えるようにしています。
速度比較
gaussian_filter を 100 回呼び出して何秒かかるかを比較しました。`time` コマンドを使ってるので画像読み込み 1 回分の時間も含まれてますが大勢に影響はないと思います。

|手法|時間|
|----|----|
|今回のコード|0.72|
|模範解答|50.60|

圧倒的じゃないか我が軍は〜〜〜
Q10. メディアンフィルタについても, H * W * (filter_size) の画像(?)を作ってからその画像に対して np.median(axis=2) をやれば高速化できるんじゃないか~~と思います。~~できました。

```
def median_filter(_img, filter_size):
    # assume that filter_size is odd
    half_size = (filter_size - 1) // 2
    (Y, X, C) = _img.shape
    img = np.zeros((Y + half_size*2, X + half_size*2, C))
    img[half_size:Y+half_size, half_size:X+half_size, :] = _img

    out_img = np.zeros_like(_img)
    for c in range(C):
        big_ch_img = np.zeros((Y, X, filter_size**2))
        for fy in range(filter_size):
            for fx in range(filter_size):
                ch = fy * filter_size + fx
                big_ch_img[:,:,ch] = img[fy:fy+Y, fx:fx+X,c]
        out_img[:,:,c] = np.median(big_ch_img, axis=2)
    return out_img
```
計測時間は 1.71 秒 vs 302.98 秒でした。

ところで Pooling については for 文を使わない方法を思いついてないので誰か知ってたら教えて下さい。
ExcelでCSVが文字化けの対策法

#システム環境
1.Excel Version:1908
2.Excel Encoding:ANSI(デフォルト)
3.CSV Encoding:UTF8

#必要なソフト
NotePad++

#解決策
１　Notepad++でCSVを開く
２．ツールでEncodingを選択
３．Convert to UFT8-BOMを選択
AWS EC2入門 #4: 固定IPを取得しよう

![aws.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/665011/2803dc07-922d-e9a3-8543-572cfffd1798.png)

今回でいったん最終回とさせていただきます。AWSにはほかにもさまざまなサービスがあるので、興味のある方はぜひ自分で調べて使ってみてください。

#Elastic IPアドレスを利用する

①EC2ダッシュボードから「Elastic IP」を選択する
![img1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/665011/c4514c49-1705-5727-b86c-bea68a26edd1.png)

②右下の「割り当て」をクリックする
![img2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/665011/f2cf3f6f-a124-c274-b2ce-a6a907920b77.png)

③「Elastic IPアドレスの関連付け」を選択する
![img3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/665011/2ba61fb9-d3d4-031c-a68e-b28670535228.png)

④リソースタイプに「インスタンス」を選択し、インスタンスを指定した後、「関連付ける」をクリックする
![img4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/665011/eee286ee-05e7-065e-3cab-fb423bdd7c61.png)

⑤インスタンスを確認すると、パブリックIPが変わっているのがわかります
![img5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/665011/0c115415-32ef-d6c5-3f03-7d99611bcd3b.png)

⑥このパブリックIPをブラウザで確認してみると、前回と同じページが表示されています
![img6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/665011/c15d81f1-85bf-ccab-5a88-6611ce8bcb81.png)
これでインスタンスを再起動したとしてもIPアドレスが変わることはありません。
【C++】初級者からみたconsteval

# constevalについて
`constexpr`関数はコンパイル時でも実行時でも実行可能であったため、コンパイル時のみ実行可能な関数として`consteval`関数が定義できるようになる。
これだけならわかりやすい話だったのですがcppreference.comのコード例がキモかった。
以下引用[^1]です。(2020/07/01時点)

```c++:
consteval int f() { return 42; }
consteval auto g() { return &f; }
consteval int h(int (*p)() = g()) { return p(); }
constexpr int r = h();   // OK。
constexpr auto e = g();  // ill-formed、即時関数へのポインタは定数式の結果として許されません。
```

GCCではコメントの通り4行目がエラーになりませんがClangではエラーです。
`h(g())`とした場合はGCCでもエラーになりました。
どうしてGCCとClangで結果が違うのかわけが分からず「最適化あたりが原因かな？」とおもっていました。
ただいろいろ調べてコードを試しているなんとなく分かりました。
どうやら`consteval`関数へのポインタは`consteval`外部に出なければ使用可能のようです。
以下のようなコードであればClangもコンパイルが通りました。

```c++:
consteval int f() { return 42; }
consteval auto g() { return &f; }
consteval int h() {int (*p)() = g(); return p(); }
constexpr int r = h();   // OK。
```

デフォルト引数を関数内と見るか関数外と見るかの違いだったようです。
なんではじめからこう書かんのかと思いましたが、きっと元のコード書いた人はC++11からタイムリープしてきたんだと勝手に納得しました。

# まとめ
`constexpr`の緩かったところを厳格にした機能になります。`constexpr`のようにうっかり実行時になる心配はないのですが逆に言うと実行時とコンパイル時で関数名か名前空間を変更する必要があるので使い所はよく考える必要がありそうですね。
また上記の~~`h()`~~ `g()`[^2]のような関数は`constexpr`関数内でも使用できないため、芋づる式に`constexpr`が伝染していきそうなのはちょっと困りものかもしれません。
余談ですが`array`が使えるようになっているの、かなりありがたいですね。私もコンパイル時実行に関してはC++14直前ぐらいからタイムリープしてきたので実際に使ってみて感動しました。
そしてまだ`cmath`のコンパイル時実行対応が規格に制定されていない事実に絶望しました。やっぱりGCCがNo.1

[^1]: https://ja.cppreference.com/w/cpp/language/consteval
[^2]: (7/15 修正)コメント指摘受けました。うっかりミスです。
【PHP】時間取得

タイムスタンプから時効への返還とか`time()`とか`strtotime()`とかの役割をすぐ忘れるので、備忘録。


#date(タイムスタンプ→日時)
日付の文字列を返してくれる。
タイムスタンプを文字列の日時に直してくれる。
##現在時刻取得

```php5
print date('Y/m/d');//20xx/x/x/
```
##タイムスタンプを文字列に変換する

```php5
$timeStamp=time();
print date('Y/m/d h:i:s',$timeStamp);
```
#strtotime(日時→タイムスタンプ)
英文形式の日付を Unix タイムスタンプに変換する。
日付をタイムスタンプ
##例

```php5
echo strtotime("now"), "\n";
echo strtotime("10 September 2000"), "\n";
echo strtotime("+1 day"), "\n";
echo strtotime("+1 week"), "\n";
echo strtotime("+1 week 2 days 4 hours 2 seconds"), "\n";
echo strtotime("next Thursday"), "\n";
echo strtotime("last Monday"), "\n";
```

#time
現在のUnixタイムスタンプを返す。

##例

```php5
print time();
```
動画をサイトに埋め込む時の注意

##動画を自動再生させたい

videoタグでの埋め込みの場合、以下のように設定します。

```
<video src="/img/video.mp4" poster="/img/video_poster.png" autoplay="" loop="" muted="" playsinline></video>
```
ポイントは、videoタグに次の属性を入れることです。

- autoplay（自動再生）
- loop（動画をループ再生）
- **muted（ミュートにする。これをしないと自動再生されないブラウザがあります）**
- **playsinline（インライン再生。これをしないとiPhoneで表示されません）**

参考サイト：
[videoタグのつまずき／スマホで再生されない/playsinlineの存在｜
umlaut.club](http://umlaut.club/web/video_tag)


##動画の読み込みを早くしたい

###videoタグ vs YouTube埋め込み
調べたところ、YouTubeの埋め込みで四苦八苦されている記事を発見。
YouTube埋め込みだと、

- 動画差し替え時にいちいちYouTubeにアップする必要がある。
- 外部からの読み込みなので、内部データよりも読み込みが遅くなる。

という理由で、videoタグの方を採用しました。

「どーーーーーしても、YouTubeを埋め込みしないとダメなんだ！」
という場合は、こちらのサイト様が参考になると思います。
→[埋め込みyoutubeが想像以上に戦犯級だった件｜ma-ya’s CREATE](https://myscreate.com/youtube-defer/)

###「ページ全体の読み込みを軽くする」のが大前提
とにかく読み込むデータを軽くする！！！
サイト制作において、これは避けては通れません。。。
最低限、以下のことはしておきたいです。

- 画像の遅延読み込み
- 画像をなるべく軽くする
- JavaScriptを最後の方に読み込む

###posterは設定するべし
posterを設定すると、
動画の読み込みが完了するまで、設定した画像を表示させておきます。
これがないと、動画の読み込みが完了するまで、何も表示されません。
（設定の仕方は上のコードを参照。）

###preloadは効果あるのか？
videoタグの属性にpreloadがありますが、
自分的にはあまり効果がなかったと思います。

###最終手段として、最初にローディングアニメーションを入れる

「動画が最初の方、静止画になっている」
とお客様からご指摘があったのですが、
これは、動画の読み込みに時間がかかっているので、
その間、posterの画像が表示されているのが原因です。

「ページ全体の読み込みを軽くする」のが大前提ですが、
トップページは特に、画像もJavaScriptも使って派手にするので、
どーーーしても重くなりがちです。

ごまかしになってしまいますが、
最初にローディングアニメーションを入れることで、
アニメーション終了後、おおよその要素が読み込み終わっているので、
有効な手段の一つと思っています。

ただ、**ローディングアニメーション終了後、
動画はすでに自動再生が始まっている**ので、
最初から再生はされないです。。。
そんなの気にしない場合にご使用ください。
HaskellでFunctorを使って簡単な複素数の足し算プログラム

#Haskellで簡単な複素数足し算プログラム

Functorをどーーしても自分で実装したくて、何か使い道がないかといろいろ考えました。
そして、複素数のプログラムを書くことにしました。が・・・、Functorの意図に沿っているかは分かりません。

##複素数足し算プログラム

```haskell:add.hs
data ComplexNumber n = Z n

instance Functor ComplexNumber where
    fmap func (Z n) = Z (func n)

main::IO()
main = do
    let a z = let a1 = (\(n,_,_,_) -> n) z
                  b1 = (\(_,n,_,_) -> n) z
                  a2 = (\(_,_,n,_) -> n) z
                  b2 = (\(_,_,_,n) -> n) z
              in
                  (a1 + a2 , b1 + b2)

    let b = fmap a

    let c = b (Z (1,2,3,4))

    let d = (\(Z n) -> n) c
    print d
```

`ComplexNumber`は、複素数を表しています。
`Z`は複素数であることを示します。

`main`関数の中身の`a`は、4組のタプルを2組のタプルにして返します。

`z1 = a1 + b1 i
z2 = a2 + b2 i
z = z1 + z2`

このような計算を想定し、`(a1,b1,a2,b2)`を受け取り`(a,b)`を返します。
[Android]他の人のアプリを盗み見しよう

業務上、競合他社アプリを~~盗み見~~参考にしたく、ソースコードを拝見させていただくことがたまーにあるので、備忘録として残す。

# 端末にインストール済みのAndroidアプリをダウンロード

```
# PC、デバイス間の接続ができているか確認
$ adb devices

# 対象のパッケージを検索
$ adb shell pm list packages -f | grep [ダウンロード対象のキーワード]
```

ダウンロード対象のキーワードは会社名やアプリの名前を入力すれば大抵引っかかる。

```
# 例
$ adb shell pm list packages -f | grep yamachita0109
package:/data/app/com.yamachita0109.voice-Q6HZbU2pgLu4T3FCQg74kg==/base.apk=com.yamachita0109.voice
```

標準出力された値を分解する。

|名|値|
|:-----------------|:------------------|
| APK保存先パス|/data/app/com.yamachita0109.voice-Q6HZbU2pgLu4T3FCQg74kg==/|
| APKファイル名 |base.apk|
| アプリケーションID|com.yamachita0109.voice|

ダウンロード。

```
# APK保存先パスを指定
$ adb pull [APK保存先パス]
```
```
# 例
$ adb pull /data/app/com.yamachita0109.voice-Q6HZbU2pgLu4T3FCQg74kg==/
/data/app/com.yamachita0109.voice-Q6HZbU2pgLu4T3FCQg74kg==/: 1 file pulled. 31.4 MB/s (9086342 bytes in 0.276s)

# APKファイルがダウンロードされている
$ ls com.yamachita0109.voice-Q6HZbU2pgLu4T3FCQg74kg\=\=/
base.apk	lib
```

# APKファイルをデコンパイルする
[jadx](https://github.com/skylot/jadx)を使用する。

```
git clone https://github.com/skylot/jadx.git
cd jadx
./gradlew dist
```
> JDK 8 or higher must be installed:

なので注意すること。

やっとデコンパイル。

```
# Pathを通してもOK
$ build/jadx/bin/jadx --log-level error [APKファイルパス]
```

APKファイル名でフォルダが作成される。
その中に、ソースコード類が入っているので、~~盗み見~~参考にすることができる。

# まとめ
> 「甘い！！ 武術の伝承とはすなわち模倣から始まるのだよ！」

史上最強の弟子ケンイチの登場人物、秋雨の名言である。

> 「すべての独創は模倣から始まる」

ジャパネットたかたの創業者、髙田明の名言である。
WSL 上で同一ディストリビューションの環境を複数インストール･管理する

Microsoft Storeから WSL 環境をインストールすると、１種類のディストリビューションは１個の環境としてしかインストールできない（と思う）。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546894/06edda99-02b9-9b3b-6a7c-2a37fc5e0abb.png)
だが同一ディストロの環境を気軽に複数作ったり壊したり消したり、使い捨てで使いたいこともあるだろう。ターミナルから簡単に環境を複製できるのでやり方を書いておく。

### 手順
WSL が入っているのは前提とする。まずターミナルで `wsl -l --verbose` を実行して、手元に存在する環境を確認する。

```
PS C:\Users\user01> wsl -l --verbose
  NAME                      STATE           VERSION
* Ubuntu-20.04              Running         2
  docker-desktop            Running         2
  docker-desktop-data       Running         2
```

例えばストアからインストールした Ubuntu-20.04 が入っていれば上記のように出力される。この、環境名 `Ubuntu-20.04` としてインストールされている Ubuntu を使い捨て用に複製してみることにする。

WSL のエクスポート機能で、環境を丸ごと tar ファイルとして出力できる。`wsl --export (エクスポートしたい WSL 環境名) (出力ファイル名)` を実行すればよい。

```
PS C:\Users\user01\export_distro> wsl --export Ubuntu-20.04 FocalFossa_copy.tar
```

これで元の `Ubuntu-20.04` の環境が tar ファイルとして出力されるので、あとはこれに別の環境名を付けてインポートすれば同一環境が得られる。`wsl --import (WSL 下に登録する環境名) (インストール先パス) (インポートする環境.tar)` を実行すればよい。

```
PS C:\Users\user01\export_distro> wsl --import FocalFossa_copy ..\wsl_manual_install\ FocalFossa_copy.tar
```

これで、指定した環境名で元の `Ubuntu-20.04` と同一の環境が複製された。

```
PS C:\Users\user01> wsl -l --verbose
  NAME                      STATE           VERSION
* Ubuntu-20.04              Running         2
  FocalFossa_copy           Stopped         2
  docker-desktop            Running         2
  docker-desktop-data       Running         2
```

ターミナルから `wsl -d (環境名)` と打ち込んで起動してもよいし、もしくは Windows Terminal のタイトルバーの `∨` ボタンから表示できる環境リストから選んで起動するなりすればよい。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546894/bdab7a9a-eff8-64f0-5387-2ad684a05a1b.png)

```
PS C:\Users\user01> wsl -l --verbose
  NAME                      STATE           VERSION
* Ubuntu-20.04              Running         2
  FocalFossa_copy           Running         2
  docker-desktop            Running         2
  docker-desktop-data       Running         2
```

無事、同一ディストロが別名環境として起動している。

なお、インポート時に指定したインストール先に環境の実体であるハードディスクイメージファイル `ext4.vhdx` が生成されているが、中身は `\\wsl$\` 下にマウントされているのでそちらからエクスプローラーでブラウジングすることができる。(※ 実体ファイルは常に `ext4.vhdx` というファイル名になるので、１つのディレクトリには１つのハードディスクイメージファイルしか作成できず、同じところに複数作ろうとすると `指定されたインストール場所は、既に使用されています。` と出て拒否られる。環境ごとにディレクトリを用意すること。)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546894/c23ccb3b-03b9-3f8a-be86-4213dd51ff45.png)
いらなくなった環境を削除したいときは、`wsl --unregister (登録名)` で削除できる。



わりと簡単に環境を複製･破壊･廃棄できるので、気兼ねなく遊んでみよう！
parcelでlint(eslint, prettier)をしてみた

そろそろソースコードのチェックをしてみようと思ってlintを。
で、使うのは[eslint](https://eslint.org/)と[prettier](https://prettier.io/)。

# インストール

- babel-eslint
- eslint
- eslint-plugin-vue
- eslint-config-prettier
- eslint-plugin-prettier
- prettier

```
$ npm install --save-dev babel-eslint eslint eslint-plugin-vue eslint-config-prettier eslint-plugin-prettier prettier
```

# 設定

## eslintの設定

[設定](https://eslint.org/docs/user-guide/configuring)

```js:.eslintrc.js
module.exports = {
  root: true,
  env: {
    browser: true,
    node: true,
  },
  parserOptions: {
    parser: 'babel-eslint',
  },
  extends: [
    'prettier',
    'prettier/vue',
    'plugin:prettier/recommended',
    'plugin:vue/base',
  ],
  plugins: ['prettier'],
  rules: {},
}
```

## prettierの設定

[オプション](https://prettier.io/docs/en/options.html)

- セミコロンはいらない
- 文字列はシングルクォーテーションで囲む

```.prettierrc
{
  "semi": false,
  "singleQuote": true
}
```

## package.jsonの設定

`scripts`に`lint`を追加する。

```json:package.json
{
  ...

  "scripts": {
    "lint": "eslint --ext .js --ignore-path .gitignore ."
  },

  ...
}
```

lintついでに直したい場合は`--fix`オプションを追加する。

```json:package.json
{
  ...

  "scripts": {
    "lint": "eslint --fix --ext .js --ignore-path .gitignore ."
  },

  ...
}
```

# 実行

```sh
$ npm run lint
```

エディタの設定でルール通りに書けると最高なんだろうなぁ。
ChromeDeveloperToolでshadow domを表示する方法

# 経緯

Seleniumで自動テストを作成する際、正しいElementを指定しても「Clickできない」「Sendkeyできない」状態になることがあります。
様々な原因がありますが、1つの原因として、shadow domが影響していることがあります。
自動テストを作成する際、常に表示しておいた方が便利なので、ChromeDevToolでshadow-domを表示する方法を記載します。

# 設定方法

* Chromeにて任意のサイトを開く
* （ChromeDevToolを開く）表示したページ画面内で右クリックし、検証を押す
* ChromeDevToolの右上にある設定アイコンを押す
![スクリーンショット 2020-07-01 16.48.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51235/b24b314e-bcba-c483-3c04-3b5e1a3b23d6.png)
* 「Show user agent shadow DOM」にチェックを入れる
![スクリーンショット 2020-07-01 16.51.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51235/f686b233-9f2f-e606-6628-13344a6c79a5.png)

* shadow-domが表示されるようになる![スクリーンショット 2020-07-01 16.48.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51235/fc87aa7b-58ce-7b4a-c716-5372e4aefb21.png)
Electronをセキュアな設定の状態で、jsのrequierを行う

# Electronの基本おさらい

Electronは、`メインプロセス`と、そこから読みだされwebページ画面として動く`レンダラープロセス`の2つの領域が存在します。
そのうち、表示を行うレンダラープロセスはセキュリティを厳しくすることが推奨されています。




# Electronのセキュリティ設定

Electronのドキュメント見ると推奨のセキュリティ設定が上げられています。
https://www.electronjs.org/docs/tutorial/security#reporting-security-issues


しかし、デフォルトとのセキュリティ要件だとレンダラー領域でrequierもできずnodeのライブラリを読めません。
もちろん、``require('electron')``もできないのでレンダラープロセスとメインプロセスとの通信もできません。


# requireを渡す

### preloadを経由することでrequireを渡すことができます

electronの仕様で、preload内でcontextBridgeを実行することでレンダリングプロセスのjsに紐づきます。
"windows.xx"のxxの部分に紐付けることができます。

### requireを使う例です。

```js:メインプロセス
const path = require("path");

//レンダラー読み出し部分
const mainWindow = new BrowserWindow({
  width: 800,
  height: 600,
  webPreferences: {
    preload: path.join(__dirname, 'preload.js'),//<--ファイルを指定。ここでは同一階層にあるpreload.js
    contextIsolation: true,//<--requireを渡すために必要な設定
  }
})
```

#### preload.jsの例

```js:preload.js
const { contextBridge, ipcRenderer} = require("electron")
const fs = require('fs')

contextBridge.exposeInMainWorld(
  "requires", {// <-- ここでつけた名前でひもづく。ここでは"window.requires"
    json5 : require("json5"),//npmで取得したライブラリを渡す時の例。レンダラーにそのまま渡す

    ipcRenderer : ipcRenderer,//ipcRendererも渡せるのでやり取りできる

    getSetting :  () => {// fsも読み込める。レンダリングプロセスにそのまま渡さず、functionにしてできることを制限したほうがセキュリアそう。。。
      const setting_path = 'c:/appSetting.json5';
      return fs.existsSync(setting_path) ? fs.readFileSync(setting_path, 'utf8') : '{}'
    }
  }
);
```

#### レンダリングプロセス側の読み出し

```js:レンダリングプロセス
const json5 = window.requires.json5;//requireしたライブラリを読み込み

let app_setting_text = window.requires.getSetting();//preload内のファンクション実行

let app_setting = json5.parse( app_setting_text );// 普通にrequireしたように使える
console.log( app_setting );
```


### まとめ

一工夫いるがElectronのセキュリティ設定を緩めずに、requiresを使用できました。
Ransackのsort_linkで孫テーブルの値でソートする

めちゃめちゃハマったので個人的なメモ。

親を表示してるけど中間テーブルを通して別テーブルの値を表示していて、その列をソートしたいとき

```
<%# 子テーブル名_孫テーブル名_属性名 %>
<%= sort_link(@q, :child_grandchild_name, '孫の名前') %>
```

でいける。
テーブル名に"_"が入ってても大丈夫。
【javascript】　テンプレートリテラル とは　一言で。

##【ゴール】
####テンプレートリテラルの理解

##【テンプレートリテラルとは、、、】
####定数や変数を楽して出力できる

**不使用の場合**
＊「+」を2回も。。面倒だな。。。

```js:hoge.js
const name = "太郎";

console.log("私の名前は" + name +"です"); //私の名前は太郎ですが出力
```


**使用した場合**

```js:hoge.js
const name = "太郎";

console.log(`私の名前は${name}です`); //私の名前は太郎ですが出力
```

##【具体的な使い方】


**①console.log()の括弧内を「``」（バッククォーテーション）で囲む**
　**※Macの方は「command + @」です**

**②変数や、定数で指定したものを${}で囲む**


以上。意外と使います。

##【合わせて読みたい】

■ 【Javascript】 メソッド　まとめ　基礎基本コード　メモ
https://qiita.com/tanaka-yu3/items/2438798d159fa402b1d5

■ 【Javascript】JS　変数　定数　違い 　一言でまとめました
https://qiita.com/tanaka-yu3/items/51b8b0630a1e4e2d52c8

■ 【JavaScript】 js　繰り返し文　for / while/ case
https://qiita.com/tanaka-yu3/items/942d9d4838ebe14be1c2
【Rails】リソースベースのルーティングを忘れていて無駄に苦労した件

大学でRuby on Railsを習いました。
せっかくなのでRuby on Railsを使ってTodoリストを作ってみようと思ったら、早速ルーティングで詰みました。
createのルーティングで詰んでました。

#環境
Rails v5.2.4.3
Ruby v2.5.1

#やりたかったこと
index.html.erbでform_forメソッドを使いcreateへデータを送信する。
index.html.erbに入力スペースを用意して、そのままデータを作れるようにしたかったんです。

```lists_controller.rb
def index
	@list = List.new()
end

def create
	@list = List.new(params[:list])
	if @list.save
		redirect_to({ action: :index }, notice: 'やることリストを追加しました')
	else
		ridirect_to({ action: :index }, notice: 'やることリストを追加できませんでした')
	end
end
```
```index.html.erb
<%= form_for @list, :url => { action: "create" } do |form| %>
	<table>
		<tr>
			<th><%= form.label :text, "内容" %></th>
			<td><%= form.text_field :text %></td>
		</tr>
		<tr>
			<th><%= form.label :deadline_at, "締め切り" %></th>
			<td><%= form.datetime_field :deadline_at %></td>
		</tr>
	</table>
	<%= form.submit %>
<% end %>
```
```routes.rb
root "lists#index"
post "lists"
```

まあ、結論から言うとエラーが出たんです。

```
controller key on routes definition, please check your routes.
```

検索しても検索しても、「rootのルーティングを『〇〇/index』にしているので『〇〇#index』にしてください！」みたいなのしかでてこん。
そこはやってたんよ。

なんか、create用のルーティングにcontrollerとactionを書いてあげたら動くようになりました。

```routes.rb
post "lists", controller: "lists", action: "create"
```

#とここまで長々とお話ししましたが
気がついたんです。
リソースベースのルーティングってなんかなかったっけ、、、
授業内でcreateのルーティング書いたっけ、、、

はい。

```routes.rb
resources :lists
```

これひとつ書けば、ListsControllerに対して`index`、`new`、`create`、`show`、`edit`、`update`、`destroy`のアクションのルーティングが設定できるんですよね！！
もう完全に忘れていました！！！
と言うか授業で教わったときには意味が全然わかってなくて、今回やっと理解できたと言う感じでしたね、、、復習頑張ります。

この場面ではrootで設定しているindex以外ではcreateしか使っていないので、

```routes.rb
root "lists#index"
resources :lists, :only => :create
```

でも問題なく動作しました。
しかし、これからいろいろ機能をつけていく予定なのでcreate以外も使えるようにしておきます。

はい。
お疲れ様でした！！！
AWS EC2入門 #3: AWSのセキュリティグループを変更しよう

![aws.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/665011/be604793-7e01-b258-924a-166f03acbc5c.png)
現時点では、インスタンスに発行されたパブリックIPをブラウザで見ようとすると、下の画面のようになってしまいます。
![img1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/665011/7adfdeaf-a21c-c87d-9530-f6176d532375.png)
これを解決するために、今回はセキュリティグループを変更していきます。

#セキュリティグループを変更する

①EC2ダッシュボードに「セキュリティグループ」があるので選択する
![img2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/665011/0ef39bb6-86e3-f14a-035d-3608f2b43131.png)

②インスタンスを指定し、「インバウンドルールを編集」をクリックする
![img3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/665011/c02c1c64-2685-352c-f1fd-5941e646626c.png)

③「ルールを追加」をクリックした後、下の画面の通りに編集し、右下の「ルールを保存」をクリックする
![img4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/665011/cbeba7c6-a39b-4828-b51d-2b37fb8b1e58.png)

④ここで、Webサーバーソフトをインストールします（ここではApacheを入れていますが、Nginxでもいいです）

```
$ sudo yum install httpd
```
と打てば、Apacheをインストールできます。
![img5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/665011/a3113472-3af5-ef10-c604-f9cd659159a7.png)
上の画像のように表示されれば、インストールは完了です。

⑤Apacheを起動します

```
$ sudo systemctl start httpd
```
![img6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/665011/1688e346-39cf-b060-03b5-7bb40568cbad.png)
特に反応はありませんが、これで起動はできています。

⑥ここで再度、パブリックIPをブラウザで見てみると、
![img7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/665011/044d18a8-9430-80fe-a149-8843f764fccc.png)
Apacheのスタートページが表示されました。

#次回

今のままではインスタンスを終了して再度起動したときにIPアドレスが変更されてしまいます。そこで、次回はElastic IPを使って固定IPを取得します。

[AWS EC2入門 #4: 固定IPを取得しよう](https://qiita.com/takahashitakuya031126/items/21e72b57a613d53f9986)
goland 設定go ModulesのEnable Vendoring Support automaticllyを外さないと

###問題###
JetBrain goland中に
テストコードを実行する時に以下のエラーが発生されました。

```
./somefile.go:3:8: cannot find package "." in:
	/project/vendor/somepackage
```

パッケージ先がgo moduleに指定されたあるはずですが、vendorに指定されて、vendorにパーケージがないから、見つからないエラーが発生されます。

###解決法###
設定
->go
->go Modules
->Enable Vendoring Support automaticllyを外したら、正常に戻ります。

<img width="1109" alt="スクリーンショット 2020-07-01 16.03.26.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191439/6a5fdeb5-0f3f-f47e-2e00-eb2e78eda21a.png">
php データベースからデータ読み込み

#概要
phpでデータベースからデータを読み込みする記述

※個人学習用メモ・記録





```php:sql.php
<?php

    //ここでsqlデータベースやユーザー名、ローカルホストもろもろ取得してるのかな。。
    $pdo = new PDO('mysql:host=localhost; dbname=mydb; charset=utf8','root','');
    
    //ここでsql文を叩く
    $sql = 'SELECT * FROM jobs'; 
    $statement = $pdo->prepare($sql);
    $statement->execute();    // => sqlを実行している

    //ここで配列にsqlを押し込んでる
    $results = [];
    while ($row = $statement->fetch(PDO::FETCH_ASSOC)) {
        $results[] = $row;
    }

    $statement = null;
    $pdo = null;

    $message = 'hello world';
    require_once 'views/content.tpl.php';

```

```php:content.tpl.php
<!DOCTYPE html>
<html lang='ja'>
    <?php include('header.inc.php'); ?>
    <body>

        <h1><?= $message ?></h1>

        <?php foreach ($results as $player) { ?>
            <p><?php print_r($player); ?></p>
        <?php } ?>

        <?php include('footer.inc.php'); ?>
    </body>
</html>
```
reg-suitを使ってみた( CI使わないver)

[reg-suitでVisual Regression Testしてみた](https://qiita.com/takahigu642/items/ff1295a6778f55610fb8
)
↑のCI使わないver

# CIを使わない理由
CI/CDを使うと、コードの変更が発生するたびに自動でテストが行われるので、テストの実行忘れや、環境依存のテストを失くすことでの品質を向上させることができる。
ただ今回はコード修正などのPR毎ではなくて、リリース時など大きなイベントが起こった際にUIのデグレを無くすために、ローカル環境でreg-suitを用いてビジュアルリグレッションテストを実行し、メンテナンスを行うことを想定した。


# 使用したリポジトリ

[Add avatar by takahigu322 · Pull Request #2 · takahigu322/reg-suit-demo3](https://github.com/takahigu322/reg-suit-demo3/pull/2)

# 使うもの

- [reg-suit](https://github.com/reg-viz/reg-suit): Command line interface to visual regression testing. It only compares pictures, so we should prepare the pictures to test.
- [Puppeteer](https://github.com/GoogleChrome/puppeteer): Node.js library which provides a high-level API to control headless Chrome over the DevTools Protocol. We capture screenshot picture from out HTML using this.
- [AWS S3](https://aws.amazon.com/s3/?nc2=h_m1): We use a S3 bucket to put snapshot images and HTML reports

[参考にしたリポジトリ](https://github.com/reg-viz/reg-puppeteer-demo)

# 自動視覚的スナップショットテストを導入する方法

1. プロジェクトを作る

    ```jsx
    mkdir reg-puppeteer-demo
    cd reg-puppeteer-demo
    git init
    npm init
    ```

2. スクリーンショットをキャプチャするためのスクリプトを作成する&CSSを適用しスクショ

    ```jsx
    npm install -D puppeteer mkdirp
    yarn add semantic-ui-css 
    ```

    ```jsx
    node capture.js
    ```

3. AWS認証情報を準備する

    後のステップでS3にアクセスするには、AWSアカウントが必要です。 AWSアクセスキーを取得して構成します（IAMユーザーのアクセスキーの管理もご覧ください）。

    ```jsx
    export AWS_ACCESS_KEY_ID=<your-access-key>
    export AWS_SECRET_ACCESS_KEY=<your-secret-key>
    ```

4. reg-suitを構成する

    ```jsx
    npm install -D reg-suit
    ```

    インストール後、以下を介してreg-suitの初期化サブコマンドを実行します。

    ```jsx
    npx reg-suit init
    ```


    reg-keygen-git-hash-plugin

    reg-notify-github-plugin

    reg-publish-s3-plugin

    reg-notify-slack-plugin

    今回は上記をinstall

    必要なのはGithubのClientIDとSlackのwebhokkURL
ここまでの変更をコミットする

    ```jsx
    # .gitignore

    node_modules/
    /screenshot/
    .reg/
    ```

    ```jsx
    git add .
    git commit -m "first commit"
    ```

    npx reg-suit runを使用して視覚回帰テストを実行する

    [Comparison Report - REG](https://reg-publish-bucket-668262e3-8df2-437c-b104-714c56988a0c.s3.amazonaws.com/defa6d4169d2786ec0a53a76c1b45e0588b2291c/index.html)

    別ブランチに入れてみる

    ```jsx
    git checkout -b add-avatar
    ```

    GitHubリポジトリでプルリクエストをコミット、プッシュ、PRオープンします。

    その後reg-suit実行

    ```jsx
    npx reg-suit run
    ```

    するとPRにbotが走る
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/528657/a3110d79-53c5-2ac7-f6b5-549a270a83ca.png)



これでローカル環境のみでreg-suitを実行しビジュアルリグレッションテストが可能になった。
C#でマルチスレッド

# マルチスレッドをC#で実装してみよう
スレッドｋとはプログラムを実行する処理の最小単位です。
アプリはメインスレッドといわれる単一のスレッド(シングルスレッド)で動作しています。

Mainスレッドで始まるスレッドがそうです。

シングルスレッドでは、通信が終わるまで他の操作はできません。

そこで出てくるのがマルチスレッドというものです。
マルチスレッドを利用することで、ネットワーク通信のように時間のかかる処理はバックグラウンドで実施し、アプリ利用者はメインスレッド上で操作を継続で気できるようになります。

ちなみに、スレッドと同じく処理単位を表す概念として、プロセスもあります。
相互の関係としては、一つのプロセスに対して、一つ以上のスレッドが属するという関係です。

プロセスはいわゆるプログラムのインスタンスそのものであり、新たなプロセスの動作にはCPUとメモリの割り当てが必要になります。その性質上、独立したメモリ空間を必要としない状況ではメモリの消費効率がよくありません。

それに対して、スレッドとはメモリ空間を共有しながら、処理だけを分離する仕組みともいえるため、その性質上メモリの消費効率は良くなりますが、反面。スレッド間でデータを共有している場合に、同時アクセス(競合)を意識しなければなりません。

新たなスレッドを生成するクラシカルな方法として、まずThreadクラスを地用することです。
しかし、後から述べる理由から現在は利用すべきではありません。

あくまで、原始的なスレッド生成実行の方法です。

```cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace MultiThread
{
    class Program
    {
        static void Main(string[] args)
        {
            var t1 = new Thread(Count);
            var t2 = new Thread(Count);
            var t3 = new Thread(Count);

            t1.Start(1);
            t2.Start(2);
            t3.Start(3);

            t1.Join();
            t2.Join();
            t3.Join();

            Console.WriteLine("すべての処理が完了しました");
        }

        static void Count(object n)
        {
            for (int i = 0;i < 50; i++)
            {
                Console.WriteLine($"Thread{n}:{i}");
            }
        }
    }
}


```

スレッドの生成実行はプロセスに比べればオーバーヘッドの小さな処理です。
しかし、通常の命令に比べると十分に重たい処理であり、スレッドの生成破棄を繰り返すことはアプリ全体のパフォーマンスを劣化させます。

そこで、いったん生成したスレッドを破棄せずに保持しておいて、別な処理で再利用する仕組みが導入されました。
それがスレッドプールです。

スレッドプールを利用することで、スレッドを大量に利用するようなアプリでもスレッドの生成破棄のオーバーヘッドを軽減できます。


```cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace MultiThread
{
    class Program
    {
        static void Main(string[] args)
        {
            Task t1 = Task.Run(() => Count(1));
            Task t2 = Task.Run(() => Count(2));
            Task t3 = Task.Run(() => Count(3));

            t1.Wait();
            t2.Wait();
            t3.Wait();


            Console.WriteLine("すべての処理が完了しました");
        }

        static void Count(object n)
        {
            for (int i = 0;i < 50; i++)
            {
                Console.WriteLine($"Thread{n}:{i}");
            }
        }
    }
}

```
OCIのFree Tier枠でデモ環境を作成する

# Free Tier枠のATPを使ってデモ環境を作成する
OCIのWEBコンソール上でも紹介されているMuShop Basicの作成を試してみた。
作成手順自体は資材のDLを行うGithubのReadMeにも記載されているが、
今後のために画面コピーなども交えて分かりやすく(したつもり)。

## 1.資材のダウンロード
[こちらのGithub](https://github.com/oracle-quickstart/oci-cloudnative#Getting-Started-with-MuShop-Basic)から下記スクショの赤枠のファイル「mushop-basic-stack-v1.1.0.zip」をDLする。
基本的にはこのGitに記載の手順でやれば問題はない…。

<img width="678" alt="01.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/195257/3a75d337-746b-eb5e-28d5-5033eaff823a.png">


## 2.構成
構成されるデモ環境のシステム構成は以下の通り。

![06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/195257/7ad6e648-c43b-5444-2df4-60a3816ffbd7.png)

### 手順1
下記スクショの様にOCIコンソールにログインしてホーム画面から「リソース・マネージャ > スタック」を辿り、
スタックの画面で[スタックの作成]を押下する。

<img width="1104" alt="02.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/195257/2c3c321b-37fe-ae53-69e3-74fbf424e349.png">


### 手順2 
「マイ構成」にチェックが入っていることを確認して、「.zipファイルをここにドロップします」の部分に
「mushop-basic-stack-v1.1.0.zip」をドラッグアンドドロップする。
名前は自動で入力されるが説明は入力されないので、必要があれば入力する。
コンパートメントを変更する場合は変更して、[次へ]を押下する。

### 手順3
General Configuration に以下設定がされていることを確認。

* DATABASE NAME：mushop(好きにしてもいいっぽい)
* NODE COUNT：2

※SSHでインスタンスにログインする場合は、公開SSHキーを入力して[次]を押下。

### 手順4
構成する情報に問題がないことを確認して[作成]を押下。
画面遷移して、下記のような画面になった後、「Terraformアクション > 適用」を押下。
適用のポップアップが出てくるが、そのまま[適用]を押下。

<img width="1127" alt="03.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/195257/193c7def-c9c5-7d01-c47d-730f5da58371.png">


### 手順5
成功するとアイコンが元の緑色になり、アイコンの下に「成功」と表示されるので、
画面を下にスクロールして、ログの一番最後に表示されているログイン情報を記録する。
尚、この際に構成するFree Tierの数が足りない場合はエラーになるっぽい・
(自環境で試した際に、VCNの数が引っかかって一度失敗した…)

<img width="1128" alt="04.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/195257/78f1fd63-734d-cac7-af13-2161bf23ba07.png">
<img width="1127" alt="05.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/195257/a7eb7c16-7cec-486b-a151-75603fd8cebb.png">


```
Apply complete! Resources: 19 added, 0 changed, 7 destroyed.

Outputs:

autonomous_database_password = <PASSWORD>
comments = The application URL will be unavailable for a few minutes after provisioning, while the application is configured
dev = Made with ❤ by Oracle A-Team
lb_public_url = http://111.111.111.11
```

※autonomous_database_password は、作成したATPにログインするためのパスワード。
　lb_public_url は作成されたデモ環境のURL。

また、上記で「lb_public_url」で指定されているURLにアクセスすると、作成したデモ環境(MuShopのサイト)にアクセスできる。

### 3.デモ環境の確認
### 手順１
「ホーム > Autonomous Transaction Processing」から作成したAutonomous Database(ATP)が確認できる。
同じ要領でコンピュートや仮想クラウドネットワーク(VCN)も確認しておく。
尚、ATPやコンピュートについては為念でAlways Free と表示されていることを確認しておく(されていない場合は多分課金されるので…)。

### 手順2
「ホーム > Autonomous Transaction Processing > 作成されたインスタンス名」で作成したデモ環境を開き、
「[ツール]タブ > SQL Developer Web」を押下後、遷移したログイン画面で以下を入力する。

* ユーザー名：admin
* パスワード：autonomous_database_password の値

### 手順3
[ワークシート]タブにてCATALOGUE_USERの持つテーブルを確認して、好きなテーブルに検索を実施すれば、
デモ用のテーブルのデータを確認することができる。

```
select table_name from dba_tables where owner='CATALOGUE_USER';
select * from catalogue_user.products;
```

---

データを追加したりした場合にどうなるのか、とかも気が向いたら試してみようかな。
プログラマー心得

# 何を学ぶのか
### 偶発的プログラミング
あるコードから始めて、そのあちこちに少しずつコードを書き加えていくやり方

Webサイトからコピーしてきたサンプルプログラムで、うまく動作しているように見えるので、少し変更を加えて自分が必要とするプログラムに近づける。
自分が何をしているのか本当にはわかってないけれど、ほぼ自分のニーズに合ったプログラムになるまでいじり続ける。
ところが、そのプログラムが本質的にどのように動いているのかわからないので、新しい機能を加えるたびにプログラムが崩壊する危険が高まっていく。
まるでトランプの城のように。

ソフトウェア開発者として、偶発的プログラミングがまずいのは明らかだろう。

### それと同じことがキャリア選択でも起こっている

キャリアを左右する大事な選択についても同じように考えると？
事実上、開発者のほとんどは、偶発的キャリア選択をしてしまっている。

どのテクノロジに投資すべきか？どの分野で専門技術を磨くべきか？知識を広げるべきか？深めるべきか？

こうした問題を自分自身に問うべきだとも思います。

### リスクと見返りのトレードオフは、投資すべきテクノロジとビジネスの選択でも重要な役割を演じる。

15年前なら、COBOLプログラミングを学ぶのはとてもリスクが低い選択だっただろう。もちろん、COBOLプログラマは大勢いたので、当時のCOBOLプログラマの平均的な給料はそれほど高くなかった。仕事を見つけるのは簡単でも、あまり金にならなかったのだ。つまり、リスクは小さく見返りも小さい。それに対し、当時まだ目新しかったJavaに取り組もうと心に決めていたら、仕事を見つけるのは難しかったかもしれない。当時、Javaが主流の言語になるかもしれないなんて、誰が予想しただろう？

でも当時の業界の様子をよく見ていれば、、Javaに何か特別なものを感じたかもしれない。ことによると、そのうち大化けしそうな予感がしたかもしれない。Javaに早々と投資していれば、やがて来るテクノロジの大潮流を率先することになっていただろう。

もちろん、今になってみれば、それは正しい選択だった。当時Javaというカードを正しく切っていれば、とても儲かる投資だったといえる。つまり、リスクが大きく見返りも大きい。

もちろん、ハイリスクなので失敗する可能性も大いに考慮すべきではある

世界中の生産現場で必ずと言っていいほど使われている安定したテクノロジを選択するのは、まだ誰も注目していない斬新なテクノロジよりも安全だ。しかし、それほどの見返りは期待できない。それじゃあ、行きつくところまで到達してしまったテクノロジの場合はどうだろう。寿命が尽きるのを待っているだけのテクノロジならどうだろうか。

今すぐ始めよう！
1.現在の市場におけるテクノロジの年齢を若年、中年、老年に分類し、表にまとめてみよう。それらを紙の上に左から右へとマップしてほしい。左側に最先端にテクノロジが、右側に衰退しつつあるテクノロジが並ぶ。できるだけたくさんのテクノロジを挙げよう。採用曲線の上に並べたときに、できるだけ同じ位置に重複するテクノロジがないようにしてほしい。考えつく限りのテクノロジを採用曲線にマップしたら、自分自身がよく知っていると思うテクノロジに印を付ける。それから、いくらか経験があるという程度のテクノロジに別の色で印を付ける。印を付けたテクノロジは採用曲線のどのあたりに多く存在するだろう？塊になっているだろうか？均等に分散しているだろうか？両端付近に、特に関心を持っているテクノロジはあるだろうか？

# コーディングはもう武器にならない
どんなテクノロジに投資するか考えるだけでは不十分。
コーディングはできて当然。
テクノロジは、究極的にはお金で手に入るものだから。

ビジネスの雑事をビジネス屋に任せて悠長にプログラミング言語やOSの勉強をしている場合じゃない。
ただのコーディングロボが必要なら、その種の仕事をする人間を他所の国から雇えばいい。重要な人材であり続けたいなら、自分が従事しているビジネスの分野にもっと首を突っ込まなければ。

自分のポートフォリオを充実させる上自分の時間をどんなビジネスに投資するか、今こそ考えようで重要なのは、ビジネスの分野を注意して選択することだ。つまり、どんな企業と業界で働くことを選ぶかが、投資における大きな問題になる。投資するビジネスの分野をまだ本気で考えていないなら、今こそ考えよう。
ファクトリーメソッド　C#

#C#でファクトリーパターンを実装してみよう

具体的なクラスを作成するときにnewというキーワードを用いると思います。

```java:qiita.java
Duck duck = new MallarDuck();
```

具体的なクラスを用いると脆く崩れやすくなる、そして、柔軟性にかけるものになってしまいます。

例えば、関連性のある具体的なクラスを用いてこのようにコードを書いたとします。

```java:qiita.java
Duck duck;
if(picnic){
   duck = new MallarDuck();
}else if(hanting){
   duck = new DecoyDuck();
}else if(inBathTab){
   duck = new RubberDuck();
}
```
スクラム開発でメンバのスキルレベルに差がある問題についての調査メモ

スクラム開発初心者で、これから始まるプロジェクトで初めてスクラム開発を導入しようとしています。
スクラムの考え方では、「開発メンバに上下関係がない」「タスクを誰でも取れる」が理想的とされていますが、開発メンバ内でスキルレベルに大きな差がある場合に、「タスクの工数見積もり」や「スキルの足りないメンバの自立」をどのように考えるべきか疑問に思ったため、調査した結果をメモしました。

##スクラムの課題の１つ
なんちゃってスクラム開発
https://qiita.com/kazukichi/items/1db417fe09d30c65506b
>3.3.チームのスキルレベルがバラバラすぎると辛い
スクラム開発では、ビジネス要件をもとにみんなで細かいタスクに落とし込んでいく。
タスクには、何時間でこなせるか工数見積もりをつけるが、これがスキルレベルに差がありすぎると辛い。
なぜなら、タスクは誰でも取れるのが理想だからだ。

>スクラムでは生産性を上げるためにも「自立や向上」を目指している。
そのためには、属人化を出来るだけ排除する必要がある。
属人化を排除するためには技術的な部分でも「透明性」が不可欠だ。
（１つの要件に１人が対応するパターンだと、その機能がその人しか分からないということになるし、その人がやった方が早く終るので結局属人化していく）

>それなのに１時間で終わる人もいれば８時間かかる人もいるとなると辛くなる。
そうなるとフラットにしていくまでにかなり時間がかかる。

チームのスキルレベルがばらばらだと、タスクの工数見積もりなどが難しくなるのは、スクラムのそもそもの課題の1つとして考えられているそうです。

##課題への対処
この課題に対する考え方として、以下の記事がとても参考になりました。

チームにスキルが足りない!? その時どうする?
https://www.ryuzee.com/contents/blog/7069

###必要なアクション
※多少、主観で解釈してまとめている部分があります。

①メンバのスキルマップを作り、チームに足りないスキルを可視化する
>スキルマップを作ることで、「スキルの見える化」「リスクの見える化」「学習速度の向上」が期待できます。

関連記事：スキルマップ作成のすすめ
https://www.ryuzee.com/contents/blog/7065

②足りないスキルが、開発を進める上で致命的となるかを確認する（チームに必要なスキルが足りず期日を守れない可能性が高い、スキルの足りないメンバが多くサポートや教育に多くの時間が必要、など）

　→●致命的な場合は、「必要なスキルが何かで代替可能ならそちらを使う」「人を入れ替える」「期間を延ばす」などの対処が必要

　→○致命的でない場合は、リスクを受け入れ、スキルの足りないメンバによる課題（タスク消化に見積もりよりも大幅に時間がかかっている、サポートしているメンバが自分のタスクを消化できない、など？）が発生した場合は、振り返りや、スプリントごとの成果を見て判断しながら改善していく
Mac の sed でファイルの先頭に文字列を挿入する

Mac の sed（BSD sed）でファイルの先頭に文字列（行）を挿入する

注：ファイルを上書きします

```sh
$ sed -i '' -e $'1s/^/挿入する文字列\\\n/' ファイル
```

ググり方が悪いのか、Linux の GNU sed の情報ばかりで一発で出てこなかったので。

# 関連記事

- [sedでcsvの先頭行にカラム名を追加する（Mac編）](https://qiita.com/zaburo/items/f3a86c80b33db513c847)
ミドルウェアの概念を得るためにWeb/AP/DBサーバから考えてみた

#はじめに
インフラまわりの知識はほぼないけど（そもそもひよっこだし）、これからアサインされる案件でインフラ寄りのこともさわることになりそうで不安。。。
ということで、ミドルウェアについて調べてみた備忘録です。
※初心者、初学者向けの内容ですのでご了承ください。
# ミドルウェアとは？
>ミドルウェア（英: Middleware）は、コンピュータの分野で、コンピュータの基本的な制御を行うオペレーティングシステム(OS)と、各業務処理を行うアプリケーションソフトウェアとの中間に入るソフトウェアのこと。
※wikipedia

エンジニアひよっこあるある、定義を調べても概念ばかりでイメージができない。
というわけでまずは具体的にイメージしやすいものを調べてみて理解を深めようと思います。

## Web・AP・DBサーバの役割
よく聞くやつ、だけど、結局何をする役割なんだろうかと。
（最近までWEB系の案件やってたのに知りませんでした、恥ずべき行為）
なので、手始めにここから見てみようと思った次第です。

**Webサーバ**
・クライアントからのリクエストをもらってレスポンスを返すよ
・静的なコンテンツなら持ってるよ
・動的なコンテンツはAPサーバに任せるよ
**APサーバ**
・Webサーバからの依頼で動的なコンテンツをつくるよ、作ったらWebサーバに投げるよ
・DBの情報が欲しいときはDBサーバに任せるよ
・具体的な処理はJavaやPHPで書かれるよ
**DBサーバ**
・APサーバからの依頼でDBを操作するよ
・結果をAPサーバに投げるよ

クライアントとのやりとりはWebサーバが全部やって、
別途処理が必要な場合は他のサーバに投げるということね。なんとなく理解した。

##本題のミドルウェア
3つのサーバにおいては以下が有名どころのようです。
**・Webサーバ：Apache
・APサーバ：Tomcat
・DBサーバ：MySQL、Oracle**
さすがに名前は聞いたことあったよかった（）
（ただ、サーブレットとかの記事見てても、なんでApacheとTomcatの2つ必要なの？？？って思ってたからようやく理解）

そしてミドルウェアの役割は、
**・アプリケーションを使いたい人が使いやすいような機能を提供すること
・OSのやハードウェアの違いを吸収して使えるようにすること**
が主なようです。
アプリケーション（やりたいこと）に共通の機能は、パッケージにしておいたほうがみんな楽だよね！という認識で落ち着きました。
なるほど、縁の下の力持ち的なポジションですね。
上記のほかにも、ジョブ運用やシステム監視などの役割をするシステム運用ミドルウェアもあるみたいです。