OmniAICreator/Qiita-1.07M huggingface dataset:
Project Schedule Acronyms

# Project Schedule Acronyms:

- RD: Requirements Definition – Gathering and defining the project/system requirements.
- BD: Basic Design – Initial high-level design outlining the system's structure.
- DD: Detailed Design – Detailed specifications for implementation based on the basic design.
- CD: Construction Design – Actual development or construction phase of the project.
- UT: Unit Testing – Testing individual components or modules for functionality.
- IT: Integration Testing – Testing the system as a whole after combining all units.
- SD: System Design (or Software Delivery) – Either the overall system design or the final delivery and deployment of the software.

# Testing Acronyms:
- LT: Load Testing – Testing system performance under expected load conditions.
- ST: Stress Testing – Testing system performance under extreme or beyond-normal conditions to find breaking points.
- PT: Performance Testing – General testing for speed, responsiveness, and stability under various conditions.
- Soak Testing: Also known as Endurance Testing, this checks how a system handles a sustained load over a long period.
Swiperの使い方: カルーセルスライダーの実装ガイド

## アジェンダ
HTMLとJavaScriptで利用できるスライダープラグイン「Swiper」を使ったカルーセルスライダーの実装方法について、サンプルコードを参考にしながら、基本的な設定とカスタマイズの方法について簡単に記述します。

## Swiperとは？

Swiperは、レスポンシブなスライダーやカルーセルを作成できるJavaScriptライブラリです。軽量でカスタマイズ性が高く、タッチ対応もしているため、スマートフォンやタブレット向けのスライダーにも最適です。

※以下はSwiperのHPになります。

https://swiperjs.com/

## Swiperのインストール方法

SwiperはCDNを利用して簡単に組み込むことができます。まず、以下のようにHTMLファイルにSwiperのスタイルシートとスクリプトを追加します。

```html
<link rel="stylesheet" href="https://unpkg.com/swiper@7/swiper-bundle.min.css">
<script src="https://unpkg.com/swiper@7/swiper-bundle.min.js"></script>
```

このコードを`<head>`タグの中に入れて、スタイルシートとJavaScriptファイルをインポートします。

※以下はGetting Startedになります。

https://swiperjs.com/get-started

## Swiperの基本構造

Swiperを利用するためには、HTML構造に特定のクラスを設定する必要があります。以下は、Swiperを利用したシンプルなスライダーのHTML構造の例です。

```html
<div class="swiper">
  <div class="swiper-wrapper">
    <div class="swiper-slide">
      <img src="./assets/img/item-card-img-1.png" alt="商品1">
      <p>商品名1</p>
    </div>
    <div class="swiper-slide">
      <img src="./assets/img/item-card-img-2.png" alt="商品2">
      <p>商品名2</p>
    </div>
    <div class="swiper-slide">
      <img src="./assets/img/item-card-img-3.png" alt="商品3">
      <p>商品名3</p>
    </div>
    <!-- さらにスライドを追加 -->
  </div>
</div>
```

- **`swiper`クラス**: スライダー全体を囲むコンテナ。
- **`swiper-wrapper`クラス**: スライドを包むラッパー。
- **`swiper-slide`クラス**: 各スライドのコンテンツ。

## Swiperの初期化

次に、Swiperの初期化コードを追加します。このコードは`<script>`タグ内に記述し、スライドの表示や動作をカスタマイズします。

```javascript
var swiper = new Swiper(".swiper", {
  slidesPerView: "auto",       // スライドの表示枚数を自動に設定
  spaceBetween: 1,             // スライド間のスペース
  grabCursor: true,            // カーソルを掴むような効果
  mousewheel: {                // マウスホイールでの操作設定
    enabled: true,             // マウスホイール操作を有効に
    sensitivity: 5,            // 感度を設定
    forceToAxis: true,         // 水平方向のみに制限
  },
});
```

### 設定オプションの解説
- **`slidesPerView`**: 一度に表示されるスライドの数を指定します。`"auto"`を指定すると、スライドのサイズに応じて自動的に調整されます。
- **`spaceBetween`**: スライド同士の間隔をピクセル単位で設定します。
- **`grabCursor`**: カーソルが掴むような見た目になるエフェクトを追加します。
- **`mousewheel`**: マウスホイールでのスライド移動を可能にし、感度や方向を設定します。

## Swiperのカスタマイズ

Swiperには多くのオプションがあり、ニーズに応じてさまざまなカスタマイズが可能です。たとえば、以下のようにページネーションやナビゲーションボタンを追加することもできます。

### ページネーションの追加

```javascript
var swiper = new Swiper(".swiper", {
  pagination: {
    el: ".swiper-pagination",
    clickable: true,
  },
});
```

### ナビゲーションボタンの追加

```javascript
var swiper = new Swiper(".swiper", {
  navigation: {
    nextEl: ".swiper-button-next",
    prevEl: ".swiper-button-prev",
  },
});
```

### 自動スライド

```javascript
var swiper = new Swiper(".swiper", {
  autoplay: {
    delay: 3000,  // 3秒ごとにスライドを自動切り替え
  },
});
```

## まとめ

Swiperは、簡単に導入でき、豊富なカスタマイズオプションを提供するスライダープラグインです。今回紹介した基本的な設定をもとに、さらに高度なスライダーを作成することが可能です。ぜひ、実際のプロジェクトでSwiperを活用してみてください。
【ChatGPT＋Code Interpreter】でDALL-E3画像四枚をダウンロードせずに一枚画像にします。


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

　今回は、DALL-E3で描画した画像四枚をダウンロードせずに一枚画像にします。

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

　まずは、ニュースです。

　解説系動画生成AIのNoLang、
　　NoLang有料クレジットの
　　　有効期限を撤廃したそうです。

　メール内容をそのまま出します。
```
Nolang ユーザーの皆様

平素よりNoLang ( https://no-lang.com/t/m0919 ) をご利用いただき、ありがとうございます。

この度、NoLang有料クレジットの有効期限を撤廃いたしました。これにより、【9/19以降】に有料プランで獲得したクレジットは、付与から一ヶ月経過した後も引き継がれ、無期限でご利用可能となります。

なお無料プランで獲得したクレジットに関しましては、クレジット更新日に失効する仕様となっております（無料プラン会員様に対して、クレジット更新日に200クレジットが付与される仕様は変わっておりません）。

現在私たちは、NoLangの利便性をさらに向上させるため、精力的に開発を進めており、様々な機能の追加・アップデートを予定しています。
今後とも変わらぬご愛顧のほど、よろしくお願いいたします。

🐬NoLang 開発チーム
```
***
　さて、本題です。

　今回は、
　　DALL-E3で描画した画像四枚を
　　　ダウンロードせずに
　　　　同一セッションで、
　　　　　一枚画像にします。

　X-Twitterでのポストに
　　必要でしたので
　　　やってみました😅

