OmniAICreator/Qiita-1.07M huggingface dataset:
正規表現

# 正規表現 (Regular Expression) ドキュメント

正規表現は、文字列の検索、置換、パターンマッチングに使用される非常に強力なツールです。特にプログラミングやテキスト処理で頻繁に活用されます。

---

## 基本構文

| パターン       | 説明                                  |
|----------------|---------------------------------------|
| `.`            | 任意の1文字                          |
| `^`            | 行頭                                  |
| `$`            | 行末                                  |
| `*`            | 直前の文字が0回以上繰り返される      |
| `+`            | 直前の文字が1回以上繰り返される      |
| `?`            | 直前の文字が0回または1回現れる       |
| `{n}`          | 直前の文字がn回繰り返される          |
| `{n,}`         | 直前の文字がn回以上繰り返される      |
| `{n,m}`        | 直前の文字がn回以上m回以下繰り返される|
| `[]`           | 指定された文字集合のいずれか1文字    |
| `[^]`          | 指定された文字集合以外の1文字        |
| `|`            | OR条件                               |
| `()`           | グループ化、またはサブパターン       |

### 基本構文の例

#### 1. 任意の1文字: `.`

正規表現: `a.c`

入力例:
```
abc
adc
afc
ac
```

出力:
```
abc
adc
afc
```

#### 2. 行頭: `^`

正規表現: `^Hello`

入力例:
```
Hello World
Say Hello
Hello
```

出力:
```
Hello World
Hello
```

#### 3. 行末: `$`

正規表現: `end$`

入力例:
```
This is the end
The end is near
end
not the end.
```

出力:
```
This is the end
end
```

#### 4. 直前の文字が0回以上繰り返される: `*`

正規表現: `ba*`

入力例:
```
ba
baa
baaa
b
bba
```

出力:
```
ba
baa
baaa
b
```

#### 5. 直前の文字が1回以上繰り返される : `+`

正規表現: `ba+`

入力例:
```
ba
baa
baaa
b
bba
```

出力:
```
ba
baa
baaa
```

#### 6. 直前の文字が0回または1回現れる : `?`

正規表現: `colou?r`

入力例:
```
color
colour
colouur
colr
```

出力:
```
color
colour
```

#### 7. 繰り返し回数: `{n}`

正規表現: `a{3}`

入力例:
```
a
aa
aaa
aaaa
```

出力:
```
aaa
```

#### 8. 範囲繰り返し: `{n,}`

正規表現: `a{2,}`

入力例:
```
a
aa
aaa
aaaa
```

出力:
```
aa
aaa
aaaa
```

#### 9. 最小・最大繰り返し: `{n,m}`

正規表現: `a{2,3}`

入力例:
```
a
aa
aaa
aaaa
```

出力:
```
aa
aaa
```

#### 10.  指定された文字集合のいずれか1文字 : `[]`

正規表現: `[aeiou]`

入力例:
```
b
c
a
e
i
o
u
```

出力:
```
a
e
i
o
u
```

#### 11. 指定された文字集合以外の1文字 : `[^]`

正規表現: `[^aeiou]`

入力例:
```
b
c
a
e
i
o
u
```

出力:
```
b
c
```

#### 12. OR条件: `|`

正規表現: `cat|dog`

入力例:
```
cat
dog
bat
```

出力:
```
cat
dog
```

#### 13. グループ化: `()`

正規表現: `(ab)+`

入力例:
```
ab
abab
ababc
abc
```

出力:
```
ab
abab
```

---

## 特殊文字

| 文字  | 説明                                  |
|-------|---------------------------------------|
| `\d` | 数字 (0-9)                            |
| `\D` | 数字以外                              |
| `\w` | 英数字またはアンダースコア (_a-zA-Z0-9)|
| `\W` | 英数字およびアンダースコア以外        |
| `\s` | 空白文字 (スペース, タブ, 改行)       |
| `\S` | 空白文字以外                          |
| `\b` | 単語境界                              |
| `\B` | 単語境界以外                          |
| `\`  | エスケープ (特殊文字を無効化)         |

---

### 特殊文字の例

#### 1. 数字: `\d`

正規表現: `\d{3}`

入力例:
```
abc123def
456
78
9012
```

出力:
```
123
456
901
```

#### 2. 数字以外: `\D`

正規表現: `\D+`

入力例:
```
123abc456
78def
90ghi12
```

出力:
```
abc
def
ghi
```

#### 3. 英数字またはアンダースコア: `\w`

正規表現: `\w+`

入力例:
```
abc_123
@#$%^
helloWorld
```

出力:
```
abc_123
helloWorld
```

#### 4. 空白文字: `\s`

正規表現: `\s+`

入力例:
```
Hello World
Tab\tHere
New Line
```

出力:
```
(space)
(tab)
(newline)
```

#### 5. 単語境界: `\b`

正規表現: `\bword\b`

入力例:
```
word
wordplay
anotherword
word.
```

出力:
```
word
word.
```

---
サーバー上にSFTPユーザーを作成し、SFTP接続してみた

とあるタスクでSFTP接続に関して調べたため、自分への復習も兼ねてアウトプットします。

## SFTP接続とは
SFTP（SSH File Transfer Protocol）は、SSHトンネルを利用して、サーバー間でファイルのやり取りができるプロトコルです。通常のFTPと比較して、やり取りが暗号化されているため、より安全にファイルのやり取りができます。

## やりたいこと
タスクでは、下記内容を行いました。
・接続するサーバー上にSFTPでアクセスできる特定のユーザーアカウントを作成する。
・サーバーにホスティングされているWordPressの特定のディレクトリにファイルを送る。
※サーバーはAWSのLinuxサーバーを使用しております。

## 手順
1.SSH接続をしたのち、接続するサーバー上にSFTPでアクセスできる、特定のユーザーアカウントを作成する
```
# サーバーにSSH接続をする。
ssh -i {秘密鍵情報} (ユーザー名)@（サーバーのIPアドレス）

# SFTP接続設定を行うために管理者権限設定
sudo su 

# ユーザーを作成する（例: sftp_user)
useradd sftp_user

# パスワード設定
passwd password

# ユーザーが作成されているか確認
cd /home
ls
```


2.作成したユーザーのユーザーディレクトリに「755」権限を付与する
```
chmod 755 /home/sftp_user

# パーミッションの確認
ls -la
```

3.`sshd_config`（サーバーのSSHの設定ファイル）でSFTP設定をし、SFTPユーザーのみパスワード認証をする。
→`PasswordAuthentication yes`にすることで、ユーザーはパスワード認証によってSFTP接続ができる。
→`ForceCommand internal-sftp`にすることで、このユーザーはデフォルトSFTP接続で、ssh接続は行わないという設定を行う。
```
vi /etc/ssh/sshd_config
→ Match User sftp_user
	  PasswordAuthentication yes
	  ForceCommand internal-sftp

# sshdの再起動
systemctl restart sshd
```

4.ユーザーディレクトリにマウントする用のディレクトリを作成する
```
cd /home/sftp_user
mkdir wp-content
```

5.ユーザーディレクトリをWordPressのファイルがホスティングされているパブリックディレクトリにマウントする
```
# ユーザーディレクトリをWordPressのファイルがホスティングされているパブリックディレクトリにマウントする
# mount --bind （マウントする側のディレクトリ）（マウントされる側のディレクトリ）
mount --bind /var/www/html/wp-content /home/sftp_user/wp-content

マウントされる側のディレクトリに上記/home/sftp_userがあるかどうか確認する。
mount
```

6.マウントの永続化設定をし、正しく適用できているのかを確認する。
```
# fstabファイル（マウントの設定について書かれたファイル）を編集して永続マウントの設定を追加
vi /etc/fstab

# 下記の永続マウントの設定を追加する
/var/www/html/wp-content /home/sftp_user/wp-content none bind 0 0

# 永続化マウントの設定が適用されているのかを確認
mount -a
```

7.SFTPクライアントから接続をし、特定のディレクトリにファイルを転送する
例）WinSCP、FileZilla


## ディレクトリの権限
ディレクトリに権限をつける理由は、**セキュリティ**と**アクセス制御のためです。**

セキュリティ: サーバに接続できた人全員がディレクトリ内のファイルに対して変更ができないようにし、データの破壊等を防ぐため

アクセス制限: 認証されたユーザーでも、必要以上の権限（書き込み権限等）を付与しないことによって、意図しない変更を防ぐため

ディレクトリの権限変更は`chmod`、所有者変更は`chown`で行います。

| 権限         | 説明                                   | 数値表現 |
|--------------|----------------------------------------|---------|
| 読み取り (r) | ファイルやディレクトリ内容の閲覧が可能  | 4       |
| 書き込み (w) | 内容の変更や新しいファイルの作成が可能  | 2       |
| 実行 (x)     | ファイルの実行、ディレクトリへのアクセス | 1       |

例）750→所有者はすべての権限、所有者グループのユーザーは読み取りと実行、その他の方は権限なし

## 最後に
最後まで読んでいただき、ありがとうございます！
git statsと打ってしまった...そんな時はF***Kしよう！

「git status」と打つつもりが「git stats」と打ってしまった...
「docker compose up」なのに「dokcer compose up」と打ってしまった...

そんな経験、ありませんか? 
今回は、そんなちょっとしたタイプミスを魔法のように修正してくれる「thefuck」というツールを紹介します.

## thefuckとは?

thefuckは、コマンドラインでの入力ミスを自動で検出し、正しいコマンドを提案してくれる便利ツールです. 
名前は少しあれですが、使い方は超シンプル!

## インストール方法

Homebrewでインストール
```bash
brew install thefuck
```

## 実践的な使用例

### 例1: gitコマンドのタイプミス
```bash
$ git stats  # 間違い
git: 'stats' is not a git command. See 'git --help'.

The most similar command is
        status
