OmniAICreator/Qiita-1.07M huggingface dataset:
エンジニア的メンタル維持方法DB

# はじめに
毎日作業しているとどうしても色んな影響で
調子の良い日と悪い日があり、作業効率が変わるように思う。
どんな技術へのキャッチアップより、
自分のパフォーマンスを維持し続ける方がずっと大事なように思った。

今回は毎日のパフォーマンスを100%発揮できるようにはどうしたらいいか、考えてみる。
皆さんの意見取り入れていきたいです。

## 作業を楽しくする工夫をしてみる。
開発は要件定義、設計、実装、テスト、運用のようなフェーズがあると思うが、
自分の得意とする作業や不得意な作業が多少なりあると思う。

もしその不得意と思っている作業があるとしたら、楽しいポイントを探してみるといいと思う。

例えば
僕は最初テスト工程が退屈な感じで好きではなかったが、
色々なテストケースを考えて実行していくことが、段々掃除のような気持ちよさがあることに気づいた。
他にも設計では、全体の構想を膨らませれると思うが、なかなかワクワクすると思う。

このように、楽しいと思えるポイントを意識的に考えるようにすると苦手な作業は減っていくと思う。

## やってて楽しいプロジェクトにしていく
これは個人単位というより、チーム単位でのメンタル維持になるが、
技術選定（言語やインフラ）でやったことのない技術にチャレンジしてみたり、
リファクタリングとか自動化とか徹底的にして管理しやすいようなプロジェクトにしておくといいと思う。

やってて、楽しくないプロジェクトになったら誰も積極的に動かなくなるし、社内で煙たがられるようになってしまう。

## 複数の働き方を試してみる
１つの会社にずっと所属していたり、会社員という選択肢しかやっていないと、
自分にあった環境を適切に選択できなくなるし、環境によって自分のパフォーマンスはかなり変わってくると思う。
パフォーマンスが良ければ成長していけるし評価されるしで色々好転していくと思う。

会社員、フリーランス、起業、Web系、SIer系、ベンチャー、大企業
色んな形態で働いてみるといいかなと思う。

## 広い視野で見れるようにする
上のトピックに被ることは多いかもしれないが、
色んな業種の偉い方の情報をいつもアンテナ貼っておくといいと思う。
そもそもエンジニアが自分にあっているのか？
お金とやりがいとか、何のために働いているのか、どの環境下なら勝てるか？

最新の情報をキャッチアップしておくことで有利なポジションに移動できるし、
そのことで燃焼できる環境にいけたり、お金稼げたり、好転していってメンタルは回復していく。

## 自分の弱み、強みを知っておく。
辛いものは辛い。何が辛いのか日々自分の感情に敏感になって原因を探っておくといいと思う。
何が辛いのかわかれば自然と自分のいるべき場所がわかるはず。
我慢し続けると、感情が鈍化していくし精神衛生上良くない。
個人的にはMBTIという性格診断をやっておいて、得意・不得意なタイプの人間を分析しておくといいと思う。

## 考えるより行動
特に設計とかの部分で考えすぎてしまって、不安になり手が止まることがあった。
でもいくら頑張って設計しても実際にやってみたらうまく行かないこともいっぱいある。
実際に手を動かして作ってみるといいと思う。　忙しくすれば悩みは減る。

## 疎結合になる
誰かに相談しなければいけない状況ばかりだと、悩みも増えるし疲れる。
一人で色々できるようになっていくことで悩みは減っていく。

## 勉強と思わない、遊びと思うこと
技術のキャッチアップを勉強と思うと、この先10年20年とは続かないと思う。
ゲームのように楽しいものとして認識するように心がけるといいと思った。
毎日楽しいものだと意識的に考えると空気を吸うように出来るようになっていく。

## 自分を過大評価する
これは人によりますが、
過大評価しすぎであれば、謙虚に。
過小評価しすぎの場合は、自慢げに。
若干過大評価しておいたほうが、自己肯定感も高まるし、物事が上手く進むと思う。

## ホルモンを上手く利用する
いわゆる3つの幸せホルモンを活用していく。
アドレナリン、セロトニン、ドーパミン。
ちゃんと上記のホルモンを出していれば、メンタルは回復すると思う。
詳しくは下記のページに参考にしていただいて、
https://www.starbucks-kenpo.or.jp/my_wellness/mindset/list15.php#:~:text=%E2%80%9C%E5%B9%B8%E3%81%9B%E3%83%9B%E3%83%AB%E3%83%A2%E3%83%B3%E2%80%9D%E3%81%A8%E3%81%97%E3%81%A6%E3%83%A1%E3%83%87%E3%82%A3%E3%82%A2%E3%81%AA%E3%81%A9,%E5%8A%9B%E3%82%92%E9%AB%98%E3%82%81%E3%82%8B%E5%8A%B9%E6%9E%9C%E3%82%82%EF%BC%81

・アドレナリン
いわゆるフロー状態。
フロー状態を遮ってるものを出来るだけ排除する。
メールの通知、騒音、パソコンが重たい。。色々ありますよね。

・セロトニン
テレワークばっかして、
朝の散歩、日光浴怠っていないか。
セロトニン不足がいわゆる鬱。

・ドーパミン
人との交流を疎かにしていないか。
友達、家族、会社の人

## 毎日少し変化を加えてみる
人によると思いますが、自分の場合は同じルーティンを繰り返すと段々つまらなくなっていきます。
なので毎日何か変化をつけていくことでメリハリが生まれるかなと思います。
例えば、
・通勤ルートを変えてみる
・テレワークと出社を混ぜてみる
・コーヒーの種類を変えてみる。
・色んなランチを食べてみる。
・キーボードを変えてみる
・作業を午前と午後で変えてみる(午前は実装、午後はリファクタリングとか)

## 味方を増やす
どうしても営業サイドとエンジニアサイドで壁があったりすると思う。
でも目的は皆一緒なはずだし、敵にしてしまったら、ストレスは増えていく。
腹を割って話せるようにしておいた方が気持ち良く仕事ができますよね。


# 最後に
皆さんのメンタル維持方法ぜひ教えてください。
federated learningについての説明

※この記事の続きです。


https://qiita.com/magisystem0408/items/804b420bdc2842370089


## FLとは、何ができるのか？
ML(マシンラーニング)は聞いたことあるはず。実はその上にFLと言うものがある。
その名を、`federated learning`、連合学習と呼ぶ。


#### AIを使えるようにするには、以下2つを考える必要がある。
- いかに推論精度を上げられるか？
- いかに学習速度を上げられるか？

この内、連合学習とは、いかに`学習速度を上げられるか？`に使用される。
(要するに、勉強時間を少なくして、テストで高得点を取るかのうちの、勉強時間を少なくする方)


#### 学習速度を向上させるには、以下2つを考えられる。
- 学習させるPC、インスタンスなどの性能を上げる。(スペックを上げる。)
- 学習させるPC、インスタンスの数を増やす。(学習環境を分散させる。)

(要するに、地頭いい人、1人に勉強させるか、頭良くないけど、100人同時に勉強させるかのうちの100人の方。)


この内連合学習とは、`インスタンスの数を増やして、学習環境を分散させる`に属する。


### どのようにやるのか？
まず、stadle.aiに対して下図のように、学習させるAIモデルをアップロードする。
アップロードできると、エンドポイントURLがえられるので、そのエンドポイントに対して、アップロードしたAIモデルと同じモデルを学習させるclientで学習させて、学習させた時に、得られる経験則(別名：Weight)をstadle.aiに対して送る。
この経験則(別名：Weight)は実際には数式が羅列されていて、その数式から元々のAIモデルを予測する事がほどんど不可能なので、プライバシー、セキュリティ面が向上する。

![スクリーンショット 2022-10-26 12.48.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1466470/a715d26d-28c3-29e2-2bc4-e963713ab8e5.png)

### どのようなケースで、有用性があるのか？

学習させるデータセットが違う時、各学習でグルーピングしたい時。
例えば、言語予測変換モデルについて考える。当然言語というのは、80代が喋る言語と、20代が喋る言語には乖離がある。
20代が、「とりまコンビニ行く？」「やばい、めんどい」と言う確率は、80代が言う確率より当然大きい。このようなケースを利用して、それぞれの年代にあった喋り方、言語予測変換モデルを生成する事が可能である。


![スクリーンショット 2022-10-26 13.03.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1466470/b3019467-5c05-0f9d-5ef3-4322d9c826cb.png)
CloudTrailでS3のデータイベントを証跡として保存してみる

# はじめに
監査ログを手軽にとれるサービスとして有名なCloudTrailですが、皆さん使っておりますでしょうか。
監査ログの中でも、データに関わる監査の重要性は高まっているように思います。
今回は、そんなデータに関わる監査の1つとして、S3に対する読み込み/書き込みオペレーションの監査ログをCloudTrailを用いて保存します。

# やりたいこと
- S3バケット「target-bucket-qiita」に対する読み込み/書き込みのオペレーションを保存する
- 保存先は、S3バケット「20221026-s3-cloudtrail-test」内の「sample」ディレクトリ内とする
    - s3://20221026-s3-cloudtrail-test/sample/xxxxx と保存される

# 方法
1.まずはCloudTrailの画面から、証跡の作成ボタンをクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2949357/7d35450e-f168-2be4-fd35-2b78009bd1b9.png)

2.「ステップ1 証跡属性の選択」は各環境にあった設定項目を入れてください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2949357/12f9a0a6-95eb-3af0-ea75-345f2cb09aae.png)


**注意**：この時、「ストレージの場所」で指定するバケットは、証跡を保存するバケットです。
今回はS3バケット「20221026-s3-cloudtrail-test」の「sample」ディレクトリ内に保存したいので、以下のように設定します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2949357/8c747b14-6ee8-95f8-f0e1-c23525f0d95f.png)


