OmniAICreator/Qiita-1.07M huggingface dataset:
【Mac】コマンドでデスクトップ上のアイコンを非表示にする方法

## 非表示にする

ターミナルで`defaults write com.apple.finder CreateDesktop false && killall Finder`を実行するとデスクトップ上のアイコンを非表示にできます。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/fe720d60-6238-483c-a404-8bad2f5210e9.png)

```terminal
defaults write com.apple.finder CreateDesktop false && killall Finder
```
実行後は以下のようにアイコンが非表示になります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/119aa220-bf68-46c6-b73a-b88ab3eadd38.png)

## 再表示する

際表示するには以下のコマンドを実行します。

```terminal
defaults write com.apple.finder CreateDesktop true && killall Finder
```

## 現在の設定値を確認する

現在、非表示の状態なのか確認するには以下のコマンドを実行します。

```terminal
defaults read com.apple.finder CreateDesktop
```

結果が`false`であれば非表示、`true`なら表示
MobaXterm を macOS（Apple Silicon）で使う。その2

数時間 Wine のインストールで四苦八苦したのですが、そもそもの目的である MobaXterm は macOS + Wine で使えるのかをまず確認したく、方針転換。

# CrossOverをインストールする
Mac Ports でだめなら、Homebrew で試してみたら、、、というのもありますが、パッケージで提供されている Wine を探しました。

Wine も派生ソフトが色々あるらしく「WineBottler」「Wineskin」といった無償で使えるものが見つかりますが、ここ数年更新されていない様子です。更新が止まってしまっているソフトは、セキュリティ的にも利用は躊躇しますね。
Wine ベースの商用ソフト「CroossOver」が評価版として期間限定ながらも無償で利用できるので、これで試してみることにします。

Free Trial をダウンロード。

https://www.codeweavers.com/crossover/download

ダウンロードした zip ファイルを展開すると、app ファイルができるので実行するだけ。Wine のインストールに四苦八苦していたのを考えると、泣けるほど簡単です。


# MobaXtermをインストールする

MobaXterm の Home Edition をダウンロード。

https://mobaxterm.mobatek.net/download.html


CrossOver を起動し「未登録のアプリケーションをインストールする」を選択。

![スクリーンショット 2025-02-23 16.43.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/375120/51a97f54-74a9-4896-a01d-bab79826e013.png)

「インストール」を押下。

![スクリーンショット 2025-02-23 16.50.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/375120/9c7a005b-9b0d-4fc6-85cc-41f4efc4d44d.png)

インストール先は「新しいボトル」とします。ボトル名はとりあえず「MobaXterm」としておいて、ボトルタイプは「Windows 10 64ビット」にしました。

![スクリーンショット 2025-02-23 16.52.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/375120/e34ac85e-d3b0-480a-ae6d-b76e9792ff6b.png)

次にインストーラーを指定しますが、先ほどダウンロードした MobaXterm の zip ファイルを展開してできた msi ファイルを選択します。

![スクリーンショット 2025-02-23 17.02.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/375120/a51019d0-d4dd-48a1-8190-36b6511062d2.png)

MobaXterm のインストーラーが立ち上がってくるので、インストールを実行。
ライセンスへ同意し、インストール先のディレクトリの指定は初期値のまま進めます。

![スクリーンショット 2025-02-23 17.07.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/375120/e57a702b-08c4-4358-acc8-e18af7ced19d.png)

特にエラーもなく終了。

![スクリーンショット 2025-02-23 17.08.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/375120/0734c761-65ab-4df3-aeab-f0489d53a79a.png)

MobaXterm を起動。

![スクリーンショット 2025-02-23 17.10.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/375120/112cd30a-773d-40fb-b2eb-3fac1be258fd.png)

あっさり起動！！感動。。。
初回の起動やCrossOverが終了している状態からの起動は、5〜10秒程度待ちますが、CrossOverが起動した状態からの2回目以降の起動は数秒程度です。

AWS上の Linux EC2インスタンスへ接続しましたが、ファイル送受信など機能的・操作性ともに問題なさそうです。

![スクリーンショット 2025-03-01 23.38.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/375120/01f0df62-7dfd-48ad-8cbe-0d33471cd95b.png)

MobaXterm が macOS ＋ Wine 上でも問題なく動くと確認できたので、再度オープンソース版の Wine のインストールにチャレンジしたいと思います。
はじめに

# はじめに

## 著者略歴

### 略歴

* 1991年京都生まれ
* 大学卒業後にオンサイト保守員、いわゆるメーカ系CEとして10年ほど勤務
* HWメーカの凋落とクラウドの台頭からジョブの将来性を懸念し独立系SIerへ転職
    * アプリより低レイヤの技術スタックで立ち回るインフラエンジニア
    * PoC支援やプリセールス、提案書作成、案件管理などもリーチ
    * プライムとして顧客折衝やBPさんハンドリングしながらポスト案件推進

### ポリシー

* 仕事は遊び、遊びは仕事
    * 仕事は遊びじゃないとはいいますが...ランクマッチとか真剣にやりません？
    * 仕事を仕事と捉えると給料をもらうことに最適化されてポンコツになるので、
    仕事は遊びと解釈するほうが、結果的にパフォーマンスが出たというエピソード
    <br>
* ロジックよりもハートだいじに
    * 人間のOSはロジックじゃなくてハートだと思う
    * ロジックはあくまでOS上で動くアプリ
    * 感情を考慮して立ち回ったり、寄り添うほうが結果的に合理的と思う
    <br>

### 趣味

* 戦略・戦術級ゲーム
* 一人カラオケ
* サバイバルゲーム
* DTM


## アウトプット方針

### アウトプットの目的

* 仕事やプライベートで培った知見を文字で残しておきたい

### アウトプットのねらい

1. 技術ブログを書くことで良質なアウトプットの練習をしたい
1. 記事のアウトプットにより自己満足したり、反響をモチベーションにしたい
1. 記事繋がりでコミュニケーションの機会が発生するなら素晴らしい

### アウトプットの傾向

1. オンプレ
    1. サーバ
        1. HPE
        1. DELL
        1. Fujitsu
    1. ストレージ
        1. NetApp
        1. PureStorage
        1. Fujitsu
    1. ネットワーク
        1. Cisco
        1. Arista
        1. Allied
        1. Juniper
    1. ハイパーバイザ
        1. vSphere
        1. AHV
        1. OCP-Virt
        1. Hyper-V
        1. Citrix
    1. OS
        1. Windows
        1. Linux
1. クラウド
    1. パブリッククラウド
        1.  AWS
        1.  Azure
        1.  GCP
    1. 3rdParty
        1. FinOps
        1. O11Y
        1. IaC
        1. BaaS
1. オンサイト保守
    1. 役立つ小技
        1. ヒアリング
        1. アウェーでの立ち回り
    1. おすすめの道具
    1. トラブルシュート
        1. 切り分け
            1. KT法
            1. 演繹法
            1. 帰納法
            1. ブレスト
1. 概念とヒント
    1. 具体と抽象のピント合わせ
    1. 水平展開と深堀り
    1. ロジックとパッションの使い分け
    1. 期待値コントロールと信頼貯金の使い方
    1. PDCAとOODAの複合エンジン
    1. 脳の仮想化とフェーズごとでの役割人格分離
    1. 仕事全体のゲーミフィケーション
        1. オンサイト保守のモンハン化
1. 資格取得体験記

### ひとこと

* せっかく記事に興味持っていただけたようなので、
　お手数ですがフォローいただけますとわたくし大変よろこびます！
【ポエム】コミュニティ活動でアウトプットする意味を考えてみた

