OmniAICreator/Qiita-1.07M huggingface dataset:
M5NanoC6とOLED SSD1306で遊ぶ (「46」よろーを表示)(ESP32-C6)(GROVE)


参考

https://qiita.com/caa45040/items/3c57c159be0fd0f7a718


https://qiita.com/caa45040/items/f7698f087967381f91af


x 過去ログを見よ!!
x Adafruit_GFXとAdafruit_SSD1306をインストール
x M5Nano C6の事
x OLEDは、たぶん、秋月で買った
x Groveコネクター、4x4基板も秋月で買った。

目的
OLEDで遊ぶ

結果

![o_coq455.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/572ec2e8-0111-955c-0b3d-969416e8cb27.jpeg)


各自、データシート確認の事


![o_coq456.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/47d7323d-cbce-351b-5ccc-24db2da72991.jpeg)


プログラム


```c++


//ssd1306_46_M6NanoC6_1


//ヘッダーファイル
#include <Arduino.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>


//定義
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
#define OLED_RESET     -1 // Reset pin # (or -1 if sharing Arduino reset pin)
#define SCREEN_ADDRESS 0x3C ///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);


//初期化
void setup() {

  // I2Cアドレスは使用するディスプレイに合わせて変更する
  display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS);

}//setup


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

  // 画面表示をクリア
  display.clearDisplay();

  // テキストサイズを設定
  display.setTextSize(3);
  // テキスト色を設定
  display.setTextColor(WHITE);
  // テキストの開始位置を設定
  display.setCursor(0, 10);

  //46を設定
  int tempval = 46;

  // 1行目に46を表示
  display.println(tempval);

  // 描画バッファの内容を画面に表示
  display.display();

  delay(1000); //1秒待つ

}//loop



```
dlib face recognitionをOpenVINOで使う

これは技術的な内容を含まない、単なる「できた！」という報告記事です。

顔認識(Face Recognition)で有名なdlibのモデルをPythonのface＿recognitionのライブラリで使うとき、GPU(CUDA)を使わないとめちゃくちゃ遅かった。
そして、dlibのインストール自体も、CUDAを使うためにも、ユーザーがCmakeを用意してコンパイルしないと使えなかった。
そこで、誰もが簡単に使えて、かつ今後出てくるAIPCのNPUで高速化しないかと思ってOpenVINO形式にしたら、NPUを使わなくてもめちゃくちゃ早くなった。

dlibのモデルはCC0 1.0 Universalというライセンスで、自由に配布可能だったので、このモデルを配布している。
よかったら試してみてください。

https://github.com/mtsnrtkhr/taguchi_face_recognition_resnet_v1_openvino_fp16_optimized
【Rails】Support for calling #default_scope without a block is removed.

## はじめに
Railsのアップデート中にdefault_scopeを使用している箇所でエラーが出たので、その対応をまとめます。

## 問題
コード
```ruby
default_scope order("created_at DESC")
```

エラー文
```ruby
Support for calling #default_scope without a block is removed. For example instead of `default_scope where(color: 'red')`, please use `default_scope { where(color: 'red') }`. (Alternatively you can just redefine self.default_scope.)
```

## 解決方法
以下のように修正します。
```ruby
default_scope { order("created_at DESC") }
```

## 参考
https://stackoverflow.com/questions/38558560/trying-to-set-up-default-scope-but-getting-support-for-calling-default-scope-w
SwapAnything.io: 新しいAIツールで簡単に顔を交換！近日中に服や髪型の交換機能も登場予定

こんにちは、皆さん！
私たちは、AI技術を使って簡単にさまざまな画像編集を行えるオンラインツール「SwapAnything.io」をリリースしました。

