OmniAICreator/Qiita-1.07M huggingface dataset:
OAuth 2.0について

## はじめに
**OAuth**という仕組みを使用してソーシャルログインを実装する時があったので、**OAuthの基本的な概念**についてを備忘録として残します。

## OAuth 2.0とは何か？
**OAuth 2.0**とは、ユーザーが自分のアカウント情報を安全に他のアプリケーションと共有できるようにするための**プロトコル**です。

これは、ユーザーが自分の資格情報を直接共有することなく、サービス間で情報を安全に共有できるようにするためのものです。

ソーシャルログイン（SNSログイン）などの**外部アカウント連携機能**で利用されます。

## OAuth 2.0はどのように利用されるのか
よく、Webサイトのログイン画面で**Googleアカウントでログイン**という機能が実装されていることがあります。

こういったソーシャルログインを実装するために使用されているのが**OAuth**になります。

#### ソーシャルログインの手順

1. メールアドレスやパスワードを入力するかわりに、**Googleアカウントでログイン**をクリックする。
1. Googleアカウントの情報へのアクセスを許可する
1. ログインが成功！

## OAuth 2.0のメリット
OAuthを使用してソーシャルログインを実装することには、以下のようなメリットがあります。

1. **ユーザビリティの向上**：ユーザーは新たにユーザー名やパスワードを覚える必要がなく、既存のソーシャルメディアアカウントを使用してログインできます。これにより、ユーザー体験が向上します。

2. **登録の簡素化**：新規ユーザーは、ソーシャルメディアアカウントを使用して簡単に登録できます。これにより、登録プロセスが簡素化され、ユーザーの離脱率が低下します。

3. **セキュリティの強化**：パスワードを直接管理する必要がなくなるため、パスワードリセットやパスワード盗難のリスクが減少します。また、ソーシャルメディアプロバイダーは通常、セキュリティ対策（例えば二段階認証）を提供しています。

4. **データアクセス**：ユーザーの許可を得て、ソーシャルメディアプロファイルから追加情報を取得することができます。これにより、パーソナライズされたユーザー体験を提供することが可能になります。

## OAuthの構成とフロー
OAuthは以下のように構成されています。

1.**リソースオーナー（ユーザー）**：サービスを利用するエンドユーザーです。
2.**クライアント**：ユーザーが使用するアプリケーションです。
3.**リソースサーバー**：ユーザーのデータを保持しているサーバーです。
4.**認可サーバー**：認可コードやアクセストークンを発行するサーバーです。

上記の4つを踏まえてGoogleアカウントを使用したログインまでのフローを示します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2851087/3df33456-35c9-8c1b-0d90-13bba63c67ca.png)

#### フロー詳細
1. ユーザはサイトのログイン画面へアクセスする。
1. ログイン画面の**Googleアカウントでログイン**をクリックするとGoogleの認可サーバーは認可画面を返却する。
1. ユーザーが許可すると認可サーバーは認可コードを発行する。
1. クライアントは、受け取った認可コードを認可サーバーに送信して、アクセストークンを受け取る。
1. 受け取ったアクセストークンをリソースサーバーに送信して、ユーザーの情報を取得する。
1. 受け取ったユーザー情報で認証を行ってログインが成功する。
無料ドメインをEC2インスタンスに与える方法－まとめ

## 概要
1. ドメインを無料で取得しようと考えた。
1. freenom.comが訴えられていた。
1. dot.tkも同じシステムなため、利用不可
1. No-ip.comはnameserversの利用が課金対象
1. 最終的にお名前ドットコムを利用
1. Route53の設定を行う
1. インスタンスと連携
1. Elastic IPの登録

## 環境
* EC2(AamazonLinux2023)

## frenom.com dot.tk

https://gigazine.net/news/20230309-freenom-sued-by-meta/

どうやら訴えられたようで、利用不可です、、

## No-ip.com
https://www.noip.com/support/knowledgebase/how-do-i-change-my-dns-servers-if-my-domain-is-registered-with-register-com

今回は無料で利用したいため利用するのをやめました。
また、EC2との連携法が全く出てこなかったため、素人の自分では無理と判断しました。

## 実際の設定（Route53の設定～インスタンスとの連携）
https://qiita.com/ponponpoko/items/a60dab676addeb040e9e

上のものがとても丁寧なので、こちらを参考にしてください。

## Elastic IP
動的にIPが決まってしまうので、せっかくドメインと関連付けても、IPが変わってしまうためにアクセスができなくなってしまう。

`対策以下の設定`を行うことで、IPを固定できる。

https://qiita.com/mat827/items/f13876340435674aa340
Python pandasのクエリについて基本的なこと


pandas.DataFrame.query(‘条件式’, inplace=False)

デフォルトのパラメータ（ inplace=False ）は、データのコピーを返す。
元のデータフレームのデータを更新する場合は、inplace=Trueとする。

条件式は、シングルコーテーション「’」又は、ダブルコーテーション「”」で囲む。

列名は、列名をそのまま使用する。（シングルコーテーション等で囲まない）

文字列は、 シングルコーテーション「’」又は、ダブルコーテーション「”」で囲む。
ただし、条件式と別の記号を使用する。
（例：‘ 列名 == “文字列“ ‘）

条件式で変数を使用するときは、変数名の前に「@」を付ける必要がある。


ここからは、各条件式について簡単にまとめる。

一致条件　==

不一致条件　!=

比較演算子　>= など

and条件　& 

or条件　|

特定列の要素で先頭が特定文字(前方一致)
対象の列名.str.startswith("特定の文字")

特定列の要素で末尾が特定文字(後方一致)
対象の列名.str.endswith("特定の文字")

特定列の要素で特定文字を含む(部分一致)
対象の列名.str.contains("特定の文字")

日付の列の要素で特定の月
対象の列.dt.month == 特定の月

日付の列の要素で特定の日にち
対象の列.dt.month == 特定の日にち
windows10パッケージ管理ツール『chocolatey』


## 初めに

新規PCを購入する度に、作業PCが変わる度に最低限必要なソフトをダウンロードし、インストールしなおしていませんか？
前回使っていたソフトは何だっけ大会を繰り広げていませんか？

そんなあなたに、**『chocolatey』** です。
『chocolatey』はコマンドラインからさまざまなソフトをインストールすることができ、chocolateyによりインストールされたソフトの一覧を取得することができます。

## 開発環境
Windows10

## 導入方法
Chocolateyを導入するにあたって、[Installing Chocolatey](https://chocolatey.org/install#individual)を参考にしましょう。
「Individual」を選択し、表示されたコマンドを管理者モードのPowerShellで実行します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2527164/5d55a520-8e42-6335-9e36-e98508453fed.png)


## 使用方法
Chocolateyが利用できるようになったら、以下のコマンドが利用できます。

```cmd
choco install ソフト名
```

例えば、firefoxをインストールする場合は、以下のように指定します。
```cmd
choco install firefox
```

アップデートもできます。
```cmd
choco upgrade firefox
```

## よく使うコマンドまとめ

- アプリのインストール
    ```cmd
    choco install firefox
    ```

- アプリのアンインストール
    ```cmd
    choco uninstall firefox
    ```

- chocolateyでインストールした全てのアプリをアップデート
    ```cmd
    choco upgrade all
    ```

- インストールしたパッケージの一覧表示
    ```cmd
    choco list --local-only
    ```
    or
    ```
    clist -l
    ```

## 最後に

chocolateyのコマンドメモのため書きました。
chocolateyは便利ですが、ソフトが微妙に最新化されていなかったりします。ご注意を


**記事の内容に間違いがありましたら連絡ください！**