　以前に、
　　[【ChatGPT＋Code Interpreter】複数枚の画像を一枚の画像にします。](https://qiita.com/kabumira/items/4e7df68d7dc569042c9c)
　　　でも同じようなことを
　　　　やりました。

　今回は
　　DALL-E3での描画のあとに
　　　ダウンロードしたり
　　　　アップロードしたりせずに
　　　　　一枚画像を作成します。

　直接、これができるとは
　　思わなかったのですが、
　　　試しにやったら、
　　　　できちゃった😅

　ではでは～
　手順です。
　❶GPT-4oであることを確認
　❷四枚の画像が描画済であることを確認
　❸Prompt入力
```Text:
この四枚の画像を、CodeInterpreterで、512×512に縮小して、上下左右につなげて、1024×1024の画像を作成してください。
```
　❹送信
　❺ダウンロードリンクが表示

　Promptを
　　使った結果が
　　　こちらになります。
![combined_mecha_musume_1024x1024.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457238/cad85f8d-bb74-18ab-3d31-18f8df1da389.png)

　512×512に縮小するのは
　　左上の部分だけを描画されたので
　　　それの回避策です。

　このPromptを工夫すれば、
　　指定した画像を
　　　同じように一枚画像にできます。

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

　今回は、ここまで。
pタグのアンチパターン: リストタグ (ulタグ, liタグ) を使うべき理由

## アジェンダ

Webページを作成する際に、特定の情報が複数ある場合に`<p>`タグで記述しておりました。
しかし、注意事項や手順などを列挙する場合、リスト形式を使用することで、読み手にとって視認性が高く、わかりやすい表現が可能になるということについて簡単にまとめます。

## `<p>`タグとリストタグの違い

以前、注意事項などの項目を段落タグ (`<p>`) で表現していた場合、次のような構造になっていたかもしれません:

```html
<p>※こちらの商品は数量限定になります。</p>
<p>※お一人様一点になります。</p>
```

この方法では、各項目が単に段落として表示されます。しかし、これでは内容が連続的に見えてしまい、個々の注意事項が独立した項目であることが分かりにくくなります。

## リストタグを使う理由

ここで、リストタグ (`<ul>` と `<li>`) を使うと、意味的に適切で視覚的にも分かりやすくなります。例えば、次のように変更します。

```html
<ul>
  <li>※こちらの商品は数量限定になります。</li>
  <li>※お一人様一点になります。</li>
</ul>
```

これによって、以下の利点があります:

1. **意味の明確化**:
   - `<ul>`は「順序のないリスト（unordered list）」を表し、`<li>`はそのリストの各項目を示します。これにより、注意事項がリストの一部として明確に表現されます。

2. **視認性の向上**:
   - 各項目が個別のリスト項目として表示されるため、読み手がそれぞれの情報を視覚的に区別しやすくなります。

3. **HTMLの意味論的適合性**:
   - 段落タグ (`<p>`) は文章のまとまりを示すためのもので、リストを表示するには意味的に適していません。複数の独立したアイテムを列挙する場合は、リストタグの方がより適切です。

## まとめ

注意事項や規則などのように、複数のアイテムを表示する際には、段落タグ (`<p>`) ではなく、リストタグ (`<ul>` と `<li>`) を使うと、意味が明確になり、読み手にとって分かりやすい表示が可能になります。
#57 isset() vs empty() What's the differences?

# isset() vs empty() What's the differences?

While start learning PHP, there are always some points which is confusing. Today I would like to make a simple note to descript the differences between `isset()`, `empty()`, `if()`

## What is isset()?

>Determine if a variable is declared and is different than null

Simply saying it checks whether a variable is set and NOT equal to `NULL`

## What is empty()?

>Determine whether a variable is empty

All the variables including ` `, `0`,`false` and `NULL` are empty.

In the offical document, we are able to find out `empty()` run the concise above.

>!isset($var) || $var == false

## isset() vs empty()

`empty()` using `isset()` to determine whether the value is empty.

It looks similar but working for different purpose, so do not get it wrong otherwise it may cause you a big trouble.

Forturnately, PHP official document provide type comparison tables which clearly showing the differences.
https://www.php.net/manual/en/types.comparisons.php

## Frequent issues

While receiving API response or checking SQL query data, we oftenly use `empty` to check whether the variable is null or empty. It is still easy to understand while checking empty string. But how about `0`?

`0` is used in different situations and defined as a non-empty variable. However, `if(!empty($x))`is oftenly seen to be used for validation and clearly it cause bug because `0` is define as empty variable in PHP.

It is simple to fix, like replace `empty` with `isset`. But we should learn the definition before using any 'language construct'.

## Conclusion

Does not like Java, PHP is not a statically-typed language, you might make a mistake without notice. Therefore read the document carefully, it is really helpful.

## Reference
https://www.php.net/manual/en/function.isset.php
https://www.php.net/manual/en/function.empty.php
https://www.php.net/manual/en/types.comparisons.php
【Rust】Pythonライブラリを超簡単に作れるツールを作った

# はじめに

最近になってRustを勉強し始めて、何か作ってみようということで`pyinit`を開発しました。この記事では開発の背景や手こずった点を紹介していこうと思います。

https://github.com/t3tra-dev/pyinit

ツール自体のインストール方法や使い方についてはGitHubリポジトリの[README.ja.md](https://github.com/t3tra-dev/pyinit/blob/main/README.ja.md)を参照してください。

# 開発背景

Pythonのライブラリ開発において、プロジェクトの初期セットアップには多くの手順が伴います。`README.md`や`setup.py`、`__init__.py`、ライセンスファイルなど、プロジェクトごとにこれらのファイルを毎回作成するのは煩わしいです。

「このセットアップを自動化できないか？」という発想から、プロジェクトのテンプレートを自動生成できるCLIツール `pyinit` を開発することにしました。これにより、Pythonライブラリの開発がより迅速に、そして効率的に行えるようになります。

ちなみに名前の`pyinit`はお察しの通り`Python` + `init`です、安直ですね。

# 使用技術

## Rust

CLIそのものの開発言語にはRustを使用しています。Rustを選んだ理由は、コンパイルされたCLIバイナリを生成でき、またクロスプラットフォーム対応が容易であることです。

## GitHub Actions

継続的インテグレーション(CI)と継続的デリバリー(CD)のためのものです。`v*.*.*`の形のタグがプッシュされると自動的にLinux、macOS、Windows用のバイナリをビルドし、GitHubのリリースページにアップロードするようになっています。

## 使用したクレート

他の言語で言うライブラリとかフレームワークみたいなやつです。

### CLIの構築

主に`clap`と`dialoguer`を使ってインタラクティブなCLIを構築しました。これにより、ユーザーが対話形式でプロジェクト名や説明、ライセンスなどを指定できるようにしました。

- `clap`: コマンドライン引数のパースとオプションの処理に使用
- `dialoguer`: プロジェクトの詳細を対話形式で入力できるプロンプトを実装

### 内部処理

主に`regex`と`reqwest`を使って内部の処理を実装しました。これにより、入力のバリデーションなどを行っています。

- `regex`: 正規表現によるバリデーションで、プロジェクト名や作者名のフォーマットチェックに使用
- `reqwest`: PyPIのAPIにアクセスし、ライブラリ名の使用可否を確認するためのHTTPリクエストに使用

# 問題と解決

## 実行権限の問題

最初に生成されたLinuxとmacOSのバイナリで、`permission denied`が発生しました。この問題は、ビルド後に実行権限が付与されていなかったことが原因です。GitHub Actionsの中で`chmod +x`コマンドを追加し、バイナリに実行権限を付与することで解決しました。

## 圧縮方法の問題

ビルドプロセスの自動化には、GitHub Actionsを使用しました。Windows、Linux、macOSの3つの環境で同時にビルドを行い、リリースページにバイナリをアップロードするまでは上手く行ったのですが、Linux/macOSで利用可能な`zip`コマンドがWindowsで使えなかったため`${{ matrix.os == 'windows-latest' }}`を用いて場合分けを行い、Windows環境では`Compress-Archive`を使うようにすることで解決しました。

# まとめ

Rustを初めて触ったにしては結構頑張った方なんじゃないでしょうか...ツール自体も結構便利だと思うのでGitHubリポジトリにstarなど頂けると励みになります。

https://github.com/t3tra-dev/pyinit

プルリクエストも大歓迎です！ただ私自身がRust初心者なのでお手柔らかに...

バグなどありましたら[issuesセクション](https://github.com/t3tra-dev/pyinit/issues)からお願いします。

# 終わりに

最後まで読んで頂きありがとうございます。不備があれば是非コメントで指摘して下さい。
XCode16の既存プロジェクトで"New Folder"でフォルダ作成すると、"Fatal error: Unknown PBXObject subclass isa=PBXFileSystemSynchronizedRootGroup"のようなコンパイルエラーになる

### 解決方法

* 作成したフォルダを右クリック -> "Convert to Group"

### 何が起こっている？

XCode 16からの新機能である、Folder機能とCocoaPodsを使ったプロジェクトと相性が悪く、Folderがあるとビルドが通らないのだと思われる


### 参考

https://developer.apple.com/documentation/xcode-release-notes/xcode-16-release-notes
https://github.com/CocoaPods/CocoaPods/issues/12456#issuecomment-2298010983
Go言語とC++で演算子の優先度が違ってバグった話

# GoからC++への移植
最近、C++の練習がてらAtCoderなどの競技プログラムをC++でもやり始めました。基本Go言語でやっているので、Go言語でプログラミングしてACしたあとに、C++に移植というスタイルでやっています。

Go言語からC++にポーティングする時に、演算子の優先度でバグったので情報共有しておきます。

# バグったコード

具体的には、以下の式です

```go
bit = x >> i % 2
```

この結果がC++とGoで異なり、どこでミスが発生しているのかを見つけるのにえらく苦労しました（まさか、ここの挙動が違うとは思いもしませんでした）。

# 実際に確認してみる

## Go言語

```go
package main

import "fmt"

func main() {
	x := 0x55

	for i := 0; i < 8; i++ {
		fmt.Println(i, x>>i%2, (x>>i)%2, x>>(i%2))
	}
}
```

上記のプログラムの実行結果は、以下になります
```text
0 1 1 85
1 0 0 42
2 1 1 85
3 0 0 42
4 1 1 85
5 0 0 42
6 1 1 85
7 0 0 42
```

## C++

```c++
#include <iostream>

using namespace std;

int main()
{
    int x = 0x55;
    for (int i = 0; i < 8; i++)
    {
        cout << i << " " << (x >> i % 2) << " " << ((x >> i) % 2) << " " << (x >> (i % 2)) << endl;
    }
}
```

上記のプログラムの実行結果は以下になります。

```text
0 85 1 85
1 42 0 42
2 85 1 85
3 42 0 42
4 85 1 85
5 42 0 42
6 85 1 85
7 42 0 42
```

## 演算の解釈が違っていた
この結果から、Go言語では`(x >> i)%2`、C++では`x >> (i%2)`と解釈されていることがわかります。

演算子の優先度を見ると、`>>`と`%`はGo言語では**同じレベル**、C++言語では、`%`の方が`>>`より優先です。同じレベルなのでGoでは左から右へ結合されたようです。

こんな違いがあると思っていなかったので、見つけるのにかなり苦労しました。

## 結論
「演算には`()`を明示的につけたほうが良い」ということは知っていたのですが、サボってました。やはり、明示的にカッコをつけた方が良いようです。
今回、基本的な演算子でも、言語で優先度が違うということがわかりましたので、これからは注意してカッコをつけようと思いました。

Python, Javaを調べましたが、この２つはC++と同じみたいです。Goが珍しいのかも・・・・
システムを作るのに必要な観点

# Motivation
既存システム開発案件に参画して急遽、退会機能を実装しなければいけませんでした。ですが、その機会のおかげで様々な学びがありました。自分の力が及ばなかったところを反省し次に活かすための振り返りをしておこうと思ったのが動機です。

# システムの観点
## データの状態が表す意味は一意となるように
システムのデータ削除方針とし物理削除ではなく、論理削除を採用しました。FW は Laravel を使っていて、標準で削除機能を実装しているので簡単に導入することができました。

「退会機能」としてだけ見れば問題なかったのですが、考慮し忘れていたのは、ユーザーに紐づくデータの削除方針です。当初私が行なっていた実装としては、ユーザーが退会したときはそのユーザーに紐づく投稿データも一緒に削除するものでした。

ここに問題点がありました。将来的に投稿の削除機能が実装され、以下のフローをとる場合を考えてみます。削除フラグだけで管理する方法を採用してしまうと

1. ユーザが自身の投稿を削除する（投稿の削除フラグを true に）
2. ユーザーが退会する
3. 投稿も論理削除される（投稿の削除フラグを true に） 

となります。そしてユーザが利用再開するとします。利用再開したときにそれまでの投稿も再度表示される仕様となっている場合、削除フラグを false にしてあげる必要があるので、ユーザーが過去に削除した投稿も一緒に表示されてしまいます。

反省点としては、実装するときは将来的にどのような機能が実装されるか、仕様がどのように変わるかを確認できるなら確認しておくことです。

ユーザが意図的に削除したのか又は、ユーザが退会したことによって副次的に削除されたかをデータの状態から判別できるようにする必要があります。

また、フラグを多用しすぎると条件分岐が増えてしまい処理が複雑になってしまうので、status カラムを使用しデータの状態を表現させてあげることをお勧めします。

## テーブルはなるべく共通化しない
例えば、顧客（clients）や管理者（admins）などを別テーブルで管理していた時、その時点でプロフィールの項目が同じだからといって一つのテーブル（profiles）に関連付けすると将来の仕様変更に耐えられなくなってしまいます。

仕様によって「顧客」「管理者」間の項目は変わってくる可能性があるので、別テーブルで管理することをまず考えます。

## 無駄な処理はなるべく実行しない
特定の状態の時に不必要な処理をしないようにしましょう。

早期リターンや break 文などで無駄な処理を省くことができます。

とはいえ、複雑化したコードだと、無駄を完全に省くことは難しいと思うので、パフォーマンスへの影響が大きい箇所のみで大丈夫だと思います。

## APIから直接実行できないようにする
ユーザーの権限・役割によって、特定のアクションを禁止する / アクション実行ボタンやリンクを非常時にする / フォームを無効化するなどはよくある実装だと思います。

ブラウザ側の操作ではそれで目的を達成できますが、API に対して直接リクエストされてしまうケースを考慮して、フロント側だけでなく、バックエンド側にバリデーションを実装することを忘れないようにしましょう。

## SQL の実行計画を見ること
必要なデータを DB から取得する際は SQL を書くかと思いますが、ちょっとした記述の違いによって実行計画が大きく変わってしまい、処理量がかなり変わってくることがあるので、なるべく処理が重くならないような SQL を書くことを心がけましょう。

## 条件を肯定文で書く
メソッド名やフラグを名などに否定系をあまり多用しすぎると、理解に時間がかかってしまうので、肯定文で書くことを心がけましょう。

# コミュニケーション編
## 仕様に関する質問は徹底する
既存システムの案件に新たに参画した場合は、コードだけでは、それが意図することや、背景を完全に読み取れない時が多々あります。また、ドキュメントが完備されてない現場も往々にしてあります。

その時は、シンプルに前任者、または、チームメンバーに聞きましょう。聞かないで自分なりの解釈で進んでいくことのほうが危険です。

## 曖昧な言葉を使わない
お互いの認識の齟齬に気がつかないまま開発が進んでいくと、あとで大事になりかねません。そんな事態にならないためにも「相手が何を意図しているか」「認識は合っているか」を頻繁に擦り合わせる必要があります。

会話に厳密性を求めることは、人によっては「しつこい」と思われてしまうかもしれませんが、曖昧な状態で進んでいくことのほうがより危険です。
【C++Buider】TChartでBottomAxisが動かないとき

プログラムでTimerで
```
  // グローバルに宣言
TDateTime mintime;

// Timerでの処理
mintime= mintime+TDateTime(0,0,1,0); // 表示する最小時刻を1秒更新
Chart->BottomAxis->Maximum = mintime + TDateTime(0,0,5,0); // 5秒間ぶん表示
Chart->BottomAxis->Minimum = mintime;
```
みたいに指定することによって、測定時間経過に合わせてChartが動くようにしていたのに、Chartは動くんだけどChartの動きに合わせて一緒にAxisが動かなくなってしまったのでメモ書き。

調べたところ、BottomAxisのStyleのRoundFirstにチェックが入っていませんでした。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274481/aec5239a-97f0-3dda-9d17-1c4e7b6654c6.png)

RoundFirstにチェックが入っていないと、plotしたデータに合わせてAxisを設定してくれないみたい。

ここで、Chartの設定のプレビューができます。わかりやすい。
https://www.steema.com/files/public/teechart/html5/latest/demos/axes/allaxes.htm
[学習メモ] git clone でリポジトリを取得して、自分のリポジトリにpushするまでの流れ

## 目的
学習用の更新できないリポジトリをクローンし、自分のリポジトリに反映する方法整理する為作成しました。<br>本来なら修正した内容のプルリクエストを作成してマージする流れなので、自分用のメモです。



### 以下を整理します
* クローンとは何なのか
* クローン実行後の状態
* push先を変更する理由

## クローンとは何なのか
リモートリポジトリの全内容を、新規でローカルリポジトリにそのままコピーしてくること<br>コードなどのファイル、コミット履歴、ブランチ情報などが含まれている

## フォークを使ったクローンとの違い、どちらを使うか
#### フォーク
コピー元リポジトリを自分のリモートリポジトリにコピーすること。学習目的以外にOSSの改修でも使用される。
フォーク後、ローカルへクローンすることでpush先が自分のリポジトリに切り替わる。


利点 ⇛ push先のoriginを変更する作業が不要になる
注意点 ⇛ フォークしたことがクローン元に通知される

<br><br>今回は通知が不要なのでフォークしない方法で作業しました



## クローン実行
### 1. GitHub上の操作：クローンしたいリポジトリのアドレスをコピー
1. クローンしたいリポジトリのページに移動し、ファイルの一覧の上にある「<> Code」をクリック
1. 「HTTPS」タグのURLの右側をクリックしてコピー

### 2. ターミナル上の操作：クローン実行
1. クローン先のディレクトリに移動
2. リポジトリをローカルリポジトリにクローン
```sh
$ git clone https://github.com/他のユーザー/他のリポジトリ.git
```
    
### 確認： `git clone`実行後の状態
* ローカルリポジトリ(.gitディレクトリ)が作成され、コミット履歴、ブランチ情報などがコピーされる
* クローン元のリポジトリ名のついたディレクトリが、内容とともにコピーされる
* クローン元のリモートリポジトリが、originという名前でfetch元とpush先に登録される
```sh
$ git remote -v
origin  https://github.com/他のユーザー/他のリポジトリ.git (fetch)
origin  https://github.com/他のユーザー/他のリポジトリ.git (push)
```
    
    
### 分かった事
このままpushしたら内容がクローン元に反映されてしまうので、push先を変更する。
コミット後の履歴に知らない履歴があっても、クローン元の履歴をローカルにコピーした為であり、push先を変えればクローン元に反映されない。

### 3. GitHub上の操作：自分のgithubにリポジトリを作成
1. マイページのヘッダー右上隅で「＋」を選択し、「New repository」をクリック
2. 「Repository name」を作成
3. 画面下、緑色の「Create repository」をクリック

### 4. ターミナル上の操作：作成したoriginをpush先に変更
```sh
$ git remote set-url origin https://github.com/自分のユーザー名/自分のリポジトリ名.git 
```
リモートリポジトリのpush先を変更するコマンド。
push先のoriginを、クローン元のリモートリポジトリから自分のリモートリポジトリに変更する。
   
### 確認：push先を変更する理由
ここで代わりに 
```sh
$ git remote add origin
```
とすると、originは既に登録済みと言われてエラーになる
```sh
error: remote origin already exists
```
上記は新規にリモートリポジトリを追加するためのコマンドで、クローン元をoriginに登録済みであることが原因

### 5. push先が変更されていることを確認
```sh
$ git remote -v
origin  https://github.com/自分のユーザー名/自分のリポジトリ名.git(fetch)
origin  https://github.com/自分のユーザー名/自分のリポジトリ名.git (push) 
```

### 6. コードを修正

### 7. 変更をリモートリポジトリに反映 
```sh
$ git add .
$ git status 
$ git commit -m "修正内容のコミットメッセージ" 
$ git log 
$ git push origin main 
```
<br><br>
##

##### 参照URL
https://docs.github.com/ja/repositories/creating-and-managing-repositories/cloning-a-repository
https://docs.github.com/ja/get-started/getting-started-with-git/managing-remote-repositories
https://qiita.com/nt-7/items/c5ea999a2638e03ee418
https://docs.github.com/ja/pull-requests/collaborating-with-pull-requests/working-with-forks/fork-a-repo
TOEIC600点から855点にするためにやった勉強

# モチベーションと背景

自分が通っている大学では、TOEICで750点以上取れば、必修の英語の授業が単位認定される仕組みがあったので、大学の1年の始めから、TOEICの勉強を始めました。

入学してすぐに受けたTOEICの試験では、600点でした。僕自身、英語に対して何か苦手意識はありませんでしたが、得意という感じでもありませんでした。文法については、高校レベルはある程度は理解していたくらいです。

最終的に、半年後の夏休みに745点、1年後の春休みに855点をとることができました。


# 勉強法
結論からいうと、僕は[abceed](https://www.abceed.com/)というアプリに課金して、学校の登校時間にかなり勉強していました。　個人的にこのアプリはオススメです。問題を解くごとに、予想スコアが上がっていくのが面白く勉強しやすかったです。すこし、値段はしますが、参考書や過去問をたくさん買うよりかはいいと思います。毎年4月にキャンペーンで1年分が半額になるのでそこで買うのがオススメです。（多分）

[TOEIC L & R TEST 出る単特急 金のフレーズ](https://www.amazon.co.jp/TOEIC-TEST-%E5%87%BA%E3%82%8B%E5%8D%98%E7%89%B9%E6%80%A5-%E9%87%91%E3%81%AE%E3%83%95%E3%83%AC%E3%83%BC%E3%82%BA-%E7%89%B9%E6%80%A5%E3%82%B7%E3%83%AA%E3%83%BC%E3%82%BA/dp/4023315680)という本のみ買いましたが、これもアプリに入っていました。でも個人的には単語を覚えるときは紙の方が覚えやすかった気がします。

## まずは単語

TOEICはビジネスよりの単語が多く出てきます。そこで、最初は単語をひたすら覚えるようにしました。単語帳を1冊かって、それを例文とかも読みながら覚えるようにした方がいい気がします。ある程度、その単語帳の単語が覚えてこれるようになったらどんどん問題を解いていきます。

## 次に、part5の問題を解きまくる

ある程度単語を覚えてきたら、問題を解きまくりました。ここでは、パターンが色々あるので、それについて問題の傾向を掴んでいきます。時間が割とシビアなので、早く解けるようにもしていきます。ここで大事なのは、どれだけ多くの問題を解けるかだと思います。それと、回答の選択肢に出てくる単語も問題を解いていくうちに覚えるようにしてきます。

僕はアプリでひたすら問題を解いていました。Part5はとりあえず、「TOEIC L&Rテスト 文法問題 でる1000問」という本を2周くらいするのがオススメです。（この本もアプリに課金すれば見れます。)

## リスニングはpart1,2から

リスニングに関しては、どれだけ耳が慣れるかで決まります。これに関しても、アプリでひたすら問題を解いていました。ここで大事なのは、同じ問題でも何回も聞くことです。繰り返し聞く時には、まずスクリプトをみて英文を見ながらきく、次に何も見ずにきいて理解できるようにします。ここで、聞くときにその場面を想像しながら聞くよううにしてください。個人的に、繰り返し聞くときに頭の中で場面を想像しながら聞くようにすると、初見でも音声を聞いただけでその場面が想像できて正解しやすくなります。


## リスニングのpart3,4
このリスニングpart3,4も慣れが重要です。慣れてくれば、ある程度次に、どんな内容が話されそうという予測もできます。リスニングが読まれる前に、選択肢を見ておき、分かった時点でマークしていくことが重要です。このリスニングも、何度も音声は聞いて、聞いただけで、すんなりその場面がイメージできるまで聞いてください。

## part6,7

長文読解です。これもまた、長文をひたすら読むことが大事です。最初はゆっくり読んで、解答する。その後解答をみて、ある程度内容理解した状態で、時間を決めてこの速度で読むようにしていけばいいのだということを覚えていきます。

## 苦手のpartの問題をひたすら解く
abceedの場合、このpartの問題を解きましょうというものが出てくるのでそれに従ってひたすら問題を解いていきます。ここで重要なのは、問題を解いて、しっかりその問題に出てきた単語や熟語、言い回しなども覚えるようにしてください。同じような単語や熟語、言い回しがよくできます。


## 模擬試験を解く

abceedのアプリでは、模擬試験を解くことができます。まとまった時間が取れる時は、2時間くらい時間をとって本番だと思って、模擬試験を解いていきます。そして、その時点での自分の実力を理解して、自分の苦手分野を克服するようにしていきましょう。大学生なら、長期休みに、模擬試験or公式問題集(アプリにはないけど、だいたい図書館で借りれる)を何度か受けてから、本番に進むことがオススメです。

## 毎日やることを意識

リスニングは特に、毎日聞くことで、だいぶ変わってきます。通学時間、通勤時間などに、聞くことをオススメします。TOEICは、しっかりと対策をすれば点数は絶対に伸びていきます。目標を定めて、それに向けて、毎日コツコツ勉強していきましょう。

## 目標は高く

個人的に、目標を750点にしていましたが、勉強してから半年のときには、745点でした。そこで、目標は高く設定していた方がいいと思い、目標を900点にして勉強して、855点取れました。本当に自分が取りたい点数より100点ぐらい上を目指して取り組んでください。
Railsでのユーザー削除の実装方法

# はじめに
この記事では、Railsでユーザーを削除する方法について紹介します。
追加で削除時に確認ダイアログを表示させ、削除が成功したかどうかを通知する仕組みも紹介します。

# 1. ルーティング設定
config/routes.rb ファイルで、destroy アクションに対応するルートを設定します。
```
resources :users, only: [:index, :show, :destroy]
```

# 2. コントローラーの実装
まず、削除処理はコントローラーの **destroy** アクションで行います。削除が成功した場合には一覧画面へリダイレクトし、失敗した場合には個別詳細画面にリダイレクトしてエラーメッセージを表示します。
```
def destroy
  if @user.destroy
    redirect_to users_path, notice: 'ユーザー情報が正常に削除されました'
  else
    redirect_to user_path, alert: '削除に失敗しました'
  end
end
```
***補足***
@user.destroy: 該当のユーザー (@user) を削除します。
redirect_to: 削除後のリダイレクト先を指定し、成功時には通知メッセージ (notice) を、失敗時にはエラーメッセージ (alert) を表示します。

# 3. ビューで削除ボタンを追加
削除ボタンをビューに追加し、削除リクエストを送信します。ここでは、削除ボタンを押した瞬間削除されるのは少々怖いと思いますので、削除する前に確認ダイアログを表示させ、誤削除を防止します。

```
.actions
  = link_to 'ユーザーの削除', user_path(@user), method: :delete, data: { turbo_method: :delete, turbo_confirm: '本当に削除しますか？' }, class: 'delete-button'
  ```
***補足***
method: :delete: 削除リクエストを送信します。
data: { turbo_confirm: '本当に削除しますか？' }: ユーザーに削除確認のダイアログを表示します。
class: 'delete-button': ボタンのスタイルを編集するためのクラスを追加しています。

# 4. まとめ
以上のコードを使用することで、Railsアプリケーションでユーザーを削除する機能を簡単に実装できます。確認ダイアログを使用することで、ユーザーの誤操作を防ぐことができ、ユーザー体験を向上させることができます。
smallタグの用途(copyrightに適切な理由)

## アジェンダ
`small`タグは、シンプルにテキストを小さく表示する手段として、著作権表記に最適です。他の用途でも使用可能ですが、補足情報を控えめに表示する場面で特に使用されます。

## smallタグが著作権表記に適している理由

HTMLの`small`タグは、主に補足的な情報を小さく表示するために使われます。このタグは、視覚的に控えめな要素を作るのに適しており、特に著作権表記に頻繁に使用されます。著作権表記はページの主要なコンテンツではなく、ページの下部やフッターに目立たない形で配置されることが一般的です。

### なぜsmallタグが著作権表記に適しているのか

著作権表記は、補足的な情報でありながらもページに含める必要があります。`small`タグを使うことで、この情報を主なコンテンツの邪魔にならずに表示することができます。テキストを小さく表示することによって、目立たせる必要のない情報を視覚的に整理し、ページ全体のデザインをより一貫させることができます。

### smallタグは他に使われることがあるのか？

`small`タグは、主に著作権や免責事項のような補足情報に使用されることが多く、他の場面ではあまり使われることがありません。現代のWebデザインでは、スタイルシートを使ってフォントサイズを細かくコントロールすることが一般的になっているため、`small`タグ自体が使われる頻度は減ってきています。

## 参考
- [smallタグの正しい使い道を考える #初心者 - Qiita](https://qiita.com/7note/items/312bd0533a040a9201c0)
【astro】ビルド時に生成されるファイル名について



astroはビルド時の出力ファイル名をbuild.formatで設定できる。

```
export default defineConfig({
  devToolbar: { enabled: false },
  compressHTML: false,
  build: {
    format: 'ココ！',
    inlineStylesheets: 'never',
  },
```

## 種類

### file
```
  build: {
    format: 'file',
    inlineStylesheets: 'never',
  },
```
#### 生成されるHTMLファイル
```
src/pages/index.astro -> dist/index.html
src/pages/foo/index.astro -> dist/foo.html
src/pages/foo/bar.astro -> dist/foo/bar.html
```

### directory
```
  build: {
    format: 'directory',
    inlineStylesheets: 'never',
  },
```
#### 生成されるHTMLファイル
```
src/pages/index.astro -> dist/index.html
src/pages/foo/index.astro -> dist/foo/index.html

```

### preserve
```
  build: {
    format: 'preserve',
    inlineStylesheets: 'never',
  },
```
※Astro v4.3以降
#### 生成されるHTMLファイル
```
src/pages/about.astro -> dist/about.html
src/pages/about/index.astro -> dist/about/index.html
```
RPCエンドポイントを利用してウォレットを実装してみる ＃３特定トランザクションの情報表示 

# テーマ設定
RPCエンドポイントを利用してウォレットのトランザクション表示機能を実装してみる。

# 前提環境
+ Node.js がインストールされている。
+ Web3.js ライブラリがインストールされている。

+ RPCエンドポイントを取得（無料）
https://cabinet-node.com/ja/docs/user-guide/create-access-token

### web3のインストール
```bash
npm install web3
```

# 実装
以下の内容でget_transaction.jsファイルを作成してください。
 ```js
const { Web3 } = require('web3');

// RPCエンドポイントを設定
const web3 = new Web3('https://gateway-api.cabinet-node.com/{access_token}');

// 取得したいトランザクションハッシュを設定
const txHash = '0x83d9c6efacf9eb72645f2c65c8ed786925aceb5b8ea2a154b247d8c498a4fc59';

async function getTransactionByHash() {
    try {
        // トランザクションをトランザクションハッシュで取得
        const transaction = await web3.eth.getTransaction(txHash);
        
        if (transaction) {
            console.log('Transaction Details:', transaction);
        } else {
            console.log('No transaction found for this hash.');
        }
    } catch (error) {
        console.error('Error fetching transaction:', error);
    }
}

getTransactionByHash();

 ```

 # 実行
  ```
node get_transaction.js
  ```

### 結果の例

```bash
Transaction Details: {
  blockHash: '0x54de2004be133565c0c6ee14b5daff080c07b027af2ef820ace86b44ed6a28e2',
  blockNumber: 20781385n,
  from: '0x4838b106fce9647bdf1e7877bf73ce8b0bad5f97',
  gas: 22111n,
  gasPrice: 14477399888n,
  maxFeePerGas: 14477399888n,
  maxPriorityFeePerGas: 0n,
  hash: '0x83d9c6efacf9eb72645f2c65c8ed786925aceb5b8ea2a154b247d8c498a4fc59',
  input: '0x',
  nonce: 695907n,
  to: '0x388c818ca8b9251b393131c08a736a67ccb19297',
  transactionIndex: 176n,
  value: 223512263928036655n,
  type: 2n,
  accessList: [],
  chainId: 1n,
  v: 0n,
  r: '0xa112d06391657c87e31f4bc5b87306df19909c0755aeb3a6dd6b6c798837ccbc',
  s: '0x5fc93f922e227978109ff75ae8f07d5a1049bd86b46273a734d81f56c4631df2',
  data: '0x'
}
```
RevenueCatの東京ハッカソンのためのAI駆動アートギャラリーツアーアプリケーションのプロンプト作成


最近、開発者チームと私はRevenueCatの東京ハッカソンのためにiOSアプリケーションの開発を始めました。RevenueCatを使用したサブスクリプション機能を備えたアプリケーションを2週間で作成するという課題がありました。私たちのアイデアは、パーソナライズされたアートギャラリー展示会の推薦を作成することでした。ユーザーがアプリケーションに親近感を持ち、価値ある情報を得られれば、毎月のサブスクリプション料金を喜んで支払うだろうという仮説を立てました。
これを実現するために、主な目標として、ユーザーが共感できる東京のアートギャラリー展示会を見つけ、旅行の計画を立て、展示会に関するパーソナライズされた情報を提供することに取り組みました。
アプリケーションをパーソナライズするために、ユーザーの現在の「雰囲気」を理解するための3つの異なるタイプの選択肢を用意しました。これらのタイプは音、質感、色でした。これらの選択を使用して、以下のことを行う方法を見つける必要がありました：

「雰囲気」に基づいてパーソナライズされたギャラリー展示会の説明を作成する。
ユーザーの選択（「雰囲気」）と無関係な展示会をフィルタリングする。

チームのバックエンド開発者が複数のAmazonサービスを使用していたため、AI関連のAPI呼び出しのソースとしてAmazon Bedrockも使用することにしました。BedrockでアクセスできるAnthropicのClaude 3.5モデルを使用することにしました。
このチャットAPIでのプロンプト作成は、主にシステムプロンプトとユーザー入力を使用します。
私たちのアイデアは、ユーザーの雰囲気の選択を使用して、各ギャラリーに対して最初に提供できる基本的な説明に基づいて、新しいギャラリー展示会の説明を作成するプロンプトシステムを作成することでした。
最初の反復は以下のようなものでした：
システムプロンプト
「あなたは、3つのユーザー選択を使用して、以下に元々記述されているアート展示会の新しい説明を書くモバイルアプリケーションです。ユーザーの選択を使用して、ユーザーがギャラリーを好む理由を説明し、展示会とユーザーの選択との関連性を強調してください。」
元の展示会の説明：
「魚は水の中にいることを知らない」は、...（ここに完全な展示会の説明が記載されていました）
そのシステムプロンプトを使用して、アプリでユーザーの選択を取得し、単純にそれらをユーザー入力に以下のように入力しました：
ユーザー入力
「ユーザーの選択：「ピンク色」、「プラスチックの光沢のある質感」、「海の音」」
この設定は非常にうまく機能し、ユーザーの選択に基づいた新しくユニークなギャラリー展示会の説明を生成しました。
次に行うべきことは、ユーザーの選択と無関係なギャラリーをフィルタリングする方法を追加することでした。そのために、システムプロンプトにテキストを追加して、「関連性スコア」と呼ぶものを作成しました。プロンプトのテキストは単純に以下のようなものでした：
「また、ユーザーの選択が展示会の説明にどの程度関連しているかを、100点満点で数字で示してください。」
それは機能し、数字も返されました。次に、APIで読み取り可能にするだけでよかったので、単にJSON形式のレスポンスを要求しました。
「あなたの回答は以下のようなJSON形式でフォーマットされるべきです：
{
newExhibitionDescription: string,
connectednessRating: number,
}
」
そして、新しいパーソナライズされた展示会の説明と、関連性のない展示会をフィルタリングするために使用できる関連性スコアが完成しました。ハッカソンの2週間以内にすべてのプロンプト作成を機能させ、サブスクリプション機能を有効化することができました。達成できるかどうか確信が持てませんでしたが、実現し、今日ではアプリストアでアプリを見つけることができます！
この技術を使用することで、ユーザーが本当に楽しみ、喜んで支払いたいと思うパーソナライゼーションをアプリに組み込むことができました！
ESP32をBluetoothキーボードにした際、データが正常に入力できない時の対処法

前回ESP32でBluetoothのキーボードを作成したが、
https://qiita.com/Kurogara/items/e847e2fac57a61215b70
連続した文字を入力した際、正常に入力できない現象が発生していた。

前回の対処法は「123」を送信したい場合、
「bleKeyboard.print("1");」の後に「delay(100);」を入れることで、
「123」を入力していた。
以下がそのソースコード
```c
#include <BleKeyboard.h>

BleKeyboard bleKeyboard("TESTBLE");

int LED_PIN = 5;
int BUTTON_PIN = 6;
int SWITCH_PIN = 7;
int back_data = 0;

void setup() {
  // put your setup code here, to run once:
  pinMode(BUTTON_PIN, INPUT_PULLUP);
  pinMode(SWITCH_PIN, INPUT_PULLUP);
  pinMode(LED_PIN, OUTPUT);

  bleKeyboard.begin();
}

void loop() {
  if (bleKeyboard.isConnected()) {
    digitalWrite(LED_PIN, HIGH);
    if (digitalRead(SWITCH_PIN) == 0) {
      if (back_data == 0) {
        bleKeyboard.print("1");
        delay(100);
        bleKeyboard.print("2");
        delay(100);
        bleKeyboard.print("3");
        delay(100);
        bleKeyboard.press(KEY_LEFT_SHIFT);
        bleKeyboard.press(KEY_TAB);
        delay(200);
        bleKeyboard.releaseAll(); // すべてのキーを離す
        back_data = 1;
      }
    } else if (digitalRead(BUTTON_PIN) == 0) {
      if (back_data == 0) {
        bleKeyboard.write(KEY_TAB);
        delay(100);
        back_data = 1;
      }
    } else {
      digitalWrite(LED_PIN, LOW);
      back_data = 0;
    }
  } else {
    digitalWrite(LED_PIN, LOW);
  }
}
```
実際はsetDelayを入れるだけで対処ができた。
```c
  bleKeyboard.begin();
  bleKeyboard.setDelay(50);
```
変更後のソースコードは以下。
```c
#include <BleKeyboard.h>

BleKeyboard bleKeyboard("TESTBLE");

int LED_PIN = 5;
int BUTTON_PIN = 6;
int SWITCH_PIN = 7;
int back_data = 0;

void setup() {
  // put your setup code here, to run once:
  pinMode(BUTTON_PIN, INPUT_PULLUP);
  pinMode(SWITCH_PIN, INPUT_PULLUP);
  pinMode(LED_PIN, OUTPUT);

  bleKeyboard.begin();
  bleKeyboard.setDelay(50);//←ここが追加箇所
}

void loop() {
  if (bleKeyboard.isConnected()) {
    digitalWrite(LED_PIN, HIGH);
    if (digitalRead(SWITCH_PIN) == 0) {
      if (back_data == 0) {
        bleKeyboard.print("123");
        back_data = 1;
      }
    } else if (digitalRead(BUTTON_PIN) == 0) {
      if (back_data == 0) {
        bleKeyboard.write(KEY_TAB);
        delay(100);
        bleKeyboard.press(KEY_LEFT_SHIFT);
        bleKeyboard.press(KEY_TAB);
        delay(200);
        bleKeyboard.releaseAll(); // すべてのキーを離す
        back_data = 1;
      }
    } else {
      digitalWrite(LED_PIN, LOW);
      back_data = 0;
    }
  } else {
    digitalWrite(LED_PIN, LOW);
  }
}
```
AWS生成 AI (Betrock)を勉強しよう

お久しぶりです。nishiokaです。
最近案件が佳境なこともあり、2回目なのに久しぶりの更新になってしまいました。
最近AWSのAI資格が出たみたいですし、簡単に今回の記事でAWSの生成AIについて学んでみましたので、その内容を簡単に記事にしてみます。

-----------------------------------------------------------------------------------

今回はAWS　Betrockで機械学習の勉強をしてみましょう。

AWS Betrockは各社が出している生成AIモデルをAWS上で利用できるプラットフォームであり、モデルを有効化することで、我々も利用することが可能です。
Betrockを使用する際は**バージニア北部、もしくはオレゴンリージョンを指定するのがおすすめ**です。
なぜなら、この二つが生成AIモデルの開発が進んでいるからです。
ただ、始めから生成AIのモデルが有効化されているわけではありません。

では今回はバージニア北部でモデルを有効化してみましょう。
モデルを有効化の際は大量にメールが届きますが、料金は発生しませんのでご安心ください。

**1.モデルを有効化してみよう**

**Amazon Betrockへアクセスし、「モデルアクセス」を選択**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3873642/58b0b3e5-37e2-1251-f4a8-65bbd0740d95.png)

**「Enable all models」をクリック**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3873642/8888d032-31eb-ff02-ad35-c6d3275c5897.png)

**「Next」をクリック**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3873642/b3cc9f87-db80-b128-a0f4-3bfb16dbef3b.png)

**「Submit」をクリック**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3873642/5931c502-a3a2-8e0b-f720-e46fd130876c.png)