```
入力ミスをしてしまったので以下のコマンドで正しいコマンドを提案させてみる
```
$ fuck
git status  # 自動で正しいコマンドを提案 [enter/↑/↓/ctrl+c]
```
### 例2: dockerコマンドのタイプミス
```bash
$ dokcer ps
Command 'dokcer' not found
```
dockerコマンドのミスもOK,
```bash
$ fuck
docker ps  # 自動修正！
```
### 例3: ファイル操作のミス
```bash
$ rm -rf /tmp/test  # 権限がない場合
rm: /tmp/test: Permission denied
```
ファイル操作の際に権限がないと出た．これはsudoを使えばよかったのだが，この修正も提案してくれる
```bash
$ fuck
sudo rm -rf /tmp/test  # sudoを自動で追加
```
## thefuckの賢い機能

1. **複数の修正候補の提示**
   間違いの種類によっては、複数の修正候補を提示してくれる. 矢印キーで選択可能.

2. **履歴からの学習**
   よく使うコマンドのパターンを学習し，より適切な修正を提案してくれます.

3. **様々なコマンドに対応**
   - git
   - docker
   - npm
   - apt-get
   など、主要なコマンドツールに対応していました

## 注意点
しかし注意点もあります．
- 全てのコマンドミスを修正できるわけではない
- 複雑なコマンドやオプションの組み合わせは苦手な場合がある
- システムコマンドの実行には注意が必要

## こんな時に特に便利

- 長いコマンドを入力中にタイプミスした時
- 似たようなコマンドを間違えた時
- 権限関連のコマンドを忘れた時
- 異なるOSでコマンドを打ち間違えた時

thefuckは、日々のコマンドライン作業での小さなストレスを解消してくれる強力なツールである．

ぜひ普段の開発作業に取り入れて、ストレスフリーな開発ライフを送りましょう!
git pushの引数を省略しよう! [Git] 

gitでpushする際にリモートリポジトリとブランチ名を指定してpushするのが一般的かなと思います。

```zsh:git
git push <remote_repository> <branch_name>
```

ですが、ローカルリポジトリにおけるブランチ名とリモートリポジトリにおけるブランチ名を同じにしてpushしてる方も多く、毎回上記のコマンドを打つのはめんどくさいですよね


初回のpush以降、ブランチ名を指定しなくていいようにする方法を紹介します

# --set-upstream(-u)オプション

ブランチ名を省略してpushできるようにするコマンドは以下のようになっています。

```zsh:git
git push -u origin <branch>
```

or

```zsh:git
git push --set-upstream origin <branch>
```

とします。

--set-upstreamもしくは同じ意味を持つ-uをつけることで、ローカルブランチとリモートブランチを紐づけることができるようになります。

これから次回以降pushコマンドを使う場合、git pushを行うだけで紐付けたリモートブランチにpushしてくれるようになります。

```zsh:git
git push 
```

# もっとコマンドを簡略化する

branchの名前が長い時はいくら補完が聞いたりしてもめんどくささが勝つと思います。


その場合はブランチ指定の部分をHEADとすることで現在いるブランチを指定することができます。

:::note
### HEADとは

HEADは`現在いるブランチ`において最新のコミット(のポインタ)を指します。

HEADを指定することで現在いるブランチを簡単に指定することができます。
:::

行う場合のコマンドは下のようになります

```zsh:git
git push -u origin HEAD
```

or

```zsh:git
git push --set-upstream origin HEAD
```

# さらに省略する

コメントで教えていただいたのですがHEADは@で省略できるそうです

```zsh:git
git push -u origin @
```

or

```zsh:git
git push --set-upstream origin @
```

めっちゃ短くなりましたね...

# git関連の記事

https://qiita.com/maooz4426/items/b547f8474e3a83f96336

https://qiita.com/maooz4426/items/0f994e08f17dfaa1b3ba

https://qiita.com/maooz4426/items/8ae2a7df1add39e9f943

https://qiita.com/maooz4426/items/a4cc324092f1e3c03c19
AIと共に進めるマルチ言語開発のススメ

この記事は[ソニックガーデン プログラマ アドベントカレンダー](https://qiita.com/advent-calendar/2024/sonicgarden)の23日目の記事です。

## はじめに

iOSアプリではSwift、WebアプリではRubyなど、複数の言語を同時に使うことがあります。
今回は、そんな複数言語の開発でAIを活用する方法を紹介します。
**なお、AIツールを使うとコードが学習データとして使われる可能性があります。仕事で利用する場合は社内ルールを確認してください。**

## 結論

複数の言語・IDEを併用するなら、コード補完にはGitHub Copilotを、抽象的な質問や相談にはChatGPTの「Work with App」を使うのがおすすめです。

## 開発時に利用しているAI

### GitHub Copilot - RubyMine

[公式ドキュメント](https://docs.github.com/en/copilot/managing-copilot/configure-personal-settings/installing-the-github-copilot-extension-in-your-environment?tool=jetbrains)

Web開発では主にRubyMineを使用しています。
GitHub Copilotのプラグインを入れるだけで、優秀な入力補完が得られます。たとえばModelのメソッドを作ると、全パターンを網羅するRSpecのコードを自動提案してくれます。


### GitHub Copilot - Xcode

[公式ドキュメント](https://docs.github.com/en/copilot/managing-copilot/configure-personal-settings/installing-the-github-copilot-extension-in-your-environment?tool=xcode)

iOSやvisionOSのアプリ開発ではXcodeを使っています。
SwiftUIで画面プレビューしながら開発できるのが魅力です。
入力補完は優秀ですが、Copilot Chatがないので「もっと良い書き方は？」「コードの改善点は？」といった抽象的な質問ができません。

### ChatGPT - Work with App

[公式ドキュメント](https://help.openai.com/en/articles/10119604-work-with-apps-on-macos)

![ChatGPT Work with App](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4529/7403f529-5183-e759-19e3-97db759baa28.png)|
|:--:|
| Work with AppでmacOSのアプリと連携 |

ChatGPTのWork with Appを使うと、RubyMineやXcode、ターミナルなどmacOSアプリならほぼ連携可能です。
コードをコピーせずにChatGPTから指示を出せるため、IDEやアプリの画面をそのまま読み取ってもらえます。どのIDEでもUIが変わらずに使える点も便利です。
Work with Appの利用には、有料プランへの加入が必要です。

![Xcodeと連携中](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4529/c4fba45d-2ced-63ab-a534-510646fc5fa0.png)|
|:--:|
| Xcodeに表示されているコードをリファクタ |

## （おまけ）Gemini - Share your screen

[Google AI Studio](https://aistudio.google.com/welcome)

個人的には、今一番気になっているのは「Gemini」です。GeminiのShare your screenを利用すればコードを書きつつ、同僚に話しかけるように音声で質問ができたり、音声で提案が返ってくるのが特徴的です。
次の動画はXcodeのコードに対して解説してもらっています。

※ 動画を見やすくするためにGeminiの返答までの時間はトリミングしています。実際には返答までにそれなりの時間がかかります。
<iframe width="560" height="315" src="https://www.youtube.com/embed/GzeYQf5rn8g?si=f-KNhJXYKerQSgNW" 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>

ただ、すべて音声ベースなので、コードを含むやりとりには少し不便です。
テキストと音声を両方使えれば、より快適になると思います。

<iframe width="560" height="315" src="https://www.youtube.com/embed/GzeYQf5rn8g?si=-64g4yNnyN0dyOFu&amp;start=95" 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>

## まとめ

現状は、コード補完にGitHub Copilot、抽象的な質問にChatGPTのWork with Appという組み合わせを使っています。
将来的には、言葉にするだけでコードを自動生成できるかもしれません。
Geminiのような新しい技術が進化すれば、AIとのペアプロがもっとスムーズになりそうで楽しみですね！
eclipseでマウススクロールが1行になるので複数行にするHotKey

```text
#Requires AutoHotkey v2.0

; Eclipseウィンドウがアクティブな場合のみスクリプトを適用
#HotIf WinActive("ahk_class SWT_Window0") ; Eclipseのウィンドウクラス名を指定

; マウスホイール上スクロール時に複数行スクロール
WheelUp::
Loop 3 { ; スクロール量を増やす（3回繰り返し）
    Send {WheelUp}
}
return

; マウスホイール下スクロール時に複数行スクロール
WheelDown::
Loop 3 { ; スクロール量を増やす（3回繰り返し）
    Send {WheelDown}
}
return

#HotIf ; 条件付きホットキーの終了
```
【Unity 6】Sentis 2.xでONNXの拡張をしたい

# 自己紹介
CyberAgentの26卒ゲームクライアントエンジニアとして内定を頂いています海道敦也（[@kaidoatsuya](https://x.com/kaidoatsuya)）です。
最近はUnity Sentisを触っているものの、なかなかうまく動いてくれないですｗ

## 本記事について
この記事はCyberAgent 26th Fresh Engineer's Advent Calendar 2024の24日目です。

本アドベントカレンダーは、サイバーエージェント26卒の有志がお送りするものです。
あくまで**有志での開催**となります。楽しんでいってください！

https://qiita.com/advent-calendar/2024/ca-26th

# Unity Senitsについて
Unity SentisとはUnity公式が提供するランタイムでAIモデルを動かすUnityパッケージです。
実態はテンソル（n次元の行列のようなもの）演算を行うライブラリです。

ONNXファイルに対応しており、Unity用に最適化するSentisファイルというものに変換できます。

https://docs.unity3d.com/Packages/com.unity.sentis@2.1/manual/index.html

# ONNXについて
ONNXは汎用的なAIモデルを表現するフォーマットです。

https://qiita.com/motoJinC25/items/d662be70b6b9b8ebbaea

# ONNXを拡張する
Unity Sentigsでは画像を入力データとしてテンソル（Tensor）に変換するときにRGBを0-1の値として生成します。
一方、一部のモデルでは入力データがRGBの値が0-255である必要があります。

こういったときにONNXを拡張する、もしくはONNXなしでモデルを簡易的に作る必要があります。
公式ドキュメントには、出力を変更するサンプルコードが掲載されていますが、入力を変更するコードは存在しません。

https://docs.unity3d.com/Packages/com.unity.sentis@2.1/manual/edit-a-model.html

今回は入力を変更するコードを基にSentisの演算プロセスの構築方法を見ていきます。

## 主要なクラス
モデルの拡張や作成に使うクラスは２つあります。`FunctionalGraph`と`Functional`というクラスです。

### FunctionalGraph
これは構造全体を構築するクラスです。
このクラスが最終的なアウトプットを出力してくれます。

### Functional
これはどのような演算をするのか指定する静的クラスです。
掛け算だとか、キャストなどが静的なメソッドを呼び出して構造を作っていきます。

## 実際のコード
言葉では上手く理解できないと思うので、ソースコードです。
```Csharp:RGB0-1 to 0-255
public void CreateRGB255()
{
    // FunctionalGraphのインスタンスを生成
    var graph = new FunctionalGraph();

    // 1. インプットを追加（Shapeはモデルに合わせて作成）
    var input = graph.AddInput(DataType.Float, new DynamicTensorShape(1, -1, -1, 3));

    // 2. 255で乗算する
    var rgb255 = Functional.Mul(input, Functional.Constant(255.0f));

    // 3. Intにキャスト
    var castInt = Functional.Int(rgb255);

    // 4. モデルをコンパイル
    var newModel = graph.Compile(castInt);
    
    // モデルを保存（Sentisファイルとして出力されます。）
    ModelWriter.Save($"{Application.dataPath}/Onnx/ToRGB255.sentis", newModel);
    
    Debug.Log("Saved the new model.");
}
```
FunctionalGraphとFunctionalの静的なメソッドから来る引数の関係が極めて分かりにくいですが、このような形です。

### 実際の処理・解説
デバッカーを用いて、どのような処理となっているのか自分なりに考察しました。
1. インプットを追加
    - `input`は入力だけを持ちます
1. 255で乗算する
    - `rgb255`は入力と乗算するという構造を持ちます
1. Intにキャスト
    - `castInt`は入力と乗算とキャストという構造を持ちます
1. モデルをコンパイル
    - `castInt`は今までの構造すべてを持っているため、これをコンパイルすればOK!

### おまけ
ちなみに、`DynamicTensorShape`という記述がありますが、これは動的な形状の入力です。
-1に値を設定したときはどのようなサイズの配列（厳密に言うと配列ではない？）がそこに入ってきてもOK！になります。

# まとめ
公式ドキュメントにもあるものの、分かりにくいところを記事にしてみました！
もう少し`FunctionalGraph`と`Functional`の関係性が分かりやすければ良いなぁと思うばかりです。

# おわりに
CyberAgent 26th Fresh Engineer's Advent Calendar 2024もそろそろ終わりですね！
それでは、さようなら！

ほかの記事も見てね～
treeコマンドでディレクトリ構造の取得


業務でディレクトリの構造を書き出す必要があったのですが、自分で
```
└─cache
    ├─hoge
    │  ├─fuga
    │  │    ├─hogehoge
