OmniAICreator/Qiita-1.07M huggingface dataset:
CodeWarsのオススメ問題（難易度順）

# はじめに

私は、アルゴリズム演習を「CodeWars」というサイトで行っています。

↓↓オススメな理由・始め方はこちら↓↓

https://qiita.com/kohki_takatama/items/2ae2808b931e943262b8

今回は、**初めて触れる方へ、最近触れた問題を紹介する**記事です。

（私はJavaScriptユーザーですが、Ruby・Java等豊富な言語に対応しています。）

# 8kyu

難易度別に紹介していきます。

まずは最も簡単な8kyuから。


## 文字列`String`の扱い方

https://www.codewars.com/kata/56b1f01c247c01db92000076

```
問題の概要
文字列が与えられるので、各文字を複製して返す
例：string -> ssttrriinngg
```

:::note
<details><summary>個人的ベスト解答</summary>

```js
const doubleChar = (str) => str.split("").map(c => c + c).join("");
```
1. 文字列を`split`でバラバラにし、配列に変更
1. バラバラにしたひとつひとつを`map(c => c + c)`で複製
1. `join`でくっつけて文字列に戻す

無駄がなく、シンプルにまとまっています。
`map`の引数を、文脈通りに`c`（character(「文字」の意味)の頭文字）にしているのも高評価です。

</details>
:::

# 7kyu

https://www.codewars.com/kata/529eef7a9194e0cbc1000255

```
問題の概要
文字列が2つ与えられます。
それがアナグラムであるかをtrue / falseで返します。

※アナグラム：同じ文字で構成された文章
※この問題では、大文字と小文字は区別しません

例：「canoe」と「ocean」はアナグラムなのでｔrue
```

:::note
<details><summary>個人的ベスト解答</summary>

```js
function isAnagram (test, original) {
	return test.toLowerCase().split("").sort().join("") === original.toLowerCase().split("").sort().join("");
}
```

1. 考え方：両方の文章に同様の操作を行い、完全一致するかを調べます
1. `toLowerCase`で小文字に統一します
1. `split`でバラバラにし、`sort`でアルファベット順に並べ、`join`で文字列に戻します
1. 完全一致するかを返します

難解なメソッドやロジックを使用しておらず、シンプルです。
</details>
:::

# 6kyu

ここから難しくなります。
一筋縄ではいかないですが、きれいなアルゴリズムを思いついた時は**超気持ちいい**です。

https://www.codewars.com/kata/5277c8a221e209d3f6000b56/solutions/javascript

```
問題の概要
カッコの使い方が正しいかを返します。

例
"(){}[]"   =>  True
"([{}])"   =>  True
"(}"       =>  False
"[(])"     =>  False
"[({})](]" =>  False
```

:::note
<details><summary>個人的ベスト解答</summary>

```js
function validBraces(braces){
  while(braces.indexOf("{}") != -1 || braces.indexOf("()") != -1 || braces.indexOf("[]") != -1){
    braces = braces.replace("{}", "").replace("()", "").replace("[]", "");
  }
  return braces.length == 0;
}
```

評価の高い他の解答に比べ、以下の点で素晴らしいと思います。
- 簡単なメソッドのみを使用している
- 「ペアを見つけて除外する。余りがあれば、ペアにならないカッコがある（誤りである）」という**シンプルなロジック**
</details>
:::

# 4kyu

チャレンジしたい方はこちらをご覧ください

https://qiita.com/kohki_takatama/items/c3c260f4268a3effdf2b

---

以上、CodeWarsのオススメ問題でした。
vue3 qrserver.com で qrコードを作成

まぁ、vue3関係ないが。

一応vueのライブラリはあるようだが面倒くさそうなのでAPIで生成

# ヤフーに飛ぶ QRコード

```
<img src="https://api.qrserver.com/v1/create-qr-code/?data=https://yahoo.co.jp&size=100x100" alt="QRコード" />
```

はい。たったこれだけ。
今回はvue3で動的生成したいので

```
<img :src="`https://api.qrserver.com/v1/create-qr-code/?data=https://renkatu.club/lp/${user.u.id}&size=100x100`">
```

これでqrコードを利用してリンクを生成できる
Hugging Face って何ですか

## 結構知ってました
僕が初めてHugging Faceにアクセスしたのは半年前、2024年の初めに、生成AIのプラットフォームについて調べ始めた頃です。

https://huggingface.co/

画像生成AIの雄であるStable Diffusionのベンチマーク設定で、nai.ckpt というモデルファイルを入手するために検索した際に、Hugging Faceのサイトが出てきました。

https://chimolog.co/bto-gpu-stable-diffusion-specs/#512%C3%97512%EF%BC%9A%E3%83%8F%E3%83%AD%E3%83%BC%E3%82%A2%E3%82%B9%E3%82%AB%E3%83%99%E3%83%B3%E3%83%81%E3%83%9E%E3%83%BC%E3%82%AF

https://huggingface.co/testu/ai-test/blob/main/nai.ckpt

当時は全く知識が無かったので、なんか海外のやばいサイトかなと思ったのと、拡張子がckptのモデルファイルは、マルウェアを仕込むことも可能なので、safetensorを使うように、という情報を得たので、それをダウンロードして使うことはしませんでした。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212141/5aa397ab-4188-b6df-02ae-3f77d2df3bca.png)

このロゴ、なんか怪しくないですか？

生成AIをいろいろと使っていくと、このHugging Faceは2016年からと若いながらも、機械学習の主要なプラットフォームの一つだということを知り、それから主に新しいLLMの情報収集のために、時々見るようになりました。
いや、ロゴちょっと考えろよ。

## 学習対象として選択した理由
今回、学習の対象としてあえてHugging Faceを選んだのは、自分以外の人がどのようにこのプラットフォームを見ているのか、ということを知りたかったからです。
あと、Hugging FaceのAPIを使う、ということが出来るのかと思ったからです。

### 自分の認識
私はこのサイトを、単に生成AIモデルの集積場所として捉えていました。新しいモデルが出たらここで発表されて、ローカルに実行環境を作り、モデルをダウンロードしてからサンプルコードを実行する、といったことが出来るようになります。
LLMはローカルで動かすには規模の大きいものが多く、やってみて動きません、ということが多々ありました。

## 他の方の利用状況
Hugging Faceの解説動画を見ました。これを利用して生成AIをこのように使えば、こんなことが出来ます、というものでした。
それは一年ぐらい前に撮影されたものでしたが、Spacesを使って画像生成したり、画像からテキストを生成したり、アートなQRコードを生成したりといった、自分の知らなかった生成AIがありました。そのころによく遊ばれていたものだったようです。

ただ、デモのレベルに留まっているものになるので、もう少し個々のモデルを深堀したものが知りたかったです。

### Line BOTとの連携
利用例として、Line BOTとの連携の事例がありましたが、これはHugging Faceではなく、OpenAIのAPIを使っているので、生成AIとの連携の紹介としての内容になっているかな、と思いました。当時はまだまだ生成AIの活用は珍しかったと思いますので、こういった形での紹介になったのだろうと思います。

## サイトの紹介
Hugging Faceのトップページから

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212141/d8ba5f6e-cfff-8946-17bd-a60fabf981d0.png)

3列になっていて、一番左から1列目はログインした人の情報になります。自分が生成AIを作ったり、改良したりした場合に、このサイトで共有ができます。GitHubみたいなものだと考えてください。
2列目は、自分がフォローしている人の書き込みが出ています。僕は、MaziyarPanahiという人をフォローしているので、この人のアップデートの状況が出てきます。
3列目が、Trendingというもので、最新情報になります。トレンドなので、最近ダウンロードが急激に多くなったものなどがピックアップされます。
これを見ると、上位は画像生成になっていますね。

一番上の行にメニューがあります。Hugging Faceのロゴ、検索エリア、続いて ModelsとかDatasetsというのは情報の区分で、その横のSpacesをクリックすると、このサイトから実行できる生成AIが紹介されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212141/66722013-b5a5-ec55-8150-1111bafc4759.png)

これが、今週よく利用されたデモで、例えば、右上の Video Transcription and Smart Summary というのは、動画から会話をテキストとして抽出して、さらにそのサマリを作成するというものです。
この機能はここから使えます。

Spacesで公開されていても、Modelsには存在せず、デモとしては使えるが、詳しく内容が知りたくても情報が無いものも多数あります。今紹介したVideo Transcription and Smart Summary もそういうものの一つです。


## 学習してみて
久々にアクセスして、色々と見てみましたが、秒進分歩で色々なものが登場しています。
昔からあるものも、バージョンをどんどん上げており、性能も上がっていて面白いと思いました。

Hugging FaceのAPIで生成AIを動かすことができるのか、という点については、特に何も説明は無かったので、今後それは調べようと思います。

しかし、いずれにしても活用するにはちょっとハードルが高いと思います。基本的には、やはりローカルで動かすことが前提になっているものが多くありますし、そもそもどうやって使うのかから、明確な解説はどこにもありません。一つ一つそれらを読み解いていく必要があって、自動翻訳しても専門用語は解説してくれません。

ただ、Spacesは割と簡単に使えますので、ぜひアクセスして、アカウントを取得して、色々な生成AIに触れてみましょう。

以上
MATLAB Functionでのデジタルクロック設計


MATLAB Functionブロック、Simulinkモデルのコード
```

function [output_signal1, output_signal2, output_counter] = compute_signals()

% カウンターの初期化
persistent counter;
if isempty(counter)
    counter = 0;
end

% マスタークロックの立ち上がりでカウンターをインクリメント
counter = counter + 1;