**するとモデルが有効化されました**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3873642/56225492-21be-db29-2ce5-8a1da283c50c.png)

今回は私はすでにオレゴンリージョンでBetrockのALモデルを解放していたので、そのままパスされましたが、
場合によっては、簡単なアンケートに答える必要があります。

会社名や使用用途をきかれますが、勉強用と答えとけば問題無いです。
だいたいすぐにモデルは有効化されますが、遅いときは1日かかるモデルもあるみたいです。
また、用途の部分で**医療用といった大きな責任のかかる使用用途は書かないでください。**
その場合、AWS側もモデルを貸すことに慎重になってしまうからです。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3873642/01942c4f-3864-009f-502a-43e02305e018.png)

**2.モデルをみてみよう**

**概要から各社が出している生成AIモデルを確認することができます。**
今回はClaude3.0sonnetを見てみましょう。(後々上げる記事に使うモデルだからです。)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3873642/fb29fd67-b25a-6722-e9bf-0b86689544e0.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3873642/fcbeee4d-c64a-6d51-2f6d-7a467521c25b.png)

**概要からは、用途、API、ARN、Maxトークン数を確認することができます。**
このMaxトークン数とはモデルが一度にどれだけのトークンを記憶できるかという意味です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3873642/0e808b08-16fe-59a8-b2ab-8f7ee80e576f.png)

