OmniAICreator/Qiita-1.07M huggingface dataset:
SourceTreeのカスタム操作でPowerShellコマンドを実行する

SourceTreeには「カスタム操作」という機能があります。
カスタム操作で[マージ済のgitブランチを一括削除](https://qiita.com/tak458/items/2fdd08ecb368bc4afd0c)したいのでやってみました。

# 前提

* SourceTree 3.3.6
* PowerShell Core 7
* [PowerShellでマージ済のgitブランチを一括削除 \- Qiita](https://qiita.com/tak458/items/2fdd08ecb368bc4afd0c) を設定済であること

# 設定方法

1. SourceTreeのメニューバーから ツール > オプション を開く
2. カスタム操作 タブに移動
3. 追加 ボタンからカスタム操作を以下のよう設定してOK

| 項目 | 設定値 |
|:---|:---|
|メニュー表示名|任意|
|別のウィンドウで開く|チェックしない|
|詳細な出力を表示|チェックする|
|バックグラウンドで実行する|チェックする|
|実行するスクリプト|PowerShellの実行ファイルへのフルパス|
|パラメータ|`-Command <コマンド文字列>`|

「別のウィンドウで開く」にチェックを入れるとカスタム操作が動かないバグがあるようです。
https://community.atlassian.com/t5/Sourcetree-questions/Custom-actions-no-longer-working/qaq-p/1219284

PowerShellの実行ファイルへのフルパスは以下のようになります。
C:\Program Files\PowerShell\7\pwsh.exe

パラメータに実際のコマンドを設定します。

```powershell
-Command Remove-GitBranchMerged $REPO
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/135280/a307f36b-2ba1-c5dd-1d9f-117b0da51903.png)

これで設定完了です。
Vue3 v-modelの仕様

v-modelに使用するデフォルトのprop名とイベントが変更になっています

## Vue2.x

```js:SomeComponent.vue
// valueのpropで受け取り
props: [value]
// onInputで返却
this.$emit('input', updatedValue)
```

```vue:
<some-component v-model="hoge" />
// ↑は↓と等価
<some-component :value="hoge" onInput="(val) => hoge = val"/>
```


## Vue3

```js:SomeComponent.vue
// modelValueのpropで受け取り
props: [modelValue]
// onUpdate:modelValueで返却
context.emit('update:modelValue', updatedValue)
```

```vue:
<some-component v-model="hoge" />
// ↑は↓と等価
<some-component :modelValue="hoge" onUpdate:modelValue="(val) => hoge = val"/>
```

### Vue3別例

```js:SomeComponent.vue
// modelValue以外もつかえる
props: [foobar]
// onUpdate:propnameで返却
context.emit('update:foobar', updatedValue)
```

```vue:
// modelValue以外のpropにv-modelで双方向バインドする場合は明示が必要
<some-component v-model:foobar="hoge" />
// ↑は↓と等価
<some-component :foobar="hoge" onUpdate:foobar="(val) => hoge = val"/>
```


ref https://github.com/vuejs/rfcs/blob/master/active-rfcs/0011-v-model-api-change.md
ソニーのミラーレスα6400で撮って出しのHDR動画をYoutubeで見れるようにして上げるまで(FFMpegのオプションの話)

主にffmpegの設定の話です。

今回ミラーレス一眼買いました。α6400です。
レンズはキットレンズはお勧めしないと言われたのもあって、思い切ってとがった物を選びSiruiの50㎜ F1.8 Anamorphicにしました。
今回はHDRが撮影できると言う事もあってα6400にした経緯もあり、さっそく試し撮りしてYoutubeにアップするまでを試してみたので、その備忘録です。
有料版ダビンチやAdobe製品を持っている方には特に必要ない情報かと思います。
## 目的
α6400はHDR動画をHLGで撮影しmp4で保存します。これをまずは撮って出しでYoutubeに投稿するにはどうすればいいのかを試しました。
また、アナモルフィックレンズなので、撮影後横に伸ばす必要があるので、これも一緒にやってしまいます

### PQで出す
アナモルフィックレンズでない場合は-aspect 24:10 -s 3840x1600の項は不要です。
```ffmpeg -y -i C0001.MP4 -aspect 24:10 -s 3840x1600 -c:v libx265 -tag:v hvc1 -crf 22 -pix_fmt yuv420p10le -x265-params "colorprim=bt2020:transfer=smpte2084:colormatrix=bt2020nc" C0001out.mp4```
上げた動画はこちら
https://youtu.be/uPuNuE5b0As
ゲームなどはこっちがHDR時に使う事が多い気がするので見慣れた感があります。Youtubeに投稿した所、HDRとして認識はされましたが、SDR環境で見る時に再生される、Youtube側で自動変換された動画のほうは色がつぶれて汚いですね。HDRモニタで見るとマシになりますが、潰れてる感じは少し残ります。
###HLGで出す
こちらもアナモルフィックレンズでない場合は-aspect 24:10 -s 3840x1600の項は不要です。
color_trc 18でHLGの指定となります。
```ffmpeg -y -i C0001.MP4 -aspect 24:10 -s 3840x1600 -c:v libx265 -tag:v hvc1 -crf 22 -pix_fmt yuv420p10le -color_trc 18 -color_primaries 9 -colorspace 9 C0001out.mp4```
上げた動画はこちら
https://youtu.be/N0Rkmyfb2Ho
こちらはSDRの方もHDRの方もPQに比べて潰れが少なく無難な形で見ることが出来ますが、悪く言えば少し眠い感じもします。グレーディングをしていない撮って出しの状態ですしこんなもんな気もします。
### 解像度について
アップロード要件に
```
720p、1080p、1440p、2160p
最適な品質で再生されるようにするため、DCI 規格ではなく UHD 規格を使用してください（例: 4096x1716 ではなく 3840x1600 のアスペクト比にする）。
```
とあったので3840*1600にしました。

### アップロードされた動画が意図したものか確認するには
動画を右クリックして、詳細統計情報をクリックします
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502600/e0e4d2f6-0223-672b-2e1a-723c8e0c3ede.png)
すると、画面右上にコーデックや色空間、色域など表示されます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502600/b9a343cf-3ca6-8d43-8fcb-b12ba23063e4.png)
注意点としてはHDR再生環境ではないモニタやブラウザで見る場合は自動変換された方の情報がでてしまうので、まずはちゃんとHDR有功になってるか確認した方がいいでしょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502600/05e1a35c-0dff-e5d4-899e-d83a29d8f769.png)


### 最後に
アップロード時にvp9に変換されてるみたいなので、最初からwebm/vp9で出した方が効率がいいかもしれません。
HDRに関してはまだまだ全然知識不足なので、突っ込みどころあれば教えて下さい。
余談ですが、以下の文言でYoutubeがこれらのアップロード時の変換にffmpegを使っていることを初めて知りました。
```TRC が FFmpeg の色空間変換フィルタでサポートされていない場合、YouTube は BT.709 に設定し直します。```
参考にあるエンコード設定の色空間の項より。

## 参考
オプションなど
https://developers.google.com/media/vp9/hdr-encoding
ハイ ダイナミック レンジ（HDR）動画をアップロードする
https://support.google.com/youtube/answer/7126552?hl=ja
エンコード設定
https://support.google.com/youtube/answer/1722171
yolov5の可視化プログラム目次

##はじめに
この個別のプログラムは標識検知と銘打っていますが,まだ外に持って行って実験できる器材の準備と諸々が実現されていないので今回は既存のモデルを使って可視化プログラムを実現しています.一応看板検知のためのモデルは作成してありますが,実現はしていませんのでご了承ください.
なお,プログラムコードをgithub上に公開しています.starを押してもらえるとやる気につながりますので合わせてお願いします.
https://github.com/S-mishina/Stop-sign-detection
##目次
⓵停まれの看板を検知する.
https://qiita.com/asmg07/items/8f450e1ae6e213890db9
⓶停まれ標識検知　可視化部分の開発part1 物体の検知と記録※今回は椅子を検出しています（モデルは自作ではありません）
https://qiita.com/asmg07/items/b0ab83d930adbed79df2
⓷停まれ標識検知　可視化部分の開発part2 物体を検知した時にソケット通信で別システムに知らせる
https://qiita.com/asmg07/items/7413b82117c629b73719
④停まれ標識検知　可視化部分の開発part3 物体を検知した時にソケット通信を使って音声で知らせる
https://qiita.com/asmg07/items/0b1361cff76fc93962a1
⑤停まれ標識検知　可視化部分の開発part4 物体を検知した時にソケット通信を使って音声で知らせる(複数編)
https://qiita.com/asmg07/items/a45c663e44c6d45f6dc6
⑥停まれ標識検知　可視化部分の開発part5 物体を検知した時に検知したものを検知したものを表示する
https://qiita.com/asmg07/items/d76625881db30d5b79ea
停まれ標識検知　可視化部分の開発part5 物体を検知した時に検知したものを検知したものを表示する

##前回まで
前回実装した機能は以下のものになります.
Yolov5上で物体を検知した時➡ソケット通信をする.➡ソケット通信を受けたときに音声を再生する.（複数）
##今回実装する機能
今までの実装で,音での可視化は可能でしたが実際のものを可視化することはできませんでした.
逆にカメラ映像を見ていればわかるだろという話もありますが...なので今回はあまり意味がないと思われる方もいる機能かもしれませんが,認識したものを可視化するプログラムについて述べていきたいと考えています.
##なぜこの機能を実現するのか
これは後々web上での可視化を行いたいと考えているので,その時にソケットで飛ばせるようにこの機能を実現しました.
##実装について
今回はソケット通信の部分を関数化したのでそこについてもちらっと載せていきます.内容はpart3とかpart4とかで書いています.
###socket部分
クライアント部分

```detect.py
def socket1():
    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s2:
                         s2.connect(('127.0.0.1', 50007))
                         BUFFER_SIZE=1024
                         data1='1'
                         s2.send(data1.encode())
                         print(s2.recv(BUFFER_SIZE).decode())
```
ここの関数は認識するものが増えたらsocketの後の数字だけ増やしてdata='1'の部分の数字を変えることで認識するものが増えても対応できます.

```server.py
# socket サーバを作成
from playsound import playsound
import socket
cont=1
# AF = IPv4 という意味
# TCP/IP の場合は、SOCK_STREAM を使う
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
    # IPアドレスとポートを指定
    s.bind(('', 50007))
    # 1 接続
    s.listen(1)
    # connection するまで待つ
    while True:
        # 誰かがアクセスしてきたら、コネクションとアドレスを入れる
        conn, addr = s.accept()
        with conn:
            while True:
                # データを受け取る
                data = conn.recv(1024)
                if not data:    
                    break
                else:
                 data2=str(data)
                 data3=(data2.replace('b', ''))
                 conn.sendall(b'Received: ' + data)
                if data3 == "'1'":
                        playsound('2.wav')
                if data3 == "'2'":
                        playsound('3.wav')
```
認識部分

```detect.py
                    if label1=="cell phone":
                     print("スマホを発見しました")
                     cv2.imwrite('sumaho.jpg',im0)
                     img = cv2.imread('sumaho.jpg')
                     cv2.imshow('sumaho', img)

                     socket1()
                     with open('daystext/'+str(d_today)+'.txt', 'a') as f:
                         dt_now = datetime.datetime.now()
                         f.write(str(dt_now)+"スマホを発見しました"+"\n")
                    if label1=="book":
                     print("本を発見しました")
                     cv2.imwrite('book.jpg',im0)
                     img = cv2.imread('book.jpg')
                     cv2.imshow('book', img)
                     socket2()
                     with open('daystext/'+str(d_today)+'.txt', 'a') as f:
                         dt_now = datetime.datetime.now()
                         f.write(str(dt_now)+"本を発見しました"+"\n")
```
サーバ部分はdata3="'1'"の数字の部分を変えてif文を増やすことで対応できます.
###可視化部分
```
                     img = cv2.imread('sumaho.jpg')
                     cv2.imshow('sumaho', img)
```
このコードをif label1=="":後に埋め込むことで実現できます.

##最後に
今までpart5まで書いてきて録画機能以外はyolov5で実現したい機能をほぼ実現してきましたのでとりあえずyolov5部分を終了にしたいと思います.次は可視化web部分を作っていけたらいいなと思っています.
もしなんか実現できそうな機能を思いついたらこの記事を書きますので連続投稿はこれで終了になります.
rails 新規アプリケーション立ち上げコマンド

#Ruby on Railsでの新規アプリケーション立ち上げ方法
###自分に向けて記憶の範囲内だけでアウトプットします！
###①
```java:ターミナル
rails _6.0.0_ new test -d mysql
```
###②
```java:ターミナル
rails db:create
```
###③
```java:ターミナル
rails g model test
```
###④
```java:db/migrate/2020・・・・・
t.string :name, null: false　(ここの行の記述は適当)
```
###⑤
```java:ターミナル
rails db:migrate
```
###⑥
```java:config/routes.rb
root to tests#index (ここの行も適当)
```
###⑦
```java:ターミナル
rails g controller tests
```
###⑧
```java:app/controller/tests.controller.rb
def index
  @tests = Test.all
end
```
###⑨
```java:database.yml
utf8○○・・・の箇所をutf8のみにする
```
###⑩
```java:app/views/index.html.erb
ここにHTMLを記述する
```
#以上！
##ここまで全て記憶内で書いてみました。足りないところや間違っているところもあると思いますが、私自身は間違っているところがあればエラー見ればわかるのでこれを参考にする方は100%信じきらないでください！
##現場からは以上です！
XMOSに書き込まれたイメージのバックアップ

# はじめに
USBオーディオインターフェース（or USBDDC）によくXMOSチップが搭載されていることがあります。
XMOSとは大雑把にいうと、FPGAのような論理回路の動作をxC言語と呼ばれる組込みソフトウェアで制御する独自のデバイスです[^whatsxmos]。

こうしたオーディオインターフェースの中に、基板にXSYS端子と呼ばれる書き込み用のコネクタが出ていたりするものがある[^subst]ので、ちょっといじって遊んでみたくなりました[^except]。

しかしプログラムはチップに上書きする形になるため、もとのプログラムが消えてしまいます（実際にこれで100ドルの基板をただのガラエポ板にしてしまうところでした！）。そこであらかじめ回路情報をバックアップする方法と、再書き込みして復元する方法を調査しましたので備忘録がてら残しておきます。

※基本的にネット上にフリーで転がっている情報のまとめに過ぎませんが、
　バックアップしたイメージの取り扱いなど、知的財産的な問題が生じないようご留意ください！！
　（自己責任でお願いします）


## 用意するもの／こと
* XSYSコネクタの搭載されたXMOS搭載基板
* [xTAG](https://www.digikey.jp/product-detail/ja/xmos/XA-XTAG/XA-XTAG-ND/2183686) : 　基板のXSYSコネクタに接続します。
* xTAGが使用できるように、xTimeComposer（開発環境）のインストール
* [USB Audio Software Design Guide](https://www.xmos.ai/file/usb-audio-software-design-guide/?version=latest) を参考に、ざっくり書き込み方法を理解

XMOSプログラミング自体に関しては勉強不足かつ本稿の趣旨と離れる上、
[こちら](https://www.xmos.ai/download/XMOS-Programming-Guide-(documentation)(F).pdf)　に詳細な記述がありますので割愛します。

## 手順
xflash コマンドを使用します。
既存のプログラム情報を.binファイル形式で吸い出し、これを再度書き込むことで復元が可能でした。
当たり前ですが吸い出したバイナリファイルを別の型番のXMOSチップに書き出すことはできません。
吸い出し／書き込みともに時間がかかります（10分以上でした）ので気長に待ちましょう。

### 対象XMOSの型番を確認
記載があればもちろんそれを参考にすればよいですし
分からなければチップ表面の記載を見ます。
例えば　``U11692C20``　といった記載があります。

こちらを検索することで、当該XMOSが
``XUF216-512-TQ128-C20``　であることがわかります。


### プログラム吸い出し
xTAGをXSYS端子に、USBコネクタをPCに接続。対象のXMOS基板にも電源を入れます。
xTIME Composer Command Promptから下記を実行します。
targetオプションには、下記例のようにサポートされている石の型番を直接書いてもよいですし、
.xnファイルの場所を直接指定することもできるようです。

```shell:「XUF216-512-TQ128-C20」の場合の例
xflash --read-all -o out.bin --target XUF216-512-TQ128-C20
```

out.binがバックアップするファイルになりますので、適切に保存しておきましょう。

### プログラム書きこみ
```shell:「XUF216-512-TQ128-C20」の場合の例

xflash --write-all out.bin --target XUF216-512-TQ128-C20
```

# 参考
似たようなことをやっている人がいました。
[read/write flash on XUF216 chip] (https://www.xcore.com/viewtopic.php?t=6204)
[trying to backup XU216-512-TQ128-C20]
(https://www.xcore.com/viewtopic.php?t=3530)

[XMOSによるUSB Audioの詳細について]
(https://www.xmos.ai/usb-multichannel-audio)



[^except]: 入出力を増やしたり、外部のペリフェラルを制御したりなどいろいろなことができそうです。

[^subst]: たとえば、DIYINHK社のUSBDDCモジュールが挙げられるでしょう。一時話題になった[こういうXMOS開発基板](https://www.mi-take.biz/system72/DAC_2/XMOS/XMOS_USB20Audio.html)にXMOS社から提供される USB Audio 2.0 Reference Design等（[配布サイト](https://www.xmos.ai/usb-multichannel-audio/)) を書き込むことでUSB DDCとして使用可能になるものもあります。

[^whatsxmos]: ジャンル分けするとしたらPLD（Programmable logic device）の一種となるようです。
postgresqlでテーブル作成時にシーケンスを自動作成する

# はじめに
quita初投稿です。
これから日々業務で学んだことを忘れないようにアウトプットしていく場として、活用いきたいとい思います。
現在業務でpostgresqlを使用しているため、業務上で経験したことを記載します。

## 環境
- postgresql 9.6
- windows10

### やり方
postgresqlでは、データ型に `連番型` が存在するので、テーブル作成時に指定することで、対応するシーケンスオブジェクトを自動で生成してくれる。

実際のCREATE文

```sql
CREATE TABLE sample(
  sample_id SERIAL NOT NULL,
  sample_name varchar(20)
  PRIMARY KEY(sample_id)
);
```
MySQLでいうとことの、`AUTO_INCREMENT`属性に近いかと思います。

CREATE文でSERIALを指定しない場合
予めシーケンスオブジェクトを作成しておいた状態で、CREATE文にシーケンスオブジェクトを指定できる。

```sql
CREATE SEQUENCE sample_sample_id_seq;
CREATE TABLE sample (
    colname integer DEFAULT nextval('sample_sample_id_seq') NOT NULL,
    sample_name varchar(20)
    PRIMARY KEY(sample_id)
);
```
[AWS認定SAP] Bastionサーバー

# Bastionサーバーって何？

AWS認定SAPの取得に向け勉強している最中出てきました。
とりあえず何も考えず翻訳すると以下のとおりです。

####Bastion：要塞

・・・・要塞サーバー？？

調べました。

「踏み台サーバー」のようです。
なんでこんな訳し方されているのかわかりませんが、踏み台サーバーのことのようです。

外部から直接アクセスできないプライベートサブネット内のサーバー（A）に対して接続する際に活躍します。

外部へのルートを持つルートテーブルを割り当てたパブリックサブネット内にBastionサーバー（B）を構築しておきます。

（A)に接続するには先に（B)に接続し、（B)からRDPなりSSHなりで（A)に接続します。
※（A)と（B）は同一VPCを想定しております。

（踏み台サーバーなので、絶対にパブリックサブネットに構築する必要があるわけでもないと思います。）

#終わりに
踏み台サーバーなら分かったのですが、SAPの練習問題では「Bastionサーバー」という表現で出題されました。
SAAでも出てきそうな表現ですが、一度も見ませんでした。。。
メモ代わりに投稿しておきます。

###Bastionサーバー＝踏み台サーバー

（参考）
[【VPC】踏み台サーバーを考える](https://blog.serverworks.co.jp/tech/2019/08/21/thinkbastion/)
UWSCで作業を効率化しよう【マウス操作 超基本編】

今回はスクリプトからマウスの操作をする「超基本的」な方法を紹介したいと思います。
また、UWSCでは画面の原点の位置が左上になるので真ん中を原点の座標と勘違いしないように注意しましょう。

# マウスカーソルの移動
カーソルの移動ではMMVと言う関数で行います

```
MMV( 画面のx座標, 画面のy座標 )
```

このような感じですね。

もし、（114, 514）と言う座標にカーソルを移動させたいなら

```
MMV( 114, 514 )
```

と言う風に書きます。

# マウスのクリック

マウスのクリックではBTNと言う関数で行います

```
BTN( ボタンの種類, 押し方,  画面のx座標, 画面のy座標 )
```
このような感じですね。

ボタンの種類は色々あるのですが自分がよく使うのは以下の種類です。

- LEFT
  - これは左クリックを押してほしい時に利用します
- RIGHT
  - これは右クリックを押してほしい時に利用します
- MIDDLE
  - これは真ん中のボタン(スクロールボタン)を押してほしい時に利用します

また押し方も色々ありますが基本的な3種類を紹介します。

- CLICK
  - これは1回だけクリックしてほしい時に利用します
- DOWN
  - これはクリックし続けてほしい時に利用します
- UP
  - これはボタンを離してほしい時に利用します

なので、（ 100, 200 )と言う座標を左クリックさせたいなら

```
BTN( LEFT, CLICK, 100, 200)
```
と書き

シンプルにその場をクリックだけさせたいなら

```
BTN( ボタンの種類 )
```
と書くこともできます。

# まとめ
これでマウス操作の基本的な操作ができるようになってできることが増えたんじゃ無いでしょうか？？

また、基本ばかりですが今回の内容だけで移動、クリックだけでなくドラッグ&ドロップのような操作もできると思います。
PCの開発環境で作ったWEBアプリをスマホでも確認する方法

最近個人開発アプリのレスポンシブ化を行いました。
デベロッパツールでも見れますが、実機でもちゃんと表示されるか確認したいですよね。そんな時に手軽にスマホアプリでも確認する方法を共有させて頂きます。

【環境】

- windows10 Pro
- Rails: 6.0.3.2
- ruby: 2.7.1p83 (2020-03-31 revision a0c7c23c9c) [x86_64-linux]
- Docker for windows
- MySQL 5.7
- nginx:1.15.8

##手順
まず、PCとスマホを同じWiFiに繋ぎます。

その後、**Windowsキー+R**を押し、**cmd**と入力します。
コマンドプロンプトを開くので、**ipconfig**と入力しエンターを押します。

```
イーサネット アダプター VirtualBox Host-Only Network:
(省略)
イーサネット アダプター VirtualBox Host-Only Network #2:
(省略)
イーサネット アダプター vEthernet (Extarnal Virtual Switch):

接続固有の DNS サフィックス . . . . .: flets-west.jp
IPv6 アドレス . . . . . . . . . . . .: 240xxxxxxxxxx
一時 IPv6 アドレス. . . . . . . . . .: 240xxxxxxxxxxxxxxxx
リンクローカル IPv6 アドレス. . . . .: xxxxxxxxxxxxxxxx
IPv4 アドレス . . . . . . . . . . . .: 192.168.1.193//この部分を覚えておく
サブネット マスク . . . . . . . . . .: xxxxxxxxxxxxxxx
デフォルト ゲートウェイ . . . . . . .: xxxxxxxxxxxxxxxxxxx
```
入力すると↑のように色々でてきますので、**おそらくですが、仮想環境にDockerを使っている場合、イーサネット アダプター vEthernet (Extarnal Virtual Switch)と書いてある欄のIPv4のIPアドレスをスマホのブラウザから入力するとアクセスできる**と思います。
（例：3000番ポートを開放している場合、http://192.168.1.193:3000/ とすると、PCの開発環境にアクセスできます。）

開発環境が違う場合、他のIPアドレスを入力する必要があると思いますので、適時つながるアドレスを見つけてください！

##最後まで読んでいただきありがとうございます！
このように日々学んだことをアウトプットしてます！少しでも皆様のお役に立てれば幸いです！ご指摘などあればコメントいただけますと嬉しいです！
AtCoder 生活　96日目

[前回](https://qiita.com/flandrescarlet237/items/fd631c9bd752759fbded)

#96日目
今回はABC179のA〜C問題をときました。

|問題|難易度|自力で解けた|かかった時間|
|:-:|:-:|:-:|---|---|
|ABC179|A|◯|2分59秒|
|ABC179|B|◯|3分59秒|
|ABC179|C|◯|10分38秒|


##[ABC179](https://atcoder.jp/contests/abc179)

###A

```c++

#include <bits/stdc++.h>
#define rep(i,n) for(int i = 0;i < (n);i++)
using namespace std;
using ll = long long;
using pii = pair<int,int>;

const int INF = 2e9;

int main(){
    string s;
    cin >> s;
    int m =s.length() - 1;
    if(s[m] == 's') cout << s << "es" << endl;
    else cout << s << "s" << endl;
}

```

解くのにかかった時間：2分59秒

###B

```c++

#include <bits/stdc++.h>
#define rep(i,n) for(int i = 0;i < (n);i++)
using namespace std;
using ll = long long;
using pii = pair<int,int>;

const int INF = 2e9;

int main(){
    int n;
    cin >> n;
    int cnt = 0;
    rep(i,n){
        int a,b;
        cin >> a >> b;
        if(a == b)cnt++;
        else cnt = 0;
        if(cnt == 3){
            cout << "Yes" << endl;
            return 0;
        }
    }
    cout << "No" << endl;
}

```

解くのにかかった時間：3分59秒

###C

```c++

#include <bits/stdc++.h>
#define rep(i,n) for(int i = 0;i < (n);i++)
using namespace std;
using ll = long long;
using pii = pair<int,int>;

const int INF = 2e9;

int main(){
    int n;
    cin >> n;
    int cnt = 0;
    for(int i = 1;i < n;i++){
        for(int j = 1;j < n/i+1;j++){
            if((n-i*j) > 0)cnt++;
        }
    }
    cout << cnt << endl;
}

```

解くのにかかった時間：10分38秒

###最後に
最近全探索の存在を忘れかけていたのでC問題がちょうどよかった。
[OutSystems]Downloadでブラウザ内にダウンロードしたファイルを表示する

Webアプリケーションからファイルをダウンロードするときに、ローカルに保存する代わりに同じブラウザのタブにコンテンツを表示する方法を検討してみます。

# 環境
Personal Environment(Version 11.9.0 (Build 16900))
Service Studio(Version 11.8.9)

テストには以下の2種類のブラウザを使いました。ブラウザや設定によっては動作が異なるかもしれません。

- Chrome Version 85.0.4183.102 (Official Build) (64-bit)
- Edge バージョン 86.0.622.38 (公式ビルド) (64 ビット)

# テストに使うPDFファイルを準備
Resourcesに以下のようにPDFファイルを登録します。
（dummy.pdf）
![qDownload1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332987/3847097f-1df4-b9db-b151-591040917f32.png)

# Traditional Webの場合
## Downloadを使った実装方法
Action Flowt中にDownloadを置いて以下のように設定すると、対象ファイルを同じタブに開きます。
![qDownload2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332987/f5218705-e952-43c0-603b-1d362ad8b79b.png)

Save to DiskプロパティをNoに設定することでブラウザ内にファイルが表示されるように。
ファイルは、Downloadを実行したタブ内に表示してしまうので、

- Screenを作成し、Preparationでこの処理を実行する
- 別の画面のリクエストで作成したScreenを新しいタブに開く

とするとよさそうです。

## 通信内容をチェック
Save to Disk = NoのDownloadを実行すると、HTTP Responseのヘッダーに以下の行が設定されます。

``` 
content-disposition: inline; filename="dummy.pdf"
```

このレスポンスはまさに（OutSystemsとは無関係に）PDFをブラウザ内に表示させるための指示のようです。Qiita内にこの点を説明している投稿がありました。
[PDFをブラウザで表示](https://qiita.com/horikeso/items/31927d28289ef54653dd)

# Reactive Web Appの場合
## Downloadに設定箇所がない……
Reactive Web AppのDownloadのパラメータは以下のようになっています。
Save to Diskプロパティがありません。
![qDownload3.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332987/a577377c-3a8b-d514-d218-5704a49f4418.png)

このまま実行してみると、ファイルを保存するダイアログが出てきて、タブ内に表示はできないようです。

## Downloadの実装をチェック
Chromeの検索機能を使って、上記Downloadの処理を追ってみましょう。
Downloadの部分で実行しているJavaScriptは以下の通り。ちなみにこの時点で、Server Actionへの通信（PDFの中身のダウンロード）は終わっています。

``` JavaScript
OS.Controller.BaseViewController.downloadBinary(downloadPdfVar.value.pdfBinaryOut, "dummy.pdf");
```
この関数の実体は同じくソースを検索してみると、見えないリンク(Aタグ)を作成し、JavaScriptからクリックさせてファイル保存させているようです。

``` JavaScript
BaseViewController.downloadBinary = function (content, filename) {
    var blob = content.toBlob() || new Blob([]);
    var link = document.createElement("a");
    link.style.display = "none";
    document.body.appendChild(link);
    if (blob.type) {
        link.type = blob.type;
    }
    var url = window.URL.createObjectURL(blob);
    link.href = url;
    link.download = filename;
    link.click();
    setTimeout(function () { return window.URL.revokeObjectURL(url); }, 500);
    link.remove();
};
```

## Reactive Web Appでブラウザ内にファイル表示するには
残念ながら、デバッガでlink.target = "_blank"にしてもブラウザ内にファイル表示してくれませんでした。それに、せっかくLow-Code製品を使っているのに、あんまり無理やり製品内の動作を上書きするような変更をしたくないですね。

そこで、どうしてもブラウザ内にファイル表示をさせたければ、

1. Traditional Webで別のモジュールを作成
2. Screenを作成し、PreparationでSave to Disk = NoのDownloadを配置する
3. Reactive Web Appから新しいタブで↑のScreenを表示する

という感じでどうでしょうか。セキュリティや業務ロジックのチェックはお忘れなく。
UWSCで作業を効率化しよう【エディタ設定編②】

今回は前回の続きでカラー設定ファイルの導入と入力補完をやっていこうと思います。

前回の記事をまだ見ていない方は[こちら](https://reishisu.xyz/?p=26)を先に見ることをお勧めします。

# カラーの設定ファイルを導入しよう！(2022/6/5 修正)

0. まずは、[こちら](https://drive.google.com/file/d/12d5QZp1PqKN4nJDEy_u48GHy9cX-qDy4/view?usp=sharing)をクリックし、GoogleDriveから設定ファイルをダウンロードしましょう。

1. 「Ctrl + 4」を押し「UWSC」にカーソルを合わせて「設定変更（S）」を押しましょう。  
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241870/317007b0-daab-e62d-e03a-5bb0216a8130.png)
2. 続いて「カラー」タブから「インポート（I）」ボタンを押しましょう。  
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241870/e7c68a94-c85c-f227-5002-28f9483a8804.png)
3. すると、ファイルを選ぶ画面が出てきますので先ほど準備したファイルを選択して「開く（O）」を押しましょう！
4. そのまま画面を閉じずに次の↓の設定に行きましょう！

※インポートの際に、エラーが出る場合は[こちら](https://techtech-note.com/820/)の方法で、ダウンロードした設定ファイルをエクスポートしたファイルにコピペして上書きしなおすと良いかもしれません。

# コメントと文字列エスケープの設定をしよう！

1. 「コメントスタイル」のところの「ブロック型（F）」に「TextBlock」その右の「～（T）」に「EndTextBlock」を入力しましょう。
2. 続けてその下の「行型（M）」の所に「//」を入力しましょう。
3. そして、その下にある「文字列エスケープ（Q）」を「PL/SQL風 “”」に変更しましょう！
4. 画像と同じ設定になっていればそのまま「OK」を押しましょう。  
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241870/a86c18d4-199f-be45-9e64-d445708148e6.png)
5. そして、「Ctrl + 4」を押して、「UWSC」を選択した状態で「一時適用（R）」を押してエディタ画面が黒くなったら成功です！！  
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241870/e181201a-34bb-d025-37a8-d0e25587f05c.png)

# 設定ファイルを準備しよう！(2022/6/5 修正)

1. まずは、[こちら](http://siromasa.html.xdomain.jp/uwsc/u_term/31_SakuraEdita/uwsc_sien.txt)をクリックしましょう。
2. ブラウザにいっぱい文字が出てきますのでそれを全部コピーしましょう！  
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241870/804366f7-0591-092f-4aa2-67a052e3c655.png)
3. コピーしたものをエディタに張り付けましょう！  
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241870/06c06806-6dfa-bc79-6ffc-d7dc971a2393.png)
4. そして、張り付けたものを任意の場所に保存しましょう！(拡張子は.txtで)  
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241870/3d0af10e-3c7c-a85f-b62c-80a9e09bccb3.png)

# 入力補完の設定をしよう！

1. まずは、「Ctrl + 4」を押し「UWSC」にカーソルを合わせて「設定変更（S）」を押しましょう。  
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241870/a48d8d1b-ac42-231c-bd8e-75fc548578ee.png)
2. 続いて「支援」タブから「入力補完機能」の「(1)…」と書かれたボタンを押して先ほど作成した入力補完のテキストファイルを選択しましょう。  
3. そしてその下の３つのチェックボックスに全部チェックを入れて画像と同じになっていれば「OK」を押して終了です！！  
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241870/8decac1e-fcac-1d9c-4709-d48a02a2a99e.png)

# ちゃんと設定できているか確認しよう！！

1. まずは「Ctrl + 4」を押して、「UWSC」を選択した状態で「一時適用（R）」を押して適用させてあげましょう！
2. 続いてエディタで「pri」まで入力して「Ctrl + スペース」を押すと入力補完の画面が出てきていたら成功です！！  
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241870/ade18ed1-aec8-e4c7-3580-c3d247bac7fa.png)
3. お疲れ様でした！！

今回でエディタ設定編は終了です！
次回からは、やっとコードの紹介などをやっていこうと思います！！
if文で論理演算子をたくさん使いたいの巻

#はじめに
　本日学んだ、if文で条件を重ねたいときに、論理演算子をどう使うかについてまとめる。

##論理演算子
&&→かつ
例

```ruby
if a && b
#処理
end
```

aとbの両方がtrueのとき、処理が実行される。

||→または
例

```ruby
if a || b
#処理
end
```

aかbのどちらかがtrueであれば処理が実行される。

`!a`
trueとfalseが反対になる。
例

```ruby
if !a
#処理
end
```

aが本当はfalseだと、処理が実行される。(falseがtrueに変わるため)

##複数の論理演算子をif文で使う

簡単に言ってしまえば、(  )を使って、まとまりを括る。

例

```ruby

if ( a && b ) || ( !a && !b )
#処理
end
```

||があるため、左辺か右辺がtrueであれば、処理が実行される。
左辺は「aかつbがtrue」であれば、左辺全体としてtrueになる。
右辺は「aかつbが本当はfalse」であれば、右辺全体としてtrueになる。
要は、<font color=red>aとbがtrueかfalseで一致してれば、処理が実行されるというコード。</font>

##さいごに
高校の数Aでやったような内容だなぁ…
swagger.yamlから、Pythonで、APIリスト.csvを作成してみました

# 環境構築
ついでに、初めてQiitaで記事を書いてみました。

### 前提
MacBook Pro
macOS Catalina 10.15.7

### 導入
下記をインストールしました。

1. Docker
* Visual Studio Code
* Visual Studio Code 拡張機能
    1. Japanese Language Pack
    * Docker 1.6.0
    * Remote - Containers 0.145.0
    * Python
    * PyLint
    * Rainbow CSV 1.7.1
    * YAML 0.11.1
    * Swagger Viewer 3.0.1
    * OpenAPI (Swagger) Editor 3.7.0

参考：

* [開いているWebページへのリンクをMarkdown形式でコピーするブックマークレット - Qiita]( https://qiita.com/vmmhypervisor/items/099582feb9f9615c5b8b )
* [VMではなくDockerでPython開発環境を作成する方法[Mac] | Laplace]( https://laplace-daemon.com/create-development-environment-by-docker/ )

### 設定

1. VS Code 同期設定の有効化
* 作業フォルダ作成 （dropbox内に作成しました）
* VS Code で作業フォルダを開く

# 作業

1. Github でレポジトリ作成
1. 手元で、[microsoft/vscode-remote-try-python]( https://github.com/microsoft/vscode-remote-try-python )をコピー（git clone）
1. フォルダ名と、git remote set-urlでremote 宛先を自分のレポジトリに変更
1. 


### エラー対応
ライブラリのインストールや、Jupiterの利用で、エラーが出たため、
ひとまず、ユーザーをrootのままとするようなコメントアウトを行いました。

### ライブラリインストール

PyYAMLライブラリ,CSVライブラリを使います。
requirements.txtに書いて、Rebuild And Rerunするだけなのでとても簡単で素晴らしいです。

```text:requirements.txt
flask
pyyaml
csv
ipykernel
```


### コーディング
yamlを開いて、
順繰りにCSVに書き込みたい内容を収集し、
CSV保存して
完了です。

yamlが辞書型というもので読み込まれるので、
欲しい条件に合致するようにループと変数取得を記述する所がポイントでした。

```python:open-api-yaml-to-csv.py
import yaml
import csv

# yamlファイルのコンテンツを、辞書型の変数に格納
with open("oidc-swagger.yaml", "r") as yf:
    data = yaml.safe_load(yf)

# 辞書内から、必要な情報を抽出し、配列として格納
api_list_array = []
i = 0
api_list_array.append(["#", "operationId", "METHOD", "PATH"])
for path in data['paths'].keys():
    if path != "/swagger":
        for verb in data['paths'][path].keys():
            # if 'operationId' in data['paths'][path][verb]:
            name = data['paths'][path][verb]['operationId']
            i = i+1
            # print(i,name, verb, path)
            api_list_array.append([i, name, verb, path])

# 配列をCSVとして保存
with open('list.csv', 'w') as csvfile:
    writer = csv.writer(csvfile)
    writer.writerows(api_list_array)
```


以上、初投稿でした。環境構築部分は苦労したので、もう少し書き足そうと思います。
【Java】コレクションクラスのSet構造(HashSetとTreeSetについて)

#プログラミング勉強日記
2020年10月15日
JavaでTreeSetを使ったが、HashSetとの違いがよくわからなかったので、記録する。

#コレクションクラスとは
　コレクションは要素を集めたオブジェクトのこと。コレクションクラスは大きく分けてList,Map,Setの3つの種類がある。それぞれ性質の異なるクラスに分かれている。

　List構造はArrayListとLinkedListの2種類ある。List構造は要素を順番付けして管理する構造で、要素はインデックス番号順に並んでいるので、番号を指定して要素の取得や挿入、更新、変更などができる。

　Map構造はHashMapとTreeMapの2種類ある。Map構造はキーと値をセットにしたものを1つの要素として管理するデータ構造で、要素がキーとして管理されているのでキーを指定して値の更新や削除をお来ぬことができる。
　今回扱うHashSetとTreeSetは名前からもある通りSet構造であり、下記にまとめる。

#Set構造のコレクションクラスとは
　Set構造はHashSetとTreeSetの2種類あり、要素を順番付けしないで管理するデータ構造である。Listのような順番付けやMapのようなキー管理もないので要素の取得にはIteratorや拡張for文で取得する。<b>要素の重複はできない</b>(同じキーがセットされた場合は上書きする。)
　HashMapとTreeSetの違いを簡単にまとめると以下のようになる。

- HashMapは取得順は関係ない
- TreeSetはソートされた順で要素の取得ができる
- HashMapはnullを扱えない
- TreeSetはnullを扱える

　HashMapは要素の取得順は保証されないが、TreeSetは自動ソートされて管理されるのでソートされた順番で要素が取得できる。また、HashMapは要素にnullを使用することができるが、TreeSetはnullを使用することができる。


#まとめ
　Set構造だけでなくコレクションクラスの特徴を表で簡単にまとめる。

| | ArrayList | LinkedList | HashMap | TreeMap | HashSet | TreeSet
|:--:|:--:|:--:|:--:|:--:|:--:|:--:|
| インタフェース | List | List | Map | Map |Set |set
| 要素の重複 | 〇 | 〇 | × | × | × | × |
| nullの要素 | 〇 | 〇 | 〇 | × | × | × |
| 自動ソート | × | × | × | 〇 | 〇 | 〇 |

　上では述べていないが、ArrayListはよその取得が早いが、挿入や削除が遅く、LinkedListは要素の挿入や削除は早いが取得は遅いという特徴がある。


#参考文献
[TreeSetクラス](https://java-reference.com/java_collection_treeset.html)
[コレクションクラスの比較](https://java-reference.com/java_collection_compare.html)
【AWS初学者用】AWS Auto Scalingとは

# 本記事について
本記事はAWS初学者の私が学習していく中でわからない単語や概要をなるべくわかりやすい様にまとめたものです。
もし誤りなどありましたらコメントにてお知らせいただけるとありがたいです。

## Auto Scalingとは
AWS Auto ScalingとはAWSが提供するリソースの使用状況に応じてインスタンスを自動的に増減させる事(スケールアウト・スケールイン)ができるサービス。なお、異常なインスタンスやAZを切り離すことも可能とのことです。

Auto Scalingの対象となるリソースはいくつかあるみたいですが,今回はEC2にAuto Scaling(EC2 Auto Scaling)を使用することを前提として進めます。
補足としてAuto Scalingは**AMIからEC2インスタンスを起動するので、AMIは常時最新の状態にしておきましょう**。

以下はAuto Scalingを実行するにあたっての3つの設定です。

## スケーリングプラン
Auto Scalingを実行するためにどんな条件・タイミングで実行するかを設定します。

- Cloud Watchのメトリクス(CPUの使用率など）に応じて実行する  
  アクセスの増減が予測できない時に有効
- スケジュールを指定して実行する  
  決まった時間にアクセスが集中するとわかってる場合に有効
- 手動でスケーリングを実行する　　
  高負荷バッチ処理の予定がある時に有効。

## 起動設定
Auto Scaling実行時にどのようなEC2インスタンスを起動するかを定義します。
定義する項目としては
- AMI
- インスタンスタイプ
- セキュリティグループ
- キーペア
- IAMロール

があります

## Auto Scalingグループ
EC2のインスタンスの管理を行う範囲のこと。インスタンス数の最小限・最大限を定義します。
要するにインスタンス数のコントロールができる感じですね。


## メリット
Auto Svalingはリソースの使用状況をモニタリングし、その使用状況に応じてEC2インスタンスを自動で増減するので常に理想のパフォーマンスを維持してくれる便利なサービス。
しかも従量制なのでコストも無駄なく利用できます。

## まとめ
ELBと連携して利用することでセキュリティもパフォーマンスも向上する優れもの！
【NGXS】ネストした状態の部分更新を簡潔に書く（patch state operator）

下記のような型の状態を管理するNGXSのStateを考える。

```ts
export interface PersonStateModel {
  name: {
    firstName: string;
    lastName: string;
  };
  age: number;
}

```

`firstName`だけ更新するコードを書こうとすると、ネストが2階層なのでctx.patchStateでは意外とシュッと書けない

```ts

export class UpdatePersonFirstName {
  static readonly type = 'Update person';
  constructor(public payload: string) {}
}

@State<PersonStateModel>({
  name: 'person',
  defaults: {
    name: {
      firstName: 'Taro',
      lastName: 'Yamada',
    },
    age: 20;
  }
})
@Injectable()
export class PersonState {
  @Action(UpdatePersonFirstName)
  updatePersonFirstName(ctx: StateContext<PersonStateModel>, { payload }: UpdatePersonFirstName) {
    ctx.patchState({
      name: {
        ...ctx.getState().name,   // ここがなんとかできないか？
        firstName: payload
      }
    });
  }
```

# State Operatorの「patch」を使うと…
```ts
@Injectable()
export class PersonState {
  @Action(UpdatePersonFirstName)
  updatePersonFirstName(ctx: StateContext<PersonStateModel>, { payload }: UpdatePersonFirstName) {
    ctx.setState(
      patch({
        name: patch({
          firstName: payload
        })
      })
    });
  }
```

ネストさせられるので、name.firstNameだけ更新されるという意図が明確になって良いのではないかと思います。

# 参考
- [State Operators - NGXS](https://www.ngxs.io/advanced/operators)
- [patchState vs. patch state operator : NGXS](https://www.reddit.com/r/NGXS/comments/bwprhu/patchstate_vs_patch_state_operator/)
rails db:migrateでエラー（StandardError: An error has occurred, this and all later migrations canceled:が出た時の対処

# はじめに
これは学習用のメモになります。

今回は＄rails db:migrate、または、＄rails db:migrateを行った後のエラーが出た時の対処をしていきます。

```
== 20200107095832 CreateMicroposts: migrating =================================
-- create_table(:microposts)
rails aborted!
StandardError: An error has occurred, this and all later migrations canceled:

SQLite3::SQLException: table "microposts" already exists: CREATE TABLE "microposts" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "content" text, "user_id" integer, "created_at" datetime NOT NULL, "updated_at" datetime NOT NULL)

以下つづく
```
### 原因
この前に行ったコマンドのmigrationで何らかの手違いがあると思います。おそらく、migration処理の途中からエラーが起きていて、テーブルは生成されているが、テーブルを生成したmigrationは未実行のまま。といった状態なのかな？と思います

# 解決策
## ①

```
$ rails db:migrate:reset
```
データベースのリセットを行った後

```
$ rails db:migrate
```
もう一度マイグレーション

データベースを削除し、新しくmigrationファイルを修正して、もう一度migrationを行いたい場合に使うコマンドです。


## ②

```
$ rails db:migrate:reset
```
データベースのリセットを行った後エラーが発生！

```
ActiveRecord::NoEnvironmentInSchemaError: 

Environment data not found in the schema. To resolve this issue, run: 

        bin/rails db:environment:set RAILS_ENV=development


Tasks: TOP => db:migrate:reset => db:drop => db:check_protected_environments
(See full trace by running task with --trace)
```

###　対処

```
rake db:migrate:status
```
上記のコマンドでdbのステータスを確認します。
⬇︎実行内容

```
 up     20201013130002  Devise create users
 down    20201015132219  Add devise to users
```

どうやら、一番下のマイグレーションファイルが怪しい。。。
エディタを確認したところ
同じマイグレーションファイルを二回作成していました。。
なので、一番下のマイグレーションファイルを削除してみます。
※downの状態だったら、手動でファイルを削除しても問題ない

```
$ rm -rf db/migrate/20201015132219_add_devise_to_users.rb
```

これでもう一度マイグレーションを行う。
⬇︎実行結果

```
== 20201013130002 DeviseCreateUsers: migrating ================================
-- create_table(:users)
   -> 0.0061s
-- add_index(:users, :email, {:unique=>true})
   -> 0.0014s
-- add_index(:users, :reset_password_token, {:unique=>true})
   -> 0.0011s
== 20201013130002 DeviseCreateUsers: migrated (0.0087s) =======================

```

問題なくできました！

# 最後に
今回はマイグレーションした際のエラーについて学習しました。
DBリセットしても解決しませんでした。
原因はマイグレーションファイルが重複していたためでした。

間違っているところがあればご指摘いただけると幸いです。
AWS Session Managerを通してVM接続

# 特徴
通常の接続と比べて...
・ポート22を開く必要がない
・踏み台ホストが必要ない
・全てのコマンドはS3/CloudWatchでログが記録される。
・SSHキーなしで　IAMユーザーを通してSSH接続ができる。

・Session Managerを使う事で、VM上でSSH接続ができるようになる。
・インバウンドポートを開いたり、踏み台ホストを使わなくて良いのが便利。

# 検証
CloudWatch>ログ>ロググループを作成を選択する。
ロググループ名を「SSMSecureShells」にして作成を選択する。

![スクリーンショット 2020-10-15 22.29.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449478/894a2111-f8e9-f5db-016f-1c9c0069d17d.png)
Systems Managaer>Session Manager>設定で編集を選択する。
![スクリーンショット 2020-10-15 22.31.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449478/74ca6d28-b4f1-9f6a-ae1c-aefa3a207bdd.png)
CloudWatch loggingをEnableにする。
![スクリーンショット 2020-10-15 22.32.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449478/f9ad8005-0cf1-ada7-72da-ab88a7d99f66.png)
CloudWatchのロググループを先ほど作成した「SSMSecureShells」を選択する。
![スクリーンショット 2020-10-15 22.32.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449478/1246a515-4196-626f-79da-0d8cccaead09.png)
Systems Manager>Session Manager>セッション履歴でセッションの開始を選択する。
![スクリーンショット 2020-10-15 22.35.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449478/6a643a21-745a-2832-1ffc-bd0fd04a754c.png)
ターゲットインスタンスを選択し、セッションを開始するを選択する。
![スクリーンショット 2020-10-15 22.36.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449478/b8e71a22-a75c-6e86-b6e2-6c74aa166148.png)
セッション先でコマンドを入力する。
![スクリーンショット 2020-10-15 22.37.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449478/404f60dc-e2f4-e5b6-e311-db49b8f3f055.png)
終了ボタンでセッションを終了する。
![スクリーンショット 2020-10-15 22.37.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449478/9a434392-8beb-576f-1b34-590b63660013.png)
CloudWatch>CloudWatch Logs>Log groupsで先ほど作成したロググループ「SSMSecureShells」を選択する。
![スクリーンショット 2020-10-15 22.39.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449478/09ff9a0b-0967-3e88-3a62-523210ac1fe6.png)
該当のログストリームを選択する。
![スクリーンショット 2020-10-15 22.39.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449478/7ec56623-9690-38db-cfc7-47bd4281387d.png)
先ほどのセッションのコマンドと結果が表示されていることを確認する。
![スクリーンショット 2020-10-15 22.39.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449478/17d9760f-96d9-35d5-9e0b-c43899fd3cba.png)

参考
Ultimate AWS Certified SysOps Administrator Associate 2020
https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/session-manager-getting-started-enable-ssh-connections.html
データベース設計アンチパターンEAVの使用感

DB設計でアンチパターン取り上げられてるEAV設計（Entity-Attribute-Value）の使用感。
気が向くたび更新。

## EAV設計のデータ例
こんなやつ。

**tbl**

|id  |type  |kind|
|---|---|---|
|001|animal|猫|
|002|animal|鳥|
|003|musical instrument|ドラム|
|004|musical instrument|ギター|

**tbl_attribute**

|id  |attribute_name  |attribute_value  |
|---|---|---|
|001|武器  |爪|
|001|特技  |仕事の邪魔|
|002|武器  |クチバシ|
|002|特技|飛ぶ|
|003|敷居  |高い|
|004|敷居  |普通|

## メリット
###　①列数減らせる
一つのテーブルで表現すると多分こうなる

|id  |type  |kind|武器 |特技 |敷居 |
|---|---|---|---|---|---|
|001|animal|猫|爪|仕事の邪魔|NULL|
|002|animal|鳥|クチバシ|飛ぶ|NULL|
|003|musical instrument|ドラム|NULL|NULL|高い|
|004|musical instrument|ギター|NULL|NULL|普通|

###　②属性増えたら列増やさなくてよい
「誕生」という属性増やしたい場合

|id  |attribute_name  |attribute_value  |
|---|---|---|
|001|武器|爪|
|001|特技|仕事の邪魔|
|001|誕生|2012-01-01|
|002|武器|クチバシ|
|002|特技|飛ぶ|
|002|誕生|2013-01-01|

## デメリット
###　①データ整合性保つのが難しい
日付箇所に日付じゃない値入れちゃったり、属性名に誤字あったりしてしまうことある。

|id  |attribute_name  |attribute_value  |
|---|---|---|
|001|ああああ|仕事の邪魔|
|001|誕生|ああああ|

###　②データ抽出つらい
たくさんJOINしないといけない。10個の属性値抽出だと10個JOINしないといけない。

```html:属性「武器」「特技」の値を取得したい
SELECT 
  tbl.kind
  , tbl_attr_weapon.attribute_value AS 武器
  , tbl_attr_skill.attribute_value AS 特技
FROM  
  tbl AS tbl
  JOIN tbl_attribute AS tbl_attr_weapon
    ON tbl.id = tbl_attr.id
    AND attribute_name = '武器'
  JOIN tbl_attribute AS tbl_attr_skill
    ON tbl.id = tbl_attr.id
    AND attribute_name = '特技'
;
```
###　③属性名や属性値に関する資料管理は必須
汎用的過ぎて何でも入るので決めや資料整理は重要。作成もその資料に慣れるのも案外大変。
属性名はこの種類、値は何パターンdate型、この属性は一つまで持てる複数持てる等。

|id  |attribute_name  |attribute_value  |
|---|---|---|
|001|武器|爪|
|001|武器|牙|
|001|武器|蹴り|

ろくに管理されてないと認識齟齬多発して工数かかりまくって炎上する。

###　④データ抽出つらいその2
抽出する属性の値の特性全部把握しないといけない。
この属性は複数可能性あるから結果配列にすべき、複数でないようにこういう条件必要とか。

その整理が案外時間かかる。

###　⑤データ抽出つらいその3
動作確認するための試験データ準備やパターン網羅が案外大変。
パターン在りすぎて考えるのも大変だしレビュアーもパターン足りてるのか判断もきっと難しい。


そんな感じです。
「[基本情報技術者試験]ユークリッドの互除法....」を参考に、WolframAlphaとSymPy Liveで最大公約数と最小公倍数を計算してみた	

オリジナル

https://qiita.com/kuro_take/items/261e3d4cc2fd6a86147c	

参考

https://qiita.com/Dexctersu/items/43d844db0e751b23b3b7	
	
# WolframAlphaを使って	

https://www.wolframalpha.com/input/?i=84%E3%81%A860%E3%81%AE%E6%9C%80%E5%A4%A7%E5%85%AC%E7%B4%84%E6%95%B0&lang=ja	
	
https://www.wolframalpha.com/input/?i=1112%E3%81%A8695%E3%81%AE%E6%9C%80%E5%A4%A7%E5%85%AC%E7%B4%84%E6%95%B0&lang=ja	

https://www.wolframalpha.com/input/?i=1112%E3%81%A8695%E3%81%AE%E6%9C%80%E5%B0%8F%E5%85%AC%E5%80%8D%E6%95%B0&lang=ja	


# SymPy Liveを使って	
https://live.sympy.org/	

```	
print gcd(84,60),gcd(1112,695),lcm(1112,695)	
12 139 5560	
```
UWSCで作業を効率化しよう【エディタ準備編】

皆さんこんばんは

前回は無事にUWSCの環境を構築することが出来ましたね。

まだやってないよ〜って方は、[こちら](https://qiita.com/reishisu252521/items/abf36183d925ed795753)に書いてますのでまずは実行環境の構築から始めましょう！

UWSCでは本来マウスのクリックを記憶させてマクロを動かすのですが、さらに細かく動作を決めたいときは自分でスクリプトファイルを作成して実行させる事もできます。

今回はUWSCのスクリプトファイルを作成するにあたってメモ帳でも作成することは可能ですが、入力補完やソースコードに色付けをすることでみやすくしたり効率よく書く事ができるエディタの「ダウンロード → インストール → 起動」までを紹介したいと思います。

また、今回の記事は見なくても開発する事も出来ますので「俺はメモ帳でも余裕だぜ！」とか言う人は見なくても問題はないです。

ちなみにこれから紹介するエディタは「サクラエディタ」と言うものです。

# サクラエディタのインストーラーをダウンロードしよう！

まずは、サクラエディタをインストールするためのインストーラーをダウンロードしましょう。

[こちら](https://sourceforge.net/projects/sakura-editor/files/latest/download)からダウンロードできます。
(画面が表示されて約５秒後くらいにダウンロードが開始されます)

ダウンロードしたフォルダにこのファイルがあればダウンロード成功です！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241870/5d9818d1-87b8-3909-1024-c6ba3e1cbe52.png)

# インストーラーを実行してインストールしよう！

1. まずは、先ほどダウンロードしらファイルをクリックして実行しましょう!
2. すると「サクラエディタをインストールします。続行しますか？」と表示されますのでそのまま「はい（Y）」を押しましょう。!  
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241870/d418d153-f61b-b21e-8dd3-3ccd57da8e55.png)
3. 続いてUACの画面が出て来ると思いますがこちらも「OK」を押しましょう。
4. ここから「サクラエディタ セットアップウィザードの開始」が表示されいよいよインストールの作業が始まります。この画面は「次へ（N)」を押しましょう。  
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241870/18a33d70-eaa4-09d4-0e0a-fb42fc3833e8.png)
5. ここで「インストール先の指定」が出てきますが、特にこだわりがある方以外はそのままで気にせずに「次へ（N)」を押しましょう。  
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241870/1397b9c8-233f-3a16-ef8d-e2ce8059583d.png)
6. 「コンポーネントの選択」がでますが、そのまま触らずに「次へ（N)」を押しましょう。  
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241870/dbdd3a2e-5f6c-c04c-4d16-b8d10f9a08e9.png)
7. 「プログラムグループの指定」が出てくると思いますが、こちらもそのまま「次へ（N)」を押しましょう。  
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241870/00456f90-d63f-a303-59b4-9dc6d9a4b0d4.png)
8. 「追加タスクの選択」が出てくると思いますが、こちらは「インストール完了時にデスクトップにアイコンを作成する」と「ファイルを右クリックしたときにSAKURAで開く」を選べるようにしたいので間違えないように「画像と同じ様にチェックを入れましょう」。チェックが完了したら「次へ（N)」を押しましょう。  
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241870/5ef8f30e-1228-72b4-4e8f-678f1caa2dff.png)
9. これでインストールする準備が完了しました！そのまま「インストール（I）」を押してインストールを開始しましょう！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241870/e207e884-4e3b-e6e4-bd79-7829e7fd5ed3.png)
10. これでインストールする準備が完了しました！そのまま「インストール（I）」を押してインストールを開始しましょう！  
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241870/800d435f-2b5d-45de-281a-cef418490a8c.png)
11. 10秒ほど待って「サクラエディタ セットアップウィザードの完了」が表示されたらインストーラーでの作業が終わりで「完了（F)」を押しましょう。これで上手くいけばインストールは成功してます！！  
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241870/65bdc586-ab97-c42a-126c-b1b97ba45ddf.png)

# インストールできてるか確認しよう！

1. まずは、デスクトップに戻りサクラエディタのアイコンがあることを確認しましょう。  
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241870/d6ed5478-edf4-7fc2-17f1-acfc4aa77fad.png)
2. 続いてアイコンをダブルクリックして実際に起動できることを確認して画像のとおりになれば無事にインストールは完了です！！  
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241870/b6c70122-1b70-f4b4-0618-4639b79084d1.png)

お疲れ様でした！！

次回は、スクリプトを効率よく書くための設定について書いていこうと思います！
鹿児島県の Go To EATの利用可能店舗のPDFをCSVに変換

鹿児島商工会議所の[利用可能店舗](http://www.kagoshima-cci.or.jp/?p=20375)のPDFからCSVに変換

エリアごとにPDFファイルが分かれているのでひとつにまとめる

# スクレイピング
```python
import requests
from bs4 import BeautifulSoup

url = "http://www.kagoshima-cci.or.jp/?p=20375"

r = requests.get(url)
r.raise_for_status()

soup = BeautifulSoup(r.content, "html.parser")

result = []

for a in soup.select("#contents_layer > span > p > a"):

    s = a.get_text(strip=True).replace("全域", "").lstrip("〇")

    # 地区は除外
    if not s.endswith("地区"):

        result.append({"area": s, "link": a.get("href")})
```

# データラングリング
```python
import camelot
import pandas as pd

dfs = []

for data in result:

    tables = camelot.read_pdf(
        data["link"], pages="all", flavor="lattice", split_text=True, strip_text=" \n"
    )

    for table in tables:

        df_tmp = table.df.iloc[1:].set_axis(["五十音", "店舗名", "所在地"], axis=1)
        df_tmp["地域"] = data["area"]

        dfs.append(df_tmp)

df = pd.concat(dfs)

df.to_csv("kagoshima.csv", encoding="utf_8_sig")
```
sedの備忘録

sedを使ってデータの一括置き換えをしたい時のための備忘録。随時追加予定。

## 削除

まず、偶数行・奇数行をそれぞれ削除したい時。
準備として偶数行と奇数行に異なる文字列を出力したファイルを準備。

```bash
$ for i in {1..10}; do
if [ $(($i % 2)) = 0 ]; then
echo '偶数行です'
else
echo '奇数行です'
fi
done > number.txt

$ cat number.txt
奇数行です
偶数行です
奇数行です
偶数行です
奇数行です
偶数行です
奇数行です
偶数行です
奇数行です
偶数行です
```

### 偶数行を削除したい

```bash
$ sed -i -e 'n; d' number.txt
$ cat number.txt
奇数行です
奇数行です
奇数行です
奇数行です
奇数行です
```

### 奇数行を削除したい

```bash
$ sed -i -e '1d; n; d' number.txt
$ cat number.txt
偶数行です
偶数行です
偶数行です
偶数行です
偶数行です
```

## 置換

### 特定の文字列を、空白を含む文字列へ一括置き換えしたい

スペースをエスケープすればいいだけだった。

```bash
# 準備
$ pen='これはペンです。\n'
$ printf $pen"%.s" {1..10} > pen.txt
$ cat pen.txt
これはペンです。
これはペンです。
これはペンです。
これはペンです。
これはペンです。
これはペンです。
これはペンです。
これはペンです。
これはペンです。
これはペンです。

# 置換
$ sed -i -e "s/これはペンです。/This\ is\ a\ pen\./g" pen.txt
$ cat pen.txt
This is a pen.
This is a pen.
This is a pen.
This is a pen.
This is a pen.
This is a pen.
This is a pen.
This is a pen.
This is a pen.
```
【５０歳過ぎたオッサンが】生まれて初めてＷＥＢアプリを作製するまで。（deep learning編）

はじめまして。

５０過ぎたオッサンです！

プログラミングスキルはゼロです！！


プログラミング経験がないので、ただ漠然とした「ＷＥＢアプリ」を作製したい！

そんな思いがありました。

アイデアもなく、ただ何かを作りたい！そう思ってました。


【ヒントの種は？】


＊＊＊まずプログラミング言語を決めるところからのスタートでした。＊＊＊


どんな言語が良いのか？

どんな言語が簡単か？

色々と検索をしたら「python」が簡単ということがわかりました。

pythonを調べまくりました。

pythonならＷＥＢ系も人工知能系もいけるということで


本を買いました！


![web.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/669624/2887d741-b949-0e1c-f259-a72caa953173.jpeg)


この本は初学者にも優しい本で、分かりやすかったです。

やりたいこと（スキルが伴う）がまだ見つからないので

困ってました。

言語はパイソン、やりたいことはまだない！何を始めようか？

よし、米国株のディープラーニングでいこう！！

何故、米国株なのかというと日本株は「ストップ安、ストップ高」で取引ができませんが

米国株なら可能だということで、米国株の未来予測に挑戦してみました。

（この未来予測については、現在作成中です。）







おススメのサイトは以下。


https://qiita.com/innovation1005/items/5be026cf7e1d459e9562

https://econ-blog.com/risk-and-return-plot-with-python/

https://katsuhiroblog.com/python-get-google-stock/










こちらの画像をどうぞ！

![本.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/669624/bccf0f3e-3616-988f-ee4a-6def88d39feb.jpeg)


１６冊の本を読み漁り、ネットでも読み漁り。

【google play】で公開できました。（＊＊＊ver1.0はＤＬを使ってません＊＊＊）


公開画像はコチラ

![bandicam 2020-10-15 21-46-28-420.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/669624/176bb19a-b148-b235-3f96-ff5b6c089fed.jpeg)


米国株のチャート分析するアプリを作製しました。


まだまだ戦いは続きます。

ＤＬを用いた株価予測を完成するまでは・・・・。
Python【 if文 等 】

Pythonの基礎知識です。
自分の勉強メモです。
過度な期待はしないでください。


基礎知識
-

・Pythonのプログラムファイルの拡張子は`py`
　例：××××.py



IDLEを使った場合
-
・シェルウィンドウ
　IDLEを起動した状態

・エディタウィンドウ
　-プログラムを入力するものをテキストエディタと言う
　-ファイルの新規作成→IDLEのシェルウィンドウのメニューバーにある`「File」→「New File」`
　-保存→エディタウィンドウにプログラムを記述をしファイルを保存する時は、エディタウィンドウのメニューバーにある`「File」→「Save as...」`
　-ファイルを開く→エディタウィンドウのメニューバーにある`「File」→「Open」`
　-プログラムの実行→エディタウィンドウのメニューバーにある`「Run」→「Run Module F5」`



命令
-
・出力を行う`print()`
　全角、半角に関わらず`文字列`を出力するには`print()`と言う命令を使う
　また、文字列を扱うには`ダブルクォテーション（""）`また、`シングルクォテーション（''）`で前後をくくる
　例：print("おはよう")　→　おはよう


・入力を行う`input()`
　`変数 = input('コンソールに表示したい文字列')`のように使うとコンソールに入力された値が変数に代入されます。
　また、inputで受け取った値は文字列型になるので数値型に変換する必要がある（「int」を用いる）

変数
-
・変数名の付け方
　-１、英単語を用いる、変数名の頭文字を数字にする事は出来ない
　　例：date
　-２、2語以上の変数名を使うときは、単語と単語の間を `_ (アンダーバー)`で区切る
　　例：user_name

・変数の値を取り出す

```py
name = "Jhon"
print(name)  # →　Jhon
print("name")  # → name　#ダブルクォテーション等を付けると文字列して認識されてしまう
```

・変数の値を更新

|基本形|省力形|
|:---:|:---:|
|X = X + 100|X += 100|
|X = X - 100|X -= 100|
|X = X * 100|X *= 100|
|X = X / 100|X /= 100|
|X = X % 100|X %= 100|


型変換
-
・数値型を文字列型に変換するには`「str」`を用いる

```py:例
price = 200  # 数値型
print("りんごの価格は"+ str(price) + "円です")
```

・文字列型を数値型に変換するには`「int」`を用いる

```py:例
count = "3"
price = 100
total_price = price * int(count)
```


if文
-
書き方

```××××.py
score = 50
if score ==100: #行末にコロンは必須
    print("等しい数値です")
#インデントを揃える（半角スペース４つ分）
```

```××××.py
score = 50
if score ==100: #行末にコロンは必須
    print("等しい数値です")
#インデントを揃える（半角スペース４つ分）
else: #行末にコロンは必須
    print("異なる数値です")
#インデントを揃える（半角スペース４つ分）
```

```××××.py
score = 80
if score ==100: #行末にコロンは必須
    print("等しい数値です")
#インデントを揃える（半角スペース４つ分）
elif score >=70: #行末にコロンは必須
    print("70よりは大きです")
else: #行末にコロンは必須
    print("異なる数値です")
#インデントを揃える（半角スペース４つ分）
```

```××××.py
# and - 「条件1も条件2も成り立つというような場合」
x = 20
if x>=10 and x<=30:
    print("xは10以上30以下です")

# or - 「条件1か条件2が成り立つというような場合」
y = 60
if y<10 or y>30:
    print("yは10未満または30より大きいです")

# not - 「条件式がFalseであればTrueになる」
z = 55
if not z== 77:
    print("zは77ではありません")

```

|式|意味|
|:---:|:---:|
|==|右辺と左辺が等しい時|
|!=|右辺と左辺が等しくない時|
|<|右辺の時が大きい時|
|<=|右辺の時が大きいまたは等しい時|
|>|左辺の時が大きい時|
|>=|左辺の時が大きいまたは等しい時|
Centos8にPostgreSQL12をインストール

# はじめに
Mysqlしか触ったことなかったので、検証用にPostgresqlを公式サイトのインストール方法でインストールした。
今回はローカルからpostgresユーザーで認証なしの接続を想定する。

# 環境
* CentOS8
* Postgresql12

# インストール
```
dnf install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-8-x86_64/pgdg-redhat-repo-latest.noarch.rpm
dnf -qy module disable postgresql
dnf install -y postgresql12-server
/usr/pgsql-12/bin/postgresql-12-setup initdb
systemctl enable postgresql-12
systemctl start postgresql-12
```
以下の公式サイトでインストールしたいものを選択してインストールする。
https://www.postgresql.org/download/linux/redhat/

# 設定変更
## 事前準備
### ユーザー変更
インストール後、postgresユーザーが追加されているため、ユーザーを変更する。
基本的にpostgresユーザーで操作を行う。

```
su - postgres
```

### ディレクトリ遷移
設定ファイルあるディレクトリに移動する。

```
cd /var/lib/pgsql/12/data
```

### PATHの追加
pg_ctlを相対PATHで使えるようにする。
.bash_profileに追記しても良い。

```
export PATH=$PATH:/usr/pgsql-12/bin/
```
## postgresql.conf
基本的な設定をするファイル。適宜設定を変更する。
今回は検証なのでデフォルトのまま。

## pg_hba.conf
接続するネットワークを設定するファイル。
identからtrustに変更することで、ローカルホストに認証なしで接続できるようにする。
postgresql.confがデフォルトだとipv6で繋ぎに行く場合もあるので、ipv6も変更する。

* 変更前
* 
```
# IPv4 local connections:
host    all             all             127.0.0.1/32            ident
# IPv6 local connections:
host    all             all             ::1/128                 ident
```

* 変更後
* 
```
# IPv4 local connections:
host    all             all             127.0.0.1/32            trust
# IPv6 local connections:
host    all             all             ::1/128                 trust
```

## 設定の反映
以下のコマンドで設定を反映する。

```
pg_ctl reload
```

# 確認
## ログイン確認
以下のコマンドでログインできることを確認する。

```
psql -h localhost
```

## パスワード変更（任意）
接続後、postgresユーザーのパスワードを変更する。

```
alter role postgres with password 'パスワード';
```

# まとめ
公式サイトにのっとてインストールしてみた。
ipv6の設定変更を忘れたり、postgresユーザーの初期パスワードがわからなかったり、意外と引っかかった。
そして、postgresユーザーの初期パスワードは今でもわかっていない。


# 参考文献
* https://www.postgresql.org/download/linux/redhat/
* [データベース初心者のためのPostgreSQL教室](https://nextpublishing.jp/book/11673.html)
俺でもわかるAurora PostgreSQLバージョンアップの実ダウンタイム雑メモ

俺です。
Aurora PostgreSQLのバージョンアップをいくつかやったのでメモを残します。

Aurora PostgreSQL バージョンアップ・パッチ適用の全体時間はだいたい20min~30minぐらいです(Event logより)
バージョンアップ中にDB Instanceの再起動が行われ、一時的に全ての接続が失われます。

この一時的にっていうのは一体どれぐらいの期間なのか、数秒なのかそれとも自分が定年退職するまでの期間なのか実際のダウンタイムがきになったので
バージョンアップ中に`psql -c SELECT NOW();` を `while : sleep 1` でぶん回して接続が復帰するまでの脳筋的体感時間を計測した結果をざっくりメモで残しておきます。


|no|verup前|verup後|クラスタ・インスタンスパラメータグループの変更、要不要|再起動対象|脳筋体感的ダウンタイム|備考|
|---|----|----|----|----|----|---|
|1|9.6|10.12|クラスタパラメータグループ・インスタンスパラメータグループ共に変更必要|writer/readerが同時に再起動される|10min ~ 20min|パラメータグループの変更が必要なのでクラスタ全体が一回shutdownされてるかんじ|
|2|10.7|10.12|パラメータグループ変更無し|writer/readerが同時に再起動される|30sec ~1min|writer/readerエンドポイントが返すAレコードは、一番早く復帰するwriterインスタンスになるが、readerインスタンス復帰後にreaderエンドポイントはreaderインスタンスのAレコードが返される|

- メジャーバージョンアップはサービスの適切なメンテナンスウインドウを設定すること。メンテナンスウインドウに重なる、もしくは前後の時間帯で走るバッチ処理調整とか考慮しないとつらいかもって気持ちになりました。
- マイナーバージョンアップであればメンテなしでもぶっこんでよい規模のサービスは多々ありそうって気持ちになりました。

おわり