OmniAICreator/Qiita-1.07M huggingface dataset:
JLCPCBで多色な基盤を注文してみよう【その１】

## JLCPCBで多色な基板を注文してみよう【その１】

宮崎県立都城工業高等学校 ロボット競技部はJLCPCBのスポンサーを受けています。

![JLCPCB-logo.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3881936/95c7a9ff-fa58-b4a1-79ed-3a482406b7c4.png)

PCB発注ならJLCPCB!!　最近需要が高まっている多層(6層など)PCB作成も出来ます。
現在たった**2ドル**で5枚、2層、サイズ 10cmx10cmどの色のPCBでもJLCPCBで発注できます！
**新規ユーザーは$60クーポンを獲得できるそうです**。この機会に発注してみてはいかがですか？

英語発注システム
https://jlcpcb.com/JPV/
日本語発注システム
https://jlcpcb.com/jp/

https://x.com/JLCPCB_Japan

## なぜ基板を作ることに至ったか
これまでは**Daisen DSR-120**の4chモータードライバを使っていましたが、**4枚(16個接続)**
までしか制御できなかったり、1枚あたりが**約2万円**ほどなので、より安く、より多く、制御できる基板を作ってみることに至りました。

### 基板(PCB)の作り方については次回(その2)で説明します。

## 今回発注した基板(PCB)とロボット部品
![IMG_20241008_205539.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3881936/24ea259f-ccb4-3b19-483a-f8013b7844f0.jpeg)
![IMG_20241004_144149.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3881936/ed6d68f8-c173-8036-fecd-a1ed389bb8e1.jpeg)
![IMG_20241008_205551.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3881936/8227b8b2-6f4a-aced-baa6-5e6ec3cc8f70.jpeg)
![IMG_20241008_205601.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3881936/76e30c4d-40ac-0ef7-bf73-82a5dbefb2b9.jpeg)
![IMG_20241008_205619.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3881936/a55da822-da67-9ae2-bc4a-0f450514fa77.jpeg)

今回はPCBA(PLCPCBが実装)を2枚とエアチャック、エア電磁弁、フィッティング、PCBなどを注文して、送料込みで140ドル(約2万円ほど)でした。

PCBAにコンデンサ、サン端子レギュレーター、タクトスイッチなどをつけてみました。
![IMG_20241008_183214.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3881936/828c5efa-a690-3e32-6d9d-e6f7b707db9c.jpeg)

## 基板の機能紹介
今回制作した基板では、Arduinoで制御できるPWMピンは限りあり、**Mega 2560**でも**13ピン**しかなく、モータードライバ(**東芝 TB67H450FNG**)で制御できるモーター数は**5個**しかなく、沢山制御するためにはI2Cで通信できる**PCA9685**で制御でき、**最大992個**のモーターを制御できるそうです。
シールド化したことにより、省スペース化を達成したり、ピンヘッダなどに配線を伸ばして接触不良などを防止することができました。

## エアチャックやエア電磁弁など
![IMG_20241008_183418.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3881936/8c83447b-0273-f93c-32cc-f9ba6d93995d.jpeg)

エアチャックとは、親機ロボットのアーム部に使われている開く、閉じるの動作を*+エア（空気圧）**で制御できるものです。
エア電磁弁とは、エアチャックに流れる**エア（空気圧）**の方向の変化によって、エアチャックの開閉を実現しています。


## 最後に

 基板の作成、発注方法につきましては、次回解説いたします。

 次の**みやざきテクノフェア**(2024/11/8,11/9開催) という大会では、今回制作した基板を取り付けて動作している次のロボットの動作などは**みやざきテクノフェア**で見ることができると思うのでぜひ来てください。とてもロマンのある機体を皆さんに見せれたらと思っています。お楽しみに。ここまで見てくださりありがとうございました。
Slackで自分の事は me

自分の投稿を検索するときも `from:me` で検索できます。

他にもワークフローなどでユーザーを検索するときも `me` で出てきます。  
※名前にmeが含まれる人も出ちゃうので自分のイニシャルが2文字でユニークな場合はそちらのほうが早いです
CSS変数とJavaScriptを使って、アンカーリンクのジャンプ先の位置を柔軟に調整する

ウェブサイトでアンカーリンクを使用する際、固定ヘッダーがあると目的の位置に正確にジャンプできないことがあります。この問題を解決するために、CSS変数とJavaScriptを組み合わせた柔軟な方法を紹介します。

## 解決策の概要

1. CSS変数を使ってデフォルトのアンカー位置調整値を設定
2. HTMLで個別の調整を可能にする
3. JavaScriptを使って動的にスタイルを適用

## コードと解説

### 1. CSS

```css
:root {
    --header-height: 4.125pc;
    --anchor: var(--header-height);
}

@media print, screen and (min-width: 744px) {
    :root {
        --header-height: 8.25pc;
        --anchor: var(--header-height);
    }
}

[anchor] {
    margin-top: calc(var(--anchor) * -1);
    padding-top: var(--anchor);
}
```

このCSSは、`:root`セレクタを使ってグローバルなCSS変数を定義しています。`--header-height`はヘッダーの高さを、`--anchor`はアンカーリンクの調整値を表します。メディアクエリを使用して、画面サイズに応じて値を変更しています。

### 2. HTML

```html
<!-- デフォルトの調整を使用 -->
<hr id="section1" anchor />

<!-- カスタム値で調整 -->
<hr id="section2" anchor="20pc" />

<!-- インラインスタイルで調整 -->
<hr id="section3" anchor style="--anchor:20pc;" />
```

HTMLでは、`anchor`属性を使ってアンカーリンクの調整を適用します。属性値を指定するか、インラインスタイルでCSS変数を上書きすることで、個別の調整が可能です。

### 3. JavaScript

```javascript
(function () {
    const elements = document.querySelectorAll('[anchor]');
    const STYLE = document.createElement('style');
    document.head.appendChild(STYLE);

    elements.forEach((el) => {
        const anchorValue = el.getAttribute('anchor');
        let id = el.id || 'anchor-' + Math.random().toString(36).substr(2, 9);
        el.id = id;

        const anchorStyle = `
            #${id} {
                margin-top: calc(-1 * (${anchorValue || 'var(--anchor)'}));
                padding-top: ${anchorValue || 'var(--anchor)'};
            }
        `;

        try {
            STYLE.sheet.insertRule(anchorStyle, STYLE.sheet.cssRules.length);
        } catch (e) {
            console.error(`Failed to insert CSS rule for element with id "${id}": ${e.message}`);
        }
    });
})();
```

このJavaScriptは以下の手順で動作します：

1. `anchor`属性を持つすべての要素を選択
2. 新しい`<style>`要素を作成
3. 各要素に対して：
   - `anchor`属性の値を取得
   - ユニークなIDを確保
   - CSSルールを生成
   - 生成したルールをスタイルシートに挿入

## 使い方

1. CSSをスタイルシートに追加
2. JavaScriptをページに読み込む
3. アンカーリンクを調整したい要素に`anchor`属性を追加
4. 必要に応じて、属性値やインラインスタイルで個別に調整

## 利点

1. **柔軟性**: デフォルト値をグローバルに設定しつつ、個別の要素で簡単に調整可能
2. **メンテナンス性**: ヘッダーの高さが変更された場合、CSS変数を更新するだけで全体に反映
3. **再利用性**: このスクリプトは様々なプロジェクトで再利用可能
4. **パフォーマンス**: JavaScriptによるDOM操作が最小限で、ページ読み込み時に一度だけ実行
5. **互換性**: `scroll-padding-top`のブラウザサポートに依存せず、幅広いブラウザで動作
6. **デザイナーフレンドリー**: HTMLの属性やインラインスタイルで簡単に調整可能

## まとめ

この方法を使用することで、アンカーリンクのジャンプ先位置を柔軟かつ効果的に調整できます。CSS変数とJavaScriptの組み合わせにより、開発者とデザイナーの両方にとって使いやすいソリューションとなっています。固定ヘッダーを使用するレスポンシブデザインのウェブサイトで特に有用であり、ユーザーエクスペリエンスを向上させることができます。
Go言語(Golang)の、変数のスコープとメモリアドレス

```go
	ok, result := true, "A"

	fmt.Printf("memory address of result: %p\n", &result)
	if ok {
		result := "B"
		fmt.Printf("memory address of result: %p\n", &result)
		println(result)
	} else {
		result := "C"
		println(result)
	}

	println(result)
```

このGo言語のコードは、変数のスコープとメモリアドレスの取得に関する例です。

```go
ok, result := true, "A"
fmt.Printf("memory address of result: %p\n", &result)
```

1. **変数の初期化**:
   - `ok` と `result` という2つの変数を同時に初期化しています。`ok` は `true`、`result` は `"A"` という文字列です。
   - `:=` 演算子を使っているため、これらの変数は新たに宣言されます。

2. **メモリアドレスの表示**:
   - `fmt.Printf` を使って `result` のメモリアドレスを表示しています。`&result` で `result` のアドレスを取得し、`%p` フォーマットを指定してポインタ形式で出力します。

```go
if ok {
	result := "B"
	fmt.Printf("memory address of result: %p\n", &result)
	println(result)
} else {
	result := "C"
	println(result)
}
```

3. **条件分岐**:
   - `if ok` の条件が `true` なので、`if` ブロック内が実行されます。
   - `result := "B"` で新たに `result` という変数を宣言し、スコープが `if` ブロック内に限定されます。この `result` は `A` とは異なる変数です。

4. **再びメモリアドレスの表示**:
   - 新しく宣言した `result` のメモリアドレスを表示します。これは `B` を指します。

5. **`println` の実行**:
   - `println(result)` で `B` が出力されます。

6. **`else` ブロック**:
   - `else` ブロックは実行されませんが、`else` の中でも同様に `result := "C"` とすると、新たに `result` が定義され、そのスコープは `else` ブロック内に限られます。

```go
println(result)
```