```
のようなものを一から作成するのは手間だと思い、一発で取得できる方法はないか探した際にいいコマンドを発見しました。Linuxコマンドの```tree```コマンドです。
# 使い方
取得したいディレクトリに移動後```tree```を打つだけで使用できます。
インストールされていないと使用できないようなので、インストールしていい環境であれば、下記でインストール
```
$ sudo apt-get install tree
```
# treeコマンドのオプション抜粋
他にもありましたが、使いそうなものだけ自分用のメモとして記載。

|オプション |説明 |
|----------|-----|
| -a | 「.」で始まる隠しファイルも表示|
|-d | ディレクトリのみツリー表示|
| -l| シンボリックの場合、階層をたどる|
|-p |ファイルのパーミッション情報を表示する|
|-s|ファイルのサイズをバイト単位で表示|

# おわりに
今回は勝手にいじれないサーバーでの作業だったので結局手動で書き出しました。ほかに何か代替のコマンドあれば教えていただきたいです。
# 参考記事
- https://www.sejuku.net/blog/54248
M3 MacでCodeBuildをローカルで実行する

# はじめに

ローカルでCodeBuildを実行しようといろんな記事を参考にしましたが、うまく起動できず、困ったので、同じように困った人の解決になればよいと思って記事にしました。


# 準備

事前に以下、インストールが必要になります。

- git
- docker

# docker image ダウンロード

## AmazonLinux2のARM版

AmazonLinux2のARM版のイメージがあるので、こちらをダウンロードします。

:::note info
ここがハマりポイントで、単純に検索しただけでは、x86_64版しか見つからず、そっちを使ってしまい、うまくビルドできなかった
:::

```
docker pull public.ecr.aws/codebuild/amazonlinux2-aarch64-standard:3.0
```

##  エージェントのDockerイメージダウンロード

こちらもARM版をダウンロードします。

```
docker pull public.ecr.aws/codebuild/local-builds:aarch64
```

# コンテナ起動シェルダウンロード

コンテナを起動する、シェルファイルをダウンロードして、実行権限を付与します。

```
curl -OL https://raw.githubusercontent.com/aws/aws-codebuild-docker-images/master/local_builds/codebuild_build.sh
chmod +x codebuild_build.sh
```

# buildspec.ymlの作成

buildspec.ymlファイルを作成します。

```
version: 0.2

phases:
  install:
    commands:
      - echo 'Hello World'
```

このときのディレクトリ構成は以下の状態です。

```
codebuild/
  buildspec.yml
  codebuild_build.sh
```

# CodeBuild実行

以下、コマンドを実行すると、CodeBuildがローカルで実行できます。

```
./codebuild_build.sh -i public.ecr.aws/codebuild/amazonlinux2-aarch64-standard:3.0 -a output -l public.ecr.aws/codebuild/local-builds:aarch64
```

# おまけ

## CodeBuildからローカルで起動してる別コンテナに接続したい

buildspec.ymlで例えばmysqlというコンテナに接続したい、とするとcodebuild_build.shを少し編集するとできるようになります。

簡単に説明すると、CodeBuildコンテナのネットワークにmysqlコンテナのネットワークを所属させてあげれば、可能になります。
※もしかしたら、別の方法もあるのかも知れませんが、この方法でも可能です。

変数は適当にdocker_command2としてます。
所属させたいコンテナのネットワーク名は`docker network list`を実行すればわかります。

```
docker_command2="docker network connec agent-resources_default ネットワーク名（mysqlコンテナが所属ネットワーク名）
eval $docker_command2
```
【New Relic】 特定のプロセスを監視して、夜しか眠れない状態にしたい


## 最初に
この記事は、[New Relic 使ってみた情報をシェアしよう！ by New Relic Advent Calendar 2024](https://qiita.com/advent-calendar/2024/newrelic "New Relic Advent Calendar 2024") のシリーズ2、23日目の記事です。

## 目的
オンプレサーバーやAmazon EC2で動いている特定のプロセスをNew Relicで監視したいと思いませんか？
バックグラウンド(nohup)やSupervisorで動かしているスクリプトやプロセス、ちゃんと正常に動いているか、つい気になりませんか？
特に、Supervisorで再起動するはずのプロセスが、なぜか再起動されずに放置され、気づかないうちに障害が発生してしまう...なんてことがあると困りますよね。こんな状況では、安心して夜も眠れません。

今回は最もフィジカルで、最もプリミティブで、そして最もフェティッシュなやり方？でいかせていただきます。

## infrastructureエージェントの導入
Linuxにinfrastructureエージェントの導入は必須です。
ご利用のディストリビューションを確認して導入していきましょう。

https://docs.newrelic.com/jp/docs/infrastructure/infrastructure-agent/linux-installation/package-manager-install/

```shell
# 設定ファイルを作成し、ライセンスキーを追加
echo "license_key: xxxx" | sudo tee -a /etc/newrelic-infra.yml

# バージョン確認
cat /etc/os-release

# Amazon Linux2(x86)を利用した場合
sudo curl -o /etc/yum.repos.d/newrelic-infra.repo https://download.newrelic.com/infrastructure_agent/linux/yum/amazonlinux/2/x86_64/newrelic-infra.repo

# リポジトリを更新
sudo yum -q makecache -y --disablerepo='*' --enablerepo='newrelic-infra'

# インストール
sudo yum install newrelic-infra -y

# サービスの状況確認
sudo systemctl status newrelic-infra

```

## /etc/newrelic-infra.ymlの設定
インストール直後、ライセンスキーが記載されているだけになっています。
```shell
$ cat /etc/newrelic-infra.yml

license_key: xxxxxx
```

上記の設定でNew Relic UIを確認してみると、プロセスが確認できていない状態です。
![newrelic-process01-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533466/001c4032-237f-190c-bf5d-3dd094f0747f.png)


特定のプロセスが監視できるようにnewrelic-infra.ymlを変更します。
```shell:変更後
license_key: xxxxxx
enable_process_metrics: true
include_matching_metrics:
  process.name:
  - efs_mount_alert
