OmniAICreator/Qiita-1.07M huggingface dataset:
話題のブラウザ「Arc」を使いはじめました

## はじめに
知人から勧められたことをきっかけに、話題のブラウザである[Arc](https://arc.net/)を使いはじめました。最初は戸惑う場面もありましたが、使い続けてみると「いいな〜」と思う場面が増えてきたので、記事で紹介したいと思います。

## Arcとは？
Arcとは、The Browser Companyという企業が開発しているブラウザで、2023年7月にリリースされました。

https://arc.net/

また、ArcはChromiumをベースに開発されたブラウザなので、Chromeで利用していたブックマークや拡張機能がそのままArcでも利用できます。自分は、Arcを利用するまでChromeを利用していたので、移行がスムーズでした。

## はじめ方
Arcは、公式サイトからダウンロードすることができます。

https://arc.net/

Homebrewを使ってインストールすることも可能です。

```zsh
brew install --cask arc
```

## 個人的に好きなところ
### ブックマークやタブの管理
Arcは、ブックマークやタブをサイドバーで管理するデザインになっています。サイドバーは、上か「Favorite（お気に入り）」、「Pinned（ブックマーク）」、「Today（タブ）」という、主に３つの要素で構成されています。

![スクリーンショット 2024-12-15 12.01.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/581736/1d081a6b-e9b1-ddc5-a3c9-4df05fb0bf91.png)

「Favorite（お気に入り）」は、「Pinned（ブックマーク）」と似ていますが、よりアクセスする内容を選択して簡単にアクセスできるようにしたものです。

Arcを使っていて良いなと思った点は、「Favorite（お気に入り）」や「Pinned（ブックマーク）」をクリックしても新たにタブが追加されないところです。Chromeを使っていた頃はどんどんタブが増えていってしまい、整理することが大変でした。Arcを使いはじめてからはそういったことが起きなくなったのでよかったです。


### 複数ウィンドウでタブの内容が共有される
自分はブラウザを複数ウィンドウ開いて利用することが多いのですが、そのような時に「タブの内容が共有されたら便利なのになあ...」と思う時が多々ありました。Arcの場合は、「Favorite（お気に入り）」、「Pinned（ブックマーク）」、「Today（タブ）」の全てが、ウィンドウに関係なく共有されるので便利です。


### 不要なタブを勝手に削除してくれる
Arcは開いているタブが一定期間経過するとアーカイブされるようになっています。自動でアーカイブされる期間はデフォルトでは12時間になっていて、24時間、1週間などに変更することが可能です。

「あのタブ、もう少し残していたかった...」という時でも安心で、アーカイブされたタブは「Archived Tabs」に表示されます。「Archived Tabs」はいわゆる履歴のようなもので、自動でアーカイブされたページだけではなく、タブで閲覧したページなどもここに表示されます。


### Split Viewが簡単にできる
Arcでは、複数ページを一画面で表示する「Split View」を簡単に行うことができます。サイドバーの内容をドラッグするだけで簡単に行うことができます。分割できる内容は、3ページ以上でも行うことができます。

![スクリーンショット 2024-12-15 11.57.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/581736/ef326dbf-4ddf-ec36-6957-7eb40c5eb22e.png)


そして、Arcではこの分割した内容を、「Pinned（ブックマーク）」に移動して保存しておくことが可能です。本当に柔軟で使いやすいですね。

![スクリーンショット 2024-12-15 12.00.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/581736/b44ed306-7a48-1ecf-7cc7-4ce720ac527b.png)



### 遷移先の内容をプレビューできる
表示されているリンクを`Shift+クリック`で、ページを開くわけではなく遷移先の内容をプレビューすることができます。「遷移先の内容を確認したいけど、わざわざ開くまでもない...」といった時に便利な機能です。

![スクリーンショット 2024-12-15 11.42.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/581736/df16987b-7a9b-4ac5-dce3-62bb1b0b4830.png)


### 動画をPiPで再生してくれる
Arcでは、YouTubeなどで動画を再生したまま違うタブに移動すると、再生している動画をPicture-in-Pictureで再生してくれます。

![スクリーンショット 2024-12-15 11.38.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/581736/e8381618-2b70-2ca5-6663-3a01e79db5db.png)

表示されている動画は以下のものです。

https://youtu.be/C25g53PC5QQ?si=Wyk1JTfswWSumF4k

### スクリーンショットが柔軟に行える
Arcでは`Command+Shift+2`でスクリーンショットをすることができます。ただ単に画面全体を撮るだけではなく、画面上の要素を選択してスクリーンショットを選択することが可能です。

![スクリーンショット 2024-12-15 12.16.42（2）.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/581736/d93dec49-fa4b-64c4-04d5-1be75e9ea31f.png)



## さいごに
いかがでしたでしょうか？Arcの機能を全て紹介できたわけではありませんが、「Arcっていいブラウザかも！」と思った方は是非使ってみてください！

...と言いたいところですが、使い始めるのは少し待ってみてもいいかもしれません。

その理由は、「Arc」を開発しているThe Browser Companyは「Dia」という新しいブラウザを開発しており、2025年の早い段階でリリース予定であるためです。

https://arc.net/l/quote/bhgakkkx

「Dia」がリリースされたタイミングで、そちらを使いはじめてもいいかもしれません。「まずはどんなものか試してみたい！」と思われ方は「Arc」を使ってみてはいかがでしょうか。
MuJoCo入門 1 : MuJoCo MPCの起動

![SS 192.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565043/a41cd967-f549-8677-1efa-2e99bf69518d.png) MuJoCoがぜんぜんわからないわかりたい

## やること

物理エンジンのMuJoCoを試します。
自分のようにエンジニアリングの常識や前提がいろいろわかっていないけど、MuJoCoを試してみたいという人向けのまとめになります。

## 環境

- Mac M1

## MuJoCoとは何か

**MuJoCo**はMulti - Jo int dynamics with Co ntact の略だそうです。
ロボット工学やアニメーション、機械学習などのための汎用物理エンジンです。
Roboti LLC によって開発された後にGoogle DeepMindのものとなり、2022年5月にオープンソース化したそうです。

**MuJoCo MPC (MJPC)** は、Google DeepMind が開発した、 MuJoCoを使用したリアルタイム予測制御のためのインタラクティブなアプリケーションおよびソフトウェア フレームワークです。

**MJPC GUI** は、MuJoCoに含まれるsimulateビューアーを拡張機能したもの。ボタンや設定がいろいろ表示されているリッチな画面のMuJoCoはこちらです。

計算エンジンとして目には見えない部分がMuJoCo本体、グラフィカルな表示部分も含んだ環境がMuJoCo MPCやMJPC GUIと思えばよいのかもしれません（よくわからない）。

# なにも考えず立ち上げてみる

デスクトップアプリをDLできますが、だからといってそのままダブルクリックで開いてもデモやサンプルが動くわけでもなく、ただただ手詰まりになります。

![SS 2917.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565043/f082f50f-8a1f-fc08-664b-c53d8e2766da.png)

この画面で表示されちているのはたぶん「MuJoCo MJPC GUI」というものです。
MuJoCo のネイティブsimulateビューアーの拡張機能で、ショートカットなどもsimulateビューアーと共通のようです。
モデルを画面にドロップすることで動くようですが、モデルがないと何もできません


## まずは公式通りに mujoco_mpc

https://github.com/google-deepmind/mujoco_mpc?tab=readme-ov-file#macos

公式のmujoco_mpcの説明通りにインストールとビルドを行ってみます。

```
$ brew install ninja zlib (←以前入れたような気がするので今回はスキップ)
$ cd [任意のディレクトリパス]
$ git clone https://github.com/google-deepmind/mujoco_mpc
$ cd mujoco_mpc
$ mkdir build
$ cd build
$ cmake .. -DCMAKE_BUILD_TYPE:STRING=Release -G Ninja -DMJPC_BUILD_GRPC_SERVICE:BOOL=ON
$ cd bin
$ ./mjpc (←実行)
```

すると、以下のような画面になります。
左側のナビゲーションから「Plan」を押すことで、四脚ロボが立って動き始めます。

動いている最中に、「ctrl + 右クリック」でロボットの胴体を持ち上げて振り回したりすることもできます。

緑の丸を動かすと四脚ロボが追いかけるようですが、自分のトラックパッドの環境では緑丸の動かし方がわかりませんでした（謎）


![SS 2924.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565043/a301334d-5ba8-5bf1-6664-fce10fae9669.png)


# mujoco_mpcの使い方

初回起動以降は、

```
$ cd [mujoco_mpcのあるディレクトリ] (←移動)
$ ./mujoco_mpc/build/bin/mjpc (←実行)
```

などで起動できます。

mujoco_mpcと操作が同じである"MuJoCo simulate"のボタンや操作についての動画チュートリアルがあります。

https://www.youtube.com/watch?v=P83tKA1iz2Y

MuJoCo simulateはモデルを画面にドロップすることで実行が可能なようですが、mujoco_mpcでも同じ操作ができるかどうかはよくわかりませんでした（ドロップするファイルがどれかよくわからない）。

# 他のモデルを試す

画面左の「Task」メニューの「Model」を選択することで、他のサンプルを試すことができます。

ためしにTask→Model→Quadrotorを選んでAgent→Planを押すと、ドローンがループ潜りをはじめます。

![SS 2927.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565043/92bd67ef-74be-afaf-e8bd-639c430cf110.png)


## 次回
個人ロボット開発にこれをどう使えるのか、まだよくわかりません。
次はPython APIを試していこうと思います。


## 参考
https://qiita.com/sunrise_lover/items/58ea54a33ff5114cb8ef

サンプルモデルの見どころなど、とても参考になります。
ハンドロボットが握ったキューブの向きをお手本の向きに回転させるサンプルとか、すごいです。

## 次回記事
https://qiita.com/Ninagawa123/items/66ebaacc9b1081183160
虫眼鏡アイコンをクリックしても検索フォームが出てこない

**-Ruby on Railsのバージョン:7.2.1**
**-Rubyのバージョン:3.3.5**

Rails初学者です。
備忘録として記載します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3931580/0fd073f7-dae0-ad70-b712-4accfecc9fd2.png)