7. **最終的な出力**:
   - `println(result)` は `if` ブロックの外にあるため、最初に定義した `result`（つまり `"A"`）が出力されます。この時、`if` ブロックで宣言した `result` はスコープ外になっているため、影響を与えません。

### まとめ
- `result` は最初に `"A"` として定義され、`if` ブロック内で新たに `result` が `"B"` として定義されていますが、これは別の変数です。
- `if` ブロック外での `println(result)` は最初の `"A"` を表示します。
【DAY29】UDPとTCP

## UDPとは
UDP（User Datagram Protocol）とは、特にスピードを重視した通信に使用される通信プロトコルです。UDPではデータ転送前に正式な接続の確立をしないことで通信を高速化します。
UDPには転送速度は高いが信頼性が低いという特徴があります。この特徴から、オンラインゲームや動画の再生など質よりも時間、リアルタイム性が求められる場面で使用されます。
## TCPとは
TCP（Transmission Control Protocol）とは、安全性を重視した通信に使用される通信プロトコルです。通信前の打診や相手の受信処理など、その都度確認をしながら通信する方法です。
TCPには信頼性は高いが転送速度が低いという特徴があります。インターネットでWebページを見る時にはこのTCPが使用されています。



UDPとTCPは、どちらもOSI参照モデルのトランスポート層にあたるプロトコルです。
Go言語(Golang)のポインタとメモリアドレス

### 1. 変数の宣言とメモリアドレスの表示

```go
var ui1 uint16
fmt.Printf("memory address of ui1: %p\n", &ui1)

var ui2 uint16
fmt.Printf("memory address of ui2: %p\n", &ui2)
```

- `ui1`と`ui2`は、`uint16`型の変数です。
- `&ui1`のように「&」を使うことで、変数のメモリアドレスを取得できます。`%p`フォーマット指定子を使って、ポインタとして出力します。

### 2. ポインタの宣言と初期化

```go
var p1 *uint16
fmt.Printf("value of p1: %v\n", p1)

p1 = &ui1
fmt.Printf("value of p1: %v\n", p1)
```

- `p1`は`uint16`型のポインタです。初期状態では`nil`（何も指していない状態）です。
- `p1 = &ui1`によって、`ui1`のメモリアドレスを`p1`に代入します。これにより、`p1`は`ui1`を指すようになります。

### 3. ポインタのサイズとメモリアドレス

```go
fmt.Printf("size of p1: %d[bytes]\n", unsafe.Sizeof(p1))
fmt.Printf("memory address of p1: %p\n", &p1)
```

- `unsafe.Sizeof(p1)`は、ポインタのサイズをバイト単位で返します。通常、ポインタのサイズはシステムによって異なります（32ビットシステムでは4バイト、64ビットシステムでは8バイト）。
- `&p1`で`p1`のメモリアドレスを出力します。

### 4. ポインタの間接参照

```go
fmt.Printf("value of ui1(dereference): %v\n", *p1)

*p1 = 1
fmt.Printf("value of ui1: %v\n", ui1)
```

- `*p1`を使うことで、ポインタが指している変数（この場合は`ui1`）の値を取得します。この操作を「間接参照」と呼びます。
- `*p1 = 1`により、`ui1`の値を1に設定します。この時点で、`ui1`の値が変更されます。

### 5. 二重ポインタの使用

```go
var pp1 **uint16 = &p1
fmt.Printf("value of pp1: %v\n", pp1)

fmt.Printf("memory address of pp1: %p\n", &pp1)
fmt.Printf("size of pp1: %d[bytes]\n", unsafe.Sizeof(pp1))
```

- `pp1`は`p1`のポインタであり、二重ポインタです。これにより、ポインタのポインタを扱うことができます。
- `&p1`で`p1`のアドレスを`pp1`に代入します。

### 6. 二重ポインタを通じた間接参照

```go
fmt.Printf("value of p1(dereference): %v\n", *pp1)
fmt.Printf("value of ui1(dereference): %v\n", **pp1)

**pp1 = 10
fmt.Printf("value of ui1: %v\n", ui1)
```

- `*pp1`は`p1`を指し、`**pp1`は`ui1`の値を直接参照します。
- `**pp1 = 10`により、`ui1`の値を10に設定します。
SwiftDataで1:多(one to many relationship)のモデル作ったよ。子要素が更新されない問題が発生したけど、なぜか解決したよ！

# はじめに
レーダーチャートを作成・管理できるアプリを作成しました。
「amime（読み方：あみめ）」です。
このアプリでは例えば「居酒屋」というグループが親になり、その子として実際のお店「磯丸水産」や「鳥貴族」などの子の評価をそれぞれ設定し、レーダーチャートで表示することができます。

この記事では1:多のモデル定義とその問題点について記載してあります。
実際にアプリを操作してみると、よりイメージを掴みやすいと思うので、是非ダウンロードしてみてください！

https://apps.apple.com/jp/app/amime/id6736557722

# 1:多のモデル定義
``` Swift
import SwiftUI
import SwiftData

@Model
final class Template: Identifiable { // ←←← 居酒屋
    @Attribute(.unique) var id: UUID
    var title: String
    var category: [String]
    @Relationship(deleteRule: .cascade, inverse: \Chart.template) var charts: [Chart]

    init(title: String, category: [String], charts: [Chart] = []) {
        self.id = UUID()
        self.title = title
        self.category = category
        self.charts = charts
    }

    init(id: UUID, title: String, category: [String], charts: [Chart] = []) {
        self.id = id
        self.title = title
        self.category = category
        self.charts = charts
    }
}

@Model
final class Chart: Identifiable, Hashable { // ←←← 磯丸水産、鳥貴族
    var template: Template
    var title: String
    var data: [String : Double]
    
    init(template: Template, title: String, data: [String : Double]) {
        self.template = template
        self.title = title
        self.data = data
    }
    
    // Hashableの準拠に必要なメソッド
    static func == (lhs: Chart, rhs: Chart) -> Bool {
        return lhs.title == rhs.title && lhs.data == rhs.data
    }
    
    func hash(into hasher: inout Hasher) {
        hasher.combine(title)
        hasher.combine(data)
    }
}
```

こちらがソースコードになります。
`@Relationship`で親子関係を定義できます。


:::note warn
でも、ちょっと待った！
実はこのソースコードだと、子要素を追加した際、画面の再描画がされないんです！
:::


# 問題点
実は、上記ソースコードだと、子要素を追加してもリストに表示されないんです。
でもアプリを再起動するとリストに表示されるので、データの永続化はできているけど、データの再取得がされていないんです！

# 解決策
```diff_swift
@Model
final class Chart: Identifiable, Hashable {
-   var template: Template
+   var template: Template?
    var title: String
    var data: [String : Double]
    
    init(template: Template, title: String, data: [String : Double]) {
        self.template = template
        self.title = title
        self.data = data
    }
    
    // Hashableの準拠に必要なメソッド
    static func == (lhs: Chart, rhs: Chart) -> Bool {
        return lhs.title == rhs.title && lhs.data == rhs.data
    }
    
    func hash(into hasher: inout Hasher) {
        hasher.combine(title)
        hasher.combine(data)
    }
}
```

これで解決するんです！
でも、何故かは分かりません！
誰か教えてください！

解決策を見つけたサイト：https://stackoverflow.com/questions/78528965/swiftdata-does-not-retrieve-my-inverse-one-to-many-relationship


# さいごに
SwiftDataを利用して1:多の関係性を表現することができました。
この記事が誰かの役に立つことを願っています。

おわり
中華製レーザーカッターセットアップ備忘録

中華製レーザーカッターのセットアップ
マニュアルもイマイチ参考になるサイトも少ないので備忘録として書いておく

##対象は制御基板が6C6879-LASER-M2の物です
制御パネル付近の筐体の中に基板はあります。
そしてシルクで型名が書いてあるのでこの内容が対象なのかは判断してください

##制御ソフト　K40をインストール
私はCADで描いたデータを使って加工したいです。
DXFファイルを読み込めて加工できる制御ソフトK40があることをしり
こちらからインストールしてセットアップしました。
https://www.scorchworks.com/K40whisperer/k40whisperer.html
#ドライバーインストール
早速動かそうとしましたがUSBドライバーが上手く認識せず模索しました。
原因はZadigというアプリを通じてUSBドライバーをインストールする必要がありました。

こちらを参考に行いました。
https://www.scorchworks.com/K40whisperer/k40w_setup_zadig.html


##最後に
今回はここまで実際にはレーザーの調整などありますが今回はここまでです
ドクターOさんのサポートを受けここまでできました
ココでお礼を言っておきます
ありがとうございました。
[備忘録]RailsでWebAPIをつくるときに抑えておくとよさそうなこと

転職をして、Railsを触り始めました。

慣れるまでに時間はかかりそうですが、慣れるとスピーディに機能追加できそうでいいなと思いました。

業務では今WebAPIを触ることがメインで、それに関することをざっくりとまとめました。

どの処理のときに何を使えばいいかをまとめています。

* リクエストを受け取れるようにする→ルーティング
  * https://railsguides.jp/routing.html
