OmniAICreator/Qiita-1.07M huggingface dataset:
AWSの基礎知識

# そもそもAWSとは？

- AWSとはAmazon Web Servicesの略で、Amazonが提供しているクラウドコンピューティングサービスの総称。
- 世界中にサービス拠点(リージョン)を持ち、利用したい人はアカウントを作成するだけで、AWS が提供する 170 以上のサービス、たとえばサーバーやデータベースの機能を**Webブラウザだけですぐに利用が可能になる**。

## 従来の物理サーバーとの違いとは

- クラウドコンピューティングサービスが登場する前まで、サーバーを利用する必要があれば自社の建物の中などにサーバー機器を設置して「オンプレミス」で運用するのが一般的だった。
- クラウドコンピューティングでは、「サーバー機器を購入する」「管理する」「スペースを確保する」「納期の間、待つ」といった必要がなくなる。

参考  

- [クラウド・AWSの情報メディア SKYARCHのITあんちょこ-AWSとは？ 初心者にもわかりやすく解説](https://www.skyarch.net/column/whataws01/)
- [AWSの基本･仕組み･重要用語が全部わかる教科書](https://www.amazon.co.jp/AWS%E3%81%AE%E5%9F%BA%E6%9C%AC%E3%83%BB%E4%BB%95%E7%B5%84%E3%81%BF%E3%83%BB%E9%87%8D%E8%A6%81%E7%94%A8%E8%AA%9E%E3%81%8C%E5%85%A8%E9%83%A8%E3%82%8F%E3%81%8B%E3%82%8B%E6%95%99%E7%A7%91%E6%9B%B8-%E8%A6%8B%E3%82%8B%E3%81%A0%E3%81%91%E5%9B%B3%E8%A7%A3-%E5%B7%9D%E7%95%91%E5%85%89%E5%B9%B3/dp/4815607850)

## rootユーザーとIAMユーザー

### rootユーザーとは？

- AWSのrootユーザーとは、AWSアカウント作成時に設定したメールアドレスとパスワードでログインできるユーザーのこと。
- このルートユーザーは、すべてのリソースに対して**無制限なアクセスが可能**なので、もし認証情報(メールアドレスとパスワード)が悪意のある第三者に漏洩しアカウントへの侵入を許した場合、非常に危険。
- そのため、公式ユーザーガイドのベストプラクティスにもこう記載されている。

>[AWSアカウントのルートユーザーのベストプラクティス](https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/root-user-best-practices.html)  
>ルートユーザーの認証情報が必要なタスクがある場合を除き、AWS アカウントのルートユーザーにはアクセスしないことを強くお勧めします。  

### IAMユーザー

- rootユーザーで作業することが好ましくないので、IAMユーザーを作成し権限を付与して使用する。
- IAMユーザーはAWSアカウント内で作成できるユーザーで、紐づけられたIAMポリシー(今回はAdministratorAccess)によって操作できる内容が変化する。

:::note info
- **IAMポリシー**を様々なリソースにアタッチして利用する。
- IAMユーザーにIAMポリシーを直接アタッチすることは推奨されていない。
- IAM（Identity and Access Management）の主要サービスはSAAで問われることも多く把握しておく。
:::

参考

- [なぜAWSのrootユーザの利用が危険なのか？〜アカウント作成後の運用方法についてまとめてみた〜](https://dev.classmethod.jp/articles/rootuser-risk/)
- [IAMによるAWS権限管理 – プロジェクトメンバーへの権限付与方針に潜む闇](https://dev.classmethod.jp/articles/iam-policy-for-project-members/)
- [【AWS IAM】IAMユーザー、IAMグループ、IAMロール、IAMポリシーの違いを整理](https://uniuni-diary.com/aws-iam/)
- [AWS IAM の概念をざっくり理解する - サーバーワークスエンジニアブログ](https://blog.serverworks.co.jp/re-getting-started-iam)

## Cloud9

- Cloud9では**開発に必要なソフトウェアがほとんど最初から入っている**ため、ローカル開発環境の構築が必要なく、どのパソコンからでも同じ環境下で開発を進めることができる。

:::note warn
- Cloud9自体は無料のサービスだが、実態はEC2インスタンス(独自のサーバーも可)なので実際に使用した分に対しては料金が発生する。
- Cloud9ではインスタンスが動いていることを意識しなくていいためつい放置してしまいがちだが、不要な課金を防ぐためにも自動停止時間を設定し、使用後は削除しておく。
:::

参考

- [AWS Cloud9 のすゝめ](https://qiita.com/hatahatahata/items/66c0a186b6bfe2f9ef7f)
- [AWS Cloud9を導入して使い方を学ぼう](https://pikawaka.com/curriculums/programming-introduction/aws-cloud9)
- [AWS Cloud9 料金](https://aws.amazon.com/jp/cloud9/pricing/)
git pushできなかったとき


## 問題
ブランチを新規作成してコードを書いた後、git commitをした後にgit push origin mainをしたら、「Everythin up-to-date」と表示されてpushできなかった。

## 原因
新規作成したブランチがリモートブランチに公開されていない

## 対処法
```
 git push --set-upstream origin ブランチ名
```

これでpushすることができました。

ちなみに、自動的に以下を有効化すると自動的にリモートブランチを設定してくれました。
```
git config --global --add --bool push.autoSetupRemote true
```
ImportError: cannot import name 'SimpleDirectoryReader' from 'llama_index' (unknown location)


Pythonのllama_indexでエラーが出た解決方法について。
バージョンがllama_index v0.10.0以上の場合は書き方を変える必要があった。


### 出てたエラー

```
from llama_index import SimpleDirectoryReader, ServiceContext, GPTSimpleVectorIndex, LLMPredictor
---------------------------------------------------------------------------
ImportError                               Traceback (most recent call last)
<ipython-input-30-7f97f81316cf> in <cell line: 1>()
----> 1 from llama_index import SimpleDirectoryReader, ServiceContext, GPTSimpleVectorIndex, LLMPredictor

ImportError: cannot import name 'SimpleDirectoryReader' from 'llama_index' (unknown location)

```


```
from llama_index import GPTVectorStoreIndex, ServiceContext
from llama_index.llms import OpenAI
# from llama_index.callbacks import CallbackManager, LlamaDebugHandler
---------------------------------------------------------------------------
ImportError                               Traceback (most recent call last)
<ipython-input-29-0a68ce9db5aa> in <cell line: 1>()
----> 1 from llama_index import GPTVectorStoreIndex, ServiceContext
      2 from llama_index.llms import OpenAI
      3 # from llama_index.callbacks import CallbackManager, LlamaDebugHandler

ImportError: cannot import name 'GPTVectorStoreIndex' from 'llama_index' (unknown location)

```


```
from llama_index import LLMPredictor, ServiceContext, SQLDatabase, VectorStoreIndex
from llama_index.indices.struct_store import SQLTableRetrieverQueryEngine
from llama_index.objects import SQLTableNodeMapping, ObjectIndex, SQLTableSchema
---------------------------------------------------------------------------
ImportError                               Traceback (most recent call last)
<ipython-input-31-83f4868ef00c> in <cell line: 1>()
----> 1 from llama_index import LLMPredictor, ServiceContext, SQLDatabase, VectorStoreIndex
      2 from llama_index.indices.struct_store import SQLTableRetrieverQueryEngine
      3 from llama_index.objects import SQLTableNodeMapping, ObjectIndex, SQLTableSchema

ImportError: cannot import name 'LLMPredictor' from 'llama_index' (unknown location)
```


### 解決方法


- llama_index v0.10.0以前の書き方


```
from llama_index import SimpleDirectoryReader, ServiceContext, GPTSimpleVectorIndex, LLMPredictor
```

- llama_index v0.10.0以降の書き方

[参考](https://github.com/run-llama/llama_index/commits/main/llama-index-core?after=0774d393be8116b7063367d613fde2e3bb11d26d+69)


```
from llama_index.core import VectorStoreIndex, SimpleDirectoryReader
from llama_index.core import ServiceContext, SQLDatabase, VectorStoreIndex
from llama_index.core.indices.struct_store import SQLTableRetrieverQueryEngine
from llama_index.core.objects import SQLTableNodeMapping, ObjectIndex, SQLTableSchema
from llama_index.legacy import LLMPredictor
```
AWS Code3兄弟のハンズオンやったのでそのメモ

以下サイトにてAWS公式のcode3兄弟ハンズオンをやったのでそのメモ
https://pages.awscloud.com/JAPAN-event-OE-Hands-on-for-Beginners-cicd-2022-confirmation_484.html

ハンズオン内で最終的に構築した構成図は以下
![スクリーンショット 2024-03-03 16.05.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3510714/5063e55e-4fef-578f-5bb4-c3761e2720f5.png)

Cloud9からソースコートを編集してgit pushするとCodePipelineが変更を検知してデプロイまで自動的にやってくれるというシステム

感想としては、単純に現職でやっている開発にSFTPユーザ渡して、ソースコード編集してもらって〜みたいな流れをこれ導入するだけでお互いに楽できるようになるので導入していったほうがいーんじゃないかなと思った

各サービスの簡単まとめ
- Cloud9:AWS上での開発環境、EC2上で動作させる
- S3:今回は静的webサイトホスティングのために使用
- CodeCommit:AWS上のGit、Cloud9やVScodeなどを使用してgit使うことが多い？
- CodePipeline:ソースコードの変更を検知して、デプロイまでを行うフローを管理している
- AWSCodeBuild:ソースコードのコンパイルやテスト実行が可能（OS違いなどの環境を考慮できる？）、
- AWSCodeDeploy:

以下はハンズオンでやった内容の簡単メモ

- 今回はソースコードの編集環境としてCloud9を利用するため、Cloud9実行環境となるEC2を立てた。ここでソースを作って、CodeCommitにpushすることで構成管理している。　Cloud9の使用は必須ではなく、普通にVScodeの拡張機能とか使ってcodecommitにpushできる環境作ればok

- codecommit + s3　はAWSコンソール上だけで完結した、CodeBuiltd,CodeDeployサービスは使用しない
- EC2インスタンスへのCI/CDは以下の手順
    1. デプロイ先のEC2インスタンス作成
    2. S3へのフルアクセスロールアタッチ
    3. EC2にCodeDeployエージェントをインストール（利用リージョンによってエージェントが違う）
    3. CodeBuildプロジェクトを作成（buildspec.ymlの配置→ビルドの動作を細かく設定？）
    3. CodeDeploy設定（EC2が複数の場合に一部にデプロイなどのオプションがある、AppSpec.ymlの配置→ファイルごとの配置場所などを指定できる）
    3. CodePipelineでデプロイまでを自動化
[UnrealEngine5]アクターを地面にスナップさせるショートカット操作をK380でやりたい時

# 概要
UE5でアクターを地面にスナップさせるにはショートカットキー「End」で行うことができます。でも無線キーボードのK380ではEndボタンが無いので無理だと思っていました。
# 本文
「fnボタン」 + 「→ボタン」で地面スナップが出来ます:thumbsup:

![スクリーンショット 2024-03-03 164819.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617265/940fcfe0-bcaa-d20b-6f47-4856898e6711.png)


# 参考にさせていただいた記事
[K380で　ホーム＆エンド　が使いたい](https://note.com/kiwikiwi_1959/n/nc666d39974b3)
画像のコントラストを調整する【道具としての OpenCV 画像認識】

# 本記事でできること
画像は、左上から横に、コントラストゲイン
0.2, 0.4, 0.6, 
0.8, 1.0, 1.2,
1.4, 1.6, 1.8
に変更したもの。（1.0は元画像と同じ）

![Screenshot from 2024-03-03 16-44-00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37698/c6b68560-e5e3-0802-6178-35f78ec4968d.png)


# 想定シーン
## ロボットをビジュアルフィードバック制御する
カメラを使ったロボットアームの制御方法を、ビジュアルフィードバック制御といいます。ここでは、ビジュアルフィードバック制御を使った自動化システムを開発する際に必要となる画像認識プログラムをまとめています。

## 画像のコントラストを調整する
産業用ロボットでビジュアルフィードバック制御を実装する際、カメラの撮像環境によっては、コントラストが低かったり高かったりして、画像認識がしにくい、というケースがあります。本記事では撮影した画像に対してコントラストを調整するプログラムを掲載します。


# 実行環境
- OS：Ubuntu 22.04 LTS
- 言語：C++
- クルーボ：v5.1.0

## クルーボについて
ロボットアプリケーション開発には、株式会社チトセロボティクスのロボット制御ソフトウェア「クルーボ」を使用します。本記事のプログラムは、クルーボがインストールされた制御コンピュータ上で動作します。

- クルーボの製品サイト：https://chitose-robotics.com/product

## プログラム抜粋
```c++
/* コントラストゲインの推奨範囲：0.2~1.8 */
cv::Mat adjust_contrast(const cv::Mat& image, const float contrast_gain) {
    cv::Mat contrast_adjusted_image = contrast_gain * image;
    return contrast_adjusted_image;
}
```

## 全体プログラム
```c++
#include <iostream>
#include <opencv2/opencv.hpp>

cv::Mat load_image(const std::string file_path) {
    cv::Mat loaded_image = cv::imread(file_path, 1);
    if (loaded_image.empty()) {
        throw std::runtime_error("画像を正常に読み込めませんでした。");
    }
    return loaded_image;
}

/* コントラストゲインの推奨範囲：0.2~1.8 */
cv::Mat adjust_contrast(const cv::Mat& image, const float contrast_gain) {
    cv::Mat contrast_adjusted_image = contrast_gain * image;
    return contrast_adjusted_image;
}

int main(void) {
    std::string file_path = "../data/fuji.jpg";
    const cv::Mat loaded_image = load_image(file_path);

    /* コントラストゲインの推奨範囲：0.2~1.8 */
    const float contrast_gain = 1.8f;
    const cv::Mat adjusted_image = adjust_contrast(loaded_image, contrast_gain);

    cv::imshow("window", adjusted_image);
    cv::waitKey(0);
}
```

## おわりに
人手作業をロボットアームで自動化するために、カメラを使ったロボット制御＝ビジュアルフィードバック制御が大切です。
ロボット制御用の画像認識でも中身のひとつひとつはシンプルなので、要素に分解して解説していきたいと思います。
Web ComponentとReact

以下の記事は、自分の知識整理のための記事です。間違っていたらご指摘ください。

# Web Componentとは

ウェブの再利用可能なウィジェット・コンポーネントを作成するための標準技術の集合。

これにより、HTML, CSS, JSをカプセル化した上で再利用することが可能になる。

## 1. カスタム要素

カスタム要素と、その動作に関するJavaScript API。以下のようなコードをJavaScriptに書くことで、HTMLからpopup-infoタグを使用できるようになる。

```javascript
customElements.define("popup-info", PopupInfo);

class PopupInfo extends HTMLElement {
  constructor() {
    // コンストラクターでは常に super を最初に呼び出してください
    super();

    // ここに要素の機能を記述します
  }
}
```

```html
<popup-info></popup-info>
```

## 2. Shadow DOM

Shadow DOMツリーを要素に紐づけて関連する機能を制御するための、一連のJava Script API。カプセル化している。つまり、シャドウDOM外のJavaScript, CSSが、シャドウDOM内の要素に影響を与えることは無い。

1のカスタム要素単体だと、カプセル化されていないので、Shadow DOMと組み合わせることで、外部と隔離された形でタグが使用できるようになる。Shadow DOMは、HTML templateと違って、attachされたらすぐにレンダリングされる。

![スクリーンショット 2024-03-02 15.20.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/371779/fbecac46-6d22-0031-c094-29b007e5d564.png)


## 3. HTML template

template要素と、slot要素によって、レンダリングされたページに表示されないマークアップのtemplateを書くことができる。JavaScriptを介してインスタンス化される。

HTML templateは、templateの内容をカスタム要素としてカプセル化した上でShadow DOMに追加することで真価を発揮する。

```javascript
customElements.define(
  "my-paragraph",
  class extends HTMLElement {
    constructor() {
      super();
      let template = document.getElementById("my-paragraph");
      let templateContent = template.content;

      const shadowRoot = this.attachShadow({ mode: "open" });
      shadowRoot.appendChild(templateContent.cloneNode(true));
    }
  },
);
```

```html
<template id="my-paragraph">
  <style>
    p {
      color: white;
      background-color: #666;
      padding: 5px;
    }
  </style>
  <p>My paragraph</p>
</template>
```

こうすると、以下のような形で、my-paragraphタグを利用できる。my-paragraphは、HTML templateなので、ページ読み込みと同時にレンダリングされるわけではないので、パフォーマンス向上に貢献できる。

```html
<my-paragraph></my-paragraph>
```

# Web ComponentとReact

[メルカリのWeb Componentsに関する記事](https://engineering.mercari.com/en/blog/entry/20221207-web-design-system-migrating-web-components-to-react/)によると、メルカリ Core teamはWeb ComoponentsからReactに移行中であるとのこと(2022年末)。
そもそもWeb Componentsを導入した背景としては、Web Componentsを使えば、React, Vueなど、様々なフレームワークで利用できるというメリットがあったためらしい。

しかし、導入後、以下のような課題が出てきた。

- Web Componentsを使ってくれる・contributeしてくれる人が少ない
- Web Componentsでサーバーサイドレンダリング(SSR)を実行するのは難しい
- Web Componentsのその他の技術的な制約

そこで、Web ComponentsからReactへの移行を実施しているらしい。

## 所感

Web Components自体は面白い技術だが、導入した場合、メルカリの記事にあるような技術課題に直面しそう。つまり、Web Componentsは「世間的な認知がそこまで高くない・SSRなどの技術的制約が存在する」。Web Componentsを導入するのであれば、組織全体でWeb Components体制をサポートする必要がある。ただ、そこまでの企業努力をしてまで導入するメリットは、一般的な会社には無さそう。エンジニア採用しやすくて、使いやすい技術スタックという観点で考えると、Reactに軍配が上がる。

### 参考

https://developer.mozilla.org/ja/docs/Web/API/Web_components

https://engineering.mercari.com/en/blog/entry/20221207-web-design-system-migrating-web-components-to-react/

https://engineering.mercari.com/blog/entry/20210823-8128e0d987/
JAWS-UGって何？ AWS使ってるからちょっと興味ある…

そんな声をたまにXのタイムラインで見かけるのでご紹介します。


# JAWS-UGとは？

AWS User Group - Japanの略で、米アマゾンが提供するクラウドサービスAWSを利用している人々によるユーザーコミュニティです。

あくまで利用者主導なのがミソで、本家AWSもサポートをしてくれますが「公式セミナー」等とは性質が異なります。

https://jaws-ug.jp/


# 具体的に何やってるの？

基本的には「AWS勉強会の開催」です。毎週、何かしらの勉強会があります。

- 日本全国でオフライン勉強会の開催。オンラインやハイブリッドも多い
- AWS利用の知見を持ち寄って発表しあったり、ディスカッションなど形式は様々
- 地域やジャンルによって「支部」が分かれている

<br>
YouTubeで過去の勉強会アーカイブも覗けます。

https://www.youtube.com/@awsjcommunitymeetups


# どんな人が参加しているの？

エンジニアが多いですが、SE・PM・情シス・企画・営業、はたまた役員・個人事業主など幅広く、所属企業もスタートアップから大企業まで、業種もWeb系・SIer・コンサル・事業会社など本当に様々なAWSユーザーが参加しています。

エンジニアの場合もインフラ、バックエンド、フロント、SREなど属性は色々です。



# ちょっと興味あるんだけど？

まずは勉強会に参加してみてください！ 以下からお近くの支部のポータルに登録してみましょう。

https://jaws-ug.jp/act/

いきなり現地参加が不安な方は、オンラインのものを覗いてみましょう。

例えば私の主催する東京支部では、毎月「ランチタイムLT会」という形でライトニングトーク（5分間プレゼン）会をYouTube配信しています。

https://jawsug.connpass.com/


# コミュニティのいいところ

- 「公式セミナー」だとどうしてもフワッとした抽象的なプレゼンや当たり障りのない講演も多くなりますが（失礼）、コミュニティでは利用者がポジ・ネガ含めたぶっちゃけ話をし合うので非常に学びになりますし、何より楽しいです。<br><br>

- X（旧Twitter）を使った情報発信や、勉強会中のつぶやきが盛んです。所属を明らかにしなくてもよいので、エンジニアはぜひXアカウントを作って仲間と交流することを強くおすすめします。ちなみに公式ハッシュタグは `#jawsug` です。



# よくある質問

### 初心者すぎて怖い。私なんかが行って大丈夫かしら

→ 全然問題ありません！ JAWS-UGは参加者の良い人率がやけに高く、新規・初心者ウェルカムでサービス精神旺盛な運営・参加者メンバーが多いです。（もし仮に嫌な体験をした際は、ぜひお知らせください）


### 人見知りでぼっちになりそう。声かけられないかも

→ 結構みんなそうですｗ ほんのちょっと勇気を出して、となりの人に「初めまして。初参加なんですが名刺交換しませんか？」と話して顔見知りになる、みたいなのを何度かやっていると、気づけば参加するたび知り合いが増えてより勉強会が楽しくなってきます。


### なんか輪ができあがってる印象があって入りづらい

→ Xとかで「飲み会ウェーイ！」みたいな愉快な写真も回ってきますが、あれは結構ごく一部です。実際に参加すると分かりますが、おっとりした優しいエンジニアが割とマス層だと思います。


# で、お前誰？

某通信会社に勤務している普通のシステムエンジニアです。JAWS-UGのSRE支部、東京支部、NW-JAWSという3つのサブコミュニティの運営に参加しています。

好きなAWSサービスはAmazon VPC LatticeとAmazon Bedrockです。

みのるんという芸名でXもやってますので、何かあればお気軽にDMください👋

https://twitter.com/minorun365
Pythonで「print関数の使い方(文字列を出力する)」の動作を確認してみた

# 概要

Pythonで「print関数の使い方(文字列を出力する)」の動作を確認してみました。
以下のページを参考にしました。

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

# 実装

以下のファイルを作成しました。
```sample.py
print("Hello")
print(256)
print("Blue", "Red", "Green")

# デフォルトの設定
print("Blue", "Red", "Green")
# 区切り文字を "+" に変更
print("Blue", "Red", "Green", sep="+")
# 区切り文字を無くして続けて出力
print("Blue", "Red", "Green", sep="")

# デフォルトの設定
print("Hello");print("Python")
# 改行しないように設定：
print("Hello", end="");print("Python")
# 最後に任意の文字列を出力するように設定
print("Hello", end="[end]\n")

myfile = open("output1_4.txt", "w")
print("Hello", file=myfile)
print("Bye", file=myfile)
myfile.close()
```

以下のコマンドを実行しました。
```
$ python3 sample.py 
Hello
256
Blue Red Green
Blue Red Green
Blue+Red+Green
BlueRedGreen
Hello
Python
HelloPython
Hello[end]
$ cat output1_4.txt 
Hello
Bye
```

# まとめ

何かの役に立てばと。
S3 Select、Athena、Redshift Spectrumの違い

# 概要
AWS上でデータ分析をする上で、登場するS3 SelectとAthenaとRedshift Spectrum。これらのサービスの違いがわかっておらず混同しがちだったため、主に使いどころの観点からサービスの違いを勉強してみました。

# S3 Select
S3に保存されているオブジェクトに対してSQLを使用して 必要なデータのみ取得できるサービス。S3に保存されたデータから特定のデータを効率的に取り出すことに特化している。

### 使いどころ
- 単一のオブジェクトに対してSQLを実行するケース

### S3 Selectを実行する時に指定するパラメータ
- S3のバケット名、オブジェクト名
- 入力データのフォーマット形式
- 圧縮の有無
- 出力形式
- 実行するSQL

### 対応フォーマット
- CSV
- JSON
- Apache Parquet
- 圧縮されたオブジェクト（GZIPやBZIP2）
- サーバー側で暗号化されたオブジェクト

### 料金
S3 Selectを実行するS3のストレージタイプやリージョンによって異なる。
詳細は以下を参照
https://aws.amazon.com/jp/s3/pricing/

例：S3標準、東京の場合
スキャン：0.00225USD/GB
戻りデータ：0.0008USD/GB

# Athena
S3に保存されたデータに対して、サーバーレスでSQLクエリを実行することができる。サーバーレスのため、実行するためのインフラの準備や管理は不要で、実行したクエリにのみ課金される。他のAWSサービスと統合することで、データを分析し可視化できるようにもなる。

### 使いどころ
- S3に格納されているデータに対してアドホックな分析をしたいケース
- S3以外のデータソースに対しても分析をしたいケース（横串検索）
※S3のデータとDynamoDBのデータなどを結合して分析したいケース

### 料金
スキャンするデータサイズに応じて課金される。1TBあたり5USB


# Redshift Spectrum
Redshiftクラスター外のS3データに対して直接クエリを実行し、Redshift内のデータと結合することができる。


### 使いどころ
- Redshiftに格納されているデータとS3に格納されているデータを統合したいケース
※頻繁にクエリを実行したいデータはRedshiftに保存し、あまりクエリを実行しないデータはS3に保存し、クエリを実行する時はRedshift Spectrumを使用するようなケース


### 料金
Athenaと同様にスキャンするデータサイズに応じて課金される。1TBあたり5USB
※Redshiftを起動していないと利用できないため、Redshiftの利用料金も必ず発生する。

# まとめ
- **S3 Select**は単一のオブジェクトに対して簡単にSQLを実行したい時に使う
- **Athena**はS3に格納されているデータ（複数のオブジェクト）に対してアドホックな分析をしたい時に使う
- **Redshift Spectrum**はRedshiftに格納されているデータとS3に格納されているデータを統合したい時に使う

# 参考
https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/selecting-content-from-objects.html

https://docs.aws.amazon.com/ja_jp/athena/latest/ug/what-is.html

https://docs.aws.amazon.com/ja_jp/redshift/latest/dg/c-using-spectrum.html
オブジェクト指向関係の(一部)書籍の時代感を把握する

# 概要

技術書には、いわゆる名著というやつがあります。名著はいつ読み返してもいいものですが、読んでいるうちに少しは時代性を抑えたほうがいいのではという気持ちになってきました。ので、とりあえず手元のものを一覧にしてみました。

主に、プロセス本、パターン本を念頭に置いています。

# 年表

ざっと調べた程度なので、間違いがある可能性があります。

|出版日|出版日(邦訳)|書籍名(邦訳)|副題(邦訳)|著者|
|:----|:----|:----|:----|:----|
|1990/??/??|1992/??/??|オブジェクト指向方法論OMT|モデル化と設計|ジェームズ・ランボー|
|1992/??/??|1995/??/??|オブジェクト指向ソフトウェア工学OOSE|use-caseによるアプローチ|イヴァー・ヤコブソン|
|1995/??/??|1995/??/??|Booch法|オブジェクト指向分析と設計|グラディ・ブーチ|
|1995/??/??|1995/??/??|オブジェクト指向における再利用のためのデザインパターン|（なし）|（ギャング・オブ・フォー）|
|1996/7/??||UML 0.9||
|1996/8/8|1999/4/1|ソフトウェアアーキテクチャ|ソフトウェア開発のためのパターン体系|Frank Bushmann、Regine Meunier、Hans Rohnert、Peter Sommerlad、Michael Stal|
|1996/10/9|2002/4/1|アナリシスパターン|再利用可能なオブジェクトモデル|マーチン・ファウラー|
|1997/1/??||UML 1.0||OMG(スリー・アミーゴス)|
|1997/10/30|1998/12/31|実践UML|オブジェクト指向分析設計と反復型開発入門|クレーグ・ラーマン|
|1999/2/4|2000/3/30|UMLによる統一ソフトウェア開発プロセス|オブジェクト指向開発方法論|(スリー・アミーゴス)|
|2000/11/6|2004/3/18|ソフトウェアエンジニアリング|実践的オブジェクト指向技術体系|エリック・J・ブロディ|
|2001/7/13|2003/10/1|実践UML（第2版）|オブジェクト指向分析設計と反復型開発入門|クレーグ・ラーマン|
|2002/11/5|2005/4/1|エンタープライズアプリケーションアーキテクチャパターン|頑強なシステムを実現するためのレイヤ化アプローチ|マーチン・ファウラー|
|2003/8/22|2011/4/8|ドメイン駆動設計|ソフトウェアの核心にある複雑さに立ち向かう|エリック・エヴァンス|
|2007/??/??|2007/10/6|ユースケース駆動開発実践ガイド|オブジェクト指向分析からSpringによる実装まで|ダグ・ローゼンバーグ, マット・ステファン|

# おま感

 - 「実践UML」が、第2版という言葉と紐付いているのは謎だなと思っていたけれど、初版が「UMLによる統一ソフトウェア開発プロセス」より前なので、第1版はかなり差異があるのかもしれない（未確認）
 - 「アナリシスパターン」の表記がUMLと違って読みにくいけど、「デザインパターン」の後ではあるけどUML1.0より前なのか……
 - 「アナリシスパターン」は「デザインパターン」をめっちゃ意識した書籍名なのだなあ（「エンタープライズアプリケーションアーキテクチャパターン」もだけど）
 - 90年代後半の熱い時代の風を感じる（ポエム）。これは結果論なのかも知れないけど、21世紀にはいってすぐ、PofEAAとDDDが全てを総括していった完結篇の流れなのかなと感じた。
 - 一方で、XP本が2000年、アジャイルソフトウェア開発宣言が2001年、TDD本が2003年なので、おおむねパターンとプロセスが整った土壌のうえでアジャイルへの動きが出てきたのも感じられた。

# 追記

 - 「実践UML」初版は、Unified Processへの言及はなく、ジェームズ・ランボーによるRPM (Recommended Process Models)に基づいているという記述がありました。
 - 「～デザインパターン」初版は、UMLへの言及はなく、OMT、Objectory(OOSE本で詳述)、Booch法に（図によって）基づくという記述がありました。
 - 「ソフトウェアアーキテクチャ」（POSA本）は今となってはあまり参照されないでしょうが、「アナリシスパターン」は参照が多い？ので、ぜひUML版を出してほしい……
   - [UML版のモデルがファウラーのWebページに一部あります](https://martinfowler.com/apsupp/uml.html)が、まあ一部なので…… 
 - こういうオタク(GeekではなくNerd的な)ことしてないで、もっと勉強したほうがいい自覚はあります。。。
macOS環境にて、gccでバイナリのマップファイルを生成する

# 本記事について
MacBookにて、バイナリのmapファイルをgccで生成する方法について記載します。

# 実行環境
・macOS Sonoma 14.3.1
・Xcode 15.2
・gcc version 13.2.0 (Homebrew GCC 13.2.0) 
・MacBook Pro 13インチ M2

# 生成方法
gccのリンカオプションとして、下記のように`-Wl,-map,${出力したいmapファイル名}`を付け加える事により、そのプログラムに対すmapファイルを生成することが出来ます。
```cpp
domdam007@MacBook-Pro test20221106 % gcc -g --sysroot=$(xcrun --show-sdk-path) main.cpp -o a.out -Wl,-map,./a.out.map
domdam007@MacBook-Pro test20221106 % 
```

<font color="Red">※Linuxだと、大文字の”-`M`ap”だったはず…</font>
グレースケール画像をカラー画像に変換する【道具としての OpenCV 画像認識】

# 本記事でできること
![Screenshot from 2024-03-03 16-01-08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37698/553a5389-43b1-6cbc-5c76-b8c91ae0920a.png)


# 想定シーン
## ロボットをビジュアルフィードバック制御する
カメラを使ったロボットアームの制御方法を、ビジュアルフィードバック制御といいます。ここでは、ビジュアルフィードバック制御を使った自動化システムを開発する際に必要となる画像認識プログラムをまとめています。

## グレースケール画像をカラー画像に変換する
カメラ画像を使用した画像処理・画像認識では、　カラー画像（3チャンネル画像）とグレースケール画像（1チャンネル画像）を扱うことが多くあります。本記事では、カラー画像に変換するプログラムを掲載します。OpenCVで扱うアルゴリズムはグレースケール用とカラー画像用があるため、画像変数を与えるときに気をつける必要がありますが、本記事のプログラムを、カラー画像用のアルゴリズムの前にとりあえず実行しておけばカラー画像であることを確認できて便利です。

注意点として、グレースケール画像をカラー画像に戻した場合でも、白黒色は変わりありません。すなわち、画像情報として、1チャンネル画像から、3チャンネル画像にするので、モノクロがカラーに変化するわけではありません。

# 実行環境
- OS：Ubuntu 22.04 LTS
- 言語：C++
- クルーボ：v5.1.0

## クルーボについて
ロボットアプリケーション開発には、株式会社チトセロボティクスのロボット制御ソフトウェア「クルーボ」を使用します。本記事のプログラムは、クルーボがインストールされた制御コンピュータ上で動作します。

- クルーボの製品サイト：https://chitose-robotics.com/product

## プログラム抜粋
```c++
cv::Mat convert_colorimage(const cv::Mat& image) {
    const int colorimage_channel_num = 3;
    if (image.channels() == colorimage_channel_num) {
        return image.clone();
    }
    cv::Mat color_image;
    cvtColor(image, color_image, cv::COLOR_GRAY2BGR);
    return color_image;
}
```

## 全体プログラム
```c++
#include <iostream>
#include <opencv2/opencv.hpp>

cv::Mat load_image(const std::string file_path) {
    cv::Mat loaded_image = cv::imread(file_path, 1);
    if (loaded_image.empty()) {
        throw std::runtime_error("画像を正常に読み込めませんでした。");
    }
    return loaded_image;
}

cv::Mat convert_grayscale(const cv::Mat& image) {
    const int grayscale_channel_num = 1;
    if (image.channels() == grayscale_channel_num) {
        return image.clone();
    }
    cv::Mat gray_image;
    cvtColor(image, gray_image, cv::COLOR_BGR2GRAY);
    return gray_image;
}

cv::Mat convert_colorimage(const cv::Mat& image) {
    const int colorimage_channel_num = 3;
    if (image.channels() == colorimage_channel_num) {
        return image.clone();
    }
    cv::Mat color_image;
    cvtColor(image, color_image, cv::COLOR_GRAY2BGR);
    return color_image;
}

int main(void) {
    std::string file_path = "../data/fuji.jpg";
    const cv::Mat loaded_image = load_image(file_path);

    const cv::Mat grayscale_image = convert_grayscale(loaded_image);
    const cv::Mat color_image = convert_grayscale(grayscale_image);

    cv::imshow("loaded_image", loaded_image);
    cv::imshow("color_image", color_image);
    cv::waitKey(0);
}
```


## おわりに
人手作業をロボットアームで自動化するために、カメラを使ったロボット制御＝ビジュアルフィードバック制御が大切です。
ロボット制御用の画像認識でも中身のひとつひとつはシンプルなので、要素に分解して解説していきたいと思います。
seleniumでchromeブラウザを操作してウェブサイトを開く

# 概要

seleniumを使い、ウェブブラウザを操作できるところまでまとめます。

# seleniumのインストール

```
pip install selenium
```

# selenium webdriverのダウンロード

https://chromedriver.chromium.org/downloads

上記からダウンロードを行いました。操作するchromeブラウザのバージョンをURL欄にchrome://versionを入力して調べてからそれに対応するものをという記事をネットで読みましたが、あまり気にせず似たようなバージョンのものをダウンロードしてきました。

# 動作例

## サンプル1

はじめのサンプルとしてgoogle.comのページを開くものを作りました。

### コード

コードは下記のものを使いました。このコードはgoogle.comをchromeブラウザで開くという動作を想定しています。開いてすぐ閉じてしまうことを防ぐために3秒まつ処理を最後にいれています。

```python
import time
from selenium import webdriver

cService = webdriver.ChromeService(executable_path='.\\src\\chromedriver-win64\\chromedriver-win64\\chromedriver.exe')

driver = webdriver.Chrome(service = cService)
driver.get('http://www.google.com/')

time.sleep(3) # 3秒まつ
```

前提として、今回実行するプログラムはWindows上で動作させることを考えています。なので、パスの書き方に少し違和感があります。srcフォルダのなかにchromedriverをいれている想定です。

### 実行

```
python.exe .\src\main.py
```

上記コマンドを実行してブラウザが表示されることを確認しました。

## サンプル2

サンプル1のものに下記の機能をつけました。

- 表示したページのhtmlを取得する
- 検索窓に文字を入力する
- linkをクリックする

### コード

```python
import time
from selenium import webdriver
from selenium.webdriver.common.by import By

cService = webdriver.ChromeService(executable_path='.\\src\\chromedriver-win64\\chromedriver-win64\\chromedriver.exe')

driver = webdriver.Chrome(service = cService)
driver.get('http://www.google.com/')

time.sleep(3) # 3秒まつ

# 表示したページのhtmlを取得し、それを画面に表示する。
page_html = driver.page_source 
print(page_html)

# textarea(検索窓)に文字を入力する。
texts = driver.find_element(By.ID, "APjFqb")
texts.send_keys("input text")

time.sleep(3) # 3秒まつ

# linkをクリック
element = driver.find_element(By.LINK_TEXT, "画像")
element.click()

time.sleep(3) # 3秒まつ
```

### 実行

```
python.exe .\src\main.py
```
多態性

ガソリン車、ハイブリッド車、電気自動車は厳密には別物ですが、大まかに捉えると車です。
このように、多態性（polymorphism）は厳密には異なるけれど本質的には類似したものを、ざっくりと捕らえる考え方です。

多態性を実現する方法としては
・キャスト
・継承の活用
などがあります。
カラー画像をグレースケール画像に変換する【道具としての OpenCV 画像認識】

# 本記事でできること
![Screenshot from 2024-03-03 15-45-31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37698/a6aacb4b-f720-bd23-2f33-63f3988cb585.png)


# 想定シーン
## ロボットをビジュアルフィードバック制御する
カメラを使ったロボットアームの制御方法を、ビジュアルフィードバック制御といいます。ここでは、ビジュアルフィードバック制御を使った自動化システムを開発する際に必要となる画像認識プログラムをまとめています。

## カラー画像をグレースケール画像に変換する
カメラ画像を使用した画像処理・画像認識では、　カラー画像（3チャンネル画像）とグレースケール画像（1チャンネル画像）を扱うことが多くあります。本記事では、グレースケールに変換するプログラムを掲載します。また、グレースケール画像への変換の機会が多いため、できるだけ処理を減らしたいと考えます。そこで、変換処理の前に、与えられた画像がグレースケール（画像チャンネル数が1）かどうかを判定し、変換しなくても良い場合には、そのまま画像を返却するようにしています。

# 実行環境
- OS：Ubuntu 22.04 LTS
- 言語：C++
- クルーボ：v5.1.0

## クルーボについて
ロボットアプリケーション開発には、株式会社チトセロボティクスのロボット制御ソフトウェア「クルーボ」を使用します。本記事のプログラムは、クルーボがインストールされた制御コンピュータ上で動作します。

- クルーボの製品サイト：https://chitose-robotics.com/product

## プログラム抜粋
```c++
cv::Mat convert_grayscale(const cv::Mat& image) {
    const int grayscale_channel_num = 1;
    if (image.channels() == grayscale_channel_num) {
        return image.clone();
    }
    cv::Mat gray_image;
    cvtColor(image, gray_image, cv::COLOR_BGR2GRAY);
    return gray_image;
}
```

## 全体プログラム
```c++
#include <iostream>
#include <opencv2/opencv.hpp>

cv::Mat load_image(const std::string file_path) {
    cv::Mat loaded_image = cv::imread(file_path, 1);
    if (loaded_image.empty()) {
        throw std::runtime_error("画像を正常に読み込めませんでした。");
    }
    return loaded_image;
}

cv::Mat convert_grayscale(const cv::Mat& image) {
    const int grayscale_channel_num = 1;
    if (image.channels() == grayscale_channel_num) {
        return image.clone();
    }
    cv::Mat gray_image;
    cvtColor(image, gray_image, cv::COLOR_BGR2GRAY);
    return gray_image;
}

int main(void) {
    std::string file_path = "../data/fuji.jpg";
    const cv::Mat loaded_image = load_image(file_path);

    const cv::Mat grayscale_image = convert_grayscale(loaded_image);

    cv::imshow("loaded_image", loaded_image);
    cv::imshow("grayscale_image", grayscale_image);
    cv::waitKey(0);
}
```

## おわりに
人手作業をロボットアームで自動化するために、カメラを使ったロボット制御＝ビジュアルフィードバック制御が大切です。
ロボット制御用の画像認識でも中身のひとつひとつはシンプルなので、要素に分解して解説していきたいと思います。
Python学んでみた　第２回（演算〜ファイル）

# はじめに
初めまして！
エンジニアになって数年、今まで本を読むだけでしたが、もっとプライベートで楽しみながら成長したい！自分が学んだ足跡を残していきたい！と思い記事を書きました！
最終的には自在に開発できるようになりたいと思っています。:triumph:
いろいろな記事を参考にさせてもらっています。:bow_tone2:
その中でもこれってどういう意味？とかつまづいたところを念入りに書いていこうかと思います。:fist:

# 今回の目的
前回の続きです。（書いてたらすごい時間と量がかかっていた・・・！）

https://qiita.com/mr_noppo/items/edb3b1652b4bf695f708

# 使用したものや事前準備
・Macbook Pro
・Python
・Anaconda
・jupyter notebook


# Python
## 演算
・足し算
```python
42+10
(42).__add__(10) # 52
```
・４２の１００乗（オブジェクトなので基本オーバーフローしない）
```python
42**100
```

## Unicode文字列
・大文字変換
```python
name = 'taro'
name.upper() # TAROと表示（変数の中身はかわらない）
```
・複数行
```python
name = 'test'
test = f"""a
b{name}
c""" # a\nbtest\nc
```

## help系
表示したときに出てくるダンダー属性（__add__）はシステム内部で使用されているもので通常使用するものではないようです。
下部に表示されるものを使用しましょう

チェインできる関数を表示
```python
name = 'string'
dir(name)
```
どんな関数か説明を表示

```python
name = 'string'
help(name.upper)
```

Docの表示
※上記で説明したダンダー属性
```python
name = 'string'
name.__add__?
```

ソース例の表示
※上記で説明したダンダー属性
```python
name = 'string'
name.__add__??
```
![スクリーンショット 2024-03-03 14.19.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/943982/72c0ed82-1333-67cd-301c-83814de0c8d9.png)

## 条件文
インデントでブロックを表現します。この場合は「B」と「C」が表示される。
andやor、notはそのまま文字で表現する。&と|についてはbit演算に使用される。
```python
grade = 82
if grade > 90:
    print("A")
elif grade > 80:
    print("B")
    Print("C")
else:
    Print("D")

'A' != 'B' # true
```

## ループ文
インデントでブロックを表現します。
```python

for number in [1,2,3,4,5]: # 1~5
    print(number)

for number in range(1,7): # 1~6 半開区間（開始含む）
    print(number)

strs = ["A","B","C"]
for index, value in enumerate(nums):
    print(index, value) # 0 A...

dict = {"A":"TEST","B","TEST2"}
for key,value in dict:
    print(key, value) # A TEST...
```

## ファイル
### 作成
```python
fout = open('names.csv', mode='w', encoding='utf8')
```
### 書き込み
ファイル入出力ストリームが開いている間は反映されない
書き込まれたバイト数が表示される。
```python
fout.write('name\n')
```
### ファイルを閉じる
```python
fout.close()
```

### 一括で実行する
close()不要になる
```python
with open('names.csv', mode='w', encoding='utf8') as fout:
    fout.write('name\n')
    fout.write('taro\n')
    fout.write('jiro\n')
```

### ファイルの読み込み
```python
with open('names.csv', encoding='utf8') as fin:
    data = fin.read() # name\ntaro\njiro\n
    one_byte = fin.read(1) # b'n' 1バイトの読み込み
```

### 使用できる文字コードの確認
```python
import encodings
print(sorted(encodings.aliases.aliases))
```

# 続き
https://qiita.com/mr_noppo/items/c79cc6f959597ed18e0c
Amazon Linux 2にGUIのブラウザを入れたいが、エラーで失敗する件

# はじめに
こんにちは、ユーゴです。今回は、EC2上で動かしているAmazon Linux 2をMicrosoft Remote Desktopから操作していた時に、GUIベースのChromeが使えたら楽だなと思いインストールを試みたものの、エラーで躓いたので、解決策を紹介していこうと思います。

# 課題
Chromeをインストールしようとした。

```bash:Chromeのインストール
sudo yum install google-chrome-stable
```

しかし、以下のようなエラーが出て、Chromeをインストールできない。

```bash:エラー
Failing package is: google-chrome-stable-122.0.6261.94-1.x86_64
GPG Keys are configured as: https://dl.google.com/linux/linux_signing_key.pub
```

なお、
キャッシュをクリーンも試したが、効果なし。

```bash:キャッシュのクリーン
sudo yum clean all
```

# 解決策
以下のコマンドを実行し、chromiumをインストールすればよいです。

```bash
sudo amazon-linux-extras install epel
```

```bash
sudo yum install chromium
```

↓左上から「アプリケーション > インターネット > Chromium ウェブ・ブラウザ」で開ける。インスタンスのスペック次第では、レンダリングに時間がかかるかも...
![スクリーンショット 2024-03-03 14.34.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2607452/f7494cd8-64fa-bb0b-9f51-61b946f99aed.png)


こちらを参考にしました。
[Amazon Linux 2 を実行している Amazon EC2 インスタンスに GUI をインストールする方法を教えてください。](https://repost.aws/ja/knowledge-center/ec2-linux-2-install-gui)

ちなみに、私は直前にseleniumを触っていた流れがあったせいで、chromiumがヘッドレスブラウザだとばかり思っていましたが、chromiumもGUIを提供しているようでした。

# まとめ
いかがだったでしょうか。
そもそも、直近で「え、EC2ってRDPできたの？！」という驚きから始まった話で、色々とサーバー上で環境構築をするにあたりGUIブラウザ上で操作できると良いなと思い、まずはChromeをインストールしようと試みた時に遭遇した思い込みとエラーでした。クラウドは、ユースケース次第ではセキュリティには大変気を使わなければならない場面もあると思いますが、本当に便利で手軽にサービスを構築できるようになりました。いい時代に生まれたと思います。
このように、AWS周りのエラー対処から、Unityなどの知見まで様々な内容を取り扱っていきます。お役に立てましたら、いいね, LGTM, フォロー等よろしくお願いいたします！
ITコンサルのキャリアを振り返る

https://qiita.com/official-events/72b44470c9c08f6f080b

Qiitaみたらキャンペーンしてたので試しに私のこれまでキャリアについて書いてみたいと思います
適当にさらーと書くのでお時間ある人は読んでもらえればと思います
ちなみに現在の職種はエンジニアでなくコンサルなのでご了承ください

# これまでのキャリア概要
・2013年 地方の大学を1年留年して卒業。大学卒業後はフリーターしたり、契約社員で働く
・2015年 昔からITが好きだったのとそろそろ正社員で働かないと思いSESの会社へ入社。Qiitaのブログで書いてるようなJava、BI、SAPなんかの開発に従事
・2020年 都内のコンサルティン会社へ転職。なんかいろいろやりながら現在へ至る。
# キャリア形成で気をつけていたこと
## 上流工程への早期参加
SESの会社では富●通やNTTデ●タみたいな大手SIerの下請けとして働いていました
その中で仕事を丸投げされて本来上流をやるべき発注元の仕事をしたり、小規模な案件を元請けで受注しその責任者を経験しました
日本のIT業界はゼネコン構造になっていて以下の理由から転職をしました
・上流ほどうまいこと
・年をとった後、下流の経験しかないと上流に入るのは難しいこと
・下流工程がやりたいのであれば自分で勉強続ければいつでも戻れること

ちなみに転職の軸は大手SI企業は一緒にお仕事をした感じあまり面白そうでなかったので除外して受託や自社サービスの企業を受けました
しかし前職での経験が評価してもらえず未経験みたいな待遇の内定しかなかったので紆余曲折ありコンサル会社に入社しました

## 専門性と汎用性の両立
上流工程に行くということは汎用的に使えるスキルの需要は高まりますが、専門性は無くなっていくと思います

またエンジニアとして働く中でプロパーで大手に入った方は机上の空論を振ります方が多くそうはなりたくないという思いがありました
なので差別化の意味も含めて実装レベルのITを理解していることを武器としつつ上流工程やマネジメントみたいな管理業務も出来るように考えています

# 今後のキャリアプラン
とりあえず上記の内容でレベルを上げていきたいと思っています
今ってゼネラリストとかプレイングマネージャーとか言えばカッコいいですが、中途半端にならないかが不安です（笑）
Unity イベント関数の実行順序 (簡易版)

毎回ドキュメントを見に行ってる気がしたので代表的なイベント関数の順序をメモしときます

<img width = 500 src = https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3669184/6b00c49b-2056-7ead-9580-c952259c0bcc.png>

## 参照　
https://docs.unity3d.com/ja/2022.3/Manual/ExecutionOrder.html
Googleフォームとスプレッドシートで家計簿を自作してみた

初投稿になります。
# そもそも家計簿を自作しようとした背景
月末になると毎回、「あれなぜこんな金が無くなっている！？」ってなるので、まずは収支を把握したく、家計簿をつけたいと思い立ちました。

自分の生活スタイルを考慮すると、以下の要件を満たす家計簿が欲しい状態でした。
* 複数人で同時に管理・記入したい
* レシートの自動読み取りではない（当時は精度が良いイメージがなかった）
* 入力項目をカスタマイズしたい
* テーブルやシートで管理したい
* 課金なしで使いたい

こんなわがままな要望を満たすアプリが当時（2021年）は見つけられなかったので、Googleフォーム×スプレッドシートで家計簿を自作しました。


# 具体的な方法とアウトプットイメージ
## フォームの作成方法
Googleフォームの作成方法は[こちら](https://support.google.com/a/users/answer/9303071?hl=ja#create_form)で、Googleフォームの項目は以下にしました。
| 質問内容 | 回答必須か | 質問形式 | 内容|
|:-:|:-:|:-:|:-:|
| 何月のレシートか |  必須 | ラジオボタン | 1〜12月のいずれかを選択 |
| 支払った人 |  必須 | ラジオボタン | 記入者 |
|  ジャンル | 必須 |  ラジオボタン | 食費（外食含む）<br>水道代<br>ガス代<br>電気代<br>日用品代<br>家賃<br>その他 |
|  ジャンルがその他の人は何を買ったか | 任意| テキスト入力  | 購入したものの詳細を入力 |
|   支払い金額 | 必須 | テキスト入力 | 数値のみ入力 |
|   備考 | 任意 |  テキスト入力 | 追加情報があれば記載<br>例. どこで買ったなど |

フォームの回答は自動的にスプレッドシートに反映されるので、特に追加の操作は必要ないと思われます。

## スプレッドシートを少し加工
スプレッドシート上で、入力されたレシート情報が何年何月のものかを示すカラムを追加しました。
このカラムがあることで毎月の支出を把握することができます。年情報はタイムスタンプ（の左4文字）から取得、月情報は「何月のレシートか」項目で取得し、それらを結合しました。


以上で家計簿シートの準備は終了です。
スプレッドシートでは以下の図のような形で反映されていました（詳細は置換してぼかしています）。
![スクリーンショット 2024-03-03 14.52.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/550831/bbc8181a-c417-33c8-e231-b8cd64decac6.png)

## あとは色々カスタマイズしてみる
あとはGoogleフォームに回答することで自動的にレシートの情報が反映されていきます。

また各家庭ごとの事情（完全折半、どちらかが食費を多めに負担など※）に合わせて、スプレッドシート上で調整してください。このカスタマイズしやすさはスプレッドシートならではだと筆者は考えています。以下はイメージ図です。
※実際に筆者は在宅勤務が多々あるため、食費と水道光熱費を60%負担しています。

![スクリーンショット 2024-03-03 15.26.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/550831/1269a6f2-32e4-29cd-a2bf-ba7dceb42be5.png)


## スマホでも使いやすくするために
iPhoneの場合は、画面上に自作したGoogleフォームをアイコンとして登録することができます。またスプレッドシートのアプリをインストールすることで用意に家計簿の状況を把握することができます。家計簿は気軽に登録できてなんぼだと思っているので、ここの工夫はぜひ検討してください。


# （若干の）課題
ほぼほぼ要件は達成できていますが、使っていく中で以下のような課題は残っています。

* レシートの対象月については、追加カラムであり、回答ごとに自動更新されないので、自分で毎度コピペする必要がある
    * 若干面倒だが、10秒以内で終わる
* 年が切り変わったタイミングで、前年のレシートを入力すると、対象月でバグる
    * 例. 2024年12月31日のレシートを2025年1月1日に入力すると、レシートの対象月が2025/12となる

以上のような課題はありますが、全体を通して満足はしています。修正するからGASを使ってゴニョゴニョしないといけなさそうですね。。。

# 終わりに
皆さんもぜひGoogleフォーム×スプレッドシートを活用して、各家庭にフィットした家計簿を作ってみてください！お読みいただきありがとうございました！
AWS認定資格を全冠達成したので振り返り

# 【はじめに】
2024年3月1日にMLS試験に合格しました。
この合格により、「2024 Japan AWS All Certifications Engineers」への応募資格を得ることができました。

最初の資格（CLF）を取得してから約2年5ヶ月が経過し、この度全ての資格を取得する旅を無事に終えることができました。この過程を記録として残すことで、将来の誰かの参考になればと思います。

# 【これまでの戦歴】
これまでの戦歴と点数を公開します。
(SAAは今見るとかなりギリギリで受かってますね…)

|試験日  |試験名(略称)  |点数  |
|---|---|---|
|2021/8/30  |CLF  |789  |
|2021/12/23  |SAA  |724  |
|2022/3/11  |DVA  |801  |
|2022/7/29  |SCS  |810  |
|2022/11/01  |SOA  |753  |
|2022/12/16  |DBS  |787 |
|2023/3/3  |DOP  |788  |
|2023/9/1  |DAS  |834  |
|2023/9/19  |SAP  |794  |
|2023/11/10  |PAS  |895  |
|2024/2/16  |ANS  |844  |
|2024/3/1  |MLS  |826  |

# 【どうやって勉強してたか】
最初は様々な方法を試していましたが、最終的には以下の4つのステップを繰り返す方法に落ち着きました。

> ① 試験ガイドを読む
> ② (必要なら)対策用の本を読む
> ③ Cloud Lisence(*1)を契約してひたすら問題を解く
> ④ わからないところはChat-GPTに聞く

個人的には、特に3番目のステップが資格取得に役立ったと感じています。
各試験で安定して90%以上の問題を解けるレベルに達してから試験に臨んでいました。

理想としては100%の正解率を目指したいところですが、そのレベルを目指すと試験までの準備期間が長くなりがちです。そのため、90%の正解率を目安にしていました。


# 【全冠してみた感想】
全ての資格を取得した今、達成感はありますが、正直なところ一番の感情は安堵でした。

その理由の一つとして、JAWS DAYS 2024でのプレゼンテーション資料に「全資格取得を達成しました」と記載していたため、「もし落ちていたら…」という不安がありました。

当日は全冠のおかげでプレゼンの掴みの部分がうまく行ったと思っているので、それだけの価値はあったかなと感じております。

また、「3年以内に目に見える成果を出す」という個人的な目標があり、
Jr.Championsの任期が切れてしまった後もAll Certとして活動できるのでその点でも非常に嬉しい限りです。

# 【あとがき】
適切な努力をすれば、試験回数を重ねることで合格は十分に可能です。
特にAWS認定資格のように柔軟に受験できる試験では、その機会を最大限に活用することが重要です。

試験に落ちた際の反省と気持ちの切り替えが一番の挑戦でしたが、
それを乗り越えることができたのは大きな成果だと感じています。

そして、資格取得が目的ではなく、あくまで通過点であることを忘れずにいたいと思います。
次の目標に向かって、これからも前進していきたいと思います。

最後に、この記録がこれから資格取得を目指す方々のお役に立てば幸いです。

### 【参考】
*1 [CloudLisence](https://cloud-license.com)
CNNやViTからよりシンプルなモデル作り【NAFNet】



**原論文**
Simple Baselines for Image Restoration
https://arxiv.org/pdf/2204.04676.pdf


# 関連研究
チャンネルの重要度を計算するCNN【SENet】
https://qiita.com/wakayama_90b/items/96527dfbbeb1e2ee06c5

空間とチャンネルを動的なパラメータで捉えるViT【Restormer】
https://qiita.com/wakayama_90b/items/100c0a72f3a8d44b1bf1


# 結論
最近の画像認識モデルが複雑だから，シンプルにした．


# 概要
画像認識分野において，CNNやViTなど，様々なモデルが提案されている．モデルの構造や情報の共有は複雑で，ブラックボックスである．モデルの構造をシンプルにしたら，人間が少し理解できやすくなるのでは？って感じで，シンプルなモデルは，良い．非線形活性化関数，例えばSigmoid、ReLU、GELU、Softmaxなどは不要だ!





# モデル構造
いろんなモデル構造を下図に示す．

(a) ViTのSelf-AttentionとGate-Conv（複雑）【Restormer】

(b)シンプルな基盤

(c)(a)に寄せるため(b)を改良．CA（chanel-Attention）チャンネル方向の重み付け．

(d)GELUをsimple Gateに，CAをSCAに置き換える．




![スクリーンショット 2024-03-03 14.08.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457775/4d89224b-ed3f-3b5e-e418-0a562d407d6e.png)





# (d)NAFNet’s Block
![スクリーンショット 2024-03-03 14.16.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457775/9b0d7e1e-0b0f-05b6-e07c-1d88f0c12a6c.png)

## Simple Gate
Gated Linear Unit(GLU)に触発された構造であり，式1の計算をすることで，通常のGELUの性能を上回る．


![スクリーンショット 2024-03-03 14.26.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457775/a1570bda-67cf-fecd-4760-fa04a37599c6.png)

f()とg()はLiner層で，⦿は，要素積．σは非線形の活性化関数（GELU）など．GELUを普通に通すのではなく，片方にだけGELUを通して要素積すると良くなるよ．

Gated Linear Unit(GLU)の解説
https://qiita.com/hasebirokou/items/c84c51537658edba718e


========================================================
けど，GLUって，より複雑になるしGELUも使用している．（GELUの式って結構複雑）．なので，f()とg()は恒等関数（何も変化なし）と仮定して，σ（非線形関数）もいらない．σを取り除いたとしても，Gate(X) = f(X) ⊙ g(X)は非線形性を含むから．そしたら，σの選択にもとらわれないし一石二鳥．


結果，式(4)のように，超シンプルなXとYの要素積になる．XとYは上図の(c)Simple Gateのように，チャンネル方向に分割した2つを使用する．
![スクリーンショット 2024-03-03 14.38.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457775/12f105ea-cb43-ee29-b91b-82e95d780a65.png)



## Simplified Channel Attention（SCA）

上図の(a)のSENetで提案されたChannel Attentionの計算は，式(5)に示す．


![スクリーンショット 2024-03-03 14.44.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457775/d09308d9-b154-3c98-2bef-095d109d1217.png)

Xは入力で，Xに，Xで作った重みσ()をかける．Wは1x1Convで，なんか複雑．結局，入力XにXで作った何かをかけたらいいんでしょ!ってことで，GAP（pool）と1x1Convのみを残した．

![スクリーンショット 2024-03-03 14.48.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457775/842f5e9b-d843-fe27-8d5d-7c73b96157c6.png)



# 実験

ノイズとかに影響されなくなった．うん．



# まとめ

今回は，CNNやViTからよりシンプルなモデル作り【NAFNet】について解説した．シンプルな構造は，わかりやすくていいね．色々計算を外しても大丈夫みたい．
AmazonQを使ってサポート起票してみた

# 概要
[公式ドキュメント](https://docs.aws.amazon.com/ja_jp/amazonq/latest/aws-builder-use-ug/support-chat.html)によるとAmazon Qがサポートケース起票の手助けをしてくれるみたいです。実際の質問内容の生成をAmazon Qがやってくれるだと思います。
また、前提として「テクニカルサポートに関する質問については、ベーシックサポートプラン以外のサポートプランのユーザーのみが Amazon Q AWS Supportに連絡することができます。」と公式ドキュメントに記載があるので、ベーシックサポートプランのユーザーは使用できない機能となります。 

# 実際にやってみた
AmazonQからサポートを起票する方法は以下2つあります。
①「誰かと話したい」や「サポートを受ける」などの質問を入力して、直接サポートを求めることができます。
②Amazon Q のレスポンスに対して評価を行い「ケースの作成」を選択する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3683522/9cc9d555-992d-24a8-1832-2d25820dcae2.png)


今回は①でサポート起票をAmazonQから行いたいと思います。

AWSコンソールログイン後画面の右上に正六角形のボタンクリックし、AmazonQを起動します。

![amazonq開くためのキャプチャ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3683522/ef2350c3-4c96-fae1-bfdf-46bff23cc6c2.png)

今回は[公式ドキュメント](https://docs.aws.amazon.com/ja_jp/amazonq/latest/aws-builder-use-ug/support-chat.html)の例にある以下ケースを想定した問い合わせをしてみます。
トラブル内容に対して末尾に「誰かと話せますか」と加えていることがサポート問い合わせのトリガーです。

>踏み台のインスタンスに接続できません。再起動して新しいキーペアの生成を試みましたが、まだ何も解決されません。これは今朝、計画的なデプロイの後に発生しました。ネットワークに関連するその他の変更は行われていないことを確認しました。誰かと話せますか？

AmazonQの回答としては以下となりました。

![amazonq記事.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3683522/8a583f53-b002-f88e-dd6c-71208d105d32.png)

サポート起票に必要な値(該当サービス、質問内容)が埋められている返答が返ってきました。後はSubmitボタンを押せば提出できる状態となっています。
また右下部分のEditを選択した場合AmazonQによって生成された値を変更することが可能です。


# まとめ
実際にAmazonQを使ってサポート起票してみました。サポートケースの文章を考えることで時間を取られるケースが多いので非常に便利です。これからどんどん使っていきたいと思います。
Qiita記事を書くときに文字の色を変えてみる（備忘録）

# はじめに
Qiita記事を書くときに文字の色を変えたいことがある。
本記事は備忘録のために作成したものである。

# 文字の色を変える方法
<font color="red">foobar</font>

上記の`foobar`の文字のように赤色に変える方法としては、
以下のように記述する。

```
<font color="red">foobar</font>
```
apache でメンテナンス画面中でもページ閲覧可能にしたい

メンテナンス中でも開発者であったり、メンテナンスしている側は動作にウェブサイトの画面にどんな影響があるのかみたいので、メンテナンスページ見えてほしくないですよね。

apache のサーバーの場合は、メンテナンスページを見えないようにすることができます。nginx でもできますが、今回はapache で実装進めていきたいと思います。

# 前提

- apache のインストールが完了していること
(バージョンは問いません) apache2 よりhttpd でインストールしているほうが好ましいと思います。ディレクトリ構造が異なったと思います。

- DocumentRoot ディレクトリを作成していること
(これも特に指定なしです)

- conf ファイルは /etc/httpd/conf.d/ 配下に作成しています
(httpd.conf で include してたら問題ないです)




# virtualhost のconf に直接設定する場合

example.com.conf に設定します。

```
<VirtualHost *:80>
    ServerName example.com
    DocumentRoot /var/www/test-example/public_html

    ErrorLog logs/example.com-error_log
    CustomLog logs/example.com-access_log common

    ErrorDocument 503 /maintenance.html

    <IfModule mod_rewrite.c>
           RewriteEngine On
           RewriteCond %{REQUEST_URI} !=/maintenance.html
           RewriteCond %{REMOTE_ADDR} !=<your_ip>
           RewriteRule ^.*$ - [R=503,L]
    </IfModule>
</VirtualHost>
```

この場合は、同じconf 内に記述しているので、conf をいちいち横断する必要がなくなります。ただ、少しconf を複雑にしてしまいかねないので、その辺りは注意です。


# メンテナンス設定解説

メンテナンスの設定は、この部分です。
```
    <IfModule mod_rewrite.c>
           RewriteEngine On
           RewriteCond %{REQUEST_URI} !=/maintenance.html
           RewriteCond %{REMOTE_ADDR} !=<your_ip>
           RewriteRule ^.*$ - [R=503,L]
    </IfModule>

```
ロジック自体はシンプルです。
Rewrite engine をオンにします、つまりリダイレクトを発生させるように設定します。そして、Rewritecond (= 条件分岐)の条件に当てはまらなかったら、503 にしてください！という記述です。

つまり、
```
① RewriteEngine on => リダイレクトする準備できたよ～～
↓
② maintenance.html 以外にアクセス来た、かつ 自分の指定したIP ではなかったら、
全部のアクセスを503 とするよ～～～
↓
③ おっ、503 きたから、ErrorDocument で指定したページを返そう

```
という流れですね。
RewriteCond はデフォルトで「かつ(&)」だったと思いますが、間違いがあれば、すいません。


# conf ファイルをわける場合

先ほどと同じように設定します。今回はファイルを分割する方法で設定してみました。

```
#example.com.conf の中身
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
<VirtualHost *:80>
    ServerName example.com
    DocumentRoot /var/www/test-example/public_html

    Include conf.d/mainte.conf

    ErrorLog logs/example.com-error_log
    CustomLog logs/example.com-access_log common

    ErrorDocument 503 /maintenance.html
</VirtualHost>

# mainte.conf の中身

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

# rewrite_maintenance.conf
ErrorDocument 503 /maintenance.html

<IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteCond %{DOCUMENT_ROOT}/maintenance.html -f
  RewriteCond %{REQUEST_URI} !=/maintenance.html
  RewriteCond %{REMOTE_ADDR} !=127.0.0.1
  RewriteCond %{REMOTE_ADDR} !=<your_ip>
  RewriteRule ^.*$ - [R=503,L]
</IfModule>
```

今回の設定のメリットとしては、conf を汚さないことですね。もし何か上手くいかない設定があった場合でもファイルを分けているので、分離できている部分では少し安心ですね。Include をVirtualhost のディレクティブで指定するだけで呼び出すことが可能です。

設定ができたら、apache をreload してあげて、設定が完了です。
メンテナンスページが表示されなければ、成功です！！されたら、失敗です。
どこか設定が間違っている可能性ありです。

# まとめ

メンテナンス時に、メンテ用の設定ができるので、ぜひ使ってみてください。

# 参考URL

https://dainamo.jp/mainte/

https://mallowlabs.hatenablog.com/entry/20140805/apache_maintenance_mode
S3の名前は各リージョンで一意にならないといけない

### S3が作成できない
自分のアカウント内では「test」というバケットは作成していないのに、「同じ名前のバケットが既に存在しています」というエラーが起きてしまっています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3552177/ebf4e8fb-4c98-eb67-4fbd-e5c54576b970.png)

### 原因
S3の名前は、各リージョンで一意になる必要があります。
これはAWSアカウント内に絞った話ではなく、そのリージョン内で誰かが作った名前のバケットは作成できないということです。
Git branch 操作術

git branchコマンドを最低限の理解する

## 表示
### git branch
ローカルブランチの一覧を表示する。

### git branch -r
-r、もしくは、--remotesオプション。
リモートブランチの一覧を表示する。

### git branch -a
-a、もしくは--allオプション。
リモートブランチを含んだブランチの一覧を表示する。

### git branch -v
-v、もしくは--verboseオプション。
詳細情報を付与した状態で、ブランチの一覧を表示する。
各ブランチの先頭のコミットのIDとメッセージを表示する。
-vvオプションを使用することで、追跡しているリモートブランチの名前を表示する。


## 操作
### git checkout -b <branchname> 
新しいブランチの作成、またはリモート上のoriginブランチをローカルに作成
同時にブランチの切り替えを行う。


### git branch -d <branchname>
-d、もしくは、--deleteオプション。
指定したローカルブランチを削除する。
-rオプションを付けた場合は、リモートブランチを削除する。
指定したブランチの内容が、追跡しているリモートブランチ(設定されていない場合はHEAD)にマージされていないと削除できない。

マージの状態に関わらず、強制的に指定したブランチを削除
```
git branch -D <branchname>
```

### git branch -m <new branchname>
-m、もしくは、--moveオプション。
現在チェックアウトしているブランチ名を<new branchname>に変更する。
git branch -m <old branchname> <new branchname>で変更元を指定することもできる。
空間の重要度計算も追加したSENet【CBAM】



**原論文**
CBAM：Convolutional Block Attention Module
https://arxiv.org/pdf/1807.06521.pdf




# 関連研究
チャンネルの重要度を計算するCNN【SENet】
https://qiita.com/wakayama_90b/items/96527dfbbeb1e2ee06c5


# 結論
SENetは，各チャンネルの重要度を計算してるので，空間方向の重要度の計算を追加した．

# 概要
画像認識のCNNは，どんな画像が入力されても同じ重み（静的なパラメータ）を使用している．けど，画像によって，画像のどこの部分が重要かって違うよね．例えば，画像に小さく写る猫は，重要な部分が猫の小さい部分で，大きくうつてる猫の画像は，画像のほとんどの部分が重要である．

画像によって，重要な部分が違うなら，重みも画像によって変更した方がいいんじゃない？って感じで画像によって変化する重み（動的なパラメータ）を持つSENetが誕生した．
しかし，SENetは，入力特徴量のチャンネル方向の重要度を決定している．その派生で空間方向の重要度を決定する構造を提案しました．これをCBAMと呼ぶ．
CBAMは，チャンネル方向と空間方向の重みつけ（重要度つけ）両方を使用して精度した．



# モデル構造
下図にモデル構造を示す．入力特徴量からチャンネル重み付け→空間重み付けする．
画像から，チャネルで「何」が空間で「どこ」にあるかについて焦点を当てる．

![スクリーンショット 2024-03-03 13.08.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457775/bbc2d4db-d247-fca3-ec7a-b22b5752163a.png)



## チャンネル重み付け
入力画像が「何」に意味があるかに注目する．
緑で示す範囲が，チャンネル重み付けである．SENetで使用されるチャンネル重みつけと似た構造である．

異なる点は，SENetは入力特徴量（$H \times W \times C$）の空間方向に対して，GAPで（$1 \times 1 \times C$）にする．しかし，空間情報を平均する方法では，重要って思って大きくした値が平均によって消えてしまう可能性がある．


CBAMでは，各チャンネルで空間方向の情報を平均した値（$1 \times 1 \times C$）赤とmax値（$1 \times 1 \times C$）青を取得して，その2つをMLPする．MLPした赤と青の要素和→sigmoid関数して完成（$1 \times 1 \times C$）．
各チャンネルの重要度を入力特徴量にかける．


![スクリーンショット 2024-03-03 13.10.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457775/7309b7b1-fa69-b265-5f50-521eb9ae0f2d.png)


## 空間重み付け
入力画像が「どこ」に意味があるかに注目する．
紫で示す範囲が，チャンネル重み付けである．入力特徴量（$H \times W \times C$）のチャンネル方向に対して，平均（$H \times W \times 1$）とmax（$H \times W \times 1$）で圧縮する．平均とmaxで求めた青と赤をチャンネル方向に並べて（$H \times W \times 2$），7x7畳み込みをする．その後sigmoid関数を通して完成（$H \times W \times 1$）．
各空間の重要度を入力特徴量にかける．




![スクリーンショット 2024-03-03 13.22.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457775/38b07c33-d4ea-94b7-61fc-041033755904.png)


# 実験

空間重みつけの（$H \times W \times 2$）の状態から，7x7でなく，1x1畳み込みを採用した場合に，精度低下する．


また，チャンネル→空間の順番で計算しているが，その順番を変更したり並列に処理したりした場合に，チャンネル→空間の順番が良かった．


![スクリーンショット 2024-03-03 13.54.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457775/2d4b2f4a-5392-b9b6-bd37-92c6112c599e.png)





# まとめ
空間の重要度計算も追加したSENet【CBAM】について解説した．SENetの派生で，空間を圧縮するか，チャンネルを圧縮するかの違いだけなので，シンプルで分かりやすい．また，圧縮方法も工夫されている．
就労移行支援事業所で学習しているプログラミング言語

# はじめに

「就労移行支援事業所」というのをご存じでしょうか？厚生労働省では以下のように定められています。

>就労移行支援事業所は、国からの補助を受け、障害のある方や難病の方の就職・復職（リワーク）を支援するサービスです。就労移行支援などの障害者総合支援法による各種サービスは、利用料の総額の1割を上限として、世帯の所得に応じて月ごとの負担上限額が設けられています。訓練を受けて2年以内に一般企業への就職を目指します。

## 就労移行支援事業所で学習、実習しているプログラミング言語

就労移行支援事業所で学習、実習しているプログラミング言語

主に以下のプログラミング言語が多いです。
・VBA(Excel)
・JavaScript
・PHP
・Ruby

VBAは事務職志望の方がExcelの実習をする際に学びます。
IT系はWeb系を学ぶことが多く、HTML/CSSの学習後、JavaScript、PHP、Rubyを学ぶことが多いです。

## Pythonは何故少ないか?

Pythonを学習する就労移行支援事業所は少ないのが実情です。理由は
① Pythonに知見のある職業指導支援員が少ない
② Webサイトの開発、WordPressに知見のあるエンジニア出身の職業指導支援員が多いと考えられるため、関連性の高いPHPを学習することが多い
③ PHPを言語に採用した場合、サーバー構築が楽
だと考えられます。

## 最後に
私も就労移行支援事業所を何か所か見学した際、調査したことを記事にしました。
`#`を含めて65文字のハッシュタグをBlueskyに投稿する方法

`#`を含めて65文字のハッシュタグをBlueskyに投稿するTypeScriptコードを示します。コードでは、`ByteSlice`の`byteStart`と`byteEnd`にそれぞれ`0`と`65`を設定し、`tag`に（`#`無しの）64文字の文字列を設定した上で、`text`に（`#`ありの）65文字の文字列を設定しています。

なお、`service`や`identifier`や`password`の値は、[公式ドキュメント](https://docs.bsky.app/docs/get-started)の例をそのまま使っています。適宜、書き換えて使ってください。

[@ioriayaneさんのコメント](https://bsky.app/profile/ioriayane.relog.tech/post/3kmkldsqo6f25)を参考にして作成しました。ただし、コードに問題があった場合、責任は@mnoguにあります。

```typescript
import { BskyAgent, Facet } from '@atproto/api'


const agent = new BskyAgent({
    service: 'https://bsky.social'
})

const main = async () => {
    await agent.login({
        identifier: 'example.com',
        password: 'hunter2'
    })

    const tag = '1234567890'.repeat(6) + '1234'

    const byteSlice = {
        byteStart: 0,
        byteEnd: tag.length + 1,
    }

    const facets: Facet[] = [
        {
            index: byteSlice,
            features: [{
                tag: tag,
                $type: 'app.bsky.richtext.facet#tag',
            }],
        },
    ]

    await agent.post({
        text: `#${tag}`,
        createdAt: new Date().toISOString(),
        facets: facets,
    })
}

main().then()
```

このコードでは、`#`を除くとハッシュタグが数字のみで構成されています。例えば`RichText`を使うときなどに、数字のみだとハッシュタグとして扱われない可能性があります。扱われなかった場合は、`1234567890`を例えば`a234567890`に変えると動くかもしれません。
huskyのv8とv9の違いを確認しつつ、npm scriptsを理解する

# 概要
husky がずっとv4のプロジェクトがあるので、 Node.js のバージョンアップに合わせてアップデートをしようとしました。
2024/1/25にv9.0.1がリリースされていたので違いを確認しつつ、 npm について理解したことをまとめます。

# v8とv9の違い
Release Note

https://github.com/typicode/husky/releases/tag/v9.0.1

v9に変わり、インストール時のコマンドが一つで済むようになり、 .husky/pre-commit もシンプルになっています。

例えば、v8のインストール手順のコマンドは以下です。

```bash
npm pkg set scripts.prepare="husky install"
npm run prepare
npx husky add .husky/pre-commit "npm test"
```

v9では上記のコマンドは以下で全て実行されます

```bash
npx husky init
```

他には、v9にあたり Node.js のv14とv16のサポートが外れ、v18以上の engines の指定が追加されています。


# npm について

## npm-pkg

https://docs.npmjs.com/cli/v10/commands/npm-pkg

package.json の読み書きができます.

```bash:example
npm pkg set version=1.0.1
npm pkg get version
# 1.0.1
```

つまり、huskyの最初のコマンドは scripts に prepare として husky install を設定しています

```bash
npm pkg set scripts.prepare="husky install"
```

## npm-scripts

https://docs.npmjs.com/cli/v10/using-npm/scripts

公式のサンプルですが、基本的な考え方として Pre/Post の接頭辞を定義することで、 scripts の実行前後に処理を実行することができます

```bash:公式サンプル
{
  "scripts": {
    "precompress": "{{ executes BEFORE the `compress` script }}",
    "compress": "{{ run command to compress files }}",
    "postcompress": "{{ executes AFTER `compress` script }}"
  }
}
```

これとは別に特別なライフサイクルイベントとして、いくつか他の scripts が存在し、 prepare はその一つです。
preapare が組み込まれている scripts は以下です。実行順序は公式ドキュメントを確認してください

- npm cache add
- npm ci
- npm diff
- npm install
- npm pack
- npm publish
- npm rebuild

インストール時や成果物生成の時に常に実行される scripts のようです
このため、複数人で開発する時にきちんと git-hooks の設定がおこなわれることになります

# サンプルコード

https://github.com/shikazuki/husky-sandbox