OmniAICreator/Qiita-1.07M huggingface dataset:
Gradioのカスタムパス設定時にはroot_pathを設定しよう

この設定をしていなかったせいで、解決に一日、時間を費やしたので共有します。
使用しているGradioのバージョンは4.42.0です。

# 背景と発生した事象
Dockerを用いて、FastAPIでサーバーを立てて、Gradioの`mount_gradio_app`でアプリケーションを紐付け、そのポートへCaddyでリバースプロキシを設定していました。
機能を実装し、いざ本番環境へデプロイすると、開発環境とローカルのDocker上で動いていたアプリケーションが、動かなくなるという事態が発生しました。
具体的には、カスタムパスでマウントしているアプリのみ、Gradioコンポーネントは描画されるけれど、コンポーネントに紐付けた関数は実行されないという現象でした。

その時のアプリケーションを簡単に書くとこうでした。
```python:server.py
from fastapi import FastAPI
import uvicorn
import gradio as gr
import main
import share
app = FastAPI()

app = gr.mount_gradio_app(app, share.main(), path="/share/")
app = gr.mount_gradio_app(app, main.main(), path="/")

if __name__ == '__main__':
    uvicorn.run(app, port=7777, host="0.0.0.0")
```
`share.main()`と`main.main()`は`Gradio.Blocks`を返します。
これはローカルでは問題なく機能しましたが、リバースプロキシを通して実行される本番環境ではうまく動かなくなります。

## 解決策
ではどのように解決したかを示します。以下のようにroot_pathを追加しました。
```python:server.py
from fastapi import FastAPI
import uvicorn
import gradio as gr
import main
import share
app = FastAPI()

app = gr.mount_gradio_app(app, share.main(), path="/share/", root_path="/share")
app = gr.mount_gradio_app(app, main.main(), path="/")

if __name__ == '__main__':
    uvicorn.run(app, port=7777, host="0.0.0.0")

```

Gradioの公式ドキュメントでroot_pathの項目を見ると、以下のように記載されています。
> root_path: この FastAPI アプリケーションのパブリックデプロイメントに対応するサブパスです。例えば、アプリケーションが "https://example.com/myapp" で提供されている場合、root_path は "/myapp" に設定する必要があります。http:// または https:// で始まる完全な URL を提供することもでき、その場合はそのまま使用されます。通常、これは（カスタムの path を使用している場合でも）提供する必要はありません。ただし、FastAPI アプリをプロキシの背後で提供している場合、プロキシがリクエストヘッダーに Gradio アプリへの完全なパスを提供しない可能性があります。その場合、ここでルートパスを提供することができます。

プロキシが間に挟まると機能しなくなる可能性があるので、root_pathを設定してくださいということが記載されていますね。

## まとめ

Gradioは使いやすくて大変ありがたいですが、何かの拍子で本番環境では動かなくて困ってしまう時がよくあります。またGradioの知見が貯まったら共有しますので、フォローよろしくお願いいたします。
【豆知識】Ransackとscope。検索機能について調べてみる。

# はじめに
検索機能を実装する時にRansackとscopeという機能があることを知りました。どちらも広く使用されているようなのでこの2つの機能を知ると同時に実際コードを入力するとなったらどんな感じになるのか、調べたことをまとめていきます。

## 環境
- Windows, WSL
- Docker
- Ruby 3.2.3
- Rails 7.1.3



## `Ransack` と `scope` の違いと使い分け

1. **`Ransack`**:
    - Ransack は、複雑な検索フォームを簡単に実装するためのGemです。ユーザーがビュー（フォーム）から入力した複数の条件（例：複数のフィルターやソート）を扱う際に便利です。
    - モデル内で `ransackable_attributes` と `ransackable_associations` を定義することで、検索可能な属性や関連を指定できます。

2. **`scope`**:
    - `scope` は、シンプルで特定の条件に基づいたクエリをモデルに追加するための方法です。たとえば、特定のカラムに対して特定のパターンの検索を行う場合や、特定のレコードのみを取得する場合に使われます。
    - `scope` は特定の用途に特化しており、モデルにカスタムメソッドとして定義され、ビューやコントローラから簡単に呼び出せます。



## 掲示板一覧の検索フォームを例に、使い分けを確認

### **Ransack使い方の例**

まず、GemfileにRansackを追加する

```ruby
# Gemfile
gem 'ransack'
```

次に、モデルにRansackの機能を使うための設定をする

```ruby
# app/models/post.rb
class Post < ApplicationRecord
  # ここに必要なスコープやバリデーションを追加
end
```

次に、コントローラでRansackを使って検索するコードを書く

```ruby
# app/controllers/posts_controller.rb
class PostsController < ApplicationController
  def index
    # Ransackを使って検索オブジェクトを作成
    @q = Post.ransack(params[:q]) 
    # 検索結果を取得（重複を排除するオプション）
    @posts = @q.result(distinct: true) 
  end
end
```

ビューでは、検索フォームを作成する

```ruby
<!-- app/views/posts/index.html.erb -->
<%= search_form_for @q do |f| %>
  <%= f.label :title_cont, "タイトルを検索" %> 
  <!-- title_contはタイトルに部分一致する条件を指定 -->
  <%= f.text_field :title_cont %>
  <%= f.submit "検索" %> 
  <!-- 検索ボタン -->
<% end %>

<% @posts.each do |post| %>
  <p><%= post.title %></p> 
  <!-- 検索結果として表示されるタイトル -->
<% end %>
```

### **scope使い方の例**

まず、モデルにscopeを追加する

```ruby
# app/models/post.rb
class Post < ApplicationRecord
  # titleに部分一致する条件を持つscopeを定義
  scope :with_title, ->(title) { where("title LIKE ?", "%#{title}%") }
end
```

コントローラでは、scopeを使って検索するコードを書く
```ruby
# app/controllers/posts_controller.rb
class PostsController < ApplicationController
  def index
    if params[:title].present?
      # scopeを使って検索条件に一致する投稿を取得
      @posts = Post.with_title(params[:title]) 
    else
      # パラメータがない場合は全ての投稿を取得
      @posts = Post.all 
    end
  end
end
```

ビューも少し変更する

```ruby
<!-- app/views/posts/index.html.erb -->
<%= form_with url: posts_path, method: :get do |f| %>
  <%= f.label :title, "タイトルを検索" %> 
  <!-- 検索フィールドのラベル -->
  <%= f.text_field :title %>
  <%= f.submit "検索" %> 
  <!-- 検索ボタン -->
<% end %>

<% @posts.each do |post| %>
  <p><%= post.title %></p> 
  <!-- 検索結果として表示されるタイトル -->
<% end %>
```


## おまけ：両方を使うこともある！？
どちらか片方だけの機能を持たせるのではなく、場合によっては両方の機能を使用することもあるんだとか。その理由については以下のようなものが挙げられるそうです。
- **柔軟性**: プロジェクトの要件によっては、単純な部分一致検索（`LIKE` クエリ）を使う場面と、より複雑な検索フォームを提供する場面が混在することがあります。この場合、特定の条件に対してはシンプルな `scope` を使い、複数の条件を組み合わせた検索には Ransack を使うことで、コードの柔軟性が向上します。
- **使い分け**: たとえば、管理者がバックエンドで複雑なフィルタリングを行うために Ransack を使い、ユーザーインターフェイスでは簡単な検索機能だけが必要であれば、`scope` を使うことができます。


## さいごに
私自身はransackを用いて作成を進めているのですが、`ransackable_attributes`をうっかり忘れてしまったり。まだまだ使いこなせるには時間がかかりそうです。今日も今日とて奮闘中。
今回の記事をきっかけに検索機能について学ぶことがあれば幸いです。
AIにコーディングを教えてもらっています

私の個人的な学習方法の話です

## 前置き

プログラミングのコーチングサービスを行っているJISOUというサービスを利用させて頂いているのですが、
そのコミュニティには現エンジニアもそうでない方もおり非常に強い意欲で学習を進めています。

私自身は会社でシステム関係を任されておりますが、成り行き上そうなっただけであり体系的な技術の学習をしたことはあまり記憶にありません。
なので"一般的なエンジニアの学習方法"というものを知りたいと思いJISOUに参加しました。

https://qiita.com/NoritakaTaniguchi/items/d5e495e7de246fdc5ec7

前述に書いた通りJISOUに参加されている方々は意欲的に学習を進めているので、
日々届くSlackでの皆さんのやり取りや報告を見て元気をもらっております。
(手が止まっているときは少し焦ったりもします笑)

## 課題への取り組み方
TypeScriptを使用してアプリケーションを作成するという課題があった際には、
ある程度の前提条件だけ頭に入れて、教わったことを完璧に覚えられていないことを自覚している状態でもVScodeを開いて書き始めます。

どう書いていいかわからず手が止まった時はChatGPT(無課金)に丸投げして、動作を確認した後にコードを見て ”こう書けばいいのか” を学習しています。

ゼロベースから雑に質問しても手順から説明してくれるのでかなり参考にしています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3784604/a6b4968e-45b8-ad3a-3c33-3620e6567bca.png)

## 何か他のものも作りたくなってくる
ChatGPTを使用することによって開発や学習のハードルを下げることができるからか、
他の物も作りたくなってきました。

社内で使用しているクラウドの納品管理システム上で動作する業務アプリケーションを作成することにしました。

適切な配送スケジュールの立案を行い運送コストを削減するために
"指定した期間に行われる予定の納品をDBから参照してその住所を地図上に表示するアプリケーションを作成することにしました。

