OmniAICreator/Qiita-1.07M huggingface dataset:
Kotlinでstaticな拡張関数を作成する

### はじめに
Androidでログの出力方法をカスタマイズしようと、`android.util.Log`に拡張関数を追加しようと考えたのですが、Logクラスはstaticで利用しインスタンスを作成しないため、staticな拡張関数の追加が出来るのか調査しました。

### 自前のクラスの場合
拡張関数を作成したいクラスに`companion object`を作成し、`対象のクラス.Companion`に拡張関数を作成し、呼び出すことが出来ますが、コードに手を入れられるのなら、`companion object`に直接関数を記述すれば十分です。
```kotlin
class MyClass{
    companion object{}
}

fun MyClass.Companion.doAnything() {
    // TODO
}

MyClass.doAnything()
```

### 一部のKotlinクラスの場合
また、一部のKotlinのクラスには`companion object`が存在するため、自前のクラスと同じような使い方が可能です。
```kotlin
fun String.Companion.doAnything() {
    // TODO
}

String.doAnything()
```

### それ以外の場合
しかし、`companion object`の存在しないKotlinのクラスや、元々`companion object`が存在しないJavaのクラスには、staticな拡張関数を作成することは出来ません。
```kotlin
fun Log.Companion.doAnything() { // コンパイルエラー
    // TODO
}

String.doAnything() // コンパイルエラー
```

### 終わりに
`android.util.Log`に直接staticな拡張関数を追加することは出来ないという結論になり、個別のクラスを作成し、拡張関数を定義するようにしました。
```kotlin
class Logger{
    companion object{
        fun debug(appName: String, className: String, message: () -> String) {
            if (BuildConfig.DEBUG) {
                Log.d(appName, "<${className}>:${message()}")
            }
        }
    }
}

Logger.debug("AppName", "ClassName") {
    // TODO
    "message"
}
```
Kotlin2.0からはstatic extensionが導入され、下記のような記述が出来るようなっているようなので、環境の移行が終わりましたら試してみたいと思います。
```kotlin
fun Log.static.doAnything() {
    // TODO
}
```

