OmniAICreator/Qiita-1.07M huggingface dataset:
【Python】pyautogui入門 -定型作業を自動化してみる-

# 概要

メルカリで行う定型作業の自動化をする際にSeleniumを用いた自動化を行おうとした。
しかし規約違反スレスレの行為でもあり、WebDriverからのアクセスは0秒でバレることを知ったため断念。

そこで普段の定型作業がキーボードとマウスをいじるだけの簡単なものだったため、opencvによる画像認識とpyautoguiを用いて作業の自動化を試みた。

# 目的

- pyautoguiで定型作業を自動化する

# 対象の動作
## 動作内容

商品を値上げした後、値段を戻すことでタイムライン上部に表示させる。

## フロー

- 現在のページからGoogle Chromeへ移動
- 商品の編集押下
- 商品の値段の末尾を一桁増やす(300円→3,000円)
    - 更新
- 商品の値段の末尾を一桁減らす(3,000円→300円)
    - 更新
- ページを閉じる

## この作業の意味

メルカリでは商品の値段を100円以上下げると、**タイムライン上部に商品が表示される**ようになる。

タイムライン上部に表示される = 売れる確率の上昇 に繋がっており、メルカリで商品を売買する身としては必須の操作です。

## 注意点

投稿者の画面解像度が4Kなので、他の画面解像度では正しく動作しない可能性があります。

# コード

``` source.py
import time
import pyautogui as pgui

# Google Chromeへ移動する
def go_page() -> None:
    pgui.keyDown('alt')
    pgui.press('tab')
    pgui.keyUp('alt')


# 指定した画像をクリックする
def click_image(image_path: str) -> tuple:

    try:
        locate : tuple = pgui.locateOnScreen(image_path, grayscale=True, confidence=0.7)
        pgui.click(locate, duration=0.5)
        return locate

    except pgui.ImageNotFoundException:
        pgui.alert(text='画像が見つかりません', title='エラー', button='OK')


# main
def main():

    # 編集画面へ遷移する
    click_image('./image/syouhinnnohensyuu.png')
    time.sleep(5)

    pgui.press('end')
    time.sleep(2)

    # 価格を一桁減らす
    click_image('./image/hanbaikakaku.png')
    pgui.press('end')
    pgui.write('0')
    pgui.press('enter')
    time.sleep(3)

    # 編集画面へ遷移する
    click_image('./image/syouhinnnohensyuu.png')
    time.sleep(5)

    pgui.press('end')
    time.sleep(2)

    # 価格を一桁増やす
    click_image('./image/hanbaikakaku.png')
    pgui.press('end')
    pgui.press('backspace')
    pgui.press('enter')
    time.sleep(3)

    # ページを閉じる。
    pgui.hotkey('ctrl', 'w')

if __name__ == '__main__':

    page_count = input('実施件数を入力してください >>> ')
    go_page()

    for _ in range(int(page_count)):
        main()

```

# ファイル構成

``` cmd

│   source.py
│   
└───image
        hanbaikakaku.png
        syouhinnnohensyuu.png

```

# その他

> github → https://github.com/Suntory-Y-Water/start_pyautogui
LPIC Level1 101受験体験記

# 初めに

初めまして。インフラエンジニアとして働いていますcoffee_cafe と申します。QiitaにAWS認定資格の受験体験記を投稿していましたが、今回は最近取得したLPIC Level1 101の記事を投稿しようと思います。

前回記事
(CLF編)：https://qiita.com/coffee_cafe/items/2603d9f658380ab6c3d3
(SAA編)：https://qiita.com/coffee_cafe/items/3e5f19405928434e3d4c
(SOA編)：https://qiita.com/coffee_cafe/items/63bcb8d8a4ee6ed25249

# 受験前の状態
実務でLinuxサーバを操作することは無くもないですが、せいぜいgrepコマンドでSyslogを覗いたりする程度。lsやcdなど超基本的なコマンドは知っていますが、Linuxサーバの構築や運用経験はなくほぼ初心者といってもいい状態でした。

# 勉強期間
約半年ほどチマチマと学習をしていましたが、実質的な学習期間は1か月ほどです。

# 学習方法
まずは下記の初学者向けテキストを読み、Linuxの基礎から学びました。こちらのテキストは試験範囲から初学者向けにポイントを絞ってコマンドなどを掲載しているので、本誌だけでは合格は難しいと思いますが、Linux素人にも分かりやすく噛み砕いた解説が載っていますので初心者の方はまずはこの本から手を付けることをお勧めします。

