OmniAICreator/Qiita-1.07M huggingface dataset:
TkinterのSimpleDialogで戻り値を取得する方法

# 概要

TkinterのダイアログでOKボタンやキャンセルボタンが押された際に、戻り値を取得してその後の処理を変えたい場合があります。
この記事では、SimpleDialogを使って戻り値を取得する方法を解説します。

# 環境

以下の環境で動作を検証しています。

* Windows10
* Python3.11

# SimpleDialogで戻り値を取得する

## 基本の形

以下のコードは`self.var`というインスタンス変数を`self.get_var()`というメソッドで呼び出し元に返す処理を表現したものです。

```Python
from tkinter import simpledialog


class CustomDialog(simpledialog.Dialog):
    def __init__(self, master):
        self.var = False
        super().__init__(parent=master, title="dialog")

    def get_var(self) -> bool:
        """
        ダイアログ上の値を返すメソッド
        """
        return self.var


print(CustomDialog(None).get_var())

```

これを実行し、OKボタンまたはCancelボタンを押すと、`False`がコンソール上に表示されます。

行っていることは単純で`CustomDialog(None)`で`CustomDialog`クラスのインスタンスを作成し、`get_var()`メソッドを呼び出しています。

## OKとCancelで戻す値を変える

次のコードはOKボタンとCancelボタンで戻す値を変える処理を表現したものです。

```Python
from tkinter import simpledialog


class CustomDialog(simpledialog.Dialog):
    def __init__(self, master):
        self.var = False
        super().__init__(parent=master, title="dialog")

    def apply(self):
        """
        OKボタンが押された場合だけに呼び出される
        """
        self.var = True

    def get_var(self) -> bool:
        return self.var


print(CustomDialog(None).get_var())
```

`apply`メソッドは`simpledialog.Dialog`クラスに実装されており、`OK`ボタンを押した際に呼ばれる処理です。
それをオーバーライドします。

このコードを実行するとOKボタンを押した場合は`True`、Cancelボタンを押した場合は`False`と値がコンソールに表示されます。


# 参考

