OmniAICreator/Qiita-1.07M huggingface dataset:
TypeSpec OpenAPI を利用したopの取り扱い

# TypeSpec OpenAPI を利用したopの取り扱い

## 背景

個人的には、OpenAPIの定義ファイルとして
Model層(Model + op) + OpenAPIの定義ファイルを分けて書くことを実施したいと思っていたが、
普通にnamespaceなどを利用しないで書いた場合に問題が生じる。
また、namespaceを利用してモデルを記載した場合も同様にmodel名にnamespaceがprefixがついてしまい、気持ちわるいと思った。


## 解決したい課題

1. opをnamespaceなしに記載した場合、openapiに定義されてしまう課題
1. namespaceを利用してmodelを定義した場合に、namespaceがprefixについてしまう

## 1. opをnamespaceなしに記載した場合、openapiに定義されてしまう課題

### 1-1. 課題

```blog.tsp
model Blog  {}
model CreateBlogDTO {}

op createBlog(dto: CreateBlogDTO): Blog

@resource("/blogs")
interface BlogAPI {
   op create is createBlog;
}
```

上記でopenapiを作成した場合に、
```openapi.yaml
paths:
  /:
      post: //blogs postと同じ
  /blogs:
      post: / postと同じ
```

上記のように意図しないschemaが生成されてしまう。

### 1-2. 回避策

[namespace](https://typespec.io/docs/language-basics/namespaces/)を利用して、operationをまとめる。

```blog.tsp
model Blog  {}
model CreateBlogDTO {}

namespace BlogOperations {
  op createBlog(dto: CreateBlogDTO): Blog
}

@resource("/blogs")
interface BlogAPI {
   @operationId("createBlog")
   op create is BlogOperations.createBlog;
}
```

上記を元に生成した場合は、意図してないschemaが生成するのを防げる。

```openapi.yaml
paths:
  /blogs:
    post:
```

## 2. namespaceを利用してmodelを定義した場合に、namespaceがprefixについてしまう

### 2-1. 課題

```blog.tsp
namespace BlogModule {
  model Blog  {}
  model CreateBlogDTO {}
}
```

```openapi.yaml
components:
  schemas:
    BlogModule.Blog:
    BlogModule.CreateBlogDTO:
```

### 2-2. 回避策

namespaceを利用せずにglobalで記載する。

```blog.tsp
model Blog  {}
model CreateBlogDTO {}
```

```openapi.yaml
components:
  schemas:
    Blog:
    CreateBlogDTO:
```
【個人メモ】Ruby on Rails チュートリアル 第5章

Ruby on Railsチュートリアルで学んだ内容を個人的なメモとして簡単にまとめたものです
# 個人メモ
- モックアップ(ワイヤーフレーム)
ユーザーインターフェイスの概要を示したもの
- Bootstrap
  - Bootstrapは bootstrap-sass gemを使ってRailsアプリケーションに導入できる
  - Bootstrapにてnavberやnav、navbar-nav、navbar-rightクラスには特別な意味がある
- パーシャル(partial)
Webサイトのレイアウトにページごとの内容を挿入する
ex) <%= render 'layouts/header' %>
  - renderと呼ばれるRailsヘルパーを用いてヘッダーの情報を置き換えている
  - _header.html.erbというファイルを探してその内容を評価し、結果をviewに挿入している
- アセットパイプライン
SassとAsset Pipelineは、開発効率のために切り分けられたCSSの冗長な部分を圧縮し、本番環境に最適化した結果を出力する
- 名前付きルーティング
ex) <%= link_to "About", about_path %>
- 統合テスト(Integration Test)
  - テンプレート作成
rails generate integration_test ファイル名
  - 実行コマンド
rails test:integration
- リンクのテスト
ex) assert_select "a[href=?]", about_path
  - about_pathのリンクが存在するかどうかを、aタグとhref属性をオプションで指定して調べる
  - Railsは自動的に"?"をabout_pathに置換している
  - これにより <a href="/about">...</a> のようなHTMLがあるかどうかをチャックできる
【Ruby】インスタンスメソッドとクラスメソッドの使いわけ

# はじめに
こんにちは、絶賛Ruby勉強中のものです。
本日はRubyのインスタンスメソッドとクラスメソッドの使い分けについて説明していきたいと思います
Rubyの経験がまだ浅い私は、クラスメソッドの使い時をあまり理解しておらずインスタンスメソッドで代用できるのでは？と考えておりました。
そこで本日はインスタンスメソッドとクラスメソッドの使い分けについて記事を書いていこうと思います。
なお、インスタンスメソッドとクラスメソッドの説明については、記事を書いたので詳しく見たい方は確認していただければ幸いです。

https://qiita.com/Taira0222/items/aca062a0cfb879fded31

# インスタンスメソッド
まずは、フルネームと年齢を取得する`User`クラスと`user1`,`user2`インスタンスについてみていきましょう。
```ruby:instance.rb
class User
  attr_accessor :first_name, :last_name, :age
  
  def initialize(first_name, last_name, age)
    @first_name = first_name
    @last_name = last_name
    @age = age
  end
  
  # インスタンスメソッド
  def full_name
    "#{@first_name} #{@last_name}"
  end
end

# インスタンスメソッドの利用例
user1 = User.new("Taro", "Yamada", 25)
user2 = User.new("Hanako", "Tanaka", 30)

puts user1.full_name  # => "Taro Yamada"
puts user2.full_name  # => "Hanako Tanaka"
```
上記のコードでは、`full_name`メソッドを使って`User`のインスタンスである`user1`からフルネームを取得しています。`user2`も同様です。
このように、<strong>インスタンスメソッドはインスタンスごとに異なる値を持つデータに対して処理を行う</strong>ため、個別のユーザー情報を扱いたいときに便利です。
ほかにも鈴木さんとか山本さんとか様々な方の名前をこのクラスで作っていくと思いますが、人数を何人か数えたい場面が出てくると思います。


# クラスメソッド
そこでクラスメソッドを使うと比較的楽に処理できます。
```ruby:class.rb
class User
  attr_accessor :first_name, :last_name
  @@user_count = 0  # ユーザーの総数を格納するクラス変数

  def initialize(first_name, last_name)
    @first_name = first_name
    @last_name = last_name
    @@user_count += 1  # インスタンスが生成されるたびにカウント
  end

  def full_name
    "#{@first_name} #{@last_name}"
  end

  # クラスメソッド
  def self.total_users
    @@user_count
  end
end

# 利用例
user1 = User.new("Taro", "Yamada")
user2 = User.new("Hanako", "Tanaka")

puts User.total_users  # => 2
```
`@@user_count`というクラス変数で、`User`インスタンスが作成されるたびにユーザー数をカウントしています。
クラスメソッド `self.total_users` を使うことで、`User`クラスにどれだけのユーザーが登録されているかを確認できます。
このように、<strong>クラスに関する全体的な情報（今回はユーザーの総数）を管理したい場合</strong>にクラスメソッドを使うと便利です。

# まとめ
上記の例を踏まえて、それぞれどのような場面で使用するかまとめていきます。
* インスタンスメソッドは個別のデータを処理するため、インスタンスごとの値を操作したい場合に使います。
* クラスメソッドはクラス全体に関連する情報を操作するため、インスタンスの生成が不要な処理や、複数のインスタンスを横断するデータを扱いたいときに使います。
[Blender] GLTF/GLBマテリアルの裏技

## はじめに
GLTFやGLBを作る際、データ容量やリアルさとの戦いで日が暮れる日々かと思います。
本稿ではマテリアル設定に焦点を当てて、より良いデータの作成方法をご紹介いたします。
使えそうな裏技が見つかったら更新していく予定です。

https://docs.blender.org/manual/ja/dev/addons/import_export/scene_gltf2.html

https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html#materials

## 前提
* Blender 3.6以上（下位バージョンでは検証していないだけです。）
* 基本的なマテリアル設定ができる

**レンダラをEeveeに設定しておいてください。**
他の3Dソフトをご使用の方にも役立つ内容かと思います。

## アンビエントオクルージョン（AO）テクスチャの割り当て方法

https://en.wikipedia.org/wiki/Ambient_occlusion

https://docs.blender.org/manual/ja/dev/addons/import_export/scene_gltf2.html#baked-ambient-occlusion

プリンシプルBSDFではAOテクスチャの割り当て先が無いため、`glTF Material Output` という特殊なノードを使います。
よくチュートリアル等で既存のGLTFからコピーして、という方法が紹介されていますが、実はただのグループノードであり一から作ることが可能です。

AOテクスチャは本来グレースケールですが、Blenderマニュアルにある通り
(R)AO (G)ラフネス（粗さ） (B)メタリックを合体させたRGBテクスチャを使うことも可能です。

![AO2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3795435/dc0dd6a3-4680-dab5-fd28-55585c9f52f8.jpeg)
![AO1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3795435/79042b54-709d-01e6-34cc-c098c74ae212.jpeg)



<details><summary>説明</summary>

適当なノードでグループを作り、`グループ入力`と`グループ出力`のパラメータをすべて削除
`グループ入力`に以下を設定
`Occlusion`（Float）
`Thickness`（Float）
`Specular`（Float）
`Specular Color`（カラー）デフォルト白（#FFFFFF）

Tabキーで戻り、参照しているノードツリーの名前を`NodeGroup`から`glTF Material Output`に改名
`画像テクスチャ`（カラー）→
（カラー）`カラー分離`（赤）→
（Occlusion）`glTF Material Output` で繋ぐ
</details>

## テクスチャ画像をタイル状に並べる方法

https://docs.blender.org/manual/ja/dev/addons/import_export/scene_gltf2.html#uv-mapping

生地や柄模様など、同じ模様が並んでいる場合に
全体的な1枚のテクスチャ画像にせず、部分的な小さな画像を並べて作る方法です。

