OmniAICreator/Qiita-1.07M huggingface dataset:
【iOS】URLのInitializerの仕様がiOS17から変更されていた

# 事の経緯
あるとき、URLの初期化が絡んだUTのケースでテストが失敗するようになった。
しかし、該当する実装はいじっていない。
謎挙動だ。。

でも影響してないからヨシ！としてしばらく目を背けていました。
これにちゃんと向き合って深ぼってみたよという話です。

# 問題
テストコードを簡単に作ってみました。
```swift
import UIKit

func test() {
    let path = "https://www.google.com/"

    guard let url = URL(string: path) else {
        print("nil")
        return
    }

    print(url) // https://www.google.com/
}

test()
```

これは正常系なので期待値は想定通り。

次に、本来URLに渡したら値を返さないはずの値を入れてみました。
```swift
//let path = "https://www.google.com/"
let path1 = "^-^" // URLで許容されていない記号
let path2 = "ほげ" // 日本語
let path3 = "" // 空欄
```

```shell
path1の結果：　"%5E-%5E"
path2の結果：　"%E3%81%BB%E3%81%92"
path3の結果：　"nil"
```

本来ならnilが表示されて欲しいはずが、URLエンコードされて表示されてしまっていました。
かろうじて空文字は期待通りになりましたが、落ちていたUTのケース的に不正なURLで問題ないかを確認するようなケースだったので、じゃあ空文字にすればテスト通るから良いよね！ということにはなりませんでした。

