OmniAICreator/Qiita-1.07M huggingface dataset:
VMware FusionでOpenWrtを起動してみた

# はじめに

この記事は、Qiita Advent Calendar 14日目の記事です。
以下の記事より、すべての記事をご覧になれます。

https://qiita.com/0_terarin_0/items/2b60d47a2d0e64a273c3

# 本編

前回と一緒で今度はUTMじゃなくてVMWare Fuscionで起動しようぜ、みたいな感じです。おそらくですが、ここのユーザーさんはUTMよりもVMware Fusionが好きな方が多いと思いますのでこっちの方が需要があるかなと…。

https://openwrt.org/docs/guide-user/virtualization/fusion

ということで、前回と同じくこの手順に従ってやっていきましょう！

## OpenWrtのイメージをダウンロード

同じく下のページからまずイメージをダウンロードします。なお、イメージは`{ver}/targets/armsr/armv8/generic-ext4-combined.img.gz`というものをダウンロードしてください。

https://downloads.openwrt.org/releases/

ダウンロードが終わったら展開しましょう。ただし、アーカイブユーテリティでは展開できませんので`gzip`コマンドでやりましょう。

```zsh
gzip -d ~/Downloads/generic-ext4-combined.img.gz
```

ここからが違うところです、VMware Fusionでこのimgをそのまま起動ドライブに指定するのはできないので、`qemu-img`コマンドでファイルを変換します。

```zsh
qemu-img convert -O vmdk ~/Downloads/openwrt.img ~/Downloads/openwrt.vmdk
```

## VMware Fusionで仮想環境を作成

さて、仮想環境を作成していきましょう。

カメラ、サウンドカード、CD/DVDドライブを削除してネットワークカードの設定をします。

アダプター1はPrivate to my Macに設定しましょう。

![Screenshot 2024-12-19 at 20.05.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/583428/eed75089-e8c7-aea7-89ea-378d915a1a20.png)

ネットワークアダプターをもう1つ追加してShare with my Macに設定しましょう。（デフォルトのままです。）

![Screenshot 2024-12-19 at 20.05.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/583428/f51f5db5-6934-40cd-da3d-4550b572d9ec.png)

全部設定が終わったら下のようになっています。

![Screenshot 2024-12-19 at 20.04.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/583428/5d7f2179-7b66-4e1b-06c5-4d641abea3e3.png)

起動しましょう！なんかスクロールが止まったらその時点でReturnを押してください。

そのままネットワークの設定を行います。

```bash
uci show network.lan
uci set network.lan.ipaddr='172.16.132.2'
uci commit
service network restart

opkg update
```

これでOpkgのアップデートが変更できたら終わりです！

# 最後に

前回はなんかFastfetchやるとか言ってましたがちょっと別の記事になってしまいました。ここからちょっとずつOpenWrtで遊んでいきたいと思います。
DiscordTokenが流出した話

こんにちは。この記事では、私のDiscordTokenが流出してしまった体験談と、その原因や対策についてお話しします。この出来事は、私にとって大きな教訓となりました。同じ失敗を繰り返さないためにも、共有したいと思います。

## 背景

私はDiscordのBotを開発している最中、ローカル環境でテストを行うため、Tokenをコード内に直接記述していました。このコードはGitでバージョン管理を行っており、Tokenもそのままコミットされ、最終的にプライベートリポジトリにプッシュされていました。

多くの方が「プライベートリポジトリなら安全」と考えるかもしれません。しかし、GitHubのプライベートリポジトリであっても、Tokenを直置きすることは非常に危険です。万が一、アカウントが乗っ取られたり、共有設定にミスがあった場合、機密情報が第三者に流出するリスクがあります。

流出に気づいたきっかけは、Botが意図しない動作を始めたり、他人が私のBotを操作している形跡を見つけたことでした。この時点で、Tokenが悪用されていることを確信しました。

以下は、問題が発覚した際に確認した被害の一例です。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3474929/8fdc1700-9b44-fd21-a311-818d872b46be.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3474929/ee8ac320-2ee4-a4c8-04b8-21faabf09f07.png)

## 流出の原因

Tokenが流出した主な原因を以下にまとめます。

1. **Tokenをハードコーディングしていた**
   - Tokenをコード内に直接記述し、セキュリティ意識が不足していました。

2. **Gitリポジトリへのコミット**
   - `.gitignore`を適切に設定しておらず、環境変数や秘密情報を管理する基本を怠りました。

3. **プライベートリポジトリへの過信**
   - プライベートリポジトリなら安全だと誤解し、Tokenをリポジトリ内に保存していました。

## 問題発覚後の対応

問題に気づいた後、以下の対応を迅速に行いました。

1. **Tokenの再生成**
   - Discordの開発者ポータルにアクセスし、流出したTokenを無効化、新しいTokenを発行しました。

2. **アクセスログの確認**
   - DiscordのAPIログを確認し、不審なアクセスがないかを調査しました。

3. **セキュリティ対策の強化**
   - Tokenや機密情報の管理方法を全面的に見直し、以下の対策を実施しました。
     - 環境変数（`.env`ファイル）を利用してTokenを管理。
     - `.gitignore`を設定し、機密情報がコミットされないようにしました。

## 教訓と今後の改善

今回の失敗を通じて、以下の重要なポイントを学びました。

- **プライベートリポジトリへの過信は禁物**
  - プライベートリポジトリであっても、Tokenや機密情報を直接保存してはいけません。

- **公開リポジトリでのセキュリティ意識を高める**
  - リポジトリを公開する前に、機密情報が含まれていないか必ず確認します。

- **定期的なセキュリティチェック**
  - リポジトリやAPIの設定を定期的に見直し、潜在的な脆弱性を排除します。

## まとめ

今回のToken流出は非常に苦い経験でしたが、貴重な教訓となりました。この記事を読んでくださった皆さんには、私の経験を通じてセキュリティ意識を高めていただければと思います。
新卒ゲームエンジニアの探検記