いつも記事を読んでいただきありがとうございます！
モブエンジニア（[@mob-engineer](https://qiita.com/mob_engineer))です！

本日（2025.03.01）に参加したJAWS DAYSへボランティア参加するなかで**コミュニティ活動でアウトプットする意味**を考えるきっかけになりましたので、思考を整理するために記事として文書化しました。

個人的意見がかなり混ざっていますが、お気軽に読んでいただければ幸いです。

:::note info
JAWS DAYSイベントレポート（ボランティア編）は明日執筆します...
:::

## コミュニティ活動でアウトプットする意味

個人的に最適解を持っているわけではないですが次のことがあると思います。

- 自身の知的好奇心・承認欲求を満たすこと
    - 私が毎日ブログ執筆しているのもこれが理由だったりします
- コミュニティ内での認知度向上につなげていく
    - 今回は本名で参加しましたがペンネームのほうが認知される印象を持ちました
- アウトプットを通じた新たな気づき
    - アウトプット活動を行う中で**自身の思考を整理することができ、新たな視点での気付きを得られるきっかけ**になると思います

## アウトプットした先にあるものは？

とは言え、アウトプット活動をしていく中で**その先に何が待っているのか**は整理できていない状況です。

個人的な意見ですが、**アウトプット活動=自己実現のための手段**として考えているので、その先に待っているものは**自身の目指すべきキャリア像**があるのではないかなぁと思いました。

今日は夜が遅いのでここまでにします。
そのうえで、本日参加したJAWS DAYSから得られた経験は数多くありましたので、複数回に分けてブログ形式でまとめていきたいと思います。

最後までお読みいただきありがとうございました
Shopify CLI を使って VS Code でテーマ開発する方法

## **はじめに**
Shopifyのテーマ開発には、従来の「Theme Kit」が廃止され、現在は「Shopify CLI」の使用が推奨されています。本記事では、**VS Codeを使ってShopifyテーマを開発する方法** をわかりやすく解説します。

---

## **1. 必要なツールを準備**
### **Shopify CLI のインストール**
#### **Mac (Homebrew経由)**
```sh
brew install shopify-cli
```
#### **npm 経由 (Windows, Mac, Linux)**
```sh
npm install -g @shopify/cli
```

### **VS Code のインストール**
- すでにインストール済みの場合はスキップしてください。
- まだの場合は、[公式サイト](https://code.visualstudio.com/)からダウンロードしてインストールします。

---

## **2. Shopify ストアにログイン**
Shopify CLI を使用する前に、Shopifyアカウントにログインします。
```sh
shopify login
```

ブラウザが開くので、Shopifyのアカウント情報でログインしてください。

---

## **3. テーマのセットアップ**
### **既存のテーマをローカルにダウンロード**
開発するテーマをローカルに取得するために、以下のコマンドを実行します。
```sh
shopify theme pull --store your-store.myshopify.com
```
※ `your-store.myshopify.com` の部分は、ご自身のストアのURLに置き換えてください。

ダウンロードが完了すると、テーマのファイルがローカルに保存されます。

---

## **4. VS Code でテーマを編集する**
VS Code を開き、ダウンロードしたテーマのフォルダを開きます。

### **リアルタイムプレビューを開始**
ローカルで編集しながら、リアルタイムプレビューを確認するには以下のコマンドを実行します。
```sh
shopify theme dev --store your-store.myshopify.com
```

### **エラーが発生した場合**
```sh
A store is required
```
このエラーが出た場合は、ストアの指定が不足しているため、以下のように明示的に指定してください。
```sh
shopify theme dev --store your-store.myshopify.com
```

---

## **5. 変更をShopifyに反映する**
ローカルで編集が完了したら、Shopifyにアップロードして反映させます。
```sh
shopify theme push
```

---

## **6. おすすめの VS Code 拡張機能**
VS Code で Shopify テーマ開発をスムーズにするために、以下の拡張機能をインストールすると便利です。

### **① Shopify Liquid Preview**
ShopifyのLiquidテンプレートをプレビューしやすくする拡張機能。
[→ インストール](https://marketplace.visualstudio.com/items?itemName=Shopify.theme-check-vscode)

### **② Shopify Liquid Snippets**
Liquidコードのスニペットを提供してくれる。
[→ インストール](https://marketplace.visualstudio.com/items?itemName=killalau.vscode-liquid-snippets)

---

## **まとめ**
1. Shopify CLI をインストール
2. `shopify login` でShopifyにログイン
3. `shopify theme pull` でテーマを取得
4. `shopify theme dev` でローカル開発開始
5. `shopify theme push` で変更を反映
6. VS Code の拡張機能を活用

これで、VS Code を使った Shopify のテーマ開発が快適に行えます！

**ぜひ試してみてください！**
Docker環境の 202404～202503頃までの動向

- このエントリーは、2024/10 - 2024/11 の個人的な技術情報エントリーです。
## 要約
- Docker/ Docker社 の 技術動向把握の方向性
   ```
    2024年度も、引き続き Docker Desktopのバージョンアップが行われれ、VSCode風のUIなどが一層改善されたバージョンなどが提供されるようになっている。
    （元々、DockerDesktopはElectronベースではあるが、より開発でスタンダードになっているVSCodeのような環境を模倣、親和性の高いUIを採用したのではないかと考える）
    そのほか、より高度・機能が盛りだくさんになっている、Docker/DockerComposeそのものや、オーケストレーション（K8sや Docker Swanなど）についてDocker独自のAI機能を追加（昨日自体は、2023年末ぐらいに導入されている）の積極的な展開や導入が行われたとみている。
   ```

- 【全体感】
    - 2024年度におけるDocker社のコンテナ技術/Dockerの技術動向は、基本2023年度ベースのブラシアップに全体的に触れているようである。
    - 通称3大プラットフォーム（WinX64、MacOS＜ARM系＞、*NIX<Linux想定＞）について、WinX64（WSL2ベース）とMacOS（ロゼッタ実装）は
    - ソフトウェアエミュレーション風の底層実装をより進展させているようである（この結論には、WSL2と、LXCの実装検討が必要であるが、時間不足と技術検討不足で実現していない）
    - *NIX（Linux）は、cGroup系実装とLXCの基礎技術の双方のデファクトスタンダードをメインで動かすような実装が進展し、ある意味おいて最も健全かつ適切な技術成長を遂げているようである。
    - ***
    - オーケストレーションについては業界デファクトスタンダードと別個のDockerSwan実装をさらにブラシアップしているものの、
    - 簡易的な下位互換実装（ただし、使いやすく実装）方向にDocker者は技術的思考を2024年度は動かしているようである。
    - →
        - ただし、DockerSwanは、2023年度に引き続き、Docker独自かつスケールアウトについては実装がK8sより簡易な実装になっているようである。
        - これを解決するべく、Docker社も実装強化を試みているように見えるものの、明確なリリースに結びつく技術実装の進展は乏しいようである。
     - また、2022年ごろから急速な成長を見せている生成AIに対してのアプローチが、Docker実装全般に総力を挙げて（特に企業ソリューションに刺さる方向に）行われているようである。
        - これは、2020年頃のDocker社の経営・社内体制刷新がいよいよ、大きく『花開いていく』過程であると考えている。

#### topic :: "クラウドとコンテナ技術の進化" と "開発者向けツールとワークフローの改善" について
開発者向けの生産性向上ツール（Docker Composeの暫時的な改善や、Testcontainers導入）や、CI/CDパイプラインとの統合に動き大きかったようです。
※ただし、Testcontainers導入は、Java/ Python/ Go が先行しており、PHP などはこれからのようです。
その他、DockerAIの導入がより積極的に行われ、これまで、手作業や開発者の経験やスキル・センスに頼っていた3の項目を該当の機能を使った系統だったルール化、スキル補助の機能を中心に進展しているようであり、
結果、煩雑に思えるDockerとK8sのようなオーケストレーションに改善のにも役立っているようです。

- Dockerコンテナ利用における、Docker ComposeとTestcontainersの位置づけ。

| 項目| Docker Compose| Testcontainers |
|---|---|---|
| 主な用途 | 開発環境構築、マルチコンテナ管理 | テスト環境の動的提供 |
| 利便性 | 設定ファイルで一括管理、操作が簡単 | コード内で依存を制御、セットアップ不要 |
| 再現性 | チーム間での環境共有に優れる | テストごとの一貫性が保証 |
| 有用度 | 開発・デバッグに高い価値 | テスト品質向上に抜群の効果 |
| 制限 | 本番環境には不向き| 起動時間やDocker依存が課題 |
 - Dockerコンテナ利用へについてのまとめ
      - Docker Compose: 開発者がDockerコンテナを「使い始める」段階での利便性を向上させ、複数コンテナの連携を簡素化。学習曲線を緩和し、迅速なプロトタイピングを可能するもののようです。
      - Testcontainers: テスト段階でのコンテナ利用を深化させ、「本番に近い環境での検証」を手軽に実現。品質と信頼性を高め、開発ライフサイクル全体を強化するようです。
      - 両ツールは、「Dockerエコシステム内で補完的な役割」を果たし、開発からテストまでのワークフローを効率化できるようです。



その他、Docker Bakeのようなコマンド整備も各種環境に対して最適化などが行われ、よりDockerの利用促進を図っているようです。

#### リンク
- https://www.docker.com/ja-jp/blog/labs-ai-tools-for-devs-docker-desktop-extension/
- https://www.docker.com/press-release/ai-trends-report-2024-unveils-key-ai-insights-for-developers-and-it-leaders/
- https://www.docker.com/ja-jp/blog/ai-trends-report-2024/
- https://www.docker.com/ja-jp/blog/docker-2024-highlights/
- https://www.docker.com/ja-jp/blog/streamlining-local-development-with-dev-containers-and-testcontainers-cloud/
- https://www.docker.com/ja-jp/blog/testcontainers-cloud-vs-docker-in-docker-for-testing-scenarios/
- https://www.docker.com/ja-jp/blog/running-testcontainers-tests-using-github-actions/
- https://www.docker.com/ja-jp/blog/connecting-to-testcontainers-services-using-testcontainers-desktop/
mpvで音声ファイルをカラオケ化

## 動機

- 音声ファイルや音楽ファイルを再生するとき、ボーカルを減らしてカラオケ風にして、演奏メインで聴きたい。
- 安全のため、ある程度メジャーなプレーヤ(オープンソース、いろんなOSで動く等)で実現したい。

## 解決策

オープンソースのmpvプレーヤを、jsでカスタマイズする。
定義または上書きしたキーを打つことで、循環的にボーカル低減レベルを切り替えることができる。

```js:~/.config/mpv/scripts/my.js
var pow0 = 0;
mp.add_key_binding(")", "mlev", function() {
  pow0 = (pow0+1) % 7;
  mp.command("no-osd af add @mlev:lavfi=[stereotools=mlev=" + Math.pow(0.5,pow0) + "]");
  mp.commandv("show-text", "mlev 0.5^" + pow0);
});
```

|命令|意味|
|--|--|
|mp.add_key_binding|処理にキーを割り当て。引数0は規定キー(shift-9(")"))。引数1は名前で`~/.config/mpv/input.conf`でキー割当変更可能。引数2は処理。|
|no-osd|オンスクリーンディスプレイを表示しない|
|af add|オーディをフィルタを追加|
|@mlev|追加するフィルタ定義のローカル名。同じ名前の定義が既に追加済なら新しい値に入れ替える。|
|lavfi|ffmpegの仮想入力デバイス名|
|stereotools|ffmpegのステレオ関連のフィルタ|
|mlev=(数字)|middle signalのレベル。0.015625 ～ 64。ボーカルはミドルに配置されていることが多いため、値を減らすと物理プラグを接触不良にしたようにボーカルの音量が小さくなる。|
MP4動画がappleデバイスで再生できない

https://widedeep.hatenablog.jp/entry/mp4-forcc-appledevice
# 状況
最近はH.264から、圧縮率の高いH.265(HEVC)に移行が進んでいますが、まだH.265に未対応の機器もたくさんあります。
ところでH.265動画をFFmpegなどを使って変換したところ、iphoneなどのappleデバイスで再生できなくなったことはないでしょうか。
今回私が陥った状況を整理したので役立てていただければと思います

以下の状況に該当する場合、この記事が役立つかもしれません。

1. android端末でH.265動画を撮影
2. 容量を圧縮するために、Windows端末でFFmpegを用いて変換（ビデオのみ変換）
3. android、Windows端末では問題ないが、iOS端末では再生不可で「MPEG-4 ムービー」と表示される
4. ただし、VLCPlayerなどの再生アプリをiOS端末に入れれば再生可能


# 原因
H.265のFourCCが`hev1` になっているため。

## 解説

ビデオにはCodecID(FourCC)と呼ばれる四バイトの識別子があります。

[https://ja.wikipedia.org/wiki/FourCC](https://ja.wikipedia.org/wiki/FourCC)

H.265のCodecIDには`hev1`と`hvc1`がありますが、appleデバイスで再生できるのは`hvc1` だけのようです。

[https://video.stackexchange.com/questions/36359/what-does-the-tag-tagv-hvc1-means](https://video.stackexchange.com/questions/36359/what-does-the-tag-tagv-hvc1-means)

FFmpegで変換するとデフォルトが`hev1` になるため、appleデバイスで再生できなくなります。

ただし、VLC media playerなどのサードパーティアプリであれば再生可能です。

[https://apps.apple.com/jp/app/vlc-media-player/id650377962](https://apps.apple.com/jp/app/vlc-media-player/id650377962)  

# 対応策
FFmpegで変換する場合は、`⁠-tag:v`を指定することで変換できます。

```
ffmpeg -i input.mp4 -c copy -tag:v hvc1 output.mp4
```

# まとめ
appleがhev1に対応してくれれば問題ないのですが。。
clangのconfigでコンパイルオプションを指定する

Clangではコンパイルオプションをconfigファイルから読み込むことができるそうなので、macOS環境で試してみました。

## Clangのconfigファイルとは

Clangのconfigファイルとは、コンパイルオプションを指定するための設定ファイルのことです。例えば、ある特定のターゲットに対してのコンパイルオプションを事前に設定しておいて、コンパイル時に指定するときなどに役立ちます。Clang Compiler User's Manual[^1]には、例として`-L`、`-I`、`-l`、`--sysroot`、`codegen`などコンパイル環境依存で設定されるようなオプションが挙げられています。

## 設定例

### --configオプションによる指定

`--config`オプションで直接指定する方法です。これが最も一般的だと思います。

```script
$ clang++ --config=a.cfg a.cpp
```

configファイルにはオプションをそのまま指定します。

```txt: a.cfg
-std=c++23
```

例として、C++23のフィーチャー(std::print[^2])のために`-std=c++23`オプションをa.cfg（ファイル名は任意）で指定することができました。

```c++: a.cpp
#include <print>

int main() {
  std::print("{}\n", "print"); 
  return 0;
}
```

オプションは追記して指定することもできます。

```txt: a.cfg
-std=c++23
-Wall
```

また、複数のconfigファイルを読み込ませることもできます。

```script
$ clang++ --config=x.cfg --config=y.cfg a.cpp
```

### デフォルト

デフォルトで参照されるconfigがあるかどうかは、環境依存かと思いますが、筆者の環境でインストールされているClang(Homebrew clang version 19.1.7)では、`/opt/homebrew/etc/clang/arm64-apple-darwin24.cfg`が参照されるようになっていました。
このファイルに追記すると、オプションを明示的に指定しなくとも読み込まれるようになります。
ただし、デフォルトのconfigファイルには`--isysroot`などシステムライブラリに必要なオプションが設定されていることもあるので、あまり不用意に変更しないほうが良さそうです。

```script
$ clang -v
Homebrew clang version 19.1.7
Target: arm64-apple-darwin24.1.0
Thread model: posix
InstalledDir: /opt/homebrew/Cellar/llvm/19.1.7_1/bin
Configuration file: /opt/homebrew/etc/clang/arm64-apple-darwin24.cfg
```

#### --config-user-dir, --config-system-dirでデフォルト参照先を変更する
コンパイル時に`--config-user-dir`や`--config-system-dir`というオプションを使用することで、userとsystemのデフォルトのconfigディレクトリを変更することができます。上の例での`/opt/homebrew/etc/clang`にあるconfigファイルを探索する代わりに、このオプションで設定したディレクトリを探索することになります。
Clang Compiler User's Manual[^1]によると、`--config-system-dir`と`--config-user-dir`オプションは指定されたディレクトリを探索して、`<triple>-<driver>.cfg`という名称のconfigファイルがあれば、それが使われます。（詳しい探索規則は、上記のマニュアルを参照していただければと思います。）

筆者が調べたところの注意点としては、以下がありました。
- 読み込まれるconfigファイルは1つだけ
- 探索規則に沿っていないファイル名(a.cfgなど)は指定ディレクトリ下に存在していても読み込まれない
- このオプションを指定すると、デフォルトのconfigは参照されなくなる

例えば、下記の例では2種類の.cfgファイルのうち、`arm64-apple-darwin24-clang++.cfg`が優先的に読み込まれます。1ファイルしか読み込まれないので、`arm64-apple-darwin24.cfg`は読み込まれません。

```script
$ ls <path_to_config_dir>
arm64-apple-darwin24.cfg
arm64-apple-darwin24-clang++.cfg
$ clang++ --config-user-dir=<path_to_config_dir> a.cpp
```

### 環境
Apple M1
macOS Sequoia 15.1.1
Homebrew clang 19.1.7

### 参考文献
[^1]:https://clang.llvm.org/docs/UsersManual.html
[^2]:https://en.cppreference.com/w/cpp/header/print
pyautoguiを使った画像認識で、画像が見つかるまで探索を繰り返す方法

# 背景
pythonでRPAツールを作る際、pyautoguiを使うことは多いと思います。
pyautoguiを使う理由として、画面上に表示されている特定の画像を探索してクリックさせる動作をさせたいというのがあると思います。
例えば、下記のように
```target_click.py
#'target.png'という画像を探してクリックする
a = pyautogui.locateOnScreen('target.png', confidence=0.8)
pyautogui.moveTo(a)
pyautogui.click()
```
しかし、対象の画像が画面上に見つからなかった場合、エラーで終了してしまいます。

# 解決策
下記のように記述することで、対象画像が見つかるまで探索を繰り返すことができます
```target_click_retry.py
while True:
    try:
        #'target.png'が見つかればbreakで抜けます
        if pyautogui.locateOnScreen('target.png', confidence=0.8):
            break
    # 「except pg.ImageNotFoundException」で画像認識できなかった時の動作を指定
    except pyautogui.ImageNotFoundException:
        print("retry") #ここはお好きに
        time.sleep(1)
        continue

#ここは一緒
a = pyautogui.locateOnScreen('target.png', confidence=0.8)
pyautogui.moveTo(a)
pyautogui.click()
```
繰り返す回数をfor文で指定して、見つからない場合タイムアウトさせるのもよいでしょう

誰かの参考になればうれしいです
PEP8の命名規則

# PEP8の命名規則

PythonにはPEP8というコーディング規約があります。
変数名や関数を考える時に毎回調べるのが面倒なので、良く使うルールをメモ書きしておきます。

## 参考資料

- [pep8-ja 1.0 ドキュメント](https://pep8-ja.readthedocs.io/ja/latest/)
- [Pythonの命名規則とルール](https://zenn.dev/gakkie555/articles/b7d89442365943)

## よく使うルール

||内容|例|
|---|---|---|
|変数名|スネークケース（すべて小文字で区切りはアンダースコア）|my_value|
|関数名|スネークケース（すべて小文字で区切りはアンダースコア）|my_func()|
|クラス名|キャメルケース（先頭は大文字で区切りは大文字）|MyClass|
|定数|コンスタンスコース（すべて大文字で区切りはアンダースコア）|MY_CONSTANT|
|パッケージ名|全て小文字の短い名前にすべき|mypackage|
|モジュール名|全て小文字の短い名前、アンダースコアは非推奨|mypackage|

## docstring

docstringのスタイルガイドに PEP257 がありますが、reStructuredTextスタイルの方が直観的に読みやすかったです。

```python
def my_func(value1=0.0, value2=0.0):
    """
    この関数はvalue1とvalue2を加算して返します。

    :param value1: 加算する一つ目の値
    :param value2: 加算する二つ目の値
    :return: 加算結果
    """
```
Flutter でのスマホアプリ開発に Teachable Machine を扱うための軽い下調べ

## はじめに
タイトル通り、Flutter でのスマホアプリ開発で Teachable Machine を扱うための下調べの話です。

それぞれ、過去に個別には扱ったことがあるのですが（※以下で出てくる記事に関連した内容を書いていたり）、それらを組み合わせて使うための下調べです。

●「flutter user:youtoy」の検索結果 - Qiita
　https://qiita.com/search?q=flutter%20user%3Ayoutoy&sort=created

●「teachable machine user:youtoy」の検索結果 - Qiita
　https://qiita.com/search?q=teachable%20machine%20user%3Ayoutoy&sort=created

## 情報源
とりあえず、検索して出てきた情報などのメモしていきます。

### 記事1
まずは検索して出てきた記事の 1つです。

 ●Integrate computer vision with flutter (using Google Teachable) - DEV Community
　https://dev.to/tedtecch/integrate-computer-vision-with-into-flutter-app-using-google-teachable-fn4

こちらでは以下を使って実装しているようです。

●tflite | Flutter package
　https://pub.dev/packages/tflite

上記について公式情報を見てみると、最終更新日は 3年前くらいで別のものを使うのが良い感じがしました。

![2025-03-01_19-39-48.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/ffc01548-d97d-47f1-98eb-f3ce2f322060.jpeg)

### 記事2
以下は別の記事です。

●TensorFlow Lite Tutorial for Flutter: Image Classification [FREE] - JOYK Joy of Geek, Geek News, Link all geek
　https://www.joyk.com/dig/detail/1675226842692353#gsc.tab=0

この記事では、以下を見ると「tflite_flutter」と「tflite_flutter_helper」の 2つを使っているようです。

![2025-03-01_19-45-51.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/fd5d613a-2c43-438d-8d9b-ff94c955d655.jpeg)

1つ目のほうは、公式ページを調べてみると以下となっているようでした。

●tflite_flutter | Flutter package
　https://pub.dev/packages/tflite_flutter

![2025-03-01_19-48-19.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/bccf02dc-b8db-4091-978a-0877110dfaa7.jpeg)

5ヶ月前くらいに更新されているので、これを使うのが良いかもしれません。

また 2つ目のほうは、上記のページ内に以下の記載がありました。

![2025-03-01_23-01-59.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/3455e5ba-409e-47e8-9fd7-97097d0de147.jpeg)

ヘルパーは使わずに実装する感じでしょうか？
具体的な実装事例をベースに、このあたりは確認できればというところです。

### 記事3
以下はさらに別の記事です。

●Flutter × Teachable Machineで画像識別してみた
　https://zenn.dev/tomohiro629/articles/2a7ef75d4de557

この中では、上でも出てきた「tflite_flutter」を使っていて、ヘルパーなしの実装っぽいです。

![2025-03-01_23-03-58.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/6fa404e0-70fe-423e-a5db-94b8d4a263cf.jpeg)

### 開発方法について

上記や他の情報を見ていったところでは「tflite_flutter」を使った開発を行うのが良さそうですが、もう少し調査をしてみたり、具体的な実装を試していければとおもいま
draw.ioで容量を抑えてpdfを出力する

# 結論
**「ダイアグラムのコピーを含める」** のチェックを外すことで容量を抑えることが出来ます．

latexのコンパイルなどで図の容量・サイズを抑えたいときはこのようにすると良いです．
チェックをいれた場合，エクスポートしたファイルをdraw.ioで開くと再び編集可能になるようです．
その他にも，**「選択範囲のみ」，「切り落とす」，「余白の広さ0」** も容量の削減に効果がありそうです．余計な部分が削ぎ落とされるので，latexなどに埋め込むときもスッキリします．

![スクリーンショット 2025-02-09 9.25.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3085757/9a23e434-eb65-254a-4a4f-8af35be9c1a9.png)

# 他の記事
↓ 以下の記事も書いています．

https://qiita.com/ryhara/items/f79953e5c96050f68bf1
GPU-CPU間のオーバーヘッドについて考える

# GPU-CPU間のオーバーヘッドについて考える

GPUを活用する際、多くの開発者が気にするのは **オーバーヘッド** です。特に、CPU-GPU間のデータ転送やカーネル起動時の遅延がボトルネックとなることがよくあります。本記事では、GPU-CPU間のオーバーヘッドの原因と、それを軽減するための手法について考えてみます。

## なぜGPU-CPU間のオーバーヘッドが発生するのか？

GPUを活用する際、主に以下のようなオーバーヘッドが発生します。

1. **データ転送の遅延**
   - GPUは通常、独立したメモリ（VRAM）を持っており、CPUのメインメモリ（RAM）とは別管理となっています。
   - データをGPUに送るためには、PCIe経由でデータ転送を行う必要があり、これが大きな遅延を生じます。
   
2. **カーネル起動のオーバーヘッド**
   - GPUカーネルを実行する際、CPU側で命令を発行し、スケジューリングを行った上でカーネルが実行されます。
   - この際に、コンテキストスイッチなどのコストが発生します。

3. **同期コスト**
   - CPUとGPUは異なるコアで並列実行されるため、データの整合性を取るための同期処理が必要になります。
   - `commandBuffer.waitUntilCompleted();` などのAPIを適切に使わないと、不要な待機が発生する可能性があります。

4. **APIのオーバーヘッド**
   - CUDA, OpenCL, Metal などのAPIは、GPUリソースを管理するために追加のオーバーヘッドを伴います。
   - 特に、頻繁なAPIコールは性能を低下させる可能性があります。

## 実際にMetalでBLASを実装してわかったこと

実際にMetalを使ってBLASを独自実装してみましたが、**OpenBLASほどの速度はまず出せない** という結論に至りました。

また、細かくBLASやLAPACK命令を実装し、それらを機械学習アルゴリズム側で何度もディスパッチ（呼び出し）すると、オーバーヘッドが大きくなり、非効率になることも明らかになりました。

したがって、GPU実装したい機械学習アルゴリズムの **コア部分を直接GPUカーネルで実装する** のが最も効率的だとわかりました。

## VeloxMLの紹介

私が開発している **VeloxML** は、高速な機械学習ライブラリをC++で実装し、Python APIを提供するプロジェクトです。VeloxMLでは、CPUでの推論・学習を高速化するために、BLAS/LAPACKの最適化を行いつつ、1から実装したGPUカーネルコードを活用し、GPUで高速な学習を行うことを目指しています。

現在、CPUベースのアルゴリズムを中心に実装していますが、**近いうちにMetal実装した機械学習アルゴリズムを追加する予定** です。Metalの最適化を活かし、GPUをフル活用することで、高速な学習と推論を実現していきます。

今後のアップデートにご期待ください！

もしVeloxMLを気に入っていただければ、スターをお願いします！

https://github.com/veloxml/VeloxML
ABC395をPythonで（A～E）

AtCoder Beginner Contest 395の解答等の速報的まとめ

https://atcoder.jp/contests/abc395



# A問題
https://atcoder.jp/contests/abc395/tasks/abc395_a

全部試す
```python:A
n = int(input())
a = list(map(int, input().split()))
print("Yes" if all(a_i < a_j for a_i, a_j in zip(a, a[1:])) else "No")
```
# B問題
https://atcoder.jp/contests/abc395/tasks/abc395_b

外側からの距離の偶奇で#と.が入れ替わる
```python:B
n = int(input())

for i in range(n):
    ans_i = ""
    for j in range(n):
        k = min(i, j, n - i - 1, n - j - 1)
        if k % 2 == 0:
            ans_i += "#"
        else:
            ans_i += "."
    print(ans_i)
```
# C問題
https://atcoder.jp/contests/abc395/tasks/abc395_c

各数字ごとに
前後の数字の距離の最短を求める
```python:C
n = int(input())
a = list(map(int, input().split()))

d = dict()
INF = 10 ** 7
ans = INF
for i, a_i in enumerate(a):
    if a_i in d:
        ans = min(ans, i - d[a_i] + 1)
    d[a_i] = i

print(ans if ans < INF else -1)
```
# D問題
https://atcoder.jp/contests/abc395/tasks/abc395_d

鳩の巣が数直線上に並んでいるとするとき
鳩の移動は、左から何番目に移動したかを記録する
巣は、$i$番目が左から何番目にあるかとその逆を記録しておいて、入れ替えるときに両方を入れ替える
```python:D
n, q = map(int, input().split())

pigeons = [i for i in range(n)] # 鳩
nests = [i for i in range(n)] # 巣
d = [i for i in range(n)]

for _ in range(q):
    com = list(map(lambda x:int(x) - 1, input().split()))
    if com[0] == 0:
        a, b = com[1:]
        target_nest = d[b]
        pigeons[a] = target_nest
    elif com[0] == 1:
        a, b = com[1:]
        ind_a, ind_b = d[a], d[b]
        nests[ind_a], nests[ind_b] = nests[ind_b], nests[ind_a]
        d[a], d[b] = ind_b, ind_a
    else:
        a = com[1]
        print(nests[pigeons[a]] + 1)
```
# E問題
https://atcoder.jp/contests/abc395/tasks/abc395_e

辺の向きが初期の向きと逆向きをそれぞれ記録し、
各頂点で初期の向きと逆向きで到着した時のコストの最小値をダイクストラで求める
```python:E
from heapq import heappop, heappush

n, m, x = map(int, input().split())
edge = [[] for _ in range(n)]
rev_e = [[] for _ in range(n)]
for _ in range(m):
    u, v = map(lambda x:int(x) - 1, input().split())
    edge[u].append(v)
    rev_e[v].append(u)

INF = float('inf')
cost = [[INF, INF] for _ in range(n)]
cost[0][0] = 0
q = [[0, 0, 0]]
while q:
    c_i, now, is_rev = heappop(q)
    if cost[now][is_rev] < c_i:
        continue

    if cost[now][is_rev ^ 1] > c_i + x:
        heappush(q, [c_i + x, now, is_rev ^ 1])

    if is_rev:
        for to in rev_e[now]:
            if cost[to][is_rev] > c_i + 1:
                cost[to][is_rev] = c_i + 1
                heappush(q, [c_i + 1, to, is_rev])
    else:
        for to in edge[now]:
            if cost[to][is_rev] > c_i + 1:
                cost[to][is_rev] = c_i + 1
                heappush(q, [c_i + 1, to, is_rev])

ans = min(cost[-1])
print(ans if ans < INF else -1)
```
プログラミング初学者が2年の夏休みから長期インターンに通った話　春休み一人アドカレ5日目

## はじめに
私は大学に入って初めてプログラミングに触れたのですが、2年の夏休みという比較的早い時期に開発系の長期インターンに通過しました。その経緯やどのようにして通ったかの自己分析などを綴ろうと思います。インターンに行こうか迷っている、行きたいけどどのようにしたらいいかわからない人の助けになればと思います。

## なぜ長期インターンに行くのか
そもそもなぜ長期インターンに行くのか、私が思う長期インターンの魅力について3つ紹介したいと思います。

### 1. 勉強してスキルアップをしながらお金が貰える
特に1,2年生のときは大学に行ったりアルバイトをしながらプログラミングや開発の学習をするのはかなり大変だと感じました。そんな中勉強とお金を稼ぐことを両立できるのはまさに一石二鳥と言えます。

### 2.就活が有利になる
就活は3年からで十分ではないかと思われるとかもしれませんが、大手企業のサマーインターンなどはインターンであっても開発経験や実務経験が求められます。先程も述べたように学業やアルバイトと両立しながら勉強や個人開発をすることは難しいです。なので初学者こそ就活時により上の企業を目指すには大きなアドバンテージとなります。

### 3.労働環境の良さ
アプリ開発などのインターンやアルバイトはオンラインでも働けることが多く、また時給が高いことも多いです。仮に時給が高くなくとも、隙間時間にオンラインで働けることは隙間時間のできやすい大学生活ととても相性がよいと思います。他のアルバイトより入れる時間が長いので、より多くお金を稼ぐことができると思います。


## インターンまでにやっていたこと
ここで本題のインターンに入るまでの1年半何をしていたかについてお話します。

 ### 1年生のとき
一年生のときにやっていたことは基礎固めとIT系の学生団体に所属したことです。

１つ目の基礎固めは単に大学の実習を行っていただけですが、paizaというサイトを用いて軽く授業の予習をしたりとしっかり理解してやることを心がけていました。

２つ目の学生団体では、授業で不明な点をきき理解を深めつつ勉強会の集まったKC3というイベントへの参加や、一年終わりに先輩にチームを組んでもらってハッカソンに出場しました。
団体に所属している周りの人や勉強会に参加することによってモチベを高めて、ハッカソンで初めて開発に触れました。

### 2年になってから
２年生になってやっと本格的に開発の勉強をするようになりました。
それも一年終わりと同様に団体から案内をもらったハッカソンが始まりでした。

そのハッカソンでは前回と違って個人で出ました。また周りも自分と同じ初心者のみとなったいました。
このハッカソンでメンターの方に教えて貰いながら、本格的に１からバックエンドでRESTAPIを構築しました。

この経験を得て、調べれば現状の自分でもアプリのバックエンド開発ができるという自信が付きました。また開発というのは結局調べながらやるので、後でやるなら今やろうという気づきをえました。
そこから軽く機能の実装を自分ひとりでやってからインターンに申し込みました。

### やったことまとめ
- 授業で基礎をしっかり理解する
- 団体やサークルに所属する
- ハッカソンに出る


## インターンに通るには
先程のべた事をもとに、どうしたらインターンに通るか私なりの解釈で述べたいと思います。
選考で見られる点はお大きく分けて
- チームで何かやることができるか
- 技術力
- やる気があるか

最初の２つは先程も話した学生団体に所属することとハッカソンに2,3回でれば十分だと思います。

最後のやる気があるかについてお話します。
結局何よりも見られるのはこのやる気だと思っています。
これを見せるのはやはり面接です。自分がどうしてそこのインターンをしたいのかを明確に話せるようにしましょう。自分が将来どのようなキャリアを築きたいかなどを元に話すと説得力がより生まれると思います。またインターンを通して何を得たいかも説明できるといいと思います。


## インターンの探し方
私は先輩に教えてもらったWantedlyで探しました。
このサイトはエンジニアに特化していて、1、2年生でも参加できるインターンも多くあります。
選ぶポイントとしては
- やりたいことができるか
- 家から通えるか
- 育てる余裕があるか

の3つは最低限みておくべきだと思います。
家から通えるかについて、リモートだからいいと思われるかもしれませんが、最初のうちは特に一二週間に一度は出社して対面で聞けたほうが安心できるとおもいます。

最後の育てる余裕があるかは、きちんとエンジニアの人がついて見てくれるかということです。
ここで成長できるかどうかが大きく決まると思います。見分け方は面談や面接でざっくりと体感できると思います。

https://www.wantedly.com/


## まとめ
ながくなりましたがまとめです。
長期インターンは様々なメリットがあるので迷っている人は是非行きましょう。
そのためには1年生で基礎固めと団体やサークルへ参加して、2年でハッカソンや個人開発で経験をつみましょう。
あとは行きたいところを見つけて情熱を伝えるだけです。


## おまけ
またハッカソンだけでは経験に不安だけど、個人開発は何したらいいかわからない人などは是非TechTrainやProgate Pathなどで実務に近い経験を積むことをおすすめします。
TechTrainは学生割引やランクが上がると無料になりますし、Progate Pathは学生は無料で受けられます。
wantedlyはプロフィールを充実させておくと面接がスムーズにいったりスカウトがくるので是非細かく記入してください。参考に私のプロフィールを載せておきます。

https://service.techtrain.dev/

https://path.progate.com/

https://www.wantedly.com/id/masachika_ura
Git 運用 コミットメッセージ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2680230/01d0ede6-a4fa-4773-9066-97953120c7e9.png)

# はじめに

各プロジェクトの背景により、自社の GitHub が利用できい事もあるので、GitHubの運用を少しずつまとめて行きたいと思いました。
共通的な GitHub の Wiki に書こうかと思ったのですが、折角なので Qiita で記載したいと思います。
以前記載した「[GitHub ざっくり How to use.](https://qiita.com/magic10r/items/392969d7837cff10fd9f)」からの続きとして、今後も継続して記載します！

# 前提

## 単位

コミットは意味のある最小の単位で行う
コミット（プッシュ）後に「アレ忘れた」や「コメントアウトの削除忘れた」などの場合は、めんどくさがらずに `rebase` などで適切なサイズのコミットに修正を行う
**レビュアーにやさしいコミット(PR)を心がけましょう！**

## フロー

1. GitHub Issue の作成
1. Branch の作成
1. プログラム修正
1. Git Commit

# 基本的な構造

```
<type>: <#issue-number> <subject>

[optional body]
```

コミットメッセージの例:
- `feat: #10 add excellent feature`
- `docs: #10 update API document`

## `type`

- `feat`: 機能の追加や修正。パフォーマンスの改善は機能の追加として扱う
- `fix`: バグ修正
- `docs`: ドキュメントの追加や修正
  - コード内のコメントの追加や修正は、ドキュメントの変更として扱う
- `chore`: ビルドプロセスやツールの変更、フォルダ構造の変更など
- `test`: テストの追加や修正
- `refactor`: バグ修正や機能追加を含まないコードの変更
  - 不要なコードの削除
  - コードの可読性や保守性を向上させるための変数名の変更
  - コーディングのスタイルに関する変更（コード意味に影響しない変更、空白、フォーマットなど）

## subject について

- 修正内容を英語で要約する
- 一行にする

## optional body

- コミットの詳細を記載
- 箇条書きで記載
- 複数記載可能
- 英語、日本語のどちらかで記載

# おわりに

少しずつまとめます。

---

**参考（感謝）**

- [GitHub ざっくり How to use.](https://qiita.com/magic10r/items/392969d7837cff10fd9f)
- [複数のコミットをまとめる方法](https://qiita.com/futakuchi0117/items/0eafe586e88fe593c23f)
【Web初心者】死ぬほど噛み砕いてWebクローラーを理解する。

## ずばり・・・
世の中に沢山存在する無数のwebサイトを自動的に巡回して情報を集めるプログラムのこと。
検索エンジンやデータ収集ツールで使用される。また、webサイトのコンテンツを解析しデータベースに保存することもできる。

## クローラーの基本的な構造

### 1.URLフロンティア（URL Frontier）
**ざっくり解説**：クロールするURLのリストを管理する部分

### 2.HTTPクライアント（Fetcher）
**ざっくり解説**：指定されたURLからWebページを取得する部分。

### 3.HTMLパーサー（Parser）
**ざっくり解説**：取得したWebページのHTMLを解析する部分。

### 4.データストレージ（Storage）
**ざっくり解説**：取得するデータを保存する部分。

## クローリングの流れ

### 1.URLの収集
・最初に種URLを用意。

### 2.HTTPリクエストの送信
・Webサーバーへリクエストを送る。
・robots.txtを確認し、禁止されている場合はスキップする。

### 3.HTMLの解析
・取得したHTMLを解析、新しいリンクをまたここで抽出する。
・テキストの他にも画像、メタデータなどの情報を保存。

### 4.データの保存
・検索エンジンの場合、解析したデータをインデックス化。（逆引きインデックス→つまり、知りたいことから探すことのできるデータ構造にする。）

### 5.次のURLに進む。
・URLフロンティアのリストから新しいURLを選択肢、2番へ戻る。


## クローラーの種類

### 汎用クローラー（検索エンジン系）
・皆大好きGoogleBot(GoogleChrome)、BingBot(Bing)
・世界中のwebページを巡回する、検索アルゴリズムを基にランクを付ける。

### 特化型クローラー（用途別）
・Amazonの価格監視クローラーとかがそうらしい。
・マーケット・リサーチや競合分析、マーケティングに活用できる。

### 自律型クローラー（学習型）
・AIベースのデータ収集クローター（今どきのやつ、GPT Crawlerとかがそう。）
・データを自動学習し、効率的に情報収集
・ユーザーの検索履歴や行動を学習したり、クロール範囲を最適化できる。

:::note info
このサイト個人的にめっちゃ面白かった
【GPT Crawler】URLを入れるだけでどんなサイトもGPTsにできる神AIを使ってみた | WEEL
https://weel.co.jp/media/tech/gpt-crawler/
:::

## もしクローラーを制御したいという場合

### robots.txtの指定
・Webサイトのルートにある設定ファイルと同じ階層に設置する。
・クローラーがアクセスできる範囲を指定。
```
User-agent: *
Disallow: /private/
```
→全てのクローラーは「/private/」ディレクトリ見ないで！という意味。

### meta robotsタグ
・HTMLの`<head>`内に記述
```
<meta name="robots" content="noindex, nofollow">
```
→ページのインデックス登録とリンクの追跡を禁止,
    `noindex,nofollow`ってなんか標語みたいw

### クローラートラフィック制限
・ログイン認証などを設ければそもそも来れない。
・IPアドレスで特定のクローラーをブロックすることもできるそうな...(?)

## クローラーの利点とこれから課題

### メリット
**利点**
・検索エンジンのインデックスの生成：（この場合のインデックスはデータベースでも出てくる文脈と同じ（？））を付けることでユーザーが情報を素早く見つけられる。

・**データ収集の自動化**：価格比較、ニュース収集などに利用可能。

・**Webサイトの監視・解析**：SEO対策、サイトのパフォーマンスの測定にも使える。

**これからの課題**
・**サーバー負荷**：大量のリクエストがサーバーに負荷をかける。（前に、POSTでやるべき処理をGETでやってしまい、クローラーがSQLにクエリを送りすぎて大変なことになったのをどこかの勉強会で聞いたことがある。）

・**プライバシー・著作権問題**：データ取得が違法になる場合もある。（これはかなりナイーブな希ガス）

・**スパムボットの悪用**：悪意のあるクローラーがコンテンツを盗用すること。

### 参考文献（参照日2025年3月1日）

https://www.elastic.co/jp/what-is/web-crawler

https://www.seohacks.net/blog/933/

https://developers.google.com/search/docs/essentials?hl=ja

https://developers.google.com/search/docs/crawling-indexing/robots/intro?hl=ja#:~:text=in%20your%20browser.-,robots.,%E3%81%9F%E3%82%81%E3%81%AE%E3%83%A1%E3%82%AB%E3%83%8B%E3%82%BA%E3%83%A0%E3%81%A7%E3%81%AF%E3%81%82%E3%82%8A%E3%81%BE%E3%81%9B%E3%82%93%E3%80%82

https://stackoverflow.com/questions/tagged/web-crawler

https://weel.co.jp/media/tech/gpt-crawler/
Laravelの既存プロジェクトでDockerを使いたい

# 導入
本記事では、既存の Laravel プロジェクトに Docker を導入する手順 を解説します。
「Docker を使った環境構築に興味がある方」や「とりあえず Laravel を Docker で動かしたい方」の参考になれば幸いです。

現在、私の開発環境は Windows です。
なお、本記事では WSL2 を使用して Docker を動かしている ことを前提にしています。
(WSL2 の導入がまだの方は、WSL2 の公式ドキュメントを参照してください。)
環境構築は以下の手順で進めることが出来ます。
## 1.DockerDesktopのインストール
https://app.docker.com/
こちらのリンクにアクセスしDockerDesktopをダウンロードしインストールしてください。（無料版を使っています。）
Dockerのインストールが完了したかどうかを確認してみます。
Windowsのpowershellを用いて以下のコマンドを実行します。
```shell:powershell　
docker --version
```
実行例：以下のようにバージョンが出力されればインストールはできています。
```shell:powershell　
Docker version 27.5.1, build xxxxxxx
```
## 2.WSL Integrationの設定
DockerはLinux上で動かすことが前提のソフトウェアツールなので、Linuxの環境が必要になります。中でもWSL2を使う設定が「WSL Integration」です。
これはDockerのアプリ画面で設定します。
「設定」⇒「Resources」⇒「WSL integration」に移動し、Ubuntu-20.04を有効にします。その後Apply＆restartをクリックして設定が完了です。

## 3.WSL2が有効になっているかの確認
そこで現在Linuxのディストリビューションの一覧とその詳細を確認します。以下のコマンドを実行してください。
```shell:powershell　
wsl --list --verbose
```
出力例
```shell:powershell　
* Ubuntu-20.04      Running         2
  docker-desktop    Running         2
```
上の出力結果がStoppedになっていたり、Versionが1になっていたりする場合はWSLを起動したり、バージョンを2に変更したりするなどいろいろ試してみてください。

## 4.LaravelをDockerで動かすための準備
まず以下のコマンドでWSLを起動します。
```shell:powershell　
wsl
```
次に対象のプロジェクトのディレクトリに移動した後、以下のコマンドを実行しLaravel Sailをインストールしていきます。
（SailとはLaravelで簡単にDockerを使えるようにするツールです。）
まず、以下のコマンドでLaravelのプロジェクトにSailを追加します。
```shell:bash
composer require laravel/sail --dev
```
    次に以下のコマンドでSailのDocker環境の設定ファイルであるdocker-compose.ymlを作成します。
```shell:bash
php artisan sail:install
```
ここで他のサービスをインストールするか問われます。私はmysqlのみ選択しました。
以上でインストールが完了です。
## 4.Dockerの起動
以下のコマンドを実行しDockerを起動します。
```shell:bash
./vendor/bin/sail up -d
```
もちろんアプリ側でコンテナを起動しても問題ありませんが、開発環境ではコマンド実行の方がいいと思います。

## まとめ
以上により既存のプロジェクトにDockerを導入することが出来ました。
記事をごらんいただきありがとうございましｔ
ubuntu(server)のssh接続が遅い原因

ubuntu `24.04`にsshすると接続が遅いので、原因を調べました。

ssh接続が遅い原因は、`systemd-logind`の`IPAddressDeny`です。これはログイン時のセキュリティです。

systemd-logind サービスの設定ファイル (/lib/systemd/system/systemd-logind.service) には、IPAddressDeny=any というオプションが含まれています。この設定は、systemd-logind プロセスによる全ての IP アドレスへのアクセスを拒否するものです

ssh接続を正常に戻すには、これを解除します。

```sh
$ sudo vim /lib/systemd/system/systemd-logind.service
```

```diff
+ IPAddressDeny=any
- #IPAddressDeny=any
```

しかし、セキュリティも確保したいので、localhostのみ解除することにします。

```sh
IPAddressAllow=localhost
IPAddressAllow=192.168.1.0/24
IPAddressDeny=any
```

この設定により、localhostと192.168.1.0/24サブネット（192.168.1.1から192.168.1.254まで）からのアクセスが許可され、それ以外のIPアドレスからのアクセスは拒否されます。

設定を反映させるために、以下のコマンドを実行します。

```sh
$ sudo systemctl daemon-reload
$ sudo systemctl restart systemd-logind.service
```

## セキュリティ上の懸念
IPAddressDeny=any をコメントアウトすることで、systemd-logind プロセスのネットワークアクセス制限が解除されます。これにより、潜在的にセキュリティリスクが増加する可能性があります。しかし、以下の点を考慮する必要があります：

systemd-logind は主にローカルシステムのセッション管理を担当するため、通常はネットワークアクセスを必要としません。

NIS クライアントなど、特定の環境設定ではネットワークアクセスが必要になる場合があります。

システム全体のファイアウォール設定や他のセキュリティ対策が適切に行われていれば、リスクは最小限に抑えられます。

セキュリティと利便性のバランスを取るために、必要最小限のネットワークアクセスのみを許可するよう、IPAddressAllow オプションを使用して特定の IP アドレスやネットワークへのアクセスを制限することも検討できます

## sshd -> ssh

なお、24.04では、unitがsshdからsshという名前に変更されています。

```diff
# sshサーバーを起動
+ $ sudo systemctl start ssh
- $ sudo systemctl start sshd

# ステータスの確認
+ $ sudo systemctl status ssh
- $ sudo systemctl status sshd

# 起動時に実行
+ $ sudo systemctl enable ssh
- $ sudo systemctl enable sshd
```
プログラミング初心者こそTypescriptとスプレッドシートを使ってみるべきだと思う。

プログラミングを学び始めよう！と思い立つと、世の中一般にはHTMLとCSSから学習をスタートする方が多いようで。
何から始めようと自由なので、別に順序なんてないよっていうのが前提としてあるけれど、プログラミング＝Web制作と捉えるかたが一定いるので、そういった状態でHTMLスタートするとぶつかる壁が多いように思っています。

https://x.com/kuma_radcof/status/1756156046941598067

固定のポストを深掘りしていくと色々書いているのですが、今自分で取り組んできた経験を振り返ると初学者こそ『Typescript』に手を出すのが良いように思う。
そしてTypescriptを扱って何をするかっていうところで、スプレッドシートを利用した業務効率化、自動化といったことに取り組むのがいいんじゃないかなーって思っている。

## プログラミングにもいろいろな種類がある

HTMLとかCSSってブラウザで簡単に確認できるし、環境構築もそんな必要ないし即座に反映されるしエラーがあっても表示が崩れるだけっていう状態だから、プログラミング＝PCでカタカタやることとイメージすれば結構合ってるようにも思う。
でも（自分がそうだったけど）、HTML・CSSを扱ってWordPressでサイト制作できるようになってきても、致命的にデザインができなかったり、コーディングしようと思ってもAIで結構成り立つしな…なんて思い始めるとなかなか突き詰められません。

## プログラミングの本質は問題・課題を見つけ解決していく能力

基本的にはプログラミングを学ぶことで得られるものって、世の中をちょびっとでも便利にできるということだと僕は思っていて。
そう考えるとこれまで印刷物としてでしか自分の事業とか活動内容を表現できなかったことがWebを使って（ホームページとして）公開できるようになるっていうのは、これはプログラミングしているって言えそうで。

とは言え、すべてのプログラミングユーザーがWebサイト持ちたいかって言われたらそうでもないし。
でも毎日やっている特定の作業を時短したり自動化したりして時間を創出して、生産性を上げるでもいいし余暇を楽しむでもいいんだけど、そういったところにプログラミングの本質があるように考えています。

となるとブラウザで表示される見た目を整えることに注力するよりも、日々時間のかかっていることや面倒なことを洗い出して効率化していくことの方がとっつきやすいのでは？と思うわけです。

## 業務効率化を考えた時にスプレッドシートは便利なツールの一つ

表計算ツール・ソフトって色々あるけれど、ウェブに繋がれば使うことができて、特別な環境構築なくプログラミングを始めることができるという点でスプレッドシートって優れたツールだと思います。
家計簿みたいなことからタスク管理・プロジェクト管理みたいなところだったり色々できますよね。
ここだけ切り取るとじゃあNotionの方がいいぜよとかいう声も聞こえてきそうだけど、この議論は本質からズレるので一旦スプレッドシート「も」いいツールってことが伝わればOKです。

そして効率化のための開発（プログラミング）をボタンひとつで始められるようになるGoogle apps scriptも非常に有用だと思っています。
Javascriptベースでかけるとかもあるけど、そこは一旦置いといて、開発始めるまでのハードルが低い、とりあえずやってみることができるというのって非常に重要です。

ただ、GASだけで頑張り続けると出てくるのが、（その時はよくわからん）エラーの頻出です。

## プログラミングする上で『型』を意識することがすごく重要だと知る

ここでいう型は作法という意味よりも、実際にどんなデータを扱うことができるかという器の種類みたいなもんです。
例えば平たい皿にラーメン入れたら汁溢れるから良くないよね、とか深皿に焼き魚置いたとしたら食べるの苦労するよね、だから適材適所で扱おうねっていうのがプログラミングにおける『型』です（少なくともここではそのくらいの感じで捉えてほしい）。

スプレッドシートに関して、GASで開発を続けていると文字列でも数字だとしても実行自体はできてしまうことがほとんどです。これって実はよろしくなくて、意図しない挙動に繋がります。
プログラミングのもう一つの良さは偶然の産物が作られるわけではなく、（ほとんどの場合）上から下まで理論だって進めることができて整然とさせられることだと思っています。
この時に、書いているコードがどんなデータを扱えるのか、どんなデータとして変換される（返る）のか示せるのが『型』になります。

GAS自体には型を書くことはできないのですが、ここで冒頭のTypescriptにつながってくるわけです。

## Typescriptで書きGASに変換して実行する

Typescriptを使うとひとつ一つに型を定義しながら進めることになるので、意味不明なエラーが出なくなってきます。あ、このコードだと配列を扱うべきなのに今は文字列を入れようとしてたのねとかそういったことがつかめてきます。

こうなるとプログラミングの道が整備されてくる感覚なのですが、問題がひとつあってTypsescriptだけだとスプレッドシートを操作することってできないんですよね。
Javascriptに変換してNode.jsを入れて実行するか、GASに変換して実行するかになります。

もちろんNode.jsを入れて実行しても良いのですが、『初学者がハードル低くスタートできてプログラミングとはどんなものか体験を通じて理解していくことができる』と考えた時に、Typescriptベースで開発してGASに変換して実行するっていうのは結構理にかなっているのではないかと感じるわけです。

そんなわけでこれを読んでからプログラミングを学習する方はまずスプレッドシートを開いてみて、GASの実行からスタートしてみましょう。
スプレッドシートからデータを取得してどこか別の場所に表示させるでもいいし、興味があればXなどの自動投稿ツールにチャレンジしてみてもいいし。
そしてぜひTypescriptについても学びながらプログラミングの楽しさを感じてもらえると嬉しいです。
Ruby, AWS LambdaでBedrockを動かしてみた


## Bedrockのモデルアクセス
AWSのコンソール画面でBedrockのモデルアクセスをします。

## Lambda関数の作成
AWSのコンソール画面でLambdaでランタイムをRuby3.3にして関数を作成します。
実行ロールでBedrockが使えるようにAmazonBedrockFullAccessポリシーを追加します。

## lambda_function.rbのファイルの作成
Localで以下のファイルを作成します。
```lambda_function.rb
require 'aws-sdk-bedrockruntime'
require 'json'

def lambda_handler(event:, context:)
  region = 'ap-northeast-1'
  model_id = 'anthropic.claude-3-haiku-20240307-v1:0'
  content = 'hello'
  bedrock_client = Aws::BedrockRuntime::Client.new(region:)
  response = bedrock_client.converse({
      model_id:,
      messages:     [
        {
          role: 'user',
          content:
        }
      ]
    })
  { statusCode: 200, body: JSON.generate(response.output.message.content[0].text) }
end
```

LocalからもBedrockを叩きたい場合は以下のようにcredentialsが必要になります
```
  def bedrock_client
    Aws::BedrockRuntime::Client.new(region:, credentials:)
  end

  def credentials
    access_key = ENV.fetch('AWS_BEDROCK_ACCESS_KEY_ID', nil)
    secret_access_key = ENV.fetch('AWS_BEDROCK_SECRET_ACCESS_KEY', nil)
    Aws::Credentials.new(access_key, secret_access_key)
  end
```


## Gemfileの作成
こちらもLocalで作成します。
```Gemfile
# frozen_string_literal: true

source 'https://rubygems.org'

gem 'aws-sdk-bedrockruntime'
gem 'json', '~> 2.6'
```

## Lambdaのデプロイ
依存関係をインストールしてzip化します。
```
bundle install --path vendor/bundle
zip -r lambda_function.zip . -x "*.git*
```
上記で作成したzipファイルをAWSのコンソール画面でLambdaにアップロードします。

## 自動デプロイ
毎回手動でzip化するのは手間なので、GitHub Actionsで自動化します。

```.github/workflows/deploy_backend.yml
name: Deploy Lambda on Merge

on:
  push:
    branches:
      - main
    paths:
      - 'backend/**'

jobs:
  deploy:
    runs-on: ubuntu-latest
    defaults:
      run:
        working-directory: backend
    permissions:
      id-token: write  # GitHub OIDC を使うのに必要
      contents: read  # ソースコードを取得するために必要

    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Configure AWS Credentials
        uses: aws-actions/configure-aws-credentials@v4
        with:
          aws-region: ap-northeast-1
          role-to-assume: ${{ secrets.AWS_ROLE_ARN }}
          role-session-name: GitHubActions

      - name: Set up Ruby
        uses: ruby/setup-ruby@v1
        with:
          ruby-version: 3.3
          bundler-cache: true # Bundlerのキャッシュを有効化

      - name: Install dependencies
        run: |
          gem install bundler
          bundle install --path vendor/bundle

      - name: Zip Lambda function
        run: |
          zip -r lambda_function.zip . -x "*.git*"

      - name: Deploy to AWS Lambda
        run: |
          aws lambda update-function-code \
            --function-name anokumo \
            --zip-file fileb://lambda_function.zip

```

`anokumo`の部分はlambdaの関数名に変えてください。

## 作ったサービス
📷 スマホで雲の写真を撮ると、その雲がどこにあるのか分かるサイトを作りました！ 
👉 https://main.d3g4hqynwxuzap.amplifyapp.com/

ソースコードはこちら。
📝 GitHub: https://github.com/issei5/anokumo

💡 フロントはAmplifyを使うことで、Lambdaと合わせて低コストで運用できそうです！
【 Node × Docker 】重いイメージの軽量化、マルチステージビルド

## プロフィール
22歳の大学生です、2025/4月から就職してエンジニアをやります

- サッカー好き
    - 国内サッカー：柏レイソルサポーター
    - 海外サッカー：プレミア、セリエを観戦 Roma推し
- アニメ、漫画好き
    - ジャンププラス定期購読者
    - ラノベ系のアニメ
    - 最近はガンダムにハマる
- ラーメンは二郎系が好み

最近はNestJSで個人開発を進めています

## イメージが重い

フロントがNext.js、バックがNestJSで個人開発を進めています。
データベース等は省きますが、これらのコンテナをDockerで構築しています。

※docker-compose.yml
```
nestjs:
  build:
    context: ./api
    dockerfile: Dockerfile
    volumes:
      - ./api/nest-api:/app
    ports:
      - '3000:3000'
    networks:
      - app-networks

nextjs:
  build:
    context: ./frontend
    dockerfile: Dockerfile
    volumes:
      - ./frontend/next-front:/app
    ports:
      - '4000:3000'
    networks:
      - app-networks

networks:
  app-networks:
    driver: bridge
```

※Dockerfile (next, nestどちらもほぼ同じ記述です)
```
FROM node:20.10.0

WORKDIR /app

COPY package*.json ./

RUN npm i -g @nestjs/cli

RUN yarn install

COPY . .

CMD ["npm", "run", "start"]
```

このように環境構築をしていた当時のイメージ容量は以下です。
Next.jsコンテナのイメージ：1.5GB
Nest.jsコンテナのイメージ：1.43GB

細かい数字までは覚えていませんが、ほとんどこの数字で合っているはずです。

コンテナを起動する際、止める際に少し鬱陶しく感じていたので、軽量化を試みました。

## Let's 軽量化！
行ったこととしては2つです。
1. .dockerignoreの追加
1. マルチステージビルド

.dockerignoreでは特に大したことはしていません。
node_module等を.dockerignoreに記しただけです。

マルチステージビルドは、Dockerfileを以下のように書き換えました。
```
FROM node:20.10.0 as build-stage

WORKDIR /app

RUN npm i -g @nestjs/cli \
    && yarn install

COPY . .

#実行ステージ
FROM node:20.10.0

WORKDIR /app

COPY --from=build-stage /app/node_modules ./node_modules
COPY --from=build-stage package*.json ./

CMD ["npm", "run", "start:dev"]
```

プログラム上ではそこまで大した変化ではないと思います。

## マルチステージビルドについて
冒頭のFROMがビルド用のステージです。依存関係のインストール等を行います。
その後のFROMで実行環境用のステージを開始し、すでにビルドされた依存関係等のみをコピーするため、ここでコピーする以外の不要なものはイメージに含まれない。

結果、実行環境は軽量なものとなる。

実際、イメージの容量は以下のように減った。

Next.jsコンテナのイメージ：1.5GB → 1.09GB
Nest.jsコンテナのイメージ：1.43GB → 1.09GB

Dockerへの理解度がまだまだ足らないため、まだ簡易的な記述だが、大きい規模のものになれば、さらなる効果を発揮するだろう。

## 終わり
Dockerエンジニアになろう
Docker利用でディスクの空き容量が減った時の対処方法

# はじめに

Windows上でDocker環境（Docker Desktop）を利用していると、いつの間にかディスクの空き容量がわずかになっていることがあります。
特にDockerの起動／コンテナの起動を繰り返していると不要なキャッシュが急速に増えていくようで、いつの間にか数十～100GB前後の不要なキャッシュが生じていることがあります。
そこで今回は、不要なキャッシュを削除することでディスクの空き容量を増やす手順をまとめています。

# 作業全体のイメージ

* Dockerが生成する仮想ディスク（ext4.vhdxとdocker_data.vhdx）は、ファイルサイズの拡張は自動的に行われます.
* 一方で、仮想ディスクの縮小は自動的に行われないため、ディスクの空き領域がどんどん減っていきます。
  * RDBMSのテーブルファイルがどんどん拡張していく一方で、自動的には縮小されない現象と似ているかもしれません。
* そのため、仮想ディスク内に含まれる不要なキャッシュファイルを削除した後、仮想ディスクに対して圧縮コマンドを実行することでディスクの空き容量を増やします。

# 事前作業1（バックアップの作成）

* 今回は仮想環境で実施したため、作業を行う前にスナップショットを作成しておきました。
  * これで操作をミスした時の心配をせずに作業できます。

# 不要なキャッシュの削除

* Docker Desktopが起動した状態で以下のコマンドを実行して、使用していないイメージ、コンテナ、ネットワークを削除（prune）します。
* 以下の実行結果を見ると、改修された全ての領域（Total reclaimed space）が35.08GBとなっていました。
  * コンテナの削除については、「docker ps -a」を実行しても表示されないキャッシュ情報も含めて削除されるようです。

```text:不要なキャッシュの削除
PS C:\Users\NKOJIMA> docker system prune 
WARNING! This will remove:
 - all stopped containers
 - all networks not used by at least one container
 - all dangling images
 - unused build cache 

Are you sure you want to continue? [y/N]
Deleted Containers: 
xxxxxxxxxxxxxxxxxxxxxxxxxx...

Deleted Networks:
xxxxxxxxxxxxxxxxxxxxxxxxxx...

Deleted Images:
untagged: xxxxxxx
deleted:
sha256:xxxxxxxxxxxxxxxxxx
untagged: yyyyyyy
deleted:
sha256:yyyyyyyyyyyyyyyyyy
...

Deleted build cache objects: 
xxxxxxxxxxxxxxxxxxxxxxxxx...

Total reclaimed space: 35.08GB
```

* 使用していないイメージやコンテナの削除だけで済ませたい時は、代わりに以下のコマンドを実行します。

```text:イメージとコンテナを個別に削除
// 使用していないイメージの削除
docker image prune

// 使用していないコンテナの削除
docker container prune
```

# 事前作業2（Docker DesktopとWSL2の停止）

* 仮想ディスクの圧縮を行う前に、以下の手順でDocker DesktopとWSL2を停止しておきます。

## DockerDesktopの停止

* タスクトレイからDocker Desktopのアイコンを右クリックして、「Quit Docker Desktop」を押してDocker Desktopを終了させます。
  * コマンドでDocker Desktopのプロセスを終了させる方法は見当たりませんでした...

## WSL2の停止

* 以下のコマンドでWSL2を停止します。

```text:WSL2の停止
wsl --shutdown
```

# 仮想ディスクの圧縮

* 仮想ディスクのあるフォルダに移動して、Optimize-VHDコマンドで仮想ディスクのサイズを圧縮します。
  * 多くのサイトでは「ext4.vhdx」を圧縮すると書かれていますが、私の環境では「docker_data.vhdx」も存在していたので、両方とも圧縮しました。
* なお、ディスク圧縮処理はディスクの帯域をフルに使うため、ディスクサイズや環境（HDD利用や仮想環境利用）によって処理時間が大きく変わると思われます。
* また、ここで利用しているOptimize-VHDコマンドはWindowsのエディションが「Pro」でないと使えないため、DISKPARTコマンドを使って圧縮するようです。

```text:仮想ディスクの圧縮
// ext4.vhdxの圧縮
cd C:\Users\NKOJIMA\AppData\Local\Docker\wsl\main Optimize-VHD -Path .\ext4.vhdx -Mode Full

// docker_data.vhdxの圧縮
cd C:\Users\NKOJIMA\AppData\Local\Docker\wsl\disk Optimize-VHD -Path .\docker_data.vhdx -Mode Full
```

# 注意点
## DockerのAPIバージョンが古い

* 試しに「docker image prune」を実行したところ、以下のようにAPIバージョンが古いというエラーメッセージが出ました。
* このようなエラーが出たときは、Docker Desktop本体を更新（バージョンアップ）することでエラーを解消できます。

```DockerのAPIバージョンが古い時のエラーメッセージ
PS C:\Users\NKOJIMA> docker image prune -a -f 
"image prune" requires API version 1.25, but the Docker daemon API version is 1.24
```

# 参考URL

* [使用していない Docker オブジェクトの削除（prune）](https://docs.docker.jp/config/pruning.html)
* [【最適化・格納先変更】Docker 肥大化したext4.vhdxの対処方法](https://zenn.dev/haretokidoki/articles/49dacc3516c441)
* [Dockerの一括削除コマンドについて](https://tech.kurojica.com/archives/57316/)
* [docker image prune したのにディスク空き容量が変わらない](https://brainlog.jp/server/docker/post-3359/)
プリザンターのアナウンス機能のプチ改善

## はじめに
プリザンターでサービス情報などを表示するために使われる[アナウンス機能](https://pleasanter.org/ja/manual/announcement-siteid)。標準だと何もスタイルが当たらない状態であったり、どこでも表示されたりとちょっと自由度が低く使い難い部分があります。今回はそこを改善してみます。

## スタイルをあててみる
アナウンス機能で表示される内容は「内容(`Body`)」に設定されているものになります。スタイルをあてるには`Body`の中身をクラスやIDを付与した`div`タグや`span`タグで巻く必要があります。
ただ、毎回Bodyの中にHTMLタグで巻いた文言を用意するのは不便。ということで、分類とサーバスクリプトを使用して、自動的に巻くようにしてみます。

イメージとしては、

```plantuml
@startuml

object div
div : class = [ClassA]
div : innerText = [DescriptionA]

object announce
announce : [Body]

announce <|-- div

@enduml
```

こんな感じになります。

### 実装してみる
マニュアルに従って期限付きテーブルを作成します。それをベースに、分類A、説明Aをくわえます。

分類Aには下記の選択肢を設定します。`announce-default`を既定値として必須項目にしましょう。
```
announce-default,通常
announce-info,情報
announce-success,成功
announce-warning,注意
announce-error,警告
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3555395/a7ba9368-36e6-4990-ae67-f5940d6a9583.png)

次に、サーバスクリプト作成します。条件は、更新前・作成前です。

```javascript
model.Body = '<div class="' + model.ClassA + '">' + model.DescriptionA + '</div>';
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3555395/5e55e150-caa3-424a-bf42-9aacd322b1c1.png)

最後は[拡張スタイル](https://pleasanter.org/ja/manual/extended-style)を設定します。メッセージの表示に使われているCSSをベースに作成してみました。

```css:Announce.css
[class^="announce-"] {
    margin-top: 4px;
    padding: 5px;
    border-radius: 20px;
}

.announce-default {
    color: #000;
    background-color: #fff;
    border: solid 1px #000;
}

.announce-info {
    color: #fff;
    background-color: #00f;
    border: solid 1px #00f;
}

.announce-success {
    color: #fff;
    background-color: #008000;
    border: solid 1px #008000;
}

.announce-warning {
    color: #000;
    background-color: #ff0;
    border: solid 1px #ff0;
}

.announce-error {
    color: #000;
    background-color: #f00;
    border: solid 1px #f00;
}
```

### 表示してみる

では、表示テストをしてみます。成功でテストと表示してみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3555395/b96c555b-688d-4c54-9e87-f7fb2e00ecf8.png)

いい感じに表示されました。

## ちょっとした裏技
アナウンス機能の表示制御ですが、

- Status : 完了(900)以上のステータスの場合は非表示にする
- StartTime - CompleteTime : 期間中のみ表示する

の2つしかマニュアルに記載されていません。実はこの2つ以外にも表示制御が可能です。

- CheckA : ログイン画面とトップ画面以外は表示しない
- CheckB : ログイン画面に表示しない
- CheckC : トップ画面に表示しない

いずれもチェックONの時の挙動となります。

## まとめ
今回は、アナウンス機能の見た目のデザイン性を向上させる方法を紹介しました。表示制御の裏技も含めて是非活用してみてください。
【Python】if文を使わないFizzBuzz

```python
def fizz():
    while True:
        yield ""
        yield ""
        yield "Fizz"


def buzz():
    while True:
        yield ""
        yield ""
        yield ""
        yield ""
        yield "Buzz"


if __name__ == "__main__":
    limit = 100

    for i, Fizz, Buzz in zip(range(limit), fizz(), buzz()):
        print((Fizz + Buzz) or i + 1)
```

実行結果

```
1
2
Fizz
4
Buzz
Fizz
7
8
Fizz
Buzz
11
Fizz
13
14
FizzBuzz
16
...
Fizz
97
98
Fizz
Buzz
```

# Appendix

kazuhoさんのFizzBuzz実装にインスピレーションを受けて。
Pythonならジェネレーターで似たようなことができるの良い仕様だと思う。

https://gist.github.com/kazuho/3300555