OmniAICreator/Qiita-1.07M huggingface dataset:
styled-componentsが急に使えなくなった時の対処法

ことの起こり
---
React / TypeScript / Vite で新規ファイルを制作して進めようとし、いつもお世話になっている styled-components をインストールしようとしたところ。以下のような状態になりました。

![001.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3368730/6b79e572-f811-76e5-a6d3-5469a2b407df.jpeg)

Cannot read ....? 'edgesOut' ....? A complete .....? ん。。。ホワッツ・イズ・ディス？？？

まぁいいや！と進めてファイルを表示してみたところ「styled-components ってインストールしてます？？」的なことを指摘されました。（当然ファイルは機能せず）

![スクリーンショット 2023-05-15 13.22.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3368730/9a51988b-c34b-06f6-efba-435106a37563.png)


そこで、styled-components　のサイト（ https://www.npmjs.com/package/@types/styled-components ）へ確認しに行き、最新？のインストール方法の記述を試してみました。
```
npm install --save @types/styled-components
```

その後`npm list`で確認したところ、インストールはたしかにされていました。

![002jpg.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3368730/a7796d1d-d576-01f8-9e6d-2563178f3e80.jpeg)


が、やはりエラーが出て動かない。。。なぜだ。

エディターのターミナルが教えてくれていた「自PC内のここにあるログを見なさい（最初の画像にあった A complete ...の部分）」的なところを見に行きましたが見方もよく分からず。実力不足（泣）
とりあえず、そのログ内の行先頭に "error" という単語が出ているところを調べて、最初に表示されていたエラーがこれでした。
```
npm ERR! Cannot read properties of null (reading 'edgesOut')
```
ちなみに、この段階でも頭の中は？でいっぱい、大混乱状態です。

そこで当該コードをそのままコピペしてグーグル先生のもとへ。
目ぼしいサイトに記述されていた下記コード（3番目）で無事にinstall？でき、動くようにもなりました。

```
1：V5、、、npm install styled-components@5.3.10またはを使用する
2：糸を使用する、yarn install styled-componentsまたは
3：ベータ版を使用するには、npm install styled-components@latest
```
先程お伝えしたとおり、私は 3 で解決しました。

私を助けてくださったサイト様はこちらです。

