OmniAICreator/Qiita-1.07M huggingface dataset:
「チェックリスト」というメチャ便利でメチャ危険なツール

## なぜチェックリストが必要なのか
業務に慣れていくにつれて担当するプロジェクトが増え、複数のタスクを同時に進行する場面が増えてきます。タスクが複雑化するにつれて、対応漏れなどのヒューマンエラーのリスクも高くなります。ヒューマンエラーによるミスや漏れが発生すると、対応コストやコミュニケーションコスト、場合によってはプロジェクトそのもののスケジュールが遅延する事態にまで発展します。

今回は、そのようなインシデントを防ぐのに有効なツールである「チェックリスト」について
* メチャ便利なポイント
* メチャ危険なポイント
* チェックリストとの付き合い方

の三つに分けてご紹介します。


## メチャ便利なポイント
### 作業内容とそのステータスが一目でわかる
当然ですが、プロジェクトごとに**納期**が存在します。そういった状況下で「自分はにどのような作業があるのか」「どれを優先して対応すべきなのか」といった**スケジュール管理**と**進捗率**を把握しておくことは非常に重要です。チェックリストによって、プロジェクトごとの作業内容が明確になるため、どのタスクのウェイトが重いかを把握しやすくなり、優先すべきタスクが浮き彫りになります。
また、納期までのスケジュールと作業内容が明確なのであれば、マイルストーンを設置することも可能です。マイルストーンと現在の進捗状況を照らし合わせて、ある程度の調整が行えるようにもなります。

:::note info
マイルストーン(milestone):中間目標地点。スケジュールの中での工程ごとの区切り。
:::

### 確認コストの削減
運用の方法にもよりますが、基本的に会話のログは肥大化し、過去のやり取りは埋もれてしまいます。
作業開始時や各環境反映時、作業中に気になることがあるたびにログを遡って確認することは効率が悪く、その都度確認に時間もかかってしまいます。
チェックリストを用いることで作業内容に関する確認が一目でわかるようになり、作業の経緯などを確認する際にだけログを遡ることで確認コストを削減できます。

![unnamed.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/652287/f68faa3a-0735-b6ec-de65-018ec67b41e0.png)


### 対応漏れを防げる
「チェックリストがあってよかった」と思うシチュエーションはヒューマンエラーによる対応漏れを防げた場合が多いです。完璧に対応できたと思っていても、意外と抜けている箇所や忘れられている箇所は存在します。チェックリストがあれば作業項目を一つずつ照らし合わせて確認できるため、対応漏れを防ぐことができます。
ただし、後述するメチャ危険なポイントには注意が必要です。


## メチャ危険なポイント
### 項目を精査しないと確認コストが上がる

以下のような項目はエンジニアにとって重要ですが、デザイナーやディレクターにはほとんど必要ありません。

- [ ] コードが正常にインデント、リファクタリングされているか
- [ ] 変数名、関数名、コメントアウトのフォーマットが統一されているか
- [ ] diffを確認し、適切な差分が検出されているか
- [ ] 実行時にコンソールエラー等が出ていないか

デザイナーは**デザイン通りのレイアウトになっているか**、ディレクターは**要件を満たしているか**など、担当によって確認するポイントが異なります。チェックリストに項目として存在している限り、それが自分の担当領域と関連性がなかろうと確認せざるをえなくなり、結果としてその分の確認コストが増大します。
エンジニアのみが見ておくべき、留意しておくべき項目はチェックリストに含めたままではノイズとなるため、プロジェクトメンバーにチェックリストを共有する際は項目の精査が必要です。

### チェックリストを放置するとむしろ対応漏れしやすくなる
チェックリストは自分の作業内容とそのステータスをリスト化したものです。しかし、一度チェックリストを作成したからといって放置することは非常に危険です。
プロジェクトを進める中で、先方とのやり取りや追加要望などによって作業内容が増減することは決して珍しくありません。もしその際にチェックリストを更新しなかった場合、その間の追加部分はチェックリストからは漏れ、結果として**対応漏れに気付かず、チェックリストはクリアしているから漏れがあるとも思わず慢心する**という、むしろチェックリストが存在することによるヒューマンエラーが発生しかねません。
チェックリストが不完全であったためにインシデントが発生し、それに対応コストがかかってしまうようでは本末転倒です。