[How do I return a result from a dialog?](https://stackoverflow.com/questions/28443749/how-do-i-return-a-result-from-a-dialog)

[Tkinter - simpledialogのソースコード](https://github.com/python/cpython/blob/main/Lib/tkinter/simpledialog.py)
XpathとXMLについて

# Xpathについて書いてみた

仕事でXpathとXMLって分かる？と聞かれて全く知らなかったので調べてみました。
とにかくIT初心者過ぎて、IT用語全然知らずに仕事してます...
仕事しながら覚えていくスタイルです…:disappointed_relieved:ほんと申し訳ないと思いながら仕事してます。

# まずXpathとは

Xpathは`XML Path Language`の略称。

ツリー構造となっており、XML/HTMLドキュメントからの要素や属性値などを指定するための簡潔な構文です。

```html
<div>
  <food>
    <h1>美味しい食べ物</h1>
       <p>ショートケーキ</p>
  </food>
</div>
```

上記から`美味しい食べ物`を取得したい場合、絶対Xpathの書き方や、
`//`を用いて途中までのパスを省略する短いXpathがあります。

絶対Xpath
```:絶対Xpath
/html/body/div/food/h1
```

短いXpath
```:短いXpath
//food/h1
```

## XMLとは

XMLとは`Extensible Markup Language`の略称
日本語で、`拡張可能なマークアップ言語`といいます。
マークアップ言語とは・・・タグと呼ばれる特殊な文字を使用したもの
　　　　　　　　　　　　＜ｘｘｘ＞　＜／ｘｘｘ＞
HTMLに似ている。
ファイルの末尾に`「.xml」`と付けます。



XMLのメリットは。。。
１.データの意味が理解しやすい
２.拡張性が高い
３.適応力が高い


```xml
<div>
  <food>
    <foodbest>美味しい食べ物</foodbest>
       <cake>ショートケーキ</cake>
       <meet>ハンバーグ</meet>
       <cookie>チョコチップクッキー</cookie>
  </food>
</div>
```

ショートケーキは、ケーキなので<cake></cake>で囲われてる
ハンバーグは、肉なので<meet></meet>で囲われている

となんかわかりやすく自由に名前を付けられます。
データの意味を表し構造化できます。
目で見てデータが何の意味を持っているか一目瞭然。
そして、変更も追加も簡単にできます。
クラス、インスタンス、無名クラスの見分け方

クラス、インスタンス、無名クラスの違いについて少しハマったのでメモ

例えばあるクラスのサブクラスを全て取得したい時は以下のコードで取得できる

```rb
class Hoge
    def self.subclasses
        ObjectSpace.each_object(Class).select { |klass| klass < self && klass.name != "" }
    end
end
```

ここであるクラスが自分のクラスを継承していることを表す条件式が `klass < self` なのだが、このクラスの継承に関する演算子 `<` はインスタンスとクラスで呼び出すとエラーになる

```rb
class Fuga < Hoge
end

p Fuga < Hoge # true

fuga = Fuga.new
p fuga < Hoge # Error
```

最初の subclass method でなぜエラーにならないかというとそれは `each_object(Class)` の部分でインスタンスが除外されているからだ

`ObjectSpace.each_object(klass)` は指定された `klass` と `Object#kind_of?` の関係にある全てのオブジェクトに対して繰り返す、とある（[参考](https://docs.ruby-lang.org/ja/latest/method/ObjectSpace/m/each_object.html)）

実際にインスタンスに対して `kind_of?(Class)` を呼び出してみると

```rb
p fuga.kind_of?(Class) # false
```

Class クラスとは関連がないと判定される

一方で無名クラスというものがあって、これは `Class.new` で作成される名前のないクラスなのだが、これは Class クラスと関連があると判定される

```rb
foo = Class.new(Fuga)
p foo.kind_of?(Class) # true
```

無名クラスの紛らわしいところは、オブジェクトを p コマンドなどで出力するとあたかもインスタンスのようなメモリの番地が表示された出力になることだ

```rb
p fuga # #<Fuga:0x0000000126a2cc00>
p foo # #<Class:0x0000000126a3f260>
```

しかし実際には fuga はインスタンスで foo はクラスである
出力で見分けようと思ったら先頭の `#<Class:` をみて判断するしかない

じゃあClass クラスのインスタンスはどうなるのかと思ったら、こちらは無名クラスと同じ扱いらしい

```rb
bar = Class.new
p bar # #<Class:0x000000012686b240>
p bar.kind_of?(Class) # true
```

確実に見分けようと思ったら `kind_of?(Class)` を呼ぶしかなさそうだ

#### 結論
インスタンスと無名クラスは紛らわしいので注意
確かめたかったら `kind_of?(Class)` を呼んでみれば良い
ChromaDBの完全なチュートリアル

## ChromaDBとは
ChromaDBは、ベクトル埋め込みを格納し、大規模な言語モデル（LLM）アプリケーションを開発・構築するために設計されたオープンソースのベクトルデータベースです。ChromaDBは、LLMアプリケーションを構築するための強力なツールです。高速で効率的で使いやすな特徴を持っています。

## ChromaDBの特徴
- 高速で効率的: ChromaDBは、人気のあるインメモリデータストアであるRedisの上に構築されています。これにより、埋め込みの格納とクエリが非常に高速に行えます。
使いやすさ: ChromaDBにはシンプルで直感的なAPIが備わっており、初めてでも簡単に始めることができます。
- 複数の埋め込みフォーマットのサポート: ChromaDBは、Word2VecやGloVe、FastTextなど、さまざまな埋め込みフォーマットをサポートしています。
- 最近傍探索のサポート: ChromaDBは、指定された埋め込みの最近傍を見つけるために使用できます。これは、セマンティック検索や質問応答などのアプリケーションに役立ちます。
- 増分更新のサポート: ChromaDBは増分で更新することが可能です。これにより、頻繁に更新が必要なアプリケーションに適しています。
- レプリケーションのサポート: ChromaDBは複数のサーバーにレプリケーションでき、高い可用性と耐障害性を提供します。
- ハイブリッドクラウドのサポート: ChromaDBはローカルおよびクラウドの両方で使用することができます。

## ChromaDBの完全なチュートリアル

https://github.com/jingwora/ChromaDB-Tutorial/blob/main

ノートブック: [English](https://github.com/jingwora/ChromaDB-Tutorial/blob/main/01_ChromaDB_Complete_Tutorial-en.ipynb) | [Japanses](https://github.com/jingwora/ChromaDB-Tutorial/blob/main/01_ChromaDB_Complete_Tutorial-ja.ipynb)

- ChromaDB 概要
  - ChromaDBとは
  - ChromaDBの特徴
  - Language Support
  - 環境構築
  - データセット
  - 埋め込み（エンベディング
- ChromaDB 関数
- Clientのメソッド
  - EphemeralClient
  - create_collection
  - heartbeat
  - reset
  - get_collection
  - get_or_create_collection
  - list_collections
  - delete_collection
- コレクションのメソッド
  - add
  - peek
  - count
  - modify
  - get
  - query
  - delete
  - update
  - upsert
- 埋め込み
  - DefaultEmbeddingFunction
  - SentenceTransformerEmbeddingFunction
  - OpenAI

参照:
- Chroma docs: https://docs.trychroma.com/
- api-reference: https://docs.trychroma.com/api-reference
- datasets: https://huggingface.co/datasets/jingwora/unstructured-data-multilingual
(ViTの論文)AN IMAGE IS WORTH 16X16 WORDS:TRANSFORMERS FOR IMAGE RECOGNITION AT SCALE, Alexey et al, 2021のメモ

# [AN IMAGE IS WORTH 16X16 WORDS:TRANSFORMERS FOR IMAGE RECOGNITION AT SCALE, Alexey et al, 2021](https://arxiv.org/abs/2010.11929)
1. Abst
    - Transformerを画像でも使おう
    - 既存のcnnとself-attentionの組み合わせは特殊な処理が多い→なるべく標準Transformerの形を使う
    - 画像をパッチに分割して、Transformerに入れる
    - 大規模データで事前学習するとよい精度が出る
2. RELATED WORK
    - 各ピクセルでself-attentionすると計算量が膨大になる
3. METHOD
    - 流れ
        1. 画像をパッチに分割→1列に並べる
        1. 各パッチをD次元のベクトルに変換
        1. class tokenベクトルを先頭に追加
        1. 各ベクトルにPositional Encodingを追加(1Dでやる、2Dでもあまり効果なかった)
        1. Transformerに入れる
        1. 下流タスクに流す
    - Inductive bias：cnnは局所性とか並進不変とかのバイアスが入ってるが、ViTにはない
    - Hybrid Architecture：生の画像をパッチにする代わりにcnnに通してからやってもok
    - FINE-TUNING AND HIGHER RESOLUTION
        - pretrainより高い解像度でfine-tuneすると精度が上がる
        - ViTは任意長にokなので、パッチサイズそのままで系列増えてもokだが、peが機能しなくなる
        - pretrainの画像サイズでのpeから入力データのpeを補完していれる
4. EXPERIMENTS
4.2 COMPARISON TO STATE OF THE ART
    -  JFT-300Mで事前学習したモデル(パッチサイズ14x14)が強かった
    -  pretrainに必要な計算量も小さかった
4.5 INSPECTING VISION TRANSFORMER
    - 1Dのpositional encofingでも近いパッチが近似するようになっている→2Dのpeがあまり必要ない理由？
a.[]= 0,1 を理解する

みなさんは `a.[]= 0,1` という式を見たときに何が行われているかパッと理解できるでしょうか？

このとき変数 a は `a = []` で初期化されているものとします

エラーが出るって？　そんなことないんです

```rb
> a = []
=> [] 
> a.[]= 0,1
=> 1
```

一点注意で `[]`と`=`の間にはスペースを入れないようにしてください
ピリオド`.`も忘れないで
理由は後述します

`1`ってなんだーと思ったそこのお方、ネタバラシをするとこの式は以下の式と等価です

`a[0] = 1`

配列に値を代入すると代入した値が戻り値として返ってくるのでこの１は配列aの0番目に1が代入された時の戻り値なのでした

しかしそもそもなんでこのような表記が可能なのでしょうか？

それは ruby において配列の要素の代入が Array クラスの**インスタンスメソッドとして定義されている**からです

[公式のドキュメント](https://docs.ruby-lang.org/ja/latest/class/Array.html)を見てみましょう

インスタンスメソッドの枠に `[]=` という項目があり、`self[nth] = val`という形式で `nth 番目の要素を val に設定します` という記載があります

もちろん公式で推奨されている書き方ではないですが、配列の要素の代入はインスタンスメソッドですので、他のメソッドと同様に `.` でチェーンして呼び出しても動きます

引数の `0,1` の部分はそれぞれ配列のインデックス、代入する値を表していて、これは [rubyの実装](https://github.com/ruby/ruby/blob/3dff315ed3e01f54980410008b73c6a838528e08/array.c#L2382C1-L2382C12) を見ればそうなっていることがわかります


```c
rb_ary_aset(int argc, VALUE *argv, VALUE ary)
{
    long offset, beg, len;

    （中略）

    return ary_aset_by_rb_ary_store(ary, offset, argv[1]);
}
```

中身の部分はおいておくとして、引数の順番としては最初に配列のインデックス、その後に値（バリュー）となっていることがわかります

他の言語で配列の要素の代入がどうなっているのかは知りませんが、rubyでこういう書き方ができるのはちょっと意外でした

しかし可読性が悪いのであえてこのような書き方をする機会はまずないと思います
トリビアの一つとして使ってください
DNSについて

# 前書き
- 調べたことをまとめます。

# 用語
- ドメイン名
    - www.yahoo.co.jp や qiita.com など。
- ドメインレジストリ
    - トップレベルドメイン（.com や .org など）を管理する組織。
    - ドメインレジストラが実際に登録作業を請け負う。（そのためドメインレジストリとレジストラは異なる）
    - WHOIS データベースの更新も行う。
- DNSサーバー
    - ドメイン名から IP アドレスを導き出す。
- Aレコード
    - ドメイン名から IPv4 アドレスを見つけるための DNS レコード。
- AAAAレコード
    - ドメイン名から IPv6 アドレスを見つけるための DNS レコード。
- CNAMEレコード
    - ドメイン名に対して別のドメインを紐づける。エイリアス。

# 補足説明
## A レコード
- 以下のコマンドで確認できる。
    ```bash
    $ dig A qiita.com
    ```
    ### 実行結果
    ```bash
    ; <<>> DiG 9.18.12-0ubuntu0.22.04.1-Ubuntu <<>> A qiita.com
    ;; global options: +cmd
    ;; Got answer:
    ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 10025
    ;; flags: qr rd ad; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 0
    ;; WARNING: recursion requested but not available

    ;; QUESTION SECTION:
    ;qiita.com.                     IN      A

    ;; ANSWER SECTION:
    qiita.com.              0       IN      A       35.72.108.153
    qiita.com.              0       IN      A       54.178.239.176
    qiita.com.              0       IN      A       54.150.61.222

    ;; Query time: 19 msec
    ;; SERVER: 172.28.224.1#53(172.28.224.1) (UDP)
    ;; WHEN: Sat Aug 19 08:48:55 JST 2023
    ;; MSG SIZE  rcvd: 84
    ```
- 上記の通り A レコードに対して N 個の IP アドレスが紐づく。

## CNAME
- 以下のコマンドで確認できる。（dig でも表示される）
    www.yahoo.co.jp = edge12.g.yimg.jp ということらしい
    ```bash
    $ nslookup -type=CNAME www.yahoo.co.jp
    Server:         172.28.224.1
    Address:        172.28.224.1#53

    Non-authoritative answer:
    www.yahoo.co.jp canonical name = edge12.g.yimg.jp.

    Authoritative answers can be found from:
    ```
快速创建Excel文件

1 打开注册表（win+r）输入regedit
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2734236/e5ae5c1c-481a-ed21-f172-9149ebfa1b1f.png)

2 指定路径位置
コンピューター\HKEY_CURRENT_USER\Software\Classes\Local Settings\MuiCache\6e\60873476
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2734236/c6988619-3fea-114f-b38a-69dd8bdd34e3.png)

3 寻找「Microsoft Excel ワークシート」文件（文件夹下Ctrl+f）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2734236/f1a011da-e91b-69e8-1fef-f95dd7f4a4b5.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2734236/05de075e-9320-9247-1dd3-0d3a142fed37.png)

4 修改[Microsoft Excel ワークシート]文件名
・[Microsoft Excel ワークシート]→[Microsoft Excel ワークシート(&X)]
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2734236/1a26c3d3-869e-6a8f-5d4c-d31851d74394.png)

5 重启电脑

6 新建excle
鼠标右键→w→x
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2734236/2b3178ff-3f44-4007-2c4a-c82970f5d39c.png)
hEXルーターでIPsec-VPN

# hEXルーターでサイト間IPsecを構築
[MikroTik製hEXルーター](https://mikrotik.com/product/RB750Gr3)で、Site-to-Site IPsecを実現した時のメモ。

## ネットワーク
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/09a26e13-4c03-4a7e-cf26-304dda42c79e.png)
サイト192.168.88.0/24とサイト192.168.89.0/24とを結ぶネットワーク（192.168.90.0/24）をIPsec化する。

## 設定
上記「hEX Router 1」の設定の説明を下記する。今回もGUIベースで、最低限のもの。「hEX Router 2」の設定については省略。

### 接続
hEX Routerの初期値として、Port1(ether1)がWAN、それ以外(Port2-5)がLAN扱いとなっている。ここではそれを踏襲し、192.168.90.0/24をWAN、192.168.88.0/24および192.168.89.0/24をLANとしている。

### IPアドレス
![IPaddress.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/174795e3-45b4-29f4-4856-46a0c72bf3b9.jpeg)
Port1(ether1)に192.168.90.1/24を指定、Port2-5(bridge)に192.168.88.0/24が設定されている。

### IPsec
![IPsecSettingのコピー.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/1dae34cc-3f98-5f78-cfbd-1f01790a3944.png)
IPsecのPeersおよびPoliciesの設定を実施（赤枠）。

#### Peers（接続先）
![IPsecPeer.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/02ace0c1-c261-b710-de29-0bdc61a58258.jpeg)
接続先のWAN側IPアドレス192.168.90.2、事前共有キー(pre shared key)を指定。それ以外は初期値のまま。

#### Policy
![IPsecPolicy.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/836865dc-8d94-57fc-d555-7506d65b41a9.jpeg)
トンネルの対象となるIPアドレス（送信側LAN192.168.88.0/24、受信側LAN192.168.89.0/24）の指定、Tunnelにチェック、SA送信側アドレスとして自身のWAN IPアドレス192.168.90.1およびSA受信側アドレスとしての相手先のWAN IPアドレス192.168.90.2を指定。それ以外は初期値。

### スタティックルート
![StaticRoute.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/06771ec0-bc44-bbfa-3414-f29f0298eb94.jpeg)
受信側LAN IPアドレス192.168.89.0/24向けに、WAN（ether1）を指定する。その他は自動的に設定される。

### Firewall
![FirewallSettingのコピー.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/2fcb65a5-adc5-65bf-de02-83492dc17966.png)
デフォルトとして用意されている、Dropルールを無効化（Disable）する。すべての無効化が必要かまでは未調査（上記の#4のみDisableで十分な気もする）。

## 確立
先ほどの図の青枠のように、「established」と表示される。

That's all.
(UIKit)segueを使わずに遷移させようとしたら、クラッシュしたんだが？

## こんな感じで動いて欲しかった
下のような感じで遷移させたかった。左はMainのView、右はAddView。
１.『右上のプラスボタン』を押す。
２.モーダル遷移でView(AddView)が表示される。
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3232025/a54f6227-597e-d754-14c0-cc06fdd7e841.png)