SwapAnything.io とは？
[SwapAnything.io](https://swapanything.io/) は、誰でも簡単に写真や動画で顔を交換できるウェブツールです。写真をアップロードするだけで、ワンクリックでリアルな顔交換を実現できます。従来の画像編集ソフトでは難しい編集作業を、シンプルで直感的な操作で行えるのが特徴です。

今後の展開：服や髪型の交換も可能に！
さらに、SwapAnything.io では、顔だけでなく 服や髪型の交換 も可能になる新機能を開発中です。


皆さんのフィードバックをお待ちしています！
現在、SwapAnything.io はベータ版としてリリースされています。ぜひ、皆さんにツールをお試しいただき、使用感や改善点などのフィードバックをお寄せいただけると幸いです。皆さんのご意見は、今後の機能開発に大いに役立ちます！

[SwapAnything.io](https://swapanything.io/) の特徴
簡単操作：アップロードするだけで顔の交換が可能
高速処理：AIが瞬時にリアルな結果を生成
今後の機能拡張：服や髪型の交換ができる新機能が追加予定
SwapAnything.io についてもっと知りたい方や、ツールを試したい方は、こちらのリンクからぜひご利用ください。

皆さんからのフィードバックをお待ちしております！
Salesforce認定Platformデベロッパー試験レポート

この投稿は先日「Salesforce認定Platformデベロッパー試験」
に合格しましたので、そのレポートになります。

【目次】
１．受験することになった経緯
２．主な勉強方法（使用した教材）
３．試験結果・感想
４．まとめ

１．受験するまでの経緯
　3月にSalesforce認定Platformアプリケーションビルダー試験に合格したので、
　さらなるステップアップの為に受験。
　↓Salesforce認定Platformアプリケーションビルダー試験を受験した経緯はこちら 
　https://qiita.com/iwamatch/items/21ef25d0d6a3c596701d

２．主な勉強方法（使用した教材）
①Trailhead(trailmix)
　まずは認定Platformアプリケーションビルダーと同様にTrailheadを実施。
　以下のTrailmixを100%になるまで実施しました。
　実施方法も認定Platformアプリケーションビルダーの時と同様ですが、
　Apexコードを実際に書かないと前に進めないような場合もあり、そこそこ時間がかかりました。
　どうしてもクリアできない場合は、回答を解説してくれているページがあるので、
　参考にして理解するようにしました。
　但し、そもそも認定アドミニストレーターと認定Platformアプリケーションビルダーの
　Trailmixを100%実施すると、全体の50%程度は完了しているので、
　一から実施するよりは時間はかかっていないです。

https://trailhead.salesforce.com/ja/users/welcome4/trailmixes/salesforce-platform-dev-1

（trailhead回答解説）
https://savepo.com/summary_trailheads_answer

②Web問題集
　以下に挙げた問題集をこの順番で3回繰り返して解きました。
　間違えた問題に関する事項は上記trailheadの文章や公式ヘルプを検索して、
　理解するようにしました。

A.TysonBlog（217問）
　認定Platformアプリケーションビルダーの時もお世話になったサイト。
　やはり、こちらが最も丁寧、かつ、正確に思えたので、
　ここに載っている解説をまず完璧に理解することを心掛けた。
https://tysonblog-whitelabel.com/category/salesforce/salesforce-developper1   

B.JPN試験（110問）
　こちらも認定Platformアプリケーションビルダーの時もお世話になったサイト。
　今回は2024/4/18バージョンを実施しました。
　Aとの重複もそれなりにありますが、今回も類似の問題が試験にも
　かなり出ていたと思うので、実施して正解でした。
https://www.jpnshiken.com/shiken/Salesforce.PDI-JPN.v2024-04-18.q110.html

C.ヨリユログ（70問）
　比較的記事が新しかったので、一通り実施。
　A.Bだけでも合格点には届くかもしれません。　
https://yoriyulog.com/category/certification-exam/


３．試験結果・感想
　試験は105分で60問を解きますが、60分程度で完了しました。
　結果は「合格」で、以下表の通り、正答率は83%程度と思われます。
　68%で合格ですので、余裕を持って合格できて良かったです。
　（単元ごとの問題数と結果得点は公表されないため、
　　結果は計算により求めた想定値となります）
|単元|配点(%)|問題数(想定)|得点数(想定)
|---|--:|--:|--:
|デベロッパーの基本|23|14|11
|プロセスの自動化とロジック|30|18|15
|ユーザインターフェース|25|15|12
|テスト、デバッグ、リリース|22|13|12
|(合計)|100|60|50

４．まとめ
　認定Platformアプリケーションビルダーに続き合格できて、ホッとしています。
　実際の問題では知識を問うというよりは、各想定される場面において、
　何を使えば実現できるかや、どういうコードを書くのが望ましいかという
　ベストプラクティスを求める問題になっていると感じました。
　特に配点の28%を占める自動化については、フローやプロセスビルダー、
　ワークフロールールの違いをしっかり押さえないと合格は難しいと思います。
　2024年11月からはSalesforceを利用した開発がいよいよ始まってくるので、
　生かしていきたいと思います。
　もし時間が取れれば上位資格にも挑戦したいと思います。

以上
[Joke] どんな言語でもヒンズー語に翻訳するプログラム 'hindi.py'

どんな言語でもヒンズー語に翻訳するプログラムです。
`chmod +x hindi.py`として、実行権を付けて動かしてください。
ジョークの解説は野暮ですが、実行させて文字列を入力すると、でたらめなヒンディー語を出力します。
ボキャブラリが小さいと思ったら、変数hindiesに適当なヒンディー語を足してください。

```hindi.py
#!/usr/bin/python

import random
hindies=["マハー","スジャー","マハ","ムスタ","シシュ","ババン","アアジ",
         "マウサム","ハイ","ナマステ","ヤア","パハレ","セ","ヘー","サカ",
         "デネ","ヴァアラ" ]

def main():
    while True:
        line=input(":: ").replace('\n','')
        if line=='':
            return
        if line=="quit":
            return
        s=len(line)//2
        for i in range(s):
            print(f"{hindies[random.randint(0,len(hindies)-1)]} ",end='')
        print("")

if __name__=='__main__':
    main()
    exit(0)
```
A-Frameでマイクラみたいなの

# A-Frame

A-FrameとはHTMLとJavaScriptを使用して3DとかVRとか作れるやつです

サイトを見るとサンプルが色々あって面白いです

https://aframe.io/

# 試してみると・・・

HTMLタグだけで3Dの図形ができるのでマイクラみたいにしたくなりました

```html
// これだけで3dの箱が設置される！
<a-box position="0 0 0" color="green" />
```

# 作ったサンプル

![m2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/329559/7eb0731c-e11d-4cdf-eadc-3f0ec27a7f47.gif)

WASDでカメラ移動、QEで上昇下降、クリックすると赤いレティクルの位置にブロックを設置します

PC&chromeでしか動作確認してません

URL: https://babu-ch.github.io/aframe-micra/

メインのソース: https://github.com/babu-ch/aframe-micra/blob/main/src/main.ts

結構それっぺぇですよね

地面を緑のブロックで埋めて、クリックするとその面にブロックを生やす実装です

# おわり

さすがにブロック多いと重いです

でもこの実装が60行くらいでできるのでA-Frameすごいですよね :thumbsup: 

github: https://github.com/babu-ch/aframe-micra
なぜサイバー攻撃をするのか

# 目的

1. ハクティビズム
1. 金目当て
1. 戦争によるもの

## 1.ハクティビズム
政治的な意思表示や政治目的の実現のためにハッキングを手段として利用する行為です。例としては以下のような世論操作システムがあります。このようなシステムはどこが予算を出してるのでしょうね。

手法例）
➀世論操作システムから偽のリンクを生成。メールで送るなどして、クリック
➁SNSのアカウントの乗っ取り、複数アカウントを一元的に管理・操作
➂ボットを使ってSNS上で、標的となるアカウントを黙らせたり、自分たちに有利な言説を広めたりする

世論操作システムとは
https://www3.nhk.or.jp/news/html/20240920/k10014585911000.html

## 2.金目当て
ランサムウェアのようにデータを元に身代金を要求したり、盗んだデータを売買します。過去２重脅迫だったものが、2024年現在、以下のような４重脅迫が当たり前のようです。
支払うともっと要求されるものです。絶対に支払ってはいけません。

手法例）
➀攻撃者がデータを暗号化して脅迫
➁データを盗んで公表すると脅迫
➂DDoS攻撃を仕掛けて脅迫
➃盗んだデータの所有者に連絡して、被害組織に身代金を支払うよう説得しろと要求する

多重脅迫が当たり前に
https://www3.nhk.or.jp/news/special/sci_cul/2022/09/special/2022-09-cyber/

## 3.戦争によるもの
戦争を起因に活動するハッカー集団がいます。過去「e-Gov」も一時アクセス困難となってます。

手法例）
➀敵対的と判断
➁ウェブサイトやサーバーなどに大量のデータを送りつけ、機能停止に追い込む「DDos攻撃」を行う

「キルネット」とは何者か？
https://www3.nhk.or.jp/news/special/sci_cul/2022/09/special/2022-09-cyber/

## 4.最後に
2022年末、政府は「国家安全保障戦略」という文書を決定しました。その中に「能動的サイバー防御」の導入が盛り込まれました。日本がサイバー攻撃を受けた時、これまでは攻撃をブロックするような「防御に専念」していましたが、攻撃側のサーバーやコンピューターを停止させるといった「攻撃」を防御のために行うというものです。

今までのセキュリティ対策から攻めた方針のようにも思いますが、どうなるのでしょうね。

サイバー安全保障を確保するための能動的サイバー防御等に係る態勢の整備の推進に関する法律案
https://www.shugiin.go.jp/internet/itdb_gian.nsf/html/gian/honbun/houan/g21306007.htm

サイバー安全保障分野での対応能⼒の向上に向けた有識者会議
https://www.cas.go.jp/jp/seisaku/cyber_anzen_hosyo/giron_seiri/giron_seiri_gaiyou.pdf
EFcoreのマイグレーションでテーブルの存在確認をする_C#

すでに作成して使用しているアプリに、後からEntityFramework_coreを使うように置き換えようとしています。
データモデルを作り、マイグレーションしてみますが、すでにテーブルが存在するとCreateTableでエラーになります。
その時に、テーブルの存在確認をする方法についてです。

# 前提として
コードファーストでマイグレーションしようとしているのに、テーブルの存在確認をして対応する。ということをすると問題の起きる懸念があります。
Issuesにいくつかありました。
https://github.com/dotnet/efcore/issues/13703
https://github.com/dotnet/efcore/issues/32071

## テーブルの存在確認をしない方法
`migrationBuilder.CreateTable`の処理を以下に変えて対応するという方法もあるようです。
https://sqlite.org/lang_altertable.html#otheralter
1. 新しいテーブルを作成する
1. データのコピー
1. 古いテーブルの削除
1. 新しい名前を古い名前に変更

# テーブルの存在確認をしてから`migrationBuilder.CreateTable`する
## 使用環境
- windows10
- .net net8.0-windows
- winフォーム
- SQLite
- 使用するPCのローカルにSQLiteファイルを作成
- すでにアプリは使用されている
- EFcoreに置き換えて以降はこれでデータベースSQLiteの変更を管理したい
- 問題として
  - すでにアプリを使用していてSQLiteファイルがある場合は、変更のみを適用したい
  - 初めて使用する場合は、すべてのマイグレーションファイルを適用させたい

## マイグレーションファイルの変更
生成されたマイグレーションファイルの内容を変更していきます。

```20240802010101_InitialCreate.cs
public partial class InitialCreate : Migration
{
    /// <inheritdoc />
    protected override void Up(MigrationBuilder migrationBuilder)
    {
        if (ContextExtensions.TableExistsCount("myTable") == 0)
        {
            migrationBuilder.CreateTable(
               name: "myTable",
               columns: table => new
               {
                   myCol = table.Column<string>(type: "TEXT", nullable: false)
               },
               constraints: table =>
               {
                   table.PrimaryKey("PK_t_Files", x => x.myCol);
               });
        }
    }
}
public static class ContextExtensions
{
    public static int TableExistsCount(string tableName)
    {
        using MyContext context = new();
        var sSQL = $@"SELECT COUNT(*) as 'Value' FROM sqlite_master WHERE TYPE = 'table' AND name = '{tableName}'";
        var sSQLFactory = FormattableStringFactory.Create(sSQL);
        var tableCount = context.Database.SqlQuery<int>(sSQLFactory).FirstOrDefault();
        return tableCount;
    }
}
```

## 変更した内容
- `TableExistsCount`という関数を追加
- `if (ContextExtensions.TableExistsCount("myTable") == 0)`の所で呼び出す
- テーブルが存在しない場合に`migrationBuilder.CreateTable`の処理をする
- `migrationBuilder.CreateTable`の部分はマイグレーションでつくられたファイルのまま

## つまった所
- `SQLite Error 1: 'no such column: t.Value'.`というエラー
  - カウント集計名称を`'Value'`としないといけないようです
  - https://github.com/npgsql/efcore.pg/issues/2739
  - https://learn.microsoft.com/en-us/ef/core/querying/sql-queries#querying-scalar-non-entity-types

## EFcoreへの移行ができた
これを使うことで、すでに使用しているアプリの状態から、EFcoreへの管理に移行できました。
これで今後データベースへの変更がある時はマイグレーションファイルを作ってそれぞれの実行環境から更新するだけになりました！
ただ前提の部分のとおり、この方法は推奨される方法ではないと思われます。

# その他参考
- https://qiita.com/Poly-P/items/a56e3e4721618cdd50d8
- https://stackoverflow.com/questions/46531671/how-to-check-if-table-exists-in-a-migration
- https://qiita.com/jun1s/items/3e2b3702a965bb5e2705
- https://learn.microsoft.com/ja-jp/ef/core/managing-schemas/migrations/?tabs=dotnet-core-cli
コードで学ぶAWS入門　15.6. Docker のインストール

# 詰まったところ
コードで学ぶAWS入門https://tomomano.github.io/learn-aws-by-coding/#sec:install_docker
で**15.6. Docker の　インストール**の最後に、設定が正しいか確認するため下記のコマンドをうつ。

`$ docker run hello-world`
```
The command 'docker' could not be found in this WSL 2 distro.
We recommend to activate the WSL integration in Docker Desktop settings.

For details about using Docker Desktop with WSL 2, visit:
https://docs.docker.com/go/wsl2/
```

このWSL 2ディストロでは、'docker'コマンドが見つかりません。
Docker Desktopの設定でWSL統合を有効にすることをお勧めします。

Docker DesktopとWSL 2の使い方の詳細については、こちらをご覧ください：
https://docs.docker.com/go/wsl2/

このように、ダウンロードしたはずのDockerが動かない。

# Dockerが動かなかった原因説明
1.Dockerをインストールしたのは、`Ubuntu-24.04`であり、`Ubuntu`ではない。

2.WSLの起動時のデフォルトのディストリビューションが`Ubuntu`になっていた。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3889006/9c03cd1e-8bdf-08a1-f61c-c22fa3addbde.png)

3.```wsl --setdefault Ubuntu-24.04```
は、`Ubuntu-24.04`をデフォルトのディストリビューションにセットしてくれる。

4.Dockerをインストールしていた`Ubuntu-24.04`がデフォルトになった
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3889006/835a6475-1e55-8bf3-383c-5456edb90c85.png)

※**アスタリスク（*）**:現在のデフォルトディストリビューションを示すマークです。


# もう一度実行
`$ docker run hello-world`

```
Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (amd64)
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 https://hub.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/get-started/
 ```
 Dockerが正常に動いたことが確認できました。
sedコマンドでファイルの特定の行だけ削除する

# 結論
* `sed -n {row}p {file_name}`
    * 削除前に行(row)を指定して確認する場合
* `sed -i '{row}d' {file_name}`
    * `'{row}d'`で行を指定して削除し、`-i`でその結果をファイルに反映させる


sedコマンドのオプションについて：https://atmarkit.itmedia.co.jp/ait/articles/1610/17/news015.html

