OmniAICreator/Qiita-1.07M huggingface dataset:
【Xcode】Utilies AreaのViewにある『Tint』って何？

## 【「Xcode」のスクショ】

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/359201/5dec9fee-b18c-440d-a3e9-9833c67dc112.png)

## 【「実機」のスクショ】

TextViewに文字を入力しようとするときにチカチカ表示される縦線
（自分のケースの場合は「赤い縦線」

![31365751-B220-42C0-BA28-C51FEB803BF5_1_201_a.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/359201/376d1f42-43b3-3eba-14f3-9dc25add5cce.jpeg)
Stable Diffusion ControlNetのCanyのLow ThresholdおよびHigh Thresholdの検証

ControlNetの輪郭を抽出するCannyというプリプロセッサおよびモデルの検証結果です。
Cannyを利用することで既存の写真と同じ構図の画像を生成することができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325297/2c93d2bc-f67e-8d87-7f97-7a0762059881.png)

# 結論
* LowとHighの違いはよくわからなかった
* Thresholdは高い方が輪郭線の量が減るが、劇的な変化はない

## Low Thresholdの値を変えて試してみる
* High Thresholdはデフォルトの150を使用

### Low Threshold:1 最低値
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325297/c1106eed-8f44-5b8c-7ab0-95a7d302850f.png)

### Low Threshold:100 デフォルト値
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325297/602618c1-4161-4321-6bd5-8d2f65588d36.png)

### Low Threshold:200
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325297/48bc3580-ac54-652a-c1ba-273ff306021d.png)

### Low Threshold:255 最高値
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325297/6945bd97-be62-cb19-0c5f-94488e435ece.png)

## High Thresholdの値を変えて試してみる
* Low Thresholdはデフォルトの100を使用

### High Threshold:1 最低値
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325297/de585a9c-5912-2acb-c325-fb96933f64d7.png)

### High Threshold:100 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325297/14fb2ae2-b2ca-c179-d644-32d97cf717cb.png)

### High Threshold:150 デフォルト値
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325297/34471a28-55c3-9dba-a2d2-9f1cee1e597c.png)

### High Threshold:200
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325297/432ef109-faad-bb15-9d4a-1c6d72e51635.png)

### High Threshold:255 最高値
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325297/8ece0715-bc38-8e53-b3cc-58253796dd3d.png)
@supabase/auth-helpersのcreateRouteHandlerSupabaseClientでログイン後にセッションが取得できない

## 遭遇した問題

[API Handler](https://beta.nextjs.org/docs/routing/route-handlers)を使い、以下のようなコードでログイン処理を実装しました。
その際[@supabase/auth-helpersのcreateRouteHandlerSupabaseClient](https://supabase.github.io/auth-helpers/modules/nextjs_src.html#createRouteHandlerSupabaseClient)を使用しました。

```ts:lib/supabase/server.ts
import { createRouteHandlerSupabaseClient } from "@supabase/auth-helpers-nextjs";
import { headers, cookies } from "next/headers";

export const createClientRouteHandler = () =>
  createRouteHandlerSupabaseClient({
    supabaseKey: process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
    supabaseUrl: process.env.NEXT_PUBLIC_SUPABASE_URL!,
    headers,
    cookies,
  });
```

```ts:app/api/auth/login/route.ts
import { NextResponse } from "next/server";
import { createClientRouteHandler } from "~/lib/supabase/server";

export async function POST(request: Request) {
  const supabase = createClientRouteHandler();
  const user = await supabase.auth.signInWithPassword({
    email: res.email,
    password: res.password,
  });
  ...
```
しかし、他のファイルで以下のようなコードでセッションを取得しようとしてもnullが返ってきます。
```ts
import { NextResponse } from "next/server";
import { createClientRouteHandler } from "~/lib/supabase/server";

export async function GET(request: Request) {
  const supabase = createClientRouteHandler();
  const { error, data } = await supabase.auth.getUser();
  console.log(data); // { user: null }
```

## 原因
Supabase公式の以下のYoutube動画で指摘されているようにNext.js側のバグの可能性が高く、cookieがうまく渡ってきていないことに起因すると思われます。
https://www.youtube.com/watch?v=KmJN-bEayeY&t=600s

## 対処法
Next.js側が対応するのを待つしかなさそうなので、一旦こういった処理はServer ComponentやClient Component側に移すことにしました。
40代エンジニアだけど、3ヵ月でAWS SAA取れました

#受験記録

【要約】
・AWS経験ほぼ無し、40代エンジニア
・SAA-C03 ３か月で合格
・今年の4月に受験（合格）
・次は、DVA→SAPを予定

０）本人の経験と、動機
【経験】
・40代、おっさんインフラ系エンジニア十年程度
・AWSは経験少ない、提案書作成とか。
・CI/CDなどは多少あり、プライベートクラウド経験はあり。
・応用情報処理、Oracleマスターなどクラウド以外の資格は多少
【動機】
・前から取らなきゃと思っていたところに、再受験無料キャンペーンが。
これに間に合わせれるように、受験を決意
・試験とか久々でブランクあるので、ゆるーく学習

１) 参考書
SA Associate BootCamp
<a herf=https://www.udemy.com/course/aws-knan/learn/quiz/4632482/results?expanded=226469176#overview>Udemy【SAA-C03版】AWS 認定ソリューションアーキテクト アソシエイト模擬試験問題集</a>
<a herf=https://mondai.ping-t.com/g/question_subjects#content-large_category_2>ping-t</a>

２）学習期間、総学習時間
　1日0.5～1hで、90日で大体100～150h位だったかと。

  i) 読込み期 <B>1カ月</b>　BootCampの読み込み、写経x1
　 　→ モチベが上がらず、ダラダラやったが、1～2Wでやれたかも。
    →その後、Udemyやったが、正答率が35%～50%と低く、さらにモチベダウン(2ヵ月程中断)

  ii) 演習期(in-out) <B>2カ月</b> ping-t ＋ Udemy

|期間 |量(毎日当り)|正答率 | 周回 | コメント |
|:-:|:-:|:-:|:-:|:-:|
|１カ月|30-50問| 40～50% → 60%<BR>→70% → 70%後半(10日毎)|2周|最初は、モチベが低く少量を繰り返し解く(*1)|
|3週間|60問|70～85%|1周|苦手70%、得意85%。80%超えてきたんで申込む   |
|1週間|100-150問|85～95%|2周半|最後の1週間追込み<BR>試験前に、Udemyx2回分(50%～60%位)(*2)|

(*1)自分は、正答率が低い状態で、長時間取り組めないタイプなので、継続重視で。
(*2)Udemyは、本番よりも難しいらしいので、気にしないことにした。
 
３）結果
  再試験無料キャンペーンの最終日に試験受験し、
  １回で合格　スコア777

４）振り返り
　・AWS Well-Architected フレームワークや、DB、サーバーに関しては、
　オンプレや情報処理での知見があれば、結構答えが導き出せる。
　　→AWSとかクラウド固有の要件だけ学習するスタンスで、通用した感じ。
　・人にもよるが、初回でUdemyで正答率低いと、継続するモチベが下がるので、
　難易度の低い問題に直ぐに切り替えた方が良さそう。
　・試験が久しぶりで、反復期間などこれだけ必要無かったかも知れない…。
　まぁ、次回以降、正答率に紐づいて学習プランを適宜変えるのも良いかも。
シグモイド関数をmatplotlibで描画してみた

# 概要
今日はディープラーニングの勉強の手始めということで、シグモイド関数をmatplotlibで描画してみました。
以下のページを参考にしました。
https://zero2one.jp/learningblog/deep-learning-activation-function/

# 基本形
シグモイド関数の基本形を描画してみました。ソースコードは上記のページを参考にしました。
```simoid.py
import numpy as np
import matplotlib.pyplot as plt 

#sigmoid関数を定義
def sigmoid(x):
    return 1/(1+np.exp(-x))

x = np.linspace(-8,8,1000)
y = sigmoid(x)

#sigmoid関数を描画
fig = plt.figure()
ax = fig.add_subplot(111)
ax.plot(x,y)
plt.grid()
plt.show()
```
実行すると以下のようなウィンドウが表示されました。
![Screenshot from 2023-05-03 13-00-38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3192024/f8a01bbc-da9f-c2a6-cc1c-0e3d52a5636f.png)

# ゲインを変更
シグモイド関数のゲインを変更してみました。ソースコードは上記のページを参考にしました。
```sigmoid2.py
import numpy as np
import matplotlib.pyplot as plt 

#一般sigmoid関数を定義
def sigmoid(x, a):
    return 1/(1+np.exp(-a*x))

#x軸
x = np.linspace(-8,8,1000)

#aの値(0.1から1まで約0.1間隔で変化させる)
a = np.linspace(0.1, 1.0, 10)

#描画
fig = plt.figure(figsize = (12, 12))
for i in range(len(a)):
    text = "a = "+str(a[i])
    ax = fig.add_subplot(5, 5, i+1, title = text)
    ax.plot(x, sigmoid(x, a[i]))

fig.subplots_adjust(wspace=0.5, hspace=0.5)
plt.show()
```
実行すると以下のようなウィンドウが表示されました。
![Screenshot from 2023-05-03 13-02-34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3192024/f2543285-7222-c46f-4e1f-92c00b70b87b.png)

