OmniAICreator/Qiita-1.07M huggingface dataset:
さくっとベンチマーク取る時のメモ

# 前提
- メモリ使用量と処理時間
- Ruby 2.7.4

# メモリ使用量
## Gem
- [memprof2](https://github.com/sonots/memprof2)を使う
- Ruby コードのどの行がどのぐらいメモリ（bytes）を消費しているか調べられる
- [かなりリソースを喰うらしい](https://qiita.com/sonots/items/c14b3e3ca8e6f7dfb651#memprof2-gem-dancers:~:text=%E6%B3%A8%E6%84%8F%3A%20%E3%81%8B%E3%81%AA%E3%82%8A%E3%83%AA%E3%82%BD%E3%83%BC%E3%82%B9%E3%82%92%E5%96%B0%E3%81%86%E3%81%AE%E3%81%A7production%E3%81%A7%E3%81%AF%E3%81%94%E5%88%A9%E7%94%A8%E3%81%84%E3%81%9F%E3%81%A0%E3%81%91%E3%81%BE%E3%81%9B%E3%82%93)

```ruby
# 計測前に掃除
GC.start

# 計測開始
Memprof2.start

# 計測対象
12.times{ "abc" }

# 計測後に計測対象をクリア
# gem内部は除いている
Memprof2.report!(ignore: /.*\/gems\/.*/)

# 計測終了
Memprof2.stop

# =>
# 168 tmp/test.rb:9:Hash
# 480 tmp/test.rb:6:String
```

## psコマンド
- [Ruby からコマンドを実行する](https://blog.freedom-man.com/measure-ruby-memory-usage#:~:text=%E3%81%97%E3%81%9F%E3%81%A8%E3%81%8D%E3%81%AE%E5%82%99%E5%BF%98%E9%8C%B2-,ps%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%A6%E8%A8%88%E6%B8%AC%E3%81%99%E3%82%8B,-ps%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89%E3%82%92)
- [RSSとVSZでメモリ確保のタイミングが異なる](https://nopipi.hatenablog.com/entry/2017/11/11/213214)
    - 前提:
        - 1.メモリ確保
        - 2.メモリ読み込み
        - 3.メモリ書き込み
    - VSZ（仮想メモリ）は 1 で増える
    - RSS（物理メモリ）は 3 で増える

```ruby
def puts_ps
  # NOTE KB -> MB を行う。詳細は、man ps で確認できる。
  rss = `ps -o rss= -p #{Process.pid}`.to_i * 0.001024
  vsz = `ps -o vsz= -p #{Process.pid}`.to_i * 0.001024
  puts "Process: #{Process.pid}: RSS = #{rss} MB, VSZ = #{vsz} MB"
end

# 計測前に掃除
GC.start

# 計測前
puts_ps

# 計測対象
12.times{ "abc" }

# 計測後
puts_ps

# =>
# Process: 2016: RSS = 210.73600000000002 MB, VSZ = 6550.928 MB
# Process: 2016: RSS = 210.74 MB, VSZ = 6550.928 MB
```


# 処理時間
- [Benchmark モジュール](https://docs.ruby-lang.org/ja/latest/class/Benchmark.html)を使う
- [user, system, total, real の違い](https://qiita.com/scivola/items/c5b2aeaf7d67a9ef310a#%E7%B5%90%E6%9E%9C%E3%81%AE%E8%A6%8B%E6%96%B9)
    - real: 現実世界の時間
    - total: user + system
    - user: ユーザー CPU 時間
        - Ruby 処理系が働いた CPU 時間
    - system: システム CPU 時間
        - OS のシステムコール実行に費やした CPU 時間
- [GC の影響を軽減するメソッドがある](https://docs.ruby-lang.org/ja/latest/class/Benchmark.html#M_BMBM:~:text=bmbm(width%20%3D%200)%20%7B%7Cjob%7C%20...%20%7D%20%2D%3E%20%5BBenchmark%3A%3ATms%5D)
    - 前提として GC はベンチマークを取る際のノイズになる
        - CPU 時間を消費する処理であり、どのタイミングで実行されるか分からない
    - リハーサル->GC->本番
        - 一回目は実行環境を安定化するためにリハーサルとして実行して
        - 二回目は GC 実行後に本番として実行する
    - 意図せずリハーサル実行でキャッシュされることに気を付ける
        - ボトルネックがDB処理で、リハーサル実行で意図せずキャッシュされてしまったことがあった

```ruby
require 'benchmark'

array = (1..1000000).map { rand }

Benchmark.bmbm do |x|
  x.report("sort")  { array.dup.sort  }
end

# =>
# Rehearsal ----------------------------------------
# sort   0.328938   0.027635   0.356573 (  0.356915)
# ------------------------------- total: 0.356573sec

#            user     system      total        real
# sort   0.296239   0.002024   0.298263 (  0.298514)
```

# 終わりに
- 計測自体は簡単に行える
- 大事なのは、ベンチマーク取る時に、計測対象以外のノイズがないこと
    - 特に意図せずキャッシュが効いているパターン
【UiPath】データテーブルに主キーを設定しておくと、データ テーブルをマージ (Merge Data Table) で重複したキーのレコードがマージされない

**データ テーブルをマージ (Merge Data Table)** は2つのデータテーブルを行方向に結合するアクティビティです。
より正確にはターゲット (Destination) のデータテーブルに、ソース (Source) のデータテーブルの行を追加するという動きになります。

本題です。
データテーブルに主キー (Primary Key) が設定されていて、
かつ、ターゲットとソースで重複する主キーが存在する場合にマージを行うと、
**重複するレコードについて、ターゲット側が残り、ソース側は挿入されない**、という挙動になります。
以下で実際に動きを見てみます。

### 主キーを設定していない場合
![image.png](http://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/578020/3bf3dabb-34f6-25ba-f138-79a612aad106.png)
①テーブル１を構築。
②テーブル２を構築。
③テーブル１にテーブル２をマージ。
④テーブル１の内容をログ出力。
という処理になります。
テーブル１とテーブル２の内容、及び実行結果については以下参照ください。
- テーブル１
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/578020/9c882d1b-9767-8b7b-3504-e638a48cc50f.png)
- テーブル２
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/578020/5b1fa54e-f29a-1c40-b759-fef00a77ce58.png)
- 実行結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/578020/d877bdfa-e6e6-0481-212a-d3119187901f.png)

シンプルにテーブル１にテーブル２の行が追加された形になりますね。

### 主キーを設定した場合
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/578020/ff097427-a94b-1fa7-b010-2b653d4c80aa.png)
基本的な処理とテーブルの内容は「主キーを設定していない場合」と同じですが、
**テーブル１を構築した後に、テーブル１の項目"ID"に主キーを設定しています。**
- 実行結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/578020/58a606c1-3137-2939-aee5-0545b45b42e0.png)

**"ID"が重複しているテーブル２の一行目のレコードが挿入されていません。**
また、"ID"=2（りんご）の価格が150（テーブル１のもの）となっていることから、
テーブル２のレコードで上書きされたわけではなく、テーブル１のレコードが残っているということがわかります。

#### オマケ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/578020/6c4bf081-ee37-3342-d38f-5ab880654ed5.png)
とはいえ"ID"=2 のレコードはRowStateがModifiedになっているので一応編集された扱いなのか…？

### 一意の制約を設定した場合
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/578020/ed081ba8-f332-0e59-f66c-f76d7efa51e3.png)
「主キーを設定していない場合」と同じ処理ですが、
今度はデータテーブルを構築する際に、テーブル１の項目"ID"に一意の制約（ユニークキー）を設定しています。
- 実行結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/578020/7768eb22-31f4-bc48-f944-f1195e3858b3.png)

この場合は制約違反でエラーになります。
ユニークキーと主キーは違うということですね。

## 動作環境
UiPath.System.Activities 21.10.4

## 参考
https://docs.uipath.com/activities/lang-ja/docs/merge-data-table

http://zawanii.com/uipath-datatable-primarykey/
Terminalでお名前レンタルサーバーにsshログインしようとしたら怒られた：「Unable to negotiate with 157.7.45.217 port 22: no matching key exchange method found.」

# 動作環境
MacOS 12.4
Terminal
お名前レンタルサーバー

# 怒られたこと
Terminalで久しぶりにサーバーへsshログインしようとしたら,

```
Unable to negotiate with IPアドレス port 22: no matching key exchange method found. Their offer: gss-group1-sha1-toWM5Slw5Ew8Mqkay+al2g==,diffie-hellman-group-exchange-sha1,diffie-hellman-group14-sha1,diffie-hellman-group1-sha1
```
パスワードも聞いてくれない。。。

# 原因
参考記事によると、MacOSアップデートでMontereyになると仕様が変わってるとのこと
https://qiita.com/naotwu/items/425e401aa652981d6e12

# 対処
 以下を追記
```:vim&nbsp;~/.ssh/config
ssh 登録名
KexAlgorithms +diffie-hellman-group1-sha1
Ciphers aes128-cbc
```
# 結果
入れた〜！

# ほかのサーバーには？
ほかのサーバーへのssh接続もトライ
KAGOYA VPS　▶︎　OK
お名前VPS ▶︎ OK
ConoHaレンタルサーバー　▶︎ OK
さくらレンタルサーバー　▶︎ OK

お名前レンタルサーバーだけ発生している模様
***
# 参考記事
https://qiita.com/naotwu/items/425e401aa652981d6e12
SQLのGROUP BYでエラーになる件

# 基本環境
MySQL 5.7

# こんなSQLがエラーに

```
SELECT ＜カラム名1＞FROM ＜テーブル名1＞ GROUP BY ＜カラム名2＞ ;
```

# 原因
“GROUP BY” で指定していないカラムが “SELECT” に入っている
MySQL 5.7以降、ONLY_FULL_GROUP_BYは初期状態で有効

# 解決
方法１
```
SELECT MAX(＜カラム名1＞) AS ＜カラム別名1＞FROM ＜テーブル名1＞ GROUP BY ＜カラム名2＞ ;
```
方法２
```
SELECT ＜カラム名1＞FROM ＜テーブル名1＞ WHERE ＜カラム名2＞ in (SELECT ＜カラム名2＞ FROM ＜テーブル名1＞ GROUP BY ＜カラム名2＞) ;
```

エラー：
SELECT makers.name, my_items.items_name, SUM(carts.count) AS sales_count FROM makers, my_items LEFT JOIN carts ON my_items.id=carts.item_id WHERE makers.id=my_items.makers_id GROUP BY carts.item_id ORDER BY sales_count DESC;

OK:
SELECT MAX(makers.name) AS name, MAX(my_items.items_name) AS items_name, SUM(carts.count) AS sales_count FROM makers, my_items LEFT JOIN carts ON my_items.id=carts.item_id WHERE makers.id=my_items.makers_id GROUP BY carts.item_id ORDER BY sales_count DESC;
LinuxサーバーにComposerをインストールしようとしたら拒否された件

# 基本環境

# コマンドが拒否された

```:EC-CUBEをインストールするディレクトリ
# php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"

Deprecated: Directive 'allow_url_include' is deprecated in Unknown on line 0
```

# php.iniが原因

phｐの設定が書き込まれているphp.iniの設定が原因だった

php.iniありか

```:index.php
<?php
phpinfo();
?>
```

![スクリーンショット 2022-09-08 10.14.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1653133/db833ca0-3eab-17d6-a362-765103a85faf.png)

php.ini書き換え

```:vim&nbsp;/etc/php.ini
allow_url_include = On
↓
allow_url_include = Off
```
LinuxサーバーにComposerをインストールしてバージョンを下げる

# やりたいこと

EC-CUBEのためにcomposerをインストール
EC-CUBE4.0系はcomposer1のみに対応しているためバージョン下げる
（composer2ではキャメル型ファイルがインストールできない）

# composerインストール

EC-CUBEをインストールするルートディレクトリへ行く

```:EC-CUBEルート
php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
```

composer-setup.phpがダウンロードされたか確認

```
ls 

composer-setup.php
```

phpファイルの改ざんチェック

```:EC-CUBEルート
php -r "if (hash_file('sha384', 'composer-setup.php') === '55ce33d7678c5a611085589f1f3ddf8b3c52d662cd01d4ba75c0ee0459970c2200a51f492d557530c71c15d8dba01eae') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"

Installer verified
```

composerをインストールする

```:EC-CUBEルート
php composer-setup.php

All settings correct for using Composer
Downloading...

Composer (version 2.0.7) successfully installed to: /EC-CUBEルート/composer.phar
Use it: php composer.phar
```

composer-setup.phpを削除

```:EC-CUBEルート
php -r "unlink('composer-setup.php');"
```

```:EC-CUBEルート
ls 

composer.phar 
```
composer-setup.phpが消えて、composer.phar ができている

# 動作確認

```:EC-CUBEルート
composer.phar

   ______
  / ____/___  ____ ___  ____  ____  ________  _____
 / /   / __ \/ __ `__ \/ __ \/ __ \/ ___/ _ \/ ___/
/ /___/ /_/ / / / / / / /_/ / /_/ (__  )  __/ /
\____/\____/_/ /_/ /_/ .___/\____/____/\___/_/
                    /_/
Composer version 2.0.7 2020-11-13 17:31:06
```

# composerバージョン確認

```:EC-CUBEルート
composer --version

Composer version 2.0.7
```

# composerバージョンを１にする

```:EC-CUBEルート
composer selfupdate --1

Upgrading to version 1.10.26 (1.x channel).
```

# composerバージョン再確認

```:EC-CUBEルート
composer --version

Composer version 1.10.26
```

***
# 参考記事
https://doc4.ec-cube.net/quickstart/command_install
https://getcomposer.org/download/
https://laboradian.com/php-composer/
https://self-development.info/composer%E3%81%AE%E6%AD%A3%E3%81%97%E3%81%84%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E6%96%B9%E6%B3%95%E3%82%92%E8%A7%A3%E8%AA%AC%E3%80%90php%E3%80%91/#:~:text=composer.json%E3%81%AB%E3%81%AF%E3%80%81%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB,%E3%81%99%E3%82%8B%E3%81%93%E3%81%A8%E3%82%82%E3%81%A7%E3%81%8D%E3%81%BE%E3%81%99%E3%80%82
https://chusotsu-program.com/win10-composer-version-down/
TerminalからphpMyAdminインストール

# 基本環境

# サーバー環境を確認

```
mysql --version

php -v
```

# 環境に対応したphpMyAdmin最新バージョンを確認

https://www.phpmyadmin.net/downloads/

# ルートディレクトリにファイルをダウンロード

```
cd ＜ルートディレクトリ＞

wget ＜ファイルのURL>
```

# zipファイルの解凍

```
unzip ＜ZIPファイル＞
```

# 所有権の変更

```
chown -R apache ＜phpMyAdminファイル名＞
```
include?メソッドとCode Runnerで文字入力した備忘録

今日も学んだことを忘れない為にメモします

### include?メソッドとは？
include?メソッドは、指定した値が配列や文字列内に含まれているかを判定するメソッド。指定した値が含まれている場合はtrueを、含まれていない場合はfalseを返り値として返す。
```
array = ["foo", "bar"]
puts array.include?("bar")
# => true
puts array.include?("hoge")
# => false
```
配列arrayを作成してinclude?メソッドで引数に含まれているか確認した文字or数字を入れる。
"bar"は含まれているのでtrue
"hoge"は含まれていないのでfalse

### 含みたくない文字の確認にも使える
ピリオドと空白は入力しないで名前を登録して欲しい時、以下のような記述で確認出来る。
```
def check_name(str) 
  if str.include?(".")
    puts "!エラー!記号は登録できません"
  elsif str.include?(" ")
    puts "!エラー!空白は登録できません"
  else
    puts "登録が完了しました"
  end
end
puts "登録したい名前を入力してください(例)YamadaTaro"
str = gets
check_name(str) 
```

getsメソッドでユーザーに登録する名前を入力してもらう。
定義したcheck_nameメソッドの引数にgetsメソッドで入力された文字列を渡して呼び出す。
if文では、仮引数strで受け取った文字列に対してinclude?メソッドを使用し、ピリオドと空白(" ")がないかを判断してる。

### Code Runnerってデフォルトの設定だと文字が入力出来ないんですね
ちゃんと処理が上手くいくかCode Runnerで確認したくて▷（RunCode）を押したけど文字が入力出来ない。
なぜ？
調べたところ、「⌘ + ,」でVScodeの設定を出す。「code-runner run in terminal」を検索して「 Run In Terminal」にチェックを付けたら出力ではターミナルで文字が入力出来るようになった。


以上がinclude?メソッドとCode Runnerで文字入力した備忘録になります。
GitHubとSlackを連携するコマンド

# /github subscribe コマンドを Slack側で送信
![スクリーンショット 2022-09-15 20.57.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1134006/095290b2-6ca0-f195-c240-782e30c9c047.png)
`owner/repository`をGitHubの`作成者名/リポジトリ名`に変更して送信ボタンを押すだけです。デフォルトでは、`issues` `pulls` `statuses` `commits` `deproyments` `public`が付与されていますが、オプションで、`reviews` `comments` `branches` `allcommits`が付けれます。上記の場合、全て購読するコマンドになります。
```
/github subscribe owner/repository reviews comments branches commits:*
```
![スクリーンショット 2022-09-15 21.23.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1134006/ab9dde63-b43e-8eee-619e-5b57878f008a.png)
このようにコメントが返ってくれば連携成功です。
|オプション|内容 |デフォルト通知設定|
|:-----|------------------------------:|:------------:|
|issues|	issueのオーブンとクローズ	|◯|
|pulls|	PR(プルリクエスト)の作成とマージ	|◯|
|commits|　デフォルトブランチに対するコミット	|◯|
|releases|	リリース(公開)	|◯|
|deployments|デプロイ時のステータス更新	|◯|
|reviews|	PRのレビュー	|×|
|comments|	PRやissueへのコメント	|×|
|branches|	ブランチの作成と削除	|×|
|commits:*|	全てのブランチに対するコミット	|×|
|discussions|作成や回答に対するディスカッション	|×|
|+label:"your label"|指定したラベルのissue/PR/コメント	|×|

[詳しくはこちらをご覧ください。](https://github.com/integrations/slack#configuration)
ソリューションアーキテクト対策_EBS篇

## はじめに
試験勉強した際のメモを自分用に記事化。
内容は公式やBlack Beltの写経ですので目新しいことはありません:pray:

## EBSとは
ネットワークで接続されたブロックレベルのストレージで、EC2とは独立無縁。
EC2をTerminatedしてもデータは保持される。スナップショットも取れる。S3に保存もできる。有料。
→DeleteOnTermination属性ていうのがある。デフォルトだとONで、EC2インスタンス削除とともにEBSも削除される。★

## EBSの特徴
・同じAZ内のEC2にしかアタッチできない。AZやリージョン、VPCをまたがったアタッチは不可能。

・EBSボリュームを作成すると同じAZ内でのみ自動的に複製される。別のリージョンには複製されない。

・他サービスのインスタンス同様、ボリュームサイズやボリュームタイプの変更が可能である。

・EBSボリュームは1つのインスタンスにのみアタッチできる。複数インスタンスでの共有はできない。
ただし、プロビジョン度IOPSボリュームの一部は複数のEC2インスタンスにアタッチするマルチアタッチが利用可能。


### インスタンスストアとEBSの違い
・インスタンスストア
一時的にアタッチされるストレージのこと。
インスタンスの停止・終了・ハードウェア障害によって永続化されないため、データは消える。
ただし課金はされない。

また、インスタンスストアはホストコンピュータのディスクを使用する。
ホストコンピュータに内臓されたディスクで、EC2と不可分のブロックレベルの一時ストレージ。
そこにEC2の一時的なデータが保存される。
EC2の停止＆終了とともにデータは削除される。
sotre-backed AMIとかがそう。このイメージは無料。

・EBS
インスタンスの停止や終了後もデータが保持される。暗号化もされる。
EBSスナップショットで簡単にバックアップもできる。
別のインスタンスに再アタッチすることも可能。

ただし、インスタンスが停止中であっても、EBSがアタッチされていれば課金が発生する。
また、EBSはネットワークで接続されたブロックレベルのストレージである。EC2とは独立して管理されている。

### プロビジョンドIOPS SSDとスループット最適化HDDについて
プロビジョンドIOPS SSDの方が性能がいい。
ただしコスト最適化したい、費用対効果の高さを重視する場合はスループット最適化HDDを選択する

### EBS プロビジョンドIOPS SSDには２種類ある
・EBSプロビジョンドIOPS SSD(io2 Block Express)
パフォーマンス高い。最大4000MB/秒

・EBSプロビジョンドIOPS SSD(io2)
パフォーマンスが次に高い。最大1000MB/秒

### EBSをデタッチする時は
インスタンスを停止してから。

### EBSのスナップショットについて
インスタンス実行中でもしかけることは可能。ただし推奨は停止。
複数のスナップショットをしかけることも可能。ただし最初のジョブが完了するまで、それ以外のジョブはPendingとなる。
また、その際にインスタンスのパフォーマンスが低下する可能性もある。

### ざっくりとストレージの種類について
・ブロックストレージ
EBSやインスタンスストアのこと。

・オブジェクトストレージ
S3, Glacierなど。オブジェクト形式でデータを保存する。

・ファイルストレージ
EFSとか。ファイル形式でデータを保存する。

## EBSのRAID構成
### RAID 0
パフォーマンスを向上させる。複数のディスクを1台のディスクのように扱う。

EBSは標準的なRAID設定は全て使用でき、単一のボリュームで実現できる以上のI/Oパフォーマンスを実現するため、RAID 0では複数のボリュームをまとめてストライピング構成が実施できる。
RAID 0構成により、I/Oがストライプ内のボリュームに渡って分散される。ボリュームを追加すると、スループットとIOPSを追加したことになり、スループットを向上させる。

### RAID 1
ボリュームの冗長性を高める。2つのボリュームを同時にミラーリングする。


### おわりに
引き続き追記します！

以上です。
Rails7 に Bootstrap5を導入しよう！


こんばんは。
Railsの案件にアサインされることになリました。
表題の件でつまづいたので、備忘録として書き残しておきます。

※ `importmap`を使用した導入方法です。
`rails new`時に`-c`オプションに`bootstrap`を指定した場合は、`esbuild`が導入されているので、そちらの手順に従ってください！！！

### 必要な対応
#### CSS<br>
- `Gemfile`に以下を追記
```
gem ‘bootstrap’, ‘~> 5.2.0’
```

- `gem`インストール
```
bundle install
```


- `app/assets/stylesheets/application.css`の名前を`aplication.scss`に変更
`app/assets/stylesheets/application.scss`の中身を全て削除し、以下を追記
```
@import “bootstrap”;
```
- `CSS`が適用されているか確認してください。

<br>

#### JavaScript
**DropDown**などのJavaScriptの読み込みが必要なコンポーネントはこのままでは動かないので、以下の対応を実施

- `config/initializers/assets.rb`に以下を追加
```
Rails.application.config.assets.precompile += %w( bootstrap.min.js popper.js )
```

- `config/importmap.rb`に以下を追加
```
pin "popper", to: 'popper.js', preload: true
pin "bootstrap", to: 'bootstrap.min.js', preload: true
```

- `app/javascript/application.js`に以下を追加
```
import "popper"
import "bootstrap"
```

### まとめ
以上です。
bootstrapを活用して快適なフロントエンド開発を実現していきましょう。
『システム運用アンチパターン』輪読会 ２章「パターナリスト症候群」

## まずは参考文献
[システム運用アンチパターン](https://www.oreilly.co.jp/books/9784873119847/ "システム運用アンチパターン")
システムの開発・運用範囲が異なるエンジニア間でも、共通して会話ができる社内輪読会にはよい書籍

---
## パターナリスト症候群
* あるリソースへのアクセス制限や承認プロセスなど

上記のような規則を正当化するような出来事が過去にあった
初期：チームをより効果的にする意図
経年：チームを停滞させてしまうプロセス
このような状態をパターナリスト症候群と筆者は呼んでいる

### 考え方
* ある行動の実行や承認に必要な資格や信頼性を持つのは特定の人物やグループだけである

---
## ゲートキーパー
パターナリスト症候群の状況において
・仕事の進め方
・仕事のタイミング

を委ねられた（権限をもった）人

---
## 障壁が作られる過程

1.　権限でコントロール

課題：システムの安全性が欠けている（誤操作しやすい状態）
解決策：操作する人を限定する

実情：誤操作のリスクは減っていない。権限保有者にストレスを集中させているだけ

---
## 障壁が作られる過程

2.　承認プロセスでコントロール

課題：その時点のプロセスで対処できない問題が発生した
解決策：問題となったプロセスで承認プロセスを入れる

実情：
* 問題が起こるたびに開発プロセス全体が重くて負担が大きくなっていく
* リリースまでに予定日が変更となるリスクが高まり、価値提供の機会が伸びる
* 新たなヒューマンエラーリスクの発生

---
## DevOps組織におけるアプローチ

ゲートキーパーに対しての改善のゴールとして
* ・チーム間のコラボレーションの強化
* ・不必要なゲートや作業の受け渡しの削減
* ・開発チームがシステムを所有するために必要なツールと権限の提供
* ・再現性のある予測可能なプロセスの構築
* ・アプリケーションの本番環境に対する責任の共有

をCAMSモデルにしたがって実現していく。

その根底として・・・
* 価値を付加するものは残しつつ、人為的な障壁を取り除く

ことにDevOps的組織は気を配る特性がある

１.文化的な問題に正面から取り組む
２.人間の能力の浪費によるコストに焦点を当てる

---
## 書籍としては
2.1節までがここまで。

2.2：障壁の生成の事例

2.3：そこで生じる新たなリスクに関する話

2.4以降：プロセスの自動化によるプロセス負荷の軽減の取り組み方について記載されています。

2.4からは、プロジェクトの進め方に近いものとなり
* ・ステークホルダーからのメンバー選定（ゲートキーパーは必須）
* ・目的の共有が一番重要
* ・解決策のサイズを小さめなものからスタート

などがポイントとなるというお話になります。
[Flutter]BLoC 7.0系から8.0系の破壊的変更に対応した話（mapEventToState廃止）

## はじめに
私の携わっているプロジェクトではflutter_blocを採用しており、
今回7系から8系にアップデートを行いました。

https://pub.dev/packages/flutter_bloc

元々v7.0.0を利用しておりましたが8系で1点破壊的変更が入っており、
対応に関する日本語での記事が少なかった為、今回共有をさせて頂きます。

## 破壊的変更点 （mapEventToState廃止）

v7.0.0を利用していた当初、何かしらのEventを発火させた後にBLoCクラス内では`mapEventToState`を用いて各種Eventのハンドリングを行なっておりました。
この`mapEventToState`は**v7.2.0から非推奨**になり**v8.0.0以降は廃止**となるようです。

> In bloc v7.2.0, mapEventToState was deprecated in favor of on<Event>. mapEventToState will be removed in bloc v8.0.0.
https://bloclibrary.dev/#/migration?id=v720

廃止後は`on<Event>`APIを用いてEventのハンドリングを行う必要があるとのことで、
今回は`mapEventToState`から`on<Event>`APIへの移行を主に対応いたしました。

### 補足
[公式曰く](https://bloclibrary.dev/#/migration?id=v720:~:text=The%20on%3CEvent,to%20state%20changes.)Dartの問題でネストした非同期ジェネレータ（async*）を扱うときにstate値の不確実性問題(?)があったようで、その問題に対応するために、`on<Event>`APIを用いたとのこと。
> The on<Event> API was introduced as part of [Proposal] Replace mapEventToState with on in Bloc. Due to an issue in Dart it's not always obvious what the value of state will be when dealing with nested async generators (async*). Even though there are ways to work around the issue, one of the core principles of the bloc library is to be predictable. The on<Event> API was created to make the library as safe as possible to use and to eliminate any uncertainty when it comes to state changes.



## 対応内容

基本は公式に沿って対応しています。
mapEventToStateを廃止し、各BLoCクラスの下に`on<EVENT>`のハンドリングを記述し、
yieldでstateを返却していた部分を`emit()`に書き換えるだけです。
下記は[公式](https://bloclibrary.dev/#/migration?id=v720)を模したもの。

---
before `v7.0.0`

```dart
abstract class TestEvent {}
class HogeEvent extends TestEvent {}
class FugaEvent extends TestEvent {}

class HogeBloc extends Bloc<TestEvent, HogeState> {
  HogeBloc() : super();

  @override 
  Stream<HogeState> mapEventToState(event) async* { <--ここが消える 
    if (event is HogeEvent) {
      yield HogeState();
    }
    if (event is FugaEvent) {
      yield HogeState();
      final response = await _hogeRepository.fetch();
      yield HogeState(response);
    }
  }
}
```

after `v8.0.0`

```dart
abstract class TestEvent {}
class HogeEvent extends TestEvent {}
class FugaEvent extends TestEvent {}

class HogeBloc extends Bloc<TestEvent, HogeState> {
  HogeBloc() : super() {
      on<HogeEvent>((event, emit) => emit(HogeState())); <--ここが追加される。  
      on<FugaEvent>((event, emit) async { <--こっちも。
        emit(HogeState());
        final response = await _hogeRepository.fetch();
        emit(HogeState(response));
      });
  }
}
```


## まとめ

`flutter_bloc`の7系を使っているPJは全ての`mapEventToState`を書き換える必要がある為、
PJによっては全ての機能を再テストする必要が出てくる可能性があるのではないでしょうか…？
かなりクリティカルではありますがコード修正の難易度自体はそこまで大きくないと思いますので、
早めに対応されることをオススメします。

## 参考サイト
https://blog.logrocket.com/introduction-flutter-bloc-8/

https://bloclibrary.dev/#/migration?id=packagebloc-2

https://stackoverflow.com/questions/71294293/migrating-to-bloc-7-2-0-with-multiple-enevts-and-shared-preferences#:~:text=With%20flutter%20bloc%20%3E%3D%207.2.0%20you%20have%20to%20use%20the%20new%20on%3C%20Event%3E%20API%20and%20replace%20your%20yield%20with%20emit.%20Here%20is%20a%20small%20example
Xcode14.0アップデートしたらpodが使えなくなった。

# はじめに
Xcode14.0へアップデート後、podでライブラリを導入しようとしたら、pod initが出来なくなってしまいました😰

# そんな時は
```
sudo gem install xcodeproj
```
をターミナルで実行してみてください。
mac起動時のパスワード入力を求められますので、入力すればpod initが実行出来る筈です😄
そこそこ人気順でまんべんなく表示したい

作品の一覧表示などで、単純に作品の人気順で表示すると、優秀な同じ作者の作品ばかりが先頭に並んでしまい、バラエティ感のない一覧になったりします。
そんなときは、各作者の１番人気を並べ、次に各作者の２番人気を並べ・・・と並べていくと、バラエティ感が損なわれず、それなりに人気のある作品が前方に並びます。（作者あたりの作品数とその人気のバラツキにもよりますが）

たとえば、以下のような作者テーブル・作品テーブルとデータがあったとします。

```sql
-- 作者テーブル
CREATE TABLE authors
(id integer primary key comment '作者ID',
 name varchar(100) comment '作者氏名'
)  charset = utf8mb4 comment '作者';

-- 作品テーブル
CREATE TABLE works
(id integer comment '作品ID' primary key,
 name varchar(100) comment '作品名',
 author_id integer comment '作者ID',
 popularity integer comment '人気度 0-100'
) charset = utf8mb4 comment '作品';
ALTER TABLE works
    ADD CONSTRAINT works_authors_fk
        FOREIGN KEY (author_id) REFERENCES authors (id);

-- 作者データ
INSERT INTO authors
  (id, name)
VALUES
  (1, '山本 茂'),
  (2, '篠田 光一'),
  (3, '浅川 慎二'),
  (4, '狩野 元気'),
  (5, '坂下 和美');

-- 作品データ
INSERT INTO works
  (id, name, author_id, popularity)
VALUES
  (1, '春の唄', 1, 98),
  (2, '日差し', 1, 97),
  (3, '北の海', 1, 92),
  (4, 'やわらかな時間', 1, 95),
  (5, '参鶏湯', 1, 73),
  (6, '晩餐会の準備', 2, 90),
  (7, 'やまなみ', 2, 93),
  (8, '記憶の破片', 2, 72),
  (9, '不如帰', 2, 91),
  (10, '大地の声', 3, 88),
  (11, '給食当番', 3, 76),
  (12, '遠足の前の日', 3, 70),
  (13, '校庭十二周', 3, 68),
  (14, 'コンクール', 4, 89),
  (15, '海を見つめて', 4, 86),
  (16, '弓道場', 4, 83),
  (17, '図書館カード', 4, 81),
  (18, '明るい玄関', 5, 88),
  (19, '注意散漫', 5, 77),
  (20, '風の通り道', 5, 74);
```



# 単純な人気順でのソート

```sql
-- 単純な人気順
SELECT works.id, authors.name, works.name, popularity
FROM works
JOIN authors on works.author_id = authors.id
ORDER BY works.popularity　DESC -- 人気度の降順でソート
LIMIT 10
;
```

上記のような SQL で単純に人気順でソートをかけると、人気の高い「山本 茂」や「篠田 光一」の作品ばかりが先頭に並びます。

|作品ID|作者名|作品名|人気度|
|-:|:-|:-|-:|
|1|山本 茂|春の唄|98|
|2|山本 茂|日差し|97|
|4|山本 茂|やわらかな時間|95|
|7|篠田 光一|やまなみ|93|
|3|山本 茂|北の海|92|
|9|篠田 光一|不如帰|91|
|6|篠田 光一|晩餐会の準備|90|
|14|狩野 元気|コンクール|89|
|10|浅川 慎二|大地の声|88|
|18|坂下 和美|明るい玄関|88|

# ウィンドウ関数を使ったソート

そこで、 ROW_NUMBER() とウィンドウ関数を使い、各作者ごとに人気順でランキングを付けて、そのランキングで順位をつけます。同じ順位の場合は人気度が高いほうが前に並ぶようにします。

```sql
-- 各作者内でのランキング > 人気順
SELECT works.id, authors.name, works.name, popularity,
    -- 各作者ごとに人気順のランキングを付ける
    ROW_NUMBER() OVER(PARTITION BY author_id ORDER BY popularity DESC) ranking
FROM works
JOIN authors on works.author_id = authors.id
ORDER BY ranking, -- 各作者ごとのランキング上位を順に表示
works.popularity DESC -- 同じ順位の場合は人気度が高いほうを優先
;
```

こうすることで、特定の作者に偏らないそこそこ人気順の作品一覧ができます。

|作品ID|作者名|作品名|人気度|各作者内でのランキング|
|-:|:-|:-|-:|-:|
|1|山本 茂|春の唄|98|1|
|7|篠田 光一|やまなみ|93|1|
|14|狩野 元気|コンクール|89|1|
|10|浅川 慎二|大地の声|88|1|
|18|坂下 和美|明るい玄関|88|1|
|2|山本 茂|日差し|97|2|
|9|篠田 光一|不如帰|91|2|
|15|狩野 元気|海を見つめて|86|2|
|19|坂下 和美|注意散漫|77|2|
|11|浅川 慎二|給食当番|76|2|
一般大学生がGo言語に初めて触れてみた！！【スターティングGo言語】

# はじめに
最近インターンシップや本選考を見るとやたら**Go言語**を使っている企業が多い気がします（笑）．
なので，Go言語について勉強したいなと思い，書籍を購入しました．
今回は，Go言語初学者として[スターティングGo言語(松尾 愛賀/翔泳社)](https://www.amazon.co.jp/dp/4798142417?tag=keiji009-22&linkCode=ogi&th=1&psc=1)を購入し，当書を読んで感じたGoの印象を書いていきたいと思います！！
誰かしらの参考になればな...と思いながら書きましたので，気軽に見てもらえると嬉しいです😀

[<img width=300 src = "https://images-na.ssl-images-amazon.com/images/I/51AFmxAFZJL._SX357_BO1,204,203,200_.jpg">](https://www.amazon.co.jp/dp/4798142417?tag=keiji009-22&linkCode=ogi&th=1&psc=1)


# 当書のいいところ
まずは，当書を読んでみて，いいなと思った点がたくさんあったので是非参考にしてください！！

* ### **基礎的な部分をほぼ網羅している**
この一冊で基礎的な部分がきっちりと記載されているため，**初学者の勉強**としてもわからないところを調べる**辞書的な使い方**のどちらもできるなと感じました．
また，自分のように一冊目から**詳しくガッツリと勉強したい**という人にとっては，この書籍はめちゃめちゃありです！！

* ### **初心者に対してGo言語の良さを共有してくれる**
この書籍はGo言語初学者向けに作られていると感じました．
その中で著者は，**他言語との違いやGo言語ならこういうことができるといったメリット**について多く記載されていました．
このような，Go言語のコーディング基礎を学びながら，**Go言語の本質的な基礎・特徴**を学ぶことができる点は，初学者に対して**Go言語に興味を持ってもらうための著者の工夫や熱い思い**をひしひしと感じました．
特に，他言語を扱ったことがある人にとっては，その利点をより強く感じれるのではないでしょうか！！

* ### **エラー例が多く記載されている**
「こういうコードは...が理由でエラーになってしまう」といった点が数多く記載されている．
そのため，**こういう点は注意しよう/こういう風には書かないでおこう**と今後コーディングをする際に意識しながらコーディングすることができました．

# Go言語について学んだこと
当書で学んだGo言語のあれこれを記載しておきます．

* ### **文法がシンプル**
このようにシンプルかつ簡素にコーディングが可能なため，他の言語を扱っている人にとってはそこまで苦痛にはならないのでは...という印象を受けました😊
特に，**セミコロン**や**型名**を定義せずに，実行できるといった点は，大規模な開発などにおけるコーディング時間を短縮できるといった恩恵をより感じることができそうですね～
また，個人的には，普段からPythonを利用している人は，上記の定義をしていない人も多いため，抵抗なくコーディングできるかも👀

~~~ go:main.go
package main 

import fmt

m := 100

func main() {
    m = m + 1
    fmt.Println(m)
}
~~~

* ### **無駄な変数に注意**
使っていない変数があった場合，そのまま実行してしまうとエラーになってしまうということに衝撃を受けました😲
例えば，下のコードはエラー出力されてしまいます．

~~~ go:main.go
package main 

import fmt

m := 100
n := 200

func main() {
    fmt.Println(m)
}
~~~

普段使っている言語によって違和感を感じない人もいるかもしれませんが，Pythonを使っている自分にとっては最初はエラーで引っ掛かりまくりでした．
**なんでこんなに使いにくいんだ...😠**と感じましたが，それが逆にGo言語のある狙いがあったんだと当書で気づかされました．

例えば下のコードを見てください．
下のコードは，変数mとnの両方を出力するプログラムと想定してください！

~~~ go:main.go
package main 

import fmt

m := 100
n := 200

func main() {
    fmt.Println(n,n) //本来ならfmt.Println(m,n)と書きたかった！！
}
~~~

このようにそれぞれ違うmとnを出力するコードを書きたかったが，うっかり両方ともnを書いてしまうことはよくあるケースです．
こういった場合でも，変数を使っていなければエラーになるGo言語の特性から，**変数mを定義だけしてるけど，使ってませんよ～**といったことに気付かせてくれるのだ！！
こういった意図があったんだと気づき，1分前の謎に切れてた自分に**頭を冷やせ🥶**と言いたくなりましたね（笑）



# まとめ
今回は，Go言語初学者が[スターティングGo言語](https://www.amazon.co.jp/dp/4798142417?tag=keiji009-22&linkCode=ogi&th=1&psc=1)で学んだことを記載しました．最後にGo言語のポイントをまとめておきます！！

:::note info
グッドポイント👍
**文法が基本的にシンプルで書きやすい**
**セミコロンや型名を書かなくてもいい**
 
:::

:::note warn
注意👀
使っていない変数があればエラーになる

:::

次は，学んだ知識を生かして，Go言語で何か一つ開発できればな～．それではこの辺で...🙋‍♂️
How to create Nextron(NextJS + electron) app?

## そもそもNextronとは何なのか

Nextronとはelectron+NextJSの環境を今までより簡単に構築できるようにつくられた(らしい)ツールです。とはいえ私はいきなりこれでやったので今までのやり方をしらないんですけども結構開発がしやすいです。

## プロジェクト作成方法

まずは以下のコマンドを入力

```
npx create-nextron-app <ProjectName>
```

割と軽めなので回線が良ければすぐ終わります。

そして
```
npm run build 
```
と入力してビルドします。これをしないとエラーになるのでお気を付けて。通常のelectronだとpackage.jsonとかmain.jsを作成・編集しないとうまく起動しませんが、Nextronは勝手にやってくれるので楽ですね。

んじゃあ

```
npm run dev
```
と入力すれば実行できます。

ちなみに起動時は開発者ツールが自動で立ち上がります。メインページはrender/pages/home.jsxとなります。まずはそのファイルを編集して挙動を確かめてみましょう。

それでは。
ESP32 での BLEScan メモ

# ESP32での BLEScan メモ
BlueToothデバイスのスキャンを行う時に、 BLEScanクラスを使いますが、パラメータ等で不明な部分があったので調査とその結果のメモです。

## setInterval()と setWindows()と start()の関係
スキャンを行うパラメータとして、Intervalと Windowと、startに与えるスキャン時間がありますが、その関係を実際にプログラムを動かしてその挙動から調査しました。

* Window = 実際のスキャンを行う時間(ミリ秒)
* Intercal = スキャン間隔(ミリ秒）
* start(時間) = スキャン全体の時間(秒）

少しわかりにくいので図示するとこのような関係になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221204/873bf9df-d078-f28c-cdfa-5e7ec71f1377.png)

* Window ≧ Inteval ≧ start時間*1000
の関係になります。

start()時間が残っている限り、スキャンが繰り返されるようです。interval途中でもstart時間がすぎるとスキャンは打ち切られるようです。

## (interval - window) で生まれる間隔に意味があるか
長さを変えても、実験の範囲では有意な変化は見られませんでした

## start時間の長さに意味があるか
実験上は、60秒のstart処理よりも1秒のstart処理を60回行ったほうが、検出回数がはるかに多くなりました。（同じデバイスの重複検出を含む）
仕組みは不明ながら、startでの検出イベントの発生は、時間が経つほどどんどん少なくなります。

## ストラテジ
実験の結果から、 interlval = window = start時間で、 値は1,2秒、これをループで回すというのが一番スキャナとしては使いやすいと感じました。
Scanのコールバックの中で処理を行うのであればいいですが、コールバックでは検出のみを記録し、Scan後に処理を行うなどの場合は、Scan時間を短くしたいという事情もあります。
【Linux】cronの設定方法

## cron とは
cron を使用することで指定した時間や期間で自動的にコマンドを実行してくれます。

## 設定方法

cronの設定をするにはターミナルで`crontab -e`を実行します。

```zsh:ターミナル
crontab -e
```

するとエディタが開きますので設定ファイルを編集します。

このとき開くエディタは以下のように`EDITOR`変数で設定できます。

```.zshrc
export EDITOR=vim
```

設定ファイルは以下の形で記述します。

```:crontab〜
*  *  *  *  *  実行するコマンド
```

`*`の箇所にコマンドを実行する時間を記述します。

指定できる値は下記のようになります。

左から　分　時　日　月　曜　に対応します。
それぞれ以下の範囲を指定できます。

|指定対象|指定範囲|
|:-:|:-:|
|分|0〜59|
|時|0〜23|
|日|1〜31|
|月|1〜12 または jan〜dec|
|曜日|0〜7 または sun〜sat|

※曜日の0~7のうち0と7が日曜日になります。


ユーザーごとに設定でき、実行ユーザーは設定したユーザーになります。

他のユーザーの設定をしたい場合には`crontab -e`を実行する際にユーザーを指定します。

```zsh:ターミナル
crontab -u ユーザー名 -e
```


またコマンドの実行場所は実行ユーザーのホームディレクトリになります。
ディレクトリ移動が必要な場合には以下のように記述して移動します。

```
* * * * * cd 移動先ディレクトリ; 実行するコマンド
```

cronでコマンドが実行されると実行ユーザーにコマンドの標準出力、標準エラー出力がメールされるようになっています。
メールの宛先を変更したい場合には`MAILTO`変数で設定します。
```:crontab〜
MAILTO="sample@example.com"
*  *  *  *  *  実行するコマンド
```
またメールを送信しないでほしい場合には空にします。
```:crontab〜
MAILTO=""
*  *  *  *  *  実行するコマンド
```
MySQLのProgrammingError

何のエラーか探すのに困ったシリーズ。

環境：
Windows10
Python3.7(Anaconda)
MySQL

```
ProgrammingError: (1064, "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '99999.9e9' at line 999")
```

Python側のpymysqlモジュールにて、
MySQL文のLIMIT句に渡した変数が
予期せず float型 になっていたからだった。
行数だから int型 でないとダメ。

ProgrammingError:
なんて出たから、SQL文が悪いのかとずいぶん考えた。
ま、プログラミングのエラーと言えば間違いないが・・・
このエラーが出てハマった際、参考になれば幸い。
S3のファイルをcatみたいに標準出力する方法

# やりたいこと
S3にあるファイルをダウンロードしないでちょっと見たいです。
`cat`コマンドでローカルのファイルを見る感じで、気軽に見たいです。

# cp + 「-」で標準出力にファイルの内容を出力できた

```zsh:S3のファイルをcatみたいに標準出力する方法
$ aws s3 cp s3://{バケット}/{ファイルパス} -
```

標準出力する方法が、ちゃんとAWSのサイトに書いてありました。

> s3 cp コマンドは、次の構文を使用して stdout 用の Amazon S3 ファイルストリームをダウンロードします。
> [Syntax] (構文)
> `$ aws s3 cp <target> [--options] -`
> [AWS CLI での高レベル (S3) コマンドの使用 - AWS Command Line Interface](https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-services-s3-commands.html#using-s3-commands-managing-objects-copy)

```zsh
# 標準入力からファイルを作ったり、
$ echo chovin頑張る | aws s3 cp - s3://pon-bucket/chovin.md
# catみたいにファイルの中身を見たりできる
$ aws s3 cp s3://pon-bucket/chovin.md -
chovin頑張る

# ヒアドキュメントでもファイルを作れて、
$ cat <<_eof_ | aws s3 cp - s3://pon-bucket/chovin.md
pipe heredoc> chovinは頑張らないでs3にあるファイルを
pipe heredoc> catみたいに
pipe heredoc> 気軽に見たい
pipe heredoc>_eof_
# 気軽に中身を見たりできる
$ aws s3 cp s3://pon-bucket/chovin.md -
chovinは頑張らないでs3にあるファイルを
catみたいに
気軽に見たい
```

## 文字化けしたら他のコマンドと合わせればいい
私、実は日本人なのでSift-JISのファイルを使うことがあります。

```zsh
# 当然ながら文字化けする
$ aws s3 cp s3://pon-bucket/fuga.md -
?X?e?B?[?u?E?W???u?X
?u???Ԃ͌????Ă???̂?????A???l?̐l???𐶂??Ď????̎??Ԃ𖳑ʂɉ߂????Ă͂????Ȃ??v
```

文字化けすると読めないけれど、ダウンロードするのも面倒くさいです。
そんな時は、`iconv`や`nkf`など文字コードを変換できるコマンドと合わせて使えば問題なしです。

```zsh
$ aws s3 cp s3://pon-bucket/fuga.md - | iconv -f sjis 
スティーブ・ジョブス
「時間は限られているのだから、他人の人生を生きて自分の時間を無駄に過ごしてはいけない」
```
CloudWatch Logs のログ調査がはかどる便利な方法

CloudWatch Logs でログデータの調査を行う際に**特定の文言を検索**したくて、ついつい、ブラウザの検索機能（Ctrl + Fキー）を使ってしまう事って割とやってしまうのですが、
**CloudWatch Logs Insights** を使えば、もっと便利に特定の文言を検索することができるので、ここにまとめておきたいと思います。

## CloudWatch Logs Insights とは何か？

CloudWatch Logs のログデータを検索や分析できるようになります。
[CloudWatch Logs Insights を使用したログデータの分析 - Amazon CloudWatch Logs](https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/logs/AnalyzingLogData.html)

## 使い方

使い方はとてもシンプルです。
CloudWatch のメニューにある「ログ」→「ログのインサイト」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/759747/d6df358a-3f8b-e56e-7e10-ece57b51fd9b.png)

選択対象となるロググループを指定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/759747/7c9c9080-66d9-723a-2c37-8bf23a6adc7b.png)

検索対象期間の指定を行います。
未入力でも検索は可能ですが、だいたいは期間を指定して検索することが多いのではないでしょうか。
![img003.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/759747/407d1619-3524-87a6-d36c-85a321152e8d.png)

クエリを入力する箇所に以下を入力します。

```sql
fields @timestamp, @message
| filter @message like /Start|START|start/
| sort @timestamp desc
| limit 20
```

ポイントは２行目になります。
今回はログの中から「Start」「START」「start」という文言を検索したいため、このように記述しています。
`filter` や `like` など、特に説明が無くても何となく理解できるのではないでしょうか。

クエリを入力して「クエリの実行」ボタンを押下すると、指定した文言がヒットしたログデータが表示されます。
また、ヒストグラムが表示されるので、ちょっとした分析（毎週○曜日に Error メッセージが沢山出る、など）にも役立ちそうです。
![img004.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/759747/35af1df4-a192-e417-87c9-720e2fbe8f7b.png)

## 最後に

[料金を確認](https://aws.amazon.com/jp/cloudwatch/pricing/)すると「スキャンしたデータ 1 GB あたり 0.0076USD」との記載がありました。
→ ap-northeast-1 リージョン、2022年9月現在

ログデータが巨大な場合は（実行しすぎないように）気を付けた方が良いかも知れません。
![img005.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/759747/726b156a-ac71-1f25-477b-d04d14ee73ac.png)

文言の検索以外にも色々と出来ることがあるようで、以下の Qiita 記事で詳しく紹介されていたので、興味のある方は確認してみてください。
- [AWS初心者がCloudWatch Logs Insightsを使ってみた - Qiita](https://qiita.com/suuu/items/8387df88f134348f22c7)
- [CloudWatch Logs Insightsの簡単なまとめ - Qiita](https://qiita.com/sakochi/items/8e60654ffe36432c5228)
インプレースアップグレードと並行アップグレード

## 勉強前イメージ

どっちも聞いたことないの・・・・

## 調査

### インプレースアップグレード とは

in-place upgrade と書き
単体では、稼働中のシステムに既存の環境やデータを維持したままソフトウェアの更新を直接行うことを言います。
複数での分散を行っている場合は、一旦停止してソフトウェアを入れ替えて稼働する方式を言います。
アップグレードインストールなどと呼ばれることもあります。
単体では稼働中のまま行うので、もしものときのことを考えておく必要があります。

### 並行アップグレード とは

並行アップグレードとは、新しいサーバ・インスタンス上で新しいOSで設定やデータを入れて稼働させることを言います。
要するに移行みたいなイメージです。
新しいところに別で作るのでインプレースアップグレードより安全に行なえますが、時間がかかります。

## 勉強後イメージ

並行アップグレードって移行のことか。

## 参考

- [インプレースアップグレード 【in-place upgrade】](https://e-words.jp/w/%E3%82%A4%E3%83%B3%E3%83%97%E3%83%AC%E3%83%BC%E3%82%B9%E3%82%A2%E3%83%83%E3%83%97%E3%82%B0%E3%83%AC%E3%83%BC%E3%83%89.html)
- [Amazon EC2 Windows インスタンスのより新しいバージョンの Windows Server へのアップグレード](https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/WindowsGuide/serverupgrade.html)
Windows10のバッチでバッチファイル自身のファイルパスを取得

# やり方

```bat:バッチファイル自身のファイルパスを表示するサンプル
rem ダブルクオテーションあり
echo %0

rem ダブルクオテーションを除去
echo %~0

rem 確認の為に一旦止める
pause
```

結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/7657e99a-3c48-c3e2-3e30-496423657fe1.png)

# %0や%~0は一体何なのか

まずバッチにおいて ```%数字``` は引数を意味している。
例えば ```%1``` なら第一引数、といった形。

つまり ```%0``` は第ゼロ引数を意味している。
そして第ゼロ引数は **バッチファイル自身のファイルパス** という特別な引数である。

だがここで問題がある。
```%0``` だとダブルクオテーション付きの文字列になってしまう。

そこで ```~``` が登場。
%と0の間に ```~``` を付けることでファイルパスからダブルクオテーションを除去できる。

# 参考サイトさん

https://web.plus-idea.net/2016/09/know-dp0-windows-meaning/

# バージョン

Windows 10 Pro 21H2 OSビルド 19044.2006
pickle install redisでシリアライザとしてigbinaryを有効にする方法

# 先に結論から

```
# 先にigbinaryを入れる
pickle install igbinary -n

# オプションをテキストファイルに出力
echo "--enable-redis-igbinary" > redis-options.txt

# --with-configure-optionsでオプション指定のテキストを指定
pickle install redis -n --with-configure-options=redis-options.txt
```

# 経緯

- php環境にredisクライアントを入れたい
- peclではなくpickleを使いたい
- 単に `pickle install redis` としてもigbinaryが有効にならない
  - インタラクティブモードで実行され、プロンプトに対してyes/noで回答していくと有効になる
  - Dockerfileでプロンプトに都度入力するのは困難
- pickleをバッチモードで実行しつつ、 `--enable-redis-igbinary` したい
私ってどこ目指してるんだっけ・・・？

<h1>初めまして！！</h1>
<h3>ご訪問ありがとうございます！！！</h3>
書き出しから何をどう書こうか1時間以上迷ってしまっている私です。。。

都内SES企業でエンジニアをしている94年産のモデルになります
最近ふと最近気付いたら１年以上コーディングを全く行っていなくて要件定義や基本設計などに携わることが増えてエンジニアとして会社から求められるのは開発スキルや経験なのに対して現場で評価されているのは顧客折衝能力や要件分析能力、オフショアチームとの連携部分であったり会社の評価と現場の評価で乖離が生まれてしまっていて

<h4>私って何者・・・？</h4>

と迷いに迷えるエンジニア6年生になります。
そこでそんな不安を解消するためにはどうしようと考えた結果、
<h4>そもそもエンジニアってなんだ！？っていうか私将来何やりたいんだ？？</h4>

と正解のない沼に落ちてしまいそうになっているのです。。
そんな中エンジニアとしての技術力の向上、また将来どんなことをしたくて自分の強みが生かせる部分ってどこだろうと考えたときに開発を極めてスペシャリストを目指すよりはコミュニケーション能力やリーダー経験などを生かして色々挑戦してみたいと思いました。

しかし具体的に将来どんな道があるかが具体的にイメージができないのも含め自分の知識不足などを踏まえてインプットの量を増やすことを第一目標として立ててイベント参加などをどうせするのであれば自分の備忘を兼ねてアウトプットとしてQiitaに投稿しておこうと思ったので始めることに致しました


<h4>長く語りましたが自分のアウトプットとしての面と自分のために業務で調べたことやイベントに参加したことについて記録を残そう！</h4>

としてQiitaに投稿していきたいと思います。まだまだ未熟な私でありますが暖かい目で見守って頂ければなと思います！
Salesforce認定アドミニストレーター試験の公式練習問題を解説してみた-その024

こんにちは。本橋孝昭です。

Salesforce認定アドミニストレーター試験の公式練習問題があるのはご存じでしょうか。
Trailheadにフラッシュカードとして何度も解ける練習問題がございます。

今回はTrailhead
アドミニストレーター認定の準備: アプリケーションと活動
セールスアプリケーションとマーケティングアプリケーションの確認

にある練習問題4問目をご紹介します。
https://trailhead.salesforce.com/ja/content/learn/modules/administrator-certification-prep-applications-activities-and-mobile/review-sales-and-marketing-applications?trail_id=administrator-certification-prep

なおこちらの内容は動画でも解説していますのでぜひご確認ください

https://www.youtube.com/watch?v=oqO7ft6Oh5E&t=11s

<iframe width="560" height="315" src="https://www.youtube.com/embed/oqO7ft6Oh5E" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

問題はこちらです

![004.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/f39a13a0-8645-3ca8-ecaf-ee85683261bd.png)


正解はとAとBです

ダッシュボードを佐久市江すれば商品の比較が可能です。


また、Chatterグループでは、ダッシュボードの共有が可能です



大規模商談アラートは商談受注のアラートなので間違いです
Google Formsの回答からWord Cloudを作成するスクリプト

## 背景
Google Formsの回答をWord Cloudで表示できれば、資料を作成する際に便利かなと思い作成した。
## 使い方
### 事前準備
+ claspをインストール
```
~$ yarn global add @google/clasp
# or
~$ npm install -g @google/clasp
```
+ Google Formsで単一選択形式の質問を用意（複数可）
+ [ここ](https://script.google.com/home/usersettings)でGoogle App Script APIを有効にする
+ ソースコードをクローンする
```
~$ git clone https://github.com/capybara-alt/googleforms-wordcloud.git
```
+ claspの設定を行う
```
~/googleforms-wordcloud$ clasp init $SCRIPT_ID
```
### 使い方
+ Google Formsの[Script editor]を押下し、Google App Scriptのエディタを開く
+ ソースコードをプッシュする
```
~/googleforms-wordcloud$ clasp push
```
+ Google App Scriptにコードが反映されていることを確認し、[Deploy]→[New Deployment]でデプロイを行う
+ デプロイ後、Webページに移動し、下のように表示されることを確認する
![スクリーンショット 2022-09-15 18.43.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316006/55446c00-2429-0252-0e1f-ba0b0253e0e2.png)
+ [Select item]から対象の質問を選択する
![スクリーンショット 2022-09-15 18.46.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316006/26549c2d-e9f3-bf4f-629e-3c5bceb1b72d.png)
+ 下のようにWord Cloudが表示される（右上のダウンロードボタンでsvg形式でのダウンロードが可能）
![スクリーンショット 2022-09-15 18.46.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316006/9c4503ed-4afc-abe4-9086-0e5f102fa687.png)
## 今後
Google Formsのドロップダウン形式の質問などの、回答が単一選択形式の質問のみ対応するように作成したので、今後、複数選択可能な質問の回答からWord Cloudを作成できるようにする（予定）。
Toggl Trackで別アカウントにデータを移す方法（CSVデータをエクスポート・インポート）

# はじめに
プログラミング学習中の[@kat_log](https://twitter.com/kat__log "Twitter")と申します。

Toggl Trackにて、メインで使うアカウントを変更しようとしたのですが、データの移行で戸惑ったのですが、解決したので共有です。

![image.png](https://soco-st.com/wp-content/themes/socost/upload/11813_color.svg)

# 手順

## エクスポート

1. 左のメニューからReportsをクリック
1. Detailedをクリック
1. 右上のダウンロードアイコンをクリック
1. Download CSVをクリック
1. 任意のフォルダに保存する

![Screen Shot 2022-09-15 at 18.00.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1455073/8388d755-5bfc-cd65-9461-5f44c964779a.png)

以上の手順で、まずCSVファイルとしてデータを入手します！

## インポート

1. 左のメニューからSettingsをクリック
1. CSV importをクリック
1. Select CSV file to uploadをクリック
1. ファインダーからCSVファイルを選択する

![Screen Shot 2022-09-15 at 18.11.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1455073/a0dad2fc-6745-346f-a6fc-0dfab88f81d4.png)

以上の手順でデータを取り込んで完了です！

# （余談）戸惑ったポイント

自分は最初、Settings→Data exportでjsonファイルをダウンロードしたのですが、json形式でのインポート方法が分からず戸惑い、上記手順にたどり着きました。

# おわりに
お読みいただきありがとうございました。
Toggl Track使いの方の参考になれば嬉しいです。

# 参考

https://support.toggl.com/en/articles/2564936-exporting-data

https://fluentlife.jp/blog-entry-31/#toc2
PlayCanvas Editor対応のファイル形式（インポートした際にAsset Typeが認識される拡張子一覧）


PlayCanvas Editorにインポートした際に、コンポーネントとして扱われる拡張子は下記の拡張子となります。

- 2023/02/17 `.glb`, `glTF` Draco圧縮に対応
- 2023/03/22 `Opus`が追加されました
- 2023/10     `avif`, `webp`が追加されました。

### 3Dモデル(source scene/render / model / template)
3Dモデルの場合はRenderまたはModelに変更されます。PlayCanvasエディタにインポート可能な3Dモデルはこちらです。
- `fbx`
- `dae`
- `obj`
- `3ds`
- `glb`

### テキスト(text)
- `txt`
- `xml`
- `atlas`

### テクスチャ（texture）
- `tif`
- `tga`
- `png`
- `jpg`
- `jpeg`
- `gif`
- `bmp`
- `dds`
- `hdr`
- `exr`
- `webp`
- `avif`


### 音声(audio)
- `wav`
- `mp3`
- `mp4`
- `ogg`
- `m4a`
- `opus`

### フォント(font)
- `ttf`
- `ttc`
- `otf`
- `dfont`
※ フォントについてはアップロードした際にFontアセットに変換されます。フォントをバイナリデータとして利用したい場合には上記以外のファイル名にしてアップロードする必要があります。

### シェーダー(shader)
- `glsl`
- `frag`
- `vert`

### HTML(html)
- `html`

### CSS(css)
- `css`

### JSON(json)
- `json`


### その他(binary)
それ以外のファイルをアップロードした場合には、`binary`として扱われます。

> typeがbinaryのアセット
![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/257048/4ca28c31-70cd-4b85-dd4d-5621b177e9a3.png)
【LINE WORKS】外部ブラウザ設定を有効にする

[外部ブラウザ設定の有効化](https://developers.worksmobile.com/jp/reference/security-external-browser-enable?lang=ja)
モバイル版アプリでURLをタップした際、OSの標準ブラウザで開くように設定する。
デフォルトではLINE WORKSのアプリ内ブラウザで開くように設定されている。
> 有償版のみ利用可能（フリープランでの使用不可）

# PostmanでLINE WORKS APIを利用する
[【LINE WORKS】LINE WORKS API 2.0をPostmanで手っ取り早く試してみる【サンプルあり】](https://qiita.com/mmclsntr/items/eee8d8f3546410fe6652)
[プログラミング知識0が挑むLINE WORKS API2.0 part1（postman準備編）](https://qiita.com/tnk-tty/items/bf663ac9ee2101e1805c)

事前準備として、上記記事を参考に、PostmanでLINE WORKS APIが利用できるよう設定する。

## アプリにスコープを追加

外部ブラウザ設定APIを利用するために `security.external-browser` スコープを追加する。

1. [Developer Consoleのアプリのページ](https://developers.worksmobile.com/jp/console/openapi/v2/app/list/view
)を開く
2. 使用するアプリを選択
3. `OAuth Scopes` の「管理」ボタンをクリック
![1663224464.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2726616/3d1c102d-0630-3086-211e-e89a88cbf1a0.png)
4. `OAuth Scope の選択` 画面で `security.external-browser` にチェックを入れて「保存」ボタンをクリック
![1663228364.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2726616/24edcb78-24b7-fe2e-0cfe-8b461760412c.png)

アプリに `security.external-browser` スコープが追加される。

## Postman用サンプルファイル

外部ブラウザ設定APIを利用するためのサンプルファイルを用意した。

1. [Git-Hub](https://github.com/ts-suzuki/lw-api-2_0-postman-External-Browser-sample)にアクセス
1. 「Code」ボタンをクリックして「Download ZIP」を選択
1. ダウンロードしたファイルを解凍する
1. `postman` フォルダ内にサンプルファイル `External-Browser.postman_collection.json` があることを確認

![1663294924.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2726616/6e257c64-7933-37d9-055e-8901dc724ec0.png)

## サンプルファイルの読み込み

Postmanの画面上の「Import」からサンプルファイルを取り込む。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2726616/29a7dbe5-dc06-c66c-b340-30c6cc329043.png)

サンプルファイル `External-Browser.postman_collection.json` を読み込み「インポート」ボタンをクリック
![1663229767.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2726616/0293b2d3-016d-2591-9b9c-495e2aa3b95a.png)
![1663229918.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2726616/1961874f-b915-c77f-98e7-5c7d3b571f11.png)

Postmanに外部ブラウザ設定コレクションが追加される。

## API Request

1. コレクションの `Access Token 取得` を選択して「Send」ボタンをクリック
![1663230214.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2726616/06724637-63b0-5691-fb93-f1d7c585cd7d.png)

2. コレクションの `外部ブラウザ設定の有効化` を選択
3. `Body` タブを選択して `domainId` を入力し、「Send」ボタンをクリック
![1663230579.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2726616/0334111f-e0a0-dfe3-5b06-358d27adb7ad.png)

成功した場合 `204 No Content` がResponseされる。

これで、モバイル版アプリでURLをタップした際、OSの標準ブラウザで開くように設定された。
SQL複数テーブルのまとめ(サブクエリとJOIN)

# サブクエリ
クエリの中にクエリの中を入れられる。この中に入れたクエリを **サブクエリ** という。
２つ以上のクエリを１つにまとめられる。
例えば、1. ドレスシャツの価格を取ってきて、
```sql
SELECT price
FROM closet
WHERE name = "ドレスシャツ";
```
出力したドレスシャツの価格:4000
2.自分で取ってきた値を入力する。
```sql
SELECT price
FROM closet
WHERE price > 4000; --取ってきたドレスシャツの価格
```
という二度手間を、以下のように一つにまとめられる。
```sql
SELECT price
FROM closet
WHERE price > ( --この括弧内がサブクエリ(ドレスシャツの価格:4000)
  SELECT price
  FROM closet
  WHERE name = "ドレスシャツ"
); 
```
サブクエリ内にセミコロンはいらない。
実行順序は、()の中のサブクエリが先。

# AS
`AS`はデータを読みやすくするのに使われる。
`SELECT`内のカラム名につける。
構文は`カラム名　AS "名前"`で、カラム名を"名前"に変えられる。
```sql
SELECT price AS "ドレスシャツの価格" --実行結果のカラム表示がpriceから"ドレスシャツの価格"に変更される。
FROM closet
WHERE price = "ドレスシャツ";
```
実行結果　priceがドレスシャツの価格に変わっている。
| ドレスシャツの価格 |
|:-:|
| 4000  |

# 複数のテーブルを扱う。
紐付けのメリットは、たくさんあるカラムの情報を一つにまとめた別テーブルがあることで、変更が容易になる。

# JOIN 結合
`JOIN`で、複数のテーブルを１つに結合する。
`ON`で、どうやって結合するか決める。
構文：`ON テーブルA.カラム名　＝　テーブルB.カラム名`
例えば、以下の`ON`では、closetテーブルのbrand_id(外部キー)と、
brandsテーブルのid(主キー)で紐付けている。

```sql
SELECT *
FROM closet
JOIN brands
ON closet.brand_id = brands.id;
```

`JOIN`の実行順は、1.結合、2.`SELECT`実行。

複数のテーブルに同じカラム名があるときは`テーブル名.カラム名`で指定。
```sql
SELECT closet.name, brands.name --テーブル名.カラム名
FROM closet
JOIN brands
ON closet.brand_id = brands.id;
```
`テーブル名.カラム名`は`WHERE`でも使える。
```sql
SELECT closet.name, brands.name --テーブル名.カラム名
FROM closet
JOIN brands
ON closet.brand_id = brands.id;
WHERE closet.name = "ドレスシャツ";
```
# 全ての実行順　上から実行
| 操作 | SQL |
|:-:|:-:|
| テーブルの指定  | FROM  |
| 結合  | JOIN ON |
| テーブル全体での絞り込み  | WHERE  |
| グループ化  | GROUP BY  |
| 集計関数  | COUNT SUM AVG MAX ...  |
| グループ化後の絞り込み  | HAVING  |
| カラムを決める  | SELECT DITINCT  |
| 並べ替え  | ORDER BY  |
| いくつまで  | LIMIT  |

# LEFT JOIN
`JOIN`するとき、外部キーが`NULL`は飛ばされる。
`NULL`も含める時、`LEFT JOIN`を使う。
```sql
SELECT closet.name, brands.name --テーブル名.カラム名
FROM closet
LEFT JOIN shops
ON closet.shop_id = shops.id;
```

# 複数テーブルをJOIN
`JOIN`は１つのクエリで何回も使える。`FROM`は１つ。結合元は１つなので。
```sql
SELECT closet.name, brands.name --テーブル名.カラム名
FROM closet
JOIN brands
ON closet.brand_id = brands.id;
LEFT JOIN shops
ON closet.shop_id = shops.id;
```
Tableau Serverメモ

自分用のメモです。

# パーミッション関連

# UI関連
### Web編集で他の人が所有者になっているワークブックを上書きする
* 他の人が所有者になっているワークブックは、そのワークブックに「上書き」パーミッションがついていても上書き保存ボタンを押せない
* 実は、「名前を付けて保存」で、もとのワークブックとまったく同じ名称で保存すると上書きされる

# TSM設定関連
## LBを構成する場合の設定
* Tableau Serverの前段にLBを構成し、かつHTTPSで通信を受け付ける場合、tsm パラメータの gateway.public.port に443を設定しておかないと、Desktopからパブリッシュした後のブラウザ自動起動で真っ白な画面になる（v2021.3で確認）

## クラスタ構成
* プロセス構成の変更時、とりわけElastic Serverプロセスの増減を伴う変更を行う場合は、一度にまとめて実施すると変更が失敗することが多い。再起動回数が多く面倒でも、Elastic Serverとその他のプロセスの変更は分けて実施、さらにElastic Serverも1サーバずつ設定するほうが安全。
## 通知
### SMTPサーバ設定/TSMのメール通知設定とサブスクリプションUIの関係
（こうだった気がする。実機で再確認したい）

* TSMの設定でSMTPサーバを空欄、またはメール通知のチェックを外しておくと、WebUI画面側でサブスクリプションやデータドリブンアラートの登録ができなくなる
* 有効なサブスクリプションスケジュールが1件もないと、WebUI側でサブスクリプションの登録ができなくなる

# リポジトリ、カスタム管理ビュー関連
### リポジトリに対する相対日付フィルター
* リポジトリDBをデータソースとするワークブックにおいて、相対日付フィルターを設定すると、表示上はローカルタイムなのに、実際はUTCでフィルタ設定され、ズレるので注意。
* たとえばJSTベースで2022/9/3 の0:00～8:59の間に相対日付「昨日」で検索すると、相対日付の設定エリアでは「2022/9/2～2022/9/2」と表示されるのに、実際に取得されるのは2022/9/1のデータとなる（UTCベースではまだ9/2のため）
https://kb.tableau.com/articles/issue/now-function-returns-utc-time?lang=ja-jp
Epoxyで最初のアイテムだけViewが違うRecyclerviewを実装したい

# 初めに
今回はEpoxyライブラリで最初のアイテムだけViewが違うRecyclerViewを実装していきたいと思います。
### 本文
```kotlin
override fun addModels(models: List<EpoxyModel<*>>) {
    val item = ExcampleBindingModel_().apply { id("header") }

    super.addModels(
        buildList {
            add(item)
            addAll(models)
        }
    )
}
```
`addModels`は`buildItemModel`で作った`EpoxyModel`のリストをViewに当てはめてくれる部分なのでその段階でヘッダーに設定したい`View`を最初に`add`するようにしてあげればいいだけです。
# 最後に
ヘッダーだけViewを変えたい等で役立つかと思います。
何かの実装の参考になれば幸いです。
ソリューションアーキテクト対策_グローバルNW篇

## はじめに
試験勉強した際のメモを自分用に記事化。
内容は公式やBlack Beltの写経ですので目新しいことはありません:pray:

## グローバルNWを利用したサービス
### CloudFront
ボリュームがあるので別記事に分けてます。

### AWS Global Accelerator
アプリケーションの可用性とパフォーマンスを改善するネットワークサービス。
AWS上のアプリケーションに対して固定エントリポイントとなる静的なIPアドレスを提供することで、様々なAWSリージョンやAZの特定のIPアドレスの管理における複雑さを排除しつつ、アプリケーションアクセスを効率化する。
→最適なエンドポイントにトラフィックをルーティングする

ユーザーとアプリケーション間のネットワークレイテンシーの改善、アプリケーションの保護の役割も兼ねる。

CloudFrontはエッジにキャッシュを蓄積する方式なので、最適なエンドポイントへのトラフィックのルーティングは行わない。
Route53はルーティングを行うが、Global Acceleratorのような機能はない。

## おわりに
引き続き追記します！

簡単ですが以上です。
【初心者】Gem::ConflictErrorについて

### Gem::ConflictErrorについて
---

**※ 9/16日 追記**
プロを目指す人のためのRuby入門の著者の伊藤 淳一さんから、この記事についてコメントをいただきました。
お忙しい中ご指導をしていただき、大変光栄です。

起動するときに、--no-pluginsオプションを入れると、コンフリクトエラーを回避できることを学びました。
実行したことは下記となります。


①削除したactivesupportをもう一度入れ直す。
```
$ gem install activesupport -v 6.1.4.1
```

②--no-pluginsオプションを入れた状態でMinitestを起動してみます。
```
$ ruby test/gate_test.rb --no-plugins
```
③無事に起動することができました。

ConflictErrorが起きた時、対象のソフトウェアを削除するのでは、今後そのソフトウェアが必要となったときに問題対処ができなくなってしまいます。今回得た知識を今後の学習に活かしたいと思います。
改めてお礼申し上げます。


---
**【書いた理由】**
チェリー本に書かれているMinitestが突然起動しなくなってしまいました。
調べてみたところエラー解決できたため、まとめてみます。
ちなみに、プログラミング歴1ヶ月の超初心者なのでご容赦ください:bow:


**①まずは原因解明**

エラー文を読んでみます。

```
/Users/takaya/.rbenv/versions/3.0.1/lib/ruby/3.0.0/rubygems/specification.rb:2247:in `raise_if_conflicts': Unable to activate railties-6.0.5.1, because activesupport-6.1.4.1 conflicts with activesupport (= 6.0.5.1) (Gem::ConflictError)
```

「Gem::ConflictError」と書いてあります。
よく読んでみると「activesupport-6.1.4.1」がコンフリクトしているようです。
ググってみたところアンインストールをした方が良さそうです。

**②activesupportをアンインストールしよう**
下のコードを入れると対象のバージョンをアンインストールできます。
```
$ gem uninstall activesupport -v 6.1.4.1
```

**③もう一度動作確認**
minitestを起動してみましょう。
```
Run options: --seed 7249

# Running:

.

Finished in 0.002668s, 374.8126 runs/s, 374.8126 assertions/s.
1 runs, 1 assertions, 0 failures, 0 errors, 0 skips
```
問題なさそうです。

**終わりに**
今回の原因は、先日別の作業をした時にgemでいろいろインストールをしたことでしょうか。
思い当たる節はそれくらいです。
今後も起こり得そうなエラーなので、冷静に対処したいところです。
PowerShell で nodenv + yarn 環境を構築する

## 1. PowerShellを立ち上げ、Bashを起動する
```bash
$ bash
```

## 2. nodenvをgit cloneする

```bash
$ git clone https://github.com/nodenv/nodenv.git ~/.nodenv
```

## 3. Nodenvの初期設定
Nodenvをクローン後、コンパイル
```
cd ~/.nodenv && src/configure && make -C src
```

コンパイラが存在しないと怒られた
```
# エラーメッセージ
  > checking for C compiler ... not found
  > ./configure: error: C compiler cc is not found
```

gccをインストール
```
$ apt install gcc
```

再度実行
```
$ cd ~/.nodenv && src/configure && make -C src
```

## 4. nodenvの初期設定を追加
```
$ echo 'export PATH="$HOME/.nodenv/bin:$PATH"' >> ~/.bash_profile
$ echo 'eval "$(nodenv init -)"' >> ~/.bash_profile
$ exec $SHELL -l
```

## 5. nodenvにバージョンを追加
```
$ git -C ~/.nodenv/plugins/node-build pull
```

## 6. Nodenvで設定したいNodeのバージョンをインストール、環境全体に適用
```
$ nodenv install 18.6.0
$ nodenv global 18.6.0
```

## 7. Yarnをインストール
```
$ npm install --global yarn 
```

## 8. 確認
立ち上がりました
```
$ yarn -v
```