OmniAICreator/Qiita-1.07M huggingface dataset:
Rustの乱数生成器はどんな型で受けるのが正解なのか

# 背景

Rustは静的型付言語であり、型に関しては厳密である一方で自由度を担保する仕組みも豊富にあります。その一つがtrait objectと呼ばれるものであり `dyn TraitA` の様に型が宣言されます。

```rust
fn f(x: &dyn TraitA)
```

と書くと`x`は`TraitA`を実装した型の参照であればなんでもいいということになります。似たような概念に `impl` というものがあり

```rust
fn f(x: &impl TraitA)
```

のように使われます。これはGenericsの別構文であり

```rust
fn f<A: TraitA>(x: &A)
```

と全く等価です。Genericsを使うとコンパイル時に型が確定し、型ごとに異なる関数が生成されるのに対し(static dispatch)、trait objectを使用すると本当に複数の実態型の関数が1つだけで実行時に動的に挙動が変わります(dynamic dispatch)。この両者の比較は本題ではないのでこれ以上は割愛します。

trait objectには制限があり、Traitがobject-safeである必要があります。このobject-safeを満たすうえで特に重要な項目がTraitがGenericsを含むmethodを持っているとobject-safeでなくなります。Rustでは乱数を使う際には算数生成器(RNG)のインスタンスを関数に渡すことが一般的です。

```rust
trait Sampler {
    fn sample(&self, rng: &mut impl rand::Rng)
}
```

例えば上記のように複数のRNGの実装を使用できるようにするとこのSamplerというTraitはobject-safeではなくってしまいます。前置きがかなり長かったですがこれを考えるのが今回のテーマです。

# 結論

`&mut dyn rand::RngCore` を使え。

まず最初に考えるのが `&mut dyn rand::Rng`に変えることですが、これはできません。なぜなら`Rng`自体がGenericsを含んだmethodをたくさん持っていてobject-safeではないからです。そこで登場するのが`rand::RngCore`です。`RngCore`も`Rng`のように様々なRNGが実装しているTraitです。というか`Rng`は`RngCore`を継承しています。重要な点としては`RngCore`が持っているmethodはすべてGenericsを使用していないのでobject-safeであることです。一方で`RngCore`は低レイヤーなメソッドしか実装しておらず。`Rng`が実装している`gen_range`などが使えません。しかしこれも実は問題ありません。なぜなら`RngCore`自体にはこれらのmethodはありませんが、`RngCore`は`Rng`を実装しているので使えてしまうんです。余談ですがこれは結構使えるテクニックだと思います。つまり以下のようなこと可能ということです。

```rust
trait TraitA {
    fn do_something(&self);
}

trait TraitB: TraitA {
    fn generic_method<T>(&self);
}

impl<K: TraitA> TraitB for K {
    fn generic_method<T>(&self) {
        println!("I can also do it");
    }
}

struct StructA;

impl TraitA for StructA {
    fn do_something(&self) {}
}

fn main() {
    let a = StructA;
    a.generic_method::<i32>();
}
```

そしてこれを見るとわかるように`TraitA`は`TraitB`のmethodをすべてデフォルトで実装しておく必要があります。`Rng`が提供している追加のmethodはすべて実際のstructの内容によらず、`RngCore`のmethodから自動的に実装できるものだけということですね。

# RNGの引数の型の指針

`rand` crateのドキュメントを読むと通常は `&mut (impl Rng + ?Sized)`の形で使えと書いてあります。`?Sized`については他の解説に譲りますが、要は関数の引数の型を`&mut (impl Rng + ?Sized)`にしておけば `&mut dyn RngCore`も受けれるようになります。以下比較表を作りました。

|引数型\変数型  |impl Rng|impl Rng + ?Sized|dyn RngCore|object-safe|
|:-:|:-:|:-:|:-:|:-:|
|impl Rng   | OK  | NG  | NG  | NO |
|impl Rng + ?Sized   | OK  | OK  | OK  | NO |
|dyn RngCore  | OK  | NG  | OK  | YES|

行が引数の型で列が実際に渡す変数の型です。つまり`&mut (impl Rng + ?Sized)`はあらゆるパターンの変数を受けることができ、`&mut (impl Rng)`はあらゆる引数パターンの関数に渡すことができるというわけです。これを考慮すると具体的に関数やTraitのmethodの引数は何を使用すればいいのかは以下のようになりました。

| ユースケース | 引数の型 | 理由 |
|:-:|:-:|:-:|
|  関数の引数で、内部で直接使用する場合 | `&mut (impl Rng + ?Sized)`  |  受けれる範囲が最も広いため |
|  関数の引数で、内部でさらに別の関数に渡す場合 | 内部で呼ぶ関数の引数の型に合わせる  | 内部の関数の要請を満たしつつ、受けれる変数の型の場合が最も多くなる  |
| Traitのmethodの引数で、object-safeにする必要がある場合  | `&mut dyn RngCore`  | object-safeにするにはこれ一択  |
| Traitのmethodの引数で、object-safeにする必要が無く、できるだけ実装に幅を持たせたい  |  `&mut impl Rng` |実際に実装する際に内部で他の関数に渡せる場合が最も多い   |
| Traitのmethodの引数で、object-safeにする必要が無く、できるだけ利用シーンを増やしたい  |  `&mut impl Rng + ?Sized` | 受けれる範囲が最も広いため   |
VSCodeでFlutterをはじめるときにxcrunがerrorしたら

塵芥以下のメモ書きです

# Situation