[npmエラー! null のプロパティを読み取ることができません (「edgesOut」を読み取る)](https://stackoverflow-com.translate.goog/questions/70810819/npm-err-cannot-read-properties-of-null-reading-edgesout?_x_tr_sl=en&_x_tr_tl=ja&_x_tr_hl=ja&_x_tr_pto=sc)
本当にありがとうございました。


もし「styled-components がいつものように動かない！」という方がいましたら、
上記をお試しください。

ちなみに
---
先程のサイトでは、更新が4日前（5/11）だったので、結構最近出てきたエラーなのかな？という印象です。
もし、他の方法もあるよー！という方はお手間でなければ教えていただけますと嬉しいです。
あと、この記事の内容がどこかで既出とかだったらすみません。

読んでいただき、ありがとうございました！
DenoでSHA-256ハッシュ

毎回調べてる気がするので。

Denoで文字列のSHA256ハッシュ値を求める方法について。

# DenoでSHA-256ハッシュ

以下の関数`sha256`を使うと、文字列のSHA-256ハッシュを得ることができる。

```ts
import { toHashString } from "https://deno.land/std@0.188.0/crypto/to_hash_string.ts";

const encoder = new TextEncoder();
async function sha256(input: string): Promise<string> {
  const data = encoder.encode(input);
  const digest = await crypto.subtle.digest("SHA-256", data);
  return toHashString(digest);
}
```

まず`encoder.encode`で文字列を`Unit8Array`に変換する。次に`crypto.subtle.digest`でSHA256ハッシュを得る。最後に、`toHashString`で16進数文字列表現を得る。
[Delphi][小ネタ] TIniFile に class helper を生やすと便利だよという話

# IniFile
随分前に[ IniFile を使って全プラットフォームのデータを保存する話](https://www.slideshare.net/pik256/inifile)を書きました。
[ソースはこちら](https://github.com/freeonterminate/delphi/tree/master/FMX.IniFile)

それはそうと、[TIniFile](https://docwiki.embarcadero.com/Libraries/ja/System.IniFiles.TIniFile) には [ReadInteger](https://docwiki.embarcadero.com/Libraries/ja/System.IniFiles.TCustomIniFile.ReadInteger), [ReadString](https://docwiki.embarcadero.com/Libraries/ja/System.IniFiles.TIniFile.ReadString) などのメソッドがあるものの [TRect](https://docwiki.embarcadero.com/Libraries/ja/System.Types.TRect) や [TRectF](https://docwiki.embarcadero.com/Libraries/Alexandria/ja/System.Types.TRectF) といった record には対応していません。

ということで、その IniFile に [class helper](https://docwiki.embarcadero.com/RADStudio/ja/%E3%82%AF%E3%83%A9%E3%82%B9_%E3%83%98%E3%83%AB%E3%83%91%E3%81%A8%E3%83%AC%E3%82%B3%E3%83%BC%E3%83%89_%E3%83%98%E3%83%AB%E3%83%91%EF%BC%88Delphi%EF%BC%89) を使ってそれらを読み書きできるメソッドを生やすと便利です。

# 例

↓は [TMemIniFile](https://docwiki.embarcadero.com/Libraries/ja/System.IniFiles.TMemIniFile) に class helper を生やす例です。

```delphi
unit PK.Utils.IniFileHelper;

interface

uses
  System.Types,
  System.IniFiles;

type
  TIniFileHelper = class helper for TMemIniFile
  private const
    RECT_LEFT = '_left';
    RECT_TOP = '_top';
    RECT_RIGHT = '_right';
    RECT_BOTTOM = '_bottom';
  public
    function ReadRectF(
      const ASection, AName: String;
      const ADefault: TRectF): TRectF;
    procedure WriteRectF(const ASection, AName: String; const AValue: TRectF);
  end;

implementation

function TIniFileHelper.ReadRectF(
  const ASection, AName: String;
  const ADefault: TRectF): TRectF;
begin
  Result.Left := ReadFloat(ASection, AName + RECT_LEFT, ADefault.Left);
  Result.Top := ReadFloat(ASection, AName + RECT_TOP, ADefault.Top);
  Result.Right := ReadFloat(ASection, AName + RECT_RIGHT, ADefault.Width);
  Result.Bottom := ReadFloat(ASection, AName + RECT_BOTTOM, ADefault.Height);
end;

procedure TIniFileHelper.WriteRectF(
  const ASection, AName: String;
  const AValue: TRectF);
begin
  WriteFloat(ASection, AName + RECT_LEFT, AValue.Left);
  WriteFloat(ASection, AName + RECT_TOP, AValue.Top);
  WriteFloat(ASection, AName + RECT_RIGHT, AValue.Right);
  WriteFloat(ASection, AName + RECT_BOTTOM, AValue.Bottom);
end;

end.
```

# 使い方

これを使うと↓のように Form の位置を簡単に保存できます。

```delphi
uses
  PK.Utils.IniFileHelper; // Helper を読み込みます

procedure TForm1.Form1Create(Sender: TObject);
begin
  var Ini := TMemIniFile.Create('ファイル名', TEncoding.UTF8);
  try
    BoundsF := Ini.ReadRectF('セクション名', '名前', BoundsF);
  finally
    Ini.Free;
  end;
end;

procedure TForm1.Form1Destroy(Sender: TObject);
begin
  var Ini := TMemIniFile.Create('ファイル名', TEncoding.UTF8);
  try
    Ini.WriteRectF('セクション名', '名前', BoundsF);
  finally
    Ini.Free;
  end;
end;
```

# おわりに
TIniFile に限らず class helper を使って良く使う機能を生やしておくと便利です！
AI画像投稿サービス 『BashDAO』をリリース

<b>セリフやモノローグ</b>を簡単につけられる<b>AI画像投稿サイトBashDAO</b>をリリースしました。

最近AIやWeb3はホットですよね。
そこで、AI画像投稿するDAOライクなサービスBashDAO(ばっしゅだお）を作りました。
https://bashdao.com/

## BashDAOの３つの特徴
1. セリフやモノローグを付けてスライドショーや漫画っぽくできます
1. 各画像ごとに課金支援設定を細かくできます
1. トークン運用でReadユーザーにもメリットを提供します

# セリフやモノローグの簡単追加
BashDAOでは１回で複数枚の画像を投稿できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398972/13b18fdc-2a66-027a-0cf6-4024a507181b.png)

各画像は編集によって簡単にセリフや吹き出しをつけることができます。
![画像1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398972/a0c4fa1f-7491-a94e-ecf2-fb37702e60ea.png)
下記LINKからセリフ機能を見れます。
https://bashdao.com/ogp?reviewId=s3PQsn2W0LgWvEB8deEw&imageId=00009-4154303507.png

セリフやモノローグをつけるのはAI画像をアップロードしやすくする目的です。
AI画像生成で誰でも美しい画像が作れる玉虫色の技術か思うかもしれませんが、現状はそうでもないです。
Machine Specをガンガン上げて、i2iで高画質化して、layerを分けて、parmeterをいじって、、、みたいなオーディオ屋さんがやるような作業をしないと良い画像は生成できません。資本力＋技術＋アートの世界です。
(M1 mackbookで512 x 512をHires.fixして生成すると１枚60分かかり、他の作業なにもできないくらい爆熱になります。)

そんな、資金と技術とアートのAI画像で戦えなくても、
<b>崩れた画像でもコメントをつけて笑って供養できればいいじゃない</b>という敷居を下げる気持ちでセリフ機能を導入しています。
もちろん、研鑽された美しい画像もウェルカムです！

# 各画像ごとに課金支援設定
画像ごとの課金設定できます。
画像20枚を投稿すると仮定して、5枚だけ有料モードにするなど細かく画像設定可能です。
設定した画像はモザイクがかかります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398972/a5f41a17-3c11-b389-eaed-847d1979966f.png)
#### Pointって？
課金で取得できる有料ポイントです。
有料ポイントで支援するとロックのかかった画像を見ることができます。
支援されたポイントは画像投稿者に還元されます。
有料ポイントは将来的に換金可能です。現状はAmazon gift券に換金で対応予定。
#### Tokenって？
Loginした状態で画像を見るともらえる無料ポイントです。
Token/Point支援者のみ表示可能になっている画像はTokenを支援することで閲覧できます。

# TokenでDAOっぽく
BashDAOではTokenという概念を導入してDAO風(自立分散組織)にしてます。
TokenはToken配布期間中にLoginして画像をLike、SKIPして見ることで取得できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398972/da1b356d-c5c8-0a33-755f-5360ec914c72.png)
Tokenは読者がクリエータを支援したり、Token/Point支援者のみ閲覧可能が画像の閲覧に使用できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398972/32b9a5a6-b486-1d3f-65d1-5c815c59b1ab.png)
現状はサービス内でのTokenの位置づけは弱いのですが、
Token配布期間が終わった画像はToken支援者しか閲覧不可といった
BashDAOを利用してToken所有してくれている方が利益を受ける仕組みを検討していきたいです。
AI業界は法整備が始まったばかりで荒れるので、
一定期間経つとToken所有者しか閲覧できないいった機能は荒れ防止には良いかもしれませんね。

# まとめ
AI画像にセリフやモノローグを加工してアップロードできるBashDAOを始めました！
これからAI画像業界は盛り上がってくると思いますので、ぜひ使ってみてください！
AI画像業界もweb3のDAO業界もまだまだ変遷していくと思うので、時流に合わせてサービスの形は変えていこうとは思います。
ぜひ、使ってみてぜひフィードバックもらえると嬉しいです。

# 実装について
・ Next.js
・ React Typescript
・ Bulma.css
・ Firebase　（本番x1, テストx1)
・ Authentication (認証・認可）
・ Cloud Firestore （Data保存）
・ Storage (OGP, Profile保存）
・ Cloud Functions

# Typescriptは神
今回始めてTypeScriptを使って開発しましたが、型宣言は神ですね。
propertyのヌケモレで発生するバグは発見も難しく、
開発規模がある程度大きくなるといつも悩まされていましたが、TypeScriptにすることで一気に解決です。最高です。
正直に言うと、
最初はtypescriptに怒られ続けて、イラッとしましたが今では相棒です！
コードでViewを表示させるときにViewController をUINavigationControllerに埋め込みさせたい

# はじめに
コードでViewを表示させるときにViewController
をUINavigationControllerに埋め込みさせたいときのメモ

# Storyboardを使わないプロジェクトの設定をします
やり方はこちらの記事どうぞ.
https://qiita.com/Imael/items/e908aef1e6fc077f29fc

# コードです
```swift
import UIKit

class SceneDelegate: UIResponder, UIWindowSceneDelegate {

    var window: UIWindow?


    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {

        guard let scene = (scene as? UIWindowScene) else { return }
        let window = UIWindow(windowScene: scene)
        let vc = ViewController()
        // NavigationControllerのルートビューにする
        let nvc = UINavigationController(rootViewController: vc)
        window.rootViewController = nvc
        window.makeKeyAndVisible()
        self.window = window
    }


}
```
UINavigationControllerクラスのrootViewControllerイニシャライザーにViewContorollerを渡します!

https://developer.apple.com/documentation/uikit/uinavigationcontroller/1621858-init
zipファイルにパスワードをつける方法（Mac）

# はじめに
Macでzipファイルにパスワードを付ける方法です。

# 手順
- ターミナルを開き、対象のファイルがあるディレクトリに移動する。
```terminal:terminal
    # （例）zip化したい元のファイルが、desktop/jobというディレクトリにある場合は以下のように入力
    cd ~/desktop/job
  ```
- 以下のコマンドを叩く。
```terminal:terminal
    # zip -e [zip後のファイル名] [zip化したいファイル名]
    # 以下に例を示す（resume.pdfというファイルを、resume.zipというファイルにzip化してパスワードを付けたいとき）
    zip -e resume.zip resume.pdf
  ```
- 上記のコマンドを実行すると、Enter passwordという表示が出るので、任意のパスワードを設定する（入力中にパスワードは表示されないが、ちゃんと入力はできているので安心してください！）
- Verify passwordも同様のものを入力する。
- adding: resume.pdf(~~%)という表示が出てれば大丈夫！
- zipファイルを開き、無事パスワード設定できているかを確認する。

# 参考
https://www.youtube.com/watch?v=GrDj4U5hqek
【Kotlin】Companionな拡張関数をデータクラスなどに生やす

### データクラス側

```kotlin
data class Product(
   val title: String
) {
   // 空のCompanionオブジェクトがあれば拡張関数が作成できる
   companion object {}
}
```

### 拡張関数を作る側
```kotlin
class ExpandMethod {
  // {className}.{Companion}.{methodName} () {}
  fun Product.Companion.create() {
      // 処理
  }
}
```
個人開発でFlutterを使って20個以上アプリを開発したので、個人開発の三大原則（コツ）を共有します

# こんにちは
初めまして！Qiitaに投稿するのは初めてなので、軽く自己紹介。

たみな涼介と申します。別に本名で活動しても問題ないのですが、この名前の方がネット上で知られるようになったのでこのままにしています。

現在は自社開発企業に勤めながら、個人でアプリを開発しています。メインはiOSのアプリ屋さんなのですが、Flutterを学んでからはAndroidにも興味が持てるようになりました。本当にいい時代になりましたね。


・開発アプリは以下で確認してみてください！

https://lit.link/taminaryousuke

## 個人開発を始めたきっかけ
元々シナリオライターとして活動していたのですが、アプリ開発に興味を持ち始めてからとある企業に就職し、アプリ開発の作法を学んでいます。

しかしそれだけではアプリ開発者としての成長が見込めないと思い、個人でもアプリを作ることにしました。

今ではすっかり個人開発の魅力に惹き込まれてしまい、毎日カタカタとキーボードを叩き続ける生活を送っています。

そんな私が**個人開発を通じて学んだ3原則**をお伝えしたいと思います。

# 個人開発で大切なこと
### 1. つくったらとにかく即リリース！悩まない！
アプリ開発に限らず個人活動にありがちなのが、「いつまでも完成しない病」にかかってしまうことです。
「本当にこんなアプリにユーザーがつくのだろうか…」
「もっとこうした方が便利で優れたアプリになるんじゃ…」
なんて考え始めた結果、そもそものアプリのコンセプト自体に疑問を感じ始めちゃったりします。

ここだけでも改修しようかな、と始めた作業。気づいたら夜の10時半。
思わぬ不具合が発生してしまい、ChatGPTやGoogle先生に聞いてもよくわからない。
簡単な修正のつもりだったからGitにコミットしてないし、ロールバックも出来ないなぁ。。

…はぁ…個人開発って、めんどくさ。
これだけは絶対に避けましょう。


個人開発者にとって、モチベーションは命です。焦りによって生じた不必要なアップデートは、開発者のライフをじわじわと削ります。さながらステルスロックを喰らったリザードンのようなもの。微力とあなどるなかれ、効果は抜群です。

アプリの価値を決めるのは、あくまでのユーザーであって、私たち個人開発者ではありません。

自分では思いつかなかった使い方をしてくれることも少なくありません。
まずはある程度土台が出来上がったら、まずは真っ先にストアへリリースすることをおすすめします。
![スクリーンショット 2023-05-15 12.09.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653721/97653357-29ff-9c41-a44b-9e6e5ae84c9b.png)

:::note info
個人開発の原則①
・迷うな！ためらうな！とにかく世に出せ！
:::

### 2. 期待しない
「アプリをリリースしたら、広告で儲けて…」
「まだ市場にこんなアプリはないから、きっと一気に拡散されてまずは100ユーザーくらいに…」
といった**期待はやめましょう**。公開してから一ヶ月以上はまともにユーザーがつかないと思った方が良いと思います。過度な期待はモチベ低下につながります。（宣伝に自信があったり、営業活動の算段がついている場合は別です！）

そのアプリがどれだけ優れていたとしても、ユーザーはそう簡単にアプリへ辿り着くことは出来ません。まだ知らないアプリの名前をストアで検索することなどあり得ませんし、ストアの検索アルゴリズム的にも新規アプリは圧倒的に不利です。

まずはストアに出してみて、ゆっくりリリースの喜びを味わう。
そこからどう宣伝していくかを、じっくりと考えていくくらいがちょうどいいと思います。

:::note info
個人開発の原則②
・じっくりと腰を据える。焦らない。
:::

### 3. お問い合わせフォームとレビュー導線は必ず用意する
これは私がとても反省していることなので、みなさんには同じ轍を踏んで欲しくないです。それは「お問い合わせフォーム」と「レビューの導線」を用意しておくこと。

簡単なもの構いません。適当にボタンを配置してあげるだけでもOKだと思います。
お問い合わせフォームについては、GoogleFormを用意してそれを外部ブラウザやWebViewで表示してあげるだけでも十分です。

ユーザーのリアクションは、個人開発者にとっての命（二つ目）です。ストアレビューの評価によって、ストアの検索順位に影響が出ます。ユーザーがどのようにアプリを使っているかを知ることで、今後の方向性を検討することが出来ます。ユーザーが送ってくれる感想が、モチベーションにもつながります。

ポケモンで例えるところの「げんきのかけら」。ひんしになった個人開発者も、ユーザーのリアクションで命を吹き返します。そこまで工数がかかるものでもありませんし、一度作成してしまえば別のアプリで使い回してもOKなので楽ちんです。

![スクリーンショット 2023-05-15 12.11.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653721/f741e9f6-398c-82e1-90ea-943069e1a404.png)
こんなシンプルなフォームでも、毎月1~2件程度のご意見が届きます。
参考になる意見はもちろん、感謝の言葉だけを伝えてくれる方もいます！

:::note info
個人開発の原則③
・ユーザーのリアクションはとても大事
:::


### おまけ
最近アプリを通じてたくさんの方と知り合えて、日々が楽しく思えるようになりました。

コーディングが楽しい、アイディアを形にするのが嬉しいというのももちろんですが、生活がより豊かになるという側面が個人開発にはあると思います。色々なモノの見方、視点が変わって面白いです。

Qiitaの投稿、いかがでしたでしょうか？

評判良さそうであれば、今後も開発したアプリについてや開発技術の情報を発信したいと思っています。
皆さんのリアクションが**命**なので、ぜひコメント等してもらえると嬉しいです！


https://pont.co/u/taminari
SpreadJSでフィルタ関連のコーディング方法

SpreadJSでフィルタ関連のコーディング方法です。
SpreadJSのバージョンは15です。

## その①フィルタをコードから適用する方法





```javascript:filter.js
//フィルタ条件の作成
const condition = new GC.Spread.Sheets.ConditionalFormatting.Condition(
GC.Spread.Sheets.ConditionalFormatting.ConditionType.textCondition,
{
	compareType: 0, //「0」は↓のexpextedの文言と一致しているかどうかの比較
	expected: "filterPhrase" //フィルタ対象としたい文言
}
);

// フィルタをインスタンス化しているイメージ
const rowFilter = activeSheet.rowFilter();

// フィルタの適用
const FILTER_TARGET_COLUMN = 1
rowFilter.addFilterItem(FILTER_TARGET_COLUMN, condition);
rowFilter.filter();
```
参考リンクは[こちら](https://developer-tools.zendesk.com/hc/ja/articles/5485652152079-%E3%82%B3%E3%83%BC%E3%83%89%E3%81%A7%E3%83%86%E3%83%BC%E3%83%96%E3%83%AB%E3%82%92%E3%83%95%E3%82%A3%E3%83%AB%E3%82%BF%E3%83%AA%E3%83%B3%E3%82%B0%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95)

https://developer-tools.zendesk.com/hc/ja/articles/5485652152079-%E3%82%B3%E3%83%BC%E3%83%89%E3%81%A7%E3%83%86%E3%83%BC%E3%83%96%E3%83%AB%E3%82%92%E3%83%95%E3%82%A3%E3%83%AB%E3%82%BF%E3%83%AA%E3%83%B3%E3%82%B0%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95

## その②適用されているフィルタを保存する方法

```javascript:filter.js
// フィルタをインスタンス化しているイメージ
const rowFilter = sheet.rowFilter();

//フィルタ情報を保持するリスト
let filterList = []

//すべての列数のフィルタを取得
for(let i=0;i<sheet.getColumnCount();i++){
	const res = rowFilter.getFilterItems(i)
	filterList.push(res)
}

```

## その③保存したフィルタを適用する方法

```javascript:filter.js

//その②で取得したフィルタ情報を適用する

// フィルタをインスタンス化しているイメージ。すでにインスタンス化済みなら不要
const rowFilter = sheet.rowFilter();

for(let i=0;i<sheet.getColumnCount();i++){
    //filterList[i]はフィルタの条件の数だけ存在するリストなので、
    //filterList[i].lengthの分だけ適用するとすべてのフィルタが適用される
    for(let j=0;j<filterList[i].length;j++){
        //第一引数は適用する列、第二引数は適用するフィルタ
    	rowFilter.addFilterItem(i, filterList[i][j]);
	}
}

//フィルタリングの実行
rowFilter.filter()

```


### 所感
grapeCityのサポートにフィルタの保存と復活情報を尋ねたけど、サポートは「案内できない」という回答だったので自力で実装しました。
Excelにおいて、全体から特定の行のみ抽出する方法

Excelに記載してあるもののうち、特定の文字から始まる行だけ抽出したい時に使用する関数

シートの中でXXX文を抽出する
```
=IFERROR(INDEX(B:B,1/LARGE(INDEX((ISNUMBER(FIND("XXX",B:B)))/ROW(B:B),0),ROW(A1))),"")
```

使用方法
新規でExcelを開く
B列の2行目にメインの内容を貼る
同じシートの2行目の右側(AA列など)に上記の関数を貼り付ける
関数を貼り付けたセルを左クリックし下に引っ張る
すると、特定の文字から始まる行だけが抽出される
matlabでオイラー法による微分方程式の解法

# はじめに
　matlabで今回、オイラー法による微分方程式の解法を実装しなさいとの課題が大学院で出ていたので、同じような課題の人もいるんじゃないかと思ってn番煎じだとは思いますが記載します。
　コードは下記に挙げているのでよかったらどうぞ！


https://github.com/murakamixi/matlab_Euler_method


## そもそも、オイラー法ってなに？

### オイラー法：初期値問題の数値解法

オイラー法は初期値問題（特定の時点での値とその変化率を表す微分方程式が与えられている問題）を数値的に解く最も単純な手法の一つです。

オイラー法は以下のように機能します：

1. 初期設定：解を探している微分方程式と初期値（特定の時点での値）を入力します。
2. 時間ステップの設定：解を見つけたい時間範囲を小さな時間ステップに分割します。
3. 値の更新：各時間ステップにおいて、微分方程式の右辺（つまり、変化率）を使用して、その時点での値から次の時点での値を予測します。


数学的には、オイラー法は以下の反復公式によって定義されます：
```
y_{n+1} = y_n + h*f(t_n, y_n)
```
ここで、
- `y_{n+1}` は次のステップでの解の近似値，
- `y_n` は現在のステップでの解の近似値，
- `h` は時間ステップの大きさ（一定），
- `f(t_n, y_n)` は微分方程式の右辺を表す関数。


オイラー法は直感的で実装が容易な一方で、誤差が累積しやすく、精度がそれほど高くないという欠点があります。したがって、より複雑な問題に対しては、より高度な手法（例えばルンゲ・クッタ法）がしばしば用いられます。


# オイラー法: 微分方程式の数値解法

オイラー法は初期値問題を解くための最も基本的な数値解法です。初期値問題とは、微分方程式とその解の初期値が与えられ、それに基づいて解を見つける問題です。

## オイラー法の基本概念

オイラー法は、微分方程式の解を近似するための逐次的な手法です。与えられた微分方程式と初期値から始めて、小さな時間ステップで進むことで、解の近似値を生成します。

具体的には、時間ステップ `h` と初期値 `y(t0)=y0` が与えられたとき、次のステップ `t0+h` における解 `y(t0+h)` の近似値 `y1` は次の式で計算されます:

```matlab
y1 = y0 + h*f(t0, y0)
```

ここで、`f(t, y)` は微分方程式の右辺を表します。

## オイラー法のサンプルプログラム（MATLAB）

以下に、オイラー法を使用して微分方程式 `dy/dx = y - t^2 + 1` を解くMATLABプログラムを示します。この微分方程式の解は `(t+1)^2 - 0.5*exp(t)` です。

```matlab
% ODEの右辺の関数と真の解の関数の定義
f = @(t, y) y - t^2 + 1.0;
g = @(t) (t+1)^2 - 0.5*exp(t);

% オイラー法の実行
[t, w, error] = eulerODE2(f, g);

% 近似解と真の解のプロット
plot(t, w, 'r', t, g(t), 'b');
legend('Euler Approximation', 'True solution');
xlabel('t');
ylabel('y');

% 誤差のプロット
figure;
plot(t, error);
xlabel('t');
ylabel('Error');
```

```matlab
function [t, w, error] = eulerODE2(f, g)
    % 入力：
    % f - ODEの右辺の関数
    % g - 真の解の関数
    
    % 出力：
    % t - 時間ベクトル
    % w - 近似解ベクトル
    % error - 真の解との誤差ベクトル
    
    % ユーザーからの入力を受け取る
    a = input('Enter the start of the interval, a: ');
    b = input('Enter the end of the interval, b: ');
    alpha = input('Enter the initial value at a, alpha: ');
    N = input('Enter the number of steps, N: ');
    
    h = (b-a)/N; % ステップ幅
    t = a:h:b; % 時間ベクトル
    w = zeros(1, N+1); % 近似解を格納するベクトル
    w(1) = alpha; % 初期値の設定
    
    % オイラー法
    for i = 1:N
        w(i+1) = w(i) + h*f(t(i), w(i));
    end
    
    % 真の解との誤差
    true_sol = g(t); % 真の解ベクトル
    error = abs(true_sol - w); % 誤差ベクトル
    
end
```



これはオイラー法の基本的な説明と実装例です。より複雑な微分方程式や他の数値解法についても同様の方法で解くことができます。

### 出力はこんな感じ

**近似解と真の解のプロット**

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235810/aa7dccd7-f3de-9688-810f-23887af3a57c.png)

**誤差のプロット**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235810/4c923b63-cc87-22a3-9555-1bdad8f12e63.png)

## 最後に
　matlab初めて初心者で綺麗なコードではないでしょうが、誰かの役に立てば幸いです。

　pythonでの実装は下記の方のがわかりやすくいいかと思います。


https://qiita.com/Sunset_Yuhi/items/fb574091fe380e677735
ライントレースを使ったアイテムを取得する方法

今回はライントレースを使ったアイテムを取得する方法をご紹介します。

『カメラを原点にしたライントレースを飛ばします』

①サードパーソンのテンプレートを起動します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3123774/c4123561-c25a-0c59-d836-6a356c8301cc.png)

②アクタクラスを作成してStatick Meshに『1M_Cube』を追加します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3123774/368bee3f-fa3c-7d26-7ce7-c325d4ca0ee1.png)

③キャラクターであるメッシュのクラスを開きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3123774/9c962b5b-f3af-2b7b-0f49-add24d10974a.png)