縦横等サイズである必要はなく、縦だけ短くして並べるということも可能です。

![tile1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3795435/78b48b50-332e-14e6-1bee-0d3debb0c8cc.jpeg)


<details><summary>説明</summary>

`UVマップ`（UV）→
（ベクトル）`マッピング`（ベクトル）→
（ベクトル）`画像テクスチャ` で繋ぐ

マッピングのスケール`X`、`Y`の値を変更
※位置や回転の変更も保持されます。
</details>

## テクスチャに単色を上乗せしたベースカラー（アルベド）の設定方法
インテリアなどで、ベースの模様は同じであるもののパーツによって色味を変えたい時、1枚のテクスチャ画像を使いまわすことで色ごとに作らず済む方法です。

※テクスチャ画像にテクスチャ画像を上乗せすることはできません。単色のみ可能です。

※あくまでも単色が上乗せされるものであり、1枚のテクスチャ画像の中で複数個所の色を個々に変えることはできません。

![color.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3795435/1541d59e-7128-bc1e-141c-d64094d0e1c9.jpeg)


<details><summary>説明</summary>

`画像テクスチャ`（カラー）→
（A）`ミックス`（結果）→
（ベースカラー）`プリンシプルBSDF` で繋ぐ

ミックスのFloatを`カラー`、ミックスを`乗算`、係数を`1`、`B`の色を上乗せしたい色に変更

※ミックスはエクスポート時にColor Factorに名前が変わりますが同じものです。
</details>