3.「ステップ2 ログイベントの選択」で、イベントタイプのデータイベントにチェックを入れます。（デフォルトの管理イベントのチェックは外す）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2949357/ec156272-3cf8-f5f4-7906-34cbef3d7ded.png)

4.同じく「ステップ2 ログイベントの選択」で、「基本的なイベントセレクターに切り替えます」をクリック

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2949357/ee75c12e-b7ce-f9c7-7eba-8c5e2a851571.png)

**注意**：高度なイベントセレクタでは、データイベントを、読み込み/書き込みよりも詳細なレベルで指定できます。今回はそこまでの制御は必要ないため、基本的なイベントセレクターを使います。

https://docs.aws.amazon.com/ja_jp/awscloudtrail/latest/userguide/logging-data-events-with-cloudtrail.html
>AWS Management Console では、高度なイベントセレクタが有効になっている場合は、選択したリソース (Amazon S3 バケットまたはアクセスポイント、Lambda 関数、AWS Outposts の S3 オブジェクト、Managed Blockchain ノード用の Ethereum、または S3 オブジェクト Lambda アクセスポイント) のすべてのデータイベントをログ記録する事前定義済みのテンプレートから選択できます。

5.データイベントの「現在および将来のすべてのS3バケット」の読み取り、書き込みのチェックを外します。
（このままだと、全てのS3バケットの証跡が記録されます）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2949357/cfd76d28-c459-efcb-713d-36490185d9e1.png)

6.「参照」ボタンをクリックして、証跡を取りたいtargetのバケットを選択します。
（この時、他にも証跡を取りたいtargetバケットがあれば、「バケットの追加」で追加できます）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2949357/c46bb03c-bd01-0be9-cec6-155d608b3149.png)

7.次へ→証跡の作成をクリックすれば、完了です。

8.証跡の保管バケットを見ると、CloudTrailのフォルダが作成されていることが分かります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2949357/19726fa9-7a83-4943-0149-b4ddf1d70480.png)


以上、コンソールを利用した設定方法でした。
非常に簡単に監査ログの設定ができるので、ぜひ皆さん利用してみてください。
【エラー解決方法】Rails7:ActionDispatch::Request::Session::DisabledSessionError

# 概要
- https://qiita.com/kazama1209/items/caa387bb857194759dc5
上記の記事でログイン機能を作成したのですが、ログイン画面からユーザーを「ID」と「パスワード」により認証するパスワード認証はできたのですが、リロードした際のトークン認証がうまくいきませんでした。

### エラー内容
```Ruby
api_1    | app/controllers/api/v1/auth/sessions_controller.rb:3:in `index'
api_1    | Completed 500 Internal Server Error in 19ms (ActiveRecord: 2.7ms | Allocations: 684)
api_1    | 
api_1    | 
api_1    |   
api_1    | ActionDispatch::Request::Session::DisabledSessionError (Your application has sessions disabled. To write to the session you must first configure a session store):
```

# 解決方法
### 参考記事
https://github.com/heartcombo/devise/issues/5443

### 解決手順
- appフォルダ配下(controllerやmodelと同階層)にhelpersフォルダの作成
- helpersフォルダ配下にrack_session_fix_controller.rbファイルの作成
- 下記をrack_session_fix_controller.rbに記述

```rack_session_fix_controller.rb
module RackSessionFixController
  extend ActiveSupport::Concern

  class FakeRackSession < Hash
    def enabled?
      false
    end
  end

  included do
    before_action :set_fake_rack_session_for_devise
    
    private

    def set_fake_rack_session_for_devise
      request.env['rack.session'] ||= FakeRackSession.new
    end
  end
end
```
デザインパターン(メモ用）

## デザインパターンとは
オブジェクト指向においてクラスの再利用性を高めるための設計テンプレート
大きく分けて下の３パターン

- 生成
- 構造
- 振る舞い


|生成 |構造  |振る舞い  |
|---|---|---|
|[Factory Method](#factory-method)  |Adaptor |Chain of Repository  |
|[Abstract Factory](#abstract-factory)|Bridge|Command  |
|[Builder](https://qiita.com/horino-5555/items/73d023ef334b69c758fb)  |Composite  |Iterator  |
|Prototype  |Decorator  |Mediator  |
|Singleton |Facade |Memento
||Fliweight |Observer
||Proxy|State
|||Strategy
|||Template Method
|||Visitor

## 前提知識
- [継承・委譲・Interface](https://qiita.com/zeebra-1122/private/5400cad5728489f2e42d)
## 生成
### Factory Method
他のクラスのコンストラクタをサブクラスで上書き可能な自分のメソッドに置き換えることで、 アプリケーションに特化したオブジェクトの生成をサブクラスに追い出し、クラスの再利用性を高めることを目的とする。

#### 概要
- まず、生成されるObjectの抽象クラスProductクラスを抽象化して定義する。
- 次に、それらのObjectを生成する Creatorクラスを実装する。
- ClientはCreatorを呼び出して実行する。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/699843/c3d51778-c351-5096-4d4a-50f973b393f5.png" width="500">

### Abstract Factory

FactroyMethod集まりで出来た抽象クラス。
FactoryMethodで生成されるオブジェクト同士が密接に関係しあう時にその関係性を意識させることを強制することができる。

#### 概要
- まず、生成されるObjectの抽象クラスProductクラスを抽象化して定義する。（例：Button, Window)
- 次に、それらのObjectを生成する Factoryクラスを同じく抽象クラスで定義する。
- 生成される環境や条件によってProductクラスとFactoryクラスを実装する。(例：WinButton, MacButton)
- ClientはAbstractFactoryを呼び出して実行する。

![デザインパターン概略図.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2929546/4f49b3a1-d1d9-a005-d826-b4493305ccf3.png)

:::note info Points
1. 生成されるObject（Prodcut)にもinterfaceが必要
1. Clientからは実際にはどのConcreteFacotoryが動いているのかは隠されている。
1. Facotryの生成をApplicationの初期化の際に行い、環境情報などから factoryの型を決定する。
:::

### Builder
### Prototype

### Singleton

生成するインスタンスの数を1つに制限する。
newによるメモリの消費を抑えたり、プログラム中でインスタンスの状態を常に保持・更新する場合やクラス間で共通のデータとして常にアクセスする必要がある場合に使用する。

#### 概要

- publicのコンストラクタを持たず、privateのコンストラクタを持つ。
- private変数として、自身のクラスインスタンスを持つ。
- public関数として、自身のクラスインスタンスを返すメソッドを持つ。

![structure-ja-2x.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2983795/b3495f45-9b3e-3796-ec2c-a73525c73338.png)

## 構造
### Adaptor
### Bridge
### Composite
### Decorator
### Facade

## 振る舞い
### Chain of Repository
### Command
### Iterator
### Mediator
### Memento
### Observer
### State
### Strategy
### Template Method
### Visitor

## 参考
https://refactoring.guru/ja/design-patterns/structural-patterns (理解)
https://www.techscore.com/tech/DesignPattern/ (実践)
Databricksのクエリーフェデレーションとは？

[What is query federation? \| Databricks on AWS](https://docs.databricks.com/query-federation/index.html) [2022/10/31時点]の翻訳です。

:::note warn
本書は抄訳であり内容の正確性を保証するものではありません。正確な内容に関しては原文を参照ください。
:::

:::note alert
**訳者注**
2022/10/28時点ではまだ日本リージョンでは利用できません。
:::

*クエリーフェデレーション*という用語は、すべてのデータを統合システムに移行する必要なしに、ユーザーやシステムが複数のサイロ化されたデータに対してクエリーを実行するできる様にするための機能コレクションを指します。

# クエリーフェデレーションはレイクハウスのどこにフィットするのか？

レイクハウスでは、データの冗長性や分断を削減するためにデータを集中して格納することを強調していますが、多くの企業においてはプロダクションのデータシステムを多数持っています。多くの理由から接続されたシステムのデータをクエリーしたいと考えるかもしれません。

- アドホックのレポート。
- POCの作業。
- 新たなETLパイプラインやレポートの開発。
- インクリメンタルな移行におけるワークロードのサポート。

Databricksにいくつかのデータセットを移行したり、取り込んだりしないという選択をしつつも、隔離されたユースケースにおいて何人かのユーザーにアクセスを与える必要がある場合があります。

# Databricks SQLのクエリーフェデレーションとは？

:::note info
**プレビュー**
本機能は[実験段階](https://docs.databricks.com/release-notes/release-types.html)です。実験段階の機能はas-isで提供され、カスタマーテクニカルサポートチャネルを通じたDatabricksによるサポートはありません。
:::

Databricks SQLを用いることで、すべてのサーバレスウェアハウス、pro SQLウェアハウスに含まれているドライバーにより人気のデータベースソリューションに対する読み取り専用接続を設定することができます。

接続の詳細については以下をご覧ください。

- [PostgreSQL](https://docs.databricks.com/query-federation/postgresql.html)
- [MySQL](https://docs.databricks.com/query-federation/mysql.html)
- [Snowflake](https://docs.databricks.com/query-federation/snowflake.html)
- [Redshift](https://docs.databricks.com/query-federation/redshift.html)
- [Synapse](https://docs.databricks.com/query-federation/synapse.html)
- [SQL Server](https://docs.databricks.com/query-federation/sql-server.html)

# Databricksにおけるクエリーフェデレーションとは？

Apache Sparkは、さまざまなシステムやデータソースから得られるさまざまなフォーマットのデータに接続するサポートを常に提供しています。数多くの[外部データソース](https://docs.databricks.com/external-data/index.html)とインテグレーションするためにDatabricksランタイムはこれらのオープンソースコネクター上に構築されており、追加のライブラリをバンドルしています。

多くのデータベースへの接続ではApache Sparkの[JDBC](https://docs.databricks.com/external-data/jdbc.html)コネクターを使用しています。これらの接続の並列性をチューニングするために数多くのオプションを指定することができ、必要に応じてクエリーをソースシステムにプッシュダウンすることができます。

Databricksランタイム11.3以降では、PythonやR、Scalaに加えてSQLでも[シークレット](https://qiita.com/taka_yayoi/items/7e4eae0786b94cb7a5de)がサポートされ、検閲された文字列を用いることでユーザースコープの認証情報を設定することができます。

# Databricksは他のシステムからのクエリーフェデレーションを許可するのか？

- Databricksでは数多くのBIツールと互換性のある[JDBCやODBCドライバー](https://docs.databricks.com/integrations/jdbc-odbc-bi.html)を提供しています。
- Delta Sharingは数多くの[クライアント](https://delta.io/sharing/)から接続するユーザーにDelta Lakeテーブルを共有するためのオープンソースプロトコルを提供しています。
- Delta Lakeは数多くの[インテグレーション](https://delta.io/integrations/)を提供する完全にオープンソースなストレージプロトコルです。
- Databricksは、レイクハウスのデータのクエリーをサポートするために数多くの[BIとビジュアライゼーションツール](https://docs.databricks.com/partners/partners.html#bi)とパートナーシップを結んでいます。

### Databricks 無料トライアル

[Databricks 無料トライアル](https://databricks.com/jp/try-databricks)
Cylinder charge, ボッシュ自動車handbook 11版(61) p.812

Management for spark-ignition engines, Cylinder charge, ボッシュ自動車handbook 11版(61)

人生で影響を受けた本100冊。
https://qiita.com/kaizen_nagoya/items/16af53acbb147a94172e

に掲載した本のうち、「新人プログラマ応援」企画で「私の推薦書３３冊」として３３冊紹介した。

新人プログラマ応援　私の推薦書３３冊
http://qiita.com/kaizen_nagoya/items/98c62f051dbdb4f8aca2
残りの６７冊から、順に過去の読書感想を引用し、新たな読書感想文を追記する。

 <この項は書きかけです。順次追記します。>
# ボッシュ自動車ハンドブック version 11, 2022

Automotive Handbook  May 2, 2022
https://www.amazon.co.jp/dp/1119911907/

ボッシュ自動車handbook(英語)11版(0)＜エンジニア夏休み企画>【読書感想文】
https://qiita.com/kaizen_nagoya/items/dfa35aa6f669e5df983e
# Contents
Motor vehicle, 28
Basic principles, 32
Mathematics and methods, 204
Materials, 258
Machine parts, 354
Joining and bonding techniques, 426
Vehicle physics, 462
Operating fluids, 538
Refrigerants for air-conditioning systems, 591
Drivetrain(駆動系), 594
Internal-combustion engines(内燃機関),642
Management for spark-ignition engines,800

# Cylinder charge(円筒充填)
p.812
## Component parts 
### Fresh A/F mixture
### Residual Exhaust gas
## Control of cylinder charge
### Throttle valve
### Charge cycle
### #xhaust gas recirculation(EGR)
### Supercharging 
## Recording of air charge 
### Particularrities for motorcycles
## Cylinder shutoff
### Configuration of cylinder shutoff
### Adaptation of vehicle components
### Engine management
### Cylinder shutoff requirement
### Changeover between partial and full engine oeration

# Reference
参考なし。　

# 自己参考資料(self reference)

ボッシュ自動車ハンドブック 

https://qiita.com/kaizen_nagoya/items/8e330ce57880f04d71d9
ボッシュ自動車handbook(英語)10版　目次

https://qiita.com/kaizen_nagoya/items/57c799ff544c96efdea9

自動車工学とBosch Vehicle Handbook

https://qiita.com/kaizen_nagoya/items/d13ff6b0e4d7c8907c0d

 ＜この記事は個人の過去の経験に基づく個人の感想です。現在所属する組織、業務とは関係がありません。＞
# 文書履歴(document history)
ver. 0.01 初稿 　20221026
### 最後までおよみいただきありがとうございました。
いいね　💚、フォローをお願いします。
####  Thank you very much for reading to the last sentence.
Please press the like icon 💚　and follow me for your happy life.
【スケジューラ】Microsoft Teamsにメッセージを送ってみる(Incoming Webhook:上級編）

前回の投稿記事、[【スケジューラ】Microsoft Teamsにメッセージを送ってみる(Incoming Webhook:基礎編）](https://qiita.com/Miki_Yokohata/items/828215c05759c709b15e)で簡単なプレインテキストを送信してみましたが、今回はプレインテキスト以外の形式等を使用したメッセージを送ってみようと思います。

前回作成したスケジューラタスクを複製します。複製の元となるタスクを選択した上で、右クリックメニューから**複製**を選ぶことで作成することができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/293027b3-7860-3aea-c1fc-8925bb382cf6.png)
早速、複製されたタスクを開き編集を開始します。
### クエリ結果をメッセージの一部に使用する ###
始めはクエリを定義して返ってくる値をメッセージで使用してみます。
`アクション`タブに移動し、`新規`アイコンを使用して**クエリー**タスクを追加します。`クエリーを編集`ボタンでクエリを定義します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/557cb715-3c73-0056-b845-0c008ed5fecd.png)
当システムのパブリッシャーで作成したレポートの総数を単に返すクエリを定義します。`OK`ボタンで保存します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/e785e23a-b22b-796b-f040-64d7a104186b.png)
`タスクのパラメーター`オプションを使用します。クエリで定義した`出力名`を指定することで、同名のタスクパラメータを作成することができる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/db4cab96-fbe6-b89a-95b5-8b642b7d0d1a.png)
`Microsoft Teams`タスクに移動します。前回のWebhookの設定はそのままで、`件名`を**Test2**とし、`メッセージ`に以下の内容を貼り付けます。`HTML`オプションも**オン**にします。クエリータスクで作成したタスクパラメータ{_Task.Param.<font color="red">ReportTotal</font>}を使用しています。その下は通常のWebページへのリンクです。
```
<p style="font-family:verdana">当システムのWebレポートの総数は{_Task.Param.ReportTotal</font>}です。</p>

