OmniAICreator/Qiita-1.07M huggingface dataset:
これを見ればテーブル定義書は作れる

# 1. テーブル定義書とは？
テーブル定義書は、データベースにおける各テーブルの仕様を詳細に記載したドキュメントです。
DBの基礎がわからない方はこちらを先に読んでいただければと思います！

https://qiita.com/y-t0910/items/65ece5844e6d1c50a268

**目的:** テーブルの構造と制約を明確にすることで、開発者や運用担当者間での認識のずれを防ぐ。
**対象:** データベース設計者、開発者、運用管理者、関係者など。

# 2. テーブル定義書の構成
テーブル定義書についてイメージしやすくなるように例をだしたいと思います。
こちらはusersテーブルについての画像になります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3823687/ae29f722-708d-fb26-deba-a3da5894dfff.png)


**(1) テーブル情報**
テーブル名（論理名と物理名）
例：顧客情報テーブル（customer）
概要・目的：テーブルが何を管理するのかを説明。
例：顧客の基本情報を格納する。

**(2) カラム（列）情報**
項目名	物理名	型	長さ	NOT NULL	主キー（PK）	備考
顧客ID	customer_id	INT	-	YES	YES	自動採番
名前	name	VARCHAR	50	YES	NO	-
電話番号	phone_number	VARCHAR	15	NO	NO	ハイフンなし
カラム名: テーブル内の各列の名前（論理名と物理名）。
型: INT、VARCHAR、DATEなどのデータ型。
長さ: VARCHARなどの型の場合、格納できる最大文字数。
NOT NULL: 空値を許容するかどうか。
主キー（PK）: 一意な識別子となるカラム。
備考: その他の仕様や注意事項。

**(3) インデックスとキー**
主キー（Primary Key）： テーブルの一意な識別子。
例：customer_id
外部キー（Foreign Key）： 他のテーブルとの参照関係。
例：order テーブルの customer_id が customer テーブルを参照する。

**(4) 制約（Constraints）**
NOT NULL: 必須入力のカラム。
UNIQUE: 重複を許さないカラム。
CHECK: カラムの値を制限する条件。
DEFAULT: デフォルト値を設定。

**(5) テーブル間の関係（ER図などで補足）**
リレーション: 外部キーを用いたテーブル間の関連性を定義。
例：customer テーブルと order テーブルが、customer_id を通じてリレーションを持つ。

# 3. テーブル定義書の作成手順

**Step 1: テーブル構造を決定**
各テーブルの役割を決定し、格納するデータを定義します。

**Step 2: カラムを決定**
各カラムの名前、型、長さ、制約を設定します。

**Step 3: 主キー・外部キーの設定**
主キーを決め、他のテーブルとの外部キーの関連を設計します。

**Step 4: 制約を設定**
必要に応じて、NOT NULL、UNIQUE、DEFAULT などの制約を加えます。

**Step 5: テーブル間の関係を整理**
ER図を使い、テーブル間のリレーションを可視化します。

# 4. テーブル定義書のサンプル
顧客情報テーブル定義書サンプル
項目名	物理名	データ型	長さ	NOT NULL	PK	備考
顧客ID	customer_id	INT	-	YES	YES	自動採番
名前	name	VARCHAR	50	YES	NO	-
メール	email	VARCHAR	100	YES	NO	UNIQUE
電話番号	phone_number	VARCHAR	15	NO	NO	ハイフンなし

# 5. 作成時のポイントと注意点
一貫性のある命名ルールを使用する

テーブル名やカラム名に、一貫した命名規則を適用する（例：スネークケース、キャメルケース）。
拡張性を考慮する

将来の要件変更を見据え、柔軟に拡張できる設計にする。
制約の適切な設定

過度な制約を避け、必要な部分でのみ設定する。
リレーションの正確な設計

テーブル間の関係を明確にし、データの整合性を保つ。
ER図と併用する

テーブル定義書とER図を併用することで、全体の構造を把握しやすくする。

# 6. テーブル定義書作成に使えるツール
**Excel/Google Sheets**

テンプレートを活用してテーブル定義書を作成可能。
ER図作成ツール（Lucidchart、Draw.io）

テーブル間の関係を可視化できる。
DB設計ツール（MySQL Workbench、PgAdmin）

データベースと直接連携し、テーブル定義を反映できます。

# 7. まとめ
テーブル定義書は、データベース設計の基盤として、開発者や関係者間での認識共有に欠かせない重要なドキュメントです。適切なテーブル設計は、システムの性能とデータの整合性を向上させます。
テーブル定義書を作成する際は、ER図などのツールも活用しながら作業を進めましょう。

次回ER図について記事にしたいと思います。

**ポイントまとめ:**
テーブルの目的とカラムの詳細を明確にする。
制約やキーの設定でデータの整合性を確保する。
拡張性を考慮し、将来の変更に備える。

**毎日更新していますので、@y-t0910をフォロー,いいねしていただけると嬉しいです！**
ABC377回答メモ

# 0.はじめに
　なんとなく、問題表示に時間かかったり、コードテストも時間かかったりした気がします。
　また攻撃とか受けてるのかな‥‥。
　Ｄ問題が解けそうで解けずに結局3問ＡＣで終了。
　レートは+5と微増でした・・・。

# 1.A - Rearranging ABC
　ABC用にそれぞれフラグを持ち、それらの文字があったら
　1をセット。最後にフラグを合計して3だったらYes違ったらNoを出力して終了

　https://atcoder.jp/contests/abc377/submissions/59158888
　

# 2.B - Avoid Rook Attack
　行と列ごとに、駒がある数をカウント
　最後に、8から行駒カウントを引いた値と8から列駒カウントを引いた値を掛けた値を
　出力して終了

　https://atcoder.jp/contests/abc377/submissions/59165464


# 3.C -  Avoid Knight Attack
　駒と駒が移動できる座標を保持するセットSを用意
　駒ごとに、駒位置とそこから移動出来る8か所をSに格納していく。
　その際、番からはみ出る場合は入れない。
　N×NからSの長さを引いた値を出力して終了

　https://atcoder.jp/contests/abc377/submissions/59172528


以上
CORSにおける単純クリエイトとプリフライトリクエストの違いを調べた

# 単純リクエスト（Simple Request）
単純リクエストは、追加の確認手続きなしで、サーバーに直接送信されるリクエストです。

### 単純リクエストの条件

・HTTPメソッド: GET、POST、HEAD のいずれかであること。

・カスタムヘッダーの使用制限: 特定の標準的なヘッダー（例: Accept、Accept-Language、Content-Type など）しか利用していないこと。

・Content-Type の制限: application/x-www-form-urlencoded、multipart/form-data、text/plain のいずれかのみ。

# プリフライトリクエスト（Preflight Request）
プリフライトリクエストは、単純リクエストの条件を満たさない場合に、
リソースを安全に利用できるかどうかを確認するためにブラウザがサーバーに送信する「事前確認用のリクエスト」です。

この場合、ブラウザはまず OPTIONS メソッドを使ったプリフライトリクエストを送信し、サーバーに実際のリクエストが許可されるかどうかを問い合わせます。

サーバーがプリフライトリクエストに許可を返した場合のみ、ブラウザは本リクエストを送信します。


### プリフライトリクエストの条件

・使用されるHTTPメソッドが PUT、DELETE など、単純リクエストで許可されていないものの場合。

・カスタムヘッダー（例：Authorization）を含む場合。

・特定の Content-Type（例：application/json など）を使っている場合。

# 主な違いのまとめ

|特徴|単純リクエスト|プリフライトリクエスト|
|:-----------|:------------|:------------|
|リクエストの内容 |GET、POST、HEAD メソッドと標準ヘッダーに限る|PUT、DELETE やカスタムヘッダーなど、追加条件付き　|
|  事前確認（プリフライト）| 不要 |必要|
|  リクエストの流れ） | 直接サーバーに送信 |OPTIONS メソッドで事前確認後に本リクエスト送信|


MDNの画像をベースに、以下のイメージ図に作りました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3538617/6482e4e9-0a7a-0ef4-7284-b4a61a2c93c2.png)



# 参考サイト

https://developer.mozilla.org/ja/docs/Web/HTTP/Headers

https://developer.mozilla.org/ja/docs/Web/HTTP/CORS#%E3%82%A2%E3%82%AF%E3%82%BB%E3%82%B9%E5%88%B6%E5%BE%A1%E3%82%B7%E3%83%8A%E3%83%AA%E3%82%AA%E3%81%AE%E4%BE%8B

https://zenn.dev/syo_yamamoto/articles/445ce152f05b02

https://fetch.spec.whatwg.org/#http-cors-protocol
投稿 119 Ruby on RailsでのMVCモデル構築とエラー解消の流れ 2024/10/27


はじめに


Ruby on Railsを使用してMVCアーキテクチャに基づくWebアプリケーションを構築する際
モデル（Model）
ビュー（View）
コントローラー（Controller）の連携が重要です。


本記事では、Railsでの基本的な設定と、特定のエラーの解決過程を詳しく解説します。

---
▪️環境構築とルーティング設定
まず、基本的な環境を構築し、PostsControllerを作成します。以下のように、ルーティングを設定しました。
```
# config/routes.rb
Rails.application.routes.draw do
  root "posts#index"
  resources :posts, only: [:index, :new, :create]
end
```


この設定により、/ ルートにアクセスすると PostsController の index アクションが呼び出されるようになります。


▪️コントローラーの実装
次に、PostsControllerを作成し、indexアクションで全てのポストを取得するようにしました。
```
class PostsController < ApplicationController
  def index
    @posts = Post.all
  end
end
```



▪️ビューの作成
ビューを作成するために、app/views/posts/index.html.erbを用意しました。このビューでは、@postsインスタンス変数を利用してポストのリストを表示します。




---
エラーの発生
サーバーを起動し、ブラウザでアプリケーションにアクセスすると、以下のエラーが表示されました。



```
NameError
uninitialized constant ApplicationController::Post
```