## １.どんな場面で起こったのか？
『右上のプラスボタン』を押すとクラッシュしてしまった。
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3232025/31250d39-63da-84d5-aa81-e7843a63398d.png)

## 2.クラッシュの内容
**Thread 1: "Storyboard (<UIStoryboard: 0x6000034a7360>) doesn't contain a view controller with identifier 'AddView'"**

『そんなIDを持ったViewControllerはこのstoryboardにはない。』
## 3.問題のコードと、わかっていなかったこと
 ``` swift
    //AddViewへ遷移させるためのボタン。
    //Buttonが置いてあるのはMainのViewController。
    @IBAction func toAddButtonAction(_ sender: Any) {
        let toAddView = storyboard?.instantiateViewController(withIdentifier: "AddView") as! AddViewController
        present(toAddView, animated: true)
      }
        
 ```
* storyboardプロパティって何？？？
* withIdentifierは間違っていないのになぜ？？？
## 4.解決
```swift
  @IBAction func toAddButtonAction(_ sender: Any) {
        let storyboard = UIStoryboard(name: "AddView", bundle: nil)
        let addView = storyboard.instantiateViewController(withIdentifier: "AddView") as! AddViewController
        let nav = UINavigationController(rootViewController: addView)
        addView.delegate = self
        present(nav, animated: true)
    }
```
* まず、storyboardプロパティとは？

https://developer.apple.com/documentation/uikit/uiviewcontroller/1621399-storyboard/

* リファレンスによると、storyboardプロパティはViewControllerの元になるStoryboardだそうです。注意点は今回『右上のプラスボタン』を置いたのがMainのStoryboardだということ。紐付いているのはViewControllerです。
* このViewControllerの中でstoryboardプロパティを使用すると、そのstoryboardプロパティはMainのStoryboardを指します。
* クラッシュしたコードでは、画面をMainViewとAddViewを分けています。そのような場合、ViewControllerのstoryboardにはAddViewが持つIDは反映されないため、クラッシュを起こしてしまったと考えられます。

なので,以下の部分で明示的に名前を指定した後に、.instantiateViewControllerメソッドを使ってあげます。
```swift
//明示的に名前を指定
let storyboard = UIStoryboard(name: "AddView", bundle: nil)
let addView = storyboard.instantiateViewController(withIdentifier: "AddView") as! AddViewController
```
クラッシュは起こさずに遷移してくれるようになりました。

『.instantiateViewController()　』については以下を参照　

https://developer.apple.com/documentation/uikit/uistoryboard/1616213-instantiateinitialviewcontroller
Goのディレクトリ構成の標準について

### GoでWebAPIを作成するにあたり、Goのディレクトリ構成に標準が存在するということで、調べた結果をアウトプットします。




## 目次
1. Goのディレクトリ構成について
2. ディレクトリ構成一覧
3. 各ディレクトリの意味
4. 参考にしたサイト

## 1. ディレクトリ構成について
#### Goのアプリケーションプロジェクトの基本的なレイアウトとなります。<br>Go開発チームによって定義された公式の標準ではありません。<br>これまでの大規模プロジェクトに共通するフォルダ構成になっているようです。


## 2. 一覧
```
┣━Project名/
┃　　┣━cmd
┃　　┣━internal
┃　　┣━pkg
┃　　┣━vender
┃　　┣━api
┃　　┣━web
┃　　┣━configs
┃　　┣━init
┃　　┣━scripts
┃　　┣━build
┃　　┣━deployments
┃　　┗━tests
┗━docker-compose.yml
```

## 3. 各フォルダの意味
### 1. /cmd
#### 本プロジェクトのメインとなるディレクトリになります。<br>本ディレクトリの配下にアプリケーションのディレクトリを作成し、main.goを配置します。
```
┣━Project名/
┃　　┗━cmd
:      ┗━myapp    
:         ┗━main.go
```
### 2. /internal
#### 外部に公開したいくないプライベートなアプリケーションやライブラリのコードを配置します。
```
┣━Project名/
┃　　┣━cmd
┃　　┃   ┗━myapp    
┃　　┃      ┗━main.go
┃　　┃
┃　　┗━internal
┃      ┗━app    
┃         ┗━myapp
```

### 3. /pkg
#### 外部に公開しても良いパブリックなアプリケーションやライブラリのコードを配置します。<br>本ディレクトリは、アプリケーションが小さい場合や本当に必要な場合以外は使用しないでください。
```
┣━Project名/
┃　　┣━cmd
┃　　┃   ┗━myapp    
┃　　┃      ┗━main.go
┃　　┃
┃　　┗━internal
┃　　┃   ┗━app    
┃　　┃      ┗━myapp
┃　　┃
┃　　┗━pkg
```

### 4. /vender
#### 依存関係のある外部パッケージを配置します。<br>Go Modulesを利用している場合は、本ディレクトリは不要です。

### 5. /api
#### OpenAPIやSwaggerの仕様書を配置します。

### 6. /web
#### webアプリケーション固有のコンポーネントを配置します。

### 7. /configs
#### 設定ファイルのテンプレートやデフォルトの設定を配置します。

### 8. /init
#### システムの初期化に必要なファイル等を配置します。

### 9. /scripts
#### 実行したいSQLなどを配置します。

### 10. /build
#### Dockerfileなどのビルドに必要なファイルを配置します。

### 11. /deployments
#### k8sのyamlファイルなどを配置します。<br>docker-compose.ymlなども本ディレクトリに配置します。

### 12. /tests
#### 外部テストアプリやテストデータを配置します。

## 4. 参考にしたサイト
https://qiita.com/sueken/items/87093e5941bfbc09bea8

https://github.com/golang-standards/project-layout/blob/master/README_ja.md
Terraform で Web Apps の送信 IP アドレスを別の Web Apps のアクセス制限に入れてみた

Web Apps や Functions など Azure App Service を基盤としたアプリで送信元の IP アドレスを制限したい場合があります。Azure ポータルからアプリのネットワーク設定にアクセス制限を登録すれば良いのですが、送信元が Web Apps の場合 IP アドレスが 27 もあったりして手作業ではとても辛くなります。そこで、せっかく Terraform を使っているのだから動的に取得した Web Apps の送信 IP アドレスを、別の Web Apps のアクセス制限に入れてみる検証をしてみました。

## 検証用の main.tf を作成

リソースグループと App Service Plan を作り、Web Apps を 2 つ用意します。


```terraform:main.tf
provider "azurerm" {
  features {}
}

variable "prefix" {
  type    = string
  default = "mnrwebfn"
}

resource "azurerm_resource_group" "rg" {
  name     = "${var.prefix}-rg"
  location = "japaneast"
}

resource "azurerm_service_plan" "plan" {
  name                = "${var.prefix}-plan"
  resource_group_name = azurerm_resource_group.rg.name
  location            = azurerm_resource_group.rg.location
  os_type             = "Linux"
  sku_name            = "B1"
}

resource "azurerm_linux_web_app" "web" {
  name                = "${var.prefix}-web"
  resource_group_name = azurerm_resource_group.rg.name
  location            = azurerm_resource_group.rg.location
  service_plan_id     = azurerm_service_plan.plan.id

  site_config {}
}

resource "azurerm_linux_web_app" "fun" {
  name                = "${var.prefix}-fun"
  resource_group_name = azurerm_resource_group.rg.name
  location            = azurerm_resource_group.rg.location
  service_plan_id     = azurerm_service_plan.plan.id

  site_config {
    dynamic "ip_restriction" {
      for_each = azurerm_linux_web_app.web.possible_outbound_ip_address_list
      content {
        ip_address = "${ip_restriction.value}/32"
        priority   = index(azurerm_linux_web_app.web.possible_outbound_ip_address_list, ip_restriction.value) + 200
      }
    }
  }
}
```

`dynamic "ip_restriction"` で、`for_each` を使い送信元 IP アドレスのリストをループします。`priority` では、リストの何番目に値があるかを調べて 200 を足しています。

## 参考

https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/linux_web_app#possible_outbound_ip_address_list