# 背景
リモートサーバーへのSSH時に、以下のようなメッセージが出て失敗。
原因として対象サーバーのSSHホスト鍵が変更された場合に、接続元の`known_hosts`に記録されているホスト鍵と一致しなくなることによるもので、新しいSSHホスト鍵に更新することで接続が成功します。
今回は上記のsedコマンドで解消できたのでメモ。
```
# ssh root@hoge01
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@    WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!     @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
Someone could be eavesdropping on you right now (man-in-the-middle attack)!
It is also possible that a host key has just been changed.
The fingerprint for the ECDSA key sent by the remote host is
**:**:**:**:**:**:**:**:**:**:**:**:**:**:**:**.
Please contact your system administrator.
Add correct host key in /root/.ssh/known_hosts to get rid of this message.
Offending ECDSA key in /root/.ssh/known_hosts:11
ECDSA host key for hoge01 has changed and you have requested strict checking.
Host key verification failed.
```

# 対応
`Offending ECDSA key in /root/.ssh/known_hosts:11`にあるように`knwon_hosts`の11行めに問題があるので、そこを確認し削除する
(削除前に`known_hosts.old`としてバックアップを残しています)
```
$ pwd
/root/.ssh
$ ls
id_rsa      id_rsa.pub     known_hosts
$ cp known_hosts known_hosts.old
$ sed -n 11p known_hosts
hoge01,192.168.0.0 ssh-rsa **:**:**:**:**:**:**:**:**:**:**:**:**:**:**:**.
$ sed -i '11d' known_hosts
$ ssh hoge01
The authenticity of host 'hoge04 (192.168.0.0)' can't be established.
RSA key fingerprint is **:**:**:**:**:**:**:**:**:**:**:**:**:**:**:**.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'hoge01,192.168.0.0' (RSA) to the list of known hosts.
root@hoge01's password:
```

# 補足
今回のようなホスト鍵更新の際は`sed`でやらなくても以下のように`ssh-keygen`で一発でできるらしい
バックアップ自動でやってくれるのもありがたい
```
$ ssh-keygen -R hoge01
# Host hoge01 found: line 11 type RSA
/root/.ssh/known_hosts updated.
Original contents retained as /root/.ssh/known_hosts.old
```
Uncaught TypeError: fetch failedというエラーの対処

# はじめに
最近Next.jsの学習し始めてなぜかjson-serverからのデータ取得ができなかったので載せます。

# 問題
以前まで正常にデータ取得できていたのに、別日にサーバを立ち上げると以下のエラーが出る。
```
Uncaught TypeError: fetch failed
```

# 原因
json-serverも立ち上げる必要がありました。検索するとサーバがちゃんと立ち上がってるかなどガッツリ出てきますがnpm run devしているからてっきり大丈夫だと思いjson-serverの存在を忘れていました(apiのコードと睨めっこしていた...)。
```
json-server --watch パス名 --port ポート番号
```

# おわりに
初心者丸出しのエラーでした。
Witmotion IMUの動作方法（ROS2）

## **はじめに**
**動作環境**
Ubuntu 22.04
ROS2 humble

**Witmotion IMU**
<img width="150" alt="Lidar.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3817260/59d2b561-33e7-8262-d807-c5d5f9230022.png">

↓ 説明書

https://m.media-amazon.com/images/I/B1C1af4xBpS.pdf

## **手順**
### **1.　パッケージをクローン・ビルド**
Rvizで表示させるために元のパッケージを一部改変しました
```shell
mkdir -p ~/ros2_ws/src

cd ~/ros2_ws/src
git clone https://github.com/Arcanain/bwt901cl_pkg.git

cd ~/ros2_ws/
source /opt/ros/humble/setup.bash
colcon build --packages-select bwt901cl_pkg
```
元のパッケージ

https://github.com/Dorebom/bwt901cl_pkg.git

### **2.　権限を付与**
IMUをPCに接続し権限を付与します
```shell
lsusb
dmesg | grep tty
sudo chmod 666 /dev/ttyUSB0
```
dmesg | grep tty で上手くいかない場合は2-1, 2-2を参照してください

**2-1.　アクセス制限を解除<sup>[1]</sup>**
<img width="600" alt="Lidar.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3817260/b9ae0667-cac0-87e2-660a-93c0918bc4c2.png">

このような表示が出た場合は以下のコマンドを実行してください
```shell
sudo touch /etc/sysctl.d/dmesg.conf
sudo nano /etc/sysctl.d/dmesg.conf
kernel.dmesg_restrict=0 ※ファイルに書き込む
sudo /sbin/sysctl --system
```

**2-2.　妨害パッケージを削除<sup>[2]</sup>**
<img width="600" alt="Lidar.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3817260/b67e0838-c1d2-511b-bafb-7aa2f9c3fc77.png">

このような表示が出た場合は以下のコマンドを実行してください
```shell
sudo apt remove brltty
sudo udevadm control --reload
```
一番下に新たな行が追加されればOKです
<img width="600" alt="Lidar.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3817260/1d482c94-39f5-4bfa-aa53-0c5ffa2415d2.png">

### **3.　Rvizで確認**
権限を付与したら起動させます
```shell
source ~/ros2_ws/install/setup.bash
ros2 run bwt901cl_pkg imu_bwt901cl
```
success! がでればOKです
<img width="150" alt="Lidar.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3817260/dd9574ff-95c9-7119-c004-eafe1ed77234.png">

次にRvizで可視化してみます
別ウィンドウでRvizを立ち上げ、以下の通りにRvizの設定を変更してください
```shell
rviz2
```
・ [Fixed Frame] を [base_link] に設定する
・ [Add] から [TF] を追加し、[Frames] 内の [imu_link] にチェックをいれる
</pr>
以下のような画面が表示されればOKです
3軸がIMUの動きと連動します
<img width="500" alt="Lidar.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3817260/12caf6b5-3cbd-fef2-8bad-cf28fd7fdcbf.jpeg">

## **キャリブレーションについて**
準備中

## **参考文献**
[1] https://pyopyopyo.hatenablog.com/entry/2019/02/15/023159
[2] https://qiita.com/74th/items/f46bccd67b2ed6fc867f

## **謝辞**
この取り組みは株式会社GxP(グロースエクスパートナーズ)様のサポートを受けて実施しています。貴重なアドバイスやロボットに必要な機材の支援をいただきました。心より感謝申し上げます。

https://www.gxp.co.jp/

https://qiita.com/organizations/gxp
C_TS422_2021 SAP Certified Application Associate SAP S/4HANA Production Planning and Manufacturing対策（91/100）

【91日目】
トピック 9：SAPS/4HANAでの簡易製造（8/9）

≪問題91≫
繰返生産の生産ラインを表す作業区はどこで更新しますか。
（２つ選択）
□製造原価コレクタ
□製造バージョン
□繰返生産プロファイル
□作業手順

≪解答≫
□製造原価コレクタ
■製造バージョン
□繰返生産プロファイル
■作業手順

≪解説≫  
◆製品に対して繰返生産を利用できるようにするためには、品目マスタと製造バージョンで特定の設定を行う必要があります。  
◆生産ラインは簡易作業区として登録され、作業区では生産ラインの利用可能在庫が定義されます。  
◆登録された作業区は、対応する製造バージョンや作業手順の単一作業に割り当てられます。
Javascriptの基本

JavaScriptの基本を押さえよう

## HTMLへの埋め込み
JavaScriptをHTMLファイルに埋め込む際には、&lt;script&gt;タグを使用します。ただし、このタグをHTMLファイルの上部に記述すると、他のまだ読み込まれていないHTML要素に影響を与え、思わぬ不具合が発生することがあります。そのため、通常は&lt;script&gt;タグをファイルの末尾に配置するのがベストです。

以下はその例です。
```html
<!doctype html>
<html lang="ja">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width" />
    <title>テストページ</title>
  </head>
  <body>
    <img src="images/sample.png" alt="テスト画像" />
  </body>
  <script src="scripts/main.js"></script>
</html>
```

このように記述することで、外部のJavaScriptファイル（ここでは main.js）がHTMLに読み込まれる仕組みになっています。

## イベント処理
JavaScriptでは「イベント」を検知して、それに応じたアクションを実行することが可能です。イベントとは、例えばクリックやスクロール、キーボード操作など、ブラウザで発生する動作のことを指します。

次のコードは、HTML全体をクリックしたときに「Hello World」というアラートを表示する簡単な例です。
```javascript:main.js
document.querySelector("html").addEventListener("click", function ()
{
 alert("Hello World")
});
```

ここでは、querySelector()メソッドを使用してHTMLの<html>要素を選択し、addEventListener()で「クリック」イベントに反応する処理を追加しています。イベントが発生すると、指定された関数が実行され、アラートが表示される仕組みです。

このようにして、JavaScriptを活用すれば、ページのインタラクティブな動きを簡単に実装することができます。
Dark Web Intelligence初歩の初歩

Dark Web Intelligence(Darknet Intelligence)をするには、ダークウェブを探索する知識がある程度必要になるため、その取っ掛かりになるものをメモ程度にまとめてみた。

# Dark Web Intelligence(Darknet Intelligence)とは
略してDARKINT。
ダークウェブ上の脅威情報を収集・分析・加工したもの、もしくは、それらを行うための活動。
脅威インテリジェンスと似ているが、DARKINTはダークウェブ上の脅威情報にフォーカスしている。

# Dark Web Intelligenceの目的
・ダークウェブ上の犯罪者の活動を観察する
・脆弱性やマルウェアなどの情報を収集する
・自社に関するデータが漏洩してないか監視&検知する
・etc.

# ダークウェブを探索する準備
この記事では、Torネットワークの探索を例に紹介する。

## Torネットワーク上のサイトへのアクセス手段
一番楽で誰でも知っていそうなのは、Tor Browserからアクセスする方法だろう。
TraceLabs OSINT VMみたいに、最初からTor Browserが入っているVMを使えば簡単に環境が構築できる。