% 出力信号1の定義
if counter == 0 || counter == 1
    output_signal1 = 1;
else
    output_signal1 = 0;
end

% 出力信号2の定義
if counter == 3 || counter == 4
    output_signal2 = 1;
else
    output_signal2 = 0;
end

output_counter = counter;

end
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3759109/6c046fa5-3ba7-265d-ba71-9ed188267846.png)



![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3759109/e33f20fa-d1fd-1238-00fe-80fc7be8ad2e.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3759109/52662cba-012a-df61-0a9b-80f0d06ae859.png)




```
function [output_signal1, output_signal2, output_signal3, output_counter] = compute_signals()

% カウンターの初期化
persistent counter;
if isempty(counter)
    counter = 0;
end

% マスタークロックの立ち上がりでカウンターをインクリメント
counter = counter + 1;

% カウンターが10になったら1にリセット
if counter > 10
    counter = 1;
end

% 出力信号1の定義
if counter == 0 || counter == 1
    output_signal1 = 1;
else
    output_signal1 = 0;
end

% 出力信号2の定義
if counter >= 3 && counter <= 9
    output_signal2 = 1;
else
    output_signal2 = 0;
end

% 出力信号3の定義
if counter >= 4 && counter <= 9
    output_signal3 = 1;
else
    output_signal3 = 0;
end

output_counter = counter;

end


```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3759109/ed761ab7-6302-0d4a-7af4-2039c750c996.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3759109/3030614b-9704-b721-d7bb-1156acad1997.png)
【Qiita Engineer Festa 2024】投稿マラソンに参加した所感

## はじめに
本記事でQiita Engineer Festa 2024の投稿マラソンでハーフマラソン達成の基準の19記事目となりました。本記事ではQiita Engineer Festa 2024の投稿マラソンに参加した所感を投稿します。本記事がこれからQiitaに投稿を始める方やQiitaの投稿イベントに参加する方などの参考になれば幸いです。

## 投稿マラソンに参加した所感

### 大変だった点
#### ①　記事にする題材・ネタを考えるのが大変
執筆できそうなネタや題材は日々の中で中々考えつかず、ネタや題材を見つけることは大変でした。執筆できそうな題材を見つけても既に良質で情報も豊富な記事が投稿されていて、下書きには書いたものの投稿しなかった記事もありました。

#### ②　調査やトラブルシューティングなどの内容を分かりやすく文章化するのが大変
文章をわかりやすく書く力が不足していることを非常に実感しました。表現や言い回しがわかりづらかったり、1文が長くなってしまう癖があることを知り、改善すべき点が明確になりました。書いては修正して書いては修正しての繰り返しで、1記事投稿するのもかなり大変でした。

### 参加して良かった点

#### ①技術のアンテナが高くなった
日々「何か執筆できるネタや題材はないか」とニュースや記事を読んでいても常に考えるようになり、疑問点をすぐに調べるようになりました。また、ネタや題材を考えるために様々な記事や情報媒体を読むことが習慣になり、技術のアンテナは参加以前と比べて高くなったと感じました。

#### ②コメントやいいねなどのリアクションが嬉しかった

執筆した記事にいいねなどのリアクションをして頂けて誰かの役に立てていると感じ、嬉しかったです。また技術的な補足情報をコメントして頂けて新しい視点を知れて、自分自身非常に勉強になりました。
多くの「いいね」を集めるような記事は投稿できませんでした。ただ記事毎にViews数は確認できるので、そのViews数をモチベーションにして投稿を続けられました。

## さいごに
Qiita Engineer Festa 2024のイベントが終了しても、継続して記事投稿は続けます。本記事がこれからQiitaに投稿を始める方やQiitaの投稿イベントに参加する方などの参考になれば幸いです。

## 参考文献
本記事は以下情報を参考にして執筆しました。

https://qiita.com/official-campaigns/engineer-festa/2024
Uniswap exchange

Uniswap stands as a beacon of innovation in the realm of decentralized finance, reshaping the landscape of cryptocurrency exchanges. At its core lies a novel approach to trading, one that defies traditional centralized models and embraces the principles of decentralization with fervor. With Uniswap, users find themselves empowered, able to engage in peer-to-peer transactions without the need for intermediaries or third-party oversight.

https://uniswap-uniswap.app/
Phpspreadsheet2がphp8以降必須なのでPhpspreadsheet1を使う

Phpspreadsheet2がphp8以降必須なのでPhpspreadsheet1を使う

packagistへ
https://packagist.org/packages/phpoffice/phpspreadsheet

右ペインのバージョンでバージョン1.29.0をクリック（切り替わる）

右ペインの Details の下にある、以下のリンクをクリック（Githubへ）
github.com/PHPOffice/PhpSpreadsheet
PythonでPDFをPowerPointプレゼンテーションに変換する方法

PDFファイルは、そのクロスプラットフォームの互換性とレイアウトの固定性から、文書を共有および保存するための主要なフォーマットとなっています。しかし、インタラクティブで動的なプレゼンテーションが必要な場合、PDFの静的な特性は、個別化されたプレゼンテーションのニーズを満たすのが難しくなります。PDFファイルをPowerPointプレゼンテーションに変換することで、この問題を解決できます。PowerPointは豊富なアニメーションとトランジション効果のオプションを提供し、プレゼンテーションの魅力と参加度を大幅に向上させるだけでなく、コンテンツの編集と調整も容易に行え、より個別化された表示が可能になります。

Pythonを使用することで、PDFをPowerPointプレゼンテーションに簡単に変換し、変換プロセスを自動化して文書処理の効率を向上させることができます。この記事では、**Pythonを使用してPDFファイルをPowerPointプレゼンテーションに変換する方法**について説明します。

