OmniAICreator/Qiita-1.07M huggingface dataset:
【OSリプレース】インフラレイヤにおいて新AWS環境はどう便利になったのか

# 初めに
ざっくり解説です。
細かいところは気にしないでください。
あと、新環境のwebcrewのシステムすべてにこの構成が当てはまっているわけではありません。あくまで、大枠のところです。

## 事の発端
もともと2020年にオンプレからAWSへの移行が行われたわけですが、構成自体はそのまま移植した感じで、全く最適化がされていませんでした。

最適化というのは、AWSに合った構成にすることで設定の管理のしやすさやコストの削減などを行うことです。

例えば外部からHTTPなどでアクセスしてくる際に必要となるロードバランサーですが、オンプレ時代から使用しているBIG-IPという製品をそのまま移植していました。
本来であれば、AWSにはAWS環境のためのロードバランサーが提供されており(ELB)、"最適化"という観点では、こちらのロードバランサーに構成を変更する必要がありました。

そのため最適化された環境へのリプレースが必要でした。

また、クラウド環境への最適化とは別に、下記の理由からもOSリプレースをする必要がありました。
### CentOS7のEOSL
ウェブクルーのサーバの半分程度がCentOS7で動いていますが、2024年2月でサポートが切れるということが大々的に発表されていました。
(まあ、サーバのもう半分のCentOS5系は2014年でサポートが切れているんですが。。)

そのため、OSを何か別のものにリプレースする必要がありました。

### リザーブドインスタンスの期限切れ
AWSはEC2インスタンスをまとまった日数分買うとある程度値引きされるシステム(リザーブドインスタンス)というものがあるのですが、こちらの期限が2024年の2月でした。
ですので、ここまでにEC2をなるべく新しい環境に移行して再購入する分を減らそうとしていました。

# 構成図

## これまでのwebcrewの構成
これまでのウェブクルーのWEBサイトはざっくり下の図のような構成でした。

![2023-12-12 135406.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2976182/599ea169-aca2-37ca-897e-cc0352f33313.png)

上記でも説明しましたが、オンプレの構成をそのまま移植した感じで、
AWSの便利な新しい機能を全く使っていなかった構成でした。

## 新環境移行後のwebcrew

phoenixは新環境に移ったわけですが、ざっくりと下記のような構成になっています。

![2023-12-12 135340.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2976182/4ef03b66-91d3-7e9f-3993-1a9446dbf10e.png)

### ロードバランサ
BIG-IPの代わりに、ALBというロードバランサを使用してロードバランシングを行っています。
また、webコンテナとappコンテナの間にNLBというロードバランサを新たに配置しています。

ALBやNLBは接続されているECSコンテナに対してずっとヘルスチェックを行っています。
ヘルスチェックとは、冗長化している2つのコンテナに対して、「生きていますか？」の信号を送ります。
返事が返ってきたらヘルスチェックはOK。ALBはそのコンテナに対してトラフィックを流します。
もしもNGが返ってきて、コンテナが異常状態になっていた場合、ALBはECSに信号を送りコンテナを再作成します。

これは、NLBであっても同様の働きをします。
特に、これまでのアーキテクチャでは、Apache⇒Tomcatのルーティングにロードバランサを用いていなかったので、tomcatが片方でも落ちるとサイトが落ちるという欠陥を持っていました。
Apache⇒Tomcat間にロードバランサを導入することで、tomcatの動作が不安定になった場合ルーティングを行わないようにしてコンテナを再作成するという作業を自動で行ってくれるようになりました。

### EC2とECS
AWSにはマネージドサービスとアンマネージドサービスという概念があります。

EC2は、アンマネージドサービスで、運用の多くを自分たちで管理する必要がありました。
ソフトウェアバージョン管理なども行わなくてはいけないですし、サーバが不調になった場合は、手動で再起動なんかをしなくてはいけませんでした。(どうにか自動でやる方法もあるにはあります)

また、EC2特有の不定期の再起動なんかも必要でした。

ECSはマネージドサービスで、運用の多くをAWSが行ってくれます。
コンテナが異常状態になったときに自動で再起動してくれたりします。

### マネージド証明書
ALBはACMというマネージドな証明書管理システムを持っており、これによってSSL証明書の更新も自動で行ってくれるようになりました。

2か月に一回行っている証明書の更新は、いまはほとんどGCP側のものしか残っていません。

### その他
上記は、「インフラ観点での便利になったこと。」でしたが、今回のリプレース作業では、javaのバージョンをjava6からjava8に変更しており、それによる恩恵も多く受けています。

phoenixの切り替え後は実際に障害は減っていますし、java6環境のままだったら障害になっていた場面も少なくありません。

# まとめ
まだまだOSリプレースは全然終わっていませんが、ウェブクルーのシステムがイマドキのシステムにアップデートされるように作業していきます。
テストケースとは何か（初心者向け）

# はじめに
この記事ではテストケースとは何かについて言葉の意味を理解するための情報をまとめています。初心者向きの内容になりますので、有識者向けの内容ではありません。

## テストケースとは何か？

ソフトウェアやシステムが期待通りに動作するかを確認するための具体的な手順や条件の集まりです。

開発したソフトウェアに不備がないかをテストすることは、ソフトウェアの品質を確保することに繋がります。ユーザーは常に高品質なソフトウェアを期待しているため、1箇所でも欠点があれば、ユーザーの満足度を著しく低下させます。

## テストケースのは表形式で作成される

テストケースは通常、以下のような表形式で作成されます。
その中でもテストケースIDとは、特定のテストケースを探しやすくしたり、他のドキュメントに資料を作成した場合の報告などで使うことができます

| テストケースID | 説明 | 前提条件 | テスト手順 | 期待される結果 |
| --- | --- | --- | --- | --- |
| TC_Login_001 | 正常なログイン | 有効なユーザー名とパスワードが提供されている | 1. ブラウザでログインページにアクセス<br>2. 有効なユーザー名を入力<br>3. 有効なパスワードを入力<br>4. 「ログイン」ボタンをクリック | - ログイン後、正常にダッシュボードページにリダイレクト<br>- 不正な入力時はエラーメッセージが表示 |
| TC_Login_002 | 不正なログイン | 無効なユーザー名またはパスワードが提供されている | 1. ブラウザでログインページにアクセス<br>2. 無効なユーザー名を入力<br>3. 無効なパスワードを入力<br>4. 「ログイン」ボタンをクリック | - エラーメッセージが表示され、ログインは拒否される |
| TC_Login_003 | ログアウト | ログイン済みである | 1. ログアウトボタンをクリック | - ログアウト後、ログインページにリダイレクト |


## テストケース作成の順番について

テストケースを作成するにはいくつかのステップが存在します

### 1.開発したソフトウェアの要件を理解する

ソフトウェアの要件とは、そのソフトウェアが持つべき機能や性能、制限事項のことです。

例えば、スマートフォンのスケジュール帳アプリを開発する場合、テキスト入力や表示機能の実装が求められます。同時に、アプリがスマートフォンの動作を遅くしないために容量を制限する必要もあります。これらの必要条件をまとめたものが要件であり、それをワードやエクセル、またはホワイトボードやノートなどに整理することを要件定義と言います。

#### 要件を理解するためにはどうすれば良いのか？

要件仕様書や設計文書を熟読することが重要です。また、開発チームへの質問や実際の現場で聞き込みをすることでも、不明な点を解消できます。



### 2.テストケースの目的と範囲を設定する

テストケースの目的は、ソフトウェアの特定の部分が正しく動くかを確かめること。たとえば、ブログ開発ではログイン機能や記事の保存をチェック。このように範囲を絞り、どこをテストするかを明確にすることで、効率的なテストを行います。

### 3.テストケースを作成する

入力データ、操作手順、期待される結果などを具体的に上記のような表形式で記述します。

例えば、ログイン機能の場合、有効なユーザー名とパスワードでログインしたら成功するか、失敗したらエラーメッセージが表示されるかなど、具体的な動作を書き出します。これにより、テストを正確に実行し、ソフトウェアが望ましい振る舞いをするかを確認します。


### 4.テストケースのレビューについて

テストケースを作成した後はチームメンバーや関係者によるテストケースのレビューを行います。これにより不足しているテスト範囲や特定や、テスト方法の改善などを図ることができます

## テストケースが実行できるか確認する

レビューを通過したテストケースは、実際のシステムや環境で実行可能かどうかを確認する必要があります

### 1.実行可能性の確認
レビューを通過したテストケースが、実際のシステムや環境で実行可能かどうかを確認します。必要なテストデータやリソースが利用可能か、テスト実行の準備が整っているかを確認します。

### 2.テスト計画の作成
テストケースを含むテストの実行計画を立てます。テストケースの実行順序や優先度、実行担当者などを含む計画を作成します。

### 3.テスト環境の準備
テストを実行するための適切なテスト環境を準備します。これには、必要なハードウェア、ソフトウェア、テストデータ、設定などが含まれます。

### 4.テストの実行
レビューを通過したテストケースを実際のシステムや環境で実行します。テストケースの実行、結果の記録、問題の特定などを行います。

### 5.実行結果の報告と分析
テストの実行結果をまとめ、報告書を作成します。成功したテストケース、発見された問題やバグ、不具合の優先度などを報告し、必要な場合は修正のための指示を提供します。

これらの手順は、テストケースのレビューがクリアされた後の一般的な流れです。実際のテストを実行し、その結果を評価・報告していくことで、システムの品質や安定性を確保するための重要なプロセスです。
今年の振り返り・研修事業編

:::note
執筆時点現在の受講者や過去の受講経験者が本稿または筆者アカウントの過去記事を閲覧する事を想定しているので、本稿で特定個人または事業社を特定できないように最大限配慮している。
:::
:::note warn
上記対象者に限り、懸念点について場合はコメント欄ではなく、DMやメールなどでご連絡いただきたい。
:::

## 対象者
- フリーランス講師の事業に興味がある方
- スカウター・マーケター

本稿はミートアップ向けに書く事になるが、ついでにセルフPRを含む内容である

## 書かないこと
- 学びのある有意義な話
- エンジニア向けの話
  - エンジニア講師向けの事業トークがメイン

対象がニッチすぎて、刺さる人にしか面白くない内容になってしまった。

## 今年目標（研修事業）
- IT教育を去年までの範囲（新卒・リスキリング）から広げる
  - 小中高生にリーチ
- （追加）エンジニアリングだけでなく、AI研修にも着手する
  - AI研修コースに参画
  - （開発事業から）生成系AIのプロンプトエンジニアリングの実績
