OmniAICreator/Qiita-1.07M huggingface dataset:
C++ メモ

## C++ について
### C++
- 1983年に開発されました。
- C++で開発したプログラムは処理速度が速く、また、大規模なソフトウェアの開発にも使えます。
- コンパイル: $ g++ 実行ファイル名
- プログラムの実行: $ ./実行ファイル名
- [公式ドキュメント](https://docs.microsoft.com/ja-jp/cpp/cpp/cpp-language-reference?view=msvc-160)
- [GitHub](https://github.com/topics/cpp)

## 開発ツールについて
### Unreal Engine
- Epic Gamesより開発されたゲームエンジンである。
- 1998年にファーストパーソン・シューティングゲーム である『Unreal』で初めて実装されました。
- Unreal Engineのコア部分はC++で記述されている。
- Unreal Engineは高レベルの移植性という特徴があり、iOS、Android、Nintendo Switch、PlayStation 4、Xbox Oneなどをサポートしている。 
- 多くのゲームコードはC++やプロプライエタリなスクリプト言語であるUnrealScriptで 記述され、ゲームの大部分はエンジン内部を深く探求せずに改良できる。 
- 加えて、他のミドルウェアと共に使用するとき、コンテント作成においてゲームデザイ ナーとアーティストの両方を支援する様々なツールも提供している。
- [公式サイト](https://www.unrealengine.com/ja/)

## C++フレームワークについて
### TreeFrog Framework
- TreeFrog FrameworkとはC++に活用される日本製のフルスタックなWebアプリケーションフレームワークです。
- サーバーサイド用のフレームワークとしてプログラミング言語はC++、フレームワークはQtで開発されました。
- 特徴として「高パフォーマンス」「O/R マッピング」「多くのDBに対応」などが挙げられます。
- アップデートの周期も３ヶ月に１度以上実施されており安心して使用することができます。
- [公式サイト](https://www.treefrogframework.org/ja/)

### Qt
- QtとはC++に活用されるクロスプラットフォームアプリケーションフレームワークです。
- リッチなGUIを表現し、高い生産性を実現することができることから高い人気を集めております。
- 特徴として「美しいインターフェイスを作成」「強力なツールを使用したコード」「すべてのプラットフォーム向けに構築 」などが挙げられます。
- 公式サイトは日本語ドキュメントへの対応もしっかりと行われているため安心して利用することができます。
- [公式サイト](https://www.qt.io/ja-jp/)

### Qat++
- Oat++とはC++に活用される非常にスケーラブルでリソース効率の高いWebフレームワークです。
- ネイティブコードであるため動きも早く、他のライブラリにも依存しないということから使いやすいという声が多く愛されております。
- その他の特徴として「5M接続の処理」「コードの一貫性を保つ」などが挙げられます。
- [公式サイト](https://oatpp.io)

### Crow
- crowとはC++に活用されるマイクロWebアプリケーションフレームワークです。
- Python用のフレームワークであるFlaskのようにコーディングできることが売りで注目を集めております。
- 軽量な設計であるため、非常に高速で使いやすいのが特徴です。
- [Github](https://github.com/ipkn/crow)
Fastly Compute (旧 Compute@Edge) 一人アドベントカレンダーの目次

:::note warn
本記事は 1 年以上前に執筆された旧版の記事であり、最新版(2024年版)のアドベントカレンダーは以下 URL にて公開されていることに注意してください。
https://qiita.com/remore/items/3e1567f04348e88339a2
:::

この記事は Fastly Compute (旧 Compute@Edge) 一人アドベントカレンダー 1 日目の記事です。Fastly Compute についての基礎知識や機能、便利な使い方などについて日本語で網羅的に理解できる情報源が見当たらなかったので、最新情報を交えながら自分の執筆体力の続く限り書いてみたいと思います。

初回となる本稿では今回のアドベントカレンダーで投稿する予定の記事を一覧で紹介します。

### 目次
- Fastly Compute (旧 Compute@Edge) について
  * [一人アドベントカレンダーの目次](https://qiita.com/remore/items/9d8a69c34a8655e37ac6)
  * [2018~2023年までの主な出来事](https://qiita.com/remore/items/1441e4883a20503aaf6e)
  * [国内外の関連記事・情報のメモ書き](https://qiita.com/remore/items/509b6c9a71a5b91d2960)
- Fastly Compute 開発の基礎
  * (1) [アカウントの準備とリソース制限の理解](https://zenn.dev/remore/articles/85f333600e9571)
  * (2) [はじめてのビルドとデプロイ（Go編）](https://zenn.dev/remore/articles/2b330f91351a6a)
  * (3) [はじめてのデバッグ](https://zenn.dev/remore/articles/90ea9e3e002401)
  * (4) [Fiddle で手軽に動作を確認する](https://zenn.dev/remore/articles/50a39ee11c7e0e)
- Fastly Compute の主な機能と SDK の役割
  * (1) [基本的な仕組み](https://zenn.dev/remore/articles/87426b7cca9d7b)
  * (2) [SDK を通して使える機能](https://zenn.dev/remore/articles/df32f19c98d18c)
  * (3) [各 SDK の特徴 <前編: Rust, Go>](https://zenn.dev/remore/articles/ef21f118592cb1)
  * (4) [各 SDK の特徴 <後編: JavaScript>](https://zenn.dev/remore/articles/2cd7234f1d2194)
  * (5) [Wasm ABI で定義される Hostcall](https://zenn.dev/remore/articles/89fe46134eb5fb)
- HTTP リクエストの作成
  * (1) [Static/Dynamic バックエンド](https://zenn.dev/remore/articles/aa62d0e8a8d7de)
  * (2) [Readthrough Cache](https://zenn.dev/remore/articles/c071b08195e43b)
  * (3) [並列/ストリーミング処理](https://zenn.dev/remore/articles/e4e79ebf88db67)
- 揮発データの読み書き
  * (1) [SimpleCache API](https://zenn.dev/remore/articles/ad117556540681)
  * (2) [CoreCache API](https://zenn.dev/remore/articles/b2e13b9b2b9f98)
- 永続ストレージへの読み書き
  * (1) [Dynamic Configurationの利用](https://zenn.dev/remore/articles/7dd733e8a28f51)
  * (2) [KVStore の利用](https://zenn.dev/remore/articles/d27bcba9a26767)
- [Fastly Compute ストレージのまとめ(2023年末版)](https://zenn.dev/remore/articles/95ef4db310e64b)
- Fastly Compute を便利に使う Tips
  * (1) [HTTP/3を有効化する方法](https://zenn.dev/remore/articles/140c3f50961255)
  * (2) [Timeout を使った実行時間の管理](https://zenn.dev/remore/articles/9a2975e72f1c0b)
  * (3) [公式から公開されているソースコードやベストプラクティス](https://zenn.dev/remore/articles/6a67edfa9490ba)
- その他
  * [次世代 Web カンファレンス で Edge Computing の話をしてきた](https://rimuru.lunanet.gr.jp/notes/post/attended-next-web-conf-2023/)
  * [Unofficial SDK で更に便利に Fastly Compute を使う（ために試行錯誤してる話）](https://rimuru.lunanet.gr.jp/notes/post/making-fastly-compute-even-more-helpful-with-unofficial-sdk/)

※ 記事作成・編集の都合で上記コンテンツは恐らく途中で計画を変更しながらお送りすると思います。

### まとめ
タイトルの紹介だけですが、なんとなく全容のイメージは掴んで頂けたでしょうか。今の所最終日まで完走できるイメージが全く湧いていませんが、まずは書き出してみたいと思います。

明日は Fastly Compute (旧 Compute@Edge) がリリースされてから今日に至るまでの出来事について、公式ブログを眺めながら理解を進める記事を執筆予定です。
pythonのif __name__ == '__main__':に関して

# はじめに

こんにちは!!B4の黒田です!
今回は，if __name__ == '__main__':に関して説明します．

推奨環境
OS：　ubuntu22.04

# 簡単に説明
if __name__ == '__main__':は，
ファイルを読み込んだ際に関数などの実行を制御してくれるものです．
(あるpythonスクリプトが他のpythonスクリプトのモジュールとしてインポートされた場合と，あるpythonスクリプトが直接実行された場合を区別するために使用されます．)

例：以下にsample.pyがあるとします．
```sample.py
def hello():
  print("Hello")

hello()
```
sample.pyの実行結果⇐以下のコマンド実行
```
$python3 sample.py
Hello
```
上記の`hello()`関数を他のpythonスクリプトで使用したいとき，その関数をimportします．

例：以下にexample.pyがあるとします．
```example.py
from sample import hello

hello()
```
example.pyの実行結果⇐以下のコマンド実行
```
$python3 example.py
Hello
Hello
```
Helloが2回出力されました．
`これは，ファイルをimportすると読み込み先のファイルに記載されている関数が実行されるからです．`
これを制御するために，if __name__ == '__main__':
を使用します．

例：先程のsample.pyを以下のように修正します．
```sample.py
def hello():
    print("Hello")
    
if __name__ == '__main__':
    hello()
```
上記を修正することで，sample.pyをimportした際でもhello()関数は実行されません．

example.pyの実行結果⇐以下のコマンド実行
```
$python3 example.py
Hello
```
以上です．
曲ってどうやって作ってるの？

音出してますか！？

グレンジのサウンドクリエーター/サウンドデザイナーのかわのです。

![68747470733a2f2f71696974612d696d6167652d73746f72652e73332e61702d6e6f727468656173742d312e616d617a6f6e6177732e636f6d2f302f323938353436352f63346631346231662d326235302d383963612d333035662d6332643363393737316232392e706e67.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2985465/16cb19b7-38d5-da92-5bb3-415caa2900ee.png)


よく聞かれることの一つとして
「曲ってどうやって作ってるの？」
というものがあります。

※DAWの使い方とかミックスの方法とか技術的な話はないです。考え方の話です。

ここでは例として「クエスト中に流れるBGM」を作成するとします。
主にメロディを中心として聴き、楽曲そのものを楽しむポップスとちがい、ゲーム音楽は状況を説明、補足、強化するのが目的なことが多いです。

まず必要なものは情報です。
プランナーさんやイラストレーターさんから登場キャラやステージのお話を聞きます。
可能な限り直接会って話します。ほぼ雑談レベルですが、経験上、文言以上に依頼する人の熱量や想いがアウトプットに影響します。

イラストやアニメーションは情報として最強です。
どんなキャラが登場するのか？舞台は？時間帯は？
など、すべてが材料になります。
イメージに近い楽曲（参考曲、リファレンス）などがあればそれも情報としては助かります。

次に必要なものは使用する楽器です。
設定やイラスト、参考曲などから世界観やキャラクターを表現できる楽器を決めます。
世の中、さまざまな楽器がありますが、それぞれに得意とする表現の分野があり、それらを使い分けて楽曲を構成します。
わかりやすいところでいうと、和の世界を表すために太鼓や三味線、篠笛、神楽鈴などを用いる、などです。

楽器が決まって、イラストがあるとなれば、半分はできたようなもんです。
イラストを睨めっこしながら、もらったイメージを反芻し、使用楽器をどう使うか考えます。
でそれを録音したり、音源を打ち込んだり、ミックスしたりすれば完成です。

たぶん、一番難しいのは
感情を音に変換する部分だと思います。
「悲しい」をなんの楽器で表すのか、ピアノなのか、アコギなのか、バイオリンなのか。
キーは？テンポは？フレーズは？

![P1070976.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2985465/a1dd0031-de98-a4f6-92ac-004e0ae265fe.jpeg)


アコースティックギターをポロポロと爪弾く。大体の人は悲しいイメージを持つと思います。
でも、絶望ほど悲しくはない。寂しいイメージにも通ずる。
郷愁を感じる人もいるでしょう。

「アコギでマイナーキーのアルペジオを弾けばほとんどの人が悲しさを覚える」
同じように、力強さを表現するためにラウドなドラムを使用する、ホルンで旋律を取る、などなど。
そういった引き出しをどのくらい持ってるかが表現の幅になると思います。

「ゲームのBGMってどうやって作ってるの？」
簡単にいうと
妄想して、それを形にする
って感じです。
独りよがりの妄想ではなく、先ほどの和楽器の例のように、いろんな人が共感できるようなものが良いです。
three.jsのDragControls Tips

three.jsにはMeshをマウスドラッグで移動できる [DragControls](https://threejs.org/docs/#examples/en/controls/DragControls) があります。

![01.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15028/fc62ef05-90b7-6826-5db5-8ebabb049e0e.gif)
簡単にドラッグ処理を実装できますが、使う時に少しハマったのでTipsを共有します。

## 動作確認バージョン

- three.js version: r159

## 1. Groupはドラッグ対象にできない

DragControlsのドラッグ対象にGroupは設定できません。Meshのような3D Objectsだけです。
three.jsを使っているとよくGroupでMeshなどをグルーピングしますが、DragControlsを使う場合は親Meshの下に子Meshを入れる形が良いでしょう。

## 2. 移動する親Meshの子Meshもドラッグ対象になる

以下のようなコードで親Meshだけ指定しても子Meshもドラッグ対象になります。
```typescript
new DragControls([親Mesh], camera, renderer.domElement );
```
以下では四隅の白いCube型のMeshは親Meshにaddすると、同じくドラッグ対象になります（親Meshの拡大縮小は自前で実装してます）

![02.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15028/57b9f483-def7-46b9-bf7a-092aa95ed272.gif)

## 3. 後からSceneにMeshを追加する場合はdisposeした方が良い

ユーザー操作で後からMeshを追加する場合、`DragControls.dispose()` して `new DragControls()`し直しましょう。
でないと以下のようにドラッグ対象にする事ができません。

![03.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15028/1a953bbf-6dcd-48a6-3b61-8925cba6a7a7.gif)

### 4. ドラッグ対象にしたくない子Meshはlayersを指定すると良い
ドラッグしたくない子Meshがある場合、layersを設定しましょう。
 以下の画像では親Mesh配下にLineがあり、`line.layers.set(1)`にしてドラッグ対象外にしてます。
また、カメラは `camera.layers.enableAll()`にして全ての レイヤーが見える状態にしましょう。
DragControlsコード内のRaycasterはデフォルトのlayers:0になってるので、それ以外のlayers番号を指定すればドラッグ対象から外せます。

![04-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15028/dc5cbf46-47fb-1bc8-c4c1-61bf65fd32e3.png)


### 5. ドラッグ対象をハイライトさせたい
DragControlsにhoveron/hoveroffイベントがあるため、ハイライトも簡単にできます。
```typescript
import { ColorRepresentation, Mesh } from 'three';

const BASE_COLOR: ColorRepresentation = 0x0066ff;
const HIGH_LIGHT_COLOR: ColorRepresentation = 0x00ccff;

dragControls.addEventListener('hoveron', (e: any) => {
  if (e.object instanceof Mesh) {
    e.object.material.color.set(HIGH_LIGHT_COLOR);
  }
});
dragControls.addEventListener('hoveroff', (e: any) => {
  if (e.object instanceof Mesh) {
    e.object.material.color.set(BASE_COLOR);
  }
});
```

以上、少しクセはありますが、DragControlsで簡単に移動操作ができるのでぜひ使ってみて下さい。
エンジニア的トリプルシンキングのすすめ

# はじめに

この記事は

- 問題解決が苦手で仕方ない方
- 仕事の進め方で上長に指摘をもらいがちな方
- 新人エンジニア

などにお勧めです

# 3行で教えて
- エンジニアの業務は問題解決の連続である。
- 問題の解決のためには、正確な理想の把握と、適切な方法の選択が重要である。
- トリプルシンキングを用いれば、エンジニアの業務としての問題解決の質を向上できる。


# 問題解決をしよう
みなさん、問題解決は得意ですか？私は苦手です。
仕事の進め方で上長に指摘をもらいがちな方、というのは私のことです。

しかし、エンジニアの業務は問題解決の連続でもあります。
「○○といった機能の開発が必要」「××という不具合を修正してほしい」
「この社内ツール不便だから改修してほしい」「△△という運用をしたいんだけど、いい方法ない？…」……

問題解決の能力が、業務をこなす力の基礎になると言っても過言ではないでしょう。
そこで、適切な問題解決に役立つビジネススキル「トリプルシンキング」の使い方を覚えて、
問題解決能力アップ → 業務遂行力アップ　と行きましょう！という記事となります。



# 問題解決に必要なもの
さて、問題を解決するため必要なもの、それはなんでしょう？
技術の知識でしょうか？ 業務への理解？ あるいは経験？
それらは助けになりますが、実は本質ではありません。

### 1.正確な理想（本当にやりたいこと）の把握
### 2.適切な解決方法の選択

実はこの２項目ができれば、おおよその問題は解決方法が導き出せます。
そして、その助けになってくれるのが「トリプルシンキング」という考え方なのです。


# トリプルシンキングを使ってみよう

## クリティカルシンキング:「本当にこうじゃなきゃダメですか？」
「批判的思考」ともいいます。

「このやり方で行けると思うからお願いしますね！」
…と依頼された内容、共有された要件をそのまま要件にしてしまったこと、ありませんか？

<b>受け取った情報や既存の結論を鵜吞みにせず</b>、
「本当にそうか？」
「考える余地はないか？」
と<b>疑い、本質を導き出す思考がクリティカルシンキングです。</b>

### 防げるリスク
エンジニアに依頼をしてくる人物は、エンジニアでないことも多いです。
エンジニアだったとしても、必ずしも要件定義が得意だとは限りません。
そういった場合でクリティカルシンキングを行わないと、以下のような事象の原因になります。

- 言われた通りにしたけど、前提が間違っており追加開発が必要になった…
- 依頼者の認識違いから、他のシステムや業務へ悪影響を与えた…
- エンジニアに依頼する人物の理解できる範囲でしか、改善や開発提案ができない…
- 論理的思考をしたつもりだったが、前提の違いで見当違いの結論を出してしまった…


## ロジカルシンキング：「具体的には何ですか？」
「垂直思考」「論理的思考」と呼ぶ場合もあります。
（ラテラルシンキングを「水平思考」と呼ぶ場合は、対応させて「垂直思考」と呼ぶ場合が多いです）


問題とされる事柄は、数多くの原因からなる複雑な構造をしている場合も多いです。

「売上を上げる開発をしてほしい！」と言われたとします。
こういった場合に、抽象的だったり複層的な問題を「売上の上がる状態って具体的にどうすれば実現される？」
と掘り下げて、
例えば「ECサイトへの流入数の増加で実現 → SEO強化で実現」といった具合で<b>具体的な内容に落とし込む、
これがロジカルシンキングです。</b>

古くからある思考法ではありますが、トヨタで採用されているとして広まった「なぜなぜ分析」などが有名です。

### 防げるリスク
上述したように、複層的な問題はそのままですと具体的な対応に落とし込むのが困難です。
ロジカルシンキングを行わないと、以下のような事象の原因になります。

- 問題が大きすぎて何をすればいいか分からない…
- 具体的な対応内容が分からず、工数の見積もりができない…
- 対応するべき問題が絞り込めず、無駄な金銭・工数コストが発生…

## ラテラルシンキング:「ほかの手段もあるな？」
「水平思考」と呼ぶ場合もあります。

既存の事柄を「代替できる方法がある？」「同じ結果を得られる方法も？」という観点で考えることで、
新たな解答を発見していくような考え方です。

ロジカルシンキングの例で言及した「ECサイトへの流入数の増加 → SEO強化」ですと、
「広告を強化すれば流入数が増えるのでは？」
「SNSを利用して流入数を増やす方法もあるのでは？」
といった具合に、流入数増加という<b>結果を得るための手段は複数あります。</b>

こういったように<b>単一の答えにとどまらず、複数の答えを発見するのがラテラルシンキングです。</b>

また、
売上を上げる→ECサイトへの流入数or購入単価の向上or…
ECサイトの流入数向上→SEO強化or広告orSNSor...
SEO強化→コンテンツ充実orリンク数増加orSEOワードor...

といったように、ロジカルシンキングとの併用で効果を発揮することも多いです。
このロジカルシンキングとの併用を、トーナメント表や樹形図のような形の図に起こして進めていく思考法を「ロジックツリー」と呼びます。

### 防げるリスク
ラテラルシンキングで複数の手段を考慮することで、それらを比較して最善のアプローチを行うことができます。
「完成はしたけど、最善じゃなかったなあ」となってしまった経験がある方は意識してみるといいかもしれませんね。

ラテラルシンキングを行わないと、以下のような事象の原因になります。

- もっと短期間で実装可能な方法があった
- もっと低コストで利用可能なプラットフォームがあった
- 開発不要で実現可能な方法があった


# 俺たちゃトリプルシンキング

さて、トリプルシンキングの３つの思考法についてご紹介しましたが、これらがまとめて称されるのには理由があります。
ロジカルシンキングとラテラルシンキングの例で軽く触れましたが、これらは<b>併用することで力を発揮します。</b>

クリティカルシンキングで本質的な問題を導き出せなければ、ロジカルシンキングでいくら掘り下げても本質的な回答は得られません。
ロジカルシンキングでいくら掘り下げても、ラテラルシンキングで対案を探さなければ非効率的なアプローチを取ってしまいかねません。
ラテラルシンキングでいくらアイデアを出しても、ロジカルシンキングでの掘り下げが足りなければ「じゃあ何をすればいいの？」というところが不明で、タスクに取り掛かることはできません。

しかし<b>これら３つが適切に力を合わせることで、複雑に見える問題でも、「解決のために何をすればいいのか？」という課題の設定・解決に落とし込むことができます。</b>

<b>トリプルシンキングを意識して業務にあたることで、問題解決能力を上げてどんどん貢献していきましょう！<b>

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2952529/9c4fc04e-0033-74a9-77c0-1722fbed6d23.png)
特定のサーバーでProxmoxインストーラーが停止してしまう場合の対応方法

こちらはProxmox Advent Calendarの2日目です。
とりあえず、Proxmoxは個人的につかっていたりいなかったりしています。

私は基本的にvSphereの検証をメインに行っていますが、Proxmoxの検証も行ってます。
そんな中でとあるサーバーにProxmoxをインストールしようとしていました。

https://support.huawei.com/enterprise/jp/intelligent-servers/rh1288-v3-pid-9901873

ISO経由でインストールしてたんですけど途中で下のようなエラーが出る。
```
Starting Chrony for opportunistic time-sync... Starting a root shell on tty3.

Installation aborted - unable to continue (type exit or CTRL-D to reboot)
root@proxmox:/#
```
『インストールが停止しました、続行できません。』

この後にリブートしても特にインストールされるわけでもなく、同じエラーが繰り返されるだけとなります。

駄目かと思ったら海外のフォーラムでSupermicroのサーバーでインストールが失敗するみたいな話がありました。

https://gist.github.com/sergey-cheperis/530666bc5d7064185ab72bfcaeb19ff1

全く同じエラーでして、対策としてこちらを実施したところ、解決できました。

ちょっとわかりにくいのが

```
Xorg -configure
mv xorg.conf.new /etc/X11/xorg.conf
nano /etc/X11/xorg.conf
```

これでXorgの設定を書き換えるというところなのですが
設定箇所がちょっとだけわかりにくいというところです。

> Find the line: Load "glx" and replace with Disable "glx".
> After that line, add Disable "glamoregl".

glxをglamoreglに書き換えを実施したり
fbdevに書き換えが必要だったりとかなりめんどいです。

> Find the line: Driver "modesetting" and replace with Driver "fbdev".
> Start the X server with startx which will automatically start the graphical installer.

その作業が終わってから
> startx

と入力するとインストールがやっと開始します。

インストールが終わるとCLIに戻る場合があるのでリブートするといままでどおりProxmoxが起動します。
中華サーバー近辺だとインストールで詰まることがあるのでもしかすると同じ手順で解決することが出来るかもです。
0から始まったり始まらなかったりするPostgreSQL

# はじめに
これはPostgreSQLを0から学ぶための入門記事ではありません。
誤解を招くタイトルで申し訳ありません。

https://qiita.com/noborus/items/5e39d144b1510f6865bd
とてもおもしろい記事でしたので、勝手にちょっと名前をもらってきました。

# PostgreSQLの配列とJSON
PostgreSQLには配列型というものがあります。
基本正規化されているDBのテーブルではそう見かけることはないですが、パフォーマンスのため正規化を崩すときや、ちょっと凝ったクエリをSQLで書くときには役に立つ、なかなかに渋い奴です。

似たよう使われ方をするものにJSON型、JSONB型というものもあります。こちらは先ほどと似たような使い方をするほか、APIのレスポンスデータのような最初からJSONとして取り扱いたいデータを扱う場合に効果的です。

JSONBは表現力が高く、いろいろなJSONBを作ることができます。
以下のクエリでできるものは全部JSONBです。
```SQl
-- {}
select '{}'::JSONB;
 jsonb
------
{}
(1 row)

-- 1
select '1'::JSONB;
 jsonb 
-------
1
(1 row)

select '[{"value":0}]'::JSONB;
 jsonb 
-------
[{"value": 0}]

select NULL::JSONB;
 jsonb 
-------
[NULL]
```

# 本題
以下の2つのクエリを実行したとき、返ってくる値はそれぞれなんでしょうか？
```SQL
-- クエリ1
select '[{"value":0},{"value":1},{"value":2}]'::JSONB->0;
-- クエリ2
select (array[0,1,2])[0];
```

答えは、1つめが{"value":0}で、2つ目が<strong>NULL</strong>です。

```SQL
select '[{"value":0},{"value":1},{"value":2}]'::JSONB->0;
 jsonb 
-------
{"value": 0}

select (array[0,1,2])[0];
 jsonb 
-------
[NULL]
```

同じPostgreSQLの中でも、配列は1始まりで、JSONの配列は0始まりなのでした。
冷静に考えると1つの言語の中でこの両方があるのはなかなかすごい言語な気がします。
ただJavaScript Object Notationに1-indexedでアクセスするのもやりたくないですし、別におかしいことはないです。<strong>ところでPostgreSQLってJSONB配列の配列も書けますよね？</strong>

```SQL
select ((array['[{"value":0}]'::JSONB,'[{"value":1}]'::JSONB,'[{"value":2}]'::JSONB])[1])->0;
 jsonb 
-------
{"value": 0}
```
さすがに苦しい！

# まとめ
```SQL
SELECT FROM オチ;
--
(1 rows)
```

# おまけ
```SQL
-- JSONパスでも0始まり
select * from jsonb_path_query('[{"value":0},{"value":1},{"value":2}]'::JSONB, '$[0]');
 jsonb 
-------
{"value": 0}
```
TryHackMeのサブスクを一年分買ってみた（一か月目）

:::note info
この記事の中身
・筆者が1か月勉強した内容の振り返り
・TryHackMeのちょっとした紹介モドキ

:::
この記事の最後でTryHackMeのサブスクを一年分買ったという事を書いてから約一か月経ち、使い方がある程度わかってきた今日この頃。
せっかくだし毎月勉強の振り返りメモを残しておこうという記事の第一回です。

https://qiita.com/tsukamoto_yadonnnn/items/43c98a7d3106f1bea0a9


## 目次
- [何日間続けているか](#何日間続けているか)
- [どれくらいの数こなしたか](#どれくらいの数こなしたか)
- [ランクの上昇幅](#ランクの上昇幅)
- [バッジ](#バッジ)
- [主に学んだ内容](#主に学んだ内容)
- [今後の学習について](#今後の学習について)

## 何日間続けているか
2023/11/27現在、44日間連続で続いてはいます。
こんな感じで草を生やしてくれるのでモチベーションにはなります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3588702/dcedacd9-6e1c-3dd6-e205-e399ebe60426.png)

色が薄いところはインフルエンザになったり、NTT持株のIOWNフォーラムで東京に行ってた時です。

https://www.rd.ntt/forum/2023/

いつもはお昼休みと家に帰ってから勉強しています。
お昼に何もやっていない日はこんな感じで帰るぐらいの時間(18:00)にメールが来るので、なんやかんやで気になって連続記録が続いています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3588702/dc418c81-2bc5-8468-985f-c225d8c74497.png)

連続記録が続いたらグッズが安くなったりするっぽいですね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3588702/9d6e9bfd-6e3e-6942-981d-41d60e7aeb8a.png)


## どれくらいの数こなしたか
コンプリートした部屋は15個です。
今月は権限昇格をメインでやっていました。
部分的に内容を知りたくて途中放置の部屋もあるので見た目以上にはやっているはずです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3588702/c620cd45-d219-b76a-9b97-c9169d2ec1e7.png)


## ランクの上昇幅
まぁこんな感じです。10万弱上がった感じでしょうか？あまり変わらないですね。
特権昇格をはじめ手を動かす方が気になってしまい、読み物系は全部スキップしてしまいました。（初心者向けの読み物からやったらもっとポイント稼げたと思います）

**11/2(1か月前)**
![スクリーンショット 2023-11-01 224341.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3588702/7c396402-cf61-1559-a8fd-975a7df40139.png)

**11/27(現在)**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3588702/b7d7d6ff-a285-be6f-8c3d-de3ce92b7505.png)

## バッジ
バッジ狙いでやってないのでほとんど手に入ってないです。
Windowsの特権昇格のルームをもう1つクリアしたらもう一個バッジが手に入るっぽいです。12月の第2週には手に入れたいですね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3588702/c3fff9c3-3bca-db99-bec2-f781778ed0da.png)

## 主に学んだ内容
今月は特権昇格メインで取り組みました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3588702/fda1bbc2-81fd-d802-5f22-1f33d6587496.png)


Linux,Windows共にやり方を基礎から学んで、OneNoteにカンペを作成して別マシンに備えたような形になります。
もともとはメモ帳に書いていたのですが、OSCPにはカンペを作るというコメントを見てOneNoteに変更しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3588702/4945f028-8cb0-ec37-8d77-0da74bacc935.png)

OneNoteは作り始めたばっかりで穴がいっぱい空いていてページ名も整理できていないですが、そのうち綺麗になると思います。
自分が打ったコマンドを赤字、注目すべき場所を黄色でメモしています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3588702/ad5a7c12-3538-6007-1c61-2fd68e493f71.png)


## 今後の学習について
来月はWindowsの特権昇格のルームが終わり次第、AD周りのルームを網羅したいと思います。年末年始はどうせ暇だと思うので。
<font color="Lavender">4月にCEHのバウチャーが切れるので、勉強しなきゃなんですがやる気が・・・</font>
私が仮想通貨Botを作ろうと決意したときに読み漁ったときのブクマフォルダを晒します

ただ垂れ流します（順不同)

https://www.theblock.co/post/45750/exploring-defi-trading-strategies-arbitrage-in-defi

https://cointelegraph.com/news/arbitrage-traders-make-10x-returns-on-new-defi-platform-for-wrapped-assets

https://qiita.com/tvextbot/items/3dc90caabc152692ea5d

https://note.com/memenote/n/n638142a41964

https://www.binance.com/en/research/analysis/defi-arbitrage-strategies

https://note.com/hht/n/n64cc4d9fcc60

https://we.love-profit.com/entry/2017/10/04/133301

https://note.com/sakiyama100/n/n20ef5a4c9549?magazine_key=mbe85e78703fc

https://note.com/j26/n/n396b5fb31663

https://blog.baowebdev.com/2019/11/how-to-build-a-compound-liquidation-bot/

https://qiita.com/bakuchi/items/5e4dadf4d1ec3e45c4f1

https://note.com/pekiron/n/n39402cae5482

https://blockchaindex.net/

https://note.com/ai_pomeranian/n/n8739e09d3763
カオナビだいたい10年プレイヤーの軌跡


この記事は『カオナビ Advent Calendar 2023(シリーズ2)の 1日目』です。

https://qiita.com/advent-calendar/2023/kaonavi


## はじめに
カオナビでVPoEをしているKeeeeenです。

シーズン1は枠がなくて参加できなかったのですが、シリーズ２ができたのでAdvent Calendarに参加しました！ちなみにすきあらば追加で他の日も書いていく予定ですw
Advent Calendarを通して、カオナビの開発組織や評価、抜擢などVPoE視点で考えるていること、やっていることをメインに書いていければ、と思っています。

私の後続の投稿を読んでもらって、私個人に興味をもってくれたら方がいれば読んでもらえれば…くらいのライトなスタンスなので、１本目は私の自己紹介です。

## 略歴
### 就職まで
和歌山県の田舎で育ちました(…と言っても和歌山に都会はないですがw)。
大学では分子生物学という学問を専攻し、狂牛病の研究をしていました。
学業以外では文化祭実行委員会に入り、実行委員長として学祭を運営していました。

### 1社目：ガラケーアプリ会社に就職
まだ世にスマホが出る前で着メロやエンタメニュースなどがコンテンツとして盛況だったので、その開発ができる環境で仕事をしたいと思いエンジニアとしてのキャリアを始めました。
最初に覚えた言語はPerlで、次にガラケーのホーム画面を操作するキセカエというコンテンツでActionScriptに触れました。最後の方ではスマホが出てきたのに合わせてAndroid担当エンジニアとしてJavaを触っていました。

### 2社目：ソシャゲ会社に入社
１社目から吸収される形で入社しました。
ここで初めてPHPに触れ、その後はプレイングマネージャーでゲームの企画/運営まで行っていました。

振り返ってみると、ここでの実務的な経験が、その後のエンジニアとしてのキャリアに繋がっていると思います。

### 3社目：カオナビ社に入社
知り合いの紹介経由で入社。
今からは想像できないくらいの小ささで、当時はまだ10人くらいしかいませんでした。toB業界は初めてでしたが想像とは違いフランクな会社で違和感なく馴染んでいきました。

そんなこんなでかれこれ10年近く勤めています。

## カオナビでやってきたこと・やっていること
### リプレイス
当時のカオナビのシステムはWriterDBしかなく(当時はMasterとよばれていましたが…)、会社として生き残るためにカスタマイズが横行していました。
その結果、
**・Writerが詰まったら何もできなくなる**
**・ソースはユーザー毎に展開されるのでデプロイにすごく時間がかかる**
**・そもそもそんな状況なので修正コストがヤバすぎる**

みたいな環境で、上場を見据えたらとても耐えられるような構成ではありませんした。
そこで会社の成長速度の足を引っ張らないように、スケールできる構成にシステムをフルリプレイスしました。

### 組織の拡大に合わせて制度や仕組みを調整
オペレーション業務をこなしつつ、会社の成長スピードを止めないために増員しながら、仕組み化を進めました。人が増えると当然ミスの発生も多くなるのでUTのカバレッジを増やすプロジェクトを推進したり、Reactへのリプレイスを開始したり(まだまだ終わっていませんが…)、入社しても覚えることを少なくして自動でフローが回るような仕組みを作ったり…と、色々やってきました。

https://www.wantedly.com/companies/kaonavi/post_articles/175731

### 新しい価値を生み出す新規の何かをつくる
今は新しい価値を創造することで会社に貢献することを生業としております。
カオナビにはクリエイティブマップと呼ばれる機能がありますが、これはVPoEとしてエンジニアの抜擢をする中で生まれた機能で、これが前述の新しい価値創造の第一歩です。

https://www.kaonavi.jp/func/creativemap/

## まとめ
10年近くいれば流石に色々やってきたし、色々結果が出てないとそんなに続かないよな…と改めて書いていて思いましたw

それではシリーズ2の2日目の記事もお楽しみください！！

https://corp.kaonavi.jp/recruit/recruitment/
【Flutter】状態管理

[chatGPT に立ててもらったスケジュール](ceecf4a987d3f75b6d93)に準じてFlutterの状態管理を勉強。
> - Day 5: Flutterの状態管理
>     - 状態管理の必要性とFlutterの提供する方法を学ぶ
>     - 状態の共有と更新の方法を理解する
# 状態管理とは
![ログインしたり アイテムをカートに入れるアニメーション ｜ 公式のgif](https://docs.flutter.dev/assets/images/docs/development/data-and-backend/state-mgmt/state-management-explainer.gif)
- なんらかのきっかけから、UIが変わるために「状態管理」する必要がある。
- たとえばユーザーがログインすれば、ログインユーザーのみの画面に遷移するとか、ECアプリでアイテムを追加したらカートの中身が反映されるとか。
- 3つの方法で状態管理ができる
  - setState
    - リビルド（画面全体の更新）が必要になる⇒重くなる可能性が増える
  - Provider
    - リビルドせずピンポイントの更新が可能
    - 公式に推奨されてる
  - Riverpod
    - Providerの改良版らしい
    - リビルドせずピンポイントの更新が可能
    - Flutter に依存しない（pure dart）⇒学習コストが高くなることもある
# 状態の共有と更新の方法
学習コスト高すぎると挫折しそうなので以下はProviderにしました。
## pubspec.yaml にproviderを導入することを記載
``` yaml
dependencies:
  provider: ^6.0.2
```
## ターミナルで依存関係として追加
```
$ flutter pub add provider
```
## Providerを実装
chatGPTにもらったサンプルソースに分からなかったところをコメントで追加
<details><summary>サンプルソース</summary>

``` dart
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

void main() {
  runApp(
    ChangeNotifierProvider( // ChangeNotifierを使いたいウィジェットを子にする。ChangeNotifierのインスタンスを提供する。
      create: (context) => CounterProvider(),
      child: MyApp(),
    ),
  );
}

class CounterProvider extends ChangeNotifier { // ChangeNotifier は変更の監視を可能にさせるクラス
  int _counter = 0;

  int get counter => _counter;

  void incrementCounter() {
    _counter++;
    notifyListeners();
  }
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Counter App with Provider'),
        ),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              Consumer<CounterProvider>( // Consumer<任意のModel> : 提供されたモデルを使うためのWidget Consumerで囲われた部分が更新対象
                builder: (context, counterProvider, child) { // (context, ChangeNotifierのインスタンス, child)
                  return Text('Count: ${counterProvider.counter}');
                },
              ),
              ElevatedButton(
                onPressed: () {
                  Provider.of<CounterProvider>(context, listen: false) // <任意のModel>にアクセス メソッドのみ呼び出したいときはlistenをfalseにすると再構築されない 試しにtrueにしてみたら画面上の数は更新されなかった
                      .incrementCounter();
                },
                child: Text('Increment'),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

```

</details>

# 参考
## 公式ドキュメント

https://docs.flutter.dev/data-and-backend/state-mgmt/options

https://docs.flutter.dev/ui/interactivity

## provider

https://www.flutter-study.dev/create-app/provider

https://kimuralog.com/?p=1914

## Riverpod

https://knmts.com/as-a-engineer-112/

## Zenn

https://zenn.dev/chooyan/books/934f823764db62/viewer/eb01d5

https://zenn.dev/ryouhei_furugen/scraps/f6810ccfd04177
アイディアメモからスケジュール・タスク管理までの流れ

# この記事は何？
- 僕の個人的な作業完了までの流れを整理して見ました。
- アイディアが浮かんでからタスクを切って作業完了するまで。
    - 人によって方法がバラバラだと思うので、個人的ベストプラクティスを描きます。
- 他人の仕事の流れって気になりません？？


# どんな悩みを解決するの？
- 私のやり方は、「やることを最小化する」ことに重きを置いています。
- 限られた時間の中で、必要最低限のタスクをこなしていくために考えたやり方です。
- 今の所、６ヶ月ほどはこの方法で個人的開発を進めています。


# Get Started!
1. アイディアが浮かんだらNotion
    - とりあえず、スマホでNotionにメモします。
    - 箇条書きでどんどんメモしていきます。
    - １つのページに箇条書きっていうのがポイントです。
    - 潔癖症の人には申し訳なのですが、ここではスピード重視です。
        - 誤字っても気にしない
        - １行で終わらせる
        - 余計なタグとか一切つけない。
1. メモを週末に整理する
    - アイディアは週末に一気に整理します。
    - ここでアイディアを精査します。
    - 「あ、やっぱりいらんわ」と思うものがたくさん出てくるので削除削除。
    - 必要なものだけに絞り込みます。
    - ここでアイディアの詳細を書き込んでいきます。
    - その過程でさらに必要なもの以外は削除していきます。
    - 最後に残るのは、だいたい３〜５個くらいですね。
    - ２０〜３０個くらい削除されます。
1. 週末にやることをissueにする
    - 生き残った３〜５このタスクをissueにします。
        - 大体の場合は開発系のタスクですからね。
        - もし「Docker＋RailsでAPI作ってみる」みたいなものは新しくリポジトリを作ってissueを作ります。
    - ここでは、とにかくissueにすることが大事です。
    - これまでは水もののタスク管理でしたが、厳選されたやることリストは結構大事なものばかり。
    - わざわざリポジトリやissueを作る甲斐はあります。
1. my sprintのissueと紐付ける
    - 実は、`MyRepository`みたいな感じで１つリポジトリが用意されています。
    - そこで毎週１つ`sprint#001`みたいなissueが作られます。
    - 作業するissueは全てそのスプリントイシューに紐付けます。
        - GitLabは`/relate ...`みたいな感じで紐付きができます。
    - いきなり几帳面ですよね。
    - こうすることで１週間ごとに自分のタスクを振り返ることができます。
    - そうです、ここからは結構几帳面になります。
1. 自分にMRを出す
    - わざわざ一人なのに自分に対してMRを出します。
    - これは、メモ的な役割もありますが、本当の意味は他にあります。
    - issueを切って、MRを出すことで時間を節約できるのです。
        - 休日の個人開発って無限に時間があると勘違いしてしまっちゃいませんか？？
        - 興味の赴くままに開発し続けちゃうんですね。
        - そう、メリハリのためです。
        - issueを作ることで作業範囲を絞り込み、MRを出すことで無駄な開発を抑える。
    - 目の前のことに没頭しちゃう人は、これ有効です。
1. 週末やることメモを空にする
    - ここまでで週末やることリストは無くなっているはずですね。
    - え？思った以上にできなかった？
    - そんなタスクは消しちゃいましょう。
        - だって、今週やる必要がないっていうことじゃないですか。
    - それでもやりたかったと悔いの残るタスクはありますよね。
        - 新しい技術の習得とか、実験とか、実験とか、実験とか。
    - そういうものは仕方がないですから、来週に持ち越しましょう。
    - でも、最後に１つ聞いてください。
        - 「２週間to doリストにあるものは、不要なタスクです！」


# プロローグ
- ブログを書いていこう！
- なんて思っても、なかなかできません。
- 真っ先に思いつくのは、ブログの内容じゃなくて、どうやってブログをつくろうか。
    - やっぱりwordpressかな。
    - いや、でも最近仕事で使ってるし、Laravelで作るのも面白い。
    - 技術が衰えないためにRailsで書いてみるのも必要だよね。
    - ええ、でもメンテナンス性を考えたら静的サイトジェネレーターも。。。
- そうですね、分かってます。
- ブログを書くことが重要であって、どう作るのかは全然重要じゃない。
- 分かってるんですけど、そんな感じで全然進まないんです。
- ということで、かるーくかける内容をQiitaに投稿しました。
- 皆さんどうなんでしょう、同じ悩み持っている人います？
- あ〜やっと１記事書けた。
- やっと１歩踏み出せました。
cronの時間指定

# cronの起動時間設定
```
* * * * * （起動したい処理）
| | | | |
| | | | └─ 曜日
| | | └─── 月
| | └───── 日
| └─────── 時
└───────── 分
```

# crontab guru
設定した値が次にどの時間になるかを確認できる
nextのリンクをクリックすればOK

https://crontab.guru/

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/660484/f68f8385-d953-230f-4576-1a0cd47a2b94.png)
[Python]requestsモジュールでSlackにメッセージを通知する

この記事は MicroAd Advent Calendar 2023 の4日目の記事です。

https://qiita.com/advent-calendar/2023/microad

こんにちは。
マイクロアドのタカギです。

PythonでSlackにメッセージを通知したい場合、slack-boltを使用するのが一般的ですが、requestsモジュールを使用してSlack通知してみようと思います。

## ソースコード

```requirements.txt
requests==2.31.0
```

```app.py
import os
import logging
import requests
from requests import Response

LOGGER = logging.getLogger('app')

CHANNEL_ID = 'xxxxxxxxxxx'
SLACK_BOT_TOKEN = os.environ['SLACK_BOT_TOKEN']


def send_message(msg: str, channel_id: str, token: str) -> Response:
    """
    slack通知
    Args:
        msg: 通知メッセージ
        channel_id: slackのチャンネルID
        token: slackトークン
    Returns:
        APIのレスポンス情報
    """
    LOGGER.info("send message to slack.")

    url = "https://slack.com/api/chat.postMessage"

    header = {
        "Authorization": f"Bearer {token}"
    }

    data = {
        "channel": channel_id,
        "text": msg
    }

    response = requests.post(url, headers=header, data=data)
    response.raise_for_status()

    LOGGER.info(response.json())

    return response


def send_by_snippet(
        content: str, channel_id: str, ts: str, token: str,
        title: str = 'thread content', filename: str = 'content.txt') -> None:
    """
    slack通知
    スレッドにスニペット形式で通知
    添付ファイルとして通知される
    Args:
        content: 添付ファイルの本文
        channel_id: slackのチャンネルID
        ts: slackメッセージ通知レスポンスのts
        token: slackトークン
        title: 添付ファイルのタイトル
        filename: 添付ファイルのファイル名
    """
    LOGGER.info("send content to slack thread.")

    url = "https://slack.com/api/files.upload"

    header = {
        "Authorization": f"Bearer {token}"
    }

    data = {
        "channels": channel_id,
        "thread_ts": ts,
        "title": title,
        "content": content,
        "filename": filename
    }

    response = requests.post(url, headers=header, data=data)
    response.raise_for_status()

    LOGGER.info(response.json())


def main() -> None:
    """
    メイン処理
    """
    msg = 'slack通知メッセージ'
    response = send_message(msg, CHANNEL_ID, SLACK_BOT_TOKEN)

    # メッセージ通知したスレッドに添付ファイルで通知
    ts = response.json()['ts']

    content = """
    添付ファイルの内容
    """

    send_by_snippet(content, CHANNEL_ID, ts, SLACK_BOT_TOKEN)


if __name__ == "__main__":
    main()

```

アプリ実行
```
python app.py
```

## 実行結果

メッセージが通知されて、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/870283/e499a448-e5f6-d980-6f38-c4352d5bfdb7.png)

スレッドにも通知されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/870283/d2ca75b6-7fb9-79fe-eec9-8c417c9fe248.png)

## 注意点

APIによって、通知先チャンネルIDを指定するパラメータのキー名が異なります。（ハマりました）

| API | チャンネルIDを指定するパラメータ |
| - | - |
| https://slack.com/api/chat.postMessage | `channel` |
| https://slack.com/api/files.upload | `channels` |

## まとめ

requestsモジュールを使用してslackにメッセージを通知することができました。

ライブラリによっては廃止になって消えたりするものもあったりするので、できるだけ汎用的なライブラリで済ませるのもありかもしれないですね。

ではでは。
[Ruby] クラス定義が重複した場合の挙動

Rubyでクラス定義を複数回書いた場合の動きが予想外でした。

## 結論

Rubyではクラス定義が重複してもエラーは起きません。メソッドは一番最後に定義したものが実行されます。

## クラス定義

```ruby
class C
    def name
        "alice"
    end

    def age
        20
    end
end

class C
    def name
        "bob"
    end
end
```

## 実行結果

```ruby
C.new.name # => bob
C.new.age # => 20
```
RFC 4180 Common Format and MIME Type for Comma-Separated Values (CSV) Filesを読んでみた。

# はじめに
こんにちは、[42tokyo Advent Calendar 2023](https://qiita.com/advent-calendar/2023/42tokyo)の3日目を担当する、42tokyoの在校生、hnoguchiです。

現在取り組んでいる課題で、csvファイルを読み込む実装を行なっており、RFCでの定義を整理するために書き始めました。
この記事は、[RFC4180](https://datatracker.ietf.org/doc/html/rfc4180)の中でも、[2. Definition of the CSV Format](https://datatracker.ietf.org/doc/html/rfc4180#section-2)　をまとめたものになります。
間違いがあったらご指摘ください。どうぞよろしくお願いします。

# まとめ
```ABNF:ABNF
file        = [header CRLF] record *(CRLF record) [CRLF]

header      = name *(COMMA name)
record      = field *(COMMA field)

name        = field
field       = (escaped / non-escaped)

escaped     = DQUOTE *(TEXTDATA / COMMA / CR / LF / 2DQUOTE) DQUOTE
non-escaped = *TEXTDATA

COMMA       = %x2C
CR          = %x0D
DQUOTE      = %x22
LF          = %x0A
CRLF        = CR LF
TEXTDATA    = %x20-21 / %x23-2B / %x2D-7E
```

# 2. CSVファイルの書き方について（定義）
そもそも、CSVの書き方には様々な仕様や実装が存在する。
そして、多様な書き方の解釈を可能にする正式な仕様は存在しない。
ここでは、多様な書き方の中で共通していると思われる書式を文書化した。

### 各recordは、改行(CRLF)で区切られる。
```csv:sample.csv
field_1,field_2,field_3[CRLF]
field_1,field_2,field_3[CRLF]
...
```

### 最終recordは、改行(CRLF)がなくとも良い。 (may or may not)
```csv:sample.csv
...
field_1,field_2,field_3[CRLF]
field_1,field_2,field_3
```

### 先頭行が、headerの可能性がある。
```csv:sample.csv
field_1_name,field_2_name,field_3_name[CRLF]
field_1,field_2,field_3[CRLF]
...
```
* header行のfield数と各recordのfield数は、同数であると良い。(should be)
* header行の有無は、MIMEタイプのoption "header" parameterで指定しておくと良い。(should be)

### headerと各recordの中には、comma(,)で区切られたfieldが1つ以上あって良い。
```csv:sample.csv
// ダメな書き方
field_1,field_2,field_3,[CRLF]
...
```
* 各行のfield数は、同数であると良い。(should)
* [space]はfieldの一部とみなす。無視してはならない。(should not be)
* recordの最終fieldの末尾には、comma(,)を付けてはいけない。(must not)

### 各fieldは二重引用符(")で囲んでも良い。(may or may not)
* 二重引用符(")に全く対応していない実装もある。
* 二重引用符(")で囲まれていないfieldに二重引用符(")がある場合、その二重引用符(")を無視するものがある。(may not)

### 改行[CRLF]、二重引用符(")、comma(,)を含むfieldは二重引用符(")で囲むべき。(should be)

```csv:sample.csv
"field_1","field,_2","field[CRLF]
_3"[CRLF]
field_1,field_2,field_3[CRLF]
...
```

### 二重引用符(")を文字として扱うには、fieldを二重引用符(")で囲み、二重引用符(")でescapeする。(must be)
```csv:sample.csv
"field""_1","field""""_2","field_3"[CRLF]
...
```
# さいごに
明確な定義（must）が少なく、あくまで推奨する定義（should）が多い印象でした。
二重引用符(")で囲まれたfieldでは、改行(CR, LF)も受け入れるところが面白かったです。

次回は、これらの定義を参考に`C++98`で、parserの実装をしていきたいと思います。（未定）
ありがとうございました。

参考
[RFC 4180 - Common Format and MIME Type for Comma-Separated Values (CSV) Files](https://datatracker.ietf.org/doc/html/rfc4180)
[Rails] fixtureが読み込まれない問題

## まず結論から

`setup`でfixtureを使う時は、`teardown`でfixtureのキャッシュを消しましょう。

## fixtureが読み込まれない現象
まずは問題のあるコードを掲載します。`SecondTest`の`some test 2`テストを見てください。`TableClass`のテーブルにfixtureデータが入っていません。

```ruby
require 'test_helper'

class FirstTest < ActiveSupport::TestCase
    setup do
        fixture_directory = ''
        fixture_files = [:tbl]
        fixture_models = { tbl: TableClass }
        ActiveRecord::FixtureSet.create_fixtures(fixture_directory, fixture_files, fixture_models, DBClass)
    end

    test 'some test 1' do
        pp TableClass.all #=> [...]
    end
end

class SecondTest < ActiveSupport::TestCase
    setup do
        fixture_directory = ''
        fixture_files = [:tbl]
        fixture_models = { tbl: TableClass }
        ActiveRecord::FixtureSet.create_fixtures(fixture_directory, fixture_files, fixture_models, DBClass)
    end
    
    test 'some test 2' do
        pp TableClass.all #=> []
    end
end
```

この挙動を理解するためには、次の二点を押さえる必要があります。

- テストケース毎にtransactionが張られて、テストが終わるとrollbackされる (参考：[Railsテスティングガイド](https://railsguides.jp/testing.html#:~:text=3.3%20%E4%B8%A6%E5%88%97%E3%83%88%E3%83%A9%E3%83%B3%E3%82%B6%E3%82%AF%E3%82%B7%E3%83%A7%E3%83%B3%E3%82%92%E3%83%86%E3%82%B9%E3%83%88%E3%81%99%E3%82%8B))
- `create_fixtures`で作られたfixtureはテーブル毎にキャッシュされる

キャッシュされたfixtureと同じテーブルに対して、再度fixtureを当てようとしてもDBアクセスは起きません。fixtureのキャッシュはテーブル名(第二引数で渡した`fixture_files`の要素)で行われるため、たとえ別の`fixture_directory`の同名のfixtureを当てようとしても何も起きません。

## 何が起きたのか

今回のケースでは、まず`FirstTest`クラスでfixtureが当てられます。次に、`SecondTest`クラスでもfixtureを当てようとするのですが、fixtureのキャッシュがあるため何も起きません。fixtureは当てられないのですが、`FirstTest`クラスのfixtureの内容はrollbackされてDBから消えます。

そのため、`some test 2`で`TableClass`テーブルの中身を見ても空だったのです。

## どうすればよかったのか

`FirstClass`の`teardown`でfixtureのキャッシュを消せば、`SecondClass`でもfixtureが読み込まれます。

```ruby
class FirstTest < ActiveSupport::TestCase
    setup do
        fixture_directory = ''
        fixture_files = [:tbl]
        fixture_models = { tbl: TableClass }
        ActiveRecord::FixtureSet.create_fixtures(fixture_directory, fixture_files, fixture_models, DBClass)
    end

    teardown
        ActiveRecord::FixtureSet.reset_cache
    end

    test 'some test 1' do
        pp TableClass.all #=> [...]
    end
end
```

## [参考] ActiveRecord::FixtureSet.create_fixtures

```ruby
def create_fixtures(fixtures_directory, fixture_set_names, class_names = {}, config = ActiveRecord::Base, &block)
    fixture_set_names = Array(fixture_set_names).map(&:to_s)
    class_names = ClassCache.new class_names, config
    
    # FIXME: Apparently JK uses this.
    connection = block_given? ? block : lambda { ActiveRecord::Base.connection }
    
    fixture_files_to_read = fixture_set_names.reject do |fs_name|
        fixture_is_cached?(connection.call, fs_name)
    end
    
    if fixture_files_to_read.any?
        fixtures_map = read_and_insert(
            fixtures_directory,
            fixture_files_to_read,
            class_names,
            connection,
        )
        cache_fixtures(connection.call, fixtures_map)
    end
    cached_fixtures(connection.call, fixture_set_names)
end
```
恥ずかしがり屋の ViewModel

# はじめに
Android Advent Calendar 2023 2日目の記事です。

https://qiita.com/advent-calendar/2023/android

恥ずかしがり屋の ViewModel ということで property を公開しすぎないようにしたいです。

# UI state
イメージとしては下図の **UI state** の部分のみを ViewModel は公開します。

<img width="500" alt="Figure 4. Diagram of how UDF works in app architecture." src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31787/a30e2dab-98ca-ade4-6012-b00b3f0f2627.png">

[1日目](https://qiita.com/ykws/items/a418572adffc8192ef30)に続き Android Developers でガイドで示されているサンプルからコードを抜粋して紹介します。

https://developer.android.com/topic/architecture/ui-layer#samples

## Good

`StateFlow` を公開するのがシンプルでわかりやすいです。

```kotlin
    private val _state = MutableStateFlow(HomeViewState())    

    val state: StateFlow<HomeViewState>
            get() = _state
```

https://github.com/android/compose-samples/blob/d8d341b1151c38bb3f63cb67776485213e21e113/Jetcaster/app/src/main/java/com/example/jetcaster/ui/home/HomeViewModel.kt#L45-L50

`HomeViewState` の中身は次のようになっています。
State が Immutable なのが良いです。

```kotlin
data class HomeViewState(
    val featuredPodcasts: PersistentList<PodcastWithExtraInfo> = persistentListOf(),
    val refreshing: Boolean = false,
    val selectedHomeCategory: HomeCategory = HomeCategory.Discover,
    val homeCategories: List<HomeCategory> = emptyList(),
    val errorMessage: String? = null
)
```

https://github.com/android/compose-samples/blob/d8d341b1151c38bb3f63cb67776485213e21e113/Jetcaster/app/src/main/java/com/example/jetcaster/ui/home/HomeViewModel.kt#L107-L113

## Bad

もし State を用意していなくて、単純に更新中の制御をしたいとして、次のような property を追加したとします。

```kotlin
    var refreshing by mutableStateOf(false)
```

View からも状態を更新できるので一見便利かもしれないですが、コードは難解になっていきます。また ViewModel の property を操作できてしまうが故に、1日目で紹介した ViewModel に依存した Composable  を生みやすくなっています。

```kotlin
@Composable
fun Home() {
    HomeContent(
        viewModel = viewModel
    )
}

@Composable
fun HomeContent(
    viewModel: HomeViewModel
) {
    if (viewModel.refreshing) {
        CancelableIndicator() {
           onDismiss = { viewModel.refreshing = false }
        }
    }
}
```

## おわりに
3日目は「無関心な ViewModel」とタイトルでさらにより良い ViewModel について続きを書こうと思います。

https://qiita.com/ykws/items/21f6f208ccb225ad5fcb
基本情報技術者試験の合格を目指しつつCSを学ぶ：文系大学生の3ヶ月学習計画

# はじめに
この記事では、文系大学生でありながら、基本情報技術者試験に合格するために実践した3ヶ月間の学習計画を共有します。来年エンジニアとしてのキャリアをスタートさせるにあたり、この資格でITの基礎知識を身につけばと思い試験対策をし合格することができました。
またこの記事は合格することが目標ではなく、基本情報技術者試験の対策を通してCSを学びたい人向けに作成しました。

# 学習計画の概要
* 期間: 3ヶ月
* 1日の学習時間: 2～3時間

# 動画教材による基礎学習（2ヶ月）
#### 使用教材

1. 令和5年版:現役講師が教える【基本情報技術者試験　科目A】講座　基礎理論から経営戦略までの全範囲を網羅

https://www.udemy.com/course/kihon_joho/

2. 令和5年版:現役講師が教える【基本情報技術者試験　科目B】Javaプログラミング言語を使った、科目B対策専門コース

https://www.udemy.com/course/kihon_joho_b/

#### 学習のポイント
* 講義内容の完全理解
* 問題演習を通じての理解深化
* 各科目の解説をしっかりと把握
* 科目Aは2周
* 科目Bは1周

#### 特に重点を置いた分野(エンジニアとして働く上で役立つと感じた分野)
* アルゴリズム
* 基礎理論
* コンピュータシステム
* データベース
* ネットワーク
* セキュリティ


# 過去問演習と新制度サンプル問題（最終1ヶ月）

#### 使用サイト

基本情報技術者過去問道場

https://www.fe-siken.com/fekakomon.php

#### 学習のポイント
* 科目A: 直近5回分の過去問演習と新制度サンプル問題
* 科目B: 新制度サンプル問題と令和5年度の公開問題

#### 合格へのアドバイス
* 科目A: 過去問を最低5回分は解く。同じ問題が出ることが多いため。
* 科目B: 問題を解くよりもプログラムの流れを理解することが重要。紙に書きながら処理を追う習慣をつける。

# まとめ
この学習計画は、基本情報技術者試験に合格するために十分なものであり、特に文系出身者にとって最低限のCSを学ぶのにも有効な方法です。目標が合格することだけなら、過去問メインでより多くの過去問演習をする方が効率的かもしれません。
DOMのセレクタは初期のレベルで宣言しよう

たとえばメソッド内に

`document.querySelector("hoge")`

を書いているとして、
毎度呼び出されているとパフォーマンス（速度）に影響が出ます。
（もしメソッドが頻繁に呼び出され、DOMの検索が重い場合とか。）

## どうすれば
コンストラクタで要素を一度だけ検索し、その参照をクラスのプロパティとして保持する方法もあります。


```ts
    hoge: HTMLInputElement;
    test: HTMLElement | null;

    constructor() {
        this.hoge = document.querySelector<HTMLInputElement>('input[type="checkbox"][name="hogehoge"]:checked');
        this.test = document.querySelector<HTMLElement>('.test-class');
    }
```

以下が期待できます。
* パフォーマンス低下の回避
    * DOMを一度だけ検索するため、頻繁な検索によるパフォーマンスの低下を回避できる。
* 記述が煩雑にならない
    * 要素の参照を一箇所で管理することで、コードがより整理され再利用性が高まる。


staticとしてまとめてあげて使用することも可能。

```ts
static hogeElements = {
        hoge: document.querySelector<HTMLInputElement>('input[type="checkbox"][name="hogehoge"]:checked');
        test: = document.querySelector<HTMLElement>('.test-class');
}
```

## 注意点
ただ注意点はあってDOMが動的に変更されることがあれば
処理毎にDOMをセレクタしてやらないと期待した動作にならないです。
更新によって指定していたDOMが古くなってしまうためです。

非同期なんかで毎度テンプレートを取得してHTMLを再生成するアーキテクチャとかがその例です。

なのでDOMに動的変更がある際は注意する。
いろいろなモジュールを使おう!!

# はじめに

こんにちは!!B4の黒田です!!
今回は，プログラムのモジュールについて紹介します．

推奨環境
OS：　ubuntu22.04
プログラム：　python

### `import sysについて`
```
import sys ##プログラム内で宣言
```
このモジュールは，pythonの実行時に関する情報や機能を提供するために使用されます．
例:
・コマンドライン引数へのアクセス
・標準入出力へのアクセス
・プログラムの終了
・パスの設定等

`・コマンドライン引数へのアクセス`
この機能をメインに使用することが多いと思います．
例えば，コマンドで以下を入力．
```
$python3 ros2bag_to_csv.py [ros2 bagファイル] [トピック名] ##コマンド入力
```
コマンド入力内のros2bag_to_csv.pyを取得したい場合：
```
sys.argv[0] ##プログラム内で入力，コマンドライン引数の0番目の要素を取得
```
同様に，[ros2 bagファイル]，[トピック名]は
```
sys.argv[1] ##プログラム内で入力
sys.argv[2] ##プログラム内で入力
```
sysは以上です．
### `import numpy as npについて`
```
import numpy as np ##プログラム内で宣言
```
このモジュールは，多次元配列・行列演算・数学関数などの機能を提供し，データ処理に広く利用されます．
例：
・numpy配列の作成
・行列演算
・数学関数

`・numpy配列の作成，簡単な行列計算`
プログラムで以下を書き込みます．⇐単純なものです．
```
a = np.array([[1, 2], [3, 4]])
b = np.array([[5, 6], [7, 8]])
print(a)
# [[1 2]
#  [3 4]]が出力されます．
print(a+b)
# [[6 8]
#  [10 12]]が出力されます．
print(np.dot(a,b)) #行列の乗算
```
更に，数学関数や乱数作成もできます．
```
x = np.array([0, 1, 2])
# サイン関数
result = np.sin(x)
# 指数関数
result = np.exp(x)
# 対数関数
result = np.log(x)

# 0から1までのランダムな値
random_value = np.random.rand()
# 正規分布に従うランダムな値
random_values = np.random.randn(5)
```
npは以上です．

### `import pandas as pdについて`
```
import pandas as pd ##プログラム内で宣言
```
このモジュールは，pythonのデータ解析用ライブラリをプログラムに導入する役割を果たす．

例：
・データフレームの作成
・データの表示
・データの操作
・データの読み書き

`・データフレームの作成`
データフレームとは，2次元のデータに対応するデータ構造．行名(index)や列名(column)を指定することや，データの取り出し，データの簡易化を行うことができる．
```
# データフレームの作成
data = {'Name': ['Alice', 'Bob', 'Charlie'],
        'Age': [25, 30, 35],
        'City': ['New York', 'San Francisco', 'Los Angeles']}
df = pd.DataFrame(data)
print(df)
    #      Name  Age           City
    #0    Alice   25       New York
    #1      Bob   30  San Francisco
    #2  Charlie   35    Los Angeles #が出力される
```

`・データの読み書き`
```
# csvファイルからデータを読み込み
df = pd.read_csv('data.csv')
# データをCSVファイルに保存
df.to_csv('output.csv', index=False)
```
pdは以上です．
新規リポジトリ作成とUbuntuファイル連携

こんにちは！

今回の記事では、GitHubで新規リポジトリを作成し、Ubuntuと連携する方法を記載したいと思います！！

この操作はUbuntuでGitHubを操作する人向けのマニュアルになりますが、編集後のコミットなどコマンドで簡単にできるのでぜひ身に着けておきたいところですね！

## 新規リポジトリの作成

まずは新規リポジトリを作成したいと思います。GitHubのアカウント登録をしていない人はGitHubのアカウントを登録してから再度この記事に戻ってきていただければと思います。

それではGitHubのページに遷移し、サインインしてください。

その後、個人のアイコンをクリックします。すると、次のような画面が登場するかと思います。

![github newrepositori.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3500754/5d64d6fd-19d0-6343-9726-671208607ce3.png)

ここで「Your repositories」をクリックしてください。

すると個人のリポジトリ一覧のような画面に遷移するかと思います。

ここで画面右上のNewをクリックします。

![newrepo.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3500754/ed300beb-486d-b713-c4dd-eb26bf4dfb24.png)


すると次のような画面に遷移します。

![createnewrepositories.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3500754/c2e254e9-a1d3-ac53-d7db-fa6be72473a7.png)

この画面上部でリポジトリの名前を設定します。

その後、Publicリポジトリなのか、Privateリポジトリなのかを選択して、画面右下のCreate repositoryをクリックします。

### PublicリポジトリとPrivateリポジトリの違い

ここで先ほど記載のあったPublicリポジトリとPrivateリポジトリの違いを記載します。

主な違いとしては第三者がリポジトリを見ることができるかどうかを指しています。個人の公にしたくないソースコードの管理などはPrivateリポジトリを作成して行います。

しかし、GitHubにはGitHub Pagesといった機能があり、サイトを制作したコードをリポジトリで管理していることでリポジトリ名でリンクが作成でき、作成したサイトを公開することができます。しかし、この機能はバックエンドを利用した制作物では利用できないので、ページのデザインや、簡単なjsでの実装などでしか使用することができません、、。

## リポジトリUbuntu連携

ここではUbuntuとGitHubの連携が済んでいる状態で話をします。

まず、Ubuntuでrootディレクトリに遷移します。そこで、例えばhogeというリポジトリ名でリポジトリを作成したとします。その場合次のようにファイルを作成します。

````
mkdir hoge
````

作成したファイルに移動します。

````
cd hoge
````

その後、次のコードを一行ずつ実行します。

````

echo "# ripositoryname" >> README.md

git init

git add README.md

git commit -m "first commit"

git branch -M main

git remote add origin https://github.com/your_yousername/ripositoryname.git

git push origin main

````

ここで、私はReadme ファイルを作成せずに、Editor(VScode)でindex.html(GitHubPagesを表示するには必要)を作成し、3行目のタイミングで

````
git add .
````

を打つことが好きです！！git add .はすべての作成編集したファイルをadd するので楽です！！

以上で新規リポジトリとUbuntuファイルを連携できたのでガンガン編集してコミットしていきましょう！！

今回の記事は以上になります。ありがとうございました:ramen:
【SwiftUI】iPadでNavigationViewを使うと起動時に知らない白紙画面が表示される

## 概要

SwiftUIでアプリを作成するとき、NavigationViewを使用する方は多いと思います。　

筆者もその1人で、個人制作でアプリを作成しているときにNavigationViewを使ったのですが、審査に出す時に「iPadに対応させなさい」と言われてしまい。今までiPhoneで作成していたアプリを急にiPadでもビルドすることになりました。

その時に、iPadではNavigationViewをそのまま使うと起動時に呼び出されるViewがNavigation側に持っていかれてしまい、知らない白紙の画面が表示されることに気がつきました。

起こった現象と、解決策を書いておくので同じ現象で困った人は参考にしていただけると幸いです。

## NavigationViewとは？
SwiftUIのNavigationViewで何ができるのか、GPT-4に聞いてみました。

> SwiftUIのNavigationViewを使用すると、以下のことができます：

> - 階層型インターフェイスの作成: 複数のビュー間でのナビゲーションをサポートし、階層型のユーザーインターフェイスを構築できます。

> - ナビゲーションバーのカスタマイズ: タイトル、ボタン、スタイルなど、ナビゲーションバーの外観と動作をカスタマイズできます。

> - ディテールビューの管理: マスター・ディテールインターフェイスでディテールビューを表示および管理できます。

> - リンクの作成: NavigationLink を使用して、異なるビュー間の移動を実装できます。

>- アダプティブUIのサポート: 異なるデバイスや画面サイズに合わせてUIが適応します。

大体書きたかったことが3秒で出力されました。正直、こんな記事を読むくらいならChatGPTに聞いたほうが早いかもしれませんね😇

## プログラム
下のプログラムは、NavigationViewを実装し、NavigationBarTitleを実装した最小限のプログラムです。
~~~swift
import SwiftUI

struct ContentView: View {
    var body: some View {
        NavigationView {
            VStack {
                Text("Hello World")
                    .font(.largeTitle)
                    .padding()
            }
            .navigationTitle("Home")
        }
    }
}

#Preview {
    ContentView()
}
~~~
このプログラムは、iPhoneでは次のように表示されますが、、、、

<img width="400" alt="iPhone15" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/526861/5f701460-e3de-17b0-a832-4dd422c3540b.png">


#### iPadでは次のようになってしまい、思ったように表示されません。😭
<img width="５００" alt="iPad11" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/526861/f46a3748-d989-36ea-09f7-c81145ab750b.png">

## 解決方法
解決方法は至って単純で、NavigationViewに下記のプログラムを追加するだけです。
~~~swift
 .navigationViewStyle(.stack)
~~~

#### 全体像
~~~Swift
import SwiftUI

struct ContentView: View {
    var body: some View {
        NavigationView {
            VStack {
                Text("Hello World")
                    .font(.largeTitle)
                    .padding()
            }
            .navigationTitle("Home")
        }
        //これを追加する
        .navigationViewStyle(.stack)
    }
}

#Preview {
    ContentView()
}
~~~

## 最後に

このように実装することで、iPadでNavigationViewを使っても、知らない白紙のViewが表示されなくなります。

<img width="５００" alt="iPhone15" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/526861/2f1c4d30-344a-cc1d-f72e-eb8b26e86c74.png">

それではみなさん楽しいSwiftライフを〜〜〜！

終わり
Milk-v duoにDHT22センサをつないで気温と湿度を測定

## はじめに
秋葉原ロボット部の有志で、milk-v duoを購入し、個々人が様々な実験を行って、勉強会内で報告しています。

Milk-v duoは9ドルのrisc-vコンピュータとして知られています。
ハードウェアは以下の通りです。

1. CPUはCVITEKのCV1800B (C906@1Ghz + C906@700MHz)
1. 最高1 GHzで動作するデュアルRV64コア
1. 64 MBのラム
1. オプションのアドオンボードを接続すると10/100Mbpsの速度でイーサーネットに接続可能

Milk-v duoのビルド環境では、WiringXがサポートされているので、様々なセンサ類をGPIOに接続可能です。

この記事では、DHT22をつないで、気温と湿度を測定します。

## DHT22の接続
DHT22の3端子は、それぞれ、VCC、GND、SIGNALです。
VCCはDHT22を動作させるのに必要な電源を接続しますので、Milk-v duoの3V3端子に接続します。
GNDはMilk-v duoのGNDに接続します。
SIGNALはGPIOA15に接続します。

SIGNALの接続箇所は、「dht22.c」の「static int DHTPIN = 15;」で指定しています。
```dht22.c
// Ref: https://github.com/technion/lol_dht22/blob/master/dht22.c
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#include <wiringx.h>
#define MAXTIMINGS 85
static int DHTPIN = 15;
static int dht22_dat[5] = {0, 0, 0, 0, 0};
static uint8_t sizecvt(const int read)
```

## 気温と湿度の測定プログラム
まず、Milk-v duoアドベントカレンダー
https://qiita.com/advent-calendar/2023
の3日の
「Milk-v duoのクロスコンパイル環境をWSL上に作成して、Gitで公開されているプログラムを動かしてみる」
に従って開発環境を構築してください。
使用するプログラムは
https://github.com/milkv-duo/duo-examples
にあります。
「duo-examples」ディレクトリに移動したら、以下のコマンドで「dht22」ディレクトリで、プログラムをビルドします。
```
$ cd dht22
$ make it
```
「dht22」と「dht22.o」が生成していることを確認します。
```
$ ls
dht22　dht22.c　dht22.o　Makefile
```
「dtt22」をmilk-v duoに転送します。
milk-v duoのコマンドプロンプト上で先ほど転送された「dht22」を実行します。
```
# ./dht22
Humidity = 42.00% Temperature = 18.5 *C
Humidity = 42.00% Temperature = 18.5 *C
Humidity = 42.00% Temperature = 18.5 *C
```
現在の湿度と気温が表示されます。

他のセンサを接続したい場合、以下のページが参考になります。
https://milkv.io/docs/duo/application-development/wiringx

参考 https://milkv.io/docs/duo/application-development/sensor-demo
linuxで起動時にプログラムを自動で実行する方法

# ラズパイ起動時にprogramを実行したい！！！
今回はsystemdを使用してシステム起動時にPythonProgramを実行してみようという企画です
（私が忘れないためにも）
それではやっていきましょう！！！

# サービス用のファイルを作成:
/etc/systemd/system/ディレクトリに、サービスの設定ファイル（例: myscript.service）を作成します。
```bash
sudo nano /etc/systemd/system/myscript.service
```
以下は、myscript.serviceの内容の例です。パスやスクリプト名は実際のものに合わせて変更してください。

```ini
[Unit]
Description=My Script Service
After=network.target

[Service]
ExecStart=/usr/bin/python3 /home/admin/Library_Tool_Ver3/main.py
WorkingDirectory=/home/admin/Library_Tool_Ver3/
Restart=always
User=admin

[Install]
WantedBy=multi-user.target
```
- ExecStart: 実行されるコマンド。Pythonのパスとスクリプトのパスを正しく指定してください。
- WorkingDirectory: スクリプトの作業ディレクトリ。スクリプトが依存するファイルがあるディレクトリを指定します。
- User: サービスを実行するユーザー。ホームディレクトリのパーミッションに注意してください。


# systemdにサービスを登録:
- enable: サービスを有効にします。これにより、システム起動時に自動的にサービスが開始されます。
```bash
sudo systemctl enable myscript.service
```
- start: サービスを手動で開始します。
```bash
sudo systemctl start myscript.service
```

# サービスの状態を確認:
- サービスの状態やエラーメッセージが表示されます。問題があればそれを解決してください。
```bash
sudo systemctl status myscript.service
```

# ログの確認:
- サービスがエラーなく起動しているか確認するために、ログを確認します。
```bash
journalctl -u myscript.service
```


# まとめ

いかがでしょうか？これで、systemdを使用してPythonスクリプトを実行するサービスが設定され、起動するはずです.
他にもlinuxでは起動時に実行する方法が複数種類あるようなので、ぜひ調べてみてくださいね！