OmniAICreator/Qiita-1.07M huggingface dataset:
自チームでクラウドを対応することになったリーダー/管理職へ（なぜAWS?）

# はじめに
これは、自分のチームでクラウドを対応することになった自身の経験をもとにしています。
最終的にクラウドアーキテクトチームを組織するまでの試行錯誤を共有できればと思います
自分のチーム/組織でクラウドを対応することになったリーダー、管理職の方々への参考に！
なお、本投稿ではIaaSクラウドを基本とし、AWSを前提にしています。

# なぜAWS？
以前の投稿で下記のように書きました。
「どのクラウドでも選択できる状態なのであれば、**まずはAWSから始める**ことをお勧めします。」


https://qiita.com/yhotta/private/c55c8c7e19462cede498

そもそもなぜこのように考えるようになったのかを今回は書きたいと思います。

# クラウドは簡単に使えるが理解するのは難しい
AWSに限らずAzureでもGoogle Cloudでも、取りあえず仮想サーバを作ってみる、データベースを起動してみる、サーバレスでコードを実行してみることはかなり簡単にできます。（これは本当に素晴らしい…）

**しかし、それぞれの仕様や特性を理解することがとても難しいです**

クラウドはクラウドサービスを提供する事業者と利用者との責任分界点が定められています。（参考　[AWS 責任共有モデル](https://aws.amazon.com/jp/compliance/shared-responsibility-model/ "AWS責任共有モデル")）
事業者の責任領域の作りや仕様は一様ではないため、それぞれに理解する必要があります。

これを明らかにするには、実際に作ってみて動作を確認することが一番です。また、いわゆる「べからず」なども試してみて初めて気が付く場面が多かったりします。ただ、それを上回る速度でクラウドは進化していきます。

https://aws.amazon.com/jp/blogs/news/tag/%E9%80%B1%E5%88%8Aaws/

これは、チームの学習に必要な時間＝コストへの大きな課題となります。
私は、まずはシェアの高いAWSとAzureを対応できるチームにしようと思ったのですが、早々にこの問題（チームの悲鳴）に直面することになりました。

# あらためてなぜAWS？
私がAWSを選んだ理由は以下のようなものです
* シェア
世界的なシェアは[総務省の資料](https://www.soumu.go.jp/johotsusintokei/whitepaper/ja/r04/html/nf306000.html#d0306200 "20. 世界のパブリッククラウドサービス市場のシェア")を見るとAWSとAzureが1位2位となっています
シェアの大きさは、世間的な技術者の多さに直結します。
要員を募集する必要が出てきた場合などとても重要な要素です。
* 学習のしやすさ
シェア的にはAWSとAzureが良さそうです。
それぞれのセミナーなどで学習をしてみた結果、AWSの方がとっつきやすい印象がありました。
中でもAWS BLACK BELT ONLINE SEMINARはかなり魅力でした。
（Microsoft製品の知識をあらかじめ持っているチームなら、この判断は変わるかもしれません）

https://aws.amazon.com/jp/events/aws-event-resource/archive/?cards.sort-by=item.additionalFields.SortDate&cards.sort-order=desc&awsf.tech-category=*all

* 実績
各クラウド認知がとても進んだ現在ではほとんど考慮の必要はないですが…　
「なぜそのクラウドを優先する？」を問われた際に、国のシステム（第二期政府共通プラットフォーム）で利用された実績は説明がしやすかったです。

https://aws.amazon.com/jp/about-aws/whats-new/2020/10/japan-government-common-platform-launches-on-aws-to-accelerate-digital-transformation-of-citizen-services/

なお、2023年現在、第二期政府共通プラットフォームの後継である「[ガバメントクラウド](https://www.digital.go.jp/assets/contents/node/basic_page/field_ref_resources/d6b5753c-c4eb-4ee6-92d0-21b3fa945a82/b90d9207/20221003_policies_gov_cloud_outline_01.pdf)」ではAWSだけでなく、Google Cloud、Azure、Oracle Cloud Infrastructureの4クラウドが認定されています。

# 最後に
チーム/組織の学習効率のためにも、対応するクラウドをまずは一つに絞ることをお勧めします。
複数のクラウドを扱う場合でも、まずは一つ選んだクラウドにて学習を進めてからその他のクラウドの学習を始めると理解が早いと思います。
私は元々ネットワークエンジニアですが、「とりあえず、まずはCiscoから」に近い考えですね。
【基礎学習/Snowflake】SnowflakeのWarehouseについて理解してみた

# 今回の課題
Snowflakeの勉強をしていて、
ドキュメントに出てくる用語（特にWarehouse周り）について理解できていないと感じたため、色々と調べてまとめてみた。

## SnowflakeにおけるWarehouseとは
Snowflakeの「Warehouse」は「データを保存する場所」を意味するのではなく、
「データの処理を実行する力」を意味するイメージ。
SQLなどの処理に使用されるクラスタ（コンピューティングリソース）のことを言う。

ちなみに、請求は下記に基づいて計算される。
* Warehouseのサイズ
* クラスターの数（マルチクラスターウェアハウスを使用している場合）
* 各クラスターのコンピューティングリソースが実行される時間の長さ。

## Snowflakeにおけるクラスタとは
「[SnowflakeにおけるWarehouseとは](https://qiita.com/Ayumu-y/items/77c5feb6c1186f9ef189#snowflake%E3%81%AB%E3%81%8A%E3%81%91%E3%82%8Bwarehouse%E3%81%A8%E3%81%AF)」で記述した、Snowflakeにおける「クラスタ」は、
Warehouseのサイズに応じて、1つのクラスタを保持している。

小さいWarehouseは数台のサーバーで構成される1つのクラスタを保持していて、
大きなWarehouseはそれよりも多くのサーバーで構成された1つのクラスタを保持しているイメージ。

### マルチクラスターウェアハウスとは
上記の通り、デフォルトではWarehouseは、
クエリを実行するために使用可能なコンピューティングリソースの1つのクラスターで構成される。
Warehouseにクラスタを追加し、並列性を強化して多くのリクエストに応えられるように強化することができ、それをマルチクラスターウェアハウスと言う。（スケールアウトのこと）

## スケールアップとスケールダウンとは
Warehouseのサイズを変更すると、クラスタ内のサーバーの数が変更される。
既存のWarehouseのサイズを大きくすることを「スケールアップ」、
小さくすることを「スケールダウン」と呼ぶ。

Warehouseのサイズを変更すると、特に大規模で複雑なクエリのパフォーマンスが向上する。
Warehouseのサイズが大きいほど高速であるとは限らず、迅速に実行されている小規模で基本的なクエリの場合、サイズを大きくしてもあまり効果がないことがある。
Python用のMySQLコネクタでトランザクションの開始終了を実装する方法

## 前提
Pythonのmysql.connectorには、
self.conn.commit()
self.conn.rollback()
上記の、トランザクションのコミットもしくはロールバックのメソッドは存在します。

しかし、トランザクションの「開始」用のメソッドは存在しません。
存在しませんが、自動でトランザクションを開始してくれているわけではないので、自前で
トランザクションを開始させる必要があります。

## 実現方法
mysql.connector.cmd_query('START TRANSACTION')
これを起動することでOKです。(MySQL用のトランザクション開始クエリーをself.conn.cmd_query
メソッドで発行します)

## おまけ
mysql.connector.cmd_queryは引数に指定した文字列のクエリを発行してくれるため便利です。

mysql.connector.cmd_query('SET innodb_lock_wait_timeout=1')
例えば、これを発行すると、トランザクションタイムアウトの時間を制御できます。
趣味プログラミングはいいぞという話

# 結論
趣味プログラミングやろう！！！

# 背景
別記事で書いてますが、うつを患ってました。

https://qiita.com/ryotashona/items/2121fc6ab1299829a6d9

そして復活しました。
よくよく考えてみると、うつになる前は長いこと業務プログラミングしかしてませんでした。
もともと、ITとかガジェットとか好きだから～ってこの業界に入ったのに。

# 視界が狭まってませんか？
業務プログラミングで同じようなことばかりしていませんか？
それで楽しければいいです。あと、ITが好きじゃない人も。
でも、もしもITが好きなら趣味プログラミングをした方が良いです。
新しい情報に揉まれます。楽しいです。もみくちゃです。
分からないことがたくさん出てきます。

# え？時間がない？疲れて出来ない？
有休があるでしょう。多少無理だと言われても調整をして取りましょう。
病欠のために残してるって？その時はその時、欠勤すればいい！なんとかなる！

大丈夫。あなたが居なくても仕事は何とかなります。
そして、趣味プログラミングで得た知識を会社に戻してあげてください。
そうすれば、結果的には会社にとってはプラスになります。
Djangoフレームワーク内でプロセスを複数起動させる方法

## 前提
Djangoフレームワーク内の処理で、プロセスを複数立ち上げて、
並列処理を実施したい場合の実装方法について解説します。

from multiprocessing import Pool
でmultiprocessingをimportして、普通にマルチプロセスを起動しようとすると、
Djangoのエラーが発生します。Djangoの1つのプロセスの中で、別のプロセスを立ち上げることは基本できません。

## 実現方法
Django内では別のプロセスは起動できないので、マルチプロセスとして起動させたい処理を、
Django外として扱うことで、プロセスを複数立ち上げることができます。

## 実装例
```python:Python
from application.service.xx.xxService import xxService
from multiprocessing import Pool

class FileDownloadServiceImpl(FileDownloadService):
    def __init__(self, result_file_num):
        self.result_file_num = result_file_num

    def mainLogic(self):

        try:
            ##Djangoに関わるimportをここで実施
            from application.repository.mdData.fileDownload_repository import FileDownloadRepository
            from scrapingSystem.repositoryImple.mdData.fileDownload_repository import FileDownloadRepositoryImple

            .....................

            partedXlByteListLenCnt = len(self.start_index_list)
            pool = Pool(processes=partedXlByteListLenCnt)
            pool_result_list = []
            args_list = []
            for i in range(partedXlByteListLenCnt):
                args = (self.xl_byte_data, i, self.start_index_list[i], self.last_index_list[i],)
                args_list.append(args)
            pool_result_list = pool.map(multiByteParseStringWrapper, args_list)
            for pool_result in pool_result_list:
                self.process_index_que.append(pool_result[0])
                self.tree_list.append(pool_result[1])

            ......................

            return self.byte_in_list
        except:
            raise

    def __twoDevideByteData(self, start_index, last_index):
        ......................

def multiByteParseString(xl_byte_data, process_index, start_index, last_index):
    ......................

def multiByteParseStringWrapper(args):
    return multiByteParseString(*args)
```
上記のように、マルチプロセスで起動させたいメソッドが、Djangoと一切関わらないようにすることで、
Djangoの処理の中で、別のプロセスを複数起動させることができます。
ESModules・CommonJSとは何か？

## 概要
- `ESModules`は、`ECMAScript`の仕様の一部。
- `CommonJS`の一部の仕様として、`Modules`がある。
- `ESModules`と`CommonJS`は、文脈的にJavascript・TypeScriptで、別のモジュールを読み込むため仕組みを指すことが多い。
- `ESModule`と`CommonJS`は、競合する関係。（正確には、`ECMAScript`と`CommonJS`は競合する関係）
    - ESModules
        - `CommonJS`の上位互換。
        - `ESModule`から`CommonJS`のモジュールを読み込むことが可能。
    - CommonJS
        - `Node.js`でデフォルトで採用されてきたが、最近は`ESModules`に変わりつつある。

### 実装上の違い
- ESModules
    - モジュール側
        ```javascript:modules.mjs
        const getName = () => {
          return 'hoge';
        };
        const getAge = () => {
          return 18;
        };
        
        export {
          getName,
          getAge,
        };
        ```
    - モジュールを呼ぶ側
        ```javascript:index.mjs
        import { getAge } from './modules.mjs';
        console.log(getAge());
        ```
- CommonJS
    - モジュール側
        ```javascript:modules.js
        module.exports = {
          getName: function() {
            return 'hoge';
          },
          getAge: function() {
            return 18;
          },
        }
        ```
    - モジュールを呼ぶ側
        ```javascript:index.js
        const { getAge } = require('./modules.js');
        console.log(getAge());
        ```

## 結論
- `ESModules`と`CommonJS`はモジュールの仕様。
- これからは、`ESModules`が主流になる。
- とは言え、まだ`CommonJS`を使うことは多い。

## ちなみに
- ESModulesをブラウザで実行するには、`type="module"`の指定が必要。
    ```html:index.html
    <script type="module" src="./index.js">
    ```
JavaScriptのnew演算子とコンストラクターのreturn文

# new 演算子とは
JavaScriptでは、new演算子を使用してオブジェクトを作成することができます。このとき、new演算子を使って呼び出される関数は、コンストラクター関数と呼ばれます。

コンストラクター関数内でreturn文が使用された場合、その返された値が新しいオブジェクトとして扱われます。具体的には、以下のような手順が実行されます。

* 新しい空のオブジェクトが作成されます。
* コンストラクター関数が呼び出されます。この時、thisキーワードは、新しく作成されたオブジェクトを参照します。
* コンストラクター関数内で、新しいオブジェクトに対してプロパティやメソッドを追加できます。
* 新しいオブジェクトがreturn文で返される場合、その値が返されます。そうでない場合、thisキーワードが自動的に返されます。


# return文ない例（通常これ）
コンストラクター関数内でreturn文が使用されていない場合、thisキーワードが自動的に返されます。例えば、以下のコードは、新しいオブジェクトを作成してthisキーワードを返す例です。

```javascript:return文なし
function Person(name) {
  this.name = name;
}

const person = new Person('Jane');
console.log(person.name); // 'Jane'
```

この場合、Personコンストラクター関数内でreturn文は使用されていません。そのため、新しいオブジェクトはthisキーワードによって参照され、person変数はそのオブジェクトを参照します。したがって、console.log(person.name)は'Jane'と出力されます。

# return文がある例
以下のコードは、Personというコンストラクター関数を定義し、return文を使用してオブジェクトを返す例です。
```javascript:return文書かれている例
function Person(name) {
  this.name = name;
  return {name: 'John'};
}

const person = new Person('Jane');
console.log(person.name); // 'John'
```

この場合、Personコンストラクター関数内でreturn {name: 'John'}が使用されています。そのため、新しいオブジェクトとして{name: 'John'}が返され、person変数はそのオブジェクトを参照します。したがって、console.log(person.name)は'John'と出力されます。

また、return文で返されるオブジェクトが、コンストラクター関数で定義されたプロパティやメソッドを上書きしてしまう場合もあります。例えば、以下のコードは、Personコンストラクター関数で定義されたgreetメソッドを上書きしてしまう例です。

```javascript:objectのプロパティの一部が被っている場合
function Person(name) {
  this.name = name;
  this.greet = function() {
    console.log(`Hello, my name is ${this.name}`);
  };
  return {
    name: 'John',
    greet: function() {
      console.log('Nice to meet you');
    }
  };
}
const person = new Person('Jane');
person.greet(); // 'Nice to meet you'
```

この場合、Personコンストラクター関数内でreturn文が使用され、greetメソッドも新しいオブジェクトに上書きされます。そのため、person.greet()は'Nice to meet you'と出力されます。

:::note warn
コンストラクター関数内でreturn文が使用されると、その返された値が新しいオブジェクトとして扱われるため、通常のnew演算子によるオブジェクトの作成とは異なる結果が得られます。new演算子を使用する際には、コンストラクター関数内でreturn文を使用することによる影響に注意しましょう。
:::



# return文でオブジェクト以外のプリミティブ値を返す場合

new演算子とreturn文の関係については、さまざまな観点から理解することができます。前述の通り、return文でオブジェクトが返された場合は、その返されたオブジェクトが新しいインスタンスとして扱われます。しかし、return文でプリミティブな値（string、number、boolean、null、undefined、symbol）が返された場合には、new演算子によって生成されたオブジェクトではなく、return文で返された値が返されます（そうじゃないJavaScriptエンジンもあるかも...）

以下は、return文でプリミティブな値を返すように定義されたコンストラクター関数の例です。

```javascript:return文でプリミティブ値返す場合
function Person(name) {
  this.name = name;
  return 123;
}

const person = new Person('John');
console.log(person); // Person { name: 'John' }
```

この例では、Personコンストラクター関数内でreturn文が使用され、123というプリミティブな値が返されます。しかし、new演算子によって生成されたpersonオブジェクトはPersonコンストラクター関数で定義されたthisのオブジェクトであり、nameプロパティを持っています。つまり、return文で返されたプリミティブな値ではなく、thisが返されていることがわかります。

# あとがき
ChatGPTに大枠の文章とサンプルコードを書かせて修正しました。
嘘つくこともあるので検証は必要ですが、文章を0から作るより楽ですね。
うつ病からの復活体験メモ

# 結論
**※※※※個人の感想です※※※※**
**誰しもなりえます。運です。**
予兆の睡眠の質低下や食生活の変化は意識しないと気づけない。
意味もなく涙が出たらすぐに病院/カウンセリングへ行った方がいい。
休職後に「体調が回復した」と思っても、そのあと数か月は様子を見てから復職した方がいい。

# 自己紹介
最近うつ状態から運よく復活した、猫大好き40代エンジニアです。
2019年の夏から2022年の冬まで、うつ状態のまま地獄を味わいました。
一度浅はかな復職をして、、、
再発に怯えてますが、結果的にはほんとに運がよかった。

# 体験記
### 1度目の休職と復職
2019年の夏、色々あって限界がきて会社を早退。
早退後にクライアントからのチャット通知に気づき発狂。
部屋のモノを破壊、泣きじゃくる、手足がしびれてしばらく動けなくなる。
そのまま数日有休取って病院へ行き、診断書を貰って休職へ。

休職後2週間は焦燥感と消えたくなる感(?)で何も出来ない。
が、それも焦燥感になる。無限ループって怖いですね。

薬が効いて少し元気になる。気晴らしに外にも出てみる。
今思えば焦ってたんでしょうね。のんびり構えてればいいものを。
担当医に「調子がいいです。復職したいです。」と告げてしまう。
晴れて1か月で復職ことに。これが地獄の始まり。

### 1度目の復職後
思考力/判断力/決断力が全く戻ってなく、パフォーマンスが全くでない。
日常生活でも
- スーパー行くと何買えばいいかわからない。フリーズ。
- 水を飲みたいと立ち上がる。冷蔵庫から何か取りたいと思う。フリーズ。

などなど。

何もできない自分にひどく落ち込む。これが半年ぐらい続いたかな・・・
その当時の具体的な記憶はあまり覚えていない。
業務の調整をしてもらいつつ、なんとか出来ることをするようになる。
が、こんなことしかできないのか・・・という気持ちは常に持ち続ける。
数か月周期で大きな波が来て、その都度「会社やめようかな」「消えたいな」と思う。

そのうち、寝起き / PCの前に座る / 何かしらある と手足がしびれて、フラッシュバック状態へ。
やるべきことが分かっているのに、簡単なコードすら書けない状態になる。
2022年の春に再度酷い限界が来て休職へ。

### そして2度目の休職
最初の1か月目は1度目と同じくだんだん調子が戻ってくる。が、ここで分岐点。
このまま復職すると同じことの繰り返しになると思い、しばらくは様子を見ようと思う。
心に余裕ができると、睡眠、食欲が異常であることが自覚出来た。
**実は2019年(たぶんもっと前)から、ここまで下記症状の自覚が全くなかったです。**
- 食欲異常：夜に「弁当(大)2つ + ロールケーキ1本」などを食べる。我慢もできない。
- 睡眠の質低下：1,2時間おきに目が覚めるかつ、一度目が覚めると寝付けない。

コイツはヤベーと。とにかく自分をコントロール出来なくなっている。
とにかくこの2つがコントロール出来までゆっくり休もう。期間は無期限と決心。
処方される睡眠薬がだんだん強くなってきて、ようやく4時間ほど連続で寝れるようになる。
朝には散歩。視界がクリアになる。食欲も普通に戻ってどんどんやせる。（最終的に3か月ぐらいで10Kg落ちた）
毎日[食事/睡眠/充実度/体重]のスコア記録を始める。

休職4か月目にはかなり回復していたが、復職後に再度不調になると思い、色々準備する。
睡眠薬を減らせるか～とか、親族関連の心配事を解決～とか、最悪セーフティネットを使ってもいいように準備～とか。
「確定ではないが1,2か月後に復職する」「出来ること、出来ないこと」を上司に宣言をして、揺らぎを見る。
などなど行い、結局6~7か月間休職しました。

### 2度目の復職後
事前に宣言した通り、出来ない仕事(1度目の休職の切っ掛けになったクライアント)からは外してもらいました。
それでも復職後1か月あたりで寝れなくなることがありました。
が、記録をつけていた事で適切に対応、担当医に相談して睡眠薬を処方してもらって安定化。
今は無理のない範囲で仕事をしつつ、システム設計、プログラミングの面白さを取り戻ました。

# まとめ
猫飼ってるんですけど、この子たちが居なかったらどこかでドロップアウトしてましたね。真面目な話。
地獄のような経験でしたが、貴重な経験でした。これも何かの縁だと今は思えます。
この経験を生かして、ゆったりやれる状況も生かしつつ、協力してくれた会社に何か返せたらなと思ってます。

そして、今の状態に戻れたことは運も大きく絡むのかなと。
もし今つらい人は「運が悪いだけだ」と、一度諦めて下さい。
あなたの状態は誰にもわかりません。そして運が良ければ戻れます。
静かに時を待ちましょう。

(書きながら思い出して泣いちゃった)
DjangoをMVCで開発するメリットについて

## Djangoフレームワークについて
通常、Djangoフレームワークは、
![スクリーンショット 2023-03-19 11.22.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1215249/f7429277-2b24-edbb-7ff2-6a423f113bb6.png)
上記のような「MVT」のアーキテクチャとなっております。
小規模なアプリケーションの開発の場合は特に問題はありませんが、大規模なサーバーサイドを開発する場合は、viewに
・RESTゲートウェイ
・業務ロジック
・DBとのIn/Out
これらの処理が一点に混在してしまうことで、viewが太り、保守性が悪くなってしまいます。

## 回避方法
MVTをMVCに変換することで、解決をすることができます。
具体的には、
![スクリーンショット 2023-03-19 11.30.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1215249/3a7cc3e1-4f74-5d03-fa4d-ff54fc84256f.png)
上記のようなアーキテクチャになります。
これは、JavaのMVCアーキテクチャを参考にしています。

最初太っていたviewを、RESTゲートウェイの機能のみに集中させます。
業務ロジックは、Application層のServiceImplに移動、
DBとのIn/Outとそれに付随する処理は、RepositoryImplに移動させます。

このように構築することで、役割を分散させることができ、viewが太ってしまうことを防ぐことができます。
Kubernetes Engineの管理

# Kubernetes Engineの管理
## Cloud SDKとCloud shellを使用して、Kubernetesを操作する

　①全てのkラスタの名前と基本情報の一覧を表示するためには、以下のコマンドで </br>
```gcloud container clusters list```

　②クラスタの詳細情報を表示するには </br>
```gcloud container clusters describe``` </br>
 または、--zone と --regionパラメータを使用して、ゾーンまたはリージョンの名前を渡す要</br>
 以下、us-central1-aにあるclusterSampleの説明を出力する</br>
```gcloud container clusters describe --zone us-central1-a clusterSample``` </br>

③ノードとポッドの情報を出力するには、kubectlコマンドを使用する</br>

 まず、正しく構成されたkubeconfigがあることを確認する、以下のコマンドで </br>
 ```gcloud container clusters get-credentials --zone us-central1-a clusterSample```  </br>
 認証情報の取得と設定が含まれる </br>

  ・次のコマンドでクラアスタのノードのリストを出力する </br>
    ```kubectl get nodes``` </br>
  ・次のコマンドでpodのリストを出力する </br>
    ```kubectl get pods``` </br>
  ・nodeとpodの詳細を出力する </br>
    ```kubectl describe nodes``` </br>  
    ```kubectl describe pods``` </br> 
   
   ④nodeの追加、修正、削除の操作</br>
     ```gcloud container clusters resize``` で追加または削除できる。</br>
     例： クラスタclusterSampleのサイズを３から５に増やすには、以下のコマンドで </br>
       ```gcloud container clusters resize clusterSample --node-pool default-pool --size 5 --region=us-central1``` </br>
       上記コマンドでcluster name、node pool name、cluster nameを指定する </br>
    ```gcloud container clusters update``` で変更できる。</br>
    例：自動スケーリングを有効にするには、以下のコマンドで </br>
     ```gcloud container clusters update　clusterSample　--enable-autoscaling --min-nodes 1 --max-nodes 5 --zone us-central1-a --node-pool default-pool```  </br>

   ⑤Podの追加、修正、削除の操作</br>
   ベストプラクティスは、Podを直接操作しないこと、KubernetesあDeploymentで指定されたPod数を管理する。Pod数を変更する場合、Deploymentの構成を変更すること。</br>
    ・ Deploymentのリストを出力するには以下のコマンドで </br>
     ```kubectl get deployments``` </br>
    ・ Podを追加または削除するには以下のコマンドで  nginx-1とのDeploymentのレプリカ数を６にする</br>
     ```kubectl scale deployment nginx-1 --replicas 5``` </br>
    ・自動スケーリング設定、autoscaleコマンドを使用する。 </br>
    　例：CPUの使用率は８０％を超える場合、最大１０個Pod追加で、Deploymentには、常に1個以上のPodが存在するとのコマンドは以下</br>
     ```kubectl autoscale deployment nginx-1 --max 10 --min 1 --cpu-percent 80``` </br>
     ・Deploymentを削除するのは、delete deployment コマンドを使用する。 </br>
    ```kubectl delete deployment nginx-1``` </br>

   ⑥サービスの追加、修正、削除の操作</br>
・ serviceのリストを出力するには以下のコマンドで </br>
     ```kubectl get services``` </br>
     ・ serviceを追加するには、kubectl runコマンドを使用して、サービスを起動する。例えば、は以下のコマンドで hello-world-serviceとのサービスを追加＆起動する</br>
     ```kubectl run hello-world-service --image=gcr.io/google/samples/hell-app:1.0 --port 8080``` </br>
     上記コマンドでは、パス「gcr.io/google/samples/」に存在するhell-appとのイメージのバージョン1.0をダウンロードして、実行する。ポート8080でアクセスする。 </br>
     サービスを公開する必要があって、exposeコマンドを使用して、公開できる。</br>
     ```kubectl expose deployment hello-world-service --type="LoadBalancer"``` </br>

⑥コンテナ　イメージの詳細</br>
  Container Registryはコンテナ　イメージを保存するためのGCPサービスです。レポジトリを作成して、イメージをプッシュすると、以下のコマンドでイメージを操作できる </br>
  ・イメージのリストを出力する</br>
　```gcloud container images list``` </br>
  ・イメージの詳細を出力する</br>
　```gcloud container images describe gcr.io/google/samples/hell-app:1.0``` </br>
【Python】Atcoder勉強記録①

# atcoder復習
下記にatcoderで解いたB問題を記載します。
勉強の記録として残します。是非参考にしてください。
[解いた問題一覧](https://kenkoooo.com/atcoder/#/table/kenbo0224)

# 目次
[1. 問題①](#1-問題①)
[2. 問題②](#2-問題②)
[3. 問題③](#2-問題③)

# 1.問題①
[B - Playing Cards Validation](https://atcoder.jp/contests/abc277/tasks/abc277_b)（<font color="SpringGreen">Difficulty65</font>）
### 解答
```python
n = int(input())
n_lst = ['H', 'D', 'C', 'S']
n_lst_1 = ['A', '2', '3', '4', '5', '6', '7', '8', '9', 'T', 'J', 'Q', 'K']
n_lst_2 = [] # 入力したデータを格納する
flg = True
for _ in range(n):
    n_1 = input()
    n_lst_2.append(n_1)
    if not n_1[0] in n_lst:
        flg = False
    if not n_1[1] in n_lst_1:
        flg = False

def chk(seq):
    '''重複確認'''
    return len(seq) != len(set(seq))

if chk(n_lst_2):
    flg = False

if flg:
    print('Yes')
else:
    print('No')
```
### 解法
確認するデータを配列に格納しておく。
入力をされたら配列の中にデータがあるのかを確認し存在していたらflgをFalseにする。
そして最後のif文で出力する文字を判断する。

if文、for文、配列を使用出来れば解ける問題である。
重複確認では配列をset型にして重複を無くし元の配列と長さを確認している。
長さが違うのであれば重複があるのでflgをFalseにしている。
# 2.問題②
[B - レ](https://atcoder.jp/contests/abc289/tasks/abc289_b)（<font color="SpringGreen">Difficulty225</font>）
### 解答
```python
N, M = map(int, input().split())
n_list = list(map(int, input().split()))
ans_list = [] # 並び替えない配列
ans_list_1 = [] # 並び替えた配列
flg_list = [True] * N
cnt = 1

for j in n_list:
    flg_list[j - 1] = False # レ点の場所をチェックする。

for k in flg_list:
    ans_list.append(cnt)
    if k == True:
        ans_list_1 += reversed(ans_list)
        ans_list = []
    cnt += 1

if M == 0:
    for i in range(1, N+ 1):
        ans_list.append(i)
    print(*ans_list)
else:
    print(*ans_list_1)
```
### 解法
flg_listでレ点がある場所にチェックをしている。True→Falseにする。
flg_listをfor文で回しTrueが出現したら配列を逆順にして別の配列にセットする。
逆順にした配列は空にする。
この処理をflg_listの中身を全部確認するまで行う。
最後に配列の中身を表示する。
# 3.問題③
[B - Call the ID Number](https://atcoder.jp/contests/abc293/tasks/abc293_b)（<font color="SpringGreen">Difficulty65</font>）
### 解答
```python
K = int(input())
k_lst = list(map(int, input().split()))
flg_lst = [0] * K
cnt = 0
ans_lst = []
for i in range(1, K + 1):
    ans = k_lst[cnt]
    if flg_lst[i - 1] != 1:
        if not flg_lst[ans - 1] == 1:
            flg_lst[ans - 1] = 1
    cnt += 1
ans = flg_lst.count(0)
print(ans)
print(*[i + 1 for i, x in enumerate(flg_lst) if x == 0])
```
### 解法
flg_lstを用意して人が呼ばれた場合にチェックをする。
今回の場合は配列のデータが1になっている場合が呼ばれている。
解答として出力するのは0の個数(呼ばれていない人数)と呼ばれていない人の数
配列に格納されている0の位置を表示するには0がどこに出現しているのかをfor文で確認して表示する。
Splunk: ソースタイプ名のみを変更する

###### 実施環境： Splunk Free 8.2.2

 Splunk のソースタイプについて、変更が必要な場合を考えます。
このとき通常は設定を作り直すものですが、何らかの理由でおおもとの設定を直接編集せずに変更したい場合があるかもしれません。
そのようなときに使用するのが、今回紹介するソースタイプ名の変更機能( sourcetype renaming )です。

### 1. 概要

例えば、ソースタイプ名「 shopping 」を作成するところが、誤って「 shoping 」としてしまったとします。
通常はソースタイプの設定自体を作り直すことになりますが、何らかの理由ですぐに修正することが難しいかもしれません。
そのようなときに一時的にソースタイプ名のみを別名に変更するのが、ソースタイプ名の変更機能です。

### 2. 設定方法

「設定」⇒「フィールド」を選択します。

![WS000536.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1465018/7f58cb91-ab79-2b90-8249-44020e5fe17e.jpeg "設定")

「ソースタイプ名の変更」を選択します。

![WS000548.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1465018/337be50f-8903-d415-3e21-81d8893ff019.jpeg "フィールド")

ソースタイプ名の変更一覧画面が開くので、右上の「新しいソースタイプ名の変更」を選択します。

![WS000549.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1465018/96dec944-2ac7-57ff-bc27-930e72a448f6.jpeg "ソースタイプ名の変更一覧1")

ソースタイプ名の変更設定を入力します。

![WS000550.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1465018/2e6b1c09-f628-7289-52ac-76b606f666b6.jpeg "ソースタイプ名の変更作成")

ここでは以下の設定を入力します。

|項目名|値|
|:-|:-|
|宛先 App | search |
|元のソースタイプ名| `scheduler` |
|新しいソースタイプ名| `test_type` |

これでソースタイプ名の変更が作成できました。

![WS000551.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1465018/da185bd9-f50f-e3cd-dcfc-efa7ab5c2007.jpeg "ソースタイプ名の変更一覧2")

### 3. 使用方法

試しに、以下の SPL で確認してみましょう。

```Splunk:Splunk
index="_internal" sourcetype="test_type"
| stats count BY status
```

![WS000553.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1465018/83e98f09-12cb-eb14-3c99-4db6c7d95bd8.jpeg "SPL1")

変更後のソースタイプ名で検索できました。

ちなみに、変更前のソースタイプ名で検索する場合は`_sourcetype`を使用します。

```Splunk:Splunk
index="_internal" _sourcetype="scheduler"
| stats count BY status
```

![WS000552.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1465018/35352985-4d7f-fd83-4230-4dc9ccf6d8ca.jpeg "SPL2")
【初学者】M2macでSQL Serverの構築・DB作成

# はじめに
Windows環境で作成したWebアプリケーション、データベースをmac環境に落とし込んで使用したいため。
macではWindowsでいうSSMS(SQL Server Management System)がないため、DockerとAzure Data Studioを用いてDB作成、接続を行います。

# 実行環境
macbook Air(M2チップ搭載2022モデル)
Visual Stidio2022 for mac(無償版)
Docker Desktop
Azure Data Studio

# Docker Desktopのインストールと環境構築
まず、https://docs.docker.com/desktop/mac/install/　
よりmac用のDocker Desktopアプリをダウンロードします。
個人で使用する際は無料で利用できます。
インストール後のDockerの設定に関しては長くなってしまうので、
「参考文献」欄に私が環境構築で参考させていただいたサイトのリンクを貼っておきます。

![スクリーンショット 2023-03-19 0.00.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2734040/942a0d3e-8bba-73c6-47ef-93a8b850298c.png)
いきなりでわかりにくいですが”Status”欄が”Running”となっていたら
Docker上での環境構築は完了という認識で大丈夫です！

# Azure Data Studioのインストールと環境構築
Dockerでの作業が完了したら次はAzure Data Studioのインストールをしていきます。
https://docs.microsoft.com/ja-jp/sql/azure-data-studio/download-azure-data-studio?view=sql-server-ver15
こちらのURLからインストールができます。
ダウンロードの”Apple Sillicon”を選択してファイルをダウンロードしていただければ動作します。
![スクリーンショット 2023-03-19 10.27.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2734040/47764272-3b11-692f-984b-b9cca1bdc573.png)
Dockerで作成したSQL Serverの動作環境を接続（詳細は「参考文献」にリンクを貼っておきます）するとこのような画面になると思います。
VS Codeにそっくりなので、使い方に関してはすぐになれるかと思います！

![スクリーンショット 2023-03-19 10.52.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2734040/787e694f-09b8-c143-7963-b1e8b18afc12.png)
ここからSQL 文を書いて実行すれば無事にデータベースを作成できます。

# 終わりに
macでもDockerを使ってSQL Serverの実行環境を用意してあげればほとんどWindowsと同じようにデータベースを扱えることがわかったこと。
Apple siliconでも特に不自由なく開発環境が整えられたので良い経験となりました。
# 参考文献
[MacにSQL Serverの実行環境を構築する手順](https://blazor-master.com/mac-sql-server/)
[Docker Desktop](https://docs.docker.com/desktop/install/mac-install/)
[Azure Data Studio](https://learn.microsoft.com/ja-jp/sql/azure-data-studio/download-azure-data-studio?view=sql-server-ver15&tabs=redhat-install%2Credhat-uninstall)
【Excelマクロ】他のブックのセル値をブックを開かずに取得する

## 経緯
訳あって複数のExcelファイルから値を抽出して1ファイルにまとめるマクロを組むことになった。
「ブックを開いて値を取得する」を繰り返す処理だと時間が掛かるので、ブックを開かずに値を取得する方法が無いか調査した。

## 外部ブックから値を取得する関数
- 前提条件: マクロ内に空のシートを`vba_wk`という名前で作っておくこと

```vb
Function getOtherBookValue(ByVal dirPath As String, ByVal fileName As String, ByVal sheetName As String, ByVal cellAddress As String)
    
    Dim sheet As Worksheet
    Set sheet = Worksheets("vba_wk")
    
    '数式を使って、別ブックを参照
    sheet.Cells(1, 1) = "='" & dirPath & "\[" & fileName & "]" & sheetName & " '!" & cellAddress

    getOtherBookValue = sheet.Cells(1, 1).Value '数式を値に変換して返却
    sheet.Cells(1, 1).Delete '後片付け

End Function

```

## 使用例

```vb
Sub test()
    ' test.xlsx A2セルの値を現在開いているシートのA1セルに書き込む
    ActiveSheet.Range("A1").Value = getOtherBookValue("C:\test", "test.xlsx", "Sheet1", "A2")
End Sub
```

## 参考

https://daitaideit.com/vba-workbooks-reference/
jfr実行したら、空のjfrファイルができてしまう

Javaの性能情報取得のため、jfrのコマンドを実行しましたが以下のエラーが発生し、空の.jfrファイルができてしまった。

```
Commercial Features are unlocked.
Status of individual features:
  Java Flight Recorder is disabled.
  Resource Management is disabled.
```
性能情報取得しようとしているプロセスに対してjava flight recorderを有効化する必要がありました。
そのため、以下の手順を作成し、jfrを有効化して、有効なJFRファイルを作成できました！

①JFRの状態確認
$jcmd ｛pid｝ JFR.check

② ①がLOCKなら、解除するコマンドを実行
$jcmd ｛pid｝ VM.unlock_commercial_features

③JFRの状態確認
$jcmd ｛pid｝ JFR.check

<h2>JFRとは</h2>
Java Flight Recorder。
Java Flight Recorder (JFR)は、実行中のJavaアプリケーションに関する診断およびプロファイリングのデータを収集するツールです


<h2>JFR情報取得コマンド</h2>
```common-lisp
jcmd $pid JFR.start duration=$INTERVALs filename=$jfrfilename compress=true
```
PID：プロセスid、性能情報取得対象のプロセス<br>
duration：記録するの時間の長さ<br>
jfrfilename：記録するファイル
（PostgreSQL）シーケンスについて理解する

## シーケンスとは

[日本語版マニュアル](https://www.postgresql.jp/document/13/html/functions-sequence.html)には、
> シーケンスオブジェクト(シーケンス生成器とも単にシーケンスとも呼ばれます)とは CREATE SEQUENCE コマンドで作成される 1 行の特別なテーブルです。シーケンスオブジェクトは通常テーブルの行に一意の識別子を生成するために使用されます。

と書いてる。
めっちゃ簡単に説明すると

**シーケンス　＝　連番を生成するモノ**

という理解でOK。

主に主キーや一意のIDの生成など、連続した番号が必要な場面で使用される。

## 実際に使ってみる

```sql:シーケンスの作成
CREATE SEQUENCE example_table_id_seq   -- シーケンス名
    INCREMENT BY 1                     -- 増分値
    MINVALUE 1                         -- 最小値
    MAXVALUE 2147483647                -- 最大値
    START WITH 1                       -- 初期値
    CACHE 1;                           -- キャッシュ値
```

```sql:idにシーケンスを設定
CREATE TABLE example_table (
    -- nextval()を使ってシーケンスの次の値を取ってくる
    id INTEGER PRIMARY KEY DEFAULT nextval('example_table_id_seq'),
    name VARCHAR(255)
);
```

idにシーケンスを設定したので、試しにidの値を指定せずにインサートしてみる
```sql:idの値を指定せずにインサート
INSERT INTO example_table (name) VALUES
('denji'),
('power'),
('aki');
```

結果、idに連番が付与されている

| id | name |
|----|------|
| 1  | denji |
| 2  | power  |
| 3  | aki  |


## SERIAL型について
カラムのデータ型を **SERIAL** にすることで、前述のシーケンスの作成・設定を自動で行ってくれる。
```SQL:SERIAL型
CREATE TABLE example_table (
    id SERIAL PRIMARY KEY, -- SERIAL
    name VARCHAR(255)
);
```
内部で「テーブル名_カラム名_seq」という名前のシーケンスが自動で作成される。
例の場合、「example_table_id_seq」というシーケンスを生成。

また、SERIALを使った場合、シーケンスの設定は以下のとおり（前述の設定と同様）
```sql
CREATE SEQUENCE example_table_id_seq   -- シーケンス名
    INCREMENT BY 1                     -- 増分値
    MINVALUE 1                         -- 最小値
    MAXVALUE 2147483647                -- 最大値
    START WITH 1                       -- 初期値
    CACHE 1;                           -- キャッシュ値
```
なお、データ型がINTEGERとBIGINTの場合で、MAXVALUEの値が変わる
INTEGER :2147483647
BIGINT  :9223372036854775807

## シーケンスに権限を付与する
勝手にシーケンスの値が変更されることのないよう、権限を付与するのがセキュリティ上重要。


```SQL:権限の付与、取消
-- 付与
GRANT USAGE ON SEQUENCE example_sequence TO example_user;

-- 取消
REVOKE USAGE ON SEQUENCE example_sequence FROM example_user;
```

- USAGE :シーケンスの値を取得できるが、変更はできない
- UPDATE: シーケンスの値を変更できる
【AWS】API Gateway→Lambda→AppSync→DynamoDBを実装したい ~ Amplifyを添えて ~ Part1

こんにちは。
掲題の件のフローを実装したく、頑張りました。（唐突）

# なぜ上記を実装したかったか
- サーバレスで安くアプリケーションを構築したかったから
- DynamoDBへのアクセスはAppSyncを利用してなるべく簡単にしたかったから
- Amplifyを利用してスピーディに実装したかったから

# アプリの全体像
以下のようになります。
![スライド2.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/239102/26b150da-1ebc-d89a-781c-0781041b5eed.jpeg)

# なんでAPI GatewayとLambdaがいるの？クライアントからAppSyncたたけばいいじゃない？
1. Lambdaが便利だから
1. 複数のアプリから簡単に同じDynamoDBにアクセスしたかったから

1つ目の理由について、クライアントからAppSyncにリクエストする設計だと、DynamoDBとのやり取り以外の処理（Cognitoへのユーザー登録、メール送信などなど）をしたい場合に別個に実装しないとならず手間になってしまうので、柔軟に処理をできるようにしました。

2つ目の理由について、「アプリの全体像」で記載しているように管理者と利用者でアプリを分ける必要がありました。
元々はそれぞれのアプリでAppSyncを利用することを考えていましたが、そうするとアプリごとにDynamoBDのテーブルができてしまい、同じデータにアクセスできない事象が発生しました。
[こちらの記事](https://qiita.com/pikanji/items/352146dc6bec1c88e159#%E8%A7%A3%E6%B1%BA%E3%81%97%E3%81%A6%E3%81%84%E3%81%AA%E3%81%84%E8%AA%B2%E9%A1%8C)にあるようにResolverの追加などで同じDynamoDBにアクセス可能ではありますが、今後も修正が発生する可能性が高く、手を入れやすいように構築したいと考え、このようになりました。

# 実装してみた
次回以降の記事にて、Amplify cliのコマンド等実行してデモ的に構築してみたいと思います。

Part2 フロントエンド + API Gateway + Lambda
Part3 AppSync + DynamoDB
Part4 上記1と2の繋ぎこみ
AWS Certified DevOps Engineer - Professional(DOP)の駆け込み受験

初めまして。Rosetta103です。 自身の勉強/情報キャッチアップの一環としてアカウントを開設しました。
AWS一筋でSE歴もうすぐ7年目に突入します。
よろしくお願いいたします。 

さて、タイトルの通りAWS Certified DevOps Engineer - Professionalの合格体験記になります。 
バージョンが002に更新される前にぎりぎり受験しました。。

![DOP結果①.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3287098/8305efd1-7593-4b7e-3f6a-3f0c4c766732.png)
![DOP結果②png.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3287098/8ff33501-2f7f-07ad-1506-3047815538b7.png)


　　準備期間：3週間ほど。勉強時間に直すとおそらく20~30時間くらい。
　　勉強方法：①問題を解く
　　　　　　　②解説を見る
　　　　　　　③分からなかったらドキュメントを見る
　　　　　　　④それでも分からなかったらAWSコンソールに入って設定をシミュレーションしてみる
のヘビーローテーション。

　参考資料
　techstockhttps://techstock.jp/
　・いつもの。自分は暗記するというよりは
　　どこら辺がテストに出るかを確かめる感覚で使用しています。
　各種AWSサービスのドキュメント
　・問題解いていて分からなければドキュメントを見て、何が問われていて何故正解なのか確認します。
　　また、何問か解いているうちにどのあたりを問われるか感覚で分かってくるので
　　気になったら関連ありそうな周辺の項目も読んでみました。
　　
　後は上記で分からなければ自身のAWSコンソールでできるものは
　設定/設定するフリをし、そのサービスをなんとなく体感します。
　どんな形であれなんとなく体感しておくだけでも結構違うと思っています。
　
　　・・・だけです。他の記事がどうかはわかりませんが自身はこれだけ。
　　　　　問題の感覚がつかめるものプラス公式のドキュメントがあればなんとかなると思っています。

　
　勉強したサービス等
　
　・OpsWorks
　・ElasticBeansTalk
　・Code系(CodeCommit,CodeBuild,CodeDeploy,CodePipeline)
　・CloudFormation
　　→それぞれのサービスの役割、デプロイ方式、自動化するにはどういう風にしたらよいか、など
　　　後はそもそものGitの知識があると楽
　
　・Route53
　・各種ELB
　・AutoScaling
　　→上記に連動してデプロイ手段の中に組み込まれていることが多い
　　
　・Lambda
　　→大体はSNSと連携して何かしてくれるもの

　・CloudWatch、CloudTrail、Config
　　→監視系。ほかのAWS資格を持っているならばその内容を思い出し、
　　　DOPの問題に当てはめればよい
　　
　・TrustedAdvisor
　　→なぜかちょくちょく出てくる(本番も1問でた)
　　　リソースをあまり使ってない状況をどうにかしたいときに。
　　　
　・ServiceCatalog
　・SSM
　・DB系(RDS、DynamoDB)
　・S3
　・IAM
　　→その他試験(SAP等)で出てくるものがそのまま出る感じ。
　　　DOPを優先してとる場合はここら辺も改めて勉強は必要

資格のバージョンが変わっても似たような勉強方法で取り直せると信じております。。
　　　
以上です。ご覧いただきありがとうございます。
今後も試験に付随する勉強だったり
個人の勉強で思うことがあれば随時発信できればと思います！
自チームでクラウドを対応することになったリーダー/管理職へ（はじめに）

# はじめに
これは、自分のチームでクラウドを対応することになった自身の経験をもとにしています。
最終的にクラウドアーキテクトチームを組織するまでの試行錯誤を共有できればと思います
自分のチーム/組織でクラウドを対応することになったリーダー、管理職の方々への参考に！
なお、本投稿ではIaaSクラウドを基本とし、AWSを前提にしています。

# クラウドを対応することになったリーダー/管理職へ
**マネジメント側の情報は意外に少ない**
技術習得のための書籍や学習サイトは沢山ありますが、チームや組織を管理するリーダーや管理職向けのクラウド情報は多くはないと思います。ただ、これはクラウドに限らず他の技術領域でも同様ですね。正解のない管理業務の辛いところではないです。
一方、これまでのサーバやネットワーク技術・開発手法については、これまでの積み重ねがあるため既にやり方が整備されていたり、管理手法踏襲できたりするのも事実ではないかと思います。歴史を刻み始めたとはいえ、クラウドについてはこれから始めるという組織もまだあるのではないでしょうか。

# 準備を進めよう
管理職としてクラウド対応を行うことになった私自身を振り返っての準備ToDoです。

## 対象クラウドを決める
チーム/組織で対応するクラウドサービスが指定される場合は当然それに従います。
もし定められたものがなく、クラウドをやる、ということならば、まずはどのクラウドに対応するのか決めます。
AWS、Azure、Google…とりあえず有名どころをいくつか手を出してみる、というのは**絶対にお勧めしません！**
どのクラウドでも選択できる状態なのであれば、**まずはAWSから始める**ことをお勧めします。
なぜあれもこれも手を出さないこと、なぜAWSから始めるのかは別の回で説明したいと思います。
私自身の反省からも…

:::note info
最初からいろいろ手を出さない、どれでもよいならまずはAWS
:::

## 時間の確保
クラウドは簡単に扱えますが、理解するのは本当に難しい…
「仕事で求められる品質」でクラウドを扱うためのノウハウが意外と組織の内外に少ないことに気が付くのではないかと思います。
（そのため、皆さんがクラウドを対応することになったのだと思いますが）
クラウドの技術習得には学習時間の確保が必要です。最初は一か月あたりの勤務時間の30%以上の時間を学習に割く必要があると思います。

:::note info
最初は学習時間を確保する
:::

## 金の確保
クラウド学習にかかる時間は、ほとんどの組織にとってコストに直結するはず。
また、実際にクラウドを使って学習することが重要ですが、そのクラウド環境のコストも必要になります。
クラウドのメリットはオートスケールや従量課金であると様々な場面で語られます。しかし、オートスケール＝コストもオートスケールしメンバーが使っただけ請求が回ってくるクラウドは、予算確保を行うリーダー/管理職にはそのメリットは一味違った見え方がするのではないでしょうか…

なお、AWSでは無料利用枠が用意されています。これを**計画的かつ効率的に活用**することをお勧めします。

https://aws.amazon.com/jp/free/?all-free-tier.sort-by=item.additionalFields.SortRank&all-free-tier.sort-order=asc&awsf.Free%20Tier%20Types=*all&awsf.Free%20Tier%20Categories=*all

## スケジュールを立てる
チーム/組織である以上、活動スケジュールを決めると思います。
その際、クラウド関連のイベントや勉強会、セミナーのスケジュールの取り込みはメンバーの育成やモチベーションの面で効果的です。

AWSでもイベントスケジュールが公開されていますので、是非参考にしてみてください。

https://aws.amazon.com/jp/events/?events-japan-cards-feature.sort-by=item.additionalFields.sortDateTime&events-japan-cards-feature.sort-order=asc&events-japan-cards.sort-by=item.additionalFields.sortDateTime&events-japan-cards.sort-order=asc&awsf.event-type=*all&awsf.event-category=*all&events-japan-cards2.sort-by=item.additionalFields.sortDateTime&events-japan-cards2.sort-order=asc

大規模イベントとして、日本国内ではAWS Summit Tokyo
（下記はAWS Summit Tokyo2023）

https://aws.amazon.com/jp/summits/tokyo/

また、費用面やスケジュール面の入念な調整は必要になるものの、AWS re:Inventなどは**学習だけでなくモチベーションの面からも参加を考えたいイベント**です。（下記はAWS re:invent2022）

https://reinvent.awsevents.com/

# 最後に
クラウドの技術情報はQiitaをはじめネット上にとても高品質な情報が揃っています。一方で、マネジメント側の情報が少ないと思っていました。自分の経験を踏まえたクラウドを対応することになったリーダー/管理職に向けた投稿をしてみようと思いました。
これから、今回投稿した内容を少し具体化した内容で投稿をしていきたいと思います。
ChatGPTへの問い合わせと回答のスクショをWebで公開して良いのか

そういうことは、当人に聞いちゃった方が早いので、聞いてみた。
2023/03/18時点の記録、ということで。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/728994/9b66b100-edc5-735d-ed52-760952708498.png)

問題なし、というこで、安心して記事が書けます。
よかったよかった。
（PostgreSQL）JOINのLEFT・RIGHT・INNERの結果早見表

## サンプル
tableA
| id | name  |
|----|-------|
| 1  | Alice |
| 2  | Bob   |
| 3  | Carol |

tableB
| id | city    |
|----|---------|
| 1  | Tokyo   |
| 2  | New York|
| 4  | London  |

# JOIN していく
各テーブルのid同士でJOINしてみる

## INNER JOIN
```sql:INNER JOIN
SELECT * FROM tableA INNER JOIN tableB ON tableA.id = tableB.id;
```

結果
| tableA.id | name  | tableB.id | city    |
|-----------|-------|-----------|---------|
| 1         | Alice | 1         | Tokyo   |
| 2         | Bob   | 2         | New York|

重複するIDのレコードのみセレクトされる


## LEFT JOIN
```sql:LEFT JOIN
SELECT * FROM tableA LEFT JOIN tableB ON tableA.id = tableB.id;
```
結果
| tableA.id | name  | tableB.id | city    |
|-----------|-------|-----------|---------|
| 1         | Alice | 1         | Tokyo   |
| 2         | Bob   | 2         | New York|
| 3         | Carol | NULL      | NULL    |

ONの条件式で左側のテーブルのレコードは全てセレクトされる
右側のテーブルに該当のIDがなければNULLになる


## RIGHT JOIN
```sql:RIGHT JOIN
SELECT * FROM tableA RIGHT JOIN tableB ON tableA.id = tableB.id;
```
結果
| tableA.id | name  | tableB.id | city    |
|-----------|-------|-----------|---------|
| 1         | Alice | 1         | Tokyo   |
| 2         | Bob   | 2         | New York|
| NULL      | NULL  | 4         | London  |

LEFTの逆
Panda3Dでの３Dゲーム開発の始め方

# Panda3Dとは
[Panda3D](https://www.panda3d.org/)とは、Pythonで3Dゲーム開発をする為のライブラリ。
日本語の公式チュートリアルが無く、Qiitaや他のサイト上にもあまり情報が見つからない。日本国内での利用者は少なめなのかも？
元々はディズニーのVRアトラクションを作る為のエンジンで、その後オープンソース化されたらしいです。
Pythonの勉強をしつつ、3Dゲームの開発をしてみたいという私みたいな人には丁度良いライブラリかも、という事で学びながら何かゲームを作っていこうと思います。
（基本はPC用の開発。[Android用には公式でビルド可能](https://docs.panda3d.org/1.11/cpp/distribution/building-for-android)なようだけど、iOSにはまだ未対応？）

# インストール
* Pyhonのインストール
[Download Python | Python.org](https://www.python.org/downloads/)
（記事投稿時のリリースverは3.11.2）

* Panda3Dのインストール
```pip3 install panda3d```
（記事投稿時のリリースverは1.10.13）

* エディタのインストール
各自使い慣れてるエディタでコードを書いていってください。
今回は[Visual Studio Code](https://azure.microsoft.com/ja-jp/products/visual-studio-code)にPython関連の拡張機能を入れて使用しています。

# サンプルコード
```python:sample.py
# Panda3Dライブラリのインポート
from direct.showbase.ShowBase import ShowBase
from panda3d.core import *

# 3D描画ウィンドウの内容
class App(ShowBase):
    # コンストラクタ
    def __init__(self):
        # 3D描画ウィンドウの初期化
        ShowBase.__init__(self)

        # デフォルトで準備されてるキューブモデルを読み込み
        self.cube = self.loader.loadModel('models/misc/rgbCube')
        # キューブのサイズ設定
        self.cube.setScale(2, 2, 2)
        # キューブの回転
        self.cube.setQuat(Quat(0, 1, 1, 1))
        # キューブの位置調整
        # (y軸に+値を設定しないと、カメラ位置がモデルの中心かモデルより前になってしまって何も表示されないので注意)
        self.cube.setPos(0, 20, 0)
        # キューブの描画
        self.cube.reparentTo(self.render)

# 3D描画ウィンドウの表示
app = App()
app.run()
```

# 実行
```py sample.py```
![01_sample.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/703546/34364ce6-b2d4-c073-904f-c5f555fa3f86.png)
画面に色分けされたキューブが表示されました。

* マウスでのカメラ操作方法
画面上でマウスを左クリックしながらドラッグ = 視点の平行移動
画面上でマウスを右クリックしながらドラッグ = 視点の前後移動
画面上でマウスを中央クリックしながらドラッグ = 視点の回転
（デフォルトだと並行移動の感度が高すぎてすぐにキューブが行方不明になります）

# 参考
[Pythonでマイクラを作る　①Panda3Dの基礎｜creativival｜note](https://note.com/creativival/n/n61ce6391664d)
Googleデジタルマーケティング＆Eコマース：有料ソーシャルメディア予算のコンポーネント

# はじめに

”Googleデジタルマーケティング＆Eコマース プロフェッショナル認定証"　の受講が完了しました(2022/3/3)。私がこのコースから得られた素晴らしい体験を、テーマごとに分割して、わかりやすくご紹介しています。興味を持たれた方は、是非下記を受講してみてください。

https://jp.coursera.org/professional-certificates/google-digital-marketing-ecommerce

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/24ea32fb-2fb3-bdb2-462a-4ffc4d60a96f.png" width="800">

# 有料ソーシャルメディアの予算

ソーシャルメディア広告の予算は、企業によって異なります。しかし、一般的に、企業のソーシャル広告予算は、年間収益によって決定されます。ガートナー社の調査によると、

- 企業は平均して年間収益の約10〜13％をマーケティングに費やしています。
- その予算の約25%が検索やソーシャルメディアなどの有料メディアに費やされています。

そして、過去の投資収益率によって、ソーシャルメディアへの投資を多くしたり少なくしたりすることができます。

# 有料ソーシャルメディア予算のコンポーネント

一般的に、ソーシャルメディアの有料予算には何が含まれるかについて説明します。

### <font color="MediumBlue">広告費</font>

広告費は、あなたの会社が広告に直接費やす金額です。Twitter、Facebook、Instagram、LinkedInなどのソーシャルメディア・プラットフォームに支払って広告を提供する金額です。また、インフルエンサーに支払い、コンテンツを宣伝してもらう金額も含まれます。

しかし、広告費は、有料ソーシャルメディア予算全体の一部にしか過ぎません。

### <font color="MediumBlue">ツール</font>

ソーシャルメディア広告キャンペーンを立ち上げ、管理し、最適化するために必要なツールやテクノロジーに関連する費用も必要です。

あなたが投資するかもしれないツールは、

- ソーシャルメディア管理ソフトウェア
- ソーシャルリスニングと分析ソフトウェア
- 写真やビデオの編集プログラム
- ストックフォトやビデオの購読
- インフルエンサーマーケティングプラットフォーム

が含まれています。

インフルエンサーマーケティング・プラットフォームとは、潜在的なインフルエンサーの大規模な検索可能なデータベースなど、インフルエンサー発見ツールを提供するソフトウェアです。有料のツールに投資する前に、無料のツールで試してみるのが有効です。ツールにお金をかける予定がない場合でも、予期せぬ費用に備えて予算の一部を確保しておくとよいでしょう。

### <font color="MediumBlue">コンテンツ制作費</font>

自社のソーシャルメディアの有料費用を考える場合、コンテンツをどのように作成するかについても考える必要があります。

コンテンツ制作の一部を社内で行っている場合でも、

- 写真撮影
- グラフィックデザイン
- ビデオ制作（タレントや制作費を含む）
- コピーライティング

などの費用が必要になる場合があります。

### <font color="MediumBlue">管理費</font>

管理業務には、

- 戦略
- コンテンツの企画と公開
- ソーシャルリスニング
- エンゲージメント
- 分析とレポート

などが含まれます。

場合によっては、デジタル・マーケティング・エージェンシーと提携し、これらの業務を管理することも可能です。これらのタスクの多くが社内のチームによって完了されている場合でも、ソーシャル広告予算に適用される関連コストが存在する可能性があることに留意してください。
ChatGPTの回答をPdfで簡単に出力する方法

# ChatGPTの回答が複数ページにわたって、スクリーンショットでは保存が面倒なので良い方法がないかChatGPTに聞いてみた結果。

1. SafariまたはChromeを開き、ChatGPTの回答が表示されているページにアクセスします。
2. Ctrl+P（Macの場合はCmd+P）を押して、「印刷」ダイアログボックスを開きます。
3. 「プリンター」または「宛先」のドロップダウンメニューから、「Save as PDF」、「PDFとして保存」、または「Microsoft Print to PDF」のいずれかを選択します。
4. 必要に応じて、保存先フォルダやファイル名を指定し、「保存」をクリックします。

## 元画像
![PDFで回答を保存する方法のコピー.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/590859/e26d9972-8cb8-40e1-8979-b0bf5a7c4898.jpeg)
Googleデジタルマーケティング＆Eコマース：効果的なコール・トゥ・アクション（CTA）

# はじめに

”Googleデジタルマーケティング＆Eコマース プロフェッショナル認定証"　の受講が完了しました(2022/3/3)。私がこのコースから得られた素晴らしい体験を、テーマごとに分割して、わかりやすくご紹介しています。興味を持たれた方は、是非下記を受講してみてください。

https://jp.coursera.org/professional-certificates/google-digital-marketing-ecommerce

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/24ea32fb-2fb3-bdb2-462a-4ffc4d60a96f.png" width="800">

# コール・トゥ・アクション（CTA)とは

***<font color="MediumVioletRed">『お客様に次に何をすべきかを伝える指示のこと』</font>***

コール・トゥ・アクションは、あらゆる種類のマーケティングで見られ、顧客に望む行動を取らせるための非常に説得力のある効果的な戦略となります。一般的に、CTAは

- ボタン
- クリックできる画像
- リンク

で、ユーザーにクリックするよう指示します。

# コール・トゥ・アクション（を書く

CTAを書くときに考慮すべき最初の、そして最も重要なことは、あなたの　***<font color="MediumBlue">ブランドの目標</font>***　です。各ソーシャルメディアの投稿で何を達成したいのか、そしてCTAはそこに到達するためにどのように役立つのでしょうか？

- 例えば、あなたのゴールがより多くのWebサイトのトラフィックを生成することである場合、多分あなたは人々があなたのホームページにそれらを送信するために投稿したリンクをクリックすることを望みます。

その場合、クリックさせる理由を明確にする必要があります。なぜ彼らはクリックする必要があります、自分自身に問います。彼らはそれから何を得るのだろうか？

### <font color="MediumBlue">明確にする</font>

CTAをクリックするとどのようなメリットがあるのかをユーザーに明確に理解してもらうためには、行動喚起の内容を明確にすることが重要です。だからといって、熱意や気の利いた言葉やアニメーションのような表現をしてはいけないというわけではありません（もちろん、それも必要ですが）。

### <font color="MediumBlue">動詞を使う</font>

CTAを使用する目的は、ユーザーに何らかの行動を起こしてもらうことです。ユーザーが何かをするように指示されていることが分かるように、明確で直接的な表現を心がけましょう。サインアップ、訪問、クリック、ダウンロード、ショッピング、フォローなどのアクションワード（動詞）は、ユーザーに取って欲しい行動を伝える効果的な方法です。

### <font color="MediumBlue">緊急性を持たせる</font>

ユーザーに「今すぐ行動しなければならない」と思わせるためには、緊急性を持たせることが効果的です。しかし、見返りに何かを提供する場合、その取引は永遠に続くとは限りません。「本日限り」のような言葉を使うことで、そのオファーに有効期限があることを伝え、行動を促すことができるのです。

### <font color="MediumBlue">ブランド・ボイスを使う</font>

キャプションやコピーで選んだ語調は、CTAにも反映させる必要があります。ブランド・ボイスは、全てのマーケティングチャネルで一貫している必要があります。あなたのブランドは、
- 温かみがあって魅力的ですか？
- クールで簡潔ですか？
- カジュアルですか？

CTAもそのように感じてもらえるようにしましょう。
Googleデジタルマーケティング＆Eコマース：ソーシャルメディアにおけるリマーケティング

# はじめに

”Googleデジタルマーケティング＆Eコマース プロフェッショナル認定証"　の受講が完了しました(2022/3/3)。私がこのコースから得られた素晴らしい体験を、テーマごとに分割して、わかりやすくご紹介しています。興味を持たれた方は、是非下記を受講してみてください。

https://jp.coursera.org/professional-certificates/google-digital-marketing-ecommerce

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/24ea32fb-2fb3-bdb2-462a-4ffc4d60a96f.png" width="800">

# リマーケティングとは

ある企業のWebサイトを訪れ、製品を見たものの、購入せずに立ち去ったときのことを思い出してみてください。もしかしたら、まだ購入するかどうか検討していたかもしれないし、他のことに気を取られていたかもしれません。そして、しばらくして、同じ商品の広告をあなたのソーシャルメディアプロフィールの1つで見かけました。これがリマーケティングの実践です。

リマーケティングは、Webサイト、アプリ、またはソーシャルメディアのプロフィールにアクセスしたことのある顧客をターゲットに有料広告を表示します。

# リマーケティングのメリット

- 潜在的なリードや顧客にリーチするための新たな機会を提供します。広告を目にする回数を増やすことで、顧客が購入の選択肢を検討する際に、貴社のブランドが目に留まるようにすることができます。
- 企業のマーケティングのパーソナライズにも役立ちます。リマーケティングは、無作為のユーザーに広告を表示するのではなく、過去に訪問したことのあるユーザーをターゲットにして、パーソナライズされた体験を提供します。これにより、より多くのコンバージョンにつなげることができるのです。

# リマーケティングの仕組み

リマーケティングは、

- 検索連動型広告
- ディスプレイ広告
- メール
- ソーシャルメディア

など、さまざまなデジタルマーケティング・チャネルで利用することができます。

リマーケティングには、大きく分けて

- ピクセルベース
- リストベース

の2種類があります。

### <font color="MediumBlue">ピクセル型リマーケティング</font>

ピクセル型リマーケティングは、ユーザーが閲覧したページや製品を追跡するCookieをWebブラウザに設置した後、自動的に広告を送信します。Cookieとは、デバイスに保存される小さなファイルで、ユーザーの行動を追跡し、トラフィックを分析することができます。

ユーザーがあなたのWebサイトを離れ、ソーシャルメディアのプロフィールや他のWebサイトを閲覧すると、Google AdsやFacebook Ad Managerなどの広告ネットワークに通知され、そのユーザーが以前に見た内容に基づいて特定の広告を表示することができます。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/dec8edd6-20ee-6359-79d8-f5fbdb7f7a78.png" width="600">

### <font color="MediumBlue">リスト型リマーケティング</font>

潜在顧客のメールアドレスをお持ちの場合は、リスト型リマーケティングを使用して、送信する広告をパーソナライズすることができます。

リスト型リマーケティングは、メールアドレスを提供した既存の顧客や訪問者のリストを使用し、その顧客に対して特定の広告を表示します。収集したユーザーデータは、ユーザーのプライバシーを保護するために慎重に取り扱う必要があります。

GoogleやFacebookなどのプラットフォームは、この目的のためにデータをアップロードする際、すべてのデータをハッシュ化します。ハッシュ化とは、メールリストに含まれる個人情報をランダムなコードに変えるセキュリティ手法のことです。

リスト型リマーケティングを開始するには、あなたのメール連絡先のリストを選択したプラットフォームにアップロードします。その後、あなたの顧客はそのプラットフォームをブラウズする際にあなたの広告を見るようになります。

# リマーケティングのベストプラクティス

### <font color="Darkcyan">特定の視聴者に基づいて広告をパーソナライズする</font>

以前あなたのプロフィールを訪問した全てのユーザーに広告を表示するのではなく、オーディエンスを興味ベースのグループにセグメント化します。これにより、各グループに特にアピールする広告をパーソナライズすることができます。

これを行うには、Twitterのこの例のように、選択したプラットフォームでカスタムオーディエンスを作成します。カスタムオーディエンスは、既存の顧客やフォロワーの独自のメールリストをアップロードすることで、高度に特定されたグループに到達するための関連性の高いリマーケティングキャンペーンを作成することが可能になります。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/237696f3-1f9a-d614-a9f7-b75dad7a7971.png" width="450">


### <font color="Darkcyan">過去に購入したことがある人にリマーケティングする</font>

米国のオンラインショップの売上全体の約半分は、リピーターによるものです。例えば、以前あなたの会社でおもちゃを購入した人がいれば、その人にリマーケティングを行い、子供向け商品の追加オファーを提供することができます。

### <font color="Darkcyan">特定のユーザーが広告を目にする頻度を制限する</font>

これにより、見込み客に負担を感じさせないようにすることができます。

### <font color="Darkcyan">購入に至った訪問者のタグを解除する</font>

これにより、コンバージョン後に広告を見過ぎないようにすることができます。


:::note info
ソーシャルメディアにおけるリマーケティングは、キャンペーンの広告資金を有効に活用することができます。貴社の組織、オーディエンス、マーケティング目標に合わせれば、リマーケティングはリーチを広げ、コンバージョン率を高めることができます。
:::
DockerでRails環境を構築した際に「Cannot find ''before_action"」となる

Railsを触ってみようとDockerで環境構築し、RubyMineでプロジェクトを開いたところ「before_action」などのRailsメソッドが補完できなかった。

ブラウザではアプリが普通に閲覧できていたので、RailsメソッドがIDEAで参照で来ていなかったよう。

通常であれば「External Libraries」でメソッドが参照できる
※自分の場合はここにactionpackが設置されていなかった

![スクリーンショット 2023-03-19 6.07.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2761705/06990f00-1ab4-acfe-f9ad-6b3ab5ddbf06.png)

## 解決法
「Tools」 → 「Bundler」 →　「Install」 で 「bundler install」と記載してRunするだけ

![スクリーンショット 2023-03-19 6.05.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2761705/056efbfb-b3a4-d056-df5a-a77d30dff1a6.png)
競技プログラミング日記#4

計算量/工夫 (1) - for 文のループを減らす(js)

・4.解けたが少し思考したので秒で解法が思い浮かぶように復習する必要あり
(N2乗個の積の総和) = (N個の数値の和「S」) * (N個の数値の和「S」)
というのに気付けるかどうか

入力を受け取る/複数の入力を受け取る(C#)5~7

・特にないがLINQを使うように意識する
[Rails] ルートの優先順位について

自戒。

# 状況
`devise`というGemを用いてユーザ登録機能を実装していた。
こいつはサインイン・サインアップまわりの一通りの機能を提供してくれる優れもので、当然そのためのビューも必要になる。

そこで、`config/routes.rb`の記述を以下の通りとした。
```rb
Rails.application.routes.draw do
  root to: 'homes#top'
  resources :users, only: [:index, :show, :edit]
  devise_for :users
end
```

`devise_for`というのも`devise`が提供するメソッドで、`users`に必要なルーティングを自動生成してくれる。
この場合でいえば、`users/sign_in`でサインイン、`users/sign_up`が新規登録画面でアクセスするわけだ。

...のはずだった。

# 問題
実際にアプリを起動し、`users/sign_in`にアクセスしてみる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2883146/52c84695-37c7-4d6c-caa8-89ad558df84c.png)

あれ...
**ここ、`users/show` やないかい...**

## 原因
これには`routes.rb`の仕様が絡んでくる。

実は`routes.rb`内に書かれたルートは**上から参照される**。
これを踏まえて、もう一度記述を確認する。

```rb
Rails.application.routes.draw do
  root to: 'homes#top'
  resources :users, only: [:index, :show, :edit]
  devise_for :users
end
```

二行目はルートパスの記述なので関係ないとして。
三行目、**`users`に`index, show, edit`の三つのアクションを設定している**のが確認できる。

ここで`show`のリンク形式を確認してみよう。

```
 user GET    /users/:id(.:format)
```

...そう、原因はここにある。
**`users/sign_in`の`sign_in`が`:id`だと誤認されることで`show`に渡されている**ことが元凶だった。

# 解決
改善は簡単。
ルートファイルの記述順序を変えてあげるだけ。

```diff_ruby
Rails.application.routes.draw do
  root to: 'homes#top'
- resources :users, only: [:index, :show, :edit]
- devise_for :users
+ devise_for :users
+ resources :users, only: [:index, :show, :edit]
end
```

# まとめ
Rails、お手軽にWebが組めてたのしい。
[Excel] エクセルで自分だけの関数を作成する方法 LAMBDA関数

# はじめに
仕事で利用できそうなエクセルの関数を探していた最中、目に見えたのはこのLAMBDA関数、説明ではカスタムで関数が組めるとのこと。
会社で自分以外の人も利用するフォーマットでVBAを作成することは後のことを考えるとよろしくない(周りが全員工学部出身なのでなんとかできそうだが)ため、エクセルのみで関数を作成できることはとても良いことであると考えた。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821152/b0221398-e002-9497-7d8c-883965bc89cf.png)

# 環境
Microsoft Excel 365

# 方法

## 一般的な税率計算
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821152/147b9034-fa33-39bb-89de-57e7e6674eb8.png)

## 関数登録
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821152/78309909-32f8-3b1a-3d66-2ec151a55bea.png)



![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821152/2063a1fa-3b12-ce35-7d61-bca48e0117ce.png)


## LAMBDA関数利用
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821152/74a9e468-2775-3200-6832-f90e31a1a0dd.png)

これで元々存在していた関数のごとく、利用することができる。

## その他の応用

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821152/8b621b52-0f39-3f2f-87ce-86e3415723b8.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821152/54a37a0e-055a-58fc-7855-11626780368c.png)



このように長くなりがちな数式を決めておくことによって適切な用途で数式を活用することができる。
沈思黙考：状態遷移データから状態遷移表と状態遷移図(PlantUML)を生成する(その１)

## 初めに

状態遷移図を作成することで、システムやプログラムの振る舞いを視覚的に表現することができる。
状態遷移表を作成することで、システムやプログラムの設計やテストにおいて、状態遷移の漏れや抜けを防ぐことができる。
状態遷移図と状態遷移表は、補完関係にあり、どちらか一方では不十分である。
ここでは、状態遷移表の元となるデータをCSVで作成して、状態遷移表と状態遷移図(PlantUML)を自動生成する方法を提示する。
さらに、Nスイッチカバレッジの抽出も行い、効率的なテストの手順を提示する。

## 状態遷移表の元となるデータ

状態遷移とは、ある状態(s1)においてイベント(ev)が発生すると次の状態(s2)に遷移することを指す。
つまり、状態遷移は、2つの状態と１つのイベントで表現することができる。
そこで、
```
事前状態(s1)、事後状態(s2)、イベント(ev)
```
の形式でデータを作れば、状態遷移表と状態遷移図を生成できるはずである。
PlantUMLの書式は、
```
state s1
state s2
s1 --> s2 : ev
```
であるので、簡単に変換できそうだ。

データフォーマットは、上記で示したs1,s2,evに、矢印の色などの属性を表現するためのattrという項目を加えて、下記のようにする。
attrはオプションとする。
区切り文字はここでは「|」としたが、お好みでよい。

```csv:フォーマット
s1|s2|ev|attr
```

具体的な遷移のデータのサンプルを用意しよう。
いわゆるstop watchの動作の状態遷移を考える。
stop watchにはスタートボタンがあり、初期状態は「準備中」で、スタートボタンを押すと
計測中になり、再度スタートボタンを押すと停止中になるものとしよう。
これを状態遷移で表現すると以下のようになる。
もちろんこれで完成ではない。
これから状態遷移図や状態遷移表を作ることで、抜けをあぶりだして、順次完成させていく。

```csv:stopWatch.state.txt
準備中|計測中|スタートボタン|[#blue]
計測中|停止中|スタートボタン|[#blue]
停止中|計測中|スタートボタン|[#blue]
```

## 状態遷移図(PlantUML)を生成するプログラム(awk)

ここではawkを使って変換プログラムを作る。
エラーが出ないように、自前でaliasの値を定めることにする。
関数getStateAlias()では、与えられた状態に対しaliasを発行する。
既出であれば、定義済みのalias値を戻すだけ。
初出であればstate文を出力して、発行したalias値を返す。
「[*]」は、開始および終了を示すもので、PlantUmlで事前に定義されているので、aliasは発行しない。
alias発行しないものがほかにもあればstateAliasMapに定義を加えておく。([H]とか)

```awk:stateCsv2pu.awk
function printUml(s1,s2,ev,attr) {
    alias1=getStateAlias(s1);
    alias2=getStateAlias(s2);
    print(alias1" -"attr"-> "join(" : ",alias2,ev));
}
function join(sep,str1,str2) {
	if(str1=="") {
		return str2;
	}
	if(str2=="") {
		return str1;
	}
	return str1""sep""str2;
}
function getStateAlias(state     ,alias) {
    if(stateAliasMap[state]=="") {
        # 初出の時に、aliasを作成し、state文を出力する
        alias = "A"(sprintf("%03d",stateAliasNumber++));
        stateAliasMap[state]=alias;
        print("state \""state"\" as "alias);
    }
    return stateAliasMap[state];
}
BEGIN{
    print("@startuml");
    print("hide empty description");
    stateAliasMap["[*]"]="[*]";
    stateAliasNumber=1;
}
NF>1{
    printUml($1,$2,$3,$4);
}
END{
    print("@enduml");
}
```

## 変換してみる

```bash:bash
awk -F\| -f stateCsv2pu.awk stopWatch.state.txt  > stopWatch.state.pu
```

```txt:stopWatch.state.pu
@startuml
hide empty description
state "準備中" as A001
state "計測中" as A002
A001 -[#blue]-> A002 : スタートボタン
state "停止中" as A003
A002 -[#blue]-> A003 : スタートボタン
A003 -[#blue]-> A002 : スタートボタン
@enduml
```
stopWatch.state.puを表示できる環境で表示する。
参考までに、私はplantuml-1.2023.1.jarを使ってローカルでpngファイルを生成して表示したり、VsCodeの拡張機能で表示したりしている。
Qiitaでは、ファイル形式を「plantuml」にすれば表示できるので、Qiitaに貼り付けてもよい。

```plantuml:
@startuml
hide empty description
state "準備中" as A001
state "計測中" as A002
A001 -[#blue]-> A002 : スタートボタン
state "停止中" as A003
A002 -[#blue]-> A003 : スタートボタン
A003 -[#blue]-> A002 : スタートボタン
@enduml
```

## 終わりに

状態遷移表の元となるデータから状態遷移図の出力は出来た。
これを見ると、おおよそstop　watchらしい動きになっていることが確認できた。

あなたも、簡単な遷移のための項目を考えてCSVを起こし、stateCsv2pu.awkを使って変換してみて欲しい。
どのような構成でも、とりあえずは状態遷移図になって表示される。
状態遷移図を眺めるだけでも、足りないところが見えてくるだろう。

次回は、状態遷移表の元となるデータから２種類の状態遷移表を出力するプログラムを作成して、この図で良いか検証する。