- 幸せなエンジニアを増やす
  - エンジニア講師指導：↓今年は実績なし
  - エンジニア教材作成：↓今年は実績なし（ただし、非エンジニア向けIT教材作成の実績）

その他：エンジニア講師コミュニティに参画

## それぞれの所感
### IT教育の対象拡大
学生指導のアプローチとして、正規のルートだと家庭教師とか個別塾など、いわゆるITではなく学校向けの5教科指導が近道。
エンジニアならいわゆるプログラミングスクールや児童ワークショップなどが近いが、スポット案件になりがち。
専門学生向けなら非常勤講師という選択肢もある。

探せばかなりやりようはあった。
ただし、まだまだ早期プログラミング教育の需要は低いように思う。いわゆるレゴとかピアノとかスイミングスクールカテゴリにすら入っていない。
→ただし、独学でプログラミングを勉強している学生も多く、非常に精力的に活動されているようだ。

なお、メンターマッチングサービスなどでは、主にリスキリング者が多いため学生へのリーチには使えなさそうだ。

### AI研修
いわゆるChatGPTとかプロンプトエンジニアリングなど。
身近な企業の課題を見ると、生成AIを活用する話よりまずはDXからやらないとダメなのでは？というシーンも多く、AI研修の前にDX研修の需要が高そうだ。
とはいえDX研修だけではパンチが弱いので、AI研修と題してDX部分もやる事になりそう。
特にセキュリティへの関心が高いため、AIのセキュリティよりも全般としてセキュリティリスク研修を入れてからAIの話をして、セキュリティを絡めるようにステップアップ方式でなければ本当の意味で浸透させるのは困難と見受ける。

まずそもそもとして、AI研修の需要が高まるのはまだまだ先の話になりそう。
（企業の競争力の観点で言えば、研修などの忖度なく早期に導入してほしい）

### 幸せなエンジニアを増やす
企業ごとにAIを特化させる需要も高まりそうなのでデータサイエンティストまたはAIエンジニアの需要も高まりそう。
AIに限った話ではないが、そろそろエンジニアも各分野ごとに専門のエンジニアが必要になる事を周知していった方が良さそう。

後発のプログラミングスクールは「人気だから」とか「先駆者がいるから」ではなく、「案件の需要」に注目してエンジニアを養成するというPRと、受講者に卒業後の明確な進路などを提示してあげないと中途半端なエンジニアが増えるだけになってしまう。
もう少し企業間連携（SESでもエージェントでも）が強まれば良いのに、と思うが、講師の立場からは提案が難しいのも事実である。

個人レベルから見ると、漠然と「エンジニアを目指す」という目標から、もう一段掘り下げて「エンジニアになって何がしたいのか」を明確にしてあげられれば、エンジニアになるモチベーションを高められる。
そのためのアプローチとして、これからエンジニアになりたい方は当然情報がない（少ない）ので、自身の体験談や各エンジニアの専門分野とできること、そしてそうなっていった経緯などが話せるとより具体化していけるだろう。

## 来年目標
他者を指導する際は「目標には数字を入れなさい」と言っている手前、自分の目標に数値を入れられないのが歯痒くて仕方ない。

- 幸せなエンジニアを増やす
  - エンジニア講師の質を高める
  - 研修の質を高める（受講生ができること）
    - 本アドベントカレンダーの初回側の記事はこれを意識
- IT教育を去年（2023年）までの範囲（新卒・リスキリング）から広げる
  - 【課題】新人研修の時にエンジニアリングを知って、そこから取り組んで適正を疑う
  - 【提案】もっと早い段階から適性を確認する機会を提供したい

嫌な話だが、全ての受講者がエンジニアになりたい、と思って勉強しているわけ**ではない**事を認識して、「エンジニアになってxxがしたい！」に昇華していけるよう、講師スキル（人間力）を高めていく。
特に子供には優しくありたい。

（開発エンジニアとしての話はどこかでするかも？）
"VSCODEでGitHub Copilotを使おう: アカウントの切り替えと検索エンジンのトラブルシューティング"

タイトル: "VSCODEでGitHub Copilotを使おう: アカウントの切り替えと検索エンジンのトラブルシューティング"

導入:

VSCODEを使用してGitHub Copilotを導入しようとする際、ログインや検索エンジンのトラブルが発生することがあります。特に、Chromeでログインしていたアカウントが、Safariで別のアカウントになってしまい、これがChromeにも影響を与える可能性があります。この記事では、アカウント切り替えの問題に焦点を当て、特にSafariでログインしていたアカウントをログアウトする手順を解説します。

1. GitHubアカウントの切り替え:

VSCODEでGitHubにログインしようとすると、予期せぬアカウントが接続される問題に遭遇することがあります。特に、Chromeでログインしていたアカウントが、Safariで別のアカウントになってしまい、これがChromeにも影響を与える可能性があります。

解決手順:

SafariでログインしていたGitHubアカウントをログアウトします。
VSCODEでGitHubに再度ログインし、正しいアカウントが接続されることを確認します。
2. 検索結果のファイルが開けない問題:

GitHubでコードを検索し、Chromeで開こうとすると、".....ファイルは開けません"という問題にぶつかることがあります。この課題は、SafariでログインしていたGitHubアカウントが影響を与えている可能性があります。

解決手順:

SafariでログインしていたGitHubアカウントをログアウトします。
検索結果のファイルが開けない問題が解消されたことを確認します。
結論:

SafariでログインしていたGitHubアカウントをログアウトすることで、アカウントの切り替え問題と検索結果のファイルが開けない問題が解決できました。これにより、VSCODEでGitHub Copilotをスムーズに利用できるようになります。
Mac環境のそれから Ver.2023-12