https://www.tracelabs.org/initiatives/osint-vm

他には、Torを使ったオンラインサービスを使うという手がある。
4everproxyのTor Web Proxyみたいに、代理でアクセスしてくれるサイトがあるので、こういったものを探してみよう。

https://www.4everproxy.com/tor-proxy

## 既に知られているサイトを探索してみる
手動でダークウェブ上のサイトを見つけてくるのは、かなり大変。
なので、誰かが既に見つけているサイトから情報を収集してくることから始めるという手がある。

下記のGitHubレポジトリは、様々なディープウェブやダークウェブの情報源が書かれているためおすすめ。

https://github.com/fastfire/deepdarkCTI

## Torネットワーク上のサイトを見つけてくる
Torネットワーク上のサイトを検索できるサービスはたくさん存在する。
・ahmia
・tor66
・haystack
・onionland
・etc.

これらのサービスでそれぞれ調べていくのは面倒なので、OnionSearchみたいなツールを使って、まとめて収集する。

https://github.com/megadose/OnionSearch

下の画像は、OnionSearchを使って、あるキーワードで収集した時に出力されたテキストファイルの一部。
![onion.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274361/880aa372-6f9d-cf45-790c-27eeddbce747.png)

## Webサイトのクローリング
ブラウザでアクセスしても問題ないのかわからないときがある。
その時に、クローリングをしてくれるツールがあると便利。

https://github.com/MikeMeliz/TorCrawl.py

# ダークウェブ上の犯罪者コミュニティを見つけるコツ
例えば、他のユーザと対戦したり、キャラやアイテムを集めて交換できるオンラインゲームがあるとする。
そのオンラインゲームのコミュニティでは、対戦したり、キャラやアイテムを交換したりする人を集めるために、特定のキーワードが飛び交っている。
なので、そのキーワードで検索すると、たくさんのコミュニティを見つけることができる。

犯罪者コミュニティも同様で、犯罪者同士が交流したり、取引したりする時によく使われているキーワードというものがある。
そういったキーワードを元に探索することで、犯罪者コミュニティを見つけることが可能になる。

# ダークウェブの探索で気をつけること
・信頼できない情報も飛び交っているので、鵜呑みにし過ぎない
・(これに限った話ではないが)セキュリティ対策を怠らない
・フォーラムとかでは、会員登録したり登録料を支払ったりしないと詳細がわからないことがあるため、すべてを把握できるわけではない
・犯罪者の利益にならないようにする
Go言語のSNMPパッケージgosnmpでTRAPを送信する方法

# はじめに

Go言語のSNMPパッケージgosnmpを紹介するシリーズの5回目です。
前回は

https://qiita.com/twsnmp/items/76d7cb98e55d2e1333db

の記事でTRAPを受信する方法について説明しました。

今回は、TRAPを送信する方法について説明します。


# TRAPを送信するプログラム

gosnmpパッケージでSNMPv2cのTRAPを送信するプログラムは

```go

package main

import (
	"log"

	g "github.com/gosnmp/gosnmp"
)

func main() {
	g.Default.Target = "192.168.1.250"
	g.Default.Port = 162
	g.Default.Community = "trap"
	err := g.Default.Connect()
	if err != nil {
		log.Fatalf("Connect() err: %v", err)
	}
	defer g.Default.Conn.Close()
	vbs := []g.SnmpPDU{
		g.SnmpPDU{
			Name:  ".1.3.6.1.6.3.1.1.4.1.0",
			Type:  g.ObjectIdentifier,
			Value: "1.3.6.1.6.3.1.1.5.1", // cloldStart
		},
	}
	trap := g.SnmpTrap{
		Variables: vbs,
	}
	_, err = g.Default.SendTrap(trap)
	if err != nil {
		log.Fatalf("SendTrap() err: %v", err)
	}
}
```

です。

このプログラムのポイントについて説明します。

### 宛先を指定

```go
	g.Default.Target = "192.168.1.250"
	g.Default.Port = 162
```

宛先のIPアドレスとポートを指定します。

### TRAPの種類を指定

```go
	vbs := []g.SnmpPDU{
		g.SnmpPDU{
			Name:  ".1.3.6.1.6.3.1.1.4.1.0",
			Type:  g.ObjectIdentifier,
			Value: "1.3.6.1.6.3.1.1.5.1", // cloldStart
		},
	}
```

の部分でTRAPの種類を表すsnmpTrapOID.0にcoldStartを設定しています。
数値のOIDで指定していますが

https://qiita.com/twsnmp/items/2986b696cced09820291

の記事で紹介したパッケージを使えば名前で指定できます。


# SNMPv3対応にする

先ほどのプログラムをSNMPv3対応したプログラムが

```diff_go
package main

import (
	"fmt"
	"log"
	"time"

	g "github.com/gosnmp/gosnmp"
)

func main() {
	g.Default.Target = "192.168.1.250"
	g.Default.Community = "trap"
	g.Default.Port = 162
+	g.Default.Version = g.Version3
+	g.Default.SecurityModel = g.UserSecurityModel
+	g.Default.MsgFlags = g.AuthPriv
+	engineID := fmt.Sprintf("17861:%d", time.Now().Unix())
+	g.Default.SecurityParameters = &g.UsmSecurityParameters{
+		UserName:                 "test",
+		AuthoritativeEngineID:    engineID,
+		AuthenticationProtocol:   g.SHA,
+		AuthenticationPassphrase: "password",
+		PrivacyProtocol:          g.AES,
+		PrivacyPassphrase:        "password",
+	}
	err := g.Default.Connect()
	if err != nil {
		log.Fatalf("Connect() err: %v", err)
	}
	defer g.Default.Conn.Close()
	vbs := []g.SnmpPDU{
		{
			Name:  ".1.3.6.1.6.3.1.1.4.1.0",
			Type:  g.ObjectIdentifier,
			Value: "1.3.6.1.6.3.1.1.5.1", // cloldStart
		},
	}
	trap := g.SnmpTrap{
		Variables: vbs,
	}
	_, err = g.Default.SendTrap(trap)
	if err != nil {
		log.Fatalf("SendTrap() err: %v", err)
	}
}
```

です。

# 送信結果

SNMPv2cとSNMPv3のどちらも同じ結果になります。
TWSNMP FCで受信した場合です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3874862/9efcbf62-259c-4962-1c95-e1851980a5df.png)



# 余談

この方法を使ってPCのCPUやメモリーの使用率が一定以上になった時、SNMPのTRAPを送信するプログラムを開発しました。

https://github.com/twsnmp/twhr2trap
レスポンシブデザイン

## デバイスのウィンドウ幅に「responsive(よく反応)」して、見やすい表示に自動で切り替える。
**メディアクエリ**

基本文法
```
@media (max-width: 430px) {
    main {
    margin-left
    
    }

}
```


できること：さまざまな（印刷、音声の制御とサイズによって表示を変える）
```
@media (条件) {
  /* 条件に合致した場合に適用されるスタイル */
}
```
条件の部分には、以下のものが指定できます。
画面サイズ: width, height
デバイス: screen, print
向き: orientation (landscape, portrait)
解像度: resolution
その他: min-width, max-width, min-height, max-heightなど

より詳しい情報を得るために

MDN Web Docs: https://developer.mozilla.org/ja/docs/Web/CSS/Media_Queries
W3Schools: https://www.w3schools.com/cssref/css3_pr_mediaquery.asp
【DAY15】Tailwind CSSのクラスの並び替え（Laravel）

## はじめに
Tailwind CSSを使用して装飾をしていたのですが、クラスの順番がぐちゃぐちゃになってしまい、可読性が低くなっているよう感じました。そのため、クラス名の順番を整理したいと思い調べたところ、自動でクラスを並び替えてくれるパッケージを見つけました。しかし、パッケージのインストールから使用まで色々と詰まって時間がかかったため、その過程をここに残しておきます。

## 開発環境
まず、私の開発環境について軽くまとめておきます。
* IDEとしてAWS Cloud9を使用
* phpフレームワークのLaravelを使用
* Laravel Breezeを使用
* npm環境が構築され、Tailwind CSSはインストール済み

## prettier-plugin-tailwind
私が使用したパッケージは、「prettier-plugin-tailwind」です。これを使用すると、クラスをいい感じに並べ替えてくれます。ざっくり説明すると、
1. レイアウトに影響を与えるクラス（display,margin,heightなど）
1. 装飾するクラス（color,box-shadowなど）
1. 修飾子付きクラス（hover:,focus:など）
1. レスポンシブ修飾子付きクラス（md:,lgなど）

といった順番です。

まず、インストールをします。
```terminal
npm install -D prettier prettier-plugin-tailwindcss
```
prettier-plugin-tailwindcssはPrettierの拡張機能なので、Prettierが必要です。私はPrettierも使っていなかったので、上記のコードでPrettierのインストールも同時に行いました。
Prettierとは、Node.js上で動作するコードフォーマッターです。

次に、設定ファイルである.prettierrc.jsonを作って、以下のコードを記述しました。
```.prettierrc.json
{
    "plugins": ["prettier-plugin-tailwindcss"],
    "tailwindConfig": "./tailwind.config.js",
    "overrides": [
        {
            "options": {
                "trailingComma": "none",
                "tabWidth": 4,
                "semi": false,
                "singleQuote": false
            }
        }
    ]
}
```

Prettierでは、以下のようなデフォルトの設定があるようです。
* "trailingComma": "es5"（末尾カンマの指定）
* "tabWidth": 2（タブ幅はスペース2つ）
* "semi": true（文の終わりにセミコロンを追加）
* singleQuote: false（文字列にシングルクォートではなくダブルクォートを使用）

私はクラス名の順番を整えたかっただけなので、末尾カンマ、セミコロンの設定はなしにして、タブ幅は自身のコードに合わせました。