ChatGPTに相談すると
・フロントエンド部分のコーディング　←　学習したことがある
・データ処理層のコーディング　←　学習したことがない
・GoogleMapsPlatformAPI ← 聞いたことがない
を使用すると作成可能であるという情報と、具体的な手順まで教えてくれるので
あっという間にアプリケーションの土台が完成しました。

土台をもとにしたコードの手直しと、ChatGPTとの壁打ちで自分の理想の状態に近づけていく作業です。

今までに学習したことがない技術をその日のうちに初学者が実装まで組み込めるなんてすごくいい時代に生まれたなぁと感動しました...!

## 最高すぎるので社内でもAIツールを布教する
この感動を他の人と共有したくて一般社員向けにChatGPTを布教するハンズオンを2回開きました。
ChatGPTでExcel関数を作成する課題を設けていたのですが、若い社員が1人VBAで簡単なマクロを作成して実行できるようになりました。(何も教えてないのに...!)

他にも手作業でやっていた会議の議事録を[tl;dv](https://tldv.io/)で文字起こし&要約 → ChatGPTで校正　などやってみたら便利すぎて戻れなくなりました。

## "とにかくやってみる"の威力が上がった
開発だけではなく物事に取り組むことのハードルが下がったことにより行動力が上がったような気がします。
もっといろんなことに挑戦したいという気持ちも強くなりました。
"AIを使ってとにかくやってみる"　おすすめです！(個人差あり)

## JISOUの課題で作ったもの
学習内容と時間を記録してくれるアプリです。

https://finstudyrecord.web.app/


# JISOUのメンバー募集中
プログラミングコーチングJISOUではメンバーを募集しています。
日本一のアウトプットコミュニティでキャリアアップしませんか？
気になる方はぜひHPからライン登録お願いします
https://projisou.jp

https://projisou.jp
Amazon Connectの電話番号を別のインスタンスに移行してみた

## はじめに
Amazon Connectのインスタンス間で電話番号を移行する場合、アカウントやリージョンによって移行方法が異なるのでまとめました。

## 背景
Amazon Connectのログイン方式をId、パスワード形式からSSO形式に変更したいという要望がありました。
Amazon Connectのログイン方式は作成時にしか選択できないため、インスタンスを別途作成するしかありません。
別のインスタンスを作成するにあたり、既存のAmazon Connectで使用していた電話番号を、新規に作成したAmazon Connectインスタンスへ移行する必要がありました。その際のナレッジを記事としてまとめました。

## 結論
Amazon Connectの移行元と移行先のAWSアカウントやリージョンによって、電話番号移行の方法が異なります。

- 同一AWSアカウントで、同一リージョンの場合は、CLIによる電話番号移行が可能です
- 別のAWSアカウントや同一AWSアカウントでもリージョンが異なる場合は、AWSへのケース起票をする必要があります

### 電話番号移行をやってみた
CLIによる移行が可能なのは、***既存のAmazon Connectインスタンスと移行先のインスタンスが同一アカウント・同一リージョンの場合のみです。***
なお、ダウンタイムはほぼありませんでした。


まず、PhoneNumberIdを取得します。

InstanceIdはAmazon ConnectのARNの末尾に記載されています。
PhoneNumberはPhoneNumberIdを探したい電話番号を記載します（ハイフンやスペースは削除しましょう）。
```
aws connect list-phone-numbers --instance-id xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx --query 'PhoneNumberSummaryList[?PhoneNumber==`+815011112222`]'
```

実行結果
```
[
    {
        "Id": "zzzzzzzz-zzzz-zzzz-zzzz-zzzzzzzzzzzz",
        "Arn": "arn:aws:connect:ap-northeast-1:000000000000:instance/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/phone-number/zzzzzzzz-zzzz-zzzz-zzzz-zzzzzzzzzzzz",
        "PhoneNumber": "+815011112222",
        "PhoneNumberType": "DID",
        "PhoneNumberCountryCode": "JP"
    }
]
```


実際の移行は以下のコマンドを実行することで移行が可能です。
PhoneNumberIdは上記で取得したものを記載します。
```
aws connect update-phone-number --phone-number-id zzzzzzzz-zzzz-zzzz-zzzz-zzzzzzzzzzzz --target-arn arn:aws:connect:ap-northeast-1:000000000000:instance/yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy
```

#### 注意点
- 移行元のインスタンスで、移行対象の電話番号がキューの「アウトバウンド発信者 ID 番号」に設定されている場合は、移行時にエラーが発生します
    - エラーが発生したらキューの「アウトバウンド発信者 ID 番号」に対象の電話番号が設定されていないか確認しましょう
- 移行先のインスタンスで、以下を設定する必要があります
    - 電話番号に紐づく問い合わせフローの設定
    - キューの「アウトバウンド発信者 ID 番号」
- 移行先インスタンスの電話番号数の上限
    - 筆者が試したところ、上限を超えても移行はできたのですが、念のため上限は事前に緩和しておくといいと思います


### 既存のAmazon Connectインスタンスと移行先のインスタンスが別アカウントもしくは別リージョンの場合
CLIなどでの移行ができないため、AWSへサポート起票する必要があります。
サポート起票の際は以下の情報を含める必要があります。

>・移行元のAmazonConnectのインスタンスARN
>
>・移行先のAmazonConnectのインスタンス ARN
>
>・移行する電話番号 (複数可)
>
>・リクエストする移行日時
>
>・移行先の問い合わせフロー ARN (AWS で Amazon 問い合わせフローを移行先のConnect インスタンスの移行された電話番号に関連付ける場合)

##### 注意点
以下re:Postに記載のあった注意点を引用しています。

>・リクエストした移行日時は保証されません。
>
>・電話番号の移行ごとに 15～20 分のダウンタイムがあります。
>
>・サポートケースを開く前に、移行する電話番号が発信者 ID として指定されていないことを確認してください。
>
>・問い合わせフローを移行先の Connect インスタンスの移行された電話番号に関連付ける場合は、問い合わせフローが存在し、移行先の Amazon Connect インスタンスで公開されていることを確認します。
>
>・電話番号によっては、移行できない場合があります。リクエストがこれに該当する場合は、サポートケースを通じて連絡があります

[引用文献](https://repost.aws/ja/knowledge-center/connect-migrate-phone-number)

#### [参考資料：AWS re:Post](https://repost.aws/ja/knowledge-center/connect-migrate-phone-number)
JaSST’24 Kansai 参加レポート

# はじめに

はじめまして、本田技研工業遠野です。

QAエンジニアをしています。（QA＝Quality Assurance、品質保証）

6月半ばにソフトウェアテストのシンポジウム”JaSST'24 Kansai”へ参加してきましたので、そのレポートとなります

https://www.jasst.jp/symposium/jasst24kansai/details.html

# レポート1：基調講演「QAエンジニアの仕事をつくる」

当日の資料が公開されています

https://www.docswell.com/s/yoshikiito/KLL73D-jasst24kansai-QAEngineer-Job-Crafting/1

## 共感したこと

- QA業務をどうするのか、QAの業務についてよく聞く疑問や悩みについて
    
    1人目だったり、話せる人が周りに少ないと、こう思うことがよくあるのではないだろうか
    
- QAがいなかった組織においてQAは”謎の存在”か”嫌な存在”どっちかが多い
    
    謎の存在だから（必要な情報がわからなくて）会議に呼ばれていなかったり、
    嫌、まではいかなくとも最初は距離を感じたりしたことがあるため共感しました
    わかってもらうまでが重要なのかなと思いました
    

## 自分でもやってみたいこと

- QAの使い方、やりたいこと、やらないことを伝えた
    わからない・知らないから、はよくあるので、
    わかりやすく宣言しておくのはいいなと思った
    
- 可視化×トップダウン：QAガイド＆クライテリア    
       
    つくるのはかなり大変そうと正直思ったけど、
    書いてあるということはやったほうがいいこと
    と直接言わなくてもわかるのはすごくいいなと思った
    

## 印象に残っていること

- 巻き込むときのポイント
    - 課題意識・危機感
    - 時間的・精神的な余裕（炎上中は改善は進まない）
    - 信頼関係
- 仕事をつくるうえで大切なこと
    - 自分に何ができるか把握しなければならない
    1. 手持ちの武器を増やす
        1. 学習、スキル習得
        2. 味方を連れてきてやってもらう
        3. 日常的にやる
    2. 持っている武器を駆使する
        1. あるものでなんとかする腕力と覚悟
        2. 一人しかいないから！
        3. パワー！！！
- ジョブ・クラフティング　の考え方はヒントになる
    - 作業クラフティング
    - 人間関係クラフティング
    - 認知クラフティング

## 感想

- わたしも、品質の領域に関しては、監督・コーチ的なポジションだと思うことがよくある
- サービスやプロダクトに対しては別の監督が居る気がする
- （監督の比喩から）どうなったら勝ちなのか、説明できたらもっといいのかな

# レポート2：テーマセッション1「品質活動を事業に結びつけるためのQA文化の築き方」

こちらも資料が公開されているため、詳細はそちらをご確認ください

https://speakerdeck.com/mii3king/how-to-build-qa-culture

## 印象に残っていること

セッションのまとめで話されていた内容が特に印象に残っています。

- トレード・オフするならスコープを削ることから検討する
- ソフトウェア品質だけではない
- その先にある体験価値の創造
- ソフトウェアが完璧につくりこまれていても、旅体験がよくなければその人にとっての旅は悪いものになる
- プロダクトの中に旅はない
- ソフトウェアが良くなければ旅にすら出てくれないけど、ソフトウェアがすべてではない
- かけ合わせで総合点はもっと上がる
- サービスの改善活動に取り組める領域はたくさんある
- QAエンジニアのキャリアの選択肢もたくさんあるはず
- QA組織という枠組みだけではなく、チーム全員で

## 感想

- 文化をつくるのはすごく難しいし、大変、時間がかかると勝手に思ってしまう
- 文化づくりに成功しているなと思った
- 戦略的に動けば可能なんだ！と思えた
- 「ソフトウェアが完璧につくりこまれていても、旅体験がよくなければその人にとっての旅は悪いものになる」にハッとした
- ソフトウェアだけに限らないということは、”品質”に対しては、QAができることは無限にあると思った
- 自分がこれまでやったああいう動きはあながち間違いではなかったかも、と思えて元気が出た
- 視野広く持とう

# レポート3：テーマセッション2「組織全体で品質を担保するための品管メンバーとしてのさまざまな役割」

同様に、資料が公開されています

https://speakerdeck.com/tarappo/zu-zhi-quan-ti-tepin-zhi-wodan-bao-surutamenopin-guan-menhatositenosamasamanayi-ge

## 印象に残っていること

- プロダクト品質の担保は誰がコミットメントするか
    - 得意なのはQAに関する職種のメンバー
    - ただし全部をやるのは無理なので「リード」しながら組織全体で動くことが大事
    - 品管メンバーがやみくもに動いても勝手にコラボレーションは生まれない
- コラボレーションに至るまでのステップ
    - 認知
        - 存在、やっていること
        - 品質にまつわることを知ってもらう
    - コミュニケーション
        - 一緒にやる
    - コラボレーション
        - 一体となっていく
    - 品管メンバーの存在を認知
    - 品管メンバーの活動を認知
    - 品管メンバーとコミュニケーション
    - 品管メンバーとコラボレーション
    - 品管メンバー関係なく自発的に様々なアクションが発生する

## 感想

- 情報密度高かったけど、わかりやすかった、聞きやすかった
- 全部を自分たちでやることは無理(泣)それはそう
- やったことをかなり具体的に知ることができて、イメージがつきやすかった
- 特に「品管週報」やってみたい！
- やりはじめたら無限に続けられると思うけど、終わりにしたのはなんでだろう？
    - 役目を果たしたから、と回答をもらいました
- （仕様起因のバグってあるあるなのかな…）

# さいごに：JaSST'24Kansai 全体を通して感想

- 自身の状況的には実質ひとり目QAなので、参考になる話ばかりだった
- 自分の仕事を知ってもらうこと の、いろんなやり方を知れた
- やってみたいと思える事例に出会えた
- ワークショップのほうも行きたかった！

レポートは以上です

お疲れさまでした、楽しかったです！
Kicadでティアドロップをつける

今回Kicad8でティアドロップを使用したので記事にしてみた。
Kicad7から対応しているらしい。

１、まずは設定。編集＞ティアドロップを編集を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1339052/50424bde-78f3-b764-f42e-15a84b9dc48e.png)

２、対象としたい項目を「スコープ」で選択して、今回はF.Cuのみティアドロップを適応してみた。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1339052/3a75e4dd-86b3-3f81-cf90-d0e8017f556c.png)

