OmniAICreator/Qiita-1.07M huggingface dataset:
【K8s】Cert-managerでDNS-01のACME認証をする話


今回はUniProのK8sとCloudflareを連携させて、DNS経由でLet's Encryptから証明書を取ってくる話です。

Cloudflareへの登録等に関しては、以下の記事で取り扱っているので、よければご覧ください。

https://qiita.com/yuito_it_/items/c8a1f441dca784725781

## 動機

HTTPでCert-managerを使用すると、.well-knownのディレクトリがNextJSの404ページになってしまい、非常にめんどくさかったんですよね...
なので、DNS経由でのACMEを用いれば幸せになれるなぁと思ってやってみました。

## 仕組み

ACMEの認証フローはこんな感じです。

1. CertmanagerがLet's Encryptからトークンをもらってくる
2. CertmanagerがCloudflareのAPIを叩いてDNSレコードを作成する
3. Let's EncryptのDNS-01のACME認証を通す
4. 証明書を受け取り次第、CloudflareのAPIを叩いてDNSレコードを削除する

要は**CloudflareのAPIを叩くための設定**さえやっとけば大体はOKですね。
では、やってみましょう。

## Issuerをたてる

ClusterIssuerにDNS01で使う設定を色々していきます。

```yaml
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: le-cf-staging
spec:
  acme:
    email: webmaster@mail.uniproject-tech.net
    privateKeySecretRef:
      name: uniproject-tech-cluster-issuer-secret
    server: https://acme-staging-v02.api.letsencrypt.org/directory
    solvers:
      - dns01:
          cloudflare:
            apiTokenSecretRef:
              name: cloudflare-api-token-secret
              key: api-token

```

### 解説

```yaml
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: le-cf-staging
spec:
  acme:
    email: webmaster@mail.uniproject-tech.net
    privateKeySecretRef:
      name: uniproject-tech-cluster-issuer-secret
    server: https://acme-staging-v02.api.letsencrypt.org/directory
```

ここまではいつも通りですね。

```yaml
    solvers:
      - dns01:
          cloudflare:
            apiTokenSecretRef:
              name: cloudflare-api-token-secret
              key: api-token
```

ここで**CloudflareのAPIを叩くための認証情報があるSecretを指定しています**。
この場合だと、cloudflare-api-token-secretのapi-tokenから持ってきていますね。

ちなみに、Cert-managerはCloudflare以外にもいろんなDNSプロバイダーをサポートしています。

- ACMEDNS
- Akamai
- AzureDNS
- CloudFlare
- Google
- Route53
- DigitalOcean
- RFC2136

## Secretを作る

これを、ClusterIssuerと同じnamespaceに置きましょう。

```yaml
apiVersion: v1
data:
  api-token: <base64 encoded API token>
kind: Secret
metadata:
  name: cloudflare-api-token-secret
```

### 解説

APIトークンはCloudflareのダッシュボードから持ってきます。

![cf-token-menu.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3342262/c8a0528f-19c5-8061-a97b-94afaa3a42a1.png)

ここで、作成、テンプレからDNSを選ぶと、とても便利です。
今回はアカウント全体にしました。

![cf-token-template.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3342262/a398b385-6f81-8f3e-4bb2-f79170e31e22.png)

あとは、セットして使ってみるだけです。

## まとめ

今回はDNS-01でACMEを使い、Cert-managerでSSL証明書を取ってくるまでをしました。
だいぶ便利なので、皆さんもやってみてください！！

## 参考文献

https://cert-manager.io/docs/configuration/acme/dns01/
API 検証で便利そうなソフト Postman を Ubuntu にインストールする

# はじめに
みなさんは API のレスポンス確認など、何を使用しているだろうか？
私は chrome や firefox などに直接リンクを入力してレスポンスを確認していた。しかし、API のレスポンス確認で便利そうなソフトを教えてもらったので、インストールして使ってみた。


# Postman のインストール
```sh
# このコマンドでインストールできる
sudo snap install postman
```
Show Application 内にこのアイコンがあればインストールは成功している。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2348896/8fd64570-51d9-d3ff-6bf0-bcef6915004e.png)


# 開いてみる
Postman を使用するのにアカウント登録が必要なのでアカウントを登録する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2348896/7ab46abb-b997-b927-975e-1018b95cc89c.png)

実際に開くとこんな感じ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2348896/031ffa4d-346e-575e-0941-ef4d2bd401d0.png)


# 使ってみる
実際に Google のリンクを叩いてみる
左側の `Collections` タブ内に `Collection` を作成し、その中に `Add request` を押してテスト用のリクエストを作成する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2348896/472a4b22-3e75-2df0-4cb1-291a7e885158.png)


### request を開いて実際に設定してみる
リンクを入力できる場所があるので、そこに Google のリンクを入力し、検索用のパラメーター `q=` を設定してみる。そして設定できたら `Send` を押してリクエストを送信する。
すると、下部にレスポンスが表示される。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2348896/205f0769-1d5f-161e-aa31-fab6ef0bfe88.png)

この設定はリクエストごとに保存しておけるので、何度も API を叩く開発陣が使用するのにすごく便利である。


### 環境変数を作って使ってみる
この設定がメチャクチャ便利。API の実装ではステージング環境と本番環境などに分け、テストしてから本番に反映するといった工程を取ると思うが、ドメインを変えるのがめんどくさい！など思ったことがあるだろう。
しかし、この環境変数を使用することで、ワンクリックで検証環境を変更できる。

使い方は `Collection` 内の `Variables` もしくは 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2348896/8978c593-d8cb-913b-7027-e0f5dcb29ea5.png)

`Environment` タブ内の環境を選択する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2348896/60215a47-7795-3f32-7b42-3304da7cc801.png)

ここではそれぞれ、`変数名` / `初期値` / `現在値` を設定することができる。
例として `Collection` 内の `Variables` に変数をセットしてみた。

これを先程の `request` で使用してみると、このような形で表記することができる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2348896/de6bacc2-ab79-d0b8-20eb-5cc3c56adf72.png)

このように変数化すると、使いまわすときや環境を変えるときにわざわざ同じ文字列を入力せずにすむ。

`Collection` 内の `Variables` に設定すると効果範囲はその `Collection` 内の `request` のみ。
`Environment` に書くとその `Workspace` 全体に効果がかかる。
また、`Environment` は右上の `"No Environment"` と書かれたところから設定できるので、全体の環境を切り替える場合はこちらのほうが便利かもしれない。


# 参考
https://tutorialcrawler.com/ubuntu-20-04にpostmanをインストールする方法/

https://qiita.com/knidik3/items/b5019b8289417fa1716a
【Advent Calendar 2024 #4日目】AWS学習〜生成AI/ML編〜 Amazon Bedrock

# はじめに

本記事は、「初めての一人アドベンドカレンダー2024 by hohe」の4日目の記事となります。
Advent Calendar 期間中は、AWSの生成AI/ML関連を中心に記事を投稿していきます。
4日目は前回に続き、Amazon Bedrockについてまとめます。

# Amazon Bedrock
Amazon Bedrock は、単一のAPIを介して大手AI企業からの高性能な基盤モデル(FM)を選択できるフルマネージドサービスで、セキュリティ、プライバシー、責任あるAIを備えた生成AIアプリケーションを構築するために必要な幅広い機能を提供します。

https://aws.amazon.com/jp/bedrock/

### RAG
RAGとは、Retrieval-Augmented Generation (検索拡張⽣成)のことで、ユーザーからの問い合わせに対して社内⽂書検索エンジンなどから関連情報を検索し、取得された関連情報も含めてモデルに⼊⼒し回答を得ることができます。このRAGの機能をBedrockではナレッジベースとして提供している。


### ガードレール
ユーザーが入力したテキストや生成AIからの応答テキストに意図せず有害な言葉・内容または機密情報がが含まれている場合の問題を回避するための機能

|ガードレールのコンポーネント|詳細|
|---|---|
|コンテンツフィルター|「憎悪、侮辱、性的、暴力、不正行為、プロンプト攻撃」に対する対して、コンテンツフィルタリングを行う|
拒否されたトピック|アプリケーション開発者が指定したトピックの会話が行われないようにする|
ワードフィルター| AWSが用意する冒涜的な言葉のリストに基づいた「冒涜フィルター」または特定の単語やフレーズを指定して、フィルタリングを行う|
機密情報フィルター|会話に含まれる機密情報をブロックまたはマスクを行う|

### エージェント 
独自データやビジネスロジックの組み込み、システム連携がおこなえる自律エージェントを構築および設定できる。
pythonを使ってxmlデータ解析をする

# xmlデータ解析
プロジェクト業務で膨大なxmlデータを解析してほしいと依頼があり、先輩からのサポートのもと実装してみたのでその時覚えたこと、躓いたことなんかを記事にまとめます。

:::note warn
本記事は誤りが多い可能性大です。
気になったら部分はご指摘いただけると幸いです、、
:::

# ElementTreeによるxml解析
pythonには様々なフレームワークが用意されています。
今回はその中でも標準ライブラリである、**ElementTree**モジュールを使った解析をしてみました。

### ElementTreeとは？
xml解析ができるライブラリです。
xmlのデータ構造を木構造に見立ててパースして、データの探索や操作なんかができるようになります。