余談ですが、トークン数とは単語数のことではありません。
OpenAIが出している、Tokenizerというツールでトークン数について確認してみましょう。
https://platform.openai.com/tokenizer

下図の結果のとおり、**基本的にひらがな等は一文字1トークンですが、漢字は2トークン以上必要なことがわかります。**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3873642/db6d6a64-a2fb-54b4-3e36-7f7d42442709.png)

**3.モデルを試してみよう**

ーーーーーーーー疲れたのでまた続きは後日更新します------------------------------------
revertのrevertで復活させたファイルが別ブランチで復活しない

一度revertで削除したファイルをバグがなくなったため復活させることにした。
開発ブランチでrevertのrevertを実施すると問題なくファイルが復活するが、releaseブランチにマージしてもreleaseブランチではファイルが復活していなかった。
開発ブランチにあるファイルがマージで反映されない事態に違和感を覚えたため調査した。

以下revertのrevertは長いのでreapplyと呼ぶ。

## 再現コード

簡略化したコードは下記。

```sh
echo "hello, world" > file
git add file
git commit -am "add file"

git branch dst
git revert <add fileしたcommit> --no-edit

git switch dst
git cherry-pick <revertしたcommit>

git switch src
# revertのrevert
git revert <revertしたcommit> --no-edit

git switch dst
git merge src
# fileが存在しない
```

