OmniAICreator/Qiita-1.07M huggingface dataset:
logを確認しながらrakeタスクを実装して、対象appを指定して起動しよう（Heroku）

こんにちは、株式会社ベストティーチャーでサーバーサイドエンジニアとして働き出したばかりのタワラです。

業務ではじめて学んだTipsを紹介したいと思います。
今回は**rakeタスクを作成してHerokuで動作確認をする手順**です。

## Rakeタスクを実装する手順
###Tips１. ローカルでRakeタスクを作成する際には、Rails.loggerを活用する

こんな感じでコードを書いていたのですが、、、キャッシュを問い合わせるだけだから、これではログに何の情報も出ないな、動作確認はどうしよう、、、と思っているところ、、、

```ruby
 namespace :hogehoge do
   desc "適当な説明をいれる"
   task :foobar => :environment do
     Rails.cache.fetch('hoge')
   end
 end
```
先輩「Rails.loggerを使うんだ！」
ボク「なるほど！」

```ruby
 namespace :hogehoge do
   desc "適当な説明をいれる"
   task :foobar => :environment do
     Rails.logger.info('foobar started!')
     Rails.cache.fetch('hoge')
     Rails.logger.info('foobar finished!')
   end
 end
```

このように記述しておけば、例えばログに結果が出ない場合の処理でも、rakeタスクの作業確認ができます。こんなふうに↓

```log/development.log
略

foobar started!
foobar finished!

略
```
きちんと動作していることが一目瞭然なのですごい便利！

### Tips２. Heroku上で確認するときはアプリ名を指定する

続いて、Heroku上で動作確認をする必要があります、↓のコマンドでrakeタスクを走らせることはできますが、、、

```
heroku run rake hogehoge:foobar 
```
先輩「ちょっとお待ち！」
先輩「オプションでプロジェクト名を指定するのを忘れないで！」

```
heroku run rake hogehoge:foobar -a omosiro-project
```
先輩「きちんとrakeタスクを起動する対象のプロジェクトなのかを確認しよう！」
先輩「こういうことでバグが起きる可能性はゼロじゃないからね」
ボク「なるほど！」

## 終わりに

今回のTipsはこの２つ！

**Tips１. ローカルでRakeタスクを作成する際には、Rails.loggerを活用する**
**Tips２. Heroku上で確認するときはアプリ名を指定する**

業務ではやはり学ぶことが多いです。
本記事が業務駆け出しの方などの役に立てば幸いです。
golangでnet.ConnのRead・Writeをcontextでcancel可能にする方法


##モチベーション
ソケットから読もうとするとブロックする可能性があるので、
それをcontextでキャンセルできる様にしたい。

可能なら以下の様なコードが書きたいが、それはできないので、代替案をメモ

~~~go
select {
case size, err := conn.Read():
// 略
case <-ctx.Done():
//略
}
~~~


## 解決策
こんな感じでSetDeadlineを使うと良い。
なお、デッドラインの設定時間により、`ctx.Done()` への応答時間が伸びたりするが、
Readへの応答時間要求に比べてctx.Done()への応答時間要求はかなりゆるい場合が多いと思うので問題になることは少ないはず。

```go

continue_read := true
for continue_read {
    err := conn.SetReadDeadline(time.Now().Add(time.Millisecond * 500))
    if err != nil {
        return err
    }

    size, err := conn.Read(buf)
    switch {
    case err == nil || os.IsTimeout(err):
        continue_read = true  // Do nothing
    case errors.Is(err, io.EOF):
        continue_read = false
    default:
        return err
    }

    // bufの操作等を書く


    select {
    case <-ctx.Done():
        return ctx.Err()
    default:
    }
}

```

うーん、一応問題は解決したものの、あんまり綺麗じゃないので何とかしたい。
Material UIでラジオボタンをクリックしても選択されない

#問題
``` JSX
{JSON.WorkSheets.map((v, i) => (
   <FormControlLabel
     key={v.ID}
     //type int
     value={v.ID}
     control={<Radio />}
     label={v.Text}
   />
))}
```
JSON内のWorkSheetsという配列をmapで回して動的にラジオボタンを作っている感じですね。
しかし、これだとラジオボタンを選択しても実際に選択されることはありません。

#解決方法
``` JSX
{JSON.WorkSheets.map((v, i) => (
   <FormControlLabel
     key={v.ID}
     //int to string
     value={v.ID.toString()}
     control={<Radio />}
     label={v.Text}
   />
))}
```
stringでないといけませんね。
Mysqlとの接続設定のメモ

#DBとの接続設定中
先にDB側で作っておく
　・DB名
　・DBユーザ
　・DBユーザパス
　・インスタンス接続名
　・ソケットパス　インスタンス接続名＋あれ

まだ接続できてないけど！

なんか呼び出すごとにコネクション情報を作ろうとしているので、
先に設定は保存しておくでよいな。