<a href='https://learn.microsoft.com/en-us/microsoftteams/platform/webhooks-and-connectors/how-to/add-incoming-webhook'>参考</a>
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/f164e8c0-fccc-4ae8-594f-728f05918b2f.png)
これでアクションの定義は終了、`OK`ボタンでタスクを保存します。
スケジューラのタスク一覧より当タスクを選択した状態で、右クリックメニューから**実行**を選び、手動でタスクを走らせてみます。
正常に終了したならTeamsでメッセージを確認します。
クエリ結果もリンクも正常にメッセージとして届いています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/141f9bf0-b678-1b07-1141-0bbe826976b2.png)
### 高度な設定メソッドの使用 ###
この方法では、JSON形式のメッセージを定義します。
先ほどのタスクを再度開き`アクション`タブに移動します。作成した**Microsoft Teams**アクションを選択し、`行のコピー`アイコンをクリックします。**Microsoft Teams**アクションが複製されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/fdaba1dd-910d-b81f-12a9-6b7b640a7349.png)
複製されたアクションを開き、今度は`高度な設定`メソッドを指定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/ce741f03-789c-070e-b46a-93316d23bff3.png)
`POSTの内容`フィールドには以下のようなフォーマットでメッセージを記入します。
```
{
        "@context": "https://schema.org/extensions",
        "@type": "MessageCard",
        "themeColor": "0072C6",
        "title": "Test by Miki - Ignore this",
        "text": "This is a test message<br><a href='https://learn.microsoft.com/en-au/outlook/actionable-messages/send-via-connectors'>参考</a>"
 }
```
`OK`ボタンでタスクを保存し、右クリックメニューから**実行**を選び、手動でタスクを走らせてみます。
正常に終了したならTeamsでメッセージを確認します。**Microsoft Teams**アクションが二つ定義されているので、二つのメッセージが届くはずです。
It's excellent!!:thumbsup:
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/1687a58b-09a8-6918-dcc3-2e7ff3a9cba9.png)

では、失礼します。
「ソフトウェアアーキテクチャの基礎」メモ

休み中に読んだのですが、記事としてアウトプットしないと「読み切った」気にならないので、メモを残します。

全部を書き出すと結局本文を読むのと同じになるし、「凝集性」といった用語はあえて書き出しても面白くないので、重要そうなキーワードをメモしておきます。

# 総評

アーキテクトになる入門書。

- 第Ⅰ部　基礎
  - アーキテクトとはどんな職能か？
  - アーキテクトの基本的な考え方（アーキテクチャ思考）
  - 基本概念の解説
    - モジュール性
    - アーキテクチャ特性
    - アーキテクチャ特性の抽出
    - アーキテクチャ特性の計測と統制
    - アーキテクチャ特性のスコープ
    - コンポーネントベース思考
- 第Ⅱ部　アーキテクチャスタイル
  - 代表的なアーキテクチャパターンの紹介
  - ３層レイヤーからマイクロサービスまで
- 第Ⅲ部　テクニックとソフトスキル
  - 実際にチームに参加してアーキテクトと働く際のテクニック
  - アーキテクチャ決定
  - リスク分析
  - 図解やプレゼンの方法
  - チームの統制方法
  - 交渉とリーダーシップ
  - キャリアパス
 
アーキテクトになる予定はなくとも基礎教養として読むことをオススメします。

# アーキテクチャ思考

アーキテクトとプログラマーとは働き方が異なる。

- アーキテクチャと設計の違いを理解し、開発チームとどう協働するか分かる
- 幅広い技術的な知識
  - アーキテクトは専門性を深めると言うより、幅広さが重要
  - トレードオフを理解し、分析し、調整できる