https://developer.hashicorp.com/terraform/language/expressions/dynamic-blocks

https://developer.hashicorp.com/terraform/language/functions/index_function
せんせー、超音速・超音速旅客機ってなに？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194265/2c47de5a-d81a-78f9-53c1-4d31d8398c36.png)

キーンコーンカーンコーン...
授業が始まります

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194265/be1492ca-910f-2708-d0fa-8fcfcf14af73.png)

せんせー、超音速・超音速旅客機ってなに？

# 超音速・超音速旅客機とは

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194265/da229491-9c49-fb7a-a542-417180e256a7.png)

## 超音速って何？

超音速（ちょうおんそく）って、飛行機がとってもとっても速く飛ぶことを言うんだよ。例えば、お手拍子をする時、手をパンッと打つと音がするでしょ？飛行機がその音よりももっと速く飛ぶと、それを「超音速」と呼ぶんだよ。

## 超音速旅客機って何？

超音速旅客機（ちょうおんそくりょかき）は、超音速で飛ぶことができる特別な飛行機です。
この飛行機は、普通の飛行機よりもずっと速く飛べるから、遠くの国へもあっという間に行けます。

## どうやって速く飛ぶの？

超音速旅客機は、特別なエンジンを持っているから、すごく速く飛べます。
それはちょっと、ロケットに似ています。
だから、まるでスーパーヒーローのように、ザーッと飛んでいくんです。

## それはどうしてすごいの？

この飛行機を使えば、遠い国にも早く行けるから、お父さんやお母さんが仕事で遠くに行くときも、
もっと早く帰ってこれるし、遠くの素敵な場所にも早く冒険に行けるんです。

## それはどうして大切なの？

超音速旅客機があると、世界中の人々がもっと簡単に会えるようになるから、
お友達をたくさん作れたり、新しい場所をもっと簡単に旅して学べるから、とっても大切なんです。

# まとめ

このように、超音速旅客機は、超音速で飛べる特別な飛行機で、
それを使うと遠い国へもあっという間に行ける、すごい飛行機なんです。
Javaで「ディレクトリに含まれるファイルやディレクトリの一覧を取得する(Files.list,Files.walk)」の動作を確認してみた

# 概要
Javaで「ディレクトリに含まれるファイルやディレクトリの一覧を取得する(Files.list,Files.walk)」の動作を確認してみました。以下のページを参考にしました。

https://www.javadrive.jp/start/file/index18.html

# 実装
以下のファイルを作成しました。
```JSample18_1.java
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.Files;
import java.io.IOException;
import java.util.stream.Stream;

class JSample18_1{
  public static void main(String[] args){
    Path dirpath = Paths.get("/code/java/file/doc");

    try(Stream<Path> stream = Files.list(dirpath)) {
      stream.forEach(p -> System.out.println(p.toString()));
    }catch(IOException e) {
      System.out.println(e);
    }
  }
}
```
以下のコマンドを実行しました。
```
$ javac JSample18_1.java 
$ java  JSample18_1 
/code/java/file/doc/manual
/code/java/file/doc/memo.txt
/code/java/file/doc/dest.20230814
/code/java/file/doc/dest
/code/java/file/doc/memo.back.20230814
/code/java/file/doc/memo.back
```
以下のファイルを作成しました。
```JSample18_2.java
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.Files;
import java.io.IOException;
import java.util.stream.Stream;

class JSample18_2{
  public static void main(String[] args){
    Path dirpath = Paths.get("/code/java/file/doc");

    try(Stream<Path> stream = Files.walk(dirpath, 3)) {
      stream.forEach(p -> System.out.println(p.toString()));
    }catch(IOException e) {
      System.out.println(e);
    }
  }
}
```
以下のコマンドを実行しました。
```
$ javac JSample18_2.java 
$ java  JSample18_2
/code/java/file/doc
/code/java/file/doc/manual
/code/java/file/doc/memo.txt
/code/java/file/doc/dest.20230814
/code/java/file/doc/dest
/code/java/file/doc/memo.back.20230814
/code/java/file/doc/memo.back
```

# まとめ
何かの役に立てばと。
WSL2のUbuntuがインストールできない



## 事象
初回のUbuntu起動時に以下のエラーが表示され、インストールできない。
`0x80370114`

## 原因
NordVPNのVPN接続が余計な動作をしていた。


## 解決方法
NordVPNのVPN接続を一時的に切断したら正常にインストールできた。
Terraform インストールしてリソース グループ作成するまで