このエラーは、Postクラスが未定義であるために発生していました。具体的には、@posts = Post.allというコードがPostsController内で実行された際に、RailsがPostモデルを見つけられなかったのです。


※Postモデルは、Ruby on Railsにおけるデータベースのテーブルと関連するデータを表すクラス

---
▪️エラーの解決
エラーを解決するために、次の手順を実行しました。


Postモデルの生成 Railsのコマンドラインツールを使用して、Postモデルを生成しました。
```
rails generate model Post title:string content:text
```
これにより、Postモデルが作成され、必要なカラムが追加されました。
マイグレーションの実行 モデルを作成した後、データベースに変更を適用するためにマイグレーションを実行しました。
```
rails db:migrate
```


サーバーの再起動 最後に、変更を反映させるためにRailsサーバーを再起動しました。

---
結果
これらの手順を経て、@posts = Post.allが正常に動作し、ビューにポストの一覧が表示されるようになりました。



---
まとめ
Railsを用いたMVCアーキテクチャでは、モデルの定義とそれに伴うマイグレーションが重要です。今回のエラーは、モデルが未定義であることによるものでしたが、適切な手順を踏むことで問題を解決できました。
今後もRailsの機能を活用し、効率的な開発を進めていきたいと思います。
Scope

[Previous << Control Flow](https://qiita.com/flowcadence/items/49857b417bbc90cfa50b)
[Next >> Type Safety](https://qiita.com/flowcadence/items/48303ea74f8e783d9d06)

https://qiita.com/flowcadence/items/3073d69c6e9895e68b5a#cadenceの言語仕様を学ぶ

すべての関数およびブロック (`{`...`}`) は、宣言用の新しいスコープを導入します。各関数およびブロックは、そのスコープ内または外部のスコープ内の宣言を参照できます。

```ruby
let x = 10

fun f(): Int {
    let y = 10
    return x + y
}

f()
/* is `20` */

/* Invalid: the identifier `y` is not in scope. */
y
```
```ruby
fun doubleAndAddOne(_ n: Int): Int {
    fun double(_ x: Int) {
        return x * 2
    }
    return double(n) + 1
}

/* Invalid: the identifier `double` is not in scope. */
double(1)
```
各スコープは新しい宣言を導入することができ、すなわち、外側の宣言が覆い隠されます。
```ruby
let x = 2

fun test(): Int {
    let x = 3
    return x
}

test()
/* is `3` */
```
スコープは字句的であり、動的ではありません。

```ruby
let x = 10

fun f(): Int {
   return x
}

fun g(): Int {
   let x = 20
   return f()
}

g()
/* is `10`, not `20` */
```
宣言は、囲む関数の上に影響（hoist）しません。
```ruby
let x = 2

fun f(): Int {
    if x == 0 {
        let x = 3
        return x
    }
    return x
}
f()
/* is `2` */
```


翻訳元

https://cadence-lang.org/docs/language/scope

***
<b>[Previous << Control Flow](https://qiita.com/flowcadence/items/49857b417bbc90cfa50b)
</b>

[Flow blockchain / Cadence version1.0ドキュメント](https://qiita.com/flowcadence/items/3073d69c6e9895e68b5a) (Scope)

<b>[Next >> Type Safety](https://qiita.com/flowcadence/items/48303ea74f8e783d9d06)</b>
React Server ComponentsとGraphQLの相性について考えてみる

最近React Server Componentsの学習を進めていく中で、「GraphQLと組み合わせたらどうなるんだろう？」とふと考えました。どちらもデータの取得を効率化するための仕組みですよね。「重複する部分も多いし、むしろ組み合わせると複雑になっちゃうのでは？」という疑問が湧いてきて、実際に検証してみることにしました。


### 想定読者
こんな方に読んでいただきたい記事です。
- React Server Componentsの基礎を押さえている開発者
- 実務でGraphQLやRESTful APIを使ったことがある方
- 「次のプロジェクトではRSCを導入したいけど、GraphQLとの兼ね合いってどうなんだろう？」と考えている方
- Reactアプリのパフォーマンスチューニングに興味がある方


この記事では、実際のプロジェクトでどちらを選ぶべきか、チーム開発の視点も含めて考えてみたいと思います。技術的な比較だけでなく、実装コストやチームの開発効率なども含めて、現場目線で考察してみました。

## RSCとGraphQLの相性について考えてみた

最初に思ったのは「RSCとGraphQLって、実は似たようなことをやろうとしてるんじゃない？」ということでした。

たとえば、どちらも以下のような課題を解決しようとしています。
- 必要なデータだけを取得したい（オーバーフェッチの防止）
- 複数の依存関係があるデータをスマートに取得したい（ウォーターフォールの解決）

### 組み合わせる時の「あれ？」ポイント

GraphQLとRSCを組み合わせようとすると、いくつかの「あれ？」というポイントに気づきます：

1. **実装が複雑になりがち**
   - GraphQLのスキーマ定義
   - RSCのデータ取得の最適化
   - 両方の機能を活かすための設計...

2. **ツールやライブラリの制約**
   - RSC対応のGraphQLクライアントってまだ少ないですよね
   - 開発ツールも発展途上な感じ

正直、チーム全員がこの2つの技術に詳しくないと、メンテナンスが大変かもしれません。

## じゃあRESTful APIならどうか

実は、RSCとRESTful APIの組み合わせってすごくシンプルに書けます。

```typescript
async function UserDashboard({ userId }: { userId: string }) {
  // シンプルに並列でデータ取得
  const [user, settings] = await Promise.all([
    fetch(`/api/users/${userId}`),
    fetch(`/api/users/${userId}/settings`)
  ]);

  const userData = await user.json();
  const settingsData = await settings.json();

  return (
    <div>
      <UserProfile user={userData} />
      <UserSettings settings={settingsData} />
    </div>
  );
}
```

### App Routerのいいところ

実は、Next.jsのApp Routerには「Request Memoization」という素敵な機能があるんです。これが地味にすごい。

```typescript
// こんなコードがあったとして
async function getData(id: string) {
  const res = await fetch(`/api/data/${id}`);
  return res.json();
}

// 複数のコンポーネントで同じデータを取得しても
async function ComponentA({ id }: { id: string }) {
  const data = await getData(id);  // 1回目の呼び出し
  return <div>{/* ... */}</div>;
}

async function ComponentB({ id }: { id: string }) {
  const data = await getData(id);  // 実は再フェッチは発生しない！
  return <div>{/* ... */}</div>;
}
```

同じリクエストは自動でメモ化されるので、パフォーマンスのことをそれほど気にしなくても大丈夫なんです。これ、個人的にすごく好きな機能です。

## じゃあ、どっちを選ぶ？

結論から言うと、**多くの場合はRSC + RESTful API**の組み合わせをお勧めします。

その理由は：
1. シンプルに書ける
2. チームメンバーの学習コストが低い
3. 既存のツールやノウハウが使える
4. パフォーマンスも予測しやすい

ただし、以下のような場合はGraphQLも検討する価値があります：
- すでにGraphQLの基盤がしっかりしている
- データの要件が本当に複雑
- クライアント側で柔軟なデータ取得が必須

## まとめ

RSCは素晴らしい機能なのですが、必ずしも全ての最新技術と組み合わせる必要はないのかもしれません。時にはシンプルな選択肢の方が、開発効率もパフォーマンスも上がることがありますよね。

特にRSC + RESTful APIの組み合わせは、
- 書きやすい
- 分かりやすい
- メンテナンスしやすい

という、実務で重要な要素が揃っています。

新しいプロジェクトを始める時は、まずはこのシンプルな組み合わせから検討してみてはいかがでしょうか。
Type Safety

[Previous << Scope](https://qiita.com/flowcadence/items/4e7652187e58908f3d7e)
[Next >> Type Inference(型推論)](https://qiita.com/flowcadence/items/cf6493f9fd297b677452)

https://qiita.com/flowcadence/items/3073d69c6e9895e68b5a#cadenceの言語仕様を学ぶ

Cadence プログラミング言語は型安全言語(*type-safe* language)です。

変数に新しい値を割り当てる場合、その値は変数と同じ型でなければなりません。例えば、変数が`Bool`型の場合、割り当てられる値は`Bool`型のみであり、例えば`Int`型は不可です。

```ruby
/* Declare a variable that has type `Bool`. */
var a = true

/* Invalid: cannot assign a value that has type `Int` to a variable which has type `Bool`. */
a = 0
```
関数に引数を渡す場合、値の型は関数のパラメータの型と一致していなければなりません。例えば、関数が`Bool`型の引数を期待している場合、`Bool`型の値のみ渡すことができ、例えば`Int`型の値は渡せません。

```ruby
fun nand(_ a: Bool, _ b: Bool): Bool {
    return !(a && b)
}

nand(false, false)
/* is `true` */

/* Invalid: The arguments of the function calls are integers and have type `Int`,
 * but the function expects parameters booleans (type `Bool`).
 */
nand(0, 0)
```
型は自動的に変換**されません**。例えば、整数型は自動的にブーリアン型に変換されません。また、`Int32`は自動的に`Int8`に変換されません。また、オプショナルの整数型`Int?`は自動的にオプショナルではない整数型`Int`に変換されません。また、その逆も同じです。
```ruby
fun add(_ a: Int8, _ b: Int8): Int8 {
    return a + b
}

/* The arguments are not declared with a specific type, but they are inferred
   to be `Int8` since the parameter types of the function `add` are `Int8`. */
add(1, 2)
/* is `3` */

/* Declare two constants which have type `Int32`. */
let a: Int32 = 3_000_000_000
let b: Int32 = 3_000_000_000

/* Invalid: cannot pass arguments which have type `Int32` to parameters which have type `Int8`. */
add(a, b)
```


翻訳元

https://cadence-lang.org/docs/language/type-safety

***
<b>[Previous << Scope](https://qiita.com/flowcadence/items/4e7652187e58908f3d7e)
</b>

[Flow blockchain / Cadence version1.0ドキュメント](https://qiita.com/flowcadence/items/3073d69c6e9895e68b5a) (Type Safety)

<b>[Next >> Type Inference(型推論)](https://qiita.com/flowcadence/items/cf6493f9fd297b677452)</b>
データベースとスプレッドシート

# スプレッドシートを制御する標準的な方法
スプレッドシートは究極のノーコードツールで式を埋め込むことで様々なアプリケーションを簡単に作ることができます。

・簡単なスプレッドシートの使用例
https://qiita.com/kawamo55/items/4a0a733ea229cde8d57f
<br/>
本格的なアプリケーションを作るとき使用するスプレッドシートの制御方法は
|スプレッドシート|制御スクリプト|
|--|--|
|Excel | VBA |
|LibreCalc|LibreOffice Basic|
|Google Spredsheet|GAS|

上の２つはOld Visual Basic系の文法でGASはJavaScriptです。
これら全ては、全てPythonに置換えることが可能です。

# Excelを例にPythonで制御する方法としては・・・
以下のURLで音声合成を呼び出す方法と同様に
https://qiita.com/kawamo55/items/8ebe565e8ef4177cecff
win32com.clientを使ってWindowsのActiveXオブジェクト(ExcelとDAO)を取得すると、Pythonで制御可能になるためVBAを使わなくても制御可能になります。

# スプレッドシートとデータベースを組み合わせることのメリット
スプレッドシートは単独でもそれなりに使えるものが作れますが、複雑な式を沢山多用しだすと１つのセルを更新するたびに再計算が発生して動作の重いスプレッドシートが出来上がってしまいます。
更に、Excelで複数シートに分けることでデータの整合性を保とうとするとファイルの移動ができなくなったり、新たな処理を開始する場合の初期化が大変なことになったりします。
これを、避けるためにデータの制御ロジックはデータベースに置いてスプレッドシートには最終的な表示のみを置いて単純な式だけで構成することで重くならず、移動させても問題のないスプレッドシートが出来上がります。

# ExcelとAccessデータベースをPythonで制御した例
以下の動画は、コマンドプロンプトから操作してExcelとAccessデータベースを使用した例です。
まだ単純な動作しかしませんが・・・

https://youtu.be/OoM4TlEJHL4

# Excelだけではなく
pythonを使用すると、前動画のような制御をLbreCalcやGoogleSpreadシートで適用できます。
具体的な方法は・・・
また書いていきます！！
PHPによる自作CSV解析関数の性能についての考察

PHPでCSV解析を行う関数を作ったので性能を検証してみた。1行144文字の100万行のCSVファイルをパースして総なめする。すると12秒ほどかかった。この関数は

* 読み込んだカラムをすべて配列で取得する

という関数で、内部ではバッファに文字を溜めてそれを配列に格納して返り値として返している。

for文のループでカウント変数をカウントするだけのコードで同じ100万行のCSVファイルをなめてみたがこれは0.5秒ほどで終わる。ということはこの関数のコストは11.5秒ほどである。100万行に12秒かかるとレコード数が100万行に達したらそれだけ時間がかかるということで、12秒待つのはなかなかしんどいと思うので、現実的なコストとは言えない。
そこで特定のカラムだけバッファに格納してそれを文字列として返す関数を作ってみたら、これは9秒ほどかかった。そうすると3秒ほど短縮できた。
特定のカラムを検索したい場合にこの関数を使い、レコードのカラム全てを取得したい場合は添え字を戻して12秒の関数を使えば、効率化はできる。ただ、それでも最悪コストは9秒ほどである。
データベースを使った場合はどれぐらいのコストがかかるのか比較したほうがいいだろう。CSVの解析は時間がかかる。
また生PHPでコードを書くのではなくC言語によるPHP関数の作成も比較したいところである。C言語で書けばもっと速くなるだろう。

これらの関数とは別に1行スキップするだけの関数も作った。これは同じCSVファイルで5秒ほどかかった。そうするとバッファと配列の処理に7秒ほど使ってることになる。しかし一行カウント変数とif文で読み込むだけで5秒は最低でもかかるということで、ここら辺は処理系の限界なのかもしれない。
Laravel / ADRパターン、アーキテクチャ

## 概要
PHPフレームワーク Laravel Webアプリケーション開発のChapter3が完了したので学んだことを記録する。

## 実装パターン
### トランザクションスクリプトパターン
　ビジネスロジックの処理をまとめたもので処理に関するものを1つのクラスにまとめたもの (1つのクラスに対し全ての実装を記述するパターン)
　シンプルなパターンであるが、様々な処理が増え共通化が困難になることから、クラスでの運用・保守が難しく設計の一貫性を失い実装内容の把握がより困難になってしまう。
　レイアードアーキテクチャーを導入することで解決することができる

### ドメインモデルパターン
　ドメイン駆動設計を取り入れて実装コードに反映させるパターンのこと。
概念整理や分析などを開発の中心におく考え方。


## ソフトウェアアーキテクチャー
### MVCパターン
すでに行なったことあるパターンのため省略

### ADRパターン
ソフトウェアアーキテクチャーの1つであり、MVCと異なり1つのアクションに対しそのリクエストからレスポンスを定義する必要がある。
これは、MVCパターンで発生するコントローラやモデルの肥大化を解消するためや、保守性可読性テストコードの書きやすさから使われる。

ADRはAction、domain、Responderで構成されており、MVCと比較するとActionがcontroller、domainがmodel、ResponderがViewの対応をしている。
ドメインとモデルの違いは特になく、レスポンダはコンテンツ情報だけでなくHTTPレスポンスを構築する処理も担当する。

## アーキテクチャー設計
アーキテクチャー設計では、開発メンバーの人数や開発期間といった様々な要素から現実的な妥協点を見出し適切に設計する必要がある。

機能要件や非機能要件(スケーラビリティ、セキュリティなどといった機能以外の要件のこと)を満たすための拡張性や保守性を保つには適切な設計に基づく抽象化と構造化が必要になる
→ MVCやADRパターンをベースにビジネスロジックからデータベース操作を分離した設計を行うことが重要になる。

### レイヤードアーキテクチャ
システムを一連の論理的なレイヤーに編成するソフトウェア設計パターンのこと。
それぞれのレイヤーに対し、システム全体の中で特定の責任と役割を持っている。
ビジネスロジックの複雑化を防ぎ、抽象化することで依存を排除することができテストの容易さや仕様変更の対応のしやすさなどに役立てることができる。

主な実装方法としては、リポジトリ層でDBを操作し、サービス層からデータベース操作を分離させる。
そのため、レイアの分離としては以下のようになる。

`コントローラ → サービスレイア → リポジトリレイア → モデル`
ESXiにてRocky LinuxへOpenshift Localをインストール・セットアップする際の注意点

## 本記事について
自宅サーバへOpenshift Localをインストール・セットアップした際に躓いた点等の備忘録。随時追記予定。

## 環境
|項目|詳細|
|:-:|:-:|
|Hypervisor|ESXi7.0 Update3|
|OS|Rocky Linux 9.4|
|CRC|2.42.0+6689ec|
|Openshift|4.17.0|
|Microshift|4.16.14|

## インストール時
- rootユーザでのインストールは不可
- 一般ユーザかつsudoアクセス権限のあるユーザでのインストールが必要（wheelグループに追加する等）
- メモリを9GBに設定すると、crc setupでのチェックに引っかかる
- VMのCPUの設定にて、「ハードウェア仮想化」を有効化する必要あり（BIOSの設定にはVirturizationのメニューは存在しない）
- `crc start`時に以下エラーが出る場合、ストレージ容量不足でOpenshift Localのインストールに失敗している可能性あり
```rb
Error getting the machine state: unexpected libvirt status 3
```
```rb
[test@Openshift-Local ~]$ df -h
Filesystem           Size  Used Avail Use% Mounted on
devtmpfs             4.0M     0  4.0M   0% /dev
tmpfs                5.8G     0  5.8G   0% /dev/shm
tmpfs                2.3G  8.9M  2.3G   1% /run
/dev/mapper/rl-root   64G  2.2G   62G   4% /
/dev/sda1            960M  225M  736M  24% /boot
/dev/mapper/rl-home   31G   31G  600K 100% /home  <-------- 
tmpfs                1.2G     0  1.2G   0% /run/user/1000
```
SQLパズル11 作業依頼　解法1　メモ

# 概要
SQLパズル11 作業依頼の解法1についてのメモです。

サブクエリとALL部分が理解に手間取ったので記録に残しておきます。
理解するのにはサブクエリと自己結合とALL(限定述語)の知識が必要。

# 要件
以下条件を満たす作業依頼IDを求めたい：
イ.工程番号0が完了している(step_nbr=0 の step_status='C')
ロ.工程番号1~Nが未完了(サブクエリ部分)

2.の部分を理解するのに手間取ったので、実際にデータを見て細かい動きを確認してきます。

# SQL
```sql
SELECT workorder_id
FROM projects AS P1
WHERE step_nbr = 0 AND step_status = 'C' -- 要件 イ
	AND 'W' = ALL (SELECT step_status -- 要件　ロ
					FROM projects AS P2
				  WHERE step_nbr <> 0
					AND P1.workorder_id = P2.workorder_id
				  );

```



## 求めたいレコード

![image (3).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/c362b08b-4669-5a77-b083-01c633dc0b80.png)


## SQL

```sql
SELECT workorder_id
FROM projects AS P1
WHERE step_nbr = 0 --←わかる
	AND step_status = 'C' -- わかる
	AND 'W' = ALL (SELECT step_status
					FROM projects AS P2
				  WHERE step_nbr <> 0
					AND P1.workorder_id = P2.workorder_id
				  )--わからない。サブクエリと'W'=ALLの部分
				  ;
```
# 1.サブクエリ部分-工程番号の組み合わせを作る

自己結合を使って作業ID毎の工程番号の組み合わせを求めます。
（工程番号0は含めない）
```sql
SELECT P1.*,P2.*
	FROM projects AS P2,projects AS P1 
  WHERE P2.step_nbr <> 0
	AND P1.workorder_id = P2.workorder_id;
```
画像

![{FAC543A5-6F1B-487A-A0C6-67EEA471693F}.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/f6f72624-0c3c-8ddf-95cb-0d516c6a9ecc.png)


# 2.'W = ALL (サブクエリ) -上で求めた組み合わせの工程ステータスが”W”であるレコードを取得する。


あとは工程番号=0かつ工程ステータス=Cのレコードのみ取得すれば、完了。

```sql
SELECT P1.*
FROM projects AS P1
WHERE 'W' = ALL (SELECT P2.step_status
					FROM projects AS P2
				  WHERE P2.step_nbr <> 0
					AND P1.workorder_id = P2.workorder_id);
```

画像
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/d89af07b-41c2-9db5-ce15-a034579c9d09.png)

①
作業依頼IDが"AA300"は工程番号１が完了(step_status="C")してるので、該当しない
作業依頼IDが"AA300"は工程番号１が完了(step_status="C")してるので、該当しない

②
WHERE step_nbr = 0  AND step_status = 'C'を満たすAA100のみを表示する



# 参考
SQLパズル　p46

SQLパズル　サポートページ
https://mickindex.sakura.ne.jp/database/db_support_sqlpuzzle.html#LocalLink-p11

postgresql All
https://www.postgresql.jp/document/7.3/user/functions-subquery.html

達人に学ぶSQL徹底指南書第２版 p44　自己結合の使い方　組み合わせ

github 差分
https://github.com/RYA234/SQL_Puzzle_Learning/commit/952c413a94e576393352153bb2e6b5fc758726d2
【Unity】CharacterControllerの移動量だけを取得して他のオブジェクトに適用させる

# 概要

タイトルのままです。
UnityのCharacterControllerは便利ですが、アタッチしているゲームオブジェクトとの紐づきが強いです。
キャラクターの移動をさせたいからといって、別にそのオブジェクトを動かしたいとは限りません。
幸い、結果は即時適用されるようなのでその結果だけ抜き出すことができました。

# 対応

一度移動を適用して結果だけ抜き出してもとに戻す拡張メソッドを作成します。

```cs:CharacterControllerExtensions.cs
using UnityEngine;

namespace TsujihaTools.Extensions
{
	public static class CharacterControllerExtensions
	{
		/// <summary>
		/// CharacterControllerに従って移動させた場合の移動量を取得する
		/// </summary>
		/// <param name="self">CharacterController</param>
		/// <param name="move">移動量</param>
		/// <returns></returns>
		public static Vector3 SimulateMove(this CharacterController self, Vector3 move)
		{
			// CharacterControllerに従って移動させる.
			var prevPos = self.transform.position;
			self.Move(move);
			var nextPos = self.transform.position;

			// 元に戻す.
			self.transform.position = prevPos;

			// 結果だけ引き抜く.
			return nextPos - prevPos;
		}
	}
}

```

使用例

```cs:CharacterControllerExtensions.cs
// 移動量.
var move = nextPosition - prevPosition;

// CharacterControllerに従って移動させ、結果だけ引き抜く.
var moveResult = col.SimulateMove(move);

// 結果を移動対象に適用させる.
MoveTarget.transform.Translate(moveResult);
```

結果(CollisionFlags)を受け取りたい場合
```cs:CharacterControllerExtensions.cs
using UnityEngine;

namespace TsujihaTools.Extensions
{
	public static class CharacterControllerExtensions
	{
		/// <summary>
		/// CharacterControllerに従って移動させた場合の移動量を取得する
		/// </summary>
		/// <param name="self">CharacterController</param>
		/// <param name="move">移動量</param>
		/// <returns></returns>
		public static CollisionFlags SimulateMove(this CharacterController self, Vector3 move, out Vector3 simulate)
		{
			// CharacterControllerに従って移動させる.
			var prevPos = self.transform.position;
			var result = self.Move(move);
			var nextPos = self.transform.position;

			// 元に戻す.
			self.transform.position = prevPos;

			// 結果だけ引き抜く.
			simulate = nextPos - prevPos;
			return result;
		}
	}
}

```

以上です。
【Git】GitLabの指定の場所に複数ファイルをアップロード

GitLabの指定の場所にファイルをアップロードするには、以下の手順で進めます。

### 前提
- Gitがインストールされ、コマンドプロンプトで使用できること
[Gitのインストール](https://qiita.com/takedon0909/items/110d64fa4d6ca4150b35)
### 手順

#### 1. **リポジトリのクローン（未クローンの場合）**
   - まだリポジトリをクローンしていない場合、コマンドプロンプトを開き、以下のコマンドでクローンします。
     ```bash
     git clone https://gitlab.com/XXXXX/vbaproject.git
     ```
   - これで、ローカルに`vbaproject`フォルダが作成されます。

#### 2. **`class`ディレクトリにファイルをコピー**
   - クローンしたリポジトリフォルダに移動します。
     ```bash
     cd vbaproject/class
     ```
   - 複数のファイルを`class`ディレクトリにコピーまたは保存します。

#### 3. **ファイルをステージングに追加**
   - 以下のコマンドで、ステージングに追加します。
     ```bash
     git add .
     ```

#### 4. **コミットを作成**
   - 変更内容をコミットします。
     ```bash
     git commit -m "Add Class to tmp directory"
     ```

#### 5. **リモートリポジトリにプッシュ**
   - コミットした内容をGitLabの`main`ブランチにプッシュします。
     ```bash
     git push origin main
     ```

これで、`Classファイル`がGitLabの`main/class`ディレクトリにアップロードされます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3782903/afb7f562-a5cc-1413-c5b4-fd877945ebc9.png)
【Git】Gitのインストール

### 1. **Gitのインストール**
   - [Git公式サイト](https://git-scm.com/)からGitをダウンロードし、インストールしてください。
   - インストール中に「Git Bash Here」などのオプションが表示されますが、通常の設定のままで問題ありません。

### 2. **環境変数の設定 (インストール後に認識されない場合)**
   - 「スタートメニュー」で「環境変数」と入力し、「システム環境変数の編集」を選択します。
   - 「環境変数」をクリックし、「Path」という名前の変数を見つけて編集します。
   - `C:\Program Files\Git\bin` や `C:\Program Files\Git\cmd`（Gitのインストール場所による）を追加します。

### 3. **確認**
   - コマンドプロンプトやターミナルで以下を実行して、Gitが正しくインストールされているか確認します。
     ```bash
     git --version
     ```
   - バージョン番号が表示されれば、正常にインストールされています。

これで、Gitコマンドが認識されるようになります。
Pythonのセイウチ演算子（Walrus Operator）について徹底解説

# Pythonのセイウチ演算子（Walrus Operator）について徹底解説

Python 3.8から導入されたセイウチ演算子（`:=`）は、変数への代入を式の中で行うことができる新しい演算子です。この演算子は、コードの可読性を高め、冗長性を減らすために使用されます。

## 基本的な書き方

セイウチ演算子を使用する基本的な書き方は以下の通りです：

```python
if (n := len(some_list)) > 0:
    print(f'リストの長さは {n} です。')
```

上記の例では、`some_list`の長さを変数`n`に代入し、その長さが0より大きい場合にメッセージを表示します。従来の方法では、次のように書く必要がありました：

```python
n = len(some_list)
if n > 0:
    print(f'リストの長さは {n} です。')
```

## よくある使用方法

### 1. ループ中での使用

セイウチ演算子は、ループ内での条件チェックに便利です。以下の例では、リスト内の要素を処理しつつ、その数を把握できます：

```python
while (n := len(queue)) > 0:
    item = queue.pop()
    print(f'処理したアイテム: {item} (残り {n-1})')
```

### 2. リスト内包表記での使用

リスト内包表記でもセイウチ演算子を用いることができます。次の例は、2倍の値を持つ数のリストを作成します：

```python
values = [1, 2, 3, 4]
result = [double for value in values if (double := value * 2) > 5]
print(result)  # [6, 8]
```

## 実用的な使用方法

### 1. マルチ行のコンテキスト管理

セイウチ演算子を用いて、複数の行にわたるコンテキストを管理することができます。以下は、ファイルを開く際に使用される例です：

```python
with open('data.txt') as f:
    if (data := f.read()):
        print(f'ファイルの内容: {data}')
```

### 2. 無限ループ処理
従来の方法では次のように書かれていました
```python
while True:
    result = judge()
    if result:
        break
    print(f'判定結果: {result}')
```

セイウチ演算子を使うことで、**`result`の代入と判定を1行でまとめられ**、よりシンプルで直感的なコードになります。
```python
while (result := judge()) is not True:
    # 処理
    print(f'判定結果: {result}')

print('ループを終了しました。')
```
- `judge()`関数の結果を`result`に代入し、その値が`True`でなければループを続行します。
- **セイウチ演算子**により、`judge()`の呼び出しが1回で済み、無駄な再計算を避けられます。
- 終了条件が満たされた場合に`print`を使って確認することで、**実行結果を見やすく**しています。

## まとめ

セイウチ演算子は、Pythonのコードをより簡潔に、美しくする強力な機能です。さまざまなシーンで応用できますので、実際のプロジェクトで積極的に使用してみてください。

セイウチ演算子を使うことで、条件付きでの代入が可能になり、冗長なコードを削減できます。今後のPythonプロジェクトで、ぜひ活用してみてください！
Java SE Gold で勉強したことメモ(Predicate編)

関数型インターフェースのPredicate\<T>の使いどころについて以下のような場合が挙げられるようです。
Predicateを用いて説明用変数を導入し、処理内容を分かりやすくできます。

```php:Type.java
public enum BloodType{ //血液型を表すEnumクラス
    A,B,AB,O;
}
```
```php:Patient.java
public class Patient{ //患者を表すクラス
    private BloodType bType;
    private int age;
    
    public Patient(BloodType bType, int age){
        this.bType = bType;
        this.age = age;
    }
    //getter類は省略
}

```
Predicateを使用しない場合
```php:Main.java
public class Main{
    public static void main(String[] args){
        Patient p = new Patient(BloodType.A, 21);

        //血液型がAで、かつ、年齢が18歳以上の患者の場合、処理を実行
        if(p.getBType().equals(BloodType.A) && p.getAge() >= 18){
            //処理内容
        }
    }
}
```
Predicateを使用した場合
```php:Main.java
public class Main{
    public static void main(String[] args){
        Patient p = new Patient(BloodType.A, 21);

        //説明用変数を宣言
        Predicate<Patient> isA = p -> getBType().equals(BloodType.A);
        Predicate<Patient> isAdult = p -> getAge() >= 18;

        //説明用変数を用いた評価式
        if(isA.and(isAdult).test(p)){
            //処理内容
        }
    }
}
```

好みはわかれるかもしれませんが、確かに評価式をパッと見た感じPredicateを使用した方がわかりやすそうではありますね。
ただ、これくらいのコード量だと、使わなくてもいいかもしれません。

使いどころがありそうなのでメモしておきました。
間違っている箇所があれば教えてください。
UnityとNode.jsにてAnt+心拍計の数値を取得、VRMに反映したかったのだが…2024

私が以前使用していた
Advanced ANT+はもうなくなってしまったので以下のページを参考に行いました。
心拍を表示するところまではうまくいったのですが、うまくいかず停滞中です。

参考にさせていただいたページ

https://qiita.com/GenkiOkuma/items/bc0469fc3b29ed2f88cf

私の前提知識：node.jsに関して全くの無知。
ode.js（ノードジェイエス）は、JavaScriptというプログラミング言語を使って、サーバーサイド（裏方）で動くアプリケーションを作るための環境。もっと簡単に言うと、普通はウェブページを作るのに使うJavaScriptを、パソコンやサーバーの中で動かして色々な処理を行えるようにするツール
ということだけ理解。もっと勉強します。

インストール　
npm install ant-plus　
※node.jsではなくコマンドプロンプトで実施する。

C:\ant_plus　を作成し、
cd C:\ant_plus　でフォルダに移動　
npm install ant-plus　でインストールした
![スクリーンショット 2024-09-15 204840.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/600172/8d775348-8b41-1e39-27ee-51e82afd9376.png)

以下の内容のant_plus.jsを作成して実行、
```js:ant_plus.js
var Ant = require('ant-plus');
console.log('ant-plus module loaded successfully');
```
ant-plus module loaded successfullyとなっており読み込みに成功。

![スクリーンショット 2024-09-15 205659.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/600172/56ada465-552c-2af0-d249-3e6e4e5db371.png)

次は以下を作成　jsが分からんのでchatGPTに一行づつ何してるのかコメントしてもらった。
```js:one-sticks00.js
'use strict';  // 厳格モードを有効にしてエラーチェックを厳密にする

const Ant = require('ant-plus');  // ant-plusライブラリを読み込み
const stick = new Ant.GarminStick2();  // Garmin ANT+ USBスティック2のインスタンスを作成
const sensor = new Ant.HeartRateSensor(stick);  // 心拍センサーのインスタンスを作成

let deviceID = null;  // デバイスIDを格納する変数

// コマンドライン引数でデバイスIDが指定されているか確認
if (process.argv.length >= 3) {
    deviceID = process.argv[2];  // 指定されていればデバイスIDを設定
}

// 心拍データが受信されたときの処理
sensor.on('hbData', function (data) {
    if (deviceID === null) {
        // デバイスIDが未設定の場合、受信したデバイスIDと心拍数を表示
        deviceID = data.DeviceID;  // 受信したデバイスIDを取得して設定
        console.log(`デバイスIDを取得しました: ${deviceID}`);
        console.log(`心拍数: ${data.ComputedHeartRate}`);
    } else if (deviceID == data.DeviceID) {
        // デバイスIDが設定済みの場合、そのデバイスからの心拍数のみを表示
        console.log(`心拍数: ${data.ComputedHeartRate}`);
    }
});

// USBスティックが接続されたときの処理
stick.on('startup', function () {
    console.log('ANT+ USBスティックが起動しました');
    sensor.attach(0, 0);  // ANT+チャンネルに心拍センサーをアタッチ（接続）
});

// USBスティックが見つからない場合のエラーハンドリング
if (!stick.open()) {
    console.log('ANT+ USBスティックが見つかりません！');
}
```

※実行するとconsole.logは日本語文字化けしました

ドングル（USB）をPCに刺し、心拍計を電源on。
PS C:\ant_plus>  node one-sticks00.js
を実行
![スクリーンショット 2024-09-15 214955.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/600172/2999554f-5fc0-b0b9-1e02-5eb4ac72fc06.png)
心拍来ました。


心拍データをJsonで出すことは出来た。
次は実際にUnityで使いたい。凹みさんの以下の記事より
https://tips.hecomi.com/entry/2014/04/21/001606

https://github.com/hecomi/NodejsUnity
上記の記事を参考にしてみたがうまく出来なかった。
VRMを使うための　UniGLF　の中のTinyManagedTaskScheduler.cs、 UnityThread.cs 更にSearcherDatabaseとコンフリクトする部分があるみたいでうまくいかなかった。他のやり方調べよう
【JavaGold】セキュアコーディング

# セキュアコーディング

#### ■ アメリカのCERTが定めるセキュアコーディングプラクティスのうち、重要な原則。
* 入力を検証する。
* コンパイラからの警告に注意を払う。
* セキュリティポリシーを実装するように設計する。
* シンプルにする。
* 拒否をデフォルトにする。
* 最小権限の原則に従う。
* ほかのシステムに送信するデータを無害化する。
* 多重防御を実践する。
* 効果的な品質保証テクニックを利用する。
* セキュアコーディング標準を採用する。

#### ■ Unicode正規化を実現するためのメソッド
java.text.Normalizerクラスのnormalizeメソッド

#### ■ 整数オーバーフロー攻撃に対応する対策
* 事前条件テストを行う。
* アップキャストを行う。
* BigIntegerクラスを使う。

#### ■ 機密情報の扱いに関する説明
* 例外が発生したとき、どのような例外が発生したのかをユーザーに見せてはいけない。
* 機密情報を扱ったインスタンスは、ガベージコレクションを待たずに、速やかに削除しなければならない。
* コアダンプは、できるだけ早期に削除すべきである。

#### ■ 機密情報の改ざんを防止する方法
* セキュリティマネージャを使用。
* 機密情報は、変更不可能なオブジェクトまたは不変オブジェクトに格納する。

#### ■ 機密情報を保護する内容
* 機密情報を明確に識別する。
* 機密情報を格納する前に入力を検証する。
* 機密情報を保持するオブジェクトへのアクセスを制限する。

#### ■ Javaアプリケーションの開発において、Dos攻撃対策
* ファイルを読み込む際には、ファイルのサイズを調べてから読み込むようにすべきである。
* ファイルへの接続は、try-with-resources文を使ったリソースの自動解放機能を利用するべき。
* メモリに過剰なデータを読み込まないよう、プログラムで予防的な制限をかけるべきである。

#### ■ セキュアなアプリケーションを開発の正しい説明
* セキュリティマネージャを有効にするには、javaコマンドのオプションに「-Djava.security.manager」を追加する


#### ■ 特定のjarファイルだけに、セキュリティ上の特権を与えるために、セキュリティポリシーファイル正しい記述
```
// codeBaseを使用する
grant codeBase "file:/Users/shiga/workspace/chap12/lib.jar" {
    permission java.io.FilePermission "/", "read";
}
```

#### ■ 不変オブジェクトを定義する際に、セキュリティ面で適正な方法
* フィールドの値を変更するようなsetterメソッドは提供しない。
* フィールドの値を変更するのであれば、ディープコピーしたインスタンスを生成して、その参照を戻す。
* フィールドはfinalで宣言し、コンストラクタで初期値を設定したら変更できないようにする。
* 継承ができないように、クラス宣言をfinalで修飾する。
* インスタンスを生成するための専用のビルダーを用意する。

#### ■ 可変オブジェクトを安全に扱うための指針
* getterメソッドでは、フィールドのオブジェクトをコピーを作って、戻す。
* コピーコンストラクタを用意する。
* 可変オブジェクトを受け取るコンストラクタでは、受け取った参照をそのまま利用しない。

#### ■ セキュアコーディングを実践するための方法
* パッケージ内で公開するインタフェースを限定する。
* モジュールを使って公開パッケージを限定する。
* クラスを宣言するときにはfinalで修飾する。

#### ■ SQLインジェクションを防ぐために使用するインタフェース
* java.sql.PreparedStatement

#### ■ 機密情報を扱うインスタンスをシリアライズするときに実施すべき対策
* フィールドをtransientで修飾する。
* serialPersistentFieldsフィールドを定義して、シリアライズされるべきフィールドを指定する。

#### ■ シリアライズ・プロキシ・パターンの説明
* シリアライズするときにはwriteReplaceメソッドがデシリアライズするときにはreadResolveメソッドが利用される。セットで定義する。

#### ■ DoS攻撃の説明
* DoS攻撃（Denial of Service attack）とは、サーバーやネットワークに大量のデータやアクセスを送信して、正常なサービスの提供を妨害するサイバー攻撃。
* DoS攻撃防ぐには、try-with-resourcesを使用して、自動的にリソースが閉じるようにする。
nvim-tree でディレクトリを作成する方法

毎回忘れるので記事にしておく

tree上の任意の場所にて、 `a` で Create file を起動
作成したいディレクトリ名を入力し、末尾に `/` を追加するとディレクトリとして作成される

`Create file /home/hoge/{name}/`

なお `mkdir -p` のように再帰的なディレクトリとファイルの作成も可能

`Create file /home/hoge/fuga/piyo/sample.txt`
ショートカットアプリとHomePod miniで毎朝『今日は何の日？』を自動読み上げさせる

# 背景

Google Home mini を利用していたときは「今日は何の日？」機能で、その日の日付の過去の出来事を毎朝起床時間に自動読み上げさせていた。しかし、Home Pod mini に買い替えてからは同様の機能が見つからず...(Siriアホの子すぎる😥)。

個人的に好きな機能だったので、同様の機能をショートカットアプリとHome Pod miniで実現させた。

# 実装

## ショートカットアプリ

[別記事](https://qiita.com/howmuch515/items/fbc30fc7d9780a07642c)でショートカットアプリからPythonのコードを直接実行させる方法を示した。

今回はコード量が少々長くなっているのでGistにPythonコードをアップロードしておき、それを読み込むことにした。こうすることでPythonのコードをPC上で修正したり、差分管理できるメリットがある。

実装した結果は以下の通り。`curl -s` と sオプションを指定することでcurlコマンドの余計なログを出力しないようにした。

![7ED33C84-9357-4EA2-AA58-0CDCE2C2D3A3_1_102_o.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57640/13c83e74-9599-5a9e-7142-b10d50a6ab1a.jpeg)

このショートカットの実行結果をインターコムでHome Pod miniに読み上げさせる。

### 今日は何の日？スクリプト

過去の出来事はWikipediaの「できごと」の欄から取得した。日本語版のWebAPIでは提供されていなさそうな項目だったのでスクレイピング方式で取得することにした。

実装は以下の通り。コードはほとんどChatGPT 4oで作成。

https://gist.github.com/howmuch515/831202151b5d54de27e6a04ffddb4f89

# まとめ

これで毎朝、その日の過去の出来事をHome Pod miniから教えてもらえるようになった。ショートカットアプリにコードを貼り付けるよりも、Gistでコード管理した方が何かと便利そう。
【Ruby】レシーバとは

# はじめに
こんにちは、現在アメリカの大学に行って語学を学びながらソフトウェアエンジニアになるために独学で勉強しているものです。
本日はRubyを勉強しているとよく出てくる、メソッドについて整理していきます。
というのも、現在progate→ゼロから分かるRuby→たのしいRubyと段階を追って勉強しているのですが、レシーバについて詳しく触れる機会がなく何となくでここまで進んでしまっているので
`rails`に入る前に定義をしっかり確立していきたいと思います。

# レシーバ
レシーバとは、メソッドが呼び出される際に、そのメソッドを実行するオブジェクトです。
オブジェクト指向プログラミングでは、オブジェクトが持つメソッドを呼び出す際、どのオブジェクトに対してメソッドを実行するのかをレシーバが決定します。

```ruby:receiver1.rb
str = "hello"   # str は String クラスのオブジェクト
str.upcase      # str がレシーバとなり、upcase メソッドが呼ばれる
```
ここでは、`hello`というStringオブジェクトの`upcase`メソッドを呼び出しています。
この場合、`str`がレシーバです。メソッドがレシーバに対して何らかの操作を行い、その結果が返されます。

# selfとは
次に、 `self`について説明します。
`self`は、<strong>そのメソッドが実行されるオブジェクト、もしくはクラスを指す特殊な変数です</strong>
`self`は現在のレシーバ（メソッドを呼び出しているオブジェクト）であるということと省略できる場合があります。
できない場合も後で説明するのでまずはこの2つを覚えておいてください。
まずは省略できるケースから紹介します

### selfが省略できるケース
selfが省略できるのはインスタンスメソッドの場合です。詳しく見ていきましょう。
```ruby:self1.rb
class Person
  def greet
    puts "Hello!"
  end
end

person = Person.new
person.greet  # => "Hello!"
```
この例では、`person`インスタンスを生成して、`greet`メソッドで呼び出しています。
`greet`はインスタンスメソッドと呼ばれ、呼び出す場合には`self`を使用しないでも大丈夫です。
これはRubyが現在のレシーバであるインスタンス(今回は`person`)を`self`として解釈してくれるからです。

### selfが省略できないケース
クラスメソッドを使う場合は`self`を省略することができません。※
どういうことか詳しく見ていきましょう
```ruby:self2.rb
class MyClass
  def self.greet
    "Hello from the class!"
  end
end
puts MyClass.greet  # => "Hello from the class!"
```

この例では、`greet`メソッドを`self.greet`と定義しています。
これにより、`greet`はクラスメソッドになり、`MyClass`というクラス自身に対して呼び出すことができます。
※クラス名を直接使って定義する方法もあり`def MyClass.greet`と書くことでもクラスメソッドを定義できます

この場合、`greet`の前に`self`を置かないとエラーになります。なぜでしょうか。

### クラスメソッドでselfが必要な理由
Rubyでは、クラス内でメソッドを定義する際に、何も指定しなければそのメソッドはインスタンスメソッドとして定義されます。
インスタンスメソッドの場合、インスタンスが暗黙のレシーバとなるため、`self`を省略してもインスタンスが自動的にレシーバとして認識されます。

一方で、クラスメソッドを定義する際には、クラス自体がレシーバになることを明確にする必要があります。クラスメソッドの場合、`self`はクラスそのものを指します。`self.greet`と書くことで、`greet`メソッドがインスタンスではなくクラスに対して実行されることを示します。

もし`self`を付けずに単に`greet`と書いてしまうと、Rubyはそれをインスタンスメソッドとして解釈しようとし、エラーが発生します。なぜなら、この場合、レシーバとなるインスタンスが存在しないからです。

### クラスメソッドとインスタンスメソッドの違い
ここで、クラスメソッドとインスタンスメソッドの違いを改めて整理します。
クラスメソッドはクラスそのものに属するメソッドであり、クラスに対して直接呼び出されます。
一方、インスタンスメソッドはクラスのインスタンス（オブジェクト）に属し、そのインスタンスに対して呼び出されます。

クラスメソッド: `MyClass.greet`
インスタンスメソッド: `my_instance.greet`
この違いを意識することで、`self`が必要なタイミングをより正確に理解できるようになります。

もしクラスメソッドとインスタンスメソッドの違いについて知りたい方は、記事を書いているのでそちらを見ていただけたら幸いです

https://qiita.com/Taira0222/items/aca062a0cfb879fded31

# まとめ
今回の記事では、レシーバと`self`の役割や使い方について説明しました。
レシーバは「どのオブジェクトがメソッドを実行するか」を決め、`self`はそのレシーバを明示的に指し示すものです。
また、クラスメソッドとインスタンスメソッドの違いも把握することで、`self`をどのように使うべきかがよりクリアになったと思います。
USBホストをM5core2で利用するときに困ったこと 

## M5core2でつかえない..?
https://www.switch-science.com/products/9566

自分の使い方が悪いのでしょうが、こちらを利用しようとしたときにうまく使えなかったので、ほかにも困っている人がいればお役に立てることを願って記事にしました。
正規の方法でもっと簡単に利用できるんだよという方法をご存じの方はコメントいただけると幸いです。

この製品の正規のライブラリは以下ですが、

https://github.com/m5stack/M5-Max3421E-USBShield/tree/master

AdafruitのtinyUSBをベースに作成されているようで、サンプルスケッチのUSBHostの初期化時にSPIのピンをcore2用に設定しても、ADCと機能が競合するというメッセージが出るだけで使えませんでした。
core2で使用する場合にも具体的な例がないですし設定方法がよくわかりませんでした。

## USB Host シールド用のライブラリを改造
https://www.switch-science.com/products/8850

core2用の製品も、Aruduino用のこちらのシールドに使われているのも同じICです。
こちらは利用経験があり、ライブラリも自分にとっては見やすかったのでこちらを使用できるように手を加えました。

ライブラリはこちらで、

https://github.com/felis/USB_Host_Shield_2.0

core2で使用する場合、ピン定義が異なるため、以下の修正を行いました。

avrpins.hの1929行目から1941行目を次のように変更します。
```diff
// Pinout for ESP32 dev module

MAKE_PIN(P0, 0);
MAKE_PIN(P1, 1); // TX0
MAKE_PIN(P10, 10); // TX1
MAKE_PIN(P3, 3); // RX0
MAKE_PIN(P21, 21); // SDA
MAKE_PIN(P22, 22); // SCL
- MAKE_PIN(P19, 19); // MISO
+ MAKE_PIN(P38, 38); // MISO はcore2では38に変更されています
MAKE_PIN(P23, 23); // MOSI
MAKE_PIN(P18, 18); // SCK
- MAKE_PIN(P5, 5); // SS
+ MAKE_PIN(P19, 19); // SS は GPIOの19に設定します
- MAKE_PIN(P17, 17); // INT
+ MAKE_PIN(P27, 27); // INT は使用しませんが他の機能と競合しないように空いているGPIOに設定しました。
```

次に、UsbCore.hの54行目を次のように変更します。
```diff
#elif defined(ESP32)
- typedef MAX3421e<P5, P17> MAX3421E; // ESP32 boards
+ typedef MAX3421e<P19, P27> MAX3421E; // 先ほど変更したピン番号に変更する
```

これで使用できるようになるはずです。
Podmanを用いてAzure Container Registryへコンテナイメージをプッシュする

# はじめに
最近AzureのContainer Registryに触れる機会があり、[ドキュメント](https://learn.microsoft.com/ja-jp/azure/container-instances/container-instances-tutorial-prepare-acr)のdockerコマンドをそのままpodmanコマンドに置換するだけではコンテナをデプロイできず詰まったため、備忘録として手順を残しておこうと思います。

# 事前に準備すること
- [Azure CLI](https://learn.microsoft.com/ja-jp/cli/azure/install-azure-cli)をインストールし、ターミナル上でazコマンドを打てるようにしておくこと
- [podman](https://podman.io/docs/installation)をインストールし、podmanコマンドをターミナル上で打てるようにしておくこと

# 手順
1. **Linux実行環境を構築**
    ```
    podman machine init
    or 
    podman machine init --user-mode-networking # VPN環境下で使用する場合はオプションが必要

    podman machine start
    ```
    <br>
2. **Azureにログイン**
    ```
    az login --tenant "テナントID"
    ```
    <br>
    
3. **Container Registryへログインするためにアクセストークンを発行**
    ```
    az acr login --name <Container Registryの名前> --expose-token
    ```
    <br>

4. **手順3で出力された情報を基に、podmanコマンドでContainer Registryへログイン**

    ```
    podman login -u 00000000-0000-0000-0000-000000000000 -p <アクセストークン> <ログインサーバー名>
    ```
    <br>

5. **デプロイするコンテナへタグ付け**
    ```
    podman images # REPOSTIRY名を確認
    podman tag <確認したREPOSTIRY名> <ログインサーバー名>/<タグ名>
    ```
    <br>

6. **コンテナImageをContainer Registryへプッシュ**
    ```
    podman push <ログインサーバー名>/<タグ名>
    ```

# 参考文献
- [How to login to Azure Container Registry using Podman?](https://stackoverflow.com/questions/78969555/how-to-login-to-azure-container-registry-using-podman)
- [チュートリアル:Azure コンテナー レジストリを作成してコンテナー イメージをプッシュする](https://learn.microsoft.com/ja-jp/azure/container-instances/container-instances-tutorial-prepare-acr)
【Doctrine】ArrayCollectionの便利メソッド3選（filter, map, forAll）

# 初めに
PHPのORMとして知られるDoctrineにはCollectionsと呼ばれるモジュールが存在します。
今回は、その中の機能の一つであるArrayCollectionでよく使うメソッドについて解説します。


# 便利メソッド3選
今回紹介するのは以下の3つです。
* filter
* map
* forAll


## filter
名前の通り、条件に合う要素のみを抽出するメソッドです。
filterの引数に戻り値がbool型のコールバック関数を渡すことで、条件に合う要素のみを抽出します。
コールバック関数に渡せるのは値だけであり、キーを渡すことはできません。

```php:filterの例
// ArrayCollection作成
$array = ['key1' => 1, 'key2' => 2, 'key3' => 3];
$arrayCollection = new ArrayCollection($array);

// filter処理
$result = $arrayCollection->filter(function($value){
    return $value >= 2;
});
// $result = ['key2' => 2, 'key3' => 3];
```

## map
foreachのように、各要素に対して処理を適用します。
filter同様、配列のキーを渡すことはできません。

```php:mapの例
// ArrayCollection作成
$array = ['key1' => 1, 'key2' => 2, 'key3' => 3];
$arrayCollection = new ArrayCollection($array);

// map処理
$result = $arrayCollection->map(function($value){
    return "value is " . $value;
});
// $result = ['key1' => value is 1, 'key2' => value is 2, 'key3' => value is 3];
```

## forAll
全ての要素が条件に当てはまるかどうかを判定する処理です。
filterやmapと違い、コールバック関数にキーを渡すことができます。

```php:forAllの例
// ArrayCollection作成
$array = ['key1' => 1, 'key2' => 2, 'key3' => 3];
$arrayCollection = new ArrayCollection($array);

// forAll処理
$result = $arrayCollection->forAll(function($key, $value){
    return $value >= 2;
});
// $result = false
```

# おすすめポイント
map、filter、forAllなどを用いると、簡単な処理でifやforeachを使う必要がなくなります。
ネストの深さを抑えられ、比較的読みやすいコードになります。

例えば、以下の二つは同じ結果になりますが、後者のほうがすっきりしていて個人的には好きです。
```php: foreachとifを用いる
// ArrayCollection作成
$array = ['key1' => 1, 'key2' => 2, 'key3' => 3];
$arrayCollection = new ArrayCollection($array);

// foreachとifで頑張る
$result = [];
foreach($arrayCollection as $key => $value) {
    if ($this->isValid($value)) {
        $result[$key] = "value is " . $value;
    }
}
```

```php: mapやfilterを用いる
// ArrayCollection作成
$array = ['key1' => 1, 'key2' => 2, 'key3' => 3];
$arrayCollection = new ArrayCollection($array);

// mapとfilter
$result = $arrayCollection
    ->filter(fn($value) => $this->isValid($value))
    ->map(fn($value) => "value is " . $value);
```
すっきりするものの、↑のような記述だとfilterとmapのそれぞれで繰り返し処理を回すことになるので、パフォーマンスは微妙かもですね:sweat:

:::note info
PHP組み込み関数の[array_map](https://www.php.net/manual/ja/function.array-map.php)や[array_filter](https://www.php.net/manual/ja/function.array-filter.php)でも同様のことはできませす。ArrayCollectionを用いない場合は配列をわざわざ変換する必要もないので、これらの組み込み関数を用いるのがいいと思います。
:::


# 終わりに
Doctrineを使う場合、filterやmapを用いることですっきりとしたコードを書くことができるようになりますね。アロー関数を使うと、モダンな雰囲気を感じることができて非常に好みです。これからも使おうと思います。

ここまで読んでいただきありがとうございました！
Llama3をローカルで動かす

# Introduction

本記事では、オープンソースのAIモデルであるLlama3とGPT-4Allをローカル環境にインストールし、活用する方法について解説します。
これらのモデルは、チャットボットやテキスト生成、自然言語処理タスクに使用される最先端の大規模言語モデルです。一般に、クラウドサービスを利用したAIモデルの活用にはネットワーク接続が必要ですが、ローカルにインストールすることで、インターネットに依存せずデータの安全性を確保しながら、高速な処理を実現できます。また、カスタマイズや柔軟なチューニングも可能であり、特にプライバシーやデータセキュリティを重視するプロジェクトに適しています（カスタマイズ等については学習中・・・）。

次のセクションでは、Llama3とGPT-4Allのインストールに必要なハードウェア・ソフトウェア要件から確認し、適切なセットアップの方法を順を追って紹介していきます。


## <font color="red">GPT4ALL</font> とは

[GPT-4All](https://www.nomic.ai/gpt4all)は、Nomic社が提供するオープンソースの大規模言語モデルで、ローカルで動作する強力なNLP（自然言語処理）ツールです。
GPT-4Allは、プライバシーを重視しながら、ユーザーがインターネット接続を必要とせずにチャットボットや文章生成といったAI機能を活用できるよう設計されています。これにより、クラウド環境を使わずに手軽にAIの利便性を享受でき、特にデータ保護やセキュリティが求められる場面に適しています。

## GPT-4Allの特徴
ローカル環境での実行： GPT-4Allはローカルで実行可能で、クラウド上にデータを送信することなくテキスト生成や会話型AIの実行が可能です。これにより、プライバシーの確保が重要なアプリケーションにおいて優れた選択肢となります(Homepageより引用)。


# インストールとセットアップ
以下では、GPT-4Allのインストール手順と、基本的なセットアップ方法、その過程で<font color="red"><b>Llama3</b></font>をインストールしていく方法を説明しています。

## SYSTEM INFO
- AMD RYZEN 9 7900X3D
- MEMORY 64GB
- NVIDIA GeFOrce RTX 3060
- OS Ubuntu 24.04.1

## INSTALL

[GPT-4All](https://www.nomic.ai/gpt4all)からインストーラー(`gpt4all-installer-linux.run`)をダウンロードします。ここでは、Ubuntuにインストールする場合を説明していきます。

ダウンロードしたインストーラーに実行権限を付与します。

```bash
chmod +x gpt4all-installer-linux.run
```

そのうえで、インストーラーを実行します。

```bash
./gpt4all-installer-linux.run
```

インストール先はどこでも良いと思いますが、デフォルトでは `/home/USER/gpt4all` になります。

![Screenshot from 2024-10-26 21-46-13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227359/56fedd47-b1aa-54a8-706f-54e30c40df41.png)

起動後は`Models`メニューにあるLLMのリストから使用したいモデルをダウンロード、インストールします。

![Screenshot from 2024-10-26 22-02-56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227359/552d802d-eeea-f12d-14bf-41e110d65847.png)

今回は`Llama3 8B`を選択しました。
あとは`Chats`メニューからインストールしたモデルを選択します。

![Screenshot from 2024-10-26 22-05-26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227359/f6ced7c2-b274-1253-b042-eb1272ab2d52.png)

![Screenshot from 2024-10-26 22-06-54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227359/a7cf0a04-eb53-88e0-2991-d35539d6f213.png)


# Conclusion

GPT-4Allは、オープンソースでありながら高度な自然言語処理機能を備えた、ローカル環境向けの言語モデルです。特に、プライバシー保護やデータセキュリティが求められるシーンで、インターネットに依存せずAIの利便性を享受できる点が魅力です。また、複数のモデルとカスタマイズ性により、さまざまな用途や分野に適応できる柔軟性も備えています。インストールや設定は簡単で、公式サイトでのサポートも充実していますので、ぜひ自分の環境でGPT-4Allの機能を試してみてください。
picoCTF #Forensics - Glory of the Garden

■問題
This garden contains more than it seems.

この庭には見た目以上のものが含まれています。

■解き方

①ファイルをダウンロードする

②xxdコマンドでファイルのバイナリデータを表示してフラグを取得する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3519665/f947bdf2-97db-45a3-b0f0-3c8b10182420.png)
※参考
xxdコマンドは、LinuxやUnix系のシステムで使用されるバイナリデータを16進数（Hex）表示や編集するためのツール。
xxdは主に、バイナリファイルの内容を人間が読みやすい形式（16進数と対応するASCII文字列）に変換して表示するために使用される。
また、逆に16進数表記からバイナリに戻すことも可能。

基本的な使い方
xxd <ファイル名>
LPIC-1 102(Version: 5.0) 合格体験記

# はじめに
実務経験7ヶ月目の私が、LPIC-1 102試験に合格するまでに行った学習内容を記録している記事です。</br>
1度落ちてしまい、2度目の試験で合格しました。かかった期間は**4週間**でした。</br>
そこで得た個人的意見を記載しています。
本記事がどなたかの参考になれば幸いです。

- [LPIC-1 Exam 102](https://learning.lpi.org/ja/learning-materials/102-500/)

## 受験時の私のスペック
- エンジニア歴7ヶ月(Python, AWS)
- 保有資格：AWS SAA, LPIC101
  - それぞれ合格体験記を書いています。 </br>[AWS SAA合格体験記](https://qiita.com/beagle_masato/items/8b58640526bea826abb2), [LPIC-1 101合格体験記](https://qiita.com/beagle_masato/items/4bc84242c69d5525515e)

## なぜ受験するのか
- 現在の現場でIaCツールを使用した自動化業務をしており、Linuxの基礎知識が必要であるため

## 学習内容

### 1度目
**ping-tの最強WEB問題集のみ**</br>
 [ping-t](https://mondai.ping-t.com/g/question_subjects#content-large_category_3)</br>
やはり便利なこちらのサイトを利用しました。
全体を通して2周し、不安なトピックのみ3周しました。
また、このサイトのAIアシスタントが優秀なため、そちらを積極的に活用しました。</br>
最終的な理解度として、最強WEB問題集の問題が9割正解できる程度の状態で試験に挑みました。

#### 学習期間
3週間の学習をしました。詳細な時間は計測していないため不明です。

#### 結果
480/800で不合格でした、、、</br>
コマンドやファイルのパスに関する記述式の問題がほぼ解けず、、、

---
### 2度目
**ping-tのコマ門 + 最強WEB問題集**</br>
 [ping-t](https://mondai.ping-t.com/g/question_subjects#content-large_category_3)</br>
記述式の問題に対応するために、コマ問を2周解きました。
結果として相当理解が深まりました。今までフワっとした理解で試験に臨んでいたことが判明、、ちゃんと対策しないとダメですね</br>

最強WEB問題集もやりましたが、1周もしていません。</br>
記述式の問題が解ける状態になっていたので、選択式の問題が簡単過ぎました！

#### 学習期間
1回目の試験から1週間だけ学習をしました。

#### 結果
630/800で合格でした!</br>


## 本番の問題の感覚
ping-tのコマ門 + 最強WEB問題集をしっかりやっている状態なら十分合格可能かと思います！別途、参考書の購入も検討しましたが、ping-tで十分でした！



## 合格を目指すにあたってのTips

記述式の問題の対策は必須かなと思います！</br>
というのも、1回目の試験では、コマンドのスペルを間違えたり、ファイルへの絶対パスを記述する際のお左方の対応ができていなかったりで、沢山間違えてしまったからです。</br>

やはり頭の中では分かっていても、いざ記述するとなると間違えてしまうものなので！</br>
(逆にLPIC-1 101試験を記述式の対策なしでパスしたのが不思議です笑)

記述式の対策を1週間しただけで、480/800→630/800に得点アップしたので、非常にやる価値があるかなと思います！

## 最後に
本記事をお読みいただきありがとうございました。</br>どなたかの参考になれば幸いです。
Ｗindows音声認識を再評価してみる　～業務へどう活用するか～

# はじめに
はじめまして。yasue-yasuoです。QIITA初めての投稿となります。こういった記事の発信自体が初めてなので、不慣れな点もあるとは思いますが、宜しくお願いします。

この記事では、Windows音声認識というWindowsOSに標準で入っている機能があるのですが、いまいち世の中での活用がされていないと感じられます。それどころかネットで調べると「Windows音声認識は精度が悪い、使い物にならない」、という語られかたをされることが多いため、その魅力・可能性を再評価していきたいと思います。

# Windowsの音声関連の機能
Windowsに標準付属している音声認識機能には、WindowsVistaから搭載されているWindows音声認識（オフライン可）、また、Windows11から搭載されているWindows音声入力（ネット接続必要）、Windows11(22H2)から搭載されたWindows音声アクセス（オフライン可）があります。

Windows11(22H2)ではWindows音声認識、Windows音声入力、Windows音声アクセスという3種類の機能が共存することになり、非常にややこしい状況ですが、この記事ではオフライン環境でも使える日本語の音声認識機能を検討しているため、ネット接続が必要なWindows音声入力と、2024年10月現在、英語しか対応していないWindows音声アクセスは検討の対象外とします。

# Windows音声認識の起動方法
①初期状態
Windows音声認識は一度も立ち上げたことがなければ、通常のスタートメニューからアプリ一覧を辿っても辿りつくことはできません。
「スタートメニュー」→「設定」→「簡単操作」→左のメニューを下に辿ると「音声認識」をクリックし、その後、画面に表示される指示に従ってください。（マイクの設定、初期トレーニングなど）　これによって今後、標準的なアプリとして使用可能な状態になります。

②設定後
「スタートメニュー」→「アプリ一覧」→「Windows簡単操作」→「Windows音声認識」より立ち上げてください。






次回からは、Ｗindows音声認識の使用場面をお伝えしていきたいと思います。
Flutterで usb_serial 0.5.2 を使ったプロジェクトがビルドできなくなったので直す(javaライブラリUsbSerial-6.1.0関連のエラー)

# 概要

Flutterで、以前正しくビルドできていたusb_serialを使ったプロジェクトが、以下のエラーメッセージが出てビルドできなくなったので、直す方法をまとめる。

```
FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':app:checkDebugAarMetadata'.
> Could not resolve all files for configuration ':app:debugRuntimeClasspath'.
   > Could not find com.github.felHR85:UsbSerial:6.1.0.
     Searched in the following locations:
       - https://dl.google.com/dl/android/maven2/com/github/felHR85/UsbSerial/6.1.0/UsbSerial-6.1.0.pom
       - https://repo.maven.apache.org/maven2/com/github/felHR85/UsbSerial/6.1.0/UsbSerial-6.1.0.pom
       - https://storage.googleapis.com/download.flutter.io/com/github/felHR85/UsbSerial/6.1.0/UsbSerial-6.1.0.pom
       - https://jcenter.bintray.com/com/github/felHR85/UsbSerial/6.1.0/UsbSerial-6.1.0.pom

```

<br>

# 詳細

## 環境

- Windows 11
- Flutter SDK 3.24.4
- Android SDK Tools 35
- usb_serial 0.5.2 (https://pub.dev/packages/usb_serial)
- VSCodeのFlutter拡張を使用してFlutterプロジェクトをビルド

```
Flutter 3.24.4 • channel stable • https://github.com/flutter/flutter.git
Framework • revision 603104015d (2 days ago) • 2024-10-24 08:01:25 -0700
Engine • revision db49896cf2
Tools • Dart 3.5.4 • DevTools 2.37.3
```

<br>

## 原因の推定

- usb_serial 0.5.2は、javaライブラリ UsbSerial-6.1.0 参照する
- そのため、ビルド時にUsbSerial-6.1.0をリポジトリに取りに行くが、置かれているはずのリポジトリで見つからない

↓

参照先リポジトリを修正する必要がありそう？

<br>

## 修正その1

usb_serialのフォルダ

```
C:\Users\{ユーザー}\AppData\Local\Pub\Cache\hosted\pub.dev\usb_serial-0.5.2
```

にあるandroid/build.gradleの2か所の参照先リポジトリを修正する。

```
buildscript {
    repositories {
        google()
        jcenter()
        mavenCentral() // 追加
    }
```

buildscriptを修正

```
rootProject.allprojects {
    repositories {
        google()
        jcenter()
        maven { url "https://jitpack.io" }
        mavenCentral() // 追加
    }
    : 以下略
```

この修正を実施し、flutterプロジェクトを **ビルドしてみたが、同様のエラーが出てしまい失敗。**

<br>

## 修正その2

何かおかしいところがないか、再度調べる過程で jitpack.io というリポジトリの

https://jitpack.io/#felHR85/UsbSerial

というページにあるビルドログを見ると、6.1.0がビルドエラーになっている。

https://jitpack.io/com/github/felHR85/UsbSerial/6.1.0/build.log

一方、1つ前の6.0.6を見るとbuild successとなっている。

https://jitpack.io/com/github/felHR85/UsbSerial/6.0.6/build.log

なので、6.1.0というのは参照できないバージョンなのではないか？と考えられた。そこで、build.gradleに戻り、その1の修正にさらに以下の変更を追加。

```
dependencies {
    // implementation 'com.github.felHR85:UsbSerial:6.1.0'
    implementation 'com.github.felHR85:UsbSerial:6.0.6'
}
```

この状態でビルドしたところ、**成功！**

```
Launching lib\main.dart on SH M24 in debug mode...
√ Built build\app\outputs\flutter-apk\app-debug.apk
```

<br>

# まとめ

usb_serial 0.5.2を使ったプロジェクトのビルドエラーを解消できた。ただし、バックグラウンドで使用されるUsbSerialのバージョンを変更したことによるアプリケーション側での影響がないかは注意する必要がある。

また、かつて6.1.0で動作していた実績はあるので今回の方法は応急処置的なものの可能性がある。いずれは6.1.0で動作するように再修正したい。
picoCTF #Forensics - information

■問題
Files can always be changed in a secret way. Can you find the

ファイルは常に秘密の方法で変更できます。あなたはそれを見つけることができますか？

■解き方
①ファイルをダウンロードする

②ダウンロードしたファイルのメタデータを確認する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3519665/d7a07128-595b-aff6-c38a-fdac7b1d1111.png)

③Licenseに記載されている文字列をbase64でデコードしフラグを取得する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3519665/0df872d5-b672-ea0a-6f47-747c4a5283e5.png)
【JavaScript】URL.canParse()の使い方

## `URL.canParse()`を使用する

`URL.canParse()`の引数にURL文字列を渡すことで有効か判定できます。

```js
function isValidURL(url) {
  return URL.canParse(url)
}
```

https://developer.mozilla.org/ja/docs/Web/API/URL/canParse_static

## URLの有効性を判定する他の方法

`URL()`コンストラクターが与えられたURL文字列が有効でなければ例外をスローすることを利用して以下のように判定することもできます。

```js
function isValidURL(url) {
  try {
    new URL(url)
    return true
  } catch {
    return false
  }
}
```

https://developer.mozilla.org/ja/docs/Web/API/URL/URL

## 参考

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