OmniAICreator/Qiita-1.07M huggingface dataset:
毎日の水筒の量を決めるのが大変！！気温に合わせて調整できるようにラインBotを使ってプロトタイプを作ったてみた

---
title: 毎日の水筒の量を決めるのが大変！！気温に合わせて調整できるようにラインBotを使ってプロトタイプを作ったてみた
tags: 初心者

---
# 毎日暑い日が続いていますが夏バテしていないですか？
6月21日の夏至の日に沖縄は梅雨明け宣言
夏は好きなタイプですが、さすがに暑い！！
夏バテしないように小まめに水分補給をしていますが水の消費量が半端なく増えた
冬場は500mlペットボトルの半分も飲まなかったが、なんと今では2000mlを飲み干すぐらい多くなっている
***<font color=red">毎日のむ水の量  冬場500mml⇒夏場2000ml約4倍</font>***  
<img width="500" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj_iBjeLPB8HwakQI_GbwxcRYEY6S8Q1BGMlDSTtTxmGLb9rsXh-RNgeW7RB_NxGlFQZNDbqmtgQ0StKsRaYl2ma-7VlhABYqR3TaCcBWyoXYxpW5kLLLhIPpD890PCtuBnfRJc3lh1XnQ/s800/natsubate_necchusyou_yobou.png">
## 準備した分が残ったり・足りずに買い足したことはありませんか？？
毎日水筒に水を入れて、会社へ行くのですが、思った以上に暑く水分が足りなくなって買い足すことが良くある
一回ぐらいなら小遣いの範囲ないでなんとかなるが、毎日になると結構出費がかさむ
又、冬場には水筒に水を多く入れすぎて余らせてしまうことも良くある
毎朝、気温に応じて準備する水分量を教えてくれるものがあった便利だなと思います
水筒に入れる水の量を毎日の気温に応じて教えてくれるLINE Botがいいと思い作りました！

<img width="500" src=https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjNMhRiqRIDtRDElUwF_30qK7ZokhS_EOUONKhn4pFbH42L8N9qIJCAr-xksOfp4nlZQm1EmTwCtUqhssje2rMJVA2DpsiU3qKQEfurjI_YI414AWHpIyGYeU8JDAOZRj8KjJTbqkSF_cQ/s800/obentou_suitou.png>


## イメージ通りにはなかかないかないが、ここまでは出来た。
https://x.com/ikejyunn400905/status/1812663194537934867


