OmniAICreator/Qiita-1.07M huggingface dataset:
Twitterリンクをvxtweetドメインに変換するBotを作ってみた

※初投稿です。
少しバージョンアップしました。最新版は[こちら](https://qiita.com/nisinosora/items/52ad3941bc473f4e8a27 "Twitterリンクをvxtweetドメインに変換するBotを作ってみた2")

タイトルの通りなのですが、画像の通りDiscordにTwitter（ツイート・ポスト）リンクを貼ると
自動的にvxtwitterのドメインに変換するBotです。
現状、どれぐらいの負荷レベルに耐えられるかが検証できていないため、
身内用のBotとして運用する予定です。
ある程度検証が完了したら、自分が参加していないサーバでもご利用いただけるようにするかもしれません。

![68747470733a2f2f71696974612d696d6167652d73746f72652e73332e61702d6e6f727468656173742d312e616d617a6f6e6177732e636f6d2f302f3538333732362f65646237303532302d333863642d363131312d633735332d3764616232356163353230322e706e67.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/583726/7bc6494d-72ef-37de-8f87-003cb0b8491a.png)

ただ、それだけです。

なお、文字装飾にも対応しています。
![68747470733a2f2f71696974612d696d6167652d73746f72652e73332e61702d6e6f727468656173742d312e616d617a6f6e6177732e636f6d2f302f3538333732362f31343361613432372d306664662d643564652d633838392d366163663237363431346235.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/583726/4e206efd-8f2e-b460-7571-50cb67a9adb3.png)
![68747470733a2f2f71696974612d696d6167652d73746f72652e73332e61702d6e6f727468656173742d312e616d617a6f6e6177732e636f6d2f302f3538333732362f38656239356136362d653164652d623133372d646437642d613739343964333230646233.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/583726/18f1eab8-9903-e349-b524-fbac287a8783.png)
![68747470733a2f2f71696974612d696d6167652d73746f72652e73332e61702d6e6f727468656173742d312e616d617a6f6e6177732e636f6d2f302f3538333732362f66383733653038642d663537332d373062312d333738302d313036343665363162356466.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/583726/6646de1d-2825-a73f-2e60-90f09e80dbbf.png)



ただし、以下のような書き方には対応していません。
\`\`\`
文字列
リンク
文字列
\`\`\`
![68747470733a2f2f71696974612d696d6167652d73746f72652e73332e61702d6e6f727468656173742d312e616d617a6f6e6177732e636f6d2f302f3538333732362f34373532656664382d393963352d393539652d396363662d633139333862303034666430.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/583726/af1a46f1-29ab-f07e-7e18-ce1e7abba467.png)


使い方は簡単。
メッセージチャンネルに、Twitter（ツイート・ポスト）リンクを貼るだけです。
上記の通り多少の文字装飾には対応しているので、文字装飾を使ってもらっても構いません。

特定チャンネルへの送信を停止したい場合は、
各チャンネルのこちらのBotに対する権限設定で「チャンネルを見る」権限を解除すれば、
変換後のメッセージを送信しなくなります。

以上です。
OAuth 2.0 Authorization Errors



+ [OAuth 2.0 Authorization Errors](https://help.salesforce.com/s/articleView?id=sf.remoteaccess_oauth_flow_errors.htm&type=5)


+ [Implement the OAuth 2.0 Web Server Flow Challange](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007BF8vf)

:::note alert
Something is wron

HTTP/1.1 302 Found

Location:https://cunning-moose-dpnazc-dev-ed.my.salesforce.com/services/oauth2/authorize?client_id=3MVG9n_HvETGhr3Bkj.pJ.50EaJZuVCRJU.olDrd7kShRc23A0hLJyWRBQ3qg8dYYE9u2hKJKl8kHF_0AT1PK&redirect_uri=https%3A%2F%2Fopenidconnect.herokuapp.com%2Fcallback&response_type=code&state=al03rcfbp4d0rcjjcn33lljus


Passing Proper URL, Client Id and Secret
:::

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/e51d0ac2-1a76-c7ed-7497-03973097e973.png)

:::note
I was getting the same error and unchecked this option in the connected app settings and is working fine now.
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/1143a0f8-5e01-1098-2805-1a65e8263608.png)
:::

+ [This site can't be reached](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007T4xRa)

:::note
I noticed that if I copied the URL of my Playground eg. https://brave-shark-7br2i9-dev-ed.trailblaze.lightning.force.com/ I got a error in the OpenID Connect Tool

However if I went to the My Domain Page and used this to generate the full URL https://

brave-shark-7br2i9-dev-ed.trailblaze.my.salesforce.com then it was able to connect to my org and generate a token as requested
:::

本当のURLがmy.salesforce.comになっているのは注意ですね。Postmanでも遭遇しました。

```
https://brave-shark-7br2i9-dev-ed.trailblaze.lightning.force.com/
https://brave-shark-7br2i9-dev-ed.trailblaze.my.salesforce.com/
```

+ [Something is wrong error coming in Open Id Connect.](https://trailhead.salesforce.com/trailblazer-community/feed/0D5KX00000KDPaX)

:::note
Make sure if you finished this Challenge on the same Playground. 
:::
JOOQで、UPDATE時、非NULL属性のみ更新する(CASE WHEN)

# 環境
| 名称 | バージョン |
|:-:|:-:|
| JOOQ | 3.18.6 |

# 問題
掲題の書き方がパッとわからなかった。
DB上の値を検証する方法は[公式ドキュメント](https://www.jooq.org/doc/3.9/manual/sql-building/column-expressions/case-expressions/)にあったけれど、ブラウザから受け取った値の検証をするコーディングに時間がかかった。

# 解決方法
priceが非NULL属性の時のみ更新する場合の例
```TestRepository.java
Product p = PRODUCT.as("p");
int resultCnt = dsl.update(p)
    .set(p.PRODUCT_NAME, form.getProductName())
    .set(p.PRICE, DSL
        // NULLになっている項目は更新除外
        .when(DSL.val((Object) form.getPrice()).isNotNull(), form.getPrice())
        .otherwise(p.PRICE))
    .where(p.PRODUCT_CODE.eq(form.getProductCode()))
    .execute();
```
# 最後に
* whenはorg.jooq.impl.DSLを使用する。
[公式ドキュメント](https://www.jooq.org/doc/3.9/manual/sql-building/column-expressions/case-expressions/)の例では記載が無かったから、すぐにわからなかった。
* whenの第1引数はConditionだが、JavaのisNull()はbooleanで戻ってくるので、型をどう合わせるかがすぐにわからなかった。
* 日頃は役立たずと思っているのだが、今回は[公式の変換ツール](https://www.jooq.org/translate/)が役に立った。

# 参考
https://rennnosukesann.hatenablog.com/entry/2018/03/02/215120
エクセルの起動が遅い場合の対応

# 現象

1～2秒ほどで開くはずのxlsxファイルなのに、開くときに15秒～30秒ほどかかる。
ファイルサイズも130KBほどでVBAとマクロも無く軽いxlsxで発生する。
『特定のxlsxファイルだけで発生』ではなく、どんなエクセルファイルを開く時も体感でエクセルの起動が遅い。

# 対応

:::note warn
『根本の原因は分からないけどこれやったら改善した』レベルなので参考情報として見て下さい。
:::
:::note warn
『自動回復用ファイルを削除してよいかどうか』は個々の状況によって変わるので注意。
:::

『ファイル』。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/2a8491f8-6938-5530-52d7-5e397387a72a.png)

『オプション』。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/8cdbe306-bf22-af9d-3bdf-294252680178.png)

『保存』『自動回復用ファイルの場所』。
このフォルダーの中身を全て消したら起動早くなりました。
消す時はエクセルを終了し、エクセルファイルを全く開いていない状態で行いました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/aa59fc6e-3c21-8729-3057-ab696dae4aee.png)

# 独自テンプレートの誤削除に注意

下記フォルダーには『エクセル起動時に開くテンプレートファイル』が置かれている場合があります。

```
C:\Users\%username%\AppData\Roaming\Microsoft\Excel\XLSTART
```

あたいの場合はフォルダー丸ごと消してしまったので、テンプレートファイルを作り直すはめに…。

# 参考サイトさん

https://dekiru.net/article/23082/


# バージョン

Microsoft Windows [Version 10.0.19045.3570]
Microsoft Excel for Microsoft 365 MSO (バージョン 2309 ビルド 16.0.16827.20166) 32 ビット
【 TypeScript 】文字列リテラル型と文字列型のユニオン型を作成する

Typescriptで型を作成するときに、'dog' や 'cat' のような特定の文字列をリテラル型として指定しつつ、その他の文字列型も含める方法について考えます。

単純に次のような型を考えてみましょう。

```ts
type AnimalWithString = 'dog' | 'cat' | string
// type Animal = string
```

この場合、`Animal`の型情報は`type Animal = string`となってしまい、`dog` や `cat` の情報が失われてしまいます。これでは役に立ちません。

`string`を取り除いてみます。

```ts
type Animal = 'dog' | 'cat'
// type Animal = "dog" | "cat"
const myAnimal:Animal = 'bird'
//Type '"bird"' is not assignable to type 'Animal'.(2322)
```

これだとただのリテラル型のユニオンになってしまい、`bird`といった他の文字列を受け入れられません。

そこでテクニックを1つ使います。

`string`のかわりに`(string & {})`を使用します。

```ts
type AnimalSpecified = 'dog' | 'cat' | (string & {})
// type AnimalSpecified = "dog" | "cat" | (string & {})
const animalIncludingMightBe:AnimalSpecified = 'bird'
```

これで`dog` や `cat` を維持したまま、string型の情報も提供されるので、文字列リテラル型と文字列型のユニオン型の両方をもった型を作成できたことになります。

[TS Playground](https://www.typescriptlang.org/play?#code/C4TwDgpgBAggdgSwLYEMA2B1BwAWBlYAJwTgHMoBeKAcgBMB7U6qAHxoGMVhm2BnIkqQBQAehFRQkWIlSZs+AWUpR+xMkKGTo8ZOmV1GPDl2qiRW6brTKARA1I3WUG52A2h7enH5QkIHbIAXAF6VNQARgiEtKaa4Noy6HiQ7AgAZggQtPr2RtSuRgAUqoJQAGRQAN4AvgCUZhLxlrLJEKkZWbb2jmwuXD1QxYrkFTX1Hl4+KIlowTOt7ZnZYdRAA)で実際の挙動を確認してみてください。

`(string & {})` において、`{}`は **非-null** **非-undefined** な型を指します。`&`を使って`string`との`Intersect`型をつくることで、TypeScriptは`string`型を維持することができます。

[こちらのStackoverFlowの質問と回答](https://stackoverflow.com/questions/61047551/typescript-union-of-string-and-string-literals)で、今回の方法を知りました。

他に良い方法があれば教えて下さい。

以上です。
AZ-104試験対策のまとめ「ネットワーク編①」

## はじめに
Microsoft Azure Administrator(AZ-104)合格に向けた勉強でまとめた内容を本記事では投稿しています。
試験範囲の内容を私が勉強していく中で、
・忘れてしまっていた内容
・他の知識と絡めて理解した方が良い内容
・Microsoft Learnの読解に苦戦した内容
などをできるだけ分かりやすく簡潔にまとめることを意識しています。
Azureの勉強を一から始め、AZ-104取得を目指している方の参考になれば幸いです。
※本記事の内容が必ず試験に出るわけではないこと、ご注意ください

## 試験対策のまとめ
### **仮想ネットワークリンク**
* プライベートDNSゾーンの作成後、仮想ネットワークをそれにリンクさせる必要がある  
    ⇒リンクさせた仮想ネットワーク内のVMはプライベートDNSゾーンにアクセス可能
* 仮想ネットワークは、登録/解決仮想ネットワークとしてプライベートDNSゾーンにリンク

#### **登録仮想ネットワーク**
* 自動登録を有効にするオプションを使用
* 仮想ネットワークにデプロイするどのVMに対しても、DNSレコードは自動的に作成
* プライベートDNSゾーンに複数の登録仮想ネットワークを含めることが可能
* 登録仮想ネットワークに関連付けられるプライベートDNSゾーンは1つだけ

#### **解決仮想ネットワーク**
* 自動登録なし
* 解決仮想ネットワークにデプロイされたVM
    - DNSレコードはプライベートDNSゾーンに自動的に作成されない
    - プライベートDNSゾーンにあるDNSレコードを正常にクエリ可能
* プライベートDNSゾーンに複数の解決仮想ネットワークを含めることが可能
* 解決仮想ネットワークには複数のプライベートDNSゾーンを関連付け可能

<br>

* 参考
    - https://learn.microsoft.com/ja-jp/azure/dns/private-dns-virtual-network-links

## 次の試験対策のまとめ
* **AZ-104試験対策のまとめ「ネットワーク編②」**

https://qiita.com/fsd-jume/items/7af3f17fc0b4e0b8f7d1

## 学習内容をまとめたページの一覧

https://qiita.com/fsd-jume/items/6eda24728c9c03c36bc3
jQueryのclick();だとAngularでのクリックイベントをトリガーが呼び出せない

jQueryで運用していたのを途中でAngularjsを導入した背景です。

## jQueryのclick();だとAngularでのクリックイベントをトリガーが呼び出せない

その通りです。`$("#myButton").click();` を使用しても、Angularの `(click)` イベントバインディングは直接トリガーできません。jQueryの `.click()` メソッドでトリガーされるのは、DOMのネイティブなクリックイベントです。

Angularの `(click)` イベントバインディングは、Angularのゾーン内で処理されます。このゾーンは、Angularの変更検出メカニズムと統合されており、DOMのネイティブなイベントとは異なる方法でハンドルされます。

jQueryの `.click()` メソッドを使用してAngularの `(click)` イベントバインディングをトリガーするには、Angularのゾーンを明示的にトリガーする必要があります。

具体的な方法としては、`NgZone` サービスを使用してAngularのゾーン内でイベントをトリガーすることが考えられます。以下はその一例です。

```typescript
import { Component, NgZone, AfterViewInit } from '@angular/core';
import * as $ from 'jquery';

@Component({
  selector: 'app-example',
  template: '<a id="myButton" (click)="openPcWindow()">保存方法はこちら</a>',
})
export class ExampleComponent implements AfterViewInit {

  constructor(private zone: NgZone) {}

  ngAfterViewInit() {
    $(document).ready(() => {
      $('#myButton').on('click', () => {
        // NgZoneを使用してAngularのゾーン内でイベントをトリガー
        this.zone.run(() => {
          this.openPcWindow();
        });
      });

      // jQueryを使用してクリックイベントをトリガー
      $("#myButton").click();
    });
  }

  openPcWindow() {
    console.log('openPcWindow function called!');
  }
}
```

このコードでは、`NgZone`を使用して `openPcWindow` メソッドをAngularのゾーン内で実行しています。これにより、jQueryの `.click()` メソッドを使用しても、Angularの `(click)` イベントバインディングを正常にトリガーすることができます。

## jQueryのクリックイベントをトリガーが発火したらAngular関数を呼ぶようにした

Angularでは通常、jQueryを直接使用するのは推奨されません。なぜなら、Angularが提供するデータバインディングやイベントリスニングのメカニズムと競合する可能性があるからです。

しかし、あえてjQueryを使用してクリックイベントをトリガーしたい場面も考えられるので、その場合の方法を以下に示します。

1. まず、プロジェクトにjQueryをインストールします。
```bash
npm install jquery --save
```

2. AngularのコンポーネントでjQueryをインポートします。
```typescript
import * as $ from 'jquery';
```

3. 次に、コンポーネントのライフサイクルメソッドのひとつ、`ngAfterViewInit`内でjQueryを使用してボタンのクリックイベントをトリガーします。

```typescript
import { Component, AfterViewInit } from '@angular/core';
import * as $ from 'jquery';

@Component({
  selector: 'app-example',
  template: '<a id="myButton" (click)="openPcWindow()">保存方法はこちら</a>',
})
export class ExampleComponent implements AfterViewInit {

  ngAfterViewInit() {
    $('#myButton').click(() => {
      this.openPcWindow();
    });
  }

  openPcWindow() {
    console.log('openPcWindow function called!');
  }
}
```

上記のコードでは、`ngAfterViewInit`内でjQueryの`click`メソッドを使って、`openPcWindow`関数を呼び出すようにしています。

ただし、この方法はあくまで例外的な場合にのみ使用してください。通常のAngularの開発では、テンプレート内の`(click)`ディレクティブを利用してイベントリスニングを行う方がベストプラクティスとされています。
Azure Stack HCIにPremier Solutionsが登場

# はじめに
Azure Stack HCIにPremier Solutionsという提供形態が登場しています。従来はOSプリインストール型のIntegrated Systemと検証済みノードに自分でOSをインストールするValidated Nodeの2種類でしたがさらに上位のモデルが登場したということになります。Premier Solutions含め各ソリューションの違いは以下のMicrosoftドキュメントもご確認ください。

https://azurestackhcisolutions.azure.microsoft.com/#/Learn?WT.mc_id=modinfra-0000-thmaure

# Azure Stack HCI 振り返り
Azure Stack HCIは仮想化されたWindowsおよびLinuxのワークロードとそのストレージを、オンプレミスインフラストラクチャとAzureクラウドサービスを組み合わせたハイブリッド環境でホストするハイパーコンバージドインフラストラクチャ（HCI）ソリューションです。

https://learn.microsoft.com/ja-jp/azure-stack/hci/overview?WT.mc_id=modinfra-0000-thmaure

# Premier Solutionsとは
Premier Solutionsはお客様のより良い管理体験とすばやい価値提供のためas-a-service型の購入オプションによる柔軟性を兼ね備えた新しいAzure Stack HCIの提供形態です。現状はDellからのみ提供されていることが確認できますが、他のベンダも今後拡充されていくことが予想されます。

https://azurestackhcisolutions.azure.microsoft.com/#/catalog?systemType=PremierSolution

Premier Solutionは以下の特徴を持ちます。
- ハードウェア、ソフトウェア、クラウドサービスの完全な統合により、お客様がインフラストラクチャの管理に費やす時間を削減し、イノベーションに集中することができる
- Microsoftとパートナーの継続的なテストにより高い信頼性とダウンタイムの短縮を保証
- エンドツーエンドの導入ワークフローにより1000のクラスターであっても繰り返しかつ確実に導入することが簡単になる
- 自動化され共同テストされたフルスタックな更新によりワンクリックでシームレスな更新を提供
- 柔軟な購入モデルと利用可能な様々な付加価値サービスにより導入時の負担を軽減
- 顧客のグローバル資産全体にわたる一貫したソリューションのグローバルな可用性

https://azure.microsoft.com/en-us/blog/accelerating-azures-edge-capabilities-through-collaborative-partnerships/?WT.mc_id=modinfra-0000-thmaure

# まとめ
以下Dell APEX Cloud Platform for Microsoft Azureのデモの中ではVMwareとVxRailの取り組みをAzure Stack HCIに持ってきたものと紹介されています。両社の協業によってソフトウェアとハードウェアの統合が進みほとんどハードウェアを意識せずに管理できるものになっていることを感じました。Premier SolutionsはこのようにMicrosoftとOEMベンダーが今まで以上に強力なパートナーシップで提供するものでありお客様は自社のアプリケーションに注力できる点が魅力な提供形態となっています。

https://www.youtube.com/watch?v=23J3fTDYWY4&t=1082s
shadcn UI導入後の404エラー解決方法

next.jsで"npx shadcn-ui@latest"を叩いた後に”npm run dev”したところ404エラーになりました。

解決法
どうやら上記コマンドを叩くとデフォルトの/src/app/globals.cssと別に、componentsディレクトリに新規のglobals.cssが生成されるようです。
また、components.jsonというshadcn UIの設定ファイルも同じく生成されているはずです。このファイルのtailwind:{"css":""}の箇所を以下のように書き換えることでエラーが解消され、正常にブラウザに表示されるようになりました。ポイントは適用させたいglobals.cssファイルのパスを正しく入力することです。srcディレクトリ、appディレクトリを使用していない場合はご自身の環境に合わせて適宜編集してください。
```diff_json
 "tailwind": {
-  "css": "app/globals.css",
+  "css": "src/app/globals.css",
 }
```
↓こちらを参考にしました
https://github.com/shadcn-ui/ui/issues/755
ハンギングストリップ - コマンド画像ハンギングストリップを使用して自宅で写真を吊るすことができます。


ハンギングストリップ: 壁の装飾と整理のための最新のソリューション

インテリア デザインや家の整理の分野では、機能性と美しさの適切なバランスを見つけることが重要です。 近年人気を集めている解決策の 1 つは、吊り下げストリップの使用です。 これらの接着剤ベースの吊り下げシステムは、さまざまなアイテムを壁に効率的かつ損傷なく吊り下げる方法を提供します。 額縁から棚やフックに至るまで、吊り下げストリップは私たちの生活空間の装飾と整理の方法に革命をもたらしました。

吊り下げストリップについて
コマンド ストリップまたは粘着ストリップとも呼ばれる吊り下げストリップは、損傷を与えることなく壁に物を吊り下げやすくするために設計された革新的なツールです。 壁に跡や穴を残すことが多かった、ドリルで穴を開けたり、釘を使用したり、その他の従来の方法を使用する必要がなくなります。 これらのストリップは通常、次の 2 つの主要コンポーネントで構成されます。

粘着ベース: 粘着ベースは、吊るす対象物の重量を支えるのに十分な強度を持つ特殊なタイプの接着剤です。 壁にも対象物にもしっかり貼りつきます。

フックまたは取り付けポイント: フックまたは取り付けポイントは、吊り下げたい物体に接続するストリップの部分です。 フック、ループ、特定のアイテムを保持するために設計されたカスタムアタッチメントなど、さまざまな形式があります。

ハンギングストリップの利点
1. 壁を傷つけない
物を壁に掛ける従来の方法では、多くの場合、ドリルで穴を開ける必要があり、見苦しく、損傷する可能性があります。 吊り下げストリップは、壁を無傷で損傷しない非侵襲的な代替手段を提供します。

2. 取り付けと取り外しが簡単
吊り下げストリップの取り付けは簡単なプロセスで、特別な工具やスキルは必要ありません。 同様に、取り外しも同様に簡単で、残留物や跡が残らないため、賃貸人や一時的な解決策を探している人にとって理想的です。

3. 多用途性
吊り下げストリップは多用途で、さまざまなアイテムに使用できます。 額縁、鏡、棚、その他の装飾品であっても、吊り下げストリップのソリューションが利用できる可能性があります。

4. 調整可能性
吊り下げストリップには、吊り下げた物の高さや位置を調整するためのオプションが付属していることが多く、ストリップを取り外したり取り付け直したりする必要はありません。 この柔軟性により、装飾のカスタマイズや再配置が簡単に行えます。

5. さまざまなスタイルと耐荷重
吊り下げストリップは、さまざまなニーズに合わせて、さまざまなスタイルと耐荷重で入手できます。 軽量のポスターを掛ける場合でも、重い鏡を掛ける場合でも、重量をしっかりと支えるように設計された吊り下げストリップが付いています。

ハンギングストリップの使用方法
吊り下げストリップを効果的に使用するには、適切な取り付けと確実な保持を確保するためのいくつかの重要な手順が必要です。

1. 表面を準備する
ハンギングストリップを貼り付ける壁の表面をきれいにします。 接着を妨げる可能性のあるほこり、汚れ、油などが付着していないことを確認してください。

2. ストリップを貼り付けます
吊り下げストリップの片側の裏地をはがし、吊り下げたい対象物にしっかりと押し付けます。 壁に接着するストリップの反対側にもこれを繰り返します。

3. 位置を決めて押します
壁上の目的の場所にオブジェクトを配置し、強力な接着力を確保するためにストリップに数秒間しっかりと押し付けます。

4.待ってテストする
耐荷重をテストする前に、推奨されている時間接着剤が固まるのを待ちます。 使用している吊り下げストリップの特定の種類に指定されている重量制限を超えないよう注意してください。

5. 削除
対象物を取り外すときは、対象物を持ってストリップをゆっくりと優しく下に引くだけです。 この動作により接着剤が伸び、壁に損傷を与えることなく接着が解除されます。

吊り下げ用ストリップの種類
いくつかの種類の吊り下げストリップがあり、それぞれ特定の目的と耐荷重に合わせて設計されています。 最も一般的なタイプは次のとおりです。

1. 絵画吊り下げストリップ
額縁やアートワークを壁にしっかりと固定できるように設計されています。 さまざまなフレームのサイズと重量に対応できるよう、さまざまなサイズと耐荷重が用意されています。

2. コマンドフック
コマンド フックは多用途で、鍵、タオル、その他の軽量アクセサリーなどのアイテムを掛けるのに便利です。 さまざまな目的に合わせてさまざまな形やサイズがあります。

3. コードおよびケーブル オーガナイザー
これらは、コードやケーブルを管理および整理し、整理整頓された環境を確保するように設計されています。 壁や机に貼り付けて、ワイヤーを所定の位置に保つことができます。

4. 棚とキャビネットのストリップ
これらは、棚、キャビネット、その他の保管ソリューションの重量を支えるように設計された、より頑丈なストリップです。 ネジや釘を使わずにしっかりと固定できます。

5. 屋外ストリップ
屋外での使用のために、気象条件に耐え、屋外の装飾を強力に保持できるように設計された特殊な吊り下げストリップがあります。

吊り下げストリップを効果的に使用するためのヒント
吊り下げストリップを最大限に活用し、取り付けを確実に成功させるには、次のヒントを考慮してください。


Amazon Product >>> https://amzn.to/405wzjX
環境構築方法

# 実行環境

- python 3.8
- matplotlib 3.0.3
- pandas 0.24.2
- scikit learn 0.23.2
- scipy 1.2.1
- nump 1.16.2
- jupyter 1.0.0
- japanize-matpotlib 1.0.4

# 構築方法

## Pythonのインストール


[環境構築ガイド](https://www.python.jp/install/install.html)参照。

## pipenv のインストール

```
pip install pipenv
```

コードやデータが格納されるディレクトリに移動し、つぎのコマンドを実行し、動かすに必要なライブラリをインストールします

```
pipenv install
```

# コードについて

ノートブックを起動します

```
pipenv run jupyter notebook
```

# データについて

`9_data`配下に、保存されている

# インポートされるモジュールとライブラリ

```
import math
import numpy as np
import pandas as pd
from matplotlib import pylab as pt
import jjapanize_matplotlib
```
セキュリティ更新OpenSSL X.509 メールアドレスのバッファオーバフロー

<font color="Grey">*[Security updates: OpenSSL X.509 email address buffer overflow](https://aiven.io/blog/security-update-on-openssl-x.509-email-address-buffer-overflow)の翻訳です。*</font>

2022年11月4日

# セキュリティ更新OpenSSL X.509 メールアドレスのバッファオーバフロー

CVE-2022-3786およびCVE-2022-3602は、現在のところAivenサービスおよびAivenプラットフォームへの影響はありません。

2022年10月25日、我々は新たな潜在的な重大なOpenSSL脆弱性を認識しました。


2022年11月1日、公式の詳細が発表されました。OpenSSL v3.0-3.6に影響を及ぼす2つの深刻度の高いOpenSSLの脆弱性があります：


* [CVE-2022-3786](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-3786)
* [CVE-2022-3602](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-3602)


これらは、サービス拒否 (「DoS」) やリモートコード実行 (「RCE」) を引き起こすバッファオーバーランにつながる可能性があります。OpenSSL.orgの声明によると、バッファオーバーランは、X.509証明書の検証に悪意のある値が証明書のフィールドに含まれている場合に引き起こされる可能性があるとのことです。


悪用するには、認証局（「CA」）が悪意のある証明書に署名しているか、アプリケーションが信頼できる発行元へのパスを構築できないにもかかわらず証明書の検証を続行する必要があります。


OpenSSLの報告チームは、公開時点では、リモートでコードが実行される可能性のある悪用を認識しておらず、公開前にこの問題が悪用された形跡もありません。


脆弱性の追加詳細が開示されて以来、当社のセキュリティ、エンジニアリング、およびオペレーションチームは、Aivenプラットフォームおよびサービスに対する潜在的な影響を徹底的に調査しました。**Aivenのサービス、基盤となるオペレーティングシステムやソフトウェアに、これらの脆弱性を突くコンポーネントは見つかっていません。


## 詳細情報


脆弱性の詳細については


1.[CVE-2022-3786およびCVE-2022-3602に関するOpenSSLブログ記事](https://www.openssl.org/blog/blog/2022/11/01/email-address-overflows/)
2.[CVE-2022-3786](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-3786)

および CVE Mitre の [CVE-2022-3602](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2022-3602) を参照。CVE MitreでCVE情報が公開されている場合に参照される可能性があります。



Aivenと当社のサービスに関する最新ニュースや、オープンソースに関するちょっとした情報を入手するには、[月刊ニュースレターを購読](https://aiven.io/newsletter)してください！Aivenに関する日々のニュースは、[LinkedIn](https://www.linkedin.com/company/aiven/)と[Twitter](https://twitter.com/aiven_io)のフィードでご覧いただけます。


サービスのアップデート情報を知りたい方は、[変更履歴](https://aiven.io/changelog)をご覧ください。


マネージド・データ・プラットフォームをお探しですか？<https://console.aiven.io/signup>から無料トライアルにお申し込みください！
DataDogでSLOを設定するときにメトリクスが選択肢にない

# はじめに

DataDogをよく利用しているのですが、初めてSLOの設定を経験したのでそのときに躓いたことをまとめます

# 問題

カスタムメトリクスを設定終えて、SLOの作成をします。
しかし、以下の画面で`select metric`で検索してもなぜか追加したメトリクスが表示されませんでした

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/810513/77e4e2ed-e4d6-32ff-eccc-051c770a88b7.png)

# 解決方法

設定後に1度アクセスがあるとサジェストに表示されるようになりました
時間が経てば表示されると思っていましたが、なかなか表示されるませんでした
これが理由だったみたいです

# おわりに

ちなみにメトリクスを追加するときは以下のパスから行いました
`apm/traces/generate-metrics`


地味に分かりづらいなと思いました
Mac,XAMPPのmysqladminでzsh: command not foundが出る時の対処方法

## MacでXAMPPでPHP環境を整えて、コマンドプロンプトでmysqladmin -u root passwordと入力した所エラーが
phpの勉強のためXAMPPをインストールしてMariaDBのデータベースを作成する際に、コマンドプロンプトで
mysqladmin -u root password
と実行した所、
zsh: command not found: mysqladminエラーが。

## 結論：こうすれば動いた↓
mysqladmin -u root password
ではなく、
/Applications/XAMPP/xamppfiles/bin/mysqladmin -u root -p
とフルパスで入力したら動いた。

![スクリーンショット 2023-10-13 4.10.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3576117/3352d3a6-1b87-3acf-7661-846024b8ce99.png)

## viエディタでパスを追加しても動かなかった
vi ~/.bash_profile
↓
eで編集、iでインサート、パスをコピペ、Escで終了、:wqで保存して終了、ターミナル再起動、
を何回か試したが、フルパスでないとエラーが起きた。

bash,zsh,それに関連するパスの設定ファイルが原因な気がしているが、今は分からないためこのまま学習を続けようと思う。
Node.jsのインストール確認コマンド

# 概要
　Qiita CLIを使用し，記事をGitHubリポジトリで管理しようとした際に躓いたことを記載する。

# 躓いたこと
## 「Node.jsのインストール確認」
参考URL2に記載してあるとおりにインストール後，Node.jsインストール確認のためにコマンドプロンプトから「node-v」や「npm-v」を入力した。しかし，「'node-v'　は，内部コマンドまたは外部コマンド，操作可能なプログラムまたはバッチファイルとして認識されていません。」が表示した。
## 原因
バージョン確認コマンドが間違っていた。
誤：node-v 　(「node」と「-v」の間に半角スペースなし)
正：node -v　(「node」と「-v」の間に半角スペースあり)
誤：npm-v 　(「npm」と「-v」の間に半角スペースなし)
正：npm -v　(「npm」と「-v」の間に半角スペースあり)

# 分かったこと
1. Node.jsやnpmのバージョン確認コマンド：「node -v」と「npm -v」
→「V18.18.0」や「9.8.1」などと出力されればOK

# 参考URL
1. [Qiitaの記事をGitHubリポジトリで管理する方法](https://qiita.com/Qiita/items/32c79014509987541130 "Qiitaの記事をGitHubリポジトリで管理する方法")　(2023/10/07時点閲覧可能)
1. [【Windows 10】「npm」と「Node.js」をインストールする方法！](https://www.excite.co.jp/news/article/OtonaLife_otona_life103500/ "【Windows 10】「npm」と「Node.js」をインストールする方法！")　(2023/10/07時点閲覧可能)

# 所感
　Qiita CLIとGitHubを使用し，記事を管理しようとしたが，GUI経験ばっかでCLI経験が少なく前提知識がなさすぎだということが分かった。とりあえずまず，GUIでいいから記事の記載方法に慣れようと思った。その中で，「SSH」や「公開鍵・秘密鍵」，「YAMLファイル」，「GitHub CLI」，「Qiita CLI」などを知っていこうと思った。
[Laravel] 使用技術の version を確認するコマンド　まとめ

# この記事でやりたいこと
Laravel Sail によるDocker開発環境でWebアプリを構築する際に、使用する技術の version を確認するコマンドが多種多様で困った経験があるので、この際にまとめておきます。

## Laravel
~~~.terminal
% sail artisan -V
Laravel Framework 10.28.0
~~~
（ sail コマンドのパスを通していない場合は、`sail` の部分を`./vendor/bin/sail` に置き換えて下さい。 以下同様）

## PHP
~~~.terminal
% sail php -v
PHP 8.2.11 (cli) (built: Oct  6 2023 09:47:18) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.2.11, Copyright (c) Zend Technologies
    with Zend OPcache v8.2.11, Copyright (c), by Zend Technologies
    with Xdebug v3.2.1, Copyright (c) 2002-2023, by Derick Rethans
~~~

## Composer
~~~.terminal
% sail composer -V
Composer version 2.6.5 2023-xx-xx xx:xx:xx
~~~

## node.js
~~~.terminal
% sail node -v
v18.18.1
~~~

## npm
~~~.terminal
% sail npm -v
10.2.0
~~~

## Docker
~~~.terminal
% docker -v
Docker version 23.0.5, build bc4487a
~~~

## Mysql
~~~.terminal
% sail mysql
> mysql select version();
+-----------+
| version() |
+-----------+
| 8.0.32    |
+-----------+
1 row in set (0.00 sec)
~~~

## Composer でインストールしたパッケージ群
~~~.terminal
% composer show -i
~~~

## npm でインストールしたパッケージ群
~~~.terminal
% npm list
% npm ls
% npm la
% npm ll
# 上記のうちどれでも可
~~~

以上です。
___
Django基本４～Templateを使用して、HTMLを表示してみた。

こんばんは。今は夜です。

今回はindex.htmlから、「どーもー」と表示してみます。

■開発準備
　今回は以下の名前で行きます。
　プロジェクト名＝norizo_project3
  アプリケーション名＝norizo_app3

１．templatesというフォルダをnorizo_app3配下に作成します。
２．templatesの中にindex.htmlを作成します。
３．「どーもー」を作りこむ
![無題.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3571777/1a859cbc-1a83-0093-2194-c9c045707fd9.jpeg)
４．views.pyをこんなかんじで修正します。
![無題.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3571777/fc0db6fd-4f32-214b-183c-3807d7fed16c.jpeg)
５．urls.pyをファイル追加します。
![無題.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3571777/e4dd1de1-00f1-bbeb-208d-6c01b3ec439f.jpeg)
６．setting.pyを修正する。
![無題.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3571777/ff2da95f-779f-f5ef-6503-6a145c5aa4b2.jpeg)
７．プロジェクトフォルダのurls.pyを修正する
![無題.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3571777/b815ebb3-4781-03eb-dbc3-852e21fb8dee.jpeg)
８起動して結果を確認します。
![無題.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3571777/8659161e-31eb-79a2-aa3a-e6d3f9e0ce5f.jpeg)
無事表示されました。
![無題.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3571777/e681c3fd-fe6d-6924-64d7-58770d8aef60.jpeg)
【初心者】VueCLIでプロジェクトを作る

## プロジェクトを作る

（※Cloud9上で実行しています）

(1) VueCLIをインストールする
```
npm install -g @vue/cli@4.5.12
```

(2) プロジェクトを作成する
```
vue create プロジェクト名
```

上記のコードを実行するとターミナル上で設定を促されるから、
以下のような設定にする。

##### please pick a preset:
- Manually select features
##### Choose vue version:
- Babel
- Linter / Foramatter
##### Choose a version of Vue.js that you want to start a project with
- ESLint + Airbnb config
##### Pick additional lint features:
- Lint on save
##### Where do you prefer placing config for Babel, Lint and etc.?
- In dedicated config files
##### Save this preset for future project?(y/N)
- y
##### Save preset as:
- ここは好きな名前でOK

これで**プロジェクト作成完了**。プロジェクトが作られると共に必要なライブラリやファイル一式も用意してくれる。こんな２ステップだけでいいみたいなんです。


## プロジェクトの中身を確認してみよう

プロジェクト作成時にVueCLIが色々と用意してくれたみたいなんで、
ちょっと中身を覗いてみましょう。

#### VueCLIプロジェクトの中身

- node_modules：ライブライブラリ用フォルダ
- public：webpackによる処理が必要のないフォルダ
- src：直接アプリケーションに関係するコード用のフォルダ

ちょっと難しく感じるけど、なんてことはない。
これからメインでいじるのはこの**srcフォルダ**である。
そしてsrcフォルダの中身は以下のようになっている、、


#### srcフォルダの中身
- assets：画像ファイル
- components：コンポーネント
- App.vue：Appコンポーネント
- main.js：コンポーネントをindex.htmlと結びつけてくれる

main.jsの中身はあらかじめ以下のように設定されているよ、、

#### main.jsの中身
```
import Vue from 'vue'; // ①
import App from './App.vue'; // ②

Vue.config.productionTip = false; // ③

new Vue({
  render: (h) => h(App), // ④
}).$mount('#app'); // ⑤
```

①: Vueライブラリの読み込み
②: Appコンポーネントの読み込み
③: 開発者向けのメッセージをコンソールで非表示に設定
④: Vueインスタンスのrender（描画）オプションで、**Appコンポーネント**を描画
⑤: Vueインスタンスをindex.htmlのDOM要素（idがappのもの）にマウントしている

## Clou9上でブラウザを表示するための準備

このままではアプリケーションをCloud9上でプレビューできないみたい。
だからそのための設定を行う。

プロジェクトフォルダの直下にvue.config.jsファイルを作成。
中身は以下のようにすればOK。

```
module.exports = {
  devServer: {
    public: process.env.C9_PID
      ? `${process.env.C9_PID}.vfs.cloud9.ap-northeast-1.amazonaws.com`
      : 'localhost:8080',
  },
};
```

意味はおそらく、「東京リージョンのサーバを使ってね」ってことだと思う。
これでやっとアプリケーションをプレビューできるようにになったので、実際にやってみよう。

ターミナル上でプロジェクトに移動
```
cd プロジェクト名
```
開発サーバを起動
```
npm run serve
```
Previewボタンから、**Preview Running Application**を押せば完了。
Appコンポーネントの中身がちゃんと表示されたかな？

## まとめ

実際に行ったことはとてもシンプル。

```
npm install　-g @vue/cli@4.5.12
```
```
vue create プロジェクト名
```
アプリケーションのプレビューを見れるようにするために、
vue.config.jsファイルをプロジェクト直下に作成
```
module.exports = {
  devServer: {
    public: process.env.C9_PID
      ? `${process.env.C9_PID}.vfs.cloud9.ap-northeast-1.amazonaws.com`
      : 'localhost:8080',
  },
};
```
[JavaScript, TypeScript] スプレット構文 (...) とはなんぞや

 ## 初めに
これは会社で先輩のコードを見た時によく目にしていまして、
なんか気になったので、調べてみました。

## スプレット構文とは
>`配列式や文字列などの反復可能オブジェクトを、0 個以上の引数 (関数呼び出しの場合) や要素 (配列リテラルの場合) を期待された場所で展開したり、オブジェクト式を、0 個以上のキーと値の組 (オブジェクトリテラルの場合) を期待された場所で展開したりすることができます。`
>>引用: https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Spread_syntax

ちょっと私の頭では何言っとるかわからなかったので、実際に書いて動かしてみました。↓

## 実際の挙動
```javascript
const numbers = [1, 2, 3, 4, 5];

console.log('numbers: ', numbers);
console.log('...numbers: ', ...numbers);

// 結果↓↓
// numbers:  [ 1, 2, 3, 4, 5 ]
// ...numbers:  1 2 3 4 5
```
ほほう……

```javascript
const sum = (a, b, c, d, e) => {
    return a + b + c + d + e;
};

const numbers = [1, 2, 3, 4, 5];

console.log("numbers: ", numbers);
console.log("...numbers: ", ...numbers);

console.log("sum(numbers): ", sum(numbers));
console.log("sum(...numbers): ", sum(...numbers));

// 結果↓↓
// numbers:  [ 1, 2, 3, 4, 5 ]
// ...numbers:  1 2 3 4 5

// sum(numbers):  1,2,3,4,5undefinedundefinedundefinedundefined
// sum(...numbers):  15
```
なんか`undefined`がいっぱいだー

こんな挙動になるんですね…
それじゃあ、関数の引数も`1`から順に`引数a`から入っていくのかしら…

```javascript
const show = (a, b, c, d, e) => {
    console.log(a, " ", b, " ", c, " ", d, " ", e);
};

const numbers = [1, 2, 3, 4, 5];

show(numbers);
show(...numbers);

// 結果↓↓
// [ 1, 2, 3, 4, 5 ]   undefined   undefined   undefined   undefined
// 1   2   3   4   5
```
どうやら、順番に入っていくようですね！
これが、さきの文言で言う、
> `0 個以上のキーと値の組 (オブジェクトリテラルの場合) を期待された場所で展開したりすることができます。`

の意味だったのかな？

## まとめ
どうだったでしょうか。
めちゃくちゃ初歩的なところでしたが、これが誰かの参考になったりしたら嬉しいです。
【プラクティス紹介】1分でさらっと分かる「受け入れ条件」

## プラクティス名（別名）
受け入れ条件 （受入基準、AC、Acceptance Criteria）

## プラクティスの目的・狙い
* プロダクトバックログアイテム（PBI）の完了基準を明確化する

## どんな時に使うか
* POとDEVの間でPBIが何をもって「完了」となるのか認識齟齬が頻発する時

## 実施手順
1. そのPBIは何をもって「完了」となるのかPOとDEVで具体的な基準について**話し合う**
1. ACは直接POがPBIに追記する（または話した内容をDEVが書き下しPOと合意する）
1. PBIを完了させる時には「受け入れ条件」「完成の定義」両方を満たしていることを確認する

ACの適切な記述粒度はケースバイケースだが、「POとDEVが齟齬無く完了/未完了を判断できる」という点が目安となる。ただしACに例外処理などアプリの詳細仕様を漏れなく書こうとするとPBLが重くなりすぎるので避けた方がよい。ある程度、会話で補完することも必要。


## アレンジ例
* ACをユーザの操作手順として記述し、スプリントレビューではその手順に沿ってデモを行う

## アンチパターン
* ACを書くのはPOの仕事と、任せきりにした結果、POが回らなくなる
* DEVがPOに「ACにそんなことは一言も書いてありません」と言う。
（これを口にしてしまうと、以後、ACが契約と化していく）
* 「受け入れ条件」と「完成の定義」の記述が混在してしまっている

:::note info
受け入れ条件：そのPBI固有の完了条件
完成の定義　：全てのPBIに共通する完了条件
:::

## 参考情報
https://www.ryuzee.com/faq/0077/

## こぼれ話（私的コメント）
真面目なPOほどACをきちんと書こうとしてボトルネックになりがちな気がします。DEVが「ACに書かれていないことは一切やらなくてよい」と考えるタイプだと特に。個人的な意見としては、たとえPOからの指定がなかったとしても、システムのプロとして、あるべき姿を考え、仕様を詰めていくのは「設計」の領域であり、DEVの責任だと考えます。つまるところACはコミュニケーションツールだ、という前提に立てば、記述云々よりも共通認識が作れているかどうかが大事、という理解にたどりつけるのかな、と思います。

　[アジャイルプラクティス一覧へ戻る](https://qiita.com/kakashi_h5/items/20584998c5ca4594b9ea)
ジェネリックで受けたEnumをIntにキャストする際のBoxingの避け方

## はじめに
軽量なステートパターンを作っているときにジェネリックで受けた`Enum`を`Int`にキャストしたい場面があった。
```cs
public void EnumToInt<T>(T target) where T : Enum
{
    //EnumからIntに変換したい
}
```
この場合、`(int)`でキャストすることができないため別のアプローチが必要になる。

## その１ enum → object → int 
見るからに遅いが、キャストできる。
```cs
public void EnumToInt<T>(T target) where T : Enum
{
    int num = (int)(object)target;
}
```
もちろんBoxing

## その2 Convert.ToInt32
```cs
public void EnumToInt<T>(T target) where T : Enum
{
    int num = Convert.ToInt32(target);
}
```
ぱっと見良さそうだが、`object`型の引数に`enum`を渡しているのでBoxing。

## その3 Unsafe.As
`Unsafe`なので使うかどうかは状況によりけりだが、爆速でキャストできる。
```cs
public void EnumToInt<T>(T target) where T : Enum
{
    int num = Unsafe.As<T, int>(ref target);
}
```
また、IntToEnumも同じようにキャストできる。
## 安全性の確保
`enum`のメンバーは`int`型だけではなく`short`, `long`, `byte`などにもできるので、`Unsafe`キャストのみでは不安が残る。
```cs
enum State : short
{
    Idle,
    Running,
}

public void EnumCast()
{
    var state = State.Idle;
    int num = Unsafe.As<State, int>(ref state);
    //この場合、ShortToIntのキャストとなり、不正なメモリ領域が読まれる。
}
```
`int`型はimmutableなので破壊的な動作をすることはなさそうだが、想定外の挙動になるので例外をはいたほうがよさそう。Enumのメンバー定数の型は`Enum.GetUnderlyingType`で取得できる。
```cs
public void EnumToInt<T>(T target) where T : Enum
{
    if (Enum.GetUnderlyingType(typeof(T)) == typeof(int) == false)
        throw new InvalidOperationException();
    int num = Unsafe.As<T, int>(ref target);
}
```
不正なメモリ領域を読まなければそれでいいという場合、サイズを比較するやり方でも良さそう
```cs
if (Unsafe.SizeOf<T>() == Unsafe.SizeOf<int>() == false)
```

## 参考
https://ufcpp.net/blog/2018/12/unsafenogarantee/
パイプ演算子 + then/2の組み合わせを学ぶ

こんにちは！
プログラミング未経験文系出身、Elixirの国に迷い込んだ？！見習いアルケミストのaliceと申します。
今回はthen/2について学んだことをまとめます。

# 目的
[then/2](https://hexdocs.pm/elixir/1.14.3/Kernel.html#then/2)の機能を理解します。

## 実行環境
Windows 11 ＋ WSL2 ＋ Ubuntu 22.04
Elixir v1.14.3
Erlang v26.0.2
Phoenix v1.7.3

# then/2とは？
通常は第一引数にしか渡せないパイプ演算子の左側の値を、第二引数他に渡せる関数。

# 利用例
`File.write/2`は第一引数にファイルのパス、第二引数にファイルの中身を指定します。
第一引数のパスに第二引数の中身でファイルを作成します。
```diff_elixir:oct10/lib/oct10.ex
 defmodule Oct10 do
  def make_a_file do
    body = "Hello, World!"
    File.write("hoge.txt", body)
    File.read("hoge.txt")
  end
 end
```
### 実行結果
```bash:shell
iex(1)> Oct10.make_a_file
{:ok, "Hello, World!"}
```

## テキストの中身をパイプ演算子で渡したい！(NG例)
`File.write/2`について、テキストの中身をパイプ演算子を使用して渡したいとします。
しかし、そのままではパイプ演算子の左側の値を、第二引数には渡せません。
```diff_elixir:oct10/lib/oct10.ex
 defmodule Oct10 do
   def make_ng_file do
     body = "Oh No, World!"
+    body |> File.write("fuga.txt", body) # then句無しではパイプ演算子の左側の要素を第二引数には渡せない
   end
 end
```

### 実行結果(NG例)
実際、上記を実行するとこのようなエラーが出ます。
```bash:shell
iex(2)> Oct10.make_ng_file
** (FunctionClauseError) no function clause matching in File.normalize_modes/2
...
```

## テキストの中身をthen/2を使用してパイプ演算子で渡す！
これを解決するのがthen/2です。
then/2を使用することでパイプ演算子の左側の値を、第二引数に渡せます！
```diff_elixir:oct10/lib/oct10.ex
defmodule Oct10 do
   def make_a_file_using_then do
     body = "Hi, World!"
+    body |> then(fn x -> File.write("piyo.txt", x) end)
   end
end
```

### 実行結果
```bash:shell
iex(3)> Oct10.make_a_file_using_then
{:ok, "Hi, World!"}
```

パイプ演算子+第一引数以外という組み合わせの際に頻出しそうですね(^▽^)/



# ～Elixirの国のご案内～
↓Elixirって何ぞや？と思ったらこちらもどぞ。Elixirは先端のアレコレをだいたい全部できちゃいます:laughing::sparkles::sparkles:

https://qiita.com/piacerex/items/09876caa1e17169ec5e1

↓ゼロからElixirを始めるなら「エリクサーチ」がおすすめ！私もエンジニア未経験から学習中です。

https://elixir-lang.info/topics/entry_column


↓[We Are The Alchemists, my friends!:bouquet:](https://qiita.com/torifukukaiou/items/6bcd5bbb80df9e594e9e "Awesome-san's Awesome article")[^10]
Elixirコミュニティは本当に優しくて温かい人たちばかり！
私が挫折せずにいられるのもこの恵まれた環境のおかげです。
まずは気軽にコミュニティを訪れてみてください。[^11]


https://speakerdeck.com/elijo/elixirkomiyunitei-falsebu-kifang-guo-nei-onrainbian




[^10]: @torifukukaiouさんのAwesomeな名言をお借りしました。Elixirコミュニティを一言で表すと、これに尽きます。


[^11]: @kn339264さんの素敵なスライドをお借りしました。Elixirコミュニティはいろんな形で活動中！
ずれない、見やすい時計の検討。結局はJavaScriptで書いてみた


作業ログ

2023/08〜2023/09

時計調達を検討した時のメモを整理したもの

# 結論
JavaScriptで書いて既存のiPad mini4で表示で良くないか？

---
以下大体時系列で整理
# 目標
部屋に以下のような時計がほしい
- 見やすい
- ズレない
- 可能なら壁掛け
- 電源は電池でもコンセントでも良い

# 方向性確認
- アナログかデジタルか
- 同期方式
- 既製品か自作か
- 専用機器かその他機器か。HWかSWか

### 検討
- アナログかデジタルか
→デジタルで、秒表示は欲しい。

- 同期方式
    - 電波時計
        - 40kHz
        - 60kHz
        - 中継機
        →先ず考えた選択肢。ただ、電波状態に左右される。
https://eng-blog.iij.ad.jp/archives/9418


    - ntp時計
        - stratum 0
        →原子時計は予算的に不可。
        - stratum 0 以外
        Little Green WIFI 自動時刻同期 時計
        Blueekin デジタル時計 LED大画面 WiFi時間自動修正対応
        WLAN電波時計 BitClock/BTCLK
        →どれも良さそうだが、秒表示がない。
https://tech-blog.abeja.asia/entry/advent-2022-day06
https://elchika.com/article/c48472ba-6e74-4fce-b45c-35af505b81c3/
https://kohacraft.com/archives/201913201202.html
https://akizukidenshi.com/catalog/g/gK-07436/
        →せっかくならやってみたい選択肢。ntpクライアントがあれば良いということ。

- 既製品か自作か
    - 既製品
    →上記で秒表示ないが安いので試すか？
    - 自作
    →上記の電子工作も良いが、取り敢えずはntpクライアントと、何か画面があれば良いのでは？ラズパイとミニディスプレイとか？

- 専用機器かその他機器か。HWかSWか
→ラズパイとミニディスプレイ、というより、別に機種変で使わなくなったスマホとかタブレットでも良くないか？
端末は基本ネットワーク接続し、デフォルトではntpされているはず。
https://touchlab.jp/2015/09/ios9_clock_problem/?amp
https://www.nict.go.jp/JST/JST5.html

### 検討　第二段階

- 既存アプリか、自作か
→アプリを探し始めたが、広告あったりイメージと違ったり。。。作れば？
https://tokusengai.com/_ct/17520523

- アプリ自作
    - ネイティブアプリ
    →iPadなりAndroidなりのアプリの開発で、凝ったことはしない。選択肢としてありかな。
    - ブラウザアプリ
    →前書いたことあったし、調べたら色々出てくるし、これで良くないか？

# 結論
JavaScriptで書いて既存のiPad mini4で表示で良くないか？
取り敢えず先駆者の記事を確認。試してみよう。
https://web-dev.tech/front-end/javascript/digital-clock/
https://dianxnao.com/category/javascript/page/3/
https://fukuno.jig.jp/20200118
https://yuukubo.github.io/clockp5/
https://digital.onl.jp/

↓書いてみた。
https://yuukubo.github.io/clockp5v2/
→safariでフルスクリーン効かない、
　iOS古くてchromeとかインストールできないので、
　取り敢えず既存のAndroid（Xperia XZとか初代novaとか）で代用。
　→でも画面が機種によってはスリーブになるのを開発者モードでも防げないとか、
　　適任者探し中。

以上
X（旧Twitter）でBADマークを押すスクリプト

### XのスペースでBADマークを押すスクリプト ###
X（旧Twitter）のスペースでBADマークを押すスクリプトです。
img要素を変えれば他のマークにも対応すると思います。
```Javascript
// 要素をクリックするコード
var element = document.querySelector('div[aria-label="反応"]');
if (element) {
  element.click(); // 要素をクリック
} else {
  console.log("要素が見つかりません");
}

var imgElement = document.querySelector('img[alt="👎"]'); // 指定の <img> 要素を選択
imgElement.click(); // <img> 要素をクリック
```
#### ブックマークレット用 ####
```Javascript
javascript:(function(){var e=document.querySelector('div[aria-label="反応"]');e?e.click():console.log("要素が見つかりません");var t=document.querySelector('img[alt="👎"]');t.click();})();
```
入れ替えれば使えました
😂😲😢💯👏✊👍👎👋
JSONでバイナリを送ってクライアント側で画像としてダウンロード

DBに画像ファイルを取り込んでおき、JSONとして画像をブラウザへ配信します。

このときクライアント側で画像ファイルにもどすことにつまづいたのでメモします。

## 成功事例

ChatGPTが教えてくれました。

[uint8arrayで保存されているバイナリデータをJSONでarrayとして送るには](https://poe.com/s/nrZrMryxuoC7znO0WAp7)

クライアント側で受け取ったUint8Arrayを画像データに変換するには、次の手順に従うことができます。以下の例では、JavaScriptを使用しています。

```jsx
// 受け取ったUint8Array
var receivedData = new Uint8Array([/* 受け取ったデータを入力 */]);

// Uint8ArrayをBlobオブジェクトに変換
var blob = new Blob([receivedData], { type: 'image/jpeg' }); // typeを適切な画像形式に合わせて設定

// BlobオブジェクトをURLに変換
var imageUrl = URL.createObjectURL(blob);

// 画像要素を作成して表示
var imgElement = document.createElement('img');
imgElement.src = imageUrl;
document.body.appendChild(imgElement);

```

上記の例では、受け取ったUint8ArrayをBlobオブジェクトに変換します。Blobオブジェクトはバイナリデータを表現するためのオブジェクトであり、その後、URL.createObjectURLメソッドを使用してBlobオブジェクトをURLに変換します。

最後に、img要素を作成し、URLを設定して画像を表示することができます。この例では、画像要素をbody要素に追加していますが、表示方法は実際の使用環境に応じて変更してください。

この方法を使用すると、クライアント側で受け取ったUint8Arrayを画像として表示することができます。

## 気をつけるべきこと

### サーバー側

JSONで送るとき、arrayにして送りましょう。Uint8Arrayのままではだめです。

理由は深く解説できないのですが…、

```typescript
// ダメな例
let jsonData = {data: binaryData as Uint8Array}
// 良い例
jsonData = {data: Array.from(binaryData as Uint8Array)}
```


### クライアント側
Uint8Arrayを作ってからBlobを作りましょう。
さらに、そのBlobをURLへ変換してユーザーにクリックさせればダウンロードできます。

具体的には

```typescript
// ArrayからUint8Arrayへ変換
const array = new Uint8Array(data); 
// Uint8ArrayからBlobへ変換
const blob = new Blob([array]);

// Blobをaタグへ埋め込み
const a = document.createElement("a");
// Blob オブジェクトをURLへ変換
a.href = URL.createObjectURL(blob)
a.download = "image.jpg";
a.textContent = "click to download";
```

ただし、Arrayとして送る方法はブラウザ互換(特にIEとかIEとかIEのこと)が保証されないそうです。しかしながらIEはもうとっくに死滅したと思われ、私の周囲では使用しない前提で開発していますので、ここはArrayで送る方法を採用しました。
下記、AIによる解説では互換性においてBase64を勧められています。
Base64を使う場合はサーバー側でArrayをUint8Arrayにして、クライアント側でその逆を行う必要があります。

## base64?Uint8Array?
[JSONに載せるバイナリデータはbase64?Uint8Arrayどちらがよい？](https://poe.com/s/qLEUnUyg8tdXQXHVsxyj)
JSONにバイナリデータを載せる場合は、通常base64エンコード文字列が使われます。

Uint8Arrayはバイナリデータを直接含めることができますが、JSON仕様には含まれていないデータ型です。ブラウザ間の互換性などを考えるとbase64がおすすめです。

base64とUint8Arrayの主な違いは以下の通りです:

- base64: JSON仕様に含まれる文字列型で移 port・互換性が高い。データサイズが原データの約33%大きくなる。
- Uint8Array: バイナリデータを直接含められるため効率的。ただしブラウザ間でのサポート状況は不明。

一般的な用途ではbase64が最も安全な選択肢だと思います。
ブラウザ間互換性や他のシステムとのインタフェースを考慮する必要がない専用アプリケーションならUint8Arrayも可能性の1つです。

要件や利用シーンに合わせて両方の長短を比較検討して選択することをおすすめします。

# 失敗例

## 結果、15BのObject objectという文字列をダウンロードした。

JPEG画像をブラウザでダウンロードできるようにするには以下のようにします。
    
1. サーバ側でJPEG画像を読み込み、Uint8Arrayに変換します。

```
const imageBuffer = fs.readFileSync(imagePath);
const imageArray = new Uint8Array(imageBuffer);

```

1. imageArrayをJSONでエンコードします。

```
const imageData = JSON.stringify(imageArray);

```

1. クライアントにimageDataを返却します。
2. クライアント側では、 JSONからimageArrayを復元します。

```
const imageArray = JSON.parse(imageData);

```

1. Blobオブジェクトを作成します。

```
const blob = new Blob([imageArray], {type: 'image/jpeg'});

```

1. アンカータグでダウンロードリンクを作成します。

```html
<a href= data:image/jpeg;base64,${btoa(blob)} download="image.jpg">
  Download
</a>

```

1. ユーザーがリンクをクリックするとブラウザによってJPEG画像がダウンロードされます。

この手順でサーバーからUint8Array画像データを受け取り、ブラウザで簡単にJPEG画像としてダウンロードできるようになります。
RESTクライアントはこんなに簡単に作れる

以下のライブラリが便利。

* google-http-client
* google-http-client-gson

Maven Repositoryを見て最新版を持ってくること。

# RESTクライアントを実装する上で必要な機能

* REST APIにHTTPでリクエストを送る
* レスポンスが返ってくるので受け取る
* 受け取ったレスポンスをJSONパーサで展開する

# ここまでの機能がこれだけで実現できる

```java:Main.java （一部）
HttpTransport transport = new NetHttpTransport();
Response response = transport.createRequestFactory()
        .buildGetRequest(url)
        .setParser(new JsonObjectParser(new GsonFactory()))
        .execute()
        .parseAs(Response.class);
```

```java:Response.java （一部）
@Data
public class Response {
    @Key
    private Integer status;
    @Key
    private String message;
    @Key
    private Result[] results;
}
```

郵便番号APIを呼び出してみたサンプルが以下。

https://github.com/cress-cc/restapi-client-example
MariaDB インストール,Testrun

MariaDBのインストール/テストランです。

### Install

```
sudo pacman -S mariadb
```

### サービスの起動

mysqlというユーザーを作ります。

```
sudo systemctl enable mariadb.service
sudo mariadb-install-db --user=mysql --basedir=/usr --datadir=/val/lib/mysql
sudo systemctl start mariadb.service
```

### テストラン

テストランは一般ユーザーだと権限設定などがややこしいのでrootでします。

ログイン

```
sudo /usr/bin/mariadb -u root
```

サンプルデータベース作成

```
CREATE DATABASE sample_db;
USE sample_db;

CREATE TABLE sample_table (
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(255) NOT NULL,
    birthdata INT NOT NULL
);
```

データの挿入

```
INSERT INTO sample_table (name, birthdata) VALUES ('Maekawa Naoko', 19880517);
INSERT INTO sample_table (name, birthdata) VALUES ('Maekawa Taisuke',19670511);
```

データベースの表示

```
SELECT * FROM sample_table;
```

データの削除

```
DELETE FROM sample_table WHERE id=1;
```
【React】トグルスイッチ

以下のように記述するとトグルスイッチを作成できます。

```tsx:ToggleSwitch.tsx
export default function ToggleSwitch() {
  const handleChange = (ev: React.ChangeEvent<HTMLInputElement>) => {
    console.log(ev.target.checked)
  }

  return (
    <div>
      <label className="relative flex cursor-pointer items-center">
        <input
          type="checkbox"
          className="peer sr-only"
          onChange={handleChange}
        />
        <div className="h-7 w-14 rounded-full bg-gray-200 after:absolute after:left-[4px] after:top-0.5 after:h-6 after:w-6 after:rounded-full after:border after:border-gray-300 after:bg-white after:transition-all after:content-[''] peer-checked:bg-blue-600 peer-checked:after:translate-x-full peer-checked:after:border-white" />
        <span className="ml-3 text-gray-900">
          トグルスイッチのサンプル
        </span>
      </label>
    </div>
  )
}


```
k8sにおけるDNS名の解決フローについて

# k8sにおけるDNS名の解決フローについて

## 1. はじめに

**Kubernetesとは**  
Kubernetesは、コンテナ化されたアプリケーションを集中的に管理・運用するためのオープンソースのオーケストレーションシステムです。大規模なシステムにおいて、サービスの可用性やスケーラビリティを保つために、内部のサービス間の通信が重要となります。

**DNSの基本とその重要性**  
DNSは、人が理解しやすいドメイン名をコンピュータが理解するIPアドレスに変換する役目を持つシステムです。Kubernetes内でのリソースの動的な生存期間やIPの変動を考慮すると、DNSの動的な解決は非常に重要です。

## 2. KubernetesのDNS構造

**CoreDNSの役割と位置づけ**  
Kubernetesクラスタ内での名前解決は、CoreDNSという高度にカスタマイズ可能なDNSサーバを使用して行われます。CoreDNSはKubernetesのAPIサーバと通信し、ServiceやPodの情報を取得します。

**クラスタ内のネームスペースとサービスの関係**  
ネームスペースは、Kubernetesリソースを論理的に分割する仕組みです。サービスはこのネームスペース内で動作し、同じネームスペース内のPodにアクセスする際のエントリーポイントとして機能します。

## 3. DNS名の解決フローのステップ

**Podからのリクエスト開始**  
例えば、Pod内から"my-service.my-namespace.svc.cluster.local"という名前のサービスにアクセスしようとすると、まずそのPodの`/etc/resolv.conf`内のDNSサーバ（通常はCoreDNSのIP）に問い合わせが行われます。

**CoreDNSへの問い合わせ**  
CoreDNSは、上述のようなリクエストを受け取るとKubernetes APIサーバから情報を取得し、適切なServiceのClusterIPや、ヘッドレスサービスの場合は関連するPodのIPを返します。

**Serviceとエンドポイントの関係**  
Serviceに関連するPodが複数ある場合、リクエストはエンドポイントというリソースを通じて適切なPodにルーティングされます。これにより、Podが追加・削除された際の動的なルーティングが可能になります。

**実際のIPへのルーティング**  
名前解決が完了し、対象のIPが特定されると、そのIP宛にリクエストがルーティングされ、通信が行われます。

## 4. 実例: ServiceとStatefulSetの利用

**コードサンプルとその解説**  
上記のYAML定義では、nginxのStatefulSetと、それに関連するヘッドレスサービスを定義しています。この構成により、各nginx Podは固有のサブドメインを持ち、他のPodから直接アクセスすることができます。

- 設定のYAMLの紹介  
  ```yaml
  kind: Service
  metadata:
    name: my-nginx-svc
    labels:
      app: nginx
  spec:
    type: ClusterIP
    clusterIP: None
    ports:
    - port: 8080
      targetPort: 80
    selector:
      app: nginx
  ---
  apiVersion: apps/v1
  kind: StatefulSet
  metadata:
    name: my-nginx
    labels:
      app: nginx
  spec:
    serviceName: my-nginx-svc
    replicas: 3
    selector:
      matchLabels:
        app: nginx
    template:
      metadata:
        labels:
          app: nginx
      spec:
        containers:
        - name: nginx
          image: nginx:latest
  ```

- コマンドを使用しての名前解決の確認  
  ```bash
  kubectl exec [POD_NAME] -- nslookup my-nginx-svc.default.svc.cluster.local
  ```

**digコマンドを使った実際の名前解決の検証**  
実際に`dig`コマンドを使用し、Kubernetes内での名前解決がどのように行われるのかを確認します。`dig`コマンドは、DNSの問い合わせを行い、その応答を表示するツールです。このコマンドを使用することで、Kubernetes内での名前解決のフローが具体的にどのように動作しているのかを視覚的に理解することができます。

## 5. まとめと考察

**DNS名の解決フローの重要性とその効果**  
Kubernetesの動的な環境下では、サービスやPodのIPアドレスが頻繁に変動する可能性があります。このような変動に迅速に対応し、確実に名前解決を行う仕組みがあることで、アプリケーション間の通信をスムーズに保つことができます。

従来、手動でのIPやエンドポイントの管理は大変な作業であり、ミスの原因ともなり得ました。しかし、Kubernetesの自動化されたDNS解決の仕組みにより、このような手間やミスのリスクが大幅に削減されました。これは、Kubernetesの強力な機能の一つと言えるでしょう。

Kubernetesのこの機能を深く理解することで、より効率的なアプリケーションの運用やトラブルシューティングが可能になります。本記事を通じて、その仕組みや利点についての理解を深めることができたことを期待しています。
統計ライブラリ pingouin で多変量正規性検定

## 結論
pingouin なら 1 行で簡単に多変量正規性検定ができます。

```python:HZtest.py
import pingouin as pg

pg.multivariate_normality(data, alpha=0.5)
```

## 問題
python で統計解析を行いたいとき、SciPy を使うのがメジャーだと思います。
最初にデータが正規分布に従うかどうかを見ることが多いかと思いますが、SciPy ではシャピロウィルク[1, 2]がよく使われます。

```python:Shapiro.py
from scipy.stats import shapiro

shapiro(data)
```

この方法ですと使えるデータは 1 つであり、2 群以上を見たいときは、各群を中心化し、その和で正規性検定を行う必要があります[3]。
中心化とは、各データから平均値を引くことで残差を求め、中心（平均）を 0 にすることを指します。
```centering.py
import numpy as np
from scipy.stats import shapiro

# データを 2 つ用意
x = np.random.normal(2, 2, 100)
y = np.random.normal(5, 10, 100)

# 平均値
mean_x = np.mean(x)
mean_y = np.mean(y)

# 中心化
centering_x = x - mean_x
centering_y = y - mean_y
centering = np.array([centering_x, centering_y])

shapiro(centering)
```

中心化を行うことで、データの分布は以下の様に（青→赤）変化します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3527076/60dd2042-8522-9b9f-58c6-a33668c4958c.png)

## pingouin
以上の問題に対し、pingouin ですと、Henze-Zirkler test[4] で 1 行で多変量の正規性を検定することができます[5]。

```python:HZtest.py
import pingouin as pd

pg.multivariate_normality(data)
```

試しに、[Kaggle のタイタニックデータ](https://www.kaggle.com/competitions/titanic)を使って見てみましょう。

```Python:titanic.py
import pandas as pd
import pingouin as pg

# データ読み込み
df = pd.read_csv("./titanic.csv")

# Survived と Fare 変数
data = {"Survived": df.iloc[:, 1], "Fare": df.iloc[:, 9]}
data = pd.DataFrame(data)

# パラメトリック検定
pg.multivariate_normality(data, alpha=0.5)
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3527076/22acd2f9-a0e5-26e5-a970-f7683a4dd643.png)