# 微分
シグモイド関数を微分した結果を表示してみました。上記のページを参考にしました。
```sigmoid3.py
import numpy as np
import matplotlib.pyplot as plt 

#微分後のsigmoid関数を定義
def grad_sigmoid(x):
    return np.exp(-x)/(1+np.exp(-x))**2

x = np.linspace(-5,5,100)
y = grad_sigmoid(x)

#描画
fig = plt.figure()
ax = fig.add_subplot(111)
ax.plot(x,y)
plt.grid()
plt.show()
```
実行すると以下のようなウィンドウが表示されました。
![Screenshot from 2023-05-03 13-04-34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3192024/8ba6a165-f664-7692-8730-f277aedee7d2.png)

何かの役に立てばと。
【SwiftUI】amazonみたいにスペースだけでは検索できないようにする

開発中のiOSアプリで検索ロジックを実装しようとした時
`半角・全角スペース`など、意図しない文字列のみで検索できてしまうと
ヒット件数がとんでもないことになってしまい、ユーザー体験としていかがなものかということで
そもそもちゃんと **「ひと文字以上文字が入力されている」** 状態でないと
検索できないようにしようという方向性になりました。

世の中のアプリをベンチマークしていると
**amazon** のネイティブアプリは
**「一文字目はそもそも`半角・全角スペース`が入力できない」** 
ということが分かったので、これだ！と思い、実装したのでご紹介します。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2633746/c261cb06-3052-b8b6-4c36-020d6c1eb8db.gif" width="300">

# Viewを実装する

今回は便利な`Searchable`を使って実装します

https://developer.apple.com/documentation/swiftui/view/searchable(text:placement:prompt:)-18a8f

:::note warn
今回は検索の具体的な実装は省略します
:::

```swift
// Search.swift

struct Search: View {
    @ObservedObject var viewModel: ViewModel
    
    var body: some View {
        NavigationView {
            VStack {
                // Not yet implement
            }
            .navigationTitle("Search")
        }
        .searchable(text: $viewModel.searchText)
    }
}

struct Search_Previews: PreviewProvider {
    static var previews: some View {
        Search(viewModel: .init())
    }
}
```
- `Searchable`を使うために`NavigationView`を使用します。

- `@ObservedObject`でこの後実装する`ViewModel`を監視します。

- `$viewModel.searchText`の部分は、`.searchable`に対して
viewModelに定義する`searchText`パブリッシャーをBindingで渡します。
文字が入力されるとこのプロパティが更新されます

Viewはこれだけです。

# ViewModelを実装する

```swift
extension Search {
    class ViewModel: ObservableObject {
        @Published var searchText: String = "" {
            didSet { toBlank() }
        }
        
        private func toBlank() {
            let invalidCharacters = [" ", "　"]
            if invalidCharacters.contains(searchText) {
                searchText = ""
            }
        }
    }
}
```
`SearchView`にextensionする形で`ViewModel`を実装しています

- `searchText`パブリッシャーが更新される度に処理をしたいので`didSet`を使います

:::note 
**プロパティオブザーバー**
ストアドプロパティの更新を監視できます

    `didSet` : 値が更新された直後に呼ばれる 
    `willSet` : 値が更新される直前に呼ばれる
:::

- 入力された文字が`半角・全角スペース`の場合に`searchText`を空文字列にする
プライベート関数`toBlank`を実装しています。

こうすることで、一文字目に`半角・全角スペース`を入力する操作をした時、
何も入力できない状態を作ることができました。

![Simulator Screen Recording - iPhone 14 Pro - 2023-05-03 at 12.56.42.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2633746/93d05a62-99ff-6673-0f6c-a00037cb5f15.gif)

# おわりに
backend側で`半角・全角スペース`の場合はクエリかけないようにしようかとも思いましたが
ユーザーからしたら「今検索ボタン押せたけど、何も出てこねえぞ？」
ってなっちゃうので、クライアント側でこのように実装するのがベストかな
という結論にひとまず落ち着きました。

ユーザビリティに大きく関わってくる部分なので、こういうところを考えるのは大事だなあ。
あと、検索ロジックって改めて難しいよなあ。
apex:variableのvalueを使ってrepeatで数値の加算を行う

前回はapex:repeatについて紹介しました。👇
https://qiita.com/Lee05/items/74586b1dfd25e5f4bd27

今回はvariableも併せて紹介したいと思います。
repeatの始まる前で追加し、その時のvalueは１
終わる前もう一回定義する、その時のvalueはrowNumber+1とする
var 変数値は同じrowNumberなので、追加された値が最終値になります
取得したrowNumberを使って、行の偶数奇数計算などもできます。
```:visualforce
<apex:page standardController="Account" >
    <table border="1" >
        <tr>
            <th>No</th>
            <th>取引先責任者名</th>
            <th>電話番号</th>
            <th>Email</th>
        </tr>
        <!--apex:variable追加箇所1 -->
        <apex:variable value="{!1}" var="rowNumber"/>
        <apex:repeat var="contacts" value="{!Account.Contacts}">
            <tr>
                <td>{!rowNumber}</td>
                <td>{!contacts.Name}</td>
                <td>{!contacts.Phone}</td>  
                <td>{!contacts.Email}</td>
            </tr>
             <!--apex:variable追加箇所2 -->
            <apex:variable value="{!rowNumber+1}" var="rowNumber"/>
        </apex:repeat>
    </table>
</apex:page>

```
上記のコードの実行結果：
Noの部分が作れるようになりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3330192/aa6eadbb-97f4-464c-6206-cf7e13209de7.png)
WSLでファイルのやり取り

WSLでWindowsやLinuxのファイルをやり取りする際の方法

+ Windows側からLinux側へアクセス
エクスプローラーでアドレスバーに下記を入力
~~~
\\wsl$
~~~
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/22836/eccc57de-7097-59a8-c3d9-c1bb68b6791c.png)

+ Linux側からWindows側へアクセス
~~~
cd /mnt/c
~~~

参考：
[Windows および Linux ファイル システム間での作業](https://learn.microsoft.com/ja-jp/windows/wsl/filesystems)
python maya get all joint with keys

```python
import maya.cmds as cmds

# Get all joint nodes
joints = cmds.ls(type="joint")

# Filter out joints that do not have any keys
keyed_joints = [joint for joint in joints if cmds.keyframe(joint, q=True, keyframeCount=True) > 0]

# Print the names of all the keyed joints
for joint in keyed_joints:
    print(joint)
```
windowsにTerraformをインストールする

# はじめに
「Terraformつかったみたい！」って思って公式サイトからTerraformダウンロードしたけど
インストール方法まで書いてなかったのでメモ残す。

結果からいうと、おそらく「インストール手順書かなくても実行ファイルを動かすだけなんだからインストール手順ってそもそも存在しないでしょ？」ってことを公式は言ってるんだろうなぁ…
と思ったけど、自分はわからなかったのであえてメモ残す。

# インストール方法
1. Terraformの公式サイト（https://developer.hashicorp.com/terraform/downloads）から、使用するWindowsのバージョンに合ったバイナリをダウンロードします。ダウンロードしたファイルはzip形式になっています。
※ウチはi386系なので↓↓のバージョンをダウンロード
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416263/59540ea9-85b2-9a9a-974a-492582f16533.png)

1. ダウンロードしたzipファイルを解凍します。解凍すると、terraform.exeというファイルが現れます。

1. terraform.exeファイルを適当な場所に配置します。例えば、C:\Users\watya\terraform\というディレクトリを作成して、その中にterraform.exeを配置する場合は、次のようにします。

```
C:\> cd C:\Users\watya
C:\Users\watya> mkdir terraform
C:\Users\watya> cd terraform
C:\Users\watya> move <解凍したterraform.exeファイルの場所>\terraform.exe .
```

1. 環境変数を設定します。環境変数にパスを通すことで、コマンドプロンプトからterraformコマンドを直接実行できるようになります。
以下の手順で、システム環境変数にパスを追加します。

コントロールパネルを開く
* システムとセキュリティ → システム → システムの詳細設定 → 環境変数 を選択
* システム環境変数の「Path」を選択して「編集」をクリック
* 「新規」をクリックして、terraform.exeがあるパス（例：C:\terraform）を追加
* OKをクリックして、設定を保存
インストールが完了したら、以下のコマンドを実行して、Terraformが正しくインストールされたかどうかを確認します。