上記の虫眼鏡アイコンをクリックしたら、

![スクリーンショット 2024-12-15 11.28.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3931580/1323f424-abd6-d16a-0b9f-1f7118885a1f.png)

のように検索ボックスを表示するようにしたかったが、クリックしても表示されない事象が起きた
コードを下記に記載する


```erb
<div class="search_container">
  <div class="search_icon" onclick="toggleSearch()">
    <i class="fas fa-search"></i><!-- Font Awesomeの虫眼鏡アイコン -->
  </div>
  <div class="search-form hidden">
    <%= form_with url: search_path, class: "form-inline", data: { turbo: false } do |f| %>
      <%= f.text_field :word, placeholder: "検索", class: "search-input" %>
      <%= f.submit "検索", class: "btn-search" %>
    <% end %>
  </div>
</div>

<script>
  function toggleSearch() {
    const searchForm = document.querySelector('.search-form');
    if (searchForm) {
    searchForm.classList.toggle('hidden');
    }
  }
</script>
```

```css
.search-container {
  position: relative;
}

.search-icon {
  cursor: pointer;
  font-size: 20px;
  color: #333;
}

.search-icon:hover {
  color: #555;
}

/* 検索フォーム */
.search-form {
  position: absolute;
  top: 0;
  right: 100;
  display: flex;
  align-items: center;
  background-color: #fff;
  border: 1px solid #ccc;
  border-radius: 5px;
  padding: 5px 10px;
  box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
}

.hidden {
  display: none;
}

.search-input {
  border: none;
  outline: none;
  font-size: 16px;
  padding: 5px;
  margin-right: 10px;
}

.btn-search {
  background-color: #007bff;
  color: white;
  border: none;
  padding: 5px 10px;
  border-radius: 5px;
  cursor: pointer;
}

.btn-search:hover {
  background-color: #0056b3;
}
```

結論
```css
.search-form {
  position: absolute;
  top: 100%;　←こいつが変なことしてた、消したら動作してほしい挙動になった
  left: 0;
  display: flex;
  align-items: center;
  background-color: #fff;
  border: 1px solid #ccc;
  border-radius: 5px;
  padding: 5px 10px;
  box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
}
```

.search-formの中でposition: absolute;を使用しているので、基準となるのは親要素である.search-containerになる。
これに対して、フォームの位置をtopやrightで指定してるが親要素を基準にtop: 100%を指定したことによってフォームが変なところにいっちゃったみたい。
あと％で指定してたからってのもあるっぽい。

指摘等あればお願いします。
Playwrightのretry設定について

# retry設定とは

Playwrightではtestが失敗した際に再試行することができる。これがretryだ。

retryについてはいくつかの設定方法がある。

# playwright.config.ts

playwright.config.tsには以下のような記述がある。

```tsx
  /* Retry on CI only */
  retries: process.env.CI ? 2 : 0,
```

これは、CI環境ならば２回、違うならば０回 retryするということだ。

CI環境とは、githubActions等の環境のことだが、Playwrightはこれを感知することができるため、区別されている。

# test.describe.configre()

以下の様に、configure()を用いて playwright.config.tsの設定をオーバーライドすることもできる。

```tsx
test.describe('slider2', () => {
  test.describe.configure({ retries: 3 });  // このブロック内のすべてのテストに適用
  
  test('test case 1', async ({ page }) => {
    // テストコード
  });

  test('test case 2', async ({ page }) => {
    // テストコード
  });
});
```

# retry環境下でのみ実行する処理を記述する

以下のようにretry環境下でのみ実行する処理を記述することもできる。
```tsx
  test('slider2', async ({ page }, testInfo) => {
    if (testInfo.retry) {
      console.log('This test is being retried');
    }
```
Qiita CLI GitHub連携 投稿テスト

# きっかけ
アウトプットを習慣化したいのですが、中々できていません。
習慣化のためより楽にブログを投稿する方法を探していました。
そこでQiita CLIすると、使い慣れたエディタで記事を作成できることを知りました。
この記事はそのお試し投稿となります。

# プレビュー

`npx qiita preview`を実行すると、プレビュー画面が開かれます。
過去に投稿した他の記事をちょっとみたい時に見やすそうです。
画像をつけたい場合は、左上の`画像をアップロードする`をクリックします。
![スクリーンショット 2024-12-15 11.20.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3862159/cc24255b-334e-eb66-d364-dd389c3f0140.png)

## 画像のアップロード

![スクリーンショット 2024-12-15 11.21.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3862159/fe131e3a-2cb2-1022-d873-adc039969535.png)

画像アドレスをコピーし、エディタに貼ると画像をつけられます。
![スクリーンショット 2024-12-15 11.24.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3862159/29130d65-2e15-8646-d5d7-28b412c5e5ca.png)

記事の投稿は`npx qiita publish <ファイル名>`
GitHubと連携すると、リポジトリにpushすると投稿できる。

# 感想
* 初期設定は思っていたより簡単で始めやすかった
* 使い慣れたエディタが利用可能
* 他の記事を参照しやすいのが便利
* GitHubとも連携すると今後の記事の管理が楽になりそう

# 参考

https://qiita.com/Qiita/items/666e190490d0af90a92b

https://qiita.com/Qiita/items/32c79014509987541130
imagemagick 使用例

# 概要
画像処理コマンド
(自分が使うパターンだけ日記)

## 環境
- Ubuntu-22.04

## 導入
```
sudo apt install -y imagemagick-6.q16
```

## 画像フォーマット変換
```:拡張子で判別
convert in.jpg out.png 
```

## 拡大縮小
```:アスペクト比を維持する
convert in.png -resize 1180x1720 out.png # -resize Bi-Cubic補間
convert in.png -scale x1024 out.png      # -scale 縮小は画素平均、拡大はNearest Neighbor法
convert in.png -sample 200% out.png      # -sample Nearest Neighbor法(補完なし)
```

```:アスペクト比を維持しない
convert in.png -resize 1180x1720! out.png
```

## 切り出し
```:左半分(50%)
convert in.png -crop 50%x100%+0+0 out.png
```
```:余白削除 ※同色(10%ノイズ許容)画素からなる辺
convert in.png -fuzz 10% -trim out.png
```
```:例: in.pngの左約半分を切り出し、余白除去した、in.png.out.pngを生成
f="1.png"
convert "$f" -crop '47%x100%+0+0' -fuzz '10%' -trim "$f.out.png"
```

## 特定レイヤーだけ抽出
```:アルファチャネル抽出
convert in.png -alpha extract out.png
```
- -alpha : 透明度

## 生成/タイル

```:黒地の画像
convert -size 640x480 xc:"#000000" black.png
```
```:白線を引く
convert black.png -stroke "#ffffff" -draw 'line 0,0 639,0' whiteline.png
```
```:画像を繰り返す
convert -size 2x2 xc:"#000000" -fill white -draw "point 0,0" 22w.png
convert -size 1200x1200 tile:22w.png mesh.png
```
〜ControllerとModelが肥大化するの厳しいって〜Railsで複雑なロジックを整理するためのServiceオブジェクトパターンを実例付きで解説❗️

