OmniAICreator/Qiita-1.07M huggingface dataset:
langchain を使ってローカルにダウンロードしたDeepSeekとollamaを使ってテキスト生成を行ってみる。

[前回の投稿](https://qiita.com/goodboy_max/items/bc2e2dbee63ee651f815)では、DeepSeekをローカルにダウンロードして ollama を使って動かすことができました。

ollama は 11434ポートのWebサービスとして裏で実行されていますので、langchain を使って ollama にアクセスしてテキスト生成を行ってみます。

langchain はLLMを活用するためのライブラリです。このライブラリの中に、ollama用のLLMs（OllamaLLM）というのがあり、テキスト生成や要約を簡単に行うことができますので簡単なサンプルを記載してみます。

参考↓
https://python.langchain.com/docs/integrations/llms/ollama/

# サンプルコード
ollamaが動作しているWebサーバの指定方法がわからなかったので探したら

Ollama: Add base_url and seed parameters #24735
https://github.com/langchain-ai/langchain/pull/24735

というのがありましたのでサンプルコードに加筆しています。

```python langchainOllamaLlms.py
from langchain_ollama.llms import OllamaLLM

# Ollama: Add base_url and seed parameters #24735
# https://github.com/langchain-ai/langchain/pull/24735

ollama = OllamaLLM(
    model="hf.co/bluepen5805/DeepSeek-R1-Distill-Qwen-14B-Japanese-gguf:latest",
    base_url="http://localhost:11434",
    seed=42
)

print(ollama.invoke("こんにちは"))
```
めっちゃ簡単ですね！

# 実行結果
```shell-session
> python .\langchainOllamaLlms.py
<think>
ユーザーが「おはようございます」と日本語で挨拶してきた。まず、丁寧に返事をする必要がある。元のメッセージは「こんにちは」だが、ユーザーが「おはようございます」を使っていることに注意する。

日本語での応対では、時間帯に合わせた挨拶を返すのが一般的だ。午前中であれば「おはようございます」、午後なら「こんにちは」になる。しかし、ユーザーが「おはようございます」と使っているので、それに合わせて返事をするのが自然だろう。

また、相手の状況や時間帯を正確に把握していないため、安全策として時間帯に関係なく丁寧な挨拶をするのも良いかもしれない。例えば、「おはようございます。どのようなご質問ですか？」と続けることで、ユーザーが求めている情報を引き出すことができる。

さらに、日本語での会話では「おはようございます」の後に続けて「どうぞよろしくお願いします」と続けたり、その後に質問を繋げると親切だ。ただし、ユーザーが何を求めているのかわからないため、まずは挨拶と簡単な誘導をするのが適切かもしれない。

ここで考慮すべき点は、日本語でのマナーである。例えば、「おはようございます」の後に「～です」と丁寧に終わらせるか、そのまま直接質問を始めるか。ユーザーが簡潔に質問したいのか、それとも丁寧な対応を求めているのかを見極める必要がある。

また、ユーザーが日本語でメッセージを送っていることから、日本語での会話が求められていると判断できる。そのため、回答も日本語で行うべきだ。ただし、元のメッセージが「こんにちは」だった点に注意し、時間帯によっては「おはようございます」と答えるのか、「こんにちは」と返すのか迷うかもしれない。

しかし、ユーザー自身が「おはようございます」と使っているため、それに合わせて同じように挨拶する方が自然だろう。例えば、「おはようございます。どのようなご質問ですか？」と返すか、あるいはより丁寧な形で「おはようございます。どうぞよろしくお願いいたします。どのようなお手伝いが必要でしょうか？」と続けることができる。

ただし、ユーザーが最初の挨拶だけで終わっている可能性もあるため、その後どのように進めればいいのか考える必要がある。例えば、次の質問を期待している場合、そのまま会話を続けていくべきか、それとも情報を求めるために追加の指示をするべきか。

また、日本語でのコミュニケーションでは、相手への配慮や丁寧さが重要である。そのため、挨拶だけでなく、その後の対応も適切であることが求められる。ユーザーが何を求めているのかを正確に把握するために、質問で誘導するのが効果的だ。

総合的に考えると、「おはようございます。どのようなご質問ですか？」と返し、その上で必要な情報を尋ねるのが良いだろう。これにより、ユーザーの求めている内容を正確に把握でき、適切なアドバイスやサポートができる。
</think>

**ステップバイステップでの対応：**

1. **時間帯の判断と挨拶の返答**
   - ユーザーが「おはようございます」と使用しているため、午前中の時間帯を想定し同様に返す。
   - 「おはようございます。どのようなご質問ですか？」で丁寧に応じる。

2. **会話の方向性の誘導**
   - 挨拶後に直接質問を開始することでユーザーのニーズを探る。
   - 「お手伝いが必要な場合は何でもおっしゃってください」と続けて親切さを示す。

3. **日本語マナーへの配慮**
   - 丁寧語を使用し、終止符で句末を締めくくることで格式に沿った会話となる。
   - 「どうぞよろしくお願いいたします」などの追加フレーズでより親切さを強調する。

4. **情報の正確な把握**
   - 質問を直接促すことでユーザーが何を求めているか迅速に判断可能。
   - 例：「例えば、どのような内容をお探しですか？」

**最終的な返信例：**

\```
おはようございます。どのようなご質問ですか？
どうぞよろしくお願いいたします。例えば、どのような内容をお探しですか？
\```

この対応により、ユーザーの求めている情報を正確に把握しつつ、日本語として適切なマナーを守ったコミュニケーションが実現できます。
```

GPUもちゃんと使っているのがわかります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/255677/73e3b933-9149-aa8d-1170-bf66b89acfdf.png)

以上です。
【ChatGPT】を使って、特定の記事や論文の要点をまとめてもらう方法です。


　どうも、カーブミラーです。

　今回は、ChatGPTを使って、特定の記事や論文の要点をまとめてもらう方法です。