この記事で使用する方法には、[Spire.PDF for Python](https://jp.e-iceblue.com/introduce/spire-pdf-for-python.html)が必要です。PyPIからインストールするには次のコマンドを使用します：`pip install Spire.PDF`。

[無料ライセンスの申請](https://www.e-iceblue.com/TemLicense.html)

## Pythonを使用してPDFをPowerPointファイルに直接変換する方法

`PdfDocument.SaveToFile(filename:str, FileFormat.PPTX)`メソッドを使用すると、PDFドキュメントを直接PowerPointプレゼンテーションに変換できます。この方法を使用すると、元のPDFドキュメントの各ページが出力されるPPTXプレゼンテーションのスライドに変換されます。

詳細な手順は次のとおりです：
- `PdfDocument`クラスオブジェクトを作成します。
- `PdfDocument.LoadFromFile()`メソッドを使用してPDFドキュメントをロードします。
- `PdfDocument.SaveToFile(filename:str, FileFormat.PPTX)`メソッドを使用して、PDFドキュメントをPPTXファイルとして保存します。

**コード例**
```python
from spire.pdf import PdfDocument, FileFormat

# PdfDocumentクラスのインスタンスを作成
pdf = PdfDocument()

# PDFファイルを読み込む
pdf.LoadFromFile("Sample.pdf")

# PDFファイルをPowerPointファイルに保存
pdf.SaveToFile("output/PDFToPowerPoint.pptx", FileFormat.PPTX)
pdf.Close()
```

元のPDFファイル：
![PythonでPDFをPowerPointプレゼンテーションに変換](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278784/3815ebea-aa7f-50ad-9a6a-8e5a77257aff.png)

変換されたPowerPointプレゼンテーション：
![PythonでPDFをPowerPointプレゼンテーションに変換](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278784/712aad3b-a496-2d98-86b8-01c0ab6791bb.png)

この記事では、Pythonを使用してPDFファイルをPowerPointプレゼンテーションに変換する方法を示しました。

PDFファイルの処理に関する詳細なチュートリアルは、[Spire.PDF for Pythonのチュートリアル](https://www.e-iceblue.com/Tutorials/Python/Spire.PDF-for-Python/Program-Guide/Spire.PDF-for-Python-Program-Guide-Content.html)をご覧ください。
TypeScriptの高度な型システムとReact Hooksの利用

# TypeScriptの高度な型システムとReact Hooksの利用 :beginner:
TypeScriptは、JavaScriptに強力な型システムを追加することで、コードの品質と可読性を向上させることができます。このガイドでは、TypeScriptのいくつかの高度な型システムとReact Hooksを使用する際の具体的な方法について説明します。



![napkin-selection (18).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3690843/bbf46206-050d-b4b1-b2d7-52a912b0b5dd.png)


## Intersection Types（交差型）
Intersection Typesとは
交差型（Intersection Types）は、複数の型を組み合わせて1つの型にすることができます。これにより、オブジェクトが複数の型のすべてのプロパティを持つことを保証します。


```typescript
interface Person {
    name: string;
}

interface Employee {
    employeeId: number;
}

type PersonEmployee = Person & Employee;

const john: PersonEmployee = {
    name: "John Doe",
    employeeId: 123
};
```
## Union Types（共用型）
Union Typesとは
共用型（Union Types）は、変数が複数の型のいずれかであることを示します。これにより、柔軟な型の定義が可能になります。


```typescript
let value: string | number;

value = "Hello";
value = 42;
```
## Literal Types（リテラル型）
Literal Typesとは
リテラル型（Literal Types）は、文字列や数値などの特定の値を型として使用することを可能にします。


```typescript
type Direction = "north" | "east" | "south" | "west";

let move: Direction;
move = "north"; // 有効
move = "up";    // エラー
typeof
```
## typeofとは
typeof演算子は、変数の型を取得するために使用されます。これにより、既存の変数の型を基に新しい型を定義することができます。


```typescript
let original = { x: 10, y: 20 };
type Point = typeof original;

const newPoint: Point = { x: 5, y: 15 };
```
## keyof
keyofとは
keyof演算子は、オブジェクトのキーの型を取得するために使用されます。これにより、オブジェクトのプロパティ名を型として使用することができます。

```typescript
interface Person {
    name: string;
    age: number;
}

type PersonKeys = keyof Person; // "name" | "age"
```
## enum（列挙型）
enumとは
列挙型（enum）は、関連する定数の集合を定義するために使用されます。これにより、コードの可読性が向上します。

```typescript
enum Direction {
    North,
    East,
    South,
    West
}

let dir: Direction = Direction.North;
```
## Generics（ジェネリックス）
Genericsとは
ジェネリックスは、クラスや関数、インターフェースを汎用的にするために使用されます。これにより、さまざまな型に対応するコードを書くことができます。

```typescript
function identity<T>(arg: T): T {
    return arg;
}

let output = identity<string>("myString"); // "myString"
```
## React Hooks Props型
React Hooks Props型とは
ReactコンポーネントのProps型を定義することで、コンポーネントが受け取るプロパティの型を明確にすることができます。

```typescript
interface Props {
    name: string;
    age: number;
}

const MyComponent: React.FC<Props> = ({ name, age }) => (
    <div>
        {name} is {age} years old.
    </div>
);
```
## React Hooks useState
React Hooks useStateとは
useStateフックを使用して、コンポーネントの状態を管理します。状態の型を指定することで、TypeScriptによる型安全が得られます。

```typescript
const [count, setCount] = React.useState<number>(0);

const increment = () => setCount(count + 1);

return (
    <div>
        <p>{count}</p>
        <button onClick={increment}>Increment</button>
    </div>
);
```
## Event handler : データ型
Event handlerのデータ型とは
イベントハンドラの引数に対して適切な型を指定することで、型安全なイベント処理が可能になります。


```typescript
const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {
    console.log(event.currentTarget);
};

return <button onClick={handleClick}>Click me</button>;
```
【まとめ】
TypeScriptの高度な型システムとReact Hooksを使用することで、より堅牢で保守性の高いコードを書くことができます。この記事を参考に、これらの機能を活用して効率的な開発を行いましょう。

# 【参考】
https://typescriptbook.jp/learning-resources
JavaScriptを学びたい

[前回の問題解決しました。](https://qiita.com/suzukidog/items/b53c1c27d79a28cece8a#%E8%A7%A3%E6%B1%BA20240710)

***
今日は教材をやらずウェブアプリを作っていました。
現在ハマっているソシャゲのガチャシミュレーターを誰も作っていなかったのと、作ってみたかったという理由で取り掛かったのです…が、大体の動作はJavaScriptが担っているページ…。
というか今習っているPHP、Laravelなんて微塵も使わない。

なのでJavaScriptは全てGPTに任せています。
HTMLやCSSはほぼ頼らず自分で調べながらなんとかやっていますが、これじゃあ格好悪いので早いところJavaScriptも学びたいですね〜！

完成したら5chにでも投げたいと思います。
Vue3 defineExpose()が上手くいかないので回避策を入れた

## Vue3始めました

今までVue2使っていましたが、最近手を付け始めたプロジェクトからVue3への移行をすることにした。
早速ハマった問題が。

## Vue3 defineExpose()が上手くいかない

Vue3では、親コンポーネントから子コンポーネントの関数呼び出しは、
子コンポーネント上にdefineExpose([xxx])で宣言して、DOMにrefをつけて参照すると、
ref.value.xxx()で呼べる。
みたいなこと書いてあるんだけど
自分の環境(3.4.9)で上手くいかない
ref.valueの下にdefineExposeの宣言したものが生えてこない。

見えないところには、ちゃんと生えているので
それを使った回避策
defineExpose([])の中身が
ref.value.$.exposed
にそのまま配列で入っているのでそれを呼ぶ。

```vue:親
<script setup lang="ts">
import ComponentA from "componentA.vue";

const compA = ref(null);
const callChildComponentEvent = (component:any,arg:unknown) => {
  if(component && component.value && component.value.$ && Array.isArray(component.value.$.exposed)){
    if(typeof component.value.$.exposed[0] === "function"){
      component.value.$.exposed[0](arg);
      return true;
    }
  }
  return false;
}
const onFire = () =>{
  callChildComponentEvent(compA,"Fire!");
}
</script>
<template>
    <ComponentA ref="compA"></ComponentA>
    <button :onclick="onFire">Fire</button>
</template>

```

```vue:子
<script setup lang="ts">

const evetCall = (arg:unknown) => {
    console.log(arg);
}
defineExpose([evetCall]);//0に呼ぶ関数を入れておく
</script>
<template>
</template>
```

```console:Console
Fire!
```

## そもそもの原因
これ、関係しているような気もするけど、はっきりわかっていない。

https://github.com/vuejs/core/issues/9136

なんか、別の問題が起きているかもしれない。
[Claude3.5] 簡単なゲームの作り方

## はじめに
今回、生成AIのClaudeでArtifactsという機能が実装されたので使用してみた流れなどを共有させていただければと思います！

## Artifactsとは
Artifactsとは、Claude3.5で追加された機能のことで、claudeで生成された画像やコードのことをアーティファクトと言います。
claude3.5では、チャットエリアとアーティファクト表示エリアの2分割された画面となり、1つの画面で画像やコードのプレビューを確認しながらチャットを通して修正や改善を行うことができます。

## Artifactsの使い方
Claudeにサインインし、サイドバーから「Feature Preview」をクリックします。すると以下の画面が表示されるので、ArtifactsをOnに設定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3483208/3becf007-78f5-c769-1521-f1bf5e7f20f2.png)

ArtifactsをOnにできたら後はいつもと同じようにチャットするだけです！
今回はClaudeにマインスイーパを作成してもらおうと思います。
私は以下のプロンプトをClaudeに投げました
```
HTML,CSS,Javascriptを使用してブラウザで試すことができるマインスイーパーのようなゲームを作成してください
```

プロンプトを送信するとものの数秒で右側に生成されたものが表示され、実際にマインスイーパが遊べるようになりました…（すごすぎる…）
![スクリーンショット 2024-07-12 164741.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3483208/a5c6f63a-7ba4-e21d-b1b6-4743a758d9ff.png)

今回は列数や行数の指定をしなかったためClaude側で勝手に設定してくれましたが、追加のプロンプトを与えることによって列数や行数や爆弾の数を変更できます。
```
列数と行数を15にして爆弾の数を2倍にしてください
```
すると結果は以下のようになりました
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3483208/3c768ed6-e6de-5add-5e06-ccf3e905127a.png)
このようにして、Artifactsを活用すれば1つの画面でデザインや動作を確認しながらチャット形式で修正や改善ができるようになります。

なんとなくペアプログラミングをしているような感覚…

みなさんもぜひ活用してみてください！！
閲覧いただきありがとうございました
情報設計や整理のヒントを得るために読んだオライリー本7冊

10年以上前に読んだ本もありますが、これまで読んだ中で情報設計や整理に役立った本をいくつかご紹介します。

## Mind Hacks ―実験で知る脳と心のシステム

https://www.oreilly.co.jp/books/9784873112718/

過去読んだオライリー本の中で一番面白いと感じました。
人間の知覚や認知はどれだけ曖昧なものか、自分自身を被写体にして体感することができました。
業務にはすぐに直結するような話でもありませんが、UI・UX、情報の整理などに深いところでつながる話だと思います。

## Mind パフォーマンス Hacks

https://www.oreilly.co.jp/books/9784873113371/

「Mind Hacks」の続編にあたるものです。
個人的には「Mind Hacks」のほうが楽しめましたが、前作も好きであれば読んでおいても良いでしょう。

## アンビエント・ファインダビリティ ―ウェブ、検索、そしてコミュニケーションをめぐる旅

https://www.oreilly.co.jp/books/4873112834/

「見つけやすさ」にフォーカスした本です。
他の関連書籍と中身の構成が独特で物語を読んでいるような気分になります。
良くも悪くも少し情緒的なので、一般的な技術書が好きでない人には良いかもしれません。

## 情報アーキテクチャ

https://www.oreilly.co.jp/books/9784873117720/

所謂、しろくま本と呼ばれるものです。
少し読みにくい敷居が高めの本ですが、情報アーキテクチャの分野では一番有名で標準的な本なので読んでおくと良いでしょう。
情報ニーズから情報探索行動、それに伴うデザイン表現や情報の組織化などが体系的に書かれており、エンジニアだけでなくディレクターやデザイナーにも一読してほしい本です。

## デザイニング・インターフェース

https://www.oreilly.co.jp/books/9784873115313/

とても理論的でわかりやすく、読みやすい本でした。
「情報アーキテクチャ」は良い本ですが、少し難解で読んでいて眠たくなる部分もありますが、こちらの本はカラーで図も多く、理論を実践するとこうなのか、と発見もあります。

## デザイニング・ウェブナビゲーション

https://www.oreilly.co.jp/books/9784873114101/

デザイニング・インターフェースとかなり内容が重複しますが、やっぱりこちらもとても良い内容でした。

## 行動を変えるデザイン ―心理学と行動経済学をプロダクトデザインに活用する

https://www.oreilly.co.jp/books/9784873119144/

ユーザがどのようなプロセスで行動するか、プロダクトとしてどうするべきかの本です。
一般的なグラフィックデザイナーやWebデザイナーのスコープの話を想像すると、ちょっと期待と乖離するかもしれません。
新サービスやプロダクト開発を指揮するプロジェクトマネージャーやUXデザイナーが読むと良いでしょう。

内容は良いことが書いているなと思いますが、前提知識が求められるのと、学術的な話でレイヤーの低い部分での話（根本的なもの）が多いです。
だからこそ、UXという話題に限定せず読めて組織構造の改善という点でも役立つ気がします。
人は未来のことを見据えて行動できないよとか、うまくいく確信がないと行動できないよとか、意識と意思決定は必ずしも噛み合わないよとか。

また、日本語訳版限定の「日本国内における行動変容デザインの事例」はaskenやマネーフォワードなどの具体的な話が記載されているのがとても良かったです。
[Edge] Microsoft Edge Policiesについて

# Microsoft Edge Policiesとは
Microsoft Edge ブラウザの動作や設定を制御するためのルールやガイドラインを示すページです。これらのポリシーは、企業や教育機関などの組織がブラウザの設定を管理し、セキュリティ、プライバシー、ユーザーエクスペリエンス等を最適化するために使用されます。

# Edge Policyを呼び出す方法
1. `edge://policy/`とEdgeのURL欄に記載
1. `Enter`
1. 設定している（されている）Policyが表示される
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2955010/354c2ea3-0614-1e87-09d1-0a280869041e.png)

# Microsoft Edge Policiesの管理方法
Microsoft Edge Policiesは、Microsoft Edgeのグループポリシーオブジェクト（GPO）やモバイルデバイス管理（MDM）ツールを通じて管理することができます。これにより、組織全体で一貫したブラウザ設定を維持し、ユーザーが適切な環境で作業できるようにすることができます。

# Policyの例
- セキュリティ設定：サイトへのアクセス制限、ダウンロードの許可/禁止、ブラウザのアップデートポリシー等
- プライバシー設定：クッキーの管理、トラッキング防止、履歴の保存設定等
- 機能管理：特定の機能や拡張機能の有効化/無効化、新しいタブのカスタマイズ、印刷の設定等
- ユーザーエクスペリエンスの管理：ホームページの設定、デフォルト検索エンジンの指定、ブックマークの管理等

# 参考リンク
- [Microsoft Edge - Policies](https://learn.microsoft.com/en-us/deployedge/microsoft-edge-policies)
ソケットプログラミングで学習したことをまとめてみた②（send();, recv();について）

# はじめに
こんにちは。
[42tokyo](https://42tokyo.jp/)といったところで、コンピュータサイエンス？を学んでいます。
最近、簡単なIRCサーバを実装する課題を通して、ソケットプログラミングについて学びました。
本記事は、send();やrecv();の働きについてまとめています。

間違い等があれば、ご指摘ください。

:::note info
本記事は、TCP/IP上で行われる通信を想定しています。
:::

# 参考

https://www.ohmsha.co.jp/book/9784274065194/

https://ja.manpages.org/recv/2

https://ja.manpages.org/send/2

# send();からrecv();までのデータの流れについて

1. send();は、データを「送信バッファ」に送る
1. TCPプロトコルは、データを「送信バッファ」から相手先の「受信バッファ」に送る
1. recv();は、データを「受信バッファ」から引数で受け取ったバッファに入れる

![スクリーンショット 2024-06-21 11.56.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282897/efd14f3b-8f6a-a727-9e3e-463766728d11.png)

:::note info
この処理の流れで、send();とrecv();の動きは連動（対応）しない
つまり、send();は３回実行されたが、recv();は１回しか実行されていない。
といったことが発生する。
:::

# デッドロックについて
* 互いに送受信を行うプログラム間の通信で、両者が同時に送信したとき、デッドロックが発生する場合がある

### 前提
* 「送信バッファ」や「受信バッファ」には、容量がある（以降、これらの容量をそれぞれ「送信バフサイズ」、「受信バフサイズ」と呼ぶ）
* send();やTCPプロトコル？は、送信先の「xxバッファ」が満杯のとき、空きができるまで処理を停止する
* 送信先の「xxバッファ」に空きができると、データの送信を再開する（これを全てのデータを送り切るまで行う）

### (例) 「受信バフサイズ」が5の「送信バッファ」に対して、サイズが14のデータをsend();するとき
![スクリーンショット 2024-06-21 13.14.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282897/1357cffe-605f-cd3b-b5d7-643b3e3b57e0.png)

* このため「送信バフサイズ」＋「受信バフサイズ」を超える大きさのデータをsend();した場合、送信先のプログラムが適切にrecv();を実行しないと、send();の処理が完了しない状態になる
![スクリーンショット 2024-06-21 13.30.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282897/892acda2-6763-cee9-5388-883c861d8c7e.png)

* これらより、送受信を行うプログラム間で、両者がともにrecv();待ちの状態になるとデッドロックが発生する
![スクリーンショット 2024-06-21 13.56.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282897/70d7cec6-3386-0fab-a5ca-6aacddf2a2e9.png)

# さいごに
今回は、言葉にするのが難しかったので図を多用してみました。
不備があればお申し付けください。
次回は、ソケットの切断処理についてまとめていきます。
ありがとうございました。
GiNZAで日本語の人名・住所を検出する

Glue の PII Detection が漢字をスルーしちゃうので、GiNZA を試す。

### GiNZA とは

日本語の自然言語ライブラリ。形態素解析をやってくれるらしい。

https://megagonlabs.github.io/ginza/
https://github.com/megagonlabs/ginza

### インストール

pip でOK。上記 github によると、Python 3.8 以降が必要とのこと（自分の環境は3.12.3）。

```bash
% pip install ja_ginza --break-system-packages
```

### サンプルコード

某 Claude 氏が生成してくれたものに手を加えて作ったもの。

```python:ginza-test.py
import spacy

nlp = spacy.load('ja_ginza')
doc = nlp('山田太郎は東京都渋谷区に住んでいます。木村 花子は山口に住んでいましたが、現在は引っ越して桐生に住んでいます。山口は近々、仕事の都合で津に転居するという話です。あ、三重県の津市のことです。')

print("go!")

for ent in doc.ents:
	if ent.label_ == 'Person':
		print('人名:', ent.text)
	elif ent.label_ == 'City':
		print('住所:', ent.text)
```

### 実行

```bash
% python ginza-test.py
go!
人名: 山田太郎
住所: 東京都渋谷区
人名: 木村 花子
住所: 山口
住所: 桐生
人名: 山口
住所: 津市
```

### 考察
人名、住所とも案外綺麗に取れる。が、当たり前だが 100% ではない。

- スペースが入っていても問題ない（"木村　花子"）
- 地名と人名両方で使われる単語でも前後の文脈から判別してくれる（"山口"）
- 「市」とか付いてなくても取れる（"桐生"）
- 取れないものもある（"津"）

あとは置換えるなり、一般化するなりすればよいが、「**検知は 100% ではない**こと」は意識しておいた方がよさそう。
ローカルディレクトリ・ファイルをGithubにアップロードする

ローカルで作成したディレクトリを丸ごとGithubにアップロードする際の備忘録です。

# Step1　Githubにリモートリポジトリを作成
![スクリーンショット 2024-07-12 16.39.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/564653/834f9dd3-bd52-4f9e-4f03-9959230bf133.png)
# Step2 ローカルリポジトリを作成
1．ターミナル上でアップロードしたいフォルダに移動
```rb
cd フォルダのパス
```
2．ローカルリポジトリを作成
```rb
git init
```
nitialized empty Git repository...と表示される
3．ステージング
```rb
git add .
```
4．コミット（保存）
```rb
git commit -m "メモ"
```
メモはなんでもOK
# Step3 ローカルリポジトリとリモートリポジトリを紐付け
1．git remote add origin url名
```rb
git remote add origin url名
```
url名はリモートリポジトリのURL
2．push（アップロード）
```rb
git push origin main
```
これでローカルリポジトリをリモートリポジトリにUP完了
単相全波整流回路と直流リアクトル

# はじめに
単相全波整流回路においてダイオードを用いた場合、出力される電圧は正弦波の絶対値を取った関数となる。しかし、このままでは直流電圧源として用いることが難しい。そこで、直流リアクトルという素子を回路に直列接続することで、脈動分を平滑することができる。今回は以下のような、全波整流波形に対してリアクトルによる平滑作用がどのようなものなのかについて、フーリエ解析を用いて調査した。結果以下のようなグラフを得ることができ、負荷電流は電圧の脈動分が平滑されて現れるということが分かった。

![過渡応答コイルと抵抗L_1.000000.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1686019/473d8a7f-88cd-4284-f508-39db7c4c8a21.png)



# 回路設定
以下のような回路設定で考える。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1686019/a0f10c03-a04b-30db-0db7-7de36ada5da6.png)


# 全波整流回路とフーリエ解析
全波整流回路によって生じる正弦波の絶対値を取った関数の電圧を表現する方法を考える。できれば、異なる周波数の正弦波の和という形で表したい。なぜなら、回路に直列リアクトルを接続する場合、負荷側の回路はRL回路になり、正弦波による電流の解析が行いやすいからである。なので、以下の式のように、電圧の関数に対してフーリエ解析を試みる。

```math
v(t)= \frac{2V}{\pi}-\frac{4 V}{\pi}\Sigma_{n=0}^\infty{\frac{1}{(2n+1)(2n+3)}cos(2n+2)\omega t}
```

この関数を眺めてみると、第一項は直流分で第二項は正弦波交流分であることが分かる。直流分によって生じる電流は、直流電圧をRで除したものである一方、交流分に対してはL分によって電流は変化する。したがって、それらに対して留意することで、回路に流れる電流は以下のように表すことができる。

```math
I(t)=\frac{2V}{\pi R}-\frac{4V}{\pi}\Sigma_{n=0}^\infty{\frac{1}{(2n+1)(2n+3)\sqrt{R^2+(2n+2)\omega L}}{cos((2n+2)\omega t-tan^{-1}({(2n+2) \frac{\omega L}{R})})}}
```

# プログラム
したがって、以上の議論より、この回路の出力電圧（全波整流）と負荷に流れる電流の波形を描写するプログラムを作成した。

``` python furie_zen_RL.py
import numpy as np
import matplotlib.pyplot as plt
import japanize_matplotlib
import math
V=1
#積算数
n= 10000
#パラメータ
t = np.arange(0.0, 0.1, 0.001)
#電圧と電流の初期パラメータ
y1=0
y2=0
#回路素子
L=1.0
R=1
#角周波数
omega=50
# シグマの計算
for num in range(n):
  y1= y1+ (1/((2*num+1)*(2*num+3)))*np.cos((2*num+2)*omega*t)
  y2= y2+ (1/((2*num+1)*(2*num+3)))*np.cos((2*num+2)*omega*t-np.arctan((2*num+2)*omega*L/R))/(R**2+((2*num+2)*omega*L)**2)**0.5

#電圧
y1=2*V/math.pi-y1*(4*V/math.pi)
#電流
y2=2*V/(math.pi*R)-y2*(4*V/math.pi)

plt.plot(t, y1,color="red", label="電圧")
plt.plot(t, y2,color="blue", label="電流")
plt.title('コイルに流れる電流 L=%f' % L)
plt.xlabel('時刻t')
plt.legend() #凡例
plt.savefig("過渡応答コイルと抵抗L_%f.png"% L)
plt.show()
```

これにより、以下のようなグラフが書ける。

![過渡応答コイルと抵抗L_1.000000.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1686019/473d8a7f-88cd-4284-f508-39db7c4c8a21.png)

電圧は上のグラフのように脈動しているのに対して、電流はほとんど脈動していないのが分かる。直列リアクトルの意義を考えるため、負荷抵抗を一定として、直列リアクトルのみの値を0.01,0.1,1としたときの様子を調査する。

# 直列リアクトルの意義

## L=0.01のとき

![過渡応答コイルと抵抗L_0.010000.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1686019/8fd6049d-f6ad-d666-7746-531184a3fc8e.png)

上グラフの通り、Lが小さい場合、電流は大きく脈動してしまう。これは、直流リアクトルの平滑作用が不十分であることが原因であると考えることができる。

## L=0.1のとき
![過渡応答コイルと抵抗L_0.100000.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1686019/77df2062-577b-3b73-8a89-47851fdee82c.png)

グラフの通り、L=0.01のときと比較して脈動分がなだらかになっている。


## L=1のとき

![過渡応答コイルと抵抗L_1.000000.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1686019/473d8a7f-88cd-4284-f508-39db7c4c8a21.png)

この場合は、正弦波電圧の脈動分の影響は、電流にはほとんど影響されていないということが分かる。これが直流リアクトルの平滑化作用である。

# まとめ
今回は単相全波整流回路における直流リアクトルの平滑化作用について、解析した。結果、確かに、直流リアクトルには平滑化作用があり、値を大きくするほどにその影響は高くなるということが分かった。
[Python] リスト（List）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3836016/55f8067c-dee8-0b34-9825-b9d681278c44.png)


# リスト（List）

## リストとは？

リストは、Pythonで複数の項目を格納することができるデータ構造です。角括弧 `[ ]` 内にカンマ `,` で区切って値を並べて作成します。

```python
>>> family = ['mother', 'father', 'boy', 'girl']
```

上記の例では、`family` は文字列を要素とするリストです。各要素はインデックスを使ってアクセスすることができます。

## リストの長さ（len）

リストの長さは、`len()` 関数を使用して確認することができます。例えば、`family` リストの長さは以下のようにして確認できます。

```python
>>> len(family)
4
```

`len()` 関数はリスト内の要素数を返します。

## リストのインデックス(Indexing)

リストはインデックスを使って各要素にアクセスできます。Pythonのインデックスは0から始まります。例えば、`family` リストから 'boy' を取得するには、次のようにインデックスを使用します。

```python
>>> family[2]
'boy'
```

ここで `family[2]` はリストの3番目の要素を示します。

## リストから要素を削除する（remove）

特定の要素をリストから削除する場合は、`remove()` メソッドを使用します。例えば、'boy' を削除してみましょう。

```python
>>> family.remove('boy')
>>> family
['mother', 'father', 'girl']
```

上記のコードでは、`remove('boy')` はリスト内の 'boy' という値を持つ要素を削除します。

これで新しいリストを作成してみてください！リストはPythonで効率的に多くのデータを扱うための重要なデータ構造です。
スマートカードと通信するには

## はじめに
スマートカードには接触型と非接触型の2種類があります。
最近スマートカードに関する開発を担当し、NFCの規格や仕様を調べる機会がありました。
この記事では非接触型のスマートカードとどうやって通信するのかを紹介します。

## NFC
非接触型のカードはNFC ( Near Field radio Communication )という近距離無線の通信規格が用いられます。
NFCフォーラムには国際標準規格ISO/IEC 14443 Type-A, Type-Bや、ISO/IEC 18092にもとづくType-Fなどの規格があり、クレジットカード、マイナンバーカード、免許証、交通系ICなどの様々なカードに用いられています。

### ATR
ATRとはAnswer To Resetの略で、カードが端末によってリセットされた際に一連のデータを応答として送信します。ATRの情報からカードとの通信プロトコルを決定します。Type-Aのカードから得たATRを下記に示します。
```
ATR: 3B 80 80 01 01
```
1バイト目はTSと呼ばれるキャラクタで、後続キャラクタの符号を決定します。
3Bの場合はLSBから順にデータが送信され、3Fの場合はMSBからデータが送信されます。
ほとんどのカードは3Bが推奨されるそうです。

2バイト目はT0と呼ばれ、このキャラクタの値によってATRの残りのキャラクタが決定されます。上位4ビットによってTA1、TB1、TC1、またはTD1の有無が決まり、5ビット目からTA1、TB1、TC1、TD1の順に対応しています。
今回、上位4ビットは"1000"であるのでTD1のみ存在します。
また、下位4ビットによってヒストリカルバイトの数を決定します。ヒストリカルバイトとは、カードの総合的な情報で、カードの種類によって送信される情報が違います。Type-AのカードではATS(Answer To Select)、Type-BのカードではATQB(Answer To reQuest for PICC B)となります。今回は"0"であるので、ヒストリカルバイトが存在しません。

3バイト目はTD1となります(T0によって決定)。上位4ビットによってT0と同様に、TA2、TB2、TC2、TD2の有無を決定します。今回は"1000"であるのでTD2のみ存在します。
また、下位4ビットは通信プロトコルを決定し、"0"であればT=0、"1"であればT=1となります。T=0はキャラクタベース、T=1はブロックベースとなるそうです。今回はT=0となります。

4バイト目はTD2となります。TDx(xは0以上の整数)はすべて同様の仕様であるので、この場合、以降のキャラクタは存在せず、T=1となります。

5バイト目はTCKと呼ばれるチェックキャラクタで、最初のキャラクタ(TS)からTCKまでの排他的論理和が"0"となるような値をとります。

ATRについての詳細は下記のサイトにあります。
[密着型ICカードの実装規約](https://www.nmda.or.jp/nmda/ic-card/iso10536/sec4.html)

### APDU
スマートカードとデータ通信する際に、APDUコマンドというものがよく使われます。
APDUとはApplication Protocol Data Unitの略で、スマートカードと通信するための規格です。
カードリーダなどのデバイスからカードに送信するAPDUをCommand-APDU、カードからデバイスに返信されるAPDUをRespons-APDUといいます。下記のサイトで詳しく解説されています。
[APDU (Application Protocol Data Unit) プロトコル](https://smartcardguy.hatenablog.jp/entry/2018/08/11/153334)

## 通信デバイス
NFCとやり取りするには通信デバイスが必要です。PC/SC Win32APIに対応したカードリーダを使うと、APIを使ってカードとやり取りすることができます。

## APDUでデータのやり取り
実際にデータのやり取りをしてみます。再度Type-Aのカードを使いました。
R-APDUの末尾が"9000"でコマンド成功となります。
```
C-APDU: 80CA00E000
R-APDU: e012c00401018010c00402018010c004030180109000
```
C-APDUのパラメータをE0とすることで、選択中アプリのKey Informationを取得できます。
R-APDUの内容は[GlobalPlatform Card Specification 2.2.0.7](https://globalplatform.org/wp-content/uploads/2018/06/GPC_Specification-2.2.1.pdf)の11.3.3.1に書いています。

レスポンスはTLV構造となっていて、1バイト目はテンプレートE0を返し、タグはC0となっています。データ部の"01 01 80 10"はそれぞれ、ID: 01、Version: 01、KeyType: DES(80)、LEN:16となります。
全部で3つあるので、まとめると
ID: 01、Version: 01、KeyType: DES(80)、LEN:16
ID: 02、Version: 01、KeyType: DES(80)、LEN:16
ID: 03、Version: 01、KeyType: DES(80)、LEN:16
となります。なぜ3つ並んでいるのかはよく分かりません。3つでトリプルDESということでしょうか("81"がTripleDESなので違う気がする)。

## まとめ
無事にスマートカードと通信することができました。スマートカードは暗号方式にトリプルDESを採用していることが多いようですが、FelicaはAESも採用しているらしいです。他にもカードによって、製造元の情報なども確認することができます。
nodejsでTwitter APIを使って画像付きでツイートするメモ

## はじめに
nodejsで画像付きのツイートを調べてみる。
色々サイトを参考にするが、意外と動かない。
Twitter APIの1.1と2.0が混在していて何がなんだか。aiに聞いてもぐふわふわしちゃう。

要するに画像のアップロードは1.1じゃないとできない。
だけど、ツイート1.1ではできず、2.0じゃないとできない。

1.1でアップロード。アップロードが完了するとmedia idを発行してくれる。
そのmedia idをつけて2.0でアップロードという方法らしいです。


``` twitterManager.ts
import {TwitterApi, TwitterApiReadWrite} from 'twitter-api-v2';
export class TwitterManager {
    constructor() {
    }
    public tweet = async (message:string, filePath:string):Promise<void> =>
    {
        const client:TwitterApi = new TwitterApi({
            appKey: process.env.API_KEY,
            appSecret: process.env.API_KEY_SECRET,
            accessToken: process.env.ACCESS_TOKEN,
            accessSecret: process.env.ACCESS_TOKEN_SECRET,
        });
        const twitterClient:TwitterApiReadWrite = client.readWrite;
        try {
            const mediaId:string  = await twitterClient.v1.uploadMedia(filePath);
            await client.v2.tweet(
                { text: message, media: { media_ids: [mediaId] } }
            );
        } catch (e) {
            console.log(e)
        }

    }
}

```

## まとめ
twitter api2.0で画像をアップロードする準備しているようです。
この話もいつまで持つことやら。
一気に両方送れた方がいいよね。

## 参考
Make a Twitter bot with Node.js and the v2 Twitter API in under 20 minutes
https://www.youtube.com/watch?v=LCydSB7JcHw
[Python] 変数

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3836016/045c4edf-0a70-49ef-9eaa-c79f6768a0e3.png)


# 変数（Variables）

## 変数とは？

変数とは、値が保存される空間を指します。プログラミングにおいても、変数は値やデータを保持するために使用されます。例えば、数学での変数と同様に、値を代入して必要な時に使用することができます。

## 整数値を指す変数

例えば、私の時計が10万円だと仮定してみましょう。

```python
>>> watch = 100000
```

ここで `watch` は時計の価格を表す変数です。同様の方法でライターの価格も変数として設定することができます。

```python
>>> lighter = 300
```

## 変数を使った数値の計算

さて、時計とライターの価格を足してみましょう。

```python
>>> watch + lighter
100300
```

コンピュータは、変数に割り当てられた値をもとに迅速に計算を行うことができます。

## 変数の値を変更する

変数に別の値を割り当てることもできます。例えば、時計の価格を100万円に変更してみましょう。

```python
>>> watch = 1000000
```

これで `watch` 変数は100万円を指すようになります。

## 割引計算する

時計を15%割引して購入する場合、価格はいくらでしょうか？

```python
>>> watch * 0.85
850000.0
```

15%割引された価格を計算することができます。

## 文字列を指す変数

変数は数字だけでなく、文字列も保存することができます。例えば、文字列 'pig' と 'dad' を変数に保存してみましょう。

```python
>>> a = 'pig'
>>> b = 'dad'
```

文字列変数を連結してみましょう。

```python
>>> a + b
'pigdad'
```

そして、スペースを追加して文字列を結合すると次のようになります。

```python
>>> a + ' ' + b
'pig dad'
```

このように変数を活用すると、文字列を操作したり結合したりするなど、さまざまな作業を行うことができます。

以上が変数に関する簡単な紹介です。変数はプログラミングにおいて非常に重要であり、さまざまなデータを扱う際に便利に使用されます。
Astroをビルド後もいじいじしたい話

Astroで作ったプロジェクトにて、ビルド後のファイルに変更を加えたり内容を確認したりすることがあります。そうなった際ファイルに改行がなかったり階層分けされていなかったりしたらとても不便です。
私は不便だった場合もありました。~~(ありません)~~
## Viteの設定
まずは設定で改行ありにします。改行とインデントがあるだけでコードはとても読みやすいです。早速`astro.config.mjs`に以下のように追記します。
```js
export default defineConfig({
  vite: {
    build: {
      minify: false,
    },
  },
  conpressHTML: false,
}
```
このようにすることで、`minify: false`によってCSSやJSなどのファイルの改行が追加されます。どちらかというと、改行を消す処理をなくす設定ですね。
## Compressの設定
`@playform/compress`も改行を無くす処理をするので、使用している場合は特定のファイルのみ処理しないように設定します。
```js
  integrations: [
    playformCompress({
      CSS: false,
      HTML: false,
      JavaScript: false,
    }),
  ],
```
今回はHTML,CSS,JSの改行を見たいので、上のような設定がいいです。場合によって変更しましょう。

## 黒魔術(おまけ)
これで正しく改行ありのファイルが生成されるはずですが、なぜかHTMLファイルのみ改行がほとんどなく、数行に収まっています。
調べてみましたが解決策なるものは見つからず、結果的にPrettierで強制的に整形することにしました。悪手であることに間違いありませんので、正しい方法を現在模索中です。
### `scripts`追加
packages.jsonに以下の内容を加えます。
```json
"scripts": {
  "build": "astro check && astro build && prettier --write ./dist/**/*.html",
},
```
### `ignore`ファイル
これだけだとdistディレクトリが.gitignoreに含まれている影響でPrettierは`dist`ディレクトリを整形できません。なので.gitignoreをコピーして.prettierignoreを作成し、そこからdistディレクトリの指定を削除します。
なぜか.gitignoreが優先されてしまうので、先程のPrettierコマンドの最後に`--ignore-path .prettierignore`と引数を増やすことで、ようやくdistディレクトリを整形できます。
```diff_json
"scripts": {
-  "build": "astro check && astro build && prettier --write ./dist/**/*.html",
+  "build": "astro check && astro build && prettier --write ./dist/**/*.html --ignore-path .prettierignore",
},
```
## 階層分け
次にファイルの階層分けをします。今の時点でも十分扱いやすいですが、プロジェクトが大きくなってくるとわかりにくくなります。
そのために`astro.config.mjs`の中の`vite.build`に以下の設定を加えてください。
```js
rollupOptions: {
  output: {
    assetFileNames: (info) => {
      const fileType = info.name.split(".").pop().toLowerCase();
      const imageTypes = ['png', 'jpg', 'jpeg', 'svg', 'gif', 'tiff', 'bmp', 'ico'];
      const scriptTypes = ["js", "ts"];
      const styleTypes = ["css", "scss"];
      
      const category = imageTypes.includes(fileType) ? "images/" :
                       scriptTypes.includes(fileType) ? "script/" :
                       styleTypes.includes(fileType) ? "css/" : "";
                       
      return `assets/${category}[name]-[hash][extname]`;
    },
  },
},
```
諸注意としてこれらの設定をするとビルド後のファイルサイズが多少増加してしまいます。
あと三項演算子もりもりのキモイコードになっているのは、私が宗教上の理由で`let`が使えないからです。

:::note warn
これにより認識したファイル形式によってディレクトリ整理がされます。この設定は私がサクッと作ったもので、決して常用しているわけではないのでバグ等にご注意ください。
:::
Rubyでキーワードによって処理を変えたい時、そのキーワードは文字列ではなくシンボルで表現しよう


以下のように特定のキーワードによって処理を変えたいメソッドがあったとします。


```ruby
# time_of_day(時間帯)によって適切な挨拶を返すメソッド
# time_of_dayの値は morning, night, daytime の3つ
# morningの場合はgood morning
# nightの場合はgoodbye
# daytimeの場合はhello を返す
#
def greeting(time_of_day)
  case time_of_day
  when 'morning'
    'Good morning'
  when 'night'
    'Goodbye'
  when 'daytime'
    'Hello'
  else
    'Invalid time of day'
  end
end

# メソッドのテスト
puts greeting('morning')  # => Good morning
puts greeting('night')    # => Goodbye
puts greeting('daytime')  # => Hello
puts greeting('evening')  # => Invalid time of day
```

このtime_of_dayの値によって処理を分けている所で、もし引数の値がアプリケーションの外からの入力値になるので文字列でないといけないなどの特別な理由が限り、文字列ではなくシンボルを使った方がいいよという話です。

```ruby
def greeting(time_of_day)
  case time_of_day
  when :morning
    'Good morning'
  when :night
    'Goodbye'
  when :daytime
    'Hello'
  else
    nil
  end
end

# メソッドのテスト
puts greeting(:morning)  # => Good morning
puts greeting(:night)    # => Goodbye
puts greeting(:daytime)  # => Hello
puts greeting('evening')  # => nil
```

理由は単純で、文字列としての機能が必要ないのであれば、シンボルの方が効率的だからです。

# シンボル(Symbol)は同じ値は同じオブジェクト、文字列は違うオブジェクト

Helloという同じ値の文字列と同じ値のシンボルのobject_idを確認した場合のキャプチャが以下になります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/26205/3202b6b4-f97e-1cf3-0acd-73c2252fabef.png)

このように`'Hello'`は実行するたびにobject_idが違う、つまり違うオブジェクトを毎回生成しているということですが、`:Hello`は同じobject_idなので、一度作ったものを再度使い回していることがわかります。
このコードがプロセスを立ち上げた後に100万回実行されたら100万個分のメモリが必要になるか、一個で済むかでメモリ使用量は大きく変わってしまいます。


# オブジェクトで利用するメモリ量もシンボルの方が格段に少ない

`ObjectSpace`というモジュールを使うとそのオブジェクトで利用しているメモリサイズがわかるので、それを使って文字列とシンボルのメモリサイズを比較してみます。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/26205/d789c44b-832c-59bd-f50a-502cb0f5c888.png)

`memsize_of`というメソッドは引数で与えられたオブジェクトのメモリサイズをByteの整数(Integer)で返すメソッドです。

同じことを表現している文字列とシンボルでもメモリ使用量が大きく違いますし、文字数が増えると文字列の場合はそれに合わせてメモリ利用量も増えますが、シンボルは変わりません。

これはシンボルが内部的には数値と同じ扱いになっているためかなり軽量になっているようです

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/26205/2e5ec27b-ba57-2d69-5a6e-0f85429c7cdc.png)