* リクエストを受け付けるとき
  * リクエストを受け付けたときの全体の処理の流れを定義する→Controller
    * https://railsguides.jp/action_controller_overview.html
  * リクエストパラメータで許可したものだけ受け付けるようにする→Strong Parameters
    * https://railsguides.jp/action_controller_overview.html#strong-parameters
  * リクエストを一度格納する→Active Model(フォームオブジェクト
    * https://applis.io/posts/rails-design-pattern-form-objects#form%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E3%81%AE%E5%BF%85%E8%A6%81%E6%80%A7
      * もっと適切なものがあるかもしれない。
    * パラメータの妥当性をチェックする→ActiveModel::Validations
* メインの処理（ビジネスロジック）を行う→複雑さによる
  * データベースのテーブル（少なめ）とのやり取りを行い、ロジックはシンプル→Active Record
  * 複雑→さまざまな議論がされて、いろいろなやり方があるよう。
    * https://techracho.bpsinc.jp/hachi8833/2021_01_07/14738
    * https://techracho.bpsinc.jp/hachi8833/2022_03_17/46482
    * https://tech.giftee.co.jp/entry/2023/02/20/000000
* レスポンスを返すとき
  * JSONやXMLなどのフォーマットでレスポンスを作成する→シリアライザー
    * https://railsguides.jp/active_model_basics.html#serialization%E3%83%A2%E3%82%B8%E3%83%A5%E3%83%BC%E3%83%AB
  * HTMLでレスポンスを作成する→Action View
    * https://railsguides.jp/action_view_overview.html
  * 例外発生時に返すレスポンスを定義する→resuce_from
    * https://railsguides.jp/action_controller_overview.html#rescue-from


認証認可やビュー、ジョブとか、他にもいろいろあるし、WebAPI自体に使えるものももっとあるだろうけど、まずはこれだけ。
UE5において "「プロジェクト名」could not be complied. Try rebuilding from source manually"と出た時の対処法。

# 動作環境
Unreal Engine 5.4.4
Visual Studio 2022
# 問題
UE5でプロジェクトを開く際に "「プロジェクト名」could not be complied. Try rebuilding from source manually"と出てしまい、プロジェクトを進めることができなくなってしまいました。
# 解決方法

### 1. UE4プロジェクトから.slnを生成する
1. エクスプローラーで.uprojectファイルを右クリック
2. 「Generate Visual Studio project files」を選択
3. .slnファイルが生成される

### 2. Visual StudioからUnreal Engineを開く
1. Visual StudioでBuild Solutionを行う。このときにエラーがあるとうまくいかない。
2. Start Without Debuggin(Ctrl+F5)でUnreal Engineのプロジェクトwが開く。

# 参考文献
https://qiita.com/chano2/items/517157c412ce5b03e905
フォーム内のtype=”submit”はひとつだけにしよう

こんな感じのフォームがあります。
```html
<form action="xxx.php" method="post">
	<h1>送信フォーム</h1>
	<div>
		<label for="name">名前</label>
		<input type="text" id="name" name="name" required maxlength="10" />

		<button @click="history.back()">戻る</button>
		<button type="submit">送信</button>
	</div>
</form>
```

名前を入力してエンターキーを押したら送信されると思いますが、
フォームをエンターキーで送信をかける場合、**formタグの子要素にある「最初」の`type=”submit”`のボタンを実行**してしまう。

「戻る」ボタンはtype属性が記述されていないのでスルーされるかと思いきや、`button`タグの`type`属性は初期値が`type=”submit”`らしい。
[HTML5タグリファレンス](https://www.htmq.com/html5/button.shtml)

### 解決策
submitしない`button`タグには、`type=”button”`を明示的に書いてあげよう。
```html
<form action="xxx.php" method="post">
	<h1>送信フォーム</h1>
	<div>
		<label for="name">名前</label>
		<input type="text" id="name" name="name" required maxlength="10" />

		<button type="button" @click="history.back()">戻る</button> <!-- type属性追加 -->
		<button type="submit">送信</button>
	</div>
</form>
```

※マウスで送信ボタンを押した場合は影響受けないです！
【Laravel】csvの全項目をダブルクォーテーションで囲む方法！

泉（[@izumin_0401](https://twitter.com/izumin_0401)）です。

今回は、Laravelでcsvの全項目をダブルクォーテーションで囲む方法を解説しやす！

:::note info
今回は、便利なので「League/Csv」というライブラリを使います。よろしくっす！
:::

# ブログ記事はこちら

https://traveler0401.com/laravel-csv-enclosure-double/

# 【Laravel】csvの全項目をダブルクォーテーションで囲む方法

```php
use League\Csv\Writer;

class CsvService
{
    public function exec()
    {
        $csv = Writer::createFromString('');

        $csv->forceEnclosure(); // ダブルクォーテーションで囲む

        $csv->insertOne($header);
        $csv->insertAll($data);

        return $csv->getContent();
    }
}
```
「forceEnclosure」を使えば全項目をダブルクォーテーションで囲んでくれます。

https://csv.thephpleague.com/9.0/writer/#force-enclosure

# まとめ
ライブラリを使えばめっちゃ簡単にできた...

よろしくっす！（謎テンション）

ではまた！

# 最後に
暇つぶしに[Twitter](https://twitter.com/izumin_0401)と[ブログ](https://traveler0401.com/)もやってるので見てね。
Vimの基本操作について：初心者向けガイド

Vimはプログラマーやライターに人気のある高機能テキストエディタです。しかし、初めて使うと少し難しく感じるかもしれません。この記事では、Vimの基本操作を初心者向けにわかりやすく説明します。

## 1. Vimの基本モード

Vimには主に3つのモードがあり、作業内容によって使い分けます。

### ノーマルモード (Normal Mode)
Vimを起動すると、最初はノーマルモードにいます。このモードでは、テキストを編集せず、カーソルの移動やテキストの削除・コピーなどができます。

- `h`：カーソルを左に移動
- `j`：カーソルを下に移動
- `k`：カーソルを上に移動
- `l`：カーソルを右に移動

### 挿入モード (Insert Mode)
テキストを入力する際は挿入モードに切り替える必要があります。

- `i`：カーソルの前に文字を挿入
- `a`：カーソルの後ろに文字を挿入
- `Esc`：挿入モードを終了し、ノーマルモードに戻る

### コマンドモード (Command-Line Mode)
ファイルを保存したり、Vimを終了したりするためのモードです。ノーマルモードで `:` を押すとコマンドラインモードに入ります。

- `:w`：ファイルを保存
- `:q`：Vimを終了
- `:wq`：保存して終了
- `:q!`：保存せずに強制終了

## 2. ファイルの開き方

Vimでファイルを開くには、ターミナルで以下のコマンドを使います。

```bash
vim ファイル名
```

## 3. テキストの基本操作

### テキストの挿入
1. ノーマルモードで `i` を押して挿入モードに入ります。
2. 文字を入力します。
3. 終了するには `Esc` キーを押してノーマルモードに戻ります。

### テキストの削除
- `x`：カーソル位置の1文字を削除
- `dd`：カーソルのある行全体を削除
- `dw`：単語を削除

### コピーと貼り付け
- `yy`：現在の行をコピー
- `p`：カーソルの後ろに貼り付け
- `P`：カーソルの前に貼り付け

## 4. カーソル移動の基本

Vimではキーボードでカーソルを効率的に移動できます。

- `w`：次の単語の先頭に移動
- `b`：前の単語の先頭に移動
- `e`：単語の末尾に移動
- `gg`：ファイルの最初に移動
- `G`：ファイルの最後に移動

## 5. 操作の取り消しとやり直し

- `u`：直前の操作を取り消し（Undo）
- `Ctrl + r`：取り消した操作をやり直し（Redo）

## 6. 保存と終了

Vimでの作業が終わったら、以下のコマンドを使ってファイルを保存・終了します。

- `:w`：ファイルを保存
- `:q`：Vimを終了
- `:wq`：保存して終了
- `:q!`：変更を破棄して終了

## まとめ

Vimは最初こそ少し複雑に感じるかもしれませんが、基本操作を覚えれば非常に効率的に作業できるツールです。今回紹介した基本操作を何度か練習することで、Vimの操作に慣れ、もっと高度な編集作業も簡単にできるようになるでしょう。
EthereumのL2の断片化の解決案

この記事は、以下の動画の内容のまとめです。
https://www.youtube.com/watch?v=4v_nSddO-24

## はじめに
現在のEthereumエコシステムでは、複数のL2やロールアップが独立したサイロとして存在しています。これは非効率的であり、ユーザー体験を損なう要因となっています。本記事では、「United Chains of Ethereum」というビジョンを紹介し、L2間の統合と効率化について詳しく解説します。

## 1. 同期的コンポーザビリティ

### 共有シーケンサーの概念

複数のL2やロールアップが単一のシーケンサーを共有することで、以下の3つのレベルの同期性を実現できます：

1. **同期的インクルージョン**：
   - 複数のロールアップ上のトランザクションが同時にチェーンに含まれることを保証
   
2. **同期的実行**：
   - ステートルートに関する保証を提供
   
3. **同期的コンポーザビリティ**：
   - 資産の即時的な移動と清算を可能にする最も強力な形態

```mermaid
sequenceDiagram
    participant A as Rollup A
    participant S as 共有シーケンサー
    participant B as Rollup B
    
    rect rgb(200, 200, 255)
        Note over A,B: スロット開始
        S->>A: トランザクション1実行
        S->>B: クロスロールアップトランザクション
        Note over A,B: 資産の即時清算
        S->>A: トランザクション2実行
    end
    
    rect rgb(200, 255, 200)
        Note over A,B: 同期的コンポーザビリティ
        S-->>A: ステート更新
        S-->>B: ステート更新
    end
    
    Note over A,B: スロット終了
```


### スーパートランザクション

共有シーケンサーは「スーパートランザクション」を実行できます：

- 複数のサブトランザクションで構成
- リアルタイムでの資産移転が可能
- サブトランザクション間で依存関係を持つことが可能
- 仮想的なロッキングメカニズムを使用

### 証明の遅延時間の課題

同期的コンポーザビリティを完全に実現するには、高速な証明生成が必要です：

- スロット時間が12秒の場合、ブロック開始時には11秒の証明時間が利用可能
- ブロック終了近くでは数ミリ秒しか証明時間がない
- Nova等の効率的な再帰的証明や、専用ASICの開発が進行中
- 証明ASICにより、コスト・並列性・電力効率で大幅な改善が期待される

### 流動性プロバイダーによる代替案

リアルタイム証明が実現するまでの代替手段として、流動性プロバイダーを活用できます：

- 即時的な流動性を提供
- デメリット：
  - 手数料が発生
  - 資本効率が低下
  - 仲介者が必要
  - NFTなど一意の資産には適用困難
  - 大規模な取引には流動性の制約

## 2. 分散型

### 概要

分散型シーケンサーでの事前確認は、以下の特徴を持ちます：

- ユーザーが次のスロットのシーケンサーを確認可能
- 各スロットで異なるシーケンサーが活動
- スラッシング（ペナルティ）メカニズムが重要

```mermaid
graph TB
    A[ユーザー] -->|要求| B[次スロットのシーケンサー]
    B -->|事前確認| A
    B -->|実行| C[ブロックチェーン]
    D[金融的担保] -->|スラッシング保証| B

```

### スラッシングの種類

1. **安全性の違反**：
   - 約束した実行内容と異なる実行
   - 誠実なシーケンサーでは発生しない

2. **活性の違反**：
   - オフライン等による事前確認の不履行
   - 誠実でも技術的問題で発生する可能性

### MEV-Boostの修正

従来のMEV-Boostパイプラインを以下のように拡張：

- ユーザーから事前確認情報を上流に伝播
- ビルダーは事前確認を考慮してブロックを構築
- ビルダーの担保設定が必要

## 3. Based シーケンシング

### コンセプト

L1のプロポーザーをシーケンサーとして活用する新しいアプローチ：

- Ethereumの既存モジュールを活用：
  1. 決済モジュール
  2. データ可用性モジュール
  3. シーケンシングモジュール（新規活用）

### メリット

- L1のセキュリティを継承
- 信頼できる中立性
- コンポーザビリティの確保
- L1の大規模なTVL（時価総額）へのアクセス

```mermaid
graph TB
    A[ユーザー] -->|要求| B[シーケンサー]
    B -->|事前確認| A
    B -->|委任| C[ゲートウェイ]
    C -->|実行| D[インクルーダー]
    E[担保] -->|保証| B

```

### 実装の課題

- 高帯域幅が必要
- 複数のフルノード運用が必要
- 高可用性と低遅延が要求される
- 実行チケット機能の実装待ち

### 短期的な解決策

- 信頼できるゲートウェイの導入
- プロポーザーからゲートウェイへの権限委任
- ゲートウェイの担保設定

## まとめ

Ethereumの統合チェーンビジョンは、以下の段階で実現を目指します：

1. 中央集権的シーケンサーから分散型シーケンサーへの移行（80%の課題）
2. 共有シーケンシングの実現（15%の課題）
3. Based シーケンシングの導入（5%の課題）

このビジョンの実現により、Ethereumエコシステムの断片化が解消され、より効率的で統合された環境が実現されることが期待されます。
pipreqsとpipreqsnbでスリムなrequirements.txt書き出し

# 内容
はじめまして。私は普段メーカーで機械学習の業務に携わっております。
仕事中、他の同僚とPythonの開発環境を揃える必要があるときは少なからずあります。
とはいえガチガチのエンジニアというわけでもない（いわゆる手を動かす研究開発も並行して行っています）ような企業研究者だと、Dockerのようなコンテナ型の仮想環境を使って……という手段も取りにくかったりします。
例えば、相手がDockerを知らない、それどころかPythonを触ったばかり、利用コストが申請しづらい（これが一番多い）等々。
そういうときに活躍するのが皆様ご存知のrequirements.txtですが、```pip freeze```で作って中身を見てみると、まあごちゃっとしていて、仮想環境に入れたパッケージが全部含まれている。.pyファイルや.ipynbファイルの必要最小限なパッケージを把握したいだけなのに。
こういうときに、スリムなrequirements.txtを出力できるpipreqsとpipreqsnbが役に立ちます。前置きが長くなりすぎました。

## 実行環境および前提条件
・Windows11
・Python3
・上記のように開発環境を揃える際にDockerを使うのが難しい人
・.pyだけでなく.ipynbもよく使う

## 使用ライブラリ
・pipreqs

https://pypi.org/project/pipreqs/

・pipreqsnb

https://pypi.org/project/pipreqsnb/

## 使用方法
#### インストール
Winキーのあとcmdと入力してコマンドプロンプトを呼び出し、下記の通りコマンドを実行する
```
pip install pipreqs
pip install pipreqsnb
```
#### 書き出し
あらかじめ```cd {プロジェクトが保存されたディレクトリパス}```で移動してから実行
```
pipreqs
```
もしくは下記のように実行すると移動しなくてもOK
```
pipreqs {プロジェクトが保存されたディレクトリパス}
```
いずれも選択したディレクトリ下にrequirements.txtが作られる。

pipreqsは.pyファイルのみが対象のため、.ipynbファイルのときはpipreqsnbを使う。
(pipreqsnbのリファレンスだと.pyもできそうだったが、試したら上手くできなかった)
```
(対象が.ipynbの場合)
pipreqsnb {プロジェクトが保存されたディレクトリパス}
```
### オプション
pipreqsnbはpipreqsのラッパーなので、ほぼ同じオプションが使える。
共通で使えるものを下記に示す。
| Option |  |
|:-|:-|
|--use-local|PyPIを使わずローカルパッケージ情報のみを使用する|
|--pypi-server {url}|カスタムPyPIサーバーを使用する|
|--proxy {url}|プロキシを使用する|
|--debug|デバッグ情報を出力する|
|--ignore {dirs}...|カンマで区切られた余分なディレクトリを無視する|
|--encoding {charset}|ファイルを開くときのエンコーディングを指定する|
|--savepath {file}|指定されたファイルに要件リストを保存する|
|--print|標準出力に要件のリストを出力する|
|--force|保存先にrequirements.txtがあっても上書きする|
|--diff {file}|requirements.txt内のパッケージとプロジェクトのインポートを比較する|
|--clean {file}|requirements.txtからプロジェクトにインポートされていないパッケージを削除する|

ちなみに、エンコーディングを指定していないと```UnicodeDecodeError```を吐くことが非常に多いので、下記のように使うことが多い（むしろ私の環境だと今のところ100%そう）。
```
pipreqsnb --encoding UTF8 {プロジェクトが保存されたディレクトリパス}
```
## 終わりに
.ipynbはpipreqsで捕捉できない！と嘆いていたところにpipreqsnbを見つけたので記事を書いてみました。
また、記事を書く際は公式リファレンス以外に下記リンクを参考にさせていただきました。
ありがとうございます。
・[最小限なrequirements.txtの作成方法](https://qiita.com/HIKARU_JY/items/21b2f9d77f7377d7ca0b)
・[pipreqsがUnicodeDecodeErrorになるときの対処法](https://qiita.com/KyleKatarn/items/27f6c49148db0961f90a)
GitHubの『サメ（Pull Shark）🦈』と『YOLO』バッジをゲットする方法と条件


## 1. はじめに
GitHubには開発者の活動を称える多くのバッジが存在します。
今回は、サメ（Pull Shark）とYOLOバッジに焦点を当て、これらの取得条件や背景について解説します。
これを参考にして、あなたもぜひバッジをゲットしてください！

## 2. YOLOバッジについて

### バッジ概要
YOLOバッジは、レビューなしでプルリクエストをマージした際に付与されるバッジです。
YOLOは「You Only Live Once」の略で、レビューを飛ばしてコードを直接マージするという大胆な行為を称えています。

### 取得条件
- **取得条件**: プルリクエストをレビューなしでマージする
- **注意点**: このバッジは1回のみ取得可能です。

## 3. サメ（Pull Shark）バッジについて

### バッジ概要
Pull Sharkバッジは、プルリクエストがマージされることで得られるバッジです。
マージ回数に応じてブロンズからプラチナまでランクがあり、たくさんのプルリクをマージすることで上位のバッジを獲得できます。

### 取得条件
- **ブロンズ**: 2つのプルリクエストがマージされると取得
- **シルバー**: 16回
- **ゴールド**: 128回
- **プラチナ**: 1024回


## 4. まとめ
GitHubの「サメ」と「YOLO」バッジは、開発者としての活動を記録し、自己の成長を視覚的に表現する良い方法です。
![スクリーンショット 2024-10-08 19.29.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3884985/67606182-8bef-7f64-76ba-decc6e893519.png)
これらを取得して、あなたのプロフィールをさらに輝かせてみてください！

詳しくは、[GitHub Achievementsのリポジトリ](https://github.com/drknzz/GitHub-Achievements)でバッジに関する詳細を確認できます。
テキストプロンプトを使用してTailwind CSSを生成する

革新が重要なウェブ開発のダイナミックな世界では、エレガントでレスポンシブなデザインを効率的に作成する能力がゲームチェンジャーです。ここに登場するのが、Tailwind CSSでのスタイリングアプローチを変革する画期的なツール、Tailwind Genieです。Tailwind Genieは、ユーザーが単に迅速に作業するだけでなく、ウェブデザインの複雑さをナビゲートする際に賢く感じることができるようにします。

Tailwind Genieの本質は、シンプルなテキストプロンプトからTailwind CSSコンポーネントを生成するAI駆動のプラットフォームです。あなたのデザインニーズを理解し、それをクリーンで機能的なコードに瞬時に変換する仮想アシスタントがいると想像してみてください。この革新的なアプローチは、生産性を高めるだけでなく、創造的なエネルギーを解放し、本当に重要なこと—あなたのビジョンを実現すること—に集中できるようにします。

Tailwind Genieの魔法は、スタイリングプロセスを解明する能力にあります。もはや、複雑なCSSと格闘したり、完璧な外観を得るために何時間もかけて微調整する必要はありません。代わりに、Tailwind Genieを使えば、シンプルな言葉でデザイン要件を表現し、必要なコードが瞬時に生成されるのを見守ることができます。たとえば、「微妙な影と丸みを帯びたエッジを持つプライマリボタンが欲しい」とリクエストすると、Tailwind Genieはほぼ瞬時に、必要なTailwind CSSコードを生成します。この効率性は時間を節約するだけでなく、デザイナーとしての自信を高めてくれます。あなたのアイデアが通常の障害を超えて実現できることを知っているからです。

さらに、Tailwind Genieはレスポンシブデザインの推測を取り除きます。今日の多様なデバイス環境では、すべての画面サイズでデザインが素晴らしく見えることが不可欠です。Tailwind Genieは自動的にレスポンシブデザインの原則を取り入れ、生成されるコードがモバイル、タブレット、デスクトップのすべてのビューに最適化されることを保証します。この機能により、デザインを柔軟に考えることができ、作成物がどんな画面にもシームレスに適応することを確信できます。

カスタマイズもTailwind Genieの魅力の一つです。コードが生成された後、色やスペーシング、他のプロパティを簡単に調整して、ブランドの美学に合わせることができます。この柔軟性により、ツールの効率を活用しながら独自のデザインアイデンティティを維持することができます。さまざまなスタイルやレイアウトを試すことができ、長いコーディングプロセスにコミットすることへの恐れがなくなるのです。

Tailwind Genieは、個々の効率性を高めるだけでなく、チーム内でのコラボレーションとシナジーを促進します。デザイナーはコンポーネントを迅速に生成し、開発者と共有することで、引き渡しプロセスを円滑にします。この協力の精神は誤解を減らし、プロジェクトの目標に全員が一致していることを保証し、より統一感のある洗練された最終製品を生み出します。

急速に変化するデジタル環境では、先を行くことが重要です。Tailwind Genieは、最先端のテクノロジーを活用してワークフローを向上させる賢いデザイナーとしての立場を確立します。このツールを取り入れることで、あなたは業界のトレンドに追いつくだけでなく、それを設定することになります。卓越したデザインを提供できるだけでなく、Tailwind Genieが煩雑な作業から解放してくれることで、プロセスをより楽しむことができるようになるでしょう。

結論として、Tailwind Genieは単なるツールではなく、ウェブデザインのアプローチを再定義する変革的な体験です。その直感的な機能とAI駆動の能力により、ユーザーはスマートに作業し、効果的にコラボレーションし、クリエイティビティを解き放つことができます。Tailwind Genieをデザインツールキットに取り入れることで、生産性を向上させるだけでなく、デザインゲームを新たな高みへと引き上げることができます。Tailwind Genieの魔法を受け入れ、今すぐあなたのクリエイティビティの可能性を解き放ちましょう！

https://tailwindgenie.com/
Gitでコミットハッシュを確認し、コミットをステージングに戻す方法

## アジェンダ
Gitでコミットした変更を再度ステージングに戻したい場合について簡単にまとめます。

## やり方
Gitでコミットした変更を再度ステージングに戻したい場合、`git reset --soft` コマンドを使います。まずは、コミットハッシュを確認して、その後ステージングに戻すまでの流れを詳しく説明します。

### 1. コミットハッシュを確認する

まず、コミットハッシュを取得する必要があります。これには `git log` コマンドを使用します。

```sh
git log
```

**git log コマンドの出力例**

```sh
commit 1a2b3c4d5e6f7g8h9i0jklmnopqrstuvwxyz
Author: Your Name <you@example.com>
Date:   Thu Oct 5 14:52:02 2023 +0900

    Your commit message here
```

- commit ハッシュ: 各コミットには一意のハッシュが割り当てられます。このハッシュは、過去のコミットを参照するために使います。
- Author: コミットを行ったユーザー情報。
- Date: コミットが行われた日付と時間。
- Commit Message: コミット時に入力された説明メッセージ。

### 2. git reset --soft コマンドでコミットをステージングに戻す

コミットハッシュが確認できたら、そのハッシュを使ってステージングエリアに戻します。

#### 最新のコミットをステージングに戻す場合:

直前のコミットをステージングエリアに戻すには、以下のコマンドを使います。

```sh
git reset --soft HEAD^
```

HEAD^ は直前のコミットを指します。このコマンドを実行すると、直前のコミットがなかったことになり、その内容はステージングエリアに戻ります。

#### 特定のコミットをステージングに戻す場合:

特定のコミットをステージングエリアに戻すには、先ほど確認したコミットハッシュを使います。ハッシュの先頭数文字を指定すれば、特定できます。

```sh
git reset --soft <commit_hash>
```

例: ハッシュが 1a2b3c4d で始まる場合

```sh
git reset --soft 1a2b3c4
```

これでそのコミットの変更内容がステージングエリアに戻されます。

### 3. ステージング状態の確認

変更がステージングエリアに戻ったかどうかは、git status コマンドで確認できます。

```sh
git status
```

このコマンドを実行すると、ステージングされているファイルが表示されます。

## まとめ
1.	`git log` コマンドでコミットハッシュを確認する。
2.	`git reset --soft <commit_hash>` を使って特定のコミットをステージングエリアに戻す。
3.	`git status` でステージング状態を確認する。

この方法を使えば、過去のコミットを元に戻し、再度ステージングエリアで調整することができます。

## 参考
- [[Git]コミットの取り消し、打ち消し、上書き #GitHub - Qiita](https://qiita.com/shuntaro_tamura/items/06281261d893acf049ed)
OAIとは(AWS CloudFront)

CloudFrontにおける、認証済みリクエストをS3オリジンに送信するための方法。
Origin Access Identityの略。

AWSではOAC(OriginAccessControl)を推奨している。
理由は以下の通り。


https://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/private-content-restricting-access-to-s3.html#:~:text=%E3%81%99%E3%81%B9%E3%81%A6%E3%81%AE%20AWS,%E3%81%A8%20DELETE
> OAC は以下をサポートしているため、OAC の使用をお勧めします。
> ・ すべての AWS リージョンのすべての Amazon S3 バケット (2022 年 12 月以降に開始されたオプトインリージョンを含む)
> ・ AWS KMS による Amazon S3 サーバー側の暗号化 (SSE-KMS)
> ・ Amazon S3 に対する動的なリクエスト (PUT と DELETE)
ChatGPTによるリアルタイムテキスト化　問い合わせ窓口の利用

こんにちは、小磯と申します。
今回はChatGPTを業務で利用する、問い合わせ窓口側について纏めようと思います。

#### 問い合わせ窓口での利用
会話を自動でテキスト化することで、これまで一から手入力していた作業の負荷を大幅に軽減することが可能。
コンタクトセンターにおいて分析や応対品質向上のためのツール。

### 1.問い合わせ窓口の利用
ツールを利用する場合、以下2パターンを利用する予定です。
※メーカーや利用用途により、パターンが増えます。
①オペレータ向け
②スーパーバイザー/マネージャー向け

### 2.利用者毎の項目についての詳細
利用者の立ち位置により、利用可能なサービスが変わります。
サービスの詳細は以下になります。
#### ①オペレータ向け
 - 通話内容のテキスト化
→お客様の通話内容をリアルタイムでテキスト化。 
 - 質問に対する適切なFAQのレコメンド
→通話中、音声認識結果からキーワードを自動抽出し、質問に関連するナレッジをオペレーターに参照します。
 - 重要事項の自動チェック
→説明しなくてはならない「重要事項」の一覧をオペレーターに表示し、発話内容に応じて自動でチェックします。 
 - スーパーバイザーへの支援依頼・チャット
→困ったときに、ワンクリックでスーパーバイザーへ支援依頼ができます。 
 - 過去の通話内容の確認
→音声やテキストで過去の通話内容を確認可能。通話かぶり、無音箇所、支援依頼などを効率的にチェックして、アフターコールワークや自己啓発に活かせます。
 - 通話内容の要約
→通話終了後に通話内容の要約文を生成。文字数の指定や項目ごとの整理など、複数の設定や選択が可能。

#### ②スーパーバイザー/マネージャー向け
 - リアルタイムの通話モニタリング
→オペレーターの通話内容をリアルタイムでテキスト化します。トラブルになりそうなNGワードも速やかに検知します。
 - オペレーターの自動評価/スコアリング
→オペレーターの応対品質評価項目の一部を自動計測し可視化します。
 - リアルタイムの感情認識
→お客様とオペレーターの感情をリアルタイムで可視化、アラート通知します。
 - コーチング機能
→システム内で目標を設定し、目標に合わせた応対評価を実施。コーチング内容や振り返り結果を記録できます。


### まとめ
問い合わせ時間の短縮により、お客様の保留時間が短くなりクレームの軽減に繋がります。
クレーム対応についても支援により、ストレス軽減にも繋がります。
クレーム対応でオペレータのメンタルサポートも、素早く対応ができると思います。

以上、小磯でした。
Streamlitで作るシンプルなMBTI診断アプリ開発記録

## はじめに
今回は、Streamlitを使ってシンプルなMBTI診断アプリを作成したので、その制作過程を記録してみようと思います。

## 使用技術
**Streamlit**: シンプルなWebアプリをサクッと作れるフレームワーク。フロントエンドを意識せずにアプリケーションを開発できるのが強みです。
**Python**: 全体のロジックやデータ処理部分はPythonで書いています。

## 実装のステップ
### 1. 基本的なロジックの設計
まず、MBTI診断の基本的な仕組みを簡単にまとめました。質問は「外向的か内向的か」「感覚か直感か」などの4つの項目で構成されており、それぞれの選択肢から最終的なタイプ（例えば "INTJ"）が決まります。ちなみに僕はENFJです。

ロジックは簡単で、以下のように各質問の結果を文字列に組み合わせていく形です。

```python
q1 = 'I' # 内向的なら"I"
q2 = 'N' # 直感型なら"N"
q3 = 'T' # 思考型なら"T"
q4 = 'J' # 判断型なら"J"

mbti = q1 + q2 + q3 + q4
```

### 2. Streamlitを使ったUI作成
Streamlitのradioコンポーネントを使って、ユーザーが4つの質問に答えられるようにしました。このとき、選択肢がそのままタイプの略称（I、E、N、Sなど）になるので、5文字目（q1[5]）を利用して選択された文字を取得する工夫を入れました。

```python
q1 = st.radio('あなたはどちらですか？', ('外向的 (E)', '内向的 (I)'))
q2 = st.radio('情報をどのように得ることが多いですか？', ('感覚型 (S)', '直感型 (N)'))
q3 = st.radio('意思決定はどのように行いますか？', ('思考型 (T)', '感情型 (F)'))
q4 = st.radio('生活の進め方は？', ('判断型 (J)', '柔軟型 (P)'))
```

### 3. MBTIによる結果の出力
こちらのタイプごとの説明をお借りし、タイプ別で結果が出せるようにしました。

https://www.16personalities.com/ja/%E6%80%A7%E6%A0%BC%E3%82%BF%E3%82%A4%E3%83%97


## つまずいた点
一番引っかかったのは、選択肢から直接MBTIのタイプを生成する部分です。radioで選択肢を表示した後、その選択肢の5文字目を使ってタイプを決定するロジックは、最初うまくいきませんでした。

**解決策**としては、選択肢に対応する文字を直接扱うか、radioの戻り値をそのまま使う方法に変更しました。最終的に、リファクタリングして直接文字列を結合する形に変更しました。

## 完成品
こちらが完成したアプリです！

https://mbti-checker.streamlit.app/

[ソースコード](https://github.com/kpab/stream_mbti)も置いておきます

## まとめ
今回の制作で感じたのは、Streamlitの素晴らしさです。Webアプリの開発が短時間で完了し、特にフロントエンドの実装に煩わされることなくロジックに集中できました。また、ユーザーが直接インタラクションできるUIを簡単に実装できる点も非常に便利でした。
短期間で楽しく制作できたので、次回はもう少し複雑な診断ロジックを組み込んだアプリに挑戦してみたいと思います！
Gitでpushが終わらない時はセキュリティソフトを疑え！！！！！！

# 背景
ワイ大学４年生なんだけど研究室のダチが

ダチ「GitのPushができねぇ！設定はできているのになんでや!?!?!?」
ワイ「おーん？どうした？？見てみようか？」

ってなった感じ

# 状況
コミットしたファイルを
```
git push origin main
```
こんな感じでPushしようとして（ログはあくまでも例）

```
Enumerating objects: 120, done.
Counting objects: 100% (120/120), done.
Delta compression using up to 8 threads
Compressing objects: 100% (120/120), done.
Writing objects: 100% (120/120), 670.28 MiB | 762.00 KiB/s, done.
Total 120(delta 1), reused 0 (delta 0), pack-reused 0
```

正常にPushできたかと・・・思えばここで止まるんよね

# 一般的な解決方法
## ターミナル一旦閉じて再度Pushする
困った時は再起動！これに尽きるね。

・・がこんなので治るわけないだろ。

## バッファサイズを上げる
```
git config --global http.postBuffer 157286400
```
ワイ「Unityのプロジェクトフォルダでサイズがデカいからバッファを上げたらいけるんじゃねぇの？」
と思い、バッファサイズを上げ再度pushする。
そうしたら9割の人は治るが・・・・・これでもいかない・・・

ワイ「は？？？？？？？」



# 結論
ワイ「ネットワークも変えたし、バッファサイズもあげたし、Githubの設定関連は問題ないな・・・・？うん・・・？なんだこのステータスバーにあるアイコンは？？？？？？？」

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1657253/cee703a3-d82a-df4d-9d56-df15587e1fa0.png)


ワイ「セキュリティソフトやんけ。ワンチャンこれ保護オフにしたらどうなるかな？」

```
Enumerating objects: 120, done.
Counting objects: 100% (120/120), done.
Delta compression using up to 8 threads
Compressing objects: 100% (120/120), done.
Writing objects: 100% (120/120), 670.28 MiB | 762.00 KiB/s, done.
Total 120 (delta 1), reused 0 (delta 0), pack-reused 0
remote: Resolving deltas: 100% (1/1), done.
To https://github.com/your-repository.git
 * [new branch]      your-branch -> your-branch
```


ワイ「や　っ　た　ぜ（長年大人のサイトを見てきた経験が役立った）」


というわけでたかがセキュリティソフトのためだけに時間食われました。マジで辛い。
（ちな本人曰くセキュリティソフトが鬱陶しいらしいので無効化してWindowsdefenderに切り替えておいた）
【Vue3】propsの書き方

# コード
```vue: App.vue
<template>
  <TitleTemplate :main-title="タイトル" />
</template>

<script setup>
import TitleTemplate from 'TitleTemplate.vue'
</script>
```

```vue: TitleTemplate.vue
<template>
  <p>{{ mainTitle + subTitle }}</p>
</template>

<script setup>
defineProps({
  // 必須の場合
  mainTitle: {
    type: String,
    required: true,
  },
  // デフォルト値を設定する場合
  subTitle: {
    type: String,
    default: 'デフォルト文言'
  },
})
</script>
```

scriptでpropsを使用する場合は、変数に格納する。
```vue: 
<script setup>
const props = defineProps({
  title: {
    type: String,
    required: true,
  },
})

const test = props.title
</script>
```

# 参考
https://ja.vuejs.org/guide/components/props
PriorityQueueにtupleを追加したらTypeErrorが出る問題

beam searchしたくてギッハブからスターがたくさんついているやつを動かしているとたまに TypeError: '<' not supported between instances of 'BeamSearchNode' and 'BeamSearchNode' がでちゃう問題が発生しました。

参考にした実装↓

https://github.com/budzianowski/PyTorch-Beam-Search-Decoding


不定期に出るエラー（抜粋）
```
  File "/~~~~~~~~~~~~/beam.py", line 119, in beam_decode
    nodes.put((score, nn))
TypeError: '<' not supported between instances of 'BeamSearchNode' and 'BeamSearchNode'
```

nodesはqueue.PriorityQueueのインスタンスです(組み込み関数)。

ちょっと調べてみると、PriorityQueueにtupleを追加していくときに、まずtupleの一つ目の要素で比較して中身をソートしてくれますが、その要素が一致してしまってpriorityが付けられない場合は2つ目の要素で比較演算子を実行し、ソートするみたいです。
今回の場合、(scores, nn)を追加していて、たまたまscoreが一致したときにnn (BeamSearchNodeのインスタンス) 同士で比較演算子が実行されてしまい、このようなエラーが出ちゃったようです。

これを解決するために、scoreの後ろに他のノードと被らないスコアを入れました。
自分で分かりやすいようにイジっているので上記のギッハブの実装とはちょっと違いますが、new nodeを追加する所は以下のように変更しました。


```python
node = BeamSearchNode(encoder_out=encoder_output,
                        previousNode=n,
                        decoder_input=next_decoder_input,
                        logProb=n.logp + log_p,
                        length=n.leng + 1)
score = -node.eval()
count += 1
nextnodes.append((score, count, node))

for i in range(len(nextnodes)):
    score, count, nn = nextnodes[i]
    nodes.put((score, count, nn))
```

\
BeamSearchNodeの中身↓

```python
class BeamSearchNode(object):
    def __init__(self, previousNode, decoder_input, logProb, length):
        self.prevNode = previousNode
        self.dec_in = decoder_input
        self.logp = logProb
        self.leng = length

    def eval(self, alpha=0.6):
        return self.logp / (((5 + self.leng) / (5 + 1)) ** alpha)
```

Transformerなのでノードに対してtokenではなく推論中のsentence全体を渡している点がギッハブの実装と異なっています。
encoderのアウトプット(memory)は外から渡してます。
あとはevalで計算するスコアにGNMTと同じペナルティ項を追加しています。
Oracle CloudのAlways Free VMへNode-REDをインストールする

# はじめに

https://www.oracle.com/jp/cloud/

## オリジナルの記事

http://note.pandako.com/2021/12/oraclecloud-node-red.html

↓ (下記を参照)

https://blogs.oracle.com/developers/post/installing-node-red-in-an-always-free-vm-on-oracle-cloud

## サインアップしてVMを作成しSSHで外部から接続するまで

https://yasurok2.wordpress.com/2020/10/17/node-red-on-free-vps-by-oracle/

### ネットワークアクセスの設定 (セキュリティ対策)

ネットワーキング
→仮想クラウド・ネットワーク
→セキュリティ・リストの詳細
→イングレス・ルール

## アップデート

```bash
sudo apt update
sudo apt upgrade
```

## dockerのインストール

https://docs.docker.com/engine/install/ubuntu/

## Node-REDの設定ファイル

```bash
mkdir .node-red
chmod 777 .node-red
```

## Node-REDをDockerで動かす
https://qiita.com/kitazaki/items/939038f77ba72616e73d

### dokcerの動作状態の確認

```bash
sudo docker ps -a
```

#### 正常な場合の出力例

```bash
CONTAINER ID   IMAGE                     COMMAND             CREATED         STATUS                   PORTS                                                                                NAMES
e717b4a0ccd0   nodered/node-red:latest   "./entrypoint.sh"   9 minutes ago   Up 4 minutes (healthy)   0.0.0.0:1883->1883/tcp, :::1883->1883/tcp, 0.0.0.0:80->1880/tcp, [::]:80->1880/tcp   funny_jones
```

#### 異常な場合の出力例

```bash
CONTAINER ID   IMAGE                     COMMAND             CREATED         STATUS                    PORTS     NAMES
e717b4a0ccd0   nodered/node-red:latest   "./entrypoint.sh"   4 minutes ago   Exited (1) 1 second ago             funny_jones
```


### dockerのコンテナの起動

"コンテナID"は上の出力例では、e717b4a0ccd0 のこと。

```bash
sudo docker start "コンテナID"
```

### dockerのコンテナの停止

```bash
sudo docker stop "コンテナID"
```

### dockerのコンテナのログ確認

```bash
sudo docker logs "コンテナID"
```

## Node-REDのベーシック認証機能を有効にする (セキュリティ対策)

https://nodered.jp/docs/user-guide/runtime/securing-node-red

### エディタをインストール

```bash
sudo apt install nano
```

### settings.jsを編集する

```bash
cd .node-red
nano settings.js
```

### Node-REDのログインパスワードの生成

Node-REDのコンテナ環境へログインし、ログインパスワードを生成します。

```bash
sudo docker exec -it "コンテナID" /bin/bash
node -e "console.log(require('bcryptjs').hashSync(process.argv[1], 8));" <パスワード>
<ハッシュ化されたパスワード文字列>
exit
```
Flask + SQLAlchemyで作る「キャリア・クエスト」- 仮想キャリア体験プラットフォームの全貌

## はじめに

こんにちは、たいしです。この記事では、私が開発した「キャリア・クエスト」という仮想キャリア体験プラットフォームの技術的な側面について、全体像を紹介します。

「キャリア・クエスト」は、ユーザーが仮想世界で様々なキャリアパスを体験し、自己分析や未来の自分とのAI対話を通じて、最適なキャリアを探索できるWebアプリケーションです。

この記事は、プロジェクトの詳細を3つのパートに分けて解説するシリーズの概要となります。各パートの内容と直接リンクは以下の通りです：

- [Part 1: プロジェクト概要とバックエンド基盤](#part-1-プロジェクト概要とバックエンド基盤)
- [Part 2: 主要機能の実装とフロントエンド](#part-2-主要機能の実装とフロントエンド)
- [Part 3: AI機能と将来展望](#part-3-ai機能と将来展望)

## プロジェクト概要

「キャリア・クエスト」の主な特徴は以下の通りです：

1. 多様な職業や人生の選択肢をAIでシミュレーション
2. 詳細な自己分析ツール
3. 未来の自分とのAI対話機能
4. データ分析と可視化機能

使用技術：
- バックエンド: Flask (Python)
- データベース: SQLite (SQLAlchemy ORM)
- フロントエンド: HTML, CSS, JavaScript
- AI/ML: scikit-learn, TensorFlow

## Part 1: プロジェクト概要とバックエンド基盤

[Part 1の記事リンク](https://qiita.com/sekainotaishi/items/f89a88fdb8bd52246eeb)

Part 1では、プロジェクトの基盤となる要素について解説しています：

1. プロジェクトの詳細な概要
2. 技術スタックの選択理由
3. アプリケーションのアーキテクチャ設計
4. データベース設計と実装の詳細

主なポイント：
- Flaskを選んだ理由（軽量性、柔軟性、拡張性）
- SQLAlchemyによるORMの利点
- スケーラブルなアーキテクチャの設計方法
- 効率的なデータベーススキーマの構築

## Part 2: 主要機能の実装とフロントエンド

[Part 2の記事リンク](https://qiita.com/sekainotaishi/items/4c700be82a7163ba4cc0)

Part 2では、アプリケーションの核となる機能の実装について深掘りしています：

1. ユーザー認証システムの構築
2. キャリアシミュレーションロジックの実装
3. フロントエンドの設計と実装
4. 開発中に直面した課題とその解決策

主なポイント：
- Flask-Loginを使用した安全な認証システム
- 複雑なキャリアシミュレーションロジックの設計
- JavaScriptを使用したインタラクティブなUI
- パフォーマンス最適化とスケーラビリティの確保

## Part 3: AI機能と将来展望

[Part 3の記事リンク](https://qiita.com/sekainotaishi/items/78609227543384feea84)

Part 3では、プロジェクトの高度な機能と今後の展望について説明しています：

1. AIを活用したキャリア提案機能の実装
2. データ分析と可視化機能の詳細
3. 将来の拡張計画と予想される技術的課題
4. プロジェクトを通じて得られた教訓

主なポイント：
- 機械学習モデルを使用したパーソナライズされた推薦システム
- D3.jsを使用したデータの視覚化
- AR/VR、ブロックチェーンなど、将来の技術統合の可能性
- 大規模Webアプリケーション開発から得られた洞察

## まとめ

「キャリア・クエスト」プロジェクトは、最新のWeb技術とAIを組み合わせて、ユーザーに革新的なキャリア探索体験を提供することを目指しています。このシリーズを通じて、複雑なWebアプリケーションの設計から実装、そして継続的な改善のプロセスについて、詳細な洞察を得ることができます。

各パートでは、技術的な側面だけでなく、実際の開発プロセスで直面した課題や、その解決策についても詳しく解説しています。Web開発やキャリアテック（Career Tech）に興味がある方、あるいは同様のプロジェクトを計画している方にとって、有益な情報源となれば幸いです。

ご質問やフィードバックがありましたら、各記事のコメント欄やtee.you0912@gmail.comでお気軽にお寄せください。
【React】React初心者がuseStateの基本を振り返ってみた

こんにちは。あがさんです！！

今回はReactでよく登場する``useState``について解説していきます。

## Reactって何？
Reactは、Facebook（現Meta）が開発したユーザーインターフェース (UI) を構築するためのJavaScriptライブラリです。主にシングルページアプリケーション (SPA) の開発で使用され、複雑なUIを効率的に管理するためのコンポーネントベースのアプローチを提供します。

## useState
useStateは、ReactのHook (便利機能みたいなもの) の一つで、関数コンポーネントで状態（state）を管理するために使います。useStateをインポートし、コンポーネント内に定義することで、管理したい値の更新を手軽に行うことができます。これにより、ユーザーの操作に応じて動的にUIが変わるようなアプリケーションを簡単に作ることができます。

# useState の特徴
### 実際にカウントアプリを作ってみました。
```page.js

import { useState } from "react"; // React Hooksをインポート

export default function Home() {
  const [count, setCount] = useState(0); // トップレベルで定義する。
 //const [現在の状態の値, 状態を更新するための関数] = useState(状態の初期値);
  console.log(count) //コンソールでcountを確認
  return (
    <div className="flex justify-center items-center min-h-screen bg-blue-50">
      <div className="text-center p-8 bg-white shadow-lg rounded-lg">
        <h1 className="text-4xl font-bold mb-6 text-blue-600">
          Hello useState!!
        </h1>
        <div className="flex flex-col space-y-4 mt-12">
          <button
            onClick={() => setCount(count + 1)}
            // クリックされる度にsetCountが+1される
            className="px-6 py-2 bg-blue-500 text-white font-semibold rounded-md shadow hover:bg-blue-600 focus:outline-none focus:ring-2 focus:ring-blue-400"
          >
            {count} 回クリックされました。
          </button>
        </div>
      </div>
    </div>
  );
```

下記がカウントアップ画面。初期値の０回からスタート

![useState.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3775546/c6490f01-1cca-a04b-b08a-52b79420b201.gif)

ボタンを押す毎にカウントアップされていきます。


### useStateの特徴① 状態を更新する
useState フックで提供される ``setCount`` 関数を使って、状態を更新できます。この関数は呼び出されるとReactがその状態を再計算し、UIの再レンダリングが必要かどうかを判断します。今回のアプリはボタンにイベントハンドラーである``onClick``を持たせて、クリックするたび``setCount``が+1ずつ増えていくようになっています。



### useStateの特徴② 再レンダリングを行う
``useState`` を使って状態を更新すると、そのコンポーネントが再レンダリングされます。画面のリロードをせずに``count``のカウント数を更新することが可能になります。

## まとめ
いかがでしたでしょうか。
今まで学習動画に倣ってuseStateを使っていましたが、
基本的な仕組みが理解できていなかったと感じました。

useStateは他にも様々な記述方法や使い方があるようなので
手を動かしながら少しずつ身につけていきたいと思います。

また次回も頑張って投稿します。
最後まで見ていただきありがとうございました!!

*~Qiitaの歴史がまた1ページ~*


関連リンク：

- [React](https://ja.react.dev/)
【react-router-dom】You cannot render a <Router> inside another <Router>. You should never have more than one in your app.の解決方法

# はじめに
Reactアプリケーションで`react-router-dom`を設定しているときに、以下のエラーメッセージが表示されました。この記事では、このエラーの原因と解決方法を紹介します。

```
You cannot render a <Router> inside another <Router>. You should never have more than one in your app.
```

:::note warn
***この記事は<font color="Red">個人的なアウトプット</font>を目的として作成したものです。そのため、誤った情報や不足している内容が含まれている可能性があります。もし間違いや気になる点がございましたら、ぜひご指摘いただけますと幸いです***。
:::


# 原因
```App.tsx
import { BrowserRouter } from "react-router-dom";
import "./App.css";
import Router from "./routes/Router";

function App() {
  return (
    <BrowserRouter>
      <Router />
    </BrowserRouter>
  );
}

export default App;
```
`App.tsx` をこのように記述しておりました。`<BrowserRouter>`の記述の位置が問題でした。

# 解決方法

```App.tsx
import "./App.css";
import Router from "./routes/Router";

function App() {
  return <Router />;
}

export default App;
```

```main.tsx
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import { BrowserRouter } from "react-router-dom";

import App from "./App.tsx";
import "./index.css";

createRoot(document.getElementById("root")!).render(
  <StrictMode>
    <BrowserRouter>
      <App />
    </BrowserRouter>
  </StrictMode>
);
```
`App.tsx` から `<BrowserRouter>` を取り除き、`main.tsx`で最上位の要素として一度だけ`<BrowserRouter>`を配置するように修正しました。これにより、アプリケーション全体で一貫したルーティングの管理ができるようになります。

当初、`<BrowserRouter>`は`<Routes>`を囲むものだと認識していましたが、実際にはアプリケーションの最上位で使用する必要があります。Viteで制作する場合は、`main.tsx`に配置するのが正しい方法です。

https://reffect.co.jp/react/react-router-6#i-4

# 終わりに
React Routerを使用する際、アプリケーション全体で一度だけ`<BrowserRouter>`を使用することが重要です。同様のエラーが発生した場合は、今回の解決方法を参考にしてください。
[Delphi][小ネタ] TThread を継承しないで簡単にスレッドを使いたい

# TThread を使った並列処理

TThread は Delphi 上でプラットフォームの Thread を抽象化したクラスです。

TThread を使えば簡単に並列処理を実装できますが、正統なやり方だとちょっと面倒…
記述量を減らしつつも、見やすくなる方法を紹介します。

## TThread を継承する（正統な方法）

TThread を継承してオリジナルの Thread を作れば、独自のスレッドを作成できます。

例えば ↓ こんな感じです。

```delphi
type
  TSampleThread = class(TThread)
  protected
    procedure Execute; override;
  end;

  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
  private
    FThread: TSampleThread;
  end;

implementation

procedure TSampleThread.Execute;
begin
  while not Terminated do
  begin
    // 何か時間の掛かる処理
  end;
end;

procedure TForm1.FormCreate;
begin
  FTherad = TSmapleThread.Create;
  FTherad.FreeOnTerminate := True;
  FTherad.Start;
end;
```

クラス定義とか沢山かかないといけなくて面倒い…

## CreateAnonymousThread を使う

TThread にはクラスを定義しなくても良い匿名メソッドを定義できる CreateAnonymousThread というメソッドがあります。
例えば ↓ のように使えます。便利～

```delphi
type
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
  private
    FThread: TThread;
  end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  // Thread 内で自分にアクセスするため変数を定義する
  // この変数はローカル変数だが削除されない (下記 note 参照)
  var Thread = TThread.CreateAnonymousThread(
    procedure
    begin
      while not Thread.CheckTerminated do
      begin
        // 何か時間の掛かる処理
      end;
    end
  );

  FThread := Thread;
  FTherad.FreeOnTerminate := True;
  FTherad.Start;
end;
```

:::note info
ローカル変数の生存期間が延びる件については下記参照
[無名メソッド変数のバインディング](https://docwiki.embarcadero.com/RADStudio/ja/Delphi_%E3%81%A7%E3%81%AE%E7%84%A1%E5%90%8D%E3%83%A1%E3%82%BD%E3%83%83%E3%83%89#.E7.84.A1.E5.90.8D.E3.83.A1.E3.82.BD.E3.83.83.E3.83.89.E5.A4.89.E6.95.B0.E3.81.AE.E3.83.90.E3.82.A4.E3.83.B3.E3.83.87.E3.82.A3.E3.83.B3.E3.82.B0)
:::


でもでも、CreateAnonymousThread の中に直接コードを書いたら、何十行とか何百行とかになったとき見通しの悪いコードになりそう（FormCreate が何百行にもなってしまう…）

## 別クラスで定義する

CreateAnonymousThread の手軽さと、TTherad 継承コードの読みやすさ、どっちも欲しい！

```delphi
type
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
  private var
    FThread: TThread;
  private
    procedure ThreadMain;
  end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  FThread := TThread.CreateAnonymousThread(
    procedure
    begin
      ThreadMain; // TForm1 に定義してあるメソッドを呼ぶだけにする
    end
  );
  FThread.Start;
end;

// Thread のメイン処理を TForm1 側に記述する
procedure TForm1.ThreaMain;
begin
  FThread.FreeOnTerminate := True;
  while not FThread.Terminated do
  begin
    // 何か時間の掛かる処理
  end;
end;
```

こんな風に TForm1 側に処理を逃がしてやれば、CreateAnonymousThread の中身を肥大化させずにコードを書けます。
しかも、TForm1 側の変数やプロパティにもアクセス自在！
（ただし、GUI 部分はメインスレッドで動かす必要があったり、別の場所からアクセスがある変数などでは排他制御が必要）

便利～

# まとめ
Thread を操りたいけど継承して作るほどでもないな～継承して作るの面倒だな～っていうとき、使ってみてください。
(SSD1327)M5NanoC6、時計で遊ぶ。


x 過去ログ見よ!!
x 時間合わせは、別
x 業務連絡　マルチメディア飲み会あるよ(絶滅メディア博物館)　なんのこと?

結果

![o_coq498.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/2b4468f1-0dc3-c465-374a-a3e723fcbd3e.jpeg)


プログラム


```c++


//SSD1327_DS1307_M5NanoC6_1


//ヘッダーファイル
#include <Arduino.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1327.h>

//定義
#define SCREEN_WIDTH  128    // OLED display width, in pixels
#define SCREEN_HEIGHT 96    // OLED display height, in pixels
#define OLED_RESET     -1   // Reset pin # (or -1 if sharing Arduino reset pin)
#define SCREEN_ADDRESS 0x3C ///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32
Adafruit_SSD1327 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

#define setCursorAA(AA,BB) setCursor(AA+16,BB)

// デバイスアドレス(スレーブ) DS1307
#define ADDR    0x68    // 2進数 1101000


//初期化
void setup() {

  // I2Cアドレスは使用するディスプレイに合わせて変更する
  display.begin(SCREEN_ADDRESS);

}//setup


//メインループ
void loop() {

  // 画面表示をクリア
  display.clearDisplay();

  // テキストサイズを設定
  display.setTextSize(2);
  // テキスト色を設定
  display.setTextColor(SSD1327_WHITE);
  // テキストの開始位置を設定
  display.setCursorAA(0, 16);

  //時計の処理 ↓ここから
  // レジスタのアドレスを先頭にする
  Wire.beginTransmission(ADDR);
  Wire.write(0x00);
  Wire.endTransmission();
  delay(1);

  // I2Cスレーブに8byteのレジスタデータを要求する
  Wire.requestFrom(ADDR, 8);

  // 8byteのデータを取得する
  char data_read[16] = {0x88, 0x88, 0x88}; //データバッファー
  int ii = 0;
  while (Wire.available())  {   // 要求より短いデータが来る可能性あり
    data_read[ii++] = Wire.read();       // 1バイトを受信
  }//while
  delay(1);

  //表示変換する パック二進化十進を文字列にする
  char cn1[16];  //桁
  cn1[0] = '0' + (data_read[2] >> 4);  //0 時 上位
  cn1[1] = '0' + (data_read[2] & 0xf); //1 時 下位
  cn1[2] = ':';
  cn1[3] = '0' + (data_read[1] >> 4);  //2 分 上位
  cn1[4] = '0' + (data_read[1] & 0xf); //3 分 下位
  cn1[5] = ':';
  cn1[6] = '0' + (data_read[0] >> 4);  //4 秒 上位
  cn1[7] = '0' + (data_read[0] & 0xf); //5 秒 下位
  cn1[8] = 0;
  //時計の処理　↑ここまで
  
  display.println(cn1); //時刻を表示する

  // 描画バッファの内容を画面に表示
  display.display();

  delay(1000); //1秒待つ

}//loop


```
【Python 通知用】LINE Notify の代替サービス【Discord】

## 概要
**LINE Notify** が2025年3月31日をもってサービス終了することが発表されました。
プログラムの実行状況通知などに利用していた方も多いと思われます。

https://developers.line.biz/ja/news/2024/10/07/line-notify-will-be-discontinued/

本記事では、**LINE Notify** の代替サービスとして **Discord** に Python から通知を送る手順を説明します。

## 1. Discord の Webhook URL をコピーする
1. Discord で Python 通知用のテキストチャンネルを新規作成する
1. 新規作成したチャンネルの歯車マーク `チャンネルの編集` をクリックする
1. `連携サービス` をクリックする
1. `ウェブフックを作成` をクリックする
1. 作成したウェブフックの `お名前` を適当な名前に編集する（通知がきたときに表示される名前）
1. `ウェブフック URL をコピー` をクリックして URL をコピーする

## 2. Python から通知を送る
1. 以下のコードを実行する

```py
import requests

url = "<コピーしたウェブフック URL>"

message = "<送信したい内容>"
data = {"content": message}

try:
    requests.post(url, data=data)
except Exception as e:
    print(f"エラー：{e}")
```
paizaラーニング問題集「【マップの扱い 3】マップの判定・縦横斜め」を解いてみた

https://paiza.jp/works/mondai/b_rank_new_level_up_problems/b_rank_new_level_up_problems__get_row_col

▼考え方

ポイントになる考え方1.～6.を以下に示します。

1.マップの書き換えの処理は関数にします。同じコードを何度も記述することを防ぐためです。

2.マップの1番上の行から1行ずつ処理をします。

3.与えられた座標のマス(y,x)と同じ行(縦:y)の横のマスはすべて、マップの書き換えの処理を行います。

4.すべての行において、与えられた座標のマス(y,x)と同じ列(横:x)のマスは、マップの書き換えの処理を行います。

5.すべての行において、与えられた座標のマス(y,x)の左斜め上(y-a,x-a)と右斜め下(y+a,x+a)に該当するマスは、マップの書き換えの処理を行います。条件として、マップの横の範囲(0～W-1)を超えないマスに対して処理を行います。

6.すべての行において、与えられた座標のマス(y,x)の右斜め上(y-a,x+a)と左斜め下(y+a,x-a)に該当するマスは、マップの書き換えの処理を行います。条件としては、考え方5.と同様です。

▼コード
```py

# 横方向 x,W,i
# 縦方向 y,H,j

########## 処理0(準備) インプット,リスト,関数定義など ###########

# 考え方1.
def kakikae(y,x):
    
    if S[y][x] == ".":
        S[y][x] = "#"
    else:
        S[y][x] = "."

H,W = map(int,input().split())

S = [[0 for i in range(W)] for j in range(H)]

for j in range(H):
    S[j] = list(input())

y,x = map(int,input().split())

########## 処理1 マップの書き換え、マップの出力 ##########

# 考え方2.
for j in range(H):

    # 考え方3.
    if j == y:
        for i in range(W):
            kakikae(j,i)

    else:
        # 考え方4.
        kakikae(j,x)
        
        # 考え方5.
        if x-(y-j) >= 0 and x-(y-j) <= W-1:
            kakikae(j,x-(y-j))

        # 考え方6.
        if x+(y-j) >= 0 and x+(y-j) <= W-1:
            kakikae(j,x+(y-j))

for j in range(H):
    print(*S[j],sep='')
```