- ビジネスドライバー（ビジネスを伸ばすために乗り越えなければならない要素）を理解し、それがどのようにアーキテクチャの関心事に反映されるか理解している

# アーキテクチャ適応度関数

アーキテクチャ特性を具体的にチームメンバーに守ってもらう仕組みを「適応度関数」と呼ぶ。

ArchiUnitは「コントローラー層から永続化層を直接呼び出してはならない」といったチェックをできるJunit風のツール。

NetflixのMonkey軍団はより高レベルの指標を統制できる。


# 「資産防御アンチパターン」

選択ミスを恐れて、アーキテクチャ決定を先延ばしするアンチパターン。情報収集し過ぎて「分析麻痺」アンチパターンに陥るのも注意。

締め切り／最終責任時点（重要な代替案がなくなってしまう時点）を見極め、そこまで情報収集する。

# 「グラウンドホッグデーアンチパターン」

つまり「エンドレスエイト」。

アーキテクチャ決定に至った経緯が理解されず、同じ議論が繰り返されるアンチパターン

単に決定の根拠を説明していないせいのこともあるが、 **技術的な根拠と、ビジネス的な根拠の、一方しか説明していないとき** に起こりがち。


# 「メール駆動アーキテクチャアンチパターン」

人々がアーキテクチャ決定を見失ったり、忘れたり、決定されたことさえ知らなかったりして、アーキテクチャ決定を実装できなくなる（ので、いちいちアーキテクトにメールで質問をしてくる）。

あと、過去のメールを読んで、古い内容にもとづいて議論し混乱する。

最新のアーキテクチャ決定は、Wikiなどに記載し、メールにはWikiへのリンクだけを書く。

「サービス間通信に関する重要な決定を行いました。詳しくは、以下のリンクから」のように、誰に影響があるのか簡単に書くと良い。

なんか、身に覚えがあるなあ。

# ADR：アーキテクチャデシジョンレコード

RFCや、PythonのPEPSのようなドキュメント。

何か決定する度に、１・２ページ程度の簡潔なものを書く

- タイトル
    - アーキテクチャ決定の簡単な説明
- ステータス
    - 提案済み。承認済み、破棄
- コンテキスト
    - 決定を行った状況
- 決定
    - 決定とその根拠
- 影響
    - 決定による影響
- コンプライアンス
    - 決定が遵守されているか確認する方法

決定を覆す時は、ステータスを「破棄」に変え、新しいADRを作る。旧ADRと新ADRは相互リンクする。

# リスク分析

「リスク基準」×「サービス・ドメイン領域」の表を作ってリスクごとに点数をつけて分析する。

1. 特定：個人個人で、リスク分析表を記入する
2. 合意：各自作成したリスク分析表を突き合わせる
3. 軽減：判明したリスクを軽減する方法を決める（DBのクラスター化など）。このとき軽減策の費用対効果についてビジネス側のステークホルダーとのすり合わせも重要。

# 効果的なチームにする

コントロールフリーク（極端な統制）←→アームチェア（極端な放任）

この両極端の適切なゾーンを選ばなければならない。

- 統制的にする：新しいチームメンバー、経験が少ない、大規模なチーム、複雑なプロジェクト、長期間
- 放任的にする：見知ったメンバー、経験豊富、小規模なチーム、シンプルなプロジェクト、短期間

# チェックリストの活用

チェックリストは上手く使えば役に立つ。

- 自動化出来ないチェック内容
- 見落としがちな項目
- プロジェクトやチーム固有の基準や
- 手順

詳しくは「アナタはなぜチェックリストを使わないのか？：重大な局面で"正しい決断"をする方法」を読みましょう。

# 可用性の目安

「ダウンタイムゼロ」は非常に高コスト。

90.0% ワンナイン: 36日12時間/年、2.4時間/日
99.0% ツーナイン: 87時間46分/年、14分/日
99.9% スリーナイン: 8時間46分/年、86秒/日
99.99% フォーナイン: 52分33秒/年、7秒/日
99.999% ファイブナイン: 5分35秒/年、1秒/日
99.9999% シックスナイン: 31.5秒/年、86ミリ秒/日

しかし「◯ナイン」はゴロが良いため、安易に使われがち。ステークホルダーが「ファイブナインが必要だ！」と言っても鵜呑みにしないこと。
アクセシビリティモードの開発中に便利な TTS ツールを見つけました

最近、ソフトウェアを開発する際に、アクセシビリティモードを一致させる必要がある開発要件があり、多くの Web サイトを見つけました。

いくつかの無料ツールを比較した結果、これが一番使い心地が良いと思います


https://ttsmaker.com/ja


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2949234/40e1de10-c498-1c9c-5631-2b08865932ef.png)
検索バーで初回表示されるテキストについて

Swiftで検索バーは多々利用しますが、自分は今まで
```ViewController.swift
@IBOutlet private weak var searchBar: UISearchBar?
searchBar.text = "初回表示テキスト"
```
として初回表示テキストを表示していました。しかし、これではUIとしてあまり良くありません。検索バーは「ここにワードを入れたら検索できる」という意図をユーザーに伝えなければなりません。このままでは「どこに検索ワードを入れたらいいのか」分かりにくいです。ですので、初回表示テキストは透明にした方が良いです。


```ViewController.swift
@IBOutlet private weak var searchBar: UISearchBar?
searchBar.placeholder = "初回表示テキスト"
```
とすると初回表示テキストが透明になるので、UIとしてより良いものになります。
細かいことではありますが、ユーザーにできるだけ気を配れることは大事だと感じています。
【Git】空コミットを作成する方法

# はじめに
空コミットを作成して空のプルリクエストを出すことで、
実装前に設計や概要などをレビュアーに共有したり相談することができます。

# 方法

オプションの-mを付けると便利です。

```terminal
$ git commit --allow-empty -m "{コミットメッセージ}"
```

その後、いつものようにgit pushします。

https://qiita.com/shimajiri/items/aedeb4f0389a27d78858
請求書システムの環境移行

2年くらい前からOSSの抹茶請求書を利用していたのですが、サーバを解約する関係で新サーバに移動しようとしたところトラブルに😱

# 抹茶請求書が動く環境
OSSで提供されており、旧サーバの動作環境がPHP5.6、CakePHP1.3でした（古い・・・）

http://oss.icz.co.jp/invoice/

PHP5.6が動く環境がなく、PHP7以上で動かそうとするとCakePHPが動かない。
CakePHPをバージョンアップすると抹茶請求書自体のコードが動かない。。。

どうしたものか🤔

# そうだ、ローカルでコンテナで動かそう
結局ローカルに構築したPHP5.6のDocker上で動かすことにしました。
理由は以下の通り。

* このシステムを利用しているのは私一人だった
* こんな古いバージョンをインターネットに接続したサーバで動かすこと自体セキュリティリスクが高い

随分古い記事ですが、Qiita上にPHP5.6＋Apache環境を構築した例があったのでこちらを参考にしてます。
（ただし、docker-composeも当時からバージョンアップしているので書き換えが必要）

https://qiita.com/you1978/items/180c37cdb9fc8d85cd57

無事動くようになりました。
ありがとうDocker、ありがとうQiita🙏✨

それにしても今後別のシステムに変更することも考えないとなぁ。
QA 共有手順


![1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531298/095fe53d-59d5-11a5-503a-2ed394e13be8.png)

![2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531298/cabbe8c9-c0cf-59a1-32c8-2ca59ad4fcbc.png)

![3.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531298/922ff385-2d6c-d67f-d88f-02679d3218a4.png)

![4.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531298/7c7ae4f5-1222-ae0d-51b7-d935da255f3e.png)

![5.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531298/dfde5686-bd2d-1453-d4ac-65aeb3a0e05e.png)
AWS Rekognition使ってみた

# AWS Rekognitionとは
画像や動画について、機械学習を使用して分析ができるサービスです。
自撮の画像と愛猫の画像に対して分析をしてみました。
独自の機械学習モデルを作成することも可能ですが、
今回は最も簡単に使用可能なデモ画面を使用しました。
- 自撮画像：顔の分析
- 猫画像：ラベル分析

![rekognition_0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2740559/3865ae66-fa82-06b1-eac1-5d555c202bef.png)

# 自撮画像の分析結果
年齢以外は正確に分析されています。
現在27歳ですが、たまに年齢確認されるので、このくらいのレンジが妥当なのかもしれません。
![rekognition_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2740559/8a68acd2-f4da-05cf-96db-412c8f1a6394.png)

# 猫画像の分析結果①
正面から撮った猫らしい画像を分析してみました。
「Cat」が96.2%となっており、猫だと認識されています。
又、床のフローリングも「Wood」として認識されています。
![rekognition_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2740559/ffd18de4-5952-9e36-0f12-ecc15f34be63.png)

# 猫画像の分析結果②
今度は少し難易度を上げたかったので、仰向けの画像を分析してみました。
「Dog」87.6%、「Cat」84%となりました。
仰向けの状態だと猫っぽい犬と認識されているようです。
このようなわかりにくい画像は独自のモデルを使用したほうがよさそうです。
![rekognition_3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2740559/ac0c30df-33b2-fca4-09b2-d88e354c739f.png)

# 所感
簡単に機械学習を試すことができ、概ね期待通りの結果だったと思います。
特殊なものでなければ、デフォルトのモデルでも十分使えそうだと思いました。
次回は独自のモデルを作成して、結果を確認してみたいと思います。
【vue/Nuxt】オブジェクトの追加

# オブジェクトの追加には注意が必要

APIで取得してきたオブジェクトをdataで宣言済みのオブジェクトに追加した際に、`Cannot read properties of undefined`エラーが出たり、リアクティブに操作できなくてはまったので備忘録。

## 結論、オブジェクトの追加は$setなどを使う