３、OKを押したあとは、配線が自動でティアドロップになる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1339052/b83c7a9c-4061-0776-113b-cb5dcf9db088.png)
Apacheにつながらない（忘備録）

# Apacheにつながらない

パソコンの移行作業をしている最中のできごとでした。
どのプロジェクトを開いてもエラーでつながらない状態でした。

## エラー内容

```
Forbidden
You don't have permission to access this resource.
```

## 結論
`C:\xampp\apache\conf\extra\httpd-vhosts.conf`
で設定したディレクトリパスが間違っていた。

間違えたパス：`C:¥xampp¥htdocs`

正しいパス：`C:\xampp\htdocs`


```
// 間違い
<VirtualHost localhost:80>
 DocumentRoot ""
 ServerName xxx.com
 <Directory "C:¥xampp¥htdocs">
  AllowOverride All
  Options All
  Require all granted
 </Directory>
</VirtualHost>
```

```
// 正しい
<VirtualHost localhost:80>
 DocumentRoot ""
 ServerName xxx.com
 <Directory "C:\xampp\htdocs">
  AllowOverride All
  Options All
  Require all granted
 </Directory>
</VirtualHost>
```


## なぜ間違えたのか

環境構築の資料（PDF）から、そのままコピペして貼り付けたものが`¥`（円マーク）だった。
この２つ`\`（バックスラッシュ）と`¥`（円マーク）は、Windowsではどちらも`¥`として表示されてしまうため、気づくのが遅くなった。
パーミッションエラーと出ていたため、初めは権限関係かと思っていた。

## 所感

２時間以上かかったけど、なんとか解決できた時は感動しました。
あまりに局所的なので役に立たないかもしれませんが、自分の忘備録として。
149日目　「DVA」合格体験記by社畜Ｓ

## :checkered_flag:はじめに
どうも、社畜Sです。  
今回はタイトルのとおり、無事に
**「AWS Certified Developer - Associate（通称：DVA）」**
に合格することができたので、いつか受けるかもしれない誰かのために合格体験記として記事にしたいと思います！
完全初心者視点で「学習開始時のスペック」「どのように学習したか」「SAAと比べてどうだったか」について書いていくので、良ければぜひ参考にしてください！
## :checkered_flag:社畜Sのスペック（DVA版）<br> 
SAA受験時と比べて社畜Sのスペックにも変化がありましたので、まずはスペックから。
> 所持資格➡基本情報とSAAを取得済み。応用情報３連敗中。来月リベンジ。
> AWSについての知識➡SAAを取得済み。業務でも実際に触るようになってきて少しずつ知識がついてきた。

前回は完全に初心者でしたが、SAA合格+実務経験で多少知識を身に着けてからDVA試験に臨むことができました。
そのため前回の学習時と比べて呑み込みが早かったと思います。
特に実務経験は実際に手を動かしながら知識をつけることができたので、とてもいい経験になっています。
## :checkered_flag:こういう勉強してました
使用した教材は
**[Cloud License](https://cloud-license.com/)**
の一本勝負でいきました。
過去問を大体370問程度解いたと思います。
学習期間は3週間程度です。

学習の流れとしては
0週目：受験日を早めに定めて勉強スイッチを入れる
1週目：過去問を解き、じっくり解説を読んで理解する
2週目：問題のパターンを見つけて、この単語が出てきたらこの答えというのをなんとなく理解する。
3週目：ひたすら過去問を解き続けて答えを暗記する

このような流れで行いました。
今回は時間の関係上テキストを使っての事前学習を行えなかったので1週目の段階で時間がかかってしまいましたが、時間に余裕がある人はテキストを読むなどの事前学習をしてからのほうが解説文を理解しやすくなると思います。
## :checkered_flag:SAAと比べて
人によって答えが分かれる「SAAとDVAどっちが難しいの問題」ですね
個人的にはSAAのほうが難易度が高かったと思います。
SAAのほうが出題の幅が広く、覚える範囲が多いと感じたのが理由です。
点数的にも

> SAA➡723点
> DVA➡771点

とSAAより余裕をもって合格していました。

ただ、だからといってDVAを先に受験したほうが良い！というわけでもなく、SAAで幅広い範囲を学んでからDVAに臨むことで専門的な範囲も理解しやすくなった（気がする）ので、これからも他のAWS試験を受けたいという人はまずはSAAから挑戦することを私はおすすめします。


## :checkered_flag:まとめ
というわけで、完全初心者によるDVA合格記でした。
SAA受験時と比べると大きな成長を感じる受験になりました。
本番まで一回も模擬試験で合格点に行かなかったので、受験前はめちゃくちゃ緊張していましたが、何とかなって本当に良かったです。
時には自分を追い込むことも大事ですね。

次回の資格試験は……絶賛3連敗中の「応用情報技術者試験」に挑戦しようと思います。
受験までの残り期間勉強頑張ります！！そろそろ合格したい！！！

## :checkered_flag:余談
**[43日目 SAAに挑んだ社畜S](https://qiita.com/QiiTaro_/items/4ec66dae7f8d2ece565e)**

社畜SがSAAに挑んだときの記事です。もし良ければこちらも読んでいただけると幸いです！
画像のドット抜けを解消するアルゴリズムを考える。

今回は画像のドット抜けを解消する
アルゴリズムを考えてみたいと思います。
完成品は下記の URL で公開しています。

[https://uni928.github.io/SephirothImageDotFix/](https://uni928.github.io/SephirothImageDotFix/)

ドット抜けのある画像を
このサイトで修正してみた所
ある程度解消できている事が確認できます。

また、このアルゴリズムは
ノイズ削除のように元の画像から
乖離していないと思います。

***

今回紹介するアルゴリズムについて

今回紹介するアルゴリズムは
以下の内容になります。

~~~
全てのピクセルに対して
左右が同じ位の色で自身のみ大幅に異なる場合に
自身を左右の平均の色に修正します。

例えば左右のピクセルが赤で
自身が青ならば異常と判定して
自身を赤にします。

この作業は上下も行います。
~~~

つまり連続する 3 点を見て
端の 2 点が同じような色で
中央だけ左右と乖離しすぎている場合に
異常と判定する

というのがこのアルゴリズムになります。

このアルゴリズムならば
ドット抜けをある程度解消した上で
元の画像から乖離しない修正を
施すことができると思われます。

***

以上ドット抜けを解消する
アルゴリズムを考えてみました。

簡単なアルゴリズムなので
既にあるアルゴリズムかもしれません。
既にあったならば申し訳ありません。

この記事が皆さんの息抜きに役立ったならば
これ以上嬉しい事はありません。

閲覧ありがとうございました。
Ubuntu でバックグラウンドダウンロードを抑止する(途中)

バックグラウンドで余計なダウンロードを抑止したい。

# 環境

Ubuntu 24.04

# packagekitd

「packagekitd を無効にして バックグラウンドでのダウンロードを停止する」
https://qiita.com/nanbuwks/items/aab0178248f2415d09bd
の記事を以前書きました。

これの対策をしましたが、まだなにか通信しています。

![Screenshot from 2024-08-31 07-52-12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/a20544bf-642c-f2b9-c92c-378105dcded5.png)

# 調査

通信しているプロセスを調査するためには、 `nethogs` が使えるらしい。

## nethogs インストール
```
$ sudo apt install nethogs
```
## 実行

起動しようとするとエラー
```
$ nethogs 
Error opening handler for device wlp4s0
                                       To run nethogs without being root, you need to enable capabilities on the program (cap_net_admin, cap_new_raw). See the documentation for details.