[参考ページ GCP](https://cloud.google.com/sql/docs/mysql/connect-functions#public-ip-default)
[参考ページ　Qiita先人たちの教え](https://qiita.com/ryu1_f/items/9ff4c88ac335eee368c1)
Unity+WebGL+WebSocketをやる時はNativeWebSocketを使おう

# 前置き
タイトル出落ちですが、日本語情報が皆無だったので。

# 配布先
NativeWebSocket
https://github.com/endel/NativeWebSocket

# 動作環境
- 対象バージョン：Unity2019以上
- .NET4.x 対応必須（PlayerSettings > Other Settings > API compatiblity Level）

# 特徴
- System.Net.WebSockets を使用するため外部ライブラリ非使用
- WebGL/HTML5サポート
- 主要なプラットフォームに対応
- シンプルなAPI
- ライセンスはApache 2.0（[wikipedia](https://ja.wikipedia.org/wiki/Apache_License)）

#個人的な感想
特殊な事情がなければ、こいつだけでもう良いんじゃないかな。
割当問題に対するハンガリー法と汎用ソルバーの比較

## これなに

「[割り当て問題とハンガリー法と整数計画問題と](https://qiita.com/___monta___/items/8da13f2204b275fa705b)」で汎用ソルバーが遅いという記事がありました。
この記事では、コードを少し直して「数理モデルを作成して汎用ソルバーで解く」方が高速であることを紹介します。

## Pythonのコード

コードは以下になります。実行には`pip install numpy pulp munkres`が必要です。

```py
import random
import time

import numpy as np
from munkres import Munkres
from pulp import PULP_CBC_CMD, LpProblem, LpVariable, lpDot, lpSum, value


class AssigmentProblem:
    def __init__(self, size, seed=0):
        self.size = size
        random.seed(seed)
        rng = range(self.size)
        self.weight = np.array([[random.randint(1, 100) for i in rng] for j in rng])

    def solve_hungarian(self):
        start_tm = time.time()
        m = Munkres()
        result = m.compute(self.weight.tolist())
        val = sum([self.weight[i, j] for i, j in result])
        tm = time.time() - start_tm
        print(f"hungarian {tm = :.2f} {val = }")

    def solve_pulp(self):
        m = LpProblem("AssignmentProblem")
        rng = range(self.size)
        x = np.array(LpVariable.matrix('x', (rng, rng), cat='Binary'))
        m += lpDot(self.weight.flatten(), x.flatten())
        start_tm = time.time()
        for i in rng:
            m += lpSum(x[i]) == 1
            m += lpSum(x[:, i]) == 1
        m.solve(PULP_CBC_CMD(mip=False, msg=False))
        val = value(m.objective)
        tm = time.time() - start_tm
        print(f"pulp      {tm = :.2f} {val = }")


if __name__ == "__main__":
    p1 = AssigmentProblem(300)
    p1.solve_hungarian()
    p1.solve_pulp()
```

### 実行結果
※ `tm`：計算時間（秒）、`val`：目的関数値
※ 上段がハンガリー法、下段が汎用ソルバー

```
hungarian tm = 2.43 val = 352
pulp      tm = 1.94 val = 352.0
```

このように、汎用ソルバーの方が速くなりました。

※ 上記の下段の時間は、数理モデル作成と汎用ソルバー実行の両方を含んでいます。
※ 数理モデル作成はPuLPというモデラーを使い、汎用ソルバー実行はcbcというソルバーを使っています。

参考：[最適化におけるPython](https://qiita.com/SaitoTsutomu/items/070ca9cb37c6b2b492f0)

## 主な修正ポイント

- 元の記事で時間がかかっていたのは**数理モデルの作成**でした。理由は`lpSum`を使わずに`sum`を使っていたからです。`sum`は無駄なメモリを作成し遅くなります。
  - 「[数理モデルにおける変数の和](https://qiita.com/SaitoTsutomu/items/6701841122acc3130a29)」も参考にしてください。
- 数理モデルの変数は0-1のバイナリ変数ですが、連続変数として解いています。割当問題の隣接行列が全ユニモジュラなので、線形緩和しても整数解が得られるからです。
  - 参考：https://www.weblio.jp/content/全ユニモジュラ性

## 余談

- 今回使用した汎用ソルバーは、cbcという無料ソルバーです。有料ソルバーを使うともっと高速になるでしょう。
- 実務では近似解で十分なことが多いです。近似解法のソルバーを使えば、解の精度とトレードオフですが、さらに高速になるでしょう。
- 今回のデータは完全2部グラフですが、実務ではデータが疎なことが多いです。その場合、変数が減るのでさらに高速になるでしょう。
- NetworkXでも割当問題を解けるのですが、比較にならないほど遅かったです。
SPSS Statistics 27で「効果量」を出力

# p値と合わせて示したい効果量
最近の学術論文では、実験で有意な差があるかどうかを示すp値だけでなく、その差にどれだけの効果があるかを示す効果量の提示が求められています。
平均値の差の検定には、効果量としてCohenのdとHedgesのgの2つがあります。一般的に2つの違いは効果量を算出する際に分散を使用するか、不偏分散を使用するかです。分散は、偏差の2乗和をnで割り、不偏分散は偏差の2乗和をn-1で割ります。母集団を推定するという観点では不偏分散が望ましいと考えられますが、サンプルサイズが大きければ結果にほとんど違いはありません。
ちなみに、SPSS Statistics 27で算出されるCohenのdは不偏分散を使用しています。また、Hedgesの補正は、その不偏分散を使用して求めたCohenのdに補正をかけた値を出力しています。

# 対応のあるサンプルのｔ検定の効果量
実際にSPSS Statistics 27 で算出してみました。
分析メニュー＞平均の比較＞対応のあるサンプルのｔ検定を選択して、対応のある変数をセットします。
ここでは、同じ被験者のgrade8とgrade9の測定値を比較しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/855260/9e9a71e5-880b-4fa2-ee34-476b64120549.png)


そして、☑効果サイズの推定を選択すれば効果量が算出できます。
効果量の選択肢には、◯差の標準偏差、◯差の不偏標準偏差、◯分散の平均があります。
さて、どれを選択しましょう？選択肢があると迷いますね。前半の流れからすると◯差の不偏標準偏差が良さそうにも思えます。

それぞれの算出方法はアルゴリズムガイドを参考にします。
ftp://public.dhe.ibm.com/software/analytics/spss/documentation/statistics/27.0.1/en/client/Manuals/IBM_SPSS_Statistics_Algorithms.pdf
さらに、アルゴリズムガイドを見ていると論文の紹介がありました。
Dunlap, W. P., Cortina, J. M., Vaslow, J. B., and Burke, M. J. (1996). Meta-analysisof experiments with matched groups or repeated measures designs. Psychological methods, 1(2):170.
要約すると対応がある2群間の相関が大きいほど、誤差は小さくなるため、検定統計量は大きくなります。2群間の相関を考慮せずに検定統計量から効果量を計算すると、効果量を過大評価します。なるほど！
効果量を算出する際に相関を使って調整しているのが◯差の不偏標準偏差でした。つまり、2群間の相関が高い場合には、◯差の不偏標準偏差を選択した方がよいということですね。

# 効果量を比較
3つのパターンで実行した結果を比べてみます。2群の相関は0.81です。
[ポイント推定]が効果量の値です。
調整しない(差の標準偏差)場合の効果量が過大評価されていることがわかります。

■対応のあるサンプルのｔ検定◯差の標準偏差
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/855260/cc3b95e9-bb3f-4082-0a82-cc90d60eb29e.png)

■対応のあるサンプルのｔ検定◯差の不偏標準偏差
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/855260/13aaf16a-ca25-dfa9-e7ca-480a0516496a.png)

■対応のあるサンプルのｔ検定◯分散の平均
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/855260/b6e4f1d0-817f-c201-4dd8-4da626b5698e.png)

# 最後に
p値だけでなく効果量の算出もこれでバッチリですね。
アルゴリズムガイドには、計算式だけでなく参考文献の記載もあるので役立ちますね。
Profile編集/

<h2>ProfileのMVCを作成する</h2>

```ruby
rails g scaffold profiles name:string birthday:date user_id:integer
```

<h2>ログイン画面からprofileの作成のアクション</h2>
<p>下記のコードをcommentsのindexファイルに追加する</p>
```ruby
<%= link_to 'New Profile', new_profile_path %>
```

<h2>親関係整える<h2>




<h2>1Userにつき1Profile</h2>
<p>#追加　とかいているところを追加する</p>
```ruby
class ProfilesController < ApplicationController
  before_action :set_profile, only: [:show, :edit, :update, :destroy]
  before_action :authenticate_user! #追加
  # GET /profiles
  # GET /profiles.json
  def index
    @profiles = Profile.all
  # GET /profiles/1
  # GET /profiles/1.json
  def show
  end
  # GET /profiles/new
  def new
    @profile = Profile.find_or_create_by(:user_id => current_user.id)
    redirect_to edit_profile_url(@profile)#追加
  end
  # GET /profiles/1/edit
  def edit
    if @profile.user_id != current_user.id
      raise ActionController::RoutingError.new("Not authorized")
    end #追加
  end
  # POST /profiles
  # POST /profiles.json
  def create
    @profile = Profile.new(profile_params)
    # @profile.save!
    # respond_to do |format|
    #   if @profile.save
    #     format.html { redirect_to @profile, notice: 'Profile was successfully created.' }
    #     format.json { render :show, status: :created, location: @profile }
    #   else
    #     format.html { render :new }
    #     format.json { render json: @profile.errors, status: :unprocessable_entity }
    #   end
    # end
  end
  # PATCH/PUT /profiles/1
  # PATCH/PUT /profiles/1.json
 def update
    respond_to do |format|
      if @profile.update(profile_params)
        format.html { redirect_to @profile, notice: 'Profile was successfully updated.' }
        format.json { render :show, status: :ok, location: @profile }
      else
        format.html { render :edit }
        format.json { render json: @profile.errors, status: :unprocessable_entity }
      end
    end
  end
  # DELETE /profiles/1
  # DELETE /profiles/1.json
  # def destroy
  #   @profile.destroy
  #   respond_to do |format|
  #     format.html { redirect_to profiles_url, notice: 'Profile was successfully destroyed.' }
  #     format.json { head :no_content }
  #   end
  # end
  private
  # Use callbacks to share common setup or constraints between actions.
  def set_profile
    @profile = Profile.find(params[:id])
  end
  # Only allow a list of trusted parameters through.
  def profile_params
    params.require(:profile).permit(:name, :birthday, :user_id)
  end
end
```
Linuxに関する基礎知識

#概要
ITエンジニアになるべくプログラミングの勉強をしておりますが、よく「Linuxの基本は知っておくべき」という情報を目にします。確かにAWSの勉強をする際、「OSはLinuxで良いでしょう」など当たり前に使われています。一度基本は学ばなければこの先厳しいと思い、今回Linuxについて調べました。

#参考資料
[Linuxとは？初心者でもわかる概要や基礎を解説！](https://game-creators.jp/g-job-tenshoku/news_articles/13)
[Linux（リナックス）とは？種類や導入メリット、Linuxで出来ることを解説！](https://www.dospara.co.jp/5info/cts_str_pc_linux)
以上を参照させて頂きました。
OSのお話になるのでPCパーツのサイトも勉強となりました。

#Linuxとは
PCを動かすソフトウェアをOS(オペレーションシステム)と呼びますが、Linuxはその一つです。また、OSの中核部のカーネルという部分のLinuxカーネルを指しているという場合もあります。
OSといえばWindows OSやMac OSが有名ですが、その中でもLinux OSの特徴として、オープンソース化されておりカスタマイズができる、サーバー用として多く使用されている点が挙げられます。

#Linuxの使用例
**サーバー構築**
Linuxはサーバー用OSとして多く使用されており、レンタルサーバーの初期OSとして選ばれることが増えている。
**システム開発**
Linuxカーネルをベースとした、Linuxディストリビューションなど多くのシステムが開発されています。
AndroidもLinuxから派生しているOSです。
**IoT**
組み込みOSとしても使われており、IoTの普及により製品をインターネットにつなげるため、Linuxをカスタマイズし、製品に組み込む使用されています。

#Linuxの種類
Linuxは二つに分けることができます。
**Linuxカーネル**
Linuxの中核になる部分でLinux OSを動かす上で必要な部分です。中核になる部分ではありますが、これだけではPCを操作することができません。
**Linuxディストリビューション**
LinuxカーネルをベースとしてカスタマイズさせたものがLinuxディストリビューションです。たくさんの開発者がLinuxカーネルをベースとしてLinuxディストリビューションを作成されており、多くの派生が生まれています。
#Linuxディストリビューションの派生
**Red Hat系**
Red Hat社が提供しているディストリビューションから派生しているものが、Red Hat系です。代表的なものとしてCentOSがあり、サーバー用として活躍しています。
**Debian系**
ボランティアが中心となって開発されたものがDebian系です。代表的なものはUbuntuが挙げられます。
**Slackware系**
最も歴史があるSlackwareをベースとしたものがSlackware系です。初期からあるため玄人向けではありますが、安定性、セキュリティ、速度も高いです。

#シェル
シェルとはOSユーザーのためにインターフェースを提供するソフトフェアです。シェルを使用することでカーネルの様々な処理を行うことができます。
またコマンドを入力することで、操作することができます。

#代表的なLinuxコマンド
**pwd**
print working directoryの略で、現在のディレクトリを表示します。

```terminal:
$ pwd
/Users/name
```

**cd**
change directoryの略で、指定したディレクトリへ移動できます。

```terminal:
$ cd /programing
$ pwd
/Users/name/programing
```

**ls**
list segmentsの略で、現在のディレクトリの内容を表示します。
-aを足すと隠しファイルを表示することができます。

```terminal:
$ ls
applications
Desktop
documents
Downloads
Library
$ ls -a
.bash_profile
.history
applications
Desktop
documents
Downloads
Library
```

**mkdir**
make directoryの略でディレクトリを作成します。

```terminal:
$ mkdir data
```

**cp**
copyの略で、ファイルをある場所へ移動することができます。

```terminal:
$ cp data1.txt data
```

**mv**
moveの略で、ファイルやディレクトリの移動、名前の変更を行うことができます。

```terminal:
$ mv data.txt data
$ cd data
$ mv data1.txt data2.txt
```

**rm**
removeの略で、指定したファイルを削除することができます。
削除したものは復元が難しいため、操作の際注意が必要です。

```terminal:
$ rm data.txt
```

**cat**
catenateの略で、ファイルの中身を表示するコマンドです。
ファイルの名前を複数指定することで、ファイル内容を連結し、結果を表示させることもできます。

#まとめ
参照サイト様の内容が非常にわかりやすく、自分の中で曖昧だったLinuxの基本を理解することができました。
サーバー構築にLinuxはかなりの率で使用されているので、今のうちに慣れていきたいです。
コマンドもこの機会に復習できてよかったです。
AWSなどのパブリッククラウドの勉強にも役立つと思うので、まとめることができてよかったです。
gitのbuffer不足でcocoaPodsにライブラリを追加出来ない時

###はじめに
Swift歴１ヶ月程の初心者です。
cocoaPodsを使ってFireBase AuthenticationやFaceBookのLoginKitをpodInstallした時に出たエラーを、バッファを増やすことで解決しました。
その時に対応したことを書きます。

###環境
MacOS(Catalina)

###エラー内容

```
[!] Error installing gRPC-C++
[!] /usr/local/bin/git clone https://github.com/grpc/grpc.git /var/folders/sq/41mx0w4x00g4m0b3rf37339h0000gn/T/d20201117-4520-1xy0pnb --template= --single-branch --depth 1 --branch v1.28.2

Cloning into '/var/folders/sq/41mx0w4x00g4m0b3rf37339h0000gn/T/d20201117-4520-1xy0pnb'...
error: RPC failed; curl 56 LibreSSL SSL_read: SSL_ERROR_SYSCALL, errno 54
fatal: The remote end hung up unexpectedly
fatal: protocol error: bad pack header
```


> エラー文：error: RPC failed; curl 56 LibreSSL SSL_read: SSL_ERROR_SYSCALL

errno 54で検索すると、 gitのバッファが少ないとインストールに失敗することが分かりました。
[xcode - RPC failed; curl 56 SSLRead() return error -9806 MiB/s - Stack Overflow](https://stackoverflow.com/questions/39939055/rpc-failed-curl-56-sslread-return-error-9806-mib-s/39940585#39940585)

[gitで大きいサイズのファイルを扱う時]
(https://qiita.com/akiko-pusu/items/2d65a54e9d2a6c7f9d13)


###対策
gitのバッファを増やしてみます

ターミナルで以下を実行。 バッファを2Mにしました。

```
git config --global http.postBuffer 2M
```

###結果
インストールに成功しました！

```
Installing BoringSSL-GRPC (0.0.7)
Installing FBSDKCoreKit (8.1.0)
Installing FBSDKLoginKit (8.1.0)
Installing Firebase (7.0.0)
Installing FirebaseAnalytics (7.0.0)
Installing FirebaseAuth (7.0.0)
Installing FirebaseCore (7.0.0)
Installing FirebaseCoreDiagnostics (7.0.0)
Installing FirebaseFirestore (7.0.0)
Installing FirebaseInstallations (7.0.0)
Installing GTMSessionFetcher (1.5.0)
Installing GoogleAppMeasurement (7.0.0)
Installing GoogleDataTransport (8.0.0)
Installing GoogleUtilities (7.0.0)
Installing PromisesObjC (1.2.11)
Installing abseil (0.20200225.0)
Installing gRPC-C++ (1.28.2)
Installing gRPC-Core (1.28.2)
Installing leveldb-library (1.22)
Installing nanopb (2.30906.0)
Generating Pods project
Integrating client project
Pod installation complete! There are 4 dependencies from the Podfile and 20 total pods installed.
```
djangoでよくやってしまうエラー その１ template.exceptions.TemplateDoesNotExistについて（備忘録）

#template.exceptions.TemplateDoesNotExist
djangoを勉強していたらよく遭遇するエラーでした！
意味としてはずばり【テンプレートがありません！】というシンプルなエラー

原因としては
・テンプレートがそもそもない
・URLが間違っている
・単純な記載ミス
などが挙げられます。

##テンプレートがそもそもない
表示したいテンプレートがフォルダの中にあるかしっかり確認しましょう。

##URLが間違っている
全体のurls.py、アプリごとのurls.pyをそれぞれ確認とsettings.pyでしっかりアプリがインストールされているか確認

##単純な記載ミス
スペルはちゃんとあっているか、階層構造は表示しているかなど、、、、
CentOSにAWSコマンドライン（awscli）をインストールして使う手順

# やりたいこと

* CentOSでAWSのコマンドライン（awscli） https://aws.amazon.com/jp/cli/ を使えるようにしたい。



# 前提

* CentOSがインストール済であり、root権限でSSH接続済であること。
* curlコマンドが実行できること。

# インストール前

awsコマンドは使えない。awsと打つと

```
bash: aws: command not found
```

と表示される。



# インストール方法

任意のディレクトリにて、root権限で下記を実行する。

```
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
./aws/install
```

```
You can now run: /usr/local/bin/aws --version
```
と表示されたらインストール成功である。
下記のように打つとバージョンが確認できる。

```
aws --version
aws-cli/2.1.1 Python/3.7.3 Linux/3.10.0-1062.12.1.el7.x86_64 exe/x86_64.centos.7
```
ELBのポートを考える

# はじめに
ELBでやたらにポート番号が聞かれて少し混乱してしまったので、備忘録的にまとめておきます。
また、今回は[こちらの記事](https://dev.classmethod.jp/articles/aws-alb-port/)を参考にまとめさせてもらいました。
間違えて解釈していることが十分にあるので、随時ご指摘いただけたら非常に嬉しいです！

# 対象読者
* **AWS**アカウントを持っている方。
* **ELB**の使い方があやふやな人。

# ELB
前回書いた記事に構築の仕方は書いているので、今回は、それぞれがどの様な設定を行っているかをまとめられたらと思っています。

## ELBの仕事
**ELB**の主な仕事は、以下のチャートで表すことができます。
今回は簡単のため、行先のインスタンスは**EC2**を1つだけとして考えます。
![201111 ELBの構成図-Page-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412378/ecd8a5a0-b5ea-1744-e4b9-b9f6daf87787.png)

上のチャートの様に基本的に決めなければいけないポートは

1.  **ELB**の外部向けのポート
2.  外部からの通信に用いるポート
3.  **ELB**の内部向けのポート
4.  ヘルスチェック時に見るポート
5.  ターゲットグループが開いているポート


になります。

実際に、 **ELB**を構築しながら確認していきます。
今回は**ALB**として考えていきます。

## ① ELBの外部向けのポート
ここで、**ELB**の外部に向けポートを決めます。
リスナーとは『データを送信してくる相手』という意味です。
**http**は慣例的に**80**番を使うので、今回もそれに倣って『**HTTP**』『**80**』にしておきます。
![スクリーンショット 2020-11-17 15.28.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412378/01001111-b3be-d687-71bf-722362feea8d.png)

## ② 外部からの通信に用いるポート
ここで、『どこからの通信に対して許可をするのか』を決めます。
先ほど行った通り、**http**通信は慣例的に**80**番を使うので『**カスタムTCP**』『**80**』にしておきます。
![スクリーンショット 2020-11-17 15.28.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412378/c5a956ea-f465-ce7f-29b6-a93a2490c0d3.png)

###※補足
上の様に、その**インスタンス**に対するアクセスを規制するセキュリティグループを**インバウンドルール**といいます。
その逆に、その**インスタンス**のデータ送信を規制することセキュリティグループを**アウトバウンドルール**といいます。

## ③ ELBの内部向けのポート
**ターゲットグループ**とはデータを送信する相手のことです。
今回、**ターゲットグループ**である**EC2**は**3000**を開けているとしているので、こちらも『**3000**』を開けます。
![スクリーンショット 2020-11-17 15.29.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412378/af8aa32d-3c43-62ce-6b7c-536c331c59be.png)

## ④ ヘルスチェック時に見るポート
**ヘルスチェック**とは、**インスタンス**が正常に機能しているかどうかを調べるシステムです。
デフォルトでは、③で決めたポートと同じ行先を見るのですが、今回はわざと明示的に設定します。
![スクリーンショット 2020-11-17 15.29.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412378/b73f8d52-7093-2f88-0d8b-3e295eab1060.png)

## ⑤ ターゲットグループが開いているポート
**ターゲットグループ**が開いているポートをここで設定します。
デフォルトでは、④と同じポート番号になっています。
![スクリーンショット 2020-11-17 15.29.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412378/82195891-80fc-507f-8edc-418df4a7ef0e.png)

# まとめ
**https**の時の挙動も今後調べていこうと思います。
【Android】なんとかAndroidアプリのaabファイルのビルドに成功した件

【Android】GooglePlayアプリのkeystoreパスがわからず新規アプリ登録した件
https://qiita.com/technopixelinc2019/items/e7150caeadd1aff6ba4d

上記の記事の続きです。
初心者向け、かつ自分への備忘録として記載残しておきます。

ビルドしようとすると「Gradle build failed」と出るので調べてみる。
【参考URL】
https://nn-hokuson.hatenablog.com/entry/2017/09/05/202327#Gradle-build-failed%E3%81%8C%E5%87%BA%E3%82%8BUnity2019%E3%81%8B%E3%82%89

参考ページによると、Unity2019からはBuild Settingsの項目から「Build System」が削除されたとの事。以前のver.なら「Systemの項目をInternalに設定」で良かったらしい。

Unity2019以降の場合は、Build Settingsの「Export Project」にチェックを入れて、AndoroidStudio用にExportして、Gradleをアップグレードさせると良いとの事。
ここは結局Unityに戻す方法がわからず、挫折。

【参考URL：動画】
https://www.youtube.com/watch?v=RNDYJPMEo98

代わりに、GradleをDLできるページを発見。
https://services.gradle.org/distributions/
→最新と思われる物（この時は6.8）を落としてきて「※任意のフォルダ」に入れる

unityに戻り下記から参照パスを変更
Edit→Preferences→Gradle installed with Unity(recommenceded)

もともと参照していた所から自分でいれたフォルダへ参照パスを変更
C:/Program Files/Unity/Hub/Editor/2019.2.12f1/Editor/Data/PlaybackEngines/AndroidPlayer/Tools/gradle
↓
「※任意のフォルダ」のパス

これで無事、aabファイルのビルドに成功しました！

■反省点
コマンドプロンプトでバッチなどを叩いたりする前に、そのパスの中身を確認する
batファイルはあるかなど、先に見て置く
SDKも同様、参照元にデータがあるのか見て置くと良いかも

■今後
とりあえずビルド成功したので、GooglePlayコンソールでリリースしてみる
Laravel passportのログイン失敗のエラーを飛ばさないようにする

Laravel passportを使うときデフォルトでは、ユーザーのログイン認証に失敗するだけでエラーを投げるようになっている。
エラートラッキングツール（Sentryなど）を使っていると、ユーザーがログイン失敗するだけで通知が来てしまうのが面倒。

Handler.pnpに、下記のように追記するとエラーが飛ばないようにできる。

```php:app/Exceptions/Handler.php
protected $dontReport = [
    \Laravel\Passport\Exceptions\OAuthServerException::class,
];
```
【Laravel基礎】データの受け渡し方    【①ルートパラメータ②Implicit Binding】

#概要#
Laravel学習で自分がつまずいた部分を備忘録としてまとめています。
今回はデータの受け渡しに関する記事です。

#つまずいたポイント#
記事投稿型の簡易アプリ作成時につまずいた問題です。

記事一覧ページ→記事の詳細ページに移る際、
ビュー→コントローラに投稿のデータを渡すにはどうしたら良いのか？
下記２つの方法で解決出来たので記事にしてみました。
####①ルートパラメータ####
####②Implicit Binding####

以下、記事内容です！

#ルートパラメータ#
まず渡し方の１つがルートパラメータを用いた方法です。

■ビュー

```laravel:index.blade.php
 @foreach ($posts as $post)
    <li>
       <a href="/posts/{{ $post->id }}">{{ $post->title }}</a>
    </li>
 @endforeach
```

まず、ビュー上でURLを用いて、ルーティングに投稿のIDを渡します。

■ルーティング
    
```laravel:web.php
Route::get('/posts/{id}','PostsController@show')
```

ここからがルートパラメータを用いた方法です。URLの中に`{ }`を設定します。
この`{ }`の中身がパラメータと言う扱いになり、アクション内でこのパラメータが使用可能になります。
仮で`{ }`の中身を`{id}`と設定していますが、中身にはビューで設定した`$post->id`が入ってきます。
※{ }は変数扱いなので、中身の文字はわかりやすい単語でOK

【例】`'/post/test'`でアクセスした場合 → `「test」`がパラメータ扱い
  　　　`'/post/1'`でアクセスした場合    　→ `「1」`がパラメータ扱い



■コントローラ

```laravel:PostsController
    //アクションの引数にパラーメータを設定
    public function show($id) {
          //パラメータをアクション内で使用出来る
          $post = Post::find($id);
          return view('posts.show')->with('post', $post);
        }
```

アクションの引数の中に先ほどのパラメータを代入する事で、
アクション内でそのパラメータが使用可能になります。

上記のshowアクションでは、
パラメータを元にfindメソッドで該当の記事データを再取得→
記事データを渡しつつ投稿の詳細画面を表示することが出来ました。


## Implicit Binding##
次は`Implicit Binding`です。
ルートパラメータの場合、URLに書かれた文字列だけをコントローラに渡しました。
Implicit Bindingの場合は、投稿を丸ごと渡すことが出来ます。
下記、その手順です。

■ビュー

```laravel:index.blade.php
@foreach ($posts as $post)
    <li>
       <a href="/posts/{{ $post }}">{{ $post->title }}</a>
    </li>
@endforeach
```

URLに`$post`を指定します。


■ルーティング

```laravel:web.php
Route::get('/posts/{post}', 'PostsController@show')
```

先述のルートパラメータで`{post}`を指定します。

            
■コントローラー
        
```laravel:PostsController
public function show(Post $post) {
              return view('show')->with('post',$post);
            }
```

アクションの引数を`(Post $post)`に指定→投稿の中身を`$post`で使用できます。

先ほどと違い、アクション内で投稿を再取得せずに`$post`をそのまま記事詳細画面に渡すことが出来ました。楽ちんですね。


##まとめ##
以上、Laravelにおけるビュー→コントローラへデータの渡し方でした。
Implicit Bindingの方が書くコードの量が少なくなるので効率的ですね。

最後まで読んで頂きありがとうございました！
【Android】GooglePlayアプリのkeystoreパスがわからず新規アプリ登録した件

【Android】GooglePlayのアプリを更新しようとしたらkeystoreのパスワードを忘れていた件
https://qiita.com/technopixelinc2019/items/754adba7fb151c5c62eb

上記の記事の続きです。
結局パスは思い出せずじまい、新規アプリで登録する事にしました。
ただ、ビルドしようとするとエラーばかり。

参考になるかわかりませんが、自分と同じようなプログラマ初心者に向けて記載しておきます。

unityでビルドしようとしたら下記エラー。
unable to install additional SDK platform. please run the SDK Manager manually make sure you have the latest set of tools and the required platforms installed. See Console for details.

ググって調べてみると、2020/8/3からandroidAPI29以上が必要になったとの事。

参考URL
【Unity】Android BuildでAPIレベル29以降にする方法
http://blog.livedoor.jp/toropippi/archives/54941822.html

コマンドプロンプトでSDKを入れようとするも、うまくいかず。
cd C:\Program Files\Unity\Hub\Editor\2019.2.12f1\Editor\Data\PlaybackEngines\AndroidPlayer\SDK\tools\bin
sdkmanager "build-tools;29.0.3"
sdkmanager "build-tools;30.0.2"
sdkmanager "platforms;android-29"
sdkmanager "platforms;android-30"
→ダウンロードされてない様子

他のページ等を見て、下記を試す
cd C:\Program Files\Unity\Hub\Editor\2019.2.12f1\Editor\Data\PlaybackEngines\AndroidPlayer\SDK\tools\bin
sdkmanager.bat "platforms;android-29"

すると次のエラー文が出る
Exception in thread "main" java.lang.NoClassDefFoundError

コマンドプロンプトを諦めて、Android StudioのSDKmanagerを試して見たらインストール完了できました
こちらで入れたのはuser以下のフォルダのようなので、unityの方へコピー

■user以下のフォルダ
C:\Users\※ユーザ名※\AppData\Local\Android\Sdk\platforms
↓
■unity以下おフォルダ
C:\Program Files\Unity\Hub\Editor\2019.2.12f1\Editor\Data\PlaybackEngines\AndroidPlayer\SDK\platforms

unityでビルドをしてみると、さらに「Gradle build failed」と出る
今度はGradleがない（足りない？）らしいです。

（つづく）
git clone リモートリポジトリからクローンを作成する(macOS)

##ターミナルでリモートリポジトリから、クローンを作成する（かなりはまりました笑）
環境
macOS Big Sur(バージョン11.0.1)
git (git version 2.29.2)


###エラー内容

```ターミナル:ターミナル
ss@saaaMPro Desktop % git clone https://github.com/sakuma-s/git-command.git
Cloning into 'git-command'...
fatal: invalid branch name: init.defaultBranch = 
```
エラー内容を翻訳すると
fatal: invalid branch name: init.default Branch
致命的：無効なブランチ名：init.defaultブランチ

ここでかなりハマりました、、、

git branchで現在のブランチを確認

```ターミナル:ターミナル
ss@saaaMPro Desktop % git branch
* master
```
と記載されており、リモートリポジトリのbranchを確認するとmainに設定している事を確認！早速変更！

```
git branch -m main
```
一応変更されているか確認

```
ss@saaaMPro Desktop % git branch
* main
```
再度git cloneを実行

```
ss@saaaMPro Desktop % git clone https://github.com/sakuma-s/git-command.git gittest05     
Cloning into 'gittest05'...
remote: Enumerating objects: 19, done.
remote: Counting objects: 100% (19/19), done.
remote: Compressing objects: 100% (9/9), done.
remote: Total 19 (delta 6), reused 19 (delta 6), pack-reused 0
Receiving objects: 100% (19/19), done.
Resolving deltas: 100% (6/6), done.
```
成功！
念の為、ローカルディレクトリも確認！

##今回のエラー原因
gitのデフォルトで設定されているbranch(master)と、リモートリポジトリのデフォルトbranch(main)が違ったため、上手くクローンが出来なかったのだと思います。。。
小さな事でもありがたいので、情報不足でしたらコメントからご指摘お願いいたします！

ブランチ名を変更する時に参考にしたサイト
[gitのローカルのブランチ名を変更したい](corocn.github.io/symbol-typing/)

助かりました！感謝いたします。
InterventionImageで編集した画像ファイルをbase64変換してMySQLに保存する

# やりたいこと
InterventionImageで編集した画像ファイルをバイナリーに変換してMySQLに保存したい
もちろん画像ファイルは/public配下やS3などのファイルシステムに保存するのが定石なのは承知の上で、今回は手軽さを優先してDBに画像ファイル自体をtextカラムに保存する

# 環境

```shell-session

% sw_vers
ProductName:	Mac OS X
ProductVersion:	10.15.7
BuildVersion:	19H2

% docker version
Client: Docker Engine - Community
 Cloud integration: 1.0.1
 Version:           19.03.13
 API version:       1.40

# php -v
PHP 7.4.7 (cli) (built: Jun 11 2020 18:41:17) ( NTS )
Copyright (c) The PHP Group
Zend Engine v3.4.0, Copyright (c) Zend Technologies
    with Xdebug v2.9.6, Copyright (c) 2002-2020, by Derick Rethans

# php artisan -v     
Laravel Framework 7.26.1

# mysql --version
mysql  Ver 14.14 Distrib 5.7.30, for Linux (x86_64) using  EditLine wrapper
```


# Intervention Image とは
ImageMagikの上位互換？のモダンな画像編集パッケージ
リサイズ、トリミング、フィルターとなんでも手軽にできるっぽい
詳しくは[公式doc](http://image.intervention.io/)参照


# MySQLに画像バイナリを保存する

```php:UserController
    public function update(Request $request, User $user)
    {
        // InterventionImageで加工&保存
        $file = $request->file('profile_img');
        $img = Image::make($file);
        $img->fit(400); //400px * 400px にトリム＆リサイズ
        $bin = base64_encode($img->encode('png'));
        
        $user->profile_img = $bin;
        $user->save();
        return redirect()->route('user.index');
    }

```

ポイントは`$bin = base64_encode($img->encode('png'));`の1行。
base64_encodeする前に一度InterventionImageインスタンスをエンコードしている。
この処理がないとbase64_encodeしても空文字が生成される。なぜかはよくわからない。
Flutter実装時にお世話になったページ 2020/11/17

## なにか

毎回、同じ問題に、同じ検索して、同じページで解決してるので。。。

## TabBarViewのスワイプによる切り替えを無効にしたかった

[Stack Overflow "disable swiping tabs in TabBar flutter"](https://stackoverflow.com/a/51523272)

## Firebase の Cloud Messaging による通知がiOSで受け取れなかった

公式ドキュメントをちゃんと読めってことですね。
iOS Integration のステップ２で、以下を読み落としてたのと
> Don't follow the steps named "Add Firebase SDK" and "Add initialization code" in the Firebase assistant.

Dart/Flutter Integration のここを実装せずにテストしてました。（Androidは無くても届く）

```
import 'package:firebase_messaging/firebase_messaging.dart';

final FirebaseMessaging _firebaseMessaging = FirebaseMessaging();
```

[Pub.dev firebase_messaging](https://pub.dev/packages/firebase_messaging)

## iOS風のモーダル表示
まだ、Flutterとしては実装されていない模様

[Github flutter "Support for sheet presentation style"](https://github.com/flutter/flutter/issues/42560)

上記のissue内に記載されている、ライブラリを使用

[Pub.dev modal_bottom_sheet](https://pub.dev/packages/modal_bottom_sheet)
kintone連携サービス「じぶんフォーム」でできること


この記事は [kintone Aevent Calendar](https://qiita.com/advent-calendar/2020/kintone) 17日目の記事です。 

# はじめに
kintone連携サービスとしてご提供しているじぶんフォームを約6ヶ月前にリリースしました。
現在はリリース後もより使いやすいサービスとするために少しずつ機能追加をしています。

この記事では現時点でじぶんフォームを使ってできることや実際の利用例をご紹介します！

# じぶんフォームってなに？
『じぶんフォーム』は株式会社ソニックガーデンが開発しているkintone連携サービスです。
https://jibun-apps.jp/form

☆ちなみに、**kintone**ってなんだっけ？という方は[こちら](https://kintone.cybozu.co.jp/what_is_kintone/beginners/)をご参照ください。

#### じぶんフォームは問い合わせのためのフォーム
一般的なフォームは入力するために利用するものですが、
じぶんフォームは**問い合わせ**の入力と関わる業務が楽になる機能を揃えています。

#### じぶんフォームはシンプル
問い合わせに特化しているサービスなので、複雑なことはできません。
その代わりに問い合わせフォームとして便利な機能をたくさん持っています。

## じぶんフォームの機能・特徴
### 自動返信メール（サンクスメール）を送ることができる
フォームのに入力した内容が登録されたら、入力してくださった方へ受付できたかどうかをお知らせすることができます。
そして、管理者にはフォームから入力があったことをお知らせします。

お知らせメールの本文・タイトルには、フォームで入力した内容を入れることができます。
どの内容をメールに記載するかは編集画面で確認することができるので、あらかじめメモをしておく必要はありません。

![管理画面｜じぶんシリーズ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134944/77e29366-d4e5-116d-bda5-0aca5ba9a714.png)

### デザインを変更することができる
入力フォームのデザインはカスタマイズすることが可能です。その方法は２つあります。

#### 1. デザインの設定機能を使って変更する
デザインの設定機能では、背景色、背景画像、ロゴの画像を設定することができます。
企業の方であれば自社のブランドカラーやサイトのデザインに合わせたフォーム画面を作成可能です。
じぶんフォームの[サンプルサイト](https://app.jibun-apps.jp/form/e46e1146-62e5-4420-800b-808d4da529df/new)もデザインの設定機能を使ってじぶんシリーズのカラーに合わせたフォームを作成しています。
![お問い合わせフォームのサンプル___じぶんフォーム.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134944/50443615-0d2d-6eec-2327-bf4ef2565102.png)

#### 2. 自社サイトに埋め込む
デザインも変更したいし、自社のサイト上にお問い合わせフォームを設置したい。
そんな時のためにじぶんフォームを自社サイトのページとして埋め込むことができる機能もあります。

埋め込み機能では埋め込み用のHTMLコードのみを取得することができます。
デザインは一切入っていないため、自社サイトのデザインをそのまま適用することが可能です。

注） 対応しているフィールド一覧（12/17時点）

| フィールドタイプ | 入力フォーマット例 |
|:----|:----|
|文字列（１行）|  |
|文字列（複数行）|  |
|数値|  |
|リンク|  |
|ラジオボタン|  |
|チェックボックス|  |
|ドロップダウン|  |
|複数選択|  |
|時刻|01:01|
|日付|2020-01-01|
|日時| 2020-01-01T01:01 / 2020-01-01T01:01:00+01:00|

### ドラッグ＆ドロップでフォーム作成できる
フォームに配置する全てのフィールドはドラッグ＆ドロップで可能です。
つまり、マウスを使って並べるだけです。
配置の変更も直感的に行うことができます。

### kintoneフィールドにはない見出しや文章を挿入できる
入力してもらいたい項目の補足となるような説明文を入力することでより親切なフォーム作成が可能です。
独立した説明文や見出し、入力欄の補足説明を設定できます。

### エラーが起きても復旧できる
問い合わせフォームから入力された内容がエラーでkintoneへ登録できなかった場合でも、内容はじぶんフォームの中に保存されるため消えません。
また、エラー通知用のメールアドレスが複数設定可能です。

### googleアナリティクスと連携できる
googleアナリティクスのトラッキングIDをお持ちであれば、じぶんフォームにも連携することができます。

### スパム対策もできる
フォーム投稿を拒否する文字列を設定したり、reCAPTCHAによるスパム判定機能を持っています。


# 最後に
じぶんフォームはシンプルだけど便利な機能がたくさんあります。
今後も機能追加をしていく予定ですので、
ご興味のある方はぜひ無料お試しを利用してみてください！

じぶんフォーム 公式ページ（無料お試しもこちらからどうぞ）
https://jibun-apps.jp/form
chromedriver_binaryのバージョンをそろえる

WindowsのChrome86が入った環境で
ドライバの.exeをいちいち入れるのが何となく嫌で
自動でドライバを選んでくれる？らしい

```
import chromedriver_binary
```

を使おうと思い

```
pip install import chromedriver_binary
```

を実行して
pythonのseleniumを使ったコードを実行したら
あんたのChromeとバージョンが違う、というエラーが出た。

どうやら現時点最新の Chrome87用がインストールされたらしい。
では自分のChrome86のバージョンを確認して

```
pip install import chromedriver_binary==86.04240.193
```

そのまま実行すると

```
ERROR: Could not find a version that satisfies the requirement chromedriver_binary==86.04240.193 (from versions: 2.29.1, 2.31.1, 2.33.1, 2.34.0, 2.35.0, 2.35.1, 2.36.0, 2.37.0, 2.38.0, 2.39.0, 2.40.1, 2.41.0, 2.42.0, 2.43.0, 2.44.0, 2.45.0, 2.46.0, 70.0.3538.16.0, 70.0.3538.67.0, 70.0.3538.97.0, 71.0.3578.30.0, 71.0.3578.33.0, 71.0.3578.80.0, 71.0.3578.137.0, 72.0.3626.7.0, 72.0.3626.69.0, 73.0.3683.20.0, 73.0.3683.68.0, 74.0.3729.6.0, 75.0.3770.8.0, 75.0.3770.90.0, 75.0.3770.140.0, 76.0.3809.12.0, 76.0.3809.25.0, 76.0.3809.68.0, 76.0.3809.126.0, 77.0.3865.10.0, 77.0.3865.40.0, 78.0.3904.11.0, 78.0.3904.70.0, 78.0.3904.105.0, 79.0.3945.16.0, 79.0.3945.36.0, 80.0.3987.16.0, 80.0.3987.106.0, 81.0.4044.20.0, 81.0.4044.69.0, 81.0.4044.138.0, 83.0.4103.14.0, 83.0.4103.39.0, 84.0.4147.30.0, 85.0.4183.38.0, 85.0.4183.83.0, 85.0.4183.87.0, 86.0.4240.22.0, 87.0.4280.20.0)
ERROR: No matching distribution found for chromedriver_binary==86.04240.193
```

見つからない、この一覧しか無いぞ？とのこと。
完全一致のバージョンが無いが、同じ86だったら大丈夫だろうか？

```
pip install import chromedriver_binary==86.0.4240.22.0
```

すると、動いた。
めでたしめでたし。
AtCoder Beginner Contest 062  C - Chocolate Bar 反省log 水色diff

## 概要

[hirokihello](https://twitter.com/maxyasuda)の解けずに解説を見た問題を、なぜ解けなかったかの分析log

## 問題について

チョコを三つの長方形に分けて、最大値と最小値に分ける問題

https://atcoder.jp/contests/abc062/tasks/arc074_a

## 思考

まず縦か横が3の倍数なら３等分できるので、その時点で最大と最小の差は0になることに気づいた。。

そこで脳が停止した。

まず縦で３等分するパターンについて、３等分する大きさの組み合わせを考えれば良いと考えたが、脳死でやるとO(n^3)で確実に間に合わない。

横について、そしてsampleの分け方についてもこの方針だとTLEすることが確実。

ここで諦めて回答を見た

## 足りなかった思考


- 問題で想定される解のパターンをきちんと場合分けすること。
- あり得る状態、条件を満たす状態から逆算して探索の手間を減らす。


> 問題で想定される解のパターンをきちんと場合分けすること。

まず状態の遷移がどのようになるのかをきちんと詰めることなく、なんとなく難しいで終わってしまっていた。

今回の場合はきちんと場合わけしてみると、簡単である。

分割した長方形をA,B,Cとする。

1. A,B,Cが横に分割
2. Aが横、B,Cは残りを縦
3. A,B,Cが縦に分割
4. Aが縦、B,Cが横

このパターンしかない。
上下左右を入れ替えても結果には影響しないので、全４パターンである。

> あり得る状態、条件を満たす状態から逆算して探索の手間を減らす。

ここについて、実際に今回の問題の制約をどのように減らすか考えてみる。

まずは上記で挙げたパターンのうちに、1,2でAが横にめいいっぱいあることを考える。

#### パターん１

よって高さの分割は、高さHとすると

```
A: aH;
B: bH;
C: cH;
```

として、aHを固定値として、基準にして考える。

下記の分け方で計算量を落とすのが多分今回のkeyだったと感じている。

aHを決めて、残りをそこから分割して求める方針で行くと、bHとcHが全体の最小、最大どちらになるにせよ、そこからの差分を小さくしたいので残りの分割の方法は2分の１にできるだけ近い部分で分けることになる。

最大になる場合、大きい方をもっとも小さくしたいので半分のところでわけ、最小になる場合は逆で小さい方をもっとも大きくしたいので半分で分ける。つまりどちらにせよ分ける部分は半分になる。

`(H - aH) / 2` もしくは`(H - aH) / 2 + 1`がbHとcHになる。

問題文より、三つの中の最大と最小の差を小さくしたいので、bとcのどっちが大きい・小さいは考えなくて良い。

よって最大値と最小値の差は

(H - aH)が偶数の場合

```
# 最大値
max(aH,(H - aH) / 2) 
# 最小値
min(aH,(H - aH) / 2)
```

(H - aH)が奇数の場合の場合

```
# 最大値
max(aH, (H - aH) / 2 + 1)
# 最小値
min(aH,(H - aH) / 2)
```

で表すことができる。あとはこれに幅のWをかけて求めれば良い。

これを全てのAHで求めるのは、aが1~nまで全て探索すれば十分なので、O(n)であり十分余裕を持って間に合う。

#### パターン2

パターン１と同じように、aHを全て探索する。

そうすると、bWとcW(B、Cの横の長さ)は常にWをまん中で求めることになる。

よって最大の面積の求め方は


奇数の場合

```
# Aの面積
aH * W


# B,Cの面積のうち大きい方(Wが奇数の場合)
(H - aH) * (W / 2 + 1)


# 最大値(W奇数)
max(aH * W, (H - aH) * (W / 2 + 1))

# B,Cの面積のうち小さい方
(H - aH) * W / 2

# 最小値
min(aH * W, (H - aH) * W / 2)
```

最小の面積は偶数の場合

```
# Aの面積
aH * W

# B,Cの面積のうち大きい方
(H - aH) * W / 2

# 最大値
max(aH * W, (H - aH) * W / 2)

# B,Cの面積のうち小さい方
(H - aH) * W / 2

# 最小値
min(aH * W, (H - aH) * W / 2)
```

これは0(n)で求めることができる。

#### パターン3, パターン４
パターン1, 2に関してHとWを逆にすれば良い。

#### 結論

よって全てのパターンでO(n)なので十分まにあう
C++入門の私的まとめ

こちらの記事は以下の書籍を参考にアウトプットとして執筆しました。
[新・明解C++入門](https://www.amazon.co.jp/gp/product/B0787YH4L2/ref=ppx_yo_dt_b_d_asin_title_o00?ie=UTF8&psc=1)

「へぇ〜」と思ったことをメモっていきます。

###整数型
|型名|説明|型指定子|
|---|---|---|
|符号なし整数型|0、正の整数|unsigned|
|符号つき整数型|負、0、正の整数|singed(型指定子を省略した場合もこれ)|
###\<climits\>ヘッダ

>C++の処理系は整数型の各型で表現できる値の最小値と最大値を<climits>ヘッダで提供します。
引用：[新・明解C++入門](https://www.amazon.co.jp/gp/product/B0787YH4L2/ref=ppx_yo_dt_b_d_asin_title_o00?ie=UTF8&psc=1)

整数型で扱える値の最小値、最大値のことであると理解した。

###オブジェクト形式マクロ
\#defineのような置換命令のこと

```c++
#define INT_MAX +32767
```
`INT_MAX`の置換対象を**マクロ**という

###defineとconst
違いはdefineはコンパイル前に書き換えるという点
>参考：[constとdefineは何が違うのですか
](https://ja.stackoverflow.com/questions/13061/const%E3%81%A8define%E3%81%AF%E4%BD%95%E3%81%8C%E9%81%95%E3%81%86%E3%81%AE%E3%81%A7%E3%81%99%E3%81%8B)

##文字型

|型名|説明|
|---|---|
|単なる文字型|char型|
|符号なし文字型|signed char型|
|符号つき文字型|unsigned char型|

###文字型のビット数

```c++
//使用している処理系の文字型のビット数
cout << CHAR_BIT ;
```
###typedef宣言
```c++
//既存の方に別名を与える
typedef A B;
//A:既存の型名
//B:型名Aの同義語となる型名
```
size_t型は符号なし整数型として定義される。
###typeid
型の色んな情報を取得できる

###多次元配列
```c++
int a[4][3];
```
行→`sizeof(a) / sizeof(a[0])`
列→`sizeof(a[0]) / sizeof(a[0][0])`

PHPみたいに`count()`みたいにシンプルなやつ無いのかな..

####初期化子
いちいち代入するよりも以下でも初期化できる

```c++
int a[3][2] = {
		{1, 2},
		{1, 2},
	}
```
ssmでansibleしてみたメモ(ただのメモ)

## 事前作業

### SSM

EC2にSSMエージェントを入れ、EC２をSSMの管理下に置く。SSM マネージドインスタンス から見えてればOK

![スクリーンショット 0002-11-17 15.13.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27932/2ac49cc6-9e1b-d5d3-0a3b-29ed9d3ad3a8.png)

参考リンク
https://dev.classmethod.jp/articles/troubleshooting-ssm-session-manager-configuration/

### S3バケット作成

AnsibleのテンプレートをzipにしてS3に配置するため。

## Ansibleテンプレート

MacでもEC2でもいいので作成する。

```yaml
[root@ip-10-1-1-87 .ansible]# cat apache.yml 
- hosts: all
  become: yes
  tasks:
  - name: Apacheインストール
    yum: name=httpd state=latest
  - name: Apacheの起動
    service: name=httpd state=started enabled=yes
  - name: Apacheの起動確認
    shell: ps aux | grep httpd
    register: ps_result
    changed_when: false
  - debug: var=ps_result.stdout_lines
    when: ps_result 
```

zipコマンドでzip化し、
zipファイルをS3にアップロードする
S3パスは控えておく

今回はyamlファイル1個ですが、AnsibleのRoleなどディレクトリごと固めてもOK

```bash:
[root@ip-10-1-1-87 .ansible]# zip ansible.zip apache.yml 
updating: apache.yml (deflated 33%)
[root@ip-10-1-1-87 .ansible]# ls
ansible.zip  apache.yml
[root@ip-10-1-1-87 .ansible]# aws s3 cp ansible.zip s3://xxx/ansible/
```

## SSMでRun Command

SSM->Run Command->[Run command]ボタン の順でクリック
コマンドドキュメント"AWS-ApplyAnsiblePlaybooks"をクリック

![スクリーンショット 0002-11-17 15.17.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27932/062b2a89-da80-a939-a78a-fbf38c23371b.png)

[コマンドを実行する]をクリック

コマンドパラメータで以下を入力や選択し、[実行]をクリック

* Source Type:S3
* Source Info:
{
   "path":"https://xxx.s3-ap-northeast-1.amazonaws.com/ansible/ansible.zip"
}

* Playbook File:apache.yml
* ターゲット:該当インスタンス(タグやリソースグループ指定も可能)(便利)

![スクリーンショット 0002-11-17 15.22.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27932/541a0e21-e69a-dcdc-0862-a8625dc8e29c.png)


## 確認



ターゲットEC2にhttpdがちょい前にインストールと起動がされてる

```bash
[ec2-user@ip-10-1-1-165 ~]$ sudo systemctl status httpd.service
● httpd.service - The Apache HTTP Server
   Loaded: loaded (/usr/lib/systemd/system/httpd.service; enabled; vendor preset: disabled)
   Active: active (running) since Tue 2020-11-17 04:35:02 UTC; 27s ago
     Docs: man:httpd.service(8)
 Main PID: 2963 (httpd)
   Status: "Total requests: 0; Idle/Busy workers 100/0;Requests/sec: 0; Bytes served/sec:   0 B/sec"
   CGroup: /system.slice/httpd.service
           ├─2963 /usr/sbin/httpd -DFOREGROUND
           ├─2965 /usr/sbin/httpd -DFOREGROUND
           ├─2966 /usr/sbin/httpd -DFOREGROUND
           ├─2967 /usr/sbin/httpd -DFOREGROUND
           ├─2968 /usr/sbin/httpd -DFOREGROUND
           └─2969 /usr/sbin/httpd -DFOREGROUND
```
unityのオブジェクトをC#で生成、子要素に移動する方法

※Unity実践リファレンスの内容を参考にしています。
＜エンジニアのためのUnity実践リファレンス ～ ゲーム開発にすぐに役立つスクリプト入門＞
https://www.amazon.co.jp/dp/B00WHEJI8W/ref=cm_sw_em_r_mt_dp_K82SFb5NXTQ27

動的にC#でゲームオブジェクトを生成し、それを特定のゲームオブジェクトの子要素として移動させるためのコードになります

![スクリーンショット 2020-11-17 15.25.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/566867/671cfc86-d482-ccb4-1209-35753861a5ec.png)



```
    // test.cs

    // Start is called before the first frame update
    void Start()
    {
        //C#で使用する変数名にparentAという名前で作り、
        //ヒエラルキー上のオブジェクト名をParentGO_Aとして生成

        var parentA = new GameObject("ParentGO_A");
        var parentB = new GameObject("ParentGO_B");
        var childA = new GameObject("childrenGO_A");
        var childB = new GameObject("childrenGO_B");
        var childBchildA = new GameObject("childrenBchildrenGO_A");

        //childAをparentAの子要素にトランスフォーム
        //これでchildAのゲームオブジェクトを指定したゲームオブジェクトの子要素に変更
        childA.transform.parent = parentA.transform;
        childB.transform.parent = parentB.transform;

        //特定の要素の子要素にする場合に、２階層下の要素としても１回で変更できる
        //この場合は
        childBchildA.transform.parent = childB.transform;
    }

```

＜実行前＞
![スクリーンショット 2020-11-17 15.24.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/566867/82b8befc-9b74-3fb2-ce96-a3b817601c82.png)

＜実行後＞
![スクリーンショット 2020-11-17 15.25.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/566867/f8b23b56-9824-b1a2-212c-12190ab2ff43.png)

ちゃんと階層構造を持ったままゲームオブジェクトが生成されました。

この機能を使って特定の条件下で生成したゲームオブジェクトがあれば、それをFind関数を利用して見つけたのちに、子要素へ移動させるということもできそうです。
Music✖️Analytics Meetupに行ってみた

# Music✖️Analytics Meetupに行った理由
こちらのイベントに行ってまいりました。
> 本イベントは「音楽×データ分析」に興味のある方に向けたイベントです。

まあ私は仕事でデータ分析を行っている訳でも、増してや音楽だって過去に楽器を弾いていたくらいです。
ただ、今後のキャリアプランとして現状やっている仕事のスキルを活かせて、尚且つ興味がある分野の仕事をしたいなと思って思い切って参加してみることにしました。
懇親会は参加していませんので、もしこの記事を見てらっしゃる参加者様がいらっしゃいましたらコメントにて情報共有いただけると誠に嬉しい限りでございます。
https://connpass.com/event/155446/

### ダイナミックプライシングとは
需要と供給に応じて価格を柔軟に変更する。
欧米ではテイラースイフトなどが導入。
ダイナミックプライシングをスポーツだけでなく、音楽にも繋げたいよね
参考wiki https://ja.wikipedia.org/wiki/%E3%83%80%E3%82%A4%E3%83%8A%E3%83%9F%E3%83%83%E3%82%AF%E3%83%BB%E3%83%97%E3%83%A9%E3%82%A4%E3%82%B7%E3%83%B3%E3%82%B0

関野場所ごとの価格変更の課題

- 機会の不平等感
- 初期価格の価格設定
- 買い控え(スローチケット販売)


## 音楽業界におけるダイナミックプライシングと二次市場
### 定義
- 一時市場...興行主
- 二次市場...一時市場での購入者が販売するもの(転売市場)
### 音楽業界のビジネス的なお話(二次市場とDP)
1次市場に占めるBotの割合42.2%
年間成長率は12.3%

### 席によって値段を変える？
需要予測が難しい
スポーツと違って定期的な公演がない。京セラとヤフオクでも全然違うじゃん。
発売日にみんな買う。価格設定間違えると一瞬で売り切れたり、沢山余ったりする。

### なぜDPか
- 収益改善
- 難しい初期価格の予測を外しても修正可能
- 適切な価格付きのもとでは転売が減る

## 歌声の特徴に基づいて曲を探そう
電通国際情報サービス
声の類似度を算出して曲との新しい出会い方を実現する

歌声は楽曲の中でリスナーがもっとも
Spleeterで耳コピできる？

## 類似ビジュアライズ
Youtube API
Spotify API
使えそうだな。今度やってみよう。

https://skymind.ai/japan/wiki/word2vec
word2vec,初めて聞いたけどやってることは面白そうでした。

## 最後に
投稿が遅くなってしまった(下書きに残っていて忘れてた)のですが、
やっぱり好きなものに関する話は聞いていて楽しいですね。
azure上のインスタンスに datadog-agent をインストールし、メトリクスを確認するまで

# 環境
Paas: Azure
OS: CentOS8(4.18.0-193.28.1.el8_2.x86_64)

# ざっくりな流れ
CentOS8 を選択したのはミスだったかも。。いろいろ失敗したとき、CentOS8 であることが調査のノイズになった。(ハマった部分でCentOS8 が原因のものがあったのかどうかは不明)
- ※参考リンク先は datadogにログインしていないと確認不可のものが多い

## datadog-agent のインストール

```
DD_AGENT_MAJOR_VERSION=7 DD_API_KEY=xxxxxx DD_SITE="datadoghq.com" bash -c "$(curl -L https://s3.amazonaws.com/dd-agent/scripts/install_script.sh)
```

実行後にプロセス起動を確認

```
# ps -ef | grep datadog
dd-agent    3040       1  2 15:18 ?        00:00:02 /opt/datadog-agent/bin/agent/agent run -p /opt/datadog-agent/run/agent.pid
dd-agent    3041       1  0 15:18 ?        00:00:00 /opt/datadog-agent/embedded/bin/process-agent --config=/etc/datadog-agent/datadog.yaml --sysprobe-config=/etc/datadog-agent/system-probe.yaml --pid=/opt/datadog-agent/run/process-agent.pid
dd-agent    3042       1  0 15:18 ?        00:00:00 /opt/datadog-agent/embedded/bin/trace-agent --config /etc/datadog-agent/datadog.yaml --pid /opt/datadog-agent/run/trace-agent.pid
root        3319    1301  0 15:19 pts/0    00:00:00 grep --color=auto datadog
#

```
参考： https://app.datadoghq.com/account/settings?_gl=1*1tbwosn*_gcl_aw*R0NMLjE2MDU1NzcwNTkuQ2owS0NRaUE0OGo5QlJDLUFSSXNBTVF1M1dSalZTRDIxaWR0MHhaRGNGQUhDX2I0OG5TM0N4eWtaOXZKeFNiVHZsU0J4QS00OEFmZ05SVWFBdFBRRUFMd193Y0I.#agent/centos

## Azureアカウント連携の下準備: Azure CLI のインストールと情報確認
az version以外の標準出力は省略

```
# yum install python36
# yum install gcc python3-devel
# curl -L https://aka.ms/InstallAzureCli | bash
# exec -l $SHELL
# az version
{
  "azure-cli": "2.15.0",
  "azure-cli-core": "2.15.0",
  "azure-cli-telemetry": "1.0.6",
  "extensions": {}
}
# az login
# az account show
# az ad sp create-for-rbac --role "Monitoring Reader" --scopes /subscriptions/{subscription_id}
```
- うまくいかなかった参考情報: https://docs.microsoft.com/en-us/cli/azure/install-azure-cli-yum
  - ※/etc/yum.repos.d/azure-cli.repo を手順通り作成すると、dnf(yum)コマンド失敗するようになったため、この方法でのAzure CLIインストールは諦めた。ググったとき、この方法を採っている人が殆どなので、これができれば一番良い
  - ※代わりの参考情報: https://asazure.hatenablog.jp/entry/2015/08/24/210600

## datadog側に情報登録
[Datadog Azure インテグレーションタイル](https://app.datadoghq.com/account/settings?_gl=1*1bu1udt*_gcl_aw*R0NMLjE2MDU1NzcwNTkuQ2owS0NRaUE0OGo5QlJDLUFSSXNBTVF1M1dSalZTRDIxaWR0MHhaRGNGQUhDX2I0OG5TM0N4eWtaOXZKeFNiVHZsU0J4QS00OEFmZ05SVWFBdFBRRUFMd193Y0I.#integrations/azure)に、"appId" を  Client ID に、"password" をClient Secret に入力。 
※参考: https://docs.datadoghq.com/ja/integrations/azure/?tab=azurecliv20
IE11でも動くワンライナー湯婆婆を作り、IE11対応のつらさを再認識する

## 何番煎じかわからないネタをやります。

### Q.なぜこんなことを？

流行りの湯婆婆にのっかりたかったんです。

### Q.JSはみんなやってるよね？

はい、しかもすげーLTGMも稼いでるのでもう勝てないなって。
なのでIE11でも動くのをやってみようと思いました。

### Q.IE11って需要あるの？

未だにIE対応が必要だと言われることがあるので、あと数年は需要があるかもしれない。
でも個人的には早く滅びてほしいと思っていますね(笑)


## というわけでコード

JSのコード自体はワンライナーの体を保っている・・・はず。

```html:湯婆婆.html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>湯婆場</title>
    <script>
    (function(f){alert((function(f,n){return "フン。"+f+"というのかい。贅沢な名だねぇ。今からお前の名前は"+n+"だ。いいかい、"+n+"だよ。分かったら返事をするんだ、"+n+"!!"})(f,f[Date.now()%f.length]))})(window.prompt("契約書だよ。そこに名前を書きな。",""))
    </script>
</head>
</html>
```

## ポイント

まず、一行で書いてしまったJSコードを一旦整形しましょう。

```javascript
(function (f) { 
  alert(
    (function (f, n) { 
       return "フン。" + f + "というのかい。贅沢な名だねぇ。今からお前の名前は"
              + n + "だ。いいかい、" + n + "だよ。分かったら返事をするんだ、" + n + "!!" 
    })(f, f[Date.now() % f.length])
  )
})(window.prompt("契約書だよ。そこに名前を書きな。", ""))
```

### 真面目な書き方をするとこうなる

ワンライナーにするためにクソコードにしてしまった。
そしてこっちのほうが文字数が少ないとかいう問題にも目をつむってほしい。

```javascript
// プロンプトで文字入力
const f = window.prompt("契約書だよ。そこに名前を書きな。", "");
// 時間使って疑似ランダム
const n = f[Date.now() % f.length];
// 結果表示
alert("フン。" + f + "というのかい。贅沢な名だねぇ。今からお前の名前は"
              + n + "だ。いいかい、" + n + "だよ。分かったら返事をするんだ、" + n + "!!" );
```

### 関数を作ってそれを即時実行

JSの関数を作って実行する場合には、だいたい以下のようにします。

```javascript
function multiple(n) {
  return n * n;
}
const nn = multiple(8);
```

それを、以下のように書くことで即時に実行することができます。

```javascript
const nn = (function(n) {
  return n * n;
})(8);

// ES2015だとここまで短縮はできる
const nn = ((n)=>n*n))(n);
```


正直、普通に書いたらいいじゃん、と思うでしょう。
本来はjQueryプラグインなんかを作るために多用していたテクニックです。

```javascript
(function($){
  $.fn.myPlugin = function() {
    // ここにプラグインの中身を記載
  }
})(jQuyery);
```

こうすることで、window.onloadよりも前のタイミングでjQueryプラグインのロードを済ませつつ、
カプセル化を(一応)実現できるようになるのです。

~~要はclass構文がなかった頃のレガシーコードなので、使ってドヤらないように注意しましょう。~~

## IE11では使えないJSの機能たち

JavaScriptにはES2015という規格があり、いろいろと新機能が追加されました。
しかしながら、IE11は中途半端に対応しているため動かない書き方が多数存在します。

### アロー関数

アロー関数とは、関数定義を簡略化して記載するための記法です。
簡易的な計算を記載したり、コールバック関数としての記載をする場合によく使用します。

```javascript
function(n) {
  return n * n;
}
// 下のように書ける
(n) => n * n;
```

なお、厳密にはthisの扱いが変わったりしますので、
なんでもかんでもアロー関数にしたらいいというわけではないので注意してください。

### テンプレート文字列

テンプレート文字列は、CやJavaでのString.formatに相当する機能で、
文字列の中に変数を定義してテンプレートとして定義できます。

```javascript
const name = "太郎";

let message = "こんにちは、" + name + "さん";

// これを以下のように書ける
let message = `こんにちは、${name}さん`;
```

ちなみに、アロー関数とテンプレート文字列を使うだけでも、ここまですっきりします。
(え、すっきりしない？)

```javascript
((f) => alert(((f,n)=>`フン。${f}というのかい。贅沢な名だねぇ。今からお前の名前は${n}だ。いいかい、${n}だよ。分かったら返事をするんだ、${n}!!`)(f,f[Date.now()%f.length])))(window.prompt("契約書だよ。そこに名前を書きな。",""))
```

## さいごに

短さや可読性は[先人の方](https://qiita.com/TD12734/items/743e90fb867fee8c562e)のほうが上ですので、真面目にJSの勉強をしたい方はそちらを参照しましょう。


IE11の対応を予定していない皆様はこの記事は幻のエンディングだと思って忘れるとよいでしょう。


### PS追記

こんなんあったんか・・・
先走ってしまったので皆さんはきをつけてね。
https://qiita.com/advent-calendar/2020/yubaba
リスナーログのセグメント番号の上限を試す（Oracle Database 19c)

# リスナー・ログ
Oracle Database 19cから、リスナーのログファイルに自動ローテーション機能が付きました。この機能はデフォルトで有効になっています。ログファイルが一定サイズになると自動的に番号が付いたセグメント・ファイルが生成され、古いファイルを自動削除することができます。

```
$ cd $ORACLE_BASE/diag/tnslsnr/dbsrv-1/listener/trace
$ ls -li
total 2028
5796100 -rw-r-----. 1 oracle oinstall 529985 Nov 17 10:34 listener_1.log
6092293 -rw-r-----. 1 oracle oinstall 540743 Nov 17 10:38 listener_2.log
6092294 -rw-r-----. 1 oracle oinstall 540155 Nov 17 10:41 listener_3.log
6092295 -rw-r-----. 1 oracle oinstall 347884 Nov 17 10:43 listener.log
```

ファイル名の番号はalertディレクトリのXML形式のファイルにも付きます。

```
$ cd $ORACLE_BASE/diag/tnslsnr/dbsrv-1/listener/alert
$ ls -li
total 2028
5796100 -rw-r-----. 1 oracle oinstall 529985 Nov 17 10:34 log_1.log
6092293 -rw-r-----. 1 oracle oinstall 540743 Nov 17 10:38 log_2.log
6092294 -rw-r-----. 1 oracle oinstall 540155 Nov 17 10:41 log_3.log
6092295 -rw-r-----. 1 oracle oinstall 347884 Nov 17 10:43 log.xml
```


# 上限を探る
番号が大きくなった場合にどのような変化があるかを調査してみました。リスナーのパラメーターを以下のように設定します。

|パラメーター| 設定値| 説明|
|:---|:---|:---|
|LOG_FILE_NUM_listener|1|番号付きのセグメント・ファイルが１個だけ保存される|
|LOG_FILE_SIZE_listener|1|ログの最大値は1MB|

大量の接続リクエストを投入してローテーションを強制し、ファイル名の変化を確認しました。

## 16ビット
リスナーを停止し、ログファイル名を以下のように変更します。

```
$ cd $ORACLE_BASE/diag/tnslsnr/dbsrv-1/listener/alert
$ mv log_1.xml log_65534.xml
$ cd ../trace
$ mv listener_1.log listener_65534.log
$ lsnrctl start listener
```

ログの書き込みを続けると、あっさり16ビットの上限を超えました。

```
$ ll
total 1148
-rw-r----- 1 oracle oinstall 1048917 Nov 17 14:57 log_65537.xml
-rw-r----- 1 oracle oinstall   58895 Nov 17 14:57 log.xml
```
##32ビット
符号付き32ビットの上限である2,147,483,647に変更します。

```
$ cd $ORACLE_BASE/diag/tnslsnr/dbsrv-1/listener/alert
$ mv log_65537.xml log_2147483647.xml
$ cd ../trace
$ mv listener_65537.log listener_2147483647.log
$ lsnrctl start listener
```

ログの出力を継続すると、マイナスになりました。このことからセグメント・ファイルの上限は符号付き32ビットで保持していることがわかります。

```
$ ll
total 520
-rw-r----- 1 oracle oinstall 515830 Nov 17 15:02 listener_-2147483648.log
-rw-r----- 1 oracle oinstall   5430 Nov 17 15:02 listener.log
```

さらに負荷をかけていくと番号が大きくなっていきます。

```
$ ll
total 520
-rw-r----- 1 oracle oinstall 516499 Nov 17 15:04 listener_-2147483645.log
-rw-r----- 1 oracle oinstall   4465 Nov 17 15:04 listener.log
```

番号を-1に変更して再度テストを実施したところローテーションは行われなくなりました。

```
$ ll
total 2936
-rw-r----- 1 oracle oinstall  515920 Nov 17 15:06 listener_-1.log
-rw-r----- 1 oracle oinstall 2438590 Nov 17 15:10 listener.log
```

上記の結果からセグメント・ファイル番号の上限は ４ バイトの上限である 4,294,967,295 であるらしいことがわかりました。
配列の要素を置き換える【Swift 5】


こんにちは、@Zhalen です。

この```Extension```では、配列の指定した要素を、同じ型の要素に置き換えるだけの面白味のないメソッドを定義します。
お手軽にお使いください。

#Extension
```swift

//ReplaceMent
extension Array where Element: Equatable {
    mutating func replace(before: Array.Element, after: Array.Element) {
        self = self.map { ($0 == before) ? after : $0 }
    }
}
```
#Usage
###Ex1
```swift
var array: [Int] = [1, 2, 3, 4, 5]

array.replace(before: 1, after: 6)//１を６に置き換える

print(array)
//[6, 2, 3, 4, 5]
```