## 参考サイト・書籍
- [chocolatey公式](https://chocolatey.org/)
- [パッケージ検索](https://community.chocolatey.org/packages?q=)
【AWS】セキュリティ観点について個人的な見解(※随時更新)

自分はセキュリティエンジニアではないので最低限の話になってきますが、
普段の業務をしていてもやっぱりセキュリティとかヒューマンエラーの防止策って
本当に大事だなーと思います。
開発するにしてもアクセス権限は最低限にしておこうとか普段から意識してますが
プロジェクト内でセキュリティ意識が認識合わせできていないので個人の裁量に
任せたままになっていることが多い気がします。

## クラウドセキュリティに必要なセキュリティ観点
### 防御
まず第一に攻撃の初期段階における外部との接続点を介した攻撃を防ぐ必要があります。
インターネットを経由した不正アクセスや不正ログイン、
侵入できたとしても暗号化によってリソースの不正利用の防止をするよう設定します。
主に次のようなサービス等を利用して防ぎます。
| 対応策 | AWSにおける該当機能 | 内容説明 |
|:-----------:|:------------:|:------------:|
| ルートユーザーの不使用 | IAM | 強力な権限をもつルートユーザーで作業せず、ユーザーアカウントを別途作成する。作業時はスイッチロールしてプロジェクト内の全てのユーザーが統一された権限で作業するのがベスト。 |
| MFAの使用 | IAM | MFAデバイスを登録し、ログイン時にコードを入力する。ログイン情報が漏れた時の保険。 |
| アクセスキー、シークレットキーの削除 | IAM | プログラムにアクセスキーとシークレットキーを保管しない。プログラムから取得する場合はSecret Managerに保管して取得するなどの対応を取る。 |
| 操作の制限 | IAM | ポリシーによるユーザーやリソースの操作制御を最低限に設定する。 |
| 通信相手の制限 | EC2、API Gateway | EC2はアクセスを許可したIPアドレス、ポート番号の制限をSecurity Groupで設定する。サブネット単位での制御はネットワークACLで制御する。API GatewayはAPIキー、リソースポリシー、相互TSL認証、Lambdaオーソライザー、Cognito認証、IAM認証等でAPIの利用者を制御する。 |
| 通信の暗号化 | AWS Certificate Manager | 通信の暗号化(HTTPS)を行う。 |
| 通信相手の認証 | Cognito | ユーザープールによるSSO機能の実装を行う。 |
| ゾーニング | VPC | サブネットの分割によるネットワークから接続できる範囲の制限 |
| データの暗号化 | S3、DynamoDB、Systems Manager、Secrets Manager等| 外部からデータが読めないように暗号化する。Secrets managerはDBのパスワードを自動でローテンションも可能。 |

### 検知
次に攻撃が実施されてしまった後にすばやく管理者が検知できる仕組みを作ります。
検知ができることでその後の対応を素早く行うことができます。
BIツールと連携してグラフ化を行ったり特定の操作が行われたときにメールやSlackに
通知する仕組みを作成することもできます。
| 対応策 | AWSにおける該当機能 | 内容説明 |
|:-----------:|:------------:|:------------:|
| 異常検知 | Amazon CloudWatch | 他のAWSサービスと連携してログを出力させる。アラートの設定も可能。 |
| 死活監視 | Amazon CloudWatch | メトリクスでEC2のCPU使用率などの監視を行う。 |
| 内部不正検知 | AWS CloudTrail | AWSサービスへの操作履歴をログに残す。 |
[iOS] Firebase Authenticationで匿名認証してからAppleIDと紐付ける方法

iOSアプリでは初回登録時にログインを必須にするとリジェクトされてしまい、初回ユーザーはログインなしで使ってもらうようにする必要がでることがあります。

これについてはFirebaseの[匿名認証](https://firebase.google.com/docs/auth/ios/anonymous-auth?hl=ja)を使うことで対応できます。

ただこれだけだと機種変時にデータが受け継がれないので、あとでなんらかのアカウントと紐づけできるようにしておく必要があります。ここではAppleIDでの連携について説明します。

## 環境
- Xcode14
- Firebase 10.14.0

## 匿名認証

[公式ドキュメント：Apple プラットフォームで Firebase 匿名認証を行う](https://firebase.google.com/docs/auth/ios/anonymous-auth?hl=ja)

### Firebaseコンソール側
- Firebase コンソールの [Authentication] セクションで、[Sign-in method] のタブを開きます。
-  [匿名] を有効にして、[保存] をクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6149/2a15e6e5-717e-f03f-d74d-e0e66493047a.png)

### コード側
すでにユーザー作成済みかどうかチェックして、未作成の場合に匿名でユーザーログインします。

```swift
import FirebaseAuth

func createUser() async throws {
    let user = Auth.auth().currentUser
    if user == nil {
        let result = try await Auth.auth().signInAnonymously()
        print(result.user.uid)
    } else {
        throw SomethingError()
    }
}
```

## AppleIDログインとの紐づけ

[公式ドキュメント：「Apple でサインイン」して Firebase で認証する](https://firebase.google.com/docs/auth/ios/apple?hl=ja)

[公式ドキュメント：匿名アカウントを永久アカウントに変換する](https://firebase.google.com/docs/auth/ios/anonymous-auth?hl=ja#convert-an-anonymous-account-to-a-permanent-account)

```swift
// SignIn with Appleボタンを押してログイン
SignInWithAppleButton(.signIn) { request in
    request.requestedScopes = []
    let nonce = randomNonceString()
    request.nonce = sha256(nonce)
} onCompletion: { result in
    switch result {
    case .success(let authResults):
        // credentialを取得
        let appleIDCredential = authResults.credential as? ASAuthorizationAppleIDCredential

        guard let appleIDToken = appleIDCredential?.identityToken else {
            fatalError()
        }
        // utf8でエンコーディングする
        guard let idTokenString = String(data: appleIDToken, encoding: .utf8) else {
            print("Unable to serialize token string from data: \(appleIDToken.debugDescription)")
            fatalError()
        }

        // 今のログインユーザーとAppleIDログインを紐付ける
        Task {
            let credential = OAuthProvider.appleCredential(withIDToken: idTokenString,rawNonce: nonce)
            do {
                try await Auth.auth().currentUser?.link(with: credential)
                print("success")
            } catch {
                print("error")
            }
        }
    case .failure(let error):
        print("Authentication failed: \(error.localizedDescription)")
    }
}
```
lima + dockerでコンテナが起動しない fork/exec /proc/xxx/exe: permission denied: unknown

---
## はじめに
船井総研デジタルのoswです。業務で使っているIntel macでdockerコンテナを起動しようとしたらエラーが発生したため、その備忘録です。

## 発生したエラー
```
$ docker compose up
Error response from daemon: failed to create task for container: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: error during container init: error running hook #0: fork/exec /proc/xxx/exe: permission denied: unknown
```

## 解決策
```
# Lima仮想マシン内で下記を実行
systemctl --user --now disable docker
systemctl --user --now disable containerd
systemctl --user --now enable docker
# 念のためLima仮想マシンを再起動
```
参考URL: https://github.com/lima-vm/lima/issues/1641

## 発生した契機
dockerコンテナはしばらく起動しておらず、起動する以前に行った動作として下記が挙げられます。
- OSのセキュリティパッチ更新
- command line tools更新

それぞれを実施したタイミングでコンテナ起動を試していないため、厳密にどちらが影響しているかはわかりませんが恐らくOS側の更新かなと思います。

## おわりに
ググるとDocker Desktopを使ったケースや似たようなエラーは出るものの、ピンポイントで同じ現象がなかなかヒットせず、解決に少々時間がかかってしまいました。
Twelve Factor Appとは

どこかの記事でTwelve Factor Appを見かけて気になったのでまとめました。

# Twelve Factor App
[Twelve factor app](https://12factor.net/ja/)はつぎのようなSaaSを作り上げるためのHerokuの中の人が提唱した、モダンなWebアプリケーションとしてあるべき姿を12のベストプラクティスにまとめた方法論です。
  
- セットアップ自動化のために 宣言的な フォーマットを使い、プロジェクトに新しく加わった開発者が要する時間とコストを最小化する。
- 下層のOSへの 依存関係を明確化 し、実行環境間での 移植性を最大化 する。
- モダンな クラウドプラットフォーム 上への デプロイ に適しており、サーバー管理やシステム管理を不要なものにする。
- 開発環境と本番環境の 差異を最小限 にし、アジリティを最大化する 継続的デプロイ を可能にする。
- ツール、アーキテクチャ、開発プラクティスを大幅に変更することなく スケールアップ できる。

## コードベース
ソースコードとアプリケーションは常に1対1の関係。もし複数のコードベースがある場合、それは分散システムであり、それぞれのコンポーネントがアプリケーションであり、個別にTwelve Factorに適合することができる。同じコードを共有する複数のアプリケーションはTwelve Factorに違反していて、その場合は共通コードをライブラリに分解し、依存関係監理ツールで組み込む。

デプロイは複数存在し、本番サイトとステージングサイト、さらにすべての開発者はローカル環境で動作するアプリケーションのコピーを持っておりこれらもデプロイとみなせる。

## 依存関係
暗黙的な依存関係は存在せず、ライブラリやシステムツールなどは明示的にしてアプリケーションだけで完結するようにする。なぜならシステムツール(curlなど)は常にデプロイさせる環境で使用できるとは限らないからである。またアプリケーションで完結できれば新たな開発者のセットアップにかかるコスト削減につながる。

## 設定
コードや設定ファイルに設定を含めるのではなく環境変数として設定するようにする。環境変数ならコードを変更することなくデプロイごとに簡単に変更でき、設定ファイルとは異なり誤ってリポジトリにチェックインされる可能性は低い。コードに含めた場合は環境ごとにビルドが必要になり、設定ファイルの場合は環境ごとにファイルが必要となりスケールしにくくなるため環境変数を使用する。

## バックエンドサービス
DBや外部サービスはアタッチ/デタッチ可能なリソースとして捉えコードを修正しなくても変更できるようにする。コードは、ローカルサービスとサードパーティサービスを区別しない。 アプリケーションにとっては、どちらもアタッチされたリソースであり、設定に格納されたURLやその他のロケーター、認証情報でアクセスする。また仮にDBが落ちた場合環境変数を書き変えるだけで別のDBに接続できる。

## ビルド、リリース、実行
ビルド、リリース、実行の3つのステージを厳密に分離する。実行ステージはできるだけ可変部分を持たないようにするべきである。なぜならアプリケーションに問題が起きると開発者が待機していない真夜中などにアプリケーションが壊れる可能性があるためである。テスト済みのコードをビルドし、その結果を各環境にリリースして実行するようにする。

## プロセス
プロセスはステートレスかつシェアドーナッシング(システムを構成するコンピュータ間で何も共有しない方式のこと。)で永続化する必要のあるすべてのデータは、ステートフルなバックエンドサービスに格納しなければならない。インスタンスは増減するものであり永続的に存在しないからである。永続的に持ちたいデータはDBなどを利用する。

## ポートバインディング
アプリケーション内にサーバを組み込み、サーバ単位ではなくポート単位でサービスを公開できるようにする。これにより自分自身もほかのサービスのバックエンドサービスとして機能を提供することが容易になる。

## 並行性
スケールアップではなくスケールアウトさせるようにする。スケールアップの場合はマシンの再起動が必要となりダウンタイムが発生するため

## 廃棄容易性
即座に起動・終了することができる。この性質が素早く柔軟なスケールとコードや設定に対する変更の素早いデプロイを容易にし本番デプロイの堅牢性を高める。

## 開発/本番一致
各環境のギャップを少なくし、できるだけ一致させた状態を保つ

## ログ
標準出力に出力させツールで一か所に集約する。スケールイン時に仮想サーバごと消える可能性があることや環境が異なっても常に行えるのでこのようにする。

## 管理プロセス
管理プロセスはアプリケーションの初期化処理として実行させるようにする。手動で管理を実行するとオペミスが発生する可能性がある。
seabornでboxplotのboxなし（線だけ）とswarmplotを重ねる

設定を忘れるので、メモ。
このようなグラフが描けます。boxplotのboxなし・whiskerなしとswarmplotを重ねます。
![dummy.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/820036/98f869cd-118b-f0c0-d421-48476c470384.png)


# ダミーデータの生成
自分のデータを持っている人はスキップしてください。
```Python:Python
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

# 2種類のダミーデータを生成
np.random.seed(seed=0)
a = np.random.normal(10, 5, 10) #平均、標準偏差、個数
b = np.random.normal(20, 10, 10)

# seabornでboxplotを描きやすいようにくっつける
df_a = pd.DataFrame([a, ["a"]*len(a)]).T
df_a.columns = ["data", "category"]
df_b = pd.DataFrame([b, ["b"]*len(a)]).T
df_b.columns = ["data", "category"]

df_melt = pd.concat([df_a, df_b], axis=0).reset_index(drop=True)
```
このようなデータです。
![スクリーンショット 2023-09-25 22.36.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/820036/940b5581-cfbb-2601-a4e1-cd22fc32061f.png)


# boxplotのboxなしとswarmplotを重ねる
```Python:Python
sns.set_style('darkgrid')

fig, ax =plt.subplots(figsize = [4, 6])

sns.boxplot(x="category", y="data", data=df_melt, showfliers=False, showbox=False, whiskerprops=dict(linewidth=0), linewidth=2, ax=ax)
sns.swarmplot(x="category", y="data", data=df_melt, ax=ax, color="black", size=10, alpha=0.5)

plt.setp(ax.lines, color="gray") #横線の色
ax.set_xlabel("", size = 24)
ax.set_ylabel("Dummy data [a.u.]", size = 24)
ax.set_xticks([0, 1], ["a", "b"], size = 18) #字を大きくするためにset
ax.set_yticks([0, 10, 20, 30, 40], [0, 10, 20, 30, 40], size = 18) #字を大きくするためにset

plt.savefig("dummy.png", dpi=100, bbox_inches="tight")
```
実際に使う時はdpiは200にしていますが、Qiitaにアップしようとしたら大きすぎたので100に設定。

# 参考
- [matplotlib/seaborn を利用したボックスプロットの作成方法](https://stats.biopapyrus.jp/python/boxplot.html)
- [seaborn.boxplot](https://seaborn.pydata.org/generated/seaborn.boxplot.html)
- [matplotlib.pyplot.boxplot](https://matplotlib.org/3.1.1/api/_as_gen/matplotlib.pyplot.boxplot.html)
OCRとは

# はじめに
毎週1本様々な技術に関する記事を投稿しています。
もし興味のある方は下のリンクから他の記事も見ていただければ幸いです。
 [@7_inai_](https://qiita.com/7_inai_)

# OCRとは
`OCR（Optical Character Recognition：光学文字認識）とは、印刷物や手書きのテキストなど、紙に書かれた文字をデジタルテキストに変換する技術`です。

# OCRの仕組み
OCRの仕組みは以下のステップに基づいています。

1. スキャンまたは画像取得
OCRプロセスの最初のステップは、印刷物や文書をスキャンしたり、デジタルカメラで撮影したりして、__テキストをデジタル画像データに取り込む__ ことです。この画像は、OCRソフトウェアが処理するための基本的な情報源となります。
2. 前処理（Preprocessing）
取り込まれた画像データは、ノイズ、歪み、光の不均一性などの問題がある場合があります。前処理ステップでは、これらの問題を解決し、OCRの精度を向上させるために画像を補正します。具体的な前処理のタスクには、__画像の二値化（白黒化）、ノイズの除去、歪み補正__ などが含まれます。
3. 文字検出（Character Detection）
OCRソフトウェアは画像内の __文字領域を特定するために、文字の輪郭や特徴を検出__ します。これにより、文字がどこに存在するかを把握し、テキスト抽出の対象を絞り込みます。
4. 文字認識（Character Recognition）
文字検出が行われた後、OCRソフトウェアは、__各文字の形状や特徴を認識し文字を識別__ します。これは文字の形状、サイズ、角度、書体などの特性に基づいて行われます。文字認識アルゴリズムは、機械学習やニューラルネットワークを使用して学習し、テキストの精度を向上させることがあります。
5. 文脈解析（Post-processing）
文字認識が行われた後、OCRソフトウェアは認識された文字を単語や文のまとまりにまとめ、__文脈を解析して文書全体を正確に再構築__ します。これには単語の綴りの修正や文法的な解析などが含まれます。
6. テキストの出力
最終的に、__OCRシステムはデジタルテキストデータを生成し、ユーザーが編集や保存できる形式に提供__ します。これにより、紙の文書を電子フォーマットに変換し、検索、編集、共有などの目的に使用できるようになります。

# 終わりに
OCR技術は、文書のデジタル化、情報の抽出、データの自動化などのさまざまな用途に利用されており、ビジネス、アーカイブ、図書館、医療、法律などの分野で広く採用されています。OCRシステムは、高度な機械学習アルゴリズムやニューラルネットワークによって逐次改善され、文字認識の精度が向上しています。これからもより精度が向上していくでしょう。


最後までお付き合いくださりありがとうございました。
JPEGとPNGの違いについて

画面遷移する際やWebページを読み込む際に遅いといった事があるかと思いますが、実はそれぞれの特徴に関係してるのです！
JPEGとPNGのそれぞれの特徴についてまとめましたので、よかったら参考にしていってください🙇‍♂️


## JPEG

通常JPEGは非可逆圧縮となっており、一部データが欠けるなどして、画像がぼやける事があります。その代わりに、データの圧縮率も高く、大きな画像を小さな画像に圧縮できるのが特徴となっています。

## PNG

可逆圧縮となっていて、圧縮前と同じ状態にする事ができます。データが欠けるなどはなく、画質が落ちることもないのが特徴ではあるものの、ファイルサイズが大きいといったデメリットがあります。ファイルサイズが大きいとデータの転送量が増えて、サーバー側への負担も大きくなってしまい、Webページの読み込みが遅くなったりします。

### 圧縮率が高いと何がいいのか!!!!

圧縮率が高いほど、画像ファイルのサイズが小さくなり、**ファイルを効率的に保存または転送することができます。**
具体的には、以下３つの特徴があります。

1.　ディスクスペースの節約
2.　高速なデータ転送
3.　ストレージの効率化

### 1.ディスクスペースの節約
圧縮率が高いと、同じ品質の画像でもファイルサイズが小さくなり、ディスクスペースを節約する事ができます。

### 2.高速なデータ転送
圧縮されたファイルは小さいため、ネットワーク上でのデータ転送が高速になります！特に、インターネット上で大量の画像を送受信する場合に有利です。

### 3.ストレージの効率化
圧縮された画像を使用することで、ウェブサイトやアプリのストレージ容量を節約する事ができる。これにより、ユーザーのデバイスに対する負荷が軽減される可能性があります。

# 可逆圧縮って何！！！
文章ファイルなどは、圧縮したものを完全に元に戻す必要があり、このような圧縮方法は可逆圧縮といい、ランレングス法やハフマン法などが使用されている。
PNGの画質が落ちないのは、このため。
ちなみに、ランレングス法などはFAXなどに用いられたりします！（気になる方は調べてみてください）

# 非可逆圧縮って何！！！
画像，音声，動画などのファイルは、画質などを完全に元に戻す必要がない場合もあります。このような圧縮方法を非可逆圧縮といい、可逆圧縮に比べて圧縮率をあげることができることが多いのが特徴です。

例）動画、音楽データ

# おまけ
## JEPG XL

PNGと同様にロスレスエンコーダーの特徴を持ち、PNG以上の圧縮率であり、プログレッシブデコーディングを採用してることから、ダウンロードが完全に終わっていなくても、逐次画像を解析することで、表示する事ができる特徴を持っているのがJPEG XLです。通常JPEGは、非可逆圧縮となっており、画像がぼやけてしまうが、JPEG　XLはロスレスエンコーダーの特性を持ち合わせいることから、可逆圧縮である事が言える。

### JPEGXLの特徴

- ロスレスエンコーダー
- プログレッシブコーディング
- 可逆圧縮

つまり、圧縮率と画質はトレードオフの関係であるが、JPEG XLはこのトレードオフの関係を限りなく無くした新しい圧縮技術と言えます。

# まとめ
日常でかなり目にするJPEGとPNGですが、それぞれの特徴を押さえておくと、Webページを作成するときなどになぜ読み込みが遅いのかの原因を突き止めたりする事ができるので、可逆圧縮と非可逆圧縮は覚えておいて損はないと思います！！！
[GAS] でセルの値をまとめてクリアする方法



getRangeセルの範囲を指定してclearContent()を使用する
Sheetオブジェクト.getRange(行番号, 列番号, 行数, 列数)

getRange(1,4,lastRow -1 ,14).clearContent();
C4からMの最終行までセルの値をクリアする
マルウェア、さまざまな攻撃

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457284/6a31417a-3046-a5b9-fb3e-db14c678b091.png)
１：マルウェア
①コンピュータウイルス
　コンピュータウイルスは、１つ以上の機能を持った悪意のあるプログラムです。近年のコンピュータウイルスは、愉快犯的なものが少なくなり、金銭の搾取、情報の窃取など、経済的、社会的な被害をもたらすものが多くなりました。厳重な注意が必要です。

「コンピュータウイルスが持つ機能」
①自己伝染機能：他のコンピュータに伝染する。
②潜伏機能：一定条件が成立するまで、機能せずに身を隠す。
③発病機能：不正な処理を実行し、被害を与える。

②トロイの木馬
　コンピュータウイルスの一形態です。プログラム中にウイルスを密かに忍び込ませて、プログラム本来の動作の裏で不正行為を行います。

③スパイウェア
　ウェブの閲覧履歴、保存ファイル一覧、メールの送受信履歴など、ユーザの利用履歴を収集し、定期的に外部のサーバに情報を送るソフトウェアです。キーボードのどのキーを押したのかを記録するキーロガーというソフトウェアもあります。キーロガーが仕組まれていると、キーボードから入力した情報はすべて盗まれてしまいます。当然、ログイン時にキーボードで入力したユーザIDやパスワードも盗まれます。

④ボット
　インターネットを介して、司令サーバ（C＆Cサーバ）からの指示を受け取り、指示に従って不正動作を行うソフトウェアです。主に、迷惑メールの配信やDoS攻撃に利用されます。ボットに感染したパソコンをゾンビPCと呼びます。また、ある司令サーバの支配下に入っている一連のゾンビPCの集団をボットネットと呼びます。

⑤ランサムウェア
　データを人質にして身代金（ransom）を要求するマルウェアをランサムウェアと言います。コンピュータ内のファイルを勝手に暗号化して読めないようにしたり、コンピュータロックしてログインできない状態にするなどの不具合を発生させ、復元のためのお金（身代金）を利用者に要求します。近年、これまでの脅迫に加え、情報を盗み取った上で「公開されたくなかったら、お金を支払え」という脅迫まで行う、二重脅迫型ランサムウェアもあります。

　ランサムウェアの被害に遭わないようにするためには、怪しいファイルを開かないことを当然のことながら、定期的にバックアップを取得し、バックアップを隔離して（PCに接続せずに）保管しておくことが大切です。

⑥ルートキット
　不正侵入したコンピュータ内において、さまざまな隠蔽工作を行うソフトウェア群のことです。不正なプロセスを隠蔽する（システム管理ツールの動作中、プロセス一覧に表示されないようにする）機能、ログを改竄する機能、バックドア（正規の認証手続きを迂回して侵入できる入り口）を設置する機能などを持ちます。不正侵入した攻撃者は、ルートキットをインストールし、システム管理者に気づかれないように長期にわたってシステムをのっとります。

※試験出題例：「C＆Cサーバが果たす役割」は「遠隔操作が可能なマルウェアに、情報収集および攻撃活動を指示する」ことである。
000_土はいいぞ【土壌物理学入門編】

# 土壌物理学入門編
### 要約：土壌物理学は土壌中の物質・エネルギーの流れを研究する学問
## 0. はじめに
### 背景：農業農村工学の中で、土壌物理学の人気が低い（気がする）
＜この記事の筆者＞農業農村工学会大会講演会にこれまで5回参加した人
＜この記事の対象＞農業農村工学を学ぶ人、興味関心がある人

ちょっとね、NN学会の中でも土壌物理学のセッションは怖いよね…
（高校で生物選択だと式変形に慣れない、先生が怖い、etc.）
でも「基本と応用がつながっているんだ」と分かると楽しい学問だと思います。
ミクロ（微視的）とマクロ（巨視的）、両方の視点で土を見てみると面白いですよ。

### 目的：土壌物理学の敷居を下げたい！
「土壌物理学は面白いし役に立つ学問だ」とお伝えしたい！
農業や環境に興味があるなら、土壌について理解しよう！！
##### 土はいいぞ！！！
なんで「土が好きなんて変わってるね」って言われるんや
宝石が好き→女の子らしい
鉱物、土壌が好き→女の子らしくない
同じ岩石由来やないですか！！解せぬ…

## 1. 土壌とは何か？
岩石が風化して、有機物（植物遺体など）が混ざったもの。

## 2. 土壌物理学の意義
土壌物理学を学ぶと何がいいか？
### 2-1. 土壌の物理性を理解できる
#### 土壌の物理性：構造、保水性、透水性、物質動態、熱エネルギー
### 2-2. 農業
#### 土＝ブラックボックス、ではなくなる
土壌診断（土壌の物理性、化学性、栄養状態を把握する）→農業に役立つ
#### 土づくり、水管理、施肥の判断材料になる
例：土壌中の窒素が足りないから肥料を増やそう
### 2-3. 環境
#### 富栄養化、温室効果ガスの放出、土壌侵食、生態系の破壊、砂漠化など
#### 様々な環境問題に寄与できる
SDGs（持続可能な開発目標）の達成には、土壌物理学の知識が不可欠

## 3. 土壌と人間生活の関わり
### 土壌の役割
- 植物生育の場
- 環境保全
- 建造物の材料、基盤
#### 土壌なくしては、人間生活はありえない
食べ物を作るにも、水を作るにも、土壌が必要

## 4. 関連するトピック
- 土壌学
- 土壌化学
- 土壌微生物学
- 土壌肥料学
- 土壌分類学
- 土壌鉱物学
- 地質学
- 陸上生態学
- 水文学（農業水文学、森林水文学、都市水文学）
- 微気象学
- 堆積学
- 植物学
- 農学
- 土質力学

## 5. おわりに
最後までお読みいただきありがとうございました。
1人でも多くの人に興味を持っていただけるよう、
これからも記事を書いていきます。**土はいいぞ！！**

よければまた見てください。

[次回の記事はこちら](https://qiita.com/nagayuka01/items/bbcd34be1108200ad810 "001_土壌物理学基礎編")
Azureでアクセスポリシーを作成できない時

## 前提
普段はWeb系やAI・IoTの開発をしており、先月よりAzureを使ったインフラ構築のキャッチアップ中。

## エラー内容
#### 1. Key Vaultでアクセスポリシーを作成できない
Key VaultでAzure Functionsリソースを利用できる様にするためにアクセスポリシーを作成しようとしたものの、プリンシパルの選択候補が一つも表示されない。
![スクリーンショット 2023-08-28 15.31.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1812049/f8afd071-6baf-3130-8886-cb0d23999d12.png)
![スクリーンショット 2023-08-28 15.32.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1812049/b2ecba6d-fb29-7be3-6e11-2faa530bfa78.png)

#### 2. SQL ServerでActive Directoryのユーザー設定ができない
SQL Serverの認証方法をAzure Active DirectoryにしたためAD管理者の設定をしたかったのですが、こちらでもユーザーが選択対象にない。。。
![スクリーンショット 2023-08-28 15.33.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1812049/a2c9a011-7223-a70a-83d1-ce5d9d626754.png)


## 原因調査
#### 1. Azureの権限に問題ある？
**「ユーザーアクセス管理者」** は付与されてた
また自分と全く同じ権限を持つ別のエンジニアは上記の作業を問題なくできたため、ここではない模様
![スクリーンショット 2023-09-21 18.12.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1812049/674d31b7-4fc3-5135-ef26-a55562837a08.png)


#### 2. Azureの権限を付与してもらってから反映されてない？
一度ログアウトして再ログインしたり、シークレットウィンドウで立ち上げても変化なし。。

#### 3. AzureADの権限に問題？
Azure Active Diretoryにアクセスして確認してみたところ、ユーザー一覧を見れなかったり表示できる部分が極端に少なかったので、ここの権限が足らないことが判明。

結論としては **「ディレクトリ閲覧者」** という権限が付与されておらず、上記のようにアクセスポリシーやAD管理を設定できなかった様です。
↓
![スクリーンショット 2023-09-25 21.47.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1812049/61883628-9d13-d7f7-baae-1f68754fbd4e.png)


## AzureADとは
https://azure.microsoft.com/ja-jp/products/active-directory

クラウドベースのIDやアクセス管理ができるサービスのこと。
テナントベースの権限で、プランによって影響範囲やコストが変わってきます。

このAzure ADを使うことで一つのIDでたくさんのサービスやアプリにアクセスすることが可能になります。（シングルサインオンなど）
また、そのIDをまとめて管理することで、退職した時やメンバーから外れた際の作業も楽になります。

#### ✅　ChatGPTに聞いてみたところ非常にイメージつきやすかったので抜粋
>Azure AD（Azure Active Directory）とは、インターネット上で使えるID管理のシステムです。
例えると、学校で使われる出席番号や生徒手帳のようなものです。
みんなが同じ学校の中で勉強や活動をするために、自分を特定できる情報が必要ですよね。

>それがAzure ADで管理されているIDやパスワードになります。
Azure ADを使うことで、たくさんのアプリやサービスに対して、一度に安全にログインできます。
これは、学校で一つの出席番号で授業や部活動に参加できるような感じです。
それぞれのアプリやサービスに、別々のIDやパスワードを覚えておく必要がないので、便利ですね。

>さらに、先生や校長先生が生徒たちの出席番号や生徒手帳を管理するように、Azure ADでは、会社や組織の管理者が、社員やメンバーのIDやパスワードを管理できます。
これにより、新しいメンバーが入ってきたときや、誰かが退職したときに、簡単にIDを追加・削除したり、アプリやサービスへのアクセス権限を変更したりできます。
つまり、Azure ADは、インターネット上でID管理を効率的に行うための仕組みであり、私たちがアプリやサービスを安全に使えるようにしてくれるものです。


今回はこちらのAzureAD周りの権限が足りなかったことで発生しました。
Azureの権限の中でもテナントベースとロールベースがあるのでそこは注意が必要したいところだと痛感しました。

## AzureADの権限を付与
無事AzureのDocに載せられてるような感じでユーザーやリソースを選択できるようになりました。

![assign-access-03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1812049/0042dadc-b022-5943-10e0-e8b64b460e49.png)
infisicalをAWSでデプロイしてみた！

# infisicalをAWSでデプロイしてみた！
## はじめに

皆さん、こんにちは。今日はインターンでインフラエンジニアとして働かせていただいている会社のAWS環境にOpen Source Software（OSS）であるinfisicalをデプロイした経緯とその成果についてお伝えします。

## そもそもinfisicalってなに？

infisicalは、エンドツーエンド暗号化（E2EE）によって安全性が高められた、ユーザーフレンドリーな管理画面を持つOSSです。チームでの環境変数の同期や管理を効率的に行うことができます。

## デプロイ前の課題

AWS、Docker、Terraformなど初めて触れる技術もあり、とりあえず挑戦してみるという前提から始まりました。
公式の[infisical](https://infisical.com)サービスも存在しますが、自社の環境変数を外部で管理するのは適切でないと判断したため、自社AWS環境へのデプロイを決定しました。

## デプロイプロセス

infisicalのWeb部分とデータベース部分を分ける形でデプロイを行いました。Web部分に関しては、[infisical/infisical (Docker Hub)](https://hub.docker.com/r/infisical/infisical) からイメージを取得してAWS ECSにデプロイ。データベースはEC2上にMongoDBを設置しました。

## 成果と反省点

デプロイに成功し、infisicalは自社のAWS環境で無事動作しています。ただし、反省点として、infisicalのアップデートが頻繁であり、最新版を常に取得していたため、新機能の導入時にエラーが発生しました。これを解決するために、Docker Hubから取得するイメージのタグを特定のバージョンに固定するように変更しました。

## まとめ
今回は、自社のAWS環境にinfisicalというOSSをデプロイする過程とその成果について紹介しました。
AWS、Docker、Terraformなど新しく学ぶ技術もあり、サービスをデプロイするという濃い学習をすることができました。
以上が今回のデプロイ経験の報告です。皆さんもinfisicalを自社環境に取り入れる際は、ぜひこの記事を参考にしていただければと思います。
video.jsでendedイベントが発火されない

## はじめに
以前、業務でvideo.jsを触っていた時に`ended`イベントが発火せず苦戦したので、その時に調査した内容と解決策をここにまとめます。

## 発生していた問題
動画がplayした時間、stopした時間、endedした時間をサーバに返す必要があり、それぞれのイベントリスナーが発火した時間を取得しようとしていましたが、`ended`イベントのみが発火しませんでした

## 原因
video.jsでは、videoのloop再生をONにしていると`ended`イベントが発火されずにループする挙動になります。業務で用いているvideo.jsでは、loopをONにしていたために`ended`イベントが発生しませんでした。

## 解決策1 loopをOFFにする
loopがONだと`ended`イベントが発生しないので単純にloopをOFFにすれば解決することはできます。

しかし、業務では諸事情でloop再生をOFFにすることはできなかったので、なんとかして動画の終了イベントを検知する必要がありました。

## 解決策2 timeupdateイベントから擬似的なendedイベントを発火させる
video.jsのイベントには、動画の現在時刻が更新されたときに発生する`timeupdate`イベントがあります。この`timeupdate`が発火した時の`currentTime`の値を変数に持っておき、動画の終了時刻から開始時刻に変化したタイミングを擬似的に`ended`イベントとすることができます。

例（React）
```typescript
const prevTimeRef = useRef<number>(0); // ループを検知するためにtimeupdateイベントの直前の時間を保持

const onReady = useCallback(
  (player: videojs.Player) => {
    // ループを検知してendedイベントを発火させる
    player.on('timeupdate', () => {
      if (
        prevTimeRef.current - player.currentTime() >
        player.duration() - 1
      ) {
        console.log('ended')
      }
      prevTimeRef.current = player.currentTime();
    });
  },
  []
);
```

ただし、`timeupdate`イベントの頻度はシステムの負荷に依存するため、正確な終了時刻を取ることはできないという課題があるため注意が必要です。今回は1秒以内に収まっていればループしたと判断しました。

## 最後に
loop時に`loop`イベントなるものが標準で用意されてくれていればこんな回りくどいことする必要ないんですけどね。。。
今回はloopをOFFにできなかったので苦肉の策でしたしより良い方法もあると思います。もしより良い方法があればコメントで教えてくださるとありがたいです！

ご覧いただきありがとうございました！
プルリクエストの作成とGitHub フローについて

## プルリクエストとは

プルリクエストとは簡単に言うと、開発者のローカルリポジトリでの変更を他の開発者に通知する機能です。プルリクエストは次のような機能を提供します。

・機能追加や改修など、作業内容をレビュー・マージ担当者やその他関係者に通知する
・ソースコードの変更箇所をわかりやすく表示する
・ソースコードに関するコミュニケーションの場を提供する
<br>

プルリクエストのメリットとしては下記のようなことが挙げられます。

・レビュー・マージ作業をタスク化して管理し、やりとりを記録できる
・作成されたプルリクエストは一覧で見ることができるため、未完了のプルリクエストを簡単に確認できる
・レビューを促進できる
・ソースコードの変更部分を明確に表示できる


## プルリクエストの作成
`git branch <ブランチ名>`

ローカルで作業ブランチを新規作成します。

`git checkout <ブランチ名>`
作業ブランチに切り替えます。

`git add <変更したファイル名>`
`git commit -m <コミットメッセージ>`
任意のファイルに変更を加え、変更をコミットします。

`git push origin pullrequest`
GitHub に作業ブランチで変更をプッシュします。
<br>

### *GitHub のウェブサイト上での操作*
GitHub のウェブサイトにアクセスし、リポジトリに移動します。

リポジトリのメインページに移動し、「Pull Requests」タブをクリックします。

「New Pull Request」ボタンをクリックして、プルリクエストを作成します。この際、比較元のブランチを作業ブランチ、比較先のブランチを main ブランチに設定します。

プルリクエストのタイトルや説明を追加し、変更内容を確認します。

問題がなければ、「Create Pull Request」ボタンをクリックしてプルリクエストを作成します。

プルリクエストが作成されたら、GitHub 上で変更をマージし、ブランチを削除します。
___


## ローカルへのリポートリポジトリの変更内容の取り込み
ローカルリポジトリの main ブランチに切り替え、リモートリポジトリ（GitHub）の main ブランチの内容をローカルリポジトリの main ブランチに取り込み、最後にローカルリポジトリの作業ブランチを削除する手順は以下の通りです。

`git checkout main`
ローカルリポジトリの main ブランチに切り替えます。

`git pull origin main`
リモートリポジトリ（GitHub）の main ブランチの最新の変更を取得し、ローカルリポジトリの main ブランチに取り込みます。

`git branch -d <ブランチ名>`
ローカルリポジトリの作業ブランチを削除します。


これで、main ブランチが最新の状態に更新され、不要な作業ブランチが削除されます。

## GitHub フロー
https://docs.github.com/ja/get-started/quickstart/github-flow(公式サイト)
https://www.kagoya.jp/howto/it-glossary/develop/githubflow/(参考にさせていただいたサイト)

「GitHub Flow」とは、GitHubで開発を進める際に使えるシンプルなワークフローです。GitHub社もGitHub開発の際に、このワークフローを使っています。

GitHub Flowの特徴は、メインとなるmasterブランチと作業用のブランチ（featureブランチ）の2種類だけでワークフローをすすめることです。
上記サイトにて分かりやすく概要がまとめられていたので引用させていただきます。

>GitHub Flow使用時の6つのルール
1.masterブランチのものは何であれデプロイ可能である
2.masterから説明的なブランチを作成する
3.名前をつけたブランチに定期的にpushする
4.いつでもプルリクエストを作る
5.マージはプルリクエストがレビューされた後だけ
6.レビューのあとは直ちにデプロイする


>GitHub Flowの流れ・使い方
作業用ブランチを作成し開発作業を行う
プルリクエストを実行する
コードレビューを行う
デプロイする
ブランチ・マージ

## ブランチの新規作成

`git branch <ブランチ名>`
ブランチを新規作成

`git branch`
ブランチ一覧を表示

## ブランチの切り替え
`git checkout <ブランチ名>`
ブランチの切り替え

## マージ

作業ブランチから main ブランチに変更をマージ（merge）する方法を示します。

1. **ローカルリポジトリで main ブランチに切り替えます**


    `git checkout main`
main ブランチを最新の状態に更新します。これにより、main ブランチに他の変更が取り込まれているかもしれません：
    <br>

1. **プルする**

    `git pull origin main`
    main ブランチを最新の状態に更新します。
    <br>

1. **マージする**

    `git merge <作業ブランチ名>`
    作業ブランチを main ブランチにマージします。
    マージコミットメッセージが生成されます：
    このコマンドは、作業ブランチの変更を main ブランチに取り込みます。
    <br>
1. **変更をコミットし、main ブランチにプッシュします**

    ```
    git commit -m "<コミットメッセージ>"
    git push origin main
    ```


    これで、作業ブランチの変更が main ブランチに取り込まれます。

この手順を実行することで、main ブランチに最新の変更が反映されます。
<br>
## ブランチの名前の変更
`git branch -m 前の名前 新しい名前`

## ブランチの削除
`git branch -d <ブランチ名>`
GitHub でリモートリポジトリ作成からプッシュまでの流れ

## リモートリポジトリ

GitHub上で新しいリポジトリを作成する手順を以下の通りです。


1. **GitHubにログインしてください**
    <br>

1. **ログインしたら、GitHubのホームページに移動します。**

    ページ右上にあるプロフィールアイコンをクリックし、ドロップダウンメニューから「Your repositories」（あなたのリポジトリ）を選択します。
    <br>

1. **"Repositories" ページに移動します。**
    このページでは、既存のリポジトリが一覧表示されています。
    "New"（新規）ボタンをクリックして新しいリポジトリを作成します。
    <br>

1. **"Create a new repository" ページが表示されます。ここで以下の情報を設定します**

    ---
    **リポジトリ名**
 新しいリポジトリの名前を入力します。これは一意でなければなりません。

    ---
    **説明**
    リポジトリの簡単な説明を入力します（任意）。

    ---
    **パブリックまたはプライベート**
    リポジトリを公開または非公開に設定できます。公開は誰でもアクセスでき、プライベートは特定のユーザーまたはチームにしかアクセス権が与えられません。

    ___
    **Initialize this repository with: README**
    リポジトリを初期化すると同時にREADMEファイルを作成します。通常、このオプションを選択します。

    ---
1. **設定が完了したら、画面下部にある "Create repository" ボタンをクリックします。**
    <br>


    これで新しいGitHubリポジトリが作成されます。その後、リポジトリにコードをプッシュするための手順に従うことができます。



## プッシュ
新しいGitリポジトリをローカルで作成し、それをGitHubなどのリモートリポジトリと連携させる手順は以下の通りです。
<br>

1. **新しいディレクトリを作成**: 新しいプロジェクト用のディレクトリを作成します。例えば、以下のコマンドを使用して新しいディレクトリを作成します。

   ```
   mkdir <ディレクトリ名>
   cd <ディレクトリ名>
   ```

    <br>

2. **Gitリポジトリの初期化**: 作成したディレクトリ内で、以下のコマンドを使用してGitリポジトリを初期化します。

   `git init`


   これにより、新しいGitリポジトリがローカルディレクトリ内に作成されます。
    <br>

3. **ファイルを追加**

   `touch <ファイル名>`
    プロジェクトファイルやコードファイルを新しいディレクトリに追加します。
    <br>



   `git add .`
    ファイルを追加した後、以下のコマンドを使用して変更をステージに追加します。
    このコマンドはすべての変更をステージに追加します。
    <br>

4. **コミット**

   `git commit -m "<コミットメッセージ>"`

    ステージに追加された変更をコミットします。コミットメッセージは変更内容を説明するものです。
    <br>

5. **リモートリポジトリの追加**: GitHubなどのリモートリポジトリを作成し、URLを取得します。
    <br>

6. **リモートリポジトリの設定**: ローカルリポジトリとリモートリポジトリを連携させるために、リモートリポジトリのURLをローカルリポジトリに設定します。

   `git remote add origin リモートリポジトリのURL`

   `origin`は通常、リモートリポジトリのデフォルトの名前ですが、変更することもできます。
    <br>

7. **プッシュ**: ローカルリポジトリの変更をリモートリポジトリにプッシュします。

   `git push -u origin main`
    <br>

   これにより、ローカルの`main`ブランチの変更がリモートリポジトリにアップロードされます。必要に応じて`main`ブランチをプロジェクトに合わせて変更してください。
    <br>

これで、新しいGitリポジトリが作成され、ローカルとリモートの両方で利用できるようになります。




## 追加の変更をプッシュ

ファイルに変更を追加し、それを GitHub にプッシュする手順は以下の通りです。
<br>

1. **ファイルを変更**
    以下のコマンドでリポジトリのルートディレクトリに移動します。
`cd /path/to/your/repository`
ファイルをテキストエディタで開き、変更を追加します。
    <br>

1. **変更をコミット。**

    `git add <ファイル名>`
    コマンドで変更をステージに追加します。


    `git commit -m "<コミットメッセージ>"`
    コミットします。変更をコミットするメッセージを付けてコミットします。
    <br>

1. **プッシュします**
    `git push origin main`
    これで README.md ファイルの変更が GitHub にプッシュされます。
    GitHub 上でリポジトリを確認すると、変更が反映されています。
    <br>

    

## クローン

1. GitHubで対象のリポジトリを開きます。
リポジトリのページに行くには、ブラウザで https://github.com/ユーザー名/リポジトリ名 を開きます。
ユーザー名とリポジトリ名をリポジトリの実際の情報に置き換えてください。

1. リポジトリの右上にある "Code" ボタンをクリックします。
その後、HTTPSまたはSSHのクローンURLを選択します。
通常、HTTPS URLは以下のようになります：https://github.com/ユーザー名/リポジトリ名.git。

1. ターミナル（コマンドプロンプトまたはGit Bashなど）を開き、クローンしたいディレクトリに移動します。
例えば、ホームディレクトリにクローンしたい場合は、次のコマンドを使用できます。

    `cd ~`

1. 次に、git clone コマンドを使用してリポジトリをクローンします。
クローンURLはGitHubリポジトリのURLからコピーして貼り付けます。

    `git clone <リポジトリのアドレス> <ディレクトリ名>`

    ディレクトリは新規だと自動で作ってくれます。
    クローンすると、リポジトリのコピーがローカルマシンに作成されます。

クローンが完了したら、指定したディレクトリに移動して、リポジトリ内で作業できます。



## その他コマンド
`git rm -r <ディレクトリ名>`　ディレクトリを削除
`git remote -v`　登録したリモートリポジトリを確認
`git remote remove <リモートリポジトリ名>`　リモートリポジトリを削除
変更状況を確認できる&元に戻すことができる

## 変更状況の確認
`git status`
確認

## 変更内容の確認
`git diff`
内容を確認


## 変更履歴
`git log`
履歴を表示する

`git log --oneline`
より簡潔に履歴を表示する


## ファイルの変更の取り消し

`git checkout -- <ファイル名>`
ファイルを直前のコミットの状態に戻す方法

## ステージの変更の取り消し
`git reset file_name`

`git add` でステージングしたファイルを取り消す

<br>

---


#### *ソースコードやプロジェクトファイルの変更や保存に関する一般的なフロー*
ワーキングツリー → インデックス → ローカルリポジトリ → リモートリポジトリ


ワーキングツリー : 最新のファイル状態
インデックス : コミットするためのファイル状態
ローカルリポジトリ : ファイルの変更履歴を記録(ローカル環境)
リモートリポジトリ : ファイルの変更履歴を記録(共有できる)

下記の用にそれぞれに変更履歴を反映させていきます。

`git add` : 「ワーキングツリー → インデックス」
`git commit` : 「インデックス → ローカルリポジトリ」
`git push` : 「ローカルリポジトリ → リモートリポジトリ」
コミットができる

## ローカルリポジトリの新規作成
新規ディレクトリを作成してください。
作成したディレクトリに移動して、Git のローカルリポジトリを新規作成してください。

`mkdir （ディレクトリ名）`
ディレクトリ作成

`cd （ディレクトリ名）`
作ったディレクトリに移動。

`git init`
ローカルリポジトリの新規作成


## 変更をステージに追加
作成したディレクトリの下にファイルを作成して、ステージに追加する。

`touch （ファイル名）`
ディレクトリの中にファイルを作る。

`git status`
正しく作成されているか確認

`git add （ファイル名）`
ワークツリーの変更をステージングエリアに追加する

## 変更を記録
`git commit -m "（変更内容を記載）"`
コミットする

`git log`
確認



## その他Gitのコマンド
備忘録的に残しておきます。

`git diff`
リポジトリとワークツリーの差分をチェック

`git diff -staged`
リポジトリとステージの差分をチェック


`git restore <ファイル名>`　
ワークツリーの変更を取り消す

`git restore -staged <ファイル名>`
ステージに挙げた変更をワークツリーに戻す

`nano <ファイル名>`
ファイルのテキストエディタを開く

`echo "追加したいテキスト" >> <ファイル名>`
コマンドラインでテキストを追記する方法
Nginxの設定で詰まった話

## 概要
1. ポートフォリオサイトをVueで作成したが、デプロイに詰まってしまった。
1. NginxのLogを確認したところ、permissionエラーであったため、対象ディレクトリの権限を付与した。
1. Nginxの再起動、インスタンスごとの再起動でも変わらずpermissionエラーが発生してしまう。
1. /WWWディレクトリを作成し、そこに権限を与えることで解決した。

## 環境
* EC2(AamazonLinux2023)
* Nginx v1.24.0
* Vue3

## 発生したエラー
```
2023/09/25 10:56:41 [crit] 2129#2129: *1 stat() "/home/ec2-user/[ディレクトリ名]/dist/" failed (13: Permission denied), client: 175.177.43.47, server: hogehoge.com, request: "GET / HTTP/1.1", host: "hogehoge.com"
```

要は、nginxユーザーが`"/home/ec2-user/ec2-dep/dist/"`にアクセスする権限を持たないことが原因で発生したようだった。

## 結論

```.conf:/etc/nginx/conf.d/hogehoge.conf
server {
    listen 80;

    server_name hogehoge.com; # ここに実際のドメイン名を入れてください。

    location / {
        root /www; # ここにビルドされたコードへのパスを入れてください。
        try_files $uri $uri/ /index.html;
    }
}
```

ec2-userで実行

```
sudo mkdir /www
```
同じように下記コマンドを実施
```
sudo chmod 755 /www
sudo chown nginx:nginx /www
```

試し用のファイルを作成
```
echo '<h1>Hello, World!</h1>' | sudo tee /www/index.html
```

Nginxをリスタート
```
sudo systemctl restart nginx
```

インスタンスのオープンIPにアクセスして、`Hello,World!`と表示されたら成功です！！

あとは、
```
npm run build
```
して、アプリをbuildしてください。
```
sudo cp -r /home/ec2-user/[ディレクトリ名]/dist/* /www/
```
/www/にdistの内容をすべてコピーしてください。

Nginxをリスタート
```
sudo systemctl restart nginx
```

再度アクセスして、変更が反映されていたら終了です！！

## 参考サイト

https://maitakeramen.hatenablog.com/entry/2019/08/23/225552#sikumi

https://asameshicode.com/deploy-vue-app/
プロセス・ジョブを管理する

## プロセス
`ps aux`

全ユーザーのプロセスを表示

## バックグラウンド
`<任意のコマンド> &`


文末に&を追加するとバックグラウンドで実行できる。
<br>

`jobs`

バックグラウンドで実行されているジョブのステータスやジョブ番号を確認するには、`jobs` コマンドを使用できます

## プロセス・ジョブの終了
バックグラウンドで実行中のコマンドを終了させるには、`kill` コマンドを使用します。まず、`jobs` コマンドを実行して、バックグラウンドで実行中のジョブのリストとジョブ番号を確認します。次に、`kill` コマンドを使用してジョブを終了します。

1.  `jobs` コマンドを実行してバックグラウンドジョブのリストとジョブ番号を確認します。例えば、次のように表示されるかもしれません

    `[1]+  <任意のコマンド> &`
    この場合、ジョブ番号は [1] です

1. ジョブ番号を使用して `kill` コマンドでジョブを終了します。
例えば、ジョブ番号が [1] の場合

    `kill %1`
    <br>
    または、PID（プロセスID）を使用しても終了できます。PIDは jobs コマンドを実行して表示されるジョブの情報から取得できます。
    <br>
    
    `kill PID`
    ジョブが終了すると、そのバックグラウンドジョブは停止します。
パーミッション操作

## ファイルのオーナーとグループ
`ls -l README.md`　

このコマンドは、README.md ファイルの詳細情報を表示します。オーナーとグループは、表示される行の中で所有者（Owner）とグループ（Group）の列で確認できます。

`-rw-r--r-- 1 username groupname 12345 Sep 22 10:00 README.md`
上記の例では、ファイルの所有者は username であり、グループは groupname です。


## ファイルのパーミッション

**3つのセット（rw-, r--, r--）**：それぞれ、所有者（Owner）、グループ（Group）、その他（Others）に対するアクセス権限を示します。

各セットは以下のように解釈されます：

**r（読み取り権限）**：ファイルの内容を表示できます。
**w（書き込み権限）**：ファイルの内容を変更できます。
**x（実行権限）**：ファイルを実行できます（通常は実行可能ファイルに対してのみ）。
**-（権限なし）**：該当のアクセス権限がありません。
<br>
したがって、`-rw-r--r--` は次のように解釈されます：

**所有者（Owner）**：読み取り（r）と書き込み（w）の権限を持っています。
**グループ（Group）**：読み取り（r）の権限を持っています。
**その他（Others）**：読み取り（r）の権限を持っています。
## ファイルのパーミッションの設定
`chmod u+rwx README.md`  
README.md ファイルのオーナーに対して、読み取り、書き込み、実行の全ての権限を付与

`ls -l README.md`　確認
## ディレクトリのパーミッションの設定
`mkdir`　　
ディレクトリ作成

`chmod g+w ディレクトリ名`　　
このコマンドは、g+w を使用してグループ (g) に対して書き込み権限 (w) を追加します。

`ls -ld ディレクトリ名`　ディレクトリができてるか確認
## スーパーユーザー
`sudo mkdir ~/superuser`

このコマンドは、スーパーユーザー権限で superuser ディレクトリを作成します。sudo を使用することで、スーパーユーザー権限が必要な操作を実行できます。


`ls -ld ~/superuser`
このコマンドは、superuser ディレクトリの詳細情報を表示し、そのディレクトリのオーナーを確認します。
じゃんけんアプリ　Vue.jsを勉強したし取り敢えずアプリを作ってみた。　Part２

画面も頭も白くなった所からのスタートです。

その後触っていると、scriptタグ内が間違っていると白くなるみたいです、、
30分試行錯誤しましたがギブアップ、、先人達の力を借りたいと思います。

簡単だと思い甘くみてました。

色々なサイトを参考させて貰いましたがVue.３仕様にしないといけない様です。
解決策も見つかり何とか良い形になったのではないかと思います。

![スクリーンショット 2023-09-18 20.11.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3512450/a5555348-bf79-a562-2d12-66dabe0e2117.png)
![スクリーンショット 2023-09-18 20.11.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3512450/f8cfd7d6-4cb0-cdd4-c920-ca4e330599a5.png)

ボタンを押したら黒い文字が消え、
相手の手、じゃんけん結果が表示されます。
思っていたよりじゃんけんの条件式が難しすぎてパンクしました。

自分なりのアレンジを加えているものの参考サイトに頼りっきりです。

自分の力だけで作れると思っていたので悔しい気持ちはありますが、初心者だからしょうがないと自分に言い聞かせて次の工程に進んで行きたいと思います。

続いては、相手の手を画像にして表示する機能をつけて行きたいと思います。
この機能が出来れば完成間近なので頑張っていこうと思います。
リダイレクト&/dev/null&パイプライン

## 標準入出力とは
Linuxは標準入力と標準出力を使用して動作しています。
キーボードからコマンドなどの入力を受け取り、コマンドの実行結果を画面に表示していることになります。
<br>

**標準入力**には一般的にキーボードが使われる
特に指定しなかった場合に利用されるデータの入力元のこと

**標準出力**はターミナルの画面が使われます。
特に指定しなかった場合に利用されるデータの出力先を標準出力という


エラーが発生した場合のエラーメッセージは、**標準エラー出力**として別に扱われています。
また、標準入力と標準出力に加え、エラーメッセージを表示するための標準エラー出力が用意されています。
この3つをあわせて標準入出力といいます。

## リダイレクト
`ls ~ > ~/root.txt`

このコマンドは、ls / でルートディレクトリの内容を表示し、> 演算子を使用してその出力を新しいファイル ~/root.txt に上書き保存します。


## エラー出力のリダイレクト
`ls aaa 2> Test_File.txt`

2が重要！


## 出力とエラー出力のリダイレクト
`{ ls /; ls /hoge; } > ~/result.txt 2>&1`

`{ ls /; ls /hoge; }`：カーリーブレース {} 内に2つの ls コマンドを記述し、これらのコマンドを連結します。つまり、ls / と ls /hoge を順番に実行します。


2>&1：標準エラー出力（stderr）を標準出力（stdout）にリダイレクトします。これにより、エラーメッセージも ~/result.txt ファイルに含まれます。
## /dev/null とは
/dev/null に書き込まれたデータはすべて破棄され、どこからどれだけ読み込んでも何もデータを返しません(EOFを返します)。
つまり何を読み書きしても何も起きないようなデバイスファイルとして用意されているのが /dev/null です。

いらない出力ストリームを捨てたり、空のデータの入力ストリームとして扱ったりできます。



## /dev/null へのリダイレクト
`ls / > /dev/null`
このコードは、ファイルとディレクトリの一覧を取得し、それを /dev/null にリダイレクトして捨てるコマンドです。


## パイプライン
小さなコマンドをパイプで連結することによって、複数のコマンドがまるで一つのプログラムのように動作する。その出力結果を自由に操ることができる。

`ls / | grep '^l'`

このコードは、ルートディレクトリ内のファイルとディレクトリの一覧を表示し、その中からファイル名やディレクトリ名が "l" から始まるものだけをフィルタリングするためのコマンド。
ファイルを操作する

## ファイルの中身を出力
`cat` 

ファイルの中身を表示しながらスクロースするが、表示は途中で止まらずに行末まで表示するとコマンドが終了する

## ファイルの中身をスクロール表示

`less` 

「less」ファイル内容を表示し、スクロールできる


## ファイルの作成
`touch READ.md`
空のファイルが作れる

`echo "文字列" > ファイル名`
ターミナルからファイルに文字を書き込む     

`nano ファイル名`
テキストエディタを開く

## ファイル名の変更
`mv　変更前のファイル名　変更後のファイル名`

## ファイルのコピー
`cp　コピー元のファイル名　コピーした後のファイル名`

## ファイルの削除
`rm 削除したいファイル名`

## シンボリックリンク
`ln -s 既存のパス名　別名のパス名`
`ls -l`　で確認できる　矢印がついていたらOK



## ファイルの検索
 `$ find ファイル名`
ファイル名を指定して検索    
<br>

`find 検索対象のディレクトリ/ -type f -exec grep -l "探したい文字列" {} \;`

検索する文字列が含まれるファイルを検索する方法  
<br>

`grep [検索したい文字列] -rl [検索対象フォルダのパス]`

ファイルを開いた中身に、「○○」という文字列が含まれているファイルのリスト。


## 検索
`echo -e "文字列" > ~/ファイル名`
sample.txt　に書き込む


`grep '^a' ~/sample.txt`
sample.txt ファイルから、"a" で始まる単語を検索　



**^**      テキスト行の先頭 
**$**      テキスト行の終わり 
**.**       任意の 1 文字
Linux って？

# OS とは

・コンピュータの基本的な人格
・魂みたいなもの
・これがないと動かない

OSとは「オペレーティングシステム」の略語で、基本ソフトウェアとしてソフトウェア（アプリなど）とハードウェア（データなどの記録・保管装置）をつなぐ役割を担っています。

# Linux とは
Linuxは、OSの一種で、「無料で使えるオープンソース」。
オープンソースとは、世界中に公開されている無料のソースコードを指します。
したがって、Linuxをベースとした開発・改良を誰でも簡単に行えるのが特徴です。

# カーネルとディストリビューション
## カーネル
LinuxにおいてOSの核になるプログラムで、「Linux」というのも、カーネルに付けられた名前になります。
いわば、ＯＳそのものと言えます。


カーネルは直接はユーザーが操作することはできません。
その橋渡しをするのが、シェル(CUI)になります。

## ディストリビューション
Linuxは、「カーネル」がコア部分で非常に重要なプログラムにはなるのですが、それだけではLinuxを利用することができません。
他にも、アプリが利用するソフトウェアだったり、ユーザーインターフェイス部分だったりが必要です。
Linuxに、それらライブラリや、インターフェイスをセットにした製品を「Linux ディストリビューション」と呼びます。

---
#### 有名なディストリビューション
Ubuntu  Debian系
Fedora（フェドーラ）  RedHat系
CentOS(セントオーエス) RedHat系
Slackware系というのもある

---

## シェル
シェルは人間が理解できる形で書かれたコマンドを機械語に翻訳してカーネルに渡します。
ユーザーとカーネルの橋渡しをしてくれる、ユーザーがLinuxを利用する上で必要なプログラムになります。
代表：・bash
　　　・csh
bytes型を要素としたリストを、str型を要素としたリストにする（Python 3）

## はじめに

IPTCInfo3で画像ファイルの情報を取得すると、各要素の型はbytes型（文字列の文字コード）で返されます。
たとえば、キーワードを取得すると、「bytes型を要素としたリスト」を返してきます。

「2月,冬,雪,ダム,雪景色,青空,サンプル」であれば、`[b'2\xe6\x9c\x88', b'\xe5\x86\xac', b'\xe9\x9b\xaa', b'\xe3\x83\x80\xe3\x83\xa0', b'\xe9\x9b\xaa\xe6\x99\xaf\xe8\x89\xb2', b'\xe9\x9d\x92\xe7\xa9\xba', b'\xe3\x82\xb5\xe3\x83\xb3\xe3\x83\x97\xe3\x83\xab']`が返されます。

これを`['2月', '冬', '雪', 'ダム', '雪景色', '青空', 'サンプル']`としたいので、各要素をstr型にしたリストに変換する方法を確認しました。

## bytes型を要素としたリスト

IPTCInfo3が返してくるリストを想定しています。

```python
# 「2月,冬,雪,ダム,雪景色,青空,サンプル」のリスト。各要素の型はbytes型
keywords = [b'2\xe6\x9c\x88', b'\xe5\x86\xac', b'\xe9\x9b\xaa', b'\xe3\x83\x80\xe3\x83\xa0', b'\xe9\x9b\xaa\xe6\x99\xaf\xe8\x89\xb2', b'\xe9\x9d\x92\xe7\xa9\xba', b'\xe3\x82\xb5\xe3\x83\xb3\xe3\x83\x97\xe3\x83\xab']
```

## 処理方法

### リスト内包表記

既存のリストから、新たなリストを作成する方法として用意されています。
特に理由がなければ、この方法が良いと考えます。

```python
list_decoded = [k.decode('utf-8') for k in keywords]

# 結果
# ['2月', '冬', '雪', 'ダム', '雪景色', '青空', 'サンプル']
```

### 通常のループ

多くの言語で可能な、汎用的な方法です。
Pythonでは、特に事情がなければ、やはりリスト内包表記で処理するのが良いと思います。

```python
list_decoded = []
for k in keywords:
    list_decoded.append(k.decode('utf-8'))

# 結果
# ['2月', '冬', '雪', 'ダム', '雪景色', '青空', 'サンプル']
```

### join()でリストを結合する際に、リストの各要素をデコードして、再度リスト化する

join()でリストを結合する際に各要素をデコードできると知って、最初に思いついた方法です。
これでも動作はしますが、この方法で処理する必要性は少ないと思います。
Pythonらしく記述するなら、リスト内包表記が良いと思います。

```python
list_decoded = b','.join(keywords).decode('utf-8').split(',')

# 結果
# ['2月', '冬', '雪', 'ダム', '雪景色', '青空', 'サンプル']
```
SRAMで遊んでみる (SRM2B256SLMX55)

- SRAM、スタティックRAM。静的。フリップフロップ(FF)で論理的に記憶しているのでDRAMの様に記憶保持動作、リフレッシュが不要。
- 高速動作するのでMPUの二次キャッシュに使われたりするもののDRAMに比べて構造が複雑なので大容量には向かないメモリ。WSやPCには構造の簡単なDRAMを使用。
- このSRM2B256SLMX55(60円。安い..)はアドレスバスがA0～A14まで15本あるので2^15で32768アドレス。
- 1アドレス当たり8BIT(I/Oバスが8ピン)あるので32768アドレス*8BITで262144BIT。
8BITで1バイトなので262144ビット/8BITで32Kバイト。1980年代のPCのメモリ容量相当。
この用量では高解像度の写真データは入らないがログデータ等記録する分には十分。
- PCへのデータ受け渡しはSDカードなど利用すればスマートだが特にアセンブリでは結構難しいのでデータはSRAMに入れてRS232C経由で受け渡しすると簡単。 
![img020.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821882/e4ea03c9-fe05-1c24-2c3a-8ab01fc7d759.jpeg)
- ブレッドボードで試験
![P1130468.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821882/69d7190b-14a6-eb05-4d85-5f9c286554b0.jpeg)
- 表面実装用チップなのでブレッドボード用に拡張する基盤使用。このはんだ付けは意外と簡単。
- CSとアドレスピンは全てGNDに接続しアドレスは0H番地固定。
- 逆にVccに接続すれば8000H番地に書き込み。実際には別途カウンタ等に接続して自動的にアドレスを変える。
- I/OはI/O1,2,3の3本使用なので3Bit書き込める。OE、WEもPICに接続。
- 書き込んだデータと比べて合致しているとLED点灯。
- I/Oポートは常時入力モードにしておいて書き込み時に出力有効(OE,WE HI)モードに変更してからIOポートを出力モードに変更する。  
![SRAMTEST.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821882/1e776acf-797e-5502-8fd4-c1731bc014a1.jpeg)

```asm
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; inf102 / SRAM SRM2B256SLMX55 TEST FOR 16F88

	__CONFIG _CONFIG1, _CP_OFF & _CCP1_RB0 & _DEBUG_OFF & _WRT_PROTECT_OFF & _CPD_OFF & _LVP_OFF & _BODEN_OFF & _MCLR_OFF & _PWRTE_ON & _WDT_OFF & _INTRC_IO 
	__CONFIG _CONFIG2, _IESO_OFF & _FCMEN_OFF

	LIST		P=PIC16F88
	INCLUDE		P16F88.INC

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	CBLOCK	020h
	CODEA
	ENDC
	
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	BSF		STATUS,RP0

	CLRF	OSCCON			; 31.25KHz
	CLRF	ANSEL
	MOVLW	0XFF
	MOVWF	TRISA			; IOPORT INPUT MODE
	CLRF	TRISB			; 0=WE 1=OE 3=LED
	
	BCF		STATUS,RP0 

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;WRITE
	BSF		PORTB,0			; OE,WE HI(output disable)
	BSF		PORTB,1

	BSF		STATUS,RP0		; IOPORT OUT　MODE
	CLRF	TRISA
	BCF		STATUS,RP0 	

	MOVLW	B'000000001'
	MOVWF	PORTA 			; ADRESS 0H DATA 1write
	
	BCF		PORTB,0			; WE　LOW
	BSF		PORTB,0			; WE HI

	BSF		STATUS,RP0		; INPUT MODE
	MOVLW	0XFF
	MOVWF	PORTA
	BCF		STATUS,RP0 

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

	BCF		PORTB,3			; LED OFF
	CLRF	PORTA

;READ
	BSF		STATUS,RP0		; INPUT MODE
	MOVLW	0XFF
	MOVWF	PORTA
	BCF		STATUS,RP0 

	BCF		PORTB,1 		; OE LOW
	BSF		PORTB,0			; WE HI
	MOVF	PORTA,W			; ADRESS 0h DATA -> W
	MOVWF	CODEA

	BTFSC	CODEA,0			; BIT0 [1] CHK.
	BSF		PORTB,3			; LED ON

	GOTO	$


	END
```
Conoha オブジェクトストレージ: 認証トークンの取得

参考ページ
[認証トークンの取得](https://support.conoha.jp/v/objectstoragecurl/?btn_id=vps-objectstorage--contents_v-objectstoragecurl#01)

## Identify Service のエンドポイントを調べる

Conoha の管理パネルにログインして、
API -> エンドポイント
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/d988582e-6b51-60d2-1dce-b421a42422a2.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/578bdca2-b3a7-4617-bc4f-a0c3c61b2379.png)

この場合は、次がエンドポイントです。
https://identity.tyo2.conoha.io/v2.0

# プログラム

## auth.json　(例)

```json:auth.json
{
  "auth": {
    "passwordCredentials": {
      "username": "ConoHa",
      "password": "paSSword123456#$%"
    },
    "tenantId": "487727e3921d44e3bfe7ebb337bf085e"
  }
}
```

## Curl

```bash:curl_token.sh
#
URL="https://identity.tyo2.conoha.io/v2.0/tokens"
#
curl -X POST -H "Accept: application/json" \
	-d @auth.json $URL > out01.json
#
jq .access.token.id out01.json
```

## Httpie

```bash:http_token.sh
#
URL="https://identity.tyo2.conoha.io/v2.0/tokens"
http POST $URL @auth.json > out02.json
#
jq .access.token.id out02.json
```

## Python

```py:get_token.py
#! /usr/bin/python
#
#	get_token.py
#
#					Sep/26/2023
#
# ------------------------------------------------------------------
import	sys
import	json
import	requests
# ------------------------------------------------------------------
def file_to_str_proc(file_in):
	str_out = ""
	try:
		fp_in = open(file_in,encoding='utf-8')
		str_out = fp_in.read()
		fp_in.close()
	except Exception as ee:
		sys.stderr.write("*** error *** file_to_str_proc ***\n")
		sys.stderr.write(str (ee))
#
	return	str_out
# ------------------------------------------------------------------
sys.stderr.write("*** 開始 ***\n")
#
file_in="auth.json"
json_str=file_to_str_proc(file_in)
url="https://identity.tyo2.conoha.io/v2.0/tokens"
#
rr=requests.post(url,json_str)
#print(rr.text)
#
dict_data = json.loads(rr.text)
#
print("token:\t" + dict_data['access']['token']['id'])
#
sys.stderr.write("*** 終了 ***\n")
# ------------------------------------------------------------------
```
疑似移動プロファイル


#### ----概要----
ActiveDirectory環境で提供される「移動プロファイル」
これはデスクトップ、マイドキュメントなどのデータをサーバに置いて、
何処でログインしてもデスクトップ内容等が同じ、同期されているという機能ですが、これを疑似的に再現する方法。
NASにディレクトリを作って適当に権限設定してそのディレクトリを画像の様に設定するだけ。

#### ----利点----
- 何処でログインしてもデスクトップが同じ
- PCをリカバリ、初期化してもデータはNASなので残ってる
　(バックアップをする必要がない)
- NASがRAID1,5 等だとストレージが損傷してもデータは保全される
　(普通はHDD損傷で全て失われる。しかもいつ来るか分からない)
- スマートフォン等でもPCのデスクトップファイルを参照できる
- その他、ドキュメントフォルダも可能。

#### ----欠点----
- ネットワーク越しなので多少遅い
- たまにデスクトップが出ない、表示されるまで待たされることがある(自分だけかもしれない)

#### ----設定方法----
![1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821882/ae84a7fc-7658-15e2-32b7-09a6e0aa4b94.jpeg)
Firebaseでproductionとstaging環境をセットアップする

### 1. プロジェクトの設定:
Firebaseプロジェクトを2つ作成する方法でやります。1つはstaging用、もう1つはproduction用として使います。

### 2. Firebase CLIの設定:
ローカルマシンでFirebase CLIをセットアップして、両方のプロジェクトにアクセスできるようにします。
```
firebase use --add staging
```

上記のコマンドで、CLIに複数のプロジェクトを追加できます。それぞれのプロジェクトにエイリアス（例: staging と production）を設定します。


### 3. 環境変数の設定:
Cloud Functionsで環境固有の設定を持つ場合、Firebaseの環境設定を使用してそれらの設定を保存できます。
```
firebase functions:config:set someservice.key="THE API KEY" someservice.id="THE CLIENT ID"
```
上記のコマンドを使用して、それぞれの環境に環境変数を設定します。


```package.json
"scripts": {
		"use:staging": "firebase use staging && firebase functions:config:set env.is_local=true env.is_production=false && firebase functions:config:get > .runtimeconfig.json",
		"use:production": "firebase use production && firebase functions:config:set env.is_local=true env.is_production=true && firebase functions:config:get > .runtimeconfig.json"
}
```
こんな感じでpackage.scriptsに呪文を追加しておくと便利ですね！
```yarn
yarn use:staging
or
yarn use:production
```

現場からは以上です！
S3のオブジェクトロックについて色々確認してみる

# この記事でやること
S3のオブジェクトロックについていろいろ確認してみる

# オブジェクトロックの有効化
オブジェクトロックは現在では、新規作成時のみ有効化することができます。


>新しいバケットに対してのみオブジェクトロックを有効にすることができます。既存のバケットのオブジェクトロックをオンにする場合は、 にお問い合わせくださいAWS Support
>オブジェクトロックが有効になっているバケットを作成すると、Amazon S3 は自動的にバケットのバージョニングを有効にします。
>オブジェクトロックを有効にしたバケットを作成すると、オブジェクトロックを無効にしたり、バケットのバージョニングを停止することはできません。


バケットの詳細設定から設定可能です。

オブジェクトロックを有効化するとバケットのバージョニング機能が自動的に有効化されます。

[作成時]
![Screenshot 2023-09-25 at 20.47.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/626370/57107a88-b19c-3fb5-774d-afb68edde2dc.png)


[作成後]
※作成した段階では、保持期間は無効にされています。
![Screenshot 2023-09-25 at 20.48.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/626370/f201f42e-baee-ec93-4afc-560e0d294ea1.png)

有効にすると、保持モードが選択できます。

- ガバナンスモード
    - s3:BypassGovernanceRetention権限を持たないユーザーはオブジェクトの上書き、削除ができない

- コンプライアンスモード
    - ルートユーザーを含め、すべてのユーザーはオブジェクトの上書き、削除ができない

コンプライアンスモードに設定すると、保持期間が終了するまでオブジェクトの削除ができなくなるのでまずはガバナンスモードでの使用を推奨します。

保持期間は、日・年単位で指定できます。

ちなみに、オブジェクトロックの設定はコンプライアンスモードでも変更可能です。

![Screenshot 2023-09-25 at 20.51.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/626370/be6e8b77-427b-eb36-527f-30750d887f64.png)

何か重要なデータやログを保管する用のバケットにはオブジェクトロックの設定を有効にしても良いと思いました。


# 参考文献
https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/object-lock-overview.html

https://dev.classmethod.jp/articles/amazon-s3-object-lock-research/

今日はここまで。ありがとうございました！！