Error opening pcap handlers for all devices.

```
sudo を付けて実行します。
```
$ sudo nethogs
```
![Screenshot from 2024-08-31 07-53-11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/738c4739-0d6d-ba9d-e32a-3880cd0e246a.png)

この図で上に表示されているグラフは nethogs ではなく、 system-monitor-next アプレットです。黄色が network download を表しています。

nethogs で google chrome と unknown TCP がリストアップされています。しかしながら黄色のグラフで表示されているように、丁度通信が止まった直後でした。

なので nethogs でどのプロセスが問題だったかは不明。またダウンロードの事象が補足できたら続けます。
@actions/upload-artifactで隠しファイルがアップロードされなくなった

# まとめ
隠しファイルをアップロードさせたいならオプションが必要になりました
```yml:sample.yml
      - name: Upload artifact
        uses: actions/upload-artifact@v4
        with:
          name: sample-app
          path: .output
          include-hidden-files: true # 隠しファイル追加オプション
```

# 経緯
数日前まで成功していたActionsのワークフローが失敗するようになり、ログを確認したところ`.output`ディレクトリがアップロードされていないことが判明
> Warning: No files were found with the provided path: .output. No artifacts will be uploaded.

actions/upload-artifactのリポジトリを確認したところ、8月末にアップデートがあったようで「デフォルトでは隠しファイルをアップロードしない」仕様に変更されたと説明
https://github.com/actions/upload-artifact/releases/tag/v4.4.0


お知らせの内容に従い、オプションを追加したことで無事アップロードに成功するように、めでたしめでたし
> Customers who need to continue to upload these files can use a new option, include-hidden-files

# 感想
モジュールの更新日も疑っていこう
C#(.NET)のNLogでshift_jis形式で出力する方法

# はじめに

.Net FrameworkではNLogでの出力ファイルがshift-jis形式だった。
.NETで同じNLog.configファイルを使ってもUTF-8形式に変わってしまった。



# 解決方法


https://qiita.com/sugasaki/items/0639ea9ca07f1ba7a9e0

NLogの問題ではなく、.NETの問題だった。
shift_jisなどのマイナーエンコードは明示的に読み込まないといけなくなったらしい。
下記2か所に対応することでshift_jis出力されるようになった。


```Program.cs
//Encodingを明示的に読み込む。
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
```


```NLog.confg
//"shift_jis"指定する
<target name="name01" xsi:type="File" encoding="shift_jis"　...>

```
Lambdaの"Task timed out after x.xx seconds"ログが出力されない問題

# 🔹結論
現状pythonのランタイムバージョンが3.12だと出力されない（3.11までは出力される）
python以外については未検証
他のランタイムバージョンにも波及する可能性あり
# 🔹詳細
以下の記事をもとにLambdaのタイムアウトエラーに対して通知できるような機能を実装しようとしたのですが、
「Task timed out after x.xx seconds」が出力されませんでした。
> [Lambda 関数がタイムアウトしているかどうかを確認するにはどうすればよいですか？](https://repost.aws/ja/knowledge-center/lambda-verify-invocation-timeouts)

ネット上に情報が特になく、以下検証を実施しました。

## 🔸前提
・アーキテクチャ：x86_64
・タイムアウト：3秒
・コードの中身：
``` python 
import json

def lambda_handler(event, context):
    # TODO implement
    while True:
        pass
    return {
        'statusCode': 200,
        'body': json.dumps('Hello from Lambda!')
    }
```
## 🔸検証結果

[Python 3.11]（3.11以下のバージョンについても同じ）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3179263/fa5142bd-51d4-5eff-7623-c873a72f05cd.png)

[Python 3.12]
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3179263/3fb53c2a-f465-490b-7af7-ca01306f9b47.png)

なぜか3.12の場合のみ出力されない...
ランタイムのライブラリバージョンが関係しているのか。

> 参考：[AWS LambdaのPythonランタイムとAWSが提供するLambdaレイヤのPythonライブラリを調べてみた。](https://dev.classmethod.jp/articles/check-lambda-python-runtime-packages/)


# 🔹原因
#### なんとLambdaのログ出力形式が変更になっていました。
 

  
> [Lambda 実行環境のライフサイクルを理解する
](https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/lambda-runtime-environment.html#:~:text=Lambda%20%E5%AE%9F%E8%A1%8C%E7%92%B0)


例 CloudWatch Logs ログ出力 (関数タイムアウト) - 旧形式
> START RequestId: b70435cc-261c-4438-b9b6-efe4c8f04b21 Version: $LATEST
2024-03-04T17:22:38.033Z b70435cc-261c-4438-b9b6-efe4c8f04b21 Task timed out after 3.00 seconds
END RequestId: b70435cc-261c-4438-b9b6-efe4c8f04b21
REPORT RequestId: b70435cc-261c-4438-b9b6-efe4c8f04b21 Duration: 3004.92 ms Billed Duration: 3000 ms Memory Size: 128 MB Max Memory Used: 33 MB Init Duration: 111.23 ms

例 CloudWatch Logs ログ出力 (関数タイムアウト) - 新形式
> START RequestId: 527cb862-4f5e-49a9-9ae4-a7edc90f0fda Version: $LATEST
END RequestId: 527cb862-4f5e-49a9-9ae4-a7edc90f0fda
REPORT RequestId: 527cb862-4f5e-49a9-9ae4-a7edc90f0fda Duration: 3016.78 ms Billed Duration: 3016 ms Memory Size: 128 MB Max Memory Used: 31 MB Init Duration: 84.00 ms Status: timeout

#### また、この変更はTimeoutだけでなく、ランタイムのクラッシュのログ出力形式に関しても同様です。


以下のように注意書きがありました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3179263/85d0bda8-66e8-f563-f00b-b4d10e3a3a05.png)

**今後数週間に全関数に適用...!!!??**


[詳細]の項で記述した、re:Postで推奨方法がNGになりそうです。
Lambda関数のクラッシュやTimeoutをCloudWatch Logsで監視している方は要注意です。
FlowiseAIを使って、複数のRAGからAgentを使ってよしなにデータを取り出す

# はじめに

最近、FlowiseAIをよく触っています。Flowiseはインストールも可能ですが、github codespaceで簡単に動かすことができるので、iPadなどから出先でサクッと作って作ったコードはgit pushできるなどが個人的に大きな利点だと思っています。この手のローコードサービスは、他にも、Apache Cassandra NoSQLデータベースの商業化した事で知られるDataStaxなどが買収したLangFlowなども存在しており、今後も続々と新たなツールが登場するのではないかと思います。今回はRAGを使う場合に、複数の知識を入れて、Agentに検索してもらって使うなどの仕組みをFlowiseで作ってみたらどうなるのか？ということをやってみたいと思います。

# つくるもの

今回は複数拠点における防災AIを作ってみたいと思います。各自治体で配布されている防災ハンドブックについて複数拠点でRAGを作成して、そこに対してAIに質問をしてみたいと思います。
防災ハンドブックは、自治体によっておおよそ共通な部分と、個別に分かれる部分が存在します。

共通...災害時の心構え、防災袋に入れておく必要のあるものリストなど
個別...避難所などの情報、緊急時の連絡先など

予想される動きとしては、共通なものはそれぞれのRAGから返答する、個別のものはAgentがRAGを選択して情報を取り出すような動きを想定します。

# RAGの作成

まずは複数のRAGを作成します。ベクトルデータベースは様々なものがあるので選定が必要ですが、無料枠で複数のindexが作れること、PDFのインポートに対応しているという条件などから、今回は、Vectaraを利用します。(普段よく使っているPAINCONなどでは無料では一つのindexしか使えないなど制限がある様子で条件から除外しました。）

## Vectaraの操作

### 1.Vectaraを開きます
![IMG_0114.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43766/76b86ca8-dab0-30de-2640-7743de7f3d90.jpeg)

### 2.RAGの名前を記述します
![IMG_0118.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43766/97cbe352-7a1b-48ee-950a-197259d9822d.jpeg)

### 3.PDFをアップロードします
![IMG_0122.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43766/e52fd632-4921-23ba-db53-0d15c80e729e.jpeg)

### 4.1-3の手順で複数のRAGを作成します。

### 5.FlowiseAIからデータを読むために、キーを作成します。作成時に、Corporaを選択します。
![IMG_0120.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43766/8e650f15-4af0-1282-ae4e-36ae4e5475b3.jpeg)

### 6.キーが作成されたのでメモしておきます。
![IMG_0121.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43766/1c1a2d2c-40d3-0f6f-66e8-7b09a4302ec0.jpeg)

## FlowiseAIの手順

Flowiseではフルスクラッチで書くことももちろんできるのですが、
参考になるテンプレートがMarketに転がっているので、作成したいものに対して、近いものがあるのであればこちらを活用すると便利です。

### 1.Marketから今回参考にするMultiple Documents QnAを選択する


![IMG_0143.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43766/7d42a149-f59e-9aac-33ad-2834c5c2b535.jpeg)


### 2.ToolAgentを中心に、ToolsにVectara(RAG)を設定、ChatModelにGPTなどを設定する

![IMG_0150.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43766/a2f6e04e-1373-f230-44bf-5158e0e4270f.jpeg)

### 3.VectaraAPIの設定を行う

VectaraCustomerID、VectaraCorpusID、APIKeyなどを設定する

![IMG_0147.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43766/81c3946f-340a-abe2-dcc1-342c3a231623.jpeg)

### 4.全体感としてはこんな感じ

![IMG_0145.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43766/6b2c836b-25bc-08b8-e5a6-dced168bc9f4.jpeg)


## 会話してみる

複数のRAGの中で共通していそうな話題と、片方のRAGを用いる話題などを試してみました。

### RAGで共通してそうな話題

![IMG_0141.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43766/f5438249-df3e-7e44-31b2-0c44cee0137d.jpeg)

### 個別のRAGについての話題

![IMG_0137.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43766/4de81082-d335-eedc-ba24-9a208e5d37c9.jpeg)

#Conclusion
SQL Serverデータベースを簡単に移行する

## はじめに
ローカル環境で開発しているWebシステムを、一度クラウドにデプロイする場合があります。その際、ローカルのデータベース（DB）をクラウドに移行する必要があります。本記事では、SQL Server間でデータベースをテーブルやデータごとまとめて移行する方法について検証しました。

## 本記事の対象者
Azureの基本的なサービスや仕組みを理解している方
Microsoft SQL Serverを使用している方

## 準備
SQL ServerとSSMS（SQL Server Management Studio）がインストールされた端末
Visual Studioなど、データ出力用のプログラムを開発できる環境

## 検証

### Auzre SQLデータベースの作成

まず、AzureでSQLデータベースを作成します。
この際、サーバー名（エンドポイント）とSQLログイン用のユーザー名とパスワードを記録しておきましょう。

※Azure SQLデータベースは、仕様によって費用が大きく異なります。検証目的や小規模なスタートには「サーバーレス」プランがおすすめです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2822850/42edb4c1-f2e3-6672-f189-8b7496ff44b5.png)

### SSMSを起動し、ローカルのSQLServerに接続する
次に、SSMSを起動し、ローカルのSQL Serverに接続します。移行したいデータベースを右クリックして、「タスク」→「データのエクスポート」を選びます。エクスポートウィザードで、コピー元のデータベースとコピー先のAzure SQLデータベース、およびアクセスユーザーを指定します。

※Windows認証を使用するとエラーが発生することがあります。SQL Server認証を使うため、専用のログインユーザーを設定しましょう。
![20240904_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2822850/6851aa04-a828-d7af-4e24-eba64bdc0aec.png)

※ユーザーに適切なロールを追加していないとエラーが発生するので注意が必要です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2822850/06d8c971-d0a1-e861-49a4-d5fde3abe1b2.png)


### 結果
ローカルのDBテーブルとデータをAzure SQLデータベースに簡単に移行することができました
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2822850/6a6802ba-53f4-1b58-2f99-7aebf9ba7d33.png)

## 感想
移行は非常に簡単でした。また、クラウドからローカルへの移行も同様に簡単にできると思います。これにより、開発環境やテスト環境の構築がよりスムーズに行えそうです。
PhpStormで空行の空白が勝手に削除される 👿【Settings/Preferences | Editor | General | Remove trailing spaces on:】

原因はこいつじゃない
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435735/8647dd3c-c816-7019-64ce-9c29c5e0a3a8.png)

.editorconfigが原因

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435735/71f06f51-d726-c2fc-d5f7-233d5c204cc4.png)

```ini:.editorconfig
root = true