このように、統計量（hz）、P 値（pval）、パラメトリックかどうか（normal）で返ってくるため、3 番目の返り値のみを使って条件分岐なども簡単に作ることもできます。

## 今後
今回は pingouin で多変量正規性検定の方法を見ました！
pingouin は優秀な統計ライブラリですが、まだ歴史が浅く、意外と日本語記事が少ないため、今後もいくつか取り扱っていく予定です。

## 修正
2023/10/15 初歩的なミス（用語の誤り、multivariate_normality の理解）がありましたので、修正しました。ご指摘いただきありがとうございました。
2023/10/17 Shapiro の中心化の話を追加しました。また、コードに一部誤りがあったため、修正しました。
2023/10/24 中心化について一部修正しました。

## 参考文献
[1]https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.shapiro.html
[2]https://python-man.club/nonpara_para_test/
[3]https://biolab.sakura.ne.jp/normality-for-t-test.html
[4]Henze, N., & Zirkler, B. (1990). A class of invariant consistent tests for multivariate normality. Communications in Statistics-Theory and Methods, 19(10), 3595-3617.
[5]https://pingouin-stats.org/build/html/generated/pingouin.multivariate_normality.html#pingouin.multivariate_normality
Raspberry Pi OS でCUIからIPアドレスを固定したい