## 使用ツール
・[Make](https://www.make.com/en)
・[お天気API](https://weather.tsukumijima.net/)
・[LINE Developers](https://developers.line.biz/ja/)
・[無料イラスト　いらすとや](https://www.irasutoya.com/)

## make構造
https://x.com/ikejyunn400905/status/1812662524019642625


## 作成

## 天気情報のAPIキー取得
https://weather.tsukumijima.net/api/forecast/city/471010

## シナリオ
➀天気情報の取得
![0713(1).PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3819918/8e4d7719-746c-f56a-634b-5f788742bdfa.png)
⓶JSONコードと取込
![0713(2).PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3819918/34467a4c-52d6-847b-6897-3f5aa2536e75.png)
③条件設定　30度以上の場合
![0713(3).PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3819918/3938d9d9-ed64-31c4-681f-b16d35be0602.png)
④条件設置　30度以下の場合
![0713(4).PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3819918/69bffd35-69f0-a3fa-4db8-5564c037ea05.png)
➄条件設定　25度以下の場合
![0713(5).PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3819918/de11df6a-5098-2be0-e4a2-0053058bf372.png)

## 今後の課題
　１、Qiitaの書き方の練習　多くの記事を書く
　２、makeのモジュールを多く試してみる。エクセル変換等
  ３、先輩の記事に触れて学習する

## 最後に
　多くの方のサポート受けながらなんとかここまでたどり着きました。
 「デジタル素人オヤジ」の真夏の初挑戦、前途多難です学ぶ姿勢を忘れずに最後まで頑張ります。
 　素晴らしい技術を肌で触れることでいい経験ができており、毎日「ワクワク」＝「ちむどんどん」（沖縄方言）しております。
  最後まで読んでいただきありがとうございます。
【python】即興で3角形の辺の長さの和を入力して、ピタゴラスの定理が成立するかチェックしてみた

# はじめに
プログラムコンテストの題材で、三角形の3辺の和の長さを整数で入力し、ピタゴラスの定理が成立する(直角三角形)かどうか判定するプログラムを実装しました。

## ソースコード

ソースコードは下記になります

```python
num = int(input())
count = 0
for b in range(1,num):
    for c in range(1,num-b):
        a = num - b - c

        ans1 = pow(a,2)
        ans2 = pow(b,2)
        ans3 = pow(c,2)
        ans4 = ans2 + ans3
        if ans1 == ans4:
            count += 1


if count >= 1:
    print("YES")
else:
    print("NO")
```

## 実行結果

実行結果は下記の画像です。

![tedt1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1055346/0c7f4ccb-4e80-c606-ed71-50b45449c586.jpeg)


# 最後に
競技プログラミングの課題に挑戦しました
今更ながら「世界一流エンジニアの思考法」を読んだ

# はじめに
今更ながら「[世界一流エンジニアの思考法](https://amzn.asia/d/ie4OZon)」と言う有名な書籍を読んでみました。すでにまとめ記事書いてる人はたくさんいますが、参考になるマインドがたくさんあったので自分でもアウトプットがてら記事に残そうと思います。

https://qiita.com/bisketoriba/items/116e73224232703b3965

記事を書きながらFailFastや、どんなにAIが進化してもソフトウェアエンジニアの仕事はなくならないなど共通してる部分がいくつかあったので、以前大学で参加したGoogle本社の方の講演を簡単にまとめた記事も載せておきます↑
# 内容
:::message
あくまで自分が勉強になったと感じた箇所やメモとして残しておきたい箇所をざっと書いているので、細かい内容は実際の書籍を読んでいただいた方がいいかもです。
:::
### 「思考法」が高い生産性を生み出す
マイクロソフトのどんなに優秀な開発者でも常人離れした記憶力や頭の回転の速さがあるわけではない。そのほとんどが思考法(マインドセット)で高い生産性を形作っている。この思考法がAI時代を生き延びる重要なスキルになってくる。
### 手を動かす前に仮説を検証する
```
事実(データ)を1つ見つける→いくつかの仮説を立てる→その仮説を証明するための行動をする
```
これによりむやみやたらに試行錯誤せず圧倒的な効率を生み出す。
### 頭が良くても「理解」には時間がかかる
マイクロソフトのどんなに優秀な開発者でも理解には時間がかかる。基礎的なことを焦らず一つずつ徹底的に理解する習慣をつける。
### Be Lazy(怠惰であれ)というマインドセット
より少ない時間で価値を最大化するという考え方。例えば
- 優先順位をつけて1つのことだけをやる
- 会議は会議の時間内で事を完結させる
- 不必要な仕事をやめる

などがある。
### Fail Fast(早く失敗する)
リスクや失敗を恐れる体質は生産性の面で劇的な低下をもたらす。どんどんチャレンジして早くフィードバックを得る。早く失敗することはそれ自体に意味がある。
### コードリーディングは全部読まない
クラスの中身などの実装はちゃんとできているとして、大まかな構造やインターフェースを把握する。
### 難易度別に分ける
物事を大きく4つの難易度に分けて考える
```
レベル1. 何もググらず即実装できる
レベル2. ググれば実装できる
レベル3. スパイクソリューションがあれば何とかなる
レベル4. 自分では無理
```
レベル1の領域をどんどん増やせるように努力する。
### マルチタスクをやらない
そもそも人間はマルチタスクに向いていない。PCのCPUもマルチタスクをしているように見えて実際は1つの作業しかしていない。
### 1日に1時間は自分の時間を確保する
1日に4時間はメール返信や他の作業をせず自分のやるべき作業だけに集中する時間を確保する。
### 技術ブログを書く
何か新しい技術を学んだらブログに書いて人に説明できるようにする。
### 人が見ることを前提としたメモやコードを書く
何かをメモしたりするときは自分が見返すためだけでなく他の人がみても理解できるような形式で書く。コードもしかり。
### タイムボックス制で学習の時間を確保する
1日のタイムスケジュールを決めておいて時間でしっかり区切って学習時間を確保する。例えば日々の業務の時間を18時までと決めたらどんなにキリが悪くてもそこで業務を終えることでより多く自分の時間を確保するようにする。
### AI時代には「専門性」こそが強みとなる
どんなにAIが高度なソフトウェアを作り出せるようになっても現実的にそれをどうやって顧客に提供するか？そこには当然人間の手が必要。例えばChatのシステムを作って、あるAIが作ったプログラムをバックエンドで使うとしたら
- たくさんのアクセスを捌くための仕組みはどう作るのか
- セキュリティはどう担保するのか
- 用途や目的に応じたAIモデルはどう作るか
- モデルを求めるサービスにどうインテグレーション(統合)させるか

などソフトウェアエンジニアが担わなければ実際に使えるサービスは生まれない。時流に惑わされず「専門性」を追求する姿勢こそが1番強いのではないか。
### 自分の人生は自分でコントロールする
自分の人生や幸せに責任を持って、自分でコントロールするというマインドを持つ。


# おわりに
今回は「世界一流エンジニアの思考法」と言う書籍についてまとめました。自分はまだ学生ですが、普段やってるインターンでも活かせそうな考え方がたくさんあり本当に勉強になりました。いきなり全てを実践することは難しいかと思いますが、記事でまとめた内容をまずは1つでも意識していけるように頑張ろうと思います！

# 参考
結構サクッと読める書籍ですのでこの機会に読んで見てください⭐️

https://amzn.asia/d/ie4OZon
Azureで利用可能な脆弱性管理について考えてみる

### はじめに
Azure環境下において、セキュリティのサービスは多種多様で整理するだけでもとても大変でした。備忘録もかねてこの記事にその整理の結果をまとめておきます。また、ご指摘やご質問等ございましたらコメントお願いいたします。

#### 目次
・[Microsoft Defender 脆弱性管理(MDVM)による評価](###-MicrosoftDefender脆弱性管理による脆弱性評価)
・[ゲスト構成による脆弱性評価](###-ゲスト構成による脆弱性評価)


## MicrosoftDefender脆弱性管理(MDVM)による評価
ざっと早見表です。
|▽ベンチマーク▽|クラウドリソース|OS|ミドルウェア<br>ソフトウェア|
|---|---|---|---|
|CIS|×|〇※|×|
|STIG|×|〇※ |× |
|[MCSB V1](https://learn.microsoft.com/ja-jp/security/benchmark/azure/overview)|×|〇※|×|
|[セキュアスコア](https://learn.microsoft.com/ja-jp/defender-xdr/microsoft-secure-score)<br>(ロジック非公開)|〇|×|×|
|[脆弱性(CVE)](https://learn.microsoft.com/ja-jp/defender-vulnerability-management/tvm-weaknesses)|〇|〇|〇|

※ Windows OSのみ対応可

#### ポイント
以下、要点です
+ WindowsOSについては、ベースライン評価機能を使用することで評価可能
+ クラウドリソースの構成評価は、セキュアスコアでも十分
+ Linux OS、Windows OS、ミドルウェア、ソフトウェアのCVEの管理が可能
+ Microsoft Defender for Endpoint(MDE)で収集したデータをもとに評価
+ Linux OSの構成を評価することはできない（Roadmapには上がっています）
+ STIG、CIS、MCSBによるWindows OSの評価は[ベースラインの評価](https://learn.microsoft.com/ja-jp/defender-vulnerability-management/tvm-security-baselines)から可能
+ 最近、[Defender for CloudがMixrosoft Defender XDRへ統合](https://learn.microsoft.com/ja-jp/azure/sentinel/ingest-defender-for-cloud-incidents)されて、XDRの画面からいろいろ管理できる

#### 構成時の注意点
+ [MDEへのオンボードが必要](https://learn.microsoft.com/ja-jp/defender-endpoint/onboarding)
+ [P2ライセンスが必要](https://learn.microsoft.com/ja-jp/azure/defender-for-cloud/remediate-security-baseline)



## ゲスト構成による脆弱性評価
先にざっと早見表です。
|▽ベンチマーク▽|クラウドリソース|OS|ミドルウェア<br>ソフトウェア|
|---|---|---|---|
|CIS|×|〇|×|
|STIG|×|〇|×|
|ASB V2|×|〇|×|

ASB V2のMSドキュメントは無かったですが、以下がベースラインの詳細な内容のようです。
+ [Linuxセキュリティベースライン](https://learn.microsoft.com/ja-jp/azure/governance/policy/samples/guest-configuration-baseline-linux)
+ [Windowsセキュリティベースライン](https://learn.microsoft.com/ja-jp/azure/governance/policy/samples/guest-configuration-baseline-windows)

#### ポイント
以下、要点です
+ ゲスト構成エージェント経由で収集したデータをもとに評価
+ LinuxOS、WindowsOSにおいてAzure Security Baseline(ASB)V2での評価が可能

#### 構成時の注意点
+ 対象の仮想マシンに[ゲスト構成拡張機能のインストール](https://learn.microsoft.com/ja-jp/azure/governance/machine-configuration/overview)が必要
+ [Azure Policyゲスト構成の設定](https://learn.microsoft.com/ja-jp/azure/cloud-adoption-framework/manage/azure-server-management/guest-configuration-policy)が必要

## 考察
構成の上で仮想マシンを利用するのであれば、基本的にゲスト構成とMDVMによる評価の双方利用するのが望ましいです。その上で、ソフトウェアやミドルウェアの設定評価をしっかりとしたいのであれば、極力、サードパーティのツールを導入しましょう。仮想マシンやAzure Arcの構成がなく、OSの評価が必要なければMDVMのセキュアスコアだけで評価は十分なようにも思います。
最近出たエラーのふりかえり、解決法

初心者ゆえのくだらないミスだけど、忘れないように残します。
あうとぷっちょ

## 環境
OS: Windows11 バージョン23H2
Laravel: 9.52.16
PHP: 8.1.0
開発環境:MAMP
## 目次
①「Unable to guess the MIME type as no guessers are available　(have you enable the php_fileinfo extension?)」

②「must not be greater than 11」

③「Log::●●();」「dd();」などを記入してもLaravel.logに反映されない。
***
## ①「Unable to guess the MIME type as no guessers are available　(have you enable the php_fileinfo extension?)」
●なんて言ってんの？
→「php_fileinfoという拡張モジュールがないからMIME typeがわからんやで。php_fileinfo持ってる?」

●解決法
**php.iniに「extension=php_fileinfo.dll」を追記する。**
☟参考記事

https://qiita.com/kouichi_c/items/4a9c60974388a88ccb68

参考記事と同じく自分もiniにそもそも記述がなかったので、単純に文言を追加した。

●php_fileinfoってなに
php_fileinfoはファイルの拡張子を判別するために必要。
画像ファイルのアップロードやバリデーションの時に必要になる。

## ②「must not be greater than 11」
●なんて言ってんの？
→「11より大きい数字はあかんやで。」

●解決法
**Request.php/rules()に記述した「max:11」を変更した。**

これはエラーというより、バリデーションで引っかかった内容。
自分の中でよくわからない勘違いをしていただけだった。
課題の中で商品を新規登録するために情報を入力するフォームがあり、金額などを入力するところでこのルールが適用されてしまったからエラーが出た。

「バリデーションルール」と「データベース定義」がなぜかごっちゃになっていた。
そのためバリデーションルールとデータ型を少し調べなおした。
☟参考記事

https://qiita.com/shima0218/items/f110df7dce64e86f770d

https://qiita.com/4649rixxxz/items/b9aa7fe0785c768a61a9

●調べたまとめ
・INT（**11**）の11は表示幅のこと。max:数値は実際に入力する値の上限のこと。
・データ型**varcharは文字列**のために、**INTは数値**のために使う。
 ただしバリデーションルールのmaxは文字列にもなるし数値にもなる。
・データ型にcharがあるけど、varcharとの違いは**可変or固定文字列**かどうか。

## ③「Log::▽▽();」「dd();」などを記入してもLaravel.logに反映されない。
●解決法
**bladeに{{$error}}を追加した。**
```php:新規登録のblade
    @if ($errors->any()) <!-- エラーが出たときに表示される部分 -->
        <div class="alert alert-danger">
            <ul>
                @foreach ($errors->all() as $error)
                    <li>{{ $error }}</li>
                @endforeach
            </ul>
        </div>
    @endif
```

データ新規登録しようにもデータの送信がされるだけで、データベースに保存されてない。
→デバッグしよう！
ということでコントローラーやモデルに「Log::▽▽();」「dd();」を記述しても履歴が残らなかった。
bladeに上記を記述して、見た目もログ上にもエラー文言が表示されるようになった。

☟Logファサードについて　Laravel公式

https://readouble.com/laravel/9.x/ja/logging.html#log-levels

***


### おわりに
いまは「call to a member function メソッド名 on null」に苦しめられている。
TypeScriptの型について

# TypeScriptの型システム
TypeScriptは、JavaScriptに静的型付けを追加したオープンソースのプログラミング言語です。型システムを導入することで、コードの安全性と可読性が向上し、バグの発生を未然に防ぐことができます。
## 基本的な型
#### プリミティブ型
TypeScriptは、JavaScriptの基本的なデータ型をサポートしています。
- string: 文字列型
- number: 数値型
- boolean: 真偽値型
- null: null型
- undefined: undefined型
```TypeScript
let username: string = "John";
let age: number = 30;
let isActive: boolean = true;
let empty: null = null;
let notDefined: undefined = undefined;
```
#### 配列型
配列型は、同じ型の要素を持つ配列を定義するために使用します。

```TypeScript
let numbers: number[] = [1, 2, 3, 4, 5];
let strings: string[] = ["apple", "banana", "cherry"];
```
#### タプル型
タプル型は、固定長の配列を定義し、各要素に異なる型を指定することができます。

```TypeScript
let person: [string, number] = ["Alice", 25];
```
#### 列挙型
列挙型（enum）は、名前付き定数の集合を定義するために使用します。

```TypeScript
enum Color {
  Red,
  Green,
  Blue
}

let favoriteColor: Color = Color.Green;
```
## オブジェクト型
オブジェクト型は、オブジェクトの構造を定義するために使用します。

```TypeScript
interface User {
  name: string;
  age: number;
  isActive: boolean;
}

let user: User = {
  name: "Bob",
  age: 28,
  isActive: true
};
```
## 関数型
関数型は、関数の引数と戻り値の型を定義するために使用します。

```TypeScript
function add(a: number, b: number): number {
  return a + b;
}

let subtract: (a: number, b: number) => number = (a, b) => a - b;
```
## ユニオン型と交差型
#### ユニオン型
ユニオン型は、複数の型のいずれかを受け入れることができる型を定義します。

```TypeScript
let value: string | number;
value = "Hello";
value = 42;
```
#### 交差型
交差型は、複数の型を組み合わせて新しい型を定義します。
```TypeScript
interface Person {
  name: string;
}

interface Employee {
  employeeId: number;
}

type EmployeePerson = Person & Employee;

let employee: EmployeePerson = {
  name: "Charlie",
  employeeId: 1234
};
```
## 型エイリアス
型エイリアスは、型に別名を付けるために使用します。

```TypeScript
type StringOrNumber = string | number;

let value: StringOrNumber;
value = "Hello";
value = 42;
```
## 型ガード
型ガードは、ランタイムで型をチェックし、特定の型に基づいた処理を行うために使用します。

```TypeScript
function isString(value: any): value is string {
  return typeof value === "string";
}

function printValue(value: string | number) {
  if (isString(value)) {
    console.log(`String: ${value}`);
  } else {
    console.log(`Number: ${value}`);
  }
}
```
## ジェネリクス
ジェネリクスは、型をパラメータとして受け取ることができる汎用的な関数やクラスを定義するために使用します。

```TypeScript
function identity<T>(value: T): T {
  return value;
}

let stringIdentity = identity<string>("Hello");
let numberIdentity = identity<number>(42);
```
## 高度な型
#### インデックス型
インデックス型は、オブジェクトのプロパティの型を動的に取得するために使用します。

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

type PersonKeys = keyof Person; // "name" | "age"
```
#### マップ型
マップ型は、既存の型を基に新しい型を生成するために使用します。

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

type ReadonlyPerson = {
  readonly [K in keyof Person]: Person[K];
};

let person: ReadonlyPerson = {
  name: "Dave",
  age: 30
};

// person.name = "Eve"; // エラー: ReadonlyPersonのプロパティは読み取り専用です
```
## まとめ
TypeScriptの型システムは、コードの安全性と可読性を大幅に向上させる強力なツールです。基本的なプリミティブ型から高度なジェネリクスやマップ型まで、さまざまな型を活用することで、より堅牢で保守性の高いコードを書くことができます。
普段Javaエンジニアとして働いているので型があると安心します。TypeScriptの型安全最高！！
Pandas: List から DataFrame を作成

## プログラム

```py:from_list.py
#! /usr/bin/python
#
#	from_list.py
#
#						Jul/15/2024
# ------------------------------------------------------------------
import pandas as pd

keys = ['aa','bb','cc','dd']
data = [[1,2],[4,56],[9,83],[11,24]]

df0 = pd.DataFrame({
	'aa': [1,2],
	'bb': [4,56],
	'cc': [9,83],
	'dd': [11,24],
})

print(df0)
print()

df = pd.DataFrame({keys[i]: data[i] for i in range(len(keys))})

print(df)
# ------------------------------------------------------------------
```

## 実行結果

```text
$ ./from_list.py 
   aa  bb  cc  dd
0   1   4   9  11
1   2  56  83  24

   aa  bb  cc  dd
0   1   4   9  11
1   2  56  83  24
```
【自分用】チートシート(Windowsショートカットキー)

# Windowsショートカットキー一覧

## 基本操作
| キー              | 機能                           |
| ----------------- | ------------------------------ |
| Ctrl + Z          | 元に戻す                       |
| Ctrl + Y          | やり直し                       |
| Ctrl + A          | 全選択                         |
| Ctrl + S          | 保存                           |
| Ctrl + P          | 印刷                           |
| Alt + Tab         | アプリ間の切り替え             |
| Alt + F4          | アクティブウィンドウを閉じる   |
| F2                | 選択されたアイテムの名前を変更 |
| F5                | ウィンドウを更新               |
| Ctrl + Shift + Esc| タスクマネージャーを開く       |
| Windowsキー + L   | 画面をロック                   |
| Windowsキー + D   | デスクトップを表示             |
| Windowsキー + E   | エクスプローラーを開く         |

## ウィンドウ管理
| キー                        | 機能                                           |
| --------------------------- | ---------------------------------------------- |
| Windowsキー + 左矢印        | ウィンドウを左半分にスナップ                   |
| Windowsキー + 右矢印        | ウィンドウを右半分にスナップ                   |
| Windowsキー + 上矢印        | ウィンドウを最大化                             |
| Windowsキー + 下矢印        | ウィンドウを最小化                             |
| Windowsキー + Shift + 左矢印| ウィンドウを左のモニターに移動                 |
| Windowsキー + Shift + 右矢印| ウィンドウを右のモニターに移動                 |

## その他
| キー                        | 機能                                           |
| --------------------------- | ---------------------------------------------- |
| Windowsキー + I             | 設定を開く                                     |
| Windowsキー + R             | 「ファイル名を指定して実行」ダイアログを開く   |
| Windowsキー + U             | アクセシビリティセンターを開く                 |
| Windowsキー + Pause         | システムプロパティを表示                       |
| Windowsキー + 数字キー      | タスクバーにピン留めしたアプリを起動           |
【2024年最新】 エンジニアのおすすめ副業と探し方5選

# 2024年最新 エンジニアのおすすめ副業と探し方5選

エンジニアとしてのスキルを活かして副業を始めたいと考えている方も多いのではないでしょうか。2024年の最新トレンドを踏まえたエンジニアのおすすめ副業とその探し方を5つご紹介します。

## 1. フリーランスエンジニア
**おすすめポイント**:
- **自由度が高い**: 自分のペースで仕事ができる。
- **高収入が期待できる**: 専門スキルを活かして高単価の案件を受注可能。

**探し方**:
- **クラウドソーシングサイト**: 「[Lancers](https://www.lancers.jp/)」「[クラウドワークス](https://crowdworks.jp/)」「[ココナラ](https://coconala.com/)」などのプラットフォームで案件を探す。
- **フリーランスエージェント**:「[リモグ](https://remogu.jp/)」「[シューマツワーカー](https://shuuumatu-worker.jp/)」 「[レバテックフリーランス](https://freelance.levtech.jp/)」「[Midworks](https://mid-works.com/)」などのエージェントを利用して案件を紹介してもらう。
- **X(旧Twitter)**: [X](https://x.com/)のツイートにて募集をかけるか、副業の募集を探す。
- **個人間マッチングサービス**: フリーランスとして「[DokuPro](https://dokupro.dev/)」を利用して、これからエンジニアを目指している人や現エンジニアでわからない部分などのお悩み相談を受ける。

## 2. オンライン講師
**おすすめポイント**:
- **知識を共有**: 自分のスキルや知識を他人に教えることで自己成長にも繋がる。
- **副収入**: 講座の受講料として収入を得ることができる。

**探し方**:
- **オンライン学習プラットフォーム**: 「[Udemy](https://www.udemy.com/ja/)」や「[Techpit](https://www.techpit.jp/)」などで自分の講座を開設する。
- **教育系スタートアップ**: 「[Progate](https://prog-8.com/)」や「[Paiza](https://paiza.jp/)」などの企業と提携して講師として活動する。
- **個人間マッチングサービス**: 「[DokuPro](https://dokupro.dev/)」を利用して、自分の得意な技術をオンラインのみで教える活動をする。

## 3. ブログ・技術記事執筆
**おすすめポイント**:
- **パッシブインカム**: 広告収入やアフィリエイト収入を得ることができる。
- **自己ブランディング**: 自分の知識や経験を発信することで、エンジニアとしての認知度を高めることができる。

**探し方**:
- **ブログプラットフォーム**: 「[Qiita](https://qiita.com/)」や「[Zenn](https://zenn.dev/)」などで技術記事を投稿する。
- **独自HPブログサイト**: 自サイトを作成して、ブログサイトを立ち上げて広告収益を得る。
- **技術書執筆**: 「技術書典」などのイベントで自分の技術書を販売する。

## 4. アプリ開発
**おすすめポイント**:
- **創造性を発揮**: 自分のアイデアを形にすることができる。
- **収益化**: アプリ内広告や課金モデルで収益を得ることができる。

**探し方**:
- **アプリストア**: 「Google Play」や「App Store」に自分のアプリを公開する。
- **クラウドファンディング**: 「[Campfire](https://camp-fire.jp/)」や「[Makuake](https://www.makuake.com/)」などで資金を集めて開発を進める。

## 5. コンサルティング
**おすすめポイント**:
- **高単価**: 専門知識を提供することで高収入が期待できる。
- **ネットワーク拡大**: クライアントとの関係を通じて人脈を広げることができる。

**探し方**:
- **ビジネスマッチングサイト**: 「[ビズリーチ](https://www.bizreach.jp/)」や「[LinkedIn](https://jp.linkedin.com/)」でコンサルティング案件を探す。
- **個人間マッチングサービス**: 「[DokuPro](https://dokupro.dev/)」を利用して、これからエンジニアを目指している人や現エンジニアでわからない部分などのお悩み相談を受ける。
- **直接営業**: 自分の専門分野に関連する企業に直接アプローチして提案する。

## まとめ
エンジニアとしてのスキルを活かした副業は多岐にわたります。自分の興味やライフスタイルに合った副業を選び、効率的に探すことで、収入を増やしながら自己成長を図ることができます。2024年も新しいチャンスを見逃さず、積極的に挑戦してみてください。

なお「DokuPro」では、**副業として教えるエンジニア大募集中です！**
**これからエンジニアを目指している方を応援したい**や**副業として気軽に空いた時間で稼ぎたい**方はお気軽に使ってみてください！

質問ある方もXのメッセージなどからお気軽にどうぞ！

https://twitter.com/derasado

https://dokupro.dev/
Seeed XIAO BLE IoT センサーデータをThingsSpeakにアップロード

![tp02.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1015969/1cf26d96-579d-aa55-3414-7f231b0955ba.jpeg)

# はじめに

[前回製作したBLE IoTセンサー](https://qiita.com/DeviceManager/items/e237b421d8ec92bca8b2)のデータを、ラズパイで取得して[ThinkgsSpeak](https://thingspeak.com/)にアップロードする簡単なゲートウエイプログラムを作成しました。

# 事前準備

[ThinkgsSpeak](https://thingspeak.com/)にアカウント作成を行います。無料で利用できる範囲で利用します。チャネルを作成しておき、以下のようにデータフィールドを設定します。


![キャプションを入力できます](https://camo.elchika.com/bac8bb11d4cf9df715f5f85136d85b2beefb274a/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f62376366383337612d373938622d343866612d393832652d6534383166313931653836312f62356237313166352d386565642d343737382d383035342d313664656335336336343838/)

また、Write API Keyをメモしておきます。プログラムの中で利用します。

![キャプションを入力できます](https://camo.elchika.com/b6ca3c91c56f346467b5a092e5b50049665c9cb7/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f62376366383337612d373938622d343866612d393832652d6534383166313931653836312f65356661313639322d633937662d343736392d626132632d373338633365653064366634/)

# 動作環境

ラズパイZeroを利用しました。以前[ウエザーステーション](https://qiita.com/DeviceManager/items/a8bc21c8296bcd051178)として設定したものです。この上でバックグラウンドで動作させます。


# プログラム

環境センサーは10秒間隔でのアドバタイズを行う想定です、CO2センサ付きと、CO2センサ無しの1台づつ構成を想定しています。(CO2なし=室外、CO2付き=室内) 10秒間スキャンして、取得データを60秒毎に、6回分の平均値計算してThingSpeakに送信します。

https://github.com/keitanak/XIAO-BLE-IoT-Sensor/tree/main/Gateway/BLEGatewayThingsSpeak


事前にBLEライブラリのインストールが必要です。
```
sudo pip3 install bluepy
```

systemctrlで制御できるようにこんなファイルを/etc/systemd/system/bletp.serviceとして作成します。

```
[Unit]
Description=BLE to ThingsSpeak

[Service]
ExecStart=/usr/bin/python3 /home/pi/tp/BleSendtoTP.py

[Install]
WantedBy=multi-user.target
```
以下コマンドで実行開始です。

```
sudo systemctl start bletp.service
```



# データアップロード状況

まだ1週間程度のデータですが、継続してデータアップロードされています。バッテリは相当持ちそうです。

https://thingspeak.com/channels/2588539

![tp02.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1015969/de2ca780-ac71-5d27-dbfa-1e1699221545.jpeg)



# 参考リンク

ThingsSpeakの利用方法について参考になりました。
https://remoteroom.jp/diary/2020-12-20/

Gatewayプログラムはこちらで公開されているものを元にして作成しました。
https://ambidata.io/samples/temphumid/ble_gw/
複数のAIを無料で一括プロンプト！「天秤AI」の魅力と活用法

## はじめに

AI技術の急速な進歩により、日々新しいAIモデルやサービスが登場しています。「このAIの性能が突出している！」「現時点で最高精度を誇る！」といった話題をよく耳にしますが、それぞれのAIの実力を確かめるのは時間と労力がかかります。そんな悩みを解決してくれるのが「天秤AI」です。
有能なのに何故か知らない人が多いので紹介です！

## 天秤AIとは

[天秤AI](https://tenbin.ai/)は、複数のAIモデルに同時にプロンプトを投げかけ、その結果を比較できるウェブサービスです。これにより、各AIの特徴や性能を効率的に比較することができます。

## 利用可能なモデル

天秤AIでは、以下の人気AIモデルを利用することができます：

- GPT-3.5 Turbo
- GPT-4o
- Gemini 1.0 Pro
- Gemini 1.5 Pro
- Gemini 1.5 Flash
- Claude 3 Haiku
- Claude 3 Sonnet
- Claude 3 Opus
- Claude 3.5 Sonnet
- Llama3 70b
- Perplexity Web検索
- Mixtral 8x7b

## 天秤AIの特徴と利点

1. **同時比較**: 最大6つのモデルを同時に比較できるため、各AIの特徴や性能の違いが一目瞭然です。

2. **時間効率**: 複数のAIに個別にプロンプトを入力する手間が省けます。

3. **客観的評価**: 同じプロンプトに対する異なるAIの回答を並べて見ることで、各モデルの強みや弱みを客観的に評価できます。

4. **人気プロンプトの閲覧**: サイト上で人気のプロンプトを見ることができ、効果的なプロンプトの書き方を学べます。

5. **無料利用**: 基本的に無料で利用できるため、個人のAI研究や学習に最適です。

6. **代替手段**: 有料AIサービスの無料枠が切れた際の代替手段としても活用できます。

## 活用シーン

1. **AIモデルの比較研究**: 研究者や開発者が異なるAIモデルの性能を比較する際に役立ちます。

2. **最適なAIの選定**: プロジェクトや特定のタスクに最適なAIモデルを選ぶ際の判断材料として使えます。

3. **プロンプトエンジニアリングの練習**: 同じプロンプトに対する異なる反応を見ることで、より効果的なプロンプトの書き方を学べます。

4. **AIの限界の理解**: 複数のAIの回答を比較することで、現在のAI技術の限界や課題を理解するのに役立ちます。

5. **教育現場での活用**: AI技術の授業やワークショップで、実際にAIの違いを体験的に学ぶツールとして使えます。

## 使い方

1. [天秤AI](https://tenbin.ai/)にアクセスします。
![スクリーンショット 2024-07-15 10.34.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2841127/3ef6b341-f0bb-e606-5388-2c4bf9daf573.png)
2. 左側のメニューから比較したいAIモデルを選択します（最大6つまで）。
![スクリーンショット 2024-07-15 10.35.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2841127/89f5b73b-6a0e-bd31-821f-4f2443f31fcf.png)
3. プロンプトを入力し、送信ボタンをクリックします。（もしくはShift+Enter）
4. 各AIモデルの回答が表示されるので、比較・分析します。
4. ![スクリーンショット 2024-07-15 10.36.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2841127/fcad1643-0269-f6fd-a5bb-0df07c035b21.png)

## 注意点

- 各AIモデルの利用には、それぞれの提供元の利用規約が適用される場合があります。
- 大量のリクエストや商用利用については、サービスの利用規約を確認してください。
- 個人情報や機密情報を含むプロンプトの使用は避けましょう。

## まとめ

天秤AIは、複数のAIモデルを簡単に比較できる強力なツールです。AI技術に興味がある方、効果的なプロンプトの書き方を学びたい方、そして最適なAIモデルを探している方にとって、非常に有用なサービスといえるでしょう。無料で利用できるこのサービスを活用して、AIの世界をより深く探求してみてはいかがでしょうか。

天秤AIと同じGMOが公開している教えてAIも有能なプロンプトが沢山掲載されています。
とても勉強になるので是非参考にしてください。
[教えてAI](https://oshiete.ai/)
Docker と curl コマンドで試すベクトル検索 (Solr9)

# 用意するもの

- Docker
- curlコマンド

# Docker で Solr の起動

```:command
docker run -d -p 8983:8983 --name my_solr solr
```

# Docker で Solr コレクションの作成

```:command
docker exec -it my_solr bin/solr create -c sandbox
```

```:output
WARNING: Using _default configset with data driven schema functionality. NOT RECOMMENDED for production use.
         To turn off: bin/solr config -c sandbox -p 8983 -action set-user-property -property update.autoCreateFields -value false

Created new core 'sandbox'

>
```

# フィールドタイプの定義

ここでは例としてベクトルのサイズが4のフィールドタイプを定義しています。

```
curl -X POST -H 'Content-type:application/json' --data-binary '{"add-field-type":{"name":"vector4","class":"solr.DenseVectorField","vectorDimension":4,"similarityFunction":"cosine"}}' http://localhost:8983/solr/sandbox/schema
```

# フィールドの定義

```
curl -X POST -H 'Content-type:application/json' --data-binary '{  "add-field":{ "name":"v4", "type":"vector4", "indexed":true, "stored":true, } }' http://localhost:8983/solr/sandbox/schema
```

# 検索対象データの追加

```
curl -X POST -H 'Content-Type:application/json' --data-binary '[ { "id": "1", "v4": [1.0, 0.0, 0.0, 0.0] } ]' http://localhost:8983/solr/sandbox/update/json/docs?commit=true
```
```
curl -X POST -H 'Content-Type:application/json' --data-binary '[ { "id": "2", "v4": [0.0, 1.0, 0.0, 0.0] } ]' http://localhost:8983/solr/sandbox/update/json/docs?commit=true
```
```
curl -X POST -H 'Content-Type:application/json' --data-binary '[ { "id": "3", "v4": [0.0, 0.0, 1.0, 0.0] } ]' http://localhost:8983/solr/sandbox/update/json/docs?commit=true
```
```
curl -X POST -H 'Content-Type:application/json' --data-binary '[ { "id": "4", "v4": [0.0, 0.0, 0.0, 1.0] } ]' http://localhost:8983/solr/sandbox/update/json/docs?commit=true
```

# 検索対象データの追加（複数文書をまとめて追加したい場合）

```
curl -X POST -H 'Content-Type:application/json' --data-binary '[ { "id": "1", "v4": [1.0, 0.0, 0.0, 0.0] }, { "id": "2", "v4": [0.0, 1.0, 0.0, 0.0] }, { "id": "3", "v4": [0.0, 0.0, 1.0, 0.0] }, { "id": "4", "v4": [0.0, 0.0, 0.0, 1.0] } ]' http://localhost:8983/solr/sandbox/update/json/docs?commit=true
```

# 検索

```
curl -X GET 'http://localhost:8983/solr/sandbox/select?q=%7B!knn%20f=v4%20topK=10%7D%5B1.0%2C1.0%2C0.0%2C0.0%5D'
```

```:検索結果
{
  "responseHeader":{
    "status":0,
    "QTime":91,
    "params":{
      "q":"{!knn f=v4 topK=10}[1.0,1.0,0.0,0.0]"
    }
  },
  "response":{
    "numFound":4,
    "start":0,
    "numFoundExact":true,
    "docs":[{
      "id":"1",
      "v4":[1.0,0.0,0.0,0.0],
      "_version_":1804607180982190080
    },{
      "id":"2",
      "v4":[0.0,1.0,0.0,0.0],
      "_version_":1804607188756332544
    },{
      "id":"3",
      "v4":[0.0,0.0,1.0,0.0],
      "_version_":1804607196582903808
    },{
      "id":"4",
      "v4":[0.0,0.0,0.0,1.0],
      "_version_":1804607205283987456
    }]
  }
}
```

---

以上.
Julia 初心者が Julia 初心者に捧ぐ Julia入門

# そもそも
## Juliaとは
「Julia」は2012年に公開された比較的若いプログラミング言語で、Pythonのような書きやすさとCのような処理（計算）速度を兼ね備えた次世代を担う言語として注目されている。数値計算やfor文の処理がPythonに比べて格段に速く、あくまで主観だが、3~4倍は早いと思う。機械学習関係のライブラリも整備されつつあり、Pythonのようにメジャーな言語になることが期待されている。

### セットアップ
公式サイトからダウンロード可能。
https://julialang.org/downloads/
詳しくは書かない。

## 基本的な構文・仕様
**めっちゃpython**それだけ。pythonとの差分だけ比較して書きます。pythonわかんない人は調べて
### for,if,while 等の違い
Julia は最後に`end`で閉じなければならない。
`:`で一行目を閉じる必要がない。（むしろそうしたらerrorになる）
* pythonのif文
```py
if a == b:
    something()
```
* Juliaのif文
```julia
if a == b
    something()
end
```

### list の違い。
定義方法は同じ。注意すべきはindex番号。

* python
```py
list = ("list1","list2","list3")
print(list[0])

>> list1
```
* Julia
```julia
list = ("list1","list2","list3")
print(list[1])

>> list1
```

> python で`0番目`は Julia で `1番目`となる。

### 関数定義
* python
```py
def 関数名(self)
    something()


#呼び出し
関数名()
```
* Julia
```julia
function 関数名(n)
    something()
end

#呼び出し
関数名()
```

### コメントアウト
* python
```py
#一行コメントアウト

"""
複数行コメントアウト
1
2
3
"""
#↑正確にはコメントアウトではないが、pythonには複数行コメントアウトがないため
#実質的な複数行コメントアウトとなる。
```

* Julia
```julia
#一行コメントアウト

#=
複数行コメントアウト
1
2
3
=#

```

> Juliaでは `#= ... =#` と囲むことで複数行をまとめてコメントアウト可能。これはphpやCなどの `/* ... */` と同じである。

> 2024年7月17日 - 追記
> [@WolfMoon](https://qiita.com/WolfMoon)様が詳しく書いてくれました！ やったね！ 
> [トリプルクオート文字列リテラル ...](https://qiita.com/098orin/items/7be7d21acb7c111db3a1#comment-e363dc6e3a90fc451b99)


## なんかpythonのパッケージが使えるらしい
### PyCallを使う
「 [PyCall](https://github.com/JuliaPy/PyCall.jl) 」というパッケージを使うことでJuliaのコード内からPythonの関数を呼び出すことが可能になるようだ。

### 例
Pythonのライブラリを呼び出して使ってみる。例として[math](https://docs.python.org/ja/3/library/math.html)ライブラリを使ってみる。

```Julia
using PyCall
@pyimport math

#これでpythonと同じようにmathが使える
```
> もしPyCallが無い なーんてことを言われたら
> ```julia
> import Pkg; Pkg.add("PyCall")
> ```
> するか、Julia の REPL の Pkg モードで
> ```julia
> (@v1.5) pkg> add PyCall
> ```
> してPyCallパッケージをインストールできる（基本的にインストールは1回だけでOK）。

## 終わりに

最後まで読んでくださってありがとうございました！
随時更新して行きます！よろしく！
zig-minisignを使ってminisig署名付きファイルを検証する

## 概要

- zig-minisignはMinisignをzigで実装したもので、今のところMinisign/signify方式で署名されたファイルの検証のみ行います


## zig-minisignの一次資料

- https://github.com/jedisct1/zig-minisign


## Minisignの一次資料

- https://jedisct1.github.io/minisign/
- https://github.com/jedisct1/minisign

## Minisign登場までの背景としてsignifyについて

1. まず2013年にOpenBSDプロジェクトによってsignifyが作られました
1. signifyが作られた目的は、OpenBSDプロジェクトがリリースした配布物に対してsignifyで署名し検証可能なものとするためでした
1. signifyはファイルにEd25519による署名と検証を行うことで完全性を担保するツールです
1. signifyは元々OpenBSDのためのツールで、他のプラットフォームではそのままではビルドできません。サードパーティ製のLinux移植版signifyはいくつか存在します

## Minisignについて

- 2015年頃にFrank Denisはsignifyの移植版としてではなく、signifyと互換性のある別のツールとしてMinisignを作り、今(2024年７月)に至ります
- Minisgnは多様なプラットフォームで動作します。公式サイトで配布されているバイナリは、ほぼ全てのLinuxディストリビューション、macOS、そしてWindowsに対応しています


## zig-minisignについて

- zig-minisignはFrank Denis自身によってzigで書かれたMinisignの派生物です
- Minisignと違い、zig-minisignは今のところminisig署名付きファイルの検証のみ可能です


## zig-minisignのインストール

zig-minisignのインストールはとても簡単です

```shell-session
$ git clone https://github.com/jedisct1/zig-minisign.git
$ cd zig-minisign
$ zig build -Doptimize=ReleaseFast
$ cp -a zig-out/bin/minizign ~/bin/
 ```

 ## minizignコマンドのオプション

 zig-minisignのコマンドは"minizign"です

 ```shell-session
$ minizign -h
Usage:
    -h, --help
            Display this help and exit

    -p, --publickey-path <PATH>
            Public key path to a file

    -P, --publickey <STRING>
            Public key, as a BASE64-encoded string

    -l, --legacy
            Accept legacy signatures

    -m, --input <PATH>
            Input file

    -q, --quiet
            Quiet mode

    -V, --verify
            Verify

    -C, --convert
            Convert the given public key to SSH format
```

## zig-minisignでファイルを検証する

ファイルの検証に必要なものは以下の3つです
- ファイル本体
- 署名ファイル(大抵は、そのファイル名の末尾に".minisig"というsuffixが付けられています)
- 公開鍵(多くの場合、信頼できるhttpsのwebサイトに掲載されることが多いようです)

試しにzigのソースパッケージを検証してみます
minisig署名付きのファイルなら他のケースでも同じように検証すれば良いです

- zigのダウンロードURL。ここに検証のために必要な公開鍵も載せてあります
  - https://ziglang.org/ja/download/

```shell-session
$ wget https://ziglang.org/builds/zig-0.14.0-dev.296+bd7b2cc4b.tar.xz
$ wget https://ziglang.org/builds/zig-0.14.0-dev.296+bd7b2cc4b.tar.xz.minisig
$ ls zig-0.14.0-*
zig-0.14.0-dev.296+bd7b2cc4b.tar.xz
zig-0.14.0-dev.296+bd7b2cc4b.tar.xz.minisig
$ minizign -Vm zig-0.14.0-dev.296+bd7b2cc4b.tar.xz -P RWSGOq2NVecA2UPNdBUZykf1CCb147pkmdtYxgb3Ti+JO/wCYvhbAb/U
Signature and comment signature verified
Trusted comment: timestamp:1720987621	file:zig-0.14.0-dev.296+bd7b2cc4b.tar.xhashed
$ gdate --date='@1720987621' -Ins -u
2024-07-14T20:07:01,000000000+00:00
```
【CSS】テキストの枠線と塗りの順番を入れ替える

## はじめに
みなさんは、テキストに縁をつけたことがありますか？

テキストに縁をつけるには、`-webkit-text-stroke` を使うことで、テキストに縁をつけることができます
しかし、`-webkit-text-stroke` だけを使うと以下の画像のように、デザイン的にあまり美しくないです！

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/390720/21404c00-727d-ee9f-48ce-ca662415b002.png)

そのため、この記事では、テキストの枠線と塗りの順番を入れ替え、デザイン的にいい感じにする方法を紹介しようと思います！

## `paint-order` とは？
テキストの枠線と塗りの順番を入れ替えるには、`paint-order` というプロパティを使います！

`paint-order` は、テキストコンテンツやシェイプが描画されるときの塗りつぶしと輪郭 (およびマーカーの描画) の順序を制御することができるプロパティです。

`paint-order` の値は以下を指定することができます。

+ `normal`：通常の描画順にする
+ `stroke`・`fill`・`markers`：これらを指定する描画したい順序を指定する

```css
/* 単一の値 */
paint-order: stroke; /* 最初に輪郭、それから塗りつぶしとマーカーを描画 */
paint-order: markers; /* 最初にマーカー、それから塗りつぶしと輪郭 */

/* 複数の値 */
paint-order: stroke fill; /* 最初に輪郭を、それから塗りつぶしを、そしてマーカーを描く */
paint-order: markers stroke fill; /* マーカー、輪郭、塗りつぶしの順に描く */
```


## テキストの枠線と塗りの順番を入れ替える
テキストの枠線と塗りの順番を入れ替えるには、`paint-order: stroke` を指定することで、デザイン的にいい感じになります！

<p class="codepen" data-height="500" data-default-tab="css,result" data-slug-hash="mdZJqmO" data-pen-title="Untitled" data-editable="true" data-user="sp_degu" style="height: 500px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/sp_degu/pen/mdZJqmO">
  Untitled</a> by でぐぅー | Qiita (<a href="https://codepen.io/sp_degu">@sp_degu</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

## まとめ
この記事では、テキストの枠線と塗りの順番を入れ替え、デザイン的にいい感じにする方法を紹介しました！
ぜひこの記事を参考にテキストの縁をいい感じにしてみてください！

---

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

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

https://twitter.com/degudegu2510
DIって難しそうだけど、FastAPI のDependsは簡単に使えた話

# はじめに

FastAPIのDepend、なぜこれを使うのか、どんな時に使うのか、私なりにまとめてみました。
Dependsは、依存性注入(DI)するものとも言われてますが、DIの側面はあまり気にせず、見てみます。

# シンプルな例

例えば、q,skip,limitのパラメータを処理common_parametersがあったとします。
エントリーポイントの関数、read_itemにパラメータを並べて、取得して、common_parametersを呼び出します。

```Python:main.py
from typing import Union

from fastapi import FastAPI, Depends

app = FastAPI()

def common_parameters(
    q: Union[str, None] = None, skip: int = 0, limit: int = 100
):
    return {"q": q, "skip": skip, "limit": limit}

@app.get("/items/{item_id}")
def read_item(item_id: int, q: Union[str, None] = None, skip: int = 0, limit: int = 100):
    commands = common_parameters(q, skip, limit)
    return {"item_id": item_id, "commands": commands}
```

fastapi dev main.pyで実行してみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/532235/7b13f71d-d76c-f62a-291f-efaa80e79588.png)

ちゃんとパラメータの読み取りができている事がわかります。

## Dependsを使った場合

Dependsを使うと次のように書く事ができます。

```Python:main.py
from typing import Union

from fastapi import FastAPI, Depends

app = FastAPI()

def common_parameters(
    q: Union[str, None] = None, skip: int = 0, limit: int = 100
):
    return {"q": q, "skip": skip, "limit": limit}

@app.get("/items/{item_id}")
def read_item(item_id: int, commands: dict = Depends(common_parameters)):
    return {"item_id": item_id, "commands": commands}
```

## 何が嬉しいのか？

Dependsを使う場合と比較してみます。

### 関数内で直接呼び出す場合:
- common_parameters関数に必要なパラメータをエントリーポイントの関数のパラメータに羅列する必要がある
- read_items関数の内部でcommon_parameters関数が呼び出されてる事は、内部に隠れていている

### Dependsを使う場合:
- common_parameters関数に必要なパラメータは、common_parameters関数に記述するだけでよい
- 関数の引数としてcommon_parametersが明示的に示されている。

## 単純なデフォルトの引数との違い

Dependsを使った表記は、デフォルト値を与える記述に見えます。Dependsを使わず、次のように書いた場合との違いはなんでしょうか？

```Python
@app.get("/items/")
async def read_items(commons: dict = common_parameters()):
    return commons
```

この記述の場合、common_parametersは関数の定義時に一度だけ呼び出されその時の返り値がcommandsに入ります。
APIが呼ばれた時の実行されるわけではなく、common_parametersにq,skipなどのパラメータを渡す事もできません。

Dependsは、read_items()が呼び出されるたびに、common_parametersを呼び出します。引数にはリクエストに含まれているパラメータが自動的に入ります。

※Depends自体がどんな実装になっているか気になりました

## 認証処理を行う例

エンドポイントとして定義された関数の引数に、Request型の値を定義すると、現在処理中のリクエストに関する情報を含むRequestオブジェクトが渡されます。
このリクエストオブジェクトを使って認証処理を行う例を作ってみます。

```Python
@app.get("/items/")
async def read_users_me(request: Request):
    authorization: str = request.headers.get("Authorization")
    scheme, _, token = authorization.partition(" ")
    user = decode_token(token)

    # userの値を使った処理が続く
```
### Dependsを使った記述

認証に関する処理を、リクエスト関数本体から完全に切り出した記述にできました。

```Python
def get_current_user(request: Request):
    authorization: str = request.headers.get("Authorization")
    scheme, _, token = authorization.partition(" ")
    user = decode_token(token)
    return usesr

@app.get("/items/")
async def read_users_me(user: dict = Depends(get_current_user)):
    # userの値を使った処理が続く

```

# まとめ

エンドポイントで行う処理は、リクエストの内容に応じて様々な処理を行う必要があり、複雑になりがちです。
Dependsを使う事で、この処理の一部を切り出して実行するようにでき、認証処理など共通した処理を記述するのに有効に利用する事ができます。
最高のエンジニアライフプラン

## まえがき
エンジニアライフプランとしてこんな経験をしたかった、
体験できてよかったと思ったことを記載いたします。
少しでも共感いただけたり、ご参考になれば幸いです。

## 情報系の大学、高専在籍の経歴
学生時代にIT系学んでいた方々のスーパーマンっぷり半端なくないですか？
嫉妬する気すら起きずに学びの日々でした。
飲みの席で少し専攻に関してお聞きする機会がありましたが、
そりゃ勝てないわと思ってしまいました。

ちなみに私は分析化学を専攻していてガスクロマトグラフィーやMALDIを使用していました。
仕事には全く関係ない分野ですね。
不具合の調査に関しては、原因を特定するために要因を洗い出していく点が体に染みついているので役に立った部分もあります。

## 度重なる転職による様々な人との関わり
これは私自身の経験です。
現在3回転職を経験しており、個性的な方々と関わってきました。

* 毎日離席時間が2時間超える方
* デグレ常習犯
* チームメンバに仕事を押し付けて定退
* 進捗遅延を未報告からのバックレ

これらの経験から得られた教訓は、
よそはよそ、うちはうちです。
このような方々をマネジメントするのは直属の上司であり、私達ではありません。
1社目ではベンチャー企業ということもあり社長に密告したこともありましたが、逆に怒られてしまいました。
その時はあたおかじゃないか！と思いましたが今では理解できます。
自分を変えられるのは自分だけ、自分の仕事は他人の働き方を改善することではないということですね。

## 朝日を拝むまで残業する
これも私の経験です。
近頃働き方に関してシビアになり残業することも減りましたが、
一度は深夜残業して朝まで働くという経験もしておいた方がいいと思っています。
私が思うメリットのみ記載いたします。
* 長時間残業の愚かさがわかる(非効率、体力的にパフォーマンスが必ず落ちます)
* 自分の限界を知れる
* チーム内で謎の連帯感が出る
* 数年経つと笑い話になる

## あとがき
パッと思いつくものを記載しました。
私のあるあるネタですがIT業界バックレる人多くないですか？
ホワイト企業ではありえないのでしょうか。

良ければ皆様のためになった経験、
こんなことしたかったという願望をコメントしてくださーい。
Pythonの recv と recvfrom の違い

### `recv`の概要
- **用途**: `recv`は主にTCPソケットで使用する。
- **機能**: データを受信するが、送信元のアドレス情報は取得しない。
- **構文**: `recv(bufsize[, flags])`
  - `bufsize`: 受信するデータの最大バイト数。
  - `flags`: オプションのフラグ（省略可能）。
- **特徴**: 接続指向プロトコル（TCP）を使っているため、接続が確立された相手からのデータを受信する。

```python
import socket

# ソケット作成
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('example.com', 80))

# データ受信
data = s.recv(1024)
print('Received', repr(data))
s.close()
```

### `recvfrom`の概要
- **用途**: `recvfrom`は主にUDPソケットで使用する。
- **機能**: データを受信し、送信元のアドレス情報も取得する。
- **構文**: `recvfrom(bufsize[, flags])`
  - `bufsize`: 受信するデータの最大バイト数。
  - `flags`: オプションのフラグ（省略可能）。
- **特徴**: コネクションレスプロトコル（UDP）を使っているため、どのアドレスからデータが送信されたかを知ることができる。

```python
import socket

# ソケット作成
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.bind(('localhost', 12345))

# データ受信
data, addr = s.recvfrom(1024)
print('Received', repr(data), 'from', addr)
s.close()
```

### `recv`と`recvfrom`の違い
1. **プロトコル**:
   - `recv`: TCP
   - `recvfrom`: UDP

2. **アドレス情報**:
   - `recv`: 送信元のアドレス情報を取得しない。
   - `recvfrom`: 送信元のアドレス情報を取得する。

3. **接続**:
   - `recv`: 接続指向。事前に接続を確立する必要がある。
   - `recvfrom`: コネクションレス。データを受信するだけで送信元を特定できる。
【gomonkey】インライン化された関数にはモンキーパッチが効かない

# TL; DR

- コンパイラの最適化によって `gomonkey.ApplyFunc` が効かなくなることがある
- `-gcflags=all=-l` で最適化を無視することでテスト可能

https://github.com/agiledragon/gomonkey/issues/34

# はじめに
gomonkey は、関数をモンキーパッチすることができるモジュールです。ユニットテストでHTTP通信/DBアクセス関数等をモックに差し替えることで、再現しづらいコーナーケースもテストできるようになります。

https://github.com/agiledragon/gomonkey

:::note alert
モンキーパッチではunsafeを用いたメモリ書き換えを行っています。**プロダクトコード側への使用は非推奨です**。
:::

本記事では、モンキーパッチの関数 `ApplyFunc` が動作しなかった際の原因と対処法について紹介します。

# gomonkey.ApplyFunc
`ApplyFunc` を使用すると、引数に渡した関数の処理を書き換えることができます。

```go
// ターゲット関数
func Fact(n int) int {
	if n <= 0 {
		return 1
	}
	return n * Fact(n-1)
}

func main() {
	fmt.Println(Fact(5))

	// Factの処理を差し替える
	patches := gomonkey.ApplyFunc(Fact, func(int) int {
		return 99999999
	})
	defer patches.Reset()

	fmt.Println(Fact(5))
}
```

```:結果
120
99999999
```

仕組みとしては、`unsafe` を使い関数ポインタを動的に書き換えることで代わりにモック関数が呼び出されるようにしています。

https://bou.ke/blog/monkey-patching-in-go/

# インライン化によりApplyFuncが動作しなくなる
しかし、下記のような場合にはモンキーパッチが効きません。

```go:インライン化されない例
func SayHi() {
	fmt.Println("Hi")
}

func main() {
	SayHi()

	patches2 := gomonkey.ApplyFunc(SayHi, func() {
		fmt.Println("patched")
	})
	defer patches2.Reset()

	SayHi()
}
```

```
Hi
Hi
```

具体的には、コンパイラの最適化によって関数がインライン化される場合です。

## インライン化
関数呼び出しには呼び出し命令分のオーバーヘッドがかかるため、本体の処理を呼び出し元に直接記載することで高速化できます。コンパイラが下記変換を自動で行うのがインライン化です。

```go:before
func SayHi() {
	fmt.Println("Hi")
}

func main() {
	SayHi()
}
```

```go:after
func main() {
	fmt.Println("Hi")
}
```

https://docs.google.com/presentation/d/1Wcblp3jpfeKwA0Y4FOmj63PW52M_qmNqlQkNaLj0P5o/edit#slide=id.p

小さな関数、関数呼び出しを行わない関数ほどインライン化されやすいため、 上記 `SayHi` は最適化の対象となっています。

そして、インライン化で置き換えられる処理は元の関数の処理なので、モンキーパッチが効かなくなってしまいます[^inline]。

```go
	patches2 := gomonkey.ApplyFunc(SayHi, func() {
		fmt.Println("patched")
	})

	// SayHi() がインライン化
	// べた書きの処理だからモンキーパッチできない！
	fmt.Println("Hi")
```

## インライン化されているか確認する

`-gcflags="-m=1"` で、最適化情報をデバッグプリントできます。

```bash
$ go build -gcflags="-m=1" 2>&1 | grep inline
./main.go:16:6: can inline SayHi
./main.go:23:38: can inline main.func1
./main.go:26:2: can inline main.deferwrap1
./main.go:32:40: can inline main.func2
./main.go:35:2: can inline main.deferwrap2
```

`SayHi` はインライン化され、`Fact` は関数呼び出しのままであることが確認できます。

# 対処法
コンパイル時にインライン化しないようにすれば解消します。以下のフラグで最適化を無効化します。

```bash
$ go build -gcflags=all=-l
```

https://github.com/agiledragon/gomonkey/issues/34#issuecomment-778617856

今度は想定通りモンキーパッチされました。

```実行結果
Hi
patched
```

# おわりに
以上、モンキーパッチが効かない原因の紹介でした。原因が分かりづらいので厄介でした...

~~いっそのこと、モンキーパッチではなくDIするように改修した方が早いかもしれません~~

[^inline]: インライン化はコンパイル時、モンキーパッチは実行時であることに注意してください。
プロセス置換のエラー処理、終了ステータスをシェルスクリプトで取る方法

## はじめに

シェルスクリプトのエラー処理は難しい場面がいくつかあります。そのため信頼性の高いシェルスクリプトを書くのが困難になっています。POSIX.1-2024 での `set -o pipefail` の標準化でパイプラインのエラー処理を移植性がある形で実装することができるようになりました。しかしまだエラー処理が難しい場面が残っています。それがプロセス置換です。この記事ではプロセス置換のエラー処理を行う方法について解説します。ちなみにこの記事の対象シェルはプロセス置換が実装されているbash、ksh93、zshです。

## なぜプロセス置換は終了ステータスを取れない？

プロセス置換の書き方はこのようなものです。

```console
$ diff -u <(echo foo) <(echo bar)
--- /dev/fd/63  2024-07-15 08:12:04.455507170 +0900
+++ /dev/fd/62  2024-07-15 08:12:04.459507190 +0900
@@ -1 +1 @@
-foo
+bar
```

ここでプロセス置換で実行しているコマンドでエラーを発生させ、終了ステータスを見てみましょう。

```console
$ diff -u <(seq -f '%x' 1) <(seq -f '%y' 1)
seq: format ‘%x’ has unknown %x directive
seq: format ‘%y’ has unknown %y directive

$ echo $?
0
```

ご覧の通り、エラーが発生しているのに終了ステータスは正常 (0)です。当然ですがこれはパイプラインではないので `PIPESTATUS` は役に立ちません。

なぜ終了ステータスが取れないかと言うと、プロセス置換の中のコマンドは呼び出し元プロセスとは独立して非同期で実行されているからです。終了ステータスが取れないのもあたりまえですね。

さてこの問題、どうやって解決しましょうか？

## サブシェルの中なら終了ステータスを取れる

コードが複雑になるのでここからはシェルスクリプトで説明します。終了ステータスが取れないと言っても、それは呼び出し元プロセスの話で、プロセス置換のサブシェルの中なら当然取ることができます。

```sh:script.sh
#!/bin/bash
diff -u <(seq -f '%x' 1; echo "ex1=$?" >&2) <(seq -f '%y' 1; echo "ex2=$?" >&2)
```

```console
$ ./script.sh
seq: format ‘%x’ has unknown %x directive
seq: format ‘%y’ has unknown %y directive
ex2=1
ex1=1
```

ここまでわかれば後は簡単ですね？ いつものやつを書くだけです。ですよね？ 

## 完成

ぱっと書けるか？と言われたら今でも考えながらでないと書けないわけですが、さすがにこんな感じでやればできるよね？ぐらいにまでは慣れました。不要なファイルディスクリプタ、ちゃんと閉じれてるよね？

```sh:script.sh
#!/bin/bash

{
  xs=$(
    {
      diff -u \
        <(seq -f '%x' 1 4>&-; echo "xs1=$?" >&4) \
        <(seq -f '%y' 1 4>&-; echo "xs2=$?" >&4) >&3 3>&-
    } 4>&1
  )
  eval "xs=$? $xs"
} 3>&1

echo "xs: $xs, xs1: $xs1, xs2: $xs2"
```

```console
$ ./script.sh
seq: format ‘%x’ has unknown %x directive
seq: format ‘%y’ has unknown %y directive
xs: 0, xs1: 1, xs2: 1
```

もう少し真面目にやるなら `set -e` の処理を付け加えるのですが、書かなくても大丈夫ですよね？ できるのはわかってるんですが、真面目に書くと面倒だなーと。

## さいごに

ということで、私の中ではおなじみのパターンになっちゃっているわけですが、よくよく考えたら誰もこのやり方知らないんじゃね？と思って書いてみました。ちゃんと調べてないので、すでにどこかで誰かが紹介しているかもしれませんが。ちょっと込み入った話になると真面目にシェルスクリプトのエラー処理書くのって面倒ですよねぇ。

あとは発展として、これを使いやすいライブラリの形に落とし込めたらなーと思っています。うーん、どういうインターフェースにすればいいだろうか、プロセス置換の数は2個とは限らないし、名前付きパイプを使って POSIX で標準化された機能だけで実現したいし。まあ今すぐ必要なわけではないのでそのうち。
NotebookLMを活用して情報を効率よく整理しよう

## はじめに
　こんにちは。まっちゃ。です。:tea: 
　今回は、情報整理の効率向上のために「NotebookLM」の使い方をまとめていきます。

## 目次
- 概要
- 使い方
- 利点
- 活用例
- まとめ

## 概要
　NotebookLMは、Googleが開発した情報処理を補助するAIツールのことであり、2024年6月に日本での提供が開始されました。

https://blog.google/intl/ja-jp/company-news/technology/notebooklm-google/

　NotebookLMでは、ファイルをアップロードすることにより、AIがファイル中の情報をもとにしてユーザーの質問に回答します。また、大規模言語モデル[^1]としてマルチモーダルなモデルである「Gemini 1.5 Pro」を搭載しているため、ファイル内の画像やグラフについても理解でき、図をもとにした回答を生成できるという特徴があります。
　さらにこのツールは、**無料**で利用可能です。

## 使い方
　使い方の大まかな流れとしては、以下の3つになります。
　1. ログイン
　2. ファイルのアップロード
　3. チャット形式の対話による情報の抽出 

　では、NotebookLMを用いた情報整理をしていきます。今回は物体検出に用いられるアルゴリズムの1つである「YOLO」[^2]の論文を使用していきます。
 
　まずは下記のページにアクセスしてください。

 https://notebooklm.google/

1 . ログイン
- 右上の「Try NotebookLM」をクリック
- 遷移後の画面にてGoogleアカウントの情報を入力し、ログイン

<img src='https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3673789/192a478f-6a40-09b3-aa7b-4216b45f2496.jpeg', width=60%>

2 . ファイルのアップロード
- ログイン後のホーム画面にて、「+ 新しいノートブック」をクリック
- アップロードするファイルの種類を決定し、ダイアログにてファイルを選択
選べるファイルの種類として、「PDF、テキスト、URL」等があります。

ログイン後のホーム画面
<img src='https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3673789/95b1cb12-ead8-2a22-f393-321f0fae7a2e.jpeg', width=60%>

ファイル種類の選択画面
<img src='https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3673789/69562d08-9234-6973-9f32-b85dff9de493.jpeg', width=60%>

　ファイルをアップロードすると、下部の「ノートブックガイド」にて、内容の概要が表示されます。また、アップロードしたファイルは左側にあるソース欄で確認することができ、チェックボックスのオン/オフにより、回答生成におけるファイルの使用/未使用を切り替えることができます。ファイルを追加する場合は、ソース欄にある「田」をクリックします。

3 . チャット形式の対話による情報の抽出
- 下部にある「チャットを表示」をクリックし、入力フォームに質問事項を記入して送信

<img src='https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3673789/ca831033-51bd-cd61-7a85-fb8193beed22.jpeg', width=60%>

　「YOLOの利点を教えて」との質問に対して、「YOLOには、処理速度と精度のバランスの良さという利点がありますが、正確なオブジェクトの位置特定、特に小さなオブジェクトの位置特定には苦労するという欠点もあります。」といった回答が生成されました。このように、関連するプラスアルファの情報も含んだ回答を生成してくれます。

　また、生成された回答は右上にあるピンのマークをクリックすることで、メモとして保存され、後から見返すことができます。

## 利点
　NotebookLMを利用して、2つの利点を感じました。
 - 時間を浪費することなく、必要な情報を取得できる
　過去に調べたことがある事柄について忘れてしまい、再び調べる必要性がでた場面を思い浮かべてください。今の時代、検索しようと思えばいくらでも情報が出てきます。しかし、ノイズが多いために時間を浪費する一方で、本当に必要な情報を取得できないことがあります。NotebookLMにあらかじめファイルをアップロードしておき、辞書として活用することで、必要な情報を即時に取得することが可能となります。 
 <br>

 - 回答の信頼性が担保できる
　生成AIの利用に関して、ハルシネーション（最もらしい嘘）が問題となります。NotebookLMでは、回答の生成で参考にした箇所を示してくれるため、情報元が明確になります。また、ファイル中の情報をもとに回答できない場合は、「ソースに基づいてあなたの質問に答えることはできません。」と返答されるため、信頼性が担保されます。

## 活用例
　ここでは、NotebookLMの活用例を2つ紹介します。
 - 論文要約
　上述したように論文のPDFファイルをアップロードするだけで、重要な点を抑えた要約をしてくれます。さらに、チャット形式で質問していくことにより、関心がある点の理解を深めることができます。
<br>
 
 - 取り扱い説明書
　各取り扱い説明書のファイルをアップロードしておくことで、まとまった独自の説明書を作成することができます。紙の説明書はサイズが異なったり、かさばったりするため保管に困ることがあります。NotebookLMを活用することで、保管場所に困らず、即時に情報を入手できる説明書となります。
<br> 

　活用法については、以下のページも参考にしてみてください。

https://weel.co.jp/media/innovator/notebooklm/#index_id12

https://www.watch.impress.co.jp/docs/topic/1602337.html

## まとめ
　NotebookLMについてまとめてきました。以前は、調べた内容の要点を逐一ノートにまとめていました。そのため、読み返しや、別々の情報をつなぎ合わせることに時間がかかっていました。NotebookLMでは、ファイルをアップロードするだけで、重要な点をまとめた回答を生成してくれるため、簡単に情報を整理することができます。今後はこれらの利点を活かして、効率よく情報整理を行っていきます。

### 補足
[^1]: 大量のデータセットにより構築された自然言語処理モデルのことです。学習を進めることで、例えば、チャットボットや検索エンジン、言語翻訳といった自然言語における様々なタスクをこなすことが可能になります。

[^2]: 「You Only Look Once」の頭文字から名付けられており、日本語で一度見ただけで物体を識別できることを指します。
【Smart Fill】自己のAI知能補助入力ツール


![图片](https://mmbiz.qpic.cn/sz_mmbiz_png/4CAA63nvHRA60EOGeWZgnPOvQ6TJPcQp9CPa5xGpZyOWIrwo5YD4E5IF5LkAsiabHFjRN0dA4AbVKYVCxn8CKVQ/640?wx_fmt=png&from=appmsg&tp=webp&wxfrom=5&wx_lazy=1&wx_co=1)

**SmartFill使用説明**

SmartFillは、テキスト入力、画像、Word、Excel、PDF、テキストファイルのアップロード、音声入力ができるインテリジェント入力ツールです。SmartFillは、ユーザーが入力した情報を抽出、変換、集約し、対応するページ項目に入力します。これにより、ユーザーが時間を節約し、効率を向上させることができます。

SmartFillは現在Chromeプラグインの形式で提供されており、Chromeプラグインストアでダウンロードして試用することができます。

![图片](https://mmbiz.qpic.cn/sz_mmbiz_png/4CAA63nvHRA60EOGeWZgnPOvQ6TJPcQpRa9NqiakaSrS9lYhHKUaUCOgm8tR0plkhlSxbsKiaWTvh04ooPdkFf5g/640?wx_fmt=png&from=appmsg&tp=webp&wxfrom=5&wx_lazy=1&wx_co=1)

**注：現在リリース中のため、サービスの利用可能性は常に保証されませんので、ご了解ください！**

**第一歩：登録、ログイン**

ユーザーが入力を行いたいページにアクセスし、SmartFill Pro Chromeプラグインをクリックして Eメールとパスワードで登録します。アカウントにログインした後、初期ユーザーは1日の無料試用期間があります。長期間使用したい場合は、axzxs2018@gmail.comまでご連絡ください。

**第二歩：インテリジェント入力項目の設定**

SmartFillは【設定なし】と【設定あり】の二つの方法があります：設定なしの方法はログインするだけで簡単に使えるが、自動入力時に少し遅かったり、不確定性がもっとあります。そのため、入力項目が固定されているページでは、設定ありの方法を使用することをお勧めします。ページの入力項目が動的に変化する場合は、設定なしの方法を使用してください。

設定方法：入力ページで「設定」メニューをクリックすると、設定ウィンドウに移動し、SmartFillはユーザーがURLページに入力する必要があるプロジェクト情報を自動的に収集します。その後、ユーザーはこれらの情報を簡単に設定するだけで、後続のインテリジェント入力が容易になります。例えば、ページに名前があり、それに対応するピンインが必要な場合は、「名前をピンインに変換する」を設定することができ、インテリジェント入力時にSmartFillは自動的に漢字を対応するピンインに変換します。また、ページに郵便番号があり、特定の形式が必要な場合は、「郵便番号（000-0000）」と設定することができます。設定はインテリジェント入力に非常に重要で、数回の調整が必要かもしれませんが、一度設定が完了すると、後続の入力は非常に便利です。

**第三歩：インテリジェント入力**

設定完了後、テキスト情報の入力、画像、Word、Excel、PDF、テキストファイルのアップロード、音声での入力が可能です。その後、送信すると、SmartFillはユーザーが入力した情報を順次ページの入力項目情報に変換します。また、QRコードを開いて携帯電話で写真を撮ったり、音声で隔空入力を行ったりして、即時に収集と入力を行うことができます。

**その他：ユーザー管理と設定管理**

SmartFillのログインページでパスワードを忘れた操作を行うことができます。入力ページでは、パスワード変更や設定管理の機能を行うことができます。もしご意見や提案がございましたら、axzxs2018@gmail.comまでお知らせください。

** コンテンツを配信する 10 の方法
1. テキストモード
![文字.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538010/ae1b5c85-bd61-0aaa-7884-dd43f846c810.gif)

2. ピクチャーモード
![图片.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538010/d347c30e-c023-aa1a-3c4a-faceefd3df28.gif)

3. 音声モード
![语音.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538010/c5ffd2c0-4e14-06b8-d22c-3cecf67e81b1.gif)

4. PDFモード
![pdf.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538010/30877e26-108c-501d-5081-f06945e21498.gif)

5. Wordモード
![word.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538010/c87d5e72-8684-6e2f-0aef-675de2653067.gif)

6. Excelモード
![excel.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538010/d4960025-073f-7808-f3cc-7e5d9e2de549.gif)


その他の方法については、https://just-agi.com/smartfill/index.html を参照してください。

(Translated by GPT)
元のリンク：https://mp.weixin.qq.com/s/ZqgSL6_yAjyp_YETi3aZcA?wt.mc_id=MVP_325642
Pandas: csv ファイルの修正

## 仕様

指定されたフォルダー内にある csv ファイルの　"2021-10-00" を "2021-10-12" に置き換える

## プログラム

```py:csv_replace_folder.py
#! /usr/bin/python
#
#	csv_replace_folder.py
#
#						Jul/15/2024
# ------------------------------------------------------------------
import pandas as pd

import sys
import glob
import csv

# ------------------------------------------------------------------
def csv_replace_single_proc(csv_file_path,str_src,str_target):
	df = pd.read_csv(csv_file_path,dtype=str)

	df = df.map(lambda x: str_target if x == str_src else x)
#
	df.to_csv(csv_file_path,index=False,quoting=csv.QUOTE_ALL)	
# ------------------------------------------------------------------
def get_csv_file_paths_proc(folder_file_path):
	files = glob.glob(folder_file_path + "/*.csv")
#	print(files)
	return sorted(files)
#
# ------------------------------------------------------------------
folder_file_path = sys.argv[1]
sys.stderr.write(folder_file_path + "\n")
files = get_csv_file_paths_proc(folder_file_path)
#
str_src = "2021-10-00"
str_target = "2021-10-12"
#
try:
	for csv_file_path in files:
		csv_replace_single_proc(csv_file_path,str_src,str_target)
#	
except Exception as ee:
	sys.stderr.write("*** error *** in file_to_str_proc ***\n")
	sys.stderr.write(str(ee) + "\n")
#

sys.stderr.write("*** end ***\n")
# ------------------------------------------------------------------
```

## 実行方法

```bash
./csv_replace_folder.py /tmp/test_folder
```