### 参考リンク
[【Kotlin】KotlinConf’23 で気になったこと](https://qiita.com/maxfie1d/items/eeabdccee696945a733f)
GCP PCA合格体験記

## はじめに

AWS DEA合格後すぐに「AWS AIF」「AWS MLA」を受ける予定でしたが、社内でGCPバウチャーを配布いただいたので前から興味があったこともあり、今回GCP試験を先に受けることにしました。

## 前提条件

- Google cloudを触った経験なし
- AWS実務経験があり
- AWS資格はAIF,MLS以外は取得済([詳細](https://qiita.com/num-bx77/items/f629cc2e9f7616a62ccb))

## 使用教材

- [Professional Cloud Architect試験対策マニュアル](https://blog.g-gen.co.jp/entry/professional-cloud-architect)
- [試験ガイド](https://services.google.com/fh/files/misc/professional_cloud_architect_exam_guide_english.pdf?hl=ja)
- [Udemy](https://www.udemy.com/course/google-cloud-professional-cloud-architect-i/?utm_source=aff-campaign&LSNPUBID=M*j*hKkY1io&utm_medium=udemyads&ranMID=47984&ranSiteID=M.j.hKkY1io-Xk1J5VyOBEf_kAWcGVokbQ)

## 結果

無事合格できました！
![スクリーンショット 2024-12-17 161351.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3904291/6179b8a2-10b2-7381-541f-944e90944e6e.png)



## 感想

試験中に4回ほど回線トラブルでデータがロードできない時間がありました。
時間にしてはおよそ1分程度で自動復旧します。割とよくあることらしいです。
ただAWS試験では起きたことがないため、GCP初見だと戸惑うポイントのひとつだと思いました。
AWS知識だけで、推測できる問題もありましたが、基本的にGCP学習は別建て必須です。
体感の難易度としては **「AWS SAA < GCP PCA < AWS SAP」** でした。


## おわりに

GCP試験を勉強の中でAWSと比較しながら勉強するのが面白かったです。
機会があれば別の試験も受けたいですが、期限のこともあるので次はAWS AIF試験を受験しようと思います。
AWS re:Invent2024に参加しました

この記事は クラウドワークス グループ Advent Calendar 2024 シリーズ3の23日目の記事です。

# はじめに
こんにちは。2024年11月から株式会社クラウドワークスグループに参画いたしました、インゲートの@k-sengaです。
経歴は元NWエンジニア、現クラウドエンジニアです。

今回、海外研修の一環でre:Invent2024に行ってきたのでそれをご紹介したいと思います。




# re:Inventとは？
毎年11月末～12月初旬頃にラスベガスで開催されるAWSの特大イベントです。
最新情報やアーキテクチャの発表、GameDayやハンズオン等様々なコンテンツがあります。
また、Re:Invent前後でもアップデートがドンドン入ってくるので情報を追いかけるのが楽しい期間となります。
一言で言えば、全力で学べて楽しむイベントです。


![1734251825567.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3948032/3c8186ba-28c8-5050-d1fb-1475ae23af6b.jpeg)


# 参加したもの
# Keynote
・CEO Keynote
・Dr.Swami Sivasubramanian Keynote
・Dr. Werner Vogels Keynote

朝開催されるKeynoteに参加しました。
Keynoteは最新情報やアーキテクチャなどをAWS側が発表してくれる場です。
国内と比べると規模やスケールも圧巻なので、参加して良かったです。
Re:InventはKeynoteから始まるとは良く言ったものです。
特にDr.Warnerのアーキテクチャの発表は興味深い内容でした。
何を自動化しないかが重要で、人が入らないところは自動化すると言っていたのがとても印象的でした。


# GameDay
Security and networkingのGameDayに参加しました。
![PXL_20241202_161943013~2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3948032/1a56ff0d-6844-8769-5efa-1b99ef5c4e3d.jpeg)


4人1組のペアで私のチームは珍しく全員日本人でした。
結果は24/66位でした。
最初が調子よく8位まで行けただけに途中の力不足で失速したのが心残りです。
NetworkFirewallやTGW周りはやってたはずなんですが…もっと精進せねばと思った次第です。


# Workshop
Hands-on with Amazon Q in QuickSight:A step-by-step workshop
Explore the power of Amazon Nova multimodal FMs
2つを受けてきました。
2つとも触ったことのないサービスの為大丈夫かな？と思いながら受けてきました。
1つ目に関しては手順化されているものをやっていく形になっていたため、特に問題なく出来ましたが、2つ目に関してはチンプンカンプンでした。
Amazon Nova使うにはBedrockやSagemakerを使えないといけないのか…？と思った次第で、今後勉強していく分野だなと思いました。

# Session系
大体の時間は受けてました。
初日は受けて、日本でも聞いたことある内容だなっと思ったので、主にNEW LAUNCHをメインで受けてました。
Re:Inventに発表された内容はおおよそここで内容を詳細に発表されてるので、内容に興味あるものがあればガンガン受けた方が良いと思います。
ただ、所々にあれ？これKeynoteで発表あったっけ？っていう内容も含まれるので油断大敵です。



# Q&A

Q.時差ボケはあった？

ありませんでした。
今回手配頂いたのが行き：13時→10時着、帰り：19:40→5時着だった為、特段時差を感じるようなことではなかったです。
なので、夜着だと時差を感じるかもしれないです。

Q.英語力はなくても平気だった？

なくても全然楽しめましたが、会話できる程度の英語力があれば…
当初私は翻訳アプリ使えば全然いけると高を括ってました。
セッション等はそれで全然大丈夫なんですが、他の参加者と会話したい時や内容を精密に理解したい、Expoでどんな事をやっているのか聞きたいと思った事が多々ありました。
なので、次回参加する時までに英語力を鍛えようと決意しました。

Q. 海外行ってる最中の体調は？

特に変化はありませんでした。
ただ、日本と違い日中は熱く、朝・夜は冷えるので服装は要注意です。
SWAGで貰ったジャケットが厚く日中の時間帯歩いて干からびそうになりました…
また、砂漠地帯で乾燥してるのでリップクリームや水分補給はこまめに必要です。


# 総括
初海外で多少怯えてはいましたが、行って良かったと率直に思いました。
何よりモチベーションが上がりました。
大雑把に理解してる部分が多いので、これを気に精度を上げたいなと思いましたし、専門外の部分も勉強してみたいなーと思う所が多々ありAmazon Q、Bedrock周りを勉強しようと思ってます。
（Amazon Novaを触りたいのでその辺を学んで土台を作りたい…）

あと、次回行く時は英会話出来るレベルには英語を勉強しようと思いました。
英語話せた方がもっと楽しくなりそうだな…と感じたので帰国後から少しずつ英語を勉強することにしました。
リベンジ編、coming soon...?



# 後日談
ロサンゼルス→羽田でトラブルに巻き込まれ、営業とエンジニア組が離れる事件ありました。
最終的には同じ便で帰れたので良かったですが、最後の最後でヒヤヒヤしました。
周りにいた、日本人客・スタッフの皆様には御礼申し上げます。
社内チャットボットを作るにあたって考えたこと　～②AIプラットフォーム～

# はじめに
2024年8月頃からAWS上でBedrockを使って社内向け生成AIチャットボットを作っています。
初めて生成AIを使ってみたところで色々考える点があったので、メモとして残しておくことにしました。

生成AI技術が日々すごいスピードで進歩しているので既に古い技術になっていそうなのと、そもそも初心者が書いておりますで、あまり技術的な参考にはならないと思いますが、ポエム的な感じ？でお読みいただけたら幸いです。

# 考えたこと②　AIプラットフォーム

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3569502/2368a4f5-16bf-a3b7-03c5-52c6854978f6.png)

考えたこと②ものの、「AWSで作る」という時点であまり悩まず、今回はAmazon Bedrockの一択でした。（DifyでLLMを使うときにモデルプロバイダーをAWSにする場合はBedrockを指すことになる）

また、下記はAWSさんが生成AIサービスについて説明されるときによく使われてた資料ですが（日本語版でよく見てたのですが見つからず…）、
今回はシンプルなQAデータを読むチャットボットを作るという目的のため、SageMakerで独自モデルを作るほどのものではなく（難しくてできない）、提供されるモデルを使っていきたいという考えがありました。

https://docs.aws.amazon.com/decision-guides/latest/bedrock-or-sagemaker/bedrock-or-sagemaker.html

### Amazon Bedrockを使いたかった理由

#### 色んな基盤モデルを利用できる
基盤モデルは種類があって次々と新しいバージョンが出てくるので、置き換えていくことで精度や性能を上げていきたいと考えました。
- 最新のモデルを使いたい
- 用途によって複数のモデルを使い分けたい

#### ナレッジベース
QAチャットボットの特性からファインチューニングではなくて、RAGを充実させたいと考えました。Dify上でもRAG（ナレッジ）は持てるのですが、以下の理由からBedrockのナレッジベースを使うことにしました。
- 将来的に多数のファイルを読み込みたい
- フォルダ単位で管理したい
- Teams版と共有したい

#### ガードレール
ガードレールというと不適切な言葉のフィルターするという目的が大きいかと思いますが、今回は社内版ということでそのあたりのガードではなくて、スコアを取得するために使いたいと考えました。

ガードレールにはGroundingとRelevanceという2つのスコアが取得できます。
簡単に書くとGroundingは根拠に基づいているかどうか、Relevanceは質問の意図を汲み取れているかどうかというスコアとのことです。
（こちらの記事を参考にさせていただきました。）

https://dev.classmethod.jp/articles/guardrails-for-amazon-bedrock-contextual-grounding-check/

初期検討時はハルシネーション抑制ためにGroundingスコアを使いたいという目的があったのですが、ある程度チャットボットの形ができあがってきた現段階では、Relevanceスコアを使ってスコアの低い回答だった場合にQAデータとして追加させようかという改善活動に向けての使い方が大きくなってきた気がします。

#### フロー
シンプルなチャットボットと言えども、質問と回答の処理だけでは成り立たなくて、RAG検索したり、スコアを取得して制御したり、履歴をDBに格納したり、ちゃんとした回答得られなかったときに代替候補出したり等々、、、フローとして処理を組むことが必要になってくると思います。
こちらはDifyの特徴であるワークフローで実現できますが、Bedrockでもフロー機能があり、どちらを使うか考えました。

初期検討時はDifyでフロント側の制御、LLMやRAG的なバックエンドにBedrock側のフローを使おうかという案もありましたが、全体的な使い易さ（UI、複製が楽、デバッグ簡単…etc）の面でDify側のフローで対応することにしました。
#Bedrock側のフローはPreview版でPrompt Flowsと呼ばれていたときに比較したので、現在はPreview外れてAmazon Bedrock Flowsになったようなので当時よりは使い易くなっているんだろうと思います。

### Amazon Bedrock 構築時に参考にしたサイト

#### DifyからBedrockにIAMロールでアクセスさせる
アクセスキーではなくEC2にIAMロールを割り当てて利用する方法として参考にしました。

https://aws.amazon.com/jp/builders-flash/202409/dify-bedrock-automate-security-operation/

#### APIの呼び出し
ナレッジベースやガードレールのAPI呼び出しは、Dify側でカスタムツールを作成して、API Gateway⇒Lambda⇒Bedrockという感じで呼び出す形としました。

https://acro-engineer.hatenablog.com/entry/2024/07/22/120000


## 考えた結果

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3569502/da07571d-bc6b-621f-23e3-4459cc9c896b.png)
windowsでiverilog その166

# 概要　
windowsでiverilogやってみた。
自作cpu、見つけたので、調査してみた。
uartやってみた。systemverilogだったのでverilogに書き換えた。

# テストベンチ

```
module test();
	reg clk;
	reg rst;
	reg [7:0] tx_data;
	reg en;
	reg ien;
	wire busy_tx;
	wire tx;
	wire [7:0] rx_data;
	wire busy_rx;
	wire rx;
	wire ack;
	wire valid;
	wire irq;
	assign rx = tx;
	uart_tx #(.WAIT_COUNT(868)) uart_tx(.clk(clk), .rst(rst), .en(en), .tx_data(tx_data), .busy(busy_tx), .tx(tx));
	uart_rx #(.WAIT_COUNT(868)) uart_rx(.clk(clk), .rst(rst), .rx(rx), .ien(ien), .ack(ack), .rx_data(rx_data), .busy(busy_rx), .valid(valid), .irq(irq));
	initial
	begin
		tx_data = 8'b10010110;
	end
	initial
	begin
		clk = 0;
		forever #5 clk = ~clk;
	end
	initial
	begin
	#10;
		rst = 1;
	#10;
		rst = 0;
	end
	initial
	begin
		ien = 1;
	end
	initial
	begin
	#100;
	#10;
		en = 1;
	#10;
		en = 0;
	#90000;
		$finish;
	end
	initial
	begin
		$dumpfile("test.vcd");
		$dumpvars(0, test);
		$display(" tx       rx");
		$monitor(" %b %b", tx_data, rx_data);
	end
endmodule





```

# 実行結果

```
>vvp a.out
VCD info: dumpfile test.vcd opened for output.
 tx      rx
 10010110 xxxxxxxx
 10010110 10010110
uart.v:186: $finish called at 90120 (1s)

```

以上。
今一度基礎からアウトプットしていこう。ツール編（インフラ・企業向け業務運用）

#### ツールを使いこなせるものほど、この世界を生き残れるのさ・・・

じゃじゃ馬しかいないけどね。



## 個人的使用したことのあるツール集

### HULFT（ハルフト）
- **概要**:  
  企業活動で発生する売上データや顧客情報、ログデータなど、ITシステムに蓄積されたデータの送受信を行うファイル転送ミドルウェア。
- **特徴**:  
  - FTPに比べ信頼性が高い。  
  - 大規模かつ高度なデータ転送が可能。  

---

### JP1
- **概要**:  
  日立製作所が開発した国内トップシェアの統合システム運用管理ソフトウェア。
- **特徴**:  
  - システムの自動化、資産管理、セキュリティ管理、ジョブ管理を統合的に実施。  
  - 定型的・定期的な業務を自動化する製品。  
  - **対応OS**: Unix, Linux, Windows。  
  - JP1をクラウドに移行するサービスを伊藤忠が提供。  

---

### Arcserve（アークサーブ）
- **概要**:  
  PCサーバのバックアップ、リカバリ、複製を行うソフトウェア。
- **特徴**:  
  - データ保護のためのソリューションとして利用。

---

### Active Directory（AD）
- **概要**:  
  Windows OSのネットワーク上で動作し、サーバ、クライアント、プリンタなどの周辺機器や利用者の識別番号、アクセス権限を一元管理するシステム。
- **特徴**:  
  - ネットワーク内のリソース管理を効率化。  
  - ドメインコントローラを用いてアクセス権限を管理し、逐一パスワードを入力する手間を軽減。  
  - 一言でいえば「大規模な管理表」。

---

### SmartOn
- **概要**:  
  二要素認証を実現するセキュリティ製品。
- **特徴**:  
  - システムへのログインや認証を強化。  
  - セキュリティ対策に有効。

---

### アプリケーションウィザード
- **概要**:  
  ソフトウェアインストール時に最初に表示される対話形式のポップアップ。
- **特徴**:  
  - インストール手順をわかりやすくガイド。  
  - 「対話できる」形式がまるで魔法のようだと感じるツール。



以下ちょっと気になるツールを分類わけしてみた。
## その他インフラ・業務運用ツールの大まかな分類

### 1. 監視運用業務
- **ツール例**:  
  - Zabbix  
  - Nagios  
  - Splunk  
- **用途**:  
  システムやネットワークの稼働状態を監視し、障害発生時に通知する。

---

### 2. バックアップ・災害復旧
- **ツール例**:  
  - Veeam  
  - Commvault  
  - Carbonate  
- **用途**:  
  データの損失やシステム障害に備え、バックアップと復旧を提供。

---

### 3. セキュリティ管理
- **ツール例**:  
  - Symantec  
  - Trend Micro  
  - Palo Alto Networks  
- **用途**:  
  サイバー攻撃や不正アクセスから企業の情報資産を保護。

---

### 4. 自動化・オーケストレーション
- **ツール例**:  
  - Ansible  
  - Chef  
  - Kubernetes  
- **用途**:  
  サーバやアプリケーションのプロビジョニング、管理、運用を自動化。

---

### 5. パフォーマンス監視と分析
- **ツール例**:  
  - New Relic  
  - AppDynamics  
- **用途**:  
  アプリケーションやシステムのパフォーマンスを監視・分析し、最適化を支援。

---

### 6. クラウドサービス
- **ツール例**:  
  - AWS  
  - Azure  
  - GCP  
- **用途**:  
  柔軟性やスケーラビリティを提供するクラウドプラットフォームを利用したシステム構築・運用。

---

### **補足カテゴリ（必要に応じて追加）**

#### ログ管理・SIEM
- **ツール例**:  
  - ELK Stack  
  - Splunk  
  - QRadar  
- **用途**:  
  ログの統合管理やセキュリティ情報・イベント管理（SIEM）。

#### データベース管理
- **ツール例**:  
  - Oracle Enterprise Manager  
  - pgAdmin  
- **用途**:  
  データベースのパフォーマンス監視や可用性の管理。


##### 所感
「え～。でもお高いんでしょう？」「はい。」
個人では手を出せない、あるいは出す必要のないものばかり。
でも、これらのうちのほとんどは、AWSでまかなえるんだろうな。
【Unity】 Gitのパッケージ管理ツール「Smart Git UPM」公開


# Smart Git UPM

Gitリポジトリのパッケージを効率的に管理するためのプラグイン

https://github.com/IShix-g/SmartGitUPM

![header.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/389614/1d1f7c19-474e-ece8-abe2-09ee1f98bd02.png)

## なぜ、今さらGitのバージョン管理？

パッケージマネージャーで、もう少しな部分を改善したくて開発しました。

### アップデートがあれば表示してほしい

Unityでは2018からパッケージマネージャーがあります。とても便利ですが、Gitのアップデートを表示してくれません。それを視覚的に分かりやすく表示します。

![update.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/389614/6557704a-a9b4-03cb-cb0b-9d196ba01659.jpeg)

### プライベートリポジトリに対応

SSH接続のプライベートリポジトリに対応しました。

![private_repo.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/389614/16ff2c15-5793-d679-31ec-1a700d270483.jpeg)

※このプラグインはSSH接続について何もしません。別でPCに設定する必要があります。
※ プライベートリポジトリの場合、初回の取得に時間が掛かる場合もあります。

#### SSH接続とは？
SSH（`Secure Shell`）は、リモートコンピュータに安全に接続して操作するためのプロトコルです。秘密鍵（自分のPC）と公開鍵（接続先）を使い、暗号化された通信で認証します。

### 更新通知

Unity Editorを開く度に、パッケージの更新があれば通知を受け取る事ができます。
もちろん通知の停止もパッケージ単位で可能です。

<img alt="Configure" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/389614/c80ab7fb-c2c6-7868-f79d-9daf349e24aa.jpeg" width="550"/>

### パッケージマネージャーを使用しているので安心

インストールやアンインストールは、パッケージマネージャーを利用しているので安心。
もし必要無くなってもSmart Git UPMを削除するだけです。インストールしたものに影響を与えません。

### 各、サービスとの比較

|  | Gitの更新情報 | 登録の必要なし | プライベートRepo | 更新の通知 |
|---|---|---|---|---|
| Smart Git UPM | O | O | O | O |
| Open UPM| O | X | X | X |
| パッケージマネージャー | X | - | O | X |

## Open UPMと何が違うの？

`Scoped Registries`に設定する事で、パッケージの情報を表示できるのが[Open UPM](https://openupm.com/)です。Smart Git UPM同様アップデート情報も知れます。

例) Admobの広告を設定した場合

![upm_scoped_registries.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/389614/a1914d7a-175b-0c57-d860-046a0027e5f9.jpeg)

パッケージマネージャーの`My Registries`タブに下記のように表示されます。

![upm.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/389614/dcb63b1e-6b16-3b01-97db-c5d2245c971d.jpeg)

とても便利なOpenUPMですが欠点もあります。

- パッケージの開発者がOpenUPMに登録する必要があり、未登録のパッケージには対応しない
- プライベートリポジトリに対応しない

Smart Git UPMなら登録の必要が無くプライベートリポジトリにも対応します。

## 最後に

個人用に開発しましたが、せっかくなので公開する事にしました。
誰かの為になりますと幸いです。

メリークリスマス🎄
良いクリスマスと新年を🎉

インストール方法などの詳細は下記リポジトリで。

https://github.com/IShix-g/SmartGitUPM
PowerAutomateのRPAをPythonでリファクタリングした話

## はじめに
APIのないウェブサービスからCSVデータを自動でダウンロードするRPAを、PowerAutomateからPythonとタスクスケジューラに移行した経験を共有します。

---

## 背景
PowerAutomateでCSVの出力とGoogleドライブへのアップロードを実装していましたが、稼働が不安定で一番データの必要な月末月初でアップデートがかかってエラーが発生していました。ログの制御が分かりづらく原因の特定ができず維持管理に困っていました。年間264,540円のコストもかかっており、より堅牢で柔軟な制御とエラーハンドリング、ログの取得のためにPythonとタスクスケジューラーへ移行して自動化することにしました。

---

## 実装のポイント
### ディレクトリの構成
RPA/
├─ worktime_extract.py
├─ .env
├─ credentials.json
├─ worktime_extract_scheduler.xml
├─ token.pickle
└─ logs/                   # ログファイル保存ディレクトリ

worktime_extract_scheduler.xmlをタスクスケジューラーにインポートすることで、ログアウトした状態でworktime_extract.pyが日次で勤怠情報の抽出ができるようにしました。
詳細なコードについては冗長になるので割愛させて頂きます。

### 1. ログイン処理の安定化
PowerAutomateでは時々ログインに失敗することがありましたが、Pythonでは以下のような改善を実施しました:
- **Seleniumを使用した明示的な待機処理**
- **ログイン試行回数の制御**
- **詳細なログ出力**

### 2. ダウンロード処理の信頼性向上
ファイルのダウンロードとその確認を確実に行うために以下を実装しました:
- **Seleniumで手順に必要な要素を待機**
- **ファイルのダウンロードの完了の確認**

---

### 3. Google Driveとの連携
PowerAutomateではログアウトした状態でファイル移動からGoogleDriveへの同期処理を行っていましたが、タスクスケジューラーではログアウトするとGoogleDriveの同期が切断されて起動できなかったためAPIでの実装を行いました。:
- **Google Drive APIを使用した確実なアップロード**
- **エラー時のリトライ処理**

---

## 改善効果

### 1. 安定性の向上
- 実装後2週間ほど経過しましたが一度もエラー発生していません
- ログの保存ができ、問題が起こった際にデバッグが必要な場合には詳細なログを追加可能

### 2. メンテナンス性の向上
- コードの可読性の向上
- エラーハンドリングの追加が容易に

### 3. 実行速度の向上
- 3－5分程度かかっていた処理が通常時1分以内で処理が完了

### 4. コストの削減
- 年間264,540円の契約を解除

---


## まとめ
PowerAutomateからPythonへの移行により以下が実現しました:
- **より堅牢なエラーハンドリング**
- **詳細なログ出力**
- **柔軟な処理の実装**
- **コストと運用工数の削減**
[備忘録]依存関係プロパティの作成の仕方

# はじめに
こんにちは、吉原です。WPFを学習していて、理解に時間のかかった依存関係プロパティについて備忘録として残しておきたいと思います。
# 依存関係プロパティとは
依存関係プロパティとは、WPFにおいて通常のプロパティを拡張し、データバインディング、スタイルなどをサポートする仕組みです。プロパティの値は、コードに直接設定された値、スタイル、バインディングなど、複数の要素から値を設定できます。また、プロパティの値が変更されると、自動的にUIに反映することができるため、再描画等の手間を軽減できます。

既存のWPFコントロールにはない、独自の依存関係プロパティを設計することで、UIの柔軟性、拡張性を向上させることが可能となります。


# 依存関係プロパティの作成
依存関係プロパティは、DependencyProperty.Registerメソッドを使用します。その際に以下の情報が必要となります。
```C#
DependencyProperty.Register(
    "プロパティ名",           // プロパティ名（文字列）
    typeof(プロパティの型),   // プロパティのデータ型
    typeof(登録するクラス),   // 登録するクラス
    ...                      // その他メタデータ
);
```
ここで登録するクラスとは、WPFが依存関係プロパティをクラス単位で管理しているため、この依存関係プロパティが「どのクラスが持つプロパティなのか」を明確にするために指定するモノです。別のクラスで使用したい場合は、DependencyProperty.AddOwnerメソッドで使用可能となります。

次にその他メタデータとは、メタデータで主に設定できるのは以下です。
- デフォルト値：プロパティが初期化されていない場合にデフォルト値を設定
- コールバック関数：プロパティの値が変更された時に呼び出されるコールバック関数の設定
- 値の強制：無効な値の設定の抑制
- バインディング値の動作設定：バインディングの方向や更新モードの設定

これらは、PropertyMetadataを使用した場合ですが、FrameworkPropertyMetadataを使用すれば、さらに詳細に設定することが可能です。

# CLRラッパー
依存関係プロパティを登録した際に、忘れてはいけないのがこのCLRラッパーです。簡単にいうと、登録した依存関係プロパティを通常のプロパティのように扱えるようにする操作です。

そもそもCLR(Commmon Language Runtime)とは、.NET対応のプログラムの実行環境を提供するランタイムのことです。そんなCLRが提供する標準的な機能を用いて定義されたものが通常のプロパティ（CLRプロパティ）です。

依存関係プロパティは通常のプロパティとは異なるため、直接的に GetValue や SetValue メソッドを呼び出して値を取得・設定する必要があります。

そこで、開発者が通常のプロパティのように簡単に使えるようにするために行う操作がCLRラッパーです。これにより、プロパティの値の取得・設定時に GetValue と SetValue の呼び出しを内部で処理し、依存関係プロパティへのアクセスが簡単になります。
```C#
public class MyControl : Control
{
    // 依存関係プロパティの登録
    public static readonly DependencyProperty IsHighlightedProperty =
        DependencyProperty.Register(
            "IsHighlighted",               // プロパティ名
            typeof(bool),                  // プロパティの型
            typeof(MyControl),             // 登録するクラス
            new PropertyMetadata(false)    // デフォルト値
        );

    // CLRラッパー（通常のプロパティと同様に扱う）
    public bool IsHighlighted
    {
        get { return (bool)GetValue(IsHighlightedProperty); }
        set { SetValue(IsHighlightedProperty, value); }
    }
}
```

# おわりに
以上の理解で私は依存プロパティを理解し実装できるようになりました。また、この記事を書くことによって、より自分の理解が確かなものへと変わったという実感が湧きました。今後も、学習や業務を通して躓いた点や大事な点があった際に、積極的に投稿していきたいと思います。
controller specでActionView::Missing Templateエラーが出る

末尾で他のaction（`do_create`、仮)を呼び出す`create`のテストを書いたとき、

```ruby
      it 'do_createが呼ばれる' do
        expect(controller).to receive(:do_create).and_return(true)
        post :create, params
      end
```

といつも通り書いたところ、下記のようなエラーが出た。

```
ActionView::MissingTemplate:
       Missing template path/to/create, ..., application/create with {:locale=>[:en, :ja], :formats=>[:html], :variants=>[], :handlers=>[:erb, :builder, :raw, :ruby, :slim, :coffee, :haml, :jbuilder]}. Searched in:
```       

要はrenderするときに指定されたテンプレートファイルが見つからないよ、というエラー

### 原因

`create`においては`do_create`がメインの処理で、その中でリダイレクトしたりエラーを出したりあるいはrenderしたりする。
つまり、`do_create`をスタブ化してしまったらこのアクションは存在しない自身のviewファイルを探しにいってしまいエラーが出てしまうということだと思われる。

### 対策

まず、仮にテンプレートファイルを置いてみた。
```bash
$ touch path/to/create.html
```
はい、これだけで問題なく通りました。
しかしこれではコミットできないので、`do_create`のスタブの中身を適当に存在するテンプレートを呼ぶrenderに変えてみた。

```ruby
expect(controller).to receive(:do_create) { render_template :edit }
post :create, params
```

しかしこれでは駄目。メソッドの最後にrenderを置いているのになぜ？恐らく書き方が悪いんだと思うがどこが悪いのかわからない。

そこでエラーを投げるようにしてみた。

```ruby
expect(controller).to receive(:do_create).and_raise(DummyError)
expect { post :create, params }.to raise_error(DummyError)
```

DummyErrorクラスは実際のエラーと区別するためにspecファイルの中で定義したエラークラス。これで一応動いた。バッドプラクティス感がすごいが、メモとして残しておきます。
【Python】Gemini APIに画像を読みこませてみる

# はじめに
先日の記事では`Gemini API`を利用したテキスト生成について紹介しました。
それに引き続き、今回は画像を読み込ませて、何らかの簡単な処理を行う方法をまとめてみました。
なお、`Gemini API`を利用するにあたり始めに行うキーの取得などは前回の記事にまとめたので、もしよかったらどうぞ。

https://qiita.com/anapausis/private/ed82b496ab9901856680

では、始めていきます。

# 概要
実行の前に、まずは`Gemini API`を利用して画像処理を行う際の概要についてまとめます。

`Gemini 1.5 Pro`と`1.5 Flash`（今回用いるのはこちら）は、最大3,600個の画像ファイルをサポートしており、各画像は258個のトークンに相当します。
画像データは、下記のいずれかでなければなりません。
<ol>
<li>PNG - image/png
<li>JPEG - image/jpeg
<li>WEBP - image/webp
<li>HEIC - image/heic
<li>HEIF - image/heif
</ol>

画像の大きさ（ピクセル数）について特に制限はなく、大きすぎたり、小さすぎたりした場合はそのアスペクト比を維持したまま拡大、縮小されます。

渡す画像の合計サイズが**20Mb未満**になる場合は、`base64`でエンコードされた画像をアップロード、またはローカルにある画像フォルダを直接アップロードすることが推奨されています。（いずれも後述）
一方、それよりも大きな画像をアップロードする際は`File API`の`media.upload`メソッドを使用します。（勉強不足によりこちらは今回省略させてもらいます、ごめんなさい）

加えて、最良の結果を得るために以下のことが公式から推奨されています。

<ol>
<li>アップロードする前に画像を適切な向きにしておくこと（上下逆さまなどにしない）
<li>ぼやけた画像を使用しないこと
<li><strong>1つの画像を使用する場合は、テキスト プロンプトを画像の後に配置すること</strong>
</ol>
特に最後はコードを記述するうえで大切そうだったので目立たせておきます。

# 実行してみる
では、実際に動かしてみます。

### base64でエンコードされた画像をアップロードする
ウィキペディアで紹介されていた、ニューヨークの景色の画像をアップロードします。
以下のように記述してみます。
```python:ewample.py
import httpx
import os
import base64
import google.generativeai as genai

genai.configure(api_key="(ここに自身のAPIキーを入力)")

model = genai.GenerativeModel("gemini-1.5-flash")
image_path = "https://upload.wikimedia.org/wikipedia/commons/8/8e/Downtown_Skyline_%2839960025320%29.jpg"

image = httpx.get(image_path)

prompt = "この画像はどこで撮影されたものだと考えられる？"
response = model.generate_content([{'mime_type':'image/jpeg', 'data': base64.b64encode(image.content).decode('utf-8')}, prompt])

print(response.text)
```
すると、以下のように返答がくると思います。
> これはニューヨーク市のマンハッタンの夜景です。写真の中央に ある象徴的なビルは ワールドトレードセンターです。周りの 高層ビルと街の照明から、この画像はニューヨーク市で撮影され たものだと推測できます。


### ローカルにある画像をアップロードする
ためしに、先日の投稿で使用した以下の画像をアップロードして、簡潔に説明させてみます。

![スクリーンショット 2024-11-13 155312.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3817741/d7e7a963-a20c-7259-e210-13644dafe16c.png)

以下のように記述してみます。

```python:example.py
import PIL.Image
import os
import google.generativeai as genai

genai.configure(api_key="(ここに自身のAPIキーを入力)")

image_path = "(ここにアップロードする画像ファイルのパスを記述)"

image = PIL.Image.open(image_path)

model = genai.GenerativeModel("gemini-1.5-flash")

prompt = "この画像について2,3文で簡単に説明して。"

response = model.generate_content([prompt, image])

print(response.text)
```
アップロードする画像ファイルのパスについては、`C:/Users/(ユーザー名)/Pictures/Screenshots/スクリーンショット 2024-11-13 155312.png`（私の場合）のように、**Cドライブからファイルまでのパス**を書く必要があります。

ちなみに、今回は以下のように返答がきました。
> これはGitHub Copilotのチャットインターフェースのスクリーンショットです。ユーザーはCopilotに雑談をしたいと尋 ねていますが、Copilotは雑談には対応 しておらず、GitHub関連の質問であれば対応できると答えています。

# おわりに
今回の記事では、`Gemini API`に画像を読み込ませ、その画像の説明を主にしてもらいました。ただ、`File API`についての理解が全然できておらず、省略という形になってしまったので、今後勉強していくようにします。

では、今回の記事はこれで終わりです。最後までお読みいただきありがとうございました。

# 参考
https://ai.google.dev/gemini-api/docs/vision?hl=ja&authuser=1&lang=python

https://ja.wikipedia.org/wiki/%E3%83%8B%E3%83%A5%E3%83%BC%E3%83%A8%E3%83%BC%E3%82%AF
SharePoint Advanced Managment

# SharePoint Advanced Managmentとは

SharePoint Premiumのアドオンライセンスとして提供される強力なツールセットで、
コンテンツのガバナンスと管理を効率化するために設計されています。
主にIT管理者向けの機能が提供されています。

## 特徴

IT管理者はコンテンツのガバナンスを強化し、効率的なデータ管理を実現できます。

- コンテンツのスプロール管理：スプロールとは、無秩序な管理状態を指します。コンテンツの過剰共有を防ぎ、適切に計画されたコンテンツの作成を確保します。
- アクセス制御：ユーザーがコンテンツを共有しすぎないようにし、アクセスを制限します。
- ライフサイクル管理：古いコンテンツや非アクティブなコンテンツを削除し、最新の情報に焦点を当てます。
- AI分析情報：AIを活用してレポートからパターンを抽出し、潜在的な問題を特定します。
- セキュリティ強化：データの整合性とセキュリティを維持し、組織全体でのデータ管理を最適化します。

## ライセンス

ユーザーごとの課金制となります。従量課金ではありません。

## 参考情報

- [Microsoft SharePoint Premium - SharePoint Advanced Management の概要](https://learn.microsoft.com/ja-jp/sharepoint/advanced-management)
PleasanterとChatGPTを連携してみた！

# PleasanterとChatGPTを連携する方法

PleasanterとChatGPTを連携することで、タスク管理や自動応答機能を強化できます。本記事では、Pleasanter APIとOpenAI APIを活用して連携を実現する手順を説明します。

## はじめに

### 前提条件

1. **Pleasanter環境**
   - APIが有効化されていること。
   - アクセストークンを発行済みであること。

2. **OpenAI APIキー**
   - ChatGPTを利用するためのAPIキーを取得していること。

3. **開発環境**
   - Pythonがインストールされていること。
   - 必要なライブラリがインストールされていること（`requests`, `openai` など）。

---

## 実装手順

### 1. Pleasanter APIの設定

Pleasanter APIを利用して、データを取得または登録します。

以下のコードは、Pleasanter APIからデータを取得する例です。

```python
import requests

PLEASANTER_API_URL = "https://your-pleasanter-domain.com/api/items"
ACCESS_TOKEN = "your_pleasanter_access_token"

headers = {
    "Authorization": f"Bearer {ACCESS_TOKEN}",
    "Content-Type": "application/json"
}

# データ取得例
def get_pleasanter_data():
    response = requests.get(PLEASANTER_API_URL, headers=headers)
    if response.status_code == 200:
        return response.json()
    else:
        print("Error:", response.status_code, response.text)

# 使用例
data = get_pleasanter_data()
print(data)
```

---

### 2. ChatGPTの設定

OpenAI APIを使用して、ChatGPTにデータを送信し、レスポンスを取得します。

以下のコードは、ChatGPTを利用する基本的な例です。

```python
import openai

OPENAI_API_KEY = "your_openai_api_key"

openai.api_key = OPENAI_API_KEY

def get_chatgpt_response(prompt):
    response = openai.ChatCompletion.create(
        model="gpt-4",
        messages=[
            {"role": "system", "content": "You are a helpful assistant."},
            {"role": "user", "content": prompt}
        ]
    )
    return response['choices'][0]['message']['content']

# 使用例
response = get_chatgpt_response("こんにちは、何をお手伝いできますか？")
print(response)
```

---

### 3. PleasanterとChatGPTの連携

以下のコードでは、Pleasanterからデータを取得し、そのデータをChatGPTで処理した結果をPleasanterに登録または更新します。

```python
def pleasanter_to_chatgpt_and_back():
    # 1. Pleasanterからデータを取得
    pleasanter_data = get_pleasanter_data()

    # 必要なデータを抽出（例: 特定のフィールド）
    prompt = pleasanter_data.get("Items", [{}])[0].get("Title", "デフォルトプロンプト")

    # 2. ChatGPTで処理
    chatgpt_response = get_chatgpt_response(prompt)

    # 3. Pleasanterにデータを登録/更新
    update_payload = {
        "Title": "ChatGPTからの応答",
        "Description": chatgpt_response
    }
    response = requests.post(PLEASANTER_API_URL, headers=headers, json=update_payload)
    if response.status_code == 200:
        print("データが正常に登録されました。")
    else:
        print("登録エラー:", response.status_code, response.text)

# 実行
pleasanter_to_chatgpt_and_back()
```

---

## 必要なライブラリのインストール

以下のコマンドを使用して必要なライブラリをインストールします。

```bash
pip install requests openai
```

---

## 注意点

1. **APIキーの管理**
   - `.env`ファイルや環境変数を使用して、APIキーを安全に管理してください。

2. **エラーハンドリング**
   - API呼び出しエラーやネットワークエラーに対応するために、例外処理を実装してください。

3. **データ形式の確認**
   - Pleasanterのデータ構造に応じて、必要に応じてデータの整形や変換を行ってください。

---

## 実行結果

この連携を実行することで、例えば以下のようなことが可能です。

- Pleasanter上のタスクやデータをChatGPTで要約。
- ChatGPTの生成したアイデアや提案をPleasanterに自動登録。

---

### おわりに

今回の例をもとに、PleasanterとChatGPTを活用した独自のワークフローを構築してみてください。ご質問や改善点があれば、コメント欄でお知らせください！
PythonでWordのブックマークを追加・削除する

Wordのブックマーク機能は、文書内の特定の場所を素早く見つけることができる非常に便利なツールです。文書の確認や編集、特定の情報の検索など、しおりは非常に便利です。
以下では、Pythonを使ってWord文書にしおりを追加したり削除したりする方法を紹介します、 ユーザが文書をより効率的に管理できるようにします。
* [Pythonで指定した段落にしおりを挿入する](#pythonで指定した段落にしおりを挿入する) 
* [Pythonで指定したテキストにしおりを挿入する](#pythonで指定したテキストにしおりを挿入する) 
* [PythonでWordからしおりを削除]()

## Word文書処理用Pythonライブラリ
この記事で使用しているメソッドは、[**Spire.Doc for Python**](https://www.e-iceblue.com/Introduce/doc-for-python.html)ライブラリを必要とします。pipで直接インストールできます：
>pip install Spire.Doc


## Pythonで指定した段落にしおりを挿入する
1. Word文書を読み込む；
1. 指定した段落を取得する；
1. **`BookmarkStart`** オブジェクトを作成し、**`Paragraph.Items.Insert()`** メソッドで段落の先頭に挿入する；
1. **`Paragraph.AppendBookmarkEnd()`** メソッドで **`BookmarkEnd`** オブジェクトを段落の最後に追加する；
1. ドキュメントを保存します。

**Pythonコード:**
```python
from spire.doc import *
from spire.doc.common import *

# Word文書を読み込む
doc = Document()
doc.LoadFromFile("蝶.docx")

# 第2パラグラフを読む
paragraph = doc.Sections[0].Paragraphs[1]

# 段落にブックマークを追加する
start = paragraph.AppendBookmarkStart("蝶の誕生")
paragraph.Items.Insert(0, start)
paragraph.AppendBookmarkEnd("蝶の誕生")

# ファイルを保存する
doc.SaveToFile("AddBookmark.docx", FileFormat.Docx2019)
doc.Close()
```
![AddWordBookmark.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2811193/2fbf7a9c-56af-f424-1bfe-b1caddfb6fa9.png)



## Pythonで指定したテキストにしおりを挿入する
1. Word文書を読み込む；
1. 文書内の指定されたテキストを検索し、それが段落内のどこにあるかのインデックスを取得します；
1. **`BookmarkStart`** オブジェクトを作成し、**`Paragraph.ChildObjects.Insert()`** メソッドで指定したテキストの前に挿入します；
1. **`BookmarkEnd`** オブジェクトを作成し、**`Paragraph.ChildObjects.Insert()`** メソッドで指定したテキストの後に挿入します；
1. ドキュメントを保存します。

**Pythonコード:**
```python
from spire.doc import *
from spire.doc.common import *

# Word文書を読み込む
doc = Document()
doc.LoadFromFile("蝶.docx")

# 文書内の指定テキストを検索する
finds = doc.FindAllString("成虫", False, True)
specificText = finds[0]

# テキストがある段落を取得する
paragraph = specificText.GetAsOneRange().OwnerParagraph

# 段落内のテキストのインデックスを取得する
index = paragraph.ChildObjects.IndexOf(specificText.GetAsOneRange())

# 指定したテキストにしおりを挿入する
start = paragraph.AppendBookmarkStart("成長")
paragraph.ChildObjects.Insert(index, start)
end = paragraph.AppendBookmarkEnd("成長")
paragraph.ChildObjects.Insert(index + 2, end)

# ファイルを保存する
doc.SaveToFile("AddBookmarkToText.docx", FileFormat.Docx2019)
doc.Close()
```
![AddBookmarkToText.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2811193/1a96238c-9ce1-4e5b-c86b-43d27254687f.png)


## PythonでWordからしおりを削除
1. Word文書を読み込む；
1. **`Document.Bookmarks[]`** プロパティで特定のブックマークを取得する；
1. **`Document.Bookmarks.Remove()`** メソッドで指定したブックマークを削除する（すべてのブックマークを削除するには **`Clear()`** メソッドを使用します）；
1. 文書を保存する。

**Pythonコード:**
```python
from spire.doc import *
from spire.doc.common import *
    
# Word文書を読み込む
document = Document()
document.LoadFromFile("AddBookmark.docx")

# 指定したブックマークを取得する
bookmark = document.Bookmarks[0]

# 指定したブックマークを削除する
document.Bookmarks.Remove(bookmark)
# すべてのブックマークを削除する
# document.Bookmarks.Clear()

# ファイルを保存する
document.SaveToFile("DeleteBookmark.docx", FileFormat.Docx)
document.Close()
```
* * *
>**赤い評価の警告を消す方法:**

https://www.e-iceblue.com/TemLicense.html
PowerDNSとPowerDNS Adminで内部DNSを整備した話〜権威DNS編〜


:::note info
この記事ではまず権威DNSの構築をしています。
フルリゾルバの構築は18日目、PowerDNS Adminの設定は19日目をご覧ください。

フルリゾルバの記事: <https://qiita.com/yuito_it_/items/1b8afe0889c65e2fb478>
PowerDNS Adminの記事: <https://qiita.com/yuito_it_/items/d868a64c20035359a6df>
:::

## はじめに

今回は内部DNSを立ててローカルIPに対してドメイン名でアクセスできるようにしていきます。
権威DNSというのは、一つもしくは複数のドメインの情報を管理する末端のDNSです。

### PowerDNSとは

PowerDNSはGPLライセンスの下で公開されているDNSサーバーです。
そしてこれは、権威DNSサーバーもフルリゾルバサーバーも構築できます。
今回はこれを用いて、まずは権威DNSを作成していきます。

https://www.powerdns.com/

### なぜBINDじゃないの？

BINDはもちろん有名なのですが、**とにかく脆弱性が多い**ということで、却下になりました。

## 環境

PowerDNSはDBでレコードを管理しています。
MySQLやPostgresSQLなどさまざま対応していますが、今回はPostgresSQLを使用していきます。

```sh
cat /etc/os-release

PRETTY_NAME="Ubuntu 24.04.1 LTS"
NAME="Ubuntu"
VERSION_ID="24.04"
VERSION="24.04.1 LTS (Noble Numbat)"
VERSION_CODENAME=noble
```

## PowerDNSをインストール

普通にaptでインストールします。

```sh
sudo apt install pdns-server pdns-tools
```

しかし、最近のOSは53番ポートを`systemd-resolved`が使用しているため、今は起動に失敗した皆のエラーが発生します。
無視して構いません。

`systemd-resolved`を止めればいいってものでもなくて、これを止めるとaptコマンドが通らなくなるので、最後に調整します。

## DBの構築

まず、PostgresSQLとPDNSのPostgresSQLのライブラリをインストールします。

```sh
sudo apt-get install pdns-backend-pgsql postgresql
```

次に、PostgresSQLのユーザーを作成します。

```sh
sudo -u postgres createuser -P -s -e pdns
```

よくわかりませんが、パスワードがないとPDNS側でエラーが起こりました。

最後にスキーマを流し込みます。
`/usr/share/pdns-backend-pgsql/schema/schema.pgsql.sql`にスキーマがあるようです。

```sh
sudo -u pdns createdb pdns
sudo -u pdns sh -c "psql -U pdns -d pdns -a -f /usr/share/pdns-backend-pgsql/schema/schema.pgsql.sql"
```

## PDNSの設定

では、PowerDNSの設定をしていきましょう。
`/etc/powerdns/pdns.conf`の設定ファイルを変更していきます。

```pdns.conf
#################################
# launch        Which backends to launch and order to query them in
#
# launch=
launch=gpgsql
gpgsql-host=/run/postgresql
gpgsql-host=127.0.0.1
gpgsql-port=5432
gpgsql-dbname=pdns
gpgsql-user=pdns
gpgsql-password="password"
```

該当のコメントアウトの下に、追記しました。

## いざ、起動！！！

というわけで、起動してみましょう。

まず、先ほども話した通り、最近のOSはローカルホストにリゾルバがあるようなので、そいつを止めます。

```sh
sudo systemctl stop systemd-resolved
```

次に、pdnsサービスを起動します。

```sh
sudo systemctl start pdns
```

### ついでに自動起動する方法も

自動起動するには、systemctlに登録する必要があります。

```sh
sudo systemctl enable pdns
# ついでに邪魔なやつを止めておく
sudo systemctl disable systemd-resolved
```

## テスト

チュートリアル通りにちょっとテスト...

```sh
sudo -u pdns pdnsutil create-zone example.com ns1.example.com
sudo -u pdns pdnsutil add-record example.com '' MX '25 mail.example.com'
sudo -u pdns pdnsutil add-record example.com. www A 192.0.2.1
```

これは、exsample.comというゾーンを作成、MXを指定する。
その後に、wwwを指定しています。

```sh
dig +short <www.example.com> @127.0.0.1
# 192.0.2.1
dig +short example.com MX @127.0.0.1
# 25 mail.example.com
```

しっかり返ってくることがわかればOKです。

## 参考文献

https://doc.powerdns.com/authoritative/installation.html

https://doc.powerdns.com/authoritative/backends/generic-postgresql.html

https://doc.powerdns.com/authoritative/guides/basic-database.html
illustratorからWeb用画像を書き出す際の注意点

Web用の画像を書き出す際、いくつかの設定を確認することで、より良い品質の画像を作成することができます。特にデザインデータを受け取って画像を書き出す際に確認しておきたいポイントをまとめました。

## カラーモードとプロファイルの設定

まずはカラーモードとプロファイルの設定を確認します。これはWeb上での表示を最適化するために重要な設定です。

1. ドキュメントのカラーモードをRGBに変更
   - ファイル＞ドキュメントのカラーモード＞RGBカラー
   - Webでの表示に適したカラーモードに設定します

2. カラープロファイルの設定
   - 編集＞プロファイルの指定 から作業用RGB「sRGB」を選択
   - Web標準のカラープロファイルを使用することで、ブラウザでの表示が安定します

## フォントの処理

フォントは、Web用画像として書き出す際に特に注意が必要です。

1. フォントのアウトライン化
   - 書式＞アウトラインを作成
   - フォントを形状データに変換することで、どの環境でも同じ表示を保証します

2. アピアランスの分割
   - オブジェクト＞アピアランスを分割
   - 線や効果を塗りに変換することで、表示の一貫性を保ちます

## 書き出し時の設定

「スクリーン用に書き出し」機能を使用する際の重要な設定です。

1. ICCプロファイルの埋め込み
   - 書き出しダイアログで「ICCプロファイルを埋め込む」にチェック
   - カラー表示の一貫性を保つために必要です

2. アートの最適化
   - 「アートに最適(スーパーサンプリング)」を選択
   - これにより、ジャギーの発生や点線のぼけを防ぐことができます

## パフォーマンス設定の調整

最後に、描画の不具合を防ぐための重要な設定があります。

1. GPUパフォーマンスの設定
   - 環境設定＞パフォーマンス＞GPUパフォーマンスのチェックを外す
   - Illustratorを再起動
   - この設定により、複合パスの描画欠けや点線の消失を防ぐことができます

これらの設定を確認することで、より品質の高いWeb用画像を書き出すことができます。特にデザインデータを受け取ってコーディングする際には、これらの設定を確認することで、意図しない表示の乱れを防ぐことができます。
ReadMe

```mark:ReadMe.md
title: Kaizen Nagoya
emoji: 🏢
colorFrom: red
colorTo: gray
sdk: streamlit
sdk_version: 1.41.1
app_file: app.py
pinned: false
license: apache-2.0
short_description: this is mine
---

Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
```
AWSのECS経由で作られたEC2インスタンスを停止する

## 概要
ECS経由で作成されたEC2インスタンスをコンソール上から停止しても、数分後には別のインスタンスとして起動してしまい止める方法がわからなかった

![スクリーンショット 2024-12-17 14.53.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3963350/f5a23f4b-8edd-632a-05bf-e652041141c7.png)

## 解決方法
EC2 > Auto Scaling グループから設定を行うことでインスタンスを停止することができた。

キャパシティの概要　> 編集から、希望する容量タイプと最小の希望する容量を**0**にすることでEC2インスタンスが停止することを確認

![スクリーンショット 2024-12-17 14.56.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3963350/e2edd016-7bdf-7a1d-a489-7132f17dc668.png)



停止中になりました
![スクリーンショット 2024-12-17 15.01.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3963350/2c376499-5634-496a-17ec-24f12a978e58.png)


逆に起動を行いたいときは希望する容量タイプと最小の希望する容量を**1**にすることでEC2インスタンスが起動します

![スクリーンショット 2024-12-17 15.03.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3963350/f96758b7-8467-b7d2-9197-37d8cdd6d2dc.png)

起動していることを確認しました。
![スクリーンショット 2024-12-17 15.04.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3963350/c9e1622c-e709-4d3e-c25f-b61daf812cf8.png)

## 終わりに
今回使用した環境は勉強用の環境でしたが、業務などで使用しているテスト環境などは未使用時は停止しておくことで、不要な費用を抑えられるので活用いただければと思います。
マウスカーソルを変更してもデフォルトに戻ってしまう時の対処

マウスカーソルを好きなキャラクターに変更したいとき、ありますよね？
変更方法自体はググれば出てくるのですが、もう一度起動したときや再起動時に、元のカーソルに戻ってしまう現象が発生しました。その対処法です。

# 結論
**目的のカーソル画像(.curや.ani)を```C:\Windows\Cursors```に移す。**

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3951138/854b9bca-42ec-d754-9235-edc1584fdee7.png)

例えば、ダウンロードの保存場所```C:\Users\(ユーザ名)\Downloads```に置いたままだと、デフォルトに戻ってしまいます。
アドベントカレンダー2024まとめ

この記事は、[適応型ソフトウェア開発 アドベントカレンダー 2024](https://qiita.com/advent-calendar/2024/adaptive-software-development) の 25日目です。


## 適応型ソフトウェア開発

適応型ソフトウェア開発のアジャイルカレンダーを１人で完走した。
今までアドカレ完走はやったことがなかったが、達成することができた。

これ書いてる間に子供生まれたりして、記事書いてることを後悔していたシーズンもあるが、無事に終わって本当に良かった。

## やってみて
やってみた結果、文章をつらつら書く分にはストレスはあまりかからないことが分かった。
実際問題数欠くこと自体には全く問題がなかった。

どちらかというと質である。

素早く出すことは良いのだが、質が低いアウトプットが多かったと思う。
クオリティが低いものが多かった。

## 反省
１本の記事を出すとき、記事にかかる内圧をゴリゴリと高めることが最も大切だったかもしれない。

１つの記事に対する熱量や調査などをまとめて書き上げることで、良い情報ソースになりえる記事は誕生する。

今回はたくさん数を書いてみたが、そこに到達することはできなかった。

来年は、１人アドカレをやらず、１本の記事にがっつりと向き合うようなものをやってみたい。


## まとめ

おつかれえええええええええ！私！
よくやった！

という具合に、年末に多大な達成感を得ることができた。
それもマッチポンプに１人で環境を用意し、実現させることができた。

達成感を得られる環境というのは、人を成長させるための挫折を何度も生むことができる。
その機会を自ら作り出すことができたのは、とても尊かった。

もうやらない。
git error3


git error
https://qiita.com/kaizen_nagoya/items/d4b08ab5e13d7c4efde1

システムが落ちた。自分のPCからやろうとした。

git error2
https://qiita.com/kaizen_nagoya/items/0d6b32e9a20de6825c4a

フォルダが作ってなかった。ファイルをコピーしてなかった。

```sh
$ mkdir kaizen-nagoya
$ cp ../Download/LoRA_template_20241127.jpynb .
$ ./up.sh
git: 'lfs' is not a git command. See 'git --help'.

The most similar command is
	log
fatal: destination path 'kaizen-nagoya' already exists and is not an empty directory.
cp: ./LoRA_template_20241127.jpynb: No such file or directory
[master 5660046] Add model
 1 file changed, 9481 insertions(+)
 create mode 100644 llm/kaizen-nagoya/LoRA_template_20241127.ipynb
fatal: The current branch master has no upstream branch.
To push the current branch and set the remote as upstream, use

    git push --set-upstream origin master
```
メソッドチェーンでPythonコードの可読性を上げる

# メソッドチェーンとは
オブジェクトに対して複数のメソッドを連続して呼び出すテクニックです。  
メソッドチェーンを活用することで**中間の一時変数**を削減でき、**コードの可読性**を向上させることができます。

メソッドチェーンがよく使用される例として、DjangoのORMやPandasなどのライブラリが挙げられます。

### メソッドチェーンで書く場合と、一時変数を用いる場合の例
通常の書き方（一時変数を使用する場合）
```python
result = obj.method1()
result = result.method2()
result = result.method3()
```
メソッドチェーンを使用する場合以下のように書けます。
```python
result = obj.method1().method2().method3()
```

## メソッドチェーンを使える条件

メソッドチェーンを実現するには、**各メソッドが戻り値として自分自身(self)または同じ型のオブジェクトを返す**ように実装する必要があります。

### 簡単な例: メソッドチェーン対応クラス

```python
class Example:
    def __init__(self, value):
        self.value = value

    def add(self, num):
        self.value += num
        return self  # 自分自身を返す

    def multiply(self, num):
        self.value *= num
        return self  # 自分自身を返す

    def result(self):
        return self.value

# メソッドチェーンの利用
example = Example(10)
final_value = example.add(5).multiply(2).result()
print(final_value)
# 出力結果： 30
```

`add()` と `multiply()` メソッドは、自分自身 (`self`) を返すため、連続して呼び出すことができます。

## 実際に作成してみる

ここでは、PostgreSQLにSQLクエリを発行するための**クエリビルダー**を実装します。

初めにメソッドチェーンを意識せずに作成した場合と、メソッドチェーンを意識して作成した場合を比較します。

### メソッドチェーンなしのクエリビルダー
```python
class QueryBuilder:
    def __init__(self):
        self._query = ""

    def select(self, *columns):
        cols = ", ".join(columns) if columns else "*"
        self._query += f"SELECT {cols} "

    def from_table(self, table_name):
        self._query += f"FROM {table_name} "

    def where(self, condition):
        self._query += f"WHERE {condition} "

    def order_by(self, column, desc=False):
        direction = "DESC" if desc else "ASC"
        self._query += f"ORDER BY {column} {direction} "

    def build(self):
        return self._query.strip() + ";"

qb = QueryBuilder()
qb.select("id", "name", "age")
qb.from_table("users")
qb.where("age > 18")
qb.order_by("name")
query = qb.build()

print(query)

# 出力結果：
# SELECT id, name, age FROM users WHERE age > 18 ORDER BY name ASC;
```

この場合、各メソッドが`self`を返さないため、個別の呼び出しが必要です。
コードの行数が増え、中間状態のオブジェクトが残りやすくなります。



### メソッドチェーンありのクエリビルダー
次に、メソッドチェーンに対応したバージョンです。
```python
class QueryBuilder:
    def __init__(self):
        self._query = ""

    def select(self, *columns):
        cols = ", ".join(columns) if columns else "*"
        self._query += f"SELECT {cols} "
        return self

    def from_table(self, table_name):
        self._query += f"FROM {table_name} "
        return self

    def where(self, condition):
        self._query += f"WHERE {condition} "
        return self

    def order_by(self, column, desc=False):
        direction = "DESC" if desc else "ASC"
        self._query += f"ORDER BY {column} {direction} "
        return self

    def build(self):
        return self._query.strip() + ";"


# クエリビルダーを使ってクエリを構築
query = (QueryBuilder()
         .select("id", "name", "age")
         .from_table("users")
         .where("age > 18")
         .order_by("name")
         .build())

print(query)
# 出力結果：
# SELECT id, name, age FROM users WHERE age > 18 ORDER BY name ASC;
```

## まとめ
メソッドチェーンを意識することでよりシンプルで可読性が高いコードを書くことができます。
ぜひメソッドチェーンを活用してみてください！
アジャイルの始祖に触れて感じたこと

この記事は、[適応型ソフトウェア開発 アドベントカレンダー 2024](https://qiita.com/advent-calendar/2024/adaptive-software-development) の 24日目です。

## アジャイルの始祖
適応型ソフトウェア開発は、アジャイルの始祖にあたるフレームワークだ。
今回それを真剣に取り組んでみたとき、様々な学びがあった。


## 学び
アジャイルの始祖に取り組んだことで分かったことがいくつもある。
それをこの記事では紹介したいと思う。

### 現代開発環境でも問題なく使える
古の知識やプラクティスも現代のモダン開発でも有効に利用できることが分かった。
どんどん出てくる新しい知識も大切だが、すでに枯れてしまった古の知識を使って最新に立ち向かっていくのも悪くない。

### 根本的な課題は当時から変わっていない
古い知識を仕入れながら進めていたが、実際のところ何も陳腐化していなかった。
根本的に発生する課題は、人間関係であったり、適応課題ばかりだった。

その適応課題の質は当時から何も変化していない様子で、技術的な課題よりもフォーカスされていることが多かった。

私たちにとってはかなり使えるものだった。

### アジャイル宣言の意味
スクラムフレームワーク、Lean UX などいろいろある。

でもその根源で大切にしなければならない宣言の意味するところが何なのかをわかっていなかった。

しかし、この原初のフレームワークである適応型ソフトウェア開発を進めることで、心から理解できたと思う。

## まとめ
アジャイルの始祖に触れること。
そこから得られることはたくさんあった。

この古の知識を使って、近代的な課題にも殴り込みをかけていきたい。
Deno で JSX に型をつける

Deno を使って JSX に型をつける方法の紹介です。

React の JSX に型をつける場合は、以下のように記述します。

```tsx
/** @jsxImportSource npm:react@^19.0.0 */
/** @jsxImportSourceTypes npm:@types/react@^19.0.0 */

// @ts-types="npm:@types/react@^19.0.0"
import { useState } from "npm:react@^19.0.0";

export default function App() {
  const [count, setCount] = useState(0);
  return <div>Hello world {count}</div>;
}
```

以上の書き方で、JSX 部分と、React からのインポート部分に型が付きます。

![Screenshot 2024-12-17 at 14.22.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13825/0c938052-893b-cb49-8493-c74e4ccd2b36.png)

![Screenshot 2024-12-17 at 14.37.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13825/4ed7b373-1b99-914b-0e86-7b44a6aaa96b.png)

解説

[jsxImportSource](https://www.typescriptlang.org/tsconfig/#jsxImportSource) は jsx のファクトリー関数を指定するためのプラグマです。

内部的には、このプラグマに指定したパッケージから以下のようにファクトリー関数がインポートされ、JSX タグのトランスパイルに利用されます。

```js
import { jsxs as _jsxs } from "npm:react@^19.0.0/jsx-runtime";
import { useState } from "npm:react@^19.0.0";
export default function App() {
    const [count, setCount] = useState(0);
    return _jsxs("div", { children: ["Hello world ", count] });
}
```

[jsxImportSourceType](https://deno.com/blog/v1.43#jsximportsourcetypes) は Deno の独自なプラグマで、`jsxImportSource` で指定した jsx ファクトリー関数に型をつけるために指定します。ここでは、[DefinitelyTyped](https://github.com/DefinitelyTyped/DefinitelyTyped) の `npm:@types/react@^19.0.0` を型として指定します。

`@ts-types` は1行下の `npm:react@19.0.0` のインポートに対して型を与えるプラグマです (react はパッケージに型情報が内包されていないため、このような `@types/react` の明示的な指定が必要になります。例えば、preact の場合はパッケージに型情報ファイルが同梱されているため、このような `@ts-types` の指定は不要になります)。

### deno.json で指定する

`jsxImportSource` と `jsxImportSourceType` は上記のようにソースコード中のプラグマで指定することも出来ますが、`deno.json` の中に記述する事も出来ます。ファイル数が多い場合などはこちらの記述方法の方が重複を減らす事ができます。

上のプラグマ指定と同値な `deno.json` の指定は以下になります。

```json
{
  "compilerOptions": {
    "jsx": "react-jsx",
    "jsxImportSource": "npm:react@^19.0.0",
    "jsxImportSourceTypes": "npm:@types/react@^19.0.0"
  }
}
```

上の記述をすると、ソースコード内のプラグマの記述は不要になります。

### `preact` の場合

React の代わりに preact を使う場合は、記述が少し簡単になります。preact はパッケージ内に型情報が同梱されているため、`@jsxImportSourceTypes` や `@ts-types` の指定が不要になります。

```ts
/** @jsxImportSource npm:preact@^10.25.2 */

import { useState } from "npm:preact@^10.25.2/hooks";

export default function App() {
  const [count, setCount] = useState(0);
  return <div>Hello world {count}</div>;
}
```

preact の場合は以上の記述で、JSX とパッケージからの import に型がついた状態になります。

この `jsxImportSource` を `deno.json` 内に記述したい場合は、React の場合と同様に

```json:deno.json
{
  "compilerOptions": {
    "jsx": "react-jsx",
    "jsxImportSource": "npm:preact@^10.25.2"
  }
}
```

となります。

Happy React Programming in Deno!

---

注: 他にも esm.sh を使う方法など、いろいろな別解があります。本記事では、Deno 本体の機能のみを使って JSX に型をつける方法を紹介しました。
edgeでIEモードに切り替える方法

# edgeでIEモードに切り替える方法

（1）ブラウザの「設定」画面 ＞ 「既定のブラウザー」画面に遷移する。

（2）「Internet Explorer モード (IE モード) でサイトの再読み込みを許可」のプルダウンを「許可」にする。
　※設定を有効にするには、ブラウザの再起動を求められる場合がある。
　※ここまでの設定のみでIEモードで閲覧出来る場合があり。下記を試す。
　サイト等のURLを閲覧した状態で、ブラウザの「…」 ＞ 「Internet Explorer モードで再読み込みする」を押下。


（3）「Internet Explorer モード ページ」の「追加」を押下して、IEモードで見たいサイト等のURLを入力。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1162001/5ad91891-1eff-9512-c2ec-66554ec94499.png)

----
（4）IEモードで閲覧出来ているかを確認

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1162001/3b6a7f98-ba95-b731-3526-d6ed7e66690a.png)
アジャイルフレームワークと適応について

この記事は、[適応型ソフトウェア開発 アドベントカレンダー 2024](https://qiita.com/advent-calendar/2024/adaptive-software-development) の 23日目です。

## アジャイルフレームワークと適応について

今回、適応型ソフトウェア開発に対して、トライしていくシーズンだった。

しかし、ここで得た適応力というものを抽象化すると、どのシーンでも有効であることが分かった。

### 適応力の内訳

適応力の内訳は、どのチームでも役に立つことが多いと考えている。

#### 素早い意思決定
わからない事に出会ったとき、とにかく素早い判断をし続けることで、チームの適応力は上がっていく。
その結果、より素早くカオスを消化し、ユーザーに価値を届けることができるようになるだろう。

#### 豊かな人間関係
どれだけ判断をする事や捨てることにストレスがあるのか。
これは理由なく大きな負担がかかってくる。

せっかく作ったものを捨てるのだ、それはそうだと思う。
徒労に終わった。そんな気持ちにもなる。
しかし、すべてを布石にして突き進むことが大切なのだ。

この布石を打てたことをチームの中でほめたたえながら進めることで、さらなる適応力を発揮する。
これができるようになるためには、お互いに尊敬している気持ちを持たなければ無理である。


#### 失敗を恐れない
むしろ失敗をするべきだ。正しい方向へ逸脱する行為なのだから。

失敗というのは、間違った方向に突き進んでいることが明らかになる現象であるため、たくさん素早く発覚したほうが良い。

これを開示することも恐怖があると思うが、それも尊敬や人間関係で突破することが大切だった。

### まとめ
アジャイル宣言でまとめられていることは非常に大切なものばかりだ。
トランスポート・プロトコルと輻輳制御

>ネットワーク容量が増加すると、TCPの従来の動作モードのいくつかは最適な性能を発揮できなくなる。特に、TCPなどはのコネクション指向プロトコルは、コネクション設定のオーバーヘッドが大きく、バッファが大きいネットワークでは性能が低下する可能性がある。

### QUIC　スループットと遅延特性を改善する
>QUICは当初Quick UDP Internet Connectionsとして提案されたものであり、TCPのスループットと遅延とく性を改善することを目的としたトランスポート・プロトコルである。

>QUICはUDP上で実行され、主な目標は、Webプロトコルなどのアプリケーション・プロトコル高速化することであった。

>QUICは単一のUDPフローとしてこれらのコネクションを多重化する。また一つのWebオブジェクト転送が遅れた場合には、他のオブジェクトの転送をブロックしないようにする

> QUICはUDPに基づいているため、それ自体は信頼性の高いトランスポートを実現できない。しかし、あるストリームで一部のデータがロスした場合でも、他のストリームにデータを転送し続けることが可能である。これにより、結果的に伝送誤り率の高いリンクの性能を上げられる

* 多重化とは
* ブロックとは
* ピギーバックとは

### バッファブローでバッファがいっぱいになって輻輳になる
>ボトルネック・バッファが大きい場合、前述のようにロスベースの輻輳制御アルゴリズムでは、バッファを埋めることは、結局バッファブローと(bufferbloat:バッファ膨張)と呼ばれる現象を起こす。

### 伝送速度が速くなりすぎてバッファがいっぱいになって返すべき通知を返せない
>ネットワーク経路に沿ったネットワーク・デバイスのバッファが大きすぎると場合、輻輳ウインドウが大きいTCP送信者は、ロスの通知を受け取るまでに、ネットワークの容量を遥かに超える速度で送信する。ネットワーク中にあるバッファがいっぱいになると、送信速度が早すぎるという送信者への輻輳通知が遅れる。（つまり、パケットがドロップしに）。重要な点は、大きなバッファ内で送信者へのパケットが他のパケットの後ろに並んでいて遅延が増加する点である。

### BBRはボトルネックとなる帯域と往復の伝搬遅延を測定、推測している
>BBRの背後にある主な考え方は、ボトルネックとなる帯域（ボトルネック帯域:bottleneck bandwidth)と往復の伝搬遅延(round trip propagation delay)を測定し、これらのパラメータの推定値を使用して、正確に適切な動作点を送信することである。従って、BBRは、ボトルネック帯域と往復の伝搬遅延を"継続的"に追跡する。TCPではすでに往復時間を追跡している。一方、BBRはこれを拡張してトランスポート・プロトコルの配信速度(delivery rate)を追跡する。BBRは、ボトルネック帯域を、特定の時間枠(通常は6~10往復)で測定された配信速度の最大値として計算する。

### 常に情報を更新している
>BBRの鍵は、ボトルネック帯域とそれに応じた往復時間お見積りを常に更新できるかにある。確認通知の一つ一つは、往復時間と平均配信速度に関する情報を更新すると同時に、配信速度が(リクエスト・レスポンス・プロトコルの場合のように)アプリケーションによって制限されていないことを確認する。

### ボトルネック帯域レートに合わせる
>ボトルネック帯域レートに一致するようにデータの送信感覚、すなわちペースを調整する方法である。この速度であるページングレート(pacing rate)は、BBRベースの輻輳制御の重要なパラメータである。定常状態では、BBRが送信する速度は、単にボトルネック帯域と往復時間の関数である。BBRはボトルネック帯域レートにペースレートを正確に合わせて、転送中のデータに有用な帯域・遅延積になる時間が長くなるようにして、遅延を最小化する。ボトルネック・レートへは非常に早く収束する。

* ボトルネック帯域とは
* ペースレートとは

https://bookplus.nikkei.com/atcl/catalog/23/03/16/00728/

### 感想
しっかり理解できるようになる
適応型ソフトウェア開発を学んだ結果得たもの

この記事は、[適応型ソフトウェア開発 アドベントカレンダー 2024](https://qiita.com/advent-calendar/2024/adaptive-software-development) の 22日目です。

## 適応型ソフトウェア開発を学んだ結果得たもの

これはたくさんある。

決まったルートのない進行を進めるとき、何をすると有効であり、何をすると失速するのかを常に考えながら望まなければならない。
そのため、スクラムフレームワークを脳死状態で続けているよりもはるかに思考量が増えた。

その中でこれからも役に立つであろう学びを共有する。

### 「失敗」は成功に向けて逸脱する行為
失敗はミスではない。
失敗は、成功方向に向けてレールが脱線することであるという教えがあった。

その気持ちがとても大切で、小さく意思決定をし、速攻でそれにこたえ、適切に評価する。
その評価の時、失敗してしまったとしても、それは正しい方向に導かれているだけである。

そう考えると、失敗が怖くなくなった。
うまいスケートボードのプレイヤーもよく転ぶものだ。


### 豊かな人間関係の必要性
豊かな人間関係があることで、組織の力はまるで変ってくることを知った。

そして適切に形成されたその人間関係は、圧倒的な適応力につながってくる。
その結果、ユーザーによりよいものを提供することが可能になる。

より良いものは、より優れた関係性の中から生まれる。
これは大切な学びだった。

### フレームワークは絶対じゃない
フレームワークは所詮道具だった。
信仰するものでもない。

今、この環境、この瞬間に適応できる道具を適切に選び、行使する事。
これが最も重要で、有効であることを知った。



## まとめ

このように普段使わないフレームワークを触ることで、気づきを多く得ることができたのである。