```
C:\> terraform --version
```
実際の結果がこちら。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416263/2a9c29c8-c42b-ed9b-ee1e-8bbf0f43393f.png)



以上。
Pythonモジュール(eland)のソース(CLI)をローカルでインストールしないで動かす

# 動機

Elasticでは[eland](https://github.com/elastic/eland)というML周りのPythonライブラリを提供していて、例えば[sklearn](https://scikit-learn.org/stable/)で作成したデータフレーム分析モデルをElasticsearchにアップロードしたりできます。同様にNLPのモデルを[Hugging Face](https://huggingface.co/)からダウンロードしてElasticsearchにアップロードするためのCLIツール `eland_import_hub_model` もこのライブラリにバンドルされています。

最近この `eland_import_hub_model` を[日本語のモデルに対応させようと思ってコードに手を入れていたのですが](https://qiita.com/daixque/items/d77305e3ebf082126c58)、その際に変更したツールをローカルで動作させるための方法がわからなかったのでメモしておこうと思います。同様にVSCodeでデバッグ実行する方法についても記載します。

例題としてelandを取り上げていますが、基本的にPython一般の話です。


# PYTHONPATHを使った実行

まずはgithubからコードをcloneします。

```
$ git clone git@github.com:elastic/eland.git
```

完了したらcloneしてできたディレクトリで`bin/eland_import_hub_model`を実行すると、以下のような結果になります。

```sh
$ cd eland
$ bin/eland_import_hub_model -h
2023-05-03 10:44:51,912 ERROR : Failed to run because module 'eland' is not available.
```

カレントディレクトリにあるelandディレクトリ配下がモジュールパスとして認識されていないようです。Pythonにモジュールの探索パスを追加するには環境変数`PYTHONPATH`を使います。

```sh
$ export PYTHONPATH=.:$PYTHONPATH
$ bin/eland_import_hub_model -h
usage: eland_import_hub_model [-h] (--url URL | --cloud-id CLOUD_ID) --hub-model-id HUB_MODEL_ID [--es-model-id ES_MODEL_ID] [-u ES_USERNAME]
                              [-p ES_PASSWORD] [--es-api-key ES_API_KEY]
                              [--task-type {text_embedding,text_expansion,zero_shot_classification,pass_through,question_answering,ner,text_similarity,fill_mask,text_classification}]
                              [--quantize] [--start] [--clear-previous] [--insecure] [--ca-certs CA_CERTS]
...
```

エラーなく実行できました。これでコードを変更してもpip installなどをせずに実行できます。



# VSCodeからデバッグ実行する

コードを変更して動かしたりするときはなるべくデバッグ実行する環境が欲しいですね。今回はVSCodeで実行しようと思います。

コマンドラインから`eland_import_hub_model`を実行する場合は以下のような使い方になります。

```sh
eland_import_hub_model \
--url http://elastic:password@localhost:9200 \
--hub-model-id cl-tohoku/bert-base-japanese-v2 \
--task-type text_embedding \
--clear-previous \
--start
```

先述の環境変数を設定しつつ、このようなコマンド引数を与えて実行するには、VSCodeのlaunch.jsonに以下のように記載します。

```json
{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "import bert-base-japanese-v2",
      "type": "python",
      "request": "launch",
      "program": "${workspaceFolder}/bin/eland_import_hub_model",
      "console": "integratedTerminal",
      "justMyCode": true,
      "args": [
        "--url=http://elastic:password@localhost:9200",
        "--hub-model-id=cl-tohoku/bert-base-japanese-v2",
        "--task-type=text_embedding",
        "--clear-previous",
        "--start"
      ],
      "env": {
        "PYTHONPATH": ".:$PYTHONPATH"
      }
    }
  ]
}
```

見てわかる通り環境変数は`env`に、コマンド引数は`args`に素直に設定すればOKです。またプログラムの実行パスはトップディレクトリを`${workspaceFolder}`として指定できます。

そうするとVSCodeのビルドタブで実行のプルダウンに今設定した`import bert-base-japanese-v2`という構成が選択できるようになっているので、これを選んで実行するとブレイクポイントやステップ実行などが可能な状態で当該の`eland_import_hub_model`を実行できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2628554/2da00e3f-1945-9ef9-d932-bf4ba4e9d2ad.png)
Python自体がクラッシュしてしまう場合のデバッグの仕方

## TL;DR

`faulthandler.enable()` を使おう。これを実行した部分以降は、Python自体がクラッシュするような状況(=シグナルが飛んできた など) になると、スタックトレースが標準エラーに出力された上でクラッシュするようになる。

## 背景

macOSで `requests.get`を使うスクリプトをデーモン化したところ、何も出力せずにクラッシュするようになって困った。
タチの悪いことに、このクラッシュはデーモン化した時だけに起こる。

(環境は Python 3.11, macOS 12.6.5)

```python:crashes_if_daemonized.py
from daemon import DaemonContext
from daemon.pidfile import PIDLockFile
import requests
import time


pid = PIDLockFile(path.join(home_dir, 'pidfile_watcher'))
fp  = open("out.log", "a+")
fpe = open("err.log", "a+")

with DaemonContext(
  pidfile=pid,
  stdout=fp,
  stderr=fpe
):
  while True:
    response = requests.get("https://example.com");
    print(response.text)
    time.sleep(60*10)

fp.close()
fpe.close()
```

`print`をあっちゃこっちゃに仕込んだり"コンソール.app"を起動したりして１時間ほど調べまくった結果、どうやら`requests.get()` で ***Segmentation Fault*** していそうだということがわかった。

## なぜそんなに時間がかかったのか

`DaemonContext`に標準エラーの向き先を渡しているにもかかわらず、Python自体がクラッシュするような状況ではログが全く出力されなかったからである。
また、コンソール.appで見つけたクラッシュレポートは、自分でプログラムの全てを書いていない限り、あまり役に立たない。ここで「全て」とは、Pythonスクリプトに加えて使ったパッケージやPythonそのものも含まれてくる。クラッシュレポートは文字通り全てのコールスタックを出力する (= 情報が多すぎる) ので、よほどPythonそのものに関わっていなければ、何がどれに対応するのか解読するのは難しいだろう。

この時点では自分に残されたデバッグ方法は `print` を仕込みまくることだけだった。出力されなくなった`print`のタイミングがクラッシュのタイミングだ。
手動で二分法的に調査するなど多少の工夫はできるだろうが、最初自分は`DaemonContext`の`stdout`にファイルを指定しておらず、`print`の出力がロストするような状況だったため、結構面倒だった。

## 解決法

***`faulthandler.enable()`*** が正解だった。

https://docs.python.org/3/library/faulthandler.html

この関数を呼び出した後は、シグナルが飛んできた場合などのPython自体が異常終了する状況になった時、そのままクラッシュする前にスタックトレースを標準エラーに流してくれる。
(例えばmacOSでのSegmentation faultはSIGSEGVが飛ぶため、この関数の機能が発動する。)
この関数で、確実に「どこでクラッシュしたのか」を掴むことができた。

## ちなみに

先ほどのスクリプトのクラッシュはmacOSにおいて不可避らしい。  

https://github.com/python/cpython/issues/74570

回避するには、プロキシを使えなくする必要がある。どうやら、macOSのプロキシの設定を取得する機能が[「フォークに対して安全ではなく」、segmentaion faultを起こしてしまうらしい。](https://github.com/python/cpython/issues/74570#issuecomment-1093748531)

プロキシを使わないようにするには、環境変数 `no_proxy` に `*` を設定すれば良い。

```python:prevent_segv.py
import os
os.environ['no_proxy'] = "*"
```
[Unity] MacでFallbackしなかったシェーダーが、WindowsでFallbackする

# はじめに
こんにちは、ユーゴです。
今回は、ChatGPTに吐かせたコードでシェーダーを書いていた時に遭遇した問題を紹介します。

# 問題
Macで動作したシェーダーが、Windowsで動作しなくなる。

# 原因
### パターン1 : WindowsのGPUがざこざこ
単純に、GPUが該当するシェーダーの負荷に耐えきれない...みたいなことが起きているかもしれません。
ただ、マルチパスで条件分岐,ループ文乱用して...とかじゃないと普通発生しないのでは？と思います。私は違いました。

### パターン2 : 特定のレンダラーを除外している
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr"># pragma exclude_renderers d3d11<br>って書いただけでFallbackコースなんてあるのか...</p>&mdash; ユーゴ / xRエンジニア (@Yugo_dvlp) <a href="https://twitter.com/Yugo_dvlp/status/1653341063028051974?ref_src=twsrc%5Etfw">May 2, 2023</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
私はこれでした。
シェーダーのコード中に、以下のようなものが含まれていないか確認してください。

```hlsl
#pragma exclude_renderers d3d11
```

d3d11の部分は何でもいいです。
これは何かというと、特定のレンダラーだけコンパイルしないようにするということです。(あまり理解できていませんが...)

(公式リファレンス)
[頂点シェーダーとフラグメントシェーダーの記述](https://docs.unity3d.com/ja/2018.4/Manual/SL-ShaderPrograms.html)

# 解決策
### パターン1 : 設計を見直す
GPUが弱いPCで動くように、コードを書き換えるほかありません。もしくはGPUを強化するなど...

### パターン2 : 全てのレンダラーをコンパイルする
シンプルに、exclude_renderersの行を消してしまえばいいです。

```hlsl
//#pragma exclude_renderers d3d11
```

# まとめ
いかがだったでしょうか。今回は、ChatGPTを使ってコードを出力させた時に遭遇した問題と解決策を紹介しました。~~おのれChatGPTめ~~
シェーダーはビジュアルに隣接するからChatGPTにはまだ早い...と少し思いますが、GPT4になってからは少しマシになった気がします。これからに期待＆AIを駆使する側になれるように頑張らないといけませんね。
もしお役に立てたり気に入っていただけましたら、いいね・LGTM・フォローの方よろしくお願いいたします！
Koeiromapで音声変換器を作ってみた

# １、概要
　皆さんは、rinna株式会社が提供するテキスト読み上げソフトウェア「koeiromap」をご存じでしょうか。　設定を変えることで色々な音色で入力したテキストを読み上げてくれるソフトです。　今回は、「koeiromap」を使用して音声入力あるいはキー入力に対応した音声変換器を作成してみましたので紹介します。　なお、残念ながら２０２３年７月１８日をもって無料の Koeiro API サービスが終了とのことです。　本記事のデモは、無料の Koeiro API サービスを使用していますので、当該日以降は使用できなくなると思いますので悪しからず！

# ２、動作環境
　本音声変換器は、「HTML」と「Javascript」で作られており、動作環境は次の通りです。　なお、残念ながら「Safari」と「FireFox」には、対応していません。
- Browser: Microsoft Edge or Google Chrome on Windows10/11 and Android

# ３、デモ
[index.html](https://to-fujita.github.io/Voice_Converter_with_Koeiromap/index.html): Koeiromap 及び Koeiro API を使用した音声変換器です。
  
<a href="https://to-fujita.github.io/Voice_Converter_with_Koeiromap/index.html"><img src="https://to-fujita.github.io/Images/Voice_Converter_with_Koeiromap.jpg"></a>
  
<a href="https://to-fujita.github.io/Voice_Converter_with_Koeiromap/index.html"><img src="https://to-fujita.github.io/Images/Voice_Converter_with_Koeiromap-01.jpg"></a>

# ４、動作方法
## 4-1. 音声変換器の起動
　上記、「３、デモ」の「index.html」をクリックすると上記画面のように起動します。

## 4-2. 使用方法
- 「Message」欄に日本語テキストをキー入力し、エンター・キーを押すと入力されたテキストが読み上げられます。　また、赤い「音声入力OFF」ボタンをクリックし、「音声入力ON」に変更することで、音声入力で日本語テキストを入力出来ますので、簡易的な音声変換器として使用できます。
-  青い「音声変更」ボタンをクリックすることで変換する音色を設定することが出来ます。
-  「設定」⇒「OTHER OPTIONS」から変換した音声データを「Base64」テキストデータとしてローカルファイルに保存・読込することが出来ます。
-　入力されたテキストの長さによって、音声変換されるまでの時間が変わります。
-　使用方法については、「設定」⇒「INFORMATIONS」⇒「Manual」で詳細が表示されます。

## 4-3. プログラムについて
　本プログラムのソースコード一式を次のGITHUBに掲載しています。
-[To-Fujita/Voice_Converter_with_Koeiromap](https://github.com/To-Fujita/Voice_Converter_with_Koeiromap): 本プログラムのソース等

　なお、「Koeiromap」の使用に際しましては、@youtoy様の「[音声合成ができる「Koeiromap」の情報を調べてみて JavaScript を使って軽く試してみる【2023年4月8日時点】](https://qiita.com/youtoy/items/258ac8ed5313f64402a3)」を参考にさせて戴きました。ありがとうございました。

## 4-4. おまけ
　もし、英語でチャットボットと会話を楽しみたい方、あるいはVOICEVOXで音声変換や朗読や音声ドラマを楽しみたい方は、次の記事を参照ください。
- [ParlAIで英会話を楽しみませんか？](https://qiita.com/halboujp/items/342c88a7db17e07fe390)
- [VOICEVOXで音声変換器を作成してみた](https://qiita.com/halboujp/items/6d9abb47fd045d417250)
- [VOICEVOXで朗読や声劇（音声ドラマ）をさせてみた](https://qiita.com/halboujp/items/659327b6df92dc8c6c92)

　また、本プログラムは、単にオーム返しをしているだけですので、返答の部分をAI等からの返答に変えることで簡単にチャットボットになると思います。

# ５、履歴
- 2023/05/03: 初校
- 2023/05/06: 変換した音声データの保存・読込の機能を追加

# ６、Reference
- [Koeiromap【正式サービス化決定】](https://twitter.com/koeiromap): Twitterです。
- [koeiromap](http://koeiromap.rinna.jp/)： rinna株式会社が提供するテキスト読み上げソフトウェア
- [音声合成ができる「Koeiromap」の情報を調べてみて JavaScript を使って軽く試してみる【2023年4月8日時点】](https://qiita.com/youtoy/items/258ac8ed5313f64402a3)
- [To-Fujita/Voice_Converter_with_Koeiromap](https://github.com/To-Fujita/Voice_Converter_with_Koeiromap): 本プログラムのソース等
Qiitaなどで本文中の見出しにh1要素は使わずh2要素から始めたほうがいい

Qiitaなどで、本文中の見出しにh1要素は使わずh2要素から始めたほうがいいよね、という話です。
Qiitaに限らず、記事のような形態のコンテンツを扱うあらゆるプラットフォームに対しても、同じことが言えます。

## 本文中の見出しにh1要素を使わないほうがいい理由

Qiitaなどの記事ページでは、タイトルにh1要素が使われていることが多いです。

![スクリーンショット 2023-05-03 10.36.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132608/70fceb71-a5c0-9cca-eeaa-45ef92aabfa0.png)

そのような状況で本文中の見出しにh1要素を使うと、それらの見出しがタイトルと同じレベルになってしまいます。
これは、HTMLのセマンティクスに反しています。

https://developer.mozilla.org/ja/docs/Glossary/Semantics#html_%E3%81%A7%E3%81%AE%E3%82%BB%E3%83%9E%E3%83%B3%E3%83%86%E3%82%A3%E3%82%AF%E3%82%B9

また、MDNの見出し要素についてのページでも、1つのページには1つのh1要素を置くのが一般的であるとされています。

https://developer.mozilla.org/ja/docs/Web/HTML/Element/Heading_Elements#%E4%BD%BF%E7%94%A8%E4%B8%8A%E3%81%AE%E6%B3%A8%E6%84%8F

>1 つのページに複数の \<h1\> 要素を使用することは HTML 標準では認められていますが（入れ子でない限り）、これはベストプラクティスとはみなされません。1 つのページには、ページの内容を説明する 1 つの \<h1\> 要素（ドキュメントの \<title\> 要素と同様）を置くのが一般的です。

## どうすればいいのか

記事のタイトルにh1要素が使われている以上、本文中の見出しにはh2要素以下の見出し要素を使うべきでしょう。

```html
<h2>例</h2>
```

Markdownの場合は、`##`になります。

```md
## 例
```

エディタの書式バーで見出しを設定する場合も、h2要素に相当するものを選びましょう。
「見出し1」から並んでいるとついつい「見出し1」を使いたくなるかもしれませんが、そこはぐっとこらえて「見出し2」を使ってください。
ただし、「見出し1」がh2要素に相当する場合はその限りではありません。

## 各プラットフォームにおける扱い

参考までに、各プラットフォームにおける見出しの扱いを見てみましょう。

### Qiita

https://qiita.com/Qiita/items/c686397e4a0f4f11683d#headings---%E8%A6%8B%E5%87%BA%E3%81%97

QiitaではMarkdown記法がそのまま紹介されており、本文中の見出しにh1要素を使うことの是非については触れられていません。

### Zenn

https://zenn.dev/zenn/articles/markdown-guide

ZennではMarkdown記法としての`#`の存在は紹介しつつも、`##`から始めることが推奨されています。

### はてなブログ

https://help.hatenablog.com/entry/text-hatena-list

はてなブログで使えるはてな記法では、もっとも大きい「大見出し」がh3要素となっています。
それはそれでh1要素の次がいきなりh3要素になってしまうので、はてな記法ではなくHTMLやMarkdownで書いたほうがよさそうです。

### note

https://www.help-note.com/hc/ja/articles/360009035653

noteで使える見出しは「大見出し」と「小見出し」の2種類のみで、「大見出し」がh2要素、「小見出し」がh3要素となっています。
ユーザーにHTMLに関する知識がなくても、自然と正しいマークアップになるのがいいですね。

### Scrapbox

https://scrapbox.io/help-jp/%E8%A6%8B%E5%87%BA%E3%81%97

Markdownではなく独自記法を採用しているScrapboxには、そもそも見出しをつくる機能がありません。
これはこれで潔いですね。
交换电磁炉的工程

电磁炉交行工程完成。
1. 首先拆掉现在的电磁炉。
![6mMfkmBJhzTeFUzqrRoA8J4KaAY2/uVb3esnFNoGlP8gp.jpg](https://firebasestorage.googleapis.com:443/v0/b/type-c1c71.appspot.com/o/6mMfkmBJhzTeFUzqrRoA8J4KaAY2%2FuVb3esnFNoGlP8gp.jpg?alt=media&token=c137e839-3af4-4a80-b338-d325bd36ed49)
2. 把周围的垃圾打扫干净。
![6mMfkmBJhzTeFUzqrRoA8J4KaAY2/6AHZLo3Z9hKGrSX8.jpg](https://firebasestorage.googleapis.com:443/v0/b/type-c1c71.appspot.com/o/6mMfkmBJhzTeFUzqrRoA8J4KaAY2%2F6AHZLo3Z9hKGrSX8.jpg?alt=media&token=f5a4d04a-bbbe-4157-9e5b-25f524311664)
3. 新的电磁炉是这样子的。
![6mMfkmBJhzTeFUzqrRoA8J4KaAY2/McrJdtcT2VCAH3l8.jpg](https://firebasestorage.googleapis.com:443/v0/b/type-c1c71.appspot.com/o/6mMfkmBJhzTeFUzqrRoA8J4KaAY2%2FMcrJdtcT2VCAH3l8.jpg?alt=media&token=4f7c2f09-27f6-4f59-9c20-1440225aa6a7)
4. 安装完成。
![6mMfkmBJhzTeFUzqrRoA8J4KaAY2/RMj6A3Hmp7mfTcww.jpg](https://firebasestorage.googleapis.com:443/v0/b/type-c1c71.appspot.com/o/6mMfkmBJhzTeFUzqrRoA8J4KaAY2%2FRMj6A3Hmp7mfTcww.jpg?alt=media&token=30717054-c1ff-41d2-ab95-62b696700152)
5. 电源在下面，需要的时候插上就行了。
![6mMfkmBJhzTeFUzqrRoA8J4KaAY2/6MLGYkkPlJSAznd4.jpg](https://firebasestorage.googleapis.com:443/v0/b/type-c1c71.appspot.com/o/6mMfkmBJhzTeFUzqrRoA8J4KaAY2%2F6MLGYkkPlJSAznd4.jpg?alt=media&token=52357059-4990-4545-8a14-f4f8213266ab)
cscの作法 その311

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

# 練習問題
openaiのapiを叩け。

# 方針
- HttpClient使う
- LitJson使う

# サンプルコード

```
using System.Collections;
using System.IO;
using System;
using System.Text;
using LitJson;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;

namespace app
{
	class test0 {
		static void Main() {
			ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;
			string _url = "https://api.openai.com/v1/chat/completions";
			string _token = "sk-****";
			string json = "{\"model\": \"gpt-3.5-turbo\",\"messages\": [{\"role\": \"user\", \"content\": \"Hello!\"}]}";
			Console.WriteLine(json);
			var content = new StringContent(json, Encoding.UTF8, "application/json");
			HttpClient client = new HttpClient();
			client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", _token);
			var response = client.PostAsync(_url, content).Result;
			var responseString = response.Content.ReadAsStringAsync().Result;
			Console.WriteLine(responseString);
			LitJson.JsonData res = LitJson.JsonMapper.ToObject(responseString);
			Console.WriteLine(res["model"]);
			Console.WriteLine(res["choices"][0]["message"]["content"]);
		}
	}
}



```

# 実行結果

```
{
	"model": "gpt-3.5-turbo",
	"messages": [{"role": "user", "content": "Hello!"}]
}

{
	"id":"chatcmpl-7Bwbrz8oGrLXLufp18FeaSuaFtB22",
	"object":"chat.completion",
	"created":1683081259,
	"model":"gpt-3.5-turbo-0301",
	"usage":{
		"prompt_tokens":10,
		"completion_tokens":9,
		"total_tokens":19
	},
	"choices":[{
		"message":{
			"role":"assistant",
			"content":"Hello! How can I assist you today?"
		},
		"finish_reason":"stop",
		"index":0
	}]
}

gpt-3.5-turbo-0301
Hello there! How may I assist you today?
```


以上。
【SwiftUI】独自のColorを便利に綺麗に拡張する

SwiftUIにはデフォルトで`Color`がたくさん用意されていますが
独自で色々なカラーを作りたい場面は多いと思うので
**拡張性**を意識して実装してみたので紹介します

# とりあえず安直にextensionしてみる

はい、みんな大好き`extension`のお時間です。
まずは安直にやってみます。ここは終着点ではないです。

```swift
// ColorExtension.swift

extension Color {
    static var light_coral = Color(red: 240 / 255, green: 128 / 255, blue: 128 / 255)
}
```
`Color`を拡張して、`static`プロパティを定義します。
RGB指定で、好き放題色を拡張できます。

### 使うとこんな感じ
```swift
// ColorsView.swift

struct ColorsView: View {
    var body: some View {
        VStack(spacing: 20) {
            MyRectangle()
                .foregroundColor(.light_coral)
        }
    }
}

struct MyRectangle: View {
    var body: some View {
        Rectangle()
            .frame(width: 350, height: 100)
            .cornerRadius(10)
    }
}
```

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2633746/822d15f5-27c2-dcb4-a667-0f3f83fa67ae.png
" width="300">


# いや、もっと綺麗に書けるでしょ

上の実装だと何がめんどいかというと、RGB指定なので
**`red: 240 / 255`**　このように`255`で割って`Double`にしないといけない点です。
拡張したいColorが増えて来ると、毎回`255`で割るなんて面倒なので
もうひと工夫加えます。

# Colorのイニシャライザをextensionする
下記のように、新しくイニシャライザを拡張します。

```swift
// ColorExtension.swift

extension Color {
    init(
        _ red: Int,
        _ green: Int,
        _ blue: Int
    ) {
        self.init(
            red: Double(red) / 255,
            green: Double(green) / 255,
            blue: Double(blue) / 255
        )
    }
}
```
:::note
**Point**
・`Int`で受け取り、`Double`に変換して、`255`で割ってColorを初期化
・外部引数は`_`にすることで初期化時に引数ラベル不要

:::

### 何が嬉しいか
新しく作ったイニシャライザを使うことで
文字通り、**`/ 255`** しなくてよくなります。
このようにstaticプロパティが増えてきた時もすっきりと書けます。

```swift
// ColorExtension.swift

extension Color {
    static var light_coral = Color(240, 128, 128)
    static var slate_blue = Color(106, 90, 205)
    static var aquamarine = Color(127, 255, 212)
    static var light_green = Color(144, 238, 144)
    static var gold = Color(255, 215, 0)
    static var khaki = Color(240, 230, 140)
}
```

# 最終形態
```swift
// ColorsView.swift

struct ColorsView: View {
    var body: some View {
        VStack(spacing: 20) {
            MyRectangle()
                .foregroundColor(.light_coral)
            MyRectangle()
                .foregroundColor(.slate_blue)
            MyRectangle()
                .foregroundColor(.aquamarine)
            MyRectangle()
                .foregroundColor(.light_green)
            MyRectangle()
                .foregroundColor(.gold)
            MyRectangle()
                .foregroundColor(.khaki)
        }
    }
}

struct MyRectangle: View {
    var body: some View {
        Rectangle()
            .frame(width: 350, height: 100)
            .cornerRadius(10)
    }
}
```


<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2633746/7183b658-2877-a15e-b098-b76067a025ac.png
" width="300">

# おわりに
やっぱり`extension`っていいなあ。。。
JQueryメソッド（自分が使ったやつ）

よく使うとかではなく、ただ自分が使う機会があってわからなかったものを備忘録的に書き留めておきます。
### .data()
- jQueryの.data()メソッド
- HTML要素にdata-〇〇となっているデータを取得することができる

例
```html
<div id="myDiv" data-name="John" data-age="30"></div>
```

```javascript
var name = $('#myDiv').data('name');
var age = $('#myDiv').data('age');
```

### datepicker()
- jQuery UIの1つで、カレンダー形式の日付選択機能を提供する
- さまざまなオプションを指定して、様々なカスタマイズが可能

datepicker()を使用して日付選択機能を有効にする例
```html
<input type="text" id="datepicker">
```
```javascript
$(function() {
  $("#datepicker").datepicker();
});
```

### new Date()
- 現在の日時を含む新しいDateオブジェクトを作成
### .val()
- jQueryを使用してHTMLフォーム要素の値を取得または設定するためのメソッド
- 主にinput、select、textareaなどのフォーム要素に対して使用される

例
```javascript
var inputValue = $('input').val();
```

### $.isNumeric(num)
- 引数が数値かどうかを判定するために使用される
### .chosen()
### .on()
- jQueryのメソッドで、イベントハンドラーを設定するために使用される
※.on('change')
- 指定された要素の変更を監視し、変更が発生した際に登録されたイベントハンドラを呼び出す
例
```javascript
$("button").on("click", function() {
  console.log("ボタンがクリックされました");
});
```
### .prop()
- 要素のプロパティ[^1]を設定または取得するために使用される
- プロパティ（checked、disabled、selected、value、srcなど）の名前、値（オプション）を取る
[^1]:プロパティとは
要素の状態を表す値であり、DOM要素自体の情報を含む

例 : #myCheckboxというIDを持つチェックボックス要素のcheckedプロパティをtrueに設定
```javascript
$('#myCheckbox').prop('checked', true);
```
### .closest()
- 指定されたセレクターに最も近い祖先要素を取得するメソッド
- 指定された要素の祖先要素の中で、最も近いセレクターに一致する要素を取得することができる

.closest()メソッドの使用例
```html
<div>
  <ul>
    <li>
      <span class="target">Target</span>
    </li>
  </ul>
</div>

<script>
  $(document).ready(function(){
    var closestDiv = $('.target').closest('div');
    console.log(closestDiv); 
  });
</script>
```
.target要素の祖先要素の中で、最も近いdiv要素が取得される
### $.ajax()
- jQueryを使用して、Ajaxリクエストを送信するための機能を提供するメソッド
- ページの再読み込みなしでサーバーとやり取りすることができる
- 様々なオプションが用意されている

例
```javascript
$.ajax({
  url: 'example.php',
  method: 'POST',
  data: {
    username: 'John',
    password: 'Doe'
  }
});
```
※オプション
- dataプロパティは、 キーと値のペアの連想配列として提供される
### .done()
- $.ajax()メソッドを使用するときに使用される、Promiseのメソッドの1つ
- サーバーからのレスポンスが成功（ステータスコード200番台）であった場合,指定した関数を実行

### $.each()
- jQueryで使用される一般的な関数の一つ
- JavaScriptのforループと似たような機能を持っている

```javascript
var myObject = {
  name: 'John',
  age: 30,
  gender: 'male'
};

$.each(myObject, function(key, value) {
  console.log('キー:', key, ' 値:', value);
});
```
### .trigger()
- イベントハンドラが登録されている要素に対して、手動でイベントを発生させることができる

例
```javascript
$('#myButton').on('click', function() {
  alert('Button clicked!');
});

$('#myButton').trigger('click');
```
### .chosen()
- 検索可能なドロップダウンリストを実装するためのjQueryプラグイン
- セレクトボックスを装飾する
###
###
###
###

```javascript
```

```html
```
モジュールの中の型を参照するときにファイル名自体を含めない方法

# はじめに
Rust にはモジュールというプログラムをファイルやフォルダに分割して管理する仕組みがあります。
これを使うとプログラムをわかりやすく整理できるのですが、ある問題があります。
この記事ではその解決方法を示します。

# 開発環境
````
macOS Monterey(v12.5.1)
rustc 1.69.0 (84c898d65 2023-04-16)
````

# 問題
この記事で解決したい問題がどんなシチュエーションで発生するかをまず説明します。
以下のようにプロジェクトを用意します。
````sh
cargo new rsmodule
````

この時点では以下のようなファイル構造になっているはずです。
* rsmodule
    * src
        * main.rs

main.rsを以下の様に書き換えます。
この時点ではモジュールを分割していないので、何の問題もなく `main.rs` から `MyStruct` を参照できます。
````rs
struct MyStruct {
    name: String
}

fn main() {
    let myStr = MyStruct { name: String::from("desktopgame") };
    println!("my name is {}.", myStr.name);
}
````

次に、 `my_module` というモジュールを作成してそこに `MyStruct` を移動させます。
以下の様なファイル構造となります。
* rsmodule
    * src
        * my_module
            * my_struct.rs
        * my_module.rs
        * main.rs

`my_struct.rs` では構造体を宣言します。
````rs
pub struct MyStruct {
    pub name: String
}
````

そして `my_module.rs` から `my_struct.rs` を参照させます。
````rs
pub mod my_struct;
````

すると、`main.rs`から以下の様に参照できるはずです。
````rs
mod my_module;

fn main() {
    let myStr = my_module::my_struct::MyStruct { name: String::from("desktopgame") };
    println!("my name is {}.", myStr.name);
}
````

これでは少々冗長です。そこで以下の様に書き換えることができます。
````rs
mod my_module;
use my_module::my_struct::MyStruct;

fn main() {
    let myStr = MyStruct { name: String::from("desktopgame") };
    println!("my name is {}.", myStr.name);
}
````

しかしこれも私のやりたいこととは違っています。
私としては `my_module::MyStruct` として参照させたいのです。

そこで `pub use` を使った方法を紹介します。

# 解決方法
`my_module.rs` を以下の様に書き換えます。
````rs
mod my_struct;
pub use my_struct::MyStruct;
````

これで `main.rs` からは以下の様に参照できます。
````rs
mod my_module;

fn main() {
    let myStr = my_module::MyStruct { name: String::from("desktopgame") };
    println!("my name is {}.", myStr.name);
}
````

この書き方だと、 `my_module::my_struct::MyStruct` としての参照はできなくなります。
`my_module.rs` で `pub mod` として宣言していないからです。

# ネストしたい場合
`my_module` の下にさらに `sub_module` というモジュールを生やしたいとします。
ファイル構造は以下の様になります。
* rsmodule
    * src
        * my_module
            * sub_module
                * sub_struct.rs
            * sub_module.rs
            * my_struct.rs
        * my_module.rs
        * main.rs

`sub_struct.rs` での型宣言は先ほどと同じです。
````rs
pub struct SubStruct {
    pub name: String
}
````

`sub_module.rs` から `sub_struct.rs` を参照します。
これも先ほどと同様です。
````rs
mod sub_struct;
pub use sub_struct::SubStruct;
````

最後に `my_module` から `sub_module` を `pub mod` で参照させます。
````rs
mod my_struct;
pub use my_struct::MyStruct;

pub mod sub_module;
````

すると `main.rs` からは `my_module::sub_module::SubStruct` として参照できます。
````rs
mod my_module;

fn main() {
    let myStr = my_module::MyStruct { name: String::from("desktopgame") };
    println!("my name is {}.", myStr.name);

    let myStr2 = my_module::sub_module::SubStruct { name: String::from("desktopgame") };
    println!("my name is {}.", myStr2.name);
}
````
Ruby：「Hash.new()」「Hash.new(0)」について


# `Hash.new()`
Hash.new()で作成されたハッシュは、存在しないキーが指定されるとnilが返されます。
```ruby
hash1 = Hash.new()
hash1["apple"] = 3
hash1["banana"] = 2

puts hash1["apple"]   # 3が出力されます
puts hash1["banana"]  # 2が出力されます
puts hash1["orange"]  # nilが出力されます
```

# `Hash.new(0)`
Hash.new(0)で作成されたハッシュは、存在しないキーが指定されるとデフォルト値である0が返されます。
```ruby
hash2 = Hash.new(0)
hash2["apple"] = 3
hash2["banana"] = 2

puts hash2["apple"]   # 3が出力されます
puts hash2["banana"]  # 2が出力されます
puts hash2["orange"]  # 0が出力されます
```

# `Hash.new()`と`Hash.new(0)`の違い
存在しないキーにアクセスしたときに返される値（デフォルト値）が異なります。Hash.new()の場合、デフォルト値はnilですが、Hash.new(0)の場合、デフォルト値は0です。

# `Hash.new(0)`を利用するメリット
このコードでは、ハッシュの値をカウントしています。`Hash.new(0)`を利用することで、存在しないキーにアクセスしたときに返される値が0になるため、ハッシュの値をカウントするような場合に便利です。`Hash.new()`を利用することで、"apple","banana"キーが存在しないため、``undefined method `+' for nil:NilClass (NoMethodError)``のエラーになります。
```ruby
# Hash.new(0)を利用するメリット
hash = Hash.new(0)
hash["apple"] += 1
hash["banana"] += 1
hash["apple"] += 1
puts hash["apple"]   # 2が出力されます
puts hash["banana"]  # 1が出力されます
puts hash["orange"]  # 0が出力されます

# Hash.new()の場合
hash = Hash.new()
hash["apple"] += 1 # undefined method `+' for nil:NilClass (NoMethodError)
hash["banana"] += 1 # undefined method `+' for nil:NilClass (NoMethodError)
```
Docker Desktop→Docker-CE→Rancher Desktopと乗り換えた

元々WindowsでDocker Desktopを使っていたのですがライセンス変更に伴って代替製品を探していました。

## Docker-CE

まずは素朴にWSL2でUbuntuを動かしてその上でDocker-CEを利用しましたがいくつか不満がありました。

#### セットアップが少し長い
WSUS環境下のためUbuntuがそのままでは入らないなど環境的事情もありましたが、
セットアップ手順が少し長く、その分ハマりどころもあった印象です。

#### host.docker.internalが使いづらい
リモートデバッグのために使いたかったのですがデフォルトでは対応していません。
`--add-host=host.docker.internal:host-gateway`を指定しても参照先がWSLのUbuntuになるので
Windowsに繋げたい時にはそこにWindowsのローカルIPを指定しなければならなかったりします。

#### WSLのレイヤを強く意識してしまう
理解する上では良いことなんですが、普段使いしはじめるとWSLのレイヤに手を取られるのが煩わしく感じます。


これらの点で他人には勧めづらいなと感じるとともにDocker Desktopの完成度の高さを改めて認識しました。

## Rancher Desktop

次にRancher Desktopを使ってみたところ上記の不満が解消していました。

Docker Desktopに比べコンテナ一覧画面が無いなど物足りない部分はありますが、そこは今後のバージョンアップに期待です。

WindowsでDocker始めるなら「Docker Desktop」か「Rancher Desktop」の二択だろうという所感です。
Power Virtual AgentからOpenAIに考えてもらった文章でメールする

### はじめに

以前[Power Virtual Agents経由でOutlookでメールを送信しました](https://qiita.com/k-kimino/items/ff4975e6d1bfe9039951)。今回は発展としてOpenAIにメールの本文を考えてもらいます。

### 注意

前回まではM365に含まれる範囲でPower Virtual Agentsを活用していたのですが、今回の記事ではプレミアムコネクタを使用するため、Power Virtual Agentsのサブスクリプションが必要になります。機能比較は[Microsoftドキュメントをご参考ください](https://learn.microsoft.com/ja-jp/power-virtual-agents/requirements-licensing-subscriptions)。

### 実際にやってみる
#### OpenAIのAPI Keyを取得する

OpenAIのAPI Keyが必要となりますので、[OpenAI](https://platform.openai.com/overview)にログインし、API Keyを取得しておきます。Keyは絶対に他人に公開しないように保管しておく必要があります。
![APIkey.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3322105/f0e9af8f-098a-3ac7-0081-0a77b85115f2.png)

ここでポイントは、フリートライアルで$18あるのですが2023/05/02時点で試したところカード登録なしで実行すると429（スロットリング）が発生しました。現状利用が制限されているようです。カード情報も登録すると回避できると思いますが、費用が発生するところなので利用規約を読むなど個人の責任でお願いします。

なおリミットを設定できるため設定しておくと安心です。
![Limit.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3322105/7d90ec82-2e8b-1154-8877-0a0b654d783e.png)


#### Power AutomateでOpenAIのAPIを呼び出す

作成したフローはこちらです。
![openAI1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3322105/0a420fd0-303c-7e35-bb24-3536199c25cd.png)
![openAI2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3322105/56dc925b-07c1-332b-70b6-c07df169db34.png)
![openAI3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3322105/59a3593d-eae4-7f82-c484-3572ed41edc6.png)

JSON for the schema definition
```
{
    "type": "object",
    "properties": {
        "text": {
            "type": "string"
        },
        "index": {
            "type": "integer"
        },
        "finish_reason": {
            "type": "string"
        }
    }
}
```


使いこなせていないのもあってやってることはシンプルで、Power Virtual Agentからもらった入力をプロンプトとしてDaVinciエンジンに投げ、返ってきた結果をまたPower Virtual Agentに渡しているだけです。

ポイントは、OpenAIのAPIからどんな形でアウトプットが入手できるか理解していないとその後のフローが書けない点です。
これは実際のOpenAIからのレスポンスを見ると話が早いのですが、choicesのtextに求めている本文がJSON形式で返ってきているのが分かります。
[公式ドキュメント](https://platform.openai.com/docs/api-reference/completions)だともっと詳しく理解できます。
![GPToutput.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3322105/26139fe8-d28c-4b14-094c-9a4a696795d6.png)

#### Power Virtual AgentにOpenAIのフローを組み込んで強化する

チャットの内容をメールの本文として送付するところまでは前回と同じなので省略します。今回はその本文を先ほどのOpenAIフローを使ってより高度にしました。自然言語で適当な作文命令をしてあげるとまあまあ良さげな文章で返してくれました。

![PVA1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3322105/714ee460-1aa1-82d1-6cae-a41eb9e695be.png)
![Outlook.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3322105/b70bbf0c-e349-f9c9-1cdc-bb0cdfa12183.png)

### まとめ

Power Virtual AgentsをインタフェースにOpenAIに作文をお願いし、Power Automateでその内容を踏まえてメールの送信をしてもらいました。セキュリティとかコンプライアンスのことは考えていないので業務利用などは注意する必要がありますが、ノーコード恐るべしです。とりあえず動かしてみたという感じなのでプロンプトやら使い道やら広げていきたいです。

### 参考
- [Connecting OpenAI to Power Virtual Agent in 10 minutes](https://www.linkedin.com/pulse/connecting-openai-power-virtual-agent-10-minutes-r%C3%A9mi-dyon/)
- [すぐに始めるchatGPT API①まずはPower Automate で呼び出してみる](https://qiita.com/Satoshi_Yoshino/items/b4fc4a74265069fdf109)
[Action Required] Rotate Login with Amazon credentials (Client Secret)

# 発端
Amazon Services API Developer Compliance Teamから、メールが届いた。
「[Action Required] Rotate Login with Amazon credentials (Client Secret)」


去年必死に対応していた、SP-API。
もう１年経つんですね。
今は使えますが、なにかを更新しろと言われているようなので調査を開始しました。

## 詳細については
> Amazon Services API ドキュメントの「アプリケーションの LWA 資格情報のローテーション」を参照してください。
https://developer-docs.amazon.com/sp-api/docs/rotating-your-apps-lwa-credentials


# AWSからの案内
メールは英文で来ているので、翻訳にかけます。
一部抜粋するとこんな感じ。

> Login with Amazon (LWA) の資格情報 (クライアント シークレット) をローテーションするのに残り 30 日あります。
180 日ごとに LWA クレデンシャルのローテーションを要求することで、API 開発者とその顧客にサービスを提供します。 2023 年 5 月 22 日までにローテーションを行わないと、アクセス権が失われ、API 呼び出しを行うことができなくなります。
> 
> 注: 資格情報のローテーションは、エンド ユーザーには影響しません。アプリケーションを再承認する必要はありません。


…？？？

API開発者のほうで何かするような指示でしょうか…？
ひとまず、AWSにログインしてあちこち見てみます。

開発が終わり、監視も終わったので
すっかり操作しなくなっていたのもあって…
…あと、以前もよくわからないまま、必死に使ってたので、
実はどこに何が出ているか、よくわからないという😅

# 対応したこと
あちこち触った結果、私の場合、対応が必要なのは、セラーセントラルのデベロッパーセントラルだったようです。


セラーセントラル＞アプリとサービス＞アプリの開発
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2627227/c4a369f4-65f0-a27f-4889-e9d4246b96ef.png)

デベロッパーセントラル
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2627227/fbe24b6e-9f72-582a-b4e6-b90eace9bdee.png)



たしかに、LWA認証情報列に警告マークが出ていました。

1. 既存シークレットを控える
1. 「表示」クリック
1. 「資格情報のローテーション」クリック
1. 再度「資格情報のローテーション」クリック
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2627227/236757a7-36e0-0ba2-2fb3-57b3af24f366.png)

この手順で完了するようです。

参考：表示をクリックして出てくるLWA認証情報のクライアント機密情報に、ローテーション期限が出ますが、そこが延びてました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2627227/da2ebd07-9f99-b57c-fe4b-642bfd562171.png)


# 注意事項
このIDでSP-APIを呼び出しているアプリにおいて、クライアント機密情報を設定しているはずなので、その変更が必要です。


以上。
Twitter→Misskeyへ自動クロスポストする方法

# IFTTTでTwitter→Misskeyへ自動クロスポストする方法

## このドキュメントは

IFTTTを使って、Twitterで呟いたツイートを自動でMisskey.ioにもノートする方法の忘備録です。

## 注意

Fediverseではマルチポストを特に規制してはいません。しかし、必ず以下の点に考慮するべきとしています。

* クロスポスト先で脈絡のないノートが投稿される点に留意する。
* メインプラットフォーム(特にTwitterのツイートへのリンク)を避ける。
* TwitterでのRTをFediverse側(Misskey側)に投稿しない設定にする。
* URL短縮サービスは使用しない。

参考

* [ベストプラクティス - Join the Fediverse](https://joinfediverse.wiki/Best_practices/ja)

## 必要なもの

* Misskey.ioのアカウント
* Twitterのアカウント
* IFTTTのアカウント

## 方法

1. Misskey.ioでAPIアクセストークンを取得する

   [Misskey API | Misskey Hub](https://misskey-hub.net/docs/api/)

   上記を参考に、Misskey APIアクセストークンを取得します。
   具体的には
   1. Misskey.ioのホーム画面の左パネルの設定→その他の設定欄の"API"を選択
   2. "アクセストークンの発行"ボタンを押す
   3. 適切な名前をつける。例えば「Twitter連携用」など(つけなくても可)
   4. 権限は"ノートを作成・削除する"を選択
   5. **表示される確認コードを控える**

   確認コードがアクセストークンとなります。

2. IFTTTでAppletを作成する
   1. IFTTTにログインし、右上の`Create`をクリック
   2. `If This`のAddボタンを押し、`Twitter`を検索して選択
   3. `New Tweet by you`を選択
   4. TwitterアカウントとIFTTTアカウントの連係がまだの場合は、ここでTwitterアカウントを追加
   5. Fediverse利用上のベストプラクティスを踏まえ、`Include`欄の**retweets, @repliesにはチェックを入れない**
   6. `Create trigger`を押す
   7. `Then That`には、`Webhooks`を検索し選択
   8. `Make a web request`を押す
   9. `URL`には`https://misskey.io/api/notes/create`を入力
   10. `Method`は`POST`を選択
   11. `Content Type`は`application/json`を選択
   12. `Body`欄に以下のように入力

       ```json
       {
        "i" : "1-5で得たアクセストークン",
        "text" : 
       }
       ```

       アクセストークンは"で囲むのを忘れないで下さい。

   13. `Add ingredient`を押し、`Text`を選ぶ
   14. 最終的に`Body`欄が以下のようになればOK

       ```json
       {
        "i" : "1-5で得たアクセストークン",
        "text" : {{Text}}
       }
       ```

   15. `Create action`を押す

これで、作成したAppletが有効であれば、Twitterでツイートした際に、ツイートの`{{Text}}`に該当する部分、即ちツイート本文がMisskey.ioにも投稿されます。

IFTTTの仕様上、常に同時にとはいかず、数分おきに新規ツイートがないか確認され、あればMisskey側にも送られます。

また、IFTTT側のサーバー負荷などにより、確認が失敗する場合もあります。

## おわりに

再三の注意となりますが、場合によってはMisskey.io側へ脈絡を無視したノートが投稿されることになります。このことを常に意識しましょう。

状況を鑑みて、連携を外すことも常に選択肢に含めてください。

## 参考文献

* [Misskeyで、Twitterのツイートをノートする - Qiita](https://qiita.com/Skota11/items/81066ae65d335b5bd02e)
GASでキーワード検索結果からURLの取得エラーcode 429

 https://www.google.com returned code 429. Truncated server response: ＜!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"＞
===
実行してみると、エラーが出力されました。
エラー文を見てみると、「code 429」が返ってきました。

内容は「https://www.google.co.jp のリクエストが失敗し、コード 429 が返されました。」というものです。

「エラーコード 429」は、リクエスト数が超えた
---
アクセスが多すぎてスパムと勘違いされたようです…

２４時間以内でアクセスできる数が決まっているので、次の日まで待ちましょう。
チェビシェフリンク機構のシミュレータ

# はじめに

チェビシェフリンクは主にロボットの歩行に使われる、擬似直線を作り出すリンク機構です。かんたんな機構で歩行しているような軌跡を描くので、色々応用できます。

これは私がレゴで作った、リモコン式ロボット。

https://twitter.com/nisshan_/status/1590168911655600129

歩行しているかのような軌跡を描くには、最適なリンクの長さがあります。「この長さを変えたらどうなるか？」という疑問は沸かないですか。このリンク機構を物理的に作れば試せますが、加工しないといけないので、長さの変更は容易ではありません。でも、簡単に試してみたいですね。

# シミュレータ

pythonでチェビシェフリンクのシミュレータを作りました。

https://github.com/nisshan-x/ChebyshevLinkageSimulator

# 説明(使い方、特徴)

* 起動方法はreadmeを参照してください。
* 起動時のデフォルトでは「歩行に最適なリンクの長さ」になっています。
* 5つのスライダーを操作すると、長さが変わります。
* Resetボタンを押すと、デフォルトの長さに戻ります。
* Randomizeボタンを押すと、全リンクの長さがランダムにセットされます。
* リンク機構として物理的に成り立たない長さの場合、計算が破綻します。そのとき、画面がピンクになります。
* 画面真ん中右の文字は、先端Dの位置の分析です。
    * x軸方向の最小値、最大値、その変化量(=歩幅)
    * y軸方向の最小値、最大値、その変化量(=足を上げる高さ)
    * y/xの変化量の比率

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/630585/5b20d236-2b5f-1721-206d-964f5ae92729.png)

https://twitter.com/nisshan_/status/1653362053887967233

https://twitter.com/nisshan_/status/1653366649968562178

# 参考

* [Chebyshev linkage - Wikipedia - ](https://en.wikipedia.org/wiki/Chebyshev_linkage)
* [Chebyshev lambda linkage - Wikipedia](https://en.wikipedia.org/wiki/Chebyshev_lambda_linkage)
* [チェビシェフリンク機構 | からくりすと](http://karakurist.jp/?p=52)
* [円と直線の交点を求める - Qiita](https://qiita.com/tydesign/items/36b42465b3f5086bd0c5)
* [点と直線の距離 - Qiita](https://qiita.com/tydesign/items/cf471b7bc1357e72c6e7)
* [【高校数学Ⅱ】定点を通る円、2円の交点を通る直線と円（円束） | 受験の月](https://examist.jp/mathematics/figure-circle/ensoku/)
* [Hyrodium laboratory: Tchebicheff Link](http://hylab.blogspot.com/2012/12/tchebicheff-link.html)
* pythonで分からないことはChatGPTに教えてもらった
ブラウザを利用して不要なセレクタを見つける。

# はじめに
はじめましてKonbuGXと申します。
ブラウザの開発者ツールのカバレッジを利用すれば
Webページ内の利用している・していないセレクタがわかります。
そのため、cssファイルの不要なセレクタを削除し
ファイルサイズを小さくすることができます。
利用方法を下記に記載いたします。

## 1.ブラウザでWebページを表示
　対象となるページをブラウザに表示させます。

## 2.開発者ツールを表示
　対象となるページで開発者ツールを表示します。
　Windowsだと「F12」もしくは「ctr + shift + I」で表示し
　Macだと「Commnd + Option + I」で表示します。
　すると下記のようなものが開きます。
  ![開発者ツール_編集.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/389845/da40e531-359f-3549-08aa-faf3e8275597.png)


## 3.開発者ツールから「カバレッジ」を選択
　開発者ツール上部から「︙」->「その他のツール」->「カバレッジ」と
　選択してカバレッジを表示させます。
　![開発者ツール2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/389845/17496554-759e-8a96-47fe-2b18fc28d833.png)

## 4.「カバレッジ」の●を押下
　「カバレッジ」の●を押下すると下記のように利用しているcssファイルが表示されます。
　「利用状況の可視化」の赤いバーは未使用で青いバーは使用中の量です
　　![カバレッジ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/389845/fdcee10c-6119-e1ad-1e49-6d7f0afab7ce.png)

## 5.「カバレッジ」のタイプが「CSS」の行を選択
　「カバレッジ」のタイプが「CSS」の行を選択します。
　すると、使用・未使用のバーが表示されているCSSファイルの内容が表示されます。
　これで不要なセレクタを見つけることができます。
　![開発者ツール3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/389845/4df0fb64-f1cf-6334-d1dc-0fbe9365f74f.png)

## 注意点
　**・使用、未使用のセレクタがわかるのは表示されているWebページのみ**
　　使用、未使用のセレクタがわかるのは表示されているWebページのみです。
　　別のhtmlファイルでは使用しているが表示されているWebページで
　　使用していない場合では未使用と判定されます。
　　なので、cssファイルを利用しているhtmlファイルをすべて表示し
　　削除していいセレクタかどうか見極める必要があります。

　**・使用、未使用の判定は正確ではない**
　　コメントや「＠media()」など消したくないものまで未使用と
　　判定されるので消していいのかどうか確認する必要があります。

## 感想
　業務で触るcssファイルは膨大な量なので
　そこから不要なセレクタを見つけるのを手作業では絶対したくないです。
　なので、完全ではないものの使用・未使用のセレクタがすぐわかるのは
　楽で良いと思いました。