この記事は [ex-crowdworks Advent Calendar 2024](https://qiita.com/advent-calendar/2024/ex-cw)の16日目の記事です。

# はじめに
今年、株式会社クラウドワークスを退職した@nisyuuです。今年、乾燥機付き洗濯機を使い始めて人生変わりました。
エンジニアとしてクラウドワークステック（旧クラウドテック）というフリーランスと企業をマッチングするエージェントサービスを開発していました。

Webアプリケーションを開発する中でモデルやコントローラにロジックが集中しすぎて複雑化してしまうケースがよくあります。
このような問題を解決するために役立つのが「Serviceオブジェクトパターン」です。
本記事では初心者向けにServiceオブジェクトパターンの概要とRailsにおける実装方法を解説します。

# Serviceオブジェクトパターンとは？

Serviceオブジェクトパターンは特定のビジネスロジックやアプリケーション固有の操作を独立したクラスに切り出すデザインパターンの一つで、以下の特徴を持っています。

- **単一責任** 一つのクラスが一つの明確な目的を持つ
- **再利用可能** 共通のロジックをまとめて再利用性を高める
- **テストが容易** 独立したロジックをテストしやすくなる

たとえばユーザーの登録処理や外部APIとの通信、複雑なクエリの実行などが該当します。

# なぜServiceオブジェクトパターンを使うのか？

RailsのMVCアーキテクチャでは以下のような課題に直面することがあります：

- **コントローラの肥大化** 複雑なロジックがコントローラに集中してしまう
- **モデルの肥大化** モデルに大量のメソッドやコールバックが追加されることによる可読性低下
- **ロジックの分散** アプリケーションロジックの散らばりで保守性が悪化

Serviceオブジェクトパターンを導入することでこれらの問題を解決できます。

# Serviceオブジェクトパターンのメリットとデメリット

## メリット

1. **責務の明確化**
   - コントローラやモデルから複雑なロジックを分離できるためコードの可読性が向上します
2. **再利用性の向上**
   - 複数の箇所で使用されるロジックを一元管理できるため重複コードを削減できます
3. **テストが容易**
   - ロジックが独立したクラスにまとめられているため単体テストがしやすくなります
4. **保守性の向上**
   - コードの変更が局所化されるため、修正が容易になります

## デメリット

1. **過剰設計のリスク**
   - 小規模なアプリケーションでは必要以上に構造を複雑化する可能性があります
2. **学習コスト**
   - クラス設計や適切な責務分担の判断が難しい場合もあります
3. **ディレクトリ構成の複雑化**
   - Serviceオブジェクトパターンを増やしすぎるとファイルやクラスの管理が煩雑になることがあります

# RailsにおけるServiceオブジェクトパターンの実装例

ここではユーザー登録処理を例にServiceオブジェクトパターンを実装してみましょう。

## Step 1: ディレクトリ構成

通常`app/services`ディレクトリを作成してServiceオブジェクトパターンを格納します。

```
app/
  services/
    user_registration_service.rb
```

## Step 2: クラスの実装

以下はユーザー登録処理を行う`UserRegistrationService`の実装例です。

```ruby
# app/services/user_registration_service.rb
class UserRegistrationService
  def initialize(user_params)
    @user_params = user_params
  end

  def call
    user = User.new(@user_params)

    if user.save
      send_welcome_email(user)
      { success: true, user: user }
    else
      { success: false, errors: user.errors.full_messages }
    end
  end

  private

  def send_welcome_email(user)
    UserMailer.welcome_email(user).deliver_later
  end
end
```

## Step 3: コントローラでの使用例

コントローラではServiceオブジェクトパターンをシンプルに呼び出すだけです。

```ruby
class UsersController < ApplicationController
  def create
    service = UserRegistrationService.new(user_params)
    result = service.call

    if result[:success]
      redirect_to user_path(result[:user]), notice: 'ユーザー登録が完了しました！'
    else
      flash[:alert] = "登録に失敗しました: #{result[:errors].join(', ')}"
      render :new
    end
  end

  private

  def user_params
    params.require(:user).permit(:name, :email, :password, :password_confirmation)
  end
end
```

# Serviceオブジェクトパターンを活用する際のベストプラクティス

1. **単一責任を守る**
   - 一つのServiceオブジェクトパターンは一つの目的に集中する
2. **名前に明確さを持たせる**
   - クラス名に役割を明示する例`PaymentProcessingService`
3. **例外処理を組み込む**
   - 予期しないエラーに備えて適切な例外処理を実装する
4. **テストを重視する**
   - 独立したクラスであるためユニットテストを簡単に実装できる

# おわりに

ServiceオブジェクトパターンはRailsアプリケーションの複雑なロジックを整理しコードの可読性と保守性を向上させる強力なツールです。
特にコントローラやモデルが肥大化しやすいプロジェクトではその効果を実感できるでしょう。
Omnicampus

LLM(Large Language Model) Calendar 2024
https://qiita.com/advent-calendar/2024/llm
15日目の記事です。

OmniCampus
https://edu.omnicamp.us/

現在利用している機能は、
>コース
運営からのお知らせ
受講済み一覧

現在利用しているページからは、About、HELPがない。

youtubeで「Omnicamp.us」で検索しても
Webで「youtube　Omnicamp.us」で検索しても
めぼしいものが出てこない。

QAに投げた方がよいかもしれない。

宿題とアンケートをせっせと提出している。

現在検討しているのは、他のシステムとの連携方法。
APIがわかってもいいかもしれないし、
他のシステムからScriptで何なら受け付けそうか、
他のシステムからの連動は何を拒否しているのか。

あたりを調べ中。

わかっていなのには、
jupyternotebookが動くのが、Defactなのかどうか。
terminal のCommandで、何をやってもいいのか。
terminal の　Commandで、Dockerを入れた場合に、dockerで動作した内容を、遠隔からアクセスしているブラウザから見る設定方法があるかどうか。
[Flutter] freezedなクラスにgetterを定義する

# やりたいこと

以下のような freezed な User モデルがある

```dart
import 'package:freezed_annotation/freezed_annotation.dart';

part 'user.freezed.dart';
part 'user.g.dart';

@freezed
class UserModel with _$UserModel {
  factory UserModel({
    required String lastName,
    required String firstName,
  }) = _UserModel;

  factory UserModel.fromJson(Map<String, dynamic> json) =>
      _$UserModelFromJson(json);
}
```

このUserモデルに `fullName` という getter を定義したい

```dart
import 'package:freezed_annotation/freezed_annotation.dart';

part 'user.freezed.dart';
part 'user.g.dart';

@freezed
class UserModel with _$UserModel {
  factory UserModel({
    required String lastName,
    required String firstName,
  }) = _UserModel;

  factory UserModel.fromJson(Map<String, dynamic> json) =>
      _$UserModelFromJson(json);

  String get fullName => '$lastName $firstName'; /////////// これ ////////////
}
```

# エラー

freezedの反映をしようと試みるがエラーになる

```zsh
❯ flutter pub run build_runner build --delete-conflicting-outputs

Building package executable... 
Built build_runner:build_runner.
[INFO] Generating build script completed, took 191ms
[INFO] Reading cached asset graph completed, took 187ms
[INFO] Checking for updates since last build completed, took 848ms
[SEVERE] freezed on lib/models/user.dart:

Getters require a MyClass._() constructor
package:remoi/models/user.dart:30:14
   ╷
30 │   String get fullName => '$lastName $firstName';
   │              ^^^^^^^^
```

# 解決方法

[公式のリポジトリのREADME](https://github.com/rrousselGit/freezed?tab=readme-ov-file#adding-getters-and-methods-to-our-models) に解決方法が記載されている

以下の一行を追加する
```dart
import 'package:freezed_annotation/freezed_annotation.dart';

part 'user.freezed.dart';
part 'user.g.dart';

@freezed
class UserModel with _$UserModel {
  factory UserModel({
    required String lastName,
    required String firstName,
  }) = _UserModel;

  const UserModel._() ///////////// この一行 ////////////////

  factory UserModel.fromJson(Map<String, dynamic> json) =>
      _$UserModelFromJson(json);

  String get fullName => '$lastName $firstName';
```

追加後、反映に成功する
```zsh
❯ flutter pub run build_runner build --delete-conflicting-outputs
```

# 説明

> For that to work, we need to define a private empty constructor. That will enable the generated code to extend/subclass our class, instead of implementing it (which is the default, and only inherits type, and not properties or methods):

これを実現するには、プライベートな空のコンストラクタを定義する必要がある。
これにより、生成されたコードがクラスを実装する（デフォルト動作であり、型のみを継承し、プロパティやメソッドは継承しない）代わりに、クラスを拡張/サブクラス化できるようになる。
103枚⁈の壁を壊すゲーム作ってみた

# はじめに

103枚の壁を壊すゲーム作りました。

30秒間で終わるミニゲームです。

(しょうもないブラウザゲームです。)

# URL

https://shisojuice.github.io/kabe103game/

# 画像

![103枚⁈の壁を壊すゲーム作ってみた02.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3777149/18716b6e-07c9-2129-e1a2-f89c92e3eba3.jpeg)


# プロジェクトの作成

Phaser(Javascript)で実装しました。

https://phaser.io/

筆者がゲーム製作はじめてで、まったく知識がなかったので

PhaserでCLIのCreateで最初に生成されるテンプレートのCoinゲームをベースに作成しています🙇‍♂️

```bash

npm create @phaserjs/game@latest

```

![103枚⁈の壁を壊すゲーム作ってみた01.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3777149/b8b2751b-e4a8-ce8f-bd7f-7afa40e8fc84.jpeg)


メニューやゲーム中に表示される一部文字にはフリーフォントの

「キルゴU かなNB」を使用させていただきました。🙏

![103枚⁈の壁を壊すゲーム作ってみた03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3777149/1b602626-c3eb-dc26-c367-9955a55a6087.png)

https://sankoufont.com/japanese-font/killgou-kananb/


# ソース

https://github.com/shisojuice/kabe103game


# まとめ（感想）

ほぼPhaserのCoinゲームテンプレートをベースに作成したので

初学者の私でもコーディング自体は1時間で完成したが、

ゲーム製作で用いられる「Sprite」や「Tween」といった用語の意味を知らなかったりと

用語を調べるところからスタートしたり、SpriteのEditor操作を覚えたりと

全体的な時間だと5,6時間はかかってしまった、、、😥

Phaserは、ドキュメントも読みやすく、技術記事も多くて助かりました。

もし、また2Dブラウザゲームを作る機会があれば、

Phaserは選択肢に入れておきたい！👾

（ゲームを30秒間、最後までプレイして頂けると嬉しいです。）
Ubuntu 20.04でPHPの認証ができなくなった問題対策

問題：2024年12月14日にPHPのアプリケーションでLDAP認証が急に出来なくなった。
原因：Ubuntuのセキュリティパッチのバグ。
[PHP7.4 ldap broken on focal after 13 dec 2024](https://bugs.launchpad.net/ubuntu/+source/php7.4/+bug/2091707)

対策は以前リリースのldap.soに戻すことです。

手順
1.該当するubuntu環境に次のサイトからdebファイルをダウンロード。<br/>https://pl.archive.ubuntu.com/ubuntu/pool/main/p/php7.4/php7.4-ldap_7.4.3-4ubuntu2.24_amd64.deb
2.ファイルを解凍。<pre>ar x php7.4-ldap_7.4.3-4ubuntu2.24_amd64.deb</pre>
3.再び解凍。<pre>tar xf data.tar.xz ldap.so</pre>
4.ldapファイルをphpディレクトリに移動<pre>sudo cp ./ldap.so /usr/lib/php/20190902/ldap.so</pre>
5.apache2を再起動<pre>systemctl restart apache2</pre>
6.apache2で起動したことを確認<pre>systemctl status apache2</pre>
7.アプリからログインできるか確認

以上
関数

### 背景
繰り返し同じ処理を行うための関数をScratchで試してみました。
ここでは12/15に作ったScratchを書き直します。

### Scratch

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103446/d3cb220b-7a79-9efc-510d-8c7786569d4a.png)

関数「0-3の整数を入力するとマトリックスにその数字を表示する」

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103446/91db3418-d158-dcaf-df4d-882bd2d45c77.png)

実行するとカウントダウンする様子が見えました。


### spheroV2
pythonは整数から文字に変換できるので、関数の中が簡単になります。

```
import time

from spherov2 import scanner
from spherov2.sphero_edu import SpheroEduAPI
from spherov2.types import Color

def retStr0(num0: int, api: SpheroEduAPI):
    if num0 > -1 and num0 < 4 :
        api.set_matrix_character(str(num0), Color(250, 250, 250))
    else :
        api.set_matrix_character('x', Color(250, 250, 250))
    time.sleep(1)
    return 0

print("Testing Starting...")
print("Connecting to Bolt...")
toy = scanner.find_BOLT()

if toy is not None:
    print("Connected.")
    with SpheroEduAPI(toy) as api:
        api.set_stabilization(False)  # Disable stabilization

        # Countdown from 4 to 1
        for i in range(4, -1, -1):  # Reverse range
            retStr0(i, api)

        # Set main LED to green
        api.set_main_led(Color(r=0, g=250, b=0))
        time.sleep(1)

        # Clear the LED matrix
        api.clear_matrix()
        time.sleep(0.5)

    print("Testing End...")

else:
    print("Failed to connect to Sphero.")
```

実行結果はこちらのようになりました。
```
git\spherov2.py\spherov2\test>python BoltTest_matrix3.py
Testing Starting...
Connecting to Bolt...
Connected.
Testing End...
```

### まとめ
Scratchの関数を試してみました。
戻り値の設定ができないようなので、使い勝手は難しいようです。
2階線形微分方程式のメモ


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3759109/4ed00511-06cb-e820-eb8a-76db3288fb5c.png)