```mermaid
%%{ init :
    {
        "theme"     : "default"
    ,   "gitGraph"  : {
            "mainBranchName"    : "src"
        }
    }
}%%

gitGraph


%% echo "hello, world" > file
%% git add file
%% git commit -am "add file"
checkout src
commit id: "add file"

%% git branch dst
branch dst
checkout src

%% git revert <add fileしたcommit> --no-edit
commit id: "Revert: 'add file'" type: REVERSE

%% git switch dst
%% git cherry-pick <revertしたcommit>
checkout dst
cherry-pick id: "Revert: 'add file'"

%% git switch src
%% # revertのrevert
%% git revert <revertしたcommit> --no-edit
checkout src
commit id: "Revert: Revert: 'add file'" tag: "Reapply 'add file'"

%% git switch dst
%% git merge src
%% # fileが存在しない
checkout dst
merge src id: "Merge 'src'" tag: "file not revived" type: HIGHLIGHT
```

最新のdstの`git log`の結果を見てみると以下の2つの歴史をマージしている
1. revertしてreapplyしたブランチ(src)
1. revertしたブランチ(dst)

```
% git log
commit 900dd818dee2762ad842428d75125e158177ad08 (HEAD -> dst)
Merge: 63f39e5 54c0ecd
Author: myoan
Date:   Thu Sep 19 08:55:38 2024 +0900

    Merge branch 'src' into dst       

commit 54c0ecd0ef0c9c0fa0b6a003e740698b53e83961 (src)
Author: myoan
Date:   Thu Sep 19 08:54:49 2024 +0900               

    Reapply "add file"                               

    This reverts commit 0ac88a74c84d2822d1592b42dee42e526ec1250e.

commit 63f39e5ba70fe038863ac887ccb974e8e6428f23 
Author: myoan
Date:   Thu Sep 19 08:05:23 2024 +0900          

    Revert "add file"                           

    This reverts commit 7e7eb9b6a126469407af3715433bb775179a4567.

commit 0ac88a74c84d2822d1592b42dee42e526ec1250e
Author: myoan
Date:   Thu Sep 19 08:05:23 2024 +0900        

    Revert "add file"                         

    This reverts commit 7e7eb9b6a126469407af3715433bb775179a4567.

commit 7e7eb9b6a126469407af3715433bb775179a4567
Author: myoan
Date:   Thu Sep 19 08:04:36 2024 +0900      
                                            
    add file
```