# まとめ

このようにシンボルと文字列はメモリ使用量において大きな差があり、シンボルで事足りる場合はシンボルを使った方が効率的になります。

正直シンボルでもいいところを文字列にしたところで、バグは出ないだろうしGCも発達しているのでこれが原因でアプリケーションに問題が出るようなことはほぼないと思います。

しかしアプリケーションを運用していてメモリ使用量が大きくなってきたときにコードを精査してこの修正を加えていくのはかなり面倒臭いので、息を吸うように使い分けできるようになるのがいいかなーと思います。

# 一緒にCBcloudで働いてくれる人募集！！！
私は現在CBcloudという、新しい配送インフラを作っていくことを目指す会社に所属して、日々Rubyでその配送インフラの実現のためにコードを書いています。

この記事は業務時間中に書いているので、それはつまり Sponsered by CBcloud のようなものなので宣伝です！

CBcloudで、一緒にRubyで新しい配送インフラを作ってくれる人を募集しているのでご興味のある方はぜひ採用サイトを覗いてみてください！


https://recruit.cb-cloud.com

沖縄オフィスもありまして、沖縄オフィス用の採用サイトもあるのでそちらも是非是非！

https://recruit-okinawa.cb-cloud.com/
chart.jsを利用してみる

# はじめに
rails7にグラフ(chart.js)を適応させた際の備忘録です