https://www.shinshu-u.ac.jp/faculty/engineering/appl/NOW/kenkyu/ohno/note09/appl1-13.pdf
MATLAB/Simulink 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3759109/da2b7a2e-b9c1-fe88-9975-b280015c6c6b.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3759109/d7441a41-3021-4fdb-1cd2-edf0925b2632.png)

```
import numpy as np
import matplotlib.pyplot as plt
from scipy.integrate import solve_ivp

# 微分方程式のパラメータ
a = 1  # 2次の係数
b = 2  # 1次の係数
c = 3  # 定数項の係数
C0 = 0  # 初期条件 x(0)
C1 = 0  # 初期条件 x'(0)

# ステップ入力の定義
def step_input(t):
    return 1 if t >= 0 else 0

# 微分方程式を定義
def diff_eq(t, y):
    x, dx = y  # y[0] = x(t), y[1] = x'(t)
    f_t = step_input(t)  # ステップ入力
    ddx = (f_t - b * dx - c * x) / a  # 2次微分の計算
    return [dx, ddx]

# 時間範囲の設定
t_span = (0, 10)  # 0秒から10秒まで
t_eval = np.linspace(0, 10, 1000)  # 時間の分割

# 初期条件
y0 = [C0, C1]  # x(0) = C0, x'(0) = C1

# 数値解を求める
solution = solve_ivp(diff_eq, t_span, y0, t_eval=t_eval)

# 結果のプロット
plt.figure(figsize=(8, 6))
plt.plot(solution.t, solution.y[0], label='x(t)', color='blue')
plt.axhline(1, color='red', linestyle='--', label='Step Input f(t)')
plt.title('Response of the System to a Step Input')
plt.xlabel('Time t')
plt.ylabel('x(t)')
plt.legend()
plt.grid()
plt.show()
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3759109/cbed54b0-0d98-8291-53f8-67224320b667.png)
非課金ChatGPT歴半年の私がお気に入りプロンプトを紹介する

## はじめに
私はChatGPT非課金勢ですが、半年間ほぼ毎日使っています。よく使っているものや、便利だったものをまとめていきます。あまり変わったことはしてなく普通のことしかやっていないですが、誰かの参考になれば幸いです。

## プロンプト集

#### 解説して{コード貼付}
コードの解説をしてほしい時に使用。追加で気になることがあれば、帰ってきた返答をコピペして、「ここを詳しく」とします。だいたい解決します。

#### レビューして{コード貼付}
自分でコードを書いた後に使っています。こうすると見やすい、とか、今はこっちの方が推奨されます、みたいなことを教えてくれます。

#### 簡潔にして{コード貼付}
冗長な部分をスッキリさせてくれたりします。回答が来た後にさらに「もっとできる？」というともっとしてくれます。変にやりすぎると可読性が落ちます（ChatGPTにもいわれます）。

#### さっきの回答との違いを明示して
同じような回答が来た時に使います。全く同じ回答をしているのに、違うふうなふりをして回答してくる時もあるので、このプロンプトを送ると間違いに気づいて謝ってきます。

#### {言語}で{処理}がしたい。コードをかいて
「C#でstringのハイフンを取り除きたい」とか「SQLで列を追加したい」とか。どうやって書くっけ？って思った時に、過去のコード見たりネット検索するよりも早く解決します。
このような一行で済むこと以外でも「HTML,JavaScript,CSSでブロック崩しを作って」といったら、コピペですぐ動くようなものも作ってくれました。

#### なにこれ{エラー文貼付}
デバッグしてエラー時に使います。エラーメッセージの意味と考えられる理由を教えてくれます。「この部分を見せてください」と言ってきたりするので、その後のやりとりで解決したりします。しないこともありますが。


#### {機能}の名前の候補を出して
変数名やメソッド名の候補を出してもらいます。複数出してくれることもあるので、「違いを教えて」と返すとニュアンスの違いを教えてくれます。

#### {知りたいこと}について調べてまとめて
最近、ChatGPTがネット検索にも対応しました。たんに「教えて」でもいいんですが、情報が古かったり誤っていたりすることもあります。この方法の場合、検索をして、ソースも教えてくれます。

#### 日本語訳して{英文貼り付け}
翻訳してほしい時に使います。迷惑メールを貼り付けたときは、これは詐欺だから気をつけろ、と教えておくれました。

#### (なんでもいいから話しかけてみる)
結局ChatGPTが追加で質問してくるので、会話のやりとりで解決していきます。最初から完璧なプロンプトなんて考えず、投げてみるのが吉です。



## パーソナライズ
実はChatGPTは、毎回の指示に一度設定しておいたことを反映させることができます。「設定」→「パーソナライズ」→「カスタム指示」ここに設定します。
以下は私の設定しているカスタム指示です。

#### 特に断りがない限り{環境}についての質問だと思ってください
ここに自分の使っている言語とかを入れておきます。それを前提に話してくれるのでいちいち伝える手間が減ります。

#### ですます調ではなくお嬢様口調で回答して
お嬢様口調になります（結構な頻度でですます調のまま返事がきます）



## おわりに
かなり便利なChatGPTですが、頼りきりにならないように気をつけたいですね。書かせておわりにせず、解説をさせるようにしています。
かなり使っているから課金してもいいのですが、タイミングを逃してずっとそのままです。無料でもすごく便利。
Cadence Linter

[Previous << Running Cadence Tests](https://qiita.com/flowcadence/items/cf23506a744373ed46ca)
[Next >> Flow Interaction Templates (FLIX)](https://qiita.com/flowcadence/items/65f173cc69d1eb22e38e)

https://qiita.com/flowcadence/items/3073d69c6e9895e68b5a#flow-cli-と-fcl

Cadence Linterは、静的解析ツールであり、Cadenceコードの潜在的な問題を発見します。Flow CLIで利用でき、一般的なミスや潜在的な問題が問題となる前に特定することで、開発者がより良いコードを作成できるよう支援するように設計されています。

また、リンターはコードのシンタックスエラーや意味(セマンティック)エラーをチェックし、修正方法の提案も行います。

```ruby
flow cadence lint [files]
```
<h1>Example Usage</h1>

```ruby
flow cadence lint **/*.cdc
```
<h1>Example Output</h1>

```ruby
test.cdc:27:6: semantic-error: cannot find variable in this scope: `abc`

test.cdc:35:6: removal-hint: unnecessary force operator

2 problems (1 error, 1 warning)
```

:::note
INFO
[Cadence VSCode 拡張](https://qiita.com/flowcadence/items/1b5bde9635935c1e4d8d)機能内にもCadence Linter が含まれており、コードを記述中にリアルタイム・フィードバックを行います。
:::

*Last updated on **Dec 6, 2024** by **Alex Ni***

翻訳元

https://developers.flow.com/tools/flow-cli/lint

***
<b>[Previous << Running Cadence Tests](https://qiita.com/flowcadence/items/cf23506a744373ed46ca)
</b>

[Flow blockchain / Cadence version1.0ドキュメント](https://qiita.com/flowcadence/items/3073d69c6e9895e68b5a) (Cadence Linter)

<b>[Next >> Flow Interaction Templates (FLIX)](https://qiita.com/flowcadence/items/65f173cc69d1eb22e38e)</b>
日本語トランスコンパイラ言語 Re:Mind（リマインド）をビルドできる環境をVSCodeで構築（シンタックスハイライト編）

# はじめに
日本語プログラミング言語ファミリー Re:Mind（リマインド）のアドベントカレンダーに初年度からご参加いただいている@Syuparnさんが、シンタックスハイライトとスニペットが使用可能なVSCode拡張機能を大幅にバージョンアップ！製品版とも言える状態に仕上げられていただいたので、ぜひ深堀りさせていただきたく、よろしくお願いいたします。

また、本記事のタイトルは少し紛らわしく、オープンな実装仕様とさせていただいる日本語トランスコンパイラ言語 Re:Mind（リマインド）の完全な実装はまだ存在せず、初期の試作品などで環境を構成する想定であることをご容赦お願い申し上げます。

# 前提条件
Windows11 Pro 22H2
VSCode(Visual Studo Code)　1.95.1


## VSCodeの拡張機能
remind-vscode 0.1.0

# 「Re:MindのVSCode拡張（非公式）」0.1.0のインストール

VSCodeの拡張機能の検索で、「remind-vscode」とタイプすると下図のような検索結果が表示されます。検索結果ペインで「Re:Mind VsCode」をダブルクリックするとエディタウィンドウにドキュメントが展開します。

![remind1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3118036/4e223c18-76bb-41c5-b68c-7d83392b8ad8.png)

# シンタックスハイライトの様子

日本語トランスコンパイラ言語のターゲットソースとしてビルド可能な記述例はあまり存在しておらず、仕様記述言語としてコンパイラ（トランスコンパイラ）非対応のコード例はいくつかあるので、それを表示してみます。

まずはこちらの記事にある「ノードカテゴライズする」と
「名称辞書を収集する」という関数の定義例をVSCode上で作成します。

https://qiita.com/mylifewithviolin/items/abf5b4fa3b12b285935f

## 「ノードカテゴライズする」

ファイルを新規作成して、コードを貼り付けた段階ではもちろん拡張子ないのでフラットな黒一色だったわけですが、それを拡張子remindで保存してみますと、下図のようにみごとなシンタックスハイライトでカラフルになりました:tada:

![remind2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3118036/2efdeb8f-5653-5a29-06f3-6d605ea8163a.png)

保存する際に、VSCodeのファイル保存コモンダイアログのファイル拡張子選択リストにもしっかりremindが出現することも確認できました！すごいです。

![remind3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3118036/93169262-415b-d921-a613-f683cad1bfd5.png)


## 「名称辞書を収集する」
つづいて、少し長めの記述量の「名称辞書を収集する」の方です。こちらは関数定義ヘッダ部が固定されてスクロールしました！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3118036/ae31f464-9136-d6c8-0bd6-6dd58bd45233.png)


# 謝辞
@Syuparnさん、素敵な機能の実装まことにありがとうございます。謹んでお礼申し上げます。スニペット機能のご紹介はまた別の記事で行わせていただきます。

# つづく
本記事のゴールは当面「Re:Mind」の試作品が対応する範囲のソースをターゲット言語でビルドできるようにtasks.jsonとlaunch.jsonを構成することです。デバッガエクステンションはないので、とりあえずMindと同じ方法でやってみます。
AtCoder ABC384 PythonでA〜Dを復習

## ABC384 感想まとめ

[トヨタ自動車プログラミングコンテスト2024#12（AtCoder Beginner Contest 384） - AtCoder](https://atcoder.jp/contests/abc384)

2ヶ月半ぶりにRated参加しました。結果はABCまでの3解答で、レーティング微減で茶色に戻っております。

久々に時間が決まっている中で問題を解いてみました。この緊張感はやはり、コンテストに参加しないとわからないものがありますね。

なんか、レーティングを気にするよりは参加回数を増やすほうが良いのかな、最近思い始めています。（イチロー氏は打率より安打数を重要視していた...という思考を真似ている)

## [A - aaaadaa](https://atcoder.jp/contests/abc384/tasks/abc384_a)

文字列 S を一文字ずつチェックして、違ったら置換します。
文字列 S を list にしておくと、楽かもしれません。

``` python
N, C1, C2 = input().split()
S = list(input())

for i in range(len(S)):
    if S[i] != C1:
        S[i] = C2

print("".join(S))
```

## [B - ARC Division](https://atcoder.jp/contests/abc384/tasks/abc384_b)

条件に従ってチェックしていきます。

``` python
N, R = map(int, input().split())
for i in range(N):
    D, A = map(int, input().split())
    if D == 1 and 1600 <= R <= 2799:
        R = R + A
        continue
    if D == 2 and 1200 <= R <= 2399:
        R = R + A
        continue
print(R)
```

## [C - Perfect Standings](https://atcoder.jp/contests/abc384/tasks/abc384_c)

問題 ["A", "B", "C", "D", "E"] 5つから解いた問題のパターンを全探索する必要があります。これは、bit全探索を使いました。

``` python
a, b, c, d, e = map(int, input().split())
points = [a, b, c, d, e]
names = ["A", "B", "C", "D", "E"]

point_names = defaultdict(list) # X点取った人の名前をリスト

# bit全探索
for bitnum in range(1, 1<<5):
    point = 0 # このbitでの得点
    name = [] # このbitでの回答者の名前
    for shift in range(5):
        # shift bit 桁だけシフトして、1/0判定
        if (bitnum>>shift) & 1:
            point += points[shift]
            name.append(names[shift])
    name.sort()
    fullname = "".join(name)
    point_names[point].append(fullname)

# 点数が高い順に並べる
sorted_keys = sorted(point_names.keys(), reverse=True)

# 点数が高い順にループ
for key in sorted_keys:
    # 同点の場合、名前順に並べる
    name_list = point_names[key]
    name_list.sort()
    for name in name_list:
        print(name)
```

## [D - Repeated Sequence](https://atcoder.jp/contests/abc384/tasks/abc384_d)

D問題はコンテスト中には正答できませんでした。

* 1ループの部分の和を求める(sum_a)
* Sをsum_aで割った余り(amari)を求める
* 余りを作れるか、判定

という流れはわかっていたんですけども、[余りを作れるか、判定]の部分を、コンテスト中はうまく実装できなかったのでした。

``` python
N, S = map(int, input().split())
A = list(map(int, input().split()))

sum_a = sum(A) # 1ループ内の合計
amari = S % sum_a # ループ外の得点(余り)

A2 = A + A # ループ2回分の配列
accumulate_a = list(itertools.accumulate(A2)) # 累積和
accumulate_a.insert(0, 0)

# A2の中で、余りに一致する部分和があるか検索
for i in range(len(accumulate_a) // 2):
    # 区間和 右端(value2)‐左端(value1) == amari になれば良い
    value1 = accumulate_a[i]

    diff = amari + value1
    index = bisect.bisect_left(accumulate_a, diff)
    if index < len(accumulate_a):
        value2 = accumulate_a[index]
        if value2 - value1 == amari:
            print("Yes")
            exit()

print("No")
```
Sequel Ace インストール

何か良いmysqlクライアントないかな〜、と探してたらSequel Aceというのが良さそうだったためインストールします。
サイトからでも
<a href="https://sequel-ace.com/">Sequel Ace</a>
コマンドでも(どちらでもOK)
```
$ brew install --cask sequel-ace
$ mas install 1518036000 # Sequel Ace
```
あとは接続先を指定すればOK
![スクリーンショット 2024-12-15 11.12.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/437239/1b4176c7-b818-07d0-5434-3f13e7ac4c25.png)
[Rust]ジェネリック型

## ジェネリック型が必要になるシーン

ジェネリック型は、構造体の型定義や関数のシグネチャを書くときに必要になる型について、呼び出し側でその型を決定できるようにする仕組みです。

### 関数にジェネリック型を使う

関数のシグネチャでは引数と戻り値の型を明記します。ただし、関数の目的によっては、特定の型に限らず、一定の条件を満たしている型であれば、関数の宣言時に型を限定する必要がないものもあります。

その場合、ジェネリック型の使用が適しています。ジェネリック型は関数名の後に`<型引数名>`と書くことで宣言します。一般的に型引数は`T`で宣言します（決まりではなく慣習です）。
ジェネリック型を定義すると、そのシグネチャ内でそのジェネリック型を使うことができます。例えば、何かしらの型の配列から特定の要素を返す関数であれば、引数の型に`&[T]`、戻り値の型に`T`と書くことができます。

```rust
fn first_element<T>(list: &[T]) -> &T {
    &list[0]
}

fn main() {
    let numbers = vec![10, 20, 30];
    let chars = vec!['a', 'b', 'c'];

    println!("The first number is {}", first_element(&numbers));
    println!("The first char is {}", first_element(&chars));
}

```

関数によっては、ジェネリック型として渡される型に条件を設けたい場合があります（例：二要素間で等価比較が可能である、標準出力が可能である、など）。それはトレイト（後日紹介）という仕組みで実現します。

### 構造体にジェネリック型を使う

```rust
struct Point<T> {
    x: T,
    y: T,
}

fn main() {
    let integer_point = Point { x: 5, y: 10 };
    let float_point = Point { x: 1.0, y: 4.0 };

    println!("integer_point: ({}, {})", integer_point.x, integer_point.y);
    println!("float_point: ({}, {})", float_point.x, float_point.y);
}
```

### 列挙型にジェネリック型を使う

```rust
enum Option<T> {
    Some(T),
    None,
}

fn main() {
    let some_number = Option::Some(5);
    let some_string = Option::Some("Hello");

    println!("{:?}, {:?}", some_number, some_string);
}
```

### メソッドにジェネリック型を使う

```rust
impl<T> Point<T> {
    fn x(&self) -> &T {
        &self.x
    }
}

fn main() {
    let point = Point { x: 5, y: 10 };
    println!("point.x: {}", point.x());
}
```

## ジェネリック型がもたらす効能

ジェネリック型を使うと、宣言を柔軟に行えるため、関数の呼び出し時や構造体の宣言時を柔軟に行いつつも、型安全性の恩恵を受けることができます。

例えば、以下の例では引数に応じて戻り値の型が自動的に決定されます。

```rust
fn identity<T>(value: T) -> T {
    value
}

fn main() {
    let number = identity(42);
    let text = identity("Hello");

    println!("number: {}, text: {}", number, text);
}
```

また、構造体の複数のフィールドの型を`T`で統一していた場合、インスタンスを生成するときにそれらのフィールドの型が一致していないとコンパイルエラーになります。

```rust
struct Pair<T> {
    first: T,
    second: T,
}

fn main() {
    // これはコンパイルが通る
    let pair = Pair { first: 1, second: 2 };

    // 型が一致しない場合はコンパイルエラー
    // let invalid_pair = Pair { first: 1, second: "string" };
}
```

このように、ジェネリック型を使うと、柔軟性と型安全性を両立させることができます。

:::note
この機構は他の言語でも積極的に採用されている印象です。TypeScriptとほぼ同等の書き心地であり、使いやすいのではないでしょうか。
TypeScriptでは、ジェネリック型に条件を付けたい場合は`extends`を使います。Rustにも似たようなことを実現するためのトレイトという機能があるので、次回はその解説を予定しています。
:::
データレイク・データウェアハウス・データマートとは？非エンジニアにもわかりやすく解説

この記事は [Ateam LifeDesign Advent Calendar 2024](https://qiita.com/advent-calendar/2024/ateam-life-design) の、24日目の記事となります。

# はじめに
## この記事の対象者
主にデータ分析に関わる方と、分析に必要なデータを蓄積しているエンジニアの方向けの記事です。

データレイク・データウェアハウス・データマートの概念を正しく理解することで、よりデータ分析が捗ることを目的にしています。

また、エンジニアの方で、既にこれらの用語は知っているよ。という方が、非エンジニアの方に説明するとき「こう説明するとわかりやすい」といった視点も含まれます。

## この概念を知るメリット
- エンジニアがデータ蓄積するとき楽になる
    - データの蓄積ルールが明確になることで、蓄積時に都度設計する手間がなくなる
- データの収集速度が上がる
    - どこに、どんなデータが入っているかが明確なので、データ収集が早い
- エンジニアの収集工数を抑えることが出来る
    - 毎回、非エンジニアの人からデータ抽出の依頼を受けて、データを加工・抽出する手間がなくなる

# データレイクとは？
データレイクは、英語にすると「Data Lake」。直訳すると「データの池」となります。
釣ってきた魚をそのまま池に放り込んでいるイメージです。

![データレイク.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/117041/350d5a35-ee7e-186d-32eb-903fbfada15e.jpeg)

データの世界では、取得したデータをそのまま保存している状態を指します。
少し難しい用語を使うと「非構造化データ」といいます。
つまり、Excelやスプレッドシート等のデータが、GoogleドライブやAmazonS3のようなストレージにそのまま加工せず保存されている状態を指します。

# データウェアハウスとは？
一言でいうと「図鑑」のイメージを持ってもらえるとよいのではと思います。
例えば、魚には背骨があり、内臓があり、目があり、エラがあり...と多くの要素で構成されています。
それらの構成要素が整理され、まとまっている状態がデータウェアハウスです。

![スクリーンショット 2024-12-15 9.42.46 2 2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/117041/87415352-7f34-7862-4ebb-4ca7b75c510d.png)

データの世界では、これを「構造化データ」といいます。例えばデータベース内のテーブルやカラムといった形で定義れた状態。定義に沿ってデータが蓄積されている状態を指します。

# データマートとは？
データマートは英語にすると「Data Mart」。直訳すると「データ売り場」となります。
つまり、釣ってきた魚が買い手にとって扱いやすい状態で販売されている状態です。

例えば、お刺身用の切り身、焼き魚用の切り身や開きになっている状態です。
スーパーマーケットの魚売り場のイメージですね。

![スクリーンショット 2024-12-15 9.42.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/117041/6cc85805-6a77-bfa0-3da5-dac99cc99347.png)

データの世界では、目的に応じてデータを抽出・加工して保存されている状態を指します。例えば営業の売上分析をしたい、マーケティングの市場分析をしたいという目的が合った場合、目的に沿った情報のみが過不足なく蓄積されている状態を指します。また、目的によってはあえて非構造データに戻すこともあります。

データウェアハウスとは別のデータベースもしくはテーブルを用意し、目的に沿った構造でデータが蓄積される状態を作り出すのが一般的です。また、データウェアハウス側にデータが蓄積されると、自動的にデータマート側も更新される仕組みが理想です。

# データ蓄積の流れ

データレイク、データウェアハウス、データマートにデータを保存する際には、以下の流れで行います。

1. まずは取得したデータをそのまま保存する（データレイク）
1. 取得したデータを構造化して保存（データウェアハウス）
1. 構造化されたデータを目的別に加工して保存（データマート）

![まとめ.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/117041/f6ba3e84-4cc5-d7e5-8d7c-4b19767cf802.jpeg)

# メリット・デメリット
## データレイク
### メリット
データの源泉を正しく保持しておくことで、万が一データウェアハウス・データマート側に何かしらのでデータ不備・問題が合った際に、改めてデータを作り直すことが可能となります。

### デメリット
データの分析には適していません。生データをそのまま集計に使うことによる集計結果の散乱、データ源泉と加工データの散在といった事象が発生し、分析の効率を落とす結果になります。

## データウェアハウス
### メリット
データが構造化されているため、データレイクと比較するとデータ分析が行いやすいです。特に、SQLを使えるデータサイエンティストにとって扱いやすい点が特徴です。

### デメリット
データを扱うためにはデータベースの基本的な概念や、SQL等の知識が必要となります。エンジニアやデータサイエンティスト以外の方にとってはやや取り扱いのハードルが高いです。

## データマート
### メリット
特にデータサイエンティスト以外のビジネスユーザーにとっての扱いやすさ、言い換えるとデータ取得の速さが一番のメリットです。また、データを取り扱うエンジニアに取っては、都度必要なデータを加工して用意する手間（工数）の削減に繋がります。

### デメリット
目的を絞って、データマート化を行わないと、データマートが散乱し逆にエンジニアの工数を必要以上に消費してしまう結果に繋がります。定常的に行わなければいけない主要な分析目的に絞ってデータマート化することが重要です。

# 終わりに
いかがでしたでしょうか？
とても簡単な説明ではありますが、概念は理解できたのではないかと思います。
また、概念を理解することで、非エンジニアの方がエンジニアと会話するときに共通言語で会話することが出来るようになると思います。

また、エンジニアの方は、データの専門家ではない人たちに、用語の意味を理解してもらうだけで、会話はかなり捗るのではないかなと思います。「あ、このことを行っているのね」と相手が理解してくれるだけで、コミュニケーションの速度も上がるし、時間の短縮にもなります。

データの専門家ではない非エンジニアの方は、上記の概念だけでも抑えて頂けると、エンジニアはとても助かると思います。ぜひご活用いただけると幸いです。
【個人備忘】Herokuのproduction用のDyno Typeの設定について

【前提】
HerokuのDyno TypeにはWebとWorkerが存在する。ざっくりとした認識は以下の通り。
```
 Web→リクエストが飛んできたら起動する。最後のリクエストから30分でスリープする。
 Worker→能動的に落とさない限り常時起動している。
```

production用のアプリケーションでは、Procfileをプロジェクトのルートディレクトリに配置して、web/worker dynoの起動コマンドを記述してやる必要がある。
どちらのDyno Typeを使用するかによって、どちらかを準備すればいい。
```Procfile:Procfile
web npm start
```
``` Procfile:Procfile
worker npm start
```
自作Railsアプリをproductionで実行しようとしたらうまくいかなかった話

# 1. 概要
自作Railsアプリのプログラム部分の開発が大体終わったので、Docker環境上でproductionできちんと動くかどうか検証したところ、一部のデザインの表示が崩れたり、グラフが表示されない、ツールチップが動作しない等の不具合が生じた。
解決まで結構時間がかかってしまったので、備忘として記録する。

# 2. 前提
Railsバージョン：7.1.4

# 3. 試したこと
ChatGPTに聞いたら色々解決策を提示してくれたので、まずは以下のことを試してみた。
### rails asset:precompile
Productionモードでは、アセットが事前にプリコンパイルされていないと正しく読み込めないとのことなので、Dockerコンテナ作成後に以下のコマンドを実施
```
docker-compose run web rails assets:precompile
```
→特に表示は変わらずデザインが崩れたままだった。
実行後に
 ```
 File to import not found or unreadable: microtip.min. (SassC::SyntaxError)
 ```
 というエラーを吐いていたので、microtip.minが正しいフォルダに格納されていないのかもと思い、確認したものの、assets/stylesheets配下に格納されているため、格納パスには問題なさそう。。。

### production.rbの見直し
production環境では、アセットパイプラインでプリコンパイルされたファイルが public/assets に配置される。Railsサーバーが適切なURLでアセットを提供していない可能性があるため、以下のコードをproduction.rbに追加。
```ruby:prodction.rb
  # 以下追加
  config.assets.compile = false
  config.assets.digest = true
  config.assets.debug = false
  config.public_file_server.enabled = true
```
→特に表示は変わらずデザインが崩れたままだった。

# 4. さらに試したこと
### rails asset:precompileに失敗していることについてもう一度考える
rails asset:precompileについてはよく理解しない状態で実行していたが、以下の記事を見ると、asset:precompileを実行することによりapp/assets配下のファイルがpublic/assets配下にプリコンパイルされるという動きをとるらしい。
production環境ではpublic/assets内のファイルを読み取る。

https://qiita.com/MIDO-ruby7/items/9718b40c97e4d282ae83

public/assets内のファイルを参照して不足しているものがあるかどうか確認したところ、ちょうど本番環境上で不具合が生じている、microtip.min.cssに対応するファイルがないことを確認。
rails asset:precompileが正常に動作していればmicrotip.min.cssに対応するファイルもpublic/assets内に存在しているはず。

**→rails asset:precompileのエラーを解決してしまえばデザインの崩れも治るはずだと考えた**
（一部デザインを除き正常に表示されているのは、ローカルで開発している過程でrails asset:precompileを実行したことがあり、その時に大半のファイルがpublic/assetsにコンパイルされたため。
事実、正常に表示されていないのはツールチップ等の開発の後半に導入したデザイン）

### rails asset:precompile実行時のエラーを解決する。
 ```
 File to import not found or unreadable: microtip.min. (SassC::SyntaxError)
 ```
rails asset:precompile実行時の上記エラーを見ると、microtip.min.cssのインポートに失敗している。
先述の通りmicrotip.min.cssはassets/stylesheetsフォルダ内に格納されているため、格納パスには問題ない。
application.css内では以下のようにしてmicrotip.min.cssのインポートを実施していたが、
 ```css: application.css
 @import 'app/assets/stylesheets/microtip.min.css';
 ```
 以下のようにフルパス指定に変えてみたところ、rails asset:precompileは正常に動作し、無事microtip.min.css等を含めてプリコンパイルすることに成功。
  ```css: application.css
 @import 'app/assets/stylesheets/microtip.min.css';
 ```

 # 5. 結果
docker-compose upコマンドでRailsアプリを立ち上げて再度アプリの動作を確認したところ、崩れていたデザインが全て正常に表示されました！

 # 6. まとめ
 rails asset:precompileの意味を初めからきちんと理解しようとしていればもっと早く解決できたので、コマンドの意味をきちんと理解した上で実行することの大切さを実感しました。。。
source、bash、shの違い

source、bash、shはすべてシェルスクリプトを実行するためのコマンドですが、それぞれ異なる特性と用途があります。以下にそれぞれの違いを詳しく説明します。

### source コマンド
- シェルの組み込みコマンド: sourceはシェルの組み込みコマンドであり、外部プログラムではありません
- 現在のシェルで実行: sourceコマンドを使ってスクリプトを実行すると、そのスクリプトは現在のシェルプロセス内で実行されます。これにより、スクリプト内で設定された環境変数やシェルオプションが現在のシェルに影響を与えます
- シンタックス: source scriptname または . scriptname（ドットコマンドとしても知られています）
### bash コマンド
- 外部プログラム: bashはBashシェル（Bourne Again Shell）を起動する外部プログラムです
- 新しいシェルプロセスで実行: bashコマンドを使ってスクリプトを実行すると、新しいBashシェルプロセスが作成され、その中でスクリプトが実行されます。スクリプト内で設定された環境変数やシェルオプションは、元のシェルには影響を与えません
- Bash特有の機能: bashはBashシェルの全機能をサポートしており、例えば配列、連想配列、拡張グロブ、プロセス置換などのBash特有の機能を利用できます
- シンタックス: bash scriptname
### sh コマンド
- 外部プログラム: shはシェル（通常はBourne Shellまたはその互換シェル）を起動する外部プログラムです
- 新しいシェルプロセスで実行: shコマンドを使ってスクリプトを実行すると、新しいシェルプロセスが作成され、その中でスクリプトが実行されます。スクリプト内で設定された環境変数やシェルオプションは、元のシェルには影響を与えません
- 互換性: shはPOSIX標準に準拠しており、Bourne Shellスクリプトの互換性を重視します。Bash特有の機能はサポートされないことが多いです
- シンタックス: sh scriptname
### 具体的な違いの例
例えば、以下のようなスクリプト example.sh があるとします。
```sh
#!/bin/bash
export MYVAR="Hello, World!"
echo "Bash version: $BASH_VERSION"
```
sourceを使った場合
```console
$ source example.sh
Bash version: 5.0.17(1)-release
$ echo $MYVAR
Hello, World!
```
sourceを使うと、example.sh内で設定された環境変数MYVARが現在のシェルに影響を与えます。また、スクリプト内のBash特有の機能も利用できます。

bashを使った場合
```console
$ bash example.sh
Bash version: 5.0.17(1)-release
$ echo $MYVAR
```

bashを使うと、新しいBashシェルプロセス内でスクリプトが実行されるため、example.sh内で設定された環境変数MYVARは元のシェルには影響を与えません。

shを使った場合
```console
$ sh example.sh
Bash version: 
$ echo $MYVAR
```

shを使うと、新しいシェルプロセス内でスクリプトが実行されますが、Bash特有の機能（例えば$BASH_VERSION）はサポートされないため、空の出力になります。

まとめ
- source: 現在のシェルプロセス内でスクリプトを実行し、環境変数やシェルオプションに影響を与える
- bash: 新しいBashシェルプロセスを作成してスクリプトを実行し、Bash特有の機能をサポートする。元のシェルには影響を与えない
- sh: 新しいシェルプロセスを作成してスクリプトを実行し、POSIX標準に準拠する。Bash特有の機能はサポートされないことが多い。元のシェルには影響を与えない
この違いを理解することで、適切なシチュエーションで適切なコマンドを選択することができます。
初めてのチーム開発で学んだこと：スニペット管理アプリの開発経験

## はじめに

Yasuと申します．私は2024年10月より，内定直結型エンジニア学習プログラム「アプレンティス」に参加しています．

https://apprentice.jp/lp

本記事では，プログラムでの初めてのチーム開発について，そのプロセスや学びを共有します．特に，初学者向けのスニペット管理アプリを開発した経験を中心に，どのように課題に取り組み，成長できたのかをご紹介します．

## 今回のチーム開発の概要

### 要件
- **テーマ**: 「自分たちの役に立つものを開発する」
- **技術スタック**: HTML/CSS，JavaScript，Ruby，MySQL
  ※フレームワークの使用は禁止．

### 開発スケジュール

| 期間         | 内容                          |
|:------------:|:-----------------------------:|
| **Term1** 2W | 自己紹介，アイデア決定        |
| **Term2** 2W | 要件定義，設計                |
| **Term3** 2W | タスク出し，環境構築          |
| **Term4** 2W | 未終了のタスクを進める                  |
| **Term5** 1W | 実装，プレゼン準備            |

※個人課題と並行しながら進行，Term5はチーム開発に専念．

## 作ったプロダクト: **SnipNest**

### 概要
**SnipNest**は，学習者向けのスニペット管理アプリです．  
学んだコードスニペットを簡単に登録・整理し，必要なときにすぐ再利用できる機能を提供します．以下の点を重視して開発しました：

- **基本機能**: CRUD操作（作成・読み取り・更新・削除）と検索絞り込み機能．
- **特徴**: プロ向けアプリのような複雑さを排除し，学習者が使いやすいシンプルなUI/UXを追求．

![a.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3837865/f158dffd-5dea-83e3-18c1-b8297afbc12d.gif)

## チーム開発の流れ

### アイデア決定

チーム結成後，ブレインストーミングで多数のアイデアを出し，「スニペット管理アプリ」を選定しました．その理由は以下の通りです：

- **既存アプリとの差別化**: プロ向けの複雑なアプリが多い中，学習者に特化した手軽なツールが少ないと感じたため．
- **実用性**: 自分たちが学んだスニペットを効率的に管理・再利用できるツールが欲しいと思ったため．

### 要件定義と設計

#### 要件定義
アプリに必要な操作を洗い出し，フロー図で整理しました．これにより，必要な機能が明確化し，設計にスムーズに移行できました．フロー図はCanvaで作成しました．

![スクリーンショット 2024-12-15 8.21.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3837865/2944c704-7c66-13b3-835e-19ee2fc1c9c0.png)


#### 設計
- 初学者ゆえ，サーバ通信やライブラリ選定に苦労．
- サーバにはRubyの**WEBrick**を採用．ローカル環境での動作を重視しました．

## 環境構築

### Dockerの活用  
チーム全員の開発環境を統一するため，Dockerを導入しました．これにより，バージョン差異やローカル環境依存の問題を解消し，全員が同じ環境で効率的に開発を進められるようになりました．

### GitHubフローとActionsの活用  
作業管理にはGitHubフローを採用し，プルリクエストを通じてコードレビューを行いました．また，GitHub Actionsを導入し，自動でRubocopやLinterによるコードチェックが実行される仕組みを構築しました．

DockerやGitHubはほぼ未経験でしたが，チームメンバーが率先して環境構築を進めてくれたおかげで，初心者の自分でもコード品質を保ちながら開発できました．これにより，安心して作業を進めることができました．

技術スタックは以下のように決定し，開発を進めました．

![スクリーンショット 2024-12-15 8.21.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3837865/5cc25288-7453-1fb3-248f-7043964177a9.png)


## 実装と担当箇所

私の担当は**トップページ**の作成でした．  
トップページは，ユーザーが他のページへアクセスする基点となるため，次の点を意識しました：

- **シンプルで高速**: 必要最低限の機能を実装し，タイル型でスニペットを直感的に表示．
- **サポート時間の確保**: 他メンバーのフォローにも時間を割くため，早期完成を目指しました．

また，トップページを早く作ることができたので，検索機能を実装したり，ページのデザインを作り込んだりすることができました．

## 成果と課題

### 成果

- **GitHubフローの理解**: チームで開発すると，各々が自由に開発するため，共通理解がないとエラーやコンフリクトが大量に生じることを実感しました．プルリクエストを活用してレビューを徹底することで，問題を最小限に抑える経験ができました．
- **フロントエンドとバックエンドの連携**: Rubyでサーバを起動し，MySQLのデータベースと連携．初学者ながら，これらを構築して一つのアプリを完成させたことは自信につながりました．
- **チームの強みを実感**: チームで連携することで，一人で作る場合よりも何倍も良いものが作れることを体感．

### 課題

- **デザインの統一性**: HTMLのidやclassを共有し，基本的なCSSをあらかじめ設定するルールが不足していました．今後は，明確なコーディング規約を策定し，メンバー間での統一感を高めたいと考えています．

## 初学者としての成長

初めてフロントエンドとバックエンドを1から構築し，それらを連携させて1つのアプリを完成させました．これは大きな自信となり，自分の成長を実感しています．また，DockerやGitHubなどのインフラ部分を体験し，その重要性や利便性を強く感じました．

特にチームメンバーのサポートがあったことで，未経験だった環境構築やコードレビューのプロセスにも対応でき，学びが深まりました．

また，スライドの作成とプレゼンを担当することで，プロダクトに関するプレゼンがどういうものなのか経験を積むことができました．

## まとめ

初めてのチーム開発を通じ，技術力とチームで成果を出す力を学びました．今後は，デザインの統一や進捗管理をさらに改善し，フレームワークなど新たな技術を活用して，より洗練されたプロダクトの開発に挑戦したいと考えています．

この記事が，同じように学習を進める方の参考になれば嬉しいです．
Fargate接続ツール(2)

本投稿は、メタップスアドベントカレンダー18日目のエントリー記事です。

## 概要

以下で [@fumiken](https://qiita.com/fumiken) さんが開発されたFargate接続ツールを紹介されています。
メインのPythonのツールについてはこの記事の内容をご参照ください。

https://qiita.com/fumiken/items/bdfa49239cdb76820e53

ツールを利用するための事前準備は [README](https://github.com/metaps/connect_to_fargate/blob/main/README.md) をご参照ください。

本記事では、このPythonプログラムをラッピングしたシェルスクリプトを作成したのでそのご紹介をします。



## 解説

シェルスクリプトは以下のものになります。

https://github.com/metaps/connect_to_fargate/blob/main/fargatessh


まずは、
```
fargatessh
```
のみで実行します。
usageが表示されます。
```
$ fargatessh
usage:
  fargatessh [OPTION]...
    -p AWS_PROFILE(require)
    -c CLUSTER_NAME
    -s SERVICE_NAME
    -t CONTAINER_NAME
    -f FORCE_LOGIN
  ex) fargatessh -p profile -c cluster -s service -t app
```

AWS_PROFILE は必須指定です。

AWS_PROFILE を指定して 
```
fargatessh -p testprofile
```
で実行してみます。
ここで、aws sso を利用している場合は、認証しているか判定されます。
未認証の場合は、ブラウザが開くので、aws sso の認証を行います。

```
fargatessh -p testprofile
Attempting to automatically open the SSO authorization page in your default browser.
If the browser does not open or you wish to use a different device to authorize this request, open the following URL:

https://device.sso.ap-northeast-1.amazonaws.com/

Then enter the code:

XXXX-XXXX
````

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/867400/f13f9673-d3d7-2b90-a612-fb2b05d70e7a.png)


以降はconnect_to_fargate.pyの動作でクラスター、サービス等を順番に選択していきます。

```
Successfully logged into Start URL: https://organization.awsapps.com/start
処理を開始します
[?] 接続先が存在するクラスター名を選択してください:
 ❯ default
   project-a-claster
```

### 利用事例

クラスター名のみが分かっているがクラスター内のサービス名が分からないといった場合は
```
fargatessh -p testprofile -c project-a-claster
```
のように実行すると、サービス名以降を選択する形になります。



頻繁にログインするfargateの場合は、すべてのオプションを指定することで、タスク名のみ選択してログインできます。
ログイン確認不要な場合は `-f (force login)` のオプションを付けておくとよいでしょう。
```
fargatessh -p testprofile -c project-a-claster -s project-a-service -f -t app
```


```
$ fargatessh -p testprofile -c project-a-claster -s project-a-service -f -t app
処理を開始します
[?] 接続先が存在するタスク名を選択してください:
 ❯ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

タスク名: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

以下のFargateに接続します
----------------------------------------
クラスター名: project-a-claster
サービス名: project-a-service
タスク名: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
コンテナ名: app
----------------------------------------

Fargateにログインします

The Session Manager plugin was installed successfully. Use the AWS CLI to start a session.


Starting session with SessionId: ecs-execute-command-xxxxxxxxxxxxxxxxxxxxxxxxxx

root@ip-10-254-1-254:/# 　　　　　　　　　　　　<------ログイン成功
```

## 補足

fargate接続後、vimの操作をする場合は、以下の記事も参考になるかと思いますので、ご参照ください。

https://qiita.com/koda-h/items/f074284025e942696351