[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
indent_style = space
indent_size = 4
trim_trailing_whitespace = true ←削除するよ

[*.md]
trim_trailing_whitespace = false

[*.{yml,yaml}]
indent_size = 2

[docker-compose.yml]
indent_size = 4
```
New Relic のクエリ (NRQL) を実行する UI のタブ機能でデータ探索を効率化

　New Relic を活用する際に欠かせない NRQL (New Relic Query Language)のクエリービルダーがタブ機能に対応しました。今回はタブ機能の特徴と便利な使い方を紹介します。

# 今回のポイント
この記事で紹介しているポイントは、次の２つです。
1. **タブ機能の特徴を知る**
 タブ機能が持つ主な特徴を3つ紹介します。
2. **タブ機能の便利な使い方がわかる**
 タブの管理方法やクエリを簡単に複製する方法等を紹介します。

:::note info
最新のアップデートの詳細はこちら
[New Relic アップデート一覧
](https://newrelic.com/jp/blog/nerdlog/new-relic-update  "New Relic アップデート一覧")
:::

:::note info
無料のアカウントで試してみよう！
[New Relic フリープランで始めるオブザーバビリティ！](https://qiita.com/ktst79/items/5ee74b34e6adb8a7a6fa)
:::

# タブ機能の特徴
## 複数のタブを切り替えて NRQL を使った調査を効率化
　これまでのクエリビルダーは複数のクエリを比較するためにわざわざブラウザのタブを追加する必要があったり、 **Recent queries** で過去に実行したクエリを再実行して調査する必要がありました。タグ機能が追加されたことにより、画面を切り替えることなくクエリビルダーのタブを切り替えるだけで複数のクエリの実行結果を比較することができるようになりました。
 ![タブ機能.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3043202/f5afd83c-26ce-3d7f-6cea-5c762728c2dd.png)


## クエリの上書きしてしまう心配がない
　New Relic の既存のチャートからクエリを確認する際によく使う **View Query** の機能がタブ機能の追加でより使いやすくなりました。**View Query** で開いたクエリは**新しいタブで開く**ため、作業していたクエリを上書きする心配がなくなりました。
 
![ViewQuery.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3043202/7deae990-5f44-af3d-e543-0c45ae48d077.gif)

 
## クエリキャッシュ機能でタブの切り替えが高速に
　タブの切り替えも高速化されています。タブの切り替えと同時にクエリの実行結果も表示されるため、調査時間が大幅に削減できます。
 
 ![クエリキャッシュ.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3043202/471a506c-396a-cce3-01c5-2e4f2824574b.gif)


# タブ機能の使い方
:::note info
まだタブ機能が使えないという方へ
　**query your data** の画面を表示して、画面上部に表示されたバーの **Try it out** のボタンを選択してください。
 ![try_it_out.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3043202/eeded680-774b-4c83-6ebe-18b130583901.png)

:::

## タブに名前をつけて管理する
　メニューから **Rename を選択する**、もしくは**タブをダブルクリックする**とタブの名称を変更することが可能です。名前をつけることで複数開いたタブの中から目的のクエリをすぐにみつ出すことができるようになります。
 
![Rename.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3043202/24bd5e62-3c7a-89ba-8559-1a4f5beb02da.png)

![変更後.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3043202/1dc5ef9e-b2ed-e0c6-67d7-c8e83a33f1be.png)

## タブを複製する
　メニューから **Duplicate を選択する**とタブを複製することが可能です。類似したクエリを作成する際にコピー＆ペースとすることなく、クエリのコピーを作成することができます。
![duplicate.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3043202/339a200f-417b-7280-47d4-a23438d0c245.png)

## NRQL の新しいクエリビルダーには便利の機能がたくさん
 新しいクエリビルダーには今回紹介したタブ機能以外にも **New Relic AI を使ってクエリを作成する機能** や **複数のアカウントにまたがるデータに対してクエリを実行する機能** 等が追加されています。詳しい内容は[こちらの記事](https://qiita.com/nr-mito/items/59d011c3fb91040d62e4)でも紹介されています。ぜひご覧ください。

 https://qiita.com/nr-mito/items/59d011c3fb91040d62e4

 :::note info
無料のアカウントで試してみよう！
[New Relic フリープランで始めるオブザーバビリティ！](https://qiita.com/ktst79/items/5ee74b34e6adb8a7a6fa)
:::

:::note info
[New Relic株式会社のQiita OrganizationOrganization](https://qiita.com/organizations/newrelic)では、
新機能を含む活用方法を公開していますので、ぜひフォローをお願いします。
:::
アプリ開発者必見！Google Playレビュー＆データ収集ツール

スマートフォンユーザーにとって、Google Playストアは日常生活に欠かせない存在です。数百万のアプリやゲームが集まるこのデジタル市場は、便利さと楽しみを提供しています。

しかし、開発者やマーケッター、そしてユーザーにとって、この膨大なデータには別の魅力があります。アプリの人気度、ユーザーの反応、市場動向—— これらの情報がPlayストアには眠っているのです。

では、このビッグデータをどのように活用できるでしょうか？ アプリのレビュー、ダウンロード数、評価など、具体的なデータを効率的に収集し分析する方法はあるのでしょうか？

本記事では、Google Playストアからデータを抽出するための方法をご紹介します。データを活用することで、市場分析や競合調査、自社アプリの改善など、様々な可能性が広がるでしょう。

<h2>Google Playをスクレイピングする方法</h2>

Google Playストアからデータを抽出する方法は複数あります。アプリ名、レビュー、評価、ダウンロード数、開発者情報など、多岐にわたる情報を収集できます。主な方法をいくつかご紹介しましょう。

<h3>1.Google Play Store API </h3>
APIを利用すれば、公式にデータにアクセスできます。ただし、1日あたり200,000リクエスト、レビューに関しては1時間あたり60リクエストという制限があります。大規模なデータ収集には向かないかもしれません。

<h3>2.Pythonスクリプト </h3>
GitHubなどで公開されているPythonスクリプトを利用する方法もあります。APIの制限がないため、大量のデータ抽出に適しています。ただし、プログラミングの知識が必要です。

<h3>3.Beautiful Soupなどのライブラリ  </h3>
PythonのBeautiful Soupなどのライブラリを使用してスクレイピングすることも可能です。こちらも一定のプログラミングスキルが求められます。
PythonとBeautiful Soupを使用してGooglePlayストアをスクレイピングする手順ガイドはこちらで入手できます。

<h2>コーディング不要でGoogle Playストアをスクレイピングする方法 </h2>

プログラミングに慣れていない方には、Octoparseのようなツールがおすすめです。ウェブスクレイピングに特化したこのツールを使えば、数クリックでGoogle Playストアのデータを抽出できます。

<h3>Octoparseの使い方：</h3>

<h4>1.Google PlayのURLを入力 </h4>
スクレイピングしたいアプリのURLをOctoparseの検索ボックスに貼り付け、「スタート」をクリックします。

![op.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/262932/af7cb00d-7b39-3350-bcb7-e36312d0a4d1.png)


<h4>2.ワークフローのカスタマイズ</h4>
自動検出されたデータを確認し、必要に応じてフィールドの追加や削除、名前の変更を行います。

![op2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/262932/52c78768-e917-4ce7-ae9c-1a2b01b33493.png)



<h4>3.データの抽出とエクスポート</h4>
設定が完了したら「実行」ボトンをクリックし、スクレイピングを開始します。抽出されたデータはExcelファイルやデータベースに保存できます。

![op3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/262932/f6fcdc6f-3b80-f5f9-8bec-5f753d2e5e86.png)


Octoparseには、Google Play専用のテンプレートも用意されています。アプリのURLと「さらに読み込む」ボタンのクリック回数を指定するだけで、レビューデータを簡単に収集できるのです。

[Google Play アプリリストクローラー](https://www.octoparse.jp/template/google-play-app-scraper)
[Google Play レビュークローラー](https://www.octoparse.jp/template/google-play-review-scraper)

<h2>まとめ</h2>
プログラミングスキルをお持ちの方なら、APIやPythonスクリプトを使用して詳細なデータ収集が可能です。一方、コーディングに自信がない方でも心配はいりません。Octoparseのようなユーザーフレンドリーなツールを使えば、数回のクリックで簡単にデータを収集できます。これらのツールは、複雑なプログラミングの知識なしでも、プロ級のデータ抽出を可能にします。
どの方法を選択するにせよ、Google Playストアのデータは、アプリ市場の動向を理解し、自社のアプリを改善する上で参考になるデータとなります。

 [Octoparse公式サイト](https://www.octoparse.jp)。
Heroku+Selenium+Chrome+Pythonでの日本語設定にハマった話

Heroku + Selenium + Chrome + Pythonの組み合わせでスクレイピングをしていたのですが、dynoを再起動したせいか、なぜか突然ページの言語が英語に。

色々と調べてみたところ、optionsの設定が足りなかったようで、だいぶハマりました。

# 従来の設定

これまでwebdriverに設定していたoptionsの内容です。

```py
    options = webdriver.ChromeOptions()
    options.add_argument('--headless')
    options.add_argument('--window-size=1920,1080')
    options.add_argument('start-maximized')
    options.add_argument('--disable-gpu')
    options.add_argument('--no-sandbox')
    options.add_argument('--disable-dev-shm-usage')
    options.binary_location = os.environ.get("GOOGLE_CHROME_BIN")
    service = Service(executable_path=os.environ.get("CHROMEDRIVER_PATH"))
    driver = webdriver.Chrome(service=service, options=options)
    return driver
```

これまでは```<html lang="ja">```となっていたのに、なぜか```<html lang="en">```になっていました。

# 次に試したこと

言語設定の方法で検索したところ、langのオプションが必要とのことで設定してみました。

```py
    options = webdriver.ChromeOptions()
    options.add_argument('--headless')
    options.add_argument('--lang=ja-JP') # ここ追加
    options.add_argument('--window-size=1920,1080')
    options.add_argument('start-maximized')
    options.add_argument('--disable-gpu')
    options.add_argument('--no-sandbox')
    options.add_argument('--disable-dev-shm-usage')
    options.binary_location = os.environ.get("GOOGLE_CHROME_BIN")
    service = Service(executable_path=os.environ.get("CHROMEDRIVER_PATH"))
    driver = webdriver.Chrome(service=service, options=options)
    return driver
```

これでもやはり英語のまま。

# たどり着いた情報

Googleではなかなか見つからなかったので、Xでも検索してみると、以下のポストが。

https://x.com/riceflow/status/1620114721356808192

なるほど、優先言語(accept-language)なるものがあるのですね。もしかしたらどこかのタイミングでこれが変わってしまっていたのかもしれません。

設定方法は以下の記事を参考にしました。

https://qiita.com/terukizm/items/ac17dfd3703402e8b658

https://miya-jan.hatenablog.com/entry/2016/07/21/230620

# 最終的な設定

最終的には、```headless=new```を入れたのと、add_experimental_optionでjaを設定した2点で解決しました。

```py
    options = webdriver.ChromeOptions()
    options.add_argument('--headless=new') # ここ変更
    options.add_argument('--lang=ja-JP')
    options.add_argument('--window-size=1920,1080')
    options.add_argument('start-maximized')
    options.add_argument('--disable-gpu')
    options.add_argument('--no-sandbox')
    options.add_argument('--disable-dev-shm-usage')
    options.add_experimental_option('prefs', {'intl.accept_languages': 'ja'}) # ここ追加
    options.binary_location = os.environ.get("GOOGLE_CHROME_BIN")
    service = Service(executable_path=os.environ.get("CHROMEDRIVER_PATH"))
    driver = webdriver.Chrome(service=service, options=options)
```
CompositionLocalをうまく使おう

# CompositionLocalとは
公式リファレンス: https://developer.android.com/develop/ui/compose/compositionlocal

Composeのバケツリレーでメソッドに値の受け渡しが不要になります
AndroidCompositionLocalsでもすでに便利な定義がされています

```Kotlin:AndroidCompositionLocals.android.kt
/**
 * The Android [Configuration]. The [Configuration] is useful for determining how to organize the
 * UI.
 */
val LocalConfiguration = compositionLocalOf<Configuration> {
    noLocalProvidedFor("LocalConfiguration")
}

/**
 * Provides a [Context] that can be used by Android applications.
 */
val LocalContext = staticCompositionLocalOf<Context> {
    noLocalProvidedFor("LocalContext")
}

internal val LocalImageVectorCache = staticCompositionLocalOf<ImageVectorCache> {
    noLocalProvidedFor("LocalImageVectorCache")
}

/**
 * The CompositionLocal containing the current [LifecycleOwner].
 */
val LocalLifecycleOwner = staticCompositionLocalOf<LifecycleOwner> {
    noLocalProvidedFor("LocalLifecycleOwner")
}

/**
 * The CompositionLocal containing the current [SavedStateRegistryOwner].
 */
val LocalSavedStateRegistryOwner = staticCompositionLocalOf<SavedStateRegistryOwner> {
    noLocalProvidedFor("LocalSavedStateRegistryOwner")
}

/**
 * The CompositionLocal containing the current Compose [View].
 */
val LocalView = staticCompositionLocalOf<View> {
    noLocalProvidedFor("LocalView")
}
```

# 独自の値を設定することも可能
SharedPreferencesなどいちいち定義するのが面倒なものもここに設定することでCompose側からならどこでも利用できるようになります

```Kotlin:SampleTheme.kt
@Composable
fun SampleTheme(
    content: @Composable () -> Unit
) {
    val preferences = LocalContext.current.getSharedPreferences("prefs", Context.MODE_PRIVATE)
    CompositionLocalProvider(
        LocalPreferences provides preferences
    ) {
        MaterialTheme(
            content = content
        )
    }
}

val LocalPreferences = staticCompositionLocalOf<SharedPreferences> {
    error("error hogehoge")
}
```

# メリット
- 無駄なバケツリレー回避
- 子コンポーネントのみ定義のオーバーライドをすることも可能
- コンポーネントの再利用性の向上

# デメリット
- 可視性が低いため、複数の子コンポーネントで値の変更をしすぎるとデバッグ困難、コードの難読化が発生
- 過剰利用によるアーキテクチャの崩壊
- 大きなComposeツリーで利用することによるパフォーマンスの低下

# おわり
あくまでもこれはComposableで使うものに限定することを強くおすすめします！
きれいなコード、きれいな設計を一発で台無しにする可能性を孕んでいるものです
用法用量を守って正しくお使いください
BeyoundCompare シンボリックリンクをリモートへコピーする方法

- BeyounCompare: v4.4.7
- **参考サイト**： https://rschu.me/beyond-compare-symbolischen-links-folgen-6df1b3f8785a
# 【**これを書くに至った経緯**】
<br>
ローカルからリモートへシンボリックリンクをコピーする必要があったため、
コピーを実行したところ、

***'SITE SYMLINK' not understood***

上記のエラーが出てコピーができなかった。
<br>


# **【解決策】**

<br>
Beyond Compareのデフォルト設定では、シンボリックリンクをたどることができず、設定を変更することで解消できるとのこと。
<br>
<br>

①**BeyounCompare ホームのセッション欄から該当のセッションを選択。**

②**編集ボタンをクリック**

③**取扱いタブを選択**

④"**シンボリックリンクを辿る**"**のチェックボックスをチェックし保存**

このオプションにチェックを入れると、シンボリックリンクを通常のファイルやディレクトリと同様に扱い、リンク先を追跡してコピーすることができる
Gitを触ったことのないエンジニアがヤバいと言われる理由を考えた

## これは何?

TwitterでGitをさわったことのないエンジニアがヤバイという発言が物議を醸していたのでなぜヤバイと言われるのかを考察しました。

## 考えられる理由

### 業界標準への理解が低い/業界の大局を追えていないように見える

現代のソフトウェア開発のバージョン管理のデファクトスタンダートがGitです。
基本的には，Gitリポジトリのホスティングサービスである，GitHubやGitLabを使うパターンが多く，こういったサービスを使うことで現代の開発フローは実現されていると思います。
そのため，Gitを使ったことがないと業界のお作法的なものができていないと思われてしまう可能性があると考えられます。

### 最新技術へのアンテナが低そうに見える

現代のOSSのほとんどがバージョン管理にGitを使用しており，GitHubやGitLabにソースコードを公開しているパターンが多いです。。そのため，OSSのコントリビュータになるにはGitを使える必要があり，Gitを使ったことがない=OSSのコントリビュータになる気がゼロということがわかってしまいます。(コントリビュータになれと言っているわけではない)
また，OSSのツールをダウンロードするだけらなzipとしてダウンロードできるので，Gitを使うのがMUSTではないですが，Gitのコマンドを使ったほうがより効率的だと思います。

---

## なぜ，今回の騒動になったのか

### 反対派の意見

Gitを使うべきもっともらしい理由を書いてみましたが，反対派もいるようです。
反対はの意見を見ると

- 会社で使わないから
- Gitでなくても代替できる

といった意見が多かったのかなと思います。

### 主語がデカすぎる。主語はエンジニアではなく開発者であるべき

エンジニアと言ってもいろいろな職種があり，上記のGitを使っていないとヤバいとい思われてしまう理由はすべて開発者に求めるスタンスだと思います。

ここからは完全に私見なのですが，開発者は最新技術に対してオープンマインドであるべきです。
開発者は新しいものをガンガン試している人が多くこれによって日々プロダクトの品質が上がったり，生産性が向上しているのだと思います。

そのため，開発者にはとりあえず使ってみる精神が求められているのだと考えられます。
Gitを使ったけど，プロダクトにマッチしていなかったので別のツールに使うという選択肢はアリなのかなと。
実際に大人気ゲームパルワールドをリリースしたポケットペアでは開発の途中でGitからSVNに移行しています。
[3日後に運命が決まる，パルワールドという偶然の物語](https://note.com/pocketpair/n/n54f674cccc40)

つまり，業界標準のGitを試していないマインドが，開発者として良くないのだと思います。これには私も賛成です。

ですが，エンジニアにも開発者以外の職種もあり，Gitを学習する優先順位が低いならGitを知らなくても良い人たちがいるのでそういう人をひとくくりにしてヤバイというのは間違っているのかなと思います。

---

## 追記: 就活の際にGitは求められるか

エンジニアという主語がでかいのは先程も書きましたが，人によってはGit使ったこと無いエンジニアはエンジニアにあらずみたいな差別をする人はいるのかなと思います(特に，駆け出しエンジニアに対して多い印象)。
また，会社によってはGitを使えることを必須条件にしている場合もあります。
もし，あなたが求職中ならば，ちょっとでもGitを触っておくのが無難だと思います。


---

## 総括

- エンジニア全員がGitを使える必要はない
- 開発者として活躍したいのであれば，Gitを全く触らないのは開発者マインドとしては微妙だと思う。
- 就活中/転職中ならGitを触っておくのが無難。
- Git使いたくなったら，この記事が良さそうだったのでこれをよむところから始めてもいいのかも↓(私の記事ではないですが)

https://qiita.com/yamadagenki/items/5e4ee79a7a680b1675e8
【ChatGPT＋Code Interpreter】で行なえるPDFの操作のまとめです。


　どうも、カーブミラーです。

　今回は、
　　PDFの操作のまとめです。

:::note info
本記事は、ChatGPT（有料版）
で行なっております。画像は
ありません。　あしからず。
:::

　まずは、ニュースです。

　ChatGPTの
　　週間アクティブユーザー数が
　　　2億人に達したそうです。

「ChatGPTのアクティブユーザー数は2億人に」──OpenAI Japan代表が公表　次世代モデル「GPT Next」にも言及
　[ITmediaNEWS AI＋](https://www.itmedia.co.jp/aiplus/spv/2409/03/news165.html)

　GPT Nextについては
　　サム・アルトマン氏も
　　　「今年中に公開する」旨を
　　　　　インタビューの中に。
　　　　　　ソース元がどこだか失念😅
***
　さて、本題です。

　今回は、PDFのまとめです。

　はい、PDFに関しては、
　　とりあえず終了です。

　これまで
　　PDFの操作をやってきました。

　　　[PDFを作成](https://qiita.com/kabumira/items/267bc681ee1909ded1c5)
　　　[PDFの連結](https://qiita.com/kabumira/items/b4202886594392fabcc4)
　　　[ページ抜き出し](https://qiita.com/kabumira/items/8f6a91cd3f8684b47f5f)
　　　[ページ分割](https://qiita.com/kabumira/items/b1e978d29a97bcd8badb)
　　　[ページ削除](https://qiita.com/kabumira/items/9ad69ded601248e2e76e)
　　　[ページ挿入](https://qiita.com/kabumira/items/84c09e3cf983d0fbecf9)
　　　[PDFファイル概要情報の取得](https://qiita.com/kabumira/items/66d0e683a61bbaada863)

　途中からPromptの記述が
　　変わっています。

　これは
　　うまくCode Interpreterが
　　　動いてくれなかったからです。

　“CodeInterpreterで”の記述を、
　　して欲しいことのあとに
　　　まわして、確実に実行を
　　　　してもらいます。

　ちなみに
　　日本語を
　　　PDFに含めて作成する際は
　　　　日本語フォントが必要に
　　　　　なります。

　こちらを
　　参照してください。
　　　[【ChatGPT＋Code Interpreter】で日本語の描画をします。](https://qiita.com/kabumira/items/7c25ca6ac0d1bc2c1f85)
***
　さて、
　　PDFの操作が終わったのですが、
　　　次はどうしましょうか？
　　　　実はまだ決まっていません😅

　構想はあるんですけど、
　　画像の認識で、止まってしまって
　　　解決策を見出だせていない
　　　　状態です😅

　ほかのツールを使えば
　　解決する問題なんですけど、
　　　それはそれで、負けた気がして😅

　ChatGPT＋Code Interpreterで
　　どこまでできるのか、を
　　　やってますからねぇ😸

　みなさんの
　　作品制作の糧に
　　　なれば、幸いです。

　今回は、ここまで。
Blank()と空白""の違い

# 困った点
powerBI serviceからDirect Queryでデータを取り込みグラフ化しようとしたが、以下のエラーが発生
OLE DB or ODBC error

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3679578/a62ff280-0c62-d650-ac0e-b59cba5a4fe7.png)

このエラーは型の不一致が起こるために発生しているようです。
- DAX式
```
sample_dax = 
SWITCH(
    TRUE(),
    SELECTEDVALUE('Table'[column1])="abc",100,
    ""
)
```
元のPowerBIでは上記の式でグラフ化できたが、Direct Queryを用いて新たなBIでグラフ作成するとき、エラーが発生してグラフが表示されなかった。

# 原因
- 型の不一致
この式は本来数字を返さないといけないが、空白""を返すと文字列と認識されるので、型の不一致が発生した。


# 解決策
- DAX式(改善後)
```
sample_dax = 
SWITCH(
    TRUE(),
    SELECTEDVALUE('Table'[column1])="abc",100,
    blank()
)
```
空白""の代わりにblank()を使用した。0でも可。ただしグラフに線が表示されることになる。それを避けるためにblank()を使用。
EC2インスタンス内のMySQLにSSHを通じて接続する手順

## アジェンダ
Ubuntu環境でEC2インスタンス内のMySQLにSSHを通じて接続する方法を簡潔にまとめます。

## 手順
### 1. SSHでEC2インスタンスにログイン
まず、SSHを使用してEC2インスタンスにログインします。

```bash
ssh -i "your-key.pem" ubuntu@your-ec2-public-ip
```

### 2. MySQLクライアントがインストールされているか確認
ログイン後、MySQLクライアントがインストールされているか確認します。以下のコマンドを実行してみてください。

```bash
mysql --version
```

もしMySQLクライアントがインストールされていない場合は、次のコマンドでインストールします。

```bash
sudo apt update
sudo apt install mysql-client -y
```

### 3. MySQLに接続する
次に、MySQLサーバーに接続します。以下のコマンドを使用して、MySQLに接続できるか確認します。

```bash
mysql -u your-username -p
```

`your-username` の部分にはMySQLのユーザー名を入力します。プロンプトが表示されたら、MySQLのユーザーのパスワードを入力してください。

### 4. データベースを確認する
接続に成功すると、MySQLシェルに入ります。ここで、データベースの一覧を表示することで、接続が正しく行われたかを確認できます。

```sql
SHOW DATABASES;
```

### 5. 接続を終了する
作業が完了したら、MySQLシェルから退出します。

```sql
EXIT;
```
EC2インスタンスにMySQL DB インスタンスをインストール、接続

## アジェンダ
プライベートサブネットに配置したEC2インスタンスにMySQLをインストールし、Webサーバーインスタンスから接続可能な状態を整える手順を、要点を押さえて備忘録として残します。

## MySQL DB インスタンスをインストール
インストール方法は、以下の記事を参考の手順通りに行なって下さい。

https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/CHAP_GettingStarted.CreatingConnecting.MySQL.html

## SSH接続の設定
ローカルマシンで、インスタンス作成時にダウンロードしたキーペア（.pemファイル）を使用します。
以下のコマンドでSSH接続を行います。

```sh
ssh -i "your-key.pem" ec2-user@your-ec2-public-ip
```
例:「キーペアがtest-key.pemでUbuntuでパブリックIDが13.235.246.234の場合」

```sh
ssh -i "test-key.pem" ubuntu@13.235.246.234
```

## Ubuntu上でのMySQLインストール手順
以下の手順で、Ubuntu上でシステムをアップデートし、MySQLサーバーをインストールできます。

### 1. パッケージリストの更新

まず、パッケージリストを最新の状態に更新します。

```bash
sudo apt-get update
```

### 2. システムのアップグレード（任意）

システム全体を最新の状態にアップグレードするには、以下のコマンドを使用します。

```bash
sudo apt-get upgrade -y
```

### 3. MySQLサーバーのインストール

次に、MySQLサーバーをインストールします。

```bash
sudo apt-get install mysql-server -y
```

### 4. MySQLサーバーの起動と自動起動の設定

インストールが完了したら、MySQLサーバーを起動し、自動起動を設定します。

```bash
sudo systemctl start mysql
sudo systemctl enable mysql
```

### 5. MySQLの初期設定

次に、MySQLのセキュリティ設定を行います。

```bash
sudo mysql_secure_installation
```

## 参考
- [MySQL DB インスタンスの作成と接続 - Amazon Relational Database Service](https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/CHAP_GettingStarted.CreatingConnecting.MySQL.html)
- [RDS MySQLを作成し、クエリーしてみた | DevelopersIO](https://dev.classmethod.jp/articles/lim-rds-mysql/#toc-1-rds)
InfluxDBをバックアップ・リストアする

# 概要
InfluxDBのバックアップ・リストア手順です。
InfluxDBはコンテナで動作していることを想定しています。

[ドキュメント](https://docs.influxdata.com/influxdb/v2/reference/cli/influx/backup/)を確認するとバックアップ方法は2つのようです。
差分・増分バックアップの方法は確認できませんでした。
* すべてのデータをバックアップする
* 特定のバケットをバックアップする

本手順では、すべてのデータをバックアップする方法を紹介します。

# 環境
本手順で取り扱う内容は、次の環境にて確認しています。

マシン：Amazon EC2
OS：Ubuntu 24.04
Docker：27.2.0
Docker Compose：v2.29.2
influxDB：2.7.10
コンテナイメージ：[bitnami/influxdb](https://hub.docker.com/r/bitnami/influxdb)

# InfluxDBバックアップ

> **注意事項**  
> バックアップを取得する前に、アプリケーションを停止して下さい。

バックアップを取得します。
※influxdbのコンテナ名は、本手順では`influxdb`としています。
```
$ docker compose exec influxdb influx backup /tmp/`date +%Y%m%d`/ -t <admin_user_token>
```

バックアップを格納するディレクトリが無い場合は作成することをお勧めします。
```
$ mkdir backup
```

バックアップデータをホストマシンのバックアップ格納用ディレクトリにコピーします。
```
$ docker compose cp influxdb:/tmp/`date +%Y%m%d`/ ./backup/`date +%Y%m%d`
```

バックアップファイルの権限を変更します。
非rootコンテナであるbitnamiのコンテナイメージを利用している都合上、このような操作が必要になります。
```
$ sudo chown 1001:root -R ./backup/`date +%Y%m%d`
```

コンテナ上のバックアップファイルを削除します。
```
$ docker compose exec influxdb rm -fr /tmp/`date +%Y%m%d`/
```

# InfluxDBリストア

バックアックファイルをコンテナにコピーします。
`<YYYYMMDD>`の箇所は、戻したい日付を指定して下さい。
```
$ sudo docker compose cp ./backup/<YYYYMMDD> influxdb:/tmp/
```

リストアを実行します。
```
$ docker compose exec influxdb influx restore -t <admin_user_token> --full /tmp/<YYYYMMDD>/
```

後片付けとして、コンテナ上に残っているバックアップファイルを削除します。
```
$ docker compose exec influxdb rm -fr /tmp/<YYYYMMDD>/
```

# 参考
https://docs.influxdata.com/influxdb/v2/admin/backup-restore/
https://docs.influxdata.com/influxdb/v2/reference/cli/influx/backup/
https://hub.docker.com/r/bitnami/influxdb
eclipseメモ

```

★検索関連
ソース検索   cstr shift R
文字列検索   cstr H

★ブランチ関連
eclipseの場合、右上のGitをクリックする。表示しない場合、Git表示するように設定。
左のGit＞ブランチ＞ローカル

master＞右クリック＞チェックアウト
eclipse>xxxxxx.git>右クリック

プル(U)
プル
上記どっちでもいいです、ただ確認画面が違います。
プル  サーバの最新ソースを取得、ローカルへ反映。
修正作業前は必ず実施、最新のソースベースに修正する

例：eclipse>xxxxxx.git>右クリック>プル

◇チェックアウト
master branch＞右クリック＞チェックアウト
◇ブランチ作成
master branch＞右クリック＞ブランチ作成
名前は現場のルールに確認する

★メモリ拡大
eclipse.ini 編集

-Xms512m

-Xms1024m

再起動

メモリ確認

windows ＞設定＞一般＞ヒープステータスを表示   チェック
BizRobo! Webブラウザ操作でのHTML要素指定の考え方

## はじめに
ビズロボでブラウザ操作をする際によく用いるファインダーの指定についてです。

ブラウザでのクリック操作、入力、抽出などでよく使用しますが、
設定で迷うことが多くあります。

今回はファインダー設定についての考え方を共有していきます。

<br>
ファインダーはプロパティのファインダータブより設定が可能です。

![6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3291018/91be0928-2d3e-7a51-d09d-b6501ee4a8ab.png)



## 大前提
ビズロボを運用していると、ロボ内でアクセスしているサイトの画面（UI）が変わることでエラーが発生することが出てくると思います。
その際に、大きく考え方が2つあるのではないかと思います。

### 1.画面構造が変わった際にはすぐにエラーとなるように作成しておく
画面構造が変わっても、ファインダーの指定方法によっては、<br>エラーなく通過することもありますが、意図しない操作を防ぐためにできるだけ画面構造が変わった際にはエラーを出すという考え方があると思います。
<br>
### 2.大幅な画面変更がない限り、できるだけエラーが発生しないように作成しておく
一方で画面構造が変わったとしても、<br>できるだけエラーを発生させないように作成する考え方です。<br>改修の工数がかからず保守性が高いといえます。<br>
特にログイン画面など画面構造が変わったとしても行う処理には変更が起こらないものに関しては、こちらのできるだけエラーを発生させないようなファインダーの設定が良いと考えています。
<br>

## ファインダーの大まかな設定箇所
### 1.検索範囲
画面内での任意の場所か特定の範囲（名前付きタグ）から検索をするかを指定します。

![8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3291018/d973e836-998b-0aaa-e298-2b3b24caa08b.png)

基本的にはページ内の任意の場所としておりますが、
id指定やパターン一致で一意の値の検索が難しい場合は、<br>範囲指定をしたうえで特定のタグを検索する名前付きタグを指定するような使い方をしております。


### 2.タグ パスおよび属性名・属性値
HTML構造での検索条件となります。
下記画像のようにタグ パスおよび属性を用いて特定のタグを検索します。
id属性（ページ内で一意の値)がある場合には設定しやすいですね。