## 所感
記載の内容はAR等、WebXR環境 / 古いThree.jsが使われている / [glTF 2.0 Extension](https://github.com/KhronosGroup/glTF/blob/main/extensions/ "glTF 2.0 Extensionのリポジトリ")が組み込まれていないといった場合に反映されない可能性が無くもないので事前にテストをおすすめします。

GLTFはバンプマップが使えなかったり足りない要素もありますが、それでも汎用3Dデータとは思えないくらい多くの要素を保持できるので凄いですよね。
【MySQL テーブルを複製する】



# はじめに

DBのパフォーマンス改善を実施中に似たような条件のテーブルをいくつか用意する必要があり、その際に実施したコマンドやエラー解消について残しますので参考にしていただけますと幸いです。

#### 開発環境
mysql:8.4.0
(確認用コマンド select version(); )

# 中身ごとテーブルを複製する方法
## 複製コマンド
```Copy.sql:

CREATE TABLE [新テーブル名] LIKE [コピー元テーブル名];
INSERT INTO [新テーブル名] SELECT * FROM [コピー元テーブル名];

```
解説：
CREATE TABLE 新テーブル名 LIKE コピー元テーブル名; は、指定した「コピー元テーブル名」の構造（カラム、データ型、インデックスなど）をそのまま使って、「新テーブル名」として新しいテーブルを作成します。

INSERT INTO 新テーブル名 SELECT * FROM コピー元テーブル名; は、「コピー元テーブル名」からすべてのデータを取得して、「新テーブル名」に挿入します。

## エラー対処
上記実行時に日付関連のエラーが出た場合、以下を実行

```Copy.sql:

SELECT @@sql_mode;

```

解説：
SELECT @@sql_mode;で、現在のSQLモードがどう設定されているかを確認します。
STRICT_TRANS_TABLESモードの場合、日付に0000-00-00など無効な値が含まれているとエラーとなります。

結果に'STRICT_TRANS_TABLES'が含まれていれば以下を実行

```Copy.sql:

SET sql_mode = 'NO_ENGINE_SUBSTITUTION';

```
または、
```Copy.sql:

SET sql_mode = REPLACE(@@sql_mode, 'STRICT_TRANS_TABLES', '');

```
解説：
ここでは、SQLモードを STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION に設定しています。
NO_ENGINE_SUBSTITUTION はエンジンの指定がない場合に自動で代替エンジンを使用しないようにする設定です。
STRICT_TRANS_TABLES を外すことで、0000-00-00のような日付がエラーとならず、代わりに警告が出るようになります。



# 補足
SELECT @@sql_mode;

で使用した@@とはmysqlサーバのセッション変数を参照するためのものです。
@@global.sql_modeのようぬするとサーバ全体の設定を参照できます。
@@session.sql_modeまたは@@sql_modeのようにすると現在のセッション内での設定を参照することができます。
そのため、ほかのセッションや全体設定は影響を与えないで一時的に変更することができます。



# 参考文献
本記事は以下情報を参考にして執筆しました。

-- https://qiita.com/nao_ipub/items/1151304ea8396770324a
スマホでページを開くとbodyの外側が白くなった

## 課題

next.jsで開発中、特定のプロジェクトだけスマホで開いたと時のbodyの外側が白くなった。

![IMG_6196.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3776694/8a57d406-8c6f-f158-e1b1-f637e656aa65.png)

通常bodyにbackground-colorを指定すれば下画像のように色が統一されるはずと思っていたので四苦八苦した。

![IMG_6197.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3776694/44021065-8f40-9bc1-ad99-13a0b1c4c49f.png)

## 原因

manifest.jsonに`"theme_color": "#fff"`が指定されているのが原因だった。

適当に検索して出てきたfaviconのジェネレータが出力したmanifest.jsonを何も考えずにプロジェクトに追加したためだった。
テーマカラーはステータスバーやアドレスバーの色に影響を与えるため、知らぬ間にオーバーライドしていた。

theme-colorの記述を消すか、任意の色、今回の場合ではbodyの背景色を指定すればいい。

ただし、metadataでテーマカラーを指定する場合に、重複や競合に注意したい。
localhostでデバッグしてる開発中のサイトをスマホでも確認したい。

開発中のサイトをスマホで開こうとする時、調べるとpcのipアドレスを入力する方法がたくさん出てきたが普通にめんどくさかった。
ngrokを使ってそこらへんを省きたい。

↓からngrokをインストール。最初はサインアップしないといけない。

https://download.ngrok.com/mac-os?tab=install

フレームワークなど使ってない場合はローカルサーバーを任意のポートでたてる。別にpython以外でも構わない。

```bash
python -m http.server xxx
```

ngrokの`xxx`にポート番号を指定する。

``` bash
ngrok http xxx
```

↓のように`https://xxxx-xxx-xx-xxx-xxx.ngrok-free.app`が出てくる。このアドレスでスマホでも開発中のサイトにアクセスできる。

```bash
Forwarding    https://xxxx-xxx-xx-xxx-xxx.ngrok-free.app -> http://localhost:3000
```
WDMってなんだろう

皆さんこんにちは。長谷川です。
今回はWDMについて簡単に説明していこうと思います。

皆さんは「WDM」と聞いて何を思い浮かべますでしょうか？また、この用語聞いたことがある方いますでしょうか？

恐らく聞いたことが無い、聞き馴染みのない用語だと思います。
それではWDMとはなんぞや？ということを書いていきたいと思います！！

# WDMとは？
まずWDMとは「Wavelength Division Multiplexing」と呼ばれるネットワーク機器を指します。

# WDMの役割とは？
WDMは、複数の波長の光信号を1本の光ファイバーで同時に伝送する技術の事を指しており、それを実現するための装置です。

私も二年前に初めて聞きました笑

# WDMってどんな機器？
基本的にWDMの役割は(大きく言うと)以下の役割を担ってくれます。
* 物理的に遠い位置にある装置(WDM)までデータを送り届ける
* 複数の光信号を束ねてくれる(きちんとまとめてくれる)

WDMを使用する場合、大規模なネットワークを構築する場合に使用すると思います。
例えば、東京から大阪までデータを送り届ける場合、(ネットワーク的に色々な技術がありますがそこは省きます)東京から大阪までケーブルをつなぐ。なんてことはしないですよね。
※できるかもしれませんがエラー出ますよね。。。笑

そこで活躍するのがWDMです。
WDMはデータを扱う際、物理データとして扱います。(レイヤでいうと1に相当します)

また、光ファイバーケーブルには様々な種類がある為それをまとめるといった機能も備えています。
→この機能が無いと光ファイバーケーブルを通じてデータを送ることができなくなります。

物理的に距離が遠い場所に送り届けようとすると、どうしてもデータが減衰してちゃんと相手に届きにくくなるといったことが発生しやすくなる為、WDMはデータの中継役として使うことができます。
※イメージとしては以下のような感じです。

(東京)Router⇔(東京)WDM⇔(横浜)WDM⇔(名古屋)WDM⇔(大阪)WDM⇔(大阪)Router

上記で言うと、横浜、名古屋のWDMがデータを受け取ったら一旦データを強くして、相手に送りなおすという役割も担っています。
※私は元気玉理論と呼んでいます笑

なかなか触れる機会が無い装置だと思いますが、こんな装置もあるんだなと思っていただければ幸いです。
それではまた。
【ChatGPT】症状を医者に説明するために使う。


　どうも、カーブミラーです。

　今回は、医師に説明するためのメモ作成にChatGPTを使うやり方、です。

:::note info
本記事は、ChatGPT（有料版）
で行なっております。画像は
ありません。　あしからず。
:::
　まずは、ニュース。

　ChatGPT に
　　履歴の検索機能が
　　　搭載されました。
　　　　[OpenAI公式ポスト](https://x.com/OpenAI/status/1851340615344406781?t=W3NLur1ydzOG6DZFHwstkQ&s=19)

　アプリ版にはありましたが、
　　Web版にも搭載されました。

　履歴を出して、
　　ルーペアイコンをタップすると、
　　　検索窓が出てきます。
![Screenshot_20241030-085205~2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457238/58b32efd-9c23-fdea-b0f6-3169e1fe03b6.png)

　そこにキーワードを入力すれば、
　　リストアップされます。

　そこから選べば、
　　そのセッションを
　　　再開できます。

　アクセス可能なのは、
　　現在は、PlusとTeamだけ。

　 EnterpriseとEduは、
　　1週間以内に
　　　アクセスできるようになります。 

　無料ユーザーは
　　来月中に
　　　アクセスできるようになります。
***
　さて、本題です。

　今回は、
　　医師への説明をするために
　　　ChatGPTを使うやり方、です。

　日々の生活で
　　体調がおかしくて、
　　　病院に行くことは
　　　　ふつうです。

　しかし、
　　イザ、医師に説明するのは
　　　非常に煩わしいものです。

　場合や人によっては
　　うまく話すこともできないことも。

　そこで
　　毎日の記録（メモ程度OK）を
　　　付けて、それを見せるだけでも
　　　　医師は助かるそうです。

　その記録を
　　ChatGPTに渡して整え、
　　　印刷して（スマホ画面でもOK）
　　　　見せれば、より良いでしょう。

　今回のこのテーマは
　　バクさんという方のポストを見て
　　　書いています。
　　　　[バクさんポスト](https://x.com/DrYumekuiBaku/status/1851028672133919197?t=6qWiXeZpsbr7kMpP4-FcbA&s=19)

　バクさんは、
　　精神科医で、
　　　実際に患者さんが
　　　　そうして印刷したものを
　　　　　持ってこられたそうです。

　　それで
　　　“助かる”とも書いています。

　まぁ、医師の中には
　　“それが何？”みたいな態度の
　　　医師もおられるらしいので
　　　　別の病院に掛かる方が
　　　　　いいのかもしれませんね。
***
　手書きメモを
　　わざわざ手入力せずに
　　　スマホで撮影して、
　　　　アップロードして
　　　　　OCR・整えることも
　　　　　　ChatGPTでできますしね。

　あるいは
　　病院に行く前に
　　　症状や気付いたことを
　　　　ChatGPTに書いて
　　　　　現状説明書を作成しても
　　　　　　いいのかもしれません。

　　現状説明書の出し方は
　　　以下のとおり。

　　思い付くまま、
　　　一行一行に綴っていき、
　　　　最後に、下記のPromptを
　　　　　追記・送信してください。
```Text:現状説明書Prompt
上記の状況を、医者に見せるように箇条書きにしてください。
```

　こちらは
　　[usutakuさんポスト](https://x.com/usutaku_channel/status/1851411891782050270?t=b2Yzh9-8kc1J-NyhhsD27w&s=19)
　　　から引用しています。
***
　また、人によっては、
　　ライフログを取る方も
　　　おられます。

　そこに、どんな症状が現れ、
　　どう対処したのかを
　　　書いていけば、
　　　　それをChatGPTに渡すことで
　　　　　現状説明書を
　　　　　　作成可能でしょう。

　医師との
　　より良い関係性を
　　　築くためのひと手間に
　　　　ChatGPTを使うのも
　　　　　良いかと思います。

　みなさんの
　　作品制作の糧に
　　　なれば、幸いです。

　今回は、ここまで。
Github Sparkとは？【概要と活用方法】

現代のビッグデータ処理において、Githubはコード管理と協力のプラットフォームとして、Apache Sparkのような分散データ処理フレームワークと組み合わせることで、データエンジニアや開発者の作業効率を大幅に向上させることができます。本記事では、GithubとSparkを組み合わせて、ビッグデータプロジェクトを効率的に開発・管理する方法を紹介します。

## Github と Apache Spark の紹介

**Github** は、世界最大のコードホスティングプラットフォームの一つであり、開発者に効率的なコラボレーション環境を提供します。個人プロジェクトから企業チームまで、Githubはバージョン管理、ブランチ管理、開発プロセスの便利なソリューションを提供します。

**Apache Spark** は、大規模データ処理に使用されるオープンソースの分散計算システムです。高速な計算と簡単なAPIインターフェースにより、Sparkはビッグデータ処理、機械学習、リアルタイムストリーム処理などの分野で広く利用されています。

## GitHub Sparkとは？

![github-spark-1.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3877124/dfd9096b-edba-870a-16a2-cb836ade8890.jpeg)

[GitHub Spark](https://githubnext.com/projects/github-spark)は、「**誰でも自分のためのソフトウェアを作成・カスタマイズできるようにするAIツール**」です。

このツールを使うことで、コードを書く必要がなく、自分だけの小さなアプリ（Spark）を簡単に作り、共有することができます。

開発者は、よく自分の環境をカスタマイズして生産性を向上させたり、使いやすくしたりしますが、通常、アプリを一から作るのは手間がかかるため、多くのアイデアを諦めてしまうことがあります。

GitHub Sparkは、そんな悩みを解決し、自分にぴったりのアプリを簡単に作れるようにするために生まれました。

## Github と Spark の統合の利点

GithubとSparkを組み合わせることで、開発者は以下の利点を享受できます：

- **バージョン管理**：Githubのバージョン管理機能を使用して、開発者はSparkアプリケーションの進捗を簡単に追跡し、チームメンバーと共同で開発できます
- **自動化されたデプロイ**：Github Actionsを活用することで、Sparkアプリケーションのテストとデプロイを自動化し、プロジェクトの納品効率を向上させます
- **CI/CD統合**：GithubはCI/CDツールとの統合をサポートしており、開発者はSparkアプリケーションを迅速にテスト、検証、リリースし、コードの品質を確保できます

## 実践における活用
典型的なワークフローは以下のようになります：

- **コード管理**：開発者はGithub上にSparkプロジェクトを作成し、メインブランチ（master）と機能ブランチ（feature）を設定します
- **開発と協力**：チームメンバーは各自のブランチで機能モジュールを開発し、Pull Request（PR）を通じてコードレビューを行います
- **自動テスト**：PRの提出時に、Github Actionsをトリガーし、自動テストを実行して、Sparkと統合されたコードに問題がないことを確認します
- **デプロイと監視**：コードレビューが完了すると、自動的にSparkクラスターへのデプロイタスクがトリガーされ、継続的インテグレーションとデリバリーが実現します

## 終わりに
クラウドコンピューティングとビッグデータ技術の発展に伴い、GithubとSparkの統合は、より多くの革新と可能性をもたらすでしょう。例えば、GithubとSparkの深い統合により、ビッグデータプロジェクトの自動化フローとチームコラボレーションの効率がさらに最適化され、より大規模なデータ処理プロジェクトが実現する可能性があります。

**最後まで見ていただきありがとうございました！
この記事を読んで少しでも理解を深めていただければ幸いです！**
Power Automate Desktopでスカウト自動送信をしたいです

中小企業で採用担当している者です。

スカウト工数削減のため、Win11の環境で、Power Automate Desktopを用い、スカウトの自動送信を試みています。
UI要素を識別する形で学生を特定しようとすると、学生ごとに固有のIDが異なるため、手順5が実装できません。
何か良い方法はございませんでしょうか？


1　採用サイトのWebページを開く
2　ログインする
3　検索条件リストからあらかじめ用意した検索条件をプルダウンで選択する
4　検索ボタンを押下する

5　表示されたリスト（学生の顔写真とID、プロフィール文の一部が表示されている）の学生を選択し押下

6　別タブで学生の情報ページが開く
7　学生の情報ページよりスカウト送信ボタンを押下する
8　学生の情報ページのタブを閉じる
9　5に戻る


あれこれ、Web検索してみたり、書籍をあさってみたりしたのですが、上記のようなケースが見つからず困っております。。
お知恵をお貸しいただけたら助かります。
Phomemo T02をMacから使ってみる

## はじめに
### 偉大なる先駆者様

https://qiita.com/ryo-endo/items/2000009d0783b34b7228

この記事は上記の記事をT02に対応させたときの備忘録です。
### 筆者の環境
ハードウェア : Macbook Air M2(2023)
OS : Sonoma 14.6.1
RAM : 8GB
エディタ : VSCode
Pythonのバージョン : 3.13.0 (anaconda)
にて動作することを確認。

### 結論
上記の記事からリンクされている[こちらのGithubのコード](https://github.com/ryo-endo/phomemo-printer)にある「PhomemoM02Pro_constants.py」内を、
```diff_python3
- DEVICE_NAME = 'M02 Pro'
+ DEVICE_NAME = 'T02'
```
とするだけで動きました。

:::note warn
注意点
main.pyをそのまま実行するとテキストが'Hello Phomemo **M02Pro** !'として出てきてしまうのでT02に書き換えないといけません。(1敗)
```diff_python
- await print_text(client=client, text='Hello Phomemo M02Pro!', fontsize=32)
+ await print_text(client=client, text='Hello Phomemo T02!', fontsize=32)
```
:::

### これからやってみたいこと
Bluetooth通信に使われてるbleakライブラリはどうやらPython-for-Androidにも対応しているようなので、スマホから印刷できるようにしてみたい。(公式アプリ使え)
### おわりに
元の記事を書いてくださった@ryo-endo氏、
及びその元となっているコードを書かれた方々に感謝の意を表します。
Windows11のPC起動時にChromeを全画面表示する方法

# はじめに
Windows11のPC起動時に、Chromeを全画面表示する方法について調べたので、備忘録としてこの記事にまとめます。

# Windows11のログインパスワード入力をスキップする
[こちらの記事](https://solutions.vaio.com/4729)を参考にして設定してください。

# スタートアップフォルダを確認する
エクスプローラのアドレスバーに「shell:startup」を入力すると、スタートアップフォルダが表示されます。

# Chromeのショートカットを作成する
1.スタートアップフォルダ内で「右クリック」-「新規作成」-「ショートカット」を選択します。
2.「項目の場所」に下記を入力します。
~~~
"C:\Program Files\Google\Chrome\Application\chrome.exe" --start-fullscreen --user-data-dir=c:\chrome2 "https://generosity.co.jp"
~~~
3.ショートカットの名前は自由に設定して構いません。

以上で設定は終わりです。
その後、PCを再起動するとChromeで指定したサイトが全画面で表示されます。

# 詳細説明
~~~
C:\Program Files\Google\Chrome\Application\chrome.exe
~~~
これはChromeの実行ファイルのパスです。PCによって異なる場合があるので、各自のPCに合わせてパスを確認してください。

~~~
--start-fullscreen
~~~
Chromeをフルスクリーンで起動するオプションです。ただし、私の環境ではこれだけではフルスクリーンにならなかったため、次のオプションを追加しています。
~~~
--user-data-dir=c:\chrome2
~~~
新しいユーザープロファイルを指定してChromeを起動するオプションです。これによりフルスクリーンで表示されるようになりました。

~~~
"https://generosity.co.jp"
~~~
表示したいWebサイトのURLです。必要に応じて任意のURLに変更してください。

# おわりに
Windows11のPC起動時にChromeを全画面表示させる方法の設定手順を説明しました。
特定のWebサイトをフルスクリーンで自動表示させたい場合に役立つ設定です。
問題が発生した場合は、Chromeのパスやオプションの確認、WebサイトのURLが正しいかなどを再度確認してみてください。
この記事が参考になれば幸いです。
ターミナルのテキストエディタが色々あったのでまとめてみる

# ターミナルで使えるエディタまとめ

ターミナルのエディタは`nano`とか`vim`しか使っていなかったけど、調べたら色々あることにいまさら気づいたのでまとめ。

## :point_up: 初心者向け
### nano（ナノ）
- **特徴**：軽量で起動が速く操作が簡単。基本的な編集機能も揃っている。
- **利点**：画面下にコマンド一覧が表示されるため、ショートカットを覚えやすく初心者にも扱いやすい。
- **コマンド**：`nano ファイル名`

---

## :point_up: 効率厨向け
### vim（ヴィム）
- **特徴**：軽量で、ショートカットを駆使して高速編集が可能。カスタマイズ性が高く多機能。
- **利点**：コマンドを覚えれば高速に作業が進むため熟練者に人気。リモートサーバーでもよく使われる。
- **コマンド**：`vim ファイル名`

---

## :point_up: 多機能マニア向け
### emacs（イーマックス）
- **特徴**：プラグインやカスタマイズが豊富で、テキストエディタ以上の使い方も可能。メール管理やファイルマネージャーとしても利用可能。最初はインストールが必要。
- **利点**：万能ツールとして愛用者も多く、エディタから広範な作業をこなせる。
- **コマンド**：`emacs ファイル名`

---

## :point_up: シンプルだけどちょっと便利な機能も欲しい人向け
### micro（マイクロ）
- **特徴**：`nano`に似たシンプルなUIと、直感的なショートカットが揃う現代風エディタ。`vim`と`nano`の中間的なエディタ。最初はインストールが必要。
- **利点**：わかりやすいインターフェイスで、初めてでも扱いやすくカラフルな表示が見やすい。個人的にかなり好きです。
- **コマンド**：`micro ファイル名`

---

## :point_up: プラグインを活かして開発を加速したい方向け
### Visual Studio Code (VS Code / ブイエス コード)
- **特徴**：Microsoftが提供する多機能エディタ。エクステンションが豊富でカスタマイズして開発が可能。最初はインストールが必要。
- **利点**：プラグインが充実しており各種言語の補完やデバッグに対応。半分GUI操作なので初心者から上級者まで使いやすい。
- **コマンド**：`code .`（ターミナルからVS Codeを開く）
monitoring

## オブザーバビリティ
可観測性：外部からシステムがどれくらい観測可能か
### 情報を収集する　Logs
Kubernetesの標準機能にもあるが、これだとPodがNodeから消えると見られなくなってしまう。
クラウドベンダーのKubernetes環境を使う時、クラウドベンダーのログ保存、検索を使うとKubernetes以外の環境でもみれるようになる
OSSの例：Grafana Loki、Fluented,Fluentbit
### 測定値を処理する　Metrics
測定値の集合。統計的な処理や傾向を見るときに使う。
例えばログインの数を数える時、Logで表示してから一つずつ数えるのは現実的ではない。
メトリクスもログ同様、クラウドベンダー標準機能を使える
OSS:Prometheus
### 通信追跡 Traces（分散トレーシング）
コンテナが複数存在する状態で環境以上が発生した時、どのユーザーのリクエストがどのコンテナを経由したかを調べる時に使う
正確に通信を追跡するにはリクエストの通るミウィ全てにTracesとSpanを設定しないといけないので実装のハードルはちょっと高い。
OSS：OpenTelemetry
Traceを収集するOSS:Jaeger,Grafana tmepo

## モニタリング
### ダッシュボード
MetricsやTraceはある一点だけをみても何もわからない。可視化するためにダッシュボードを作る必要がある。障害調査、性能劣化、異常の発見に使える。
OSS:Grafana
### アラート
異常が出たらわかるように、アラートにはMetricsを使う。
OSS:Prometheus内部にAlertManagerというのがある
自社ドメインの作成

## コアサーバーが安い
「個人事業主 メールアドレス」で検索したサイトからvalue domainとかコアサーバーってのが安いと言われた。
１２か月契約なら月々￥520程度でよいらしい。しかも何やらドメイン登録料、更新料無料とのこと。
※ドメイン登録料は体験後に本契約したら返金される形なので、実質「体験」だけで終わらせることはできないと理解している。

## 体験
しようとしたけど、前述のとおり契約しないとドメイン登録料は取られてしまう（そりゃそうだよね）ので、ドメインはひとまずあきらめて、コアサーバーの使い勝手だけ検証することに。

## コアサーバー体験。まずはSSH接続
SSH接続はputtyからしたいので、PuTTYgenを使ってPutty用の鍵を作成する。
コアサーバーの鍵はSSH鍵なのでそれを元に作成する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3916302/18db0315-c283-78f2-ab63-28e9b478a10d.png)
最近脆弱性が取りざたされたのはECDSA。RSAのほうが弱いけど、コアサーバーのものはRSAぽい（未確認）ので、ひとまずこれで。

「既存の秘密鍵の読み込み」で、コアサーバでダウンロードする前に設定したSSH鍵のパスフレーズを入力して完了。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3916302/efe2111b-36ab-657c-4d4c-177e007127b7.png)

「秘密鍵を保存」で拡張子ppkのファイルを保存（終わったあとで消そうね）

あとはputty.exeに上記ppkを設定して、無事にログイン完了！
今日はここまで

今度はルートディレクトリまで見えたので、独自ソフトをインストールしてみる。
※WordPressとか有名どころはコントロールパネルからぽちればインストールできるぽい。
【Unity】シーン間をまたいだ変数を作成する

## はじめに

こんにちは、かなたです。

Unityのゲーム開発中にシーン間をまたいだ変数を作成したいことがありました。

備忘録として解決方法を残しておきます。


## 使用想定

- リザルトシーンで別シーンの変数を利用したい場合

- 音を再生したい場合


## 1. シーン遷移しても残るクラスの作成

今回は例としてゲームを管理するクラスを作成します。

`DontDestroyOnLoad`が実装されている場合はシーンの遷移時にオブジェクトが破壊されず残ります。

```csharp:GameManager.cs
using UnityEngine;

public class GameManager : MonoBehaviour
{
    public static GameManager Instance { get; private set; }

    public ScoreModel scoreModel;

    private void Awake()
    {
        if (Instance == null)
        {
            Instance = this;
            DontDestroyOnLoad(gameObject);
        }
        else
        {
            Destroy(gameObject);
        }
    }
}

```

クラスに定義した変数は以下のとおりです。
内部にtabletTotalとmissCountを持っています。

```csharp:ScoreModel.cs
public class ScoreModel : MonoBehaviour
{
    public int tabletTotal;
    public int missCount;

    public void Default(int tabletTotal = 0, int missCount = 0)
    {
        this.tabletTotal = tabletTotal;
        this.missCount = missCount;
    }

    public void Miss()
    {
        ++this.missCount;
    }

    public void Correct()
    {
        --this.tabletTotal;
    }
}
```


## 2.最初のゲームシーンにクラスを設定する

Hierarchyに`GameManager`と`ScoreModel`を作成し、Inspectorにクラスを設定します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3922528/02ac5943-dc64-38b7-921c-7f2103b1520b.png)


## 3.シーン遷移で残るか確認

最初に`DontDestroyOnLoad`シーンが作成され、シーン遷移後に`DontDestroyOnLoad`が残ることを確認します。

![image02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3922528/0637f803-9cf7-69d2-9f0c-2e7c86ee44c2.png)

![image03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3922528/a1115197-d14b-79e6-53e5-978c5e33a106.png)

## Ex.変数を参照する

クラスは`GameObject.Find()`で探せます。
今回はゲーム管理クラスの変数を読み込みました。

```csharp:InGameController.cs
public class InGameController : MonoBehaviour
{
    public ScoreModel scoreModel;

    void Start()
    {
        this.scoreModel = GameObject.Find("GameManager").GetComponent<GameManager>().scoreModel;
        scoreModel.Default(0, 0);
    }
}
```




## おわりに

シーン間をまたいだ変数の作成について紹介しました。
Unityのゲーム開発では頻出の内容で、Unityゲーム開発者はできて当たり前の技術とは思います。
何かこの記事で為になることがあれば嬉しいです。
それではさよなら。
IBM Cloud: VPC環境(CentOS9)におけるsingle user modeを使ったpasswordリセット方法

# 1.はじめに

IBM Cloud VPC環境で、不幸にもrootパスワードを設定していなかったり（もしくは忘れてしまったり）、/etc/ssh/sshd_configを誤って構成したり、SSH秘密鍵を紛失してしまったために、環境にログインできなくなった場合には、どうすればよいだろうか？

今から10年ほど前（！？）にIBM CloudのClassic Infrastructure環境（当時はSoftLayerという名前でした）で、[ShinobiLayer: rootユーザー(Linux)のpasswordリセット方法](https://qiita.com/testnin2/items/f304ffa833dac2c41794)という記事を書いた。しかし、Classic Infrastructre環境ではrescue modeというものがあるが、VPC環境にはそれに対応するものが存在しない。

IBM Cloud VPC環境では、snapshotやcustom imageを作成した上で、再度それらから別のVSIを起動する（場合によってはuser dataでカスタムスクリプトも組み合わせて誤った構成を修正する）という方法も１つの方法ではあるが、IBM Cloud VPC環境には`VNC Console`や`serial console`の機能があるので、Linuxのsingle user modeを使ってこれらの問題を解決する方法を本稿で紹介する。

# 2. single user modeの実行方法

1. バックアップとしてsnapshot/custom imageを作成しておく（省略）
2. VNC Consoleを起動する。![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/9c75f5b4-910f-70af-95c3-c4aa1e472dd2.png)
3. VNC Consoleから、再起動を行い、すぐさまVNC Consoleの画面をクリックしてスクロールキーを上下に動かし続ける（あっという間にgrubメニューが終わってしまうので、grubメニューが表示された後にカーソルを移動していたら間に合わない）![test.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/450842fd-953a-f13c-7063-1fb35cb4cc57.gif)
4. 1番上のメニューで`e`を押下。![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/cc5afecc-dd66-9520-3578-359bc89dfe9d.png)
5. `linux`から始まる行において、`ro`を`rw init=/sysboot/bin/sh`に置き換えて、`Ctrl-x`を押下
    - Before![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/e9562cc5-afc2-5300-7b20-ced3e8b76b3d.png)
    - After: ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/93ff8f28-05e7-9531-b32a-9c7bf902101e.png)
6. すると処理が進んで、この画面になる。しかし、ここから先が（理由はわからないが）キーボード操作を受け付けてくれない。![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/ccb73b98-dccd-22c9-4d0d-44b5e6fa2c7e.png)
7. ここからは、`serial console`を起動する。![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/6b64f206-fd2c-3f65-3c98-a523e4ed0bf9.png)
8. `serial console`では、キーボード操作を受け付けてくれる。`chroot /sysroot`でルートディレクトリを移動した後は、`passwd`コマンドでパスワードを変更したり、`/etc/ssh/sshd_config`を編集すれば良い。 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62127/4463529f-b48b-e56e-64e4-b9ac8552aa29.png)
NFS サーバ構築 2024 年度版w

# 対象
[FreeBSD](https://www.freebsd.org/) [14.1-RELEASE](https://www.freebsd.org/releases/14.1R/relnotes/) を元に書いちょりますけん、古いリリースのんはm(__)m
当然じゃが cli で[デーモン君](https://ja.wikipedia.org/wiki/BSD%E3%83%87%E3%83%BC%E3%83%A2%E3%83%B3)を、それなりに操れる人向け✌
注：CPU のアーキテクチャ(armとかriscvとかね)には依存しませんよぉー
# お膳立て
ネットワークが他への通信が可能な事w
たちまち、ファイアウォールはスルーでm(__)m
# 手を動かす(デーモン君)
共有したいディレクトリと、必要であれば制限等の呪文を記述する
必要最小限の記述はディレクトリ名のみでおｋ
```text:/etc/exports
/share -network 2001:db8:beef:dead::/64 -maproot=0 -alldirs
```
リモートマウントポイント [/etc/exports](http://koganemaru.co.jp/cgi-bin/mroff.cgi?sect=5&cmd=&lc=1&subdir=man&dir=jpman-14.1.2%2Fman&subdir=man&man=exports) 解説
| パラメタ | 解説文 |
|:-|:-|
| /share | nfs で共有したいディレクトリ名 |
| -network | ネットワークアクセス制限 |
| -maproot | クライアントからユーザの認証する際に用いる |
| -alldirs | 指定ディレクトリ以降もアクセス権を継承 |
```shell:再起動迄 nfsd を起動(一時実行)
service nfsd onestart
```
```shell:恒久的に nfsd を起動
service nfsd enable
service nfsd start
```
```shell:nfsd を停止(一時実行の時)
service nfsd onestop`
```
```shell:nfsd を停止
service nfsd stop
```
# /etc/exports を書き換えたYo!
はい、その際には mountd を HUP シグナル送って設定ファイルを再読み込みさせないと、デーモン君は書き換えた事を知る術を持っちょらんのんじゃ
```shell:/etc/exports のリロード
service mountd reload
```
# 昔ばなし
[4.0-RELEASE](https://www.freebsd.org/releases/4.0R/notes/) 位の頃は [nfsd](http://koganemaru.co.jp/cgi-bin/mroff.cgi?subdir=man&lc=1&cmd=&man=nfsd&dir=jpman-14.1.2%2Fman&sect=0) を起動させる為の御呪いを沢山唱える必要が有ったんじゃ
nfsd やら [rpcbind(旧portmap)](http://koganemaru.co.jp/cgi-bin/mroff.cgi?subdir=man&lc=1&cmd=&man=rpcbind&dir=jpman-14.1.2%2Fman&sect=0) に [mountd](http://koganemaru.co.jp/cgi-bin/mroff.cgi?subdir=man&lc=1&cmd=&man=mountd&dir=jpman-14.1.2%2Fman&sect=0) と複数のデーモン君を起こす呪文を唱えなてたのが懐かしい💦
昨今は一つのファイルを作り(ここは昔から変わらぬ伝統)、ワンライナーのコマンドで即席 nfsd が構築出来ちゃる(^_-)-☆

\<ぼそ>ワシは [2.2.8-RELEASE](https://www.freebsd.org/releases/2.2.8R/announce/) の頃からボンヤリと FreeBSD を触り始めて、実際に自分なりに管理出来るようになったのが 4.0-RELEASE 位からじゃけ、それ以前の nfsd の動きは触れちょらん✌\</ぼそ>
# 結び
ファイアウォールは結構面倒じゃけ、出来ればルータにお任せをお勧め✌
既存のディレクトリを共有する際には、リードオンリーのフラグを立てて置くと、クライアント側での操作ミスによるファイルの損失が軽減できる筈(経験則)

クライアント側は、書く気になれば書こうかねぇw
NgrokでGETメソッドを使用する

## はじめに
Ngrokとはhttp://localhost:3000/ などの開発環境をhttps:// にて外部公開できるサービスです。

Ngrokの使い方は[こちらの記事](https://qiita.com/mininobu/items/b45dbc70faedf30f484e)などを参考にしてください。

## GETメソッドが送信できない
下記の実装でGETメソッドが送信できませんでした。
```
export const useFetchAbc = () => {
  const baseUrl = process.env.NEXT_PUBLIC_API_BASE_URL;
  const url = `${baseUrl}/abc`;
  const fetchAbc = async () => {
    try {
      const response = await fetch(url, {
        method: "GET",
        headers: {
          "Content-Type": "application/json",
          Authorization: `Bearer ${accessToken}`,
        },
```
POSTメソッドは問題なかったので同じように書いて上記となっていました。
Ngrokの警告？ページにアクセスして目的のエンドポイントまで到達出来なかったです。
## hedersに追加すると出来ました！
下記に変更するとアクセスできました。
```
export const useFetchAbc = () => {
  const baseUrl = process.env.NEXT_PUBLIC_API_BASE_URL;
  const url = `${baseUrl}/abc`;
  const fetchAbc = async () => {
    try {
      const response = await fetch(url, {
        method: "GET",
        headers: {
          "Content-Type": "application/json",
          Authorization: `Bearer ${accessToken}`,
          "ngrok-skip-browser-warning": "true", //この行を追加
        },
```
同じ内容でうまくいかない方は試してみてください。
ありがとうございました。
S3のデータをAzure上で動くSnowflakeに取り込んでみた！

# やってみたこと
Amazon S3のデータを
Microsoft Azure上で動くSnowflakeに取り込めるのか検証しました

## 検証のきっかけ
Snowflakeへデータを取り込む場合はS3などのデータレイクを使う事が一般的かと思います。
Snowflakeへのデータ取り込みを考える中で、例えばAmazon S3のデータをSnowflakeに取り込みたい場合はAWS上で動くSnowflakeでないといけないのでは？という疑問が生まれました。

## ドキュメントによると

> Snowflakeは、Snowflakeアカウントのクラウドプラットフォームに関係なく、
次のいずれかの場所にステージングされたファイルからのデータのロードをサポートしています。

https://docs.snowflake.com/ja/user-guide/intro-cloud-platforms

ドキュメントよりSnowflakeアカウントとデータレイクのサービスは関係ないとのことですが、この目で確かめてみたいので検証してみます！

# 検証内容
 **Amazon S3** に格納されているデータを
 **Microsoft Azure** 上で動く **Snowflake** に取り込んでみた！

▼全体像
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3586761/019a97b0-ea59-6b50-0d14-d8c68e0451af.png)


## 準備したもの
・CSV形式のダミーデータ
・Amazon S3
・Snowflakeトライアルアカウント

### ダミーデータの作成
Chat GPTに作ってもらいました！テストデータ作成でもお世話になっています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3586761/b5bfd59d-71e0-3a44-d6af-ce2980e6af26.png)

### Snowflake
1\. まず以下のURLからトライアルアカウントを作成します。

https://signup.snowflake.com/?_l=ja&utm_source=google&utm_medium=paidsearch&utm_campaign=ap-jp-jp-brand-trial-exact&utm_content=go-rsa-evg-ss-free-trial&utm_term=c-g-snowflake%E3%83%88%E3%83%A9%E3%82%A4%E3%82%A2%E3%83%AB-e&_bt=610748255507&_bk=snowflake%E3%83%88%E3%83%A9%E3%82%A4%E3%82%A2%E3%83%AB&_bm=e&_bn=g&_bg=142614214047&gclsrc=aw.ds&gad_source=1&gclid=Cj0KCQjwlvW2BhDyARIsADnIe-IZIs7EzcnJrmMde-WN1mImVxuDYVnzXmQnZNtqu2fjadIOFs8KWwwaAg8TEALw_wcB

クラウドプロバイダーは「Microsoft Azure」を選択しました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3586761/a7b28a79-3152-cccf-e821-67936de4b42d.png)

2\.データベース、スキーマ、テーブルを作成
CUSTOMERテーブルにCSVファイルのデータを取り込みます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3586761/01585cea-aa8e-588a-ac65-426b86bfcfed.png)


### ②Amazon S3
バケットを作成し、サンプルデータをアップロード

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3586761/931a5a9a-a959-1211-2632-581be4637d47.png)

## Snowflakeへ取り込み
### 前提
Amazon S3からのデータ取り込みは外部ステージにあげたCSVファイルをCOPYコマンドで取り込みます。

・外部ステージ

https://docs.snowflake.com/ja/user-guide/data-load-s3-config-storage-integration

・COPYコマンド

https://docs.snowflake.com/ja/sql-reference/sql/copy-into-table

## 実践
SnowflakeのGUI上でCOPYコマンドを実行します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3586761/2aeab6a5-da11-a57c-bd72-038a4f26ca49.png)

## 結果
CUSTOMERテーブルにデータが入っていることを確認できました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3586761/7b53cc61-c501-31f4-6b48-d01724f7af12.png)


## 結論
Snowflakeのクラウドプラットフォームと、データレイクのサービスは関係なくデータをロードできる！:clap:

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3586761/f0dae03f-4ec1-5167-e9ba-20a4301f230f.png)


## 最後に
ドキュメントを確認して終わりでは無く、自分の目で検証することは大事だと感じました。
今後も少しでも気になったことは検証してみようと思います！
多層アーキテクチャにおけるデータベース中心の設計になってしまう問題

## はじめに

MVCなど従来の多層アーキテクチャを採用したアプリケーションにおいて最初にどこから実装を始めるでしょうか。

おそらく多くの開発者は最初にデータベースの構造をどのようにするかを決めて、そのあとにビジネスロジックを実装したはずです。

私もデータベースのテーブル設計をどうするかから実装を始めていました。

多くのチュートリアル系の記事でもまずはデータベースの構築から始めることが多いはずです。なぜならデータベースがないと保存や参照が行えないからです。依存の流れに沿っている訳です。

このような流れで開発することはまったく理に適っておらず、適切な開発を行うのであれば、何よりも先にビジネスロジックから実装すべきです。

### 補足: ビジネスロジックとは

ビジネスロジックは業務に関する処理のことを指します。

例えば、MVCで言うとビューのように表示に関するものやモデルのようにデータベースを操作したりといった業務とは直接関係ないもの以外です。

## データベースを中心に設計してしまう原因

O/Rマッパー(Object-Relational Mapper)をビジネスロジックで利用すると問題が起こります。

例でいうとLaravelフレームワークにおけるEloquent ORMは、
ドメイン駆動設計(Domain-Driven Design)におけるエンティティとリポジトリの2つの役割を兼ねています。

:::note info
ドメイン駆動設計のエンティティとクリーンアーキテクチャのエンティティ
https://nrslib.com/clean-ddd-entity
:::

## データベースを中心に設計することによる問題

DDDにおけるドメイン層に配置されるべきエンティティが永続化層(リポジトリ)に配置されてしまいます。

ドメイン層と永続化層が密結合となり、ドメイン層のコードがビジネスロジックに加えて、永続化の関心事である即時読み込み(Eager Loading)や遅延読み込み(Lazy Loading)、キャッシュの読み書き、データベーストランザクションの管理なども扱う必要が出てきてしまいます。

こうなるとアプリケーションは柔軟性が損なわれてしまいます。

## 補足: レイヤー構造

### 1. ドメイン層 (Domain Layer)

- ビジネスロジックやビジネスルールを実装する層
- ドメインモデルを置く
  - エンティティ（Entity）
  - 値オブジェクト（Value Object）
  - ドメインサービス（Domain Service）

### 2. アプリケーション層 (Application Layer)

- アプリケーション固有の処理の流れやユースケースを実現するための層
- ドメイン層とインターフェース層の橋渡し役

### 3. インフラストラクチャ層 (Infrastructure Layer)

- データベースや外部APIなど、外部との接続を担う層
- 意図が伝わりやすいので永続化層と呼んでいます

### 4. ユーザーインターフェース層 / プレゼンテーション層 (User Interface / Presentation Layer)

- ユーザーとのやりとりや、外部システムへの出力を担当する層

## どうやって解決するか

本記事は「手を動かしてわかるクリーンアーキテクチャ　ヘキサゴナルアーキテクチャによるクリーンなアプリケーション開発」の「2.1 データベース中心の設計になってしまう問題」から抜粋して紹介させていただきました。

https://www.amazon.co.jp/dp/429501978X

この本にはパッケージ構成やコード例など細かく実装する上で困る問題事についても書かれてありました。もし興味をもった方はぜひ読んでみてください。

## PR

私が所属するミライトデザインではYouTubeで動画やライブ配信、connpassで月1の勉強会(オフライン&オンライン)を開催しています。
もし興味があれば、チャンネル登録や勉強会へ遊びに来てください🤗

https://www.youtube.com/channel/UCPI9u6wLr0APIZxNAB7o8qw

https://phper-oop.connpass.com
Parasolid クラス構造

## Parasolid クラス構造


1. **オブジェクトobjects**
   - Parasolidとアプリケーション間で交換されるデータ項目のこと。
   - 各オブジェクトは特定のクラスに属し、そのクラスによってオブジェクトの性質が決定される。
2. **クラスclass**
   - オブジェクトの共通のタイプを定義するための構造。
   - Parasolidのクラスは階層的なツリー構造に従っており、親子関係が形成される。
   - 図1ではすべてのクラスを示していないが、追加のクラスはボックスで囲まれた省略記号（...）で表現されている。
3. **最上位クラス（CLASS）**
   - Parasolidクラスの最上位に位置するクラスであり、すべての他のクラスのスーパークラス。
   - すべてのクラスはCLASSから派生している。
4. **タグtags**
   - 各オブジェクトはユニークなタグを持ち、これによりオブジェクトを識別できる。
5. **重要なクラス**
   - **TOPOL**:
     - トポロジに関連するクラスで、モデルの形状や構造に関する情報を管理する。
     - このクラスのサブクラスは、トポロジの詳細な構造を提供する。
   - **GEOM**:
     - 幾何学に関連するクラスで、形状の定義や処理に関与する。
     - GEOMクラスのサブクラスも多く存在し、複雑な幾何学的構造を表現する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2445123/6fb51e49-a189-7c42-9b43-9d4821c72c78.png)
図1 An outline of the Parasolid class hierarchy
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2445123/b266fd5c-abf6-4165-36ae-ebb68fe387ee.png)
図2 The TOPOL class and its subclasses
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2445123/9f9fcb51-7fb9-b052-a1e9-3beda9783844.png)
図3 The GEOM class and its subclasses
Railsでの joins と includes の違いと使い分け

## 目次
- [joinsとは？](#1-joinsとは)
- [includesとは](#2-includesとは)
- [joinsとincludesの使い分け](#3-joinsとincludesの使い分け)
- [N+1問題とは？](#4-n1問題とは)
- [ベストプラクティス](#5-ベストプラクティス)
- [組み合わせて使用する例](#6-組み合わせて使用する例)

## はじめに

Railsのアプリケーション開発では、モデル間の関連性を活用してデータを取得することが多く、その際に利用するのが `joins` と `includes` です。この記事では、データベースから必要な情報を取得する際に使用する`joins`と`includes`について、具体的な使い分けとその効果を解説します。

## 1. `joins`とは？

`joins`は、内部結合 (INNER JOIN) を使用して、関連するテーブルからデータを取得するためのメソッドです。RailsのActiveRecordで`joins`を使用すると、関連付けされた複数のテーブルを結合してクエリを発行できます。

### 使用例

以下は、`User`モデルと`Post`モデルを結合する例です。

```ruby
User.joins(:posts).where(posts: { published: true })
```

このコードは、投稿が公開されているユーザーを取得します。`joins`を使用することで、関連するテーブルの条件を効率的に絞り込むことができます。

### 特徴

- **結合条件**でフィルタリングができます。
- 取得されるのは結合されたテーブルのデータだけで、関連オブジェクトは取得されません。
- **N+1問題の解決**には不向きです。

## 2. `includes`とは？

`includes`は、関連するテーブルのデータを事前にロードする (Eager Loading) ために使用します。このメソッドを使うことで、N+1問題を回避し、複数のクエリ発行を抑えることができます。

### 使用例

以下は、ユーザーとその投稿を取得する例です。

```ruby
User.includes(:posts).each do |user|
  puts user.posts.map(&:title)
end
```

このコードでは、ユーザーとその関連する投稿が一度のクエリで取得されるため、各ユーザーごとにクエリが発行されるN+1問題を回避できます。

### 特徴

- 関連オブジェクトを含めたデータをまとめて取得します。
- **N+1問題の回避**に効果的です。
- 結合条件でのフィルタリングには不向きです。

## 3. `joins`と`includes`の使い分け

`joins`と`includes`はそれぞれの特徴を理解し、目的に応じて使い分ける必要があります。

### `joins`を使用する場面

- 結合条件を使用したフィルタリングが必要な場合
- 関連するテーブルの一部のデータのみを取得したい場合
- シンプルな結合が求められるクエリの場合

### `includes`を使用する場面

- 関連するデータを頻繁に参照する場合
- N+1問題を回避したい場合
- 関連オブジェクトをまとめて取得する必要がある場合

## 4. N+1問題とは？

N+1問題は、関連データを取得する際に対象のレコードごとに追加のクエリが発行され、データベースの負荷が増える問題です。例えば、10人のユーザーそれぞれに関連する投稿を取得する場合、`joins`を使わないと11回（1回のユーザー取得 + 10回の投稿取得）のクエリが発行されます。

## 5. ベストプラクティス

- **条件付きの結合**が必要な場合は`joins`を使用します。
- **N+1問題の回避**には`includes`を優先的に使用します。
- **必要なデータ**だけを取得するために、`select`メソッドと組み合わせます。

## 6. 組み合わせて使用する例

以下は、`joins`と`includes`を効果的に組み合わせた例です。

```ruby
users = User.includes(:posts).joins(:comments).where(comments: { spam: false })
users.each do |user|
  puts "#{user.name}: #{user.posts.count} posts"
end

```

このように、`joins`でフィルタリングしつつ、`includes`でN+1問題を回避することが可能です。
## 7. まとめ
`joins` と `includes` は、Railsで複数のテーブルからデータを取得する際に不可欠なメソッドです。

- **`joins`** は、内部結合で一致するデータだけを取得したい場合に適しています。
- **`includes`** は、N+1問題を解決し、関連データを一括取得するのに役立ちます。
Claude Computer UseをAndroidで動かす




Anthropicの「Computer Use」機能をAndroid環境でADBを使って実装するには、PC向けのインターフェースをAndroid向けに調整する必要があります。この機能はAIがスクリーンショットを解析し、画面上の操作を自動で行うことを目指しています【11】【12】。以下の手順でAndroid環境に適用する流れを解説します。

---

### 手順：ADBでAnthropicの「Computer Use」機能をAndroidで使う

#### 1. **開発環境の準備**
- Android端末をPCに接続し、`adb devices`で認識されていることを確認します。
- ADBが正常にインストールされていることが必要です。

#### 2. **スクリーンショットの取得**
Claudeは画面の状態を理解するためにスクリーンショットを活用します。ADBを使って以下のコマンドでスクリーンをキャプチャします。
```bash
adb shell screencap -p /sdcard/screen.png
adb pull /sdcard/screen.png
```
- 取得したスクリーンショットをClaudeのAPIに送信し、画面解析結果を受け取ります。

#### 3. **画面操作のシミュレーション**
Claudeから受け取った指示に従い、ADBでタップやスワイプを実行します。
- **タップ操作の例**  
```bash
adb shell input tap X Y
```
- **スワイプ操作の例**  
```bash
adb shell input swipe X1 Y1 X2 Y2 1000
```
Claudeが解析した結果に基づき、適切な座標を指定して操作します。

#### 4. **キーボード入力**
画面に文字を入力する場合は、以下のコマンドで実行します。
```bash
adb shell input text 'テキスト'
```

#### 5. **APIとADBの連携**
Pythonなどのスクリプトで、以下のようにClaude APIとADBを連携させます：
1. ADBでスクリーンショットを取得し、Claude APIに送信。
2. APIから返された指示に基づき、ADBで対応する操作を実行。

#### 6. **セキュリティとプライバシーの考慮**
Anthropicはこの機能の悪用を防ぐため、慎重な使用を求めています【11】【12】。特にAIが機密情報にアクセスしないよう、AIがアクセスするアプリやデータを管理することが重要です。

---

### 注意点と今後の展望
Claudeの「Computer Use」はまだベータ版であり、スクロールやズームといった操作は現時点では難しい場合があります。しかし、APIを活用することでAndroid上のタスク自動化や複数アプリ間の操作が大幅に効率化される可能性があります【10】。

これらの手順を通じて、Android環境でClaudeの機能を試すことで、タスクの自動化やワークフロー改善に貢献できるでしょう。
結合に対して互換性のないデータ型: LONGおよび SYMBOL(SPSS Modeler データ加工逆引き12-2)

# 結合に対して互換性のないデータ型: LONGおよび SYMBOL

![スクリーンショット 2024-10-23 11.24.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/afb8f6bd-65ac-2685-770b-2767b8b6ce73.png)

## 1.想定されるトラブル

・[レコード結合]ノードでキー結合時にエラーが発生する

## 2.サンプルストリームのダウンロード

https://github.com/yoichiro0903n/blue/raw/refs/heads/main/join_ng.str

## 3.サンプルストリームの説明

![スクリーンショット 2024-10-23 11.33.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/4e17217d-53a5-7d57-7ece-5949f46a9517.png)

a.入力するデータのひとつ目は以下の通りです。

![スクリーンショット 2024-10-23 11.35.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/ba41d1a7-92ee-6683-5d4c-2dde03a03ea4.png)

この後結合時にキーとなる[ID]が連続型で定義されています。

![スクリーンショット 2024-10-23 11.36.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/2e6102b1-5b86-4fad-85b5-a946a1f2a96f.png)

b.入力するデータのふたつ目は以下の通りです。

![スクリーンショット 2024-10-23 11.36.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/ace85585-7c19-0103-cd94-39b750d982ca.png)

この後結合時にキーとなる [ID]が名義型で定義されています。

![スクリーンショット 2024-10-23 11.37.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/f5c400ec-98d7-76bd-99c3-5d433e221380.png)

c.[レコード結合]ノードを編集します。

![スクリーンショット 2024-10-23 11.37.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/5ab5c4c6-5963-5355-ae8c-158092185124.png)

#### エラーの現象を確認する

[テーブル]を実行すると以下のエラーメッセージが表示されます。

![スクリーンショット 2024-10-23 11.38.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/f443b3d5-579f-dd2b-23d2-b8381ac1ba84.png)

#### 文字列はたは整数に一致させて問題を解決する

d.[置換]ノードを編集します。

![スクリーンショット 2024-10-23 11.38.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/9485738a-e17f-2748-0aca-d99ca584ac23.png)

[式ビルダ]を利用すると[変換]から関数を簡単に探せて入力できます。

![スクリーンショット 2024-10-23 11.39.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/cf3398de-2c10-217b-8eaf-ab85ab8ef712.png)

[テーブル]を実行します。

![スクリーンショット 2024-10-23 11.39.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/cc4da879-b855-86d9-eb59-303293dcb3fa.png)


#### 注意事項

dを[データ型]ノードにして以下の通り強制的に連続型を名義型にしても同じエラーになります。

![スクリーンショット 2024-10-23 11.58.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/eaafffdb-7ce5-654e-bbdd-af6adf2a875b.png)


## 4.参考情報

#### IDでテーブルを結合する 内部結合と完全外部結合

https://qiita.com/416nishimaki/items/de1963eece361d587187

#### SPSS Modeler ノードリファレンス目次

https://qiita.com/416nishimaki/private/503037195081d3323eee

#### SPSS Modeler 逆引きストリーム集（データ加工）

https://qiita.com/416nishimaki/items/4bf813e6cba84b2a1008
paiza.ioでrust その13

# 概要
paiza.ioでrustやってみた。
練習問題やってみた。

# 練習問題
structとimplを使え。

# サンプルコード

```
struct Texts {
	s1: String,
	s2: String,
}
impl Texts {
	fn concat(&self) -> String {
		let s: String = format!("{}_123_{}", self.s1, self.s2);
		s
	}
	fn new(s1: String, s2: String) -> Self {
		Texts { s1, s2 }
	}
}
fn main() {
	let s: String = "hello".to_string();
	let t: Texts = Texts::new(s, "world!".to_string());
	println!("{}", t.concat())
}


```

# 実行結果

```
hello_123_world!
```

# 成果物

https://paiza.io/projects/m1qknkoINLV7mb7HaM9hHw


以上
TypeScriptで網羅性が必要な分岐が出てきた時に便利なtips

## 概要

TypeScriptで網羅性が必要な分岐が出てきた時に、assert neverを使うとコンパイル時にエラーがわかって便利です。<a href="4"/>

## 詳細

下記のようなswitchがあったときに、defaultでErrorをthrowしていたとします。<a href="7"/>

```typescript
type Animal = "Dog" | "Cat";

function cry(animal: Animal): void {
  switch (animal) {
    case "Dog": {
      console.log("ワン");
      break;
    }
    case "Cat": {
      console.log("ニャー");
      break;
    }
    default: {
      throw new Error("鳴かないよ");
    }
  }
}
```

AnimalにMonkeyを追加されたとき、switchにcaseを追加しないと実行時にdefaultでErrorとなってしまいます。<a href="9"/>

ただ、実行時にErrorを知るよりも、コンパイル時にErrorになって教えてくれた方が漏れがなくなって安心ですよね？<a href="10"/>

そんな時に便利なのが、assert neverを使った方法です。<a href="11"/>

```typescript
const asserNever = (_x: never) => {
  throw new Error("assert value");
};

type Animal = "Dog" | "Cat" | "Monkey";

function cry(animal: Animal): void {
  switch (animal) {
    case "Dog": {
      console.log("ワン");
      break;
    }
    case "Cat": {
      console.log("ニャー");
      break;
    }
    default: {
      asserNever(animal); //型 '"Monkey"' の引数を型 'never' のパラメーターに割り当てることはできません
    }
  }
}
```

> 型 '"Monkey"' の引数を型 'never' のパラメーターに割り当てることはできません

上記のようなasserNeverを使用している部分でエラーとなります。<a href="14"/>

```typescript
const asserNever = (_x: never) => {
  throw new Error("assert value");
};

type Animal = "Dog" | "Cat" | "Monkey";

function cry(animal: Animal): void {
  switch (animal) {
    case "Dog": {
      console.log("ワン");
      break;
    }
    case "Cat": {
      console.log("ニャー");
      break;
    }
    case "Monkey": {
      console.log("ウッキー");
      break;
    }
    default: {
      asserNever(animal);
    }
  }
}
```

分岐を網羅しているとエラーとなることはありません。<a href="16"/>

## 結論

コンパイルの時に網羅しなければいけないところを知れて分岐の追加忘れを防げるのが便利すぎる<a href="19"/>
null参照を滅せよ！

## おさらい・null参照とは

----
## $10億ドルの損失

- 実際、JavaやC#、JavaScriptでnull参照が原因でプログラムが落ちるのはひじょーによく目にする

----
## null参照の厄介なところ

- あらゆる参照がnullとなる可能性がある
- 原因と離れたところで例外が起きる

----
## 関数を作る際の心得(1/2)

- 安易にnullを返さない
- 安易にnullを返さない
- 安易にnullを返さない

１万回唱えても足りない！
例外をcatchしない、と並べて家訓にしたい。

----
## 関数を作る際の心得

- 例外的状況を表現するのにnullを使うのは明確な誤り
- そう、ここは例外の出番

```ts
if (!arg) throw new Exception("この関数の引数はnullやundefinedを許容しません")
```

----
## nullを避ける

- null初期化をやめる
  これを徹底するだけでプログラムのバグは半分になる（割りと本気で言ってます）
- そもそも変数を作らない
- nullかもしれないことを表現する型を使う
  JavaのOptional型
  ※C#のNullableは違う！

----
## 可能性のある結果を全て表現可能な型を作る

- JavaのOptional型相当品を作る
- HaskellのMaybe相当品ならすぐ作れる

----
## 最後に

- nullを軽く考えないようにしましょう
- nullの代わりとなる仕組みを覚えましょう＆作りましょう
kubernetesで継続した開発をするために

## kubernetesでデプロイを継続してやるために
•いつ誰がコマンド実施したかがわからない
•コマンド実施したことで、マニフェスト同士が衝突するかもしれない
•手作業でデプロイするのはめんどくさいし、ヒューマンエラーが起きやすい　という課題がある
それを解決する手段を紹介していく
### Push型のデプロイ　CIOps
kubectl apply --filename <file>を自動化しようと思った時、まず考えるのは「MasterブランチにFutureブランチをマージしたら本番環境にkubectl applyを実施」という方法だと思う
この自動化をCIツールで実行することを**CIOps**という。
### Pull型のデプロイ　GitOps
Gitを使って入ればGitOpsというわけではなく、定義がある
1.宣言的であること：システム全体は宣言的に記述される必要がある
2.バージョン管理と不変：正規の望ましいシステムの状態はバージョン管理されている
3.自動的に取得：承認された変更はシステムに自動的に適用される
4.継続的な調整：ソフトウェアエージェントが正確さを保証し、乖離があった場合にアラートを出す
**なぜわざわざGitOpsを選ぶのか**
四つの定義のうち三つ目が大きな違いの一つである。pull型であることで次のようなメリットがある
**セキュリティリスク低減**
CIOpsはその性質上、書き込み権限が必要になる。そのため万が一乗っ取られた時、読み書きが可能になってしまう。
GitOpsは読めればPullできるので、乗っ取られたとして取られる権限が小さく、CIOpsよりは被害が少なく済むと考えられる。
**CI•COが分離できる**
CIOpsはCI,CDともにCIツールを用いるため、実行タイミング、スクリプトが同じになることもある。規模が大きくなってくると、「CIが大きいせいでデプロイが遅い」「CI•CDのスクリプトが長すぎて調整ができない、めんどくさい」となってしまう。
GitOpsでは専用デプロイツールを利用して、デプロイの情報を宣言的に管理することでCIとCDを分離できる。
## Kubernetesのマニフェスト管理
実際の開発で、ほぼ似たようなマニフェストを描く機会があるだろう。少ないうちはいいが、規模が大きくなるとコピーアンドペーストし続けるのは現実的じゃない。そこでいろいろな管理方法やツールがあります。
### Helm
簡単にいうと、**他の人の作ったマニフェストをテンプレ的に使うことができる。**
他の開発者が作ったカスタムコントローラ用のマニフェストを使う時に便利
helm installで他の人のCRがデプロイできる
**実は**
helm installを直接実行するのはGitOpsと相性が悪い。そこでArgoCDなど書くGitOpsの仕様に従って実行するか、CIを利用して生成したマニフェストをGitOpsで管理するなどの方法がある
### Kustomize
環境ごとに異なるマニフェストの一部だけを管理したい。そんな時に使う方法。
具体的にはマニフェストの共通部分はbaseディレクトリで管理し、環境ごとの差分をoverlaysというディレクトリで管理する。
つまり同じようなマニフェストを作らないといけなくなっても、これを使えば差分だけ書けばいいのである！
**kustomize build <ディレクトリ名＞** でBase部分とディレクトリ独自の部分をまとめて出力してくれる便利なコマンドがある。
マニフェストの設定
kustomization.yaml
**resources**:ベースとなるディレクトリ、ファイルを書く。Baseディレクトリや、そのディレクトリ固有のファイルを書く。
**patches**:ovrelaysでBaseの設定を上書きするのに使う。上書きで使用するディレクトリを書く。
paiza.ioでrust その12

# 概要
paiza.ioでrustやってみた。
練習問題やってみた。

# 練習問題
Forthインタープリターを書いて、数9を4個つかって1から15までの数を表す式を実行せよ。

# サンプルコード

```

const MAXVAL: usize = 20;
fn push(val: &mut [f32; MAXVAL], sp: &mut i32, op: f32) {
	if *sp < MAXVAL as i32
	{
		val[*sp as usize] = op;
		*sp += 1;
	}
	else
	{
		println!("error: stack full, can't push {}", op);
	}
}
fn pop(val: &mut [f32; MAXVAL], sp: &mut i32) -> f32 {
	if *sp > 0
	{
		*sp -= 1;
		return val[*sp as usize];
	}
	else
	{
		println!("error: stack empty");
		return 0.0;
	}
}

fn Forth(s: &str) {
	let mut sp: i32 = 0;
	let mut val: [f32; MAXVAL] = [0.0; MAXVAL];
	//println!("{}", s);
    let strs = s.split_whitespace();
	//println!("{:?}", strs); 
	let cs: Vec<&str> = s.split_whitespace().collect::<Vec<_>>();
	//println!("{:?}", cs); 
	for token in cs
	{
		//println!("{}", token);
		match token
    	{
			"+" => {
				let right = pop(&mut val, &mut sp);
				let left = pop(&mut val, &mut sp);
                push(&mut val, &mut sp, left + right);
    		}
			"-" => {
				let right = pop(&mut val, &mut sp);
				let left = pop(&mut val, &mut sp);
                push(&mut val, &mut sp, left - right);
		    }
			"*" => {
				let right = pop(&mut val, &mut sp);
				let left = pop(&mut val, &mut sp);
                push(&mut val, &mut sp, left * right);
			}
			"/" => {
				let right = pop(&mut val, &mut sp);
				let left = pop(&mut val, &mut sp);
                push(&mut val, &mut sp, left / right);
			}
			"." => {
				let right = pop(&mut val, &mut sp);
        		println!("{}", right);
			}
			"dup" => {
				let right = pop(&mut val, &mut sp);
                push(&mut val, &mut sp, right);
                push(&mut val, &mut sp, right);
    		}
			"drop" => {
				let right = pop(&mut val, &mut sp);
    		}
			_ => {
			    let number: f32 = token.parse::<f32>().expect("REASON");
				push(&mut val, &mut sp, number);
			}
		}
	}
}

fn main() {
    Forth("9 9 - 9 9 / .");
    Forth("9 9 / 9 9 / + .");
    Forth("9 9 + 9 + 9 / .");
    Forth("9 9 9 + 9 / dup + .");
    Forth("9 9 9 + 9 / dup + - .");
    Forth("9 dup 9 + 9 + 9 / - .");
    Forth("9 9 9 + 9 / - .");
    Forth("9 9 9 drop 9 / - .");
    Forth("9 9 - 9 * 9 + .");
    Forth("9 9 / 9 dup 9 / + .");
    Forth("9 9 9 + 9 / + .");
    Forth("9 dup 9 9 + + 9 / + .");
    Forth("9 9 9 + 9 / dup + + .");
    Forth("9 dup 9 9 + 9 / dup + - + .");
    Forth("9 dup dup 9 + 9 + 9 / - + .");
}




```

# 実行結果

```
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
```

# 成果物

https://paiza.io/projects/6QijRpNCltRRLlW25hZefg


以上
paiza.ioでrust その11

# 概要
paiza.ioでrustやってみた。
練習問題やってみた。

# 練習問題
関数を使え。

# サンプルコード

```
fn hello_world1() -> String {
	return "Hello world1".to_string();
}
fn hello_world3() -> &'static str {
	return "Hello world3";
}
fn foo() -> String {
	String::from("foo!!")
}
fn append_world(str: &mut String) {
  str.push_str(" World");
}
fn concat_reference(a: &String, b: &String) -> String {
	let c: String = format!("{} {}", a, b);
	c
}

fn main() {
	println!("{}", hello_world1());
	println!("{}", hello_world3());
	println!("{}", foo());
    let mut str = "Hello".to_string();
    append_world(&mut str);
    println!("{}", str); 
    println!("{}", concat_reference(&str, &str)); 
}




```

# 実行結果

```
Hello world1
Hello world3
foo!!
Hello World
Hello World Hello World
```

# 成果物

https://paiza.io/projects/S1Nf2GVsdXLAVZvQmdkGXA


以上