## したいこと
Raspberry Pi OS でCUIからIPアドレスを固定したい．
調べてみたら `/etc/dhcpcd.conf` を編集するような記事ばっかだが，そんなファイルが無い...．

OSの情報
```bash
$ cat /etc/os-release
PRETTY_NAME="Raspbian GNU/Linux 12 (bookworm)"
NAME="Raspbian GNU/Linux"
VERSION_ID="12"
VERSION="12 (bookworm)"
VERSION_CODENAME=bookworm
ID=raspbian
ID_LIKE=debian
HOME_URL="http://www.raspbian.org/"
SUPPORT_URL="http://www.raspbian.org/RaspbianForums"
BUG_REPORT_URL="http://www.raspbian.org/RaspbianBugs"
```

## 解決策
サークルに書き込んだらNetworkManagerに移行したらしいと教えてもらえた．

https://www.raspberrypi.com/documentation/computers/configuration.html#configuring-networking

ので，`nmtui`で設定．
まだインターネットに接続していなくて日本語が文字化けしていたので`LANGUAGE=en_US`で英語にして操作した．
Flappy：AI統合を単純化するための言語学習モデル（LLM）エージェントSDK

皆さん、こんにちは。今日は皆さんに、AI統合を劇的に簡単にするプロダクションレディの言語学習モデル(LLM)エージェントSDK、Flappyについて紹介します。

