OmniAICreator/Qiita-1.07M huggingface dataset:
windowsでiverilog その171

# 概要　
windowsでiverilogやってみた。
練習問題、やってみた。

# 練習問題
AtCoderを解け。

# 二つの整数a,bの積の偶奇を判定する。

```

module test;
	integer p;
	integer stdin = 'h8000_0000;
	integer a,
		b,
		c;
	integer ch;
	reg [7:0] pc;
	reg [7:0] str[0:9];
	integer v;
	initial
	begin
		pc <= 10;
		v = 0;
	end
	always #1
	begin
		case(pc)
		10:
		begin
			p = $fscanf(stdin, "%d%d", a, b);
			pc <= 20;
		end
		20:
		begin
			c = (a * b) % 2;
			if (c == 0)
			begin
				$write("Even");
			end
			else
			begin
				$write("Odd");
			end
			pc <= 30;
		end
		30:
		begin
			$finish(0);
		end
		endcase
	end
	initial
	begin
		//$monitor(" %d", pc);
	end
endmodule




```

以上。
OpenCVのAVIF/WebP Animationを試そう！

この記事は[OpenCV Advent Calendar 2024](https://qiita.com/advent-calendar/2024/opencv)の22日目の記事です。
他の記事は目次にまとめられています。

TL;DR
=====
- OpeCV 4.11にAnimation WebP Codecsが追加されました！
- ファイルへ書き出すときは`imwriteanimation()`関数を使ってください！
- `imwriteanimation()`は、WebPもAVIFもサポートしているけど、GIFやAPNGはまだだよ（多分）

はじめに
========
[OpenCVのGIF codecを試してみよう！](https://qiita.com/hon_no_mushi/items/9b34f2893558606f96ed) で述べた通り、GIFフォーマットはLZW特許問題で色々あった…

さて、JPEG形式は今なお絶大なシェアを持つ画像形式ではあるが、これに対抗できるフォーマットについては検討が続いている。その中で、googleが2010年に発表したのが、webpである。そしてその後継としてAVIFも徐々にシェアを伸ばしつつある…。

さて、GSoc 2024として、OpenCVでは、animation画像対応として、前述のGIFに加えて、Animation WebPサポートの検討も行っていた。 

ということで、OpenCVのanimationが、2024/12/20に4.x branchにマージされたので、さっそく動かしていきたい！

https://github.com/opencv/opencv/wiki/GSoC_2024#idea-animated-images-and-other-functionality-for-imgcodecs

# imwriteanimation()の使い方
ではさっそく、アニメーション生成機能を動かしていく。

なお、公式ドキュメントしか好かん！というかたはこちらを参考ください。
https://docs.opencv.org/4.x/d5/dfb/tutorial_animations.html

```cpp
// g++ main.cpp -o a.out -I/usr/local/include/opencv4 -lopencv_core -lopencv_imgcodecs -lopencv_imgproc

#include <opencv2/core.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/imgproc.hpp>

int main()
{
  cv::Animation anims;
  cv::Mat logo = imread("opencv-logo-white.png", cv::IMREAD_COLOR);
  for(int i=0; i < 20; i ++ )
  {
    cv::Mat work = logo.clone();
    cv::putText(work,
        cv::format("%d",i),
        cv::Point(40,40),
        cv::FONT_HERSHEY_SIMPLEX,
        1.5,
        cv::Scalar::all(255) );
    anims.frames.push_back( work );
    anims.durations.push_back( 200 /*ms*/ );
  }
  imwriteanimation("output.webp", anims );
  imwriteanimation("output.avif", anims );
  imwriteanimation("output.gif", anims ); // 何も起きない
}
```

たったこれだけである！！（どどーん！）
- `cv::Animation anims` でインスタンスを作る
- `anims.frames.push_back()` でイメージを追加
- `anims.durationis.push_back()` で更新間隔を追加
- `imwriteanimation("ファイル名", anims) で出力。ファイル名の拡張子でWEBPにしたりAVIFにしたり

なお、QiitaさんはWebPもAVIFも受け付けてくれなかったので、ファイルは無しでございます・・・

GIF/APNGはおそらくこれからサポート
--------------------------------
OpenCVのドキュメント上では、AVIF、WebPだけでなく、GIFやAPNGもサポートに見えるけど、実際はまだ非サポートっぽいですね…

https://docs.opencv.org/4.x/d7/d65/structcv_1_1Animation.html#details
> Represents an animation with multiple frames. The Animation struct is designed to store and manage data for animated sequences such as those from animated formats (e.g., GIF, AVIF, APNG, WebP). It provides support for looping, background color settings, frame timing, and frame storage.

GIF Encoderと比べるとどうなの？
=============================
今回のGIF Encoderは1frame単位でLZW圧縮しているので、前フレームとの差分とかをとって画像サイズを小さくしていないみたい。

これに対して、libavifやlibwebpなどを使って圧縮するので、より小さいサイズになることが期待できそう！

できれば、こっちを使った方がいいですね・・・

まとめ
======
- OpeCV 4.11にAnimation WebP Codecsが追加されました！
- ファイルへ書き出すときは`imwriteanimation()`関数を使ってください！
- `imwriteanimation()`は、WebPもAVIFもサポートしているけど、GIFやAPNGはまだだよ（多分）
Snowflakeで数理最適化の問題を解いてみる

# やること
以下のような高校数学でも習うような簡単な問題をSnowflake を用いて解いてみる．
今回解くのは，数理最適化の中でも簡単に解くことのできる，連続な線形最適化問題とする．数理最適化についてはUdemyでコンテンツを出しているため、こちら[明日から役立つ「オペレーションズ・リサーチ概論」](https://www.udemy.com/course/ortkskmshd/?couponCode=V2JPLETSLEARN)を視聴いただければ幸いである．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3880471/411fc159-fa58-08bc-4a63-41fa704ddbf0.png)

# サンプルコード
以下，Python on Snowflake で動作するサンプルコードである．
Snowflake のデータベースへのアクセスは行っていないが，応用すれば，Snowflake のデータベースからデータを入力し，結果を書き込むことも可能である．
```Python
import snowflake.snowpark as snowpark
from snowflake.snowpark.functions import col
from pulp import LpMaximize, LpProblem, LpVariable, value
import pandas as pd

def main(session: snowpark.Session): 

    m = LpProblem(sense=LpMaximize)  # 数理モデル
    x = LpVariable("x", lowBound=0)  # 変数
    y = LpVariable("y", lowBound=0)  # 変数
    m += x + y                       # 目的関数
    m += x + 2 * y <= 2              # 制約条件1
    m += 2 * x + y <= 2              # 制約条件2    
    m.solve()  # ソルバーの実行
    results = [{'var': v.name, 'val': v.varValue} for v in m.variables()]
    df_results = pd.DataFrame(results)
    df_results.loc[len(df_results)] = ['opt',value(m.objective)]
    dataframe = session.create_dataframe(df_results)
    
    return dataframe
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3880471/b20f515e-cda2-a39f-f7b3-533fe0a186fa.png)
大型プロジェクトで学んだこと

# 前置き
筆者は社会人4年目のエンジニアです。

今回、初めて<b>0から機能開発</b>するプロジェクトに携わらせていただきました。
本記事は、<INS>大型プロジェクトで学んだこと(「課題」と「解決策」)</INS>をメモとして記したものです。

# 課題①プロジェクトが長期に渡ると疲弊する
体力には多少自信があったのですが、同じプロジェクトに長く触れ続けるのはかなり苦痛でした。
嫌い、とかではなく、飽きが来てました。

## 解決策①リリースのみでなく、間に細かくマイルストーンを設定することで、区切りをつける
常に全部やるではなく、画面ごとや機能ごとに関係者と完了を設定しなければいけません。でないと一生終わりません。
すぐにわかることであればマイルストーンは必要ありません。しかし、初めてやる長期の全貌が見えてないものほど、<b>誰でもわかるマイルストーンを必ず置かなければいけません。</b>

# 課題②わかりやすく短く正しく報連相ができない
仕事、ましてや大型プロジェクトは一人でできませんでした。
そのため、報連相は必須、かつ、多くなるのですが、うまく話せず相手に伝わらないことが多く、お互い時間を奪ってしまっていました。

## 解決策②：3Sな報連相
ビジネスコミュニケーションが苦手だとわかったとき、絶望しました。
どの仕事でもビジネスコミュニケーションは必要なので。
苦手でも人並にできないかと思い、<b>カンペ</b>を作るようにしました。
時間がかかっても<b>シンプルで短く、正確な報告</b>ができるように作成、報連相することを意識しました。

# 課題③関係者が多い
要件、セキュリティ、UI、クライアント、すべて一人ではできないので、担当者がいます。
担当者が多ければ、担当者とのやり取りが多くなります。
担当者とのやり取りが多くなれば、考慮すべき課題も多くなります。疲弊します。
しかし、リリースまでにどれも必要です。欠くとしっぺ返しを喰らいます。

## 解決策③リリースに必要な要素を明確に
曖昧にものごとを進めてしまいました。
つまり<b>「ゴール」とは何を指すのか</b>、関係者と認識の擦り合わせができておりませんでした。
正直、業界知識も浅く、「決断」を後回しにし、「ゴール」の条件を決定しなかったことを後悔しています。

# まとめ
今回の大型プロジェクト、かなり疲弊しました。まだ終わってませんが。
まるでゾンビのようになって、考えることを放棄しそうになってました。
上記の3つ以外で重要なのは<b>「息抜き」</b>でした。自分がリラックスできて、スマホから離れ、くだらないことでも<b>考える時間を無理やりでも設ける</b>ことが必要でした。

大変なことが多かったですが、<b>振り返ることで得られた学びは大きい</b>と感じます。
同じようにプロジェクトで悩んでいる方の参考になれば幸いです。
AndroidStudioでデバッグ中に「processing classes for emulated method breakpoints」が出る


# はじめに
AndroidStudioでデバッグをかけたところタイトルにあるような表示がでて少し待ったのですが、読み込みが進まずフリーズしてしまいました。

# 対策
ブレイクポイントを本当に必要なところ以外全て消して実行したところフリーズはしなくなりました。

また、調べたところAndroid StudioのバージョンがKoaraだと出ると言ってる情報もありました。
実際私もKoaraだったので頻繁に発生する場合はバージョンアップまたは、バージョンダウンしてもいいかもしれません



# 参考
https://stackoverflow.com/questions/78125635/processing-classes-for-emulated-method-breakpoints-this-popup-comes-and-loadin

https://stackoverflow.com/questions/42478937/how-to-effectively-remove-all-breakpoints-in-android-studio/42478994#42478994
アドベントカレンダーのトピックまとめ

## 2024アドベントカレンダーのトピックを分類しました

さて、2024年のアドベントカレンダーを書い進めてきましたが、「まとめが欲しい」とのリクエストがありましたので、全体の構成の話をします。気になるトピックをまとめて読みたい場合は、参考にしてください。


## テスト設計で使うアクティビティを、順に挙げていた
実は、全体を通して、テストアクティビティが表面的に網羅できるように構成していました。なので、一通り読むと、Web製品のアプリケーションレイヤーで、全体的なアクティビティとして、どういったものがあるかが、大まかに把握できるようになっています。

単に「テスト」といっても、この程度の知識は必要になってきますし、やることはたくさんありますよ、というのが少し伝われば幸いです。

以下、分類です。重複があるのは、１つの記事が多面性を持っているためです。

### テスト設計
[[自分のテストフレームワークを作ろう！]](https://qiita.com/EgaSaQA/items/1eb643ebda0cceafa4bb)
[[テスト設計の話]](https://qiita.com/EgaSaQA/items/6ec8cc23ae2c3cb7e92e)
[[テストコンディションにはどんなものがある？]](https://qiita.com/EgaSaQA/items/328f51cafa1ea570a780)
[[エンティティを整理して気付きを得る]](https://qiita.com/EgaSaQA/items/f02f41c15303c51c6aaf)
[[膨大なテストコンディションがあるときの対策]](https://qiita.com/EgaSaQA/items/967c9411c2e35fdfb017)
[[1ページテスト計画]](https://qiita.com/EgaSaQA/items/57daa2fee5e9d3f41540)
[[点と線、因子と水準の話]](https://qiita.com/EgaSaQA/items/56db9f23fa82ab1f4311)
[[面を作る話]](https://qiita.com/EgaSaQA/items/96c3c58be07d014abaea)
[[立方を作る話]](https://qiita.com/EgaSaQA/items/000be3c0c3ec9ef237d7)
[[Web系のテストでよく使われる技法]](https://qiita.com/EgaSaQA/items/783bc11544c64f1767a3)
[[テスト戦略の話]](https://qiita.com/EgaSaQA/items/e9d0a80d545a432d05bf)

### 品質保証戦略
[[自分のテストフレームワークを作ろう！]](https://qiita.com/EgaSaQA/items/1eb643ebda0cceafa4bb)
[[Regression貧乏の話]](https://qiita.com/EgaSaQA/items/7fdbba1d138ecd01b0ea)
[[膨大なテストコンディションがあるときの対策]](https://qiita.com/EgaSaQA/items/967c9411c2e35fdfb017)
[[クライテリアコントロールの話]](https://qiita.com/EgaSaQA/items/03317ee6b649ee59b757)
[[Web系のテストでよく使われる技法]](https://qiita.com/EgaSaQA/items/783bc11544c64f1767a3)
[[パレート分析の話]](https://qiita.com/EgaSaQA/items/1c6014d0c175d116d627)
[[テスト戦略の話]](https://qiita.com/EgaSaQA/items/e9d0a80d545a432d05bf)


### テストコントロール
[[膨大なテストコンディションがあるときの対策]](https://qiita.com/EgaSaQA/items/967c9411c2e35fdfb017)
[[クライテリアコントロールの話]](https://qiita.com/EgaSaQA/items/03317ee6b649ee59b757)

### エンハンスメント
[[モデリングの話]](https://qiita.com/EgaSaQA/items/6b63210d0f7ece6700cb)
[[マインドマップを使いこなす]](https://qiita.com/EgaSaQA/items/a9d915f2f840f0aba416)
[[時系列に従ったテストを洗い出す、アミダモデリングの話]](https://qiita.com/EgaSaQA/items/820f069144ca6056f0b4)
[[QC７つ道具の活用（特性要因図）]](https://qiita.com/EgaSaQA/items/133ebd92143d750281dc)

### エッセイ
[[QA学園の話]](https://qiita.com/EgaSaQA/items/1b2ddb978712a8f9f03a)
[[「結合テストは死んだのか？」]](https://qiita.com/EgaSaQA/items/c0b9448e86d2a9f4b2ed)
[[ChatGPTの使いどころ]](https://qiita.com/EgaSaQA/items/84def8a9e8bf4849a6c0)
[[グローバルQAチームの日常]](https://qiita.com/EgaSaQA/items/d584d5505c65f0a7d398)
[[アプリケーションとして正しいものと製品としてあるべきもの](未記載)
[[テストの性能について]](未記載)

#
### 用語解説

#### テストコントロール
計画と実行の乖離を調整するために行う活動
Quality forwardでテスト管理ツールの乗り換え時に必要なことを考えてみた①

## はじめに
この記事はQiita Advent Calendar 2024に投稿したものです。

## テスト管理ツールを乗り換える難しさ
- 品質保証業務を行う中で、テストの作成と管理は欠かせません。規模の小さなサービスやアプリケーションでは、Excelなどの表計算ツールで対応できることがあります。しかし、大規模なサービスでは管理が困難になるため、専用のテスト管理ツールを使用することが一般的です
- テスト管理ツールはさまざまな会社から提供されており、どのツールを選ぶべきか迷うことが多いでしょう。また、一度導入したツールは継続して使用し続けることが一般的で、ツールの乗り換えにはハードルがあるという印象を持たれていることが多いです
- 本記事では、サンプルやテンプレートの重要性について考察します
※この記事では「Quality Forward（以下：QF）」の無料版を利用し、個人的な考えをまとめています

## ツール乗り換え時に重要なこと
### ①初期学習コストが低いこと
- ツールにサンプルやテンプレートが充実していると、初期学習の負担を軽減できます。ツール内で使い方が説明されていることや、テスト用のサンプルデータが提供されていると、導入時のハードルが下がります
- QFには「SNSアプリのテスト」を想定したサンプルが用意されており、テスト計画からテスト完了までの一連の流れを学べるようになっています。このサンプルにより、初めて利用する人でもスムーズにテスト管理を始められるよう配慮されています
- サンプルの種類も分かりやすく整理されており、次のように分類されています
```
テストケースのサンプル→「テストスイート」
テスト実行のサンプル→「テストフェーズ」
テストレポートのサンプル→「レポート」
```
### ②テスト設計をスムーズに進められること
- サンプルやテンプレートの存在は、テスト設計を効率的に進めるためにも重要です。ゼロから作業を始める必要がないため、導入後すぐに利用できるメリットがあります
- QFでは、提供されたサンプルをそのまま活用したり、編集して利用することが可能です。例えば、「テストスイート」をコピーして類似のテンプレートを増やす仕組みや、事前に入力されたコメントを参考に運用イメージを掴むことができます。これにより、効率的にテスト設計を進められます
### ③チーム間での標準化を容易にできること
- サンプルやテンプレートを活用することで、チーム内の作業や運用ルールを標準化しやすくなります。これにより、チームメンバー全員が同じ基準で作業を進めることができます
- ツールをチームで運用する際には、独自ルールやドキュメントが増えがちです。しかし、QFのサンプルを活用することで、これらを簡略化しながら効率的に運用ルールの標準化を進めることができます
- QFでは「テストフェーズ」に複数の「テストスイート」が含まれ、その中に「テストサイクル」が階層化されています。このような構成や用語は文章だけでは理解しにくいですが、QFではサンプルを実際に触れることで直感的に理解できるようになっています

## おわりに
- サンプルやテンプレートからも、テスト管理ツールを提供する企業の工夫や配慮が伝わってきます
- 今後もテスト管理ツールの調査を続け、学びを深めつつ情報を発信していきたいと思います
【Three.js】テクスチャを反映する

## はじめに

みなさんは、Three.jsで3Dオブジェクトにテクスチャを反映させたいと思ったことはありますか？
この記事では、Three.jsを使った、テクスチャを反映させる方法を紹介しようと思います！

## テクスチャを反映する

### ① テクスチャをロードする
`TextureLoader()` は、画像を読み込むためのクラスです。
`TextureLoader()`を使って、画像を読み込みます！

```js
const textureLoader = new THREE.TextureLoader()
const texture = textureLoader.load('/textures/image.png')
```

https://threejs.org/docs/#api/en/loaders/TextureLoader

### ② カラースペースを定義する
読み込む画像がsRGBカラースペースを使っているので、画像がちゃんと読み込まれるようにsRGBカラースペースを定義します。

```js
const textureLoader = new THREE.TextureLoader()
const texture = textureLoader.load('/textures/image.png')

texture.colorSpace = THREE.SRGBColorSpace
```

### ③ テクスチャを反映する
テクスチャを反映させます。

```js
const textureLoader = new THREE.TextureLoader()
const texture = textureLoader.load('/textures/image.png')
texture.colorSpace = THREE.SRGBColorSpace

const geometry = new THREE.BoxGeometry(1, 1, 1) // オブジェクトを定義
const material = new THREE.MeshBasicMaterial({ map: texture }) // テクスチャを定義
const mesh = new THREE.Mesh(geometry, material) // メッシュベースのオブジェクトにする
scene.add(mesh) // シーンにメッシュを追加
```

### ④ 完成系
![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390720/32cb77a1-9dc6-a8df-1a93-188e742f8d52.png)


## テクスチャを調整する

### 分割する

```js
const texture = textureLoader.load('/textures/image.png')
texture.colorSpace = THREE.SRGBColorSpace
texture.repeat.x = 2
texture.repeat.y = 3
```

このようにすることで、
x軸に1 / 2個分のサイズに、y軸に1 / 3個分のサイズになり、
足りない部分は、端のピクセルが引き伸ばされます。

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390720/68de3588-16b0-87d0-834a-0b0733f387ff.png)

### リピートする

```js
texture.wrapS = THREE.RepeatWrapping
texture.wrapT = THREE.RepeatWrapping
```

### リピートの方向性を変える

```js
texture.wrapS = THREE.MirroredRepeatWrapping
texture.wrapT = THREE.MirroredRepeatWrapping
```

### オフセットをつける

```js
texture.offset.x = 0.5
texture.offset.y = 0.5
```

### 回転させる

```js
colorTexture.rotation = Math.PI * 0.25
colorTexture.center.x = 0.5
colorTexture.center.y = 0.5
```

## まとめ
この記事では、Three.jsでテクスチャを反映させる方法を紹介しました。

---

最後まで読んでくださってありがとうございます！

普段はデザインやフロントエンドを中心にQiitaで記事を投稿しているので、ぜひQiitaのフォローとX(Twitter)のフォローをお願いします。

https://twitter.com/degudegu2510
FitbitのPythonライブラリを作ったよ1

# はじめに
~~今までFit BitアプリからExcelに手入力したりしてデータをまとめていましたが流石に面倒臭いのでWEBAPIを使ってデータを取得してみようと考えました。先人がまとめてくれた記事などがありますが、公式ドキュメントは英語のみであったりFitBitがGoogleと統合されたりなど色々な理由から少し分かりずらくなってしまったので学習しつつ本記事を書いています。~~
Pythonのfitbitライブラリが軒並み最終更新日が何年も前になってしまっており、使えない機能が結構あったので結局自分でライブラリを作ってしまいました。このページは準備編ということで残しておきます。

# 準備
## 実行環境
|ハードウェア|OS|Python|
|----------|--|------|
|RaspberryPi4|Linux raspberrypi 6.6.62+rpt-rpi-v8 #1 SMP PREEMPT Debian 1:6.6.62-1+rpt1 (2024-11-25) aarch64 GNU/Linux|Python 3.11.2|

## アプリケーションの作成
1. デベロッパーページにアクセスする。（参考URL参照）
※FitBitアカウントを持っていない人は先にFitBitアカウントを作成しておきましょう
1. アプリケーションの作成
デベロッパーページの「REGISTER AN APP」から必要情報を入力して作成。自分のデータを取得したいだけなら以下のような感じでOKです。

|Application Name|適当な名前を入力|
|----------------|-------------|
|Description|適当な説明文を入力|
|Application Website URL|http://localhost|
|Organization|none|
|Organization Website URL|http://localhost|
|Terms of Service URL|http://localhost|
|Privacy Policy URL|http://localhost|
|OAuth 2.0 Application Type|Personal|
|Redirect URL|http://localhost:8000|
|Default Access Type|Read Only|

## アクセストークンの取得
1. Fitbit OAuth 2.0 Tutorialページにアクセスする
デベロッパーページの「MANAGE MY APPS」タブで、アプリケーションの作成で作成したアプリケーションをクリックし、OAuth 2.0 Tutorialのリンクをクリックする。
1. App Settingsに以下を入力する
    1. Client ID
        - 作成したアプリケーションのOAuth 2.0 Client ID
    1. Application Type
        - Clientを選択
1. Getting an Access Tokenで以下を入力する
    1. Step 1: Generate PKCE and State Values
        - PKCE Code VerifieのGENERATEをクリックする
        - StateのGENERATEをクリックする
1. Step 2: Display Authorization Page
    1. Authorization URLのURLをクリックする
        - アクセス権の画面で全て許可を選択し許可をクリックする
        - ブラウザによるが「localhost 接続が拒否されました。」が表示されるが、次のステップで使用するためそのままにしておく
1. Step 3: Handle the Redirect
    1. Authorization Codeに「localhost 接続が拒否されました。」のページのURLのhttp://localhost:8000/?code=<ここ>&state=〜　code=の部分の値を入力する
    1. Stateに「localhost 接続が拒否されました。」のページのURLのhttp://localhost:8000/?code=〜&state=<ここ>　state=の部分の値を入力する
1. Step 4: Get Tokens
    1. SUBMIT REQUESTをクリックする
        - Responseにエラーが表示されずにトークンが表示されていること
        - Responseの内容をToken.json（ファイル名はなんでも良いが）という名前でテキストファイルに保存する
1. Access User Data
    1. SUBMIT REQUESTをクリックする
        - Responseにエラーが表示されずにあなたのプロフィールデータが表示されていること

## Configファイルの作成
次の内容でConfig.jsonというファイルを作成する
```json:Config.json
{
    "CLIENT_ID":"<作成したアプリケーションのOAuth 2.0 Client ID>",
    "CLIENT_SECRET":"<作成したアプリケーションのClient Secret>"
}
```

# 参考URL
- デベロッパーページ　https://dev.fitbit.com/apps
- リファレンス　https://dev.fitbit.com/build/reference/web-api/
インターネットエクスプローラをwindows10/11で使えるようにしてみた

# windows10/11でインターネットエクスプローラーが使える！？
実は、windows10/11の中にインターネットエクスプローラーがあるのですが開くとedgeが開くようになっています。ですが、https://www.youtube.com/watch?v=Q3JIzKtuJec を参考にして作るとなんと開けるようになります。しかし、これだとインターネットエクスプローラー感が出ないので、再現できるものを作ってみました。
# 本題
まず[このリンク](https://simasimanekosan.f5.si/IeLauncher/)を押したら、こうなる
![Screenshot 2024-12-22 18.54.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3569677/9f8b8c3c-f5e9-7a48-7df4-2e99b89a96f2.png)
ので、ノーマル(msi)版か、レガシー版(exe)版を選んでダウンロードします。(推奨はmsi版です。)
もし、インストールするときに「デスクトップ上にアイコンを作成する」があったら**必ず**押してください。
そしてインストールが終わるとInternetExplorerがあるので押すと...
![Internet Explorer 2024_12_22 19_02_50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3569677/d04975ea-c335-c326-d708-0b5ecf67957e.png)
このようにできるはずです。
# 終わり
実は私、インストーラーに何時間も時間使ってましたｗ
今思えば簡単な作業でしたが...
2024年の振り返り

この記事は クラウドワークス グループ Advent Calendar 2024 シリーズ1の22日目の記事です。

株式会社クラウドワークスの@keshiwoです。

エンジニアとして「クラウドログ」という工数管理システムの開発を行なっています。

今回は私の2024年を振り返りつつ、「クラウドログのエンジニアの働き方」や「どのような課題に取り組んでいるか」が少しでも伝われば幸いです。

# 蒼天社グループインによる開発組織拡大とクラウドログのさらなる進化

クラウドログにとって今年一番の注目すべき出来事はこちらでしょう。
蒼天社グループインによってクラウドログから新たにPC管理機能を提供することとなりました！

(グループインに伴うチームビルディングの話は[こちら](https://qiita.com/tera4ma/items/e0c79af43dac2f6c5299)に記載がありますので是非ご覧ください。)

この統合は、単なるブランドの変更にとどまらず、工数管理とPC資産管理を連携させることでより包括的なサービスへと進化した点に大きな特徴があります。

### 工数提案機能のリリース

PC管理機能の提供開始に伴い、工数管理とPC管理のサービス連携機能の第一弾として「工数提案機能」をリリースしました！

「工数提案機能」はその名の通り工数管理アプリ側でユーザーの工数入力時に「どのような作業を何時間していたか」を自動で提案し工数入力を補助する機能です。

この機能はPC管理機能により取得したPC操作ログデータを基に提案を行なっており、まさに蒼天社のグループインがあったからこそ提供できた機能です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1872140/44eed691-c2b0-db3b-4318-6d22a21be35a.png)


今回の開発では、リリーススピードを優先するため、データ連携部分にチームとして初めてAWS DMSを採用しました。新たなサービスを活用することで、いくつか新しい知見が得られ、開発チームとして大きく成長できたプロジェクトでもあります。

# 工数分析レポート機能の性能改善

クラウドログ工数管理の目玉機能である「工数レポート」の性能改善も行いました。
こちらの機能は入力された工数の実績をプロジェクトや従業員、取引先といった様々な軸で分析できる機能です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1872140/2512b583-3a92-4115-d192-73a11a3f0bf5.png)

レポートを表示するにあたり入力実績と指定された分析軸を元にリアルタイムで集計を行なっていたためデータ量が多いお客様において「表示に時間が掛かってしまう」という性能問題がありました。

この問題を解決すべくリアルタイム集計から事前集計したものを表示するように変更しました。

夜間バッチで対象期間内の工数データを全て集計してデータを作成し工数レポート表示には集計済みのデータを利用するように改修を入れることで対応しました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1872140/45c5f396-cec9-9f7a-eb0d-8a1f42a2c173.png)


性能改善にあたり、事前集計するだけではなくパーティショニングを利用して会社IDと集計時間をパーティションキーとすることでスキャン範囲を最適化するように工夫しました。

結果的に特定の検索軸において約144倍の速度改善を行うことができました。

ただし、検索軸の組み合わせによっては性能改善を実感できなかったものも存在しているため
引き続き、お客様に快適に利用していただけるよう改善に努めていきます！

# 部署横断での勉強会開催

クラウドログ開発部隊内で開催している勉強会「LogStudy」を部署横断で開催しました！
(LogStudyについては[こちら](https://engineer.crowdworks.jp/entry/2023/10/24/174812)の記事で詳しく紹介させていただいております)

普段は事業部内に閉じて開催しているのですが、LogStudy運営委員会内で「勉強会のテーマによっては事業部を跨いで開催できるはずだ」という話になり、今年実現することができました！

内容としては「DBテーブル設計 輪読会」と題し、アプリ開発の多くのケースで利用されるRDBの設計に関する書籍の輪読会を開催しました！(全4回)

参加人数は22名となり普段の3倍くらいの規模で実施することができました。

ただ本の内容に沿って議論を行うだけでなく、「うちではこんな感じでやってるよー」といった具合に事業部間での技術事情共有などを行うことができとても有意義な時間となりました！

今年は事業部を超えた開催でしたが来年はさらに拡大してCWグループ間での勉強会開催ができたらと目論んでいます！

# 負債解消チームを拡大

昨年クラウドログのバックエンド部分の負債解消や改善を行うチームを発足しましたが
今年はそこにメンバーを新たに加えてバックエンド部分だけではなくフロントエンド部分に関しても対応を行なっていくべくチームを拡大しました。

今までフロントエンドの改善については有志で行われており継続的な改善のフローを回すことができていませんでした。(フロントエンド人材の不足と改善すべき課題の優先度により)

そのためぼんやりと課題感はもっているが誰がいつ解決していくかが明らかになっておらず
タスクが溜まり続けている状況でした。
そこにメスを入れるべく今までバックエンドを得意としていたメンバーにもフロントエンドのタスクに挑戦してもらうように変更してチームの役割を拡大しました。

直近ではE2Eテスト導入によるプロダクトの品質改善に取り組んでいます！


# 最後に

2024年は今まで以上に困難な課題に挑戦し開発チームとして大きく成長できた年だったと感じています。

2025年もチーム一丸となってクラウドログを多くのお客様に届けられるように尽力していきたいと思います！

頑張るぞ！！
SlackからアップロードしたPDFをChromaDBに登録したい

こちらの記事の続きです！

https://qiita.com/does_not_exist/items/aa20a49bb930ee2dfe97

# 結果

![スクリーンショット 2024-12-22 18.47.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2889192/af83bb02-31d1-3a9f-2cbe-2c47aeae270e.png)


# やりたいこと
- Slackからファイルアップロード（今回はPDF）
- PDFの中身を取得
- 中身をChromaDBに登録

# コード

```python
import os
import requests
from slack_bolt import App
from slack_sdk import WebClient
from slack_sdk.errors import SlackApiError
import PyPDF2
from io import BytesIO
from docx import Document
from dotenv import load_dotenv

load_dotenv()

SLACK_BOT_TOKEN = os.getenv('SLACK_BOT_TOKEN')
client = WebClient(token=SLACK_BOT_TOKEN)

app = App(token=SLACK_BOT_TOKEN)

@app.event("file_shared")
def handle_file_shared(event, say):
    try:
        file_id = event['file_id']
        response = client.files_info(file=file_id)
        file_info = response['file']
        file_url = file_info['url_private']

        file_content = download_file_from_slack(file_url)
        if not file_content:
            say("ファイルのダウンロードに失敗しました。")
            return

        file_type = file_info['mimetype']
        text_content = ""

        if 'pdf' in file_type:
            text_content = extract_text_from_pdf(file_content)
        else:
            say(f"サポートされていないファイル形式です: {file_type}")
            return

        print(f"ファイル内容:\n{text_content}")
        say(f"ファイルの内容が抽出されました。内容を確認してください。")

    except SlackApiError as e:
        print(f"Slack API Error: {e.response['error']}")

def download_file_from_slack(file_url):
    headers = {'Authorization': f'Bearer {SLACK_BOT_TOKEN}'}
    response = requests.get(file_url, headers=headers)
    return response.content if response.status_code == 200 else None

def extract_text_from_pdf(file_content):
    try:
        pdf_reader = PyPDF2.PdfReader(BytesIO(file_content))
        text = ""
        for page in pdf_reader.pages:
            text += page.extract_text()
        return text
    except Exception as e:
        print(f"Error extracting PDF text: {e}")
        return ""

@app.event("message")
def handle_message_events(event, logger):
    subtype = event.get('subtype')

    if subtype == 'file_share':
        logger.info("ファイル共有メッセージはスキップされました。")
        return
    else:
        user_message = event.get('text', '')
        logger.info(f"受信したメッセージ: {user_message}")

if __name__ == "__main__":
    from slack_bolt.adapter.socket_mode import SocketModeHandler
    SocketModeHandler(app, os.getenv('SLACK_APP_TOKEN')).start()

```

# なんちゃって解説

`@app.event("file_shared")`
Slackにファイルをアップロードしたときのイベント

`response = client.files_info(file=file_id)`
Slack APIのfiles_infoメソッドでファイルの詳細情報を取得

`requests.get`

ファイルのプライベートURLを取得し、ファイルの内容をダウンロード
```python
def download_file_from_slack(file_url):
    headers = {'Authorization': f'Bearer {SLACK_BOT_TOKEN}'}
    response = requests.get(file_url, headers=headers)
    return response.content if response.status_code == 200 else None
```

`PyPDF2.PdfReader`
PDFを読み込み、各ページからテキストを抽出

# おわりに
次は画像のテキスト化や、登録した内容に関連する回答が返ってくるか検証したいです。
ABC385Dを解いた【SortedSet,二分探索】


筆者はレート800前後の茶～緑コーダ

ABC385当日にACできなかったD問題を解いていく

ABCの問題を解いていく
    
https://atcoder.jp/contests/abc385/tasks/abc385_d

# 実装コード

SortedSetで家の位置を管理したあとに、順番に巡回する
通過した家はSetから取り除く必要があるようだ

```python:main.py
from bisect import bisect_left, bisect_right
from collections import defaultdict

from sortedcontainers import SortedSet

import sys
def rI(): return int(sys.stdin.readline().rstrip())
def rLI(): return list(map(int,sys.stdin.readline().rstrip().split()))
def rI1(): return (int(sys.stdin.readline().rstrip())-1)
def rLI1(): return list(map(lambda a:int(a)-1,sys.stdin.readline().rstrip().split()))
def rS(): return sys.stdin.readline().rstrip()
def rLS(): return list(sys.stdin.readline().rstrip().split())
def err(*args): print(*args, file=sys.stderr)

dy = [-1, 0, 1, 0]
dx = [0, 1, 0, -1]
move = {c:(x,y)for c,y,x in zip("DRUL",dy,dx)}

dhx = defaultdict(SortedSet)
dhy = defaultdict(SortedSet)

visited = set()

def main():
    N, M, X, Y = rLI()
    for _ in range(N):
        x, y = rLI()
        dhx[x].add(y)
        dhy[y].add(x)
    
    cx, cy = X, Y

    for _ in range(M):
        d, c = rLS()
        c = int(c)
        nx, ny = move[d]
        mx, my = nx * c, ny * c

        if nx == 0:
            hs = dhx[cx]
            l, r = sorted([cy,cy+my])
            li = bisect_left(hs, l)
            ri = bisect_right(hs, r)-1
            if li <= ri:   
                visited.update((cx, hy) for hy in hs[li:ri+1])
                for hy in hs[li:ri+1]:
                    dhx[cx].remove(hy)
                    dhy[hy].remove(cx)
        else:
            hs = dhy[cy]
            l, r = sorted([cx,cx+mx])
            li = bisect_left(hs, l)
            ri = bisect_right(hs, r)-1 
            if li <= ri:   
                visited.update((hx, cy) for hx in hs[li:ri+1])
                for hx in hs[li:ri+1]:
                    dhx[hx].remove(cy)
                    dhy[cy].remove(hx)

        # err(d,c,l,r,hs[li:ri+1])
        cx+=mx
        cy+=my
    
    print(cx, cy, len(visited))

    
if __name__ == '__main__':
    main()

```

# まとめ

通過した家をSetから取り除く発想がなくて撃沈。

そして何よりも恥ずるべきなのは単純な誤字に全く気づかないところ
```py
            l, r = sorted([cx,cx+my]) # 誤
            l, r = sorted([cx,cx+mx]) # 正
```

こういう誤字があるのでコピペはしたくないのに
コピペしないようにすると
余計処理を考えるのに苦労するのが非常に困る。
Love2DのHTML5出力

# Love2DのHTML5出力

環境はManjaroLinuxです。
Love(11.5)、nodeを使います。

## Love2Dのゲームの準備

1. 公式サイトからzipを持ってきて展開する。
1. そのフォルダ内にmain.luaというファイルを作り`love.update`、`love.draw`を書く。
1. ターミナルを開き、そのフォルダで`love .`とするとゲームを実行できる。

lume.lua(高階関数やユーティリティ関数)、maid64(Canvasのサイズを固定にする為使う)、tween.lua(アニメーション。補間)、bump.lua(AABB当たり判定)などのライブラリを使う。

## `PROJECTNAME.love`ファイルを作る

ソースコードとアセットをzipファイルに固めて拡張子を`.love`にする
このファイルを配るだけで、『各プラットフォームにlove2dをインストールしてもらえば』ゲームを動かせる
自分はソースコードからアセットのファイル名を集めるようにした。

```sh
zip -q -9 -u PROJECTNAME.love main.lua ...
```

## HTML5出力する

npmでlove.jsをインストールしておく
下のコマンドでPROJECTNAMEフォルダが作られ、そこにいくつかのファイルができる。

1. `npx love.js #{PROJECTNAME}.love html\_#{PROJECTNAME} -c -t \"#{PROJECTNAME..' -v '..VERSION}\"`
1. 適当なweb サーバーを起動 `python -m http.server 8000`
1. ブラウザで `localhost:8000` を開く

さらに
`cd #{PROJECTNAME} && node ../globalizeFS.js` すると、love.filesystemが使える。(=ゲームでsave loadができる)

出力されたフォルダごとgithubにアップロードするだけで、ゲームを公開することができる

[2048](https://muu2007.github.io/game2048/)

[smario](https://muu2007.github.io/smario/)

## 各プラットフォームでの差異

### Windows

- love.exeにcat でPROJECTNAME.loveをくっつけると実行ファイルができる！
  dllをまとめることはできないようだ

### Android

- quit イベントが来ない？
- 画面を消してもゲームは止まらない(バッテリー消費し続ける)?

### HTML5

- jit ではない
- getOS は'Web'と設定される
- DLL/soファイルがloveファイル内にあっても良いが、呼び出さないように場合分けしておく
- 文字列でユニコードリテラルが認識されない
- 座標がずれる(maid64を改造して対応した)
【Servicenow】数字をソートしたい！【GlideRecord】

ServiceNowで「数字」をGlideRecordでソート取得したいときのメモ

Servicenowで数値型（Integer）で定義すべきカラムを文字列型（String）で作成すると
GlideRecordでは文字列型カラムの数字は期待通りにソートして取得することができません。

例えばこのようなテーブル定義をして、両カラムに１，５，１０，２０を登録します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/644024/4f8e26ba-ac0d-f16a-8799-bb0b0422266f.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/644024/b921b702-9cf1-0137-783b-074b1a24df96.png)

両カラムをそれぞれ昇順ソートでGlideRecordしてみても
Numberは期待通りに取得できていますが、StrNumberはできていません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/644024/ed9286e1-b284-8f80-317d-394f4a55c238.png)

<details open><summary>サンプルコード①</summary>

```sample.js
/*
 * 検証用のScript①
 */
var grSortMst = new GlideRecord('sample_strnumsort');

gs.info('数値型カラムのソート');
grSortMst.orderBy('number');
grSortMst.query();
while(grSortMst.next()){
	gs.info(grSortMst.number);
}

gs.info('-------------------------------');
gs.info('文字列型カラムのソート');
grSortMst.initialize();
grSortMst.orderBy('strnumber');
grSortMst.query();
while(grSortMst.next()){
	gs.info(grSortMst.strnumber);
}
```

</details>

この問題を解決するためには普通はカラムを再定義すればよいと思いますが
そういうことができないときのために[GlideDBFunctionBuilder.length](https://www.servicenow.com/docs/ja-JP/bundle/xanadu-api-reference/page/app-store/dev_portal/API_reference/GlideDBFunctionBuilderScoped/concept/GlideDBFunctionBuilderScopedAPI.html#title_GlideDBFBScoped-length)を使用してみます。

使用した結果は以下の通りとなります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/644024/a6eaebd9-b3ff-302e-b6f8-fb437424e3ca.png)

<details open><summary>サンプルコード②</summary>

```sample2.js
/*
 * 検証用のScript②
 */

// GlideDBFunctionBuilderをインスタンス化
var fbSort = new GlideDBFunctionBuilder();
var fbLen = fbSort.length();
fbLen = fbSort.field('strnumber'); // 文字列カラムの文字数を取得する定義
fbLen = fbSort.build();

var grSortMst = new GlideRecord('sample_strnumsort');

gs.info('数値型カラムのソート');
grSortMst.orderBy('number');
grSortMst.query();
while(grSortMst.next()){
	gs.info(grSortMst.number);
}

gs.info('-------------------------------');
gs.info('文字列型カラムのソート');
grSortMst.initialize();
grSortMst.addFunction(fbLen);
grSortMst.orderBy(fbLen); // 第１ソートキーに文字列カラムの文字数を定義
grSortMst.orderBy('strnumber');
grSortMst.query();
while(grSortMst.next()){
	gs.info(grSortMst.strnumber);
}
```

</details>

GlideDBFunctionBuilder.lengthを使用することで、対象カラムの文字数を取得できます。
GlideRecord.orderByに上記インスタンスを渡すことで
文字数の範囲で昇順ソートができるため数値と同じようなソートが可能になりました。
Raspberry Pi Pico - Python SDK のドキュメントを読む③

# 第３章 RPシリーズポートについて

今回は第３章の途中まで(たぶん PIO の前あたりまで)。

## 3.1 Timer

いきなり難しいところからきたなぁという感じ。Lチカを Timer 機能を使って実現する方法について記載している。

Timer は主に特定の処理を定期的に呼び出すときに使う。要するにタイマー割り込み。CircuitPython が嫌う割り込みのAPIですな。

```python
from machine import Pin, Timer

led = Pin("LED", Pin.OUT)
tim = Timer()
def tick(timer):
    global led
    led.toggle()

tim.init(freq=2.5, mode=Timer.PERIODIC, callback=tick)
```

`tim.init()` により、2.5Hz でtick()関数を繰り返し呼び出すようになる。この呼び出しはタイマー割込みで行われるので、並行して別の処理を動かすことができる。

この程度の処理では問題ないが、MicroPython の割り込み処理には注意しなければならないことがある。[こちら](https://micropython-docs-ja.readthedocs.io/ja/latest/reference/isr_rules.html#isr-rules)を参照。本ドキュメントには、そのへんの記載がないので注意である。

## 3.2 UART

UART1からUART0にバイト列を送り込む簡単な例が示されている。

```python
from machine import UART, Pin
import time

uart1 = UART(1, baudrate=9600, tx=Pin(8), rx=Pin(9))

uart0 = UART(0, baudrate=9600, tx=Pin(0), rx=Pin(1))

txData = b'hello world\n\r'
uart1.write(txData)
time.sleep(0.1)
rxData = bytes()
while uart0.any() > 0:
    rxData += uart0.read(1)

print(rxData.decode('utf-8'))
```

## 3.3 ADC

ADコンバータの使い方について記述している。

ADCクラスのコンストラクター第１引数には、GPIO番号かチャンネル番号を指定できるとあるが、どう区別しているのであろうかと思ったら、単純に 0〜4 をチャンネル番号と見ているらしい。GPIOからADCに使えるのはGP26〜GP29なので、同じ整数値で与えても何を示しているのか判別できる。ただ、API設計としてはあまりよろしくないように思える。

例としては、特にセンサーを外付けしなくても試せる内蔵の温度センサー（チャンネル４）の読み出し方が載っている。

## 3.4 割込み

一般的な割込みの使い方が載っている。

ここでも指定するコールバックについての注意書きがない。[こちら](https://micropython-docs-ja.readthedocs.io/ja/latest/reference/isr_rules.html#isr-rules)を参照。

## 3.5 マルチコアのサポート

Pico 用 MicroPython のスクリプトは通常 core0 で動いている。core1 を使うために、なぜかマルチスレッドの API (`_thread`)を使うことになっている。

このため、Picoシリーズ用の MicroPython では、core1 の１スレッドでしか _thread を動かせない。GIL がないという利点もあるにはあるのだが。

## 3.6 I2C

ハードウェア I2C バスの使用例が記載されている。

MicroPython には、この他にソフトウェア I2C バスの API があるが、本ドキュメントには記載なし。ソフトウェア I2C については[こちら](https://micropython-docs-ja.readthedocs.io/ja/latest/library/machine.I2C.html#machine-softi2c)を参照。

## 3.7 SPI

ハードウェア SPI バスの使用例が記載されている。

MicroPython には、この他にソフトウェア SPI バスの API があるが、本ドキュメントには記載なし。ソフトウェア SPI については[こちら](https://micropython-docs-ja.readthedocs.io/ja/latest/library/machine.SPI.html#machine-softspi)を参照。

## 3.8 PWM

Pico の内蔵LEDをPWMを使ってゆっくり明滅しているように見せるデモを載せている。GPIOに直接繋がっていない Pico W ではさずがにこのデモは動かせないので、注意書きがある。Pico W では外部の LED を繋いで試してくれと。

ここまで読んできて、SDK のドキュメントという割には API についてあまり説明されていない。APIは本家のドキュメントを読めということなのか。
Amazon Bedrock Prompt Caching とは

:::note info
2024/12 現在 プレビュー
:::


# 内容

AWS re:Invent 2024 で発表があった Amazon Bedrock Prompt Caching をシンプルに纏めます。

https://aws.amazon.com/jp/blogs/news/reduce-costs-and-latency-with-amazon-bedrock-intelligent-prompt-routing-and-prompt-caching-preview/

https://aws.amazon.com/jp/about-aws/whats-new/2024/12/amazon-bedrock-preview-prompt-caching/

頻繁に使用されるコンテキストをプロンプトにキャッシュできる。
キャッシュされたコンテキストは、アクセスするたびに最大 5 分間使用可能。
コストを最大 90% 削減し、レイテンシーを最大 85% 削減。


# 利用可能なモデル

- Claude 3 Haiku, Claude 3.5 Sonnet v2
- Nova Micro/Lite/Pro(バージニアのみ)


# 対応リージョン

- バージニア
- オレゴン


# 実装方法

`cachePoint` ブロックを追加してあげれば良いようです。

https://docs.aws.amazon.com/bedrock/latest/userguide/prompt-caching.html


# SDK での実装

実装は、AWS ブログのものを利用させていただいてます。

```python
import json
import boto3

MODEL_ID = "us.anthropic.claude-3-5-sonnet-20241022-v2:0"

AWS_REGION = "us-west-2"

bedrock_runtime = boto3.client(
    "bedrock-runtime",
    region_name=AWS_REGION,
)

DOCS = [
    "bedrock-or-sagemaker.pdf",
    "generative-ai-on-aws-how-to-choose.pdf",
    "machine-learning-on-aws-how-to-choose.pdf",
]

messages = []


def converse(new_message, docs=[], cache=False):

    if len(messages) == 0 or messages[-1]["role"] != "user":
        messages.append({"role": "user", "content": []})

    for doc in docs:
        print(f"Adding document: {doc}")
        name, format = doc.rsplit('.', maxsplit=1)
        with open(doc, "rb") as f:
            bytes = f.read()
        messages[-1]["content"].append({
            "document": {
                "name": name,
                "format": format,
                "source": {"bytes": bytes},
            }
        })

    messages[-1]["content"].append({"text": new_message})

    if cache:
        messages[-1]["content"].append({"cachePoint": {"type": "default"}})

    response = bedrock_runtime.converse(
        modelId=MODEL_ID,
        messages=messages,
    )

    output_message = response["output"]["message"]
    response_text = output_message["content"][0]["text"]

    print("Response text:")
    print(response_text)

    print("Usage:")
    print(json.dumps(response["usage"], indent=2))

    messages.append(output_message)


converse("AWS Trainium と AWS Inferentia を 20 文字以内で比較する。", docs=DOCS, cache=True)
converse("Amazon Textract と Amazon Transcribe を 20 字以内で比較する。")
converse("Amazon Q BusinessとAmazon Q Developerを20字以内で比較する。")
```

```
botocore.exceptions.ParamValidationError: Parameter validation failed:
Unknown parameter in messages[0].content[4]: "cachePoint", must be one of: text, image, document, video, toolUse, toolResult, guardContent
```
　
やはり、プレビュー中で[リクエスト](https://pages.awscloud.com/promptcaching-Preview.html)しないとダメそうですね。

https://github.com/boto/boto3/issues/4376

GA されたまたやってみて更新したいと思います。
mindの研究 その94

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

# 練習問題
chromeを起動せよ。

# 環境
windows10

# サンプルコード

```

メインとは
　「"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" "qiita.com"」を　プログラム実行
。




```

以上。
Error: Cannot perform an interactive login from a non TTY device

## エラー内容
これまではAWS CLIを使用して正常にサインインできていたのに、ある日突然以下のエラーが発生しました。
```
Error: Cannot perform an interactive login from a non TTY device
```
このエラーにより、CLIを通じた操作が一切できなくなり、開発作業が中断される事態に陥りました。コンソール画面を確認したところ、以下のように、自分のアカウントのアクセス許可が制限されていました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2984024/262e0a92-21ba-008c-7abc-92ab33368b85.png)

## 原因
調査した結果、開発グループのメンバーが私のアカウントを用いてサインインしていたことが原因と判明しました。
[公式サイト](https://docs.aws.amazon.com/ja_jp/aws-managed-policy/latest/reference/AWSCompromisedKeyQuarantineV3.html)によると、AWSでは複数の端末や不審なIPアドレスからのアクセスが検出されると、不正アクセスとみなされ、制限をかける特別なロール（AWSCompromisedKeyQuarantineV3）が自動的に割り当てられる仕組みがあるそうです。

![スクリーンショット 2024-12-22 18.08.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2984024/d79bd976-5766-a996-f2c0-bd2cc7c9490f.png)

## 解決
AWSコンソールで該当するロールを削除したところ、正常にサインインできるようになりました。
## 最後に
今回の問題は、アカウント情報がチームの共有チャンネル（Discord）で共有されていたことが根本的な原因でした。その結果、不正アクセスが容易に実現されてしまいました。今回の経験を活かし、セキュリティ対策の重要性を改めて学びました。今後はアカウント情報は厳重に管理しようと思います。
Stack Overflow調査から見る、Webアプリ開発のバックエンド言語ランキングと比較

# はじめに

エンジニアのみなさま、日々の学習本当にお疲れ様です！
また本記事まで足を運んでいただき本当に感謝です。

最近案件を増やすために営業活動してます。
顧客から質問が飛んできた時にできる限り回答できるように、いろんな情報にアンテナ張ってる最中です。今回はここ数年でどのような言語が使われているかが気になったので調べてみました。加えて、今回ランキングされているWebアプリ開発のバックエンド言語に絞って比較してみたので最後まで読んでもらえると幸いです。

# 最も使われている言語ってなに？

以下のグラフの通りとなります。
代表的なITエンジニアのコミュニティサイトの1つである「Stack Overflow」などを運営するStack Overflowが調査した、3年平均で約7万5000人のITエンジニアが回答したアンケート結果の一部になります。

![スクリーンショット 2024-12-22 16.34.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3744730/ee31b60e-475d-cec5-2694-aefc8b383542.png)

プログラミング言語・スクリプティング言語、マークアップ言語とがっちゃんこしてます笑
直近3年の1位が全て **JavaScript！** めちゃ強いですね！ちなみに10年連続1位らしいです笑
そしてどのグラフにもRubyが入っていない！私がプログラミングスクールに通っていた時に学習した言語ですが、少し悲しい気持ちになりました...

# 各言語の比較

ランキングされていた **JavaScript（Node.js使う想定）、Python、Java、C#、PHP** に加えて、完全独断で申し訳ないですが **Ruby** も含めた6つの言語の比較をしていきたいと思います。

### スレッドモデル

シングルスレッドは **1つのスレッドで1つのプログラムを実行** します。
マルチスレッドは **複数のプログラムを並行して実行** します。

![スクリーンショット 2024-12-22 17.17.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3744730/3f6182e4-0380-e015-76d9-a353643725ff.png)

### 型システム

静的型付けは **「プログラムを実行する前に型付けを行う」** 言語です。
動的型付けは **「プログラム実行時に型付けを行う」** 言語です。

![スクリーンショット 2024-12-22 17.23.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3744730/ec20cb5c-1cee-f4db-31c4-4b181cd44a72.png)

### 言語処理系

インタプリタは **1行ずつマシン語に変換するのと同時に、その都度命令を処理・実行** します。
コンパイラは **すべての命令をまとめて一括でマシン語に変換を済ませてから、一気に処理・実行** します。

![スクリーンショット 2024-12-22 17.28.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3744730/669594df-bdd4-9581-b070-83a3d78d6f0d.png)

### 求人数・案件数

Javaが圧倒的ですね。

![スクリーンショット 2024-12-22 17.51.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3744730/03469632-fd6f-6fff-7cb1-535678a3b01c.png)

# さいごに

各言語それぞれ得手・不得手があると思いますが、それらを補完するためにライブラリやフレームワークがどんどん出ています。どのような経緯で出されたのかを深掘りすると、技術選定での説得力がUPするなと感じました。
Stack Overflowのアンケート結果記事を3年分貼りました。 **『最も使われているクラウド』** や **『最も使われているフレームワーク』** など、本記事ではご紹介できなかった興味深いランキングも掲載されているため、もし時間があれば合わせて読んでみてくださいね！

# 参考記事

https://www.publickey1.jp/blog/24/stack_overflow6itjavascriptpostgresql1stack_overflow_2024_developer_survey.html

https://www.publickey1.jp/blog/23/stack_overflow9itjavascriptmysqlpostgresql1stack_overflow_2023_developer_survey.html

https://www.publickey1.jp/blog/22/7itrustdbpostgresqlvscodeneovimstack_overflow_2022_developer_survey.html

https://plainprogram.com/processing-speed-of-program/

https://career.levtech.jp/guide/knowhow/article/918/?utm_source=chatgpt.com

# おまけ

弊社のご紹介もさせてください！

### 「日本で一番エンジニアが成長できる会社を創る」

https://prum.jp/

### エンジニアリングの募集

https://www.wantedly.com/projects/1808638

### PM・Webディレクションの募集

https://www.wantedly.com/projects/1355235

### セールス・事業開発の募集

https://www.wantedly.com/projects/1792065

### コーポレート系の募集

https://www.wantedly.com/projects/1752874

### コンサルティングの募集

https://www.wantedly.com/projects/1794481

弊社メンバーは日々学習した内容をアウトプットしております！
少しでもご興味を持たれた方は求人を見てみてください！
ご応募もお待ちしております！

### 最後までご覧いただき、ありがとうございました！
相対エントロピー絡み

PhysiKyu2024アドベントカレンダー23日目です．B3の金山が担当します．

私は今年度統計検定1級を受験しまして, 1次試験の統計数理には合格することができました. なので物理と統計に関わる記事として, 最近授業で受けた量子情報のテキストに相対エントロピーについて書かれていたので, そこから色々話を広げて書こうと思います.  

<!-- 各チャプター -->

# 相対エントロピーとは
みなさんは相対エントロピーについてご存知でしょうか. 相対エントロピーは別名がいくつかあり, ここでは次の2つを紹介しておきます.
①**相対エントロピー**(relative entropy)
②**カルバック・ライブラー情報量** (Kullback–Leibler divergence)

:::note info
ダイバージェンスとありますが, 物理学科に馴染みのあるベクトル解析のdivではないです.
:::

では, 相対エントロピー(カルバック・ライブラー情報量)の定義を書きます.
**相対エントロピー(カルバック・ライブラー情報量)の定義**
確率分布$f(x), g(x)$において、$f(x)$の$g(x)$に対する相対エントロピー(カルバック・ライブラー情報量)は
```math
KL(f(x),g(x))=E_F \left[\mathrm{log} \frac{f(X)}{g(X)}\right]
```
:::note info
期待値の添え字は, $f(x)$について期待値を取るという意味で,$f(x), g(x)$が離散分布だったらΣ, 連続だったら積分で期待値を取ります.
:::
この相対エントロピー(カルバック・ライブラー情報量)が意味していることは, 2つの確率分布がどれほど異なっているか, です.

相対エントロピー(カルバック・ライブラー情報量)は, 次の**ギブスの不等式**を満たします.
```math
KL(f(x),g(x))\ge0
```
等号成立しているとき, $f(x)=g(x)$, $f(x)$と$g(x)$の差異がないほど$0$に近いです.

$g(x)$が真の確率分布, $f(x)$が実験で得た確率分布や推定で得た確率分布だとして, 相対エントロピー(カルバック・ライブラー情報量)を計算すると, 2つの確率分布を評価できますね.

また, シャノン・エントロピーや相互情報量は, この相対エントロピー(カルバック・ライブラー情報量)の派生として理解できます. 

# 量子相対エントロピー
古典論の相対エントロピーは2つの確率分布がどれくらい異なっているかの尺度でした. では次に, 量子相対エントロピー(quantum relative entropy)の定義を書きます.

**量子相対エントロピーの定義**
2つの量子状態$\hat{\rho}, \hat{\sigma}$に対する量子相対エントロピーは
```math
D(\hat{\rho},\hat{\sigma})=\mathrm{Tr} \, \hat{\rho}\,[\mathrm{log}\, \hat{\rho}-\mathrm{log}\, \hat{\sigma}]
```

(以下, 区別するために, 古典論の相対エントロピーはカルバック・ライブラー情報量と書きます.)
量子相対エントロピーは, カルバック・ライブラー情報量のときと同様に考えると, 2つの量子状態がどれくらい異なっているかの尺度となりますね.

また,カルバック・ライブラー情報量のときと同様に, フォン・ノイマン・エントロピーや, 量子相互情報量は, 量子相対エントロピーの派生として理解できます. 

# 赤池情報量基準(AIC)
最後に数理統計学の話をします. 赤池情報量基準(以下, AICと書きます)はカルバック・ライブラー情報量に基づいて導出されます. 導出過程は書かず, 結果だけ書くと, 
```math
\mathrm{AIC}=-2\, \mathrm{log}L+2k
```
ただし, $L$は最大尤度(適合度のようなものと考えて大丈夫です), $k$は自由度です.

このAICは, 適切なモデルを選ぶモデル選択などで活躍します. 例えば, 実験で得られたデータをプロットし, それをある関数でフィッティングすることを考えましょう. 今回, 紙を投げる実験をし, 変数として紙の固さ, 投げる距離, 投げる手などを考えます. 各変数を固定していろいろなフィッティングを行い, それぞれのAICを計算します. AICが最小な関数がもっとも適切なモデルとなり, 次のデータの予測などができます.　

AICについて, AICの第1項はモデルの適合度を表しています. モデルの当てはまりがよいほど, 最大対数尤度は大きくなります. 第2項はデータの複雑さへのペナルティです. データの数が少なすぎると, モデルの予想は難しいですよね. 逆に, データの数が多くなると, ノイズが入ったりしてモデルが複雑になります. いわゆる過学習というやつです. 

# 終わりに
今回はカルバック・ライブラー情報量から色々関連付けて, 量子相対エントロピーと赤池情報量基準について意味をざっくり理解してもらえるように簡潔に紹介しました. 量子情報などに登場する色々なエントロピー, 情報量の関係を勉強する機会や, 数理統計学の勉強の機会になれば嬉しいです.

# 参考文献
- [現代数理統計学の基礎](https://www.kyoritsu-pub.co.jp/book/b10003681.html) (久保川 達也 著)
- [多変量解析入門](https://www.iwanami.co.jp/book/b265441.html) (小西 貞則 著)
- [量子情報科学入門](https://www.kyoritsu-pub.co.jp/book/b10080739.html)　(石坂 智 著・ 小川 朋宏 著・ 河内 亮周 著・ 木村 元 著・ 林 正人 著)
Docker環境でWordPress + Nginxを構築中に発生した「PHPではWordPressに必要なMySQL拡張を利用できない」エラーの解決方法

## はじめに

Docker環境でWordPressとNginxを使って仮想環境を構築している際に、サーバー再起動後に以下のエラーが発生しました：

> お使いのサーバーのPHPではWordPressに必要なMySQL拡張を利用できないようです

さらに調査したところ、私の場合は**ローカルの`php.ini`ファイルが消えていた**ため、PHPの設定が初期化されてしまったことが原因でした。本記事では、このような状況での問題解決手順を具体的に説明します。

---

## エラーの原因

このエラーが発生する主な原因は以下の通りです：

1. PHPがWordPressに必要なMySQL拡張（`mysqli`や`pdo_mysql`）を利用できない。
2. `php.ini`ファイルが存在しない、または設定が正しくない。
3. MySQLコンテナが正常に動作していない、またはWordPressと接続できていない。

特に、**ローカル環境で`php.ini`が何らかの理由で消失している場合**には、PHPの動作そのものに影響を与えるため、早急に再設定が必要です。

---

## 解決方法

私が実際に行った解決手順を以下にまとめます。

### 1. PHP MySQL拡張が有効か確認

まず、`mysqli`や`pdo_mysql`などの拡張が有効になっているかを確認します。

#### PHP拡張の確認コマンド
Dockerコンテナ内で以下のコマンドを実行します。

```bash
docker exec -it <phpコンテナ名> php -m | grep mysqli
```

結果に`mysqli`が表示されない場合、PHPイメージに必要な拡張を追加する必要があります。

#### Dockerfileの編集
PHPイメージに拡張をインストールするようにDockerfileを編集します。

```Dockerfile
RUN docker-php-ext-install mysqli pdo_mysql
```

編集後、Dockerイメージを再ビルドします。

```bash
docker-compose build
docker-compose up -d
```

---

### 2. php.ini の再設定

私のケースでは、**ローカルの`php.ini`ファイルが消えていた**ため、新しい設定ファイルをダウンロードして再構築しました。

#### php.ini のダウンロード
以下のリポジトリから`php.ini-development`をダウンロードしました。

- [PHP公式GitHubリポジトリ](https://github.com/php/php-src/blob/php-8.1.17/php.ini-development)

#### php.ini の配置
ダウンロードしたファイルを`php.ini`としてリネームし、PHPが参照するディレクトリに配置します。

```bash
mv php.ini-development php.ini
cp php.ini /usr/local/etc/php/php.ini
```

Docker環境の場合、永続化するために以下を`docker-compose.yml`に追加します。

```yaml
volumes:
  - ./php.ini:/usr/local/etc/php/php.ini
```

#### 必要な設定の追加
以下の設定を`php.ini`に追記しました。

```ini
extension=mysqli
```

設定後、PHPを再起動します。

```bash
docker-compose restart
```

---

### 3. MySQLとWordPressの接続確認

MySQLが正常に動作しているか確認します。

```bash
docker exec -it <mysqlコンテナ名> mysql -u root -p
```

WordPressの`wp-config.php`で以下の設定が正しいか確認します。

```php
define('DB_HOST', 'mysql'); // Docker環境では通常 'mysql'
define('DB_USER', 'root');
define('DB_PASSWORD', 'password');
define('DB_NAME', 'wordpress');
```

---

### 4. PHP情報ページで確認

最終的に、`phpinfo()`を使ってPHPの設定情報を確認しました。

```php
<?php phpinfo(); ?>
```

ブラウザで`mysqli`が有効化されているかを確認します。

---

## 参考にしたページ

今回の解決にあたって、以下の情報を参考にしました：

1. [DockerでWordPress環境構築時に発生するMySQL拡張エラーの解決方法](https://qiita.com/Muusann/items/6696601f03f80b2e8322)  
2. [MySQLとPHPの設定に関するトラブルシューティング](http://neareal.net/index.php?IT%2FCMS%2FWordPress%2FTrouble%20with%20MySQL%20and%20PHP%20setting)  
3. [Docker + PHP環境でphp.iniを適用する方法](https://qiita.com/alpha_z/items/b4ee671130e2abeff6d3)  
4. [PHP公式リポジトリ](https://github.com/php/php-src/blob/php-8.1.17/php.ini-development)

---

## おわりに

Docker環境では、PHPやMySQLの設定が永続化されていない場合にエラーが発生することがあります。特に`php.ini`が消失するようなケースでは、再設定が必要です。本記事が同じ問題を抱えている方の参考になれば幸いです。
Pythonのre-raise方法の違いについてまとめてみた

# はじめに
Pythonで実装している際に、標準のエラーやサードパーティ製ライブラリから出るエラーを独自のカスタムエラーでオーバーライドしてre-raiseする時などがあるかと思いますが、そんな時にエラーチェインする場合としない場合や、そのままraiseするのとraise eとするもので違いがあるのかなど気になったので調べてみました。


#### 今回比較で使用したサンプルコード
```python
try:
    with open("sample_file.txt", "r") as file:
        content = file.read()
except FileNotFoundError as e:
    raise  # パターン①: 簡易再送
    raise e  # パターン②: 元のエラーを再発生
    raise RuntimeError("ファイルが見つかりませんでした。")  # パターン③: エラー置き換え
    raise RuntimeError("ファイルが見つかりませんでした。") from e  # パターン④: エラーチェイン付きでエラーを発生
    raise RuntimeError("ファイルが見つかりませんでした。") from None # パターン⑤: 元の例外情報を明示的にチェインしないようにエラー置き換え
```

## パターン①: `raise`
**概要:** `except`ブロック内で`raise`を呼び出すと、キャッチされた元の例外をそのまま再発生させます。

```bash
Traceback (most recent call last):
  File "main.py", line 3, in <module>
    with open("sample_file.txt", "r") as file:
FileNotFoundError: [Errno 2] No such file or directory: 'sample_file.txt'
```

**特徴:**
- 元の例外を再発生させることで、最初のエラーのコンテキストが維持されるます。
- 最もシンプルな再送方法。

## パターン②: `raise e`
**概要:** 捕捉したエラーオブジェクト`e`を明示的に再発生させます。

```bash
Traceback (most recent call last):
  File "main.py", line 7, in <module>
    raise e
  File "main.py", line 3, in <module>
    with open("sample_file.txt", "r") as file:
FileNotFoundError: [Errno 2] No such file or directory: 'sample_file.txt'
```

**特徴:**
- スタックトレースに`raise e`の行番号が追加され、元のエラー発生箇所に加えて再発生箇所も表示されます。
- `raise`単独のほうが基本的に適切みたい。

## パターン③: `raise RuntimeError(...)`
**概要:** 元の例外を無視して新しい例外を発生させます。

```plaintext
Traceback (most recent call last):
  File "main.py", line 3, in <module>
    with open("sample_file.txt", "r") as file:
FileNotFoundError: [Errno 2] No such file or directory: 'sample_file.txt'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "main.py", line 7, in <module>
    raise RuntimeError("ファイルが見つかりませんでした。")
RuntimeError: ファイルが見つかりませんでした。
```

**特徴:**
- スタックトレースには元のエラーが表示されますが、「何が原因か」の説明がないため、慎重に使用すべき。

## パターン④: `raise RuntimeError(...) from e`
**概要:** 新しい例外を発生させる際に、元の例外情報をチェイン（原因として関連付け）します。

```plaintext
Traceback (most recent call last):
  File "main.py", line 3, in <module>
    with open("sample_file.txt", "r") as file:
FileNotFoundError: [Errno 2] No such file or directory: 'sample_file.txt'

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "main.py", line 7, in <module>
    raise RuntimeError("ファイルが見つかりませんでした。") from e
RuntimeError: ファイルが見つかりませんでした。
```

**特徴:**
- 元のエラー情報を保持しつつ、新しい例外を追加します。
- エラーの発生原因を追いやすく、デバッグに有用。
- Pythonicな方法として推奨される。

## パターン⑤: raise RuntimeError(...) from None
**概要:** 新しい例外を発生させる際に、元の例外情報を明示的にチェインしないよう指定します。

```python
Traceback (most recent call last):
  File "main.py", line 7, in <module>
    raise RuntimeError("ファイルが見つかりませんでした。") from None
RuntimeError: ファイルが見つかりませんでした。
```
**特徴:**
- 元のエラー情報（スタックトレース）は完全に省略され、新しい例外のみが表示されます。
- 元のエラー情報を不要として意図的に隠す場合に使用します。
- 原因追跡が難しくなるため、使用には注意が必要です。

## 最後に
この記事では、Pythonで例外を再送 (re-raise) する方法について、さまざまなパターンまとめてみました。
ご拝読ありがとうございました。
駆け出しは資格取得に時間割かない方がいいと思った

初めてQiitaに投稿します。
特にこれといって突出して語れる内容がないので、とりあえず無難にIT資格小話を1つ。

数年前にSESからプログラマとしてのキャリアをスタートさせて
今ではなんとかモダンな開発もお任せいただけるようになった私ですが、

駆け出しの頃はほかの駆け出しさんと同じく「資格を取るべきかどうか」で結構悩んでいた時期があります。
エンジニアデビューした会社はバリバリのSES企業だったので営業や自社は当然のように資格取得を推奨してくる、というか資格を定期的に取らないといくらポートフォリオを作っても「プライベートで勉強する気なし」の烙印を押されるくらいの会社でした。

なのでまあJavaSilverや基本・応用情報、AWS、Oracle系などいろいろ取ったわけですが、
振り返ってみるとあの時間は手を動かす学びに使っていた方がよかったなというのが私なりの結論です。

正直SES時代でも面談で資格が話題に上がったことなんて1回くらいしかないですし、
「あ、ここ資格で勉強した内容だ！」みたいに業務で役立ったこともほぼないです。

むしろ今までを振り返ると技術的な部分で大きく成長できたのはかならずといっていいほど手を動かした時期です。
ポートフォリオを作ったり、未経験の技術の案件に潜り込んで学びながらなんとか実装を進めたり、そういう時期に学んだことが今でも私を支え続けてくれています。

というわけで資格に関してはいろんなご意見ありますし確かに必要という場面がないわけではないでしょうが、基本的に私は資格に時間を使うのはリスクかなと思っていますという話です。

どうしても取りたいor会社が取れってうるさいなら基本情報くらいは取っておいてもいいかもしれません。