```js
data() {
      return {
        test: {
          default: {},
        },
      };
    },
    mounted() {
      this.$set(this.test, "add", {}); // -> リアクティブなadd{}が追加される
    },
```

単純に`=`を使ってオブジェクトの追加をしていたのが原因だった。dataの中で宣言しておくか、$setを使って、get/setを持つリアクティブデータとして追加して解決。

## 解説

vueインスタンスのdataの中に宣言されたものはget/setを持ち、何かしら変更があったら感知ができるリアクティブなデータになる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2609332/c0712f41-abc2-2c59-0371-5f663e76b20a.png)

dataの中で宣言したものはリアクティブなものだが、`=`などで後から追加されたオブジェクトはget/setを持たない、非リアクティブなデータ。
下記サンプルコードで確認してみる。

```js
data() {
      return {
        test: {
          default: {},
        },
      };
    },
    mounted() {
      this.test.add = {};
      this.$set(this.test, "add2", {});
      console.log(this.test);
    },
```
出力結果
![スクリーンショット 2022-10-26 11.13.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2609332/5312015e-7f03-7b3d-0405-0915a76e6e21.png)

dataの中で宣言していた、`default: {}`はget/setを持つリアクティブデータ。
`=`で単純に追加した`add: {}`はget/setを持たない非リアクティブデータ。
`$set`を使って追加した`add2: {}`はget/setを持つリアクティブデータであることがわかる。

## まとめ

リアクティブなデータを追加していかないと、予期せぬエラーになる。
なのでデータを追加する際には`$set`を使って、get/setを持つリアクティブデータで追加する。
公式を見ると`Object.assign()` や `_.extend()`でも追加できるよう。 

