OmniAICreator/Qiita-1.07M huggingface dataset:
SQLserver コマンドでログイン・ユーザ作成



<tag> TAG </tag>
* SQlServer
* SQL Server Management Studio 19.0.2

## 補足 ログインユーザー と データベースユーザー について
* ログインユーザー  :  ログインするのに必要なユーザー

* データベースユーザー  :  データベース毎に作成するユーザー
  
## 登録の流れとポイント

### 1. ログインユーザー を 登録

**ポイント**


* 変数を宣言
```.sql
DECLARE @sql NVARCHAR(MAX);
DECLARE @user_name NVARCHAR(MAX) = 'username';
```
* CREATE LOGIN で ログインユーザーを作成
```.sql
SET @sql = 'CREATE LOGIN ' + QUOTENAME(@user_name) + ' WITH PASSWORD = ''Password'', DEFAULT_DATABASE = ' + QUOTENAME(@db_name) + ';';
EXEC sp_executesql @sql;
```

<br>

### 2. ログインユーザー を データベース に登録

**ポイント**

* CREATE USERでデータベース に １で作成したログインユーザーを登録する

```.sql
SET @sql = 'CREATE USER ' + QUOTENAME(@user_name) + ' FOR LOGIN ' + QUOTENAME(@user_name) + ';';
EXEC sp_executesql @sql;
```

### 3. 権限付与

**ポイント**
* ALTER ROLE
* db_datareader : Read
* db_datawriter : Write
* db_execute : Execute※

```.sql
SET @sql = 'ALTER ROLE db_datareader ADD MEMBER ' + QUOTENAME(@user_name) + ';';
EXEC sp_executesql @sql;

SET @sql = 'ALTER ROLE db_datawriter ADD MEMBER ' + QUOTENAME(@user_name) + ';';
EXEC sp_executesql @sql;

SET @sql = 'ALTER ROLE db_execute ADD MEMBER ' + QUOTENAME(@user_name) + ';';
EXEC sp_executesql @sql;
```

### ※db_executeの作成
```.sql
-- ロールが存在しない場合にのみロールを作成し、権限を与える
IF NOT EXISTS (SELECT 1 FROM sys.database_principals WHERE name = 'db_execute' AND type = 'R')
BEGIN
    -- ロールを作成
    CREATE ROLE db_execute;
    -- 作成したロールに「実行」権限を与える
    GRANT EXECUTE TO db_execute;
END
```
## その他 bat文法

**実行確認処理**
```.bat
@echo off
SET /P ANSWER="ログインユーザを作成します。 (Y/N)？"

if /i {%ANSWER%}=={y} (goto :yes)
if /i {%ANSWER%}=={yes} (goto :yes)
EXIT
:yes
```

**接続情報とSQLファイルの実行**

```.bat
REM #####################
REM ★接続情報
REM #####################
REM サーバー名(サーバーのPC名\インスタンス名)
set dbServer=192.168.xxx.xxx
REM データベース名
set dbName=test_db
REM ユーザー名
set userName=sa
REM パスワード
set password=testpass

REM #####################
REM ★SQLファイルを実行
REM #####################

sqlcmd -S %dbServer% -d %dbName% -U %userName% -P %password% -i create.sql >> log.txt

echo バッチを実行しました。
pause
```



## その他 SQL文法


**SQL発行手順**
1. @sqlにSQL文を代入する
2. QUOTENAME()を使って変数を変換する※注意
3. EXEC sp_executesql @sql でSQLを実行する

```.sql
SET @sql = 'ALTER ROLE db_datareader ADD MEMBER ' + QUOTENAME(@user_name) + ';';
EXEC sp_executesql @sql;
```
**※注意**
以下のように直接ステートメントに変数を使うとエラーになる
```
ALTER ROLE db_datareader ADD MEMBER @user_name;
```



**変数宣言・代入**
```.sql
DECLARE @db_name NVARCHAR(128);
SET @db_name = 'test_db';
```

**配列**
```.sql
DECLARE @user_names TABLE (Name VARCHAR(30));
INSERT INTO @user_names (Name) VALUES 
    ('TEST_01'),
    ('TEST_02'),
    ('TEST_03');
```

**for**
```.sql
DECLARE userNameCursor CURSOR FOR
SELECT Name FROM @user_names;

OPEN userNameCursor;
FETCH NEXT FROM userNameCursor INTO @user_name;

WHILE @@FETCH_STATUS = 0
BEGIN
    DECLARE @sql NVARCHAR(max);

    -- ここに処理

END

CLOSE userNameCursor;
DEALLOCATE userNameCursor;
```
AWSの認定ソリューションアーキテクト-アソシエイト合格体験記（2024年3月版）

## はじめに

2024年3月に、AWSの認定ソリューションアーキテクト-アソシエイト（通称AWS SAA-C03）を受験し、合格することができました。勉強をする中での反省点や、受験前のudemyの模擬試験の成績など、これからAWS SAAを受験する方に役立つ情報を共有したいと思います。

## 学習開始前の知識状況
AWS SAAの学習を開始する時点での状況は以下の通りでした。

・AWSの経験は、新人研修で1か月触った程度
・AWS クラウドプラクティショナー取得なし
・保有資格はITパスポートとG検定

## 実際に行った試験対策
udemy＋Ping-tの2つの教材を使用して２ヶ月半程で合格しました。

1.udemy(有料)

【SAA-C03 版】これだけで OK！ AWS 認定ソリューションアーキテクト–アソシエイト試験突破講座

実際にAWSコンソール上で手を動かして学ぶハンズオン動画講義です。動画だけで合計47時間以上もあるため、学習時間におよそ１ヶ月かかりました。udemyのセール期間を狙うと1500円で購入可能です。

https://www.udemy.com/course/aws-associate/?couponCode=ST12MT030524

2.Ping-t ソリューションアーキテクト－アソシエイト（無料）

無料の問題演習サイトです。一部の資格は有料ですが、AWS SAAの問題は完全無料です。

2024年3月7日時点で問題数は636問あり、これが無料で利用できるのは脅威的です。
他のAWS SAAの問題集と比べ、難易度の低い問題が多いという特徴があります。ですが上記のudemyの模擬問題に比べ、圧倒的に解説が丁寧でした。１周半で学習時間におよそ１ヶ月かかりました。

https://ping-t.com/
 
## 試験当日と結果
試験の得点は812/1000点でした。（合格ライン720点）
難易度はping-tの問題より高く、udemyの模擬問題より低かったです。ちなみに直前に行ったudemyの模擬試験のスコアは73％でした。初めて聞くサービス名についての問いがありましたが、基本的なサービスの理解をしっかりしていればping-tの問題集の知識で回答できる問題が９割だったと思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3738134/07af71d7-97a1-bab4-a185-72cce19d0700.png)

## オススメの試験対策
結論、Ping-tのみで十分です。
udemyはハンズオンの部分に冗長な箇所があり、時間がかかりすぎるため効率良くありません。また、Amazonで評価の高い書籍の解説よりping-tの解説の方が断然わかりやすく頭に入りやすいです。
ping-tは単元ごとの基本問題が充実しており実践問題は解説が非常に丁寧で、基礎となる土台の理解がしやすいと思います。ping-tで基礎〜応用まで網羅できるので最短で試験に合格したい場合は、ping-tだけに一点集中するのが最も効率よく合格できると今回の試験対策で感じました。

## まとめ
AWS SAAの効率的な勉強としてはPing-tで模擬試験が受けられるくらいまでの理解度にもっていき模擬試験で量をこなして仕上げられるかだと思います。

私自身なんとか無事に合格はしましたが、知識だけはある頭でっかちの状態になってしまっているので、これからはudemyの講座のハンズオンなどを利用してゆっくり手を動かしていこうと思います。
3/9 tecHub（IT交流会）を秋葉原で開催！

![3-9tecHub1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3670233/b806da27-db6d-f609-4e46-fb6e0d38f9d4.jpeg)

4月が近づき、慣れ親しむ仕事や生活が変わる時期になりました。
新生活に備えると共に仕事の悩み事や、キャリアアップなど、考える人も多いのではないでしょうか？

3月度のtecHubでは、そのような悩み・課題の解決に向けてヒントを得ようとする人が集まった交流会になりました。