Mac OS 14にて、HomebrewでインストールしたFlutterとVSCodeをつかって[Flutter入門](https://codelabs.developers.google.com/codelabs/flutter-codelab-first?hl=ja)しようとしたときの話
より具体的には、サンプルアプリをとりあえずコピペして`lib/main.dart`からデバッグしようとしたとき

# Error Message
```:VSCode Debug Console
Launching lib/main.dart on macOS in debug mode...
ProcessException: Process exited abnormally with exit code 72:
xcrun: error: unable to find utility "xcodebuild", not a developer tool or in PATH
  Command: /usr/bin/arch -arm64e xcrun xcodebuild -list -project Runner.xcodeproj

Exited (1).
```

# Solution

```shell:shell
flutter doctor -v
```
これを叩くと何が足りないのか教えてくれる。うちの場合は
```
[✗] Xcode - develop for iOS and macOS
    ✗ Xcode installation is incomplete; a full installation is necessary for iOS
      and macOS development.
      Download at: https://developer.apple.com/xcode/
      Or install Xcode via the App Store.
      Once installed, run:
        sudo xcode-select --switch /Applications/Xcode.app/Contents/Developer
        sudo xcodebuild -runFirstLaunch
    ✗ CocoaPods not installed.
        CocoaPods is a package manager for iOS or macOS platform code.
        Without CocoaPods, plugins will not work on iOS or macOS.
        For more info, see https://flutter.dev/to/platform-plugins
      For installation instructions, see
      https://guides.cocoapods.org/using/getting-started.html#installation
```
このセクションの内容に従っていろいろやると解決した。(Warningはまだ出てるがとりあえずデバッグ用アプリウィンドウは開いたのでヨシ)

# refs

https://github.com/flutter/flutter/issues/147867
Polarsを使って、PuLPの数理モデルを作ってみよう

## 概要

次の記事では、pandasを使って、PuLPの数理モデルを作ってみました。

https://qiita.com/SaitoTsutomu/items/070ca9cb37c6b2b492f0

本記事では、**Polarsを使って、PuLPの数理モデルを作成**します。
PuLPの使い方については、上記記事を参照してください。
Polarsについては、公式ドキュメントを参照してください。

https://docs.pola.rs/

## 諸元

参照記事と同じように倉庫や工場の諸元を作成します。
ここでは、パッと見てわかりやすいように変数名に漢字を使っています。

```python
import polars as pl
from pulp import PULP_CBC_CMD, LpProblem, LpVariable, lpDot, lpSum, value

供給 = [44, 42, 45]
需要 = [39, 23, 22, 32]
輸送費 = [17, 16, 18, 10, 13, 15, 14, 13, 13, 10, 11, 15]

df_倉庫 = pl.DataFrame({"倉庫": ["W1", "W2", "W3"], "供給": 供給})
df_工場 = pl.DataFrame({"工場": ["F1", "F2", "F3", "F4"], "需要": 需要})
```

## 数理モデル

Polarsを使って数理モデルを作成します。

```python
# 数理モデル
m = LpProblem()

# 変数表
_vars = [LpVariable(f"v_{i:02}", lowBound=0) for i in range(len(輸送費))]
df_変数 = df_倉庫.join(df_工場, how="cross").with_columns(
    輸送費=pl.Series(輸送費), 変数=pl.Series(_vars)
)

# 目的関数
m.setObjective(lpDot(df_変数.get_column("輸送費"), df_変数.get_column("変数")))

# 制約条件
for _, group in df_変数.group_by("倉庫"):
    m += lpSum(group.get_column("変数")) <= group.get_column("供給")[0]
for _, group in df_変数.group_by("工場"):
    m += lpSum(group.get_column("変数")) >= group.get_column("需要")[0]
```

## ソルバーの実行と結果表示

```python
m.solve(PULP_CBC_CMD(msg=False))
_values = df_変数.get_column("変数").map_elements(value, pl.Float64)
df_変数 = df_変数.with_columns(結果=_values)
print(df_変数.filter(pl.col("結果") > 0))
print(f"目的関数値 = {m.objective.value()}")
```

```
shape: (4, 7)
┌──────┬──────┬──────┬──────┬────────┬────────┬──────┐
│ 倉庫 ┆ 供給 ┆ 工場 ┆ 需要 ┆ 輸送費 ┆ 変数   ┆ 結果 │
│ ---  ┆ ---  ┆ ---  ┆ ---  ┆ ---    ┆ ---    ┆ ---  │
│ str  ┆ i64  ┆ str  ┆ i64  ┆ i64    ┆ object ┆ f64  │
╞══════╪══════╪══════╪══════╪════════╪════════╪══════╡
│ W1   ┆ 44   ┆ F4   ┆ 32   ┆ 10     ┆ v_03   ┆ 32.0 │
│ W2   ┆ 42   ┆ F1   ┆ 39   ┆ 13     ┆ v_04   ┆ 39.0 │
│ W3   ┆ 45   ┆ F2   ┆ 23   ┆ 10     ┆ v_09   ┆ 23.0 │
│ W3   ┆ 45   ┆ F3   ┆ 22   ┆ 11     ┆ v_10   ┆ 22.0 │
└──────┴──────┴──────┴──────┴────────┴────────┴──────┘
目的関数値 = 1299.0
```

## 数式を扱うときの注意

Polarsの特徴は、実データを含まずに、式（エクスプレッション）を記述できることです。
しかし、最適化モデルの変数を含んだ数式は、エクスプレッションとして記述できません。

たとえば、次の目的関数の式は実データで内積を取っています。

```python
lpDot(df_変数.get_column("輸送費"), df_変数.get_column("変数"))
```

エクスプレッションが数式を扱えれば次のように書けますが、実際には書けません。

```python
df_変数.select(pl.col("輸送費") * pl.col("変数")).sum()
```

このようにPolarsで数式を扱う場合、実データを使って計算を記述しないといけないことに注意してください。

## まとめ

Polarsを使って、PuLPの数理モデルを作成しました。
Polarsは、DataFrameとSeriesが、1つの文で独立にメソッドチェーンを組み立てられます。
これにより、シンプルな構文のまま柔軟な処理を記述できます。
また、モデル作成の処理時間が（pandasより）高速になるかもしれません。

## 参考

https://qiita.com/SaitoTsutomu/items/16f588265a01feacecbe

以上
v-htmlの使い方

# Vueでリストを表示させたかった時に、htmlタグで改行を入れたかった
通常はマスタッシュ構文を使うが、それだとhtmlタグを入れてもただの文字列として認識されてしまう。そこで、`v-html`属性を用いる。

### マスタッシュ構文
```html:index.html
<span>{{ hoge.name }}</span>
```
### v-html属性
```html:index.html
<span v-html="hoge.name"></span>
```

備忘録として残させてください。アウトプットです。hogehoge
Why AWS Certification is Essential for Cloud Career Growth

In today’s rapidly evolving digital landscape, cloud computing has become the backbone of many industries. With a 28% forecasted growth in jobs requiring cloud skills over the next five years, professionals need to stay ahead of the curve. AWS (Amazon Web Services) Certification has emerged as a critical credential for IT professionals looking to enhance their cloud expertise. This article explores why getting AWS Certified is more important than ever, examining its benefits for both individuals and organizations.

Demand for Cloud Skills is on the Rise
The demand for cloud skills is skyrocketing as more businesses migrate to the cloud. According to industry forecasts, jobs that require cloud expertise are expected to grow by 28% in the next five years. AWS, being one of the most widely used cloud platforms, presents a unique opportunity for professionals to upskill and meet the market's growing demands. By preparing for an [AWS Certification Exams](https://www.p2pexams.com/amazon), individuals can build essential skills that will make them more competitive in the job market.

AWS Certification Fuels Innovation
For organizations, having AWS Certified staff translates into tangible benefits. 91% of organizations with AWS Certified employees report an increase in innovation with AWS services. AWS Certification equips IT professionals with in-depth knowledge and hands-on experience, enabling them to leverage the platform's full potential. This results in better utilization of AWS tools, leading to the development of new solutions and a competitive edge in the market.

Boost in Productivity
The impact of AWS Certification goes beyond just innovation. A staggering 90% of IT leaders say that productivity improved after their staff earned AWS Certifications. Certified professionals can work more efficiently, reducing the time it takes to complete tasks and implement solutions. The certification process sharpens critical skills like troubleshooting, deployment, and cloud architecture, making employees more adept at handling day-to-day challenges.

Faster Troubleshooting and Problem Solving
In addition to increased productivity, AWS Certification is a game-changer when it comes to troubleshooting. According to reports, 89% of IT leaders noticed faster troubleshooting times among AWS Certified employees. This is crucial in today’s fast-paced environments, where downtime or delays can lead to significant losses. AWS Certification ensures that staff are well-equipped to resolve issues quickly, minimizing disruptions and ensuring smooth operations.
【豆知識】Tailwind CSSやDaisyUIなどの理解

# はじめに
今回はTailwind CSSやDaisyUIなどのフレームワークについて違いが何かがいまいち理解していなかったので調べたことを自分なりにまとめてみます。


## まずはTailwind CSSとDaisyUIについての理解
私は課題のアプリ制作でTailwind CSSとDaisyUIという機能を使用しています。
（そもそも「機能」という呼び方で合っているのか？）


Tailwind CSSを更に補完するものとしてDaisyUIがある？
フレームワークとTailwind CSSとDaisyUIは別物？どういう関係？

### 0：2つのツールについて
どちらも CSS に関連するツールです。
CSSというのは**Cascading Style Sheets**の略称で、Webサイトの見た目を設定するプログラミング言語になります。色やサイズ、レイアウトなどのデザインを定義する際に使用され、「シーエスエス」や「スタイルシート」とも呼ばれ役割や使い方に少し違いがあります。
HTML（Hypertext Markup Language）と共に使用されることで、Webページの装飾やアニメーション、外部リソースの組み込みなどを行うことができます。

**HTMLは枠組みを作り、CSSはそれを装飾する役割**
CSSとHTMLの違いについては👇下記サイトが例もあり分かりやすかったです。

https://coosy.co.jp/blog/about-css-basic/



### 1. **Tailwind CSS**

- **どういうものか**: Tailwind CSS は、ウェブページをデザインするための **ユーティリティファースト（CSSは使わずにTailwind CSSが提供しているクラスのみを使用してスタイリングする考え方のこと）の CSS フレームワーク**です。通常の CSS のように長いクラス名を定義する代わりに、既に用意された短いクラス（ユーティリティクラス）を HTML 要素に直接適用することでデザインを行います。
    - 例: `<div class="bg-blue-500 text-white p-4">` のように、クラス名でデザインを細かく調整できます。
- **特徴**:
    - CSS を一から書く必要がなく、すぐに使える。
    - 非常にカスタマイズ可能で、自由にデザインを作り上げることができる。


### 2. **DaisyUI**
- **どういうものか**: DaisyUI は **Tailwind CSS の拡張（プラグイン）** で、デザインに使える **コンポーネント集** です。ボタン、フォーム、カードなど、ウェブサイトでよく使われるデザインの部品（コンポーネント）が用意されており、Tailwind CSS の上に組み込まれています。
    - 例: `<button class="btn btn-primary">` のように、既にスタイルされたボタンを簡単に追加できます。
- **特徴**:
    - Tailwind CSS のユーティリティクラスをさらに簡単に使えるように、**すぐに使えるスタイル済みコンポーネント**を提供します。
    - デフォルトでテーマも用意されており、デザインを短時間で仕上げたい場合に便利。


### 3. **2つのツールを少し理解したうえで、どういう関係なのか？**
- 1と2の説明文からもわかるように、同じものではないという事がわかります。Tailwind CSS は、ウェブページのスタイルを柔軟に作るための基礎ツール。一方、DaisyUI は Tailwind CSS をもっと使いやすくするためにデザイン済みの部品（コンポーネント）を提供するプラグインという事になります。
- Tailwind CSSの機能を拡張したものがDaisyUI。
- チートシートなんかもある。サイトのコードをそのままもってきて使える

https://musclecoding.com/tailwindcss-how-to-use/

https://zenn.dev/ikenohi/articles/596594edebb76f



### 結論
- これらは、**一緒に使うことで効率的にデザインができる**関係にあるという事が理解できました。
- 一つだけでもできることは増えますが、もっとデザインにこだわったりするときに2つを一緒に使用すると便利！
- 今回の記事が何か参考になれば幸いです。
片物理ボリュームを強制的にAcitveにする方法について

ボリュームのLVM構成において
```
lsvg -p VG名
```
を実行して、片PVがmissingの状態のときのケースを想定する。

下記のコマンドで対象ボリュームグループを活動化を試みた際に、

```
varyonvg VG名
```
を指定しても、VGが活動化しないときは

物理ボリュームのhdiskの強制的にアクティブ状態にするコマンドを実行するとよいです。
```
chpv -va hdisk1
```
競プロでNeovim×pythonを使う方法

# 競プロでNeovim×pythonを使う方法

:::note warn
文章力が明らかに欠陥している中学生が書いた記事です。
どうぞ温かい目でご覧ください。
:::

## 前提条件
Python
Neovim
Git
がインストールされている状態

# 完成図

![output.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3889080/fdd43fd7-0856-8972-5851-341e98d1504d.gif)


# Lazy.vimのインストール

https://www.lazyvim.org/

lazy.vimはプラグインマネージャーときれいなuiを提供します

```terminal
# バックアップを取ります
mv ~/.config/nvim{,.bak}
mv ~/.local/share/nvim{,.bak}
mv ~/.local/state/nvim{,.bak}
mv ~/.cache/nvim{,.bak}

#インストール
git clone https://github.com/LazyVim/starter ~/.config/nvim

rm -rf ~/.config/nvim/.git
```

# pythonのlspのセットアップ
Neovimの設定ディレクトリに移動し/lua/config/lazy.luaを開きます


```diff_lua:/lua/config/lazy.lua
require("lazy").setup({
  spec= {
        { "LazyVim/LazyVim", import = "lazyvim.plugins" },
+ { import = "lazyvim.plugins.extras.lang.python" },
  }
})
```
これでpythonのlspの設定が完了します

# 便利プラグイン

## toggleterm.nvim

https://github.com/akinsho/toggleterm.nvim

**簡単にターミナルを開くためのプラグインです**

Neovimの設定ディレクトリに/lua/plugins/utils.lua
を作成します
ファイル名は何でもいいです

```lua:/lua/plugins/utils.lua
return {

  -- amongst your other plugins
  { "akinsho/toggleterm.nvim", version = "*", config = true },
  {
    "akinsho/toggleterm.nvim",
    version = "*",
    opts = {--[[ things you want to change go here]]
    },
  },
}
```

そしてinit.luaに設定を加えます
```diff_lua:init.lua
require("config.lazy")

+ require("toggleterm").setup({
+ size = 20,
+ open_mapping=[[<c-\>]],
+ hide_numbers = true, 
+ shade_filetypes = {},
+ shade_terminals = true,
+ shading_factor = "1",
+ start_in_insert = true, 
+ persist_size = true,
+ direction = "horizontal",
+ close_on_exit = true, 
+ shell = vim.o.shell, 
})
```
## nvim-scrollbar

https://github.com/petertriho/nvim-scrollbar

**行番号の左にスクロールバーを作成します**

```diff_lua:/lua/plugins/utils.lua
+ { "petertriho/nvim-scrollbar" },
```
init.luaに
```diff_lua:init.lua
+ require("ibl").setup()
```
### これで完成です

# 最後に
結構簡単にできますのでぜひ試してみてください
コメントがあればご気軽にどうぞ


# 追記
2024/9/23
toggletermのセットアップにコロンとカッコが抜けていたところを修正しました。
リストの作り方

## 導入
メールを整理していたら
```
リスト{1,1,2,2,3,3,4,4,5,5・・・100,100}の作成方法がよくわからないです
```
という質問が見えたので。
## プログラム
```
(define nil '())

(define (make-list limit)
  (define (iter i lst)
    (if (= i 0)
        lst
        (iter (- i 1) (cons i (cons i lst)))))
  (iter limit nil))
```
こんな風に書けば作れるよ。
リスト処理なら Scheme にお任せ。リストを処理するプログラミング言語だからね！

## 実行
```
gosh> (print (make-list 100))
(1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 10 10 11 11 12 12 13 13 14 14 15 15 16 16 17 17 18 18 19 19 20 20 21 21 22 22 23 23 24 24 25 25 26 26 27 27 28 28 29 29 30 30 31 31 32 32 33 33 34 34 35 35 36 36 37 37 38 38 39 39 40 40 41 41 42 42 43 43 44 44 45 45 46 46 47 47 48 48 49 49 50 50 51 51 52 52 53 53 54 54 55 55 56 56 57 57 58 58 59 59 60 60 61 61 62 62 63 63 64 64 65 65 66 66 67 67 68 68 69 69 70 70 71 71 72 72 73 73 74 74 75 75 76 76 77 77 78 78 79 79 80 80 81 81 82 82 83 83 84 84 85 85 86 86 87 87 88 88 89 89 90 90 91 91 92 92 93 93 94 94 95 95 96 96 97 97 98 98 99 99 100 100)
#<undef>
```
ほらできた。簡単でしょ。
## 編集後記
メールの未読が 2,000 超え（ほとんどいらんメール）なので、はやく整理しなさい。

ハイ...
【Next.js】画面遷移時にスクロール位置が最上部に移動しない

# はじめに
久しぶりの投稿です。
最近業務でNext.jsを触り始めたので、ささやかな学びを共有します。

# 困ったこと
画面遷移を行うUIコンポーネントを利用した際、画面遷移時にスクロール位置が画面最上部に移動しないという不具合が発生しました。

# 問題箇所を抜粋
今回利用したUIコンポーネントは、`<Link>`を用いて、コンポーネント押下時に指定した画面へ遷移する機能を提供していました。

下記、UIコンポーネントの`<Link>`実装部分のみを抜粋してます。
```tsx
<Link className={classes} href={href} scroll={false} {...otherProps}>
  {children}
</Link>
```

# 解決策
[Next.jsの公式ドキュメント](https://nextjs.org/docs/pages/api-reference/components/link#scroll)によると、`<Link>`の`scroll`プロパティが`false`の場合、スクロール位置は画面最上部に移動せず、直前のページのスクロール位置を保持される仕様になっています。

今回、UIコンポーネント内の実装で`<Link>`の`scroll`プロパティが`false`となっていたことが不具合の原因でした。
画面遷移時にスクロール位置を最上部に移動させたいので、`scroll`プロパティを`true`（または指定なし）にすることで、期待する動作を実現できます。

```tsx
<Link className={classes} href={href} {...otherProps}>
  {children}
</Link>

// または

<Link className={classes} href={href} scroll={true} {...otherProps}>
  {children}
</Link>
```


# 参考文献
https://nextjs.org/docs/pages/api-reference/components/link
006 皆で使おう　専門分野特化のＬＬＭ　flaskでインターネットで公開！！！


皆で使おう　専門分野特化のＬＬＭ　flaskでインターネットで公開！！！


追加学習済みのＬＬＭを安価に共有する方法です。
完成ずみのwebapiを使って、
既にある、皆様のポータルサイトで呼び出したり
別途、独立サイトで運用したり　色々できます。

完成イメージ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237930/1e461bef-06f7-9844-54df-71f50108e092.png)


flaskは、万能選手でwebapiも　webappも両方作れます。
今回もサーバーレスで　デプロイです。

何度かWebアプリやwebAPIを開発したので
google製のサーバーレスも　全制覇です。

　app engine　：　サーバーレスの基本型（アプリ毎）
　cloud run　　：　ドッカー使って安定型（ＯＳ毎）
　cloud functions　：　webapiの特化型（関数毎）

どれも、特徴があり適材適所で選べますし、
少し頑張ると、サーバーレスの利便性を享受できます。
サーバー有り（≒普通の仮想マシン）を死ぬほど作ると有難味が分かります。
作り方は公式参照


https://cloud.google.com/appengine/docs/an-overview-of-app-engine?hl=ja



今回も　無事に
　皆で使おう　専門分野特化のＬＬＭ　flaskでインターネットで公開！！！
完成です。おめでとうございます。



前回までの２４

第六回：追加学習済み　LLMの　flaskでWebアプリをクラウドデプロイ
本書



第五回：追加学習済み　LLMの　streamlitでWebアプリをクラウドデプロイ

https://qiita.com/bono0/items/2f7fbdbd1ad843e7858e

第四回：追加学習済み　LLMのwebapiをクラウドデプロイ

https://qiita.com/bono0/items/f954ca48d19cc51fb344


第三回：追加学習済み　LLMのwebapiを作る

https://qiita.com/bono0/items/f3330d8a57024e7cd44b


第二回：大規模言語モデルの簡単な追加学習、実践編

https://qiita.com/bono0/items/bd0a01e50d5804bdacf3


第一回：大規模言語モデルの簡単な追加学習

https://qiita.com/bono0/items/4a992dc388527d3b99f4



サーバーレスの作り方シリーズで
ー続く？ー
[ガチ🔰]Dockerで、ホストマシンとコンテナのディレクトリを同期したい

# この記事はDocker超初心者（脳筋）向けです
とあるツール(Ginza)の環境構築の際に、クロスプラットフォームに対応するためDockerを使うことにしたが、コンテナとホストマシンのディレクトリをどう同期させているのかが微妙だったので記録しておく。

自分は身体で覚えるスタイルなので、チュートリアルとかはやらず（よくない）、最小の要素（なるべくシンプルなとこ）から段々欲しいものを追加してツールを学んでいく。そういった脳筋向けの人はきっと同じとこで困っている気がするので、そのための記録でもある。

## Dockerfileを書いて、dockerコマンドのみで使うところから

### vol.1

一番初めに書いたもの

```docker
# ベースイメージ
FROM python:3.9-slim

# 作業ディレクトリ作成
WORKDIR /app

# ライブラリのインストール
RUN apt-get update && \\
    apt-get install -y --no-install-recommends \\
    build-essential \\
    && rm -rf /var/lib/apt/lists/*

# spaCyとGiNZAをインストール
RUN pip install --no-cache-dir spacy ginza ja_ginza

# spaCyの日本語モデルをダウンロード
RUN python -m spacy download ja_core_news_lg

# ginza_testディレクトリをコピー
COPY ./ginza_test /app/ginza_test

# スクリプトを実行
ENTRYPOINT ["python", "/app/ginza_test/gingin.py"]

```

最初はこれをbuildし、runさせることでなんとかpyファイルを実行していた。
が、これではgingin.py以外のpyファイルを実行したい時にいちいち書き換えなければいけない。

めんどうなので、シェルを起動する形にしてみる。

### vol.2

```docker
# ginza_testディレクトリをコピー
COPY ./ginza_test /app/ginza_test

# デフォルトでシェルを起動する
CMD ["bash"]

```

Dockerfile内でスクリプトを実行するのではなく、シェルを起動した後に、コマンドでpythonファイルを実行する。
これならばginza_test/にあるpyファイルを好きなだけ実行できる。

しかし、COPYでホストマシンのディレクトリをコンテナの作業環境によっこいしょしているので、ファイルの編集内容を同期させるにはいちいちbuildし直さなくてはいけない。

世のDockerユーザーがこんなに面倒なことをしているわけはないと確信しさらに調べると、volumeという概念（ではないと思う）を見つける。

**volumeでできること**

- コンテナ内のデータを永久保持させる
- **ホストとコンテナでディレクトリ同期**
- コンテナとコンテナでディレクトリを同期

これやん、ということで、ホストとコンテナでディレクトリを同期させてみる。

### docker-compose.ymlに気が付く

volumeを使ってみようと思い立ったところで、dockerコマンドで実行してみようとすると、ふとめんどくさいことに気が付く。

**今後同じように追加していきたい時、全部コマンドでやるの？**

そこでもしやdocker-composeが活躍するのかと思って調べると、どうやらそうらしい。

[Docker Compose 概要 — Docker-docs-ja 24.0 ドキュメント](https://docs.docker.jp/compose/index.html#docker-compose)

要するに、

- 複数のコンテナを定義し、同時に管理
- コンテナの設定をコードで一元管理

ができると言っているような気がしたので、docker-composeを導入。

### vol.3

```docker
FROM python:3.9-slim

WORKDIR /app

RUN apt-get update && \\
    apt-get install -y --no-install-recommends \\
    build-essential \\
    && rm -rf /var/lib/apt/lists/*

RUN pip install --no-cache-dir spacy ginza ja_ginza

```

```docker
services:
  app:
    build: .
    volumes:
      - ./ginza_test:/app/ginza_test
    working_dir: /app
    command: tail -f /dev/null
    ports:
      - "8000:8000"

```

volumes:- ./ginza_test:/app/ginza_test
で、ホストとコンテナのディレクトリを同期している。

実際にこれを

```bash
docker compose up
docker compose exec app bash

```

とすることで、先ほどのvol.2のようにコンテナのbashを使えるようにしつつ、ローカルの編集をそのままコンテナにリアルタイム同期できるようになった。

command: tail -f /dev/null

は、docker-composeにそのままbashと書くとなぜか一瞬で切れてしまうので（なんでなんだろう）gptに聞いたら、これで持続的にコンテナを実行できると教えてくれた。よくわかっていないけど動いているのでいいことにする。


## まとめ
せっかく数時間をDocker理解に費やしたので、忘れないように記事にした。
絶対に働き始めたら使うので、もっと理解していこう。

最初からチュートリアルを見ていたらこんなに時間はかからなかったのかもしれないし、あるいは脳筋方法をとったから仕組みが体験として理解できたような気もする。
畢竟、好きな方法で勉強したらいい。
【C#】色々なforeachの使用方法【初心者向け】

# 概要
単なるリストや配列以外をforeachで回すサンプルコードを記載しました。

基本的なforeach文は以下のようになると思います。

```C#
    List<string> collection = new List<string>(){"hoge","fuga","piyo"};
    foreach (var item in collection)
    {
        // 処理
    }
```
上記以外の、タプルやディクショナリ等を使用したforeachのサンプルコードをまとめました。

# 目次
- [タプルを使用したforeach文](#タプルを使用したforeach文)
- [Dictonaryを使用したforeach文](#dictonaryを使用したforeach文)
- [コレクションを合体させたものを回すforeach文](#コレクションを合体させたものを回すforeach文)
- [参照渡しのforeach文](#参照渡しのforeach文)


# タプルを使用したforeach文
```C#
    Tuple<int, string, bool>[] tuples = { Tuple.Create(0, "hoge", true), Tuple.Create(1, "fuga", false) };
    foreach (var (first, second, third) in tuples)
    {
      // 処理
        Console.WriteLine($"1つ目: {first}, 2つ目: {second},3つ目: {third}");
    }
```

# Dictonaryを使用したforeach文
```C#
    var dic = new Dictionary<string, int>
    {
        {"田中さん", 37},
        {"山田さん", 42},
        {"佐藤さん", 24}
    };

    foreach (var pair in dic)
    {
        // 処理
        Console.WriteLine($"{pair.Key} は {pair.Value} 歳です。");
    }
```

また、以下のような拡張関数を記載しておくことで、

```C#
    static class KeyvalueExtensions {
        public static void Deconstruct<K,V>(this KeyValuePair<K,V> self, out K k, out V v)
            => (k, v) = (self.Key, self.Value);
    }
```
以下のように回すことも可能です。
```C#
    var dic = new Dictionary<string, int>
    {
        {"田中さん", 37},
        {"山田さん", 42},
        {"佐藤さん", 24}
    };
    
    foreach (var (k, v) in dic)
    {
        // 処理
        Console.WriteLine($"{k} は {v} 歳です。");
    }
```

# コレクションを合体させたものを回すforeach文
```C#
    var names = new List<string> { "田中さん", "山田さん", "佐藤さん" };
    var ages = new List<int> { 37, 42, 24 };
    
    var results = names.Zip(ages, (n, a) => new { Name = n, Age = a });
    foreach (var pair in results)
    {
        // 処理
        Console.WriteLine($"{pair.Name} は {pair.Age} 歳です。");
    }
```

:::note
LINQのZipメソッドは、2のコレクションを1つに合体させることができるメソッドです。
:::

以下のように書くと、よりわかりやすくなります。

```C#
    var names = new List<string> { "田中さん", "山田さん", "佐藤さん" };
    var ages = new List<int> { 37, 42, 24 };
    
    var results = names.Zip(ages);
    foreach (var (name, age) in results)
    {
        // 処理
        Console.WriteLine($"{name} は {age} 歳です。");
    }
```

# 参照渡しのforeach文
```C#
{
    var names = new string[] { "田中さん", "山田さん", "佐藤さん" };
    foreach(ref var name in names.AsSpan())
        name += "2";

    // 処理
    Console.WriteLine($"{string.Join(", ", names)}");
}
```

# 終わりに
使用箇所は少ないかもしれませんが、使用できる場面で使用せず冗長？なコードにならないように気を付けたいです。
Direct ConnectとTransit Gatewayの通信量が合わない

# やりたいこと
* Direct Connectで日毎の通信量合計を確認するグラフを作成したい
* Transit Gatewayで日毎の通信量合計を確認するグラフを作成したい

# 構成

![met.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523652/71122113-0b2b-c9a7-d5b2-426da1c1eb9c.png)

* オンプレミスからDirect Connectで接続する。
* DXGW経由でTransit Gatewayに接続する。
* Transit Gatewayアタッチメントで1つのVPCに接続する。
* CloudWatchメトリクスで下記トラフィック送受信量を取得する。

|No|メトリクス|説明|
|:---:|:---|:--|
|①|VirtualInterfaceBpsIngress|※に記載|
|②|BytesIn|Transit Gateway あたりの受信バイト数。|
|③|BytesOut|Transit Gateway からの送信バイト数。|

※VirtualInterfaceBpsIngress
仮想インターフェイスの AWS 側へのインバウンドデータのビットレート。
報告される数値は、指定した時間長 (デフォルトは 5 分) にわたる集計 (平均) です。
単位: ビット/秒

# 問題

* ①はオンプレミスからAWSへの受信量
* ②はTransit GatewayがDirect Connectから受信した通信量
* ③はTransit Gatewayがアタッチメント送信した通信量

この構成だと①≒②≒③のようになりそうだが①と②③が全然違う。
上記の通り`VirtualInterfaceBpsIngress`は期間の平均値を示すため`BytesIn`や`ByteOut`と単位が違う。

# 解決方法

* ①`VirtualInterfaceBpsIngress`の統計を「平均」、期間を「1日」にする。
1日毎の平均値（単位：ビット/秒）のグラフが作成される。

* ②`VirtualInterfaceBpsIngress /8 * 86400`のメトリクスを作成する。
ビットのため÷8でバイトにする。(単位：バイト/秒になる)
×1日(86400秒)をする。（単位：バイト/日になる）⇒1日毎のバイトを求めることが出来る。

これで①≒②≒③のようになり、Direct ConnectとTransit Gatewayの通信量を比較出来る。
Uncaught TypeError: $(...).remodal is not a function の解決法



## はじめに

最近、あるプロジェクトで `Uncaught TypeError: $(...).remodal is not a function` というエラーに遭遇しました。この記事では、この問題の原因と解決策を共有します。

## エラーの背景

このエラーは、jQueryプラグインのRemodalを使用しようとしたときに発生しました。コンソールにこのエラーが表示され、モーダルウィンドウが機能しなくなりました。

## 原因

調査の結果、主な原因は以下でした：

1. jQueryの多重読み込み
2. Remodalプラグインの読み込み順序の問題

## 解決手順

### 1. jQueryの重複チェック

まず、ページ内でjQueryが複数回読み込まれていないか確認しました。

```html
<!-- これが重複していた -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
```

### 2. 読み込み順序の修正

jQueryとRemodalの読み込み順序を正しく設定しました。

```html
<!-- 正しい順序 -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/remodal/1.1.1/remodal.min.js"></script>
```



### 3. キャッシュのクリア

最後に、ブラウザのキャッシュをクリアし、ページを強制リロードしました。

## 結果

これらの手順を実行後、エラーは解消され、Remodalが正常に機能するようになりました。

## 学んだこと

1. スクリプトの重複に注意する
2. ライブラリの読み込み順序は重要
3. エラーメッセージをよく読むことの大切さ

## まとめ

このエラーは一見複雑に見えますが、基本に立ち返って確認することで解決できました。同様の問題に直面した方の参考になれば幸いです。
先月末までの実績データを抽出する(SPSS Modeler データ加工逆引き4-26)

# 先月末までの実績データを抽出する

![スクリーンショット 2024-09-18 14.46.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/53eebd8a-753b-83c1-6481-943706e19bc6.png)

＊数日が経過した後に確定している先月末締め以前の実績で集計表を作る際の抽出

## 1.想定される利用目的

・月次レポートための相対的な処理

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

https://github.com/yoichiro0903n/blue/raw/main/exclude_currenet_month.str

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

![スクリーンショット 2024-09-18 14.54.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/e0e9d81f-1f43-ea5f-b55c-dc2fc0da8a6a.png)

a.入力するデータは以下の通りです。2024年の1月1日から8月23日までの実績です。Valueはランダム値です。

![スクリーンショット 2024-09-18 14.59.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/5a83ced3-fdae-3e82-5be9-ec69c8f40c99.png)

b.[レコード集計]ノードを編集します。

![スクリーンショット 2024-09-18 14.59.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/d74f7bec-f21e-9fde-d848-cf8af6fab452.png)

[プレビュー]します。

![スクリーンショット 2024-09-18 14.59.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/3467659c-b9ba-9060-2882-cc15d33d854e.png)

c.[レコード結合]ノードを編集します。キーをブランクにして1対Nの結合を行います。

![スクリーンショット 2024-09-18 15.00.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/04908226-5752-b102-2c95-29c5e5e797fb.png)

[プレビュー]します。すべてのレコードに処理時点での最大日付が付与されました。

![スクリーンショット 2024-09-18 15.01.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/1659733e-d0a4-7c42-69e5-7887cca38989.png)

d.[条件抽出]ノードを編集します。該当レコードの日付[Date]と処理時点での最大日付　[Date_Max]をあらかじめ文字型に変換した上で、最初の7文字（西暦4文字＋ハイフン1文字＋月2文字）が一致したものを排除することで当月データを除く先月末までの抽出が可能になります。

![スクリーンショット 2024-09-18 15.02.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/81052f50-6a15-0813-8111-f374abb44edb.png)

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

![スクリーンショット 2024-09-18 15.03.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/4fe1ff9b-a566-d424-8d19-8c2bad214d8d.png)

#### 注意事項

PCのカレンダーを取得する場合には以下の記事を参考にしてください。

https://qiita.com/416nishimaki/items/0238eeaa1d7e6c7a9f00

## 4.参考情報


#### データとして記録された最新7日間を抽出する

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

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

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

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

https://qiita.com/416nishimaki/private/4bf813e6cba84b2a1008
[T-DASH] 任意の時刻を任意のフォーマットで取得する

# Outline

T-DASHでは、時刻の情報を変数として用いる方法として、予約語がある。
この予約語を用いることで、時刻情報を使うことができる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267085/983b88c8-7500-ea3a-1233-7ede412e3310.png)

https://service.valtes.co.jp/t-dash/function/tutorial/behaviordefinitions_vol_006


が！　パターンが少ない！！

- 過去の指定した時刻の情報を使いたい！
- 違ったフォーマットで (YYYY/MM/DD や MM/DD/YYYY など）情報が欲しい！

なので、好きな相対時刻、好きなフォーマットで時刻情報を汎用的にとれるカスタム動作を紹介する

https://service.valtes.co.jp/t-dash/?qiita

# 技術的情報

robot frameworkのGet Current Dateを用いる

https://robotframework.org/robotframework/latest/libraries/DateTime.html#Get%20Current%20Date


```
${date} =  Get Current Date  local  -5 hours  result_format=datetime
```

第一引数 local は time_zone を指定します。
localで、自身の地域を指定します。

第二引数 increment は現在時刻からの加算日時を指定します。
加算日時として、以下単位を用いて構成します。

| 単位 | 意味 | 
|:-----------|:------------|
| days       | 日数        |
| hours       | 時数        |
| minutes       | 分数        |
| secounds       | 秒数        |

記入例
| 値 | 意味 | 
|:-----------|:------------|
| 1 days       | 1日後        |
| - 1 hours       | 1時間前        |
| - 1 days - 1 hours      | 1日と1時間前   |


第三引数 result_format は出力フォーマットを指定します。

代表例として
| フォーマット | 出力例 | 
|:-----------|:------------|
| %Y-%m-%d %H:%M:%S       | 2024-10-01 12:00:00        |
| %Y/%m/%d (%a) | 2024/09/19 (Thu) |

詳しくは、以下の仕様より取得してください

https://docs.python.org/3/library/datetime.html#strftime-strptime-behavior

# T-DASHの手順

## カスタム動作

以下設定内容を Date.yamlのファイル名で保存する
```
ACT-CAT-CUSTOM-4d91c6b0-65ee-4636-a9cb-58758cbf05ea:
  action_category_name: Date
  icon: ''
  color: '#a38fcc'
  custom_data:
    file_name: Date
    pip_list: []
    library_list:
    - DateTime
  actions:
    ACT-CUSTOM-4061ff76-392e-49d8-b7fc-d952d9016200:
      action_name: 相対時刻を任意のフォーマットで変数に入れる
      action_type: operation
      action_format: 現在から「設定値1」加算した時刻を「設定値2」のフォーマットで変数名「設定値3」に格納する
      action_note: ''
      action_args:
      - value1
      - value2
      - value3
      action_def:
      - - '${date} = '
        - Get Current Date
        - local
        - ${value1}
        - result_format=${value2}
      - - Set Suite Variable
        - ${${value3}}
        - ${date}
```

次に、作成された Date.yamlをT-DASHの動作定義 -> カスタム動作 -> カスタム動作をインポート にてインポートし、実際にインポートされた設定内容を開く

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267085/67484cf7-5818-c696-c9b8-60ac467a7416.png)

4行目が、現在の時刻から、timezone、増減の日時、指定した時刻のカスタムフォーマット、で取得している。
5行目が、指定した変数名に得られた時刻データを設定する。


## スクリプト

技術的情報に記載した、増減時刻の指定、フォーマットを第一、第二引数に設定した例です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267085/36acb149-84df-3be4-95f5-69fffaf29627.png)

その結果は以下のようになります。
あとは、得られた変数 ${result_date1} ~ ${result_date3}を予約語と同じように変数として利用すればよい。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267085/33a51cc1-aabc-1874-fbd3-141eac5d892b.png)
新卒が要件定義からタスクを任された話

## はじめに
入社して 2 ヶ月目の 5 月末頃に，プロダクトの追加機能についての案件オーナーとして開発タスクをやらせてもらいました．このプロダクトには，集計したデータを PDF 形式のレポートとして出力する機能があり，このレポートの内容を英語で出力する要望に応えるための案件でした．要件定義がそもそも何かをわかっていない状態から，リリースまでやり遂げた際に学んだこと・振り返りなどを記録します．

## 要求・要件定義編
### ユーザーストーリーについて考える
当たり前ではありますが，プロダクトは誰かに使ってもらうために作っています．そのため，どのような人に向けて作るのか，どのような課題を解決するために作るのかを要求定義の形でまとめます．

PdM（プロダクトマネージャー）が本来この部分を担当するのですが，せっかくの機会というのもあり，書かせてもらいました．ここでの学びは，**ユーザーの立場から考えることが大切である**ことでした．でなければ，必要とされない開発に貴重な時間を費やしてしまうからです．

:::note
要求定義をする際にはいくつかのフレームワークがあり，[ジョブストーリー](https://jtbd.info/replacing-the-user-story-with-the-job-story-af7cdee10c27)，[バリュープロポジションキャンバス](https://www.strategyzer.com/library/the-value-proposition-canvas)，[ギャップ分析](https://asana.com/resources/gap-analysis)から定義しました．
:::

### 機能開発をする上で各所と合意を取る必要がある
要求定義が決まると，次にそれをシステムでどうやって実現するのかを要件定義の形でまとめます．この段階では，主に決めることが二つあり，仕様の決定と工数の見積もりがあります．

仕様を決定するためには，開発部署以外の人を含めたステークホルダーを集めて会議を設けたり，テキストでやり取りをする必要がありました．最終的な目的としては，各所から合意を取ることで，見当違いな機能ができあがらないようにするためです．ここでは，**話した内容や合意した内容についてエビデンスとして残しておくことが大事**でした．こうすることで，後の認識齟齬を防ぐことができます．

:::note
会議の際は，テンプレートで用意されている議事録に，基本的な日時や参加者などの情報と，議題を事前に準備しておきました．会議内で議事録を更新していき，会議後に手直しをして参加者に共有するフローで進めました．
:::

工数の見積もりをするためには，決まった仕様からタスクの大きさに分解し，それぞれにかかる人日を想像しました．当時，どのような開発やテストが発生し，どのぐらいの時間がかかるのかは正直わからなかったので，メンターと確認しながら進めました．この部分では**スケジュールなどに左右されず，純粋にかかる時間を図ることが重要**でした．工数が多くかかる場合は，人的資源を投じることや，開発スコープを狭めるなどの対策を正確に講じることにつながります．

上記の仕様と工数を再度 PdM に最終的なアウトプットや要する時間を確認してもらいました．今回の案件では，自分一人で開発してもスケジュール的に問題ないと判断されましたが，リリース日が事前に決まっているため絶対に遅れないように，と言われていました．結果的に遅延はありませんでしたが，この時細かく状況を報告するように心がけるようにしました．

## 開発編
### 実装のしやすさは要件定義で決められているほどにやりやすい
いざ実装してみて一番感じたのは，**仕様がしっかり決まっているところの開発はスムーズ**に進んだ点です．実装方針も自ずと決まるため，迷わず正しいものを作っているのがわかりました．逆に，実装するとなって発覚する仕様漏れなどは，都度仕様を改めて決める必要があったため，開発着手までにその分の時間が追加でかかりました．

今回の案件では，レポートの内容を英訳するにあたり表示する文字数が増え，デザインを変更する必要がありました．一枚のページに収めるために削っても良い箇所や内容の省略表示について，実装を進めたタイミングで改めて仕様を見直しました．

:::note
開発では feature flag を利用して進めました．各 PR を細かく main ブランチにマージできたのが利点でした．他の進め方として，統合ブランチを作成する方法もあったかと思います．
:::

### QA の観点は鋭い
6 月末ごろに開発が一通り終わり，開発したものの QA を依頼しました．開発者テストもしっかり行っていたつもりでしたが，様々な観点から事前に不具合が見つかりました．一つ具体的には，文章の省略表示を文字数で判断していた実装でしたが，レポート上に表れる英字は種類によって文字幅が異なるため，別の方法の実装に置き換える必要がありました．実装ロジックが間違ってはいなかったものの，QA 観点から様々なデータでテストしてもらえるのは，とても心強いと感じました．

## リリース編
### プロダクトの変更は十分に周知するべき
プロダクトに変更を加える際には，ヘルプページの作成・変更依頼と，顧客と直接やり取りをする CS（カスタマーサポート）チームに周知します．今回の案件で一番の反省点となったのは，ここの周知が十分にできていなかったため，CS から顧客への周知より先に本番リリースしてしまい，多くのお問い合わせを発生させてしまいました．エンジニアとしては，**リリース日と変更内容を十分に各所に周知することが大事**だと身をもって知りました．

### 想定外のニーズに対する追加実装をした話
新機能を 7 月上旬にリリースしてから数日して，デザイン変更で削られた内容が想定以上に見られていたことが判明しました．仕様作成段階では，問題ないと判断していたことが，実際のニーズと異なってしまい，要求を定める難しさが垣間見えました．このため，緊急的にこの要求に応えるような追加実装も自分が担当し，再度リリースをすることになりました．

:::note
リリース後しばらくしてから，feature flag を利用していたため，技術的負債を残さないために，このフラグを削除する対応も行いました．
:::

## まとめ
約 2 ヶ月に渡り，開発過程を試行錯誤しながら，一気通貫して携わることができた貴重な体験でした．今後はこの経験を活かし，自分のスタイルで開発の仕事を進められたら良いと考えています．あくまでも一例ではありますが，始めて開発のフローに携わる方がイメージを持つ助けになれば幸いです．
gmailのメール通知が多くて困りますよね

# TL;DR

ラベルを使うべし

# はじめに・困りごと

弊社のメールは、初期で複数のメーリングリストに参加している状態でした。各メーリングリスト宛のメールが受信ボックスにきてしまい、受信ボックスが一瞬で溢れてしまいました。

メールに気がつけなくなるので、良くないな〜とは思いつつも、まぁいいかと放置していました。ですが、ついに個人のgmailの通知も溜まってしまうようになり、解決先を調べたので共有します！！

# 解決方法

### 0. 通知を受け取りたくないメーリングリスト宛のメールを開く

### 1. Toの横の▼を押下

![Frame 16.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3790952/98bceb48-1cec-ed6e-7d12-c85a53f1f3b7.jpeg)


### 2.「MLフィルタ設定」を押下

![Frame 17.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3790952/96081195-3717-51a7-1e9f-7a79f135c44d.jpeg)


### 「フィルタ作成」を押下

![Frame 18.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3790952/71fcfa57-a734-dcde-1866-96806f1d81e6.jpeg)

### 「受信トレイをスキップ」を選択

![Frame 21.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3790952/6acf64c2-2f82-1e08-3ef0-f12510831a01.jpeg)

### 「ラベルを付ける」を選択し、ラベルを選択or新規作成し、「フィルタを作成」を押下

![Frame 20.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3790952/398a71f8-3a10-2fc2-6396-a46ed62e209c.jpeg)

:::note
チェックボックス最下「一致するスレッドにもフィルタを適用する。」をチェックすると、既存のメールも振り分けられます。
:::

### 任意のラベルを選択

![Frame 19.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3790952/8d4ce123-55e5-3a2f-2f65-7b90156582e8.jpeg)

指定したメーリングリストに届くメールが、受信トレイじゃなく各ラベルに格納されます！
これで受信トレイがスッキリしますね！

### iPhoneの通知も来なくなる

![iphone.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3790952/ec57d107-92df-0e2d-82f8-3fdb25997254.jpeg)

受信トレイに溜まらないので、iPhoneの通知バッチも消えます！嬉しい！

# ラベルの一覧を確認する

### 画面右上の設定アイコンを押下

![Frame 22.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3790952/a23f3165-2e9a-afba-1d9b-e1e6d27b8faf.jpeg)

### 「すべての設定を表示」を押下

![Frame 23.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3790952/5a112dda-5b65-721b-3fdf-1429de01cc61.jpeg)

### 「フィルタとブロック中のアドレス」を押下

![Frame 24.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3790952/0c58c4f3-385a-ddbf-fc0d-a7bcfd930de3.jpeg)

ここで一覧が確認できます。

# 受信トレイを既読済みにする

### 検索窓に「is:unread」と入力

![Frame 25.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3790952/2908b428-29bf-8135-cc70-0f049bfdc1ad.jpeg)

### チェックボックですべて選択し、既読ボタンを押下

![Frame 25.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3790952/69df2c27-5e8b-6095-db8f-f6492aabf010.jpeg)

これですべて既読にできますね！もっと簡単に行う方法もあるようです。

https://woman.mynavi.jp/article/210630-28/

気になる方は、こちらをご覧ください〜
AlmaLinuxでCppcheckによる静的解析

# Cppcheckのインストール
AlmaLinux 8 で`Cppcheck`をインストールする場合は下記のようにします。
```
# dnf --enablerepo=powertools install cppcheck
```
# VSCodeでCppcheckを使用する
## 設定
`Visual Studio Code`で`Cppcheck`を使用するには拡張機能で`C/C++ Advanced Lint`をインストールします。
**(1)［ファイル］－［ユーザー設定］－［設定］** 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3767959/ebc6d22b-dbe6-ae18-10ff-550ab678ba8e.png)

**(2)［設定］タブで［ユーザー］－［拡張機能］－［C/C++ Advanced Lint］** `Cppcheck:Enable`を`ON`にする（デフォルトでONになっている） 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3767959/e26cd324-e304-31c0-83e5-9aa0a1100508.png)

## 解析結果
VSCodeの［問題］タブに指摘が表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3767959/b9d09f30-c1bd-76b5-baf9-4b166ab9b5ea.png)

重大度(Severities)は次の通り

**error**
when code is executed there is either undefined behavior or other error, such as a memory leak or resource leak

**warning**
when code is executed there might be undefined behavior

**style**
stylistic issues, such as unused functions, redundant code, constness, operator precedence, possible mistakes.

**performance**
run time performance suggestions based on common knowledge, though it is not certain any measurable speed difference will be achieved by fixing these messages.

**portability**
portability warnings. Implementation defined behavior. 64-bit portability. Some undefined behavior that probably works “as you want”, etc.

**information**
configuration problems, which does not relate to the syntactical correctness, but the used Cppcheck configuration could be improved.

`Cppcheck`のマニュアルはこちら
https://cppcheck.sourceforge.io/manual.pdf

## 手動解析
`result.log`に結果をXMLで出力します。（結果は標準エラーで出力されます）
```
cppcheck --enable=all --xml [プロジェクトのルートフォルダ] 2> result.xml
```
Node.jsについて勉強したのでまとめてみた。

## 勉強のきっかけ

普段からフロントエンド、バックエンド両方の開発でお世話になっているNode.jsですが、サーバー環境を簡単に作れるライブラリー程度に考えて、あまり理解せずに使ってきたので、良い機会だと思い勉強することにしました。ここでは私が気づいたポイントをシェアします。
## Node.jsとは？JavaScriptのフロントからサーバーサイドへの拡張

Node.jsは、**JavaScriptをサーバーサイドで動作させるためのランタイム環境**です。もともとJavaScriptは、ユーザーのブラウザ上で動作し、動的なWebページを構築するために使われていました。しかし、Node.jsの登場により、サーバー上でもJavaScriptを実行できるようになり、開発者はフロントエンドとバックエンドの両方をJavaScriptで書けるようになりました。

Node.js以前はクライアントサイドではJavaScript、サーバーサイドではPHPやRubyを使って開発するのが一般的でしたが、Node.jsを使うことで**JavaScript一つでフルスタック開発**が可能となりました。これにより、開発の一貫性や効率が大幅に向上し、**JavaScriptの再利用**というメリットが生まれたそうです。

## Node.jsが誕生した背景

そもそもNode.jsが生まれた背景には、**従来のサーバーサイド技術の限界**を解消したいというニーズがありました。従来の技術では、大量のリクエストを効率的に処理することが難しく、特にリアルタイム通信や大規模なアプリケーションでは性能に制約が生じることがよくありました。例えば、PHPやRubyのサーバーでは、リクエストが多くなるとスレッドが増加し、処理の遅延やパフォーマンス低下が発生しやすくなります。

そこで、2009年に**Ryan Dahl**によってNode.jsが開発されました。彼は、ファイルI/Oやデータベースアクセスなどの**I/O操作がブロックされる**問題を解決するため、JavaScriptの非同期処理の強みを活かして、**効率的にリクエストを処理できるサーバー**を構築することを目指したそうです。


## ランタイム環境って何？
ランタイム環境は、**プログラムが動作するために必要な機能やリソースを提供する環境**です。例えば、Node.jsは、JavaScriptがサーバーサイドで動作するために必要なAPIやライブラリを提供しています。これにより、JavaScriptがネットワーク通信やファイルの読み書きを簡単に扱えるようになり、サーバーサイドの処理が可能になります。

このランタイム環境を「キッチン」に例えるとわかりやすいです。料理を作るためには、レシピ（プログラム）と、キッチン（ランタイム環境）が必要です。キッチンには包丁やコンロ、冷蔵庫など、料理に必要な道具が揃っています。同様に、Node.jsはJavaScriptがサーバーで動作するための「道具」を提供してくれるのです。
具体的には、**メモリやCPUの管理、ファイルシステムへのアクセス、ネットワーク通信**などの機能を持っていて、開発者がこれらのことを考えなくても良いようにしてくれています。


## Node.jsの特徴と革新性

Node.jsの特徴として、特に注目すべきは次の3つです：

1. **非同期I/Oとシングルスレッドモデル**  
   Node.jsは、非同期処理を活用して少ないリソースで大量のリクエストを効率よく処理することができる。シングルスレッドでありながら、並行して多数のリクエストを処理できるため、リアルタイム性が求められるアプリケーションに強い。

2. **JavaScriptの再利用**  
   フロントエンドとバックエンドの両方でJavaScriptを使用できるため、コードの一貫性が保たれ、学習コストや開発効率を大幅に向上させる。

3. **NPMエコシステム**  
   NPM（Node Package Manager）を通じて、膨大な数のオープンソースライブラリを活用可能。これにより、サーバー構築やAPI開発など、複雑な機能を迅速に導入できる点もNode.jsの大きな強みとなっている。

## Node.jsでサーバーを構築してみる

実際にNode.jsを使ってサーバーを立てるのも、ものすごく簡単で、数行のコードでシンプルなHTTPサーバーを作成できます。

```ts
import { createServer } from 'http';

const server = createServer((req, res) => {
  res.statusCode = 200;
  res.setHeader('Content-Type', 'text/plain');
  res.end('Hello, World!\n');
});

server.listen(3000, () => {
  console.log('Server running at http://localhost:3000/');
});

```

## Node.jsを学んで気づいたこと
普段はNest.jsなどを使用してバックエンドの開発を行うことが多いのですが、今回改めてNode.jsについて学んで、Nest.jsもNode.jsの上に構築されているのだなと改めて実感しました。フルスタックJavaScriptの道を切り開いた先人達の意思を受け継ぎ、これからもTypeScriptでフロント、バックエンド両方開発していこうと思います。
空間フィルター

## 空間フィルター
空間の情報は直線、カーブする曲線、円や四角など形を表す情報である。このような形を取り出す方法として、**空間フィルター**という画像処理がある。
フィルターは2次元の行列で表し、画像の一部とフィルターの要素の積の和を、画像をスライドさせながら画像の現領域で求めていく。このような計算を**畳み込み演算**と呼ぶ。

元画像の位置(i, j)のピクセル値をx(i, j)、3×3のフィルターをh(i, j)としたら、畳み込み演算でえられる値g(i, j)は、以下のようになる。

```math
g(i, j) = \sum_{u=-1}^{1} \sum_{v=-1}^{1} x(i + u, j + v) h(u + 1, v + 1)
```

フィルターの大きさは3×3だけでなく任意に決めることができるが、5×5、7×7など、中心を決められる奇数の幅が使いやすい。
実際に手書き数字に畳み込み演算をしてみる。

```python
import numpy as np
import matplotlib.pyplot as plt
import time

from keras.datasets import mnist
from keras.utils import to_categorical

from keras.models import Sequential
from keras.layers import Dense, Activation
from keras.optimizers import Adam

(x_train, y_train), (x_test, y_test) = mnist.load_data()

x_train = x_train.reshape(60000, 28, 28, 1)
x_train = x_train.astype('float32')
x_train = x_train / 255

num_classes = 10

y_train = to_categorical(y_train, num_classes)

x_test = x_test.reshape(10000, 28, 28, 1)
x_test = x_test.astype('float32')
x_test = x_test / 255

y_test = to_categorical(y_test, num_classes)

id_img = 2
myfile1 = np.array([[1, 1, 1], [1, 1, 1], [-2, -2, -2]], dtype=float)
myfile2 = np.array([[-2, 1, 1], [-2, 1, 1], [-2, 1, 1]], dtype=float)

x_img = x_train[id_img, :, :, 0]
img_h = 28
img_w = 28

x_img = x_img.reshape(img_h, img_w)

out_img1 = np.zeros_like(x_img)
out_img2 = np.zeros_like(x_img)

# フィルター処理
for ih in range(img_h - 3):
    for iw in range(img_w - 3):
        img_part = x_img[ih:ih + 3, iw:iw + 3]
        out_img1[ih + 1, iw + 1] = np.dot(img_part.reshape(-1), myfile1.reshape(-1))
        out_img2[ih + 1, iw + 1] = np.dot(img_part.reshape(-1), myfile2.reshape(-1))

# 表示
plt.figure(1, figsize=(12, 3.2))
plt.subplots_adjust(wspace=0.5)
plt.gray()

plt.subplot(1, 3, 1)
plt.pcolor(1 - x_img)
plt.xlim(-1, 29)
plt.ylim(29, -1)

plt.subplot(1, 3, 2)
plt.pcolor(-out_img1)
plt.xlim(-1, 29)
plt.ylim(29, -1)

plt.subplot(1, 3, 3)
plt.pcolor(-out_img2)
plt.xlim(-1, 29)
plt.ylim(29, -1)

plt.show()
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3850581/a2075b5d-b16c-deb7-45d6-4608ea863922.png)

左画像が元の画像であり、真ん中は横ラインにエッジを効かせた画像。右は縦ラインにエッジを効かせた画像である。

フィルターを適用すると出力画像のサイズは一回り小さくなる。この対応策として**パディング**という方法がある。

パディングはフィルターを適用する前に、0などの固定した要素で周囲を水増しする方法である。
3×3のフィルターを適用する場合には、幅1のパディングを施、5×5の場合には、幅2のパディングをすればいい。

パディングに加えてフィルター処理に関するパラメータがもう1つある。フィルターは1つ間隔をずらすが、2でも3でも、任意の間隔でずらすことができる。この間隔を**ストライド**呼ぶ。
ストライドを大きくすると出力画像は小さくなる。パディングやストライドの値はライブラリで畳み込みネットワークを使う際に、引数として渡すことになる。
漸近展開

## 漸近展開とは

漸近展開は, 複雑な関数$f(x)$を$x\rightarrow x_0$の極限において別の単純な関数の列$\\{\phi_j(x)\\}$を使って近似する方法である.

テイラー展開のように関数の定義域全体にわたって近似するものではなく, あくまでも$x\rightarrow x_0$における近似値を与えることを目的とする.

展開した数列は必ずしも収束するとは限らないが, 適当な個数の項によって元の関数をよく近似することができる.

## 定義

関数$f(x)$と$g(x)$が,
$$\lim_{x\rightarrow x_0}\frac{f(x)}{g(x)} = 1$$

という関係を満たすとき, 「$x\rightarrow x_0$において$f(x)$は$g(x)$に**漸近する**」といい,
$$f(x) \sim g(x) \quad as \quad x \rightarrow x_0$$

と書く. 一般的に$f(x)$は複雑な関数, $g(x)$は単純な関数である.

$f(x) = o(g(x))$という記号（small "o"）は, $x\rightarrow x_0$のときに$f(x) \ll g(x)$, つまり$\lim_{x\rightarrow x_0}\frac{f(x)}{g(x)}=0$を意味する.

$\\{\phi_j(x)\\}$は, $x\rightarrow x_0$で$\phi_{j+1}(x) = o(\phi_j(x))$となるとき, $ x \rightarrow x_0$での**漸近関数列**という.

$f(x)$は, $\\{\phi_j(x)\\}$が漸近関数列で,
$$f(x) - \sum_{j=1}^{n}a_j\phi_j(x) = o(\phi_n(x))$$

となるとき, **漸近展開**
$$f(x) \sim a_1\phi_1(x) + a_2\phi_2(x) + \cdots $$

を持つ, という.

別の言い方をすると, 関数$f(x)$を漸近関数列で展開し, $n$項目までの和を$S_n(x)=\sum_{j=1}^{n}a_j\phi_j(x)$, $n+1$項目以降の和を$R_n(x)=f(x)-S_n(x)$としたとき, 近似に利用する最後の項$\phi_n(x)$よりも, 無視する部分$R_n(x)$が非常に小さくなるような展開が漸近展開である.

## 漸近展開の例
大きな正の実数$x>0$について次の積分を考える. 普通に計算するのは難しい.
$$f(x)=\int_{0}^{\infty}\frac{\exp(-xt)}{1+t}dt \tag{1}$$

そこで, 展開
$$\frac{1}{1+t}=1-t+t^2-t^3 \cdots \tag{2}$$

を式$(1)$に代入し, ガウス積分の公式
$$\int_{0}^{\infty}t^n \exp(-xt)dt= \frac{n!}{x^{n+1}} \tag{3}$$

を使うと, 次のような数列で書くことができる.

```math
\begin{eqnarray}
f(x)&=&\int_{0}^{\infty}\frac{\exp(-xt)}{1+t}dt\\
&=&\int_{0}^{\infty}\exp(-xt)\lbrack1-t+t^2-t^3 \cdots \rbrack dt\\
&=&\frac{1}{x} - \frac{1!}{x^2} + \frac{2!}{x^3} - \frac{3!}{x^4} \cdots \tag{4}
\end{eqnarray}
```

この数列の第$n$項は$g_n(x)=(-1)^{n-1}\frac{(n-1)!}{x^n}$である. ダランベールの収束判定法を使うと, どんなに大きな$x>0$をとっても, それよりもさらに大きな$n$については,
```math
\begin{eqnarray}
\Bigg\lvert\frac{g_{n+1}(x)}{g_n(x)}\Bigg\rvert=\frac{n!}{(n-1)!} \cdot \frac{x^n}{x^{n+1}}=\frac{n}{x} > 1\tag{5}
\end{eqnarray}
```
となり, 数列は収束しない.

しかし, たとえば$x=10$ と置いて4次の項まで計算すると, 
```math
\begin{eqnarray}
f(10) &\approx& \frac{1}{10} - \frac{1!}{10^2} + \frac{2!}{10^3} - \frac{3!}{10^4} = 0.0914
\end{eqnarray}
```
となり, 数値計算によって正確に求めた $f(10)=0.09156 \cdots $とよく一致する.

これは, $f(x)$を, $x\rightarrow \infty$における漸近関数列$\phi_n(x)=\frac{1}{x^n}$と係数$a_n=(-1)^{n-1}(n-1)!$で,

$$f(x) \sim \sum_{n=1}^{\infty}a_n\phi_n(x)$$

と漸近展開した形になっており, 適切に項数を選ぶことにより良い近似が得られることが確認できる.

## 参考
[Asymptotics and perturbation methods - Lecture 1: Asymptotic expansions](https://www.youtube.com/watch?v=KZsk8B_z8pI)
最も簡単なLinuxでのNVIDIA GPUファン速度制御ガイド

## はじめに

LinuxサーバーやPCにNVIDIA GPUが搭載されており、グラフィカルインターフェースなしでSSHを使用してファン速度を調整したい場合、このガイドがその方法を提供します。騒音の低減、効率の向上、またはハードウェアの冷却を目的とするかに関係なく、このガイドを使えば簡単に設定が可能です。

**（GUIは不要、SSHで完結）（おそらく最もシンプルな方法）**

スクリプトのリンク: https://github.com/RoversX/nvidia_fan_control_linux/

[English Version](https://blog.closex.org/posts/26a7c6ee/)

<br>

## クイックスタートガイド
### 環境設定

1. **Python仮想環境を作成**

    ```bash
    python3 -m venv fan
    source fan/bin/activate
    ```

2. **pynvmlライブラリをインストール**

    ```bash
    pip3 install pynvml
    ```

3. **ファンコントロールスクリプトをダウンロード**

    ```bash
    wget https://raw.githubusercontent.com/RoversX/nvidia_fan_control_linux/main/nvidia_fan_control.py
    ```

4. **スクリプトのパラメータを調整**

    ```py
    # ファンカーブの設定
    temperature_points = [0, 40, 57, 70]
    fan_speed_points = [27, 40, 80, 100]
    
    # CPU負荷軽減のためのスリープ時間
    sleep_seconds = 5
    ```
![Screenshot 2024-06-28 at 7.39.43 PM.webp](https://bu.dusays.com/2024/06/28/667ea1109142b.webp)
### スクリプトの設定

スクリプトの起動を簡単にするため、次のような`fan.sh`スクリプトを作成します。

```bash
nano fan.sh
```

エディタが開いたら、以下の内容をコピーして貼り付けてください：

```sh
#!/bin/bash

# 仮想環境を有効化するためにsudo権限を使用
sudo bash <<EOF
source /home/x/Workspace/fan/bin/activate
python /home/x/Workspace/fan/nvidia_fan_control.py
deactivate
EOF
```

### ファンコントロールの起動

設定が完了したら、以下のコマンドでファン速度の制御を開始します：

```bash
./fan.sh
```

## 出力例

スクリプト実行後、以下のような出力が表示されます：

```bash
x@x:~$ ./fan.sh
[sudo] password for x: 
============================================================
Driver Version: 535.183.01
GPU 0: NVIDIA GeForce RTX 2080 Ti
Fan Count: 1
============================================================
Temperature: 42°C
Total Curve Point: 4
Current Curve Point: 2
Previous_Curve_Point: 1
Fan_Speed: 45%
============================================================
Temperature_Delta: 17
Fan_Speed_Delta: 40
Temperature_Increment: 2
Fan_Speed_Increment: 4.705882352941177
Previous_Temperature: 42°C
Step_Down_Temperature: 37
============================================================
```

この出力により、GPUの温度やファン速度の状態が確認でき、適切な条件で動作しているかどうかがわかります。

このスクリプトは、https://github.com/Cippo95/nvidia-fan-control に基づき改良されており、一部のコードは https://gist.github.com/AlexKordic/65f031b708177a01a002cc19f0d7298c のものを利用しています。

```py
finally:
    # 自動ファンコントロールにリセット
    for handle, fan_count in zip(handles, fan_counts):
        for i in range(fan_count):
            nvmlDeviceSetDefaultFanSpeed_v2(handle, i)
    nvmlShutdown()
```

## 結論

この手順に従えば、GUIを使用せずにLinuxでNVIDIA GPUのファン速度を簡単に制御できるようになります。特にリモート管理やサーバー環境での使用に適しています。

Zenn での初公開: https://zenn.dev/closex/articles/a179489b47fdd3
OneDriveとNASでのGit運用の違いについて

Gitを使ってプロジェクトを共有する際、OneDriveでは問題なく共有ができたが、NASではうまくいかなかった経験について書きます。

OneDriveの場合
ローカル同期：OneDriveはクラウドストレージながら、ローカルにファイルを同期するため、
Gitはファイルを直接ローカルで操作でき、変更の追跡やコミットもスムーズに行えます。

NASの場合
ネットワークドライブの制約：NASはファイルがネットワーク越しにあるため、Gitはリアルタイムで変更を
追跡するのが難しいことがあります。特に、ネットワーク遅延や接続の安定性が影響を与えることがあります。

解決策
NASのファイルをローカルにコピーして作業し、変更後にNASへ戻すことで一時的に問題を回避できます。また、NASの設定やGitの設定を見直すことで改善できる可能性もあります。
OCIでroot Compartmentに設定が必要なリソース

# はじめに
OCIのCompartmentを使用することで、テナンシーを論理的に分割することができます。例えば、システムごとにCompartmentで分割し、各Compartmentの管理者がリソースを管理することができます。
ただし、一部のリソースでは、テナンシー単位でのポリシー設定などが必要な場合があります。そのようなリソースの管理には、テナンシー管理者の協力が必要です。
ここではこのようなリソースをまとめています。

:::note 
この記載が全てではなく、私が遭遇したものを忘れないようにまとめたものです
:::

# クロステナンシーポリシー
テナンシーをまたがって認可するためのポリシーです。
そのポリシー構文をroot Compartmentに設定する必要があります。

https://speakerdeck.com/ocise/ociji-shu-zi-liao-idoyobiakusesuguan-li-iam-xiang-xi?slide=61

# Virtual Nodes
サーバーレスのOKE（Kubernetesのマネージドサービス）です。AWSだとFargateにあたるものです。
Virtual Nodesを使用するには、root Compartmentにポリシー設定が必要です。

https://docs.oracle.com/ja-jp/iaas/Content/ContEng/Tasks/contengvirtualnodes-Required_IAM_Policies.htm

# ネットワーク・ソース
ネットワーク・ソースはOCIの各サービスにアクセスできるIPアドレスを制限するための設定です。
ネットワーク・ソースはroot Compartmentに作成するので、テナンシー管理者に設定を依頼するか、Compartment管理者に以下のポリシーが必要です。

`allow group グループ名 to manage network-sources in tenancy`

# OS管理ハブ
OS管理ハブは、OCIまたはAWSやAzure、オンプレミスのインスタンスのOSを管理するサービスです。

https://docs.oracle.com/ja-jp/iaas/osmh/doc/getstarted.htm#supported-environments

管理に使用するリポジトリ（ソフトウェアソース）のうち、Oracle Linuxのリポジトリはroot Compartmentにのみ追加できます。
root Compartmentに追加したあとに、各Compartmentにレプリケートすることはできます。

https://docs.oracle.com/ja-jp/iaas/osmh/doc/add-vendor-software-sources.htm