これで設定もできたので、一旦一つのファイルを指定して以下のコードで実行しました。
```terminal
npx prettier --write resources/views/questions/index.blade.php
```
するとエラーが発生。どうやらlaravelの.blade.phpというカスタムファイル拡張子は対応していないようです。
blade.phpにも対応するよう、新たなプラグインをインストール&設定ファイルに追記。
```terminal
npm install -D prettier-plugin-blade
```
```.prettierrc.json
"plugins": ["prettier-plugin-tailwindcss", "prettier-plugin-blade"],

```
これで実行したところ、クラス名のソートは行われましたが、タグ内の属性が多く行の文字数が長いところは改行されました。個人的に改行は要らなかったので行の文字数の指定を設定ファイルに追記。
```.prettierrc.json
"printWidth": 500,
```
これで実行すると、思い通りにクラス名がソートされました。
シングルクオーテーションとダブルクオーテーションもぐちゃぐちゃだったのでそれもフォーマットされてお得。
挙動が確認できたので、設定ファイルで.blade.phpファイルに対して実行するよう指定して実行。
```.prettierrc.json
"overrides": [
    {
        "files": "*.blade.php",
        "options": {
            "trailingComma": "none",
            "tabWidth": 4,
            "semi": false,
            "singleQuote": false
        }
    }
]
```
```
npx prettier --write .
```
これで全ての.blade.phpファイルのクラス名がソートされました。
Traceback (most recent call last):   File "/usr/local/lib/python3.10/dist-packages/lightning/fabric/utilities/data.py", line 487, in __getattr__     return self[key] KeyError: 'num_classes'

# 事前訓練モデルデータを読み込むとエラーがでる
モデルを読み込むとKeyErrorが発生するということが起きたが、このモデルを用いて過去に実験を回していたので、エラーがでるはずがない。
そこで、原因を探ると、仮想環境上のlightningのバージョンがあがってしまったのが原因ではないかと推測したので、それについてまとめる。

# 解決策
現在のエラーが発生しているバージョンが2.4.0だった。そこで、前バージョンの2.3.3に下げてみたが、同じようなエラーが発生した（微妙に無いといわれるKeyが変わった気がしたが...)。次に2.2.5に下げたところ、正常に動作することを確認した。

# まとめ
学習済みのモデルを読み込んだときにKeyErrorが発生する場合は、lightningのバージョンを下げてみると解決できるかも？
【フリーランスエンジニアになるには？】エンジニアが独立するメリットについて

「記事についてコメント」の機能の利用では質問内容が公開されてしまうため、もっと気軽に質問に対応できるように