**目次▼**
<INS>[毎月開催のイベントです](#毎月開催のイベントです)
[イベントに参加した人の声](#イベントに参加した人の声)
[今後について](#今後について)
[次回の開催](#次回の開催)</INS>

3/9にtecHubを秋葉原で開催しました。
参加者は約60名となり大盛況でした！

日付：3/9(土)　14:00～16:30
場所：LIFORK秋葉原Ⅱ1階ラウンジ
参加者：60名
内容：IT交流会


<h3>毎月開催のイベントです</h3>
tecHubは3ヶ月に1度、LT(ライトニングトーク)と懇親会の2部構成のイベントを開催していましたが、昨年から交流会をメインとしたイベントを開催し、毎回60~80名近くの方が参加している人気のイベントとなっております。

IT交流会では、ピザとドリンクを片手に、参加者同士が情報交換や、他の分野の話を聞いたり、キャリアの相談をしたりと、普段の職場では聞けない話が聞けることで、会を重ねるごとに参加する方が増えています。

![3-9tecHub2 (1).JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3670233/37d08f01-0857-28e1-6316-6fecccc8797a.jpeg)

<h3>イベントに参加した人の声</h3>
今回も、幅広い分野のIT関係者が集まり、会社員からフリーランスエンジニア、法人化されている方と、様々な人が参加していました。

幅広い分野と様々なキャリアの人がいることで、転職やフリーランス転向などキャリアアップを考えている人にも今後の働き方をイメージでき、参加してよかった、勉強になったなどの声もいただいています。

さらにIT業界に興味ある他業界の方も参加しており、IT業界の話が聞けて良かったとの声もありました。イベント中はもちろんの事、会場の扉が閉まる最後まで活気ある雰囲気で盛り上がりました。

<h3>今後について</h3>
来月も交流会メインのイベントを実施します。
今後もtecHubをよろしくお願いいたします。

<h3>次回の開催</h3>
次回の開催は以下の日程を予定しております。

日時：4/20(土)　14:00～16:30　
場所：LIFORK秋葉原Ⅱ1階ラウンジ
内容：IT交流会
詳細とお申込みは以下をご確認ください。

https://www.navi56.com/communities/tecHub

※イベントの申込みにはコミュニティに参加が必要になります。tecHubコミュニティに参加後にサイト内のイベントからお申込みください。
Rails6にyarnでBootstrap5.0を導入したらHerokuへのデプロイの際にエラーが起きた

Railsでyarnを使ってBootstrapを導入後、Herokuへのデプロイ時エラーに遭遇したので共有と備忘録として記事にしました。

## 開発環境

Ruby 3.0.1

Rails 6.1.7.6

導入したBootstrap5.0.2

## yarnを使ってBootstrapを導入した手順

以下の記事の手順を参考にさせていただき導入しました。
> [【2022年最新】Rails6にBootstrap5を導入する方法 - Qiita](https://qiita.com/jibiking/items/d2ebb21db620f9cce887)


### Bootstrap5.0.2をインストール

```bash
$ yarn add bootstrap@5.0.2
```

popper.jsをインストール

```bash
$ yarn add @popperjs/core
```

### application.html.erbに追記

```ruby:app/views/layouts/application.html.erb
<!DOCTYPE html>
<html>
  <head>
    <title>Title</title>
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <%= csrf_meta_tags %>
    <%= csp_meta_tag %>

    <% stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
    <%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
    <%# ここに追加↓ %>
    <%= stylesheet_pack_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
	　　<%# ここに追加↑ %>
  </head>

  <body>
    <%= yield %>
  </body>
</html>
```

### application.scssの作成・追記

```bash
$ mkdir ./app/javascript/stylesheets
$ touch ./app/javascript/stylesheets/application.scss
```

作成したapplication.scssに以下の文を記入

```ruby:app/javascript/stylesheets/application.scss
@import "~bootstrap/scss/bootstrap.scss";
```

### application.jsに追記

application.scssを読み込む記述をapplication.jsに追記

```ruby:app/javascript/packs/application.js
import Rails from "@rails/ujs"
import Turbolinks from "turbolinks"
import * as ActiveStorage from "@rails/activestorage"
import "channels"
// ここを追加↓
import "bootstrap";
import "../stylesheets/application.scss";
// ここを追加↑

Rails.start()
Turbolinks.start()
ActiveStorage.start()
```

## Herokuへのデプロイ時に起きたエラー

Bootstrap導入後、Herokuへデプロイしようとすると以下のようなエラーメッセージが返ってきました。

```bash
ERROR in ./app/javascript/stylesheets/application.scss
Module build failed (from ./node_modules/mini-css-extract-plugin/dist/loader.js):
ModuleBuildError: Module build failed (from ./node_modules/postcss-loader/src/index.js):
ParserError: Syntax Error at line: 1, column 25
```

上記のエラーメッセージに書いてある`./app/javascript/stylesheets/application.scss` の1行目の25列目に構文エラーがあるそうなので確認すると、先ほど記載したyarnを使ってBootstrapをインストールする際に作成したファイルへ記述した内容でした。

↓エラーがあった部分

```ruby
@import "~bootstrap/scss/bootstrap.scss";
```

## 解決方法

`./app/javascript/stylesheets/application.scss` にエラーがあることはわかりましたが、何が間違っているのか分からず。結局上記のエラーがあったファイルは削除してCDNを使用する手順でBootstrapを入れ直して無事デプロイできました。導入する際は以下の記事を参考にさせていただきました。

https://qiita.com/kubochiro/items/8a73ac7c903d8b85a653

## 学んだこと
メンターさんも言っていたようにCDNで導入するのが簡単だしエラー少なく無難だと学びました📝
AtCoder Beginner Contest 337 振り返り

# ABC337
## 概要
https://atcoder.jp/contests/abc337

## A - Scoreboard
__考えてたこと__
特になし、全部足すだけ。

__提出したもの__
```c++:a.cpp
int main() {
    int n;
    cin >> n;
    int takahashi = 0;
    int aoki = 0;
    rep(i, 0, n) {
        int a, b;
        cin >> a >> b;
        takahashi += a;
        aoki += b;
    }
    if (takahashi > aoki) {
        cout << "Takahashi" << endl;
    } else if (takahashi < aoki) {
        cout << "Aoki" << endl;
    } else {
        cout << "Draw" << endl;
    }
    return 0;
}
```

__振り返り__
特になし。

## B - Extended ABC
__考えてたこと__
先頭からABC順番に消して行って文字列が残ったらYes, Noとかにする...?って考えたけど、最近お仕事で使ったから正規表現使ってみることにしたらすごく簡単だった。

__提出したもの__
```c++:b.cpp
int main() {
    string s;
    cin >> s;

    if (regex_match(s, regex("A*B*C*"))) {
        cout << "Yes" << endl;
    } else {
        cout << "No" << endl;
    }
    return 0;
}
```
__振り返り__
お仕事で偶然勉強したことがこういうところで活かせると少し嬉しくなります。

## C - Count xxx
__考えてたこと__
全然解けなくて解説を見てもよくわからなかったのでyoutubeの公式解説動画まで見てやっと理解できました。
n番目の人がA[i]の後ろで...みたいに難しく考えて自分の首を絞めていました。
解説を見ながら真似して書いたのが以下。

__提出したもの__
```c++:c.cpp
int main() {
    int n;
    cin >> n;
    vector<int> vec(n);
    map<int, int> map;

    for (int i = 0; i < n; i++) {
        cin >> vec[i];
    }

    // map[a]=bの時、aの後ろにbが並んでいる
    for (int i = 0; i < n; i++) {
        map[vec[i]] = i + 1;
    }

    int start;
    for (int i = 0; i < n; i++) {
        if (vec[i] == -1) {
            start = i + 1;
        }
    }

    int cnt = 0;
    while (cnt < n) {
        cout << start << " ";
        start = map[start];
    }
    cout << start << endl;
}
```


__振り返り__
自分で解いてた時でもmap[a]=b(bの後ろにaがいる)、みたいな連想配列自体を作れていたのでなぜそれを逆にできなかったのか...。落ち着いたら解けたかも、反省です。

## D - Cheating Gomoku Narabe
__考えてたこと__
これは実力不足で解けなかったかなぁと思いました。ただ累積和使う問題自体は以前も解いたことがあるので数をこなして慣れたいです。解説を見ながら書いたコードが以下。

__提出したもの__
```c++:d.cpp
int main() {
    int h, w, k;
    cin >> h >> w >> k;
    int x[200001], d[200001];
    char glid[h][w];
    for (int i = 0; i < h; i++) {
        for (int j = 0; j < w; j++) {
            cin >> glid[i][j];
        }
    }

    int ans = 1e9;
    for (int i = 0; i < h; i++) {
        for (int j = 0; j < w; j++) {
            x[j + 1] = x[j];
            d[j + 1] = d[j];
            if (glid[i][j] == 'x')
                x[j + 1]++;
            if (glid[i][j] == '.')
                d[j + 1]++;
        }
        for (int i = 0; i < w - k + 1; i++) {
            if (x[i + k] - x[i] == 0) {
                ans = min(ans, d[i + k] - d[i]);
            }
        }
    }

    for (int i = 0; i < w; i++) {
        for (int j = 0; j < h; j++) {
            x[j + 1] = x[j];
            d[j + 1] = d[j];
            if (glid[j][i] == 'x')
                x[j + 1]++;
            if (glid[j][i] == '.')
                d[j + 1]++;
        }
        for (int i = 0; i < h - k + 1; i++) {
            if (x[i + k] - x[i] == 0) {
                ans = min(ans, d[i + k] - d[i]);
            }
        }
    }

    if (ans > k)
        ans = -1;
    cout << ans << endl;

    return 0;
}
```
__振り返り__
解説にある通り、いきなり全部考えるんじゃなくてまずは一行の時にどのように求めるか、みたいに落ち着いて課題を分解すれば良かったかもです、学び。

## 感想
C問題までは安定して解きたいって思ってるからまた解けなくてちょっとショック。
落ち着いて解くことと数をこなして問題自体に慣れていきたいです。
MySQLで全角+半角の文字列検索がうまくいかない

## 事象
MySQLで全角、半角が入り混じった文字列を検索した際、狙ったデータが取得できずハマってしまった。。

### テーブル
| id | name |memo|
|:-----------|------------:|------------:|
| 1     | あ |半角スペース+文字列+半角スペース|
| 2     |　あ　|全角スペース+文字列+全角スペース|
| 3     | あ|半角スペース+文字列|
| 4     |　あ|全角スペース+文字列|

### SQL(半角スペース+文字列)
```
SELECT * FROM user_table WHERE name = " あ"
```
### 想定
| id | name |memo|
|:-----------|------------:|------------:|
| 3     | あ|半角スペース+文字列|

### 結果
| id | name |memo|
|:-----------|------------:|------------:|
| 1     | あ |半角スペース+文字列+半角スペース|
| 2     |　あ　|全角スペース+文字列+全角スペース|
| 3     | あ|半角スペース+文字列|
| 4     |　あ|全角スペース+文字列|

①半角スペースと全角スペースが区別されていない
②末尾のスペースが無視されている

## 原因
照合順序が「utf8mb4_unicode_ci」だったため
①大文字小文字区別しない/半角全角を区別しない
②pad属性が「PAD SPACE」つまり末尾のスペースが無視される

## 解決策
照合順序を「utf8mb4_bin」に変更したら意図した検索結果になった
末尾のスペースが無視される問題のみ解決したい場合は、演算子に「LIKE」を使うことで正確な文字列比較をしてくれる

## 参照元

照合順序
https://www.wakuwakubank.com/posts/797-mysql-collation/

pad属性
https://dev.mysql.com/doc/refman/8.0/ja/charset-binary-collations.html#charset-binary-collations-trailing-space-comparisons
Extract Product Data From Amazon Using ASIN to UPC and EAN

How_to_Extract_Product_Data_From_Amazon_Using_ASIN_to_UPC_and_EAN
You can search GTIN, ISBN, ASIN, UPC, EAN, or Keywords and find Amazon products search results.

Scrape product name, search ranking, ASIN, prices, etc. in real-time by searching any particular keyword, GTIN, ISBN, ASIN, or product’s name from Amazon’s search result pages.

Extract Amazon Data from Different Input Types
Find real-time Amazon search results by offering any of the given as inputs.

Product Name
Product ASIN
Search or Category URL
Part Number
EAN
UPC
GTIN
ISBN
Keywords
Just Go Through This Detailed Code
Just_Go_Through_This_Detailed_Code_01 Just_Go_Through_This_Detailed_Code_02 Just_Go_Through_This_Detailed_Code_03 Just_Go_Through_This_Detailed_Code_04 Just_Go_Through_This_Detailed_Code_05 Just_Go_Through_This_Detailed_Code_06 Just_Go_Through_This_Detailed_Code_07 Just_Go_Through_This_Detailed_Code_08
Get More Information by Integrating Amazon Products Data and Price Data Scraping from Actowiz Solutions
You can find more product data like best seller ranking, categories, product specification, images, etc., by integrating Amazon Products Data and Price API from Actowiz Solutions.

Easy Integration
Integrating our scraping services with your app and streaming scraped data flawlessly is easy.

Real-Time Data
Our scraping services API returns well-structured JSON data in real-time within a few seconds.

Avoid Captchas and IP Bans
We utilize the finest residential proxies for routing your requests and avoid captchas and IP bans.

Strong Infrastructure
Our robust infrastructure helps us scale our API to fulfill your daily high-volume demands.

If you want to extract product data from Amazon using ASIN to UPC and EAN, contact Actowiz Solutions now! You can also contact us for all your mobile app and web scraping services requirements.

sources >>> https://www.actowizsolutions.com/how-to-extract-product-data-from-amazon-using-asin-to-upc-and-ean.php
【読書メモ】ISUCON本 1章 チューニングの基礎知識

## はじめに
**自己紹介**
未経験からWEB系エンジニアへの転職を目指している者です。現在はRuby on Railsを学習中です。

**この記事を書いたきっかけ**
現在、プログラミング学習コミュニティでISUCONの勉強会に参加しています。
[『達人が教えるWebパフォーマンスチューニング〜ISUCONから学ぶ高速化の実践』](https://gihyo.jp/book/2022/978-4-297-12846-3)
を読みながら学習を進めているので、情報整理とアウトプットの練習を兼ねてQiitaで読書メモを作成することにしました。

## 要点
1章の要点を個人的にまとめました。

[1.高速なWebサービスとは？](#高速なwebサービスとは)
[2.必要十分なキャパシティを用意するには?](#必要十分なキャパシティを用意するには)
[3.パフォーマンスチューニングのきほん](#パフォーマンスチューニングのきほん)

## 高速なWebサービスとは？
**高速なシステムはコスト対性能効率が良い**
基本的にコストと性能はトレードオフなイメージがあるが、高速に処理できるということはサーバーのリソースを占有する時間が短いので、同じリソースでも単位時間あたりにたくさんの処理を実行できる。高速なシステムはムダがないということ。

**レイテンシが低い**
リクエストしてから、受信完了するまでの待機時間が短いということ。

**スループットが高い**
同時にたくさんのリクエストを処理できるということ。

## 必要十分なキャパシティを用意するには?

**Webサービスにおけるキャパシティ**
そのWebサービスがその時に利用可能な計算資源の量(CPU時間、メモリ容量、ネットワーク帯域など)のこと。

**必要十分であるとは**
需要に対してキャパシティが不足せず、過剰でない状態のこと。

**需要側の調整**
- 処理要求を順番待ちさせる(キューイング)
- 処理要求の受付を単位時間あたり一定数に絞る(レートリミット)
- 処理要求の発生にランダムな待ち時間を発生させる

**供給側の調整**
- 垂直スケーリング、水平スケーリングを事前に行う
- オートスケーリングでシステムリソース需要をもとにキャパシティを調整する

## パフォーマンスチューニングのきほん
**推測せず計測する**
推測してやみくもに改善するのではなく、ベンチマークの計測結果をもとに改善すべき箇所を探す。

**条件を揃えて公平に比較する**
2つのデータを比較する時は条件を揃えることで、変更箇所と結果の関係が推察できる。

**対策は1つづつ比較する**
対策を複数思いついたとしても、基本的には可能な限り1項目づつ対策を適用して効果を検証する。

**ボトルネックだけにアプローチする**
ボトルネック以外の箇所を改善してもパフォーマンスチューニング的な効果は得られない。

## 用語
<details><summary>レイテンシ</summary>

- データをリクエストしてからクライアントにデータが送られてくるまでに生じる通信の遅延時間のこと
- 単位は[ms]
</details>

<details><summary>スループット</summary>

- コンピュータやネットワーク機器が単位時間あたりに処理できるデータ量のこと
- 単位は「bps」「kbps」「Mbps」で1秒あたりのデータ量をビット数で表す
</details>

<details><summary>パフォーマンスチューニング</summary>

- 高速なWebサービスを実現するための取り組み
</details>

<details><summary>垂直スケーリング</summary>

- サーバーの性能を向上させてシステムリソースの総量を変える手法
- 性能を上げることをスケールアップ、性能を下げることをスケールダウンと呼ぶ
</details>

<details><summary>水平スケーリング</summary>

- サーバーの数を変えることで供給側のキャパシティを調整する手法
- サーバーの数を増やすことをスケールアウト、減らすことをスケールインと呼ぶ
</details>

<details><summary>オートスケーリング</summary>

- サーバー負荷に応じて、自動的にクラウドサーバーの台数を増減させる機能のこと
</details>
ミスしがちな俺がチェック用のjsを書いたらめちゃくちゃはかどった話

## 背景
「よっしゃー日本語50ページおわった〜 英語ページを作るか...！」

「日本語ページをコピーして、langをenにして、スタイル用にbodyにenクラスをつけて...タイトルとdescriptionも英語にしないと...」


「あ、ページ内のリンクも英語ページにいくようにしなきゃ...」

「...」

「いつかやりもらしがでそうだな...」

というわけで、ちょっと面倒だけどチェック用のjsを書いてみました

## 前提
- 英語ページは以下のように対応しています<br>（日）/about/index.html → （英）/en/about/index.html<br>（日）/contact/index.html → （英）/en/contact/index.html ...
- 日本語ページのHTMLをコピーして、英語ページを作成する想定です
- 全ページでmain.jsが読み込まれているものとします
- 本記事では以下の内容をチェックすることとします
    - lang属性がenになっているか
    - リンクが英語ページに飛ぶようになっているか

## 実装

大枠は以下のような感じ

``` javaScript: main.js
/**
 *    　　　　・
 * 　　   　　・
 * 　　　   　・
 * 　　　   　・
 * 　　　   　
 *  ここらへんにはハンバーガーメニューのjsなどいろんなコードが書かれています。
 *  チェック用のjsはわかりやすく一番下に書いときます
 * 
 * 
 * 
 */

 
document.addEventListener("DOMContentLoaded",() => {

  // urlに「/en/」が含まれていたら...
  if(location.href.match(/\/en\//)) {

    const checkLang = () => {
      // lang属性がenになっているか
    }

    const checkLinks = () => {
      // 全てのリンクが英語ページに飛ぶか
    }

    
    checkLang();
    checkLinks();
  };
})
```

今回はミスがあったらコンソールに表示するようにしました。また、リンクについては赤枠をつけてみました。

``` diff_javaScript: main.js
  document.addEventListener("DOMContentLoaded",() => {
+   let isError = false; // ミスがあったらtrueになる

    // urlに「/en/」が含まれていたら...
    if(location.href.match(/\/en\//)) {

      const checkLang = () => {
+       if(document.documentElement.lang !== "en") {
+         console.error("lang属性を確認してください");
+         isError = true;
+       }
+     }

      const checkLinks = () => {
+       const links = document.querySelectorAll('a');
+
+       for (const link of links) {
+         if(!link.getAttribute("href")?.match((/\/en\//))) {
+           console.error("以下の要素のhrefを確認してください");
+           console.error(link)
+
+           link.style.outline = "2px solid red";
+           isError = true;
+         }
        }
      }

      
      checkLang();
      checkLinks();
    };
  })

```

lang属性を変更し忘れたり、リンク先を英語ページにとばすのを忘れたりするとおこられます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2704882/cc0566d5-5202-e1bb-e96c-e9a8dac3d215.png)

今回はisErrorは使いませんでしたが、「isError が true だったらヘッダーのbodyを赤くする」などするとチェック事項が多くなってもすぐに気づくかもしれません（やりすぎ...？）

## 結果
書いたjsはそれほど難しくはないのですが、とにかく**ミスにすぐ気づけるという安心感**がものすごく良いです。
実際に英語ページを作ってみても、やれパンくずのTOPへのリンクが英語ページになってないだの、やれlang属性を変更し忘れるだの、やっぱりミスがありました。
そういった細かいミスをconsoleくんが指摘してくれるのはとてもありがたかったです。

## 最後に
やっぱりこういった単純なチェック作業はコンピュータに任せたいね
【MySQL】データベースのセキュリティや障害対策についてのメモ

https://dev.mysql.com/doc/refman/8.0/ja/security-guidelines.html

mysql -u rootを打ってパスワードを入力せずにサーバに入れたらやばい。

平文パスワードをデータベースに保存しない。ハッシュ化する。ハッシュ化するときに平文をそのままハッシュ関数に入れると、レインボーテーブルを使ってデータが漏れてしまう可能性があるから、hash(hash(パスワード)+ソルト) 値という風にする。

https://it-trend.jp/encryption/article/64-0067

https://qiita.com/thtitech/items/c2fba7cd3495eefffcf0

辞書にかいてあるような単語をパスワードにしない。

ファイアウォールを必ず設定する。

ユーザから送られるデータを信頼しない。例えばSQLインジェクションとかがある。

https://www.nttpc.co.jp/column/security/sql_injection.html

```
shell> mysql -u francis -pfrank db_name
```

じゃなくて、

```
shell> mysql -u francis -p db_name
Enter password: ********
```
【備忘録】Docker使ってLaravel sailで環境構築〜手動〜

## はじめに

Laravel sailっていう便利なコマンドツールがあるらしいので、それを使ってLaravelの環境構築をしました。
DockerもLaravel sailも初めて使います。
Dockerのセキュリティ対策の設定があるらしいので変更してからLaravel sailの環境構築しようとコマンドを実行しても、ディレクトリが作成されず、つまづいておりました。
（参考記事：[dockerでWhalesayイメージがpull(run)できない時の対処法](https://qiita.com/nasuB7373/items/92166d7958044ab8d450)）
> Dockerで環境構築するときにDockerのセキュリティ機能であるDOCKER_CONTENT_TRUST（DCT）が有効になっているので解除する。
> 
とりあえず、タスク進捗が悪いと、（チーム開発なので）他の方々にご迷惑おかけしそうなので、下記の手順（手動）で環境構築しました。

## 【環境】

・DockerのバージョンはDocker version 24.0.7, build afdd53b
・Docker Desktop 4.26.1
・macOS Sonoma 14.3（アップデート前の14.2でも確認済み）
・PHPのバージョンは8.0

## １、手動でLaravelアプリケーションの作成

```php
composer create-project --prefer-dist laravel/laravel post_backend
```

今回は「post_backend」というプロジェクト名で作成しました。

## ２、Laravel sailのインストール

```php
composer require laravel/sail --dev
```

## ３、Laravel sailのキャッチアップ

```php
php artisan sail:install
```

（途中でWhich services would you like to install? [mysql]:と聞かれたので、mysqlを選んでおきました。スクショしておけばよかった😭）

## ４、Dockerの起動

```php
./vendor/bin/sail up
```

## ５、設定ファイルの編集

「config/app.php」でタイムゾーンと言語の設定とdocker-compose.yamlファイルでphpmyAdminの設定を追記。
以下のQiita記事より「２. 設定ファイルの編集」を参考。

（参考記事：[Laravel10の環境構築手順書(Mac, Laravel Sail)](https://qiita.com/0528604/items/0fb3f1bdcade952a004b)）

## ６、Docker起動

```php
./vendor/bin/sail up -d
```

大成功( ◠‿◠ )

![スクリーンショット 2024-01-31 3.44.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3681288/1b243ccb-b7b0-5451-4eaf-defa7f6b5fa1.png)


ここで問題！？
チーム開発なので、Gitにある環境と同じ環境にしないといけないと思い、composer.jsonを目視確認。
ここでローカルのcomposer.jsonをgitにあるcomposer.jsonをコピペ。
composer updateというコマンドでgitにある環境と同じ環境にアップデートできました。

めでたしめでたし。

参考記事：
[dockerでWhalesayイメージがpull(run)できない時の対処法](https://qiita.com/nasuB7373/items/92166d7958044ab8d450)
[Laravel Sail 導入時に発生したエラーと解決方法](https://qiita.com/kuma15/items/ef4ea1a2088f8894e03e)
[Laravel sail を使って Laravel9 の環境構築を行う](https://qiita.com/hinako_n/items/45a7232b0b0ed16bffc8)
[Laravel10の環境構築手順書(Mac, Laravel Sail)](https://qiita.com/0528604/items/0fb3f1bdcade952a004b)
[composer install と composer updateの違い](https://qiita.com/YusukeHigaki/items/47dd3ec23544225f7301)
failed to authentification error!(wsl+docker engine,vscode環境構築等で起きた対処)

<b>環境</b>
・windows11 wsl ubuntu 22.04 LTS
・docker engine without docker desktop

<b>行ったこと</b>
1. wsl+docker engine
1. vscode環境構築&ローカル上でdocker containerのマウント
1. jupyter→python書き直し

# １に関して

<b>問題</b>
・ネット接続不可
sudo apt update を実行
→failed to authentification error!
これは社内でUbuntu環境構築の際に証明書が必要であった。mvコマンドやupdate等を実行し、指定の場所に証明書を入れる。
```
sudo apt-get install -y ca-certificates
mv <社内配布の証明書.srt?> /usr/local/share/ca-certificates
sudo update-ca-certificates
```
デフォルトであれば格納場所は上記で間違いないと思うがそれぞれの環境で確認してほしい。ディレクトリだけでも用意されてると思う。
これらのことを行うと、ネット接続（プロキシサーバー）がアクセスを認証してくれるようになる。
プロキシサーバはWifiのIDパスワードが入るので忘れないようにどこかに必ずメモしておく。

# 2に関して（vscode環境構築&ローカル上でdocker containerのマウント）
前の記事にざっくりと示した。
vscode上でcontainer構築&マウントができるようになった。
wslシェル上でtouch aを実行すると、vscode上にも反映された。
同期完了。（同期というより、マウントしたことで同じところを見れるようになった。）
<b>vscodeとシェル上のkeyword(F1)</b>
add dev container
reload window
format
mkdir .devcontainer
touch devcontainer.json
/bin/bash

# 3に関して
.devcontainer-devcontainer.jsonファイルにpythonライブラリを記載。
環境を立ち上げるたびにpip installをする必要がなくなる。
LLM-Agentで自動運転用の3Dデータを生成する技術「ChatSim」について

Chatsimはマルチエージェントを使って、自動運転用の3Dシミュレーションデータを生成する技術です。（自動運転の学習データとしても活用できると思います）
最近中国で話題になりましたので、共有したいと思います。

実際自動運転シーンの生成プロセスは、以下のようなイメージです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3556459/4253db25-4f7e-eaf3-cad0-7f36ebd771ae.png)

ChatSimの最も大きな特徴は、画面の一貫性を保持できることです。
従来の自動運転シミュレーションデータの生成では、主に二つのアプローチがあります。一つは、道路や車などすべての要素の3Dモデルを作成し、自動運転のシーンをツールで模擬する方法です（よく使われているツールとは、CARLA、AirSimなどがあるようです）。もう一つは、画像生成技術で生成する方法です。

それぞれのアプローチには弱点があって、3Dモデルを使用する方法では、時間もかかりますし、解像度も高くないため、現実世界との差異があります。一方、画像生成では、一貫性を保持できないことが課題となっています。同じプロンプトを使用しても、わずかな内容の変更により、生成された画像が前の画像と大きく異なってしまうことは避けられません。

ChatSimは、複数のエージェントにタスクを分担し、それぞれエージェントが担当する生成の部分だけを変更することで、生成される画像の一貫性を保つことができるようになりました。

もう一つはレンダリングに関する進化ですが、これは私もよくわからなかったです。ChatSimは、McNeRFという新しい神経放射場を提案しました。これは、複数のカメラを何らかの方法で調整することで、できるだけ一貫性のあるレンダリングを実現できるような技術らしいです。

⇩はClaude3がMcNeRFに対す解釈
「McNeRFは、複数のカメラアングルから撮影された画像を入力とし、シーンの3D表現を学習します。この3D表現は、連続的な関数で表現されるため、任意のカメラアングルからシーンをレンダリングすることができます。これにより、カメラが移動しても、シーンの見え方が自然で一貫性のあるものになります。」


ChatSimが実際使う時のサンプルもgithub上に載せています。非常に使いやすいようです。
例えば、「視点がゆっくりと前方に移動します。近くの前方に、前に移動している車を追加してください。」と指示すると、⇩のような動画が生成されます。

![2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3556459/ba18daf7-ab69-c174-f6a9-efacec4db4b6.gif)

そして、別の条件を加えて、「追加された車を左折するように修正してください。追加された車の前にもう1台”Chevrolet”を追加してください。」にすると、⇩のような動画が生成されます。ターゲットとなっている車だけが変化し、他のものは全く変わっていません。

![3.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3556459/02f3e164-fdd5-f207-62c8-e8c364373cf1.gif)


「左側に、こちらに向かってくる車を追加してください。」といった指示も可能です

![4.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3556459/ac41b54f-d27d-49ad-289c-90e88f970067.gif)


マルチエージェント間のチューニングは非常に複雑であるため、中身はどう設計しているのは論文内で公開されていないですが、github上では近日中にコードを公開したいと書かれていますので、コードが公開されたらどのように実現したのかを確認したいと思います。


興味ある方：

https://github.com/yifanlu0227/ChatSim

https://arxiv.org/abs/2402.05746
Nest.jsでロギング用のMiddlewareを実装しよう！

## 概要
ロギング用のMiddlewareを作成することでAPIを実行するたびに共通のログを出力できるのでとても便利で実装方法について解説します

## 前提
- Nest.jsのアプリケーションを作成済み

## ディレクトリ構成
```
tree
.
└── application
    ├── README.md
    ├── common
    │   └── logger.middleware.ts
    ├── nest-cli.json
    ├── package-lock.json
    ├── package.json
    └── src
        ├── app.controller.ts
        ├── app.module.ts
        ├── app.service.ts
        └── main.ts
```

## 実装
ロギング用のMiddlewareを実装する際に
- logger.middleware.ts
- main.ts

を作成および編集する必要があります

### logger.middleware.ts
今回作成するロギング用のMiddlewareのクラスです
レスポンスが帰ってきてからログを出力したいので

```typescript
response.on('finish', () => {
```
と記載します
また、
```typescript
this.logger.log(`${ip} ${method} ${originalUrl} ${statusCode}`);
```

の箇所で出力したいログの形式を指定します


```common/logger.middleware.ts
// logger.middleware.ts
import { Injectable, NestMiddleware, Logger } from '@nestjs/common';
import { Request, Response, NextFunction } from 'express';

@Injectable()
export class LoggerMiddleware implements NestMiddleware {
  private readonly logger = new Logger('HTTP');

  use(request: Request, response: Response, next: NextFunction): void {
    const { ip, method, originalUrl } = request;
    response.on('finish', () => {
      const { statusCode } = response;
      this.logger.log(`${ip} ${method} ${originalUrl} ${statusCode}`);
    });
    next();
  }
}

```

## app.module.ts
Moduleに先ほど作成したLoggerMiddlewareを適用するよう設定します
今回は全てのAPIにLoggerMiddlerwareを適用させたいのでforRoutesで指定するルートをアスタリスク(*)にします

```src/app.module.ts
import { MiddlewareConsumer, Module, NestModule } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { LoggerMiddleware } from 'common/logger.middleware';

@Module({
  controllers: [AppController],
  providers: [AppService],
})
// LoggerMiddlewareの設定を全ルートで適用する
export class AppModule implements NestModule {
  configure(consumer: MiddlewareConsumer) {
    consumer.apply(LoggerMiddleware).forRoutes('*');
  }
}

```

## APIを実行してみよう！
以下のようにAPIを実行した際にログが表示されたら成功です

```
2024-03-07 15:47:07 [Nest] 48498  - 03/07/2024, 6:47:07 AM     LOG [HTTP] ::ffff:192.168.65.1 POST /auth/signup 201
```

## 参考
https://docs.nestjs.com/middleware
cosmos DB: RBAC permissons が無い、と言われた時の対処。コントロールプレーン vs データプレーン

# 背景

Cosmos DB をアプリから操作する際に出たエラーの対処の記録
エラー自体はこんな感じ。

> principal [principal id] does not have required RBAC permissions to perform action [Microsoft.DocumentDB/databaseAccounts/readMetadata] on 
resource [/]. Learn more: https://aka.ms/cosmos-native-rbac.

単なる RBAC 化と思い、 Azure Portal でサクッと解決するかと思ったが、ちょっと違ったって話。

コントロールプレーンではなく、データプレーンでの RBAC を行う必要があった。

# 結論

cosmosdb 用の Role をアサインする。

- Read

> az cosmosdb sql role assignment create -a \<cosmosdbName> -g \<resourceGroupName> -s "/" -p \<principalId> -d 00000000-0000-0000-0000-000000000001

- Read/Write

> az cosmosdb sql role assignment create -a \<cosmosdbName> -g \<resourceGroupName> -s "/" -p \<principalId> -d 00000000-0000-0000-0000-000000000002

カスタムロールも作成して適用可能。

# 詳細

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/bb3b238a-97b0-6fe3-7894-3197dcb45e44.png)

Resource から IAM で設定できるRBAC とは違って、Cosmos DB に対しての Role があるそうな。

現状は以下の理解

- 管理プレーン（コントロールプレーン）
    - ARM によって制御されるリソース管理の仕組み
- データプレーン
    - 各リソースにおける機能管理の仕組み

詳細は以下で。

https://learn.microsoft.com/ja-jp/azure/azure-resource-manager/management/control-plane-and-data-plane


で、cosmos DB については、以下

https://learn.microsoft.com/ja-jp/azure/cosmos-db/how-to-setup-rbac

Blog での言及が以下

https://techcommunity.microsoft.com/t5/azure-architecture-blog/configure-rbac-for-cosmos-db-with-managed-identity-instead-of/ba-p/3056638

# あとがき

RBAC をなんとなく理解したと思ってたら、control plane and data plane という未知なる扉が :sweat:
AWS WAF アプトプット

初めまして、メグです。

4月からAWSの仕事に携わるために、AWSの資格を取得するため日々勉強をしています。

今年の1月末に SAAを取得し、現在は3月末の SOAの試験に向けて勉強中です。

今回は、「**AWS WAF**」について学習した内容を、記憶を頼りに記載していきます。

## サービス概要
AWS WAF はサービスに対しての HTTP ,HTTPS リクエストをモニタリングする機能です。

保護対象のリソース
* Cloud Front ディストリビューション
* ALB
* AWS AppSync
* AWS API Gateway
* etc..


## 利点
#### 指定した基準でサービスを保護できる
* アクセス元IPアドレス
* アクセス元の国
* 悪意のある可能性があるSQLコード(SQLインジェクション）の有無
* 悪意のある可能性があるスクリプト（クロスサイトすくリプト）の有無


## 類似サービスとの違い
#### AWS Sheild

# 自己紹介
初めまして、メグです。(@megggguguuuuuuu)

高専を卒業後、新卒で今の会社に入社をしました。
今年の4月で、3年目突入になります。

現在は、SESにてとあるサービスの運用・保守をしています。
4月以降はAWS関連のメインの業務に参画する予定なため、AWSの勉強を行っております。

AWS資格を現在 CLF,SAA を取得しており、現在 SOA の資格取得に向けて勉強中。
DVA は6月までに取得するつもります。

AWS資格 12冠することが目標です。
同じくAWS 資格を目指す方は、お互いに刺激しあいながら資格取得に向けて頑張りましょう！

# 宣伝
毎週の土日に、僕が入社している会社のオフィス(池袋)にて「もくもく会」をしています。
ぜひご興味がある方がいましたらご参加ください！！！

https://mokumoku-teikoku.connpass.com/
Git 学習記録

Gitとは
----------------------------
Gitがファイルのバージョン管理をするため、効率的に開発を進めることができる


変更記録はスナップショットとして保存される
----------------------------
スナップショットで変更を記録することにより、差分を計算する手順が省かれ、マージする際に計算をせず、ブランチをマージすることができる
よって、開発の効率があがる

変更記録を差分で確認する際は、計算をする必要がある
https://gihyo.jp/dev/column/01/prog/2011/diff_sd200906

利点
バージョンを記録することにより、以前の状態の戻すことができる
バージョンを記録する際に、コミットをするため、コミットを辿ることで、以前のバージョンに戻すことできる

git add
----------------------------
１．git add コマンド実行後にGitオブジェクトが作成される
Gitオブジェクトは.git/object配下のディレクトリに保存される
Gitオブジェクトとは、blobオブジェクト、treeオブジェクト、commitオブジェクトなどが当たる

blobオブジェクト
git addしたファイルの中身ヘッダーとファイルの内容を、SHA1というハッシュ関数で40文字の英数字に変換したオブジェクトのこと
ハッシュIDのうち、最初の2文字をサブディレクトリとして、残りの38文字をオブジェクト名として保存する

```
#blobオブジェクトを確認
$ find .git/objects -type f
.git/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391

#ステージングされたハッシュIDを表示します
$ git hash-object test/test
e69de29bb2d1d6434b8b29ae775ad8c2e48c5391

#.git以下のファイル構造を表示する
--snip--
 tree .git
|-- objects
|   |-- e6
|   |   `-- 9de29bb2d1d6434b8b29ae775ad8c2e48c5391
--snip--

$ git ls-files --stage
100644 188f4affe876964499a95325588f71d4955c16ef 0       test
100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0       testgsdjfs
```
040000:ディレクトリ
100644:通常の実行不可能なファイル
100664:グループ書き込み可能な通常の実行不可能ファイル
100755:実行可能ファイル
120000:シンボリックリンク
160000:Gitのリンク
先頭の3文字は、ファイルやディレクトリそれ以外を指す
後半3文字は、権限を指す

競合がない場合は、0となる

git commit
----------------------------
２．treeオブジェクト
blobオブジェクト名は、ヘッダーとファイル内容をSHA1によって、ハッシュ化された名前となる
そのため、blobオブジェクトとgit addしたファイルを、treeオブジェクトが紐づける
※treeオブジェクトはファイル構造とは異なる
```
#ツリーファイルのIDを取得する
$ git cat-file -p HEAD
tree 850626a9d2a85698c118b332191586765aeb01f6
author user名 <xx@gmail.com> 1709757111 +0900
committer user名 <xx@gmail.com> 1709757111 +0900

test

#ツリーファイルの中身を表示する
$ git cat-file -p 850626
040000 tree f05af273ba36fe5176e5eaab349661a56b3d27a0    test
```

３．Commitオブジェクト
commit時にcommit オブジェクトが生成される
commit オブジェクトはいつ、だれが、何を、目的が記録される
```
#ツリーファイルのIDを取得する
$ git cat-file -p HEAD
tree 449ddfa86385848f2d570d485c2dfa376ff6408f
parent 7a519397572c9cb8e9bebb62182532ecaa00d429
author user名 <xx@gmail.com> 1709757111 +0900
committer user名 <xx@gmail.com> 1709757111 +0900
```
treeは、ツリーオブジェクトが保存されている
parentは、親コミットを保存している
committerは、コミットを実施した人を保存している
Authorは、ファイルを編集を実施した人を保存している



備考
----------------------------
gitの構造はシンプルで素敵ですね

https://qiita.com/hiroaki-u/items/1c474c569b674c24493b
https://stackoverflow.com/questions/737673/how-to-read-the-mode-field-of-git-ls-trees-output
日時チェックがしたい 

先日ふと
日付形式がyyyy/MM/dd の形式ではうまく実装ができない箇所があった。
uuuu/mm/ddの形式であれば実装できたのだが違いが分からなかったので簡単にまとめる。

以下はどこでも見るような簡単な日付チェックの処理の一文である。
```java

try {
      LocalDate.parse("日付を保持したクラス",DateTimeFormatter.ofPattern("uuuu-MM-dd").withResolverStyle(ResolverStyle.STRICT));
    } catch (DateTimeParseException e) {
      return false;
    }
```

処理に関して西暦で処理を実施するのであれば、
存在しない日付の自動的な修正も含めてuuuuの形式が無難であった。
逆に、存在しない日付をエラーとしたい場合は上記のように
ResolverStyle.STRICTをつけることで2022/09/31などをエラーとすることができる。
（※そのままだと自動的に09/30に修正してしまう）

逆に、
Japanesedate（）などで、和暦に変換したり
GをつけてADを表示したい場合などはyyyyの形式の方が柔軟に対応ができる

基本的なシステムでは西暦でデータを管理する方が主だと思うため、
特段指定がない場合はuuuuの形式の方がデータが崩れる心配などが低いかと思われる
Java util timerに関して（スケジューラ）

javaのtimerクラスに処理の定期実行を実施するクラスがある。
スケジュールメソッドで実行するのだが、
引数に
１・実行する処理
２・開始時間（ミリ秒）
３・実施間隔（ミリ秒）
で指定することで簡易的にではあるがJP１のような
定期実行処理をJavaで実施することができる。

例えばAの処理を10秒後に、60秒間隔で実行する
ような処理の場合
```java
    time.scheduleAtFixedRate(A(), 10000, 60000);
```
といった実装になる。

問題点としては複雑な実行処理が難しい点で
複数タスクをこのメソッドで実行するのはやや難がある

例えばサイトアクセスのカウントなどであれば単一のタスクを永遠と繰り返すだけのため
このようなTimerメソッドでも問題はないのだが、

A→B→Cのような連続したタスクの実行の場合
処理速度の如何によっては並行して処理が実施されるため挙動に影響が出る

複数の処理実施の場合はバッチで順々に呼び出す方が無難かと思われた

TimerクラスはThreadよりは使いやすそうに見えるが
周期的に実行するクラスとメインのクラスを同時に実施する場合は処理結果の同期化を
一定のタイミングで実施しないことには問題が出そうである
グローバルIPが無いけど外からリクエストを受け付けたいときに使うサービス2選

# はじめに

CTFでリバースシェルやXSSなどを試す際、リクエストを受け付けられるサーバが欲しくなることがあります。
ローカルPCをサーバとする場合、多くはNAT配下なのでポートフォワーディングを設定する必要があり面倒だったり権限がなかったりします。
またEC2などクラウドで立てることも1つですが、それ用に立てるのも手間です。

そこで無料で使えるサービスを使って、手軽にサーバを公開しようというのがこちらの記事です。

※本記事は紹介するサービスの安全性を保障するものではありません。

# Webhook.site

HTTP/HTTPSリクエストを受信して、リクエスト内容を表示してくれるサイトです。
XSSやSSRFのテストなどで使っています。

無料・会員登録無しで専用のURLを一時的に払い出してくれます。

こんな感じでリクエスト内容を表示してくれます。
履歴も確認できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3523344/1e01f0e6-5b82-4e48-2798-806f46a0c76e.png)

XSSのパラメタに情報を含めてこのURLにリクエストを飛ばすとか、SSRF出来そうなところにこのURLを送ってリクエストが来るか試すのに非常に便利です。

# Ngrok

無料ですが要会員登録です。

特定のポートを外部に中継して公開してくれるサービスです。
プロトコルとしてhttpはもちろん、tcpも指定できますので

`$ ngrok tcp 10443`

とすると、`$ nc -lvnp 10443`で待ち受けているものを外部からアクセス可能にすることができます。

以下のようにドメインとポート番号が表示されますので、そちらを使ってアクセスします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3523344/82338c63-715a-5e50-cdf5-4f7e217c55c6.png)

ドメインではなくIPアドレスがよければdigなどで名前解決して調べたIPアドレスを使えば大丈夫です。

# おわりに

グローバルIPが無くてもCTFなどで困らないようにするためのサービス2つをご紹介しました。
何かとちょっとだけ外からリクエストを受け付けたいことはあるかと思いますので、参考になれば幸いです。
RaycastでQiita記事を検索するQuicklinkを設定する

## はじめに

RaycastのQuicklink機能を使用して素早くQiitaの記事検索をする方法を紹介します。
Raycastの機能全般については [Raycastのススメと使い方
](https://zenn.dev/fumi_sagawa/articles/2ff5fd9c03fbcd)に詳しく載ってますので、気になる方はご参照ください。

## 設定手順

1. Raycastを起動し、macなら`command` + `,` で設定画面に移動します。
2. 「Extensions」タブをクリック「+」ボタン→「Create Custom Shortcut」を選択します。
    
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/260540/d2d13832-ab99-87a5-a3d8-5894234d31d4.png)
    
3. 「Name」フィールドにショートカットの名前を入力します（例：「qi」お好みで設定してください）
4. 「URL」フィールドに以下のURLを入力します：
ここで、`{Query}`は検索クエリに置き換えられます。
    
    ```
    <https://qiita.com/search?q={Query}>
    ```
    
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/260540/e03e52b8-6f96-f594-bd5b-9548e409d9f0.png)
    
5. 「Create Quicklink」ボタンをクリックしてショートカットを保存します。

## 使い方

1. Raycastを開き、`Nameに登録したキーワード` + `tab`を入力します。
2. Queryを入力してEnterキーを押すと、デフォルトのWebブラウザでQiitaの検索結果ページが表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/260540/f7c720c8-2e7e-1cf1-0bb6-c851ccc6d82d.png)


## まとめ

Raycastの機能を使えば、web検索などより効率的に行うことができます。
様々なカスタマイズができるので自分好みに設定してみてください。
【開発経験】Googleカレンダーの予定を追加し招待リンクを生成する

# はじめに
みなさんこんにちは！
まずは本記事を読んでいただきありがとうございます。

今回はボタンをクリックするとGoogleカレンダーの予定追加画面に遷移し、招待リンクを生成するときの手順を説明したいと思います。

# できること
URLリンクを設置し、ボタンをクリックするとGoogleカレンダーの予定追加画面に遷移し、初期値をセットすることができます。


例1）URLリンクをクリックすると初期値に予定の「件名」「詳細」がセットされます。

[URLリンク](https://www.google.com/calendar/render?action=TEMPLATE&text=同期ディズニー&dates=20240331T120000/20240331T140000&location=千葉県浦安市舞浜１−１&trp=true&details=サークルの同期と卒業旅行&trp=undefined&trp=true&sprop=&add=hoge@gmail.com)

![スクリーンショット 2024-03-07 20.23.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3691932/7c2a6fd9-cfd3-14f2-5a2b-3da11cd5cc1e.png)

## 実現方法

URLリンクに任意のパラメータに初期値の値をセットします。

例えば、 先ほどの例は下記のようなパラメータがセットされていました。

[https://www.google.com/calendar/render?action=TEMPLATE&text=同期ディズニー&dates=20240331T120000/20240331T140000&location=千葉県浦安市舞浜１−１&trp=true&details=サークルの同期と卒業旅行&trp=undefined&trp=true&sprop=&add=hoge@gmail.com](https://www.google.com/calendar/render?action=TEMPLATE&text=同期ディズニー&dates=20240331T120000/20240331T140000&location=千葉県浦安市舞浜１−１&trp=true&details=サークルの同期と卒業旅行&trp=undefined&trp=true&sprop=&add=hoge@gmail.com)


パラメータの一覧は以下のようになります。
　
|  パラメータ  |　説明 |
| ---- | ---- | 
| text  | 件名   |
| dates | 日時 <br>例） dates=20090621T063000Z/20090621T080000Z<br>フォーマット：YYYYMMDDTHHmmSSZ/YYYYMMDDTHHmmSSZ  | 
| location  | 場所   | 
| details | 詳細 |
| sprop | サイトURLやサイト名 |
| add  | ゲストのメールアドレス 複数指定する場合は「,」で区切る |

# 最後に

ここまで読んでいただきありがとうございます。

今回はボタンをクリックするとGoogleカレンダーの予定追加画面に遷移し、招待リンクを生成するときの手順を説明しました。

カレンダーの招待機能が、パラメータを指定してリンクを踏むだけで作成できることに非常に驚きました！

普通にgoogleカレンダーから入力しても同じやん！と思った方もいると思います。

そこで！！ 
応用例としては、イベント作成アプリが挙げられます。

**<フロー>**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3691932/ee553239-5f05-46db-9b08-ef94e61b772f.png)

**<フォーム>**
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3691932/f3055221-7b77-9bb1-ce8c-480b509a7a15.png" width=40%>

このような感じになります。

webサービスに組み込みたいと思った方はぜひ参考にしていただけると幸いです！！

## 参考
- [Googleカレンダーに追加するURLリンクを自動生成してくれるツール](https://webasterisk.sakura.ne.jp/googlecalendar_eventbuttonsgenerator/)
簡易版 画面を閉じる (SendMessage) 

WPFでも動くと思います。
FindWindowでタイトル検索してあった場合はSendMessageでWM_CLOSE送るだけ。
サンプルではC:　のトップDirを開いているエクスプローラを閉じる。
(複数ある場合はループさせるなり要工夫)

使い道としては、
・面倒な閉じる作業の自動化
・利用者に特定アプリを使用できないようにしたい等。

同様にDllImportでShowWindowを指定してSW_MAXIMIZE送ると最大化したり色々できます。

```c#
using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace WindowsFormsApp1 {
    public partial class Form1 : Form {

        // #define WM_CLOSE 0x0010

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

        [DllImport("user32.dll")]
        public static extern int SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam);

        public Form1() {
            InitializeComponent();

            IntPtr hWnd = FindWindow(null, "C:\\");
            if (hWnd != IntPtr.Zero) SendMessage(hWnd, 0x0010, (IntPtr)0, (IntPtr)0);
            
        }

        private void Form1_Load(object sender, EventArgs e) {
        }
    }
}

```
HTML・CSS　ナビゲーションメニューの実装方法

HTML・CSSにおいて、ナビゲーションメニューの実装を行って行く上で学んだことをアウトプットします。
まだまだ初心者ですので、間違っている箇所等ございましたら、ご指摘頂けると幸いです！

・ナビゲーションメニューとしたい文章（画像）をaタグで囲います。
```HTML:index.html
<a href="#mv">文章（画像）</a>
```
その後飛ばしたい先の部分をsectionタグで区切ります。
```HTML:index.html
<section id="mv">
  <div class="main-visual">
    <p class="main-title">Lorem Ipsum</p>
    <p class="sub-title">simply dummy text of the printing</p>
  </div>
</section>
```
上記のように記述すると、ナビゲーションメニューとして設定した文章（画像）はこの記述部分へと飛んでいってくれます。

以上簡単ではありますが、ナビゲーションメニューの実装でした！
Windows ServerでUSB Wifi受信アダプタを取り付けても動作しないときの解決策

Windows ServerでUSB Wifi受信アダプタを取り付けても動作しないときの解決策

先日、Windows ServerマシンにUSB Wifi受信アダプタを取り付けてインターネット接続する機会がありました。

接続したWifi受信端末は「ELECOM WDC-150SU2M Wireless Adapter」です。

同アダプタのドライバをインターネットの製品ドライバダウンロードページからダウンロード、そしてインストール、マシンがアダプタを認識した上で、Wifiに接続を試みたのですが、、、

Windowsコントロールパネル、Wifiネットワーク接続設定画面でインストールしたはずのWifiアダプタが認識されません!!!

そこでインターネット上でいろいろ検索したところ、以下のページたどり着きました。
結果的に、記載の通りの手順で実行したところ、解決しました。

:paperclip: Windows Server 2022でUSB Wi-Fiアダプタを差してもネットワークに接続できない
https://mag.autumn.org/Content.modf?id=20220313142712

備忘録のために抜粋、引用させていただきます。
※以下を実行する前に、アダプタのドライバをインストールしておいてください。

##### 1.管理者権限でPowerShellを起動する
　アイコンを右クリックして起動します。
##### 2.以下のコマンドを実行する
　`Install-WindowsFeature -Name Wireless-Networking`
　※コマンドを入力して[Enter]キーを押下する(以下同様)。
##### 3.以下のコマンドでコンピュータを再起動する
　`Restart-Computer`
##### 4. 管理者権限でPowerShellを起動する
　アイコンを右クリックして起動します。
##### 5.以下のコマンドを実行する
　`net start WlanSVC`


コントロールパネルのネットワークから「アダプタの接続の変更」を開き、
下図のように色がカラー(グレーでない)となっていることを確認する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399135/a5cffaaa-aaa4-e7ea-c8e0-622ce49b6cf1.png)

エラーが出ておらず、正常にインターネットに接続できればOK
S3 Multi-Region Access Points：AWSのプライベートネットワーク経由で別リージョンのS3にアクセスしたい

# はじめに
NTTデータの西川です。
普段は公共部門の技術集約組織でクラウドの導入支援に従事しています。

「別リージョンのS3にアクセスしたいけどインターネット経由は要件的に厳しいな～」って時ないですか？わたしはあります。

そこで今回は解決策の1つとしてS3 Multi-Region Access Pointsを紹介したいと思います。
> S3 Multi-Region Access Points
https://aws.amazon.com/jp/s3/features/multi-region-access-points/

# ユースケース
私が担当する公共部門のシステムでよくあるユースケースとして、プライベートネットワーク経由でバックアップリージョンのバックアップデータをメインリージョンヘリストアしたいケースがあります。
> 公共部門に限らずセキュリティ要件が厳しく求められる業界の方もよくあるユースケースではないでしょうか？

S3以外で別リージョンのAWSサービスの利用が必要な場合はTransit GatewayやVPC Peeringも選択肢として検討されるかもしれません。
しかし、バックアップ&リストア文脈でS3を使うためだけに、別リージョンにあるAWSサービスを利用したいケースは少なくないはずです。

# S3 Multi-Region Access Points
そんな場合の解決策の1つが今回紹介するS3 Multi-Region Access Pointsです。

「Amazon S3 のよくある質問」から、S3 Multi-Region Access Pointsの動作に関するQ&Aを抜粋してみました。

**S3 Multi-Region Access Pointsを利用して別リージョンのS3にアクセスする際の経路**は、インターネット経由ではなく**AWSグローバルネットワーク経由**であることが分かります。


>  **Q：S3 Multi-Region Access Points はどのように機能しますか?**
A：Multi-Region Access Points は、お客様のリクエストを 1 つ以上の基盤となる S3 バケットに動的にルーティングします。マルチリージョンアクセスポイントを設定して、1 つの AWS リージョンごとに 1 つのバケットを、最大 20 の AWS リージョンでルーティングすることができます。マルチリージョンアクセスポイントを作成すると、S3 は DNS と互換性のある名前を自動的に作成します。この名前は、お客様が使用できるグローバルエンドポイントとして使用されます。お客様がこのエンドポイントに対してリクエストを実行すると、S3 はそのリクエストを、Multi-Region Access Points の設定で指定された基盤となるバケットの 1 つに動的にルーティングします。**インターネットベースのリクエストは AWS グローバルネットワークにオンボーディングされ、インターネット上のネットワークセグメントの輻輳を回避します。**

私が初めて上記の文章を読んだ際、AWSグローバルネットワークってインターネットと何が違うんだっけ？と純粋に疑問に思いました。



# AWSグローバルネットワークとは？
AWSグローバルネットワークを知るために、AWSの公式情報を確認してみました。

**個々のデータセンター、リージョンを相互接続しているAWSグローバルネットワークはAWSが保有する専用線でプライベート接続されている**と記載されています。
つまり、AWSグローバルネットワークはインターネット経由とは異なり、AWSのプライベートネットワーク経由ということが明記されています。



> データセンターとリージョンを相互接続する AWS グローバルネットワークを流れるすべてのデータは、安全性が保証された施設を離れる前に、物理レイヤーで自動的に暗号化されます。どんなときでも暗号化、移動、保管管理を行う機能を含め、常にデータを制御しているという認識を持って、最も安全なグローバルインフラストラクチャを構築できます。

> AWS グローバルインフラストラクチャ
> https://aws.amazon.com/jp/about-aws/global-infrastructure/

# さいごに
S3 Multi-Region Access Pointsを利用することで、AWSのプライベートネットワーク経由で別リージョンのS3にアクセスすることができることが分かりました。

S3 Multi-Region Access Pointsの最新状況については公開情報をご確認ください。
※ 本ブログに記載した内容は個人の見解であり、所属する会社、組織とは関係ありません。


<br>

以下、追加の関連情報です。
Multi-Region Access Point policyを利用すると、指定した特定のVPCからのアクセスのみを許可するようなアクセス制限を行うことが可能だそうです。VPCレベルでアクセス制御をしたい場合は是非ご活用ください。

> Multi-Region Access Point policy
https://docs.aws.amazon.com/AmazonS3/latest/userguide/MultiRegionAccessPointPermissions.html#use-mrap-policy
Pythonで「bool関数の使い方(オブジェクトが真か偽か判定する)」の動作を確認してみた

# 概要

Pythonで「bool関数の使い方(オブジェクトが真か偽か判定する)」の動作を確認してみました。
以下のページを参考にしました。

https://www.javadrive.jp/python/function/index5.html

# 実装

以下のファイルを作成しました。
```sample.py
print(bool("Hello"))
print(bool(""))
print(bool(1))
print(bool(0))
print(bool(["A", "B"]))
print(bool([]))
```

以下のコマンドを実行しました。
```
$ python3 sample.py 
True
False
True
False
True
False
```

# まとめ

何かの役に立てばと。
【Python】辞書内包表記を使ってDBアクセス回数を減らす方法

# 概要
Pythonの辞書内包表記を使って、DBへの接続回数を減らす実装を行いました。
以下にサンプルコードを紹介します。

# 辞書内包表記を使う
例えば、以下のようなコードがあります（DjangoのORMを使用）。

```py
for item in list_fruit_cd:
    fruit_data = FruitCd.objects.filter(fruit_cd=item).first()
    ## 後続処理...
```

上記だと`list_fruit_cd`の要素数が大量の場合に毎回DBアクセスすることとなり、パフォーマンスに影響が出る可能性もあります。そんな場合に、`for`文の外で一度だけDBアクセスさせ、その結果を辞書に格納し、その後のループで辞書から必要なオブジェクトを取得するようにするとパフォーマンスが向上すると思われます。

つまり、以下のようにします。

```py
fruit_dict = {obj.fruit_cd: obj for obj in FruitCd.objects.filter(fruit_cd__in=list_fruit_cd)}

for item in list_fruit_cd:
    fruit_obj = fruit_dict.get(item)
    ## 後続処理...
```

これにより、`for`ループの中で毎回DBにアクセスすることがなくなりました。

## クラスを利用したサンプルコード
具体的にサンプルコードを作ってみていきます。
上記はDjangoのORM使用時でしたが、以下のようにPythonのクラスで再現することもできます。

```py
class FruitCd:
    def __init__(self, fruit_cd, name):
        self.fruit_cd = fruit_cd
        self.name = name

list_fruit_cd = [1, 2, 3, 4]
objects = [
    FruitCd(1, 'Banana'),
    FruitCd(2, 'Lemon'),
    FruitCd(3, 'Orange'),
    FruitCd(4, 'Apple'),
]

# fruit_cdがlist_fruit_cdに含まれるオブジェクトだけを辞書に変換
fruit_dict = {obj.fruit_cd: obj for obj in objects if obj.fruit_cd in list_fruit_cd}

# 結果を表示
for fruit_cd, obj in fruit_dict.items():
    print(f'{fruit_cd}: {obj.name}')

# 出力結果
# 1: Banana
# 2: Lemon
# 3: Orange
# 4: Apple
```


## 補足（サンプルコード解説）

```py
fruit_dict = {obj.fruit_cd: obj for obj in objects if obj.fruit_cd in list_fruit_cd}
```

上記の辞書内包表記の部分ですが、`objects`リストからオブジェクトを取り出し、そのオブジェクトの`fruit_cd`属性が`list_fruit_cd`に含まれている場合に、新しい辞書`fruit_dict`を作成する、というコードです。

`fruit_dict`を`print`してみると以下のように返ってくることがわかります。

```
{1: <__main__.FruitCd object at 0x101127fd0>, 2: <__main__.FruitCd object at 0x101127ee0>, 3: <__main__.FruitCd object at 0x101127e80>, 4: <__main__.FruitCd object at 0x101127e20>}
```

`fruit_cd`をキーとし、そのキーに対応する`FruitCd`オブジェクトを値とする辞書が生成されたことを確認できました。

そのあと、`for fruit_cd, obj in fruit_dict.items():`のところで、`fruit_dict`を反復処理。
`fruit_dict.items()`は辞書の各エントリーをキーと値のペア（タプル）として返します。`for`ループを使用して、これらのペアを一つずつ取り出し、キーに対応する値を出力するようにしています。
docker in dockerでボリュームがマウントされない

# はじめに

Docker in Docker (dind)のボリュームマウントで躓いたので図解でまとめます

# 問題

以下のような構成でボリュームマウントをしようと考えました

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/810513/60dec230-0a27-e2c7-ed96-f148d9970870.png)

Docker1の`/hoge`とDocker2の`/hoge`をマウントしようとしましたがなぜかうまくディレクトリがマウントされておらずDocker2の/hogeには中身のフィルがコピーされていませんでした

Docker1の中で以下のコマンドでボリュームマウントしました

```
$ docker run -v /hoge:/hoge ...
````

# 解決方法

DinDの場合、ボリュームマウントすると以下のようにホストのボリュームをマウントしてしまいます(Docker1のボリュームは関係なくデーモンのボリュームを共有する)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/810513/45aac69a-28da-46c0-4442-62a8a31518a8.png)

なので、ローカルと共有している`/sample`とDocker1の`/hoge`をマウントして、ローカルの`/sample`とDocker2の`/hoge`をマウントするとうまくいきます

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/810513/1106652c-ec57-24d9-2d11-570664c57347.png)

```
# ローカルで叩く
$ docker run -v /hoge:/sample ...

# Docker 1で叩く
$ docker run -v /sample:/hoge ...
````

この方法は1度ローカルのボリュームを経由するのでスピードが遅くなるなどデメリットも存在しますが、DinDで行う場合はこの方法が素早く実現する方法みたいです

# おわりに

過去に1度同じところでつまづいていたのですが、すぐに気づけなかったので図解でまとめてみました
「MCP9700サポート」Temperature MCP9701 MCP9700 の関数化(浮動小数点)(Arduino UNO)(リッチプログラミング)(マクロ)


「MCP9700サポート」Temperature MCP9701 MCP9700 の関数化(浮動小数点)(Arduino UNO)(リッチプログラミング)(マクロ)

Arduino 電子工作 ArduinoUno 温度センサー MCP9701

x MCP9701-E/TO 販売コード 103199
x 販売コード 103199 型番 MCP9701-E/TO
x 販売コード 114300 型番 MCP9700A-E/TO
x 販売コード 130012 型番 MCP9700T-E/TT
x 販売コード 109692 型番 MCP9700-E/TO

目的
温度センサーMCP9701のテスト
MCP9700サポート
AI、ノンコード、ローコード用
マクロ化することでローデング量を最小化

https://github.com/caa45040/Temperature_MCP9701_MCP9700

結果

![o_cop983.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/6cbdddcf-e324-775e-3961-c960d8a26ea2.jpeg)



プログラム


```c++


//SER_Temperature_MCP9701_UNO_3


//インクルド
#include <Arduino.h>
#include "Temperature_MCP9701_MCP9700.h"


//初期化処理
void setup()
{

  //シリアルの初期化
  Serial.begin(9600);

} //setup


//メインループ
void loop()
{

  //センサーの値を読み込む
  //int Sensor = analogRead(A0); // センサーの読み取り値
  //温度の表示
  //float Voltage = Sensor * ( 5.0 / 1024.0 );
  //float Temperature = Temperature_MCP9701(Voltage);
  //Serial.println(Temperature);

  //温度の表示
  Serial.println(Temperature_MCP9700_A0());

  //1秒の待ち
  delay(1000);

} //loop


```


Temperature_MCP9701_MCP9700.h



```c++



// Temperature_MCP9701_MCP9700.h 
//
// ex 3.3V analogReadResolution(12);
//         float Sensor = analogRead(A2);
//         float Voltage = Sensor * ( 3.3 / 4096.0 );
//         float Temperature = Temperature_MCP9701(Voltage);
//
float Temperature_MCP9701(float Voltage){

  return((Voltage - 0.4) * (1.0 / 0.0195));

}//Temperature_MCP9701


float Temperature_MCP9700(float Voltage){

  return((Voltage - 0.5) * (1.0 / 0.01));

}//Temperature_MCP9700


#define Temperature_MCP9701_A0() Temperature_MCP9701(analogRead(A0)*(5.0/1024.0))
#define Temperature_MCP9701_A1() Temperature_MCP9701(analogRead(A1)*(5.0/1024.0))
#define Temperature_MCP9701_A2() Temperature_MCP9701(analogRead(A2)*(5.0/1024.0))
#define Temperature_MCP9701_A3() Temperature_MCP9701(analogRead(A3)*(5.0/1024.0))
#define Temperature_MCP9701_A4() Temperature_MCP9701(analogRead(A4)*(5.0/1024.0))
#define Temperature_MCP9701_A5() Temperature_MCP9701(analogRead(A5)*(5.0/1024.0))

#define Temperature_MCP9700_A0() Temperature_MCP9700(analogRead(A0)*(5.0/1024.0))
#define Temperature_MCP9700_A1() Temperature_MCP9700(analogRead(A1)*(5.0/1024.0))
#define Temperature_MCP9700_A2() Temperature_MCP9700(analogRead(A2)*(5.0/1024.0))
#define Temperature_MCP9700_A3() Temperature_MCP9700(analogRead(A3)*(5.0/1024.0))
#define Temperature_MCP9700_A4() Temperature_MCP9700(analogRead(A4)*(5.0/1024.0))
#define Temperature_MCP9700_A5() Temperature_MCP9700(analogRead(A5)*(5.0/1024.0))



```