3-way mergeで考えるとsrcブランチはrevertとreapplyをしているため実質base commitとの差分がない。
対してdstはrevertしてるためファイルが削除されている。
そのためマージしてもファイルが削除された(=復活していないように見えた)。

今回はrevertやcherry-pickを題材にいているが本件に関係はなく、単純なファイル追加・削除でも再現する。
問題の本質はmergeのタイミングでbaseと`HEAD`, baseと`MERGE_HEAD`それぞれのdiffが思い描けてなかったことにある。

## 対策

もしも発生してしまったら、該当ファイルを削除してdstにマージ、ファイルを復活させてdstにマージ。とするのが簡単か？

個人開発ならともかく、チーム開発しているとdiffを思い描くなんて無理な話である。
ブランチ戦略を変えずに防止・検知する仕組みも考える。

すぐ思いつくのはcherry-pickをした後に srcがdstをマージすることである。
(2つのブランチの歴史が異なるほど安全とは言えないかもしれない)
その上でreapplyをすれば、dstがsrcをマージしてもfileが追加される。
他にはsrc, dstのdiffを定期的に取って確認をすることも有用そう。

## 更新履歴

2024/09/20 @gyokuto さんにgit graphを記述していただきました。ありがとうございます。
ハッカソンに参加したものの、途中でリタイアした話

こんにちは。今回は、先日参加したハッカソンでリタイアすることになった経験について書きます。

ハッカソンという短期間での開発は、新しい技術に触れたり、チームでの開発を経験できたりする貴重な機会ですが、私たちのチームは途中で解散し、最終的に目標を達成することはできませんでした。この経験を振り返ることで、自分自身が学んだことや、今後に活かすべき教訓を整理していきたいと思います。


## ハッカソン参加の背景
私はこれまでにハッカソンに参加したことはありませんでした。今回参加したハッカソンでは、モバイルアプリとRevenueCatというサブスクリプション管理をするSDKを使用して、アプリ内課金の機能を実装することを目標としていました。

## チーム編成とプロジェクトの進行について
今回のハッカソンでは、3人のチームを組んで開発を進めることになりました。リーダーの方はWeb開発に精通しており、すでにWebアプリのプロトタイプを作成していました。そして、ハッカソンの後もWeb側でアプリ開発を続けたいというリーダーの意向により、ネイティブ側でのRevenueCatの実装は行わず、Web SDKを使用して機能を完結させる方針が決まりました。これにより、私ともう一人のiOSエンジニアの方の役割はWebViewを用いてWebアプリをネイティブアプリ上で表示するだけの実装となりました。単にWebViewでラップしたアプリをリリースする場合、Apple側の審査でリジェクトをもらうと考えていたため、最小限の機能で一度アプリを審査に出し、その後必要な対応を取っていく方針となりました。

## 途中でのリタイア
冒頭でもお伝えしたとおり、私たちのチームはハッカソン開始から数日でチームを解散することになりました。
チームが解散した理由として、リーダーが抱えていた現実的な課題がありました。具体的には、Google Playで個人情報（本名、電話番号、住所）を公開する義務があるため、プライバシー保護の観点から躊躇されていました。また、AppleのApp Storeでは、30％の手数料がかかることに加え、開発者プログラムへの登録手続きでも問題が発生し、登録が完了しない状態も続いていました。これらの理由から、リーダーはアプリをストアでリリースしないという決断を下しました。