[「LINE公式アカウント」](https://lin.ee/aXrB5xv)

を作りました。
もちろん、この投稿に関連した内容ではなくとも質問できます。

オフ会や勉強会の案内もお送りしていますので、気になる方は友だちになっておいてください。

## エンジニアが独立するメリット
　エンジニアとして働いている方の中には、独立してフリーランスエンジニアとしてのキャリアを築くことに興味を持つ方も多いでしょう。フリーランスになることには、さまざまなメリットがあります。ここでは、その主なメリットについて具体的に解説します。
## 働き方の自由度が高まる
　フリーランスエンジニアの最大のメリットは、働き方の自由度が格段に高まることです。案件の選択など、すべて自分の裁量で決めることができます。
## 収入アップのチャンスがある
　正社員の場合、年収は固定給や昇給ペースに依存しますが、フリーランスエンジニアは、自分のスキルや実績に応じて報酬を自由に設定できます。高単価な案件を受注することで、収入を大幅に増やすことが可能です。さらに、成功すればフリーランスとしての年収が正社員時代よりも大幅に増えるケースもあります。
## スキルアップの機会が広がる
　フリーランスとして働くと、様々なプロジェクトや業界に携わる機会が増えます。これにより、新しい技術やスキルを習得する機会が自然と多くなり、自分の市場価値を高めることができます。また、案件ごとに求められるスキルが異なるため、幅広い知識や技術を習得することで、より多くのクライアントから信頼を得られるようになります。
## 自己成長とやりがいを感じやすい
　フリーランスエンジニアは、自分のビジネスを自ら運営するという側面があります。クライアントから直接フィードバックをもらえる機会が増えるため、自分の仕事の成果が評価される喜びを感じやすく、やりがいを持って働くことができます。
## キャリアの多様化が図れる
　フリーランスになると、自分のキャリアを自由に設計することができます。例えば、特定の分野に特化して専門性を高めることもできますし、様々なプロジェクトに関わって幅広い経験を積むこともできます。また、個人での業務に加えて、将来的にはチームを組んでプロジェクトを受注したり、自分自身のビジネスを立ち上げるといった多様なキャリアの選択肢が広がります。
## まとめ
　エンジニアが独立してフリーランスになることには、働き方の自由度が高まり、収入アップのチャンスが広がるなど、数多くのメリットがあります。自分のスキルや経験を活かしながら、柔軟でやりがいのあるキャリアを築きたいと考えている方にとって、フリーランスエンジニアとしての独立は大きな一歩となるでしょう。
 
*****

「記事についてコメント」の機能の利用では質問内容が公開されてしまうため、もっと気軽に質問に対応できるように

[「LINE公式アカウント」](https://lin.ee/aXrB5xv)

を作りました。
もちろん、この投稿に関連した内容ではなくとも質問できます。

オフ会や勉強会の案内もお送りしていますので、気になる方は友だちになっておいてください。

またこちらの投稿を読み、

・〇〇部分を詳しく説明して欲しい
・主張が矛盾している
・内容が間違っている

等のご意見があれば、著者までメッセージをお願いします。
すべての意見を反映できるわけではありませんが、できる限りの修正・追記をさせてより良いものにしていこうと考えております。

よろしくお願いします！😃
Amazon S3 Express One Zoneのデータアクセス速度を計測してみた

# 1. はじめに

**[Amazon S3 Express One Zone ストレージクラス](https://aws.amazon.com/jp/s3/storage-classes/express-one-zone/)** (以降、S3 Express One Zoneと示します)は、アクセス頻度が高いデータ向けの最速とされるストレージクラスであり、AWS公式ドキュメントによると、S3 Express One Zoneは **[Amazon S3 標準 ストレージクラス](https://aws.amazon.com/jp/s3/storage-classes/)** (以降、S3 標準と示します) と比べてデータアクセス速度が最大10倍速いとされています。
そこで、 **S3 Express One Zone のデータアクセス速度を実際に計測**してみました。比較対象としてS3 標準についてもデータアクセス速度も計測しています。

# 2. 計測方法
S3 Express One ZoneとS3 標準について、同条件でのファイルアップロード (PUT) およびファイルダウンロード (GET) にかかる時間を計測します。計測に用いるツール
と環境、テストシナリオは以下です。

- ツール
  - AWS公式が提供する、Python用のAWSを操作するためのライブラリである [Boto3](https://aws.amazon.com/jp/sdk-for-python/) を使用して、S3にファイルアップロードおよびファイルダウンロードを実行するPyhtonプログラムを作成し利用します。
- 環境
  - 上記 Python プログラムを実行する環境は、[Amazon EC2](https://aws.amazon.com/jp/ec2/) のt3.medium サイズ（2vCPU、4.0GiBメモリ）です。ネットワーク帯域幅は最大5Gbpsです。
  - 上記 Amazon EC2 と同じリージョンかつ同じアベイラビリティーゾーン (以降、AZと示します) のS3 Express One Zoneと、同じリージョンのS3 標準を使用します。
- テストシナリオ
  - 下記3パターンのファイルサイズとファイル数の条件で、ファイルアップロードおよびファイルダウンロードにかかる時間をそれぞれ計測します(計6テストケース)。
  下記3パターンは合計ファイルサイズが同じです。
    - 1GBファイル1個
    - 10MBファイル100個
    - 100KBファイル10,000個
  - テストケースごとに10回計測した値(秒)の平均値を計測値とします。

# 3. 計測結果
性能検証の結果を表1と表2に示します。
ファイルアップロードとファイルダウンロードの両方で、いずれのパターンでもS3 Express One Zoneの方がS3 標準よりも短時間に実行できています。特にファイル数が多い場合に差異が大きく、100KBファイル10,000個のダウンロードでは約9.4倍の差となりました。
AWS公式に言われている、S3 Express One ZoneはS3 標準より最大10倍速いということに、信憑性のある結果となりました。

*表1 アップロード計測結果*
|テストケース|S3 Express One Zone (秒)|S3 標準 (秒)|差異|
|:--|:--|:--|:--|
|1GBファイル1個のアップロード|10.094|28.840|x2.85|
|10MBファイル100個のアップロード|12.821|50.052|x3.90|
|100KBファイル10,000個のアップロード|103.130|603.371|x5.85|


*表2 ダウンロード計測結果*
|テストケース|S3 Express One Zone (秒)|S3 標準 (秒)|差異|
|:--|:--|:--|:--|
|1GBファイル1個のダウンロード|7.082|11.370|x1.60|
|10MBファイル100個のダウンロード|8.025|34.715|x4.32|
|100KBファイル10,000個のダウンロード|111.547|1,047.844|x9.39|

# 4. 考察
上記のように、S3 Express One ZoneはS3 標準よりファイルアップロードおよびファイルダウンロードが高速であることがわかりました。
この理由について考察します。

- S3 Express One Zoneではデータを単一の AZ に保存するため、AZ 内での高速なデータ転送が可能となっています。 
このことが、S3 標準より高速になる一因だと考えられます。
- S3 Express One Zoneは [AWS IAM](https://aws.amazon.com/jp/iam/) 認証の他に、[セッションベースの認証](https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/s3-express-create-session.html) をサポートしています。
セッションベースの認証では、連続してデータアクセスを実施する際に、AWS IAMでの承認を繰り返す必要がないため、特にファイル数が多い場合にS3 標準より高速となった一因だと考えられます。
- ファイル数が多くなるほど、リクエストのオーバーヘッドが大きくなるため、S3 Express One ZoneとS3 標準のリクエスト処理性能の差が顕著になったと考えられます。
- [S3 Express One Zoneではバケットが階層的なディレクトリ構造になっており、S3 標準ではバケットはフラットな構造になっています](https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/directory-buckets-overview.html)。この構造の差により、バケット内のオブジェクトを検索する場合にS3 Express One Zoneの方が高速なようですが、今回の検証ではバケット内のオブジェクト数は極めて少ないため、結果に影響していないと考えられます。

# 5. おわりに
S3 Express One Zoneの明確な長所は性能です。
そのため、ストレージアクセスを高速化したいアプリケーションでは、S3 Express One Zoneが向いています。
例えば、高速なデータアクセスにより全体の処理時間を短縮したいアプリケーションや、静的Webコンテンツや画像、動画などのメディアコンテンツへの高速なアクセスを実現したい場合の利用が考えられます。

一方、本稿では記載していませんが、S3 Express One ZoneはAZ冗長性がない、[ストレージ容量に対する価格がS3 標準より高い](https://aws.amazon.com/jp/s3/pricing/)といった点もあります。

Amazon S3を利用する場合には、要件や制約に応じた適切なストレージクラスを選択する必要があると、今回の計測を通して改めて感じました。
【フリーランスエンジニアになるには？】最短でスキルアップするならフリーランスがおすすめな理由

「記事についてコメント」の機能の利用では質問内容が公開されてしまうため、もっと気軽に質問に対応できるように

[「LINE公式アカウント」](https://lin.ee/aXrB5xv)

を作りました。
もちろん、この投稿に関連した内容ではなくとも質問できます。

オフ会や勉強会の案内もお送りしていますので、気になる方は友だちになっておいてください。

## エンジニアが最短でスキルアップするならフリーランスがおすすめな理由
　エンジニアとしてスキルアップを目指す場合、フリーランスになることは非常に効果的な方法です。フリーランスエンジニアとして働くことで、スキルアップが加速する理由を具体的に解説します。

## 多様なプロジェクトに参加できる
　フリーランスエンジニアとして働く最大の利点は、さまざまなプロジェクトに参加できることです。企業に属していると、同じプロジェクトや技術スタックに長期間従事することが多いですが、フリーランスでは異なるクライアントのプロジェクトに次々と参画することができます。これにより、短期間で多様な技術やツールに触れることができ、スキルの幅が広がります。

※ただし、短期間（1年未満）で離脱しているプロジェクトをスキルシートに記載することは、スキルシートを確認する採用担当者やクライアントに対して悪印象を与える可能性があります。特に、短期間での離脱が繰り返されている場合、プロジェクトに対する責任感や継続力に疑問を持たれ、信頼性が損なわれるリスクがあります。スキルシートは自分の実績や能力をアピールする重要なツールであるため、短期間でのプロジェクト離脱が記載されていると、その内容が逆に足かせとなり、次のキャリアチャンスに影響を与える恐れがあります。

## 自ら学び、適応する力が求められ、身に付く
　フリーランスエンジニアは、新しいプロジェクトごとに異なる要求や技術的な課題に直面します。そのため、常に最新の技術トレンドをキャッチアップし、自分自身で学ぶ姿勢が求められます。この環境は、自然と自己学習の習慣を身につけ、迅速に新しいスキルを習得する力を養うことにつながります。

## 自分のペースで成長を管理できる
　フリーランスとして働くと、自分の成長のペースを自分でコントロールできるようになります。新しい技術を学びたい場合、そのスキルが必要なプロジェクトを選んで挑戦することが可能です。また、時間を作って集中して学習やトレーニングに取り組むこともできます。自分のキャリア目標に合わせて、最も効果的な方法でスキルを伸ばせる点がフリーランスの魅力です。

## 繋がりと新たな機会の創出ができる
　フリーランスとして働くことで、業界内での繋がりの機会が増えます。クライアントや他のフリーランスエンジニアとのつながりを築くことで、新たなプロジェクトや技術トレンドに触れる機会が得られます。こうしたネットワークを通じて得た情報や経験が、スキルアップを加速させる要因となります。

## まとめ
　エンジニアが最短でスキルアップを目指すなら、フリーランスとして働くことが非常に有効です。多様なプロジェクトに参加し、自分のペースで学びながら成長を管理できる環境は、スキルアップを加速させる要因となります。さらに、フリーランスとしての経験は、技術的なスキルだけでなく、自己管理能力や問題解決力も高めることができ、エンジニアとしての総合力を飛躍的に向上させることができます。

*****

「記事についてコメント」の機能の利用では質問内容が公開されてしまうため、もっと気軽に質問に対応できるように

[「LINE公式アカウント」](https://lin.ee/aXrB5xv)

を作りました。
もちろん、この投稿に関連した内容ではなくとも質問できます。

オフ会や勉強会の案内もお送りしていますので、気になる方は友だちになっておいてください。

またこちらの投稿を読み、

・〇〇部分を詳しく説明して欲しい
・主張が矛盾している
・内容が間違っている

等のご意見があれば、著者までメッセージをお願いします。
すべての意見を反映できるわけではありませんが、できる限りの修正・追記をさせてより良いものにしていこうと考えております。

よろしくお願いします！😃
【フリーランスエンジニアになるには？】正社員がイイ！というマインドブロックについて

「記事についてコメント」の機能の利用では質問内容が公開されてしまうため、もっと気軽に質問に対応できるように

[「LINE公式アカウント」](https://lin.ee/aXrB5xv)

を作りました。
もちろん、この投稿に関連した内容ではなくとも質問できます。

オフ会や勉強会の案内もお送りしていますので、気になる方は友だちになっておいてください。

またこちらの投稿を読み、

・〇〇部分を詳しく説明して欲しい
・主張が矛盾している
・内容が間違っている

等のご意見があれば、著者までメッセージをお願いします。
すべての意見を反映できるわけではありませんが、できる限りの修正・追記をさせてより良いものにしていこうと考えております。

よろしくお願いします！😃

## 正社員でいる方が安心？
　「正社員でいるほうが安心だ」という考え方は、多くのエンジニアが抱く共通の思いかもしれません。これを「正社員がイイというマインドブロック」として捉えることができます。

## 正社員として働くことのメリット
　正社員として働くことのメリットは明確です。安定した収入、福利厚生、そして会社からのサポート体制が整っていることで、日々の業務に集中できる環境が提供されます。これらは確かに大きな安心感をもたらす要素です。

## 本当の意味での「安定」とは？
　しかし、少し視点を変えてみると、その「安定」や「安心」が本当に自分にとってベストな選択肢なのかを再考する必要があります。例えば、これまでのキャリアで感じたことがあるかもしれませんが、会社の都合での異動、リストラ、給与の減額など、予期しない変化が訪れることは少なくありません。こうした状況に直面したとき、本当の意味での「安定」とは何かを考えることが求められます。

## フリーランスとしての可能性に目を向ける
　フリーランスエンジニアとしての働き方には、正社員とは異なるチャレンジが待ち受けています。エージェントとともに案件を探し、契約を交わして、納期を守るために自己管理を徹底する必要があります。しかし、その一方で、自分のスキルや経験を最大限に活かし、自由度の高い働き方を実現することができるのもフリーランスの魅力です。あなた自身のスキルや専門知識に自信があるなら、その価値を市場で直接評価してもらうことができるのです。

　また、現代のテクノロジー環境は、フリーランスエンジニアとしての働き方をより手軽にしています。リモートワークの普及、クラウドサービスの活用、そしてオンラインでの案件マッチングサービスの充実など、フリーランスとして活躍するための基盤は整いつつあります。

　正社員としての働き方に対する「安心感」は確かに存在しますが、それが「唯一の選択肢」だと考えることで、かえってあなたの可能性を制限してしまうかもしれません。フリーランスとしての可能性に目を向け、新たなキャリアの選択肢を検討してみる価値は十分にあります。

## 最後に
　最後に、自分自身に問いかけてみてください。「本当に今の働き方が自分にとって最適なのか？」と。フリーランスエンジニアとしての可能性を考えることで、新たなキャリアの選択肢が広がるかもしれません。正社員というマインドブロックを乗り越え、新たな挑戦へと進むことで、自由と成長のチャンスを手に入れましょう。

*****

「記事についてコメント」の機能の利用では質問内容が公開されてしまうため、もっと気軽に質問に対応できるように

[「LINE公式アカウント」](https://lin.ee/aXrB5xv)

を作りました。
もちろん、この投稿に関連した内容ではなくとも質問できます。

オフ会や勉強会の案内もお送りしていますので、気になる方は友だちになっておいてください。
大学サークルのホームページを作ってみた！(その１-概要)

## 作成したホームページ

https://fmmediasaga.chillout.jp

https://github.com/KunitakeHyuga/fmmediasaga

## はじめに
私は大学3年で情報系(ネットワークやソフトウェア開発)を専攻しているのですが，大学の授業でホームページを作成したり，アプリ開発をしたりといったことは今まで1度もやったことがありません．大学でCS専攻になってからの1番のギャップです．
ある程度自分で開発経験を積まないと実務をするまでの技術力に到達できないのではないかと考え始めたので，今回はお試しで大学サークルのホームページを作ってみました．

実際にページ作成→仮想環境→本番環境までの流れを行う中で意外と参考記事を見つけるのが難しかったのでできるだけ詳細に書いてみようと思います．今後ホームページ作成する人などの参考になれば幸いです．

## 使用技術について
使用言語
・HTML
・CSS
・JavaScript

たぶん一番オーソドックスな言語選定だと思います．
ネットでは「プログラミングはHTMLから始めろ」という文言をよく見ますが，大学に入って初めてプログラミングをやった自分はPython→C++→Java→その他(PHP，JS，C#など)といった流れで学習していき，実はHTMLもCSSも触ったことがありません．たぶんどこのCS専攻でも同じ感じみたいですね．

サーバー
・ロリポップ

HTML，CSS，JavaScriptを書いたはいいものの，これどうやってネット上に公開するんだ？ってなりました笑　初めてすぎるが故の落とし穴でした．とりあえず調べてレンタルサーバーを借りることにしました．月100円くらいなら全然アリだったので一旦借りてみることに．昔はHerokuという無料レンタルサーバがあったみたいです．羨ましい．


## 改善点
VScodeでリアルタイムにWebページの状況を確認していきましたが，これはパソコンでの見え方を確認しているだけでした．スマホでの見え方はどうだったかというとグチャグチャでした．他のサイトはパソコンとスマホでいい感じにレイアウトが切り替わるのに，自分が作ったサイトは見たことないくらい文字や画像比率がおかしかったです．
大学サークルのサイトである以上，1番ターゲット層になるのは大学に入ってすぐの大学1年生かなと思います．入学したての大学生はパソコンよりスマホで見る機会が多そうだと考えたので，一旦レイアウトはスマホで見たときに綺麗であること，パソコンは見る上で困らない程度のレイアウトであることというイメージで作成していきました．

## 感想
初めてホームページを作りましたが，率直にこんな感じか~と思いました．まずプログラミング言語に関しては全く苦労することなく書けました．上の改善点で書いたことをガン無視してるじゃんと思われるかもしれないですが，"初めて"と考えると最低ラインは到達できたのかなと思います．
それよりも驚いたことというか，意外だったことはコードを書いている時間よりも調べている時間，考えている時間の方が圧倒的に長かった点です．分からないことだらけだったのでコードエディタの使い方どうするのとか，サーバー周りどうするの？とかの疑問点を解決する時間がとても長かったです．逆にコードを書くときはこういう画面を作りたいと調べればだいたい出てくるので特に困らなかった気がします．
JavaScriptはほんと気持ち程度にしか使えていないので，もっとぽいホームページを作れるように頑張ります．
バックエンドエンジニアが初めてDart/Flutterのコードをリリースして感じた3つの特徴

私が所属している[CBcloud](https://cb-cloud.com)が展開しているプロダクト、[ピックゴー](https://pickgo.town)のモバイルアプリはFlutter/Dartを使って開発をしております。

以前からFlutterを使ってモバイルアプリ開発をするのに興味はあったのですが、私はRubyonRailsでバックエンドの開発をする方が多く、モバイル側はモバイルアプリのエンジニアにお願いした方が早いので自分が触る機会はなかなかありませんでした。ただ、あるプロジェクトで簡易的にアプリ側を修正する必要が出てた時にこれぐらいだったら導入として良さそうでは？と思い、「これ、僕がモバイルも修正しますねー！」と勝手に宣言して初めてFlutterアプリへのコミット、そしてリリースをすることができました。

その開発を通して個人的に気付いたFlutter/Dartを使ったモバイルアプリ開発の特徴を書いていきたいと思います。

# 1: 開発環境(エディタ）を選ばない自由
過去に本当に小さなアプリですが、iOS/Androidのアプリを作ったことがあったのですが、その時の印象としてはiOS、Androidともに開発環境として実質専用のIDEを使う前提になっていてそれ以外の方法で開発するのはかなり厳しい印象がありました。

iOSだとXCode、AndroidだとAdroid Studioですね。

僕は普段Emacsで開発をしているので、それ以外のエディタを使うと途端にiQが10下がるほど開発効率が落ちてしまうのでIDE使うのがかなり苦手だったのですが、FlutterはコマンドラインツールやEmacsで開発していてもほとんどストレスなく開発をすることができました。

ドキュメントもVSCodeやAndroid Stdioでのやり方に合わせてCLIで実行する方法を大体書いてくれているのでほとんど困りませんでした。

僕は自由に失うのをとても嫌うので、開発環境の自由が保障されているFlutterの開発は、これならモバイルアプリ開発をやってもいいな〜と思える物でした。

# 2: hot reload/restartだけでもFlutterを使う理由になる圧倒的な開発者体験
過去にモバイルアプリの開発をちょっとやった時に苦痛だったのが、書いたコードのフィードバックループの遅さです。
僕はコードを一気に書いて一気に実行してテストするよりも、本当に少しづつ書いて、確認して、直すのフィードバックループを細かく早く何度も回す開発スタイルを好むのすが、iOS/Androidで開発した時にそれを端末にビルド・インストール・起動・確認するのが非常に時間がかかることにものすごいストレスを感じていました。

ただFlutterだと大抵のコードがhot reloadに対応してくれるので書いたコードの変更をすぐに端末に反映して変更内容を確認することができたことに革命的に良い開発者体験を感じました。
UIの修正をする時に、その画面に遷移するのに幾つかの操作が必要の場合、ビルド・インストール・起動の待ち時間だけでなく起動後の画面から修正箇所の画面に移動するのもまた手間だったりするのですが、hot reloadによってその画面を開いた状態でコードの修正をして変更結果を確認できるのは相当開発効率が上がります。

iOS/Androidのネイティブ開発がいまhot reloadに対応しているのかちょっとわかりませんが、もし対応していないのであれば、iOS/Androidの特有の機能を使わないのであればクロスプラットフォーム対応をしなくてもFlutterで開発したいと思わされました。

# 3. コードを自分で書くだけではなく生成するという文化
APIクライアントやJSONパースして特定のオブジェクトに変換するなど、ボイラープレートとなるようなコードが増えても生産性が落ちないようにそのようなコードは自分で書くのではなく自動生成しようと文化がコミュニティで育っているのが面白いです。

Rubyで普段開発していると言語自体の柔軟性が高いので、コード生成するというよりもコードの実行中にメソッド定義やクラス定義などのボイラプレートなるコードを実行していて開発を効率化しているのですが、Dartは言語自体にはRubyほどの柔軟性はない（出来るべきはないと考えていそう）ので、そもそも定義となるコードを書いたらそのコードを元に生成することで繰り返しの多いコードを書かなくてよくするライブラリが育っていました。

Rubyとは言語体系は全然違いますが、開発者体験をいかに良くするか、楽しくプログラミングするにはどうすればいいかが中心的な価値観になっていそうな点に親しみを覚えてDartという言語自体も少し好きになりました。

# 終わりに
小さな機能とはいえDart/Flutterのコードを書いてリリースするという経験を積め、しかもコードを書くのが楽しいと思えることができたので、今後もどんどんモバイルアプリの開発にも手を伸ばしていきたいと思います。

CBcloudではDart/Flutterを使ったモバイルアプリ開発をやりたい人を募集しているので、興味があればぜひ採用情報を覗いてみてください。

https://recruit.cb-cloud.com/1
【GoogleCloud】BigQuery　別プロジェクトへのテーブルコピー方法

# はじめに
既に運用されているBigQueryの一部テーブルを、別プロジェクトのテーブルへコピーするための参考手順となります。


## データセットのコピーについて
GoogleCloud の公式ドキュメントを参照すると「データセットのコピー」という項目があり、手順が記載されています。
https://cloud.google.com/bigquery/docs/managing-datasets?hl=ja#copy-datasets
　
しかし、2024/09/24現在ではまだベータ版となっており、以下のような注意書きがある状況です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3493488/96317da2-4ad6-6683-3a8b-0ccc7c9f3c77.png)

ベータ版の説明は以下
https://cloud.google.com/products?hl=ja#product-launch-stages
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3493488/7be3fc20-564b-8f8c-40d6-34f7c5c2c30d.png)

利用はできそうですが、SLAやテクニカルサポートの義務はないとのことから、別の方法を検討する事に。

## bq コマンドでのコピー
コピー方法をいくつか検討しました。

#### 案①　既存BigQueryからエクスポートし、新規BigQueryへインポートする方法
運用中のBigQuery各テーブルをCloud Storageへエクスポートし、BigQuery追加ページでエクスポートしたファイルから読み込む手順を選定し実施しました。
エクスポートはCSV形式でおこない、インポート時にスキーマを自動検出をオンにし、インポートしてみたのですが、テーブル種別がうまく引き継がれず、スキーマ情報を手動で入力しました。
元のスキーマ情報をGoogleCloudコンソール上でコピーし、インポート時にペーストしていたところ、フィールド名の頭に半角スペースが入ってしまいました。
しかも、GoogleCloudコンソール上では、フィールド名頭に半角スペースが入っておらず、ミスにつながる可能性があったので、こちらの案はボツとなりました。

#### 案②　コマンドを利用したコピー
上記案①のようなミスを防ぐために、作業をコマンドで実施するように検討する事に。
調べてみたところ bq コマンドで、別プロジェクトを指定できることがわかりました。

bq コマンドライン ツール リファレンス
https://cloud.google.com/bigquery/docs/reference/bq-cli-reference?hl=ja

bqコマンドを利用することで以下のようにデータセットをコピーすることができました。
```
# １．コピー元の対象テーブルのスキーマ情報を作成（誤入力を防止）
bq show -schema --project_id ＜既存プロジェクト名＞ ＜コピー元データセット名＞.＜コピー元テーブル名＞ > schema.json

# ２．コピー先へ空のテーブルを作成
bq mk --project_id ＜コピー先プロジェクト名＞ --table ＜コピー先データセット名＞.＜コピー先テーブル名＞ schema.json

# ３．コピー先テーブルへコピー実行
bq query --project_id ＜コピー先プロジェクト名＞ --destination_table ＜コピー先データセット名＞.＜コピー先テーブル名＞ --use_legacy_sql=false "select * from ＜既存プロジェクト名＞.＜既存データセット名＞.＜既存テーブル名＞;"
```

コピー後は、コピー元とコピー先のテーブル詳細画面を開き、行数やパーティションなどの数が同様であるかを確認し、作業終了とした。

## ■ 身につけた知識
・極力、手入力を避けた方が良い
・やむなく手入力してしまった場合、設定値確認はコマンドにて実施しよう。
【Apollo Client】FragmentをネストしたらUnionのデータが空になった

Next.jsを使ったアプリケーションを開発していて、APIからGraphQLプロトコルでデータを取得するところにはApollo Clientを使っています。
表題の通り、Unionの導入の際にデータが取得できなくてハマったので共有です。

## こんな風にネストするとうまくいかない
```graphql
query SomeQuery {
  someQuery {
    items {
      ...Info
    }
  }
}

fragment Info on InfoType {
  itemId
  firstResult {
    ...Result
  }
  secondResult {
    ...Result
  }
}

fragment Result on ResultUnion {
  ... on PayloadType {
    data
  }
  ... on ErrorType {
    message
  }
  __typename
}
```
このようにUnionのフラグメントをネストした定義でフェッチすると、`firstResult`や`secondResult`には`__typename`しかフィールドを持たない空のデータがキャッシュされてしまいます。

## ネストをやめるとうまくいく
```graphql
query SomeQuery {
  someQuery {
    items {
      ...Info
    }
  }
}

fragment Info on InfoType {
  itemId
  firstResult {
    ... on PayloadType {
      data
    }
    ... on ErrorType {
      message
    }
    __typename
  }
  secondResult {
    ... on PayloadType {
      data
    }
    ... on ErrorType {
      message
    }
    __typename
  }
}
```
このようにネストをやめるとちゃんとデータが入ってくるのですが、最初の例のようにどうしてもフラグメントを使いたい場面はあるかと思います。

# 解決策
同じ内容のissueを見つけたのですが、

https://github.com/apollographql/apollo-client/issues/7050

これによると、`InMemoryCache`の初期化時に、`possibleTypes`にUnionの親子関係を記述するとちゃんとデータを取得できるようです。

```typescript
new ApolloClient({
    ...
    cache: new InMemoryCache({
      ...
      possibleTypes: {
        ResultUnion: [
          "PayloadType",
          "ErrorType",
        ],
      },
    }),
  })
```
無事データがキャッシュされるようになりました。

Apolloの公式ドキュメントにもUnionとInterfaceのフラグメントを使うときは`possibleTypes`を明示する必要があると書かれているので、Interfaceの場合でも同じだと推測されます。

https://www.apollographql.com/docs/react/data/fragments/#using-fragments-with-unions-and-interfaces
Knowledge Bases for Amazon Bedrockを消し忘れたら$50消えた話

# あらすじ
BedrockでRAGを試すために、作成したKnowledge Base。後日もう少し触ってみようと思っていましたが、いろいろ忙しくて忘れてた。
10日ぶりに確認すると、請求額が$60を超えていました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3879374/58a9ac29-0192-6653-8805-c821e6efb9dd.png)
**$60ドル?** 
多少の金額は覚悟していましたが、ほぼ1万円は予想外。
Knowledge Baseってそんなにかかるの?
サービス別料金を確認すると、何やらOpenSearch Serviceというものにかかっている模様
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3879374/c41f53d5-bb44-5bc4-0516-786eec53ce83.png)
でもこんなサービス使った覚えがない。
しかし、Amazon Open Serviceにアクセスしてみると、作成した覚えのないドメインが作成されている
# 原因
Knowledge Baseの実態はAmazon OpenSearch Serverlessベクトルデータベースというもののようです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3879374/f5ebfd63-498c-b2de-2ae8-3a434838ca7f.png)
そして、OpneSearchServiceの料金体制は1時間ごと（詳しい料金は https://aws.amazon.com/jp/opensearch-service/pricing/ ）
それは$60ドルもかかるわけですわ

# まとめ
AWS初心者はどんなサービスを使っているか、どんな料金体制か公式ドキュメントで確認すべきですね。それからこまめにBilling and Cost Managementをチェック。
高い勉強代でした。

# 参考文献
https://aws.amazon.com/jp/blogs/news/knowledge-bases-for-amazon-bedrock-rag-patent/

https://aws.amazon.com/jp/opensearch-service/pricing/
[CAIレシピ] プロセスのデプロイ先・認証方法によるサービスURLの違い

## はじめに
この記事は次の記事の内容を理解していることを前提としています。

- [プロセスの作成と実行(匿名アクセスと基本認証)](https://qiita.com/shunsuzu/private/01d91caedb92bd7781ea)
- [プロセス実行環境の切り替え(Secure Agent環境での実行)](https://qiita.com/shunsuzu/private/2afc72613d894b4d553e)

これらの記事では、いくつかの条件を変更しながらCAIプロセスの実行手順を確認しておりました。CAIプロセスの実行時にサービスURLの違いに気づいた方もいらっしゃるかもしれません。この記事では、CAIプロセスを実行する条件により、どのようにサービスURLが変わるかを確認します。

## 条件別によるサービスURLの確認
### クラウドサーバー
CAIプロセスをクラウドサーバーで実行する設定としている場合、サービスURLは __匿名認証であるか・BASIC認証であるか__ によって決まります。

|匿名/<br>BASIC認証|REST|SOAP|
|-|-|-|
|BASIC|https://[POD URL]/active-bpel/rt/[serviceName]|https://[POD URL]/active-bpel/soap/[serviceName]|
|匿名|https://[POD URL]/active-bpel/__public__/rt/__[Org ID]__/[serviceName]|https://[POD URL]/active-bpel/__public__/soap/__[Org ID]__/[serviceName]|

:::note info
匿名認証の場合、サービスURLに OrgID(組織ID) が含まれます。
:::

### Secure Agent

CAIプロセスをSecure Agentサーバーで実行する設定としている場合、サービスURLは __匿名認証であるか・BASIC認証であるか__ に加えて __プロトコル(HTTP/HTTPS)__ によって決まります。

|匿名/<br>BASIC認証|HTTP/</br>HTTPS|REST|SOAP|
|-|-|-|-|
|BASIC|HTTP|__http__://[host]__:7080__/process-engine/rt/[serviceName]|__http__://[host]__:7080__/process-engine/soap/[serviceName]|
|匿名|HTTP|__http__://[host]__:7080__/process-engine/__public__/rt/[serviceName]|__http__://[host]__:7080__/process-engine/__public__/soap/[serviceName]|
|BASIC|HTTPS|__https__://[host]__:7443__/process-engine/rt/[serviceName]|__https__://[host]__:7443__/process-engine/soap/[serviceName]|
|匿名|HTTPS|__https__://[host]__:7443__/process-engine/__public__/rt/[serviceName]|__https__://[host]__:7443__/process-engine/__public__/soap/[serviceName]|



:::note info
匿名認証の場合、CAIプロセスの実行環境がクラウドサーバー、Secure Agentサーバー、いずれの場合においてもサービスURLに __public__ が含まれます。
:::

## 参照

- [Qiita - IICS CAIの実装レシピ - マスターページ](https://qiita.com/shunsuzu/items/3d1971ef6e3b993516aa)
Qiita始めました！

## ご挨拶
(2024/09/24)
はじめまして！プログラミングの勉強をしております、大学院生です。
この度、自分のやったことを記録するためにQiitaを始めました！
主にPythonの勉強を行っており、AtCoderで競技プログラミングにも参加しています(超初心者)。

今後は学んだことや、AtCoderでの問題などを共有していきたいと考えています。
よろしくお願いします！
毎日のルーティーン業務をGoogleToDoリストに自動登録する

## はじめに
毎日のルーティーン業務をToDoリストで管理したいけど，毎日登録するのは面倒くさい，かと言って明日以降のタスクを登録してしまうと大事なタスクが埋もれてしまって困る．
こういった経験のある方はいらっしゃいませんか？

私は大学生なのでレポート〆切やバイトの重要書類提出をToDoリストで管理することが多いです．そこに日々のちょっとしたタスクも追加したいけど，本当に重要なレポート〆切のタスクが埋もれてしまうのは嫌だなと感じます．

そこでGoogleToDoリストとGoogleAppsScriptを使って毎日のちょっとしたタスクを当日に自動登録できるスクリプトを作成しました．

## 実装例
大学生の毎日のタスク(笑)という感じではありますが，よくある事例としてソシャゲのログインボーナスをこなすみたいなものって実行時間は数分なのにやり始めるまでのハードルが高いみたいなことは有り得ると思います．私は野球のソフトバンクホークスが好きで，タカポイントというアプリがあるんですね．毎日ミニゲームをしたら観戦チケットと交換できるポイントが貯めれて，これを毎日すれば年間4回くらいタダで観戦できるくらいには貯まります．でも，やり忘れるんです(笑)
そこでこのミニゲームをするというタスクを毎日ToDoリストに追加できてたらいいなと思いました．毎日9時に定期実行して登録する．GoogleToDoはGoogleカレンダーに同期されるので，その日のタスクはカレンダー上に表示される仕組みです．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3888054/f9ac8628-b62b-73c4-98ff-c6b97664da24.png)

## 実行方法
1.Googleドライブ→新規→その他→GoogleAppsScript
　ここにサンプルコードをコピペしてください．
2.サービス→Tasks APIを有効にしておいてください．
3.自身のToDoリストIDを取得してサンプルコードにコピペしてください．
4.最後に毎日実行のトリガーを設定すればOKです．

## まとめ
今回は私のしょうもないミニゲームを例にあげましたが，
・毎朝メールを確認する
・朝会に参加する
・筋トレをする
・ログインボーナスを管理する
などなど色々な用途に使えるかなと思います．
私はタスクとして目に留まるとそれを終わらせなきゃという衝動が生まれるタイプなので自動登録させるのはとても有効でした．参考にしていただければ幸いです．

## サンプルコード
~~~
function createDASH() {
  // 自分のGoogleToDoリストID
  const listId = '###############'; 
  
  // タスクタイトル
  const taskTitle = 'ふうさんDASH';
  
  // 日付定義
  const today = new Date();
  today.setHours(23, 59, 59, 999);  

  // 日付を日時へ変換
  const dueDate = today.toISOString();

  // タスク定義
  const task = {
    title: taskTitle,
    due: dueDate
  };
  
  // タスクを追加
  const newTask = Tasks.Tasks.insert(task, listId);
  Logger.log('Task created: %s', newTask.title);
  Logger.log('Task ID: %s', newTask.id);
}
~~~