公式:[リアクティブの探求](https://jp.vuejs.org/v2/guide/reactivity.html)
[WordPress] サイト内検索に Algolia を使う時に最初に設定しておくこと

# 要件

サイトは WordPress で作成。
サイト内検索に Algolia を利用。

本記事では WordPress と Algolia の連携し利用できるようにするまでの手順を記載。

# Algoliaのアカウント/APIキーを取得

https://www.algolia.com/

また、開発用/本番用とでAlgoliaのアプリケーションは分離しておく。
アカウント取得時は無料でよいが、無料枠の場合は検索回数の上限やチームユーザーの制限があるため、本番環境用で利用する場合は素直に支払い情報を登録しておきましょう。

APIキーは
- Application ID
- Search-Only API Key
- Write API Key（旧名称 Admin API key）

を控えておく。

# WordPressでプラグインのセットアップ
WP Search with Algoliaをインストール

https://wordpress.org/plugins/wp-search-with-algolia/

## 1. APIキーの設定
Algolia search→SettingsでAPIキーを入力/保存。
Index name prefix はデフォルトのままでOK。

## 2. 検索フォームの選択
Algolia search→Search Page。
検索ページをどのように実装するかによって異なるのでサイトに合わせて選択する。

- Do not use Algolia: サイト内検索をAlgoliaに置き換えない。**自前で実装**する場合はこちら。
- Use Algolia in the backend : サイト内検索をWordPressからAlogliaに置き換えるが、Instantsearch.jsでは無く **PHP** を利用した検索になる
- Use Algolia with Instantsearch.js : サイト内検索をWordPressからAlogliaに置き換え**Instantsearch.js**を利用する

## 3. インデックスに送信する投稿タイプなどの設定
Algolia search→Autocomplete。
検索窓でオートコンプリート機能を使う場合は、 「Enable autocomplete」のチェックを入れる。
ConfigurationでAlgoliaのインデックスに登録する（検索対象とする）、投稿タイプ/ユーザー情報/タクソノミーにチェックを入れる。

保存したらインデックスの送信を促すボタンが出るので送信しておく。

# Algoliaのインデックスの設定

AlgoliaのダッシュボードでWordPress送信されたインデックスの設定を行う。
各インデックスのConfigurationタブで設定する。
インデックスが複数ある場合、1つのインデックスの設定を他のインデックスにも反映させることができるので、同じ設定であれば複数回繰り返さなくても良い。

## 1. インデックスが作成されているかの確認
prefixがデフォルトのままの場合

- wp_searchable_posts→全ての投稿タイプの投稿が含まれるインデックス
- wp_posts_post→投稿のみのインデックス

など、インデックスが作成されているか確認

## 2. Languages
形態素解析を使用できる様 **日本語のサイトの場合は必ず設定しておく。**

| 設定名 | 内容 |
|:-|:-|
| Index Languages | Japanese |
| Query Languages | Japanese |

## 3. Searchable attributes
検索対象となる要素名を指定する。
WP Search with Algolia プラグイン利用時のデフォルトは下記の通り。

| Algoliaの要素名 | WordPress | 検索語のマッチした位置 |
|:-|:-|:-|
| post_title | 投稿のタイトル | unordered |
| taxonomies | 投稿に付与されているタクソノミー（カテゴリー、タグ、カスタムタクソノミー）  | unordered |
| content | 投稿の本文 | unordered |

検索語のマッチした位置はマッチした位置を考慮するかどうか。
ordered にするとより早い位置（前のほう）に出てくるレコードが上位になる。

要素の並び順を変更すると検索時のランキングに影響する。

## 4. Ranking and sorting
検索結果のランキング/重み付けの設定。
WP Search with Algolia プラグイン利用時のデフォルトは下記の通り。

| 種別 | Algoliaの要素名 | 順序 |
|:-|:-|:-|
| TEXTUAL | Ranking Criteria |  |
| CUSTOM RANKING | is_sticky | Descending |
| CUSTOM RANKING | post_date | Descending |
| CUSTOM RANKING | record_index | Ascending |

1. Algolia のデフォルトランキングストラテジー に基づくランク付け
1. 同じランキングの場合「先頭に固定表示」の投稿を優先
1. 同じランキングの場合「公開日時」の新しい投稿を優先
1. 同じランキングの場合「レコードインデックス」が小さい投稿を優先

# Webサイト側の検索ページ

どういう検索をさせたいかによるのでこの記事で具体的な手法は記載しない。

- WP Search with Algolia プラグインの場合、WordPressデフォルトの検索フォームをAlogliaに置き換えてくれる
- WP Search with Algolia プラグインのテンプレートを利用する
- [Search with Algolia Instantsearch Blocks](https://wordpress.org/plugins/search-with-algolia-instantsearch-blocks/) を使う
- Instantsearch.js APIを利用して自前で頑張る

# あわせて読んで欲しい記事

https://knowledge.amimoto-ami.com/knowledge/algolia

https://labworks.digitalcube.jp/blog/technology_20211220_shifter-algolia-usecase/

https://qiita.com/gatespace/items/7e1b379c7212b4ce8c34

https://blog.tatsuroh.com/2020-12-21/algolia-searching-ja

https://blog.tatsuroh.com/2020-12-02/algolia-ranking-explained

https://blog.tatsuroh.com/2020-12-07/algolia-rankinginfo-customization
QA 色変え手順



![1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531298/a02e638b-1c84-3bde-7e2e-4f38feb499b1.png)


![2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531298/edc84397-1d34-2376-c384-6ac3742cc973.png)


![3.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531298/13244ca9-e4bb-23d3-6376-421d88daad22.png)

![4.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531298/71302de2-417a-253b-d37d-945ba56872ef.png)

![5.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531298/85b421dc-0ed7-3562-2b5e-79e2049c6285.png)

![6.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531298/a86e2a96-05bf-b1f1-5024-67ef22d44511.png)

![7.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531298/d579cd10-4242-aa72-c84c-68f06b7d19ab.png)

![uploading...0]()
【データ基盤構築/BigQuery】QUALIFY句を使用して、重複データのチェックやフィルタリングを行う

# 今回の課題
業務内でETLツールを介して、BigQueryにクエリを実行し、
BigQuery→Google Spread Sheetに「追記」するかたちでデータを転送したところ、
**Google Spread Sheetに大量の重複データが格納されている。**
という不具合が発生していた。

下記の２つの方法で改善できそうだと分かり、
転送量が少なくて済むため、後者で実装することにした。

# 改善方法
* 「追記」ではなく、「全量洗い替え更新」するかたちで転送する。
* QUALIFY句によるデータ重複チェックをクエリ内に盛り込んだ上で「追記」でデータを転送する。

## QUALIFY句とは
クエリで分析関数を使用した場合に分析関数の結果でフィルタリングを行うことができる。

QUALIFY句を使用する際は、
WHERE句、GROUPBY句、HAVING句のいずれかがクエリ内で使用されていなければならない。
※参考：[BigQueryのQUALIFY句を使ってみる](https://dev.classmethod.jp/articles/bq_qualify/)
## 実際に使用したクエリ
下記のようにクエリにQUALIFY句を使用して、
BigQuery→Google Spread Sheetsにデータを「追記」転送することにより、
重複するデータを除外して「追記」転送することに成功した。
```SQL
select
    * -- 省略
from
    `テーブル名`
where -- QUALIFY句を使用するには、WHERE, GROUPBY, HAVINGのどれかを入れておかないといけない。
    1=1
qualify -- 同じpage_title, release_dateの組み合わせのデータの重複を除外（同じpage_title, release_dateの組み合わせのデータは１つしか存在しないというフィルタリング）
    row_number() over(partition by page_title, release_date order by release_date desc) = 1
```
以上で、今回の課題を解決することができた。

# おまけ
QUALIFY句を使用して、実際に重複している行を確認することもできる。
データが多すぎる時や、重複しているような気がしたときに下記クエリを試してみると役に立つかも。
```SQL
select
    * -- 省略
from
    `テーブル名`
where -- QUALIFY句を使用するには、WHERE, GROUPBY, HAVINGのどれかを入れておかないといけない。
    1=1
qualify -- 同じpage_title, release_dateの組み合わせのデータの重複を除外（同じpage_title, release_dateの組み合わせのデータは１つしか存在しないというフィルタリング）
    row_number() over(partition by <ユニークキー相当> order by <時系列系/順序系カラム> desc) > 1
```
ClusterAutoscalerでのスケールイン時のDaemonSetの挙動に気をつける

Kubernetes環境でサーバー自体のスケールイン・アウトを管理する場合、ClusterAutoscaler(以下CA)を使用することがあります。
CAでスケールインするときのDaemonSetの挙動について気をつけないといけないなぁと思ったことがあるので記載します。

* この記事中の想定環境
    * Kubernetesプラットフォーム
        * AWS EKS
            * Ver1.21
    * ClusterAutoscaler
        * Ver1.21.3


---

DaemonSetを利用する用途として「ログ収集」があります。
アプリケーションのPodがログを標準出力した場合、ホスト上の `/var/log/containers/` にログが出力されます。
DaemonSetを利用し、自ホスト上のログをFluentdなど使用しログ収集先に転送する、といったようなことをするためです。

このような用途でDaemonSetを使用する場合、Nodeを削除する際にDaemonSet管理下のPodはDaemonSet以外のPodよりも早く消えてはいけません。
なぜならNodeの削除する際はDrainを行いPodの排出を行いますが、その際もログは吐き続けているからです。
仮にアプリケーションのPodよりも先にDaemonSetのFluentdのPodが先に消えてしまうと、それ以降に出力したログを収集できません。

ではCAでスケールインする場合はどういう挙動になるのでしょうか？

ということで検証してみます。

## CAでのスケールイン時のDaemonSetのデフォルトの挙動の検証
以下のようなPodがいる状態です。

```bash
$ kubectl get po -A -o jsonpath='{.items}' | jq -c '.[] | [.metadata.name,.status.phase]'
["aws-node-gccws","Running"]
["kube-proxy-q7v7h","Running"]
["daemonset-fluentd-cwzb2","Running"]
["deployment-app-6d4b447dfb-7zhgt","Running"]
```

見てわかるようにDaemonSetのFluentdのPodとDeploymentのアプリケーションPodを想定したものです。
アプリケーションPodには `spec.containers.lifecycle.preStop` に `sleep 15` を仕込んでおり、Podを終了してもすぐには消えないようにしてあります。

この状態でCAがスケールインをすると・・・

```bash
$ kubectl get po -A -o jsonpath='{.items}' | jq -c '.[] | [.metadata.name,.status.phase]'
["aws-node-gccws","Running"]
["kube-proxy-q7v7h","Running"]
["deployment-app-6d4b447dfb-7zhgt","Running"]
```

DaemonSetのFluentdのPodがまず消えてしまいました。
これではアプリケーションPodが出力しているログを収集できません。

## なぜDaemonSetのPodが先に消えてしまうのか？
CAのデフォルト設定を眺めてみると以下の設定がありました。

option name | default | description
--- | --- | ---
daemonset-eviction-for-empty-nodes	 | false | Whether DaemonSet pods will be gracefully terminated from empty nodes
daemonset-eviction-for-occupied-nodes	 | true | Whether DaemonSet pods will be gracefully terminated from non-empty nodes

https://github.com/kubernetes/autoscaler/blob/master/cluster-autoscaler/FAQ.md#what-are-the-parameters-to-ca

どうやら `non-empty nodes` に対してDaemonSetのPodを排出するような設定がデフォルトのようです。
このオプションを変更することにより、DaemonSetのPodを消さないようにできそうです。

※このオプションが使用できるのはCAのバージョン `v1.21.3` 以降です。

## デフォルトの挙動を変更して実行
`--daemonset-eviction-for-occupied-nodes=false` をCAの引数に追加します。
その後検証用Podを以下のように立ち上げて

```bash
$ kubectl get po -A -o jsonpath='{.items}' | jq -c '.[] | [.metadata.name,.status.phase]'
["aws-node-s2bdl","Running"]
["kube-proxy-wtfhh","Running"]
["daemonset-fluentd-9zbl4","Running"]
["deployment-app-6d4b447dfb-2q7f4","Running"]
```

この状態でCAでスケールインすると・・・

```bash
$ kubectl get po -A -o jsonpath='{.items}' | jq -c '.[] | [.metadata.name,.status.phase]'
["aws-node-s2bdl","Running"]
["kube-proxy-wtfhh","Running"]
["daemonset-fluentd-9zbl4","Running"]
```

DaemonSetのPodはDeploymentのPodよりも長く生存しています！

ということで、スケールイン時にPodがどのように消えていくのかは注意する必要があります。
QA表作成


![1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531298/50c6d871-7e3c-cee4-76aa-3b87bd53f263.png)


![2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531298/501ea91c-9111-5465-87cf-655fa239e811.png)


![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531298/b2bdff27-dedf-cec5-b015-2f2ab286a440.png)



![uploading...0]()
TimeWithZoneクラスについて

## 環境
Ruby2.6
Rails5.2

## はじめに
Railsでシステム日付を取得する場合は、Ruby標準のTimeメソッド、Dateメソッドは使わずに、Railsで用意されている、TimeWithZoneクラスを使うことになります。

TimeWithZoneクラスはActive Supportの拡張メソッドです。Ruby標準のTimeメソッド、Dateメソッドを使ってシステム日付を取得すると、OSが持っている日付がそのまま取得されるのに対し、TimeWithZoneクラスを使うと、OSのシステム日付がどうであれ、config/application.rbで設定しているタイムゾーンに該当する日付に変換して取得してくれます。

例えば、OSのタイムゾーンがUTC（協定世界時）である場合、Ruby標準のメソッドを使うと、UTCの日付がそのまま取得されます。しかし、TimeWithZoneクラスを利用すると、OSのタイムゾーンがUTCであっても、Railsで下記の設定をしている場合、JST（日本標準時間）に変換して取得してくれます。
```config/application.rb
config.time_zone='Asia/Tokyo'
```

OSのタイムゾーンが元々、JSTになっていれば、Ruby標準のメソッドを使っても、TimeWithZoneクラスを使っても、結果的には同じJSTの日付を取得してくれます。Linuxの場合、デフォルトのタイムゾーンはUTCになっています。デフォルトのままで、長年使い続けていることは恐らくないかと思います。大抵の場合、Linuxをインストールした後、コマンドを色々と打ち込んで、CUI操作を覚えている時期のどこかのタイミングで、タイムゾーンをUTCからJSTに変更しているはずだと思います。よって、開発環境においては、Railsでシステム日付を取得するときに、Ruby標準のメソッドを使ったとしても、大抵の場合、問題ないかと思います。

しかし、本番サーバーで動かす段階になると、サーバーのOS環境に依存することなく、JSTでシステム日付を取得するように、Railsで指定しておいた方が、トラブルを未然に回避できるかと思います。考えられることして、サーバーの環境設定は別の人が担当していて、タイムゾーンがどう設定されているか分からないまま、アプリをデプロイしてしまうといった場合です。リスクヘッジの意味合いにおいても、RaisではTimeWithZoneクラスを使っておいた方が無難という言い方はできるかと思います。

ちなみに、TimeWithZoneクラスを使っても、config.time_zone='Asia/Tokyo'を設定しないと、OSのタイムゾーンがJSTになっていたとしても、デフォルトでUTCの日付を取得することになります。

## 動作確認
Ruby単体の環境で、TimeWithZoneクラスを使う場合は、このように定義する必要があります。
```test.rb
require 'active_support/time'
```

Time.nowではRubyの標準メソッドを使ってシステム日付を取得していますが、Time.currentでは、RailsのTimeWithZoneクラスを使ってシステム日付を取得しています。TimeWithZoneクラスを使っても、Time.nowと全く同じように取得しています。
```test.rb
puts Time.now            # =>2022-10-25 16:56:19 +0900
puts Time.current        # =>2022-10-25 16:56:19 +0900
```

心配しなくても、Time.currentでもTime型で取得されています。
```test.rb
Time.current.class        # => Time
```

何日前、何日後を求めたい場合、Ruby標準のTimeクラスには該当するメソッドが用意されていないため、Dateクラスを使わざるを得ませんでした。TimeWithZoneクラスを使うと、Timeクラスを使って、何日前、何日後を求めることができるようになります。

TimeWithZoneクラスを使うと、今まで、Dateクラスでやっていたことが、Timeクラス一本でほぼほぼ実現できそうなイメージです。かといって、これからは、Dateクラスは使わずに、TimeWithZoneクラス一本に絞って使った方がいいのかと言えば、そういうわけでもありません。

TimeWithZoneクラスを使うメリットは、日付の操作を、Timeクラスで実現できるところにあります。日付と時間とをセットで扱いたい場合は、TimeWithZoneクラスを使うと便利になるかと思います。個人的には、システム日付を取得する以外で、「TimeWithZoneクラス超便利！」と感じたことはなかったりします。「Dateクラスでよくね？」と少しドライだったりします。

取り扱うのはあくまでも日付だけで、時間は扱わないのであれば、Dateクラスを使った方が逆に便利かと思います。日付しか扱わないのに、TimeWithZoneクラスを使うと、00:00:00 +0900という、時間がゴミデータのように、一緒に取得されることとなり、いちいち取り除くのが煩わしくなる場合があるためです。
```test.rb
# TimeWithZoneクラスを使って、何日前、何日後を求める場合です。
puts Time.local(2022,10,26).days_ago(3)         # => 2022-10-23 00:00:00 +0900
puts Time.local(2022,10,26).days_since(3)       # => 2022-10-29 00:00:00 +0900
```

```test.rb
# Dateクラスを使って、何日前、何日後を求める場合です。
puts Date.parse("2022/10/26").prev_day(3)       # => 2022-10-23
puts Date.parse("2022/10/26").next_day(3)       # => 2022-10-29
```

上記のメソッドを比較して、メソッド名を見て、直感的に何をやっているか分かりやすいのはどちらでしょうか。どちらも同じだと思います。
Gitのstatusでプッシュし忘れに気付く

英語が苦手だからちょくちょく飛ばして読んでしまうのは私の悪い癖です。

今回はその英語が何を意味するのかしっかり理解したのでメモを残します。

コンフリクトが起きて解消に気力と体力を持ってかれていた私がgit statusで確認をしたら以下のような内容が。

Your branch is ahead of 'origin/main' by 5 commits.
  (use "git push" to publish your local commits)

ええと。。。
今日はもう疲れちゃった。。。
明日調べよう。

そして今日意味を調べました。
あなたのブランチは 'origin/main' よりも 5 コミット進んでいます。(ローカルでのコミットを公開するには "git push" を使用します)

あーなるほど。
コミットで止まっているってことなのか。
この後ちゃんとプッシュまでやりました。
ReactでReferenceError useState is not definedが出た時の対処法

# エラーの背景と解決策
TODOアプリの作成時にuseStateを定義しようとしたら以下のエラーが出ました。

```
ReferenceError useState is not defined
```
調べたら```import { useState } from "react";```の記述がなかったので
***useStateがうまくimportできていない***状況でした。

```App.jsx
import React from "react";
import "./styles.css";
import { useState } from "react";  //この記述を追記

export const App = () => {
  const [incompleteTodo, setIncompleteTodo] = useState(["ポチ", "(ピーコ"]);
  const [completeTodo, setCompleteTodo] = useState(["ちび"]);
//省略
```
初歩的でしたが、上記のやり方で解決できました。

# 資料

https://bobbyhadz.com/blog/react-referenceerror-usestate-is-not-defined
Deno の Web フレームワーク Fresh でメタデータを設定する方法

# はじめに

最近流行りの JavaScript/TypeScript ランタイム Deno の Web フレームワーク Fresh を試していたときに、メタデータを設定する方法がドキュメントを探しても見当たらなかったので、記事にしてみました。

https://fresh.deno.dev/

### 開発環境

|  | version |
| --- | --- |
| OS | Ubuntu 20 (WSL2) |
| deno |  1.26.1 |
| fresh | 1.1.1 |

# Fresh のおさらい

Freshでは `routes` ディレクトリ内にファイルを作成すると、`fresh.gen.ts` が生成され適切にルーティングしてくれます。

例として、以下のように `routes/test.tsx` ファイルを作成します。

```tsx:routes/test.tsx
export default function() {
  return (
    <div>test</div>
  )
}
```

`deno task start` コマンドでサーバーを立ち上げ、 `http://localhost:8000/test` にアクセスすると以下のようなHTMLが返りページが表示されます！

```html:http://localhost:8000/test
<!DOCTYPE html>
<html lang="en">
  <head>省略</head>
  <body>
    <div>test</div>
  </body>
</html>
```

では、本題へ移ります。

# 特定のページにメタデータを設定する方法

`Head` コンポーネントを使うことでメタデータを設定できます。

https://github.com/denoland/fresh/blob/main/src/runtime/head.ts

例として、先ほどの `routes/test.tsx` に `Head` でタイトルを入れてみました。

```tsx:routes/test.tsx
import { Head } from "$fresh/runtime.ts"

export default function() {
  return (
    <>
      <Head>
        <title>テストページ</title>
      </Head>
      <div>test</div>
    </>
  )
}
```

`http://localhost:8000/test` にアクセスすると、無事にタイトルが表示されました。

```html:http://localhost:8000/test

<!DOCTYPE html>
<html lang="en">
  <head>
    省略
    <title>テストページ</title>
  </head>
  <body>
    <div>test</div>
  </body>
</html>
```

# すべてのページに共通のメタデータを設定する方法

`routes/_app.tsx` ファイルを作成し、以下のように `Head` コンポーネントを使うことで、全ページ共有のメタデータを設定できます。

```tsx:routes/_app.tsx
import { AppProps } from "$fresh/server.ts"
import { Head } from "$fresh/runtime.ts"

export default function({ Component }: AppProps) {
  return (
    <>
      <Head>
        <title>テストページ</title>
      </Head>
      <Component />
    </>
  )
}
```

`routes/_app.tsx` 以外にも、 `_` から始まる特殊なファイルがいくつかあるので Fresh を使い始める際には一通り見ておくとよさそうです！

https://github.com/denoland/fresh/blob/08d43803f799232853384311823adcd1a1638559/src/server/context.ts#L181-L186

# おわりに

`_app.tsx` を用いた方法は公式ドキュメントにはまだ載っていませんが(2022年10月25日時点)、ドキュメントを追加する Pull Rrequest は発見できたので近いうちにより詳しい情報がドキュメントに追記されるかもしれないです。

https://github.com/denoland/fresh/pull/494

また、Fresh を使った Web アプリケーションの例が以下に複数あります。本記事で紹介した `_app.tsx` の使い方など、ドキュメントに乗っていないテクニックがたくさんあるのでとても参考になります。

https://fresh.deno.dev/showcase

Fresh は2022年6月に v1.0.0 が公開されたばかりの新しい Web フレームワークですが、「Deno のインストールから Deno Deploy にデプロイ」という一連の流れがとてもスムーズにできて感動したので、もっと Fresh の開発の楽しさを体験してほしいです！

先日の Qiita Night フロントエンド特集でも Fresh の紹介がありました！

https://qiita.com/takusan64/items/f5e815202d7283a5dcc9

Fresh のこれからが楽しみですね！

# 参考文献

- Deno: https://deno.land/
    - Qiita: https://qiita.com/tags/deno
    - 週刊Deno: https://uki00a.github.io/deno-weekly/
- Fresh: https://fresh.deno.dev/
    - GitHub: https://github.com/denoland/fresh
- Deno Deploy
    - https://deno.com/deploy
【Linux】cpコマンド/mvコマンドについて

## cpコマンドについて
ファイルやディレクトリのコピーをする際に使用するコマンドです。
構文は`cp コピー元　コピー先`となります。よく使うパターンだけ記載しておきます。使わないと、たまに忘れてしまうので、、

下記で試しに、ファイルのコピーを行いました。

```shell_session:ファイルのコピー
[root@localhost tmp]# touch test.txt
[root@localhost tmp]# ll
合計 0
-rw-r--r--. 1 root root 0 10月 24 23:01 test.txt
[root@localhost tmp]# cp test.txt test.txt.bk
[root@localhost tmp]# ll
合計 0
-rw-r--r--. 1 root root 0 10月 24 23:01 test.txt
-rw-r--r--. 1 root root 0 10月 24 23:01 test.txt.bk
```

コピー先にディレクトリを指定した場合は、指定したディレクトリ内にファイル名をそのままでコピーする事も出来ます。まとめてファイルをコピーして、どこかに置いときたい時に使ってます。

```shell_session:ファイルをまとめてコピー
[root@localhost tmp]# touch test_{01..05}.txt
[root@localhost tmp]# ll
合計 0
drwxr-xr-x. 2 root root 6 10月 24 23:20 test
-rw-r--r--. 1 root root 0 10月 24 23:25 test_01.txt
-rw-r--r--. 1 root root 0 10月 24 23:25 test_02.txt
-rw-r--r--. 1 root root 0 10月 24 23:25 test_03.txt
-rw-r--r--. 1 root root 0 10月 24 23:25 test_04.txt
-rw-r--r--. 1 root root 0 10月 24 23:25 test_05.txt
[root@localhost tmp]# cp test_*.txt test
[root@localhost tmp]# ll test
合計 0
-rw-r--r--. 1 root root 0 10月 24 23:26 test_01.txt
-rw-r--r--. 1 root root 0 10月 24 23:26 test_02.txt
-rw-r--r--. 1 root root 0 10月 24 23:26 test_03.txt
-rw-r--r--. 1 root root 0 10月 24 23:26 test_04.txt
-rw-r--r--. 1 root root 0 10月 24 23:26 test_05.txt
```

ディレクトリをコピーしたい場合は、`-rオプション`を使用します。ディレクトリを再帰的にコピーするオプションです。

```shell_session:ディレクトリのコピー
[root@localhost tmp]# ll | grep '^d'
drwxr-xr-x. 2 root root 101 10月 24 23:26 test
[root@localhost tmp]# cp -r test test2
[root@localhost tmp]# ll | grep '^d'
drwxr-xr-x. 2 root root 101 10月 24 23:26 test
drwxr-xr-x. 2 root root 101 10月 24 23:35 test2
```

後は、`-pオプション`もよく使います。mode,ownership,timestampsを保持したまま、コピーを行えます。
これはrootでやらないと、所有者・所有グループがcpコマンドを実行したユーザーに書き換わってしまうのでその点は注意が必要です。


```shell_session:所有者等の情報を保持したままコピー
[root@localhost ~]# ll /tmp
合計 4
-rw-rw-r--. 1 test_01 test_01 5 10月 25 22:17 test_file.txt
[root@localhost ~]# cp -p /tmp/test_file.txt .
[root@localhost ~]# ll
合計 4
-rw-rw-r--. 1 test_01 test_01 5 10月 25 22:17 test_file.txt
```

## mvコマンドについて
ファイル名の変更やファイル/ディレクトリの移動で使うコマンドです。
ファイル名の変更を行う場合は`mv 対象ファイル 変更後のファイル名`で、ファイル/ディレクトリの移動は`mv 対象ファイル/ディレクトリ 移動先`です。

試しにファイル名の変更をします。

```shell_session:ファイル名変更
[root@localhost tmp]# touch test.txt
[root@localhost tmp]# ls
test.txt
[root@localhost tmp]# mv test.txt nyao.txt
[root@localhost tmp]# ls
nyao.txt
```

ファイル/ディレクトリの移動も試しにやります。よく使うオプションとしては、上書き防止で`-iオプション`を使用します。(cpコマンドにも同じオプションあります。)

```shell_session:ファイル/ディレクトリ移動
[root@localhost tmp]# touch test_file.txt
[root@localhost tmp]# mkdir test_dir1 test_dir2
[root@localhost tmp]# mv test_file.txt test_dir1
[root@localhost tmp]# ls
test_dir1  test_dir2
[root@localhost tmp]# ls test_dir1
test_file.txt
[root@localhost tmp]# touch test_file.txt

[root@localhost tmp]# ls
test_dir1  test_dir2  test_file.txt
[root@localhost tmp]# ls test_dir1
test_file.txt
[root@localhost tmp]# mv -i test_file.txt test_dir1
mv: `test_dir1/test_file.txt' を上書きしますか? y
[root@localhost tmp]# ls
test_dir1  test_dir2
[root@localhost tmp]# mv test_dir1 test_dir2
[root@localhost tmp]# ls
test_dir2
[root@localhost tmp]# ls test_dir2/
test_dir1
```

## 終わり
コマンド使わないと忘れるので、たまに用もなくぽちぽちしてます。
【vue/Nuxt】イベントオブジェクトの取得

# vueやnuxtでのイベントオブジェクト取得方法

## サンプルコード

```vue
<button @click="btnClickEvent">イベントオブジェクト</button>
<button @click="btnClickArg(1)">引数</button>
<button @click="btnClickEventArg(1, $event)">イベントオブジェクトと引数</button>
```
```js
let app = new Vue({
        el: "#app",
        data() {
          return {};
        },
        methods: {
          btnClickEvent(e) {
            console.log(e);
          },
          btnClickArg(int) {
            console.log(int);
          },
          btnClickEventArg(int, e) {
            console.log(int, e);
          },
        },
      });
```

methodsの引数に`e`と入れるだけでイベントオブジェクトが取得できます。
それに加え、引数も取りたい場合は第一引数に実引数、第二引数に`$event`と記述することで両方取得できます。

参考：https://negalog.com/vue-event-object-argument/
公式：https://jp.vuejs.org/v2/api/#v-on
Gitのコンフリクトで痛い目にあった話

少しずつGitの使い方が分かってきて、ある程度の問題なら自分で解決できるなーって思っていた矢先に起きたトラブルです。

◆著者ステータス
Git経験　　　2か月
Java経験　　　1年
angular経験　1か月

◆起きたトラブル
誤ったマージを行った事によるテストの遅延。

gitの操作はpull,status,logなどはコマンドで実行して、コミット、プッシュはVscodeやエクリプスの方が楽なので、そちらで行っていました。

◆競合が起きた時のいつもの対処
コミット及びプッシュを同時に行い、競合が起きたら一度コミットした状態(ステージング状態)をGit resetで戻し、競合部を解消。
再度コミット＆プッシュ

★今回の対応
On branch main
Your branch and 'origin/main' have diverged,
and have 3 and 1 different commits each, respectively.
  (use "git pull" to merge the remote branch into yours)

All conflicts fixed but you are still merging.
  (use "git commit" to conclude merge)

まず見慣れない文章に戸惑いながら対応

対象のコードでこんなのが出ている。
<<<<<<< HEAD　
hoge

=======
fuga

">>>>>> 008d1b857b029fdef7f11da9f49107950eb17272

色々やって別の部分もマージしてしまい大変なことになったので、今回は次に備えて対策を記載する。

<<<===>>>をマージマーカーと呼ぶ
<<<Headまでが今チェックアウトしているブランチの変更

どっちの部分を残すか手動で修正する。
修正後自分でコミットする。

その後Git statusをみるとこう表示されるが一応pullは出来るのでコンフリクトは解消されたようだ。

On branch main
Your branch is ahead of 'origin/main' by 4 commits.
  (use "git push" to publish your local commits)

nothing to commit, working tree clean

色々まだわからない点もあるが、解決はしたので今回はここまでとする。
AWS Certified Cloud Practitioner 超格安！ スレスレ合格体験記

# AWS Certified Cloud Practitioner *超格安！* スレスレ合格体験記

## 本記事の目的
2022 年 8 月 18 日に AWS 認定 Practitionaer の試験を受け、資格を取得しました。
本記事では、私がどのような状態からどのような経緯で資格取得に至ったかについて、振り返っていきたいと思います。


## 前提

受験を決定した段階での私の状態、環境は下記の通りです。

- AWS の学習、使用経験なしから学習をスタート
- クラウド以外のコンピュータおよびネットワークの知識は、座学中心でおおまかに習得済み（無資格）
- 技術者としての業務経験は無し
- AWS の各種サービスやリソースはある程度自由に使用可能
- 平日、業務時間を試験対策に充てることができる

## 目標設定

受験に当たっての目標です。これらに沿って学習計画を練ります。

- 学習期間約 1 か月での取得を目指す
- __有料コンテンツは可能な限り使わない__
- SAA など上位の資格を今後受験することや、業務で将来的に扱うことを意識して、発展を見越した学習を行なう

## 学習計画

大雑把に、AWS の概要理解→各種サービスの使い方→出題傾向に沿った対策と進めます。

サービスの使い方については 2 か月で網羅することは難しいため、試験までに主要なサービスのうち 6 割程度に触れられれば充分と考えました。200 を超えるサービスから 120 種使えるようする、というわけではなく、VPC や IAM などの中心的なサービスを網羅しておくことが目指すところです。

また、出題傾向に合わせた対策は受験 2 週間前から開始し、可能な限り無料サイトで情報収集していくことにします。

## 試験対策で行なったこと

対策開始から試験日までに行なった試験対策の内容です。
順番は厳密ではありませんが、おおまかに時系列に沿っています。

1. AWSome Day Online Conference  
AWS の完全な初心者に向けたウェビナーです。私は完全な初心者だったので、まずは AWS の意義、強み、特徴について俯瞰的に学びました。  
最初に AWS について知るにはうってつけで、試験問題にありがちなビジネス上の価値を問われる問題についてはすべてこのウェビナーに詰め込まれていたように思います。

1. AWS Hands-on for Beginners  
AWS 公式が提供している、初めて AWS を学習する人に向けたハンズオンです。  
約 20 種の講座があり、ひとつに付き 1~2 時間の動画を見て各種サービスについて学べます。  
試験対策としては各項目に対して過剰な学習となりますが、技術の定着を見越してハンズオンにかなり注力しました。
試験日までの達成率は 8 割ほどです。この過程で VPC や IAM などの取り扱いを手で覚えていった形になります。

1. [試験問題サイト](https://aws-exam.net/clf/)での対策  
無料サイトで掲載量が多いところを探しました。  
今回お世話になったサイトは 130 問以上の問題数とその解説があり、開放されたコメント欄にはユーザーからの補完もあったため、有用と判断して利用しました。  
取り組み方として 4~5 周かけて理解度を高めました。1 周目は問題の雰囲気と自分の理解度を知るために流し気味に解き、2 周目では間違えた問題や難しく感じた問題で立ち止まって公式の情報などを参考に理解度を上げました。3 周目ではほとんどの問題で根拠を持って正答できることを目標にしましたが 8 割程度の達成度だったので、4~5 周目で残りの 2 割を補いました。  
問題数が多いとはいえ 130 そこらなので、周回を重ねる負担はそこまで感じませんでした。


## 試験当日

これらの対策を重ねたうえで試験本番に臨みました。  
ちなみに受験方式はオンラインで、寝室を少し整理してそこにちゃぶ台サイズの雀卓を置いて環境をセットしました。  
使用した PC は MacBook Air で、通信は Wi-Fi でした。
これら環境に特に不便は感じませんでした。

肝心の試験問題ですが、上項の問題サイトで触れた問題には難なく答えられたものの、初見の問題がたくさん出ました。
体感の割合にして 4~5 割は対策不足の問題でした。そのうち約半分は対策よりも詳細な情報を問われるものであり、残り半分はそもそもマークしていた範囲外です。

より詳細な聞かれ方をした問題は、例えばマネージドサービスにおいてユーザーが何をする必要があるか、といった具合のものが多かったように思います。ハンズオンで触れたサービスについてはあまり困らず回答することができました。触れていない上に細かく問われた問題は博打でした。

範囲外で困ったのは主に Well-Architected フレームワークのものが多かったです。範囲については公式の資料をよく見ていなかったので私の落ち度がかなり大きいのですが、今試験ガイドを見ても Well-Architected フレームワークには言及されてませんね。目的と方法論をつなぐ指針を問われたので、その範囲の出題に関しては最初に受けたウェビナーの恩恵を強く感じました。

## 結果

正答率 74% となり、合格ライン 70% に対してギリギリな結果となりました。  
反省として、範囲・難易度ともにカバーが足りず、安定して回答できた問題が少なかったです。  
改善案として、公式の試験ガイドと突き合わせて勉強範囲の漏れを確かめる、ケチらず有料サイトを使う、無料サイトの場合は複数種類のサイトを参照する、などが挙げられます。一番効率と信頼を担保できるのは有料サイトを使うことですかね......。近々 SAA も受験する予定なので、そちらで試してみたいと思います。

余談ですが、オンラインで試験を受けることができてしかも結果が即座に分かるというのはとてもありがたかったです。良い時代だなぁとつくづく感じます。
交通費などもかからなかったので、今回の受験での合計費用は、受験費と一部ハンズオンのリソース費用のみです。（どちらも会社持ちなので一銭も払っていません。）


## まとめ

- 公式のウェビナーやハンズオンは試験対策の効率としては微妙だが、得られる知識と技術の質は非常に高い
- 無料のサイトひとつに頼り切る対策は極めて危険である
- 人は PC の置き場にベッドと雀卓の二択を迫られると、雀卓を使う