```
必ずinfrastructureエージェントの再起動を実施しておきましょう。
```
sudo systemctl restart newrelic-infr
```

## New Relic UIにて確認

![newrelic-process02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533466/49f16590-0e8d-58f5-ae31-66c4aaa6802b.png)
監視したいプロセスが確認できていますね。

:::note info
［備考］今回、監視したプロセスについて

動作状況を確認するための簡易ヘルスチェックです。(CloudWatchログなどを使わず簡易的に行なっています)
・サーバーにマウントしたEFSが外れたか、マウントが外れたことによる再マウントを試みたことを特定のログに出力
・各アベイラビリティゾーンのEFSマウントターゲットへtelnetコマンドで接続確認を行い結果を特定のログに出力

上記のログにて問題が発生した文字列を検知して、Slackにアラートを送る簡易的なシェルスクリプトをSupervisorでバックグラウンド実行しています。
:::

## 最後に
特定のプロセスの状態が確認できるようになりました。
あとはNRQLを駆使しNew Relicダッシュボードで確認できる状態にして観測性を高め、New Relicアラートを用いてプロセスの異常時(高負荷、停止、メモリリークなど)を即座に検知してSlackなどに通知を行うことにより、問題が発生しても即時対応できる状態になります。

また、インフラエージェントで出力されたログをNew Relicに送信して監視する方法もあります。
プロセス監視かログ監視どちらが良いか、それとも両方監視して運用すべきなのか検討して知見をためてきます。

では、最後までお付き合いいただき、ありがとうございます。
あくまで一例ではありますが、New Relicをご活用いただく際のヒントになれば幸いです。
来年も何卒よろしくお願いいたします。

## 参考
[New Relic Organizationの記事](https://qiita.com/organizations/newrelic/items)にある

https://qiita.com/ume67026265/items/a4fbb9c3b3fb673c6c49

を元に記事を書いています。
上記の記事は、プロセスに関する情報を取得して、New Relicへの転送データ量を最適化する方法やnewrelic-infra.ymlの設定について記載されており、より深くプロセス監視の設定方法について理解することができます。

.
.
.

~~無印良品ギフトカードが欲しい~~
【kintone】LineWorksルーム通知プラグイン(Incomming Webhook)を作りました！

こちらは[LINEWORKSアドベントカレンダー2024](https://qiita.com/advent-calendar/2024/lineworks)参加の記事です！

みなさんはIncomming Webhookアプリ、もう試しましたか？
Incomming Webhookはトークルームへ簡単に通知を送ることができるURLを発行できるサービスです。
定型のPOSTメッセージを送るだけで、通知が発行できちゃいます！

https://line-works.com/appdirectory/incoming-webhook/

ぼくはこの機能を利用して、kintoneからトークルームへ通知できるプラグインを作成してみました。

# LineWorksルーム通知プラグイン
プラグインはこちらからダウンロードできます。（無料で配布してます）
セットアップ方法も解説しています。

https://www.pulsar-works.jp/dist/kintone-lineworks-notice/

ぜひ試してみてください！

# LWTTで教えてもらいました
11月に名古屋で開催されたLWTT(LineWorks Tech Talk)で、IncommingWebhookを教えていただきました。これがkintoneの機能にぴったりだったので、kintoneのプラグインを作ろうと思い立ちました。

やろうと思ってもきっかけがないとできないと思ったので、アドベントカレンダーにも登録させていただきました。ちゃんと発表できてよかったです。

Incomming Webhookは素晴らしいです。それまで、LineWorksとの連携はOAuthによる連携が必須だったので、サーバーが必ず必要でした。Incomming WebhookはURLへのPOSTのみで成立させられるので、とても手軽に連携ができました。

# プラグインの機能の裏技
ここからはLineWorksルーム通知プラグインでできる機能をご紹介します。

![スクリーンショット 2024-11-23 145710.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3712902/4daf1ae8-e1ef-d408-7d88-07330ecd7f96.png)

**メッセージ内容**を見てください。
こちらはテンプレートエンジンに [Handlebars](https://handlebarsjs.com/) を利用していますので、Handlebarsでの記法をそのまま利用できるようになっています。

「kintoneのデータが更新されました！」といったメッセージのみでも十分有用だと思いますが、kintoneのレコードデータを利用することで、詳しいメッセージになったり、メンションに利用したりといったことができます。

### レコードデータの利用
```
{{更新者.value.name}}
```
👆はkintoneレコードの更新者の名前を取得しています。

```
{{文字列一行.value}}
```
👆は文字列一行のレコードデータを利用した記法です。


### 組み込み関数の利用
```
{{now "HH:mm"}}
```
👆は現在日時の時間と分を表示しています。

```
{{date 更新日時.value "HH:mm"}}
```
👆はkintoneレコード内の【更新日時】フィールドのデータから時間と分を表示しています。

now, dateはHandlebarsにはない、LineWorksルーム通知プラグイン専用の組み込み関数として用意しています。

Handlebarsに組み込まれた**each**などの関数を利用することで、サブテーブルの展開などができます。

https://handlebarsjs.com/guide/builtin-helpers.html

### メンション
LineWorksへのメンションは
```
<m userId="{userId}">
```
の形式であれば、メッセージ内容に組み込まれていればできます。

なので、【メンション】の項目にIDを設定しなくても、kintone上にデータがあればテンプレート機能でメンションを動的に生成できます。

```
{{#if メンション.value}}
<m userId={{メンション.value}}>
{{/if}}
```
👆はメンションという文字列フィールドに値が入っていれば、メンションするというテンプレートです。

# まとめ
今回はIncomming Webhookを利用したkintoneプラグインを作ってみました。

LineWorks-kintone連携は実はたくさんのサービスがあります。
ただ、IncommingWebhookを利用すれば、限定された用途なら、もっと手軽に開発ができてしまいます。
簡単な通知であればトライしてみてはいかがでしょうか？

プラグインの開発、とっても楽しかったです😊

---
この記事は以上です。ありがとうございました。

https://www.pulsar-works.jp/

kintoneのプラグイン開発や研修などを行っています。
お仕事のお話はこちらまで。
はじめてOrganizationに記事を紐づけしてみた！未経験エンジニアの挑戦記

## はじめに
今回はこちらのアドベントカレンダーに参加したので誰かの参考になるような記事を書きたいと思います。

https://qiita.com/advent-calendar/2024/first-time

## 私について
エンジニアへの転職を第一目標に、プログラミングスクールで学び、アウトプットの場としてQiitaを活用しているわーちゃんと申します。
今回の記事では、私が初めてOrganizationに記事を紐づけした際の経験を振り返ります。
初心者でも簡単に挑戦できることをお伝えしたいと思います！


## そもそもOrganizationって何？
QiitaのOrganization機能を初めて知ったのは、Qiitaエンジニアフェスタに参加した時でした。
個人の投稿だけでなく、チームや会社で情報を共有できる素晴らしい仕組みだと感じました。
私が通っているプログラミングスクールにもOrganizationが前からあったようなのですが、その存在を知らずに今まで個人で記事を書いていました。


## 紐づけに挑戦するまでのハードル
今回のQiitaアドベントカレンダーのイベントが開催された初めごろ、プログラミングスクールのOrganizationから突然招待の通知が届きました！

初めて記事を紐づけする際、『自分の記事が本当に役立つのか』と不安でいっぱいでした。しかし、同じように初心者からスタートした人の記事を見て、『挑戦することに意味がある』と感じました。


## 実際に紐づけをやってみた！
私はてっきり記事を新規で投稿すると、自動的にOrganizationにも記事が投稿された状態になるのかと思っていましたが、そうではありませんでした…。かなり時間が経ってから気づきました。
（具体的には下記3の部分で選択を行っていなかった💦）

実際にOrganizationに紐づける作業はとても簡単でした。
新規投稿の際には下記手順で記事を紐づけてみてください！
1. QiitaでOrganizationページを開く  
2. 自分のアカウントを紐づけたいOrganizationに加入  
3. 記事投稿時にOrganizationを選択  


### 後から紐づけ
私は**後から紐づけ**に挑戦してみました！！
下記Qiitaの公式記事を参考に、初期に書いた私のつたない記事を紐づけてみたいと思います！！

https://help.qiita.com/ja/articles/qiita-org-article

https://qiita.com/wa-chan222/items/1159dccc33ef483d60ba


##### 1：「・・・」マークをクリックし、「編集する」を選択
[![Image from Gyazo](https://i.gyazo.com/def74927e810b00de7a31b3cd41dc6e0.png)](https://gyazo.com/def74927e810b00de7a31b3cd41dc6e0)

##### 2：「公開設定」をクリック。
[![Image from Gyazo](https://i.gyazo.com/baf7fb4b8129f919ea838b349dacb22f.png)](https://gyazo.com/baf7fb4b8129f919ea838b349dacb22f)

##### 3：「Organization紐づけ」選択欄で紐づけしたいOrganizationを選択する
[![Image from Gyazo](https://i.gyazo.com/93125362843b1a609f9abdd98739d6cd.png)](https://gyazo.com/93125362843b1a609f9abdd98739d6cd)

##### 4：紐づけ後「記事を更新する」ボタンをおして完了！！
[![Image from Gyazo](https://i.gyazo.com/8653a01f9e3342a740fa1013cf11e902.png)](https://gyazo.com/8653a01f9e3342a740fa1013cf11e902)

##### 5:「@wa-chan222」の右隣にOrganizationの名前が追加されていることが確認:blush:
[![Image from Gyazo](https://i.gyazo.com/e1672114f9e0a9a597a75de3295a301d.png)](https://gyazo.com/e1672114f9e0a9a597a75de3295a301d)



## 紐づけ後に感じたこと
紐づけ後、思いがけずいいねをいただき、すごく励みになりました。
また、自分の記事がチーム内で役立つ情報になっていると知り、アウトプットの価値を、通常よりもさらに実感することができました。


## さいごにまとめ
紐づけは初歩的なことかもしれませんが、この記事を通じて、QiitaのOrganization紐づけが初心者にも簡単にできることをお伝えできたら嬉しいです。
これからもたくさんアウトプットして成長していきたいと思います！
生物物理屋が数理最適化でブラックジャックに勝つ手を探してみた話 後編その2

## はじめに
この記事は「[ただただアウトプットを癖付けるための Advent Calendar 2024](https://qiita.com/advent-calendar/2024/newbie2024)」に投稿した記事です。

[最初の記事](https://qiita.com/yotabouya/items/e63c53c5e18b3cf6a454#%E3%81%AF%E3%81%98%E3%82%81%E3%81%AB)にも書いた通り、私は生物物理の実験を専門にしている研究者です。
最近はデータ解析のため機械学習のコード開発も行っており、幸いにもその成果が[NeurIPSに採択されました](https://neurips.cc/virtual/2024/poster/93465)。

前々回から学習のため、今回はブラックジャックでの行動を最適化するという課題に取り組んでいます。
今回の記事では、前回定式化した問題を実際にpythonで実装し、最適化を行ってみた結果を報告します。

## 関連記事

#### 前の記事 「[生物物理屋が数理最適化でブラックジャックに勝つ手を探してみた話 後編](https://qiita.com/yotabouya/items/40563070a5c9d8769ee9)」

#### 次の記事「[【生物物理屋による論文紹介】複数種類の物理モデルを学習したシミュレーター](https://qiita.com/yotabouya/private/fb28d434248d78914a91)」

## 実装
次に、定式化した数理最適化問題を実装します。
今回こそ離散的な変数の最適化をおこないます。
実装したものを[こちらのリポジトリ](https://github.com/MasahitoUWAMICHI/optimize_blackjack)に置いています。よければご覧ください。

### ライブラリの選定
まずはpythonの数理最適化ライブラリを選定します。
ライブラリの一覧は[こちら](https://qiita.com/np_hsgw/items/0a7b55935bf944da8fc6)を参考にしました。

今回の問題設定は非線形かつ離散的な問題です。
したがって、非線形最適化ライブラリを選定する必要があります。

今回の問題設定だと、以下のような方針で最適化をおこなうことになります。
- 状態空間を定め、そこでの勝敗を計算する関数を定義する
- バースト状態とディーラーのターンにおける方策を与える
- それ以外の状態について、方策を与える
- 状態価値関数を計算する
- 評価関数を計算する
- 評価関数を最大化するような方策を求める

非線形であり、やや複雑な問題設定になるため、pyomoやGekkoあたりが適していると考えられます。

今回は、Gekkoを用いて最適化を行います。
Gekkoのドキュメンテーションが充実していたためです。

### 変数

まずは変数を定義します。
前回scipyでの最適化用に定義した変数を、Gekko用に変える形です。
まずは、Gekkoオブジェクトをインスタンス化します。
その後、インスタンスのArrayメソッドによって変数の配列を定義します。
この配列のそれぞれにVarメソッドにより定義された変数を割り当てれば完了です。
Varメソッドでの定義は、値の上下限と、整数かどうかという引数を取ります。
ここでは下限0,上限1の整数としました。

### 目的関数の定義

これも、scipy用に定義したものの流用を試しました。
評価関数を返す関数を、インスタンスのObjメソッドに渡すことで完了します。

### 書き換えその1

しかしながら、この定義の方法では動きませんでした。
方策すべてを使って評価関数を定義する式が複雑すぎて、Gekkoで扱われる範囲を超えていたためです。
このため、評価関数の内部計算のそれぞれをGekko用に書き換えることとなりました。

とは言っても、方策を反映した勝率を返すif文をインスタンスのif3メソッドに置き換えたことと、各状態における勝率を中間変数MVとして扱い、確率による加重平均をsumメソッドとArrayメソッドで書き直したくらいです。

## 書き換えその2

動くようにはなりましたが、なぜか最適化の結果としてすべての方策がスタンドになってしまっています。
勝率を最小化させてみても同じ結果なので、変数の参照にエラーが残っているようです。

どうもこの原因は、変数=定数となる対応関係を入れるときに、変数と定数を別々に定義して、通常の代入で処理していたことのようです。
これでは、python上での参照先を変えただけで、Gekkoでの等式とは認識されません。
定数との等式ならEquation,ほかの変数と等しいならConnectionをつかって、式を認識させてやる必要があります。

また、if3関数がまったく反映されていませんでした。
if3では値が非負ならTrueの扱いになっていたためです。
なお、方策から0.5を引いて判定させてもうまく動かなかったため、結局if3は使わず、方策をあたかも確率のようにして重み付け平均をとる操作を採用しました。

さらには、中間変数をMVで定義していたために、すべて制御変数になってしまっていました。
これをSVに変更し、状態変数として定義し直しました。

### 結果

まず、solveした際に表示される自由度が方策の数と合致するようになりました。
また、方策はすべて1として初期化したのですが、いくつかは0となったので、変数へのアクセスもきちんとできています。
さらに、各状態でスタンドおよびヒットを選択した場合の勝率と方策を比較したところ、より勝率が高い方策が選ばれていました。
Githubのリポジトリをpublicからprivateに変更する方法

## はじめに
ある日、映像授業でキャッチアップしており、差分を管理するために`github`で`public`リポジトリを作成しました。
しかし、その映像授業は有料コンテンツだったため、`private`に変更する必要が出てきました。
その際に、少し苦戦したのでアウトプットを兼ねて、この記事では、その変更方法を紹介します。

## 変更方法
1. 該当リポジトリのメニューの一番右に`settings`があるのでクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3552884/4b99599a-acb3-dc86-ec92-527dc1c3a1e9.png)

2. 一番下までスクロールすると`Danger Zone`がある
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3552884/efcb07d0-4abf-5a28-1411-b87b57a265b8.png)

3. `Danger Zone`の一番上に`Change repository visibility This repository is currently public.` とあり、`Change visibiity`というボタンがあるのでクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3552884/7d647408-2d09-2149-c069-42f6f3008f0a.png)

4. `Change to private`と出るのでクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3552884/0ff06c59-f03e-2f76-1653-27babb051c91.png)

5. `Make owner/repository_name`というモーダルが表示されるので、`I want to make this repository private`をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3552884/17f13839-3bd2-0961-0789-1ba38412f4e1.png)

6. 再度、確認画面のようなものが出現するので、`I have read and understand these effects`というボタンをクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3552884/65388a35-b047-b325-3b60-2617dc498807.png)

:::note info
<補足> 英語の文章を、簡単に要約
「一度プライベートにすると、いくつかの機能や評価が永久に失われるので、よく考えて決めてください」という警告メッセージ

プライベートリポジトリに変更により失われる主な機能：
- リポジトリのフォーク情報
- スター数やウォッチャー数の履歴
- パブリック時の統計データ
:::

7.警告メッセージを理解したならば、`Make this repository private`をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3552884/ec04255f-a24f-7fa1-05a7-cbc3506626b8.png)

8.Headerのリポジトリ名の右に鍵マークがあることを確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3552884/4f73a41b-2c7f-3ec6-7d84-b988d7ef7e1f.png)

## まとめ
`private`から`public`にするときも同様のアプローチで大丈夫そうです（試してないから断言はできない...）
セキュリティをすごく大事にしている`github`だからこそ、何回も警告してくるので心の中で本当にいいのか...?という気持ちになってしまいました。
勢いがあったり、大きいリポジトリは警告文をちゃんと読んで判断しないといけないですね（規模や勢い関係なく警告は確認しましょう）
Zabbixのメール通知にOCI Email Deliveryサービスを利用する

# 概要
[Oracle Cloud Infrastructure（OCI）](https://www.oracle.com/jp/cloud/)に構築したZabbixにおいて、メール通知にOCI Email Deliveryを利用します。

# 構成
<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2730992/79749960-e934-5168-f4da-1df19cde4550.png">

# 前提
以下を前提としています。
- ZabbixをOCI内のCompute上に構築していること

# 準備
## OCI Email Delivery
以下を参考にEmail Deliveryを設定します
- SMTP資格証明の作成
- 電子メール・ドメインの作成
- SPFの構成
- DKIMの構成
- 承認済送信者の作成

https://docs.oracle.com/ja-jp/iaas/Content/Email/home.htm

https://oracle-japan.github.io/ocitutorials/intermediates/sending-emails-1/

https://oracle-japan.github.io/ocitutorials/intermediates/sending-emails-2/

## Zabbix
Zabbixの管理>>メディアタイプからメール設定を行います
- 名前:任意
- タイプ:メール
- SMTPサーバー:OCIコンソールから開発者サービス>>電子メール配信>>構成を選択してSMTP送信情報-パブリック・エンドポイント
- SMTPサーバーポート番号:587
- SMTP helo:ドメイン名
- 送信元メールアドレス:承認済送信者で設定したメールアドレス
- 接続セキュリティ:STARTTLS
- 認証:ユーザー名とパスワード
- ユーザー名:SMTP資格証明で取得したユーザー名
- パスワード:SMTP資格証明で取得したパスワード

<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2730992/40312044-b512-06a9-4281-1551d1c67d38.png">
Not観客席経営：事業会社のマーケターに必要なスタンス

この記事は [Howtelevision Advent Calendar 2024](https://qiita.com/advent-calendar/2024/howtv) の23日目の記事です。

## はじめに

株式会社ハウテレビジョンでHead of Product & Marketingを務めている長﨑です。主に新卒事業（[外資就活ドットコム](https://gaishishukatsu.com/)）のプロダクト開発とマーケティング、アライアンスなどを担当しています。また、中途事業（[LIiga](https://liiga.me/)）の事業責任者も兼務しており、いくつかある役割の中で、今年はマーケターとしての観点から感じたことをまとめました。

## そもそもマーケティングとは？

マーケティングの定義は人や組織によって、それぞれあり、あまり議論したくないので、あくまで個人的な考えとして触れさせてください。

- 本来は、「広義のMarketing」（4P全てを捉える）　であるべきですが、一般的に言われがちなのは、「狭義のMarketing」（Communication領域）に限定されている事が多いと思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3939092/61c6ebbc-2766-cdf1-499e-8b9a12cdf84e.png)


では、当社におけるマーケティングの定義とは、
- **「Marketing = Market（顧客）に支持され続ける仕組みをつくる事」**

としています。つまりは、広義のマーケティングの視点を大切にしています。

また、これも個人的な解釈ですが、

- **「Market = 市場 = 顧客（ユーザー）一人一人の集積」**

と捉えています。どういう事かというと、「Market」という言葉を日本語訳すると「市場」ですが、そこに実体はなくて、「こういう（傾向の）人が居て、じゃあこの人たちは、こういうセグメントとして分けよう」とし、そこで初めて「市場」と定義される。という考えです。

つまり、

- Marketingとは、突き詰めると顧客（ユーザー）一人一人と向き合う事

と言い換えられます。

## 当社でのマーケターの役割

もう少し具体的な役割、業務としては、以下のように規定しています。

![Screenshot 2024-12-23 at 0.09.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3939092/2f97a8ad-6653-7e59-15ce-67bb6a7c2b57.png)


当社の様な、Web/Appプロダクトを中心に置いた、事業会社でのマーケターの役割は、「集客」の範囲を担う事が多いと思います。KPIとしては、toCであれば、会員数や、CV数、Active率、細かいところでは、イベント集客人数等。toBであれば、リード数等がそれにあたります。

業務遂行のポイントとしては、「KPI設定力」「リーダーシップ」「コミュニケーション領域の専門性」の3つです。

1. KPI設定力
    - 事業会社では、KPIはクライアントや誰かが決めてくれるわけではないので、決められた目標の達成を目指すだけではなく、そもそもの目標を設定できる力が求められます。
2. リーダーシップ
    - マーケターは、セールスの様に自身で販売したり、エンジニアの様に自身で開発をできるわけではなく、社内外の専門家と協力し、PJをリードしていく必要があります。（ここでいうリーダーシップは、役職ではなく、個人に依存するものと捉えてください）
3. Communication領域の専門性
    - 一方で、コミュニケーション施策の実行の専門性を持っているのもまた一つの側面であり、様々なチャネル、手法の引き出しを持っている必要もあります。

今回の当社のアドベントカレンダーで、マーケの文脈で書いてくださっているマーケターの皆さんも日々、こういった全体の業務領域を意識しながら、それぞれの役割を担ってくださっています。

## 狭義のマーケ（集客）領域だけを担えば良いのか？

個人的な考えとしては、NOです。

また、誤解を恐れずに言うと、プロダクトKPIを達成しているだけでもダメで、重要なのは、「事業に良い進捗をもたらしているかどうか」であり、

究極的には、短期売上の達成はもちろん、中長期でこの事業が成長する仕組みをつくれているのか、組織体制を含めて、担当する事業における全ての「結末に責任を持つ」事だと思います。

## Not観客席経営！レポート責任を持つ

マーケに限らず、機能別の部門, 職種では、油断をすると「観客席経営」になりがちです。

- 観客席経営とは
    - 第三者として、進捗を見守るだけ（口出しはするが、結末への責任は持たない）
    - 解像度が低い（事業、顧客への解像度が低く、過去の経験や一般論で語る）

実際に、私もそういう節がありましたし、今もそうならないように日々意識をしています。（意識をしないと、いつでもそうなってしまうという恐怖もあります）

「結末に責任を持つ」とは具体的にどういう事か？それは、「レポート責任を持つ」だと思います。

- 事業責任者として、経営チームへ事業進捗（短期業績、中長期方針策定）をレポートする
- プロダクト、マーケの責任者として、事業責任者へプロダクト進捗（KPI）をレポートする
- イベントの集客担当として、マーケの責任者へ集客進捗をレポートする　等々

最終的なレポートの場面を想像すると、「あ、これは絶対突っ込まれるな」とか「こういう観点も考えておくべきだな」となり、進捗の深まりが、数段変わってくる感覚があります。

今年、私はたまたま、マーケティング部門がプロダクト部門と統合し、その責任者となったり、中途事業部門の責任者を引き継いだりと、強制的に様々な立場として、様々な立場の人へレポートする機会に~~晒されました~~（恵まれました）。今まで「自分はマーケだから（会員獲得は順調だから）と逃げていた」ところから強制的に、あらゆる結末への責任を求められる事となり、マーケターとしての成長、自分なりの能力開花を感じられた一年になったと、個人的に振り返る事ができています。

## おわりに

当社では、あらゆる職種, 部門で、能力開花の機会が溢れています。

マーケターはもちろん、他職種でも、少しでもこの考えに共感してくださる方いらっしゃれば、ぜひ気軽にお話しましょう。

▼募集中ポジション

https://herp.careers/v1/howtv

▼会社紹介サイト

https://howtelevision.co.jp/

[https://www.notion.so/howtv/cc2f2fd7f22c4e4ca04913796058b7a2](https://www.notion.so/cc2f2fd7f22c4e4ca04913796058b7a2?pvs=21)
CodeBuild での SSM パラメータ取得方法の比較とベストプラクティス

AWS CodeBuild で SSM パラメータストアから値を取得する際、以下の2つの方法があります。

1. **スクリプト内で SSM パラメータを直接取得する**
2. **環境変数に事前に設定して利用する**

この記事では、この2つの方法を比較し、それぞれのメリット・デメリットや、環境変数を使う方法がベストプラクティスとなる理由を解説します。

---

## 1. スクリプト内で直接 SSM パラメータを取得する

#### メリット
- 柔軟性
  - パラメータ名を動的に生成できるため、特定の条件に応じたパラメータ取得が可能

- シンプル
  - 必要なときにパラメータを取得するため、スクリプトがシンプルになる場合がある

#### デメリット
- 処理速度の遅延
  - get_parameter の呼び出しごとに SSM API を利用するため、ネットワーク通信が発生する
    - 通常、1回の呼び出しに 50～300ミリ秒程度 かかる
    - 繰り返し取得が必要な場合は、累積で処理時間が増加する

- オーバーヘッド
  - boto3 クライアントの初期化や認証処理のオーバーヘッドが発生する

- 並列実行でのボトルネック
  - 同時に多数のプロセスが SSM API を呼び出すと、API レート制限やリソース競合が発生する可能性がある


## 2. 環境変数に事前設定して利用する

#### メリット
- 高速
  - 環境変数の参照はローカルメモリ上で行われるため、ほぼオーバーヘッドがない
  - SSM API を呼び出す際のネットワーク通信や認証の遅延が解消される

- スクリプトのシンプル化
  - スクリプトから SSM に関するロジックを排除でき、コードの可読性が向上する
  
- レート制限の回避
  - 事前に環境変数を設定することで、SSM API 呼び出し回数を削減できる
  
- 再利用性
  - 同じ環境変数を複数のスクリプトやプロセスで利用可能

#### デメリット
- 動的なパラメータ取得には不向き
  - パラメータ名を動的に生成したい場合や、実行中に異なる値を取得したい場合には対応が難しい
- セキュリティ上のリスク
  - 環境変数をそのままログに出力してしまうと、パラメータが漏洩するリスクがある 

項目 | スクリプト内で取得 | 環境変数を利用
| -- | -- | -- |
速度 | 数十～数百ミリ秒/回 | ほぼゼロ
柔軟性 | 高い | 中程度（静的パラメータ向き）
スクリプトの可読性 | SSM | ロジックが増える | シンプルに保てる
セキュリティ | シークレット値を直接扱う場合注意 | 環境変数の管理が必要
レート制限の影響 | 高い | 低い
並列実行での効率性 | 競合が発生しやすい | 安定している

## 結論: ベストプラクティス
基本的には以下の理由で環境変数を利用する方法を推奨する。

1. 速度が速い: 環境変数参照はローカル操作のため、ほぼ遅延が発生しない
2. 安定性が高い: 大量の並列プロセスが動作しても、SSM API レート制限の影響を受けない
3. 可読性が高い: スクリプト内で SSM API 呼び出しの処理を省略できるため、ロジックがシンプルになる

ただし、動的なパラメータ取得や複雑な条件が必要な場合は、スクリプト内で直接 SSM API を呼び出す方法が適している。
API Best Practices ~【Appendix】繰り返しフィールドの更新

## 【Appendix】繰り返しフィールドの更新

https://protobuf.dev/programming-guides/api/#updating-repeated-fields

repeated フィールドを更新する最悪の方法は、クライアントに置換リストを強制することです。
クライアントに配列全体を提供することを強制することには多くの危険性があります。
未知のフィールドを保持しないクライアントはデータ損失を引き起こします。
同時書き込みはデータ損失を引き起こします。
これらの問題が適用されなくても、クライアントはサーバー側でフィールドがどのように解釈されるかを理解するために、ドキュメントを注意深く読む必要があります。
空のフィールドは、サーバーがそれを更新しないことを意味しますか、それともサーバーがそれをクリアすることを意味しますか？

### 修正1
クライアントが配列全体を書き込み時に提供することなく、配列に要素を置き換え、削除、または挿入できるようにする、repeated フィールド用のフィールドマスクを使用します。

### 修正2
リクエストプロトに個別の追加、置換、削除配列を作成します。

### 修正3
追加またはクリアのみを許可します。
繰り返しフィールドをメッセージでラップすることで、これを行うことができます。
存在するが空のメッセージはクリアを意味し、それ以外の場合は、繰り返し要素は追加を意味します。

---

取り急ぎで置換リストを強制する状態になっていることが多い印象。
要件によるとも思うので、適切な実装を選択していきたい。
API Best Practices ~【Appendix】繰り返しフィールドを返す

## 【Appendix】繰り返しフィールドを返す

https://protobuf.dev/programming-guides/api/#returning-repeated-fields

repeated のフィールドが empty の場合、クライアントはそのフィールドが単にサーバによって入力されなかっただけなのか、それともそのフィールドのバッキングデータが本当に空なのかを判断することができません。

これを解決する具体的な方法は、フィールド読み取りマスクを使用することです。
フィールドが要求された場合、空リストはデータがないことを意味します。
フィールドがリクエストされなかった場合、クライアントはレスポンス中のフィールドを無視すべきです。

---

明示的に欲しいと request したもの以外は見ないし、欲しいといったものは response を信用する。
でも聞いてみたらサーバでミスってたごめんね。の場合は多そうなのでコミュニケーションとれる場合はとっていきたいですね。
葬送のCSS（CSSの進化を静かにたどる）

長い旅を続けていると、ふと振り返る瞬間がある。遥か昔に置き去りにしたものたちが、今の私たちをどれほど形作っているのかを思うと、少しだけ胸が締め付けられる。

この物語は、Webレイアウトの歴史を静かに振り返るものだ。かつての手法やアイデアがどのように生まれ、どのように消えていったのか。そして、どんな風に次の時代へと受け継がれたのか。

CSSと共に歩んだこの長い旅を振り返れば、その歴史は試行錯誤の連続だった。


## 1990年代：静的なページとtableレイアウトの時代

あの頃は、まだWebという世界が産声をあげたばかりの時代だった。ページはただの「文書」だったんだ。見た目のデザインはおまけみたいなもので、構造の中にスタイルを埋め込んで、なんとか整えていた。

思い出すよ、「tableレイアウト」が支配していた日々を。デザイナーたちはテーブルのセルにデザインを押し込めて、まるでパズルを組み立てるように苦労していた。表の中に空白のセルを使って「スペーサー」を配置したり、無理やりグリッドを作り出していたんだよね。あれは手間の塊だったけど、デザイナーたちはそれを当然だと思っていた。

でも、そんな方法には限界があった。変更があるたびに、すべてを作り直さなきゃいけなかったからね。それでも、あの不器用な手法は、初めてWebデザインに「整える」という概念をもたらした。


## 2000年代前半：CSSの台頭とセマンティックWeb

時代は移り変わり、CSSが静かに登場した。あれはまるで、誰も気づかないところに芽吹いた小さな草花みたいだった。CSSがもたらした変化は、まさに「見た目」と「構造」を分けるという考え方だった。デザインのルールを文書から切り離して、別の場所にまとめることで、変更が圧倒的に楽になったんだ。多くのデザイナーがその恩恵に気づくまでには少し時間がかかったけど。

とはいえ、すべてがスムーズに進んだわけじゃない。当時のブラウザはそれぞれ独自の解釈でCSSをレンダリングしていたから、「対応ブラウザの確認」という作業が必須だったんだ。IEとNetscapeが対立する時代、同じスタイルが異なる見え方になることなんて日常茶飯事だった。

「セマンティックWeb」という概念も、この頃に注目を集めた。意味を持つマークアップを書くことで、検索エンジンやアクセシビリティを向上させる動きが広まったんだ。でも、それは理想論に近くて、現場では「とりあえず動けばいい」という現実との板挟みも多かった。


## 2000年代後半：グリッドシステムとモダンブラウザの普及

ブラウザ戦争が終わりに近づくと、モダンブラウザが少しずつ普及していった。それに伴って、Webデザインの世界にも新たな風が吹き込まれた。それが「グリッドシステム」だった。

あの頃、「960GridSystem」というシンプルなグリッドシステムが話題をさらった。横幅を12のカラムに分けて、それぞれの要素を整列させる仕組み。これが登場してから、Webデザインが一気に洗練されたよね。

とはいえ、実装にはまだまだ手作業が多くて、デザイナーはよくこう言ってた。「グリッドに合わせるのはいいけど、細かいズレが気になるんだよ」って。それでもこの考え方が浸透したことで、複雑なレイアウトをスムーズに構築する土台ができたんだ。


## 2010年代前半：レスポンシブデザインの登場

スマートフォンが急速に普及し、画面サイズの多様化が進む中で生まれたのが「レスポンシブデザイン」だった。デザイナーたちは、どんなデバイスでも美しく表示されるように頭を悩ませていたよ。

最初はメディアクエリを使ってスタイルを切り替えるだけだったけど、その後の進化で、より柔軟なレイアウトが可能になった。でも、実際にやってみると「この画面サイズだけ崩れるんだけど！」という声が絶えなかった。

それでも、この考え方がWebデザインに革命をもたらしたのは間違いない。「ひとつのデザインで、すべてのデバイスに対応する」という理想が、現実のものとなったんだ。


## 2010年代後半：FlexboxとCSS Gridの普及

FlexboxとCSS Gridが登場したのは、この時代の象徴と言える出来事だったね。それまでデザイナーたちは、浮動要素（float）やインラインブロックといった不完全な手法でレイアウトに挑んでいた。どれも工夫の余地がある手法だったけど、やっぱりどこか限界があったんだ。

この時代、Flexboxがもたらしたのは、親子関係でレイアウトを管理できるという発想だった。横一列に並べたり、均等に間を空けたりするのが、もう特別な手法じゃなくなった。CSS Gridはさらにその上をいく。2次元でレイアウトを組み立てる新しいアプローチは、まるで建築士が地図を描くような感覚だったよね。

ただ、最初はみんな戸惑った。だって、これまでの常識を覆すような書き方だったから。でも、試行錯誤を繰り返すうちに、これこそが理想のレイアウトだ。って気づく人が増えていった。


## 2020年代：ユニットの多様化とダークモード対応

最近のことになるけど、この時代はCSSの進化がさらに加速しているよね。たとえば、clamp()やmin()、max()みたいな新しい単位が生まれたことで、デザインの柔軟性が大きく広がった。これまではピクセルやパーセントだけに頼っていたけど、いまや動的な値を簡単に計算して指定できるようになったんだ。

そして、忘れちゃいけないのがダークモード。背景を暗くして目に優しいデザインが求められるようになったのも、この時代特有の変化だね。CSSではprefers-color-schemeメディアクエリが登場して、ユーザーの設定に応じたテーマ切り替えが簡単になった。

もちろん、新しい手法に慣れるのには時間がかかるけど、デザイナーたちはこれを武器に、さらに洗練された表現体験をや体験を提供しようと日々挑んでいる。


## 受け継がれる記憶、形を変える仕組み
長い旅路の果てに、私たちは数えきれないほどの記憶を背負い込む。過ぎ去った時代も、消え去った「仕組み」も、その一つひとつが、今の私たちを形づくる礎となっている。

初めて触れたテーブルレイアウトの世界は、きっと無骨で、不器用で、けれど温かいものだった。レスポンシブデザインの登場に胸を躍らせ、FlexboxやCSS Gridで自由を手に入れたときの歓喜は、今も鮮やかだ。

どんな仕組みも、どんな発想も、やがては役目を終え、記憶の中へと消えていく。それでも、それらが残した足跡は、次の歩みを支える大地となる。そして私たちは、その大地の上をまた一歩ずつ歩んでいくのだろう。

この旅は、決して終わることはない。けれど、だからこそ愛おしい。移りゆく時代の中で、私たちは何度でも、新しい何かを見つけていける。そうして振り返るとき、きっと「過去」が教えてくれるのだ。かつての試みが、どれほどの未来を支えていたのかを。

静かに、けれど確かに。これが「CSSの葬送」であり、また新たな旅の始まり。これからも、共に歩んでいこう。


## あとがき
なお、本記事で触れた年代区分は大まかなものであり、技術の普及速度や採用状況には地域差やブラウザごとの対応状況が影響しています。そのため、すべての進化が一律に進行したわけではない点をご了承ください。
MarkdownAIで「今日」を教えてくれるアプリを作る

# 概要

これは[Markdown AIのサーバーAI機能を使ってWebサイトを作ってみよう by MarkdownAI Advent Calendar 2024](https://qiita.com/advent-calendar/2024/markdownai)の23日目の記事です。

Markdown AIを使ってサクッとアプリを作ってみました。

# どんなアプリか

ボタンを押すと今日の日付から「こんな日だよ」と抽象的な回答を表示してくれるアプリです。

https://mdown.ai/content/e087587e-a1a7-4627-8dc6-081319539ad5

![今日はなんの日](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/302006/d73120e8-1965-1328-b3ab-a9a8f357b57a.png)

# AIへの指示

プロンプトはこんな感じにしました。

```text
あなたは歴史の学者で、今までにおきた出来事を記憶しています。
あなたの役割はユーザーから入力された日付を確認して、その日にちなんでどんな日なのかを一文で言い表すことです。
答えは30文字以内にしてください。

入力される日付の例：
2024年3月1日
2024/3/1
2024/03/01
2024-3-1
2024.3.1

回答例：
〇〇な日
〇〇する日
おでんを食べる日
ちょっと遠くへ散歩に出かける日

回答しなくて良いので同じ日付に対して10個の回答を用意してください。
その中から毎回異なる答えをランダムに1個選び、1個回答してください

ルール
直接的な表現は避け、間接的で抽象的な表現にしてください
NG：クリスマスの日
OK：サンタクロースからのプレゼントをあける日

同じ日付の場合は同じ回答をしないでください。
```

## 工夫した点

日付に強い歴史学者という設定にして、抽象的な回答をしてもらうように指示しています。
抽象的、と言わないと建国記念日など面白みのない回答が返ってくるためです。

あと回答例やこういう回答にしてほしいという指示を出すと狙った回答が出やすいです。

# 感想

AIモデル作るだけなら10分もかからずで、装飾などにこだわると1時間程度かかりました。
さくっと作って公開できるので、結構楽しく遊べるサービスだなと思います。
[git initして警告が出た時の対処]Using 'master' as the name for the initial branch. This default branch name

##  概要
`git init` したら、下記のようなhint が出てきたので、その場合の対処法を書きます。
(git init でGitリポジトリを初期化した際に、デフォルトで master という名前のブランチが作成されたケース)

```
git init
hint: Using 'master' as the name for the initial branch. This default branch name
hint: is subject to change. To configure the initial branch name to use in all
hint: of your new repositories, which will suppress this warning, call:
hint: 
hint:   git config --global init.defaultBranch <name>
hint: 
hint: Names commonly chosen instead of 'master' are 'main', 'trunk' and
hint: 'development'. The just-created branch can be renamed via this command:
hint: 
hint:   git branch -m <name>
Initialized empty Git repository in /Users/hoge/work/Go-Project/Go-Learn/.git/
hoge@hogenoMacBook-Pro Go-Learn % git config
usage: git config [<options>]
```


## 解説
git initコマンドを実行したことで、Gitリポジトリが初期化されて、新しいブランチとしてmasterブランチを作成しました。
が、最近のGitでは、master という名前の代わりに main や他の名前を使うことが推奨されており、これに関する警告が表示されているようです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/613261/31fc5f18-924b-399a-fe29-e27fd6bbd79e.png)


## 対処法
Gitの設定を変更すればok。

手順1
グローバル設定を変更する。
```
git config --global init.defaultBranch <name>

-> ex) git config --global init.defaultBranch main
```


これにより、今後作成するリポジトリの初期ブランチ名が main になります。

手順2
masterブランチからmainブランチに変更する。
現在のブランチ名の変更: 既に作成されたブランチの名前を変更したい場合は、
```
git branch -m <name>

-> ex) git branch -m main 
```

以上です！


## まとめ
* 新しいリポジトリで使用するデフォルトのブランチ名を変更したい場合は、
`git config --global init.defaultBranch <name>`
で設定できる。
* `git branch -m <name>` で現在のブランチ名を変更することができる。
過去の自分に教えたい、ソフトウェア品質の心得

こんにちは、Naotoです！Ψ

ソフトウェアの品質って、エンジニアとして避けて通れないテーマですよね。  
そもそも品質って何だろう？どんな基準で「良い」「悪い」を判断しているのか？  
そんな疑問を一緒に考えていきましょう。

## 品質とは？

「品質」とは一言で言うと、**製品やサービスがどれだけ期待や要求を満たしているか**を表すものです。  
この「期待」や「要求」には、ユーザーの期待、仕様、基準、そして開発者自身の価値観も含まれます。

たとえばソフトウェアの場合

- **ユーザー視点の品質**  
  使いやすく、安定していて、価値を提供できるもの。
- **仕様視点の品質**  
  要件通りに機能が実装されていること。
- **内部的な品質**  
  コードが読みやすく、保守しやすい状態。

---

## ソフトウェア品質の2つの側面

### 1. 外部品質（ユーザーが感じる品質）
ユーザーやステークホルダーが直接体験する品質です。  
私は特に非機能の部分を重視して取り組みます。経験上ボトルネックになりやすい部分ですので。

- **機能性**: 期待通りの動作をしているか？  
- **信頼性**: バグが少なく安定しているか？  
- **使いやすさ**: UIが直感的で操作が分かりやすいか？  
- **効率性**: パフォーマンスは問題ないか？  
- **互換性**: 他システムや環境と相性が良いか？  

### 2. 内部品質（開発者が見る品質）
こちらはソフトウェアの内部構造やコードの状態です。開発者にとっての重要な視点。
プログラマーの視点で内部品質は考えてよいのでは？と日々思ってます。どでかいシステムだと設計書の精緻化はマストになってますね。

- **保守性**: コードが理解しやすい、修正しやすい。  
- **再利用性**: 他でも使えるコードか？  
- **拡張性**: 機能追加や変更が簡単か？  
- **テスト容易性**: テストしやすい設計か？  
- **効率的な設計**: 無駄が少なく最適化されているか？  

内部品質が高いと、長期的に開発コストを抑えられるし、チームの開発速度もアップします。

---

## 品質を判断する基準

品質を「良い」とするか「悪い」とするかは、以下の基準で考えてます。
要件整理ができているか？プログラマーの質で雑なコードになっていないか？無駄なタスク・効率的な作業を模索できているか？

1. **要求との適合**  
   ユーザー要件や仕様をちゃんと満たしているか？  

2. **期待の満足度**  
   「動けばいい」じゃなくて、「使って気持ち良い」「価値を感じる」と思えるか？  

3. **欠陥や問題の有無**  
   バグが少なく、修正も簡単な状態か？  

4. **定量的な評価**  
   テストカバレッジやレスポンス速度など、具体的な数値目標を設定。  

5. **コストと時間のバランス**  
   品質向上は大事だけど、やり過ぎると納期遅延やコスト増につながります。  

---

## QA（品質保証）とQC（品質管理）の違い

品質に関わる活動として、よく出てくるのが**QA**と**QC**。違いを整理してみました。
記載してみましたが、違いがあるんだなぐらいで私は良いと思ってます。同じ部門の人が担当することが多いと思いますので。

| **項目**            | **品質保証（QA）**                | **品質管理（QC）**             |
|---------------------|----------------------------------|--------------------------------|
| **目的**            | 問題の未然防止とプロセス改善      | 問題の検出と是正               |
| **焦点**            | プロセス全体                     | 製品やサービスの結果            |
| **アプローチ**      | プロアクティブ（予防的）          | リアクティブ（反応的）          |
| **活動範囲**        | 規格や手順の作成、監査            | 検査、テスト、統計的品質管理など |
| **適用範囲**        | 開発・製造プロセス全般            | 製品や成果物                   |

### QAとQCの相互補完的な関係
- **QA**は「正しいやり方で作る仕組み」を設計します。  
- **QC**は「その結果、品質が正しいか」を確認します。  

---

## 品質を高めるためのポイント
<p style="color:red; font-size:20px;"><strong>※重要</strong></p>
一番の本記事で伝えたい部分です。システム開発している方々に刺さると思います。

- **「動く」と「良い」は違う**  
  動くコードは最低限。「良いコード」は保守性、読みやすさ、再利用性が高いこと。

- **テストはコストではなく投資**  
  テストを書く時間がない、は言い訳。テストはトラブルを防ぎ、未来の開発速度を守る保険です。

- **レビューは学びの場**  
  コードレビューで指摘を受けるのは恥じゃない。成長のチャンス！

- **仕様書の曖昧さがバグを生む**  
  疑問点を放置せず明確化しよう。ここが品質の第一歩。

- **技術的負債を放置しない**  
  「後で直そう」はほとんど直せない。「未来の自分」に優しいコードを。

- **品質はチーム全員の責任**  
  QAやテスト担当者だけでなく、チーム全員で意識すべき課題。

- **ユーザー視点を忘れない**  
  完璧なコードでも使いにくければ意味がない。ユーザーの体験を最優先に。

---

## 最後に

品質は人やチーム次第で変わる生き物みたいなものです。  
人の入れ替わりがあっても品質を落とさず、ユーザーに価値を届けるにはどうするか？  
日々考え、チーム全員で取り組む必要があります。

最後まで読んでいただきありがとうございました！  
よければ以下の記事もチェックしてみてください👇  
[品質に関わるコードレビューとエビデンスの重要性](https://qiita.com/Z-Naoto/items/b715628b9ffb3633c185)
【個人的に】PowerBIに関する活動を振り返る

## はじめに
この記事は、「Microsoft Power BI Advent Calendar 2024」の23日目の記事です。

https://qiita.com/advent-calendar/2024/powerbi

今回は技術に関する内容は一切ありませんので、緩い感じになっております。

## 投稿主について
自分をご存じない方について一応紹介します。
この記事の投稿主は、普段RPAツール(Ui〇a〇h)を使って顧客の業務自動化の開発～保守まで幅広く行っております。
なお業務でPowerBIに触れたことは一度もなく、現在の会社に入社して間もなく7年になりますがPowerBIを使用する案件に参画したことはありません。
ちなみに過去、PowerBIに関するブログ投稿は2度行いました。

https://qiita.com/saosao885/items/a16807989ba71636075d

https://qiita.com/saosao885/items/aaf38e5b33633df77c65

## 今期の活動記録
私は業務上、PowerBIに触れる機会が全くなく情報取得はYoutubeやMicrosoftに関するネットの記事を読むか、アドベントカレンダーの時期になるとやる気を出して投稿...がメインになってきます。

で、今年の結果ですが
・RPACommunityにおけるPowerBI関連のイベント：参加できず
・PowerBI Weekly Newsの視聴：月1～2回
という感じで、なかなか学習時間の確保が難しい1年でした。

## 原因
### ①業務量の多さ
今年は厄年(本厄)の影響？かどうかはさておき、本業務がとにかく多忙でした。
1～3月は業務量が多く22時ごろまでやって引継ぎ...もあり、出張もありでバタつき、4～12月は最初の3か月はまあ落ち着きを見せていましたが7月になりほぼワンオペで回し...となり業務とプライベートのバランスが取れなくなってしまったことです。
PowerBIに関する業務に今のところ関われないというのもありますが、案件に入るためにはある程度の理解やブログ投稿などによる痕跡や資格取得も欠かせません。
現状の業務量見直しも必要ですね。

### ②優先順位を見失う(<b>仕事の業務は除く</b>)
昔から自分のやりたいことにがむしゃらな自分はなんでもやりたがりなのでついつい「やる！」といってはやりたいことが多すぎて優先順位を見失うことがあります。
昨今は生成AIや各種サービスの登場により技術や情報量の多さもあり、技術に関する情報自体は多少なりとも仕入れておきたいというエンジニアの性？みたいなものがあります。
来年はPowerBIのニュース動画視聴やイベント参加、ブログ記事の投稿についても優先順位を持って取り組みたいです。


### ③やる気不足？
これは上記①と②に連動していますが、
<b>やることが多い/業務量多い
→疲労感増大
→着手までたどり着けず...スタミナ不足で集中力低下</b>
という負のサイクルになっていました。

自己学習なので当然賃金は発生しませんし、業務との優先順位を比較しても後になってしまいます。
それでもせっかくPowerBIに関するスキルも早く身につけて活躍する...そのイメージをして業務を早く終わらせることも必要になってきます。

## まとめ
技術情報は一切なく、振り返りになってしまいましたが今後は大学院でデータサイエンスや統計に関する研究もやりたいのでPowerBIも理解しておきたいです。
業務自動化を構築する自分自身も効率化を行ってPowerBIの学習時間を確保していきます。

最後までお読みいただきありがとうございました。
mindの研究 その95

# 概要
mindが、謎なので調べてみた。
練習問題、やってみた。

# 練習問題
文字列を連結せよ。

# サンプルコード

```