## 背景
[前回](https://qiita.com/atakig/items/61da94d77e8b9ea6eba9)、[前々回](https://qiita.com/atakig/items/16c191199b2d3fd159df)とBeeX AdventcalendarでMacBook Airの環境設定について書いてきました
それの第三弾となります

### IDE/エディタ
[Neovim](https://qiita.com/atakig/items/97413b70c6012c076136)に乗り換えました
快適に使えています

メモ帳がわりの、[Moped](https://apps.apple.com/us/app/moped-text-editor/id1477419086?mt=12)も導入しました


### ターミナル
[WezTerm](https://wezfurlong.org/wezterm/index.html)を使っていましたが、発色の綺麗さ、動作の安定度で結局[iTerm2](https://iterm2.com/)に戻りました
Tmux終了時に、良くクラッシュするので、[Zellij](https://github.com/zellij-org/zellij/tree/main)に乗り換え予定です

### shell
変わらず、[fish](https://fishshell.com/)を愛用しています
気分によって[nu](https://www.nushell.sh/ja/)も使います

#### [asdf](https://asdf-vm.com/)
pythonやnodeのバージョンマネージャーをこちらにしました
どちらかのバージョンマネージャーがfishの起動をめちゃくちゃ遅くしていたので

#### [CodeWhisperer for command line](https://docs.aws.amazon.com/codewhisperer/latest/userguide/command-line-getting-started-installing.html)
基本、fishの自動補完の方が早いのですが、aws関係のうろ覚えのオプションもバンバン候補を出してくれるのが気持ち良いです

#### [Task](https://taskfile.dev/)
まとめてコマンドを実行してくれたり、コマンドラインパラメータのテンプレート化機能等々、コマンドライン実行の抽象化を良い感じに行なってくれます
ECRへのpushが1コマンドで済むようになったのは大助かりです

### 日本語変換
[AquaSKK](https://github.com/codefirst/aquaskk)をやめ、MacOSデフォルトのものを使っています
PowerPointで資料を作成する際のキーバインドの被りや、それに伴う複数日本語変換切り替えのコストを考えると、MacOSのもの単独で使うのが良いという結論になりました

### [Toggl](https://toggl.com/)
工数（時間）管理ツールです
手放せません

### キーボード
ロジクールやApple純正のものも試しましたが、HHKBの日本語レイアウトに落ち着きました
日本語モードと英字モードの行ったり来たりが多いので、変換キー/無変換キーで瞬時に切り替えられるのと、印字されたキーの通りに入力されるのは、大きなメリットですね
出張の時はApple純正を持っていく予定です

### マウス
あちこちぶつけるので、家にあった[ケンジントンのトラックボール](https://www.kensington.com/ja-jp/p/%E8%A3%BD%E5%93%81/%E3%82%A8%E3%83%AB%E3%82%B4%E3%83%8E%E3%83%9F%E3%82%AF%E3%82%B9/%E4%BA%BA%E9%96%93%E5%B7%A5%E5%AD%A6%E3%81%AB%E5%9F%BA%E3%81%A5%E3%81%84%E3%81%9F%E5%85%A5%E5%8A%9B%E3%83%87%E3%83%90%E3%82%A4%E3%82%B9/%E3%82%B9%E3%83%AA%E3%83%A0%E3%83%96%E3%83%AC%E3%83%BC%E3%83%89%E3%83%88%E3%83%A9%E3%83%83%E3%82%AF%E3%83%9C%E3%83%BC%E3%83%AB/)に変えて良い感じだったので、Amazonのセールで買った、ワイヤレスの[ロジクール M575S](https://www.logicool.co.jp/ja-jp/products/mice/m575s-ergo-wireless-trackball.910-005877.html)を使っています


## 終わりに
今回の内容がどなたかの快適な環境構築の1助になれば嬉しく思います
【PostgreSQL】pg_locksについて

## pg_locksとは？

pg_locksはPostgreSQLのシステムビューの一つで、現在のデータベース内で持たれている全てのロック情報を提供します。ロックとは、同時に多くのユーザーがデータベースにアクセスする際に衝突を防ぐためのメカニズムで、それぞれのトランザクションがデータに正しくアクセスできるようにする役割があります。

## pg_locksの使い方

pg_locksは、SELECTクエリを使用してアクセスできます。例えば、次のようにすべてのロック情報を表示することができます。

```SQL
SELECT * FROM pg_locks;
```

このクエリを実行すると、各ロックに関する詳細な情報が表示されます。これには、ロックが取得されているオブジェクトのID、ロックのタイプ、ロックのモード、ロックが取得されているセッションのIDなどが含まれます。

| 列 | 型 | 説明 |
| :---: | :---: | :--- |
| locktype | text | ロックオブジェクトのタイプです。 relation、extend、frozenid、page、tuple、transactionid、virtualxid、spectoken、object、userlock、advisoryのどれかです。 |
| database | oid （参照先 pg_database.oid） | ロック対象が存在しているデータベースのOID。対象が共有オブジェクトの場合はゼロ。対象がトランザクションIDである場合はNULL。 |
| relation | oid （参照先 pg_class.oid） | ロックの対象となるリレーションのOID。対象がリレーションではない場合かリレーションの一部である場合はNULL。 |
| page | int4 | ロックの対象となるリレーション内のページ番号。対象がタプルもしくはリレーションページではない場合はNULL。 |
| tuple | int2 | ページ内のロックの対象となっているタプル番号。対象がタプルではない場合はNULL。 |
| virtualxid | text | ロックの対象となるトランザクションの仮想ID。対象が仮想トランザクションIDではない場合はNULL。 |
| transactionid | xid | ロックの対象となるトランザクションのID。対象がトランザクションIDではない場合はNULL。 |
| classid | oid （参照先 pg_class.oid） | ロックの対象を含むシステムカタログのOID。対象が一般的なデータベースオブジェクトではない場合はNULL。 |
| objid | oid （いずれかのOID列） | システムカタログ内のロックの対象のOID。 対象が一般的なデータベースオブジェクトでない場合はNULL。 |
| objsubid | int2 | ロック対象の列番号（classidとobjidはテーブル自身を参照します）、その他の一般的なデータベースオブジェクトではゼロ、一般的ではないデータベースオブジェクトではNULLです。 |
| virtualtransaction | text | ロックを保持、もしくは待っている仮想トランザクションID。 |
| pid | int4 | ロックを保持、もしくは待っているサーバプロセスのプロセスID。 ただしプリペアードトランザクションによりロックが保持されている場合はNULL。 |
| mode | text | このプロセスで保持または要求するロックモードの名称。 |
| granted | bool | ロックが保持されている場合は真、ロックが待ち状態の場合は偽 |
| fastpath | bool | ファストパス経由でロックが獲得されている場合は真、メインロックテーブル経由で獲得されている場合は偽。 |
| waitstart | timestamptz | サーバプロセスがこのロックを待ち始めた時刻。ロックを獲得していればNULL。 grantedがfalseであっても、待ちを開始してから非常に短い時間の間、これはNULLになることがあることに注意してください。 |

## pg_locksの活用法

pg_locksを活用することで、データベースのパフォーマンス問題の解析やデバッグに役立つ情報を得ることができます。

例えば、特定のトランザクションが他のトランザクションと競合しているかどうかを調べたい場合、pg_locksを使用して該当のトランザクションがどのようなロックを持っているかを調べることができます。

また、データベースのパフォーマンスが低下している場合、それがロック競合によるものかどうかを調べるためにもpg_locksを使用することができます。

## 注意点

pg_locksは非常に便利なツールですが、注意点もあります。pg_locksは現在存在する全てのロックの情報を提供しますが、それは一瞬一瞬で変わるため、同じクエリをすぐに再実行しても結果が異なることがあります。

また、pg_locksはロック情報を提供するだけで、ロックの問題を自動的に解決するわけではありません。

## まとめ

PostgreSQLのpg_locksは、データベースのロック情報を手に入れるための強力なツールです。これを活用することで、データベースのパフォーマンス問題の原因を特定し、適切な対策を立てることが可能になります。ただし、pg_locksの提供する情報を適切に解釈し、適切なアクションを取るためには、ロックとトランザクションの基本的な理解が必要です。
gqlgenで大きなファイルをアップロードできない時の対処法

# はじめに
普段、業務でGo + GQLGenを使ってアプリケーションを構築しているものです。
https://gqlgen.com/

その中で3MBぐらいのファイルをアップロードした時にエラーが出る事象が発生しました。その時の解決まで至る過程を記します。

# 不具合発生
ある日、ビジネス側から不具合の報告が

「ファイル（画像）を50枚ぐらい一度にアップロードしようとするとエラーになる」

すぐにローカルで確認しましたが、再現。コンソールを見ると、

```
net::ERR_CONNECTION_RESET
```

が出ていました。

# 調査
エラーメッセージが汎用的なものだったので、全く原因がわからず非常に苦戦しました。

ログを見てみると、バックエンドにリクエスト自体は来ているみたいなので、バックエンドのどこかで落ちていると仮定して、調べてみました。

# 解決法

どうやらGQLGenではデフォルトでファイルの最大が決められているらしく、それを変えたら正常に動くようになりました。

https://stackoverflow.com/questions/75646152/set-graphqls-max-file-upload-size-golang

当初、このように初期化していました。

```go
conf := graph.Config{}
srv := handler.NewDefaultServer(graph.NewExecutableSchema(conf))
```

[ソースコード](https://github.com/99designs/gqlgen/blob/24ea195cebea095035caf4d23af7f3d75fd0a041/graphql/handler/server.go#L32)をみると、この`NewDefaultServer`で、色々とデフォルトの設定がされているようでしたので、その設定を取っ払って、自分で設定し直せばいけるのではと踏みました。

まず、`NewDefaultServer`を以下のように変更

```go
srv := handler.New(graph.NewExecutableSchema(conf))
```

そして、`AddTransport`を追加

```go
srv.AddTransport(transport.MultipartForm{
    MaxUploadSize: 3 << 30, // 3gb
    MaxMemory:     3 << 30, // 3gb
})
```

そして、これだけだと`NewDefaultServer`でやっていたデフォルトの設定が取っ払われてしまうので、自分で設定しました。

```go
srv := handler.New(graph.NewExecutableSchema(conf))
srv.AddTransport(transport.MultipartForm{
    MaxUploadSize: 3 << 30, // 3gb
    MaxMemory:     3 << 30, // 3gb
})
srv.AddTransport(transport.Websocket{
    KeepAlivePingInterval: 10 * time.Second,
})
srv.AddTransport(transport.Options{})
srv.AddTransport(transport.GET{})
srv.AddTransport(transport.POST{})
srv.SetQueryCache(lru.New(1000))
srv.Use(extension.Introspection{})
srv.Use(extension.AutomaticPersistedQuery{Cache: lru.New(100)})
```

以上で3GBまで耐えられるようになりました。

# おわりに
StackOverflowはやはり神。
かなりニッチな内容ですが、同じようにエラーに苦しんでいる人の助けになれば幸いです。
JavaScript オブジェクトの扱い

## はじめに
JavaScriptの勉強を進めています。今はオブジェクトのところを勉強しており習ったことをまとめます。
他の言語の勉強も少ししたことがあるのですが、JavaScrptのオブジェクトって便利ですね！
自分用のまとめなので間違いなどあるかもしれないのでご了承お願いします

## オブジェクトとは
オブジェクトは配列と違ってから値に対して名前を付けることができます。{キー:値}と記述し、2つ合わせてプロパティと呼びます。
また、配列とは異なり{}で括ります。

```js
const scores = [10, 20, 30, 40]; //配列の宣言
const scores = {math: 10, science: 20}; //オブジェクトの宣言
```
キーは基本的に''(シングルクオーテーション)で括らなくても良いらしいです。もちろん例外規定はあるんですが、自分は英数字から始まるキーを使うことはないので''で括らなくても良いと覚えておきます。

また、前回の記事同様に縦並びでの記述も可能です。
```js
const scores = {
    math: 10,
    science: 20,
    }; 
```

## 値の取得
オブジェクト名[キー]、オブジェクト.キーで値の取得を行えます。
```js
let math_score = score['math'];
let math_score = score.math;
```
今の自分からしたら上の書き方のほうが配列みたいなものを扱っている感じがしてぱっと見わかりやすいです。

## 値を書き換え
値を書き換えたい時は以下のように書き換えます。
```js
score['math'] = 90; 
score.math = 90;
```

## プロパティの追加
オブジェクトに存在しないプロパティを追加すればいけます。
```js
scores.english = 85;  //プロパティの追加
```

## プロパティの削除
deleteを使って削除します。
```js
delete scores.english;  //プロパティの削除
```
追加と削除が違う書き方だとごっちゃになります。慣れですかね...

## forEach()は使えない
配列で使ったforEach()はオブジェクトに対して使うことができません。なのでforEach()を使えるようにするためにオブジェクトを配列化します。
```js
const entries_scores = Object.entries(scores); //ObjectのOは大文字です。
```
entries_scoresにはプロパティの数だけ配列が入っています。scoresオブジェクトの中には2つプロパティがあるのでentries_scoresには2つ配列が入っています。配列の中身は以下です。
```js
['math', 90]
['sicence', 20]
```
AWS re:Invent2023に現地参加する上で意識した３つのこと

# はじめに

AWS re:Invent2023に参加し、帰国してから既に１週間が経過していると思うと時の流れの早さを感じるばかりです。未だに毎日余韻に浸っています:airplane::sparkles:

AWS re:Inventに参加した率直な感想は、**「現地参加してよかった、また絶対いきたい！」**　です。おそらく、現地参加した方は皆さんそう思われているのではないかと思います。

生活リズムは乱れますし日本にいるよりも過酷な1週間を過ごすことにはなりますが、毎日が本当に刺激的でした。（5歳位若返った気持ち:baby_tone1:）

とはいえ、なにも意識せずに参加をすると「なんとなく」参加した感が強くなってしまいそうな気がして個人的にこれから記載する３点を意識してre:Invent2023に参加したので感想を交えながら書き連ねられたらと思います。

:::note info
- 現地レポートは別記事で更新しておりますので、併せてご覧ください！
- この記事の内容は個人の感想になります。温かい目で読み進めて頂けますと幸いです
:::

# ① 疲れている雰囲気をなるべく出さない

私が一番意識していた点は、疲れている雰囲気をなるべく出さない！です。
「**話しかけやすいオーラ全開:cherry_blossom:**」をずっと意識していました。例えば、目が合った際には軽く挨拶をするなど、小さなジェスチャー一つ一つに配慮していました。（時差ボケや連日の遅寝早起きの生活で隠しきれない疲労感はあったと思いますが:innocent:笑）

その理由は、re:Inventは世界中のAWSユーザーと出会うチャンスが沢山ある場所だからです。一言でも多く色々な方とお話したいと思っていました。

会期中は、朝食/昼食の提供があり大きなテーブルに基本相席状態になったり、セッションの待ち時間や待機列等では前後や隣同士になった人と話すチャンスも沢山あります。

そんなときに疲れている雰囲気を出していると相手も話かけづらいですし、疲労MAXな雰囲気を出している人から話かけられても会話が弾まないですよね:disappointed_relieved:

折角の交流チャンスを逃したくない！という気持ちで過ごしていたところ、実際にUSで働かれている方とLinked inを交換したり日本人の方ともネットワーキングの場以外でも知り合うことができました。これは私にとって大きな収穫だと思っています:relaxed:

# ② 現地でしか体験できない事にも積極的に参加する

現地でしか体験できない事項は大きく２つかなと思います。

- re:Inventで用意されているアクティビティセッション
- re:Invent外のラスベガスで有名な場所巡り

今回、睡眠時間を削ってでも上記2つの体験には現地ならではの感じられることがあると思いますので積極的に参加するようにしていました:muscle:

振り返ってみると、この2つは現地での日本人同士のネットワーキング会（Japan Night等）の場や現地での参加者同士の会話で最初のアイスブレイクとして話されるトピックスとして話されることがとても多かったなと感じましたので意識してよかったなと思っております。

re:Inventで用意されているアクティビティセッションの内、今回私は初めて開催された「[ヨガセッション](https://qiita.com/mizuki_hori_POHD_CCoE/items/4ee29e44c6afb60f3ff6)」に参加をしました！アクティビティ系のセッションは早朝スタート（6時半開始）のものが多く、参加するだけで一緒に頑張っているという一体感を感じることができます。

また、re:Invent外のラスベガスで有名な場所としまして、今回は2023年9月末にオープンになった[Sphere](https://www.thespherevegas.com/)は参加者の話題になっていました。私も合間の時間を縫いSphereの中にも入ってみました。チケットは円安の影響もあり若干高価でしたが、お値段以上の価値があったと思っています。

最先端技術に触れることができた事への満足感は勿論ですが、それ以上に多くの出会いや会話が参加者と生まれたことにとても価値を感じています。

Sphereの感想で盛り上がった場面もありましたし、たまたまSphere内のシアター視聴時に私の近くの席にもre:Inventに参加されている方がいらっしゃりお話をして名刺交換をすることもできたり等思わぬ場面での交流もありました:sunglasses:

通常セッション以外の時間にも積極的に活動する事も非常に重要だと感じましたので、2024年以降に参加される方はぜひ積極的に活動してみていただければと思います！

# ③ 簡単な英文は頑張って話す！

結論、**英語ペラペラでなくてもなんとかなりますし、楽しめます！**

ただ、折角英語を話せる機会を1週間与えて頂いているので簡単な質問（道をきいたり、セッション会場の場所を聞いたり等）は英語でしてみよう！と思い、あえてアプリで検索をしたりせずAWSスタッフやお店の店員に質問をしてみたりしていました。

そうすることで、セッションにいきなり参加をして英語を聞くと全く聞き取れないという状況を若干ですが軽減できた気がします。
また、店員さんやAWSスタッフは発音が多少間違っていてもどうにか聞き取ろうとしてくれるので「英語が通じた！」という小さな成功体験を積み重ねることができ少し自分に自信がついたなと思います:woman:

自信が少しついたことで、re:Invent参加者から英語で話しかけられても多少ですが会話することができ「もっと英語を理解したい！」という思いが強くなりました。帰国後、英語への勉強意欲が高まり早速毎日Duolingoで勉強をはじめました！（小さな事からコツコツ、即行動大事:v:）

https://ja.duolingo.com/

次回またre:Inventに参加する機会が巡ってきた際には今回以上に英語への理解も深めておけるように日々努力したいと思います！

# 最後に

まとめますと、私が意識した点は以下３つです。

:::note info
1. 疲れている雰囲気をなるべく出さない
2. 現地でしか体験できない事にも積極的に参加する
3. 簡単な英文は頑張って話す！
:::

私は折角参加する機会を頂いたので、なるべく積極的に活動しようと心がけておりました。

AWS re:Inventへの参加を通して、もっとAWSについて知りたいと思いましたしAWSユーザーにも沢山出会いたいという意識が強くなりました。来年は、国内のイベント/勉強会にも積極的に参加したいとおもいます！

AWS re:Inventに現地参加するメリットは沢山ありますので、チャンスがあればぜひ参加してみてください！:airplane:



# 弊社では一緒に働く仲間を募集中です :leaves:
現在、様々な職種を募集しております。
カジュアル面談も可能ですので、ご連絡お待ちしております！

募集内容等詳細は、是非採用サイトをご確認ください。

https://engineer.po-holdings.co.jp/
Workatoで実現していくRevenue Operations

# はじめに 


先月Workato社のイベントに参加してきまして、Revenue Operations（レベニューオペレーションズ）について聞いてきました。
なので、今回はRevenue Operationsについてと、Workato（ワーカート）による実現性について軽く書いていこうと思います。


# Revenue Operationsとは
Revenue Ops、RevOpsとも呼ばれるもので、マーケティング/セールス/カスタマーサクセス/ファイナンス等を部門横断的に連携を図り、データドリブンで効果的・迅速に経営判断を行い収益成果の最大化を目指すものです。
日本ではまだあまり知られていないですが、米国を中心に急速に発展している取組です。

```:データドリブンとは
売上データやマーケティングデータ、WEB解析データ等のデータに基づいて判断・アクションする事
```

# 注目される背景

日々、新しいテクノロジーやサービスが生み出されていく現代において市場変化の追随、もしくはユーザー要求を的確に捉えた新サービスを他社に先駆けて展開していくことは容易ではありません。
ましてや各部門がサイロ化されていては尚のことです。

```:サイロ化とは
組織の中でシステムや部門が分断され、独立している状態
```

各部門がサイロ化されていては、効果的な経営判断/市場変化の追随とFB/迅速なアクション、を実行する上で視野が狭くなりがちです。
部門単位では収益成果の最大化を実現していると思っていても、会社単位で見た時には収益成果の最大化を実現しているとは言えないかもしれません。

上記の課題を解決する為には各部門の情報やリソースを連携し、効果的且つ、迅速なデータドリブンを行う必要があります。
よってデータ活用基盤を部門横断的に設計運用していくRevenue Operationsが注目されています。

# 成功させる為の要素

成功の為には以下の3つを意識することです。
各項目を掘り下げて書いていくと記事の内容が膨大になるので要点のみを書いていきます。


・ データ活用
・ イネーブルメント
・ プロセス

### データ活用
ここが最重要です。
Revenue Operationsは全社のデータを基盤として、データドリブンすることを肝としている為、全ての基礎となります。
データが複数のツールやシステムに分散されデータ活用基盤が充分でなければ、断片的な戦略しか実行できなくなります。

さしあたって最初に行うこととしては、「対象データの選定」、「評価指標の策定」です。
対象データの選定や指標の策定ってどうしたらよいの？という方もいるでしょう。
あげていくと、どんどん出てくると思いますし、合っているのかも分かりません。

また、これらは企業の成長ステージによって異なってくる為、一概にコレ！というのは言えません。
スタートアップ企業であればCRMやBI等を導入することなくGoogleスプレッドシート等でこと足りるかもしれない為です。
そこでいくつか参考になりそうな基準や考え方について検索ワードを残しておきます。
（リンクを記載していいのか判断に迷ったので、ワードだけでも・・・）
```:参考
・SaaS Metrics 2.0
・Deal Desk
・SalesOps等の他のxOps
```

### イネーブルメント
上記の「データ活用」が明確化してきてデータ連携がうまくいっても、それをイネーブルメントしなければ意味がありません。
```:イネーブルメントとは
営業組織を強化・改善するための取り組み
```
まずは集まったデータやリソースを基にソリューションの定義と実行計画を作成します。
その後は、KPIを把握し、優先度を設定、進捗確認、定期的な評価等を行います。
そうすることで修正改善を繰り返し、会社全体として統一されたソリューションに向かっていけます。

### プロセス
上記の「イネーブルメント」を"実行できるか"は、プロセスにかかっています。

具体的には、4つのポイントでプロセスを実現することです。

コストリダクション(コスト削減)
　⇒ 無駄を見直し改善やリソース節約をすること
アライアンス(連携)
　⇒ 部門横断的に連携を図り、共通の目標に向かって集中させること
 フレキシブル(柔軟性)
　⇒ 予測の難しい市場や経済状況の変化に対応可能な状態にすること
コンシスタント(一貫性)
　⇒ 定義されたソリューションに対してのアクションなのだと一貫性を持たせること

# Workatoによる実現性

成功させるための3つに対して効果ありますが、特に「データ活用」と「プロセス」に対して効果を発揮します。

CRM、BIツール、チャットツール、タスク管理ツール、BPM、ERP、etc.
現代のビジネスシーンでは様々なツールがあり、また導入されていることでしょう。
全社でどんなツールを使用しているのかどんなデータを取り扱っているのかを洗い出し、全体最適化していく。
途方もない時間がかかりそうですね…。
また、最適化していく中で機能が重複しているものもあり、まずはツール移行を経てからなんてことも発生すると思います。
そこで、Workatoが活躍します！

各ツールのデータ連携、Input/Outputの中核に据えることで統合主導による自動化をすることが出来「データ活用」基盤を構築することが容易になります。
Webインターフェースしか存在しない、AppUIしか存在しない場合はRPAと組み合わせることにより盤石のものとなります。

そして、「データ活用」基盤を構築していく中で、「プロセス」構築を行うことも出来ます。
効果の高いRevenue Operationsを実現する為には、即時性も重要なファクターであると思いますが、Webhookも機能として備えている為、実現可能です。

具体的な機能や事例などは[他のメンバーが書いている記事](https://qiita.com/organizations/bstylevt)を参考にしていただければと思います。


# おわりに
ただテクノロジーやツールを活用する、業務を効率化するといったフェーズは過ぎ去っているなとヒシヒシ感じます。
また、生成AIの登場により、働く上での価値発揮はより高度なものを求められていくでしょう。
それは個人だけでなく会社としても求められ、どんなソリューションを提供できるのかといった、「モノ」の提供ではなく「コト」の提供をしていく必要がありますね。

[弊社の概要と記事一覧はこちらからどうぞ](https://qiita.com/organizations/bstylevt/profile)
【CSSデザイン】回転しながら変形する癒しのボールの作り方

## はじめに
CSSで遊ぶのが好きな女が、
回転しながら変形する癒しのボールをCSSだけで作成しました。

## コードはこちら
<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="PoVgeOj" data-user="ubdhtixg-the-scripter" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/ubdhtixg-the-scripter/pen/PoVgeOj">
  Untitled</a> by 森由唯 (<a href="https://codepen.io/ubdhtixg-the-scripter">@ubdhtixg-the-scripter</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

## 回転する仕組み
マウスホバー時に
- `transform: translate()` で水平方向に移動する
- `transform: rotate()` で180度回転する

```
transform: translate(200%, 0%) rotate(180deg);
```

これだけです:relaxed:

`@keyframes` でアニメーションさせても良いと思います。
グラデーションだけでなく、画像に置き換えてもかわいいかも。
【PostgreSQL】pg_hba.confについて

## 初めに
PostgreSQLではサーバーへのアクセスの際にクライアント認証が行われています。
- クライアント認証とは
例えば、クライアントが自身のIDとパスワードをサーバーに提供します。サーバーは、これらの情報がデータベースに格納されている情報と一致するかどうかを確認します。もし一致した場合、クライアントの身元が確認され、リクエストされたサービスへのアクセスが許可されます。

PostgreSQLではpg_hba.conf[^1]で管理しています。
[^1]:hbaとは？
host-based authenticationの略。

## pg_hba.confとは
`pg_hba.conf`の中身は以下のようになっている。

``` pg_hba.conf
# TYPE  DATABASE        USER            ADDRESS                 METHOD

# "local" is for Unix domain socket connections only
local   all             all                                     md5
# IPv4 local connections:
host    all             all             127.0.0.1/32            ident
# IPv6 local connections:
host    all             all             ::1/128                 ident
# Allow replication connections from localhost, by a user with the
# replication privilege.
local   replication     all                                     md5
host    replication     all             127.0.0.1/32            ident
host    replication     all             ::1/128                 ident
```
特徴としては以下の通り
- 1行につき1つのレコード
- スペース区切り
- #以降の文字は無視される
- 最初に条件を満たした認証方式で認証を行う
- 条件を満たさなかった場合に、認証は拒否される

また、書く順番としては、対象アドレスの範囲が狭いものから、認証方式の条件が緩いレコードを書きます。

認証方式はいくつかあります。

| 設定値 | 種別 | 説明 |
| :---: | :---: | :--- |
| trust | 無条件 | 無条件で許可 |
| reject | 無条件 | 無条件で拒否 |
| md5 | パスワード認証 | md5暗号化によるパスワード認証 |
| password | パスワード認証 | 平文のパスワード認証 |
| scram-sha-256 | パスワード認証 | scram-sha-256暗号化による認証 |
| ident | Ident認証 | クライアントのマシン上の「Identification Protocol、RFC1413」サービスに依存 |

PostgreSQL13まではmd5が
PostgreSQL14以降ではscram-sha-256がデフォルト暗号化手法となっている。

## まとめ
DBなので接続元は基本的には限定的なはずなのでpg_hba.confで明確に設定しておくことは大事ですね。
PHP ぼやき日記 2023-12-12

- [次回](https://qiita.com/sj-i/items/ea5df5e11926406b56d1)

- Qiita ガイドライン的にはスレスレな気もしつつ、まあ絶対に日記を書いてはアカンということもないと思うので、試しに日記というか継続的殴り書きをやってみる
- 毎日やるぞみたいな意気込み感はあまりないし、飽きたり疲れたりしたらやめるし、書く余裕がないくらい忙しい時は書かない

# PHP_CodeSniffer (phpcs) の 3.8.0 が出た
- https://github.com/PHPCSStandards/PHP_CodeSniffer/releases/tag/3.8.0
- phpcs の現状は [The Future of PHP_CodeSniffer](https://github.com/squizlabs/PHP_CodeSniffer/issues/3932) の通り
- 17 年メンテしてきた Greg のひとが引退して jrfnl のひとがメンテナをやってくことに
- リポジトリは squizlabs/PHP_CodeSniffer から PHPCSStandards/PHP_CodeSniffer に移行
- packagist のパッケージの向き先が変わったので利用者は composer で update したら降ってくる
- またメンテが止まったら困るなあ、会社で使ってるんだよなあ、という人は[金銭的支援を検討](https://opencollective.com/php_codesniffer)するとよいかも

# FrankenPHP の 1.0 が出た
- https://frankenphp.dev/
- 新しい SAPI
- Go 製の Caddy を前段に置いて ZTS な処理系が PHP 処理をがんばる構成
- リクエスト間で状態をリセットしない worker モードがある
- ZTS なので ZTS 固有の問題を踏む場合はありそう
    - [最近音沙汰のない parallel](https://github.com/krakjoe/parallel) 以外で唯一のまじめな ZTS 利用者なので、ZTS の将来のためにがんばってほしい
- 通常の CLI を使う [RoadRunner](https://roadrunner.dev/) とくらべると opcache がまともに使えてメモリ消費をややおさえやすいのが利点か
    - なお RoadRunner 側では [issue は出ている](https://github.com/roadrunner-server/roadrunner/issues/1271)
        - だいぶ前に RoadRunner の Discord で「opcache 効いてないけどこうすればできるよ」みたいな話を rustatian のひとにしたことがある
        - なお最近はその Discord のほうで「もう俺 php-src 側に Windows 以外でも関係ないプロセス間で SHM 共有できるようにする修正入れよっかな」ってボヤいてた

# PHP アプリケーションをワンバイナリで配布できるやつ
- https://github.com/crazywhalecc/static-php-cli
- musl libc 使った静的リンクワンバイナリな PHP 処理系に exe packer みたいな奴で php ファイルや phar を抱き合わせるとアプリケーション丸っとワンバイナリで配布できますねというやつ
- これを使った FrankenPHP の機能で [Web アプリをワンバイナリで配布する](https://frankenphp.dev/docs/static/)みたいなのもある
- わりと夢が広がるのだが FFI は動的リンク前提なので、たとえば FFI で自身の libc にアクセスするみたいなのが普通にはできない

# New "PECL"
- https://externals.io/message/121927
- [PHP Foundation](https://thephp.foundation/) で PECL をどうにかしよう！というお金を [ Sovereign Tech Fund](https://www.sovereigntechfund.de/) から得たのでどうにかするらしい
- 公開の Google Document 使って要件をまとめてるところ

# Reddit で「final やめろよ！継承できないだろ！」って吠えてる外人がいて朝から笑った
- https://www.reddit.com/r/PHP/comments/18g007i/stop_using_final_classes/
- あわせて読みたい [前に訳した奴](https://qiita.com/sj-i/items/2c3d548079522da1b0e9)
- A「継承できないから final やめろ！」
B「うるせえ Decorator を使え！」
A「それだと変えたい部分以外を素通しするだけのボイラープレートを沢山書かなきゃいけなくなるだろ！」
B「でけーからだよ public interface が！小さく切れ！」
A「今いわれても手遅れなんだよ！」
みたいな決して交わらない世界がある
- 常時 `final` 使いましょう、というのは「基本 `interface` に依存させつつ継承より合成でいきましょう」みたいなオブジェクト指向矯正ギブス的な修行の一種
- 公開ライブラリはともかくアプリケーションコードの場合、「継承を考えナシに使うのは避けましょう」という話だけチーム内で合意できていれば別に final 使わなくてもいい（し、それだとコード上の `interface` 切るの後回しにして雑に書きながらモックできる）と思っており、[惣菜をパックのまま食卓へ出すネタ](https://anond.hatelabo.jp/20210712205129)に近いところがある
画像１枚からLoRAを作りました

こんにちは、AIでアニメを作るG-VISの延藤です。
今回参加したハッカソンで画像１枚からそこそこの精度のLoRAを作ることができたので共有します。
(↓アニメ系モデル＋今回作成したLoRA)
![image (14).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1455134/91137202-ff62-2442-f9e9-2a9642987c28.png)

# 画像１枚LoRAの有用性

皆さん、画像生成してますか？
chatGPTにも画像生成機能が追加されて、より身近なものになりましたよね！

さて、そんなこんなで画像生成していると、一期一会の「これだ！！！！」って画像と出会うことがあるかと思います。
stablediffusionならまぁモデル合わせて、シード値とかcontrolnet使えば似た画像が作れると思いますが、chatGPTのDall-Eとかだとそうもいきませんよね。

せっかくの神画像が１枚きりで終わってしまいます。
そんな時に１枚LoRAがあれば、永久にその神画像の絵柄を真似した画像を生成してくれるようになります！

これがあればオリジナルキャラクターを作ったり、AI彼女に着せ替えしてみたり色々できることの幅が広がります！

おめでとうございます。
あなたの一期一会に祝福を。(???)

# LoRAを作ってみよう！
stablediffusion webuiを使っていきます。

今回使用する画像はこちら！
![testwhole.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1455134/263cac4f-2f44-29a8-f49a-6f9f1c8c6c17.png)

株式会社DiFunがプロデュースするキャラクター「Lei」です。

みるからに複雑で、まさに一期一会って感じですよね。
これを量産できるLoRAを作っていきましょう！

## ステップ１：ちょっと違う画像を量産する
img2imgタブを選択して、その少し下のinpaintを押します。

leiちゃん画像をupload
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1455134/7a7665bd-1537-ed6b-f54e-cfe046467b67.png)


leiちゃんじゃない部分を塗りつぶします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1455134/52ea2758-d549-ea12-722a-fba4a5823171.png)
淵の部分はこんな感じでぽんぽんクリックしていくといい感じです。
ミスったら右上の戻るボタンでundoできます。

taggerでプロンプトを画像から作成し、（GPTに画像投げてプロンプト生成してもらうのもありです）

背景の色だけプロンプトを足して画像生成します。

## ステップ２：選ぶ
Leiちゃんの特徴をうまく反映できている画像を選んでいきます。
うまく生成できたものTop30くらいを選ぶといいのではないでしょうか。


(ここで30枚も満足のいくものがないのであれば、1,2を繰り返したり、画像編集ソフトで背景抜いてみたりとか反転したりとか傾けたりとか色々やります。)

## ステップ３：データセットにする
タグ付けですね。この動画が最高にわかりやすいです。
https://www.youtube.com/watch?v=8EghxL4gcDw&t=628s
この記事は基本的にこの動画のやり方をそっくり真似ています。

まずdataset_tag_editorでタグをつけていきます。(スタンドアロン版がおすすめです)
https://github.com/toshiaki1729/dataset-tag-editor-standalone

タグ付けはこんな感じで行いました。
バッチ処理でremoveを選び、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1455134/c51ea12f-a7e4-a4ab-711c-93b7f556cf44.png)

Leiちゃん本体の特徴にチェックを入れていきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1455134/95be4abc-51c6-84ea-d1d2-32ce906803ac.png)
そしてRemoveします。

残すタグは生成する時に入れるプロンプトって感じです。

kohya_ssに移動して学習していきます。
フォルダ名に数字入れましょう　今回は５にしています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1455134/18abe3cc-cc6a-a009-9b69-39e75587b449.png)

細かい設定は先ほど紹介した動画にベストプラクティスが乗っているので参考にしましょう。
ただ、多めにチェックポイント設定しておいて、後で実際に回しながらいいモデルを選択するほうが手間はかかりますけど、結果的にいいものができると思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1455134/b7c0caff-4c0b-9aa7-398a-c0aad7c7bf58.png)
自分は50個くらい作りました（こんなに細かい必要はなかったです）
５段階くらいがちょうどいいと思います。

# テストする　
早速学習したLoRAを使ってみましょう、
学習回数の違うモデルがいくつか出力されているので、ベストなモデルを探していきます。
今回は学習回数1000回が使いやすい強度でした。
強度が高すぎるモデルだと、色が変になったり、姿勢が全て同じになったりします。
程よく自由度があるものを探してください。

# 使う
ベースモデルを変えたりしても面白いです。
今回はアニメ系のモデルで試したらかなり綺麗にできたので満足しています。
![image (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1455134/a5dbcbff-76da-a393-e8b0-0068cbfd4110.png)
背景もごちゃついていなくて使い勝手がいい画像になりました！

# まとめ
inpantとか外部ソフトで画像を編集して水増しすることで画像１枚からでも実用的なLoRAは作成できます。
AIときくと最初から最後までスマートに自動でできるものみたいなイメージがつきがちですが
「泥臭い努力を組み合わせることで可能性は無限大になる」
ということを学びました。
新卒エンジニアが遠方からほぼフルリモートをしてみた

こんにちは。Supership株式会社アドテクノロジーセンターのsho44です。

:::note warn
この記事は、[Supershipグループ Advent Calendar 2023](https://qiita.com/advent-calendar/2023/supership)の14日目の記事になります。
:::

## TL;DR
リモート環境下でチームで行っている施策・個人的にやってよかったことを紹介します。

## 自己紹介
私は新卒社員として実務に入ってから約5ヶ月、SSP側の管理画面を作っています。
研修期間を含めると入社してから約8ヶ月が経ちました。
就業している会社は東京にあるのですが、私は関西圏からリモートワークで業務に携わっており、月に3日ほど出社しています。

## チームで行っている施策
### 22卒の先輩と2on1
チームにジョインしてから約5ヶ月、毎週30分ほど22卒の先輩方との2on1を実施しています。
この時間は雑談や業務に関する質問・悩みについてお話しできる時間です。
最初はチームに馴染めるか心配でしたが、先輩方が親身にお話を聞いてくださったことで、発言するハードルが下がりました。
雑談ではおすすめのガジェットやリモート下でのテンションの維持方法なども話題にし、これが生産性向上につながっているように感じます。
毎週の2on1を通じて、社会人としての力も徐々についてきているように思います。

### ELとの1on1
2on1と同じく毎週30分ほど業務やキャリアに関する質問・悩み相談、雑談をできる時間です。
評価の認識を合わせたり、具体的なタスクの進捗を確認することで、今後の方針を明確にできるようになったことはもちろん、雑談の中で「最近調子が悪いです...」といった話もでき、リモート環境でも健康面を気にせず仕事ができています。

### 定期的な雑談会とランチ会
進捗共有や話したいこと、困ったことがないかチームメンバー全員で話し合う時間を毎日30分、毎週1時間確保しています。
これにより、おすすめのふるさと納税やIDEのアップデート情報共有、MTGのタイミングなど、slackで話すほどの大きなことではないトピックも共有できるようになりました。

ランチ会は会社からの食事補助費を利用し、毎月1回実施しています。
他チームとの交流もあり、ミーティングやプロジェクト時の円滑なコミュニケーションにも寄与しています。

### ドキュメントの整備
オンライン上でドキュメントを整備することで、コミュニケーションコストが抑えられています。
オンボーディング資料があるため、新人はほぼ自走してキャッチアップが可能です。ただし、まだ整備されていない部分もあるため、新卒目線でドキュメントの改善に取り組んでいます。

### bizメンバーとの雑談会
毎週30分ほどbizメンバーとdevメンバーで雑談会を行っています。これは対面での雑談を意図的に行うもので、普段の業務での質問しやすさにも繋がっています。
雑談のネタ帳は、[M3さんのブログ](https://www.m3tech.blog/entry/zatsudan-mahou-no-spreadsheet)を参考にさせていただいています。

### テキストベースで語彙を和らげる
メンバーで合意を得て語彙を和らげているわけではありませんが、強い言葉を避け、適切な絵文字の使得ことで質問しやすさが向上していると感じます。

### 輪読会
チーム外で行っている施策になりますが、毎週1時間同期と輪読会を行っています。
コミュニケーション不足を感じないよう、積極的に意見を交換しています。
輪読会の詳細についての記事はこちらになります。
[新卒エンジニアで輪読会をしている話](https://qiita.com/haruki_kasai/items/1e429f66d75a0285b45c)

## 個人的にやってよかったこと
### 質問ルールの決定
仕様がわからない場合、ドキュメントとslackを検索して出てこなければすぐにメンバーに質問するようにしています。

実装で詰まった場合、手詰まりを感じて15分ほど経ったらメンバーに質問するようにしています。copilotやchatgptを使うと詰まることがほとんどないので質問する頻度はあまり多くないです。

また、質問する際には必要性がある場合を除きテキストベースで聞くようにしています。
タスクの進捗遅れに繋がらず、無駄にメンバーの時間を貰うことにもなっていないように感じます。


### 不定期で同期と雑談
自チームに還元できるアイディアがあると考え、不定期で同期と雑談を行っています。
気分転換にもなり、集中力の維持に寄与しています。

### 出社や飲み会への積極参加
リモートワークだけでなく、対面での雑談や飲み会も必要な側面もあると考え、積極的に参加しています。飲み会では異なるプロジェクトのメンバーと交流する機会があり、今後の仕事にもプラスになると感じています。

### 運動と食事の管理
リモートワークでは椅子に座りっぱなしになりがちですが、運動を積極的に取り入れ、食事にも気を付けています。これにより、メンタルの安定と仕事への集中力の向上を実感しています。

### お昼休み時間のルーティン
お昼休みのルーティンとして、寝ることを習慣にしています。これによりリフレッシュが図れ、休憩後もコンディションを保ちながら仕事ができています。

### 新幹線移動中のルーティン
新幹線で出社しており、往復約7時間〜8時間かかります。
勉強や仕事をしている時もありますが、寝不足によるパフォーマンス低下を避けるため、寝ている時もあります。
なるべく深くリクライニングできる席を選び、ほっとアイマスクをつけ、フットレストを使い寝るようにしています。


## おわりに
今回紹介したチームの施策と個人的なアプローチにより、リモートワークのデメリットを解決しつつ効果的な仕事ができていると感じています。
ただし、まだ改善の余地があると考えており、皆さんからのフィードバックやネタがあれば、ぜひコメントしていただければと思います。

また、去年新卒で入社した方が書かれたリモートワークに関する記事もご参考にしていただければ幸いです。
[新卒でフルリモート可の企業に就職しました。](https://qiita.com/hosomin0211/items/04abb7be8ff77b2c0ecf)


:::note
**最後に宣伝です。**

Supershipではプロダクト開発やサービス開発に関わる人を絶賛募集しております。
ご興味がある方は以下リンクよりご確認ください。
[Supership 採用サイト](https://supership.jp/recruit/)
是非ともよろしくお願いします。
:::
TouchDesigner: ScriptTOPのScriptが階層上がったりPerformance Modeにするとcookされない時の対処法

こんにちは！こちらは TouchDesigner Advent Calendar 2023 12日目の記事です。

## サンプル
今回作ったサンプルは以下にあります。
[chimanaco/touchdesigner-advent-calendar-2023](https://github.com/chimanaco/touchdesigner-advent-calendar-2023)

## はじめに

表題の件、Script TOP を使って OpenCV で顔認識をしてその位置を元に何か出す、ということをやっていた時に起こった問題について書いていきます。他にもっと根本的な解決方法がある気がしますが、自分の対処方法を残しておきます。
この記事のサンプルは `2023.11290` で作っていますが、`2022.33910` でも同じでした。

## うまくいかなかった例
![2023-12-12_12h15_47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58558/4a51b38c-43ba-a50b-cc7e-40804bde826a.png)

`script1_callbacks` はこんな感じです（2023から const の value が value0 から const0value になった…？）。`script1_callbacks` で得られた値（サンプルではランダムな値にしています）を他で使用するべく `Constant CHOP` に入れています。

```
def onCook(scriptOp):
	frame = op('SRC').numpyArray()
	scriptOp.copyNumpyArray(frame)
	
	op('constant1').par.const0value = tdu.rand(absTime.frame)
	return
```

これが各オペレーターがあるネットワーク上だと更新されるものの Performance Mode にすると更新されなくなってしまいました。上の階層に行っても同様の症状でした。

## うまくいった例

解決方法としてどこかで見かけたのが Storage を使う方法（フォーラムだったと思うのですが見つけたら追記します）です。Stroage を使うとオペレーターに紐づけて値を保存することができます。`Constant CHOP` の代わりに `Script CHOP` を使って実装します。

![2023-12-12_12h16_59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58558/dfe18a1c-c42e-1366-421f-3d5b9aa61412.png)

`script1_callbacks` はこんな感じです。`scriptOp.store('var1', 10)` のところで `script1` に紐づけて `var1` の値を保存しています。また、`script2` の変数名と値を更新しています。`scr.lock = True` と `scr.lock = False` を入れておくと `script1` と `script2` の Loop を回避できます。

```
def onCook(scriptOp):
	frame = op('SRC').numpyArray()
	scriptOp.copyNumpyArray(frame)
	
	# This fix the cooking bug
	scriptOp.store('var1', 10)
	
	scr = op('script2')
	scr.lock = True
	scr.clear()
	tx = scr.appendChan('tx')	
	tx[0] = tdu.rand(absTime.frame)
	scr.lock = False
	return
```

`script2_callbacks` はこんな感じです。`fetch()` で `script1` の Storage に保存されている値を読み込んでいます。

```
def onCook(scriptOp):
	# Force creating a relation between script1 and script2
	features = op('script1').fetch('var1')
	return
```

これで無事 Performance Mode にしたり階層上がったりしても値が更新されるようになりました。
store する値はこのサンプルのように同じ値でも強制的に cook してくれるようです。サンプルだと `Script TOP` が cook されるごとに `store()` していますが、これを `Execute DAT` で `onStart()` で `me.parent().store` とかしてもうまくいきませんでした。また困ったことがあったら調べてみようと思います。

それではみなさま Happy Holidays!!

参考
* [Storage - Derivative](https://docs.derivative.ca/Storage)
* [TouchDesignerでの状態管理の方法について #TouchDesigner - Qiita](https://qiita.com/aa_debdeb/items/562c4da5e8b8c1d1a424)
* [Storage | TouchDesigner - YouTube](https://www.youtube.com/watch?v=jS905hEz3Ck)
* [OpenCV multiple face tracking in TouchDesigner - YouTube](https://www.youtube.com/watch?v=tEksriIknZE)
* [Google Colaboratory+OpenCVでWebカメラ画像から顔検出 #Python - Qiita](https://qiita.com/uranishi/items/85184baf1df33192e00a)
* [TouchDesignerでOpenCVをはじめーる（Windows10、Python3.7、OpenCV4.0） #Python - Qiita](https://qiita.com/SatoshiGachiFujimoto/items/f548501a52d8c34fb73d)
k6でvusごとの識別子を作る方法について

この記事は [ソフトウェアテストの小ネタのカレンダー | Advent Calendar 2023](https://qiita.com/advent-calendar/2023/software-testing-koneta) の 12 日目の記事です。

# はじめに

k6使ってますか？
私は2023年はじまってすぐくらいにk6に出会って、負荷試験をするときは愛用しています。

負荷をかけるためのクライアントに良いスペックのマシンを用意する必要がなく、
手軽に1000req/s以上の負荷をかけられるのが楽で最高です。

また、負荷のかけ方をコマンドライン引数からも調整できるので、緩くリクエストをし続けてる間に、障害を起こして何が起きるか試験をするのにも適しています。

# このページについて

そんなk6ですが、仮想ユーザー数を簡単に増やせるのは良いけど、そのユーザー間で衝突しないように一意な値を振りたいな、という欲求もあったりします。
例えば、
- ユーザーID
- 適当な名前に連番付けたい

みたいなときなど。

このページでは、小ネタカレンダーらしく、上記を行うための小ネタを紹介します。
（一瞬で終わる）

# vusのIDの取り方

> __VUS

これで取れます（以上！）

これだと芸がないのでコード載せていきます。

```js:test.js

import http from 'k6/http'
import { params } from "./params";

const operationName = "test"

export const options = {
    vus: 100,
    duration: '300s',
}

const query = `mutation test($input: TestInput!) {
  test(input: $input) {
    ... on Success {
      id
    }
    ... on Errors {
      errors {
        __typename
      }
    __typename
    }
  }
}`

let incrementalNumber = __VU * 100000
export default function () {
    const variables = {
        input: {
            name: "k6から保存：" + (++incrementalNumber),
            tester_id: __VU
        }
    }
    http.post("http://localhost:18080",
        JSON.stringify({
            operationName,
            query,
            variables
        }), params)
}


```

```js:params.js

import encoding from 'k6/encoding'

import {
    uuidv4,
} from 'https://jslib.k6.io/k6-utils/1.4.0/index.js'

export const params = {
    headers: {
        'Content-Type': 'application/json',
        "X-Request-Id": uuidv4()
    }
}

```

test.jsのインスタンス自体は、vusごとに作られるので、実行回数をインクリメントしておけば、vusごとにある程度把握のしやすい連番、というのは作れます。
ぜひお試しあれ〜

# 最後に
k6でvusごとの識別子を取る・作る方法と、しれっとGraphQLのリクエストをk6で行う方法についてお届けました。
Kinesis Lambdaでは、failure record を特定するまでの batch splitting は、retry countに計上されない

表題の通り。



> If the function receives the records but returns an error, Lambda retries until the records in the batch expire, exceed the maximum age, or reach the configured retry quota.
> For function errors, you can also configure the event source mapping to split a failed batch into two batches. Retrying with smaller batches isolates bad records and works around timeout issues. **Splitting a batch does not count towards the retry quota.**


具体例を挙げると、

(batch size, retry attempt, split on error) = (64, 5, true)で最初のレコードがproblematicな場合、

- ⭕️ `1-64(failure)` -> `1-32` -> `1-16` -> `1-8` -> `1-4` -> `1-2` -> `1` -> `1` -> `1` -> `1` -> `1` and Kinesis Lambda gives up.
- ❌ `1-64(failure)` -> `1-32` -> `1-16` -> `1-8` -> `1-4` -> `1-2` and Kinesis Lambda gives up.


## Ref.

https://docs.aws.amazon.com/lambda/latest/dg/with-kinesis.html#services-kinesis-errors
Rails RSpec 要素を指定する時の記述

## はじめに
RUNTEQに入学して4ヶ月目の学習者です。検証したことを記述していますが、誤った記述等あればコメント貰えると助かります。
## 1.なぜこの記事を書いたのか
テスト作成時に要素の指定の仕方を忘れることがある、いくつか種類があるのでそれぞれの特徴をまとめておきたいと思った。
## 2.環境
- ruby 3.2.2
- rails 7.1.2
## 3.色々
### have_content
`expect()`内の要素の中に指定した値が含まれているかを確認する。これと逆で`have_no_content`がある。
```erb:view/homes/top.html.erb
<p class="example">テスト</p>
```
```ruby:
it 'テストの文字が表示されている' do
    visit home_top_path
    expect(page).to have_content('テスト'), '文字「テスト」が表示されていません'
end
```

### have_selector
`expect()`内の要素でhave_selectorで第1引数で指定した要素の中に第2引数の要素が含まれているか確認する。下の例で表す様に孫要素でも検出可能。第1引数はクラス名の指定も可能。
```erb:view/home/top.html.erb
<div><p class="example">テスト</p></div>
```
```ruby
it 'テストの文字が表示されている' do
    visit home_top_path
    expect(page).to have_selector('div', text: 'テスト'), '文字「テスト」が表示されていません'
end
```
### find
capybaraのメソッドで`find()`内のページ上の要素を選択する。
```erb:view/homes/top.html.erb
<div><p class="example">テスト</p></div>
```
```ruby:
it 'テストの文字が表示されている' do
    visit home_top_path
    expect(find('.example')).to have_content('テスト'), '文字「テスト」が表示されていません'
end
```
### within
セレクタを指定する
```erb:view/homes/top.html.erb
<div class="example">
  <p id="p">テスト</p>
  <button id="btn">Push!</button>
</div>
```
```js:app/javascript.application.js
// ボタンを押すとテキストが変更される

const p = document.getElementById('p');
const btn = document.getElementById('btn');
btn.addEventListener('click', () => {
  p.textContent = 'テキスト変更'
})
```
```ruby:
it 'テストの文字が表示されている' do
      visit home_top_path
      within find('.example') do
        click_button 'Push!'
      end
      expect(find('.example')).to have_content('テキスト変更'), '文字「テキスト変更」が表示されていません'
    end
```
今のところはこの4つを使ってテストを作成していて困ることはありませんが、また便利な指定するメソッド、マッチャーがあったら追記していきます。
Pod Topology Spread Constraints と Spot VM で可用性を担保しつつ、インフラコストの削減をする

この記事は、[CyberAgent Group SRE Advent Calendar](https://qiita.com/advent-calendar/2023/ca-sre) 2023の13日目の記事です。

# はじめに
株式会社CAM の SRE team に所属している岡です。

弊社は、エンターテインメント事業に注力しており、それらサービスのインフラストラクチャの運用・保守を SRE team が担当しています。

本記事では、GKE 環境において Pod Topology Spread Constraints と Spot VM を使用することで、可用性を担保しつつ、コスト削減を行なった方法をご紹介します。

# Spot VM の課題

Spot VM とは Regular VM（標準的な Compute Engine VM）と比べ、可用性が保証されない代わりに、料金がとても低い VM です（[参照](https://cloud.google.com/kubernetes-engine/docs/concepts/spot-vms?hl=ja)）。
割引率はインスタンスタイプや時期にもよりますが 90% 以上の割引率が適用されたりもします。

本番環境に導入することができれば大きな額のコスト削減が見込めるためとても魅力的なサービスです。
しかし、本番環境に導入するには以下のような課題がありました。

- 在庫不足などにより Spot VM が 1 台も起動できない状況を考慮する必要がある
- 複数台の Spot VM が同時に停止される可能性を考慮する必要がある

# Pod Topology Spread Constraints が解決する課題

先ほど上げた課題は **「サービスを構成する全Podの内 50% は Regular VMにスケジュールする」** といったようなことが実現できれば、Spot VM が全て停止されてしまった場合でも、**半数の Pod は稼働していることが保証できる**ため解決できます。

Pod Topology Spread Constraints とはユーザーが定義したドメインに基づいて Pod を分散配置してくれる機能です（[参照](https://kubernetes.io/docs/concepts/scheduling-eviction/topology-spread-constraints/)）。

この機能を使用することで、最低限の可用性を担保しつつ、Spot VM を使用しコスト削減をすることが可能になります。

# 実装

ここからはコード交えつつ、実装方法の紹介をしていきます。

## Taint/Toleration の定義

なんでもかんでも Spot VM にスケジュールしたくないので、Taint を Node に付与し、Spot VM にスケジュールしたい Pod 側で Toleration を定義します。

Taint
```
key    = "allow-schedule-to-spot-vm"
value  = true
effect = "NO_EXECUTE"
```

Toleration
```yaml
tolerations:
  - key: "allow-schedule-to-spot-vm"
    operator: "Equal"
    value: "true"
    effect: "NoExecute"
```

## Pod Topology Spread Constraints の定義

Spot VM にスケジュールしたい Pod に Pod Topology Spread Constraints を定義します。
この際、**Regular VM と Spot VM を判別するための Labele を Node に付与しておく必要があります**。
今回の例では Regular VM に `spot-vm: false`、Spot VM に `spot-vm: true` という Label が付与されている程でコードの例を出します。

```yaml
topologySpreadConstraints:
  - maxSkew: 1
    topologyKey: spot-vm
    whenUnsatisfiable: DoNotSchedule
    labelSelector:
      matchLabels:
        app: example-app
        release: example-app
```

以上で実装は終了です。
特に難しい設定もなく簡単に実装できると思います。

# 注意事項

Pod Topology Spread Constraints を導入するにあたって、Pod のスケールイン時や、ローリングアップデート時に定義した戦略通りのスケジューリングにならない可能性があることを考慮する必要があります。
[Descheduler](https://github.com/kubernetes-sigs/descheduler) というソフトウェアを使用することで、戦略に従っていない Pod を Evict し再スケジュールすることが可能なためインストールすることを推奨します。

# おわりに
Pod Topology Spread Constraints を利用することで最低限の可用性を保ちつつ、Spot VM を利用することができ、コスト削減を実施することができました。
Spot VM 使いたいけど、可用性の問題で使えてないよといった方の参考になると幸いです。
明日は @kznrluk さんの「SRE入門のための自宅K8sクラスタ」です。
最小二乗法を動画で説明してみる

統計・機械学習の数理 Advent Calendar 2023 15日目の記事です。

https://qiita.com/advent-calendar/2023/mathematical_statistics

## 動機
私のお気に入りYoutubeチャンネル「3Blue1Brown」に憧れて作りました。
3Blue1Brownとは数学系の知識を可視化して分かりやすく動画で説明してくれているチャネルです。

3Blue1Brownの動画は、Manimという数学系可視化ライブラリを使って作られているそうで
私にも作れるんじゃないか、アドベントカレンダーのネタになるんじゃないか？
という気軽な気持ちで始めたのですが、、、、結構大変でした。

私の下手くそな動画よりも、本家を見てほしい。
上手に作ればこんな美しい動画が作れます。
[【面白い数学】衝突回数に円周率が現れる理由](https://youtu.be/a-EOA3j3tw4?si=eLvFunNC4PVkdOH1)

[ニュートン法と美しきフラクタルの世界](https://youtu.be/3tHSIxInkGc?si=sk7_sgoSbEfZ1n3H)

[【視覚的に理解する】フーリエ変換](https://www.youtube.com/watch?v=fGos3wrKeHY)

## 最小二乗法を動画で説明してみる

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

## 解説

### インストール
Visual Studio CodeとPythonがまず必須です。
あとFFMPEGという、老舗エンコードソフトのインストールが必須です。
https://ffmpeg.org/
きれいな数式を表示したい場合、Texという文法で書きますが
こちらも事前にMikTeXというソフトのインストールがいります。
https://miktex.org/download

Pythonがインストール後にpip（Pythonのパッケージ管理ソフト）を使って
Manimをインストールします。
```
pip install manim
```
今回私がやっていたように、音声を足したい場合は、
manim-voiceoverプラグインのインストールをします。
```
pip install "manim-voiceover"
```

### 書き方
本動画のコードを元に説明すると非常に分かりにくくなりそうなので、、、
（要望あればアップします。）
公式のQuickStartを見てもらうのが最も簡単です。
https://docs.manim.community/en/stable/tutorials/quickstart.html

1. 適当にフォルダを作る。例えばproject
2. シナリオを定義したpythonクラスを作成する 
例えばScene.pyというファイルを作って、その中にクラスを作ります。
```python
from manim import *


class CreateCircle(Scene):
    def construct(self):
        circle = Circle()  # 円を生成
        circle.set_fill(PINK, opacity=0.5)  # 色と
        self.play(Create(circle))  # 動かす
```

3. コマンドラインで`manim -pql scene.py CreateCircle`を実行

動画が作成され、メディアプレイヤーで再生されます。
高解像度にしたければ、-pqlを-pqhにするとよいです。

Example Galleryが充実しています。
面白そうなコードをコピペして動画作成してみるのが、理解への近道です。
https://docs.manim.community/en/stable/examples.html

### 苦労したこと
**レイアウト**
つい、PowerPointの間隔で１ページにいろんな情報を盛り込もうとすると
レイアウトが難しくなります。はみ出たり、重なったりしてよく分からなくなります。
１つのシーンはなるべくシンプルに構成したほうがよいですね。

**そもそも、わかりやすい可視化方法を思いつくのが難しい**
道具は良くても使うのは人なわけで、どう可視化したら良いかがミソです。
今回、最小二乗法を思いついた時点で
データポイントと直線の偏差と、傾き、切片を変えたときの偏差平方和を
連動してグラフ化しようというところまで考えていました。
が、実際描き始めると傾きが変わると切片グラフの偏差平方和も変わるので
なんだかわかりにくい、ということに気づきました。（今更、、、）
a,bの寄与分を分けて数値化するとよいかも、と思ったのですが説明がややこしくなるし
3Dにしてしまえ、と思ったのですが3Dと2Dの混在は座標系が非常に面倒でやめました。

数学的な深い理解は必要として、物事を別の視点から見ることができる視野の広さが
要るのではないかな、と思います。

## 結論
実は初めてYoutubeに動画を公開しました。
作ってみて世のユーチューバーはすごいと実感しました。
飛び抜けたアイディアと、視野の広さ、伝える技術と、最後までやりきる、それを継続する、、見習いたいと思います。
GitLabCIでftpアップロード

GitLab CIでmainにコミットしたらその一式をftpアップロードする設定メモです。静的ページとかスクリプトなどgitでバージョンやブランチを管理しながらポイっと置く時に使います。

細かいGitLab CIの説明は省略します。

## ファイル

.gitlab-ci.yamlを作成し、プロジェクトルートにおきます。

```yaml:.gitlab-ci.yaml
stages:
  - deploy

deploy-prod:
  stage: deploy
  image: maurosoft1973/alpine-lftp
  variables:
    FTP_SERVER: ''
    FTP_PORT: '21'
    FTP_USERNAME: ''
    FTP_PASSWORD: ''
    FTP_LOCAL_FOLDER: './'
    FTP_REMOTE_FOLDER: './www/'
  only:
    - main
  script:
    - /restore_last_git_modified_time.sh
    - lftp -e "set ssl:verify-certificate no; set ftp:use-mdtm-overloaded true; open $FTP_SERVER; user $FTP_USERNAME $FTP_PASSWORD; mirror -X .* -X .*/ --reverse --verbose --delete $FTP_LOCAL_FOLDER $FTP_REMOTE_FOLDER; bye"
```
上記設定は

- SSL証明書をチェックしない
- ファイル更新時刻を修正する（アップロード時刻でなくGit同期する）
- ミラーリングを行い「.」で始まるファイル/フォルダは転送しない
- 同期元(git)にないファイルは削除を行う

という感じです。lftpの引数なので必要に応じて変更します。

variables部分は上記ファイルに書き込む場合は公開権限に注意してください。普通はセキュリティをちゃんと考えてGitLabの`Settings -> CI/CD -> Variables`に情報を追加します。

![スクリーンショット 2023-12-12 13.04.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14768/1679ded6-a196-39eb-6bca-e2dfa78fabff.png)

コミットして実際にrunnerを動かして確認します。

## せつめい

lftpの入ったalpineイメージを使います。12MB程のコンパクトなイメージです。

https://hub.docker.com/r/maurosoft1973/alpine-lftp

特にひねらずページのサンプルほぼそのままです

`restore_last_git_modified_time.sh`を実行することで、ファイルにレポジトリーの最終変更日がセットされます。

そのカレントディレクトリー（=gitのカレントディレクトリー）のファイルをFTPアップロードします。

## ひとこと

とりあえずうまくいったので自分メモです。
アイスタイルの新卒エンジニアになって半年を振り返る

## 目次
- はじめに
- 4~6月
- 7~8月
- 9~12月(今現在)
- 最後に

## はじめに
この投稿はアイスタイル [Advent Calendar 2023](https://qiita.com/advent-calendar/2023/istyle) の18日目の記事です。

アイスタイル新卒1年目のonnです。
アイスタイルに新卒エンジニアとして入社して9ヶ月がたちました。

入社してからの9ヶ月を時系列で振り返りたいと思います。



## 4~6月
4月は総合職の方と一緒に集合研修を行いました。ここで基本的なビジネスマナーやアイスタイルついての理解を深める研修を行いました。

5,6月は「OJT研修」として数人ごとに現場の各部署に配属され、実業務に近い研修を行いました。1人あたり2部署を経験することができました。

この期間は学生から社会人への切り替え期間ということもあり大変なこともありましたが、今となってはとても良い経験だったと思います。
また総合職の方々とも仲を深められた期間でもありました。
(ちょこちょこ同期全員で同期会をしたり休日も一緒に遊びに行ったりととても仲良しです)

## 7~8月
7月から8月中旬まではエンジニア研修を行いました。
出社とリモート半々くらいで行われました。
講師は主に社員の方でしたが、AWSの外部研修に参加する機会もありました。

簡単にエンジニア研修についても振り返っていきたいと思います。

(※アイスタイルの新卒エンジニア研修は毎年内容が変わります。ですが、雰囲気は伝わると思うので就活生の皆さんの参考になれば幸いです)

研修内容は大きく分けて以下の3つでした。
- チーム開発
- 部署説明
- 1on1

##### チーム開発
チーム開発はアイスタイルの開発フローを理解する、という目的のもと実施しました。
実際のアイスタイルの開発フローである
1. 要件定義
2. 設計
3. 見積もり
4. 開発
5. サービステスト
6. リリース

を講師の方にサポートしていただきながら行いました。

講師の方が事前に研修用のサービス(コスメクチコミサイト)を開発してくださっており、それに対して機能追加をしたり、バグを改修したりを開発フローに沿って行いました。
実務にとても近い経験ができました。

##### 部署説明
各部の部長に部署について説明していただきました。
また部署のミーティングに参加する機会もいただきました。
各部署が何をしているかが包括的にわかるとても良い機会でした。

##### 1on1
10人くらいの社員さんとそれぞれ2回ずつ1on1をして頂きました。
この1on1では研修中の疑問点や、配属の相談、エンジニアとしての考え方など様々なことを相談できました。

以上が2023年新卒エンジニア研修の内容になります。
講師の方のサポートも手厚く、疑問点なども気軽に聞けるとても良い環境でした。
アウトプット重視のとても充実した研修期間でした。

またそれだけでなく、テック全体の各部署について知ることができたり、いろんな社員の方と関わることが出来ました。

## 9~12月(今現在)
8月中旬にエンジニア研修が終わり、ECの決済周りや店舗に関するシステムなどを開発する部署に配属になりました。

アイスタイルでは配属後の1人1人にメンターがつき、ほぼ毎日1on1(夕会)をしてくださいます。
そこでわからなかったことを聞いたりして、日々の不安を解消することができました。
(私のメンターはとても過保護&優しすぎるので9月10月あたりまでは朝会もしてくださってました...本当にありがたかったです。)

9~12月の間で
- 機能追加(Laravel + Vue)
- 画面の改修(Laravel)
- APIの作成(Laravel)

など他にもさまざまなタスクを任せていただきました。
一人で解決できないこともメンターをはじめ、同じ部署の先輩方が優しく教えてくださりました。

恩返しするためにも早くチームの戦力となれるよう頑張っていきたいと思います！

## 最後に
入社して9ヶ月経って思うのはアイスタイルに入社して本当に良かった、ということです。
みなさん本当に優しく、いつでも親身になって寄り添ってくださいます。
そんな先輩たちを見ていて自分もそんな先輩になれたらなと思います！