# 解決策
ここで一度公式のドキュメントを見直してみると、[URLの初期化に関するページ](https://developer.apple.com/documentation/foundation/url/3126806-init)で重要な記述を見つけました。

>For apps linked on or after iOS 17 and aligned OS versions, URL parsing has updated from the obsolete RFC 1738/1808 parsing to the same RFC 3986 parsing as URLComponents. This unifies the parsing behaviors of the URL and URLComponents APIs. Now, URL automatically percent- and IDNA-encodes invalid characters to help create a valid URL.

要するに、
- iOS17以降のバージョンだと従来のURL解析は廃止されてURLComponentsと同じ解析方法を用いるように更新された
- 無効な文字を自動的にエンコードするようになった

といったことが言及されています。

じゃあiOS17ではどうすれば従来通りの挙動になるのか？というところですが、`init(string:encodingInvalidCharacters:)`を使うと良いです。
`encodingInvalidCharacters`を`false`にすることで、URL文字列が厳密に有効であるかを確認するようになります。

下記のように修正すると、無事に従来通りの挙動になりました。
```swift
func test() {
    let path = "^-^"

    guard let url = URL(string: path, encodingInvalidCharacters: false) else {
        print("nil") // 早期リターンのケースに入り、nilが表示される
        return
    }

    print(url)
}
```

とはいえ、この初期化のメソッドはiOS17以降から利用できるものになるので、iOS16以前のバージョンも対応している場合は条件を分岐して利用するのが良いでしょう。

```swift
if #available(iOS 17.0, *) {
    let url = URL(string: path, encodingInvalidCharacters: false)
    // 何らかの処理
} else {
    let url = URL(string: path)
    // 何らかの処理
}
```

# まとめ
挙動に困惑しましたが、蓋を開けてみれば原因と解決策はシンプルなものでした。
同じように困った人がいれば助けになると幸いです。

（こんな記事書いといてもうすぐiOS18が出そう...次のOSの準備をせねば...！）

# 参照

1. [init(string:) | Apple Developer Documentation](https://developer.apple.com/documentation/foundation/url/3126806-init)
1. [init(string:encodingInvalidCharacters:) | Apple Developer Documentation](https://developer.apple.com/documentation/foundation/url/4191020-init)
1. [[Swift] iOS17（Swift 5.9） で日本語ドメインのURLが生成できるようになってる！](https://qiita.com/akadateppei/items/40913c1fde7860acdf47)
Marpで発表スライドを作ろう

## はじめに

スライドの作成ツールにはgoogleスライドやパワーポイント、canvaなど様々あると思います。
そんな中で今回はmarkdown形式のファイルからスライドを生成できるMarpというサービスを紹介したいと思います。
Marpを利用することでファイルをGitHubやGitLabなどのGitホスティングサービス上で管理したり、VSCodeの拡張機能を利用することでVSCode上でスライドを動かすことができます。

## Marpとは
MarpとはMarkdown Presentation Ecosystemとも呼ばれ、Markdownドキュメントを記述することでスライドに変換できるツールです。

https://marp.app/

## Marpを利用してスライドを作ってみる

以下の２ステップでMarpに対応させることができます

1. VSCodeの拡張機能をインストールする

![vscode_extension_marp.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1087368/fd7f6d42-3b0d-d073-670b-44e3c2a548d0.png)
2. mdファイルの先頭に以下の記載をする

```jsx
---
marp: true
---
```

## カスタマイズする

指定を追加することでスライドをカスタマイズすることもできます

### テーマの変更

mdファイル内に以下の記載を追加することでテーマを変更することができます。

```jsx
---
marp: true
theme: 
---
```
以下の記事でテーマについて紹介していただいています。

https://qiita.com/YoshikiIto/items/74b3d786266b1de3ed93

### ページ番号の追加

mdファイル内に以下の記載を追加することでページ番号を追加することができます。

```jsx
---
marp: true
paginate: true
---
```

### カスタマイズする

自分でcssを使用してカスタマイズすることもできます。

**mdファイル内に直接記述するパターン**

```css
style: |
  section {
    background-color: gray;
    font-size: 40px;
  }
```

**cssファイルに記述するパターン**

vscode のsettings.jsonに利用するテーマを定義したファイルを記述することで、自身で作成したcssファイルを適用することができます。

```
/.vscode/settings.json
/themes/xxx.css
xxx.md
```

## 所感

- 軽い資料を作成するときはすごく便利
- gitで管理できる
- 凝った資料を作るのは大変

以下にサンプルを用意したのでぜひご覧ください

https://github.com/sayyyyyy/marp-slide/blob/main/tetemeat_lt.md

## 参考

https://marp.app/

https://marketplace.visualstudio.com/items?itemName=marp-team.marp-vscode

https://marpit.marp.app/directives?id=theme
US-100超音波センサの値がおかしくなったのを対処した話

仕事で超音波センサUS-100を使う機会がありました。
https://www.switch-science.com/products/5512

↑
これ

測定対象物との距離を測定したかったので、
Raspberry Pi 4B 2GBと組み合わせて、
Pythonで距離測定を1秒おきに繰り返すコードを書きました。
仕事で書いたコードなので手元にありませんが、
要はWhile TRUE内でWait 1して1秒おきにWhile文の中でセンサの値を取得してるわけです。

んで、10回に2，3回ぐらい測定対象物が測定範囲内にあるのに「1100㎝」とか変な値を返してきて困ってたんですけど、
https://learn.adafruit.com/ultrasonic-sonar-distance-sensors/python-circuitpython
に載ってたプログラムの
uart = serial.Serial("/dev/ttyS0", baudrate=9600, timeout=1)
のTimeoutを2に設定して、Python内でWait 2に設定したら治りました。

まあ安物のセンサで1秒おきに測定しようとすんなってことですね（そうか？）
私の用途では1秒おきも2秒おきも大して変わらなかったので問題なかったです。

マイナーなセンサで日本語情報が乏しく、同じ事象で困ってる人が一人でも助かったらいいなという感じです。
AtCoder 勉強記録 [C++] その2

AtCoderで入茶を目指して勉強しています。
勉強を継続するために投稿を始めました。
もともとアカウントを作成していましたが、今年の4月から本格的に勉強を始めました。
一応自分用に解法を書いていますが雑です、自分で読み返して困ったら修正します。
[私のアカウント](https://atcoder.jp/users/nanami_brother)
[解いた問題](https://kenkoooo.com/atcoder/#/table/nanami_brother)
# 本日解いた問題
## B - Hard Calculation
[B - Hard Calculation](https://atcoder.jp/contests/abc229/tasks/abc229_b)
解答
```c++
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using vec = vector<ll>;
#define rep(i, n) for (int i = 0; i < (int)(n); i++)

int main() {
  ll a, b;
  cin >> a >> b;
  while(a > 0 || b > b){
    if(a%10 + b%10 >= 10) {
      cout << "Hard" << endl;
      exit(0);
    }
    a /= 10;
    b /= 10;
  }
  cout << "Easy" << endl;
}
```
### 解法
while文を使って1桁ずつ加算を考える。繰り上がったらHardを出力して終了、ループが終了したらEasyを出力。
## B - Triple Metre
[B - Triple Metre](https://atcoder.jp/contests/abc230/tasks/abc230_b)
```c++
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using vec = vector<ll>;
#define rep(i, n) for (int i = 0; i < (int)(n); i++)

int main() {
  string s, t;
  cin >> s;
  rep(i,10) t += "oxx";
  rep(i,3){
    bool jud = true;
    for(int j=0;j<s.size();j++){
      if(t[j+i] != s[j]) jud = false;
    }
    if(jud) {
      cout << "Yes" << endl;
      exit(0);
    }
  }
  cout << "No" << endl;
}
```
### 解法
oxxを10^5個つなげた文字列Tと入力された文字列Sの比較を行う。Sと比較するときTをそれぞれ１文字目、2文字目、3文字目スタートで比較するとTがSを含むかどうか判定できる。
## B - Election
[B - Election](https://atcoder.jp/contests/abc231/tasks/abc231_b)
```c++
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using vec = vector<ll>;
#define rep(i, n) for (int i = 0; i < (int)(n); i++)

int main() {
  ll n;
  map<string,ll> res;
  cin >> n;
  string s;
  rep(i,n){
    cin >> s;
    res[s]++;
  }
  ll tmp = 0;
  for(auto const&[k,v]:res){
    if(tmp<=v) {
      tmp = v;
      s = k;
    }
  }
  cout << s << endl;
}
```
### 解法
Mapを使うことで候補者の票数を簡単に数えることができる。私はMapのkeyを候補者の名前、valueを票数とした。最後にvalueが一番大きいkeyを出力する。
## C - Select Mul
[C - Select Mul](https://atcoder.jp/contests/abc221/tasks/abc221_c)
```c++
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using vec = vector<ll>;
#define rep(i, n) for (int i = 0; i < (int)(n); i++)

int main() {
  string n;
  cin >> n;
  sort(n.begin(),n.end());
  int res = 0;
  do{
    for(int i = 1; i < n.size(); i++){
      string a,b;
      for(int j = 0; j < i; j++) a += n[j];
      for(int j = i; j < n.size(); j++) b += n[j];
      if(a[0] == '0' || b[0] == '0') continue;
      res = max(res,stoi(a)*stoi(b));
    }
  } while(next_permutation(n.begin(),n.end()));
  cout << res << endl;
}
```
### 解法＋メモ
順列を生成するnext_permutation関数を使用する。生成されたNの順列に対してfor文を使用し2つに分割し、乗算を行い最大値を求める。
普通にわからなかったうえにnext_permutation関数も知らなかったため要復習。解説を読んだら理解できた。

### 参考文献
[C - Select Mul 解説 by penguinman](https://atcoder.jp/contests/abc221/editorial/2720)
量子エンジニア(アニーリング式)勉強会メモ #1

# 事の起こり
昨年末に今まで何度も勉強しようとして挫折していた量子コンピュータの再度始めることにしました。その切っ掛けになったのが、TYTAN SDKというOSSのシミュレーターの勉強会に参加したことでした。しかし、最近忙しさで久しく触っていなかったので、復習も兼ねて再度参加してみることにしました。

https://qiita.com/y-vectorfield/items/697fdd269ed9c18415c3

# 第1回の内容
## n個の量子ビットのうちm個を1にする

```python
H += (q[0] + q[1] + q[2] + ・・・ + q[n] - m)**2
```

## ライブラリのimport

```python
from tytan import *
```

## n個の量子ビットを用意する

```python
q = symbols_list(n, 'q{}')
```

```python:n = 3の時
print(q)
[q0 q1 q2]
```

```python:3個の量子ビットのうち1個を1にする
H = 0
H += (q[0] + q[1] + q[2] - 1)**2 (*)
```

# コンパイル

```python
qubo, offset = Compile(H).get_qubo()
```

```python:Hが(*)の時
print(qubo)
{('q0', 'q0'): -1.0, ('q1', 'q1'): -1.0, ('q2', 'q2'): -1.0, ('q0', 'q1'): 2.0, ('q0', 'q2'): 2.0, ('q1', 'q2'): 2.0}
```

```python:Hが（*)の時
print(offset)
1
```

# サンプラーの選択

```python
solver = sampler.SASampler()
```

# サンプリング

```python
results = solver.run(qubo)
```

# 結果の表示

```python
for r in results:
    print(r)
```

```python:上記の例の場合(量子ビットの状態(辞書型), エネルギー, ヒット数)
[{'q0': 0, 'q1': 0, 'q2': 1}, -1.0, 48]
[{'q0': 0, 'q1': 1, 'q2': 0}, -1.0, 23]
[{'q0': 1, 'q1': 0, 'q2': 0}, -1.0, 29]
```
* ヒット数の合計 = 100
* エネルギーは低い順( = 良い順)に出力

# Reference
https://github.com/tytansdk/tytan_tutorial
Cloudblast AWS 代替 - AMD Epyc VPS, 10 Gbps, 2.5Tbps DDoS保護, 時間単位の課金

![Frame 69.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3824912/7dcf38c6-d056-61ae-9290-32ed3756151d.png)

ウェブサイト: https://cloudblast.io/
Discord: https://discord.gg/rMMZs6jpN6

主な特徴:
🌐 VPS全てで10 Gbps
🛡️ 2.5 TbpsのDDoS保護
🔥AMD EPYCハードウェア
🔥高速NVMe SSD
💵 時間単位の課金
🌟とても使いやすいコンソールパネル
関数とメソッドは近しいけど別だよな話


普段業務でプログラミングをしていて無意識に関数とメソッドを使い分けている人も多いと思います。

動けばOKというような感じはしますが、人に説明するときに微妙に伝えたいことと言葉がミスマッチを起こしてしまうことがあります。

この記事では関数とメソッドはどう違うのかを改めて整理してみます。

みなさんもコミュニケーションをするときに注意してみてください。

（かく言う私も過去には気にせずに先輩エンジニアに多大な負荷をかけてしまっていたので誰かの役に立つと良いなと思いながら書きます）

## 関数とは

関数(function)はプログラムの中で処理をまとめたものです。

関数は引数を受け取り、処理を行い、戻り値を返すことができます。

何を今更感がありますが、Goでサンプルを書くとこんな感じです。

```go
func add(a, b int) int {
    return a + b
}
```

言うまでもないですがadd関数は引数を2つ受け取り、足し算をして戻り値として返しています。

## メソッドとは

一方でメソッドとは、オブジェクト指向プログラミングにおいて、オブジェクトに対して行う処理をまとめたものです。

大体は関数みたいなものですがオブジェクトに対して処理を行うという点が異なります。

Goで書く場合はこんな感じです。

```go
type Calculator struct {
    a, b int
}

func (c Calculator) add() int {
    return c.a + c.b
}
```

関数とは形が違いますね。

関数では足し算をする対象が**引数**で与えられましたが、メソッドでは足し算をする対象が**レシーバ**として与えられています。

メソッドでは操作する対象の値が引数だけでなくレシーバとしても与えられるという点が関数との大きな違いです。

timeパッケージで関数とメソッドの差を見てみると、関数はtime.Now()のように呼び出し、メソッドはtime.Time型のレシーバに対して呼び出すことができます。

```go
package main

import (
    "fmt"
    "time"
)

func main() {
    fmt.Println(time.Now()) // 関数

    now := time.Now()
    fmt.Println(now.Year()) // メソッド
}
```

## まとめ

言葉の定義をしっかり抑えて人に説明するときに自信を持って伝えられるようにしましょう。

（過去の自分に届け）
aptコマンド

# はじめに
インストールやアップデートを行うコマンドaptのメモ

# aptとは
aptは"Advanced Package Tool"の略で、DebianベースのLinuxディストリビューション（例：Ubuntu）で使用されるパッケージ管理ツール
aptはシステムのパッケージ（ソフトウェア）をインストール、アップデート、削除、検索するためのコマンドラインツール
apt-getやapt-cacheを統合したもの

# aptはこうやる
パッケージをインストール
```
sudo apt install <パッケージ名>
```
パッケージリストの更新
```
sudo apt update
```
インストール済みパッケージを最新版に更新
```
sudo apt upgrade
```
インストール済みパッケージを削除
```
sudo apt remove <パッケージ名>
```
パッケージの情報を表示
```
apt show <パッケージ名>
```

# さいごに
aptコマンドはLinuC レベル1　101の試験範囲のコマンドです。
Linuxを使えることでエンジニアとしての付加価値を上げていきましょう。

https://linuc.org/linuc1/range/101.html

https://linuc.org/study/samples/index/101/
AWS RDS PostgreSQLで使用するSecurityGroup（アウトバウンド）について調査

# 概要

AWS RDS PostgreSQLで使用するSecurityGroupのインバンドの設定は分かりやすいものの、アウトバウンドの設定についてRDS側からアウトバウンドするケースがあるのかと気になったので調査した。

# 結論
基本的には「**アウトバウンドを使用することはない**」が、
限定された条件でアウトバウンドを使用する場合がある。
※リンクは全てAWS公式ドキュメントです。

* S3へのデータ転送
    * [参考「RDS for PostgreSQL DB インスタンスから Amazon S3 へのデータのエクスポート」](https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/postgresql-s3-export.html)
* Lambda関数の実行
    * [参考「Aurora PostgreSQL DB クラスターから AWS Lambda 関数を呼び出す」](https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/AuroraUserGuide/PostgreSQL-Lambda.html)
* DBクラスターに対して論理レプリケーションを通じた接続
    * [参考「Aurora での PostgreSQL 論理的なレプリケーションの使用」](https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/AuroraUserGuide/AuroraPostgreSQL.Replication.Logical.html)

# まとめ

最近はインバウンドよりアウトバウンドの制限の方が難しいく感じることが増えました。。
特にマネージドサービスだと、サービス自体の更新などでSGを開けた方がいいのかなど迷う機会があったりするのでこの記事が少しでも皆様の参考になれば幸いです。
OCIでnostrリレーを動かそう (前編)

前編ではnostrのリレー実装strfryをビルド&設定するところまでをやっていく

#### Oracle Cloud Accountを作る
ちょっとめんどくさい (流れに沿って登録していけばいいので割愛)

:::note info
リージョンは自由にえらんでよいがTokyoは人気すぎるのでOsakaをえらんだ
:::

#### Instanceを作成
Ubuntu 22.04 Minimal / VM.Standard.E2.1.Micro (Always Free) を選択してCreate

SSHを用いてインスタンスにアクセスするのが基本になるのできちんとprivate key, public keyは設定しておく

ダウンロードしたkeyはパーミッションが適切に設定されていないので注意 (たとえば以下のようにする)

```sh
chmod 400 .ssh/ssh-key-2024-06-22
```

:::note info
イメージは一応好みで選んでいるがディスク容量の削減とUbuntuの方が普及率が高くセットアップが容易なことからえらんだ
:::

:::note info
aarch64をえらぶとarm64マシンになるが人気なのでArm Ampere A1は取れなかった
:::

#### セットアップ
sshでログインするとなにもない環境がある
適宜必要なものをインストールして使おう

```sh
ssh ${instance-username}@${your-instance-ip} -i .ssh/ssh-key-2024-06-22
```

```sh
sudo apt update
sudo apt install --no-install-suggests build-essential git nano
```

:::note info
インスタンス立ち上げには少し時間がかかる
インスタンスのページでスペースの確保と起動が確認されてからsshへログインできるようになるまでにも少しかかる
失敗したと思わず気長に待とう (それでも2,3分もかからないだろう)
:::

#### swapfileの設定
strfryのビルドに入るまえにswapの設定をしておく
なぜならフリー枠のインスタンスはメモリーが1Gしかなく普通にやるとメモリーが足りなくなるからである

```sh
sudo dd if=/dev/zero of=/swapfile bs=1M count=1024
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
sudo sysctl vm.swappiness=10
```

以下で確認
```sh
sudo swapon -s
free -h
```

:::note info
これは永続的な設定ではない
しかしビルドが出来ればいいのでこれで十分である
:::

#### strfryのビルド

早速ビルドしていく
strfryのドキュメントを見れば簡単 (時間がかかる)
```sh
sudo apt install --no-install-suggests libyaml-perl libtemplate-perl libregexp-grammars-perl libssl-dev zlib1g-dev liblmdb-dev libflatbuffers-dev libsecp256k1-dev libzstd-dev
git clone https://github.com/hoytech/strfry
cd strfry/
git submodule update --init
make setup-golpe
make
```

#### エンディング
ここまでくれば前半は終了
[後編](https://qiita.com/WhiteCat6142/items/4da60f13445ea82df2ad)へつづく
just_audioで複数音声を同時に再生する時のトラブル

# やりたいこと
Flutterを使って以下のようなアプリを作りたい
この時、**左右にスライドしたときの値（パーセント）によってBGMに新たな音源をリアルタイムに追加したい**

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3804252/1409c8f0-081d-ca4a-bc44-2fec9998bd71.png)

アプリの内容に関して詳しくは[前回記事](https://qiita.com/eteoto/items/fb053ab662fed7bd8d0a)をみて欲しい

# やろうとしたこと
起動時にjust_audioを使って、複数の音源を再生し、値（パーセント）に応じて各音源の音量を0から100に変更した。これでいつ値を変更しても、音源の再生されているタイミングは同じなので各音源がずれずにあたかも値(パーセント)に応じて再生されたように見える。
以下はイメージ図である。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3804252/2cc00ca8-bc35-0636-8fca-44b8c479522e.png)

```Dart:play_audio.dart
import 'package:just_audio/just_audio.dart';


class StartPageState extends State<StartPage> with WidgetsBindingObserver {
  List<AudioPlayer> _players = []; // オーディオプレイヤーのリスト
  late List<String> _audioPaths; // 全てのMP3ファイルのパスを格納するリスト

  Future<void> _setupSession() async {
    final session = await AudioSession.instance;
    await session.configure(AudioSessionConfiguration.speech());
    await _loadAudioFiles(); // 全てのMP3ファイルをロード
    await _playSoundFiles(); // 全てのMP3ファイルを再生
  }

  Future<void> _loadAudioFiles() async {
    _audioPaths = [
      'assets/audio/bgm1.mp3',
      'assets/audio/bgm2.mp3',
      'assets/audio/bgm3.mp3',
      'assets/audio/bgm4.mp3',
      'assets/audio/bgm5.mp3',
    ];

    // 各MP3ファイルに対してAudioPlayerを初期化し、再生可能状態にする
    for (String audioPath in _audioPaths) {
      AudioPlayer player = AudioPlayer();
      await player.setAsset(audioPath);
      await player.setSpeed(1.0);
      await player.setLoopMode(LoopMode.one);
      _players.add(player);
    }
  }

  Future<void> _playSoundFiles() async {
    // 各オーディオプレイヤーの再生を開始する
    await Future.wait(_players.asMap().entries.map((entry) {
      int index = entry.key;
      AudioPlayer player = entry.value;
      double volume = (index == 0) ? 1.0 : 0.0;
      return player.setVolume(volume).then((_) => player.play());
    }));
  }

  void resetBgm() {
    // BGMをリセットする
    _players.asMap().entries.map((entry) {
      int index = entry.key;
      AudioPlayer player = entry.value;
      double volume = (index == 0) ? 1.0 : 0.0;
      player.setVolume(volume);
    });
  }
  ```
  
  
# 問題点(各音源が同時に再生されない)
端末の処理速度によって、そもそも全ての音源を同時に再生することができず、若干ずれてしまう。そのため、値(パーセント)の変更で音量を変えても、最初の時点で同時に再生できていないのでズレた音源が流れてしまう。
これは、毎回ズレの度合いも違ったため調整が不可能…
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3804252/846a7a18-44ee-d34c-2c67-99e25853b28a.png)


# 解決法
解決法といっていいのかわからないが、**最初にAudio0だけ再生して、残りの音源はいつ再生されても違和感のない環境音にする**ことにした。
ドラムやピアノといった**リズムの概念が存在しない鳥の声や風の音などの環境音**にすればどのタイミングで音量が増えても違和感ないだろうということに…

# 教えて…
どなたか複数の音源を完全に同時再生させる方法があれば教えて欲しい…
Qiita-CLIで作ったmdファイルを整理するpart3


# はじめに

Qiita-CLI を使っていると md ファイルが多くなりすぎて管理ができなくなってしまう．
もちろん，後に編集はできるようにしたいのですべて public フォルダにおいておきたい．（md ファイルが public フォルダにないとプレビューがみれない）

そのため，ファイル名を正規化して，ツリー構造を作成することでどのような記事があるかを一目でわかるようにする．

# 前回の記事

https://qiita.com/soranjiro/items/dbd7833190e6e4b48f77


# 自動でファイル名を変更する

前回，ファイル名を変更するスクリプトを作成した．

しかし，それを毎回実行するのは面倒なので，自動で実行するようにしたい！

どうせファイルで書いているなら，git管理をしているということで，github actions で自動実行するようにする．

# github actions で自動実行

github actions は github で提供されている CI/CD ツールである．

今回は，Qiita-CLI で作成した md ファイルを整理するためのスクリプトを自動で実行するようにする．


## 0.ファイル名を管理する`.ipynb`ファイルを作成

ファイル内容は[前回の記事](https://qiita.com/soranjiro/items/dbd7833190e6e4b48f77)を参照

今回は`.ipynb`で作成しています．
理由は特にないです，，

## github actions で実行するスクリプトを作成

まずは，前回作成したスクリプトを github actions で実行するようにする．

以下のファイルを`.github/workflows/run_notebook.yml`として作成する．

```run_notebook.yml
name: Run Genre Notebook and Commit Changes

on:
  push:
    branches:
      - main
      - master
  workflow_dispatch:

jobs:
  run-and-commit-notebook:
    runs-on: ubuntu-latest
    steps:
    - name: リポジトリをチェックアウト
      uses: actions/checkout@v2

    - name: Set up Python
      uses: actions/setup-python@v2
      with:
        python-version: '3.x'

    - name: 依存関係をインストール
      run: |
        python -m pip install --upgrade pip
        pip install jupyter numpy glob2

    - name: Notebookを実行
      run: |
        jupyter nbconvert --to notebook --execute --inplace genre.ipynb

    - name: Commit & Push
      env:
        ACCESS_TOKEN: ${{ secrets.PERSONAL_ACCESS_TOKEN }}
      run: |
        git config user.name github-actions
        git config user.email github-actions@github.com
        git add -A .
        git commit -m "update file name"
        git -c http.extraheader="AUTHORIZATION: bearer ${ACCESS_TOKEN}" push
```


## github secrets にアクセストークンを登録

こちらの記事を参考に github secrets にアクセストークンを登録する．

https://qiita.com/soranjiro/items/3909b8e0598c01cac5e7
githubのアクセストークンを設定


# githubのアクセストークンを設定

github actionsを用いて自動的にファイルを修正してもらいたい時などがあります．

その際に，自分のリポジトリの情報を取得するために，githubのtokenを設定する必要があります．

今回はそのやり方について詳細に説明をします．


### 1. githubのtokenを生成

:::note warn
自分のアカウントのリポジトリの情報を取得するために，githubのtokenを生成します．
これをすることで，自分のプライベートリポジトリの情報も取得できるようになります．
:::

1. githubの右上のアイコンをクリックして，`Settings`をクリックします．
2. 左のメニューから`Developer settings`をクリックします．
3. 左のメニューから`Personal access tokens`をクリックします．

![スクリーンショット 2024-06-08 1.38.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3670528/952a8f59-d21b-c44c-317f-d407d721bdcf.png)

4\. `Generate new token`をクリックします．

:::note warn
Fine-granted tokensというbeta版のものもありますが，今回は簡単に`Tokens (classic)`を使用します．
:::

5\. tokenの名前を入力し，`repo`にチェックを入れて，`Generate token`をクリックします．

![スクリーンショット 2024-06-08 1.06.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3670528/58f360e2-7c79-98a8-4e3a-0e81c8572ead.png)

6\. tokenが生成されるので，これをコピーしておきます．

:::note warn
このtokenは一度しか表示されないので，必ずコピーしておきましょう！
:::

### 2. githubのtokenを設定する

1. 自分のアカウント名のリポジトリの`Settings`から`Secrets and variables`の`actions`を開く

![スクリーンショット 2024-06-08 1.46.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3670528/53d17030-c68b-d0ee-3a65-dc194cfcf9d6.png)

2\. `Repository secrets`の`New repository secret`をクリックします．

![New repository secret](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3670528/1d722007-6330-3850-cf32-6dc63b02fe09.png)

3\. `Name`に`PERSONAL_ACCESS_TOKEN`，`Value`に先ほどコピーしたtokenを入力し，`Add secret`をクリックします．

![PERSONAL_ACCESS_TOKENの設定](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3670528/f57027fc-5485-ac5a-9bf4-6549e34f13c3.png)

4\. `Settings`の`Actions`の`General`の一番下に，`Workflow permissions`とあるので，それの`Read and write permissions`を選択します．

![スクリーンショット 2024-06-08 1.47.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3670528/483098d0-7e65-cdaa-12aa-1bfb43bbb162.png)

:::note info
これによってgithub actionsが自分のリポジトリにcommit,pushできるようになります．
:::

以上で，githubのtokenの設定が完了しました．

### 3. github actionsでの利用

せっかくなので，github actionsでの利用方法も記載しておきます．

`.github/workflows/auto_commit.yml`として作成します．

```auto_commit.yml
name: commit and push

on:
  push:
    branches:
      - main
      - master
  workflow_dispatch:

jobs:
  run-and-commit-notebook:
    runs-on: ubuntu-latest
    steps:
    - name: リポジトリをチェックアウト
      uses: actions/checkout@v2

    ## ここにスクリプトを追加

    - name: Commit & Push
      env:
        ACCESS_TOKEN: ${{ secrets.PERSONAL_ACCESS_TOKEN }}
      run: |
        git config user.name github-actions
        git config user.email github-actions@github.com
        git add -A .
        git commit -m "update file name"
        git -c http.extraheader="AUTHORIZATION: bearer ${ACCESS_TOKEN}" push
```

user.nameとuser.emailは，現在githubという仮の名前を設定しています．
自分のアカウントでコミットを行なって欲しい場合は，適宜変更してください．
カラム毎の照合順序の違いによる MySQL テーブル変更エラーと、ロールバックできない不整合

## カラム毎の照合順序の違いによるテーブル変更エラー

MySQL では、データベース・テーブル・カラム単位のそれぞれで照合順序を指定できます。
照合順序の詳しい説明は省きますが、ざっくり言うと、文字を並び替えたり比較する時の優先順位を決めるルールのことです。

この「カラム単位」で指定できるという点で、過去問題が発生したことがありました。

ある`samples`テーブルにおける`temp_id`カラムに外部キー制約を追加しようとしました。
```
ALTER TABLE `samples` ADD CONSTRAINT `samples_ibfk_1` FOREIGN KEY `temp_id` REFERENCES temps(id);
```

すると、下記のようなエラーが発生したのです。
```
Referencing column 'temp_id' and referenced column 'id' in foreign key constraint 'samples_ibfk_1' are incompatible.
```

これは、なんと`samples.temp_id`と`temps.id`のカラム照合順序が異なっていることにより発生したのです…。

## ロールバックできない問題

そして、上記と付随して起こった問題があります。

元々複数テーブル・カラムにおいて外部キー制約を追加しようとしており、一連の処理を一つの
マイグレーションファイルにまとめていました。

しかし途中のテーブル変更処理が上記問題によりコケてしまったがために、テーブルが中途半端な状態で更新されるということが起こりました。

そして、この`ALTER TABLE`処理は、`TRANSACTION`による`ROLLBACK`が効かないのです。
そのため、途中でマイグレーション処理がコケた場合は、整合性を考慮しながら SQL を実行し、適切な状態になるよう修正しなければなりませんでした。

参考：https://www.zawatech.com/post?p=127

## 問題の解消

上記問題を解消するために、下記のようにカラム照合順序を修正し、カラム間の不一致を無くしました。
```
ALTER TABLE temps MODIFY COLUMN id VARCHAR(36) NOT NULL COLLATE 'utf8mb4_bin' COMMENT '仮の ID',
```

その後、元々実行したかった外部キー制約の追加をして対応完了です。

おしまい。
関数のカリー化 is 何

関数を引数に取る関数を定義することができる関数を高階関数と呼び、Go, JavaScript, Python などのプログラミング言語では高階関数をサポートしています。

この機能を使うことで、関数を引数に取る関数を定義することができます。また、関数を返す関数を定義することもできます。

何を言っているかわかりづらくなってきたのでGoで具体的な例を見てみましょう。

## 高階関数

```go
func highOrderFunc(f func(int) int) func(int) int {
	return f
}
```

この関数のように関数を引数に取ることや、関数を返すことができます。

## カリー化

カリー化とは、関数を部分適用することで新しい関数を作ることです。

もう少し詳細に説明すると複数の引数を取る関数を、一つの引数を取る関数の連続で表現することです。

`f(x, y)` という関数をカリー化すると、`f(x)(y)` という形になります。

この状態をGoで表現してみましょう。

```go
func curriedAdd(x int) func(int) int {
	return func(y int) int {
		return x + y
	}
}

func main() {
	// カリー化のサンプル
	c1 := curriedAdd(1)
	fmt.Println(c1(2)) // 3
}

```

関数を引数に取る関数を定義することで、カリー化された関数を作ることができます。

`currriedAdd(1)` という関数を呼び出すことで、`x` に `1` が適用された関数が返され、その関数に引数 `2` を適用することで `3` が返されます。

このように関数が取る一部の引数をあらかじめ固定して残りの引数を後から適用することで、新しい関数を作ることができ、この手法を部分適用と呼びます。

## まとめ

関数のカリー化は関数を部分適用することで新しい関数を作る手法で、共通化された処理を関数に閉じ込めることで、コードの再利用性を高めることができます。
Shareable Projects in Claude: 効率的なチームコラボレーションを実現

## はじめに
Claudeは、チャットをプロジェクトに整理し、共有可能な新機能を提供しています。この記事では、その具体的な使い方と利便性について紹介します。詳細なデモは、公式のYouTube動画をご覧ください。

## プロジェクト機能の概要
Claudeのプロジェクト機能により、次のことが可能になります：
- **内部知識の統合**：スタイルガイド、コードベース、インタビュートランスクリプトなどの内部資料をプロジェクトに追加。
- **大容量コンテキスト**：200Kトークン（約500ページの本相当）のコンテキストウィンドウを持つ。
- **共有とコラボレーション**：チームメンバーとプロジェクトを共有し、共同作業が可能。

## 実際の使用例
新入社員のオンボーディングを例に、以下の手順でプロジェクトを作成します：
1. プロジェクトを作成し、「New hire onboarding」と命名。
2. チームチャーター、全員会議のメモ、業務慣行などのドキュメントを追加。
3. Claudeに組織図の作成を依頼し、プロジェクトに保存。
4. プロジェクトリンクを新しいチームメンバーにメールで送信し、チャットを開始。

## 公式デモ動画
具体的な操作手順は、以下の公式YouTube動画で確認できます。

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

## まとめ
Claudeのプロジェクト機能は、効率的なチームコラボレーションを実現するための強力なツールです。ProおよびTeamプランで利用可能なこの機能を活用して、チームの生産性を向上させましょう。
エンジニア必見！知っておきたい、ショートカット

マウスを使ったら負け！キーボード、ショートカットキーだけでいかにやるか、これを考え抜かないと置いていかれる。

　　　　　　　　　　　　　　　＜全ソフトウェア共通＞

コピー 
cmd + C

ペースト
cmd + V

切り取り
cmd + X

全選択
cmd + A

新規ファイル
cmd + N

保存
cmd + S

名前をつけて保存
cmd + shift + S

ファイルを開く
cmd + O

新規ウインドウ
cmd + shift + N

アプリケーションの切り替え
cmd + Tab

アプリケーションを閉じる
cmd + Q

spotlight/ファイルを指定、（Alred ５を作動）
cmd + space

文字を大きくする
cmd + "+"

文字を小さくする
cmd + "-"

行の先頭へ移動
cmd + ←

行の語尾に移動
cmd + →

ページの最前列へ移動
cmd + ↑

ページの最後尾へ移動
cmd + ↓

単語の先頭へ移動　 プログラミングVScodeでよく使用されます。
opt + ←

単語の語尾へ移動
opt + →

部分選択
shift + ↑/→/↓/←  押した回数選択されます

行を選択
cmd + shift + ↑/→/↓/← 押した回数選択されます

単語を選択する
opt + shift + ←/→

１つ前の状態に戻す
cmd + Z

１つ後の状態に戻す
cmd + shift + Z

キャンセル　間違えてfinderの保存画面へ移動した場合など
esc　ボタン

finderのファイル名の名称を変更
選択中でEnterキー

フォーカス（進む）　フォーム画面など
Tab　ボタン

チェック　
space

フォーカス（戻る）
tab + shift 

ページ内検索　Webページ、VScode内で見つけたい単語など
cmd + F

ページ内検索でフォーカス（進む）　検索にヒットした単語のみ対象
cmd + F + Enter

ページ内検索でフォーカス（戻る）　検索にヒットした単語のみ対象

履歴ページを開く
cmd + Y

設定画面を開く 開いているページの設定を開くことができます。
cmd + ,

新規タブ
cmd + T

タブを閉じる
cmd + W

タブの切り替え（戻る）
control + shift + Tab

タブの切り替え（進む）
control + Tab

リロード（再読み込み）　最新の情報を取得する
cmd + R

スーパーリロード
cmd + shift + R

プリントアウト Webページで使用することが多いです。
cmd + P

ウインドウを最小化する
cmd + M

不可視ファイルを表示する　開発向け
cmd + shift + .

隠しファイル（hidden file）とは、ストレージ(外部記憶装置）内に作成・保存されたファイルのうち、ファイルシステムなどの機能によって一覧に表示しないよう設定されたファイルのこと。

スクリーンショット撮影
cmd + shift + 3/4/5
3:フル画面撮影
4:部分選択し撮影
５：スクリーンショットのツールバーを使って撮影する


　　　　　　　　　　　　　　　　　　　＜VScode＞

インデント（追加） コード内の行頭をスペースやタブでずらすこと
Tab

インデント（戻す）
shift + Tab

コメントアウト 
cmd + /　　　もう一度押すと元に戻る
他の人にコードの意図を伝えるだけでなく、特定のコードを一時的に無効化することでバグの発見にもつながる重要な機能です
選択した状態でコメンアウトを行うこともできる。

複数選択 選択しても前に選択したものは残る。複数箇所選択肢、修正、削除することができる。
opt + click

選択したワードをページ内と同じワードを選択 上から順番に選択される
cmd + D

選択する項目をスキップ
cmd + K

サイドバーの表示、非表示　開かれているファイルを表示、非表示
cmd + B

クイックオープン 開かれていないファイルでも表示されます。
cmd + P

ファイル内検索
cmd + F

ファイル検索
cmd + shift + H

プロジェクト内置換 全て変更されるので確証ある時のみ実行しましょう。
cmd + shift + H

フォーマット整形 インデントが揃っていない時など
shift + option + F

コマンドライン ターミナルなどを表示させる
cmd + J

別タブで開く
cmd + click

　　　　　　　　　　　　　　　　＜コマンドライン＞

過去のコマンドを呼び出し
↑/↓
複数回押すと遡ることができます。

先頭に移動
cmd + A

末尾に移動
cmd + E

行を削除
cmd + U

ログのクリア エラーなどいらない情報のログを削除したい場合
cmd + I

パスをコピー
cd ディレクトリーをドラッグ
C_TS422_2021 SAP Certified Application Associate SAP S/4HANA Production Planning and Manufacturing対策（18/100）

【18日目】
トピック 3：SAPS/4HANAのマスタデータ（7/22）

≪問題18≫
在庫、入出庫予定、または購買伝票が存在する場合、以下のどの状況下で品目の品目タイプを変更できますか。
（２つ選択）
□同じロット管理レベルが使用されること。
□同じ基本数量単位が使用されること。
□数量と金額の更新が同じレベルであること。
□同じ勘定カテゴリが使用されること。

≪解答≫
□同じロット管理レベルが使用されること。
□同じ基本数量単位が使用されること。
■数量と金額の更新が同じレベルであること。
■同じ勘定カテゴリが使用されること。

◆品目を登録した後に品目タイプを変更する必要が生じる場合がありますが、取引がすでに転記されている場合には問題が発生することがあります。
◆そのため、品目タイプの変更が可能かどうかをシステムがチェックします。
（1）在庫、入出庫予定、購買伝票が存在しない場合、制限なしで品目タイプを変更することができます。
（2）在庫、入出庫予定、購買伝票が存在する場合、以下の条件が満たされる場合にのみ品目タイプを変更することができます。
 - 同じ勘定カテゴリが使用されること。
 - 同じ数量および金額の更新がされること。
メンバーから相談されないときは、メンバーに相談する

## はじめに

◆この記事は何？
相談を引き出すTipsを紹介する記事です

◆対象は？
チームメンバーから相談が少ないと悩むリーダー

## 先に結論
- メンバーから相談が少ないときは、リーダーからメンバーに相談する
- 悪いことを共有する
- 情報をオープンにする、やむを経ず非公開にするときは非公開にする理由を伝える

## 相談が少ないときはリーダーから話す

メンバーから相談されないとき、そもそも相談して良いかをメンバーがわかっていないことがあります。

そこで、リーダーからメンバーに先に相談することで、相談の方法を示すと同時に相談しても大丈夫であることを間接的に示せます。。

特に効果的なのは、悪いことの共有と相談です。
メンバーの目線では、「悪いことをチームで話し合える」と相談のハードルが下がります。

## 情報の透明性

相談を引き出すためには、情報の透明性が重要です。

チームリーダーが情報を隠すと、メンバーも情報を隠して良いと無意識的に判断してしまう可能性があります。
これが積み重なると、情報を隠す文化が意図せず形成されてしまうかもしれません。

一方で、非公開にせざるを得ない情報もあります。
そのときは、①クローズドな情報があること②なぜクローズドなのか、存在と理由を説明すると効果的です。

例えば、「メンバー層が参加していないリーダー層だけの会議がある」「お金などセンシティブな情報を扱うため、参加メンバーを限定している」などを伝えます。

リーダーがクローズドな情報について概要を共有することで、メンバーは安心できます。
その結果、メンバー自身も情報を隠すことが減り、積極的に情報を共有できるようになると思います。

## おわりに

この記事では、メンバーから相談を引き出すTipsを紹介しました。

皆様のチームの参考になれば幸いです。
VSCode探していた一括選択コマンドを見つけた

## はじめに
VSCodeを使っていて、一気に同じ単語を選択したいなってときがありましたが、Ctrl + Fで検索したり、Ctrl + Dで一つ一つ選択していったりしてました。
ほしいコマンドはこれじゃないんだけどなって思いながら、過ごすある日・・・とうとう念願のコマンドを見つけました。

## 一括選択コマンド
**`Ctrl + Shift + L`**

探し求めていたコマンドがありました。

一つの単語を選択して、
**`Ctrl + Shift + L`**
を入力すると

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1328154/da0635f3-4797-bdab-7d77-aff5541f9633.png)

これで一気に変更できます。
選択して、`Ctrl + Shift + L`入力後の一括選択できるっていうのはすっきりします。

## 終わりに
よかったら使ってみてください
LaravelでCSVファイルをインポート（maatwebsite/excel）

LaravelでCSVファイルのインポート機能を作成しようと思い、maatwebsite/excelというライブラリを使ってみました。
メモとして使用例を残しておきます。

## インストール

公式に則って行います。
https://docs.laravel-excel.com/3.1/getting-started/installation.html

```
composer require maatwebsite/excel
```
```
php artisan vendor:publish --provider="Maatwebsite\Excel\ExcelServiceProvider" --tag=config
```

`config/excel.php`というファイルが作成されます。

## 前提

今回アップロードしたいCSVのサンプル
```
企業名,郵便番号,住所,電話番号,代表者名,担当者名,備考
テスト02株式会社,2203456,埼玉県上尾市井戸木,090-4736-0924,佐藤,中島,テストです
```
上記の1行目をタイトルとして認識させ、2行目以降をデータとして挿入したいという要件です。

## Importクラスの作成
app/Imports/CompaniesImport.phpを作成

```php
namespace App\Imports;

use App\Models\Company;
use Maatwebsite\Excel\Concerns\ToModel;
use Maatwebsite\Excel\Concerns\WithHeadingRow;

class CompaniesImport implements ToModel, WithHeadingRow
{
    public function model(array $row)
    {
        return new Company([
            'name' => $row['企業名'],
            'post_code' => $row['郵便番号'],
            'address' => $row['住所'],
            'tel' => $row['電話番号'],
            'ceo_name' => $row['代表者名'],
            'responsible_person_name' => $row['担当者名'],
            'note' => $row['備考'],
        ]);
    }
}
```
`WithHeadingRow`を使用すると、最初の行をタイトルとして認識してくれるようです。
他にも色々使い方があるようなので、公式をご確認ください。
https://docs.laravel-excel.com/3.1/imports/heading-row.html

## コントローラーの作成
app/Http/Controllers/CompanyController.php

```php
// メソッドだけ抜き取り

public function import(Request $request)
{
    $file = $request->file('file');
    Excel::import(new CompaniesImport, $file);
    return redirect()
        ->route('company.index')
        ->with('message', 'データが正常にインポートされました');
}
```

## ルーティング
web.php

```php
Route::post('/company/import', [CompanyController::class, 'import'])->name('company.import');
```

## フロント（Blade）
resources/views/company/create.blade.php

```html
<form action="{{ route('company.import') }}" method="post" enctype="multipart/form-data" class="flex flex-col md:flex-row items-center gap-2 justify-end w-full md:w-3/4 lg:w-2/5">
    @csrf
    <div class="w-full flex-1">
        <input type="file" name="file" id="file" accept=".csv,.xlsx,.xls" class="w-full text-gray-500 font-medium text-sm bg-gray-100 file:cursor-pointer cursor-pointer file:border-0 file:py-2 file:px-4 file:mr-4 file:bg-gray-800 file:hover:bg-gray-700 file:text-white rounded">
    </div>
    <div class="w-full md:w-44 flex gap-2 justify-end">
        <button type="submit" class="focus:ring-4 focus:ring-blue-300 font-medium rounded-lg text-sm px-3 py-1.5 border border-gray-300 hover:opacity-80">アップロード</button>
        <button type="button" id="clearButton" class="focus:ring-4 focus:ring-blue-300 font-medium rounded-lg text-sm px-3 py-1.5 border border-gray-300 hover:opacity-80">クリア</button>
    </div>
</form>
```

ファイル送信の際には、formタグに`enctype="multipart/form-data"`を入れる必要があるので忘れずに。
2つ目のボタン（クリアボタン）は、ファイル選択したけど「やっぱやめた」というとき用のボタンです。
これはJavaScriptで実装しているのですが、今回の内容とはずれるので詳細は割愛します。

最後にImportクラスの`WithHeadingRow`で最初の行のタイトルが日本語だとうまくいかなったのですが、`config/excel.php`の`Heading Row Formatter`の部分を`none`にするとうまくいきました。

```php
'heading_row'  => [
    'formatter' => 'none',
],
```

以上、誰かの参考になれれば幸いです。
C_TS4FI_2021 SAP Certified Associate - SAP S/4HANA 2021 for Financial Accounting対策（5/100）

【5日目】
トピック 1：組織割当およびプロセス統合（5/15）

≪問題5≫
非SAPシステムとのインタフェースを介して得意先請求書を転記する必要があります。ソースシステムの伝票番号と一致する特定の伝票番号範囲を参照して新しい伝票タイプを定義します。伝票番号範囲はどのように定義しますか。
正しい答えを選択してください。
□内部番号割当または外部番号割当を使用できる。
□内部番号割当または外部番号割当を使用できるが、番号が連続している必要がある。
□内部番号割当を使用する必要がある。
□外部番号割当を使用する必要がある。

≪解答≫
□内部番号割当または外部番号割当を使用できる。
□内部番号割当または外部番号割当を使用できるが、番号が連続している必要がある。
□内部番号割当を使用する必要がある。
■外部番号割当を使用する必要がある。

≪解説≫
◆番号割当には、以下の2種類があります。
（1）内部番号割当
このタイプの番号割当では、番号範囲から最後に使用された伝票番号が現在番号項目に保存されます。そして、現在番号の次の番号が次の伝票番号として割り当てられます。
（2）外部番号割当
このタイプの番号割当では、ユーザーがオリジナル伝票の番号を手動で入力するか、または別のシステムから自動的に番号が転送されます。これらの番号は連続していないため、現在番号は保存されません。外部番号割当には英数字を使用することが可能です。
◆別のシステムで発番された伝票番号を転送するためには、外部番号割当が使用されます。
AWS上にActiveDirectoryを構築したらEC2やVPCの一覧が見えなくなったぞ!?

# 状況
オンプレのADをクラウドに移行したらEC2の一覧画面でずっと読込中→タイムアウトになっちゃった…

# 結論
Active DirectoryのDNSサーバのフォワーダにRoute53 Resolverが入っていませんか？(VPCセグメントの先頭+2のIPアドレス)
CloudWatchをプライベートサブネットで使うためにVPCエンドポイントを作っていませんか？
VPCエンドポイントにCloudWatchがあるとec2.*.amazonaws.comに対しての名前解決がVPCセグメント内に行われ、VPCセグメント外からアクセスしようとすると応答できないので表示できなくなります。

# 対策
1. ADのフォワーダに登録されたRoute53 Resolverを削除
2. Route53 ResolverにADのドメインに対しての問い合わせルールを登録(ADのドメインに対してはADのEC2に対してDo53で転送)
3. VPC内のEC2でAD以外のマシンはADに向けていたDNS設定を全てRoute53 Resolverに向け直す
(オンプレやVPC外のEC2等はそのままADに向け続けてOK)
:::note warn
Route53 Resolverに向ける場合、絶対にセカンダリは空白にするか、AD以外にしてください。
セカンダリにADを向けると何らかの理由でセカンダリにリクエストが飛んだ場合にVPCエンドポイントの名前解決ができなくなる場合があります。
:::


# 参考情報
https://repost.aws/questions/QUp-Nc7dXJR3CAT3C_mxo76w/ec2-us-east-1-amazonaws-com-endpoint-resolving-to-private-ip-address
Filter関数とリスト内包表記の動作速度の違い

やっぱり基礎が大事ということで、基礎本を読んでいたところ
「高階関数のmap関数やfilter関数を使うより、リスト内包を使った方が速い」との事。

どのぐらい違うか試してみた。

### ランダムに大量の配列を作成
```Python
import random

# ランダムに配列を作成
array = [random.randint(0, 10000000) for _ in range(10000000)]
```

### filter()を使って計測
処理は偶数値のみ抽出
```Python
import time

start = time.time()
list(filter(lambda n: n % 2 == 0, array))
end = time.time()
filtertime = end - start
print("filter time: ", filtertime)

> filter time:  0.48375964164733887
```

### リスト内包を使って計測
```Python
import time

start = time.time()
[n for n in array if n % 2 == 0]
end = time.time()
connotationtime = end - start
print("list time: ", connotationtime)

> list time:  0.35934996604919434
```

### 結果
```Python
filter time:  0.48375964164733887
list time:  0.35934996604919434
Time difference : 0.12440967559814453
```
約 <font color="Red">1.35倍</font>ほど早くなっていた。
※map関数を使用した場合もほぼ同じぐらいの差があった。

filter関数はlambdaを呼び出して処理を行っている為どうも遅いらしい。
lambdaではなく関数を使用しても結果同じことなので、リスト内包を使用したほうが効率的!!
【Ruby】privateとprotectedの違い

# 初めに
rubyのclassにおけるprotectedが理解できず調べていたのですが、分からなかった理由はprivateの理解を誤っていたからでした。
今回は思考の整理のため、privateメソッドとprotectedメソッドの違いについてまとめてみます。
# 共通点
・クラス内かサブクラス内でのみ呼び出せる点（他の言語ではprivateはサブクラス内では呼び出せない場合もあるみたいですが、Rubyではそうではないです）
・レシーバがselfの場合、privateメソッドでもprotectedメソッドでも挙動は変わらない。
bメソッドの中でaメソッドを呼び出している部分は、省略されているだけでその前にselfがあります。
```

class Parent
  def initialize(name)
    @name = name
  end

  def b
    a
  end

  protected #privateでも同じ結果が出ます

  def a
    puts "a"
  end
end

parent = Parent.new("Alice")

parent.b
parent.a #クラス外から呼んでいるのでエラー


```

# 相違点
privateメソッドはレシーバがselfの場合でしか呼び出すことができないみたいです（selfは省略してもしなくてもいい）。
だから、「self.メソッド名」ならいけるが、「self以外のレシーバ.メソッド名」とかなら無理です。
逆に、protectedの場合は、レシーバがself以外であっても、そのクラスかサブクラスのインスタンスであれば動きます。それが1番の違いです。
例えば下記のコードの場合、protectedなのでエラーは出ませんがprivateならエラーがでます。
```


class Parent
  def initialize(name)
    @name = name
  end

  def compare_names(other)
    if self.protected_method == other.protected_method #ここでotherからprotectedメソッドを呼んでいるが、もしprivateだったらエラーが出る
      puts "Names are the same"
    else
      puts "Names are different"
    end
  end

  protected

  def protected_method
    @name
  end
end

class Child < Parent
end

parent = Parent.new("Alice")
child = Child.new("Alice")
another_parent = Parent.new("Bob")

parent.compare_names(child)          # privateならエラー
parent.compare_names(another_parent) # privateならエラー
parent.protected_method              # クラス外から呼んでいるのでprivate,protected共にエラー


```

# 終わりに
大雑把な説明ですいません。興味がある方は色々調べてみてください。
以上です。ありがとうございました。
azure-search-openai-demo: azd down 後に、再度 up するときは、*.md5 を消すことで、data ファイルがアップロードされるよ

# 背景

以下の Sample を再デプロイしようとしたら、data フォルダの index 化がされなくて躓いた備忘録

https://github.com/Azure-Samples/azure-search-openai-demo/tree/main

# 結論

## 対処法

- *.md5 を全部消す


## 原因

- upload ファイルの変化を hash (.md5) で記録している
- provision 時に、同一となる .md5 が存在していると、変更点無しと判断され、Index 生成されない
    - {元のファイル名}.md5


## ドキュメント

分かってから探したら、以下に記述してあった :sweat_smile: 

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/c5e0c3cb-b379-eb2f-7fb6-a87fbf4e2be1.png)

# あとがき

結局ドキュメントを全部読んでいなかった為の躓きです

とはいえ、躓いた程度なんで、よしとしよう
【ポエム】レビューを居酒屋にしないために

こちらのエントリを拝見して気づいたのですが、「レビュー」という概念が近いうちに消えるのでは？と思ったので書いてみたいと思います。

https://qiita.com/ynmc0214/items/068afccca9693baf298d#comment-92c3253b064b88baf6eb

# よくあるシーン
:::note warn
・「レビューは会議を設定して下さい」
・「いきなり机上レビューは不可です」
:::

このような人が組織にいたら黄信号かもしれません。

# なぜか
・同期、非同期コミュニケーションの使い分けに興味がない
・チームの効率化に興味がない
・つまり進歩や成長に興味がない

と、極論ぽいですがそういうことになるかと思います。
進歩や成長に興味がない人よりは、興味がある人と一緒に仕事をしたいですよね。（私だけでしたらすみません）

# レビュー居酒屋とはなにか？
・仕事を飲み屋のような「安らぎのひととき」にしてしまうことです。
・居酒屋で政治などを熱く語っている方を見かけます。あれに近いものだと思います。

# 仕事というよりは「空間」「時間」
・お酒は議論というより、その場の空気を楽しむためのものですよね。
・つまり仕事への貢献や生産性というよりは、「その空間」が大事なのですね。
・キャバクラやテレクラにも近いかもしれません。
　↑ものすごい懐かしい単語がでてきて自分でもびっくりしました。

# 机上レビューではそれができない
・文章を読んで添削して・・・という非同期コミュニケーションではそれができません。
・同じ時間を共有する、ということが（本人にとって）大事になってきます。

# なぜ居酒屋にしてしまうのか
・実際の効率とか成果はともあれ、口で指摘すると「働いてる感」「仕事できる人」感がある
・電話とおなじで会議してると時間が早くたつ

# リモートワークという環境のせいもある？
・奥さんや子供に聞こえるように声を出して論を述べることで、働いているパパを見せることができます。
・あるいは同僚へのプレゼンス。
・仕事の私物化といえばそれまでですが・・・
・それらをふまえて総合的に「居酒屋」と呼んでおります。

# 居酒屋化してくる兆候
:::note alert
・「毎週この時間に〇時間のレビュー枠をとって下さい」（長めなのがポイント）
・「いま時間空いたのでレビューを前倒しして下さい」（＝今飲みたい気分です）（＝マスターいま飲める？）
・令和の時代に「～くん」呼び
・呼び捨て、敬語なし
:::

このあたりはレッドフラグです。
もし定常化しているのであれば、組織全体が問題を抱えています。

# なにがまずいのか
・会話は記録に残しづらく、内容が蒸発してしまうケースが多いです。
・メモを取ったり、書き起こしたりすると、それだけでレビューの数倍の時間がかかります。
・チームの効率性と考えると、無駄が多くなってしまいます。
・つまり居酒屋レビューとは、チームや組織の犠牲の上にレビュアーだけが気持ちよい世界になりがちです。

# 「レビュー」は一方通行
・伝統的なレビューはキャッチボールでいえば1時間かけて1往復するイメージです。
・「ボールは丁寧に息でハーハーして磨いてから投げること！」みたいなことも。
・「私に対して時間をかけて」「場を設けて」というお客さんみたいな一方通行感があると思います。
・お給料をもらってお客さんになっている、ということだと思いますが。

:::note
・このマインドが上に書いた、進歩や成長への興味ということと関わっていそうです。
:::

# 「レビュー」は自分が正解になれる
・指摘している側は、自分が正解者になれるというのもあると思います。
・プログラミングやビジネスプロセスでは、一つの正解しかないことも多いです。
・そんななか、答えのない分野で自分の発言が（その空間においては）正解になれるので、一服の清涼剤に。
・同じことは文章添削やWebデザイン添削などでもいえますね。

# 「レビュー」という概念が消えるかもしれない？
・その背景には、もちろんAIがあります。
・AIがすぐれた添削や指摘をしてくれるのはご周知のとおりです。
・そこには上に述べた、立場や家庭といった個人事情によるバイアスもありません。
・均質な結果を提供してくれます。

# AI時代にはレビューという形をとらない？
・AIは全然使いこなしてないのですが、プロンプトエンジニア？というのが最近聞きますね。
・プロンプトつまり対話・議論のキャッチボールによる成果の醸成みたいなかんじなのかなと。

# つまり
・キャッチボールの例でいうと、AIを使って数分で数往復したほうが良い結果になるのは当然ではないでしょうか。
・以上、レビューという概念が消えるのでは、というポエムでした。

# 例外はあります
・「これだけ活動時間をかけました」を報告して時間工数で稼ぐビジネスは元々そういうモデルです。
・従業員が進化や成長すると儲からなくなってしまいます。こちらは別枠でお考え下さい。

# 居酒屋にもメリットはある？
:::note
・2つあると思います。健康効果と感情効果。
・口に出すことでエクササイズになりますので、文字では不可能な健康効果があります。
・そして感情の交換によるモチベーションUP。
:::
・文字だけの添削を何往復もするよりは、早いし瞬発力もあるといえます。
・けっきょくはバランスではないでしょうか。

# 自分だったらどうする
・毎日30分程度、できれば朝、レビューという形ではなくブレストの時間を作りますね。
・役職に関係なく一人一人が意見を順番に述べていくというものです。
・そして他人の意見に意見しないといったルールです（たしか）。
・朝の運動や価値観の共有により、一日のチームの効果が上がれば、って感じでしょうか。

# まとめ
・結局は仕事をしているのか、仕事っぽく運動や飲酒をしているか、の2択になるのかと思います。
・ただ、仕事だけしてたら疲れてしまうのも人間。それは分かります。
・運動が体に良いのはもちろんですし、少量の酒も百薬の長といわれます。
・依存症にならない程度にうまく使いこなせば、組織全体としてもメリットはあると思います。
R.Swift使い方とエラー対応方法について忘れないように

R.Swiftの導入と使い方で詰まることが多かったので、参考にした記事と共に備忘録として書きます。

## 導入方法と使い方
- https://mama-lifestyle.jp/swift-dev-jp/rswift/
Localizable.stringsファイルを使用した文字列撲滅方法について、ファイルの作り方から、使用方法まで具体的に書かれている。
- https://qiita.com/m_rn/items/7c73d77e07ee7bd484cb
R.Swiftの導入方法について具体的に書かれている。
この記事で画像と色はAssetsに追加すれば使えるんだなと分かりました。

## R.SWiftの利点と仕組み
- https://dev.classmethod.jp/articles/r-swift-introduction/
上記の記事から引用します。下記の通り記載されています。
```markdown
プロジェクトがビルドされるたびに、
このR.generated.swiftファイルの中にリソースファイルへのアクセスが構造体として定義されて、
それによって型指定によるリソースへのアクセスが可能になるという仕組みのようです。
```
つまり、新たにimageや文字列追加したら都度ビルドです。
ビルドしないと使えません！
R. と打って予測変換に追加した項目が表示されない時はビルド忘れの可能性が高いです。


## エラー時の対応方法
- https://qiita.com/celcior0913/items/fb8007ca6a899b7bd862
Localizable.stringsの書き方ミスによるエラー。
末尾セミコロンつけ忘れに注意です。
図のエラーは"ヨーロッパ"末尾セミコロンつけ忘れが原因。
```swift
validation failed: Couldn't parse property list because the input data was in an invalid format
```
![スクリーンショット 2024-06-26 21.18.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1015674/aee5d03f-3af3-c468-c9a3-2173595758fc.png)

- https://qiita.com/kaito-seita/items/97c656b2daf2c0e1b4be
追加してビルドしたのにエラーが残っている。
そんな時は Product > Clean Build Folder... をしてから再度ビルドをするとエラーが消え、使えるようになります。

- https://ios-docs.dev/missing-package-product/
`Missing Package product RSwiftLibrary`
File → Packages → Reset Package Cachesでなおりました。
Jest が firebase のライブラリに対して Cannot find module ... と出してくる際の対処法

# 何があったか

あるTypescriptのテストでfirebaseのライブラリを使っていると、Jestでテストを回したときに以下のようなエラーが出る。

```
  ● Test suite failed to run

    Cannot find module 'firebase-admin/app-check' from 'node_modules/firebase-functions/lib/common/providers/https.js'

    Require stack:
      node_modules/firebase-functions/lib/common/providers/https.js
      node_modules/firebase-functions/lib/common/providers/identity.js
      node_modules/firebase-functions/lib/v1/providers/auth.js
      node_modules/firebase-functions/lib/v1/index.js
      ...

      at Resolver.resolveModule (node_modules/jest-resolve/build/resolver.js:324:11)
      at Object.<anonymous> (node_modules/firebase-functions/lib/common/providers/https.js:29:21)

Test Suites: 1 failed, 1 total
Tests:       0 total
Snapshots:   0 total
Time:        3.248 s
```

# 解決方法
jest.config.jsにmoduleNameMapperを設定してあげるとpathの依存が解決する。

```functions/jest.config.js
moduleNameMapper: {
    "^firebase-admin/(.*)$": "<rootDir>/node_modules/firebase-admin/lib/$1/index.js",
  },
```

# 参考記事
https://github.com/firebase/firebase-admin-node/issues/1465#issuecomment-1152297856
Hunter×Hunter キャラクターリスト

## はじめまして
オランダでコンピューターサイエンスのブートキャンプに参加したのをきっかけにエンジニアに興味を持ち、現在は独学でRuby on Railsの学習しています。
パーフェクトRuby on Railsという参考書を一通り学習したので、大好きなHunter×Hunterのキャラクターリストを作りました。

サービスURL↓

https://evening-oasis-56233-285d435ecde1.herokuapp.com/

## キャラクターリストの紹介
### トップページ
今まで登場したキャラクターの一覧が表示される

![スクリーンショット 2024-06-26 20.46.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3733846/3aa66941-8fea-a4df-5256-89cb2fd35dfa.png)

画像をクリックすると各キャラクターの詳細が表示される
![スクリーンショット 2024-06-26 21.04.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3733846/0d4b8759-458c-f1d8-8d03-6a476e510815.png)


Githubリポジトリ

https://github.com/Killua0615/hunter

## 技術構成
### 使用技術
| カテゴリ	 |     技術 | 
|:-----------|:-----------|
| フロントエンド     | HTML, CSS, JavaScript, ERB| 
| バックエンド     | Ruby 3.1.2, Rails 7.1.3   |       
| データベース   | MySQL      |        

### ER図
![スクリーンショット 2024-06-26 21.17.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3733846/6c71e47e-63f4-5211-c279-69f757492bc7.png)

## 改善点
<dl>
  <dt>RSpecをセットアップしておく</dt>
  <dt>ER図</dt>
  <dd>スネーク型に変更</dd>
  <dd>PKをidに変更</dd>
  <dd>テーブル名　複数形に</dd>
</dl>

## 思ったこと
今回は特にデータベースの扱いに慣れていないので、躓くことが多かったです。まだ右も左もわからない程の初心者ですが、少しずつ上達して行けたらと思います！
Azure（クラウド）の課金の仕組みを大雑把に理解する

# 概要
Azureの課金の仕組みは初心者には難しい部分があります。
この記事では大雑把にAzureの課金とはどういうものかを記載しています。

# 課金は主に３種類に分けられる
Azureに限らずクラウドで課金されるのは大きく以下３つになります。

1. CPUやメモリといった計算リソース
2. ストレージやディスクといったデータストレージ
3. ネットワークの帯域やネットワーク量

それぞれの特徴を見ていきましょう。

## CPUやメモリといった計算リソース
CPUやメモリはプログラムを動かすためのリソースです。
仮想マシンにはもちろん、Azure AppServiceやAzure Automationといったサービスの中でも使われています。

特徴としては、CPUやメモリを***確保している時間***によって課金されます。
この「確保している」というのはどういうことかといいますと、いつでもすぐに使える状態であるということです。

例えば仮想マシンやAppServiceを使ってWebアプリを作ったとします。
もちろんアプリは起動している間、誰も使っていなくてもいつでも使えるようにリソースとして***確保している***必要があります。

また、***確保している***間は他の人が使えなくなるため、***確保している時間***によって課金されるのです。

### 節約方法
メモリやCPUはサービスによっては***解放***することが出来ます。
例えば、仮想マシンは「割り当て解除」という状態にすることで、CPUやメモリを解放することが出来ます。
もちろん、解放してしまうとすぐに使えないといったデメリットがあります。
そのため、普段は使っていない時間帯だけ解放するといった工夫が必要になります。

## ストレージやディスクといったデータストレージ
データストレージはデータを保管するためのリソースです。
ストレージ系のリソースは大きく以下２つのパターンでストレージのサイズを決めます。
- 事前に保管領域を確保するパターン　
- 保管領域が足りなくなったら追加していくパターン

どちらも保管領域分のストレージ料金がかかるのが特徴です。

### 節約方法
大きく以下の２点に注意することで課金額を下げられます。
- 保管領域をできるだけ小さくする（必要以上に確保しない + 要らないデータは削除する）
- 使用頻度の低いデータは、安いストレージへ移動する

## ネットワークの帯域やネットワーク量
最後にネットワークの帯域やネットワーク量です。
大きく以下２つの課金パターンがあります。
- VNetやIPアドレスといった確保しているリソースの量によって課金されるパターン
- 大きなファイルをダウンロードやアップロードすることで課金されるパターン

### 節約方法
以下に気を付けてください。
- 大きなファイルをダウンロード、アップロードするのは必要最低限にする

## 最後に
AzureやAWSといったクラウドの課金体系は公式ドキュメントが複雑怪奇です。
初心者の方に少しでも参考になったら幸いです。
Azure: Cosmos DB データプレーンのRole を確認する方法

# 背景

Cosmos DB のデータプレーンの Role を生成する際に、作成済みかどうかを確認したかった為の調査記録

# 結論

1. 定義してある JSON から読み込み
1. Azure で Role 名で検索
1. あとは、見つかったかどうかで条件分岐

```powershell: 
# Role 定義ファイルから読み込み
$roleDefinition = Get-Content -Path $roleDefinitionJsonPath -Raw | ConvertFrom-Json
# 定義 Role 名取得
$cosmosRoleName = $roleDefinition.RoleName
# Role に一致するものを、Cosmos DB から取得
$roleInfos = az cosmosdb sql role definition list --account-name {Cosmos Account} --resource-group {Resource Group} --query "[?roleName=='$cosmosRoleName'].{id: id, roleName: roleName}" --output json | ConvertFrom-Json
# 一致する Role の数で確認。null でもいい
if ($roleInfos.Count -eq 0) {
  # Role does not exist
} else {
  # Role exists
}
```

```json: role の例
{
    "RoleName": "MyReadWriteRole",
    "Type": "CustomRole",
    "AssignableScopes": ["/"],
    "Permissions": [{
        "DataActions": [
            "Microsoft.DocumentDB/databaseAccounts/readMetadata",
            "Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/items/*",
            "Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/*"
        ]
    }]
}
```

https://github.com/Azure-Samples/jp-azureopenai-samples/blob/main/5.internal-document-search/scripts/cosmosreadwriterole.json

# あとがき

以前やったときは、query に RoleName を書く事に気付かず探せなかったが、今回はすぐだった・・
脳みそさんが backend で動いていてくれたんですかね :laughing:
npm i? npm ci?

# 導入

Node系のプロジェクトをセットアップするとき、依存関係のインストールしますが、その際、「npm i」を使用することが多いかと思います。一方で、「npm i」に似たコマンドとして、「npm ci」があります。
この違いがよくわからずに使っていたので、その内容について調べて本記事にまとめました。
正直赤字の2箇所が本記事において重要な部分です。

# [npm i] と[npm ci]の違い

## npm iとは？

「npm i」は「npm install」の短縮形で、Node.jsプロジェクトの依存関係をインストールするためのコマンドです。このコマンドは、`package.json`にリストされているすべての依存関係をインストールしてくれます。

npm iの特徴としては以下の点が挙げられます。

- <font color="red">`package.json`に基づいて依存関係をインストールします。</font>
- 依存関係をインストールする際、`package-lock.json`を更新します。もし、`package-lock.json`が存在しない場合、生成してくれます。
- 依存関係がすでにインストールされている場合、`node_modules`フォルダを参照して、必要に応じて更新や追加を行ってくれます。

## npm ciとは？

「npm ci」は「npm clean install」の略で、特にCI（継続的インテグレーション）環境やデプロイプロセスで使用されるので、「npm ci」の「ci」をCI（継続的インテグレーション）とご認識されることがしばしばあるとかないとか。

npm ci の特徴としては以下の点が挙げられます。

- <font color="red">依存関係をインストールする際、`package-lock.json`をしっかりと参照し、記述されている**バージョンを正確に**インストールしてくれます。そのため、環境差異が生じにくいです。</font>
- `package-lock.json`が存在しない場合、エラーが発生します。
- `node_modules`フォルダを完全に削除してから再インストールするため、前回のインストール状態に依存せず、クリーンな状態を保証します。
- `package-lock.json`に基づいて直接依存関係をインストールするため、`npm i`よりも高速にインストールが完了します。

## 使い分けのポイント

「npm i」と「npm ci」を使い分ける際のポイントは、主に開発環境と本番環境といった環境ごとにおけるニーズによります。

- **開発環境**では、柔軟に依存関係を管理するために「npm i」を使用することが多いです。新しいパッケージを追加したり、既存のパッケージを更新したりする際に便利です。

- **CI/CD環境や本番環境**では、一貫性とスピードを重視して「npm ci」を使用することが推奨されます。これにより、依存関係のバージョンが確実に固定され、予期せぬエラーを防ぐことができます。
- また、開発環境においても、開発チーム全体で同じ依存関係を使用するためには、一貫したインストールが重要となるため、「npm ci」を使用することで、チームメンバー間で依存関係のバージョンがズレることを防げます。

# 最後に

「npm i」と「npm ci」はどちらもNode.jsプロジェクトの依存関係をインストールするための強力なツールですが、それぞれの特性と用途が異なります。
これらの違いを理解して、適切な場面で適切なコマンドを使用することで、プロジェクトの開発と運用をスムーズに進めることができるかと思います。
Fluent-Bitのストレージ設定と挙動(SERVICEセクション)

# この記事では

Fluent-Bitが何らかの理由によりクラッシュしてもデータをなるべく失わせず処理を継続させるための設定と動作について記します。

今回はflunet-bit 3.0の公式ドキュメントを引用しつつ解説を交えていきます。

https://docs.fluentbit.io/manual/administration/buffering-and-storage

# ストレージ設定とは？

ログレコードを処理する段階で**チャンク**と呼ばれる論理的なグループがメモリ上に作成されます。チャンクのサイズは2MBでデフォルト設定では最大128個までチャンクを作成することができます。

INPUTプラグインでログレコードを読み込んで処理するにもメモリ上で行うことができて高速ではあるもののFluent-Bitコンテナ(サーバー)がダウンしてしまったら...メモリ上のデータは無かったことになります。

そういった事態を避けるために、データをメモリ上に作成すると同時に外部に複製データを作成し、**メモリとファイルシステムの二段構えを取ることで信頼性を高めることができます。**

## storage.path

デフォルトでは特に指定は無く、その場合はメモリでのみ処理を行います。
事前にパーミッション設定を適切に行ったディレクトリの絶対パスを指定することでファイルシステム上へのバックアップが出力されます。

例: `storage.path /var/fluent-bit/storage`

## storage.sync

メモリ上のデータとファイルシステム上のデータの同期モードを**normal**または**full**のどちらかで指定します。fullのほうがメモリとファイルシステム間の同期を厳格に行ってくれるようです。
normalとfullでどのような挙動の違いがあるのか正確なところまで掴めていませんが詳しく追うには次のページから辿っていく必要がありました。
※MAP_SYNC項に記載されています。

https://man7.org/linux/man-pages/man2/mmap.2.html

# おわりに

大切な物というのは失ってから気付くと言われています。
開発チームから「あのログは？」と聞かれてからでは遅いのです.....

この他にもQiita Engineer Festaを良い機会として隙を見つけて投稿していきたいですね。
Salesforceでフローを作成しよう～Todo作成時に作成ユーザの部署情報を残す方法

本橋孝昭です

今回はフローでTodo作成時作成ユーザの部署情報を残す方法を解説します


前提としてAPI参照名test01__cというテキスト型カスタム項目をあらかじめ活動オブジェクトに作成してください


フローの全貌はこちらです

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/f3556f86-96bb-f7ce-94f8-e544ad11e0d2.png)



更新の値はこちらです

>{!$Record.CreatedBy.Department}


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/5f060938-d981-a3e8-f41b-1bdff0873e79.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/f63059a2-1ee6-6585-ee7e-01f852e97d3e.png)