## Flappyとは？

Flappyは使いやすい、普遍的に互換性があり、プロダクションレディのソリューションです。これにより、開発者は自分が好むプログラミング言語に関係なく、AIの力を手に入れることができます。

### 主な特長

- **使いやすさ**：FlappyはCRUDアプリケーション開発と同じくらいユーザーフレンドリーに設計されています。
- **プロダクションレディ**：Flappyはコスト効率とサンドボックスセキュリティをバランス良く提供し、商用環境での安定したプラットフォームを提供します。
- **言語に依存しない**：FlappyはPythonが必要でない限り、あらゆるプログラミング言語とシームレスに統合します。

## なぜFlappyなのか？

Flappyは、日々のアプリケーションで大規模な言語学習モデル（LLMs）の力を引き出す鍵です。新しいデータを作り出すだけでなく、既存のデータを変換し、意味のある洞察を得るために合成します。

LLMsの商用価値は、業界特有のユースケースでの応用にあります。しかし、これらのモデルを既存のビジネスシステムに統合することは大きな課題です。ここでFlappyが活躍します。それは、すべての開発者のためのプロダクションレディのLLMエージェントSDKとして機能し、LLMsと他のソフトウェアシステム間のやり取りを容易にします。

## コアコンポーネント

### エージェント機能