メインとは
　文字列1は　文字列
　文字列2は　文字列

　「あれ」を　文字列１に　入れ
　「これ」を　文字列２に　入れ

　「"data1"」と　「 "data2"」を　合成　一行表示する
　文字列２をつみ　文字列１を　合成　一行表示する

　「最初の文字列」を　第一合成文字列設定
　'&'を　さらに一文字合成
　「　次の文字列　」を　さらに合成
　「　次の次の文字列　」を　さらに合成
　「　次の次の次の文字列　」を　さらに合成　一行表示する



```

# 実行結果

```
>moji1
"data1" "data2"
これあれ
最初の文字列&　次の文字列　　次の次の文字列　　次の次の次の文字列　

```

以上。
GASでスプレッドシートのフィルタ条件を複数設定する（OR条件）

これだ！という正解の記事が見当たらなかったので備忘として纏めておきます。

# 困ったこと

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/445087/ddf65861-f518-1e2f-397d-9421ff9e7059.png)


スプレッドシートのフィルタをGASで自動作成し「前月の末尾より後の日付」である行のみ表示したいので次のようなコードを書いた。

```js
function addFilterToSheet() {

  //前月の末日を取得
  const today = new Date();
  const firstDayOfCurrentMonth  = new Date(today.getFullYear(),today.getMonth(),1);
  const lastDayOfPreviousMonth  = new Date(firstDayOfCurrentMonth - 1);

  const sheet = SpreadsheetApp.getActiveSheet();

  //フィルタ条件を設定
  const criteria = SpreadsheetApp.newFilterCriteria()
    .whenDateAfter(lastDayOfPreviousMonth)
    .build(); 

  //既存のフィルタを削除
  if(sheet.getFilter() != null) {
    sheet.getFilter().remove();
  }

  //フィルタを作成
  sheet.getDataRange().createFilter().setColumnFilterCriteria(1, criteria);

  return false;
}
```
すると、フィルタ結果として空白セルまで表示されなくなったのでOR条件を追加したい。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/445087/c3f1190f-d2c0-fc94-d1c0-5f5aaa9703de.png)


# 実現したいこと

1. スプレッドシートのフィルタをGASで作成（更新）する
2. 同じ列に複数のOR条件を設定して「前月の末尾より後」または「セルの値が空白」であるフィルタを作成する


# 結論
条件を数式で作成する


# 修正後

### 条件
A列の日付を「前月の末尾より後」または「セルの値が空白」でフィルタする

### コード

```js
function addFilterToSheet() {

  //前月の末日を取得
  const today = new Date();
  const firstDayOfCurrentMonth  = new Date(today.getFullYear(),today.getMonth(),1);
  const lastDayOfPreviousMonth  = new Date(firstDayOfCurrentMonth - 1);

  const sheet = SpreadsheetApp.getActiveSheet();

  //条件となる数式を文字列で作成
  const formula = '=OR(A2>DATE(' + Utilities.formatDate(lastDayOfPreviousMonth,'JST','yyyy,MM,dd') + '),A2="")';

  //数式をフィルタ条件として設定
  const criteria = SpreadsheetApp.newFilterCriteria()
    .whenFormulaSatisfied(formula)
    .build(); 

  //既存のフィルタを削除
  if(sheet.getFilter() != null) {
    sheet.getFilter().remove();
  }

  //フィルタを作成
  sheet.getDataRange().createFilter().setColumnFilterCriteria(1, criteria);

  return false;

}
```
### 実行結果
ちゃんと空白セルも表示されました
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/445087/e912fe0c-a2c3-0181-3d14-f6aa92168d7b.png)

フィルタにはカスタム数式がセットされています
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/445087/eae592e4-de91-5178-d005-3c0a06c2d228.png)

# おまけ
私が実現したかったこのコードでは「GASをトリガーしたタイミングでフィルターを更新する」前提なので、毎月実行しないとフィルタ条件が古いままです。

一回数式をセットしたらずっと「前月の末尾より後」または「セルの値が空白」でフィルタしたいのであれば、数式の部分に日付をテキストで埋め込むのではなく、スプレッドシートの関数をセットしてやればよいです。
### 数式の書き換え 

```js
const formula = '=OR(A2>DATE(' + Utilities.formatDate(lastDayOfPreviousMonth,'JST','yyyy,MM,dd') + '),A2="")'
```
任意のタイミングでフィルタしたいので、数式には日付を固定で設定していますが、EOMONTH関数を書いてやればスプレッドシートを開いたタイミングですぐにフィルタされます。
```js
const formula = '=OR(A2>EOMONTH(TODAY(), -1),A2="")';
```

このやり方では「月が変わった直後」にスプレッドシートを開くと前月以前がすべてフィルタされてしまうので、私の場合は使っていません。