④右手にアイテムをアタッチしたいのでhand_rを右クリックしてAdd Socket後に追加された新規ソケットであるhand_rSocketにプレビューメッシュを追加してアイテムのTransform情報を編集します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3123774/b1e08a5f-05dd-7790-6b37-66ce51d16312.png)


⑤キャラクターブループリントでライントレースを作成後に当たり判定を確認してアイテムのクラスだったらキャラクターにアタッチする処理をくんでいます。
AttachActorToComponentのSocket Name入力値は④で追加した新規ソケット名になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3123774/02997170-41bf-945a-683e-e581eacb1dc7.png)

⑥ライントレースを飛ばしてアイテムを取得したところ右手にうまくアタッチされました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3123774/2d71560d-fd73-8f1b-a551-7da55f663463.png)

以上になります。
AudioWorklet で Uncaught (in promise) DOMException: The user aborted a request が出る問題

## はじめに

AudioWorklet を使った時に`Uncaught (in promise) DOMException: The user aborted a request`のエラーではまったので、書いてみました！！

## まず nextjs でプロジェクトを作成

今回は nextjs のプロジェクトで起きたので nextjs で書きます。

- [下記で立ち上げてください。](https://nextjs.org/docs/pages/api-reference/create-next-app)

```
npx create-next-app@latest
```

## AudioWorklet の準備

MDN を参考にして、AudioWorklet を触っていきます。

- [AudioWorklet](https://developer.mozilla.org/ja/docs/Web/API/AudioWorklet)

- [下記のコードは MDN のコードを参照してます。](https://developer.mozilla.org/ja/docs/Web/API/AudioWorkletProcessor)

white-noise-processor.js

```
class WhiteNoiseProcessor extends AudioWorkletProcessor {
  process(inputs, outputs, parameters) {
    const output = outputs[0];
    output.forEach((channel) => {
      for (let i = 0; i < channel.length; i++) {
        channel[i] = Math.random() * 2 - 1;
      }
    });
    return true;
  }
}

registerProcessor("white-noise-processor", WhiteNoiseProcessor);

```

hooks.ts

```
 const audioContext = new AudioContext();
 await audioContext.audioWorklet.addModule("white-noise-processor.js");
 const whiteNoiseNode = new AudioWorkletNode(audioContext, "white-noise-processor");
 whiteNoiseNode.connect(audioContext.destination);
```

## 問題

white-noise-processor.js を hooks.ts と同じディレクトリにしていたけど、` Uncaught (in promise) DOMException: The user aborted a request`というエラーが出て叩けない。。。

## 解決策

- public フォルダーに`AudioWorkletProcessor`で書いたファイルを置く。
- 恐らく、サービスワーカーのため public フォルダーに置く必要がある。

## 余談

- public フォルダーに置いてもアクセス出来ない時は先頭に/を書くと出来る場合がある。
  `await audioContext.audioWorklet.addModule("white-noise-processor.js");`
  `await audioContext.audioWorklet.addModule("/white-noise-processor.js");`
読書研修ーWebを支える技術　第11章microformats

## RDFとmicroformats
### RDFの場合
プログラムで処理可能な情報の意味を記述するための仕様としてRDF です。RDFでは「トリプル」(Tiple)と呼ばれる主語、述語、目的語の3つの組を使って、Web上のリソースにメタデータを与え、プログラムがリソ-スの意味を処理できるようにします
<strong>RDFの問題点：</strong>
・記述が複雑になりがち
・統一的な記述がしづらい
・対象データとは独立したメタデータが必要

### microformatsの場合
microformats はもとのHTML文書の`<a>`要素に必要最低限の情報追加しているだけです。RDFと比べると記述量が減っています。また、RDFは対象データとは別の独立したメタデ-タとして記述しなければなりませんか、microformats はもとのHTMLに埋め込まれています。

## microformatsの標準化
<strong>標準化済みのmicroformats
|名前| 概要 |
|:-:|:-:|
| hCalendar  | イベント情報。ベースはRFC 2445(icalendar)  |
| hCard  |  プロフィール情報 ,ペースは FC 2426(vCard)|
|  rel-license | ライセンス情報  |
|  rel-nofllow |  スバムリンク防止 |
| rel-tag  |  ソーシャルタグ |
|  Vote Links |  リンク先への賛否 |
| XFN(XHTML Friends Network)  |  友人関係 |
| XMDP(XHTML Meta Data Profiles)  |  microformats自体のスキーマ |
| XOXO(Extensible Open XHTML Outlines)  | アウトラインフオーマット |
			
## microformatsの分類
### elemental microformats
リンク関係(`<a>`要素や`<link>`要素のrel属性)を使ってメタデータを表現するフォーマット	
|名前| 概要 |
|:-:|:-:|
|  rel-license | ライセンス情報  |
|  rel-nofllow |  スバムリンク防止 |


### compound microformats
主にcass属性を使って階層構造のあるメタデータを表現するフオーマット
|名前| 概要 |作用　|
|:-:|:-:|:-|
| hCalendar  | イベント情報 ||
| hAtom  |  更新情報 |hAtomを使うと、Webページに含まれているエントリの更新日時やパーマリンクといったメタデータを、プログラムから処理可能な形で埋め込めます。



## microformatsとRDFa
### microformatsの問题点
microformats ではcass属性やrel属性の値だけでメタデ-タを特定するため、もしたまたま同じ値のclass属性やrel属性を持ったWebペ-ジがあった場合、プログラムが誤判定を起こしたり、同じ属性值を持った別の microformatsが作れなくなったりするのです。
### RDFaでの解決(と残る問題点)
RDFaの見た目は microformatsとほとんど同じですが、microformatsが持つ名前の衝突問題をXMLの名前空間で解決します。
#### RDFаの問題:
* せっかくシンプルな仕様を目指していたはずのmicroformatsが名前空間を使ったとたんに複雜化してしまう点です。
*  1つは名前空間を前提としているため XHTML でしか利用できな点です。いろいろな事情でHTMLを利用したいケ-スがあると思いますが、その場合RDFаは使えません。
## microformatsの可能性

#### hAtom/xFolkとLDRize/AutoPagerize
<strong>LDRize</strong>はWebページをlivedoor Readerのような操作性で閲覧できる Firefox/Greasemonkeyのユーザスクリプトです。
<strong>AutoPagerize/strong>も同様にユーザスクリプトで、検索結果ページやニュース記事など複数に分割されているWebページにおいて、現在のペ-ジの下に自動で次のペ-ジを继ぎ足してくれます。
LDRizeとAutoPagerizeは、microformatsのそんな可能性を示してくれたと思います。

## リソ-スの表現としてのmicroformats
#### プログラム用に別のWeb APIを提供するスタイルには、弱点:・ 
* Web サ-ビスと Web API で提供する機能が異なってしまいがち 
* 開発規模の増大に伴うメンテナンス性の低下
* WebAPIに必要な技術の習得コスト
#### microformatsはこれらの弱点を補ってくれるリソース表現です。
【IOS】Universal Linksとapple-app-site-associationの活用


こんにちは！

本記事は、iOS開発における非常に便利な機能、**Universal Links**とその設定ファイル**apple-app-site-association**について説明します。

これらの機能を使えば、あなたのアプリとウェブサイトがシームレスに連携できます。

## Universal Linksとは？

Universal Links（ユニバーサルリンク）とは、iOS 9以降で利用可能な機能です。
ユーザーがウェブリンクをタップしたときに、そのリンクがあなたのアプリと関連付けられていれば、そのアプリを直接開くことができます。

これにより、ユーザーにとってアプリとウェブサイトの間の移動がスムーズになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/987057/4232c181-3741-85ac-e5ad-57ead9764402.png)
出典：https://8vivid.net/whats-url-scheme/
## apple-app-site-associationとは？

それでは、どのようにしてウェブサイトとアプリを関連付けるのでしょうか？

ここで**apple-app-site-association**が登場します。これはJSON形式のファイルで、あなたのウェブサイトのドメインと、あなたのアプリがどのようなURLパスを処理できるかを定義します。

例えば、以下のような内容のapple-app-site-associationファイルを作成します：

```json
{
    "applinks": {
        "apps": [],
        "details": [
            {
                "appID": "D3KQX62K1A.com.example.app",
                "paths": [ "/content/*", "/user/*/profile"]
            }
        ]
    }
}
```

ここでは、`appID`はあなたのApple開発者チームIDとアプリのバンドルIDを組み合わせたものになります。そして、`paths`にはあなたのアプリが処理できるウェブサイトのパスを指定します。

このファイルを作成したら、ウェブサーバーのルートディレクトリか`.well-known`サブディレクトリにアップロードします。

## apple-app-site-associationの設定がもたらす効果

apple-app-site-associationファイルを適切に設定し、あなたのサーバーにアップロードすると、それによりiOSデバイスは特定のリンクがあなたのアプリと関連付けられていることを認識します。

具体的には、このファイルに定義されているパスのリンクをユーザーがタップしたとき、そのリンクはブラウザではなくあなたのアプリで開かれます。もしアプリがインストールされていない場合は、リンクは通常通りブラウザで開かれます。

たとえば、もし`/content/*`や`/user/*/profile`といったパスをapple-app-site-associationファイルに指定している場合、それらのパスにマッチするURL（例：`https://yourwebsite.com/content/article1`）がメールやウェブページにあるとき、そのリンクをユーザーがタップすると直接アプリが開きます。

この挙動は、ウェブサイトとアプリの間の移動をスムーズにし、ユーザー体験を向上させます。

例えば、あなたのウェブサイトのコンテンツをアプリ内で最適化したビューで表示したい、あるいはアプリ内で特定のアクションを起動したいといった場合に非常に有効です。

## まとめ

apple-app-site-associationファイルを設定することによって、ウェブリンクとアプリの間にシームレスな連携を作ることができます。
ユーザー体験を向上させるため、ぜひ活用してみてください。
【HackGPT Tokyo2023】ChatGPTを活用したプロダクト開発に挑戦しました

# はじめに
Data Science Leagueのエンジニア、yoda(@RyutoYoda)です。2023年5月6日から5月7日にかけて開催された「HackGPT Tokyo2023」に参加しました。DSLからも複数のメンバーが参加しました。

https://hackgpt.tokyo/

# ハッカソンの内容
今回のハッカソンは、ChatGPTのAPIを用いた効果的な開発手法とChatGPTの活用事例についての講義が行われ、その後、各チームがChatGPTを使った新しいプロダクトの開発に挑戦するという内容でした。

# 開発プロセス
講義の後、すぐに開発を始めるためのKick Offセッションが行われました。ChatGPTのAPIを活用した新しいアイデアを出すために、チーム全員でブレインストーミングを行いました。最終的に、私たちのチームは4コマ漫画自己紹介アプリの開発に集中することを決めました。

開発期間中のBuild Timeでは、チームメンバーが協力してアプリの開発に取り組みました。私たちのアプリは、ユーザーがプロフィール写真やキャプションを入力すると、ChatGPTが自動的にそれに基づいて4コマ漫画を生成する機能を備えていました。

# ChatGPTのAPIを効果的に活用するための重要なポイント
ChatGPTのAPIを効果的に活用するためには、以下の重要なポイントに注意する必要がありました。

1. 適切なプロンプトエンジニアリング
ChatGPTは指示されたプロンプトに基づいて応答を生成します。したがって、明確で具体的な指示を与えることが重要です。プロンプトには、ユーザーのプロフィール情報や要求事項を適切に組み込むことで、よりパーソナライズされた結果を得ることができます。私たちのチームは、ユーザーの情報を適切にプロンプトに反映させることで、高品質な漫画の生成に成功しました。

```
prompt = f"""
  「自己紹介」を基に、起承転結を意識して4コマ漫画を作りたい。「何コマ目か(数字)」と「起、承、転、結でそれぞれ文章(日本語)」と「その場面に該当する画像を出力するプロンプト(English)」を出力してください。
  
  出力はJSON形式のみにしてください。
  
  keyとvalueの対応を以下に示す。
  key:value
  = panels:何コマ目？
  = caption:その場面の説明
  = sceneDescription:その場面の絵を生成するプロンプト
～～～～～～～～

```

2. 高品質なデータセットの収集と整形
ChatGPTのファインチューニングには、高品質なデータセットが必要です。私たちのチームは4コマ漫画のデータセットを収集し、適切な形式に整形する作業に時間を費やしました。データセットの質と量は、モデルの性能に直接影響を与えるため、慎重に選択し、整形する必要があります。特に、特定のトピックやスタイルに合わせた漫画生成を行う場合には、適切なデータセットの収集が重要です。

3. エラーハンドリングと応答品質の向上
ChatGPTのAPIを使用する際には、エラーハンドリングと応答品質の向上にも注意を払う必要があります。ユーザーからの入力によっては、予期しない応答や不適切な結果が生成される場合があります。私たちのチームは、エラーハンドリングの仕組みを実装し、生成された漫画の品質を向上させるためにフィードバックループを活用しました。

# 成果
最終プレゼンテーションでは、私たちのチームが開発した4コマ漫画自己紹介アプリを発表しました。その創造性とエンターテイメント性は他の参加者から高く評価され、最終的には1位を獲得することができました。

# 感想
ChatGPTのAPIを効果的に活用するためには、適切なプロンプトエンジニアリングと高品質なデータセットの収集と整形、エラーハンドリングと応答品質の向上といったポイントに注意する必要があります。これらの要素を適切に組み合わせることで、優れたプロダクトの開発とユーザー満足度の向上を実現できるでしょう。
いい加減オリジンとかドメインとかホストとかごっちゃになるのをやめたい

# はじめに
正直に白状するとオリジンとかドメインとかホストとか、この辺の用語がごっちゃになる節があって、時々会話や文章の中で何を指してるのか「？？」となることがあります。
そんな状況に終止符を打つべく、整理と振り返り用にまとめてみました。


# 解説

`http://www.example.co.jp`を例にします。
|用語|例|意味|
|-|-|-|
|スキーマ(プロトコル)|`http`, `https`など|Webにおいては通信プロトコルを指す。<br>スマホアプリだとアプリ製作者が設定した任意のスキーマ名でアプリを立ち上げたりできるらしい。|
|ドメイン|`co`, `jp`, `com`など|広義には`.`で区切られた`www`, `example`, `co`, `jp`は全てドメインとなる。<br>特にURL末尾に使われる`jp`や`com`などをトップレベルドメインという。<br>狭義には`example.co.jp`(ドメイン名)のことを指したりもする。会話や文章ではよく**ドメイン名の意味で「ドメイン」の呼称が使われる**ことがある。<br>たぶん狭義で使われている場合が多い。|
|サブドメイン|`www`, `api`, `co`など|広義にはトップレベルドメイン以外のドメインは全てサブドメインとなるため`www`, `example`, `co`がサブドメインとなる。<br>狭義には**ドメイン名に対するサブドメイン**を指しており`api`, `www`, `mail`などがそれにあたる。<br>たぶん狭義で使われている場合が多い。|
|ドメイン名|`example.co.jp`, `qiita.com`など|IPアドレス(ネットワーク上の住所)につけた名前。<br>単にドメインと略されていることもある。|
|ホスト|-|サーバー、ホストコンピュータのこと。<br>文脈によって指すものが違う。<br>例えば今、操作している端末のホストといえばiOSやWindowsを指すが、閲覧しているWebページのホストといえばQiitaの保有しているWebサーバーを指す。<br>**ホスト名の意味で「ホスト」の呼称が使われる**ことがある。|
|ホスト名|`www`, `api`など|サーバー、ホストコンピュータにつけた名前。<br>例えば`example.co.jp`というドメインを取得して、Webページを表示するためのWebサーバーに`www`と名付けた場合、ホスト名は`www`であり、APIを処理するためのAPIサーバーに`api`と名付けた場合、ホスト名は`api`である。<br> **`www.example.co.jp`, `api.example.co.jp`をホスト名と呼んでいることもある。** <br>単にホストと略されていることもある。|
|ポート番号|`80`, `443`など|ネットワークから流れてきたデータが、サーバー(コンピュータ)内のどのソフトウェアと通信するかを識別するための番号。<br>`http`や`https`などのプロトコルはウェルノウンポート番号としてあらかじめ`80`, `443`のように番号が決まっている。<br>ほかにレジスタードポート番号、ダイナミックポート番号に大別される。|
|FQDN<br>(Fully Qualified Domain Name)|`www.example.co.jp.`<br>(`www.example.co.jp`)|サブドメイン(ホスト名)とドメイン名を合わせたもの。<br>末尾にルートドメインと呼ばれる`.`があるのが正式だが、一般的には略した形がFQDNとして使われている。<br>完全修飾ドメイン名ともいう。
|オリジン|`http://www.example.co.jp:80`|スキーマと(あればホスト名と)ドメイン名とポート番号を合わせたもの。<br>スキーマが`http`や`https`の場合、ポート番号は略せるため明記しないこともある。<br>このときのホスト名とは、あくまでホストコンピュータのことなので、ホスト名がサブドメインのない`http://example.co.jp`の場合もありうる。|

# 総括
用語を解説しているサイトを色々見て回りましたが、あるところではホストをホスト名の意味で使っていたり、ドメインをドメイン名として使っていたり、ホスト名とドメイン名の違いがよくわからなかったり…
ただ今回のまとめで認識が大きくズレていることはないと思います。

また業界内でも人によって、用語の内容に幅があるようです(FQDNとホスト名の内容が混同していたり)。
用語の持つ幅を前提知識として持ちつつ、文脈で判断したり、不安なときは確認することが大事でしょう。
あなたがまだ知らないReactのテクニック10選

## はじめに

Reactは、UIを構築するための人気のあるJavaScriptライブラリです。
しかし、この強力なツールは、表面だけを見ているだけでは、その真の力を発揮することはありません。ここでは、あなたがまだ知らないかもしれないReactのテクニック10選を紹介します。

（本記事は初心者向けで作成してます。）

## 1. フラグメントを利用する

React.Fragmentは、余分なノードをDOMに追加せずに、複数の要素をグループ化する素晴らしい方法です。

```jsx
<>
  <ChildA />
  <ChildB />
  <ChildC />
</>
```

## 2. 条件付きレンダリングをマスターする

複数の条件でのレンダリングを管理するために、JavaScriptの`&&`や三項演算子`? :`を使いましょう。

```jsx
{condition && <Component />}
{condition ? <Component /> : <OtherComponent />}
```

## 3. カスタムフックを作る

ロジックを再利用するための最良の方法は、カスタムフックを作成することです。これにより、コードのDRY（Don't Repeat Yourself）化が可能になります。

```jsx
function useCustomHook() {
  // Custom logic here
}
```

## 4. プロップタイプスを設定する

コンポーネントのプロップスの型を設定することで、開発中のエラーを早期に検出できます。

```jsx
Component.propTypes = {
  name: PropTypes.string.isRequired,
};
```

## 5. インライン関数の代わりにコールバック関数を使う

インライン関数は、レンダリングごとに新しい関数を作成します。これを避けるために、コールバック関数を使用してください。

```jsx
<button onClick={this.handleClick}>Click Me</button>
```

## 6. 配列のmapメソッドでキーを設定する

Reactでは、配列をレンダリングする際には、一意の`key`プロパティが必要です。

```jsx
{items.map(item => (
  <Component key={item.id} />
))}
```

## 7. React.PureComponentやReact.memoを使う

不必要なレンダリングを避けるために、React.PureComponentやReact.memoを使用してください。

```jsx
export default React.memo(Component);
```

## 8. 遅延ロード（Lazy Loading）を使用する

React.lazyを使うことで、大きなアプリケーションのパフォーマンスを向上させることができます。これは、コンポーネントを必要になるまでロードしないというものです。

```jsx
const OtherComponent = React.lazy(() => import('./OtherComponent'));

function MyComponent() {
  return (
    <div>
      <React.Suspense fallback={<div>Loading...</div>}>
        <OtherComponent />
      </React.Suspense>
    </div>
  );
}
```

## 9. 関数コンポーネントを使う

React Hooksの導入以降、関数コンポーネントはクラスコンポーネントと同等の能力を持つようになりました。そのため、簡潔なコードを書くためには関数コンポーネントの使用を推奨します。

```jsx
function Component() {
  // Your code here
  return <div>Hello, world!</div>;
}
```

## 10. React DevToolsを使いこなす

React開発者ツールは、アプリケーションのデバッグを助け、パフォーマンスのボトルネックを特定するのに役立ちます。

https://chrome.google.com/webstore/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi?hl=ja

![スクリーンショット 2023-05-12 10.58.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/987057/54cd6cdf-9723-0bf9-e347-885e9f1ffe95.png)
3分でお手軽にReactアプリをGithub Pagesにデプロイする方法🍞

Reactアプリを作成できたが、どうやってデプロイ（公開）すればいいのだろう。。。？

今回は、GitHubが提供するGitHub Pagesというサービスで
Reactで作成したアプリをGitHub Pagesにデプロイする手順をご紹介します。

## 必要なもの（前提条件）
- Node.jsとnpmがインストールされた開発環境
- GitHubアカウント
- GitHub PagesにデプロイしたいReactアプリ
## 手順
### Githubリモートリポジトリを作成
まず最初に、Reactアプリを保存するためのGitHubリモートリポジトリを作成します。
このリポジトリは公開（Public）リポジトリにして下さい。

### gh-pagesをインストール
GitHub Pagesと連携するパッケージgh-pagesをインストールする必要があります。
以下のコマンドを実行してインストールしましょう。

```bash
npm install gh-pages --save-dev
```
### package.jsonの更新
次に、package.jsonファイルにhomepageフィールドを追加します。これが公開URLとなります。
ここで、
[your-github-username]はあなたのGitHubのユーザー名に、
[github-repo-name]はGitHubリポジトリの名前に、置き換えてください。

```package.json
"homepage": "http://[your-github-username].github.io/[github-repo-name]"
```
4. package.jsonのスクリプトの更新
package.jsonの"scripts"セクションに以下の2行を追加します。

```package.json
"scripts": {
    "predeploy": "npm run build",
    "deploy": "gh-pages -d build"
    // 既存コード
}
```

npm run deployコマンドが実行すると、まずビルドが行われ、
その後ビルドされたファイルがgh-pagesブランチにプッシュされます。

### デプロイ
以下のコマンドを実行してアプリケーションをデプロイします。

```bash
npm run deploy
```
### GitHubリポジトリの設定
最後に、GitHubリポジトリの設定を行います。GitHubリポジトリに移動し、設定(Settings)タブを開きます。
"GitHub Pages"セクションを下にスクロールし、Sourceブランチをgh-pagesに設定します。その後、保存します。

以上の手順でReactアプリをGitHub Pagesにデプロイできます。
これで設定したURLから、Reactアプリを閲覧することが可能です。

## 注意点
GitHub Pagesは静的サイトのホスティングに特化しています。そのため、サーバーサイドレンダリングやAPIとの連携など、サーバー側で動的な処理が必要なReactアプリについては、NetlifyやVercelなど他のホスティングプラットフォームを検討することをおすすめします。

## まとめ
この記事では、Reactで作成したアプリをGitHub Pagesにデプロイする手順を説明しました。手順自体は比較的シンプルで、あなたのReactアプリを公開するのに最適な方法の一つです。ぜひこの方法を試して、自分の作成したReactアプリを世界に公開してみてください。

## 参照
公式ドキュメントをみれば、さらに理解が深まります。
https://create-react-app.dev/docs/deployment/
Viewの実装がもっと楽しくなる考え方

開発者の皆様
デザイナーから上がってきたデザインを咀嚼して実装していますか？

なぜオブジェクトの配置はそうなのか、なぜその文言なのか、なぜマウスオーバーしたときにオブジェクトの色が変わるように実装しないといけないのか、なぜ私達はそのコードを書かないといけないのか。

ちゃんと納得していますか？

「なんとなぁく、そのデザインのほうがが良いからじゃない？」とか
「まぁUIのことは分からないけど、我々は実装するのみだ！」とか思っていませんか？
↑これは過去の私の意見です。

最近、「オブジェクト指向UIデザイン」という本を読んだことを皮切りに、デザインについてちょっと考えてみました。デザインについて理解が深まると、今までよりもViewの実装が楽しく感じられたので、考えた事を書き留めておくことにします。（本投稿の内容は本の内容とほとんどリンクしてません笑）

## はじめに

製品の機能はデザインにラップされてユーザーに届けられるため、ユーザーに使ってもらう事を想定しているのであれば（工作でないのであれば）、機能をユーザーに届けるためのUIが重要になります。
UIが適切であれば、ユーザーはストレスなく目的を達成できるはずで、そういう製品はよく使われます。
逆にUIが悪く、使うことにストレスがかかるような製品は使われなくなります。
より使われる製品を作るためにはUIにこだわることが重要ですし、開発側もデザインの意図を理解して実装すると、価値を生み出している感を感じられ、納得感を持って仕事ができるようになります。

これからいくつかの例を紹介します。

## ホバー時にオブジェクトに変化を加えることの重要性

現実世界と同じ感覚でコンピュータの世界を操作出来るようにすることは、ストレスのないユーザー体験への一歩になります。
これを踏まえると、ホバー時にオブジェクトに変化を加えることは非常に重要なことだと感じます。

現実世界では、行為者が対象物に注目し、手をのばすと、対象物の様相は変化してみえます。対象物に影が落ちて色がが変わって見えるかもしれないし、対象物を掴んだらむにゅっと形が変わるかもしれません。もっと言うと、行為者が対象物に注目することで、その色や形がより鮮明に見える（写真でいうとピントが合う状態になる）でしょう。
つまり、現実世界では、行為者が対象物を選択しようとすると、オブジェクトの様相が変わって見えるのが「普通」ということになります。逆に言うと、その「普通」が感じられなかったら、行為者は何かがおかしいと不安に思うでしょう。

それに対し、コンピュータの世界は、現実世界の物理が通じない世界なので、オブジェクト（ボタンとか）を選択しようとしても、勝手に様相が変わることはありません。

そのため、選択している感をユーザーが感じられるように、ホバー時やアクティブ時に色や文字の太さを変化させるように実装する必要があるのです。
こう考えると、CSSのちょっとした実装でも良いユーザー体験に強く貢献していることが分かると思います。

## プレースホルダーを設定する意味

プレースホルダーは、テキストフィールドに薄い黒で記入例などをユーザーに提示することができる機能ですが、この必要性を実装者は感じられないことが多いのではないでしょうか。
なぜなら、実装者は知りすぎているからです。開発側はどこに何を入力して、どの操作をすれば、どの処理が走るかを知っていますし、毎日毎日動作確認で同じ画面を触っていると、親切な導線がなくても違和感を感じなくなってきます。
しかし、新規ユーザーにとって親切な動線は必要です。

テキストフィールドの位置やラベル情報から何を入力すればいいか推測できるかもしれませんが、初めての場所で文脈を適切に理解して正しい推測をするのは、ユーザーにストレスをかけていますよね。

私は前に初めてマラソンに参加した際に、開始の30分前にどこにいれば良いのか分からなくてオドオドした経験がありますが、きっと新規ユーザーもそんな不安の中製品を触っているんだろうなと思います。

適切な誘導は重要ですね。
ただ、それに気づくにはユーザー視点になりきらないといけません。レビューで意識的にユーザー目線になるよう心がけましょう。

## 一貫性

ユーザーは同じ製品に対しては、一貫性のあるUIを求めます。
機能AにおけるCRUD（Create、Read、Update、Delete）の画面と機能BにおけるCRUDの画面が全く違ったら、ユーザーはストレスです。

たとえA機能とB機能が異なる機能だとしても、語り口（情報の提示や使用感）が同じであればユーザーはA機能とB機能を往復してもストレスがありませんし、初めてB機能を使うとしても、A機能を使ってきた経験を転用してある程度使えるはずです。

そういう事を考えると、同じ製品内ではアナロジーを使ってユーザーが取るべき操作を推測できるようにしておくのが良いと思います。

## 最後に

今回はホバーやプレースホルダーなどをピックアップして書いてきましたが、フォントサイズや色、オブジェクトの配置など、デザイナーが込めた意図をちゃんと汲み取って実装するとViewの実装がより楽しくなります。もっとデザインについても理解を深めていきたいなぁと思っています。
aureport -ts (--start) 日付指定は 「mm/dd/yy」正:yy 誤:yyyy 💢

# aureportでtodayとかじゃなく日付指定したくて `--start mm/dd/yyyy` を指定したら怒られた

```console
$ aureport --auth --start "01/01/2023" -if /var/log/audit/audit.log
Error parsing start date (01/01/2023)
```
なんでー?かの国💢フォーマットで年をお尻にしてるじゃんっ⁉

# 年は *2桁* で指定するらしい

```console
$ aureport --auth --start "01/01/23" -if /var/log/audit/audit.log
Authentication Report
============================================
# date time acct host term exe success event
============================================
1. 2023年...
```

OTL もう、なんなのよ、、、

```console
-ts, --start [start-date] [start-time]
    Search for events with time stamps equal to or after the given end time. The format of end time  depends  on  your
    locale.  If  the date is omitted, today is assumed. If the time is omitted, midnight is assumed. Use 24 hour clock
    time rather than AM or PM to specify time. An example date using the en_US.utf8 locale is 09/03/2009.  An  example
    of time is 18:00:00. The date format accepted is influenced by the LC_TIME environmental variable.
```

manの`09/03/2009`とか`LC_TIME`はミスリードなのでは。

環境依存なのかしら。bugレポートらしき情報は見つけたけど詳細調べる気にもならない徒労感。

```console
$ aureport --version
aureport version 3.0.7
$ locale
LANG=ja_JP.UTF-8
LC_CTYPE="ja_JP.UTF-8"
LC_NUMERIC="ja_JP.UTF-8"
LC_TIME="ja_JP.UTF-8"
LC_COLLATE="ja_JP.UTF-8"
LC_MONETARY="ja_JP.UTF-8"
LC_MESSAGES="ja_JP.UTF-8"
LC_PAPER="ja_JP.UTF-8"
LC_NAME="ja_JP.UTF-8"
LC_ADDRESS="ja_JP.UTF-8"
LC_TELEPHONE="ja_JP.UTF-8"
LC_MEASUREMENT="ja_JP.UTF-8"
LC_IDENTIFICATION="ja_JP.UTF-8"
LC_ALL=
```

locale周りを理解出来ていない可能性...(それにしたって...)
Power Automate DesktopはPower Automateと勘違いしやすいのではないか

# 結論
「Power Automate Desktop」は「Power Automate」と勘違いしやすいのではないかと思います。
「Power Automate Desktop」や「Power Automate」についてネットなどで調べるときは「Power Automate Desktop」の記事なのかクラウドの「Power Automate」の記事なのか、前提を確認しておいたほうがいいです。

# 解説
以前、「Power Autoamte Desktop」と「Power Automate」は別物という記事を投稿しました。

https://qiita.com/76r6qo698/items/a805886881aea78e7660

この「Power Autoamte Desktop」と「Power Automate」は別物であるという前提での話です。

Power Automate Desktopを起動するとわかるんですが、表示名が「Power Automate」となっています。
![powerautomatedesktop.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3071987/a1a43291-8318-4296-b33d-9ee45b332959.png)
これ、クラウドの「Power Automate」の存在を知らないまま、Power Automate Desktopのことを「Power Automate」と覚えてしまうこともあると思うんですね。
そうすると仮に「Power Automate Desktop」のことでネット調査をしようとした時、クラウドの「Power Automate」の情報が出てきて「Power Automateの解説ページ見たのに、掲載されているスクショと全然画面が違う！」と混乱する人も出てくるんじゃないかと思ってます。(実際に私がそうでした。。。)

# あとがき
分かってしまえば何も感じなくなると思いますが、使い始めのうちは混乱するかもしれないと思ったため記事にしました。結論でも書きましたが、「Power Automate Desktop」や「Power Automate」について調べるときはどちらの記事なのかを確認しておいたほうがいいです。
Delta Live TablesでS3のメタデータを処理する

S3ではオブジェクトにメタデータを付与することができます。

https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/UsingMetadata.html

今回はDLTのパイプラインでこのメタデータを操作してみます。

# メタデータの付与

```py:Python
import boto3

bucketname = 'ty-db-data-bucket'
key = 'dlt_data/metadata.jpg'

s3 = boto3.resource('s3', aws_access_key_id='<アクセスキーID>', aws_secret_access_key='<シークレットアクセスキー>')
s3_client = s3.meta.client

with open(filepath, 'rb') as body:
    response_put = s3_client.put_object(
        Bucket=bucketname,
        Body=body,
        Key=key,
        ServerSideEncryption='AES256',
        Metadata={
            'test': 'test metadata'
        }
    )
    print(response_put)
```

メタデータを確認します。

```py:Python
response_get = s3_client.get_object(
  Bucket=bucketname,
  Key=key
)
metadata = response_get['Metadata']
print(metadata)
```

```
{'test': 'test metadata'}
```

# DLTパイプラインの構築

シンプルな1つのテーブルのパイプラインを作成します。

```py:Python
import dlt
import pyspark.sql.functions as F
from pyspark.sql.functions import lit

import boto3

# S3バケット
bucketname = 'ty-db-data-bucket'
```

メタデータを取り出すUDFを定義します。アクセスキー以外の方法を使った方がいいとは思っていますが、一旦こちらで。

```py:Python
def get_bronze_meta_json(path: str) -> str:
  # AWSキーを用いたboto3の設定
  s3 = boto3.resource('s3', aws_access_key_id='<アクセスキーID>', aws_secret_access_key='<シークレットアクセスキー>')
  s3_client = s3.meta.client

  # メタデータの取得
  response_get = s3_client.get_object(
    Bucket=bucketname,
    Key=key
  )

  # リテラルを返します
  metadata = response_get['Metadata']
  return lit(metadata['test'])
```

Auto Loaderで読み込んだデータにUDFを適用します。

```py:Python
@dlt.table(name="recordings_bronze_w_metadata")
def recordings_bronze_w_metadata():
  
  df = (spark.readStream
    .format("cloudFiles")
    .option("cloudFiles.format", "binaryFile")
    .load("dbfs:/mnt/dlt_data/dlt_data/"))

  df = df.withColumn("json_meta", get_bronze_meta_json(F.col("path")))
  return df
```

# パイプラインの実行

1行のみの処理ですが、うまく動きました。

![Screenshot 2023-05-15 at 9.28.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/1664f0bf-3a37-a309-29f8-3d4531c2959b.png)

DLTの設定でターゲットスキーマを指定しているので、結果がテーブルに格納されています。結果のテーブルも確認します。

```sql:SQL
SELECT path,json_meta FROM recordings_bronze_w_metadata
```
![Screenshot 2023-05-15 at 9.35.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/3ce9a672-cf0d-2b20-2d78-3851aa84908f.png)

ちゃんとS3のメタデータが取得できています！

### Databricksクイックスタートガイド

[Databricksクイックスタートガイド](https://www.amazon.co.jp/dp/B09V1YXFVQ/)


### Databricks無料トライアル

[Databricks無料トライアル](https://databricks.com/jp/try-databricks)
ボーナスが出たので OSS に寄付します


私事ですがボーナスもらいました。
ということで、お世話になっている OSS に少額ながら寄付をします。

いつもお世話になっている Neovim さんに寄付します。
GitHub からの寄付が可能です。

https://github.com/sponsors/neovim


毎月は厳しいので今回だけの寄付にしました。寄付額は公開すると色々とめんどくさそうなので公開を控えさせてもらいます。（画像の$5はデフォルト値です）
![Sponsor @neovim on GitHub Sponsors - Google Chrome.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2960076/3b4dab8d-1bdd-0a86-3ac9-f324923f7a81.png)

GitHub で寄付すると Profile の Sponsoring に Neovim が追加されます。
![lx-sasabo (luxiar_sasahara) - Google Chrome 2023-0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2960076/5a900b89-b9c7-d310-f8c4-dc96fbc68c77.png)


ちなみに本家の [vim](https://www.vim.org/sponsor/) にも寄付しようとしたのですが PayPal だと「この受取人への寄付は、この国ではサポートされていません」のエラーが発生しました。[2年前に寄付したとき](https://sasabo-h.hatenablog.com/entry/2021/12/12/004655)は寄付できたのですが…


ググると下記の記事を発見しました。

https://qiita.com/kinichiro/items/fb21bda66bd1fd90fb6c

アドレス指定で寄付する方法で回避できるようです。
この方法でトライしようと思ったのですが、指定するアドレスに自信が無かったというのと、PayPal の支払いのときに本人確認が必要になり、思ったより面倒だったので一旦止めました…

というわけで今年はちゃんと OSS に貢献できました。（去年はすっかり忘れていました）
ボーナスのタイミングでやるようにすれば来年以降も続けられそうな気がします。
ntpdの起動

ntpdを起動するときにはntpdateが正常に処理できた後に起動する必要があります。停電の復旧などでネットワークの準備が出来てない場合などを考慮して、スクリプトで実行する場合、下記のようにします。

```sh
#!/bin/sh

while :
do
        ntpdate ntp.nict.jp
        if [ $? == 0 ]; then
                break
        fi
        sleep 30
done

ntpd -p /var/run/ntpd.pid
```
【リーダブルコード】コメントは正確で簡潔に

[リーダブルコード](https://amzn.asia/d/caRjT2n)の6章「__コメントは正確で簡潔に__」を読んだので、内容をまとめています。
コメントを書くのであれば、正確に書くべき（できるだけ明確で詳細に）。
またコメントには画面の領域を取られるし、読むにも時間がかかるので、簡潔であるべき。

---

## 忙しい人向けに、まとめから
:::note info
__鍵となる考え__
コメントは領域に対する情報の比率が高くなければならない
:::
__具体的なポイント__
+ 複数のものを指す可能性がある「それ」や「これ」などの**代名詞を避ける**。
+ **関数の動作**はできるだけ正確に説明する。
+ コメントに含める入出力の実例を慎重に選ぶ。
+ **コードの意図**は、詳細レベルではなく、高レベルで記述する。
+ よくわからない引数にはインラインコメントを使う。
+ **多くの意味が詰め込まれた言葉や表現**を使って、コメントを簡潔に書く。


## 6章の内容
#### コメントは簡潔にしておく
必要な場合を除いて、コメントは簡潔に。
**具体例**
```c++
改善前
// intはCategoryType
// pairは最初のfloatは'score'
// 2つ目は'weight'
typedef hash_map<int, pair<float, float > Scormap;
```
↓
```c++
改善後
# CategoryType -> (score, weight)
typedef hash_map<int, pair<float, float > Scormap;
```

#### あいまいな代名詞を避ける
代名詞は物事を複雑にしてしまう。読み手は代名詞を「還元」しなければならない。紛らわしい場合は、名詞を代名詞に「代入」してみる。
**具体例**
```c++
改善前
// データをキャッシュに入れる。ただし、先にそのサイズをチェックする。
```
↓
```c++
改善後
# データをキャッシュに入れる。ただし、先にデータのサイズをチェックする。
```

#### 歯切れの悪い文章を磨く
コメントを正確にすることと、簡潔にすることは両立されることが多い。単純で短く直接的な表現を意識する。
**具体例**
```c++
改善前
// これまでにクロールしたURLかどうかによって優先度を変える。
```
↓
```c++
改善後
# これまでにクロールしていないURLの優先度を高くする。
```
#### 関数の動作を正確に記述する
**具体例** **（ファイルの行数を数える関数）**
このケースの場合、「行」という単語が様々な解釈をされてしまう。（コーナーケース）
・ ""(空のファイル）は0行？1行？
・ "hello"は、0行？1行？
・ "hello\n"は、1行？2行？
・ "hello\n world"は、1行？2行？
・ "hello\n\r cruel\n world\r"は、2行？3行？それとも4行？
```c++
改善前
// このファイルに含まれる行数を返す
int CountLines(string filename){ ... }
```
↓
最初のコメントより、それほど長くないのに、伝わる情報が格段に増える。
```c++
改善後
# このファイルに含まれる改行文字（'\n'）を数える。
int CountLines(string filename){ ... }
```
#### 入出力のコーナーケースに実例を使う
慎重に選んだ入出力の実例をコメントに書いておけば、それは千の言葉に等しい。
**具体例** **（文字列の一部を除去する関数）**
このケースの場合以下のような質問が生まれてしまう
・ charsは、除去する文字列なのか、順序のない文字集合なのか？
・ srcの末尾に複数のcharsがあったらどうなるのか？
```c++
改善前
// 'src'の先頭や末尾にある'chars'を除去する
String Strip(String src, String chars){ ... }
```
↓
適切な実例を使用することで、Strip()の全ての機能を「見せて」いる。
```c++
改善後
# 実例：Strip("abba/a/ba", "ab")は"/a/"を返す
String Strip(String src, String chars){ ... }
```

#### コードの意図を書く
コードの動作をそのまま書くだけのコメントではなく、よりプログラムの動作を**高レベル**から説明しているコメントを書く。そうすることで、、
技術的に正しくても、**作者の意図と実際のコードが矛盾している場合**に気づきやすくなる。
```c++
改善前
// listを逆順にいてレートする
for (list<Product>::reverse_iterator it = products.rbegin(): it != products.rend(); ++it):
```
↓
```c++
改善後
// 値段の高い順に表示する
for (list<Product>::reverse_iterator it = products.rbegin(): it != products.rend(); ++it):
```


#### 「名前付き引数」コメント
引数の役割を明確にする。

以下のような関数呼び出しでは、数値とプールが渡されたものの、何を示すのかよくわからない。
```python
改善前
connect(10, false);
```
↓
名前付き引数で関数を呼び出す
```python
改善後
connect(timeout = 10, use_encryption = false);
```

#### 情報密度の高い言葉を使う
プログラミングでは、同じ問題や解決策が何度も繰り返し登場する。そのため、同じようなパターンやイディオムを説明するための言葉や表現がある。このような言葉を使うことで、コメントを**簡潔**にできる。

**具体例**
```ruby
改善前
# このクラスには大量のメンバがある。同じ情報はデータベースにも保管されている。ただし、
# 速度の面からここにも保管しておく。このクラスを読み込んだ時には、メンバが存在しているかどうか先に確認する。
#　　もし存在していれば、そのまま返す。存在しなければ、データベースから読み込んで、
# 次回のためにデータをフィールドに保管する
```
↓
```ruby
改善後
# このクラスの役割は、データベースのキャッシュ層である。
```

---
引用
[リーダブルコード ―より良いコードを書くためのシンプルで実践的なテクニック (Theory in practice)](https://amzn.asia/d/eLinYdT)
PowerShellとAzCopyを使ってローカルとAzure Blob Storageのファイルのやり取りをする


ローカル端末のファイルをAzure Blob Storageにアップロードしたい場合、AzCopyでAzure Blob Storageにファイルをアップロードすることができます。

使うコマンドは以下です。
```
azcopy copy SourcePath DestinationURI
```

DestinationURIにはAzure Blob StorageコンテナのSAS URIの入力が必要です。Azure Portalからも生成可能ですが、せっかくコマンドで完結させたいのにそれでは意味がないので以下のコマンドでの生成を目指します。

```
# Connect to Azure
Connect-AzAccount
# List Azure Subscriptions
Get-AzSubscription

# Define Variables
$subscriptionId = "yourSubscriptionId"
$storageAccountRG = "demo-azcopy-rg"
$storageAccountName = "tomsaccount"
$storageContainerName = "images"
$localPath = "C:\temp\images"

# Select right Azure Subscription
Select-AzSubscription -SubscriptionId $SubscriptionId

# Get Storage Account Key
$storageAccountKey = (Get-AzStorageAccountKey -ResourceGroupName $storageAccountRG -AccountName $storageAccountName).Value[0]

# Set AzStorageContext
$destinationContext = New-AzStorageContext -StorageAccountName $storageAccountName -StorageAccountKey $storageAccountKey

# Generate SAS URI
$containerSASURI = New-AzStorageContainerSASToken -Context $destinationContext -ExpiryTime(get-date).AddSeconds(3600) -FullUri -Name $storageContainerName -Permission rw
```

逆にダウンロードする際は以下のようにソースとDestinationを逆にするだけです。
```
azcopy copy DestinationURI SourcePath
```

なお、Azcopy copyコマンドはオプションで細かく設定もできるので興味ある方は[こちら](https://learn.microsoft.com/en-us/azure/storage/common/storage-ref-azcopy-copy#options)も見てみてください。

本記事は[How To Upload files to Azure Blob Storage using PowerShell and AzCopy](https://techcommunity.microsoft.com/t5/itops-talk-blog/how-to-upload-files-to-azure-blob-storage-using-powershell-and/ba-p/650309?WT.mc_id=twitter-social-thmaure)を参考にしています。
ST7735(パラレル)で遊ぶ5(1か月から3か月の長期記事)ATM0177B5


x 秋月で売っている液晶であるST7735のパラレル接続のやつ


いろいろ
5月14日(日)にお散歩しつつ休憩でアイスコーヒーを飲んだら
このアイデアが天から降ってきた。
その、時間は、無駄では、なかった。
なんのこと?
自分で言うのもなんだけど、かなりの特異体質で脳内で図面が動かせる
から手ぶらでOK
ちなみにプログラムも脳内で実行、トレース出来る。変態、病気!!
この、変態、変態、変態!!(変態は、最高の誉め言葉です。)




組み立て


![IMG_2142.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/db05d68b-0214-f42a-de08-dfc6d405358f.jpeg)

![IMG_2143.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/6b2bd315-9fbd-af74-c618-962ebeab4d30.jpeg)

![IMG_2144.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/dd0d8081-b277-d638-32f9-da37241f521b.jpeg)
Reactとは

## React（リアクト）は、Facebook社が開発したJavaScriptライブラリ

UI（ユーザーインターフェース）の構築に使用される
→コンポーネントベースのUI開発が簡単になる

ReactはVirtual DOMを採用
UIをコンポーネントとして分割し、それぞれのコンポーネントを再利用できる
コンポーネントは、状態（ステート）とプロパティ（プロップス）を持ち、状態が変化したときに自動的に再描画される
→効率的なレンダリングができ、UIのパフォーマンスを向上させる

Reactは、JavaScriptで記述される
React Nativeというフレームワークを使用することで、ネイティブアプリケーションの開発にも利用可能
【CopilotForXcode】無料で使えるコード提案AIのCodeiumが使えるようになった！

# はじめに
Codeiumは無料で使えるGitHubCopilotって思ってもらっていいと思います

https://github.com/intitni/CopilotForXcode

過去のCopilotForXcodeの記事がこちら

https://qiita.com/SNQ-2001/items/046826dd2ac792ad3d10

https://qiita.com/SNQ-2001/items/ca0ebe026bc0e88499ce

# Codeiumのアカウントを作成する
こちらからアカウントを作成してください
特に難しいところはないです。

https://codeium.com/account/register

# 設定
① 「Service」を選択します
② 「Codeium」を選択します
③ 「Install」を選択します
![スクリーンショット 2023-05-14 22.07.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/f818a285-5562-84e3-93cf-45605676d179.png)

④ 「Sign In」を選択します
![スクリーンショット 2023-05-14 22.09.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/f922c381-7285-9309-a3a7-1d099b445c78.png)

⑤ Tokenをコピーします
![スクリーンショット 2023-05-14 23.32.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/d6effef4-c06b-0ace-fc75-f7c9540c80e0.png)

⑥ コピーしたTokenを貼り付けます
⑦ 「Sign In」を選択します
![スクリーンショット 2023-05-14 23.34.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/26e533bb-b3c4-f80d-f3f3-aed7f43f2d99.png)

⑧ 「Feature」を選択します
⑨ 「Suggestion」を選択します
⑩ 「Feature Provider」を`Codeium`に変更します
![スクリーンショット 2023-05-14 23.39.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/4677b25a-0ae9-339a-be8d-7665b3c3e758.png)

# 動作確認
表示された！！
![スクリーンショット 2023-05-14 23.43.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/b43f982f-4e97-6937-a70e-5da3b3bd5bf0.png)

# おわり
GitHubCopilotレベルのサジェストされてる気がします
正直あんまり違いはわからないです笑