OmniAICreator/Qiita-1.07M huggingface dataset:
【Flutter】asdfの管轄外でFlutterをインストール/アップグレードしてしまった時

## 概要
バージョン管理ツールのasdfでFlutterのバージョンを管理しているにも関わらず、プロジェクトディレクトリ内で直接Flutterをインストール/アップグレードしてしまった時の対処法です。


## 環境
MacBook Pro M1 2020
メモリ：16GB
macOS：Sonoma


## 結論
プロジェクトディレクトリで
```
which flutter
```
を打って`/Users/username/.asdf/shims/flutter`を指定している場合は正しくasdfを参照できています。参照元が正しいことを確認できた場合、一旦asdfでFlutterをアンインストールし、再度インストールしましょう！

1.プロジェクトディレクトリにいる状態ですべてのバージョンのFlutterをアンインストール
```
asdf uninstall flutter
```
2.Flutterが正しく削除されたことを確認
```
which flutter
```
3.Flutterをインストール（"バージョン"は3.19.3-stable等バージョンを指定します。）
```
asdf install flutter バージョン
```
4.flutterが正しくインストールされたことを確認
```
flutter doctor -v
```
上記の方法でFlutterバージョンをasdfの管理下に戻すことができます🎉

※pubのパッケージを利用している場合はプロジェクトをビルドする前に`flutter clean && flutter pub get`を実行してpackage導入とクリーンをしましょう！


## 背景
プロジェクトディレクトリで`flutter upgrade`を誤って実行し、問答無用で最新版にアップデートされてしまったのを元に戻すところでハマってしまいました。

### 当時の状況
- asdfでPCのデフォルトとしてglobal設定しているFlutterバージョンは`3.19.3-stable`
- asdfでプロジェクトディレクトリのバージョンとしてlocal設定しているFlutterバージョンは`3.13.8`
- プロジェクトのリモートdevelopブランチで使っているFlutterバージョンは`3.19.3`
- プロジェクトのリモートdevelopブランチをpullした後プロジェクトディレクトリのバージョンを変更しようとした際に誤って`flutter upgrade`を実行し直接上げてしまったFlutterバージョンは`3.22.2`

本来はasdfでバージョンを管理しているので`flutter upgrade`をする必要はありません。プロジェクトのflutterバージョンとプロジェクトディレクトリのflutterバージョンが異なることに起因するビルドエラーから頭がこんがらがり、気づいたら間違えて`flutter upgrade`を打っていました。着々と最新バージョンがインストールされていく様子に思考が停止しました...
asdfの管理外で直接flutterのバージョンを上げてしまったものの、プロジェクトディレクトリが参照しているのはasdfのままでした。asdfが管理するflutterのフォルダに、直接インストールした最新バージョンの中身が突っ込まれている状態です。新しいバージョンも含め丸ごと消して解決したということになります。


## 本来行うべきasdfを使ったバージョン管理の方法
プロジェクトディレクトリで使うFlutterバージョンを指定する時
```
asdf local flutter バージョン
```
asdfでバージョン管理をしている場合、本来は上記のコマンドを打つだけでバージョンを指定することができます。


## 備考
asdfで管理している場合、そうでない場合も、`flutter downgrade`コマンドは効果がありません。asdfで管理している場合はasdfでバージョン指定を、そうでない場合はGitからFlutterの過去バージョンを取得してダウングレードすることができます。方法はさまざまな記事がありますのでご参照ください。


## おわりに
一度失敗したのでもう失敗はしないですね！
最後までお読みいただき、ありがとうございました。
突然VSCodeが起動しなくなったよ

## VSCodeが起動しなくなったよ

ブラウザで調べ物をしたのち、さぁ取り掛かろうかとVSCodeのアイコンをクリックするが
一瞬メニューがVSCodeになるだけで、またFinderに戻ってしまう。（Mac）
さっきまで起動してくれてたのに。

今VSCodeに死なれたら共倒れだぜー！と調べてみると
バージョンアップしたものと相性が悪かったんだな、
今のところ旧バージョンをインストールするしか方法はねぇぜ！HaHaHa！
という英語のIssuesがあったので以前のバージョンをインストールしてみた。

## 旧バージョンをダウンロード