## 準備
[Azure PowerShell を使用して Windows に Terraform をインストールする | Microsoft Learn](https://learn.microsoft.com/ja-jp/azure/developer/terraform/get-started-windows-powershell?tabs=bash)

[Install | Terraform | HashiCorp Developer](https://developer.hashicorp.com/terraform/downloads)

### Path を通す
```
C:\Users\nobukoyamada>terraform -version
Terraform v1.5.5
on windows_386
```


## 本題

[クイック スタート: Terraform を使用して Azure リソース グループを作成する | Microsoft Learn](https://learn.microsoft.com/ja-jp/azure/developer/terraform/create-resource-group?tabs=azure-cli)

### ファイルを用意

```providers.tf

terraform {
  required_version = ">=0.12"

  required_providers {
    azurerm = {
      source  = "hashicorp/azurerm"
      version = "~>2.0"
    }
    random = {
      source  = "hashicorp/random"
      version = "~>3.0"
    }
  }
}

provider "azurerm" {
  features {}
}
```

```main.tf
resource "random_pet" "rg_name" {
  prefix = var.resource_group_name_prefix
}

resource "azurerm_resource_group" "rg" {
  location = var.resource_group_location
  name     = random_pet.rg_name.id
}
```

```variables.tf
variable "resource_group_location" {
  default     = "eastus"
  description = "Location of the resource group."
}

variable "resource_group_name_prefix" {
  default     = "rg"
  description = "Prefix of the resource group name that's combined with a random ID so name is unique in your Azure subscription."
}
```

```outputs.tf
output "resource_group_name" {
  value = azurerm_resource_group.rg.name
}
```


`terraform init -upgrade`

`terraform apply main.tfplan`


## 完成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93824/96e64041-052e-0014-6d49-94036a114bad.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93824/2f121d8d-8da6-2da7-4cb9-fcec0122aee2.png)

## 後片付け

`terraform plan -destroy -out main.destroy.tfplan`

`terraform apply main.destroy.tfplan`

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93824/c72d6ef9-3558-e104-5b27-fc95356a0a86.png)



以上を踏まえ、[クイック スタート: Terraform を使用して Linux VM を作成する - Azure Virtual Machines | Microsoft Learn](https://learn.microsoft.com/ja-jp/azure/virtual-machines/linux/quick-create-terraform) を行えば VM 作成から削除までよろしくできる

はずだが、小細工しないと動かなかった。

[クイックスタート: Terraform を使用して Azure で Linux VM クラスターを作成する - Azure Virtual Machines | Microsoft Learn](https://learn.microsoft.com/ja-jp/azure/virtual-machines/linux/quick-cluster-create-terraform?tabs=azure-cli)

のほか

[TerraformでVM作成（Azure） - Qiita](https://qiita.com/Asano_san/items/90aa39d726f3558b3051) を踏まえ、以下に完成

[Terraform で Linux VM 作成して SSH するまで - Qiita](https://qiita.com/e99h2121/items/00781afec389a8b8e85e)

以上です～
Laravel+Viteのbuildで、画像ファイルやフォントファイルを正しくアセット化する方法

# 概要

Laravel+Viteの環境で本番環境用にJavaScriptやCSSをコンパイルする（``npm run build``）ときに、view（blade）にしか記載されていない画像ファイルが``public/build/assets``フォルダに格納されず、本番環境の画面で正常に表示できない問題が発生します。
これを正しい方法で解決します。

# 問題の詳細

## Viteのbuildの動き

ViteでJavaScriptやCSSをコンパイルするために``npm run build``を実行すると、次のように動作します。

１．``vite.config.js``を読んで、``input:``に記載されているSCSSやJSファイルをコンパイル対象として認識する。以下の例だと、'resources/sass/adminmain.scss'、'resources/sass/frontmain.scss'、・・・といった12個のファイルが対象とみなす。

``` vite.config.js
import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
import react from '@vitejs/plugin-react';

export default defineConfig({
    plugins: [
        laravel({
            input: [
                'resources/sass/adminmain.scss',
                'resources/sass/frontmain.scss',
                'resources/sass/main.scss',
                'resources/sass/oneui/themes/amethyst.scss',
                'resources/sass/oneui/themes/city.scss',
                'resources/sass/oneui/themes/flat.scss',
                'resources/sass/oneui/themes/modern.scss',
                'resources/sass/oneui/themes/smooth.scss',
                'resources/js/oneui/app.js',
                'resources/js/admin.js',
                'resources/js/front.js',
                'resources/js/app.js',
            ],
            refresh: true,
        }),
        react(),
    ],
(後略)
```
２．各対象が必要とする（JavaScriptなら``import``していたり、SCSSなら``@import``や``background-image:url();``で指定されていたり）ファイルをコンパイル対象に含めるためすべてのファイルの中身を確認する。
３．コンパイルした結果のJSファイルおよびCSSファイルと、必要となる画像ファイルを``public/build/assets``フォルダにバージョン付名称で格納する。例えば``resources/sass/adminmain.scss``は``public/build/assets/adminmain-ed6fcaf9.css``などとなる。

## bladeで使う画像の問題

blade内で画像ファイルを参照するときは、
```*.blade.php
<img src="{{ Vite::asset('resources/images/toplogo.png') }}">
```
のように画像ファイルを使うのですが、この画像ファイルはJSやCSSで利用されるわけではないので、Viteのbuild実行のときに存在がわからないことになります。これにより、上記の``resources/images/toplogo.png``は``public/build/assets``フォルダに存在しないファイルとなってしまうので、以下のようにエラーが出てしまいます。
```
Unable to locate file in Vite manifest: resources/images/toplogo.png.
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315589/862ccd7b-e66e-527d-05c2-e82bb340bc94.png)

# 解決方法

この問題の解決方法は公式ページに明記されています。

[Processing Static Assets With Vite](https://laravel.com/docs/10.x/vite#blade-processing-static-assets)

※ネット上を検索すると色々他の方法が見つかったりしますが、他の問題があったり記述方法に環境依存性が合ったりするので、公式記載の方法を採用すべきです。

## JavaScriptにStaticアセットのフォルダを記載する

``vite.config.js``に指定したコンパイル対象のJavaScriptのいずれかに、以下を追記します。

```admin.js
...
import.meta.glob([
    '../images/**',
]);
...
```

これで、``npm run build``後も以下部分でのエラーはなくなります。
```*.blade.php
<img src="{{ Vite::asset('resources/images/toplogo.png') }}">
```
Linuxとは？

# ・目次
[1.はじめに](#はじめに)
[2.OSの仕事](#osの仕事)
[3.OS起動までの流れ](#os起動までの流れ)
[4.最後に](#最後に)


# ・はじめに
　プログラミングの学習していると「つべこべ言わずにLinuxとJavaScriptを学べ」というのをときどき見ます。それを見るたびにしっかり勉強しないとな～と思いつつも<b>Linuxってなにに使える？</b>という感情が交じり、毎回少し齧る程度で終わらせてまとめていなかったのでそれをまとめていきます。

まずLinuxとはWindowsやMacなどと同じく<b>OS（オペレーティングシステム）</b>のことです。

じゃあOSとはなんでしょうか？
OSとは<b>PCのハードウェアとソフトウェアをつなげる役割</b>をしているPCのシステムの１つです。

# ・OSの仕事
OSは
<ul>
<li>
ハードウェアの管理
</li>

<li>
ソフトウェアの管理
</li>


<li>
ファイルの管理
</li>

<li>
ユーザーインターフェース
</li>

<li>
セキュリティ管理</li>
</ul>
の１つの役割を果たしています。
　<br><br>　

<details>
<summary>OSの仕事の詳細</summary>
<div>
まず、OSは<b>CPUを管理してパソコンが行うタスクやその処理の管理</b>をします。これがハードウェアの管理です。<br><br>
　２つ目のOSの仕事は<b>アプリの実行から終了までの流れ</b>を担当することです。これがソフトウェアの管理です。
<br>
<br>
　３つ目の仕事はファイル管理です。ハードディスクなどの記憶装置を管理して<b>ファイルがどこにあるのかなどを示したり、ファイル探しなどの効率化</b>をしています。
<br>
<br>
　４つ目の仕事はユーザーインターフェースです。これは一般的なUIのことではなく、ユーザーが<b>PCを操作できるインターフェース、つまりOSが用意しているユーザーインターフェースのこと</b>で代表例としてコマンドプロンプトがあげられます。
<br>
<br>
　最後の仕事はセキュリティ管理です。これは<b>ユーザーアカウントの管理・アクセス制御・ファイアウォール</b>を担当しています。これの代表例としてはパスコードを入力しないとPCが起動できないあのパスコードをOSが行っています。<br>【※ノートンセキュリティはOSのセキュリティ管理に追加されたOSとは別のソフトウェアのセキュリティ管理です】
</div>
</details>

# ・OS起動までの流れ
　次にどのような流れでPCの処理がされていくかを見ていきます。

まずPCを起動させると<b>BIOS</b>というハードウェアを動かすシステムが作動します。それによりCPUが作動してOSが起動します。OSが起動することによってユーザーがソフトウェアを操作することができるようになります。

# ・最後に
これがおおよそのOSの説明です。

最後に本題に入り、Linuxの話をします。
<b>Linux＝OS</b>の１つです。
つまり、LinuxがPC（コンピュータ）のハードウェアとソフトウェアをつなげる機能を持っていることです。

使用用途としては
Win・Mac＝＞一般的なパソコンのＯＳとして使われいます。
Linux＝＞<b>サーバーのＯＳ</b>として使われています。しかしLinuxはサーバーだけでなく一般的なパソコンのＯＳにも使えます。さらには組込みシステム、ゲームのＯＳなど幅広く使うことができます。

これがLinuxの正体でした。ありがとうございました。
ガバナンスの存在理由

# 前置き
皆さまこんばんは。
実は仕事で今まで扱ったこともないガバナンスのアーキテクチャを考える汎用的プロセスを考えていて、
その道中でいろいろ制約理論など情報を漁っていて気づいたことがあります。

業務フローの中で分岐が走るとこがあると思います。
たとえば図書館とかであれば、返却滞納してたら新しい蔵書を借りることができないとか。
何かしらの【判断】がそこにはあります。

しかし、このルールもともとはなぜできあがったのでしょうか？
それをリスク分析やTOC制約理論を少し学んできた自分なりに推測してみようと思います。


# ルール(規定)の存在理由
ルールは調べてみると以下のように定義されていました。

--引用--
なんらかの目的のための行動や手続きなどに関して定められたこと。
「学校の規則」「就業規則」など。
また「規則正しい生活」「規則的な音」のように、一定の秩序の意味にも使われる。

とあります。
つまり、ルールなくして目的の達成は難しいと考えられるから定義したってことですね。

ではなぜ？？？
ここで自分なりの仮説として、確信しているのが【脅威のリスク】が考えられます。
目的の達成を阻害する予期せぬ事態、それを回避または軽減したいという下心がそこにはあります。

上記であげた図書館とかであれば、
何もルールがなかったらそもそも借りた蔵書を返しにわざわざ来ますかね？

たしかに顔見知りとかから何かものを借りるのであれば、
借りたものを返さなかったことによって発生する【信用】にひびが入りますね。
それを避けたいと思うから、返すという行為をするわけです。

しかしながら、顔見知りでない人たちが管理している蔵書を一定数の人間が返さずに持ち逃げすると何が起きるでしょうか？

ここで一度そもそもの図書館という空間の最上位の目的を考えてみましょう。
図書館は基本的に老若男女問わずに、どなたでも蔵書を借りることができる空間です。

## 仮説
ここでまた完全に仮説になってしまいますが、
わたしは図書館の最上位目的は以下のように類推しています。

【共有する知的財産によって、手に取った人達が互いに異なる観点から対象を観察、
さらにそこで学んだ内容を使って新たな学びの輪を拡げたりや、社会に貢献する知見を身に着けてほしい。
学ぶことを楽しんでほしい。】
といった目的と背景が隠れているように考えました。

だれもが平等に学ぶことが許された空間っていうことです。

しかしながら、タダでモノを貸し与えると一定数持ち逃げするTakerが必ず出てきます。
それによってどんな２次的リスクが起きるかというと、
持ち逃げされた蔵書を本来手にするべきであった人たちの学びのチャンスが減ります。

学びは点と点を繋ぐことによって、単なる足し算ではなく、指数関数的に効果を発揮しますので、
たった１冊失われただけでも、失われた学習効果は１冊当たり底知れない数値(ここではxとします)をたたき出すでしょう。
それを本来持ち逃げされなかったであろう未来で仮に100人借りるはずであったとしましょうか。
失われた損失はどのくらいでしょうか？
単純にxに100かけた100xになるでしょうか？

いえ！そんなことはないです！！
だって同じ蔵書を通じてワークショップとかをやったりすること考えたら、
その100人が学びの輪を広げることによって得られる学習効果は、10000xや下手したら100000000x
とかの数値をたたき出すでしょう。
(ここでは議論の本質ではない、蔵書の人気度とかは無視します)

それがたった１冊持ち逃げされることによって生じる損失の数値なわけです。

それが２冊、３冊なんてなったら、これもまた単なる掛け算ではなく、
２乗、３乗って増加するって考えたら、目的に対しての損失は想像を絶する値をたたき出します。

どう考えても許容できるような数値のリスクではないですね。
よって、軽減処置などの対策が必要なリスクと考えられます。


## 貸出期限という制約
これもまた仮説ですが、仮に貸した人がず～～～っと借りてたらどうなりますかね？
他の人がその間蔵書を借りられないから、その分だけ損失が生まれますね。
だから、１週間などといった制約を設けることによって、平等にみなに知識が行きわたるようにしている。
またこれはエンドユーザ視点になってみて考えても、
「借りたいって思ってた蔵書がずっと借りられてる💦」といった感情を生まないためにもなるし、
仮にまだ存在を認知していないこれから出逢う本とのチャンスにも繋がるので嬉しいものです。


# ルールによるリスク対策
さてさてここまでまとめてみましょう。
業務ルールとして、以下のことが上記のリスクの対策になると考えると理屈が通ります。

まず蔵書を持ち逃げされないために、信用の仕組みとして
・本人確認をする
・滞納して借りている人には貸さない

借りたい人に公平に行き届くように
・期限という制約を設ける
・その期限を守れない信用のない人には貸さない

といったルールです。
つまり、ルールとは本来それがあることによって、ビジネスサイドやユーザサイドが損失を受けない、
それがあることによってむしろ利益を発生させるような概念であることが理想の姿です。


# ルールに対する固定観念
しかしながら、私たちは普段何気なく過ごしている中で、このルールについて深く考えているでしょうか？
それが何のためにあって、そのルールが足かせになってはいないのか？
そのルールを変えてはいけないという変な固定観念の中で生きていないでしょうか？？

ルールとは、本来「なんかよくわかんないけど守らないとダメ」って思考停止して受け入れるものではないです。

確かに守ることによって、回避できるリスクなどがあるから設けている仕組みではありますが、
この不確実性の高い社会においては、一度決めたルールが時間の流れとともに、
負債を生む根本原因となっていることもまた事実のはずです。

しかも暗黙の背景の中で設けられ、何となくみんな従ってるルールなんて私から言えばただのゴミです。
だって意味のないルールなんて何の価値がありますか？

だから見直す必要がある。　
それによってより効率性を高めたりしていけるから、より皆が豊かになれる可能性がある。

次回は、そんなルールに関する仕組みについて自分なりの考察を書き記します。
localhost (127.0.0.1)の自己署名証明書を手っ取り早く作りたい

# 概要
ローカルPCに適当なHTTPSサーバーを立ててテストしたいということはよくあると思います。
HTTPSを使うには自己署名のSSL/TLSサーバー証明書 (いわゆる**オレオレ証明書**)が必要ですが、
いろいろググりながらやったら意外と苦戦したので手順をメモしておきます。

# 作るもの
* `server.key` : 秘密鍵ファイル
* `server.crt` : サーバー証明書ファイル
* `server.csr` : 署名リクエストファイル (中間生成物としてのみ使用します)

OpenSSLを使用して`localhost (127.0.0.1)`に対してサーバー証明書を作成します。
`localhost`でアクセスしても`127.0.0.1`でアクセスしても怪しい警告が出ないようにします。
OpenSSLのインストール方法などはここでは説明しません。

# 手順
1. 以降の作業はすべて同一のディレクトリで行います。最終的に以下のようなファイル構成になります。
    ```
    workdir/
    ├── san.txt
    ├── server.crt
    ├── server.csr
    └── server.key
    ```
1. 以下の内容のファイルを作成して`san.txt`として保存します。
    ```bash:san.txt
    subjectAltName=DNS:localhost,IP:127.0.0.1
    ```
1. 以下のコマンドを実行します。
    ```bash
    openssl genrsa -out server.key
    openssl req -new -key server.key -out server.csr -subj "/CN=localhost"
    openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt -extfile san.txt
1. 出力されたサーバー証明書(`server.crt`)をWindowsの場合は「信頼されたルート証明書」にインストールします。Unix系はわかりません:v:
    参考: https://jp.globalsign.com/support/ssl/config/cert-import-win.html

# 確認
`https://127.0.0.1/`や`https://localhost/`でアクセスしてみて警告が表示されないか確認します。
会社員からフリーランスに転向してみた感想

## 会社員➡フリーランスになって良かったこと:clap:

- 付き合いがシンプルになる:point_up:
会社だから当然なのかもしれないですが、親睦会・歓迎会・忘年会など、組織に属しているからこそ参加せざるを得ないシーンって沢山あると思います。もちろん、会社や所属している組織に思い入れがある場合は苦に思わないかもしれないですが、（特に中小企業～大企業にお勤めの多くは）やはり**自分が誰と飲みに行きたいか**を重視したいですよね。
<INS>フリーランスになると、まず**組織ではなく個人**を優先して考えることができるので、気の合う方だけと、飲みや食事するといったことができますね。</INS>

- 技術トレンドを追いやすい:point_up:
これは、所属会社に依るかもしれないですが、特に金融系や通信系では、昔に開発したフレームワークとか、ずっと保守しているところが多い気がします。（自分がいた現場がそうでした。周りも同じよう環境だったと思います。）一生その現場にいるなら良いですが、そうでないなら、トレンドの技術を使っている所に参画した方が、**高いシェアなので他の会社や現場で使われていることが多いので、経験者として採用されやすくなる**ことが挙げられると思います。
<INS>フリーランスでは、（今は人手不足ということもあって）希望の言語やFWはほとんど叶う印象です。さらにいえば、フルリモートなど働き方も大体叶うかなという感じです。</INS>

- 収入を増やしやすい:point_up:
みなさん気になる所かと思います。よくTwitterとかで月収100万とかみますが、あれは直接企業と契約していたりと中々できる芸当ではないと思います。大体がエージェントを利用すると思いますが、この場合は正直、**会社員とそんなに大差ない**かと思います。ただ、会社員ではどんなに長く勤めてもおおよその上限が決まっていると思います。（これを「安定」または「不満」か解釈の仕方が二手に分かれそうですね。）
<INS>フリーランスでは、技術を磨く・（例えば直接契約を目指し）営業を頑張るなど努力と工夫次第では、どこまでも収入を増やせるといった感じです。</INS>

## 余談

初投稿なので、私のターニングポイントになったところを記事にしてみました。
私自身、フリーランスが性に合っていてとても満足していますが、十人十色とはよくいったもので、中には会社員として働く方が良い方もいらっしゃいます。
<INS>ただ、どちらの選択をするにしても**後悔が残らない選択**が一番大事だと思います。</INS>

今後は、技術周りの話もちょくちょく記事にしていくつもりです。
アプリ開発系がメインになるかなと思います。

では、また次回まで:raised_hand:
DockerでReactホットリロード効かへん

Dockerを使いReactの環境構築して、初期画面をイジっていたら画面が更新されないことに気づきました。

package.jsonを以下のように修正しました。

```javascript:package.json 
"scripts": {
    "start": "WATCHPACK_POLLING=true react-scripts start",
    "build": ...
  },
```
そして、コンテナを再起動するとホットリロード成功！
Dockerのインストール

dockerをインストールして使えるようにするまでをまとめる。
OSはUbuntu20.04 LTSとなっている。
ちなみにdocker-compose はdockerコマンドに統合されたので、dockerをインストールすれば使える！！


# Dockerインストール
```shell
sudo apt update
sudo apt install ca-certificates curl gnupg
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg
echo \
  "deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
  "$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt update
sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
```
# バージョン確認
```shell
$ docker -v
Docker version 24.0.5, build ced0996
$ docker compose version
Docker Compose version v2.20.2
```

# 一般ユーザでコマンド実行を可能にする
Dockerコマンドはsudo権限が必要になるが毎回打つのは面倒なので一般ユーザでもコマンド実行を可能にする。
```shell
sudo groupadd docker
sudo gpasswd -a $USER docker
exit
```
全ての設定が終わったら一度ログインしているターミナルから抜けてもらい再度ログインする。
```shell
$ groups
adm cdrom sudo dip plugdev lxd docker
```
このようにdockerが追加されていることがわかる。
これによりsudoなしでもdockerコマンドが実行可能となる。
達人に学ぶSQL徹底指南書 2章 CREATE, INSERT文まとめ

[達人に学ぶSQL徹底指南書](https://www.amazon.co.jp/%E9%81%94%E4%BA%BA%E3%81%AB%E5%AD%A6%E3%81%B6SQL%E5%BE%B9%E5%BA%95%E6%8C%87%E5%8D%97%E6%9B%B8-%E7%AC%AC2%E7%89%88-%E5%88%9D%E7%B4%9A%E8%80%85%E3%81%A7%E7%B5%82%E3%82%8F%E3%82%8A%E3%81%9F%E3%81%8F%E3%81%AA%E3%81%84%E3%81%82%E3%81%AA%E3%81%9F%E3%81%B8-CodeZine-BOOKS/dp/4798157821)
2章：必ずわかるウインドウ関数

本文中に書かれている内容を実行したかったので、自分用にメモ。
※本のサンプルと行の順序が異なる場合あり

https://www.db-fiddle.com/

## CREATE
``` SQL:
CREATE TABLE LoadSample (
  sample_date varchar(255),
  load_val int
) charset utf8mb4;

CREATE TABLE ServerLoadSample (
  server varchar(255),
  sample_date varchar(255),
  load_val int
) charset utf8mb4;
```

## INSERT
``` SQL:
INSERT INTO LoadSample VALUES
('2018-02-01', 1024),
('2018-02-02', 2366),
('2018-02-05', 2366),
('2018-02-07', 985),
('2018-02-08', 780),
('2018-02-12', 1000);

INSERT INTO ServerLoadSample VALUES
('A', '2018-02-01', 1024),
('A', '2018-02-02', 2366),
('A', '2018-02-05', 2366),
('A', '2018-02-07', 985),
('A', '2018-02-08', 780),
('A', '2018-02-12', 1000),
('B', '2018-02-01', 54),
('B', '2018-02-02', 39008),
('B', '2018-02-03', 2900),
('B', '2018-02-04', 556),
('B', '2018-02-05', 12600),
('B', '2018-02-06', 7309),
('C', '2018-02-01', 1000),
('C', '2018-02-07', 2000),
('C', '2018-02-16', 500);
```
python matplotlibでlabelの文字を変えずに文字サイズを変える

通常以下のように、グラフ作成時に文字サイズを指定できます。
```python
fig,ax = plt.subplots()
ax.plot(range(1,10,1))
ax.set_xlabel("x label",fontweight="bold",fontsize=20)
ax.set_ylabel("y label")
plt.show()
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3328308/82809039-e262-da0b-8415-fe496180da3a.png)

この後にラベルの文字サイズを変えます。
```python
y_label = ax.yaxis.get_label()
print(y_label)

Text(24.000000000000007, 0.5, 'y label')
```

これより、
Text インスタンスが帰ってきてるのがわかりました。
なので、あとは[Textインスタンスに対する処理](https://matplotlib.org/stable/api/text_api.html)として書けます。

いまylabeの設定がxlabelと異なるので、同じにしてみます。

```python
fig,ax = plt.subplots()
ax.plot(range(1,10,1))
ax.set_xlabel("x label",fontweight="bold",fontsize=20)
ax.set_ylabel("y label")

y_label = ax.yaxis.get_label()
y_label.set_fontsize(20)
y_label.set_fontweight("bold")
plt.show()
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3328308/4545134b-ca9a-46ae-e18a-46de9737ae9f.png)

できました～
もちろんこれ以外にもtextインスタンスに行える処理ができます。
技術に興味がなくて何が良い？

## TL;DR
技術に興味がない方が、エンジニアとしての生存可能性が高いかも。技術に興味がないと何が良いのか考えてみた。

## 対象読者
自分を技術に興味がある側の人間だと思う方

## 筆者について
- Webアプリケーション業務システムの開発エンジニア。最近の主な仕事は画面機能設計、内部設計、実装コーディングテストなどの準委任契約に基づく開発支援業務。
- 音楽に興味がある。できれば音楽を職にしたかった。
- 現役時代は、事業責任者として契約獲得、営業提案、要件定義、運用なども行っていた。新卒時の職種はハードウェアエンジニア。

## 初めに
最近のポエムのメガトレンドとして、情報技術者は一般的に自職域の技能に関する興味の度合いが強いらしく、筆者は自覚していなかったが、興味を強く持たねばならない的な同調圧力も世間には相応に存在するようだ。それに反論した記事が大きな反響を巻き起こしている模様。[^1]
そこで、二番煎じというか3匹目のどじょう狙いというか、近いテーマでポエムを書いてみた。


## 「技術に興味があるとエンジニアに向いている」の根拠
これはある程度の地頭の存在が前提となっている論拠のようだ。技術に興味があるからといってエンジニアに向いているとは限らない。

一定以上の問題解決能力は必要だろう。向いているかいないかの必須要件は、興味のあるなしより前記能力のあるなしのがウエイトが大きいとも考えられるが、それぞれの組み合わせの程度というものも存在するだろう。

#### 興味があっても勉強しないこともできる
興味の強さにもよるが、興味があっても完全にスルーすることは可能だ。

## エンジニアであってもビジネスマンでないひとはざらにいる
ここでは自分の技術的な作業や成果物に対してなんらかの経済的な価値の対価を得ている人をエンジニアと定義してみよう。

そして、ビジネスをなんらかの経済的な価値の対価を得ていく営利活動と定義して、ビジネスマンとは性別にかかわらず、そのような活動に従事する人と広い意味で定義しよう。

そしてさらに、狭い意味としてのビジネスマンを、対価が得られることを未確定な状況から確定していく過程に直接関与する人、または自分の活動の前後にはそのような過程が存在していることを認識している人としてみよう。

営利活動の一環としての組織的な業務活動の中で、自分の技能に対して対価を得ているエンジニアは広い意味で無条件にビジネスマンだが、前記狭い意味でのビジネスマンではないエンジニアはざらにいる。

## 趣味のエンジニアになる
そもそも「技術」とか「エンジニア」とか、対象領域はほぼ無限に広く深い。すべての領域、はてはソフトウェアを超えたハードウェアエンジニアリングまで裾野を広げた場合、すべてをカバーすることは事実上不可能だ。

最近は３Ｄプリンタなどの出現により、趣味のハードウェアエンジニアリングも、かなり可能な状態となってきてはいる。しかし、ソフトウェアエンジニアリングのよいところは、かなりミニマムな環境でいろいろ試せることだろう。

完全に経済的な対価を度外視して、自分の興味本位でなにかを実現してみるというのも（あなたの脳にとっては）よいかもしれない。

## 興味があるからこそやらないでみる
筆者の場合は３Ｄプリンタ方面などは、まさにそれである。３ＤプリンタCADソフトウェアとかは実装する気にならない。使う分にはかまわない。

## 最近興味あること
光半導体[^2] とか、アイオン[^3] とか。

## 最後に
ソフトウェア技術が仕事なのにソフトウェア技術に興味がなくて何が良いか考えてみた。（ここまでの論述の中で根拠が直接展開されていない場合があるが）下記の点がメリットとして考えられた。

1)適切な職務パフォーマンスの維持
2)健全なメンタルヘルス・ヒューマンリレーションシップの維持
3)コントロールされたエンジニアライフサイクルの展開

ソフトウェア技術が仕事でソフトウェア技術に興味があったら上記のメリットが実現できないという意味はない。

ただし、ソフトウェア技術にのみ興味が集中する場合は、これらのメリットを失うリスクが相対的に高いような気はする。
反証として、職務パフォーマンスがイノベーションをドライブするような職責の場合はまた別の話であるとも思う。


# 参考リンク
https://www.direct-commu.com/terms/interest/#%E8%88%88%E5%91%B3%E3%81%AE%E6%84%8F%E5%91%B3%E3%81%A8%E3%81%AF


[^1]: Qiita [技術に興味がなくて何が悪い？](https://qiita.com/indigonightism/items/c1bf747bed15e2840936) 参照
[^2]: 正式には光電融合デバイスと呼ばれる。
[^3]: NTTが2030年の実現を目指す次世代通信基盤
PICAXE奮闘記03 I2CタイプのLCDでキャラクタ登録とカタカナ表示に挑戦

今回は前回に引き続きＬＣＤ表示を深めます。
オリジナルキャラクタ登録とカタカナ表示ができるかやってみます。
マクロを取り入れて繰り返し記述の簡素化も取り入れました。

結果出来ました。パチパチ


```vb
'**************************************
'     I2C LCD test Display test 
'	AE-AQM1602A(KIT)
'     *3.1V to 3.5V!! Not use AA battry*3=4.5V
'     (I2C LCD 16 x 2 lines)
'	 for PICAXE 08M2
'**************************************
'	Information of Connection
'		pin1 VCC
'		pin2 serial in
'		pin3 analog in
'		pin4 n.c
'	----
'		pin8 GND
'		pin7 serial out
'		pin6 SCL(10kohm pull up by lcdkit)
'		pin5 SDA(10kohm pull up by lcdkit)
'**************************************
'04 液晶表示に成功
'05 キャラクター登録とカタカナ表示に挑戦


#PICAXE 08M2
#NO_DATA

#macro CaractorSet(Command,Byte0,Byte1,Byte2,Byte3,Byte4,Byte5,Byte6,Byte7)
	hi2cout ($00,Command)
	pause 50
	hi2cout ($40,Byte0,Byte1,Byte2,Byte3,Byte4,Byte5,Byte6,Byte7)
	pause 50
#endmacro

'I2C initialize
hi2csetup i2cmaster,$7C, i2cfast, i2cbyte 'AKIDUKI LCD
hi2cout ($00,$01)	'Clear display
pause 50
hi2cout ($00,$38)	'拡張コマンドOFF
pause 50		'Wait
hi2cout ($00,$0C)	'ディスプレイON カーソルOFF
pause 50		'Wait
hi2cout ($00,$06)	'エントリーモードセット
pause 300		'Wait
hi2cout ($00,$39)	'コントラスト設定を行うため拡張命令ON
pause 50		'Wait
symbol Contrast = 30	'0 - 32 - 63 $00 - $3f 液晶のコントラスト設定値
'定数同士の計算は予め計算されるため、プログラムサイズに影響無し。
symbol ContrastL1 = Contrast // 16
symbol ContrastL2 = ContrastL1 or $70
hi2cout 0,(ContrastL2)	'液晶コントラスト下位指定
pause 50
symbol ContrastH1 = Contrast / 16
symbol ContrastH2 = ContrastH1 or $54
hi2cout 0,(ContrastH2)	'液晶コントラスト上位指定
pause 50
hi2cout ($00,$6C)	'フォロワー制御設定
pause 50
hi2cout ($00,$38)	'拡張命令OFF
pause 50
hi2cout ($00,$01)	'Clear display
pause 50

'Command,Byte0,Byte1,Byte2,Byte3,Byte4,Byte5,Byte6,Byte7
'Command = Set CGRam Address $40,$48
CaractorSet($40,$00,$0A,$00,$04,$00,$11,$0E,$00)'キャラクタ0 スマイル
CaractorSet($48,$04,$0E,$0e,$0e,$1f,$00,$04,$00)'キャラクタ1　ベル

'Displaying Hello world
hi2cout ($00,$80)	'Set DDR Address
pause 50		'Wait
hi2cout ($40,"Volt ﾃﾞﾝｱﾂ",$00,$01)

main:
	READADC10  C.4,w0
	'スケーリング　$3ff(1023)が3500となるようにスケーリング
	let w0 = w0 * 16	'4bit shift(max $3ff0)
	'スケーリング後の値をhigh word　で取得するので 3500($dac) が $dac00000 を $3ff0 で割ってスケーリング定数を得る。
	'1word(16bit) * 1word(16bit)=2word(32bit)
	'** 演算子は計算結果のhigh wordが帰ってくる。
	' $dac0000 = $3ff0 * x
	' x = $dac0000/$3ff0 = $36bd
	let w0 = w0 ** $36BD	'high word return
	'これで$3ffの時に$dac(3500)となる。正確には3499
	bintoascii w0,b6,b5,b4,b3,b2	' convert to ascii
	hi2cout ($00,$c5)	'Set DDR Address
	debug			' debug values for testing
	'最上位桁のゼロサプレス処理
	if b6 = "0" then
		b6 = " "
'		if b5 = "0" then
'			b5 = " "
'		endif
	endif
	hi2cout ($40,b6,b5,".",b4,b3,b2,"V")
	pause 200		'wait 0.2sec
	goto main
end
```
![IMG_0143.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2606106/d804c98a-69cc-f782-c866-b3341c0b72d6.jpeg)

スマイルとベルのマークはソフトから登録したものです。
カタカナはプログラム上にカタカナ記述するだけで表示出来ました。
![IMG_0144.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2606106/8b9d6d72-7832-7e13-de2a-525d247069ea.jpeg)

![IMG_0145.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2606106/f3192a7f-214d-dcc7-a909-e41fe82e5f30.jpeg)

SDA,SCLのプリアップ抵抗を有効にするため、２カ所はんだブリッジが必要です。
【React】パスワードの表示・非表示を切り替える

## 実装方法

```tsx:PasswordInput
import ToggleRevealButton from './ToggleRevealButton'
import useToggleRevealButton from './ToggleRevealButton/useToggleRevealButton'
import { InputProps } from '../Input'
import LabeledInput from '../LabeledInput'

type Props = Pick<InputProps, 'register' | 'errors'>

export default function PasswordInput({ register, errors }: Props) {
  const { isRevealed, toggleReveal } = useToggleRevealButton()
  return (
    <LabeledInput
      label="パスワード"
      type={isRevealed ? 'text' : 'password'}
      register={register}
      suffixIcon={
        <ToggleRevealButton isRevealed={isRevealed} onClick={toggleReveal} />
      }
      errors={errors}
      autoComplete="current-password"
    />
  )
}
```

```tsx:ToggleRevealButton.tsx
import { EyeIcon, EyeSlashIcon } from '@heroicons/react/24/outline'
import IconButton from '@/components/Buttons/IconButton'

type Props = {
  isRevealed: boolean
  onClick: () => void
}

export default function ToggleRevealButton({ isRevealed, onClick }: Props) {
  return (
    <IconButton type="button" onClick={onClick}>
      {isRevealed ? (
        <EyeSlashIcon className="h-5 w-5" />
      ) : (
        <EyeIcon className="h-5 w-5" />
      )}
    </IconButton>
  )
}
```

```ts:useToggleRevealButton.ts
import { useCallback, useState } from 'react'

export default function useLoginForm() {
  const [isRevealed, setIsRevealed] = useState(false)

  const toggleReveal = useCallback(() => {
    setIsRevealed((prev) => !prev)
  }, [])

  return {
    isRevealed,
    toggleReveal,
  }
}
```
「型」という言葉の定義

「型」という言葉は話者と文脈によって異なった意味で使われることがあります。型理論の研究者などは下の定義 1 のみを「型」と呼ぶので注意しましょう。

- **定義 1**: 型システムによる静的検証のためにプログラム内の式や文などの構成要素を分類する概念
    - 例文: Boolean 型を持つ式を函数として適用するコードを書いたので型エラーが発生した。
    - 例文: Ruby は型のない言語だ。
    - 注意: 定義 1 は俗に「静的な型」「コンパイル時の型」と呼ばれることがあるが、コンパイルの有無は定義とは特に関係がない。
- **定義 2**: プログラムが取り扱う情報(の特定の部分集合)の範囲や意味
    - 例文: 整数型の値同士は足し算や掛け算ができる。
    - 例文: 一般的なプログラミング言語は整数型の他に実数型や真理値型も扱える。
- **定義 3**: どのような型 (定義 2) の値をどのようなビットやバイトの並びとして表現するかというデータの形態・形式の定義
    - 例文: Java の int 型は $-2^{31}$ から $2^{31}-1$ までの整数を 2 の補数表現で表す 4 バイトの型だ。
    - 例文: C では代入時などに暗黙の型変換が行われることがある。
- **定義 4**: 一部のプログラミング言語において、構築したい[第一級オブジェクト]の型 (定義 3) やそれに対して実行できる操作を定義する、プログラム内の構成要素
    - 例文: C++ では class や union を使って新しい型を定義できる。
    - 例文: C# では struct は値型を、class は参照型を定義する。
- **定義 5**: プログラム内の特定の[第一級オブジェクト]を生成するのに使われた型 (定義 4) が何だったかという情報
    - 例文: Ruby では全てのオブジェクトが実行時型情報を持つ。
    - 例文: Java の instanceof 演算子は実行時にオブジェクトの型を検査する。
    - 注意: 定義 5 は俗に「動的な型」「実行時の型」と呼ばれることがある。ただし、言語仕様や処理系の性能によっては型を使う計算がプログラム実行前に完結している事もありうる。
- **定義 6:** プログラム内のそれぞれの[第一級オブジェクト]がどのようなプロパティやメソッドを持っているかというデータ構造
    - 注意: 定義 6 も俗に「動的な型」「実行時の型」と呼ばれることがある。英語では shape などと呼ばれることがある。
    - 例えば JavaScript ではクラスのような型 (定義 4) を用いなくてもオブジェクトごとに固有のプロパティやメソッドを定義できる。 `foo.bar` という式はオブジェクト `foo` が持つプロパティ `bar` へのアクセスを試みる意味論を持つが、その評価結果は実際にオブジェクトがプロパティを持っているかどうかによって変わる。プロパティやメソッドが存在しない場合に評価結果が特殊な値 (`undefined`) になったり例外が送出されたりするような挙動を好ましくないものとして排除したいという文脈において、俗に以下のような言い回しがされることがある。
        - 例文: JavaScript では実行時にオブジェクトの型が検査される。
        - 例文: 函数に渡したオブジェクトの型が合っていなかったので例外が発生した。

[第一級オブジェクト]: https://ja.wikipedia.org/wiki/%E7%AC%AC%E4%B8%80%E7%B4%9A%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88
SQL Serverで複数テーブルを一括で削除したい

# 1. はじめに
* SQL Serverのデータベース内の複数テーブルを一括で削除したい
* SQL Server Management Studioを使用してGUIから実施したい

# 2. 開発環境 
* SQLServer 2017
* Microsoft SQL Server Management Studio v18

# 3. テーブル削除手順
## 3.1. SQL Server Management Studioを起動してログインする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2852081/28474bec-9639-0726-0564-ce9290a8e3b8.png)

## 3.2. 表示 > オブジェクトエクスプローラー詳細を選択する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2852081/baf1a0df-503a-2bdc-30ed-3fbfa294a815.png)

## 3.3. 削除するテーブルを選択して、右クリックから削除を選択する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2852081/40c12ec0-26fb-0b86-7ec0-cebdb781b88a.png)


## 3.4. OKボタンをクリックして削除する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2852081/08487d90-1945-04be-89d1-e879ad116d8a.png)

# 4. 参考文献

https://sql55.com/sql-server/how-to-delete-multiple-tables-at-once-using-sql-server-management-studio.php
【2023年8月】tweepyで動画付きツイートをする方法

# TL;DR
v1とv2を両方使い、アップロード、ツイートを行う(らしい)

## 以下サンプル

```python:
import tweepy

# 認証
api_key = ""
api_secret = ""
access_token = ""
access_token_secret = ""

def get_twitter_conn_v1(api_key, api_secret, access_token, access_token_secret) -> tweepy.API:
    """Get twitter conn 1.1"""

    auth = tweepy.OAuth1UserHandler(api_key, api_secret)
    auth.set_access_token(
        access_token,
        access_token_secret,
    )
    return tweepy.API(auth)


def get_twitter_conn_v2(api_key, api_secret, access_token, access_token_secret) -> tweepy.Client:
    """Get twitter conn 2.0"""

    client = tweepy.Client(
        consumer_key=api_key,
        consumer_secret=api_secret,
        access_token=access_token,
        access_token_secret=access_token_secret,
    )

    return client


client_v1 = get_twitter_conn_v1(api_key, api_secret, access_token, access_token_secret)
client_v2 = get_twitter_conn_v2(api_key, api_secret, access_token, access_token_secret)

media_path = r"C:~~.mp4"

media = client_v1.media_upload(filename=media_path, media_category="tweet_video")
media_id = media.media_id

client_v2.create_tweet(text="Tweet text", media_ids=[media_id])
```


こちら必ず指定してあげてください。

```python:
media_category="tweet_video"
```

誰かのお役に立てれば...

##### 参考
https://stackoverflow.com/questions/70891698/how-to-post-a-tweet-with-media-picture-using-twitter-api-v2-and-tweepy-python

https://twittercommunity.com/t/large-file-can-not-be-finalized-synchronously/82929