##
この記事は[グレンジアドベントカレンダー](https://qiita.com/advent-calendar/2024/grenge)20日目の記事になります！

# 自己紹介

株式会社グレンジに2024年度に新卒入社した原島です！職種はクライアントエンジニアです。

普段の業務ではUnityを用いてモバイルアプリのクライアントサイドの実装であったり出稿する広告の制作などを行っています。

# 会社について

グレンジの所属するサイバーエージェントのゲーム事業部は、各社の強みを活かした子会社戦略をとっており、全部で9つの子会社で構成されています。
![image (7).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2919633/72f7443a-1377-e824-f9a8-7b57010ff585.png)



ゲーム事業部に配属の決まった新卒は各子会社へ希望を出し、研修後各社に配属されます。

グレンジは現在ポコロンダンジョンズというタイトルを運用しながら、新規開発も並行して行なっています。

# 入社前〜配属

サイバーエージェントには入社前に現場で就業経験を積むことができる内定者アルバイトという仕組みがあり、私自身も１年ほどで７つの子会社で就業経験を積みました。

この内定者バイト期間を振り返ると、エンジニアとしての技術力向上、入社前に現場の開発の流れを知ること、各子会社の社員との繋がりができたことが大きな収穫でした。

それと同時に、子会社への配属希望の大きな判断材料になったと感じています。

実際に就業し役員やプロデューサーの方にお話を聞いたり、プロジェクトの中に入って開発、運用をすることで各社の根本にある考え方の解像度がぐんと上がりました。

会社の方針や考え方はその会社のプロジェクトや社員の雰囲気、働き方などにも色濃く反映されます。また、プロジェクトや人は様々な都合で移り変わるものですが、会社の根底にある考え方や指針はそう簡単に変わりません。

これに共感し納得感を持って仕事ができるかが、配属後長く活躍するためにとても大事だと考えています。

# なぜ現在の会社を選んだのか

グレンジに配属希望を出した理由はずばり、環境です！

グレンジはゲーム事業部の中では比較的規模の小さな会社なのですが、10周年を迎えたポコロンダンジョンズの他にも複数のプロダクトを開発してきました。

その中で働く社員も知識や経験が豊富なベテランが多く、常に大きな背中を見せてくれます。

「新卒だから、」という枕詞なしに同じ土俵、目線で仕事ができる環境がとても魅力的です！

そんなつよつよ先輩エンジニアと日々議論をしたりタスクのFBをもらうことができるので、自分の成長角度も上がっていき、成果を出すことができると考えました。

# 目標設定

入社後まず初めにしたのが、半期~1年での目標設計です。

業務の内容が含まれるので具体的には記載しませんが、以下のことを意識しました！

## 定量的

これは「平均チケット消化〇〇件！」などの数字や基準を設けることです。

定量的に測れる指標を目標に盛り込むと振り返った時に達成度合いが明確で、改善もしやすいですし評価する側も分かりやすいです。

設定する数字は根拠があるとよいですが、難しい場合はわかりやすい数値をせっていするとよいかもしれません（センス！センス！）

## ちょっと背伸びする

半期で達成できるであろう成果量+αくらいの設定を意識することです。

ほぼ確実に達成できるであろう目標だと、どこか気が緩んだり低い基準にフォーカスを合わせてしまって成長機会を逃してしまうことに繋がってしまうと思います。

逆に不可能な目標を設定してしまうのも、無理と分かった途端に目標が意味のないものになってしまいあまり効果的ではないかもしれません。

「ちょっと」の基準は人やタスクによって違うので修正しながらでもいいかもしれません（これもセンス！センス！）

例）チケットの消化目標

1日2件（ほぼ確で達成できるライン）→ 「とりあえず2件終わらて目標達成だから3件目はいいか…」

1日3件（ちょっと背伸びしたライン）→できそうでできないから工夫するし、あとちょっとでいけそう…！で踏ん張れる

1日10件（現実的じゃないやりすぎライン）→ 絶対無理だから達成感ない 😇

## 事業目線かつ個人目線

一番大事かもしれません。配属前の子会社選びでも触れましたが、些細なタスク一つをとっても「なんのためにやるのか」を意識するとやる気やアウトプットの質も変わりますし、「なんのために」を紐解くと会社が定めているビジョンや目標に行き着くと思います。

それと自分のやり甲斐ややりたいことの方向性と同じだと「好きなことをやってたら成果出た」という無敵の状況が生まれます。

自分の場合だと「３年後どうなっているのが個人の理想状態か」ということ、「自分のやる気の源泉」を改めて考えるのと同時に、

「会社として目指しているゴール」と「そのために何が必要か」を過去の開発ログであったり先輩社員の話を聞いて解像度を上げていきました。

# さいごに

就活生や自分と同じ新卒の方々の参考になれば幸いです！

メリークリスマス！！
ブラウザ拡張機能でログを新しいウィンドウに出力する

# 概要

これは[初心者のブラウザ拡張機能 Advent Calendar 2024](https://qiita.com/advent-calendar/2024/browser-extension)の18日目の記事です。

簡単にデバッグログをページに出力する方法を記載します。

# やること

拡張機能を作っているときに`console.log`で出力されるログを新しく作ったウィンドウに表示します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/302006/0ea9d55b-8365-e6f0-3d2f-00bd6adc42b9.png)

# 具体的なコード

```html:page.html
<!DOCTYPE html>

<html>
  <head>
    <meta charset="utf-8">
    <meta name="color-scheme" content="dark light">
  </head>

<body>
    <h1>拡張機能ページ</h1>
    <pre id="log"></pre>
    <script src="log.js"></script>
</body>

</html>
```

```javascript:log.js
const logElem = document.getElementById("log");
console.log = (msg) => (logElem.textContent = `${logElem.textContent}\n${msg}`);

setInterval(() => {
    console.log("log");
}, 1000);
```

`console.log`をアロー関数でつないで`logElem`のテキストコンテンツヘ出力するようにします。
`logElem`は`log`というIDを持つDOM要素で、HTMLファイル内で作成しておきます。

ログを出力する処理として`setInterval`を使っていますが、ここは各機能でデバッグしたいときに`console.log`を使うようにします。


あとは新しいウィンドウを作るように拡張機能の各ファイルを作ります。

```json:manifest.json
{
    "browser_specific_settings": {
        "gecko": {
          "id": "the-town-sample-consolelog@example.com"
        }
    },
    "manifest_version": 3,
    "name": "init-extention",
    "version": "0.1",
  
    "description": "コンソールログサンプル",
  
    "icons": {
      "48": "icons/icon-48.png"
    },

    "background": {
        "scripts": ["background.js"]
      },
  
      "permissions": [
        "menus"
      ]
}
```

```javascript:background.js
browser.menus.create(
    {
      id: "sample",
      title: "sample menu",
      contexts: ["page"],
    }
  );

function createPage() {
    let createData = {
        type: "popup",
        url: "page.html",
        width: 500,
        height: 300,
      };
    let creating = browser.windows.create(createData);
}

browser.menus.onClicked.addListener((info, tab) => {
    if (info.menuItemId === "sample") {
        createPage();
        console.log("click");
    }
});
```

# まとめ

`console.log`で通常時はコンソールに出力し、デバッグしやすいようにウィンドウ内に表示させるのも良いなと思います。

既存コードで`console.log`を使っているものに対してデバッグするときに有用かなと感じます。

# 参考

[画面キャプチャ API の使用](https://developer.mozilla.org/ja/docs/Web/API/Screen_Capture_API/Using_Screen_Capture#%E4%BE%8B)
このドキュメント内に使い方がありました。
eslintを実行したらSIGSEGVで終了してしまう

## 発生していたエラー

ある日、いつも通りeslintを実行しようとしたところ、SIGSEGVで終了してしまうことが起きた。

```console
$ eslint '**/*.ts'
error Command failed with signal "SIGSEGV".
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
```

## 対処法

原因を探っていたら、`node_modules/bin/eslint.js`の以下の`v8-compile-cache`をrequireしている行でエラーになっていることがわかった。

```js
// to use V8's code cache to speed up instantiation time
require("v8-compile-cache");
```

`v8-compile-cache`で類似のエラーを探していたところ、どうやら`v8-compile-cache`のキャッシュが原因そうとのことだった。

https://zenn.dev/anatoo/articles/1a9a686a14b437

`v8-compile-cache`のREADMEによると、

https://github.com/zertosh/v8-compile-cache

> Set the environment variable `DISABLE_V8_COMPILE_CACHE=1` to disable the cache.
>
> Cache directory is defined by environment variable `V8_COMPILE_CACHE_CACHE_DIR` or defaults to `<os.tmpdir()>/v8-compile-cache-<V8_VERSION>`.

とのことなので、キャッシュを消してみたところeslintが動くようになった。

```console
$ rm -fr $(node -r 'node:os' -e 'console.log(os.tmpdir())')/v8-compile-cache-*
```

たびたび起こるが、現時点ではSIGSEGVになる条件がわかっておらず、上記の対応で誤魔化している。
どこからがPowerBI？どこまでがExcel？（PowerQueryの話）

## はじめに
Power BIに興味を持った方に向けて、Excelとの違いを簡単にまとめます。
「EBPMを推進したいのでPowerBIを導入する。将来的には全社展開していく」
そんなことを考えはじめた方のお役に立てれば幸いです。

※BI（ビジネスインテリジェンス）とは、多様なデータソースからデータを収集・加工・分析・可視化し、業務上の意思決定に活用すること。

## PowerBIとは
PowerBIはデータの共有・可視化を行うためのツールで、Microsoft PowerPlatformの一員です。
Desktop版・Pro版などのラインナップがありますが、ここでは一括りに論じます。

## Power Queryとは
Power Queryはデータの前処理(※)を行うためのツールで、ExcelやPower BIに搭載されています。
※データを利用しやすくなるよう変換、結合、欠損値補完などで整えること

データはファイルだけでなく各種データベースやオンラインサービスといった多様なデータソースから受け取って利用できます。
PowerPlatformファミリーなのかofficeファミリーなのか微妙な立ち位置のヤツです。


- Power Queryは**データの前処理を行うツール**
- Power Queryは**ExcelとPower BIの両方に搭載されている**
大事なことなので２回言いました。


## どこまでがExcel？
すなわち、BIツールの紹介としてよく書かれている「大量データの前処理」「多様なデータソースからのETL」はPowerBIにおいてはPowerQuery側の機能であり、
同じくPowerQueryを搭載しているエクセルでも（ほとんど）同じことができます。
さらに、エクセルはPowerPivotも組み合わせれば**リレーションシップや可視化**まで可能であり、ビジネスインテリジェンスへの対応範囲は意外と広いのです。


## 改めて、どこからがPowerBI？
そんなエクセルに対して、PowerBIの差別化ポイントは以下のような点になります。
**更に大量の**データ処理（数百万レコード規模、多数のデータソース）
**更に多様かつ動的な**可視化表現
**更にリアルタイムかつ高度な**データ更新

## PowerBIはどんなとき必要か
ここまで読んでくださったら、「EBPMを推進したいのでPowerBIを導入する」というロジックは飛躍していると分かっていただけると思います。

言うまでもなく一般ユーザーにとってはエクセルの方がデファクトスタンダードですので、
PowerBIに惹かれたEBPM推進担当者は、**「Excelでいいじゃん」** という自問からは逃れられません。

PowerBIを展開する際には、以上の話を踏まえて「エクセルでなくPowerBIであるべき理由」をしっかり掘り下げておく必要があります。
もちろん、BI黎明期の啓発にエクセルを活用したうえで段階的にBIを導入するといった両刀遣いも有効です。
【ABC解説】 ABC384 解説 (B~D)【Python】

トヨタ自動車プログラミングコンテスト2024#12（AtCoder Beginner Contest 384） のB問題〜D問題をPythonで解説します。

https://atcoder.jp/contests/abc384

# 提出コード

https://github.com/Syogo-Suganoya/AlgoArena/tree/main/atcoder/ABC/ABC384

# B問題
https://atcoder.jp/contests/abc384/tasks/abc384_b

## 問題
![B-1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411120/d13f2c54-cad6-6a2f-6a57-2cdad29081af.jpeg)

<details><summary>画像の文字起こし</summary>

Div.1とDiv.2があります。
それぞれのコンテストにはレートの更新範囲があります。
Div.1の更新範囲は1600～2799です。
Div.2の更新範囲は1200～2399です。
参加したコンテストと、増レート数が与えられます。
現在のレートがコンテストの更新範囲ならレートを更新して、最終的なレートを出力してください。

</details>

## アプローチ
![B-2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411120/cfc20acf-b6dd-f8b2-be75-c9b1181178a6.jpeg)

<details><summary>画像の文字起こし</summary>

forとifで実装できます。
Dで条件分岐して、レートの更新範囲なら、レートに足します。

</details>

# C問題
https://atcoder.jp/contests/abc384/tasks/abc384_c

## 問題
![C-1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411120/ec27c0a8-8bb9-df85-dcf5-41b75ec920ba.jpeg)

<details><summary>画像の文字起こし</summary>

AからEまでの問題があり、各問題の得点が入力されます。
コンテスト参加者の得点状況は文字列で管理されます。
BCD ならBとCとD問題が解けて、それ以外は解けなかったことを表します。
ありうる得点の取り方の組み合わせを全て列挙してください。
並び方はスコアの降順、名前の昇順で並べてください。

</details>

## アプローチ
![C-2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411120/563a844a-6a60-324a-64e9-4c5316929f32.jpeg)
![C-3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411120/89db3094-304b-9ade-6e2f-425d01187635.jpeg)

<details><summary>画像の文字起こし</summary>

Bit全探索で2^5までを全探索します。
bitが立っている箇所をその得点が取れたこととして、記録します。
同時にABCDEの名前もそのbitが立っている文字をとって名前を生成します。

最後に名前の昇順にソートしてから、得点の降順にソートします。
先に名前の昇順をすることで、得点のソートをした際に、得点、名前のソートがされるようになります。

</details>

# D問題
https://atcoder.jp/contests/abc384/tasks/abc384_d

## 問題
![D-1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411120/682905de-6432-2d69-ed80-65000b7f2e79.jpeg)

<details><summary>画像の文字起こし</summary>

数値SとリストAが与えられます。リストAの中身は軽数です。
リストAの部分集合の和から、Sを生成できるかを求めてください。

例1
S = 42
A = [3, 8, 4]

[8,4,3,8,4,3,8,4］の部分集合で生成できます。

例2
S = 1
A = [3, 8, 4]

どの部分集合でも生成できません。

</details>

## アプローチ
![D-2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411120/1a8ee68f-9206-744d-3996-074aaabb6935.jpeg)

<details><summary>画像の文字起こし</summary>

最初にSをAの和で割った余りを求めます。
こうすることで、計算範囲をSまでにできます。これをaとします。
S = sum(A) * x + aと置けます。
したがって、このaが部分和にあるなら、Sを生成できます。
a = 42 % (3 + 8 + 4) ＝ 12
a + 累積和が累積和の1つなら、それは生成できるということになります。
a+3=15の15は累積和に含まれます。よって生成できます。

</details>

## 累積和の特徴
![D-3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411120/092e6ad1-46be-7a21-9e93-540ce18e255a.jpeg)

<details><summary>画像の文字起こし</summary>

累積和a - 累積和b ＝ 部分和k が成り立ちます。

</details>
AndroidでViewBindingを実装する方法

## ViewBinding

ViewBindingとは：

- Androidでプロジェクトを作成する際、xmlファイルとkotlin/Javaファイルのソースが別々なため、kotlinファイル内でxmlファイル内の要素を指定したい場合、`findViewById()`を使っています。しかし、プロジェクトが大きくなったり、要素が増えるといちいち`findViewById()`と記載するのは面倒です。
    
    → そこでViewBindingです！
    
    ViewBindingを実装すると`findViewById()`を記載することなくxmlファイル内の要素を指定できます。

## ViewBindingと似たDataBindingとは何か？
- ViewBindingの上位互換。ただし、エネルギー消費的にViewBindingで済む箇所はできる限りViewBindingを使用していきましょう。

## ViewBindingの実装
### build.gradle(Module:app)内の記述
- build.gradle(Module:app)を開き、`android{}`配下に以下の記入しましょう。
    
    ```kotlin
    buildFeatures {
        viewBinding = true
    }
    ```
     - 記載をしたらSyncする必要があります。
     
- Syncを終えたら、Build＞Rebuild ProjectよりGradleを再度ビルドしましょう。
    - `findViewById()`を記載する代わりにBindingオブジェクトを使います。Rebuild Projectすることにより、ViewBindingがそれぞれのレイアウトに対し、Bindingオブジェクトを作成します。
        - 例：activity_main.xmlはBindingオブジェクトとしてActivityMainBindingを作成します。
        
    #### Bindingオブジェクトを作成しないxmlファイルがある場合
    
    - Bindingオブジェクトを作成しないxmlファイルがある場合はxmlファイルの最上要素のConstraintLayout等に以下を追加します。
        
        ```kotlin
        tools:viewBindingIgnore="true"
        ```

### MainActivity.kt内にBindingクラスをインポート
- もともとの記載のsetContentView(R.layout.activity_main)を消し、bindingオブジェクトを使用する記述を追加します。
    
    ```kotlin
    class MainActivity : AppCompatActivity() {
    	private lateinit var binding: ActivityMainBinding
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            //setContentView(R.layout.activity_main)
            
            binding = ActivityMainBinding.inflate(layoutInflater)
            val view = binding.root
            setContentView(view)
        }
    }
    ```
    #### ソースコードの説明
    - 元の記述である`setContentView(R.layout.activity_main)`の一文をコメントアウト。
        ```kotlin
        binding = ActivityMainBinding.inflate(layoutInflater)
        val view = binding.root
        setContentView(view)
        ```
        
        - これによりBindingオブジェクトを使ってxmlファイルとkotlinファイルを繋ぎます。これでViewBindingの実装ができました。

## 繋いだ後のViewBindingの使用方法
- binding.〇〇のように記載します。〇〇にはxmlファイルの要素idが入ります。
        
    ```kotlin
    binding.btnSubmit.setOnClickListener {
        val name = binding.etName.text.toString()
        binding.tvMessage.text = "Hello $name"
        binding.etName.setText("")
    }
    ```
        
    - また、bindingを多く使用する場合はbinding.apply{}スコープで囲うとbinding以降の記述のみにすることができる。
    
        ```kotlin
        binding.apply{
            btnSubmit.setOnClickListener {
                val name = etName.text.toString()
                tvMessage.text = "Hello $name"
                etName.setText("")
            }
        }
        ```

## まとめ
- 以前まではXMLに記載した要素はfindViewById()から一つずつ取得していたものが、ViewBindingを使用することによって`findViewById()`の使用回数と、変数の作成、宣言数を減らすことができます！

    ViewBindingを実装することでソースコードが見やすくなりますし、すっきりします。
    ぜひ活用してみてください。
KiCADのJLCPCBプラグインでPOSのエラーが出るときの対処法

みなさん、回路設計はKiCADを使っていますか？
KiCADにはJLCPCBプラグインというものがあり、JLCPCBさんに発注するためのデータを自動で生成することができます。

今回はその際にPOSのところでエラーが出たので対処法を共有しようと思います。

# 問題
以下の用に、ガーバーデータを出力する際にPOSが×となっている部品がある。
このような部品があるとJLCPCBにアップロードしたときにエラーとなる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3124670/6f1a5064-116d-2b55-0aa7-0ee33510c3c1.png)

# 対処法
該当の部品のプロパティを見て、「部品配置ファイルから除外」にチェックが入っていればチェックを外す。
もしくは「部品表から除外」にチェックを入れる。（こうすると電子部品として認識されなくなる）。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3124670/4c22a028-97c9-c734-ca25-6ba1412fd292.png)
prismaを初期化したら謎のメッセージ(Error: (0 , KSe.isError) is not a function)が表示されて失敗した話

# はじめに
Next.jsプロジェクトにprismaを導入しようとしたら、
以下のようなメッセージが表示されてprismaの初期化に失敗したので、
原因と対応内容を備忘録として残します。
```bash
% npm install prisma --save-dev
% npx init prisma
Error: (0 , KSe.isError) is not a function
```

# 筆者のバージョン
```bash
% node -v
v23.4.0

% npx prisma --version
prisma                  : 6.1.0
@prisma/client          : 5.16.1
```

# 原因
Nodeの最新バージョンv23に対応していないためでした。
以下は現時点(2024/12/19)でのPrisma公式サイトの対応状況です。
![iScreen Shoter - Google Chrome - 241219190731.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3947973/3fe23b72-2a27-5c63-9a1f-e02a05e08cce.jpeg)

# 対応
Nodeのバージョンを対応バージョンに差し戻します。
`n`というパッケージ管理ツールでダウングレードするのが簡単でした。
今回は22.11にダウングレードしてみます。
```bash
# n をインストールしていない場合
% sudo npm install -g n

# インストール確認
% npm list -g            
/usr/local/lib
├── corepack@0.30.0
├── n@10.1.0
└── npm@11.0.0

# 切り替え可能なバージョンの確認
% n ls-remote --all
23.4.0
23.3.0
23.2.0
23.1.0
23.0.0
22.12.0
22.11.0
...

# Nodeのダウングレード
% sudo n 22.11.0

% node -v
v22.11.0
```

もし切り替わらない場合は一度ターミナルを消して、
再度`node -v`を実行してみてください。

# 再度prismaの初期化を実施してみる
```bash
% npx prisma init     

✔ Your Prisma schema was created at prisma/schema.prisma
  You can now open it in your favorite editor.
```

無事初期化することができました！
【ABC解説】 ABC383 解説 (B~D)【Python】

大和証券プログラミングコンテスト2024（AtCoder Beginner Contest 383） のB問題〜D問題をPythonで解説します。

https://atcoder.jp/contests/abc383

# 提出コード

https://github.com/Syogo-Suganoya/AlgoArena/tree/main/atcoder/ABC/ABC383

# B問題
https://atcoder.jp/contests/abc383/tasks/abc383_b

## 問題
![B-1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411120/832c8a2a-78c4-f905-e17a-2549afec240c.jpeg)

<details><summary>画像の文字起こし</summary>

H*Wのマスがあります。マスには机と床があります。
床のマスから異なる2マスを選んで加湿器を置くとき、最も加湿される床のマス数を求めてください。
加湿器はマンハッタン距離がD内の床のマスを加湿します。
マンハッタン距離とは2点（X,y），（X,y）における|xーx'|＋|y-y'|です。

（1,1） と （1,5） のマスに加湿器を置くことが最も加します。
（1,1） ， （1,5） のマンハッタン距離は0（2,1）のマンハッタン距離は1です。
よって、加湿される床のマス数は3です。

</details>

## アプローチ
![B-2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411120/9adf6872-5bc1-2f7b-0601-755f3ec3773c.jpeg)
![B-3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411120/3e50434f-2de0-6fd8-acaf-44b53473dc91.jpeg)

<details><summary>画像の文字起こし</summary>

2つの加湿器を置く組み合わせを全パターン試して、最も加湿される組み合わせを探索します。
1つ目の加湿器は全ての床のマス、2つ目の加湿器は現在1つ目の加湿器が置かれていない床以外のマスを探索します。

加されるマスの探索も全探索します。
現在置かれている加湿器のマンハッタン距離内のマスを加湿されるマスとしてカウントします。
つまり3重ループの処理になります。

</details>

# C問題
https://atcoder.jp/contests/abc383/tasks/abc383_c

## 問題
![C-1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411120/61622152-63ae-272c-f1ff-f37d96cff2ad.jpeg)

<details><summary>画像の文字起こし</summary>

H*Wのマスがあります。マスには壁と床と加湿器があります。
加湿器は床を上下左右にD回以内で移動できる床のマスを加湿します。
加湿される床のマス数を求めてください。

</details>

## アプローチ
![C-2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411120/11473413-0c65-6e8c-4e16-5b2ec3177253.jpeg)

<details><summary>画像の文字起こし</summary>

多始点BFSで解けます。
最初に加湿器の位置をキューに追加しBFSを始めます。
移動距離がD以内で届くマスを記録し、最後にそのマス数を出力します。

よって、5マスです。

</details>

## BFSとは
![C-3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411120/fda03396-4c5d-67ef-9883-8035e774a764.jpeg)

<details><summary>画像の文字起こし</summary>

・幅優先探索です。
・近いところから順番に探す方法です。
・キューを使います。

</details>

# D問題
https://atcoder.jp/contests/abc383/tasks/abc383_d

## 問題
![D-1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411120/bdd45759-123c-2b84-bd90-75d455207ccf.jpeg)

<details><summary>画像の文字起こし</summary>

N以下の正整数のうち、正の約数をちょうど9個持つものの個数を求めてください。

入力例 1
200
出力例1
3

36,100,196の3つです。
例えば、36の約数は 1,2,3,4,6,9, 12,18,36の9つです。

入力例2
4000000000000
出力例 2
407073

</details>

## アプローチ
![D-2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411120/ebccdbc9-90ae-f44d-4b4f-330bcf27aa06.jpeg)

<details><summary>画像の文字起こし</summary>

N以下の約数の個数の求め方には公式があります。

Nの素因数分解を以下のように置きます。
`N=Pi*P%*.. *Pi`

約数の個数は次の公式で求められます。
`（ei+1） * （ez+1） *…* （ek+1）`

例えば`12=（2^3）*（3^1）`です。
よって約数の個数は`（2+1）*（1＋1）=6`となります。
実際に12の約数は 1,2,3,4,5,6,10,12の6個です。

正の約数が9個となるのは `P^8`の時と`P^2*Q^2`の時のみです。
`P^8`は`（8+1）=9`、`P^2*Q^2`は`（2+1）*（2+1）=9`です。

あとは、Pは素数なので、素数一覧をループします。
ループ範囲は、Nまでで十分です。`P^2*Q^2＜＝N`より、`P,q＜＝N`となります。

素数一覧はPythonだと `sympy.primerange` が便利です。
`primerange(start, end)`
`primerange(10, 50) = [11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47]`

素数をループして、`P^8＜=N`もしくは`P^2*Q^2＜=N`に当てはまる数をカウントします。

</details>
CSSで斜線を引く（offset-pathを使ったケース）

この記事にインスパイアされました。

https://zenn.dev/fraim/articles/6501d8f8842a7c

グラデーションで描くことしか思いつかなかったので、この手法はいいな、と感じました。



なので、三角関数を使わずに、`offset-path`で左上から右下までパスを書き、`offset-rotate: auto`で、そのパスの角度に回転させてしまおう、という発想で書いてみました。

```css
.diagonal-box {
    container-type: size;
    position: absolute;
    height: 100%;
    background: rgba(0, 0, 0, 0.25);
    top: 0;
    left: 0;
    width: 100%;
    overflow: hidden;
    pointer-events: none;

    &::before {
        content: "";
        display: block;
        position: absolute;
        width: max(200cqh, 200cqw);
        border-bottom: 1px solid #f00;
        offset-path: polygon(0% 0%, 100% 100%); /* これ */
        offset-anchor: top left; /* これ */
    }
}
```


<p class="codepen" data-height="300" data-default-tab="result" data-slug-hash="ZYzeMBN" data-pen-title="Diagonal line" data-user="lhankor_mhy" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/lhankor_mhy/pen/ZYzeMBN">
  Diagonal line</a> by lhankor_mhy (<a href="https://codepen.io/lhankor_mhy">@lhankor_mhy</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

ただ、Chrome において、とある reset CSS を使うと、なぜかリサイズに追従しなくなるのが気になっています。何が原因なんだろ……？

---

調べてみたところ、Chrome のバグっぽいです。かなり限定された状況でしか再現しませんでした。
【競技プログラミング】AtCoder Beginner Contest 220_D問題

# 問題
https://atcoder.jp/contests/abc220/tasks/abc220_d

## 要約
1. 0から9までの整数からなる長さNの数列Aがある。

2. 数列の長さが1になるまで、以下の2つの操作のいずれかを繰り返し行う
   - 操作F: 左端の2つの値(x,y)を削除し、(x+y)%10を左端に挿入
   - 操作G: 左端の2つの値(x,y)を削除し、(x×y)%10を左端に挿入

3. K = 0, 1, ..., 9 について、以下の問題に答える。
   - 最終的に残る値がKとなる操作手順は何通りあるか？

4. 答えは998244353で割った余りを求める。

- N: 数列の長さ
- A = (A1, ..., AN): 初期の数列
- K: 最終的に残る値（0から9の各値について計算が必要）

# 既存投稿一覧ページへのリンク
[一覧ページ](https://qiita.com/o_chan_t/items/fc759695acfaef8df2cc)


# アプローチ

動的計画法を用いて、各ステップでの可能な状態とその状態に至る方法の数を追跡する。
二次元のDPテーブルを使用し、dp[i][j]を「i番目の要素まで処理した時点で、現在の値がjとなる操作手順の数」と定義する。
初期状態から始めて、順次状態を更新していくことで最終的な結果を得る。

# 解法手順

1. 入力を受け取る。数列の長さnと数列aを取得する。

2. dp[n][10]の二次元配列を作成し、0で初期化する。

3. 初期状態としてdp[0][a[0]] = 1とする。これは、最初の要素a[0]から始める唯一の方法を表す。

4. i = 1からn-1まで以下の処理を繰り返す：
   a. j = 0から9まで以下の処理を繰り返す：
      - dp[i][(j+a[i])%10] += dp[i-1][j]を計算し、998244353で割った余りを取る（操作F）
      - dp[i][(j*a[i])%10] += dp[i-1][j]を計算し、998244353で割った余りを取る（操作G）

5. 最終的な結果として、dp[n-1][0]からdp[n-1][9]までの値を出力する。各値は998244353で割った余りとなっている。


# ACコード
```python:ac.py
def io_func():
    # 数列の長さnを入力として受け取る
    n = int(input())
    # 数列aを入力として受け取り、整数のリストに変換する
    a = list(map(int, input().split()))
    return n, a

def solve(n, a):
    # dp[i][j]: i番目の要素まで処理した時点で、現在の値がjとなる操作手順の数
    dp = [[0]*10 for _ in range(n)]
    
    # 初期状態の設定
    dp[0][a[0]] = 1
    
    # 動的計画法による状態の更新
    for i in range(1, n):
        for j in range(10):
            # 操作F: 加算
            dp[i][(j+a[i])%10] += dp[i-1][j]
            dp[i][(j+a[i])%10] %= 998244353
            # 操作G: 乗算
            dp[i][(j*a[i])%10] += dp[i-1][j]
            dp[i][(j*a[i])%10] %= 998244353
    
    # 結果の出力
    for i in range(10):
        print(dp[n-1][i])

# メイン処理
n, a = io_func()
solve(n, a)

###
# n: 数列の長さ
# a: 入力された数列
# dp: 動的計画法のテーブル。dp[i][j]は、i番目の要素まで処理した時点で、現在の値がjとなる操作手順の数を表す

# 1. io_func関数で入力を受け取る
# 2. solve関数で主な処理を行う
#    - dpテーブルを初期化
#    - 初期状態を設定
#    - 動的計画法により状態を更新
#    - 最終結果を出力
# 3. メイン処理でio_func関数とsolve関数を呼び出す
```

# 計算量の概算

O(n)

# 動的計画法について
## 問題
この問題では、最終的に残る値Kとなる操作手順の数を求める必要がある。

## DPテーブルの設計
DPテーブルを「i番目の要素まで処理した時点で、現在の値がjとなる操作手順の数」として設計する。

## 状態遷移の考え方
- 初期状態: dp[0][a[0]] = 1 （最初の要素a[0]から始まる）
- i番目の要素を処理する際:
  - 操作F（加算）: dp[i][(j+a[i])%10] += dp[i-1][j]
  - 操作G（乗算）: dp[i][(j*a[i])%10] += dp[i-1][j]

   これは、「i-1番目まで処理して値jになる方法数」から、「i番目も処理して新しい値になる方法数」を計算しています。

## 結果
dp[n-1][K]が、数列全体を処理して最後にKになる操作手順の数を表す。
Flutterについてお世話になった記事のまとめ

https://qiita.com/kanatatsu64/items/bd33c85fbf890743cfc5

https://zenn.dev/tatukane/articles/1985d23cfae8d8

https://qiita.com/ishikawato/items/60fe536a54fdcb1c38f4

https://qiita.com/Statham/items/46812e0aab4862d44709

https://zenn.dev/mukkun69n/articles/d594bdc25b932c

https://blog.pentagon.tokyo/138/

https://zenn.dev/susatthi/articles/20220406-061305-flutter-native-splash

https://zenn.dev/susatthi/articles/20220413-153500-flutter-logger

https://zenn.dev/inari_sushio/articles/0f4c606c8340ee#%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E4%BF%9D%E5%AD%98%E6%99%82%E3%81%AE%E8%87%AA%E5%8B%95%E3%82%A2%E3%82%AF%E3%82%B7%E3%83%A7%E3%83%B3%E3%82%92%E8%BF%BD%E5%8A%A0%E3%81%99%E3%82%8B
if-elseラダー(else if)が構文ではないことを確認してみた

## はじめに

「[プロになるJava
―仕事で必要なプログラミングの知識がゼロから身につく最高の指南書](https://gihyo.jp/book/2022/978-4-297-12685-8)」でelse ifに関して興味深い文章が書いてあったので調べました。

> 実際には特別な構文があるわけではなく、else句のあとに新たにif文をつなげているだけです。

## if-elseラダーとは

if-else if-elseの構造をとりelse ifを含むif文を言います。
この構造は条件を絞り込むときに有用です。
また、条件が真(true)になった時点で処理がスキップされます。

## ここで疑問発生

**特別な構文でないのならば、なぜその後の処理をスキップできるのか**

if-elseの後にif-elseをつなぐと条件分岐が2回起きるのではないかと考えました。
私は、else ifでなぜスキップができるのかわからなくなってしまいました。

## Geminiに聞いてみた

> 「else if」は、厳密に言えば独立した特別な構文というよりは、「else」ブロックの中に別の「if」文をネスト（入れ子）にした構文の略記法、または慣用句と捉えることができます。

ここでelse ifの表現がif文のネスト(入れ子)を表現しているという新たな発想に気づきました。

また、else ifのようにif文のネストを略記するものをシンタックスシュガーということも知りました。

## シンタックスシュガー(糖衣構文)とは

[IT用語辞典 e-Words](https://e-words.jp/w/%E3%82%B7%E3%83%B3%E3%82%BF%E3%83%83%E3%82%AF%E3%82%B9%E3%82%B7%E3%83%A5%E3%82%AC%E3%83%BC.html)より

>  シンタックスシュガー（syntax sugar）とは、プログラミング言語で、ある構文を別の記法で記述できるようにしたもの。長い構文を簡略に記述できるようにしたり、複雑な構文を読み書きしやくするために用意される。

アロー関数もシンタックスシュガーの一種といえますね。

## まとめ

else ifは構文ではなく略記の一種(シンタックスシュガー)でした。

## さいごに

else ifのことをすでに知っているような気でいましたが新しい発見があり調べてよかったです。
また、シンタックスシュガーという概念にも触れられてよかったです。

## 参考
[プロになるJava
―仕事で必要なプログラミングの知識がゼロから身につく最高の指南書](https://gihyo.jp/book/2022/978-4-297-12685-8)
[IT用語辞典 e-Words](https://e-words.jp/w/%E3%82%B7%E3%83%B3%E3%82%BF%E3%83%83%E3%82%AF%E3%82%B9%E3%82%B7%E3%83%A5%E3%82%AC%E3%83%BC.html)
DNSクエリのもう一つの役割

>DNSの主なメカニズムは、人間が読み取れる名前をIPアドレスにマッピングすることであるが、長年にわたって、他のさまざまな目的で使用されていきた。

### DNSBLに載っていないかを調べる
>DNSクエリのもう一つの一般的な使用方法は、DNSBL(DNS-based blacklist:DNSベースのブラックリスト)でドメインを探索することである。DNSBLは、スパマー（スパム・メールの発信者)やマルウェアに関連づけられたIPアドレスを追跡するために、共通に維持されているリストである。DNSBLでドメイン名を探索するために、クライアントはDNS Aレコード・クエリを特殊なDNSサーバーに送る。例えば、メール・サーバーへのコネクションを想定していないIPアドレスのリストを保持ているpbl.spamhaus.org(ポリシー・ブラック・リストの一つ）などである。特定のIPアドレスを探索するには、IPアドレスのオクテットを逆にして、pbl.spamhaus.orgの前に追加するだけで良い。

>例えば、127.0.0.2を探索するには、クライアントは2.0.0.127.pbl.spamhaus.orgのクエリが発行する。対応するIPアドレスがリストに含まれている場合、DNSクエリは、通常は、リスト内のそのエントリの出所などいくつかの追加情報とともにIPアドレスを返す。IPアドレスがリストに含まれていない場合には、DNSサーバーは、「そのようなドメインはない」を意味するNXDOMAINレスポンスを返す

https://bookplus.nikkei.com/atcl/catalog/23/03/16/00728/
【シリーズすごいぞiQ-F】その場しのぎのST言語プログラミング_その2

:::note warn
本記事はラダー言語を主に使用する電気技術者を対象として記述しています。
:::

## はじめに
その場しのぎのST言語プログラミング　その2として下記について記事にします。

+ シーケンス命令でのパルスキャッチの記述方法
+ シーケンス命令でのタイマー記述方法

## 1．シーケンス命令でのパルスキャッチの記述方法
シーケンス命令でパルスの立上りを検出するにはLDP(EN,s)命令を使用します。
ディスティネーションを持たないので戻り値を使用する格好になります。
ENの実行条件には"TRUE"を記述してください。
sで指定したビットの変化を捉えます。

**例**
 
    ラダープログラム       
         │  X0                               Y0    │
         ├┤ ↑ ├───────────────────────────────○────┤
         │                                         │
        
    //ST代入文
        Y0 := LDP(TRUE,X0);
    

    
## 2．シーケンス命令でのタイマー記述方法
あれこれ説明するより、回路例を示します。
1）～3）のプログラムはt_1の接点出力をランプの点滅に使用するような交番タイマープログラムです。


**1)ラダープログラムの例**
 
     ラベル名　データ型　クラス
    	t_1   タイマ    VAR
        t_2   タイマ    VAR
     ラダープログラム     
        │  t_2                                                    │
     (0)├┤ ／ ├──┬────────────────────────────────[OUT  t_1  K50 ]┤
        │        │                                                │
        │        │  t_1                                           │
        │        └┤    ├──────────────────────────[OUT  t_2  K50 ]┤
        │                                                         │
	
**2)IF文で記述したST言語プログラムの例（非推奨）**

     ラベル名　データ型　クラス
    	t_1   タイマ    VAR
        t_2   タイマ    VAR
        
    STプログラム
    
    IF NOT t_2.S THEN
    	OUT_T(TRUE,t_1.C,50);
    	IF t_1.S THEN 
    		OUT_T(TRUE,t_2.C,50);
    	END_IF;
    ELSE;
    	OUT_T(FALSE,t_1.c,0);
    	OUT_T(FALSE,t_2.c,0);
    END_IF;

ラダーとの相違点

+ タイマーラベルを記述する際は接点なのかコイルなのか等、メンバにて明示するのが無難
+ タイマーをリセットさせる文を記述する必要がある

ただし、同じタイマーラベルを指定した命令をプログラムの複数箇所に記述するような書き方は推奨されません。
IF文内ではタイマーの実行条件を制御し、END_IF;の後にタイマー実行文を記述するのが良いでしょう。
ちなみにマニュアルによると、実行条件TRUEで同じタイマーラベルを指定した命令をプログラムの複数箇所に記述すると記述した個数倍の速さでタイマーがカウントされるそうです。

**3)シーケンス命令の実行条件で制御したST言語プログラムの例**

     ラベル名　データ型　クラス
    	t_1   タイマ    VAR
        t_2   タイマ    VAR
        
    STプログラム    
        
    OUT_T(NOT t_2.s,t_1.c,50);
    OUT_T(t_1.s,t_2.c,50);

ラダーとの相違点は2）と同じく

+ タイマーラベルを記述する際は接点なのかコイルなのか等、メンバにて明示するのが無難
+ タイマーをリセットさせる文を記述する必要がある

タイマー命令の実行条件にタイマー接点を直接記述するとこのような書き方になります。
タイマー命令は常に駆動状態にあり、実行条件が変化することにより動作が変化します。
ラダープログラムの場合は回路ブロックとしてまとめる為に2行目もt_2接点にぶら下げる格好で記述しましたが、ST言語の場合は回路ブロックを意識する必要は無いので、2行目に関して

     OUT_T(NOT t_2.s AND t_1.s,t_2.c,50);

では無く

     OUT_T(t_1.s,t_2.c,50);

と記述しました。

## おわりに
ラダープログラムの感覚の延長で記述すると思い通りに動かないタイマーやパルスについて記事にしました。

+ 命令が戻り値を使用するのかディスティネーションに結果を返すのかよく確認する
+ ディスティネーションをOFFするときに命令が駆動状態にないといけない

この部分が理解できれば他の命令にも応用が利くと考えています。

いまのところ、私の場合、メインの機械制御ファンクションブロックはラダーで組んで、その呼び出しはST言語で組むと云うスタイルになっています。

今後、機械制御ファンクションブロックの部分もST言語で組むことを検討していますが、その際はその場しのぎというわけでは無く、CASE文を活用した状態遷移の管理が必要と考えています。



## 過去記事一覧
+ [過去記事一覧](https://qiita.com/fujiteruo/items/af2459d320e8109963db)
環境変数がundefinedになる

環境変数の読み込みにキャッシュが残って
なかなか解決しなかった話

## APIキーのエラー
supabaseでリクエストのテストを行ったところ、下記のエラーが発生
```
message: "TypeError: Failed to execute 'set' on 'Headers': String contains non ISO-8859-1 code point.
```
このエラーは `SUPABASE_URL` や `SUPABASE_ANON_KEY` に日本語や改行などが含まれている場合に発生するようです
私の場合はスペースでした

しかし削除後もエラーが解決せず。

* `SUPABASE_URL` や `SUPABASE_ANON_KEY` は `.env` ファイルから参照
* 変数を直接代入するとエラーが出ない
* `.env`ファイルからの参照に原因があるっぽい

##  変数の値が `undefined` になる
変数をコンソールに出力すると下記の出力に
* `SUPABASE_URL` は `undefined`
* `SUPABASE_ANON_KEY` は `supabaseのAPI KEY`

`.env` の内容が正しく読み込まれていないようなので
設定周りを色々見直すことに

## 解決：開発サーバーの再起動
読み込みがうまくいかない原因はいくつかありますが
いろいろ確認して問題なければ
サーバーを再起動してみるのが良さそうです
“任せる勇気”が育む後輩の自走力──チーム運営を託して得た学び

# はじめに
こんにちは。GxPのすずき（@ksuzuki-gxp）です。
この記事は、[グロースエクスパートナーズ Advent Calendar 2024](https://qiita.com/advent-calendar/2024/gxp) 22日目の記事です。

この記事では、私がチームの後輩メンバーにチーム運営をやってもらった経験についてお話します。
後輩に今までやってもらっていなかったことをお願いする必要があり、主体的に動いてもらうための方法がわからず困っている人の参考となれば幸いです。
正直、私自身も手探りでしたが、学びの多い体験でした。

# 役割転換のタイミング
ここ1年、そろそろ後輩メンバーにも主体的にチームを担ってもらいたいという思いと、
チームメンバーが半分以下に減少したことも相まって、私含め少数メンバーで日々の業務を回す必要性が出てきました。
特に後輩メンバーには、今まであまりお願いしていなかった「お客様との調整」「チームに方向性を示して主体的に動く」という役割を担ってもらわなければならない場面が増えていました。
それには自分で考えて動くことをやってもらう必要があるのですが、今まで新人さん等にやっていた「仕事のやり方を教える」では考え方はあまり浸透せず、どうやったらその思考回路を持ってもらえるのか、とても苦戦していました。

# 気づきのきっかけは「1時間の寝坊」
苦戦中の日々の中、あるリリース対応が深夜まで伸びてしまい、一旦仮眠を取って朝6時に再開しなければならない状況になりました。
結局、私は1時間寝坊して7時に慌てて戻ったのですが、焦った私をよそに、伝えた確認方法を活用して後輩が1人で作業を進めてくれていました。
これを見た時、「そうか、自分が心配しすぎていただけで、任せてみたらできるのかも」と気づくことができました。

その後、ある小さなプロジェクトの管理・進行・調整・リリースを、思い切ってその後輩にお願いしてみました。もちろん問題もいくつか発生しましたが、最終的には無事成功。
その過程で、「お客様との調整」「チームに方向性を示して主体的に動く」というスキルを身につけてくれました。


# 挑戦してもらうことの重要性
この経験から学んだことは、**実際に失敗や大変なこと含めて経験してもらうことが何より重要だ**ということです。
私が「まだできない」「心配だ」と思い、任せることを躊躇していたのが問題そのものだったと反省しました。
後日談として、何があって変わったのか後輩に聞いたところ、やはり小さなプロジェクトを一通り自分で回した経験が大きかったと言っていました。

現在は、できる/できないに関わらず、他の後輩メンバーにもプロジェクト管理や運営・お客様調整をお願いしています。その結果、少しずつ自主性が高まったり、管理の視点を持ってくれるようになり、チームにも非常に貢献してくれています。


# 実践してみてのポイント
現在は意図的に後輩メンバーにお願いすることが多くなりましたが、毎度難しいなと思うことが介入度合いのバランスです。入りすぎると学べるポイントを減らしてしまうし、逆に入らなさすぎると何かあったときにフォローできなくなってしまいます。
「何かあったときにフォローできる体制があること」が挑戦しやすさに繋がるとも思っているので、お願いしたあとのフォローが上手くできるためのポイントを見つけることと、
気になって口を出してしまいそうになるのを意識的にぐっと堪えることの2つが重要だと思っています。
今もなお上手く実践するために、日々練習中です。


# おわりに
去年のアドベントカレンダーでは[自分が主体的に動けるようになった話](https://qiita.com/ksuzuki-gxp/items/82bf7d17f1aac965f608)を書きましたが、今年は真逆で、人にやってみてもらう話を書きました。
人にお願いすることが多かったにも関わらず、去年よりも苦戦するような学びが多く、人として未熟さを感じることが多い1年でした。
しかし、そんな未熟な私を見限ることなく、一緒にチームを回してくれている後輩メンバーや上司（GM・M）には感謝してもしきれないです。
まだまだ試行錯誤の日々だとは思いますが、引き続き実践して一緒に頑張っていけたらと思っています。
また、同様に後輩育成に苦戦している人へ、何かしらのきっかけとなれば幸いです。
最後まで読んでいただきありがとうございました。
原始根を求めるCプログラム

2024年の10月から秋葉原ロボット部の「ガロア理論の頂を踏む」読書会に参加していますが、1章9節に原始根という言葉が出てきました。

定義は、既約剰余類群(Z/pZ)*[^1]の元であってそのべき乗を計算すると全ての(Z/pZ)*の元を表せるもの[^2]、です。

また1章10節によるとpが素数ならば原始根は必ず存在します。原始根を探すアルゴリズムも載っているのですが少々複雑なので、単純に定義に基づいてpに対する原始根を全て求めるプログラムをC言語で作ってみました。

```C
#include <stdio.h>

// nがpの原始根であるか判定
int isPrimitiveRoot(int p, int n)
{
	int count = 0;
	long long m = 1; // intだと溢れた
	char already[110000] = {0}; // 10000個目の素数は104729

	while (1) {
		m *= n; // mにnのべき乗が入る
		m %= p; // 溢れないよう即mod p
		count++;

		//if (m != 1) // pが素数なら原始根でなくても必ず1に到達する前提のコード←NG
		if (already[m] == 0) { // pが素数でなくても無限ループにならないようにするため
			already[m] = 1;
			continue;
		}

		if (m != n) // pが素数なら起きないみたいだが、素数でないと起きる場合があった
			printf("%d %d\n", m, n);
		//if (count == p - 1) // pが素数なら原始根でなくても必ず1に到達する前提のコード←NG
		if (count == p)
			return 1;
		else
			return 0;
	}
}

int main(void)
{
	int p;

	printf("prime number: ");
	scanf("%d", &p);

	int count = 0;
	for (int i = 2; i < p; i++)
		if (isPrimitiveRoot(p, i)) {
			printf("%d ", i);
			count++;
			count %= 10;
			if (count == 0)
				printf("\n");
		}
	printf("\n");

	return 0;
}
```

本に載っていた41の原始根を求めてみた例です。
```
prime number: 41
6 7 11 12 13 15 17 19 22 24
26 28 29 30 34 35
```
グロタンディーク素数には原始根はありませんでした。:-)
```
prime number: 57

```

このプログラムは、入力されたpに対し2からp-1の数が原始根であるかをisPrimitiveRoot関数で判定し、原始根であれば表示しています。

pが素数でない場合にも原始根がありうるのか(いくつか調べた感じではなさそうですが)、あったとして数学的に使い道があるのかは分かりませんが、一応素数でないpを入力されても無限ループに陥らないためにnのべき乗を計算していて既に出現した値が再び出現したかをチェックするようにしました。

ネットで原始根をある程度まで求めた情報が載っていましたが、それとは一致していました。またネットで素数表を探したところ10000個目の素数は104729ですが無限ループに陥ることなく終了できました。

抽象的な議論だけだとどこかもやもやするので具体的に原始根の値を計算してみたお話でした。

[^1]:整数をpで割った余りは0、1、、p-1のp通りなので、整数を余りによってp個に分類でき($0$、$1$、$2$、、$p-1$と表し数のように扱う)、これらの集合をZ/pZと表します。Z/pZは足し算に関して群を成します。
Z/pZの元からpと互いに素であるものだけを選ぶと掛け算に関して群を成し既約剰余類群と呼び(Z/pZ)*と表します。

[^2]:具体例として(Z/5Z)*の元は$1$、$2$、$3$、$4$の4個ですがどれが原始根か定義に従って確認してみます。各元をべき乗して5で割った余りを求めると、
$1$は何乗しても$1$以外の元が出てこないので$1$は原始根ではありません。
$2^1=2$、$2^2=4$、$2^3=8=3$、$2^4=16=1$ と全ての元が出てきたので$2$は原始根です。
$3^1=3$、$3^2=9=4$、$3^3=27=2$、$3^4=81=1$ と全ての元が出てきたので$3$は原始根です。
$4^1=4$、$4^2=16=1$、$4^3=64=4$、$4^4=256=1$ となり$4$と$1$しか出てこないので$4$は原始根ではありません。
「愚直にやる」ということ

:::note info
この記事は、[LITALICO Engineers Advent Calendar 2024](https://qiita.com/advent-calendar/2024/litalico)シリーズ３の２０日目の記事です！
:::

# はじめに
皆様こんにちは！
今年の4月に入社したエンジニアの@ryunosuke_sakoです！
突然ですが、お恥ずかしながら私は「報告・連絡・相談（**ホウレンソウ**）」を適切に行うことが苦手です。
原因としては、以下のようなものがありました。

- 忙しい中で、自分が分からないことについて声をかけるのを躊躇ってしまう
- 自分なりに考えることが必要だと思ってしまい、指示に対して愚直に遂行できない
- 「詰まっている・進捗が出ない」状態についても伝える、という考えを持てていない

今回は、特に入社してからの７ヶ月でこの**ホウレンソウ**ができないという弱点について、どのように育成していただき、自身にどのような変化があったかをまとめようと思います。

# ４月〜６月

### 状況
インターンから正式に入社し、継続して同じチームに配属された。
業務としては、学習やキャッチアップをメインにしていたインターン時代に比べて、開発や調査のタスクを担当することが多くなった。
徐々にタスクを進めるにあたっての**ホウレンソウ**が必要になっていったが、その量や質が指示していただいたものとズレてしまうことが多発していた。

### 毎日30分の1on1
育成を担当していただいていた先輩との1on1で、前日の進捗確認や当日の予定について打ち合わせを行いました。
各タスクに予実と難易度、達成状況を設定したシートを見て自分の状況を振り返るとともに、日々の進捗について報告するタイミングが生まれます。
しかし、進捗が芳しくないときや逆に手が空いたときにすぐ伝えることはできず、一日一回のこのタイミングでの報告になっていました。
![スクリーンショット 2024-12-19 17.50.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3641629/01ec5cdb-a66d-597f-c6c7-5e7e527f7b7a.png)

# ７月〜８月

### 状況
**ホウレンソウ**が不足していることで、他のメンバーの方に進捗の確認をしていただく、手戻りが発生する、など余分な業務を増やしてしまった。
「上手く報告ができない→チームに迷惑をかける→焦って視野が狭まる→上手く報告ができない→…」という悪いサイクルに陥っていた。

### 1on1の廃止
次のステップとして、定期的な1on1を廃止して自発的な報告を始めることになります。
しかし、量と質の両面で不足している状態から抜け出すことができませんでした。
量：ある程度の目処が立ってから報告するべきではないか、という考えから、報告を増やすようにご指摘をいただいても増やすことができませんでした。
質：効率の良い報告にしたい、自分なりに取り組んだことを伝えたい、という考えから、報告するべき内容をまとめることができず、確認していただく手間を生んでしまいました。

# ９月〜１０月

### 状況
育成を担当していただいていた先輩から「まずは愚直にやりなさい」というアドバイスをいただき、いただいている指示について充分に理解できていない状態で、自分の考えを取り入れようとしていたことに気がついた。
「上手く報告ができる→報告の勘所がわかる→改善について相談できる→上手く報告ができる→…」という良いサイクルが回り始めた。
日々の業務に余裕が生まれ、コミュニケーションも以前より円滑に取れるようになった。

### 分報
まず、**ホウレンソウ**の量を改善するトレーニングとして分報を始めました。
読んで字の如く1分間に1回状況を報告する取り組みで、殆どは「◯◯中」という内容になり、業務時間中ずっと時間と時計に追われます。
ですがこの取り組みを行うことで、「報告する内容が積まれていく感覚」「1分1分を消費する感覚」を実感することができました。
また、これらが骨身に染みてから、徐々に「◯◯中」などの無駄になっているものを落としていくことで、相対的に質も高めていきました。
![スクリーンショット 2024-12-19 18.22.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3641629/82021be2-768e-1494-d8a6-bcae3d7782df.png)

# 「愚直にやる」ということ
私の行動で特に問題だったのは、「一度も愚直にやらず自分なりに進めた」ことでした。
なぜその指示を受けたのかということを考えることがなく、言われたままに進めるのは良くないという考えのみで間違った方向に進んでしまったのです。
**守破離**という言葉があるように、何事もまずは先輩や先駆者の教えを守り、それを踏まえて自分なりのやり方を身につけていくものなのだと、今では考えています。

# おわりに
まだまだ未熟な私ですが、ここまで自分の苦手について向き合うことができたのは、辛抱強く育成をしていただいた先輩と、何度も協力をしていただいたチームの皆様のお陰です。
この場を借りて、感謝申し上げます！

ここまで読んで下さった皆様、アドカレへの参加にご協力頂いた皆様、本当に有難うございます！
明日のアドベントカレンダー２１日目は、
- @ti_aiuto  さん

です！引き続き、お楽しみください！
ElixirDesktop: WebViewからAndroidとiOSの機能を呼び出し

# リポジトリ

以下のリポジトリで、記事中に含まれるコードを確認できる。

https://github.com/BlackTanuTanuNinjas/tutorial_desktop

# 記事を読むことできるようになること

* ElixirDesktopでAndroid/iOSの機能を呼び出せる

# 省略する内容

* ElixirDesktopの初期化手順
* evaluateJavaScriptについて

# 本題

WebViewにはAndroidやiOSの機能を呼び出す機能がある。
具体的には、KotlinやSwiftのコードをWebView上から次の仕組みを用いて呼び出すことができる。

* Android: `Javacscriptinterface`
* iOS: `WKWebView`, `WKScriptMessageHandler`

## Android

Androidでは**JavascriptInterface**を使用する。

以下の手順で作業を行う

* JavascriptInterfaceを有効化
* 関数定義
* JavaScriptからの呼び出し

### JavascriptInterfaceを有効化

`Bridge`クラスの`init`に以下の記述を追加し、JavascriptInterfaceを有効にする。

```kotlin:Bridge.kt
init {
    // 略
    webview.addJavascriptInterface(this, "Android")
}
```
### 関数定義

`@JavascriptInterface`を付与して、JSから呼び出す関数を定義する

```kotlin:Bridge.kt
    @JavascriptInterface
    fun sample1(): String? {
        return Build.VERSION.RELEASE
    }
```

### JavaScriptからの呼び出し

以上の記述を追加することで、JSから以下の記述でAndroidの機能や関数を呼び出すことが可能である。

以下の記述により定義した`sample1`関数を呼び出せる

`webview.Android.sample1()`

## IOS

iOSでは、メッセージハンドラを使用してJavascriptから関数を呼び出す。
値を返却する場合は`evaluteJavascript`を用いる必要がある。

以下の手順で作業を行う

1. `override init()`内にメッセージハンドラを登録する
2. `userContentController`に、メッセージに対応する処理を記述する
3. 必要に応じて`evaluteJavaScript`で値を返却する

### メッセージハンドラの登録

WebView.swift内の`override init()`でメッセージハンドラを登録する。

```swift:WebView.swift
override init() {
    // 略
    configuration.userContentController.add(self, name: "sample1")
}
```

### メッセージに対応する処理

メッセージハンドラに対応する処理を`userContentController{関数内に記述する


```swift:WebView
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
    switch message.name {
        case "sample1":
            let osVersion = UIDevice.current.systemVersion
            self.evalJavaScript(message: osVersion)
        // 略
    }
}
```

### 値の返却

値を返却する場合は、evaluateJavaScript関数を使用してJavaScriptの関数を呼び出す。

```swift
    func evalJavaScript(message: String) {
        let executeScript: String = "window.callFromNative(\"\(message)\");"

        webview.evaluateJavaScript(executeScript, completionHandler: {(object, error) -> Void in
            if let object {
                print(object)
            }
            if let error = error {
                print(error)
            }
        })
    }
```

### 呼び出し

JavaScriptからは以下のように呼び出すことが可能である。

```javascript
window.webkit.messageHandlers.sample1.postMessage("sample1");

const sample1 = (message) => {
    document.getElementById("ios-ver").textContent = message;
}

window.callFromNative = sample1;
```

ちなみに`postMessage`に渡している引数は、特に使用しなければなんでもよい。

## まとめ

Androidの手順

1. `init {}`に`webview.addJavascriptInterface(this, "Android")`を追記する
2. `@JavascriptInterface`を付与した関数を定義する
3. JavaScriptから`window.Android.関数()`で呼び出す

iOSの手順

1. `override init()`に`configuration.userContentController.add(self, name: メッセージ名)`を追記する
2. `userContentController`関数に、メッセージに対応する処理を記述する
3. JavaScriptから`window.webkit.messageHandlers.メッセージ.postMessage(引数);`で呼び出す
4. 値を返却する場合、`webview.evaluateJavaScript`を使用する
5. JavaScriptで対応する関数を定義する 

特に(1)の記述漏れに注意すること
RSpec を書きたくて....

こちらの記事は「[CBcloud Advent Calendar 2024](https://qiita.com/advent-calendar/2024/cbcloud)」20日目の記事です。
他の方の記事もぜひ見てください :tada: 

# はじめに
最近（前職含め）気になっていたことは何かと考えた...
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3945304/22da9620-f5b8-99c0-f8bd-aa085fe9c259.png)

とりあえず、Rspec に関して書こうと決めた感じです（かなりここまでで行き当たりばったり....）

どうせ書くならば、ちょっとぐらい頑張りたいと思ったので、久しぶりにコードをしっかり触ってみることにしました。
（今までではリーダー業務＋納期に間に合わせるコーディング＋全員分のPRレビューをやってきたので、本気で調べられてなかったので（がっつり言い訳））

## 本記事のターゲット
初心者の方〜3年目ぐらいの人をターゲットにしてます。
（可能な限りわかりやすく書き砕いたつもり....）

## RSpec の書き方を調べつつ、書いてみる
RSpec を書く前に知っておきたいのは、Junichi Ito さんの記事が上がるはず！（ですよね...）

https://qiita.com/jnchito/items/42193d066bd61c740612

`describe` や `context` の使い方などそもそもの流儀を学習できるサイトで、自分も4~5 年前ぐらいに読んだ記憶があります。
ただ開発チームによって書き方が違うパターンもあり、RSpec でも色々流派やこだわりがあるので、開発チームの認識揃えるのに困るなぁと思った記憶があります。

https://zenn.dev/noraworld/articles/rspec-rules-for-team

ただ基本的には `describe` と `context` はこんな感じで使われる想定です。
```rb
  describe 'タイポチェック' do # ここでやりたいテストを明示する（テスト観点の明記）
    context 'タイポがある場合' do # テストのパターンを明記（ここで「ある」場合を見るならば「ない」場合もみる）
       it 'タイポが修正されること' do # テスト結果を明記
          ...
       end
    end

    context 'タイポがない場合' do # テストのパターンを明記（ここで「ない」場合を見るならば「ある」場合もみる）
       it '何も修正されないこと' do # テスト結果を明記
          ...
       end
    end
  end
```

`context` には `~~~の場合` と記載するようにすることで、テストケースの実施パターンを想像させるように意識付けてます。
（英語では `When ...` と記載される認識なので、あえてこうしてます）

## 高速化を目指してみる
高速化を本気で目指すと、色々工夫することができます！！！
```
1. データの生成まわり
    1-1. データを作成(create) せずに build で頑張る
    1-2. DB への初期化データをなるべく insert しない
2. 処理の工夫
    2-1. テストの実施を並列化する
    2-2. sleep の利用を減らす
    2-3. なるべくモックを使う（連携テストなど）
```

高速化周りは、個人的には [Kaigi on Rails 2021](https://kaigionrails.org/2021/) がかなり熱かったイメージ（もちろん毎年すごい発表がありますが...）

最近？？でも企業から発信している例も多くかなり熱が上がっている印象です

https://tech.findy.co.jp/entry/2024/04/08/101952

https://qiita.com/nakajima-yuusuke/items/68cdbc317bb770b139a8

https://speakerdeck.com/tomoasleep/2x-faster-github-actions-rspec-on-qiita

さぁ「高速化を目指してやっていくぞー！」という気概は高まった状態になりました
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3945304/b17e3600-3ad8-72f2-55c5-119828290b63.png)

## 高速化を目指したかった...
やり方を調べて、やろうと思った（ここで投稿日前日であることに気づく....）

気持ちは来年に持ち越す方針にするのが良さそうだと気づき、高速化は来年のどこかで投稿します :bow: :bow: 

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3945304/e6dfd9ad-f160-c061-ae37-2413c7c569e0.png)

（ちゃんとした結果を出したくて、中途半端は嫌すぎるので....ごめんなさい）

### 最後に
弊社のエンジニアもまだまだ募集しているので、ぜひカジュアル面談にも参加してみてください

https://recruit.cb-cloud.com/

エンジニアの記事もあるので、ぜひご覧ください

https://recruit.cb-cloud.com/member/engineer
StableDiffusionを使ってイラストを生成してみた

## はじめに
初めましての人もそうでない人もこんにちは！

最近ぼちぼち開発をしていて思うことがあります！
それは自分が絵を描けないということです！！

私の中学、高校時代の美術の成績は壊滅的でした。。
努力してこなかったツケがここにきて響くとは全く予想していなかった・・・

皆さんは多少絵が描ける様になったほうが個人開発の幅が多少広がると思います！

**注意**
今回作る生成AI絵ですがGoogleColaboratoryを使います！
しかしGPUの都合上無料枠だと相当厳しい(というか無理)だと思います。。。
無料枠だとRuntimeErrorがでます。
その場合は大変申し訳ありませんが上位プランを購入後試してみてください。

## 作成してみよう！
### Hugging Faceのトークンを取得
今回はhuggingfaceというサイトを利用して作成してます！
huggingfaceというのはAIの開発に役立つものを提供するプラットフォームです！

少し話題になっているMeta社の大規模言語モデルであるLlama3もここに提供されているので時間がるときでも覗いてみてはいかがでしょうか！

それでは、huggingfaceにアクセスしてアカウントを作成してください！

https://huggingface.co/

1.右上にある自身のアカウントのアイコンをクリック
2.settingsをクリック
3.左側にあるAccess Tokensをクリック
4.New Tokenを押してNameを決め、TypeはWriteを選択(Readはダメ！)
5.Generate a tokenで完成！

トークンは誰にも見せないで安全に管理してください！
トークンを取得したら"huggingfaceのアクセストークン"の部分に入れてください！

### コーディング

Googleアカウントを作成してColaboratoryにアクセスしてください！

アクセスしたら以下のコードをセルの中にコピペしてください！
```python
from huggingface_hub import login

#huggingfaceのトークンを設定
HF_TOKEN = "huggingfaceのアクセストークン"
login(token=HF_TOKEN)
```

出力したら最後に「Login successful」が表示されたら成功です！
このコードはhuggingfaceを使うためのコードだと思ってください！
それでは次にいきましょう！

新しくセルを作ってコードをコピペです！
```
!pip install --upgrade diffusers accelerate
```

このコードでは"diffusers"と"accelerate"というパッケージを最新版にアップグレードするコードです！

新しくセルを作ってこのコードをコピペです！
```python
# 必要なモジュールをインポート
import torch
from diffusers import StableDiffusion3Pipeline

# Stable Diffusion 3のパイプラインを読み込み
pipe = StableDiffusion3Pipeline.from_pretrained("stabilityai/stable-diffusion-3-medium-diffusers", torch_dtype=torch.float16)

# パイプラインをGPUに移動
pipe = pipe.to("cuda")

def generate_image(prompt, negative_prompt="", num_inference_steps=28, guidance_scale=7.0):
    # 画像を生成
    image = pipe(
        prompt, # プロンプト
        negative_prompt=negative_prompt, # ネガティブプロンプト
        num_inference_steps=num_inference_steps, # ステップ数
        guidance_scale=guidance_scale,
    ).images[0]

    return image
```
このコードでは必要なモジュールをインポートします！
その次に今回絵を生成するのに必要なstable-diffusion-3というモデルを読み込みます！
そして処理を高速化させるためにGPUを使える様にします！
最後に画像生成の定義を行って画像を出力させています！

そして上の方でも話しましたが無料枠だとここでRuntimeErorrが表示されてしまいます！

## 画像を生成してみよう！

はてさてようやく完成したので絵を生成してみましょう！
この記事を書く前に見た鬼滅の刃がとても印象深かったのでそれを意識してプロンプトを書いてみましょう！

```python
prompt = "月夜に鬼を倒す鬼殺隊の画像、アニメ調"
negative_prompt = ""

image = generate_image(prompt, negative_prompt)

image
```
生成された画像がこちら！！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3631203/c67fd9ee-cd7d-df60-931c-4465a996bb7e.png)

・・・うーん、よくみると顔の部分や指先など不自然に見えるところなどちらほらありますねー

日本語ではなく英語で次はやってみます！

```python
prompt = "Image of the Demon Slayer Corps slaying demons on a moonlit night, anime style"
negative_prompt = ""

image = generate_image(prompt, negative_prompt)

image
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3631203/96535d46-300e-a994-caed-34abb7ba3493.png)

・・・みんな似たような見た目だし左上に限っては面白いことになってますねw

## おわりに
今回の記事はいかがだったでしょうか？

皆さんもぜひ使ってみてください！(お金はかかりますが)
それではまた別の記事でお会いしましょう！
REST APIのテスト自動化：最初の一歩

## 1. はじめに

REST APIのテスト自動化には以下の利点がありと考えています！

- 効率的な実行: 手動でテストケースを実行する時間と労力を節約できる

- 一貫性の確保: 常に同じ手順とアサーションを実行するため、テスト結果の一貫性が確保される

- 早期のバグ検出: 短時間で大量のテストケースを実行できるため、バグや問題を早期に検出し、修正することができる

これらの利点により、REST APIのテスト自動化は効率的で信頼性の高いテストプロセスを実現し、開発チームの生産性と品質を向上させることができます。

## 2. 概要と目的

REST APIの自動テストに挑戦したいと思った時に、最もシンプルな自動テストの基盤となる物を作っていきたいと思います。

まずは下記テスト内容を作っていきます。
 - リクエストの正常な応答
 - レスポンス速度が大きく遅延していない

## 3. 使用ツール
PostmanとNewmanを組み合わせることで、APIのテストと自動化を効果的に行うことができます。
- Postman
APIの開発、テスト、ドキュメント作成等を行えるツール
- Newman
Postmanコレクションをコマンドラインから実行するためのツール

## 4. Postmanでテストケースを作成

### 4-1. Postmanをインストール
- Postmanの<a href="https://www.postman.com/">公式ウェブサイト</a>にアクセス
- ダウンロードページから、対応するオペレーティングシステム用のPostmanをダウンロード
- ダウンロードが完了したら、インストーラを実行し、指示に従ってPostmanをインストール

### 4-2. リクエストの作成と送信
Postmanを起動し、以下の手順でリクエストを作成して送信できます。
1. Postmanを開き、新しいリクエストを作成
2. リクエストのメソッド（GET、POSTなど）とエンドポイント（APIのURL）を指定
3. 必要に応じて、ヘッダーやパラメーターを追加
4. 必要に応じて、リクエストボディに必要なデータを入力
5. 作成したリクエストを送信し、レスポンスを確認

### 4-3. テストスクリプトの作成
レスポンスを確認できたら、Scripts画面にテストスクリプトを書いていきます。

```Javascript
// Test Case 1: 疎通確認
pm.test("APIが正常に応答すること", function () {
    pm.response.to.be.ok;
    pm.response.to.have.status(200);
});

// Test Case 2: パフォーマンス確認
pm.test("レスポンス時間が一定範囲内であること", function () {
    pm.expect(pm.response.responseTime).to.be.below(3000);
});
```

### 4-3. テストスクリプトの実行と結果の確認
テストスクリプトは、Postmanのテストランナーを使用して実行できます。以下の手順でテストスクリプトを実行し、結果を確認できます。

1. Postman右上の「Send」ボタンをクリック
2. テストが実行され、結果が表示
3. テストが成功した場合は緑色のチェックマークが表示され、Test Results画面に実施したテストケースの結果が表示される
3. 
```Javascript
PASS APIが正常に応答すること
PASS レスポンス時間が一定範囲内であること
```

## 5. テストの自動化とエクスポート
Postmanで作成したテストケースをNewmanを使用して実行できるようにします。

### 5-1. Newmanをインストール
1. NewmanはNode.jsで動作するため、まずNode.jsをインストール
2. ターミナルまたはコマンドプロンプトを開き、以下のコマンドを実行してNewmanをインストール
```Javascript
 npm install -g newman
```

### 5-2. テストケースのエクスポートとコレクションの作成
1. Postmanを開き、テストケースを含むコレクションを選択
2. コレクションの右上にある「...」アイコンをクリックし、「エクスポート」を選択
3. エクスポートのオプションを選択し、コレクションをエクスポート

### 5-3. Newmanを使用したテストの自動化と実行
1. ターミナルまたはコマンドプロンプトを開く
2. 
```Javascript
newman run コレクションファイル名.json
```

3.  コレクション内のすべてのリクエストが実行される


## 6. まとめ
今回作ってみた自動テストは、REST APIの自動化を行っていくための最初の一歩です！
この基本を覚えた上で、テストスクリプトにテストケースを増やして網羅率あげていったり、newmanの実行をCIツールを利用して定期実行をかけて安定稼働、監視を行ったりと、テストを充実させていくきっかけにしていきます。
[Rails] 容量を圧迫しているtmpとlogファイルを削除する

# 概要
開発マシンが容量不足...
容量を圧迫しているファイルを特定すると、Railsの`tmp`と`log`ディレクトリが容量を食い潰していました。

```bash
$ sudo du -h --max-depth=1 . | sort -hr
43G     .
26G     ./tmp
17G     ./log
```

# 削除

VSCode上から削除しても良かったのですが、
調べてみると、`Rails` で `log`と `tmp`を削除するコマンドが用意されていました。

## tmp の削除

```ruby
rails tmp:clear
```

> tmpディレクトリからキャッシュ、ソケット、スクリーンショットファイルをクリア

https://railsdoc.com/page/rails_tmp_clear

## log の削除

```ruby
rails log:clear
```

> logディレクトリ以下にあるすべての*.logファイルを0バイトに切り詰める

https://railsdoc.com/page/rails_log_clear