[1週間でLPICの基礎が学べる本 第3版 徹底攻略シリーズ](https://www.amazon.co.jp/1%E9%80%B1%E9%96%93%E3%81%A7LPIC%E3%81%AE%E5%9F%BA%E7%A4%8E%E3%81%8C%E5%AD%A6%E3%81%B9%E3%82%8B%E6%9C%AC-%E7%AC%AC3%E7%89%88-%E5%BE%B9%E5%BA%95%E6%94%BB%E7%95%A5%E3%82%B7%E3%83%AA%E3%83%BC%E3%82%BA-%E4%B8%AD%E5%B3%B6%E8%83%BD%E5%92%8C-ebook/dp/B07TD1TTYJ/ref=sr_1_3?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&crid=2Z444VURZ0LBD&keywords=lpic+%E3%81%AF%E3%81%98%E3%82%81%E3%81%AE%E4%B8%80%E6%AD%A9&qid=1679877574&s=digital-text&sprefix=lpic+%E3%81%AF%E3%81%98%E3%82%81%E3%81%AE%2Cdigital-text%2C234&sr=1-3)

つづけて、所謂「あずき本」に手を付けました。掲載されているナレッジが非常に多く、受験後も辞書として使っていけるところは良い点かと思います。ただ、個人的にはどの箇所を覚えればよいのか判別ができず、ポイントを絞った学習ができないと判断し、途中で読むのは頓挫してしまいました・・

[Linux教科書 LPICレベル1 Version5.0対応](https://www.amazon.co.jp/s?k=Lpic+%E3%81%AF%E3%81%98%E3%82%81%E3%81%AE&i=digital-text&__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&crid=2Z444VURZ0LBD&sprefix=lpic+%E3%81%AF%E3%81%98%E3%82%81%E3%81%AE%2Cdigital-text%2C234&ref=nb_sb_noss)

あずき本から切り替えて、最後は以下「白本」ベースで学習をしました。本誌は試験対策に特化しており、実試験の再現性が高い問題が掲載されていました。

[Linux教科書 LPIC レベル1 スピードマスター問題集 Version5.0対応 ](https://www.amazon.co.jp/Linux%E6%95%99%E7%A7%91%E6%9B%B8-LPIC-%E3%83%AC%E3%83%99%E3%83%AB1-%E3%82%B9%E3%83%94%E3%83%BC%E3%83%89%E3%83%9E%E3%82%B9%E3%82%BF%E3%83%BC%E5%95%8F%E9%A1%8C%E9%9B%86-Version5-0%E5%AF%BE%E5%BF%9C-ebook/dp/B07TVTKW2C)


# 受験結果
スコ720点で合格することができました。

# 感想
・Lpic Level1 101は予想以上に暗記が必要なコマンドやオプションが多く、世間の評判以上に難易度が高く感じた。
　⇒ひたすらコマンドやオプションを覚える必要があるので、私にように単純暗記が苦手な人は苦戦するかもしれない。
・白本からは類題が多数出題された。
　⇒試験対策に特化した勉強をするならば、白本オンリーでもいいかも。
　⇒体系的に学びたいのであれば、あずき本を辞書代わりにして読むとよいです。
・正規表現やLinuxを操作する上で最低限知っておくべきコマンドが出題されるので、実務でLinuxの運用・構築をする人や今後担当する予定がある人は必ず取得することをお勧めします。
GASで「指定のURL」の検索結果をSpreadSheetに一覧記載

# 概要
特に外向けに難しいことを発信しようとしたわけでもなく、今後もたまに使いそうだと思った、GASのスクリプトを備忘しておきます、みたいなシリーズのその３。

# 「指定のURL」の検索結果をSpreadSheetに一覧記載

```javascript
function searchAndExportToSpreadsheet() {
  // APIキーとSearchEngineIdを記載
  const apiKey = '（GoogleCloudPlatformで取得のAPIキー）';
  const searchEngineId = '（検索エンジンID）';

  // 検索文字列入れる
  const query = '（検索したい文字列）';

  // SSは新しく作ってしまう
  const ss = SpreadsheetApp.create('Search Results for ' + query);
  const sheet = ss.getActiveSheet();
  sheet.appendRow(['Title', 'URL', 'Snippet']);

  // 取得したいページ数÷10で繰り返し（今回は200件分）
  for (var i = 0; i < 20; i++) {
    let start = i * 10 + 1;

    // 検索APIのURL類似検索結果も対象にするのでfilter=0
    let url = 'https://www.googleapis.com/customsearch/v1?';
    url += 'key=' + apiKey + '&cx=' + searchEngineId + '&q=' + encodeURIComponent(query) + '&start=' + start + '&filter=0';
    let response = UrlFetchApp.fetch(url, { method: 'GET', muteHttpExceptions: true });
    let json = JSON.parse(response.getContentText());

    // 検索結果チェック
    if (!json.items || json.items.length === 0) {
      break;
    }

    // 検索結果ごとに、SSに項目追記
    json.items.forEach(function (item) {
      sheet.appendRow([item.title, item.link, item.snippet]);
    });
  }

  // 作成したSSのURLをログ出力
  Logger.log('Search results spreadsheet created: %s', ss.getUrl());
}

```

# 終わり

すいません、ChatGPTに外注して作らせました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215128/c8052233-3884-25a7-eb46-7cfb80f4e46a.png)

この程度なら、スクリプト書いてる間に人の手でやったほうが早い説もある。質問投げてるだけでちょっとずつチューニングしてくれるのは楽というところか。
Watson Query SaaS版とWatson Knowledge Catalog SaaS版の連携設定

[Watson Query](https://cloud.ibm.com/catalog/services/watson-query)は、データの物理的なフォーマットや場所を理解する必要がなく、データを移動させることなくアクセス、操作(=[データ仮想化](https://qiita.com/nishikyon/items/ef2d60b4687b8a6c3e39#1-%E3%83%87%E3%83%BC%E3%82%BF%E4%BB%AE%E6%83%B3%E5%8C%96))、分析を可能にするIBMCloudのSaaSのサービスです。

[Watson Knowledge Catalog](https://cloud.ibm.com/catalog/services/watson-knowledge-catalog)と連携することで、仮想化の際にビジネス用語を列名に割り当てができたり、テクニカルプレビューですが、メールアドレスなどの個人情報などみせたくない情報のマスキング処理などができます。

どちらのサービスもSaaS版にはLiteプランがあり、無料でお試し可能です。

この2つサービスを連携させるにはSW版では何もしなくてもよいのですが、SaaS版の場合は設定が必要です。また、2つのサービスは同じリージョンで作成する必要があります。

当記事はWatson Query SaaS版とWatson Knowledge Catalog SaaS版の連携させるための設定について記載します。

ちなみにドキュメントだと[このあたり](https://dataplatform.cloud.ibm.com/docs/content/dvaas/dvaas-catalog.html?context=analytics&audience=wdp)に書いてある内容です。

# 0. 前提
- [Watson Query](https://cloud.ibm.com/catalog/services/watson-query)のインスタンス作成済み
- [Watson Knowledge Catalog](https://cloud.ibm.com/catalog/services/watson-knowledge-catalog)のインスタンスが**WatsonQueryと同じリージョンに**作成済み

# 1. Cloud Pak for Data servicesにログイン
ログインURLはリージョンによって異なります。
不明の場合は[IBM Cloudのコンソール](https://cloud.ibm.com/)のリソースリストからWatson Queryのインスタンスの詳細を開いて、「Launch in IBM Cloud Pak Data」ボタンをクリックして、 Cloud Pak for Data servicesダッシュボードを表示してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/9f7ad3ec-08d1-aeae-13a2-fd1ad67f1a19.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/584e5ebc-62c5-8723-2d40-5ff67d9fdcfc.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/1cc40708-6dc0-204d-8454-57a5408fbc71.png)

# 2. 個人の資格情報を有効にする
2-1. 右上のナビゲーションメニュー(≡)をクリックし、「管理」→「アカウントと請求」→「アカウント」を表示します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/f3ba866d-c971-d0bf-228a-221ed825420a.png)

2-2. 「接続の資格情報」の「個人の資格情報」を有効にします
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/84bd0d6c-cd6e-bb11-d6c6-943c47a1d25a.png)

# 3. Watson Knowledge Catalog サービスに、 Watson Query インスタンスのデータへのアクセスを許可

3-1. Watson Knowledge Catalog インスタンスと Watson Query インスタンスがプロビジョンされている [IBM® Cloud アカウントにログイン](https://cloud.ibm.com/)し、ダッシュボードを表示します。

3-2. 上部メニューから、 「管理」 → 「アクセス (IAM)」 → 「許可」を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/b371fd4a-dc2f-d4a3-0328-fe54f16dfc07.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/80a38481-ada4-a754-a141-60d51fa8512c.png)

3-3. 「作成」をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/dc6cb7d2-89bb-db96-0bef-9d59b665ef5d.png)


3-4. 「ソース・サービス」 として `Watson Knowledge Catalog` を選択し、 「ターゲット」・サービスとして `Watson Query` を選択します。
3-5. 「サービス・アクセス」の「DataAccess」にチェックを入れます。
3-6. 「許可」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/d111e8fb-a929-f1dd-b6e7-7f9409a6b0ef.png)

3-7. 設定した許可が「表示されていることを確認します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/294516/b296e93b-04d1-ba1c-f1b2-0d06808549c0.png)

以上です。
これでWatson QueryとWatson Knowledge Catalogは連携されます。
【ruby】win10での環境構築【rails】

# ruby on railsの環境構築

### この記事を書いた理由
AWSのcloud9から、自分のパソコンへ環境を移行しようと思ったのがきっかけ。
インスタンス起動してるとその分、お金がかかるので。

その過程をお届けします。

git からクローンしたアプリを
rails sしても、webpackerのエラーで悩まされた。
一日中、GPT先生にエラー内容を片っ端から解説してもらっていた。

もちろん、
```
bundle install
rails db:migrate
yarn install
rails webpacker:install
```
など、一通りコマンドをうちましたよ。

原因はnode.jsのバージョンが18だったことが原因でした。
結論から言うと、16系のバージョンが必要だった。

rails new　して作成したアプリも、エラーが出てくる。
gemファイルの、
```
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]
```
でエラーを起こしていた。いろいろ記事を調べたら、

``` 
, platforms: [:mingw, :mswin, :x64_mingw, :jruby]
```
この部分を消せばエラー解消できるようだったので、消したら、確かにエラーは解消された。


https://qiita.com/tatama/items/3f0f5e42cb5f75b53817




## progateの手順で実行

https://prog-8.com/docs/ruby-env-win


ruby version 3
 
## railsの環境構築

https://prog-8.com/docs/rails-env-win

rails vesion 6

## sqlite3
以下のコマンドをcmdに入力。
```
gem install sqlite3
```

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

上のリンクから、以下の２つをダウンロード

![無題sql.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3084646/60dbc9a5-db7c-0dc6-a4dc-bb3a1f2e9416.png)

### 展開(解凍)する
「sqlite3.dll」をRubyをインストールしたディレクトリの「bin」ディレクトリに移動する。

すべてのファイル「.exe」3つをRubyをインストールしたディレクトリの「bin」ディレクトリに移動する。
![無題db.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3084646/6830e27a-380d-d11f-9483-1301bfb46926.png)




## node.js

https://nodejs.org/en/blog/release/v16.14.2

![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3084646/9fa761d2-59a2-c654-82e8-fdbcaf422ca5.png)


node -v
versionが16系ならOK


## yarn

https://classic.yarnpkg.com/en/docs/install#windows-stable

Download the installer　からmsiをダウンロードしてインストール。

yarn -v
1.22(現在のバージョン)


## サーバーを立てる
rails s



## 参考にした記事

https://qiita.com/AoiLaurent/items/0b3b5f41fbd143bfa563
Nuxt3をSSGモードでCloudflare Pagesにデプロイする

昨年11月頃、Nuxt3がリリースされました。しばらく時間が経ちましたが、SSGモードでホスティングサービスにデプロイする方法が載った記事が少なく苦労したので、今回備忘録として筆を執ることにしました。

リポジトリのリンクも貼っておくので是非そちらも参考にしてください。

https://github.com/newt239/newt239.dev

なお、この記事はローカルでの開発は終わり、デプロイ直前の段階まで済んでいることを前提とします。

## バージョン

```
Nuxi 3.3.2
Nuxt 3.3.2 with Nitro 2.3.2
```

## Nuxt側の設定

`nuxt.config.ts` で、最低限以下の記述が含まれているか確認してください。

```typescript:nuxt.config.ts
export default defineNuxtConfig({
  ssr: true,
  target: "static",
});
```

このように設定することで、ビルド時に必要に応じてAPIリクエストなどを行った上で静的ファイルを書き出してくれます。

ビルド時に行ってほしい処理は `<script>` タグ内に直接書いてください。`onMounted` フックなどの内側に書き、フロントエンドで外部のAPIにリクエストを投げようとするとCORSエラーが発生します。他の記事を見てみると`server`ディレクトリにリクエストを記述する[^1]という解決方法が説明されていますが、これはSSRでのみ有効です。Cloudflare PagesではSSRはできないため `server` ディレクトリは使えません。

なお、動的ルーティングを行っている場合はデプロイ時にすべてのページをビルドさせるために別途設定が必要です。まだ実験的な機能のようですが、以下の記事などが参考になると思います。

https://zenn.dev/kon_karin/articles/0e514dea329044

ただし、`@nuxt/content` を使って動的ルーティングを行う場合は特に設定しなくても生成してくれるようです。

## Cloudflare Pagesの設定

https://developers.cloudflare.com/pages/framework-guides/deploy-a-nuxt-site/

基本的には上記リンクの通りで問題ないと思います。

まず、環境変数に

- 変数名: `NODE_VERSION`
- 値: `17`

を設定し、「ビルドの構成」を以下のようにしてください。

- ビルド コマンド: `npx nuxt generate`
- ビルド出力ディレクトリ: `/dist`

ビルド出力ディレクトリは、公式の説明では `.output/public` にするよう説明があり、以前まではこの設定でデプロイできていたのですが、今回この設定でデプロイしようとしたところ失敗しました。

Cloudflareのログをよく見てみると「 `dist` ディレクトリをデプロイしろ」という記述が確認できます。

![Cloudflare Pagesのログ](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406294/6a8179e7-519a-6cbc-19cb-648be97386e1.png)

しかしローカル環境で同じコマンドを実行したところ「 `.output/public` をデプロイしろ」という記述が出力されました。

![ローカル環境でのログ](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406294/3b9e01a6-63b1-d77c-4944-ac7533d6b668.png)

どちらもバージョンが同じであるのに、このように挙動が変わる理由がよくわからないのですが、`.output/public`でうまくデプロイできなかった方は、一度`dist`にして試してみると良いと思います。

なお、上記コマンドを実行した際、ローカルでは `.output/public` ディレクトリだけでなく `dist` ディレクトリもシンボリックリンクとして生成されていました。

![シンボリックリンクの表示](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406294/769240f5-ed99-7e42-05ea-e3eef403ddd7.png)

個人的にはこのあたりに原因があるのではないかと睨んでいるのですが、もしこの仕様についてご存じの方がいればお知らせいただけると幸いです。

## おわりに

Nuxt2だけでなくNuxt3 betaの頃からの仕様変更もあるようで、なかなか情報を見つけにくい状態になっています。もう少しドキュメントが整備されていくとと良いですね。

[^1]: https://nuxt.com/docs/guide/directory-structure/server
Middyを利用したLambda関数のhandlerをテストする

# 概要
Serverless Frameworkの[aws-nodejs-typescript](https://github.com/serverless/examples/tree/v3/legacy/aws-nodejs-typescript)を導入して、Middyを利用したLambda関数を作成しました。
その単体テストを作成する際に他に同じようなことをしている方のリポジトリを見つけることができず、ハマったのでメモです。

# Middyとは？
簡単に説明すると、MiddyはLambdaで使える軽量なミドルウェアエンジンです。
バリデーション処理やロギングなど、様々な共通処理をMiddyに任せることで
業務ロジックだけに専念することができることがメリットです。
詳細はドキュメントを参照ください。

https://middy.js.org/

# 前提
Serverless FrameworkでNode.jsとTypeScriptを利用したテンプレートである
[aws-nodejs-typescript](https://github.com/serverless/examples/tree/v3/legacy/aws-nodejs-typescript)を利用しています。
ここに既にMiddyが導入されています。

# Jestを導入する
以下コマンドでJestをインストール
`npm install jest ts-jest @types/jest -D`

設定ファイルを用意します。
```javascript:jest.config.js
module.exports = {
  preset: 'ts-jest',
  roots: ['<rootDir>/src/__tests__'],
  transform: {
    '^.+\\.tsx?$': 'ts-jest',
  },
  moduleNameMapper: {
    '^@src/(.*)$': '<rootDir>/src/$1',
    '^@libs/(.*)$': '<rootDir>/src/libs/$1',
    '^@functions/(.*)$': '<rootDir>/src/functions/$1'
  },
  testMatch: ['**/__tests__/**/*.+(ts|js)', '**/?(*.)+(spec|test).+(ts|js)'],
  collectCoverageFrom: ['src/**/*.{js,ts}', '!**/node_modules/**', '!**/vendor/**'],
  coveragePathIgnorePatterns: ['src/__tests__/', 'src/types/'],
};
```
## テストフォルダ作成
src直下に`__test__`というディレクトリを作成し、その中にテストファイルを配置します。
テストファイル名は`XXX.spec.ts`または`XXX.test.ts`とします。

## テストコードを作成する
```typescript:src/functions/hello/hello.ts
import { formatJSONResponse } from '@libs/api-gateway';
import { middyfy } from '@libs/lambda';

const hello = async (event: any) => {
  return formatJSONResponse({
    message: `Hello ${event.body.name}, welcome to the exciting Serverless world!`
  });
};

export const main = middyfy(hello);

```
上記のようなLambda handlerに対してテストを用意する際は以下のようにします。

```typescript:src/__tests__/hello.spec.ts
jest.mock('@libs/lambda', () => ({
    middyfy: jest.fn((handler) => handler),
}));

import { main } from '@functions/hello/handler';

const event: any = {
  "headers": {
    "Content-Type": "application/json"
  },
  "body": {
    "name": "Frederic"
  }
}

describe('hello関数のテスト', () => {
    test('正しいレスポンスを返す', async () => {
        const context: any = undefined
        const actual = await main(event, context);

        const expected = {
            body: JSON.stringify({
                message: `Hello ${event.body.name}, welcome to the exciting Serverless world!`
            }),
            statusCode: 200
        };

        expect(actual).toEqual(expected);
    });
});
```

本来TypeScriptの適切な型を定義すべきですが、無理やり通してしまっているためcontext変数などの定義を行っています。

実際にはhandlerのexport値に対してmiddyfyされているため、テストを作成する方法に悩みましたが、最初の3行のようにモック化させることでhandler内のテスト作成ができました。

`npx jest`でテスト実行できます。
`package.json`に記載して`npm test`とすることもできます。

## テストデータをJSONファイルに切り出す
`tsconfig.json`の`compilerOptions`に`"resolveJsonModule": true`設定することでJSONモジュールを読み込めるようになります。
event.bodyの値をJSONファイルに切り出してテストデータを作れます。

## その他
以下のようなSererless Frameworkのドキュメント内に以下のテストライブラリも紹介されていましが、そんなに有名でない＆普通にJestをインストールすることと大差ないと判断しました。

https://github.com/nordcloud/serverless-jest-plugin
Vue.jsコンポーネント管理 - watchやPiniaの$subscribeでハマったこと

# 概要
まだまだVue.jsの理解も浅い中で、コンポーネント分割していたらロジックが複雑になってしまい、状態管理に[Pinia](https://pinia.vuejs.org/)を使うことにしました。
`$subscribe`によるState監視で意図しない動きをしてしまっていたので、メモです。そもそもこのようなPiniaの使い方がよくない可能性がありますが、、、

# 状況
Piniaで2つのStore（StoreA, StoreB）を利用しており、StoreAにはオブジェクト情報、StoreBにはオブジェクトのリスト情報を保持していました。
状況によって、StoreAの中にStoreBのリスト内のオブジェクトを保持するケースがありました。

```typescript:storea.ts
import { defineStore } from 'pinia'

export const useStoreA = defineStore({
  id: 'storea',
  state: () => ({
    obj: {}
  }),
  getters: {
    // ...省略
  },
  actions: {
    updateObj(obj) {
      this.obj = obj
    },
    // ...省略
  }
})
```

```typescript:storeb.ts
import { defineStore } from 'pinia'

export const useStoreB = defineStore({
  id: 'storeb',
  state: () => ({
    Array: []
  }),
  getters: {
    getObjById: (state) => (id: string) => {
        return state.obj.find((obj) => obj.id == id)
    }
  },
  actions: {
    // ...省略
  }
})
```

# 起きたこと
storeBから取得したオブジェクトをそのままstoreAに更新かけました。
```typescript
const storeA = useStoreA()
const storeB = useStoreB()

const obj = storeB.getById(3)
storeA.updateObj(obj)
```

別のところで`$subscribe`を設定し、storeBのstateを監視していました。
すると、storeAのstateが更新された際に、storeBの`$subscribe`アクションが動いてしまいました。

# 解決策
getしてきたstoreBの参照を渡してしまっていることが原因だと思います。
このまま渡すのであれば、オブジェクトのディープコピーを渡すことで正しく動きました。
ディープコピーはObject.assign(), JSON.parse(), JSON.stringfy()を組み合わせて作成します。

```typescript
const storeA = useStoreA()
const storeB = useStoreB()

const obj = storeB.getById(3)
storeA.updateObj(Object.assign({}, JSON.parse(JSON.stringify(obj))))
```
ShellScriptのzipコマンド

# zipコマンドとは？
「zip」は、ファイルをZIP形式で圧縮するコマンドです。
ZIPはWindows環境で特にポピュラーな圧縮形式で、複数のファイルを圧縮して1つのファイルにすることができます。
※ZIPファイルから元のファイルを取り出す場合は、「unzip」コマンドを使用します。

# 参考サイト
https://atmarkit.itmedia.co.jp/ait/articles/1607/25/news021.html#sample1
Vue.jsでドラッグアンドドロップを使ったノードツリー生成ライブラリ検討（v-graph-network）

# 概要
[ノードツリー](https://ja.wikipedia.org/wiki/%E6%9C%A8%E6%A7%8B%E9%80%A0_(%E3%83%87%E3%83%BC%E3%82%BF%E6%A7%8B%E9%80%A0))をユーザーが作れるような機能を考える際に、ライブラリを探したメモとして残します。
[Miro](https://miro.com/ja/)のような機能が実現できるのが一番の理想ですが、現状実現しているのは以下GIFのような[デシジョンツリー](https://ja.wikipedia.org/wiki/%E6%B1%BA%E5%AE%9A%E6%9C%A8)に近いイメージです。

v-network-graphというライブラリのメモと他に検討したライブラリについて記載しています。
![DragDrop_Demo.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/532866/969cf920-6dc2-7ba0-9fb1-39cbd8167543.gif)

# 想定読者
- Vue.jsでドラッグアンドドロップを使ってオブジェクトを動かせるライブラリを探している方
- v-network-graphの基本的な利用方法を知りたい方

# 検証した環境
- vue：3.2.47
- v-network-graph: 0.8.1

# v-network-graph
https://github.com/dash14/v-network-graph

グラフDBのデータを表示するのに利用するのが主な使い方かもしれませんが、ノードツリーのような利用も可能だと思いました。
2023/3/11時点でv0.8.2がlatest版、287Star、28Forkです。
2021/8/12にInitial Releaseされており、ドキュメントも読みやすく使いやすいです。
メンテナンスは今後も行われていくようです[（https://github.com/dash14/v-network-graph/issues/40）](https://github.com/dash14/v-network-graph/issues/40)

上のデモはドキュメントの以下のページのExampleを参考にして作ってみました。
https://dash14.github.io/v-network-graph/examples/misc.html

## configuration
以下のような細かい設定はConfigurationページを見たら理解できます。（[https://dash14.github.io/v-network-graph/reference/configurations.html](https://dash14.github.io/v-network-graph/reference/configurations.html)）
- Node（デモGIFの青い四角）の形を変更する
- Label（文字）をNode内に表示する
- Edge（デモGIFでNode同士をつなげているもの）を矢印にする
- Zoom in/outできるようにする

## イベントハンドラ
v-network-graphの中でノード名を直接変更するような設定は存在しませんでした。
ただgraph表示としてはノード情報を以下のような形式で持てば問題ないことがExampleから判断できるので、特に他に制約はないです。

```typescript
const nodes = {
  // id: { name: "", その他好きなプロパティ... }
  node1: { name: "N1" },
}
```

別コンポーネントとして、編集フォームを設け、そこで編集できるようにしました。
https://dash14.github.io/v-network-graph/reference/events.html にはイベントハンドラが設定されています。

以下のようにnodeをクリックした際に編集オブジェクトを表示するようにしました。
click時にはnodesに登録した `id: string` が取得できるようです。（上記の例だと`node1`）

```typescript
const eventHandlers: vNG.EventHandlers = {
  "node:click": ({ node }) => {
    // showEditForm()
  },
}
```

## 実現が難しそうな機能
以下は現時点で実現が難しそうな機能です。

### Edgeを曲線に変える
MiroのようにNodeの場所によって矢印を見やすく曲げることはできないです。
現状はEdgeは直線ベースで、同じNode同士に2本以上のEdgeがひかれたときに曲線にすることはできます。
以下のissueで機能リクエストが出されているので将来的に実現できる可能性はあります。

https://github.com/dash14/v-network-graph/issues/76

# 【参考】他に検討したライブラリ
他にも検討したライブラリを参考までに載せておきます。
GitHubリポジトリ内に実際に触れるデモ環境があるので、使用感を知りたい方はリポジトリを参照ください。
## vue-mindmap

https://github.com/anteriovieira/vue-mindmap
    
機能としてはv-network-graph同様にやりたいことが実現できそうと思いました。v-network-graphで困難なEdgeの曲線表示もできています。
一方で動的にNodeやEdgeを増やすにはカスタマイズが必要かつ、最終更新が6年前でVue3対応されていないので断念しました。

## Vue.Draggable

https://github.com/SortableJS/Vue.Draggable
    
リスト単位やテーブルのドラッグアンドドロップなどには最適です。
ただ、ノードツリーのような線を引っ張ったり、縦横無尽に動かせるわけではなさそうと思い断念しました。

## vue-pipeline

https://github.com/jinfang134/vue-pipeline
    
パイプラインの図を作るのによいライブラリです。
ドラッグアンドドロップなど、自由に動かすのに少し不便そうと思い断念しました。

## vue3-mindmap

https://github.com/hellowuxin/vue3-mindmap

マインドマップライブラリです。
デモを見る限りだとマインドマップ意外の形にするにはカスタマイズが必要だと思い断念しました。
ただ、Node追加、Zoom in/out、ドラッグアンドドロップなどの機能はついています。
Crystal言語からDeeplのAPIを呼ぶ

追記：ツール化しました

https://qiita.com/kojix2/items/fbc27b2d354cd4ffba45


## はじめに

タイトルの通りです。最近は、ChatGPTが盛んですが、ChatGPTは日本語よりも英語で問いかけた方が解答の精度が高いという特徴があるため、ChatGPTに問いかけを行うために、さくっと日本語から英語に翻訳したいときがあります。

## Crystsal言語からDeepL翻訳を呼び出すスニペット

ChatGPTに、Crystal言語から、参照コードと、参照ドキュメントを渡すことにより、DeepLのAPIを呼び出す言語を書いてもらいました。利用には API Key が必要です。

```crystal
require "http/client"
require "json"

module Deepl
  class ApiKeyError < Exception; end
  class RequestError < Exception; end

  class Translator
    API_ENDPOINT = "https://api-free.deepl.com/v2/translate"

    @http_headers : HTTP::Headers

    def initialize
      @http_headers = build_http_headers
    end

    def build_http_headers
      HTTP::Headers{
        "Authorization" => "DeepL-Auth-Key #{get_api_key}",
        "Content-Type"  => "application/x-www-form-urlencoded",
      }
    end

    def get_api_key
      if ENV.has_key?("DEEPL_API_KEY")
        ENV["DEEPL_API_KEY"]
      else
        raise ApiKeyError.new
      end
    end

    def request_translation(text : String, target_lang : String)
      request_payload = "text=#{URI.encode_www_form(text)}&target_lang=#{URI.encode_www_form(target_lang)}"
      send_post_request(request_payload)
    end

    def send_post_request(request_data : String)
      HTTP::Client.post(API_ENDPOINT, body: request_data, headers: @http_headers)
    rescue error
      raise RequestError.new("Error: #{error} #{error.message}")
    end

    def translate(text, target_lang)
      response = request_translation(text, target_lang)
      parsed_response = JSON.parse(response.body)
      parsed_response.dig("translations", 0, "text")
    end
  end
end
```

Example Response はこんな感じですので、

```
{
  "translations": [
    {
      "detected_source_language": "EN",
      "text": "Hallo, Welt!"
    }
  ]
}
```

こんな感じで利用します。

```crystal
input_text = ARGV[0]
target_lang = "EN"

translator = Deepl::Translator.new
translated_text = translator.translate(input_text, target_lang)

puts translated_text
```

```
./deepl こんにちは。
Hello.
```

この記事は以上です。
ChatGPTを使ってコードレビューを自動化するWebアプリを作ってみた

## はじめに
こんにちは！都内でWebエンジニアをしている[@wimkmb](https://twitter.com/wimkmb)です。
最近話題のOpenAIのChatGPTを使ってコードレビューを自動化するWebアプリ[GPTReview](https://gptreview.dev)を開発しました。
この記事では、その概要と開発のポイントについて紹介します。

## 着想
個人開発をしているとレビューしてくれる人がいないので、
ChatGPTにレビューやリファクタリングを投げていたのですが
やり取りが結構面倒なので、ファイルのアップロードやコードの入力をしたら
自動でレビューしてくれるWebアプリを開発しようと思い、実装をしました。

## GPTReviewの概要
GPTReviewは、ChatGPTを用いてコードレビューを行うWebアプリです。
ユーザーはファイルをアップロードするかコードを入力をすると、
ChatGPTがコードレビューを行い、200文字程度のフィードバックとコードの改善例を提供します。

:::note warn
文章が途切れる可能性があるので、その点はご了承ください。
:::

![スクリーンショット 2023-03-27 21.13.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/53660/108622c6-5939-ef58-1385-c091513f81fe.png)

https://twitter.com/wimkmb/status/1638027026497146880?s=20

## 技術スタック
- Python3.11.2
- Django4.0.3
- Tailwind CSS2.2.19
- OpenAI API
- GCP, GAE

## 開発ポイント
1. OpenAI APIの活用: OpenAIのAPIを使って、自動コードレビューを実現しています。（プロンプトは見直す必要あり）
2. Djangoフレームワーク: バックエンドとしてPythonのDjangoフレームワークを利用し、効率的なWebアプリケーション開発を行っています。
3. UI/UXデザイン: シンプルなインターフェースを提供するために、Tailwind CSSを使用しています。
4. レスポンシブデザイン: デバイスに応じて適切な表示がされるよう、レスポンシブデザインを実装しています。
5. エラーハンドリング: ユーザーが不正な入力をした際にエラーメッセージを表示し、使いやすさを向上させています。
6. セキュリティ対策: CSRF対策やエスケープ処理など、セキュリティ対策を実施しています
7. デプロイメント: GCPにアプリケーションをデプロイし、公開しています。

## まとめと今後
使ってもらってフィードバックをいただきつつ、改善していきたいです！
遊び半分でも使ってもらえると嬉しいです:pray:
https://gptreview.dev
あと、プロンプトは見直してフィードバックの精度を向上させるためのチューニングを行っていきます。
最後に、GPTReviewがコードレビューの手助けとなり、皆さんの開発効率向上に貢献できれば幸いです！
Power Appsのソリューションとは

今回は、Power Appsのソリュ―ションについて、使うメリットや使い方などご紹介します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2883014/f652c487-dbb2-865e-ed47-2c53970ffb58.png)

↓同じ内容を動画でも解説しておりますので、よろしければこちらもご覧ください。

https://youtu.be/rIi2pVOKcGA

ソリューションをエクスポート、インポートする手順については以下を参照してください。

https://qiita.com/skuramoto/items/a425e128cad2a827a5dc

# ソリュ―ションとは？
簡単に言うと**フォルダーのようなもの**です！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2883014/9a2ce048-566d-6267-81f3-0709d326fa60.png)

Power Platformのアプリに関わる様々なコンポーネントを一つのまとまりとしてパッケージ化し、管理、配布、展開が可能になる仕組みです。

<font color="DarkRed">**使うコンポーネントが増えてきたら使いましょう！**</font>


# 使うメリット
- 総じて管理が楽になる
    - 同じ場所で関連コンポーネントが管理可能<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2883014/c8810f2d-50b6-9bc2-d5ee-b1a8f75717d4.png" width=60%>

    - ソリューション単位でコンポーネントが公開可能（すべてのカスタマイズの公開）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2883014/36311f18-184c-4eaf-f12a-88f69b5459f0.png)
- バージョン情報が付与される
- zipファイルの形式で、パッケージとしてエクスポートされる為、ローカルへの保存や他の環境への移行が可能
- GithubやAzure DevOpsと組み合わせることで、差分管理も可能

# ソリューションの作り方
Power Appsの左のメニューで[ソリューション]を開き、左上の[新しいソリューション]をクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2883014/16b4dae5-a742-ccf9-1d0d-21c07404a30f.png)


|項目名 |入力内容 |補足 |
|---|---|---|
|表示名  |わかりやすい名前  |  |
|名前  |英語の名前  |  |
|公開元  |こだわりがなければ、規定の発行者を選ぶことが多い  |このソリューションの発行者の意味。作成したか、それ以外の人かで権限を設定することもできる。ここで設定するIDがコンポーネントの論理名の接頭辞になる。 
|バージョン  |基本は規定の値にする(変えることもできる)|アプリのバージョンと同じ考え方  |

例として以下の画像を参考にしてください。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2883014/776212d4-93fd-11dd-bc3b-de3d59ffd01a.png" width=30%>

以上を設定して[作成]ボタンをクリックします。
公開元に関して、詳しくは以下をご参照ください。

https://learn.microsoft.com/ja-jp/power-apps/maker/data-platform/create-solution?source=recommendations#%E3%82%BD%E3%83%AA%E3%83%A5%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E7%99%BA%E8%A1%8C%E8%80%85|




# ソリューションに含めることができるコンポーネントの一例
ソリューションは、一部の例外を除き、基本的にはほどんどのコンポーネントに対応しています。
- キャンバスアプリ
- モデル駆動型アプリ
- Dataverse テーブル
- セキュリティロール
- Power BIダッシュボード、レポート
- チャットボット([解説記事あり](https://qiita.com/skuramoto/items/77ae6d87ba417495b3fc))
- SLA、ルーティング規則、レコード作成・更新ルール
- クラウドフロー
- デスクトップフロー
- カスタムコネクタ
- ビジネスプロセスフロー
- Webリソース
- コンポーネントライブラリ
- 環境変数
- プラグイン

・・・などなど

# まとめ
今回はソリューションについて説明しました。
特に、複数のコンポーネントを組み合わせてアプリを作る際は、ぜひソリューションを使って管理をしやすくしてみてください！
ソリューションをエクスポート、インポートする手順については以下を参照してください。

https://qiita.com/skuramoto/items/a425e128cad2a827a5dc
MicroStrategyにおいて階層をもったデータをレポート抽出する設計方法

# はじめに
本記事ではMicroStrategyにおいて
階層を持つデータを使用した設計についてご紹介します。

# 概要
ここでは以下のように項目同士が階層になっているデータを階層データとします。
テストデータとしてエリア＜グループ＜部門と粒度が大きくなるデータを用意しました。
このようなデータをMicroStrategyで設計する際の活用方法を本記事ではご紹介できればと思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2737479/418d2413-5b2f-1394-a31f-58bc9a2bb3f9.png)


# 活用方法
まずはプロンプトなど条件設定の際の設計紹介になります。
KAISOという階層マスタとKAISOTRNというトランをエリアという項目で結合しています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2737479/c2d0a6a2-b390-3f8a-cd85-edbccd93577f.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2737479/b9455ade-85f6-3b6c-198f-7cfea44694ab.png)
レポート項目にはトランから作成したトランID・商品コード、
マスタから作成したグループ・部門を配置しています。
またプロンプト（条件設定）にはマスタから作成したグループ・部門を配置しています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2737479/baee0d7b-9e86-a16d-d5f4-62c3a03fdf7a.png)
エレメントプロンプトにすると以下のようにグループや部門などから条件を選択することができ、SQLは以下のようになります。階層の最下層とトランの項目を結合させると、階層や組織情報が変わった際もマスタの更新をすれば、レポートの改修影響を少なくできるかと思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2737479/65e13d06-3636-27d8-2293-369671e6164b.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2737479/e78f2d4d-6933-9099-724b-a80c8c27d7f5.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2737479/732c2c3e-bfff-1121-f9e7-cd35625f1044.png)


またデータ制御についてもエリアが頻繁に変わる場合などは、グループや部門単位で制御をすると手メンテ工数が減るので、制御設計の際にも活用できるかと思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2737479/28d0ed47-70c0-9758-d0a4-1c4447dd1263.png)

# さいごに
今回は簡易的な記事ですが、
マスタでできるだけ情報をもたせて運用を簡易化するという点で
みなさまの業務にぜひご活用いただけますと幸いでございます。
RDS IAM認証を試す

# 概要

IAM 認証を使用して DB インスタンスへ接続する。

- パスワード無しでログイン。
- ユーザごとにアクセスできる DB を制限する。


https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/UsingWithRDS.IAMDBAuth.Connecting.html

# 手順

## RDS DB インスタンスで IAM DB 認証をアクティブ化

「パスワードと IAM データベース認証」にチェックして、RDS を構成。
![スクリーンショット 2023-03-27 18.12.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280929/b657f7eb-74bb-4f73-a438-e3f4a9ca107b.png)

## AWS 認証トークンを使用するデータベースユーザーアカウントを作成します。

まず、通常通り「パスワード認証」で、EC2 から RDS にログイン。

```
mysql -h {エンドポイント} -P 3306 -u admin -p
```

ユーザー（iam_db_user）を作成。

```
CREATE USER iam_db_user  IDENTIFIED WITH AWSAuthenticationPlugin AS 'RDS';
```

ユーザー（iam_db_user）が作成されているか確認。

```
select Host, User from mysql.user;
+-----------+------------------+
| Host      | User             |
+-----------+------------------+
| %         | admin            |
| %         | iam_db_user      |
| localhost | mysql.infoschema |
| localhost | mysql.session    |
| localhost | mysql.sys        |
| localhost | rdsadmin         |
+-----------+------------------+
6 rows in set (0.02 sec)
```

DB（iam_db） の作成。

```
create database iam_db;
```

DB（iam_db） が作成されているか確認。

```
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| iam_db             |
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
5 rows in set (0.03 sec)
```

iam_db_user が　iam_db　にログインできるように権限を付与。

```
GRANT ALL PRIVILEGES ON iam_db.* TO 'iam_db_user '@'%';
```

## アクセストークン取得用IAMポリシー、ロールの作成とアタッチ

- データベースユーザーを IAM ロールにマップする IAM ポリシーを作成。

https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/UsingWithRDS.IAMDBAuth.IAMPolicy.html

```json:rds_許可
{
   "Version": "2012-10-17",
   "Statement": [
      {
         "Effect": "Allow",
         "Action": [
             "rds-db:connect"
         ],
         "Resource": [
             "arn:aws:rds-db:ap-northeast-1:[アカウントID]:dbuser:[RDSのリソースID]/iam_db_user"
         ]
      }
   ]
}
```

- Amazon EC2 から Amazon RDS へのアクセスを許可する IAM ロールを作成。

```json:ec2_信頼関係
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Service": "ec2.amazonaws.com"
            },
            "Action": "sts:AssumeRole"
        }
    ]
}
```

- IAM ロールを Amazon EC2 インスタンスにアタッチ。

## ログイン確認

-p 以下で認証トークンを取ってくる。

https://docs.aws.amazon.com/cli/latest/reference/rds/generate-db-auth-token.html

```
mysql -u iam_db_user -h {エンドポイント} -p`aws rds generate-db-auth-token --hostname {エンドポイント} --port 3306 --username iam_db_user --region ap-northeast-1` --enable-cleartext-plugin
```
PMもしくはPMOがプロジェクトの成功率を上げるためにやるべき工夫

## 朝会と夕会の実施

## 進捗報告会での報告フォーマットの作成
正確で無駄のない進捗報告をしてもらうため。

## ストレートな物言いをする


## Teamsチャットが乱立していたら、タイトルを付与する


***
他にもあればご教示ください。
輪読会を開催してみて

## はじめに
### 要約(chat gpt)
この記事は輪読会を開催するための参考情報を提供しています。
輪読会の選定について、そして各回の流れについて説明されています。
この記事の筆者は技術者派遣の会社の社員であり、毎週土曜日に行われる輪読会についての経験を共有しています。
選定された書籍は「リーダブルコード」であり、開催前にはslackを使って告知し、開催当日はGoogleスライドとSlidoを使用して、リアルタイムで質問や感想を共有できるようにしました。
開催後にはスレッド形式で振り返りを行いました。最後に、この輪読会の良かった点について説明されています。

### 対象読者
これから輪読会を開催しようと考えている人
以下について、本記事は参考になるかと思います。
- 対象書籍の選定について
- 各回の流れ


### 自己・環境紹介
#### 自己紹介
社員の中では社内発信が多いタイプ
- 資格の合格体験記
- ITニュースの共有
- 他社員の共有に対する返信など

#### 環境紹介
技術者派遣の会社
- 所属エンジニア数：約600人(うちITエンジニア約450名)
- 2021年後半にslack本格導入

(私目線の感想)
- 社員同士のコミュニケーションは活発には行われていない。
- 特に技術分野の話題は10名ほどしか発信をしていない。

## 実施内容
- 毎週土曜日
- 11:00 ~ 正午 (1時間)
- 3ヵ月間開催(2022年11月～2023年2月)
### 対象書籍
リーダブルコード（約260ページ）

#### 書籍の選定理由
以下の理由から、輪読会の初回にふさわしいと思った。
- 多くのエンジニアが読書済みであり、多くのエンジニアが読むべき名著である。
- 設計からコーディング・テストという幅で活用可能な知識が紹介されており、業務内容的に活用できる人が多い。

### 各回の流れ
#### 開催前
社内のslackにて、以下のような告知を投稿
![スクリーンショット 2023-03-07 115133.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/505609/0ba88c37-7bad-4505-c0ef-c3de68b0707f.png)

#### 開催当日
Googleスライドと[slido](https://www.slido.com/jp)を連携させて、黙読中にリアルタイムで質問を投稿できるようにしました。

#### 開催後
開催告知にスレッド形式で、その日に挙がった質問・感想を投稿
![szzz.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/505609/47a990b3-d575-b42e-5983-92ca8d77187e.png)

## おわりに
### 振り返り
1,2回目の参加人数が8名程度だったが、回を重ねるごとに減少し、最終回の参加人数は3人であった。

#### よかったところ
##### slidoは便利
以下３点は特によかったポイントです
- 黙読中に表示するスライドに動きがでるので、寂しくない
- リアルタイムに更新されるので、参加者の読書ペースをある程度把握できる
- 匿名で投稿できるので、気軽に投稿できる
##### 議論の内容がよかった。
議論の内容は、書籍の要点ではなく、書籍を読んだ所感や関連する体験談にした。
技術者派遣という会社の特性上、各々が担当しているプロダクト・所属するチームが異なるので、様々な体験談を聞く機会になった。
##### 

#### 改善すべきところ
##### 書籍の準備にハードルがあった
参加者に聞いてみたところ、同僚・後輩で書籍を購入する習慣がない人が多いらしい。
次回はネット上に公開されているドキュメントを対象にしてみようと思います。
##### 書籍および開催日時を運営側が指定した
初回の書籍・開催日時を指定した理由は、それらのアンケート時にリアクションが無く、初回から盛り下がる可能性を排除するためでした。
社内で輪読会が開催されたという実績を作れたので、次回は対象書籍及び開催日時をアンケート形式で募ろうと思います。

---
最近は英語の勉強もしているので、次の輪読会は英語を絡めてみたいな～とも思ってみたり
NVIDIA VR Ready

|グラフィックボート|VR Ready|アーキテクチャ|
|---|---|---|
|RTX 6000  Ada Generation|〇|Ada Lovelace|
|RTX 4000 SFF Ada Generation|〇|Ada Lovelace|
|RTX A6000|〇|Ampere|
|RTX A5500|〇|Ampere|
|RTX A4500|〇|Ampere|
|RTX A5000|〇|Ampere|
|RTX A4000|〇|Ampere|
|RTX A2000|〇|Ampere|
|T1000||Turing|
|T600||Turing|
|T400||Turing|
|Quadro RTX6000|〇|Turing|
|Quadro RTX 5000|〇|Turing|
|Quadro RTX 4000|〇|Turing|
|Quadro GV100|〇|Volta|
|Quadro P6000|〇|Pascal|

- Turing以降 : Multi-View Rendering (MVR)に対応 
- Pascal : Single Pass Stereo (SPS) renderingに対応
---
出典
https://resources.nvidia.com/ja-jp-nvidia-rtx-resources/nvidia-rtx-linecard
https://www.nvidia.com/en-us/design-visualization/desktop-graphics/
https://developer.nvidia.com/vrworks/graphics/multiview
既存プロジェクトへPMOとして配属することが決まったら早急にやるべきこと一覧


既存プロジェクトにPMOとして参加することが決まったら最低限実施すべきことを記載しました。



# 1. PMからの情報収集
### 1.1 プロジェクトの過去、現在、未来、目的の把握
例
プロジェクトがどんなきっかけで始まり、現在どのようなフェーズにいて、どのような未来を描いているか。
過去に困っていたこと。
現在困っていること。
将来困りそうなこと。

プロジェクトの各工程でやらないといけないこと
クリティカルパス

### 1.2 各定例の開催日時と目的の把握
特に以下の定例の日時を把握すること
・得意先に進捗を報告する定例
・プロジェクト責任者に進捗を報告する定例

### 1.3 PMOに期待する役割の把握
最低限やらないといけないことを把握する


# 2. 資料読み込み(PMにポイントになる箇所をヒアリングすること)
・プロジェクトの体制図
・システム構成図(アプリ構成、システム構成の把握)


# 3. その他
### 3.1 使用頻度の高い資料にアクセスし易くする工夫
例
・Excelファイルをピン留めに固定
・フォルダをクイックアクセスに固定
・Webサイトのブックマーク
・主要なTeamsチャットの固定



### 3.2 必要な業務知識の習得
例　金融取引システムの開発プロジェクトであれば、金融商品の取引や証券取引所の知識など



### 3.3 関係者各位と仲良くなっておく
重要な人物と仲良くなっておけば、相談や依頼などのハードルが下がり、プロジェクトが成功する確率が上がる。
最初が肝心。ランチをご一緒できたらベスト。
ある程度時間が経過し、自分の存在が明確に認識されてから仲良くなるのは不可能。「なんだコイツ」と思われる。

***
他にもあれば、教えていただけると幸いです。
サルでもわかるリカバリープランの考え方


## 目的  
> プロジェクトが失敗であるとみなされる観点として、QCDと呼ばれる、品質(Quality)、コスト(Cost)、納期(Delivery)に対する失敗があります。作業失敗しないための保管用永久メモとして書きました。  

## プロジェクトとは    
> ある一定期間で一定の(人的・資金的・物質的)リソースを投資して目的の成果物(製品・サービス)を作り上げる活動です。

### クリティカルパスとは  
>  プロジェクトの全工程を最短時間で完了するために重要な作業経路のことを言います。 重要な作業 (タスク) を特定することで、スケジュールの柔軟性も判断することができるようになります。 プロジェクトには複数のタスクが存在し、個々のタスクを終わらせなければプロジェクトは完了しません。

> クリティカルパス上にある作業が鍵となることを忘れてはいけない。そういった作業に生産性の高いリソースを割り当てる一方、生産性の低いリソースをクリティカルパス上にない作業に再割り当てするような選択も可能なはずである。クリティカルパス上にない作業が遅れたとしても、プロジェクト全体の納期を守るという点ではまだ大丈夫ということもある 。   

#### クリティカルパス作成ツール  
[https://www.lucidchart.com/pages/ja/examples/cpm-software](https://www.lucidchart.com/pages/ja/examples/cpm-software
)
> その他にも多数便利に使うことができる機能が多数あり。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57249/8f770f8b-119f-ac08-7956-164b9844a130.png)
 

## バッファの利用  
> プロジェクト用語では「資源の円滑化」と呼ばれる方法で、計画上存在しているスケジュールの「余裕（バッファ）」を使って対応する方法  

###  ここで注意したいのは、”バッファを割り当てる要員”です。
> 同じバッファを使うにしても、可能な限りスキルレベルの高いメンバーにバッファを使用する方が良い  

## 増員しない場合
> “時間” を投下して残業を行った場合、疲れによる人的ミスの誘発を招き手戻りコストが発生し得る。  
> “モノ” を投下してツールや備品を増やした場合、使い方を覚えるための学習コストが発生し得る。    
> どうすればよいか整理した資料やメモを基に有識者とよく相談して次のステップへ。    

## 増員した場合
> “人” を投下してメンバーを増やした場合、新規参画者向けの教育コストが発生し得る。    
> “モノ” を投下してツールや備品を増やした場合、使い方を覚えるための学習コストが発生し得る。    

## 増員前後に起きる問題  
### 増員背景としてだいたいが、期日までにこのままだと全タスク分が終わらない  
> ノウハウや教育の認識合わせができていない  ⇒  検証者の確認量が増え、戻りが多くなる  

## 解決手順 まとめ    
1. チームのリーダーに現状整理したものを基に、何日もらえるか調整を行う。 
2. チーム内で各担当の１番ベテランと思う人から○○レクチャ会または、認識合わせを通じて、手順書を展開する。
3. <2>だけで不明点が続く場合は、<2>のレクチャ担当の人に質問して理解を100%にする。  
4. 言っていることが正しいかの確認になるので、<2>の人を混ぜての打合せを15分～30分程度で開催する。  
5. <作業中>  作業の区切りまたは最後に、成果物のセルフチェックをする。  
6. <5> でNGの場合は、<2>の人に確認を行う。※時間が取れない場合は、一旦共有場等にメモを残して次のステップに進む。そのことを<1>や<2>の人に連絡だけ入れておく。  
7. 作業者同士でクロスチェック後に検証者のクロスチェック  
8. 問題なければ、作業終了。問題があれば<1>または<2>からやり直す。 または対策案が既にある場合はその対策案を実行して、<5>から作業実施する。  

## タスク整理の方法  
> よく１番ググってあるのは「KJ法」や「5W1H、6W1H、6W3H」    
 
### ひとりKJ法⇒通常のKJ法
1. アイデア出し  
2. グルーーピング  
3. 関連付け  
4. 文章化  
5. 皆で通常のKJ法による打合せと実行
チルダ記号を使って条件を反転させる


# チルダ記号 ~

```python

a = df[~df["カラム1"] <= 100) ]
```

この`~`ヘナヘナマークがチルダ。
notみたいな意味合いで使われ、条件が逆転する。
上記だと100以下が取得されるが、チルダの役割により100以上のデータが取得されるようになる。

最初試した時は、エラーになりましたが()を挟むことにより動いてくれました。
うまいくいかないときは、~()でかくといいかもしれない。

https://vector-ium.com/pandas-get-values/
[AWS Q&A 365][EKS]AWSのよくある問題の毎日5選 #16

# 1. Amazon EKSとは何で、どのように機能するのでしょうか？
回答：Amazon EKSは、独自のKubernetesコントロールプレーンをインストールまたは運用する必要なく、AWS上でKubernetesを実行することを容易にする管理されたサービスです。 Amazon EKSでは、既に知っているKubernetesの機能やツールをすべて使用できます。

# 2. Amazon EKSの価格オプションは何ですか？
回答：Amazon EKSの価格は、クラスター内のKubernetesワーカーノードの数と、Amazon EKSワーカーノードを実行するために作成するAWSリソースに基づいています。 Amazon EKSワーカーノードを実行するために作成するAWSリソース（例：EC2インスタンスまたはEBSボリュームなど）に支払い、Amazon EKS自体には追加料金はありません。

# 3. Amazon EKSでクラスターを作成および管理するにはどうすればよいですか？
回答：AWS Management Console、AWS CLI、またはeksctlコマンドラインツールを使用して、Amazon EKSでクラスターを作成および管理できます。また、CloudFormationテンプレートまたはTerraformモジュールを使用して、Amazon EKSクラスターを作成および管理することもできます。

# 4. Amazon EKSでWindowsサポートを有効にするにはどうすればよいですか？
回答：クラスター内にWindowsノードグループを作成することで、Amazon EKSでWindowsサポートを有効にできます。その後、KubernetesワークロードでWindows Serverコンテナを使用し、Kubernetesを使用してWindowsアプリケーションを展開できます。

# 5. Amazon EKSでエンドポイントアクセスを構成するにはどうすればよいですか？
回答：Kubernetes APIサーバーエンドポイントを変更し、Amazon EKSコントロールプレーンVPCのネットワークアクセス制御リスト（ACL）を構成することで、Amazon EKSでエンドポイントアクセスを構成できます。また、PrivateLinkを使用して、Kubernetes APIサーバーエンドポイントに安全にアクセスし、公共インターネットに公開することなくアクセスすることもできます。
[VS Code] [Pylint] VS CodeでPylintのPylintArgsが反映されない場合の対処メモ

# はじめに

VSCodeのlinterとしてPylintを使っていたのですが、プロジェクト(作業フォルダ)外のファイルに対してはPylintArgsの設定が有効になっていませんでした。
ログを見てみると、PylintArgsを渡さずにグローバル設定で実行されているようです。
VSCodeの設定でそのようなファイルにもPylintArgsを渡せるように出来れば良いのですが、よくわからないのでグローバル設定を設定して対処しました。
そのメモです。

# 環境

```:python
Python 3.11.0 (main, Oct 24 2022, 18:26:48) [MSC v.1933 64 bit (AMD64)]
pylint             2.17.1
```

```:VSCode
Version: 1.76.2 (user setup)
Commit: ee2b180d582a7f601fa6ecfdad8d9fd269ab1884
Date: 2023-03-14T17:55:54.936Z
Electron: 19.1.11
Chromium: 102.0.5005.196
Node.js: 16.14.2
V8: 10.2.154.26-electron.0
OS: Windows_NT x64 10.0.22621
Sandboxed: Yes
```

# 対策

方法は、単純でホームディレクトリに`.pylintrc`を用意してやれば良いです。
Windowsの場合は、HOMEPATH(`C:\Users\<userName>\.pylintrc`)に置いてやれば良いです。
とりあえず、以下のような設定を置いてみましたら問題なく反映されました。
ただ、このままだとプロジェクト内のファイルは、PylintArgsが優先されます。
同じ設定にしようとするとPylintArgsを消す必要があります。

設定自体は、異端過ぎて宗教裁判が起きそうですが。

```ini:.pylintrc
[MAIN]
#

[BASIC]
attr-naming-style=camelCase
argument-naming-style=camelCase
class-const-naming-style=PascalCase
class-naming-style=PascalCase
const-naming-style=PascalCase
function-naming-style=camelCase
# good-names=a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,_,id
good-names-rgxs=.$,..$
method-naming-style=camelCase
module-naming-style=PascalCase
variable-naming-style=camelCase

[CLASSES]
#

[DESIGN]
#

[EXCEPTIONS]
#

[FORMAT]
indent-after-paren=2
indent-string='  '
max-line-length=240

[IMPORTS]
#

[LOGGING]
logging-format-style=new

[MESSAGES CONTROL]
disable=missing-function-docstring,
        missing-class-docstring,
        missing-module-docstring

[METHOD_ARGS]
#

[MISCELLANEOUS]
#

[REFACTORING]
#

[REPORTS]
#

[SIMILARITIES]
#

[SPELLING]
#

[STRING]
#

[TYPECHECK]
# generated-members=cv2,

[VARIABLES]
#

```
JSを始めよう!



### DOM操作







- documentオブジェクトのメソッド（HTML要素自体を操作）
`getElementById()`：指定されたID属性を持つ要素を取得
`getElementsByClassName()`：指定されたクラス名を持つすべての要素を取得
`getElementsByTagName()`：指定されたタグ名を持つすべての要素を取得
`querySelector()`：指定されたCSSセレクターに一致する最初の要素を取得
`querySelectorAll()`：指定されたCSSセレクターに一致する**すべて**の要素を取得
`createElement()`：指定された要素の名前で新しい要素を作成
`appendChild()`：指定された要素を、指定された親要素の子要素として追加
`removeChild()`：指定された子要素を、指定された親要素から削除
`setAttribute()`：指定された属性と値を持つ指定された要素に属性を追加
`getAttribute()`：指定された属性の値を取得
`addEventListener()`：特定のイベントが発生したときに、指定した関数を呼び出すことができる。ボタンがクリックされたときに、そのボタンに関連付けられた関数を呼び出すことができる
`removeEventListener()`：指定されたイベントのリスナー関数を指定された要素から削除
`querySelectorAll()`：指定されたセレクターに一致する**すべて**の要素を返す
`querySelector()`：指定されたセレクターに一致する最初の要素を返す

- elementオブジェクトのメソッド（HTML要素自体を操作）
`getElementById(id) `: 引数で指定されたidを持つHTML要素を取得
`querySelector(selector) `: 引数で指定されたCSSセレクタに一致する最初の要素を取得
`querySelectorAll(selector)` : 引数で指定されたCSSセレクタに一致するすべての要素を取得
`appendChild(node) `: 引数で指定されたノードを、要素の子要素の末尾に追加
`removeChild(node) `: 引数で指定された子要素を要素から削除
`setAttribute(attribute, value) `: 引数で指定された属性に値を設定
`getAttribute(attribute) `: 引数で指定された属性の値を取得
`style.property = value `: 引数で指定されたCSSプロパティに値を設定
`classList.add(className) `: 引数で指定されたクラスを要素に追加
`classList.remove(className) `: 引数で指定されたクラスを要素から削除
`classList.contains(className)` : 引数で指定されたクラスが要素に含まれているかどうかを判定
`classList.toggle(className) `: 引数で指定されたクラスが要素に含まれている場合は削除し、含まれていない場合は追加
`addEventListener(event, function) `: 引数で指定されたイベントが発生したときに、指定された関数を実行
`dispatchEvent(event) `: 引数で指定されたイベントを発生させます。





- classListオブジェクトのメソッド（HTML要素のクラス属性を操作）
`add(class1)`：要素に指定されたクラスを追加
`remove(class1, class2, ...)`：要素から指定されたクラスを削除
toggle(class, true|false)`：指定されたクラスが要素に存在する場合は削除し、存在しない場合は追加します。引数にtrueまたはfalseを指定すると、クラスの追加または削除
`contains(class)`：指定されたクラスが要素に含まれているかどうかをチェックし、結果をtrueまたはfalseで返す

### 用語
`DOM（Document Object Model）`：HTMLなどを解釈し木構造で表現したもの
これまでDOMを直接操作していた
それではレンダリングコストが高い、コードが複雑化しやすい
それを解決したのが`仮想DOM`
いきなりDOMを操作せず、JS上で仮想DOMを操作し差分を出してからDOMに反映させる



`パッケージマネージャー`：
・内部ではNode.jsが動いている。
・依存関係を勝手に解決してくれる。
・import先が明示的にわかる
・世界中で公開されているパッケージをコマンド１つで利用できる
・チーム内での共有も簡単

`NPM`：パッケージのレジストリ
`packeage.json`：設計書
`package-lovk.json`：依存関係、バージョンの解決。
`node_modules`：モジュールの実体。（githubにはあげない）


`ECMScript`：JSの標準規格、毎年一回発表される

`モジュールバンドラー（webpack）`：複数のJSファイルを1つにまとめるためのもの

`トランスパイラ`：新しいJSの記法を古い記法に変換してくれる

`SPA（Single Page Applicaiton）`：HTMLは1つのみでJSで画面を切り替える。
JSでHTMLのDOMを書き換えるて、HTMLはそのままだけど画面が変わったように見える。
メリット・・ページ遷移事のちらつきがなくなる。コンポーネント分割が容易になることで開発効率アップ


### 例（作成途中）

element =documetn.createElement(要素)：指定した要素を新しく作る
element.innnerText = ""：要素のテキストを設定
documet.body.appendChild(element)：要素をbodyに追加
innerHTMLプロパティでテキストを変更する


addEventListner(イベント名,イベント時の挙動)：要素に対して指定したイベントが発生したときの挙動を設定
イベント例
clck：要素をクリックした時
mouseover：要素の上にカーソルが来た時
mouseleave：要素の上からカーソルが外れた時



insertAdjacentHTML()は、指定したHTML文字列をDOMツリーに挿入するメソッドです。このメソッドは、挿入する位置を指定することができます。

textContentは、要素のテキストコンテンツ（HTMLタグを含まないプレーンテキスト）を取得または設定するためのプロパティです。このプロパティは、テキストノードの内容を取得するためによく使用されます
AWS Fargate, ECSを用いたコンテナ運用設計、構築をしてみた。~アーキテクチャ考察~

# やりたいこと
1. AWS上でコンテナを動かす！
1. やるからには実用的なものを構築する！
1. データプレーンにFargateを使用してみたい！（やってみたいだけ）

# 目標
**頑張ること（頑張ったこと）**
* ECS on Fargateでコンテナを動かす
* フロントエンド、バックエンドを分けた構成にする
* Brue/Greenデプロイメントを採用する
* 運用に必要なログを取得可能にする

**あきらめたこと**
* WAFの導入
* CI/CD環境の導入
* アプリのガチ作成、ガチ運用（いつか自分でWebアプリも作ってみたいですね笑笑）

こんな感じでやっていきます。
結論から言うと既に構築済みです。（やったー）
これからQiitaに構築手順をまとめていこうかと思います！！何Partまで行くのか、、、

あきらめたことに関しても今後やっていきたいと思います！！
ガチ初学者なので間違っているとこあったら是非ご教授ください。

# アーキテクチャ設計
はい、ドーン。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3138153/8acf99e8-feab-9b43-394c-00154d613fea.png)

こんな感じのアーキテクチャになりました！！
ポイントはアーキテクチャにも記載しているけど以下の通りかと
* ECS + Fargateでコンテナ運用することによる運用工数の削減
* CodeDeploy + ALBでBlue/Greenデプロイメントを実装
* 秘密情報をSSMパラメータストアに格納
* ログ運用を考えたCloudWatch, S3の配置
→長期保管はS3、短期はCloudWatch等

コンテナに乗せるアプリケーションのイメージは以下のようになります。
今回の検証では簡単なWebアプリでやっていきますが、大体のWebアプリに応用可能なアーキテクチャになっているかと！（なっていると良いな）
* フロントエンド：Webページ作成、APIコール
* バックエンド：データ作成、取得API
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3138153/6e56d9d7-7451-3506-bf6d-6bab73321842.png)

# まとめ
なにはともあれ実装は完了してます〇
コンテナ周りやAPIは勉強中なので、アーキテクチャや構築手順をQiitaにまとめることで勉強したことの復習に役立てようかと。
まとめたことが他の人の役に立てば良いなと。
次回以降から構築手順をまとめていきます！！

次↓
[AWS Fargate, ECSを用いたコンテナ運用設計、構築をしてみた。~ネットワーク編~](https://qiita.com/bakuchiku/items/b9b723e33d18d0164fed "AWS Fargate, ECSを用いたコンテナ運用設計、構築をしてみた。~ネットワーク編~")
HTML/CSSを始めよう!

## HTML
HTMLは全体を要素として前に開始タグをつける、後には終了タグを。
空要素：タグで囲うコンテンツがなく、その存在を開始タグだけで示す要素のこと（終了タグはない）
例）img要素・br要素・br要素・input要素・meta要素・link要素
属性を指定することもできる。
例）src・alt

- 全体構造
DOCTYPE宣言の中に
`html要素`の中に
`head要素`・`body要素`を順に一つずつ配置する
`html要素`：HTML文書のルート（DOMツリーの頂点）となる要素。すべての要素はこの要素の中に書く。グローバル属性であるlang属性を指定してその文書で使用されている言語の種類を示す。<html lang="ja">
`head要素`：HTML文書のメタデータコンテンツをいれるための要素。この要素の中にtitle要素をいれる
`body要素`：HTML文書のコンテンツを入れるための要素。
`title要素`：それがHTML文書のタイトルまたは名前であることを示す要素。
`meta要素`：
`link要素`：
`div要素`：他のほとんどの要素と異なり、その範囲が何であるのかを示さない要素。他に使用すべき適切な要素がない場合にのみ使用することが推奨される。class属性・lang属性・title属性などを指定することで用途を示す。
`span要素`：div要素と同様にその範囲が何であるかを示さない要素。class属性・lang属性・title属性などを指定することで用途を示す。

- セクション
`h1~h6要素`：セクションの見出しとなる要素
`hgroup要素`：見出しとサブタイトル、副題などをグループ化する
`article要素`：
`section要素`：一般的なセクションを表す要素
`aside要素`：
`nav要素`：そのページのおけるナビゲーションのリンクを含むセクション
`header要素`：その部分のヘッダーであることを示す要素
`footer要素`：自分自身を含むもっとも近いセクションのフッターであることを示す要素
`main要素`：その部分がその文書における主要なコンテンツであることを示す要素
`adress要素`：自分自身を含むもっとも近いarticle要素またはbody要素の内容に関する問い合わせ先を示す要素

- テキスト
`p要素`：一つの段落を表す（paragraph）
`a要素`：href属性を指定すると、そのa要素の要素内容がリンクになります。
`em要素`：強調されている部分を示すための要素
`strong要素`：その要素の内容が重要、緊急性を示す要素。
`blockquote要素`：引用してきた文章を示す要素
`br要素`：改行させるための空要素

- リスト
`ul要素`：箇条書きのような項目を持つリストを表すための要素。この要素内にli要素としてマークアップする























- グローバル属性
すべての要素に共通して指定できる属性のこと。
`class属性`：それを指定した要素が属する種類・分類を示すための属性
`id属性`：それを指定した要素に固有の名前をつけるための属性。固有ですので同じページ内の他のid属性に同じ値を指定できない
`lang属性`：要素内容と属性値の言語の種類を示す属性
`title属性`：ブラウザではツールチップで表示される
`style属性`：CSSの宣言

- 問い合わせフォーム




## CSS

`セレクタ`：CSS適用先
セレクタに続く｛｝の範囲全体を宣言ブロックと言い、その中のそれぞれの表示指定は`宣言`という。
宣言ブロックの中に宣言が複数ある場合は;で区切る。セレクタは,で区切ることで複数指定することが可能。
宣言の前半部分のキーのようなものが`プロパティ`といい、値の部分を`値`という。



link要素は関連する別の文書やファイルなどを示すための空要素。外部スタイルシートを読み込む際にも、このlink要素が使用される。
style要素は要素内容としてCSSを組み込むことができる。



|  TH  |  TH  ||
| ---- | ---- | ---- |
|  TD  |  TD  | |
|  TD  |  TD  ||
DevToolsの主なパネル

`Elements（要素）`：WebページのDOM（Document Object Model）を表示し、要素を選択し、スタイルや属性を変更することができます。要素を選択すると、対応するHTML要素がハイライト表示され、その要素に関する情報が表示されます。また、CSSスタイルを変更することで、Webページのデザインをリアルタイムで確認することができます

`Console（コンソール）`：JavaScriptコードをテストすることができます。また、ログやエラーメッセージを表示することもできます。また、コンソールにJavaScriptコードを入力することで、WebページのDOMを操作することができます。

`Sources（ソース）`：WebページのJavaScript、CSS、およびHTMLのソースコードを表示し、デバッグすることができます。

`Network（ネットワーク）`：WebページのHTTP通信を監視し、リクエストとレスポンスの情報を表示することができます。これにより、Webページがどのようにロードされているかを理解し、パフォーマンスの問題を特定することができます。

`Performance（パフォーマンス）`：Webページのパフォーマンスを測定し、ボトルネックを特定し、パフォーマンスを最適化するためのヒントを提供することができます。

`Application（アプリケーション）`：Webページのストレージ、クッキー、キャッシュなどの情報を表示することができます。

`Security（セキュリティ）`：WebページのHTTPS接続を確認し、セキュリティに関する警告やエラーを表示することができます。
Pythonで「Excelの実質行数」を知りたい件


# やりたいこと

Excelで
~~~
No  Data1 Data2  
 1  AAA   aaa
 2  BBB   bbb
 3  CCC   ccc
 4  DDD   ddd
 5  EEE   eee
 6  FFF   fff
 7  GGG   ggg
 8  HHH   hhh
 9
10
11
12
...
98
99
~~~
みたいに"No"だけがずっと先のNoで定義されているが実質はもっと少ないデータを、実質の部分だけ抜き出したい。
今回だと、行数が99行と言われるのではなく、行数は8行と言ってほしい。
※元Excelは、別の作成者が作ったもののため **編集不可** である点に注意。

# 参考文献
今回はChatGPTに書き方を聞いた。ChatGPTはいいぞ。

# ソリューション

```Python
#-------------------------------------------------
# 「列名」の中にデータが入っている行番号の最大
# ※Excelでindexだけが多数定義されているが実際のデータが無い場合の対応
# df  : DataFrame
# col_str: 列名
#-------------------------------------------------
def get_max_row_num_with_contain_data(df, col_str):
    print(" -> get_max_row_num_with_contain_data: " + str(col_str))
    row_num = df.index[df[col_str].notnull()].max() +1
    return row_num
```