リーダーの決定は、チームの解散に繋がってしまいましたが、彼の意思決定を素直にチームメンバーに伝えてくださったことは感謝しています。もともとアプリを開発したいとの思いでハッカソンに参加されていたと思うので、難しい決断だったと思います。でも、開発が本格的に始まる前に彼の気持ちを正直に伝えてくれたのは、とても勇気のある行動だと感じました！

## まとめ
この経験から学んだことは、プロジェクトの方針を明確にして、チーム内で共通の目標を持つことの重要性です。特にハッカソンのような短期間で成果を出さなければならない場では、プロジェクトの現実的な制約や、ビジネス面での課題を考慮しながら進めることが大切だと感じました。また、リーダーが抱えていた課題に対して、もっと早い段階でサポートできる余地があったのではないかと個人的に反省しています。

読んでいただきありがとうございました！
【PowerShell】タスクスケジューラで実行すると"Internet Explorer エンジンを使用できないエラー"IE初回起動設定してもなおらない初歩的なミス

## 事象・エラー内容

WindowsのタスクスケジューラでPowerShellのバッチを実行すると、下記のエラーが発生していた。

```
Internet Explorer エンジンを使用できないか、Internet Explorer の初回起動構成が完了していないため、応答のコンテンツを解析できません。UseBasicParsing パラメーターを指定して再試行してください。
```

原因をググると、どうやらインターネット上のWebページからコンテンツを取得する「Invoke-WebRequest」というコマンドでこのエラーが起こっているようで、IEの初期起動時に表示される設定を行えば解消されるみたい。
または別の対応として、「-UseBasicParsing」のオプションを付ければ回避できるとのこと。

上記対応のうち前者の初期起動時の設定を行い、再度タスクスケジューラで実行してみた。
しかし、まだ同じエラーが出てくる。
試しに、タスクスケジューラからではなく、手動でPowerShellを実行してみると正常に実行できた。
バッチの問題ではなくタスクスケジューラの設定に原因がある？

## 原因
**タスクスケジューラの実行ユーザが誤っているという初歩的なミス** 

タスクスケジューラでは設定「全般」の中で、セキュリティオプション＞タスクの実行時に使うユーザアカウントで実行ユーザを選択している。

設定されていた実行ユーザが、初回起動構成を試したユーザと異なるため、実行ユーザでもIE11の初期起動構成を設定する必要があった。

実行ユーザでWindowsにログインしなおし、IEの設定をすることで無事実行することに成功！
超初心者向け！Amazon Bedrockのモデル推論APIをわかりやすく解説

## はじめに

「Amazon Bedrockって聞いたけど、よくわからない…」

そんなあなたのために、超初心者向けにAmazon Bedrockのモデル推論APIをわかりやすく解説します。

### モデル推論APIとは？

Amazon Bedrockは、様々な種類のAIモデルを使って、アプリ開発を簡単にできるサービスです。モデル推論APIはその中でも、AIモデルを使って実際の結果を得るための重要なツールです。

例えば、テキストを生成したり、画像を分析したり、翻訳したりといったことを、APIを使って簡単に実行できます。

### 主要なモデル推論API

Amazon Bedrockには、様々なモデル推論APIが用意されていますが、今回は特に重要な4つのAPIをご紹介します。

#### 1. InvokeModel API: 基礎となる汎用API

InvokeModel API は、最も基本的なAPIです。テキストや画像、ベクトルの生成など、幅広いAIモデルに対応しています。モデルの指定や入力パラメータの設定が必要ですが、結果はすぐに確認できます。

#### 2. InvokeModel with ResponseStream API: リアルタイムな結果表示

InvokeModel with ResponseStream API は、チャットアプリのように結果を少しずつ表示したい場合に便利なAPIです。レスポンスをストリームとして取得するため、ユーザーの待ち時間を短縮し、より良い体験を提供できます。

#### 3. Converse API: 対話形式モデルを簡単に利用

Converse API は、対話形式のAIモデルを簡単に切り替えられるAPIです。入力形式が統一されているため、複数のモデル間でプロンプトやパラメータの違いを気にする必要はありません。

#### 4. ConverseStream API: リアルタイムな対話体験

ConverseStream API は、Converse API のストリーミング版で、リアルタイムに近い出力を実現できます。チャットボットなどの開発に最適です。

### バッチ推論: 大量のデータを効率的に処理

バッチ推論は、複数のプロンプトを一括で処理する機能です。Amazon S3 に JSONL 形式の入力ファイルを用意し、CreateModelInvocationJob API でバッチジョブを実行します。この機能は、オンデマンド推論の50%の料金で利用可能で、大量のデータ処理に適しています。

### まとめ

Amazon Bedrock のモデル推論APIは、様々な用途でAIモデルを活用するための強力なツールです。今回の記事では、主要なAPIを簡単に紹介しました。

ぜひ、これらのAPIを使って、あなたのアプリ開発をさらに進化させてください！