参考文献：[PythonでXMLを処理する — 【完全解説】ElementTreeモジュールの使い方](https://challenge-pg.com/2024/02/10/python-xml-read/)

使い方自体は簡単で専用のモジュールをimport宣言してあげるだけです。
```python:test.py
import xml.etree.ElementTree as ET
```
※「as ET」の部分はエイリアスです。
　あっても無くても良いですが、あった方が実際使うときコードの記載が短くできたりするので便利です。
　無い場合は後述するメソッド使用宣言「ET.~」の部分を「xml.etree.ElementTree.~」とする必要があります。

### 使い方
使い方は色々あるみたいですが、自分がよく使う手順を大きく分けると以下の通りです。
- xmlファイルをパース
- rootタグを設定
  - xmlデータを操作する際の起点となるタグを探索
- root下の指定のタグを探索
  - メソッドを使って指定の属性やその値が存在するか探索

### コード例
**・xmlファイルをパース**
```python:test.py
tree = ET.parse("パースしたいxmlファイル名")
```
**・rootタグを設定**
```python:test.py
root = tree.getroot()
```
**・root下の指定のタグを探索**
```python:test.py
tag = root.findall(".//'探索したいタグ名'")
```
探索するメソッドが**findall**です。同じく探索用に**find**メソッドというのもあるので用途に合わせて使い分けます。
2つの違いは以下の通りです。
- findall
    - 指定したタグを全て取得する
- find
    - 最初に見つかったタグだけを取得する

xmlデータによってはブロックが細分化され、ブロック別に同名属性が複数存在するケースがあると思います。
その対象全てを取得したければfindall、最初の要素だけ取得したければfindといった用途で分けて使います。

因みに、「(".//'探索したいタグ名'")」の「/」が1つか2つかによっても探索範囲が異なるので注意が必要です。
- /の場合
    - root直下のタグだけを検索
- //の場合
    - root以下全てのタグを再帰的に検索

# 終わりに
取り急ぎ自分が使ってみた際躓いたポイントなどをまとめてみました。
今後も気づいた事があれば別記事などでまとめていこうと思いますので気になったら見に来てください。
よくあるエラー8個

# Python よくあるエラー一覧

## 1. SyntaxError: invalid syntax
- 構文の誤り（カンマ、括弧、コロンの欠落等）
```python
# 誤
if True print("Hello")

# 正
if True: print("Hello")
```

## 2. NameError: name '変数名' is not defined
- 未定義の変数/関数の使用
```python
# 誤 
print(value)

# 正
value = 42
print(value)
```

## 3. TypeError: '型' object is not callable
- 関数として呼び出せないオブジェクトの使用
```python
# 誤 
list = [1, 2, 3]
list()

# 正
my_list = [1, 2, 3]  
print(my_list)
```


## 4. IndexError: list index out of range
- リスト範囲外のインデックス参照
 ```python
# 誤
arr = [1, 2, 3]
print(arr[3])

# 正
arr = [1, 2, 3]
if len(arr) > 3:
    print(arr[3])
```
## 5. KeyError: 'キー'
- リスト範囲外のインデックス参照
 ```python
# 誤
data = {"name": "Alice"}
print(data["age"])

# 正
data = {"name": "Alice"}
print(data.get("age", "Key not found"))
```

## 6.AttributeError: 'オブジェクト' object has no attribute '属性名'
- 存在しない属性/メソッドの呼び出し
 ```python
# 誤
str_value = "hello"
str_value.append("!")

# 正
str_value = "hello"
str_value += "!"
```


## 7. ValueError: invalid literal for int() with base 10
- 不適切な型変換
 ```python
# 誤
value = int("hello")

# 正
value = "42"
if value.isdigit():
    print(int(value))
```


## 8. ZeroDivisionError: division by zero
- ゼロ除算
 ```python
# 誤
result = 10 / 0

# 正
denominator = 0
if denominator != 0:
    result = 10 / denominator
else:
    print("Cannot divide by zero")
```
ケムリクサと22世紀のマーケティング

## ケムリクサを知っていますか？

みなさんは「ケムリクサ」をご存知ですか？

たつき監督がてがけた2019年のアニメです。

この作品がどのようなものかということについては、是非視聴した上で判断してもらいたいですが、この作品のテーマの1つは「好き」であると私は思っています。

当時のネットでも言われていましたが、"KEMURIKUSA"のアナグラムは"MAKE UR SUKI"、つまり「あなたの好きを為せ」です。

…5年も前のアニメを語る理由は、私の好きを語るのと同時に、これからのマーケティングについての私の妄想と、なぜ技術・組織・ビジネス・哲学に私が心血を注いでいるかの理由を述べたいからです。

そのためには、まず、お金もしくは通貨のお話をしようと思います。

## お金の歴史

通貨には3つの機能が存在すると言われています。

1. 交換手段: 財と交換することで取引を可能にする
1. 計算単位: 財の価値を表すための尺度
1. 価値貯蔵手段: 将来のために保有し続けられる(購買力を将来に移す)

これら3つの機能を果たしてきた通貨は、現在のような法定通貨が出る以前からありました。黒曜石、青銅、鉄、銀、コイン、米、さらに、金本位制だった時の貨幣もあれば、今のように租税を担保に発行されるものもあります。

そして、これらは手元に少なくなっていくものが、貨幣の機能をより多く有することになっていきました。よって、手に入りやすいものは価値が減少し、手に入りにくいものはより価値が上昇しました。今、黒曜石や青銅の通貨としての価値というのはほとんどないので、想像に難くないでしょう。

そして、貨幣は一方的に増えるもので、市場や制度が変わらない限り、価値は下がり続けることになります。そして、いずれは別のより価値のあるものに取って代わられてしまいます。

その次の通貨がなんなのか。それは「あなたの「好き」」だと私は思っております。

## これからのマーケティング

22世紀にあるであろう、これからのマーケティングはマス(大衆)を対象にするところからミクロ(ニッチ)に行くというのが私の予想です。

### バルミューダは天才

バルミューダフォンはエンジニアの人からすると、ひどいものだと思うかもしれません。

しかしながら、バルミューダのトースター等については、あのマーケティング手法は素晴らしいです。

「トースターなんてどこも一緒」、「使えれば十分」、というのが多くの、マスの意見でしょう。しかし、バルミューダは違って、「ダイニングテーブルの上にダサいトースターがあるのは絶対に許せない」、という少ない、ミクロの、ニッチな意見を追いかけたのです。

自分の好きなもの、そして、それに共感してくれる人、この狭いニッチな領域をターゲットにマーケティングをしたのです。そして、あの成功が成し遂げられたのです。

大事なのは、自分の「好き」を追求することです。

今後、世界がどうなっていくか、労働人口がどうなっていくか、世界の賃金格差がどうなっていくか、これらはわからないですが、人間の「好き」という感情は絶対残り続け、そして、それを追い求める人たちはずっといます。

この「好き」こそが、現在の法定通貨に取って代わる、新たな貨幣・通貨へと、本当に価値あるものへと変わっていくと私は予想しています。

そして、そのための22世紀のマーケティングは、マスではなくミクロへ、ニッチへと行くと思っています。

### なんか知らんが　心が動く　あなたのそれは　なんですか？

この新たな時代のマーケティングのためにやるべきことは、繰り返し述べるようですが、あなたの「好き」を追求することです。そして、それに共感してくれる、同じ思いを持ってくれる人、彼らに価値を提供することです。

その上で、聞きます。

「なんか知らんが　心が動く　あなたのそれは　なんですか？」(金野火織の金色提言 / DJ TECHNORCH feat. 宇宙★海月)

そう、あなたが「好き」なもの、あなたの心をグイグイ惹きつけて離さないものはなんですか？

技術ですか？　ビジネスですか？　マネジメントですか？　それともそれ以外のなにかですか？　もっと細かいニッチなものかもしれません。

それを忘れてはいけませんし、それを追いかけるのを諦めてもいけません。

22世紀の市場においては、それを追求できる人しか生き残れない可能性を、私は大いに見出しています。

だからこそ、私は、自分の好きな、自分の心を離さない、技術・組織・ビジネス・哲学に心血を注いでいるのです。たとえ、その中の領域において、私の興味範囲がニッチであったとしても、ホットでなかったりトレンディなかったりしても、追求し続けるのです。

## Tease

前回の記事では、「自分が学習することにおいて、一番マーケティングすべき対象は自分である」、と私は述べました。

この主張も、今回の記事の内容にある「好き」というところを大事にするところから始まります。

そして、次回や最終回では、私の好きな、"Philosophy of Computer Science"と「データモデリングでドメインを駆動する」について話そうと思います。

それでは

## Appendix

弊社matsuri technologies株式会社では多数募集枠を用意しております。以下のHERPからぜひ、お気軽にお問い合わせください。

https://herp.careers/v1/matsuritech
Azure: App Service の kudu での新しい GUI (newui) なら、ファイルアップロードもD&Dで出来て便利 

# 背景

kudu でファイルアップロードが面倒だと思ってたら、簡単に出来る方法が、newui で対応されていた :sunglasses: 

Portal からだと直接リンクが見つかってないので、
kudu を起動したら、末尾に <code>newui</code> を付加して接続してみましょう
※Internet-facing, Internal は若干相異有 

> https://{app-name}.scm.azurewebsites.net/newui

::: note warn
newui endpoint is only available for App Service on Linux
:::


詳細は以下で紹介されていました。

https://techcommunity.microsoft.com/blog/appsonazureblog/new-kudu-ui-for-app-service-on-linuxpreview/3212270

## 新旧比較

newui の特徴としては

- 左側にナビゲーション用サイドパネル追加
   - Linuxの場合、上に有ったメニューが左側に行った感じ  
- 分類の変更
   これによって、どこを確認したいか？によって選びやすくなったんじゃないかな

    - Environment/REST API/Browse Directory
    - App Essentials/Deployments/Web App Container

![2024-11-21_09h14_46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1645569/ab8ad89f-6a82-6107-fed3-d02dd93982fd.png)

## newui での便利そうな事

### インスタンス切り替え

![2024-11-21_09h41_47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1645569/ecd00184-7239-b7f7-597d-89acbde42c6d.png)

### ファイルアップロード

FTP 不要で、D&Dで簡単にアップロードが出来るようになった :high_brightness: 

![2024-11-21_12h11_54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1645569/3cba34c7-4a2a-fe22-d04d-0a4703ed8976.png)


### ファイルダウンロード＆閲覧

> https://{app-name}.scm.azurewebsites.net/api/vfs/LogFiles.zip

のようなパスコピーしてダウンロードする必要がなく、GUI で簡単操作閲覧＆ダウンロードが出来るようになった

![2024-11-21_09h53_41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1645569/bf686da9-50d7-7150-e1f1-007a0469faa0.png)

ダウンロードはダウンロードアイコンか、ファイル名選択で

### 環境変数とか諸々（JSON Viewer)

設定や、ログファイル情報が、Json Viewer が一新されたことで使いやすくなった

特に、この copy Raw Json で、ダウンロードより簡単に取得出来るのは個人的に好き。
※完全に好みの問題だとは思うけど :sweat_smile:  

![2024-11-21_12h09_10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1645569/beb87e02-5878-7144-9a5e-185a15153397.png)

# あとがき

Default として newui にしてくれればいいのに、何故してくれないのか？ :thinking: 

何か問題があるのかもしれないので注意は必要かも
新社会人や駆け出しエンジニアに知っておいて欲しいことを書きました（説教臭い話）

※本当は今年のGWらへんで投稿しようと思ってたんですが、投げ忘れてました。

エンジニアになろうと就職活動して、見事エンジニアのスタート地点に立った皆様、研修を終えいよいよ配属という皆様、中途採用でキャリアチェンジでエンジニアのスタートラインに立った皆様。

一緒にIT業界や日本を良くするために頑張っていきましょう。

そこでですが、割と勘違いというか、まだ分かってないというか、誤解している人が散見されるので、今回はあくまで私の考えですが、プロフェッショナルとは何か、エンジニアとして仕事をするとは何か、仕事を任されるということはどういうことなのか、ここら辺について、私の仕事観と言うか考えみたいなものを書いてみようと思います。

※そんな香ばしい話興味ないし、そこそこ金もらって、いけてる上司の下で働ければOK！と思っている方は趣旨とズレるのでブラウザバックを推奨します。

# プロフェッショナルとは何か

wikipediaを参照すると、以下のように書かれています。
- 専門的な仕事に従事し、その能力が高く、その仕事の技術に優れ、確かな仕事をする人
- 主たる収入を得るために、特定の分野に従事している人

https://ja.m.wikipedia.org/wiki/プロフェッショナル

一般には後者の方が適切かもしれませんが、私の考えとしては前者であります。
つまり専門家であるべきというのが、あるべき姿であるということです。

# エンジニアとして仕事をするとは何か

エンジニアに限った話ではないですが、お客様や世の中の問題をエンジニアリングで解決するのがエンジニアの仕事です。つまり問題解決が目的であり、その手段がエンジニアリングであるというのが、エンジニアです。

# 仕事を任されるということはどういうことなのか

世の中には様々な仕事がありますが、仕事を任されるというのは、問題解決のために自分のリソース(能力、時間、体力、メンタルなど)を使うことだと思います。
そして、リソースを使うことに加え解決の責任も伴います。
責任というと重たい言葉ですが、解決できない人間に仕事は任せないわけで、つまり、解決に責任が伴います。
壊れたPC、繋がらないスマホ、傾いた家、腐った食べ物にお金払いますか?払わないですよね?仕事を任せるということはそういう「期待される成果」を求められている、つまり任される側にはそれを果たす責任が伴うことになります。

# 理解しておいて欲しいこと

会社や組織に属している人、プロジェクトに参画してる人、全員に言えるのが、「顧客の期待に応える」責任が発生しているということ。

プロ野球で例えてみます。

日本のプロ野球選手は、基本的にドラフトで指名され入団します。
多くの選手は入団後2〜3年2軍で体力づくりや、プロレベルの試合経験を積みます。
その中で結果を出した人が1軍に上がり、少ないチャンスをものにした人がレギュラーとして試合に出続けます。

ここで何を言いたいかというと

- 「できないから教えてください」スタンスの選手はいない(少なくとも1軍レベルには)
- 1〜2年で1軍レベルの結果が出ないからといって諦めたり不貞腐れる人はいない
- 成果のために日々試行錯誤と努力をしている

駆け出しエンジニアにも同じようなことが言えると思っていて

- 「分からないことはとにかくなんでも教わる」スタンスでは主力にはなれない（私たちエンジニアが解決する問題って誰も解いたこと無い問題のほうが多いです、そういう問題解決の方法は聞けないし教えられないんですよね）
- 1〜2年で5〜10年やってる主力の先輩たちと同等の成果を求めたって大抵無理(たまにいるかも)
- 試行錯誤や努力をやめたら成長は止まる

# 最後に

主力になりたい、稼ぎたい、やりたいようにやりたい。
そう思うのであれば、プロスポーツの一流でやってる人たちの考え方を真似るのが良いと思っています。

- 少ないチャンスをいかにモノにするか
- チャンスをモノにするために準備はできているか?しているか?
- チャンスを呼び込むための種まきはしているか?
- 1〜2年で心折れてないか？
- 試行錯誤、努力を諦めていないか？

スキルが身につくか？成長するか？学びがあるか?
当然、環境として存在することは必要条件ですが、最後は本人がどう取り組むか次第だと思うので、いつまでも大学の大教室に行く感覚で「出席すればOK」という感覚は、邪魔になるのでさっさと捨てましょう。
自ら取りに行く、取りに行ってもアサインされない場合は信用、信頼が足りないので、信頼、信用を勝ち取れるようなアクションを取り続けましょう。
上司が無能とか、会社がいけてないとか、他責にする前に自分がやれることを全てやりましょう。
それが社会人だし、大人だと思ってます。
中華ゲーム機 SDカードよもやま話 その1

![IMG_0382.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3930874/e7c08e47-ec24-aaac-2f43-1f66f91276cd.jpeg)

# はじめに
中華ゲーム機ってなに？
という方は[「pyxelを中華ゲーム機のLinuxで動作させるためのノウハウ」](https://qiita.com/moto_game_de_it/items/da1cc733afb9e20922f8)をご覧くださいませ

# 中華ゲーム機のOS開発者にとってA2規格のSDが使い勝手いい話
[中華ゲーム機のOS](https://github.com/game-de-it/plumOS-GKD)を作り・リリースする際には、その作業過程でSDカードの書き込みを数十回行う必要があるため、時短を最優先するためにアプリケーションパフォーマンスクラス「A2規格」のSDカードを利用しています。
OSイメージファイルは2GB~6GBほどあるため、この容量を何十回とSDカードに書き込まなければなりません。

下記の表はA1とA2のランダムアクセス時のパフォーマンスが記されていますが、実はシーケンシャルwriteの速度は2~3倍ほどの差があります。
| | A1 | A2 |
|:-:|:-:|:-:|
|  ランダムアクセス（IOPS） | Read1500/Write500  |  Read4000/Write2000 |

64GB A1規格のSDカードだと実測20~25MB/s程度で、128GB A2規格だと65~90MB/sの書き込み速度が得られます。
単純に作業時間が1/2~1/3になるのでこの差はとても大きいです。

OSが完成してリリースした後は速度にこだわる必要がなくなるため、64GB A1規格のSDカードを利用しています。

なおハンドヘルド側がA2に対応しているか否かは考えておらず、あくまでも作業PC(Windows、Mac)側がA2の仕様で動作してくれれば良いのであります🫡

# 中華ゲーム機においてSDカードはどのように扱われるか
中華ゲーム機で使われているLinuxは、OS起動時・起動後に何らかのファイルを積極的にSDカードへ書き込むことはしません。
そのため`squashfs`と呼ばれる「読み取り専用の領域」を利用しているOSもあります。

プレイするゲームも同様に、そもそもROMカートリッジやCD-ROMなど「読み取り専用の媒体」で販売されていることから、ファイルを書き込むという動作はしないことがわかると思います。
あるとしたらセーブデータぐらいなものです。

よってSDカードに求められる性能は「読み込み速度」を重視して選択すればいいわけで、書き込み速度はさほど気にする必要がないともいえます。

ただし次の項目で例を出しますがステートセーブのようにユーザが任意のタイミングで積極的にファイルを書き込んだりする場合は、write性能に注目する必要があります。


# 中華ゲーム機におけるwrite性能のパフォーマンス
昨今のハンドヘルドではA2規格のSDカードを使うと素晴らしいパフォーマンスを体験できます。
例えばステートセーブを行う際に、ステートセーブファイル容量の大きいPS,SS,DCなどでは一瞬でステートセーブが完了、ステートロードも一瞬です。

機種によってはA1だとステートファイル作成時にプチフリしたり、ステートファイル作成時の時間がかかることもしばしばあります。

[plumOS系列](https://github.com/game-de-it)ではステートセーブ場所を「ROMと同じ場所」になるよう設定を変更してリリースしています。
(他のOSではデフォでSD1側にステートファイルを保存する場合が多い)

一般的にはOSが格納されているSD1には容量が小さく・遅いSDカードを選択される傾向があり、ROMを格納するSD2には大容量(＝高速)なものを選択する傾向があります。
よってplumOS系列では高速なSD2にステートファイルが保存されるよう設計しています。

また、シェーダーキャッシュを生成するようなエミュ(wiiとか3DSとか)では、書き込み性能をフル重視した方が快適に動作するでしょう。
下記の例ではSDカードよりも高速なwrite性能を持つSSDを利用しているにも関わらず、シェーダキャッシュ生成によってプチフリに近い状況に陥っていることがわかると思います。

https://x.com/0_game_it/status/1709310912237351363


とはいえ上記の例は特殊といえば特殊な状況ですので、利用したいエミュの特性に応じて自分に必要なSDカードをチョイスするといいでしょう。

# A2規格のおすすめSD
Amazonでは128GBのA1とA2では価格差がほとんどなく、場合によってはA1の方が値段が高い場合があります。

私が実際に使っているA2規格でおすすめの2枚をご紹介します。(スクショは2024年12月6日現在)

- SAMSUNG  EVO Plus
  - シーケンシャルwrite 65MB/s
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3930874/2b57968e-44db-f3d3-0d32-2c43fb290226.png)
- TCELL Endurance
  - シーケンシャルwrite 90MB/s
  - 高耐久性なので大量のファイルを何度も書き換えたりする用途に最適
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3930874/26224985-5e2d-a1bd-1c4d-f1b210f2e1fd.png)

以上
mac に go を mise でインストールしたメモ

# mac に mise で go をインストールしたメモ
今回初めて mise で go を mac にインストールしてみました。
備忘録としてメモを残しておきます。

# インストール手順
まず mise をインストールします。
```
$ brew install mise
```

mise で go の最新を確認します。
```
$ mise latest golang

1.23.4
```

go の最新をインストールします。
```
$ mise install golang@1.23.4

$ mise use golang@1.23.4 --global

mise ~/.config/mise/config.toml tools: go@1.23.4

$ mise list golang

Tool  Version  Config Source              Requested
go    1.23.4   ~/.config/mise/config.toml 1.23.4
```

go の version を確認してみる
```
$ go version

zsh: command not found: go
```
あれ？
どうやらパスが通っていないようでした。

そもそもどこにインストールされたかわからないので go を探します。
```
$ find ~ -name "go" -type f

/Users/hogehoge/.local/share/mise/installs/go/1.23.4/bin/go
```
あった、こんなところにありました。

.zshrc の最後に下記のようにパスの追加を記述します。
```
export PATH=$PATH:"/Users/hogehoge/.local/share/mise/installs/go/1.23.4/bin/"
```

環境ファイルを有効化して go の version を確認します。
```
$ souce .zshrc
$ go version

go version go1.23.4 darwin/arm64
```

ちゃんと version が表示されました。
インストール完了です。
Clojure 高階関数

![advent_calendar_2024.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2985550/f4cd8ce0-6352-a1d8-4cae-f39dd44f4def.png)

[*Advent Calendar 2024 Day 9*](https://qiita.com/advent-calendar/2024/clojure)

## 高階関数とは

**高階関数**とは、関数を操作するための関数です。

1. 関数を引数として受け取る関数
1. 関数を返り値として返す関数

## 具体例

### 1. map

引数で関数とコレクションを受け取り、各要素に対して関数を適用し、新しいシーケンスを生成する関数

```clojure
(map inc [1 2 3])
;; => (2 3 4)

(map + [1 2 3] [2 3 4])
;; => (3 5 7)
```

### 2. filter

引数で関数とコレクションを受け取り、条件を満たす要素だけを抽出する関数

```clojure
(filter even? [1 2 3 4 5 6 7 8 9 10])
;; => (2 4 6 8 10)
```

### 3. 関数を返す関数

受け取った値(x)よりも大きいかどうかを判定する関数を返す`greater-than`という関数を作ってみます。

```clojure
(defn greater-than [n]
  (fn [x] (> x n)))
;; => #'todo.core/greater-than
(def greater-than-5 (greater-than 5))
;; => #'todo.core/greater-than-5

(greater-than-5 6)
;; => true
(greater-than-5 4)
;; => false
```

このような高階関数を使うことで、コードの再利用性、コードの簡潔性、メンテナンス性、柔軟な抽象化をすることができそうです
BOTANのmissonを紹介します！

# はじめに
こんばんは、初めまして！Gardens4号機 BOTANのmissionと安全審査をやっているいっちーです。
今回は、BOTANのmission概要をざっくりとお話します！

# Misson
主にカメラとジャイロとAPRSの3つのミッションがあります。私はカメラ担当なので、ジャイロとAPRSの詳しいお話はいつかのお楽しみに…

社会問題からmissionの内容を決め、軽石とトウモロコシ🌽とオーロラの三つの撮影を行います！
## トウモロコシ
日本は飼料用トウモロコシのほとんどを輸入に頼っているんです。アメリカのサウスダコタ州からデントコーンを年間1千万トン！
そんな中、サウスダコタは三年前に干ばつによる被害が大きく、生産高が低くなりました。このままだと日本に影響が出てしまう！ということで、「トウモロコシ🌽の生育状況をVARIを使用して把握する」という内容になりました。

## オーロラ
1989年にカナダでは太陽フレアによる電波障害や停電が発生し、600万人に影響、約650万ドル(当時のレートで約8億9700万円)の被害額を負いました。
今はさらに技術が発展しているので、もっと被害が多くなりそうですよね…
太陽フレアは低緯度オーロラを発生させると知った私たちは、オーロラを撮影して太陽フレアが地球に引き起こす影響を推定しようと考えました✨

## 軽石
2021年夏に福徳岡ノ場が噴火し、鹿児島県と沖縄県の漁港に軽石が漂着しました。それにより10億9,300万円の軽石除去費用がかかり、漁船の損傷や航行不能、マリンレジャーへの影響もありました。
軽石の撮影を行い漂流経路と時間を推測し、台風の予報円マップのようなものを作る予定です！漁船の被害を50%以上削減する事が目標🧐

## Gyro
「理科ばなれ」意外に深刻なんです…学生もですが、教員の方が理科に苦手意識があるのだそう。理科の授業が少なく、暗記傾向になっているのも要因の一つにあります。
その中で、宇宙に関連する内容は太陽や惑星などのみで、人工衛星に触れていない！
学生も先生も、人工衛星について学べるアプリを使ってもらい、理科を楽しく学んでほしい🌏

## APRS
Gardensでは、先輩が開発した2機の衛星が無事運用を終えました👏(来週からGardensの新たな衛星の運用が始まります♪)そんな先輩たちもAPRSmissionに挑戦しました！
内容は「世界中のアマチュア無線家に情報を送る」としています。
宇宙から送られてくる情報、楽しみ〜！

# 最後に
あともうひと踏ん張りなBOTANをぜひ応援してください🙏
最後まで読んでいただき、ありがとうございました！
また機会があればその時に👋
Google Cloud FunctionsでGoogle Drive内の情報をSlack通知してみた①(セットアップ編)

## 概要

Google Driveのフォルダ内にあるスプレッドシート情報をSlackに通知するCloud Functionsを試験的に作成してみたのでご紹介します。本記事はセットアップ編です。

### 構成
- Google Cloud Functions
- Google Cloud Run
- Google Drive API
- Google Sheets API
- Slack Webhook

### 全体の流れ
以下の流れで記事を進めていきます。本記事は2までの紹介です。
1. **Google Cloudの設定**: 
    - サービスアカウントの作成と必要なロールの付与
    - Workload Identity連携の設定
2. **Slack Webhookの設定**
3. **Cloud Functionsの実装**:
    - Google Drive APIとGoogle Sheets APIを使用して、フォルダ内のファイルリストをファイル最終更新者にメンションするFunctionを作成
4. **Cloud Runでの実行と結果**: 
    - Cloud RunからCloud Functionsを呼び出し、サービスアカウントを使用して実行


## Google Cloudの設定

### サービスアカウントの作成
まずはサービスアカウントを作成します。
1. GCPコンソールにアクセスし、プロジェクトを選択します
2. ナビゲーションメニューから「IAMと管理」 > 「サービスアカウント」を選択します
3. 「サービスアカウントを作成」から、以下の情報を入力し「作成して続行」を選択：
   - サービスアカウント名
   - サービスアカウントID


4.「サービスアカウントにプロジェクトへのアクセスを許可する」から以下ロールを付与：
```
roles/artifactregistry.createOnPushWriter
roles/cloudbuild.builds.builder
roles/cloudfunctions.invoker
roles/iam.serviceAccountTokenCreator
roles/iam.serviceAccountUser
roles/iam.workloadIdentityUser
roles/logging.logWriter
roles/run.serviceAgent
roles/storage.objectAdmin
```

詳細な手順については、Googleの公式ドキュメントを参照してください。

https://cloud.google.com/iam/docs/service-accounts-create



### Workload Identity連携
サービスアカウントを使用してGoogle APIにアクセスできるよう、Workload Identity連携をします。

1. **Workload Identityプールの作成**
   - GCPコンソールで「IAMと管理」 > 「Workload Identity連携」を選択します
   - 「Workload Identityプールを作成」から任意のプールIDを設定します
   - プールのプロバイダを追加します。今回はOIDCプロバイダを使用します
   - プロバイダの属性を構成後、保存で完了です



2. **サービスアカウントへ連携**
   - プールの詳細ページに移動し、「アクセスを許可」を選択します
   - サービスアカウントの権限借用を使用してアクセス権を付与するを選択します
   - 連携したいサービスアカウント選択し、保存で完了です

詳細な手順については、Googleの公式ドキュメントを参照してください。

https://cloud.google.com/iam/docs/manage-workload-identity-pools-providers

### Google Drive APIの有効化とサービスの作成

1. GCPコンソールで「APIとサービス」 > 「ライブラリ」を選択します
2. 「Google Drive API」を検索し、有効化します
3. 同様に、「Google Sheets API」も検索して有効化します

以下のように有効化されていればOKです。

![スクリーンショット 2024-12-06 22.18.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3588676/7c20ab27-08b0-0ef3-b32b-a505e11f1eaa.png)

## Slack Webhookの設定

1. Slackアプリの作成
    - [Slack API](https://api.slack.com/apps) にアクセス
    - 「create New App」> 「From scratch」を選択します
    - アプリの名前、ワークスペースを設定して作成完了です

2. Incoming Webhooksの有効化
    - 左側のメニューから「Incoming Webhooks」を選択します
    - 「Activate Incoming Webhooks」をオンにします

3. Webhookの作成
    - 「Add New Webhook to Workspace」からメッセージを投稿するワークスペースを選択します
    - 投稿するSlackチャンネルを指定し「許可する」を選択するとWebhook URLが生成されます

4. Webhook URLの使用
    - お試しで、HTTP POSTリクエストを送信します。Sample curl request to post to a channel：を実行してみます
  ```bash
  curl -X POST -H 'Content-type: application/json' --data '{"text":"Hello, world!"}' 生成されたWebhook URL
```
問題なく通知されました

![スクリーンショット 2024-12-06 22.31.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3588676/0b455550-50af-430d-7a96-6519b960c7b0.png)


詳細な手順については、Slackの公式ドキュメントを参照してください。

https://api.slack.com/messaging/webhooks

---

次の記事では、以下の3,4を紹介をします。
1. Google Cloudの設定
2. Slack Webhookの設定
3. **Cloud Functionsの実装**
4. **Cloud Runでの実行と結果**
【プロダクト開発】不具合修正チケットに書くべき内容を私なりに整理してみます

開発の現場では不具合修正の案件は、チケット、プロダクトバックログアイテム(PBI)、github issuesなどで管理していると思います。
私の持論ですが、バグは見つけたらすぐ直すべき派なのですが、必ずしもすぐに対応できない場合もあると思います。（優先順位、工数、難易度、必要な意思決定のサイズ等に起因して）

すぐにやれない場合は、ちゃんと情報を整理しておくべきです。
着手できるようになった際に、0ベースで調べ直すことなく、低コストで着手できるレベルまで情報を揃えておく必要があります。
その時間すら惜しい場合もありますが、不具合を直すよりは短時間でやれるはずですし、直したほうが早いなら、わざわざ整理して置く必要もなく、さっさとその場で直せばいいので、うだうだ言わずにすぐ直せないならちゃんとやりましょう。
それが対応する人への思いやりだし、開発チームとしてやるべき仕事です。


# 不具合チケットに書くべき内容

個人的にやっている内容と、やれているか怪しい内容がありますが、ひとまずこれだけ揃えていれば、十分だろうと考えているものを列挙していきます。
裏を返せば、私がこれだけ整っているバグチケットを見たらうれしいレベルの内容でもあります。


## 【MUST】バグレポートに相当する内容

https://qiita.com/flyaway/items/ce9ba28c857822cea45b#%E3%83%90%E3%82%B0%E3%83%AC%E3%83%9D%E3%83%BC%E3%83%88%E3%81%A8%E3%81%97%E3%81%A6%E6%88%90%E7%AB%8B%E3%81%97%E3%81%A6%E3%81%84%E3%82%8B%E3%81%8B

不具合修正のときは、事象を再現させて、その事象が直るようにコードを修正するという手順を踏みます。
そのため、バグレポートに書かれているべき以下の情報

- バグの再現方法(できるだけ詐しく)と発生頻度
   - 再現方法 = 発生条件（設定、環境、アカウントなどの情報）、再現手順（どういう操作か）、起動経路など
- 本来の仕様(バグがない場合の望ましい動作。こうあるべき、という自分の意見でかまわない) 
   - 期待結果と呼ぶ場合もある
- 実際の動作(完全でなくても、自分の記録した範囲で詳しく書く)
   - バグの事象です。再現方法を実施したときにどう言う結果が不具合として起こるのか


## 【視覚的に分かる場合はMUST】画面キャプチャ等の視覚的に不具合が分かる情報

Webサービス系の不具合であれば、画面に不具合の事象が顕在化する事が多いと思います。
画面を見れば不具合とわかるものは、画面キャプチャを添付すべきです。
**※gifなど、動作がわかるものだとより良いでしょう。**

その不具合修正をする人が必ずしもその画面の有識者とは限らないからです（弊社では1年目のメンバーのオンボーディングの一環で軽微な画面の不具合修正を担当することも多い）。
視覚的な情報を提供することで、その不具合に対する解像度が高まります。

## 【SHOULD】不具合の原因箇所

ソースコードの場所が特定できている場合は必ず記載すべきです。
実際に対応する人に対して、（実は他の部分で修正するのがベストなのに別の所を指示してしまうことで）バイアスをかける可能性もありえますが、少なくとも0ベースでコードを探す事による工数の浪費は削減できます。

調べきれていない場合は「ちゃんと調べられてないけど、このパッケージらへん」「こういう名前のクラスのこういう処理でこういう状態になっているはず」のように、仮説ベースであっても良いので書かれているだけで、大量のソースコードがら探し当てる作業は減らせますし、いきなり仮説の検証から入れます。（仮説構築は経験が浅いほどコスト高い）


## 【COULD】修正方針

直す工数が取れなくても、「私だったらこんな感じで直す」を書いておくことで、ここでも修正方針を考える部分を削減できます。
不具合は一刻も早く潰す方が良いので、（「おそらくこんな感じだろう」が）わかっているなら書いておいた方が良い。

## 【COULD】修正による影響範囲（とその仮説）

修正方針を記載するのであれば、合わせて記載しておいたほうがよいのが、修正による影響範囲です。
疎結合高凝集なコードの場合、影響範囲の推定、調査はそれほど大変ではない場合もありますが、それ故に様々なところで使われている場合もあります。
レガシーコードやスパゲッティコードの場合は、影響範囲を読みきれない場合もあります。
推測レベルでも、無いよりはあったほうが良いです。
自分の持っている情報や自分の考える観点を他者がもっているとは限らないためです。

例えば、

- その修正方針によって（良くも悪くも）動作が変わる可能性がある機能や画面は何なのか
- どの程度の範囲に影響がありそうなのか
- etc

# 最後に

文字でダラダラ書いてきましたが、
自動テストが整備されていて、6～70％以上のカバレッジが担保されている恵まれた開発環境下では、Shouldくらいまであれば十分な気もします。
影響範囲を調べずとも、動作が変わるなら自動テストが失敗するはずだからです。

一方でそのような恵まれた環境ではないプロダクトの場合は、不具合修正の過程で自動テストの拡充とともに影響範囲調査を丁寧にやることで、機能への理解が深まるとともに、トラブルシューティングへの耐性・スキルも上がるので、特に若手の皆様においては、手を抜かずしっかり向き合ってほしいと思います。
【誰得】一筆書きの手書きパターンを認識するOCRもどきのクソ雑魚アルゴリズム


## これは何

一筆書きの手書きパターンを認識するOCRもどきのクソ雑魚アルゴリズム

例えば、以下のような図形Aがあったとして、

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/649673/c92a5105-f53c-f1e2-82ec-d776fb88d0d1.png)

ユーザーが

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/649673/39fc8124-2063-fa9f-57e4-af3b7ea1cccb.png)

のように手書きしても図形Aだと判定したい。というお話。

## 却下した方法

面積や縦横比などで比較する案が最初に浮かんだが却下した。
それらが異なっていても図形Aのように見えるケースが考えられるため。

## 結論

X軸、Y軸の移動の変化で比較すればよい。

例えば図形Aは

X軸：左右左
Y軸：上下上下

と線が変化している。

これは例で示したユーザーの下手糞な絵にも共通する事象であり、比較対象として適切である。

具体的なアルゴリズムは面倒だし、ほとんど自明なので書かない。
細かいところが気になる人は各自頑張って。

終わり。

## おまけ

https://doodles.google/doodle/halloween-2024/
uv 導入のきっかけについて

uv は先進ユーザーの間で普及しつつありますが、導入する明確な動機が見い出せていませんでした。Python + venv は Node.js + npm と似たような運用を可能にしますが、activate による状態遷移を伴う点が異なります。これが実は運用に大きく影響し、uv はそのギャップを埋めるものだと気付いたことが、導入のきっかけとなりました。それについてまとめます。

# venv 運用の実態

:::note info
大規模なプロジェクトではなく、個人的な運用での話です。
:::

ディレクトリごとの venv 構築が面倒だったため、似たような用途のディレクトリで venv を使い回すことが常態化していました。その結果、個々の venv が何を目的として作られたのかが不明瞭になり、依存関係の管理も複雑化していきました。

具体的には、あるディレクトリで使用するパッケージには特定のバージョンを入れていたはずなのに、別のディレクトリで追加のパッケージを入れたために更新されてしまうなどの問題が発生しました。

作業環境の混乱も大きな課題でした。あちこちに作業ディレクトリが散在する中で、venv の activate 忘れによるエラーが発生しました。また、必ずしもディレクトリに包含関係があるわけではないことなどから、どの venv で実行していたか把握できなくなることもありました。

まさに散らかり放題の「汚部屋状態」といった状況でした。

:::note warn
【追記 2025/4/28】
ローリングリリース（バージョンに分けないで継続的に更新する方式）を採用する Arch Linux で python を更新したところ、あるタイミングで 3.12 から 3.13 への切り替えが発生しました。venv はバージョンごとにパッケージを分けるため、3.12 で使っていた venv が使えなくなりました。uv では python 本体のバージョンも含めて管理対象となるため、このような問題が回避できます。👉[参考](https://x.com/7shi/status/1907832230120141128)
:::

# activate 不要の持つ意味

MCP サーバー開発のため uv に触る機会がありました。

https://qiita.com/7shi/items/3bf54f47a2d38c70d39b

外部からスクリプトを実行する際、従来の venv のように activate する必要がなく、直接 uv 経由で実行できることに気付きました。

```sh:例
uv run /foo/bar/baz.py
```

:::note info
`python` の代わりに `uv run` と打ち込むという感覚です。
:::

これまでも venv と npm の類似性は認識していましたが、この activate 不要という特徴は、npm が以前から実現していたのとほぼ同じスタイルです。MCP サーバー開発では並行して TypeScript も使っていたため、そのことが明確に意識できました。

これまで当たり前のように行っていた activate という作業が実は負担になっていたことに気付くことで、uv のメリットが浮き彫りになったわけです。

# uv による環境改善

uv を導入することで、より細かい粒度で環境の分離が可能になりました。その際、uv の高速性が大きく効いてくることも実感しました。従来の pip を使用していた場合、大規模なライブラリ群をインストールするのは時間がかかるため、結果として似たような用途のディレクトリ間で venv を使い回すことにつながっていました。それに対して uv ではインストール時間が大幅に短縮されることから、同じようなライブラリを複数回インストールすることへの実務的な障壁が大きく軽減されます。これは単なる待ち時間の短縮以上の意味があり、環境分離の実践をより現実的なものにしてくれます。

なお、ディレクトリごとに独立した環境を作ることによって、消費するディスク容量は増大します。共通のライブラリが環境ごとに重複するためです。しかし、最近のストレージ容量を考えれば、環境分離によるメリットが上回ると判断しました。

以上のように、uv によってディレクトリ単位での明確な分離が現実的になりました。また、あるディレクトリでどの venv を使うべきか考える必要もなくなりました。単にそのディレクトリで直接 uv コマンドを実行するだけで、適切な仮想環境が自動的に選択されるためです。

# 補足

ディレクトリ単位と書いていますが、その中にはサブディレクトリを含み、サブディレクトリは親ディレクトリの環境を共有する前提です。つまり用途ごとに分類して、その中で細分化します。

今まではナイーブに運用していたことから、必ずしも包含関係がないディレクトリでも venv を使い回すことがありました。そのようなケースに uv を導入する場合、pyproject.toml をコピーして `uv sync` で環境を作り直します。

:::note info
pyproject.toml などの設定ファイルは、先入観で何だか面倒くさそうと思っていましたが、環境の再構築に有益だと気付いて見方が変わりました。

面倒に思っていたのは、あらかじめ手動で書く必要があると誤解していたことも一因です。実際は `uv add` したものが自動で追記されます。pip を使っていた時、後で環境を再構築するには何を `pip install` するのか列挙する必要がありましたが、それが自動で記録されるようなイメージです。
:::

# 今後の展望

今後は既存の作業ディレクトリを段階的に uv での管理に移行していく予定です。

# 関連記事

https://qiita.com/7shi/items/29a16427c2a8deee4747

# 参考

taskipy を使えば、`make foo` のように `uv run task foo` として実行するコマンドを登録できます。

https://zenn.dev/nowa0402/articles/e84d3598001c9c

https://github.com/astral-sh/uv/issues/5903

以下の記事は npm との比較によって uv を捉えており、スタンスが似ています。

https://zenn.dev/junseinagao/articles/8c06779239bfa0
トイオ・プレイグラウンドのカードのStandardID一覧

トイオ・プレイグラウンドのカードのStandardIDについて調べてみました。 

https://toio.io/titles/playground.html

本来このカードはtoio core cubeをプレイグラウンドモード(底面ランプ黄色点灯状態)で使うものですが、カード自体は普通にStandard IDが印刷してあるようで、プレイグラウンドモードにしない状態だと読み取りセンサーによってStandard IDを読み取ることができました。
([toio.js](https://github.com/toio/toio.js)、[toio.py](https://github.com/toio/toio.py)や[M5StackToio](https://github.com/kenichi884/M5StackToio)のID読み取りAPIやイベント(notify)で普通に読み取れます。)

オフィシャルの技術情報のところにトイオ・プレイグラウンドのカードのIDも載っているのかなと思いましたが、

https://toio.github.io/toio-spec/docs/hardware_standard_id

なぜかトイオ・プレイグラウンドのカードのIDについての記載がないので調べてみました。

カード名は以下から参照

https://toio.io/playground/card.html

# トイオ・プレイグラウンドのカードのStandardID一覧

以下、アドバンスにしか入っていないカードも含みます。

## そうこうカード

|カード名|Standard ID|
|---|---|
|ゆっくり　ひだり|3702450 0x387eb2|
|ゆっくり　まっすぐ|3702451 0x387eb3|
|ゆっくり　みぎ|3702452 0x387eb4|
|はやく　ひだり|3702453 0x387eb5|
|はやく　まっすぐ|3702454 0x387eb6|
|はやく　みぎ|3702455 0x387eb7|
|とてもはやく　ひだり|3702456 0x387eb8|
|とてもはやく　まっすぐ|3702457 0x387eb9|
|とてもはやく　みぎ|3702458 0x387eba|

## アクションカード

|カード名|Standard ID|
|---|---|
|ゴール|3702090 0x387d4a|
|おとしあな|3702113 0x387d61|
|こっち　むく|3702093 0x387d4d|
|どこか　むく|3702112 0x387d60|
|ぶつかるまで　まつ|3702092 0x387d4c|
|スピン|3702095 0x387d4f|
|ダッシュ|3702099 0x387d53|
|パニック|3702152 0x387d88|
|１びょう　まつ|3702096 0x387d50|
|３びょう　まつ|3702097 0x387d51|
|５びょう　まつ|3702098 0x387d52|
|ゆっくり　ひだりかいてん|3702104 0x387d58|
|はやく　ひだりかいてん|3702105 0x387d59|
|とてもはやく　ひだりかいてん|3702106 0x387d5a|
|ゆっくり　みぎかいてん|3702101 0x387d55|
|はやく　みぎかいてん|3702102 0x387d56|
|とてもはやく　みぎかいてん|3702103 0x387d57|
|１ぽ　すすむ|3702107 0x387d5b|
|２ほ　すすむ|3702108 0x387d5c|
|３ぽ　すすむ|3702109 0x387d5d|

## おとカード

|カード名|Standard ID|
|---|---|
|ベル　ドレミファソラシド|3702091 0x387d4b|
|うた　ハッピバースデートゥーユー|3702381 0x387e6d|
|うた　かえるのがっしょう|3702392 0x387e78|
|せいかい|3702360 0x387e58|
|ふせいかい|3702361 0x387e59|

## わりこみかーど

|カード名|Standard ID|
|---|---|
|１びょう　ごとに　わりこみ|3702190 0x387dae|
|２びょう　ごとに　わりこみ|3702191 0x387daf|
|３びょう　ごとに　わりこみ|3702192 0x387db0|
|ぶつかる　たびに　わりこみ|3702200 0x387db8|
|じしゃく　に　ちかづくたびに　わりこみ|3702201 0x387db9|

## きろくさいせいかーど

|カード名|Standard ID|
|---|---|
|きろくA|3702051 0x387d23|
|きろくB|3702052 0x387d24|
|きろくC|3702053 0x387d25|
|きろくていし|3702050 0x387d22|
|さいせいA|3702071 0x387d37|
|さいせいB|3702072 0x387d38|
|さいせいC|3702073 0x387d39|
|ループさいせいA|3702061 0x387d2d|
|ループさいせいB|3702062 0x387d2e|
|ループさいせいC|3702063 0x387d2f|

# おわりに

基本的にStandardIDなので、プレイグラウンドモードにしないで使えば自作プログラム用の自由な用途のカードとして利用できそうです。

IDの割り当てを見ているとなんとなく開発中の歴史とか意図っぽいものが妄想できておもしろいですね。「ゴール」と「ベル　ドレミファソラシド」が番号が並んでいるので「ベル　ドレミファソラシド」は「おと」ではなくて「アクション」一族だったのかも、とか。
Sequence Makerでカメラの画像を取り込む

## はじめに
Sequence MakerはExcelから測定器を制御可能にするアドインです。Sequence MakerのV1.70からカメラの画像を取り込むことができるようになりました。この記事ではこのカメラ機能について解説したいと思います。なお、Sequence Makerについての詳細は以下の記事を参照ください。

https://qiita.com/sequencemaker/items/8e6a370ab0a793a06a3b

:::note warn
***お断り***
本記事の内容はSequence Maker開発元の公式見解ではなく、あくまでも個人が趣味の範囲内で執筆しているものです。記事の内容について開発元へ問い合わせることはお控えください。ご質問・要望などは各記事のコメント欄へお願いいたします。
:::

## カメラ機能とは
Sequence MakerのV1.70で追加された機能です。パソコンで認識しているカメラの画像をExcelのワークシート上に取り込むことができます。認識しているカメラはデバイスマネージャーで確認できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3821782/78d80843-a647-3530-683a-d599418879fd.png)

## カメラオプション
Sequence Makerの詳細設定を開くと右下にカメラオプションがあります。カメラ機能を使用するためには「カメラを使用する」に✅を入れておく必要があります。その下のプルダウンから使用するカメラを選択します。さらにその下に選択したカメラプレビューが表示されるので、カメラの向きなどを調整しておきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3821782/c6daa497-fbd6-e197-8ee6-ef57a58d2443.png)

## 簡単な使い方
カメラ画像を取り込みたいセルに、「#CAMERA?」という専用コマンドを書くだけです。セルを選択して「コマンド送受信」ボタンを押してシーケンスをスタートさせれば、カメラ画像が取り込まれます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3821782/5d1058fa-ac20-77b0-cba5-96c416b06ef7.png)

::: note
Sequence Makerは本来は測定器とセットで使うものですが、測定器を繋がずにカメラ機能だけお試しする場合は、インターフェイスの設定で「仮想」を選んでおくとシーケンスをスタートできます。
:::

## 表示サイズを調整
カメラの種類によっては、取り込まれる画像のサイズが大きかったりすることがあります。そんな時は、サイズを指定しましょう。「#CAMERA?」の後に、括弧付きでサイズを指定すればOKです。サイズの単位はptです。適宜調整してください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3821782/5e7019bf-d87f-ad6d-bad9-69a24ba572d1.png)

## 画像ファイルとして保存する
カメラ画像をExcelのシートに貼り付けるのではなく、BMPファイルとして保存することができます。「#CAMERAFILE?」と書けばOKです。保存に成功すると、ファイルのパスがワークシート上に表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3821782/2224ebc5-eed4-ae32-c335-1d09e0a49551.png)

なお、ファイル名は自動的に付けられますが、指定することも可能です。「#CAMERAFILE?」の後に、括弧付きでファイル名を指定しましょう。拡張子は勝手に「.BMP」が付きますが、「ファイル名.bmp」のように指定することも可能です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3821782/514ba032-5754-4bc8-5485-628b87693543.png)

::: note
画像ファイルが保存されるパスは固定です。
```
C:\Users\<User Name>\Documents\Sequence Maker\
```
:::

## 用途
- 長期測定中の観測対象の様子を記録に残す
- 観測対象が停止したり、燃えていたりしないかチェックする（ぇ
- コマ撮りしてパラパラ漫画を作る（ん？

## エラーが出るとき
「Error」となってうまく撮影できない時は以下をチェックしてみてください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3821782/7bf62a40-e9a1-a861-8860-a858bc6959fa.png)

- 詳細設定で「カメラを使用する」に✅が入っているか？
- カメラはPCに正しく認識できているか？（Windows標準付属のカメラアプリなどで確認してみるのも良い）
- Sequence Makerで使えないカメラなんかもあるかも？

## まとめ
今回はSequence Makerを使ってカメラ画像を取り込んでみました。カメラが画像が自動で取り込めると、いろいろな記録に使えそうです。ぜひいろいろな写真を撮影しまくってみてください！！
AzureでAKSクラスターをTerraformで立てる。

基本的に
git clone https://github.com/hashicorp-education/learn-terraform-provision-aks-cluster
でよいのですが、はまったところがあったので注意点

必ず下記コマンドを実行し、メモすること

```
az login
az ad sp create-for-rbac --skip-assignment
```

コード
```aks-cluster.tf 
provider "azurerm" {
  subscription_id   = ""
  skip_provider_registration=true
  features {}
}

resource "azurerm_resource_group" "default" {
  name     = "${random_pet.prefix.id}-rg"
  location = "West US 2"

  tags = {
    environment = "Demo"
  }
}

resource "azurerm_kubernetes_cluster" "default" {
  name                = "${random_pet.prefix.id}-aks"
  location            = azurerm_resource_group.default.location
  resource_group_name = azurerm_resource_group.default.name
  dns_prefix          = "${random_pet.prefix.id}-k8s"
  kubernetes_version  = "1.30"　#バージョンに注意

  default_node_pool {
    name            = "default"
    node_count      = 2
    vm_size         = "Standard_D2_v2"
    os_disk_size_gb = 30
  }

  service_principal {
    client_id     = var.appId
    client_secret = var.password
  }

  role_based_access_control_enabled = true

  tags = {
    environment = "Demo"
  }
}
```

```terraform.tfvars
# Copyright (c) HashiCorp, Inc.
# SPDX-License-Identifier: MPL-2.0

appId    = ""ちゃんと入力すること
password = ""ちゃんと入力すること
```

```variables.tf
# Copyright (c) HashiCorp, Inc.
# SPDX-License-Identifier: MPL-2.0

variable "appId" {
  description = "Azure Kubernetes Service Cluster service principal"
}

variable "password" {
  description = "Azure Kubernetes Service Cluster password"
}
```

```versions.tf
# Copyright (c) HashiCorp, Inc.
# SPDX-License-Identifier: MPL-2.0

terraform {
  required_providers {
    azurerm = {
      source  = "hashicorp/azurerm"
      version = "3.67.0"
    }
  }

  required_version = ">= 0.14"
}
```

```outputs.tf
# Copyright (c) HashiCorp, Inc.
# SPDX-License-Identifier: MPL-2.0

output "resource_group_name" {
  value = azurerm_resource_group.default.name
}

output "kubernetes_cluster_name" {
  value = azurerm_kubernetes_cluster.default.name
}

# output "host" {
#   value = azurerm_kubernetes_cluster.default.kube_config.0.host
# }

# output "client_key" {
#   value = azurerm_kubernetes_cluster.default.kube_config.0.client_key
# }

# output "client_certificate" {
#   value = azurerm_kubernetes_cluster.default.kube_config.0.client_certificate
# }

# output "kube_config" {
#   value = azurerm_kubernetes_cluster.default.kube_config_raw
# }

# output "cluster_username" {
#   value = azurerm_kubernetes_cluster.default.kube_config.0.username
# }

# output "cluster_password" {
#   value = azurerm_kubernetes_cluster.default.kube_config.0.password
# }


```
20分でWebTransportを体験できるハンズオン

アドベントカレンダーが空いたので明日の記事もまだ書いてないけど乱入！

この投稿はKDDIテクノロジーアドベントカレンダーの12/06分の記事です。
他の記事はこちらです。
https://qiita.com/advent-calendar/2024/kddi-technology

## 何の話?

もう半年くらい前に社内で [WebTransport](https://developer.mozilla.org/en-US/docs/Web/API/WebTransport) を使った通信を体験できるハンズオンを実施しました。持ち時間20分で！

WebTransport の雑な説明込みで20分だったのでハンズオンは10分くらい。
半年経ちましたが、WebTransportをここまで短時間に超簡単に試せる環境はそれなりにまだ需要あるかな？と思うので、いまさら感はあるけど公開。

資料はこちら。

https://github.com/tadfmac/powt-example1/blob/main/ja/README.md

## 概要

[node.js 版 WebTransport サーバー fails-components/webtransport](https://github.com/fails-components/webtransport)を簡単に立てられるようにしたラッパーライブラリ[powt](https://www.npmjs.com/package/powt) を書いたので、それを使ったexample を動かす、というもの。

webTransportってstream APIが多重構造になってて、なかなか初見殺しなんですよね。そのあたりをイベントドリブンに隠蔽してWebSocketっぽく使えるようにしている。

ハンズオンの手順としては

- 証明書をインストール
- npm から example をインストール
- サーバーを起動してローカル環境で WebTransport通信を試す

というものでした。

コードは書きません！（なんだそのハンズオンwwww）

## 環境を作るのもメンドクサイ人へ

こちらから試せます。

https://wtapp.4191333.xyz:4445

## 今後の展開

webTransportってまだiPhoneで使えないんですよね。
来年くらいには使えるようになるといいな！という感じですけど、2024年12月時点での can i use でこんな感じ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31758/0948a7b1-5340-e9cf-d774-442dda0325e1.png)

というわけで、スマホでも使えるようなアプリでこれ単体（前提）で採用はまだ難しい。
WebSocketにフォールバックするように [powt](https://www.npmjs.com/package/powt) をラッパーするライブラリを描かないと自分であまり使えないな。と思ってるところ。

[socket.io](https://socket.io/get-started/webtransport) 使えよ。という声が聞こえてきそうだけど、これ結構動かすの大変なので、powt を書いたという順番だったりもする。

リアルタイムアプリケーションにはかなり有望な通信手段なので、2025年はもう少し積極的に使っていこうと思います！
プログラミングで楽しいと思える瞬間


## はじめに

こんにちは！
[RUNTEQ Advent Calendar 2024](https://qiita.com/advent-calendar/2024/runteq)の7日目を担当する、たかおと申します。
現在、プログラミングスクールRUNTEQでRailsを中心に学習しています。
プログラミングの楽しさをもっと多くの人に知ってもらいたいと思い、今回初めてQiitaに記事を投稿することにしました。
この記事では、私がプログラミング学習を通じて感じた「楽しい瞬間」を共有したいと思います。
特に初心者の方が、「プログラミングって楽しい！」と感じるきっかけになれば嬉しいです。
## 本文

### (1) プログラミングを始めたきっかけ

私がプログラミングに初めて触れたのは、大学生のときでした。
授業でHTMLとCSSを使い、簡単なウェブサイトを作ったのがきっかけです。
自分で組んだコードがそのまま画面に表示され、初めての体験でとても感動したのを今でも覚えています。
そのとき、「自分の手で何かを作れる楽しさ」を強く感じ、プログラミングに興味を持つようになりました。
その後、IT企業に入社し、さらに深く学びたいと思い、現在プログラミングスクールで学習しています。



## (2) 楽しいと感じた瞬間
### **①自分で作ったものが動く瞬間**

プログラミングの中で最も楽しい瞬間の一つは、**自分が書いたコードが初めて動いたとき**だと思います。

それまで画面には何も表示されなかったり、真っ白なページだったりした状態が、自分のコードによって動き始め、形になった瞬間の感動は特別なものがあります。

例えば、RailsでCRUDアプリを作ったとき、データを入力し、それが一覧表示される流れを実現できたときには、「こんなに簡単にWebアプリが作れるんだ！」という驚きがありました。

特に、ボタンをクリックしてデータが保存され、それが画面に反映される動きを目にすると、自分の手で何か新しいものを生み出したという実感が湧いてきます。

この瞬間の楽しさが、プログラミングを「もっとやってみたい！」という気持ちを後押しし、学習のモチベーションになっています。

---

### **②エラーを解決したとき**

一方で、プログラミングの学習にはエラーとの戦いがつきものです。

初めてエラーが出たときは、画面に表示される見慣れない赤いエラーメッセージに戸惑い、どこから手をつければいいのかすら分かりませんでした。

特に、環境構築では細かいミスや設定の不備で何度も立ち止まりました。

しかし、試行錯誤しながらエラーの原因を突き止め、一つひとつ修正してコードを実行し、エラーが解決したときの達成感は格別です。

たとえば、環境変数の設定ミスを解消してサーバーが無事に立ち上がったときや、スペルミスを直してプログラムが動いたときなど、その瞬間は思わず「よっしゃ！」と声に出してしまうぐらい喜びを感じました。

また、こうしたエラーを解決した経験は次第に自分の中に蓄積され、次に似たような問題が起きたときに「あのときの知識が使える！」と思えるようになります。

この繰り返しが、プログラミング学習の成長を実感させてくれる大きなポイントだと思います。

---

### **③趣味へ応用できた瞬間**
また、自分の趣味や生活に応用できる点もプログラミングの魅力の一つだと感じています。
単に学習するだけで終わらず、プログラミングのスキルを使って「こんなものがあったらいいな」と思うものを自分で作れるのはとても楽しいことです。

例えば、私はミニマリストとして「少数精鋭の持ち物で快適に暮らす」ことを目指しているのですが、より良いアイテムを見つけたり、その情報を共有したりするのが一つの趣味でもあります。
この趣味とプログラミングを組み合わせて、「ミニマリスト向けレビューサイトを作ろう」と思い立ったとき、プログラミングが単なる技術ではなく、自分のやりたいことを実現するツールだと改めて実感しました。

自分の趣味とプログラミングが結びつくと、「これをもっと便利にするにはどうすればいいだろう？」と考える時間が増え、学習自体が楽しさに変わります。
コードを書くのが目的ではなく、自分の好きなことをもっと深めるための手段としてプログラミングを使えるようになると、学ぶモチベーションがどんどん湧いてくるのです。

さらに、趣味で作ったものが形になり、家族や友人に見せたときに「これ便利そうだね」と言ってもらえると、ますますやりがいを感じます。
プログラミングを学ぶことで、趣味がさらに広がり、自分だけの特別なツールやサービスを作れるという楽しさは、誰にでも共感してもらえるのではないでしょうか。


## まとめ

プログラミングを始めてから、私は「楽しい！」と感じる瞬間を何度も経験してきました。

自分の手で何かを作れる達成感や、エラーを乗り越えたときの喜び、そして趣味に応用できる幅広さは、プログラミングの大きな魅力だと思います。

これからプログラミングを始めようとしている方や、学び始めて間もない方には、「楽しむ気持ち」を大切にしてほしいです。

どんなに難しいと感じる瞬間があっても、乗り越えた先には必ず楽しい瞬間が待っています！
Ubuntu使いのwindows入門

ifconfig (linux) じゃなくて ipconfig

export Foo='An example'　じゃなくて　$Env:Foo = 'An example'


まずは、PowerShell
[PowerShell(パワーシェル)は何ができるの？メリット、使い方、実例まで](https://www.dospara.co.jp/5info/cts_str_pcuse_powershell.html)


sudo ではなく、PowerShellを管理者権限で起動する。

apt ではなく、windows用のインストーラファイルのダウンロードと実行

~/.bashrc ではなく　［システム］［詳細設定］［環境変数］
```
［Windows］＋［Pause］キーを押して、［設定］アプリの［システム］－［バージョン情報］画面（Windows 10の場合は［Windowsの設定］アプリの［システム］－［詳細情報］画面）を開く
［システムの詳細設定］リンクをクリックして、［システムのプロパティ］画面を開く
［詳細設定］タブの右下にある［環境変数］ボタンをクリックして、［環境変数］画面を開く
```


gcc + CMake 一択から Visual Studio の　*.sln


pycharm + Git Bashを使うと、ストレスが少し減る。
[WindowsにGit Bashをインストールする](https://qiita.com/suke_masa/items/404f06309bb32ca6c9c5)
【百聞より５分相談】仕事に取り掛かる前に認識をすりあわせる習慣をもとう

## 認識がすりあってない例
山田：
佐藤さん、この新しいWebページの案なんだけど、トップページのデザインを簡単に作ってみてくれない？

佐藤：
分かりました、トップページですね。いつまでに作っておけばいいですか？

山田：
うーん、３日後のミーティングまでにおねがい。色合いやレイアウトの大枠だけでもいいよ。

佐藤：
了解です！トップページを作成してみます。

## 3日後

![CleanShot 2024-12-06 at 22.18.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2883/96e2a6a0-a59b-bc1a-372f-771dea28b010.png)

山田：
佐藤さん、あのトップページの案、見せてもらっていいかな？

佐藤：
はい、こちらです！

（完成度の高いモックアップが用意されており、配色やテキスト、画像がかなり作り込まれている。）

山田：
おお、すごくしっかり作り込んであるね…！
でも、これ作るのに相当時間かかったんじゃない？

佐藤：
そうですね…細かいところもちゃんと詰めたほうが良いと思って、見た目や内容も調整しました。（昨日は徹夜もしたな）

山田：
なるほど…でも今回頼んだのはラフの段階だったんだよね。
今のクオリティは素晴らしいけど、まだ全体の方向性が固まってない段階だと、細部を作り込むのはあとでも良かったかな。

佐藤：
もっと軽いラフで方向性だけ確認するつもりだったんですね…。



## 「する、しない」をはっきりさせる

### そもそもの目的を明確にしてすりあわせる

山田さんはラフなページを作ってとおねがいしたと思っていて、
佐藤さんは作り込まれたページを要求されてると思ってしまった。

仕事を頼む側は、相手が納得して質問がなければ伝わっていると感じます。
今回であれば佐藤さんの方から「トップページは何のために必要で、どれくらいの品質を求めているのか」を確認しておきたいですね。

### 「決まってないこと」も合わせて確認する

決まったことの裏には、決まってないことや次回の会議で決めることもある。
という観点をもって、それらも合わせて確認すると抜け漏れがぐっと減らせます。

むしろ決まっていないことの方が重要という場面もあるので、「決まったことはコレ、決まってないことはコレ」と確認できているかを考える習慣を。


## １日５分相談する

**任されたその場ですぐによい質問が出せるか心配。**

なのであれば、途中で進行方向の確認をすればよいとおもいます。

佐藤さんが仕事を受けてから３日後までモクモクと作業を続けていたとすれば、１日に５分だけ相談をしていまの進捗状況をつたえる機会をつくると、その場でフィードバックをもらえて方向修正することができます。

まずは聞く、相談する。
そして、お互いにすりあった状態で仕事をすることを目指すことが成果への第一歩になります。
pandasを用いてデータをcsvファイルに保存したり出力したりする

# pandasを用いたcsvファイルの操作方法
## ヘッダー付きでデータをcsvファイルに保存
Pythonのリストから```pandas```データフレームを作成し、そのデータをヘッダー付きのcsvファイルに保存するプログラムを書く。
### データの内容
名前と年齢と在住している都市のデータを扱う。
- Name：人の名前（文字列）
- Age：年齢（整数）
- City：都市（文字列）

データは次の通りです：
- Alice, 30, New York
- Bob, 25, Los Angeles
- Charlie, 35, Chicago

ファイル名
- ```people_with_header.csv```

条件
- ヘッダーを含めるように保存すること。（ヘッダーとは、csvファイルやデータフレームの最初の行に含まれる列名（タイトル）のこと。今回で言えば、Name, Age, City である。）
```python 
import pandas as pd

data = {'Name':["Alice", "Bob", "Charlie"],
        "Age":[30, 25, 35],
        "City":["New York", "Los Angels", "Chicago"]}
        
df = pd.DataFrame(data)
df.to_csv("people_with_header.csv")
```
### 結果
![スクリーンショット 2024-12-06 22.23.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3901686/1e6f5154-09a7-0d5e-5fe4-c4102890540f.png)

## ヘッダーなしでデータを読み込む
 ```people_with_header.csv```ファイルをヘッダーなしで読み込む。ヘッダーを無視して読み込むには、```header=None```を使用する。
```python
# CSVファイルをヘッダーなしで読み込む
data_read = pd.read_csv("people_with_header.csv", header=None)
print(data_read)
```
```sql
     0        1    2           3
0  NaN     Name  Age        City
1  0.0    Alice   30    New York
2  1.0      Bob   25  Los Angels
3  2.0  Charlie   35     Chicago
```
### ポイント
- csvファイルの最初の行（```Name, Age, City```）がデータの一部として読み込まれる。
- 最初の列は、元々のインデックス列である。```to_csv()```のデフォルト設定でインデックスも保存されたため、この列が含まれている。

### インデックス列を含めたくない場合
```to_csv()```で```index=False```としてcsvファイルに保存することで、余計なインデックス列が含まれなくなる。
```python
# CSVファイルに保存（インデックスを含めない）
df.to_csv("people_with_header_no_index.csv", index=False)

# 再びヘッダーなしで読み込む
data_read_no_index = pd.read_csv("people_with_header_no_index.csv", header=None)
print(data_read_no_index)
```
### 結果
![スクリーンショット 2024-12-06 22.47.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3901686/c037dcd6-da59-087a-0720-d289793ea36a.png)
```markdown
       0   1            2
0   Name Age        City
1  Alice  30    New York
2    Bob  25  Los Angeles
3 Charlie  35     Chicago
```
## まとめ
- ```header=None```を指定することで、csvファイルの最初の列をヘッダーとして扱わず、全ての行をデータとして読み込む。
- ```to_csv()```の```index```パラメータを適切に設定することで、インデックス（行番号）を保存するかどうかを制御できる。
- ```index=False```とすることで、csvファイルにインデックスを含めずに、余分な行が生成されないようにできる。
DB設計④

## 正規化
### DBをマスターしたい
前回に引き続き、DBの基本知識を学習している
今回はER図についてまとめる

#### 参考文献
[達人に学ぶDB設計徹底指南書](https://www.amazon.co.jp/%E9%81%94%E4%BA%BA%E3%81%AB%E5%AD%A6%E3%81%B6DB%E8%A8%AD%E8%A8%88-%E5%BE%B9%E5%BA%95%E6%8C%87%E5%8D%97%E6%9B%B8-%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-%E3%83%9F%E3%83%83%E3%82%AF/dp/4798124702)

---
### 目次
1. ER図の役割
1. 正規化とは
1. ストレージの冗長構成
1. バックアップ設計
---

### 1.ER図の役割
#### テーブルが多すぎる
　正規化していくと、テーブルの数が増えていく
　＝管理が難しくなってくる
　そこでテーブルがどのように関連してるかを見えるようにする＝ER図

#### ER図とは
　ER図はEntity（実体）とRelationship（かんれん）の略である
　つまりテーブル同士の関連についての図であると言える

#### 2つの表記法
　E-R図の表記法はIDEF1XとIE表記法の2つある。

### 2.テーブルの関連
テーブルの関連は３種類ある
* 1対1
* 1対多
* 多対多

#### 1対1
　あまり見かけない
　二つのレコードのテーブルが1対1に対応するということ
　普通は一つのテーブルにまとめてしまって問題ない

#### 1対多
　最もよくある関連のタイプ
 「会社-社員」、「部署-社員」などが該当する
　１つの会社に対して複数の社員が所属する関係

### 3.E-R図の描き方
#### テーブル（エンティティ）の表記方法
　テーブルは以下のように表記します
　どちらの表記でも同じです。

![スクリーンショット 2024-12-04 22.37.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3659965/7c7fa0c2-f642-7b93-116d-0705a55966a1.png)

#### IE表記法でのE-R図
* 会社と社員の関係
　「会社」エンティティ側の横棒はカーディナリティが１であることを表す
　「社員」エンティティは０以上の複数を表します
　これは、社員が所属していない会社のレコードがある事を指す
　※カーディナリティ：相手のエンティティに対応するレコード数のこと
* 社員と部署の関係
　「部署」エンティティ側のカーディナリティは同じく1
　「社員」エンティティ側のカーディナリティは1以上の複数を表します
　これは、社員が所属していない部署のレコードはない事を指す
![スクリーンショット 2024-12-04 22.53.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3659965/986ce286-7d49-b600-31ae-5a849b199d32.png)

カーディナリティの記述パターンは以下となる
![スクリーンショット 2024-12-04 23.10.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3659965/0441f34f-1fcb-e1b8-25ab-fefbfb4069f3.png)


#### IDEF1XでのE-R図
* 独立エンティティ
　表記方法は角の尖った四角のエンティティ
　他のテーブルのデータに依存することのなく、データを保持できるエンティティ
　ex)会社テーブル、部署テーブル
 
* 従属エンティティ
　表記方法は角の丸い四角のエンティティ
　他のテーブルにデータが存在しなければ、データを保持できないエンティティ
　ex)社員テーブル

 ※双方の区別は主キーに外部キーが含まれているかどうかで判断する

![スクリーンショット 2024-12-05 23.19.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3659965/9962547e-d2ac-ea72-68d6-3a3a78cfc004.png)

カーディナリティの記述パターンは以下となる
![スクリーンショット 2024-12-05 23.26.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3659965/e4676541-61ab-6b8f-d6c7-4e4a41165d75.png)

### 4.「多対多」と関連実体
#### 「多対多」の具体例
* 学生と講義のリレーション
　1人の学生は複数の講義を受講できる＝カーディナリティは「多」となる
　1つの講義を複数の学生が受講できる＝カーディナリティは「多」となる
![スクリーンショット 2024-12-06 22.25.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3659965/5ce50ac3-ee24-b20f-ee2a-34a54e2f1cac.png)

* 解決方法は「関連実体」
　この多対多の関係を解決する方法が「関連実体」である
 ![スクリーンショット 2024-12-06 22.38.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3659965/ed223bd2-3a23-ae06-93a7-8d37cb930f6c.png)

関連実体（associative entity）は２つのエンティティの間に作られる
学生と講義それぞれに対して「１対多」の関係となる