[Visual Studio Code FAQ](https://code.visualstudio.com/docs/supporting/faq "Visual Studio Code FAQ")
このページの Previous release versions 項目に
旧バージョンのVSCodeがダウンロードできるURLが書いてあった。

例えば Intel Mac であれば下記。
| macOS Intel chip | https://update.code.visualstudio.com/{version}/darwin/stable |
|:-----------|:------------|

この {version} にダウンロードしたいバージョン番号を入れる。

[Visual Studio Code Updates](https://code.visualstudio.com/updates/v1_91 "Updates")
このページの左列にアップデート履歴があるので希望の年月を選択。

例えば　May 2024　を選択すると
May 2024 (version 1.90)　が表示される。

## 慌てないで

バージョンが表示されたので早速先程のURLに適用し、
ダウンロードしようとしたが「Cannot GET /1.90/darwin/stable」の表示。
https://update.code.visualstudio.com/1.90/darwin/stable

注意して見たらページタイトルの下に履歴の表示があった。
Update 1.90.2: The update addresses these issues.
Update 1.90.1: The update addresses these issues.

なのでURLを修正
https://update.code.visualstudio.com/1.90.2/darwin/stable

無事ダウンロード出来ました。

## そして起動

無事起動もしました。

今回はたまたまVSCodeのバージョンアップとの相性が悪かったと思う。

しかし無事に起動できて良かった。


## その後

自動更新をOFFにしないと
またまたバージョンアップで起動できなくなるよ。
DX Suite (New UI) と WinActorのAPI連携のRPA実行してみた。

## はじめに
今回はDX Suite (New UI)と、国産RPAでおなじみのWinActorを組み合わせた業務効率化のお話です！
「API連携」という方法でDX Suite (New UI)とWinActorを組み合わせて、
**WinActor実行ボタンをポチッ！⇒ 読取結果CSV出力完了！**
までできるRPAを実行してみます！

「うちではもうRPAと組み合わせてDX Suite を使ってるから関係ないか…」
と思ったそこのあなた！待ってください！
その処理速度…もっと速くなるかもしれませんよ…？(ニヤリ)

## 実行シナリオについて
今回お見せするシナリオは、WinActor公式から提供されているサンプルシナリオをもとにしています。
現状、公式からは旧UI版のサンプルシナリオしか提供されていないので、
弊社でNew UI に対応するように変更したシナリオで実行していきます！

:::note warn
以下、WinActorのサンプルシナリオ画像です。
今回使用するサンプルシナリオは、**1枚の画像ファイル読取**に対応しています。
※画像、縦に長いです(><)
:::

![フロー図.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3625460/bdbb4ba3-928f-75cf-f036-44d73c5cf79f.png)



※画像参照元：[DX Suite (NewUI) と WinActorのAPI連携を実装](https://bstyle-value-technologies.blogspot.com/2024/06/winactor3.html)

:::note info
複数枚ファイルの読み取りに対応したシナリオも弊社で作成できます！
:::
  
## 実際にシナリオを実行してみよう
### 実行準備
- DX Suite のワークフロー設定を事前に行ってください
    読取対象帳票の読取箇所等を設定してください。
    今回は以下の画像を使用し、次の3点を読み取るワークフローを作成しています。
    - フリガナ
    - 名前
    - 住所

    ![原紙_個人票.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3625460/b0511f6d-dc2b-061e-f864-5d9c67a8a05c.png)

### 実行方法
1. New UI に対応したサンプルシナリオを開く
1. 変数一覧を表示する
1. グループ名「実行前設定」内の変数の初期値を変更する
1. サンプルシナリオを実行する


## 実行結果
API連携で「画像の読取～CSV出力」までを実行してみた結果、
問題なくDX Suite でユニットを作成して読み取り、読取結果をCSVで出力することができました！

DX Suite のサイトでの操作をすることなくユニットが作成され、
![⑤API連携実行結果.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3625460/9739bbfb-1044-283d-d382-93c331d9cbc0.png)


読取結果CSVも任意のフォルダに出力されました！
![⑥読取結果CSV保存.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3625460/07e86c95-0259-962a-5b93-978c4ee6a1a2.png)



驚くべきはその実行時間！
![④API連携実行時間.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3625460/d7561830-63d7-42f4-5967-b87fd5713237.png)
**なんと約8秒！**
今回は１つのPDFのみ処理しているので短時間で完了すると予想してましたが
10秒を切ってくるとは…！

## API連携とUI操作の違い
### API連携
- メリット
    - 処理スピードがめちゃめちゃ速い
- デメリット
    - 読み取りからCSV出力まで一気におこなうため、DX Suite 上で人の目によるデータチェックができない
### UI操作
- メリット
    - サイト上でどう動いているのかがわかりやすい
- デメリット
    - サイトのUIが変化してしまうとRPA改修作業が必要になってしまう

## 最後に
いかがでしたか？
API連携を活用していくことで、さらなる業務を効率化していくことができます！

今回のWinActor公式サンプルシナリオは1つの帳票を読み取る処理に対応しています。
「え、複数枚の帳票を読み取れないと困る！」
「フォルダ内にある帳票を全部読み取るような処理がしたい！」
そんなご要望にもお応えできるように、
**弊社では複数枚ファイルの読取に対応したシナリオも作成できます！**


また今回使用したWinActor公式サンプルシナリオも、弊社でNew UI に対応するように変更を加えています。
「何を変更したらいいの？」
「自分たちでやってみたい！」
という方向けに、変更方法の解説記事を用意しておりますのでご活用ください！
↓
**[DX Suite (NewUI) と WinActorのAPI連携を実装](https://bstyle-value-technologies.blogspot.com/2024/06/winactor3.html)**





※「DX Suite」はAI inside 株式会社の登録商標です。
【Rails】Amazon BedrockのKnowledgeBaseを使ってRAGを使ってみた。

どうもこんにちは。

今回は、Amazon BedrockのKnowledgeBaseを使ったRAGをRailsアプリケーションで行ってみました。

pineconeやKnowledgeBaseのセットアップ方法、AWSコンソール上でのテストについては、さまざまな方が記事にしているので、自分はRailsでの使い方にフォーカスして話を進めます。

# 環境

Ruby: 3.2.2
Rails: 7.1.3.4
リージョン： バージニア北部（東京リージョンだとpineconeが使えなかったので...）

# 前提条件

以下の記事を参考にして、pineconeやKnowledgeBaseをセットアップしたものとして話を進めます。

https://aws.amazon.com/jp/blogs/news/leveraging-pinecone-on-aws-marketplace-as-a-knowledge-base-for-amazon-bedrock/



# Railsへの実装

## 1. ライブラリインストール

Gemfileに記載して、インストールします。

```Gemfile
gem 'aws-sdk-bedrockagentruntime'
```

```sh
bundle install
```

## 2. Bedrockクライアント設定

```ruby
access_key = 'XXXXXXXXXXXXXXXXXXX'
secret_access_key = 'YYYYYYYYYYYYYYYYYYYYYYYYYY'
credentials = Aws::Credentials.new(access_key, secret_access_key)
bedrock_client = Aws::BedrockAgentRuntime::Client.new(region: 'us-east-1', credentials: credentials)
```

## 3. インプット文章の用意

```ruby
input = {
    "text": "私は日本人なので、日本語で教えてください。「<好きな質問してください。>」}"
}
```

## 4. APIのための設定

```ruby
config = {
    knowledge_base_configuration: {
    knowledge_base_id: "ZZZZZZZZZZZZ",
    model_arn: "arn:aws:bedrock:us-east-1::foundation-model/anthropic.claude-3-haiku-20240307-v1:0",
    retrieval_configuration: {
            vector_search_configuration: {
                override_search_type: "SEMANTIC"
            }
        }
    },
    type: "KNOWLEDGE_BASE"
}
```

## 5. リクエスト実行

```ruby
prompt = {
    input: input,
    retrieve_and_generate_configuration: config
}
response = bedrock_client.retrieve_and_generate(prompt)
```

## 6. レスポンス出力

```ruby
completion_value = response.output.text
```

以上
GROWIプラグインを開発する（テンプレート編）

[オープンソースの社内WikiであるGROWI](https://growi.org/ja/)にはプラグイン機能が用意されています。自社のデータを表示したり、表示をカスタマイズするのに利用できます。

今回は、GROWIプラグインの開発手順について解説します。まだ全体を把握できていないので、分かっている範囲ですが、開発時の参考にしてください。

## プラグインの種類

GROWIのプラグインには、以下の3種類があります。

- script
- theme
- template

今回はスクリプト（template）を対象として紹介します。

## 注意点

GROWIでは、日報や議事録など同じフォルダ内で繰り返し使える[ページテンプレート機能](https://docs.growi.org/ja/guide/features/template.html#%E9%9A%8E%E5%B1%A4%E3%81%AB%E5%AF%BE%E3%81%97%E3%81%A6%E3%83%86%E3%83%B3%E3%83%95%E3%82%9A%E3%83%AC%E3%83%BC%E3%83%88%E3%82%92%E9%81%A9%E7%94%A8%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95)もあります。この記事で取り上げるテンプレートは、任意のページで作成できる使えるテンプレート、かつオンラインに公開して共有できるプラグインになります。

## テンプレート

プラグイン作成に使えるテンプレートを作成しました。こちらをベースに解説します。

[goofmint/growi-plugin-script-template](https://github.com/goofmint/growi-plugin-templates-template)

## プラグインの構成

テンプレートプラグインはコーディング知識は不要です。編集するのは `dist` フォルダ以下になります。構成は以下のようになっています。

```
% tree .
.
└── example
    ├── en_US
    │   ├── meta.json
    │   └── template.md
    └── ja_JP
        ├── meta.json
        └── template.md

3 directories, 4 files
```

## 新しいテンプレートを作成する

`example` フォルダをコピー、またはリネームしてください。名称は自由ですが、後々のメンテナンスを考えて分かりやすいものにしてください。なお、テンプレートは複数作成できます。

## パッケージ名の変更

パッケージ名は `package.json` に定義されています。最初に変更してください。

```js
{
  "name": "growi-plugin-templates-for-template", // ここを修正
  "version": "1.0.0",
  "description": "GROWI template plugin for template", // ここを修正
  // 省略
}
```

## ロケール毎に修正する

GROWIはデフォルトで日英に対応しています。それぞれのロケール用に `en_US` と `ja_JP` フォルダが用意されています。他の言語を追加する場合には、 `package.json` を修正してください。この他、現在は中国語 `zh_CN` と フランス語 `fr_FR` に対応しています。

```javascript
{
  // 省略
  "growiPlugin": {
    "schemaVersion": "4",
    "types": [
      "template"
    ],
    "locales": [
      "en_US", "ja_JP" // ここに追加
    ]
  }
}
```

## メタファイルの修正

メタファイル `meta.json` では、テンプレートの一覧表示時の名前を設定してください。

```js
{
  "title": "Example title" // ここを修正
}
```

## テンプレートの修正

テンプレートの内容は `template.md` になります。内容を自由に編集してください。

```markdown
# テンプレート例

ここに素晴らしいテンプレート内容を記述してください！
```

これでテンプレートを自由に作成できます。

## テンプレートの内容を作成する

テンプレートの作成は、実際にGROWI上で書くのが簡単です。できあがった内容が問題ないのを確認して、 `template.md` にコピーしてください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197026/e1b4e220-575a-b179-2c70-d4382dd9db48.png)


## テンプレートを利用する

作成したテンプレートの利用手順です。

### 注意点

テンプレートはGitリポジトリとして公開されている必要があります。

### インストール

GROWIの管理画面、プラグイン管理にてインストールを行います。GitリポジトリのURLを入力してください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197026/6920dc59-9be0-15dc-1f3f-0061b67293a4.png)


### 利用する

利用する際には、ページの編集画面を表示して、下にあるファイルアイコンをクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197026/0742b182-5bc2-416f-59fb-4e665419f82c.png)


テンプレート一覧が表示されますので、そこから利用したいテンプレートを選択してください。ロケールも指定できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197026/b3066af0-1646-bce9-c101-ffaffea71a35.png)

## まとめ

テンプレートプラグインを使うことで、良くある構成のページを素早く作成できます。また、網羅性のあるページテンプレートを使うことで、記述漏れや検討漏れを防げます。

ぜひテンプレートを活用してください。

[OSS開発wikiツールのGROWI | 快適な情報共有を、全ての人へ](https://growi.org/ja/)
お金欲しい

**[前回の問題解決しました。](https://qiita.com/suzukidog/items/af09c201fac3cccc4687#%E8%A7%A3%E6%B1%BA20240705)**

***
俺はたまに自己満足で勉強画面を配信している（非公開）のだが、OBSを使うと常にCPUが80%に張り付くためパソコンは熱くなるし動作がちょっとカクカクする。
M1チップじゃ配信には少し足りないようなので買い替えたいとも考えるが、いかんせん高い…。
本当の本当に金欠で流石にパソコンを買う余裕はないので今は我慢。

あと配信をする上でもうひとつ不満があり、peppyを完全リスペクトした配信なため手元も映している。
しかし午後になり学生が増えてくるとカメラを向けられないので毎回カメラを切る必要がある。
こうなると完全個室制コワーキングスペースが欲しくなったり、家を建てて誘惑のない小さい部屋が欲しくなる。

どれもこれもお金が必要…勉強頑張って仕事初めてお金稼ぐぞ！
リレーショナルデータベースとRedisの利点を整理し、使い分け方を学ぶ

# まえがき
一時的なデータの置き場所を検討する際に「リレーショナルデータベースに退避する」「Redisに退避する」の2つが案として出てきたため、それぞれの優劣を整理しつつどちらを選ぶべきか検討してみたいと思います。

## 例示
以下のような架空のECサイトを例とします。
- カートに商品を入れた後、決済が完了したら購入処理を行う
- 決済は外部決済システムのAPIをリクエストする
- APIのリクエストを行う前に入力内容をどこかに退避しておく
- 決済システムは処理結果をWebhookで通知する
- Webhookを受け取ったら処理結果を確認し、決裁が成功している場合は顧客の入力内容をデータベースに保存する

```mermaid
sequenceDiagram
    participant Browser as ブラウザ
    participant EC as ECサイト
    participant PaymentAPI as 決済システムAPI(外部)
    participant WebhookReceiver as 決済結果Webhookハンドラ
    participant Database as データベースまたはRedis

    Browser->>EC: 購入リクエスト
    EC->>Database: 入力内容の退避(取引IDをキーとする)
    note left of WebhookReceiver: 入力内容
    EC->>PaymentAPI: 決済リクエスト (callback URLを含む)
    PaymentAPI-->>EC: 決済処理中
    PaymentAPI->>WebhookReceiver: 決済結果 (callback URL)
    WebhookReceiver->>Database: 取引IDをキーにして検索
    Database->>WebhookReceiver: 入力内容を取得
    note left of Database: 入力内容
    WebhookReceiver->>Database: 購入内容を登録
    EC-->>Browser: 購入完了通知
```

一時的な入力内容の退避場所としてリレーショナルデータベースとRedisのどちらを選ぶべきか検討していきます。

## リレーショナルデータベースとRedisの比較
### リレーショナルデータベースが優れているもの
#### データの永続化
データベースに保存されたレコードはよほどなことが起きなければ消失しません。
一方、Redisはデフォルトではメモリ上で動いています。
ですので、保存されたデータはサーバの停止などで消失する可能性があります。
なお、Redisにデータを永続化する仕組みはありますが、完全な永続化は保証されていません。

#### データ整合性
トランザクション管理が厳密に行われているのはリレーショナルデータベースです。
ACID特性が保証されており、部分ロールバックなどもサポートされていることが多いです。
Redisはシンプルなトランザクションコマンドが用意されていますが、完全なACID特性を保証していません。

### Redisが優れているもの

#### パフォーマンス
Redisは高速な読み書きを得意としており、その特性を活かしてキャッシュなどに用いられます。
リアルタイム性が求められる処理、あるいは一度に大量の利用者が発生するシステムなどはRedisを使うことでレスポンスの向上に役立てています。

#### 保存可能なデータ構造
Redisは文字列の他にリスト、セット、ハッシュなどのデータ構造が用意されています。
リレーショナルデータベースで同じデータ構造を格納しようとした場合は、
- シリアライズして格納する
- キーバリューで格納できるテーブルを用意して、複数レコードに格納する

などの対応が必要となります。

## 今回の例における判断
本来はパフォーマンスについて考えるためにどのくらい集中アクセスが来るか等の条件が必要ですが、それよりも下記が重要であるため今回は割愛します。
今回の仕組みの場合、退避してからWebhookのリクエストが届くまでに、入力内容が消えてしまうことが大きな問題となります。
そのため、データの永続化が求められており、リレーショナルデータベースへを選択するほうが好ましいと考えます。

## 判断を行うために必要な情報
今回の内容を経て、リレーショナルデータベースとRedisのどちらを使うべきかを判断するために以下の情報が必要だと感じましたので最後に記します。

- データは消えても問題ないか
- データの整合性がどのくらい求められているか
- 保存するデータの構造
- 保存するデータのサイズ
- データにアクセスする頻度
- 利用者の数
- スケーリングを行うか
ISTQB Foundation Level合格までの道のり【Qiita初投稿】

## 目次
[1. 背景と自己紹介](#1-背景と自己紹介)
[2. 資格取得後の正直なメリット・デメリット](#2-資格取得後の正直なメリット・デメリット)
[3. 学習方法](#3-学習方法)
[4. 最後に](#4-最後に)

## 1. 背景と自己紹介
Q. 受験の背景
A. QAエンジニアとして働き始めて1年半が経過し、基礎を固めたいと思ったため。

Q. なぜJSTQBではなく、ISTQB?
A. 英語の学習にもなるので。

Q. 合格までの期間は?
A. 1日2~3時間を1ヶ月ほどでした。

Q. Qiita初投稿の経緯は？
A. 実はこの資格を取得した直後にQAエンジニアからコンサルに転職しまして。現在もIT関連の業務内容なんですが、せっかく取得したので共有したいなと。。。

**[LinkedIn](https://www.linkedin.com/in/tatsuya-fujisaki/)もやってるので、ぜひ繋がり申請だったり、メッセージください!!!🙌**

## 2. 資格取得後の正直なメリット・デメリット
取得した個人的な感想にはなりますが、最初に記載しておこうかなと( ͡° ͜ʖ ͡°)

**メリット**
- 言わずもがな、資格証明にはなりますね。転職の歓迎条件にISTQB(JSTQB)があった際の。
- Foundation LevelはQAエンジニアとして業務を開始した方、またはQAポジションに転職を考えている方にとってはプラスかなという印象です。テストの目的、一連の流れ、テスト手法の種類などを網羅的に知れるのは良いですね。

**デメリット**
- 上記の内容とは反対に、既にテスト設計や一連の流れを経験している方にとっては不要かなと感じました。
- ISTQBは約220$(3万3千円)ほど掛かるため、価格に見合った価値を見出せるかですね。(自分の場合は違うポジションに移ったため微妙です)

## 3. 学習方法
使用したのは主に2つです。以下2つを[Notion](https://copper-lynx-062.notion.site/ISTQB-2c1a938289b44fa9869afcb5a0944bee)に自分用メモとしてまとめて公開してるので、ぜひ参照してみて下さい。
1. [公式シラバス](https://www.istqb.org/certifications/certified-tester-foundation-level)
2. [(Udemy) ISTQB Foundation Level preparation course+1000quiz examples](https://www.udemy.com/course/istqb-foundation-level-ctfl-certification/) 
(自分が買った時はセールで1500円でした)

シラバスでのインプットをベースにしつつ、Udemyを使って問題を解いていくという進め方でした。

## 4. 最後に
今後はテスト手法も変化しつつ、それでもQAの需要は増していくのでは？と個人的には思っているため、この記事が誰かの参考になれたら幸いです。

現在の自分はAWS環境での開発に携わっているため、AWS Certified Solutions Architect - Associateの資格取得に向けて学習中です。それではまた、どこかで。
`revert`がわからなかった件

## はじめに
今回は、後から言われればすごく簡単なことなのに、なぜか長い時間悩んだこと`revert`についてお話します。

## 経緯
- 課題をGit hubから1回目の提出`Create pull request`を押す
- 仕組みをさっぱり分かっておらず`Merge pull request`と`Confirm merge`を押す
- 修正するよう返信が来たので、コードを修正して、再度`git add`から`git push ～`までをおこなっていたがGit hub上では修正されたものが出ていない？？
- 相談すると`revert`するよう指示がでた

・・・さぁ、問題の`revert`が出てきました。

## revertとは何？
- 既存のコミットを取り消すためのコマンド
- 「取り消したいコミットを打ち消すようなコミットを新しく作成する」という処理によって、既存のコミットを取り消します
- 日本語訳は「〔元の習慣・状態などに〕立ち戻る」
- 既存コミットの履歴は消えず、新たにコミットを追加
- どんな変更があったか、という事は残り、リモートにpushされて公開されているコミットに対しても安全に使うことが可能

コマンドを使った操作は以下の記事で詳しく解説されていました。

https://qiita.com/chihiro/items/2fa827d0eac98109e7ee

## こういう流れで解決できた
なんとGit hubの`Create pull request`を押した後の画面に`revert`というボタンがありました！！
私自身ボタンの存在がどこか全く分からず「`revert`？何それ？」状態でした。

- まずは修正したコードを改めて`git add .`から`git push～`まで行う
- 次に`revert`ボタンをおし、上のプルダウンの「Branches」を「revert-1-develop」から「develop」に選択しなおす
※ここで、つい先ほど`git commit`で名前を付けたコメント名のものがちゃんとcommitされていることがわかる
- 改めて`Create pull request`だけおす

**ここまでで提出は終了！あとは合否判定待つだけ！勝手にMergeしない**

## さいごに
まちがえてMergeまでしてしまったときはrevertで戻すことができる…今回の失敗から学べてよかった。

## 参考
他のよさそうな記事も挙げておきたいと思います。

https://phoeducation.work/entry/20210913/1631487480

https://qiita.com/kuuuuumiiiii/items/42d2d9ed11e3b29c22cf

https://qiita.com/aipacommander/items/d61d21988a36a4d0e58b
RVCとVCClientで始める！AIボイチェン超速入門

# ボイチェンを始めたい方向け

つい先日ボイチェンに入門したので方法をまとめます。
ボイチェンにとても詳しい方々の監修の元書きましたので、2024年7月5日現在のベストな方法だと思います。
ボイチェン通話を楽しんでいきましょう～！！

## 追記

この記事は、VCClient Ver1 安定版の インストール方法を解説したものです。
軽さや遅延の短さを重視する方は、アルファ版である VCllient Ver2で、Beatriceを使うのがおすすめです。

## 前提条件
- NVIDIAのグラフィックボードを利用している
- Windowsを利用している

## 手順

### 1. CUDAをインストール
CUDAは、NVIDIAのGPUを使って高速な計算をするためのソフトウェアです。

#### Windowsのみを利用している人
以下のリンクからCUDAをダウンロードしてインストールします。

https://developer.nvidia.com/cuda-downloads

#### 普段WSLを利用している人
以下のリンクを参照してCUDAをインストールします。

https://learn.microsoft.com/ja-jp/windows/ai/directml/gpu-cuda-in-wsl

インストールが終わったら、コマンドプロンプトを開いて以下のコマンドを入力し、インストールが成功したか確認します。
```
nvcc --version
```

### 2. VCClientをインストール
VCClient は、声をリアルタイムで変えるためのソフトウェアです。以下のリンクからVCClientをダウンロードします。

https://huggingface.co/wok000/vcclient000/tree/main

`MMVCServerSIO_win_onnxgpu-cuda_v.1.5.3.18a.zip` をダウンロードします。今回は1.5.3.18aを利用していますが、安定版ならどれでもOKです

ここで重要なことは、ダウンロード先の相対パス名（つまり、フォルダ名や親フォルダ名）にスペースや特殊文字が入っていないことです。スペースや特殊文字が入っていると正常に動作しません。
Cドライブ直下などに、RVC専用のフォルダを英数字のみの名前で作成して、VCClientを置いておくと安心です。

### 3. インストールしたzipファイルを解凍
ダウンロードしたzipファイルを解凍します。ファイルを右クリックして「すべて展開」を選択し、適切なフォルダに解凍します。解凍後、`MMVCServerSIO_win_onnxgpu-cuda_v.1.5.3.18a`というフォルダができるはずです。
Windowsでは、解凍を行わなくてもフォルダの中身が見えますが、ファイルが実行できないので、必ず、解凍を行いましょう。

### 4. 仮想ケーブルをダウンロードする
仮想ケーブル（Virtual Audio Cable）は、コンピュータ内で音声をやり取りするための仮想的なオーディオデバイスです。以下のリンクからダウンロードしてインストールします。

https://vb-audio.com/Cable/

すでに類似のアプリをインストールしている場合は、改めてインストールする必要はありません。

### 5. VCClientを実行する
解凍したフォルダ内の `MMVCServerSIO_win_onnxgpu-cuda_v.1.5.3.18a\MMVCServerSIO\start_http.bat` をダブルクリックして実行します。自動的にコマンドプロンプトが開き、実行が始まります。少し待つとVCClientのウィンドウが立ち上がります。

### 6. ffmpegをインストールする（必要な場合）
VCClientが正常に動作しない場合、ffmpegというソフトウェアをインストールする必要があります。ffmpegは音声や動画を変換するためのツールです。

以下のリンクからffmpegをダウンロードします。

https://www.ffmpeg.org/download.html

ダウンロードした後、ffmpegのbinフォルダのパスをWindowsの環境変数に追加します。以下の手順で行います
1. デスクトップでWindowsボタンとSを同時に押し、検索窓に「環境変数」と入力します
2. 「システム環境変数の編集」を選択します
3. 「環境変数」をクリックします
4. 「システム環境変数」の中の「Path」を選択して「編集」をクリックします
5. 「新規」をクリックして、ダウンロードしたffmpegのbinフォルダのパスを貼り付けます

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237066/5887a838-dec4-18d8-b5ff-531ecd6900e7.png)

コマンドプロンプトを開いて以下のコマンドを入力し、パスが無事に通ったかを確認します。

```
ffmpeg
```

### 7. VCClientの設定を行う
`MMVCServerSIO_win_onnxgpu-cuda_v.1.5.3.18a\MMVCServerSIO\start_http.bat`をダブルクリックしてVCClientを起動します。お好きなキャラクターを選択しましょう。右上の「開始」ボタンを押すとボイスチェンジャー機能が開始します。
出力デバイスは `CABLE Input(VB-Audio Virtual Cable)` に設定します。さらに「モニター」項目を自分のヘッドフォンに設定すると、ボイチェンのかかった自分の声をリアルタイムで聴くことができます。

### 8. 通話アプリの設定を変更する
使用している通話アプリ（例：DiscordやZoomなど）の設定を開き、入力デバイスを `CABLE Output(VB-Audio Virtual Cable)` に変更します。出力デバイスはそのままで問題ありません。

## 完成!!
これでボイチェン通話が可能になります。AI技術は日進月歩の世界ですが、この方法でしばらくは問題なく使用できると思います。お疲れさまでした！！！✨✨✨


## 宣伝

VCClient初回起動時にダウンロードされるプリセットモデルは汎用的なもので、より自分の声質にあったリアルでハイレベルなモデルも、GPUさえあれば個人で作成可能と聞きます。AIボイチェン沼へ足を踏み入れたい方はどうぞこちらへいらしてください。

https://discord.com/invite/bmNezxjCq2
Qiita記事投稿時のテンプレート(プログラミング時の技術課題を解決する記事)

# はじめに

私が技術記事のQiita投稿を行う際に使用している、プログラミング時の技術課題を解決する記事のテンプレートを紹介します。プログラミング時の技術課題を解決する記事を投稿される方の参考になれば幸いです。

### 本記事の参考文献

本記事は以下情報を参考にして執筆しました。

https://qiita.com/Qiita/items/c686397e4a0f4f11683d

https://qiita.com/daisuke0715/items/a3ebf9e28e2aa9c72628

# 以下Qiita記事投稿時のテンプレート

<pre>

# はじめに

--本記事を投稿しようと考えた背景・経緯を記載

#### 開発環境
--使用したOSやプログラミング言語、使用したパッケージ名とバージョンなどの情報を詳細に記載することで、読者が同様の開発環境で再現できます。

# 技術課題にはまって失敗した旨のタイトル(例：「～～なErrorが発生する」「～～で動作が停止する」など)

:::note warn
Sampleプログラムを実行する上での注意点
--Sampleプログラムを実行すると、どのような挙動になるかを記載
-プログラムが停止する、画面がフリーズするなどの挙動の場合、復旧方法も記載
:::


```FailureSample.py:

技術課題にはまって実行に失敗した際のSampleプログラムの記載

```

--Sampleプログラムの説明や技術課題の詳細説明を記載することで、読者が同様の技術課題に遭遇した際の参考になります。


# 技術課題を解決した旨のタイトル


```SuccessSample.py:

技術課題を解決した際のSampleプログラムの記載

```
-- 技術課題を解決した詳細説明を記載することで、読者が技術課題を解決するための参考になります。


# 参考文献
本記事は以下情報を参考にして執筆しました。

--参考にした記事を掲載(URLなど)

</pre>

# はじめに

--本記事を投稿しようと考えた背景・経緯を記載

#### 開発環境
--使用したOSやプログラミング言語、使用したパッケージ名とバージョンなどの情報を詳細に記載することで、読者が同様の開発環境で再現できます。

# 技術課題にはまって失敗した旨のタイトル(例：「～～なErrorが発生する」「～～で動作が停止する」など)

:::note warn
Sampleプログラムを実行する上での注意点
--Sampleプログラムを実行すると、どのような挙動になるかを記載
-プログラムが停止する、画面がフリーズするなどの挙動の場合、復旧方法も記載
:::


```FailureSample.py:

技術課題にはまって実行に失敗した際のSampleプログラムの記載

```

--Sampleプログラムの説明や技術課題の詳細説明を記載することで、読者が同様の技術課題に遭遇した際の参考になります。


# 技術課題を解決した旨のタイトル


```SuccessSample.py:

技術課題を解決した際のSampleプログラムの記載

```
-- 技術課題を解決した詳細説明を記載することで、読者が技術課題を解決するための参考になります。


# 参考文献
本記事は以下情報を参考にして執筆しました。

--参考にした記事を掲載(URLなど)
C_TS452_2021 - SAP Certified Application Associate - SAP S/4HANA Sourcing and Procurement対策（1/100）

MM領域（在庫・購買管理）の出題が予想される過去問を紹介いたします。
試験概要は下記のリンクに掲載されています。

【試験概要】
https://training.sap.com/certification/c_ts452_2021-sap-certified-associate---sap-s4hana-sourcing-and-procurement-g/

【1日目】
トピック1：企業構造とマスタデータ（1/11）

≪問題1≫
生産計画および原価積上を会社に導入する予定です。在庫評価に選択する必要がある組織レベルはどれですか。
□会社コード
□プラント
□管理領域
□事業領域

≪解答≫
□会社コード
■プラント
□管理領域
□事業領域

≪解説≫
◆評価エリアは品目が評価される組織レベルのことで、カスタマイジングで評価エリアを会社コードまたはプラントレベルのどちらで設定するかを指定することができます。この指定はクライアント全体に適用されます。本稼働システムでは、プラントと会社コードとの間で評価エリアを切り替えることはできません。
◆生産計画と実際の生産はプラントごとに実行されます。
◆原価積上はプラント共通ベースで実行可能です。
Randomとusing Systemの衝突を回避する方法

## 0.0 はじめに
Randam.RangeなどのRandamクラスを使用している状態でusing Systemを追加するとRandom使用箇所にエラーがでます。
これは最初から導入されているUnityEngineとSystemの名前空間（usingにある）のどちらにもRandomクラスが存在するためです。

## 1.0 対処方法
Randomの前にUnityEngine.を付けます

```C# Test.cs
using UnityEngine;
usgin System;

UnityEngine.Random.Range(0, 5);

```
AWS  EC2

# はじめに
AmazonEC2とはAmazon Elastic Compute Cloudの略で
AWSが提供する「仮想サーバサービス」です。
Amazon EC2を利用することで、従来のような物理サーバの構築や環境作業をすることなく、手軽に仮想サーバを用意することができます。
# Amazon EC2の機能
Amazon EC2を利用する上での代表的な機能は以下の通りです。
* インスタンス
* Amzon マシンイメージ(AMI)
* インスタンスのタイプ
* Amazon EBS ボリューム
* インスタンスストアボリューム
* キーペア
* セキュリティグループ

## インスタンス
インスタンスとは、AWS上で稼働する仮想サーバのことをさし、仮想サーバを数える際の単位としても使われます。AWSでは仮想サーバのCPUやメモリなどの組み合わせがインスタンスタイプとして定義されています。必要なスペックに応じたインスタンスタイプを選択し、OS、ストレージ容量などを決定してインスタンスを作成します。また、インスタンスの負荷状況に応じて自動的にインスタンスをスケールアウト(台数増)/イン(台数減)することが可能なオーケストリングなど、用途に合わせた柔軟な運用が可能です。
## Amazonマシンイメージ(AMI)
サーバに必要なコンポーネントをパッケージ化した、インスタンス用に事前に設定されているテンプレート(オペレーティングシステム及び追加のソフトウェアを含む)
## インスタンスのタイプ
インスタンス用のCPU、メモリ、ストレージ、ネットワーキングキャパシティーの様々な設定。
## Amazon EBSボリューム
Amazon Elastic Block Store(Amazon EBS)を使用したデータ用の永続的ストレージボリューム。
## インスタンスストアボリューム
インスタンスを停止、休止、または終了するときに削除される一時データ用のストレージボリューム。
## キーペア
インスタンス用の安全なログイン情報。AWSはパブリックキー、ユーザーはプライベートキーを安全な場所に保存します。
## セキュリティグループ
インスタンスに到達できるプロトコル、ポート、送信元IPの範囲、及びインスタンスが接続できる宛先IPの範囲を指定できる仮想ファイアウォール。

# Amazon EC2利用のメリット
Amazon EC2を利用するメリットを4つ紹介します。

## サーバの構築や運用にかかる時間を削減
Amazon EC2の最大のメリットと言えるのが、サーバ構築にかかる時間を削減できる点です。数分でサーバを起動することができるので、物理サーバと比べ大幅な時間短縮が可能となります。
また物理的なサーバの場合、物理サーバを含めたインフラの保守・運用に当たる人的リソースも必要になりますが、Amazon EC2のような仮想サーバを利用することで、こういったインフラ設備の運用に関する負荷も削減できます。
# 状況に合わせたスペック変更ができる
2つ目の利点は、利用状況に合わせて、サーバのCPU、メモリ、ハードディスクの容量などのスペックを容易に変更可能な点です。繁忙期や日中夜間で利用状況に差があるときに、サーバの負担が変化する時期や時間帯に合わせてスペックを増減させることが可能です。
状況に合わせた柔軟なスペック変更により、限られた予算の中でリソースを無駄なく活用できます。
## 従量課金制により費用を抑制
物理サーバや定額制のホスティングサービスの場合、アクセス数やデータ量を想定し必要以上のスペックで準備することが一般的です。Amazon EC2では、クラウドサービスでよくみられる従量課金制を採用しており、繁忙期や閑散期などデータ転送量に差がある場合でも、使用した分の費用しかかかりません。ただし、予期しない急激なトラフィック増加の際には、増加した分のデータ転送量に応じて費用が発生するため注意が必要です。
## 簡単に仮想サーバの冗長化が可能
商用環境で利用されるサーバでは、万が一の障害でシステムが停止することがないように複数のサーバ、いわゆる冗長化構成にて設計することが一般的です。
オンプレミスでサーバを冗長化する場合、サーバ本体だけでなく周辺のネットワークも冗長化する必要があるため、ネットワーク機器も冗長化を前提として調達・設計する必要があります。
# 参考元、引用元
* https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/concepts.html
* https://is.gd/iwqe0e
俺の考える最強のスクラム

# スクラム開発とは
専門用語がたくさん登場するので良く理解せずになんとなくチーム開発の一種くらいにしか思ってない人も多そう。
アジャイルの開発手法の一種です。今の開発の主流になってきています。

# 一般的なスクラム
## 役割
スクラム開発の登場人物です
名前|役割の詳細
---|---
PO（プロダクトオーナー）|スクラムの成果物に対するあらゆる責任を負う人。スクラムから外に出ていくときはこの人の承認が必須。偉い人。
SM（スクラムマスター）|開発進捗など現場の監督責任者。開発リーダみたいな役職の人がやってることが多いけど厳密には開発リーダではない。スクラムの運営責任者という位置づけ。
ステークホルダー|成果物の恩恵を受ける人たち。管理画面の開発ならそのユーザである運用チーム。C向けサービスの開発ならアプリユーザ。自社サービスでないなど明確な出資者がいる場合は出資者を指すこともある。

## スプリント
スクラム開発の単位。スクラムでは工数や日数、時間数のような単位では数えず、スプリントという周期を用いて開発サイクルを数える。
1スプリントの時間数はプロダクトによって様々で、1週間のところもあれば2週間のところもあれば1ヶ月のところもある。
主観による週数とその効果は以下
週数|効果
---|---
1週間|短すぎて成果物として何も出来上がらないままスプリントが終わる。開発の実態に合わせた週数ではなく働く感覚に合わせた週数でしかない。やめた方がいい。
2週間|1週間よりはマシで小さい機能なら完成可能な範囲。しかし時間が足りずに次のスプリントに持ち越すこともしばしば。1ヶ月の半分に一見見えるが実際は1ヶ月は4週間以上あるので徐々にズレていくしキリが良さそうなのはまやかし。
3週間|大体の機能が完成まで持っていける。有給や祝日で2日くらい潰れても余裕を持てる。個人的には一番のおすすめ。
4週間|長すぎる。スプリントの最初の週のことなんか覚えてなくなってしまう。ダメ。

## スクラムイベント
イベントという名の主にMTG
名前|イベント詳細
---|---
スプリントプランニング|このスプリントでやることと成果物を決める。プランニングポーカーをしてストーリーポイントの見積もりをしたりする。プランニングの準備としてステークホルダーから開発項目を収集しておき、PO承認のもとで開発優先度を付けて優先度が高いものから開発していく。大事なのは「やること」だけで終わらないこと。「成果」としてスプリントが終わる頃にどうなっていなければならないのかまで決めること。
デイリースクラム|チームによって朝だったり夕方だったりする。1日単位で開発進捗をチームで共有する会。見積もりよりも長くかかってしまいそうなので上位開発者へヘルプを出したり、差し込みタスクの確認などを行う。最終成果物の変更はしないのでPOは不在でOK。
レトロスペクティブ|スプリントの終了日付近で行う。KPTなどの手法を用いて今回のスプリントの振り返りを行うこと。スクラム自体が成長させていくものなのでそのためのイベント。
スプリントレビュー|プロダクトオーナーやステークホルダーに対して今回のスプリントの成果物をお披露目する会。スプリントの間隔が短すぎるとお披露目するものがなくなる。ここで出た意見などは次回以降のスプリントのタスクに積まれていく。

# 経験から考える最強のスクラム周期
私がいろんな場所でスクラム開発をしてきた中で、こういう周期で進めるのが一番開発効率が高まるのではないかと思っている形が以下です。
項目|値
---|---
スプリント間隔|3週間
スプリント曜日|火〜月 or 水〜火
プランニング|開始日の午前中に各自で自由にタスク積み上げ。開始日午後イチで積まれたタスクに関しての認識合わせとポーカー。
デイリースクラム|毎日昼過ぎ。朝だと昨日やったことを思い出して報告する形になって漏れやすい。その日に少し作業に入ってからやった方が有意義になる。
レトロスペクティブ|KPTボードは期間中ずっとOPENにしておいて、スプリントの期間中、気がついたタイミングで適宜書いてもらう。終了日に時間をとっていっぺんに書こうとするとだいたい漏れるし意味ない。期間中に書いておいたものをまとめて最終日に30分くらいのMTGで振り返る。
スプリントレビュー|成果物を画面共有等で見せながらその場でフィードバックをもらう。フィードバックの内容はすぐにチケット化するのを忘れない。
PDF翻訳ツール「Doclingo」

　私たちはよくさまざまな種類のファイルを扱う必要がありますが、その中でも最も一般的なのがPDF文書です。しかしながら、外国語のPDF文書に遭遇すると、通訳費用が高すぎて困ることがあります。しかし、今、よいニュースがあります！PDF翻訳ツール「Doclingo」を見つけました！このツールはPDFファイルを素早く翻訳するだけでなく、元の形式を完全に保持することができます。手動でのコピー＆ペーストの手間から解放されます。仕事の契約書、学習ノート、旅行中の観光案内など、数ステップで必要な言語に簡単に翻訳できます。この驚くべき無料PDF翻訳ツールを一緒に見ましょう！
 
![20240701165955.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3825442/fe3b5f8f-019b-f1b5-a572-c98f24dccfbb.png)

## PDF翻訳は無料です
　このツールは無料の翻訳サービスを提供して、ユーザーは無料でPDFファイルをアップロードし、目標言語を選択して翻訳することができます。この製品は先進的なAI翻訳技術とアルゴリズムを使用し、PDFファイルの内容を迅速かつ正確に翻訳できます。また、このツールにはテキスト認識や元の書式を保持するなどの高度な機能も提供されており、ユーザーの個別のニーズに応えています。総括すると、このツールは無料でありながら機能が強力なPDF翻訳ツールであり、使いやすく効率的な翻訳体験を提供しています。

## PDF翻訳の具体的な手順
　このツールを使用してPDFを翻訳する具体的な手順は以下の通りです：まず、このツールを開き、「PDF翻訳」機能を選択します。次に、「ファイルを選択」ボタンをクリックし、翻訳したいPDFファイルを選択してアップロードします。その後、ソース言語と目標言語を選択します。例えば、英語から日本語への翻訳です。そして、「翻訳を開始」ボタンをクリックし、システムが自動的に翻訳処理を行います。しばらく待つと、翻訳結果がページに表示されます。ユーザーは翻訳されたPDFファイルをダウンロードしたり、翻訳されたテキストをコピーしたりすることができます。これらの手順を踏むことで、ユーザーは無料でこのツールを使用してPDFを簡単に翻訳できます。
　ユーザーは翻訳したいPDF文書をアップロードし、目標言語を選択するだけで、高品質な翻訳結果を迅速に得ることができます。このウェブサイトはビジネス、技術、医学など、広範な分野で一般的な言語の翻訳をサポートしています。さらに、このツールは使いやすく、操作が簡単で、翻訳速度が速く、翻訳結果が正確で信頼性があります。個人ユーザーも企業も、このツールを使用して簡単にPDFファイルの言語を変換することができます。

　以上のように、このツールは強力で実用的なツールであり、ユーザーに便利で効率的なPDF翻訳サービスを提供します。[doclingo.ai](https://www.doclingo.ai/ja/)
Azure Data Factory メタデータ駆動コピータスクにてSalesforce のデータセットを選択できない事象への対応方法

## 概要

Azure Data Factory メタデータ駆動コピータスクにてSalesforce のデータセットを選択できない事象への対応方法を共有します。 2024年7月5日時点では、`接続の種類`が`すべて`の場合に`新しい接続`から`Salesforce`コネクタを選択できず、ソースの種類を`Salesforce`にしても既存のデータセットを選択できません。とりあえず、新規のデータセットを作成後にデータセットを切り替える暫定対応方法を共有します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/88d9f33e-bb90-76e8-418f-327b15656ac9.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/572222e6-b196-ddea-3afc-82cd184710b2.png)

## 手順

### 1.  `ソースの種類`を`Salesforce`に設定し`新しい接続`を選択

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/9333495c-9fbc-7841-95d6-20dc11c7b31e.png)

### 2. 暫定のリンクサービスを作成

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/648c5193-0738-fab0-09ae-1829e5b21255.png)

### 3. 連携対象のオブジェクトを選択しメタデータ駆動コピータスクの作成完了まで進める

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/d780002e-b2a5-4652-b9c3-eb453d7fbf18.png)

### 4. `MetadataDrivenCopyTask_xxx_BottomLevel`パイプラインの`FullLoadOneObject`アクティビティのデータセットを切り替えてオブジェクト API 名を渡すように修正

> @json(item().SourceObjectSettings).objectApiName

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/1e9dd11d-62f0-3ca6-44a1-ccce49b53ee8.png)

### 5. `MetadataDrivenCopyTask_xxx_BottomLevel`パイプラインの`DeltaLoadOneObject`アクティビティのデータセットを切り替えてオブジェクト API 名を渡すように修正

> @json(item().SourceObjectSettings).objectApiName

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/dadfdc50-b46a-6c08-ec64-70caae54e424.png)

### 6. `MetadataDrivenCopyTask_xxx_BottomLevel`パイプラインの`DefaultFullLoadOneObject`アクティビティのデータセットを切り替えてオブジェクト API 名を渡すように修正

> @json(item().SourceObjectSettings).objectApiName

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/a2d473ec-28a2-6e1f-16dd-06fa71bc2164.png)

### 7. `MetadataDrivenCopyTask_xxx_BottomLevel`パイプラインの`GetMaxWatermarkValue`アクティビティのデータセットを切り替えてオブジェクト API 名を渡すように修正

> @json(item().SourceObjectSettings).objectApiName

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/0df63be6-e75c-93f1-8b5f-094f3b8eec3b.png)


### 8. データセットにて暫定的に作成した`MetadataDrivenCopyTask_xxx_SourceDS`データセットを削除

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/a43129f0-e69d-7f78-8479-4c3c4c7f1be3.png)

### 9. リンクサービスにて暫定的に作成した`Salesforce__temp`リンクサービスを削除

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/a00ff471-3556-4c25-a054-cd85c3e29814.png)


## 動作確認

### 1. パイプラインを実行して正常終了することを確認

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/5678ea65-eb1e-de95-080c-34b66555db3a.png)

### 2. データが連携されていることを確認

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/7e335e73-2288-e399-e75e-9d99ac9234c4.png)
【scrapy】Tor経由でクローリングを行う

# はじめに
onion service内のコンテンツに対してスクレイピングを行うためにTor経由でクロールを行った．

しかしscrapyではTorプロキシはサポートされていないため，今回はミドルウェアとしてPrivoxyを使用した．

また，クロール中にIPアドレスを変更したかったためscrapy-tor-proxy-rotationも使用した．

# 実行環境
Ubuntu 22.04 LTS

# 使用したツール
- Scrapy (ver 2.11.2)
- Tor (ver 0.4.6.10)
- Privoxy (ver 3.0.33)
- scrapy-tor-proxy-rotation (ver 0.0.4)

# インストール
```shell-session
$ pip install scrapy
$ sudo apt-get install tor
$ sudo apt install privoxy
$ pip install scrapy-tor-proxy-rotation
```

# Torの設定
一旦 Tor を停止させる
```shell-session
$ sudo service tor stop
```

そしたら ```/etc/tor/torrc``` を開き，以下の行を追加する
```
ControlPort 9051
CookieAuthentication 0
```

最後に Tor を起動させる
```shell-session
$ sudo service tor start
```

# Privoxyの設定
一旦 Privoxy を停止させる
```shell-session
$ sudo service privoxy stop
```

そしたら ```/etc/privoxy/config``` を開き，以下の行を追加する
```
forward-socks5t / 127.0.0.1:9050
```

最後に Privoxy を起動させる
```shell-session
$ sudo service privoxy start
```

# Scrapyの構築
クローラーを作成したいディレクトリ内で以下のスクリプトを実行する（```"プロジェクト名"```の部分は任意の文字列を入力）
```shell-session
$ scrapy startproject "プロジェクト名"
```

そしたら ```"プロジェクト名"/"プロジェクト名"/settings.py``` を開き，以下の行を追加する
```python
DOWNLOADER_MIDDLEWARES = {
    ...,
    'scrapy.downloadermiddlewares.httpproxy.HttpProxyMiddleware': 110,
    'tor_ip_rotator.middlewares.TorProxyMiddleware': 100
}
TOR_IPROTATOR_ENABLED = True
TOR_IPROTATOR_CHANGE_AFTER = 5 #IPアドレスを変更する頻度
```

後は通常通り scrapy を構築すればよい

# 参考
https://pypi.org/project/scrapy-tor-proxy-rotation
Goの空の構造体

Goの特定のデータセットを扱える構造体で、A Tour of Goにも出てくる。

```go
package main

import "fmt"

type Vertex struct {
    X int
    Y int
}

func main() {
    fmt.Println(Vertex{1, 2})
}
```

この例ではX, Yをintとして持つVertexという構造体を定義している。

そんな構造体のフィールドを持たない空の構造体を使うこともある。

空の構造体の特徴と使う例をまとめる。

## 空の構造体

空の構造体は以下のようなものである。

```go
type emptyStruct struct{}

var emptyStructVar struct{}{}
```

再度の説明にはなってしまうが、空の構造体はフィールドを持たない構造体である。

フィールドを持たないため使い道がないじゃん？と思うかもしれないが、メモリを消費しない。

通常の構造体はフィールドを持つためその分のメモリを確保するが、空の構造体はフィールドがないためメモリを消費しないという動きになる。

## 使い方

メモリを消費しないことを利用して以下のような使い方がある。

### セット型の表現

Pythonなどには実装されているセットをGoで表現するときに使う。

```go
func main() {
    set := make(map[string]struct{})
    set["a"] = struct{}{}
    set["b"] = struct{}{}
    set["c"] = struct{}{}

    // check if a exists
    if _, ok := set["a"]; ok {
        fmt.Println("a exists")
    }

    fmt.Println(set)
}
```

mapのvalueにboolを入れると少なからずメモリを消費するが、空の構造体を入れることでメモリを消費しない。

これとmapの2つ目の返り値を使ってkeyが存在するかどうかを判定することができSetのように使うことができる。

### チャネルのクローズ

チャネルのシグナル送信の際にも使用可能。

Goのchanはint, stringなどの型を指定するが、空の構造体を指定することでメモリを消費しない。

```go
func main() {
    ch := make(chan struct{})

    go func() {
        time.Sleep(1 * time.Second)
        close(ch)
    }()

    <-ch
    fmt.Println("done")
}
```

## まとめ

空の構造体はフィールドを持たない構造体でメモリを消費しない。

値に意味を持たせずにメモリ消費を抑えることが可能になる。
これでもうスマホ画面でアドレスバーに隠れない！（vhとdvhを使いこなして解決しよう）

スマートフォンでWebサイトを閲覧する際、アドレスバーやナビゲーションバーが画面上部（safariだと下部）に表示され、せっかくのデザインやコンテンツが下の方に隠れてしまい「あ～～～」となったのでvh→dvhに変更したら解決した話。

そもそもあまり使い慣れてない「vh」。
そもそもそこまで出番のない「vh」。（失礼）
だったので理解を深めつつそれぞれの場面にあった適切な解決方法も記載していきます。
## Viewport Height（vh）とは？
vhはビューポートの高さを基準とする単位です。1vhはビューポート高さの1%を表します。たとえば、ビューポートの高さが800pxの場合、1vhは8pxになります。vhはレスポンシブデザインにおいてよく使用され、コンテナの高さをビューポートに応じて動的に変更するのに役立ちます。
またvhは、ビューポートの初期ロード時の高さに基づいて計算されますが、モバイルデバイスでのアドレスバーの表示・非表示によるビューポートの高さの変化は反映されません。
## Dynamic Viewport Height（dvh）とは？
dvhはCSSの標準単位ではありませんが、動的に変わるビューポートの高さに基づく単位です。1dvhは、ビューポートの動的な高さの1%を表します。dvhは、アドレスバーやナビゲーションバーを除いたブラウザウィンドウの「動的」な高さを100としたときの割合で要素の高さを指定する単位です。つまり、常に画面に表示されている領域の高さに合わせてコンテンツの高さを調整してくれるのです。
比較的新しい単位のため対応ブラウザが気になるかもしれませんが2022年時点で主要ブラウザChrome、Edge、Safari、Firefox）でサポート完了しているようです。やった～！
[CSSの新しい単位（lvh, svh, dvh)がすべてのブラウザでサポート、100vhがビューポートの高さいっぱいにならない問題を解決](https://coliss.com/articles/build-websites/operation/css/large-small-dynamic-viewport-sizes.html)
## 各単位の違い
vhはCSSで直接使用できるビューポートの高さに基づく単位であり、dvhはビューポートの高さの変化に動的に対応するためのJavaScriptを介したアプローチを指します。dvhは公式のCSS単位ではなく、特定のレイアウトの問題を解決するために開発者が独自に実装する概念です。
他にもsvh（Small Viewport Height）とlvh（Large Viewport Height）のようなdvhと同様に、アドレスバーやナビゲーションバーの影響を受けずに要素の高さを設定できるCSS単位もあります。

| 単位　 | 説明 | 用途 |
|:------------|:------------|:------------|
|vh　|ビューポートの静的な高さを基準とする単位|デスクトップやアドレスバーが固定されたブラウザ|
|dvh　|ビューポートの動的な高さを基準とする単位|スマホブラウザなど、アドレスバーが表示・非表示になる場合に有効|
|svh　|最小ビューポートの高さを基準とする単位|アドレスバーが表示された状態のスマホブラウザ|
|lvh　|最大ビューポートの高さを基準とする単位|アドレスバーが非表示になった状態のスマホブラウザ|

![image.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3625328/7eca7124-fe63-5af8-b5be-387dc43d4a81.jpeg)

lvhはデスクトップ向けに、svhはスマートフォン向けに最適化されており、それぞれ異なるビューポートにおけるコンテンツの見やすさを向上させることができます。

dvhは、スマートフォンやデスクトップのUIに合わせて要素の高さを自動的に調整してくれる便利なCSS単位です。従来のvhと異なり、アドレスバーやナビゲーションバーの影響を受けずに、常に画面に表示される領域の高さを基準としています。

ということでdvhめちゃ便利～～～～～～～～～:v_tone1:
Cartopy利用時のプロキシ認証について

## はじめに

pythonライブラリのCartopyの地図データはインストール時にはローカルに保存せず、利用する際にネット経由でダウンロードする。その際に標準ライブラリ`urllib.request`を利用する。  
ただしCartopyでプロキシ設定やSSLサーバ証明書の設定ができないという問題があり、外部の設定で行わなければならない。  
標準ライブラリ`urllib.request`のうちSSLに関係するものは標準ライブラリ`ssl`が関係し、`ssl`は`openssl`を使用している。


## プロキシ設定について

環境変数

- http_proxy=protocol://[user:passwd@]host:port
- https_proxy=protocol://[user:passwd@]host:port


## SSLサーバ証明書について

### pipの場合

こちらの`ca-certificates`の仕組みでSSLサーバ証明書を更新すると`openssl`でデフォルト利用している証明書が更新される。

https://qiita.com/Torahugu/items/6db2715753ade438170b#%E3%83%87%E3%82%A3%E3%82%B9%E3%83%88%E3%83%AA%E3%83%93%E3%83%A5%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%81%AEca%E8%A8%BC%E6%98%8E%E6%9B%B8%E3%81%AE%E8%BF%BD%E5%8A%A0

### anacondaの場合

```python
import ssl
ssl.get_default_verify_paths()
# DefaultVerifyPaths(
# cafile='/home/XXXX/miniconda3/envs/XXXX/ssl/cert.pem', 
# capath='/home/XXXX/miniconda3/envs/XXXX/ssl/certs',
# openssl_cafile_env='SSL_CERT_FILE',
# openssl_cafile='/home/XXXX/miniconda3/envs/XXXX/ssl/cert.pem',
# openssl_capath_env='SSL_CERT_DIR',
# openssl_capath='/home/XXXX/miniconda3/envs/XXXX/ssl/certs'
# )
```
で指定されているcafileやcapathにSSLサーバ証明書を更新するか、あるいは`ca-certificates`の仕組みで更新したcafileやcapathを環境変数SSL_CERT_FILE,SSL_CERT_DIRで指定するかのどちらかである。簡単な方は後者。

#### Ubuntu 22.04での環境変数

SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt
SSL_CERT_DIR=/etc/ssl/certs

#### CentOS Stream 9での環境変数

SSL_CERT_FILE=/etc/pki/tls/cert.pem
SSL_CERT_DIR=/etc/pki/tls/certs
42Tokyoの基礎課程(1st circle)を修了した話

# はじめに
この度、42Tokyoの基礎課程（1st circle）を修了したので、42Tokyoでの学びについて記事を書くことにしました。
大学3年生の5月に入学し、大学4年生の6月に修了しました。
これから入学試験を受ける方や、42Tokyoについて興味がある方の参考になればと思います。

# 42Tokyoとは
42Tokyoは学費完全無料、パリ発のエンジニア養成機関です。現在新宿に校舎があります。（2023年度まで六本木）
箇条書きですが以下のような特徴があります。詳細は公式ホームページを御覧ください。

- 特徴
    - 学費無料、経歴不問、24h開校
    - 4週間の入学試験
    - 教師なし、授業なしで生徒で教え合うピアラーニング
    - 個人やチームで課題を進めていく
    - お互いの課題をレビューし合う
    - C言語、C++をメインに基礎課程を学習し、その後は自由に勉強が可能
    - 基礎課程修了までは、退学期日が決まっており、課題を進めることで延命出来る
    - スポンサー企業や海外キャンパスとの交流
    - ※2024年度より基礎課程修了後にも期限付きの制度が導入

https://42tokyo.jp/


# 実際の42Tokyoとは
### 入学試験について
4週間の入学試験の内容について、詳細に述べることは禁止されているのであまり詳しいことは話せません...
ただ、最近ではいろんな記事がネット上に落ちているので、どんなことをするかは調べれば分かると思います。

個人的に入学試験合格に必要なことは、**時間**だと思います。
**4週間分**の予定を開けておくことが、合格への第一歩です。
この入学試験を受けるだけでも、とても良い経験になるのでぜひ検討してみてください。


### 本科での学習について
ホームページのこの文言を見て、試験を受けるのをためらっている人がいると思います。
個人的には、この文言は完全に無視して良いと思っています。
> 42 Tokyoキャンパスに通える方（35時間/週 程度通える方）




実際、私は1日も校舎に行っていない月が**5ヶ月くらい**あると思います。普段は大学生なので、基本的に**長期休み**と**土日**しか通っていませんでした。
また新校舎になってからは**3回**しか行っていないと思います。
それでもほとんど寄り道をせず、地道に課題を進めて、約1年1ヶ月で修了しました。（入学試験の同期の中ではおそらく１番？入学時期が同じ中でも3番くらい？）

ただ、全く何もやらなくて良いわけではなく、授業中や学校終わりに黙々と課題を進めていました。１人でも課題を進められる程度にドキュメントは整備されていますし、Discordを活用すれば、教えてくれる人も沢山います。

とはいっても、校舎に行かないとモチベーションは下がり、レビュー・イベントなどの42Tokyoならではの環境を最大限活用することは出来ません。
そのため、個人的には最低でも**週1,2**は校舎に通えることが望ましいと思います。
特に入学して最初の1ヶ月~3ヶ月くらいは周りに遅れを取らないように通えるのがベストです。

### おすすめできる人
個人的には学生におすすめです。ハッカソンや技術系のイベントでは42Tokyoのことを知ってくれている人が居たりします。また、インターンなどの面接でも話のネタになります。


- 大学生・専門学生
    - 文理問わず時間のある大学生におすすめです。プログラミングに興味さえあれば、やっていけます。高等教育で情報が必修になった今、学んでおいて損はないと思います。
    - 理系の学生には特におすすめです。情報系かどうかに関係なく、プログラミングを触る機会はあると思います。授業や研究においても役に立つスキルが身につきます。
    - 時間のある1,2年生のうちに入学試験を受けるのがおすすめです！


- 高校生
    - 現在18歳以上という制限だけありますが、若い人にこそおすすめします。

42Tokyoをきっかけに色々な繋がりが出来るので、エンジニア等との繋がりを増やしたい人にもおすすめです。

# 身についたこと
### 基本的なプログラミング能力
C言語で基本的な所から勉強するため、ベースとなるプログラミング能力がついたと思います。レビューやチーム課題などで、他の学生から綺麗なコードの書き方や、慣例なども学ぶことも出来ました。
１人で学習していると、自分のコードを見てもらったり、人にコードの解説をしてもらう機会は無いのでそこが42の利点だと思います。
また、C言語のコード規約があることで綺麗なコードを書くように心がけるようになりました。

### コードやドキュメントを読む力
レビューで他学生のコードを読んだり、manでコマンドを調べたり、課題に関係するドキュメントや参考になるコードを読んでるうちにコードやドキュメントを読むことに慣れてきます。
私は実際にインターンや研究で、他人のコードや、ドキュメントを読まなければならない機会が多くあるのですが、その際も苦ではなくなりました。

### 様々な業界や会社について学べたこと
最近では定期的にスポンサー企業様とのイベントや、会社説明会などを開催しています。
私はあまり多くは参加できていませんが、かなりの頻度で開催されているのでおすすめです。

### ガクチカ・業務経験
私はサークルなどに所属していないため42Tokyoがガクチカの1つになっています。
また、42で実力をつけた後、エンジニアの長期インターンも始めたため、**開発インターンの経験**もガクチカの1つになっています。
また、ハッカソンにも出場するようになりました。

私の場合、面接などでは42Tokyoよりもインターンの話のほうが深堀りされることが多い気がします。
42Tokyoに入ったことで満足するのではなく、入学することで刺激を受けて、その後何をしたかが大事だと思います。

### 大学の授業が楽になった
情報系の学部に通っているため、C言語やオブジェクト指向、ネットワーク、アルゴリズム、OSなどに関する授業がありました。
大学の授業では理論や研究ベースで学び、42では実装ベースで学ぶことが出来るため、両立することで学習効果が増したと思います。

# 最後に
私は、42Tokyoに入ってから、インターンやハッカソン、このような記事を書いたり等、色々なことを始めました。
大学生活の中でも、かなり大きなトピックの１つになっています。
誘ってくれた友達や、一緒に課題を進めてきた学生にとても感謝しています。
少しでも42Tokyoについて、興味を持っていただけたら嬉しいです。

最後まで読んでいただきありがとうございました。

# 補足
主に私が入学試験を受けてから新校舎に移転するまでの体験がメインに書かれています。
新校舎移転後、私はほとんど通っていないかつ、運営状況も変わっているので異なる点があるかもしれませんが、ご了承ください。

**個人的には42Tokyoだけではなく、大学、インターン、外部のハッカソンや個人開発などの活動と両立することが大事だと思います。**
AWSのメンテナンスサーバーを作る(メモ)

# メンテナンス用サーバを作ろう
コンソール操作をするのをなるべくセキュアにするために。

## EC2のインスタンスを作る
接続元を限定したセキュリティグループにする

## 設定ファイルいじる
```
ssh -i ~/.ssh/favy-maintenance.pem ubuntu@***.***.***.***
sudo su
vi /etc/ssh/sshd_config
```
```
...
#PermitRootLogin prohibit-password ←これコメントアウト(デフォルトでコメントアウトしてあるはず)
...
PubkeyAuthentication yes ←コメントインする
...
PasswordAuthentication no ←本来YesだけどNoに変更させてコメントイン
PermitEmptyPasswords no ←コメントイン
...
```

## 接続後ユーザー作成する
```
ubuntu@ip-***-***-***-***:~$ sudo adduser maintenance
```
コマンドうつと以下のような対話型が始まる
```
Adding user `maintenance' ...
Adding new group `maintenance' (1001) ...
Adding new user `maintenance' (1001) with group `maintenance' ...
Creating home directory `/home/maintenance' ...
Copying files from `/etc/skel' ...
New password:
Retype new password:
passwd: password updated successfully
Changing the user information for maintenance
Enter the new value, or press ENTER for the default
	Full Name []:
	Room Number []:
	Work Phone []:
	Home Phone []:
	Other []:
Is the information correct? [Y/n] Y
```
passwordは適当に作る。あとは空白でもOK。

## maintenance君の想定
ログインユーザー と 実際のコンソールコマンド運用するユーザーは別にしたほうがいい。
ログインユーザがバレたらなんでも出来ちゃえるから。
つまりｍaintenance君はコマンドをする担当。直接ログインはできないようにする

## 色々インストールする

### ruby install
```
sudo apt install ruby
sudo gem install bundler
```

### aws cli のインストール
https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html
```
mkdir ~/tmp; cd ~/tmp
curl "https://awscli.amazonaws.com/awscli-exe-linux-aarch64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
sudo mv aws /opt/
cd /opt/aws
sudo ./install
```
### session manager plugin のインストール
https://docs.aws.amazon.com/systems-manager/latest/userguide/session-manager-working-with-install-plugin.html
```
cd ~/tmp
curl "https://s3.amazonaws.com/session-manager-downloads/plugin/latest/ubuntu_arm64/session-manager-plugin.deb" -o "session-manager-plugin.deb"
sudo dpkg -i session-manager-plugin.deb
```
### ssh-ecs 関係ファイルの配置, bundle install

```
cd /opt
sudo mkdir -p ops-utils/sg-maintenance
cd ops-utils/sg-maintenance/
sudo vi Gemfile
sudo vi Gemfile.lock
sudo vi ssh-ecs
sudo chmod +x ssh-ecs
sudo bundle install
sudo ln -s /opt/ops-utils/sg-maintenance/ssh-ecs /usr/local/bin/
```

### IAMの作成

ecsいじれる系のIAMの調整
* e.g. ecs-exec-hogehoge を新規に作成
* 既存のIAMを参考に権限周りはコピー
    * aws:SourceIp 変える必要あり

### credentials の配置
ecs-exec-hogehoge の認証情報を発行。
```
vi ~/.aws/credentials
chmod 600 ~/.aws/credentials
```
### 実際のコンソール接続テスト
```
# メンテサーバに入る
ssh -i ~/.ssh/favy-maintenance.pem ubuntu@***.***.***.***
# メンテ君に切り替え
ubuntu@ip-***-***-***-***:~$ sudo su - maintenance

maintenance@ip-***-***-***-***:~$ ssh ~/.aws/credentials/*** root@***.***.***.***
```

1回メンテサーバに入って、maintenance君に切り替えて、そいつがcredentialsを使って入りたいサーバへ入る。
いわゆる踏み台サーバ的な感じでのログイン。
M5PoECAMの書き込み方法とGrove出力方法まとめ

M5PoECAM

公式ドキュメント
https://docs.m5stack.com/en/unit/M5PoECAM-W

書き込みに必要なkitは公式ドキュメントより
https://docs.m5stack.com/ja/accessory/esp32_downloader_kit

公式ショップサイドの画像を見たほうがどうしなければならないのかわかる
https://shop.m5stack.com/products/esp32-downloader-kit

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/345260/fb70baf7-9a80-64a2-fd7e-3d899af2f1be.png)

上記のコネクタははんだ付け必須なので注意する。


Grove端子から出力するための設定
```C++
void setup() {
    Serial1.begin(9600,SERIAL_8N1, 3, 1); 
    Serial2.begin(9600,SERIAL_8N1, 25, 33);
```
イメージ図
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/345260/e86ebff6-7789-9019-772a-db064a801a3f.png)

コーディング中であればSerial1でも構わないかもしれないが
かなり端子が緩くて外れやすいのでSerial2のGrove端子の活用を推奨します。
[Bash]コマンドを実行した時の結果を「日付付き」ファイル名に保存したい

# 完全に個人的な備忘録
Google先生とかChatGPTとか調べるのもいいんだけど「自分でやった」というアレを残したいがために、クソみたいな内容ですが個人的な備忘録として。。。

# 日ごとにログファイル分かれててほしくね？
Cronとかで日次で実行されるコマンドの実装結果を
「日付(yyyymmdd)_batchName.log」とかで保存するためのアレです。

```bash:適当.sh
#!/bin/bash
# dateコマンドの結果をログファイルに保存するだけの簡単なお仕事
date > /var/log/sampleBatch/$(date +%Y%m%d)_batchName.log
```

# ゴメンこれだけなんだ。。。
なんかもっとSHに関することを書けって感じですが、
取り急ぎでメモりたかっただけなので許してほしい。

ほら、こういうコマンドってよく使うけど、書き方って忘れるでしょ？
Python+poetry+fastAPIのDocker開発環境構築

# 前提条件
- Python 3.11.6
- Poetry 1.82

# フォルダ構成

大体`poetry new`で生成されるものを使用しました。
```
my_project/
├── .venv/
├── main/
│   └─ server.py
├── tests/
│   └─ テストファイルたち
├── Dockerfile
├── poetry.lock
├── pyproject.toml
├── README.md
├── .dockerignore
└── .pre-commit-config.yaml
```

testやpre-commitは今回の記事では触れません。

# ライブラリ追加

poetryで必要なライブラリをインストールしていきます。
必要なのは`fastapi`と`uvicorn`です。

```bash
poetry add fastapi uvicorn
```

# ファイル作成

## server.py

```server.py
from fastapi import FastAPI

server = FastAPI()

@server.get("/")
async def root():
    return {"message": "Hello World"}
```

よくある"Hello, World"を返すだけのやつです。

## .dockerignore

```.dockerignore
# git関連
.git
.gitignore

# 開発でしか使用しない
tests
.pre-commit-config.yaml
.vscode

# コンテナに含める必要はない
Dockerfile
.dockerignore

# ドキュメント
README.md

# 仮想環境
.venv

# キャッシュファイル
**/*/__pycache__

# このプロジェクトでは使用していない
**/*/__init__.py
```

コンテナに含める必要のないファイルを指定します。

## Dockerfile

```Dockerfile
# builderとrunnerで使うベースイメージを決めています
FROM python:3.11.9-slim-bullseye AS base

# baseをbuilderステージで使用
FROM base AS builder

RUN pip install poetry

WORKDIR /app

# 作業ディレクトリにpyproject.tomlとpoetry.lockをコピー
COPY pyproject.toml poetry.lock ./

# poetryの仮想環境を作らないように指定、依存関係のインストールを行う
# --no-devを付けることで、開発にしか使用しないパッケージを除いてインストールする
RUN poetry config virtualenvs.create false \
    && poetry install --no-dev

# プロジェクトのコードをコピー
# COPY main ./　とすると失敗します。理由がわかる方教えてください。
COPY . ./

# baseをrunnerステージで使用
FROM base AS runner 
WORKDIR /app

# システムグループを作成
RUN addgroup --system --gid 1001 python

# システムユーザーを作成
RUN adduser --system --uid 1001 api

# builderステージから/appディレクトリ全体をrunnerステージにコピー
COPY --from=builder /app /app

# builderステージからPythonのサイトパッケージディレクトリをrunnerステージにコピー
COPY --from=builder /usr/local/lib/python3.11/site-packages /usr/local/lib/python3.11/site-packages

# builderステージから/usr/local/binディレクトリをrunnerステージにコピー
COPY --from=builder /usr/local/bin /usr/local/bin

# ユーザーをapiに設定
USER api

# コンテナの8080番ポートを開ける
EXPOSE 8080

# poetryを使ってuvicornを実行し、APIサーバーの起動を行っている
CMD ["poetry", "run", "uvicorn", "main.server:server", "--host", "0.0.0.0", "--port", "8080"]
```

マルチステージビルドを採用することで最終的なイメージのサイズを小さくしています。
また、一般ユーザー(api)にユーザー切り替えすることで、コンテナがroot権限で実行されないようにしています。


#　docker runまで

Dockerfileがあるディレクトリからターミナルを操作する想定です。

```bash
# name=任意の名前
# tag=任意のタグ
docker build -t name:tag .
```

最後のコロンはDockerfileに位置を指定しているものです。

docker runを実行します。
```bash
docker run -it -p 8080:8080 name:tag
> Creating virtualenv chroma-key-api-9TtSrW0h-py3.11 in /home/api/.cache/pypoetry/virtualenvs
> INFO:     Started server process [1]
> INFO:     Waiting for application startup.
> INFO:     Application startup complete.
> INFO:     Uvicorn running on http://0.0.0.0:8080 (Press CTRL+C to quit)
```

これで`http://0.0.0.0:8080`に接続できれば成功です。
C#でPDFをJPG/ PNG画像に変換する

PDFファイルと比較して、画像ファイルは、特にソーシャルメディアプラットフォーム上で共有しやすく、より幅広いデバイスと互換性があります。これらの要因により、PDFから画像への変換は、今日のデジタル時代においてニーズが高まっています。
**C#でPDFをJPGやPNGのような画像形式に変換する**信頼性の高い効率的な方法をお探しなら、[**Spire.PDF for .NET**](https://www.e-iceblue.com/Introduce/pdf-for-net-introduce.html)ライブラリが正しい選択です。この記事では、この.NET PDFライブラリを使用してタスクを達成する方法を詳しく説明します。

## PDFを画像に変換する.NETライブラリ
[Spire.PDF](https://www.e-iceblue.com/Introduce/pdf-for-net-introduce.html)ライブラリは、C#、VB.NET、ASP.NET、.NET CoreでPDFファイルの作成、読み込み、書き込み、変換、印刷を含む幅広いPDF処理機能をサポートしています。
以下のリンクからダウンロードするか、[**Nuget**](http://www.nuget.org/packages/Spire.PDF/)経由でインストールしてください。

https://www.e-iceblue.com/Download/download-pdf-for-net-now.html



## PDFから画像への変換手順
1.	必要な名前空間をインポートする。
2.	PDFファイルを読み込みます。
3.	PDFページを画像に変換し、**`PdfDocument.SaveAsImage (int pageIndex, PdfImageType type, int dpiX, int dpiY)`** メソッドを使用して画像のDpiを設定します。
4.	画像を任意の画像形式（PNG、JPG、BMP、EMFなど）に保存します。

## PDFをJPG、PNG画像に変換するC#コード
```c#
using Spire.Pdf;
using Spire.Pdf.Graphics;
using System;
using System.Drawing;
using System.Drawing.Imaging;

namespace PDFtoImage
{
    class Program
    {
        static void Main(string[] args)
        {
            //サンプルPDF文書を読み込む
            PdfDocument pdf = new PdfDocument();
            pdf.LoadFromFile("新聞.pdf");

            //PDFの各ページをループする
            for (int i = 0; i < pdf.Pages.Count; i++)
            {
                //すべてのページを画像に変換し、画像のDpiを設定する。
                Image image = pdf.SaveAsImage(i, PdfImageType.Bitmap, 500, 500);

                //画像をPNG形式で指定フォルダに保存 
                string file = string.Format("Image\\ToImage-{0}.png", i);
                image.Save(file, ImageFormat.Png);

            }
        }
    }
}
```
上記のコード例は、PDFファイル内の全ページを繰り返し処理し、各ページを指定されたファイルパスに個別の画像に変換します。

**4ページのPDFファイルを変換した出力結果：**
![PDFtoImage.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2811193/30409e02-540b-7c73-dc3a-a41ddeca9c89.png)

* * *

>:round_pushpin: Spire.PDF for .NETは、PDFからJPGやPNGへの変換に加えて、[PDFからWord](https://www.e-iceblue.com/Tutorials/Spire.PDF/Spire.PDF-Program-Guide/Conversion/How-to-convert-PDF-to-Doc-in-C-VB.NET.html)、[PDFからHTML](https://www.e-iceblue.com/Tutorials/Spire.PDF/Spire.PDF-Program-Guide/Conversion/C-Convert-PDF-to-HTML.html)や[HtmlからPDF](https://www.e-iceblue.com/Tutorials/Spire.PDF/Spire.PDF-Program-Guide/Convert-HTML-to-PDF-Customize-HTML-to-PDF-Conversion-by-Yourself.html)、[PDFからExcel](https://www.e-iceblue.com/Tutorials/Spire.PDF/Program-Guide/Conversion/Convert-PDF-to-Excel-in-C-VB.NET.html)、[PDFからPowerPoint](https://www.e-iceblue.com/Tutorials/NET/Spire.PDF/Program-Guide/Conversion/C-/VB.NET-Convert-PDF-to-PowerPoint.html)、[PDFからSVG](https://www.e-iceblue.com/Tutorials/Spire.PDF/Spire.PDF-Program-Guide/Conversion/Convert-PDF-to-SVG-Scalable-Vector-Graphics-in-C-VB.NET.html)などへの変換もサポートしています。
Linuxで開発環境を整えた!

# はじめに
せっかくLinux用のPCを持っているので、Linuxで開発環境を整えました

## インストールしたソフトウェア
①Visual Studio Code
②python3.11.5
③.Net SDK 8
④Git

## インストールし、設定して困ったこと
④のGitの認証が通らない問題に直面しました。

## 解決策
下記のQiitaのリンク先を参考に、アクセストークン(Classic)を行い、無事認証が通りました、

https://qiita.com/jun_aws/items/35599f54633582ae2086

## 結果

実際にGitHubにソースコードをチェックイン、コミットしたところ、無事にソ−スコードのチェックイン、コミットできました。

# 最後に
Linuxでも開発していきたいですね。
GitHubのBranchProtectionRulesで全ブランチを対象にする

Branch name patternに`**/*`と指定する

> ワイルドカードを使って、任意の文字列に一致させることができます。 GitHub では File::FNM_PATHNAME フラグを File.fnmatch 構文で使うため、* のワイルドカードがディレクトリの区切り記号 (/) と照合されません。 たとえば、qa/* は、qa/ で始まり、1 つのスラッシュを含むすべてのブランチと照合されますが、qa/foo/bar とは照合されません。 qa の後には、qa/**/* を使用して任意の数のスラッシュを含めることができます。これは、たとえば qa/foo/bar/foobar/hello-world と一致します。 qa**/**/* を使い qa の文字列を拡張して、より包括的にすることもできます。
https://docs.github.com/ja/repositories/configuring-branches-and-merges-in-your-repository/managing-rulesets/creating-rulesets-for-a-repository#using-fnmatch-syntax