### 関係資料
[AmazonBedrockモデル推論b.実践編【AmazonBedrockSeries#実践編】【AWSBlackBelt】-YouTube](https://www.youtube.com/watch?v=YnFch0WIPqw)
[AmazonBedrockモデル推論b.実践編【AmazonBedrockSeries#実践編】【AWSBlackBelt】-PDF](https://www.youtube.com/redirect?event=video_description&redir_token=QUFFLUhqbjBMd1ZXRjJRTHI5T09BRUhpa2xUOGxocEpNQXxBQ3Jtc0tsazI0akRoTjZwa0VqRTA3amtxM05BRE4xUHNfNlhzSWlJYkhTMkc5TEdXeHJjc1lYYzktMUtQRmFuTUhQZGxmWDFZLVFMVEVERnBPMEFOYWRIcGpJamRXSU94N2UzWXZxQmowQXJKZlBCZWVLV0UxMA&q=https%3A%2F%2Fpages.awscloud.com%2Frs%2F112-TZM-766%2Fimages%2FAWS-Black-Belt_2024_Amazon-Bedrock-Model-Inference-b_0909_v1.pdf&v=YnFch0WIPqw)
APEXのFreeワークスペースの取得方法

# APEXとは
Oracle APEXは、Oracle Databaseのためのローコードアプリケーション開発プラットフォームです。クラウド環境でもオンプレミスでも、Oracle Database上であればどこでもアプリケーションを開発・実装できます。

さらに、Oracle Databaseを持っていなくても無償でAPEXを試すことができます。このFreeのワークスペースでは、Oracle APEXが提供するほぼすべての機能を利用可能ですが、ストレージ容量は50MBまでの制限があるため、機能検証や学習以外での利用はできません。

本記事では、Freeのワークスペースの取得方法をご紹介します。

# Freeのワークスペースの取得方法

1. 先ずは、[こちらのページ](https://apex.oracle.com/pls/apex/r/apex/quick-sign-up/request-workspace)に行きます。

2. 氏名・メールアドレス等を入力し、**Request Workspace**をクリックします。
![68747470733a2f2f71696974612d696d6167652d73746f72652e73332e61702d6e6f727468656173742d312e616d617a6f6e6177732e636f6d2f302f333736323230312f30333964316330332d326236662d343830312d666632642d6134333765383730386331612e706e67.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3762201/c512a422-9f00-a4a8-d415-24340cd4462d.png)


3. 入力したメールアドレスにメールが送信されるので確認します（1～2分程度かかります）。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3762201/5aa4374f-1463-9aac-2011-c4f690e01d52.png)

4. **Workspace Request Approved**と記載してあるメールが届いたら、**Create Workspace**をクリックします。
![68747470733a2f2f71696974612d696d6167652d73746f72652e73332e61702d6e6f727468656173742d312e616d617a6f6e6177732e636f6d2f302f333736323230312f65316466656334642d336466632d613232612d613639612d6633306136373931333533322e706e67.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3762201/a6326676-f9cd-be23-ee09-df0b7ea90d28.png)


5. ワークスペースが作成されたので、ワークスペースにサインインします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3762201/515a5f4f-2782-fb0b-bc42-84ec799a99d6.png)

6. ワークスペースのパスワードを変更します。
![68747470733a2f2f71696974612d696d6167652d73746f72652e73332e61702d6e6f727468656173742d312e616d617a6f6e6177732e636f6d2f302f333736323230312f39373034626535362d663238342d363635622d346461332d6165343639306330336438302e706e67.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3762201/23937988-4cf1-dee9-0257-93bfe3641e97.png)


7. これでワークスペースにログインすることが出来ました。
![68747470733a2f2f71696974612d696d6167652d73746f72652e73332e61702d6e6f727468656173742d312e616d617a6f6e6177732e636f6d2f302f333736323230312f34313432303232372d336339372d613433352d663538322d3132343364313565643238392e706e67.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3762201/8cc690d4-39b2-19c7-b4d1-6d4c08118736.png)


Freeの環境を活用し、様々な機能をお試し下さい。
【自己紹介】僕がフリーランスエンジニアを目指そうと考えてから実現するまで

## 軽く自己紹介
私はななみ、フリーランスエンジニアをやりながら、IT企業の採用担当をしています。
新卒でSES企業に入社し、WEBエンジニアとしてキャリアをスタートしました。Javaエンジニアとしてデビューし、HTML、CSS、JavaScriptなどのフロントエンド技術から、PHPやPythonなどのバックエンド技術まで幅広く経験を積んできました。その後、社内で採用業務にも携わるようになり、エンジニア採用についての知見も得ました。
現在はフリーランスエンジニア業務と知人のIT企業の採用業務を両立しながら、生計を立てています。

採用担当としての業務では、特にエンジニアの採用を担当しており、技術的部分はもちろんコミュニケーション能力を持ったポテンシャルの高い候補者を見極めることが私の強みです。自らも現場でエンジニアとして活動していた経験があるため、書類選考や面接の際に、候補者の技術力やポテンシャルを正確に評価することができます。採用活動においては、エンジニア業務以上に楽しみながら業務を行っており、企業のカルチャーやチームに合った人材を見つけるためのスクリーニングプロセスを最適化することに力を入れています。

## フリーランスエンジニアとしての転機
私にとってキャリアの大きな転機となったのは、初めてフリーランスとして案件を探し始めた時です。会社員としての経験を経て、フリーランスエンジニアとしてのキャリアをスタートさせる決断をしました。

しかし、その道のりは簡単ではありませんでした。特にSES企業に勤めていた当初、給料の手取り額が毎月10万円台だった時期があり、何のために働いているのか、自分には社会的な価値がないのではないかと深く悩んでいました。精神的にも辛い時期でしたが、この経験があったからこそ自分を大きく成長させたと思います。

最初に担当になったフリーランスエンジニア向けの専門エージェントさんは私のキャリアに対して深い理解がなく、コミュニケーションにコストがかかり、3年後、5年後、10年後のキャリア展望についてのコンサルティングもほとんど行ってくれませんでした。

そのエージェントさんとは契約をせずに、別のエージェントを探すことにしました。運良くその後にとても優秀なエージェントさんを知り合いから紹介してもらうことができました。そのエージェントさんは私のスキルセットやキャリア目標を深く理解し、私にぴったりのAI関連の案件を紹介してくれました。当時、AIの業務は未経験でしたがAI技術に非常に興味を持っていたため、その案件に参加できたことは大きなチャンスでした。

この案件での経験を通じて、AI分野における知識や技術を実践的に学ぶことができ、エンジニアとしての成長を大きく感じました。また、この案件での成功がきっかけとなり、その後もAI関連のプロジェクトに継続的に関わることができています。

## フリーランスエンジニアを目指す方へのサポート
これまでの経験を通じて、現在はフリーランスエンジニアとして独立を考えている方々へのサポートも行っています。フリーランスとしての最初の案件探しや、どの技術分野に注力するかといったキャリアの方向性についてアドバイスをする機会が増えています。私自身、フリーランスの世界に足を踏み入れた際に多くの不安や課題に直面しましたが、今ではその経験が、これからフリーランスを目指す方の支えになると信じています。

短い時間ではありますが、少しでも今後のキャリアの方向性が明確になったり、現状抱えている不安が解消できるような、良いキッカケとなる時間を過ごしていただけることを大切にしています。特に初めてフリーランスに挑戦する方に対して、エージェントとの付き合い方や案件選びのポイント、スキルを活かす方法について、実体験に基づいたアドバイスを提供しています。

## 今後の展望
今後は、採用担当としてさらに多くの優秀なエンジニアを支援しつつ、エンジニアとしても成長を続けていきたいと考えています。AIや機械学習、クラウドコンピューティングなど、今後もIT業界で求められるスキルセットを深め、常に最前線で活躍できるエンジニアであり続けたいです。

エンジニアが減少しているといわれる日本で、企業の成長に貢献するだけでなく、さらにチャレンジをしたい！と考えてらっしゃるエンジニアのキャリア成長にも寄与できるような活動をしていきたいと考えています。
【Javascript】比較演算子の種類



| 記述 | 意味 |
|:----|:-----|
|a == b|a と b の値が等しい|
|a === b|a と b の値とデータ型が等しい|
|a < b|a が b よりも小さい|
|a > b|a が b よりも大きい|
|a <= b|a が b 以下である|
|a >= b|a が b 以上である|
|a != b|a と b が等しくない|
Arduino UNO 3、ブザー Grove- Buzzer で遊ぶ


参考

![o_coq436.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/f1585cda-fef8-e7f8-2fa6-0b9362378b57.jpeg)

https://wiki.seeedstudio.com/Grove_Starter_Kit_for_BeagleBone_Green/

結果

わかりずらいが確かに音がなった
(発振器内蔵タイプだった)




プログラム![o_coq435.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/19171352-09e3-40d7-a74b-7a2624eb7416.jpeg)


```c++


//Grove_Buzzer_UNO_1

// the setup function runs once when you press reset or power the board
void setup() {
  // initialize digital pin as an output.
  pinMode(14, OUTPUT); //14 = A0
}

// the loop function runs over and over again forever
void loop() {
  digitalWrite(14, HIGH);   // turn the on (HIGH is the voltage level)
  delay(1000);                       // wait for a second
  digitalWrite(14, LOW);    // turn the off by making the voltage LOW
  delay(1000);                       // wait for a second
}


```
Azure と AWS の サーバーレス コンピューティングの主要な違いを個人的に比較

[2024/11/06 追記] サポートするプログラミング言語 の AWS Lambda の記載に Node.js が不足していたため追記し、Azure Functions も Node.js と記載するのが適切と判断し表現を改めました。

Azure Functions と AWS Lambda は、どちらもサーバーレスコンピューティングの主要サービスであり、多くの類似点がありますが、重要な違いも存在します。
この比較では、機能面、性能面、そして特徴的な機能に焦点を当てて両サービスを詳細に比較します。

## 機能面の比較

### サポートするプログラミング言語

- **Azure Functions:** C#, Java, PowerShell, Python, Node.js (JavaScript, TypeScript) [^1]
- **AWS Lambda:** C#, Java, PowerShell, Python, Node.js (JavaScript, TypeScript), _Go, Ruby_ [^2]

[^1]: https://learn.microsoft.com/ja-jp/azure/azure-functions/supported-languages
[^2]: https://aws.amazon.com/jp/lambda/faqs/

### トリガーとバインド/イベントソース

- **Azure Functions:** Azure の各種サービス、タイマー、Webhook など [^3]
- **AWS Lambda:** AWS の各種サービス [^4]
  - タイマーを使用する場合は CloudWatch 等を利用[^5]
  - Webhook を使用する場合は API Gateway 等を利用[^6]

[^3]: https://learn.microsoft.com/ja-jp/azure/azure-functions/functions-triggers-bindings
[^4]: https://docs.aws.amazon.com/lambda/latest/dg/lambda-services.html#listing-of-services-and-links-to-more-information
[^5]: https://docs.aws.amazon.com/ja_jp/sdk-for-javascript/v3/developer-guide/scheduled-events-invoking-lambda-example.html
[^6]: https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/services-apigateway.html

## 性能面の比較

### 最大実行時間

- **Azure Functions:** 従量課金プランであれば 10 分、それ以外の構成なら無制限 [^7]
  - 無制限な場合、固定料金のかかる構成になる (ただ、[プレビュー中の Flex 従量課金プラン](https://learn.microsoft.com/ja-jp/azure/azure-functions/flex-consumption-plan)に希望がある)
- **AWS Lambda:** 15 分 [^8]

[^7]: https://learn.microsoft.com/ja-jp/azure/azure-functions/functions-scale
[^8]: https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/gettingstarted-limits.html

### 最大メモリ割り当て

- **Azure Functions:** 従量課金プランであれば 1.5 GB, それ以外の構成なら構成次第で 14 GB など [^7]
- **AWS Lambda:** 10,240 MB(10 GB) [^8]

## その他

個人的に、非常に大きな特徴と考えているポイントは下記です。

### Azure Functions の特徴: Durable Functions の存在

ステートフルに複数の Functions を連携させたり、非同期な API を構成したりできます。

https://learn.microsoft.com/ja-jp/azure/azure-functions/durable/durable-functions-overview

AWS だと同様の仕組みは Step Functions の利用を検討すると良いかもしれません。

### AWS Lambda の特徴: コンテナを動かす場合も固定費無し

Azure Functions の場合はコンテナを動かす場合に従量課金プランは使用できず固定料金がかかりますが、AWS Lambda の場合は追加料金が不要で動かした分だけ課金です。
(コンテナを用意するための ECR リポジトリの料金は必要)

https://aws.amazon.com/jp/blogs/news/new-for-aws-lambda-container-image-support/

Azure でコンテナを従量課金で動かしたい場合は、Container Apps の利用を検討すると良いかもしれません。
【タスクスケジューラ】無期限を設定しているのに、再起動したらタスク実行しなくなった

## 困ったこと

タスクスケジューラで1時間おきに半永久的に実行させたいが、一度再起動を行うと実行されなくなってしまった。無効→有効にしてみたり、タスクが続いているのかと思ってタスクの終了をしたりしたが、上手くいかない。また次回の実行時刻には日時が入っているが、その時刻になっても実行されない。

## 設定していたトリガー

![タスクスケジューラ_トリガ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549739/15e1f970-7775-ed9b-1b4e-92128d529fd6.png)

## 対処

「毎日、毎週、毎月」に設定している かつ 継続時間を「無期限」に設定していると、
タスクを無効化して再度有効化した場合にうまくいかない場合があるとのこと。
https://jpwinsup.github.io/blog/2023/02/07/UserInterfaceAndApps/Repeat-task-indefinitely-issues/
上記の記事の対応方法に書かれていた通り「毎週」から「1回」に変更すれば、動くようになった。

![タスクスケジューラ_解消.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549739/8ac62316-db7e-310a-3d8a-29fcd79a328a.png)