![17.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3291018/3bcd88bf-fd16-d851-c382-4a85bbec50ac.png)

<br>
<br>
id属性がない場合に関しては、classやパターン一致を用いて指定をします。

:::note info
classやname属性で指定をする場合には、
一意の値ではないということを念頭に置き、
名前付きタグで範囲指定を行うもしくは、
下記画像のように要素にインデックスを付けて指定します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3291018/47fa4145-b16e-a477-3322-a1596c9e3861.png)
:::

<b>※インデックスを付ける場合には、<br>画面構造に変更があった場合に修正が必要となりますが、
IDとPWのように順番が基本的に入れ替わることがない場合については、インデックスでの指定をしております。</b>



### 4. タグパターン

主に取得したい要素のテキストと一致するものを検索する場合に使用することが多いです。
class名指定では同じページ内に複数ある可能性があるため、class名とタグパターンを組み合わせることで検索処理の精度を上げることができます。

![11.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3291018/57a9c3b3-0466-76cb-0c88-b4456fa99fbc.png)


## 最後に

ファインダー設定については、
HTMLの理解、そして保守性を意識した設定が大切になります。

また、ファインダー設定の方針をメンバー内で認識を合わせていくことで、
その後の改修対応がスムーズに進みます。

ステップ一つひとつの処理に対して、
丁寧に設定することでより良いロボットになっていくと考えています。



<br>
最後まで見ていただきありがとうございました。