:::note info
本記事は、ChatGPT（Plus版）
で行なっております。
画像はありません。あしからず。
:::
　ChatGPT等の動作状況を知らせる
　　OpenAIのステータスページ。
　　　[OpenAIステータス](https://status.openai.com/)
***
　こちらも載せますね。
　　[ChatGPTが使えない？ログインできない・反応しない原因やエラー時の対処法を解説](https://aismiley.co.jp/ai_news/chatgpt-error-resolution-explanation/)
***
　まずは、ニュースです。

　米国で
　　アメリカンフットボールの祭典、
　　　スーパーボールが
　　　　はじまりました。

　そこに
　　OpenAIが初めてのCMを
　　　打っています。

　米メディアによると
　　60秒で1400万ドル（約21億円）😵‍💫

　そのCMは、こちらです。
　　[OpenAI　YouTube動画](https://youtu.be/kIhb5pEo_j0?si=lU04OlcH7XmdQWTo)
  
***
　次に

　サムがブログを更新しました。
　　[サム・アルトマンブログ](https://blog.samaltman.com/three-observations)

　『３つの観察』というタイトルで
　　以下について述べています。

　　1. 優れた創造的出力の源
　　2. 技術の発展と機会の増大
　　3. 人間の行動の変化は遅い
***
　では、【本題】です。

　今回は、
　　ChatGPTを使って、
　　　特定の記事や論文の要点を
　　　　まとめてもらう方法です。

　記事や論文は
　　その記述者によって
　　　書き方が異なりますが、
　　　　前書き、本文、後書きで
　　　　　書かれることが
　　　　　　多いかと思います。

　しかし、
　　何を言いたいのかわからないとか
　　　長過ぎて読んでる時間が
　　　　もったいないとか
　　　　　思うこともしばしば。
***
　Web検索を使うことが前提ですが、
　　次の手順で要約してもらえます。

　手順
　❶URLをコピーする。
　　（方法はブラウザによります）
　❷ChatGPTに“要約して。”と入力。
　❸URLをペーストする。
　❹送信。
***
　なお、
　　直接アクセスすることが出来ず、
　　　エラーとなる場合があります。

　　これはサイトの方針ですから
　　　仕方ありませんね。

　　サイトに入って、
　　　記事を読める状態であれば、
　　　　記事すべてをコピペすれば
　　　　　イケます。

　また、
　　エラーではなく、
　　　間違った内容を
　　　　出力してくる場合もあります。

　　原因はわかりませんが、
　　　記事が一般公開されていない
　　　　可能性がありそうです。

　　この場合も
　　　すべてコピペで
　　　　解決できます。
***
　“すべてコピペだと、余計な情報が”と
　　思われるかもしれませんが、
　　　大丈夫です。

　　ChatGPTが意図を汲み取って
　　　処理してくれます。
***
　それから
　　ふつうに記事を読んでいると
　　　広告が入っていますよね。

　　スマホで読んでいると、
　　　とても邪魔で、
　　　　広告の上でスライドさせても
　　　　　動かなかったり
　　　　　　そのサイトに飛んだりして
　　　　　　　イラつきます。

　　その点、
　　　ChatGPTならば
　　　　“以下の記事だけ出力して。”と
　　　　　入れて、すべてコピペすれば
　　　　　　記事だけを読めます。

　　　単純に出力するのではなく、
　　　　読みやすくしてくれるので
　　　　　ありがたいですよ。

　　これの欠点は
　　　画像は考慮されない、という点。

　　　そこは、
　　　　記事の方を見るしか
　　　　　ありませんね。

　みなさんの
　　作品制作の糧に
　　　なれば、幸いです。

　今回は、ここまで。
qemu内のwindowsの時刻自動修正

# 内容
qemuでwindowsを起動すると
ホストの時間が自動的に取得されて
時刻設定されるが、9時間ずれて表示される

例えば、ホストの時間が`Mon Feb 10 11:37:09 AM JST 2025`だとすると
qemuにはUTCの`Mon Feb 10 02:37:09 AM UTC 2025`が渡って
それがJSTとして解釈されて`02:37`で表示される
これを`11:37`で表示する

# 環境

- fedora 40
- QEMU 8.2.8

# 手順

起動時のコマンドに `-rtc clock=vm,base=$(date +"%Y-%m-%dT%H:%M:%S")`を含める

例)
```shell
sudo qemu-system-x86_64 -M q35,smm=on -smp 2 -m 8G /opt/vdisk/win11.qcow2 -net nic -net user,smb=/opt/share,hostfwd=tcp::445-10.0.2.15:445 -enable-kvm -usb -device usb-host,vendorid=0x0403,productid=0x6001 -device usb-host,vendorid=0x0403,productid=0x6015 -rtc clock=vm,base=$(date +"%Y-%m-%dT%H:%M:%S")
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3786381/3b7e611e-9f47-b812-7bd1-c075c186038f.png)
【Rails】route.rbのパスの指定方法

# はじめに
こんにちは。アメリカで独学でエンジニアを目指している者です。
現在 Rails を勉強中で、routes.rb のルーティングの指定方法について、忘れないうちにまとめておきたいと思い、この記事を書きました。

## ルーティングとは
Railsでは、ユーザーがアクセスしたURL（例: GET /help）をどのコントローラのどのアクションに結びつけるかを、`routes.rb` というファイルで定義します。典型的には以下のような記述を行います。
```ruby
Rails.application.routes.draw do
  get '/help', to: 'static_pages#help'
end
```

この場合、`"/help"` に GETリクエストが送られると、`StaticPagesController` の `help` アクションが実行されるという設定になります。

## 名前付きルートヘルパーについて
Railsは、ルーティングで定義したURLに応じて**名前付きルートヘルパー**というメソッドを自動生成します。例えば、上の例では以下のヘルパーメソッドが使えるようになります。

* `help_path` -> `"/help"`
* `help_url` -> `http://localhost:3000/help` (開発環境の場合)

Railsの慣習としては、ビューなどでリンクを貼る場合には `help_path` を使うことが多く、リダイレクトするときには `help_url` を用いることがあるようです。

## ルーティングの書き方
Railsチュートリアルでは2つのルーティングの書き方について習いました(8章まで)。
* `get '/help', to: 'static_pages#help'`(URL指定)
* `get 'static_pages/help'`

### `get '/help', to: 'static_pages#help'`(URL指定)
1. **URLがシンプル**
コントローラ名を表示しないので、`/help` のような短いURLになります。ユーザーにも覚えやすく、入力しやすいです。

2. **SEO（検索エンジン最適化）に良い**
シンプルなURLは検索エンジンにも好まれ、サイトの評価が上がる可能性があります。

3. **名前付きルートが自動生成される**
例えば '/help' を定義すると、`help_path`・`help_url` というシンプルな名前付きルートが生成されます。

### `get 'static_pages/help'`
1. コントローラとアクションの対応が明確
static_pages/help のように書くことで、「コントローラ名が static_pages でアクションが help なんだな」とひと目で分かります。

2. 小規模・学習用途で手軽に使える
開発の初期段階や学習目的であれば、特別にURLをカスタマイズしなくてもよいケースがあります。


## どちらのルーティングの書き方を使うべきか
Railsチュートリアルでも解説されていますが、上記の内容を踏まえると、`get '/help', to: 'static_pages#help'`（URL指定）の書き方を採用するのが一般的におすすめです。
ユーザーにとっては `/help` や `/about` のように短いURLのほうが理解しやすく、入力もしやすいでしょう。
また、`'static_pages#help'` は「StaticPages コントローラーの help アクションを使う」と明示的に指定しています。
一方、`get 'static_pages/help'` は URLからコントローラーとアクション名をRailsが推測しているため、誤ったルーティングが設定されるリスクがわずかにあるといわれています。

# まとめ
Railsのルーティングには、`get '/help', to: 'static_pages#help'` のようにURLを明示的に指定する方法と、`get 'static_pages/help'` のようにコントローラー名とアクション名をそのまま記述する方法があります。
どちらにも利点はありますが、一般的にはシンプルでわかりやすいURLを使用したほうがユーザーに親切であり、SEOの面でもメリットが大きいです。ぜひアプリケーションの目的に合わせて使い分けてみてください。
Python3お勉強メモ（リストの繰り返し処理）

リストの繰り返し処理にもいくつかやり方があるみたいなので整理

##### 基本の繰り返し
リストを参照するだけならこの書き方で問題なさそう
``` python
li = [1, 2, 3]
for a in li:
    print(a)
```

##### インデックスで繰り返し
組み込み関数enumerate()を使う形
https://docs.python.org/ja/3/library/functions.html#enumerate

要素だけでなく、インデックスも欲しい場合に
``` python
li = [1, 2, 3]
for i,a in enumerate(li):
    print(i,a)
```

##### インデックスで繰り返し（要素の変更あり）
range()とlen()を組み合わせてC言語のようなインデックスで参照する形
要素の変更が伴う場合に
``` python
li = [1, 2, 3]
for i in range(len(li)):
    li[i] = i*2
```
@dataclassとEnum使ってたらはまった話


普段、pythonでコードを書いているのですが、先日`@dataclass`とEnumの組み合わせではまったので備忘録として記載します。
pythonについては既存のコードを見つついじる程度の知識しかないので、そもそもこんな風につかわないよ！等あるかもしれません。
既存コードを参考に書いていましたが、Enumに`@dataclass`つける意味あるのか？と最近ではうっすら思っていますが、事象として興味深かったのでまとめました。

# どうはまったのか
以下のようなEnumを定義しました。

```
@dataclass
class Fruits(Enum):
    APPLE = 0
    BANANA = 1
    CHERRY = 2
```
処理の都合上、APPLEとBANANAのみ処理をしたかったので、以下のようなコードを描きました。

```
if fruit in [Fruits.APPLE, Fruits.BANANA]:
    # リンゴかバナナであれば処理をする
```

`fruit=Fruits.CHERRY`を代入し、実行したところ、処理が行われてしまいました。
この辺りを整理してみたところ、以下のような結果となりました。

|式|結果| |
|---|---|---|
Fruits.CHERRY in Fruits|True| |
Fruits.APPLE in [Fruits.APPLE, Fruits.BANANA]|True| |
Fruits.CHERRY in [Fruits.APPLE, Fruits.BANANA]|**True**|Falseを想定したのにTrueになっていた|
Fruits.CHERRY is Fruits.APPLE or Fruits.CHERRY is Fruits.BANANA|False| |

## dataclassを付けない場合
一方で、以前に同様のコードを書いたときは動いていた記憶があったので、確認してみるとそのコードには`@dataclass`がついていませんでした。


```
class Vegetables(Enum):
    AVOCADO = 0
    BROCCOLI = 1
    CARROT = 2
```

こちらは以下のような結果となりました。

|式|結果| |
|---|---|---|
Vegetables.AVOCADO in Vegetables|True|
Vegetables.AVOCADO in [Vegetables.AVOCADO, Vegetables.BROCCOLI] |True| |
Vegetables.CARROT in [Vegetables.AVOCADO, Vegetables.BROCCOLI] |**False**|想定通り|
Vegetables.CARROT is Vegetables.AVOCADO or Vegetables.CARROT is Vegetables.BROCCOLI|False| |

## なぜ？
問題の起こった評価式をログで出力してみたところ、以下のようになりました。

|式|結果| |
|---|---|---|
|[Fruits.APPLE, Fruits.BANANA] | `[Fruits(), Fruits()]`
|[Vegetables.AVOCADO, Vegetables.BROCCOLI] | `[<Vegetables.AVOCADO: 0>, <Vegetables.BROCCOLI: 1>]`|

`@dataclass`がついていない場合(Vegetables)はそれぞれの要素になっているのに対して、`@dataclass`がついている場合(Fruits)はオブジェクトになっている？ようです。(ちょっとこへんよくわかっていないです)
これによって`fruit in [Fruits.APPLE, Fruits.BANANA]`はfruitにCHERRYが入っていても、Fruitsの要素だったらオッケー！といった評価になったようです。

# 最後に
この事象はユニットテストが通らなかったことで発見したので、ユニットテストは本当に大事だなと思います。
既存コードにあるからといって、何となくコピーで使うのは良くないなと改めて思いました。
 

やっぱり、Enumに`@dataclass`ついてるのおかしくない？
CH32X035で充電器をPPS制御する

# 経緯
　「[前回](https://qiita.com/hi631/items/5613f73f4001111acf35)」CH32X035でPD制御を行い、充電器から5V以上の電圧を取り出した。
　しかし、PD制御では充電器が有する固定電圧しか指定できない。
　そこで、次なる方法として自由に電圧指定出来るPPS制御を試みる事にした。
　◆◆◆　折角買ったんだから、試してみよう　◆◆◆
　アリエ〇の充電器も、誇大広告が多いと思うな。

# 推進方法
　PPS制御の実例は何点か有るが、制御の資料は見つけられなかった。
　そこで、実例の解析を試みたが、プログラムが長く良く判らん。
　そこで、取敢えず実例のコンパイルから始める事にした。
　　※今回は実例から不要な部分を削ぎ落し、多少色を付けただけ。
　　※ソース公開に感謝します。
  
  　「[CH32X035-USB-PD-Adapter(Github)](https://github.com/wagiminator/CH32X035-USB-PD-Adapter)」

# 必要なハード
　◇CH32X035のチップが乗った基板
　　CH32X035F8U6 Mini Core Board。
　　アリエクで1200円/5個程度で販売していた。
　　日本のアマゾ〇では売ってないようだ。
  ![board.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/159764/cb4a9d00-bb8d-d512-91af-79d7ee027b4a.jpeg)

　◇開発装置
　　WCH-LinkE
　　同様に500-1000円程度で販売している。日本でも売られている。
![wch-linke.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/159764/a73799af-4d32-c11e-a428-c25a3f6d2875.jpeg)

# 接続
　下記６本を、基板とWCH-LinkE間で接続。下記２本はプログラム内で使用。
　　基板　　　WCH-LinkE
　　３Ｖ３　　３Ｖ３　　　電源
　　ＧＮＤ　　ＧＮＤ　　　グランド
　　ＤＣＫ　　ＳＷＣＬＫ　デバッククロック
　　ＤＩＯ　　ＳＷＤＩＯ　デバック信号
　　Ａ２　　　ＲＸ　　　　シリアル送信
　　Ａ３　　　ＴＸ　　　　シリアル受信

# 開発環境
　◇コンパイラ
　　実例のコンパイルには、LINUX環境が必要でありこの準備をする。
　　と言っても、当方はWindows環境なので「WSL」を使う。
　　　※WSL: Windows Subsystem for Linux　WindowsのサブシステムとしてLINUXが動作。
　　「[マイクロソフトのサイト](https://learn.microsoft.com/ja-jp/windows/wsl/install)」に詳しく書かれてている。
　　　※ディフォルトではubuntuがインストールされる。
　　　　当方の環境ではubuntuでは環境が構築できず、追加でDebianを導入した。
　　次はツールチェーンを導入するのでLINUXを起動し、コンソール画面で下記コマンドを入力。
　　　sudo apt-get install gcc-multilib gcc-riscv64-unknown-elf
　　下記コマンドで導入の確認が出来と思う。
　　　/usr/bin/riscv64-unknown-elf-gcc --version
　　下記の様な表示が出れば導入成功。
　　　riscv64-unknown-elf-gcc (12.2.0-14+11+b1) 12.2.0
　　　Copyright (C) 2022 Free Software Foundation, Inc.
　　　　※ch32v003funの導入は不要のようだ。
　　　　※LINUXには詳しく無いので、同じやり方で上手く行くとも限らない。
　　　　　ダメな場合は、自分で探してバンバンしてくれ。
　◇ダウンローダー
　　WCH-LinkUtility
　　「[ＷＣＨ社](https://www.wch-ic.com/products/WCH-Link.html)」より、WCH-LinkUtility.ZIPを落す。

　　必要ならドライバーを入れ、デバイスマネージャーで確認する。
　　　※Interface-WCHLinkEと、WCH-Link SERIAL(COMx)が追加されている。
　　WCH-LinkUtility.ZIPを適当なディレクトリに解凍。WCH-LinkUtility.exeを起動。
　　画面のCore:をRISC-Vに、Series:をCH32X035/34/33に変更。
　　基板とWCH-LinkEを接続し、USBに刺す。
　　Active WCH-Link Mode : (画面下の方)をWCH-LinkRVに変更し、「Get」「Set」を順に押す。
　　Query Chip Info(画面上３個目のアイコン)を実行して、MCU ID等が読み込まれれば接続は正常。
　　WSLからWCH-LinkEを操作する方法を(私は)知らないので、TargetFile:	として、
　　下記例での入力内容を示す。※usrnameは各人の環境に合わせる。
　　WSL環境でコンパイルが通ったなら、Execute(画面上４個目のアイコン)を押す。
![wch-link.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/159764/caed71ef-50e4-e438-8862-b32693c5bde3.jpeg)

# サンプルソフト(CH32X035_adp)の説明

　「[ソフトの格納場所(Github)](https://github.com/hi631/CH32X035) 」のCH32X035_adpディレクトリに有る。

　本ソフトはCH32X035の動作確認を目的としている。
　チップと基板の動作確認コマンドを、BASICコマンドとして発行する。
　動作確認の為にTINY BASICに下記を追加している。
　◇ＰＰＳ　「PPS xxxxx」(xxxxxは電圧、単位はmV)。
　◇ＬＥＤ　「LED x」(xは1又は0)で、基板上のLEDが明滅。

　BASICが起動したらPPS xxxxxと入力すると、xx.xxxVの電圧が発生する。
　　※起動後に充電器との接続を、一端オンオフする必要が有る。※充電器のリセット方法が判らん。
　　※放置していると数秒で消えるので、継続的にコマンド発行が必要。
　

  ![pps_out19.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/159764/739deacf-48f8-990b-4468-e18bd95a9bd4.jpeg)


# 感想
　一応動作はしたが、ソフトをWindows環境に持って行きたい。
　ライブラリが異なって居る様で、とんでもない量のエラーが出る。
　なお、上記記載内容は全て無保証であり、各自の責任においてご利用願います。
サーバーからクライアントへ Promise をそのまま渡せる時代へ！

# サーバーからクライアントへ Promise をそのまま渡せる時代へ！

こんにちは、React の世界は日々進化していますね。最近のアップデートで、Server Component から Client Component へ Promise を返して、さらにデータストリーミングができるようになったんです！
この新機能のおかげで、サーバーで作成した Promise をそのままクライアントに渡し、**Suspense** と連携させることで、シームレスに非同期データを扱えるようになりました！

## どういうこと？

簡単に言うと、サーバー側で Promise を生成し、そのままクライアント側で `use` API を使って解決できます。今までなら、サーバーサイドで await してからデータを props として渡す必要がありましたが、これでレンダリングのブロッキングを回避できる可能性が広がります。

## こんなコードで実現！

まずはサーバー側で Promise を生成してクライアントコンポーネントへ渡す例です。以下は `src/App.js` のコードです。

```jsx:src/App.js
import { Suspense } from "react";
import { fetchMessage } from "./lib.js";
import { Message } from "./message.js";

export default function App() {
  // サーバー側で非同期にデータ（Promise）を取得
  const messagePromise = fetchMessage();

  return (
    <Suspense fallback={<p>⌛メッセージを取得中...</p>}>
      {/* Promise を props として渡す */}
      <Message messagePromise={messagePromise} />
    </Suspense>
  );
}
```

次に、クライアント側で Promise を `use` フックで解決する例です。こちらは `src/message.js` に記述しています。

```jsx:src/message.js
"use client";

import { use } from "react";

export function Message({ messagePromise }) {
  // Promise の解決を待って値を取得
  const messageContent = use(messagePromise);
  return <p>メッセージ: {messageContent}</p>;
}
```

## この機能がもたらすメリット

- **ストリーミングでのデータ処理**  
  サーバーで Promise を作成し、その Promise をクライアントで解決するため、サーバーの処理がクライアントのレンダリングをブロックしません。  
- **簡潔なコード**  
  従来のデータフェッチパターンに比べ、サーバーコンポーネントとクライアントコンポーネントの連携が非常にスッキリしています。

## 少しだけ注意点

- `use` は React コンポーネントまたはカスタムフック内でのみ使えます。このため、ループや条件分岐の中でも使える柔軟さはありますが、必ずコンポーネント内で呼び出すようにしましょう。
- Promise の解決値はシリアライズ可能である必要があります。関数などシリアライズできない値は渡せないので注意してください。

## まとめ

React 19 で追加された `use` API を使えば、サーバーで生成した Promise をクライアントにそのまま渡してデータをストリーミングすることが可能になりました。  
これにより、データフェッチのパターンが格段にシンプルに！  
アプリケーションのパフォーマンス向上やコードの簡潔さを追求する方には、まさに朗報ですね。

React の最新情報については、公式ドキュメントもチェックしてみてくださいね。  
[React Docs - Streaming data from the server to the client](https://react.dev/reference/react/use#streaming-data-from-server-to-client)

## 参考資料

- [React Server ComponentsでのPromiseの最適な扱い方 #promise - Qiita](https://qiita.com/reoring/items/2c04963da0409c7b9715)
- [React Server ComponentsにおけるPromise処理の仕組み #promise - Qiita](https://qiita.com/reoring/items/3e1c0ad5e02fba39b748)
- [Web Streams APIの概要と仕組み #React - Qiita](https://qiita.com/reoring/items/2c502d15a7d3c97d7b5d)
SnowPro Core取得にむけて行動開始

# SnowPro Core取得に向けて行動開始  
1月末にSnowflakeに携わることがきまり、急ピッチで準備をすすめています。ひとつのケジメとしてSnowPro Core資格の取得を目指して本格的に動き始めましたが、思った以上に道のりは長そうで、試行錯誤の毎日です。今回の記事では、ここまでの取り組みや感じたこと、悩を共有したいと思います。


## コミュニティは温かい

最初の一歩は、Snowflakeのユーザーコミュニティに参加したことでした。Snowflakeの経験が豊富な方々からのアドバイスをいただき、何とか進めることができています。

- **ご紹介いただいた教材など**  
まず取り組んでいるものはこちらです
  - 「Snowflake入門 - ゼロからはじめるSnowflake」  
  - 「SNOWPRO Ⓡ CORE COF-C02 AND COF-R02 試験学習ガイド」  


## 「Snowflake入門 - ゼロからはじめるSnowflake」について

トライアル環境のセットアップから基本的な操作までを、「Snowflake入門 - ゼロからはじめるSnowflake」を参考に進めました。全体知識が薄いなか進めているので、触ってみたものの「本当に身についているのか？」という不安は残っています。たとえば、簡単なクエリの実行はできるようになったけれど、バックグラウンドで何が起きているのかがまだ曖昧です。また、Time Travelやデータ共有機能など、Snowflake特有の機能については理解が浅いと感じています。

https://quickstarts.snowflake.com/guide/getting_started_with_snowflake_ja/index.html?index=..%2F..index#0




## 「SNOWPRO Ⓡ CORE COF-C02 AND COF-R02 試験学習ガイド」  について


当初自力でたどり着けず、こちらもコミュニティの優しい方にお忙しい中サポートいただいてしまいました。いつか必ず恩返ししなければいけません。初心者に優しいコミュニティはプロダクトも発展するとどこかでききました（使う人が増え、習得難易度も下がるため私もそう信じています。）

https://training.snowflake.com/lmt/clmsBrowseV2.prMain?site=sf&in_region=us

ガイドへのたどり方はこちら
->[COF-C02] SnowPro Core試験学習ガイド
->Enroll
->play
->SNOWPRO Ⓡ CORE COF-C02 AND COF-R02 試験学習ガイド　最終更新日：2025年01月15日


現在進めているのはこちらの内容をピックアップしながら確認していく方法です。
中でも注目したのが、"LEVEL UP"というトレーニングプログラムです。こちらは、Snowflakeのコアコンセプトを段階的に強化できるよう設計されております。
しかし、トピックが非常に多く、一通りこなすには相当な時間がかかりそうで、まだすべてを終えられていません。自分のペースで進めるべきだとはわかっていますが、焦りが募っているのも事実です。



## 会社からのプレッシャーとどう向き合うか

資格取得に向けたプレッシャーを感じる一番の理由は、会社からの「資格はまだ？」という質問です。上司からのプレッシャーは、単なる期待ではなく業務上の要請に近いものもあります。1月末に業務支持をうけてから2週間。なかなかスムーズにはいきません。
当然のこととはいえ、まだ準備が整っていない現状ではしんどさを感じています。ただ、このプレッシャーが逆にモチベーションにつながる部分もあり、少しずつ前進できています。

2/12(火)にはコミュニティ主催の初心者勉強会がタイムリーにあり、仕事の移動中と被っていますが参加させていただく予定です。


## 問題集はいつ、どれをつかうべきか

資格取得には問題集が必須だと考えています。google検索やX検索、コミュニティでのおすすめを総合すると、使うべき問題集はほぼ絞られました。英語のUdemyに2つほど、日本語のnoteに1つありました。
英語は忌避するほどではないにしろ学習コストを考えると日本語noteを使おうと考えています。ちょうどこの週末でX(旧Twitter)にて日本語noteだけで合格したとのツイートを発見。
その方、Snowflake DataSuperHero 2024,2025という物凄い肩書の方なので信憑性は高いと思います。

あとは、いつ問題集を購入するかどうかで迷っています。効率よく対策したい気持ちはあるものの、「問題集だけで十分か？」という疑問も残ります。いまはトライアル環境（30日限定）でじっくり環境になれるべき時期なのではないか。

---

## 今後の学習計画

現時点での課題と今後の計画は以下の通りです：

1. **LEVEL UPプログラムの進捗管理**  
   量が多いため、進捗を可視化しながら少しずつ進める。
   
2. **問題集を購入して解き始めるかの判断**  
   実際の試験問題に触れることで、苦手分野を明確にする。

3. **弱点克服**  
   わからない点をまとめ、公式ドキュメントで確認する。
   ChatGPTはハルシネーションが多く、資格試験勉強での使い道がわからない

---
データ拡張

# データ拡張とは
機械学習の世界でコンピューターに画像認識や推論を行わせようとする際に訓練データを学習させる必要があります。この訓練データですが、実際の現場では充実していないケースが珍しくありません。その問題を解決する方法の１つが「データ拡張」です。

# 具体的な加工方法
データ拡張ではデータの水増しをします。画像の訓練データを例に説明しましょう。画像認識ではその画像が人なのか車かなどを判別するために様々な訓練データが必要になります。少ない訓練データをどのように水増しするかというと、画像を回転・拡大・縮小・一部を切り取るなどして訓練データを増やします。回転する際はその角度を複数設定し、他の加工であっても様々なパラメータを変更することができます。このような加工によって1つのデータから複数の訓練データを生み出すことが可能になりモデルの能力を向上させることができます。
PHPUnit9系から10系のバージョンアップをClineとRectorを使用して行う


# はじめに

PHPUnit9系から10系にバージョンアップした際に、やったことをまとめていきます。
今回は、RectorやClineを組み合わせてすんなり上がったので、書きたくなってしまいました。


## コードを修正する必要のある主な変更点

 - @testはアトリビュートで#[Test]にする

以前の書き方
```php5
    /**
     * @test
     */
    public function sample(): void {
        $this->assertTrue(true);
    }
```

10系で推奨されている書き方
```php5
    #[Test]
    public function sample(): void {
        $this->assertTrue(true);
    }
```


 - @dataProvider もアトリビュート #[DataProvider('someProvider')]
 - データプロバイダー関数はpublic かつ staticにする

以前の書き方

```php5
    /**
     * @test
     * @dataProvider sampleDataProvider
     */
    public function sampleDataProviderTest(int $a, int $b, int $expected): void {
        $this->assertSame($expected, $a + $b);
    }

    public function sampleDataProvider(): array {
        return [
            [1, 1, 2],
            [1, 2, 3],
            [2, 2, 4],
        ];
    }
```
10系で推奨されている書き方
```php5
    #[Test]
    #[DataProvider('sampleDataProvider')]
    public function sampleDataProviderTest(int $a, int $b, int $expected): void {
        $this->assertSame($expected, $a + $b);
    }

    public static function sampleDataProvider(): array {
        return [
            [1, 1, 2],
            [1, 2, 3],
            [2, 2, 4],
        ];
    }
```

## その他変更点

 - 非推奨な書き方をしているテストがある場合、PHPUnit Deprecations: 1という形で個数を教えてくれるようになった
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/330768/168b9d56-4627-6dc8-b7be-593461b61edb.png)


# 課題
 - 今回のバージョンアップで非推奨な書き方となってしまったテストコードがたくさん出てきた
 - phpunit.xmlに関しても非推奨な書き方として、警告が出るようになってしまった


# やったこと

### Rectorで一括変換
https://github.com/rectorphp/rector-phpunit

単純な一括変換はRectorを使うと便利である

```rector.php
use Rector\Config\RectorConfig;
use Rector\PHPUnit\Set\PHPUnitSetList;

return RectorConfig::configure()
    ->withSets([
        PHPUnitSetList::PHPUNIT_100,
    ]);
```

### clineでAIにphpunit.xmlを編集してもらう

設定ファイル系は、AIに書かせると精度が高い結果を得られる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/330768/31718d61-8773-2241-a2dd-c092adeebd9e.png)

その後ドキュメントを見て変更内容が正しいか確認
https://docs.phpunit.de/en/10.5/configuration.html


### phpunit.xmlに非推奨コードの箇所を出力するオプションを追加

```phpunit.xml
displayDetailsOnPhpunitDeprecations="true"
```

```console
1 test triggered 1 PHPUnit deprecation:

1) Tests\Unit\SampleTest::sampleDataProviderTest
Data Provider method Tests\Unit\SampleTest::sampleDataProvider() is not static
```

# まとめ

以上の方法で、修正箇所が大量にあるPHPUnitのバージョンアップを比較的対応時間少なく対応できた。
すでにPHPUnit11もリリースされており、近い未来にバージョンアップ対応予定であるので忘れないためにまとめておきます。
React のバージョン更新を手伝ってください

これはカード音楽ゲームで、UI を改良するつもりです。
[Github link](https://github.com/haruto2930485/music-game)
このゲームは数年前に作られたので、始める前に node js のバージョンをアップグレードする必要があります。
chatgpt でいろいろ試しましたが、できませんでした。
プロジェクトをチェックして、教えていただけたらと思います。
🙏
Flutterでimage_pickerライブラリを画像ファイルをアップロード

Flutterでアプリを作っていて、端末の画像ファイルをアプリ上でアップロードして
使うような実装する機会がありました。
初めてで、うまくいかないこともあり、備忘録として手順などを残します。

iOSシュミレータで動かすことを前提としています。

## image_pikerの導入
Flutterで画像をアップする手法としてはimage_pikerライブラリを使うのが一般的みたいです。
https://pub.dev/packages/image_picker
ドキュメントを参考に、インストールします。
```
flutter pub add image_picker
```
続いて、pubspec.yaml に追記します
```
dependencies:
  image_picker: ^1.1.2
```

## 下準備
アプリから端末の画像にアクセスするためには、権限を付与？
するような設定をflutterでやってあげないといけないようです。
(公式ドキュメントにも書いてますが、私は見落としエラーにハマりました、、、。)

![ぴckwr.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3332453/deea8c2f-5e3b-8a10-ff98-d6bf3cc27a49.png)


iosシュミレータの場合、下記の手順で設定を行います。
flutterプロジェクトの中にInfo.plisというファイルがあるので、
ここに設定を追加します。
場所: ios/Runner/Info.plis
![image-pi.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3332453/255a73ff-064e-7261-52f6-547309e6c0ae.png)

設定は、下記を追加してください。
```:Info.plis
	<key>NSPhotoLibraryUsageDescription</key>
    <key>NSCameraUsageDescription</key>
```
これで、下準備が整いました。

## 画像をアップする処理にトライ
それでは、画像をアップする処理を書いてみます
画像をアップする関数を作ってみましょう。

画像アップロードを使いたいファイルに、下記のような関数を書きます。
```dart

XFile? image;//画像ファイルを格納する変数
final imagePicker = ImagePicker();

//端末から画像を選択
Future pickImage() async {
    final image = await ImagePicker().pickImage(source: ImageSource.gallery);
    // 画像がnullの場合戻る
    if (image == null) return;
    final imageTemp = XFile(image.path);

    //画像ファイルをimage変数に格納
    setState(() => this.image = imageTemp);
    
}
```

この関数を、ボタンのonPressに設定し、ボタンを押すと
画像を選択するドロワーが出現するような処理が実現できます。
ボタンのWigetを下記のように追加してください。
```datr
    ElevatedButton(
      onPressed: () {
        pickImage();
      },
      child: Text("画像を開く"),
    ),
```
ボタンを押すと、下記のように画像を選択するドロワーが出現します。
![pikker.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3332453/b4ad7506-3b3a-6a9b-81a4-6352b809e0b6.png)

## アップした画像を表示
せっかくなので、アップした画像を表示したいですね。
Image.fileを使って表示できます。
実装例としては下記のようになります。
'dart:io'をインポートするのを忘れずに。
```dart

import 'dart:io'; 

Center(
  child: image == null
      ? const Text('画像が選択されていません')
      : Image.file(File(image!.path)),
),
```

以上、簡単ですがimage_pickerを用いたflutterでの画像のアップロード備忘録でした。
個人開発者なら知っておきたい！SQLiteデータ消失からの復旧術

こんにちは、個人でアプリを15本リリースしているYuKiOです。

個人開発をしていると、ユーザーから「データが消えた！」と問い合わせを受けることがあるかもしれません。通常、アプリではバックアップを取っていますが、先日、一部のユーザー環境で原因不明のトラブルによりバックアップが取得できず、さらにデータが欠損するという不具合に遭遇しました。

今回は、その状況から なんとかデータを復旧した方法 を共有します。SQLiteデータベースの破損を修復し、削除されたデータを可能な限り取り戻す方法を解説します。アプリは事前に不具合が出た特定のユーザーのみデータベースを引っこ抜けるようにしています。今回はそちらを送ってもらいました。使用環境はMacです。

## 1. 破損したデータの確認

最初に、データベースに freelist が含まれているかを確認します。これは、削除されたデータがまだディスク上に残っている可能性を示します。

### DB Browser for SQLite の準備

SQLiteデータベースを視覚的に管理するために DB Browser for SQLite をダウンロード・インストールします。
[DB Browser for SQLite](https://sqlitebrowser.org/)

### freelist の確認方法

DB Browser for SQLite で対象のデータベース (database.sqlite など) を開き、「実行」タブで以下の SQL を実行してください。
```
PRAGMA freelist_count;
```
結果が 0 ならば、削除されたデータはありません。

0 以外の値ならば、削除されたデータが復旧できる可能性があります。

## 2. 破損データを復旧する準備

sqlite3 の .recover コマンドを使用して、削除データを含む SQL スクリプトを出力します。

```
sqlite3 database.sqlite .recover > recovered_data.sql
```

database.sqlite は対象のデータベースファイル名に変更してください。

recovered_data.sql には復旧可能なデータが SQL 形式で出力されます。


## 3. 新しいデータベースを作成し、修復データを適用する

新しい sqlite データベースを作成し、修復データを適用します。
```
sqlite3 repaired_database.sqlite < recovered_data.sql
```
これにより、 repaired_database.sqlite に復旧データが反映されます。ここで、lost_and_found というテーブルが作成され、削除されたデータが含まれていることを確認できます。

## 4. 削除データの確認と整理

修復後の repaired_database.sqlite を DB Browser for SQLite で開き、lost_and_found テーブルを確認します。lost_and_found にはテーブルのレコードが混ざっているため、それらを適切なカテゴリごとに分け、CSVに保存します。

分離したCSVデータをPythonスクリプトなどで、再度SQLファイルに導入します。

Pythonスクリプトの詳細な実装は環境によって異なるため、ChatGPT に依頼してみてください。

## 5. 修復データを新しいデータベースへ取り込み

修復データを新しいデータベースへ統合します。分離したCSVデータからそれぞれのテーブルに挿入していきます。こちらもPythonスクリプトなどを使うと便利なので、ChatGPTに作成してもらってください。

## 6. 修復後のデータベースを暗号化して保存
メールなどで渡すことになるのでセキュリティのために、修復した  データベースを、セキュリティのために暗号化 ZIP に保存します。こちらをアプリに戻して、データベースに戻すことで、復元できます。

zip -e repaired_database.zip repaired_database.sqlite

実行後に パスワード を入力します。

パスワードはアプリの内部ドキュメントに記載 しておくと安全です。

## まとめ

以上の手順で、破損した SQLite データベースを修復し、削除データを復旧することができます。

### 🔍 おさらい

✅ freelist を確認し、削除データが残っているかチェック
✅ .recover で削除データを含む SQL を取得
✅ 新しいデータベースに復旧データを適用
✅ lost_and_found を CSV でエクスポートし、整理
✅ データを import_cleaned_data.py で統合
✅ 修復後のデータベースを暗号化 ZIP に保存


🚀 この記事が役に立ったら、ぜひシェアしてください！

# Xでアプリ開発の発信をしています。

<blockquote class="twitter-tweet" data-media-max-width="560"><p lang="ja" dir="ltr">HackerMemoを大幅にアップデートしたので、<br><br>海外向けのPVを作ってみました😆<br><br>夜なべして頑張って作ったので、拡散頂けたら泣いて喜びます😭🙏<br><br>音有りがオススメです！<br><br>元ネタわかる人いるかな〜🤔<br><br>アプリはこちら🔽<br>■iPhoneの方<a href="https://t.co/6T10L94Ld1">https://t.co/6T10L94Ld1</a><br><br>■Androidの方<a href="https://t.co/uBevCXrNw2">https://t.co/uBevCXrNw2</a> <a href="https://t.co/wiGLv46kaG">pic.twitter.com/wiGLv46kaG</a></p>&mdash; YuKiO｜アプリ個人開発｜Flutter × Firebase (@oo_forward) <a href="https://twitter.com/oo_forward/status/1348103082769453056?ref_src=twsrc%5Etfw">January 10, 2021</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
個人的備忘録：AWS・GCP・Azureのクラウド vs. 自社管理のオンプレミス——最適な選択を判断するために比較表を作ってみた

## はじめに

クラウドコンピューティングの普及により、企業のITインフラの選択肢として「クラウド」と「オンプレミス」のどちらを採用するかが重要なテーマとなっています。

:::note info
**それぞれにメリット・デメリットがあり、用途に応じて適切な選択をすることが求められます。**
:::

本記事では、クラウドとオンプレミスの違いを整理し、それぞれの特性について比較します。

## 書こうと思ったきっかけ

近年、AWSやGCPなどのクラウドサービスが一般的になり、多くの企業がクラウドを採用するようになりました。***一方で、金融機関や政府機関のように、依然としてオンプレミスを選択するケースもあります。***

:::note warn
このような状況を踏まえ、「**クラウドとオンプレミスのどちらを選ぶべきか？**」という疑問を持つ人が増えていると感じました。
:::

そこで、両者の違いやメリット・デメリットを整理し、選択の参考となる情報をまとめようと思いました。

## 実際に表形式でまとめてみた

### 1. 定義
- **クラウド**: 外部のクラウドプロバイダー（AWS, GCP, Azure など）のデータセンター上で提供されるサービスを利用する形態。
- **オンプレミス**: 自社やデータセンター内にサーバーやネットワーク機器を設置し、管理・運用する形態。

### 2. インフラの所有と管理

| 比較項目     | クラウド | オンプレミス |
|-------------|---------|-------------|
| **インフラ所有** | クラウドプロバイダーが所有 | 企業が所有 |
| **運用管理** | プロバイダーが大部分を管理（IaaS, PaaS, SaaS による違いあり） | 企業がすべて管理 |
| **物理設備** | 不要 | 必要（データセンター、電源、冷却設備など） |

### 3. コスト

| 比較項目     | クラウド | オンプレミス |
|-------------|---------|-------------|
| **初期コスト** | 低い（利用した分だけ支払う Pay-as-you-go） | 高い（サーバー、ネットワーク機器の購入が必要） |
| **運用コスト** | 変動費（使用量に応じて課金） | 固定費（設備保守、電気代、人件費など） |

### 4. スケーラビリティ（拡張性）

| 比較項目     | クラウド | オンプレミス |
|-------------|---------|-------------|
| **拡張の容易さ** | 容易（数クリックでリソース追加可能） | 困難（機器の追加・設置が必要） |
| **リソースの柔軟性** | 必要に応じて増減可能 | 事前に計画が必要 |

### 5. セキュリティとコンプライアンス

| 比較項目     | クラウド | オンプレミス |
|-------------|---------|-------------|
| **データ管理** | クラウド事業者の責任（リージョン選択で制御可） | 自社で完全に管理可能 |
| **セキュリティ** | プロバイダーが提供するセキュリティ対策を活用 | 自社の対策が必要 |
| **コンプライアンス** | 一部の規制ではクラウド利用が制限される場合あり | 業界規制に完全対応しやすい |

### 6. 可用性と災害対策

| 比較項目     | クラウド | オンプレミス |
|-------------|---------|-------------|
| **可用性** | クラウドプロバイダーの SLA（例: 99.99% 稼働保証） | 自社で冗長構成を組まないと可用性が確保できない |
| **災害対策（DR）** | マルチリージョン構成が容易 | 別データセンターの準備が必要 |

### 7. 利用ケースの違い

| クラウドが向いているケース | オンプレミスが向いているケース |
|----------------------|----------------------|
| スタートアップや小規模ビジネス | 金融機関や政府機関などの厳格な規制がある場合 |
| 需要変動が大きいアプリケーション | 低遅延・高性能が求められるシステム |
| 初期投資を抑えたい場合 | 既存のオンプレ環境が整っている場合 |
| グローバル展開を考えている場合 | 物理的なデータの所有・管理が必要な場合 |

### 8. まとめ

| 比較項目     | クラウド | オンプレミス |
|-------------|---------|-------------|
| **インフラ所有** | クラウドプロバイダー | 企業 |
| **運用管理** | クラウドが対応（一部企業も管理可） | 企業が管理 |
| **コスト** | 初期費用が低く、従量課金 | 初期費用が高く、固定費 |
| **スケーラビリティ** | 高い（リソースの増減が容易） | 低い（ハードウェア追加が必要） |
| **セキュリティ** | クラウド事業者が対策（設定次第） | 企業が完全管理 |
| **可用性** | SLAで保証される | 冗長化が必要 |
| **災害対策** | 容易に実現可能 | 自社で準備が必要 |

結論として、**クラウドは柔軟性とコスト効率を重視する場合に適しており、オンプレミスはデータ管理や規制対応を重視する場合に適しています**。

## まとめ

クラウドとオンプレミスは、それぞれ異なる特徴を持っています。

:::note note
***どちらを選ぶべきかは、コスト、運用負担、セキュリティ要件、ビジネスの柔軟性といった要素を総合的に考慮する必要があります。***
:::

クラウドはスケーラビリティやコスト効率を重視する場合に適しており、オンプレミスはセキュリティや規制対応が求められる環境に適しています。

それぞれの特性を理解し、自社のニーズに合ったITインフラを選択することが重要です。
cscの作法 その554

# 概要
cscの作法、調べてみた。
練習問題やってみた。

# 練習問題
メモ帳を書け。

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/eb8b38e6-215a-ea85-054b-7a5d98b6b574.png)

# サンプルコード

```

using System;
using System.IO;
using System.Windows.Forms;
using System.Drawing;
using System.Text;

namespace App
{
	public partial class Form1: Form {
		TextBox bo1;
		MenuStrip menuStrip1;
		ToolStripMenuItem openToolStripMenuItem;
		ToolStripMenuItem saveToolStripMenuItem;
		ToolStripMenuItem quitToolStripMenuItem;
		public Form1() {
			Text = "memo";
			ClientSize = new Size(500, 500);
			bo1 = new TextBox();
			bo1.Text = "本日は晴天なり";
			bo1.Multiline = true;
			bo1.Font = new Font("ＭＳ Ｐゴシック", 12);
			bo1.Dock = DockStyle.Fill;
			this.menuStrip1 = new MenuStrip();
			this.menuStrip1.Location = new Point(0, 0);
			this.menuStrip1.Name = "menu";
			this.menuStrip1.Size = new Size(353, 24);
			this.menuStrip1.TabIndex = 1;
			this.menuStrip1.Text = "menu";
			this.openToolStripMenuItem = new ToolStripMenuItem();
			this.openToolStripMenuItem.Name = "open";
			this.openToolStripMenuItem.Text = "open";
			this.openToolStripMenuItem.Click += new System.EventHandler(this.openToolStripMenuItem_Click);
			this.saveToolStripMenuItem = new ToolStripMenuItem();
			this.saveToolStripMenuItem.Name = "save";
			this.saveToolStripMenuItem.Text = "save";
			this.saveToolStripMenuItem.Click += new System.EventHandler(this.saveToolStripMenuItem_Click);
			this.quitToolStripMenuItem = new ToolStripMenuItem();
			this.quitToolStripMenuItem.Name = "quit";
			this.quitToolStripMenuItem.Text = "quit";
			this.quitToolStripMenuItem.Click += new System.EventHandler(this.quitToolStripMenuItem_Click);
			this.menuStrip1.Items.AddRange(new ToolStripItem[] {
				this.openToolStripMenuItem,
				this.saveToolStripMenuItem,
				this.quitToolStripMenuItem
			});
			Controls.AddRange(new Control[] {
				bo1,
				menuStrip1
			});
		}
		private void openToolStripMenuItem_Click(object sender, EventArgs e) {
			OpenFileDialog dialog = new OpenFileDialog();
			dialog.Filter = "テキストファイル(*.txt)|*.txt";
			dialog.Title = "開く";
			if (dialog.ShowDialog() == DialogResult.OK)
				bo1.Text = File.ReadAllText(dialog.FileName, Encoding.GetEncoding("UTF-8"));
		}
		private void saveToolStripMenuItem_Click(object sender, EventArgs e) {
			SaveFileDialog dialog = new SaveFileDialog();
			dialog.Filter = "テキストファイル(*.txt)|*.txt";
			dialog.Title = "保存";
			if (dialog.ShowDialog() == DialogResult.OK)
			{
				File.WriteAllText(dialog.FileName, bo1.Text);
			}
		}
		private void quitToolStripMenuItem_Click(object sender, EventArgs e) {
			DialogResult result = MessageBox.Show("メモ帳を終了します", "終了", MessageBoxButtons.YesNo);
			if (result == DialogResult.Yes)
			{
				Close();
			}
		}
		[STAThread]
		public static void Main(string[] args) {
			Application.Run(new Form1());
		}
	}
}

```

以上。
投資損益データの可視化をGeminiで

# きっかけ
2024年の大納会が終わったタイミングでこれまでの税引き後損益の累積を可視化しようと思った．コード自体はGeminiに聞いて小一時間でできたんだけど，だらけすぎた年始が過ぎて修論が始まって全力で駆け抜けて，気付けば2月．修論発表が終わったので記事を書く．

# 前提
- 言語はPython
- Googleアカウントを持っていること

# 今回やったこと
- CSVファイルの取得
- Geminiに頼んで作ってもらう
    - 銘柄ごとの税引き後損益を求める
    - ついでに可視化

# CSVファイルの取得
まずは使うデータを持ってくるために，楽天証券のページ上で実現損益のデータを`CSV`で取得する．
この辺の操作は私が参考にしたページで確認してほしい．
[Pythonの基礎も知らない超初心者が、楽天証券の実現損益データをPythonでグラフ化してみた](https://qiita.com/cotton11aq/items/da964da514bf0c3eaccc)
簡単に言うと，楽天証券に入って，口座管理 > 損益・税金履歴 > 実現損益 を開いて，CSV形式で保存する．ファイル名はソースコードに合わせて`trade.csv`にしておく．

:::note
参考にしたページでは「object型」から「int型」への変換がどうしてもできなかったと書いてあるが，AIで解決する．
:::

# Geminiに頼んで作ってもらう
Google Colaboratoryを開いて，Geminiに聞く．プロンプトは「CSVファイルを読み込んで，銘柄ごとの実現損益の合計を求めて」とかだったと思う．もともとExcelでまとめていた投資日記と値がずれていないかを確かめるために，可視化の前に一旦銘柄ごとのそんえき出力している．また，`実現損益`は税金でもっていかれる約2割を考慮していないが，そこは自分が使いやすいように税引き後に調整して以下．

`銘柄ごとの税引き後損益を求めるコード`

```Python
import pandas as pd

# CSVファイルの読み込み
file_path = 'trade.csv'
df = pd.read_csv(file_path, encoding='shift_jis')

# 実現損益を数値に変換（エラー時にはNaNに変換）
df['実現損益[円]'] = pd.to_numeric(df['実現損益[円]'].str.replace('円', '').str.replace(',', ''), errors='coerce')

# 銘柄ごとの実現損益の合計と最終約定日を計算
def calculate_adjusted_profit(profit):
    if profit > 0:
        return profit * 0.79685
    else:
        return profit

result = df.groupby(['銘柄コード', '銘柄名']).agg(
    total_profit_loss=('実現損益[円]', lambda x: x.apply(calculate_adjusted_profit).sum()),
    last_trade_date=('約定日', 'max')
).reset_index()

# 銘柄ごとの損益の合計を求める
total_profit_loss_sum = result['total_profit_loss'].sum()

# 銘柄ごとの結果の表示
print("個々の銘柄の実現損益合計（税引き後）:")
print(result)

print(f"\n全銘柄の実現損益の合計: {total_profit_loss_sum} 円") 
```

参考にしたページで可視化していたのでついでにGeminiに頼んでみた．
`可視化のためのコード`

```Python
import pandas as pd
import matplotlib.pyplot as plt

# CSVファイルの読み込み
df = pd.read_csv('trade.csv', encoding='shift_jis')

# '実現損益[円]' 列の値をクリーンアップし、数値に変換
df['実現損益[円]'] = pd.to_numeric(df['実現損益[円]'].str.replace('[^0-9.-]', '', regex=True), errors='coerce')

# NaNを除外
df = df.dropna(subset=['実現損益[円]'])

# 税引き後損益を計算する関数
def calculate_adjusted_profit(profit):
    if profit > 0:
        return profit * 0.79685
    else:
        return profit

# '実現損益[円]' 列に税引き後損益を適用
df['実現損益[円]'] = df['実現損益[円]'].apply(calculate_adjusted_profit)

# 約定日をdatetimeオブジェクトに変換
df['約定日'] = pd.to_datetime(df['約定日'])

# 月ごとに集計
monthly_df = df.resample('ME', on='約定日')['実現損益[円]'].sum().cumsum()

# グラフのサイズとアスペクト比を指定
fig, ax = plt.subplots(figsize=(8, 4))  # 横長に設定 (幅12, 高さ4)

# 累積損益をプロット
monthly_df.plot(ax=ax) # axを指定

# 軸ラベルとグリッドを設定
ax.set_xlabel("Date", size="12")
ax.set_ylabel("Cumulative profit/loss", size="12")
ax.grid(True)

# 縦軸の範囲を設定
ax.set_ylim(0)  # 最低値を0に設定

# 余白を調整
plt.tight_layout()

# グラフを表示
plt.show()

```

自分の売買データを可視化するとこんな感じ．

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3191770/ea9bdf69-83b6-66d5-2f77-63abf7e95ab4.png" width=100%>

最初に儲けたあと1年ほど投資から離れていたことや2024年末に初めての損出しをして下がっていること，2025年の最初は調子がいいことが一目瞭然．

## 参考文献

この記事は以下の情報を参考にして執筆しました．

- [Pythonの基礎も知らない超初心者が、楽天証券の実現損益データをPythonでグラフ化してみた](https://qiita.com/cotton11aq/items/da964da514bf0c3eaccc)
【JavaScript】padStart で数字の先頭に0をつける

# はじめに
この記事では、JavaScript String オブジェクトのインスタンスメソッドである padStart の概要や用途を記載します。

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/padStart

# 概要
padStart では、対象の文字列が第1引数で指定した長さになるよう文字列の先頭に第2引数で指定した文字列を繰り返し追加します。

```
padStart(targetLength, padString)
```

以下の例では、文字列の長さが 10 になるまで、文字列の先頭に `.` を追加しています。`Pizza` が5文字なので、`.` が5つ追加されます。

```sample.js
const str = "Pizza";
const formattedStr = str.padStart(10, ".");
console.log(formattedStr);
// Output: ".....Pizza"
```

:::note
対象の文字列が padStart の第1引数で指定した長さになっている場合、実行前と結果は変わりません。

```sample.js
const str = "Pizza";
export const formattedStr = str.padStart(5, ".");
console.log(formattedStr);
// Output: "Pizza"
```
:::

# 用途
次は padStart の用途（ユースケース）を考えてみます。

## 1. 固定の桁数表示
本記事のタイトルにあたるユースケースです。
以下の例では、数字の先頭に0をつけて2桁表示にしています。

```sample.js
const index = "1";
const formattedIndex = index.padStart(2, "0");
console.log(formattedIndex);
// Output: "01"
```

## 2. データのマスキング
以下の例では、`cardNumbe` の下4桁以外を `*` でマスキングしています。

```sample.js
const cardNumber = "1234567812345678";
const maskedCardNumber = cardNumber.slice(-4).padStart(cardNumber.length, "*");
console.log(maskedCardNumber);
// Output: "************5678"
```

## 3. プレフィックスの追加
以下の例では、`category` のプレフィックスに `#` を3つ追加しています。

```sample.js
const category = "Science";
const formattedCategory = category.padStart(category.length + 3, "#");
console.log(formattedCategory);
// Output: "###Science"
```

# 参考
- [String.prototype.padStart()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/padStart)
- [文字列が指定の長さになるように先頭または末尾に文字を追加する(padStart, padEnd)](https://www.javadrive.jp/javascript/string/index24.html)
SwiftUIでハーフモーダルの高さを制限したい

# はじめに
今回はハーフモーダルの高さ制限をする方法を紹介していきます
### 本文
コード自体は下記になります。
実際に高さを制限しているのは　`presentationDetents()`です。
ここで注意が必要なのはsheetに対してではなく内部のViewに対して生えていることです。
また、`fraction`は画面の割合をFloatで指定できるのですが、他にも`.midium`などといった用意された固定値や`.height`にすることで直接指定することもできます。
```swift
.sheet(isPresented: $isShow) {
                VStack {
                }
                .presentationDetents([.fraction(0.2)])
            }
```
### 最後に
自分が実装した時に少し古めの記事が多く多少やり方が変わってるので記事にしました。
どなたかのお役に立てれば幸いです
Picker表示時に背景をグレーアウトさせたい

# はじめに
今回はPickerなどの既存のViewに部品が覆い被さって表示されてる時に背景をグレーアウトする方法を紹介していきます
### 本文
やることは単純で、基盤となるViewをZStackを使用して実装し、その内部の最下層に灰色を配置するだけです。
基本的にPickerやDialogはStateアノテーションを付与したBool値で表示管理をしていると思いますが、下記のようにしてあげることで出し分けることが可能になります
```swift
@State var isShow = false
 var body: some View {
        ZStack {
            if isShow {
                Color.Gray
            }
        }
    }
```
### 最後に
宣言的UIはどこに配置するかで大きく変わってくるので、どなたかのお役に立てれば幸いでs
[実機動作確認/レスポンシブデザイン/localhost外部接続] Chrome Developerツールで検出しきれないデバイス特有のバグ対策

## はじめに

Chrome Developerツールを使って各デバイスのレスポンシブデザインを確認し、本番環境へデプロイ。しかし、いざ実機で試してみるとバグが発生……。

- でも、ブランチ単位でテスト環境のURLを発行するのは面倒。
- スマホとPCを繋ぐケーブルも持っていない。

そんなあなたに向けた、簡単に実機で動作確認を行うための対策を紹介します！

---

## **対策: ngrokを使ってlocalhostを外部からアクセス可能にする**

### 1. ngrokのインストール

まずはngrokをインストールしましょう。以下のコマンドで簡単に導入できます。

```bash
# Mac (Homebrewを使用)
brew install ngrok

# Windows
choco install ngrok

# Linux (Ubuntu/Debian)
sudo apt update && sudo apt install ngrok
```

もしくは、[公式サイト](https://ngrok.com/)からダウンロードしてインストールしてください。

### 2. ngrokでローカルサーバーを外部公開

以下のコマンドを実行し、ngrokを起動します。

```bash
ngrok http 3000  # 例: Next.jsやRailsが3000番ポートで動作している場合
```

実行すると、ngrokが発行するURLが表示されます。

```bash
Forwarding    https://abcd1234.ngrok.io -> http://localhost:3000
```

このURLを実機のブラウザで開けば、ローカル環境のサイトをスマホやタブレットで確認できます。

---

## **実機での動作確認**

1. ngrokを起動し、発行されたURLをコピーする。
2. 確認したいデバイスでブラウザを開き、URLを入力。
3. 実機での動作を確認し、Chrome Developerツールでは見つけられなかったバグをチェック！

---

## **まとめ**

Chrome Developerツールでは確認しきれないデバイス特有のバグも、ngrokを使えば簡単に実機でテストできます。

✅ **ngrokを使えば、実機で手軽に確認可能！**
✅ **ケーブル不要！簡単にローカル環境を公開！**
✅ **レスポンシブデザインの最終チェックに最適！**

ぜひ活用して、レスポンシブ対応の品質を向上させましょう！

---

### **参考リンク**
- [ngrok 公式サイト](https://ngrok.com/)
個人的備忘録：IT学習の「点と線」の考え方について振り返りながら、AWS学習を例にして考えてみた

## はじめに

IT学習において、知識を効率的に習得し、実務で活かせるスキルにするためには、「**点と線**」の概念を理解することが重要です。

:::note info
**知識（点）を増やすだけでなく、それらを適切につなげ（線）、実際に使える形にすることで、学習の成果を最大化できます。**
:::

本記事では、この「**点と線**」の考え方をもとに、IT学習を効果的に進める方法を紹介します。

## 書こうと思ったきっかけ

ITの学習を進めている中で、「知識は増えているはずなのに、実際の開発や業務でどう活かせばいいのかわからない」と感じることがありました。

:::note warn
***例えば、プログラミング言語の文法やLinuxコマンドを学んでも、それ単体では具体的なシステムやサービスの開発につながらないことが多いです。***
:::

そこで、個々の知識（点）を実践的なスキル（線）へとつなげる方法を整理することで、より効果的な学習ができるのではないかと考え、本記事を書きました。

## IT学習における「点と線」について

「**点と線**」という概念は、学習やスキル習得において、個々の知識（点）がどのように関連付けられ、全体の理解（線）へとつながるかを示す考え方です。

### 1. 「点」とは？

IT学習における「**点**」は、個々の技術や知識を指します。たとえば：

- **プログラミング言語の基本構文**（Pythonの変数、関数、クラス）
- **OSの基礎知識**（Linuxコマンド、プロセス管理）
- **ネットワークの基礎**（TCP/IP、DNS、HTTP）
- **クラウドの概念**（AWS、Azureのサービス）
- **データベースの知識**（SQL、NoSQL）

これらは単体では独立した知識のように見えますが、それだけでは実践的に使うのが難しい場合があります。

### 2. 「線」とは？

「**線**」は、それぞれの点（知識）をつなげて、実際の業務やプロジェクトで活用できるようにすることを指します。例えば：

- **Webアプリ開発**（Python + フレームワーク + データベース + クラウド）
- **システム運用**（Linux + ネットワーク + 監視ツール + セキュリティ）
- **CI/CDの導入**（GitHub Actions + Docker + Kubernetes）
- **AWSインフラ設計**（VPC + EC2 + RDS + IAM）

つまり、「**点**」だけでは単なる知識の断片であり、「**線**」として結びつけることで実務に活かせるスキルセットになるのです。

## IT学習における「点」と「線」の作り方

### 1. まずは点を増やす（基礎知識を学ぶ）
- 書籍やオンライン講座で知識をインプット  
- 小さなサンプルコードを書いて動作確認  
- Linuxコマンドを試す  

### 2. 点をつなぐ意識を持つ（実践的な学習）
- **小規模なプロジェクトを作る**（Flaskで簡単なWebアプリを作る）  
- **他の技術と組み合わせる**（DockerでFlaskをコンテナ化）  
- **クラウド環境で試す**（AWS上にデプロイする）  

### 3. 線を強化する（プロジェクトや業務で活用）
- **自分でシステムを設計して動かす**  
- **チーム開発に参加し、異なる技術と連携する**  
- **実際の業務で使えるようにパフォーマンスやセキュリティも考慮**  

## 例：AWS学習における「点と線」

### 点
- **EC2の立ち上げ方**
- **S3のファイル保存**
- **IAMの権限管理**

### 線
- **EC2でWebサーバを動かし、S3に画像を保存、IAMで適切なアクセス制御を設定**

単なる「点」ではなく、それらをつなげて「線」にすることで、実践的なAWSスキルが身につきます。

## まとめ
IT学習における「点」は、個々の知識や技術であり、それらを「線」として結びつけることで、実際の業務やプロジェクトで活用できるスキルとなります。

学習の流れとしては、まず基本的な知識を増やし（点を増やす）、次にそれらを組み合わせて小さなプロジェクトで試し（点をつなぐ）、最終的に実務で活かせるレベルに仕上げていく（線を強化する）ことが重要です。

:::note info
**とはいえ、私自身もまだまだIT学習の「点」を増やしている最中です。**
:::

すべてがつながる瞬間を楽しみにしながら、日々の学習を積み重ねていきたいと思います！
Jestで"Found a label with the text of: **, however no form control was found associated to that label."のエラーが出る

# はじめに
next.js×TypeScriptで作成したアプリに対して、Jestでテスト実行したところ、下記のようなエラーが出ました。
和訳すると「**ラベルのテキスト（タイトル）は見つかったけど、そのラベルに関連付けられたフォームコントロールが見つからない。**」とのことです。
```
TestingLibraryElementError: Found a label with the text of: タイトル, however no form control was found associated to that label. Make sure you're using the "for" attribute or "aria-labelledby" attribute correctly.
```
テスト時には`getByLabelText`を使ってタイトルを取得しようとしています。

```tsx:page.test.tsx
  it("フォームが正しく表示されること", () => {
    render(<Page />);

    expect(screen.queryByText("投稿作成")).toBeInTheDocument();
    expect(screen.getByLabelText("タイトル")).toBeInTheDocument();
    expect(screen.getByLabelText("内容")).toBeInTheDocument();
    expect(screen.getByLabelText("ユーザー名")).toBeInTheDocument();
    expect(screen.getByRole("button", { name: "投稿" })).toBeInTheDocument();
  });
```
テスト対象コードはこちら
```tsx:page.tsx
        <div>
          <label className="block mb-2 text-indigo-500">
          　タイトル
        　</label>
          <input
            className="w-full p-2 mb-2 text-indigo-700 border-b-2 border-indigo-500 outline-none focus:bg-gray-300"
            type="text"
            {...register("title")}
          />
          {errors.title && (
            <p className="text-red-500">{errors.title.message}</p>
          )}{" "}
        </div>
```
# 原因
私が`getByLabelText`の用法をいまいち理解しないまま使っていました。

公式ドキュメントにある通り、`getByLabelText`は下記のように設定されたDOM構造の入力ノードを検索します。
つまり、**`<input>`要素にid属性を追加し、`<label>`の`for`属性と一致させる必要があります**。
```tsx:tsx
// `username`を検索する例
<label for="username-input">Username</label>
<input id="username-input" />
```
上記のほかにも複数例載っています。

https://testing-library.com/docs/queries/bylabeltext/

# 解決方法

上記の修正を適用して、**`<input>`要素に`id="title"`を追加し、`<label>`要素にもidと同じ値 `htmlFor="title"`を付与しました**。
これで無事にテストが通りました。
```tsx:page.tsx
        <div>
          <label htmlFor="title" className="block mb-2 text-indigo-500">
            タイトル
          </label>
          <input
            id="title"
            className="w-full p-2 mb-2 text-indigo-700 border-b-2 border-indigo-500 outline-none focus:bg-gray-300"
            type="text"
            {...register("title")}
          />
          {errors.title && (
            <p className="text-red-500">{errors.title.message}</p>
          )}{" "}
        </div>
```
# おわりに
公式ドキュメントでは、使用するクエリの優先順位なんかも定義されています。
自分の知っているクエリだけを使いまわすんじゃなくて、しっかりと各クエリの用法を理解しながら適切な選択をしていきたいです。

https://testing-library.com/docs/queries/about#priority
個人的備忘録：冬の陣ハッカソンでコミュニケーションの重要性を痛感したので、記事としてアウトプットしてみた

## はじめに

チーム開発において、技術的なスキルと同じくらい重要なのが「**コミュニケーション**」です。

:::note info
**円滑なコミュニケーションが取れていないと、認識のズレや作業の遅れが発生し、結果的にプロジェクト全体の進行に悪影響を及ぼします。**
:::

今回は、チーム開発において、意識すべきコミュニケーションについて、自分なりにまとめていきます。

## 書こうと思ったきっかけ

現在受講しているITスクールのチーム開発であるハッカソンに参加をしていますが、その中でコミュニケーションの難しさを改めて痛感しています。

:::note warn
***顔の見えない関係性の中で、どのようにお互いの認識を同じ状態に持っていくのかがすごく難しいところだと思っています。***
:::

オンライン環境では、対面よりも意思疎通することが難しくて、ちょっとした些細な情報連携漏れが大幅な納期の遅れに近づくこともあります。

今回は、そんなコミュニケーションについて、焦点を挙げて、知識、整理をしていきます。

## コミュニケーションの大切さ

- **認識の統一**  
  仕様や要件に関する理解がメンバー間でずれると、実装の方向性がバラバラになり、手戻りが増える。

- **効率的な作業分担**  
  誰が何をやるのかを明確にし、進捗を把握することで、無駄なく開発を進められる。

- **問題の早期発見**  
  不明点や課題を早めに共有し、対策を講じることで、大きなトラブルを未然に防げる。

- **チームのモチベーション向上**  
  気軽に意見を言い合える環境があると、安心して開発に取り組める。

## 難しいこと

- **オンライン環境での情報共有**  
  テキストコミュニケーションでは、意図が正確に伝わらないことがある。

- **適切な報告・相談のタイミング**  
  何をどこまで共有するべきか、頻度や内容のバランスが難しい。

- **価値観や考え方の違い**  
  メンバーのバックグラウンドや開発スタイルが異なると、意見が食い違うこともある。

- **忙しい時のコミュニケーション不足**  
  納期が迫ると、報連相が後回しになりやすく、結果的にミスを招く。

## 意識すること

- **定期的なミーティング**  
  週1回の進捗報告や、毎朝のスタンドアップミーティングなど、定期的に状況を確認する。

- **ツールの活用**  
  SlackやNotion、GitHubのIssueなどを活用し、必要な情報を適切に共有する。

- **具体的に伝える**  
  曖昧な表現を避け、「いつまでに」「どのように」「何をすべきか」を明確にする。

- **相手の意図を確認する**  
  「こういう認識で合っていますか？」と確認しながら進めることで、誤解を防ぐ。

- **心理的安全性の確保**  
  意見を言いやすい雰囲気を作ることで、課題の早期発見や建設的な議論ができる。

## まとめ

読んでいただきありがとうございました。***チーム開発におけるコミュニケーションはすごく難しいポイントですが、上記のことを意識するだけで少し負担は軽減されるかと思います。***

今後も技術的な記事も投稿しつつ、このようなソフトスキルについても体系的にまとめていきたいと思っています！
M5StampS3でアナログジョイスティックの上限を求めて遊ぶ(少し改良)


x 過去ログを見て!!!


結果
----


![Screenshot from 2025-02-10 06-29-36.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/3e14b12e-bc18-0bb3-2716-998ca3cbabd1.jpeg)

![image_original (44).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/681683f1-b4db-5639-bd72-6804ec282ac1.jpeg)


プログラム
----










```c++




//ser_analog_joystick_max_M5StampS3

#define G_X 13
#define G_Y 15

void setup() {
  // put your setup code here, to run once:

  //シリアルの初期化
  Serial.begin(9600);
  Serial.println();
  //シリアルの待ちが0.5*9
  for (int i = 0; i < 9; i++) {
    Serial.print('.');delay(500);  //接続待ち
  } //for
  Serial.println();

  pinMode(G_X, ANALOG);  //gpio init
  pinMode(G_Y, ANALOG);  //gpio init

  float c_yl = 0;
  float c_yr = 0;

  int s = 0;  //input
  for (int i = 0; i < 128; i++) {
    //センサー入力する
    s = s + analogRead(G_X);             //センサーの値
  } //for
  s = s >> 7;                            // s / 128
  c_yl = ((float)s) * (3.3f / 4096.0f);  //  電圧こと

  s = 0;
  for (int i = 0; i < 128; i++) {
    //センサー入力する
    s = s + analogRead(G_Y);             //センサーの値
  } //for
  s = s >> 7;                            // s / 128
  c_yr = ((float)s) * (3.3f / 4096.0f);  //  電圧こと

  //表示
  Serial.print(c_yl);
  Serial.print(',');
  Serial.print(c_yr);
  Serial.println();

} //setup

void loop() {
  // put your main code here, to run repeatedly:

  delay(300);  //ダミー 0.3秒待つ

} //loop




```
JavaScriptで買い物かごを作る方法

Progateの講座にて、JavaScriptで買い物かごを作る方法でつまづいたので、自分用にメモ。
## そもそも
### 配列とは
変数を複数格納できるもの。以下の記述で初期化・宣言する。
```javascript
const array = []; //初期化
const array1 = ['こんにちは', 12345, true]; //初期化と宣言を同時に行う
const array2 = [{name: "Hanako", age: 25}, {name: "Taro", age: 20}]; 
```

配列に要素を追加したい場合は **pushメソッド** を用いる。
```javascript
array.push('要素を追加');
```
この場合、**配列の末尾**に「要素を追加」文字列が追加される。

配列の中の要素を検索したい場合は **findメソッド** を用いる。
```javascript
const array1 = [5, 12, 8, 130, 44];

const found = array1.find((element) => element > 10);

console.log(found); // Expected output: 12
```
この場合、配列の中で一番最初に当てはまったもののみが返却される。

★アロー関数の復習👇

```javascript
// (引数,...) => {return 関数の中身} 
//（引数 => 関数の中身）

let calculater = (number1, number2) => {
  return number1 + number2;
};

let calculater（（number1, number2）=> number1 + number2 );
```

## 問題文
>引数として与えられた商品（オブジェクト）をカート（配列）に追加するプログラムを作成します。
関数 addToCart は商品を追加する先となる配列 cart と、商品名 productName の２つの引数を受け取ります。
商品には商品名と商品の数量があります。商品をカートに追加するときに、同じ商品がカートに存在する場合は、その商品の数量を増やし、存在しない場合は新しい商品をカートに追加してください。
商品の名前はnameに、商品の数量はquantityにデータを保持してください。

### 考え方
- addToCart関数を作成する（引数2つ。配列cartと商品名productName）
- cartの中身は2つのラベルを持ったデータの配列になる（name, quantity）
- findメソッドを使ってカート内に既にある商品を検索する
- ifを使用して条件分岐させる
- カートへの商品の追加にはpushメソッドを使用する
- quantityを操作する

### 答え
```javascript
function addToCart(cart, productName) {
    let inCart = cart.find(item => item.name === productName);
    if (inCart){
        inCart.quantity += 1;
    } else {
        cart.push({name: productName, quantity: 1});
    }
    return cart; //任意
}

const cartArray = [];

addToCart(cartArray, "apple");
addToCart(cartArray, "banana");
addToCart(cartArray, "apple");
cartArray.forEach((item) =>  console.log(item));
```

### つまづいたポイント
- Pushメソッド・Findメソッドの使い方を知らなかった
- アロー関数の記述方法をど忘れ
- 配列の定義方法もど忘れ

### 所感
まだ完全には理解できていない(笑)
今回この問題を解くにあたっていろいろなサイトを調べたり自力で環境構築してJSの動作を確認したりと、新たな学びを得ることができてよかった。
Progateの演習問題で理解した気になっていたけど、実は理解できていなかったことがmosyaだとあぶりだされて助かる。
引き続き学習を継続していきます！
途中アサインの苦痛とコーヒー牛乳


ソースコードはコーヒー牛乳みたいなものである。

もともとコーヒーだったものに、途中で牛乳が追加され、コーヒー牛乳になったとする。

このとき、初期メンバーは「最初のコーヒーに牛乳を足しただけ」と認識しているため、すぐに全体を理解できる。

しかし、途中アサインされた人は、「この処理はコーヒーなのか？ それとも牛乳なのか？」を逐一考える必要がある。

一度混ざったコーヒー牛乳をコーヒーと牛乳に戻すのが難しいように、
ソースコードの歴史を遡り、元の意図を理解するのは困難なのだ。
PHPで「ヒアドキュメントを使った文字列リテラルの作成」の動作を確認してみた。

# 概要

PHPで「ヒアドキュメントを使った文字列リテラルの作成」の動作を確認してみました。
以下のページを参考にしました。

https://www.javadrive.jp/php/string/index6.html

# 実装

以下のファイルを作成しました。

```sample.php
<pre>
<?php
$name = "本田";
echo <<<LABEL
こんにちは。\n私の名前は{$name}です。
LABEL;
?>
</pre>
```

以下のコマンドを実行しました。

```
$ php sample.php 
<pre>
こんにちは。
私の名前は本田です。</pre>
```

# まとめ

何かの役に立てばと。