# 実装
毎度定番のstimulus-componetsにchart.jsがあったので、それを利用します

https://www.stimulus-components.com/docs/stimulus-chartjs

```
yarn add @stimulus-components/chartjs
```

```javascript:app/javascript/controllers/index.js
import Chart from "@stimulus-components/chartjs";
application.register("chart", Chart);
```

```erb:app/views/charts/index.html.erb
<canvas
  data-controller="chart"
  data-chart-data-value="<%= @chart_data.to_json %>"
  data-chart-options-value="<%= @chart_options.to_json %>"
></canvas>
```

```rb:app/controllers/charts_controller.rb
  def index
    @chart_data = {
      labels: (Date.today.prev_year..Date.today).select { |day| day.day == 1 }.map { |a| a.strftime('%Y/%m') },
      datasets: [{
        type: 'line',
        label: 'スコア1推移',
        data: [26, 18, 63, 26, 61, 10, 46, 27, 23, 98, 39, 20],
        borderColor: '#F08080',
        backgroundColor: '#F08080',
        yAxisID: 'y'

      }, {
        type: 'line',
        label: 'スコア2推移',
        data: [71, 25, 69, 100, 97, 14, 47, 13, 86, 48, 33, 72],
        borderColor: '#6495ED',
        backgroundColor: '#6495ED',
        yAxisID: 'y'
      }, {
        type: 'line',
        label: 'PV数',
        data: [709, 678, 778, 23, 509, 541,
               666, 505, 563, 104, 972, 324],
        borderColor: '#008000',
        backgroundColor: '#008000',
        yAxisID: 'y1'
      }]
    }

    @chart_options = {
      responsive: true,
      scales: {
        y: {
          type: 'linear',
          display: true,
          position: 'left'
        },
        y1: {
          type: 'linear',
          display: true,
          position: 'right',
          grid: {
            drawOnChartArea: false
          }
        }
      }
    }
  end
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3632357/3cef74bf-e8d1-82c4-ab6c-2b8c99461fd3.png)

以上！

# さいごに
実装そのものはサクッとできたのですが、グラフを弄る際にV2、V3、V4で書き方が異なるため、迷走していました。
調べてみたところ、「stimulus-chartjs」では、以下の最新が割り当てられてましたので、公式のページを参照するのが一番でした(2024/7/12時点)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3632357/483da34f-f55a-d5cf-365f-c9f0d3a32de1.png)

https://www.chartjs.org/docs/latest/

もし、ご利用される際はご注意ください。
timestamp with timezone ⇔ timestamp の変換はcast asではなくat time zone演算子で

timestamp with timezone と timestamp
----
PostgreSQLの日付時刻型をおさらいしましょう。
- **timestamp with timezone**
絶対時刻を保持している型です。名前にはちょっと反して、タイムゾーン情報は持っていません。
- **timezone**
正しくはtimestamp without timezone。
どこのタイムゾーンのものとも限らない年月日時分秒を保持している型です。タイムゾーンが決まっていないゆえ、いつの瞬間を指しているとは定まりません。

timestamp with timezone ⇔ timestamp の相互変換
---
SQLを書いていれば、timestamp with timezone型とtimestamp型のカラムを比較しないといけないシーンが出てくることがあるかもしれません。もしくは、取得した後のアプリロジック側の都合で絶対時刻であるか日本時間時刻であるか決まっていてそれにあわせに行く必要があるかもしれません。そういうときに型変換が発生します。

たとえばDBには日本時間の日時がtimestamp型で入っているとしますが、それを読み出すアプリでは絶対時刻値が必要というケース
```sql
SELECT
  cast(some_timestamp as timestamp with timezone) as some_timestamptz,
  ...