Flappyのエコシステムでは、エージェントはLLMの多目的な媒体として動作し、データの構造化、外部APIの呼び出し、必要に応じてLLMが生成したPythonコードのサンドボックス化など、さまざまなタスクを実行します。

### 関数実装の詳細

Flappyはこれらの関数を強化するために独自の実装メカニズムを導入します：

- **ユニークなJSONスキーマ統合**：Flappyは、ユーザーが自分の好みのプログラミング言語で抽象クラスを定義することを可能にします。FlappyはそれらをJSONスキーマに変換します。
- **ASTパーシング**：FlappyはLLMの出力に対して抽象構文木（AST）パーシングを行い、生成されたJSONデータが定義済みのJSONスキーマに厳密に準拠することを保証します。

### コードインタープリタ

Flappyのコードインタープリタは、LLMが生成したPythonまたはTypeScriptコードを実行するための安全な環境を提供します。これはサンドボックス化された安全機能を提供し、ランタイムエラーや潜在的なセキュリティ脆弱性を減らします。

### LLM抽象化レイヤー

Flappyは、さまざまなLLMのための抽象化レイヤーを提供します。この機能により、ユーザーは簡単に異なるLLM間を切り替えたり、フォールバックLLMを指定したりできます。

Flappyは、開発者が言語に依存しない方法でLLMベースのアプリケーションを構築することを可能にします。今日からFlappyと一緒にAIの巨大な可能性を引き出し、自分の好きなプログラミング言語でAIを活用しましょう。

ソースコードは[こちら](https://github.com/pleisto/flappy)でご覧いただけます。是非、ご覧になって、この革新的なプロジェクトに貢献してみてください。