OmniAICreator/Qiita-1.07M huggingface dataset:
【Next.js(App Router)+Supabase】`cookies` was called outside a request scope.を解決する

# 原因
[公式ドキュメント](https://nextjs.org/docs/messages/next-dynamic-api-wrong-context)にあるように動的APIがリクエストスコープの外で呼び出された際に発生します。

:::note info
> Why This Error Occurred
A Dynamic API was called outside a request scope. (Eg.: Global scope).
> 
> Note that Dynamic APIs could have been called deep inside other modules/functions (eg.: third-party libraries) that are not immediately visible.
> 
> Possible Ways to Fix It
> Make sure that all Dynamic API calls happen in a request scope.

このエラーが発生した理由
動的APIがリクエストスコープの外で呼び出された。 (例: グローバルスコープ) 

動的APIは、すぐには見えない他のモジュール/関数(例: サードパーティライブラリ)の奥深くで呼び出された可能性があることに注意してください。

可能な修正方法
すべての動的API呼び出しがリクエストスコープ内で行われるようにしてください。
:::

今回のエラーメッセージでは`cookies`がリクエストスコープの外で呼び出されたことが原因となります。
```
`cookies` was called outside a request scope. Read more: https://nextjs.org/docs/messages/next-dynamic-api-wrong-context
```

# 解決方法

私の使い方は以下のようにコンポーネント定義の外でsupbase変数を定義したのでエラーとなってしまいました（createClient関数の中でcookies()を使っています）

```tsx
const supabase = createClient()

export default async function Page() {
  const { data } = await supabase.from('hoge').select();
}

  return (
    ...
  )

```

正しくはコンポーネント定義の中で`createClient()`を呼び出すように修正します。
これで、リクエストコープ内で呼び出すようになり、エラーが解消されます。

```diff
- const supabase = createClient()

export default async function Page() {
+ const supabase = createClient()
  const { data } = await supabase.from('hoge').select();
}

  return (
    ...
  )

```

## 深掘り
エラーが起きるということは、`cookies()`は動的APIなんだろうなという理解はしつつも、どこかに書いていないかなと思ったら **`cookies()`は動的関数である、リクエスト時に動的レンダリングへのルートが選択される** と[公式ドキュメント](https://nextjs.org/docs/app/api-reference/functions/cookies)に記載がありました。
なので、`cookies()`は動的APIに当てはまるという理解をしました。

この辺りの理解が間違っていたらご指摘ください🙇

![スクリーンショット 2024-07-21 12.59.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/517223/4c645100-af9a-eb3e-0d8f-10c6f62830fb.png)
sys.argvの個人的まとめ

# 0.sys.argvとは
sys.argv は、Python でコマンドライン引数を処理するために使用されるリストです。プログラムがコマンドラインから実行されたとき、その引数が sys.argv に格納されます。

# 1.sys.stdinとの比較

sys.argv はコマンドライン引数を取得するために使用され、プログラムの起動時に与えられる入力に対応します。
sys.stdin は標準入力からデータを読み取るために使用され、プログラムの実行中に提供される入力に対応します。

# 2.sys.argvのコードの例

```python:
import sys

# コマンドライン引数のリストを表示
print("コマンドライン引数:", sys.argv)

# コマンドライン引数が2つ以上ある場合、それらを表示
if len(sys.argv) > 1:
    print("引数のリスト:")
    for i, arg in enumerate(sys.argv[1:], start=1):
        print(f" 引数 {i}: {arg}")
else:
    print("引数がありません。")
```
Pythonの標準入力sys.stdinの個人的まとめ

# 0.はじめに

Pythonのユーザー入力というとinput()とsys.stdinの2つがありますが、ここではsys.stdinについて記載したいと思います。

# 1.sys.stdinとは
sys.stdinはファイルオブジェクトの一種で、標準入力（通常はキーボード）から直接データを読み取ることができます。主にスクリプトやプログラムで標準入力から一括してデータを読み取るのに使われます。

# 2.input()との比較

## 2.1.対話型入力と一括入力

input(): 対話型で一行ずつ入力を受け取るのに適しています。
sys.stdin: ファイルやパイプからの一括入力や複数行の入力を処理するのに適しています。

## 2.2.プロンプト表示

input(): プロンプトメッセージを表示してユーザーに入力を促します。
sys.stdin: プロンプトは表示されません。直接入力を受け取ります。


## 2.3.用途

input(): 主にスクリプトの対話型入力に使用されます。
sys.stdin: 標準入力からのデータ読み込みが必要なスクリプトや、リダイレクトされた入力（ファイルやパイプからの入力）を処理するのに適しています。

# 3.sys.stdinのコードの例

## 3.1.sys.stdin.read()のコードの例

```python:
import sys

# 標準入力から全ての行を読み取る
input_text = sys.stdin.read()

# 読み取ったテキストを出力する
print("以下のテキストが入力されました:")
print(input_text)
```


### 3.2.sys.stdin.readline()のコードの例

```python:
import sys

print("入力を終了するには、空行を入力してください。")

while True:
    # 標準入力から一行読み取る
    line = sys.stdin.readline()
    
    # 空行（改行のみ）が入力された場合、終了
    if line == '\n':
        break
    
    # 読み取った行を出力
    print(f"入力された行: {line}", end='')

print("入力を終了しました。")
```
Flutter での Image.asset と AssetImage の違い

メモ：

Flutter で自分のフォルダ内の画像を取得する方法として、
``` Flutter
Image.asset(ファイル名),
```
のように指定するやり方と、
``` Flutter
Image(image: AssetImage(ファイル名)),
```
のようなやり方がある。

この2つの違いを調べてみると、```Image.asset```は内部で```AssetImage```を使っているということらしい。([参考URL](https://stackoverflow.com/questions/53309622/what-is-the-difference-between-assetimage-and-image-asset-flutter))

つまり、AssetImage の方が、実行スピードが**僅かに**早くなる。と思われる。
1枚の画像なら大した問題にならないと思うが、大量に画像を出す時は AssetImage の使用がいいかもしれない。
ビジネスサイドとエンジニアサイドの知識交流

## はじめに
社内コミュニケーションにおいて、ビジネスサイドとエンジニアサイドの知識の違いでコミュニケーションコストが上がることはままあります。

ビジネスサイドはエンジニアリングのことでわかっていない事が多いと思いますし、その逆でエンジニアもビジネスには疎い人が多いかと思います。この辺のギャップは多くの企業が直面する課題の一つです。この課題に取り組むため、「Techbridge Workshop」という勉強会を開催しました。

このワークショップは、両部門の相互理解を深め、より効果的な協働を実現することを目的としています。（ちなみにこの勉強会の名前はChatGPTに考えてもらいました）

## Techbridge Workshopの概要

Techbridge Workshopは、以下の2つの主要セッションで構成されています：

1. ビジネスサイドへのエンジニア研修
2. エンジニアへのビジネス研修

これらのセッションを通じて、参加者は相手の領域について学び、共通言語、共通知識を増やすのが目的です。

## ビジネスサイドへのエンジニア研修

このセッションでは、ビジネス部門に対して、ソフトウェア開発の基本的な概念と技術を紹介しました。主なトピックは以下の通りです。

1. **プログラミング一般用語について**
    - OSとは何か？
    - Dockerとは？なぜDockerを使うのか
    - 静的型付け、動的型付け言語の違い
    
2. **フロントエンド開発**
   - HTMLやCSSの基本
   - JavaScriptの概要
   - モダンなフレームワーク（React、Vueなど）の紹介

3. **バックエンド開発**
   - バックエンドプログラミングの基礎
   - REST API, GraphQL APIとは
   - ステータスコード

4. **SQL**
   - リレーショナルデータベースの基本
   - 基本的なSQLクエリの書き方
   - データ分析の基礎

5. **AWS（Amazon Web Services）**
   - クラウドコンピューティングの概要
   - 主要なAWSサービスの紹介

6. **ブロックチェーン**
   - コントラクト開発方法（Solidity）
   - Blockchain Explorerの読み方

### 感想
SQLセッションが非常に好評でした。社内データやブロックチェーンデータの解析に役立つスキルを学ぶことができ、直接業務に活かせる想像がしやすいためかなと思います。

他のセッションも役に立つという評価でしたが、AWSのところはあまり業務との関連を見出せない方が多かったです。弊社ではAWSを使うことが多く、用語としてもエンジニア間では飛び交うのである程度は理解してると、ビジネスサイドの人がPMで入る時とかは割と役に立つかなと思ってたのですが、そこまでは不要なのかもしれません。

## エンジニアへのビジネス研修

このセッションでは、エンジニアにビジネスプロセスの全体像を理解してもらうことに焦点を当てました。主なトピックは以下の通りです：

1. **リードジェネレーション**
   - 潜在顧客獲得の方法
   - インバウンド/アウトバウンド営業


2. **リードナーチャリング＆リードクオリフィケーション**
   - 潜在顧客から商談化まで
   - 商談時にどんな話をするのか


3. **プレゼンテーション&クロージング**
   - 提案するもの、しないものを決める
   - 金額交渉


4. **プロジェクトマネジメント**
   - プロジェクトとは
   - スコープ、時間、コストの管理
   - ステークホルダーマネジメント


5. **顧客関係管理**
   - 顧客満足度の維持と向上
   - 次の契約を取れるような土台づくり

### 感想
このセッションを通じて、ビジネス全体の流れを理解することができたと思います。エンジニア側の満足度も高かったです。
一方で、実務に繋がるという実感を得た人はあまり多くなく、エンジニアが関われる部分にもう少しフォーカスするとより良いものになるかもしれません。

## Techbridge Workshopの効果

Techbridge Workshopは、全体として好評で今後も続けたいという人がほとんどでした。特にビジネスサイドのエンジニア研修は実務に直結しやすいことから非常に有効かなと感じます。
まだ、1回開催したのみで特に具体的な効果を観測できてはいませんが、今後も続けることでコミュニケーションコストが下がることを期待しています。

## 注意点

気をつけないといけないのは短時間で全てを理解するのは不可能ということです。これはカバーする範囲が広すぎて全てをちゃんとは理解できないという意味ではなく、間違った理解をしてしまうということです。

ビジネス側へのエンジニア研修の資料を社内のエンジニアに作ってもらったのですが、短時間である程度カバーするために正確性より分かりやすさを重視して資料作成をお願いしました。

なるべく注釈をつけるようにはしましたが、間違った理解をしてビジネスサイドだけで技術の話が進むということも考えられるので、その辺はエンジニア側、ビジネス側双方のコミュケーションはもちろん必要かなと思います。

あくまで目的はエンジニア側とビジネス側の相互理解であり、ビジネス側だけで技術の話が進められるようになるというものではありません。仮にそのビジネス側の人が社内で一番技術に詳しかったっとしても、エンジニアとコミュニケーションは必須かなと思います。コミュニケーションコストを下げるというのはコミュニケーション量を減らすというよりはコミュニケーションの質を上げるといった観点で捉えると良いのかなと思います。


## 結論
参加者アンケートによると、総じて満足度は高く、今後も続けていきたいという評価をもらいました。
ビジネスサイドへのエンジニア研修では、知識としてだけでなくそれぞれの実務でも役に立つ、役に立ちそうという評価をもらいました。

ただ、一方でエンジニアサイドへのビジネス研修は今回の内容では面白いという意見が多かったものの、実務に役に立つという意見は少なかったため、この辺の内容はアップデートが必要かなと思いました。

共通言語を持つことでコミュニケーションの質が向上し、プロジェクトの成功率が高まることを期待し、今後も継続的な学習と交流を通じて、組織全体の競争力を高めていきたいです。
GPT-4o miniを含む最新のOpenAI、VertexAI、ClaudeのAPI利用料まとめ（2024年7月21日時点）

GPT-4o miniが登場してそのAPI料金の安さに世の中をあっと驚かせましたが、そういえば他のモデルとの料金差や機能の差ってどうなんだっけ？というのは気になるところです。ということで最新のAPI料金を調べてみました。

## OpenAIのGPT-4o miniとその他モデルの比較

### GPT-4o miniの料金とその特徴
#### 料金

OpenAIは、GPT-4o miniの料金を以下のように設定しており、GPT-3.5 Turboと比較して約60%以上安価であり、以前のフロンティアモデルと比べると1桁以上安くなっています

- 入力: $0.15 / 1M トークン
- 出力: $0.60 / 1M トークン

#### 特徴
GPT-4o miniは以下のような特徴を持っており、高性能かつ低コストなモデルとしてAIアプリケーションの開発と展開をより手頃な価格で可能にすることが期待できそうですね。

- 128Kトークンのコンテキストウィンドウ
- 2023年10月までの知識を保有
- MMLUベンチマークで82%のスコアを記録（GPT-4を上回る）
- テキストとビジョンの両方をサポート
- 将来的にテキスト、画像、ビデオ、オーディオの入出力もサポート予定
- ChatGPTのFree、Plus、Team版ユーザーは2024年7月18日からアクセス可能
- APIでは、アシスタントAPI、チャット補完API、バッチAPIで利用可能

### OpenAIの各モデル毎のAPI利用料

GPT-4o miniの料金を他のOpenAIモデルと比較すると:

|モデル|入力 ($/1M トークン)|出力 ($/1M トークン)|
|---|---|---|
|GPT-4o|$5.00|$15.00|
|GPT-4o mini|$0.15|$0.60|
|GPT-4 Turbo|$10.00|$30.00|
|GPT-4|$30.00|$60.00|
|GPT-3.5 Turbo|$0.50|$1.50|

※料金の情報は下記の情報を参考にまとめました
https://openai.com/api/pricing/


## Google Vertex AIの各モデル毎のAPI利用料
OpenAIの状況がわかったとしても他社の状況も比較してみたいところなので、Generative AI on Vertex AIの状況をまとめてみました。

基本的に料金は1000文字あたりで算出されるようになっていますが、比較するのに1000文字だとツライのでひとつの目安として100万文字あたりの料金として表にまとめなおしました。

|モデル|入力料金 (100万文字あたり)|出力料金 (100万文字あたり)|
|---|---|---|
|Gemini 1.5 Pro|$1.25|$3.75|
|Gemini 1.5 Flash|$0.125|$0.375|
|Gemini 1.0 Pro|$0.125|$0.375|

注意点：
1. Gemini 1.5 Proは、他のモデルと比較して10倍高価
2. Gemini 1.5 FlashとGemini 1.0 Proは同じ料金設定
3. すべてのモデルで、出力料金は入力料金の3倍
4. 128,000文字以下のコンテキストウィンドウに適用され、128,000文字を超える場合の料金は2倍
5. Gemini 1.0 Proは最大32,000文字のコンテキストウィンドウのみをサポート


なお、公式情報として記載がある1000文字あたりの料金と金額算出上の注意点は下記の通りです。

|モデル|入力料金 (1,000文字あたり)|出力料金 (1,000文字あたり)|
|---|---|---|
|Gemini 1.5 Pro|$0.00125|$0.00375|
|Gemini 1.5 Flash|$0.000125|$0.000375|
|Gemini 1.0 Pro|$0.000125|$0.000375|

https://cloud.google.com/vertex-ai/generative-ai/pricing?hl=ja

## Anthropic Claudeの各モデル毎のAPI利用料

最後にAnthropic Claudeの各モデル毎のAPI利用料を見てみましょう。

|モデル|入力料金 (100万トークンあたり)|出力料金 (100万トークンあたり)|
|---|---|---|
|Claude 3.5 Sonnet|$3.00|$15.00|
|Claude 3 Opus|$15.00|$75.00|
|Claude 3 Sonnet|$3.00|$15.00|
|Claude 3 Haiku|$0.25|$1.25|
|Claude 2.1|$8.00|$24.00|
|Claude 2.0|$8.00|$24.00|
|Claude Instant 1.2|$0.80|$2.40|

https://www.anthropic.com/pricing#anthropic-api

## まとめ
こうしてまとめてみるとGPT-4o miniの安さは際立っていますね。とはいえハルシネーションが多いという一部情報もありますので、適宜モデルを切り替えながら用途に合ったものを使用していくのがよさそうです。
Apple Intelligenceとは

# Apple Intelligenceとは

## はじめに

Apple Intelligenceは、AppleがiOS 18、iPadOS 18、macOS Sequoiaに導入予定の次世代パーソナルインテリジェンスシステムです。この記事では、Apple Intelligenceの概要と、これが開発にもたらす影響について説明します。

## Apple Intelligenceとは？

[Apple Intelligence](https://www.apple.com/jp/apple-intelligence/)は、iPhoneやiPadなどのApple製品に搭載される人工知能（AI）システムです。このシステムは、ユーザーの日常的なタスクをより簡単かつ効率的に行えるよう支援します。

主な特徴：
1. **オンデバイス処理**: 多くの処理をデバイス上で行い、プライバシーを保護します。
2. **Private Cloud Compute**: 複雑な処理には、安全なクラウドコンピューティングを活用します。
3. **ChatGPT連携**: OpenAIのChatGPTと統合し、高度な質問応答機能を提供します。

## 今公開されている主な機能

### 1. テキスト処理
- **文章の書き直し・校正・要約**: 
  - 例: メールアプリで長文を書いた後、「この内容を簡潔にまとめて」と指示すると、AIが要約を生成します。
- **スマートリプライ**: 
  - 例: メッセージアプリで受信した内容を分析し、適切な返信候補を提案します。

### 2. 画像生成・管理
- **Image Playground**: 
  - 例: 「夕日を背景に走る犬」と指示すると、AIがその場面のイラストを生成します。
- **Genmoji**: 
  - 例: 「笑顔の猫」と入力すると、その描写に合った絵文字を自動生成します。

### 3. Siri機能強化
- **高度な言語理解**: 
  - 例: 「明日の午後3時に...あ、やっぱり4時に変更して」という言い直しにも柔軟に対応します。
- **アプリ間のアクション実行**:
  - 例: 「写真アプリの最新の写真をメールで送って」という複数アプリにまたがる指示を実行できます。
  - サードパーティとしては、この点に注目しますよね。

## iOS開発への影響


App Intents フレームワークを使用することで、アプリを Siri や Shortcuts アプリと統合できます。もって、Apple Intelligenceと統合できます。
既存のApp Intentsの理解をした上で、Apple Intelligenceとの関係を把握する必要があります。

https://developer.apple.com/documentation/appintents/integrating-your-app-with-siri-and-apple-intelligence


### 3. プライバシー重視の設計

Apple Intelligenceは、ユーザーのプライバシーを最重要視しています。開発者は、このポリシーに沿ったアプリ設計が求められます。

例えば：
- ユーザーデータの取り扱いには十分注意し、必要最小限のデータのみを使用する。
- Private Cloud Computeを使用する際は、データの匿名化や暗号化を適切に行う。


## 開発者の準備

1. **Apple Developer Programに参加**: ベータ版のiOS 18やXcodeにアクセスするために必要です。
2. **WWDC（Apple Worldwide Developers Conference）のセッションを視聴**: Apple Intelligenceに関する詳細な情報や開発のベストプラクティスを学べます。
https://developer.apple.com/videos/wwdc2024
https://developer.apple.com/videos/play/wwdc2024/102
https://developer.apple.com/videos/play/wwdc2024/10153
https://developer.apple.com/videos/play/wwdc2024/10133/
https://developer.apple.com/videos/play/wwdc2024/10210/

3. **サンプルコードの研究**: Appleが提供するサンプルコードを通じて、実際の実装方法を学びます。
4. **プライバシーガイドラインの理解**: Appleのプライバシーポリシーを十分に理解し、それに準拠したアプリ開発を行います。

## 結論

Apple Intelligenceは、iOS開発に大きな変革をもたらす可能性を秘めています。App Intentsに馴染みがない場合、まず既存の概念や技術を学ぶ必要がありますが、これらの知識は今後のアプリ開発において非常に価値のあるものとなるでしょう。

Apple Intelligenceの登場により、より直感的で効率的なアプリ開発が可能になります。この機会を活かし、ユーザーにとってより価値のあるアプリを作成することができるでしょう。

この新しい技術に積極的に取り組むことで、大きな可能性を手に入れることができます。Apple Intelligenceの詳細が明らかになり次第、公式ドキュメントやチュートリアルを活用して、着実にスキルアップしていきましょう！
【ChatGPT GPT-4o mini】をどう使うのか？


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

　今回は、GPT-4o miniをどう使うのか、について考えてみました。

:::note info
本記事は、ChatGPT（有料版）
で行なっております。画像は
ありません。　あしからず。
:::

　ニュースはないので、
　　本題に入ります。

　GPT-4o miniをどう使うのか？
　　ここでは、使い道について
　　　考えてみたいと思います。

　GPT-4o miniは
　　Google Gemini
　　Microsoft Copilot
　　Anthropic Claude
　　　の同等モデルに
　　　　匹敵・凌駕するモデルです。

　しかし、
　　チャットボットとしては
　　　基本機能しかなく、
　　　　インターネットにも
　　　　　つながらない。

　将来的には
　　つながるかとは思いますが、
　　　今すぐではありません。

　こんな基本機能しかない
　　チャットボットを
　　　どう活用すればいいのか。

　ヒントは
　　ChatGPTが登場したころを
　　　思い返せば、たくさんあります。

　2022年11月30日に公開された
　　ChatGPTは、たった1週間で
　　　100万人のユーザーを獲得。

　2023年1月には、
　　1億人のアクティブユーザー数に
　　　到達しましたよね。

　ニュースで騒がれたにもかかわらず、
　　日本での利用者数が
　　　伸び悩んでいました。

　現在でも
　　伸び率は、
　　　世界に比べて、低いです。

　まぁ、それはともかく、
　　ChatGPT登場の際の使用用途は、
　　　なんだったでしょうか？

　Perplexityに尋ねました。
　　最近はGoogle SGEを使わず、
　　　Perplexityばかりです😅
***
***user***
ChatGPT登場時、使用用途はなんでしたか？　できるだけ多くお願いします。

***Perplexity***
ChatGPTが登場した際、その使用用途は非常に多岐にわたっていました。以下に代表的な使用用途を挙げます。

### 1. **カスタマーサポート**
企業のカスタマーサポートとして、顧客からの問い合わせに自動で対応するために利用されました。これにより、対応時間の短縮とコスト削減が図られました。

### 2. **コンテンツ生成**
ブログ記事、ニュース記事、広告コピー、SNSの投稿など、様々なコンテンツの生成に利用されました。特にライターやマーケターにとっては、アイデア出しや文章作成の補助として重宝されました。

### 3. **教育支援**
学生や教師に向けて、質問に答えたり、課題のサポートを行ったりするために使用されました。特にリモート学習の普及に伴い、教育分野での利用が増加しました。

### 4. **翻訳と言語学習**
多言語対応が可能なため、翻訳ツールとして利用されたり、言語学習の補助としても活用されました。

### 5. **パーソナルアシスタント**
スケジュール管理、リマインダー設定、情報検索など、個人の生活をサポートするためのアシスタントとして利用されました。

### 6. **クリエイティブライティング**
小説や詩、脚本などのクリエイティブな文章作成の補助としても利用されました。作家やクリエイターがアイデアを広げるためのツールとして活用されました。

### 7. **医療相談**
医療専門家ではないものの、一般的な健康に関する質問に答えたり、症状に関する情報を提供するために利用されました。ただし、診断や治療の決定は専門家に任せる必要があります。

### 8. **ゲーム開発**
ゲームのストーリーラインやキャラクターの対話を生成するために利用されました。特にインディーゲーム開発者にとっては、コストを抑えつつ高品質なコンテンツを作成する手助けとなりました。

### 9. **調査とデータ分析**
データの要約や分析結果の解説、調査レポートの作成など、ビジネスインテリジェンスやマーケットリサーチの分野でも利用されました。

### 10. **法務と契約書作成**
契約書や法的文書のドラフト作成、法的質問への回答など、法務分野でも利用されました。これにより、法務部門の効率が向上しました。

### 11. **ソーシャルメディア管理**
SNSの投稿スケジュール管理、コメントへの対応、トレンド分析など、ソーシャルメディアの運営においても活用されました。

### 12. **技術サポート**
プログラミングの質問に答えたり、コードのバグを見つけたりするために利用されました。特に新米プログラマーにとっては、学習の補助として非常に役立ちました。

これらの用途は、ChatGPTの柔軟性と高い自然言語処理能力によって可能となりました。今後も新たな用途が開発されることで、さらに多くの分野での利用が期待されています。
***

　いろいろとありましたね。

　かくいう私も
　　QiitaでChatGPT無料版（GPT-3.5）を
　　　使った記事を約半年に渡って
　　　　書いてきました。

　メール文章、
　　小説執筆関連、
　　　プログラミング関連などなど。

　GPT-3.5は
　　今から考えると
　　　とても低機能です。

　それでも
　　それなりの
　　　利用が可能でした。

　ならば
　　GPT-4o miniは
　　　さまざまな点で
　　　　実用的な文章生成AIです。

　そう考えれば、
　　GPT-4o miniは
　　　仕事の場面の多くで
　　　　十二分な活用が可能です。

　特に速度は有益です。
　　GPT-4oに比べて、
　　　体感で半分の時間で
　　　　処理できます。

　英訳と和訳をさせてみましたが
　　ともかく早かった😅

　もちろん、
　　ハルシネーションが心配ですが、
　　　GPT-3.5に比べたら、雲泥の差。

　何度も使ってみて、
　　GPT-4o miniのクセを
　　　捉えれば、注意点も
　　　　わかるかと思います。

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

　今回は、ここまで。
【react-router-dom】遷移元の画面に戻りたい

## 初めに
Reactで単語帳アプリを作ろうと思ったら遷移元の画面に戻る処理でつまづいたので解決方法を残しておきます。
## 作りたい処理
画面は次の3つ
- 単語を一覧表示する画面
- 単語の詳細を確認する画面
- 単語を編集する画面

遷移図はこんな感じ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3493608/58588f3e-5c6c-c6bf-06e1-83cfcab05b6f.png)
編集画面の戻るボタンを押したときの遷移先を一覧画面から遷移したのか詳細画面から遷移したのかで変えたかった。
## 解決方法
`react-router-dom`の`useNavigate()`の引数に`-1`を入れるだけで簡単に遷移元の画面に戻る処理ができた。
React Router v6からの仕様らしい(?)
```sample.tsx
const navigate = useNavigate();
navigate(-1)
```

実際の画面が以下の通り
※画面遷移に関係ないところは省略してます
### 一覧画面
```WordList.tsx
import { useNavigate } from "react-router-dom";

const WordList = () => {
    const navigate = useNavigate();

    // 詳細画面に遷移するボタン押下時処理
    const clickInfo = () => {
        navigate('/10');
    };

    // 編集画面に遷移するボタン押下時処理
    // /:id/editに遷移したいが便宜上/10/editに遷移
    const clickEdit = () => {
        navigate('/10/edit')
    }

    return (
        <>
            <h1>一覧画面</h1>
            <button onClick={clickInfo}>詳細</button>
            <button onclick={clickEdit}>編集</button>
        </>
    )
}
```
### 詳細画面
```WordInfo.tsx
import { useNavigate } from "react-router-dom";

const WordList = () => {
    const navigate = useNavigate();

    // 一覧画面に遷移するボタン押下時処理
    const clickInfo = () => {
        navigate('/');
    };

    //編集画面に遷移するボタン押下時処理
    // /:id/editに遷移したいが便宜上/10/editに遷移
    const clickEdit = () => {
        navigate('/10/edit')
    }

    return (
        <>
            <h1>一覧画面</h1>
            <button onClick={clickList}>戻る</button>
            <button onclick={clickEdit}>編集</button>
        </>
    )
}
```
### 編集画面
```WordInfo.tsx
import { useNavigate } from "react-router-dom";

const WordList = () => {
    const navigate = useNavigate();

    // 戻るボタン押下時処理
    const clickBack = () => {
        navigate(-1);
    };

    return (
        <>
            <h1>編集画面</h1>
            <button onClick={clickBack}>戻る</button>
        </>
    )
}
```

間違っているところや他の方法あれば教えてください！
【Python3】【殿堂入りキャンペーン】残り物の量 (paizaランク C 相当)をやってみた

https://paiza.jp/works/mondai/c_rank_skillcheck_archive/leftover

**問題: スーパーマーケットの生鮮食品の売れ残り計算**

**入力**: 
1. 生鮮食品の初期重量 `m` (kg)
2. 生のまま販売した時の売上割合 `p` (%)
3. 売れ残りをお惣菜にした時の売上割合 `q` (%)

**出力**: 
- 最終的な売れ残りの重量 (kg)

**アプローチ**:
1. 初期重量 `m` から `p%` を売り上げる
2. 残りの `m` から `q%` をお惣菜として売り上げる
3. 最終的な売れ残りを計算して出力

**コード**:
```python
def solve(m, p, q):
    # 最初に売れた量を計算 (生のまま)
    sold_initially = m * p / 100.0
    # 最初に売れた後の残りの量
    remaining_after_first_sale = m - sold_initially
    # 残りをお惣菜にして売れた量を計算
    sold_as_osozai = remaining_after_first_sale * q / 100.0
    # 最終的な残りの量を計算
    leftover_stock = remaining_after_first_sale - sold_as_osozai
    return leftover_stock

# 入力の受け取り
import sys
input = sys.stdin.read().strip().split()
m, p, q = map(int, input)

# 売れ残り量の計算
leftover = solve(m, p, q)

# 結果の出力（小数点以下6桁まで表示）
print(f"{leftover:.6f}")
```

**コードの説明**:
1. **関数 `solve` の定義**:
    - `m`: 生鮮食品の初期重量
    - `p`: 生のまま販売した時の売上割合
    - `q`: 売れ残りをお惣菜にした時の売上割合

    ```python
    def solve(m, p, q):
        # 最初に売れた量を計算 (生のまま)
        sold_initially = m * p / 100.0
        # 最初に売れた後の残りの量
        remaining_after_first_sale = m - sold_initially
        # 残りをお惣菜にして売れた量を計算
        sold_as_osozai = remaining_after_first_sale * q / 100.0
        # 最終的な残りの量を計算
        leftover_stock = remaining_after_first_sale - sold_as_osozai
        return leftover_stock
    ```

2. **入力の受け取り**:
    - 標準入力から値を読み込み、`m`, `p`, `q` に分割して整数に変換。
    - `input` を使ってデータを読み込みます。

    ```python
    import sys
    input = sys.stdin.read().strip().split()
    m, p, q = map(int, input)
    ```

3. **売れ残り量の計算**:
    - `solve` 関数を呼び出して売れ残りの量を計算。
    - 最終結果を小数点以下6桁まで表示して出力。

    ```python
    leftover = solve(m, p, q)
    print(f"{leftover:.6f}")
    ```

このプログラムは、与えられた生鮮食品の初期重量と売上割合に基づいて、最終的な売れ残りの重量を正確に計算し、指定された形式で出力します。
Hack Fes. 2024 CTF SQAT writeup

問題の閲覧が出来なくなることは想定してなかったので、残ってるスクショだけ共有！
別のCTFの開始時間間違えてて、急遽空いた時間で参加してました！10位！
Hack Fes参加したかったな......東京イベント遠い～～～～

![スクリーンショット 2024-07-21 113940.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1899463/4fe1ce70-304f-959c-7bc6-b0b39b634aa4.png)

OSINTの企業PR問の50点フラグはオンライン勢は何処から見れたんだろう.....？分からず。
(追記)
(
![スクリーンショット 2024-07-23 114557.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1899463/32e82940-eb86-4013-903d-fb287af8596d.png)
ツイッターからツイキャスに飛んで、QRコードを読み込むとそれがフラグでした！フェアだった！
)



### やってみましょう
Webページのソースのjsにいくつか別れてbase64のフラグを分解したのが散らばってたので、くっつけるだけ。
![やってみましょう.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1899463/d137ec3c-63db-62ef-6c5d-3096b19bbef6.png)

![やってみましょう_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1899463/47dba2dd-318d-a08c-bf0d-4a0f20197b14.png)


### ブロック崩し
なんか色塗ってそう感を感じた。
![ブロック崩し.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1899463/6e854d29-202e-92da-c877-52362829512e.png)
![ブロック崩し_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1899463/25e72517-45f9-2c45-fbcc-570c045ef203.png)

### チャットAI
いろいろ試した。「英訳して」とか「変換」、「逆から」とかが防げるようにできるようになったのか！
https://gigazine.net/news/20231220-gm-dealer-chat-bot-tricked/
この記事好き。

![チャットAI.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1899463/6207d01a-9c30-09cd-8628-ded2f7e69afa.png)

### パケット解析（その１）
文字ダンプ＆grepで見つかった。

![パケット解析（その１）.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1899463/4725ab08-e8eb-c978-791f-ce08dc6db4b5.png)

### パケット解析（その２）

パスワードの各桁ごとにブルーフォースしてて、正しい時だけ応答速度が0.2sでそれ以外は0.1s。
0.2sの時のみのNo抽出して、それのひとつ前に試してたPasswordも抽出。
それぞれを合算して完成！

......この問題どういう実装したらこういう問題起きるんだろうか？

![パケット解析（その２）.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1899463/a7610adb-27e2-4d25-e4c5-2390ea2468aa.png)
![パケット解析（その２）_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1899463/3f323ec8-e237-2dfd-d804-222393e0c75c.png)
![パケット解析（その２）_3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1899463/468f8c66-311f-0834-a856-1ff66568963a.png)
![パケット解析（その２）_4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1899463/4856e118-68fc-6ab9-0e33-43fd1cbbc11a.png)


### OSINTの場所問1問目
N35.7051_E139.7719このあたりなのはわかってて、48~52と18~22を全探索したかったが提出制限厳しくてやめた。正解分からず。
![photo_1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1899463/d2351755-a242-fc06-0b66-2d32f62df092.jpeg)

### OSINTの場所問2問目
1問目で痛い目にあったので、解いてなかった...
設置場所少ないから接地床の色を比較しつつ企業ホームページで行けたのかな...？
![photo.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1899463/99e01138-8192-2f27-0cbd-73fd93a9ae0e.jpeg)
JSF**k講座 1限目【基礎講座】

# 第一回の内容

今回はJSFuckには触れず、基礎知識です
これが理解できないとお話にならないんできちんと理解しましょう

# そもそもJSFuckってなんぞや？
JSFuckとは`[` `]` `(` `)` `+` `!`の6種類の文字だけを使ってjsをかくことです

一言で言うなら
### 縛りプレイ
　
ですね
語源はbrain fuckから来てるっぽいです

>あんまりfuckっていうのもアレなんで以降JSFと書きます
もちろんJava Server Facesではありません


# JSの型の変換について


```Num+Str.js 
 10 + ''
 //'10'
```
`10`はNumber, `""`が空のStringです。

つまりやっていることは
`Number + String`
です。
この場合Stringで出力されます

内部的には`10`と`''`(空String)の二つを結合しているため、Stringで出力される、と言うわけです。

```+(-)Str.js
 +'10'
 //10
```
`+`は単項演算子, `'10'`が10のStringです

今回やっていることは
`+String`
です。
この場合はNumberで出力されます

仕組み的には`+`の左側に何もない場合、`+`は単項演算子として働きます。

:::note warn
もちろん`-`でもいいのですが、出力する数字が反転してしまうため、使い所は選びましょう。
:::


単項演算子は右側のものがNumberに変換可能だった場合、Numberに変更します。
もし変更できないものだった場合、`NaN`が返されます。

また
```js
+true
//1
```
というようにすると　、1が帰ってきます
trueは1、falseだと0が帰ってきます

```!.js
!true
//false
```
!は否定演算子,　trueはboolean型です
よく見るのはif文などの条件式で、`!=`や`!hoge()`などで使われてることが多いと思います。
否定演算子という通りtrueやfalseなどのboolean型などを反転することができます

他にも
```!''.js
!''
//true
```
というふうに何もないもの(false)を否定してあげると、`true`が帰ってきます

```'hoge'[0].js
'hoge'[0]
//'h'
```
`'hoge'`がString, `[0]`がインデックス(添え字)です
String[n]というふうに書くとStringのn番目の文字を取得できます
左から順に0から連番で振られています。

# 練習問題
先ほどまでのことを問題にしました
解いてみましょう

Q1
```js
10+10
```
<details><summary>A1</summary>

```javascript
20
```
</details>

Q2
```js
"10"+"10"
```
<details><summary>A2</summary>

```javascript
'1010'
```
</details>

Q3
```js
10+"10"
```
<details><summary>A3</summary>

```javascript
'1010'
```
</details>

Q4
```js
+"10"
```
<details><summary>A4</summary>

```javascript
10
```
</details>

Q5
```js
(+true)+'0'
```
<details ><summary>A5</summary>

```javascript
'10'
```
</details>

Q6
```js
!""+""
```
<details ><summary>A6</summary>

```javascript
'true'
```
</details>

Q7
```js
'hogehoge'[3]
```
<details ><summary>A7</summary>

```javascript
'e'
```
</details>

# 終わり
以上でJSF講座1限目を終わります
この基礎が非常に大切です

2限目ではいよいよJSFを書いていきます！

## 時間割
1限目
[JSF**k講座1限目【基礎講座】(ここ)](https://qiita.com/shimgo2008/private/b7421974a1aab8131b43)
2限目
[JSF**k講座2限目【最初の文字たち】](https://qiita.com/shimgo2008/items/285ba81ee5f925cc0258)
3限目
[JSF**k講座3限目【関数の実行】](https://qiita.com/shimgo2008/items/8fe67d6a40a516b7a6da)
4限目
[JSF**k講座4限目【全ての英字(小文字)】](https://qiita.com/shimgo2008/items/1d9be501040fc6b98c6b)


チートシート
[JSFチートシート](https://qiita.com/shimgo2008/items/5aeaa977d2dbf11ae4ec)
【Python3】みかんの仕分け (paizaランク C 相当)をやってみた

https://paiza.jp/works/mondai/c_rank_skillcheck_archive/mikan

**問題: みかんを重さごとに仕分ける**

**入力**:
1. 仕分ける重さの区切りを表す整数 `N`
2. みかんの個数を表す整数 `M`
3. 各みかんの重さ `w_1` から `w_M`

**出力**:
- 各みかんを最も近い重さに仕分け、その重さを出力

**アプローチ**:
1. 標準入力から `N`, `M` と各みかんの重さを読み込む
2. 各みかんの重さについて、仕分け先の重さを計算
3. 仕分け先の重さを出力

**コード**:
```python
def classify_oranges(weight, num_oranges, oranges):
    # 各みかんの重さに対して仕分け先の重さを計算して出力
    for orange in oranges:
        # もし、みかんの重さがweight以下ならweightの箱に仕分け
        if orange <= weight:
            print(weight)
        else:
            # みかんの重さに最も近い下の区切りの重さを計算
            lower_bound = (orange // weight) * weight
            # みかんの重さに最も近い上の区切りの重さを計算
            upper_bound = lower_bound + weight
            
            # みかんの重さがlower_boundとupper_boundのどちらに近いかを判断
            if (orange - lower_bound) < (upper_bound - orange):
                print(lower_bound)
            else:
                print(upper_bound)

# 標準入力からデータを読み込む
import sys
input = sys.stdin.read().strip().split()
N = int(input[0])  # 仕分ける重さの区切り
M = int(input[1])  # みかんの個数
oranges = [int(input[i + 2]) for i in range(M)]  # 各みかんの重さリスト

# みかんを仕分ける
classify_oranges(N, M, oranges)
```

**コードの説明**:
1. **関数 `classify_oranges` の定義**:
    - `weight`: 仕分ける重さの区切り
    - `num_oranges`: みかんの個数
    - `oranges`: 各みかんの重さのリスト

2. **みかんの重さに対する仕分け先の重さの計算**:
    - 各みかんの重さ `orange` に対して以下の処理を行います:
        - もし `orange` が `weight` 以下なら、そのまま `weight` の箱に仕分けします。
        - そうでない場合、`orange` に最も近い下の区切りの重さ `lower_bound` と、上の区切りの重さ `upper_bound` を計算します。
        - `orange` と `lower_bound` および `upper_bound` の距離を比較し、近い方の重さの箱に仕分けます。同じ距離の場合は `upper_bound` を選択します。

3. **結果の出力**:
    - 各みかんの仕分け先の重さを順に出力します。

このプログラムは、与えられた各みかんの重さを最も近い重さに仕分けし、その結果を正確に出力します。
CoreMP135のLCDにPythonでCPU温度を表示

## 目的
CoreMP135のLCDにPythonでCPU温度を表示を描画します。
CoreMP135はファンレスであるため、CPU温度があがりやすいので、簡単に確認できるようにしました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73020/f5916609-2505-1a2c-d89a-d5f2d5ab6a27.png)

## 開発環境
Debian12をインストールしたCoreMP135を使いました。

```
CoreMP135
 Description:    Debian GNU/Linux 12 (bookworm)
 Linux CoreMP135 5.15.118 #1 SMP PREEMPT Thu Jun 27 19:59:30 JST 2024 armv7l GNU/Linux
```

### CPU温度の確認
CoreMP135のCPU温度は、デバイスファイル"/sys/class/thermal/thermal_zone0/temp"で確認することができます。ただし、この値は1000で割る必要があります。

```
$ cat /sys/class/thermal/thermal_zone0/temp
64164
```
この場合は、CPU温度64.164℃を表します。

## ライブラリのインストール
　今回は、Pythonライブラリに、numpy, Pillowを使います。aptコマンドで、numpyとPillowを使します。
 
```
sudo apt install python3-numpy
sudo apt install python3-pil
```


### LCDへの描画
温度を取得し、
python3のプログラムで、LCDのフレームバッファ（320x240、RGB565）にCPU温度の画像を書き込みます。

```
# python3 coremp135_lcd_temp.py
```

``` coremp135_lcd_temp.py
import os
import fcntl
import mmap
import time
from PIL import Image, ImageDraw, ImageFont

# フレームバッファのパス
FB_PATH = "/dev/fb1"

# フレームバッファの設定
FB_WIDTH = 320
FB_HEIGHT = 240

def get_cpu_temperature():
    with open("/sys/class/thermal/thermal_zone0/temp", "r") as f:
        temp = float(f.read()) / 1000.0
    return f"{temp:.1f}°C"

def draw_text_to_framebuffer(text):
    # 画像を作成
    image = Image.new("RGB", (FB_WIDTH, FB_HEIGHT), color="black")
    draw = ImageDraw.Draw(image)

    # フォントの設定（サイズを大きくする）
    font = ImageFont.truetype("/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf", 48)

    # テキストのサイズを取得
    bbox = draw.textbbox((0, 0), text, font=font)
    text_width = bbox[2] - bbox[0]
    text_height = bbox[3] - bbox[1]

    # テキストを中央に配置
    position = ((FB_WIDTH - text_width) // 2, (FB_HEIGHT - text_height) // 2)

    # テキストを描画
    draw.text(position, text, font=font, fill="white")

    # 画像を180度回転（上下左右反転）
    image = image.rotate(180)

    # RGB565形式に変換
    image_rgb565 = image.convert("RGB")
    pixels = image_rgb565.load()
    buffer = bytearray(FB_WIDTH * FB_HEIGHT * 2)
    
    for y in range(FB_HEIGHT):
        for x in range(FB_WIDTH):
            r, g, b = pixels[x, y]
            rgb = (r & 0xF8) << 8 | (g & 0xFC) << 3 | b >> 3
            buffer[(y * FB_WIDTH + x) * 2] = rgb >> 8
            buffer[(y * FB_WIDTH + x) * 2 + 1] = rgb & 0xFF

    # フレームバッファに書き込む
    with open(FB_PATH, "wb") as fb:
        fb.write(buffer)

def main():
    while True:
        cpu_temp = get_cpu_temperature()
        draw_text_to_framebuffer(cpu_temp)
        time.sleep(1)  # 1秒ごとに更新

if __name__ == "__main__":
    main()
```
【サクラエディタ】選択文字を自動ハイライト

選択した単語をハイライトしてわかりやすくします。
意外と便利なので使ってみてください。
```
S_SelectWord(0);
S_SearchClearMark(0);
```

### 参考

https://qiita.com/yasushi-jp/items/931e833cf84c1142092e
Lambda式の理解

# 関数型インターフェスとLambda
Javaでは変数として関数(処理の実装)を受け取るための変数が用意されています。
関数型インタフェースの用途を理解することでLambda式も理解できるかと思います。

|変数型|サンプル|
|----|----|
|String|"abcdefg"|
|Integer|123456|
|関数型インタフェース|x+yの結果を返す関数|

関数型インタフェースについてはjava.util.functionパッケージ内で準備されています。
関数型インタフェースの概要についていくつか説明します。

|関数型インタフェース|メソッド|概要|
|---|---|---|
|Function\<T,R>|R apply(T t)|入力値Tを受け取り、結果Rを返却|
|Predicate\<T>|boolena test(T t)|入力値Tを受け取り、評価結果booleanを返却|
|Consumer\<T>|void accept(T t)|入力値Tを受け取る|
|Supplier\<T>|T get()|結果Tを返却|

## Function\<T,R>のサンプル
入力値を受け取り、大文字変換し返却
```java
public class App {
    public static void main(String[] args) {
        Function<String, String> toUpperCase = String::toUpperCase;
        System.out.println(toUpperCase.apply("hello world!"));
    }
}
```

## Predicate\<T>のサンプル
入力値を受け取り、ブランクであるかどうか検証
```java
public class App {
    public static void main(String[] args) {
        Predicate<String> predicate = String::isEmpty;
        System.out.println(predicate.test("abc"));
    }
}
```

## Consumer\<T>のサンプル
入力値を受け取り、結果は返さない
```java
public class App {
    public static void main(String[] args) {
        Consumer<String> consumer = System.out::println;
        consumer.accept("Hello World!");
    }
}
```


## Supplier\<T>のサンプル
引数は受け取らず、結果のみを返却
```java
public class App {
    public static void main(String[] args) {
        Supplier<String> supplier = () -> "Hello World!";
        System.out.println(supplier.get());
    }
}
```

# まとめ
今回は関数型インタフェースをlambdaで記載したサンプルコードとなります。
lambdaを利用することで直感的なコード記載が可能になりますので、生産性向上、品質向上に寄与できると思います。
lambda式マスターとなり、スキル向上を目指していきましょう！
Python ２次元配列の複数キーによるソートについて

# はじめに
　２次元配列の複数キー（優先順位付き）によるソートについて、Lambda関数を使用した要領について、備忘録を兼ねてまとめました。

# 特定の列を基準としたソート
　身長（昇順）、体重（降順）、名前（昇順：辞書順）にする場合は次の通り、優先するキーから順に記載します。
``` Python:Python
import pprint

class_data = [
 [taro,178,60],
 [jiro,180,82],
 [saburo,178,65]
 ]

class_data.sort(key=lambda x:(x[1],-x[2],x[0]))
pprint.pprint(class_data)

#[[saburo,178,65],
# [taro,178,60],
# [jiro,180,82]]
 
```
:::note info
各キーの前に「-」を付けることで、昇順を降順に切り替えることができます。
:::


参考にしたサイトを見失ったので、見つけられたら貼り付けます。
ABC363回答メモ

# 0.はじめに
　下降の一途をたどるレートですが、まぁ実力的に
　こんなもんかと思い、心を入れ替えてC問題までを
　確実に解くように進めていこうと思いました。
　
　今回は、C問題までしか結局解けませんでしたが
　レートは+6と若干持ち直しました。


# 1.A - Piling Up
　Nを1ずつ増やしていき、100、200，300のいずれかをはじめに超えたタイミングが
　答えとなります。
　100,200,300を格納したリストを作り、先頭からNと比較し
　Nがそれぞれの数以下の時、その和人の差分を出力して終了。としました。

　https://atcoder.jp/contests/abc363/submissions/55769699


# 2.B - Japanese Cursed Doll
　呪いの日本人形がモチーフの問題・・・？
　の割にはあっさりと問題は語られていました。
　それぞれの人が、後何ミリ髪が伸びれば
　Tに達するか（あるいはすでに足しているか）を
　別リストに持ち、昇順ソート後
　そのリストの先頭からP番目の値を出力して終了としました。
　
　解説を読んだら、単純にリストをソートして、P番目の人が
　何ミリ伸ばせばいいかを計算するだけでよい事を理解しました・・・。

　https://atcoder.jp/contests/abc363/submissions/55778475


# 3.C - Avoid K Palindrome 2
　制限を見てとりあえず素直な実装でも時間足りるかもなーと実装
　
　【実装１】
　　・Sを一文字ずつリストとしてリストSに読みこみ
　　・itertools.permutationsでSの全順序組み合わせをリストpairに格納
　　・セットリストLにpairの各組み合わせを格納（重複は削除）
　　・Lの各組み合わせをK文字ずつチェックし、回文になっている個所が無かったら
　　　変数ansに1を加算
　
　上記実装で、10文字の入力例３も時間内に解けたので、とりあえず提出。
　→TLE2個と、ギリギリNG
　パターンとして、S内の文字がすべて異なる場合が一番時間がかかる＆
　その場合は、絶対回文にならないので、実装１の前に、
　・リストSの文字がすべて異なったら10文字の全組み合わせパターン数である
　　3628800を出力
　という小ネタを仕込んでみたところ
　見事ACでした。
　
　我ながら小ずるい感じではありますが、C++だったら間に合うとゆっくり解説にもあったので
　一つのテクニックとして良しとします。

　https://atcoder.jp/contests/abc363/submissions/55796690

以上
Matplotlibの基礎

# Matplotlibを使うための前準備

注）ここではjupyter Notebookを使っております。
matplotlibを使うためにまずはインストールしよう！

```
#MatplotlibとNumpyの読み込み
import matplotlib as mpl
import numpy as np

#別名で実行できるようにする
import matplotlib.pyplot as plt
import numpy.random as random

#Jupyter Notebook上でグラフを表示させるために必要なマジックコマンド
%matplotlib inline
```
　「import matplotlib as mpl」は、PythonのMatplotlibライブラリを mpl という名前でインポートする文法です。これにより、Matplotlibの機能にアクセスする際 「mpl」 を接頭辞として使用することができます。
　「import matplotlib.pyplot as plt」 は、PythonのMatplotlibライブラリから pyplot モジュールをインポートし、それを 「plt」 という名前で使えるようにする文法です。
　「%matplotlib inline」 は、Jupyter NotebookやJupyterLabなどのIPython環境で使われるマジックコマンドです。このコマンドを使うことで、Matplotlibによって生成されたグラフをNotebook内で直接表示することができます。これにより、グラフを表示するための plt.show() を明示的に呼び出す必要がありません。


## 散布図
```
#シード値の固定
random.seed(0)

#x軸のデータ
x = random.randn(30)
#y軸のデータ
y = np.sin(x) + random.randn(30)

#グラフのサイズ
plt.figure(figsize=(20,6))

plt.plot(x,y,'o')

#グラフのタイトル
plt.title("no title")
#xの座表名
plt.xlabel("x")
#yの座標名
plt.ylabel("y")

#グラフ中の縦線横線の有無
plt.grid(True)
```

これで簡単な散布図を作ることができます。
このほかにも連続曲線や「subplot」を使ったグラフの分割、「plt.hist」を使ったヒストグラムの作成などができます。興味があれば調べてみてください。





この記事は「東京大学のデータサイエンティスト育成講座」という著書を参考に書きました。
法人向けインターネット回線選定の考え方（ベストエフォート型）

# はじめに
昨今のSASE需要により法人向けのインターネット回線の販売が伸びている
特にベストエフォートタイプ（以下、BEと略す）は個人宅から大企業まで幅広く利用されているが、どのサービスが良いのか非常に分かりづらい
個人的なナレッジを以下にまとめる


# インターネット接続の基本構成

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2697215/8651c51a-aadf-e394-2ba4-a1a8d52c1243.png" width=50%>


<table>
  <thead>
    <tr>
      <th>用語</th> <th>説明</th>
    </tr>
  </thead>
  <tr>
    <td> プロバイダ設備 </td> <td>インターネット接続機能を提供するプロバイダ企業の設備<br>NTT系のOCNやKDDI系のビッグローブが該当</td>
  </tr>
  <tr>
    <td> アクセス設備 </td> <td>プロバイダ設備にアクセスするための設備 <br>光ファイバーを利用した回線でフレッツ回線が代表的なサービス</td>
  </tr>
  <tr>
    <td> ONU </td> <td>光回線終端装置。光ファイバー接続（アナログ光信号）からLAN接続（デジタル信号）に変換する装置</td>
  </tr>
  <tr>
    <td> ブロードバンドルーター </td> <td>インターネット接続機能（IPoE・PPPoE接続機能など）を有した機器。単純にルーターと呼ぶ。セキュリティ機能を有したUTMでも可</td>
  </tr>
  <tr>
    <td> スイッチ </td> <td>L2スイッチ、ハブなど。ルーターは基本的に物理的な接続ポートが少ないため、複数の機器を有線接続したい場合は必要</td>
  </tr>

</table>

# 予算の確認
インターネット回線にかかる費用はピンキリだが、月額の価格帯としては概ね以下のとおり
　数千円　　⇒ 個人向けインターネット回線（BE型）
　数万円　　⇒ 法人向けインターネット回線（BE型）
　数十万円　⇒ 法人向けインターネット回線（帯域確保型）
 
:::note info
Q. 法人向けと個人向けで何が違うのか？
A. 通信品質とオプション、保守対応が異なる
最大帯域〇〇bpsという通信帯域を複数ユーザーで共有する安価なプランでも法人・個人向けでは設備は分かれる。（法人の方がユーザーあたりの帯域設計が大きい）
:::

:::note info
Q. 最近のトレンドは？
A. ダークファイバ系や電力系の高品質なBE回線サービスの需要が伸びている
コロナ禍以降、オンライン会議やSaaS利用が普及している中、
フレッツ等のアクセス設備を他ユーザーと共有するタイプは通信品質が安定せず、
帯域確保型は高価なわりに確保できる帯域が少なくむしろボトルネックになる。
その中間層として、アクセス設備が専有である少し割高なBE回線の需要が高い。
（カタログスペックに近い帯域を利用でき、帯域確保型より安価）
FTTHのシェアについても後述する
:::



# 回線の選定の考え方
各社の宣伝文句を真に受けていると品質の差が全く分からないが、
どのサービスであっても**どのアクセス設備を利用しているか**という制限からは逃れられない
よって、基本的にはアクセス設備の種別を基に判断することが理にかなっている
アクセスは以下のように分類される

### フレッツ系
NTT東西が提供するFTTHサービス（光コラボを含む）
　メリット　：短納期・低価格・提供エリアが広い
　デメリット：通信速度が遅く安定しない
 
 :::note info
 こんな人に向いている
    とにかく安いサービスを利用したい人（光コラボを活用）
    地方などの遠方も含めてサービス・請求・保守を統一したい人
    SIでカスタマイズしたい人（PPPoEでマルチセッション構成など）
:::


### ダークファイバ系
SONY（NURO）やソフトバンク等、アクセス設備を持たない企業が、NTT東西からダークファイバ（使用していない光回線）を借用し、自社サービスとして提供
　メリット　：比較的に安価で高品質（サービスによっては専有型）
　デメリット：納期がかかる（概ね3,4か月程度）
 
 :::note info
 こんな人に向いている
    オフィス利用など安定した通信を利用したい人（特にオンライン会議）
    専有型や一部帯域確保など一定の通信品質を担保したい人
:::


### 電力系
KDDIやオプテージ、各電力が自社で保有するアクセス設備で提供するサービス
　メリット　：1社で高品質・高価格サービスから低品質・低価格までラインナップが多い
　デメリット：提供エリアが限定的
 
 :::note info
 こんな人に向いている
     特定の地方のみで利用する人
     コストパフォーマンスの高いサービスを利用したい人
     電力とセットで申し込みたい人（キャンペーンを活用）
:::

### 備考

:::note warn
バックアップ用に回線を用意したい場合は、回線種別を分けることを推奨する
（単一の設備故障で複数の回線が同時に通信断になるケースがある）
バックアップ用回線にはモバイル回線も選択肢に加えると良い
稀に大規模障害で特定のプロバイダが全断するため、プロバイダも分けると良い
:::


参考情報として、FTTHのシェア（マンションタイプを除く）を以下に掲載する
　フレッツ系（NTT東西）が62.2%、
　ダークファイバ系（SONY、アルテリア）が4.2％
　電力系（KDDI、オプテージ、QTnet、その他電力系）が21.4％
　その他（不明）が12.1％
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2697215/a8812bef-589a-5b44-5d8d-9ae0bbf62660.png)
引用：総務省 電気通信サービスの契約数及びシェアに関する四半期データの公表（令和5年度第4四半期（3月末））
c言語 extern宣言について



## extern宣言とは
　extern宣言とは、外部のファイルで定義した変数を使用する際、コンパイラに対して「このファイルは外部で定義済みの変数です」と宣言するために使用する。
 
　関数の外部で定義された変数はグローバル変数と呼ばれ、システム全体（プログラム全体）で参照可能な変数として扱われる。そのため、あるファイル内で定義したグローバル変数は別ファイルで使用することができる。

 しかし、例えば以下のようにmain.cで宣言、定義した変数g_hogeをsub.cで参照するとコンパイルエラーが発生する。
 ```main.c
/* グローバル変数g_hogeを宣言&定義 */
int g_hoge = 0;

void sub(void);

int main (void)
{
    sub();
    return 0;
}    
```

```sub.c
#include <stdio.h>

void sub(void)
{
    printf("g_hoge = %d¥n",g_hoge);
    return;
}
```
コンパイルエラーが発生する理由は、コンパイルはファイル単位で実施されるため、sub.cをコンパイルする際にコンパイラがg_hogeのシンボル定義を見つけられないからである。
g_hogeはmain.cで宣言、定義済みのため、その旨をコンパイラに伝えることができればコンパイルは通りそうである。
　
 そこで使用するのがextern宣言である。
main.cで宣言、定義済みのg_hogeをコンパイラに通知するため、sub.cでextern宣言を以下のように行う（ここでextern int g_hoge = 1のように定義を行うことはNG。あくまでexternは宣言を行うためのものであり、定義時には使用しない）。
これによりコンパイラがg_hogeの存在を認識し、sub.cでg_hogeが使用可能になる。

 ```sub.c
#include <stdio.h>

extern int g_hoge;

void sub(void)
{
    printf("g_hoge = %d¥n",g_hoge);
    return;
}
```

## externの宣言場所
　extern宣言は一般的にヘッダファイル上で行う。g_hogeをmain.c以外のファイル上で使用したい場合、extern宣言が記述されたmain.hをインクルードすることによってg_hogeの存在が知らされるため使用可能になる。

```main.c
#include "main.h"

/* グローバル変数g_hogeを宣言&定義 */
int g_hoge = 0;

void sub(void);

int main (void)
{
    sub();
    return 0;
}    
```
```main.h
#ifndef MAIN_H
#define MAIN_H

extern int g_hoge;

#endif

```

```sub.c
#include <stdio.h>
#include "main.h"

void sub(void)
{
    printf("g_hoge = %d¥n",g_hoge);
    return;
}
```
上記の通り、基本的なexternの使用方法としては以下の通りである。
・あるソースファイル内（※）でグローバル変数(g_hogeとする)を定義する。
・g_hogeが定義されたソースファイルがインクルードしているヘッダファイル上でg_hogeのextern宣言を行う。
・extern宣言したヘッダファイルをインクルードしたソースファイル内でg_hogeを使用する。

（※）グローバル変数の定義をヘッダファイル上で行わないようにする。ヘッダファイルで定義した場合、そのヘッダファイルが複数ファイルから参照されていると、変数の複数定義となるためリンク時にエラーが発生する。
CoreMP135のLCDにPythonで描画する

## 目的
CoreMP135のLCDにPythonで描画します。
CoreMP135のLCDのデバイスファイル/dev/fb1/ に、Python3を使ってYellow画像(320x240, RGB565形式))を書き込みます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73020/1ff7bc43-c110-61c4-3db1-ed16f87980d6.png)

## 開発環境

Debian12をインストールしたCoreMP135を使いました。

```
CoreMP135
 Description:    Debian GNU/Linux 12 (bookworm)
 Linux CoreMP135 5.15.118 #1 SMP PREEMPT Thu Jun 27 19:59:30 JST 2024 armv7l GNU/Linux
```

## ライブラリのインストール
　今回は、Pythonライブラリに、numpy, fcntl, mmapを使います。fcntlとmmapは標準ライブラリの一部なので、追加でインストールする必要はありません。numpyをインストールする。
 
```
sudo apt install python3-numpy
```


### LCDへの描画
python3のプログラムで、LCDのフレームバッファのパスと情報（320x240、RGB565）を設定します。
そして、フレームバッファファイルを開き、メモリにマップします。
黄色の値をRGB565の値に計算して、フレームバッファ全体を塗りつぶします。

```
# python3 coremp135_lcd_yellow.py
```

``` coremp135_lcd_yellow.py
import numpy as np
import fcntl
import mmap

# フレームバッファのパス
FB_PATH = '/dev/fb1'

# フレームバッファの情報
WIDTH = 320
HEIGHT = 240
BPP = 2  # RGB565の場合、1ピクセルあたり2バイト

# 黄色のRGB565値を計算
# RGB888での黄色は (255, 255, 0)
# RGB565に変換: R(5bit)|G(6bit)|B(5bit)
YELLOW_RGB565 = ((31 << 11) | (63 << 5) | 0).to_bytes(2, byteorder='little')

# フレームバッファを開く
with open(FB_PATH, 'rb+') as fb:
    # メモリにマップ
    fb_memory = mmap.mmap(fb.fileno(), WIDTH * HEIGHT * BPP)

    # 黄色で塗りつぶす
    yellow_array = YELLOW_RGB565 * (WIDTH * HEIGHT)
    fb_memory.write(yellow_array)

    # 変更をフラッシュ
    fb_memory.flush()

print("Yellow color has been written to the framebuffer.")
```
AWS IoT Greengrass v2 で、特定の Deployment の全リビジョンを一括削除する

AWS IoT Greengrass v2 では、 Deployment を更新すると新しいリビジョンが作成されます。  
リビジョン数がかさんだ Deployment をお掃除するのが面倒なので、シェルコマンドを備忘のため記載。


```bash
DEPLOYMENT_NAME="<削除したいDeploymentの名前>"
for DID in `aws greengrassv2 list-deployments --query "deployments[?deploymentName=='${DEPLOYMENT_NAME}'].deploymentId" --output text --history-filter=ALL`
do
    aws greengrassv2 cancel-deployment --deployment-id $DID
    aws greengrassv2 delete-deployment --deployment-id $DID
done

```
プロジェクト運営・設計から運用まで学ぶための個人開発に挑戦！ ～企画～

## はじめに

#### なぜ個人開発を始めたのか？
 理由は二つあります。
　1,技術力の向上
　2,ITエンジニアの技術一辺倒からの脱却と挑戦
   
##### 1,技術力の向上
  ITエンジニアとして当たり前の思いですが、もっと技術を磨いて仕事に反映していきたいです。

##### 2,ITエンジニアの技術一辺倒からの脱却と挑戦
　仕事やSNSを通じて、技術に偏りすぎたITエンジニアの残念な現実を痛感することが多くなりました。詳細を書くと炎上してしまうので控えますが、この問題は私にとって大きな課題と感じています。

　友人の開発プロジェクトを手伝う中で、アプリの知名度を広める苦労を実感しました。技術力だけではなく、マーケティングやコミュニケーションも重要な要素です。

　そこで、今回は一人でどこまでできるかチャレンジし、勉強していくことにしました。技術力を磨くだけでなく、プロジェクトの運営やマーケティングにも注力し、総合的なスキルを身につけたいと思っています。
 
 #### ■■自己紹介■■

ITエンジニア歴: 約6年
仕事分野: サーバーサイド中心
趣味: 旅行、読書、パワースポット巡り、観光地巡り、着物
特技: 空手

## 背景

今年に入ってから、趣味で着物にチャレンジしています。好きな観光地、例えば博物館や科学館などに着物を着て行ったり、日常生活に着物を取り入れたいと思い、着物の世界に踏み込みました。しかし、着物の世界は初心者にとって非常に厳しいものでした。

#### 着物初心者が直面した課題

・着付けの問題: 着物の着付けは思った以上に難しく、何度も練習が必要でした。
・一般のお店に入りづらい: 着物を扱うお店は敷居が高く、初心者には入りづらい雰囲気があります。
・安くて入りやすいお店の罠: 安いと思って入ったお店では、高価な着物を押し売りされることがありました。数十万円もする着物を押し付けられることも。
・着物警察: 着物の着方やマナーに厳しい人たちに出会い、指摘されることがしばしば。

これらの問題に
対処するため、私は初心者向けの着物情報サイトを作ることにしました。このサイトを通じて、着物初心者が感じる不便さや不安を解消し、より多くの人が気軽に着物を楽しめるようにしたいと思っています。

#### 目的
　「着物の初心者さん（興味を持った方）が安全で安心して着物を着てほしい」

##### 目標の順
 プロジェクトの目標を考えてみました。
 順番や内容はおおむね以下です。
 
①とりあえず、小さく素早く作成　
　→第一ステップで、企画・設計、開発をがんばるフェーズ
②情報を豊富にする
　→運用と改修フェーズ
③じっくり技術選定して拡大する
　→技術の勉強のために、使ってみたいものはいくつかあるので技術選定から勉強フェーズ
④初心者の方が知っているってようなレベルで知名度を上げてみる
　→SEOやSNS戦略なども勉強してみるフェーズ
 
 
## 今回作りたいもの
 初心者向けの情報サイト
 　システム：TOPページ、着物についてのＱ＆Ａページ、着物作家さん紹介ページ、おすすめのお店ページ、記事（プログ）

  今回の目標（フェーズ）は「小さく素早く作る」なので、機能や情報にこだわらないです。

## 技術
　今回のフェーズでの開発に選んだ技術は以下の通りです。

・WordPress
・サクラのレンタルサーバー

### 技術選定の理由
#### WordPress
 とりあえず早くサイトを作りたかったため、直感的で素早く構築できるWordPressを選びました。WordPressは多くのテーマやプラグインが利用可能で、初心者でも簡単にサイトを作成できる点が魅力です。

#### サクラのレンタルサーバー
 サーバー選定ではコスト面を重視しました。円安が続く中、海外のクラウドサービスは費用がかさむため、日本国内で安定したサービスを提供しているサクラのレンタルサーバーを選びました。AWSと比較してもコストパフォーマンスが良く、個人開発にはよいかと考えました。


## 詳細な企画
 #### 参考文献
 WEBサイトを0から立ち上げるのは初めてなので、以下の本を購入し勉強しながら作成しました。

 
[いちばんよくわかるWebデザインの基本きちんと入門](https://amzn.asia/d/04uBKJki)

　こちらの書籍は、WEBデザインを作成するにあたり、デザインばかりではなく企画を作成・運用の方法がありました。開発以外の知識も幅広く網羅できます。WEBの知識０の人にはよいかと思いました。


#### 詳細な企画
　①ターゲット
　着物民、着物に興味を持っている人
        ・性別→10代後半～30代以降
        ・着物に興味があるが、自由に着たい
        ・多様性のある着付け
　②コンセプト
  　「初心者でも着物を安全で安心して着てほしい」
　③WEBサイトの目的
    　初心者さん向け、情報発信サイト
      交流サイト
     着物情報サイト
  ④作成するシステム
    ・情報発信するためのWEBサイト
    ・交流するための掲示板か何か
    ・着物情報を手軽にするための、チャットボット
　


 ーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
  今回は企画までをまとめてみました。
  この企画は4月～5月半ばに計画しました。
  時間がかかった理由は、着物イベント等での調査、個人開発の勉強、本業です。
  個人開発は自分の時間配分の調節が大事であることが認識できました。

　次回、[設計編](https://qiita.com/CatLogic_Blue/items/f6d8b369e7f971eed3d9)

  ##### 参考文献
  [いちばんよくわかるWebデザインの基本きちんと入門](https://amzn.asia/d/04uBKJki)
  
 [ゼロから学ぶ はじめてのWordPress](https://amzn.asia/d/0hK7EwId)
CORSって何？

CORS(Cross-Origin-Resource-Sharing)とは、異なるオリジンとのデータ交換を可能にするもの。

## オリジンって？

- URLのホスト
- プロトコル
- ポート番号

上記3つで構成されている識別子のこと

上記3つがすべて同一の場合、同一オリジン。

基本的に、同一オリジンでしかデータ交換はできない。

## 異なるオリジン間のデータ交換
クライアント側はreact、サーバ側はexpressで作成してみる。
``` javascript
import { useEffect, useState } from "react";
import axios from "axios";

function App() {
  const [message, setMessage] = useState("");

  useEffect(() => {
    axios.get("http://localhost:3000/api/message").then((res) => {
      setMessage(res.data);
    });
  }, []);

  return (
    <>
      <h1>hello</h1>
      <p>{message}</p>
    </>
  );
}

export default App;

```
``` javascript
const express = require("express");
const app = express();

const server = app.listen(3000, () => {
  console.log("server start");
});

app.get("/api/message", (req, res, next) => {
  res.json("hello");
});

```
異なるポートで動作させているので、
```
Access to XMLHttpRequest at 'http://localhost:3000/api/message' from origin 'http://localhost:5000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
```
上記のようなエラーが出る。

### Access-Conrtol-Allow-Origin

異なるオリジンとデータ交換を許可するための仕掛け。

上記のコードでデータのやり取りをするためには

react側のpackage.jsonに

```jsx
"proxy": "http://localhost:3000/",
```

を追加する

express側では

```jsx
const cors = require("cors");

app.use(
  cors({
    origin: "http://localhost:5173",
    credentials: true,
    optionsSuccessStatus: 200,
  })
);
```

を追加する。

そうすることで、異なるオリジン間でもデータのやり取りができるようになる。
GASでメールを送信する方法(宛先,CC,BCC,送信元,返信先,添付ファイルの指定)

## 基本

以下でメール送信可能

``` TypeScript
  // タイトル
  var title = 'メールのタイトル';
  // 題名(改行は"\n"で指定する)
  var content = 'メール内容\n改行後の文章';

  // オプションの指定(ここ自体なくても良い)
  let options =
    {
        //返信先メールアドレス
        "replyTo": 'replryTo@test.test.com',
        //送信元名称
        "name" : '　メール送信者の名称',
        //送信元メールアドレス(権限が無いとエラーになるので注意)
        "from" : 'from@test.test.com'
    }

  //送信(送信先,タイトル,本文,オプションを渡す)
  GmailApp.sendEmail('sendTo@test.test.com', title, content, options);
```

## 補足
### 本文
改行は`\n`で指定可能

### 送信先
複数に送信する場合は、`,`(カンマ)区切りで指定する
例
``` TypeScript
  GmailApp.sendEmail('sendTo1@test.test.com,sendTo2@test.test.com', '題名', '本文');
```

#### CC,BCCの指定方法
以下の様にoptionに指定する
複数の場合は送信先同様に`,`(カンマ)区切りで指定する

```  TypeScript
options = {
 "cc" : "ccAdress@test.com",
 "bcc" : "bccAdress@test.com"
}
```

### 添付ファイル
例
``` TypeScript
options = {
   "attachments": "添付ファイル(Blob型)"
}
```
複数送信する場合は、配列で渡す
GoogleDriveから取得する場合を想定して例を記載する

``` TypeScript
let attchmentFiles = [];
attchmentFiles.push(DriveApp.getFileById('添付したいGoogleDriveのファイルID1').getBlob());
attchmentFiles.push(DriveApp.getFileById('添付したいGoogleDriveのファイルID2').getBlob());
//オプションで添付ファイル指定
options = {
   "attachments": attchmentFiles
}
//メール送信部分は省略
```
【Next.js】SSGのサイトをVercelにデプロイすると `Error: The file "/vercel/path0/out/routes-manifest.json" couldn't be found. This is often caused by a misconfiguration in your project.` とエラー

## 環境

- Next.js 13.x

## エラー

![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2601631/d34c2a56-5277-8f0e-9c30-208222d18f78.png)

Next.js13のSSGのサイトをVercelにデプロイしようとしたところ、以下のエラーが出る。

```plaintext
Error: The file "/vercel/path0/out/routes-manifest.json" couldn't be found. This is often caused by a misconfiguration in your project.
```

## 原因

メニュー「Settings」→「General」→「Build & Development Settings」の中の「Framework Preset」を`Next.js`にしていたことが原因だった。

![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2601631/b76f731e-6125-1426-8f5e-1d29066fc6da.png)

## 解決策

### 手順１
メニュー「Settings」→「General」→「Build & Development Settings」の中の「Framework Preset」を`Other`に変更する

### 手順2
「Save」ボタンをクリックして保存する

![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2601631/671f9a84-d882-cb3f-050e-b53a4a8dc12a.png)

### 手順3
メニュー「Deployments」の、失敗していたデプロイに戻り、「Redeploy」ボタンをクリックし、デプロイ後に「Status」が`Ready`になっていれば完了

![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2601631/e6535201-b14d-ecb2-7325-3cb7791f9718.png)
Inkscapeによるベクター画像の変換

# はじめに
共同研究などで先方からデータ解析を頼まれた場合に、画像やチャートのデータは色やフォントなどを変えられるよう、なるべくベクター画像形式で送ることにしています。  
例えばRで出力するチャートは主にEPSで出力し、自分の作ったプログラムで図を出力する場合は大体SVG（なにせ作りやすい！）で出力していたりします。  
ところが、図表作成はPowerPoint一択という流儀の人も結構いて、それだとEPSやSVGは逆に扱いづらく、WMF/EMFの方が良いというケースが多々あります。  
しかし、一応RはWMF/EMFの出力も可能ですが、必ずしも世のプログラムが全てWMF/EMFの出力に対応しているわけではありません。  
そんなわけで、PowerPointで使えるようにデータが欲しいと言ってきた人には、まとめてEMFに変換してスライドファイル(.pptx)に貼り付けて送っています。  
変換のときにLinux上でInkscapeを利用しているのですが、最近その方法を教えてほしいと言われ、ついでにベクター画像の変換コマンドをまとめてGoogle Colabのノートとして[こちら](https://github.com/YujiSue/GeneralScripts/blob/main/VectorImageConverter.ipynb)にアップしたので、ここで紹介します。  

## Inkscapeとは
知らない人のために簡単な紹介をしておきます。筆者がまだ大学院生だった頃、後輩に**無料のIllustrator**と説明していました。多少の語弊はありますが、簡易説明としては概ね間違っていないと思います。  
もう少しちゃんと言うと、Adobe Illustratorみたいな直感的に分かりやすい操作性でデザインやイラスト作成などの作業を出来る無料のソフトです。今回はGUIを使用しませんが、最近は色々な機能が追加されて...いることでしょう、きっと（←普段コマンドラインでしか使ってない）。

## 実際の変換方法
本題である変換についてです。  
まずInkscapeをインストールします。ColabはUbuntuベースなのでaptのコマンドを下に載せていますが、他のディストリビューションでも、基本的にインストールパッケージが用意されています。  
```sh
sudo apt-get install -y inkscape
```

あとは、変換したい形式に応じて下記に挙げたInkscapeのコマンドを実行するだけです。
変換元の形式は AI (人工知能ではなくAdobe Illustratorのやつ), EPS, PDF, SVG などに対応しています。あと、英語（内容含めて半角英数字のみ）での使用が前提です。

* ### To WMF
```sh
#最近のInkscape (> ver. 1.0)
inkscape --export-filename=<出力するファイルパス(.wmf)> <元画像のパス>
#過去のInkscape
inkscape --without-gui --export-wmf=<出力するファイルパス(.wmf)> <元画像のパス>
```
* ### To EMF
```sh
#最近のInkscape (> ver. 1.0)
inkscape --export-filename=<出力するファイルパス(.emf)> <元画像のパス>
#過去のInkscape
inkscape --without-gui --export-emf=<出力するファイルパス(.emf)> <元画像のパス>
```
ついでに
* ### To PDF
```sh
#最近のInkscape (> ver. 1.0)
inkscape --export-filename=<出力するファイルパス(.pdf)> <元画像のパス>
#過去のInkscape
inkscape --without-gui  --export-pdf=<出力するファイルパス(.emf)> <元画像のパス>
```
* ### To EPS
```sh
#最近のInkscape (> ver. 1.0)
inkscape --export-text-to-path --export-filename=<出力するファイルパス(.eps)> <元画像のパス>
#過去のInkscape
inkscape --without-gui --export-ps-level=3 --export-text-to-path --export-eps=<出力するファイルパス(.eps)> <元画像のパス>
```
* ### To SVG
```sh
#新旧共通
inkscape --export-plain-svg=<出力するファイルパス(.svg)> <元画像のパス>
```

実は最近のInkscapeを使えば、出力ファイル名の拡張子を変えるだけで、自動でその拡張子に合わせたフォーマットへ変換されます。  
もし古いバージョンのInkscapeを使う場合は、下段のコマンドで動くと思います（割と最近まで筆者は古いバージョンを使ってました）。  
EPSへの変換については、UTF-8エンコードの半角英数字ですら文字化けすることがあるので、文字をパス化するオプションが余分についています。  

* ### さらにおまけでPNG化
ラスター画像 => ベクター画像への変換と違って、ベクター画像 => ラスター画像へ変換出来るプログラムは多いので、あえてInkscapeを使う必要もないと思いますが、一応ラスター化も出来ます。
```sh
# 背景色を白にしたい場合
inkscape --export-background=white --export-filename=<出力するファイルパス(.png)> <元画像のパス>
# 背景色を透明にしたい場合
inkscape --export-background=white --export-background-opacity=0.0 --export-filename=<出力するファイルパス(.png)> <元画像のパス>

# 過去のInkscape
## '--export-filename'を'--export-png'に置き換える
```

# 最後に
最初に書いたように[Colabのノートブック](https://github.com/YujiSue/GeneralScripts/blob/main/VectorImageConverter.ipynb)にまとめて公開しています。  
上のコードはローカルでも動いていますが、環境によってInkscapeのインストールが上手くいかない、実行するとエラーが出るetc...といったトラブルが起きるようなら、Colabの方にちょいと元画像をアップして変換してからダウンロードし直した方が早いかもです。  
なんならRから動かせますし、python-pptxを使っている人はPowerPointファイルでの出力まで自動化出来ますしね。

# 参考
Inkscapeのコマンドラインオプションの簡易説明wiki
> https://wiki.inkscape.org/wiki/Using_the_Command_Line