![unnamed (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/652287/28ab0c97-080e-ef54-8a87-0228090bfffa.png)

## チェックリストとの付き合い方
ここまでの説明だと「ハイリスクハイリターンでは」と思われるかも知れませんが、適切な付き合い方をすることによってリスクを最小限にすることが可能です。以下は私が考える適切なチェックリストとの付き合い方です。

### 自分用とは別でプロジェクトメンバー用を作る
先ほど、**チェックリストを共有する際は項目の精査が必要**とお話しさせていただきましたが、では、どのようにチェックリストを作成し、精査すれば良いのでしょうか？
結論から言うと**全ての項目が含まれた自分用のチェックリストを作成し、そこから項目を精査したプロジェクトメンバー用のチェックリストを作成する**のが作成手順として良いと思います。

### 作業内容が更新されるたびにチェックリストも更新する
**チェックリストは完成しないもの**という考えを持つことが大事です。
作業内容の増減に合わせてチェックリストを更新することは必須です。
また、
* 過去の状態を保持しておく必要がほとんどない
* どのチェックリストが最新かわからなくなる

上記の理由から、作業内容が増減するたびにチェックリストを一から作りなおすのではなく、一つのチェックリストを更新し続ける方針が良いと思います。
チェックリストは対応するプロジェクトの小課題や課題本文に記載しておくと、そのプロジェクトとチェックリストの紐付けがよりわかりやすくなります。

### それでも過信しない
チェックリストはあくまでも自分のタスクをわかりやすくするためのものであり、**クリアすれば何も問題がないと断定できるもの**ではありません。上記までの対応を完璧に運用できたとしても、各環境への反映時や先方への展開時などの重要な場面では、念の為ログを確認したり作業内容を今一度洗い出すことで万が一のミスも防ぐことができます。

## まとめ
今回は私が考えるチェックリストの便利なポイントと注意点、それらを踏まえた付き合い方についてご紹介させていただきました。チェックリストをうまく活用して制作物の精度を上げていきましょう！
ソケットプログラミングで学習したことをまとめてみた①（ソケットの作成から接続まで）

# はじめに
こんにちは。
[42tokyo](https://42tokyo.jp/)といったところで、コンピュータサイエンス？を学んでいます。
最近、簡単なIRCサーバを実装する課題を通して、ソケットプログラミングについて学びました。
本記事は、ソケットの作成についてまとめています。

間違い等があれば、ご指摘ください。

:::note info
本記事では、TCP/IP上で行われる通信を想定しています。
:::


# 本記事における用語について
:::note info
「ソケットAPI」とは、
* ソケットに関連するシステムコールの総称
* ソケットに関連するシステムコールとは、socket()、bind()、listen()、connect()、accept()、send()、recv()など
:::
:::note info
「ソケット構造体」とは、

* 本記事において、あるソケット(TCP)に関する諸情報をまとめて「ソケット構造体」と呼ぶ
* 諸情報とは、以下の通り
  * FIFOバッファ(SendQ, RecvQ)
  * ソケットの状態
  * ローカルipアドレス
  * ローカルポート
  * リモートipアドレス
  * リモートポート
:::

* 「ソケット構造体」は、socket()によって生成されたディスクリプタでアクセスする
* 「ソケットAPI」は「ソケット構造体」が持つデータを扱うものと言える

# まとめ（全体図）
![スクリーンショット 2024-06-19 18.31.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282897/f557f0c9-928b-db70-5ed0-ea537fa26474.png)

# 参考
https://www.ohmsha.co.jp/book/9784274065194/

https://ja.manpages.org/socket/2

https://ja.manpages.org/bind/2

https://ja.manpages.org/listen/2

https://ja.manpages.org/connect/2

https://ja.manpages.org/accept/2

# サーバ=クライアント間における接続処理について
### サーバ側の動き（socket(); -> bind(); -> listen();まで）

[int socket(int domain, int type, int protocol);](https://ja.manpages.org/socket/2)
* ソケット構造体が作成される
* 戻り値のディスクリプタは、この構造体にアクセスできる
* ソケットの状態は、Closed

[int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);](https://ja.manpages.org/bind/2)
* クライアントが識別可能なローカルポートを設定する
* クライアントは、ここで設定されたローカルポートを目印に、connect()を実行する

[int listen(int sockfd, int backlog);](https://ja.manpages.org/listen/2)
* クライアントのconnect()を待ち受ける状態になる
* ソケットの状態が、Listeningになる

![スクリーンショット 2024-06-19 18.33.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282897/e39b25e0-27ea-9a2a-5224-a8edcf270267.png)

### クライアント側の動き(socket(); -> connect();まで)
[int socket(int domain, int type, int protocol);](https://ja.manpages.org/socket/2)
* ソケット構造体が作成される
* 戻り値のディスクリプタは、この構造体にアクセスできる
* ソケットの状態は、Closed

[int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);](https://ja.manpages.org/connect/2)
* ソケット構造体の4箇所にそれぞれ値が代入される
* ローカルポートには、使用されていない値が割り振られる（bind()していないので)
* サーバとの接続処理が始まり完了すると、ソケットの状態は、Establishedとなる
* ソケットの状態が、Cnnectedになる

![スクリーンショット 2024-06-19 18.35.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282897/69f02c5c-c157-9fc3-0f6e-a996d702db2e.png)

### サーバ側の動き(accept()まで)
[int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);](https://ja.manpages.org/accept/2)
* クライアントから接続要求がきたら、新しいソケット構造体を作成する
* 各フィールドには、パケットから適切な値を取り出し代入する
  * ローカルipアドレス = パケットの送信先ipアドレス
  * ローカルポート　　= パケットの送信先ポート(サーバのローカルポートと同じ値)
  * リモートipアドレス = パケットの送信元ipアドレス
  * リモートポート　　= パケットの送信元ポート
* ソケットの状態は、Connecting、not-quite-connected socketsの順番に遷移し、クライアントとの接続処理が完了すると、Establishedとなる

![スクリーンショット 2024-06-19 18.36.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282897/1f6f957d-a4d9-3ee7-4f84-8d1343e57206.png)

# さいごに
聞き慣れない用語が沢山あったので、理解に時間が掛かりました。
不備があればお申し付けください。
次回は、recv();, send();について学んだことをまとめていきます。
ありがとうございました。

つづき

https://qiita.com/gu-chi/items/7e598b3b0343a4782b10
スケールするシステムを作りたいときに考慮する設計

1人だけに使われるシステムを作る場合は単一のサーバーにそのままリクエストしてレスポンスを返すだけで十分に動くことが多い。

しかし1億人に使われるシステムを作るにはそれだけでは十分ではなくなってくる。

この記事では1人に使われるシステムから1億人に使われるシステムをスケールさせる際に考えるべき点を書いていく。

注）人数はあくまで例で1と1億がわかりやすく差があると思っているのでそんな表現をしています。

## 1人に使われるシステム

フロントエンドとバックエンドサーバーとデータベースサーバーを構築することで1人（実際にはもっと人数がいてもいい）が利用する分には問題ないことが多い。

![single.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/655827/42e2f72e-e218-6116-7f63-d1a61a1371d6.png)


バックエンドサーバーとDBサーバーとにおける処理のおおよそのフローとしては2つ。

1. バックエンドサーバーはクライアントからリクエストを受け取る
1. バックエンドサーバーからDBサーバーにクエリを発行してクライアントにレスポンスを返す

ユーザー数が少なければこれで十分動き続ける。

## 1億人に使われるシステム

ユーザー数が増えるに連れて各サーバーの負荷が上がってくる。

サーバーのリソースが枯渇してしまうとレスポンスを返すことができなくてユーザーが困ってしまう。

こんな悲しい状態にならないために各サーバーを冗長構成にして負荷分散をすることを考えましょう。

### バックエンドサーバーの冗長化

クライアントからリクエストが来た時に単一のサーバーで処理しきらずに複数の同一の処理をするサーバーに分散させることができる。

![be_dup.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/655827/5c9a6ccc-54d8-ce2f-c18c-9d97451c4b8c.png)


一般的にクライアントからのリクエストは直接バックエンドサーバーに向かわせずにロードバランサー(LB)に向かわせることが多い。

LBは複数のバックエンドサーバーへ振り分けて1台あたりの負荷を減らすことでリソースが枯渇することを回避させることが可能になる。

またLBを導入するとあるサーバーが障害を起こして止まってしまった場合には別のサーバーに処理を流すように設定することができ、サービスを使い続けられる状況を維持することができるようになる。

### DBサーバーの冗長化

DBサーバーの冗長化も考えてみましょう。

ここでの考慮すべきポイントバックエンドサーバーと同様に冗長化すると保存されたデータが分散されることになります。

例えば3台のDBサーバーがあり、あるレコードを保存した時には3台のDBサーバーのうちの1台に保存されることになり、データ取得時にどのDBサーバーからデータを取得するかを考える必要があります。

（シャーディングという手法を使うことでデータを分散して保存することができますが今回は別の方法を紹介します）

これを解決方法はレプリケーションという手法を使うことができます。

レプリケーションは1台のDBサーバーの状態を他の複数のDBサーバーに同期することで冗長化を実現する手法です。

その1台をソース、他の複数台をレプリカと呼び、書き込み処理はソースに対して行い、読み込み処理はレプリカに対して行うことで負荷を分散させることができます。

![db_dup.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/655827/2449aba4-079e-0b01-1c35-48ccaa3bba70.png)


この構成ではソースが障害を起こしてしまった場合にはレプリカをソースに昇格させることでサービスを継続させることができます。

## 1億人に快適に使われるシステム

ここまでで多くのユーザーが使えるシステムを作る手法を紹介してきた。

一方で遅延がなく快適に使われるかについては度外視してきたため、ここからは快適に使われるための設計を考えていく。

快適と言っているのはローディングスピナーがいつまでもぐるぐる回っていなく、あるイベントが発生したら速く反応してくれることを指している。

### キャッシュの導入

キャッシュとはデータを一時的に保存しておくことでデータ取得時にオリジンへのアクセスする回数を減らし高速化する手法です。

システム構成に限らずプロセッサ、ディスク、メモリやCDNなど様々な箇所でキャッシュを導入することができます。

ことサーバーサイドのキャッシュについてはRedisやMemcachedなどのインメモリデータベースを使ってキャッシュを導入することができます。

![cache.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/655827/2ddb437e-9b9d-68f7-5fae-ab2fa733407e.png)


動きとしては

1. キャッシュにデータがあるか確認する
1. キャッシュにデータがあればキャッシュからデータを取得して返す
1. キャッシュにデータがなければオリジンからデータを取得してキャッシュに保存して返す

という流れになります。（これをRead Throughと呼びます。）

特に読み込み処理が多く、その読み込みが複雑で重い処理であればキャッシュを導入することで高速化することができます。

### 非同期処理の導入

読み込みだけでなく書き込みを高速化する手法もあります。

それが非同期処理で。非同期処理はリクエストを受け取った後にその処理をバックグラウンドで行う手法です。

![queue.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/655827/1c5244f9-ef2f-1f3a-9e60-8abbe3663937.png)


あるリクエストが来た時にその処理を全て完了させてからレスポンスを返すのではなく、リクエストを受け取った後にキューイングをしてレスポンスを返し、リクエストに対して非同期的にワーカーで処理を行うようにすることで高速化することができます。

リクエストを受け取ったらサーバーはメッセージキューにリクエストを入れておき、ワーカーがそのキューからリクエストを取り出して処理を行うことで高速化することができます。

## まとめ

システムをスケールさせて、かつ快適に使われる手法をまとめてみました。

負荷分散やキャッシュ、非同期処理などを導入することでユーザーが快適に使えるシステムを作ることができ、ユーザー思いの設計をできるようになりましょう。
CloudFormationでManaged Preflix Listを作成しよう！

## 概要
CloudFormationでManaged Preflix Listを作成する方法について解説します

## Managed Prefix Listとは
簡単に説明するとIPアドレスを格納するリスト群です


## Managed Prefix Listの作成
今回はPrefix Listの作成とUserAとUserBのIPv4のIPアドレスを登録するCloudFormationのテンプレートを作成します
主に

- セキュリティグループおよびネットワークACLのIPアドレスの管理
- WAFが許可、拒否するIPアドレスの管理

などで使用されます

```yaml
AWSTemplateFormatVersion: 2010-09-09
Description: "Managed Prefix List for my-project"

# -------------------------------------
# Metadata
# -------------------------------------
Metadata:
  AWS::CloudFormation::Interface:
    ParameterGroups:
      - Label:
          default: "Project Configuration"
        Parameters:
          - ProjectName
      - Label:
          default: "Managed Prefix List Configuration"
        Parameters:
          - UserA
          - UserB

# -------------------------------------
# Parameters
# -------------------------------------
Parameters:
  ProjectName:
    Description: "Enter the project name (ex: my-project)"
    Type: String
    MinLength: 1
    ConstraintDescription: "ProjectName must be enter"
    Default: my-project
  UserA:
    Description: "Enter the IP addresses for UserA (ex: 0.0.0.0/32)"
    Type: String
  UserB:
    Description: "Enter the IP addresses for UserB (ex: 1.1.1.1/32)"
    Type: String

Resources:
  # -------------------------------------
  # Managed Prefix List
  # -------------------------------------
  PrefixList:
    Type: AWS::EC2::PrefixList
    Properties:
      PrefixListName: "IP Address Lists For Remote Developers"
      AddressFamily: "IPv4"
      MaxEntries: 10
      Entries:
        - Cidr: !Ref UserA
          Description: "UserA Remote User IP List"
        - Cidr: !Ref UserB
          Description: "UserB Remote User IP List"
      Tags:
        - Key: ProjectName
          Value: !Ref ProjectName

# -------------------------------------
# Outputs
# -------------------------------------
Outputs:
  PrefixList:
    Value: !Ref PrefixList

```

## 実際に作成してみよう！
以下のようにPrefix Listが作成され、指定したIPアドレスが登録されたら成功です

![スクリーンショット 2024-07-05 15.00.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/625980/8f1dbbd2-11c6-e189-fae6-d933c74c592a.png)

![スクリーンショット 2024-07-05 15.00.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/625980/35ba0892-3ca2-ff67-1981-29b7551f44b0.png)

![スクリーンショット 2024-07-05 15.01.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/625980/6fbf6c38-a053-766b-534a-cf8eca572f6b.png)


## まとめ
Managed Preflix Listをコード化できるのは便利なものの、IPアドレスを配列として複数以上登録できるようにしてほしいですよねー
CloudFormationで実現できる方法がわかり次第追記していきたいと思います

## 参考
https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-prefixlist.html#cfn-ec2-prefixlist-entries

https://www.idnet.co.jp/column/page_188.html
【コード付き】売上データのツリーダイアグラムでの可視化

# 売上データのツリーダイアグラムでの可視化

## 概要
この記事では、新規顧客と既存顧客からの売上をさらに一回当たりの平均購入単価、購入人数、購入回数に分解し、この情報をツリーダイアグラムで可視化する方法を解説します。Pythonの`networkx`ライブラリを使用し、JupyterLab環境での実行を前提としています。
![スクリーンショット 2024-07-05 140403.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3804860/ff437bf8-9c25-b4dd-51f5-29007a7d6036.png)


## 1.必要なライブラリのインストール
まず、以下のコマンドを実行して、必要なライブラリをインストールします。

```bash
pip install networkx matplotlib
```

## 2. NetworkXを使った有向グラフの作成
```python:qiita.rb
G = nx.DiGraph()
```
nx.DiGraph()はnetworkxライブラリを用いて空の有向グラフを作成します。このグラフはノード（点）とエッジ（矢印つきの線）を追加して拡張できます。

## 3.ノードを追加
```python:qiita.rb
node_labels = {
    'Revenues': format_currency(revenues),
    'New Customers': format_currency(new_customer_rev),
    'Existing Customers': format_currency(exi_customer_rev),
    'People New': str(new_customer_amount),
    'Per Order Money New': format_currency(new_customer_per_order_money),
    'Frequency New': str(new_customer_freq),
    'People Existing': str(exi_customer_amount),
    'Per Order Money Existing': format_currency(exi_customer_per_order_money),
    'Frequency Existing': str(exi_customer_freq)
}
for key, value in node_labels.items():
    G.add_node(f'{key}\n{value}')
```
ここではまずnode_labelsという辞書を使って各ノードのラベルと値を定義しています。format_currency()関数を使って数値をフォーマットし、各ノードに名前と値を割り当てます。その後、forループを使ってこれらのラベルを持つノードをグラフGに追加します。

## 4. エッジの追加
```python:qiita.rb
edges = [
    ('Revenues', 'New Customers'),
    ('Revenues', 'Existing Customers'),
    ('New Customers', 'People New'),
    ('New Customers', 'Per Order Money New'),
    ('New Customers', 'Frequency New'),
    ('Existing Customers', 'People Existing'),
    ('Existing Customers', 'Per Order Money Existing'),
    ('Existing Customers', 'Frequency Existing')
]
for src, dst in edges:
    G.add_edge(f'{src}\n{node_labels[src]}', f'{dst}\n{node_labels[dst]}')
```    
 各ノード間の関係（つまりエッジ）を定義しています。エッジはタプルのリストで表され、それぞれのタプルはエッジの始点と終点を示します。forループを使って、これらのエッジをグラフに追加しています。

 ## 6.# レイアウトを定義
 各位置のノードを定義
 ```python:qiita.rb
pos = {
    f'{key}\n{value}': coord for key, value, coord in zip(node_labels.keys(), node_labels.values(), [
        (0, 2), (-1, 1), (1, 1),
        (-3, 0), (-2, 0), (-1, 0),
        (1, 0), (2, 0), (3, 0)
    ])
}
 ```
 ## 5. グラフの描画
```python:qiita.rb
plt.figure(figsize=(18,8))
nx.draw(G, pos, with_labels=True, node_size=9000, node_color="orange", font_size=10, font_color="black", font_weight="bold", arrows=True)
plt.title("Sales Tree Diagram")
plt.show()
```
checkov に無視してもらいたい

## はじめに

Super-Linter が 6.0.0 から checkov をサポートしました

https://github.com/super-linter/super-linter

これにより、これまでより一層厳密なチェックが行われます

ただし、どうしてもチェックで無視してほしい場合というのが出てきます

この記事では GitHub Actions の Super-Linter で checkov に無視してもらう方法を紹介します

## checkov とは

checkov はクラウドインフラの構成定義をチェックするツールです

IaC (Infrastracture as Code) ツールで使用するファイルを静的解析し、セキュリティリスクなどを検出します

https://www.checkov.io/

以下のような IaC 用ファイルに対応しています

- Terraform
- CloudFormation
- AWS SAM
- Kubernetes
- Dockerfile
- Ansible

## 設定ファイルによる無視

checkov 自体の設定ファイルでルール単位、IaCツール単位の無視が可能です

https://github.com/bridgecrewio/checkov?tab=readme-ov-file#configuration-using-a-config-file

```yml
skip-check: 
  - CKV_DOCKER_3 
  - CKV_DOCKER_2 
skip-framework:
  - dockerfile
  - secrets
```

デフォルトの設定ファイル名は `.checkov.yaml` ですが、実行時に `--config-file` で指定可能です

## リソース内のコメントによる無視

各ファイル内にコメントとして無視対象のルールを書くことで無視できます

https://www.checkov.io/2.Basics/Suppressing%20and%20Skipping%20Policies.html

```terraform
resource "aws_s3_bucket" "foo-bucket" {
  region        = var.region
  #checkov:skip=CKV_AWS_20:The bucket is a public static content host
  bucket        = local.bucket_name
  force_destroy = true
  acl           = "public-read"
}
```

## Super-Linter での checkov

毎回全てのファイルをチェックしていると時間も費用もかかるため、通常は変更箇所のみチェックするように GitHub Actions を設定します

```yml
---
...
      - name: Lint Code Base
        uses: github/super-linter/slim@v6
        env:
          DEFAULT_BRANCH: main
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          LINTER_RULES_PATH: ./
          VALIDATE_ALL_CODEBASE: false
```

`VALIDATE_ALL_CODEBASE: false` とすることで、 `DEFAULT_BRANCH` に指定した `main` との差分だけをチェックできます

ただし、 checkov に関しては複数ファイル間の参照まで検証する必要があるため、 **必ず全量がチェックされます**

プルリクエストに関係ない箇所までチェックするため厳密で良い反面、後に対応する予定の箇所などであっても毎回必ずエラーになってしまいます

Issue にも取り上げられていますが、今のところ対策は立てられていません

https://github.com/super-linter/super-linter/issues/5308

従って、エラーになるのを防ぐためには checkov に無視してもらう他ない状況です

### checkov の無効化

`VALIDATE_CHECKOV: false` とすることで checkov 自体を無効化することが可能です

ただし、無視すべきもの以外も全て無視することになるためオススメしません

### checkov の設定ファイル

環境変数 `CHECKOV_FILE_NAME` で checkov の設定ファイル名を指定可能です

デフォルトでは `.checkov.yaml` になっています

`LINTER_RULES_PATH: ./` の場合、プロジェクトのルートディレクトリー配下に `.checkov.yaml` を作ることで設定を変更できます

`.checkov.yaml` 内に無視したいルールを書きましょう

## まとめ

以下の方法で checkov のエラーを無視することができました

- `.checkov.yaml` ファイルにスキップ対象のルールを書く
- 各ファイル内にコメントでスキップ対象のルールを書く

無視する方法を書きましたが、基本的には無視せず対処した方が良いです
AWS Transfer Family で SFTPサーバーを起動してコンソールから接続する例

# STEP 1.  AWS S3 のバケットを作成しておく

SFTPサーバーのファイル保存先は選択できるが、デフォルトはS3なので、まずはバケットを作成しておく

この例ではバケット名を `this-is-the-example-bucket` とする

![CleanShot 2024-07-05 at 13 32 10@2x](https://github.com/YumaInaura/YumaInaura/assets/13635059/17b5fec9-7327-4977-b58b-083264e21b98)

バケットのパブリックアクセスは全てブロックしたままで良い


# STEP 2. SFTPサーバーを作成する

![CleanShot 2024-07-05 at 13 22 33@2x](https://github.com/YumaInaura/YumaInaura/assets/13635059/e6909a17-9db5-4c2c-8e9b-6f9ebff7e3da)

(途中にいくつかの画面が表示されるが、デフォルトのまま進む)

デフォルトのままS3を選択する

![CleanShot 2024-07-05 at 13 23 52@2x](https://github.com/YumaInaura/YumaInaura/assets/13635059/f37b65e3-7c42-4563-a465-17dec2fc829a)

サーバー作成時にはまだ具体的なS3バケットは選択できない

# STEP 3. ロールを作成する

SFTPユーザが利用するロールを作成する

ユースケースから選ぶと簡単だが、権限が広いので実利用の場合は注意が必要そう

![CleanShot 2024-07-05 at 13 59 14@2x](https://github.com/YumaInaura/YumaInaura/assets/13635059/81a983e8-b4bf-4766-9866-012d16d869f7)

## ポリシーの選択

いろんなポリシーの候補が表示されるが、以下を選んでおく

ここではテストのため広い権限のポリシーを指定するが、実運用ではもっと権限を絞るべし

- AmazonS3FullAccess
- AWSTransferFullAccess

## 信頼関係

ユースケースからのロール作成では、以下の信頼関係も最初から設定されている

>サービスに使用されるすべてのロールは、transfer.amazonaws.com を信頼する必要があります。

https://docs.aws.amazon.com/ja_jp/transfer/latest/userguide/requirements-roles.html#role-create-procedure

```json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "transfer.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
```

# STEP 4 . SFTPユーザーの作成

AWSユーザーとは全く別の、SFTPサーバーへの接続用ユーザを作成する

## local でユーザ用の鍵を作成する

鍵の作成

```
ssh-keygen -f sftp_example -N ''
```

生成された公開鍵のファイル内容をコピーするなどして控えておく

```
cat sftp_example.pub
```

## AWSでサーバーのユーザーを登録する

### 基本項目

- ここでS3バケットを選ぶ項目がある
- さっき作ったロールを指定する

![CleanShot 2024-07-05 at 14 04 02@2x](https://github.com/YumaInaura/YumaInaura/assets/13635059/e182de29-daf2-406c-a18e-4c876a490554)

## 公開鍵の登録

localで作った公開鍵の中身を入力する

![CleanShot 2024-07-05 at 13 50 57@2x](https://github.com/YumaInaura/YumaInaura/assets/13635059/4b0c5fc3-fb65-4cdb-9fda-8309a8ae3f76)

# STEP 5. SFTPサーバーに接続する

こんなコマンドで接続する

localで試しても良いし、sftpコマンドが実行できる環境であればどこからでも良い

```
sftp -v -i <作成した秘密鍵のパス> <SFTPユーザー名>@<SFTPサーバーのエンドポイント>
```

- 「作成した秘密鍵のパス」は実行環境のlocalでのファイルパス
- 「SFTPユーザー名」はさっき作成したユーザ名
- 「SFTPサーバーのエンドポイント」はAWS上で確認できる

具体例

```
sftp -v  -i ./sftp_example example-sftp-user@*****.server.transfer.*********.amazonaws.com
```

## SFTPコマンド

接続できたらSFTPコマンドを試してみる

カレントディレクトリを表示する

```
sftp> pwd
Remote working directory: /this-is-the-example-bucket/example-sftp-user
```

接続元 (local)のファイルをSFTPサーバーに転送する

```
sftp> put example.txt
```

転送されたファイルの確認をする

```
sftp> ls
a.txt
```

終了する

```
sftp>quit
```


# エラー対策

「sftpサーバーに接続は出来るが、権限エラーでコマンドが実行できない」という場合はロールの権限、もしくは信頼関係の設定が抜けていると思われるため、上記の手順通りの設定にする

```
sftp>ls
remote readdir("/****"): Permission denied
```



# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ


# プロフィール・経歴

https://github.com/YumaInaura/YumaInaura
DJI Virtual Flight （Windows版）をAVATA 2 のコントローラー３で使えるようにする方法

## 説明
　無料のドローンシミュレーターであるDJI Virtual Flight (Windows版）は、そのままでは、DJI AVATA 2用の送信機３では使えません。

 ただ、XBOXのコントローラーでは使えるので、X360CEと言うエミュレーターソフトを使うことによって、送信機３をXBOXコントローラとして、認識させてしまうわけです。
 　この方法を使えば、手持ちのプロポも使えるようになります。

## 用意するもの
①　DJI Virtual Flight ソフト
②　X360CE　ソフト
③　プロポ　（DJI コントローラー ３、又は自前のプロポ）

## ① DJI Virtual Flight をダウンロードする
　ここでまず、つまづきます。日本のDJIサイトからは、なぜかダウンロード出来なくなっています。 そこで、サイトを日本以外、例えばアメリカとかに変更してからでないと出来ません。
 やり方は、まず[DJIのホームページ](https://www.dji.com/jp)に移動して、一番下までスクロールしたら、右下の [日本/日本語] と言うところをクリックして、出てきたメニューから、北アメリカの[United States]を選択して下さい。
 
 
 ![国選択.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2520758/2b9b47ff-be21-39ab-64a1-7a79e0996dcd.png)
そうしたら、一番上のメニューから[support]を選択して下さい。
  下の画面に成ったら、[View all Download Center>]をクリックします。
 ![ダウンロード.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2520758/6e0260b9-660b-f083-2244-b2940a071997.png)
 そうしたら、左メニューから[Software]➡[Other Software]➡[DJI Virtual Flight]を選択して、Windows版をダウンロードして、インストールして下さい。
 ![virtualflight.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2520758/f2ae92fa-da2b-637b-d1f3-92ebafc46cb2.png)


## ② X360CEをダウンロードする
[X360CEのダウンロードサイト](https://www.x360ce.com/)に行き、最新版をダウンロードして下さい。
![X360CE.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2520758/42705618-9dea-94de-f37b-9f064117c96d.png)
インストールは必要ないので、解凍したら、[X360CE.exe]ファイルを適当なところに保存して下さい。

## X360CE の設定
X360CE.exeを起動して下さい。
もし、[issues]タブの所に、不足のドライバーやDLLファイルが出てたら、インストールして下さい。私は何も必要なかった気がします。
![issues.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2520758/12170cac-0870-3f04-6529-666cc91c9190.png)

 準備が出来たら、登録したいプロポをUSBでPCに繋いで下さい。
 [Controller1]タブに戻って、[+Add]を押し、繋いだプロポを選択し、[Add selected Device]を押します。
![X360CE設定.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2520758/99e6bf7c-1fa2-4c02-95e2-f0111555917b.png)

 そしたら、各ボタンにプロポのボタンやスティックを割り当てましょう。
 割り当てたい場所をマウスでクリックしたら、プロポのスティックやボタンを押して登録していきます。
DJIコントローラ３の場合は以下のように割り当てましょう。
![X360ce-DJI.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2520758/94b4c553-d167-f805-35af-0fb89290fd29.png)
 設定を終えたら、画面右上の[Save All]を押して保存します。
 [＋Add]で、複数のプロポをController1に割り当てできます。

以上で準備は完了です。

## 実行
先ず、「X360CE」を起動します。最小化して大丈夫です。
次に「DJI Virtual Flight」を起動します。

　この時一つ注意することがあります。 それは、**メニュー選択画面の時は、プロポのスロットル位置を中央にして置くこと**です。
　また、他のスイッチもすべてOFFの状態にして置かないと、マウスのクリックが上手く反応してくれません。

以上です。
無料のシミュレーターを存分に楽しんでください。
Zabbix7.0のインストール（AlmaLinux9、PostgreSQL版）

# 本記事について
備忘を兼ねつつインストール手順をまとめておく。
ぶっちゃけZabbixのダウンロードページでもコマンド等記載があるが、本記事で少し補足する。
https://zabbix.com/jp/download

参考サイト様：https://tech-mmmm.blogspot.com/2024/06/zabbix-70almalinux-9postgresql.html
↑こちらのサイト様ではZabbixのWeb画面に入ってからの初期設定の画面キャプチャもあるのでおススメです

# 構築環境
VMware上に仮想マシンとして展開
|項目|設定値|
|:-:|:-:|
|OS|AlmaLinux 9.4|
|CPU|2vCPU|
|メモリ|16GB|
|DB|PostgreSQL 13.14|
|WebServer|Apache 2.4.57|
|Zabbix|Ver.7.0|

# インストール手順
 ひとまずOSをインストールする。設定値は任意で。
dnf upgradeで全パッケージを最新化しておく。

以下コマンドでSELinuxが動いてるか確認。
```
getenforce
```
表示がEnforcingの場合は動いてるので、以下ファイルを編集。
```
# /etc/selinux/config
SELINUX=enforcing ← disabledに変更
```
もう一度確認し、Disableと出力されればSELinuxの停止はOK。

ポート空けとか面倒なら、firewalldも切っておく。

PostgreSQLをインストールする。導入するZabbixのバージョンがサポートしているバージョンのものを入れるべし。
```
dnf install postgresql-server postgresql-contrib
```
DBの初期化を実施。
```
postgresql-setup initdb
```
postgreの認証方式をmd5に修正する。
```
# /var/lib/pgsql/data/pg_hba.conf

# "local" is for ...
local   all   all   peer ← peerをmd5に変更
# IPv4 local connections:
host   all   all   ident ← identをmd5に変更
# IPv6 local connections:
host   all   all   ident ← identをmd5に変更
```
必要に応じて以下ファイルを編集する。
```
# /var/lib/pgsql/data/postgresql.conf

shared_buffers = 128MB ←　共有メモリバッファの容量、OS割り当てメモリの25%ほどを充てておく
checkpoint_timeout = 5min ← 5分は短いみたいなので、30minへ変更
max_wal_size = 1GB ← こちらも少し増加させておく
```
postgreSQLを再起動&自動起動設定
```
systemctl restart postgresql
systemctl enable postgresql
```
Zabbix7.0をインストールする。
```
rpm -Uvh https://repo.zabbix.com/zabbix/7.0/alma/9/x86_64/zabbix-release-7.0-3.el9.noarch.rpm
dnf clean all
dnf install zabbix-server-pgsql zabbix-web-pgsql zabbix-apache-conf zabbix-sql-scripts zabbix-selinux-policy zabbix-agent
```
:::note warn
EPELリポジトリを導入している場合、エラーが出てインストールできない。
その場合は以下ファイルでzabbix関係のパッケージをEPELからダウンロードしないように設定する。
```
 # /etc/dnf/dnf.conf
    
[epel]
excludepkgs=zabbix*
```
:::

Web管理画面の言語を英語や日本語にしたい場合は以下パッケージもインストールする。
```
dnf install glibc-langpack-en zabbix-web-japanese
```
PostgreSQLでZabbix用のユーザとDBを作成する。
```
su - postgres -c "psql -c \"create user zabbix login encrypted password '[password]'\""
su - postgres -c "createdb -O zabbix zabbix"
```
ZabbixDB初期化用SQLファイルの流し込みを行う。echoの結果が0ならOK。
```
zcat /usr/share/zabbix-sql-scripts/postgresql/server.sql.gz | sudo -u zabbix psql zabbix > /dev/null
echo $?
0
```
Zabbixを起動&自動起動設定。
```
systemctl restart zabbix-server zabbix-agent httpd php-fpm
systemctl enable zabbix-server zabbix-agent httpd php-fpm
```
以下URLにアクセスし、ZabbixのWeb管理画面へ接続する。
http://(Zabbixサーバのホスト名 or IPアドレス)/zabbix/

画面に表示される指示に従って初期設定を完了する。
1. デフォルトの言語は「日本語（ja_JP）」を選択する。
1. 前提条件のチェックですべて「OK」のステータスとなっていることを確認する。
1. 「データベース接続設定」では以下を設定する。
    ・「データーベーススキーマ」は、空欄。
    ・「パスワード」は、事前に設定したZabbixユーザのパスワードを入力。
    ・「データベース接続のTLS暗号化」は、任意でチェックを入れる。同一サーバにDBがあるなら特に不要かと思う。
1. 「設定」では以下を設定
    ・「Zabbixサーバー名」は任意の名前を設定する。サーバのホスト名とかでいいと思う。
    ・「デフォルトのタイムゾーン」はAsia/Tokyoを選択。
    ・「デフォルトのテーマ」は好みで選択する。
1. 「設定パラメータの確認」で設定項目に問題ないことを確認する。

初期設定が完了するとログイン画面が表示される。初期アカウントは以下となる。
・ID：Admin
・Password：zabbix

管理画面が表示されればZabbixの初期設定は完了となる。
【カタカナ】IT用語の読み方

# はじめに

なんてよむかわからない、けど、検索してもすぐに確定しない
そういう単語の読み方をカタカナでここに残します

:::note info
ほかの読み方もあるかもしれませんね
:::

# 読み方

| 単語 | ヨミカタ |
|:-:|:-:|
| awk | オーク　／　オウク |
| cron | クーロン |
| IEEE  | アイトルプルイー  |
| k8s | ケーエイツ |
| Kubernetes | クーバネティス ／ クバネティス |
| PoC  | ピーオーシー ／ ポック  |
| Proxmox | プロックスモックス |
| stonith  | ストニス  |
| corosync | コロシンク |

# さいごに

むずかしい
Insta360 x4から画像を取り出す

ThetaやInsta360で撮影した360度画像を使ったWebアプリを開発しました。

画質が大幅に向上したという`Insta360 X4`を入手したので、早速画像を使おうとしましたが、PCに画像を転送できません。
公式マニュアルで対応できなかったので備忘として残します。

https://onlinemanual.insta360.com/x4/ja-jp/camera/appuse/filetransfer

:::note warn
! 2024/7/12 追記
7/12現在の最新のファームウェア（6/13リリースのv1.1.4で対応?）により、
本体とPCをUSB接続してファイルを転送する機能がリリースされ、アプリを経由しなくてもファイル転送できるようになりました。
:::

※サポートに問い合わせましたが、解決しないため自力解決しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30994/9bdcff50-c767-89ef-806b-8fde2619091b.png)

# 今回の環境
- カメラ：Insta360 X4
- スマホ：Google Pixel 6a
- スマホアプリ: [Insta360](https://play.google.com/store/apps/details?id=com.arashivision.insta360akiko&hl=ja)
- PC: Windows 11 Pro, 23H2

# 何がどうした
Insta360 X4で撮影した画像は、Insta360アプリに転送でき、そこからPCに転送できます。
[公式マニュアル](https://onlinemanual.insta360.com/x4/ja-jp/camera/appuse/filetransfer
)によると、Insta360アプリのデータは、Android内部ストレージ（`data > com.arashivision.insta360akiko`）にあるはずですが、どうもそのようなフォルダが見つかりません。
## ※余談
というか、内部ストレージのフォルダが見れません！！
ここで、上記のサポートにスクショなどと一緒に問い合わせるのですが、1週間経っても10日経っても解決せず、とうとう2週間ほど経ってしましました。

# 何をどうした

## 必要なツールの導入
[Google USB Driver](https://developer.android.com/studio/run/win-usb)と、[Android Debug Bridge](https://developer.android.com/tools/adb?hl=ja)(`adb`)をPCにインストールします。
これらのツールは、個別にインストールできますが、[Android Studio](https://developer.android.com/studio?hl=ja)でまとめて導入できます。今回はAndroid Studioで入れました。

## 作業
- `adb`を使って、`pull`により該当フォルダから360度画像をコピーしました。
- ※アクセスエラーが起きたら、`kill-server`をして`start-server`をします。

下記のようにWindowsバッチファイルにもできます。
※私はAndroid StudioをDドライブに入れています。
```winbatch
cd /d D:
%LOCALAPPDATA%\Android\Sdk\platform-tools\adb.exe kill-server
%LOCALAPPDATA%\Android\Sdk\platform-tools\adb.exe start-server
%LOCALAPPDATA%\Android\Sdk\platform-tools\adb.exe pull /sdcard/Android/data/com.arashivision.insta360akiko/files/Insta360OneR/galleryOriginal/X4/Camera01/ .
```
Azure仮想マシンでログイン画面を表示させる方法

Azureでクライアント仮想マシンを作成し、Microsoft Entra ID参加 (以下Entra参加) の動作検証をしていたのですが、Entra参加したアカウントへの切り替えができず詰まってしまいました。
調べたところ、仮想マシンの設定変更とRDPファイルの編集で解決することができたので、備忘録として記事に起こします。

## 1.仮想マシンの設定
まずは仮想マシンにログインし、以下の場所を開きます。
コントロールパネル⇒システムとセキュリティ⇒リモートアクセスの許可⇒システムのプロパティ
システムのプロパティにて、赤枠内のチェックを外して保存します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3262345/23150c52-3251-bed2-6c18-93c932f5c6a3.png)

## 2.RDPファイルの編集
AzureからダウンロードしたRDPファイルをメモ帳などで開きます。
開くとこんな感じの情報が書き込まれていると思います。
![ダウンロード.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3262345/a4b7b48c-b2ba-3223-57fd-011a64837117.png)

1行目は接続先IPアドレスを示しているため特に触らず、2行目以降を以下のように編集して保存します。
prompt for credentials:i:0
enablecredsspsupport:i:0
authentication level:i:2
![ダウンロード (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3262345/4285be9b-c03e-15d0-44bc-cc7e4be9ca82.png)

## 3.RDP接続
設定は完了したので早速仮想マシンにアクセスしてみます。
するとログイン画面が表示されるようになりました。
この状態でEntra参加したユーザーのID/PWを入力すればログインできるようになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3262345/92913acd-ed09-2682-0d9c-89b20163454f.png)

:::note warn
IDの前には必ず「azuread\」を入れてください。
:::

***
今までは会社に置いてある実機でME-IDやIntuneの動作検証していましたが、この方法を知ることで重たいPCを持ち帰る必要もなく、自宅で検証できる幅が広がりました。
下準備もそこまで難しくないので、参考にしていただければと思います。
俺のアニメーションのオブジェクトにRigidbodyをつけたら飛んでいった件

# アニメーションのオブジェクトにRigidbodyをつけたら飛んでいった

![テキストの動画編集(500 x 500 px) (1).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191635/5fd287f8-be70-df86-752d-c05e3b0a822f.gif)

# 対処法①
## 物理挙動をアニメーション準拠にする。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191635/b5c69cf2-a15c-e261-88c0-cbbd5ffd1d9b.png)

# 対処法②
## 物理演算を無効にする。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191635/28486231-858e-6b2f-8284-27c9feea48c4.png)

ふだん使わない機能に触ると何かが起きがち。
ROS2 HumbleでT265を使う

※2024/7/4時点の方法です。

# 環境
- Ubuntu 22.04
- ROS2 Humble
- Raspberry Pi 4

## インストールするもの
最新のSDKはT265をサポートしていないため、少し前のバージョンのSDKを使う必要があります。
- librealsense（v2.53.1）realsenseのSDK
- realsense-ros（build 4.51.1）：ROS2のラッパー

## 手順
- githubからlibrealsenseのv2.53.1をダウンロードする
    - https://github.com/IntelRealSense/librealsense/releases/tag/v2.53.1
- マニュアルの手順にしたがってビルドする
    - https://github.com/IntelRealSense/librealsense/blob/master/doc/installation.md
    - `cmake ../ -DCMAKE_BUILD_TYPE=Release`
- ビルドが完了したら、`realsense-viewer`コマンドでビューワーが起動するかどうかを確認
- githubからrealsense-rosのbuild 4.51.1をダウンロードする
    - https://github.com/IntelRealSense/realsense-ros/releases/tag/4.51.1
- ros2のワークスペースを作成して、`src`ディレクトリにダウンロードしたファイルを入れる
- ワークスペースをビルドする
    - `colcon build`
    - 注意：普通にビルドするとメモリ不足でフリーズするので、`export MAKEFLAGS=-j1`を実行して、MAKEFLAGS環境変数で並列処理する数を指定したうえでビルドする
    - 参考：[colcon build中にubuntuデスクトップがフリーズするときの対処方法](https://qiita.com/porizou1/items/efe537a6d427eff4a29f)
- ワークスペースを有効化して、ros2のローンチファイルを実行する
    - `ros2 launch realsense2_camera rs_launch.py`
    - realsense関連のトピックがパブリッシュされていることを確認する
Raspberry Pi 5でサイネージ　カーソルを非表示にする（Wayland/Wayfire対応）

Raspberry Piでサイネージを作ろうとすると、専用OS([Anthias](https://anthias.screenly.io/))や、Chromiumの『キオスクモード』などの選択肢があります。
後者については公式サイトでチュートリアルが用意されていますが、色々「こういうのがほしい」が出てきたので、今回は『カーソルを非表示にする』対応をまとめます。

https://www.raspberrypi.com/tutorials/how-to-use-a-raspberry-pi-in-kiosk-mode/

# 今回の環境
- ハードウェア：[Raspberry Pi 5](https://www.switch-science.com/products/9250?_pos=3&_sid=5c9859324&_ss=r)
- OS: Raspberry Pi OS(64bit) `Debian 12 "Bookworm"`
- デスクトップ環境: `Wayfire`

# 何をどうする
ビルド済みのプラグインを取得して、ファイルを配置＆`wayfire.ini`に設定を追加しました。

## プラグイン取得（`hide-mouse`プラグイン）
プラグインをソースから自分でビルドすればよいのですが、`ninja`やら色々なツールを導入する必要があるので、[ビルド済みのもの](https://raspberrypi.stackexchange.com/questions/145382/remove-hide-mouse-cursor-when-idle-on-rasbperry-pi-os-bookworm/145390#145390)をいただきます。

なお、Raspberry PiのCPUに合わせてファイルが変わります。
※CPUアーキテクチャがわからない場合は`uname -m`で調べます。今回は`aarch64`でした。
```bash
wget https://github.com/seffs/wayfire-plugins-extra-raspbian/releases/download/v0.7.5/wayfire-plugins-extra-raspbian-aarch64.tar.xz
tar xf wayfire-plugins-extra-raspbian-aarch64.tar.xz
```

## ファイルをコピー
先の手順で`usr`ディレクトリができます。
その中から、soファイルとxmlファイルをコピーします。
※ここでも、CPUアーキテクチャに応じたコピー先を選びます。
```bash
sudo cp usr/lib/aarch64-linux-gnu/wayfire/libhide-cursor.so /usr/lib/aarch64-linux-gnu/wayfire/
sudo cp usr/share/wayfire/metadata/hide-cursor.xml /usr/share/wayfire/metadata/
```

## Wayfireの設定ファイルを編集
現状のpluginsを調べます。

```bash
grep 'plugins = ' /etc/wayfire/defaults.ini
```
`~/.config/wayfire.ini`を編集して、下記のように末尾に`hide-cursor`を含めたplugins設定を追記します。

```ini
[core]
plugins = alpha animate autostart autostart-static command cube pixdecor expo fast-switcher fisheye grid idle invert move oswitch place resize switcher vswitch window-rules wm-actions wrot zoom winshadows hide-cursor
```

# その他備忘
- [hideaway](https://gitlab.com/interception/linux/plugins/hideaway)だと動いたり動かなかったりしたのでやめました
モバイルアプリケーションでの Mobile Only のナビゲーションメニュー



+ [Salesforce モバイルアプリケーションでの Mobile Only のナビゲーションメニューのカスタマイズ](https://help.salesforce.com/s/articleView?id=sf.salesforce_app_customize_nav_menu.htm&type=5)

**Mobile Only アプリケーションについて**

Mobile Only アプリケーションは Salesforce モバイルアプリケーションのナビゲーション環境です。システム管理者は、[設定] で Mobile Only のナビゲーションメニューをカスタマイズできます。ユーザーがナビゲーションバーの [メニュー] をタップすると、ナビゲーション項目が表示されます。**最初の 4 項目は、画面下部のナビゲーションバーにも表示されます。**

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/047a1933-8432-13a3-5928-687f2a310b06.png)


この4項目の表示は、Mobile Only のナビゲーションだけでなく、どのメニューを選んでも最初の４つが下部に表示されます。

**ナビゲーション項目のカスタマイズ**

Visualforce ページ、Lightning ページ、Lightning コンポーネントを含めることができます。まず、それらの項目のタブを作成してください。タブを作成するには、[設定] から、[クイック検索] ボックスに「タブ」と入力し、[タブ] を選択します。

ナビゲーション項目をカスタマイズするには、[クイック検索] ボックスに「ナビゲーション」と入力し、[Salesforce ナビゲーション] を選択します。変更を保存したら、変更を確認するために Salesforce モバイルアプリケーションを更新します。

# 解答例

+ [「モバイル専用」アプリの「承認」タブを非表示にする](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007A4B7G)

:::note
My recommendation is to create a Mobile Enabled Lightning App for your users instead of relying on "Mobile Only"

Mobile Only was meant to be a catch-all solution for the Lightning on Mobile upgrade, which is why there are limitations and general quirkiness.

私の推奨事項は、「モバイルのみ」に依存するのではなく、ユーザ向けにモバイル対応 Lightning アプリケーションを作成することです。

Mobile Only は、Lightning on Mobile アップグレードの包括的なソリューションであることを意図しており、そのため制限や一般的な奇妙な点があります。
:::
InfluxDBv2 CLIでSQLのDELETEあるいはTRUNCATE相当の事をする場合

macOSでの小さなハマりごと。`date -u`オプションを使いましょう。

## 公式ドキュメント

`influx delete`コマンドでできる。

https://docs.influxdata.com/influxdb/v2/write-data/delete-data/

今現在のドキュメントには次のコマンドラインで例示がされている。

```sh
influx delete --bucket example-bucket \
  --start '1970-01-01T00:00:00Z' \
  --stop $(date --utc +"%Y-%m-%dT%H:%M:%SZ") \
  --predicate '_measurement="example-measurement" AND exampleTag="exampleTagValue"'
```

## macOSでの問題点

しかし上記のコマンドの3行目までをmacOSでコピペし、条件を変えてもその手前で動かない。

問題点は単純に`date`コマンドオプションが異なり`-—utc`を使っているから。

GNUとBSDの`date`コマンドの相違については次の記事を参照

https://qiita.com/ma2shita/items/d322463352fa01d776c8

それぞれの`man date`を見てみると。

### GNU date (Debian)

```text
       -u, --utc, --universal
              print or set Coordinated Universal Time (UTC)
```

### BSD date (macOS)

```text
     -u      Display or set the date in UTC (Coordinated Universal) time.  By default date displays the time in the time zone described by /etc/localtime or the TZ environment variable.
```

BSDでは`-u`のみGNUでは`-u`も`-—utc`も`-—universal`も受け付ける。

## ということで

どっちもOKな`date -u`が良い。

条件なしで全件削除の場合は

```sh
$ influx delete --bucket example-bucket \        
  --start '1970-01-01T00:00:00Z' \
  --stop $(date -u +"%Y-%m-%dT%H:%M:%SZ") 
```

InfluxDataのドキュメントのCLIインストール説明ではmacOSが最初に書かれているのに…

https://docs.influxdata.com/influxdb/cloud/reference/cli/influx/#download-and-install-the-influx-cli

 `-u`で例示してくれれば、macOSでもLinuxでも両方コピペで動くのにねぇ。
言語処理100本ノックやってみてる　その２　第3章25

前回の投稿から早2週間半、たぶん合計
60時間
100時間ぐらいかけてタグが英語になってる一部を除いてどの国も引いてこれるプログラムを書くという修行をしちゃってた。正規表現の学習にちょうど良かったかもしれない。

以下は前回定義した関数を使って呼び出したtextから第三章の25番目の問題の回答

検索かけても少なくともトップのほうには出てこないしほかの人の回答とかまだ見てないけどネストされた括弧の数を合わせて取得できる正規表現とか作れないのかだいぶ疑問。

```
re.match('{{基礎情報[\s\S]+?\|注記.*?=.*?\n}}',text[88:])
<re.Match object; span=(0, 3016), match='{{基礎情報 国\n|略名  =イギリス\n|日本語国名 = グレートブリテン及び北アイルランド連>

for key,value in re.findall('\|(.*?)=([\s\S]*?)\n',text[88:3104]):
 list[key]=value
```



第三章21から24問目も追記 以下2024/07/09

21問め
```
category_lines=[x for x,l in enumerate(text.splitlines()) if re.search('\[\[(Category|カテゴリ):.+?\]\]',l)]
```

22問め
```
category_names=[match.group(2) for x,l in enumerate(text.splitlines()) if (match:=re.search('\[\[(Category|
カテゴリ):(.+?)\]\]',l))]
```

23問め タプルで内包表記できることにいまきがついたけどそのまま
```
for x,l in enumerate(text.splitlines()):
...  if match:=re.search('(={2,}) *?(.+?) *?={2,}',l):
...   print(len(match.group(1)),match.group(2))
```

24問め
```
file_names=[tag.group(3) for l in text.splitlines() if (tag:=re.search('(\[\[|\{\{)(ファイル|file|Audio|視聴
):.*?([^|]+?\.[a-z]{3}?).*?(\]\]|\}\})',l))]
```

---以下2024年7月9日追記
```26. 強調マークアップの除去
jisyo={key:value.replace('\'','') if re.search('\'{2,}(.*?)\'{2,}',value) else value for key,value in re.findall('\|(.*?)=([\s\S]*?)\n',text[88:3104])}
```

```27. 内部リンクの除去
jisyo={key:re.sub('[\[\]\']','',value) if (m:=re.search('(\'{2,}|\[\[)(.*?)(\'{2,}|\]\])',value)) else value for key,value in re.findall('\|(.*?)=([\s\S]*?)\n',text[88:3104])}
```

28もんめMediaWikiマークアップの除去
ほかの問題もpythonぽい書き方や正規表現で極力どうにかする事にこだわらなければーみたいな話だけど時間をかけてるけど、この28問めも見た目の問題で時間かければどうにでもなりそうな気がするからパスする事に

29もんめ国旗画像のURLを取得する
ウィキのAPIで接続してなんたらーという事なんで第2章からの流れで使ってるwslのubunntsの何かと特に連携することもなく使ってたターミナルでpythonのライブラリをインストールしようとしたところでスーパーユーザーにログインできなくされてるみたいで、再インストール2回目の今の時点で以下のエラーという事にされてるっぽい状態。
どうすりゃいいんだこれ
wslの登録を解除ですぐ解決

```
CanonicalGroupLimited.Ubuntu_79rhkp1fndgsc\LocalState\ext4.vhdx' を WSL2  にアタッチできませんでした: 指定されたファイルが見つかりません。
Error code: Wsl/Service/CreateInstance/MountVhd/HCS/ERROR_FILE_NOT_FOUND
```


以下2024/07/19追記
ウィキAPIのページのサンプルをほとんどそのまま書いただけ
```29.国旗画像のURLを取得する
ses=req.Session()
URL = "https://en.wikipedia.org/w/api.php"
PARAMS={'action': 'query', 'format': 'json', 'prop': 'imageinfo', 'titles': 'File:'+jisyo['基礎情報 国']['国旗画像'], 'iiprop': 'url'}
res=ses.get(url=URL,params=PARAMS)
res.json()['query']['pages']['23473560']['imageinfo'][0]['url']
'https://upload.wikimedia.org/wikipedia/en/a/ae/Flag_of_the_United_Kingdom.svg
```

言語処理１００本ノック第三章完
[備忘録]constとfinalの使い分け[dart]

`const`と`final`どっち使えばいいかちょくちょくわからなくなるので、備忘録としてまとめます。

## 参考記事
この記事で詳しく書かれていました。

[Flutter/Dart】 finalとconst の違いって何？](https://blog.flutteruniv.com/flutter-dart-final-const/)

## 個人的な理解

- `const`と`final`どちらも変数を再代入させない
- `const`の方が制約は厳しい
- `const`で設定したobjectはimmutableになる


プログラムのパフォーマンスも`const`はimmutableになるのでパフォーマンスも良いらしい。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1782522/e3441630-fd66-4671-78a1-af10dac1517e.png)
railsの部分テンプレート描写について

# はじめに
railsで、部分テンプレートとしてパーシャルを利用しています。
しかし、使いすぎると描写に時間が掛かったりとデメリット部分もあり、使いどころに迷うケースがあります。
今回、そのパーシャルの利用方法が初見だったので、備忘録として残しました。

# やりたかったこと
スケルトンローダーの画面を作成したかった
![l_6814799_128_cc8998bdb47074590d3c2505975a7e2d.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3632357/c3ef4dcd-a68b-228b-9077-248e1013b516.png)

スケルトンローダーに関しては、こちらが分かりやすいかもしれません

https://marron-web.site/blog/cdad43/

# 作成
```css:css
.one_comment {
  display: flex;
  animation: pulse 2s cubic-bezier(.4,0,.6,1) infinite;
  margin-top: 10px;
}
@keyframes pulse {
  0%,
  100% {
    opacity: 1;
  }
  50% {
    opacity: .5;
  }
}

.comment_avatar_area {
  width: 40px;
}

.comment_avatar {
  background-color: #9CA3AF;
  width: 3rem;
  height: 3rem;
  border-radius: 9999px;
}

.comment_content_area {
  padding-top: 0.25rem;
  padding-bottom: 0.25rem;
  flex: 1 1 0%;
  padding-top: .25rem;
  padding-bottom: .25rem;
}

.comment_dummy1 {
  border-radius: 0.25rem;
  width: 75%;
  height: 1rem;
  background-color: #9CA3AF;
  margin-bottom: 10px;
}

.comment_dummy2 {
  border-radius: 0.25rem;
  height: 1rem;
  background-color: #9CA3AF;
  margin-bottom: 10px;
}

.comment_dummy3 {
  border-radius: 0.25rem;
  width: 83.333333%;
  height: 1rem;
  background-color: #9CA3AF;
  margin-bottom: 10px;
}
```
```haml:haml
- 3.times do
  .one_comment
    .comment_avatar_area
      .comment_avatar
    .comment_content_area
      .comment_dummy1
      .comment_dummy2
      .comment_dummy3
```

# リファクタリング
まず、ソースが冗長だなーと思い、パーシャル化しました
```haml:_dummy.html.haml
.one_comment
  .comment_avatar_area
    .comment_avatar
  .comment_content_area
    .comment_dummy1
    .comment_dummy2
    .comment_dummy3
```
```haml:haml
- 3.times do
  = render 'dummy'
```
そうすると、もちろんパーシャルの問題点が発生するわけです
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3632357/c9410171-bc61-8667-d14d-85033138248c.png)

そこで調べたところ、こちらのサイトのこの部分

https://qiita.com/fujisawaryohei/items/0a2524e5b23877c87b7b

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3632357/fc5e11c5-494f-fb71-a3c4-a25a747c2230.png)

配列OKなのかーと思い、さらにリファクタリング
```haml:haml
= render partial: 'dummy', collection: [*1..3]
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3632357/32f09c97-0b03-35af-c549-68baf7099547.png)
いけた！！

変更があるものでもないので、キャッシュ化すれば後々効率化ができます
```haml:haml
= render partial: 'dummy', collection: [*1..3] , cache: true
```

# おわりに
普段の使い方とは異なる使い方だったので、いけるか半信半疑でしたが動いたことに驚きでした。
もし、他にもいいアイディアがある方はご教授頂けますと幸いです。
Tailwindのレスポンシブデザインについてのメモ

# 背景
Tailwindに限らず、Bootstrapとかもそうですが、いまだにレスポンシブデザインのための`md`とか`xl`とかのprefixが理解できないため、理解するためのメモです

# 本編

https://tailwindcss.com/docs/responsive-design

Breakpoint prefix | Minimum width | 	CSS |
|:-:|:-:|:-:|
| sm | 640px | `@media (min-width: 640px) { ... }` |
| md | 768px | `@media (min-width: 768px) { ... }` |
| lg | 1024px | `@media (min-width: 1024px) { ... }` |
| xl | 1280px | `@media (min-width: 1280px) { ... }` |
| 2xl | 1536px | `@media (min-width: 1536px) { ... }` |

まずは定義です
Tailwindでは、各prefixがあらわすbreakpointは上記のようになっています

---

そして、おさらいです

```
@media (min-width: 640px) {
    background-color: red;
}
```

上記の意味は、『640px以上ならば背景色がredになる』です

---

これを踏まえて、Tailwindのprefixを考えます

```
<div class="sm:bg-red-500"></div>
```
とあったときは、
```
@media (min-width: 640px) {
    background-color: /* bg-red-500 */;
}
```
ということで、『640px以上ならば背景色が/* bg-red-500 */になる』となります

---

わたしは、`sm`、`md`、`lg`等をサイズ名と考えてしまうため、混乱しているのだと思います
正しくは、`sm`は`640px以上`、`md`は`768px以上`、`lg`は`1024px以上`と考えないとなりません
これがなかなか覚えられません

---

たとえば、以下のような場合は

```html
<span class="sm:invisible">hello world</span>
```

『（不要なので指定していませんが）デフォルトが表示だけど、640px以上で非表示になる』で、
つまり、0～639pxで表示、640px以上で非表示ですね、だよね

次に、

```html
<span class="invisible sm:visible md:invisible">hello world</span>
```

こうだと、『デフォルトは非表示状態だけど、640px以上で表示され、768px以上で非表示になる』ですから、0～639pxで非表示、640px～767pxで表示、768px以上で非表示ですね

ちょっとわかってきました

---

ここでTailwindのResponsive Designのページを読んでいたら、以下の項目を見つけました

https://tailwindcss.com/docs/responsive-design#working-mobile-first

> By default, Tailwind uses a mobile-first breakpoint system, similar to what you might be used to in other frameworks like Bootstrap.

デフォルトでは、Tailwindはモバイルファーストのbreakpointシステムを採用している、Bootstrapのような他のフレームワークでそうだったかもしれないのに似ていて――のようなことが書かれていました

『モバイルファースト』は、まったく知りませんが、スマホ等の小さいディスプレイの表示から実装していくとか考えていくとかデザインしていくとか、みたいなことだったような……

```html
<div class="text-center sm:text-left"></div>
```

ですから、上の例のように、
『デフォルトでは』つまり『モバイル端末では』『文字列は中央揃え』と決めてから、『640px以上のディスプレイでは』『文字列は左揃え』と指定していくのでしょうか

> Use unprefixed utilities to target mobile, and override them at larger breakpoints

この文の`override`をイメージしておくと、理解しやすいかも

---

メディアクエリにはrangeという概念もあるようなので、それについての書き方も書かれていました

https://tailwindcss.com/docs/responsive-design#targeting-a-breakpoint-range

```html
<!-- mdブレークポイントから、xlブレークポイントまでflex -->
<div class="md:max-xl:flex"></div>

<!-- mdブレークポイントから、lgブレークポイントまでflex -->
<!-- mdの次がlgのため、つまり、一段階の間だけflexを適用するということ -->
<div class="md:max-lg:flex"></div>
```

こちらのほうがわかりやすいような、わかりにくいような……

# 後書き

多少理解が深まりました
具体的な実装方法の手順も書かれていたので、マニュアルはちゃんと読むべきだなと思いました
オズボーンのチェックリスト　思いつめすぎて、考えに行き詰まったら、発想の転換に活用してみてください。

## はじめに
**要件定義と提案**を行う際に、オズボーンのチェックリストに従って、内容を整理したら、スムーズに考えを整理できたので、これは良いと思い。今回、内容を整理して、ご紹介させて頂こうと思います。考えに行き詰まったら、発想の転換に活用してみてください。

## オズボーンのチェックリストとは？

オズボーンのチェックリストは、**創造性を高め、新しいアイデアを生み出す**ための思考法です。**ブレインストーミングの生みの親**であるアレックス・F・オズボーンが提唱しました。

オズボーンは、生まれつき創造性の豊かな人たちが無意識に行っている思考プロセスを分析し、**誰でも創造的思考を行えるように**このチェックリストを開発しました。

オズボーンのチェックリストは、既存の製品やサービス、プロセスを新しい視点から見直し、創造的なアイデアを生み出すための強力なツールです。各質問を順に適用することで、多角的な視点からアイデアを出すことができ、革新や改善の可能性を広げることができます。

## 意外と身近にある実例

おむつを子供だけでなく大人にも使ってもらえないか？**高齢者用おむつ**
軍事用レーダーの研究中に、異なる用途への転用ができないか？**電子レンジ** 
無人野菜販売所を加工食品にも応用できないか？**無人餃子販売店、オフィスグリコ**
紅茶の色を変えてみることはできないか？**透明のミルクティー**
家具を組み立てや配送プロセスを省略して売ることができないか？**IKEA**
肉の代わりに野菜で「お肉料理」を作れないか？**豆腐ハンバーグ**
携帯電話とPCを合体させられないか？**スマートフォン**

## オズボーンのチェックリストの使い方

1. **アイデアを出し**たいテーマを決めます。
2. 9つの視点それぞれの**質問**をテーマに当てはめて、アイデアを考えます。
3. 思いついたアイデアを書き出します。
4. すべての質問に対してアイデアを考え終わったら、**最も良いアイデア**を選びます。


## 注意点

* オズボーンのチェックリストは、**既存のアイデアをベース**にするため、思いつくアイデアは既存のアイデアから大きく離れることはありません。
* 自由な発想を妨げる可能性があるため、**他のアイデア発想法と併用**すると効果的です。
* すべての質問に対してまんべんなくアイデアを考えるのではなく、**自分が良いと思う質問から優先的に**考えていくと効率的です。

### オズボーンのチェックリスト

| 項目                        | 質問例                                                                                     |
|-----------------------------|--------------------------------------------------------------------------------------------|
| **他に使い道はないか？**（Put to other uses） | この製品やサービスを他の用途に使えないか？他の市場や顧客層に提供できないか？                         |
| **応用できないか？**（Adapt）               | 他の業界や分野で成功しているアイデアを応用できないか？既存の要素を異なる状況や用途に適応させられないか？ |
| **修正できないか？**（Modify）              | 製品やサービスの形状、色、サイズ、機能を変更できないか？プロセスの一部を改善できないか？               |
| **拡大できないか？**（Magnify）             | 製品やサービスの機能や性能を強化できないか？規模を拡大できないか？                                     |
| **縮小できないか？**（Minify）              | 製品やサービスの一部を簡素化できないか？コストや時間を削減できないか？                                 |
| **代用できないか？**（Substitute）          | ある要素を別の要素に置き換えられないか？素材やプロセスを変更できないか？                               |
| **再配置できないか？**（Rearrange）         | プロセスの順序を変更できないか？要素の配置を変えられないか？                                           |
| **逆転できないか？**（Reverse）             | 製品やサービスの機能を逆転させられないか？プロセスの順序を逆にできないか？                             |
| **結合できないか？**（Combine）             | 複数の要素を組み合わせて新しいアイデアを生み出せないか？異なる機能を一つの製品に統合できないか？       |

## 活用例

**ボールペンをより便利にする**

**転用**：絵筆や楽器の代わりに使う。
**応用**：宇宙空間でも使えるようにする。
**変更**：インクの色を複数使えるようにする。
**拡大**：太い芯にして、書き心地を良くする。
**縮小**：小型化して、持ち運びやすくする。
**代用**：インクを別の液体に変える。
**再配置**：ノック式ではなく、キャップ式にする。
**逆転**：消しゴムの機能をボールペンに付ける。
**結合**：定規やライトと組み合わせて、多機能にする。

### 思いつめすぎて、考えに行き詰まったら、発想の転換に活用してみてください。
DjangoアプリケーションでAWS S3を使用して画像をアップロードする設定方法

# AWS S3への画像アップロードを行うDjangoアプリケーションの設定方法
この記事では、自分がDjangoアプリケーションでAWS S3を使用して画像をアップロードするために行った設定を記述します。具体的には、Djangoの設定ファイルにAWS認証情報を追加し、Apache経由で環境変数を設定する手順を詳しく載せておきます。

## 前提条件
AWSアカウントがあること
Djangoアプリケーションが既にセットアップされていること
Apacheがインストールされ、設定されていること

## ステップ1：AWS認証情報の設定
AWS管理コンソールにログインし、新しいアクセスキーを作成します。作成したアクセスキーとシークレットアクセスキーをメモしておきます。

## ステップ2：Apache環境変数の設定
AWS認証情報をApacheの環境変数として設定します。これにより、DjangoアプリケーションがAWS S3にアクセスするための資格情報を取得できます。

Apacheの環境変数ファイルを編集します：
```bash
sudo nano /etc/apache2/envvars
```
次の内容を追加します：
```bash
export AWS_ACCESS_KEY_ID='your_access_key_id'
export AWS_SECRET_ACCESS_KEY='your_secret_access_key'
```
※ your_access_key_id と your_secret_access_key は、作成した実際のアクセスキーとシークレットアクセスキーに置き換えてください。

Apacheを再起動します：
```bash
sudo systemctl restart apache2
```
## ステップ3：Django設定ファイルの更新
Djangoアプリケーションの settings.py ファイルを編集し、AWS S3を使用するための設定を追加します。

settings.py ファイルを編集します：
```python
import os

AWS_ACCESS_KEY_ID = os.environ.get('AWS_ACCESS_KEY_ID')
AWS_SECRET_ACCESS_KEY = os.environ.get('AWS_SECRET_ACCESS_KEY')

print(f"DEBUG: AWS_ACCESS_KEY_ID = {AWS_ACCESS_KEY_ID}")
print(f"DEBUG: AWS_SECRET_ACCESS_KEY = {AWS_SECRET_ACCESS_KEY}")

DEFAULT_FILE_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage'
AWS_STORAGE_BUCKET_NAME = 'your_AWS_STORAGE_BUCKET_NAME'
AWS_S3_REGION_NAME = 'your_AWS_S3_REGION_NAME'
```
boto3 と django-storages をインストールします：
```bash
pip install boto3 django-storages
```
## ステップ4：静的ファイルの収集
AWS S3を使用するための設定を行った後、静的ファイルを収集します。

manage.py を使用して静的ファイルを収集します：
```bash
sudo python3 manage.py collectstatic
```

## ステップ5：デプロイと確認
Apacheサーバーを再起動し、Djangoアプリケーションが正しく動作しているか確認します。

Apacheサーバーを再起動します：
```bash
sudo systemctl restart apache2
```
AWS認証情報が正しく読み込まれていることを確認するために、Apacheのエラーログを確認します：
```bash
sudo tail -f /var/log/apache2/error.log
```
## 結論
この記事では、DjangoアプリケーションでAWS S3を使用して画像をアップロードするための設定方法を説明しました。Apacheの環境変数を使用してAWS認証情報を設定し、Djangoの設定ファイルを更新することで、AWS S3へのアクセスを実現しました。

この手順を踏むことで、DjangoアプリケーションがAWS S3に画像をアップロードできるようになります。

## 注意
本番環境で動作させる時には以下の点に気をつけてください

・your_access_key_id や your_secret_access_key などのプレースホルダーを実際の値に置き換えない。

・デバッグメッセージ (print(f"DEBUG: AWS_ACCESS_KEY_ID = {AWS_ACCESS_KEY_ID}") など) を本番環境に残さない。