OmniAICreator/Qiita-1.07M huggingface dataset:
TryHackMeのOpenVPN接続に2日殺されたので辿り着いた誰かのためへ

## 環境
OS : kali linux
OpenVPN : 2.6.3
あなた : 日本語の文献は読み漁った人

※ 特になんでもいいと思います
## やること1
[ここ](https://tryhackme.com/access)のVPNServer : EU-Regular-3を1か2に変更する
3のサーバは壊れてるらしいです
## やること2
[ここ](https://tryhackme.com/access)でダウンロードしたファイルの中身をテキストエディタかなんかで開く
14,5,6,7行目くらいに
ciphers AES-256-CBC
とあるので
data-ciphers AES-256-CBC
に書き換える

保存して閉じる

## やること3
ターミナルからsudo openvpn Downloads/名前.ovpnを実行
（Desktop（ホーム画面）に置いてしまった方は cd Desktop を実行した後に sudo openvpn 名前.ovpn を実行してください）
しばらく待ってスクロールが止まったら接続に成功しているはずです。
Initialization Sequence Completedとなるはずらしいですが
ぼくはこれ↓で無事つながってました
SIGTERM[soft,exit-with-notification] received, process exiting

## 接続確認
[ここ](https://tryhackme.com/access)に戻って
OpenVPN Access Details
チェック✓2つとIPアドレスが出てたらOK

## マシンにつないでください
遊びたいroomでStart Machineボタンを押す
1分後くらいにIPアドレスが表示される
それをkali linux上のブラウザにコピペ
【PostgreSQL】テスト環境でのシーケンスの自動採番がリセットされない


## 発生した現象

RSpecでテスト実行後、普通はデータベースはリセットされてPKが1から採番されると思いますが、
何故かリセットされずテスト実行の度にPKがインクリメントしていくという現象が起きていました。

----

**[例]**
- 1回目のテストを実行し、Userのテストデータを5人分作成したらusersテーブルのidが1〜5まで生成される。
- 1回目を終え、2回目のテストを実行するとusersテーブルのidが6〜10が生成される。レコード自体は残っていない。

----
といった感じです。

別にバグやエラーというわけではないですが、気持ち悪かったので解消しようと思い
一応解決したので備忘録として残します。

## 環境
- Ruby 3.2.2
- Ruby on Rails 7.1.1
- PostgreSQL 15.3

docker composeで環境構築しています。

## 原因

結論、特定はできませんでした。
（わかる方いらっしゃればコメントいただけますと幸いです）

調べていてよく出てきたのは
「rails_helper.rbの`config.use_transactional_fixtures`がfalseになっているとデータベースがロールバックされないよ〜」
とかでしたが、データは消えているので違いそうでした。。

## 解決策

テーブルに対して`reset_pk_sequence!`を使えば、
見事テスト実行の度にシーケンスの自動採番が1から生成されるようになりました。

`before(:suite)`を指定することで、テストスイート実行の前に毎回実行されます。

ちなみに`reset_pk_sequence!`はDBがPostgreSQLの時だけ使えるようです。


```rb:spec/rails_helper.rb
RSpec.configure do |config|
###
  config.before(:suite) do
    ActiveRecord::Base.connection.tables.each do |table_name|
      ActiveRecord::Base.connection.reset_pk_sequence!(table_name)
    end
  end
###
end
```

## 参考記事

以下の記事で解決しました。
感謝です！！

https://kkawazoe.github.io/blog/2022/05/24/how-to-auto-seq-for-postgre-sql-with-rails/

https://blog.piyo.tech/posts/2018-08-22-fix-seed-dump-script/

https://apidock.com/rails/ActiveRecord/ConnectionAdapters/PostgreSQLAdapter/reset_pk_sequence%21
paloaltoの解析講座1：Wireshark

<!--
2023/11/11
-->
* paloalto解析講座
やってみたら、超便利そうで、自分に合ったカスタマイズのメモ
とても勉強になったし、正直リスペクトです。

https://unit42.paloaltonetworks.jp/unit42-customizing-wireshark-changing-column-display/

## Columnのカスタマイズ
* 完成のイメージ
httpとhttpsの通信で、ホスト名が表示されている状態。
時間は見やすい表示形式。
![screenshot.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/160736/5bd33119-dc39-ce82-43b8-940951c2c426.png)
表示するためのフィルターは以下で。
`http.host or tls.handshake.extensions_server_name`
<br>

* 設定の画面のイメージ
カラムのタイトルを右クリックして、`Column Preferences ・・・`を選択。
こんな感じになるように設定。
![screenshot 5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/160736/dfaa5016-d648-3137-57fc-d1d8b5155d17.png)
<br>

* 基本的な手順
`Edit` `Configuration Profiles`からプロファイルを追加
`Customized`などの名前をつける。
カラムのタイトルを右クリックして、`Column Preferences ・・・`を選択。

|Displayed|Title|Type|Fields|
|-|-|-|-|
| |No|Number||
|✔︎|Time|UTC date,as YYYY-MM-DD,and time||
|✔︎|Source|Source address||
|✔︎|S port|Source port||
|✔︎|Destination|Destination address||
|✔︎|D port|Destination port||
|✔︎|Host|Custom|http.host or tls.handshake.extensions_server_name|
|　　|Protocol|Protocol||
| |Length|Packet length(bytes)||
|✔︎|Info|Information||
<br>

* `S port` `D port`はカラム名を右クリックして、`Align Left`にチェック
<br>

* 時刻の表示
`View` `Time Display Format`を選択してそれぞれを選択する。
表示書式
`UTC Date and Time of Day(1970-01-01 01:02:03.1123456)` 
秒までの表示
`Seconds`
<br>  


* インポートする方法
`Edit` `Configuration Profiles`からプロファイルをインポート
<br>

* 以上です。


## 参考サイト
https://unit42.paloaltonetworks.jp/wireshark-workshop-videos/

https://www.freekb.net/Article?id=130
統計検定学習備忘録　⑤統計検定1級2022数理統計　大問3(1)(2)別解・別解説　ポアソン分布・ガウス分布に関する計算

普段より、自分のプログラミング等に関する質問に答えて下さっている皆様ありがとうございます。m( _ _)m　よろしければ統計検定の学習等にご利用ください。

<h2>問題文URL（統計数理　大問３（P８）を参照して下さい）

chrome-extension://efaidnbmnnnibpcajpcglclefindmkaj/https://static.toukei-kentei.jp/wp-content/uploads/20230112122939/202211grade1suri-20230112122939-20230112122939.pdf

<h1>大問3 (1)Poisson distribution（ポアソン分布）の平均・分散を定義に従ってゴリ押しで計算

<h3>下準備①：離散型確率密度関数に関する知識

https://drive.google.com/drive/u/0/folders/1k792Jv2EuZJ0tLUp5WV8HbMTDgcXC5rB

<h3>下準備②：Taylor級数展開に関する知識等

https://drive.google.com/drive/u/0/folders/1e_rHJ0OkO_pbfctMh-91VEuCMMUZsBxe

<h3>(1)ゴリ押し計算別解・別解説

https://drive.google.com/drive/u/0/folders/1P2jiISnRtN_1L_DrjKLMHOoibt45WsKU

<h3>Githubバージョン（中身は同じです）

https://github.com/thinking-weed/analysis-statics-memo/tree/main/Poisson_distribution

<h1>大問3 (2)Gaussian distribution（ガウス分布　※正規分布ではない）の平均・分散を定義に従ってゴリ押しで計算

<h3>下準備：Γ（ガンマ）関数に関する性質（＝命題）について

https://drive.google.com/drive/u/0/folders/1JW0SLvRSpZH7AoksnM0O8UyxBWRUpqN7

<h3>(2)ゴリ押し計算別解・別解説

https://drive.google.com/drive/u/0/folders/1ARi_BHPTeQ0L8bVDJISqHk7wgQkBpR4G

<h3>Githubバージョン（中身は同じです）

https://github.com/thinking-weed/analysis-statics-memo/tree/main/Gaussian_distribution
____
<h3>〇余談ですが・・・

基本、なんか数学勉強してて見たことない文字（または記号）がでてきたら、それは**大概ギリシャ文字（※大文字・小文字あります）かロシア語**です。※ Γ（ガンマ）もギリシャ文字

<h1>参考資料一覧（※全部の内容を自分も理解できているわけではないです。）

①統計検定1級公式問題集　実務教育出版　
　※過去問のページ　https://www.toukei-kentei.jp/prepare/kakomon/
②青チャートI＋A、Ⅱ＋B　数研出版
③理工系の微分積分学　吹田信之、新保経彦　共著　学術図書出版書
④線形代数入門　齋藤正彦　著　東京大学出版会
⑤定本　解析概論　高木貞治　著　岩波書店　
⑥数学シリーズ　数理統計学　改訂版　稲垣萱生　著　裳華房
⑦数学シリーズ　集合と位相　内田伏一　著　裳華房
⑧one point 推定と検定　鷲尾泰俊　著　共立出版
⑨電磁場とベクトル解析　深谷賢治　著　岩波書店
Cloud Storage の Cloud Pub/Sub 通知構成のペイロードとは

GCSのPub/Sub通知構成において、ペイロードが不明でしたので確認してみました。
# GCSのPub/Sub通知構成
GCSのバケットにあるオブジェクトに変更が発生した場合にCloud Pub/Subへ通知を送る機能となります。
・[Cloud Storage の Pub/Sub 通知の構成](https://cloud.google.com/storage/docs/reporting-changes?hl=ja#gcloud_2)
# 通知構成の取得
通知構成はバケットに対して設定します。
通知構成はオプションを使用せず作成した場合、デフォルトで以下のように設定されていることが確認できます。
通知条件となる[イベントタイプ](https://cloud.google.com/storage/docs/pubsub-notifications?hl=ja#events)はデフォルトでは4種類全てが対象となる動きとなります。
```
---
Bucket URL: gs://<バケット名>/
Notification Configuration:
  etag: '1'
  id: '1'
  kind: storage#notification
  payload_format: JSON_API_V1
  selfLink: https://www.googleapis.com/storage/v1/b/<バケット名>/notificationConfigs/11
  topic: //pubsub.googleapis.com/projects/<プロジェクト名>/topics/<トピックID>
  ```
上記より3項目をピックアップ
| 項目 | 内容 |
|:-----|:-----|
| etag | エンティティタグ<br>ウェブリソースのバージョン管理に使用され、エンティティタグはリソースの特定のバージョンを識別し、キャッシュの整合性を確保するために役立つ。数字を変更することは不可
| id | オブジェクトID<br>特定の通知構成を取得する際に使用するID。数字を変更することは不可|
| payload_format　　 | 変更されたオブジェクトのメタデータを含む文字列<br>通知設定を作成するときに、トリガーされた通知に入れる[ペイロード](https://cloud.google.com/storage/docs/pubsub-notifications?hl=ja#payload)の種類を指定する。ペイロードの種類はデフォルトでは「JSON_API_V1」となり、他に「なし」を指定することが可能|

ペイロードの上記内容は公開記事より引用しておりますが、ペイロードとはデータ本体の意を表すものと認識しており、上記内容では動作が不明でしたので、設定を「JSON_API_V1」と「なし」で比較してみました。

# ペイロードの評価結果
以下の通り、ペイロードはメッセージ本文、本文のJSONキーを表しており、
このことからパブリッシャーでどこのバケット名から来たものでファイル名は何なのか等の情報が必要な場合はペイロードが必要ということがわかりました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3587144/ed1c815b-536a-f1c2-c517-ea8715c8eea3.png)
【React】textareaをホットキーで確定できるようにする方法

以下のように記述すると`cmd` + `Enter`または`ctl` + `Enter`で`textarea`の内容をsubmitできます。

```tsx
// ...
export function Sample() {
  // ...

  const handleKeyDown = (event: React.KeyboardEvent<HTMLTextAreaElement>) => {
    if (event.key === 'Enter' && (event.metaKey || event.ctrlKey)) {
      // submitのための処理
    }
  }

  return (
    <form onSubmit={handleSubmitWrapper} onBlur={handleBlur}>
      <textarea
        onKeyDown={handleKeyDown}
      />
    </form>
  )
}
// ...

```
http環境（非https）でのクリップボードへのコピー【JavaScript/TypeScript】

## はじめに

偉大なる本家様は以下になります。
この記事は、以下のページで紹介されているjQueryのコードをTypeScript（+α）に書き換えた記事です。

https://mamewaza.com/support/blog/javascript-copy.html

## 概要

JavaSciptでクリップボードへコピーする際、 `navigator.clipboard`[[1]](https://developer.mozilla.org/ja/docs/Web/API/Navigator/clipboard) を利用することで実現出来ます。
しかしながら、http環境では動作しません。
そこで、 http環境でも動作する`document.execCommand`[[2]](https://developer.mozilla.org/ja/docs/Web/API/Document/execCommand) を利用したコピー方法をフォールバックとして利用します。

このフォールバックなコピーコードが以下になります。

## コード

```typescript
const initCopyActions = () => {
    // コピーする際に押すボタン（id="copy-button"の場合）
    const copyButton = document.getElementById('copy-button');
    
    // http環境で動くコピーコード
    const copyTextFallback = (str: string): string => {
        if (!str || typeof str !== 'string') {
            return '';
        }
        const textarea = document.createElement('textarea');
        textarea.id = 'tmp_copy';
        textarea.style.position = 'fixed';
        textarea.style.right = '100vw';
        textarea.style.fontSize = '16px';
        textarea.setAttribute('readonly', 'readonly');
        textarea.textContent = str;
        document.body.appendChild(textarea);
        const elm = document.getElementById('tmp_copy') as HTMLTextAreaElement;
        elm.select();
        const range = document.createRange();
        range.selectNodeContents(elm);
        const sel = window.getSelection();
        if (sel) {
            sel.removeAllRanges();
            sel.addRange(range);
        }
        elm.setSelectionRange(0, 999999);
        document.execCommand('copy');
        document.body.removeChild(textarea);
    
        return str;
    };
    
    // メインのコピーコード
    const copyTemplate = (copyText: string, targetText: string) => {
        if (!navigator.clipboard) {
            // navigator.clipboardが利用的出来ない場合は、フォールバックなコードを実行
            copyTextFallback(copyText);
            alert(`${targetText}をコピーしました。`);
            return;
        }
        // https環境で動作するコード
        navigator.clipboard.writeText(copyText).then(
            () => {
                alert(`${targetText}をコピーしました。`);
            },
            () => {
                alert('コピーに失敗しました。');
            }
        );
    };
    
    // コピーコードを実行するコード
    const copyEmailToClipboard = () => {
        copyTemplate('aiueo@gmail.com', 'メールアドレス');
    };
    
    // イベントハンドラ
    copyButton?.addEventListener('click', copyEmailToClipboard);
};
```

## 結果

以下のようにダイアログが表示され、クリップボードへ `aiueo@gmail.com` がコピーされます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1160002/464d13e3-db0e-bb6d-4c76-fda0fe765294.png)

## リンク

[1] [MDN: Navigator: clipboard プロパティ](https://developer.mozilla.org/ja/docs/Web/API/Navigator/clipboard)
[2] [MDN: Document: execCommand() メソッド](https://developer.mozilla.org/ja/docs/Web/API/Document/execCommand)
Microsoft Learnという謎のサービス

Microsoft　Learnという得体の知れないサービスを利用しはじめた。
試しにC++の講習をスタートさせたが、あんなものでプログラムが分かるわけないだろうという感じでした。

なんというか、分かるんだか分からないんだかよく分からない説明だった。

たぶん、あの何だかよく分からない感覚を乗り越えるために自分で講習を補強する必要があるんだろうと思う。
しばらく続けてみる事にした。
https://learn.microsoft.com/ja-jp/training/
固有表現抽出　概観

## 固有表現抽出の手法についての紹介

### 固有表現抽出とは何か？
固有表現抽出（Named Entity Recognition, NER）は、テキストから人名、組織名、場所、日付などの固有名詞を特定し、分類する技術です。例を挙げると、「レオナルド・ダ・ヴィンチがモナリザを描いた」という文において、レオナルド・ダ・ヴィンチ（人名）とモナリザ（絵画）を固有表現として抽出します。

#### 固有表現抽出の使用が考えられるケース
- **情報抽出**: ニュース記事や科学論文から重要な情報を抽出するのにNERが使われます。例えば、ニュース記事から主要人物や地名を特定し、その情報を要約やデータベースへの入力に活用することができます。

- **顧客サポートとCRM**: 顧客からの問い合わせやフィードバックに含まれる重要な情報（製品名、場所、日付など）を抽出し、それに応じた対応や分析を行うのにNERが役立ちます。

- **自然言語理解 (NLU)**: チャットボットや音声認識システムでは、ユーザーの質問や要求から固有名詞を特定して、より適切な応答を生成します。

- **医療分野**: 医療記録から患者の名前、症状、薬の名前などを抽出し、より良い診断支援や治療計画を立てるのにNERが使用されます。

- **法的文書の解析**: 法律文書や契約書から特定の固有表現（人名、企業名、法的用語など）を抽出し、文書の管理や分析を容易にするためにNERが使われることがあります。

## 固有表現抽出の手法
固有表現抽出の方法としては、以下の３つの主要なアプローチがあります。

### **ルールベース**
この手法では、あらかじめ定められたルールをテキストに適用します。例えば、「〇〇様」や「〇〇さん」のような表現には、通常人名が含まれることが多いです。これらのルールを正規表現としてプログラムに組み込むことで抽出が可能になります。

#### 正規表現の例
```
[\u3041-\u3096\u30A1-\u30FA\u4E00-\u9FAF]+[様さん]
```
この正規表現は日本語の文字を指定します。`\u3041-\u3096`はひらがな、`\u30A1-\u30FA`はカタカナ、`\u4E00-\u9FAF`は漢字の範囲を表し、`+`は1文字以上の日本語文字列を表します。

##### メリットとデメリット
メリット： シンプル、データセットが少ない場合でも使える
デメリット： 柔軟性に欠ける

、手動で規則を考える必要がある

### **機械学習 (CRF)**
機械学習手法の中でも時系列分析で使われるのがCRF(Conditional Random Field；条件付き確率場)です。CRFは、それぞれの単語のラベルが前後のラベルに依存するという文脈依存性をモデリングします。

具体的には、観測確率（その単語が固有表現であるか）と遷移確率（その前の単語の次に固有表現が来るかどうか）の積が最大のものを採用する手法です。

##### メリットとデメリット
メリット：ルールベースよりも抽出の柔軟性が向上する
デメリット：大規模なアノテーションデータが必要・特徴量エンジニアリングが必要

### **深層学習 (RNN, LSTM, BERT)**
深層学習を使ったアプローチには、以下のような手法があります。

- **LSTMとCRFの組み合わせ**
  LSTMは文中の単語間の長距離依存関係を捉えることができます。CRFを組み合わせることで、全体として最も可能性の高いタグのシーケンスを割り当てます。

- **BERT (Transformers)のファインチューニング**
  BERTはアテンション機構を使用して、単語間の相互作用と関連性を評価します。これを固有表現抽出に特化させるために、データセットを用いてファインチューニングします。

- **LLM(大規模言語モデル)のファインチューニング**
  GPTなどの生成系LLMモデルは、特に少量のデータセットでも高度な精度を出せるため、データの量よりも質を重視して学習させることが可能です。

## まとめ
固有表現抽出のタスクには多くの手法があり、それらを組み合わせて使うことも、固有表現のラベルによってはルールベースの方が精度が良い場合もあります。また、使用可能なデータセットの量も手法を選ぶ際の重要な考慮事項です。

自然言語処理の道を歩み始めたばかりです。記事に何か誤りや改善すべき点が見つかれば、コメントでご指摘いただけると幸いです。皆様のご意見や知見を拝聴できることを心待ちにしております。

## 参考ページ
https://www.intellilink.co.jp/column/ai/2021/120700.aspx

https://www.intellilink.co.jp/column/ai/2022/010600.aspx

https://www.intellilink.co.jp/column/ai/2022/022800.aspx

https://www.ibm.com/topics/named-entity-recognition
Ciscoルータのルーティング(経路選択)について

CCNA勉強のためのメモです。

# 概要
Ciscoルータは、大体**3つの値**を元にルーティング(経路選択)を行います。
[1.プレフィックス長](#1-プレフィックス長)
[2.AD値(アドミニストレーティブディスタンス)](#2-ad値アドミニストレーティブディスタンス)
[3.メトリック値](#3-メトリック値)

# 1. プレフィックス長
**プレフィックス長**とは、IPアドレスに付いてる192.168.10.1/24の/**24**のことです。
プレフィックス長が**大きい**ルートがまず選択されます。

> (例)
> ```ruby
> C 192.168.1.0/24 is directly connected, FastEthernet1 #プレフィックス長は24
> C 192.168.1.0/28 is directly connected, FastEthernet0 #プレフィックス長は28
> ```
> この場合、**プレフィックス長がより大きい**FastEthernet0が選択されます。

# 2. AD値(アドミニストレーティブディスタンス)
**プレフィックス長が同じ場合、AD値が小さいルートが選択されます。**
AD値は下記の場合、**120**です。
```ruby
                 ##これ
R	192.168.1.0/24 [120/1] via 192.168.1.254 00:00:06 FastEthernet1
```
**directly**の場合、**AD値は0**になります。
```ruby
#directlyがあれば、AD値は0
C 192.168.1.0/24 is directly connected, FastEtherne1
```
> (例)
> ```ruby
> R	192.168.1.0/24 [120/1] via 192.168.1.254 00:00:06 FastEthernet1 #AD値は120
> C   192.168.1.0/24 is directly connected, FastEthernet2 #AD値は0
> ```
> この場合、AD値が**小さい**FastEthernet2が選択されます。

# 3. メトリック値
**プレフィックス長もAD値も同じ場合、メトリック値が小さいルートが選択されます。**
メトリック値は、AD値の右の数字です。
下記の場合、メトリック値は**100**になります。
```ruby
                       #これ
R	192.168.1.0/24 [120/100] via 192.168.1.254 00:00:06 FastEthernet1
```
> (例)
> ```ruby
> R	192.168.1.0/24 [120/100] via 192.168.1.254 00:00:06 FastEthernet1 #メトリック値は100
> R	192.168.1.0/24 [120/200] via 192.168.1.253 00:00:06 FastEthernet2 #メトリック値は200
> ```
> この場合、メトリック値が**小さい**FastEthernet1が選択されます。
【Unity】Swift のネイティブプラグインからのコールバックで文字列を渡す

## 本記事について

この記事は [CoreBluetoothForUnity Advent Calendar 2023](https://qiita.com/advent-calendar/2023/core-bluetooth-for-unity) の19日目の記事です。

ネイティブプラグインから C# のコールバックを呼ぶ際に文字列を渡す方法のうち、文字列そのもののポインタを渡す方法について説明します。

## やること

C# から文字列を NSString のポインタとして受け取る場合はざっくり以下の流れになります。

![callback1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/113504/1b2f6e89-cc3a-52e6-b35f-12a210e7dc83.png)

C# 側からネイティブプラグイン側に破棄を指示しています。

この流れでは C# 側から処理が始まっていますが、コールバックの場合はネイティブプラグイン側から呼ばれることになるので、以下のようになります。

![callback4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/113504/bc7507f4-0f72-0131-16cf-81272c4c1b3b.png)

この場合コールバックの処理は同期のため、コールバックの処理終了後にネイティブプラグイン側に処理を入れることが可能です。

であるならば、C# 側で破棄を指示せず、ネイティブプラグイン側で文字列を破棄しても問題ないはずです。

![callback5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/113504/a1184e90-340d-327a-1945-0f7b759b69e6.png)

さらに、破棄をネイティブプラグイン側で行うのであれば NSString のポインタじゃなくて最初から文字列渡してしまえばいいのでは？というのが以下です。

![callback3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/113504/6f291f3b-a9e3-2c19-5806-878215920f7d.png)

とてもシンプルになりました。

長くなりましたが、本記事ではこれをどうやって書くのかを説明します。

## 環境

- CoreBluetoothForUnity 0.4.6

## コード

例として示す delegate は以下です。

```.cs
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate void CB4UCentralManagerDidConnectHandler(IntPtr centralPtr, IntPtr peripheralIdPtr);
```

```.swift
public typealias CB4UCentralManagerDidConnectHandler = @convention(c) (UnsafeRawPointer, UnsafePointer<CChar>) -> Void
```

peripheralIdPtr が文字列のポインタです。
ペリフェラルは CoreBluetooth の用語であり、本記事では気にする必要はありません。

### Swfit

[リンク](https://github.com/teach310/CoreBluetoothForUnity/blob/0.4.6/Plugins/CoreBluetoothForUnity/Sources/CoreBluetoothForUnity/CB4UCentralManager.swift#L73)

```CB4UCentralManager.swift
public func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) {
    let peripheralId = peripheral.identifier.uuidString
    peripheralId.withCString { (uuidCString) in
        didConnectHandler?(selfPointer(), uuidCString)
    }
}
```

peripheralId は String です。
[withCString](https://developer.apple.com/documentation/swift/string/withcstring(_:)) を使って null 終端の C 文字列を取得し、コールバックの引数として渡しています。

この関数を抜けると Swift によって文字列は勝手に破棄されます。

### C#

[リンク](https://github.com/teach310/CoreBluetoothForUnity/blob/0.4.6/Packages/com.teach310.core-bluetooth-for-unity/Runtime/NativeCallbacks/NativeCentralManagerCallbacks.cs)

```NativeCentralManagerCallbacks.cs
[AOT.MonoPInvokeCallback(typeof(NativeMethods.CB4UCentralManagerDidConnectHandler))]
static void DidConnect(IntPtr centralPtr, IntPtr peripheralIdPtr)
{
    GetDelegate(centralPtr)?.DidConnect(Marshal.PtrToStringUTF8(peripheralIdPtr));
}
```

`Marshal.PtrToStringUTF8` を使って文字列を取得するのが楽です。

Marshal.PtrToStringUTF8 内で文字列はマネージドメモリにコピーされるため、元の文字列が破棄されても問題ありません。

## おわりに

本記事では Swift のネイティブプラグインにおいてコールバックで文字列を渡す方法としてはおそらくこれが一番簡単だろうと思うものを紹介しました。
`withCString` にたどり着くために少し時間かかったため、Swift のネイティブプラグインを書く際に参考になれば幸いです！
コマンドラインでiOSアプリをビルドしシミュレータで起動する

# はじめに

本稿は、コマンドラインでiOSアプリをビルドし、シミュレータにインストールおよび起動する方法について書いています。

# シェルスクリプトの作成

以下のbuild.shをプロジェクトのルートディレクトリに配置します。
build.shには `chmod +x build.sh` して実行権限を与えておきます。

```shell:build.sh
#!/bin/sh

SCHEME='Your Scheme'
SIM_NAME='iPhone 15' # シミュレータ名
DESTINATION="platform=iOS Simulator,name=$SIM_NAME"
CONFIG='Debug' # 'Debug' or 'Release'
DERIVED_DATA_PATH='./build'
APP_NAME='Your App Name'
APP_PATH="$DERIVED_DATA_PATH/Build/Products/$CONFIG-iphonesimulator/$APP_NAME.app"
BUNDLE_ID='your.bundle.id'

CLEAN=''; [ "$1" = "clean" ] && CLEAN='clean'

# アプリのビルド
xcodebuild -scheme $SCHEME -destination "$DESTINATION" -configuration $CONFIG -derivedDataPath $DERIVED_DATA_PATH $CLEAN build

# シミュレータの起動
xcrun simctl boot "$SIM_NAME"

# Xcodeのシミュレータアプリケーションを開く
open -a Simulator

# シミュレータにアプリをインストール
xcrun simctl install booted "$APP_PATH"

# シミュレータでアプリを起動
xcrun simctl launch booted "$BUNDLE_ID"
```

`SCHEME` 、 `APP_NAME` などはプロジェクトに合わせて指定します。

`SIM_NAME` には、

```
xcrun simctl list devices
```

で出力される利用可能なシミュレータの名前を指定します。

build.shのそれぞれのコマンドの意味はコメントの通りです。

:::note info
本稿執筆時点でのxcodebuildのバージョンは以下になります。

```
xcodebuild -version
Xcode 15.0
Build version 15A240d
```
:::

# シェルスクリプトの実行

```
./build.sh [clean]
```

`clean` はオプションです。 `clean` を付けるとクリーンビルドします。ただし、クリーンビルドはビルド時間が長くなる傾向にありますので、適宜付けたり付けなかったりしてください。

build.shを実行することで、iOSアプリをビルドし、指定したシミュレータで起動することができます。
CSSで上下左右中央寄せにする主要な方法5選

# CSSで上下左右中央寄せにする主要な方法5選

Webデザインにおいて、要素を上下左右中央寄せにすることは、ページの見栄えを整える上で非常に重要です。CSSを使えば、さまざまな方法で要素を中央寄せに配置することができます。この記事では、CSSで上下左右中央寄せにする主要な5つの方法を具体的な使用例とともに紹介します。

## 左右中央寄せ

### ① text-alignで左右中央寄せにする

#### 使い方

```css
.center-text {
    text-align: center;
}
```

`text-align: center;`は、テキストやインライン要素を左右中央寄せにする最も簡単な方法です。このプロパティを適用すると、テキストやインライン要素はコンテナの中央に配置されます。

### ② margin:autoで左右中央寄せにする

#### 使い方

```css
.center-block {
    width: 50%;
    margin: 0 auto;
}
```

ブロックレベル要素を左右中央寄せにする際には、`margin: 0 auto;`を使用します。これにより、左右のマージンが自動的に調整され、要素が中央に配置されます。

### ③ display: flex; ＆ justify-content: center;で左右中央寄せにする

#### 使い方

```css
.flex-container {
    display: flex;
    justify-content: center;
}
```

Flexboxを使用して要素を左右中央寄せにする方法です。`display: flex;`でFlexboxコンテナを作成し、`justify-content: center;`で子要素を水平方向の中央に配置します。

## 上下中央寄せ

### ④ display: flex; ＆ align-items: center;で高さ中央にする

#### 使い方

```css
.flex-container {
    display: flex;
    align-items: center;
    height: 200px;
}
```

Flexboxを使って要素を垂直方向に中央寄せにする方法です。`align-items: center;`を使用すると、Flexboxコンテナ内の要素は高さの中央に配置されます。

### ⑤ line-heightとheightを同じ高さにすることで高さ中央にする

#### 使い方

```css
.center-line-height {
    height: 50px;
    line-height: 50px;
}
```

`line-height`と`height`を同じ値に設定することで、テキストを垂直方向の中央に配置することができます。この方法は、一行のテキストを中央寄せする場合に特に有効です。

## まとめ

要素を上下左右中央寄せにする方法は多岐にわたりますが、上記の5つの方法が主要です。`text-align`や`margin:auto`は簡単に左右中央寄せを実現でき、Flexboxを使用すると、より複雑なレイアウトにおいても要素の中央寄せが容易になります。これらのテクニックを駆使することで、見栄えの良いWebページを設計することが可能です。
RustでGmailを送る

## なぜこの記事を書こうと思ったのか
Rustでメールを送るのはどうやるのだろうと思って調べてみたのですが、意外と面倒だったのでメモしておきます。
SlackやChatworkほど簡単ではなかったです。。

## 事前にアプリパスワードを取得しておく
[こちら](https://support.google.com/mail/answer/185833?hl=ja)の **アプリパスワードを作成、使用する** を参考にして、アプリパスワードを取得しておいてください

## コード内容
```Cargo.toml
[dependencies]
lettre = "0.11.1"
```

```rust:main.rs
use lettre::{
    transport::smtp::authentication::Credentials, Message,
    message::{header, SinglePart},
    SmtpTransport, Transport, message::Mailbox, Address
};

fn main() {
    let username = "******@gmail.com";
    let app_password = "**** **** **** **** ";//事前に取得しておいたアプリパスワード
    let smtp = "smtp.gmail.com";
    let email = Message::builder()
        .to(Mailbox::new(None, username.parse::<Address>().unwrap()))
        .from(Mailbox::new(None, username.parse::<Address>().unwrap()))
        .subject("題名")
        .singlepart(
            SinglePart::builder()
                .header(header::ContentType::TEXT_PLAIN)
                .body(String::from("本文"))
        )
        .unwrap();
    let credentials = Credentials::new(username.into(), app_password.into());
    let mailer = SmtpTransport::starttls_relay(smtp)
        .unwrap()
        .credentials(credentials)
        .build();
    let result = mailer.send(&email);
    println!("{:?}", result);
}
```

## 参考にさせていただいたサイト
https://github.com/lettre/lettre/blob/master/examples/maud_html.rs
素因数分解

<!--
2023/11/18
-->
[picoCTF][Cryptography][Very Smooth]

## Writeup
* 素因数分解のサイトでは、素因数分解できなかった。
参考サイトの説明を元に、コードを作成。
~~~python:Pollard's ρ-1 algorithm
import math

N = 0xb03ea698ce2b51fb00e11e6fbaf1e5373dc5b0c70eb2b14a36d21e8667be8774eee51f6050a10237f6b24f21204fc8013681e7ed72ed051188f3274aae8f1de0d39389b514c196fa82c98a270bfabefd044da8c687b0e114ebbde82536c0709ac5ad81bfe0077e9d9b798ad5abecee52767e68f8060c45936521fd93893102eb1676f2ff41324a7a6b3dff2e830538e06d25934e9f14bf6b40ab5674fe648e314bf06f84282f5ef52bc1401de3a42eb66e64bcdadd2674348e5bdb7016feda44d719af387a948ad81cbaed10213dd930fc7bc7677d8c4cdab0645d0ff15e6ad6ca37135942c3be08f23e7be0992c8b3370dcdc31045e086d823107fb2e443dc9
exp = 1
base = 2

while True:
    base = pow(base, exp, N)
    p = math.gcd(base-1, N)
    if 1 < p < N:
        break
    else:
        exp += 1

print("p =", p)
print("q =", N//p)
~~~
* コードを実行
素因数分解に成功。
![screenshot.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/160736/77a1c002-79a9-608b-241e-60241bdb3b5e.png)
<br>

* 与えられたコードを確認
`math.lcm`を使用している。
![screenshot 3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/160736/86563401-489e-3a4a-de6c-4212c1594655.png)

<br>

* 必要なライブラリをインストール
~~~
pip install pycryptodome
~~~

* デコードするコードを作成
~~~python:dec.py
import math
from Crypto.Util.number import *

c = 0xa913a96e215b5aa79c702d27fa375c73d06787639c4131fb32877cafefaa8faf70e15f6a17ef2a9a6f5310b157cb287b740e77cb5385081d1853a9104bc16357b259fa2d146bd87398d4ef6f1c078289812952c67792cf9cd745049aeb9d4ab4dff2825a9c0b3381f19b2a67164f9d4de33c25f98bc2f224feb5507b531e1a1c7be5ed2d8ddd01f3fae37245e8cf99c75a21848993d445e1d6d69d555a3e6cc8055704fdde88df9084bda3ea65a9384fa64bf8df4d88946449526320c15d4d2d871638070489adf3f8c95caffeab40b0d137a9319be20cdf6ebbaf037f62093d9bd33edd4ffd7e1929b9ab06252956fd85250a0515ef2b4e035017be5702cdd3
e = 65537
p = 166778678181685622576528273627655558408416154535903271612099666211650718813574353644982679332718906416639262976090347767411961612927781793104151632976133030663080503056699508483393432483211221435369665266139037807475222869716828564531056095553338227197069928344760597134918054695465937470622255206477029220627
q = 133403359244090432282498741122238666960102072347999139399194192684930601046915449960642287092839790447663496118648044185489682661151904512440107598783041356688524538695035027282386056258524355032597865645378353170572838674473248880702185307449067157154593351616151961260356975594350933975792987875901590674739

phi = math.lcm(p-1, q-1)
# eを-1乗して、phiのmod（余り）を計算
d = pow(e, -1, phi)
# 暗号文をd乗して、nのmod（余り）を計算
P = pow(c, d, p*q)

print(long_to_bytes(P).decode())
~~~
* コードを実行し、デコードに成功
![screenshot 1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/160736/781edf34-efd6-9d15-7007-5a205288de2a.png)
<br>

* 以上です。

## 参考サイト

https://ir0nstone.gitbook.io/crypto/rsa/factorisation-methods/pollards-p-1
Autopsuy , ssh-keygen

<!--
2023/11/16
-->

[picoCTF][Forensics][Operation Oni]

## Writeup
* イメージファイルを解凍
どっちでも大丈夫。
いろいろ解凍できるunarは便利ね。
~~~
sudo apt install -y unar
unar disk.img.gz
~~~
~~~
gunzip disk.img.gz
~~~
<br>

* `autopsy`でイメージファイルを調査する。
`NewCase` `AddHost` `AddImage`と適当に名前を付けて、disk.imgを指定。
この問題では`Hash`の計算は必要ない。
~~~
sudo autopsy &
~~~
* イメージファイルの全体像
![screenshot 38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/160736/22203bc0-a055-eee1-975c-6c44f61f98fe.png)
<br>

* `ANALYZE` `FILE ANALYSIS`からファイルを確認
`/1/`は回復用のパーティションか何かかな。
`/2/`はLinuxっぽい。`apk`ファイルがあるので、Androidかな。
とりあえずコマンドの履歴を確認。
![screenshot 40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/160736/866abce5-517d-7ef3-db23-3456dbd090ae.png)
<br>

* `ssh-keygen -t ed25519`で鍵を生成していることを確認できた。
'ed25519'って、エドワーズ曲線デジタル署名アルゴリズム(EdDSA)の１つだそう。
そもそもエドワーズ曲線デジタル署名アルゴリズムが分かりません。
ただ署名アルゴリズムということは理解しました。
![screenshot 42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/160736/75ccf483-6045-5415-8445-9d9c92a259d7.png)
<br>

* `ssh-keygen`のデフォルトは`rsa`で、`id_rsa`という鍵が作られるようです。
`ed25199`だと`id_ed25199`という鍵のようだ。
![screenshot 43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/160736/51276370-6be6-1d19-2623-25f86281741e.png)
鍵を探すため、`id_ed25519`で検索。
![screenshot 44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/160736/d109ce19-aaa9-a416-d0aa-0a7331ac15e8.png)
`Export`して、 `key_file`にファイル名を変更。
<br>

* サーバへの接続をトライ。
`key_file`の権限が良くないと言われた。
![screenshot 46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/160736/a52419eb-7dd7-1239-bd9c-7382e1502fe9.png)
権限を変更。
~~~
chmod 600 key_file
~~~

* 再度、サーバへの接続をトライ。
無事に接続できた。
![screenshot 47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/160736/c069e3f7-cd80-6796-0163-c3e655be32e2.png)
ファイルを確認。
![screenshot 48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/160736/ea4b69f4-375f-4d78-0655-071e49457b59.png)
<br>

* 以上です。 

## 参考サイト

https://www.twx-threatintel.com/hobokomo-securitynews/20220630/tips-338/
AI搭載IDE、CURSORのダウンロード方法

<h1> CURSORをダウンロードする方法について </h1>

初投稿になります。TETTSUNです。今回お話しすることは題名そのままのことです。
(注意：今回の投稿はWindows向けの投稿になっております。MacOSだと多少内容が異なる可能性があります。)

<h2> １，CURSORとは？ </h2>
<p>CURSORとは、簡単に言うとAIを搭載した総合開発環境のことです。</p>
<p>このIDEのAIを使うと、エラーの原因やその解決策の提示、修正までしてくれます。</p>
<p>CURSORは将来性も期待されており、今後も新機能が追加されていくことでしょう。
<p>ちなみにcursorにはVScodeと互換性があり、cursorにその拡張機能をうつすことも可能です。
<h2>２，CURSORをダウンロードしてみよう。
<p>ここからはCURSORをダウンロードする方法をご紹介します。

 <p>１，まず<a href="https://cursor.sh/">このリンク</a>から公式サイトに移動してください。
 <p>２，次にDownload for Windowsボタンをクリック。ファイルのダウンロードが開始します。
 <p>３，ファイルを開くとナビゲーターが開きます。あとはそれの指示に従ってください。アカウントの作成、メールでの承認を済ませたら早速CURSORが使えるようになります。
 <h2>３，補足</h2>
 <p>CURSORには有料版も存在しています。</p>
 <p>有料版だと、AIを使える回数が増え、様々な特典があります。有料版は二種類存在するそうなので、よければ調べてみてください。</p>
 <h2>４，最後に。</h2>
 <p>今回はCURSORをダウンロードする方法をご紹介しました。</p>
 初めての投稿なのでちょっとわかりずらいかもです。
【Unity】ネイティブプラグインからのコールバックでインスタンスメソッドを呼ぶ

## 本記事について

この記事は [CoreBluetoothForUnity Advent Calendar 2023](https://qiita.com/advent-calendar/2023/core-bluetooth-for-unity) の18日目の記事です。

ネイティブプラグインにおいてデリゲートを使う場合 C# 側では呼び出す**静的メソッド**に対して [MonoPInvokeCallback](https://learn.microsoft.com/en-us/dotnet/api/objcruntime.monopinvokecallbackattribute?view=xamarin-ios-sdk-12) 属性を付ける必要があります。

Unity の [Building plug-ins for iOS](https://docs.unity3d.com/2022.3/Documentation/Manual/PluginsForIOS.html) のドキュメントの Using delegate の項目にも記載されています。

インスタンスメソッドを渡すことはできないため、インスタンスメソッドを呼んで欲しかったら静的メソッドを経由して呼び出す必要があります。

その方法として以下の3つを考えました。

1. C# のオブジェクトに紐づくアンマネージドオブジェトのポインタを引数に渡す
2. デリゲート登録時にコールバックを呼び出すインスタンスを渡す。
3. クラスに ID を付与して、その ID を引数に渡す

このうち 1 がメンバ変数増やす必要がなくて簡単だったためこの方法を選択しました。
開発する上で問題は発生しませんでした。

この方法の具体的なやり方を説明します。

## 環境

- CoreBluetoothForUnity 0.4.6

## コード

見た方が理解が早いと思うため、コードを先に示します。

[INativeCentralManagerDelegate](https://github.com/teach310/CoreBluetoothForUnity/blob/0.4.6/Packages/com.teach310.core-bluetooth-for-unity/Runtime/CBCentralManager.cs#L21-L28)

```CBCentralManager.cs
    internal interface INativeCentralManagerDelegate
    {
        // 呼び出したいメソッド
    }
```

CoreBluetoothForUnity ではネイティブプラグインから読んでほしいメソッドはインタフェースで定義しています。
インタフェースで定義することで依存切ってるのはドキュメント生成の都合のため、本記事の内容とはほぼ関係ありません。
このインタフェースを実装したクラスのメソッドを呼びたいとだけ理解していただければ大丈夫です。

それを踏まえて以下のクラスでインスタンスメソッドの呼び出しを実装しています。

[NativeCentralManagerCallbacks](https://github.com/teach310/CoreBluetoothForUnity/blob/0.4.6/Packages/com.teach310.core-bluetooth-for-unity/Runtime/NativeCallbacks/NativeCentralManagerCallbacks.cs#L9)

```NativeCentralManagerCallbacks.cs

    internal class NativeCentralManagerCallbacks : INativeCentralManagerCallbacks
    {
        readonly static Dictionary<IntPtr, INativeCentralManagerDelegate> s_centralManagerDelegateMap = new Dictionary<IntPtr, INativeCentralManagerDelegate>();

        public void Register(SafeNativeCentralManagerHandle handle, INativeCentralManagerDelegate centralManagerDelegate)
        {
            s_centralManagerDelegateMap[handle.DangerousGetHandle()] = centralManagerDelegate;
            NativeMethods.cb4u_central_manager_register_handlers(
                handle,
                DidConnect,
                DidDisconnectPeripheral,
                DidFailToConnect,
                DidDiscoverPeripheral,
                DidUpdateState
            );
        }
...
        static INativeCentralManagerDelegate GetDelegate(IntPtr centralPtr)
        {
            return s_centralManagerDelegateMap.GetValueOrDefault(centralPtr);
        }

        [AOT.MonoPInvokeCallback(typeof(NativeMethods.CB4UCentralManagerDidConnectHandler))]
        static void DidConnect(IntPtr centralPtr, IntPtr peripheralIdPtr)
        {
            GetDelegate(centralPtr)?.DidConnect(Marshal.PtrToStringUTF8(peripheralIdPtr));
        }
```

1. 事前に静的な辞書 `Dictionary<IntPtr, INativeCentralManagerDelegate>` を用意しておく
2. `MonoPInvokeCallback` 属性を付けた静的メソッドが呼び出される。
3. 静的な辞書からアンマネージドオブジェクトのポインタをキーにしてインスタンスを取得する

## おわりに

ネイティブプラグインからのコールバックでインスタンスメソッドを呼ぶ方法を説明しました。
IntPtr をキーにするのはいかがなものか..とは思うものの、理想通りに動いてしまっているのでまぁいいかとしています。
こっちのほうがいいよ！等あればぜひ教えてください！
Python学習備忘録①　コードエラー等もなさげなのに、Python3で作ったモジュール（拡張子が.pyのPythonファイル）がなんか開かない（≒起動しない）んですが・・(´д｀)　

「時代はたぶんAIだしPythonでもやってみるかぁ(´д｀)」と、とりあえずPython3を今メインで学習しています。エディターは今はVScodeです。
 
 **「確かな力がつくPython「超」入門　鎌田正浩　著」（個人的に初学者にとっては名著だと思う）**
 
 を中心に勝手に学び始め、スクレイピングとかRSSとかなんとなくわかったんですが、tkinterという標準ライブラリのところでモジュールのGUI化（≒自分みたいなプログラミング真の弱々が、見た感じでなんとなく使えるようにする（画面を出現させる）こと？）するところで、タイトルの問題にぶち当たりました。

<h2>とりあえず、こうしてQiitaに現状を文字に起こして整理してみる（自動保存便利）

・pip listというコマンドでチェックしてみたところ、必要なライブラリはきちんとインストールされている
・一見コードミスはなさそう **（※実はありました）**
・Visual Studio Codeでそもそもエラーだと赤字出してくる拡張機能のError Lensは何も騒いでない・・
・インデントも大丈夫そう（Pythonは関数や条件分岐時、インデントを適切に気をつけないと基本文句言ってきます。）

<h2>Pythonのファイルの開き方多過ぎ・・・(´д｀)

ずっと、とあるプログラミングスクールでメインで学習していたPHPとかは
開発環境のファイルクリックして開くと
（Windowsで今もLaravel復習するときは開発環境はXAMPPを起動）
エラーならエラーが表示され、エラーがなければ、そのまま出力なのですが・・
（自分が他の開き方知らないだけかもしれない(-_-;)）

____
とりあえず、
<h3>tkinterをimportして、左上に羽のマークがついた画面（ウィンドウ？）が
出てくるようにした拡張子が「.py」のファイルを作った場合、

先述の本をもう一度読み返して整理すると、**ファイルの開き方は少なくとも次の３つ**（※Windowsの場合　Macはコマンドプロンプトを「ターミナル」、VSコードのpowershellを「zsh」に読み替えるといけるはずです。なおエディター等によりたぶんもっとあるはず・・(-_-;)）

___
<h4>①普通にそのファイルをクリック
<h4>②VSコードで、そのファイルが入っているフォルダを開いて、「.\」の後に拡張子込みで.\ファイル名.pyでEnterポチ（違うフォルダの場合、cdコマンドで移動）

※cd は「change directory」の略らしいです
<h4>③コマンドプロンプトを起動し、cdコマンド（※）で②と同様に扱うファイルの場所を指定
⇒ファイル名.pyでEnterポチ（※「.\」はこのとき要りません）

（※VSコードのターミナル(powershell)に出る絶対パスをコピペすると楽です。）
____

<h3>分からねえ(´д｀)あれ・・。でも・・何かなんか違うような・・・

そんな感じで、Taylor Swift聞きながらTaylor級数展開利用してポアソン分布に関する計算、BiriBiriしながら時々見返し、やっぱ分からんと思い、ヌーに追われながら今度はガウス分布に関する計算。Ayaseって実は歌ってる曲あるんや・・撫でる？(´д｀)あ～日本レコード大賞。個人的には「ミスター」・・・分からねえ

<h3>違和感の正体：①、②の開き方はエラーすら出ず何も動かないが、
<h2>③コマンドプロンプト、エラーメッセージ出してくれてる・・・。しかも何行目じゃない？とかあるし。神(ﾟДﾟ)

そして、そこを見るとコーディングミスがあり、直すと①～③いずれの方法でも無事動きましたとさ。めでたし。めでたし。

<h1>結論：これからtkinter（ライブラリ）で何かしら作られる方はコマンドプロンプト（※）でファイルを開くのをオススメします。

※コンソールともいうそうです。（Macは「ターミナル」とかいうらしい）たぶん、JavascriptやDeveloper Toolのコンソールと同じ意味？

<h2>学習参考資料

①確かな力がつくPython「超」入門　鎌田正浩　著 SB Creative社（以下、Amazonリンク）
 https://www.amazon.co.jp/%E7%A2%BA%E3%81%8B%E3%81%AA%E5%8A%9B%E3%81%8C%E8%BA%AB%E3%81%AB%E3%81%A4%E3%81%8FPython%E3%80%8C%E8%B6%85%E3%80%8D%E5%85%A5%E9%96%80-%E7%AC%AC2%E7%89%88-%E7%A2%BA%E3%81%8B%E3%81%AA%E5%8A%9B%E3%81%8C%E8%BA%AB%E3%81%AB%E3%81%A4%E3%81%8F%E3%80%8C%E8%B6%85%E3%80%8D%E5%85%A5%E9%96%80-%E9%8E%8C%E7%94%B0-%E6%AD%A3%E6%B5%A9/dp/4815613729/ref=sr_1_15?crid=22N3IJUTCV99Y&keywords=python+%E5%85%A5%E9%96%80&qid=1700658483&sprefix=Pythontyou%2Caps%2C218&sr=8-15
 
②https://qiita.com/canard0328/items/5ea096352e160b8ececa
③https://note.com/freedom997/n/nd07b74194eef
④https://qiita.com/studio_haneya/items/ddbaa76a6ee2c705ad5a
⑤tkinter公式ドキュメント　https://docs.python.org/ja/3/library/tkinter.html
スマホで表示すると謎の余白。解決方法。

## はじめに
謎の余白の対処方法の備忘録です💁
初心者です😅
間違えてる部分多々あると思います。
もし見つけた場合、ツッコミいただけると助かります🙇

## 🦁 結論 🦁
:::note info
* Chromeの検証を行って余白にはみ出してる部分を見つけてCSSで修正する。
:::

## 内容
サイトを作成する上でCSSを使う上で、謎の余白をとの戦いがある。
今回は自分のスマホで閲覧した際に残念な余白との戦いがあったため、対処法を掲載。下記のサイトを見ることで全ての解決につながった。


## 参考にしたサイト📗
[【スマホ】レスポンシブで右側に生じた謎な余白（空白）を消す方法](https://bl-rakulog.com/responsive-right-white-space)

:::note warn
注意点⚠️
* PC、タブレットでのそれぞれ違うため、メディアクエリを使って切り替えできるようにする。
* Max-widthを活用して大きくなりすぎないように工夫する
* Widthは基本1000pxではなく、100％などで表すといい。
:::
VSCode gopls client: couldn't create connection to server.の解決法

表題にあるエラーでめちゃくちゃハマったので、解決策を残します。

```bash
[Error - 10:13:34 PM] gopls client: couldn't create connection to server.
  Message: Pending response rejected since connection got disposed
  Code: -32097 
[Error - 10:13:35 PM] The gopls server failed to initialize.
[Error - 10:13:35 PM] gopls client: couldn't create connection to server.
  Message: Pending response rejected since connection got disposed
  Code: -32097 
Error starting language server: Error: Pending response rejected since connection got disposed
```

# 解決の手順
以下の手順で解決しました。

1. goplsのパスを通す
1. GO111MODULEをオン
1. VSCodeの設定から`semantictokens`をtrue

サクッと説明しましたが、少し難しいので細かく説明していきます。

## goplsのパスを通す

### パスの確認
まず、goplsのパスを確認します。
```bash
% which gopls
```

以下のようにレスポンスが返って来れば
このセクションを進めます。
もし`/Users/ユーザ名/go/bin/gopls`と返って来れば
このセクションは飛ばしましょう！
```zsh
gopls not found.
```

### パスを通す
以下のコマンドでパスを通します。
```zsh
% codesign -f -s - /Users/ユーザ名/go/bin/gopls
```
すると、goplsが確認できるようになります！
```zsh
% which gopls
/Users/yuuki/go/bin/gopls
```

::: note warn
`~/go/bin/gopls`はみなさんの環境によって違うかもしれません。
（大抵は`Users/ユーザ名`配下の`go/bin`にあると思います）
:::

ただ、このタイミングではgoplsは正常に動作せず、以下のようになります。
```zsh
% gopls
zsh: killed     gopls
```

この状態でVSCodeを起動し、Outputタブ（`gopls(server)`）を見ると以下のような表示が出ます。何かしらのパッケージのダウンロードに失敗します。
```zsh
go: downloading google.golang.org/appengine/v2 v2.0.1 failed.
```
そこで、次のセクションです！

## GO111MODULEをオン

以下のエラーを解決するため、とあるIssueを参考にしました。
```zsh
go: downloading google.golang.org/appengine/v2 v2.0.1 failed.
```

https://github.com/googleapis/gax-go/issues/83

こちらのIssueの最後には
> hmm the problem might've been i ran with GO111MODULES=on instead of GO111MODULE=on inside my GOPATH project.

というありがたいヒントが海外ニキより残されていますので、こちらを参考にGO111MODULEをオンにします。

```zsh
% go env -w GO111MODULE=on
```


そしてVSCodeを再起動すると以下のエラーが出ると思います。
```zsh
[Error - 9:34:47 PM] Request textDocument/semanticTokens/range failed.
  Message: semantictokens are disabled
  Code: 0
```

このエラーを次のセクションで解決します！



## VSCodeの設定から`semantictokens`をtrue
こちらも海外ニキのIssueを参考にしました！
（ありがとう海外ニキ！！）

https://github.com/golang/go/issues/43353

`ctrl+shif+p`でパレットを開き、Settingと検索し、
`Open User Settings(JSON)`を選んでください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2017749/8cc984d1-cdb8-48cc-6bcc-c82f1e67cbd3.png)

以下のような画面になると思います。
色々設定はありますが、個人差ありますので、気にしなくて良いです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2017749/a616ec5c-0aa0-7250-8781-f4fa316bb77f.png)

先ほど紹介したIssueにある、以下の設定を追記します！
```json
{
  "gopls": {
    "semanticTokens": true
  }
}
```

そして、VSCodeを再起動orGoのLSPを再起動すると、、、

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2017749/8ccb38fd-a908-731b-4368-cca8fdf4d211.png)

動作しました！！！！！🎉🎉🎉🎉

## 最後に
今回はかなり苦労した（解決に12時間要した）ので、備忘録的に残しております。Goの環境で苦労される方が1人でも減ることをお祈りいたします🙏

お疲れ様でした！

## 参考文献

https://github.com/googleapis/gax-go/issues/83

https://normalblog.net/system/go-go111module-gopath-go-modules/

https://github.com/golang/go/issues/43353
Djangoでmodelを登録する手順

Djangoでmodelを登録する手順についての個人的メモです。

## ①models.pyにmodelの内容を記述する

```:models.py
from django.db import models

# Create your models here.
class Example(models.Model):
        name = models.CharField(max_length=100)
        age = models.IntegerField()
        def __str__(self):
                return self.name
```

## ②admin.pyにモデルのインポート、管理パネルへの追加処理を記述する

これによって、管理画面でモデルが確認できるようになる。

```:admin.py
from django.contrib import admin

from Model.models import Example

# Register your models here.
admin.site.register(Example)
```

`from Model.models import Example`ここは`アプリ名.models`

## ③migrationファイルを作成する

```
python manage.py makemigrations
```

## ④migrationファイルをデータベースに適用する

```
python manage.py migrate
```

migrationファイルは、モデルの変更をデータベースに反映するためのもの。

## ⑤管理画面で登録・確認できるようになる

![管理画面.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3580185/8201ffcc-7fab-c85d-6e06-a4fd220cacfb.jpeg)
GitHub Action 内で .github/workflow 配下のファイルを変更したい

# はじめに

git-auto-commit-action という github action があります

https://github.com/stefanzweifel/git-auto-commit-action

レポジトリの説明を引用すると
> A GitHub Action to detect changed files during a Workflow run and to commit and push them back to the GitHub repository. By default, the commit is made in the name of "GitHub Actions" and co-authored by the user that made the last commit.

とのことで、要するに Github Action のなかで加えられたファイルの変更を検知して、それを実際にレポジトリに commit & push してくれる　action です。

どのように使うかというと、例えば `npm run format` などと合わせて、以下のような Actions を定義すると Github Action のなかで `npm run format` を実行し、結果をそのままブランチにプッシュしてくれます。

```
      - name: Run format
        run: npm run format
      - uses: stefanzweifel/git-auto-commit-action@v3.0.0
        with:
          commit_message: Format by GitHub Actions
```

# 今回遭遇した問題

通常であれば上記のような記述だけで問題なく実行できるのですが、今回私が `.github/workflows` 配下の `deploy.yml` に変更を加えたとき、問題が起こりました。

```
[main 9a01a11] Format by GitHub Actions
 Author: kromiii <kromiii@users.noreply.github.com>
 1 file changed, 1 insertion(+), 1 deletion(-)
To https://github.com/kromiii/astro-notion-blog
 ! [remote rejected] main -> main (refusing to allow a GitHub App to create or update workflow `.github/workflows/deploy.yml` without `workflows` permission)
error: failed to push some refs to 'https://github.com/kromiii/astro-notion-blog'
##[debug]Docker Action run completed with exit code 1
##[debug]Finishing: Run stefanzweifel/git-auto-commit-action@v3.0.0
```

`npm run format` により、GithubAction のなかで `deploy.yml` に変更が加えられたのですが、その変更を push しようとした時に権限がないとエラーになってしまっているようでした。

最初は Github Workflow の権限が足りないのではないか？と疑って色々設定を見たのですが、どうも権限は正しく設定されていそうです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/176789/14226e4f-cb23-a5cc-67fd-2e874a3722d8.png)

では何が問題なのか？

エラー文の中に少し気になる一文がありました

`refusing to allow a GitHub App to create or update workflow ` 

エラー文でググってみると以下の記事がヒット

https://stackoverflow.com/questions/66643917/refusing-to-allow-a-github-app-to-create-or-update-workflow

どうやら Github Workflow で Actions の定義ファイルを変更するには特別なパーミッションが必要なようです

# 解決方法

と言うわけで、workflow を変更する権限を持った専用の PAT を発行してみる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/176789/0e821df3-53ca-3060-8eed-da65a01f40b3.png)

`workflow` にチェックを入れるのがポイント

ここで発行した PAT を Github Action の Secret Token に適当な名前で入れます

今回は `PAT_GRANTED` としました

これを `actions/checkout` の引数に渡してあげます
**（`stefanzweifel/git-auto-commit-action` の引数でないことに注意）**

```
        uses: actions/checkout@v4
        with:
          token: ${{ secrets.PAT_GRANTED }}
```

さて、結果はいかに・・・

```
[main e9282fc] Format by GitHub Actions
 Author: kromiii <kromiii@users.noreply.github.com>
 1 file changed, 1 insertion(+), 1 deletion(-)
To https://github.com/kromiii/astro-notion-blog
   b9d9aa5..e9282fc  main -> main
```

git-auto-commit-action が成功しました :tada: 

# まとめ
Github Actions で .github/workflow 配下のファイルを変更する場合は特別な権限が必要みたいなので注意です

そう言う場合は個別にPATを発行して Actions で指定してあげましょう
HTML 属性: autocomplete

## はじめに
autocompleteの備忘録です💁
初心者です😅
間違えてる部分多々あると思います。
もし見つけた場合、ツッコミいただけると助かります🙇


## 内容
ポートフォリオサイトを作成した際にお問い合わせサイトを作成した。
お問い合わせに必ず、「name」「Email」「comment」を作成する。
それぞれに属性があり設定する。
その際にautocompleteがあり、入力を補助してくれる。
タイピングの労力を減らすために広く使用されている。

```Contact.js
<div className="nameInput">
    <input 
        name="name"
        autoComplete="name" // この属性を指定してる。
        value={user.name} 
        onChange={handleUser}
        type="text"
        placeholder="name"
    />
    {errors.name && <p className="name-error-message">{errors.name}</p>}
</div>
```

## よく使いそうな属性
email　メールアドレス。

username　ユーザー名またはアカウント名。

new-password　　新しいパスワード。

current-password　ユーザーの現在のパスワードです。

postal-code　　郵便番号です

cc-number　　クレジットカードや口座番号など番号です。

bday　　生年月日の全体です。

sex　　性別です。

tel　　国番号を含む、完全な電話番号です。

url　　URL です。


:::note warn
注意点⚠️
* 各種の細かいカテゴリも存在する。
:::

:::note info
押さえておくべき点🧠
* ユーザーに合わせて設定してあげることで入力の手間を省ける。
:::

## 参考にしたサイト📗
[HTML 属性: autocomplete](https://developer.mozilla.org/ja/docs/Web/HTML/Attributes/autocomplete)
Windows の Firefox で X(Twitter) の 『さらに表示』が出るのは何のバグなのか

たいそうなタイトルを付けたが、やる気がなくなったので軽く書く。

# 省略要素がないのに『さらに表示』がでる

筆者が使用しているFirefox119では、X(Twitter)で、長文ではないポスト（ツイート）でも、リンクなどがなければ、『さらに表示』出る。
その姿は壮観である（？）

ちなみに、Youtubeでも、長くないコメントでも『続きを読む』でる。

# 原因

## 概略
フォントがメイリオの場合、なる。
ブラウザのフォントを変更すればなおるが、Windows でX(Twitter)をやると大抵、メイリオになるので厄介。

## 詳しい原因
いわゆる、『さらに表示』は、offsetHeight と scrollHeigh tの差がある場合に『さらに表示』を出していると思われる。
Firefoxのメイリオでの描画の場合、line-height を指定して描画すると細かい差が出ることが多い。

bugzilla にバグ報告が上がっていたが直る気配はしない。
https://bugzilla.mozilla.org/show_bug.cgi?id=1416615

# Firefoxのバグではなくないか？
↑の bugzilla でもあったが、chromium 系と同じ動作を Firefox でも保障しているわけではないし、W3Cがブラウザの表示を1ピクセル単位で規定しているわけでもない。

だから別に見方を変えれば Firefox の動作としては正しく、Firefox で正しい動きにならないサイトが悪い。X(Twitter)のエンジニアも、Youtubeのエンジニアも日本語環境の Firefox での動作確認をしてないのである。

今の時代、chromium だけで動かせればたいてい何とかなる。
ただ HTTP の世界は、chromium、もといGoogleのプラットフォームではないんだから、Webの標準を重視しているFirefoxでこそ動作確認をしてもらいたいものである。

事実 Firefox で動かないサイト、動くことを保障していないサイトも増えている。
先日もBOOKWALKERの試し読みが Firefoxで動かずに泣いたばかりである。

私は、だけど、Firefox を使う。

# 直し方

Twitterには stylusでこれ使えば何とかなる
```css
main div > span  {
    line-height: normal !important;
}
```

line-height を normal にして上書きしてあげればたいてい直ると思うのでお試しあれ。
Teamsコネクタの「キーワードが言及された場合」を利用するときの注意点（前編）

:::note info
この記事は、[Power Automate Advent Calendar 2023](https://qiita.com/advent-calendar/2023/powerautomate) 12月1日担当分の記事です。
:::
こんにちは、[たな](https://twitter.com/dreams_panda) です。
Qiita Advent Calendarへの参加ということで、Qiitaで記事を書いていこうと思います。

2023/10/28 に開催された 「[気ままに勉強会 #71](https://kimamani.connpass.com/event/300120/)」 「Teamsコネクタについて④」の回で、[Miyake](https://twitter.com/MiTo60448639)さんにTeamsコネクタの「キーワードが言及された場合」トリガーが日本語のキーワードにも反応することを教えていただきました。

以前は、キーワードを日本語で指定している場合は、反応してくれなかったので、利用用途が広がって嬉しい限りです。

[Miyake](https://twitter.com/MiTo60448639)さんの登壇資料は、「[Teamsコネクタについて](https://speakerdeck.com/miyakemito/teamskonekutanituite-timu-tiyaneru) 」をご参照ください。


:::note warn
2023年11月時点の検証結果です。今後のアップデートで動作が変わる可能性があります点はご注意ください。
:::
# 「キーワードが言及された場合」トリガー

「キーワードが言及された場合」トリガーは、設定したキーワードを含むメッセージが投稿されると実行されます。
コネクタリファレンスには以下のように記載されています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1382111/a26adaf3-48c8-7350-004f-78fe2fd8d993.png)
コネクタリファレンス：[キーワードが言及された場合](https://learn.microsoft.com/ja-jp/connectors/teams/?WT.mc_id=DX-MVP-5005072#%E3%82%AD%E3%83%BC%E3%83%AF%E3%83%BC%E3%83%89%E3%81%8C%E8%A8%80%E5%8F%8A%E3%81%95%E3%82%8C%E3%81%A6%E3%81%84%E3%82%8B%E3%81%A8%E3%81%8D)

## グループチャットの場合
実際のトリガーの設定は以下です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1382111/28c7050a-b588-adc9-6bbc-f76f75ebd20a.png)

## チャネルの場合
実際のトリガーの設定は以下です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1382111/7d5c6666-ac20-332c-81c8-d557d494345b.png)

[メッセージの種類]が「グループチャット」と「チャネル」の場合で、設定する項目が若干異なりますが、どこの投稿内容をチェックするかという設定の違いであり、[検索キーワード]に設定する文字列をどうするかがポイントのようです。


# やってみたかったこと
私は「たな」と呼ばれています。YouTube Liveをみているときに、コメント欄に「〇〇したな」といったコメントが投稿されると、「〇〇し` たな` ー」といったように自分の名前が呼ばれたように協調表示されるのをなんども目撃しています。
日常会話の中で「〇〇したな」というのは結構使われているんですよね。もちろん私もよく使います。

そこで、Teamsでのやりとりで「〇〇したなー」と投稿されたら、「呼んだ？🐼」と自動で返信してみようと思い立ちました。


# 実装してみた
使ったのは「キーワードが言及された場合」トリガーと「チャットまたはチャネルでメッセージを投稿する」アクションです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1382111/6c92bf3d-0800-0f02-027a-bd54ad0d2535.png)
注意：設定が分かりやすいようにクラシックデザイナーでキャプチャしてます。

# 雑談している会議チャットにこっそり仕込んでみた

みんなで雑談してる最中にこっそりこのフローを仕込みました。
誰か「たな」って含まれる投稿しないかなー。ワクワクｗ

・・・じっと待つ・・・・・・・・・・・・・・・・・・・・
・・・・・・・・・・・・・・・・・・・・・・・・・・・・
・・・・・・・・・・・・・・・・・・・・・・・・・・・・
・・・・・・・・・・・・・・・・・・・・・・・・・・・・

<strong>動いた！！！・・・・？？？？？？？？？？？？？？</strong>

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1382111/3b8ecb7b-4df7-b89f-1989-08ddf4c2899f.png)



# なにが起きたのか？
<strong>無限ループしてる？？？</strong>
現在進行形で雑談している会議チャット上で突然始まる「呼んだ？🐼」BOM発動！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1382111/067a21e2-80d8-8fa2-5c4e-59eb4f54c560.png)

怪奇現象発生でチャット上は騒然

さて、みなさん何が起きたかわかりますか？
少し考えてみてください。ヒントは画像の中にあります。

# 解決編
何が起きたのかの解説は「[Teamsコネクタの「キーワードが言及された場合」を利用するときの注意点](https://tana-techlog.net/?p=1104)」をご参照ください。
【SwiftUI】ATTが表示されない問題の解決策

# はじめに
「ATTが表示されない」で検索すると同じ問題で記事を書いてる方が割といます。
それらの記事は`DispatchQueue.main.asyncAfter(deadline: .now() + 1.0)`で遅延実行してATTを表示させてました。
1秒遅延させたら表示されないってことはなかなかないと思いますが、個人的には美しくないと思うので、別の解決策を考えました。

# 原因
おそらく、`applicationState`が`active`になっている時にATTリクエストしないとアラートが表示されないっぽい？です。

`applicationState`の確認方法です。

```swift
func debugApplicationState(mark: String) {
    switch UIApplication.shared.applicationState {
    case .active:
        print("\(mark): active")
    case .inactive:
        print("\(mark): inactive")
    case .background:
        print("\(mark): background")
    @unknown default:
        print("\(mark): @unknown")
    }
}
```

```swift
import SwiftUI

class AppDelegate: NSObject, UIApplicationDelegate {
    func application(
        _: UIApplication,
        didFinishLaunchingWithOptions _: [UIApplication.LaunchOptionsKey: Any]? = nil
    ) -> Bool {
        debugApplicationState(mark: "1") // background

        DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
            debugApplicationState(mark: "2") // active
        }

        return true
    }
}

@main
struct sampleApp: App {
    @UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate

    var body: some Scene {
        WindowGroup {
            ContentView()
                .onReceive(NotificationCenter.default.publisher(for: UIApplication.didBecomeActiveNotification)) { _ in
                    debugApplicationState(mark: "3") // active
                }
        }
    }
}
```

# 解決方法
`onReceive`で`didBecomeActiveNotification`を監視します。
```swift
import SwiftUI
import AppTrackingTransparency

@main
struct sampleApp: App {
    @UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate

    var body: some Scene {
        WindowGroup {
            ContentView()
                .onReceive(NotificationCenter.default.publisher(for: UIApplication.didBecomeActiveNotification)) { _ in
                    ATTrackingManager.requestTrackingAuthorization { status in
                        switch status {
                        case .notDetermined:
                            print("トラッキング許可の有無が未設定です")
                        case .restricted:
                            print("トラッキングが制限されています")
                        case .denied:
                            print("トラッキングが拒否されました")
                        case .authorized:
                            print("トラッキングが許可されました")
                        @unknown default:
                            print("不明な状態です")
                        }
                    }
                }
        }
    }
}
```

# おわり
AppDelegateの`applicationDidBecomeActive`はなぜか実行されていませんでした
なんで？？？笑