```
このようにcast構文を使うと一見正しく変換できて動いてくれてしまいます。

「日本時間で」という情報がどこにも与えられていませんが、PostgreSQLは何かの設定からこの文脈は日本時間であるということを知って、ちゃんと日本時間日付時刻を読み取って絶対時刻にしてくれます。つまりデフォルトタイムゾーンがあるってことですね。

そしてこの「何かの設定から」が非常にハイリスクなのです。

これはちょうど10年前、PostgreSQLが9.1から9.2にバージョンアップしたときにconfファイルにtimezoneが未設定だったときに設定されるデフォルトタイムゾーンが変わってしまいました[^1]。私もこの影響の対応でずいぶん大変な思いをしたものです⋯

マイナーバージョンアップした程度でクエリの意味が9時間変わってしまうのは恐ろしいことですね。タイムゾーンを暗黙でわかってもらうのではなく、明示して変換するように書いてみましょう。それは`at time zone`構文を使ってこう書きます。

```sql
SELECT
  some_timestamp at time zone 'Asia/Tokyo' as some_timestamptz,
  ...
```
この`at time zone`構文、timestamp型に対して使うとtimestamp with timezone型を返しますし、逆にtimestamp with timezone型に対して使うとtimestamp型を返すおもしろい定義になっています。

そして、この例では`Asia/Tokyo`と都市名指定のタイムゾーンで変換していますが、時間幅指定の`+09:00`を使いたい場合はちょっと記法に注意が必要です。（`Asia/Tokyo`表記があるのにわざわざ`+09:00`と表記するケースがあるものかについては <a href='https://qiita.com/yuba/items/e087b81ea23917d2f2c0'>別記事に書きました</a>）

```sql
× some_timestamp at time zone '+09:00'
○ some_timestamp at time zone interval '+09:00'
```
`interval` キーワードを置いてinterval型として与える必要があります。これを忘れるとどうなるかはドキュメントに記載が無いですが、実際にやってみると（PG 15.3）⋯　恐ろしいことに、エラーになるのではなくてなんと9時間足すはずが引いてしまうという正反対の動作をしてくれました⋯！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2852/f6fc5cd9-b9c8-fc5f-b086-26ed820a3579.png)



[^1]:未記述だった場合にはOSのTZ環境変数をとるようになっていたのが、GMT固定に変わった。その代わりに起動時にOSのTZ環境変数値をconfに自動で書き込んでくれる仕様も盛り込まれたのだが、confファイルをansibleなんかで管理しているとこの自動書き込みは上書きされて消えてしまうことに。
#シンクライアント端末とファットクライアント端末とは？（；・∞・）

## はじめに
IT業界を未経験で転職したずんだ餅です！
今回はキッティングの現場で触れる機会があり
初めて耳にした端末2種類について書かせていただきます。
すでに知っている方は温かい目で見守ってください〜
## シンクライアント端末とは？( 一一)
シンクライアントとはサーバー側でほとんどのファイルやアプリケーションなどの資源を管理することで必要最低限の記憶媒体やアプリケーションしかもたせてないクライアントコンピューターのことを指します。
簡単にまとめると
### 管理者側:cop:から機能制限された端末
という事ですね。

#### なぜそのような制限をするのかというと‥
クライアント側にデータを持たせないことによって、
「機密情報や顧客情報の漏洩を防止できる」セキュリティ面のメリットにつながるからです。
最近の企業情報システムではシンクライアント端末を導入し始めています。
また、ほかにも安価で導入できるというメリットもあります。
## ファット端末（ファットクライアント端末）とは？(+_+)
ファットクライアントとは、クライアント側で処理を実行するための記憶媒体やアプリケーションなどの環境を全て備えたコンピューターのことを指します。
皆さんがイメージしやすい
### 一般的なパソコン:keyboard:
のことですね！

ブラウザやオフィスツール、メールクライアントなど、様々なアプリや機能を実装しているため値段も高価になります。
これらの端末は以前まで、【クライアント】【パンコン】などと呼ばれていましたが、
「シンクライアント」が普及してからは区別するために「ファットクライアント】と呼ばれるようになりました。
個人が所有するパソコンはアプリケーションを端末にインストールして使ったり、データを保存したりするので、「ファットクライアント」ということになります。
## おわりに
初投稿とのこともあり何を書いたらいいのか分かりませんでしたが聞く人みんなからなんでもいいのよ！と言われたのでチャレンジしてみました。
IT業界初心者の自分が頭の中でイメージしやすいように記載しています:writing_hand:
これからも苦手なアウトプットを積極的に取り組めるように投稿していきたいと思います。

ご一読いただき、ありがとうございます:clap:
一緒に見習いエンジニアからレベルアップしていきましょう:muscle:
Databricks Certified Machine Learning Professionalに合格しました！

これで3つ目。

![](https://api.accredible.com/v1/frontend/credential_website_embed_image/certificate/108673218)

https://qiita.com/taka_yayoi/items/08be162d451126d4b54b

https://qiita.com/taka_yayoi/items/8c73be3176cc7e8626a0

# 試験概要

https://www.databricks.com/learn/certification/machine-learning-professional

Databricks Certified Machine Learning Professional資格試験では、プロダクションのタスクにおいて高度な機械学習を実行するために、Databricksの機械学習に関する機能を活用する個人の能力を評価します。これには、機械学習エクスペリメントの追跡、バージョン管理、管理するための能力、機械学習エクスペリメントの管理、機械学習モデルのライフサイクルを管理する能力が含まれます。さらに、この試験では、機械学習モデルのデプロイのための戦略を実装する能力も評価します。最後に、受験者はデータドリフトを検知するためのモニタリングソリューションを構築する能力も評価されます。この試験に合格した人は、Databricks機械学習を用いた機械学習エンジニアリングタスクを実行できることが期待されます。

この試験では以下をカバーします:

1. 実験 - 30%
1. モデルライフサイクル管理 - 30%
1. モデルのデプロイメント - 25%
1. ソリューションとデータのモニタリング 15%

# 試験の詳細

**タイプ:** 監督官付きの試験
**問題数:** 60
**時間制限:** 120分
**登録費用:** 200ドル
**質問タイプ:** 選択式
**テスト支援:** 許可しない
**言語:** 英語
**提供方法:** オンライン監督
**前提条件:** なし、しかし、関連トレーニングを強く推奨
**推奨される経験:** 試験ガイドで説明されている機械学習タスクを実行する1年以上のハンズオンの経験
**有効期限:** 2年

# 関連トレーニング

インストラクター付きトレーニング: [Machine Learning in Production](https://www.databricks.com/learn/training/catalog/ml-production)
セルフペース(Databricks Academyで受講可能): Machine Learning in Production

## 試験の準備

1. 試験に何が出題されるのかを理解するために、[Machine Learning Professional Exam Guide](https://www.databricks.com/sites/default/files/2024-05/databricks-certified-machine-learning-professional-exam-guide.pdf)を確認する
1. 関連トレーニングを受講する
1. 試験に登録する
1. [technical requirements](https://kryterion.my.site.com/support/s/article/Online-Testing-Requirements?language=en_US)を確認し、[system check](https://www.kryterion.com/systemcheck/)を実行する
1. ギャップを特定するために再度試験ガイドを確認する
1. ギャップを埋めるために勉強する
1. 試験を受ける！

# 登録

[exam delivery platform](http://webassessor.com/databricks)から登録

# 所感

他の方も言われていたように、Data Engineer Professionalよりは難しくはありませんでした。しかし、Databricks AcademyでMachine Learning in Productionを受講することを強くお勧めします。

[ガイド](https://www.databricks.com/sites/default/files/2024-05/databricks-certified-machine-learning-professional-exam-guide.pdf)にあるように、この辺りを一通り触る必要はあるかと思います。

- MLflow(Tracking/Models/Projects/Model Registry)
- Model RegistryのWebhook
- Feature Store

### はじめてのDatabricks

[はじめてのDatabricks](https://qiita.com/taka_yayoi/items/8dc72d083edb879a5e5d)

### Databricks無料トライアル

[Databricks無料トライアル](https://databricks.com/jp/try-databricks)
論文読み：WALT3D: Generating Realistic Training Data from Time-Lapse Imagery for Reconstructing Dynamic Objects under Occlusion

## WALT3D: Generating Realistic Training Data from Time-Lapse Imagery for Reconstructing Dynamic Objects under Occlusion

CVPR 2024 (Oral, Top 0.8%)
[論文](https://openaccess.thecvf.com/content/CVPR2024/html/Vuong_WALT3D_Generating_Realistic_Training_Data_from_Time-Lapse_Imagery_for_Reconstructing_CVPR_2024_paper.html)
[project page](https://www.cs.cmu.edu/~walt3d/)
[github](https://github.com/kvuong2711/WALT3D)

## 概要
WALT3Dは、固定カメラからのタイムラプス画像を利用して、遮蔽された状況下でも動的な物体の検出やセグメンテーションを高精度に行う新しい手法を提案している．
従来の手法では、都市環境などで頻繁に発生する遮蔽に対して十分な対応ができていなかったが、この研究では、リアルなデータと合成データの双方の利点を活かし、固定カメラで長期間撮影されたタイムラプス画像を利用することで、遮蔽が発生しない物体を自動的に収集し、これを用いて合成的に遮蔽シナリオを生成する手法を開発.

## 従来手法との比較
従来の物体検出やセグメンテーション手法は、遮蔽が発生する場面での性能が低下しやすいという問題があった．特に、COCOやImageNetのような大規模データセットでも、遮蔽された物体のラベル付けが十分に行われておらず、その結果、遮蔽に対するロバスト性が学習されにくいという課題が存在した．
また、合成データを用いた手法では、リアルなデータとのドメインギャップが問題となり、現実のシナリオに適用する際の精度が低下していた.


## 新規性
WALT3Dの新規性は、長期間にわたる固定カメラのタイムラプス画像を利用して、遮蔽が発生しない物体を自動的に収集し、これを用いて遮蔽シナリオを合成的に生成する点にある．この手法により、リアルなデータに近い形で大量の遮蔽データを生成することが可能となり、遮蔽に対するロバスト性を大幅に向上させることができる．また、時間をかけて収集された無遮蔽の物体データを利用することで、遮蔽された物体の学習を効率化し、短期間での学習が可能となっている

## WALT2Dからの進化点
### 1. 3Dベースの合成手法
WALT2Dでは2D画像の合成によって遮蔽シナリオを生成していたが、WALT3Dでは3Dベースの合成手法を導入している．遮蔽の配置がより現実的になり、学習データの品質が向上している．

### 2. 無遮蔽物体の再構築
WALT3Dでは、タイムラプス画像から無遮蔽の物体を自動的に検出し、その3D形状と姿勢を再構築する．このプロセスは、カメラの内部パラメータと地面平面を利用して行われ、物理的に妥当な再構築が可能となっている．

### 3. Pseudo-groundtruthの生成
WALT3Dでは、既存のオフ・ザ・シェルフ手法を利用して生成された3D形状や姿勢、セグメンテーション、キーポイントなどをpseudo-groundtruthとして使用している．これにより、大量のラベル付きデータを生成することができ、人手によるアノテーションの必要性を大幅に削減している．

### 4. 高品質な訓練データの生成
WALT3Dのアプローチにより、訓練データの質が向上している．物理的に正確な遮蔽配置が可能となったことで、訓練データが現実のシナリオにより近くなり、モデルの学習効率が向上している．WALT2Dでは、このような高品質な訓練データの生成は難しかった．

### 5. データ効率の向上
WALT3Dは、同じ量の訓練データであっても、より高い性能を引き出すことができる．WALT2Dと比較して、WALT3Dを使用することで、少ないデータ量でも高いパフォーマンスが得られる．

## 方法論
- **無遮蔽物体の収集**: 固定カメラのタイムラプス画像から、長期間にわたり無遮蔽の物体を検出・収集する．これは、同じ地平面上にある物体が互いに遮蔽する際のバウンディングボックスの重なりを利用して行われる
- **合成的な遮蔽シナリオの生成**: 収集された無遮蔽の物体を用いて、同じシーン内で重ね合わせることで、現実に近い形の遮蔽シナリオを生成する．この合成データは、ディープラーニングネットワークのトレーニングに利用される
- **Amodalセグメンテーションの学習**: 合成データを用いて、物体の遮蔽状況下でも正確に検出・セグメンテーションができるAmodalネットワークを学習する．これにより、物体の全体的な表現を学習し、遮蔽が発生している場合でも正確なセグメンテーションが可能となる

## 結果と評価
この手法を用いることで、歩行者や車両の検出・セグメンテーション精度が大幅に向上し、遮蔽が増加しても性能の低下が緩やかであることが確認された．特に、遮蔽が発生する場面でのトラッキング性能が向上し、実際の交通監視などのアプリケーションでの有用性が示された
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2323577/0d903e38-b3fb-3743-dc0b-a1c761cd587e.png)

:::note info
従来手法（WALT 2D）では不自然な合成画像が生じていたが、奥行き方向の情報も加味することでより自然な画像を作成することに成功！
:::

## 結論
WALT3Dは、固定カメラからのタイムラプス画像を利用して、物体の遮蔽状況下でも高精度な検出・セグメンテーションを実現する新しい手法を提案している．この手法により、従来の手法では難しかった遮蔽に対するロバスト性を大幅に向上させることができる．今後は、この手法を自動運転などの新しい応用分野に展開することが期待される